]> code.delx.au - gnu-emacs/blobdiff - src/xfns.c
2002-08-10 Andrew Choi <akochoi@shaw.ca>
[gnu-emacs] / src / xfns.c
index 6c4b68cb24580f2095310cc287cfe87417539f2d..4f23af432c8c889cc83af0dc2301a2681b70da38 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
@@ -183,7 +185,7 @@ Lisp_Object Vx_pixel_size_width_font_regexp;
 
 Lisp_Object Qauto_raise;
 Lisp_Object Qauto_lower;
-Lisp_Object Qbar;
+Lisp_Object Qbar, Qhbar;
 Lisp_Object Qborder_color;
 Lisp_Object Qborder_width;
 Lisp_Object Qbox;
@@ -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");
@@ -295,12 +301,7 @@ check_x_display_info (frame)
     dpyinfo = x_display_info_for_name (frame);
   else
     {
-      FRAME_PTR f;
-
-      CHECK_LIVE_FRAME (frame, 0);
-      f = XFRAME (frame);
-      if (! FRAME_X_P (f))
-       error ("Non-X frame used");
+      FRAME_PTR f = check_x_frame (frame);
       dpyinfo = FRAME_X_DISPLAY_INFO (f);
     }
 
@@ -635,7 +636,7 @@ x_create_bitmap_from_file (f, file)
     {
       if (dpyinfo->bitmaps[id].refcount
          && dpyinfo->bitmaps[id].file
-         && !strcmp (dpyinfo->bitmaps[id].file, (char *) XSTRING (file)->data))
+         && !strcmp (dpyinfo->bitmaps[id].file, (char *) SDATA (file)))
        {
          ++dpyinfo->bitmaps[id].refcount;
          return id + 1;
@@ -643,12 +644,12 @@ x_create_bitmap_from_file (f, file)
     }
 
   /* Search bitmap-file-path for the file, if appropriate.  */
-  fd = openp (Vx_bitmap_file_path, file, Qnil, &found, 0);
+  fd = openp (Vx_bitmap_file_path, file, Qnil, &found, Qnil);
   if (fd < 0)
     return -1;
   emacs_close (fd);
 
-  filename = (char *) XSTRING (found)->data;
+  filename = (char *) SDATA (found);
 
   result = XReadBitmapFile (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                            filename, &width, &height, &bitmap, &xhot, &yhot);
@@ -659,11 +660,11 @@ x_create_bitmap_from_file (f, file)
   dpyinfo->bitmaps[id - 1].pixmap = bitmap;
   dpyinfo->bitmaps[id - 1].refcount = 1;
   dpyinfo->bitmaps[id - 1].file
-    = (char *) xmalloc (STRING_BYTES (XSTRING (file)) + 1);
+    = (char *) xmalloc (SBYTES (file) + 1);
   dpyinfo->bitmaps[id - 1].depth = 1;
   dpyinfo->bitmaps[id - 1].height = height;
   dpyinfo->bitmaps[id - 1].width = width;
-  strcpy (dpyinfo->bitmaps[id - 1].file, XSTRING (file)->data);
+  strcpy (dpyinfo->bitmaps[id - 1].file, SDATA (file));
 
   return id;
 }
@@ -731,6 +732,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 +740,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 +778,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 +823,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 +875,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 +924,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 +975,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 +1031,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 +1148,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),
+
+                                 /* 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);
+    }
 
-      x_uncatch_errors (FRAME_X_DISPLAY (f), count);
+      had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
     }
+      
+  x_uncatch_errors (FRAME_X_DISPLAY (f), count);
+      
+  UNBLOCK_INPUT;
 
-  *xptr = win_x;
-  *yptr = win_y;
+  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 +1291,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,14 +1380,14 @@ 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
         an important optimization.  */
-  if (strcmp (XSTRING (color_name)->data, "black") == 0)
+  if (strcmp (SDATA (color_name), "black") == 0)
     return BLACK_PIX_DEFAULT (f);
-  else if (strcmp (XSTRING (color_name)->data, "white") == 0)
+  else if (strcmp (SDATA (color_name), "white") == 0)
     return WHITE_PIX_DEFAULT (f);
 #endif
 
@@ -1283,7 +1397,7 @@ x_decode_color (f, color_name, mono_color)
 
   /* x_defined_color is responsible for coping with failures
      by looking for a near-miss.  */
-  if (x_defined_color (f, XSTRING (color_name)->data, &cdef, 1))
+  if (x_defined_color (f, SDATA (color_name), &cdef, 1))
     return cdef.pixel;
 
   Fsignal (Qerror, Fcons (build_string ("Undefined color"),
@@ -1326,6 +1440,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 +1601,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 +1610,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 +1620,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 +1631,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,16 +1640,16 @@ 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));
     }
   else
-    cross_cursor = XCreateFontCursor (dpy, XC_crosshair);
+    cross_cursor = XCreateFontCursor (dpy, XC_hand2);
 
   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 +1803,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);
@@ -1725,6 +1858,19 @@ x_specified_cursor_type (arg, width)
       type = BAR_CURSOR;
       *width = XINT (XCDR (arg));
     }
