Do renamings:
[bpt/emacs.git] / src / xfns.c
index 9e508dc..9ed565a 100644 (file)
@@ -1,5 +1,5 @@
 /* Functions for the X window system.
-   Copyright (C) 1989, 1992, 1993, 1994 Free Software Foundation.
+   Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation.
 
 This file is part of GNU Emacs.
 
@@ -53,8 +53,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 */
@@ -164,6 +166,7 @@ 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 Qmouse_color;
@@ -260,32 +263,32 @@ check_x_display_info (frame)
 /* Return the Emacs frame-object corresponding to an X window.
    It could be the frame's main window or an icon window.  */
 
-/* This function can be called during GC, so use XGCTYPE.  */
+/* This function can be called during GC, so use GC_xxx type test macros.  */
 
 struct frame *
-x_window_to_frame (wdesc)
+x_window_to_frame (dpyinfo, wdesc)
+     struct x_display_info *dpyinfo;
      int wdesc;
 {
   Lisp_Object tail, frame;
   struct frame *f;
 
-  for (tail = Vframe_list; XGCTYPE (tail) == Lisp_Cons;
-       tail = XCONS (tail)->cdr)
+  for (tail = Vframe_list; GC_CONSP (tail); tail = XCONS (tail)->cdr)
     {
       frame = XCONS (tail)->car;
-      if (XGCTYPE (frame) != Lisp_Frame)
+      if (!GC_FRAMEP (frame))
         continue;
       f = XFRAME (frame);
+      if (f->output_data.nothing == 1 || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
+       continue;
 #ifdef USE_X_TOOLKIT
-      if (f->display.nothing == 1) 
-       return 0;
-      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 */
     }
@@ -297,23 +300,23 @@ x_window_to_frame (wdesc)
    windows.  */
 
 struct frame *
-x_any_window_to_frame (wdesc)
+x_any_window_to_frame (dpyinfo, wdesc)
+     struct x_display_info *dpyinfo;
      int wdesc;
 {
   Lisp_Object tail, frame;
   struct frame *f;
-  struct x_display *x;
+  struct x_output *x;
 
-  for (tail = Vframe_list; XGCTYPE (tail) == Lisp_Cons;
-       tail = XCONS (tail)->cdr)
+  for (tail = Vframe_list; GC_CONSP (tail); tail = XCONS (tail)->cdr)
     {
       frame = XCONS (tail)->car;
-      if (XGCTYPE (frame) != Lisp_Frame)
+      if (!GC_FRAMEP (frame))
         continue;
       f = XFRAME (frame);
-      if (f->display.nothing == 1) 
-       return 0;
-      x = f->display.x;
+      if (f->output_data.nothing == 1 || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
+       continue;
+      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) 
@@ -326,34 +329,94 @@ x_any_window_to_frame (wdesc)
   return 0;
 }
 
+/* Likewise, but exclude the menu bar widget.  */
+
+struct frame *
+x_non_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;
+      /* This frame matches if the window is any of its widgets.  */
+      if (wdesc == XtWindow (x->widget) 
+         || wdesc == XtWindow (x->column_widget) 
+         || wdesc == XtWindow (x->edit_widget))
+       return f;
+    }
+  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.  */
 
 struct frame *
-x_top_window_to_frame (wdesc)
+x_top_window_to_frame (dpyinfo, wdesc)
+     struct x_display_info *dpyinfo;
      int wdesc;
 {
   Lisp_Object tail, frame;
   struct frame *f;
-  struct x_display *x;
+  struct x_output *x;
 
-  for (tail = Vframe_list; XGCTYPE (tail) == Lisp_Cons;
-       tail = XCONS (tail)->cdr)
+  for (tail = Vframe_list; GC_CONSP (tail); tail = XCONS (tail)->cdr)
     {
       frame = XCONS (tail)->car;
-      if (XGCTYPE (frame) != Lisp_Frame)
+      if (!GC_FRAMEP (frame))
         continue;
       f = XFRAME (frame);
-      if (f->display.nothing == 1) 
-       return 0;
-      x = f->display.x;
+      if (f->output_data.nothing == 1 || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
+       continue;
+      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;
 }
@@ -537,12 +600,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;
        }
     }
 }
@@ -604,6 +669,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 ();
@@ -625,6 +691,7 @@ static struct x_frame_parm_table x_frame_parms[] =
   "border-color", x_set_border_color,
   "cursor-type", x_set_cursor_type,
   "icon-type", x_set_icon_type,
+  "icon-name", x_set_icon_name,
   "font", x_set_font,
   "border-width", x_set_border_width,
   "internal-border-width", x_set_internal_border_width,
@@ -669,11 +736,15 @@ x_set_frame_parameters (f, alist)
   /* Same here.  */
   Lisp_Object left, top;
 
+  /* Same with these.  */
+  Lisp_Object icon_left, icon_top;
+
   /* Record in these vectors all the parms specified.  */
   Lisp_Object *parms;
   Lisp_Object *values;
   int i;
   int left_no_change = 0, top_no_change = 0;
+  int icon_left_no_change = 0, icon_top_no_change = 0;
 
   i = 0;
   for (tail = alist; CONSP (tail); tail = Fcdr (tail))
@@ -696,6 +767,7 @@ x_set_frame_parameters (f, alist)
     }
 
   width = height = top = left = Qunbound;
