[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