extern void abort ();
#ifndef VMS
+#if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
+#include "bitmaps/gray.xbm"
+#else
#include <X11/bitmaps/gray>
+#endif
#else
#include "[.bitmaps]gray.xbm"
#endif
/* The class of this X application. */
#define EMACS_CLASS "Emacs"
-/* The name we're using for this X application. */
-Lisp_Object Vxrdb_name;
+#ifdef HAVE_X11R4
+#define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
+#else
+#define MAXREQUEST(dpy) ((dpy)->max_request_size)
+#endif
+
+/* The name we're using in resource queries. */
+Lisp_Object Vx_resource_name;
/* Title name and application name for X stuff. */
extern char *x_id_name;
Lisp_Object Qfont;
Lisp_Object Qforeground_color;
Lisp_Object Qgeometry;
-Lisp_Object Qicon;
+/* Lisp_Object Qicon; */
Lisp_Object Qicon_left;
Lisp_Object Qicon_top;
Lisp_Object Qicon_type;
/* The below are defined in frame.c. */
extern Lisp_Object Qheight, Qminibuffer, Qname, Qonly, Qwidth;
-extern Lisp_Object Qunsplittable, Qmenu_bar_lines, Qicon;
+extern Lisp_Object Qunsplittable, Qmenu_bar_lines;
extern Lisp_Object Vwindow_system_version;
-/* Mouse map for clicks in windows. */
-extern Lisp_Object Vglobal_mouse_map;
-
\f
/* Error if we are not connected to X. */
static void
/* Same here. */
Lisp_Object left, top;
- width = height = top = left = Qnil;
+ /* Record in these vectors all the parms specified. */
+ Lisp_Object *parms;
+ Lisp_Object *values;
+ int i;
+
+ i = 0;
+ for (tail = alist; CONSP (tail); tail = Fcdr (tail))
+ i++;
+
+ parms = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
+ values = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
+
+ /* Extract parm names and values into those vectors. */
+ i = 0;
for (tail = alist; CONSP (tail); tail = Fcdr (tail))
{
Lisp_Object elt, prop, val;
elt = Fcar (tail);
- prop = Fcar (elt);
- val = Fcdr (elt);
+ parms[i] = Fcar (elt);
+ values[i] = Fcdr (elt);
+ i++;
+ }
+
+ width = height = top = left = Qunbound;
+
+ /* Now process them in reverse of specified order. */
+ for (i--; i >= 0; i--)
+ {
+ Lisp_Object prop, val;
- /* Ignore all but the first set presented. You're supposed to
- be able to append two parameter lists and have the first
- shadow the second. */
- if (EQ (prop, Qwidth) && NILP (width))
+ prop = parms[i];
+ val = values[i];
+
+ if (EQ (prop, Qwidth))
width = val;
- else if (EQ (prop, Qheight) && NILP (height))
+ else if (EQ (prop, Qheight))
height = val;
- else if (EQ (prop, Qtop) && NILP (top))
+ else if (EQ (prop, Qtop))
top = val;
- else if (EQ (prop, Qleft) && NILP (left))
+ else if (EQ (prop, Qleft))
left = val;
else
{
}
}
- /* Don't call these unless they've changed; the window may not actually
- exist yet. */
+ /* Don't set these parameters these unless they've been explicitly
+ specified. The window might be mapped or resized while we're in
+ this function, and we don't want to override that unless the lisp
+ code has asked for it.
+
+ Don't set these parameters unless they actually differ from the
+ window's current parameters; the window may not actually exist
+ yet. */
{
Lisp_Object frame;
- if (NILP (width)) XSET (width, Lisp_Int, FRAME_WIDTH (f));
- if (NILP (height)) XSET (height, Lisp_Int, FRAME_HEIGHT (f));
-
- if (NILP (top)) XSET (top, Lisp_Int, f->display.x->top_pos);
- if (NILP (left)) XSET (left, Lisp_Int, f->display.x->left_pos);
-
XSET (frame, Lisp_Frame, f);
- if (XINT (width) != FRAME_WIDTH (f)
- || XINT (height) != FRAME_HEIGHT (f))
+ if ((NUMBERP (width) && XINT (width) != FRAME_WIDTH (f))
+ || (NUMBERP (height) && XINT (height) != FRAME_HEIGHT (f)))
Fset_frame_size (frame, width, height);
- if (XINT (left) != f->display.x->left_pos
- || XINT (top) != f->display.x->top_pos)
+ if ((NUMBERP (left) && XINT (left) != f->display.x->left_pos)
+ || (NUMBERP (top) && XINT (top) != f->display.x->top_pos))
Fset_frame_position (frame, left, top);
}
}
BLOCK_INPUT;
#ifdef HAVE_X11
- /* It's not okay to crash if the user selects a screwey cursor. */
+ /* It's not okay to crash if the user selects a screwy cursor. */
x_catch_errors ();
if (!EQ (Qnil, Vx_pointer_shape))
Lisp_Object window;
int n;
{
- for (; !NILP (window); window = XWINDOW (window)->next)
- {
- struct window *w = XWINDOW (window);
+ struct window *w = XWINDOW (window);
- XFASTINT (w->top) += n;
+ XFASTINT (w->top) += n;
+ XFASTINT (w->height) -= n;
- if (!NILP (w->vchild))
- x_set_menu_bar_lines_1 (w->vchild, n);
+ /* Handle just the top child in a vertical split. */
+ if (!NILP (w->vchild))
+ x_set_menu_bar_lines_1 (w->vchild, n);
- if (!NILP (w->hchild))
- x_set_menu_bar_lines_1 (w->hchild, n);
+ /* Adjust all children in a horizontal split. */
+ for (window = w->hchild; !NILP (window); window = w->next)
+ {
+ w = XWINDOW (window);
+ x_set_menu_bar_lines_1 (window, n);
}
}
FRAME_MENU_BAR_LINES (f) = nlines;
x_set_menu_bar_lines_1 (f->root_window, nlines - olines);
- /* Use FRAME_NEW_WIDTH, HEIGHT so as not to override a size change
- made by the user but not fully reflected in the Emacs frame object. */
- x_set_window_size (f,
- (FRAME_NEW_WIDTH (f)
- ? FRAME_NEW_WIDTH (f)
- : FRAME_WIDTH (f)),
- ((FRAME_NEW_HEIGHT (f)
- ? FRAME_NEW_HEIGHT (f)
- : FRAME_HEIGHT (f))
- + nlines - olines));
}
/* Change the name of frame F to ARG. If ARG is nil, set F's name to
/* Subroutines of creating an X frame. */
#ifdef HAVE_X11
+
+/* Make sure that Vx_resource_name is set to a reasonable value. */
+static void
+validate_x_resource_name ()
+{
+ if (! STRINGP (Vx_resource_name))
+ Vx_resource_name = make_string ("emacs", 5);
+}
+
+
extern char *x_get_string_resource ();
extern XrmDatabase x_load_resources ();
DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0,
"Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.\n\
-This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the\n\
-class, where INSTANCE is the name under which Emacs was invoked.\n\
+This uses `NAME.ATTRIBUTE' as the key and `Emacs.CLASS' as the\n\
+class, where INSTANCE is the name under which Emacs was invoked, or\n\
+the name specified by the `-name' or `-rn' command-line arguments.\n\
\n\
The optional arguments COMPONENT and SUBCLASS add to the key and the\n\
class, respectively. You must specify both of them or neither.\n\
-If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'\n\
+If you specify them, the key is `NAME.COMPONENT.ATTRIBUTE'\n\
and the class is `Emacs.CLASS.SUBCLASS'.")
(attribute, class, component, subclass)
Lisp_Object attribute, class, component, subclass;
if (NILP (component) != NILP (subclass))
error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
+ validate_x_resource_name ();
+
if (NILP (component))
{
/* Allocate space for the components, the dots which separate them,
and the final '\0'. */
- name_key = (char *) alloca (XSTRING (Vxrdb_name)->size
+ name_key = (char *) alloca (XSTRING (Vx_resource_name)->size
+ XSTRING (attribute)->size
+ 2);
class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
+ 2);
sprintf (name_key, "%s.%s",
- XSTRING (Vxrdb_name)->data,
+ XSTRING (Vx_resource_name)->data,
XSTRING (attribute)->data);
sprintf (class_key, "%s.%s",
EMACS_CLASS,
}
else
{
- name_key = (char *) alloca (XSTRING (Vxrdb_name)->size
+ name_key = (char *) alloca (XSTRING (Vx_resource_name)->size
+ XSTRING (component)->size
+ XSTRING (attribute)->size
+ 3);
+ 3);
sprintf (name_key, "%s.%s.%s",
- XSTRING (Vxrdb_name)->data,
+ XSTRING (Vx_resource_name)->data,
XSTRING (component)->data,
XSTRING (attribute)->data);
sprintf (class_key, "%s.%s.%s",
screen_visual, /* set in Fx_open_connection */
attribute_mask, &attributes);
- class_hints.res_name = (char *) XSTRING (Vxrdb_name)->data;
+ validate_x_resource_name ();
+ class_hints.res_name = (char *) XSTRING (Vx_resource_name)->data;
class_hints.res_class = EMACS_CLASS;
XSetClassHint (x_current_display, FRAME_X_WINDOW (f), &class_hints);
/* Extract the window parameters from the supplied values
that are needed to determine window geometry. */
- x_default_parameter (f, parms, Qfont,
- build_string
- /* If we use an XLFD name for this font, the lisp code
- knows how to find variants which are bold, italic,
- etcetera. */
- ("-*-fixed-*-*-*-*-*-120-*-*-c-*-iso8859-1"),
- "font", "Font", string);
+ {
+ Lisp_Object font;
+
+ font = x_get_arg (parms, Qfont, "font", "Font", string);
+ BLOCK_INPUT;
+ /* First, try whatever font the caller has specified. */
+ if (STRINGP (font))
+ font = x_new_font (f, XSTRING (font)->data);
+ /* Try out a font which we hope has bold and italic variations. */
+ if (!STRINGP (font))
+ font = x_new_font (f, "-misc-fixed-medium-r-normal-*-*-120-*-*-c-*-iso8859-1");
+ if (! STRINGP (font))
+ font = x_new_font (f, "-*-*-medium-r-normal-*-*-120-*-*-c-*-iso8859-1");
+ if (! STRINGP (font))
+ /* This was formerly the first thing tried, but it finds too many fonts
+ and takes too long. */
+ font = x_new_font (f, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
+ /* If those didn't work, look for something which will at least work. */
+ if (! STRINGP (font))
+ font = x_new_font (f, "-*-fixed-*-*-*-*-*-120-*-*-c-*-iso8859-1");
+ UNBLOCK_INPUT;
+ if (! STRINGP (font))
+ font = build_string ("fixed");
+
+ x_default_parameter (f, parms, Qfont, font,
+ "font", "Font", string);
+ }
x_default_parameter (f, parms, Qborder_width, make_number (2),
"borderwidth", "BorderWidth", number);
- /* This defaults to 2 in order to match xterm. */
+ /* This defaults to 2 in order to match xterm. We recognize either
+ internalBorderWidth or internalBorder (which is what xterm calls
+ it). */
+ if (NILP (Fassq (Qinternal_border_width, parms)))
+ {
+ Lisp_Object value;
+
+ value = x_get_arg (parms, Qinternal_border_width,
+ "internalBorder", "BorderWidth", number);
+ if (! EQ (value, Qunbound))
+ parms = Fcons (Fcons (Qinternal_border_width, value),
+ parms);
+ }
x_default_parameter (f, parms, Qinternal_border_width, make_number (2),
"internalBorderWidth", "BorderWidth", number);
x_default_parameter (f, parms, Qvertical_scroll_bars, Qt,
f->display.x = (struct x_display *) xmalloc (sizeof (struct x_display));
bzero (f->display.x, sizeof (struct x_display));
- /* Some temprorary default values for height and width. */
+ /* Some temporary default values for height and width. */
width = 80;
height = 40;
f->display.x->left_pos = -1;
FRAME_PTR f = NILP (frame) ? selected_frame : XFRAME (frame);
int face_id = face_name_id_number (f, face);
- if (face_id < 0 || face_id >= FRAME_N_FACES (f)
- || FRAME_FACES (f) [face_id] == 0)
+ if (face_id < 0 || face_id >= FRAME_N_PARAM_FACES (f)
+ || FRAME_PARAM_FACES (f) [face_id] == 0)
size_ref = f->display.x->font;
else
{
- size_ref = FRAME_FACES (f) [face_id]->font;
+ size_ref = FRAME_PARAM_FACES (f) [face_id]->font;
if (size_ref == (XFontStruct *) (~0))
size_ref = f->display.x->font;
}
&info); /* info_return */
UNBLOCK_INPUT;
- {
- Lisp_Object *tail;
- int i;
-
- list = Qnil;
- tail = &list;
- for (i = 0; i < num_fonts; i++)
- if (! size_ref
- || same_size_fonts (&info[i], size_ref))
- {
- *tail = Fcons (build_string (names[i]), Qnil);
- tail = &XCONS (*tail)->cdr;
- }
+ list = Qnil;
- XFreeFontInfo (names, info, num_fonts);
- }
+ if (names)
+ {
+ Lisp_Object *tail;
+ int i;
+
+ tail = &list;
+ for (i = 0; i < num_fonts; i++)
+ if (! size_ref
+ || same_size_fonts (&info[i], size_ref))
+ {
+ *tail = Fcons (build_string (names[i]), Qnil);
+ tail = &XCONS (*tail)->cdr;
+ }
+
+ XFreeFontInfo (names, info, num_fonts);
+ }
return list;
}
return make_number (DisplayCells (dpy, DefaultScreen (dpy)));
}
+DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
+ Sx_server_max_request_size,
+ 0, 1, 0,
+ "Returns the maximum request size of the X server FRAME is using.")
+ (frame)
+ Lisp_Object frame;
+{
+ Display *dpy = x_current_display;
+ check_x ();
+ return make_number (MAXREQUEST (dpy));
+}
+
DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
"Returns the vendor ID string of the X server FRAME is on.")
(frame)
}
}
-/* Erase the top horzontal lines of the contour, and then extend
+/* Erase the top horizontal lines of the contour, and then extend
the contour upwards. */
static void
mod = Fcar (rest);
CHECK_STRING (mod, 3);
modifier_list[i] = XStringToKeysym ((char *) XSTRING (mod)->data);
+#ifndef HAVE_X11R5
+ if (modifier_list[i] == NoSymbol
+ || !(IsModifierKey (modifier_list[i])
+ || ((unsigned)(modifier_list[i]) == XK_Mode_switch)
+ || ((unsigned)(modifier_list[i]) == XK_Num_Lock)))
+#else
if (modifier_list[i] == NoSymbol
|| !IsModifierKey (modifier_list[i]))
+#endif
error ("Element is not a modifier keysym");
i++;
}
DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
1, 2, 0, "Open a connection to an X server.\n\
-DISPLAY is the name of the display to connect to. Optional second\n\
-arg XRM_STRING is a string of resources in xrdb format.")
+DISPLAY is the name of the display to connect to.\n\
+Optional second arg XRM_STRING is a string of resources in xrdb format.")
(display, xrm_string)
Lisp_Object display, xrm_string;
{
CHECK_STRING (display, 0);
if (x_current_display != 0)
error ("X server connection is already initialized");
+ if (! NILP (xrm_string))
+ CHECK_STRING (xrm_string, 1);
/* This is what opens the connection and sets x_current_display.
This also initializes many symbols, such as those used for input. */
#ifdef HAVE_X11
XFASTINT (Vwindow_system_version) = 11;
- if (!EQ (xrm_string, Qnil))
- {
- CHECK_STRING (xrm_string, 1);
- xrm_option = (unsigned char *) XSTRING (xrm_string)->data;
- }
+ if (! NILP (xrm_string))
+ xrm_option = (unsigned char *) XSTRING (xrm_string)->data;
else
xrm_option = (unsigned char *) 0;
- xrdb = x_load_resources (x_current_display, xrm_option, EMACS_CLASS);
-#if defined (HAVE_X11R5) && ! defined (NO_XRM_SET_DATBASE)
+
+ validate_x_resource_name ();
+
+ BLOCK_INPUT;
+ xrdb = x_load_resources (x_current_display, xrm_option,
+ (char *) XSTRING (Vx_resource_name)->data,
+ EMACS_CLASS);
+ UNBLOCK_INPUT;
+#if defined (HAVE_X11R5)
XrmSetDatabase (x_current_display, xrdb);
#else
x_current_display->db = xrdb;
#endif
- /* Make a version of Vinvocation_name suitable for use in xrdb
- queries - i.e. containing no dots or asterisks. */
- Vxrdb_name = Fcopy_sequence (Vinvocation_name);
- {
- int i;
- int len = XSTRING (Vxrdb_name)->size;
- char *data = XSTRING (Vxrdb_name)->data;
-
- for (i = 0; i < len; i++)
- if (data[i] == '.' || data[i] == '*')
- data[i] = '-';
- }
-
x_screen = DefaultScreenOfDisplay (x_current_display);
screen_visual = select_visual (x_screen, &n_planes);
staticpro (&Qforeground_color);
Qgeometry = intern ("geometry");
staticpro (&Qgeometry);
- Qicon = intern ("icon");
- staticpro (&Qicon);
Qicon_left = intern ("icon-left");
staticpro (&Qicon_left);
Qicon_top = intern ("icon-top");
init_x_parm_symbols ();
DEFVAR_INT ("mouse-buffer-offset", &mouse_buffer_offset,
- "The buffer offset of the character under the pointer.");
+ "The buffer offset of the character under the pointer.");
mouse_buffer_offset = 0;
DEFVAR_INT ("x-pointer-shape", &Vx_pointer_shape,
- "The shape of the pointer when over text.\n\
+ "The shape of the pointer when over text.\n\
Changing the value does not affect existing frames\n\
unless you set the mouse color.");
Vx_pointer_shape = Qnil;
- staticpro (&Vxrdb_name);
+ DEFVAR_LISP ("x-resource-name", &Vx_resource_name,
+ "The name Emacs uses to look up X resources; for internal use only.\n\
+`x-get-resource' uses this as the first component of the instance name\n\
+when requesting resource values.\n\
+Emacs initially sets `x-resource-name' to the name under which Emacs\n\
+was invoked, or to the value specified with the `-name' or `-rn'\n\
+switches, if present.");
+ Vx_resource_name = Qnil;
+ staticpro (&Vx_resource_name);
#if 0
DEFVAR_INT ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
defsubr (&Sx_display_color_p);
defsubr (&Sx_list_fonts);
defsubr (&Sx_color_defined_p);
+ defsubr (&Sx_server_max_request_size);
defsubr (&Sx_server_vendor);
defsubr (&Sx_server_version);
defsubr (&Sx_display_pixel_width);