+  else if (EQ (arg, Qhbar))
+    {
+      type = HBAR_CURSOR;
+      *width = 2;
+    }
+  else if (CONSP (arg)
+          && EQ (XCAR (arg), Qhbar)
+          && INTEGERP (XCDR (arg))
+          && XINT (XCDR (arg)) >= 0)
+    {
+      type = HBAR_CURSOR;
+      *width = XINT (XCDR (arg));
+    }
   else if (NILP (arg))
     type = NO_CURSOR;
   else
@@ -1746,9 +1892,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
@@ -1769,9 +1914,9 @@ x_set_icon_type (f, arg, oldval)
   BLOCK_INPUT;
   if (NILP (arg))
     result = x_text_icon (f,
-                         (char *) XSTRING ((!NILP (f->icon_name)
+                         (char *) SDATA ((!NILP (f->icon_name)
                                             ? f->icon_name
-                                            : f->name))->data);
+                                            : f->name)));
   else
     result = x_bitmap_icon (f, arg);
 
@@ -1823,11 +1968,11 @@ x_set_icon_name (f, arg, oldval)
   BLOCK_INPUT;
 
   result = x_text_icon (f,
-                       (char *) XSTRING ((!NILP (f->icon_name)
-                                          ? f->icon_name
-                                          : !NILP (f->title)
-                                          ? f->title
-                                          : f->name))->data);
+                       (char *) SDATA ((!NILP (f->icon_name)
+                                        ? f->icon_name
+                                        : !NILP (f->title)
+                                        ? f->title
+                                        : f->name)));
 
   if (result)
     {
@@ -1849,18 +1994,18 @@ 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);
 
   BLOCK_INPUT;
   result = (STRINGP (fontset_name)
-           ? x_new_fontset (f, XSTRING (fontset_name)->data)
-           : x_new_font (f, XSTRING (arg)->data));
+           ? x_new_fontset (f, SDATA (fontset_name))
+           : x_new_font (f, SDATA (arg)));
   UNBLOCK_INPUT;
   
   if (EQ (result, Qnil))
-    error ("Font `%s' is not defined", XSTRING (arg)->data);
+    error ("Font `%s' is not defined", SDATA (arg));
   else if (EQ (result, Qt))
     error ("The characters of the given font have varying widths");
   else if (STRINGP (result))
@@ -1895,12 +2040,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 +2071,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 +2090,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 +2358,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,17 +2370,19 @@ 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;
-  int bytes = STRING_BYTES (XSTRING (string));
+  unsigned char *str = SDATA (string);
+  int chars = SCHARS (string);
+  int bytes = SBYTES (string);
   int charset_info;
   int bufsize;
   unsigned char *buf;
   struct coding_system coding;
+  extern Lisp_Object Qcompound_text_with_extensions;
 
   charset_info = find_charset_in_text (str, chars, bytes, NULL, Qnil);
   if (charset_info == 0)
@@ -2233,6 +2394,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 = SDATA (string);
+      chars = SCHARS (string);
+      bytes = SBYTES (string);
+    }
   coding.src_multibyte = 1;
   coding.dst_multibyte = 0;
   coding.mode |= CODING_MODE_LAST_BLOCK;
@@ -2244,7 +2414,9 @@ x_encode_text (string, coding_system, text_bytes, stringp)
   buf = (unsigned char *) xmalloc (bufsize);
   encode_coding (&coding, str, buf, bytes, bufsize);
   *text_bytes = coding.produced;
-  *stringp = (charset_info == 1 || !EQ (coding_system, Qcompound_text));
+  *stringp = (charset_info == 1
+             || (!EQ (coding_system, Qcompound_text)
+                 && !EQ (coding_system, Qcompound_text_with_extensions)));
   return buf;
 }
 
@@ -2286,12 +2458,12 @@ x_set_name (f, name, explicit)
       /* Check for no change needed in this very common case
         before we do any consing.  */
       if (!strcmp (FRAME_X_DISPLAY_INFO (f)->x_id_name,
-                  XSTRING (f->name)->data))
+                  SDATA (f->name)))
        return;
       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 +2488,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 +2500,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);
@@ -2345,16 +2517,16 @@ x_set_name (f, name, explicit)
        XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &icon);
 #endif /* not USE_X_TOOLKIT */
        if (!NILP (f->icon_name)
-           && icon.value != XSTRING (f->icon_name)->data)
+           && icon.value != SDATA (f->icon_name))
          xfree (icon.value);
-       if (text.value != XSTRING (name)->data)
+       if (text.value != SDATA (name))
          xfree (text.value);
       }
 #else /* not HAVE_X11R4 */
       XSetIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                   XSTRING (name)->data);
+                   SDATA (name));
       XStoreName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                 XSTRING (name)->data);
+                 SDATA (name));
 #endif /* not HAVE_X11R4 */
       UNBLOCK_INPUT;
     }
@@ -2409,7 +2581,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 +2595,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 +2607,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);
@@ -2452,16 +2624,16 @@ x_set_title (f, name, old_name)
        XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &icon);
 #endif /* not USE_X_TOOLKIT */
        if (!NILP (f->icon_name)
-           && icon.value != XSTRING (f->icon_name)->data)
+           && icon.value != SDATA (f->icon_name))
          xfree (icon.value);
