(fix_submap_inheritance, get_keyelt, store_in_keymap,
[bpt/emacs.git] / src / xfns.c
index 63a58d1..bc704cc 100644 (file)
@@ -1,5 +1,5 @@
 /* Functions for the X window system.
-   Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation.
+   Copyright (C) 1989, 92, 93, 94, 95, 96, 1997 Free Software Foundation.
 
 This file is part of GNU Emacs.
 
@@ -15,7 +15,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 /* Completely rewritten by Richard Stallman.  */
 
@@ -35,11 +36,20 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "dispextern.h"
 #include "keyboard.h"
 #include "blockinput.h"
-#include "paths.h"
+#include <paths.h>
+#include "charset.h"
+#include "fontset.h"
 
 #ifdef HAVE_X_WINDOWS
 extern void abort ();
 
+/* On some systems, the character-composition stuff is broken in X11R5.  */
+#if defined (HAVE_X11R5) && ! defined (HAVE_X11R6)
+#ifdef X11R5_INHIBIT_I18N
+#define X_I18N_INHIBITED
+#endif
+#endif
+
 #ifndef VMS
 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work.  */
 #include "bitmaps/gray.xbm"
@@ -53,8 +63,10 @@ extern void abort ();
 #ifdef USE_X_TOOLKIT
 #include <X11/Shell.h>
 
+#ifndef USE_MOTIF
 #include <X11/Xaw/Paned.h>
 #include <X11/Xaw/Label.h>
+#endif /* USE_MOTIF */
 
 #ifdef USG
 #undef USG     /* ####KLUDGE for Solaris 2.2 and up */
@@ -68,8 +80,9 @@ extern void abort ();
 
 #include "../lwlib/lwlib.h"
 
-/* Do the EDITRES protocol if running X11R5 */
-#if (XtSpecificationRelease >= 5)
+/* Do the EDITRES protocol if running X11R5
+   Exception: HP-UX (at least version A.09.05) has X11R5 without EditRes */
+#if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
 #define HACK_EDITRES
 extern void _XEditResCheckMessages ();
 #endif /* R5 + Athena */
@@ -78,8 +91,10 @@ extern void _XEditResCheckMessages ();
    Library.  */
 extern LWLIB_ID widget_id_tick;
 
+#ifdef USE_LUCID
 /* This is part of a kludge--see lwlib/xlwmenu.c.  */
-XFontStruct *xlwmenu_default_font;
+extern XFontStruct *xlwmenu_default_font;
+#endif
 
 extern void free_frame_menubar ();
 #endif /* USE_X_TOOLKIT */
@@ -93,9 +108,13 @@ extern void free_frame_menubar ();
 #define MAXREQUEST(dpy) ((dpy)->max_request_size)
 #endif
 
-/* The name we're using in resource queries.  */
+/* The name we're using in resource queries.  Most often "emacs".  */
 Lisp_Object Vx_resource_name;
 
+/* The application class we're using in resource queries.
+   Normally "Emacs".  */
+Lisp_Object Vx_resource_class;
+
 /* The background and shape of the mouse pointer, and shape when not
    over text or in the modeline.  */
 Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
@@ -114,6 +133,9 @@ Lisp_Object Vx_no_window_manager;
 /* Search path for bitmap files.  */
 Lisp_Object Vx_bitmap_file_path;
 
+/* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.  */
+Lisp_Object Vx_pixel_size_width_font_regexp;
+
 /* Evaluate this expression to rebuild the section of syms_of_xfns
    that initializes and staticpros the symbols declared below.  Note
    that Emacs 18 has a bug that keeps C-x C-e from being able to
@@ -158,14 +180,15 @@ Lisp_Object Qborder_width;
 Lisp_Object Qbox;
 Lisp_Object Qcursor_color;
 Lisp_Object Qcursor_type;
-Lisp_Object Qfont;
 Lisp_Object Qforeground_color;
 Lisp_Object Qgeometry;
 Lisp_Object Qicon_left;
 Lisp_Object Qicon_top;
 Lisp_Object Qicon_type;
+Lisp_Object Qicon_name;
 Lisp_Object Qinternal_border_width;
 Lisp_Object Qleft;
+Lisp_Object Qright;
 Lisp_Object Qmouse_color;
 Lisp_Object Qnone;
 Lisp_Object Qparent_id;
@@ -184,10 +207,11 @@ Lisp_Object Qdisplay;
 
 /* The below are defined in frame.c.  */
 extern Lisp_Object Qheight, Qminibuffer, Qname, Qonly, Qwidth;
-extern Lisp_Object Qunsplittable, Qmenu_bar_lines;
+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
@@ -197,10 +221,11 @@ check_x ()
     error ("X windows are not in use or not initialized");
 }
 
-/* Nonzero if using X for display.  */
+/* Nonzero if we can use mouse menus.
+   You should not call this unless HAVE_MENUS is defined.  */
 
 int
-using_x_p ()
+have_menus_p ()
 {
   return x_in_use;
 }
@@ -222,7 +247,7 @@ check_x_frame (frame)
       f = XFRAME (frame);
     }
   if (! FRAME_X_P (f))
-    error ("non-X frame used");
+    error ("Non-X frame used");
   return f;
 }
 
@@ -252,7 +277,7 @@ check_x_display_info (frame)
       CHECK_LIVE_FRAME (frame, 0);
       f = XFRAME (frame);
       if (! FRAME_X_P (f))
-       error ("non-X frame used");
+       error ("Non-X frame used");
       return FRAME_X_DISPLAY_INFO (f);
     }
 }
@@ -276,16 +301,16 @@ x_window_to_frame (dpyinfo, wdesc)
       if (!GC_FRAMEP (frame))
         continue;
       f = XFRAME (frame);
-      if (f->display.nothing == 1 || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
+      if (f->output_data.nothing == 1 || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
        continue;
 #ifdef USE_X_TOOLKIT
-      if ((f->display.x->edit_widget 
-          && XtWindow (f->display.x->edit_widget) == wdesc)
-          || f->display.x->icon_desc == wdesc)
+      if ((f->output_data.x->edit_widget 
+          && XtWindow (f->output_data.x->edit_widget) == wdesc)
+          || f->output_data.x->icon_desc == wdesc)
         return f;
 #else /* not USE_X_TOOLKIT */
       if (FRAME_X_WINDOW (f) == wdesc
-          || f->display.x->icon_desc == wdesc)
+          || f->output_data.x->icon_desc == wdesc)
         return f;
 #endif /* not USE_X_TOOLKIT */
     }
