Improve window dividers code.
[bpt/emacs.git] / src / xterm.c
index 2633bf1..e187312 100644 (file)
@@ -1,6 +1,6 @@
 /* X Communication module for terminals which understand the X protocol.
 
-Copyright (C) 1989, 1993-2013 Free Software Foundation, Inc.
+Copyright (C) 1989, 1993-2014 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -98,7 +98,7 @@ extern void _XEditResCheckMessages (Widget, XtPointer, XEvent *, Boolean *);
 
 #ifdef USE_TOOLKIT_SCROLL_BARS
 #if defined USE_MOTIF
-#include <Xm/Xm.h>             /* for LESSTIF_VERSION */
+#include <Xm/Xm.h>             /* For LESSTIF_VERSION */
 #include <Xm/ScrollBar.h>
 #else /* !USE_MOTIF i.e. use Xaw */
 
@@ -133,9 +133,9 @@ extern void _XEditResCheckMessages (Widget, XtPointer, XEvent *, Boolean *);
 
 /* Default to using XIM if available.  */
 #ifdef USE_XIM
-int use_xim = 1;
+bool use_xim = true;
 #else
-int use_xim = 0;  /* configure --without-xim */
+bool use_xim = false;  /* configure --without-xim */
 #endif
 
 /* Non-zero means that a HELP_EVENT has been generated since Emacs
@@ -148,13 +148,6 @@ static bool any_help_event_p;
 
 struct x_display_info *x_display_list;
 
-/* This is a list of cons cells, each of the form (NAME
-   . FONT-LIST-CACHE), one for each element of x_display_list and in
-   the same order.  NAME is the name of the frame.  FONT-LIST-CACHE
-   records previous values returned by x-list-fonts.  */
-
-Lisp_Object x_display_name_list;
-
 #ifdef USE_X_TOOLKIT
 
 /* The application context for Xt use.  */
@@ -172,11 +165,6 @@ static bool toolkit_scroll_bar_interaction;
 
 static Time ignore_next_mouse_click_timeout;
 
-/* Incremented by XTread_socket whenever it really tries to read
-   events.  */
-
-static int volatile input_signal_count;
-
 /* Used locally within XTread_socket.  */
 
 static int x_noop_count;
@@ -221,7 +209,7 @@ enum xembed_message
   };
 
 static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *);
-static void x_set_window_size_1 (struct frame *, int, int, int);
+static void x_set_window_size_1 (struct frame *, int, int, int, bool);
 static void x_raise_frame (struct frame *);
 static void x_lower_frame (struct frame *);
 static const XColor *x_color_cells (Display *, int *);
@@ -260,7 +248,7 @@ static void x_sync_with_move (struct frame *, int, int, int);
 static int handle_one_xevent (struct x_display_info *,
                              const XEvent *, int *,
                              struct input_event *);