-       if (text.value != XSTRING (name)->data)
+       if (text.value != SDATA (name))
          xfree (text.value);
       }
 #else /* not HAVE_X11R4 */
       XSetIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                   XSTRING (name)->data);
+                   SDATA (name));
       XStoreName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                 XSTRING (name)->data);
+                 SDATA (name));
 #endif /* not HAVE_X11R4 */
       UNBLOCK_INPUT;
     }
@@ -2586,10 +2758,10 @@ validate_x_resource_name ()
 
   if (STRINGP (Vx_resource_name))
     {
-      unsigned char *p = XSTRING (Vx_resource_name)->data;
+      unsigned char *p = SDATA (Vx_resource_name);
       int i;
 
-      len = STRING_BYTES (XSTRING (Vx_resource_name));
+      len = SBYTES (Vx_resource_name);
 
       /* Only letters, digits, - and _ are valid in resource names.
         Count the valid characters and count the invalid ones.  */
@@ -2628,12 +2800,12 @@ validate_x_resource_name ()
 
   for (i = 0; i < len; i++)
     {
-      int c = XSTRING (new)->data[i];
+      int c = SREF (new, i);
       if (! ((c >= 'a' && c <= 'z')
             || (c >= 'A' && c <= 'Z')
             || (c >= '0' && c <= '9')
             || c == '-' || c == '_'))
-       XSTRING (new)->data[i] = '_';
+       SSET (new, i, '_');
     }
 }
 
@@ -2641,7 +2813,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 +2821,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 +2831,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");
 
@@ -2673,37 +2845,37 @@ and the class is `Emacs.CLASS.SUBCLASS'.  */
 
   /* Allocate space for the components, the dots which separate them,
      and the final '\0'.  Make them big enough for the worst case.  */
-  name_key = (char *) alloca (STRING_BYTES (XSTRING (Vx_resource_name))
+  name_key = (char *) alloca (SBYTES (Vx_resource_name)
                              + (STRINGP (component)
-                                ? STRING_BYTES (XSTRING (component)) : 0)
-                             + STRING_BYTES (XSTRING (attribute))
+                                ? SBYTES (component) : 0)
+                             + SBYTES (attribute)
                              + 3);
 
-  class_key = (char *) alloca (STRING_BYTES (XSTRING (Vx_resource_class))
-                              + STRING_BYTES (XSTRING (class))
+  class_key = (char *) alloca (SBYTES (Vx_resource_class)
+                              + SBYTES (class)
                               + (STRINGP (subclass)
-                                 ? STRING_BYTES (XSTRING (subclass)) : 0)
+                                 ? SBYTES (subclass) : 0)
                               + 3);
 
   /* Start with emacs.FRAMENAME for the name (the specific one)
      and with `Emacs' for the class key (the general one).  */
-  strcpy (name_key, XSTRING (Vx_resource_name)->data);
-  strcpy (class_key, XSTRING (Vx_resource_class)->data);
+  strcpy (name_key, SDATA (Vx_resource_name));
+  strcpy (class_key, SDATA (Vx_resource_class));
 
   strcat (class_key, ".");
-  strcat (class_key, XSTRING (class)->data);
+  strcat (class_key, SDATA (class));
 
   if (!NILP (component))
     {
       strcat (class_key, ".");
-      strcat (class_key, XSTRING (subclass)->data);
+      strcat (class_key, SDATA (subclass));
 
       strcat (name_key, ".");
-      strcat (name_key, XSTRING (component)->data);
+      strcat (name_key, SDATA (component));
     }
 
   strcat (name_key, ".");
-  strcat (name_key, XSTRING (attribute)->data);
+  strcat (name_key, SDATA (attribute));
 
   value = x_get_string_resource (check_x_display_info (Qnil)->xrdb,
                                 name_key, class_key);
@@ -2725,13 +2897,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");
 
@@ -2739,37 +2911,37 @@ display_x_get_resource (dpyinfo, attribute, class, component, subclass)
 
   /* Allocate space for the components, the dots which separate them,
      and the final '\0'.  Make them big enough for the worst case.  */
-  name_key = (char *) alloca (STRING_BYTES (XSTRING (Vx_resource_name))
+  name_key = (char *) alloca (SBYTES (Vx_resource_name)
                              + (STRINGP (component)
-                                ? STRING_BYTES (XSTRING (component)) : 0)
-                             + STRING_BYTES (XSTRING (attribute))
+                                ? SBYTES (component) : 0)
+                             + SBYTES (attribute)
                              + 3);
 
-  class_key = (char *) alloca (STRING_BYTES (XSTRING (Vx_resource_class))
-                              + STRING_BYTES (XSTRING (class))
+  class_key = (char *) alloca (SBYTES (Vx_resource_class)
+                              + SBYTES (class)
                               + (STRINGP (subclass)
-                                 ? STRING_BYTES (XSTRING (subclass)) : 0)
+                                 ? SBYTES (subclass) : 0)
                               + 3);
 
   /* Start with emacs.FRAMENAME for the name (the specific one)
      and with `Emacs' for the class key (the general one).  */
-  strcpy (name_key, XSTRING (Vx_resource_name)->data);
-  strcpy (class_key, XSTRING (Vx_resource_class)->data);
+  strcpy (name_key, SDATA (Vx_resource_name));
+  strcpy (class_key, SDATA (Vx_resource_class));
 
   strcat (class_key, ".");