@@ -303,7 +328,7 @@ x_any_window_to_frame (dpyinfo, wdesc)
 {
   Lisp_Object tail, frame;
   struct frame *f;
-  struct x_display *x;
+  struct x_output *x;
 
   for (tail = Vframe_list; GC_CONSP (tail); tail = XCONS (tail)->cdr)
     {
@@ -311,9 +336,9 @@ x_any_window_to_frame (dpyinfo, wdesc)
       if (!GC_FRAMEP (frame))
         continue;
       f = XFRAME (frame);
-      if (f->display.nothing == 1 || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
+      if (f->output_data.nothing == 1 || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
        continue;
-      x = f->display.x;
+      x = f->output_data.x;
       /* This frame matches if the window is any of its widgets.  */
       if (wdesc == XtWindow (x->widget) 
          || wdesc == XtWindow (x->column_widget) 
@@ -335,7 +360,7 @@ x_non_menubar_window_to_frame (dpyinfo, wdesc)
 {
   Lisp_Object tail, frame;
   struct frame *f;
-  struct x_display *x;
+  struct x_output *x;
 
   for (tail = Vframe_list; GC_CONSP (tail); tail = XCONS (tail)->cdr)
     {
@@ -343,9 +368,9 @@ x_non_menubar_window_to_frame (dpyinfo, wdesc)
       if (!GC_FRAMEP (frame))
         continue;
       f = XFRAME (frame);
-      if (f->display.nothing == 1 || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
+      if (f->output_data.nothing == 1 || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
        continue;
-      x = f->display.x;
+      x = f->output_data.x;
       /* This frame matches if the window is any of its widgets.  */
       if (wdesc == XtWindow (x->widget) 
          || wdesc == XtWindow (x->column_widget) 
@@ -355,6 +380,33 @@ x_non_menubar_window_to_frame (dpyinfo, wdesc)
   return 0;
 }
 
+/* Likewise, but consider only the menu bar widget.  */
+
+struct frame *
+x_menubar_window_to_frame (dpyinfo, wdesc)
+     struct x_display_info *dpyinfo;
+     int wdesc;
+{
+  Lisp_Object tail, frame;
+  struct frame *f;
+  struct x_output *x;
+
+  for (tail = Vframe_list; GC_CONSP (tail); tail = XCONS (tail)->cdr)
+    {
+      frame = XCONS (tail)->car;
+      if (!GC_FRAMEP (frame))
+        continue;
+      f = XFRAME (frame);
+      if (f->output_data.nothing == 1 || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
+       continue;
+      x = f->output_data.x;
+      /* Match if the window is this frame's menubar.  */
+      if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
+       return f;
+    }
+  return 0;
+}
+
 /* Return the frame whose principal (outermost) window is WDESC.
    If WDESC is some other (smaller) window, we return 0.  */
 
@@ -365,7 +417,7 @@ x_top_window_to_frame (dpyinfo, wdesc)
 {
   Lisp_Object tail, frame;
   struct frame *f;
-  struct x_display *x;
+  struct x_output *x;
 
   for (tail = Vframe_list; GC_CONSP (tail); tail = XCONS (tail)->cdr)
     {
@@ -373,16 +425,20 @@ x_top_window_to_frame (dpyinfo, wdesc)
       if (!GC_FRAMEP (frame))
         continue;
       f = XFRAME (frame);
-      if (f->display.nothing == 1 || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
+      if (f->output_data.nothing == 1 || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
        continue;
-      x = f->display.x;
+      x = f->output_data.x;
       /* This frame matches if the window is its topmost widget.  */
       if (wdesc == XtWindow (x->widget))
        return f;
+#if 0 /* I don't know why it did this,
+        but it seems logically wrong,
+        and it causes trouble for MapNotify events.  */
       /* Match if the window is this frame's menubar.  */
       if (x->menubar_widget 
          && wdesc == XtWindow (x->menubar_widget))
        return f;
+#endif
     }
   return 0;
 }
@@ -543,7 +599,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 (XSTRING (file)->size_byte + 1);
   dpyinfo->bitmaps[id - 1].depth = 1;
   dpyinfo->bitmaps[id - 1].height = height;
   dpyinfo->bitmaps[id - 1].width = width;
@@ -566,12 +623,14 @@ x_destroy_bitmap (f, id)
       --dpyinfo->bitmaps[id - 1].refcount;
       if (dpyinfo->bitmaps[id - 1].refcount == 0)
        {
+         BLOCK_INPUT;
          XFreePixmap (FRAME_X_DISPLAY (f), dpyinfo->bitmaps[id - 1].pixmap);
          if (dpyinfo->bitmaps[id - 1].file)
            {
              free (dpyinfo->bitmaps[id - 1].file);
              dpyinfo->bitmaps[id - 1].file = NULL;
            }
+         UNBLOCK_INPUT;
        }
     }
 }
@@ -598,27 +657,7 @@ x_destroy_all_bitmaps (dpyinfo)
 
    The name of a parameter, as a Lisp symbol,
    has an `x-frame-parameter' property which is an integer in Lisp
-   but can be interpreted as an `enum x_frame_parm' in C.  */
-
-enum x_frame_parm
-{
-  X_PARM_FOREGROUND_COLOR,
-  X_PARM_BACKGROUND_COLOR,
-  X_PARM_MOUSE_COLOR,
-  X_PARM_CURSOR_COLOR,
-  X_PARM_BORDER_COLOR,
-  X_PARM_ICON_TYPE,
-  X_PARM_FONT,
-  X_PARM_BORDER_WIDTH,
-  X_PARM_INTERNAL_BORDER_WIDTH,
-  X_PARM_NAME,
-  X_PARM_AUTORAISE,
-  X_PARM_AUTOLOWER,
-  X_PARM_VERT_SCROLL_BAR,
-  X_PARM_VISIBILITY,
-  X_PARM_MENU_BAR_LINES
-};
-
+   that is an index in this table.  */
 
 struct x_frame_parm_table
 {
@@ -633,6 +672,7 @@ void x_set_cursor_color ();
 void x_set_border_color ();
 void x_set_cursor_type ();
 void x_set_icon_type ();
+void x_set_icon_name ();
 void x_set_font ();
 void x_set_border_width ();
 void x_set_internal_border_width ();
@@ -643,28 +683,31 @@ void x_set_vertical_scroll_bars ();
 void x_set_visibility ();
 void x_set_menu_bar_lines ();
 void x_set_scroll_bar_width ();
+void x_set_title ();
 void x_set_unsplittable ();
 
 static struct x_frame_parm_table x_frame_parms[] =
 {
-  "foreground-color", x_set_foreground_color,
+  "auto-raise", x_set_autoraise,
+  "auto-lower", x_set_autolower,
   "background-color", x_set_background_color,
-  "mouse-color", x_set_mouse_color,
-  "cursor-color", x_set_cursor_color,
   "border-color", x_set_border_color,
+  "border-width", x_set_border_width,
+  "cursor-color", x_set_cursor_color,
   "cursor-type", x_set_cursor_type,
-  "icon-type", x_set_icon_type,
   "font", x_set_font,
-  "border-width", x_set_border_width,
+  "foreground-color", x_set_foreground_color,
+  "icon-name", x_set_icon_name,
+  "icon-type", x_set_icon_type,
   "internal-border-width", x_set_internal_border_width,
-  "name", x_explicitly_set_name,
-  "auto-raise", x_set_autoraise,
-  "auto-lower", x_set_autolower,
-  "vertical-scroll-bars", x_set_vertical_scroll_bars,
-  "visibility", x_set_visibility,
   "menu-bar-lines", x_set_menu_bar_lines,
+  "mouse-color", x_set_mouse_color,
+  "name", x_explicitly_set_name,
   "scroll-bar-width", x_set_scroll_bar_width,
+  "title", x_set_title,
   "unsplittable", x_set_unsplittable,
+  "vertical-scroll-bars", x_set_vertical_scroll_bars,
+  "visibility", x_set_visibility,
 };
 
 /* Attach the `x-frame-parameter' properties to
@@ -679,7 +722,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.  */
 
@@ -693,7 +736,7 @@ x_set_frame_parameters (f, alist)
   /* If both of these parameters are present, it's more efficient to
      set them both at once.  So we wait until we've looked at the
      entire list before we set them.  */
-  Lisp_Object width, height;
+  int width, height;
 
   /* Same here.  */
   Lisp_Object left, top;
@@ -728,9 +771,20 @@ x_set_frame_parameters (f, alist)
       i++;
     }
 
-  width = height = top = left = Qunbound;
+  top = left = Qunbound;
   icon_left = icon_top = Qunbound;
 
+  /* Provide default values for HEIGHT and WIDTH.  */
+  if (FRAME_NEW_WIDTH (f))
+    width = FRAME_NEW_WIDTH (f);
+  else
+    width = FRAME_WIDTH (f);
+
+  if (FRAME_NEW_HEIGHT (f))
+    height = FRAME_NEW_HEIGHT (f);
+  else
+    height = FRAME_HEIGHT (f);
+
   /* Now process them in reverse of specified order.  */
   for (i--; i >= 0; i--)
     {
@@ -739,10 +793,10 @@ x_set_frame_parameters (f, alist)
       prop = parms[i];
       val = values[i];
 
-      if (EQ (prop, Qwidth))
-       width = val;
-      else if (EQ (prop, Qheight))
-       height = val;
+      if (EQ (prop, Qwidth) && NUMBERP (val))
+       width = XFASTINT (val);
+      else if (EQ (prop, Qheight) && NUMBERP (val))
+       height = XFASTINT (val);
       else if (EQ (prop, Qtop))
        top = val;
       else if (EQ (prop, Qleft))
@@ -769,18 +823,18 @@ x_set_frame_parameters (f, alist)
   if (EQ (left, Qunbound))
     {
       left_no_change = 1;
-      if (f->display.x->left_pos < 0)
-       left = Fcons (Qplus, Fcons (make_number (f->display.x->left_pos), Qnil));
+      if (f->output_data.x->left_pos < 0)
+       left = Fcons (Qplus, Fcons (make_number (f->output_data.x->left_pos), Qnil));
       else
-       XSETINT (left, f->display.x->left_pos);
+       XSETINT (left, f->output_data.x->left_pos);
     }
   if (EQ (top, Qunbound))
     {
       top_no_change = 1;
-      if (f->display.x->top_pos < 0)
-       top = Fcons (Qplus, Fcons (make_number (f->display.x->top_pos), Qnil));
+      if (f->output_data.x->top_pos < 0)
+       top = Fcons (Qplus, Fcons (make_number (f->output_data.x->top_pos), Qnil));
       else
-       XSETINT (top, f->display.x->top_pos);
+       XSETINT (top, f->output_data.x->top_pos);
     }
 
   /* If one of the icon positions was not set, preserve or default it.  */
@@ -799,13 +853,7 @@ x_set_frame_parameters (f, alist)
        XSETINT (icon_top, 0);
     }
 
-  /* Don't die if just one of these was set.  */
-  if (EQ (width, Qunbound))
-    XSETINT (width, FRAME_WIDTH (f));
-  if (EQ (height, Qunbound))
-    XSETINT (height, FRAME_HEIGHT (f));
-
-  /* Don't set these parameters these unless they've been explicitly
+  /* Don't set these parameters 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.
@@ -820,34 +868,35 @@ x_set_frame_parameters (f, alist)
 
     XSETFRAME (frame, f);
 
-    if ((NUMBERP (width) && XINT (width) != FRAME_WIDTH (f))
-       || (NUMBERP (height) && XINT (height) != FRAME_HEIGHT (f)))
-      Fset_frame_size (frame, width, height);
+    if (width != FRAME_WIDTH (f)
+       || height != FRAME_HEIGHT (f)
+       || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))
+      Fset_frame_size (frame, make_number (width), make_number (height));
 
     if ((!NILP (left) || !NILP (top))
        && ! (left_no_change && top_no_change)
-       && ! (NUMBERP (left) && XINT (left) == f->display.x->left_pos
-             && NUMBERP (top) && XINT (top) == f->display.x->top_pos))
+       && ! (NUMBERP (left) && XINT (left) == f->output_data.x->left_pos
+             && NUMBERP (top) && XINT (top) == f->output_data.x->top_pos))
       {
        int leftpos = 0;
        int toppos = 0;
 
        /* Record the signs.  */
-       f->display.x->size_hint_flags &= ~ (XNegative | YNegative);
+       f->output_data.x->size_hint_flags &= ~ (XNegative | YNegative);
        if (EQ (left, Qminus))
-         f->display.x->size_hint_flags |= XNegative;
+         f->output_data.x->size_hint_flags |= XNegative;
        else if (INTEGERP (left))
          {
            leftpos = XINT (left);
            if (leftpos < 0)
-             f->display.x->size_hint_flags |= XNegative;
+             f->output_data.x->size_hint_flags |= XNegative;
          }
        else if (CONSP (left) && EQ (XCONS (left)->car, Qminus)
                 && CONSP (XCONS (left)->cdr)
                 && INTEGERP (XCONS (XCONS (left)->cdr)->car))
          {
            leftpos = - XINT (XCONS (XCONS (left)->cdr)->car);
-           f->display.x->size_hint_flags |= XNegative;
+           f->output_data.x->size_hint_flags |= XNegative;
          }
        else if (CONSP (left) && EQ (XCONS (left)->car, Qplus)
                 && CONSP (XCONS (left)->cdr)
@@ -857,19 +906,19 @@ x_set_frame_parameters (f, alist)
          }
 
        if (EQ (top, Qminus))
-         f->display.x->size_hint_flags |= YNegative;
+         f->output_data.x->size_hint_flags |= YNegative;
        else if (INTEGERP (top))
          {
            toppos = XINT (top);
            if (toppos < 0)
-             f->display.x->size_hint_flags |= YNegative;
+             f->output_data.x->size_hint_flags |= YNegative;
          }
        else if (CONSP (top) && EQ (XCONS (top)->car, Qminus)
                 && CONSP (XCONS (top)->cdr)
                 && INTEGERP (XCONS (XCONS (top)->cdr)->car))
          {
            toppos = - XINT (XCONS (XCONS (top)->cdr)->car);
-           f->display.x->size_hint_flags |= YNegative;
+           f->output_data.x->size_hint_flags |= YNegative;
          }
        else if (CONSP (top) && EQ (XCONS (top)->car, Qplus)
                 && CONSP (XCONS (top)->cdr)
@@ -880,13 +929,13 @@ x_set_frame_parameters (f, alist)
 
 
        /* Store the numeric value of the position.  */
-       f->display.x->top_pos = toppos;
-       f->display.x->left_pos = leftpos;
+       f->output_data.x->top_pos = toppos;
+       f->output_data.x->left_pos = leftpos;
 
-       f->display.x->win_gravity = NorthWestGravity;
+       f->output_data.x->win_gravity = NorthWestGravity;
 
        /* Actually set that position, and convert to absolute.  */
-       x_set_offset (f, leftpos, toppos, 0);
+       x_set_offset (f, leftpos, toppos, -1);
       }
 
     if ((!NILP (icon_left) || !NILP (icon_top))
@@ -911,47 +960,44 @@ x_real_positions (f, xptr, yptr)
      the problem that arises when restarting window-managers.  */
 
 #ifdef USE_X_TOOLKIT
-  Window outer = XtWindow (f->display.x->widget);
+  Window outer = XtWindow (f->output_data.x->widget);
 #else
-  Window outer = f->display.x->window_desc;
+  Window outer = f->output_data.x->window_desc;
 #endif
   Window tmp_root_window;
   Window *tmp_children;
   int tmp_nchildren;
 
-  x_catch_errors (FRAME_X_DISPLAY (f));
   while (1)
     {
+      int count = x_catch_errors (FRAME_X_DISPLAY (f));
+      Window outer_window;
+
       XQueryTree (FRAME_X_DISPLAY (f), outer, &tmp_root_window,
-                 &f->display.x->parent_desc,
+                 &f->output_data.x->parent_desc,
                  &tmp_children, &tmp_nchildren);
-      xfree (tmp_children);
+      XFree ((char *) tmp_children);
 
       win_x = win_y = 0;
 
       /* Find the position of the outside upper-left corner of
         the inner window, with respect to the outer window.  */
-      if (f->display.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
-       {
-         XTranslateCoordinates (FRAME_X_DISPLAY (f),
+      if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
+       outer_window = f->output_data.x->parent_desc;
+      else
+       outer_window = outer;
 
-                                /* From-window, to-window.  */
-#ifdef USE_X_TOOLKIT
-                                XtWindow (f->display.x->widget),
-#else
-                                f->display.x->window_desc,
-#endif
-                                f->display.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,
 
-         win_x += f->display.x->border_width;
-         win_y += f->display.x->border_width;
-       }
+                            /* Child of win.  */
+                            &child);
 
       /* It is possible for the window returned by the XQueryNotify
         to become invalid by the time we call XTranslateCoordinates.
@@ -959,13 +1005,16 @@ x_real_positions (f, xptr, yptr)
         If so, we get an error in XTranslateCoordinates.
         Detect that and try the whole thing over.  */
       if (! x_had_errors_p (FRAME_X_DISPLAY (f)))
-       break;
-    }
+       {
+         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->display.x->left_pos - win_x;
-  *yptr = f->display.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
@@ -979,22 +1028,42 @@ x_report_frame_params (f, alistptr)
      Lisp_Object *alistptr;
 {
   char buf[16];
+  Lisp_Object tem;
+
+  /* Represent negative positions (off the top or left screen edge)
+     in a way that Fmodify_frame_parameters will understand correctly.  */
+  XSETINT (tem, f->output_data.x->left_pos);
+  if (f->output_data.x->left_pos >= 0)
+    store_in_alist (alistptr, Qleft, tem);
+  else
+    store_in_alist (alistptr, Qleft, Fcons (Qplus, Fcons (tem, Qnil)));
+
+  XSETINT (tem, f->output_data.x->top_pos);
+  if (f->output_data.x->top_pos >= 0)
+    store_in_alist (alistptr, Qtop, tem);
+  else
+    store_in_alist (alistptr, Qtop, Fcons (Qplus, Fcons (tem, Qnil)));
 
-  store_in_alist (alistptr, Qleft, make_number (f->display.x->left_pos));
-  store_in_alist (alistptr, Qtop, make_number (f->display.x->top_pos));
   store_in_alist (alistptr, Qborder_width,
-                  make_number (f->display.x->border_width));
+                  make_number (f->output_data.x->border_width));
   store_in_alist (alistptr, Qinternal_border_width,
-                  make_number (f->display.x->internal_border_width));
+                  make_number (f->output_data.x->internal_border_width));
   sprintf (buf, "%ld", (long) FRAME_X_WINDOW (f));
   store_in_alist (alistptr, Qwindow_id,
                   build_string (buf));
+  store_in_alist (alistptr, Qicon_name, f->icon_name);
   FRAME_SAMPLE_VISIBILITY (f);
   store_in_alist (alistptr, Qvisibility,
                  (FRAME_VISIBLE_P (f) ? Qt
                   : FRAME_ICONIFIED_P (f) ? Qicon : Qnil));
   store_in_alist (alistptr, Qdisplay,
                  XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->car);
+
+  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
 
@@ -1062,8 +1131,16 @@ defined_color (f, color, color_def, alloc)
                              * ((color_def->blue >> 8) - (cells[x].blue >> 8))));
              if (trial_delta < nearest_delta) 
                {
-                 nearest = x;
-                 nearest_delta = trial_delta;
+                 XColor temp;
+                 temp.red = cells[x].red;
+                 temp.green = cells[x].green;
+                 temp.blue = cells[x].blue;
+                 status = XAllocColor (display, screen_colormap, &temp);
+                 if (status)
+                   {
+                     nearest = x;
+                     nearest_delta = trial_delta;
+                   }
                }
            }
          color_def->red = cells[nearest].red;
@@ -1108,8 +1185,8 @@ x_decode_color (f, arg, def)
   if (defined_color (f, XSTRING (arg)->data, &cdef, 1))
     return cdef.pixel;
 
-  /* defined_color failed; return an ultimate default.  */
-  return def;
+  Fsignal (Qerror, Fcons (build_string ("undefined color"),
+                         Fcons (arg, Qnil)));
 }
 \f
 /* Functions called only from `x_set_frame_param'
@@ -1125,15 +1202,15 @@ x_set_foreground_color (f, arg, oldval)
      struct frame *f;
      Lisp_Object arg, oldval;
 {
-  f->display.x->foreground_pixel
+  f->output_data.x->foreground_pixel
     = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
   if (FRAME_X_WINDOW (f) != 0)
     {
       BLOCK_INPUT;
-      XSetForeground (FRAME_X_DISPLAY (f), f->display.x->normal_gc,
-                     f->display.x->foreground_pixel);
-      XSetBackground (FRAME_X_DISPLAY (f), f->display.x->reverse_gc,
-                     f->display.x->foreground_pixel);
+      XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
+                     f->output_data.x->foreground_pixel);
+      XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->reverse_gc,
+                     f->output_data.x->foreground_pixel);
       UNBLOCK_INPUT;
       recompute_basic_faces (f);
       if (FRAME_VISIBLE_P (f))
@@ -1149,28 +1226,28 @@ x_set_background_color (f, arg, oldval)
   Pixmap temp;
   int mask;
 
-  f->display.x->background_pixel
+  f->output_data.x->background_pixel
     = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
 
   if (FRAME_X_WINDOW (f) != 0)
     {
       BLOCK_INPUT;
       /* The main frame area.  */
-      XSetBackground (FRAME_X_DISPLAY (f), f->display.x->normal_gc,
-                     f->display.x->background_pixel);
-      XSetForeground (FRAME_X_DISPLAY (f), f->display.x->reverse_gc,
-                     f->display.x->background_pixel);
-      XSetForeground (FRAME_X_DISPLAY (f), f->display.x->cursor_gc,
-                     f->display.x->background_pixel);
+      XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
+                     f->output_data.x->background_pixel);
+      XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->reverse_gc,
+                     f->output_data.x->background_pixel);
+      XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc,
+                     f->output_data.x->background_pixel);
       XSetWindowBackground (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                           f->display.x->background_pixel);
+                           f->output_data.x->background_pixel);
       {
        Lisp_Object bar;
        for (bar = FRAME_SCROLL_BARS (f); !NILP (bar);
             bar = XSCROLL_BAR (bar)->next)
          XSetWindowBackground (FRAME_X_DISPLAY (f),
                                SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar)),
-                               f->display.x->background_pixel);
+                               f->output_data.x->background_pixel);
       }
       UNBLOCK_INPUT;
 
@@ -1187,21 +1264,22 @@ x_set_mouse_color (f, arg, oldval)
      Lisp_Object arg, oldval;
 {
   Cursor cursor, nontext_cursor, mode_cursor, cross_cursor;
+  int count;
   int mask_color;
 
   if (!EQ (Qnil, arg))
-    f->display.x->mouse_pixel
+    f->output_data.x->mouse_pixel
       = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
-  mask_color = f->display.x->background_pixel;
+  mask_color = f->output_data.x->background_pixel;
                                /* No invisible pointers.  */
-  if (mask_color == f->display.x->mouse_pixel
-       && mask_color == f->display.x->background_pixel)
-    f->display.x->mouse_pixel = f->display.x->foreground_pixel;
+  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;
 
   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))
     {
@@ -1244,12 +1322,12 @@ 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;
 
-    fore_color.pixel = f->display.x->mouse_pixel;
+    fore_color.pixel = f->output_data.x->mouse_pixel;
     back_color.pixel = mask_color;
     XQueryColor (FRAME_X_DISPLAY (f),
                 DefaultColormap (FRAME_X_DISPLAY (f),
@@ -1274,23 +1352,23 @@ x_set_mouse_color (f, arg, oldval)
       XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), cursor);
     }
 