-#ifdef USE_GTK
+#if ! (defined USE_X_TOOLKIT || defined USE_MOTIF)
 static int x_dispatch_event (XEvent *, Display *);
 #endif
 /* Don't declare this _Noreturn because we want no
@@ -516,6 +504,59 @@ x_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
             f->output_data.x->normal_gc, x, y0, x, y1);
 }
 
+/* Draw a window divider from (x0,y0) to (x1,y1)  */
+
+static void
+x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
+{
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  struct face *face = FACE_FROM_ID (f, WINDOW_DIVIDER_FACE_ID);
+  struct face *face_first = FACE_FROM_ID (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
+  struct face *face_last = FACE_FROM_ID (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
+  unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f);
+  unsigned long color_first = (face_first
+                              ? face_first->foreground
+                              : FRAME_FOREGROUND_PIXEL (f));
+  unsigned long color_last = (face_last
+                             ? face_last->foreground
+                             : FRAME_FOREGROUND_PIXEL (f));
+  Display *display = FRAME_X_DISPLAY (f);
+  Window window = FRAME_X_WINDOW (f);
+
+  if (y1 - y0 > x1 - x0 && x1 - x0 > 2)
+    /* Vertical.  */
+    {
+      XSetForeground (display, f->output_data.x->normal_gc, color_first);
+      XFillRectangle (display, window, f->output_data.x->normal_gc,
+                     x0, y0, 1, y1 - y0);
+      XSetForeground (display, f->output_data.x->normal_gc, color);
+      XFillRectangle (display, window, f->output_data.x->normal_gc,
+                     x0 + 1, y0, x1 - x0 - 2, y1 - y0);
+      XSetForeground (display, f->output_data.x->normal_gc, color_last);
+      XFillRectangle (display, window, f->output_data.x->normal_gc,
+                     x1 - 1, y0, 1, y1 - y0);
+    }
+  else if (x1 - x0 > y1 - y0 && y1 - y0 > 3)
+    /* Horizontal.  */
+    {
+      XSetForeground (display, f->output_data.x->normal_gc, color_first);
+      XFillRectangle (display, window, f->output_data.x->normal_gc,
+                     x0, y0, x1 - x0, 1);
+      XSetForeground (display, f->output_data.x->normal_gc, color);
+      XFillRectangle (display, window, f->output_data.x->normal_gc,
+                     x0, y0 + 1, x1 - x0, y1 - y0 - 2);
+      XSetForeground (display, f->output_data.x->normal_gc, color_last);
+      XFillRectangle (display, window, f->output_data.x->normal_gc,
+                     x0, y1 - 1, x1 - x0, 1);
+    }
+  else
+    {
+      XSetForeground (display, f->output_data.x->normal_gc, color);
+      XFillRectangle (display, window, f->output_data.x->normal_gc,
+                     x0, y0, x1 - x0, y1 - y0);
+    }
+}
+
 /* End update of window W.
 
    Draw vertical borders between horizontally adjacent windows, and
@@ -543,7 +584,12 @@ x_update_window_end (struct window *w, bool cursor_on_p,
                                w->output_cursor.x, w->output_cursor.y);
 
       if (draw_window_fringes (w, 1))
-       x_draw_vertical_border (w);
+       {
+         if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
+           x_draw_right_divider (w);
+         else
+           x_draw_vertical_border (w);
+       }
 
       unblock_input ();
     }
@@ -583,6 +629,32 @@ XTframe_up_to_date (struct frame *f)
 }
 
 
+/* Clear under internal border if any for non-toolkit builds. */
+
+
+#if !defined USE_X_TOOLKIT && !defined USE_GTK
+void
+x_clear_under_internal_border (struct frame *f)
+{
+  if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
+    {
+      Display *display = FRAME_X_DISPLAY (f);
+      Window window = FRAME_X_WINDOW (f);
+      int border = FRAME_INTERNAL_BORDER_WIDTH (f);
+      int width = FRAME_PIXEL_WIDTH (f);
+      int height = FRAME_PIXEL_HEIGHT (f);
+      int margin = FRAME_TOP_MARGIN_HEIGHT (f);
+
+      block_input ();
+      x_clear_area (display, window, 0, 0, border, height);
+      x_clear_area (display, window, 0, margin, width, border);
+      x_clear_area (display, window, width - border, 0, border, height);
+      x_clear_area (display, window, 0, height - border, width, border);
+      unblock_input ();
+    }
+}
+#endif
+
 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
    arrow bitmaps, or clear the fringes if no bitmaps are required
    before DESIRED_ROW is made current.  This function is called from
@@ -592,38 +664,42 @@ XTframe_up_to_date (struct frame *f)
 static void
 x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
 {
-  struct frame *f;
-  int width, height;
-
   eassert (w);
 
   if (!desired_row->mode_line_p && !w->pseudo_window_p)
     desired_row->redraw_fringe_bitmaps_p = 1;
 
+#ifdef USE_X_TOOLKIT
   /* When a window has disappeared, make sure that no rest of
      full-width rows stays visible in the internal border.  Could
      check here if updated window is the leftmost/rightmost window,
      but I guess it's not worth doing since vertically split windows
      are almost never used, internal border is rarely set, and the
      overhead is very small.  */
-  if (windows_or_buffers_changed
-      && desired_row->full_width_p
-      && (f = XFRAME (w->frame),
-         width = FRAME_INTERNAL_BORDER_WIDTH (f),
-         width != 0)
-      && (height = desired_row->visible_height,
-         height > 0))
-    {
-      int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
+  {
+    struct frame *f;
+    int width, height;
+
+    if (windows_or_buffers_changed
+       && desired_row->full_width_p
+       && (f = XFRAME (w->frame),
+           width = FRAME_INTERNAL_BORDER_WIDTH (f),
+           width != 0)
+       && (height = desired_row->visible_height,
+           height > 0))
+      {
+       int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
 
-      block_input ();
-      x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                   0, y, width, height);
-      x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                   FRAME_PIXEL_WIDTH (f) - width,
-                   y, width, height);
-      unblock_input ();
-    }
+       block_input ();
+       x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                     0, y, width, height);
+       x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                     FRAME_PIXEL_WIDTH (f) - width,
+                     y, width, height);
+       unblock_input ();
+      }
+  }
+#endif
 }
 
 static void
@@ -638,10 +714,8 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring
   /* Must clip because of partially visible lines.  */
   x_clip_to_row (w, row, ANY_AREA, gc);
 
-  if (!p->overlay_p)
+  if (p->bx >= 0 && !p->overlay_p)
     {
-      int bx = p->bx, by = p->by, nx = p->nx, ny = p->ny;
-
       /* In case the same realized face is used for fringes and
         for something displayed in the text (e.g. face `region' on
         mono-displays, the fill style may have been changed to
@@ -651,55 +725,8 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring
       else
        XSetForeground (display, face->gc, face->background);
 
-#ifdef USE_TOOLKIT_SCROLL_BARS
-      /* If the fringe is adjacent to the left (right) scroll bar of a
-        leftmost (rightmost, respectively) window, then extend its
-        background to the gap between the fringe and the bar.  */
-      if ((WINDOW_LEFTMOST_P (w)
-          && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
-         || (WINDOW_RIGHTMOST_P (w)
-             && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)))
-       {
-         int sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
-
-         if (sb_width > 0)
-           {
-             int bar_area_x = WINDOW_SCROLL_BAR_AREA_X (w);
-             int bar_area_width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
-                                   * FRAME_COLUMN_WIDTH (f));
-
-             if (bx < 0)
-               {
-                 /* Bitmap fills the fringe.  */
-                 if (bar_area_x + bar_area_width == p->x)
-                   bx = bar_area_x + sb_width;
-                 else if (p->x + p->wd == bar_area_x)
-                   bx = bar_area_x;
-                 if (bx >= 0)
-                   {
-                     int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
-
-                     nx = bar_area_width - sb_width;
-                     by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
-                                                           row->y));
-                     ny = row->visible_height;
-                   }
-               }
-             else
-               {
-                 if (bar_area_x + bar_area_width == bx)
-                   {
-                     bx = bar_area_x + sb_width;
-                     nx += bar_area_width - sb_width;
-                   }
-                 else if (bx + nx == bar_area_x)
-                   nx += bar_area_width - sb_width;
-               }
-           }
-       }
-#endif
-      if (bx >= 0 && nx > 0)
-       XFillRectangle (display, window, face->gc, bx, by, nx, ny);
+      XFillRectangle (display, window, face->gc,
+                     p->bx, p->by, p->nx, p->ny);
 
       if (!face->stipple)
        XSetForeground (display, face->gc, face->foreground);
@@ -1650,7 +1677,7 @@ x_alloc_nearest_color (struct frame *f, Colormap cmap, XColor *color)
    get color reference counts right.  */
 
 unsigned long
