[PATCH libX11 4/5] Make XSendEvent able to send GenericEvents >32byte

Carlos Garnacho carlosg at gnome.org
Fri Sep 24 11:57:09 PDT 2010


As GenericEvents are part of the core protocol, make XSendEvent() able to deal with GenericEvents by using the xGESendEventReq request available in the Xge protocol. It also uses the handler registered through XESetEventCookieToWire() to convert events from extensions to the wire protocol.

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.0.4



More information about the xorg-devel mailing list