]> code.delx.au - gnu-emacs/blobdiff - src/xfns.c
Merge from origin/emacs-24
[gnu-emacs] / src / xfns.c
index b21228a8697b85052f5ba51faaa533a453167348..234915a8ce2435f109c014dd800931bd8102cf1b 100644 (file)
@@ -24,6 +24,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "lisp.h"
 #include "xterm.h"
+#include "menu.h"
 #include "frame.h"
 #include "window.h"
 #include "character.h"
@@ -45,12 +46,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <sys/types.h>
 #include <sys/stat.h>
 
-#if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work.  */
 #include "bitmaps/gray.xbm"
-#else
-#include <X11/bitmaps/gray>
-#endif
-
 #include "xsettings.h"
 
 #ifdef HAVE_XRANDR
@@ -124,11 +120,6 @@ extern LWLIB_ID widget_id_tick;
 
 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
 
-static Lisp_Object Qsuppress_icon;
-static Lisp_Object Qundefined_color;
-static Lisp_Object Qcompound_text, Qcancel_timer;
-Lisp_Object Qfont_param;
-
 #ifdef GLYPH_DEBUG
 static ptrdiff_t image_cache_refcount;
 static int dpyinfo_refcount;
@@ -159,7 +150,7 @@ check_x_display_info (Lisp_Object object)
     }
   else if (TERMINALP (object))
     {
-      struct terminal *t = get_terminal (object, 1);
+      struct terminal *t = decode_live_terminal (object);
 
       if (t->type != output_x_window)
         error ("Terminal %d is not an X display", t->id);
@@ -186,7 +177,7 @@ x_real_positions (struct frame *f, int *xptr, int *yptr)
 {
   int win_x, win_y, outer_x IF_LINT (= 0), outer_y IF_LINT (= 0);
   int real_x = 0, real_y = 0;
-  int had_errors = 0;
+  bool had_errors = false;
   Window win = f->output_data.x->parent_desc;
   Atom actual_type;
   unsigned long actual_size, bytes_remaining;
@@ -329,8 +320,43 @@ x_real_positions (struct frame *f, int *xptr, int *yptr)
   *yptr = real_y;
 }
 
-\f
+/* Get the mouse position in frame relative coordinates.  */
+
+void
+x_relative_mouse_position (struct frame *f, int *x, int *y)
+{
+  Window root, dummy_window;
+  int dummy;
+
+  eassert (FRAME_X_P (f));
+
+  block_input ();
+
+  XQueryPointer (FRAME_X_DISPLAY (f),
+                 DefaultRootWindow (FRAME_X_DISPLAY (f)),
+
+                 /* The root window which contains the pointer.  */
+                 &root,
+
+                 /* Window pointer is on, not used  */
+                 &dummy_window,
+
+                 /* The position on that root window.  */
+                 x, y,
 
+                 /* x/y in dummy_window coordinates, not used.  */
+                 &dummy, &dummy,
+
+                 /* Modifier keys and pointer buttons, about which
+                    we don't care.  */
+                 (unsigned int *) &dummy);
+
+  unblock_input ();
+
+  /* Translate root window coordinates to window coordinates.  */
+  *x -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
+  *y -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
+}
 
 /* Gamma-correct COLOR on frame F.  */
 
@@ -355,7 +381,7 @@ bool
 x_defined_color (struct frame *f, const char *color_name,
                 XColor *color, bool alloc_p)
 {
-  bool success_p = 0;
+  bool success_p = false;
   Display *dpy = FRAME_X_DISPLAY (f);
   Colormap cmap = FRAME_X_COLORMAP (f);
 
@@ -384,9 +410,9 @@ x_decode_color (struct frame *f, Lisp_Object color_name, int mono_color)
 
   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 false /* 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 (SDATA (color_name), "black") == 0)
     return BLACK_PIX_DEFAULT (f);
   else if (strcmp (SDATA (color_name), "white") == 0)
@@ -399,7 +425,7 @@ x_decode_color (struct frame *f, Lisp_Object color_name, int mono_color)
 
   /* x_defined_color is responsible for coping with failures
      by looking for a near-miss.  */
-  if (x_defined_color (f, SSDATA (color_name), &cdef, 1))
+  if (x_defined_color (f, SSDATA (color_name), &cdef, true))
     return cdef.pixel;
 
   signal_error ("Undefined color", color_name);
@@ -422,15 +448,23 @@ x_set_tool_bar_position (struct frame *f,
                          Lisp_Object new_value,
                          Lisp_Object old_value)
 {
-  if (! EQ (new_value, Qleft) && ! EQ (new_value, Qright)
-      && ! EQ (new_value, Qbottom) && ! EQ (new_value, Qtop))
-    return;
-  if (EQ (new_value, old_value)) return;
+  Lisp_Object choice = list4 (Qleft, Qright, Qtop, Qbottom);
 
+  if (!NILP (Fmemq (new_value, choice)))
+    {
 #ifdef USE_GTK
-  xg_change_toolbar_position (f, new_value);
-  fset_tool_bar_position (f, new_value);
+      if (!EQ (new_value, old_value))
+       {
+         xg_change_toolbar_position (f, new_value);
+         fset_tool_bar_position (f, new_value);
+       }
+#else
+      if (!EQ (new_value, Qtop))
+       error ("The only supported tool bar position is top");
 #endif
+    }
+  else
+    wrong_choice (choice, new_value);
 }
 
 #ifdef USE_GTK
@@ -438,10 +472,10 @@ x_set_tool_bar_position (struct frame *f,
 /* Set icon from FILE for frame F.  By using GTK functions the icon
    may be any format that GdkPixbuf knows about, i.e. not just bitmaps.  */
 
-int
+bool
 xg_set_icon (struct frame *f, Lisp_Object file)
 {
-  int result = 0;
+  bool result = false;
   Lisp_Object found;
 
   found = x_find_image_file (file);
@@ -461,7 +495,7 @@ xg_set_icon (struct frame *f, Lisp_Object file)
                               pixbuf);
          g_object_unref (pixbuf);
 
-         result = 1;
+         result = true;
        }
       else
        g_error_free (err);
@@ -472,17 +506,17 @@ xg_set_icon (struct frame *f, Lisp_Object file)
   return result;
 }
 
-int
+bool
 xg_set_icon_from_xpm_data (struct frame *f, const char **data)
 {
   GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data (data);
 
   if (!pixbuf)
-    return 0;
+    return false;
 
   gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
   g_object_unref (pixbuf);
-  return 1;
+  return true;
 }
 #endif /* USE_GTK */
 
@@ -577,35 +611,6 @@ x_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
     }
 }
 
-static Cursor
-make_invisible_cursor (struct frame *f)
-{
-  Display *dpy = FRAME_X_DISPLAY (f);
-  static char const no_data[] = { 0 };
-  Pixmap pix;
-  XColor col;
-  Cursor c = 0;
-
-  x_catch_errors (dpy);
-  pix = XCreateBitmapFromData (dpy, FRAME_DISPLAY_INFO (f)->root_window,
-                               no_data, 1, 1);
-  if (! x_had_errors_p (dpy) && pix != None)
-    {
-      Cursor pixc;
-      col.pixel = 0;
-      col.red = col.green = col.blue = 0;
-      col.flags = DoRed | DoGreen | DoBlue;
-      pixc = XCreatePixmapCursor (dpy, pix, pix, &col, &col, 0, 0);
-      if (! x_had_errors_p (dpy) && pixc != None)
-        c = pixc;
-      XFreePixmap (dpy, pix);
-    }
-
-  x_uncatch_errors ();
-
-  return c;
-}
-
 static void
 x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 {
@@ -723,9 +728,6 @@ x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
     XDefineCursor (dpy, FRAME_X_WINDOW (f),
                    f->output_data.x->current_cursor = cursor);
 
-  if (FRAME_DISPLAY_INFO (f)->invisible_cursor == 0)
-    FRAME_DISPLAY_INFO (f)->invisible_cursor = make_invisible_cursor (f);
-
   if (cursor != x->text_cursor
       && x->text_cursor != 0)
     XFreeCursor (dpy, x->text_cursor);
@@ -771,20 +773,20 @@ static void
 x_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 {
   unsigned long fore_pixel, pixel;
-  bool fore_pixel_allocated_p = 0, pixel_allocated_p = 0;
+  bool fore_pixel_allocated_p = false, pixel_allocated_p = false;
   struct x_output *x = f->output_data.x;
 
   if (!NILP (Vx_cursor_fore_pixel))
     {
       fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
                                   WHITE_PIX_DEFAULT (f));
-      fore_pixel_allocated_p = 1;
+      fore_pixel_allocated_p = true;
     }
   else
     fore_pixel = FRAME_BACKGROUND_PIXEL (f);
 
   pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
-  pixel_allocated_p = 1;
+  pixel_allocated_p = true;
 
   /* Make sure that the cursor color differs from the background color.  */
   if (pixel == FRAME_BACKGROUND_PIXEL (f))
@@ -792,7 +794,7 @@ x_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
       if (pixel_allocated_p)
        {
          x_free_colors (f, &pixel, 1);
-         pixel_allocated_p = 0;
+         pixel_allocated_p = false;
        }
 
       pixel = x->mouse_pixel;
@@ -801,7 +803,7 @@ x_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
          if (fore_pixel_allocated_p)
            {
              x_free_colors (f, &fore_pixel, 1);
-             fore_pixel_allocated_p = 0;
+             fore_pixel_allocated_p = false;
            }
          fore_pixel = FRAME_BACKGROUND_PIXEL (f);
        }
@@ -826,8 +828,8 @@ x_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 
       if (FRAME_VISIBLE_P (f))
        {
-         x_update_cursor (f, 0);
-         x_update_cursor (f, 1);
+         x_update_cursor (f, false);
+         x_update_cursor (f, true);
        }
     }
 
