]> code.delx.au - gnu-emacs/blobdiff - src/xterm.c
* xterm.c, xfns.c (toplevel): Remove #ifdef HAVE_X_WINDOWS because
[gnu-emacs] / src / xterm.c
index 55347a3310e222f8a1278022190a18195b85d9c8..05766341cbc98f17cab3d0fae988c1f47455f111 100644 (file)
@@ -23,8 +23,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <config.h>
 #include <stdio.h>
 
-#ifdef HAVE_X_WINDOWS
-
 #include "lisp.h"
 #include "blockinput.h"
 #include "syssignal.h"
@@ -140,16 +138,11 @@ 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 bool any_help_event_p;
 
-/* Last window where we saw the mouse.  Used by mouse-autoselect-window.  */
-static Lisp_Object last_window;
-
 /* This is a chain of structures for all the X displays currently in
    use.  */
 
@@ -235,10 +228,6 @@ static Lisp_Object last_mouse_scroll_bar;
 
 static Time last_mouse_movement_time;
 
-/* Time for last user interaction as returned in X events.  */
-
-static Time last_user_time;
-
 /* Incremented by XTread_socket whenever it really tries to read
    events.  */
 
@@ -292,15 +281,11 @@ 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 *);
@@ -316,7 +301,8 @@ 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 *);
@@ -342,29 +328,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)
-    {
-      eassert (FRAME_X_P (f));
-      XFlush (FRAME_X_DISPLAY (f));
-    }
-  else
-    {
-      /* Flush all displays and so all frames on them.  */
-      struct x_display_info *xdi;
-      for (xdi = x_display_list; xdi; xdi = xdi->next)
-       XFlush (xdi->display);
-    }
+  XFlush (FRAME_X_DISPLAY (f));
   unblock_input ();
 }
 
@@ -434,7 +410,7 @@ x_find_topmost_parent (struct frame *f)
   Window win = None, wi = x->parent_desc;
   Display *dpy = FRAME_X_DISPLAY (f);
 
-  while (wi != FRAME_X_DISPLAY_INFO (f)->root_window)
+  while (wi != FRAME_DISPLAY_INFO (f)->root_window)
     {
       Window root;
       Window *children;
@@ -453,7 +429,7 @@ x_find_topmost_parent (struct frame *f)
 void
 x_set_frame_alpha (struct frame *f)
 {
-  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
   Display *dpy = FRAME_X_DISPLAY (f);
   Window win = FRAME_OUTER_WINDOW (f);
   double alpha = 1.0;
@@ -553,8 +529,7 @@ x_update_begin (struct frame *f)
 }
 
 
-/* Start update of window W.  Set output_cursor to the cursor
-   position of W.  */
+/* Start update of window W.  */
 
 static void
 x_update_window_begin (struct window *w)
@@ -562,7 +537,7 @@ x_update_window_begin (struct window *w)
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
 
-  set_output_cursor (&w->cursor);
+  w->output_cursor = w->cursor;
 
   block_input ();
 
@@ -612,18 +587,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);
@@ -634,11 +608,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;
-    }
+    reset_mouse_highlight (MOUSE_HL_INFO (XFRAME (w->frame)));
 }
 
 
@@ -705,10 +675,10 @@ x_after_update_window_line (struct window *w, 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 ();
     }
 }
@@ -723,7 +693,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)
     {
@@ -816,7 +786,7 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring
       if (p->overlay_p)
        {
          clipmask = XCreatePixmapFromBitmapData (display,
-                                                 FRAME_X_DISPLAY_INFO (f)->root_window,
+                                                 FRAME_DISPLAY_INFO (f)->root_window,
                                                  bits, p->wd, p->h,
                                                  1, 0, 1);
          gcv.clip_mask = clipmask;
@@ -840,27 +810,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
  ***********************************************************************/
@@ -941,14 +890,14 @@ x_set_cursor_gc (struct glyph_string *s)
       xgcv.graphics_exposures = False;
       mask = GCForeground | GCBackground | GCGraphicsExposures;
 
-      if (FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc)
-       XChangeGC (s->display, FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc,
+      if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
+       XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
                   mask, &xgcv);
       else
-       FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc
+       FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
          = XCreateGC (s->display, s->window, mask, &xgcv);
 
-      s->gc = FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc;
+      s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
     }
 }
 
@@ -988,14 +937,14 @@ x_set_mouse_face_gc (struct glyph_string *s)
       xgcv.graphics_exposures = False;
       mask = GCForeground | GCBackground | GCGraphicsExposures;
 
-      if (FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc)
-       XChangeGC (s->display, FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc,
+      if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
+       XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
                   mask, &xgcv);
       else
-       FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc
+       FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
          = XCreateGC (s->display, s->window, mask, &xgcv);
 
-      s->gc = FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc;
+      s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
 
     }
   eassert (s->gc != 0);
