(line-number-display-limit): Doc fix.
[bpt/emacs.git] / src / xfns.c
index 603d2a8..5a25161 100644 (file)
@@ -1,5 +1,5 @@
 /* Functions for the X window system.
-   Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996 Free Software Foundation.
+   Copyright (C) 1989, 92, 93, 94, 95, 96, 1997 Free Software Foundation.
 
 This file is part of GNU Emacs.
 
@@ -36,7 +36,7 @@ Boston, MA 02111-1307, USA.  */
 #include "dispextern.h"
 #include "keyboard.h"
 #include "blockinput.h"
-#include <paths.h>
+#include <epaths.h>
 #include "charset.h"
 #include "fontset.h"
 
@@ -191,6 +191,7 @@ Lisp_Object Qleft;
 Lisp_Object Qright;
 Lisp_Object Qmouse_color;
 Lisp_Object Qnone;
+Lisp_Object Qouter_window_id;
 Lisp_Object Qparent_id;
 Lisp_Object Qscroll_bar_width;
 Lisp_Object Qsuppress_icon;
@@ -211,6 +212,7 @@ extern Lisp_Object Qunsplittable, Qmenu_bar_lines, Qbuffer_predicate, Qtitle;
 
 extern Lisp_Object Vwindow_system_version;
 
+Lisp_Object Qface_set_after_frame_default;
 \f
 /* Error if we are not connected to X.  */
 void
@@ -260,7 +262,8 @@ check_x_display_info (frame)
 {
   if (NILP (frame))
     {
-      if (FRAME_X_P (selected_frame))
+      if (FRAME_X_P (selected_frame)
+         && FRAME_LIVE_P (selected_frame))
        return FRAME_X_DISPLAY_INFO (selected_frame);
       else if (x_display_list != 0)
        return x_display_list;
@@ -586,6 +589,9 @@ x_create_bitmap_from_file (f, file)
   fd = openp (Vx_bitmap_file_path, file, "", &found, 0);
   if (fd < 0)
     return -1;
+  /* XReadBitmapFile won't handle magic file names.  */
+  if (fd == 0)
+    return -1;
   close (fd);
 
   filename = (char *) XSTRING (found)->data;
@@ -598,7 +604,8 @@ x_create_bitmap_from_file (f, file)
   id = x_allocate_bitmap_record (f);
   dpyinfo->bitmaps[id - 1].pixmap = bitmap;
   dpyinfo->bitmaps[id - 1].refcount = 1;
-  dpyinfo->bitmaps[id - 1].file = (char *) xmalloc (XSTRING (file)->size + 1);
+  dpyinfo->bitmaps[id - 1].file
+    = (char *) xmalloc (STRING_BYTES (XSTRING (file)) + 1);
   dpyinfo->bitmaps[id - 1].depth = 1;
   dpyinfo->bitmaps[id - 1].height = height;
   dpyinfo->bitmaps[id - 1].width = width;
@@ -609,7 +616,7 @@ x_create_bitmap_from_file (f, file)
 
 /* Remove reference to bitmap with id number ID.  */
 
-int
+void
 x_destroy_bitmap (f, id)
      FRAME_PTR f;
      int id;
@@ -711,6 +718,7 @@ static struct x_frame_parm_table x_frame_parms[] =
 /* Attach the `x-frame-parameter' properties to
    the Lisp symbol names of parameters relevant to X.  */
 
+void
 init_x_parm_symbols ()
 {
   int i;
@@ -720,7 +728,7 @@ init_x_parm_symbols ()
          make_number (i));
 }
 \f
-/* Change the parameters of FRAME as specified by ALIST.
+/* Change the parameters of frame F as specified by ALIST.
    If a parameter is not specially recognized, do nothing;
    otherwise call the `x_set_...' function for that parameter.  */
 
@@ -749,6 +757,8 @@ x_set_frame_parameters (f, alist)
   int left_no_change = 0, top_no_change = 0;
   int icon_left_no_change = 0, icon_top_no_change = 0;
 
+  struct gcpro gcpro1, gcpro2;
+
   i = 0;
   for (tail = alist; CONSP (tail); tail = Fcdr (tail))
     i++;
@@ -768,7 +778,15 @@ x_set_frame_parameters (f, alist)
       values[i] = Fcdr (elt);
       i++;
     }
+  /* TAIL and ALIST are not used again below here.  */
+  alist = tail = Qnil;
+
+  GCPRO2 (*parms, *values);
+  gcpro1.nvars = i;
+  gcpro2.nvars = i;
 
+  /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP,
+     because their values appear in VALUES and strings are not valid.  */
   top = left = Qunbound;
   icon_left = icon_top = Qunbound;
 
@@ -940,6 +958,8 @@ x_set_frame_parameters (f, alist)
        && ! (icon_left_no_change && icon_top_no_change))
       x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top));
   }
+
+  UNGCPRO;
 }
 
 /* Store the screen positions of frame F into XPTR and YPTR.
@@ -968,7 +988,8 @@ x_real_positions (f, xptr, yptr)
 
   while (1)
     {
-      x_catch_errors (FRAME_X_DISPLAY (f));
+      int count = x_catch_errors (FRAME_X_DISPLAY (f));
+      Window outer_window;
 
       XQueryTree (FRAME_X_DISPLAY (f), outer, &tmp_root_window,
                  &f->output_data.x->parent_desc,
@@ -980,28 +1001,21 @@ x_real_positions (f, xptr, yptr)
       /* Find the position of the outside upper-left corner of
         the inner window, with respect to the outer window.  */
       if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
