-/* Make sure that Vx_resource_name is set to a reasonable value.
- Fix it up, or set it to `emacs' if it is too hopeless. */
-
-static void
-validate_x_resource_name ()
-{
- int len = 0;
- /* Number of valid characters in the resource name. */
- int good_count = 0;
- /* Number of invalid characters in the resource name. */
- int bad_count = 0;
- Lisp_Object new;
- int i;
-
- if (STRINGP (Vx_resource_name))
- {
- unsigned char *p = SDATA (Vx_resource_name);
- int i;
-
- len = SBYTES (Vx_resource_name);
-
- /* Only letters, digits, - and _ are valid in resource names.
- Count the valid characters and count the invalid ones. */
- for (i = 0; i < len; i++)
- {
- int c = p[i];
- if (! ((c >= 'a' && c <= 'z')
- || (c >= 'A' && c <= 'Z')
- || (c >= '0' && c <= '9')
- || c == '-' || c == '_'))
- bad_count++;
- else
- good_count++;
- }
- }
- else
- /* Not a string => completely invalid. */
- bad_count = 5, good_count = 0;
-
- /* If name is valid already, return. */
- if (bad_count == 0)
- return;
-
- /* If name is entirely invalid, or nearly so, use `emacs'. */
- if (good_count == 0
- || (good_count == 1 && bad_count > 0))
- {
- Vx_resource_name = build_string ("emacs");
- return;
- }
-
- /* Name is partly valid. Copy it and replace the invalid characters
- with underscores. */
-
- Vx_resource_name = new = Fcopy_sequence (Vx_resource_name);
-
- for (i = 0; i < len; i++)
- {
- int c = SREF (new, i);
- if (! ((c >= 'a' && c <= 'z')
- || (c >= 'A' && c <= 'Z')
- || (c >= '0' && c <= '9')
- || c == '-' || c == '_'))
- SSET (new, i, '_');
- }
-}
-
-
-extern char *x_get_string_resource ();
-
-DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0,
- doc: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.
-This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the
-class, where INSTANCE is the name under which Emacs was invoked, or
-the name specified by the `-name' or `-rn' command-line arguments.
-
-The optional arguments COMPONENT and SUBCLASS add to the key and the
-class, respectively. You must specify both of them or neither.
-If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
-and the class is `Emacs.CLASS.SUBCLASS'. */)
- (attribute, class, component, subclass)
- Lisp_Object attribute, class, component, subclass;
-{
- register char *value;
- char *name_key;
- char *class_key;
-
- CHECK_STRING (attribute);
- CHECK_STRING (class);
-
- if (!NILP (component))
- CHECK_STRING (component);
- if (!NILP (subclass))
- CHECK_STRING (subclass);
- if (NILP (component) != NILP (subclass))
- error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
-
- validate_x_resource_name ();
-
- /* Allocate space for the components, the dots which separate them,
- and the final '\0'. Make them big enough for the worst case. */
- name_key = (char *) alloca (SBYTES (Vx_resource_name)
- + (STRINGP (component)
- ? SBYTES (component) : 0)
- + SBYTES (attribute)
- + 3);
-
- class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
- + SBYTES (class)
- + (STRINGP (subclass)
- ? SBYTES (subclass) : 0)
- + 3);
-
- /* Start with emacs.FRAMENAME for the name (the specific one)
- and with `Emacs' for the class key (the general one). */
- strcpy (name_key, SDATA (Vx_resource_name));
- strcpy (class_key, EMACS_CLASS);
-
- strcat (class_key, ".");
- strcat (class_key, SDATA (class));
-
- if (!NILP (component))
- {
- strcat (class_key, ".");
- strcat (class_key, SDATA (subclass));
-
- strcat (name_key, ".");
- strcat (name_key, SDATA (component));
- }
-
- strcat (name_key, ".");
- strcat (name_key, SDATA (attribute));
-
- value = x_get_string_resource (Qnil,
- name_key, class_key);
-
- if (value != (char *) 0)
- return build_string (value);
- else
- return Qnil;
-}
-
-/* Used when C code wants a resource value. */
-
-char *
-x_get_resource_string (attribute, class)
- char *attribute, *class;
-{
- char *name_key;
- char *class_key;
- struct frame *sf = SELECTED_FRAME ();
-
- /* Allocate space for the components, the dots which separate them,
- and the final '\0'. */
- name_key = (char *) alloca (SBYTES (Vinvocation_name)
- + strlen (attribute) + 2);
- class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
- + strlen (class) + 2);
-
- sprintf (name_key, "%s.%s",
- SDATA (Vinvocation_name),
- attribute);
- sprintf (class_key, "%s.%s", EMACS_CLASS, class);
-
- return x_get_string_resource (sf, name_key, class_key);
-}
-
-/* Types we might convert a resource string into. */
-enum resource_types
-{
- RES_TYPE_NUMBER,
- RES_TYPE_FLOAT,
- RES_TYPE_BOOLEAN,
- RES_TYPE_STRING,
- RES_TYPE_SYMBOL
-};
-
-/* Return the value of parameter PARAM.
-
- First search ALIST, then Vdefault_frame_alist, then the X defaults
- database, using ATTRIBUTE as the attribute name and CLASS as its class.
-
- Convert the resource to the type specified by desired_type.
-
- If no default is specified, return Qunbound. If you call
- w32_get_arg, make sure you deal with Qunbound in a reasonable way,
- and don't let it get stored in any Lisp-visible variables! */
-
-static Lisp_Object
-w32_get_arg (alist, param, attribute, class, type)
- Lisp_Object alist, param;
- char *attribute;
- char *class;
- enum resource_types type;
-{
- register Lisp_Object tem;
-
- tem = Fassq (param, alist);
- if (EQ (tem, Qnil))
- tem = Fassq (param, Vdefault_frame_alist);
- if (EQ (tem, Qnil))
- {
-
- if (attribute)
- {
- tem = Fx_get_resource (build_string (attribute),
- build_string (class),
- Qnil, Qnil);
-
- if (NILP (tem))
- return Qunbound;
-
- switch (type)
- {
- case RES_TYPE_NUMBER:
- return make_number (atoi (SDATA (tem)));
-
- case RES_TYPE_FLOAT:
- return make_float (atof (SDATA (tem)));
-
- case RES_TYPE_BOOLEAN:
- tem = Fdowncase (tem);
- if (!strcmp (SDATA (tem), "on")
- || !strcmp (SDATA (tem), "true"))
- return Qt;
- else
- return Qnil;
-
- case RES_TYPE_STRING:
- return tem;
-
- case RES_TYPE_SYMBOL:
- /* As a special case, we map the values `true' and `on'
- to Qt, and `false' and `off' to Qnil. */
- {
- Lisp_Object lower;
- lower = Fdowncase (tem);
- if (!strcmp (SDATA (lower), "on")
- || !strcmp (SDATA (lower), "true"))
- return Qt;
- else if (!strcmp (SDATA (lower), "off")
- || !strcmp (SDATA (lower), "false"))
- return Qnil;
- else
- return Fintern (tem, Qnil);
- }
-
- default:
- abort ();
- }
- }
- else
- return Qunbound;
- }
- return Fcdr (tem);
-}
-
-/* Record in frame F the specified or default value according to ALIST
- of the parameter named PROP (a Lisp symbol).
- If no value is specified for PROP, look for an X default for XPROP
- on the frame named NAME.
- If that is not found either, use the value DEFLT. */
-
-static Lisp_Object
-x_default_parameter (f, alist, prop, deflt, xprop, xclass, type)
- struct frame *f;
- Lisp_Object alist;
- Lisp_Object prop;
- Lisp_Object deflt;
- char *xprop;
- char *xclass;
- enum resource_types type;
-{
- Lisp_Object tem;
-
- tem = w32_get_arg (alist, prop, xprop, xclass, type);
- if (EQ (tem, Qunbound))
- tem = deflt;
- x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
- return tem;
-}
-\f
-DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0,
- doc: /* Parse an X-style geometry string STRING.
-Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
-The properties returned may include `top', `left', `height', and `width'.
-The value of `left' or `top' may be an integer,
-or a list (+ N) meaning N pixels relative to top/left corner,
-or a list (- N) meaning -N pixels relative to bottom/right corner. */)
- (string)
- Lisp_Object string;
-{
- int geometry, x, y;
- unsigned int width, height;
- Lisp_Object result;
-
- CHECK_STRING (string);
-
- geometry = XParseGeometry ((char *) SDATA (string),
- &x, &y, &width, &height);
-
- result = Qnil;
- if (geometry & XValue)
- {
- Lisp_Object element;
-
- if (x >= 0 && (geometry & XNegative))
- element = Fcons (Qleft, Fcons (Qminus, Fcons (make_number (-x), Qnil)));
- else if (x < 0 && ! (geometry & XNegative))
- element = Fcons (Qleft, Fcons (Qplus, Fcons (make_number (x), Qnil)));
- else
- element = Fcons (Qleft, make_number (x));
- result = Fcons (element, result);
- }
-
- if (geometry & YValue)
- {
- Lisp_Object element;
-
- if (y >= 0 && (geometry & YNegative))
- element = Fcons (Qtop, Fcons (Qminus, Fcons (make_number (-y), Qnil)));
- else if (y < 0 && ! (geometry & YNegative))
- element = Fcons (Qtop, Fcons (Qplus, Fcons (make_number (y), Qnil)));
- else
- element = Fcons (Qtop, make_number (y));
- result = Fcons (element, result);
- }
-
- if (geometry & WidthValue)
- result = Fcons (Fcons (Qwidth, make_number (width)), result);
- if (geometry & HeightValue)
- result = Fcons (Fcons (Qheight, make_number (height)), result);
-
- return result;
-}
-
-/* Calculate the desired size and position of this window,
- and return the flags saying which aspects were specified.
-
- This function does not make the coordinates positive. */
-
-#define DEFAULT_ROWS 40
-#define DEFAULT_COLS 80
-
-static int
-x_figure_window_size (f, parms)
- struct frame *f;
- Lisp_Object parms;
-{
- register Lisp_Object tem0, tem1, tem2;
- long window_prompting = 0;
-
- /* Default values if we fall through.
- Actually, if that happens we should get
- window manager prompting. */
- SET_FRAME_WIDTH (f, DEFAULT_COLS);
- f->height = DEFAULT_ROWS;
- /* Window managers expect that if program-specified
- positions are not (0,0), they're intentional, not defaults. */
- f->output_data.w32->top_pos = 0;
- f->output_data.w32->left_pos = 0;
-
- /* Ensure that old new_width and new_height will not override the
- values set here. */
- FRAME_NEW_WIDTH (f) = 0;
- FRAME_NEW_HEIGHT (f) = 0;
-
- tem0 = w32_get_arg (parms, Qheight, 0, 0, RES_TYPE_NUMBER);
- tem1 = w32_get_arg (parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
- tem2 = w32_get_arg (parms, Quser_size, 0, 0, RES_TYPE_NUMBER);
- if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
- {
- if (!EQ (tem0, Qunbound))
- {
- CHECK_NUMBER (tem0);
- f->height = XINT (tem0);
- }
- if (!EQ (tem1, Qunbound))
- {
- CHECK_NUMBER (tem1);
- SET_FRAME_WIDTH (f, XINT (tem1));
- }
- if (!NILP (tem2) && !EQ (tem2, Qunbound))
- window_prompting |= USSize;
- else
- window_prompting |= PSize;
- }
-
- f->output_data.w32->vertical_scroll_bar_extra
- = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
- ? 0
- : FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0
- ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f)
- : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.w32->font)));
-
- x_compute_fringe_widths (f, 0);
-
- f->output_data.w32->pixel_width = CHAR_TO_PIXEL_WIDTH (f, f->width);
- f->output_data.w32->pixel_height = CHAR_TO_PIXEL_HEIGHT (f, f->height);
-
- tem0 = w32_get_arg (parms, Qtop, 0, 0, RES_TYPE_NUMBER);
- tem1 = w32_get_arg (parms, Qleft, 0, 0, RES_TYPE_NUMBER);
- tem2 = w32_get_arg (parms, Quser_position, 0, 0, RES_TYPE_NUMBER);
- if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
- {
- if (EQ (tem0, Qminus))
- {
- f->output_data.w32->top_pos = 0;
- window_prompting |= YNegative;
- }
- else if (CONSP (tem0) && EQ (XCAR (tem0), Qminus)
- && CONSP (XCDR (tem0))
- && INTEGERP (XCAR (XCDR (tem0))))
- {
- f->output_data.w32->top_pos = - XINT (XCAR (XCDR (tem0)));
- window_prompting |= YNegative;
- }
- else if (CONSP (tem0) && EQ (XCAR (tem0), Qplus)
- && CONSP (XCDR (tem0))
- && INTEGERP (XCAR (XCDR (tem0))))
- {
- f->output_data.w32->top_pos = XINT (XCAR (XCDR (tem0)));
- }
- else if (EQ (tem0, Qunbound))
- f->output_data.w32->top_pos = 0;
- else
- {
- CHECK_NUMBER (tem0);
- f->output_data.w32->top_pos = XINT (tem0);
- if (f->output_data.w32->top_pos < 0)
- window_prompting |= YNegative;
- }
-
- if (EQ (tem1, Qminus))
- {
- f->output_data.w32->left_pos = 0;
- window_prompting |= XNegative;
- }
- else if (CONSP (tem1) && EQ (XCAR (tem1), Qminus)
- && CONSP (XCDR (tem1))
- && INTEGERP (XCAR (XCDR (tem1))))
- {
- f->output_data.w32->left_pos = - XINT (XCAR (XCDR (tem1)));
- window_prompting |= XNegative;
- }
- else if (CONSP (tem1) && EQ (XCAR (tem1), Qplus)
- && CONSP (XCDR (tem1))
- && INTEGERP (XCAR (XCDR (tem1))))
- {
- f->output_data.w32->left_pos = XINT (XCAR (XCDR (tem1)));
- }
- else if (EQ (tem1, Qunbound))
- f->output_data.w32->left_pos = 0;
- else
- {
- CHECK_NUMBER (tem1);
- f->output_data.w32->left_pos = XINT (tem1);
- if (f->output_data.w32->left_pos < 0)
- window_prompting |= XNegative;
- }