@@ -1366,7 +1315,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;
@@ -1431,7 +1380,7 @@ x_frame_of_widget (Widget widget)
       f = XFRAME (frame);
       if (FRAME_X_P (f)
          && f->output_data.nothing != 1
-         && FRAME_X_DISPLAY_INFO (f) == dpyinfo
+         && FRAME_DISPLAY_INFO (f) == dpyinfo
          && f->output_data.x->widget == widget)
        return f;
     }
@@ -1640,7 +1589,7 @@ x_color_cells (Display *dpy, int *ncells)
 void
 x_query_colors (struct frame *f, XColor *colors, int ncolors)
 {
-  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 
   if (dpyinfo->color_cells)
     {
@@ -1880,7 +1829,7 @@ x_setup_relief_color (struct frame *f, struct relief *relief, double factor, int
   unsigned long pixel;
   unsigned long background = di->relief_background;
   Colormap cmap = FRAME_X_COLORMAP (f);
-  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
   Display *dpy = FRAME_X_DISPLAY (f);
 
   xgcv.graphics_exposures = False;
@@ -2975,10 +2924,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);
 }
 
 
@@ -2990,11 +2939,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));
@@ -3119,22 +3064,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);
@@ -3185,9 +3130,9 @@ XTtoggle_invisible_pointer (struct frame *f, int invisible)
   block_input ();
   if (invisible)
     {
-      if (FRAME_X_DISPLAY_INFO (f)->invisible_cursor != 0)
+      if (FRAME_DISPLAY_INFO (f)->invisible_cursor != 0)
         XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                       FRAME_X_DISPLAY_INFO (f)->invisible_cursor);
+                       FRAME_DISPLAY_INFO (f)->invisible_cursor);
     }
   else
     XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
@@ -3220,20 +3165,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
  ***********************************************************************/
@@ -3259,7 +3190,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
@@ -3456,6 +3387,181 @@ x_focus_changed (int type, int state, struct x_display_info *dpyinfo, struct fra
     }
 }
 
+/* Return the Emacs frame-object corresponding to an X window.
+   It could be the frame's main window or an icon window.  */
+
+static struct frame *
+x_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
+{
+  Lisp_Object tail, frame;
+  struct frame *f;
+
+  if (wdesc == None)
+    return NULL;
+
+  FOR_EACH_FRAME (tail, frame)
+    {
+      f = XFRAME (frame);
+      if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
+       continue;
+      if (f->output_data.x->hourglass_window == wdesc)
+       return f;
+#ifdef USE_X_TOOLKIT
+      if ((f->output_data.x->edit_widget
+          && XtWindow (f->output_data.x->edit_widget) == wdesc)
+         /* A tooltip frame?  */
+         || (!f->output_data.x->edit_widget
+             && FRAME_X_WINDOW (f) == wdesc)
+          || f->output_data.x->icon_desc == wdesc)
+        return f;
+#else /* not USE_X_TOOLKIT */
+#ifdef USE_GTK
+      if (f->output_data.x->edit_widget)
+      {
+        GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
+        struct x_output *x = f->output_data.x;
+        if (gwdesc != 0 && gwdesc == x->edit_widget)
+          return f;
+      }
+#endif /* USE_GTK */
+      if (FRAME_X_WINDOW (f) == wdesc
+          || f->output_data.x->icon_desc == wdesc)
+        return f;
+#endif /* not USE_X_TOOLKIT */
+    }
+  return 0;
+}
+
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
+
+/* Like x_window_to_frame but also compares the window with the widget's
+   windows.  */
+
+static struct frame *
+x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
+{
+  Lisp_Object tail, frame;
+  struct frame *f, *found = NULL;
+  struct x_output *x;
+
+  if (wdesc == None)
+    return NULL;
+
+  FOR_EACH_FRAME (tail, frame)
+    {
+      if (found)
+        break;
+      f = XFRAME (frame);
+      if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo)
+       {
+         /* This frame matches if the window is any of its widgets.  */
+         x = f->output_data.x;
+         if (x->hourglass_window == wdesc)
+           found = f;
+         else if (x->widget)
+           {
+#ifdef USE_GTK
+              GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
+              if (gwdesc != 0
+                  && gtk_widget_get_toplevel (gwdesc) == x->widget)
+                found = f;
+#else
+             if (wdesc == XtWindow (x->widget)
+                 || wdesc == XtWindow (x->column_widget)
+                 || wdesc == XtWindow (x->edit_widget))
+               found = f;
+             /* Match if the window is this frame's menubar.  */
+             else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
+               found = f;
+#endif
+           }
+         else if (FRAME_X_WINDOW (f) == wdesc)
+           /* A tooltip frame.  */
+           found = f;
+       }
+    }
+
+  return found;
+}
+
+/* Likewise, but consider only the menu bar widget.  */
+
+static struct frame *
+x_menubar_window_to_frame (struct x_display_info *dpyinfo, XEvent *event)
+{
+  Window wdesc = event->xany.window;
+  Lisp_Object tail, frame;
+  struct frame *f;
+  struct x_output *x;
+
+  if (wdesc == None)
+    return NULL;
+
+  FOR_EACH_FRAME (tail, frame)
+    {
+      f = XFRAME (frame);
+      if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
+       continue;
+      x = f->output_data.x;
+#ifdef USE_GTK
+      if (x->menubar_widget && xg_event_is_for_menubar (f, event))
+        return f;
+#else
+      /* Match if the window is this frame's menubar.  */
+      if (x->menubar_widget
+         && lw_window_is_in_menubar (wdesc, x->menubar_widget))
+       return f;
+#endif
+    }
+  return 0;
+}
+
+/* Return the frame whose principal (outermost) window is WDESC.
+   If WDESC is some other (smaller) window, we return 0.  */
+
+struct frame *
+x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
+{
+  Lisp_Object tail, frame;
+  struct frame *f;
+  struct x_output *x;
+
+  if (wdesc == None)
+    return NULL;
+
+  FOR_EACH_FRAME (tail, frame)
+    {
+      f = XFRAME (frame);
+      if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
+       continue;
+      x = f->output_data.x;
+
+      if (x->widget)
+       {
+         /* This frame matches if the window is its topmost widget.  */
+#ifdef USE_GTK
+          GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
+          if (gwdesc == x->widget)
+            return f;
+#else
+         if (wdesc == XtWindow (x->widget))
+           return f;
+#endif
+       }
+      else if (FRAME_X_WINDOW (f) == wdesc)
+       /* Tooltip frame.  */
+       return f;
+    }
+  return 0;
+}
+
+#else /* !USE_X_TOOLKIT && !USE_GTK */
+
+#define x_any_window_to_frame(d, i) x_window_to_frame (d, i)
+#define x_top_window_to_frame(d, i) x_window_to_frame (d, i)
+
+#endif /* USE_X_TOOLKIT || USE_GTK */
+
 /* The focus may have changed.  Figure out if it is a real focus change,
    by checking both FocusIn/Out and Enter/LeaveNotify events.
 
@@ -3529,7 +3635,7 @@ x_mouse_leave (struct x_display_info *dpyinfo)
 static void
 XTframe_rehighlight (struct frame *frame)
 {
-  x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame));
+  x_frame_rehighlight (FRAME_DISPLAY_INFO (frame));
 }
 
 static void
@@ -3762,7 +3868,7 @@ construct_mouse_click (struct input_event *result, XButtonEvent *event, struct f
   result->kind = MOUSE_CLICK_EVENT;
   result->code = event->button - Button1;
   result->timestamp = event->time;
-  result->modifiers = (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
+  result->modifiers = (x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO (f),
                                               event->state)
                       | (event->type == ButtonRelease
                          ? up_modifier
@@ -3775,7 +3881,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.
 
@@ -3928,7 +4033,7 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
 
        x_catch_errors (FRAME_X_DISPLAY (*fp));
 
-       if (FRAME_X_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame
+       if (FRAME_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame
            && FRAME_LIVE_P (last_mouse_frame))
          {
            /* If mouse was grabbed on a frame, give coords for that frame
@@ -3967,7 +4072,7 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
                   want the edit window.  For non-Gtk+ the innermost
                   window is the edit window.  For Gtk+ it might not
                   be.  It might be the tool bar for example.  */
-               if (x_window_to_frame (FRAME_X_DISPLAY_INFO (*fp), win))
+               if (x_window_to_frame (FRAME_DISPLAY_INFO (*fp), win))
                  break;
 #endif
                win = child;
@@ -3989,10 +4094,10 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
 #ifdef USE_GTK
            /* We don't wan't to know the innermost window.  We
               want the edit window.  */
-           f1 = x_window_to_frame (FRAME_X_DISPLAY_INFO (*fp), win);
+           f1 = x_window_to_frame (FRAME_DISPLAY_INFO (*fp), win);
 #else
            /* Is win one of our frames?  */
-           f1 = x_any_window_to_frame (FRAME_X_DISPLAY_INFO (*fp), win);
+           f1 = x_any_window_to_frame (FRAME_DISPLAY_INFO (*fp), win);
 #endif
 
 #ifdef USE_X_TOOLKIT
@@ -4145,10 +4250,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.  */
 
@@ -4190,20 +4291,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;
     }
@@ -4235,7 +4339,7 @@ x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole)
 
   /* Construct a ClientMessage event to send to the frame.  */
   ev->type = ClientMessage;
-  ev->message_type = FRAME_X_DISPLAY_INFO (f)->Xatom_Scrollbar;
+  ev->message_type = FRAME_DISPLAY_INFO (f)->Xatom_Scrollbar;
   ev->display = FRAME_X_DISPLAY (f);
   ev->window = FRAME_X_WINDOW (f);
   ev->format = 32;
@@ -4328,39 +4432,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;
 
@@ -4376,7 +4480,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;
 
@@ -4387,7 +4491,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);
     }
 }
@@ -4403,12 +4506,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));
-  struct frame *f = (struct frame *) 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);
@@ -4418,53 +4520,52 @@ xg_scroll_callback (GtkRange     *range,
     {
     case GTK_SCROLL_JUMP:
       /* Buttons 1 2 or 3 must be grabbed.  */
-      if (FRAME_X_DISPLAY_INFO (f)->grabbed != 0
-          && FRAME_X_DISPLAY_INFO (f)->grabbed < (1 << 4))
+      if (FRAME_DISPLAY_INFO (f)->grabbed != 0
+          && FRAME_DISPLAY_INFO (f)->grabbed < (1 << 4))
         {
           part = scroll_bar_handle;
           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,
@@ -4486,11 +4587,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 ();
@@ -4511,8 +4613,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);
 }
 
@@ -4528,11 +4630,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 ();
@@ -4550,8 +4652,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);
 }
 
@@ -4826,7 +4928,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;
 
@@ -4861,19 +4963,28 @@ 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;
+#if ! defined (HAVE_XAW3D)
+    /* With Xaw, 'top' values too closer to 1.0 may
+       cause the thumb to disappear.  Fix that.  */
+    top = min (top, 0.99f);
+#endif
     /* Keep two pixels available for moving the thumb down.  */
     shown = max (0, min (1 - top - (2.0f / height), shown));
+#if ! defined (HAVE_XAW3D)
+    /* Likewise with too small 'shown'.  */
+    shown = max (shown, 0.01f);
+#endif
 
-    /* If the call to XawScrollbarSetThumb below doesn't seem to work,
-       check that your system's configuration file contains a define
-       for `NARROWPROTO'.  See s/freebsd.h for an example.  */
+    /* If the call to XawScrollbarSetThumb below doesn't seem to
+       work, check that 'NARROWPROTO' is defined in src/config.h.
+       If this is not so, most likely you need to fix configure.  */
     if (top != old_top || shown != old_shown)
       {
-       if (NILP (bar->dragging))
+       if (bar->dragging == -1)
          XawScrollbarSetThumb (widget, top, shown);
        else
          {
@@ -4929,7 +5040,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
     a.event_mask = (ButtonPressMask | ButtonReleaseMask
                    | ButtonMotionMask | PointerMotionHintMask
                    | ExposureMask);
-    a.cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
+    a.cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
 
     mask = (CWBackPixel | CWEventMask | CWCursor);
 
@@ -4938,8 +5049,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.  */
@@ -4965,8 +5075,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);
@@ -5023,7 +5136,7 @@ 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;
   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
   GC gc = f->output_data.x->normal_gc;
@@ -5075,11 +5188,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)
@@ -5102,12 +5213,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 ();
@@ -5155,11 +5263,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;
@@ -5188,16 +5296,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?  */
@@ -5209,11 +5308,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 ();
        }
 
@@ -5248,10 +5347,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,
@@ -5275,12 +5374,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
@@ -5294,11 +5391,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);
          }
       }
 
@@ -5333,7 +5429,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);
 