-  if (cursor != f->display.x->text_cursor && f->display.x->text_cursor != 0)
-    XFreeCursor (FRAME_X_DISPLAY (f), f->display.x->text_cursor);
-  f->display.x->text_cursor = cursor;
+  if (cursor != f->output_data.x->text_cursor && f->output_data.x->text_cursor != 0)
+    XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->text_cursor);
+  f->output_data.x->text_cursor = cursor;
 
-  if (nontext_cursor != f->display.x->nontext_cursor
-      && f->display.x->nontext_cursor != 0)
-    XFreeCursor (FRAME_X_DISPLAY (f), f->display.x->nontext_cursor);
-  f->display.x->nontext_cursor = nontext_cursor;
+  if (nontext_cursor != f->output_data.x->nontext_cursor
+      && f->output_data.x->nontext_cursor != 0)
+    XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->nontext_cursor);
+  f->output_data.x->nontext_cursor = nontext_cursor;
 
-  if (mode_cursor != f->display.x->modeline_cursor
-      && f->display.x->modeline_cursor != 0)
-    XFreeCursor (FRAME_X_DISPLAY (f), f->display.x->modeline_cursor);
-  f->display.x->modeline_cursor = mode_cursor;
-  if (cross_cursor != f->display.x->cross_cursor
-      && f->display.x->cross_cursor != 0)
-    XFreeCursor (FRAME_X_DISPLAY (f), f->display.x->cross_cursor);
-  f->display.x->cross_cursor = cross_cursor;
+  if (mode_cursor != f->output_data.x->modeline_cursor
+      && f->output_data.x->modeline_cursor != 0)
+    XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->modeline_cursor);
+  f->output_data.x->modeline_cursor = mode_cursor;
+  if (cross_cursor != f->output_data.x->cross_cursor
+      && f->output_data.x->cross_cursor != 0)
+    XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->cross_cursor);
+  f->output_data.x->cross_cursor = cross_cursor;
 
   XFlush (FRAME_X_DISPLAY (f));
   UNBLOCK_INPUT;
@@ -1307,35 +1385,35 @@ x_set_cursor_color (f, arg, oldval)
     fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
                                 WHITE_PIX_DEFAULT (f));
   else
-    fore_pixel = f->display.x->background_pixel;
-  f->display.x->cursor_pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
+    fore_pixel = f->output_data.x->background_pixel;
+  f->output_data.x->cursor_pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
   
   /* Make sure that the cursor color differs from the background color.  */
-  if (f->display.x->cursor_pixel == f->display.x->background_pixel)
+  if (f->output_data.x->cursor_pixel == f->output_data.x->background_pixel)
     {
-      f->display.x->cursor_pixel = f->display.x->mouse_pixel;
-      if (f->display.x->cursor_pixel == fore_pixel)
-       fore_pixel = f->display.x->background_pixel;
+      f->output_data.x->cursor_pixel = f->output_data.x->mouse_pixel;
+      if (f->output_data.x->cursor_pixel == fore_pixel)
+       fore_pixel = f->output_data.x->background_pixel;
     }
-  f->display.x->cursor_foreground_pixel = fore_pixel;
+  f->output_data.x->cursor_foreground_pixel = fore_pixel;
 
   if (FRAME_X_WINDOW (f) != 0)
     {
       BLOCK_INPUT;
-      XSetBackground (FRAME_X_DISPLAY (f), f->display.x->cursor_gc,
-                     f->display.x->cursor_pixel);
-      XSetForeground (FRAME_X_DISPLAY (f), f->display.x->cursor_gc,
+      XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc,
+                     f->output_data.x->cursor_pixel);
+      XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc,
                      fore_pixel);
       UNBLOCK_INPUT;
 
       if (FRAME_VISIBLE_P (f))
        {
-         x_display_cursor (f, 0);
-         x_display_cursor (f, 1);
+         x_update_cursor (f, 0);
+         x_update_cursor (f, 1);
        }
     }
 }
-
+\f
 /* Set the border-color of frame F to value described by ARG.
    ARG can be a string naming a color.
    The border-color is used for the border that is drawn by the X server.
@@ -1371,16 +1449,16 @@ x_set_border_pixel (f, pix)
      struct frame *f;
      int pix;
 {
-  f->display.x->border_pixel = pix;
+  f->output_data.x->border_pixel = pix;
 
-  if (FRAME_X_WINDOW (f) != 0 && f->display.x->border_width > 0)
+  if (FRAME_X_WINDOW (f) != 0 && f->output_data.x->border_width > 0)
     {
       Pixmap temp;
       int mask;
 
       BLOCK_INPUT;
       XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                        pix);
+                       (unsigned long)pix);
       UNBLOCK_INPUT;
 
       if (FRAME_VISIBLE_P (f))
@@ -1396,13 +1474,13 @@ x_set_cursor_type (f, arg, oldval)
   if (EQ (arg, Qbar))
     {
       FRAME_DESIRED_CURSOR (f) = bar_cursor;
-      f->display.x->cursor_width = 2;
+      f->output_data.x->cursor_width = 2;
     }
   else if (CONSP (arg) && EQ (XCONS (arg)->car, Qbar)
           && INTEGERP (XCONS (arg)->cdr))
     {
       FRAME_DESIRED_CURSOR (f) = bar_cursor;
-      f->display.x->cursor_width = XINT (XCONS (arg)->cdr);
+      f->output_data.x->cursor_width = XINT (XCONS (arg)->cdr);
     }
   else
     /* Treat anything unknown as "box cursor".
@@ -1414,7 +1492,7 @@ x_set_cursor_type (f, arg, oldval)
      often do people change cursor types?  */
   update_mode_lines++;
 }
-
+\f
 void
 x_set_icon_type (f, arg, oldval)
      struct frame *f;
@@ -1433,7 +1511,10 @@ x_set_icon_type (f, arg, oldval)
 
   BLOCK_INPUT;
   if (NILP (arg))
-    result = x_text_icon (f, 0);
+    result = x_text_icon (f,
+                         (char *) XSTRING ((!NILP (f->icon_name)
+                                            ? f->icon_name
+                                            : f->name))->data);
   else
     result = x_bitmap_icon (f, arg);
 
@@ -1443,16 +1524,6 @@ x_set_icon_type (f, arg, oldval)
       error ("No icon window available");
     }
 
-  /* If the window was unmapped (and its icon was mapped),
-     the new icon is not mapped, so map the window in its stead.  */
-  if (FRAME_VISIBLE_P (f))
-    {
-#ifdef USE_X_TOOLKIT
-      XtPopup (f->display.x->widget, XtGrabNone);
-#endif
-      XMapWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
-    }
-
   XFlush (FRAME_X_DISPLAY (f));
   UNBLOCK_INPUT;
 }
@@ -1472,7 +1543,49 @@ x_icon_type (f)
     return Qnil;
 }
 
+void
+x_set_icon_name (f, arg, oldval)
+     struct frame *f;
+     Lisp_Object arg, oldval;
+{
+  Lisp_Object tem;
+  int result;
+
+  if (STRINGP (arg))
+    {
+      if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
+       return;
+    }
+  else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
+    return;
+
+  f->icon_name = arg;
+
+  if (f->output_data.x->icon_bitmap != 0)
+    return;
+
+  BLOCK_INPUT;
+
+  result = x_text_icon (f,
+                       (char *) XSTRING ((!NILP (f->icon_name)
+                                          ? f->icon_name
+                                          : !NILP (f->title)
+                                          ? f->title
+                                          : f->name))->data);
+
+  if (result)
+    {
+      UNBLOCK_INPUT;
+      error ("No icon window available");
+    }
+
+  XFlush (FRAME_X_DISPLAY (f));
+  UNBLOCK_INPUT;
+}
+\f
 extern Lisp_Object x_new_font ();
+extern Lisp_Object x_new_fontset ();
+extern Lisp_Object Fquery_fontset ();
 
 void
 x_set_font (f, arg, oldval)
@@ -1480,15 +1593,21 @@ x_set_font (f, arg, oldval)
      Lisp_Object arg, oldval;
 {
   Lisp_Object result;
+  Lisp_Object fontset_name;
+  Lisp_Object frame;
 
   CHECK_STRING (arg, 1);
 
+  fontset_name = Fquery_fontset (arg);
+
   BLOCK_INPUT;
-  result = x_new_font (f, XSTRING (arg)->data);
+  result = (STRINGP (fontset_name)
+           ? x_new_fontset (f, XSTRING (fontset_name)->data)
+           : x_new_font (f, XSTRING (arg)->data));
   UNBLOCK_INPUT;
   
   if (EQ (result, Qnil))
-    error ("Font \"%s\" is not defined", XSTRING (arg)->data);
+    error ("Font `%s' is not defined", XSTRING (arg)->data);
   else if (EQ (result, Qt))
     error ("the characters of the given font have varying widths");
   else if (STRINGP (result))
@@ -1498,6 +1617,9 @@ x_set_font (f, arg, oldval)
     }
   else
     abort ();
+
+  XSETFRAME (frame, f);
+  call1 (Qface_set_after_frame_default, frame);
 }
 
 void
@@ -1507,13 +1629,13 @@ x_set_border_width (f, arg, oldval)
 {
   CHECK_NUMBER (arg, 0);
 
-  if (XINT (arg) == f->display.x->border_width)
+  if (XINT (arg) == f->output_data.x->border_width)
     return;
 
   if (FRAME_X_WINDOW (f) != 0)
     error ("Cannot change the border width of a window");
 
-  f->display.x->border_width = XINT (arg);
+  f->output_data.x->border_width = XINT (arg);
 }
 
 void
@@ -1522,14 +1644,20 @@ x_set_internal_border_width (f, arg, oldval)
      Lisp_Object arg, oldval;
 {
   int mask;
-  int old = f->display.x->internal_border_width;
+  int old = f->output_data.x->internal_border_width;
 
   CHECK_NUMBER (arg, 0);
-  f->display.x->internal_border_width = XINT (arg);
-  if (f->display.x->internal_border_width < 0)
-    f->display.x->internal_border_width = 0;
+  f->output_data.x->internal_border_width = XINT (arg);
+  if (f->output_data.x->internal_border_width < 0)
+    f->output_data.x->internal_border_width = 0;
+
+#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);
+#endif
 
-  if (f->display.x->internal_border_width == old)
+  if (f->output_data.x->internal_border_width == old)
     return;
 
   if (FRAME_X_WINDOW (f) != 0)
@@ -1560,7 +1688,7 @@ x_set_visibility (f, value, oldval)
   else
     Fmake_frame_visible (frame);
 }
-
+\f
 static void
 x_set_menu_bar_lines_1 (window, n)
   Lisp_Object window;
@@ -1603,23 +1731,32 @@ 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)
-    FRAME_EXTERNAL_MENU_BAR (f) = 1;
+    {
+      FRAME_EXTERNAL_MENU_BAR (f) = 1;
+      if (FRAME_X_P (f) && f->output_data.x->menubar_widget == 0)
+       /* Make sure next redisplay shows the menu bar.  */
+       XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
+    }
   else
     {
       if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
        free_frame_menubar (f);
       FRAME_EXTERNAL_MENU_BAR (f) = 0;
-      f->display.x->menubar_widget = 0;
+      if (FRAME_X_P (f))
+       f->output_data.x->menubar_widget = 0;
     }
 #else /* not USE_X_TOOLKIT */
   FRAME_MENU_BAR_LINES (f) = nlines;
   x_set_menu_bar_lines_1 (f->root_window, nlines - olines);
 #endif /* not USE_X_TOOLKIT */
 }
-
+\f
 /* Change the name of frame F to NAME.  If NAME is nil, set F's name to
        x_id_name.
 
@@ -1668,24 +1805,40 @@ x_set_name (f, name, explicit)
   if (! NILP (Fstring_equal (name, f->name)))
     return;
 
+  f->name = name;
+
+  /* For setting the frame title, the title parameter should override
+     the name parameter.  */
+  if (! NILP (f->title))
+    name = f->title;
+
   if (FRAME_X_WINDOW (f))
     {
       BLOCK_INPUT;
 #ifdef HAVE_X11R4
       {
-       XTextProperty text;
+       XTextProperty text, icon;
+       Lisp_Object icon_name;
+
        text.value = XSTRING (name)->data;
        text.encoding = XA_STRING;
        text.format = 8;
-       text.nitems = XSTRING (name)->size;
+       text.nitems = XSTRING (name)->size_byte;
+
+       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_byte;
 #ifdef USE_X_TOOLKIT
        XSetWMName (FRAME_X_DISPLAY (f),
-                   XtWindow (f->display.x->widget), &text);
-       XSetWMIconName (FRAME_X_DISPLAY (f), XtWindow (f->display.x->widget),
-                       &text);
+                   XtWindow (f->output_data.x->widget), &text);
+       XSetWMIconName (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget),
+                       &icon);
 #else /* not USE_X_TOOLKIT */
        XSetWMName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &text);