@@ -887,7 +889,7 @@ x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 static void
 x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 {
-  int result;
+  bool result;
 
   if (STRINGP (arg))
     {
@@ -919,7 +921,7 @@ x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 static void
 x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 {
-  int result;
+  bool result;
 
   if (STRINGP (arg))
     {
@@ -954,7 +956,7 @@ x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 }
 
 \f
-void
+static void
 x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
 {
   int nlines;
@@ -985,7 +987,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
       FRAME_EXTERNAL_MENU_BAR (f) = 1;
       if (FRAME_X_P (f) && f->output_data.x->menubar_widget == 0)
        /* Make sure next redisplay shows the menu bar.  */
-       XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = 1;
+       XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = true;
     }
   else
     {
@@ -998,7 +1000,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
 #else /* not USE_X_TOOLKIT && not USE_GTK */
   FRAME_MENU_BAR_LINES (f) = nlines;
   FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
-  resize_frame_windows (f, FRAME_TEXT_HEIGHT (f), 0, 1);
+  adjust_frame_size (f, -1, -1, 2, true, Qmenu_bar_lines);
   if (FRAME_X_WINDOW (f))
     x_clear_under_internal_border (f);
 
@@ -1049,14 +1051,10 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
    height of all windows on frame F to match the new tool bar height.
    The frame's height doesn't change.  */
 
-void
+static void
 x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
 {
   int nlines;
-#if ! defined (USE_GTK)
-  int delta, root_height;
-  int unit = FRAME_LINE_HEIGHT (f);
-#endif
 
   /* Treat tool bars like menu bars.  */
   if (FRAME_MINIBUF_ONLY_P (f))
@@ -1068,57 +1066,46 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
   else
     nlines = 0;
 
-#ifdef USE_GTK
+  x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
+}
 
+
+/* Set the pixel height of the tool bar of frame F to HEIGHT.  */
+void
+x_change_tool_bar_height (struct frame *f, int height)
+{
+#ifdef USE_GTK
   FRAME_TOOL_BAR_LINES (f) = 0;
   FRAME_TOOL_BAR_HEIGHT (f) = 0;
-  if (nlines)
+  if (height)
     {
-      FRAME_EXTERNAL_TOOL_BAR (f) = 1;
+      FRAME_EXTERNAL_TOOL_BAR (f) = true;
       if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0)
        /* Make sure next redisplay shows the tool bar.  */
-       XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = 1;
+       XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = true;
       update_frame_tool_bar (f);
     }
   else
     {
       if (FRAME_EXTERNAL_TOOL_BAR (f))
         free_frame_tool_bar (f);
-      FRAME_EXTERNAL_TOOL_BAR (f) = 0;
+      FRAME_EXTERNAL_TOOL_BAR (f) = false;
     }
-
 #else /* !USE_GTK */
+  int unit = FRAME_LINE_HEIGHT (f);
+  int old_height = FRAME_TOOL_BAR_HEIGHT (f);
+  int lines = (height + unit - 1) / unit;
 
   /* Make sure we redisplay all windows in this frame.  */
   windows_or_buffers_changed = 60;
 
-  /* DELTA is in pixels now.  */
-  delta = (nlines - FRAME_TOOL_BAR_LINES (f)) * unit;
 
-  /* Don't resize the tool-bar to more than we have room for.  Note: The
-     calculations below and the subsequent call to resize_frame_windows
-     are inherently flawed because they can make the toolbar higher than
-     the containing frame.  */
-  if (delta > 0)
-    {
-      root_height = WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f)));
-      if (root_height - delta < unit)
-       {
-         delta = root_height - unit;
-         /* When creating a new frame and toolbar mode is enabled, we
-            need at least one toolbar line.  */
-         nlines = max (FRAME_TOOL_BAR_LINES (f) + delta / unit, 1);
-       }
-    }
-
-  FRAME_TOOL_BAR_LINES (f) = nlines;
-  FRAME_TOOL_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
-  resize_frame_windows (f, FRAME_TEXT_HEIGHT (f), 0, 1);
-#if !defined USE_X_TOOLKIT && !defined USE_GTK
-  if (FRAME_X_WINDOW (f))
-    x_clear_under_internal_border (f);
-#endif
-  adjust_frame_glyphs (f);
+  /* Recalculate tool bar and frame text sizes.  */
+  FRAME_TOOL_BAR_HEIGHT (f) = height;
+  FRAME_TOOL_BAR_LINES (f) = lines;
+  /* Store the `tool-bar-lines' and `height' frame parameters.  */
+  store_frame_param (f, Qtool_bar_lines, make_number (lines));
+  store_frame_param (f, Qheight, make_number (FRAME_LINES (f)));
 
   /* We also have to make sure that the internal border at the top of
      the frame, below the menu bar or tool bar, is redrawn when the
@@ -1132,30 +1119,58 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
       clear_current_matrices (f);
     }
 
-  /* If the tool bar gets smaller, the internal border below it
-     has to be cleared.  It was formerly part of the display
-     of the larger tool bar, and updating windows won't clear it.  */
-  if (delta < 0)
+  if ((height < old_height) && WINDOWP (f->tool_bar_window))
+    clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
+
+  /* Recalculate toolbar height.  */
+  f->n_tool_bar_rows = 0;
+
+  adjust_frame_size (f, -1, -1,
+                    (!f->tool_bar_redisplayed_once ? 1
+                     : (old_height == 0 || height == 0) ? 2
+                     : 4),
+                    false, Qtool_bar_lines);
+
+  /* adjust_frame_size might not have done anything, garbage frame
+     here.  */
+  adjust_frame_glyphs (f);
+  SET_FRAME_GARBAGED (f);
+  if (FRAME_X_WINDOW (f))
+    x_clear_under_internal_border (f);
+
+#endif /* USE_GTK */
+}
+
+
+static void
+x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+  int border;
+
+  CHECK_TYPE_RANGED_INTEGER (int, arg);
+  border = max (XINT (arg), 0);
+
+  if (border != FRAME_INTERNAL_BORDER_WIDTH (f))
     {
-      int height = FRAME_INTERNAL_BORDER_WIDTH (f);
-      int width = FRAME_PIXEL_WIDTH (f);
-      int y = nlines * unit;
+      FRAME_INTERNAL_BORDER_WIDTH (f) = border;
 
-      /* height can be zero here. */
-      if (height > 0 && width > 0)
+#ifdef USE_X_TOOLKIT
+      if (FRAME_X_OUTPUT (f)->edit_widget)
+       widget_store_internal_border (FRAME_X_OUTPUT (f)->edit_widget);
+#endif
+
+      if (FRAME_X_WINDOW (f) != 0)
        {
-          block_input ();
-         x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                       0, y, width, height);
-          unblock_input ();
-        }
+         adjust_frame_size (f, -1, -1, 3, false, Qinternal_border_width);
 
-      if (WINDOWP (f->tool_bar_window))
-       clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
+#ifdef USE_GTK
+         xg_clear_under_internal_border (f);
+#else
+         x_clear_under_internal_border (f);
+#endif
+       }
     }
 
-  run_window_configuration_change_hook (f);
-#endif /* USE_GTK */
 }
 
 