-       {
-         XTranslateCoordinates (FRAME_X_DISPLAY (f),
+       outer_window = f->output_data.x->parent_desc;
+      else
+       outer_window = outer;
 
-                                /* From-window, to-window.  */
-#ifdef USE_X_TOOLKIT
-                                XtWindow (f->output_data.x->widget),
-#else
-                                f->output_data.x->window_desc,
-#endif
-                                f->output_data.x->parent_desc,
+      XTranslateCoordinates (FRAME_X_DISPLAY (f),
 
-                                /* From-position, to-position.  */
-                                0, 0, &win_x, &win_y,
+                            /* From-window, to-window.  */
+                            outer_window,
+                            FRAME_X_DISPLAY_INFO (f)->root_window,
 
-                                /* Child of win.  */
-                                &child);
+                            /* From-position, to-position.  */
+                            0, 0, &win_x, &win_y,
 
-#if 0  /* The values seem to be right without this and wrong with.  */
-         win_x += f->output_data.x->border_width;
-         win_y += f->output_data.x->border_width;
-#endif
-       }
+                            /* Child of win.  */
+                            &child);
 
       /* It is possible for the window returned by the XQueryNotify
         to become invalid by the time we call XTranslateCoordinates.
@@ -1010,15 +1024,15 @@ x_real_positions (f, xptr, yptr)
         Detect that and try the whole thing over.  */
       if (! x_had_errors_p (FRAME_X_DISPLAY (f)))
        {
-         x_uncatch_errors (FRAME_X_DISPLAY (f));
+         x_uncatch_errors (FRAME_X_DISPLAY (f), count);
          break;
        }
 
-      x_uncatch_errors (FRAME_X_DISPLAY (f));
+      x_uncatch_errors (FRAME_X_DISPLAY (f), count);
     }
 
-  *xptr = f->output_data.x->left_pos - win_x;
-  *yptr = f->output_data.x->top_pos - win_y;
+  *xptr = win_x - f->output_data.x->border_width;
+  *yptr = win_y - f->output_data.x->border_width;
 }
 
 /* Insert a description of internally-recorded parameters of frame X
@@ -1027,6 +1041,7 @@ x_real_positions (f, xptr, yptr)
    and whose values are not correctly recorded in the frame's
    param_alist need to be considered here.  */
 
+void
 x_report_frame_params (f, alistptr)
      struct frame *f;
      Lisp_Object *alistptr;
@@ -1055,6 +1070,9 @@ x_report_frame_params (f, alistptr)
   sprintf (buf, "%ld", (long) FRAME_X_WINDOW (f));
   store_in_alist (alistptr, Qwindow_id,
                   build_string (buf));
+  sprintf (buf, "%ld", (long) FRAME_OUTER_WINDOW (f));
+  store_in_alist (alistptr, Qouter_window_id,
+                  build_string (buf));
   store_in_alist (alistptr, Qicon_name, f->icon_name);
   FRAME_SAMPLE_VISIBILITY (f);
   store_in_alist (alistptr, Qvisibility,
@@ -1063,9 +1081,11 @@ x_report_frame_params (f, alistptr)
   store_in_alist (alistptr, Qdisplay,
                  XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->car);
 
-  store_in_alist (alistptr, Qparent_id,
-                 (f->output_data.x->parent_desc == FRAME_X_DISPLAY_INFO (f)->root_window
-                  ? Qnil : f->output_data.x->parent_desc));
+  if (f->output_data.x->parent_desc == FRAME_X_DISPLAY_INFO (f)->root_window)
+    tem = Qnil;
+  else
+    XSETFASTINT (tem, f->output_data.x->parent_desc);
+  store_in_alist (alistptr, Qparent_id, tem);
 }
 \f
 