@@ -5517,7 +5613,7 @@ x_scroll_bar_handle_click (struct scroll_bar *bar, XEvent *event, struct input_e
   emacs_event->kind = SCROLL_BAR_CLICK_EVENT;
   emacs_event->code = event->xbutton.button - Button1;
   emacs_event->modifiers
-    = (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO
+    = (x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO
                               (XFRAME (WINDOW_FRAME (XWINDOW (bar->window)))),
                               event->xbutton.state)
        | (event->type == ButtonRelease
@@ -5543,14 +5639,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
 
@@ -5567,20 +5662,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)
 {
   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)
        {
@@ -5632,8 +5727,8 @@ x_scroll_bar_report_motion (struct frame **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;
@@ -5643,7 +5738,7 @@ x_scroll_bar_report_motion (struct frame **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;
@@ -5688,18 +5783,7 @@ x_scroll_bar_clear (struct frame *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.  */
@@ -5712,6 +5796,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.  */
 
@@ -5849,6 +5939,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;
@@ -6052,7 +6148,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
       break;
 
     case SelectionNotify:
-      last_user_time = event.xselection.time;
+      dpyinfo->last_user_time = event.xselection.time;
 #ifdef USE_X_TOOLKIT
       if (! x_window_to_frame (dpyinfo, event.xselection.requestor))
         goto OTHER;
@@ -6061,7 +6157,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
       break;
 
     case SelectionClear:       /* Someone has grabbed ownership.  */
-      last_user_time = event.xselectionclear.time;
+      dpyinfo->last_user_time = event.xselectionclear.time;
 #ifdef USE_X_TOOLKIT
       if (! x_window_to_frame (dpyinfo, event.xselectionclear.window))
         goto OTHER;
@@ -6077,7 +6173,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
       break;
 
     case SelectionRequest:     /* Someone wants our selection.  */
-      last_user_time = event.xselectionrequest.time;
+      dpyinfo->last_user_time = event.xselectionrequest.time;
 #ifdef USE_X_TOOLKIT
       if (!x_window_to_frame (dpyinfo, event.xselectionrequest.owner))
         goto OTHER;
@@ -6096,7 +6192,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
       break;
 
     case PropertyNotify:
-      last_user_time = event.xproperty.time;
+      dpyinfo->last_user_time = event.xproperty.time;
       f = x_top_window_to_frame (dpyinfo, event.xproperty.window);
       if (f && event.xproperty.atom == dpyinfo->Xatom_net_wm_state)
         if (x_handle_net_wm_state (f, &event.xproperty)
@@ -6129,8 +6225,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
           f->top_pos = y;
 
           /* Perhaps reparented due to a WM restart.  Reset this.  */
-          FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_UNKNOWN;
-          FRAME_X_DISPLAY_INFO (f)->net_supported_window = 0;
+          FRAME_DISPLAY_INFO (f)->wm_type = X_WMTYPE_UNKNOWN;
+          FRAME_DISPLAY_INFO (f)->net_supported_window = 0;
 
           x_set_frame_alpha (f);
         }
@@ -6142,11 +6238,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))
             {
@@ -6218,7 +6313,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 ();
@@ -6297,7 +6392,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
 
     case KeyPress:
 
-      last_user_time = event.xkey.time;
+      dpyinfo->last_user_time = event.xkey.time;
       ignore_next_mouse_click_timeout = 0;
 
 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
@@ -6308,6 +6403,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)
@@ -6317,6 +6413,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)
@@ -6363,7 +6460,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
 #endif
 
           event.xkey.state
-            |= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f),
+            |= x_emacs_to_x_modifiers (FRAME_DISPLAY_INFO (f),
                                        extra_keyboard_modifiers);
           modifiers = event.xkey.state;
 
@@ -6437,7 +6534,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
          /* Common for all keysym input events.  */
          XSETFRAME (inev.ie.frame_or_window, f);
          inev.ie.modifiers
-           = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), modifiers);
+           = x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), modifiers);
          inev.ie.timestamp = event.xkey.time;
 
          /* First deal with keysyms which have defined
@@ -6626,7 +6723,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
 #endif
 
     case KeyRelease:
-      last_user_time = event.xkey.time;
+      dpyinfo->last_user_time = event.xkey.time;
 #ifdef HAVE_X_I18N
       /* Don't dispatch this event since XtDispatchEvent calls
          XFilterEvent, and two calls in a row may freeze the
@@ -6637,7 +6734,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
 #endif
 
     case EnterNotify:
-      last_user_time = event.xcrossing.time;
+      dpyinfo->last_user_time = event.xcrossing.time;
       x_detect_focus_change (dpyinfo, &event, &inev.ie);
 
       f = x_any_window_to_frame (dpyinfo, event.xcrossing.window);
@@ -6662,7 +6759,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
       goto OTHER;
 
     case LeaveNotify:
-      last_user_time = event.xcrossing.time;
+      dpyinfo->last_user_time = event.xcrossing.time;
       x_detect_focus_change (dpyinfo, &event, &inev.ie);
 
       f = x_top_window_to_frame (dpyinfo, event.xcrossing.window);
@@ -6696,7 +6793,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
 
     case MotionNotify:
       {
-        last_user_time = event.xmotion.time;
+        dpyinfo->last_user_time = event.xmotion.time;
         previous_help_echo_string = help_echo_string;
         help_echo_string = Qnil;
 
@@ -6722,18 +6819,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
@@ -6741,13 +6836,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;
           }
@@ -6759,7 +6854,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
@@ -6841,9 +6936,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
            by the rest of Emacs, we put it here.  */
         bool tool_bar_p = 0;
 
-        memset (&compose_status, 0, sizeof (compose_status));
+       memset (&compose_status, 0, sizeof (compose_status));
        last_mouse_glyph_frame = 0;
-        last_user_time = event.xbutton.time;
+       dpyinfo->last_user_time = event.xbutton.time;
 
         if (dpyinfo->grabbed
             && last_mouse_frame
@@ -6858,6 +6953,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)))
@@ -6870,13 +6966,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)
@@ -7191,7 +7285,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;
@@ -7215,7 +7310,7 @@ static void
 x_draw_hollow_cursor (struct window *w, struct glyph_row *row)
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
-  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
   Display *dpy = FRAME_X_DISPLAY (f);
   int x, y, wd, h;
   XGCValues xgcv;
