]> code.delx.au - gnu-emacs/blobdiff - src/xterm.c
* dispextern.h, image.c (x_bitmap_height, x_bitmap_width): Now static.
[gnu-emacs] / src / xterm.c
index 89f543abca641bfbb4f54c31545cd99bf53742f2..26ad526762558c57058a63f0c719c9ea269a80a7 100644 (file)
@@ -84,7 +84,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #endif
 #endif
 
-#ifdef USE_LUCID
+#if defined (USE_LUCID) || defined (USE_MOTIF)
 #include "../lwlib/xlwmenu.h"
 #endif
 
@@ -148,17 +148,6 @@ static bool any_help_event_p;
 
 struct x_display_info *x_display_list;
 
-/* This is a list of cons cells, each of the form (NAME
-   . FONT-LIST-CACHE), one for each element of x_display_list and in
-   the same order.  NAME is the name of the frame.  FONT-LIST-CACHE
-   records previous values returned by x-list-fonts.  */
-
-Lisp_Object x_display_name_list;
-
-/* This is a frame waiting to be auto-raised, within XTread_socket.  */
-
-static struct frame *pending_autoraise_frame;
-
 #ifdef USE_X_TOOLKIT
 
 /* The application context for Xt use.  */
@@ -176,52 +165,6 @@ static bool toolkit_scroll_bar_interaction;
 
 static Time ignore_next_mouse_click_timeout;
 
-/* Mouse movement.
-
-   Formerly, we used PointerMotionHintMask (in standard_event_mask)
-   so that we would have to call XQueryPointer after each MotionNotify
-   event to ask for another such event.  However, this made mouse tracking
-   slow, and there was a bug that made it eventually stop.
-
-   Simply asking for MotionNotify all the time seems to work better.
-
-   In order to avoid asking for motion events and then throwing most
-   of them away or busy-polling the server for mouse positions, we ask
-   the server for pointer motion hints.  This means that we get only
-   one event per group of mouse movements.  "Groups" are delimited by
-   other kinds of events (focus changes and button clicks, for
-   example), or by XQueryPointer calls; when one of these happens, we
-   get another MotionNotify event the next time the mouse moves.  This
-   is at least as efficient as getting motion events when mouse
-   tracking is on, and I suspect only negligibly worse when tracking
-   is off.  */
-
-/* Where the mouse was last time we reported a mouse event.  */
-
-static XRectangle last_mouse_glyph;
-static struct frame *last_mouse_glyph_frame;
-
-/* The scroll bar in which the last X motion event occurred.
-
-   If the last X motion event occurred in a scroll bar, we set this so
-   XTmouse_position can know whether to report a scroll bar motion or
-   an ordinary motion.
-
-   If the last X motion event didn't occur in a scroll bar, we set
-   this to Qnil, to tell XTmouse_position to return an ordinary motion
-   event.  */
-
-static Lisp_Object last_mouse_scroll_bar;
-
-/* This is a hack.  We would really prefer that XTmouse_position would
-   return the time associated with the position it returns, but there
-   doesn't seem to be any way to wrest the time-stamp from the server
-   along with the position query.  So, we just keep track of the time
-   of the last movement we received, and return that in hopes that
-   it's somewhat accurate.  */
-
-static Time last_mouse_movement_time;
-
 /* Incremented by XTread_socket whenever it really tries to read
    events.  */
 
@@ -303,12 +246,12 @@ static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *,
                                         enum scroll_bar_part *,
                                         Lisp_Object *, Lisp_Object *,
                                         Time *);
-static int x_handle_net_wm_state (struct frame *, const XPropertyEvent * const);
+static int x_handle_net_wm_state (struct frame *, const XPropertyEvent *);
 static void x_check_fullscreen (struct frame *);
 static void x_check_expected_move (struct frame *, int, int);
 static void x_sync_with_move (struct frame *, int, int, int);
 static int handle_one_xevent (struct x_display_info *,
-                             const XEvent * const, int *,
+                             const XEvent *, int *,
                              struct input_event *);
 #ifdef USE_GTK
 static int x_dispatch_event (XEvent *, Display *);
@@ -3299,9 +3242,9 @@ x_new_focus_frame (struct x_display_info *dpyinfo, struct frame *frame)
        x_lower_frame (old_focus);
 
       if (dpyinfo->x_focus_frame && dpyinfo->x_focus_frame->auto_raise)
-       pending_autoraise_frame = dpyinfo->x_focus_frame;
+       dpyinfo->x_pending_autoraise_frame = dpyinfo->x_focus_frame;
       else
