*** empty log message ***
[bpt/emacs.git] / src / xfns.c
index 6c4b68c..1f22f00 100644 (file)
@@ -19,13 +19,15 @@ along with GNU Emacs; see the file COPYING.  If not, write to
 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
-#define DOC_STRINGS_IN_COMMENTS
-
 #include <config.h>
 #include <signal.h>
 #include <stdio.h>
 #include <math.h>
 
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
 /* This makes the fields of a Display accessible, in Xlib header files.  */
 
 #define XLIB_ILLEGAL_ACCESS
@@ -217,6 +219,10 @@ 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;
+Lisp_Object Qfullscreen;
+Lisp_Object Qfullwidth;
+Lisp_Object Qfullheight;
+Lisp_Object Qfullboth;
 
 /* The below are defined in frame.c.  */
 
@@ -263,7 +269,7 @@ check_x_frame (frame)
 
   if (NILP (frame))
     frame = selected_frame;
-  CHECK_LIVE_FRAME (frame, 0);
+  CHECK_LIVE_FRAME (frame);
   f = XFRAME (frame);
   if (! FRAME_X_P (f))
     error ("Non-X frame used");
@@ -297,7 +303,7 @@ check_x_display_info (frame)
     {
       FRAME_PTR f;
 
-      CHECK_LIVE_FRAME (frame, 0);
+      CHECK_LIVE_FRAME (frame);
       f = XFRAME (frame);
       if (! FRAME_X_P (f))
        error ("Non-X frame used");
@@ -731,6 +737,7 @@ static void x_disable_image P_ ((struct frame *, struct image *));
 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));