@@ -7282,7 +7377,7 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row, int width, enum text
     {
       Display *dpy = FRAME_X_DISPLAY (f);
       Window window = FRAME_X_WINDOW (f);
-      GC gc = FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc;
+      GC gc = FRAME_DISPLAY_INFO (f)->scratch_cursor_gc;
       unsigned long mask = GCForeground | GCBackground | GCGraphicsExposures;
       struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
       XGCValues xgcv;
@@ -7303,7 +7398,7 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row, int width, enum text
       else
        {
          gc = XCreateGC (dpy, window, mask, &xgcv);
-         FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc = gc;
+         FRAME_DISPLAY_INFO (f)->scratch_cursor_gc = gc;
        }
 
       x_clip_to_row (w, row, TEXT_AREA, gc);
@@ -7368,8 +7463,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))
@@ -7381,7 +7475,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));
 
@@ -7434,9 +7530,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
@@ -7471,7 +7565,7 @@ x_bitmap_icon (struct frame *f, Lisp_Object file)
   else
     {
       /* Create the GNU bitmap and mask if necessary.  */
-      if (FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id < 0)
+      if (FRAME_DISPLAY_INFO (f)->icon_bitmap_id < 0)
        {
          ptrdiff_t rc = -1;
 
@@ -7485,7 +7579,7 @@ x_bitmap_icon (struct frame *f, Lisp_Object file)
 
          rc = x_create_bitmap_from_xpm_data (f, gnu_xpm_bits);
          if (rc != -1)
-           FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id = rc;
+           FRAME_DISPLAY_INFO (f)->icon_bitmap_id = rc;
 
 #endif
 
@@ -7497,8 +7591,8 @@ x_bitmap_icon (struct frame *f, Lisp_Object file)
              if (rc == -1)
                return 1;
 
-             FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id = rc;
-             x_create_bitmap_mask (f, FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id);
+             FRAME_DISPLAY_INFO (f)->icon_bitmap_id = rc;
+             x_create_bitmap_mask (f, FRAME_DISPLAY_INFO (f)->icon_bitmap_id);
            }
        }
 
@@ -7506,9 +7600,9 @@ x_bitmap_icon (struct frame *f, Lisp_Object file)
         this increments the ref-count one extra time.
         As a result, the GNU bitmap and mask are never freed.
         That way, we don't have to worry about allocating it again.  */
-      x_reference_bitmap (f, FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id);
+      x_reference_bitmap (f, FRAME_DISPLAY_INFO (f)->icon_bitmap_id);
 
-      bitmap_id = FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id;
+      bitmap_id = FRAME_DISPLAY_INFO (f)->icon_bitmap_id;
     }
 
   x_wm_set_icon_pixmap (f, bitmap_id);
@@ -7722,7 +7816,7 @@ x_connection_closed (Display *dpy, const char *error_message)
       if (FRAME_X_P (XFRAME (frame))
          && FRAME_X_P (XFRAME (minibuf_frame))
          && ! EQ (frame, minibuf_frame)
-         && FRAME_X_DISPLAY_INFO (XFRAME (minibuf_frame)) == dpyinfo)
+         && FRAME_DISPLAY_INFO (XFRAME (minibuf_frame)) == dpyinfo)
        delete_frame (frame, Qnoelisp);
     }
 
