Cleaning up a few X scroll bar bits.
[bpt/emacs.git] / src / xterm.c
index e4a6810..7ad790e 100644 (file)
@@ -69,7 +69,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "atimer.h"
 #include "keymap.h"
 #include "font.h"
-#include "fontset.h"
 #include "xsettings.h"
 #include "xgselect.h"
 #include "sysselect.h"
@@ -141,15 +140,10 @@ int use_xim = 1;
 int use_xim = 0;  /* configure --without-xim */
 #endif
 
-\f
-
 /* Non-zero means that a HELP_EVENT has been generated since Emacs
    start.  */
 
-static int any_help_event_p;
-
-/* Last window where we saw the mouse.  Used by mouse-autoselect-window.  */
-static Lisp_Object last_window;
+static bool any_help_event_p;
 
 /* This is a chain of structures for all the X displays currently in
    use.  */
@@ -213,8 +207,7 @@ static unsigned long ignore_next_mouse_click_timeout;
 /* Where the mouse was last time we reported a mouse event.  */
 
 static XRectangle last_mouse_glyph;
-static FRAME_PTR last_mouse_glyph_frame;
-static Lisp_Object last_mouse_press_frame;
+static struct frame *last_mouse_glyph_frame;
 
 /* The scroll bar in which the last X motion event occurred.
 
@@ -289,22 +282,16 @@ enum xembed_message
     XEMBED_ACTIVATE_ACCELERATOR   = 14
   };
 
-/* Used in x_flush.  */
-
 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_raise_frame (struct frame *);
 static void x_lower_frame (struct frame *);
 static const XColor *x_color_cells (Display *, int *);
-static void x_update_window_end (struct window *, int, int);
-
 static int x_io_error_quitter (Display *);
 static struct terminal *x_create_terminal (struct x_display_info *);
 void x_delete_terminal (struct terminal *);
 static void x_update_end (struct frame *);
 static void XTframe_up_to_date (struct frame *);
-static void XTset_terminal_modes (struct terminal *);
-static void XTreset_terminal_modes (struct terminal *);
 static void x_clear_frame (struct frame *);
 static _Noreturn void x_ins_del_lines (struct frame *, int, int);
 static void frame_highlight (struct frame *);
@@ -320,11 +307,11 @@ static void x_draw_hollow_cursor (struct window *, struct glyph_row *);
 static void x_draw_bar_cursor (struct window *, struct glyph_row *, int,
                                enum text_cursor_kinds);
 
-static void x_clip_to_row (struct window *, struct glyph_row *, int, GC);
+static void x_clip_to_row (struct window *, struct glyph_row *,
+                          enum glyph_row_area, GC);
 static void x_flush (struct frame *f);
 static void x_update_begin (struct frame *);
 static void x_update_window_begin (struct window *);
-static void x_after_update_window_line (struct glyph_row *);
 static struct scroll_bar *x_window_to_scroll_bar (Display *, Window);
 static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *,
                                         enum scroll_bar_part *,
@@ -347,26 +334,19 @@ static void x_wm_set_icon_pixmap (struct frame *, ptrdiff_t);
 static void x_initialize (void);
 
 
-/* Flush display of frame F, or of all frames if F is null.  */
+/* Flush display of frame F.  */
 
 static void
 x_flush (struct frame *f)
 {
+  eassert (f && FRAME_X_P (f));
   /* Don't call XFlush when it is not safe to redisplay; the X
      connection may be broken.  */
   if (!NILP (Vinhibit_redisplay))
     return;
 
   block_input ();
-  if (f == NULL)
-    {
-      Lisp_Object rest, frame;
-      FOR_EACH_FRAME (rest, frame)
-        if (FRAME_X_P (XFRAME (frame)))
-          x_flush (XFRAME (frame));
-    }
-  else if (FRAME_X_P (f))
-    XFlush (FRAME_X_DISPLAY (f));
+  XFlush (FRAME_X_DISPLAY (f));
   unblock_input ();
 }
 
@@ -555,9 +535,7 @@ x_update_begin (struct frame *f)
 }
 
 
-/* Start update of window W.  Set the global variable updated_window
-   to the window being updated and set output_cursor to the cursor
-   position of W.  */
+/* Start update of window W.  */
 
 static void
 x_update_window_begin (struct window *w)
@@ -565,8 +543,7 @@ x_update_window_begin (struct window *w)
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
 
-  updated_window = w;
-  set_output_cursor (&w->cursor);
+  w->output_cursor = w->cursor;
 
   block_input ();
 
@@ -602,7 +579,7 @@ x_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
             f->output_data.x->normal_gc, x, y0, x, y1);
 }
 
-/* End update of window W (which is equal to updated_window).
+/* End update of window W.
 
    Draw vertical borders between horizontally adjacent windows, and
    display W's cursor if CURSOR_ON_P is non-zero.
@@ -616,18 +593,17 @@ x_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
    here.  */
 
 static void
-x_update_window_end (struct window *w, int cursor_on_p, int mouse_face_overwritten_p)
+x_update_window_end (struct window *w, bool cursor_on_p,
+                    bool mouse_face_overwritten_p)
 {
-  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
-
   if (!w->pseudo_window_p)
     {
       block_input ();
 
       if (cursor_on_p)
-       display_and_set_cursor (w, 1, output_cursor.hpos,
-                               output_cursor.vpos,
-                               output_cursor.x, output_cursor.y);
+       display_and_set_cursor (w, 1,
+                               w->output_cursor.hpos, w->output_cursor.vpos,
+                               w->output_cursor.x, w->output_cursor.y);
 
       if (draw_window_fringes (w, 1))
        x_draw_vertical_border (w);
@@ -638,13 +614,7 @@ x_update_window_end (struct window *w, int cursor_on_p, int mouse_face_overwritt
   /* If a row with mouse-face was overwritten, arrange for
      XTframe_up_to_date to redisplay the mouse highlight.  */
   if (mouse_face_overwritten_p)
-    {
-      hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
-      hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
-      hlinfo->mouse_face_window = Qnil;
-    }
-
-  updated_window = NULL;
+    reset_mouse_highlight (MOUSE_HL_INFO (XFRAME (w->frame)));
 }
 
 
@@ -665,9 +635,8 @@ x_update_end (struct frame *f)
 }
 
 
-/* This function is called from various places in xdisp.c whenever a
-   complete update has been performed.  The global variable
-   updated_window is not available here.  */
+/* This function is called from various places in xdisp.c
+   whenever a complete update has been performed.  */
 
 static void
 XTframe_up_to_date (struct frame *f)
@@ -679,15 +648,13 @@ XTframe_up_to_date (struct frame *f)
 
 /* 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.  The window being updated is
-   found in updated_window.  This function It is called from
+   before DESIRED_ROW is made current.  This function is called from
    update_window_line only if it is known that there are differences
    between bitmaps to be drawn between current row and DESIRED_ROW.  */
 
 static void
-x_after_update_window_line (struct glyph_row *desired_row)
+x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
 {
-  struct window *w = updated_window;
   struct frame *f;
   int width, height;
 
@@ -698,7 +665,7 @@ x_after_update_window_line (struct glyph_row *desired_row)
 
   /* 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,
+     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.  */
@@ -714,10 +681,10 @@ x_after_update_window_line (struct glyph_row *desired_row)
 
       block_input ();
       x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                   0, y, width, height, False);
+                   0, y, width, height);
       x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                    FRAME_PIXEL_WIDTH (f) - width,
-                   y, width, height, False);
+                   y, width, height);
       unblock_input ();
     }
 }
@@ -732,7 +699,7 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring
   struct face *face = p->face;
 
   /* Must clip because of partially visible lines.  */
-  x_clip_to_row (w, row, -1, gc);
+  x_clip_to_row (w, row, ANY_AREA, gc);
 
   if (!p->overlay_p)
     {
@@ -849,27 +816,6 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring
   XSetClipMask (display, gc, None);
 }
 
-\f
-
-/* This is called when starting Emacs and when restarting after
-   suspend.  When starting Emacs, no X window is mapped.  And nothing
-   must be done to Emacs's own window if it is suspended (though that
-   rarely happens).  */
-
-static void
-XTset_terminal_modes (struct terminal *terminal)
-{
-}
-
-/* This is called when exiting or suspending Emacs.  Exiting will make
-   the X-windows go away, and suspending requires no action.  */
-
-static void
-XTreset_terminal_modes (struct terminal *terminal)
-{
-}
-
-\f
 /***********************************************************************
                            Glyph display
  ***********************************************************************/
@@ -878,8 +824,6 @@ XTreset_terminal_modes (struct terminal *terminal)
 
 static void x_set_glyph_string_clipping (struct glyph_string *);
 static void x_set_glyph_string_gc (struct glyph_string *);
-static void x_draw_glyph_string_background (struct glyph_string *,
-                                            int);
 static void x_draw_glyph_string_foreground (struct glyph_string *);
 static void x_draw_composite_glyph_string_foreground (struct glyph_string *);
 static void x_draw_glyph_string_box (struct glyph_string *);
