From: Carlos Garnacho <carl...@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 <carl...@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 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel