]> code.delx.au - gnu-emacs/blobdiff - src/xfns.c
Change doc-string comments to `new style' [w/`doc:' keyword].
[gnu-emacs] / src / xfns.c
index 8ed08ee75ffd90a6586159ed7b6fc4fac15b74dc..22c5bd9125442c5123cc216abdd1ab6af0dd3963 100644 (file)
@@ -107,10 +107,15 @@ extern XFontStruct *xlwmenu_default_font;
 extern void free_frame_menubar ();
 extern double atof ();
 
-#endif /* USE_X_TOOLKIT */
+#ifdef USE_MOTIF
+
+/* LessTif/Motif version info.  */
+
+static Lisp_Object Vmotif_version_string;
 
-#define min(a,b) ((a) < (b) ? (a) : (b))
-#define max(a,b) ((a) > (b) ? (a) : (b))
+#endif /* USE_MOTIF */
+
+#endif /* USE_X_TOOLKIT */
 
 #ifdef HAVE_X11R4
 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
@@ -209,6 +214,7 @@ extern Lisp_Object Qdisplay;
 Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background;
 Lisp_Object Qscreen_gamma, Qline_spacing, Qcenter;
 Lisp_Object Qcompound_text, Qcancel_timer;
+Lisp_Object Qwait_for_wm;
 
 /* The below are defined in frame.c.  */
 
@@ -635,7 +641,7 @@ x_create_bitmap_from_file (f, file)
     }
 
   /* Search bitmap-file-path for the file, if appropriate.  */
-  fd = openp (Vx_bitmap_file_path, file, "", &found, 0);
+  fd = openp (Vx_bitmap_file_path, file, Qnil, &found, 0);
   if (fd < 0)
     return -1;
   emacs_close (fd);
@@ -720,9 +726,9 @@ static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
 static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object));
 static void x_change_window_heights P_ ((Lisp_Object, int));
 static void x_disable_image P_ ((struct frame *, struct image *));
-static void x_create_im P_ ((struct frame *));
 void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
 static void x_set_line_spacing P_ ((struct frame *, Lisp_Object, Lisp_Object));
+static void x_set_wait_for_wm P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
@@ -791,7 +797,8 @@ static struct x_frame_parm_table x_frame_parms[] =
   "scroll-bar-foreground",     x_set_scroll_bar_foreground,
   "scroll-bar-background",     x_set_scroll_bar_background,
   "screen-gamma",              x_set_screen_gamma,
-  "line-spacing",              x_set_line_spacing
+  "line-spacing",              x_set_line_spacing,
+  "wait-for-wm",               x_set_wait_for_wm
 };
 
 /* Attach the `x-frame-parameter' properties to
@@ -1304,8 +1311,22 @@ x_set_line_spacing (f, new_value, old_value)
 }
 
 
+/* Change the `wait-for-wm' frame parameter of frame F.  OLD_VALUE is
+   the previous value of that parameter, NEW_VALUE is the new value.
+   See also the comment of wait_for_wm in struct x_output.  */
+
+static void
+x_set_wait_for_wm (f, new_value, old_value)
+     struct frame *f;
+     Lisp_Object new_value, old_value;
+{
+  f->output_data.x->wait_for_wm = !NILP (new_value);
+}
+
+
 /* Change the `screen-gamma' frame parameter of frame F.  OLD_VALUE is
-   the previous value of that parameter, NEW_VALUE is the new value.  */
+   the previous value of that parameter, NEW_VALUE is the new
+   value.  */
 
 static void
 x_set_screen_gamma (f, new_value, old_value)
@@ -1338,25 +1359,37 @@ x_set_foreground_color (f, arg, oldval)
      struct frame *f;
      Lisp_Object arg, oldval;
 {
-  unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
+  struct x_output *x = f->output_data.x;
+  unsigned long fg, old_fg;
 
-  unload_color (f, f->output_data.x->foreground_pixel);
-  f->output_data.x->foreground_pixel = pixel;
+  fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
+  old_fg = x->foreground_pixel;
+  x->foreground_pixel = fg;
 
   if (FRAME_X_WINDOW (f) != 0)
     {
+      Display *dpy = FRAME_X_DISPLAY (f);
+      
       BLOCK_INPUT;
-      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);
-      XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc,
-                     f->output_data.x->foreground_pixel);
+      XSetForeground (dpy, x->normal_gc, fg);
+      XSetBackground (dpy, x->reverse_gc, fg);
+
+      if (x->cursor_pixel == old_fg)
+       {
+         unload_color (f, x->cursor_pixel);
+         x->cursor_pixel = x_copy_color (f, fg);
+         XSetBackground (dpy, x->cursor_gc, x->cursor_pixel);
+       }
+      
       UNBLOCK_INPUT;
+      
       update_face_from_frame_parameter (f, Qforeground_color, arg);
+      
       if (FRAME_VISIBLE_P (f))
         redraw_frame (f);
     }
+      
+  unload_color (f, old_fg);
 }
 
 void
@@ -1364,33 +1397,38 @@ x_set_background_color (f, arg, oldval)
      struct frame *f;
      Lisp_Object arg, oldval;
 {
-  unsigned long pixel = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
+  struct x_output *x = f->output_data.x;
+  unsigned long bg;
 
-  unload_color (f, f->output_data.x->background_pixel);
-  f->output_data.x->background_pixel = pixel;
+  bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
+  unload_color (f, x->background_pixel);
+  x->background_pixel = bg;
 
   if (FRAME_X_WINDOW (f) != 0)
     {
+      Display *dpy = FRAME_X_DISPLAY (f);
+      
       BLOCK_INPUT;
-      /* The main frame area.  */
-      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->output_data.x->background_pixel);
+      XSetBackground (dpy, x->normal_gc, bg);
+      XSetForeground (dpy, x->reverse_gc, bg);
+      XSetWindowBackground (dpy, FRAME_X_WINDOW (f), bg);
+      XSetForeground (dpy, x->cursor_gc, bg);
+
+#ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
+                                  toolkit scroll bars.  */
       {
        Lisp_Object bar;
-       for (bar = FRAME_SCROLL_BARS (f); !NILP (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->output_data.x->background_pixel);
+         {
+           Window window = SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar));
+           XSetWindowBackground (dpy, window, bg);
+         }
       }
-      UNBLOCK_INPUT;
+#endif /* USE_TOOLKIT_SCROLL_BARS */
 
+      UNBLOCK_INPUT;
       update_face_from_frame_parameter (f, Qbackground_color, arg);
 
       if (FRAME_VISIBLE_P (f))
@@ -1403,149 +1441,141 @@ x_set_mouse_color (f, arg, oldval)
      struct frame *f;
      Lisp_Object arg, oldval;
 {
+  struct x_output *x = f->output_data.x;
+  Display *dpy = FRAME_X_DISPLAY (f);
   Cursor cursor, nontext_cursor, mode_cursor, cross_cursor;
   Cursor hourglass_cursor, horizontal_drag_cursor;
   int count;
   unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
-  unsigned long mask_color = f->output_data.x->background_pixel;
+  unsigned long mask_color = x->background_pixel;
 
   /* Don't let pointers be invisible.  */
-  if (mask_color == pixel
-      && mask_color == f->output_data.x->background_pixel)
+  if (mask_color == pixel)
     {
       x_free_colors (f, &pixel, 1);
-      pixel = x_copy_color (f, f->output_data.x->foreground_pixel);
+      pixel = x_copy_color (f, x->foreground_pixel);
     }
 
-  unload_color (f, f->output_data.x->mouse_pixel);
-  f->output_data.x->mouse_pixel = pixel;
+  unload_color (f, x->mouse_pixel);
+  x->mouse_pixel = pixel;
 
   BLOCK_INPUT;
 
   /* It's not okay to crash if the user selects a screwy cursor.  */
-  count = x_catch_errors (FRAME_X_DISPLAY (f));
+  count = x_catch_errors (dpy);
 
-  if (!EQ (Qnil, Vx_pointer_shape))
+  if (!NILP (Vx_pointer_shape))
     {
       CHECK_NUMBER (Vx_pointer_shape, 0);
-      cursor = XCreateFontCursor (FRAME_X_DISPLAY (f), XINT (Vx_pointer_shape));
+      cursor = XCreateFontCursor (dpy, XINT (Vx_pointer_shape));
     }
   else
-    cursor = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_xterm);
-  x_check_errors (FRAME_X_DISPLAY (f), "bad text pointer cursor: %s");
+    cursor = XCreateFontCursor (dpy, XC_xterm);
+  x_check_errors (dpy, "bad text pointer cursor: %s");
 
-  if (!EQ (Qnil, Vx_nontext_pointer_shape))
+  if (!NILP (Vx_nontext_pointer_shape))
     {
       CHECK_NUMBER (Vx_nontext_pointer_shape, 0);
-      nontext_cursor = XCreateFontCursor (FRAME_X_DISPLAY (f),
-                                         XINT (Vx_nontext_pointer_shape));
+      nontext_cursor
+       = XCreateFontCursor (dpy, XINT (Vx_nontext_pointer_shape));
     }
   else
-    nontext_cursor = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_left_ptr);
-  x_check_errors (FRAME_X_DISPLAY (f), "bad nontext pointer cursor: %s");
+    nontext_cursor = XCreateFontCursor (dpy, XC_left_ptr);
+  x_check_errors (dpy, "bad nontext pointer cursor: %s");
 