-       XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &text);
+       XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &icon);
 #endif /* not USE_X_TOOLKIT */
       }
 #else /* not HAVE_X11R4 */
@@ -1696,8 +1849,6 @@ x_set_name (f, name, explicit)
 #endif /* not HAVE_X11R4 */
       UNBLOCK_INPUT;
     }
-
-  f->name = name;
 }
 
 /* This function should be called when the user's lisp code has
@@ -1721,7 +1872,75 @@ x_implicitly_set_name (f, arg, oldval)
 {
   x_set_name (f, arg, 0);
 }
+\f
+/* Change the title of frame F to NAME.
+   If NAME is nil, use the frame name as the title.
+
+   If EXPLICIT is non-zero, that indicates that lisp code is setting the
+       name; if NAME is a string, set F's name to NAME and set
+       F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
+
+   If EXPLICIT is zero, that indicates that Emacs redisplay code is
+       suggesting a new name, which lisp code should override; if
+       F->explicit_name is set, ignore the new name; otherwise, set it.  */
 
+void
+x_set_title (f, name)
+     struct frame *f;
+     Lisp_Object name;
+{
+  /* Don't change the title if it's already NAME.  */
+  if (EQ (name, f->title))
+    return;
+
+  update_mode_lines = 1;
+
+  f->title = name;
+
+  if (NILP (name))
+    name = f->name;
+  else
+    CHECK_STRING (name, 0);
+
+  if (FRAME_X_WINDOW (f))
+    {
+      BLOCK_INPUT;
+#ifdef HAVE_X11R4
+      {
+       XTextProperty text, icon;
+       Lisp_Object icon_name;
+
+       text.value = XSTRING (name)->data;
+       text.encoding = XA_STRING;
+       text.format = 8;
+       text.nitems = XSTRING (name)->size_byte;
+
+       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_byte;
+#ifdef USE_X_TOOLKIT
+       XSetWMName (FRAME_X_DISPLAY (f),
+                   XtWindow (f->output_data.x->widget), &text);
+       XSetWMIconName (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget),
+                       &icon);
+#else /* not USE_X_TOOLKIT */
+       XSetWMName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &text);
+       XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &icon);
+#endif /* not USE_X_TOOLKIT */
+      }
+#else /* not HAVE_X11R4 */
+      XSetIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                   XSTRING (name)->data);
+      XStoreName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                 XSTRING (name)->data);
+#endif /* not HAVE_X11R4 */
+      UNBLOCK_INPUT;
+    }
+}
+\f
 void
 x_set_autoraise (f, arg, oldval)
      struct frame *f;
@@ -1751,9 +1970,17 @@ x_set_vertical_scroll_bars (f, arg, oldval)
      struct frame *f;
      Lisp_Object arg, oldval;
 {
-  if (NILP (arg) != ! FRAME_HAS_VERTICAL_SCROLL_BARS (f))
+  if ((EQ (arg, Qleft) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
+      || (EQ (arg, Qright) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
+      || (NILP (arg) && FRAME_HAS_VERTICAL_SCROLL_BARS (f))
+      || (!NILP (arg) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f)))
     {
-      FRAME_HAS_VERTICAL_SCROLL_BARS (f) = ! NILP (arg);
+      FRAME_VERTICAL_SCROLL_BAR_TYPE (f)
+       = (NILP (arg)
+          ? vertical_scroll_bar_none
+          : EQ (Qright, arg)
+          ? vertical_scroll_bar_right 
+          : vertical_scroll_bar_left);
 
       /* We set this parameter before creating the X window for the
         frame, so we can get the geometry right from the start.
@@ -1769,25 +1996,41 @@ 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) = 2;
+
+      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->display.x->font);
+      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;
       if (FRAME_X_WINDOW (f))
        x_set_window_size (f, 0, FRAME_WIDTH (f), FRAME_HEIGHT (f));
     }
+
+  change_frame_size (f, 0, FRAME_WIDTH (f), 0, 0);
+  FRAME_CURSOR_X (f) =  FRAME_LEFT_SCROLL_BAR_WIDTH (f);
 }
 \f
 /* Subroutines of creating an X frame.  */
 
-/* Make sure that Vx_resource_name is set to a reasonable value.  */
+/* 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 ()
 {
@@ -1799,12 +2042,15 @@ validate_x_resource_name ()
   Lisp_Object new;
   int i;
 
+  if (!STRINGP (Vx_resource_class))
+    Vx_resource_class = build_string (EMACS_CLASS);
+
   if (STRINGP (Vx_resource_name))
     {
       unsigned char *p = XSTRING (Vx_resource_name)->data;
       int i;
 
-      len = XSTRING (Vx_resource_name)->size;
+      len = XSTRING (Vx_resource_name)->size_byte;
 
       /* Only letters, digits, - and _ are valid in resource names.
         Count the valid characters and count the invalid ones.  */
@@ -1832,7 +2078,7 @@ validate_x_resource_name ()
   if (good_count == 0
       || (good_count == 1 && bad_count > 0))
     {
-      Vx_resource_name = make_string ("emacs", 5);
+      Vx_resource_name = build_string ("emacs");
       return;
     }
 
@@ -1871,7 +2117,6 @@ and the class is `Emacs.CLASS.SUBCLASS'.")
   register char *value;
   char *name_key;
   char *class_key;
-  Lisp_Object resname;
 
   check_x ();
 
@@ -1886,50 +2131,110 @@ and the class is `Emacs.CLASS.SUBCLASS'.")
     error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
 
   validate_x_resource_name ();
-  resname = Vx_resource_name;
 
-  if (NILP (component))
+  /* 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_byte
+                             + (STRINGP (component)
+                                ? XSTRING (component)->size_byte : 0)
+                             + XSTRING (attribute)->size_byte
+                             + 3);
+
+  class_key = (char *) alloca (XSTRING (Vx_resource_class)->size_byte
+                              + XSTRING (class)->size_byte
+                              + (STRINGP (subclass)
+                                 ? XSTRING (subclass)->size_byte : 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))
     {
-      /* Allocate space for the components, the dots which separate them,
-        and the final '\0'.  */
-      name_key = (char *) alloca (XSTRING (resname)->size
-                                 + XSTRING (attribute)->size
-                                 + 2);
-      class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
-                                  + XSTRING (class)->size
-                                  + 2);
-
-      sprintf (name_key, "%s.%s",
-              XSTRING (resname)->data,
-              XSTRING (attribute)->data);
-      sprintf (class_key, "%s.%s",
-              EMACS_CLASS,
-              XSTRING (class)->data);
+      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 (check_x_display_info (Qnil)->xrdb,
+                                name_key, class_key);
+
+  if (value != (char *) 0)
+    return build_string (value);
   else
+    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 (XSTRING (Vx_resource_name)->size_byte
+                             + (STRINGP (component)
+                                ? XSTRING (component)->size_byte : 0)
+                             + XSTRING (attribute)->size_byte
+                             + 3);
+
+  class_key = (char *) alloca (XSTRING (Vx_resource_class)->size_byte
+                              + XSTRING (class)->size_byte
+                              + (STRINGP (subclass)
+                                 ? XSTRING (subclass)->size_byte : 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))
     {
-      name_key = (char *) alloca (XSTRING (resname)->size
-                                 + XSTRING (component)->size
-                                 + XSTRING (attribute)->size
-                                 + 3);
-
-      class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
-                                  + XSTRING (class)->size
-                                  + XSTRING (subclass)->size
-                                  + 3);
-
-      sprintf (name_key, "%s.%s.%s",
-              XSTRING (resname)->data,
-              XSTRING (component)->data,
-              XSTRING (attribute)->data);
-      sprintf (class_key, "%s.%s.%s",
-              EMACS_CLASS,
-              XSTRING (class)->data,
-              XSTRING (subclass)->data);
+      strcat (class_key, ".");
+      strcat (class_key, XSTRING (subclass)->data);
+
+      strcat (name_key, ".");
+      strcat (name_key, XSTRING (component)->data);
     }
 
-  value = x_get_string_resource (check_x_display_info (Qnil)->xrdb,
-                                name_key, class_key);
+  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);
@@ -1949,7 +2254,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 (XSTRING (Vinvocation_name)->size_byte
                              + strlen (attribute) + 2);
   class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
                               + strlen (class) + 2);
@@ -1981,7 +2286,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;
@@ -1997,9 +2303,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;
@@ -2046,9 +2353,29 @@ x_get_arg (alist, param, attribute, class, type)
   return Fcdr (tem);
 }
 
+/* Like x_get_arg, but also record the value in f->param_alist.  */
+
+static Lisp_Object
+x_get_and_record_arg (f, alist, param, attribute, class, type)
+     struct frame *f;
+     Lisp_Object alist, param;
+     char *attribute;
+     char *class;
+     enum resource_types type;
+{
+  Lisp_Object value;
+
+  value = x_get_arg (FRAME_X_DISPLAY_INFO (f), alist, param,
+                    attribute, class, type);
+  if (! NILP (value))
+    store_frame_param (f, param, value);
+
+  return value;
+}
+
 /* 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.  */
 
@@ -2064,7 +2391,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));
@@ -2147,20 +2474,21 @@ 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
      window manager prompting.  */
-  f->width = DEFAULT_COLS;
+  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->display.x->top_pos = 0;
-  f->display.x->left_pos = 0;
+  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))
@@ -2171,7 +2499,7 @@ x_figure_window_size (f, parms)
       if (!EQ (tem1, Qunbound))
        {
          CHECK_NUMBER (tem1, 0);
-         f->width = XINT (tem1);
+         SET_FRAME_WIDTH (f, XINT (tem1));
        }
       if (!NILP (tem2) && !EQ (tem2, Qunbound))
        window_prompting |= USSize;
@@ -2179,73 +2507,73 @@ x_figure_window_size (f, parms)
        window_prompting |= PSize;
     }
 
-  f->display.x->vertical_scroll_bar_extra
+  f->output_data.x->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->display.x->font)));
-  f->display.x->pixel_width = CHAR_TO_PIXEL_WIDTH (f, f->width);
-  f->display.x->pixel_height = CHAR_TO_PIXEL_HEIGHT (f, f->height);
+       : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.x->font)));
+  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))
        {
-         f->display.x->top_pos = 0;
+         f->output_data.x->top_pos = 0;
          window_prompting |= YNegative;
        }
       else if (CONSP (tem0) && EQ (XCONS (tem0)->car, Qminus)
               && CONSP (XCONS (tem0)->cdr)
               && INTEGERP (XCONS (XCONS (tem0)->cdr)->car))
        {
-         f->display.x->top_pos = - XINT (XCONS (XCONS (tem0)->cdr)->car);
+         f->output_data.x->top_pos = - XINT (XCONS (XCONS (tem0)->cdr)->car);
          window_prompting |= YNegative;
        }
       else if (CONSP (tem0) && EQ (XCONS (tem0)->car, Qplus)
               && CONSP (XCONS (tem0)->cdr)
               && INTEGERP (XCONS (XCONS (tem0)->cdr)->car))
        {
-         f->display.x->top_pos = XINT (XCONS (XCONS (tem0)->cdr)->car);
+         f->output_data.x->top_pos = XINT (XCONS (XCONS (tem0)->cdr)->car);
        }
       else if (EQ (tem0, Qunbound))
-       f->display.x->top_pos = 0;
+       f->output_data.x->top_pos = 0;
       else
        {
          CHECK_NUMBER (tem0, 0);
-         f->display.x->top_pos = XINT (tem0);
-         if (f->display.x->top_pos < 0)
+         f->output_data.x->top_pos = XINT (tem0);
+         if (f->output_data.x->top_pos < 0)
            window_prompting |= YNegative;
        }
 
       if (EQ (tem1, Qminus))
        {
-         f->display.x->left_pos = 0;
+         f->output_data.x->left_pos = 0;
          window_prompting |= XNegative;
        }
       else if (CONSP (tem1) && EQ (XCONS (tem1)->car, Qminus)
               && CONSP (XCONS (tem1)->cdr)
               && INTEGERP (XCONS (XCONS (tem1)->cdr)->car))
        {
-         f->display.x->left_pos = - XINT (XCONS (XCONS (tem1)->cdr)->car);
+         f->output_data.x->left_pos = - XINT (XCONS (XCONS (tem1)->cdr)->car);
          window_prompting |= XNegative;
        }
       else if (CONSP (tem1) && EQ (XCONS (tem1)->car, Qplus)
               && CONSP (XCONS (tem1)->cdr)
               && INTEGERP (XCONS (XCONS (tem1)->cdr)->car))
        {
-         f->display.x->left_pos = XINT (XCONS (XCONS (tem1)->cdr)->car);
+         f->output_data.x->left_pos = XINT (XCONS (XCONS (tem1)->cdr)->car);
        }
       else if (EQ (tem1, Qunbound))
-       f->display.x->left_pos = 0;
+       f->output_data.x->left_pos = 0;
       else
        {
          CHECK_NUMBER (tem1, 0);
-         f->display.x->left_pos = XINT (tem1);
-         if (f->display.x->left_pos < 0)
+         f->output_data.x->left_pos = XINT (tem1);
+         if (f->output_data.x->left_pos < 0)
            window_prompting |= XNegative;
        }
 
@@ -2301,11 +2629,12 @@ hack_wm_protocols (f, widget)
     unsigned long nitems = 0;
     unsigned long bytes_after;
 