@@ -1210,7 +1225,7 @@ x_set_scroll_bar_background (struct frame *f, Lisp_Object value, Lisp_Object old
   if (f->output_data.x->scroll_bar_background_pixel != -1)
     unload_color (f, f->output_data.x->scroll_bar_background_pixel);
 
-#ifdef USE_TOOLKIT_SCROLL_BARS
+#if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
   /* Scrollbar shadow colors.  */
   if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
     {
@@ -1222,7 +1237,7 @@ x_set_scroll_bar_background (struct frame *f, Lisp_Object value, Lisp_Object old
       unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
       f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
     }
-#endif /* USE_TOOLKIT_SCROLL_BARS */
+#endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
 
   f->output_data.x->scroll_bar_background_pixel = pixel;
   if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
@@ -1249,20 +1264,16 @@ x_set_scroll_bar_background (struct frame *f, Lisp_Object value, Lisp_Object old
    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,
+   If the text contains only ASCII and Latin-1, store true in *STRING_P,
    which means that the `encoding' of the result can be `STRING'.
-   Otherwise store 0 in *STRINGP, which means that the `encoding' of
+   Otherwise store false in *STRINGP, which means that the `encoding' of
    the result should be `COMPOUND_TEXT'.  */
 
 static unsigned char *
-x_encode_text (Lisp_Object string, Lisp_Object coding_system, int selectionp,
-              ptrdiff_t *text_bytes, int *stringp, int *freep)
+x_encode_text (Lisp_Object string, Lisp_Object coding_system,
+              ptrdiff_t *text_bytes, bool *stringp, bool *freep)
 {
   int result = string_xstring_p (string);
   struct coding_system coding;
@@ -1271,8 +1282,8 @@ x_encode_text (Lisp_Object string, Lisp_Object coding_system, int selectionp,
     {
       /* No multibyte character in OBJ.  We need not encode it.  */
       *text_bytes = SBYTES (string);
-      *stringp = 1;
-      *freep = 0;
+      *stringp = true;
+      *freep = false;
       return SDATA (string);
     }
 
@@ -1286,7 +1297,7 @@ x_encode_text (Lisp_Object string, Lisp_Object coding_system, int selectionp,
                        SCHARS (string), SBYTES (string), Qnil);
   *text_bytes = coding.produced;
   *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
-  *freep = 1;
+  *freep = true;
   return coding.destination;
 }
 
@@ -1304,8 +1315,8 @@ x_set_name_internal (struct frame *f, Lisp_Object name)
       {
        XTextProperty text, icon;
        ptrdiff_t bytes;
-       int stringp;
-        int do_free_icon_value = 0, do_free_text_value = 0;
+       bool stringp;
+       bool do_free_icon_value = false, do_free_text_value = false;
        Lisp_Object coding_system;
        Lisp_Object encoded_name;
        Lisp_Object encoded_icon_name;
@@ -1337,14 +1348,12 @@ x_set_name_internal (struct frame *f, Lisp_Object name)
           properties.  Per the EWMH specification, those two properties
           are always UTF8_STRING.  This matches what gtk_window_set_title()
           does in the USE_GTK case. */
-       text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp,
-                                   &do_free_text_value);
+       text.value = x_encode_text (name, coding_system, &bytes,
+                                   &stringp, &do_free_text_value);
        text.encoding = (stringp ? XA_STRING
                         : FRAME_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
        text.format = 8;
        text.nitems = bytes;
-       if (text.nitems != bytes)
-         error ("Window name too large");
 
        if (!STRINGP (f->icon_name))
          {
@@ -1354,14 +1363,12 @@ x_set_name_internal (struct frame *f, Lisp_Object name)
        else
          {
            /* See the above comment "Note: Encoding strategy".  */
-           icon.value = x_encode_text (f->icon_name, coding_system, 0,
-                                       &bytes, &stringp, &do_free_icon_value);
+           icon.value = x_encode_text (f->icon_name, coding_system, &bytes,
+                                       &stringp, &do_free_icon_value);
            icon.encoding = (stringp ? XA_STRING
                             : FRAME_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
            icon.format = 8;
            icon.nitems = bytes;
-           if (icon.nitems != bytes)
-             error ("Icon name too large");
 
            encoded_icon_name = ENCODE_UTF_8 (f->icon_name);
          }
@@ -1399,16 +1406,16 @@ x_set_name_internal (struct frame *f, Lisp_Object name)
 /* Change the name of frame F to NAME.  If NAME is nil, set F's name to
        x_id_name.
 
-   If EXPLICIT is non-zero, that indicates that lisp code is setting the
+   If EXPLICIT is true, that indicates that lisp code is setting the
        name; if NAME is a string, set F's name to NAME and set
        F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
 
-   If EXPLICIT is zero, that indicates that Emacs redisplay code is
+   If EXPLICIT is false, that indicates that Emacs redisplay code is
        suggesting a new name, which lisp code should override; if
        F->explicit_name is set, ignore the new name; otherwise, set it.  */
 
 static void
-x_set_name (struct frame *f, Lisp_Object name, int explicit)
+x_set_name (struct frame *f, Lisp_Object name, bool explicit)
 {
   /* Make sure that requests from lisp code override requests from
      Emacs redisplay code.  */
@@ -1457,7 +1464,7 @@ x_set_name (struct frame *f, Lisp_Object name, int explicit)
 static void
 x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 {
-  x_set_name (f, arg, 1);
+  x_set_name (f, arg, true);
 }
 
 /* This function should be called by Emacs redisplay code to set the
@@ -1466,7 +1473,7 @@ x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 void
 x_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 {
-  x_set_name (f, arg, 0);
+  x_set_name (f, arg, false);
 }
 \f
 /* Change the title of frame F to NAME.
@@ -1505,14 +1512,36 @@ x_set_scroll_bar_default_width (struct frame *f)
   FRAME_CONFIG_SCROLL_BAR_COLS (f) = (minw + unit - 1) / unit;
   FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = minw;
 #else
-  /* The width of a non-toolkit scrollbar is at least 14 pixels and a
-     multiple of the frame's character width.  */
+  /* The width of a non-toolkit scrollbar is 14 pixels.  */
   FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit;
   FRAME_CONFIG_SCROLL_BAR_WIDTH (f)
     = FRAME_CONFIG_SCROLL_BAR_COLS (f) * unit;
 #endif
 }
 
+void
+x_set_scroll_bar_default_height (struct frame *f)
+{
+  int height = FRAME_LINE_HEIGHT (f);
+#ifdef USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_GTK
+  int min_height = xg_get_default_scrollbar_height ();
+#else
+  int min_height = 16;
+#endif
+  /* A minimum height of 14 doesn't look good for toolkit scroll bars.  */
+  FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = min_height;
+  FRAME_CONFIG_SCROLL_BAR_LINES (f) = (min_height + height - 1) / height;
+#else
+  /* The height of a non-toolkit scrollbar is 14 pixels.  */
+  FRAME_CONFIG_SCROLL_BAR_LINES (f) = (14 + height - 1) / height;
+
+  /* Use all of that space (aside from required margins) for the
+     scroll bar.  */
+  FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = 14;
+#endif
+}
+
 \f
 /* Record in frame F the specified or default value according to ALIST
    of the parameter named PROP (a Lisp symbol).  If no value is
@@ -1523,7 +1552,7 @@ static Lisp_Object
 x_default_scroll_bar_color_parameter (struct frame *f,
                                      Lisp_Object alist, Lisp_Object prop,
                                      const char *xprop, const char *xclass,
-                                     int foreground_p)
+                                     bool foreground_p)
 {
   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
   Lisp_Object tem;
@@ -1535,13 +1564,14 @@ x_default_scroll_bar_color_parameter (struct frame *f,
 
       /* See if an X resource for the scroll bar color has been
         specified.  */
-      tem = display_x_get_resource (dpyinfo,
-                                   build_string (foreground_p
-                                                 ? "foreground"
-                                                 : "background"),
-                                   empty_unibyte_string,
-                                   build_string ("verticalScrollBar"),
-                                   empty_unibyte_string);
+      AUTO_STRING (foreground, "foreground");
+      AUTO_STRING (background, "foreground");
+      AUTO_STRING (verticalScrollBar, "verticalScrollBar");
+      tem = (display_x_get_resource
+            (dpyinfo, foreground_p ? foreground : background,
+             empty_unibyte_string,
+             verticalScrollBar,
+             empty_unibyte_string));
       if (!STRINGP (tem))
        {
          /* If nothing has been specified, scroll bars will use a
@@ -1559,7 +1589,8 @@ x_default_scroll_bar_color_parameter (struct frame *f,
 #endif /* not USE_TOOLKIT_SCROLL_BARS */
     }
 
-  x_set_frame_parameters (f, list1 (Fcons (prop, tem)));
+  AUTO_FRAME_ARG (arg, prop, tem);
+  x_set_frame_parameters (f, arg);
   return tem;
 }
 
@@ -1578,9 +1609,9 @@ hack_wm_protocols (struct frame *f, Widget widget)
 {
   Display *dpy = XtDisplay (widget);
   Window w = XtWindow (widget);
-  int need_delete = 1;
-  int need_focus = 1;
-  int need_save = 1;
+  bool need_delete = true;
+  bool need_focus = true;
+  bool need_save = true;
 
   block_input ();
   {
@@ -1592,7 +1623,7 @@ hack_wm_protocols (struct frame *f, Widget widget)
 
     if ((XGetWindowProperty (dpy, w,
                             FRAME_DISPLAY_INFO (f)->Xatom_wm_protocols,
-                            (long)0, (long)100, False, XA_ATOM,
+                            0, 100, False, XA_ATOM,
                             &type, &format, &nitems, &bytes_after,
                             &catoms)
         == Success)
@@ -1604,20 +1635,20 @@ hack_wm_protocols (struct frame *f, Widget widget)
            nitems--;
            if (atoms[nitems]
                == FRAME_DISPLAY_INFO (f)->Xatom_wm_delete_window)
-             need_delete = 0;
+             need_delete = false;
            else if (atoms[nitems]
                     == FRAME_DISPLAY_INFO (f)->Xatom_wm_take_focus)
-             need_focus = 0;
+             need_focus = false;
            else if (atoms[nitems]
                     == FRAME_DISPLAY_INFO (f)->Xatom_wm_save_yourself)
-             need_save = 0;
+             need_save = false;
          }
       }
     if (catoms)
       XFree (catoms);
   }
   {
-    Atom props [10];
+    Atom props[10];
     int count = 0;
     if (need_delete)
       props[count++] = FRAME_DISPLAY_INFO (f)->Xatom_wm_delete_window;
@@ -1669,17 +1700,18 @@ static const char xic_default_fontset[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
 /* Create an Xt fontset spec from the name of a base font.
    If `motif' is True use the Motif syntax.  */
 char *
-xic_create_fontsetname (const char *base_fontname, int motif)
+xic_create_fontsetname (const char *base_fontname, bool motif)
 {
   const char *sep = motif ? ";" : ",";
   char *fontsetname;
+  char *z;
 
   /* Make a fontset name from the base font name.  */
   if (xic_default_fontset == base_fontname)
     {
       /* There is no base font name, use the default.  */
       fontsetname = xmalloc (strlen (base_fontname) + 2);
-      strcpy (fontsetname, base_fontname);
+      z = stpcpy (fontsetname, base_fontname);
     }
   else
     {
@@ -1700,9 +1732,9 @@ xic_create_fontsetname (const char *base_fontname, int motif)
             Use the specified font plus the default.  */
          fontsetname = xmalloc (strlen (base_fontname)
                                 + strlen (xic_default_fontset) + 3);
-         strcpy (fontsetname, base_fontname);
-         strcat (fontsetname, sep);
-         strcat (fontsetname, xic_default_fontset);
+         z = stpcpy (fontsetname, base_fontname);
+         z = stpcpy (z, sep);
+         z = stpcpy (z, xic_default_fontset);
        }
       else
        {
@@ -1750,7 +1782,7 @@ xic_create_fontsetname (const char *base_fontname, int motif)
          len = p - base_fontname + strlen (allcs) + 1;
          font_allcs = alloca (len);
          memcpy (font_allcs, base_fontname, p - base_fontname);
-         strcat (font_allcs, allcs);
+         strcpy (font_allcs + (p - base_fontname), allcs);
 
          /* Build the font spec that matches all families and
             add-styles.  */
@@ -1758,31 +1790,31 @@ xic_create_fontsetname (const char *base_fontname, int motif)
          font_allfamilies = alloca (len);
          strcpy (font_allfamilies, allfamilies);
          memcpy (font_allfamilies + strlen (allfamilies), p1, p - p1);
-         strcat (font_allfamilies, allcs);
+         strcpy (font_allfamilies + strlen (allfamilies) + (p - p1), allcs);
 
          /* Build the font spec that matches all.  */
          len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1;
          font_all = alloca (len);
-         strcpy (font_all, allfamilies);
-         strcat (font_all, all);
-         memcpy (font_all + strlen (all) + strlen (allfamilies), p2, p - p2);
-         strcat (font_all, allcs);
+         z = stpcpy (font_all, allfamilies);
+         z = stpcpy (z, all);
+         memcpy (z, p2, p - p2);
+         strcpy (z + (p - p2), allcs);
 
          /* Build the actual font set name.  */
          len = strlen (base_fontname) + strlen (font_allcs)
            + strlen (font_allfamilies) + strlen (font_all) + 5;
          fontsetname = xmalloc (len);
-         strcpy (fontsetname, base_fontname);
-         strcat (fontsetname, sep);
-         strcat (fontsetname, font_allcs);
-         strcat (fontsetname, sep);
-         strcat (fontsetname, font_allfamilies);
-         strcat (fontsetname, sep);
-         strcat (fontsetname, font_all);
+         z = stpcpy (fontsetname, base_fontname);
+         z = stpcpy (z, sep);
+         z = stpcpy (z, font_allcs);
+         z = stpcpy (z, sep);
+         z = stpcpy (z, font_allfamilies);
+         z = stpcpy (z, sep);
+         z = stpcpy (z, font_all);
        }
     }
   if (motif)
-    return strcat (fontsetname, ":");
+    strcpy (z, ":");
   return fontsetname;
 }
 #endif /* HAVE_X_WINDOWS && USE_X_TOOLKIT */
@@ -1910,7 +1942,7 @@ void
 xic_free_xfontset (struct frame *f)
 {
   Lisp_Object rest, frame;
-  bool shared_p = 0;
+  bool shared_p = false;
 
   if (!FRAME_XIC_FONTSET (f))
     return;
@@ -1923,7 +1955,7 @@ xic_free_xfontset (struct frame *f)
           && FRAME_DISPLAY_INFO (cf) == FRAME_DISPLAY_INFO (f)
           && FRAME_XIC_FONTSET (cf) == FRAME_XIC_FONTSET (f))
         {
-          shared_p = 1;
+          shared_p = true;
           break;
         }
     }
@@ -1944,8 +1976,7 @@ static XIMStyle
 best_xim_style (XIMStyles *xim)
 {
   int i, j;
-  int nr_supported =
-    sizeof (supported_xim_styles) / sizeof (supported_xim_styles[0]);
+  int nr_supported = ARRAYELTS (supported_xim_styles);
 
   for (i = 0; i < nr_supported; ++i)
     for (j = 0; j < xim->count_styles; ++j)
@@ -2184,7 +2215,7 @@ xic_set_xfontset (struct frame *f, const char *base_fontname)
 /* Create and set up the X widget for frame F.  */
 
 static void
-x_window (struct frame *f, long window_prompting, int minibuffer_only)
+x_window (struct frame *f, long window_prompting)
 {
   XClassHint class_hints;
   XSetWindowAttributes attributes;
@@ -2192,7 +2223,7 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only)
   Widget shell_widget;
   Widget pane_widget;
   Widget frame_widget;
-  Arg al [25];
+  Arg al[25];
   int ac;
 
   block_input ();
@@ -2202,7 +2233,7 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only)
      for the window manager, so GC relocation won't bother it.
 
      Elsewhere we specify the window name for the window manager.  */
-  f->namebuf = xstrdup (SSDATA (Vx_resource_name));
+  f->namebuf = xlispstrdup (Vx_resource_name);
 
   ac = 0;
   XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
@@ -2253,8 +2284,7 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only)
 
   /* Do some needed geometry management.  */
   {
-    char *tem, shell_position[sizeof "=x++" + 4 * INT_STRLEN_BOUND (int)];
-    Arg gal[10];
+    Arg gal[3];
     int gac = 0;
     int extra_borders = 0;
     int menubar_size
@@ -2263,8 +2293,8 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only)
            + f->output_data.x->menubar_widget->core.border_width)
         : 0);
 