+static void x_set_fullscreen 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));
@@ -738,6 +745,7 @@ void x_set_border_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
+static void x_set_fringe_width P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_font P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_border_width P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_internal_border_width P_ ((struct frame *, Lisp_Object,
@@ -775,32 +783,36 @@ static unsigned long lookup_pixel_color P_ ((struct frame *f, unsigned long p));
 
 static struct x_frame_parm_table x_frame_parms[] =
 {
-  "auto-raise",                        x_set_autoraise,
-  "auto-lower",                        x_set_autolower,
-  "background-color",          x_set_background_color,
-  "border-color",              x_set_border_color,
-  "border-width",              x_set_border_width,
-  "cursor-color",              x_set_cursor_color,
-  "cursor-type",               x_set_cursor_type,
-  "font",                      x_set_font,
-  "foreground-color",          x_set_foreground_color,
-  "icon-name",                 x_set_icon_name,
-  "icon-type",                 x_set_icon_type,
-  "internal-border-width",     x_set_internal_border_width,
-  "menu-bar-lines",            x_set_menu_bar_lines,
-  "mouse-color",               x_set_mouse_color,
-  "name",                      x_explicitly_set_name,
-  "scroll-bar-width",          x_set_scroll_bar_width,
-  "title",                     x_set_title,
-  "unsplittable",              x_set_unsplittable,
-  "vertical-scroll-bars",      x_set_vertical_scroll_bars,
-  "visibility",                        x_set_visibility,
-  "tool-bar-lines",            x_set_tool_bar_lines,
-  "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,
-  "wait-for-wm",               x_set_wait_for_wm
+  {"auto-raise",               x_set_autoraise},
+  {"auto-lower",               x_set_autolower},
+  {"background-color",         x_set_background_color},
+  {"border-color",             x_set_border_color},
+  {"border-width",             x_set_border_width},
+  {"cursor-color",             x_set_cursor_color},
+  {"cursor-type",              x_set_cursor_type},
+  {"font",                     x_set_font},
+  {"foreground-color",         x_set_foreground_color},
+  {"icon-name",                        x_set_icon_name},
+  {"icon-type",                        x_set_icon_type},
+  {"internal-border-width",    x_set_internal_border_width},
+  {"menu-bar-lines",           x_set_menu_bar_lines},
+  {"mouse-color",              x_set_mouse_color},
+  {"name",                     x_explicitly_set_name},
+  {"scroll-bar-width",         x_set_scroll_bar_width},
+  {"title",                    x_set_title},
+  {"unsplittable",             x_set_unsplittable},
+  {"vertical-scroll-bars",     x_set_vertical_scroll_bars},
+  {"visibility",               x_set_visibility},
+  {"tool-bar-lines",           x_set_tool_bar_lines},
+  {"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},
+  {"left-fringe",              x_set_fringe_width},
+  {"right-fringe",             x_set_fringe_width},
+  {"wait-for-wm",              x_set_wait_for_wm},
+  {"fullscreen",                x_set_fullscreen},
+  
 };
 
 /* Attach the `x-frame-parameter' properties to
@@ -816,6 +828,28 @@ init_x_parm_symbols ()
          make_number (i));
 }
 \f
+
+/* Really try to move where we want to be in case of fullscreen.  Some WMs
+   moves the window where we tell them.  Some (mwm, twm) moves the outer
+   window manager window there instead.
+   Try to compensate for those WM here. */
+static void
+x_fullscreen_move (f, new_top, new_left)
+     struct frame *f;
+     int new_top;
+     int new_left;
+{
+  if (new_top != f->output_data.x->top_pos
+      || new_left != f->output_data.x->left_pos)
+    {
+      int move_x = new_left + f->output_data.x->x_pixels_outer_diff;
+      int move_y = new_top + f->output_data.x->y_pixels_outer_diff;
+
+      f->output_data.x->want_fullscreen |= FULLSCREEN_MOVE_WAIT;
+      x_set_offset (f, move_x, move_y, 1);
+    }
+}
+
 /* Change the parameters of frame F as specified by ALIST.
    If a parameter is not specially recognized, do nothing special;
    otherwise call the `x_set_...' function for that parameter.
@@ -846,6 +880,7 @@ x_set_frame_parameters (f, alist)
   int i, p;
   int left_no_change = 0, top_no_change = 0;
   int icon_left_no_change = 0, icon_top_no_change = 0;
+  int fullscreen_is_being_set = 0;
 
   struct gcpro gcpro1, gcpro2;
 
@@ -894,23 +929,34 @@ x_set_frame_parameters (f, alist)
   /* Process foreground_color and background_color before anything else.
      They are independent of other properties, but other properties (e.g.,
      cursor_color) are dependent upon them.  */
+  /* Process default font as well, since fringe widths depends on it.  */
+  /* Also, process fullscreen, width and height depend upon that */
   for (p = 0; p < i; p++) 
     {
       Lisp_Object prop, val;
 
       prop = parms[p];
       val = values[p];
-      if (EQ (prop, Qforeground_color) || EQ (prop, Qbackground_color))
+      if (EQ (prop, Qforeground_color)
+         || EQ (prop, Qbackground_color)
+         || EQ (prop, Qfont)
+          || EQ (prop, Qfullscreen))
        {
          register Lisp_Object param_index, old_value;
 
-         param_index = Fget (prop, Qx_frame_parameter);
          old_value = get_frame_param (f, prop);
-         store_frame_param (f, prop, val);
-         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);
+         fullscreen_is_being_set |= EQ (prop, Qfullscreen);
+         
+         if (NILP (Fequal (val, old_value)))
+           {
+             store_frame_param (f, prop, val);
+
+             param_index = Fget (prop, Qx_frame_parameter);
+             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);
+           }
        }
     }
 
@@ -934,17 +980,22 @@ x_set_frame_parameters (f, alist)
        icon_top = val;
       else if (EQ (prop, Qicon_left))
        icon_left = val;
-      else if (EQ (prop, Qforeground_color) || EQ (prop, Qbackground_color))
+      else if (EQ (prop, Qforeground_color)
+              || EQ (prop, Qbackground_color)
+              || EQ (prop, Qfont)
+               || EQ (prop, Qfullscreen))
        /* Processed above.  */
        continue;
       else
        {
          register Lisp_Object param_index, old_value;
 
-         param_index = Fget (prop, Qx_frame_parameter);
          old_value = get_frame_param (f, prop);
+
          store_frame_param (f, prop, val);
-         if (NATNUMP (param_index)
+
+         param_index = Fget (prop, Qx_frame_parameter);
+         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);
@@ -985,6 +1036,21 @@ x_set_frame_parameters (f, alist)
        XSETINT (icon_top, 0);
     }
 
+  if (FRAME_VISIBLE_P (f) && fullscreen_is_being_set)
+    {
+      /* If the frame is visible already and the fullscreen parameter is
+         being set, it is too late to set WM manager hints to specify
+         size and position.
+         Here we first get the width, height and position that applies to
+         fullscreen.  We then move the frame to the appropriate
+         position.  Resize of the frame is taken care of in the code after
+         this if-statement. */
+      int new_left, new_top;
+      
+      x_fullscreen_adjust (f, &width, &height, &new_top, &new_left);
+      x_fullscreen_move (f, new_top, new_left);
+    }
+  
   /* 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
@@ -1087,70 +1153,115 @@ x_real_positions (f, xptr, yptr)
      FRAME_PTR f;
      int *xptr, *yptr;
 {
-  int win_x, win_y;
-  Window child;
+  int win_x, win_y, outer_x, outer_y;
+  int real_x = 0, real_y = 0;
+  int had_errors = 0;
+  Window win = f->output_data.x->parent_desc;
 
-  /* This is pretty gross, but seems to be the easiest way out of
-     the problem that arises when restarting window-managers.  */
+  int count;
 
-#ifdef USE_X_TOOLKIT
-  Window outer = (f->output_data.x->widget
-                 ? XtWindow (f->output_data.x->widget)
-                 : FRAME_X_WINDOW (f));
-#else
-  Window outer = f->output_data.x->window_desc;
-#endif
-  Window tmp_root_window;
-  Window *tmp_children;
-  unsigned int tmp_nchildren;
+  BLOCK_INPUT;
+
+  count = x_catch_errors (FRAME_X_DISPLAY (f));
 
-  while (1)
+  if (win == FRAME_X_DISPLAY_INFO (f)->root_window)
+    win = FRAME_OUTER_WINDOW (f);
+
+  /* This loop traverses up the containment tree until we hit the root
+     window.  Window managers may intersect many windows between our window
+     and the root window.  The window we find just before the root window
+     should be the outer WM window. */
+  for (;;)
     {
-      int count = x_catch_errors (FRAME_X_DISPLAY (f));
-      Window outer_window;
+      Window wm_window, rootw;
+      Window *tmp_children;
+      unsigned int tmp_nchildren;
+      int success;
 
-      XQueryTree (FRAME_X_DISPLAY (f), outer, &tmp_root_window,
-                 &f->output_data.x->parent_desc,
-                 &tmp_children, &tmp_nchildren);
-      XFree ((char *) tmp_children);
+      success = XQueryTree (FRAME_X_DISPLAY (f), win, &rootw,
+                           &wm_window, &tmp_children, &tmp_nchildren);
 
-      win_x = win_y = 0;
+      had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
 
-      /* Find the position of the outside upper-left corner of
-        the inner window, with respect to the outer window.  */
-      if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
-       outer_window = f->output_data.x->parent_desc;
-      else
-       outer_window = outer;
+      /* Don't free tmp_children if XQueryTree failed.  */
+      if (! success)
+       break;
+
+      XFree ((char *) tmp_children);
 
+      if (wm_window == rootw || had_errors)
+        break;
+
+      win = wm_window;
+    }
+    
+  if (! had_errors)
+    {
+      int ign;
+      Window child, rootw;
+          
+      /* Get the real coordinates for the WM window upper left corner */
+      XGetGeometry (FRAME_X_DISPLAY (f), win,
+                    &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
+
+      /* Translate real coordinates to coordinates relative to our
+         window.  For our window, the upper left corner is 0, 0.
+         Since the upper left corner of the WM window is outside
+         our window, win_x and win_y will be negative:
+
+         ------------------          ---> x
+         |      title                |
+         | -----------------         v y
+         | |  our window
+      */
       XTranslateCoordinates (FRAME_X_DISPLAY (f),
 
                             /* From-window, to-window.  */
-                            outer_window,
                             FRAME_X_DISPLAY_INFO (f)->root_window,
+                             FRAME_X_WINDOW (f),
 
                             /* From-position, to-position.  */
-                            0, 0, &win_x, &win_y,
+                             real_x, real_y, &win_x, &win_y,
 
                             /* Child of win.  */
                             &child);
 
-      /* It is possible for the window returned by the XQueryNotify
-        to become invalid by the time we call XTranslateCoordinates.
-        That can happen when you restart some window managers.
-        If so, we get an error in XTranslateCoordinates.
-        Detect that and try the whole thing over.  */
-      if (! x_had_errors_p (FRAME_X_DISPLAY (f)))
+      if (FRAME_X_WINDOW (f) == FRAME_OUTER_WINDOW (f))
        {
-         x_uncatch_errors (FRAME_X_DISPLAY (f), count);
-         break;
+          outer_x = win_x;
+          outer_y = win_y;
        }
+      else
+        {
+          XTranslateCoordinates (FRAME_X_DISPLAY (f),
 
-      x_uncatch_errors (FRAME_X_DISPLAY (f), count);
+                                 /* From-window, to-window.  */
+                                 FRAME_X_DISPLAY_INFO (f)->root_window,
+                                 FRAME_OUTER_WINDOW (f),
+                                     
+                                 /* From-position, to-position.  */
+                                 real_x, real_y, &outer_x, &outer_y,
+                         
+                                 /* Child of win.  */
+                                 &child);
     }
 
-  *xptr = win_x;
-  *yptr = win_y;
+      had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
+    }
+      
+  x_uncatch_errors (FRAME_X_DISPLAY (f), count);
+      
+  UNBLOCK_INPUT;
+
+  if (had_errors) return;
+      
+  f->output_data.x->x_pixels_diff = -win_x;
+  f->output_data.x->y_pixels_diff = -win_y;
+  f->output_data.x->x_pixels_outer_diff = -outer_x;
+  f->output_data.x->y_pixels_outer_diff = -outer_y;
+
+  *xptr = real_x;
+  *yptr = real_y;
 }
 
 /* Insert a description of internally-recorded parameters of frame X
@@ -1185,6 +1296,14 @@ x_report_frame_params (f, alistptr)
                   make_number (f->output_data.x->border_width));
   store_in_alist (alistptr, Qinternal_border_width,
                   make_number (f->output_data.x->internal_border_width));
+  store_in_alist (alistptr, Qleft_fringe,
+                  make_number (f->output_data.x->left_fringe_width));
+  store_in_alist (alistptr, Qright_fringe,
+                  make_number (f->output_data.x->right_fringe_width));
+  store_in_alist (alistptr, Qscroll_bar_width,
+           make_number (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
+                        ? FRAME_SCROLL_BAR_PIXEL_WIDTH(f)
+                        : 0));
   sprintf (buf, "%ld", (long) FRAME_X_WINDOW (f));
   store_in_alist (alistptr, Qwindow_id,
                   build_string (buf));
@@ -1266,7 +1385,7 @@ x_decode_color (f, color_name, mono_color)
 {
   XColor cdef;
 
-  CHECK_STRING (color_name, 0);
+  CHECK_STRING (color_name);
 
 #if 0 /* Don't do this.  It's wrong when we're not using the default
         colormap, it makes freeing difficult, and it's probably not
@@ -1326,6 +1445,25 @@ x_set_wait_for_wm (f, new_value, old_value)
 }
 
 
+/* Change the `fullscreen' frame parameter of frame F.  OLD_VALUE is
+   the previous value of that parameter, NEW_VALUE is the new value. */
+
+static void
+x_set_fullscreen (f, new_value, old_value)
+     struct frame *f;
+     Lisp_Object new_value, old_value;
+{
+  if (NILP (new_value))
+    f->output_data.x->want_fullscreen = FULLSCREEN_NONE;
+  else if (EQ (new_value, Qfullboth))
+    f->output_data.x->want_fullscreen = FULLSCREEN_BOTH;
+  else if (EQ (new_value, Qfullwidth))
+    f->output_data.x->want_fullscreen = FULLSCREEN_WIDTH;
+  else if (EQ (new_value, Qfullheight))
+    f->output_data.x->want_fullscreen = FULLSCREEN_HEIGHT;
+}
+
+
 /* Change the `screen-gamma' frame parameter of frame F.  OLD_VALUE is
    the previous value of that parameter, NEW_VALUE is the new
    value.  */
@@ -1468,7 +1606,7 @@ x_set_mouse_color (f, arg, oldval)
 
   if (!NILP (Vx_pointer_shape))
     {
-      CHECK_NUMBER (Vx_pointer_shape, 0);
+      CHECK_NUMBER (Vx_pointer_shape);
       cursor = XCreateFontCursor (dpy, XINT (Vx_pointer_shape));
     }
   else
@@ -1477,7 +1615,7 @@ x_set_mouse_color (f, arg, oldval)
 
   if (!NILP (Vx_nontext_pointer_shape))
     {
-      CHECK_NUMBER (Vx_nontext_pointer_shape, 0);
+      CHECK_NUMBER (Vx_nontext_pointer_shape);
       nontext_cursor
        = XCreateFontCursor (dpy, XINT (Vx_nontext_pointer_shape));
     }
@@ -1487,7 +1625,7 @@ x_set_mouse_color (f, arg, oldval)
 
   if (!NILP (Vx_hourglass_pointer_shape))
     {
-      CHECK_NUMBER (Vx_hourglass_pointer_shape, 0);
+      CHECK_NUMBER (Vx_hourglass_pointer_shape);
       hourglass_cursor
        = XCreateFontCursor (dpy, XINT (Vx_hourglass_pointer_shape));
     }
@@ -1498,7 +1636,7 @@ x_set_mouse_color (f, arg, oldval)
   x_check_errors (dpy, "bad nontext pointer cursor: %s");
   if (!NILP (Vx_mode_pointer_shape))
     {
-      CHECK_NUMBER (Vx_mode_pointer_shape, 0);
+      CHECK_NUMBER (Vx_mode_pointer_shape);
       mode_cursor = XCreateFontCursor (dpy, XINT (Vx_mode_pointer_shape));
     }
   else
@@ -1507,7 +1645,7 @@ x_set_mouse_color (f, arg, oldval)
 
   if (!NILP (Vx_sensitive_text_pointer_shape))
     {
-      CHECK_NUMBER (Vx_sensitive_text_pointer_shape, 0);
+      CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
       cross_cursor
        = XCreateFontCursor (dpy, XINT (Vx_sensitive_text_pointer_shape));
     }
@@ -1516,7 +1654,7 @@ x_set_mouse_color (f, arg, oldval)
 
   if (!NILP (Vx_window_horizontal_drag_shape))
     {
-      CHECK_NUMBER (Vx_window_horizontal_drag_shape, 0);
+      CHECK_NUMBER (Vx_window_horizontal_drag_shape);
       horizontal_drag_cursor
        = XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape));
     }