-  strcat (class_key, XSTRING (class)->data);
+  strcat (class_key, SDATA (class));
 
   if (!NILP (component))
     {
       strcat (class_key, ".");
-      strcat (class_key, XSTRING (subclass)->data);
+      strcat (class_key, SDATA (subclass));
 
       strcat (name_key, ".");
-      strcat (name_key, XSTRING (component)->data);
+      strcat (name_key, SDATA (component));
     }
 
   strcat (name_key, ".");
-  strcat (name_key, XSTRING (attribute)->data);
+  strcat (name_key, SDATA (attribute));
 
   value = x_get_string_resource (dpyinfo->xrdb, name_key, class_key);
 
@@ -2791,13 +2963,13 @@ x_get_resource_string (attribute, class)
 
   /* Allocate space for the components, the dots which separate them,
      and the final '\0'.  */
-  name_key = (char *) alloca (STRING_BYTES (XSTRING (Vinvocation_name))
+  name_key = (char *) alloca (SBYTES (Vinvocation_name)
                              + strlen (attribute) + 2);
   class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
                               + strlen (class) + 2);
 
   sprintf (name_key, "%s.%s",
-          XSTRING (Vinvocation_name)->data,
+          SDATA (Vinvocation_name),
           attribute);
   sprintf (class_key, "%s.%s", EMACS_CLASS, class);
 