-       pending_autoraise_frame = 0;
+       dpyinfo->x_pending_autoraise_frame = NULL;
     }
 
   x_frame_rehighlight (dpyinfo);
@@ -3462,7 +3405,7 @@ x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
 
 static struct frame *
 x_menubar_window_to_frame (struct x_display_info *dpyinfo,
-                          const XEvent * const event)
+                          const XEvent *event)
 {
   Window wdesc = event->xany.window;
   Lisp_Object tail, frame;
@@ -3544,7 +3487,7 @@ x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
 
 static void
 x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame,
-                      const XEvent * const event, struct input_event *bufp)
+                      const XEvent *event, struct input_event *bufp)
 {
   if (!frame)
     return;
@@ -3824,9 +3767,25 @@ x_get_keysym_name (int keysym)
   return value;
 }
 
+/* Mouse clicks and mouse movement.  Rah.
 
-\f
-/* Mouse clicks and mouse movement.  Rah.  */
+   Formerly, we used PointerMotionHintMask (in standard_event_mask)
+   so that we would have to call XQueryPointer after each MotionNotify
+   event to ask for another such event.  However, this made mouse tracking
+   slow, and there was a bug that made it eventually stop.
+
+   Simply asking for MotionNotify all the time seems to work better.
+
+   In order to avoid asking for motion events and then throwing most
+   of them away or busy-polling the server for mouse positions, we ask
+   the server for pointer motion hints.  This means that we get only
+   one event per group of mouse movements.  "Groups" are delimited by
+   other kinds of events (focus changes and button clicks, for
+   example), or by XQueryPointer calls; when one of these happens, we
+   get another MotionNotify event the next time the mouse moves.  This
+   is at least as efficient as getting motion events when mouse
+   tracking is on, and I suspect only negligibly worse when tracking
+   is off.  */
 
 /* Prepare a mouse-event in *RESULT for placement in the input queue.
 
@@ -3835,7 +3794,7 @@ x_get_keysym_name (int keysym)
 
 static Lisp_Object
 construct_mouse_click (struct input_event *result,
-                      const XButtonEvent * const event,
+                      const XButtonEvent *event,
                       struct frame *f)
 {
   /* Make the event type NO_EVENT; we'll change that when we decide
@@ -3864,65 +3823,49 @@ construct_mouse_click (struct input_event *result,
    the mainstream emacs code by setting mouse_moved.  If not, ask for
    another motion event, so we can check again the next time it moves.  */
 
-static XMotionEvent last_mouse_motion_event;
-static Lisp_Object last_mouse_motion_frame;
-
 static int
-note_mouse_movement (struct frame *frame, const XMotionEvent * const event)
+note_mouse_movement (struct frame *frame, const XMotionEvent *event)
 {
-  last_mouse_movement_time = event->time;
-  last_mouse_motion_event = *event;
-  XSETFRAME (last_mouse_motion_frame, frame);
+  XRectangle *r;
+  struct x_display_info *dpyinfo;
 
   if (!FRAME_X_OUTPUT (frame))
     return 0;
 
+  dpyinfo = FRAME_DISPLAY_INFO (frame);
+  dpyinfo->last_mouse_movement_time = event->time;
+  dpyinfo->last_mouse_motion_frame = frame;
+  dpyinfo->last_mouse_motion_x = event->x;
+  dpyinfo->last_mouse_motion_y = event->y;
+
   if (event->window != FRAME_X_WINDOW (frame))
     {
       frame->mouse_moved = 1;
-      last_mouse_scroll_bar = Qnil;
+      dpyinfo->last_mouse_scroll_bar = NULL;
       note_mouse_highlight (frame, -1, -1);
-      last_mouse_glyph_frame = 0;
+      dpyinfo->last_mouse_glyph_frame = NULL;
       return 1;
     }
 
 
   /* Has the mouse moved off the glyph it was on at the last sighting?  */
-  if (frame != last_mouse_glyph_frame
-      || event->x < last_mouse_glyph.x
-      || event->x >= last_mouse_glyph.x + last_mouse_glyph.width
-      || event->y < last_mouse_glyph.y
-      || event->y >= last_mouse_glyph.y + last_mouse_glyph.height)
+  r = &dpyinfo->last_mouse_glyph;
+  if (frame != dpyinfo->last_mouse_glyph_frame
+      || event->x < r->x || event->x >= r->x + r->width
+      || event->y < r->y || event->y >= r->y + r->height)
     {
       frame->mouse_moved = 1;
-      last_mouse_scroll_bar = Qnil;
+      dpyinfo->last_mouse_scroll_bar = NULL;
       note_mouse_highlight (frame, event->x, event->y);
       /* Remember which glyph we're now on.  */
-      remember_mouse_glyph (frame, event->x, event->y, &last_mouse_glyph);
-      last_mouse_glyph_frame = frame;
+      remember_mouse_glyph (frame, event->x, event->y, r);
+      dpyinfo->last_mouse_glyph_frame = frame;
       return 1;
     }
 
   return 0;
 }
 