@@ -1670,7 +1808,7 @@ x_set_border_color (f, arg, oldval)
 {
   int pix;
 
-  CHECK_STRING (arg, 0);
+  CHECK_STRING (arg);
   pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
   x_set_border_pixel (f, pix);
   update_face_from_frame_parameter (f, Qborder_color, arg);
@@ -1746,9 +1884,8 @@ x_set_cursor_type (f, arg, oldval)
   FRAME_DESIRED_CURSOR (f) = x_specified_cursor_type (arg, &width);
   f->output_data.x->cursor_width = width;
 
-  /* Make sure the cursor gets redrawn.  This is overkill, but how
-     often do people change cursor types?  */
-  update_mode_lines++;
+  /* Make sure the cursor gets redrawn.  */
+  cursor_type_changed = 1;
 }
 \f
 void
@@ -1849,7 +1986,7 @@ x_set_font (f, arg, oldval)
   Lisp_Object frame;
   int old_fontset = f->output_data.x->fontset;
 
-  CHECK_STRING (arg, 1);
+  CHECK_STRING (arg);
 
   fontset_name = Fquery_fontset (arg, Qnil);
 
@@ -1895,12 +2032,20 @@ x_set_font (f, arg, oldval)
     }
 }
 
+static void
+x_set_fringe_width (f, new_value, old_value)
+     struct frame *f;
+     Lisp_Object new_value, old_value;
+{
+  x_compute_fringe_widths (f, 1);
+}
+
 void
 x_set_border_width (f, arg, oldval)
      struct frame *f;
      Lisp_Object arg, oldval;
 {
-  CHECK_NUMBER (arg, 0);
+  CHECK_NUMBER (arg);
 
   if (XINT (arg) == f->output_data.x->border_width)
     return;
@@ -1918,7 +2063,7 @@ x_set_internal_border_width (f, arg, oldval)
 {
   int old = f->output_data.x->internal_border_width;
 
-  CHECK_NUMBER (arg, 0);
+  CHECK_NUMBER (arg);
   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;
@@ -1937,6 +2082,8 @@ x_set_internal_border_width (f, arg, oldval)
       SET_FRAME_GARBAGED (f);
       do_pending_window_change (0);
     }
+  else
+    SET_FRAME_GARBAGED (f);
 }
 
 void
@@ -2203,6 +2350,10 @@ x_set_scroll_bar_background (f, value, oldval)
    CODING_SYSTEM, and return a newly allocated memory area which
    should be freed by `xfree' by a caller.
 
+   SELECTIONP non-zero means the string is being encoded for an X
+   selection, so it is safe to run pre-write conversions (which
+   may run Lisp code).
+
    Store the byte length of resulting text in *TEXT_BYTES.
 
    If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
@@ -2211,9 +2362,10 @@ x_set_scroll_bar_background (f, value, oldval)
    the result should be `COMPOUND_TEXT'.  */
 
 unsigned char *
-x_encode_text (string, coding_system, text_bytes, stringp)
+x_encode_text (string, coding_system, selectionp, text_bytes, stringp)
      Lisp_Object string, coding_system;
      int *text_bytes, *stringp;
+     int selectionp;
 {
   unsigned char *str = XSTRING (string)->data;
   int chars = XSTRING (string)->size;
@@ -2233,6 +2385,15 @@ x_encode_text (string, coding_system, text_bytes, stringp)
     }
 
   setup_coding_system (coding_system, &coding);
+  if (selectionp
+      && SYMBOLP (coding.pre_write_conversion)
+      && !NILP (Ffboundp (coding.pre_write_conversion)))
+    {
+      string = run_pre_post_conversion_on_str (string, &coding, 1);
+      str = XSTRING (string)->data;
+      chars = XSTRING (string)->size;
+      bytes = STRING_BYTES (XSTRING (string));
+    }
   coding.src_multibyte = 1;
   coding.dst_multibyte = 0;
   coding.mode |= CODING_MODE_LAST_BLOCK;
@@ -2291,7 +2452,7 @@ x_set_name (f, name, explicit)
       name = build_string (FRAME_X_DISPLAY_INFO (f)->x_id_name);
     }
   else
-    CHECK_STRING (name, 0);
+    CHECK_STRING (name);
 
   /* Don't change the name if it's already NAME.  */
   if (! NILP (Fstring_equal (name, f->name)))
@@ -2316,7 +2477,7 @@ x_set_name (f, name, explicit)
        coding_system = Vlocale_coding_system;
        if (NILP (coding_system))
          coding_system = Qcompound_text;
-       text.value = x_encode_text (name, coding_system, &bytes, &stringp);
+       text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp);
        text.encoding = (stringp ? XA_STRING
                         : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
        text.format = 8;
@@ -2328,7 +2489,7 @@ x_set_name (f, name, explicit)
          }
        else
          {
-           icon.value = x_encode_text (f->icon_name, coding_system,
+           icon.value = x_encode_text (f->icon_name, coding_system, 0,
                                        &bytes, &stringp);
            icon.encoding = (stringp ? XA_STRING
                             : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
@@ -2409,7 +2570,7 @@ x_set_title (f, name, old_name)
   if (NILP (name))
     name = f->name;
   else
-    CHECK_STRING (name, 0);
+    CHECK_STRING (name);
 
   if (FRAME_X_WINDOW (f))
     {
@@ -2423,7 +2584,7 @@ x_set_title (f, name, old_name)
        coding_system = Vlocale_coding_system;
        if (NILP (coding_system))
          coding_system = Qcompound_text;
-       text.value = x_encode_text (name, coding_system, &bytes, &stringp);
+       text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp);
        text.encoding = (stringp ? XA_STRING
                         : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
        text.format = 8;
@@ -2435,7 +2596,7 @@ x_set_title (f, name, old_name)
          }
        else
          {
-           icon.value = x_encode_text (f->icon_name, coding_system,
+           icon.value = x_encode_text (f->icon_name, coding_system, 0,
                                        &bytes, &stringp);
            icon.encoding = (stringp ? XA_STRING
                             : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
@@ -2641,7 +2802,7 @@ 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.
+       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.
@@ -2649,8 +2810,8 @@ 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))
+and the class is `Emacs.CLASS.SUBCLASS'.  */)
+     (attribute, class, component, subclass)
      Lisp_Object attribute, class, component, subclass;
 {
   register char *value;
@@ -2659,13 +2820,13 @@ and the class is `Emacs.CLASS.SUBCLASS'.  */
 
   check_x ();
 
-  CHECK_STRING (attribute, 0);
-  CHECK_STRING (class, 0);
+  CHECK_STRING (attribute);
+  CHECK_STRING (class);
 
   if (!NILP (component))
-    CHECK_STRING (component, 1);
+    CHECK_STRING (component);
   if (!NILP (subclass))
-    CHECK_STRING (subclass, 2);
+    CHECK_STRING (subclass);
   if (NILP (component) != NILP (subclass))
     error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
 
@@ -2725,13 +2886,13 @@ display_x_get_resource (dpyinfo, attribute, class, component, subclass)
   char *name_key;
   char *class_key;
 
-  CHECK_STRING (attribute, 0);
-  CHECK_STRING (class, 0);
+  CHECK_STRING (attribute);
+  CHECK_STRING (class);
 
   if (!NILP (component))
-    CHECK_STRING (component, 1);
+    CHECK_STRING (component);
   if (!NILP (subclass))
-    CHECK_STRING (subclass, 2);
+    CHECK_STRING (subclass);
   if (NILP (component) != NILP (subclass))
     error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
 
@@ -2999,20 +3160,20 @@ 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.
+       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))
+or a list (- N) meaning -N pixels relative to bottom/right corner.  */)
+     (string)
      Lisp_Object string;
 {
   int geometry, x, y;
   unsigned int width, height;
   Lisp_Object result;
 
-  CHECK_STRING (string, 0);
+  CHECK_STRING (string);
 
   geometry = XParseGeometry ((char *) XSTRING (string)->data,
                             &x, &y, &width, &height);
@@ -3091,12 +3252,12 @@ x_figure_window_size (f, parms)
     {
       if (!EQ (tem0, Qunbound))
        {
-         CHECK_NUMBER (tem0, 0);
+         CHECK_NUMBER (tem0);
          f->height = XINT (tem0);
        }
       if (!EQ (tem1, Qunbound))
        {
-         CHECK_NUMBER (tem1, 0);
+         CHECK_NUMBER (tem1);
          SET_FRAME_WIDTH (f, XINT (tem1));
        }
       if (!NILP (tem2) && !EQ (tem2, Qunbound))
@@ -3109,8 +3270,9 @@ x_figure_window_size (f, parms)
     = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
        ? 0
        : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.x->font)));
-  f->output_data.x->flags_areas_extra
-    = FRAME_FLAGS_AREA_WIDTH (f);
+
+  x_compute_fringe_widths (f, 0);
+
   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);
 
@@ -3141,7 +3303,7 @@ x_figure_window_size (f, parms)
        f->output_data.x->top_pos = 0;
       else
        {
-         CHECK_NUMBER (tem0, 0);
+         CHECK_NUMBER (tem0);
          f->output_data.x->top_pos = XINT (tem0);
          if (f->output_data.x->top_pos < 0)
            window_prompting |= YNegative;
@@ -3169,7 +3331,7 @@ x_figure_window_size (f, parms)
        f->output_data.x->left_pos = 0;
       else
        {
-         CHECK_NUMBER (tem1, 0);
+         CHECK_NUMBER (tem1);
          f->output_data.x->left_pos = XINT (tem1);
          if (f->output_data.x->left_pos < 0)
            window_prompting |= XNegative;
@@ -3181,6 +3343,22 @@ x_figure_window_size (f, parms)
        window_prompting |= PPosition;
     }
 
+  if (f->output_data.x->want_fullscreen != FULLSCREEN_NONE)
+    {
+      int left, top;
+      int width, height;
+      
+      /* It takes both for some WM:s to place it where we want */
+      window_prompting = USPosition | PPosition;
+      x_fullscreen_adjust (f, &width, &height, &top, &left);
+      f->width = width;
+      f->height = height;
+      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);
+      f->output_data.x->left_pos = left;
+      f->output_data.x->top_pos = top;
+    }
+  
   return window_prompting;
 }
 
@@ -3922,8 +4100,8 @@ x_icon (f, parms)
   icon_y = x_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
   if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
     {
-      CHECK_NUMBER (icon_x, 0);
-      CHECK_NUMBER (icon_y, 0);
+      CHECK_NUMBER (icon_x);
+      CHECK_NUMBER (icon_y);
     }
   else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
     error ("Both left and top icon corners of icon must be specified");
@@ -4092,7 +4270,7 @@ 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.
+       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,
@@ -4100,8 +4278,8 @@ 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))
+This function is an internal primitive--use `make-frame' instead.  */)
+     (parms)
      Lisp_Object parms;
 {
   struct frame *f;
@@ -4147,7 +4325,7 @@ This function is an internal primitive--use `make-frame' instead.  */
   if (EQ (parent, Qunbound))
     parent = Qnil;
   if (! NILP (parent))
-    CHECK_NUMBER (parent, 0);
+    CHECK_NUMBER (parent);
 
   /* make_frame_without_minibuffer can run Lisp code and garbage collect.  */
   /* No need to protect DISPLAY because that's not used after passing
@@ -4311,7 +4489,7 @@ This function is an internal primitive--use `make-frame' instead.  */
   x_default_parameter (f, parms, Qborder_width, make_number (2),
                       "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
   
-  /* This defaults to 2 in order to match xterm.  We recognize either
+  /* This defaults to 1 in order to match xterm.  We recognize either
      internalBorderWidth or internalBorder (which is what xterm calls
      it).  */
   if (NILP (Fassq (Qinternal_border_width, parms)))
@@ -4346,6 +4524,10 @@ This function is an internal primitive--use `make-frame' instead.  */
                       "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
   x_default_parameter (f, parms, Qline_spacing, Qnil,
                       "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
+  x_default_parameter (f, parms, Qleft_fringe, Qnil,
+                      "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
+  x_default_parameter (f, parms, Qright_fringe, Qnil,
+                      "rightFringe", "RightFringe", RES_TYPE_NUMBER);
 
   x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
                                        "scrollBarForeground",
@@ -4373,6 +4555,8 @@ This function is an internal primitive--use `make-frame' instead.  */
                       "title", "Title", RES_TYPE_STRING);
   x_default_parameter (f, parms, Qwait_for_wm, Qt,
                       "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
+  x_default_parameter (f, parms, Qfullscreen, Qnil,
+                       "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
 
   f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
 
@@ -4386,7 +4570,7 @@ This function is an internal primitive--use `make-frame' instead.  */
     {
       int margin, relief, bar_height;
       
-      relief = (tool_bar_button_relief > 0
+      relief = (tool_bar_button_relief >= 0
                ? tool_bar_button_relief
                : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
 
@@ -4555,9 +4739,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.
-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);
@@ -4576,14 +4760,14 @@ 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;
   FRAME_PTR f = check_x_frame (frame);
 
-  CHECK_STRING (color, 1);
+  CHECK_STRING (color);
 
   if (x_defined_color (f, XSTRING (color)->data, &foo, 0))
     return Qt;
@@ -4592,14 +4776,14 @@ 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;
   FRAME_PTR f = check_x_frame (frame);
 
-  CHECK_STRING (color, 1);
+  CHECK_STRING (color);
 
   if (x_defined_color (f, XSTRING (color)->data, &foo, 0))
     {
@@ -4615,8 +4799,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);
@@ -4639,12 +4823,12 @@ 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.
+       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))
+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);
@@ -4669,11 +4853,11 @@ 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.
+       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))
+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);
@@ -4683,11 +4867,11 @@ 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.
+       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))
+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);
@@ -4697,11 +4881,11 @@ 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.
+       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))
+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);
@@ -4711,11 +4895,11 @@ 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.
+       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))
+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);
@@ -4727,11 +4911,11 @@ 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.
+       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))
+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);
@@ -4740,11 +4924,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.
+       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))
+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);
@@ -4755,15 +4939,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.
+       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))
+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);
@@ -4775,11 +4959,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,
-       /* Return the number of screens on the X server of 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))
+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);
@@ -4788,11 +4972,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,
-       /* Return the height in millimeters of the X 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))
+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);
@@ -4801,11 +4985,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,
-       /* Return the width in millimeters of the X 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))
+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);
@@ -4815,12 +4999,12 @@ 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.
+       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))
+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);
@@ -4850,14 +5034,14 @@ 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,
-       /* Return the visual class of the X display DISPLAY.
+       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))
+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);
@@ -4893,11 +5077,11 @@ 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.
+       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))
+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);
@@ -4965,7 +5149,7 @@ visual_classes[] =
   {"PseudoColor",      PseudoColor},
   {"TrueColor",                TrueColor},
   {"DirectColor",      DirectColor},
-  NULL
+  {NULL, 0}
 };
 
 
@@ -4982,7 +5166,7 @@ XScreenNumberOfScreen (scr)
   int i;
 
   for (i = 0; i < dpy->nscreens; ++i)
-    if (scr == dpy->screens[i])
+    if (scr == dpy->screens + i)
       break;
 
   return i;
@@ -5079,7 +5263,7 @@ x_display_info_for_name (name)
   Lisp_Object names;
   struct x_display_info *dpyinfo;
 
-  CHECK_STRING (name, 0);
+  CHECK_STRING (name);
 
   if (! EQ (Vwindow_system, intern ("x")))
     error ("Not using X Windows");
@@ -5114,20 +5298,20 @@ 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.
+       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))
+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;
   struct x_display_info *dpyinfo;
 
-  CHECK_STRING (display, 0);
+  CHECK_STRING (display);
   if (! NILP (xrm_string))
-    CHECK_STRING (xrm_string, 1);
+    CHECK_STRING (xrm_string);
 
   if (! EQ (Vwindow_system, intern ("x")))
     error ("Not using X Windows");
@@ -5147,9 +5331,9 @@ terminate Emacs if we can't open the connection.  */
   if (dpyinfo == 0)
     {
       if (!NILP (must_succeed))
-       fatal ("Cannot connect to X server %s.
-Check the DISPLAY environment variable or use `-d'.
-Also use the `xhost' program to verify that it is set to permit
+       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
@@ -5164,10 +5348,10 @@ 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.
+       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))
+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);
@@ -5203,8 +5387,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;
 
@@ -5216,15 +5400,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.
+       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))
+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);
@@ -5271,8 +5455,8 @@ Lisp_Object Qxbm;
 /* Keywords.  */
 
 extern Lisp_Object QCwidth, QCheight, QCforeground, QCbackground, QCfile;
-extern Lisp_Object QCdata;
-Lisp_Object QCtype, QCascent, QCmargin, QCrelief;
+extern Lisp_Object QCdata, QCtype;
+Lisp_Object QCascent, QCmargin, QCrelief;
 Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask;
 Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask;
 
@@ -5603,12 +5787,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).
+       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))
+or omitted means use the selected frame.  */)
+     (spec, pixels, frame)
      Lisp_Object spec, pixels, frame;
 {
   Lisp_Object size;
@@ -5636,10 +5820,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.
+       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))
+or omitted means use the selected frame.  */)
+     (spec, frame)
      Lisp_Object spec, frame;
 {
   Lisp_Object mask;
@@ -5770,6 +5954,104 @@ image_ascent (img, face)
   return ascent;
 }
 
+\f
+/* Image background colors.  */
+
+static unsigned long
+four_corners_best (ximg, width, height)
+     XImage *ximg;
+     unsigned long width, height;
+{
+  unsigned long corners[4], best;
+  int i, best_count;
+
+  /* Get the colors at the corners of ximg.  */
+  corners[0] = XGetPixel (ximg, 0, 0);
+  corners[1] = XGetPixel (ximg, width - 1, 0);
+  corners[2] = XGetPixel (ximg, width - 1, height - 1);
+  corners[3] = XGetPixel (ximg, 0, height - 1);
+
+  /* Choose the most frequently found color as background.  */
+  for (i = best_count = 0; i < 4; ++i)
+    {
+      int j, n;
+         
+      for (j = n = 0; j < 4; ++j)
+       if (corners[i] == corners[j])
+         ++n;
+
+      if (n > best_count)
+       best = corners[i], best_count = n;
+    }
+
+  return best;
+}
+
+/* Return the `background' field of IMG.  If IMG doesn't have one yet,
+   it is guessed heuristically.  If non-zero, XIMG is an existing XImage
+   object to use for the heuristic.  */
+
+unsigned long
+image_background (img, f, ximg)
+     struct image *img;
+     struct frame *f;
+     XImage *ximg;
+{
+  if (! img->background_valid)
+    /* IMG doesn't have a background yet, try to guess a reasonable value.  */
+    {
+      int free_ximg = !ximg;
+
+      if (! ximg)
+       ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap,
+                         0, 0, img->width, img->height, ~0, ZPixmap);
+
+      img->background = four_corners_best (ximg, img->width, img->height);
+
+      if (free_ximg)
+       XDestroyImage (ximg);
+
+      img->background_valid = 1;
+    }
+
+  return img->background;
+}
+
+/* Return the `background_transparent' field of IMG.  If IMG doesn't
+   have one yet, it is guessed heuristically.  If non-zero, MASK is an
+   existing XImage object to use for the heuristic.  */
+
+int
+image_background_transparent (img, f, mask)
+     struct image *img;
+     struct frame *f;
+     XImage *mask;
+{
+  if (! img->background_transparent_valid)
+    /* IMG doesn't have a background yet, try to guess a reasonable value.  */
+    {
+      if (img->mask)
+       {
+         int free_mask = !mask;
+
+         if (! mask)
+           mask = XGetImage (FRAME_X_DISPLAY (f), img->mask,
+                             0, 0, img->width, img->height, ~0, ZPixmap);
+
+         img->background_transparent
+           = !four_corners_best (mask, img->width, img->height);
+
+         if (free_mask)
+           XDestroyImage (mask);
+       }
+      else
+       img->background_transparent = 0;
+
+      img->background_transparent_valid = 1;
+    }
+
+  return img->background_transparent;
+}
 
 \f
 /***********************************************************************
@@ -5800,12 +6082,14 @@ x_clear_image_1 (f, img, pixmap_p, mask_p, colors_p)
     {
       XFreePixmap (FRAME_X_DISPLAY (f), img->pixmap);
       img->pixmap = None;
+      img->background_valid = 0;
     }
 
   if (mask_p && img->mask)
     {
       XFreePixmap (FRAME_X_DISPLAY (f), img->mask);
       img->mask = None;
+      img->background_transparent_valid = 0;
     }
       
   if (colors_p && img->ncolors)
@@ -5982,10 +6266,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.
+       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))
+FRAME t means clear the image caches of all frames.  */)
+     (frame)
      Lisp_Object frame;
 {
   if (EQ (frame, Qt))
@@ -6135,8 +6419,9 @@ lookup_image (f, spec)
       else
        {
          /* Handle image type independent image attributes
-            `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF'.  */
-         Lisp_Object ascent, margin, relief;
+            `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
+            `:background COLOR'.  */
+         Lisp_Object ascent, margin, relief, bg;
 
          ascent = image_spec_value (spec, QCascent, NULL);
          if (INTEGERP (ascent))
@@ -6164,6 +6449,18 @@ lookup_image (f, spec)
              img->vmargin += abs (img->relief);
            }
 
+         if (! img->background_valid)
+           {
+             bg = image_spec_value (img->spec, QCbackground, NULL);
+             if (!NILP (bg))
+               {
+                 img->background
+                   = x_alloc_image_color (f, img, bg,
+                                          FRAME_BACKGROUND_PIXEL (f));
+                 img->background_valid = 1;
+               }
+           }
+
          /* Do image transformations and compute masks, unless we
             don't have the image yet.  */
          if (!EQ (*img->type->type, Qpostscript))
@@ -6877,10 +7174,13 @@ xbm_load_image (f, img, contents, end)
       value = image_spec_value (img->spec, QCforeground, NULL);
       if (!NILP (value))
        foreground = x_alloc_image_color (f, img, value, foreground);
-      
       value = image_spec_value (img->spec, QCbackground, NULL);
       if (!NILP (value))
-       background = x_alloc_image_color (f, img, value, background);
+       {
+         background = x_alloc_image_color (f, img, value, background);
+         img->background = background;
+         img->background_valid = 1;
+       }
 
       img->pixmap
        = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f),