+  icon_left = icon_top = Qunbound;
 
   /* Now process them in reverse of specified order.  */
   for (i--; i >= 0; i--)
@@ -713,6 +785,10 @@ x_set_frame_parameters (f, alist)
        top = val;
       else if (EQ (prop, Qleft))
        left = val;
+      else if (EQ (prop, Qicon_top))
+       icon_top = val;
+      else if (EQ (prop, Qicon_left))
+       icon_left = val;
       else
        {
          register Lisp_Object param_index, old_value;
@@ -720,9 +796,8 @@ x_set_frame_parameters (f, alist)
          param_index = Fget (prop, Qx_frame_parameter);
          old_value = get_frame_param (f, prop);
          store_frame_param (f, prop, val);
-         if (INTEGERP (param_index)
-             && XINT (param_index) >= 0
-             && (XINT (param_index)
+         if (NATNUMP (param_index)
+             && (XFASTINT (param_index)
                  < sizeof (x_frame_parms)/sizeof (x_frame_parms[0])))
            (*x_frame_parms[XINT (param_index)].setter)(f, val, old_value);
        }
@@ -732,18 +807,34 @@ 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.  */
+  if (EQ (icon_left, Qunbound) || ! INTEGERP (icon_left))
+    {
+      icon_left_no_change = 1;
+      icon_left = Fcdr (Fassq (Qicon_left, f->param_alist));
+      if (NILP (icon_left))
+       XSETINT (icon_left, 0);
+    }
+  if (EQ (icon_top, Qunbound) || ! INTEGERP (icon_top))
+    {
+      icon_top_no_change = 1;
+      icon_top = Fcdr (Fassq (Qicon_top, f->param_alist));
+      if (NILP (icon_top))
+       XSETINT (icon_top, 0);
     }
 
   /* Don't die if just one of these was set.  */
@@ -752,7 +843,7 @@ x_set_frame_parameters (f, alist)
   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.
@@ -773,28 +864,28 @@ x_set_frame_parameters (f, alist)
 
     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)
@@ -804,19 +895,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)
@@ -827,14 +918,18 @@ 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))
+       && ! (icon_left_no_change && icon_top_no_change))
+      x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top));
   }
 }
 
@@ -854,19 +949,20 @@ 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)
     {
+      x_catch_errors (FRAME_X_DISPLAY (f));
+
       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);
 
@@ -874,17 +970,17 @@ x_real_positions (f, xptr, yptr)
 
       /* Find the position of the outside upper-left corner of
         the inner window, with respect to the outer window.  */