-  if (!EQ (Qnil, Vx_hourglass_pointer_shape))
+  if (!NILP (Vx_hourglass_pointer_shape))
     {
       CHECK_NUMBER (Vx_hourglass_pointer_shape, 0);
-      hourglass_cursor = XCreateFontCursor (FRAME_X_DISPLAY (f),
-                                           XINT (Vx_hourglass_pointer_shape));
+      hourglass_cursor
+       = XCreateFontCursor (dpy, XINT (Vx_hourglass_pointer_shape));
     }
   else
-    hourglass_cursor = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_watch);
-  x_check_errors (FRAME_X_DISPLAY (f), "bad hourglass pointer cursor: %s");
+    hourglass_cursor = XCreateFontCursor (dpy, XC_watch);
+  x_check_errors (dpy, "bad hourglass pointer cursor: %s");
   
-  x_check_errors (FRAME_X_DISPLAY (f), "bad nontext pointer cursor: %s");
-  if (!EQ (Qnil, Vx_mode_pointer_shape))
+  x_check_errors (dpy, "bad nontext pointer cursor: %s");
+  if (!NILP (Vx_mode_pointer_shape))
     {
       CHECK_NUMBER (Vx_mode_pointer_shape, 0);
-      mode_cursor = XCreateFontCursor (FRAME_X_DISPLAY (f),
-                                      XINT (Vx_mode_pointer_shape));
+      mode_cursor = XCreateFontCursor (dpy, XINT (Vx_mode_pointer_shape));
     }
   else
-    mode_cursor = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_xterm);
-  x_check_errors (FRAME_X_DISPLAY (f), "bad modeline pointer cursor: %s");
+    mode_cursor = XCreateFontCursor (dpy, XC_xterm);
+  x_check_errors (dpy, "bad modeline pointer cursor: %s");
 
-  if (!EQ (Qnil, Vx_sensitive_text_pointer_shape))
+  if (!NILP (Vx_sensitive_text_pointer_shape))
     {
       CHECK_NUMBER (Vx_sensitive_text_pointer_shape, 0);
       cross_cursor
-       = XCreateFontCursor (FRAME_X_DISPLAY (f),
-                            XINT (Vx_sensitive_text_pointer_shape));
+       = XCreateFontCursor (dpy, XINT (Vx_sensitive_text_pointer_shape));
     }
   else
-    cross_cursor = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_crosshair);
+    cross_cursor = XCreateFontCursor (dpy, XC_crosshair);
 
   if (!NILP (Vx_window_horizontal_drag_shape))
     {
       CHECK_NUMBER (Vx_window_horizontal_drag_shape, 0);
       horizontal_drag_cursor
-       = XCreateFontCursor (FRAME_X_DISPLAY (f),
-                            XINT (Vx_window_horizontal_drag_shape));
+       = XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape));
     }
   else
     horizontal_drag_cursor
-      = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_sb_h_double_arrow);
+      = XCreateFontCursor (dpy, XC_sb_h_double_arrow);
 
   /* 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), count);
+  x_check_errors (dpy, "can't set cursor shape: %s");
+  x_uncatch_errors (dpy, count);
 
   {
     XColor fore_color, back_color;
 
-    fore_color.pixel = f->output_data.x->mouse_pixel;
+    fore_color.pixel = x->mouse_pixel;
     x_query_color (f, &fore_color);
     back_color.pixel = mask_color;
     x_query_color (f, &back_color);
     
-    XRecolorCursor (FRAME_X_DISPLAY (f), cursor,
-                   &fore_color, &back_color);
-    XRecolorCursor (FRAME_X_DISPLAY (f), nontext_cursor,
-                   &fore_color, &back_color);
-    XRecolorCursor (FRAME_X_DISPLAY (f), mode_cursor,
-                   &fore_color, &back_color);
-    XRecolorCursor (FRAME_X_DISPLAY (f), cross_cursor,
-                   &fore_color, &back_color);
-    XRecolorCursor (FRAME_X_DISPLAY (f), hourglass_cursor,
-                    &fore_color, &back_color);
-    XRecolorCursor (FRAME_X_DISPLAY (f), horizontal_drag_cursor,
-                    &fore_color, &back_color);
+    XRecolorCursor (dpy, cursor, &fore_color, &back_color);
+    XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
+    XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
+    XRecolorCursor (dpy, cross_cursor, &fore_color, &back_color);
+    XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
+    XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
   }
 
   if (FRAME_X_WINDOW (f) != 0)
-    XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 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->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 (hourglass_cursor != f->output_data.x->hourglass_cursor
-      && f->output_data.x->hourglass_cursor != 0)
-    XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->hourglass_cursor);
-  f->output_data.x->hourglass_cursor = hourglass_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;
-
-  if (horizontal_drag_cursor != f->output_data.x->horizontal_drag_cursor
-      && f->output_data.x->horizontal_drag_cursor != 0)
-    XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->horizontal_drag_cursor);
-  f->output_data.x->horizontal_drag_cursor = horizontal_drag_cursor;
+    XDefineCursor (dpy, FRAME_X_WINDOW (f), cursor);
+
+  if (cursor != x->text_cursor
+      && x->text_cursor != 0)
+    XFreeCursor (dpy, x->text_cursor);
+  x->text_cursor = cursor;
+
+  if (nontext_cursor != x->nontext_cursor
+      && x->nontext_cursor != 0)
+    XFreeCursor (dpy, x->nontext_cursor);
+  x->nontext_cursor = nontext_cursor;
+
+  if (hourglass_cursor != x->hourglass_cursor
+      && x->hourglass_cursor != 0)
+    XFreeCursor (dpy, x->hourglass_cursor);
+  x->hourglass_cursor = hourglass_cursor;
+
+  if (mode_cursor != x->modeline_cursor
+      && x->modeline_cursor != 0)
+    XFreeCursor (dpy, f->output_data.x->modeline_cursor);
+  x->modeline_cursor = mode_cursor;
+  
+  if (cross_cursor != x->cross_cursor
+      && x->cross_cursor != 0)
+    XFreeCursor (dpy, x->cross_cursor);
+  x->cross_cursor = cross_cursor;
 
-  XFlush (FRAME_X_DISPLAY (f));
+  if (horizontal_drag_cursor != x->horizontal_drag_cursor
+      && x->horizontal_drag_cursor != 0)
+    XFreeCursor (dpy, x->horizontal_drag_cursor);
+  x->horizontal_drag_cursor = horizontal_drag_cursor;
+
+  XFlush (dpy);
   UNBLOCK_INPUT;
 
   update_face_from_frame_parameter (f, Qmouse_color, arg);
@@ -1558,6 +1588,7 @@ x_set_cursor_color (f, arg, oldval)
 {
   unsigned long fore_pixel, pixel;
   int fore_pixel_allocated_p = 0, pixel_allocated_p = 0;
+  struct x_output *x = f->output_data.x;
 
   if (!NILP (Vx_cursor_fore_pixel))
     {
@@ -1566,13 +1597,13 @@ x_set_cursor_color (f, arg, oldval)
       fore_pixel_allocated_p = 1;
     }
   else
-    fore_pixel = f->output_data.x->background_pixel;
+    fore_pixel = x->background_pixel;
   
   pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
   pixel_allocated_p = 1;
 
   /* Make sure that the cursor color differs from the background color.  */
-  if (pixel == f->output_data.x->background_pixel)
+  if (pixel == x->background_pixel)
     {
       if (pixel_allocated_p)
        {
@@ -1580,7 +1611,7 @@ x_set_cursor_color (f, arg, oldval)
          pixel_allocated_p = 0;
        }
       
-      pixel = f->output_data.x->mouse_pixel;
+      pixel = x->mouse_pixel;
       if (pixel == fore_pixel)
        {
          if (fore_pixel_allocated_p)
@@ -1588,27 +1619,25 @@ x_set_cursor_color (f, arg, oldval)
              x_free_colors (f, &fore_pixel, 1);
              fore_pixel_allocated_p = 0;
            }
-         fore_pixel = f->output_data.x->background_pixel;
+         fore_pixel = x->background_pixel;
        }
     }
 
-  unload_color (f, f->output_data.x->cursor_foreground_pixel);
+  unload_color (f, x->cursor_foreground_pixel);
   if (!fore_pixel_allocated_p)
     fore_pixel = x_copy_color (f, fore_pixel);
-  f->output_data.x->cursor_foreground_pixel = fore_pixel;
+  x->cursor_foreground_pixel = fore_pixel;
 
-  unload_color (f, f->output_data.x->cursor_pixel);
+  unload_color (f, x->cursor_pixel);
   if (!pixel_allocated_p)
     pixel = x_copy_color (f, pixel);
-  f->output_data.x->cursor_pixel = pixel;
+  x->cursor_pixel = pixel;
 
   if (FRAME_X_WINDOW (f) != 0)
     {
       BLOCK_INPUT;
-      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);
+      XSetBackground (FRAME_X_DISPLAY (f), x->cursor_gc, x->cursor_pixel);
+      XSetForeground (FRAME_X_DISPLAY (f), x->cursor_gc, fore_pixel);
       UNBLOCK_INPUT;
 
       if (FRAME_VISIBLE_P (f))
@@ -2073,6 +2102,9 @@ x_set_tool_bar_lines (f, value, oldval)
       x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                    0, y, width, height, False);
       UNBLOCK_INPUT;
+
+      if (WINDOWP (f->tool_bar_window))
+       clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
     }
 }
 