-#if 0 /* Experimentally, we now get the right results
-        for -geometry -0-0 without this.  24 Aug 96, rms.  */
+#if false /* Experimentally, we now get the right results
+            for -geometry -0-0 without this.  24 Aug 96, rms.  */
     if (FRAME_EXTERNAL_MENU_BAR (f))
       {
         Dimension ibw = 0;
@@ -2273,7 +2303,7 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only)
       }
 #endif
 
-    f->output_data.x->menubar_height = menubar_size;
+    FRAME_MENUBAR_HEIGHT (f) = menubar_size;
 
 #ifndef USE_LUCID
     /* Motif seems to need this amount added to the sizes
@@ -2284,6 +2314,8 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only)
     extra_borders *= 2;
 #endif
 
+    f->shell_position = xmalloc (sizeof "=x++" + 4 * INT_STRLEN_BOUND (int));
+
     /* Convert our geometry parameters into a geometry string
        and specify it.
        Note that we do not specify here whether the position
@@ -2291,23 +2323,23 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only)
        We pass that information later, in x_wm_set_size_hints.  */
     {
       int left = f->left_pos;
-      int xneg = window_prompting & XNegative;
+      bool xneg = (window_prompting & XNegative) != 0;
       int top = f->top_pos;
-      int yneg = window_prompting & YNegative;
+      bool yneg = (window_prompting & YNegative) != 0;
       if (xneg)
        left = -left;
       if (yneg)
        top = -top;
 
       if (window_prompting & USPosition)
-       sprintf (shell_position, "=%dx%d%c%d%c%d",
+       sprintf (f->shell_position, "=%dx%d%c%d%c%d",
                 FRAME_PIXEL_WIDTH (f) + extra_borders,
                 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders,
                 (xneg ? '-' : '+'), left,
                 (yneg ? '-' : '+'), top);
       else
         {
-          sprintf (shell_position, "=%dx%d",
+          sprintf (f->shell_position, "=%dx%d",
                    FRAME_PIXEL_WIDTH (f) + extra_borders,
                    FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders);
 
@@ -2321,12 +2353,7 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only)
         }
     }
 
-    /* We don't free this because we don't know whether
-       it is safe to free it while the frame exists.
-       It isn't worth the trouble of arranging to free it
-       when the frame is deleted.  */
-    tem = xstrdup (shell_position);
-    XtSetArg (gal[gac], XtNgeometry, tem); gac++;
+    XtSetArg (gal[gac], XtNgeometry, f->shell_position); gac++;
     XtSetValues (shell_widget, gal, gac);
   }
 
@@ -2395,9 +2422,9 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only)
      the X server hasn't been told.  */
   {
     Lisp_Object name;
-    int explicit = f->explicit_name;
+    bool explicit = f->explicit_name;
 
-    f->explicit_name = 0;
+    f->explicit_name = false;
     name = f->name;
     fset_name (f, Qnil);
     x_set_name (f, name, explicit);
@@ -2509,10 +2536,6 @@ x_window (struct frame *f)
   class_hints.res_class = SSDATA (Vx_resource_class);
   XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints);
 
-  /* The menubar is part of the ordinary display;
-     it does not count in addition to the height of the window.  */
-  f->output_data.x->menubar_height = 0;
-
   /* This indicates that we use the "Passive Input" input model.
      Unless we do this, we don't get the Focus{In,Out} events that we
      need to draw the cursor correctly.  Accursed bureaucrats.
@@ -2538,9 +2561,9 @@ x_window (struct frame *f)
      the X server hasn't been told.  */
   {
     Lisp_Object name;
-    int explicit = f->explicit_name;
+    bool explicit = f->explicit_name;
 
-    f->explicit_name = 0;
+    f->explicit_name = false;
     name = f->name;
     fset_name (f, Qnil);
     x_set_name (f, name, explicit);
@@ -2586,15 +2609,12 @@ x_icon_verify (struct frame *f, Lisp_Object parms)
 static void
 x_icon (struct frame *f, Lisp_Object parms)
 {
-  Lisp_Object icon_x, icon_y;
-#if 0
-  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
-#endif
-
   /* Set the position of the icon.  Note that twm groups all
      icons in an icon window.  */
-  icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
-  icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
+  Lisp_Object icon_x
+    = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
+  Lisp_Object icon_y
+    = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
   if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
     {
       CHECK_TYPE_RANGED_INTEGER (int, icon_x);
@@ -2608,9 +2628,10 @@ x_icon (struct frame *f, Lisp_Object parms)
   if (! EQ (icon_x, Qunbound))
     x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
 
-#if 0 /* x_get_arg removes the visibility parameter as a side effect,
-         but x_create_frame still needs it.  */
+#if false /* x_get_arg removes the visibility parameter as a side effect,
+            but x_create_frame still needs it.  */
   /* Start up iconic or window? */
+  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
   x_wm_set_window_state
     (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL),
             Qicon)
@@ -2761,12 +2782,6 @@ do_unwind_create_frame (Lisp_Object frame)
   unwind_create_frame (frame);
 }
 
-static void
-unwind_create_frame_1 (Lisp_Object val)
-{
-  inhibit_lisp_code = val;
-}
-
 static void
 x_default_font_parameter (struct frame *f, Lisp_Object parms)
 {
@@ -2825,7 +2840,8 @@ x_default_font_parameter (struct frame *f, Lisp_Object parms)
     {
       /* Remember the explicit font parameter, so we can re-apply it after
         we've applied the `default' face settings.  */
-      x_set_frame_parameters (f, list1 (Fcons (Qfont_param, font_param)));
+      AUTO_FRAME_ARG (arg, Qfont_param, font_param);
+      x_set_frame_parameters (f, arg);
     }
 
   /* This call will make X resources override any system font setting.  */
@@ -2843,7 +2859,7 @@ Signal error if FRAME is not an X frame.  */)
   struct frame *f = decode_window_system_frame (frame);
 
   block_input ();
-  x_wm_set_size_hint (f, 0, 0);
+  x_wm_set_size_hint (f, 0, false);
   unblock_input ();
   return Qnil;
 }
@@ -2851,29 +2867,31 @@ Signal error if FRAME is not an X frame.  */)
 static void
 set_machine_and_pid_properties (struct frame *f)
 {
-  long pid = (long) getpid ();
-
   /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME.  */
   XSetWMProperties (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), NULL, NULL,
                     NULL, 0, NULL, NULL, NULL);
-  XChangeProperty (FRAME_X_DISPLAY (f),
-                   FRAME_OUTER_WINDOW (f),
-                   XInternAtom (FRAME_X_DISPLAY (f),
-                                "_NET_WM_PID",
-                                False),
-                   XA_CARDINAL, 32, PropModeReplace,
-                   (unsigned char *) &pid, 1);
+  pid_t pid = getpid ();
+  if (pid <= 0xffffffffu)
+    {
+      unsigned long xpid = pid;
+      XChangeProperty (FRAME_X_DISPLAY (f),
+                      FRAME_OUTER_WINDOW (f),
+                      XInternAtom (FRAME_X_DISPLAY (f),
+                                   "_NET_WM_PID",
+                                   False),
+                      XA_CARDINAL, 32, PropModeReplace,
+                      (unsigned char *) &xpid, 1);
+    }
 }
 
 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
        1, 1, 0,
        doc: /* Make a new X window, which is called a "frame" in Emacs terms.
-Return an Emacs frame object.
-PARMS is an alist of frame parameters.
+Return an Emacs frame object.  PARMS is an alist of frame parameters.
 If the parameters specify that the frame should not have a minibuffer,
-and do not specify a specific minibuffer window to use,
-then `default-minibuffer-frame' must be a frame whose minibuffer can
-be shared by the new frame.
+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.  */)
   (Lisp_Object parms)