@@ -1204,8 +1224,15 @@ x_set_foreground_color (f, arg, oldval)
      struct frame *f;
      Lisp_Object arg, oldval;
 {
-  f->output_data.x->foreground_pixel
+  unsigned long pixel
     = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
+
+  if (f->output_data.x->foreground_pixel != f->output_data.x->mouse_pixel
+      && f->output_data.x->foreground_pixel != f->output_data.x->cursor_pixel
+      && f->output_data.x->foreground_pixel != f->output_data.x->cursor_foreground_pixel)
+    unload_color (f, f->output_data.x->foreground_pixel);
+  f->output_data.x->foreground_pixel = pixel;
+
   if (FRAME_X_WINDOW (f) != 0)
     {
       BLOCK_INPUT;
@@ -1228,9 +1255,15 @@ x_set_background_color (f, arg, oldval)
   Pixmap temp;
   int mask;
 
-  f->output_data.x->background_pixel
+  unsigned long pixel
     = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
 
+  if (f->output_data.x->background_pixel != f->output_data.x->mouse_pixel
+      && f->output_data.x->background_pixel != f->output_data.x->cursor_pixel
+      && f->output_data.x->background_pixel != f->output_data.x->cursor_foreground_pixel)
+    unload_color (f, f->output_data.x->background_pixel);
+  f->output_data.x->background_pixel = pixel;
+
   if (FRAME_X_WINDOW (f) != 0)
     {
       BLOCK_INPUT;
@@ -1266,21 +1299,30 @@ x_set_mouse_color (f, arg, oldval)
      Lisp_Object arg, oldval;
 {
   Cursor cursor, nontext_cursor, mode_cursor, cross_cursor;
+  int count;
   int mask_color;
-
+  unsigned long pixel = f->output_data.x->mouse_pixel;
+  
   if (!EQ (Qnil, arg))
-    f->output_data.x->mouse_pixel
-      = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
+    pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
+
   mask_color = f->output_data.x->background_pixel;
                                /* No invisible pointers.  */
-  if (mask_color == f->output_data.x->mouse_pixel
-       && mask_color == f->output_data.x->background_pixel)
-    f->output_data.x->mouse_pixel = f->output_data.x->foreground_pixel;
+  if (mask_color == pixel
+      && mask_color == f->output_data.x->background_pixel)
+    pixel = f->output_data.x->foreground_pixel;
+
+  if (f->output_data.x->background_pixel != f->output_data.x->mouse_pixel
+      && f->output_data.x->foreground_pixel != f->output_data.x->mouse_pixel
+      && f->output_data.x->cursor_pixel != f->output_data.x->mouse_pixel
+      && f->output_data.x->cursor_foreground_pixel != f->output_data.x->mouse_pixel)
+    unload_color (f, f->output_data.x->mouse_pixel);
+  f->output_data.x->mouse_pixel = pixel;
 
   BLOCK_INPUT;
 
   /* It's not okay to crash if the user selects a screwy cursor.  */
-  x_catch_errors (FRAME_X_DISPLAY (f));
+  count = x_catch_errors (FRAME_X_DISPLAY (f));
 
   if (!EQ (Qnil, Vx_pointer_shape))
     {
@@ -1323,7 +1365,7 @@ x_set_mouse_color (f, arg, oldval)
 
   /* Check and report errors with the above calls.  */
   x_check_errors (FRAME_X_DISPLAY (f), "can't set cursor shape: %s");
-  x_uncatch_errors (FRAME_X_DISPLAY (f));
+  x_uncatch_errors (FRAME_X_DISPLAY (f), count);
 
   {
     XColor fore_color, back_color;
@@ -1380,24 +1422,37 @@ x_set_cursor_color (f, arg, oldval)
      struct frame *f;
      Lisp_Object arg, oldval;
 {
-  unsigned long fore_pixel;
+  unsigned long fore_pixel, pixel;
 
   if (!EQ (Vx_cursor_fore_pixel, Qnil))
     fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
                                 WHITE_PIX_DEFAULT (f));
   else
     fore_pixel = f->output_data.x->background_pixel;
-  f->output_data.x->cursor_pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
-  
+  pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
+
   /* Make sure that the cursor color differs from the background color.  */
-  if (f->output_data.x->cursor_pixel == f->output_data.x->background_pixel)
+  if (pixel == f->output_data.x->background_pixel)
     {
-      f->output_data.x->cursor_pixel = f->output_data.x->mouse_pixel;
-      if (f->output_data.x->cursor_pixel == fore_pixel)
+      pixel = f->output_data.x->mouse_pixel;
+      if (pixel == fore_pixel)
        fore_pixel = f->output_data.x->background_pixel;
     }
+
+  if (f->output_data.x->background_pixel != f->output_data.x->cursor_foreground_pixel
+      && f->output_data.x->foreground_pixel != f->output_data.x->cursor_foreground_pixel
+      && f->output_data.x->mouse_pixel != f->output_data.x->cursor_foreground_pixel
+      && f->output_data.x->cursor_pixel != f->output_data.x->cursor_foreground_pixel)
+    unload_color (f, f->output_data.x->cursor_foreground_pixel);
   f->output_data.x->cursor_foreground_pixel = fore_pixel;
 
+  if (f->output_data.x->background_pixel != f->output_data.x->cursor_pixel
+      && f->output_data.x->foreground_pixel != f->output_data.x->cursor_pixel
+      && f->output_data.x->mouse_pixel != f->output_data.x->cursor_pixel
+      && f->output_data.x->cursor_foreground_pixel != f->output_data.x->cursor_pixel)
+    unload_color (f, f->output_data.x->cursor_pixel);
+  f->output_data.x->cursor_pixel = pixel;
+
   if (FRAME_X_WINDOW (f) != 0)
     {
       BLOCK_INPUT;
@@ -1446,10 +1501,12 @@ x_set_border_color (f, arg, oldval)
    Note that this does not fully take effect if done before
    F has an x-window.  */
 
+void
 x_set_border_pixel (f, pix)
      struct frame *f;
      int pix;
 {
+  unload_color (f, f->output_data.x->border_pixel);
   f->output_data.x->border_pixel = pix;
 
   if (FRAME_X_WINDOW (f) != 0 && f->output_data.x->border_width > 0)
@@ -1584,8 +1641,6 @@ x_set_icon_name (f, arg, oldval)
   UNBLOCK_INPUT;
 }
 \f
-extern Lisp_Object x_new_font ();
-
 void
 x_set_font (f, arg, oldval)
      struct frame *f;
@@ -1593,10 +1648,11 @@ x_set_font (f, arg, oldval)
 {
   Lisp_Object result;
   Lisp_Object fontset_name;
+  Lisp_Object frame;
 
   CHECK_STRING (arg, 1);
 
-  fontset_name = Fquery_fontset (arg);
+  fontset_name = Fquery_fontset (arg, Qnil);
 
   BLOCK_INPUT;
   result = (STRINGP (fontset_name)
@@ -1607,7 +1663,7 @@ x_set_font (f, arg, oldval)
   if (EQ (result, Qnil))
     error ("Font `%s' is not defined", XSTRING (arg)->data);
   else if (EQ (result, Qt))
-    error ("the characters of the given font have varying widths");
+    error ("The characters of the given font have varying widths");
   else if (STRINGP (result))
     {
       recompute_basic_faces (f);
@@ -1615,6 +1671,9 @@ x_set_font (f, arg, oldval)
     }
   else
     abort ();
+
+  XSETFRAME (frame, f);
+  call1 (Qface_set_after_frame_default, frame);
 }
 
 void
@@ -1648,8 +1707,7 @@ x_set_internal_border_width (f, arg, oldval)
 
 #ifdef USE_X_TOOLKIT
   if (f->output_data.x->edit_widget)
-    widget_store_internal_border (f->output_data.x->edit_widget,
-                                 f->output_data.x->internal_border_width);
+    widget_store_internal_border (f->output_data.x->edit_widget);
 #endif
 
   if (f->output_data.x->internal_border_width == old)
@@ -1726,6 +1784,9 @@ x_set_menu_bar_lines (f, value, oldval)
   else
     nlines = 0;
 
+  /* Make sure we redisplay all windows in this frame.  */
+  windows_or_buffers_changed++;
+
 #ifdef USE_X_TOOLKIT
   FRAME_MENU_BAR_LINES (f) = 0;
   if (nlines)
@@ -1815,14 +1876,14 @@ x_set_name (f, name, explicit)
        text.value = XSTRING (name)->data;
        text.encoding = XA_STRING;
        text.format = 8;
-       text.nitems = XSTRING (name)->size;
+       text.nitems = STRING_BYTES (XSTRING (name));
 
        icon_name = (!NILP (f->icon_name) ? f->icon_name : name);
 
        icon.value = XSTRING (icon_name)->data;
        icon.encoding = XA_STRING;
        icon.format = 8;
-       icon.nitems = XSTRING (icon_name)->size;
+       icon.nitems = STRING_BYTES (XSTRING (icon_name));
 #ifdef USE_X_TOOLKIT
        XSetWMName (FRAME_X_DISPLAY (f),
                    XtWindow (f->output_data.x->widget), &text);
@@ -1905,14 +1966,14 @@ x_set_title (f, name)
        text.value = XSTRING (name)->data;
        text.encoding = XA_STRING;
        text.format = 8;
-       text.nitems = XSTRING (name)->size;
+       text.nitems = STRING_BYTES (XSTRING (name));
 
        icon_name = (!NILP (f->icon_name) ? f->icon_name : name);
 
        icon.value = XSTRING (icon_name)->data;
        icon.encoding = XA_STRING;
        icon.format = 8;
-       icon.nitems = XSTRING (icon_name)->size;
+       icon.nitems = STRING_BYTES (XSTRING (icon_name));
 #ifdef USE_X_TOOLKIT
        XSetWMName (FRAME_X_DISPLAY (f),
                    XtWindow (f->output_data.x->widget), &text);
@@ -1988,20 +2049,25 @@ x_set_scroll_bar_width (f, arg, oldval)
      struct frame *f;
      Lisp_Object arg, oldval;
 {
+  int wid = FONT_WIDTH (f->output_data.x->font);
+
   if (NILP (arg))
     {
+      /* Make the actual width at least 14 pixels
+        and a multiple of a character width.  */
+      FRAME_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
+      /* Use all of that space (aside from required margins)
+        for the scroll bar.  */
       FRAME_SCROLL_BAR_PIXEL_WIDTH (f) = 0;
-      FRAME_SCROLL_BAR_COLS (f) = 3;
+
       if (FRAME_X_WINDOW (f))
         x_set_window_size (f, 0, FRAME_WIDTH (f), FRAME_HEIGHT (f));
     }
   else if (INTEGERP (arg) && XINT (arg) > 0
           && XFASTINT (arg) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f))
     {
-      int wid = FONT_WIDTH (f->output_data.x->font);
-
-      if (XFASTINT (arg) < 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM)
-       Fsignal (Qargs_out_of_range, Fcons (arg, Qnil));
+      if (XFASTINT (arg) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM)
+       XSETINT (arg, 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM + 1);
 
       FRAME_SCROLL_BAR_PIXEL_WIDTH (f) = XFASTINT (arg);
       FRAME_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + wid-1) / wid;
@@ -2037,7 +2103,7 @@ validate_x_resource_name ()
       unsigned char *p = XSTRING (Vx_resource_name)->data;
       int i;
 
-      len = XSTRING (Vx_resource_name)->size;
+      len = STRING_BYTES (XSTRING (Vx_resource_name));
 
       /* Only letters, digits, - and _ are valid in resource names.
         Count the valid characters and count the invalid ones.  */
@@ -2121,16 +2187,16 @@ and the class is `Emacs.CLASS.SUBCLASS'.")
 
   /* 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 (XSTRING (Vx_resource_name)->size
+  name_key = (char *) alloca (STRING_BYTES (XSTRING (Vx_resource_name))
                              + (STRINGP (component)
-                                ? XSTRING (component)->size : 0)
-                             + XSTRING (attribute)->size
+                                ? STRING_BYTES (XSTRING (component)) : 0)
+                             + STRING_BYTES (XSTRING (attribute))
                              + 3);
 
-  class_key = (char *) alloca (XSTRING (Vx_resource_class)->size
-                              + XSTRING (class)->size
+  class_key = (char *) alloca (STRING_BYTES (XSTRING (Vx_resource_class))
+                              + STRING_BYTES (XSTRING (class))
                               + (STRINGP (subclass)
-                                 ? XSTRING (subclass)->size : 0)
+                                 ? STRING_BYTES (XSTRING (subclass)) : 0)
                               + 3);
 
   /* Start with emacs.FRAMENAME for the name (the specific one)
@@ -2162,6 +2228,73 @@ and the class is `Emacs.CLASS.SUBCLASS'.")
     return Qnil;
 }
 
+/* Get an X resource, like Fx_get_resource, but for display DPYINFO.  */
+
+static Lisp_Object
+display_x_get_resource (dpyinfo, attribute, class, component, subclass)
+     struct x_display_info *dpyinfo;
+     Lisp_Object attribute, class, component, subclass;
+{
+  register char *value;
+  char *name_key;
+  char *class_key;
+
+  check_x ();
+
+  CHECK_STRING (attribute, 0);
+  CHECK_STRING (class, 0);
+
+  if (!NILP (component))
+    CHECK_STRING (component, 1);
+  if (!NILP (subclass))
+    CHECK_STRING (subclass, 2);
+  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 (STRING_BYTES (XSTRING (Vx_resource_name))
+                             + (STRINGP (component)
+                                ? STRING_BYTES (XSTRING (component)) : 0)
+                             + STRING_BYTES (XSTRING (attribute))
+                             + 3);
+
+  class_key = (char *) alloca (STRING_BYTES (XSTRING (Vx_resource_class))
+                              + STRING_BYTES (XSTRING (class))
+                              + (STRINGP (subclass)
+                                 ? STRING_BYTES (XSTRING (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, XSTRING (Vx_resource_name)->data);
+  strcpy (class_key, XSTRING (Vx_resource_class)->data);
+
+  strcat (class_key, ".");
+  strcat (class_key, XSTRING (class)->data);
+
+  if (!NILP (component))
+    {
+      strcat (class_key, ".");
+      strcat (class_key, XSTRING (subclass)->data);
+
+      strcat (name_key, ".");
+      strcat (name_key, XSTRING (component)->data);
+    }
+
+  strcat (name_key, ".");
+  strcat (name_key, XSTRING (attribute)->data);
+
+  value = x_get_string_resource (dpyinfo->xrdb, name_key, class_key);
+
+  if (value != (char *) 0)
+    return build_string (value);
+  else
+    return Qnil;
+}
+
 /* Used when C code wants a resource value.  */
 
 char *
@@ -2174,7 +2307,7 @@ x_get_resource_string (attribute, class)
 
   /* Allocate space for the components, the dots which separate them,
      and the final '\0'.  */
-  name_key = (char *) alloca (XSTRING (Vinvocation_name)->size
+  name_key = (char *) alloca (STRING_BYTES (XSTRING (Vinvocation_name))
                              + strlen (attribute) + 2);
   class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
                               + strlen (class) + 2);
@@ -2206,7 +2339,8 @@ enum resource_types
    and don't let it get stored in any Lisp-visible variables!  */
 
 static Lisp_Object
-x_get_arg (alist, param, attribute, class, type)
+x_get_arg (dpyinfo, alist, param, attribute, class, type)
+     struct x_display_info *dpyinfo;
      Lisp_Object alist, param;
      char *attribute;
      char *class;
@@ -2222,9 +2356,10 @@ x_get_arg (alist, param, attribute, class, type)
 
       if (attribute)
        {
-         tem = Fx_get_resource (build_string (attribute),
-                                build_string (class),
-                                Qnil, Qnil);
+         tem = display_x_get_resource (dpyinfo,
+                                       build_string (attribute),
+                                       build_string (class),
+                                       Qnil, Qnil);
 
          if (NILP (tem))
            return Qunbound;
@@ -2283,7 +2418,8 @@ x_get_and_record_arg (f, alist, param, attribute, class, type)
 {
   Lisp_Object value;
 
-  value = x_get_arg (alist, param, attribute, class, type);
+  value = x_get_arg (FRAME_X_DISPLAY_INFO (f), alist, param,
+                    attribute, class, type);
   if (! NILP (value))
     store_frame_param (f, param, value);
 
@@ -2291,8 +2427,8 @@ x_get_and_record_arg (f, alist, param, attribute, class, type)
 }
 
 /* Record in frame F the specified or default value according to ALIST
-   of the parameter named PARAM (a Lisp symbol).
-   If no value is specified for PARAM, look for an X default for XPROP
+   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.  */
 
@@ -2308,7 +2444,7 @@ x_default_parameter (f, alist, prop, deflt, xprop, xclass, type)
 {
   Lisp_Object tem;
 
-  tem = x_get_arg (alist, prop, xprop, xclass, type);
+  tem = x_get_arg (FRAME_X_DISPLAY_INFO (f), alist, prop, xprop, xclass, type);
   if (EQ (tem, Qunbound))
     tem = deflt;
   x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
@@ -2391,6 +2527,7 @@ x_figure_window_size (f, parms)
   int height, width, left, top;
   register int geometry;
   long window_prompting = 0;
+  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
 
   /* Default values if we fall through.
      Actually, if that happens we should get
@@ -2402,9 +2539,9 @@ x_figure_window_size (f, parms)
   f->output_data.x->top_pos = 0;
   f->output_data.x->left_pos = 0;
 
-  tem0 = x_get_arg (parms, Qheight, 0, 0, number);
-  tem1 = x_get_arg (parms, Qwidth, 0, 0, number);
-  tem2 = x_get_arg (parms, Quser_size, 0, 0, number);
+  tem0 = x_get_arg (dpyinfo, parms, Qheight, 0, 0, number);
+  tem1 = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, number);
+  tem2 = x_get_arg (dpyinfo, parms, Quser_size, 0, 0, number);
   if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
     {
       if (!EQ (tem0, Qunbound))
@@ -2432,9 +2569,9 @@ x_figure_window_size (f, parms)
   f->output_data.x->pixel_width = CHAR_TO_PIXEL_WIDTH (f, f->width);
   f->output_data.x->pixel_height = CHAR_TO_PIXEL_HEIGHT (f, f->height);
 
-  tem0 = x_get_arg (parms, Qtop, 0, 0, number);
-  tem1 = x_get_arg (parms, Qleft, 0, 0, number);
-  tem2 = x_get_arg (parms, Quser_position, 0, 0, number);
+  tem0 = x_get_arg (dpyinfo, parms, Qtop, 0, 0, number);
+  tem1 = x_get_arg (dpyinfo, parms, Qleft, 0, 0, number);
+  tem2 = x_get_arg (dpyinfo, parms, Quser_position, 0, 0, number);
   if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
     {
       if (EQ (tem0, Qminus))
@@ -2717,6 +2854,10 @@ x_window (f, window_prompting, minibuffer_only)
     }
 
     len = strlen (shell_position) + 1;
+    /* We don't free this because we don't know whether
+       it is safe to free it while the frame exists.
+       It isn't worth the trouble of arranging to free it
+       when the frame is deleted.  */
     tem = (char *) xmalloc (len);
     strncpy (tem, shell_position, len);
     XtSetArg (al[ac], XtNgeometry, tem); ac++;
@@ -2824,6 +2965,7 @@ x_window (f, window_prompting, minibuffer_only)
 
 /* Create and set up the X window for frame F.  */
 
+void
 x_window (f)
      struct frame *f;
 
@@ -2952,6 +3094,7 @@ x_icon (f, parms)
      Lisp_Object parms;
 {
   Lisp_Object icon_x, icon_y;
+  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
 
   /* Set the position of the icon.  Note that twm groups all
      icons in an icon window.  */
@@ -2972,7 +3115,7 @@ x_icon (f, parms)
 
   /* Start up iconic or window? */
   x_wm_set_window_state
-    (f, (EQ (x_get_arg (parms, Qvisibility, 0, 0, symbol), Qicon)
+    (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, symbol), Qicon)
         ? IconicState
         : NormalState));
 
@@ -3039,7 +3182,7 @@ x_make_gc (f)
   f->output_data.x->cursor_gc
     = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                 (GCFont | GCForeground | GCBackground
-                 | GCFillStyle | GCStipple | GCLineWidth),
+                 | GCFillStyle /* | GCStipple */ | GCLineWidth),
                 &gc_values);
 
   /* Create the gray border tile used when the pointer is not in
@@ -3090,7 +3233,7 @@ This function is an internal primitive--use `make-frame' instead.")
      until we know if this frame has a specified name.  */
   Vx_resource_name = Vinvocation_name;
 
-  display = x_get_arg (parms, Qdisplay, 0, 0, string);
+  display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, string);
   if (EQ (display, Qunbound))
     display = Qnil;
   dpyinfo = check_x_display_info (display);
@@ -3100,7 +3243,7 @@ This function is an internal primitive--use `make-frame' instead.")
   kb = &the_only_kboard;
 #endif
 
-  name = x_get_arg (parms, Qname, "name", "Name", string);
+  name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", string);
   if (!STRINGP (name)
       && ! EQ (name, Qunbound)
       && ! NILP (name))
@@ -3110,7 +3253,7 @@ This function is an internal primitive--use `make-frame' instead.")
     Vx_resource_name = name;
 
   /* See if parent window is specified.  */
-  parent = x_get_arg (parms, Qparent_id, NULL, NULL, number);
+  parent = x_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL, number);
   if (EQ (parent, Qunbound))
     parent = Qnil;
   if (! NILP (parent))
@@ -3121,7 +3264,7 @@ This function is an internal primitive--use `make-frame' instead.")
      it to make_frame_without_minibuffer.  */
   frame = Qnil;
   GCPRO4 (parms, parent, name, frame);
-  tem = x_get_arg (parms, Qminibuffer, "minibuffer", "Minibuffer", symbol);
+  tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer", symbol);
   if (EQ (tem, Qnone) || NILP (tem))
     f = make_frame_without_minibuffer (Qnil, kb, display);
   else if (EQ (tem, Qonly))
@@ -3143,9 +3286,10 @@ This function is an internal primitive--use `make-frame' instead.")
   f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
   bzero (f->output_data.x, sizeof (struct x_output));
   f->output_data.x->icon_bitmap = -1;
+  f->output_data.x->fontset = -1;
 
   f->icon_name
-    = x_get_arg (parms, Qicon_name, "iconName", "Title", string);
+    = x_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title", string);
   if (! STRINGP (f->icon_name))
     f->icon_name = Qnil;
 
@@ -3158,7 +3302,7 @@ This function is an internal primitive--use `make-frame' instead.")
 
   if (!NILP (parent))
     {
-      f->output_data.x->parent_desc = parent;
+      f->output_data.x->parent_desc = (Window) XFASTINT (parent);
       f->output_data.x->explicit_parent = 1;
     }
   else
@@ -3194,16 +3338,15 @@ This function is an internal primitive--use `make-frame' instead.")
   {
     Lisp_Object font;
 
-    font = x_get_arg (parms, Qfont, "font", "Font", string);
-    if (!STRINGP (font))
-      font = x_get_arg (parms, Qfontset, "fontset", "Fontset", string);
+    font = x_get_arg (dpyinfo, parms, Qfont, "font", "Font", string);
+
     BLOCK_INPUT;
     /* First, try whatever font the caller has specified.  */
     if (STRINGP (font))
       {
-       Lisp_Object fontset = Fquery_fontset (font);
-       if (STRINGP (fontset))
-         font = x_new_fontset (f, XSTRING (fontset)->data);
+       tem = Fquery_fontset (font, Qnil);
+       if (STRINGP (tem))
+         font = x_new_fontset (f, XSTRING (tem)->data);
        else
          font = x_new_font (f, XSTRING (font)->data);
       }
@@ -3223,7 +3366,7 @@ This function is an internal primitive--use `make-frame' instead.")
     if (! STRINGP (font))
       font = build_string ("fixed");
 
-    x_default_parameter (f, parms, Qfont, font, 
+    x_default_parameter (f, parms, Qfont, font,
                         "font", "Font", string);
   }
 
@@ -3234,7 +3377,7 @@ This function is an internal primitive--use `make-frame' instead.")
 #endif
 
   x_default_parameter (f, parms, Qborder_width, make_number (2),
-                      "borderwidth", "BorderWidth", number);
+                      "borderWidth", "BorderWidth", number);
   /* This defaults to 2 in order to match xterm.  We recognize either
      internalBorderWidth or internalBorder (which is what xterm calls
      it).  */
@@ -3242,7 +3385,7 @@ This function is an internal primitive--use `make-frame' instead.")
     {
       Lisp_Object value;
 
-      value = x_get_arg (parms, Qinternal_border_width,
+      value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
                         "internalBorder", "internalBorder", number);
       if (! EQ (value, Qunbound))
        parms = Fcons (Fcons (Qinternal_border_width, value),
@@ -3251,7 +3394,7 @@ This function is an internal primitive--use `make-frame' instead.")
   x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
                       "internalBorderWidth", "internalBorderWidth", number);
   x_default_parameter (f, parms, Qvertical_scroll_bars, Qleft,
-                      "verticalScrollBars", "ScrollBars", boolean);
+                      "verticalScrollBars", "ScrollBars", symbol);
 
   /* Also do the stuff which must be set before the window exists.  */
   x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
@@ -3330,7 +3473,7 @@ This function is an internal primitive--use `make-frame' instead.")
   x_wm_set_size_hint (f, window_prompting, 0);
   UNBLOCK_INPUT;
 
-  tem = x_get_arg (parms, Qunsplittable, 0, 0, boolean);
+  tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, boolean);
   f->no_split = minibuffer_only || EQ (tem, Qt);
 
   UNGCPRO;
@@ -3352,7 +3495,7 @@ This function is an internal primitive--use `make-frame' instead.")
     {
       Lisp_Object visibility;
 
-      visibility = x_get_arg (parms, Qvisibility, 0, 0, symbol);
+      visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, symbol);
       if (EQ (visibility, Qunbound))
        visibility = Qt;
 
@@ -3420,6 +3563,7 @@ fonts to match.  The first MAXIMUM fonts are reported.")
   FRAME_PTR f;
   Lisp_Object key;
   int maxnames;
+  int count;
 
   check_x ();
   CHECK_STRING (pattern, 0);
@@ -3485,13 +3629,13 @@ fonts to match.  The first MAXIMUM fonts are reported.")
        {
          XFontStruct *thisinfo;
 
-         x_catch_errors (FRAME_X_DISPLAY (f));
+         count = x_catch_errors (FRAME_X_DISPLAY (f));
 
          thisinfo = XLoadQueryFont (FRAME_X_DISPLAY (f),
                                     XSTRING (XCONS (tem)->car)->data);
 
          x_check_errors (FRAME_X_DISPLAY (f), "XLoadQueryFont failure: %s");
-         x_uncatch_errors (FRAME_X_DISPLAY (f));
+         x_uncatch_errors (FRAME_X_DISPLAY (f), count);
 
          if (thisinfo && same_size_fonts (thisinfo, size_ref))
            newlist = Fcons (XCONS (tem)->car, newlist);
@@ -3507,7 +3651,7 @@ fonts to match.  The first MAXIMUM fonts are reported.")
 
   BLOCK_INPUT;
 
-  x_catch_errors (FRAME_X_DISPLAY (f));
+  count = x_catch_errors (FRAME_X_DISPLAY (f));
 
   /* Solaris 2.3 has a bug in XListFontsWithInfo.  */
 #ifndef BROKEN_XLISTFONTSWITHINFO
@@ -3525,7 +3669,7 @@ fonts to match.  The first MAXIMUM fonts are reported.")
                        &num_fonts); /* count_return */
 
   x_check_errors (FRAME_X_DISPLAY (f), "XListFonts failure: %s");
-  x_uncatch_errors (FRAME_X_DISPLAY (f));
+  x_uncatch_errors (FRAME_X_DISPLAY (f), count);
 
   UNBLOCK_INPUT;
 
@@ -3560,11 +3704,11 @@ fonts to match.  The first MAXIMUM fonts are reported.")
 
              BLOCK_INPUT;
 
-             x_catch_errors (FRAME_X_DISPLAY (f));
+             count = x_catch_errors (FRAME_X_DISPLAY (f));
              thisinfo = XLoadQueryFont (FRAME_X_DISPLAY (f), names[i]);
              x_check_errors (FRAME_X_DISPLAY (f),
                              "XLoadQueryFont failure: %s");
-             x_uncatch_errors (FRAME_X_DISPLAY (f));
+             x_uncatch_errors (FRAME_X_DISPLAY (f), count);
 
              UNBLOCK_INPUT;
 
@@ -3944,10 +4088,10 @@ x_char_height (f)
 }
 
 int
-x_screen_planes (frame)
-     Lisp_Object frame;
+x_screen_planes (f)
+     register struct frame *f;
 {
-  return FRAME_X_DISPLAY_INFO (XFRAME (frame))->n_planes;
+  return FRAME_X_DISPLAY_INFO (f)->n_planes;
 }
 \f
 #if 0  /* These no longer seem like the right way to do things.  */
@@ -4781,7 +4925,8 @@ also be depressed for NEWSTRING to appear.")
 
   if (NILP (modifiers))
     XRebindKeysym (x_current_display, keysym, modifier_list, 0,
-                  XSTRING (newstring)->data, XSTRING (newstring)->size);
+                  XSTRING (newstring)->data,
+                  STRING_BYTES (XSTRING (newstring)));
   else
     {
       register Lisp_Object rest, mod;
@@ -4809,7 +4954,8 @@ also be depressed for NEWSTRING to appear.")
        }
 
       XRebindKeysym (x_current_display, keysym, modifier_list, i,
-                    XSTRING (newstring)->data, XSTRING (newstring)->size);
+                    XSTRING (newstring)->data,
+                    STRING_BYTES (XSTRING (newstring)));
     }
 
   return Qnil;
@@ -4840,7 +4986,7 @@ See the documentation of `x-rebind-key' for more information.")
       if (!NILP (item))
        {
          CHECK_STRING (item, 2);
-         strsize = XSTRING (item)->size;
+         strsize = STRING_BYTES (XSTRING (item));
          rawstring = (unsigned char *) xmalloc (strsize);
          bcopy (XSTRING (item)->data, rawstring, strsize);
          modifier[1] = 1 << i;
@@ -5092,6 +5238,7 @@ x_sync (f)
   UNBLOCK_INPUT;
 }
 \f
+void
 syms_of_xfns ()
 {
   /* This is zero if not using X windows.  */
@@ -5156,6 +5303,8 @@ syms_of_xfns ()
   staticpro (&Qvisibility);
   Qwindow_id = intern ("window-id");
   staticpro (&Qwindow_id);
+  Qouter_window_id = intern ("outer-window-id");
+  staticpro (&Qouter_window_id);
   Qx_frame_parameter = intern ("x-frame-parameter");
   staticpro (&Qx_frame_parameter);
   Qx_resource_name = intern ("x-resource-name");
@@ -5168,6 +5317,9 @@ syms_of_xfns ()
   staticpro (&Qdisplay);
   /* This is the end of symbol initialization.  */
 
+  Qface_set_after_frame_default = intern ("face-set-after-frame-default");
+  staticpro (&Qface_set_after_frame_default);
+
   Fput (Qundefined_color, Qerror_conditions,
        Fcons (Qundefined_color, Fcons (Qerror, Qnil)));
   Fput (Qundefined_color, Qerror_message,
@@ -5306,6 +5458,7 @@ Chinese, Japanese, and Korean.");
   get_font_info_func = x_get_font_info;
   list_fonts_func = x_list_fonts;
   load_font_func = x_load_font;
+  find_ccl_program_func = x_find_ccl_program;
   query_font_func = x_query_font;
   set_frame_fontset_func = x_set_font;
   check_window_system_func = check_x;