@@ -2855,15 +3027,15 @@ x_get_arg (dpyinfo, alist, param, attribute, class, type)
          switch (type)
            {
            case RES_TYPE_NUMBER:
-             return make_number (atoi (XSTRING (tem)->data));
+             return make_number (atoi (SDATA (tem)));
 
            case RES_TYPE_FLOAT:
-             return make_float (atof (XSTRING (tem)->data));
+             return make_float (atof (SDATA (tem)));
 
            case RES_TYPE_BOOLEAN:
              tem = Fdowncase (tem);
-             if (!strcmp (XSTRING (tem)->data, "on")
-                 || !strcmp (XSTRING (tem)->data, "true"))
+             if (!strcmp (SDATA (tem), "on")
+                 || !strcmp (SDATA (tem), "true"))
                return Qt;
              else 
                return Qnil;
@@ -2877,11 +3049,11 @@ x_get_arg (dpyinfo, alist, param, attribute, class, type)
              {
                Lisp_Object lower;
                lower = Fdowncase (tem);
-               if (!strcmp (XSTRING (lower)->data, "on")
-                   || !strcmp (XSTRING (lower)->data, "true"))
+               if (!strcmp (SDATA (lower), "on")
+                   || !strcmp (SDATA (lower), "true"))
                  return Qt;
-               else if (!strcmp (XSTRING (lower)->data, "off")
-                     || !strcmp (XSTRING (lower)->data, "false"))
+               else if (!strcmp (SDATA (lower), "off")
+                     || !strcmp (SDATA (lower), "false"))
                  return Qnil;
                else
                  return Fintern (tem, Qnil);
@@ -2999,22 +3171,22 @@ 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,
+  geometry = XParseGeometry ((char *) SDATA (string),
                             &x, &y, &width, &height);
 
 #if 0
@@ -3091,12 +3263,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 +3281,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 +3314,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 +3342,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 +3354,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;
 }
 
@@ -3370,7 +3559,7 @@ create_frame_xic (f)
        {
          /* Determine the base fontname from the ASCII font name of
             FONTSET.  */
-         char *ascii_font = (char *) XSTRING (fontset_ascii (fontset))->data;
+         char *ascii_font = (char *) SDATA (fontset_ascii (fontset));
          char *p = ascii_font;
          int i;
 
@@ -3591,7 +3780,7 @@ x_window (f, window_prompting, minibuffer_only)
      Elsewhere we specify the window name for the window manager.  */
      
   {
-    char *str = (char *) XSTRING (Vx_resource_name)->data;
+    char *str = (char *) SDATA (Vx_resource_name);
     f->namebuf = (char *) xmalloc (strlen (str) + 1);
     strcpy (f->namebuf, str);
   }
@@ -3724,8 +3913,8 @@ x_window (f, window_prompting, minibuffer_only)
 
   validate_x_resource_name ();
 
-  class_hints.res_name = (char *) XSTRING (Vx_resource_name)->data;
-  class_hints.res_class = (char *) XSTRING (Vx_resource_class)->data;
+  class_hints.res_name = (char *) SDATA (Vx_resource_name);
+  class_hints.res_class = (char *) SDATA (Vx_resource_class);
   XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
 
 #ifdef HAVE_X_I18N
@@ -3852,8 +4041,8 @@ x_window (f)
   
   validate_x_resource_name ();
 
-  class_hints.res_name = (char *) XSTRING (Vx_resource_name)->data;
-  class_hints.res_class = (char *) XSTRING (Vx_resource_class)->data;
+  class_hints.res_name = (char *) SDATA (Vx_resource_name);
+  class_hints.res_class = (char *) SDATA (Vx_resource_class);
   XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints);
 
   /* The menubar is part of the ordinary display;
@@ -3922,8 +4111,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");
@@ -3940,9 +4129,9 @@ x_icon (f, parms)
         ? IconicState
         : NormalState));
 
-  x_text_icon (f, (char *) XSTRING ((!NILP (f->icon_name)
+  x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
                                     ? f->icon_name
-                                    : f->name))->data);
+                                    : f->name)));
 
   UNBLOCK_INPUT;
 }
@@ -4092,7 +4281,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 +4289,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;
@@ -4110,7 +4299,7 @@ This function is an internal primitive--use `make-frame' instead.  */
   int minibuffer_only = 0;
   long window_prompting = 0;
   int width, height;
-  int count = BINDING_STACK_SIZE ();
+  int count = SPECPDL_INDEX ();
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
   Lisp_Object display;
   struct x_display_info *dpyinfo = NULL;
@@ -4147,7 +4336,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
@@ -4275,9 +4464,9 @@ This function is an internal primitive--use `make-frame' instead.  */
       {
        tem = Fquery_fontset (font, Qnil);
        if (STRINGP (tem))
-         font = x_new_fontset (f, XSTRING (tem)->data);
+         font = x_new_fontset (f, SDATA (tem));
        else
-         font = x_new_font (f, XSTRING (font)->data);
+         font = x_new_font (f, SDATA (font));
       }
     
     /* Try out a font which we hope has bold and italic variations.  */
@@ -4311,7 +4500,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 +4535,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 +4566,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 +4581,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 +4750,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,32 +4771,32 @@ 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))
+  if (x_defined_color (f, SDATA (color), &foo, 0))
     return Qt;
   else
     return Qnil;
 }
 
 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))
+  if (x_defined_color (f, SDATA (color), &foo, 0))
     {
       Lisp_Object rgb[3];
 
@@ -4615,8 +4810,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 +4834,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 +4864,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 +4878,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 +4892,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 +4906,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 +4922,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 +4935,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 +4950,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 +4970,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 +4983,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 +4996,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 +5010,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 +5045,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 +5088,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 +5160,7 @@ visual_classes[] =
   {"PseudoColor",      PseudoColor},
   {"TrueColor",                TrueColor},
   {"DirectColor",      DirectColor},
-  NULL
+  {NULL, 0}
 };
 
 
@@ -4982,7 +5177,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;
@@ -5012,12 +5207,12 @@ select_visual (dpyinfo)
       /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
         of `PseudoColor', `TrueColor' etc. and DEPTH is the color
         depth, a decimal number.  NAME is compared with case ignored.  */
-      char *s = (char *) alloca (STRING_BYTES (XSTRING (value)) + 1);
+      char *s = (char *) alloca (SBYTES (value) + 1);
       char *dash;
       int i, class = -1;
       XVisualInfo vinfo;
 
-      strcpy (s, XSTRING (value)->data);
+      strcpy (s, SDATA (value));
       dash = index (s, '-');
       if (dash)
        {
@@ -5041,7 +5236,7 @@ select_visual (dpyinfo)
       if (class == -1
          || !XMatchVisualInfo (dpy, XScreenNumberOfScreen (screen),
                                dpyinfo->n_planes, class, &vinfo))
-       fatal ("Invalid visual specification `%s'", XSTRING (value)->data);
+       fatal ("Invalid visual specification `%s'", SDATA (value));
       
       dpyinfo->visual = vinfo.visual;
     }
@@ -5079,7 +5274,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");
@@ -5100,10 +5295,10 @@ x_display_info_for_name (name)
   validate_x_resource_name ();
 
   dpyinfo = x_term_init (name, (char *)0,
-                        (char *) XSTRING (Vx_resource_name)->data);
+                        (char *) SDATA (Vx_resource_name));
 
   if (dpyinfo == 0)
-    error ("Cannot connect to X server %s", XSTRING (name)->data);
+    error ("Cannot connect to X server %s", SDATA (name));
 
   x_in_use = 1;
   XSETFASTINT (Vwindow_system_version, 11);
@@ -5114,26 +5309,26 @@ 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");
 
   if (! NILP (xrm_string))
-    xrm_option = (unsigned char *) XSTRING (xrm_string)->data;
+    xrm_option = (unsigned char *) SDATA (xrm_string);
   else
     xrm_option = (unsigned char *) 0;
 
@@ -5142,18 +5337,18 @@ terminate Emacs if we can't open the connection.  */
   /* This is what opens the connection and sets x_current_display.
      This also initializes many symbols, such as those used for input.  */
   dpyinfo = x_term_init (display, xrm_option,
-                        (char *) XSTRING (Vx_resource_name)->data);
+                        (char *) SDATA (Vx_resource_name));
 
   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);
+              SDATA (display));
       else
-       error ("Cannot connect to X server %s", XSTRING (display)->data);
+       error ("Cannot connect to X server %s", SDATA (display));
     }
 
   x_in_use = 1;
@@ -5164,10 +5359,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 +5398,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 +5411,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 +5466,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;
 
@@ -5467,7 +5662,7 @@ parse_image_spec (spec, keywords, nkeywords, type)
 
       /* Find key in KEYWORDS.  Error if not found.  */
       for (i = 0; i < nkeywords; ++i)