@@ -2132,6 +2164,20 @@ x_set_scroll_bar_background (f, value, oldval)
   if (f->output_data.x->scroll_bar_background_pixel != -1)
     unload_color (f, f->output_data.x->scroll_bar_background_pixel);
   
+#ifdef USE_TOOLKIT_SCROLL_BARS
+  /* Scrollbar shadow colors.  */
+  if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
+    {
+      unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
+      f->output_data.x->scroll_bar_top_shadow_pixel = -1;
+    }
+  if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
+    {
+      unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
+      f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
+    }
+#endif /* USE_TOOLKIT_SCROLL_BARS */
+
   f->output_data.x->scroll_bar_background_pixel = pixel;
   if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
     {
@@ -2593,16 +2639,16 @@ validate_x_resource_name ()
 extern char *x_get_string_resource ();
 
 DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0,
-  "Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.\n\
-This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the\n\
-class, where INSTANCE is the name under which Emacs was invoked, or\n\
-the name specified by the `-name' or `-rn' command-line arguments.\n\
-\n\
-The optional arguments COMPONENT and SUBCLASS add to the key and the\n\
-class, respectively.  You must specify both of them or neither.\n\
-If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'\n\
-and the class is `Emacs.CLASS.SUBCLASS'.")
-  (attribute, class, component, subclass)
+  doc: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.
+This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the
+class, where INSTANCE is the name under which Emacs was invoked, or
+the name specified by the `-name' or `-rn' command-line arguments.
+
+The optional arguments COMPONENT and SUBCLASS add to the key and the
+class, respectively.  You must specify both of them or neither.
+If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
+and the class is `Emacs.CLASS.SUBCLASS'.  */)
+     (attribute, class, component, subclass)
      Lisp_Object attribute, class, component, subclass;
 {
   register char *value;
@@ -2924,9 +2970,9 @@ x_default_scroll_bar_color_parameter (f, alist, prop, xprop, xclass,
                                    build_string (foreground_p
                                                  ? "foreground"
                                                  : "background"),
-                                   build_string (""),
+                                   empty_string,
                                    build_string ("verticalScrollBar"),
-                                   build_string (""));
+                                   empty_string);
       if (!STRINGP (tem))
        {
          /* If nothing has been specified, scroll bars will use a
@@ -2951,12 +2997,12 @@ x_default_scroll_bar_color_parameter (f, alist, prop, xprop, xclass,
 
 \f
 DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0,
-       "Parse an X-style geometry string STRING.\n\
-Returns an alist of the form ((top . TOP), (left . LEFT) ... ).\n\
-The properties returned may include `top', `left', `height', and `width'.\n\
-The value of `left' or `top' may be an integer,\n\
-or a list (+ N) meaning N pixels relative to top/left corner,\n\
-or a list (- N) meaning -N pixels relative to bottom/right corner.")
+       doc: /* Parse an X-style geometry string STRING.
+Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
+The properties returned may include `top', `left', `height', and `width'.
+The value of `left' or `top' may be an integer,
+or a list (+ N) meaning N pixels relative to top/left corner,
+or a list (- N) meaning -N pixels relative to bottom/right corner.  */)
      (string)
      Lisp_Object string;
 {
@@ -3969,8 +4015,7 @@ x_make_gc (f)
        gray_bits, gray_width, gray_height,
        f->output_data.x->foreground_pixel,
        f->output_data.x->background_pixel,
-       DefaultDepth (FRAME_X_DISPLAY (f),
-                     XScreenNumberOfScreen (FRAME_X_SCREEN (f)))));
+       DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
 
   UNBLOCK_INPUT;
 }
@@ -4045,16 +4090,16 @@ unwind_create_frame (frame)
 
 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
        1, 1, 0,
-  "Make a new X window, which is called a \"frame\" in Emacs terms.\n\
-Returns an Emacs frame object.\n\
-ALIST is an alist of frame parameters.\n\
-If the parameters specify that the frame should not have a minibuffer,\n\
-and do not specify a specific minibuffer window to use,\n\
-then `default-minibuffer-frame' must be a frame whose minibuffer can\n\
-be shared by the new frame.\n\
-\n\
-This function is an internal primitive--use `make-frame' instead.")
-  (parms)
+       doc: /* Make a new X window, which is called a "frame" in Emacs terms.
+Returns an Emacs frame object.
+ALIST is an alist of frame parameters.
+If the parameters specify that the frame should not have a minibuffer,
+and do not specify a specific minibuffer window to use,
+then `default-minibuffer-frame' must be a frame whose minibuffer can
+be shared by the new frame.
+
+This function is an internal primitive--use `make-frame' instead.  */)
+     (parms)
      Lisp_Object parms;
 {
   struct frame *f;
@@ -4133,6 +4178,10 @@ This function is an internal primitive--use `make-frame' instead.")
   f->output_data.x->fontset = -1;
   f->output_data.x->scroll_bar_foreground_pixel = -1;
   f->output_data.x->scroll_bar_background_pixel = -1;
+#ifdef USE_TOOLKIT_SCROLL_BARS
+  f->output_data.x->scroll_bar_top_shadow_pixel = -1;
+  f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
+#endif /* USE_TOOLKIT_SCROLL_BARS */
   record_unwind_protect (unwind_create_frame, frame);
 
   f->icon_name
@@ -4155,6 +4204,16 @@ This function is an internal primitive--use `make-frame' instead.")
   {
     Lisp_Object black;
     struct gcpro gcpro1;
+
+    /* Function x_decode_color can signal an error.  Make
+       sure to initialize color slots so that we won't try
+       to free colors we haven't allocated.  */
+    f->output_data.x->foreground_pixel = -1;
+    f->output_data.x->background_pixel = -1;
+    f->output_data.x->cursor_pixel = -1;
+    f->output_data.x->cursor_foreground_pixel = -1;
+    f->output_data.x->border_pixel = -1;
+    f->output_data.x->mouse_pixel = -1;
     
     black = build_string ("black");
     GCPRO1 (black);
@@ -4310,6 +4369,8 @@ This function is an internal primitive--use `make-frame' instead.")
                       RES_TYPE_SYMBOL);
   x_default_parameter (f, parms, Qtitle, Qnil,
                       "title", "Title", RES_TYPE_STRING);
+  x_default_parameter (f, parms, Qwait_for_wm, Qt,
+                      "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
 
   f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
 
@@ -4455,6 +4516,11 @@ This function is an internal primitive--use `make-frame' instead.")
     }
 
   UNGCPRO;
+
+  /* Make sure windows on this frame appear in calls to next-window
+     and similar functions.  */
+  Vwindow_list = Qnil;
+  
   return unbind_to (count, frame);
 }
 
@@ -4487,9 +4553,9 @@ x_get_focus_frame (frame)
    following a user-command.  */
 
 DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
-  "Set the input focus to FRAME.\n\
-FRAME nil means use the selected frame.")
-  (frame)
+       doc: /* Set the input focus to FRAME.
+FRAME nil means use the selected frame.  */)
+     (frame)
      Lisp_Object frame;
 {
   struct frame *f = check_x_frame (frame);
@@ -4508,8 +4574,8 @@ FRAME nil means use the selected frame.")
 
 \f
 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
-  "Internal function called by `color-defined-p', which see.")
-  (color, frame)
+       doc: /* Internal function called by `color-defined-p', which see.  */)
+     (color, frame)
      Lisp_Object color, frame;
 {
   XColor foo;
@@ -4524,8 +4590,8 @@ DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
 }
 
 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
-  "Internal function called by `color-values', which see.")
-  (color, frame)
+       doc: /* Internal function called by `color-values', which see.  */)
+     (color, frame)
      Lisp_Object color, frame;
 {
   XColor foo;
@@ -4547,8 +4613,8 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
 }
 
 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
-  "Internal function called by `display-color-p', which see.")
-  (display)
+       doc: /* Internal function called by `display-color-p', which see.  */)
+     (display)
      Lisp_Object display;
 {
   struct x_display_info *dpyinfo = check_x_display_info (display);
@@ -4570,13 +4636,13 @@ DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
 }
 
 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.")
-  (display)
+       0, 1, 0,
+       doc: /* Return t if the X display supports shades of gray.
+Note that color displays do support shades of gray.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.  */)
+     (display)
      Lisp_Object display;
 {
   struct x_display_info *dpyinfo = check_x_display_info (display);
@@ -4600,12 +4666,12 @@ If omitted or nil, that stands for the selected frame's display.")
 }
 
 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
-  0, 1, 0,
-  "Returns the width in pixels of the X display DISPLAY.\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.")
-  (display)
+       0, 1, 0,
+       doc: /* Returns the width in pixels of the X display DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.  */)
+     (display)
      Lisp_Object display;
 {
   struct x_display_info *dpyinfo = check_x_display_info (display);
@@ -4614,12 +4680,12 @@ If omitted or nil, that stands for the selected frame's display.")
 }
 
 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
-  Sx_display_pixel_height, 0, 1, 0,
-  "Returns the height in pixels of the X display DISPLAY.\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.")
-  (display)
+       Sx_display_pixel_height, 0, 1, 0,
+       doc: /* Returns the height in pixels of the X display DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.  */)
+     (display)
      Lisp_Object display;
 {
   struct x_display_info *dpyinfo = check_x_display_info (display);
@@ -4628,12 +4694,12 @@ If omitted or nil, that stands for the selected frame's display.")
 }
 
 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