-\f
-/************************************************************************
-                             Mouse Face
- ************************************************************************/
-
-static void
-redo_mouse_highlight (void)
-{
-  if (!NILP (last_mouse_motion_frame)
-      && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame)))
-    note_mouse_highlight (XFRAME (last_mouse_motion_frame),
-                         last_mouse_motion_event.x,
-                         last_mouse_motion_event.y);
-}
-
-
-
 /* Return the current position of the mouse.
    *FP should be a frame which indicates which display to ask about.
 
@@ -3949,10 +3892,11 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
                  Time *timestamp)
 {
   struct frame *f1;
+  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
 
   block_input ();
 
-  if (! NILP (last_mouse_scroll_bar) && insist == 0)
+  if (dpyinfo->last_mouse_scroll_bar && insist == 0)
     x_scroll_bar_report_motion (fp, bar_window, part, x, y, timestamp);
   else
     {
@@ -3970,7 +3914,7 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
             && FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp))
          XFRAME (frame)->mouse_moved = 0;
 
-      last_mouse_scroll_bar = Qnil;
+      dpyinfo->last_mouse_scroll_bar = NULL;
 
       /* Figure out which root window we're on.  */
       XQueryPointer (FRAME_X_DISPLAY (*fp),
@@ -4008,22 +3952,24 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
 
        x_catch_errors (FRAME_X_DISPLAY (*fp));
 
-       if (FRAME_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame
-           && FRAME_LIVE_P (last_mouse_frame))
+       if (x_mouse_grabbed (dpyinfo))
          {
            /* If mouse was grabbed on a frame, give coords for that frame
               even if the mouse is now outside it.  */
            XTranslateCoordinates (FRAME_X_DISPLAY (*fp),
 
-                                  /* From-window, to-window.  */
-                                  root, FRAME_X_WINDOW (last_mouse_frame),
+                                  /* From-window.  */
+                                  root,
+
+                                  /* To-window.  */
+                                  FRAME_X_WINDOW (dpyinfo->last_mouse_frame),
 
                                   /* From-position, to-position.  */
                                   root_x, root_y, &win_x, &win_y,
 
                                   /* Child of win.  */
                                   &child);
-           f1 = last_mouse_frame;
+           f1 = dpyinfo->last_mouse_frame;
          }
        else
          {
@@ -4047,7 +3993,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_DISPLAY_INFO (*fp), win))
+               if (x_window_to_frame (dpyinfo, win))
                  break;
 #endif
                win = child;
@@ -4069,10 +4015,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_DISPLAY_INFO (*fp), win);
+           f1 = x_window_to_frame (dpyinfo, win);
 #else
            /* Is win one of our frames?  */
-           f1 = x_any_window_to_frame (FRAME_DISPLAY_INFO (*fp), win);
+           f1 = x_any_window_to_frame (dpyinfo, win);
 #endif
 
 #ifdef USE_X_TOOLKIT
@@ -4118,15 +4064,17 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
               on it, i.e. into the same rectangles that matrices on
               the frame are divided into.  */
 
-           remember_mouse_glyph (f1, win_x, win_y, &last_mouse_glyph);
-           last_mouse_glyph_frame = f1;
+           /* FIXME: what if F1 is not an X frame?  */
+           dpyinfo = FRAME_DISPLAY_INFO (f1);
+           remember_mouse_glyph (f1, win_x, win_y, &dpyinfo->last_mouse_glyph);
+           dpyinfo->last_mouse_glyph_frame = f1;
 
            *bar_window = Qnil;
            *part = 0;
            *fp = f1;
            XSETINT (*x, win_x);
            XSETINT (*y, win_y);
-           *timestamp = last_mouse_movement_time;
+           *timestamp = dpyinfo->last_mouse_movement_time;
          }
       }
     }
@@ -4283,13 +4231,6 @@ xt_action_hook (Widget widget, XtPointer client_data, String action_name,
 }
 #endif /* not USE_GTK */
 
