Commit 89079179 authored by Kim F. Storm's avatar Kim F. Storm

(x_focus_changed, x_detect_focus_change): Remove

numchars arg.  Always store event into bufp arg.  Return nothing.
Callers changed accordingly.
(glyph_rect): Simplify.
(STORE_KEYSYM_FOR_DEBUG): New macro.
(SET_SAVED_MENU_EVENT): Use inev instead of bufp, etc.
(current_bufp, current_numcharsp) [USE_GTK]: Remove.
(current_hold_quit) [USE_GTK]: Add.
(event_handler_gdk): Adapt to new handle_one_xevent.
(handle_one_xevent): Remove bufp_r and numcharsp args.
Add hold_quit arg. Rework to use just one, local, inev
input_event. Store inev directly in fifo using
kbd_buffer_store_event_hold.  Update count in one place.
Postpone call to gen_help_event until inev is stored; use new
local do_help for this.
Simplify handling of keysyms (consolidate common code).  Fix bug
where count was updated with nchars instead of nbytes.
Remove local emacs_event in handing of ButtonPress event; just use
inev instead (so no reason to copy it later).
Remove `out' label.  Rename label `ret' to `done'; add various
`goto done' to clarify code flow in deeply nested blocks.
(x_dispatch_event): Simplify as handle_one_xevent now calls
kbd_buffer_store_event itself.
(XTread_socket): Remove bufp_r and numcharsp args. Add hold_quit
arg.  Call handle_one_xevent with new arglist.  Store event from
x_session_check_input in fifo.
[USE_GTK]: Setup current_hold_quit.
Decrement handling_signal before unblocking input.
(x_initialize) [USE_GTK]: Initialize current_count.
parent a6950dfa
...@@ -336,16 +336,10 @@ static void x_clear_frame P_ ((void)); ...@@ -336,16 +336,10 @@ static void x_clear_frame P_ ((void));
static void frame_highlight P_ ((struct frame *)); static void frame_highlight P_ ((struct frame *));
static void frame_unhighlight P_ ((struct frame *)); static void frame_unhighlight P_ ((struct frame *));
static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *)); static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
static int x_focus_changed P_ ((int, static void x_focus_changed P_ ((int, int, struct x_display_info *,
int, struct frame *, struct input_event *));
struct x_display_info *, static void x_detect_focus_change P_ ((struct x_display_info *,
struct frame *, XEvent *, struct input_event *));
struct input_event *,
int));
static int x_detect_focus_change P_ ((struct x_display_info *,
XEvent *,
struct input_event *,
int));
static void XTframe_rehighlight P_ ((struct frame *)); static void XTframe_rehighlight P_ ((struct frame *));
static void x_frame_rehighlight P_ ((struct x_display_info *)); static void x_frame_rehighlight P_ ((struct x_display_info *));
static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *)); static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
...@@ -364,11 +358,8 @@ static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *, ...@@ -364,11 +358,8 @@ static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
unsigned long *)); unsigned long *));
static void x_check_fullscreen P_ ((struct frame *)); static void x_check_fullscreen P_ ((struct frame *));
static void x_check_expected_move P_ ((struct frame *)); static void x_check_expected_move P_ ((struct frame *));
static int handle_one_xevent P_ ((struct x_display_info *, static int handle_one_xevent P_ ((struct x_display_info *, XEvent *,
XEvent *, int *, struct input_event *));
struct input_event **,
int *,
int *));
/* Flush display of frame F, or of all frames if F is null. */ /* Flush display of frame F, or of all frames if F is null. */
...@@ -3167,20 +3158,16 @@ x_new_focus_frame (dpyinfo, frame) ...@@ -3167,20 +3158,16 @@ x_new_focus_frame (dpyinfo, frame)
/* Handle FocusIn and FocusOut state changes for FRAME. /* Handle FocusIn and FocusOut state changes for FRAME.
If FRAME has focus and there exists more than one frame, puts If FRAME has focus and there exists more than one frame, puts
a FOCUS_IN_EVENT into BUFP. a FOCUS_IN_EVENT into *BUFP. */
Returns number of events inserted into BUFP. */
static int static void
x_focus_changed (type, state, dpyinfo, frame, bufp, numchars) x_focus_changed (type, state, dpyinfo, frame, bufp)
int type; int type;
int state; int state;
struct x_display_info *dpyinfo; struct x_display_info *dpyinfo;
struct frame *frame; struct frame *frame;
struct input_event *bufp; struct input_event *bufp;
int numchars;
{ {
int nr_events = 0;
if (type == FocusIn) if (type == FocusIn)
{ {
if (dpyinfo->x_focus_event_frame != frame) if (dpyinfo->x_focus_event_frame != frame)
...@@ -3190,17 +3177,12 @@ x_focus_changed (type, state, dpyinfo, frame, bufp, numchars) ...@@ -3190,17 +3177,12 @@ x_focus_changed (type, state, dpyinfo, frame, bufp, numchars)
/* Don't stop displaying the initial startup message /* Don't stop displaying the initial startup message
for a switch-frame event we don't need. */ for a switch-frame event we don't need. */
if (numchars > 0 if (GC_NILP (Vterminal_frame)
&& GC_NILP (Vterminal_frame)
&& GC_CONSP (Vframe_list) && GC_CONSP (Vframe_list)
&& !GC_NILP (XCDR (Vframe_list))) && !GC_NILP (XCDR (Vframe_list)))
{ {
bufp->kind = FOCUS_IN_EVENT; bufp->kind = FOCUS_IN_EVENT;
XSETFRAME (bufp->frame_or_window, frame); XSETFRAME (bufp->frame_or_window, frame);
bufp->arg = Qnil;
++bufp;
numchars--;
++nr_events;
} }
} }
...@@ -3226,27 +3208,25 @@ x_focus_changed (type, state, dpyinfo, frame, bufp, numchars) ...@@ -3226,27 +3208,25 @@ x_focus_changed (type, state, dpyinfo, frame, bufp, numchars)
XUnsetICFocus (FRAME_XIC (frame)); XUnsetICFocus (FRAME_XIC (frame));
#endif #endif
} }
return nr_events;
} }
/* The focus may have changed. Figure out if it is a real focus change, /* The focus may have changed. Figure out if it is a real focus change,
by checking both FocusIn/Out and Enter/LeaveNotify events. by checking both FocusIn/Out and Enter/LeaveNotify events.
Returns number of events inserted into BUFP. */ Returns FOCUS_IN_EVENT event in *BUFP. */
static int static void
x_detect_focus_change (dpyinfo, event, bufp, numchars) x_detect_focus_change (dpyinfo, event, bufp)
struct x_display_info *dpyinfo; struct x_display_info *dpyinfo;
XEvent *event; XEvent *event;
struct input_event *bufp; struct input_event *bufp;
int numchars;
{ {
struct frame *frame; struct frame *frame;
int nr_events = 0; int nr_events = 0;
frame = x_any_window_to_frame (dpyinfo, event->xany.window); frame = x_any_window_to_frame (dpyinfo, event->xany.window);
if (! frame) return nr_events; if (! frame)
return;
switch (event->type) switch (event->type)
{ {
...@@ -3260,29 +3240,20 @@ x_detect_focus_change (dpyinfo, event, bufp, numchars) ...@@ -3260,29 +3240,20 @@ x_detect_focus_change (dpyinfo, event, bufp, numchars)
if (event->xcrossing.detail != NotifyInferior if (event->xcrossing.detail != NotifyInferior
&& event->xcrossing.focus && event->xcrossing.focus
&& ! (focus_state & FOCUS_EXPLICIT)) && ! (focus_state & FOCUS_EXPLICIT))
nr_events = x_focus_changed ((event->type == EnterNotify x_focus_changed ((event->type == EnterNotify ? FocusIn : FocusOut),
? FocusIn : FocusOut), FOCUS_IMPLICIT,
FOCUS_IMPLICIT, dpyinfo, frame, bufp);
dpyinfo,
frame,
bufp,
numchars);
} }
break; break;
case FocusIn: case FocusIn:
case FocusOut: case FocusOut:
nr_events = x_focus_changed (event->type, x_focus_changed (event->type,
(event->xfocus.detail == NotifyPointer (event->xfocus.detail == NotifyPointer ?
? FOCUS_IMPLICIT : FOCUS_EXPLICIT), FOCUS_IMPLICIT : FOCUS_EXPLICIT),
dpyinfo, dpyinfo, frame, bufp);
frame,
bufp,
numchars);
break; break;
} }
return nr_events;
} }
...@@ -3627,35 +3598,39 @@ glyph_rect (f, x, y, rect) ...@@ -3627,35 +3598,39 @@ glyph_rect (f, x, y, rect)
XRectangle *rect; XRectangle *rect;
{ {
Lisp_Object window; Lisp_Object window;
int found = 0; struct window *w;
struct glyph_row *r, *end_row;
window = window_from_coordinates (f, x, y, 0, &x, &y, 0); window = window_from_coordinates (f, x, y, 0, &x, &y, 0);
if (!NILP (window)) if (NILP (window))
{ return 0;
struct window *w = XWINDOW (window);
struct glyph_row *r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
struct glyph_row *end = r + w->current_matrix->nrows - 1;
for (; !found && r < end && r->enabled_p; ++r) w = XWINDOW (window);
if (r->y >= y) r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
{ end_row = r + w->current_matrix->nrows - 1;
struct glyph *g = r->glyphs[TEXT_AREA];
struct glyph *end = g + r->used[TEXT_AREA];
int gx;
for (gx = r->x; !found && g < end; gx += g->pixel_width, ++g) for (; r < end_row && r->enabled_p; ++r)
if (gx >= x) {
{ if (r->y >= y)
rect->width = g->pixel_width; {
rect->height = r->height; struct glyph *g = r->glyphs[TEXT_AREA];
rect->x = WINDOW_TO_FRAME_PIXEL_X (w, gx); struct glyph *end = g + r->used[TEXT_AREA];
rect->y = WINDOW_TO_FRAME_PIXEL_Y (w, r->y); int gx = r->x;
found = 1; while (g < end && gx < x)
} gx += g->pixel_width, ++g;
} if (g < end)
{
rect->width = g->pixel_width;
rect->height = r->height;
rect->x = WINDOW_TO_FRAME_PIXEL_X (w, gx);
rect->y = WINDOW_TO_FRAME_PIXEL_Y (w, r->y);
return 1;
}
break;
}
} }
return found; return 0;
} }
...@@ -5648,6 +5623,11 @@ static XComposeStatus compose_status; ...@@ -5648,6 +5623,11 @@ static XComposeStatus compose_status;
static int temp_index; static int temp_index;
static short temp_buffer[100]; static short temp_buffer[100];
#define STORE_KEYSYM_FOR_DEBUG(keysym) \
if (temp_index == sizeof temp_buffer / sizeof (short)) \
temp_index = 0; \
temp_buffer[temp_index++] = (keysym)
/* Set this to nonzero to fake an "X I/O error" /* Set this to nonzero to fake an "X I/O error"
on a particular display. */ on a particular display. */
...@@ -5667,15 +5647,8 @@ static struct x_display_info *next_noop_dpyinfo; ...@@ -5667,15 +5647,8 @@ static struct x_display_info *next_noop_dpyinfo;
f->output_data.x->saved_menu_event \ f->output_data.x->saved_menu_event \
= (XEvent *) xmalloc (sizeof (XEvent)); \ = (XEvent *) xmalloc (sizeof (XEvent)); \
bcopy (&event, f->output_data.x->saved_menu_event, size); \ bcopy (&event, f->output_data.x->saved_menu_event, size); \
if (numchars >= 1) \ inev.kind = MENU_BAR_ACTIVATE_EVENT; \
{ \ XSETFRAME (inev.frame_or_window, f); \
bufp->kind = MENU_BAR_ACTIVATE_EVENT; \
XSETFRAME (bufp->frame_or_window, f); \
bufp->arg = Qnil; \
bufp++; \
count++; \
numchars--; \
} \
} \ } \
while (0) while (0)
...@@ -5717,14 +5690,13 @@ x_filter_event (dpyinfo, event) ...@@ -5717,14 +5690,13 @@ x_filter_event (dpyinfo, event)
#endif #endif
#ifdef USE_GTK #ifdef USE_GTK
static struct input_event **current_bufp;
static int *current_numcharsp;
static int current_count; static int current_count;
static int current_finish; static int current_finish;
static struct input_event *current_hold_quit;
/* This is the filter function invoked by the GTK event loop. /* This is the filter function invoked by the GTK event loop.
It is invoked before the XEvent is translated to a GdkEvent, It is invoked before the XEvent is translated to a GdkEvent,
so we have a chanse to act on the event before GTK. */ so we have a chance to act on the event before GTK. */
static GdkFilterReturn static GdkFilterReturn
event_handler_gdk (gxev, ev, data) event_handler_gdk (gxev, ev, data)
GdkXEvent *gxev; GdkXEvent *gxev;
...@@ -5733,7 +5705,7 @@ event_handler_gdk (gxev, ev, data) ...@@ -5733,7 +5705,7 @@ event_handler_gdk (gxev, ev, data)
{ {
XEvent *xev = (XEvent *) gxev; XEvent *xev = (XEvent *) gxev;
if (current_numcharsp) if (current_count >= 0)
{ {
struct x_display_info *dpyinfo; struct x_display_info *dpyinfo;
...@@ -5751,11 +5723,11 @@ event_handler_gdk (gxev, ev, data) ...@@ -5751,11 +5723,11 @@ event_handler_gdk (gxev, ev, data)
if (! dpyinfo) if (! dpyinfo)
current_finish = X_EVENT_NORMAL; current_finish = X_EVENT_NORMAL;
else else
current_count += handle_one_xevent (dpyinfo, {
xev, current_count +=
current_bufp, handle_one_xevent (dpyinfo, xev, &current_finish,
current_numcharsp, current_hold_quit);
&current_finish); }
} }
else else
current_finish = x_dispatch_event (xev, xev->xany.display); current_finish = x_dispatch_event (xev, xev->xany.display);
...@@ -5774,28 +5746,29 @@ event_handler_gdk (gxev, ev, data) ...@@ -5774,28 +5746,29 @@ event_handler_gdk (gxev, ev, data)
*FINISH is zero if caller should continue reading events. *FINISH is zero if caller should continue reading events.
*FINISH is X_EVENT_DROP if event should not be passed to the toolkit. *FINISH is X_EVENT_DROP if event should not be passed to the toolkit.
Events representing keys are stored in buffer *BUFP_R,
which can hold up to *NUMCHARSP characters.
We return the number of characters stored into the buffer. */ We return the number of characters stored into the buffer. */
static int static int
handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish) handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
struct x_display_info *dpyinfo; struct x_display_info *dpyinfo;
XEvent *eventp; XEvent *eventp;
/* register */ struct input_event **bufp_r;
/* register */ int *numcharsp;
int *finish; int *finish;
struct input_event *hold_quit;
{ {
struct input_event inev;
int count = 0; int count = 0;
int do_help = 0;
int nbytes = 0; int nbytes = 0;
struct frame *f; struct frame *f;
struct coding_system coding; struct coding_system coding;
struct input_event *bufp = *bufp_r;
int numchars = *numcharsp;
XEvent event = *eventp; XEvent event = *eventp;
*finish = X_EVENT_NORMAL; *finish = X_EVENT_NORMAL;
EVENT_INIT (inev);
inev.kind = NO_EVENT;
inev.arg = Qnil;
switch (event.type) switch (event.type)
{ {
case ClientMessage: case ClientMessage:
...@@ -5850,8 +5823,10 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish) ...@@ -5850,8 +5823,10 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
} }
/* Not certain about handling scroll bars here */ /* Not certain about handling scroll bars here */
#endif /* 0 */ #endif /* 0 */
goto done;
} }
else if (event.xclient.data.l[0]
if (event.xclient.data.l[0]
== dpyinfo->Xatom_wm_save_yourself) == dpyinfo->Xatom_wm_save_yourself)
{ {
/* Save state modify the WM_COMMAND property to /* Save state modify the WM_COMMAND property to
...@@ -5862,11 +5837,9 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish) ...@@ -5862,11 +5837,9 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
/* If we have a session manager, don't set this. /* If we have a session manager, don't set this.
KDE will then start two Emacsen, one for the KDE will then start two Emacsen, one for the
session manager and one for this. */ session manager and one for this. */
if (numchars > 0
#ifdef HAVE_X_SM #ifdef HAVE_X_SM
&& ! x_session_have_connection () if (! x_session_have_connection ())
#endif #endif
)
{ {
f = x_top_window_to_frame (dpyinfo, f = x_top_window_to_frame (dpyinfo,
event.xclient.window); event.xclient.window);
...@@ -5881,41 +5854,36 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish) ...@@ -5881,41 +5854,36 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
event.xclient.window, event.xclient.window,
0, 0); 0, 0);
} }
goto done;
} }
else if (event.xclient.data.l[0]
== dpyinfo->Xatom_wm_delete_window) if (event.xclient.data.l[0]
== dpyinfo->Xatom_wm_delete_window)
{ {
struct frame *f f = x_any_window_to_frame (dpyinfo,
= x_any_window_to_frame (dpyinfo,
event.xclient.window); event.xclient.window);
if (!f)
goto OTHER; /* May be a dialog that is to be removed */
if (f) inev.kind = DELETE_WINDOW_EVENT;
{ XSETFRAME (inev.frame_or_window, f);
if (numchars == 0) goto done;
abort ();
bufp->kind = DELETE_WINDOW_EVENT;
XSETFRAME (bufp->frame_or_window, f);
bufp->arg = Qnil;
bufp++;
count += 1;
numchars -= 1;
}
else
goto OTHER; /* May be a dialog that is to be removed */
} }
goto done;
} }
else if (event.xclient.message_type
if (event.xclient.message_type
== dpyinfo->Xatom_wm_configure_denied) == dpyinfo->Xatom_wm_configure_denied)
{ {
goto done;
} }
else if (event.xclient.message_type
== dpyinfo->Xatom_wm_window_moved) if (event.xclient.message_type
== dpyinfo->Xatom_wm_window_moved)
{ {
int new_x, new_y; int new_x, new_y;
struct frame *f f = x_window_to_frame (dpyinfo, event.xclient.window);
= x_window_to_frame (dpyinfo, event.xclient.window);
new_x = event.xclient.data.s[0]; new_x = event.xclient.data.s[0];
new_y = event.xclient.data.s[1]; new_y = event.xclient.data.s[1];
...@@ -5925,63 +5893,55 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish) ...@@ -5925,63 +5893,55 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
f->left_pos = new_x; f->left_pos = new_x;
f->top_pos = new_y; f->top_pos = new_y;
} }
goto done;
} }
#ifdef HACK_EDITRES #ifdef HACK_EDITRES
else if (event.xclient.message_type if (event.xclient.message_type
== dpyinfo->Xatom_editres) == dpyinfo->Xatom_editres)
{ {
struct frame *f f = x_any_window_to_frame (dpyinfo, event.xclient.window);
= x_any_window_to_frame (dpyinfo, event.xclient.window);
_XEditResCheckMessages (f->output_data.x->widget, NULL, _XEditResCheckMessages (f->output_data.x->widget, NULL,
&event, NULL); &event, NULL);
goto done;
} }
#endif /* HACK_EDITRES */ #endif /* HACK_EDITRES */
else if ((event.xclient.message_type
== dpyinfo->Xatom_DONE) if ((event.xclient.message_type
|| (event.xclient.message_type == dpyinfo->Xatom_DONE)
== dpyinfo->Xatom_PAGE)) || (event.xclient.message_type
== dpyinfo->Xatom_PAGE))
{ {
/* Ghostview job completed. Kill it. We could /* Ghostview job completed. Kill it. We could
reply with "Next" if we received "Page", but we reply with "Next" if we received "Page", but we
currently never do because we are interested in currently never do because we are interested in
images, only, which should have 1 page. */ images, only, which should have 1 page. */
Pixmap pixmap = (Pixmap) event.xclient.data.l[1]; Pixmap pixmap = (Pixmap) event.xclient.data.l[1];
struct frame *f f = x_window_to_frame (dpyinfo, event.xclient.window);
= x_window_to_frame (dpyinfo, event.xclient.window);
x_kill_gs_process (pixmap, f); x_kill_gs_process (pixmap, f);
expose_frame (f, 0, 0, 0, 0); expose_frame (f, 0, 0, 0, 0);
goto done;
} }
#ifdef USE_TOOLKIT_SCROLL_BARS #ifdef USE_TOOLKIT_SCROLL_BARS
/* Scroll bar callbacks send a ClientMessage from which /* Scroll bar callbacks send a ClientMessage from which
we construct an input_event. */ we construct an input_event. */
else if (event.xclient.message_type if (event.xclient.message_type
== dpyinfo->Xatom_Scrollbar) == dpyinfo->Xatom_Scrollbar)
{ {
x_scroll_bar_to_input_event (&event, bufp); x_scroll_bar_to_input_event (&event, &inev);
++bufp, ++count, --numchars; *finish = X_EVENT_GOTO_OUT;
goto out; goto done;
} }
#endif /* USE_TOOLKIT_SCROLL_BARS */ #endif /* USE_TOOLKIT_SCROLL_BARS */
else
{
struct frame *f
= x_any_window_to_frame (dpyinfo, event.xclient.window);
if (f) f = x_any_window_to_frame (dpyinfo, event.xclient.window);
{
int ret = x_handle_dnd_message (f, &event.xclient,
dpyinfo, bufp);
if (ret > 0)
{
++bufp, ++count, --numchars;
}
if (ret != 0) if (!f)
*finish = X_EVENT_DROP; goto OTHER;
}
else if (x_handle_dnd_message (f, &event.xclient, dpyinfo, &inev))
goto OTHER; *finish = X_EVENT_DROP;
}
} }
break; break;
...@@ -6001,19 +5961,11 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish) ...@@ -6001,19 +5961,11 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
{ {
XSelectionClearEvent *eventp = (XSelectionClearEvent *) &event; XSelectionClearEvent *eventp = (XSelectionClearEvent *) &event;
if (numchars == 0) inev.kind = SELECTION_CLEAR_EVENT;
abort (); SELECTION_EVENT_DISPLAY (&inev) = eventp->display;
SELECTION_EVENT_SELECTION (&inev) = eventp->selection;
bufp->kind = SELECTION_CLEAR_EVENT; SELECTION_EVENT_TIME (&inev) = eventp->time;
SELECTION_EVENT_DISPLAY (bufp) = eventp->display; inev.frame_or_window = Qnil;
SELECTION_EVENT_SELECTION (bufp) = eventp->selection;
SELECTION_EVENT_TIME (bufp) = eventp->time;
bufp->frame_or_window = Qnil;
bufp->arg = Qnil;
bufp++;
count += 1;
numchars -= 1;
} }
break; break;
...@@ -6030,22 +5982,14 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish) ...@@ -6030,22 +5982,14 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
XSelectionRequestEvent *eventp XSelectionRequestEvent *eventp
= (XSelectionRequestEvent *) &event; = (XSelectionRequestEvent *) &event;
if (numchars == 0) inev.kind = SELECTION_REQUEST_EVENT;
abort (); SELECTION_EVENT_DISPLAY (&inev) = eventp->display;
SELECTION_EVENT_REQUESTOR (&inev) = eventp->requestor;
bufp->kind = SELECTION_REQUEST_EVENT; SELECTION_EVENT_SELECTION (&inev) = eventp->selection;
SELECTION_EVENT_DISPLAY (bufp) = eventp->display; SELECTION_EVENT_TARGET (&inev) = eventp->target;