@@ -7083,6 +7383,7 @@ enum xpm_keyword_index
   XPM_HEURISTIC_MASK,
   XPM_MASK,
   XPM_COLOR_SYMBOLS,
+  XPM_BACKGROUND,
   XPM_LAST
 };
 
@@ -7100,7 +7401,8 @@ static struct image_keyword xpm_format[XPM_LAST] =
   {":conversion",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},
   {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
   {":mask",            IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-  {":color-symbols",   IMAGE_DONT_CHECK_VALUE_TYPE,            0}
+  {":color-symbols",   IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":background",      IMAGE_STRING_OR_NIL_VALUE,              0}
 };
 
 /* Structure describing the image type XBM.  */
@@ -7717,10 +8019,6 @@ colors_in_color_table (n)
                              Algorithms
  ***********************************************************************/
 
-static void x_laplace_write_row P_ ((struct frame *, long *,
-                                    int, XImage *, int));
-static void x_laplace_read_row P_ ((struct frame *, Colormap,
-                                   XColor *, int, XImage *, int));
 static XColor *x_to_xcolors P_ ((struct frame *, struct image *, int));
 static void x_from_xcolors P_ ((struct frame *, struct image *, XColor *));
 static void x_detect_edges P_ ((struct frame *, struct image *, int[9], int));
@@ -8047,13 +8345,14 @@ x_build_heuristic_mask (f, img, how)
 {
   Display *dpy = FRAME_X_DISPLAY (f);
   XImage *ximg, *mask_img;
-  int x, y, rc, look_at_corners_p;
+  int x, y, rc, use_img_background;
   unsigned long bg = 0;
 
   if (img->mask)
     {
       XFreePixmap (FRAME_X_DISPLAY (f), img->mask);
       img->mask = None;
+      img->background_transparent_valid = 0;
     }
 
   /* Create an image and pixmap serving as mask.  */
@@ -8067,17 +8366,14 @@ x_build_heuristic_mask (f, img, how)
                    ~0, ZPixmap);
 
   /* Determine the background color of ximg.  If HOW is `(R G B)'
-     take that as color.  Otherwise, try to determine the color
-     heuristically. */
-  look_at_corners_p = 1;
+     take that as color.  Otherwise, use the image's background color. */
+  use_img_background = 1;
   
   if (CONSP (how))
     {
-      int rgb[3], i = 0;
+      int rgb[3], i;
 
-      while (i < 3
-            && CONSP (how)
-            && NATNUMP (XCAR (how)))
+      for (i = 0; i < 3 && CONSP (how) && NATNUMP (XCAR (how)); ++i)
        {
          rgb[i] = XFASTINT (XCAR (how)) & 0xffff;
          how = XCDR (how);
@@ -8086,44 +8382,14 @@ x_build_heuristic_mask (f, img, how)
       if (i == 3 && NILP (how))
        {
          char color_name[30];
-         XColor exact, color;
-         Colormap cmap;
-
          sprintf (color_name, "#%04x%04x%04x", rgb[0], rgb[1], rgb[2]);
-         
-         cmap = FRAME_X_COLORMAP (f);
-         if (XLookupColor (dpy, cmap, color_name, &exact, &color))
-           {
-             bg = color.pixel;
-             look_at_corners_p = 0;
-           }
+         bg = x_alloc_image_color (f, img, build_string (color_name), 0);
+         use_img_background = 0;
        }
     }
   
-  if (look_at_corners_p)
-    {
-      unsigned long corners[4];
-      int i, best_count;
-
-      /* Get the colors at the corners of ximg.  */
-      corners[0] = XGetPixel (ximg, 0, 0);
-      corners[1] = XGetPixel (ximg, img->width - 1, 0);
-      corners[2] = XGetPixel (ximg, img->width - 1, img->height - 1);
-      corners[3] = XGetPixel (ximg, 0, img->height - 1);
-
-      /* Choose the most frequently found color as background.  */
-      for (i = best_count = 0; i < 4; ++i)
-       {
-         int j, n;
-         
-         for (j = n = 0; j < 4; ++j)
-           if (corners[i] == corners[j])
-             ++n;
-
-         if (n > best_count)
-           bg = corners[i], best_count = n;
-       }
-    }
+  if (use_img_background)
+    bg = four_corners_best (ximg, img->width, img->height);
 
   /* Set all bits in mask_img to 1 whose color in ximg is different
      from the background color bg.  */
@@ -8131,6 +8397,9 @@ x_build_heuristic_mask (f, img, how)
     for (x = 0; x < img->width; ++x)
       XPutPixel (mask_img, x, y, XGetPixel (ximg, x, y) != bg);
 
+  /* Fill in the background_transparent field while we have the mask handy. */
+  image_background_transparent (img, f, mask_img);
+
   /* Put mask_img into img->mask.  */
   x_put_x_image (f, mask_img, img->mask, img->width, img->height);
   x_destroy_x_image (mask_img);
@@ -8389,7 +8658,11 @@ pbm_load (f, img)
        fg = x_alloc_image_color (f, img, fmt[PBM_FOREGROUND].value, fg);
       if (fmt[PBM_BACKGROUND].count
          && STRINGP (fmt[PBM_BACKGROUND].value))
-       bg = x_alloc_image_color (f, img, fmt[PBM_BACKGROUND].value, bg);
+       {
+         bg = x_alloc_image_color (f, img, fmt[PBM_BACKGROUND].value, bg);
+         img->background = bg;
+         img->background_valid = 1;
+       }
       
       for (y = 0; y < height; ++y)
        for (x = 0; x < width; ++x)
@@ -8452,6 +8725,10 @@ pbm_load (f, img)
      free the color table.  */
   img->colors = colors_in_color_table (&img->ncolors);
   free_color_table ();
+
+  /* Maybe fill in the background field while we have ximg handy. */
+  if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
+    IMAGE_BACKGROUND (img, f, ximg);
   
   /* Put the image into a pixmap.  */
   x_put_x_image (f, ximg, img->pixmap, width, height);
@@ -8497,6 +8774,7 @@ enum png_keyword_index
   PNG_ALGORITHM,
   PNG_HEURISTIC_MASK,
   PNG_MASK,
+  PNG_BACKGROUND,
   PNG_LAST
 };
 
@@ -8513,7 +8791,8 @@ static struct image_keyword png_format[PNG_LAST] =
   {":relief",          IMAGE_INTEGER_VALUE,                    0},
   {":conversion",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},
   {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-  {":mask",            IMAGE_DONT_CHECK_VALUE_TYPE,            0}
+  {":mask",            IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":background",      IMAGE_STRING_OR_NIL_VALUE,              0}
 };
 
 /* Structure describing the image type `png'.  */
@@ -8622,7 +8901,6 @@ png_load (f, img)
   png_byte channels;
   png_uint_32 row_bytes;
   int transparent_p;
-  char *gamma_str;
   double screen_gamma, image_gamma;
   int intent;
   struct png_memory_storage tbr;  /* Data to be read */
@@ -8760,36 +9038,53 @@ png_load (f, img)
       || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
     png_set_gray_to_rgb (png_ptr);
 
-  /* The value 2.2 is a guess for PC monitors from PNG example.c.  */
-  gamma_str = getenv ("SCREEN_GAMMA");
-  screen_gamma = gamma_str ? atof (gamma_str) : 2.2;
+  screen_gamma = (f->gamma ? 1 / f->gamma / 0.45455 : 2.2);
 
   /* Tell the PNG lib to handle gamma correction for us.  */
 
 #if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
   if (png_get_sRGB (png_ptr, info_ptr, &intent))
-    /* There is a special chunk in the image specifying the gamma.  */
-    png_set_sRGB (png_ptr, info_ptr, intent);
+    /* The libpng documentation says this is right in this case.  */
+    png_set_gamma (png_ptr, screen_gamma, 0.45455);
   else
 #endif
   if (png_get_gAMA (png_ptr, info_ptr, &image_gamma))
     /* Image contains gamma information.  */
     png_set_gamma (png_ptr, screen_gamma, image_gamma);
   else
-    /* Use a default of 0.5 for the image gamma.  */
-    png_set_gamma (png_ptr, screen_gamma, 0.5);
+    /* Use the standard default for the image gamma.  */
+    png_set_gamma (png_ptr, screen_gamma, 0.45455);
 
   /* Handle alpha channel by combining the image with a background
      color.  Do this only if a real alpha channel is supplied.  For
      simple transparency, we prefer a clipping mask.  */
   if (!transparent_p)
     {
-      png_color_16 *image_background;
+      png_color_16 *image_bg;
+      Lisp_Object specified_bg
+       = image_spec_value (img->spec, QCbackground, NULL);
+
+      if (STRINGP (specified_bg))
+       /* The user specified `:background', use that.  */
+       {
+         XColor color;
+         if (x_defined_color (f, XSTRING (specified_bg)->data, &color, 0))
+           {
+             png_color_16 user_bg;
+
+             bzero (&user_bg, sizeof user_bg);
+             user_bg.red = color.red;
+             user_bg.green = color.green;
+             user_bg.blue = color.blue;
 
-      if (png_get_bKGD (png_ptr, info_ptr, &image_background))
+             png_set_background (png_ptr, &user_bg,
+                                 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+           }
+       }
+      else if (png_get_bKGD (png_ptr, info_ptr, &image_bg))
        /* Image contains a background color with which to 
           combine the image.  */
-       png_set_background (png_ptr, image_background,
+       png_set_background (png_ptr, image_bg,
                            PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
       else
        {
@@ -8902,6 +9197,18 @@ png_load (f, img)
        }
     }
 
+  if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
+    /* Set IMG's background color from the PNG image, unless the user
+       overrode it.  */
+    {
+      png_color_16 *bg;
+      if (png_get_bKGD (png_ptr, info_ptr, &bg))
+       {
+         img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue);
+         img->background_valid = 1;
+       }
+    }
+
   /* Remember colors allocated for this image.  */
   img->colors = colors_in_color_table (&img->ncolors);
   free_color_table ();
@@ -8914,6 +9221,9 @@ png_load (f, img)
   img->width = width;
   img->height = height;
 
+  /* Maybe fill in the background field while we have ximg handy. */
+  IMAGE_BACKGROUND (img, f, ximg);
+
   /* Put the image into the pixmap, then free the X image and its buffer.  */
   x_put_x_image (f, ximg, img->pixmap, width, height);
   x_destroy_x_image (ximg);
@@ -8921,6 +9231,10 @@ png_load (f, img)
   /* Same for the mask.  */
   if (mask_img)
     {
+      /* Fill in the background_transparent field while we have the mask
+        handy. */
+      image_background_transparent (img, f, mask_img);
+
       x_put_x_image (f, mask_img, img->mask, img->width, img->height);
       x_destroy_x_image (mask_img);
     }
@@ -8974,6 +9288,7 @@ enum jpeg_keyword_index
   JPEG_ALGORITHM,
   JPEG_HEURISTIC_MASK,
   JPEG_MASK,
+  JPEG_BACKGROUND,
   JPEG_LAST
 };
 
@@ -8990,7 +9305,8 @@ static struct image_keyword jpeg_format[JPEG_LAST] =
   {":relief",          IMAGE_INTEGER_VALUE,                    0},
   {":conversions",     IMAGE_DONT_CHECK_VALUE_TYPE,            0},
   {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-  {":mask",            IMAGE_DONT_CHECK_VALUE_TYPE,            0}
+  {":mask",            IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":background",      IMAGE_STRING_OR_NIL_VALUE,              0}
 };
 
 /* Structure describing the image type `jpeg'.  */
@@ -9289,6 +9605,10 @@ jpeg_load (f, img)
   jpeg_destroy_decompress (&cinfo);
   if (fp)
     fclose ((FILE *) fp);
+
+  /* Maybe fill in the background field while we have ximg handy. */
+  if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
+    IMAGE_BACKGROUND (img, f, ximg);
   
   /* Put the image into the pixmap.  */
   x_put_x_image (f, ximg, img->pixmap, width, height);
@@ -9329,6 +9649,7 @@ enum tiff_keyword_index
   TIFF_ALGORITHM,
   TIFF_HEURISTIC_MASK,
   TIFF_MASK,
+  TIFF_BACKGROUND,
   TIFF_LAST
 };
 
@@ -9345,7 +9666,8 @@ static struct image_keyword tiff_format[TIFF_LAST] =
   {":relief",          IMAGE_INTEGER_VALUE,                    0},
   {":conversions",     IMAGE_DONT_CHECK_VALUE_TYPE,            0},
   {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-  {":mask",            IMAGE_DONT_CHECK_VALUE_TYPE,            0}
+  {":mask",            IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":background",      IMAGE_STRING_OR_NIL_VALUE,              0}
 };
 
 /* Structure describing the image type `tiff'.  */
@@ -9637,14 +9959,18 @@ tiff_load (f, img)
   /* Remember the colors allocated for the image.  Free the color table.  */
   img->colors = colors_in_color_table (&img->ncolors);
   free_color_table ();
+      
+  img->width = width;
+  img->height = height;
+
+  /* Maybe fill in the background field while we have ximg handy. */
+  if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
+    IMAGE_BACKGROUND (img, f, ximg);
 
   /* Put the image into the pixmap, then free the X image and its buffer.  */
   x_put_x_image (f, ximg, img->pixmap, width, height);
   x_destroy_x_image (ximg);
   xfree (buf);
-      
-  img->width = width;
-  img->height = height;
 
   UNGCPRO;
   return 1;
@@ -9683,6 +10009,7 @@ enum gif_keyword_index
   GIF_HEURISTIC_MASK,
   GIF_MASK,
   GIF_IMAGE,
+  GIF_BACKGROUND,
   GIF_LAST
 };
 