-/* A vector of windows used for communication between
-   x_send_scroll_bar_event and x_scroll_bar_to_input_event.  */
-
-static struct window **scroll_bar_windows;
-static ptrdiff_t scroll_bar_windows_size;
-
-
 /* Send a client message with message type Xatom_Scrollbar for a
    scroll action to the frame of WINDOW.  PART is a value identifying
    the part of the scroll bar that was clicked on.  PORTION is the
@@ -4299,10 +4240,13 @@ static void
 x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole)
 {
   XEvent event;
-  XClientMessageEvent *ev = (XClientMessageEvent *) &event;
+  XClientMessageEvent *ev = &event.xclient;
   struct window *w = XWINDOW (window);
   struct frame *f = XFRAME (w->frame);
-  ptrdiff_t i;
+  intptr_t iw = (intptr_t) w;
+  enum { BITS_PER_INTPTR = CHAR_BIT * sizeof iw };
+  verify (BITS_PER_INTPTR <= 64);
+  int sign_shift = BITS_PER_INTPTR - 32;
 
   block_input ();
 
@@ -4313,33 +4257,16 @@ x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole)
   ev->window = FRAME_X_WINDOW (f);
   ev->format = 32;
 
-  /* We can only transfer 32 bits in the XClientMessageEvent, which is
-     not enough to store a pointer or Lisp_Object on a 64 bit system.
-     So, store the window in scroll_bar_windows and pass the index
-     into that array in the event.  */
-  for (i = 0; i < scroll_bar_windows_size; ++i)
-    if (scroll_bar_windows[i] == NULL)
-      break;
-
-  if (i == scroll_bar_windows_size)
-    {
-      ptrdiff_t old_nbytes =
-       scroll_bar_windows_size * sizeof *scroll_bar_windows;
-      ptrdiff_t nbytes;
-      enum { XClientMessageEvent_MAX = 0x7fffffff };
-      scroll_bar_windows =
-       xpalloc (scroll_bar_windows, &scroll_bar_windows_size, 1,
-                XClientMessageEvent_MAX, sizeof *scroll_bar_windows);
-      nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows;
-      memset (&scroll_bar_windows[i], 0, nbytes - old_nbytes);
-    }
-
-  scroll_bar_windows[i] = w;
-  ev->data.l[0] = (long) i;
-  ev->data.l[1] = (long) part;
-  ev->data.l[2] = (long) 0;
-  ev->data.l[3] = (long) portion;
-  ev->data.l[4] = (long) whole;
+  /* A 32-bit X client on a 64-bit X server can pass a window pointer
+     as-is.  A 64-bit client on a 32-bit X server is in trouble
+     because a pointer does not fit and would be truncated while
+     passing through the server.  So use two slots and hope that X12
+     will resolve such issues someday.  */
+  ev->data.l[0] = iw >> 31 >> 1;
+  ev->data.l[1] = sign_shift <= 0 ? iw : iw << sign_shift >> sign_shift;
+  ev->data.l[2] = part;
+  ev->data.l[3] = portion;
+  ev->data.l[4] = whole;
 
   /* Make Xt timeouts work while the scroll bar is active.  */
 #ifdef USE_X_TOOLKIT
@@ -4359,15 +4286,18 @@ x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole)
    in *IEVENT.  */
 
 static void