-x_copy_color (struct frame *f, long unsigned int pixel)
+x_copy_color (struct frame *f, unsigned long pixel)
 {
   XColor color;
 
@@ -1688,7 +1715,8 @@ x_copy_color (struct frame *f, long unsigned int pixel)
    Value is non-zero if successful.  */
 
 static bool
-x_alloc_lighter_color (struct frame *f, Display *display, Colormap cmap, long unsigned int *pixel, double factor, int delta)
+x_alloc_lighter_color (struct frame *f, Display *display, Colormap cmap,
+                      unsigned long *pixel, double factor, int delta)
 {
   XColor color, new;
   long bright;
@@ -1764,7 +1792,8 @@ x_alloc_lighter_color (struct frame *f, Display *display, Colormap cmap, long un
    be allocated, use DEFAULT_PIXEL, instead.  */
 
 static void
-x_setup_relief_color (struct frame *f, struct relief *relief, double factor, int delta, long unsigned int default_pixel)
+x_setup_relief_color (struct frame *f, struct relief *relief, double factor,
+                     int delta, unsigned long default_pixel)
 {
   XGCValues xgcv;
   struct x_output *di = f->output_data.x;
@@ -1781,11 +1810,10 @@ x_setup_relief_color (struct frame *f, struct relief *relief, double factor, int
   /* Free previously allocated color.  The color cell will be reused
      when it has been freed as many times as it was allocated, so this
      doesn't affect faces using the same colors.  */
-  if (relief->gc
-      && relief->allocated_p)
+  if (relief->gc && relief->pixel != -1)
     {
       x_free_colors (f, &relief->pixel, 1);
-      relief->allocated_p = 0;
+      relief->pixel = -1;
     }
 
   /* Allocate new color.  */
@@ -1793,10 +1821,7 @@ x_setup_relief_color (struct frame *f, struct relief *relief, double factor, int
   pixel = background;
   if (dpyinfo->n_planes != 1
       && x_alloc_lighter_color (f, dpy, cmap, &pixel, factor, delta))
-    {
-      relief->allocated_p = 1;
-      xgcv.foreground = relief->pixel = pixel;
-    }
+    xgcv.foreground = relief->pixel = pixel;
 
   if (relief->gc == 0)
     {
@@ -2956,7 +2981,7 @@ XTflash (struct frame *f)
 #endif
     {
       /* Get the height not including a menu bar widget.  */
-      int height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, FRAME_LINES (f));
+      int height = FRAME_PIXEL_HEIGHT (f);
       /* Height of each line to flash.  */
       int flash_height = FRAME_LINE_HEIGHT (f);
       /* These will be the left and right margins of the rectangles.  */
@@ -3116,34 +3141,6 @@ x_scroll_run (struct window *w, struct run *run)
      fringe of W.  */
   window_box (w, ANY_AREA, &x, &y, &width, &height);
 
-#ifdef USE_TOOLKIT_SCROLL_BARS
-  /* If the fringe is adjacent to the left (right) scroll bar of a
-     leftmost (rightmost, respectively) window, then extend its
-     background to the gap between the fringe and the bar.  */
-  if ((WINDOW_LEFTMOST_P (w)
-       && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
-      || (WINDOW_RIGHTMOST_P (w)
-         && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)))
-    {
-      int sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
-
-      if (sb_width > 0)
-       {
-         int bar_area_x = WINDOW_SCROLL_BAR_AREA_X (w);
-         int bar_area_width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
-                               * FRAME_COLUMN_WIDTH (f));
-
-         if (bar_area_x + bar_area_width == x)
-           {
-             x = bar_area_x + sb_width;
-             width += bar_area_width - sb_width;
-           }
-         else if (x + width == bar_area_x)
-           width += bar_area_width - sb_width;
-       }
-    }
-#endif
-
   from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
   to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
   bottom_y = y + height;
@@ -3274,7 +3271,9 @@ x_focus_changed (int type, int state, struct x_display_info *dpyinfo, struct fra
           /* Don't stop displaying the initial startup message
              for a switch-frame event we don't need.  */
           /* When run as a daemon, Vterminal_frame is always NIL.  */
-          bufp->arg = (((NILP (Vterminal_frame) || EQ (Fdaemonp (), Qt))
+          bufp->arg = (((NILP (Vterminal_frame)
+                         || ! FRAME_X_P (XFRAME (Vterminal_frame))
+                         || EQ (Fdaemonp (), Qt))
                        && CONSP (Vframe_list)
                        && !NILP (XCDR (Vframe_list)))
                       ? Qt : Qnil);
@@ -3537,7 +3536,7 @@ x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame,
 }
 
 
-#if defined HAVE_MENUS && !defined USE_X_TOOLKIT && !defined USE_GTK
+#if !defined USE_X_TOOLKIT && !defined USE_GTK
 /* Handle an event saying the mouse has moved out of an Emacs frame.  */
 
 void
@@ -3967,7 +3966,7 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
 
                                   /* From-window.  */
                                   root,
-                                  
+
                                   /* To-window.  */
                                   FRAME_X_WINDOW (dpyinfo->last_mouse_frame),
 
@@ -4250,6 +4249,10 @@ x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole)
   XClientMessageEvent *ev = &event.xclient;
   struct window *w = XWINDOW (window);
   struct frame *f = XFRAME (w->frame);
+  intptr_t iw = (intptr_t) w;
+  enum { BITS_PER_INTPTR = CHAR_BIT * sizeof iw };
+  verify (BITS_PER_INTPTR <= 64);
+  int sign_shift = BITS_PER_INTPTR - 32;
 
   block_input ();
 
@@ -4260,27 +4263,13 @@ x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole)
   ev->window = FRAME_X_WINDOW (f);
   ev->format = 32;
 
-  /* 32-bit X client on a 64-bit X server can pass window pointer
-     as is.  64-bit client on a 32-bit X server is in trouble
-     because pointer does not fit and will be truncated while
-     passing through the server.  So we should use two slots
-     and hope that X12 will resolve such an issues someday.  */
-
-  if (BITS_PER_LONG > 32)
-    {
-      union {
-       int i[2];
-       void *v;
-      } val;
-      val.v = w;
-      ev->data.l[0] = val.i[0];
-      ev->data.l[1] = val.i[1];
-    }
-  else
-    {
-      ev->data.l[0] = 0;
-      ev->data.l[1] = (long) w;
-    }
+  /* A 32-bit X client on a 64-bit X server can pass a window pointer
+     as-is.  A 64-bit client on a 32-bit X server is in trouble
+     because a pointer does not fit and would be truncated while
+     passing through the server.  So use two slots and hope that X12
+     will resolve such issues someday.  */
+  ev->data.l[0] = iw >> 31 >> 1;
+  ev->data.l[1] = sign_shift <= 0 ? iw : iw << sign_shift >> sign_shift;
   ev->data.l[2] = part;
   ev->data.l[3] = portion;
   ev->data.l[4] = whole;
@@ -4311,19 +4300,10 @@ x_scroll_bar_to_input_event (const XEvent *event,
   struct window *w;
 
   /* See the comment in the function above.  */
-
-  if (BITS_PER_LONG > 32)
-    {
-      union {
-       int i[2];
-       void *v;
-      } val;
-      val.i[0] = ev->data.l[0];
-      val.i[1] = ev->data.l[1];
-      w = val.v;
-    }
-  else
-    w = (void *) ev->data.l[1];
+  intptr_t iw0 = ev->data.l[0];
+  intptr_t iw1 = ev->data.l[1];
+  intptr_t iw = (iw0 << 31 << 1) + (iw1 & 0xffffffffu);
+  w = (struct window *) iw;
 
   XSETWINDOW (window, w);
 
@@ -4973,7 +4953,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
     /* Clear the area of W that will serve as a scroll bar.  This is
        for the case that a window has been split horizontally.  In
        this case, no clear_frame is generated to reduce flickering.  */
-    if (width > 0 && height > 0)
+    if (width > 0 && window_box_height (w) > 0)
       x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                    left, top, width, window_box_height (w));
 
@@ -4999,7 +4979,6 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
   bar->start = 0;
   bar->end = 0;
   bar->dragging = -1;
-  bar->fringe_extended_p = 0;
 #if defined (USE_TOOLKIT_SCROLL_BARS) && defined (USE_LUCID)
   bar->last_seen_part = scroll_bar_nowhere;
 #endif
@@ -5175,44 +5154,17 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
   struct frame *f = XFRAME (w->frame);
   Lisp_Object barobj;
   struct scroll_bar *bar;
-  int top, height, left, sb_left, width, sb_width;
+  int top, height, left, width;
   int window_y, window_height;
-#ifdef USE_TOOLKIT_SCROLL_BARS
-  bool fringe_extended_p;
-#endif
 
   /* Get window dimensions.  */
   window_box (w, ANY_AREA, 0, &window_y, 0, &window_height);
   top = window_y;
-  width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f);
   height = window_height;
 
-  /* Compute the left edge of the scroll bar area.  */
+  /* Compute the left edge and the width of the scroll bar area.  */
   left = WINDOW_SCROLL_BAR_AREA_X (w);
-
-  /* Compute the width of the scroll bar which might be less than
-     the width of the area reserved for the scroll bar.  */
-  if (WINDOW_CONFIG_SCROLL_BAR_WIDTH (w) > 0)
-    sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
-  else
-    sb_width = width;
-
-  /* Compute the left edge of the scroll bar.  */
-#ifdef USE_TOOLKIT_SCROLL_BARS
-  if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
-    sb_left = left + (WINDOW_RIGHTMOST_P (w) ? width - sb_width : 0);
-  else
-    sb_left = left + (WINDOW_LEFTMOST_P (w) ? 0 : width - sb_width);
-#else
-  if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
-    sb_left = left + width - sb_width;
-  else
-    sb_left = left;
-#endif
-
-#ifdef USE_TOOLKIT_SCROLL_BARS
-  fringe_extended_p = WINDOW_FRINGE_EXTENDED_P (w);
-#endif
+  width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
 
   /* Does the scroll bar exist yet?  */
   if (NILP (w->vertical_scroll_bar))
@@ -5220,18 +5172,12 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
       if (width > 0 && height > 0)
        {
          block_input ();
-#ifdef USE_TOOLKIT_SCROLL_BARS
-         if (fringe_extended_p)
-           x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                         sb_left, top, sb_width, height);
-         else
-#endif
-           x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                         left, top, width, height);
+         x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                       left, top, width, height);
          unblock_input ();
        }
 
-      bar = x_scroll_bar_create (w, top, sb_left, sb_width, height);
+      bar = x_scroll_bar_create (w, top, left, width, max (height, 1));
     }
   else
     {
@@ -5242,11 +5188,11 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
 
       block_input ();
 
-      if (sb_left != bar->left)
+      if (left != bar->left)
        mask |= CWX;
       if (top != bar->top)
        mask |= CWY;
-      if (sb_width != bar->width)
+      if (width != bar->width)
        mask |= CWWidth;
       if (height != bar->height)
        mask |= CWHeight;
@@ -5254,55 +5200,31 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
 #ifdef USE_TOOLKIT_SCROLL_BARS
 
       /* Move/size the scroll bar widget.  */
-      if (mask || bar->fringe_extended_p != fringe_extended_p)
+      if (mask)
        {
          /* Since toolkit scroll bars are smaller than the space reserved
             for them on the frame, we have to clear "under" them.  */
          if (width > 0 && height > 0)
-           {
-             if (fringe_extended_p)
-               x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                             sb_left, top, sb_width, height);
-             else
-               x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                             left, top, width, height);
-           }
+           x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                         left, top, width, height);
 #ifdef USE_GTK
           xg_update_scrollbar_pos (f, bar->x_window, top,
-                                  sb_left, sb_width, max (height, 1));
+                                  left, width, max (height, 1));
 #else /* not USE_GTK */
           XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar),
