[PATCH 2/3] Make XSendEvent handle GenericEvents >32bytes
carlosg at gnome.org
carlosg at gnome.org
Fri Nov 26 14:59:28 PST 2010
From: Carlos Garnacho <carlosg at gnome.org>
If the event is a GenericEvent, XSendEvent() will use
xGESendEventReq to send it to the server, otherwise the
old code path is still used.
XGE-based extensions will need to implement a handler for
XESetEventCookieToWire() in order to have XSendEvent work
with its events.
Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
---
src/SendEvent.c | 105 +++++++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 83 insertions(+), 22 deletions(-)
diff --git a/src/SendEvent.c b/src/SendEvent.c
index cc8bd5a..67b1b05 100644
--- a/src/SendEvent.c
+++ b/src/SendEvent.c
@@ -27,6 +27,7 @@ in this Software without prior written authorization from The Open Group.
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+#include <X11/extensions/geproto.h>
#include "Xlibint.h"
/*
@@ -41,38 +42,98 @@ XSendEvent(
long event_mask,
XEvent *event)
{
- register xSendEventReq *req;
- xEvent ev;
- register Status (**fp)(
- Display * /* dpy */,
- XEvent * /* re */,
- xEvent * /* event */);
Status status;
- /* initialize all of the event's fields first, before setting
- * the meaningful ones later.
- */
- memset (&ev, 0, sizeof (ev));
-
LockDisplay (dpy);
/* call through display to find proper conversion routine */
- fp = &dpy->wire_vec[event->type & 0177];
- if (*fp == NULL) *fp = _XEventToWire;
- status = (**fp)(dpy, event, &ev);
+ if (event->type == GenericEvent) {
+ static Bool ext_initialized = False;
+ static _XExtension *ext = NULL;
+ XGenericEventCookie *xcookie = (XGenericEventCookie *) event;
+ xGenericEvent *ev = NULL;
+ register Status (**fp)(
+ Display * /* dpy */,
+ XGenericEventCookie* /* re */,
+ xGenericEvent ** /* event */);
+
+ if (!ext_initialized) {
+ for (ext = dpy->ext_procs; ext; ext = ext->next) {
+ if (ext->name && strcmp (ext->name, GE_NAME) == 0)
+ break;
+ }
+
+ ext_initialized = True;
+ }
+
+ /* No XGE */
+ if (!ext)
+ return BadRequest;
+
+ fp = &dpy->generic_wire_vec[xcookie->extension & 0x7F];
+
+ if (!fp || !*fp)
+ return BadRequest;
+
+ status = (**fp)(dpy, xcookie, &ev);
+
+ if (status && ev) {
+ register xGESendEventReq *req;
+ register long len;
+
+ GetReq (GESendEvent, req);
+
+ req->reqType = ext->codes.major_opcode;
+ req->ReqType = X_GESendEvent;
+ req->destination = w;
+ req->propagate = propagate;
+ req->eventMask = event_mask;
+
+ len = ev->length;
+ len += SIZEOF (xEvent) >> 2;
+
+ if (dpy->bigreq_size || req->length + len <= (unsigned) 65535) {
+ SetReqLen(req, len, len);
+ Data (dpy, (char *)ev, len << 2);
+ } else {
+ XFree(ev);
+ return BadLength;
+ }
+ }
+
+ if (ev)
+ XFree(ev);
+ } else {
+ xEvent ev;
+ register Status (**fp)(
+ Display * /* dpy */,
+ XEvent * /* re */,
+ xEvent * /* event */);
+
+ /* initialize all of the event's fields first, before setting
+ * the meaningful ones later.
+ */
+ memset (&ev, 0, sizeof (ev));
+
+ fp = &dpy->wire_vec[event->type & 0177];
+ if (*fp == NULL) *fp = _XEventToWire;
+ status = (**fp)(dpy, event, &ev);
+
+ if (status) {
+ register xSendEventReq *req;
- if (status) {
- GetReq(SendEvent, req);
- req->destination = w;
- req->propagate = propagate;
- req->eventMask = event_mask;
+ GetReq(SendEvent, req);
+ req->destination = w;
+ req->propagate = propagate;
+ req->eventMask = event_mask;
#ifdef WORD64
- /* avoid quad-alignment problems */
- memcpy ((char *) req->eventdata, (char *) &ev, SIZEOF(xEvent));
+ /* avoid quad-alignment problems */
+ memcpy ((char *) req->eventdata, (char *) &ev, SIZEOF(xEvent));
#else
- req->event = ev;
+ req->event = ev;
#endif /* WORD64 */
+ }
}
UnlockDisplay(dpy);
--
1.7.3.2
More information about the xorg-devel
mailing list