-  0, 1, 0,
-  "Returns the number of bitplanes of the X display DISPLAY.\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.")
-  (display)
+       0, 1, 0,
+       doc: /* Returns the number of bitplanes of the X display DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.  */)
+     (display)
      Lisp_Object display;
 {
   struct x_display_info *dpyinfo = check_x_display_info (display);
@@ -4642,12 +4708,12 @@ If omitted or nil, that stands for the selected frame's display.")
 }
 
 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
-  0, 1, 0,
-  "Returns the number of color cells of the X display DISPLAY.\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.")
-  (display)
+       0, 1, 0,
+       doc: /* Returns the number of color cells of the X display DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.  */)
+     (display)
      Lisp_Object display;
 {
   struct x_display_info *dpyinfo = check_x_display_info (display);
@@ -4658,12 +4724,12 @@ If omitted or nil, that stands for the selected frame's display.")
 
 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
        Sx_server_max_request_size,
-  0, 1, 0,
-  "Returns the maximum request size of the X server of display DISPLAY.\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.")
-  (display)
+       0, 1, 0,
+       doc: /* Returns the maximum request size of the X server of display DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.  */)
+     (display)
      Lisp_Object display;
 {
   struct x_display_info *dpyinfo = check_x_display_info (display);
@@ -4672,11 +4738,11 @@ If omitted or nil, that stands for the selected frame's display.")
 }
 
 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
-  "Returns the vendor ID string of the X server of display DISPLAY.\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.")
-  (display)
+       doc: /* Returns the vendor ID string of the X server of display DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.  */)
+     (display)
      Lisp_Object display;
 {
   struct x_display_info *dpyinfo = check_x_display_info (display);
@@ -4687,14 +4753,15 @@ If omitted or nil, that stands for the selected frame's display.")
 }
 
 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
-  "Returns the version numbers of the X server of display DISPLAY.\n\
-The value is a list of three integers: the major and minor\n\
-version numbers of the X Protocol in use, and the vendor-specific release\n\
-number.  See also the function `x-server-vendor'.\n\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.")
-  (display)
+       doc: /* Returns the version numbers of the X server of display DISPLAY.
+The value is a list of three integers: the major and minor
+version numbers of the X Protocol in use, and the vendor-specific release
+number.  See also the function `x-server-vendor'.
+
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.  */)
+     (display)
      Lisp_Object display;
 {
   struct x_display_info *dpyinfo = check_x_display_info (display);
@@ -4706,11 +4773,11 @@ If omitted or nil, that stands for the selected frame's display.")
 }
 
 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
-  "Returns the number of screens on the X server of display DISPLAY.\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.")
-  (display)
+       doc: /* Return the number of screens on the X server of display DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.  */)
+     (display)
      Lisp_Object display;
 {
   struct x_display_info *dpyinfo = check_x_display_info (display);
@@ -4719,11 +4786,11 @@ If omitted or nil, that stands for the selected frame's display.")
 }
 
 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
-  "Returns the height in millimeters of the X display DISPLAY.\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.")
-  (display)
+       doc: /* Return the height in millimeters of the X display DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.  */)
+     (display)
      Lisp_Object display;
 {
   struct x_display_info *dpyinfo = check_x_display_info (display);
@@ -4732,11 +4799,11 @@ If omitted or nil, that stands for the selected frame's display.")
 }
 
 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
-  "Returns the width in millimeters of the X display DISPLAY.\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.")
-  (display)
+       doc: /* Return the width in millimeters of the X display DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.  */)
+     (display)
      Lisp_Object display;
 {
   struct x_display_info *dpyinfo = check_x_display_info (display);
@@ -4745,13 +4812,13 @@ If omitted or nil, that stands for the selected frame's display.")
 }
 
 DEFUN ("x-display-backing-store", Fx_display_backing_store,
-  Sx_display_backing_store, 0, 1, 0,
-  "Returns an indication of whether X display DISPLAY does backing store.\n\
-The value may be `always', `when-mapped', or `not-useful'.\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.")
-  (display)
+       Sx_display_backing_store, 0, 1, 0,
+       doc: /* Returns an indication of whether X display DISPLAY does backing store.
+The value may be `always', `when-mapped', or `not-useful'.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.  */)
+     (display)
      Lisp_Object display;
 {
   struct x_display_info *dpyinfo = check_x_display_info (display);
@@ -4780,14 +4847,15 @@ If omitted or nil, that stands for the selected frame's display.")
 }
 
 DEFUN ("x-display-visual-class", Fx_display_visual_class,
-  Sx_display_visual_class, 0, 1, 0,
-  "Returns the visual class of the X display DISPLAY.\n\
-The value is one of the symbols `static-gray', `gray-scale',\n\
-`static-color', `pseudo-color', `true-color', or `direct-color'.\n\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.")
-       (display)
+       Sx_display_visual_class, 0, 1, 0,
+       doc: /* Return the visual class of the X display DISPLAY.
+The value is one of the symbols `static-gray', `gray-scale',
+`static-color', `pseudo-color', `true-color', or `direct-color'.
+
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.  */)
+     (display)
      Lisp_Object display;
 {
   struct x_display_info *dpyinfo = check_x_display_info (display);
@@ -4822,12 +4890,12 @@ If omitted or nil, that stands for the selected frame's display.")
 }
 
 DEFUN ("x-display-save-under", Fx_display_save_under,
-  Sx_display_save_under, 0, 1, 0,
-  "Returns t if the X display DISPLAY supports the save-under feature.\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.")
-  (display)
+       Sx_display_save_under, 0, 1, 0,
+       doc: /* Returns t if the X display DISPLAY supports the save-under feature.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.  */)
+     (display)
      Lisp_Object display;
 {
   struct x_display_info *dpyinfo = check_x_display_info (display);
@@ -5043,12 +5111,13 @@ x_display_info_for_name (name)
 
 
 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
-       1, 3, 0, "Open a connection to an X server.\n\
-DISPLAY is the name of the display to connect to.\n\
-Optional second arg XRM-STRING is a string of resources in xrdb format.\n\
-If the optional third arg MUST-SUCCEED is non-nil,\n\
-terminate Emacs if we can't open the connection.")
-  (display, xrm_string, must_succeed)
+       1, 3, 0,
+       doc: /* Open a connection to an X server.
+DISPLAY is the name of the display to connect to.
+Optional second arg XRM-STRING is a string of resources in xrdb format.
+If the optional third arg MUST-SUCCEED is non-nil,
+terminate Emacs if we can't open the connection.  */)
+     (display, xrm_string, must_succeed)
      Lisp_Object display, xrm_string, must_succeed;
 {
   unsigned char *xrm_option;
@@ -5093,11 +5162,11 @@ connections from your machine.\n",
 
 DEFUN ("x-close-connection", Fx_close_connection,
        Sx_close_connection, 1, 1, 0,
-   "Close the connection to DISPLAY's X server.\n\
-For DISPLAY, specify either a frame or a display name (a string).\n\
-If DISPLAY is nil, that stands for the selected frame's display.")
-  (display)
-  Lisp_Object display;
+       doc: /* Close the connection to DISPLAY's X server.
+For DISPLAY, specify either a frame or a display name (a string).
+If DISPLAY is nil, that stands for the selected frame's display.  */)
+     (display)
+     Lisp_Object display;
 {
   struct x_display_info *dpyinfo = check_x_display_info (display);
   int i;
@@ -5132,8 +5201,8 @@ If DISPLAY is nil, that stands for the selected frame's display.")
 }
 
 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
-  "Return the list of display names that Emacs has connections to.")
-  ()
+       doc: /* Return the list of display names that Emacs has connections to.  */)
+     ()
 {
   Lisp_Object tail, result;
 
@@ -5145,15 +5214,15 @@ DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
 }
 
 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