-                             sb_left, top, sb_width, max (height, 1), 0);
+                             left, top, width, max (height, 1), 0);
 #endif /* not USE_GTK */
        }
 #else /* not USE_TOOLKIT_SCROLL_BARS */
 
-      /* Clear areas not covered by the scroll bar because it's not as
-        wide as the area reserved for it.  This makes sure a
-        previous mode line display is cleared after C-x 2 C-x 1, for
-        example.  */
-      {
-       int area_width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f);
-       int rest = area_width - sb_width;
-       if (rest > 0 && height > 0)
-         {
-           if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
-             x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                           left + area_width - rest, top, rest, height);
-           else
-             x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                           left, top, rest, height);
-         }
-      }
-
       /* Move/size the scroll bar window.  */
       if (mask)
        {
          XWindowChanges wc;
 
-         wc.x = sb_left;
+         wc.x = left;
          wc.y = top;
-         wc.width = sb_width;
+         wc.width = width;
          wc.height = height;
          XConfigureWindow (FRAME_X_DISPLAY (f), bar->x_window,
                            mask, &wc);
@@ -5311,17 +5233,15 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 
       /* Remember new settings.  */
-      bar->left = sb_left;
+      bar->left = left;
       bar->top = top;
-      bar->width = sb_width;
+      bar->width = width;
       bar->height = height;
 
       unblock_input ();
     }
 
 #ifdef USE_TOOLKIT_SCROLL_BARS