-      if (f->display.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
+      if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
        {
          XTranslateCoordinates (FRAME_X_DISPLAY (f),
 
                                 /* From-window, to-window.  */
 #ifdef USE_X_TOOLKIT
-                                XtWindow (f->display.x->widget),
+                                XtWindow (f->output_data.x->widget),
 #else
-                                f->display.x->window_desc,
+                                f->output_data.x->window_desc,
 #endif
-                                f->display.x->parent_desc,
+                                f->output_data.x->parent_desc,
 
                                 /* From-position, to-position.  */
                                 0, 0, &win_x, &win_y,
@@ -892,8 +988,10 @@ x_real_positions (f, xptr, yptr)
                                 /* Child of win.  */
                                 &child);
 
-         win_x += f->display.x->border_width;
-         win_y += f->display.x->border_width;
+#if 0  /* The values seem to be right without this and wrong with.  */
+         win_x += f->output_data.x->border_width;
+         win_y += f->output_data.x->border_width;
+#endif
        }
 
       /* It is possible for the window returned by the XQueryNotify
@@ -903,12 +1001,14 @@ x_real_positions (f, xptr, yptr)
         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));
     }
 
   x_uncatch_errors (FRAME_X_DISPLAY (f));
 
-  *xptr = f->display.x->left_pos - win_x;
-  *yptr = f->display.x->top_pos - win_y;
+  *xptr = f->output_data.x->left_pos - win_x;
+  *yptr = f->output_data.x->top_pos - win_y;
 }
 
 /* Insert a description of internally-recorded parameters of frame X
@@ -922,22 +1022,39 @@ 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);
 }
 \f
+
 /* Decide if color named COLOR is valid for the display associated with
    the selected frame; if so, return the rgb values in COLOR_DEF.
    If ALLOC is nonzero, allocate a new colormap cell.  */
@@ -949,20 +1066,72 @@ defined_color (f, color, color_def, alloc)
      XColor *color_def;
      int alloc;
 {
-  register int foo;
+  register int status;
   Colormap screen_colormap;
+  Display *display = FRAME_X_DISPLAY (f);
 
   BLOCK_INPUT;
-  screen_colormap
-    = DefaultColormap (FRAME_X_DISPLAY (f),
-                      XDefaultScreen (FRAME_X_DISPLAY (f)));
+  screen_colormap = DefaultColormap (display, XDefaultScreen (display));
 
-  foo = XParseColor (FRAME_X_DISPLAY (f), screen_colormap, color, color_def);
-  if (foo && alloc)
-    foo = XAllocColor (FRAME_X_DISPLAY (f), screen_colormap, color_def);
+  status = XParseColor (display, screen_colormap, color, color_def);
+  if (status && alloc) 
+    {
+      status = XAllocColor (display, screen_colormap, color_def);
+      if (!status)
+       {
+         /* If we got to this point, the colormap is full, so we're 
+            going to try and get the next closest color.
+            The algorithm used is a least-squares matching, which is
+            what X uses for closest color matching with StaticColor visuals.  */
+
+         XColor *cells;
+         int no_cells;
+         int nearest;
+         long nearest_delta, trial_delta;
+         int x;
+
+         no_cells = XDisplayCells (display, XDefaultScreen (display));
+         cells = (XColor *) alloca (sizeof (XColor) * no_cells);
+
+         for (x = 0; x < no_cells; x++) 
+           cells[x].pixel = x;
+
+         XQueryColors (display, screen_colormap, cells, no_cells);
+         nearest = 0;
+         /* I'm assuming CSE so I'm not going to condense this. */
+         nearest_delta = ((((color_def->red >> 8) - (cells[0].red >> 8))
+                           * ((color_def->red >> 8) - (cells[0].red >> 8)))
+                          +
+                          (((color_def->green >> 8) - (cells[0].green >> 8))
+                           * ((color_def->green >> 8) - (cells[0].green >> 8)))
+                          +
+                          (((color_def->blue >> 8) - (cells[0].blue >> 8))
+                           * ((color_def->blue >> 8) - (cells[0].blue >> 8))));
+         for (x = 1; x < no_cells; x++) 
+           {
+             trial_delta = ((((color_def->red >> 8) - (cells[x].red >> 8))
+                             * ((color_def->red >> 8) - (cells[x].red >> 8)))
+                            +
+                            (((color_def->green >> 8) - (cells[x].green >> 8))
+                             * ((color_def->green >> 8) - (cells[x].green >> 8)))
+                            +
+                            (((color_def->blue >> 8) - (cells[x].blue >> 8))
+                             * ((color_def->blue >> 8) - (cells[x].blue >> 8))));
+             if (trial_delta < nearest_delta) 
+               {
+                 nearest = x;
+                 nearest_delta = trial_delta;
+               }
+           }
+         color_def->red = cells[nearest].red;
+         color_def->green = cells[nearest].green;
+         color_def->blue = cells[nearest].blue;
+         status = XAllocColor (display, screen_colormap, color_def);
+       }
+    }
   UNBLOCK_INPUT;
 
-  if (foo)
+  if (status)
     return 1;
   else
     return 0;
@@ -991,10 +1160,13 @@ x_decode_color (f, arg, def)
   if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
     return def;
 
+  /* defined_color is responsible for coping with failures
+     by looking for a near-miss.  */
   if (defined_color (f, XSTRING (arg)->data, &cdef, 1))
     return cdef.pixel;
-  else
-    Fsignal (Qundefined_color, Fcons (arg, Qnil));
+
+  /* defined_color failed; return an ultimate default.  */
+  return def;
 }
 \f
 /* Functions called only from `x_set_frame_param'
@@ -1010,15 +1182,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))
@@ -1034,28 +1206,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;
 
@@ -1075,13 +1247,13 @@ x_set_mouse_color (f, arg, oldval)
   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;
 
@@ -1134,7 +1306,7 @@ x_set_mouse_color (f, arg, oldval)
   {
     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),
@@ -1159,23 +1331,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;
@@ -1192,24 +1364,24 @@ 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;
 
@@ -1256,16 +1428,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))
@@ -1279,19 +1451,21 @@ x_set_cursor_type (f, arg, oldval)
      Lisp_Object arg, oldval;
 {
   if (EQ (arg, Qbar))
-    FRAME_DESIRED_CURSOR (f) = bar_cursor;
-  else
-#if 0
-    if (EQ (arg, Qbox))
-#endif
-      FRAME_DESIRED_CURSOR (f) = filled_box_cursor;
-  /* Error messages commented out because people have trouble fixing
-     .Xdefaults with Emacs, when it has something bad in it.  */
-#if 0
+    {
+      FRAME_DESIRED_CURSOR (f) = bar_cursor;
+      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->output_data.x->cursor_width = XINT (XCONS (arg)->cdr);
+    }
   else
-    error
-      ("the `cursor-type' frame parameter should be either `bar' or `box'");
-#endif
+    /* Treat anything unknown as "box cursor".
+       It was bad to signal an error; people have trouble fixing
+       .Xdefaults with Emacs, when it has something bad in it.  */
+    FRAME_DESIRED_CURSOR (f) = filled_box_cursor;
 
   /* Make sure the cursor gets redrawn.  This is overkill, but how
      often do people change cursor types?  */
@@ -1316,7 +1490,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);
 