@@ -7731,7 +7825,7 @@ x_connection_closed (Display *dpy, const char *error_message)
      for another frame that we need to delete.  */
   FOR_EACH_FRAME (tail, frame)
     if (FRAME_X_P (XFRAME (frame))
-       && FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
+       && FRAME_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
       {
        /* Set this to t so that delete_frame won't get confused
           trying to find a replacement.  */
@@ -7954,7 +8048,7 @@ xim_destroy_callback (XIM xim, XPointer client_data, XPointer call_data)
   FOR_EACH_FRAME (tail, frame)
     {
       struct frame *f = XFRAME (frame);
-      if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo)
+      if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo)
        {
          FRAME_XIC (f) = NULL;
           xic_free_xfontset (f);
@@ -8045,7 +8139,7 @@ xim_instantiate_callback (Display *display, XPointer client_data, XPointer call_
          struct frame *f = XFRAME (frame);
 
          if (FRAME_X_P (f)
-              && FRAME_X_DISPLAY_INFO (f) == xim_inst->dpyinfo)
+              && FRAME_DISPLAY_INFO (f) == xim_inst->dpyinfo)
            if (FRAME_XIC (f) == NULL)
              {
                create_frame_xic (f);
@@ -8143,7 +8237,7 @@ x_calc_absolute_position (struct frame *f)
   /* Treat negative positions as relative to the leftmost bottommost
      position that fits on the screen.  */
   if (flags & XNegative)
-    f->left_pos = x_display_pixel_width (FRAME_X_DISPLAY_INFO (f))
+    f->left_pos = x_display_pixel_width (FRAME_DISPLAY_INFO (f))
       - FRAME_PIXEL_WIDTH (f) + f->left_pos;
 
   {
@@ -8166,7 +8260,7 @@ x_calc_absolute_position (struct frame *f)
 #endif
 
     if (flags & YNegative)
-      f->top_pos = x_display_pixel_height (FRAME_X_DISPLAY_INFO (f))
+      f->top_pos = x_display_pixel_height (FRAME_DISPLAY_INFO (f))
        - height + f->top_pos;
   }
 
@@ -8189,9 +8283,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);
@@ -8209,7 +8300,7 @@ x_set_offset (struct frame *f, register int xoff, register int yoff, int change_
   modified_left = f->left_pos;
   modified_top = f->top_pos;
 
-  if (change_gravity != 0 && FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A)
+  if (change_gravity != 0 && FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A)
     {
       /* Some WMs (twm, wmaker at least) has an offset that is smaller
          than the WM decorations.  So we use the calculated offset instead
@@ -8222,7 +8313,7 @@ x_set_offset (struct frame *f, register int xoff, register int yoff, int change_
                modified_left, modified_top);
 
   x_sync_with_move (f, f->left_pos, f->top_pos,
-                    FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN
+                    FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN
                     ? 1 : 0);
 
   /* change_gravity is non-zero when this function is called from Lisp to
@@ -8236,8 +8327,8 @@ x_set_offset (struct frame *f, register int xoff, register int yoff, int change_
      need to compute the top/left offset adjustment for this frame.  */
 
   if (change_gravity != 0 &&
-      (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN
-       || (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A
+      (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN
+       || (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A
            && (FRAME_X_OUTPUT (f)->move_offset_left == 0
                && FRAME_X_OUTPUT (f)->move_offset_top == 0))))
     x_check_expected_move (f, modified_left, modified_top);
@@ -8258,7 +8349,7 @@ wm_supports (struct frame *f, Atom want_atom)
   unsigned long actual_size, bytes_remaining;
   int i, rc, actual_format;
   Window wmcheck_window;
-  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
   Window target_window = dpyinfo->root_window;
   long max_len = 65536;
   Display *dpy = FRAME_X_DISPLAY (f);
@@ -8339,7 +8430,7 @@ wm_supports (struct frame *f, Atom want_atom)
 static void
 set_wm_state (Lisp_Object frame, int add, Atom atom, Atom value)
 {
-  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (frame));
+  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (XFRAME (frame));
 
   x_send_client_event (frame, make_number (0), frame,
                        dpyinfo->Xatom_net_wm_state,
@@ -8358,7 +8449,7 @@ void
 x_set_sticky (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
 {
   Lisp_Object frame;
-  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 
   XSETFRAME (frame, f);
 
@@ -8381,7 +8472,7 @@ get_current_wm_state (struct frame *f,
   Atom actual_type;
   unsigned long actual_size, bytes_remaining;
   int i, rc, actual_format, is_hidden = 0;
-  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
   long max_len = 65536;
   Display *dpy = FRAME_X_DISPLAY (f);
   unsigned char *tmp_data = NULL;
@@ -8445,7 +8536,7 @@ get_current_wm_state (struct frame *f,
 static int
 do_ewmh_fullscreen (struct frame *f)
 {
-  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
   int have_net_atom = wm_supports (f, dpyinfo->Xatom_net_wm_state);
   int cur, dummy;
 
@@ -8563,7 +8654,7 @@ x_check_fullscreen (struct frame *f)
   if (do_ewmh_fullscreen (f))
     return;
 
-  if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
+  if (f->output_data.x->parent_desc != FRAME_DISPLAY_INFO (f)->root_window)
     return; /* Only fullscreen without WM or with EWM hints (above). */
 
   /* Setting fullscreen to nil doesn't do anything.  We could save the
@@ -8573,7 +8664,7 @@ x_check_fullscreen (struct frame *f)
   if (f->want_fullscreen != FULLSCREEN_NONE)
     {
       int width = FRAME_PIXEL_WIDTH (f), height = FRAME_PIXEL_HEIGHT (f);
-      struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+      struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 
       switch (f->want_fullscreen)
         {
@@ -8620,7 +8711,7 @@ x_check_expected_move (struct frame *f, int expected_left, int expected_top)
       int adjusted_left;
       int adjusted_top;
 
-        FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_A;
+        FRAME_DISPLAY_INFO (f)->wm_type = X_WMTYPE_A;
       FRAME_X_OUTPUT (f)->move_offset_left = expected_left - current_left;
       FRAME_X_OUTPUT (f)->move_offset_top = expected_top - current_top;
 
@@ -8638,7 +8729,7 @@ x_check_expected_move (struct frame *f, int expected_left, int expected_top)
     /* It's a "Type B" window manager.  We don't have to adjust the
        frame's position. */
 
-      FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_B;
+      FRAME_DISPLAY_INFO (f)->wm_type = X_WMTYPE_B;
 }
 
 
@@ -8690,8 +8781,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;
@@ -8699,8 +8790,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)
     {
@@ -8713,11 +8804,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 */
     }
@@ -8930,15 +9021,16 @@ x_ewmh_activate_frame (struct frame *f)
   /* See Window Manager Specification/Extended Window Manager Hints at
      http://freedesktop.org/wiki/Specifications/wm-spec  */
 
-  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 
   if (FRAME_VISIBLE_P (f) && wm_supports (f, dpyinfo->Xatom_net_active_window))
     {
       Lisp_Object frame;
       XSETFRAME (frame, f);
       x_send_client_event (frame, make_number (0), frame,
-                           dpyinfo->Xatom_net_active_window,
-                           make_number (32), list2i (1, last_user_time));
+                          dpyinfo->Xatom_net_active_window,
+                          make_number (32),
+                          list2i (1, dpyinfo->last_user_time));
     }
 }
 
@@ -8963,7 +9055,7 @@ static void
 xembed_set_info (struct frame *f, enum xembed_info flags)
 {
   unsigned long data[2];
-  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 
   data[0] = XEMBED_VERSION;
   data[1] = flags;
@@ -8982,7 +9074,7 @@ xembed_send_message (struct frame *f, Time t, enum xembed_message msg,
 
   event.xclient.type = ClientMessage;
   event.xclient.window = FRAME_X_OUTPUT (f)->parent_desc;
-  event.xclient.message_type = FRAME_X_DISPLAY_INFO (f)->Xatom_XEMBED;
+  event.xclient.message_type = FRAME_DISPLAY_INFO (f)->Xatom_XEMBED;
   event.xclient.format = 32;
   event.xclient.data.l[0] = t;
   event.xclient.data.l[1] = msg;
@@ -9172,8 +9264,8 @@ x_make_frame_invisible (struct frame *f)
   window = FRAME_OUTER_WINDOW (f);
 
   /* Don't keep the highlight on an invisible frame.  */
-  if (FRAME_X_DISPLAY_INFO (f)->x_highlight_frame == f)
-    FRAME_X_DISPLAY_INFO (f)->x_highlight_frame = 0;
+  if (FRAME_DISPLAY_INFO (f)->x_highlight_frame == f)
+    FRAME_DISPLAY_INFO (f)->x_highlight_frame = 0;
 
   block_input ();
 
@@ -9227,8 +9319,8 @@ x_iconify_frame (struct frame *f)
   Lisp_Object type;
 
   /* Don't keep the highlight on an invisible frame.  */
-  if (FRAME_X_DISPLAY_INFO (f)->x_highlight_frame == f)
-    FRAME_X_DISPLAY_INFO (f)->x_highlight_frame = 0;
+  if (FRAME_DISPLAY_INFO (f)->x_highlight_frame == f)
+    FRAME_DISPLAY_INFO (f)->x_highlight_frame = 0;
 
   if (FRAME_ICONIFIED_P (f))
     return;
@@ -9303,7 +9395,7 @@ x_iconify_frame (struct frame *f)
 
     msg.xclient.window = FRAME_X_WINDOW (f);
     msg.xclient.type = ClientMessage;
-    msg.xclient.message_type = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_change_state;
+    msg.xclient.message_type = FRAME_DISPLAY_INFO (f)->Xatom_wm_change_state;
     msg.xclient.format = 32;
     msg.xclient.data.l[0] = IconicState;
 
@@ -9342,7 +9434,7 @@ x_iconify_frame (struct frame *f)
 void
 x_free_frame_resources (struct frame *f)
 {
-  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
   Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
 #ifdef USE_X_TOOLKIT
   Lisp_Object bar;
@@ -9453,16 +9545,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 ();
 }
@@ -9473,7 +9557,7 @@ x_free_frame_resources (struct frame *f)
 static void
 x_destroy_window (struct frame *f)
 {
-  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 
   /* If a display connection is dead, don't try sending more
      commands to the X server.  */
@@ -9519,9 +9603,9 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
 
   size_hints.width_inc = FRAME_COLUMN_WIDTH (f);
   size_hints.height_inc = FRAME_LINE_HEIGHT (f);
-  size_hints.max_width = x_display_pixel_width (FRAME_X_DISPLAY_INFO (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_X_DISPLAY_INFO (f))
+  size_hints.max_height = x_display_pixel_height (FRAME_DISPLAY_INFO (f))
     - FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
 
   /* Calculate the base and minimum sizes.  */
@@ -9834,7 +9918,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 ();
@@ -9975,8 +10058,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);
 
   {
@@ -10047,9 +10128,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);
@@ -10091,33 +10170,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,
@@ -10278,16 +10336,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,
@@ -10299,6 +10349,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);
@@ -10399,8 +10451,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)
@@ -10478,7 +10528,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;
     }
@@ -10501,13 +10551,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,
@@ -10529,6 +10573,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.  */
@@ -10547,6 +10592,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);
 
@@ -10587,6 +10634,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);
@@ -10614,11 +10665,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;
@@ -10812,5 +10863,3 @@ default is nil, which is the same as `super'.  */);
                                     make_float (DEFAULT_REHASH_THRESHOLD),
                                     Qnil);
 }
-
-#endif /* HAVE_X_WINDOWS */