-  bar->fringe_extended_p = fringe_extended_p;
-
   x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
 #else /* not USE_TOOLKIT_SCROLL_BARS */
   /* Set the scroll bar's current state, unless we're currently being
@@ -5802,7 +5722,7 @@ static void xembed_send_message (struct frame *f, Time,
    *FINISH is X_EVENT_DROP if event should not be passed to the toolkit.
    *EVENT is unchanged unless we're processing KeyPress event.
 
-   We return the number of characters stored into the buffer. */
+   We return the number of characters stored into the buffer.  */
 
 static int
 handle_one_xevent (struct x_display_info *dpyinfo,
@@ -6230,7 +6150,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
             SET_FRAME_GARBAGED (f);
 
           /* Check if fullscreen was specified before we where mapped the
-             first time, i.e. from the command line. */
+             first time, i.e. from the command line.  */
           if (!f->output_data.x->has_been_visible)
             x_check_fullscreen (f);
 
@@ -6320,7 +6240,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 #ifdef USE_GTK
           /* Don't pass keys to GTK.  A Tab will shift focus to the
              tool bar in GTK 2.4.  Keys will still go to menus and
-             dialogs because in that case popup_activated is TRUE
+             dialogs because in that case popup_activated is nonzero
              (see above).  */
           *finish = X_EVENT_DROP;
 #endif
@@ -6750,8 +6670,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
         {
 #ifndef USE_X_TOOLKIT
 #ifndef USE_GTK
-          int rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, event->xconfigure.height);
-          int columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, event->xconfigure.width);
+          int width = FRAME_PIXEL_TO_TEXT_WIDTH (f, event->xconfigure.width);
+          int height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, event->xconfigure.height);
 
           /* In the toolkit version, change_frame_size
              is called by the code that handles resizing
@@ -6760,18 +6680,19 @@ handle_one_xevent (struct x_display_info *dpyinfo,
           /* Even if the number of character rows and columns has
              not changed, the font size may have changed, so we need
              to check the pixel dimensions as well.  */
-          if (columns != FRAME_COLS (f)
-              || rows != FRAME_LINES (f)
+          if (width != FRAME_TEXT_WIDTH (f)
+              || height != FRAME_TEXT_HEIGHT (f)
               || event->xconfigure.width != FRAME_PIXEL_WIDTH (f)
               || event->xconfigure.height != FRAME_PIXEL_HEIGHT (f))
             {
-              change_frame_size (f, rows, columns, 0, 1, 0);
-              SET_FRAME_GARBAGED (f);
+              change_frame_size (f, width, height, 0, 1, 0, 1);
+             x_clear_under_internal_border (f);
+             SET_FRAME_GARBAGED (f);
               cancel_mouse_face (f);
             }
 
-          FRAME_PIXEL_WIDTH (f) = event->xconfigure.width;
-          FRAME_PIXEL_HEIGHT (f) = event->xconfigure.height;
+/**           FRAME_PIXEL_WIDTH (f) = event->xconfigure.width; **/
+/**           FRAME_PIXEL_HEIGHT (f) = event->xconfigure.height; **/
 #endif /* not USE_GTK */
 #endif
 
@@ -6996,8 +6917,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
   return count;
 }
 