@@ -9700,7 +10027,8 @@ static struct image_keyword gif_format[GIF_LAST] =
   {":conversion",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},
   {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
   {":mask",            IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-  {":image",           IMAGE_NON_NEGATIVE_INTEGER_VALUE,       0}
+  {":image",           IMAGE_NON_NEGATIVE_INTEGER_VALUE,       0},
+  {":background",      IMAGE_STRING_OR_NIL_VALUE,              0}
 };
 
 /* Structure describing the image type `gif'.  */
@@ -9849,8 +10177,8 @@ gif_load (f, img)
       return 0;
     }
 
-  width = img->width = gif->SWidth;
-  height = img->height = gif->SHeight;
+  width = img->width = max (gif->SWidth, gif->Image.Left + gif->Image.Width);
+  height = img->height = max (gif->SHeight, gif->Image.Top + gif->Image.Height);
 
   /* Create the X image and pixmap.  */
   if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
@@ -9948,6 +10276,10 @@ gif_load (f, img)
     }
   
   DGifCloseFile (gif);
+
+  /* Maybe fill in the background field while we have ximg handy. */
+  if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
+    IMAGE_BACKGROUND (img, f, ximg);
   
   /* Put the image into the pixmap, then free the X image and its buffer.  */
   x_put_x_image (f, ximg, img->pixmap, width, height);