@@ -1326,16 +1503,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;
 }
@@ -1355,6 +1522,44 @@ 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
+                                          : f->name))->data);
+
+  if (result)
+    {
+      UNBLOCK_INPUT;
+      error ("No icon window available");
+    }
+
+  XFlush (FRAME_X_DISPLAY (f));
+  UNBLOCK_INPUT;
+}
+
 extern Lisp_Object x_new_font ();
 
 void
@@ -1390,13 +1595,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
@@ -1405,14 +1610,14 @@ 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;
 
-  if (f->display.x->internal_border_width == old)
+  if (f->output_data.x->internal_border_width == old)
     return;
 
   if (FRAME_X_WINDOW (f) != 0)
@@ -1495,7 +1700,7 @@ x_set_menu_bar_lines (f, value, oldval)
       if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
        free_frame_menubar (f);
       FRAME_EXTERNAL_MENU_BAR (f) = 0;
-      f->display.x->menubar_widget = 0;
+      f->output_data.x->menubar_widget = 0;
     }
 #else /* not USE_X_TOOLKIT */
   FRAME_MENU_BAR_LINES (f) = nlines;
@@ -1556,19 +1761,28 @@ x_set_name (f, name, explicit)
       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;
+
+       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;
 #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 */
@@ -1660,7 +1874,7 @@ x_set_scroll_bar_width (f, arg, oldval)
   else if (INTEGERP (arg) && XINT (arg) > 0
           && XFASTINT (arg) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f))
     {
-      int wid = FONT_WIDTH (f->display.x->font);
+      int wid = FONT_WIDTH (f->output_data.x->font);
       FRAME_SCROLL_BAR_PIXEL_WIDTH (f) = XFASTINT (arg);
       FRAME_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + wid-1) / wid;
       if (FRAME_X_WINDOW (f))
@@ -1670,18 +1884,29 @@ x_set_scroll_bar_width (f, arg, oldval)
 \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 ()
 {
+  int len;
+  /* Number of valid characters in the resource name.  */
+  int good_count = 0;
+  /* Number of invalid characters in the resource name.  */
+  int bad_count = 0;
+  Lisp_Object new;
+  int i;
+
   if (STRINGP (Vx_resource_name))
     {
-      int len = XSTRING (Vx_resource_name)->size;
       unsigned char *p = XSTRING (Vx_resource_name)->data;
       int i;
 
-      /* Allow only letters, digits, - and _,
-        because those are all that X allows.  */
+      len = XSTRING (Vx_resource_name)->size;
+
+      /* Only letters, digits, - and _ are valid in resource names.
+        Count the valid characters and count the invalid ones.  */
       for (i = 0; i < len; i++)
        {
          int c = p[i];
@@ -1689,12 +1914,41 @@ validate_x_resource_name ()
                 || (c >= 'A' && c <= 'Z')
                 || (c >= '0' && c <= '9')
                 || c == '-' || c == '_'))
-           goto fail;
+           bad_count++;
+         else
+           good_count++;
        }
     }
   else
-  fail:
-    Vx_resource_name = make_string ("emacs", 5);
+    /* Not a string => completely invalid.  */
+    bad_count = 5, good_count = 0;
+
+  /* If name is valid already, return.  */
+  if (bad_count == 0)
+    return;
+
+  /* If name is entirely invalid, or nearly so, use `emacs'.  */
+  if (good_count == 0
+      || (good_count == 1 && bad_count > 0))
+    {
+      Vx_resource_name = build_string ("emacs");
+      return;
+    }
+
+  /* Name is partly valid.  Copy it and replace the invalid characters
+     with underscores.  */
+
+  Vx_resource_name = new = Fcopy_sequence (Vx_resource_name);
+
+  for (i = 0; i < len; i++)
+    {
+      int c = XSTRING (new)->data[i];
+      if (! ((c >= 'a' && c <= 'z')
+            || (c >= 'A' && c <= 'Z')
+            || (c >= '0' && c <= '9')
+            || c == '-' || c == '_'))
+       XSTRING (new)->data[i] = '_';
+    }
 }
 
 