-#if defined USE_GTK || defined USE_X_TOOLKIT
-
 /* Handles the XEvent EVENT on display DISPLAY.
    This is used for event loops outside the normal event handling,
    i.e. looping while a popup menu or a dialog is posted.
@@ -7016,8 +6935,6 @@ x_dispatch_event (XEvent *event, Display *display)
 
   return finish;
 }
-#endif
-
 
 /* Read events coming from the X server.
    Return as soon as there are no more events to be read.
@@ -7036,9 +6953,6 @@ XTread_socket (struct terminal *terminal, struct input_event *hold_quit)
 
   block_input ();
 
-  /* So people can tell when we have read the available input.  */
-  input_signal_count++;
-
   /* For debugging, this gives a way to fake an I/O error.  */
   if (dpyinfo == XTread_socket_fake_io_error)
     {
@@ -7830,6 +7744,7 @@ Lisp_Object
 x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
 {
   struct font *font = XFONT_OBJECT (font_object);
+  int unit;
 
   if (fontset < 0)
     fontset = fontset_from_font (font_object);
@@ -7844,20 +7759,25 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
   FRAME_COLUMN_WIDTH (f) = font->average_width;
   FRAME_LINE_HEIGHT (f) = FONT_HEIGHT (font);
 
+  FRAME_TOOL_BAR_HEIGHT (f) = FRAME_TOOL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
+  FRAME_MENU_BAR_HEIGHT (f) = FRAME_MENU_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
+
   compute_fringe_widths (f, 1);
 
-  /* Compute the scroll bar width in character columns.  */
-  if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
-    {
-      int wid = FRAME_COLUMN_WIDTH (f);
-      FRAME_CONFIG_SCROLL_BAR_COLS (f)
-       = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid-1) / wid;
-    }
-  else
-    {
-      int wid = FRAME_COLUMN_WIDTH (f);
-      FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
-    }
+  unit = FRAME_COLUMN_WIDTH (f);
+#ifdef USE_TOOLKIT_SCROLL_BARS
+  /* The width of a toolkit scrollbar does not change with the new
+     font but we have to calculate the number of columns it occupies
+     anew.  */
+  FRAME_CONFIG_SCROLL_BAR_COLS (f)
+    = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + unit - 1) / unit;
+#else
+  /* The width of a non-toolkit scrollbar is at least 14 pixels and a
+     multiple of the frame's character width.  */
+  FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit;
+  FRAME_CONFIG_SCROLL_BAR_WIDTH (f)
+    = FRAME_CONFIG_SCROLL_BAR_COLS (f) * unit;
+#endif  
 
   if (FRAME_X_WINDOW (f) != 0)
     {
@@ -7865,7 +7785,8 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
         doing it because it's done in Fx_show_tip, and it leads to
         problems because the tip frame has no widget.  */
       if (NILP (tip_frame) || XFRAME (tip_frame) != f)
-        x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+       x_set_window_size (f, 0, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
+                          FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 1);
     }
 
 #ifdef HAVE_X_I18N
@@ -8680,23 +8601,23 @@ x_wait_for_event (struct frame *f, int eventtype)
    size changes.  Otherwise we leave the window gravity unchanged.  */
 
 static void
-x_set_window_size_1 (struct frame *f, int change_gravity, int cols, int rows)
+x_set_window_size_1 (struct frame *f, int change_gravity, int width, int height, bool pixelwise)
 {
   int pixelwidth, pixelheight;
 
-  check_frame_size (f, &rows, &cols);
-  f->scroll_bar_actual_width
-    = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
-       ? 0
-       : FRAME_CONFIG_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f));
+  check_frame_size (f, &width, &height, pixelwise);
 
   compute_fringe_widths (f, 0);
 
-  pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols)
-    + FRAME_TOOLBAR_WIDTH (f);
-  pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows)
-    + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f);
-
+  pixelwidth = ((pixelwise
+                ? FRAME_TEXT_TO_PIXEL_WIDTH (f, width)
+                : FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width))
+               + FRAME_TOOLBAR_WIDTH (f));
+  pixelheight = ((pixelwise
+                 ? FRAME_TEXT_TO_PIXEL_HEIGHT (f, height)
+                 : FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height))
+                + FRAME_MENUBAR_HEIGHT (f)
+                + FRAME_TOOLBAR_HEIGHT (f));
   if (change_gravity) f->win_gravity = NorthWestGravity;
   x_wm_set_size_hint (f, (long) 0, 0);
   XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
@@ -8730,9 +8651,7 @@ x_set_window_size_1 (struct frame *f, int change_gravity, int cols, int rows)
     x_wait_for_event (f, ConfigureNotify);
   else
     {
-      change_frame_size (f, rows, cols, 0, 1, 0);
-      FRAME_PIXEL_WIDTH (f) = pixelwidth;
-      FRAME_PIXEL_HEIGHT (f) = pixelheight;
+      change_frame_size (f, width, height, 0, 1, 0, 1);
       x_sync (f);
     }
 }
@@ -8744,17 +8663,19 @@ x_set_window_size_1 (struct frame *f, int change_gravity, int cols, int rows)
    Otherwise we leave the window gravity unchanged.  */
 
 void
-x_set_window_size (struct frame *f, int change_gravity, int cols, int rows)
+x_set_window_size (struct frame *f, int change_gravity, int width, int height, bool pixelwise)
 {
   block_input ();
 
+  check_frame_size (f, &width, &height, pixelwise);
+
   if (NILP (tip_frame) || XFRAME (tip_frame) != f)
     {
-      int r, c;
+      int text_width, text_height;
 
       /* When the frame is maximized/fullscreen or running under for
          example Xmonad, x_set_window_size_1 will be a no-op.
-         In that case, the right thing to do is extend rows/cols to
+         In that case, the right thing to do is extend rows/width to
          the current frame size.  We do that first if x_set_window_size_1
          turns out to not be a no-op (there is no way to know).
          The size will be adjusted again if the frame gets a
@@ -8765,23 +8686,27 @@ x_set_window_size (struct frame *f, int change_gravity, int cols, int rows)
          is however.  */
       pixelh -= FRAME_MENUBAR_HEIGHT (f);
 #endif
-      r = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixelh);
-      /* Update f->scroll_bar_actual_width because it is used in
-         FRAME_PIXEL_WIDTH_TO_TEXT_COLS.  */
-      f->scroll_bar_actual_width
-        = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f);
-      c = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, FRAME_PIXEL_WIDTH (f));
-      change_frame_size (f, r, c, 0, 1, 0);
+      text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, FRAME_PIXEL_WIDTH (f));
+      text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelh);
+
+      change_frame_size (f, text_width, text_height, 0, 1, 0, 1);
     }
 
 #ifdef USE_GTK
   if (FRAME_GTK_WIDGET (f))
-    xg_frame_set_char_size (f, cols, rows);
+    if (! pixelwise)
+      xg_frame_set_char_size (f, width * FRAME_COLUMN_WIDTH (f),
+                             height * FRAME_LINE_HEIGHT (f));
+    else
+      xg_frame_set_char_size (f, width, height);
   else