-       if (strcmp (keywords[i].name, XSYMBOL (key)->name->data) == 0)
+       if (strcmp (keywords[i].name, SDATA (SYMBOL_NAME (key))) == 0)
          break;
 
       if (i == nkeywords)
@@ -5603,12 +5798,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 +5831,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 +5965,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 +6093,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)
@@ -5847,7 +6142,7 @@ x_alloc_image_color (f, img, color_name, dflt)
 
   xassert (STRINGP (color_name));
 
-  if (x_defined_color (f, XSTRING (color_name)->data, &color, 1))
+  if (x_defined_color (f, SDATA (color_name), &color, 1))
     {
       /* This isn't called frequently so we get away with simply
         reallocating the color vector to the needed size, here.  */
@@ -5982,10 +6277,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 +6430,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 +6460,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))
@@ -6364,7 +6672,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, Qnil, &file_found, 0);
+  fd = openp (search_path, file, Qnil, &file_found, Qnil);
   
   if (fd == -1)
     file_found = Qnil;
@@ -6572,7 +6880,7 @@ xbm_image_p (object)
 
              if (STRINGP (elt))
                {
-                 if (XSTRING (elt)->size
+                 if (SCHARS (elt)
                      < (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR)
                    return 0;
                }
@@ -6587,7 +6895,7 @@ xbm_image_p (object)
        }
       else if (STRINGP (data))
        {
-         if (XSTRING (data)->size
+         if (SCHARS (data)
              < (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR * height)
            return 0;
        }
@@ -6877,10 +7185,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),
@@ -6914,9 +7225,9 @@ xbm_file_p (data)
 {
   int w, h;
   return (STRINGP (data)
-         && xbm_read_bitmap_data (XSTRING (data)->data,
-                                  (XSTRING (data)->data
-                                   + STRING_BYTES (XSTRING (data))),
+         && xbm_read_bitmap_data (SDATA (data),
+                                  (SDATA (data)
+                                   + SBYTES (data)),
                                   &w, &h, NULL));
 }
 
@@ -6952,7 +7263,7 @@ xbm_load (f, img)
          return 0;
        }
 
-      contents = slurp_file (XSTRING (file)->data, &size);
+      contents = slurp_file (SDATA (file), &size);
       if (contents == NULL)
        {
          image_error ("Error loading XBM image `%s'", img->spec, Qnil);
@@ -7002,9 +7313,9 @@ xbm_load (f, img)
                                          background);
 
       if (in_memory_file_p)
-       success_p = xbm_load_image (f, img, XSTRING (data)->data,
-                                   (XSTRING (data)->data
-                                    + STRING_BYTES (XSTRING (data))));
+       success_p = xbm_load_image (f, img, SDATA (data),
+                                   (SDATA (data)
+                                    + SBYTES (data)));
       else
        {
          if (VECTORP (data))
@@ -7018,13 +7329,13 @@ xbm_load (f, img)
                {
                  Lisp_Object line = XVECTOR (data)->contents[i];
                  if (STRINGP (line))
-                   bcopy (XSTRING (line)->data, p, nbytes);
+                   bcopy (SDATA (line), p, nbytes);
                  else
                    bcopy (XBOOL_VECTOR (line)->data, p, nbytes);
                }
            }
          else if (STRINGP (data))
-           bits = XSTRING (data)->data;
+           bits = SDATA (data);
          else
            bits = XBOOL_VECTOR (data)->data;
 
@@ -7083,6 +7394,7 @@ enum xpm_keyword_index
   XPM_HEURISTIC_MASK,
   XPM_MASK,
   XPM_COLOR_SYMBOLS,
+  XPM_BACKGROUND,
   XPM_LAST
 };
 
@@ -7100,7 +7412,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.  */
@@ -7424,10 +7737,10 @@ xpm_load (f, img)
        {
          Lisp_Object name = XCAR (XCAR (tail));
          Lisp_Object color = XCDR (XCAR (tail));
-         xpm_syms[i].name = (char *) alloca (XSTRING (name)->size + 1);
-         strcpy (xpm_syms[i].name, XSTRING (name)->data);
-         xpm_syms[i].value = (char *) alloca (XSTRING (color)->size + 1);
-         strcpy (xpm_syms[i].value, XSTRING (color)->data);
+         xpm_syms[i].name = (char *) alloca (SCHARS (name) + 1);
+         strcpy (xpm_syms[i].name, SDATA (name));
+         xpm_syms[i].value = (char *) alloca (SCHARS (color) + 1);
+         strcpy (xpm_syms[i].value, SDATA (color));
        }
     }
 
@@ -7448,14 +7761,14 @@ xpm_load (f, img)
        }
       
       rc = XpmReadFileToPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                               XSTRING (file)->data, &img->pixmap, &img->mask,
+                               SDATA (file), &img->pixmap, &img->mask,
                                &attrs);
     }
   else
     {
       Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL);
       rc = XpmCreatePixmapFromBuffer (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                                     XSTRING (buffer)->data,
+                                     SDATA (buffer),
                                      &img->pixmap, &img->mask,
                                      &attrs);
     }
@@ -7717,10 +8030,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 +8356,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 +8377,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 +8393,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 +8408,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);
@@ -8288,7 +8568,7 @@ pbm_load (f, img)
          return 0;
        }
 
