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 <[email protected]>
---
 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

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to