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