@@ -2881,10 +2899,9 @@ This function is an internal primitive--use `make-frame' instead.  */)
   struct frame *f;
   Lisp_Object frame, tem;
   Lisp_Object name;
-  int minibuffer_only = 0;
+  bool minibuffer_only = false;
   long window_prompting = 0;
-  int width, height;
-  ptrdiff_t count = SPECPDL_INDEX (), count2;
+  ptrdiff_t count = SPECPDL_INDEX ();
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
   Lisp_Object display;
   struct x_display_info *dpyinfo = NULL;
@@ -2936,12 +2953,12 @@ This function is an internal primitive--use `make-frame' instead.  */)
   else if (EQ (tem, Qonly))
     {
       f = make_minibuffer_frame ();
-      minibuffer_only = 1;
+      minibuffer_only = true;
     }
   else if (WINDOWP (tem))
     f = make_frame_without_minibuffer (tem, kb, display);
   else
-    f = make_frame (1);
+    f = make_frame (true);
 
   XSETFRAME (frame, f);
 
@@ -2953,10 +2970,10 @@ This function is an internal primitive--use `make-frame' instead.  */)
   FRAME_FONTSET (f) = -1;
   f->output_data.x->scroll_bar_foreground_pixel = -1;
   f->output_data.x->scroll_bar_background_pixel = -1;
-#ifdef USE_TOOLKIT_SCROLL_BARS
+#if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
   f->output_data.x->scroll_bar_top_shadow_pixel = -1;
   f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
-#endif /* USE_TOOLKIT_SCROLL_BARS */
+#endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
   f->output_data.x->white_relief.pixel = -1;
   f->output_data.x->black_relief.pixel = -1;
 
@@ -3005,16 +3022,15 @@ This function is an internal primitive--use `make-frame' instead.  */)
   }
 
   /* Specify the parent under which to make this X window.  */
-
   if (!NILP (parent))
     {
       f->output_data.x->parent_desc = (Window) XFASTINT (parent);
-      f->output_data.x->explicit_parent = 1;
+      f->output_data.x->explicit_parent = true;
     }
   else
     {
       f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
-      f->output_data.x->explicit_parent = 0;
+      f->output_data.x->explicit_parent = false;
     }
 
   /* Set the name; the functions to which we pass f expect the name to
@@ -3022,13 +3038,13 @@ This function is an internal primitive--use `make-frame' instead.  */)
   if (EQ (name, Qunbound) || NILP (name))
     {
       fset_name (f, build_string (dpyinfo->x_id_name));
-      f->explicit_name = 0;
+      f->explicit_name = false;
     }
   else
     {
       fset_name (f, name);
-      f->explicit_name = 1;
-      /* use the frame's title when getting resources for this frame.  */
+      f->explicit_name = true;
+      /* Use the frame's title when getting resources for this frame.  */
       specbind (Qx_resource_name, name);
     }
 
@@ -3091,7 +3107,9 @@ This function is an internal primitive--use `make-frame' instead.  */)
 #endif
                       "verticalScrollBars", "ScrollBars",
                       RES_TYPE_SYMBOL);
-
+  x_default_parameter (f, parms, Qhorizontal_scroll_bars, Qnil,
+                      "horizontalScrollBars", "ScrollBars",
+                      RES_TYPE_SYMBOL);
   /* Also do the stuff which must be set before the window exists.  */
   x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
                       "foreground", "Foreground", RES_TYPE_STRING);
@@ -3112,10 +3130,10 @@ This function is an internal primitive--use `make-frame' instead.  */)
 
   x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
                                        "scrollBarForeground",
-                                       "ScrollBarForeground", 1);
+                                       "ScrollBarForeground", true);
   x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_background,
                                        "scrollBarBackground",
-                                       "ScrollBarBackground", 0);
+                                       "ScrollBarBackground", false);
 
 #ifdef GLYPH_DEBUG
   image_cache_refcount =
@@ -3123,32 +3141,23 @@ This function is an internal primitive--use `make-frame' instead.  */)
   dpyinfo_refcount = dpyinfo->reference_count;
 #endif /* GLYPH_DEBUG */
 
-  /* Init faces before x_default_parameter is called for scroll-bar
-     parameters because that function calls x_set_scroll_bar_width,
-     which calls change_frame_size, which calls Fset_window_buffer,
-     which runs hooks, which call Fvertical_motion.  At the end, we
-     end up in init_iterator with a null face cache, which should not
-     happen.  */
+  /* Init faces before x_default_parameter is called for the
+     scroll-bar-width parameter because otherwise we end up in
+     init_iterator with a null face cache, which should not happen.  */
   init_frame_faces (f);
-  
-  /* Temporary disable window-configuration-change-hook to avoid
-     an infloop in next_frame and access to uninitialized frame
-     from Lisp code (Bug#18161).  */
-
-  count2 = SPECPDL_INDEX ();
-  record_unwind_protect (unwind_create_frame_1, inhibit_lisp_code);
-  inhibit_lisp_code = Qt;
-
-  /* PXW: This is a duplicate from below.  We have to do it here since
-     otherwise x_set_tool_bar_lines will work with the character sizes
-     installed by init_frame_faces while the frame's pixel size is still
-     calculated from a character size of 1 and we subsequently hit the
-     eassert (height >= 0) assertion in window_box_height.  The
-     non-pixelwise code apparently worked around this because it had one
-     frame line vs one toolbar line which left us with a zero root
-     window height which was obviously wrong as well ...  */
-  change_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
-                    FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 1, 0, 0, 1);
+
+  /* The following call of change_frame_size is needed since otherwise
+     x_set_tool_bar_lines will already work with the character sizes
+     installed by init_frame_faces while the frame's pixel size is
+     still calculated from a character size of 1 and we subsequently
+     hit the (height >= 0) assertion in window_box_height.
+
+     The non-pixelwise code apparently worked around this because it
+     had one frame line vs one toolbar line which left us with a zero
+     root window height which was obviously wrong as well ...  */
+  adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
+                    FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, true,
+                    Qx_create_frame_1);
 
   /* Set the menu-bar-lines and tool-bar-lines parameters.  We don't
      look up the X resources controlling the menu-bar and tool-bar
@@ -3164,8 +3173,6 @@ This function is an internal primitive--use `make-frame' instead.  */)
                       ? make_number (0) : make_number (1),
                       NULL, NULL, RES_TYPE_NUMBER);
 
-  unbind_to (count2, Qnil);
-
   x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
                       "bufferPredicate", "BufferPredicate",
                       RES_TYPE_SYMBOL);
@@ -3174,12 +3181,12 @@ This function is an internal primitive--use `make-frame' instead.  */)
   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);
+                      "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
   x_default_parameter (f, parms, Qtool_bar_position,
-                       f->tool_bar_position, 0, 0, RES_TYPE_SYMBOL);
+                       FRAME_TOOL_BAR_POSITION (f), 0, 0, RES_TYPE_SYMBOL);
 
   /* Compute the size of the X window.  */
-  window_prompting = x_figure_window_size (f, parms, 1);
+  window_prompting = x_figure_window_size (f, parms, true);
 
   tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
   f->no_split = minibuffer_only || EQ (tem, Qt);
@@ -3188,7 +3195,7 @@ This function is an internal primitive--use `make-frame' instead.  */)
 
   /* Create the X widget or window.  */
 #ifdef USE_X_TOOLKIT
-  x_window (f, window_prompting, minibuffer_only);
+  x_window (f, window_prompting);
 #else
   x_window (f);
 #endif
@@ -3215,17 +3222,17 @@ This function is an internal primitive--use `make-frame' instead.  */)
   x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
                       "scrollBarWidth", "ScrollBarWidth",
                       RES_TYPE_NUMBER);
+  x_default_parameter (f, parms, Qscroll_bar_height, Qnil,
+                      "scrollBarHeight", "ScrollBarHeight",
+                      RES_TYPE_NUMBER);
   x_default_parameter (f, parms, Qalpha, Qnil,
                       "alpha", "Alpha", RES_TYPE_NUMBER);
 
-  /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
-     Change will not be effected unless different from the current
-     FRAME_LINES (f).  */
-  width = FRAME_TEXT_WIDTH (f);
-  height = FRAME_TEXT_HEIGHT (f);
-  FRAME_TEXT_HEIGHT (f) = 0;
-  SET_FRAME_WIDTH (f, 0);
-  change_frame_size (f, width, height, 1, 0, 0, 1);
+  /* Consider frame official, now.  */
+  f->can_x_set_window_size = true;
+
+  adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, true,
+                    Qx_create_frame_2);
 
 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
   /* Create the menu bar.  */
@@ -3249,7 +3256,7 @@ This function is an internal primitive--use `make-frame' instead.  */)
      badly we want them.  This should be done after we have the menu
      bar so that its size can be taken into account.  */
   block_input ();
-  x_wm_set_size_hint (f, window_prompting, 0);
+  x_wm_set_size_hint (f, window_prompting, false);
   unblock_input ();
 
   /* Make the window appear on the frame and enable display, unless
@@ -3378,7 +3385,7 @@ DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
 
   CHECK_STRING (color);
 
-  if (x_defined_color (f, SSDATA (color), &foo, 0))
+  if (x_defined_color (f, SSDATA (color), &foo, false))
     return Qt;
   else
     return Qnil;
@@ -3393,7 +3400,7 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
 
   CHECK_STRING (color);
 
-  if (x_defined_color (f, SSDATA (color), &foo, 0))
+  if (x_defined_color (f, SSDATA (color), &foo, false))
     return list3i (foo.red, foo.green, foo.blue);
   else
     return Qnil;
@@ -4220,6 +4227,124 @@ Internal use only, use `display-monitor-attributes-list' instead.  */)
   return attributes_list;
 }
 