-   "If ON is non-nil, report X errors as soon as the erring request is made.\n\
-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.\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.")
-  (on, display)
+       doc: /* If ON is non-nil, report X errors as soon as the erring request is made.
+If ON is nil, allow buffering of requests.
+Turning on synchronization prohibits the Xlib routines from buffering
+requests and seriously degrades performance, but makes debugging much
+easier.
+The optional second argument DISPLAY specifies which display to act on.
+DISPLAY should be either a frame or a display name (a string).
+If DISPLAY is omitted or nil, that stands for the selected frame's display.  */)
+     (on, display)
     Lisp_Object display, on;
 {
   struct x_display_info *dpyinfo = check_x_display_info (display);
@@ -5274,11 +5343,22 @@ valid_image_p (object)
   
   if (CONSP (object) && EQ (XCAR (object), Qimage))
     {
-      Lisp_Object symbol = Fplist_get (XCDR (object), QCtype);
-      struct image_type *type = lookup_image_type (symbol);
-      
-      if (type)
-       valid_p = type->valid_p (object);
+      Lisp_Object tem;
+
+      for (tem = XCDR (object); CONSP (tem); tem = XCDR (tem))
+       if (EQ (XCAR (tem), QCtype))
+         {
+           tem = XCDR (tem);
+           if (CONSP (tem) && SYMBOLP (XCAR (tem)))
+             {
+               struct image_type *type;
+               type = lookup_image_type (XCAR (tem));
+               if (type)
+                 valid_p = type->valid_p (object);
+             }
+           
+           break;
+         }
     }
 
   return valid_p;
@@ -5309,6 +5389,7 @@ enum image_value_type
 {
   IMAGE_DONT_CHECK_VALUE_TYPE,
   IMAGE_STRING_VALUE,
+  IMAGE_STRING_OR_NIL_VALUE,
   IMAGE_SYMBOL_VALUE,
   IMAGE_POSITIVE_INTEGER_VALUE,
   IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,
@@ -5406,6 +5487,11 @@ parse_image_spec (spec, keywords, nkeywords, type)
            return 0;
          break;
 
+       case IMAGE_STRING_OR_NIL_VALUE:
+         if (!STRINGP (value) && !NILP (value))
+           return 0;
+         break;
+
        case IMAGE_SYMBOL_VALUE:
          if (!SYMBOLP (value))
            return 0;
@@ -5515,12 +5601,12 @@ image_spec_value (spec, key, found)
      
 
 DEFUN ("image-size", Fimage_size, Simage_size, 1, 3, 0,
-  "Return the size of image SPEC as pair (WIDTH . HEIGHT).\n\
-PIXELS non-nil means return the size in pixels, otherwise return the\n\
-size in canonical character units.\n\
-FRAME is the frame on which the image will be displayed.  FRAME nil\n\
-or omitted means use the selected frame.")
-  (spec, pixels, frame)
+       doc: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
+PIXELS non-nil means return the size in pixels, otherwise return the
+size in canonical character units.
+FRAME is the frame on which the image will be displayed.  FRAME nil
+or omitted means use the selected frame.  */)
+     (spec, pixels, frame)
      Lisp_Object spec, pixels, frame;
 {
   Lisp_Object size;
@@ -5548,10 +5634,10 @@ or omitted means use the selected frame.")
 
 
 DEFUN ("image-mask-p", Fimage_mask_p, Simage_mask_p, 1, 2, 0,
-  "Return t if image SPEC has a mask bitmap.\n\
-FRAME is the frame on which the image will be displayed.  FRAME nil\n\
-or omitted means use the selected frame.")
-  (spec, frame)
+       doc: /* Return t if image SPEC has a mask bitmap.
+FRAME is the frame on which the image will be displayed.  FRAME nil
+or omitted means use the selected frame.  */)
+     (spec, frame)
      Lisp_Object spec, frame;
 {
   Lisp_Object mask;
@@ -5783,6 +5869,7 @@ x_alloc_image_color (f, img, color_name, dflt)
  ***********************************************************************/
 
 static void cache_image P_ ((struct frame *f, struct image *img));
+static void postprocess_image P_ ((struct frame *, struct image *));
 
 
 /* Return a new, initialized image cache that is allocated from the
@@ -5893,10 +5980,10 @@ clear_image_cache (f, force_p)
 
 DEFUN ("clear-image-cache", Fclear_image_cache, Sclear_image_cache,
        0, 1, 0,
-  "Clear the image cache of FRAME.\n\
-FRAME nil or omitted means use the selected frame.\n\
-FRAME t means clear the image caches of all frames.")
-  (frame)
+       doc: /* Clear the image cache of FRAME.
+FRAME nil or omitted means use the selected frame.
+FRAME t means clear the image caches of all frames.  */)
+     (frame)
      Lisp_Object frame;
 {
   if (EQ (frame, Qt))
@@ -5914,6 +6001,81 @@ FRAME t means clear the image caches of all frames.")
 }
 
 
+/* Compute masks and transform image IMG on frame F, as specified
+   by the image's specification,  */
+
+static void
+postprocess_image (f, img)
+     struct frame *f;
+     struct image *img;
+{
+  /* Manipulation of the image's mask.  */
+  if (img->pixmap)
+    {
+      Lisp_Object conversion, spec;
+      Lisp_Object mask;
+
+      spec = img->spec;
+      
+      /* `:heuristic-mask t'
+        `:mask heuristic'
+        means build a mask heuristically.
+        `:heuristic-mask (R G B)'
+        `:mask (heuristic (R G B))'
+        means build a mask from color (R G B) in the
+        image.
+        `:mask nil'
+        means remove a mask, if any.  */
+             
+      mask = image_spec_value (spec, QCheuristic_mask, NULL);
+      if (!NILP (mask))
+       x_build_heuristic_mask (f, img, mask);
+      else
+       {
+         int found_p;
+                   
+         mask = image_spec_value (spec, QCmask, &found_p);
+                 
+         if (EQ (mask, Qheuristic))
+           x_build_heuristic_mask (f, img, Qt);
+         else if (CONSP (mask)
+                  && EQ (XCAR (mask), Qheuristic))
+           {
+             if (CONSP (XCDR (mask)))
+               x_build_heuristic_mask (f, img, XCAR (XCDR (mask)));
+             else
+               x_build_heuristic_mask (f, img, XCDR (mask));
+           }
+         else if (NILP (mask) && found_p && img->mask)
+           {
+             XFreePixmap (FRAME_X_DISPLAY (f), img->mask);
+             img->mask = None;
+           }
+       }
+         
+      /* Should we apply an image transformation algorithm?  */
+      conversion = image_spec_value (spec, QCconversion, NULL);
+      if (EQ (conversion, Qdisabled))
+       x_disable_image (f, img);
+      else if (EQ (conversion, Qlaplace))
+       x_laplace (f, img);
+      else if (EQ (conversion, Qemboss))
+       x_emboss (f, img);
+      else if (CONSP (conversion)
+              && EQ (XCAR (conversion), Qedge_detection))
+       {
+         Lisp_Object tem;
+         tem = XCDR (conversion);
+         if (CONSP (tem))
+           x_edge_detection (f, img,
+                             Fplist_get (tem, QCmatrix),
+                             Fplist_get (tem, QCcolor_adjustment));
+       }
+    }
+}
+
+
 /* Return the id of image with Lisp specification SPEC on frame F.
    SPEC must be a valid Lisp image specification (see valid_image_p).  */
 
@@ -5947,6 +6109,8 @@ lookup_image (f, spec)
   /* If not found, create a new image and cache it.  */
   if (img == NULL)
     {
+      extern Lisp_Object Qpostscript;
+      
       BLOCK_INPUT;
       img = make_image (spec, hash);
       cache_image (f, img);
@@ -5998,71 +6162,10 @@ lookup_image (f, spec)
              img->vmargin += abs (img->relief);
            }
 
-         /* Manipulation of the image's mask.  */
-         if (img->pixmap)
-           {
-             /* `:heuristic-mask t'
-                `:mask heuristic'
-                       means build a mask heuristically.
-                `:heuristic-mask (R G B)'
-                `:mask (heuristic (R G B))'
-                       means build a mask from color (R G B) in the
-                       image.
-                `:mask nil'
-                       means remove a mask, if any.  */
-             
-             Lisp_Object mask;
-
-             mask = image_spec_value (spec, QCheuristic_mask, NULL);
-             if (!NILP (mask))
-               x_build_heuristic_mask (f, img, mask);
-             else
-               {
-                 int found_p;
-                   
-                 mask = image_spec_value (spec, QCmask, &found_p);
-                 
-                 if (EQ (mask, Qheuristic))
-                   x_build_heuristic_mask (f, img, Qt);
-                 else if (CONSP (mask)
-                          && EQ (XCAR (mask), Qheuristic))
-                   {
-                     if (CONSP (XCDR (mask)))
-                       x_build_heuristic_mask (f, img, XCAR (XCDR (mask)));
-                     else
-                       x_build_heuristic_mask (f, img, XCDR (mask));
-                   }
-                 else if (NILP (mask) && found_p && img->mask)
-                   {
-                     XFreePixmap (FRAME_X_DISPLAY (f), img->mask);
-                     img->mask = None;
-                   }
-               }
-           }
-         
-         /* Should we apply an image transformation algorithm?  */
-         if (img->pixmap)
-           {
-             Lisp_Object conversion;
-
-             conversion = image_spec_value (spec, QCconversion, NULL);
-             if (EQ (conversion, Qdisabled))
-               x_disable_image (f, img);
-             else if (EQ (conversion, Qlaplace))
-               x_laplace (f, img);
-             else if (EQ (conversion, Qemboss))
-               x_emboss (f, img);
-             else if (CONSP (conversion)
-                      && EQ (XCAR (conversion), Qedge_detection))
-               {
-                 Lisp_Object tem;
-                 tem = XCDR (conversion);
-                 if (CONSP (tem))
-                   x_edge_detection (f, img,
-                                     Fplist_get (tem, QCmatrix),
-                                     Fplist_get (tem, QCcolor_adjustment));
-               }
-           }
+         /* Do image transformations and compute masks, unless we
+            don't have the image yet.  */
+         if (!EQ (*img->type->type, Qpostscript))
+           postprocess_image (f, img);
        }
 
       UNBLOCK_INPUT;
@@ -6259,7 +6362,7 @@ x_find_image_file (file)
   GCPRO2 (file_found, search_path);
 
   /* Try to find FILE in data-directory, then x-bitmap-file-path.  */
-  fd = openp (search_path, file, "", &file_found, 0);
+  fd = openp (search_path, file, Qnil, &file_found, 0);
   
   if (fd == -1)
     file_found = Qnil;