@@ -1716,7 +1970,6 @@ and the class is `Emacs.CLASS.SUBCLASS'.")
   register char *value;
   char *name_key;
   char *class_key;
-  Lisp_Object resname;
 
   check_x ();
 
@@ -1731,48 +1984,41 @@ 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'.  */
-      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);
-    }
-  else
+  /* 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
+                             + (STRINGP (component)
+                                ? XSTRING (component)->size : 0)
+                             + XSTRING (attribute)->size
+                             + 3);
+
+  class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
+                              + XSTRING (class)->size
+                              + (STRINGP (subclass)
+                                 ? XSTRING (subclass)->size : 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, EMACS_CLASS);
+
+  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);
     }
 
+  strcat (name_key, ".");
+  strcat (name_key, XSTRING (attribute)->data);
+
   value = x_get_string_resource (check_x_display_info (Qnil)->xrdb,
                                 name_key, class_key);
 
@@ -1823,7 +2069,7 @@ enum resource_types
 
    If no default is specified, return Qunbound.  If you call
    x_get_arg, make sure you deal with Qunbound in a reasonable way,
-   and don't let it get stored in any lisp-visible variables!  */
+   and don't let it get stored in any Lisp-visible variables!  */
 
 static Lisp_Object
 x_get_arg (alist, param, attribute, class, type)
@@ -2000,8 +2246,8 @@ x_figure_window_size (f, parms)
   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);
@@ -2024,14 +2270,14 @@ 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);
@@ -2040,61 +2286,61 @@ x_figure_window_size (f, parms)
     {
       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;
        }
 
-      if (!NILP (tem2))
+      if (!NILP (tem2) && ! EQ (tem2, Qunbound))
        window_prompting |= USPosition;
       else
        window_prompting |= PPosition;
@@ -2146,11 +2392,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)
        {
@@ -2199,25 +2446,33 @@ x_window (f, window_prompting, minibuffer_only)
   Widget shell_widget;
   Widget pane_widget;
   Widget frame_widget;
-  char* name;
   Arg al [25];
   int ac;
 
   BLOCK_INPUT;
 
-  if (STRINGP (f->name))
-    name = (char*) XSTRING (f->name)->data;
-  else
-    name = "emacs";
+  /* 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 = (char *) XSTRING (Vx_resource_name)->data;
+    f->namebuf = (char *) xmalloc (strlen (str) + 1);
+    strcpy (f->namebuf, str);
+  }
 
   ac = 0;
   XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
   XtSetArg (al[ac], XtNinput, 1); ac++;
-  shell_widget = XtAppCreateShell (name, EMACS_CLASS,
-                                  topLevelShellWidgetClass,
+  XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
+  XtSetArg (al[ac], XtNborderWidth, f->output_data.x->border_width); ac++;
+  shell_widget = XtAppCreateShell (f->namebuf, EMACS_CLASS,
+                                  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++,
@@ -2227,10 +2482,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.  */
@@ -2241,15 +2493,12 @@ x_window (f, window_prompting, minibuffer_only)
   XtSetArg (al[ac], XtNallowResize, 1); ac++;
   XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
   XtSetArg (al[ac], XtNemacsFrame, f); ac++;
-  frame_widget = XtCreateWidget (name,
+  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.  */
@@ -2258,37 +2507,57 @@ 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 (FRAME_EXTERNAL_MENU_BAR (f))
       {
-        Dimension ibw;
+        Dimension ibw = 0;
         XtVaGetValues (pane_widget, XtNinternalBorderWidth, &ibw, NULL);
         menubar_size += ibw;
       }
 
-    if (window_prompting & USPosition)
-      {
-       int left = f->display.x->left_pos;
-       int xneg = window_prompting & XNegative;
-       int top = f->display.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,
+    f->output_data.x->menubar_height = menubar_size;
+
+    /* 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.  */
+    if (!strcmp (lwlib_toolkit_type, "motif"))
+      XtVaGetValues (f->output_data.x->edit_widget, XtNinternalBorderWidth,
+                    &extra_borders, NULL);
+
+    /* Convert our geometry parameters into a geometry string
+       and specify it.
+       Note that we do not specify here whether the position
+       is a user-specified or program-specified one.
+       We pass that information later, in x_wm_set_size_hints.  */
+    {
+      int left = f->output_data.x->left_pos;
+      int xneg = window_prompting & XNegative;
+      int top = f->output_data.x->top_pos;
+      int yneg = window_prompting & YNegative;
+      if (xneg)
+       left = -left;
+      if (yneg)
+       top = -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), 
-              PIXEL_HEIGHT (f) + menubar_size);
+      else
+       sprintf (shell_position, "=%dx%d",
+                PIXEL_WIDTH (f) + extra_borders, 
+                PIXEL_HEIGHT (f) + menubar_size + extra_borders);
+    }
+
     len = strlen (shell_position) + 1;
     tem = (char *) xmalloc (len);
     strncpy (tem, shell_position, len);
@@ -2296,22 +2565,21 @@ x_window (f, window_prompting, minibuffer_only)
     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;
   XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
 
-  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);
 
   hack_wm_protocols (f, shell_widget);
 
@@ -2351,10 +2619,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");
 }
@@ -2371,8 +2643,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;
@@ -2386,30 +2658,35 @@ x_window (f)
   BLOCK_INPUT;
   FRAME_X_WINDOW (f)
     = XCreateWindow (FRAME_X_DISPLAY (f),
-                    FRAME_X_DISPLAY_INFO (f)->root_window,
-                    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);
 
   validate_x_resource_name ();
+
   class_hints.res_name = (char *) XSTRING (Vx_resource_name)->data;
   class_hints.res_class = EMACS_CLASS;
   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);
 
   /* Request "save yourself" and "delete window" commands from wm.  */
   {
@@ -2434,7 +2711,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;
 
@@ -2478,6 +2755,10 @@ x_icon (f, parms)
         ? IconicState
         : NormalState));
 
+  x_text_icon (f, (char *) XSTRING ((!NILP (f->icon_name)
+                                    ? f->icon_name
+                                    : f->name))->data);
+
   UNBLOCK_INPUT;
 }
 
@@ -2507,34 +2788,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),
@@ -2543,12 +2824,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)))));
 
@@ -2579,13 +2860,24 @@ This function is an internal primitive--use `make-frame' instead.")
   struct gcpro gcpro1;
   Lisp_Object display;
   struct x_display_info *dpyinfo;