+DEFUN ("x-frame-geometry", Fx_frame_geometry, Sx_frame_geometry, 0, 1, 0,
+       doc: /* Return geometric attributes of frame FRAME.
+
+FRAME must be a live frame and defaults to the selected one.
+
+The return value is an association list containing the following
+elements (all size values are in pixels).
+
+- `frame-outer-size' is a cons of the outer width and height of FRAME.
+  The outer size include the title bar and the external borders as well
+  as any menu and/or tool bar of frame.
+
+- `border' is a cons of the horizontal and vertical width of FRAME's
+  external borders.
+
+- `title-bar-height' is the height of the title bar of FRAME.
+
+- `menu-bar-external' if `t' means the menu bar is external (not
+  included in the inner edges of FRAME).
+
+- `menu-bar-size' is a cons of the width and height of the menu bar of
+  FRAME.
+
+- `tool-bar-external' if `t' means the tool bar is external (not
+  included in the inner edges of FRAME).
+
+- `tool-bar-side' tells tells on which side the tool bar on FRAME is and
+  can be one of `left', `top', `right' or `bottom'.
+
+- `tool-bar-size' is a cons of the width and height of the tool bar of
+  FRAME.
+
+- `frame-inner-size' is a cons of the inner width and height of FRAME.
+  This excludes FRAME's title bar and external border as well as any
+  external menu and/or tool bar.  */)
+  (Lisp_Object frame)
+{
+  struct frame *f = decode_live_frame (frame);
+  int inner_width = FRAME_PIXEL_WIDTH (f);
+  int inner_height = FRAME_PIXEL_HEIGHT (f);
+  int outer_width, outer_height, border, title;
+  Lisp_Object fullscreen = Fframe_parameter (frame, Qfullscreen);
+  int menu_bar_height, menu_bar_width, tool_bar_height, tool_bar_width;
+
+  border = FRAME_OUTER_TO_INNER_DIFF_X (f);
+  title = FRAME_X_OUTPUT (f)->y_pixels_outer_diff - border;
+
+  outer_width = FRAME_PIXEL_WIDTH (f) + 2 * border;
+  outer_height = (FRAME_PIXEL_HEIGHT (f)
+                 + FRAME_OUTER_TO_INNER_DIFF_Y (f)
+                 + FRAME_OUTER_TO_INNER_DIFF_X (f));
+
+#if defined (USE_GTK)
+  {
+    bool tool_bar_left_right = (EQ (FRAME_TOOL_BAR_POSITION (f), Qleft)
+                               || EQ (FRAME_TOOL_BAR_POSITION (f), Qright));
+
+    tool_bar_width = (tool_bar_left_right
+                     ? FRAME_TOOLBAR_WIDTH (f)
+                     : FRAME_PIXEL_WIDTH (f));
+    tool_bar_height = (tool_bar_left_right
+                      ? FRAME_PIXEL_HEIGHT (f)
+                      : FRAME_TOOLBAR_HEIGHT (f));
+    if (tool_bar_left_right)
+      /* For some reason FRAME_OUTER_TO_INNER_DIFF_X does not count the
+        width of a tool bar.  */
+      outer_width += FRAME_TOOLBAR_WIDTH (f);
+  }
+#else
+  tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f);
+  tool_bar_width = ((tool_bar_height > 0)
+                   ? outer_width - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)
+                   : 0);
+#endif
+
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
+  menu_bar_height = FRAME_MENUBAR_HEIGHT (f);
+#else
+  menu_bar_height = FRAME_MENU_BAR_HEIGHT (f);
+#endif
+
+  menu_bar_width = ((menu_bar_height > 0)
+                   ? outer_width - 2 * border
+                   : 0);
+
+  if (!FRAME_EXTERNAL_MENU_BAR (f))
+    inner_height -= menu_bar_height;
+  if (!FRAME_EXTERNAL_TOOL_BAR (f))
+    inner_height -= tool_bar_height;
+
+  return
+    listn (CONSTYPE_PURE, 10,
+          Fcons (Qframe_position,
+                 Fcons (make_number (f->left_pos), make_number (f->top_pos))),
+          Fcons (Qframe_outer_size,
+                 Fcons (make_number (outer_width), make_number (outer_height))),
+          Fcons (Qexternal_border_size,
+                 ((EQ (fullscreen, Qfullboth) || EQ (fullscreen, Qfullscreen))
+                  ? Fcons (make_number (0), make_number (0))
+                  : Fcons (make_number (border), make_number (border)))),
+          Fcons (Qtitle_height,
+                 ((EQ (fullscreen, Qfullboth) || EQ (fullscreen, Qfullscreen))
+                  ? make_number (0)
+                  : make_number (title))),
+          Fcons (Qmenu_bar_external, FRAME_EXTERNAL_MENU_BAR (f) ? Qt : Qnil),
+          Fcons (Qmenu_bar_size,
+                 Fcons (make_number (menu_bar_width),
+                        make_number (menu_bar_height))),
+          Fcons (Qtool_bar_external, FRAME_EXTERNAL_TOOL_BAR (f) ? Qt : Qnil),
+          Fcons (Qtool_bar_position, FRAME_TOOL_BAR_POSITION (f)),
+          Fcons (Qtool_bar_size,
+                 Fcons (make_number (tool_bar_width),
+                        make_number (tool_bar_height))),
+          Fcons (Qframe_inner_size,
+                 Fcons (make_number (inner_width),
+                        make_number (inner_height))));
+}
+
 /************************************************************************
                              X Displays
  ************************************************************************/
@@ -4274,13 +4399,13 @@ select_visual (struct x_display_info *dpyinfo)
 {
   Display *dpy = dpyinfo->display;
   Screen *screen = dpyinfo->screen;
-  Lisp_Object value;
 
   /* See if a visual is specified.  */
-  value = display_x_get_resource (dpyinfo,
-                                 build_string ("visualClass"),
-                                 build_string ("VisualClass"),
-                                 Qnil, Qnil);
+  AUTO_STRING (visualClass, "visualClass");
+  AUTO_STRING (VisualClass, "VisualClass");
+  Lisp_Object value = display_x_get_resource (dpyinfo, visualClass,
+                                             VisualClass, Qnil, Qnil);
+
   if (STRINGP (value))
     {
       /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
@@ -4291,7 +4416,7 @@ select_visual (struct x_display_info *dpyinfo)
       int i, class = -1;
       XVisualInfo vinfo;
 
-      strcpy (s, SSDATA (value));
+      lispstpcpy (s, value);
       dash = strchr (s, '-');
       if (dash)
        {
@@ -4593,75 +4718,43 @@ FRAME nil or omitted means use the selected frame.  Value is PROP.  */)
 }
 
 
-DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
-       1, 6, 0,
-       doc: /* Value is the value of window property PROP on FRAME.
-If FRAME is nil or omitted, use the selected frame.
-
-On X Windows, the following optional arguments are also accepted:
-If TYPE is nil or omitted, get the property as a string.
-Otherwise TYPE is the name of the atom that denotes the type expected.
-If SOURCE is non-nil, get the property on that window instead of from
-FRAME.  The number 0 denotes the root window.
-If DELETE-P is non-nil, delete the property after retrieving it.
-If VECTOR-RET-P is non-nil, don't return a string but a vector of values.
-
-On MS Windows, this function accepts but ignores those optional arguments.
-
-Value is nil if FRAME hasn't a property with name PROP or if PROP has
-no value of TYPE (always string in the MS Windows case).  */)
-  (Lisp_Object prop, Lisp_Object frame, Lisp_Object type,
-   Lisp_Object source, Lisp_Object delete_p, Lisp_Object vector_ret_p)
+static Lisp_Object
+x_window_property_intern (struct frame *f,
+                          Window target_window,
+                          Atom prop_atom,
+                          Atom target_type,
+                          Lisp_Object delete_p,
+                          Lisp_Object vector_ret_p,
+                          bool *found)
 {
-  struct frame *f = decode_window_system_frame (frame);
-  Atom prop_atom;
-  int rc;
-  Lisp_Object prop_value = Qnil;
   unsigned char *tmp_data = NULL;
+  Lisp_Object prop_value = Qnil;
   Atom actual_type;
-  Atom target_type = XA_STRING;
   int actual_format;
   unsigned long actual_size, bytes_remaining;
-  Window target_window = FRAME_X_WINDOW (f);
+  int rc;
   struct gcpro gcpro1;
 
   GCPRO1 (prop_value);
-  CHECK_STRING (prop);
-
-  if (! NILP (source))
-    {
-      CONS_TO_INTEGER (source, Window, target_window);
-      if (! target_window)
-       target_window = FRAME_DISPLAY_INFO (f)->root_window;
-    }
 
-  block_input ();
-  if (STRINGP (type))
-    {
-      if (strcmp ("AnyPropertyType", SSDATA (type)) == 0)
-        target_type = AnyPropertyType;
-      else
-        target_type = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (type), False);
-    }
-
-  prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (prop), False);
   rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
                           prop_atom, 0, 0, False, target_type,
                           &actual_type, &actual_format, &actual_size,
                           &bytes_remaining, &tmp_data);
-  if (rc == Success)
-    {
-      int size = bytes_remaining;
 
+  *found = actual_format != 0;
+
+  if (rc == Success && *found)
+    {
       XFree (tmp_data);
       tmp_data = NULL;
 
       rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
-                              prop_atom, 0, bytes_remaining,
-                              ! NILP (delete_p), target_type,
-                              &actual_type, &actual_format,
-                              &actual_size, &bytes_remaining,
-                              &tmp_data);
+                               prop_atom, 0, bytes_remaining,
+                               ! NILP (delete_p), target_type,
+                               &actual_type, &actual_format,
+                               &actual_size, &bytes_remaining,
+                               &tmp_data);
       if (rc == Success && tmp_data)
         {
           /* The man page for XGetWindowProperty says:
@@ -4689,7 +4782,7 @@ no value of TYPE (always string in the MS Windows case).  */)
             }
 
           if (NILP (vector_ret_p))
-            prop_value = make_string ((char *) tmp_data, size);
+            prop_value = make_string ((char *) tmp_data, actual_size);
           else
             prop_value = x_property_data_to_lisp (f,
                                                   tmp_data,
@@ -4701,121 +4794,85 @@ no value of TYPE (always string in the MS Windows case).  */)
       if (tmp_data) XFree (tmp_data);
     }
 
-  unblock_input ();
   UNGCPRO;
   return prop_value;
 }
 
+DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
+       1, 6, 0,
+       doc: /* Value is the value of window property PROP on FRAME.
+If FRAME is nil or omitted, use the selected frame.
 
-\f
-/***********************************************************************
-                               Busy cursor
- ***********************************************************************/
-
-/* Timer function of hourglass_atimer.  TIMER is equal to
-   hourglass_atimer.
+On X Windows, the following optional arguments are also accepted:
+If TYPE is nil or omitted, get the property as a string.
+Otherwise TYPE is the name of the atom that denotes the type expected.
+If SOURCE is non-nil, get the property on that window instead of from
+FRAME.  The number 0 denotes the root window.
+If DELETE-P is non-nil, delete the property after retrieving it.
+If VECTOR-RET-P is non-nil, don't return a string but a vector of values.
 
-   Display an hourglass pointer on all frames by mapping the frames'
-   hourglass_window.  Set the hourglass_p flag in the frames'
-   output_data.x structure to indicate that an hourglass cursor is
-   shown on the frames.  */
+On MS Windows, this function accepts but ignores those optional arguments.
 
-void
-show_hourglass (struct atimer *timer)
+Value is nil if FRAME hasn't a property with name PROP or if PROP has
+no value of TYPE (always string in the MS Windows case).  */)
+  (Lisp_Object prop, Lisp_Object frame, Lisp_Object type,
+   Lisp_Object source, Lisp_Object delete_p, Lisp_Object vector_ret_p)
 {
-  /* The timer implementation will cancel this timer automatically
-     after this function has run.  Set hourglass_atimer to null
-     so that we know the timer doesn't have to be canceled.  */
-  hourglass_atimer = NULL;
-
-  if (!hourglass_shown_p)
-    {
-      Lisp_Object rest, frame;
-
-      block_input ();
-
-      FOR_EACH_FRAME (rest, frame)
-       {
-         struct frame *f = XFRAME (frame);
-
-         if (FRAME_LIVE_P (f) && FRAME_X_P (f) && FRAME_X_DISPLAY (f))
-           {
-             Display *dpy = FRAME_X_DISPLAY (f);
-
-#ifdef USE_X_TOOLKIT
-             if (f->output_data.x->widget)
-#else
-             if (FRAME_OUTER_WINDOW (f))
-#endif
-               {
-                 f->output_data.x->hourglass_p = 1;
+  struct frame *f = decode_window_system_frame (frame);
+  Atom prop_atom;
+  Lisp_Object prop_value = Qnil;
+  Atom target_type = XA_STRING;
+  Window target_window = FRAME_X_WINDOW (f);
+  struct gcpro gcpro1;
+  bool found;
 
-                 if (!f->output_data.x->hourglass_window)
-                   {
-                     unsigned long mask = CWCursor;
-                     XSetWindowAttributes attrs;
-#ifdef USE_GTK
-                      Window parent = FRAME_X_WINDOW (f);
-#else
-                      Window parent = FRAME_OUTER_WINDOW (f);
-#endif
-                     attrs.cursor = f->output_data.x->hourglass_cursor;
-
-                     f->output_data.x->hourglass_window
-                       = XCreateWindow (dpy, parent,
-                                        0, 0, 32000, 32000, 0, 0,
-                                        InputOnly,
-                                        CopyFromParent,
-                                        mask, &attrs);
-                   }
-
-                 XMapRaised (dpy, f->output_data.x->hourglass_window);
-                 XFlush (dpy);
-               }
-           }
-       }
+  GCPRO1 (prop_value);
+  CHECK_STRING (prop);
 
-      hourglass_shown_p = 1;
-      unblock_input ();
+  if (! NILP (source))
+    {
+      CONS_TO_INTEGER (source, Window, target_window);
+      if (! target_window)
+       target_window = FRAME_DISPLAY_INFO (f)->root_window;
     }
-}
 
+  block_input ();
+  if (STRINGP (type))
+    {
+      if (strcmp ("AnyPropertyType", SSDATA (type)) == 0)
+        target_type = AnyPropertyType;
+      else
+        target_type = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (type), False);
+    }
 
-/* Hide the hourglass pointer on all frames, if it is currently
-   shown.  */
-
-void
-hide_hourglass (void)
-{
-  if (hourglass_shown_p)
+  prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (prop), False);
+  prop_value = x_window_property_intern (f,
+                                         target_window,
+                                         prop_atom,
+                                         target_type,
+                                         delete_p,
+                                         vector_ret_p,
+                                         &found);
+  if (NILP (prop_value)
+      && ! found
+      && NILP (source)
+      && target_window != FRAME_OUTER_WINDOW (f))
     {
-      Lisp_Object rest, frame;
+      prop_value = x_window_property_intern (f,
+                                             FRAME_OUTER_WINDOW (f),
+                                             prop_atom,
+                                             target_type,
+                                             delete_p,
+                                             vector_ret_p,
+                                             &found);
+    }
 
-      block_input ();
-      FOR_EACH_FRAME (rest, frame)
-       {
-         struct frame *f = XFRAME (frame);
 
-         if (FRAME_X_P (f)
-             /* Watch out for newly created frames.  */
-             && f->output_data.x->hourglass_window)
-           {
-             XUnmapWindow (FRAME_X_DISPLAY (f),
-                           f->output_data.x->hourglass_window);
-             /* Sync here because XTread_socket looks at the
-                hourglass_p flag that is reset to zero below.  */
-             XSync (FRAME_X_DISPLAY (f), False);
-             f->output_data.x->hourglass_p = 0;
-           }
-       }
-
-      hourglass_shown_p = 0;
-      unblock_input ();
-    }
+  unblock_input ();
+  UNGCPRO;
+  return prop_value;
 }
 
-
-\f
 /***********************************************************************
                                Tool tips
  ***********************************************************************/
@@ -4893,13 +4950,14 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
 
   frame = Qnil;
   GCPRO3 (parms, name, frame);
-  f = make_frame (1);
+  f = make_frame (true);
   XSETFRAME (frame, f);
 
-  buffer = Fget_buffer_create (build_string (" *tip*"));
+  AUTO_STRING (tip, " *tip*");
+  buffer = Fget_buffer_create (tip);
   /* Use set_window_buffer instead of Fset_window_buffer (see
      discussion of bug#11984, bug#12025, bug#12026).  */
-  set_window_buffer (FRAME_ROOT_WINDOW (f), buffer, 0, 0);
+  set_window_buffer (FRAME_ROOT_WINDOW (f), buffer, false, false);
   old_buffer = current_buffer;
   set_buffer_internal_1 (XBUFFER (buffer));
   bset_truncate_lines (current_buffer, Qnil);
@@ -4923,17 +4981,17 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
   FRAME_FONTSET (f) = -1;
   f->output_data.x->scroll_bar_foreground_pixel = -1;
   f->output_data.x->scroll_bar_background_pixel = -1;
-#ifdef USE_TOOLKIT_SCROLL_BARS
+#if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
   f->output_data.x->scroll_bar_top_shadow_pixel = -1;
   f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
-#endif /* USE_TOOLKIT_SCROLL_BARS */
+#endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
   f->output_data.x->white_relief.pixel = -1;
   f->output_data.x->black_relief.pixel = -1;
 
   fset_icon_name (f, Qnil);
   FRAME_DISPLAY_INFO (f) = dpyinfo;
   f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
-  f->output_data.x->explicit_parent = 0;
+  f->output_data.x->explicit_parent = false;
 
   /* These colors will be set anyway later, but it's important
      to get the color reference counts right, so initialize them!  */
@@ -4973,12 +5031,12 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
   if (EQ (name, Qunbound) || NILP (name))
     {
       fset_name (f, build_string (dpyinfo->x_id_name));
-      f->explicit_name = 0;
+      f->explicit_name = false;
     }
   else
     {
       fset_name (f, name);
-      f->explicit_name = 1;
+      f->explicit_name = true;
       /* use the frame's title when getting resources for this frame.  */
       specbind (Qx_resource_name, name);
     }
@@ -5042,17 +5100,14 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
   dpyinfo_refcount = dpyinfo->reference_count;
 #endif /* GLYPH_DEBUG */
 
-  /* Init faces before x_default_parameter is called for scroll-bar
-     parameters because that function calls x_set_scroll_bar_width,
-     which calls change_frame_size, which calls Fset_window_buffer,
-     which runs hooks, which call Fvertical_motion.  At the end, we
-     end up in init_iterator with a null face cache, which should not
-     happen.  */
+  /* Init faces before x_default_parameter is called for the
+     scroll-bar-width parameter because otherwise we end up in
+     init_iterator with a null face cache, which should not happen.  */
   init_frame_faces (f);
 
   f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
 
-  x_figure_window_size (f, parms, 0);
+  x_figure_window_size (f, parms, false);
 
   {
     XSetWindowAttributes attrs;
@@ -5104,12 +5159,15 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
   width = FRAME_COLS (f);
   height = FRAME_LINES (f);
   SET_FRAME_COLS (f, 0);
-  FRAME_LINES (f) = 0;
-  change_frame_size (f, width, height, 1, 0, 0, 0);
+  SET_FRAME_LINES (f, 0);
+  change_frame_size (f, width, height, true, false, false, false);
 
   /* Add `tooltip' frame parameter's default value. */
   if (NILP (Fframe_parameter (frame, Qtooltip)))
-    Fmodify_frame_parameters (frame, list1 (Fcons (Qtooltip, Qt)));
+    {
+      AUTO_FRAME_ARG (arg, Qtooltip, Qt);
+      Fmodify_frame_parameters (frame, arg);
+    }
 
   /* FIXME - can this be done in a similar way to normal frames?
      http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
@@ -5127,7 +5185,10 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
       disptype = intern ("color");
 
     if (NILP (Fframe_parameter (frame, Qdisplay_type)))
-      Fmodify_frame_parameters (frame, list1 (Fcons (Qdisplay_type, disptype)));
+      {
+       AUTO_FRAME_ARG (arg, Qdisplay_type, disptype);
+       Fmodify_frame_parameters (frame, arg);
+      }
   }
 
   /* Set up faces after all frame parameters are known.  This call
@@ -5146,10 +5207,13 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
     call2 (Qface_set_after_frame_default, frame, Qnil);
 
     if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
-      Fmodify_frame_parameters (frame, list1 (Fcons (Qbackground_color, bg)));
+      {
+       AUTO_FRAME_ARG (arg, Qbackground_color, bg);
+       Fmodify_frame_parameters (frame, arg);
+      }
   }
 
-  f->no_split = 1;
+  f->no_split = true;
 
   UNGCPRO;
 
@@ -5162,7 +5226,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
      below.  And the frame needs to be on Vframe_list or making it
      visible won't work.  */
   Vframe_list = Fcons (frame, Vframe_list);
-
+  f->can_x_set_window_size = true;
 
   /* Setting attributes of faces of the tooltip frame from resources
      and similar will increment face_change_count, which leads to the
@@ -5267,7 +5331,8 @@ Text larger than the specified size is clipped.  */)
   int root_x, root_y;
   struct buffer *old_buffer;
   struct text_pos pos;