@@ -6352,8 +6455,8 @@ static struct image_keyword xbm_format[XBM_LAST] =
   {":width",           IMAGE_POSITIVE_INTEGER_VALUE,           0},
   {":height",          IMAGE_POSITIVE_INTEGER_VALUE,           0},
   {":data",            IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-  {":foreground",      IMAGE_STRING_VALUE,                     0},
-  {":background",      IMAGE_STRING_VALUE,                     0},
+  {":foreground",      IMAGE_STRING_OR_NIL_VALUE,              0},
+  {":background",      IMAGE_STRING_OR_NIL_VALUE,              0},
   {":ascent",          IMAGE_ASCENT_VALUE,                     0},
   {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
   {":relief",          IMAGE_INTEGER_VALUE,                    0},
@@ -6887,10 +6990,12 @@ xbm_load (f, img)
        }
 
       /* Get foreground and background colors, maybe allocate colors.  */
-      if (fmt[XBM_FOREGROUND].count)
+      if (fmt[XBM_FOREGROUND].count
+         && STRINGP (fmt[XBM_FOREGROUND].value))
        foreground = x_alloc_image_color (f, img, fmt[XBM_FOREGROUND].value,
                                          foreground);
-      if (fmt[XBM_BACKGROUND].count)
+      if (fmt[XBM_BACKGROUND].count
+         && STRINGP (fmt[XBM_BACKGROUND].value))
        background = x_alloc_image_color (f, img, fmt[XBM_BACKGROUND].value,
                                          background);
 
@@ -8078,8 +8183,8 @@ static struct image_keyword pbm_format[PBM_LAST] =
   {":conversion",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},
   {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
   {":mask",            IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-  {":foreground",      IMAGE_STRING_VALUE,                     0},
-  {":background",      IMAGE_STRING_VALUE,                     0}
+  {":foreground",      IMAGE_STRING_OR_NIL_VALUE,              0},
+  {":background",      IMAGE_STRING_OR_NIL_VALUE,              0}
 };
 
 /* Structure describing the image type `pbm'.  */
@@ -8277,9 +8382,11 @@ pbm_load (f, img)
       parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm);
       
       /* Get foreground and background colors, maybe allocate colors.  */
-      if (fmt[PBM_FOREGROUND].count)
+      if (fmt[PBM_FOREGROUND].count
+         && STRINGP (fmt[PBM_FOREGROUND].value))
        fg = x_alloc_image_color (f, img, fmt[PBM_FOREGROUND].value, fg);
-      if (fmt[PBM_BACKGROUND].count)
+      if (fmt[PBM_BACKGROUND].count
+         && STRINGP (fmt[PBM_BACKGROUND].value))
        bg = x_alloc_image_color (f, img, fmt[PBM_BACKGROUND].value, bg);
       
       for (y = 0; y < height; ++y)
@@ -9385,6 +9492,34 @@ tiff_size_of_memory (data)
 }
 
 
+static void
+tiff_error_handler (title, format, ap)
+     const char *title, *format;
+     va_list ap;
+{
+  char buf[512];
+  int len;
+  
+  len = sprintf (buf, "TIFF error: %s ", title);
+  vsprintf (buf + len, format, ap);
+  add_to_log (buf, Qnil, Qnil);
+}
+
+
+static void
+tiff_warning_handler (title, format, ap)
+     const char *title, *format;
+     va_list ap;
+{
+  char buf[512];
+  int len;
+  
+  len = sprintf (buf, "TIFF warning: %s ", title);
+  vsprintf (buf + len, format, ap);
+  add_to_log (buf, Qnil, Qnil);
+}
+
+
 /* Load TIFF image IMG for use on frame F.  Value is non-zero if
    successful.  */
 
@@ -9408,6 +9543,9 @@ tiff_load (f, img)
   file = Qnil;
   GCPRO1 (file);
 
+  TIFFSetErrorHandler (tiff_error_handler);
+  TIFFSetWarningHandler (tiff_warning_handler);
+
   if (NILP (specified_data))
     {
       /* Read from a file */
@@ -10028,9 +10166,13 @@ x_kill_gs_process (pixmap, f)
     if (c->images[i]->pixmap == pixmap)
       break;
 
+  /* Should someone in between have cleared the image cache, for
+     instance, give up.  */
+  if (i == c->used)
+    return;
+  
   /* Kill the GS process.  We should have found PIXMAP in the image
      cache and its image should contain a process object.  */
-  xassert (i < c->used);
   img = c->images[i];
   xassert (PROCESSP (img->data.lisp_val));
   Fkill_process (img->data.lisp_val, Qnil);
@@ -10087,6 +10229,12 @@ x_kill_gs_process (pixmap, f)
       
       UNBLOCK_INPUT;
     }
+
+  /* Now that we have the pixmap, compute mask and transform the
+     image if requested.  */
+  BLOCK_INPUT;
+  postprocess_image (f, img);
+  UNBLOCK_INPUT;
 }
 
 
@@ -10097,10 +10245,10 @@ x_kill_gs_process (pixmap, f)
 
 DEFUN ("x-change-window-property", Fx_change_window_property,
        Sx_change_window_property, 2, 3, 0,
-  "Change window property PROP to VALUE on the X window of FRAME.\n\
-PROP and VALUE must be strings.  FRAME nil or omitted means use the\n\
-selected frame.  Value is VALUE.")
-  (prop, value, frame)
+       doc: /* Change window property PROP to VALUE on the X window of FRAME.
+PROP and VALUE must be strings.  FRAME nil or omitted means use the
+selected frame.  Value is VALUE.  */)
+     (prop, value, frame)
      Lisp_Object frame, prop, value;
 {
   struct frame *f = check_x_frame (frame);
@@ -10125,9 +10273,9 @@ selected frame.  Value is VALUE.")
 
 DEFUN ("x-delete-window-property", Fx_delete_window_property,
        Sx_delete_window_property, 1, 2, 0,
-  "Remove window property PROP from X window of FRAME.\n\
-FRAME nil or omitted means use the selected frame.  Value is PROP.")
-  (prop, frame)
+       doc: /* Remove window property PROP from X window of FRAME.
+FRAME nil or omitted means use the selected frame.  Value is PROP.  */)
+     (prop, frame)
      Lisp_Object prop, frame;
 {
   struct frame *f = check_x_frame (frame);
@@ -10148,11 +10296,11 @@ FRAME nil or omitted means use the selected frame.  Value is PROP.")
 
 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
        1, 2, 0,
-  "Value is the value of window property PROP on FRAME.\n\
-If FRAME is nil or omitted, use the selected frame.  Value is nil\n\
-if FRAME hasn't a property with name PROP or if PROP has no string\n\
-value.")
-  (prop, frame)
+       doc: /* Value is the value of window property PROP on FRAME.
+If FRAME is nil or omitted, use the selected frame.  Value is nil
+if FRAME hasn't a property with name PROP or if PROP has no string
+value.  */)
+     (prop, frame)
      Lisp_Object prop, frame;
 {
   struct frame *f = check_x_frame (frame);
@@ -10184,7 +10332,7 @@ value.")
                               &actual_type, &actual_format, 
                               &actual_size, &bytes_remaining, 
                               (unsigned char **) &tmp_data);
-      if (rc == Success)
+      if (rc == Success && tmp_data)
        prop_value = make_string (tmp_data, size);
 
       XFree (tmp_data);
@@ -10377,9 +10525,9 @@ hide_hourglass ()
  ***********************************************************************/
 
 static Lisp_Object x_create_tip_frame P_ ((struct x_display_info *,
-                                          Lisp_Object));
+                                          Lisp_Object, Lisp_Object));
 static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
-                               Lisp_Object, int *, int *));
+                               Lisp_Object, int, int, int *, int *));
      
 /* The frame of a currently visible tooltip.  */
 
@@ -10396,6 +10544,10 @@ Window tip_window;
 
 Lisp_Object last_show_tip_args;
 
+/* Maximum size for tooltips; a cons (COLUMNS . ROWS).  */
+
+Lisp_Object Vx_max_tooltip_size;
+
 
 static Lisp_Object
 unwind_create_tip_frame (frame)
@@ -10415,7 +10567,8 @@ unwind_create_tip_frame (frame)
 
 
 /* Create a frame for a tooltip on the display described by DPYINFO.
-   PARMS is a list of frame parameters.  Value is the frame.
+   PARMS is a list of frame parameters.  TEXT is the string to
+   display in the tip frame.  Value is the frame.
 
    Note that functions called here, esp. x_default_parameter can
    signal errors, for instance when a specified color name is
@@ -10423,9 +10576,9 @@ unwind_create_tip_frame (frame)
    when this happens.  */
 
 static Lisp_Object
-x_create_tip_frame (dpyinfo, parms)
+x_create_tip_frame (dpyinfo, parms, text)
      struct x_display_info *dpyinfo;
-     Lisp_Object parms;
+     Lisp_Object parms, text;
 {
   struct frame *f;
   Lisp_Object frame, tem;
@@ -10436,6 +10589,8 @@ x_create_tip_frame (dpyinfo, parms)
   struct gcpro gcpro1, gcpro2, gcpro3;
   struct kboard *kb;
   int face_change_count_before = face_change_count;
+  Lisp_Object buffer;
+  struct buffer *old_buffer;
 
   check_x ();
 
@@ -10461,6 +10616,16 @@ x_create_tip_frame (dpyinfo, parms)
   GCPRO3 (parms, name, frame);
   f = make_frame (1);
   XSETFRAME (frame, f);
+
+  buffer = Fget_buffer_create (build_string (" *tip*"));
+  Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer);
+  old_buffer = current_buffer;
+  set_buffer_internal_1 (XBUFFER (buffer));
+  current_buffer->truncate_lines = Qnil;
+  Ferase_buffer ();
+  Finsert (1, &text);
+  set_buffer_internal_1 (old_buffer);
+  
   FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
   record_unwind_protect (unwind_create_tip_frame, frame);
 
@@ -10475,6 +10640,10 @@ x_create_tip_frame (dpyinfo, parms)
   f->output_data.x->fontset = -1;
   f->output_data.x->scroll_bar_foreground_pixel = -1;
   f->output_data.x->scroll_bar_background_pixel = -1;