@@ -1164,7 +1108,7 @@ x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h)
    contains the first component of a composition.  */
 
 static void
-x_draw_glyph_string_background (struct glyph_string *s, int force_p)
+x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
 {
   /* Nothing to do if background has already been drawn or if it
      shouldn't be drawn in the first place.  */
@@ -1377,7 +1321,7 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
        }
       else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
        {
-         sprintf ((char *) buf, "%0*X",
+         sprintf (buf, "%0*X",
                   glyph->u.glyphless.ch < 0x10000 ? 4 : 6,
                   glyph->u.glyphless.ch);
          str = buf;
@@ -1414,11 +1358,6 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
 
 #ifdef USE_X_TOOLKIT
 
-static Boolean cvt_string_to_pixel (Display *, XrmValue *, Cardinal *,
-                                    XrmValue *, XrmValue *, XtPointer *);
-static void cvt_pixel_dtor (XtAppContext, XrmValue *, XtPointer,
-                            XrmValue *, Cardinal *);
-
 #ifdef USE_LUCID
 
 /* Return the frame on which widget WIDGET is used.. Abort if frame
@@ -2648,7 +2587,10 @@ x_draw_underwave (struct glyph_string *s)
 
   /* Find and set clipping rectangle */
 
-  wave_clip = (XRectangle){ x0, y0, width, wave_height };
+  wave_clip.x = x0;
+  wave_clip.y = y0;
+  wave_clip.width = width;
+  wave_clip.height = wave_height;
   get_glyph_string_clip_rect (s, &string_clip);
 
   if (!x_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
@@ -2689,7 +2631,7 @@ x_draw_underwave (struct glyph_string *s)
 static void
 x_draw_glyph_string (struct glyph_string *s)
 {
-  int relief_drawn_p = 0;
+  bool relief_drawn_p = 0;
 
   /* If S draws into the background of its successors, draw the
      background of the successors first so that S can draw into it.
@@ -2988,10 +2930,10 @@ x_delete_glyphs (struct frame *f, register int n)
    If they are <= 0, this is probably an error.  */
 
 void
-x_clear_area (Display *dpy, Window window, int x, int y, int width, int height, int exposures)
+x_clear_area (Display *dpy, Window window, int x, int y, int width, int height)
 {
   eassert (width > 0 && height > 0);
-  XClearArea (dpy, window, x, y, width, height, exposures);
+  XClearArea (dpy, window, x, y, width, height, False);
 }
 
 
@@ -3003,11 +2945,7 @@ x_clear_frame (struct frame *f)
   /* Clearing the frame will erase any cursor, so mark them all as no
      longer visible.  */
   mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
-  output_cursor.hpos = output_cursor.vpos = 0;
-  output_cursor.x = -1;
 
-  /* We don't set the output cursor here because there will always
-     follow an explicit cursor_to.  */
   block_input ();
 
   XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
@@ -3132,22 +3070,22 @@ XTflash (struct frame *f)
       x_flush (f);
 
       {
-       EMACS_TIME delay = make_emacs_time (0, 150 * 1000 * 1000);
-       EMACS_TIME wakeup = add_emacs_time (current_emacs_time (), delay);
+       struct timespec delay = make_timespec (0, 150 * 1000 * 1000);
+       struct timespec wakeup = timespec_add (current_timespec (), delay);
 
        /* Keep waiting until past the time wakeup or any input gets
           available.  */
        while (! detect_input_pending ())
          {
-           EMACS_TIME current = current_emacs_time ();
-           EMACS_TIME timeout;
+           struct timespec current = current_timespec ();
+           struct timespec timeout;
 
            /* Break if result would not be positive.  */
-           if (EMACS_TIME_LE (wakeup, current))
+           if (timespec_cmp (wakeup, current) <= 0)
              break;
 
            /* How long `select' should wait.  */
-           timeout = make_emacs_time (0, 10 * 1000 * 1000);
+           timeout = make_timespec (0, 10 * 1000 * 1000);
 
            /* Try to wait that long--but we might wake up sooner.  */
            pselect (0, NULL, NULL, NULL, &timeout, NULL);
@@ -3193,7 +3131,7 @@ XTflash (struct frame *f)
 
 
 static void
-XTtoggle_invisible_pointer (FRAME_PTR f, int invisible)
+XTtoggle_invisible_pointer (struct frame *f, int invisible)
 {
   block_input ();
   if (invisible)
@@ -3233,20 +3171,6 @@ XTring_bell (struct frame *f)
     }
 }
 
-\f
-/* Specify how many text lines, from the top of the window,
-   should be affected by insert-lines and delete-lines operations.
-   This, and those operations, are used only within an update
-   that is bounded by calls to x_update_begin and x_update_end.  */
-
-static void
-XTset_terminal_window (struct frame *f, int n)
-{
-  /* This function intentionally left blank.  */
-}
-
-
-\f
 /***********************************************************************
                              Line Dance
  ***********************************************************************/
@@ -3272,7 +3196,7 @@ x_scroll_run (struct window *w, struct run *run)
   /* Get frame-relative bounding box of the text display area of W,
      without mode lines.  Include in this box the left and right
      fringe of W.  */
-  window_box (w, -1, &x, &y, &width, &height);
+  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
@@ -3328,7 +3252,6 @@ x_scroll_run (struct window *w, struct run *run)
   block_input ();
 
   /* Cursor off.  Will be switched on again in x_update_window_end.  */
-  updated_window = w;
   x_clear_cursor (w);
 
   XCopyArea (FRAME_X_DISPLAY (f),
@@ -3433,13 +3356,12 @@ 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.  */
-          if ((NILP (Vterminal_frame) || EQ (Fdaemonp(), Qt))
-              && CONSP (Vframe_list)
-              && !NILP (XCDR (Vframe_list)))
-            {
-              bufp->kind = FOCUS_IN_EVENT;
-              XSETFRAME (bufp->frame_or_window, frame);
-            }
+          bufp->arg = (((NILP (Vterminal_frame) || EQ (Fdaemonp (), Qt))
+                       && CONSP (Vframe_list)
+                       && !NILP (XCDR (Vframe_list)))
+                      ? Qt : Qnil);
+          bufp->kind = FOCUS_IN_EVENT;
+          XSETFRAME (bufp->frame_or_window, frame);
         }
 
       frame->output_data.x->focus_state |= state;
@@ -3457,6 +3379,9 @@ x_focus_changed (int type, int state, struct x_display_info *dpyinfo, struct fra
         {
           dpyinfo->x_focus_event_frame = 0;
           x_new_focus_frame (dpyinfo, 0);
+
+          bufp->kind = FOCUS_OUT_EVENT;
+          XSETFRAME (bufp->frame_or_window, frame);
         }
 
 #ifdef HAVE_X_I18N
@@ -3787,7 +3712,6 @@ construct_mouse_click (struct input_event *result, XButtonEvent *event, struct f
   return Qnil;
 }
 
-\f
 /* Function to report a mouse movement to the mainstream Emacs code.
    The input handler calls this.
 
@@ -3800,7 +3724,7 @@ static XMotionEvent last_mouse_motion_event;
 static Lisp_Object last_mouse_motion_frame;
 
 static int
-note_mouse_movement (FRAME_PTR frame, XMotionEvent *event)
+note_mouse_movement (struct frame *frame, XMotionEvent *event)
 {
   last_mouse_movement_time = event->time;
   last_mouse_motion_event = *event;
@@ -3876,11 +3800,11 @@ redo_mouse_highlight (void)
    movement.  */
 
 static void
-XTmouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window,
+XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
                  enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y,
                  Time *timestamp)
 {
-  FRAME_PTR f1;
+  struct frame *f1;
 
   block_input ();
 
@@ -4157,10 +4081,6 @@ static void x_set_toolkit_scroll_bar_thumb (struct scroll_bar *,
 
 static Lisp_Object window_being_scrolled;
 
-/* Last scroll bar part sent in xm_scroll_callback.  */
-
-static int last_scroll_bar_part;
-
 /* Whether this is an Xaw with arrow-scrollbars.  This should imply
    that movements of 1/20 of the screen size are mapped to up/down.  */
 
@@ -4202,20 +4122,23 @@ xt_action_hook (Widget widget, XtPointer client_data, String action_name,
       && WINDOWP (window_being_scrolled))
     {
       struct window *w;
+      struct scroll_bar *bar;
 
       x_send_scroll_bar_event (window_being_scrolled,
                               scroll_bar_end_scroll, 0, 0);
       w = XWINDOW (window_being_scrolled);
+      bar = XSCROLL_BAR (w->vertical_scroll_bar);
 
-      if (!NILP (XSCROLL_BAR (w->vertical_scroll_bar)->dragging))
+      if (bar->dragging != -1)
        {
-         XSCROLL_BAR (w->vertical_scroll_bar)->dragging = Qnil;
+         bar->dragging = -1;
          /* The thumb size is incorrect while dragging: fix it.  */
          set_vertical_scroll_bar (w);
        }
       window_being_scrolled = Qnil;
-      last_scroll_bar_part = -1;
-
+#if defined (USE_LUCID)
+      bar->last_seen_part = scroll_bar_nowhere;
+#endif
       /* Xt timeouts no longer needed.  */
       toolkit_scroll_bar_interaction = 0;
     }
@@ -4340,39 +4263,39 @@ x_scroll_bar_to_input_event (XEvent *event, struct input_event *ievent)
 static void
 xm_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data)
 {
-  struct scroll_bar *bar = (struct scroll_bar *) client_data;
-  XmScrollBarCallbackStruct *cs = (XmScrollBarCallbackStruct *) call_data;
+  struct scroll_bar *bar = client_data;
+  XmScrollBarCallbackStruct *cs = call_data;
   int part = -1, whole = 0, portion = 0;
 
   switch (cs->reason)
     {
     case XmCR_DECREMENT:
-      bar->dragging = Qnil;
+      bar->dragging = -1;
       part = scroll_bar_up_arrow;
       break;
 
     case XmCR_INCREMENT:
-      bar->dragging = Qnil;
+      bar->dragging = -1;
       part = scroll_bar_down_arrow;
       break;
 
     case XmCR_PAGE_DECREMENT:
-      bar->dragging = Qnil;
+      bar->dragging = -1;
       part = scroll_bar_above_handle;
       break;
 
     case XmCR_PAGE_INCREMENT:
-      bar->dragging = Qnil;
+      bar->dragging = -1;
       part = scroll_bar_below_handle;
       break;
 
     case XmCR_TO_TOP:
-      bar->dragging = Qnil;
+      bar->dragging = -1;
       part = scroll_bar_to_top;
       break;
 
     case XmCR_TO_BOTTOM:
-      bar->dragging = Qnil;
+      bar->dragging = -1;
       part = scroll_bar_to_bottom;
       break;
 
@@ -4388,7 +4311,7 @@ xm_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data)
        whole = XM_SB_MAX - slider_size;
        portion = min (cs->value, whole);
        part = scroll_bar_handle;
-       bar->dragging = make_number (cs->value);
+       bar->dragging = cs->value;
       }
       break;
 
@@ -4399,7 +4322,6 @@ xm_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data)
   if (part >= 0)
     {
       window_being_scrolled = bar->window;
-      last_scroll_bar_part = part;
       x_send_scroll_bar_event (bar->window, part, portion, whole);
     }
 }
@@ -4415,11 +4337,11 @@ xg_scroll_callback (GtkRange     *range,
                     gdouble       value,
                     gpointer      user_data)
 {
-  struct scroll_bar *bar = (struct scroll_bar *) user_data;
+  struct scroll_bar *bar = user_data;
   gdouble position;
   int part = -1, whole = 0, portion = 0;
   GtkAdjustment *adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (range));
-  FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (range), XG_FRAME_DATA);
+  struct frame *f = g_object_get_data (G_OBJECT (range), XG_FRAME_DATA);
 
   if (xg_ignore_gtk_scrollbar) return FALSE;
   position = gtk_adjustment_get_value (adj);
@@ -4436,46 +4358,45 @@ xg_scroll_callback (GtkRange     *range,
           whole = gtk_adjustment_get_upper (adj) -
             gtk_adjustment_get_page_size (adj);
           portion = min ((int)position, whole);
-          bar->dragging = make_number ((int)portion);
+          bar->dragging = portion;
         }
       break;
     case GTK_SCROLL_STEP_BACKWARD:
       part = scroll_bar_up_arrow;
-      bar->dragging = Qnil;
+      bar->dragging = -1;
       break;
     case GTK_SCROLL_STEP_FORWARD:
       part = scroll_bar_down_arrow;
-      bar->dragging = Qnil;
+      bar->dragging = -1;
       break;
     case GTK_SCROLL_PAGE_BACKWARD:
       part = scroll_bar_above_handle;
-      bar->dragging = Qnil;
+      bar->dragging = -1;
       break;
     case GTK_SCROLL_PAGE_FORWARD:
       part = scroll_bar_below_handle;
-      bar->dragging = Qnil;
+      bar->dragging = -1;
       break;
     }
 
   if (part >= 0)
     {
       window_being_scrolled = bar->window;
-      last_scroll_bar_part = part;
       x_send_scroll_bar_event (bar->window, part, portion, whole);
     }
 
   return FALSE;
 }
 
-/* Callback for button release. Sets dragging to Qnil when dragging is done.  */
+/* Callback for button release. Sets dragging to -1 when dragging is done.  */
 
 static gboolean
 xg_end_scroll_callback (GtkWidget *widget,
                         GdkEventButton *event,
                         gpointer user_data)
 {
-  struct scroll_bar *bar = (struct scroll_bar *) user_data;
-  bar->dragging = Qnil;
+  struct scroll_bar *bar = user_data;
+  bar->dragging = -1;
   if (WINDOWP (window_being_scrolled))
     {
       x_send_scroll_bar_event (window_being_scrolled,
@@ -4497,11 +4418,12 @@ xg_end_scroll_callback (GtkWidget *widget,
 static void
 xaw_jump_callback (Widget widget, XtPointer client_data, XtPointer call_data)
 {
-  struct scroll_bar *bar = (struct scroll_bar *) client_data;
-  float top = *(float *) call_data;
+  struct scroll_bar *bar = client_data;
+  float *top_addr = call_data;
+  float top = *top_addr;
   float shown;
   int whole, portion, height;
-  int part;
+  enum scroll_bar_part part;
 
   /* Get the size of the thumb, a value between 0 and 1.  */
   block_input ();
@@ -4522,8 +4444,8 @@ xaw_jump_callback (Widget widget, XtPointer client_data, XtPointer call_data)
     part = scroll_bar_handle;
 
   window_being_scrolled = bar->window;
-  bar->dragging = make_number (portion);
-  last_scroll_bar_part = part;
+  bar->dragging = portion;
+  bar->last_seen_part = part;
   x_send_scroll_bar_event (bar->window, part, portion, whole);
 }
 
@@ -4539,11 +4461,11 @@ xaw_jump_callback (Widget widget, XtPointer client_data, XtPointer call_data)
 static void
 xaw_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data)
 {
-  struct scroll_bar *bar = (struct scroll_bar *) client_data;
+  struct scroll_bar *bar = client_data;
   /* The position really is stored cast to a pointer.  */
-  int position = (long) call_data;
+  int position = (intptr_t) call_data;
   Dimension height;
-  int part;
+  enum scroll_bar_part part;
 
   /* Get the height of the scroll bar.  */
   block_input ();
@@ -4561,8 +4483,8 @@ xaw_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data)
     part = scroll_bar_move_ratio;
 
   window_being_scrolled = bar->window;
-  bar->dragging = Qnil;
-  last_scroll_bar_part = part;
+  bar->dragging = -1;
+  bar->last_seen_part = part;
   x_send_scroll_bar_event (bar->window, part, position, height);
 }
 
@@ -4837,7 +4759,7 @@ x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int positio
       shown = (float) portion / whole;
     }
 
-  if (NILP (bar->dragging))
+  if (bar->dragging == -1)
     {
       int size, value;
 
@@ -4872,7 +4794,7 @@ x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int positio
                   NULL);
 
     /* Massage the top+shown values.  */
-    if (NILP (bar->dragging) || last_scroll_bar_part == scroll_bar_down_arrow)
+    if (bar->dragging == -1 || bar->last_seen_part == scroll_bar_down_arrow)
       top = max (0, min (1, top));
     else
       top = old_top;
@@ -4884,7 +4806,7 @@ x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int positio
        for `NARROWPROTO'.  See s/freebsd.h for an example.  */
     if (top != old_top || shown != old_shown)
       {
-       if (NILP (bar->dragging))
+       if (bar->dragging == -1)
          XawScrollbarSetThumb (widget, top, shown);
        else
          {
@@ -4949,8 +4871,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
        this case, no clear_frame is generated to reduce flickering.  */
     if (width > 0 && height > 0)
       x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                   left, top, width,
-                   window_box_height (w), False);
+                   left, top, width, window_box_height (w));
 
     window = XCreateWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                            /* Position and size of scroll bar.  */
@@ -4976,8 +4897,11 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
   bar->height = height;
   bar->start = 0;
   bar->end = 0;
-  bar->dragging = Qnil;
+  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
 
   /* Add bar to its frame's list of scroll bars.  */
   bar->next = FRAME_SCROLL_BARS (f);
@@ -5034,9 +4958,9 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
 static void
 x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end, int rebuild)
 {
-  int dragging = ! NILP (bar->dragging);
+  bool dragging = bar->dragging != -1;
   Window w = bar->x_window;
-  FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
+  struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
   GC gc = f->output_data.x->normal_gc;
 
   /* If the display is already accurate, do nothing.  */
@@ -5086,11 +5010,9 @@ x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end, int rebuild
        zero-height areas; that means "clear to end of window."  */
     if (start > 0)
       x_clear_area (FRAME_X_DISPLAY (f), w,
-                   /* x, y, width, height, and exposures.  */
                    VERTICAL_SCROLL_BAR_LEFT_BORDER,
                    VERTICAL_SCROLL_BAR_TOP_BORDER,
-                   inside_width, start,
-                   False);
+                   inside_width, start);
 
     /* Change to proper foreground color if one is specified.  */
     if (f->output_data.x->scroll_bar_foreground_pixel != -1)
@@ -5113,12 +5035,9 @@ x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end, int rebuild
        clear zero-height areas; that means "clear to end of window." */
     if (end < inside_height)
       x_clear_area (FRAME_X_DISPLAY (f), w,
-                   /* x, y, width, height, and exposures.  */
                    VERTICAL_SCROLL_BAR_LEFT_BORDER,
                    VERTICAL_SCROLL_BAR_TOP_BORDER + end,
-                   inside_width, inside_height - end,
-                   False);
-
+                   inside_width, inside_height - end);
   }
 
   unblock_input ();
@@ -5166,11 +5085,11 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
   int top, height, left, sb_left, width, sb_width;
   int window_y, window_height;
 #ifdef USE_TOOLKIT_SCROLL_BARS
-  int fringe_extended_p;
+  bool fringe_extended_p;
 #endif
 
   /* Get window dimensions.  */
-  window_box (w, -1, 0, &window_y, 0, &window_height);
+  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;
@@ -5199,16 +5118,7 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
 #endif
 
 #ifdef USE_TOOLKIT_SCROLL_BARS
-  if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
-    fringe_extended_p = (WINDOW_LEFTMOST_P (w)
-                        && WINDOW_LEFT_FRINGE_WIDTH (w)
-                        && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
-                            || WINDOW_LEFT_MARGIN_COLS (w) == 0));
-  else
-    fringe_extended_p = (WINDOW_RIGHTMOST_P (w)
-                        && WINDOW_RIGHT_FRINGE_WIDTH (w)
-                        && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
-                            || WINDOW_RIGHT_MARGIN_COLS (w) == 0));
+  fringe_extended_p = WINDOW_FRINGE_EXTENDED_P (w);
 #endif
 
   /* Does the scroll bar exist yet?  */
@@ -5220,11 +5130,11 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
 #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, False);
+                         sb_left, top, sb_width, height);
          else
 #endif
            x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                         left, top, width, height, False);
+                         left, top, width, height);
          unblock_input ();
        }
 
@@ -5259,10 +5169,10 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
            {
              if (fringe_extended_p)
                x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                             sb_left, top, sb_width, height, False);
+                             sb_left, top, sb_width, height);
              else
                x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                             left, top, width, height, False);
+                             left, top, width, height);
            }
 #ifdef USE_GTK
           xg_update_scrollbar_pos (f,
@@ -5286,12 +5196,10 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
       if (VERTICAL_SCROLL_BAR_WIDTH_TRIM)
        {
          x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                       left, top, VERTICAL_SCROLL_BAR_WIDTH_TRIM,
-                       height, False);
+                       left, top, VERTICAL_SCROLL_BAR_WIDTH_TRIM, height);
          x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                        left + width - VERTICAL_SCROLL_BAR_WIDTH_TRIM,
-                       top, VERTICAL_SCROLL_BAR_WIDTH_TRIM,
-                       height, False);
+                       top, VERTICAL_SCROLL_BAR_WIDTH_TRIM, height);
        }
 
       /* Clear areas not covered by the scroll bar because it's not as
@@ -5305,11 +5213,10 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
          {
            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, False);
+                           left + area_width - rest, top, rest, height);
            else
              x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                           left, top, rest, height, False);
+                           left, top, rest, height);
          }
       }
 
@@ -5344,7 +5251,7 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
 #else /* not USE_TOOLKIT_SCROLL_BARS */
   /* Set the scroll bar's current state, unless we're currently being
      dragged.  */
-  if (NILP (bar->dragging))
+  if (bar->dragging == -1)
     {
       int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height);
 
@@ -5377,7 +5284,7 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
    `*redeem_scroll_bar_hook' is applied to its window before the judgment.  */
 
 static void
-XTcondemn_scroll_bars (FRAME_PTR frame)
+XTcondemn_scroll_bars (struct frame *frame)
 {
   /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS.  */
   while (! NILP (FRAME_SCROLL_BARS (frame)))
@@ -5445,7 +5352,7 @@ XTredeem_scroll_bar (struct window *window)
    last call to `*condemn_scroll_bars_hook'.  */
 
 static void
-XTjudge_scroll_bars (FRAME_PTR f)
+XTjudge_scroll_bars (struct frame *f)
 {
   Lisp_Object bar, next;
 
@@ -5481,7 +5388,7 @@ static void
 x_scroll_bar_expose (struct scroll_bar *bar, XEvent *event)
 {
   Window w = bar->x_window;
-  FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
+  struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
   GC gc = f->output_data.x->normal_gc;
   int width_trim = VERTICAL_SCROLL_BAR_WIDTH_TRIM;
 
@@ -5554,14 +5461,13 @@ x_scroll_bar_handle_click (struct scroll_bar *bar, XEvent *event, struct input_e
 
 #ifndef USE_TOOLKIT_SCROLL_BARS
     /* If the user has released the handle, set it to its final position.  */
-    if (event->type == ButtonRelease
-       && ! NILP (bar->dragging))
+    if (event->type == ButtonRelease && bar->dragging != -1)
       {
-       int new_start = y - XINT (bar->dragging);
+       int new_start = y - bar->dragging;
        int new_end = new_start + bar->end - bar->start;
 
        x_scroll_bar_set_handle (bar, new_start, new_end, 0);
-       bar->dragging = Qnil;
+       bar->dragging = -1;
       }
 #endif
 
@@ -5578,20 +5484,20 @@ x_scroll_bar_handle_click (struct scroll_bar *bar, XEvent *event, struct input_e
    mark bits.  */
 
 static void
-x_scroll_bar_note_movement (struct scroll_bar *bar, XEvent *event)
+x_scroll_bar_note_movement (struct scroll_bar *bar, XMotionEvent *event)
 {
-  FRAME_PTR f = XFRAME (XWINDOW (bar->window)->frame);
+  struct frame *f = XFRAME (XWINDOW (bar->window)->frame);
 
-  last_mouse_movement_time = event->xmotion.time;
+  last_mouse_movement_time = event->time;
 
   f->mouse_moved = 1;
   XSETVECTOR (last_mouse_scroll_bar, bar);
 
   /* If we're dragging the bar, display it.  */
-  if (! NILP (bar->dragging))
+  if (bar->dragging != -1)
     {
       /* Where should the handle be now?  */
-      int new_start = event->xmotion.y - XINT (bar->dragging);
+      int new_start = event->y - bar->dragging;
 
       if (new_start != bar->start)
        {
@@ -5608,13 +5514,13 @@ x_scroll_bar_note_movement (struct scroll_bar *bar, XEvent *event)
    on the scroll bar.  */
 
 static void
-x_scroll_bar_report_motion (FRAME_PTR *fp, Lisp_Object *bar_window,
+x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
                            enum scroll_bar_part *part, Lisp_Object *x,
                            Lisp_Object *y, Time *timestamp)
 {
   struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
   Window w = bar->x_window;
-  FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
+  struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
   int win_x, win_y;
   Window dummy_window;
   int dummy_coord;
@@ -5643,8 +5549,8 @@ x_scroll_bar_report_motion (FRAME_PTR *fp, Lisp_Object *bar_window,
 
       win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER;
 
-      if (! NILP (bar->dragging))
-       win_y -= XINT (bar->dragging);
+      if (bar->dragging != -1)
+       win_y -= bar->dragging;
 
       if (win_y < 0)
        win_y = 0;
@@ -5654,7 +5560,7 @@ x_scroll_bar_report_motion (FRAME_PTR *fp, Lisp_Object *bar_window,
       *fp = f;
       *bar_window = bar->window;
 
-      if (! NILP (bar->dragging))
+      if (bar->dragging != -1)
        *part = scroll_bar_handle;
       else if (win_y < bar->start)
        *part = scroll_bar_above_handle;
@@ -5682,7 +5588,7 @@ x_scroll_bar_report_motion (FRAME_PTR *fp, Lisp_Object *bar_window,
    redraw them.  */
 
 static void
-x_scroll_bar_clear (FRAME_PTR f)
+x_scroll_bar_clear (struct frame *f)
 {
 #ifndef USE_TOOLKIT_SCROLL_BARS
   Lisp_Object bar;
@@ -5699,18 +5605,7 @@ x_scroll_bar_clear (FRAME_PTR f)
 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 }
 
-\f
-/* The main X event-reading loop - XTread_socket.  */
-
-/* This holds the state XLookupString needs to implement dead keys
-   and other tricks known as "compose processing".  _X Window System_
-   says that a portable program can't use this, but Stephen Gildea assures
-   me that letting the compiler initialize it to zeros will work okay.
-
-   This must be defined outside of XTread_socket, for the same reasons
-   given for enter_timestamp, above.  */
-
-static XComposeStatus compose_status;
+#ifdef ENABLE_CHECKING
 
 /* Record the last 100 characters stored
    to help debug the loss-of-chars-during-GC problem.  */
@@ -5723,6 +5618,12 @@ static short temp_buffer[100];
     temp_index = 0;                                            \
   temp_buffer[temp_index++] = (keysym)
 
+#else /* not ENABLE_CHECKING */
+
+#define STORE_KEYSYM_FOR_DEBUG(keysym) ((void)0)
+
+#endif /* ENABLE_CHECKING */
+
 /* Set this to nonzero to fake an "X I/O error"
    on a particular display.  */
 
@@ -5860,6 +5761,12 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
   struct coding_system coding;
   XEvent event = *eventptr;
   Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
+  /* This holds the state XLookupString needs to implement dead keys
+     and other tricks known as "compose processing".  _X Window System_
+     says that a portable program can't use this, but Stephen Gildea assures
+     me that letting the compiler initialize it to zeros will work okay.  */
+  static XComposeStatus compose_status;
+
   USE_SAFE_ALLOCA;
 
   *finish = X_EVENT_NORMAL;
@@ -6153,11 +6060,10 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
         {
 #ifdef USE_GTK
           /* This seems to be needed for GTK 2.6.  */
-          x_clear_area (event.xexpose.display,
-                        event.xexpose.window,
-                        event.xexpose.x, event.xexpose.y,
-                        event.xexpose.width, event.xexpose.height,
-                        FALSE);
+         x_clear_area (event.xexpose.display,
+                       event.xexpose.window,
+                       event.xexpose.x, event.xexpose.y,
+                       event.xexpose.width, event.xexpose.height);
 #endif
           if (!FRAME_VISIBLE_P (f))
             {
@@ -6229,7 +6135,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
 
     case UnmapNotify:
       /* Redo the mouse-highlight after the tooltip has gone.  */
-      if (event.xmap.window == tip_window)
+      if (event.xunmap.window == tip_window)
         {
           tip_window = 0;
           redo_mouse_highlight ();
@@ -6319,6 +6225,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
 
       f = x_any_window_to_frame (dpyinfo, event.xkey.window);
 
+#if ! defined (USE_GTK)
       /* If mouse-highlight is an integer, input clears out
         mouse highlighting.  */
       if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
@@ -6328,6 +6235,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
           clear_mouse_face (hlinfo);
           hlinfo->mouse_face_hidden = 1;
         }
+#endif
 
 #if defined USE_MOTIF && defined USE_TOOLKIT_SCROLL_BARS
       if (f == 0)
@@ -6733,18 +6641,16 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
             /* Generate SELECT_WINDOW_EVENTs when needed.
                Don't let popup menus influence things (bug#1261).  */
             if (!NILP (Vmouse_autoselect_window) && !popup_activated ())
-              {
-                Lisp_Object window;
-
-                window = window_from_coordinates (f,
-                                                  event.xmotion.x, event.xmotion.y,
-                                                  0, 0);
-
-                /* Window will be selected only when it is not selected now and
-                   last mouse movement event was not in it.  Minibuffer window
-                   will be selected only when it is active.  */
-                if (WINDOWP (window)
-                    && !EQ (window, last_window)
+             {
+               static Lisp_Object last_mouse_window;
+               Lisp_Object window = window_from_coordinates
+                 (f, event.xmotion.x, event.xmotion.y, 0, 0);
+
+               /* Window will be selected only when it is not selected now and
+                  last mouse movement event was not in it.  Minibuffer window
+                  will be selected only when it is active.  */
+               if (WINDOWP (window)
+                   && !EQ (window, last_mouse_window)
                    && !EQ (window, selected_window)
                    /* For click-to-focus window managers
                       create event iff we don't leave the
@@ -6752,13 +6658,13 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
                    && (focus_follows_mouse
                        || (EQ (XWINDOW (window)->frame,
                                XWINDOW (selected_window)->frame))))
-                  {
-                    inev.ie.kind = SELECT_WINDOW_EVENT;
-                    inev.ie.frame_or_window = window;
-                  }
-
-                last_window=window;
-              }
+                 {
+                   inev.ie.kind = SELECT_WINDOW_EVENT;
+                   inev.ie.frame_or_window = window;
+                 }
+               /* Remember the last window where we saw the mouse.  */
+               last_mouse_window = window;
+             }
             if (!note_mouse_movement (f, &event.xmotion))
              help_echo_string = previous_help_echo_string;
           }
@@ -6770,7 +6676,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
                                         event.xmotion.window);
 
             if (bar)
-              x_scroll_bar_note_movement (bar, &event);
+              x_scroll_bar_note_movement (bar, &event.xmotion);
 #endif /* USE_TOOLKIT_SCROLL_BARS */
 
             /* If we move outside the frame, then we're
@@ -6850,7 +6756,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
       {
         /* If we decide we want to generate an event to be seen
            by the rest of Emacs, we put it here.  */
-        int tool_bar_p = 0;
+        bool tool_bar_p = 0;
 
         memset (&compose_status, 0, sizeof (compose_status));
        last_mouse_glyph_frame = 0;
@@ -6869,6 +6775,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
 #endif
         if (f)
           {
+#if ! defined (USE_GTK)
             /* Is this in the tool-bar?  */
             if (WINDOWP (f->tool_bar_window)
                 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)))
@@ -6881,13 +6788,11 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
                 tool_bar_p = EQ (window, f->tool_bar_window);
 
                 if (tool_bar_p && event.xbutton.button < 4)
-                  {
-                   handle_tool_bar_click (f, x, y,
-                                          event.xbutton.type == ButtonPress,
-                                          x_x_to_emacs_modifiers (dpyinfo,
-                                                                  event.xbutton.state));
-                  }
+                 handle_tool_bar_click
+                   (f, x, y, event.xbutton.type == ButtonPress,
+                    x_x_to_emacs_modifiers (dpyinfo, event.xbutton.state));
               }
+#endif /* !USE_GTK */
 
             if (!tool_bar_p)
 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
@@ -6971,14 +6876,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
             && event.xbutton.same_screen)
           {
             SET_SAVED_BUTTON_EVENT;
-            XSETFRAME (last_mouse_press_frame, f);
             *finish = X_EVENT_DROP;
           }
-        else if (event.type == ButtonPress)
-          {
-            last_mouse_press_frame = Qnil;
-            goto OTHER;
-          }
         else
           goto OTHER;
 #endif /* USE_X_TOOLKIT || USE_GTK */
@@ -7208,7 +7107,8 @@ XTread_socket (struct terminal *terminal, struct input_event *hold_quit)
    mode lines must be clipped to the whole window.  */
 
 static void
-x_clip_to_row (struct window *w, struct glyph_row *row, int area, GC gc)
+x_clip_to_row (struct window *w, struct glyph_row *row,
+              enum glyph_row_area area, GC gc)
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   XRectangle clip_rect;
@@ -7385,8 +7285,7 @@ x_define_frame_cursor (struct frame *f, Cursor cursor)
 static void
 x_clear_frame_area (struct frame *f, int x, int y, int width, int height)
 {
-  x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-               x, y, width, height, False);
+  x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), x, y, width, height);
 #ifdef USE_GTK
   /* Must queue a redraw, because scroll bars might have been cleared.  */
   if (FRAME_GTK_WIDGET (f))
@@ -7398,7 +7297,9 @@ x_clear_frame_area (struct frame *f, int x, int y, int width, int height)
 /* RIF: Draw cursor on window W.  */
 
 static void
-x_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x, int y, int cursor_type, int cursor_width, int on_p, int active_p)
+x_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x,
+                     int y, enum text_cursor_kinds cursor_type,
+                     int cursor_width, bool on_p, bool active_p)
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
 
@@ -7451,9 +7352,7 @@ x_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x, int
 #endif
     }
 
-#ifndef XFlush
   XFlush (FRAME_X_DISPLAY (f));
-#endif
 }
 
 \f
@@ -7659,7 +7558,7 @@ x_check_errors (Display *dpy, const char *format)
 /* Nonzero if we had any X protocol errors
    since we did x_catch_errors on DPY.  */
 
-int
+bool
 x_had_errors_p (Display *dpy)
 {
   /* Make sure to catch any errors incurred so far.  */
@@ -7824,10 +7723,9 @@ static void x_error_quitter (Display *, XErrorEvent *);
 static int
 x_error_handler (Display *display, XErrorEvent *event)
 {
-#ifdef HAVE_GTK3
-  if (event->error_code == BadMatch
-      && event->request_code == X_SetInputFocus
-      && event->minor_code == 0)
+#if defined USE_GTK && defined HAVE_GTK3
+  if ((event->error_code == BadMatch || event->error_code == BadWindow)
+      && event->request_code == X_SetInputFocus)
     {
       return 0;
     }
@@ -8098,13 +7996,10 @@ xim_initialize (struct x_display_info *dpyinfo, char *resource_name)
     {
 #ifdef HAVE_X11R6_XIM
       struct xim_inst_t *xim_inst = xmalloc (sizeof *xim_inst);
-      ptrdiff_t len;
 
       dpyinfo->xim_callback_data = xim_inst;
       xim_inst->dpyinfo = dpyinfo;
-      len = strlen (resource_name);
-      xim_inst->resource_name = xmalloc (len + 1);
-      memcpy (xim_inst->resource_name, resource_name, len + 1);
+      xim_inst->resource_name = xstrdup (resource_name);
       XRegisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb,
                                      resource_name, emacs_class,
                                      xim_instantiate_callback,
@@ -8210,9 +8105,6 @@ x_set_offset (struct frame *f, register int xoff, register int yoff, int change_
 
   if (change_gravity > 0)
     {
-      FRAME_X_OUTPUT (f)->left_before_move = f->left_pos;
-      FRAME_X_OUTPUT (f)->top_before_move = f->top_pos;
-
       f->top_pos = yoff;
       f->left_pos = xoff;
       f->size_hint_flags &= ~ (XNegative | YNegative);
@@ -8370,9 +8262,9 @@ set_wm_state (Lisp_Object frame, int add, Atom atom, Atom value)
                        (make_number (add ? 1 : 0),
                         Fcons
                         (make_fixnum_or_float (atom),
-                         value != 0
-                         ? Fcons (make_fixnum_or_float (value), Qnil)
-                         : Qnil)));
+                         (value != 0
+                         ? list1 (make_fixnum_or_float (value))
+                         : Qnil))));
 }
 
 void
@@ -8533,7 +8425,7 @@ do_ewmh_fullscreen (struct frame *f)
 }
 
 static void
-XTfullscreen_hook (FRAME_PTR f)
+XTfullscreen_hook (struct frame *f)
 {
   if (FRAME_VISIBLE_P (f))
     {
@@ -8711,8 +8603,8 @@ x_wait_for_event (struct frame *f, int eventtype)
 {
   int level = interrupt_input_blocked;
 
-  SELECT_TYPE fds;
-  EMACS_TIME tmo, tmo_at, time_now;
+  fd_set fds;
+  struct timespec tmo, tmo_at, time_now;
   int fd = ConnectionNumber (FRAME_X_DISPLAY (f));
 
   pending_event_wait.f = f;
@@ -8720,8 +8612,8 @@ x_wait_for_event (struct frame *f, int eventtype)
 
   /* Set timeout to 0.1 second.  Hopefully not noticeable.
      Maybe it should be configurable.  */
-  tmo = make_emacs_time (0, 100 * 1000 * 1000);
-  tmo_at = add_emacs_time (current_emacs_time (), tmo);
+  tmo = make_timespec (0, 100 * 1000 * 1000);
+  tmo_at = timespec_add (current_timespec (), tmo);
 
   while (pending_event_wait.eventtype)
     {
@@ -8734,11 +8626,11 @@ x_wait_for_event (struct frame *f, int eventtype)
       FD_ZERO (&fds);
       FD_SET (fd, &fds);
 
-      time_now = current_emacs_time ();
-      if (EMACS_TIME_LT (tmo_at, time_now))
+      time_now = current_timespec ();
+      if (timespec_cmp (tmo_at, time_now) < 0)
        break;
 
-      tmo = sub_emacs_time (tmo_at, time_now);
+      tmo = timespec_sub (tmo_at, time_now);
       if (pselect (fd + 1, &fds, NULL, NULL, &tmo, NULL) == 0)
         break; /* Timeout */
     }
@@ -8934,7 +8826,7 @@ x_lower_frame (struct frame *f)
 /* Request focus with XEmbed */
 
 void
-xembed_request_focus (FRAME_PTR f)
+xembed_request_focus (struct frame *f)
 {
   /* See XEmbed Protocol Specification at
      http://freedesktop.org/wiki/Specifications/xembed-spec  */
@@ -8946,7 +8838,7 @@ xembed_request_focus (FRAME_PTR f)
 /* Activate frame with Extended Window Manager Hints */
 
 void
-x_ewmh_activate_frame (FRAME_PTR f)
+x_ewmh_activate_frame (struct frame *f)
 {
   /* See Window Manager Specification/Extended Window Manager Hints at
      http://freedesktop.org/wiki/Specifications/wm-spec  */
@@ -8964,7 +8856,7 @@ x_ewmh_activate_frame (FRAME_PTR f)
 }
 
 static void
-XTframe_raise_lower (FRAME_PTR f, int raise_flag)
+XTframe_raise_lower (struct frame *f, int raise_flag)
 {
   if (raise_flag)
     x_raise_frame (f);
@@ -9448,6 +9340,19 @@ x_free_frame_resources (struct frame *f)
        unload_color (f, f->output_data.x->black_relief.pixel);
 
       x_free_gcs (f);
+
+      /* Free extra GCs allocated by x_setup_relief_colors.  */
+      if (f->output_data.x->white_relief.gc)
+       {
+         XFreeGC (dpyinfo->display, f->output_data.x->white_relief.gc);
+         f->output_data.x->white_relief.gc = 0;
+       }
+      if (f->output_data.x->black_relief.gc)
+       {
+         XFreeGC (dpyinfo->display, f->output_data.x->black_relief.gc);
+         f->output_data.x->black_relief.gc = 0;
+       }
+
       XFlush (FRAME_X_DISPLAY (f));
     }
 
@@ -9461,16 +9366,8 @@ x_free_frame_resources (struct frame *f)
     dpyinfo->x_focus_event_frame = 0;
   if (f == dpyinfo->x_highlight_frame)
     dpyinfo->x_highlight_frame = 0;
-
   if (f == hlinfo->mouse_face_mouse_frame)
-    {
-      hlinfo->mouse_face_beg_row
-       = hlinfo->mouse_face_beg_col = -1;
-      hlinfo->mouse_face_end_row
-       = hlinfo->mouse_face_end_col = -1;
-      hlinfo->mouse_face_window = Qnil;
-      hlinfo->mouse_face_mouse_frame = 0;
-    }
+    reset_mouse_highlight (hlinfo);
 
   unblock_input ();
 }
@@ -9813,18 +9710,11 @@ get_bits_and_offset (long unsigned int mask, int *bits, int *offset)
 /* Return 1 if display DISPLAY is available for use, 0 otherwise.
    But don't permanently open it, just test its availability.  */
 
-int
+bool
 x_display_ok (const char *display)
 {
-    int dpy_ok = 1;
-    Display *dpy;
-
-    dpy = XOpenDisplay (display);
-    if (dpy)
-      XCloseDisplay (dpy);
-    else
-      dpy_ok = 0;
-    return dpy_ok;
+  Display *dpy = XOpenDisplay (display);
+  return dpy ? (XCloseDisplay (dpy), 1) : 0;
 }
 
 #ifdef USE_GTK
@@ -9849,7 +9739,6 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
   struct terminal *terminal;
   struct x_display_info *dpyinfo;
   XrmDatabase xrdb;
-  Mouse_HLInfo *hlinfo;
   ptrdiff_t lim;
 
   block_input ();
@@ -9921,7 +9810,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
 
         dpy = DEFAULT_GDK_DISPLAY ();
 
-#if GTK_MAJOR_VERSION <= 2 && GTK_MINOR_VERSION <= 90
+#if ! GTK_CHECK_VERSION (2, 90, 0)
         /* Load our own gtkrc if it exists.  */
         {
           const char *file = "~/.emacs.d/gtkrc";
@@ -9990,8 +9879,6 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
   /* We have definitely succeeded.  Record the new connection.  */
 
   dpyinfo = xzalloc (sizeof *dpyinfo);
-  hlinfo = &dpyinfo->mouse_highlight;
-
   terminal = x_create_terminal (dpyinfo);
 
   {
@@ -10062,9 +9949,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
   dpyinfo->display = dpy;
 
   /* Set the name of the terminal. */
-  terminal->name = xmalloc (SBYTES (display_name) + 1);
-  memcpy (terminal->name, SSDATA (display_name), SBYTES (display_name));
-  terminal->name[SBYTES (display_name)] = 0;
+  terminal->name = xlispstrdup (display_name);
 
 #if 0
   XSetAfterFunction (x_current_display, x_trace_wire);
@@ -10106,33 +9991,12 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
   select_visual (dpyinfo);
   dpyinfo->cmap = DefaultColormapOfScreen (dpyinfo->screen);
   dpyinfo->root_window = RootWindowOfScreen (dpyinfo->screen);
-  dpyinfo->client_leader_window = 0;
-  dpyinfo->grabbed = 0;
-  dpyinfo->reference_count = 0;
   dpyinfo->icon_bitmap_id = -1;
-  dpyinfo->n_fonts = 0;
-  dpyinfo->bitmaps = 0;
-  dpyinfo->bitmaps_size = 0;
-  dpyinfo->bitmaps_last = 0;
-  dpyinfo->scratch_cursor_gc = 0;
-  hlinfo->mouse_face_mouse_frame = 0;
-  hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
-  hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
-  hlinfo->mouse_face_face_id = DEFAULT_FACE_ID;
-  hlinfo->mouse_face_window = Qnil;
-  hlinfo->mouse_face_overlay = Qnil;
-  hlinfo->mouse_face_mouse_x = hlinfo->mouse_face_mouse_y = 0;
-  hlinfo->mouse_face_defer = 0;
-  hlinfo->mouse_face_hidden = 0;
-  dpyinfo->x_focus_frame = 0;
-  dpyinfo->x_focus_event_frame = 0;
-  dpyinfo->x_highlight_frame = 0;
   dpyinfo->wm_type = X_WMTYPE_UNKNOWN;
 
-  /* See if we can construct pixel values from RGB values.  */
-  dpyinfo->red_bits = dpyinfo->blue_bits = dpyinfo->green_bits = 0;
-  dpyinfo->red_offset = dpyinfo->blue_offset = dpyinfo->green_offset = 0;
+  reset_mouse_highlight (&dpyinfo->mouse_highlight);
 
+  /* See if we can construct pixel values from RGB values.  */
   if (dpyinfo->visual->class == TrueColor)
     {
       get_bits_and_offset (dpyinfo->visual->red_mask,
@@ -10192,69 +10056,73 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
     }
 
   {
-    const struct
+    static const struct
     {
       const char *name;
-      Atom *atom;
+      int offset;
     } atom_refs[] = {
-      { "WM_PROTOCOLS", &dpyinfo->Xatom_wm_protocols  },
-      { "WM_TAKE_FOCUS", &dpyinfo->Xatom_wm_take_focus },
-      { "WM_SAVE_YOURSELF", &dpyinfo->Xatom_wm_save_yourself },
-      { "WM_DELETE_WINDOW", &dpyinfo->Xatom_wm_delete_window },
-      { "WM_CHANGE_STATE", &dpyinfo->Xatom_wm_change_state },
-      { "WM_CONFIGURE_DENIED", &dpyinfo->Xatom_wm_configure_denied },
-      { "WM_MOVED", &dpyinfo->Xatom_wm_window_moved },
-      { "WM_CLIENT_LEADER", &dpyinfo->Xatom_wm_client_leader },
-      { "Editres", &dpyinfo->Xatom_editres },
-      { "CLIPBOARD", &dpyinfo->Xatom_CLIPBOARD },
-      { "TIMESTAMP", &dpyinfo->Xatom_TIMESTAMP },
-      { "TEXT", &dpyinfo->Xatom_TEXT },
-      { "COMPOUND_TEXT", &dpyinfo->Xatom_COMPOUND_TEXT },
-      { "UTF8_STRING", &dpyinfo->Xatom_UTF8_STRING },
-      { "DELETE", &dpyinfo->Xatom_DELETE },
-      { "MULTIPLE", &dpyinfo->Xatom_MULTIPLE },
-      { "INCR", &dpyinfo->Xatom_INCR },
-      { "_EMACS_TMP_",  &dpyinfo->Xatom_EMACS_TMP },
-      { "TARGETS", &dpyinfo->Xatom_TARGETS },
-      { "NULL", &dpyinfo->Xatom_NULL },
-      { "ATOM", &dpyinfo->Xatom_ATOM },
-      { "ATOM_PAIR", &dpyinfo->Xatom_ATOM_PAIR },
-      { "CLIPBOARD_MANAGER", &dpyinfo->Xatom_CLIPBOARD_MANAGER },
-      { "_XEMBED_INFO", &dpyinfo->Xatom_XEMBED_INFO },
+#define ATOM_REFS_INIT(string, member) \
+      { string, offsetof (struct x_display_info, member) },
+      ATOM_REFS_INIT ("WM_PROTOCOLS", Xatom_wm_protocols)
+      ATOM_REFS_INIT ("WM_TAKE_FOCUS", Xatom_wm_take_focus)
+      ATOM_REFS_INIT ("WM_SAVE_YOURSELF", Xatom_wm_save_yourself)
+      ATOM_REFS_INIT ("WM_DELETE_WINDOW", Xatom_wm_delete_window)
+      ATOM_REFS_INIT ("WM_CHANGE_STATE", Xatom_wm_change_state)
+      ATOM_REFS_INIT ("WM_CONFIGURE_DENIED", Xatom_wm_configure_denied)
+      ATOM_REFS_INIT ("WM_MOVED", Xatom_wm_window_moved)
+      ATOM_REFS_INIT ("WM_CLIENT_LEADER", Xatom_wm_client_leader)
+      ATOM_REFS_INIT ("Editres", Xatom_editres)
+      ATOM_REFS_INIT ("CLIPBOARD", Xatom_CLIPBOARD)
+      ATOM_REFS_INIT ("TIMESTAMP", Xatom_TIMESTAMP)
+      ATOM_REFS_INIT ("TEXT", Xatom_TEXT)
+      ATOM_REFS_INIT ("COMPOUND_TEXT", Xatom_COMPOUND_TEXT)
+      ATOM_REFS_INIT ("UTF8_STRING", Xatom_UTF8_STRING)
+      ATOM_REFS_INIT ("DELETE", Xatom_DELETE)
+      ATOM_REFS_INIT ("MULTIPLE", Xatom_MULTIPLE)
+      ATOM_REFS_INIT ("INCR", Xatom_INCR)
+      ATOM_REFS_INIT ("_EMACS_TMP_",  Xatom_EMACS_TMP)
+      ATOM_REFS_INIT ("TARGETS", Xatom_TARGETS)
+      ATOM_REFS_INIT ("NULL", Xatom_NULL)
+      ATOM_REFS_INIT ("ATOM", Xatom_ATOM)
+      ATOM_REFS_INIT ("ATOM_PAIR", Xatom_ATOM_PAIR)
+      ATOM_REFS_INIT ("CLIPBOARD_MANAGER", Xatom_CLIPBOARD_MANAGER)
+      ATOM_REFS_INIT ("_XEMBED_INFO", Xatom_XEMBED_INFO)
       /* For properties of font.  */
-      { "PIXEL_SIZE", &dpyinfo->Xatom_PIXEL_SIZE },
-      { "AVERAGE_WIDTH", &dpyinfo->Xatom_AVERAGE_WIDTH },
-      { "_MULE_BASELINE_OFFSET", &dpyinfo->Xatom_MULE_BASELINE_OFFSET },
-      { "_MULE_RELATIVE_COMPOSE", &dpyinfo->Xatom_MULE_RELATIVE_COMPOSE },
-      { "_MULE_DEFAULT_ASCENT", &dpyinfo->Xatom_MULE_DEFAULT_ASCENT },
+      ATOM_REFS_INIT ("PIXEL_SIZE", Xatom_PIXEL_SIZE)
+      ATOM_REFS_INIT ("AVERAGE_WIDTH", Xatom_AVERAGE_WIDTH)
+      ATOM_REFS_INIT ("_MULE_BASELINE_OFFSET", Xatom_MULE_BASELINE_OFFSET)
+      ATOM_REFS_INIT ("_MULE_RELATIVE_COMPOSE", Xatom_MULE_RELATIVE_COMPOSE)
+      ATOM_REFS_INIT ("_MULE_DEFAULT_ASCENT", Xatom_MULE_DEFAULT_ASCENT)
       /* Ghostscript support.  */
-      { "DONE", &dpyinfo->Xatom_DONE },
-      { "PAGE", &dpyinfo->Xatom_PAGE },
-      { "SCROLLBAR", &dpyinfo->Xatom_Scrollbar },
-      { "_XEMBED", &dpyinfo->Xatom_XEMBED },
+      ATOM_REFS_INIT ("DONE", Xatom_DONE)
+      ATOM_REFS_INIT ("PAGE", Xatom_PAGE)
+      ATOM_REFS_INIT ("SCROLLBAR", Xatom_Scrollbar)
+      ATOM_REFS_INIT ("_XEMBED", Xatom_XEMBED)
       /* EWMH */
-      { "_NET_WM_STATE", &dpyinfo->Xatom_net_wm_state },
-      { "_NET_WM_STATE_FULLSCREEN", &dpyinfo->Xatom_net_wm_state_fullscreen },
-      { "_NET_WM_STATE_MAXIMIZED_HORZ",
-        &dpyinfo->Xatom_net_wm_state_maximized_horz },
-      { "_NET_WM_STATE_MAXIMIZED_VERT",
-        &dpyinfo->Xatom_net_wm_state_maximized_vert },
-      { "_NET_WM_STATE_STICKY", &dpyinfo->Xatom_net_wm_state_sticky },
-      { "_NET_WM_STATE_HIDDEN", &dpyinfo->Xatom_net_wm_state_hidden },
-      { "_NET_WM_WINDOW_TYPE", &dpyinfo->Xatom_net_window_type },
-      { "_NET_WM_WINDOW_TYPE_TOOLTIP",
-        &dpyinfo->Xatom_net_window_type_tooltip },
-      { "_NET_WM_ICON_NAME", &dpyinfo->Xatom_net_wm_icon_name },
-      { "_NET_WM_NAME", &dpyinfo->Xatom_net_wm_name },
-      { "_NET_SUPPORTED",  &dpyinfo->Xatom_net_supported },
-      { "_NET_SUPPORTING_WM_CHECK", &dpyinfo->Xatom_net_supporting_wm_check },
-      { "_NET_WM_WINDOW_OPACITY", &dpyinfo->Xatom_net_wm_window_opacity },
-      { "_NET_ACTIVE_WINDOW", &dpyinfo->Xatom_net_active_window },
-      { "_NET_FRAME_EXTENTS", &dpyinfo->Xatom_net_frame_extents },
+      ATOM_REFS_INIT ("_NET_WM_STATE", Xatom_net_wm_state)
+      ATOM_REFS_INIT ("_NET_WM_STATE_FULLSCREEN", Xatom_net_wm_state_fullscreen)
+      ATOM_REFS_INIT ("_NET_WM_STATE_MAXIMIZED_HORZ",
+                     Xatom_net_wm_state_maximized_horz)
+      ATOM_REFS_INIT ("_NET_WM_STATE_MAXIMIZED_VERT",
+                     Xatom_net_wm_state_maximized_vert)
+      ATOM_REFS_INIT ("_NET_WM_STATE_STICKY", Xatom_net_wm_state_sticky)
+      ATOM_REFS_INIT ("_NET_WM_STATE_HIDDEN", Xatom_net_wm_state_hidden)
+      ATOM_REFS_INIT ("_NET_WM_WINDOW_TYPE", Xatom_net_window_type)
+      ATOM_REFS_INIT ("_NET_WM_WINDOW_TYPE_TOOLTIP",
+                     Xatom_net_window_type_tooltip)
+      ATOM_REFS_INIT ("_NET_WM_ICON_NAME", Xatom_net_wm_icon_name)
+      ATOM_REFS_INIT ("_NET_WM_NAME", Xatom_net_wm_name)
+      ATOM_REFS_INIT ("_NET_SUPPORTED",  Xatom_net_supported)
+      ATOM_REFS_INIT ("_NET_SUPPORTING_WM_CHECK", Xatom_net_supporting_wm_check)
+      ATOM_REFS_INIT ("_NET_WM_WINDOW_OPACITY", Xatom_net_wm_window_opacity)
+      ATOM_REFS_INIT ("_NET_ACTIVE_WINDOW", Xatom_net_active_window)
+      ATOM_REFS_INIT ("_NET_FRAME_EXTENTS", Xatom_net_frame_extents)
+      ATOM_REFS_INIT ("_NET_CURRENT_DESKTOP", Xatom_net_current_desktop)
+      ATOM_REFS_INIT ("_NET_WORKAREA", Xatom_net_workarea)
       /* Session management */
-      { "SM_CLIENT_ID", &dpyinfo->Xatom_SM_CLIENT_ID },
-      { "_XSETTINGS_SETTINGS", &dpyinfo->Xatom_xsettings_prop },
-      { "MANAGER", &dpyinfo->Xatom_xsettings_mgr },
+      ATOM_REFS_INIT ("SM_CLIENT_ID", Xatom_SM_CLIENT_ID)
+      ATOM_REFS_INIT ("_XSETTINGS_SETTINGS", Xatom_xsettings_prop)
+      ATOM_REFS_INIT ("MANAGER", Xatom_xsettings_mgr)
     };
 
     int i;
@@ -10279,7 +10147,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
                   False, atoms_return);
 
     for (i = 0; i < atom_count; i++)
-      *atom_refs[i].atom = atoms_return[i];
+      *(Atom *) ((char *) dpyinfo + atom_refs[i].offset) = atoms_return[i];
 
     /* Manual copy of last atom */
     dpyinfo->Xatom_xsettings_sel = atoms_return[i];
@@ -10289,16 +10157,8 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
   }
 
   dpyinfo->x_dnd_atoms_size = 8;
-  dpyinfo->x_dnd_atoms_length = 0;
   dpyinfo->x_dnd_atoms = xmalloc (sizeof *dpyinfo->x_dnd_atoms
                                   * dpyinfo->x_dnd_atoms_size);
-
-  dpyinfo->net_supported_atoms = NULL;
-  dpyinfo->nr_net_supported_atoms = 0;
-  dpyinfo->net_supported_window = 0;
-
-  connection = ConnectionNumber (dpyinfo->display);
-  dpyinfo->connection = connection;
   dpyinfo->gray
     = XCreatePixmapFromBitmapData (dpyinfo->display, dpyinfo->root_window,
                                   gray_bits, gray_width, gray_height,
@@ -10310,6 +10170,8 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
 
   xsettings_initialize (dpyinfo);
 
+  connection = ConnectionNumber (dpyinfo->display);
+
   /* This is only needed for distinguishing keyboard and process input.  */
   if (connection != 0)
     add_keyboard_wait_descriptor (connection);
@@ -10410,8 +10272,6 @@ x_delete_display (struct x_display_info *dpyinfo)
         break;
       }
 
-  delete_keyboard_wait_descriptor (dpyinfo->connection);
-
   /* 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)
@@ -10489,7 +10349,7 @@ x_activate_timeout_atimer (void)
   block_input ();
   if (!x_timeout_atimer_activated_flag)
     {
-      EMACS_TIME interval = make_emacs_time (0, 100 * 1000 * 1000);
+      struct timespec interval = make_timespec (0, 100 * 1000 * 1000);
       start_atimer (ATIMER_RELATIVE, interval, x_process_timeouts, 0);
       x_timeout_atimer_activated_flag = 1;
     }
@@ -10512,13 +10372,7 @@ static struct redisplay_interface x_redisplay_interface =
     x_after_update_window_line,
     x_update_window_begin,
     x_update_window_end,
-    x_cursor_to,
-    x_flush,
-#ifdef XFlush
     x_flush,
-#else
-    0,  /* flush_display_optional */
-#endif
     x_clear_window_mouse_face,
     x_get_glyph_overhangs,
     x_fix_overlapping_area,
@@ -10540,6 +10394,7 @@ void
 x_delete_terminal (struct terminal *terminal)
 {
   struct x_display_info *dpyinfo = terminal->display_info.x;
+  int connection = -1;
 
   /* Protect against recursive calls.  delete_frame in
      delete_terminal calls us back when it deletes our last frame.  */
@@ -10558,6 +10413,8 @@ x_delete_terminal (struct terminal *terminal)
      and dpyinfo->display was set to 0 to indicate that.  */
   if (dpyinfo->display)
     {
+      connection = ConnectionNumber (dpyinfo->display);
+
       x_destroy_all_bitmaps (dpyinfo);
       XSetCloseDownMode (dpyinfo->display, DestroyAll);
 
@@ -10598,6 +10455,10 @@ x_delete_terminal (struct terminal *terminal)
 #endif /* ! USE_GTK */
     }
 
+  /* No more input on this descriptor.  */
+  if (connection != -1)
+    delete_keyboard_wait_descriptor (connection);
+
   /* Mark as dead. */
   dpyinfo->display = NULL;
   x_delete_display (dpyinfo);
@@ -10625,11 +10486,11 @@ x_create_terminal (struct x_display_info *dpyinfo)
   terminal->delete_glyphs_hook = x_delete_glyphs;
   terminal->ring_bell_hook = XTring_bell;
   terminal->toggle_invisible_pointer_hook = XTtoggle_invisible_pointer;
-  terminal->reset_terminal_modes_hook = XTreset_terminal_modes;
-  terminal->set_terminal_modes_hook = XTset_terminal_modes;
+  terminal->reset_terminal_modes_hook = NULL;
+  terminal->set_terminal_modes_hook = NULL;
   terminal->update_begin_hook = x_update_begin;
   terminal->update_end_hook = x_update_end;
-  terminal->set_terminal_window_hook = XTset_terminal_window;
+  terminal->set_terminal_window_hook = NULL;
   terminal->read_socket_hook = XTread_socket;
   terminal->frame_up_to_date_hook = XTframe_up_to_date;
   terminal->mouse_position_hook = XTmouse_position;
@@ -10720,9 +10581,6 @@ syms_of_xterm (void)
   DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
   DEFSYM (Qlatin_1, "latin-1");
 
-  staticpro (&last_mouse_press_frame);
-  last_mouse_press_frame = Qnil;
-
 #ifdef USE_GTK
   xg_default_icon_file = build_pure_c_string ("icons/hicolor/scalable/apps/emacs.svg");
   staticpro (&xg_default_icon_file);