-  int i, width, height, seen_reversed_p;
+  int i, width, height;
+  bool seen_reversed_p;
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
   int old_windows_or_buffers_changed = windows_or_buffers_changed;
   ptrdiff_t count = SPECPDL_INDEX ();
@@ -5405,7 +5470,7 @@ Text larger than the specified size is clipped.  */)
 
   FRAME_TOTAL_COLS (f) = w->total_cols;
   adjust_frame_glyphs (f);
-  w->pseudo_window_p = 1;
+  w->pseudo_window_p = true;
 
   /* Display the tooltip text in a temporary buffer.  */
   old_buffer = current_buffer;
@@ -5417,7 +5482,8 @@ Text larger than the specified size is clipped.  */)
   try_window (FRAME_ROOT_WINDOW (f), pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
 
   /* Compute width and height of the tooltip.  */
-  width = height = seen_reversed_p = 0;
+  width = height = 0;
+  seen_reversed_p = false;
   for (i = 0; i < w->desired_matrix->nrows; ++i)
     {
       struct glyph_row *row = &w->desired_matrix->rows[i];
@@ -5429,7 +5495,7 @@ Text larger than the specified size is clipped.  */)
        break;
 
       /* Let the row go over the full width of the frame.  */
-      row->full_width_p = 1;
+      row->full_width_p = true;
 
       row_width = row->pixel_width;
       if (row->used[TEXT_AREA])
@@ -5439,7 +5505,7 @@ Text larger than the specified size is clipped.  */)
          if (!row->reversed_p)
            {
              last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
-             if (INTEGERP (last->object))
+             if (NILP (last->object))
                row_width -= last->pixel_width;
            }
          else
@@ -5449,10 +5515,10 @@ Text larger than the specified size is clipped.  */)
                 Don't count that glyph.  */
              struct glyph *g = row->glyphs[TEXT_AREA];
 
-             if (g->type == STRETCH_GLYPH && INTEGERP (g->object))
+             if (g->type == STRETCH_GLYPH && NILP (g->object))
                {
                  row_width -= g->pixel_width;
-                 seen_reversed_p = 1;
+                 seen_reversed_p = true;
                }
            }
        }
@@ -5488,12 +5554,12 @@ Text larger than the specified size is clipped.  */)
 
          if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
            break;
-         row->full_width_p = 1;
+         row->full_width_p = true;
          row_width = row->pixel_width;
          if (row->used[TEXT_AREA] && !row->reversed_p)
            {
              last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
-             if (INTEGERP (last->object))
+             if (NILP (last->object))
                row_width -= last->pixel_width;
            }
 
@@ -5518,8 +5584,8 @@ Text larger than the specified size is clipped.  */)
   unblock_input ();
 
   /* Draw into the window.  */
-  w->must_be_updated_p = 1;
-  update_single_window (w, 1);
+  w->must_be_updated_p = true;
+  update_single_window (w);
 
   /* Restore original current buffer.  */
   set_buffer_internal_1 (old_buffer);
@@ -5655,7 +5721,7 @@ clean_up_file_dialog (void *arg)
   block_input ();
   XtUnmanageChild (dialog);
   XtDestroyWidget (dialog);
-  x_menu_set_in_use (0);
+  x_menu_set_in_use (false);
   unblock_input ();
 }
 
@@ -5779,7 +5845,7 @@ value of DIR as in previous invocations; this is standard Windows behavior.  */)
   record_unwind_protect_ptr (clean_up_file_dialog, dialog);
 
   /* Process events until the user presses Cancel or OK.  */
-  x_menu_set_in_use (1);
+  x_menu_set_in_use (true);
   result = 0;
   while (result == 0)
     {
@@ -5833,7 +5899,7 @@ value of DIR as in previous invocations; this is standard Windows behavior.  */)
 static void
 clean_up_dialog (void)
 {
-  x_menu_set_in_use (0);
+  x_menu_set_in_use (false);
 }
 
 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
@@ -5935,12 +6001,12 @@ nil, it defaults to the selected frame. */)
   XSETFONT (font, FRAME_FONT (f));
   font_param = Ffont_get (font, intern (":name"));
   if (STRINGP (font_param))
-    default_name = xstrdup (SSDATA (font_param));
+    default_name = xlispstrdup (font_param);
   else
     {
       font_param = Fframe_parameter (frame, Qfont_param);
       if (STRINGP (font_param))
-        default_name = xstrdup (SSDATA (font_param));
+        default_name = xlispstrdup (font_param);
     }
 
   font = xg_get_font (f, default_name);
@@ -6046,7 +6112,11 @@ present and mapped to the usual X keysyms.  */)
          XkbFreeNames (kb, 0, True);
        }
 
-      XkbFreeClientMap (kb, 0, True);
+      /* As of libX11-1.6.2, XkbGetMap manual says that you should use
+        XkbFreeClientMap to free the data returned by XkbGetMap.  But
+        this function just frees the data referenced from KB and not
+        KB itself.  To free KB as well, call XkbFreeKeyboard.  */
+      XkbFreeKeyboard (kb, XkbAllMapComponentsMask, True);
 
       if (delete_keycode
          && backspace_keycode
@@ -6088,17 +6158,19 @@ frame_parm_handler x_frame_parm_handlers[] =
   x_set_mouse_color,
   x_explicitly_set_name,
   x_set_scroll_bar_width,
+  x_set_scroll_bar_height,
   x_set_title,
   x_set_unsplittable,
   x_set_vertical_scroll_bars,
+  x_set_horizontal_scroll_bars,
   x_set_visibility,
   x_set_tool_bar_lines,
   x_set_scroll_bar_foreground,
   x_set_scroll_bar_background,
   x_set_screen_gamma,
   x_set_line_spacing,
-  x_set_fringe_width,
-  x_set_fringe_width,
+  x_set_left_fringe,
+  x_set_right_fringe,
   x_set_wait_for_wm,
   x_set_fullscreen,
   x_set_font_backend,
@@ -6110,15 +6182,10 @@ frame_parm_handler x_frame_parm_handlers[] =
 void
 syms_of_xfns (void)
 {
-  /* The section below is built by the lisp expression at the top of the file,
-     just above where these variables are declared.  */
-  /*&&& init symbols here &&&*/
-  DEFSYM (Qsuppress_icon, "suppress-icon");
   DEFSYM (Qundefined_color, "undefined-color");
   DEFSYM (Qcompound_text, "compound-text");
   DEFSYM (Qcancel_timer, "cancel-timer");
   DEFSYM (Qfont_param, "font-parameter");
-  /* This is the end of symbol initialization.  */
 
   Fput (Qundefined_color, Qerror_conditions,
        listn (CONSTYPE_PURE, 2, Qundefined_color, Qerror));
@@ -6131,7 +6198,7 @@ Changing the value does not affect existing frames
 unless you set the mouse color.  */);
   Vx_pointer_shape = Qnil;
 
-#if 0 /* This doesn't really do anything.  */
+#if false /* This doesn't really do anything.  */
   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
@@ -6145,7 +6212,7 @@ This variable takes effect when you create a new frame
 or when you set the mouse color.  */);
   Vx_hourglass_pointer_shape = Qnil;
 
-#if 0 /* This doesn't really do anything.  */
+#if false /* This doesn't really do anything.  */
   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
@@ -6207,31 +6274,25 @@ Chinese, Japanese, and Korean.  */);
 If nil or if the file selection dialog is not available, the new GTK file
 chooser is used instead.  To turn off all file dialogs set the
 variable `use-file-dialog'.  */);
-  x_gtk_use_old_file_dialog = 0;
+  x_gtk_use_old_file_dialog = false;
 
   DEFVAR_BOOL ("x-gtk-show-hidden-files", x_gtk_show_hidden_files,
     doc: /* If non-nil, the GTK file chooser will by default show hidden files.
 Note that this is just the default, there is a toggle button on the file
 chooser to show or not show hidden files on a case by case basis.  */);
-  x_gtk_show_hidden_files = 0;
+  x_gtk_show_hidden_files = false;
 
   DEFVAR_BOOL ("x-gtk-file-dialog-help-text", x_gtk_file_dialog_help_text,
     doc: /* If non-nil, the GTK file chooser will show additional help text.
 If more space for files in the file chooser dialog is wanted, set this to nil
 to turn the additional text off.  */);
-  x_gtk_file_dialog_help_text = 1;
-
-  DEFVAR_BOOL ("x-gtk-whole-detached-tool-bar", x_gtk_whole_detached_tool_bar,
-    doc: /* If non-nil, a detached tool bar is shown in full.
-The default is to just show an arrow and pressing on that arrow shows
-the tool bar buttons.  */);
-  x_gtk_whole_detached_tool_bar = 0;
+  x_gtk_file_dialog_help_text = true;
 
   DEFVAR_BOOL ("x-gtk-use-system-tooltips", x_gtk_use_system_tooltips,
     doc: /* If non-nil with a Gtk+ built Emacs, the Gtk+ tooltip is used.
 Otherwise use Emacs own tooltip implementation.
 When using Gtk+ tooltips, the tooltip face is not used.  */);
-  x_gtk_use_system_tooltips = 1;
+  x_gtk_use_system_tooltips = true;
 
   /* Tell Emacs about this window system.  */
   Fprovide (Qx, Qnil);
@@ -6262,7 +6323,7 @@ When using Gtk+ tooltips, the tooltip face is not used.  */);
     char gtk_version[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
     int len = sprintf (gtk_version, "%d.%d.%d",
                       GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
-    Vgtk_version_string = make_pure_string (gtk_version, len, len, 0);
+    Vgtk_version_string = make_pure_string (gtk_version, len, len, false);
   }
 #endif /* USE_GTK */
 
@@ -6289,6 +6350,7 @@ When using Gtk+ tooltips, the tooltip face is not used.  */);
   defsubr (&Sx_display_backing_store);
   defsubr (&Sx_display_save_under);
   defsubr (&Sx_display_monitor_attributes_list);
+  defsubr (&Sx_frame_geometry);
   defsubr (&Sx_wm_set_size_hint);
   defsubr (&Sx_create_frame);
   defsubr (&Sx_open_connection);