+#ifdef USE_TOOLKIT_SCROLL_BARS
+  f->output_data.x->scroll_bar_top_shadow_pixel = -1;
+  f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
+#endif /* USE_TOOLKIT_SCROLL_BARS */
   f->icon_name = Qnil;
   FRAME_X_DISPLAY_INFO (f) = dpyinfo;
 #if GLYPH_DEBUG
@@ -10720,13 +10889,15 @@ x_create_tip_frame (dpyinfo, parms)
 
 /* Compute where to display tip frame F.  PARMS is the list of frame
    parameters for F.  DX and DY are specified offsets from the current
-   location of the mouse.  Return coordinates relative to the root
-   window of the display in *ROOT_X, and *ROOT_Y.  */
+   location of the mouse.  WIDTH and HEIGHT are the width and height
+   of the tooltip.  Return coordinates relative to the root window of
+   the display in *ROOT_X, and *ROOT_Y.  */
 
 static void
-compute_tip_xy (f, parms, dx, dy, root_x, root_y)
+compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
      struct frame *f;
      Lisp_Object parms, dx, dy;
+     int width, height;
      int *root_x, *root_y;
 {
   Lisp_Object left, top;
@@ -10740,46 +10911,61 @@ compute_tip_xy (f, parms, dx, dy, root_x, root_y)
   
   /* Move the tooltip window where the mouse pointer is.  Resize and
      show it.  */
-  BLOCK_INPUT;
-  XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
-                &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
-  UNBLOCK_INPUT;
+  if (!INTEGERP (left) && !INTEGERP (top))
+    {
+      BLOCK_INPUT;
+      XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
+                    &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
+      UNBLOCK_INPUT;
+    }
 
-  *root_x += XINT (dx);
-  *root_y += XINT (dy);
-  
-  if (INTEGERP (left))
-    *root_x = XINT (left);
   if (INTEGERP (top))
     *root_y = XINT (top);
+  else if (*root_y + XINT (dy) - height < 0)
+    *root_y -= XINT (dy);
+  else
+    {
+      *root_y -= height;
+      *root_y += XINT (dy);
+    }
+
+  if (INTEGERP (left))
+    *root_x = XINT (left);
+  else if (*root_x + XINT (dx) + width > FRAME_X_DISPLAY_INFO (f)->width)
+    *root_x -= width + XINT (dx);
+  else
+    *root_x += XINT (dx);
 }
 
 
 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
-  "Show STRING in a \"tooltip\" window on frame FRAME.\n\
-A tooltip window is a small X window displaying a string.\n\
-\n\
-FRAME nil or omitted means use the selected frame.\n\
-\n\
-PARMS is an optional list of frame parameters which can be\n\
-used to change the tooltip's appearance.\n\
-\n\
-Automatically hide the tooltip after TIMEOUT seconds.\n\
-TIMEOUT nil means use the default timeout of 5 seconds.\n\
-\n\
-If the list of frame parameters PARAMS contains a `left' parameters,\n\
-the tooltip is displayed at that x-position.  Otherwise it is\n\
-displayed at the mouse position, with offset DX added (default is 5 if\n\
-DX isn't specified).  Likewise for the y-position; if a `top' frame\n\
-parameter is specified, it determines the y-position of the tooltip\n\
-window, otherwise it is displayed at the mouse position, with offset\n\
-DY added (default is -10).")
-  (string, frame, parms, timeout, dx, dy)
+       doc: /* Show STRING in a "tooltip" window on frame FRAME.
+A tooltip window is a small X window displaying a string.
+
+FRAME nil or omitted means use the selected frame.
+
+PARMS is an optional list of frame parameters which can be used to
+change the tooltip's appearance.
+
+Automatically hide the tooltip after TIMEOUT seconds.  TIMEOUT nil
+means use the default timeout of 5 seconds.
+
+If the list of frame parameters PARAMS contains a `left' parameters,
+the tooltip is displayed at that x-position.  Otherwise it is
+displayed at the mouse position, with offset DX added (default is 5 if
+DX isn't specified).  Likewise for the y-position; if a `top' frame
+parameter is specified, it determines the y-position of the tooltip
+window, otherwise it is displayed at the mouse position, with offset
+DY added (default is -10).
+
+A tooltip's maximum size is specified by `x-max-tooltip-size'.
+Text larger than the specified size is clipped.  */)
+     (string, frame, parms, timeout, dx, dy)
      Lisp_Object string, frame, parms, timeout, dx, dy;
 {
   struct frame *f;
   struct window *w;
-  Lisp_Object buffer, top, left;
+  Lisp_Object buffer, top, left, max_width, max_height;
   int root_x, root_y;
   struct buffer *old_buffer;
   struct text_pos pos;
@@ -10833,9 +11019,10 @@ DY added (default is -10).")
            }
 
          BLOCK_INPUT;
-         compute_tip_xy (f, parms, dx, dy, &root_x, &root_y);
+         compute_tip_xy (f, parms, dx, dy, PIXEL_WIDTH (f),
+                         PIXEL_HEIGHT (f), &root_x, &root_y);
          XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                      root_x, root_y - PIXEL_HEIGHT (f));
+                      root_x, root_y);
          UNBLOCK_INPUT;
          goto start_timer;
        }
@@ -10863,26 +11050,36 @@ DY added (default is -10).")
 
   /* Create a frame for the tooltip, and record it in the global
      variable tip_frame.  */
-  frame = x_create_tip_frame (FRAME_X_DISPLAY_INFO (f), parms);
+  frame = x_create_tip_frame (FRAME_X_DISPLAY_INFO (f), parms, string);
   f = XFRAME (frame);
 
-  /* Set up the frame's root window.  Currently we use a size of 80
-     columns x 40 lines.  If someone wants to show a larger tip, he
-     will loose.  I don't think this is a realistic case.  */
+  /* Set up the frame's root window.  */
   w = XWINDOW (FRAME_ROOT_WINDOW (f));
   w->left = w->top = make_number (0);
-  w->width = make_number (80);
-  w->height = make_number (40);
+  
+  if (CONSP (Vx_max_tooltip_size)
+      && INTEGERP (XCAR (Vx_max_tooltip_size))
+      && XINT (XCAR (Vx_max_tooltip_size)) > 0
+      && INTEGERP (XCDR (Vx_max_tooltip_size))
+      && XINT (XCDR (Vx_max_tooltip_size)) > 0)
+    {
+      w->width = XCAR (Vx_max_tooltip_size);
+      w->height = XCDR (Vx_max_tooltip_size);
+    }
+  else
+    {
+      w->width = make_number (80);
+      w->height = make_number (40);
+    }
+  
+  f->window_width = XINT (w->width);
   adjust_glyphs (f);
   w->pseudo_window_p = 1;
 
   /* Display the tooltip text in a temporary buffer.  */
-  buffer = Fget_buffer_create (build_string (" *tip*"));
-  Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer);
   old_buffer = current_buffer;
-  set_buffer_internal_1 (XBUFFER (buffer));
-  Ferase_buffer ();
-  Finsert (1, &string);
+  set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
+  current_buffer->truncate_lines = Qnil;
   clear_glyph_matrix (w->desired_matrix);
   clear_glyph_matrix (w->current_matrix);
   SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
@@ -10924,11 +11121,11 @@ DY added (default is -10).")
 
   /* Move the tooltip window where the mouse pointer is.  Resize and
      show it.  */
-  compute_tip_xy (f, parms, dx, dy, &root_x, &root_y);
+  compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
 
   BLOCK_INPUT;
   XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                    root_x, root_y - height, width, height);
+                    root_x, root_y, width, height);
   XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
   UNBLOCK_INPUT;
   
@@ -10951,9 +11148,9 @@ DY added (default is -10).")
 
 
 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
-  "Hide the current tooltip window, if there is any.\n\
-Value is t is tooltip was open, nil otherwise.")
-  ()
+       doc: /* Hide the current tooltip window, if there is any.
+Value is t if tooltip was open, nil otherwise.  */)
+     ()
 {
   int count;
   Lisp_Object deleted, frame, timer;
@@ -10988,7 +11185,7 @@ Value is t is tooltip was open, nil otherwise.")
        struct frame *f = SELECTED_FRAME ();
        Widget w = f->output_data.x->menubar_widget;
        extern void xlwmenu_redisplay P_ ((Widget));
-       
+
        if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f)->screen)
            && w != NULL)
          {
@@ -11025,13 +11222,28 @@ file_dialog_cb (widget, client_data, call_data)
 }
 
 
+/* Callback for unmapping a file selection dialog.  This is used to
+   capture the case where a dialog is closed via a window manager's
+   closer button, for example. Using a XmNdestroyCallback didn't work
+   in this case.  */
+
+static void
+file_dialog_unmap_cb (widget, client_data, call_data)
+     Widget widget;
+     XtPointer call_data, client_data;
+{
+  int *result = (int *) client_data;
+  *result = XmCR_CANCEL;
+}
+
+
 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0,