-    x_set_window_size_1 (f, change_gravity, cols, rows);
+    x_set_window_size_1 (f, change_gravity, width, height, pixelwise);
 #else /* not USE_GTK */
 
-  x_set_window_size_1 (f, change_gravity, cols, rows);
+  x_set_window_size_1 (f, change_gravity, width, height, pixelwise);
+#if !defined USE_X_TOOLKIT
+  x_clear_under_internal_border (f);
+#endif
 
 #endif /* not USE_GTK */
 
@@ -8957,9 +8882,6 @@ void
 x_make_frame_visible (struct frame *f)
 {
   int original_top, original_left;
-  int retry_count = 2;
-
- retry:
 
   block_input ();
 
@@ -9008,7 +8930,6 @@ x_make_frame_visible (struct frame *f)
      so that incoming events are handled.  */
   {
     Lisp_Object frame;
-    int count;
     /* This must be before UNBLOCK_INPUT
        since events that arrive in response to the actions above
        will set it when they are handled.  */
@@ -9062,16 +8983,16 @@ x_make_frame_visible (struct frame *f)
 
     XSETFRAME (frame, f);
 
-    /* Wait until the frame is visible.  Process X events until a
-       MapNotify event has been seen, or until we think we won't get a
-       MapNotify at all..  */
-    for (count = input_signal_count + 10;
-        input_signal_count < count && !FRAME_VISIBLE_P (f);)
+    /* Process X events until a MapNotify event has been seen.  */
+    while (!FRAME_VISIBLE_P (f))
       {
        /* Force processing of queued events.  */
        x_sync (f);
 
-       /* Machines that do polling rather than SIGIO have been
+       /* This hack is still in use at least for Cygwin.  See
+          http://lists.gnu.org/archive/html/emacs-devel/2013-12/msg00351.html.
+
+          Machines that do polling rather than SIGIO have been
           observed to go into a busy-wait here.  So we'll fake an
           alarm signal to let the handler know that there's something
           to be read.  We used to raise a real alarm, but it seems
@@ -9087,21 +9008,14 @@ x_make_frame_visible (struct frame *f)
            poll_for_input_1 ();
            poll_suppress_count = old_poll_suppress_count;
          }
-      }
-
-    /* 2000-09-28: In
-
-       (let ((f (selected-frame)))
-          (iconify-frame f)
-         (raise-frame f))
-
-       the frame is not raised with various window managers on
-       FreeBSD, GNU/Linux and Solaris.  It turns out that, for some
-       unknown reason, the call to XtMapWidget is completely ignored.
-       Mapping the widget a second time works.  */
 
-    if (!FRAME_VISIBLE_P (f) && --retry_count != 0)
-      goto retry;
+       if (XPending (FRAME_X_DISPLAY (f)))
+         {
+           XEvent xev;
+           XNextEvent (FRAME_X_DISPLAY (f), &xev);
+           x_dispatch_event (&xev, FRAME_X_DISPLAY (f));
+         }
+      }
   }
 }
 
@@ -9301,8 +9215,7 @@ x_free_frame_resources (struct frame *f)
       /* We must free faces before destroying windows because some
         font-driver (e.g. xft) access a window while finishing a
         face.  */
-      if (FRAME_FACE_CACHE (f))
-       free_frame_faces (f);
+      free_frame_faces (f);
 
       if (f->output_data.x->icon_desc)
        XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->icon_desc);
@@ -9364,9 +9277,9 @@ x_free_frame_resources (struct frame *f)
       if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
        unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
 #endif /* USE_TOOLKIT_SCROLL_BARS */
-      if (f->output_data.x->white_relief.allocated_p)
+      if (f->output_data.x->white_relief.pixel != -1)
        unload_color (f, f->output_data.x->white_relief.pixel);
-      if (f->output_data.x->black_relief.allocated_p)
+      if (f->output_data.x->black_relief.pixel != -1)
        unload_color (f, f->output_data.x->black_relief.pixel);
 
       x_free_gcs (f);
@@ -9452,8 +9365,9 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
   size_hints.height = FRAME_PIXEL_HEIGHT (f);
   size_hints.width = FRAME_PIXEL_WIDTH (f);
 
-  size_hints.width_inc = FRAME_COLUMN_WIDTH (f);
-  size_hints.height_inc = FRAME_LINE_HEIGHT (f);
+  size_hints.width_inc = frame_resize_pixelwise ? 1 : FRAME_COLUMN_WIDTH (f);
+  size_hints.height_inc = frame_resize_pixelwise ? 1 : FRAME_LINE_HEIGHT (f);
+
   size_hints.max_width = x_display_pixel_width (FRAME_DISPLAY_INFO (f))
     - FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
   size_hints.max_height = x_display_pixel_height (FRAME_DISPLAY_INFO (f))
@@ -9467,7 +9381,15 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
     base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
     base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
 
-    check_frame_size (f, &min_rows, &min_cols);
+    check_frame_size (f, &min_cols, &min_rows, 0);
+
+    if (frame_resize_pixelwise)
+      /* Needed to prevent a bad protocol error crash when making the
+        frame size very small.  */
+      {
+       min_cols = 2 * min_cols;
+       min_rows = 2 * min_rows;
+      }
 
     /* The window manager uses the base width hints to calculate the
        current number of rows and columns in the frame while
@@ -9482,8 +9404,8 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
     size_hints.flags |= PBaseSize;
     size_hints.base_width = base_width;
     size_hints.base_height = base_height + FRAME_MENUBAR_HEIGHT (f);
-    size_hints.min_width  = base_width + min_cols * size_hints.width_inc;
-    size_hints.min_height = base_height + min_rows * size_hints.height_inc;
+    size_hints.min_width  = base_width + min_cols * FRAME_COLUMN_WIDTH (f);
+    size_hints.min_height = base_height + min_rows * FRAME_LINE_HEIGHT (f);
   }
 
   /* If we don't need the old flags, we don't need the old hint at all.  */