-x_scroll_bar_to_input_event (const XEvent * const event,
+x_scroll_bar_to_input_event (const XEvent *event,
                             struct input_event *ievent)
 {
-  XClientMessageEvent *ev = (XClientMessageEvent *) event;
+  const XClientMessageEvent *ev = &event->xclient;
   Lisp_Object window;
   struct window *w;
 
-  w = scroll_bar_windows[ev->data.l[0]];
-  scroll_bar_windows[ev->data.l[0]] = NULL;
+  /* See the comment in the function above.  */
+  intptr_t iw0 = ev->data.l[0];
+  intptr_t iw1 = ev->data.l[1];
+  intptr_t iw = (iw0 << 31 << 1) + (iw1 & 0xffffffffu);
+  w = (struct window *) iw;
 
   XSETWINDOW (window, w);
 
@@ -4380,10 +4310,10 @@ x_scroll_bar_to_input_event (const XEvent * const event,
   ievent->timestamp =
     XtLastTimestampProcessed (FRAME_X_DISPLAY (XFRAME (w->frame)));
 #endif
-  ievent->part = ev->data.l[1];
-  ievent->code = ev->data.l[2];
-  ievent->x = make_number ((int) ev->data.l[3]);
-  ievent->y = make_number ((int) ev->data.l[4]);
+  ievent->code = 0;
+  ievent->part = ev->data.l[2];
+  ievent->x = make_number (ev->data.l[3]);
+  ievent->y = make_number (ev->data.l[4]);
   ievent->modifiers = 0;
 }
 
@@ -5504,7 +5434,7 @@ XTjudge_scroll_bars (struct frame *f)
    mark bits.  */
 
 static void
-x_scroll_bar_expose (struct scroll_bar *bar, const XEvent * const event)
+x_scroll_bar_expose (struct scroll_bar *bar, const XEvent *event)
 {
   Window w = bar->x_window;
   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
@@ -5543,7 +5473,7 @@ x_scroll_bar_expose (struct scroll_bar *bar, const XEvent * const event)
 
 static void
 x_scroll_bar_handle_click (struct scroll_bar *bar,
-                          const XEvent * const event,
+                          const XEvent *event,
                           struct input_event *emacs_event)
 {
   if (! WINDOWP (bar->window))
@@ -5602,14 +5532,14 @@ x_scroll_bar_handle_click (struct scroll_bar *bar,
 
 static void
 x_scroll_bar_note_movement (struct scroll_bar *bar,
-                           const XMotionEvent * const event)
+                           const XMotionEvent *event)
 {
   struct frame *f = XFRAME (XWINDOW (bar->window)->frame);
+  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 
-  last_mouse_movement_time = event->time;
-
+  dpyinfo->last_mouse_movement_time = event->time;
+  dpyinfo->last_mouse_scroll_bar = bar;
   f->mouse_moved = 1;
-  XSETVECTOR (last_mouse_scroll_bar, bar);
 
   /* If we're dragging the bar, display it.  */
   if (bar->dragging != -1)
@@ -5636,7 +5566,8 @@ 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);
+  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
+  struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
   Window w = bar->x_window;
   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
   int win_x, win_y;
@@ -5648,22 +5579,19 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
 
   /* Get the mouse's position relative to the scroll bar window, and
      report that.  */
-  if (XQueryPointer (FRAME_X_DISPLAY (f), w,
+  if (XQueryPointer (FRAME_X_DISPLAY (f), w,
 
-                      /* Root, child, root x and root y.  */
-                      &dummy_window, &dummy_window,
-                      &dummy_coord, &dummy_coord,
+                    /* Root, child, root x and root y.  */
+                    &dummy_window, &dummy_window,
+                    &dummy_coord, &dummy_coord,
 
-                      /* Position relative to scroll bar.  */
-                      &win_x, &win_y,
+                    /* Position relative to scroll bar.  */
+                    &win_x, &win_y,
 
-                      /* Mouse buttons and modifier keys.  */
-                      &dummy_mask))
-    ;
-  else
+                    /* Mouse buttons and modifier keys.  */
+                    &dummy_mask))
     {
-      int top_range
-       = VERTICAL_SCROLL_BAR_TOP_RANGE     (f, bar->height);
+      int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height);
 
       win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER;
 
@@ -5691,11 +5619,10 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
       XSETINT (*y, top_range);
 
       f->mouse_moved = 0;
-      last_mouse_scroll_bar = Qnil;
+      dpyinfo->last_mouse_scroll_bar = NULL;
+      *timestamp = dpyinfo->last_mouse_movement_time;
     }
 
-  *timestamp = last_mouse_movement_time;
-
   unblock_input ();
 }
 
@@ -5853,7 +5780,7 @@ static void xembed_send_message (struct frame *f, Time,
 
 static int
 handle_one_xevent (struct x_display_info *dpyinfo,
-                  const XEvent * const event,
+                  const XEvent *event,
                   int *finish, struct input_event *hold_quit)
 {
   union {
@@ -6078,7 +6005,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
         goto OTHER;
 #endif /* USE_X_TOOLKIT */
       {
-        const XSelectionClearEvent * const eventp = &event->xselectionclear;
+        const XSelectionClearEvent *eventp = &event->xselectionclear;
 
         inev.ie.kind = SELECTION_CLEAR_EVENT;
         SELECTION_EVENT_DISPLAY (&inev.sie) = eventp->display;
@@ -6094,7 +6021,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
         goto OTHER;
 #endif /* USE_X_TOOLKIT */
       {
-       const XSelectionRequestEvent * const eventp = &event->xselectionrequest;
+       const XSelectionRequestEvent *eventp = &event->xselectionrequest;
 
        inev.ie.kind = SELECTION_REQUEST_EVENT;
        SELECTION_EVENT_DISPLAY (&inev.sie) = eventp->display;
@@ -6133,11 +6060,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       f = x_top_window_to_frame (dpyinfo, event->xreparent.window);
       if (f)
         {
-          int x, y;
           f->output_data.x->parent_desc = event->xreparent.parent;
-          x_real_positions (f, &x, &y);
-          f->left_pos = x;
-          f->top_pos = y;
+          x_real_positions (f, &f->left_pos, &f->top_pos);
 
           /* Perhaps reparented due to a WM restart.  Reset this.  */
           FRAME_DISPLAY_INFO (f)->wm_type = X_WMTYPE_UNKNOWN;
@@ -6151,13 +6075,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       f = x_window_to_frame (dpyinfo, event->xexpose.window);
       if (f)
         {
-#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);
-#endif
           if (!FRAME_VISIBLE_P (f))
             {
               SET_FRAME_VISIBLE (f, 1);
@@ -6166,8 +6083,18 @@ handle_one_xevent (struct x_display_info *dpyinfo,
               SET_FRAME_GARBAGED (f);
             }
           else
-           expose_frame (f, event->xexpose.x, event->xexpose.y,
-                         event->xexpose.width, event->xexpose.height);
+           {
+#ifdef USE_GTK
+             /* This seems to be needed for GTK 2.6 and later, see
+                http://debbugs.gnu.org/cgi/bugreport.cgi?bug=15398.  */
+             x_clear_area (event->xexpose.display,
+                           event->xexpose.window,
+                           event->xexpose.x, event->xexpose.y,
+                           event->xexpose.width, event->xexpose.height);
+#endif
+             expose_frame (f, event->xexpose.x, event->xexpose.y,
+                           event->xexpose.width, event->xexpose.height);
+           }
         }
       else
         {
@@ -6227,7 +6154,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       if (event->xunmap.window == tip_window)
         {
           tip_window = 0;
-          redo_mouse_highlight ();
+          x_redo_mouse_highlight (dpyinfo);
         }
 
       f = x_top_window_to_frame (dpyinfo, event->xunmap.window);
@@ -6663,8 +6590,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 #ifdef USE_GTK
       /* We may get an EnterNotify on the buttons in the toolbar.  In that
          case we moved out of any highlighted area and need to note this.  */
-      if (!f && last_mouse_glyph_frame)
-        note_mouse_movement (last_mouse_glyph_frame, &event->xmotion);
+      if (!f && dpyinfo->last_mouse_glyph_frame)
+        note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &event->xmotion);
 #endif
       goto OTHER;
 
@@ -6696,8 +6623,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
         }
 #ifdef USE_GTK
       /* See comment in EnterNotify above */
-      else if (last_mouse_glyph_frame)
-        note_mouse_movement (last_mouse_glyph_frame, &event->xmotion);
+      else if (dpyinfo->last_mouse_glyph_frame)
+        note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &event->xmotion);
 #endif
       goto OTHER;
 
@@ -6711,11 +6638,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
         previous_help_echo_string = help_echo_string;
         help_echo_string = Qnil;
 
-        if (dpyinfo->grabbed && last_mouse_frame
-            && FRAME_LIVE_P (last_mouse_frame))
-          f = last_mouse_frame;
-        else
-          f = x_window_to_frame (dpyinfo, event->xmotion.window);
+       f = (x_mouse_grabbed (dpyinfo) ? dpyinfo->last_mouse_frame
+            : x_window_to_frame (dpyinfo, event->xmotion.window));
 
         if (hlinfo->mouse_face_hidden)
           {
@@ -6831,9 +6755,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
           if (FRAME_GTK_OUTER_WIDGET (f)
               && gtk_widget_get_mapped (FRAME_GTK_OUTER_WIDGET (f)))
 #endif
-            {
-             x_real_positions (f, &f->left_pos, &f->top_pos);
-            }
+           x_real_positions (f, &f->left_pos, &f->top_pos);
 
 #ifdef HAVE_X_I18N
           if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea))
@@ -6851,15 +6773,11 @@ handle_one_xevent (struct x_display_info *dpyinfo,
         bool tool_bar_p = 0;
 
        memset (&compose_status, 0, sizeof (compose_status));
-       last_mouse_glyph_frame = 0;
+       dpyinfo->last_mouse_glyph_frame = NULL;
        dpyinfo->last_user_time = event->xbutton.time;
 
-        if (dpyinfo->grabbed
-            && last_mouse_frame
-            && FRAME_LIVE_P (last_mouse_frame))
-          f = last_mouse_frame;
-        else
-          f = x_window_to_frame (dpyinfo, event->xbutton.window);
+        f = (x_mouse_grabbed (dpyinfo) ? dpyinfo->last_mouse_frame
+            : x_window_to_frame (dpyinfo, event->xbutton.window));
 
 #ifdef USE_GTK
         if (f && xg_event_is_for_scrollbar (f, event))
@@ -6932,7 +6850,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
         if (event->type == ButtonPress)
           {
             dpyinfo->grabbed |= (1 << event->xbutton.button);
-            last_mouse_frame = f;
+            dpyinfo->last_mouse_frame = f;
 
             if (!tool_bar_p)
               last_tool_bar_item = -1;
@@ -7088,6 +7006,7 @@ XTread_socket (struct terminal *terminal, struct input_event *hold_quit)
 {
   int count = 0;
   int event_found = 0;
+  struct x_display_info *dpyinfo = terminal->display_info.x;
 
   block_input ();
 
@@ -7095,36 +7014,33 @@ XTread_socket (struct terminal *terminal, struct input_event *hold_quit)
   input_signal_count++;
 
   /* For debugging, this gives a way to fake an I/O error.  */
-  if (terminal->display_info.x == XTread_socket_fake_io_error)
+  if (dpyinfo == XTread_socket_fake_io_error)
     {
       XTread_socket_fake_io_error = 0;
-      x_io_error_quitter (terminal->display_info.x->display);
+      x_io_error_quitter (dpyinfo->display);
     }
 
 #ifndef USE_GTK
-  while (XPending (terminal->display_info.x->display))
+  while (XPending (dpyinfo->display))
     {
       int finish;
       XEvent event;
 
-      XNextEvent (terminal->display_info.x->display, &event);
+      XNextEvent (dpyinfo->display, &event);
 
 #ifdef HAVE_X_I18N
       /* Filter events for the current X input method.  */
-      if (x_filter_event (terminal->display_info.x, &event))
+      if (x_filter_event (dpyinfo, &event))
         continue;
 #endif
       event_found = 1;
 
-      count += handle_one_xevent (terminal->display_info.x,
-                                  &event, &finish, hold_quit);
+      count += handle_one_xevent (dpyinfo, &event, &finish, hold_quit);
 
       if (finish == X_EVENT_GOTO_OUT)
-        goto out;
+       break;
     }
 
- out:;
-
 #else /* USE_GTK */
 
   /* For GTK we must use the GTK event loop.  But XEvents gets passed
@@ -7174,12 +7090,11 @@ XTread_socket (struct terminal *terminal, struct input_event *hold_quit)
     }
 
   /* If the focus was just given to an auto-raising frame,
-     raise it now.  */
-  /* ??? This ought to be able to handle more than one such frame.  */
-  if (pending_autoraise_frame)
+     raise it now.  FIXME: handle more than one such frame.  */
+  if (dpyinfo->x_pending_autoraise_frame)
     {
-      x_raise_frame (pending_autoraise_frame);
-      pending_autoraise_frame = 0;
+      x_raise_frame (dpyinfo->x_pending_autoraise_frame);
+      dpyinfo->x_pending_autoraise_frame = NULL;
     }
 
   unblock_input ();
@@ -8533,7 +8448,7 @@ XTfullscreen_hook (struct frame *f)
 
 
 static int
-x_handle_net_wm_state (struct frame *f, const XPropertyEvent * const event)
+x_handle_net_wm_state (struct frame *f, const XPropertyEvent *event)
 {
   int value = FULLSCREEN_NONE;
   Lisp_Object lval;
@@ -9015,7 +8930,6 @@ xembed_send_message (struct frame *f, Time t, enum xembed_message msg,
 void
 x_make_frame_visible (struct frame *f)
 {
-  Lisp_Object type;
   int original_top, original_left;
   int retry_count = 2;
 
@@ -9023,9 +8937,7 @@ x_make_frame_visible (struct frame *f)
 
   block_input ();
 
-  type = x_icon_type (f);
-  if (!NILP (type))
-    x_bitmap_icon (f, type);
+  x_set_bitmap_icon (f);
 
   if (! FRAME_VISIBLE_P (f))
     {
@@ -9232,7 +9144,6 @@ x_iconify_frame (struct frame *f)
 #ifdef USE_X_TOOLKIT
   int result;
 #endif
-  Lisp_Object type;
 
   /* Don't keep the highlight on an invisible frame.  */
   if (FRAME_DISPLAY_INFO (f)->x_highlight_frame == f)
@@ -9243,9 +9154,7 @@ x_iconify_frame (struct frame *f)
 
   block_input ();
 
-  type = x_icon_type (f);
-  if (!NILP (type))
-    x_bitmap_icon (f, type);
+  x_set_bitmap_icon (f);
 
 #if defined (USE_GTK)
   if (FRAME_GTK_OUTER_WIDGET (f))
@@ -9978,26 +9887,16 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
 
   {
     struct x_display_info *share;
-    Lisp_Object tail;
 
-    for (share = x_display_list, tail = x_display_name_list; share;
-        share = share->next, tail = XCDR (tail))
-      if (same_x_server (SSDATA (XCAR (XCAR (tail))),
+    for (share = x_display_list; share; share = share->next)
+      if (same_x_server (SSDATA (XCAR (share->name_list_element)),
                         SSDATA (display_name)))
        break;
     if (share)
       terminal->kboard = share->terminal->kboard;
     else
       {
-       terminal->kboard = xmalloc (sizeof *terminal->kboard);
-       init_kboard (terminal->kboard);
-       kset_window_system (terminal->kboard, Qx);
-
-       /* Add the keyboard to the list before running Lisp code (via
-           Qvendor_specific_keysyms below), since these are not traced
-           via terminals but only through all_kboards.  */
-       terminal->kboard->next_kboard = all_kboards;
-       all_kboards = terminal->kboard;
+       terminal->kboard = allocate_kboard (Qx);
 
        if (!EQ (XSYMBOL (Qvendor_specific_keysyms)->function, Qunbound))
          {
@@ -10036,11 +9935,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
   dpyinfo->next = x_display_list;
   x_display_list = dpyinfo;
 
-  /* Put it on x_display_name_list as well, to keep them parallel.  */
-  x_display_name_list = Fcons (Fcons (display_name, Qnil),
-                              x_display_name_list);
-  dpyinfo->name_list_element = XCAR (x_display_name_list);
-
+  dpyinfo->name_list_element = Fcons (display_name, Qnil);
   dpyinfo->display = dpy;
 
   /* Set the name of the terminal. */
@@ -10367,27 +10262,6 @@ x_delete_display (struct x_display_info *dpyinfo)
         break;
       }
 
-  /* Discard this display from x_display_name_list and x_display_list.
-     We can't use Fdelq because that can quit.  */
-  if (! NILP (x_display_name_list)
-      && EQ (XCAR (x_display_name_list), dpyinfo->name_list_element))
-    x_display_name_list = XCDR (x_display_name_list);
-  else
-    {
-      Lisp_Object tail;
-
-      tail = x_display_name_list;
-      while (CONSP (tail) && CONSP (XCDR (tail)))
-       {
-         if (EQ (XCAR (XCDR (tail)), dpyinfo->name_list_element))
-           {
-             XSETCDR (tail, XCDR (XCDR (tail)));
-             break;
-           }
-         tail = XCDR (tail);
-       }
-    }
-
   if (next_noop_dpyinfo == dpyinfo)
     next_noop_dpyinfo = dpyinfo->next;
 
@@ -10601,12 +10475,6 @@ x_create_terminal (struct x_display_info *dpyinfo)
   terminal->delete_terminal_hook = x_delete_terminal;
 
   terminal->rif = &x_redisplay_interface;
-  terminal->scroll_region_ok = 1;    /* We'll scroll partial frames. */
-  terminal->char_ins_del_ok = 1;
-  terminal->line_ins_del_ok = 1;         /* We'll just blt 'em. */
-  terminal->fast_clear_end_of_line = 1;  /* X does this well. */
-  terminal->memory_below_frame = 0;   /* We don't remember what scrolls
-                                        off the bottom. */
 
   return terminal;
 }
@@ -10651,8 +10519,6 @@ x_initialize (void)
 #endif
 #endif
 
-  pending_autoraise_frame = 0;
-
   /* Note that there is no real way portable across R3/R4 to get the
      original error handler.  */
   XSetErrorHandler (x_error_handler);
@@ -10665,12 +10531,6 @@ syms_of_xterm (void)
 {
   x_error_message = NULL;
 
-  staticpro (&x_display_name_list);
-  x_display_name_list = Qnil;
-
-  staticpro (&last_mouse_scroll_bar);
-  last_mouse_scroll_bar = Qnil;
-
   DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
   DEFSYM (Qlatin_1, "latin-1");
 
@@ -10729,9 +10589,6 @@ With MS Windows or Nextstep, the value is t.  */);
   Vx_toolkit_scroll_bars = Qnil;
 #endif
 
-  staticpro (&last_mouse_motion_frame);
-  last_mouse_motion_frame = Qnil;
-
   Qmodifier_value = intern_c_string ("modifier-value");
   Qalt = intern_c_string ("alt");
   Fput (Qalt, Qmodifier_value, make_number (alt_modifier));