-  "Read file name, prompting with PROMPT in directory DIR.\n\
-Use a file selection dialog.\n\
-Select DEFAULT-FILENAME in the dialog's file selection box, if\n\
-specified.  Don't let the user enter a file name in the file\n\
-selection dialog's entry field, if MUSTMATCH is non-nil.")
-  (prompt, dir, default_filename, mustmatch)
+       doc: /* Read file name, prompting with PROMPT in directory DIR.
+Use a file selection dialog.
+Select DEFAULT-FILENAME in the dialog's file selection box, if
+specified.  Don't let the user enter a file name in the file
+selection dialog's entry field, if MUSTMATCH is non-nil.  */)
+     (prompt, dir, default_filename, mustmatch)
      Lisp_Object prompt, dir, default_filename, mustmatch;
 {
   int result;
@@ -11041,9 +11253,7 @@ selection dialog's entry field, if MUSTMATCH is non-nil.")
   Arg al[10];
   int ac = 0;
   extern XtAppContext Xt_app_con;
-  char *title;
   XmString dir_xmstring, pattern_xmstring;
-  int popup_activated_flag;
   int count = specpdl_ptr - specpdl;
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
 
@@ -11077,6 +11287,8 @@ selection dialog's entry field, if MUSTMATCH is non-nil.")
                 (XtPointer) &result);
   XtAddCallback (dialog, XmNcancelCallback, file_dialog_cb,
                 (XtPointer) &result);
+  XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb,
+                (XtPointer) &result);
 
   /* Disable the help button since we can't display help.  */
   help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
@@ -11128,10 +11340,18 @@ selection dialog's entry field, if MUSTMATCH is non-nil.")
       XmListSetPos (list, item_pos);
     }
 
-  /* Process events until the user presses Cancel or OK.  */
+  /* Process events until the user presses Cancel or OK.  Block
+     and unblock input here so that we get a chance of processing
+     expose events.  */
+  UNBLOCK_INPUT;
   result = 0;
-  while (result == 0 || XtAppPending (Xt_app_con))
-    XtAppProcessEvent (Xt_app_con, XtIMAll);
+  while (result == 0)
+    {
+      BLOCK_INPUT;
+      XtAppProcessEvent (Xt_app_con, XtIMAll);
+      UNBLOCK_INPUT;
+    }
+  BLOCK_INPUT;
 
   /* Get the result.  */
   if (result == XmCR_OK)
@@ -11176,11 +11396,11 @@ selection dialog's entry field, if MUSTMATCH is non-nil.")
 
 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
        Sx_backspace_delete_keys_p, 0, 1, 0,
-  "Check if both Backspace and Delete keys are on the keyboard of FRAME.\n\
-FRAME nil means use the selected frame.\n\
-Value is t if we know that both keys are present, and are mapped to the\n\
-usual X keysyms.")
-  (frame)
+       doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
+FRAME nil means use the selected frame.
+Value is t if we know that both keys are present, and are mapped to the
+usual X keysyms.  */)
+     (frame)
      Lisp_Object frame;
 {
 #ifdef HAVE_XKBGETKEYBOARD
@@ -11223,8 +11443,9 @@ usual X keysyms.")
                && (delete_keycode == 0 || backspace_keycode == 0));
               ++i)
            {
-             /* The XKB symbolic key names can be seen most easily
-                in the PS file generated by `xkbprint -label name $DISPLAY'.  */
+             /* The XKB symbolic key names can be seen most easily in
+                the PS file generated by `xkbprint -label name
+                $DISPLAY'.  */
              if (bcmp ("DELE", kb->names->keys[i].name, 4) == 0)
                delete_keycode = i;
              else if (bcmp ("BKSP", kb->names->keys[i].name, 4) == 0)
@@ -11338,6 +11559,8 @@ syms_of_xfns ()
   staticpro (&Qcompound_text);
   Qcancel_timer = intern ("cancel-timer");
   staticpro (&Qcancel_timer);
+  Qwait_for_wm = intern ("wait-for-wm");
+  staticpro (&Qwait_for_wm);
   /* This is the end of symbol initialization.  */
 
   /* Text property `display' should be nonsticky by default.  */
@@ -11371,124 +11594,134 @@ syms_of_xfns ()
   init_x_parm_symbols ();
 
   DEFVAR_BOOL ("cross-disabled-images", &cross_disabled_images,
-    "Non-nil means always draw a cross over disabled images.\n\
-Disabled images are those having an `:conversion disabled' property.\n\
-A cross is always drawn on black & white displays.");
+    doc: /* Non-nil means always draw a cross over disabled images.
+Disabled images are those having an `:conversion disabled' property.
+A cross is always drawn on black & white displays.  */);
   cross_disabled_images = 0;
 
   DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,
-    "List of directories to search for bitmap files for X.");
+    doc: /* List of directories to search for bitmap files for X.  */);
   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\
-Changing the value does not affect existing frames\n\
-unless you set the mouse color.");
+    doc: /* The shape of the pointer when over text.
+Changing the value does not affect existing frames
+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.\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.\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'.");
+    doc: /* The name Emacs uses to look up X resources.
+`x-get-resource' uses this as the first component of the instance name
+when requesting resource values.
+Emacs initially sets `x-resource-name' to the name under which Emacs
+was invoked, or to the value specified with the `-name' or `-rn'
+switches, if present.
+
+It may be useful to bind this variable locally around a call
+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 reasonable practice.  See also the variable `x-resource-name'.");
+    doc: /* The class Emacs uses to look up X resources.
+`x-get-resource' uses this as the first component of the instance class
+when requesting resource values.
+
+Emacs initially sets `x-resource-class' to "Emacs".
+
+Setting this variable permanently is not a reasonable thing to do,
+but binding this variable locally around a call to `x-get-resource'
+is a reasonable practice.  See also the variable `x-resource-name'.  */);
   Vx_resource_class = build_string (EMACS_CLASS);
 
 #if 0 /* This doesn't really do anything.  */
   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.");
+    doc: /* The shape of the pointer when not over text.
+This variable takes effect when you create a new frame
+or when you set the mouse color.  */);
 #endif
   Vx_nontext_pointer_shape = Qnil;
 
   DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape,
-    "The shape of the pointer when Emacs is busy.\n\
-This variable takes effect when you create a new frame\n\
-or when you set the mouse color.");
+    doc: /* The shape of the pointer when Emacs is busy.
+This variable takes effect when you create a new frame
+or when you set the mouse color.  */);
   Vx_hourglass_pointer_shape = Qnil;
 
   DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
-    "Non-zero means Emacs displays an hourglass pointer on window systems.");
+    doc: /* Non-zero means Emacs displays an hourglass pointer on window systems.  */);
   display_hourglass_p = 1;
   
   DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
-     "*Seconds to wait before displaying an hourglass pointer.\n\
-Value must be an integer or float.");
+    doc: /* *Seconds to wait before displaying an hourglass pointer.
+Value must be an integer or float.  */);
   Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
 
 #if 0 /* This doesn't really do anything.  */
   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.");
+    doc: /* The shape of the pointer when over the mode line.
+This variable takes effect when you create a new frame
+or when you set the mouse color.  */);
 #endif
   Vx_mode_pointer_shape = Qnil;
 
   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\
-or when you set the mouse color.");
+              doc: /* The shape of the pointer when over mouse-sensitive text.
+This variable takes effect when you create a new frame
+or when you set the mouse color.  */);
   Vx_sensitive_text_pointer_shape = Qnil;
 
   DEFVAR_LISP ("x-window-horizontal-drag-cursor",
              &Vx_window_horizontal_drag_shape,
-  "Pointer shape to use for indicating a window can be dragged horizontally.\n\
-This variable takes effect when you create a new frame\n\
-or when you set the mouse color.");
+  doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
+This variable takes effect when you create a new frame
+or when you set the mouse color.  */);
   Vx_window_horizontal_drag_shape = Qnil;
 
   DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
-              "A string indicating the foreground color of the cursor box.");
+    doc: /* A string indicating the foreground color of the cursor box.  */);
   Vx_cursor_fore_pixel = Qnil;
 
+  DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
+    doc: /* Maximum size for tooltips.  Value is a pair (COLUMNS . ROWS).
+Text larger than this is clipped.  */);
+  Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
+  
   DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
-              "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.");
+    doc: /* Non-nil if no X window manager is in use.
+Emacs doesn't try to figure this out; this is always nil
+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.");
+    doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
+
+Since Emacs gets width of a font matching with this regexp from
+PIXEL_SIZE field of the name, font finding mechanism gets faster for
+such a font.  This is especially effective for such large fonts as
+Chinese, Japanese, and Korean.  */);
   Vx_pixel_size_width_font_regexp = Qnil;
 
   DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay,
-     "Time after which cached images are removed from the cache.\n\
-When an image has not been displayed this many seconds, remove it\n\
-from the image cache.  Value must be an integer or nil with nil\n\
-meaning don't clear the cache.");
+    doc: /* Time after which cached images are removed from the cache.
+When an image has not been displayed this many seconds, remove it
+from the image cache.  Value must be an integer or nil with nil
+meaning don't clear the cache.  */);
   Vimage_cache_eviction_delay = make_number (30 * 60);
 
 #ifdef USE_X_TOOLKIT
-  Fprovide (intern ("x-toolkit"));
-#endif
+  Fprovide (intern ("x-toolkit"), Qnil);
 #ifdef USE_MOTIF
-  Fprovide (intern ("motif"));
-#endif
+  Fprovide (intern ("motif"), Qnil);
+
+  DEFVAR_LISP ("motif-version-string", &Vmotif_version_string,
+              doc: /* Version info for LessTif/Motif.  */);
+  Vmotif_version_string = build_string (XmVERSION_STRING);
+#endif /* USE_MOTIF */
+#endif /* USE_X_TOOLKIT */
 
   defsubr (&Sx_get_resource);