-    if (Success == XGetWindowProperty (dpy, w,
-                                      FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
-                                      0, 100, False, XA_ATOM,
-                                      &type, &format, &nitems, &bytes_after,
-                                      (unsigned char **) &atoms)
+    if ((XGetWindowProperty (dpy, w,
+                            FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
+                            (long)0, (long)100, False, XA_ATOM,
+                            &type, &format, &nitems, &bytes_after,
+                            (unsigned char **) &atoms)
+        == Success)
        && format == 32 && type == XA_ATOM)
       while (nitems > 0)
        {
@@ -2359,10 +2688,15 @@ x_window (f, window_prompting, minibuffer_only)
 
   BLOCK_INPUT;
 
+  /* Use the resource name as the top-level widget name
+     for looking up resources.  Make a non-Lisp copy
+     for the window manager, so GC relocation won't bother it.
+
+     Elsewhere we specify the window name for the window manager.  */
+     
   {
-    char *str
-      = (STRINGP (f->name) ? (char *)XSTRING (f->name)->data : "emacs");
-    f->namebuf = (char *) xrealloc (f->namebuf, strlen (str) + 1);
+    char *str = (char *) XSTRING (Vx_resource_name)->data;
+    f->namebuf = (char *) xmalloc (strlen (str) + 1);
     strcpy (f->namebuf, str);
   }
 
@@ -2370,11 +2704,12 @@ x_window (f, window_prompting, minibuffer_only)
   XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
   XtSetArg (al[ac], XtNinput, 1); ac++;
   XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
+  XtSetArg (al[ac], XtNborderWidth, f->output_data.x->border_width); ac++;
   shell_widget = XtAppCreateShell (f->namebuf, EMACS_CLASS,
-                                  topLevelShellWidgetClass,
+                                  applicationShellWidgetClass,
                                   FRAME_X_DISPLAY (f), al, ac);
 
-  f->display.x->widget = shell_widget;
+  f->output_data.x->widget = shell_widget;
   /* maybe_set_screen_title_format (shell_widget); */
 
   pane_widget = lw_create_widget ("main", "pane", widget_id_tick++,
@@ -2384,10 +2719,7 @@ x_window (f, window_prompting, minibuffer_only)
                                  (lw_callback) NULL,
                                  (lw_callback) NULL);
 
-  f->display.x->column_widget = pane_widget;
-
-  if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
-    initialize_frame_menubar (f);
+  f->output_data.x->column_widget = pane_widget;
 
   /* mappedWhenManaged to false tells to the paned window to not map/unmap 
      the emacs screen when changing menubar.  This reduces flickering.  */
@@ -2401,12 +2733,9 @@ x_window (f, window_prompting, minibuffer_only)
   frame_widget = XtCreateWidget (f->namebuf,
                                  emacsFrameClass,
                                  pane_widget, al, ac);
-  lw_set_main_areas (pane_widget, f->display.x->menubar_widget, frame_widget);
  
-  f->display.x->edit_widget = frame_widget;
+  f->output_data.x->edit_widget = frame_widget;
  
-  if (f->display.x->menubar_widget)
-    XtManageChild (f->display.x->menubar_widget);
   XtManageChild (frame_widget); 
 
   /* Do some needed geometry management.  */
@@ -2415,18 +2744,34 @@ x_window (f, window_prompting, minibuffer_only)
     char *tem, shell_position[32];
     Arg al[2];
     int ac = 0;
+    int extra_borders = 0;
     int menubar_size 
-      = (f->display.x->menubar_widget
-        ? (f->display.x->menubar_widget->core.height
-           + f->display.x->menubar_widget->core.border_width)
+      = (f->output_data.x->menubar_widget
+        ? (f->output_data.x->menubar_widget->core.height
+           + f->output_data.x->menubar_widget->core.border_width)
         : 0);
+    extern char *lwlib_toolkit_type;
 
+#if 0 /* Experimentally, we now get the right results
+        for -geometry -0-0 without this.  24 Aug 96, rms.  */
     if (FRAME_EXTERNAL_MENU_BAR (f))
       {
         Dimension ibw = 0;
         XtVaGetValues (pane_widget, XtNinternalBorderWidth, &ibw, NULL);
         menubar_size += ibw;
       }
+#endif
+
+    f->output_data.x->menubar_height = menubar_size;
+
+#ifndef USE_LUCID
+    /* Motif seems to need this amount added to the sizes
+       specified for the shell widget.  The Athena/Lucid widgets don't.
+       Both conclusions reached experimentally.  -- rms.  */
+    XtVaGetValues (f->output_data.x->edit_widget, XtNinternalBorderWidth,
+                  &extra_borders, NULL);
+    extra_borders *= 2;
+#endif
 
     /* Convert our geometry parameters into a geometry string
        and specify it.
@@ -2434,43 +2779,84 @@ x_window (f, window_prompting, minibuffer_only)
        is a user-specified or program-specified one.
        We pass that information later, in x_wm_set_size_hints.  */
     {
-      int left = f->display.x->left_pos;
+      int left = f->output_data.x->left_pos;
       int xneg = window_prompting & XNegative;
-      int top = f->display.x->top_pos;
+      int top = f->output_data.x->top_pos;
       int yneg = window_prompting & YNegative;
       if (xneg)
        left = -left;
       if (yneg)
        top = -top;
-      sprintf (shell_position, "=%dx%d%c%d%c%d", PIXEL_WIDTH (f), 
-              PIXEL_HEIGHT (f) + menubar_size,
-              (xneg ? '-' : '+'), left,
-              (yneg ? '-' : '+'), top);
+
+      if (window_prompting & USPosition)
+       sprintf (shell_position, "=%dx%d%c%d%c%d",
+                PIXEL_WIDTH (f) + extra_borders, 
+                PIXEL_HEIGHT (f) + menubar_size + extra_borders,
+                (xneg ? '-' : '+'), left,
+                (yneg ? '-' : '+'), top);
+      else
+       sprintf (shell_position, "=%dx%d",
+                PIXEL_WIDTH (f) + extra_borders, 
+                PIXEL_HEIGHT (f) + menubar_size + extra_borders);
     }
 
     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++;
     XtSetValues (shell_widget, al, ac);
   }
 
-  x_calc_absolute_position (f);
-
   XtManageChild (pane_widget);
   XtRealizeWidget (shell_widget);
 
   FRAME_X_WINDOW (f) = XtWindow (frame_widget); 
 
   validate_x_resource_name ();
+
   class_hints.res_name = (char *) XSTRING (Vx_resource_name)->data;
-  class_hints.res_class = EMACS_CLASS;
+  class_hints.res_class = (char *) XSTRING (Vx_resource_class)->data;
   XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
 
-  f->display.x->wm_hints.input = True;
-  f->display.x->wm_hints.flags |= InputHint;
+#ifdef HAVE_X_I18N
+#ifndef X_I18N_INHIBITED
+  { 
+    XIM xim;
+    XIC xic = NULL;
+
+    xim = XOpenIM (FRAME_X_DISPLAY (f), NULL, NULL, NULL);
+
+    if (xim)
+      {
+       xic = XCreateIC (xim,  
+                        XNInputStyle,   XIMPreeditNothing | XIMStatusNothing,
+                        XNClientWindow, FRAME_X_WINDOW(f),
+                        XNFocusWindow,  FRAME_X_WINDOW(f),
+                        NULL);
+
+       if (xic == 0)
+         {
+           XCloseIM (xim);
+           xim = NULL;
+         }
+      }
+    FRAME_XIM (f) = xim;
+    FRAME_XIC (f) = xic;
+  }
+#else /* X_I18N_INHIBITED */
+  FRAME_XIM (f) = 0;
+  FRAME_XIC (f) = 0;
+#endif /* X_I18N_INHIBITED */
+#endif /* HAVE_X_I18N */
+
+  f->output_data.x->wm_hints.input = True;
+  f->output_data.x->wm_hints.flags |= InputHint;
   XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-              &f->display.x->wm_hints);
+              &f->output_data.x->wm_hints);
 
   hack_wm_protocols (f, shell_widget);
 
@@ -2510,10 +2896,14 @@ x_window (f, window_prompting, minibuffer_only)
   }
 
   XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                f->display.x->text_cursor);
+                f->output_data.x->text_cursor);
 
   UNBLOCK_INPUT;
 
+  if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
+    initialize_frame_menubar (f);
+  lw_set_main_areas (pane_widget, f->output_data.x->menubar_widget, frame_widget);
+
   if (FRAME_X_WINDOW (f) == 0)
     error ("Unable to create window");
 }
@@ -2530,8 +2920,8 @@ x_window (f)
   XSetWindowAttributes attributes;
   unsigned long attribute_mask;
 
-  attributes.background_pixel = f->display.x->background_pixel;
-  attributes.border_pixel = f->display.x->border_pixel;
+  attributes.background_pixel = f->output_data.x->background_pixel;
+  attributes.border_pixel = f->output_data.x->border_pixel;
   attributes.bit_gravity = StaticGravity;
   attributes.backing_store = NotUseful;
   attributes.save_under = True;
@@ -2545,30 +2935,67 @@ x_window (f)
   BLOCK_INPUT;
   FRAME_X_WINDOW (f)
     = XCreateWindow (FRAME_X_DISPLAY (f),
-                    f->display.x->parent_desc,
-                    f->display.x->left_pos,
-                    f->display.x->top_pos,
+                    f->output_data.x->parent_desc,
+                    f->output_data.x->left_pos,
+                    f->output_data.x->top_pos,
                     PIXEL_WIDTH (f), PIXEL_HEIGHT (f),
-                    f->display.x->border_width,
+                    f->output_data.x->border_width,
                     CopyFromParent, /* depth */
                     InputOutput, /* class */
                     FRAME_X_DISPLAY_INFO (f)->visual,
                     attribute_mask, &attributes);
+#ifdef HAVE_X_I18N
+#ifndef X_I18N_INHIBITED
+  { 
+    XIM xim;
+    XIC xic = NULL;
+
+    xim = XOpenIM (FRAME_X_DISPLAY(f), NULL, NULL, NULL);
+
+    if (xim)
+      {
+       xic = XCreateIC (xim,  
+                        XNInputStyle,   XIMPreeditNothing | XIMStatusNothing,
+                        XNClientWindow, FRAME_X_WINDOW(f),
+                        XNFocusWindow,  FRAME_X_WINDOW(f),
+                        NULL);
+
+       if (!xic)
+         {
+           XCloseIM (xim);
+           xim = NULL;
+         }
+      }
+
+    FRAME_XIM (f) = xim;
+    FRAME_XIC (f) = xic;
+  }
+#else /* X_I18N_INHIBITED */
+  FRAME_XIM (f) = 0;
+  FRAME_XIC (f) = 0;
+#endif /* X_I18N_INHIBITED */
+#endif /* HAVE_X_I18N */
 
   validate_x_resource_name ();
+
   class_hints.res_name = (char *) XSTRING (Vx_resource_name)->data;
-  class_hints.res_class = EMACS_CLASS;
+  class_hints.res_class = (char *) XSTRING (Vx_resource_class)->data;
   XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints);
 
+  /* The menubar is part of the ordinary display;
+     it does not count in addition to the height of the window.  */
+  f->output_data.x->menubar_height = 0;
+
   /* This indicates that we use the "Passive Input" input model.
      Unless we do this, we don't get the Focus{In,Out} events that we
      need to draw the cursor correctly.  Accursed bureaucrats.
    XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack);  */
 
-  f->display.x->wm_hints.input = True;
-  f->display.x->wm_hints.flags |= InputHint;
+  f->output_data.x->wm_hints.input = True;
+  f->output_data.x->wm_hints.flags |= InputHint;
   XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-              &f->display.x->wm_hints);
+              &f->output_data.x->wm_hints);
+  f->output_data.x->wm_hints.icon_pixmap = None;
 
   /* Request "save yourself" and "delete window" commands from wm.  */
   {
@@ -2593,7 +3020,7 @@ x_window (f)
   }
 
   XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                f->display.x->text_cursor);
+                f->output_data.x->text_cursor);
 
   UNBLOCK_INPUT;
 
@@ -2613,11 +3040,12 @@ 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.  */
-  icon_x = x_get_arg (parms, Qicon_left, 0, 0, number);
-  icon_y = x_get_arg (parms, Qicon_top, 0, 0, number);
+  icon_x = x_get_and_record_arg (f, parms, Qicon_left, 0, 0, number);
+  icon_y = x_get_and_record_arg (f, parms, Qicon_top, 0, 0, number);
   if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
     {
       CHECK_NUMBER (icon_x, 0);
@@ -2633,10 +3061,14 @@ 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));
 
+  x_text_icon (f, (char *) XSTRING ((!NILP (f->icon_name)
+                                    ? f->icon_name
+                                    : f->name))->data);
+
   UNBLOCK_INPUT;
 }
 
@@ -2666,34 +3098,34 @@ x_make_gc (f)
      Note that many default values are used.  */
 
   /* Normal video */
-  gc_values.font = f->display.x->font->fid;
-  gc_values.foreground = f->display.x->foreground_pixel;
-  gc_values.background = f->display.x->background_pixel;
+  gc_values.font = f->output_data.x->font->fid;
+  gc_values.foreground = f->output_data.x->foreground_pixel;
+  gc_values.background = f->output_data.x->background_pixel;
   gc_values.line_width = 0;    /* Means 1 using fast algorithm.  */