@@ -9716,7 +9638,7 @@ same_x_server (const char *name1, const char *name2)
    get to the first bit.  With MASK 0x7e0, *BITS is set to 6, and *OFFSET
    to 5.  */
 static void
-get_bits_and_offset (long unsigned int mask, int *bits, int *offset)
+get_bits_and_offset (unsigned long mask, int *bits, int *offset)
 {
   int nr = 0;
   int off = 0;
@@ -9913,26 +9835,16 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
 
   {
     struct x_display_info *share;
-    Lisp_Object tail;
 
-    for (share = x_display_list, tail = x_display_name_list; share;
-        share = share->next, tail = XCDR (tail))
-      if (same_x_server (SSDATA (XCAR (XCAR (tail))),
+    for (share = x_display_list; share; share = share->next)
+      if (same_x_server (SSDATA (XCAR (share->name_list_element)),
                         SSDATA (display_name)))
        break;
     if (share)
       terminal->kboard = share->terminal->kboard;
     else
       {
-       terminal->kboard = xmalloc (sizeof *terminal->kboard);
-       init_kboard (terminal->kboard);
-       kset_window_system (terminal->kboard, Qx);
-
-       /* Add the keyboard to the list before running Lisp code (via
-           Qvendor_specific_keysyms below), since these are not traced
-           via terminals but only through all_kboards.  */
-       terminal->kboard->next_kboard = all_kboards;
-       all_kboards = terminal->kboard;
+       terminal->kboard = allocate_kboard (Qx);
 
        if (!EQ (XSYMBOL (Qvendor_specific_keysyms)->function, Qunbound))
          {
@@ -9971,11 +9883,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
   dpyinfo->next = x_display_list;
   x_display_list = dpyinfo;
 
-  /* Put it on x_display_name_list as well, to keep them parallel.  */
-  x_display_name_list = Fcons (Fcons (display_name, Qnil),
-                              x_display_name_list);
-  dpyinfo->name_list_element = XCAR (x_display_name_list);
-
+  dpyinfo->name_list_element = Fcons (display_name, Qnil);
   dpyinfo->display = dpy;
 
   /* Set the name of the terminal. */
@@ -10258,12 +10166,12 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
     if (STRINGP (value)
        && (!strcmp (SSDATA (value), "false")
            || !strcmp (SSDATA (value), "off")))
-      use_xim = 0;
+      use_xim = false;
 #else
     if (STRINGP (value)
        && (!strcmp (SSDATA (value), "true")
            || !strcmp (SSDATA (value), "on")))
-      use_xim = 1;
+      use_xim = true;
 #endif
   }
 
@@ -10302,27 +10210,6 @@ x_delete_display (struct x_display_info *dpyinfo)
         break;
       }
 
-  /* Discard this display from x_display_name_list and x_display_list.
-     We can't use Fdelq because that can quit.  */
-  if (! NILP (x_display_name_list)
-      && EQ (XCAR (x_display_name_list), dpyinfo->name_list_element))
-    x_display_name_list = XCDR (x_display_name_list);
-  else
-    {
-      Lisp_Object tail;
-
-      tail = x_display_name_list;
-      while (CONSP (tail) && CONSP (XCDR (tail)))
-       {
-         if (EQ (XCAR (XCDR (tail)), dpyinfo->name_list_element))
-           {
-             XSETCDR (tail, XCDR (XCDR (tail)));
-             break;
-           }
-         tail = XCDR (tail);
-       }
-    }
-
   if (next_noop_dpyinfo == dpyinfo)
     next_noop_dpyinfo = dpyinfo->next;
 
@@ -10415,6 +10302,7 @@ static struct redisplay_interface x_redisplay_interface =
     x_clear_frame_area,
     x_draw_window_cursor,
     x_draw_vertical_window_border,
+    x_draw_window_divider,
     x_shift_glyphs_for_insert
   };
 
@@ -10536,12 +10424,6 @@ x_create_terminal (struct x_display_info *dpyinfo)
   terminal->delete_terminal_hook = x_delete_terminal;
 
   terminal->rif = &x_redisplay_interface;
-  terminal->scroll_region_ok = 1;    /* We'll scroll partial frames. */
-  terminal->char_ins_del_ok = 1;
-  terminal->line_ins_del_ok = 1;         /* We'll just blt 'em. */
-  terminal->fast_clear_end_of_line = 1;  /* X does this well. */
-  terminal->memory_below_frame = 0;   /* We don't remember what scrolls
-                                        off the bottom. */
 
   return terminal;
 }
@@ -10598,9 +10480,6 @@ syms_of_xterm (void)
 {
   x_error_message = NULL;
 
-  staticpro (&x_display_name_list);
-  x_display_name_list = Qnil;
-
   DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
   DEFSYM (Qlatin_1, "latin-1");
 
@@ -10659,14 +10538,14 @@ With MS Windows or Nextstep, the value is t.  */);
   Vx_toolkit_scroll_bars = Qnil;
 #endif
 
-  Qmodifier_value = intern_c_string ("modifier-value");
-  Qalt = intern_c_string ("alt");
+  DEFSYM (Qmodifier_value, "modifier-value");
+  DEFSYM (Qalt, "alt");
   Fput (Qalt, Qmodifier_value, make_number (alt_modifier));
-  Qhyper = intern_c_string ("hyper");
+  DEFSYM (Qhyper, "hyper");
   Fput (Qhyper, Qmodifier_value, make_number (hyper_modifier));
-  Qmeta = intern_c_string ("meta");
+  DEFSYM (Qmeta, "meta");
   Fput (Qmeta, Qmodifier_value, make_number (meta_modifier));
-  Qsuper = intern_c_string ("super");
+  DEFSYM (Qsuper, "super");
   Fput (Qsuper, Qmodifier_value, make_number (super_modifier));
 
   DEFVAR_LISP ("x-alt-keysym", Vx_alt_keysym,