+  Lisp_Object parent;
+  struct kboard *kb;
 
   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 (parms, Qdisplay, 0, 0, string);
   if (EQ (display, Qunbound))
     display = Qnil;
   dpyinfo = check_x_display_info (display);
+#ifdef MULTI_KBOARD
+  kb = dpyinfo->kboard;
+#else
+  kb = &the_only_kboard;
+#endif
 
   name = x_get_arg (parms, Qname, "title", "Title", string);
   if (!STRINGP (name)
@@ -2593,16 +2885,26 @@ This function is an internal primitive--use `make-frame' instead.")
       && ! 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);
+  if (EQ (parent, Qunbound))
+    parent = Qnil;
+  if (! NILP (parent))
+    CHECK_NUMBER (parent, 0);
+
   tem = x_get_arg (parms, Qminibuffer, 0, 0, symbol);
   if (EQ (tem, Qnone) || NILP (tem))
-    f = make_frame_without_minibuffer (Qnil);
+    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);
+    f = make_frame_without_minibuffer (tem, kb, display);
   else
     f = make_frame (1);
 
@@ -2613,11 +2915,32 @@ This function is an internal primitive--use `make-frame' instead.")
   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->icon_name
+    = x_get_arg (parms, Qicon_name, "iconName", "Title", string);
+  if (! STRINGP (f->icon_name))
+    f->icon_name = Qnil;
 
   FRAME_X_DISPLAY_INFO (f) = dpyinfo;
+#ifdef MULTI_KBOARD
+  FRAME_KBOARD (f) = kb;
+#endif
+
+  /* Specify the parent under which to make this X window.  */
+
+  if (!NILP (parent))
+    {
+      f->output_data.x->parent_desc = parent;
+      f->output_data.x->explicit_parent = 1;
+    }
+  else
+    {
+      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.  */
   f->phys_cursor_x = -1;
@@ -2667,9 +2990,11 @@ This function is an internal primitive--use `make-frame' instead.")
                         "font", "Font", string);
   }
 
+#ifdef USE_X_TOOLKIT
   /* 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),
                       "borderwidth", "BorderWidth", number);
@@ -2708,25 +3033,25 @@ This function is an internal primitive--use `make-frame' instead.")
   x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
                       "scrollBarWidth", "ScrollBarWidth", number);
 
-  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);
@@ -2757,12 +3082,11 @@ This function is an internal primitive--use `make-frame' instead.")
   f->height = f->width = 0;
   change_frame_size (f, height, width, 1, 0);
 
-/* With the toolkit, the geometry management is done in x_window.  */
-#ifndef USE_X_TOOLKIT
+  /* Tell the server what size and position, etc, we want,
+     and how badly we want them.  */
   BLOCK_INPUT;
   x_wm_set_size_hint (f, window_prompting, 0);
   UNBLOCK_INPUT;
-#endif /* USE_X_TOOLKIT */
 
   tem = x_get_arg (parms, Qunsplittable, 0, 0, boolean);
   f->no_split = minibuffer_only || EQ (tem, Qt);
@@ -2780,34 +3104,41 @@ This function is an internal primitive--use `make-frame' instead.")
   FRAME_X_DISPLAY_INFO (f)->reference_count++;
 
   /* Make the window appear on the frame and enable display,
-     unless the caller says not to.  */
-  {
-    Lisp_Object visibility;
-
-    visibility = x_get_arg (parms, Qvisibility, 0, 0, symbol);
-    if (EQ (visibility, Qunbound))
-      visibility = Qt;
-
-    if (EQ (visibility, Qicon))
-      x_iconify_frame (f);
-    else if (! NILP (visibility))
-      x_make_frame_visible (f);
-    else
-      /* Must have been Qnil.  */
-      ;
-  }
+     unless the caller says not to.  However, with explicit parent,
+     Emacs cannot control visibility, so don't try.  */
+  if (! f->output_data.x->explicit_parent)
+    {
+      Lisp_Object visibility;
+
+      visibility = x_get_arg (parms, Qvisibility, 0, 0, symbol);
+      if (EQ (visibility, Qunbound))
+       visibility = Qt;
+
+      if (EQ (visibility, Qicon))
+       x_iconify_frame (f);
+      else if (! NILP (visibility))
+       x_make_frame_visible (f);
+      else
+       /* Must have been Qnil.  */
+       ;
+    }
 
   return unbind_to (count, frame);
 }
 