-  f->display.x->normal_gc = XCreateGC (FRAME_X_DISPLAY (f),
+  f->output_data.x->normal_gc = XCreateGC (FRAME_X_DISPLAY (f),
                                       FRAME_X_WINDOW (f),
                                       GCLineWidth | GCFont
                                       | GCForeground | GCBackground,
                                       &gc_values);
 
   /* Reverse video style.  */
-  gc_values.foreground = f->display.x->background_pixel;
-  gc_values.background = f->display.x->foreground_pixel;
-  f->display.x->reverse_gc = XCreateGC (FRAME_X_DISPLAY (f),
+  gc_values.foreground = f->output_data.x->background_pixel;
+  gc_values.background = f->output_data.x->foreground_pixel;
+  f->output_data.x->reverse_gc = XCreateGC (FRAME_X_DISPLAY (f),
                                        FRAME_X_WINDOW (f),
                                        GCFont | GCForeground | GCBackground
                                        | GCLineWidth,
                                        &gc_values);
 
   /* Cursor has cursor-color background, background-color foreground.  */
-  gc_values.foreground = f->display.x->background_pixel;
-  gc_values.background = f->display.x->cursor_pixel;
+  gc_values.foreground = f->output_data.x->background_pixel;
+  gc_values.background = f->output_data.x->cursor_pixel;
   gc_values.fill_style = FillOpaqueStippled;
   gc_values.stipple
     = XCreateBitmapFromData (FRAME_X_DISPLAY (f),
                             FRAME_X_DISPLAY_INFO (f)->root_window,
                             cursor_bits, 16, 16);
-  f->display.x->cursor_gc
+  f->output_data.x->cursor_gc
     = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                 (GCFont | GCForeground | GCBackground
                  | GCFillStyle | GCStipple | GCLineWidth),
@@ -2702,12 +3134,12 @@ x_make_gc (f)
   /* Create the gray border tile used when the pointer is not in
      the frame.  Since this depends on the frame's pixel values,
      this must be done on a per-frame basis.  */
-  f->display.x->border_tile
+  f->output_data.x->border_tile
     = (XCreatePixmapFromBitmapData
        (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window, 
        gray_bits, gray_width, gray_height,
-       f->display.x->foreground_pixel,
-       f->display.x->background_pixel,
+       f->output_data.x->foreground_pixel,
+       f->output_data.x->background_pixel,
        DefaultDepth (FRAME_X_DISPLAY (f),
                      XScreenNumberOfScreen (FRAME_X_SCREEN (f)))));
 
@@ -2735,7 +3167,7 @@ This function is an internal primitive--use `make-frame' instead.")
   long window_prompting = 0;
   int width, height;
   int count = specpdl_ptr - specpdl;
-  struct gcpro gcpro1;
+  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
   Lisp_Object display;
   struct x_display_info *dpyinfo;
   Lisp_Object parent;
@@ -2743,7 +3175,11 @@ This function is an internal primitive--use `make-frame' instead.")
 
   check_x ();
 
-  display = x_get_arg (parms, Qdisplay, 0, 0, 0);
+  /* Use this general default value to start with
+     until we know if this frame has a specified name.  */
+  Vx_resource_name = Vinvocation_name;
+
+  display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, string);
   if (EQ (display, Qunbound))
     display = Qnil;
   dpyinfo = check_x_display_info (display);
@@ -2753,42 +3189,55 @@ This function is an internal primitive--use `make-frame' instead.")
   kb = &the_only_kboard;
 #endif
 
-  name = x_get_arg (parms, Qname, "title", "Title", string);
+  name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", string);
   if (!STRINGP (name)
       && ! EQ (name, Qunbound)
       && ! NILP (name))
     error ("Invalid frame name--not a string or nil");
 
+  if (STRINGP (name))
+    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))
     CHECK_NUMBER (parent, 0);
 
-  tem = x_get_arg (parms, Qminibuffer, 0, 0, symbol);
+  /* make_frame_without_minibuffer can run Lisp code and garbage collect.  */
+  /* No need to protect DISPLAY because that's not used after passing
+     it to make_frame_without_minibuffer.  */
+  frame = Qnil;
+  GCPRO4 (parms, parent, name, frame);
+  tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer", symbol);
   if (EQ (tem, Qnone) || NILP (tem))
-    f = make_frame_without_minibuffer (Qnil, kb);
+    f = make_frame_without_minibuffer (Qnil, kb, display);
   else if (EQ (tem, Qonly))
     {
       f = make_minibuffer_frame ();
       minibuffer_only = 1;
     }
   else if (WINDOWP (tem))
-    f = make_frame_without_minibuffer (tem, kb);
+    f = make_frame_without_minibuffer (tem, kb, display);
   else
     f = make_frame (1);
 
+  XSETFRAME (frame, f);
+
   /* Note that X Windows does support scroll bars.  */
   FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
 
-  XSETFRAME (frame, f);
-  GCPRO1 (frame);
-
   f->output_method = output_x_window;
-  f->display.x = (struct x_display *) xmalloc (sizeof (struct x_display));
-  bzero (f->display.x, sizeof (struct x_display));
-  f->display.x->icon_bitmap = -1;
+  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 (dpyinfo, parms, Qicon_name, "iconName", "Title", string);
+  if (! STRINGP (f->icon_name))
+    f->icon_name = Qnil;
 
   FRAME_X_DISPLAY_INFO (f) = dpyinfo;
 #ifdef MULTI_KBOARD
@@ -2799,13 +3248,13 @@ This function is an internal primitive--use `make-frame' instead.")
 
   if (!NILP (parent))
     {
-      f->display.x->parent_desc = parent;
-      f->display.x->explicit_parent = 1;
+      f->output_data.x->parent_desc = (Window) XFASTINT (parent);
+      f->output_data.x->explicit_parent = 1;
     }
   else
     {
-      f->display.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
-      f->display.x->explicit_parent = 0;
+      f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
+      f->output_data.x->explicit_parent = 0;
     }
 
   /* Note that the frame has no physical cursor right now.  */
@@ -2826,16 +3275,27 @@ This function is an internal primitive--use `make-frame' instead.")
       specbind (Qx_resource_name, name);
     }
 
+  /* Create fontsets from `global_fontset_alist' before handling fonts.  */
+  for (tem = Vglobal_fontset_alist; CONSP (tem); tem = XCONS (tem)->cdr)
+    fs_register_fontset (f, XCONS (tem)->car);
+
   /* Extract the window parameters from the supplied values
      that are needed to determine window geometry.  */
   {
     Lisp_Object font;
 
-    font = x_get_arg (parms, Qfont, "font", "Font", string);
+    font = x_get_arg (dpyinfo, 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);
+      {
+       tem = Fquery_fontset (font);
+       if (STRINGP (tem))
+         font = x_new_fontset (f, XSTRING (tem)->data);
+       else
+         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-*-*-140-*-*-c-*-iso8859-1");
@@ -2852,14 +3312,14 @@ 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);
   }
 
-#ifdef USE_X_TOOLKIT
+#ifdef USE_LUCID
   /* Prevent lwlib/xlwmenu.c from crashing because of a bug
      whereby it fails to get any font.  */
-  xlwmenu_default_font = f->display.x->font;
+  xlwmenu_default_font = f->output_data.x->font;
 #endif
 
   x_default_parameter (f, parms, Qborder_width, make_number (2),
@@ -2871,16 +3331,16 @@ This function is an internal primitive--use `make-frame' instead.")
     {
       Lisp_Object value;
 
-      value = x_get_arg (parms, Qinternal_border_width,
-                        "internalBorder", "BorderWidth", number);
+      value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
+                        "internalBorder", "internalBorder", 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,
-                      "verticalScrollBars", "ScrollBars", boolean);
+  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", symbol);
 
   /* Also do the stuff which must be set before the window exists.  */
   x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
@@ -2898,26 +3358,30 @@ This function is an internal primitive--use `make-frame' instead.")
                       "menuBar", "MenuBar", number);
   x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
                       "scrollBarWidth", "ScrollBarWidth", number);
+  x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
+                      "bufferPredicate", "BufferPredicate", symbol);
+  x_default_parameter (f, parms, Qtitle, Qnil,
+                      "title", "Title", string);
 
-  f->display.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
+  f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
   window_prompting = x_figure_window_size (f, parms);
 
   if (window_prompting & XNegative)
     {
       if (window_prompting & YNegative)
-       f->display.x->win_gravity = SouthEastGravity;
+       f->output_data.x->win_gravity = SouthEastGravity;
       else
-       f->display.x->win_gravity = NorthEastGravity;
+       f->output_data.x->win_gravity = NorthEastGravity;
     }
   else
     {
       if (window_prompting & YNegative)
-       f->display.x->win_gravity = SouthWestGravity;
+       f->output_data.x->win_gravity = SouthWestGravity;
       else
-       f->display.x->win_gravity = NorthWestGravity;
+       f->output_data.x->win_gravity = NorthWestGravity;
     }
 
-  f->display.x->size_hint_flags = window_prompting;
+  f->output_data.x->size_hint_flags = window_prompting;
 
 #ifdef USE_X_TOOLKIT
   x_window (f, window_prompting, minibuffer_only);
@@ -2945,7 +3409,8 @@ This function is an internal primitive--use `make-frame' instead.")
      f->height.  */
   width = f->width;
   height = f->height;
-  f->height = f->width = 0;
+  f->height = 0;
+  SET_FRAME_WIDTH (f, 0);
   change_frame_size (f, height, width, 1, 0);
 
   /* Tell the server what size and position, etc, we want,
@@ -2954,7 +3419,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;
@@ -2972,11 +3437,11 @@ This function is an internal primitive--use `make-frame' instead.")
   /* Make the window appear on the frame and enable display,
      unless the caller says not to.  However, with explicit parent,
      Emacs cannot control visibility, so don't try.  */
-  if (! f->display.x->explicit_parent)
+  if (! f->output_data.x->explicit_parent)
     {
       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;
 
@@ -2995,6 +3460,7 @@ This function is an internal primitive--use `make-frame' instead.")
 /* FRAME is used only to get a handle on the X display.  We don't pass the
    display info directly because we're called from frame.c, which doesn't
    know about that structure.  */
+
 Lisp_Object
 x_get_focus_frame (frame)
      struct frame *frame;
@@ -3007,45 +3473,11 @@ x_get_focus_frame (frame)
   XSETFRAME (xfocus, dpyinfo->x_focus_frame);
   return xfocus;
 }
-
-DEFUN ("focus-frame", Ffocus_frame, Sfocus_frame, 1, 1, 0,
-  "Set the focus on FRAME.")
-  (frame)
-     Lisp_Object frame;
-{
-  CHECK_LIVE_FRAME (frame, 0);
-
-  if (FRAME_X_P (XFRAME (frame)))
-    {
-      BLOCK_INPUT;
-      x_focus_on_frame (XFRAME (frame));
-      UNBLOCK_INPUT;
-      return frame;
-    }
-
-  return Qnil;
-}
-
-DEFUN ("unfocus-frame", Funfocus_frame, Sunfocus_frame, 0, 0, 0,
-  "If a frame has been focused, release it.")
-  ()
-{
-  if (FRAME_X_P (selected_frame))
-    {
-      struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (selected_frame);
-
-      if (dpyinfo->x_focus_frame)
-       {
-         BLOCK_INPUT;
-         x_unfocus_frame (dpyinfo->x_focus_frame);
-         UNBLOCK_INPUT;
-       }
-    }
-
-  return Qnil;
-}
 \f
-DEFUN ("x-list-fonts", Fx_list_fonts, Sx_list_fonts, 1, 3, 0,
+#if 1
+#include "x-list-font.c"
+#else
+DEFUN ("x-list-fonts", Fx_list_fonts, Sx_list_fonts, 1, 4, 0,
   "Return a list of the names of available fonts matching PATTERN.\n\
 If optional arguments FACE and FRAME are specified, return only fonts\n\
 the same size as FACE on FRAME.\n\
@@ -3060,9 +3492,12 @@ The return value is a list of strings, suitable as arguments to\n\
 set-face-font.\n\
 \n\
 Fonts Emacs can't use (i.e. proportional fonts) may or may not be excluded\n\
-even if they match PATTERN and FACE.")
-  (pattern, face, frame)
-    Lisp_Object pattern, face, frame;
+even if they match PATTERN and FACE.\n\
+\n\
+The optional fourth argument MAXIMUM sets a limit on how many\n\
+fonts to match.  The first MAXIMUM fonts are reported.")
+  (pattern, face, frame, maximum)
+    Lisp_Object pattern, face, frame, maximum;
 {
   int num_fonts;
   char **names;
@@ -3072,12 +3507,23 @@ even if they match PATTERN and FACE.")
   XFontStruct *size_ref;
   Lisp_Object list;
   FRAME_PTR f;
+  Lisp_Object key;
+  int maxnames;
+  int count;
 
   check_x ();
   CHECK_STRING (pattern, 0);
   if (!NILP (face))
     CHECK_SYMBOL (face, 1);
 
+  if (NILP (maximum))
+    maxnames = 2000;
+  else
+    {
+      CHECK_NATNUM (maximum, 0);
+      maxnames = XINT (maximum);
+    }
+
   f = check_x_frame (frame);
 
   /* Determine the width standard for comparison with the fonts we find.  */
@@ -3090,23 +3536,24 @@ even if they match PATTERN and FACE.")
 
       /* Don't die if we get called with a terminal frame.  */
       if (! FRAME_X_P (f))
-       error ("non-X frame used in `x-list-fonts'");
+       error ("Non-X frame used in `x-list-fonts'");
 
       face_id = face_name_id_number (f, face);
 
       if (face_id < 0 || face_id >= FRAME_N_PARAM_FACES (f)
          || FRAME_PARAM_FACES (f) [face_id] == 0)
-       size_ref = f->display.x->font;
+       size_ref = f->output_data.x->font;
       else
        {
          size_ref = FRAME_PARAM_FACES (f) [face_id]->font;
          if (size_ref == (XFontStruct *) (~0))
-           size_ref = f->display.x->font;
+           size_ref = f->output_data.x->font;
        }
     }
 
   /* See if we cached the result for this particular query.  */