-      contents = slurp_file (XSTRING (file)->data, &size);
+      contents = slurp_file (SDATA (file), &size);
       if (contents == NULL)
        {
          image_error ("Error reading `%s'", file, Qnil);
@@ -8303,8 +8583,8 @@ pbm_load (f, img)
     {
       Lisp_Object data;
       data = image_spec_value (img->spec, QCdata, NULL);
-      p = XSTRING (data)->data;
-      end = p + STRING_BYTES (XSTRING (data));
+      p = SDATA (data);
+      end = p + SBYTES (data);
     }
 
   /* Check magic number.  */
@@ -8389,7 +8669,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 +8736,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 +8785,7 @@ enum png_keyword_index
   PNG_ALGORITHM,
   PNG_HEURISTIC_MASK,
   PNG_MASK,
+  PNG_BACKGROUND,
   PNG_LAST
 };
 
@@ -8513,7 +8802,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 +8912,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 */
@@ -8644,7 +8933,7 @@ png_load (f, img)
        }
 
       /* Open the image file.  */
-      fp = fopen (XSTRING (file)->data, "rb");
+      fp = fopen (SDATA (file), "rb");
       if (!fp)
        {
          image_error ("Cannot open image file `%s'", file, Qnil);
@@ -8666,8 +8955,8 @@ png_load (f, img)
   else
     {
       /* Read from memory.  */
-      tbr.bytes = XSTRING (specified_data)->data;
-      tbr.len = STRING_BYTES (XSTRING (specified_data));
+      tbr.bytes = SDATA (specified_data);
+      tbr.len = SBYTES (specified_data);
       tbr.index = 0;
 
       /* Check PNG signature.  */
@@ -8760,36 +9049,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, SDATA (specified_bg), &color, 0))
+           {
+             png_color_16 user_bg;
 
-      if (png_get_bKGD (png_ptr, info_ptr, &image_background))
+             bzero (&user_bg, sizeof user_bg);
+             user_bg.red = color.red;
+             user_bg.green = color.green;
+             user_bg.blue = color.blue;
+
+             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 +9208,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 +9232,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 +9242,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 +9299,7 @@ enum jpeg_keyword_index
   JPEG_ALGORITHM,
   JPEG_HEURISTIC_MASK,
   JPEG_MASK,
+  JPEG_BACKGROUND,
   JPEG_LAST
 };
 
@@ -8990,7 +9316,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'.  */
@@ -9172,7 +9499,7 @@ jpeg_load (f, img)
          return 0;
        }
   
-      fp = fopen (XSTRING (file)->data, "r");
+      fp = fopen (SDATA (file), "r");
       if (fp == NULL)
        {
          image_error ("Cannot open `%s'", file, Qnil);
@@ -9219,8 +9546,8 @@ jpeg_load (f, img)
   if (NILP (specified_data))
     jpeg_stdio_src (&cinfo, (FILE *) fp);
   else
-    jpeg_memory_src (&cinfo, XSTRING (specified_data)->data,
-                    STRING_BYTES (XSTRING (specified_data)));
+    jpeg_memory_src (&cinfo, SDATA (specified_data),
+                    SBYTES (specified_data));
 
   jpeg_read_header (&cinfo, TRUE);
 
@@ -9289,6 +9616,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 +9660,7 @@ enum tiff_keyword_index
   TIFF_ALGORITHM,
   TIFF_HEURISTIC_MASK,
   TIFF_MASK,
+  TIFF_BACKGROUND,
   TIFF_LAST
 };
 
@@ -9345,7 +9677,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'.  */
@@ -9560,7 +9893,7 @@ tiff_load (f, img)
        }
          
       /* Try to open the image file.  */
-      tiff = TIFFOpen (XSTRING (file)->data, "r");
+      tiff = TIFFOpen (SDATA (file), "r");
       if (tiff == NULL)
        {
          image_error ("Cannot open `%s'", file, Qnil);
@@ -9571,8 +9904,8 @@ tiff_load (f, img)
   else
     {
       /* Memory source! */
-      memsrc.bytes = XSTRING (specified_data)->data;
-      memsrc.len = STRING_BYTES (XSTRING (specified_data));
+      memsrc.bytes = SDATA (specified_data);
+      memsrc.len = SBYTES (specified_data);
       memsrc.index = 0;
 
       tiff = TIFFClientOpen ("memory_source", "r", &memsrc,
@@ -9637,14 +9970,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 +10020,7 @@ enum gif_keyword_index
   GIF_HEURISTIC_MASK,
   GIF_MASK,
   GIF_IMAGE,
+  GIF_BACKGROUND,
   GIF_LAST
 };
 
@@ -9700,7 +10038,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'.  */
@@ -9803,7 +10142,7 @@ gif_load (f, img)
        }
   
       /* Open the GIF file.  */
-      gif = DGifOpenFileName (XSTRING (file)->data);
+      gif = DGifOpenFileName (SDATA (file));
       if (gif == NULL)
        {
          image_error ("Cannot open `%s'", file, Qnil);
@@ -9815,8 +10154,8 @@ gif_load (f, img)
     {
       /* Read from memory! */
       current_gif_memory_src = &memsrc;
-      memsrc.bytes = XSTRING (specified_data)->data;
-      memsrc.len = STRING_BYTES (XSTRING (specified_data));
+      memsrc.bytes = SDATA (specified_data);
+      memsrc.len = SBYTES (specified_data);
       memsrc.index = 0;
 
       gif = DGifOpen(&memsrc, gif_read_from_memory);
@@ -9849,8 +10188,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 +10287,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 +10336,7 @@ enum gs_keyword_index
   GS_ALGORITHM,
   GS_HEURISTIC_MASK,
   GS_MASK,
+  GS_BACKGROUND,
   GS_LAST
 };
 
@@ -10012,7 +10356,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,23 +10592,23 @@ 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);
+  prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
   XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                   prop_atom, XA_STRING, 8, PropModeReplace,
-                  XSTRING (value)->data, XSTRING (value)->size);
+                  SDATA (value), SCHARS (value));
 
   /* Make sure the property is set when we return.  */
   XFlush (FRAME_X_DISPLAY (f));
