emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 1552e67: Fix bug that munged selection info


From: Paul Eggert
Subject: [Emacs-diffs] master 1552e67: Fix bug that munged selection info
Date: Tue, 23 Jun 2015 23:31:08 +0000

branch: master
commit 1552e6737317ea2c85e06600e178114c6b0f9fb2
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    Fix bug that munged selection info
    
    On some optimizing C compilers, copying a structure did not
    copy the padding bytes between elements, and the type punning
    between struct input_data and struct selection_input_data did
    not work.  Change the C code to use a proper union type instead.
    Problem reported by YAMAMOTO Mitsuharu (Bug#20756).
    * src/keyboard.c (kbd_buffer, kbd_fetch_ptr, kbd_store_ptr)
    (readable_events, discard_mouse_events, kbd_buffer_events_waiting)
    (kbd_buffer_get_event, process_special_events, stuff_buffered_input)
    (mark_kboards):
    Use union buffered_input_event, not struct input_event.
    (clear_event, deliver_input_available_signal, process_special_events):
    Remove unnecessary forward decls.
    (kbd_buffer_store_buffered_event): New function, mostly just the
    old kbd_buffer_store_event_hold, except its argument is of type
    union buffered_input_event, not struct input_event.
    (kbd_buffer_unget_event): Define only if HAVE_X11, since it's
    not needed otherwise.  Argument is now of type
    struct selection_input_event *, not struct input_event *.
    All callers changed.
    (clear_event): Arg is now of type union buffered_input_event *,
    not struct input_event *.  All callers changed.
    * src/keyboard.h [HAVE_X11]: Include "xterm.h".
    (union buffered_input_event): New type.
    (kbd_buffer_store_event_hold): Now an inline function,
    defined here.
    * src/termhooks.h (EVENT_KIND_WIDTH): New constant.
    (struct input_event): Use it.
    * src/xselect.c (struct selection_event_queue):
    Make elements be of type struct selection_input_event,
    not struct input_event.
    (selection_input_event_equal): New static function.
    (x_queue_event): Use it.
    (x_queue_event, x_decline_selection_request)
    (x_selection_current_request, x_reply_selection_request)
    (x_handle_selection_request, x_handle_selection_clear)
    (x_handle_selection_event): Use struct selection_input_event,
    not struct input_event.  All callers changed.
    (x_convert_selection): Omit unused first arg.  All callers changed.
    (Fx_disown_selection_internal): Omit unnecessary union.
    * src/xterm.c (handle_one_xevent): Use new union buffered_input_event
    rather than rolling our own equivalent.  Prefer sie.kind when
    setting up that kind of structure.
    Call kbd_buffer_store_buffered_event, not kbd_buffer_store_event_hold.
    * src/xterm.h (struct selection_input_event: Use EVENT_KIND_WIDTH.
    (SELECTION_EVENT_DISPLAY, SELECTION_EVENT_DPYINFO)
    (SELECTION_EVENT_REQUESTOR, SELECTION_EVENT_SELECTION)
    (SELECTION_EVENT_TARGET, SELECTION_EVENT_PROPERTY)
    (SELECTION_EVENT_TIME, x_handle_selection_event):
    Arg is now of type struct selection_input_event *)
    not struct input_event *.  All callers changed.
---
 src/keyboard.c  |  151 +++++++++++++++++++++++++++----------------------------
 src/keyboard.h  |   30 ++++++++++-
 src/termhooks.h |    5 ++-
 src/xselect.c   |   54 +++++++++++--------
 src/xterm.c     |   13 ++---
 src/xterm.h     |   20 ++++----
 6 files changed, 151 insertions(+), 122 deletions(-)

diff --git a/src/keyboard.c b/src/keyboard.c
index 7bfc3f3..8ea7b53 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -288,18 +288,18 @@ static bool input_was_pending;
 
 /* Circular buffer for pre-read keyboard input.  */
 
-static struct input_event kbd_buffer[KBD_BUFFER_SIZE];
+static union buffered_input_event kbd_buffer[KBD_BUFFER_SIZE];
 
 /* Pointer to next available character in kbd_buffer.
    If kbd_fetch_ptr == kbd_store_ptr, the buffer is empty.
    This may be kbd_buffer + KBD_BUFFER_SIZE, meaning that the
    next available char is in kbd_buffer[0].  */
-static struct input_event *kbd_fetch_ptr;
+static union buffered_input_event *kbd_fetch_ptr;
 
 /* Pointer to next place to store character in kbd_buffer.  This
    may be kbd_buffer + KBD_BUFFER_SIZE, meaning that the next
    character should go in kbd_buffer[0].  */
-static struct input_event * volatile kbd_store_ptr;
+static union buffered_input_event *volatile kbd_store_ptr;
 
 /* The above pair of variables forms a "queue empty" flag.  When we
    enqueue a non-hook event, we increment kbd_store_ptr.  When we
@@ -372,14 +372,9 @@ static bool help_char_p (Lisp_Object);
 static void save_getcjmp (sys_jmp_buf);
 static void restore_getcjmp (sys_jmp_buf);
 static Lisp_Object apply_modifiers (int, Lisp_Object);
-static void clear_event (struct input_event *);
 static void restore_kboard_configuration (int);
-#ifdef USABLE_SIGIO
-static void deliver_input_available_signal (int signo);
-#endif
 static void handle_interrupt (bool);
 static _Noreturn void quit_throw_to_read_char (bool);
-static void process_special_events (void);
 static void timer_start_idle (void);
 static void timer_stop_idle (void);
 static void timer_resume_idle (void);
@@ -3446,7 +3441,7 @@ readable_events (int flags)
 #endif
                   ))
         {
-          struct input_event *event;
+          union buffered_input_event *event;
 
           event = ((kbd_fetch_ptr < kbd_buffer + KBD_BUFFER_SIZE)
                    ? kbd_fetch_ptr
@@ -3463,8 +3458,8 @@ readable_events (int flags)
                  && !((flags & READABLE_EVENTS_IGNORE_SQUEEZABLES)
                       && (event->kind == SCROLL_BAR_CLICK_EVENT
                           || event->kind == HORIZONTAL_SCROLL_BAR_CLICK_EVENT)
-                      && event->part == scroll_bar_handle
-                      && event->modifiers == 0)
+                      && event->ie.part == scroll_bar_handle
+                      && event->ie.modifiers == 0)
 #endif
                  && !((flags & READABLE_EVENTS_FILTER_EVENTS)
                       && event->kind == BUFFER_SWITCH_EVENT))
@@ -3551,8 +3546,8 @@ kbd_buffer_store_event (register struct input_event 
*event)
    subsequent input events have been parsed (and discarded).  */
 
 void
-kbd_buffer_store_event_hold (register struct input_event *event,
-                            struct input_event *hold_quit)
+kbd_buffer_store_buffered_event (union buffered_input_event *event,
+                                struct input_event *hold_quit)
 {
   if (event->kind == NO_EVENT)
     emacs_abort ();
@@ -3562,36 +3557,36 @@ kbd_buffer_store_event_hold (register struct 
input_event *event,
 
   if (event->kind == ASCII_KEYSTROKE_EVENT)
     {
-      register int c = event->code & 0377;
+      int c = event->ie.code & 0377;
 
-      if (event->modifiers & ctrl_modifier)
+      if (event->ie.modifiers & ctrl_modifier)
        c = make_ctrl_char (c);
 
-      c |= (event->modifiers
+      c |= (event->ie.modifiers
            & (meta_modifier | alt_modifier
               | hyper_modifier | super_modifier));
 
       if (c == quit_char)
        {
-         KBOARD *kb = FRAME_KBOARD (XFRAME (event->frame_or_window));
-         struct input_event *sp;
+         KBOARD *kb = FRAME_KBOARD (XFRAME (event->ie.frame_or_window));
 
          if (single_kboard && kb != current_kboard)
            {
              kset_kbd_queue
-               (kb, list2 (make_lispy_switch_frame (event->frame_or_window),
+               (kb, list2 (make_lispy_switch_frame (event->ie.frame_or_window),
                            make_number (c)));
              kb->kbd_queue_has_data = 1;
+             union buffered_input_event *sp;
              for (sp = kbd_fetch_ptr; sp != kbd_store_ptr; sp++)
                {
                  if (sp == kbd_buffer + KBD_BUFFER_SIZE)
                    sp = kbd_buffer;
 
-                 if (event_to_kboard (sp) == kb)
+                 if (event_to_kboard (&sp->ie) == kb)
                    {
-                     sp->kind = NO_EVENT;
-                     sp->frame_or_window = Qnil;
-                     sp->arg = Qnil;
+                     sp->ie.kind = NO_EVENT;
+                     sp->ie.frame_or_window = Qnil;
+                     sp->ie.arg = Qnil;
                    }
                }
              return;
@@ -3599,7 +3594,7 @@ kbd_buffer_store_event_hold (register struct input_event 
*event,
 
          if (hold_quit)
            {
-             *hold_quit = *event;
+             *hold_quit = event->ie;
              return;
            }
 
@@ -3610,9 +3605,9 @@ kbd_buffer_store_event_hold (register struct input_event 
*event,
          {
            Lisp_Object focus;
 
-           focus = FRAME_FOCUS_FRAME (XFRAME (event->frame_or_window));
+           focus = FRAME_FOCUS_FRAME (XFRAME (event->ie.frame_or_window));
            if (NILP (focus))
-             focus = event->frame_or_window;
+             focus = event->ie.frame_or_window;
            internal_last_event_frame = focus;
            Vlast_event_frame = focus;
          }
@@ -3682,22 +3677,27 @@ kbd_buffer_store_event_hold (register struct 
input_event *event,
 }
 
 
-/* Put an input event back in the head of the event queue.  */
+#ifdef HAVE_X11
+
+/* Put a selection input event back in the head of the event queue.  */
 
 void
-kbd_buffer_unget_event (register struct input_event *event)
+kbd_buffer_unget_event (struct selection_input_event *event)
 {
   if (kbd_fetch_ptr == kbd_buffer)
     kbd_fetch_ptr = kbd_buffer + KBD_BUFFER_SIZE;
 
   /* Don't let the very last slot in the buffer become full,  */
-  if (kbd_fetch_ptr - 1 != kbd_store_ptr)
+  union buffered_input_event *kp = kbd_fetch_ptr - 1;
+  if (kp != kbd_store_ptr)
     {
-      --kbd_fetch_ptr;
-      *kbd_fetch_ptr = *event;
+      kp->sie = *event;
+      kbd_fetch_ptr = kp;
     }
 }
 
+#endif
+
 /* Limit help event positions to this range, to avoid overflow problems.  */
 #define INPUT_EVENT_POS_MAX \
   ((ptrdiff_t) min (PTRDIFF_MAX, min (TYPE_MAXIMUM (Time) / 2, \
@@ -3776,7 +3776,7 @@ kbd_buffer_store_help_event (Lisp_Object frame, 
Lisp_Object help)
 void
 discard_mouse_events (void)
 {
-  struct input_event *sp;
+  union buffered_input_event *sp;
   for (sp = kbd_fetch_ptr; sp != kbd_store_ptr; sp++)
     {
       if (sp == kbd_buffer + KBD_BUFFER_SIZE)
@@ -3806,7 +3806,7 @@ discard_mouse_events (void)
 bool
 kbd_buffer_events_waiting (void)
 {
-  struct input_event *sp;
+  union buffered_input_event *sp;
 
   for (sp = kbd_fetch_ptr;
        sp != kbd_store_ptr && sp->kind == NO_EVENT;
@@ -3824,7 +3824,7 @@ kbd_buffer_events_waiting (void)
 /* Clear input event EVENT.  */
 
 static void
-clear_event (struct input_event *event)
+clear_event (union buffered_input_event *event)
 {
   event->kind = NO_EVENT;
 }
@@ -3945,13 +3945,13 @@ kbd_buffer_get_event (KBOARD **kbp,
      mouse movement enabled and available.  */
   if (kbd_fetch_ptr != kbd_store_ptr)
     {
-      struct input_event *event;
+      union buffered_input_event *event;
 
       event = ((kbd_fetch_ptr < kbd_buffer + KBD_BUFFER_SIZE)
               ? kbd_fetch_ptr
               : kbd_buffer);
 
-      *kbp = event_to_kboard (event);
+      *kbp = event_to_kboard (&event->ie);
       if (*kbp == 0)
        *kbp = current_kboard;  /* Better than returning null ptr?  */
 
@@ -3964,12 +3964,10 @@ kbd_buffer_get_event (KBOARD **kbp,
          || event->kind == SELECTION_CLEAR_EVENT)
        {
 #ifdef HAVE_X11
-         struct input_event copy;
-
          /* Remove it from the buffer before processing it,
             since otherwise swallow_events will see it
             and process it again.  */
-         copy = *event;
+         struct selection_input_event copy = event->sie;
          kbd_fetch_ptr = event + 1;
          input_pending = readable_events (0);
          x_handle_selection_event (&copy);
@@ -3983,7 +3981,7 @@ kbd_buffer_get_event (KBOARD **kbp,
 #if defined (HAVE_NS)
       else if (event->kind == NS_TEXT_EVENT)
         {
-          if (event->code == KEY_NS_PUT_WORKING_TEXT)
+          if (event->ie.code == KEY_NS_PUT_WORKING_TEXT)
             obj = list1 (intern ("ns-put-working-text"));
           else
             obj = list1 (intern ("ns-unput-working-text"));
@@ -3998,7 +3996,7 @@ kbd_buffer_get_event (KBOARD **kbp,
       else if (event->kind == DELETE_WINDOW_EVENT)
        {
          /* Make an event (delete-frame (FRAME)).  */
-         obj = list2 (Qdelete_frame, list1 (event->frame_or_window));
+         obj = list2 (Qdelete_frame, list1 (event->ie.frame_or_window));
          kbd_fetch_ptr = event + 1;
        }
 #endif
@@ -4007,13 +4005,13 @@ kbd_buffer_get_event (KBOARD **kbp,
       else if (event->kind == ICONIFY_EVENT)
        {
          /* Make an event (iconify-frame (FRAME)).  */
-         obj = list2 (Qiconify_frame, list1 (event->frame_or_window));
+         obj = list2 (Qiconify_frame, list1 (event->ie.frame_or_window));
          kbd_fetch_ptr = event + 1;
        }
       else if (event->kind == DEICONIFY_EVENT)
        {
          /* Make an event (make-frame-visible (FRAME)).  */
-         obj = list2 (Qmake_frame_visible, list1 (event->frame_or_window));
+         obj = list2 (Qmake_frame_visible, list1 (event->ie.frame_or_window));
          kbd_fetch_ptr = event + 1;
        }
 #endif
@@ -4029,8 +4027,8 @@ kbd_buffer_get_event (KBOARD **kbp,
        {
          kbd_fetch_ptr = event + 1;
          input_pending = readable_events (0);
-         if (FRAME_LIVE_P (XFRAME (event->frame_or_window)))
-           x_activate_menubar (XFRAME (event->frame_or_window));
+         if (FRAME_LIVE_P (XFRAME (event->ie.frame_or_window)))
+           x_activate_menubar (XFRAME (event->ie.frame_or_window));
        }
 #endif
 #ifdef HAVE_NTGUI
@@ -4038,9 +4036,9 @@ kbd_buffer_get_event (KBOARD **kbp,
        {
          /* Make an event (language-change FRAME CODEPAGE LANGUAGE-ID).  */
          obj = list4 (Qlanguage_change,
-                      event->frame_or_window,
-                      make_number (event->code),
-                      make_number (event->modifiers));
+                      event->ie.frame_or_window,
+                      make_number (event->ie.code),
+                      make_number (event->ie.modifiers));
          kbd_fetch_ptr = event + 1;
        }
 #endif
@@ -4049,16 +4047,16 @@ kbd_buffer_get_event (KBOARD **kbp,
        {
 #ifdef HAVE_W32NOTIFY
          /* Make an event (file-notify (DESCRIPTOR ACTION FILE) CALLBACK).  */
-         obj = list3 (Qfile_notify, event->arg, event->frame_or_window);
+         obj = list3 (Qfile_notify, event->ie.arg, event->ie.frame_or_window);
 #else
-          obj = make_lispy_event (event);
+          obj = make_lispy_event (&event->ie);
 #endif
          kbd_fetch_ptr = event + 1;
        }
 #endif /* USE_FILE_NOTIFY */
       else if (event->kind == SAVE_SESSION_EVENT)
         {
-          obj = list2 (Qsave_session, event->arg);
+          obj = list2 (Qsave_session, event->ie.arg);
          kbd_fetch_ptr = event + 1;
         }
       /* Just discard these, by returning nil.
@@ -4075,11 +4073,11 @@ kbd_buffer_get_event (KBOARD **kbp,
        {
          Lisp_Object object, position, help, frame, window;
 
-         frame = event->frame_or_window;
-         object = event->arg;
-         position = make_number (Time_to_position (event->timestamp));
-         window = event->x;
-         help = event->y;
+         frame = event->ie.frame_or_window;
+         object = event->ie.arg;
+         position = make_number (Time_to_position (event->ie.timestamp));
+         window = event->ie.x;
+         help = event->ie.y;
          clear_event (event);
 
          kbd_fetch_ptr = event + 1;
@@ -4095,14 +4093,14 @@ kbd_buffer_get_event (KBOARD **kbp,
             switch-frame event if necessary.  */
          Lisp_Object frame, focus;
 
-          frame = event->frame_or_window;
+          frame = event->ie.frame_or_window;
           focus = FRAME_FOCUS_FRAME (XFRAME (frame));
           if (FRAMEP (focus))
             frame = focus;
 
           if (
 #ifdef HAVE_X11
-              ! NILP (event->arg)
+              ! NILP (event->ie.arg)
               &&
 #endif
               !EQ (frame, internal_last_event_frame)
@@ -4119,7 +4117,7 @@ kbd_buffer_get_event (KBOARD **kbp,
 #ifdef HAVE_WINDOW_SYSTEM
 
           Display_Info *di;
-          Lisp_Object frame = event->frame_or_window;
+          Lisp_Object frame = event->ie.frame_or_window;
           bool focused = false;
 
           for (di = x_display_list; di && ! focused; di = di->next)
@@ -4135,13 +4133,13 @@ kbd_buffer_get_event (KBOARD **kbp,
 #ifdef HAVE_DBUS
       else if (event->kind == DBUS_EVENT)
        {
-         obj = make_lispy_event (event);
+         obj = make_lispy_event (&event->ie);
          kbd_fetch_ptr = event + 1;
        }
 #endif
       else if (event->kind == CONFIG_CHANGED_EVENT)
        {
-         obj = make_lispy_event (event);
+         obj = make_lispy_event (&event->ie);
          kbd_fetch_ptr = event + 1;
        }
       else
@@ -4151,7 +4149,7 @@ kbd_buffer_get_event (KBOARD **kbp,
          Lisp_Object frame;
          Lisp_Object focus;
 
-         frame = event->frame_or_window;
+         frame = event->ie.frame_or_window;
          if (CONSP (frame))
            frame = XCAR (frame);
          else if (WINDOWP (frame))
@@ -4171,7 +4169,7 @@ kbd_buffer_get_event (KBOARD **kbp,
 
          if (NILP (obj))
            {
-             obj = make_lispy_event (event);
+             obj = make_lispy_event (&event->ie);
 
 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
     || defined (HAVE_NS) || defined (USE_GTK)
@@ -4181,7 +4179,7 @@ kbd_buffer_get_event (KBOARD **kbp,
                 beginning of the menu sequence, and we might as well leave
                 that as the `event with parameters' for this selection.  */
              if (used_mouse_menu
-                 && !EQ (event->frame_or_window, event->arg)
+                 && !EQ (event->ie.frame_or_window, event->ie.arg)
                  && (event->kind == MENU_BAR_EVENT
                      || event->kind == TOOL_BAR_EVENT))
                *used_mouse_menu = 1;
@@ -4261,7 +4259,7 @@ kbd_buffer_get_event (KBOARD **kbp,
 static void
 process_special_events (void)
 {
-  struct input_event *event;
+  union buffered_input_event *event;
 
   for (event = kbd_fetch_ptr; event != kbd_store_ptr; ++event)
     {
@@ -4284,23 +4282,22 @@ process_special_events (void)
             between kbd_fetch_ptr and EVENT one slot to the right,
             cyclically.  */
 
-         struct input_event copy = *event;
-         struct input_event *beg
+         struct selection_input_event copy = event->sie;
+         union buffered_input_event *beg
            = (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE)
            ? kbd_buffer : kbd_fetch_ptr;
 
          if (event > beg)
-           memmove (beg + 1, beg, (event - beg) * sizeof (struct input_event));
+           memmove (beg + 1, beg, (event - beg) * sizeof *beg);
          else if (event < beg)
            {
              if (event > kbd_buffer)
                memmove (kbd_buffer + 1, kbd_buffer,
-                        (event - kbd_buffer) * sizeof (struct input_event));
+                        (event - kbd_buffer) * sizeof *kbd_buffer);
              *kbd_buffer = *(kbd_buffer + KBD_BUFFER_SIZE - 1);
              if (beg < kbd_buffer + KBD_BUFFER_SIZE - 1)
                memmove (beg + 1, beg,
-                        (kbd_buffer + KBD_BUFFER_SIZE - 1 - beg)
-                        * sizeof (struct input_event));
+                        (kbd_buffer + KBD_BUFFER_SIZE - 1 - beg) * sizeof 
*beg);
            }
 
          if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE)
@@ -10311,7 +10308,7 @@ stuff_buffered_input (Lisp_Object stuffstring)
       if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE)
        kbd_fetch_ptr = kbd_buffer;
       if (kbd_fetch_ptr->kind == ASCII_KEYSTROKE_EVENT)
-       stuff_char (kbd_fetch_ptr->code);
+       stuff_char (kbd_fetch_ptr->ie.code);
 
       clear_event (kbd_fetch_ptr);
     }
@@ -11937,7 +11934,7 @@ mark_kboards (void)
       mark_object (KVAR (kb, echo_string));
     }
   {
-    struct input_event *event;
+    union buffered_input_event *event;
     for (event = kbd_fetch_ptr; event != kbd_store_ptr; event++)
       {
        if (event == kbd_buffer + KBD_BUFFER_SIZE)
@@ -11946,10 +11943,10 @@ mark_kboards (void)
        if (event->kind != SELECTION_REQUEST_EVENT
            && event->kind != SELECTION_CLEAR_EVENT)
          {
-           mark_object (event->x);
-           mark_object (event->y);
-           mark_object (event->frame_or_window);
-           mark_object (event->arg);
+           mark_object (event->ie.x);
+           mark_object (event->ie.y);
+           mark_object (event->ie.frame_or_window);
+           mark_object (event->ie.arg);
          }
       }
   }
diff --git a/src/keyboard.h b/src/keyboard.h
index bcdeaf6..5278051 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -21,6 +21,10 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include "coding.h"             /* for ENCODE_UTF_8 and ENCODE_SYSTEM */
 #include "termhooks.h"
 
+#ifdef HAVE_X11
+# include "xterm.h"            /* for struct selection_input_event */
+#endif
+
 INLINE_HEADER_BEGIN
 
 /* Most code should use this macro to access Lisp fields in struct kboard.  */
@@ -217,6 +221,15 @@ kset_window_system (struct kboard *kb, Lisp_Object val)
   kb->Vwindow_system_ = val;
 }
 
+union buffered_input_event
+{
+  ENUM_BF (event_kind) kind : EVENT_KIND_WIDTH;
+  struct input_event ie;
+#ifdef HAVE_X11
+  struct selection_input_event sie;
+#endif
+};
+
 /* Temporarily used before a frame has been opened. */
 extern KBOARD *initial_kboard;
 
@@ -438,9 +451,20 @@ extern void clear_waiting_for_input (void);
 extern void swallow_events (bool);
 extern bool lucid_event_type_list_p (Lisp_Object);
 extern void kbd_buffer_store_event (struct input_event *);
-extern void kbd_buffer_store_event_hold (struct input_event *,
-                                         struct input_event *);
-extern void kbd_buffer_unget_event (struct input_event *);
+extern void kbd_buffer_store_buffered_event (union buffered_input_event *,
+                                            struct input_event *);
+INLINE void
+kbd_buffer_store_event_hold (struct input_event *event,
+                            struct input_event *hold_quit)
+{
+  union buffered_input_event *ev = (union buffered_input_event *) event;
+  verify (sizeof *event == sizeof *ev && alignof (*event) == alignof (*ev));
+  return kbd_buffer_store_buffered_event ((union buffered_input_event *) event,
+                                         hold_quit);
+}
+#ifdef HAVE_X11
+extern void kbd_buffer_unget_event (struct selection_input_event *);
+#endif
 extern void poll_for_input_1 (void);
 extern void show_help_echo (Lisp_Object, Lisp_Object, Lisp_Object,
                             Lisp_Object);
diff --git a/src/termhooks.h b/src/termhooks.h
index 3cafc43..168bc35 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -243,6 +243,9 @@ enum event_kind
 
 };
 
+/* Bit width of an enum event_kind tag at the start of structs and unions.  */
+enum { EVENT_KIND_WIDTH = 16 };
+
 /* If a struct input_event has a kind which is SELECTION_REQUEST_EVENT
    or SELECTION_CLEAR_EVENT, then its contents are really described
    by `struct selection_input_event'; see xterm.h.  */
@@ -255,7 +258,7 @@ enum event_kind
 struct input_event
 {
   /* What kind of event was this?  */
-  ENUM_BF (event_kind) kind : 16;
+  ENUM_BF (event_kind) kind : EVENT_KIND_WIDTH;
 
   /* Used in scroll back click events.  */
   ENUM_BF (scroll_bar_part) part : 16;
diff --git a/src/xselect.c b/src/xselect.c
index 19ace06..bd2d65e 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -45,9 +45,8 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 struct prop_location;
 struct selection_data;
 
-static void x_decline_selection_request (struct input_event *);
-static bool x_convert_selection (struct input_event *, Lisp_Object,
-                                Lisp_Object, Atom, bool,
+static void x_decline_selection_request (struct selection_input_event *);
+static bool x_convert_selection (Lisp_Object, Lisp_Object, Atom, bool,
                                 struct x_display_info *);
 static bool waiting_for_other_props_on_window (Display *, Window);
 static struct prop_location *expect_property_change (Display *, Window,
@@ -117,7 +116,7 @@ selection_quantum (Display *display)
 
 struct selection_event_queue
   {
-    struct input_event event;
+    struct selection_input_event event;
     struct selection_event_queue *next;
   };
 
@@ -127,10 +126,22 @@ static struct selection_event_queue *selection_queue;
 
 static int x_queue_selection_requests;
 
+/* True if the input events are duplicates.  */
+
+static bool
+selection_input_event_equal (struct selection_input_event *a,
+                            struct selection_input_event *b)
+{
+  return (a->kind == b->kind && a->dpyinfo == b->dpyinfo
+         && a->requestor == b->requestor && a->selection == b->selection
+         && a->target == b->target && a->property == b->property
+         && a->time == b->time);
+}
+
 /* Queue up an SELECTION_REQUEST_EVENT *EVENT, to be processed later.  */
 
 static void
-x_queue_event (struct input_event *event)
+x_queue_event (struct selection_input_event *event)
 {
   struct selection_event_queue *queue_tmp;
 
@@ -138,7 +149,7 @@ x_queue_event (struct input_event *event)
      This only happens for large requests which uses the incremental protocol. 
 */
   for (queue_tmp = selection_queue; queue_tmp; queue_tmp = queue_tmp->next)
     {
-      if (!memcmp (&queue_tmp->event, event, sizeof (*event)))
+      if (selection_input_event_equal (event, &queue_tmp->event))
        {
          TRACE1 ("DECLINE DUP SELECTION EVENT %p", queue_tmp);
          x_decline_selection_request (event);
@@ -419,7 +430,7 @@ x_get_local_selection (Lisp_Object selection_symbol, 
Lisp_Object target_type,
    meaning we were unable to do what they wanted.  */
 
 static void
-x_decline_selection_request (struct input_event *event)
+x_decline_selection_request (struct selection_input_event *event)
 {
   XEvent reply_base;
   XSelectionEvent *reply = &(reply_base.xselection);
@@ -444,7 +455,7 @@ x_decline_selection_request (struct input_event *event)
 
 /* This is the selection request currently being processed.
    It is set to zero when the request is fully processed.  */
-static struct input_event *x_selection_current_request;
+static struct selection_input_event *x_selection_current_request;
 
 /* Display info in x_selection_request.  */
 
@@ -549,7 +560,7 @@ static int x_reply_selection_request_cnt;
 #endif  /* TRACE_SELECTION */
 
 static void
-x_reply_selection_request (struct input_event *event,
+x_reply_selection_request (struct selection_input_event *event,
                            struct x_display_info *dpyinfo)
 {
   XEvent reply_base;
@@ -740,7 +751,7 @@ x_reply_selection_request (struct input_event *event,
    This is called from keyboard.c when such an event is found in the queue.  */
 
 static void
-x_handle_selection_request (struct input_event *event)
+x_handle_selection_request (struct selection_input_event *event)
 {
   struct gcpro gcpro1, gcpro2;
   Time local_selection_time;
@@ -809,7 +820,7 @@ x_handle_selection_request (struct input_event *event)
                                               AREF (multprop, 2*j+1));
 
          if (subproperty != None)
-           x_convert_selection (event, selection_symbol, subtarget,
+           x_convert_selection (selection_symbol, subtarget,
                                 subproperty, true, dpyinfo);
        }
       success = true;
@@ -818,7 +829,7 @@ x_handle_selection_request (struct input_event *event)
     {
       if (property == None)
        property = SELECTION_EVENT_TARGET (event);
-      success = x_convert_selection (event, selection_symbol,
+      success = x_convert_selection (selection_symbol,
                                     target_symbol, property,
                                     false, dpyinfo);
     }
@@ -849,7 +860,7 @@ x_handle_selection_request (struct input_event *event)
    Return true iff successful.  */
 
 static bool
-x_convert_selection (struct input_event *event, Lisp_Object selection_symbol,
+x_convert_selection (Lisp_Object selection_symbol,
                     Lisp_Object target_symbol, Atom property,
                     bool for_multiple, struct x_display_info *dpyinfo)
 {
@@ -902,7 +913,7 @@ x_convert_selection (struct input_event *event, Lisp_Object 
selection_symbol,
    This is called from keyboard.c when such an event is found in the queue.  */
 
 static void
-x_handle_selection_clear (struct input_event *event)
+x_handle_selection_clear (struct selection_input_event *event)
 {
   Atom selection = SELECTION_EVENT_SELECTION (event);
   Time changed_owner_time = SELECTION_EVENT_TIME (event);
@@ -954,7 +965,7 @@ x_handle_selection_clear (struct input_event *event)
 }
 
 void
-x_handle_selection_event (struct input_event *event)
+x_handle_selection_event (struct selection_input_event *event)
 {
   TRACE0 ("x_handle_selection_event");
   if (event->kind != SELECTION_REQUEST_EVENT)
@@ -2006,10 +2017,7 @@ On MS-DOS, all this does is return non-nil if we own the 
selection.  */)
 {
   Time timestamp;
   Atom selection_atom;
-  union {
-    struct selection_input_event sie;
-    struct input_event ie;
-  } event;
+  struct selection_input_event event;
   struct frame *f = frame_for_x_selection (terminal);
   struct x_display_info *dpyinfo;
 
@@ -2038,10 +2046,10 @@ On MS-DOS, all this does is return non-nil if we own 
the selection.  */)
      the selection owner to None.  The NCD server does, the MIT Sun4 server
      doesn't.  So we synthesize one; this means we might get two, but
      that's ok, because the second one won't have any effect.  */
-  SELECTION_EVENT_DPYINFO (&event.sie) = dpyinfo;
-  SELECTION_EVENT_SELECTION (&event.sie) = selection_atom;
-  SELECTION_EVENT_TIME (&event.sie) = timestamp;
-  x_handle_selection_clear (&event.ie);
+  SELECTION_EVENT_DPYINFO (&event) = dpyinfo;
+  SELECTION_EVENT_SELECTION (&event) = selection_atom;
+  SELECTION_EVENT_TIME (&event) = timestamp;
+  x_handle_selection_clear (&event);
 
   return Qt;
 }
diff --git a/src/xterm.c b/src/xterm.c
index 4d79450..d573738 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -7358,10 +7358,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                   const XEvent *event,
                   int *finish, struct input_event *hold_quit)
 {
-  union {
-    struct input_event ie;
-    struct selection_input_event sie;
-  } inev;
+  union buffered_input_event inev;
   int count = 0;
   int do_help = 0;
   ptrdiff_t nbytes = 0;
@@ -7589,7 +7586,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       {
         const XSelectionClearEvent *eventp = &event->xselectionclear;
 
-        inev.ie.kind = SELECTION_CLEAR_EVENT;
+        inev.sie.kind = SELECTION_CLEAR_EVENT;
         SELECTION_EVENT_DPYINFO (&inev.sie) = dpyinfo;
         SELECTION_EVENT_SELECTION (&inev.sie) = eventp->selection;
         SELECTION_EVENT_TIME (&inev.sie) = eventp->time;
@@ -7605,7 +7602,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       {
        const XSelectionRequestEvent *eventp = &event->xselectionrequest;
 
-       inev.ie.kind = SELECTION_REQUEST_EVENT;
+       inev.sie.kind = SELECTION_REQUEST_EVENT;
        SELECTION_EVENT_DPYINFO (&inev.sie) = dpyinfo;
        SELECTION_EVENT_REQUESTOR (&inev.sie) = eventp->requestor;
        SELECTION_EVENT_SELECTION (&inev.sie) = eventp->selection;
@@ -8116,7 +8113,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                                ? ASCII_KEYSTROKE_EVENT
                                : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
                inev.ie.code = ch;
-               kbd_buffer_store_event_hold (&inev.ie, hold_quit);
+               kbd_buffer_store_buffered_event (&inev, hold_quit);
              }
 
            count += nchars;
@@ -8533,7 +8530,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
  done:
   if (inev.ie.kind != NO_EVENT)
     {
-      kbd_buffer_store_event_hold (&inev.ie, hold_quit);
+      kbd_buffer_store_buffered_event (&inev, hold_quit);
       count++;
     }
 
diff --git a/src/xterm.h b/src/xterm.h
index 3081c16..5622344 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -960,7 +960,7 @@ struct scroll_bar
 
 struct selection_input_event
 {
-  int kind;
+  ENUM_BF (event_kind) kind : EVENT_KIND_WIDTH;
   struct x_display_info *dpyinfo;
   /* We spell it with an "o" here because X does.  */
   Window requestor;
@@ -970,23 +970,23 @@ struct selection_input_event
 
 /* Unlike macros below, this can't be used as an lvalue.  */
 INLINE Display *
-SELECTION_EVENT_DISPLAY (struct input_event *ev)
+SELECTION_EVENT_DISPLAY (struct selection_input_event *ev)
 {
-  return ((struct selection_input_event *) ev)->dpyinfo->display;
+  return ev->dpyinfo->display;
 }
 #define SELECTION_EVENT_DPYINFO(eventp) \
-  (((struct selection_input_event *) (eventp))->dpyinfo)
+  ((eventp)->dpyinfo)
 /* We spell it with an "o" here because X does.  */
 #define SELECTION_EVENT_REQUESTOR(eventp)      \
-  (((struct selection_input_event *) (eventp))->requestor)
+  ((eventp)->requestor)
 #define SELECTION_EVENT_SELECTION(eventp)      \
-  (((struct selection_input_event *) (eventp))->selection)
+  ((eventp)->selection)
 #define SELECTION_EVENT_TARGET(eventp) \
-  (((struct selection_input_event *) (eventp))->target)
+  ((eventp)->target)
 #define SELECTION_EVENT_PROPERTY(eventp)       \
-  (((struct selection_input_event *) (eventp))->property)
+  ((eventp)->property)
 #define SELECTION_EVENT_TIME(eventp)   \
-  (((struct selection_input_event *) (eventp))->time)
+  ((eventp)->time)
 
 /* From xfns.c.  */
 
@@ -1079,7 +1079,7 @@ extern void x_clear_under_internal_border (struct frame 
*f);
 
 extern void x_handle_property_notify (const XPropertyEvent *);
 extern void x_handle_selection_notify (const XSelectionEvent *);
-extern void x_handle_selection_event (struct input_event *);
+extern void x_handle_selection_event (struct selection_input_event *);
 extern void x_clear_frame_selections (struct frame *);
 
 extern void x_send_client_event (Lisp_Object display,



reply via email to

[Prev in Thread] Current Thread [Next in Thread]