+/* 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 ()
+x_get_focus_frame (frame)
+     struct frame *frame;
 {
+  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (frame);
   Lisp_Object xfocus;
-  if (! x_focus_frame)
+  if (! dpyinfo->x_focus_frame)
     return Qnil;
 
-  XSETFRAME (xfocus, x_focus_frame);
+  XSETFRAME (xfocus, dpyinfo->x_focus_frame);
   return xfocus;
 }
 
@@ -2833,11 +3164,16 @@ DEFUN ("unfocus-frame", Funfocus_frame, Sunfocus_frame, 0, 0, 0,
   "If a frame has been focused, release it.")
   ()
 {
-  if (x_focus_frame)
+  if (FRAME_X_P (selected_frame))
     {
-      BLOCK_INPUT;
-      x_unfocus_frame (x_focus_frame);
-      UNBLOCK_INPUT;
+      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;
@@ -2864,7 +3200,9 @@ even if they match PATTERN and FACE.")
 {
   int num_fonts;
   char **names;
+#ifndef BROKEN_XLISTFONTSWITHINFO
   XFontStruct *info;
+#endif
   XFontStruct *size_ref;
   Lisp_Object list;
   FRAME_PTR f;
@@ -2892,12 +3230,12 @@ even if they match PATTERN and 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;
        }
     }
 
@@ -2930,7 +3268,8 @@ even if they match PATTERN and FACE.")
           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;
@@ -2941,18 +3280,20 @@ even if they match PATTERN and FACE.")
   BLOCK_INPUT;
 
   /* Solaris 2.3 has a bug in XListFontsWithInfo.  */
-#ifdef BROKEN_XLISTFONTSWITHINFO
-  names = XListFonts (FRAME_X_DISPLAY (f),
-                      XSTRING (pattern)->data,
-                      2000, /* maxnames */
-                      &num_fonts); /* count_return */
-#else
-  names = XListFontsWithInfo (FRAME_X_DISPLAY (f),
-                             XSTRING (pattern)->data,
-                             2000, /* maxnames */
-                             &num_fonts, /* count_return */
-                             &info); /* info_return */
+#ifndef BROKEN_XLISTFONTSWITHINFO
+  if (size_ref)
+    names = XListFontsWithInfo (FRAME_X_DISPLAY (f),
+                               XSTRING (pattern)->data,
+                               2000, /* maxnames */
+                               &num_fonts, /* count_return */
+                               &info); /* info_return */
+  else
 #endif
+    names = XListFonts (FRAME_X_DISPLAY (f),
+                       XSTRING (pattern)->data,
+                       2000, /* maxnames */
+                       &num_fonts); /* count_return */
+
   UNBLOCK_INPUT;
 
   list = Qnil;