@@ -10275,17 +10620,17 @@ 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);
+  prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
   XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), prop_atom);
 
   /* Make sure the property is removed when we return.  */
@@ -10298,11 +10643,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,9 +10659,9 @@ 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);
+  prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
   rc = XGetWindowProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                           prop_atom, 0, 0, False, XA_STRING,
                           &actual_type, &actual_format, &actual_size,
@@ -10587,7 +10932,7 @@ x_create_tip_frame (dpyinfo, parms, text)
   Lisp_Object name;
   long window_prompting = 0;
   int width, height;
-  int count = BINDING_STACK_SIZE ();
+  int count = SPECPDL_INDEX ();
   struct gcpro gcpro1, gcpro2, gcpro3;
   struct kboard *kb;
   int face_change_count_before = face_change_count;
@@ -10709,9 +11054,9 @@ x_create_tip_frame (dpyinfo, parms, text)
       {
        tem = Fquery_fontset (font, Qnil);
        if (STRINGP (tem))
-         font = x_new_fontset (f, XSTRING (tem)->data);
+         font = x_new_fontset (f, SDATA (tem));
        else
-         font = x_new_font (f, XSTRING (font)->data);
+         font = x_new_font (f, SDATA (font));
       }
     
     /* Try out a font which we hope has bold and italic variations.  */
@@ -10913,7 +11258,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 +11278,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,41 +11311,40 @@ 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;
   int i, width, height;
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
   int old_windows_or_buffers_changed = windows_or_buffers_changed;
-  int count = BINDING_STACK_SIZE ();
+  int count = SPECPDL_INDEX ();
   
   specbind (Qinhibit_redisplay, Qt);
 
   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 +11499,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;
@@ -11167,7 +11516,7 @@ Value is t if tooltip was open, nil otherwise.  */
   GCPRO2 (frame, timer);
   tip_frame = tip_timer = deleted = Qnil;
   
-  count = BINDING_STACK_SIZE ();
+  count = SPECPDL_INDEX ();
   specbind (Qinhibit_redisplay, Qt);
   specbind (Qinhibit_quit, Qt);
   
@@ -11240,12 +11589,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;
@@ -11256,12 +11605,12 @@ selection dialog's entry field, if MUSTMATCH is non-nil.  */
   int ac = 0;
   extern XtAppContext Xt_app_con;
   XmString dir_xmstring, pattern_xmstring;
-  int count = specpdl_ptr - specpdl;
+  int count = SPECPDL_INDEX ();
   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);
@@ -11271,10 +11620,10 @@ selection dialog's entry field, if MUSTMATCH is non-nil.  */
   /* Create the dialog with PROMPT as title, using DIR as initial
      directory and using "*" as pattern.  */
   dir = Fexpand_file_name (dir, Qnil);
-  dir_xmstring = XmStringCreateLocalized (XSTRING (dir)->data);
+  dir_xmstring = XmStringCreateLocalized (SDATA (dir));
   pattern_xmstring = XmStringCreateLocalized ("*");
     
-  XtSetArg (al[ac], XmNtitle, XSTRING (prompt)->data); ++ac;
+  XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac;
   XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac;
   XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac;
   XtSetArg (al[ac], XmNresizePolicy, XmRESIZE_GROW); ++ac;
@@ -11325,7 +11674,7 @@ selection dialog's entry field, if MUSTMATCH is non-nil.  */
       int item_pos;
 
       default_xmstring
-       = XmStringCreateLocalized (XSTRING (default_filename)->data);
+       = XmStringCreateLocalized (SDATA (default_filename));
 
       if (!XmListItemExists (list, default_xmstring))
        {
@@ -11398,11 +11747,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
@@ -11493,6 +11842,8 @@ syms_of_xfns ()
   staticpro (&Qauto_lower);
   Qbar = intern ("bar");
   staticpro (&Qbar);
+  Qhbar = intern ("hbar");
+  staticpro (&Qhbar);
   Qborder_color = intern ("border-color");
   staticpro (&Qborder_color);
   Qborder_width = intern ("border-width");
@@ -11563,6 +11914,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 +11954,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 +11982,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 +11995,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 +12057,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 +12066,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 +12078,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 +12134,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");