-  list = Fassoc (pattern,
+  key = Fcons (pattern, maximum);
+  list = Fassoc (key,
                 XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr);
 
   /* We have info in the cache for this PATTERN.  */
@@ -3128,13 +3575,19 @@ even if they match PATTERN and FACE.")
        {
          XFontStruct *thisinfo;
 
-          thisinfo = XLoadQueryFont (FRAME_X_DISPLAY (f),
+         count = x_catch_errors (FRAME_X_DISPLAY (f));
+
+         thisinfo = XLoadQueryFont (FRAME_X_DISPLAY (f),
                                     XSTRING (XCONS (tem)->car)->data);
 
-          if (thisinfo && same_size_fonts (thisinfo, size_ref))
+         x_check_errors (FRAME_X_DISPLAY (f), "XLoadQueryFont failure: %s");
+         x_uncatch_errors (FRAME_X_DISPLAY (f), count);
+
+         if (thisinfo && same_size_fonts (thisinfo, size_ref))
            newlist = Fcons (XCONS (tem)->car, newlist);
 
-         XFreeFont (FRAME_X_DISPLAY (f), thisinfo);
+         if (thisinfo != 0)
+           XFreeFont (FRAME_X_DISPLAY (f), thisinfo);
         }
 
       UNBLOCK_INPUT;
@@ -3144,21 +3597,26 @@ even if they match PATTERN and FACE.")
 
   BLOCK_INPUT;
 
+  count = x_catch_errors (FRAME_X_DISPLAY (f));
+
   /* Solaris 2.3 has a bug in XListFontsWithInfo.  */
 #ifndef BROKEN_XLISTFONTSWITHINFO
   if (size_ref)
     names = XListFontsWithInfo (FRAME_X_DISPLAY (f),
                                XSTRING (pattern)->data,
-                               2000, /* maxnames */
+                               maxnames, 
                                &num_fonts, /* count_return */
                                &info); /* info_return */
   else
 #endif
     names = XListFonts (FRAME_X_DISPLAY (f),
                        XSTRING (pattern)->data,
-                       2000, /* maxnames */
+                       maxnames,
                        &num_fonts); /* count_return */
 
+  x_check_errors (FRAME_X_DISPLAY (f), "XListFonts failure: %s");
+  x_uncatch_errors (FRAME_X_DISPLAY (f), count);
+
   UNBLOCK_INPUT;
 
   list = Qnil;
@@ -3174,7 +3632,7 @@ even if they match PATTERN and FACE.")
       for (i = 0; i < num_fonts; i++)
        full_list = Fcons (build_string (names[i]), full_list);
       XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr
-       = Fcons (Fcons (pattern, full_list),
+       = Fcons (Fcons (key, full_list),
                 XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr);
 
       /* Make a list of the fonts that have the right width.  */
@@ -3191,10 +3649,22 @@ even if they match PATTERN and FACE.")
              XFontStruct *thisinfo;
 
              BLOCK_INPUT;
+
+             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), count);
+
              UNBLOCK_INPUT;
 
              keeper = thisinfo && same_size_fonts (thisinfo, size_ref);
+             BLOCK_INPUT;
+             if (thisinfo && ! keeper)
+               XFreeFont (FRAME_X_DISPLAY (f), thisinfo);
+             else if (thisinfo)
+               XFreeFontInfo (NULL, thisinfo, 1);
+             UNBLOCK_INPUT;
 #else
              keeper = same_size_fonts (&info[i], size_ref);
 #endif
@@ -3216,6 +3686,7 @@ even if they match PATTERN and FACE.")
 
   return list;
 }
+#endif
 
 \f
 DEFUN ("x-color-defined-p", Fx_color_defined_p, Sx_color_defined_p, 1, 2, 0,
@@ -3291,6 +3762,7 @@ If omitted or nil, that stands for the selected frame's display.")
 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
   0, 1, 0,
   "Return t if the X display supports shades of gray.\n\
+Note that color displays do support shades of gray.\n\
 The optional argument DISPLAY specifies which display to ask about.\n\
 DISPLAY should be either a frame or a display name (a string).\n\
 If omitted or nil, that stands for the selected frame's display.")
@@ -3299,12 +3771,22 @@ If omitted or nil, that stands for the selected frame's display.")
 {
   struct x_display_info *dpyinfo = check_x_display_info (display);
 
-  if (dpyinfo->n_planes <= 2)
+  if (dpyinfo->n_planes <= 1)
     return Qnil;
 
-  return (dpyinfo->n_planes > 1
-         && (dpyinfo->visual->class == StaticGray
-             || dpyinfo->visual->class == GrayScale));
+  switch (dpyinfo->visual->class)
+    {
+    case StaticColor:
+    case PseudoColor:
+    case TrueColor:
+    case DirectColor:
+    case StaticGray:
+    case GrayScale:
+      return Qt;
+
+    default:
+      return Qnil;
+    }
 }
 
 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
@@ -3541,21 +4023,21 @@ int
 x_char_width (f)
      register struct frame *f;
 {
-  return FONT_WIDTH (f->display.x->font);
+  return FONT_WIDTH (f->output_data.x->font);
 }
 
 int
 x_char_height (f)
      register struct frame *f;
 {
-  return f->display.x->line_height;
+  return f->output_data.x->line_height;
 }
 
 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.  */
@@ -3572,19 +4054,19 @@ x_rectangle (f, gc, left_char, top_char, chars, lines)
 {
   int width;
   int height;
-  int left = (left_char * FONT_WIDTH (f->display.x->font)
-                   + f->display.x->internal_border_width);
-  int top = (top_char * f->display.x->line_height
-                  + f->display.x->internal_border_width);
+  int left = (left_char * FONT_WIDTH (f->output_data.x->font)
+                   + f->output_data.x->internal_border_width);
+  int top = (top_char * f->output_data.x->line_height
+                  + f->output_data.x->internal_border_width);
 
   if (chars < 0)
-    width = FONT_WIDTH (f->display.x->font) / 2;
+    width = FONT_WIDTH (f->output_data.x->font) / 2;
   else
-    width = FONT_WIDTH (f->display.x->font) * chars;
+    width = FONT_WIDTH (f->output_data.x->font) * chars;
   if (lines < 0)
-    height = f->display.x->line_height / 2;
+    height = f->output_data.x->line_height / 2;
   else
-    height = f->display.x->line_height * lines;
+    height = f->output_data.x->line_height * lines;
 
   XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                  gc, left, top, width, height);
@@ -3632,7 +4114,7 @@ numbers X0, Y0, X1, Y1 in the cursor pixel.")
     }
 
   BLOCK_INPUT;
-  x_rectangle (XFRAME (frame), XFRAME (frame)->display.x->cursor_gc,
+  x_rectangle (XFRAME (frame), XFRAME (frame)->output_data.x->cursor_gc,
               left, top, n_chars, n_lines);
   UNBLOCK_INPUT;
 
@@ -3681,7 +4163,7 @@ X0, Y0, X1, Y1 in the regular background-pixel.")
     }
 
   BLOCK_INPUT;