@@ -9993,6 +10325,7 @@ enum gs_keyword_index
   GS_ALGORITHM,
   GS_HEURISTIC_MASK,
   GS_MASK,
+  GS_BACKGROUND,
   GS_LAST
 };
 
@@ -10012,7 +10345,8 @@ static struct image_keyword gs_format[GS_LAST] =
   {":relief",          IMAGE_INTEGER_VALUE,                    0},
   {":conversion",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},
   {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-  {":mask",            IMAGE_DONT_CHECK_VALUE_TYPE,            0}
+  {":mask",            IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":background",      IMAGE_STRING_OR_NIL_VALUE,              0}
 };
 
 /* Structure describing the image type `ghostscript'.  */
@@ -10247,17 +10581,17 @@ 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.
+       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))
+selected frame.  Value is VALUE.  */)
+     (prop, value, frame)
      Lisp_Object frame, prop, value;
 {
   struct frame *f = check_x_frame (frame);
   Atom prop_atom;
 
-  CHECK_STRING (prop, 1);
-  CHECK_STRING (value, 2);
+  CHECK_STRING (prop);
+  CHECK_STRING (value);
 
   BLOCK_INPUT;
   prop_atom = XInternAtom (FRAME_X_DISPLAY (f), XSTRING (prop)->data, False);
@@ -10275,15 +10609,15 @@ 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.
-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);
   Atom prop_atom;
 
-  CHECK_STRING (prop, 1);
+  CHECK_STRING (prop);
   BLOCK_INPUT;
   prop_atom = XInternAtom (FRAME_X_DISPLAY (f), XSTRING (prop)->data, False);
   XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), prop_atom);
@@ -10298,11 +10632,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.
+       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))
+value.  */)
+     (prop, frame)
      Lisp_Object prop, frame;
 {
   struct frame *f = check_x_frame (frame);
@@ -10314,7 +10648,7 @@ value.  */
   int actual_format;
   unsigned long actual_size, bytes_remaining;
 
-  CHECK_STRING (prop, 1);
+  CHECK_STRING (prop);
   BLOCK_INPUT;
   prop_atom = XInternAtom (FRAME_X_DISPLAY (f), XSTRING (prop)->data, False);
   rc = XGetWindowProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
@@ -10913,7 +11247,7 @@ compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
   
   /* Move the tooltip window where the mouse pointer is.  Resize and
      show it.  */
-  if (!INTEGERP (left) && !INTEGERP (top))
+  if (!INTEGERP (left) || !INTEGERP (top))
     {
       BLOCK_INPUT;
       XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
@@ -10933,15 +11267,20 @@ compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
 
   if (INTEGERP (left))
     *root_x = XINT (left);
-  else if (*root_x + XINT (dx) + width > FRAME_X_DISPLAY_INFO (f)->width)
+  else if (*root_x + XINT (dx) + width <= FRAME_X_DISPLAY_INFO (f)->width)
+    /* It fits to the right of the pointer.  */
+    *root_x += XINT (dx);
+  else if (width + XINT (dx) <= *root_x)
+    /* It fits to the left of the pointer.  */
     *root_x -= width + XINT (dx);
   else
-    *root_x += XINT (dx);
+    /* Put it left-justified on the screen--it ought to fit that way.  */
+    *root_x = 0;
 }
 
 
 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
-       /* Show STRING in a "tooltip" window on frame FRAME.
+       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.
@@ -10961,13 +11300,12 @@ 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))
+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, max_width, max_height;
   int root_x, root_y;
   struct buffer *old_buffer;
   struct text_pos pos;
@@ -10980,22 +11318,22 @@ Text larger than the specified size is clipped.  */
 
   GCPRO4 (string, parms, frame, timeout);
 
-  CHECK_STRING (string, 0);
+  CHECK_STRING (string);
   f = check_x_frame (frame);
   if (NILP (timeout))
     timeout = make_number (5);
   else
-    CHECK_NATNUM (timeout, 2);
+    CHECK_NATNUM (timeout);
   
   if (NILP (dx))
     dx = make_number (5);
   else
-    CHECK_NUMBER (dx, 5);
+    CHECK_NUMBER (dx);
   
   if (NILP (dy))
     dy = make_number (-10);
   else
-    CHECK_NUMBER (dy, 6);
+    CHECK_NUMBER (dy);
 
   if (NILP (last_show_tip_args))
     last_show_tip_args = Fmake_vector (make_number (3), Qnil);
@@ -11150,9 +11488,9 @@ Text larger than the specified size is clipped.  */
 
 
 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
-       /* Hide the current tooltip window, if there is any.
-Value is t if 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;
@@ -11240,12 +11578,12 @@ file_dialog_unmap_cb (widget, client_data, call_data)
 
 
 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0,
-       /* Read file name, prompting with PROMPT in directory DIR.
+       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))
+selection dialog's entry field, if MUSTMATCH is non-nil.  */)
+     (prompt, dir, default_filename, mustmatch)
      Lisp_Object prompt, dir, default_filename, mustmatch;
 {
   int result;
@@ -11260,8 +11598,8 @@ selection dialog's entry field, if MUSTMATCH is non-nil.  */
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
 
   GCPRO5 (prompt, dir, default_filename, mustmatch, file);
-  CHECK_STRING (prompt, 0);
-  CHECK_STRING (dir, 1);
+  CHECK_STRING (prompt);
+  CHECK_STRING (dir);
 
   /* Prevent redisplay.  */
   specbind (Qinhibit_redisplay, Qt);
@@ -11398,11 +11736,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.
+       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))
+usual X keysyms.  */)
+     (frame)
      Lisp_Object frame;
 {
 #ifdef HAVE_XKBGETKEYBOARD
@@ -11563,6 +11901,14 @@ syms_of_xfns ()
   staticpro (&Qcancel_timer);
   Qwait_for_wm = intern ("wait-for-wm");
   staticpro (&Qwait_for_wm);
+  Qfullscreen = intern ("fullscreen");
+  staticpro (&Qfullscreen);
+  Qfullwidth = intern ("fullwidth");
+  staticpro (&Qfullwidth);
+  Qfullheight = intern ("fullheight");
+  staticpro (&Qfullheight);
+  Qfullboth = intern ("fullboth");
+  staticpro (&Qfullboth);
   /* This is the end of symbol initialization.  */
 
   /* Text property `display' should be nonsticky by default.  */
@@ -11595,24 +11941,24 @@ 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.
+  DEFVAR_BOOL ("cross-disabled-images", &cross_disabled_images,
+    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.  */);
+  DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,
+    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.
+  DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
+    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.
+  DEFVAR_LISP ("x-resource-name", &Vx_resource_name,
+    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
@@ -11623,8 +11969,8 @@ 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.
+  DEFVAR_LISP ("x-resource-class", &Vx_resource_class,
+    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.
 
@@ -11636,61 +11982,61 @@ 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.
+  DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
+    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.
+  DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape,
+    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.  */);
+  DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
+    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.
+  DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
+    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.
+  DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
+    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.
+             &Vx_sensitive_text_pointer_shape,
+              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.
+             &Vx_window_horizontal_drag_shape,
+  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.  */);
+  DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
+    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
-    /* Maximum size for tooltips.  Value is a pair (COLUMNS . ROWS).
+  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.
+  DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
+    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
@@ -11698,8 +12044,8 @@ unless you set it to something else.  */);
   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'.
+              &Vx_pixel_size_width_font_regexp,
+    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
@@ -11707,8 +12053,8 @@ 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.
+  DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay,
+    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.  */);
@@ -11719,8 +12065,8 @@ meaning don't clear the cache.  */);
 #ifdef USE_MOTIF
   Fprovide (intern ("motif"), Qnil);
 
-  DEFVAR_LISP ("motif-version-string", &Vmotif_version_string
-              /* Version info for LessTif/Motif.  */);
+  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 */
@@ -11775,8 +12121,6 @@ meaning don't clear the cache.  */);
   /* Images.  */
   Qxbm = intern ("xbm");
   staticpro (&Qxbm);
-  QCtype = intern (":type");
-  staticpro (&QCtype);
   QCconversion = intern (":conversion");
   staticpro (&QCconversion);
   QCheuristic_mask = intern (":heuristic-mask");