@@ -2975,27 +3316,36 @@ even if they match PATTERN and FACE.")
       list = Qnil;
       for (i = 0; i < num_fonts; i++)
         {
-         XFontStruct *thisinfo;
+         int keeper;
 
+         if (!size_ref)
+           keeper = 1;
+         else
+           {
 #ifdef BROKEN_XLISTFONTSWITHINFO
-          BLOCK_INPUT;
-          thisinfo = XLoadQueryFont (FRAME_X_DISPLAY (f), names[i]);
-          UNBLOCK_INPUT;
+             XFontStruct *thisinfo;
+
+             BLOCK_INPUT;
+             thisinfo = XLoadQueryFont (FRAME_X_DISPLAY (f), names[i]);
+             UNBLOCK_INPUT;
+
+             keeper = thisinfo && same_size_fonts (thisinfo, size_ref);
 #else
-         thisinfo = &info[i];
+             keeper = same_size_fonts (&info[i], size_ref);
 #endif
-          if (thisinfo && (! size_ref
-                          || same_size_fonts (thisinfo, size_ref)))
+           }
+          if (keeper)
            list = Fcons (build_string (names[i]), list);
         }
       list = Fnreverse (list);
 
       BLOCK_INPUT;
-#ifdef BROKEN_XLISTFONTSWITHINFO
-      XFreeFontNames (names);
-#else
-      XFreeFontInfo (names, info, num_fonts);
+#ifndef BROKEN_XLISTFONTSWITHINFO
+      if (size_ref)
+       XFreeFontInfo (names, info, num_fonts);
+      else
 #endif
+       XFreeFontNames (names);
       UNBLOCK_INPUT;
     }
 
@@ -3004,7 +3354,7 @@ even if they match PATTERN and FACE.")
 
 \f
 DEFUN ("x-color-defined-p", Fx_color_defined_p, Sx_color_defined_p, 1, 2, 0,
-       "Return non-nil color COLOR is supported on frame FRAME.\n\
+       "Return non-nil if color COLOR is supported on frame FRAME.\n\
 If FRAME is omitted or nil, use the selected frame.")
   (color, frame)
      Lisp_Object color, frame;
@@ -3023,7 +3373,8 @@ If FRAME is omitted or nil, use the selected frame.")
 DEFUN ("x-color-values", Fx_color_values, Sx_color_values, 1, 2, 0,
   "Return a description of the color named COLOR on frame FRAME.\n\
 The value is a list of integer RGB values--(RED GREEN BLUE).\n\
-These values appear to range from 0 to 65280; white is (65280 65280 65280).\n\
+These values appear to range from 0 to 65280 or 65535, depending\n\
+on the system; white is (65280 65280 65280) or (65535 65535 65535).\n\
 If FRAME is omitted or nil, use the selected frame.")
   (color, frame)
      Lisp_Object color, frame;
@@ -3075,6 +3426,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.")
@@ -3083,12 +3435,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,
@@ -3325,14 +3687,14 @@ 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
@@ -3356,19 +3718,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);
@@ -3416,7 +3778,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;
 
@@ -3465,7 +3827,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;
 
@@ -3484,9 +3846,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
@@ -3579,18 +3941,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);
     }
 
@@ -3616,18 +3978,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;
@@ -3728,13 +4090,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);
    }
 
@@ -3750,9 +4112,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.  */
@@ -3773,9 +4135,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.  */
@@ -3815,27 +4177,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
+  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
     + (w->left
-       * FONT_WIDTH (f->display.x->font));
+       * 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;
@@ -3846,13 +4208,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)
@@ -3862,8 +4225,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);
        }
@@ -3881,12 +4244,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;
            }
        }
@@ -3916,12 +4279,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);
@@ -3930,9 +4293,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);
@@ -3990,7 +4353,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);
 
@@ -4070,19 +4433,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));
@@ -4101,7 +4464,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;
@@ -4114,7 +4477,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;
 
@@ -4139,7 +4502,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
@@ -4320,6 +4683,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)
@@ -4330,13 +4696,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);
@@ -4361,26 +4730,34 @@ 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
     xrm_option = (unsigned char *) 0;
 
+  /* Use this general default value to start with.  */
+  Vx_resource_name = Vinvocation_name;
+
   validate_x_resource_name ();
 
   /* 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;
@@ -4447,7 +4824,7 @@ DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
 If ON is nil, allow buffering of requests.\n\
 Turning on synchronization prohibits the Xlib routines from buffering\n\
 requests and seriously degrades performance, but makes debugging much\n\
-easier.
+easier.\n\
 The optional second argument DISPLAY specifies which display to act on.\n\
 DISPLAY should be either a frame or a display name (a string).\n\
 If DISPLAY is omitted or nil, that stands for the selected frame's display.")
@@ -4510,6 +4887,8 @@ 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");
@@ -4555,7 +4934,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\
@@ -4600,11 +4979,19 @@ 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;
 
 #ifdef USE_X_TOOLKIT
   Fprovide (intern ("x-toolkit"));
 #endif
+#ifdef USE_MOTIF
+  Fprovide (intern ("motif"));
+#endif
 
   defsubr (&Sx_get_resource);
 #if 0