-  x_rectangle (XFRAME (frame), XFRAME (frame)->display.x->reverse_gc,
+  x_rectangle (XFRAME (frame), XFRAME (frame)->output_data.x->reverse_gc,
               left, top, n_chars, n_lines);
   UNBLOCK_INPUT;
 
@@ -3700,9 +4182,9 @@ outline_region (f, gc, top_x, top_y, bottom_x, bottom_y)
      GC gc;
      int  top_x, top_y, bottom_x, bottom_y;
 {
-  register int ibw = f->display.x->internal_border_width;
-  register int font_w = FONT_WIDTH (f->display.x->font);
-  register int font_h = f->display.x->line_height;
+  register int ibw = f->output_data.x->internal_border_width;
+  register int font_w = FONT_WIDTH (f->output_data.x->font);
+  register int font_h = f->output_data.x->line_height;
   int y = top_y;
   int x = line_len (y);
   XPoint *pixel_points
@@ -3795,18 +4277,18 @@ selected frame.")
   y1 = f->cursor_y;
 
   if (y1 > y0)                 /* point below mouse */
-    outline_region (f, f->display.x->cursor_gc,
+    outline_region (f, f->output_data.x->cursor_gc,
                    x0, y0, x1, y1);
   else if (y1 < y0)            /* point above mouse */
-    outline_region (f, f->display.x->cursor_gc,
+    outline_region (f, f->output_data.x->cursor_gc,
                    x1, y1, x0, y0);
   else                         /* same line: draw horizontal rectangle */
     {
       if (x1 > x0)
-       x_rectangle (f, f->display.x->cursor_gc,
+       x_rectangle (f, f->output_data.x->cursor_gc,
                     x0, y0, (x1 - x0 + 1), 1);
       else if (x1 < x0)
-         x_rectangle (f, f->display.x->cursor_gc,
+         x_rectangle (f, f->output_data.x->cursor_gc,
                       x1, y1, (x0 - x1 + 1), 1);
     }
 
@@ -3832,18 +4314,18 @@ at X, Y on the selected frame.")
   y1 = f->cursor_y;
 
   if (y1 > y0)                 /* point below mouse */
-    outline_region (f, f->display.x->reverse_gc,
+    outline_region (f, f->output_data.x->reverse_gc,
                      x0, y0, x1, y1);
   else if (y1 < y0)            /* point above mouse */
-    outline_region (f, f->display.x->reverse_gc,
+    outline_region (f, f->output_data.x->reverse_gc,
                      x1, y1, x0, y0);
   else                         /* same line: draw horizontal rectangle */
     {
       if (x1 > x0)
-       x_rectangle (f, f->display.x->reverse_gc,
+       x_rectangle (f, f->output_data.x->reverse_gc,
                     x0, y0, (x1 - x0 + 1), 1);
       else if (x1 < x0)
-       x_rectangle (f, f->display.x->reverse_gc,
+       x_rectangle (f, f->output_data.x->reverse_gc,
                     x1, y1, (x0 - x1 + 1), 1);
     }
   UNBLOCK_INPUT;
@@ -3944,13 +4426,13 @@ DEFUN ("x-select-region", Fx_select_region, Sx_select_region, 1, 1, "e",
                               && x_contour_x > point_x))
    {
      mouse_below_point = 1;
-     outline_region (f, f->display.x->cursor_gc, point_x, point_y,
+     outline_region (f, f->output_data.x->cursor_gc, point_x, point_y,
                     x_contour_x, x_contour_y);
    }
  else
    {
      mouse_below_point = 0;
-     outline_region (f, f->display.x->cursor_gc, x_contour_x, x_contour_y,
+     outline_region (f, f->output_data.x->cursor_gc, x_contour_x, x_contour_y,
                     point_x, point_y);
    }
 
@@ -3966,9 +4448,9 @@ DEFUN ("x-select-region", Fx_select_region, Sx_select_region, 1, 1, "e",
           {
             mouse_below_point = 0;
 
-            outline_region (f, f->display.x->reverse_gc, point_x, point_y,
+            outline_region (f, f->output_data.x->reverse_gc, point_x, point_y,
                             x_contour_x, x_contour_y);
-            outline_region (f, f->display.x->cursor_gc, x_mouse_x, x_mouse_y,
+            outline_region (f, f->output_data.x->cursor_gc, x_mouse_x, x_mouse_y,
                             point_x, point_y);
           }
         else if (x_mouse_y < x_contour_y)        /* Bottom clipped.  */
@@ -3989,9 +4471,9 @@ DEFUN ("x-select-region", Fx_select_region, Sx_select_region, 1, 1, "e",
           {
             mouse_below_point = 1;
 
-            outline_region (f, f->display.x->reverse_gc,
+            outline_region (f, f->output_data.x->reverse_gc,
                             x_contour_x, x_contour_y, point_x, point_y);
-            outline_region (f, f->display.x->cursor_gc, point_x, point_y,
+            outline_region (f, f->output_data.x->cursor_gc, point_x, point_y,
                             x_mouse_x, x_mouse_y);
           }
         else if (x_mouse_y > x_contour_y)        /* Top clipped.  */
@@ -4031,27 +4513,27 @@ DEFUN ("x-horizontal-line", Fx_horizontal_line, Sx_horizontal_line, 1, 1, "e",
   register Lisp_Object obj;
   struct frame *f = selected_frame;
   register struct window *w = XWINDOW (selected_window);
-  register GC line_gc = f->display.x->cursor_gc;
-  register GC erase_gc = f->display.x->reverse_gc;
+  register GC line_gc = f->output_data.x->cursor_gc;
+  register GC erase_gc = f->output_data.x->reverse_gc;
 #if 0
   char dash_list[] = {6, 4, 6, 4};
   int dashes = 4;
   XGCValues gc_values;
 #endif
   register int previous_y;
-  register int line = (x_mouse_y + 1) * f->display.x->line_height
-    + f->display.x->internal_border_width;
-  register int left = f->display.x->internal_border_width
-    + (w->left
-       * FONT_WIDTH (f->display.x->font));
+  register int line = (x_mouse_y + 1) * f->output_data.x->line_height
+    + f->output_data.x->internal_border_width;
+  register int left = f->output_data.x->internal_border_width
+    + (WINDOW_LEFT_MARGIN (w)
+       * FONT_WIDTH (f->output_data.x->font));
   register int right = left + (w->width
-                              * FONT_WIDTH (f->display.x->font))
-    - f->display.x->internal_border_width;
+                              * FONT_WIDTH (f->output_data.x->font))
+    - f->output_data.x->internal_border_width;
 
 #if 0
   BLOCK_INPUT;
-  gc_values.foreground = f->display.x->cursor_pixel;
-  gc_values.background = f->display.x->background_pixel;
+  gc_values.foreground = f->output_data.x->cursor_pixel;
+  gc_values.background = f->output_data.x->background_pixel;
   gc_values.line_width = 1;
   gc_values.line_style = LineOnOffDash;
   gc_values.cap_style = CapRound;
@@ -4062,13 +4544,14 @@ DEFUN ("x-horizontal-line", Fx_horizontal_line, Sx_horizontal_line, 1, 1, "e",
                       | GCLineWidth | GCForeground | GCBackground,
                       &gc_values);
   XSetDashes (FRAME_X_DISPLAY (f), line_gc, 0, dash_list, dashes);
-  gc_values.foreground = f->display.x->background_pixel;
-  gc_values.background = f->display.x->foreground_pixel;
+  gc_values.foreground = f->output_data.x->background_pixel;
+  gc_values.background = f->output_data.x->foreground_pixel;
   erase_gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                       GCLineStyle | GCJoinStyle | GCCapStyle
                       | GCLineWidth | GCForeground | GCBackground,
                       &gc_values);
   XSetDashes (FRAME_X_DISPLAY (f), erase_gc, 0, dash_list, dashes);
+  UNBLOCK_INPUT;
 #endif
 
   while (1)
@@ -4078,8 +4561,8 @@ DEFUN ("x-horizontal-line", Fx_horizontal_line, Sx_horizontal_line, 1, 1, "e",
          && x_mouse_y < XINT (w->top) + XINT (w->height) - 1)
        {
          previous_y = x_mouse_y;
-         line = (x_mouse_y + 1) * f->display.x->line_height
-           + f->display.x->internal_border_width;
+         line = (x_mouse_y + 1) * f->output_data.x->line_height
+           + f->output_data.x->internal_border_width;
          XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                     line_gc, left, line, right, line);
        }
@@ -4097,12 +4580,12 @@ DEFUN ("x-horizontal-line", Fx_horizontal_line, Sx_horizontal_line, 1, 1, "e",
              BLOCK_INPUT;
              XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                         erase_gc, left, line, right, line);
-             UNBLOCK_INPUT;
              unread_command_event = obj;
 #if 0
              XFreeGC (FRAME_X_DISPLAY (f), line_gc);
              XFreeGC (FRAME_X_DISPLAY (f), erase_gc);
 #endif 
+             UNBLOCK_INPUT;
              return Qnil;
            }
        }
@@ -4132,12 +4615,12 @@ DEFUN ("x-track-pointer", Fx_track_pointer, Sx_track_pointer, 0, 0, 0,
 
   BLOCK_INPUT;
   if (EQ (Vmouse_frame_part, Qtext_part)
-      && (current_pointer_shape != f->display.x->nontext_cursor))
+      && (current_pointer_shape != f->output_data.x->nontext_cursor))
     {
       unsigned char c;
       struct buffer *buf;
 
-      current_pointer_shape = f->display.x->nontext_cursor;
+      current_pointer_shape = f->output_data.x->nontext_cursor;
       XDefineCursor (FRAME_X_DISPLAY (f),
                     FRAME_X_WINDOW (f),
                     current_pointer_shape);
@@ -4146,9 +4629,9 @@ DEFUN ("x-track-pointer", Fx_track_pointer, Sx_track_pointer, 0, 0, 0,
       c = *(BUF_CHAR_ADDRESS (buf, mouse_buffer_offset));
     }
   else if (EQ (Vmouse_frame_part, Qmodeline_part)
-          && (current_pointer_shape != f->display.x->modeline_cursor))
+          && (current_pointer_shape != f->output_data.x->modeline_cursor))
     {
-      current_pointer_shape = f->display.x->modeline_cursor;
+      current_pointer_shape = f->output_data.x->modeline_cursor;
       XDefineCursor (FRAME_X_DISPLAY (f),
                     FRAME_X_WINDOW (f),
                     current_pointer_shape);
@@ -4206,7 +4689,7 @@ DEFUN ("x-track-pointer", Fx_track_pointer, Sx_track_pointer, 1, 1, "e",
          /* Erase previous rectangle.  */
          if (mouse_track_width)
            {
-             x_rectangle (f, f->display.x->reverse_gc,
+             x_rectangle (f, f->output_data.x->reverse_gc,
                           mouse_track_left, mouse_track_top,
                           mouse_track_width, 1);
 
@@ -4234,7 +4717,7 @@ DEFUN ("x-track-pointer", Fx_track_pointer, Sx_track_pointer, 1, 1, "e",
          if (tab_width <= 0 || tab_width > 20) tab_width = 8;
          do
            {
-             c = FETCH_CHAR (p);
+             c = FETCH_BYTE (p);
              if (len == f->width && hp == len - 1 && c != '\n')
                goto draw_or_not;
 
@@ -4286,19 +4769,19 @@ DEFUN ("x-track-pointer", Fx_track_pointer, Sx_track_pointer, 1, 1, "e",
            {
              XDefineCursor (FRAME_X_DISPLAY (f),
                             FRAME_X_WINDOW (f),
-                            f->display.x->text_cursor);
-             x_rectangle (f, f->display.x->cursor_gc,
+                            f->output_data.x->text_cursor);
+             x_rectangle (f, f->output_data.x->cursor_gc,
                           mouse_track_left, mouse_track_top,
                           mouse_track_width, 1);
            }
          else if (in_mode_line)
            XDefineCursor (FRAME_X_DISPLAY (f),
                           FRAME_X_WINDOW (f),
-                          f->display.x->modeline_cursor);
+                          f->output_data.x->modeline_cursor);
          else
            XDefineCursor (FRAME_X_DISPLAY (f),
                           FRAME_X_WINDOW (f),
-                          f->display.x->nontext_cursor);
+                          f->output_data.x->nontext_cursor);
        }
 
       XFlush (FRAME_X_DISPLAY (f));
@@ -4317,7 +4800,7 @@ DEFUN ("x-track-pointer", Fx_track_pointer, Sx_track_pointer, 1, 1, "e",
 
   if (mouse_track_width)
     {
-      x_rectangle (f, f->display.x->reverse_gc,
+      x_rectangle (f, f->output_data.x->reverse_gc,
                   mouse_track_left, mouse_track_top,
                   mouse_track_width, 1);
       mouse_track_width = 0;
@@ -4330,7 +4813,7 @@ DEFUN ("x-track-pointer", Fx_track_pointer, Sx_track_pointer, 1, 1, "e",
     }
   XDefineCursor (FRAME_X_DISPLAY (f),
                 FRAME_X_WINDOW (f),
-                f->display.x->nontext_cursor);
+                f->output_data.x->nontext_cursor);
   XFlush (FRAME_X_DISPLAY (f));
   UNBLOCK_INPUT;
 
@@ -4355,7 +4838,7 @@ x_draw_pixmap (f, x, y, image_data, width, height)
                                 FRAME_X_WINDOW (f), image_data,
                                 width, height);
   XCopyPlane (FRAME_X_DISPLAY (f), image, FRAME_X_WINDOW (f),
-             f->display.x->normal_gc, 0, 0, width, height, x, y);
+             f->output_data.x->normal_gc, 0, 0, width, height, x, y);
 }
 #endif
 \f
@@ -4388,7 +4871,7 @@ 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, XSTRING (newstring)->size_byte);
   else
     {
       register Lisp_Object rest, mod;
@@ -4416,7 +4899,7 @@ also be depressed for NEWSTRING to appear.")
        }
 
       XRebindKeysym (x_current_display, keysym, modifier_list, i,
-                    XSTRING (newstring)->data, XSTRING (newstring)->size);
+                    XSTRING (newstring)->data, XSTRING (newstring)->size_byte);
     }
 
   return Qnil;
@@ -4447,7 +4930,7 @@ See the documentation of `x-rebind-key' for more information.")
       if (!NILP (item))
        {
          CHECK_STRING (item, 2);
-         strsize = XSTRING (item)->size;
+         strsize = XSTRING (item)->size_byte;
          rawstring = (unsigned char *) xmalloc (strsize);
          bcopy (XSTRING (item)->data, rawstring, strsize);
          modifier[1] = 1 << i;
@@ -4536,6 +5019,9 @@ x_display_info_for_name (name)
 
   CHECK_STRING (name, 0);
 
+  if (! EQ (Vwindow_system, intern ("x")))
+    error ("Not using X Windows");
+
   for (dpyinfo = x_display_list, names = x_display_name_list;
        dpyinfo;
        dpyinfo = dpyinfo->next, names = XCONS (names)->cdr)
@@ -4546,13 +5032,16 @@ x_display_info_for_name (name)
        return dpyinfo;
     }
 
+  /* Use this general default value to start with.  */
+  Vx_resource_name = Vinvocation_name;
+
   validate_x_resource_name ();
 
   dpyinfo = x_term_init (name, (unsigned char *)0,
-                        XSTRING (Vx_resource_name)->data);
+                        (char *) XSTRING (Vx_resource_name)->data);
 
   if (dpyinfo == 0)
-    error ("X server %s not responding", XSTRING (name)->data);
+    error ("Cannot connect to X server %s", XSTRING (name)->data);
 
   x_in_use = 1;
   XSETFASTINT (Vwindow_system_version, 11);
@@ -4577,6 +5066,9 @@ terminate Emacs if we can't open the connection.")
   if (! NILP (xrm_string))
     CHECK_STRING (xrm_string, 1);
 
+  if (! EQ (Vwindow_system, intern ("x")))
+    error ("Not using X Windows");
+
   if (! NILP (xrm_string))
     xrm_option = (unsigned char *) XSTRING (xrm_string)->data;
   else
@@ -4587,16 +5079,18 @@ terminate Emacs if we can't open the connection.")
   /* This is what opens the connection and sets x_current_display.
      This also initializes many symbols, such as those used for input.  */
   dpyinfo = x_term_init (display, xrm_option,
-                        XSTRING (Vx_resource_name)->data);
+                        (char *) XSTRING (Vx_resource_name)->data);
 
   if (dpyinfo == 0)
     {
       if (!NILP (must_succeed))
-       fatal ("X server %s not responding.\n\
-Check the DISPLAY environment variable or use \"-d\"\n",
+       fatal ("Cannot connect to X server %s.\n\
+Check the DISPLAY environment variable or use `-d'.\n\
+Also use the `xhost' program to verify that it is set to permit\n\
+connections from your machine.\n",
               XSTRING (display)->data);
       else
-       error ("X server %s not responding", XSTRING (display)->data);
+       error ("Cannot connect to X server %s", XSTRING (display)->data);
     }
 
   x_in_use = 1;
@@ -4714,8 +5208,6 @@ syms_of_xfns ()
   staticpro (&Qcursor_color);
   Qcursor_type = intern ("cursor-type");
   staticpro (&Qcursor_type);
-  Qfont = intern ("font");
-  staticpro (&Qfont);
   Qforeground_color = intern ("foreground-color");
   staticpro (&Qforeground_color);
   Qgeometry = intern ("geometry");
@@ -4726,10 +5218,14 @@ syms_of_xfns ()
   staticpro (&Qicon_top);
   Qicon_type = intern ("icon-type");
   staticpro (&Qicon_type);
+  Qicon_name = intern ("icon-name");
+  staticpro (&Qicon_name);
   Qinternal_border_width = intern ("internal-border-width");
   staticpro (&Qinternal_border_width);
   Qleft = intern ("left");
   staticpro (&Qleft);
+  Qright = intern ("right");
+  staticpro (&Qright);
   Qmouse_color = intern ("mouse-color");
   staticpro (&Qmouse_color);
   Qnone = intern ("none");
@@ -4762,6 +5258,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,
@@ -4771,7 +5270,7 @@ syms_of_xfns ()
 
   DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,
     "List of directories to search for bitmap files for X.");
-  Vx_bitmap_file_path = Fcons (build_string (PATH_BITMAPS), Qnil);
+  Vx_bitmap_file_path = decode_env_path ((char *) 0, PATH_BITMAPS);
 
   DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
     "The shape of the pointer when over text.\n\
@@ -4780,16 +5279,30 @@ unless you set the mouse color.");
   Vx_pointer_shape = Qnil;
 
   DEFVAR_LISP ("x-resource-name", &Vx_resource_name,
-    "The name Emacs uses to look up X resources; for internal use only.\n\
+    "The name Emacs uses to look up X resources.\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.");
+switches, if present.\n\
+\n\
+It may be useful to bind this variable locally around a call\n\
+to `x-get-resource'.  See also the variable `x-resource-class'.");
   Vx_resource_name = Qnil;
 
+  DEFVAR_LISP ("x-resource-class", &Vx_resource_class,
+    "The class Emacs uses to look up X resources.\n\
+`x-get-resource' uses this as the first component of the instance class\n\
+when requesting resource values.\n\
+Emacs initially sets `x-resource-class' to \"Emacs\".\n\
+\n\
+Setting this variable permanently is not a reasonable thing to do,\n\
+but binding this variable locally around a call to `x-get-resource'\n\
+is a reasonabvle practice.  See also the variable `x-resource-name'.");
+  Vx_resource_class = build_string (EMACS_CLASS);
+
 #if 0 /* This doesn't really do anything.  */
-  DEFVAR_INT ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
+  DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
              "The shape of the pointer when not over text.\n\
 This variable takes effect when you create a new frame\n\
 or when you set the mouse color.");
@@ -4797,14 +5310,14 @@ or when you set the mouse color.");
   Vx_nontext_pointer_shape = Qnil;
 
 #if 0 /* This doesn't really do anything.  */
-  DEFVAR_INT ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
+  DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
              "The shape of the pointer when over the mode line.\n\
 This variable takes effect when you create a new frame\n\
 or when you set the mouse color.");
 #endif
   Vx_mode_pointer_shape = Qnil;
 
-  DEFVAR_INT ("x-sensitive-text-pointer-shape",
+  DEFVAR_LISP ("x-sensitive-text-pointer-shape",
              &Vx_sensitive_text_pointer_shape,
              "The shape of the pointer when over mouse-sensitive text.\n\
 This variable takes effect when you create a new frame\n\
@@ -4816,11 +5329,29 @@ or when you set the mouse color.");
   Vx_cursor_fore_pixel = Qnil;
 
   DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
-              "Non-nil if no X window manager is in use.");
+              "Non-nil if no X window manager is in use.\n\
+Emacs doesn't try to figure this out; this is always nil\n\
+unless you set it to something else.");
+  /* We don't have any way to find this out, so set it to nil
+     and maybe the user would like to set it to t.  */
+  Vx_no_window_manager = Qnil;
+
+  DEFVAR_LISP ("x-pixel-size-width-font-regexp",
+              &Vx_pixel_size_width_font_regexp,
+     "Regexp matching a font name whose width is the same as `PIXEL_SIZE'.\n\
+\n\
+Since Emacs gets width of a font matching with this regexp from\n\
+PIXEL_SIZE field of the name, font finding mechanism gets faster for\n\
+such a font.  This is especially effective for such large fonts as\n\
+Chinese, Japanese, and Korean.");
+  Vx_pixel_size_width_font_regexp = Qnil;
 
 #ifdef USE_X_TOOLKIT
   Fprovide (intern ("x-toolkit"));
 #endif
+#ifdef USE_MOTIF
+  Fprovide (intern ("motif"));
+#endif
 
   defsubr (&Sx_get_resource);
 #if 0
@@ -4856,8 +5387,6 @@ or when you set the mouse color.");
 #endif
   defsubr (&Sx_parse_geometry);
   defsubr (&Sx_create_frame);
-  defsubr (&Sfocus_frame);
-  defsubr (&Sunfocus_frame);
 #if 0
   defsubr (&Sx_horizontal_line);
 #endif
@@ -4865,6 +5394,14 @@ or when you set the mouse color.");
   defsubr (&Sx_close_connection);
   defsubr (&Sx_display_list);
   defsubr (&Sx_synchronize);
+
+  /* Setting callback functions for fontset handler.  */
+  get_font_info_func = x_get_font_info;
+  list_fonts_func = x_list_fonts;
+  load_font_func = x_load_font;
+  query_font_func = x_query_font;
+  set_frame_fontset_func = x_set_font;
+  check_window_system_func = check_x;
 }
 
 #endif /* HAVE_X_WINDOWS */