From a14a0c711397ff7ca0220946010300fc1b2a6e67 Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Fri, 22 Apr 2011 22:19:39 -0700 Subject: [PATCH 01/28] Move event filter initializer out of the structure itself When kept in the structure, it causes the entire MAXDEVICES * 128 masks to be stored in the data segment and loaded from the file, and also leads to worries about later generations inheriting changes across server reset. text data bss dec hex filename Before: 91837 20528 32 112397 1b70d .libs/events.o After: 92277 48 20512 112837 1b8c5 .libs/events.o Before: 3013384 122696 163156 3299236 3257a4 Xorg After: 3013832 102216 183636 3299684 325964 Xorg File size before: 4337008 Xorg File size after: 4316568 Xorg Signed-off-by: Alan Coopersmith Reviewed-by: Jamey Sharp Reviewed-by: Jeremy Huddleston Reviewed-by: Daniel Stone --- dix/events.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/dix/events.c b/dix/events.c index d70d62fd8..1d513eb10 100644 --- a/dix/events.c +++ b/dix/events.c @@ -345,8 +345,8 @@ extern int DeviceMotionNotify; /** * Event masks for each event type. * - * One set of filters for each device, but only the first layer - * is initialized. The rest is memcpy'd in InitEvents. + * One set of filters for each device, initialized by memcpy of + * default_filter in InitEvents. * * Filters are used whether a given event may be delivered to a client, * usually in the form of if (window-event-mask & filter); then deliver event. @@ -355,7 +355,9 @@ extern int DeviceMotionNotify; * time a button is pressed, the filter is modified to also contain the * matching ButtonXMotion mask. */ -static Mask filters[MAXDEVICES][128] = { +static Mask filters[MAXDEVICES][128]; + +static const Mask default_filter[128] = { NoSuchEvent, /* 0 */ NoSuchEvent, /* 1 */ @@ -392,7 +394,7 @@ static Mask filters[MAXDEVICES][128] = { ColormapChangeMask, /* ColormapNotify */ CantBeFiltered, /* ClientMessage */ CantBeFiltered /* MappingNotify */ -}}; +}; /** * For the given event, return the matching event filter. This filter may then @@ -4977,12 +4979,9 @@ InitEvents(void) inputInfo.off_devices = (DeviceIntPtr)NULL; inputInfo.keyboard = (DeviceIntPtr)NULL; inputInfo.pointer = (DeviceIntPtr)NULL; - /* The mask for pointer motion events may have changed in the last server - * generation. See comment above definition of filters. */ - filters[0][PointerMotionMask] = MotionNotify; - for (i = 1; i < MAXDEVICES; i++) + for (i = 0; i < MAXDEVICES; i++) { - memcpy(&filters[i], filters[0], sizeof(filters[0])); + memcpy(&filters[i], default_filter, sizeof(default_filter)); } syncEvents.replayDev = (DeviceIntPtr)NULL; From 65b54548dce80c8e8ff5ff91fc4f0659e9b2d921 Mon Sep 17 00:00:00 2001 From: Chase Douglas Date: Tue, 18 Jan 2011 20:08:09 +0000 Subject: [PATCH 02/28] Input: Pass co-ordinates by reference to transformAbsolute With the upcoming XI 2.1 touch work, the co-ordinate values will need to be passed by reference, rather than modified in-place. Signed-off-by: Chase Douglas Reviewed-by: Daniel Stone --- dix/getevents.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/dix/getevents.c b/dix/getevents.c index 4267b61cb..5ffa1df92 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -1051,23 +1051,14 @@ FreeEventList(EventListPtr list, int num_events) } static void -transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask) +transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask, int *x, int *y) { - struct pixman_f_vector p; - - /* p' = M * p in homogeneous coordinates */ - p.v[0] = (valuator_mask_isset(mask, 0) ? valuator_mask_get(mask, 0) : - dev->last.valuators[0]); - p.v[1] = (valuator_mask_isset(mask, 1) ? valuator_mask_get(mask, 1) : - dev->last.valuators[1]); - p.v[2] = 1.0; + struct pixman_f_vector p = {.v = {*x, *y, 1}}; pixman_f_transform_point(&dev->transform, &p); - if (lround(p.v[0]) != dev->last.valuators[0]) - valuator_mask_set(mask, 0, lround(p.v[0])); - if (lround(p.v[1]) != dev->last.valuators[1]) - valuator_mask_set(mask, 1, lround(p.v[1])); + *x = lround(p.v[0]); + *y = lround(p.v[1]); } /** @@ -1158,7 +1149,16 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons, } } - transformAbsolute(pDev, &mask); + x = (valuator_mask_isset(&mask, 0) ? valuator_mask_get(&mask, 0) : + pDev->last.valuators[0]); + y = (valuator_mask_isset(&mask, 1) ? valuator_mask_get(&mask, 1) : + pDev->last.valuators[1]); + transformAbsolute(pDev, &mask, &x, &y); + if (valuator_mask_isset(&mask, 0)) + valuator_mask_set(&mask, 0, x); + if (valuator_mask_isset(&mask, 1)) + valuator_mask_set(&mask, 1, y); + moveAbsolute(pDev, &x, &y, &mask); } else { if (flags & POINTER_ACCELERATE) { From 706326491011be8cecb9b56c06f7241b7cbd425f Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 18 Jan 2011 20:16:36 +0000 Subject: [PATCH 03/28] Input: Add DeepestSpriteWin function Does what it says on the box: returns the deepest child window in a given sprite's trace. Signed-off-by: Daniel Stone Reviewed-by: Chase Douglas Reviewed-by: Keith Packard --- dix/events.c | 4 ++-- include/inputstr.h | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/dix/events.c b/dix/events.c index 1d513eb10..4a2815b0f 100644 --- a/dix/events.c +++ b/dix/events.c @@ -2182,7 +2182,7 @@ MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents, static Window FindChildForEvent(SpritePtr pSprite, WindowPtr event) { - WindowPtr w = pSprite->spriteTrace[pSprite->spriteTraceGood-1]; + WindowPtr w = DeepestSpriteWin(pSprite); Window child = None; /* If the search ends up past the root should the child field be @@ -2625,7 +2625,7 @@ XYToWindow(SpritePtr pSprite, int x, int y) else pWin = pWin->nextSib; } - return pSprite->spriteTrace[pSprite->spriteTraceGood-1]; + return DeepestSpriteWin(pSprite); } /** diff --git a/include/inputstr.h b/include/inputstr.h index bd7c78dec..bc0accc87 100644 --- a/include/inputstr.h +++ b/include/inputstr.h @@ -591,4 +591,14 @@ typedef struct _EventSyncInfo { extern EventSyncInfoRec syncEvents; +/** + * Given a sprite, returns the window at the bottom of the trace (i.e. the + * furthest window from the root). + */ +static inline WindowPtr DeepestSpriteWin(SpritePtr sprite) +{ + assert(sprite->spriteTraceGood > 0); + return sprite->spriteTrace[sprite->spriteTraceGood - 1]; +} + #endif /* INPUTSTRUCT_H */ From 73de54210446e9eca81b96ea6775ee5ea1a31d75 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Mon, 24 Jan 2011 08:40:10 +1000 Subject: [PATCH 04/28] Input: Fix event size confusion in CheckPassiveGrabsOnWindow We were just storing a DeviceEvent, but allocating enough space for an InternalEvent. Signed-off-by: Daniel Stone Reviewed-by: Julien Cristau Reviewed-by: Adam Jackson Reviewed-by: Cyril Brulebois --- dix/events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dix/events.c b/dix/events.c index 4a2815b0f..bc08f7b54 100644 --- a/dix/events.c +++ b/dix/events.c @@ -3565,7 +3565,7 @@ CheckPassiveGrabsOnWindow( if (grabinfo->sync.state == FROZEN_NO_EVENT) { if (!grabinfo->sync.event) - grabinfo->sync.event = calloc(1, sizeof(InternalEvent)); + grabinfo->sync.event = calloc(1, sizeof(DeviceEvent)); *grabinfo->sync.event = *event; grabinfo->sync.state = FROZEN_WITH_EVENT; } From bf2059b07a97e5e579c13c2c9d49707093427dc2 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 15 Apr 2011 14:06:20 +1000 Subject: [PATCH 05/28] input: Only release SD buttons for explicit floating/reattachment (#36146) Grabbing an SD device temporary floats the device but we must not release the buttons. Introduced in commit 9d23459415b84606ee4f38bb2d19054c432c8552 Author: Peter Hutterer Date: Fri Feb 25 11:08:19 2011 +1000 dix: release all buttons and keys before reattaching a device (#34182) X.Org Bug 36146 Signed-off-by: Peter Hutterer Reviewed-by: Jeremy Huddleston --- Xi/xichangehierarchy.c | 2 ++ dix/devices.c | 4 +--- include/input.h | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c index 0736a5a36..96ead6fcd 100644 --- a/Xi/xichangehierarchy.c +++ b/Xi/xichangehierarchy.c @@ -355,6 +355,7 @@ detach_slave(ClientPtr client, xXIDetachSlaveInfo *c, int flags[MAXDEVICES]) goto unwind; } + ReleaseButtonsAndKeys(dev); AttachDevice(client, dev, NULL); flags[dev->id] |= XISlaveDetached; @@ -406,6 +407,7 @@ attach_slave(ClientPtr client, xXIAttachSlaveInfo *c, goto unwind; } + ReleaseButtonsAndKeys(dev); AttachDevice(client, dev, newmaster); flags[dev->id] |= XISlaveAttached; diff --git a/dix/devices.c b/dix/devices.c index 3f46ad6fb..7968c7357 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -2365,7 +2365,7 @@ RecalculateMasterButtons(DeviceIntPtr slave) * Generate release events for all keys/button currently down on this * device. */ -static void +void ReleaseButtonsAndKeys(DeviceIntPtr dev) { EventListPtr eventlist = InitEventList(GetMaximumEventsNum()); @@ -2434,8 +2434,6 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) free(dev->spriteInfo->sprite); } - ReleaseButtonsAndKeys(dev); - oldmaster = GetMaster(dev, MASTER_ATTACHED); dev->master = master; diff --git a/include/input.h b/include/input.h index 86078daee..6799a53dd 100644 --- a/include/input.h +++ b/include/input.h @@ -495,6 +495,8 @@ extern _X_EXPORT int GetMotionHistory( ScreenPtr pScreen, BOOL core); +extern void ReleaseButtonsAndKeys(DeviceIntPtr dev); + extern int AttachDevice(ClientPtr client, DeviceIntPtr slave, DeviceIntPtr master); From 56901998020b6f443cbaa5eb303100d979e81b22 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 5 May 2011 08:48:19 +1000 Subject: [PATCH 06/28] input: change CHECKEVENT macro to verify_internal_event function The macro is sufficient if called during a development cycle, but not sufficient information when triggered by a user (e.g. https://bugzilla.redhat.com/show_bug.cgi?id=688693). Expand what this does to print the event content and a backtrace, so at least we know where we're coming from. Only the first 32 bytes are printed since if something goes wrong, the event we have is almost certainly an xEvent or xError, both restricted to 32 bytes. Signed-off-by: Peter Hutterer Reviewed-by: Daniel Stone --- Xi/exevents.c | 3 ++- dix/events.c | 4 ++-- dix/inpututils.c | 28 ++++++++++++++++++++++++++++ include/eventstr.h | 4 ---- include/inpututils.h | 2 ++ mi/mieq.c | 10 +++++----- 6 files changed, 39 insertions(+), 12 deletions(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index 76d5c3759..d48d397cf 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -77,6 +77,7 @@ SOFTWARE. #include "xiquerydevice.h" /* For List*Info */ #include "eventconvert.h" #include "eventstr.h" +#include "inpututils.h" #include #include "xkbsrv.h" @@ -920,7 +921,7 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device) DeviceIntPtr mouse = NULL, kbd = NULL; DeviceEvent *event = &ev->device_event; - CHECKEVENT(ev); + verify_internal_event(ev); if (ev->any.type == ET_RawKeyPress || ev->any.type == ET_RawKeyRelease || diff --git a/dix/events.c b/dix/events.c index bc08f7b54..b0107a081 100644 --- a/dix/events.c +++ b/dix/events.c @@ -2377,7 +2377,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab, xEvent *xE = NULL, *core = NULL; int rc, mask, count = 0; - CHECKEVENT(event); + verify_internal_event(event); while (pWin) { @@ -2723,7 +2723,7 @@ CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev) WindowPtr prevSpriteWin, newSpriteWin; SpritePtr pSprite = pDev->spriteInfo->sprite; - CHECKEVENT(ev); + verify_internal_event(ev); prevSpriteWin = pSprite->win; diff --git a/dix/inpututils.c b/dix/inpututils.c index 077ffce01..aeace6ef8 100644 --- a/dix/inpututils.c +++ b/dix/inpututils.c @@ -36,6 +36,7 @@ #include "xkbsrv.h" #include "xkbstr.h" #include "inpututils.h" +#include "eventstr.h" /* Check if a button map change is okay with the device. * Returns -1 for BadValue, as it collides with MappingBusy. */ @@ -556,3 +557,30 @@ CountBits(const uint8_t *mask, int len) return ret; } + +/** + * Verifies sanity of the event. If the event is not an internal event, + * memdumps the first 32 bytes of event to the log, a backtrace, then kill + * the server. + */ +void verify_internal_event(const InternalEvent *ev) +{ + if (ev && ev->any.header != ET_Internal) + { + int i; + unsigned char *data = (unsigned char*)ev; + + ErrorF("dix: invalid event type %d\n", ev->any.header); + + for (i = 0; i < sizeof(xEvent); i++, data++) + { + ErrorF("%02hx ", *data); + + if ((i % 8) == 7) + ErrorF("\n"); + } + + xorg_backtrace(); + FatalError("Wrong event type %d. Aborting server\n", ev->any.header); + } +} diff --git a/include/eventstr.h b/include/eventstr.h index 673207ce3..049688ca0 100644 --- a/include/eventstr.h +++ b/include/eventstr.h @@ -68,10 +68,6 @@ enum EventType { ET_Internal = 0xFF /* First byte */ }; -#define CHECKEVENT(ev) if (ev && ((InternalEvent*)(ev))->any.header != 0xFF) \ - FatalError("Wrong event type %d.\n", \ - ((InternalEvent*)(ev))->any.header); - /** * Used for ALL input device events internal in the server until * copied into the matching protocol event. diff --git a/include/inpututils.h b/include/inpututils.h index b8ca6abfc..92a754327 100644 --- a/include/inpututils.h +++ b/include/inpututils.h @@ -37,4 +37,6 @@ struct _ValuatorMask { int valuators[MAX_VALUATORS]; /* valuator data */ }; +extern void verify_internal_event(const InternalEvent *ev); + #endif diff --git a/mi/mieq.c b/mi/mieq.c index 08a0c8758..3e6f93110 100644 --- a/mi/mieq.c +++ b/mi/mieq.c @@ -156,7 +156,7 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e) pthread_mutex_lock(&miEventQueueMutex); #endif - CHECKEVENT(e); + verify_internal_event(e); /* avoid merging events from different devices */ if (e->any.type == ET_Motion) @@ -292,8 +292,8 @@ static void FixUpEventForMaster(DeviceIntPtr mdev, DeviceIntPtr sdev, InternalEvent* original, InternalEvent *master) { - CHECKEVENT(original); - CHECKEVENT(master); + verify_internal_event(original); + verify_internal_event(master); /* Ensure chained button mappings, i.e. that the detail field is the * value of the mapped button on the SD, not the physical button */ if (original->any.type == ET_ButtonPress || @@ -323,7 +323,7 @@ CopyGetMasterEvent(DeviceIntPtr sdev, int type = original->any.type; int mtype; /* which master type? */ - CHECKEVENT(original); + verify_internal_event(original); /* ET_XQuartz has sdev == NULL */ if (!sdev || IsMaster(sdev) || IsFloating(sdev)) @@ -376,7 +376,7 @@ mieqProcessDeviceEvent(DeviceIntPtr dev, DeviceIntPtr master; InternalEvent mevent; /* master event */ - CHECKEVENT(event); + verify_internal_event(event); /* Custom event handler */ handler = miEventQueue.handlers[event->any.type]; From 00ba884556c675b2b25e116f5ab4eb4590b6dd56 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Wed, 19 Jan 2011 20:38:44 +0000 Subject: [PATCH 07/28] Input: Make CheckPassiveGrabsOnWindow take InternalEvent Previously, it only took DeviceEvents, but it would be much more useful if it took InternalEvents. Any event that activates a grab must still be a DeviceEvent, so put in a check to enforce this. Change all callers to make the appropriate casts. Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer --- dix/events.c | 72 ++++++++++++++++++++++++++++++++++++++------------- include/dix.h | 2 +- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/dix/events.c b/dix/events.c index b0107a081..17194b181 100644 --- a/dix/events.c +++ b/dix/events.c @@ -2663,7 +2663,8 @@ ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win) event.deviceid = dev->id; event.sourceid = dev->id; event.detail.button = 0; - rc = (CheckPassiveGrabsOnWindow(win, dev, &event, FALSE, TRUE) != NULL); + rc = (CheckPassiveGrabsOnWindow(win, dev, (InternalEvent *) &event, FALSE, + TRUE) != NULL); if (rc) DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveUngrab); return rc; @@ -2700,7 +2701,8 @@ ActivateEnterGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win) event.deviceid = dev->id; event.sourceid = dev->id; event.detail.button = 0; - rc = (CheckPassiveGrabsOnWindow(win, dev, &event, FALSE, TRUE) != NULL); + rc = (CheckPassiveGrabsOnWindow(win, dev, (InternalEvent *) &event, FALSE, + TRUE) != NULL); if (rc) DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveGrab); return rc; @@ -3387,7 +3389,7 @@ GrabPtr CheckPassiveGrabsOnWindow( WindowPtr pWin, DeviceIntPtr device, - DeviceEvent *event, + InternalEvent *event, BOOL checkCore, BOOL activate) { @@ -3404,9 +3406,22 @@ CheckPassiveGrabsOnWindow( return NULL; /* Fill out the grab details, but leave the type for later before * comparing */ + switch (event->any.type) + { + case ET_KeyPress: + case ET_KeyRelease: + tempGrab.detail.exact = event->device_event.detail.key; + break; + case ET_ButtonPress: + case ET_ButtonRelease: + tempGrab.detail.exact = event->device_event.detail.button; + break; + default: + tempGrab.detail.exact = 0; + break; + } tempGrab.window = pWin; tempGrab.device = device; - tempGrab.detail.exact = event->detail.key; tempGrab.detail.pMask = NULL; tempGrab.modifiersDetail.pMask = NULL; tempGrab.next = NULL; @@ -3414,6 +3429,8 @@ CheckPassiveGrabsOnWindow( { DeviceIntPtr gdev; XkbSrvInfoPtr xkbi = NULL; + xEvent *xE = NULL; + xEvent core; gdev= grab->modifierDevice; if (grab->grabtype == GRABTYPE_CORE) @@ -3439,16 +3456,15 @@ CheckPassiveGrabsOnWindow( tempGrab.modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0; /* Check for XI2 and XI grabs first */ - tempGrab.type = GetXI2Type((InternalEvent*)event); + tempGrab.type = GetXI2Type(event); tempGrab.grabtype = GRABTYPE_XI2; if (GrabMatchesSecond(&tempGrab, grab, FALSE)) match = XI2_MATCH; - tempGrab.detail.exact = event->detail.key; if (!match) { tempGrab.grabtype = GRABTYPE_XI; - if ((tempGrab.type = GetXIType((InternalEvent*)event)) && + if ((tempGrab.type = GetXIType(event)) && (GrabMatchesSecond(&tempGrab, grab, FALSE))) match = XI_MATCH; } @@ -3457,7 +3473,7 @@ CheckPassiveGrabsOnWindow( if (!match && checkCore) { tempGrab.grabtype = GRABTYPE_CORE; - if ((tempGrab.type = GetCoreType((InternalEvent*)event)) && + if ((tempGrab.type = GetCoreType(event)) && (GrabMatchesSecond(&tempGrab, grab, TRUE))) match = CORE_MATCH; } @@ -3469,8 +3485,6 @@ CheckPassiveGrabsOnWindow( int rc, count = 0; xEvent *xE = NULL; - event->corestate &= 0x1f00; - event->corestate |= tempGrab.modifiersDetail.exact & (~0x1f00); grabinfo = &device->deviceGrab; /* In some cases a passive core grab may exist, but the client * already has a core grab on some other device. In this case we @@ -3515,7 +3529,24 @@ CheckPassiveGrabsOnWindow( } if (!activate) + { return grab; + } + else if (!GetXIType(event) && !GetCoreType(event)) + { + ErrorF("Event type %d in CheckPassiveGrabsOnWindow is" + " neither XI 1.x nor core\n", event->any.type); + return NULL; + } + + /* The only consumers of corestate are Xi 1.x and core events, + * which are guaranteed to come from DeviceEvents. */ + if (match & (XI_MATCH | CORE_MATCH)) + { + event->device_event.corestate &= 0x1f00; + event->device_event.corestate |= + tempGrab.modifiersDetail.exact & (~0x1f00); + } if (match & CORE_MATCH) { @@ -3524,28 +3555,31 @@ CheckPassiveGrabsOnWindow( { if (rc != BadMatch) ErrorF("[dix] %s: core conversion failed in CPGFW " - "(%d, %d).\n", device->name, event->type, rc); + "(%d, %d).\n", device->name, event->any.type, + rc); continue; } } else if (match & XI2_MATCH) { - rc = EventToXI2((InternalEvent*)event, &xE); + rc = EventToXI2(event, &xE); if (rc != Success) { if (rc != BadMatch) ErrorF("[dix] %s: XI2 conversion failed in CPGFW " - "(%d, %d).\n", device->name, event->type, rc); + "(%d, %d).\n", device->name, event->any.type, + rc); continue; } count = 1; } else { - rc = EventToXI((InternalEvent*)event, &xE, &count); + rc = EventToXI(event, &xE, &count); if (rc != Success) { if (rc != BadMatch) ErrorF("[dix] %s: XI conversion failed in CPGFW " - "(%d, %d).\n", device->name, event->type, rc); + "(%d, %d).\n", device->name, event->any.type, + rc); continue; } } @@ -3566,7 +3600,7 @@ CheckPassiveGrabsOnWindow( { if (!grabinfo->sync.event) grabinfo->sync.event = calloc(1, sizeof(DeviceEvent)); - *grabinfo->sync.event = *event; + *grabinfo->sync.event = event->device_event; grabinfo->sync.state = FROZEN_WITH_EVENT; } @@ -3641,7 +3675,8 @@ CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor) for (; i < focus->traceGood; i++) { pWin = focus->trace[i]; - if (CheckPassiveGrabsOnWindow(pWin, device, event, sendCore, TRUE)) + if (CheckPassiveGrabsOnWindow(pWin, device, (InternalEvent *) event, + sendCore, TRUE)) { ret = TRUE; goto out; @@ -3657,7 +3692,8 @@ CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor) for (; i < device->spriteInfo->sprite->spriteTraceGood; i++) { pWin = device->spriteInfo->sprite->spriteTrace[i]; - if (CheckPassiveGrabsOnWindow(pWin, device, event, sendCore, TRUE)) + if (CheckPassiveGrabsOnWindow(pWin, device, (InternalEvent *) event, + sendCore, TRUE)) { ret = TRUE; goto out; diff --git a/include/dix.h b/include/dix.h index c201e3ac1..fb9be43c2 100644 --- a/include/dix.h +++ b/include/dix.h @@ -375,7 +375,7 @@ extern void ReleaseActiveGrabs( extern GrabPtr CheckPassiveGrabsOnWindow( WindowPtr /* pWin */, DeviceIntPtr /* device */, - DeviceEvent * /* event */, + InternalEvent * /* event */, BOOL /* checkCore */, BOOL /* activate */); From 70cef8d8baf058bacaff87ef49e3851628269597 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Wed, 19 Jan 2011 20:42:10 +0000 Subject: [PATCH 08/28] Input: Simplify CheckPassiveGrabsOnWindow loop Instead of a mega never-ending if branch with no else, just continue to the next iteration of the loop if the conditions aren't met - pretty much entirely reindentation. Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer --- dix/events.c | 224 +++++++++++++++++++++++++-------------------------- 1 file changed, 109 insertions(+), 115 deletions(-) diff --git a/dix/events.c b/dix/events.c index 17194b181..895ab4035 100644 --- a/dix/events.c +++ b/dix/events.c @@ -3430,7 +3430,7 @@ CheckPassiveGrabsOnWindow( DeviceIntPtr gdev; XkbSrvInfoPtr xkbi = NULL; xEvent *xE = NULL; - xEvent core; + int count, rc; gdev= grab->modifierDevice; if (grab->grabtype == GRABTYPE_CORE) @@ -3478,135 +3478,129 @@ CheckPassiveGrabsOnWindow( match = CORE_MATCH; } - if (match && (!grab->confineTo || - (grab->confineTo->realized && - BorderSizeNotEmpty(device, grab->confineTo)))) - { - int rc, count = 0; - xEvent *xE = NULL; + if (!match || (grab->confineTo && + (!grab->confineTo->realized || + !BorderSizeNotEmpty(device, grab->confineTo)))) + continue; - grabinfo = &device->deviceGrab; - /* In some cases a passive core grab may exist, but the client - * already has a core grab on some other device. In this case we - * must not get the grab, otherwise we may never ungrab the - * device. - */ + grabinfo = &device->deviceGrab; + /* In some cases a passive core grab may exist, but the client + * already has a core grab on some other device. In this case we + * must not get the grab, otherwise we may never ungrab the + * device. + */ - if (grab->grabtype == GRABTYPE_CORE) + if (grab->grabtype == GRABTYPE_CORE) + { + DeviceIntPtr other; + BOOL interfering = FALSE; + + /* A passive grab may have been created for a different device + than it is assigned to at this point in time. + Update the grab's device and modifier device to reflect the + current state. + Since XGrabDeviceButton requires to specify the + modifierDevice explicitly, we don't override this choice. + */ + if (tempGrab.type < GenericEvent) { - DeviceIntPtr other; - BOOL interfering = FALSE; - - /* A passive grab may have been created for a different device - than it is assigned to at this point in time. - Update the grab's device and modifier device to reflect the - current state. - Since XGrabDeviceButton requires to specify the - modifierDevice explicitly, we don't override this choice. - */ - if (tempGrab.type < GenericEvent) - { - grab->device = device; - grab->modifierDevice = GetPairedDevice(device); - } - - for (other = inputInfo.devices; other; other = other->next) - { - GrabPtr othergrab = other->deviceGrab.grab; - if (othergrab && othergrab->grabtype == GRABTYPE_CORE && - SameClient(grab, rClient(othergrab)) && - ((IsPointerDevice(grab->device) && - IsPointerDevice(othergrab->device)) || - (IsKeyboardDevice(grab->device) && - IsKeyboardDevice(othergrab->device)))) - { - interfering = TRUE; - break; - } - } - if (interfering) - continue; + grab->device = device; + grab->modifierDevice = GetPairedDevice(device); } - if (!activate) + for (other = inputInfo.devices; other; other = other->next) { - return grab; - } - else if (!GetXIType(event) && !GetCoreType(event)) - { - ErrorF("Event type %d in CheckPassiveGrabsOnWindow is" - " neither XI 1.x nor core\n", event->any.type); - return NULL; - } - - /* The only consumers of corestate are Xi 1.x and core events, - * which are guaranteed to come from DeviceEvents. */ - if (match & (XI_MATCH | CORE_MATCH)) - { - event->device_event.corestate &= 0x1f00; - event->device_event.corestate |= - tempGrab.modifiersDetail.exact & (~0x1f00); - } - - if (match & CORE_MATCH) - { - rc = EventToCore((InternalEvent*)event, &xE, &count); - if (rc != Success) + GrabPtr othergrab = other->deviceGrab.grab; + if (othergrab && othergrab->grabtype == GRABTYPE_CORE && + SameClient(grab, rClient(othergrab)) && + ((IsPointerDevice(grab->device) && + IsPointerDevice(othergrab->device)) || + (IsKeyboardDevice(grab->device) && + IsKeyboardDevice(othergrab->device)))) { - if (rc != BadMatch) - ErrorF("[dix] %s: core conversion failed in CPGFW " - "(%d, %d).\n", device->name, event->any.type, - rc); - continue; - } - } else if (match & XI2_MATCH) - { - rc = EventToXI2(event, &xE); - if (rc != Success) - { - if (rc != BadMatch) - ErrorF("[dix] %s: XI2 conversion failed in CPGFW " - "(%d, %d).\n", device->name, event->any.type, - rc); - continue; - } - count = 1; - } else - { - rc = EventToXI(event, &xE, &count); - if (rc != Success) - { - if (rc != BadMatch) - ErrorF("[dix] %s: XI conversion failed in CPGFW " - "(%d, %d).\n", device->name, event->any.type, - rc); - continue; + interfering = TRUE; + break; } } + if (interfering) + continue; + } - (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE); + if (!activate) + { + return grab; + } + else if (!GetXIType(event) && !GetCoreType(event)) + { + ErrorF("Event type %d in CheckPassiveGrabsOnWindow is neither" + " XI 1.x nor core\n", event->any.type); + return NULL; + } - if (xE) + /* The only consumers of corestate are Xi 1.x and core events, which + * are guaranteed to come from DeviceEvents. */ + if (match & (XI_MATCH | CORE_MATCH)) + { + event->device_event.corestate &= 0x1f00; + event->device_event.corestate |= tempGrab.modifiersDetail.exact & + (~0x1f00); + } + + if (match & CORE_MATCH) + { + rc = EventToCore(event, &xE, &count); + if (rc != Success) { - FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE); - - /* XXX: XACE? */ - TryClientEvents(rClient(grab), device, xE, count, - GetEventFilter(device, xE), - GetEventFilter(device, xE), grab); + if (rc != BadMatch) + ErrorF("[dix] %s: core conversion failed in CPGFW " + "(%d, %d).\n", device->name, event->any.type, rc); + continue; } - - if (grabinfo->sync.state == FROZEN_NO_EVENT) - { - if (!grabinfo->sync.event) - grabinfo->sync.event = calloc(1, sizeof(DeviceEvent)); - *grabinfo->sync.event = event->device_event; - grabinfo->sync.state = FROZEN_WITH_EVENT; + } else if (match & XI2_MATCH) + { + rc = EventToXI2(event, &xE); + if (rc != Success) + { + if (rc != BadMatch) + ErrorF("[dix] %s: XI2 conversion failed in CPGFW " + "(%d, %d).\n", device->name, event->any.type, rc); + continue; } + count = 1; + } else + { + rc = EventToXI(event, &xE, &count); + if (rc != Success) + { + if (rc != BadMatch) + ErrorF("[dix] %s: XI conversion failed in CPGFW " + "(%d, %d).\n", device->name, event->any.type, rc); + continue; + } + } - free(xE); - return grab; - } + (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE); + + if (xE) + { + FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE); + + /* XXX: XACE? */ + TryClientEvents(rClient(grab), device, xE, count, + GetEventFilter(device, xE), + GetEventFilter(device, xE), grab); + } + + if (grabinfo->sync.state == FROZEN_NO_EVENT) + { + if (!grabinfo->sync.event) + grabinfo->sync.event = calloc(1, sizeof(DeviceEvent)); + *grabinfo->sync.event = event->device_event; + grabinfo->sync.state = FROZEN_WITH_EVENT; + } + + free(xE); + return grab; } return NULL; #undef CORE_MATCH From 72b6639c83df74767094a5e0c2861fdc5ea03ecd Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 3 May 2011 02:39:55 +0100 Subject: [PATCH 09/28] XKB: Don't send unnecessary NewKeyboardNotifies In the XKB GetKeyboardByName handler, we had the following pseudocode: if (device was last slave of its MD) { XkbCopyDeviceKeymap(master, slave); XkbSendNewKeyboardNotify(slave, ¬ify); } Even if the SendNewKeyboardNotify line nominated the correct device, which it didn't, it's unnecessary as XkbCopyDeviceKeymap already sends a NewKeyboardNotify on the destination device. Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer --- xkb/xkb.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/xkb/xkb.c b/xkb/xkb.c index 4044d333d..c4cb74015 100644 --- a/xkb/xkb.c +++ b/xkb/xkb.c @@ -5902,10 +5902,8 @@ ProcXkbGetKbdByName(ClientPtr client) if (!IsMaster(dev)) { DeviceIntPtr master = GetMaster(dev, MASTER_KEYBOARD); - if (master && master->lastSlave == dev) { + if (master && master->lastSlave == dev) XkbCopyDeviceKeymap(master, dev); - XkbSendNewKeyboardNotify(dev,&nkn); - } } } if ((new!=NULL)&&(new!=xkb)) { From b8540d18c7d3a0f93f9e2565a410986eddedcecb Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 3 May 2011 02:50:48 +0100 Subject: [PATCH 10/28] XKB: Simplify a loop in ProcXkbGetKbdByName Replace: for (stuff; things; etc) { if (misc || other) { [...] } } with: for (stuff; things; etc) { if (!misc && !other) continue; [...] } Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer --- xkb/xkb.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/xkb/xkb.c b/xkb/xkb.c index c4cb74015..e17e216c1 100644 --- a/xkb/xkb.c +++ b/xkb/xkb.c @@ -5870,21 +5870,22 @@ ProcXkbGetKbdByName(ClientPtr client) xkb->ctrls->num_groups= nTG; for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) { - if ((tmpd == dev) || (!IsMaster(tmpd) && GetMaster(tmpd, MASTER_KEYBOARD) == dev)) { - if (tmpd != dev) - XkbCopyDeviceKeymap(tmpd, dev); + if (tmpd != dev && GetMaster(tmpd, MASTER_KEYBOARD) != dev) + continue; - if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) { - old_sli = tmpd->kbdfeed->xkb_sli; - tmpd->kbdfeed->xkb_sli = NULL; - sli = XkbAllocSrvLedInfo(tmpd, tmpd->kbdfeed, NULL, 0); - if (sli) { - sli->explicitState = old_sli->explicitState; - sli->effectiveState = old_sli->effectiveState; - } - tmpd->kbdfeed->xkb_sli = sli; - XkbFreeSrvLedInfo(old_sli); + if (tmpd != dev) + XkbCopyDeviceKeymap(tmpd, dev); + + if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) { + old_sli = tmpd->kbdfeed->xkb_sli; + tmpd->kbdfeed->xkb_sli = NULL; + sli = XkbAllocSrvLedInfo(tmpd, tmpd->kbdfeed, NULL, 0); + if (sli) { + sli->explicitState = old_sli->explicitState; + sli->effectiveState = old_sli->effectiveState; } + tmpd->kbdfeed->xkb_sli = sli; + XkbFreeSrvLedInfo(old_sli); } } From c7634498d4cd42c8571805122224dc2d0e44a585 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 3 May 2011 02:59:53 +0100 Subject: [PATCH 11/28] XKB: Remove duplicate keymap-copying loop Previously we had: foreach (device + slaves of device) { XkbCopyDeviceKeymap(i, device); [...] } if (device was last slave of its MD) { XkbCopyDeviceKeymap(master, device); } and now: foreach (device + slaves of device + MD if device was last slave) { XkbCopyDeviceKeymap(i, device); [...] } As an extra bonus, when changing the keymap on a slave device, we now ensure the LED info on the master is kept in sync. Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer --- xkb/xkb.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/xkb/xkb.c b/xkb/xkb.c index e17e216c1..4d21200db 100644 --- a/xkb/xkb.c +++ b/xkb/xkb.c @@ -5586,6 +5586,7 @@ ProcXkbGetKbdByName(ClientPtr client) { DeviceIntPtr dev; DeviceIntPtr tmpd; + DeviceIntPtr master; xkbGetKbdByNameReply rep = {0}; xkbGetMapReply mrep = {0}; xkbGetCompatMapReply crep = {0}; @@ -5611,6 +5612,7 @@ ProcXkbGetKbdByName(ClientPtr client) return BadAccess; CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode); + master = GetMaster(dev, MASTER_KEYBOARD); xkb = dev->key->xkbInfo->desc; status= Success; @@ -5869,8 +5871,12 @@ ProcXkbGetKbdByName(ClientPtr client) } xkb->ctrls->num_groups= nTG; + /* Update the map and LED info on the device itself, as well as + * any slaves if it's an MD, or its MD if it's an SD and was the + * last device used on that MD. */ for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) { - if (tmpd != dev && GetMaster(tmpd, MASTER_KEYBOARD) != dev) + if (tmpd != dev && GetMaster(tmpd, MASTER_KEYBOARD) != dev && + (tmpd != master || dev != master->lastSlave)) continue; if (tmpd != dev) @@ -5900,12 +5906,6 @@ ProcXkbGetKbdByName(ClientPtr client) if (geom_changed) nkn.changed|= XkbNKN_GeometryMask; XkbSendNewKeyboardNotify(dev,&nkn); - - if (!IsMaster(dev)) { - DeviceIntPtr master = GetMaster(dev, MASTER_KEYBOARD); - if (master && master->lastSlave == dev) - XkbCopyDeviceKeymap(master, dev); - } } if ((new!=NULL)&&(new!=xkb)) { XkbFreeKeyboard(new,XkbAllComponentsMask,TRUE); From a79d4544fee806a25447d0147535ebc5a1cae6b9 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 3 May 2011 03:03:06 +0100 Subject: [PATCH 12/28] XKB: Send NewKeyboardNotify for dev before its master/slaves When we change the keymap on a device, send the NewKeyboardNotify for that device before we copy the keymap to and notify for its attached master/slave devices. Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer --- xkb/xkb.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/xkb/xkb.c b/xkb/xkb.c index 4d21200db..86231a895 100644 --- a/xkb/xkb.c +++ b/xkb/xkb.c @@ -5871,6 +5871,18 @@ ProcXkbGetKbdByName(ClientPtr client) } xkb->ctrls->num_groups= nTG; + nkn.deviceID= nkn.oldDeviceID= dev->id; + nkn.minKeyCode= new->min_key_code; + nkn.maxKeyCode= new->max_key_code; + nkn.oldMinKeyCode= xkb->min_key_code; + nkn.oldMaxKeyCode= xkb->max_key_code; + nkn.requestMajor= XkbReqCode; + nkn.requestMinor= X_kbGetKbdByName; + nkn.changed= XkbNKN_KeycodesMask; + if (geom_changed) + nkn.changed|= XkbNKN_GeometryMask; + XkbSendNewKeyboardNotify(dev,&nkn); + /* Update the map and LED info on the device itself, as well as * any slaves if it's an MD, or its MD if it's an SD and was the * last device used on that MD. */ @@ -5894,18 +5906,6 @@ ProcXkbGetKbdByName(ClientPtr client) XkbFreeSrvLedInfo(old_sli); } } - - nkn.deviceID= nkn.oldDeviceID= dev->id; - nkn.minKeyCode= new->min_key_code; - nkn.maxKeyCode= new->max_key_code; - nkn.oldMinKeyCode= xkb->min_key_code; - nkn.oldMaxKeyCode= xkb->max_key_code; - nkn.requestMajor= XkbReqCode; - nkn.requestMinor= X_kbGetKbdByName; - nkn.changed= XkbNKN_KeycodesMask; - if (geom_changed) - nkn.changed|= XkbNKN_GeometryMask; - XkbSendNewKeyboardNotify(dev,&nkn); } if ((new!=NULL)&&(new!=xkb)) { XkbFreeKeyboard(new,XkbAllComponentsMask,TRUE); From 460a377ef2d645d9ae38a8356fb248ccc47bed4a Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 3 May 2011 03:07:50 +0100 Subject: [PATCH 13/28] XKB: Send XKB events for all devices to all clients We were using XIShouldNotify(client, device) as a test for whether or not to send XKB map/state/etc changed events, which limits it to only sending events for the current ClientPointer/ClientKeyboard for that client. While this makes perfect sense for core events (e.g. MappingNotify), XKB events carry a device ID, so are safe to send to all clients for all devices. Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer --- xkb/xkbEvents.c | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/xkb/xkbEvents.c b/xkb/xkbEvents.c index 7f91e9ae1..d342acc28 100644 --- a/xkb/xkbEvents.c +++ b/xkb/xkbEvents.c @@ -164,9 +164,6 @@ XkbSendNewKeyboardNotify(DeviceIntPtr kbd,xkbNewKeyboardNotify *pNKN) if (!(clients[i]->newKeyboardNotifyMask & changed)) continue; - if (!XIShouldNotify(clients[i], kbd)) - continue; - pNKN->sequenceNumber = clients[i]->sequence; pNKN->time = time; pNKN->changed = changed; @@ -232,8 +229,7 @@ register CARD16 changed,bState; if ((!interest->client->clientGone) && (interest->client->requestVector != InitialVector) && (interest->client->xkbClientFlags&_XkbClientInitialized) && - (interest->stateNotifyMask&changed) && - XIShouldNotify(interest->client,kbd)) { + (interest->stateNotifyMask&changed)) { pSN->sequenceNumber = interest->client->sequence; pSN->time = time; pSN->changed = changed; @@ -280,9 +276,6 @@ XkbSendMapNotify(DeviceIntPtr kbd, xkbMapNotify *pMN) if (!(clients[i]->mapNotifyMask & changed)) continue; - if (!XIShouldNotify(clients[i], kbd)) - continue; - pMN->time = time; pMN->sequenceNumber = clients[i]->sequence; pMN->changed = changed; @@ -401,8 +394,7 @@ Time time = 0; if ((!interest->client->clientGone) && (interest->client->requestVector != InitialVector) && (interest->client->xkbClientFlags&_XkbClientInitialized) && - (interest->ctrlsNotifyMask&changedControls) && - XIShouldNotify(interest->client, kbd)) { + (interest->ctrlsNotifyMask&changedControls)) { if (!initialized) { pCN->type = XkbEventCode + XkbEventBase; pCN->xkbType = XkbControlsNotify; @@ -450,7 +442,6 @@ CARD32 state,changed; if ((!interest->client->clientGone) && (interest->client->requestVector != InitialVector) && (interest->client->xkbClientFlags&_XkbClientInitialized) && - XIShouldNotify(interest->client, kbd) && (((xkbType==XkbIndicatorStateNotify)&& (interest->iStateNotifyMask&changed))|| ((xkbType==XkbIndicatorMapNotify)&& @@ -534,8 +525,7 @@ XID winID = 0; if ((!interest->client->clientGone) && (interest->client->requestVector != InitialVector) && (interest->client->xkbClientFlags&_XkbClientInitialized) && - (interest->bellNotifyMask) && - XIShouldNotify(interest->client,kbd)) { + (interest->bellNotifyMask)) { if (!initialized) { time = GetTimeInMillis(); bn.type = XkbEventCode + XkbEventBase; @@ -589,8 +579,7 @@ CARD16 sk_delay,db_delay; if ((!interest->client->clientGone) && (interest->client->requestVector != InitialVector) && (interest->client->xkbClientFlags&_XkbClientInitialized) && - (interest->accessXNotifyMask&(1<detail)) && - XIShouldNotify(interest->client, kbd)) { + (interest->accessXNotifyMask&(1<detail))) { if (!initialized) { pEv->type = XkbEventCode + XkbEventBase; pEv->xkbType = XkbAccessXNotify; @@ -637,8 +626,7 @@ CARD32 changedIndicators; if ((!interest->client->clientGone) && (interest->client->requestVector != InitialVector) && (interest->client->xkbClientFlags&_XkbClientInitialized) && - (interest->namesNotifyMask&pEv->changed) && - XIShouldNotify(interest->client, kbd)) { + (interest->namesNotifyMask&pEv->changed)) { if (!initialized) { pEv->type = XkbEventCode + XkbEventBase; pEv->xkbType = XkbNamesNotify; @@ -683,8 +671,7 @@ CARD16 firstSI = 0, nSI = 0, nTotalSI = 0; if ((!interest->client->clientGone) && (interest->client->requestVector != InitialVector) && (interest->client->xkbClientFlags&_XkbClientInitialized) && - (interest->compatNotifyMask) && - XIShouldNotify(interest->client, kbd)) { + (interest->compatNotifyMask)) { if (!initialized) { pEv->type = XkbEventCode + XkbEventBase; pEv->xkbType = XkbCompatMapNotify; @@ -736,8 +723,7 @@ Time time = 0; if ((!interest->client->clientGone) && (interest->client->requestVector != InitialVector) && (interest->client->xkbClientFlags&_XkbClientInitialized) && - (interest->actionMessageMask) && - XIShouldNotify(interest->client, kbd)) { + (interest->actionMessageMask)) { if (!initialized) { pEv->type = XkbEventCode + XkbEventBase; pEv->xkbType = XkbActionMessage; @@ -783,8 +769,7 @@ CARD16 reason; if ((!interest->client->clientGone) && (interest->client->requestVector != InitialVector) && (interest->client->xkbClientFlags&_XkbClientInitialized) && - (interest->extDevNotifyMask&reason) && - XIShouldNotify(interest->client, dev)) { + (interest->extDevNotifyMask&reason)) { if (!initialized) { pEv->type = XkbEventCode + XkbEventBase; pEv->xkbType = XkbExtensionDeviceNotify; From 3231962db826f5efd431596a309c96e907a191d1 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 3 May 2011 03:20:23 +0100 Subject: [PATCH 14/28] XKB: Fix sense inversion for core MapNotify events Due to an unfortunate sense inversion incident while switching from a if (foo) { ... } to if (!foo) continue; style in f06a9d, we punished any client who attempted to use XKB to restrict the MapNotify events they wanted by sending them exactly the events they _didn't_ want, and nothing else. NewKeyboardNotifies (coming from a client setting the map with an XKB request, when switching between master devices, etc) weren't affected, but this would impact anyone using xmodmap-style core requests. Could explain a fair bit. Clarified the comments while I was at it. Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer --- xkb/xkbEvents.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/xkb/xkbEvents.c b/xkb/xkbEvents.c index d342acc28..dfbf7f2b3 100644 --- a/xkb/xkbEvents.c +++ b/xkb/xkbEvents.c @@ -88,11 +88,15 @@ XkbSendLegacyMapNotify(DeviceIntPtr kbd, CARD16 xkb_event, CARD16 changed, if (!clients[i] || clients[i]->clientState != ClientStateRunning) continue; - /* Ignore clients which will have already received this. - * Inconsistent with themselves, but consistent with previous - * behaviour.*/ - if (xkb_event == XkbMapNotify && (clients[i]->mapNotifyMask & changed)) + /* XKB allows clients to restrict the MappingNotify events sent to + * them. This was broken for three years. Sorry. */ + if (xkb_event == XkbMapNotify && + (clients[i]->xkbClientFlags & _XkbClientInitialized) && + !(clients[i]->mapNotifyMask & changed)) continue; + /* Emulate previous server behaviour: any client which has activated + * XKB will not receive core events emulated from a NewKeyboardNotify + * at all. */ if (xkb_event == XkbNewKeyboardNotify && (clients[i]->xkbClientFlags & _XkbClientInitialized)) continue; From 1b8593a6c12315b1071a4fa586151e12f46458f5 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 9 May 2011 15:13:17 +1000 Subject: [PATCH 15/28] xfree86: print the device ID to the log when adding a device. Sometimes the name isn't enough, it's handy to see the device ID's from the log file. Signed-off-by: Peter Hutterer --- hw/xfree86/common/xf86Xinput.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c index ef4542c5f..aae665864 100644 --- a/hw/xfree86/common/xf86Xinput.c +++ b/hw/xfree86/common/xf86Xinput.c @@ -329,8 +329,8 @@ xf86ActivateDevice(InputInfoPtr pInfo) dev->config_info = xf86SetStrOption(pInfo->options, "config_info", NULL); if (serverGeneration == 1) - xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n", - pInfo->name, pInfo->type_name); + xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s, id %d)\n", + pInfo->name, pInfo->type_name, dev->id); return dev; } From e7150db5350bc2113ff4126019b489847a4dc217 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 11 Apr 2011 15:48:15 +1000 Subject: [PATCH 16/28] input: Provide Queue{Button|Keyboard|Proximity}Event helpers Don't require every caller to use GPE + mieqEnqueue, provide matching Queue...Event functions instead. Signed-off-by: Peter Hutterer Reviewed-by: Jeremy Huddleston --- dix/getevents.c | 80 ++++++++++++++++++++++++++++++++++ hw/dmx/input/dmxevents.c | 54 +++++++---------------- hw/kdrive/src/kinput.c | 18 +++----- hw/xfree86/common/xf86Events.c | 6 +-- hw/xfree86/common/xf86Xinput.c | 38 ++++------------ hw/xnest/Events.c | 32 +++++--------- hw/xquartz/darwinEvents.c | 20 +++------ hw/xwin/winkeybd.c | 6 +-- hw/xwin/winmouse.c | 15 ++----- include/input.h | 21 +++++++++ 10 files changed, 155 insertions(+), 135 deletions(-) diff --git a/dix/getevents.c b/dix/getevents.c index 5ffa1df92..68a5224dc 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -47,6 +47,7 @@ #include "eventstr.h" #include "eventconvert.h" #include "inpututils.h" +#include "mi.h" #include #include "xkbsrv.h" @@ -924,6 +925,39 @@ updateHistory(DeviceIntPtr dev, ValuatorMask *mask, CARD32 ms) } } +static void +queueEventList(DeviceIntPtr device, EventList *events, int nevents) +{ + int i; + + for (i = 0; i < nevents; i++) + mieqEnqueue(device, (InternalEvent*)((events + i)->event)); +} + +/** + * Generate internal events representing this keyboard event and enqueue + * them on the event queue. + * + * FIXME: don't require the event list to be passed in. + * FIXME: flags for relative/abs motion? + * + * @param events Event list used as temporary storage + * @param device The device to generate the event for + * @param type Event type, one of KeyPress or KeyRelease + * @param keycode Key code of the pressed/released key + * @param mask Valuator mask for valuators present for this event. + * + */ +void +QueueKeyboardEvents(EventList *events, DeviceIntPtr device, int type, + int keycode, const ValuatorMask *mask) +{ + int nevents; + + nevents = GetKeyboardEvents(events, device, type, keycode, mask); + queueEventList(device, events, nevents); +} + /** * Returns a set of InternalEvents for KeyPress/KeyRelease, optionally * also with valuator events. @@ -1061,6 +1095,30 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask, int *x, int *y) *y = lround(p.v[1]); } +/** + * Generate internal events representing this pointer event and enqueue them + * on the event queue. + * + * FIXME: don't require the event list to be passed in. + * + * @param events Event list used as temporary storage + * @param device The device to generate the event for + * @param type Event type, one of ButtonPress, ButtonRelease, MotionNotify + * @param buttons Button number of the buttons modified. Must be 0 for + * MotionNotify + * @param flags Event modification flags + * @param mask Valuator mask for valuators present for this event. + */ +void +QueuePointerEvents(EventList *events, DeviceIntPtr device, int type, + int buttons, int flags, const ValuatorMask *mask) +{ + int nevents; + + nevents = GetPointerEvents(events, device, type, buttons, flags, mask); + queueEventList(device, events, nevents); +} + /** * Generate a series of InternalEvents (filled into the EventList) * representing pointer motion, or button presses. @@ -1214,6 +1272,28 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons, return num_events; } +/** + * Generate internal events representing this proximity event and enqueue + * them on the event queue. + * + * FIXME: don't require the event list to be passed in. + * + * @param events Event list used as temporary storage + * @param device The device to generate the event for + * @param type Event type, one of ProximityIn or ProximityOut + * @param keycode Key code of the pressed/released key + * @param mask Valuator mask for valuators present for this event. + * + */ +void +QueueProximityEvents(EventList *events, DeviceIntPtr device, int type, + const ValuatorMask *mask) +{ + int nevents; + + nevents = GetProximityEvents(events, device, type, mask); + queueEventList(device, events, nevents); +} /** * Generate ProximityIn/ProximityOut InternalEvents, accompanied by diff --git a/hw/dmx/input/dmxevents.c b/hw/dmx/input/dmxevents.c index 15d80f5bb..3f9035cdd 100644 --- a/hw/dmx/input/dmxevents.c +++ b/hw/dmx/input/dmxevents.c @@ -176,7 +176,7 @@ static void enqueueMotion(DevicePtr pDev, int x, int y) { GETDMXLOCALFROMPDEV; DeviceIntPtr p = dmxLocal->pDevice; - int i, nevents, valuators[3]; + int valuators[3]; EventListPtr events; int detail = 0; /* XXX should this be mask of pressed buttons? */ ValuatorMask mask; @@ -185,10 +185,8 @@ static void enqueueMotion(DevicePtr pDev, int x, int y) valuator_mask_set_range(&mask, 0, 2, valuators); GetEventList(&events); - nevents = GetPointerEvents(events, p, MotionNotify, detail, - POINTER_ABSOLUTE | POINTER_SCREEN, &mask); - for (i = 0; i < nevents; i++) - mieqEnqueue(p, (InternalEvent*)(events + i)->event); + QueuePointerEvents(events, p, MotionNotify, detail, + POINTER_ABSOLUTE | POINTER_SCREEN, &mask); return; } @@ -291,10 +289,8 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal, deviceValuator *xv = (deviceValuator *)xev+1; int thisX = 0; int thisY = 0; - int i; int count; EventListPtr events; - int nevents; ValuatorMask mask; memset(xE, 0, sizeof(xE)); @@ -348,6 +344,7 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal, } count = 2; } else { + int i; for (i = 0, count = 0; i < axesCount; i += 6) { xev->time = GetTimeInMillis(); xev->type = DeviceMotionNotify; @@ -376,10 +373,8 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal, dmxSigioBlock(); valuator_mask_set_range(&mask, firstAxis, axesCount, v); GetEventList(&events); - nevents = GetPointerEvents(events, pDevice, MotionNotify, 0, - POINTER_ABSOLUTE, &mask); - for (i = 0; i < nevents; i++) - mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event); + QueuePointerEvents(events, pDevice, MotionNotify, 0, + POINTER_ABSOLUTE, &mask); if (block) dmxSigioUnblock(); @@ -395,7 +390,6 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal, DeviceIntPtr pDevice = dmxLocal->pDevice; int valuators[MAX_VALUATORS]; EventListPtr events; - int nevents, i; ValuatorMask mask; if (!e) @@ -453,11 +447,7 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal, if (block) dmxSigioBlock(); GetEventList(&events); - nevents = GetKeyboardEvents(events, pDevice, event, - ke->keycode, &mask); - for (i = 0; i < nevents; i++) - mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event); - + QueueKeyboardEvents(events, pDevice, event, ke->keycode, &mask); if (block) dmxSigioUnblock(); break; @@ -468,11 +458,8 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal, if (block) dmxSigioBlock(); GetEventList(&events); - nevents = GetPointerEvents(events, pDevice, event, ke->keycode, - POINTER_ABSOLUTE, &mask); - for (i = 0; i < nevents; i++) - mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event); - + QueuePointerEvents(events, pDevice, event, ke->keycode, + POINTER_ABSOLUTE, &mask); if (block) dmxSigioUnblock(); break; @@ -483,10 +470,7 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal, if (block) dmxSigioBlock(); GetEventList(&events); - nevents = GetProximityEvents(events, pDevice, event, &mask); - for (i = 0; i < nevents; i++) - mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event); - + QueueProximityEvents(events, pDevice, event, &mask); if (block) dmxSigioUnblock(); break; @@ -667,7 +651,7 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym, GETDMXINPUTFROMPDEV; xEvent xE; DeviceIntPtr p = dmxLocal->pDevice; - int i, nevents, valuators[3]; + int valuators[3]; EventListPtr events; ValuatorMask mask; @@ -685,9 +669,7 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym, GetEventList(&events); /*ErrorF("KEY %d sym %d\n", detail, (int) keySym);*/ - nevents = GetKeyboardEvents(events, p, type, detail, NULL); - for (i = 0; i < nevents; i++) - mieqEnqueue(p, (InternalEvent*)(events + i)->event); + QueueKeyboardEvents(events, p, type, detail, NULL); return; case ButtonPress: @@ -695,10 +677,8 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym, detail = dmxGetButtonMapping(dmxLocal, detail); valuator_mask_zero(&mask); GetEventList(&events); - nevents = GetPointerEvents(events, p, type, detail, - POINTER_ABSOLUTE | POINTER_SCREEN, &mask); - for (i = 0; i < nevents; i++) - mieqEnqueue(p, (InternalEvent*)(events + i)->event); + QueuePointerEvents(events, p, type, detail, + POINTER_ABSOLUTE | POINTER_SCREEN, &mask); return; case MotionNotify: @@ -707,10 +687,8 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym, valuators[1] = e->xmotion.y; valuators[2] = e->xmotion.state; /* FIXME: WTF?? */ valuator_mask_set_range(&mask, 0, 3, valuators); - nevents = GetPointerEvents(events, p, type, detail, - POINTER_ABSOLUTE | POINTER_SCREEN, &mask); - for (i = 0; i < nevents; i++) - mieqEnqueue(p, (InternalEvent*)(events + i)->event); + QueuePointerEvents(events, p, type, detail, + POINTER_ABSOLUTE | POINTER_SCREEN, &mask); return; case EnterNotify: diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c index f21475fb6..521542c91 100644 --- a/hw/kdrive/src/kinput.c +++ b/hw/kdrive/src/kinput.c @@ -1793,7 +1793,7 @@ void KdReleaseAllKeys (void) { #if 0 - int key, nEvents, i; + int key; KdKeyboardInfo *ki; KdBlockSigio (); @@ -1804,9 +1804,7 @@ KdReleaseAllKeys (void) if (key_is_down(ki->dixdev, key, KEY_POSTED | KEY_PROCESSED)) { KdHandleKeyboardEvent(ki, KeyRelease, key); GetEventList(&kdEvents); - nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, KeyRelease, key, NULL); - for (i = 0; i < nEvents; i++) - KdQueueEvent (ki->dixdev, (kdEvents + i)->event); + QueueGetKeyboardEvents(kdEvents, ki->dixdev, KeyRelease, key, NULL); } } } @@ -1842,7 +1840,7 @@ KdEnqueueKeyboardEvent(KdKeyboardInfo *ki, unsigned char key_code; KeyClassPtr keyc = NULL; KeybdCtrl *ctrl = NULL; - int type, nEvents, i; + int type; if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed || !ki->dixdev->key) return; @@ -1863,10 +1861,7 @@ KdEnqueueKeyboardEvent(KdKeyboardInfo *ki, type = KeyPress; GetEventList(&kdEvents); - - nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, type, key_code, NULL); - for (i = 0; i < nEvents; i++) - KdQueueEvent(ki->dixdev, (InternalEvent *)((kdEvents + i)->event)); + QueueKeyboardEvents(kdEvents, ki->dixdev, type, key_code, NULL); } else { ErrorF("driver %s wanted to post scancode %d outside of [%d, %d]!\n", @@ -1965,7 +1960,6 @@ void _KdEnqueuePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z, int b, int absrel, Bool force) { - int nEvents = 0, i = 0; int valuators[3] = { x, y, z }; ValuatorMask mask; @@ -1976,9 +1970,7 @@ _KdEnqueuePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z, valuator_mask_set_range(&mask, 0, 3, valuators); GetEventList(&kdEvents); - nEvents = GetPointerEvents(kdEvents, pi->dixdev, type, b, absrel, &mask); - for (i = 0; i < nEvents; i++) - KdQueueEvent(pi->dixdev, (InternalEvent *)((kdEvents + i)->event)); + QueuePointerEvents(kdEvents, pi->dixdev, type, b, absrel, &mask); } void diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c index 3006ad183..6402d72b3 100644 --- a/hw/xfree86/common/xf86Events.c +++ b/hw/xfree86/common/xf86Events.c @@ -376,7 +376,7 @@ static void xf86ReleaseKeys(DeviceIntPtr pDev) { KeyClassPtr keyc; - int i, j, nevents, sigstate; + int i, sigstate; if (!pDev || !pDev->key) return; @@ -399,9 +399,7 @@ xf86ReleaseKeys(DeviceIntPtr pDev) i++) { if (key_is_down(pDev, i, KEY_POSTED)) { sigstate = xf86BlockSIGIO (); - nevents = GetKeyboardEvents(xf86Events, pDev, KeyRelease, i, NULL); - for (j = 0; j < nevents; j++) - mieqEnqueue(pDev, (InternalEvent*)(xf86Events + j)->event); + QueueKeyboardEvents(xf86Events, pDev, KeyRelease, i, NULL); xf86UnblockSIGIO(sigstate); } } diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c index aae665864..111f16f50 100644 --- a/hw/xfree86/common/xf86Xinput.c +++ b/hw/xfree86/common/xf86Xinput.c @@ -1012,7 +1012,6 @@ xf86PostMotionEventM(DeviceIntPtr device, int is_absolute, const ValuatorMask *mask) { - int i = 0, nevents = 0; int flags = 0; if (valuator_mask_num_valuators(mask) > 0) @@ -1050,11 +1049,7 @@ xf86PostMotionEventM(DeviceIntPtr device, } #endif - nevents = GetPointerEvents(xf86Events, device, MotionNotify, 0, flags, mask); - - for (i = 0; i < nevents; i++) { - mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event)); - } + QueuePointerEvents(xf86Events, device, MotionNotify, 0, flags, mask); } void @@ -1099,13 +1094,8 @@ xf86PostProximityEventM(DeviceIntPtr device, int is_in, const ValuatorMask *mask) { - int i, nevents; - - nevents = GetProximityEvents(xf86Events, device, - is_in ? ProximityIn : ProximityOut, mask); - for (i = 0; i < nevents; i++) - mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event)); - + QueueProximityEvents(xf86Events, device, + is_in ? ProximityIn : ProximityOut, mask); } void @@ -1157,7 +1147,6 @@ xf86PostButtonEventM(DeviceIntPtr device, int is_down, const ValuatorMask *mask) { - int i = 0, nevents = 0; int flags = 0; if (valuator_mask_num_valuators(mask) > 0) @@ -1177,13 +1166,9 @@ xf86PostButtonEventM(DeviceIntPtr device, } #endif - nevents = GetPointerEvents(xf86Events, device, - is_down ? ButtonPress : ButtonRelease, button, - flags, mask); - - for (i = 0; i < nevents; i++) - mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event)); - + QueuePointerEvents(xf86Events, device, + is_down ? ButtonPress : ButtonRelease, button, + flags, mask); } void @@ -1235,8 +1220,6 @@ xf86PostKeyEventM(DeviceIntPtr device, int is_absolute, const ValuatorMask *mask) { - int i = 0, nevents = 0; - #if XFreeXDGA DeviceIntPtr pointer; @@ -1250,12 +1233,9 @@ xf86PostKeyEventM(DeviceIntPtr device, } #endif - nevents = GetKeyboardEvents(xf86Events, device, - is_down ? KeyPress : KeyRelease, - key_code, mask); - - for (i = 0; i < nevents; i++) - mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event)); + QueueKeyboardEvents(xf86Events, device, + is_down ? KeyPress : KeyRelease, + key_code, mask); } void diff --git a/hw/xnest/Events.c b/hw/xnest/Events.c index 5c800860a..574e4e415 100644 --- a/hw/xnest/Events.c +++ b/hw/xnest/Events.c @@ -104,20 +104,16 @@ xnestCollectExposures(void) void xnestQueueKeyEvent(int type, unsigned int keycode) { - int i, n; - GetEventList(&xnestEvents); lastEventTime = GetTimeInMillis(); - n = GetKeyboardEvents(xnestEvents, xnestKeyboardDevice, type, keycode, NULL); - for (i = 0; i < n; i++) - mieqEnqueue(xnestKeyboardDevice, (InternalEvent*)(xnestEvents + i)->event); + QueueKeyboardEvents(xnestEvents, xnestKeyboardDevice, type, keycode, NULL); } void xnestCollectEvents(void) { XEvent X; - int i, n, valuators[2]; + int valuators[2]; ValuatorMask mask; ScreenPtr pScreen; GetEventList(&xnestEvents); @@ -138,20 +134,16 @@ xnestCollectEvents(void) valuator_mask_set_range(&mask, 0, 0, NULL); xnestUpdateModifierState(X.xkey.state); lastEventTime = GetTimeInMillis(); - n = GetPointerEvents(xnestEvents, xnestPointerDevice, ButtonPress, - X.xbutton.button, POINTER_RELATIVE, &mask); - for (i = 0; i < n; i++) - mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event); + QueuePointerEvents(xnestEvents, xnestPointerDevice, ButtonPress, + X.xbutton.button, POINTER_RELATIVE, &mask); break; case ButtonRelease: valuator_mask_set_range(&mask, 0, 0, NULL); xnestUpdateModifierState(X.xkey.state); lastEventTime = GetTimeInMillis(); - n = GetPointerEvents(xnestEvents, xnestPointerDevice, ButtonRelease, - X.xbutton.button, POINTER_RELATIVE, &mask); - for (i = 0; i < n; i++) - mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event); + QueuePointerEvents(xnestEvents, xnestPointerDevice, ButtonRelease, + X.xbutton.button, POINTER_RELATIVE, &mask); break; case MotionNotify: @@ -159,10 +151,8 @@ xnestCollectEvents(void) valuators[1] = X.xmotion.y; valuator_mask_set_range(&mask, 0, 2, valuators); lastEventTime = GetTimeInMillis(); - n = GetPointerEvents(xnestEvents, xnestPointerDevice, MotionNotify, - 0, POINTER_ABSOLUTE, &mask); - for (i = 0; i < n; i++) - mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event); + QueuePointerEvents(xnestEvents, xnestPointerDevice, MotionNotify, + 0, POINTER_ABSOLUTE, &mask); break; case FocusIn: @@ -193,10 +183,8 @@ xnestCollectEvents(void) valuators[1] = X.xcrossing.y; valuator_mask_set_range(&mask, 0, 2, valuators); lastEventTime = GetTimeInMillis(); - n = GetPointerEvents(xnestEvents, xnestPointerDevice, MotionNotify, - 0, POINTER_ABSOLUTE, &mask); - for (i = 0; i < n; i++) - mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event); + QueuePointerEvents(xnestEvents, xnestPointerDevice, MotionNotify, + 0, POINTER_ABSOLUTE, &mask); xnestDirectInstallColormaps(pScreen); } } diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index f3e12250e..99956e012 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -433,7 +433,6 @@ static void DarwinPrepareValuators(DeviceIntPtr pDev, int *valuators, ScreenPtr void DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button, float pointer_x, float pointer_y, float pressure, float tilt_x, float tilt_y) { static int darwinFakeMouseButtonDown = 0; - int i, num_events; ScreenPtr screen; int valuators[5]; @@ -486,15 +485,13 @@ void DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button, floa darwinEvents_lock(); { ValuatorMask mask; valuator_mask_set_range(&mask, 0, (pDev == darwinPointer) ? 2 : 5, valuators); - num_events = GetPointerEvents(darwinEvents, pDev, ev_type, ev_button, - POINTER_ABSOLUTE, &mask); - for(i=0; i 0) DarwinPokeEQ(); + QueuePointerEvents(darwinEvents, pDev, ev_type, ev_button, + POINTER_ABSOLUTE, &mask); + DarwinPokeEQ(); } darwinEvents_unlock(); } void DarwinSendKeyboardEvents(int ev_type, int keycode) { - int i, num_events; if(!darwinEvents) { DEBUG_LOG("DarwinSendKeyboardEvents called before darwinEvents was initialized\n"); @@ -502,15 +499,13 @@ void DarwinSendKeyboardEvents(int ev_type, int keycode) { } darwinEvents_lock(); { - num_events = GetKeyboardEvents(darwinEvents, darwinKeyboard, ev_type, keycode + MIN_KEYCODE, NULL); - for(i=0; i 0) DarwinPokeEQ(); + QueueKeyboardEvents(darwinEvents, darwinKeyboard, ev_type, keycode + MIN_KEYCODE, NULL); + DarwinPokeEQ(); } darwinEvents_unlock(); } void DarwinSendProximityEvents(DeviceIntPtr pDev, int ev_type, float pointer_x, float pointer_y, float pressure, float tilt_x, float tilt_y) { - int i, num_events; ScreenPtr screen; int valuators[5]; @@ -531,9 +526,8 @@ void DarwinSendProximityEvents(DeviceIntPtr pDev, int ev_type, float pointer_x, darwinEvents_lock(); { ValuatorMask mask; valuator_mask_set_range(&mask, 0, 5, valuators); - num_events = GetProximityEvents(darwinEvents, pDev, ev_type, &mask); - for(i=0; i 0) DarwinPokeEQ(); + QueueProximityEvents(darwinEvents, pDev, ev_type, &mask); + DarwinPokeEQ(); } darwinEvents_unlock(); } diff --git a/hw/xwin/winkeybd.c b/hw/xwin/winkeybd.c index 912e2de1c..cf0dea22e 100644 --- a/hw/xwin/winkeybd.c +++ b/hw/xwin/winkeybd.c @@ -473,7 +473,6 @@ void winSendKeyEvent (DWORD dwKey, Bool fDown) { EventListPtr events; - int i, nevents; /* * When alt-tabing between screens we can get phantom key up messages @@ -485,10 +484,7 @@ winSendKeyEvent (DWORD dwKey, Bool fDown) g_winKeyState[dwKey] = fDown; GetEventList(&events); - nevents = GetKeyboardEvents(events, g_pwinKeyboard, fDown ? KeyPress : KeyRelease, dwKey + MIN_KEYCODE, NULL); - - for (i = 0; i < nevents; i++) - mieqEnqueue(g_pwinKeyboard, (InternalEvent*)events[i].event); + QueueKeyboardEvents(events, g_pwinKeyboard, fDown ? KeyPress : KeyRelease, dwKey + MIN_KEYCODE, NULL); winDebug("winSendKeyEvent: dwKey: %d, fDown: %d, nEvents %d\n", dwKey, fDown, nevents); diff --git a/hw/xwin/winmouse.c b/hw/xwin/winmouse.c index 080e09626..0e36687cf 100644 --- a/hw/xwin/winmouse.c +++ b/hw/xwin/winmouse.c @@ -235,7 +235,6 @@ void winMouseButtonsSendEvent (int iEventType, int iButton) { EventListPtr events; - int i, nevents; ValuatorMask mask; if (g_winMouseButtonMap) @@ -243,11 +242,8 @@ winMouseButtonsSendEvent (int iEventType, int iButton) valuator_mask_zero(&mask); GetEventList(&events); - nevents = GetPointerEvents(events, g_pwinPointer, iEventType, iButton, - POINTER_RELATIVE, &mask); - - for (i = 0; i < nevents; i++) - mieqEnqueue(g_pwinPointer, (InternalEvent*)events[i].event); + QueuePointerEvents(events, g_pwinPointer, iEventType, iButton, + POINTER_RELATIVE, &mask); #if CYGDEBUG ErrorF("winMouseButtonsSendEvent: iEventType: %d, iButton: %d, nEvents %d\n", @@ -367,7 +363,6 @@ winMouseButtonsHandle (ScreenPtr pScreen, */ void winEnqueueMotion(int x, int y) { - int i, nevents; int valuators[2]; ValuatorMask mask; EventListPtr events; @@ -378,9 +373,7 @@ void winEnqueueMotion(int x, int y) valuator_mask_set_range(&mask, 0, 2, valuators); GetEventList(&events); - nevents = GetPointerEvents(events, g_pwinPointer, MotionNotify, 0, - POINTER_ABSOLUTE | POINTER_SCREEN, &mask); + QueuePointerEvents(events, g_pwinPointer, MotionNotify, 0, + POINTER_ABSOLUTE | POINTER_SCREEN, &mask); - for (i = 0; i < nevents; i++) - mieqEnqueue(g_pwinPointer, (InternalEvent*)events[i].event); } diff --git a/include/input.h b/include/input.h index 6799a53dd..100c00fc0 100644 --- a/include/input.h +++ b/include/input.h @@ -461,6 +461,14 @@ extern _X_EXPORT int GetPointerEvents( int flags, const ValuatorMask *mask); +extern _X_EXPORT void QueuePointerEvents( + EventListPtr events, + DeviceIntPtr pDev, + int type, + int buttons, + int flags, + const ValuatorMask *mask); + extern _X_EXPORT int GetKeyboardEvents( EventListPtr events, DeviceIntPtr pDev, @@ -468,12 +476,25 @@ extern _X_EXPORT int GetKeyboardEvents( int key_code, const ValuatorMask *mask); +extern _X_EXPORT void QueueKeyboardEvents( + EventListPtr events, + DeviceIntPtr pDev, + int type, + int key_code, + const ValuatorMask *mask); + extern int GetProximityEvents( EventListPtr events, DeviceIntPtr pDev, int type, const ValuatorMask *mask); +extern void QueueProximityEvents( + EventListPtr events, + DeviceIntPtr pDev, + int type, + const ValuatorMask *mask); + extern void PostSyntheticMotion( DeviceIntPtr pDev, int x, From 8670c46bdfdade64e63119d2ebbd5ef63b6fa2c3 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 14 Apr 2011 22:05:41 +1000 Subject: [PATCH 17/28] input: replace EventListPtr with InternalEvent array EventListPtr is a relic from pre-1.6, when we had protocol events in the event queue and thus events of varying size. Signed-off-by: Peter Hutterer Reviewed-by: Jeremy Huddleston --- Xext/xtest.c | 5 +- dix/devices.c | 6 +- dix/getevents.c | 101 +++++++++++++-------------------- hw/dmx/input/dmxevents.c | 8 +-- hw/kdrive/src/kinput.c | 2 +- hw/xfree86/common/xf86Priv.h | 2 +- hw/xfree86/common/xf86Xinput.c | 2 +- hw/xnest/Events.c | 2 +- hw/xnest/Init.c | 2 +- hw/xquartz/darwinEvents.c | 2 +- hw/xwin/winkeybd.c | 2 +- hw/xwin/winmouse.c | 4 +- include/input.h | 36 +++++------- mi/mieq.c | 47 +++------------ mi/mipointer.c | 5 +- xkb/xkbActions.c | 4 +- 16 files changed, 85 insertions(+), 145 deletions(-) diff --git a/Xext/xtest.c b/Xext/xtest.c index 18e1ef7ae..daa6430f1 100644 --- a/Xext/xtest.c +++ b/Xext/xtest.c @@ -52,6 +52,7 @@ #include "mipointer.h" #include "xserver-properties.h" #include "exevents.h" +#include "eventstr.h" #include "inpututils.h" #include "modinit.h" @@ -61,7 +62,7 @@ extern int DeviceValuator; /* XTest events are sent during request processing and may be interruped by * a SIGIO. We need a separate event list to avoid events overwriting each * other's memory */ -static EventListPtr xtest_evlist; +static InternalEvent* xtest_evlist; /** * xtestpointer @@ -428,7 +429,7 @@ ProcXTestFakeInput(ClientPtr client) } for (i = 0; i < nevents; i++) - mieqProcessDeviceEvent(dev, (InternalEvent*)(xtest_evlist+i)->event, NULL); + mieqProcessDeviceEvent(dev, &xtest_evlist[i], NULL); if (need_ptr_update) miPointerUpdateSprite(dev); diff --git a/dix/devices.c b/dix/devices.c index 7968c7357..9a4498b9f 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -2368,7 +2368,7 @@ RecalculateMasterButtons(DeviceIntPtr slave) void ReleaseButtonsAndKeys(DeviceIntPtr dev) { - EventListPtr eventlist = InitEventList(GetMaximumEventsNum()); + InternalEvent* eventlist = InitEventList(GetMaximumEventsNum()); ButtonClassPtr b = dev->button; KeyClassPtr k = dev->key; int i, j, nevents; @@ -2383,7 +2383,7 @@ ReleaseButtonsAndKeys(DeviceIntPtr dev) { nevents = GetPointerEvents(eventlist, dev, ButtonRelease, i, 0, NULL); for (j = 0; j < nevents; j++) - mieqProcessDeviceEvent(dev, (InternalEvent*)(eventlist+j)->event, NULL); + mieqProcessDeviceEvent(dev, &eventlist[j], NULL); } } @@ -2394,7 +2394,7 @@ ReleaseButtonsAndKeys(DeviceIntPtr dev) { nevents = GetKeyboardEvents(eventlist, dev, KeyRelease, i, NULL); for (j = 0; j < nevents; j++) - mieqProcessDeviceEvent(dev, (InternalEvent*)(eventlist+j)->event, NULL); + mieqProcessDeviceEvent(dev, &eventlist[j], NULL); } } diff --git a/dix/getevents.c b/dix/getevents.c index 68a5224dc..e8c2f45b0 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -68,15 +68,15 @@ /* Number of motion history events to store. */ #define MOTION_HISTORY_SIZE 256 -/* InputEventList is the container list for all input events generated by the +/* InputEventList is the storage for input events generated by the * DDX. The DDX is expected to call GetEventList() and then pass the list into * Get{Pointer|Keyboard}Events. */ -EventListPtr InputEventList = NULL; +InternalEvent* InputEventList = NULL; int InputEventListLen = 0; int -GetEventList(EventListPtr* list) +GetEventList(InternalEvent** list) { *list = InputEventList; return InputEventListLen; @@ -224,7 +224,7 @@ set_valuators(DeviceIntPtr dev, DeviceEvent* event, ValuatorMask *mask) } void -CreateClassesChangedEvent(EventList* event, +CreateClassesChangedEvent(InternalEvent* event, DeviceIntPtr master, DeviceIntPtr slave, int type) @@ -233,7 +233,7 @@ CreateClassesChangedEvent(EventList* event, DeviceChangedEvent *dce; CARD32 ms = GetTimeInMillis(); - dce = (DeviceChangedEvent*)event->event; + dce = &event->changed_event; memset(dce, 0, sizeof(DeviceChangedEvent)); dce->deviceid = slave->id; dce->masterid = master->id; @@ -677,15 +677,15 @@ clipValuators(DeviceIntPtr pDev, ValuatorMask *mask) * is done in the event processing). * Pull in the coordinates from the MD if necessary. * - * @param events Pointer to a pre-allocated event list. + * @param events Pointer to a pre-allocated event array. * @param dev The slave device that generated an event. * @param type Either DEVCHANGE_POINTER_EVENT and/or DEVCHANGE_KEYBOARD_EVENT * @param num_events The current number of events, returns the number of * events if a DCCE was generated. * @return The updated @events pointer. */ -EventListPtr -UpdateFromMaster(EventListPtr events, DeviceIntPtr dev, int type, int *num_events) +InternalEvent* +UpdateFromMaster(InternalEvent* events, DeviceIntPtr dev, int type, int *num_events) { DeviceIntPtr master; @@ -926,12 +926,11 @@ updateHistory(DeviceIntPtr dev, ValuatorMask *mask, CARD32 ms) } static void -queueEventList(DeviceIntPtr device, EventList *events, int nevents) +queueEventList(DeviceIntPtr device, InternalEvent *events, int nevents) { int i; - for (i = 0; i < nevents; i++) - mieqEnqueue(device, (InternalEvent*)((events + i)->event)); + mieqEnqueue(device, &events[i]); } /** @@ -949,7 +948,7 @@ queueEventList(DeviceIntPtr device, EventList *events, int nevents) * */ void -QueueKeyboardEvents(EventList *events, DeviceIntPtr device, int type, +QueueKeyboardEvents(InternalEvent *events, DeviceIntPtr device, int type, int keycode, const ValuatorMask *mask) { int nevents; @@ -962,12 +961,13 @@ QueueKeyboardEvents(EventList *events, DeviceIntPtr device, int type, * Returns a set of InternalEvents for KeyPress/KeyRelease, optionally * also with valuator events. * - * events is not NULL-terminated; the return value is the number of events. - * The DDX is responsible for allocating the event structure in the first - * place via GetMaximumEventsNum(), and for freeing it. + * The DDX is responsible for allocating the event list in the first + * place via InitEventList(), and for freeing it. + * + * @return the number of events written into events. */ int -GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, +GetKeyboardEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int key_code, const ValuatorMask *mask_in) { int num_events = 0; CARD32 ms = 0; @@ -1000,7 +1000,7 @@ GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, ms = GetTimeInMillis(); - raw = (RawDeviceEvent*)events->event; + raw = &events->raw_event; events++; num_events++; @@ -1013,7 +1013,7 @@ GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, set_raw_valuators(raw, &mask, raw->valuators.data); - event = (DeviceEvent*) events->event; + event = &events->device_event; init_event(pDev, event, ms); event->detail.key = key_code; @@ -1034,37 +1034,16 @@ GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, } /** - * Initialize an event list and fill with 32 byte sized events. + * Initialize an event array large enough for num_events arrays. * This event list is to be passed into GetPointerEvents() and * GetKeyboardEvents(). * * @param num_events Number of elements in list. */ -EventListPtr +InternalEvent* InitEventList(int num_events) { - EventListPtr events; - int i; - - events = (EventListPtr)calloc(num_events, sizeof(EventList)); - if (!events) - return NULL; - - for (i = 0; i < num_events; i++) - { - events[i].evlen = sizeof(InternalEvent); - events[i].event = calloc(1, sizeof(InternalEvent)); - if (!events[i].event) - { - /* rollback */ - while(i--) - free(events[i].event); - free(events); - events = NULL; - break; - } - } - + InternalEvent *events = calloc(num_events, sizeof(InternalEvent)); return events; } @@ -1075,12 +1054,8 @@ InitEventList(int num_events) * @param num_events Number of elements in list. */ void -FreeEventList(EventListPtr list, int num_events) +FreeEventList(InternalEvent *list, int num_events) { - if (!list) - return; - while(num_events--) - free(list[num_events].event); free(list); } @@ -1101,7 +1076,7 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask, int *x, int *y) * * FIXME: don't require the event list to be passed in. * - * @param events Event list used as temporary storage + * @param events Set of events list used as temporary storage * @param device The device to generate the event for * @param type Event type, one of ButtonPress, ButtonRelease, MotionNotify * @param buttons Button number of the buttons modified. Must be 0 for @@ -1110,7 +1085,7 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask, int *x, int *y) * @param mask Valuator mask for valuators present for this event. */ void -QueuePointerEvents(EventList *events, DeviceIntPtr device, int type, +QueuePointerEvents(InternalEvent *events, DeviceIntPtr device, int type, int buttons, int flags, const ValuatorMask *mask) { int nevents; @@ -1120,11 +1095,10 @@ QueuePointerEvents(EventList *events, DeviceIntPtr device, int type, } /** - * Generate a series of InternalEvents (filled into the EventList) - * representing pointer motion, or button presses. + * Generate a series of InternalEvents representing pointer motion, or + * button presses. * - * events is not NULL-terminated; the return value is the number of events. - * The DDX is responsible for allocating the event structure in the first + * The DDX is responsible for allocating the events in the first * place via InitEventList() and GetMaximumEventsNum(), and for freeing it. * * In the generated events rootX/Y will be in absolute screen coords and @@ -1134,9 +1108,11 @@ QueuePointerEvents(EventList *events, DeviceIntPtr device, int type, * last.valuators[x] of the master device is in absolute screen coords. * * master->last.valuators[x] for x > 2 is undefined. + * + * @return the number of events written into events. */ int -GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons, +GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int buttons, int flags, const ValuatorMask *mask_in) { int num_events = 1; CARD32 ms; @@ -1174,7 +1150,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons, events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events); - raw = (RawDeviceEvent*)events->event; + raw = &events->raw_event; events++; num_events++; @@ -1243,7 +1219,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons, clipValuators(pDev, &mask); - event = (DeviceEvent*) events->event; + event = &events->device_event; init_event(pDev, event, ms); if (type == MotionNotify) { @@ -1286,7 +1262,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons, * */ void -QueueProximityEvents(EventList *events, DeviceIntPtr device, int type, +QueueProximityEvents(InternalEvent *events, DeviceIntPtr device, int type, const ValuatorMask *mask) { int nevents; @@ -1299,12 +1275,13 @@ QueueProximityEvents(EventList *events, DeviceIntPtr device, int type, * Generate ProximityIn/ProximityOut InternalEvents, accompanied by * valuators. * - * events is not NULL-terminated; the return value is the number of events. - * The DDX is responsible for allocating the event structure in the first - * place via GetMaximumEventsNum(), and for freeing it. + * The DDX is responsible for allocating the events in the first place via + * InitEventList(), and for freeing it. + * + * @return the number of events written into events. */ int -GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type, const ValuatorMask *mask_in) +GetProximityEvents(InternalEvent *events, DeviceIntPtr pDev, int type, const ValuatorMask *mask_in) { int num_events = 1, i; DeviceEvent *event; @@ -1336,7 +1313,7 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type, const Valuato events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events); - event = (DeviceEvent *) events->event; + event = &events->device_event; init_event(pDev, event, GetTimeInMillis()); event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut; diff --git a/hw/dmx/input/dmxevents.c b/hw/dmx/input/dmxevents.c index 3f9035cdd..8aa1b8036 100644 --- a/hw/dmx/input/dmxevents.c +++ b/hw/dmx/input/dmxevents.c @@ -177,7 +177,7 @@ static void enqueueMotion(DevicePtr pDev, int x, int y) GETDMXLOCALFROMPDEV; DeviceIntPtr p = dmxLocal->pDevice; int valuators[3]; - EventListPtr events; + InternalEvent* events; int detail = 0; /* XXX should this be mask of pressed buttons? */ ValuatorMask mask; valuators[0] = x; @@ -290,7 +290,7 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal, int thisX = 0; int thisY = 0; int count; - EventListPtr events; + InternalEvent* events; ValuatorMask mask; memset(xE, 0, sizeof(xE)); @@ -389,7 +389,7 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal, XDeviceMotionEvent *me = (XDeviceMotionEvent *)e; DeviceIntPtr pDevice = dmxLocal->pDevice; int valuators[MAX_VALUATORS]; - EventListPtr events; + InternalEvent* events; ValuatorMask mask; if (!e) @@ -652,7 +652,7 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym, xEvent xE; DeviceIntPtr p = dmxLocal->pDevice; int valuators[3]; - EventListPtr events; + InternalEvent* events; ValuatorMask mask; DMXDBG2("dmxEnqueue: Enqueuing type=%d detail=0x%0x\n", type, detail); diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c index 521542c91..62e8f7866 100644 --- a/hw/kdrive/src/kinput.c +++ b/hw/kdrive/src/kinput.c @@ -66,7 +66,7 @@ static struct KdConfigDevice *kdConfigPointers = NULL; static KdKeyboardDriver *kdKeyboardDrivers = NULL; static KdPointerDriver *kdPointerDrivers = NULL; -static EventListPtr kdEvents = NULL; +static InternalEvent* kdEvents = NULL; static Bool kdInputEnabled; static Bool kdOffScreen; diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h index 7137a5363..015e12c3f 100644 --- a/hw/xfree86/common/xf86Priv.h +++ b/hw/xfree86/common/xf86Priv.h @@ -149,7 +149,7 @@ extern _X_EXPORT int xf86SetLogVerbosity(int verb); extern _X_EXPORT Bool xf86CallDriverProbe( struct _DriverRec * drv, Bool detect_only ); /* xf86Xinput.c */ -extern _X_EXPORT EventList *xf86Events; +extern _X_EXPORT InternalEvent *xf86Events; #endif /* _NO_XF86_PROTOTYPES */ diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c index 111f16f50..9827661d6 100644 --- a/hw/xfree86/common/xf86Xinput.c +++ b/hw/xfree86/common/xf86Xinput.c @@ -99,7 +99,7 @@ return; \ } -EventListPtr xf86Events = NULL; +InternalEvent* xf86Events = NULL; static int xf86InputDevicePostInit(DeviceIntPtr dev); diff --git a/hw/xnest/Events.c b/hw/xnest/Events.c index 574e4e415..bbd70bf03 100644 --- a/hw/xnest/Events.c +++ b/hw/xnest/Events.c @@ -43,7 +43,7 @@ is" without express or implied warranty. CARD32 lastEventTime = 0; -extern EventList *xnestEvents; +extern InternalEvent *xnestEvents; void ProcessInputEvents(void) diff --git a/hw/xnest/Init.c b/hw/xnest/Init.c index 8a90cc65e..f8637f2ab 100644 --- a/hw/xnest/Init.c +++ b/hw/xnest/Init.c @@ -45,7 +45,7 @@ is" without express or implied warranty. Bool xnestDoFullGeneration = True; -EventList *xnestEvents = NULL; +InternalEvent *xnestEvents = NULL; void InitOutput(ScreenInfo *screenInfo, int argc, char *argv[]) diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index 99956e012..6736e3d69 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -88,7 +88,7 @@ static pthread_mutex_t fd_add_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t fd_add_ready_cond = PTHREAD_COND_INITIALIZER; static pthread_t fd_add_tid = NULL; -static EventListPtr darwinEvents = NULL; +static InternalEvent* darwinEvents = NULL; static pthread_mutex_t mieq_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t mieq_ready_cond = PTHREAD_COND_INITIALIZER; diff --git a/hw/xwin/winkeybd.c b/hw/xwin/winkeybd.c index cf0dea22e..8b6be0266 100644 --- a/hw/xwin/winkeybd.c +++ b/hw/xwin/winkeybd.c @@ -472,7 +472,7 @@ winKeybdReleaseKeys (void) void winSendKeyEvent (DWORD dwKey, Bool fDown) { - EventListPtr events; + InternalEvent* events; /* * When alt-tabing between screens we can get phantom key up messages diff --git a/hw/xwin/winmouse.c b/hw/xwin/winmouse.c index 0e36687cf..aaa4d4b99 100644 --- a/hw/xwin/winmouse.c +++ b/hw/xwin/winmouse.c @@ -234,7 +234,7 @@ winMouseWheel (ScreenPtr pScreen, int iDeltaZ) void winMouseButtonsSendEvent (int iEventType, int iButton) { - EventListPtr events; + InternalEvent* events; ValuatorMask mask; if (g_winMouseButtonMap) @@ -365,7 +365,7 @@ void winEnqueueMotion(int x, int y) { int valuators[2]; ValuatorMask mask; - EventListPtr events; + InternalEvent* events; miPointerSetPosition(g_pwinPointer, POINTER_RELATIVE, &x, &y); valuators[0] = x; diff --git a/include/input.h b/include/input.h index 100c00fc0..3c7740dce 100644 --- a/include/input.h +++ b/include/input.h @@ -109,18 +109,8 @@ typedef union _GrabMask GrabMask; typedef struct _ValuatorMask ValuatorMask; -typedef struct _EventList { - xEvent* event; - int evlen; /* length of allocated memory for event in bytes. This is not - the actual length of the event. The event's actual length is - 32 for standard events or 32 + - ((xGenericEvent*)event)->length * 4 for GenericEvents. - For events in the EQ, the length is - ((InternalEvent*)event)->u.any.length */ -} EventList, *EventListPtr; - /* The DIX stores incoming input events in this list */ -extern EventListPtr InputEventList; +extern InternalEvent* InputEventList; extern int InputEventListLen; typedef int (*DeviceProc)( @@ -439,22 +429,22 @@ extern _X_EXPORT void CloseInput(void); extern _X_EXPORT int GetMaximumEventsNum(void); -extern _X_EXPORT int GetEventList(EventListPtr* list); -extern _X_EXPORT EventListPtr InitEventList(int num_events); -extern _X_EXPORT void FreeEventList(EventListPtr list, int num_events); +extern _X_EXPORT int GetEventList(InternalEvent** list); +extern _X_EXPORT InternalEvent *InitEventList(int num_events); +extern _X_EXPORT void FreeEventList(InternalEvent *list, int num_events); -extern void CreateClassesChangedEvent(EventListPtr event, +extern void CreateClassesChangedEvent(InternalEvent *event, DeviceIntPtr master, DeviceIntPtr slave, int type); -extern EventListPtr UpdateFromMaster( - EventListPtr events, +extern InternalEvent * UpdateFromMaster( + InternalEvent *events, DeviceIntPtr pDev, int type, int *num_events); extern _X_EXPORT int GetPointerEvents( - EventListPtr events, + InternalEvent *events, DeviceIntPtr pDev, int type, int buttons, @@ -462,7 +452,7 @@ extern _X_EXPORT int GetPointerEvents( const ValuatorMask *mask); extern _X_EXPORT void QueuePointerEvents( - EventListPtr events, + InternalEvent *events, DeviceIntPtr pDev, int type, int buttons, @@ -470,27 +460,27 @@ extern _X_EXPORT void QueuePointerEvents( const ValuatorMask *mask); extern _X_EXPORT int GetKeyboardEvents( - EventListPtr events, + InternalEvent *events, DeviceIntPtr pDev, int type, int key_code, const ValuatorMask *mask); extern _X_EXPORT void QueueKeyboardEvents( - EventListPtr events, + InternalEvent *events, DeviceIntPtr pDev, int type, int key_code, const ValuatorMask *mask); extern int GetProximityEvents( - EventListPtr events, + InternalEvent *events, DeviceIntPtr pDev, int type, const ValuatorMask *mask); extern void QueueProximityEvents( - EventListPtr events, + InternalEvent *events, DeviceIntPtr pDev, int type, const ValuatorMask *mask); diff --git a/mi/mieq.c b/mi/mieq.c index 3e6f93110..236ffcc3b 100644 --- a/mi/mieq.c +++ b/mi/mieq.c @@ -64,7 +64,7 @@ in this Software without prior written authorization from The Open Group. #define DequeueScreen(dev) dev->spriteInfo->sprite->pDequeueScreen typedef struct _Event { - EventListPtr events; + InternalEvent* events; ScreenPtr pScreen; DeviceIntPtr pDev; /* device this event _originated_ from */ } EventRec, *EventPtr; @@ -111,7 +111,7 @@ mieqInit(void) for (i = 0; i < QUEUE_SIZE; i++) { if (miEventQueue.events[i].events == NULL) { - EventListPtr evlist = InitEventList(1); + InternalEvent* evlist = InitEventList(1); if (!evlist) FatalError("Could not allocate event queue.\n"); miEventQueue.events[i].events = evlist; @@ -146,7 +146,7 @@ void mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e) { unsigned int oldtail = miEventQueue.tail; - EventListPtr evt; + InternalEvent* evt; int isMotion = 0; int evlen; Time time; @@ -188,21 +188,7 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e) evlen = e->any.length; evt = miEventQueue.events[oldtail].events; - if (evt->evlen < evlen) - { - evt->evlen = evlen; - evt->event = realloc(evt->event, evt->evlen); - if (!evt->event) - { - ErrorF("[mi] Running out of memory. Tossing event.\n"); -#ifdef XQUARTZ - pthread_mutex_unlock(&miEventQueueMutex); -#endif - return; - } - } - - memcpy(evt->event, e, evlen); + memcpy(evt, e, evlen); time = e->any.time; /* Make sure that event times don't go backwards - this @@ -211,7 +197,7 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e) miEventQueue.lastEventTime - time < 10000) e->any.time = miEventQueue.lastEventTime; - miEventQueue.lastEventTime = ((InternalEvent*)evt->event)->any.time; + miEventQueue.lastEventTime = evt->any.time; miEventQueue.events[oldtail].pScreen = pDev ? EnqueueScreen(pDev) : NULL; miEventQueue.events[oldtail].pDev = pDev; @@ -431,10 +417,8 @@ void mieqProcessInputEvents(void) { EventRec *e = NULL; - int evlen; ScreenPtr screen; - static InternalEvent *event = NULL; - static size_t event_size = 0; + static InternalEvent event; DeviceIntPtr dev = NULL, master = NULL; @@ -445,20 +429,7 @@ mieqProcessInputEvents(void) while (miEventQueue.head != miEventQueue.tail) { e = &miEventQueue.events[miEventQueue.head]; - evlen = e->events->evlen; - if(evlen > event_size) - { - event = realloc(event, evlen); - event_size = evlen; - } - - - if (!event) - FatalError("[mi] No memory left for event processing.\n"); - - memcpy(event, e->events->event, evlen); - - + event = *e->events; dev = e->pDev; screen = e->pScreen; @@ -480,10 +451,10 @@ mieqProcessInputEvents(void) DPMSSet(serverClient, DPMSModeOn); #endif - mieqProcessDeviceEvent(dev, event, screen); + mieqProcessDeviceEvent(dev, &event, screen); /* Update the sprite now. Next event may be from different device. */ - if (event->any.type == ET_Motion && master) + if (event.any.type == ET_Motion && master) miPointerUpdateSprite(dev); #ifdef XQUARTZ diff --git a/mi/mipointer.c b/mi/mipointer.c index db243810c..322be9e44 100644 --- a/mi/mipointer.c +++ b/mi/mipointer.c @@ -63,6 +63,7 @@ in this Software without prior written authorization from The Open Group. # include "dixstruct.h" # include "inputstr.h" # include "inpututils.h" +# include "eventstr.h" DevPrivateKeyRec miPointerScreenKeyRec; @@ -99,7 +100,7 @@ static void miPointerDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen); static void miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y); -static EventList* events; /* for WarpPointer MotionNotifies */ +static InternalEvent* events; /* for WarpPointer MotionNotifies */ Bool miPointerInitialize (ScreenPtr pScreen, @@ -689,7 +690,7 @@ miPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) darwinEvents_lock(); #endif for (i = 0; i < nevents; i++) - mieqEnqueue(pDev, (InternalEvent*)events[i].event); + mieqEnqueue(pDev, &events[i]); #ifdef XQUARTZ darwinEvents_unlock(); #endif diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c index c4336d7b4..4b5405ab0 100644 --- a/xkb/xkbActions.c +++ b/xkb/xkbActions.c @@ -1351,7 +1351,7 @@ static void InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, ValuatorMask *mask) { ScreenPtr pScreen; - EventListPtr events; + InternalEvent* events; int nevents, i; DeviceIntPtr ptr, mpointer, lastSlave = NULL; Bool saveWait; @@ -1377,7 +1377,7 @@ InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, Valuat OsReleaseSignals(); for (i = 0; i < nevents; i++) - mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL); + mieqProcessDeviceEvent(ptr, &events[i], NULL); FreeEventList(events, GetMaximumEventsNum()); From 20fb07f436f7d4a0f330b2067a93a5a4829fccf5 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 15 Apr 2011 10:07:10 +1000 Subject: [PATCH 18/28] input: remove DDX event list handling The current approach to event posting required the DDX to request the event list (allocated by the DIX) and then pass that list into QueuePointerEvent and friends. Remove this step and use the DIX event list directly. This means that QueuePointerEvent is not reentrant but it wasn't before anyway. Signed-off-by: Peter Hutterer Reviewed-by: Jeremy Huddleston --- dix/events.c | 6 ++--- dix/getevents.c | 43 ++++++++++++++-------------------- hw/dmx/input/dmxevents.c | 28 +++++++--------------- hw/kdrive/src/kinput.c | 11 +++------ hw/xfree86/common/xf86Events.c | 2 +- hw/xfree86/common/xf86Init.c | 2 -- hw/xfree86/common/xf86Priv.h | 3 --- hw/xfree86/common/xf86Xinput.c | 11 ++++----- hw/xnest/Events.c | 14 ++++------- hw/xnest/Init.c | 4 ---- hw/xquartz/darwinEvents.c | 7 +++--- hw/xwin/winkeybd.c | 3 +-- hw/xwin/winmouse.c | 8 ++----- include/input.h | 5 ---- 14 files changed, 46 insertions(+), 101 deletions(-) diff --git a/dix/events.c b/dix/events.c index 895ab4035..276bc75fa 100644 --- a/dix/events.c +++ b/dix/events.c @@ -5035,8 +5035,7 @@ InitEvents(void) DontPropagateRefCnts[i] = 0; } - InputEventListLen = GetMaximumEventsNum(); - InputEventList = InitEventList(InputEventListLen); + InputEventList = InitEventList(GetMaximumEventsNum()); if (!InputEventList) FatalError("[dix] Failed to allocate input event list.\n"); } @@ -5044,8 +5043,7 @@ InitEvents(void) void CloseDownEvents(void) { - FreeEventList(InputEventList, InputEventListLen); - InputEventListLen = 0; + FreeEventList(InputEventList, GetMaximumEventsNum()); InputEventList = NULL; } diff --git a/dix/getevents.c b/dix/getevents.c index e8c2f45b0..13789f6a2 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -68,19 +68,12 @@ /* Number of motion history events to store. */ #define MOTION_HISTORY_SIZE 256 -/* InputEventList is the storage for input events generated by the - * DDX. The DDX is expected to call GetEventList() and then pass the list into - * Get{Pointer|Keyboard}Events. +/** + * InputEventList is the storage for input events generated by + * QueuePointerEvents, QueueKeyboardEvents, and QueueProximityEvents. + * This list is allocated on startup by the DIX. */ InternalEvent* InputEventList = NULL; -int InputEventListLen = 0; - -int -GetEventList(InternalEvent** list) -{ - *list = InputEventList; - return InputEventListLen; -} /** * Pick some arbitrary size for Xi motion history. @@ -937,10 +930,10 @@ queueEventList(DeviceIntPtr device, InternalEvent *events, int nevents) * Generate internal events representing this keyboard event and enqueue * them on the event queue. * - * FIXME: don't require the event list to be passed in. + * This function is not reentrant. Disable signals before calling. + * * FIXME: flags for relative/abs motion? * - * @param events Event list used as temporary storage * @param device The device to generate the event for * @param type Event type, one of KeyPress or KeyRelease * @param keycode Key code of the pressed/released key @@ -948,13 +941,13 @@ queueEventList(DeviceIntPtr device, InternalEvent *events, int nevents) * */ void -QueueKeyboardEvents(InternalEvent *events, DeviceIntPtr device, int type, +QueueKeyboardEvents(DeviceIntPtr device, int type, int keycode, const ValuatorMask *mask) { int nevents; - nevents = GetKeyboardEvents(events, device, type, keycode, mask); - queueEventList(device, events, nevents); + nevents = GetKeyboardEvents(InputEventList, device, type, keycode, mask); + queueEventList(device, InputEventList, nevents); } /** @@ -1074,9 +1067,8 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask, int *x, int *y) * Generate internal events representing this pointer event and enqueue them * on the event queue. * - * FIXME: don't require the event list to be passed in. + * This function is not reentrant. Disable signals before calling. * - * @param events Set of events list used as temporary storage * @param device The device to generate the event for * @param type Event type, one of ButtonPress, ButtonRelease, MotionNotify * @param buttons Button number of the buttons modified. Must be 0 for @@ -1085,13 +1077,13 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask, int *x, int *y) * @param mask Valuator mask for valuators present for this event. */ void -QueuePointerEvents(InternalEvent *events, DeviceIntPtr device, int type, +QueuePointerEvents(DeviceIntPtr device, int type, int buttons, int flags, const ValuatorMask *mask) { int nevents; - nevents = GetPointerEvents(events, device, type, buttons, flags, mask); - queueEventList(device, events, nevents); + nevents = GetPointerEvents(InputEventList, device, type, buttons, flags, mask); + queueEventList(device, InputEventList, nevents); } /** @@ -1252,9 +1244,8 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int buttons * Generate internal events representing this proximity event and enqueue * them on the event queue. * - * FIXME: don't require the event list to be passed in. + * This function is not reentrant. Disable signals before calling. * - * @param events Event list used as temporary storage * @param device The device to generate the event for * @param type Event type, one of ProximityIn or ProximityOut * @param keycode Key code of the pressed/released key @@ -1262,13 +1253,13 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int buttons * */ void -QueueProximityEvents(InternalEvent *events, DeviceIntPtr device, int type, +QueueProximityEvents(DeviceIntPtr device, int type, const ValuatorMask *mask) { int nevents; - nevents = GetProximityEvents(events, device, type, mask); - queueEventList(device, events, nevents); + nevents = GetProximityEvents(InputEventList, device, type, mask); + queueEventList(device, InputEventList, nevents); } /** diff --git a/hw/dmx/input/dmxevents.c b/hw/dmx/input/dmxevents.c index 8aa1b8036..41bc4bf2d 100644 --- a/hw/dmx/input/dmxevents.c +++ b/hw/dmx/input/dmxevents.c @@ -177,15 +177,13 @@ static void enqueueMotion(DevicePtr pDev, int x, int y) GETDMXLOCALFROMPDEV; DeviceIntPtr p = dmxLocal->pDevice; int valuators[3]; - InternalEvent* events; int detail = 0; /* XXX should this be mask of pressed buttons? */ ValuatorMask mask; valuators[0] = x; valuators[1] = y; valuator_mask_set_range(&mask, 0, 2, valuators); - GetEventList(&events); - QueuePointerEvents(events, p, MotionNotify, detail, + QueuePointerEvents(p, MotionNotify, detail, POINTER_ABSOLUTE | POINTER_SCREEN, &mask); return; } @@ -290,7 +288,6 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal, int thisX = 0; int thisY = 0; int count; - InternalEvent* events; ValuatorMask mask; memset(xE, 0, sizeof(xE)); @@ -372,8 +369,7 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal, if (block) dmxSigioBlock(); valuator_mask_set_range(&mask, firstAxis, axesCount, v); - GetEventList(&events); - QueuePointerEvents(events, pDevice, MotionNotify, 0, + QueuePointerEvents(pDevice, MotionNotify, 0, POINTER_ABSOLUTE, &mask); if (block) @@ -389,7 +385,6 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal, XDeviceMotionEvent *me = (XDeviceMotionEvent *)e; DeviceIntPtr pDevice = dmxLocal->pDevice; int valuators[MAX_VALUATORS]; - InternalEvent* events; ValuatorMask mask; if (!e) @@ -446,8 +441,7 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal, valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count, valuators); if (block) dmxSigioBlock(); - GetEventList(&events); - QueueKeyboardEvents(events, pDevice, event, ke->keycode, &mask); + QueueKeyboardEvents(pDevice, event, ke->keycode, &mask); if (block) dmxSigioUnblock(); break; @@ -457,8 +451,7 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal, valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count, valuators); if (block) dmxSigioBlock(); - GetEventList(&events); - QueuePointerEvents(events, pDevice, event, ke->keycode, + QueuePointerEvents(pDevice, event, ke->keycode, POINTER_ABSOLUTE, &mask); if (block) dmxSigioUnblock(); @@ -469,8 +462,7 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal, valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count, valuators); if (block) dmxSigioBlock(); - GetEventList(&events); - QueueProximityEvents(events, pDevice, event, &mask); + QueueProximityEvents(pDevice, event, &mask); if (block) dmxSigioUnblock(); break; @@ -652,7 +644,6 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym, xEvent xE; DeviceIntPtr p = dmxLocal->pDevice; int valuators[3]; - InternalEvent* events; ValuatorMask mask; DMXDBG2("dmxEnqueue: Enqueuing type=%d detail=0x%0x\n", type, detail); @@ -667,27 +658,24 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym, if (dmxLocal->sendsCore && dmxLocal != dmxLocalCoreKeyboard) xE.u.u.detail = dmxFixup(pDev, detail, keySym); - GetEventList(&events); /*ErrorF("KEY %d sym %d\n", detail, (int) keySym);*/ - QueueKeyboardEvents(events, p, type, detail, NULL); + QueueKeyboardEvents(p, type, detail, NULL); return; case ButtonPress: case ButtonRelease: detail = dmxGetButtonMapping(dmxLocal, detail); valuator_mask_zero(&mask); - GetEventList(&events); - QueuePointerEvents(events, p, type, detail, + QueuePointerEvents(p, type, detail, POINTER_ABSOLUTE | POINTER_SCREEN, &mask); return; case MotionNotify: - GetEventList(&events); valuators[0] = e->xmotion.x; valuators[1] = e->xmotion.y; valuators[2] = e->xmotion.state; /* FIXME: WTF?? */ valuator_mask_set_range(&mask, 0, 3, valuators); - QueuePointerEvents(events, p, type, detail, + QueuePointerEvents(p, type, detail, POINTER_ABSOLUTE | POINTER_SCREEN, &mask); return; diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c index 62e8f7866..cdf55d7f9 100644 --- a/hw/kdrive/src/kinput.c +++ b/hw/kdrive/src/kinput.c @@ -66,8 +66,6 @@ static struct KdConfigDevice *kdConfigPointers = NULL; static KdKeyboardDriver *kdKeyboardDrivers = NULL; static KdPointerDriver *kdPointerDrivers = NULL; -static InternalEvent* kdEvents = NULL; - static Bool kdInputEnabled; static Bool kdOffScreen; static unsigned long kdOffScreenTime; @@ -1803,8 +1801,7 @@ KdReleaseAllKeys (void) key++) { if (key_is_down(ki->dixdev, key, KEY_POSTED | KEY_PROCESSED)) { KdHandleKeyboardEvent(ki, KeyRelease, key); - GetEventList(&kdEvents); - QueueGetKeyboardEvents(kdEvents, ki->dixdev, KeyRelease, key, NULL); + QueueGetKeyboardEvents(ki->dixdev, KeyRelease, key, NULL); } } } @@ -1860,8 +1857,7 @@ KdEnqueueKeyboardEvent(KdKeyboardInfo *ki, else type = KeyPress; - GetEventList(&kdEvents); - QueueKeyboardEvents(kdEvents, ki->dixdev, type, key_code, NULL); + QueueKeyboardEvents(ki->dixdev, type, key_code, NULL); } else { ErrorF("driver %s wanted to post scancode %d outside of [%d, %d]!\n", @@ -1969,8 +1965,7 @@ _KdEnqueuePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z, valuator_mask_set_range(&mask, 0, 3, valuators); - GetEventList(&kdEvents); - QueuePointerEvents(kdEvents, pi->dixdev, type, b, absrel, &mask); + QueuePointerEvents(pi->dixdev, type, b, absrel, &mask); } void diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c index 6402d72b3..c4a4db9be 100644 --- a/hw/xfree86/common/xf86Events.c +++ b/hw/xfree86/common/xf86Events.c @@ -399,7 +399,7 @@ xf86ReleaseKeys(DeviceIntPtr pDev) i++) { if (key_is_down(pDev, i, KEY_POSTED)) { sigstate = xf86BlockSIGIO (); - QueueKeyboardEvents(xf86Events, pDev, KeyRelease, i, NULL); + QueueKeyboardEvents(pDev, KeyRelease, i, NULL); xf86UnblockSIGIO(sigstate); } } diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c index 0b36163c0..53f763aaf 100644 --- a/hw/xfree86/common/xf86Init.c +++ b/hw/xfree86/common/xf86Init.c @@ -806,8 +806,6 @@ InitInput(int argc, char **argv) mieqInit(); - GetEventList(&xf86Events); - /* Initialize all configured input devices */ for (pDev = xf86ConfigLayout.inputs; pDev && *pDev; pDev++) { /* Replace obsolete keyboard driver with kbd */ diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h index 015e12c3f..5d91ab367 100644 --- a/hw/xfree86/common/xf86Priv.h +++ b/hw/xfree86/common/xf86Priv.h @@ -148,9 +148,6 @@ extern _X_EXPORT int xf86SetVerbosity(int verb); extern _X_EXPORT int xf86SetLogVerbosity(int verb); extern _X_EXPORT Bool xf86CallDriverProbe( struct _DriverRec * drv, Bool detect_only ); -/* xf86Xinput.c */ -extern _X_EXPORT InternalEvent *xf86Events; - #endif /* _NO_XF86_PROTOTYPES */ diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c index 9827661d6..e7e1ce1f0 100644 --- a/hw/xfree86/common/xf86Xinput.c +++ b/hw/xfree86/common/xf86Xinput.c @@ -99,8 +99,6 @@ return; \ } -InternalEvent* xf86Events = NULL; - static int xf86InputDevicePostInit(DeviceIntPtr dev); @@ -1049,7 +1047,7 @@ xf86PostMotionEventM(DeviceIntPtr device, } #endif - QueuePointerEvents(xf86Events, device, MotionNotify, 0, flags, mask); + QueuePointerEvents(device, MotionNotify, 0, flags, mask); } void @@ -1094,8 +1092,7 @@ xf86PostProximityEventM(DeviceIntPtr device, int is_in, const ValuatorMask *mask) { - QueueProximityEvents(xf86Events, device, - is_in ? ProximityIn : ProximityOut, mask); + QueueProximityEvents(device, is_in ? ProximityIn : ProximityOut, mask); } void @@ -1166,7 +1163,7 @@ xf86PostButtonEventM(DeviceIntPtr device, } #endif - QueuePointerEvents(xf86Events, device, + QueuePointerEvents(device, is_down ? ButtonPress : ButtonRelease, button, flags, mask); } @@ -1233,7 +1230,7 @@ xf86PostKeyEventM(DeviceIntPtr device, } #endif - QueueKeyboardEvents(xf86Events, device, + QueueKeyboardEvents(device, is_down ? KeyPress : KeyRelease, key_code, mask); } diff --git a/hw/xnest/Events.c b/hw/xnest/Events.c index bbd70bf03..619427ded 100644 --- a/hw/xnest/Events.c +++ b/hw/xnest/Events.c @@ -43,8 +43,6 @@ is" without express or implied warranty. CARD32 lastEventTime = 0; -extern InternalEvent *xnestEvents; - void ProcessInputEvents(void) { @@ -104,9 +102,8 @@ xnestCollectExposures(void) void xnestQueueKeyEvent(int type, unsigned int keycode) { - GetEventList(&xnestEvents); lastEventTime = GetTimeInMillis(); - QueueKeyboardEvents(xnestEvents, xnestKeyboardDevice, type, keycode, NULL); + QueueKeyboardEvents(xnestKeyboardDevice, type, keycode, NULL); } void @@ -116,7 +113,6 @@ xnestCollectEvents(void) int valuators[2]; ValuatorMask mask; ScreenPtr pScreen; - GetEventList(&xnestEvents); while (XCheckIfEvent(xnestDisplay, &X, xnestNotExposurePredicate, NULL)) { switch (X.type) { @@ -134,7 +130,7 @@ xnestCollectEvents(void) valuator_mask_set_range(&mask, 0, 0, NULL); xnestUpdateModifierState(X.xkey.state); lastEventTime = GetTimeInMillis(); - QueuePointerEvents(xnestEvents, xnestPointerDevice, ButtonPress, + QueuePointerEvents(xnestPointerDevice, ButtonPress, X.xbutton.button, POINTER_RELATIVE, &mask); break; @@ -142,7 +138,7 @@ xnestCollectEvents(void) valuator_mask_set_range(&mask, 0, 0, NULL); xnestUpdateModifierState(X.xkey.state); lastEventTime = GetTimeInMillis(); - QueuePointerEvents(xnestEvents, xnestPointerDevice, ButtonRelease, + QueuePointerEvents(xnestPointerDevice, ButtonRelease, X.xbutton.button, POINTER_RELATIVE, &mask); break; @@ -151,7 +147,7 @@ xnestCollectEvents(void) valuators[1] = X.xmotion.y; valuator_mask_set_range(&mask, 0, 2, valuators); lastEventTime = GetTimeInMillis(); - QueuePointerEvents(xnestEvents, xnestPointerDevice, MotionNotify, + QueuePointerEvents(xnestPointerDevice, MotionNotify, 0, POINTER_ABSOLUTE, &mask); break; @@ -183,7 +179,7 @@ xnestCollectEvents(void) valuators[1] = X.xcrossing.y; valuator_mask_set_range(&mask, 0, 2, valuators); lastEventTime = GetTimeInMillis(); - QueuePointerEvents(xnestEvents, xnestPointerDevice, MotionNotify, + QueuePointerEvents(xnestPointerDevice, MotionNotify, 0, POINTER_ABSOLUTE, &mask); xnestDirectInstallColormaps(pScreen); } diff --git a/hw/xnest/Init.c b/hw/xnest/Init.c index f8637f2ab..ee74101d2 100644 --- a/hw/xnest/Init.c +++ b/hw/xnest/Init.c @@ -45,8 +45,6 @@ is" without express or implied warranty. Bool xnestDoFullGeneration = True; -InternalEvent *xnestEvents = NULL; - void InitOutput(ScreenInfo *screenInfo, int argc, char *argv[]) { @@ -100,8 +98,6 @@ InitInput(int argc, char *argv[]) if (rc != Success) FatalError("Failed to init Xnest default devices.\n"); - GetEventList(&xnestEvents); - mieqInit(); AddEnabledDevice(XConnectionNumber(xnestDisplay)); diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index 6736e3d69..fe744b741 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -485,8 +485,7 @@ void DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button, floa darwinEvents_lock(); { ValuatorMask mask; valuator_mask_set_range(&mask, 0, (pDev == darwinPointer) ? 2 : 5, valuators); - QueuePointerEvents(darwinEvents, pDev, ev_type, ev_button, - POINTER_ABSOLUTE, &mask); + QueuePointerEvents(pDev, ev_type, ev_button, POINTER_ABSOLUTE, &mask); DarwinPokeEQ(); } darwinEvents_unlock(); } @@ -499,7 +498,7 @@ void DarwinSendKeyboardEvents(int ev_type, int keycode) { } darwinEvents_lock(); { - QueueKeyboardEvents(darwinEvents, darwinKeyboard, ev_type, keycode + MIN_KEYCODE, NULL); + QueueKeyboardEvents(darwinKeyboard, ev_type, keycode + MIN_KEYCODE, NULL); DarwinPokeEQ(); } darwinEvents_unlock(); } @@ -526,7 +525,7 @@ void DarwinSendProximityEvents(DeviceIntPtr pDev, int ev_type, float pointer_x, darwinEvents_lock(); { ValuatorMask mask; valuator_mask_set_range(&mask, 0, 5, valuators); - QueueProximityEvents(darwinEvents, pDev, ev_type, &mask); + QueueProximityEvents(pDev, ev_type, &mask); DarwinPokeEQ(); } darwinEvents_unlock(); } diff --git a/hw/xwin/winkeybd.c b/hw/xwin/winkeybd.c index 8b6be0266..2fa6b3f6e 100644 --- a/hw/xwin/winkeybd.c +++ b/hw/xwin/winkeybd.c @@ -483,8 +483,7 @@ winSendKeyEvent (DWORD dwKey, Bool fDown) /* Update the keyState map */ g_winKeyState[dwKey] = fDown; - GetEventList(&events); - QueueKeyboardEvents(events, g_pwinKeyboard, fDown ? KeyPress : KeyRelease, dwKey + MIN_KEYCODE, NULL); + QueueKeyboardEvents(g_pwinKeyboard, fDown ? KeyPress : KeyRelease, dwKey + MIN_KEYCODE, NULL); winDebug("winSendKeyEvent: dwKey: %d, fDown: %d, nEvents %d\n", dwKey, fDown, nevents); diff --git a/hw/xwin/winmouse.c b/hw/xwin/winmouse.c index aaa4d4b99..b1b0657cf 100644 --- a/hw/xwin/winmouse.c +++ b/hw/xwin/winmouse.c @@ -234,15 +234,13 @@ winMouseWheel (ScreenPtr pScreen, int iDeltaZ) void winMouseButtonsSendEvent (int iEventType, int iButton) { - InternalEvent* events; ValuatorMask mask; if (g_winMouseButtonMap) iButton = g_winMouseButtonMap[iButton]; valuator_mask_zero(&mask); - GetEventList(&events); - QueuePointerEvents(events, g_pwinPointer, iEventType, iButton, + QueuePointerEvents(g_pwinPointer, iEventType, iButton, POINTER_RELATIVE, &mask); #if CYGDEBUG @@ -365,15 +363,13 @@ void winEnqueueMotion(int x, int y) { int valuators[2]; ValuatorMask mask; - InternalEvent* events; miPointerSetPosition(g_pwinPointer, POINTER_RELATIVE, &x, &y); valuators[0] = x; valuators[1] = y; valuator_mask_set_range(&mask, 0, 2, valuators); - GetEventList(&events); - QueuePointerEvents(events, g_pwinPointer, MotionNotify, 0, + QueuePointerEvents(g_pwinPointer, MotionNotify, 0, POINTER_ABSOLUTE | POINTER_SCREEN, &mask); } diff --git a/include/input.h b/include/input.h index 3c7740dce..4de4ff52c 100644 --- a/include/input.h +++ b/include/input.h @@ -111,7 +111,6 @@ typedef struct _ValuatorMask ValuatorMask; /* The DIX stores incoming input events in this list */ extern InternalEvent* InputEventList; -extern int InputEventListLen; typedef int (*DeviceProc)( DeviceIntPtr /*device*/, @@ -429,7 +428,6 @@ extern _X_EXPORT void CloseInput(void); extern _X_EXPORT int GetMaximumEventsNum(void); -extern _X_EXPORT int GetEventList(InternalEvent** list); extern _X_EXPORT InternalEvent *InitEventList(int num_events); extern _X_EXPORT void FreeEventList(InternalEvent *list, int num_events); @@ -452,7 +450,6 @@ extern _X_EXPORT int GetPointerEvents( const ValuatorMask *mask); extern _X_EXPORT void QueuePointerEvents( - InternalEvent *events, DeviceIntPtr pDev, int type, int buttons, @@ -467,7 +464,6 @@ extern _X_EXPORT int GetKeyboardEvents( const ValuatorMask *mask); extern _X_EXPORT void QueueKeyboardEvents( - InternalEvent *events, DeviceIntPtr pDev, int type, int key_code, @@ -480,7 +476,6 @@ extern int GetProximityEvents( const ValuatorMask *mask); extern void QueueProximityEvents( - InternalEvent *events, DeviceIntPtr pDev, int type, const ValuatorMask *mask); From c8674a328c68f03de6e4fad7790a595cdfc18736 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 14 Apr 2011 16:45:56 +1000 Subject: [PATCH 19/28] dix: replace unneded goto with break. Signed-off-by: Peter Hutterer Reviewed-by: Daniel Stone --- dix/eventconvert.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dix/eventconvert.c b/dix/eventconvert.c index 14731f4f6..024f2e833 100644 --- a/dix/eventconvert.c +++ b/dix/eventconvert.c @@ -156,7 +156,7 @@ EventToCore(InternalEvent *event, xEvent **core_out, int *count_out) case ET_RawButtonRelease: case ET_RawMotion: ret = BadMatch; - goto out; + break; default: /* XXX: */ ErrorF("[dix] EventToCore: Not implemented yet \n"); From a311a03135f9734aa4f7dc0f2fa0e4c91768343b Mon Sep 17 00:00:00 2001 From: Jamey Sharp Date: Wed, 11 May 2011 14:08:28 -0700 Subject: [PATCH 20/28] dix: split implicit grab activation into a separate function. I'm not sure I like splitting the check for button-press event from the code which makes assumptions about that check. How about replacing patches 3 and 4 with this patch instead? Signed-off-by: Jamey Sharp Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- dix/events.c | 91 +++++++++++++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 41 deletions(-) diff --git a/dix/events.c b/dix/events.c index 276bc75fa..fb114a75a 100644 --- a/dix/events.c +++ b/dix/events.c @@ -1939,6 +1939,54 @@ TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents, return 1; } +static BOOL +ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win, + xEvent *event, Mask deliveryMask) +{ + GrabRec tempGrab; + OtherInputMasks *inputMasks; + CARD8 type = event->u.u.type; + GrabType grabtype; + + if (type == ButtonPress) + grabtype = GRABTYPE_CORE; + else if (type == DeviceButtonPress) + grabtype = GRABTYPE_XI; + else if (XI2_EVENT(event) && ((xGenericEvent*)event)->evtype == XI_ButtonPress) + { + type = ((xGenericEvent*)event)->evtype; + grabtype = GRABTYPE_XI2; + } + else + return FALSE; + + memset(&tempGrab, 0, sizeof(GrabRec)); + tempGrab.next = NULL; + tempGrab.device = dev; + tempGrab.resource = client->clientAsMask; + tempGrab.window = win; + tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE; + tempGrab.eventMask = deliveryMask; + tempGrab.keyboardMode = GrabModeAsync; + tempGrab.pointerMode = GrabModeAsync; + tempGrab.confineTo = NullWindow; + tempGrab.cursor = NullCursor; + tempGrab.type = type; + tempGrab.grabtype = grabtype; + + /* get the XI and XI2 device mask */ + inputMasks = wOtherInputMasks(win); + tempGrab.deviceMask = (inputMasks) ? inputMasks->inputEvents[dev->id]: 0; + + if (inputMasks) + memcpy(tempGrab.xi2mask, inputMasks->xi2mask, + sizeof(tempGrab.xi2mask)); + + (*dev->deviceGrab.ActivateGrab)(dev, &tempGrab, + currentTime, TRUE | ImplicitGrabMask); + return TRUE; +} + /** * Deliver events to a window. At this point, we do not yet know if the event * actually needs to be delivered. May activate a grab if the event is a @@ -2050,47 +2098,8 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent * Note that since core events are delivered first, an implicit grab may * be activated on a core grab, stopping the XI events. */ - if ((type == DeviceButtonPress || type == ButtonPress || - ((XI2_EVENT(pEvents) && ((xGenericEvent*)pEvents)->evtype == XI_ButtonPress))) - && deliveries - && (!grab)) - { - GrabRec tempGrab; - OtherInputMasks *inputMasks; - - memset(&tempGrab, 0, sizeof(GrabRec)); - tempGrab.next = NULL; - tempGrab.device = pDev; - tempGrab.resource = client->clientAsMask; - tempGrab.window = pWin; - tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE; - tempGrab.eventMask = deliveryMask; - tempGrab.keyboardMode = GrabModeAsync; - tempGrab.pointerMode = GrabModeAsync; - tempGrab.confineTo = NullWindow; - tempGrab.cursor = NullCursor; - tempGrab.type = type; - if (type == ButtonPress) - tempGrab.grabtype = GRABTYPE_CORE; - else if (type == DeviceButtonPress) - tempGrab.grabtype = GRABTYPE_XI; - else - { - tempGrab.type = ((xGenericEvent*)pEvents)->evtype; - tempGrab.grabtype = GRABTYPE_XI2; - } - - /* get the XI and XI2 device mask */ - inputMasks = wOtherInputMasks(pWin); - tempGrab.deviceMask = (inputMasks) ? inputMasks->inputEvents[pDev->id]: 0; - - if (inputMasks) - memcpy(tempGrab.xi2mask, inputMasks->xi2mask, - sizeof(tempGrab.xi2mask)); - - (*pDev->deviceGrab.ActivateGrab)(pDev, &tempGrab, - currentTime, TRUE | ImplicitGrabMask); - } + if (deliveries && !grab && ActivateImplicitGrab(pDev, client, pWin, pEvents, deliveryMask)) + /* grab activated */; else if ((type == MotionNotify) && deliveries) pDev->valuator->motionHintWindow = pWin; else From 536ca28f1b0b4d8715a41b8acc5f30364c833f9b Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 12 Apr 2011 13:44:30 +1000 Subject: [PATCH 21/28] dix: split out window owner event delivery from DeliverEventsToWindow No functional changes, just for readability. Signed-off-by: Peter Hutterer Reviewed-by: Jamey Sharp --- dix/events.c | 75 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 20 deletions(-) diff --git a/dix/events.c b/dix/events.c index fb114a75a..4e9af8df4 100644 --- a/dix/events.c +++ b/dix/events.c @@ -1987,6 +1987,43 @@ ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win, return TRUE; } +enum EventDeliveryState { + EVENT_DELIVERED, /**< Event has been delivered to a client */ + EVENT_NOT_DELIVERED, /**< Event was not delivered to any client */ + EVENT_SKIP, /**< Event can be discarded by the caller */ + EVENT_REJECTED, /**< Event was rejected for delivery to the client */ +}; + +/** + * Attempt event delivery to the client owning the window. + */ +static enum EventDeliveryState +DeliverToWindowOwner(DeviceIntPtr dev, WindowPtr win, + xEvent *events, int count, Mask filter, + GrabPtr grab) +{ + /* if nobody ever wants to see this event, skip some work */ + if (filter != CantBeFiltered && + !((wOtherEventMasks(win)|win->eventMask) & filter)) + return EVENT_SKIP; + + if (IsInterferingGrab(wClient(win), dev, events)) + return EVENT_SKIP; + + if (!XaceHook(XACE_RECEIVE_ACCESS, wClient(win), win, events, count)) + { + int attempt = TryClientEvents(wClient(win), dev, events, + count, win->eventMask, + filter, grab); + if (attempt > 0) + return EVENT_DELIVERED; + if (attempt < 0) + return EVENT_REJECTED; + } + + return EVENT_NOT_DELIVERED; +} + /** * Deliver events to a window. At this point, we do not yet know if the event * actually needs to be delivered. May activate a grab if the event is a @@ -2023,28 +2060,26 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent /* Deliver to window owner */ if ((filter == CantBeFiltered) || CORE_EVENT(pEvents)) { - /* if nobody ever wants to see this event, skip some work */ - if (filter != CantBeFiltered && - !((wOtherEventMasks(pWin)|pWin->eventMask) & filter)) - return 0; + enum EventDeliveryState rc; - if (IsInterferingGrab(wClient(pWin), pDev, pEvents)) + rc = DeliverToWindowOwner(pDev, pWin, pEvents, count, filter, grab); + + switch(rc) + { + case EVENT_SKIP: return 0; - - if (XaceHook(XACE_RECEIVE_ACCESS, wClient(pWin), pWin, pEvents, count)) - /* do nothing */; - else if ( (attempt = TryClientEvents(wClient(pWin), pDev, pEvents, - count, pWin->eventMask, - filter, grab)) ) - { - if (attempt > 0) - { - deliveries++; - client = wClient(pWin); - deliveryMask = pWin->eventMask; - } else - nondeliveries--; - } + case EVENT_REJECTED: + nondeliveries--; + break; + case EVENT_DELIVERED: + /* We delivered to the owner, with our event mask */ + deliveries++; + client = wClient(pWin); + deliveryMask = pWin->eventMask; + break; + case EVENT_NOT_DELIVERED: + break; + } } /* CantBeFiltered means only window owner gets the event */ From 236ed6f50675dc0303a505ac6f0418c515438fe1 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 12 Apr 2011 14:04:37 +1000 Subject: [PATCH 22/28] dix: split out client delivery from DeliverEventsToWindow No real functional changes, this is just for improved readability. DeliverEventsToWindow used to return an int to specify the number of deliveries (or rejected deliveries if negative). The number wasn't used by any caller other than for > 0 comparison. This patch also changes the return value to be -1 or 1 even in case of multiple deliveries/rejections. The comment was updated accordingly. A future patch should probably use the enum EventDeliveryState for DeliverEventsToWindow. Signed-off-by: Peter Hutterer Reviewed-by: Jamey Sharp --- dix/events.c | 132 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 88 insertions(+), 44 deletions(-) diff --git a/dix/events.c b/dix/events.c index 4e9af8df4..77f871564 100644 --- a/dix/events.c +++ b/dix/events.c @@ -2024,6 +2024,75 @@ DeliverToWindowOwner(DeviceIntPtr dev, WindowPtr win, return EVENT_NOT_DELIVERED; } +/** + * Deliver events to clients registered on the window. + * + * @param client_return On successful delivery, set to the recipient. + * @param mask_return On successful delivery, set to the recipient's event + * mask for this event. + */ +static enum EventDeliveryState +DeliverEventToClients(DeviceIntPtr dev, WindowPtr win, xEvent *events, + int count, Mask filter, GrabPtr grab, + ClientPtr *client_return, Mask *mask_return) +{ + int attempt; + enum EventDeliveryState rc = EVENT_SKIP; + InputClients *other; + + if (CORE_EVENT(events)) + other = (InputClients *)wOtherClients(win); + else if (XI2_EVENT(events)) + { + OtherInputMasks *inputMasks = wOtherInputMasks(win); + /* Has any client selected for the event? */ + if (!GetWindowXI2Mask(dev, win, events)) + goto out; + other = inputMasks->inputClients; + } else { + OtherInputMasks *inputMasks = wOtherInputMasks(win); + /* Has any client selected for the event? */ + if (!inputMasks || + !(inputMasks->inputEvents[dev->id] & filter)) + goto out; + + other = inputMasks->inputClients; + } + + rc = EVENT_NOT_DELIVERED; + + for (; other; other = other->next) + { + Mask mask; + + if (IsInterferingGrab(rClient(other), dev, events)) + continue; + + mask = GetEventMask(dev, events, other); + + if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), win, + events, count)) + /* do nothing */; + else if ( (attempt = TryClientEvents(rClient(other), dev, + events, count, + mask, filter, grab)) ) + { + if (attempt > 0) + { + rc = EVENT_DELIVERED; + *client_return = rClient(other); + *mask_return = mask; + /* Success overrides non-success, so if we've been + * successful on one client, return that */ + } else if (rc == EVENT_NOT_DELIVERED) + rc = EVENT_REJECTED; + } + } + +out: + return rc; +} + /** * Deliver events to a window. At this point, we do not yet know if the event * actually needs to be delivered. May activate a grab if the event is a @@ -2042,21 +2111,20 @@ DeliverToWindowOwner(DeviceIntPtr dev, WindowPtr win, * @param filter Mask based on event type. * @param grab Possible grab on the device that caused the event. * - * @return Number of events delivered to various clients. + * @return a positive number if at least one successful delivery has been + * made, 0 if no events were delivered, or a negative number if the event + * has not been delivered _and_ rejected by at least one client. */ int DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent *pEvents, int count, Mask filter, GrabPtr grab) { int deliveries = 0, nondeliveries = 0; - int attempt; - InputClients *other; ClientPtr client = NullClient; Mask deliveryMask = 0; /* If a grab occurs due to a button press, then this mask is the mask of the grab. */ int type = pEvents->u.u.type; - /* Deliver to window owner */ if ((filter == CantBeFiltered) || CORE_EVENT(pEvents)) { @@ -2085,50 +2153,26 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent /* CantBeFiltered means only window owner gets the event */ if (filter != CantBeFiltered) { - if (CORE_EVENT(pEvents)) - other = (InputClients *)wOtherClients(pWin); - else if (XI2_EVENT(pEvents)) + enum EventDeliveryState rc; + + rc = DeliverEventToClients(pDev, pWin, pEvents, count, filter, grab, + &client, &deliveryMask); + + switch(rc) { - OtherInputMasks *inputMasks = wOtherInputMasks(pWin); - /* Has any client selected for the event? */ - if (!GetWindowXI2Mask(pDev, pWin, pEvents)) + case EVENT_SKIP: return 0; - other = inputMasks->inputClients; - } else { - OtherInputMasks *inputMasks = wOtherInputMasks(pWin); - /* Has any client selected for the event? */ - if (!inputMasks || - !(inputMasks->inputEvents[pDev->id] & filter)) - return 0; - - other = inputMasks->inputClients; - } - - for (; other; other = other->next) - { - Mask mask; - if (IsInterferingGrab(rClient(other), pDev, pEvents)) - continue; - - mask = GetEventMask(pDev, pEvents, other); - - if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), pWin, - pEvents, count)) - /* do nothing */; - else if ( (attempt = TryClientEvents(rClient(other), pDev, - pEvents, count, - mask, filter, grab)) ) - { - if (attempt > 0) - { - deliveries++; - client = rClient(other); - deliveryMask = mask; - } else - nondeliveries--; - } + case EVENT_REJECTED: + nondeliveries--; + break; + case EVENT_DELIVERED: + deliveries++; + break; + case EVENT_NOT_DELIVERED: + break; } } + /* * Note that since core events are delivered first, an implicit grab may * be activated on a core grab, stopping the XI events. From 2054ca73060a20b5a3025e8d5ef68182149484d3 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 14 Apr 2011 15:09:39 +1000 Subject: [PATCH 23/28] dix: move the grab activation condition into a if block. Rather than 3 conditions with if (deliveries && ...), have one block with the three in them. No functional changes. Signed-off-by: Peter Hutterer Reviewed-by: Jamey Sharp --- dix/events.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/dix/events.c b/dix/events.c index 77f871564..aeb37aa27 100644 --- a/dix/events.c +++ b/dix/events.c @@ -2173,24 +2173,22 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent } } - /* - * Note that since core events are delivered first, an implicit grab may - * be activated on a core grab, stopping the XI events. - */ - if (deliveries && !grab && ActivateImplicitGrab(pDev, client, pWin, pEvents, deliveryMask)) - /* grab activated */; - else if ((type == MotionNotify) && deliveries) - pDev->valuator->motionHintWindow = pWin; - else - { - if ((type == DeviceMotionNotify || type == DeviceButtonPress) && - deliveries) - CheckDeviceGrabAndHintWindow (pWin, type, - (deviceKeyButtonPointer*) pEvents, - grab, client, deliveryMask); - } if (deliveries) + { + /* + * Note that since core events are delivered first, an implicit grab may + * be activated on a core grab, stopping the XI events. + */ + if (!grab && ActivateImplicitGrab(pDev, client, pWin, pEvents, deliveryMask)) + /* grab activated */; + else if ((type == MotionNotify)) + pDev->valuator->motionHintWindow = pWin; + else if (type == DeviceMotionNotify || type == DeviceButtonPress) + CheckDeviceGrabAndHintWindow (pWin, type, + (deviceKeyButtonPointer*) pEvents, + grab, client, deliveryMask); return deliveries; + } return nondeliveries; } From 5bcc22757e6e1f24ee2bfec65f68a5f567300532 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 14 Apr 2011 15:43:56 +1000 Subject: [PATCH 24/28] dix: return deliveries from DeliverGrabbedEvent This isn't currently used by any of the callers but it will likely be in the future. Signed-off-by: Peter Hutterer Reviewed-by: Jamey Sharp --- dix/events.c | 6 +++++- include/dix.h | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/dix/events.c b/dix/events.c index aeb37aa27..30b689aed 100644 --- a/dix/events.c +++ b/dix/events.c @@ -3884,8 +3884,10 @@ unwind: * grab. If not, TryClientEvents() is used. * * @param deactivateGrab True if the device's grab should be deactivated. + * + * @return The number of events delivered. */ -void +int DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev, Bool deactivateGrab) { @@ -4053,6 +4055,8 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev, free(core); free(xi); free(xi2); + + return deliveries; } /* This function is used to set the key pressed or key released state - diff --git a/include/dix.h b/include/dix.h index fb9be43c2..9a111e8a7 100644 --- a/include/dix.h +++ b/include/dix.h @@ -415,7 +415,7 @@ extern void DeliverFocusedEvent( InternalEvent* /* event */, WindowPtr /* window */); -extern void DeliverGrabbedEvent( +extern int DeliverGrabbedEvent( InternalEvent* /* event */, DeviceIntPtr /* thisDev */, Bool /* deactivateGrab */); From dc45d5816dd65168645f0017394eebfc5599d698 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 14 Apr 2011 15:59:08 +1000 Subject: [PATCH 25/28] Xi: split DeviceStateNotify delivery into a separate function Signed-off-by: Peter Hutterer Reviewed-by: Jamey Sharp --- Xi/exevents.c | 202 ++++++++++++++++++++++++++------------------------ 1 file changed, 104 insertions(+), 98 deletions(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index d48d397cf..c6f9d467f 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -1189,6 +1189,108 @@ FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, first += ev->num_valuators; } +static void +DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win) +{ + int evcount = 1; + deviceStateNotify *ev, *sev; + deviceKeyStateNotify *kev; + deviceButtonStateNotify *bev; + + KeyClassPtr k; + ButtonClassPtr b; + ValuatorClassPtr v; + int nval = 0, nkeys = 0, nbuttons = 0, first = 0; + + if (!(wOtherInputMasks(win)) || + !(wOtherInputMasks(win)->inputEvents[dev->id] & DeviceStateNotifyMask)) + return; + + if ((b = dev->button) != NULL) { + nbuttons = b->numButtons; + if (nbuttons > 32) + evcount++; + } + if ((k = dev->key) != NULL) { + nkeys = k->xkbInfo->desc->max_key_code - + k->xkbInfo->desc->min_key_code; + if (nkeys > 32) + evcount++; + if (nbuttons > 0) { + evcount++; + } + } + if ((v = dev->valuator) != NULL) { + nval = v->numAxes; + + if (nval > 3) + evcount++; + if (nval > 6) { + if (!(k && b)) + evcount++; + if (nval > 9) + evcount += ((nval - 7) / 3); + } + } + + sev = ev = (deviceStateNotify *) malloc(evcount * sizeof(xEvent)); + FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); + + if (b != NULL) { + FixDeviceStateNotify(dev, ev++, NULL, b, v, first); + first += 3; + nval -= 3; + if (nbuttons > 32) { + (ev - 1)->deviceid |= MORE_EVENTS; + bev = (deviceButtonStateNotify *) ev++; + bev->type = DeviceButtonStateNotify; + bev->deviceid = dev->id; + memcpy((char*)&bev->buttons[4], (char*)&b->down[4], DOWN_LENGTH - 4); + } + if (nval > 0) { + (ev - 1)->deviceid |= MORE_EVENTS; + FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); + first += 3; + nval -= 3; + } + } + + if (k != NULL) { + FixDeviceStateNotify(dev, ev++, k, NULL, v, first); + first += 3; + nval -= 3; + if (nkeys > 32) { + (ev - 1)->deviceid |= MORE_EVENTS; + kev = (deviceKeyStateNotify *) ev++; + kev->type = DeviceKeyStateNotify; + kev->deviceid = dev->id; + memmove((char *)&kev->keys[0], (char *)&k->down[4], 28); + } + if (nval > 0) { + (ev - 1)->deviceid |= MORE_EVENTS; + FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); + first += 3; + nval -= 3; + } + } + + while (nval > 0) { + FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first); + first += 3; + nval -= 3; + if (nval > 0) { + (ev - 1)->deviceid |= MORE_EVENTS; + FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); + first += 3; + nval -= 3; + } + } + + DeliverEventsToWindow(dev, win, (xEvent *) sev, evcount, + DeviceStateNotifyMask, NullGrab); + free(sev); +} + void DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin) @@ -1255,104 +1357,8 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1, DeviceFocusChangeMask, NullGrab); - if ((event.type == DeviceFocusIn) && - (wOtherInputMasks(pWin)) && - (wOtherInputMasks(pWin)->inputEvents[dev->id] & DeviceStateNotifyMask)) - { - int evcount = 1; - deviceStateNotify *ev, *sev; - deviceKeyStateNotify *kev; - deviceButtonStateNotify *bev; - - KeyClassPtr k; - ButtonClassPtr b; - ValuatorClassPtr v; - int nval = 0, nkeys = 0, nbuttons = 0, first = 0; - - if ((b = dev->button) != NULL) { - nbuttons = b->numButtons; - if (nbuttons > 32) - evcount++; - } - if ((k = dev->key) != NULL) { - nkeys = k->xkbInfo->desc->max_key_code - - k->xkbInfo->desc->min_key_code; - if (nkeys > 32) - evcount++; - if (nbuttons > 0) { - evcount++; - } - } - if ((v = dev->valuator) != NULL) { - nval = v->numAxes; - - if (nval > 3) - evcount++; - if (nval > 6) { - if (!(k && b)) - evcount++; - if (nval > 9) - evcount += ((nval - 7) / 3); - } - } - - sev = ev = (deviceStateNotify *) malloc(evcount * sizeof(xEvent)); - FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); - - if (b != NULL) { - FixDeviceStateNotify(dev, ev++, NULL, b, v, first); - first += 3; - nval -= 3; - if (nbuttons > 32) { - (ev - 1)->deviceid |= MORE_EVENTS; - bev = (deviceButtonStateNotify *) ev++; - bev->type = DeviceButtonStateNotify; - bev->deviceid = dev->id; - memcpy((char*)&bev->buttons[4], (char*)&b->down[4], DOWN_LENGTH - 4); - } - if (nval > 0) { - (ev - 1)->deviceid |= MORE_EVENTS; - FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); - first += 3; - nval -= 3; - } - } - - if (k != NULL) { - FixDeviceStateNotify(dev, ev++, k, NULL, v, first); - first += 3; - nval -= 3; - if (nkeys > 32) { - (ev - 1)->deviceid |= MORE_EVENTS; - kev = (deviceKeyStateNotify *) ev++; - kev->type = DeviceKeyStateNotify; - kev->deviceid = dev->id; - memmove((char *)&kev->keys[0], (char *)&k->down[4], 28); - } - if (nval > 0) { - (ev - 1)->deviceid |= MORE_EVENTS; - FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); - first += 3; - nval -= 3; - } - } - - while (nval > 0) { - FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first); - first += 3; - nval -= 3; - if (nval > 0) { - (ev - 1)->deviceid |= MORE_EVENTS; - FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); - first += 3; - nval -= 3; - } - } - - DeliverEventsToWindow(dev, pWin, (xEvent *) sev, evcount, - DeviceStateNotifyMask, NullGrab); - free(sev); - } + if (event.type == DeviceFocusIn) + DeliverStateNotifyEvent(dev, pWin); } int From c4f9c3a07dbb05b81c8e2193a083102f710ebb27 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 11 May 2011 11:43:16 +1000 Subject: [PATCH 26/28] dix: use a tmp variable instead of multiple rClient(other). no functional changes. Signed-off-by: Peter Hutterer Reviewed-by: Jamey Sharp --- dix/events.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dix/events.c b/dix/events.c index 30b689aed..e67c3a254 100644 --- a/dix/events.c +++ b/dix/events.c @@ -2064,23 +2064,24 @@ DeliverEventToClients(DeviceIntPtr dev, WindowPtr win, xEvent *events, for (; other; other = other->next) { Mask mask; + ClientPtr client = rClient(other); - if (IsInterferingGrab(rClient(other), dev, events)) + if (IsInterferingGrab(client, dev, events)) continue; mask = GetEventMask(dev, events, other); - if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), win, + if (XaceHook(XACE_RECEIVE_ACCESS, client, win, events, count)) /* do nothing */; - else if ( (attempt = TryClientEvents(rClient(other), dev, + else if ( (attempt = TryClientEvents(client, dev, events, count, mask, filter, grab)) ) { if (attempt > 0) { rc = EVENT_DELIVERED; - *client_return = rClient(other); + *client_return = client; *mask_return = mask; /* Success overrides non-success, so if we've been * successful on one client, return that */ From ffd4874798ba54f86acac75779a15b4babeaa5f3 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 11 May 2011 12:20:50 +1000 Subject: [PATCH 27/28] include: add version_compare helper function Compare two version numbers in the major.minor form. Switch the few users of manual version switching over to the new function. Signed-off-by: Peter Hutterer Reviewed-by: Jamey Sharp --- Xi/xiqueryversion.c | 7 ++--- include/misc.h | 18 +++++++++++++ randr/rrdispatch.c | 8 +++--- test/Makefile.am | 3 ++- test/misc.c | 62 +++++++++++++++++++++++++++++++++++++++++++++ xfixes/xfixes.c | 12 ++++----- 6 files changed, 94 insertions(+), 16 deletions(-) create mode 100644 test/misc.c diff --git a/Xi/xiqueryversion.c b/Xi/xiqueryversion.c index ae63297da..f647f9872 100644 --- a/Xi/xiqueryversion.c +++ b/Xi/xiqueryversion.c @@ -58,7 +58,6 @@ ProcXIQueryVersion(ClientPtr client) xXIQueryVersionReply rep; XIClientPtr pXIClient; int major, minor; - unsigned int sversion, cversion; REQUEST(xXIQueryVersionReq); REQUEST_SIZE_MATCH(xXIQueryVersionReq); @@ -72,10 +71,8 @@ ProcXIQueryVersion(ClientPtr client) pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey); - sversion = XIVersion.major_version * 1000 + XIVersion.minor_version; - cversion = stuff->major_version * 1000 + stuff->minor_version; - - if (sversion > cversion) + if (version_compare(XIVersion.major_version, XIVersion.minor_version, + stuff->major_version, stuff->minor_version) > 0) { major = stuff->major_version; minor = stuff->minor_version; diff --git a/include/misc.h b/include/misc.h index 803f5bade..bdcc8cc1e 100644 --- a/include/misc.h +++ b/include/misc.h @@ -223,6 +223,24 @@ pad_to_int32(const int bytes) { extern char** xstrtokenize(const char *str, const char* separators); +/** + * Compare the two version numbers comprising of major.minor. + * + * @return A value less than 0 if a is less than b, 0 if a is equal to b, + * or a value greater than 0 + */ +static inline int +version_compare(uint16_t a_major, uint16_t a_minor, + uint16_t b_major, uint16_t b_minor) +{ + int a, b; + + a = a_major << 16 | a_minor; + b = b_major << 16 | b_minor; + + return (a - b); +} + /* some macros to help swap requests, replies, and events */ #define LengthRestB(stuff) \ diff --git a/randr/rrdispatch.c b/randr/rrdispatch.c index 213550475..d1c99c288 100644 --- a/randr/rrdispatch.c +++ b/randr/rrdispatch.c @@ -28,8 +28,8 @@ RRClientKnowsRates (ClientPtr pClient) { rrClientPriv(pClient); - return (pRRClient->major_version > 1 || - (pRRClient->major_version == 1 && pRRClient->minor_version >= 1)); + return version_compare(pRRClient->major_version, pRRClient->minor_version, + 1, 1) >= 0; } static int @@ -47,8 +47,8 @@ ProcRRQueryVersion (ClientPtr client) rep.length = 0; rep.sequenceNumber = client->sequence; - if ((stuff->majorVersion * 1000 + stuff->minorVersion) < - (SERVER_RANDR_MAJOR_VERSION * 1000 + SERVER_RANDR_MINOR_VERSION)) + if (version_compare(stuff->majorVersion, stuff->minorVersion, + SERVER_RANDR_MAJOR_VERSION, SERVER_RANDR_MINOR_VERSION) < 0) { rep.majorVersion = stuff->majorVersion; rep.minorVersion = stuff->minorVersion; diff --git a/test/Makefile.am b/test/Makefile.am index fe9bc1f2e..b7ee070a1 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,7 +1,7 @@ if ENABLE_UNIT_TESTS if HAVE_LD_WRAP SUBDIRS= . xi2 -noinst_PROGRAMS = xkb input xtest list +noinst_PROGRAMS = xkb input xtest list misc check_LTLIBRARIES = libxservertest.la TESTS=$(noinst_PROGRAMS) @@ -18,6 +18,7 @@ xkb_LDADD=$(TEST_LDADD) input_LDADD=$(TEST_LDADD) xtest_LDADD=$(TEST_LDADD) list_LDADD=$(TEST_LDADD) +misc_LDADD=$(TEST_LDADD) libxservertest_la_LIBADD = \ $(XSERVER_LIBS) \ diff --git a/test/misc.c b/test/misc.c new file mode 100644 index 000000000..3d3b1a1e3 --- /dev/null +++ b/test/misc.c @@ -0,0 +1,62 @@ +/** + * Copyright © 2011 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include +#include "misc.h" + +static void dix_version_compare(void) +{ + int rc; + + rc = version_compare(0, 0, 1, 0); + assert(rc < 0); + rc = version_compare(1, 0, 0, 0); + assert(rc > 0); + rc = version_compare(0, 0, 0, 0); + assert(rc == 0); + rc = version_compare(1, 0, 1, 0); + assert(rc == 0); + rc = version_compare(1, 0, 0, 9); + assert(rc > 0); + rc = version_compare(0, 9, 1, 0); + assert(rc < 0); + rc = version_compare(1, 0, 1, 9); + assert(rc < 0); + rc = version_compare(1, 9, 1, 0); + assert(rc > 0); + rc = version_compare(2, 0, 1, 9); + assert(rc > 0); + rc = version_compare(1, 9, 2, 0); + assert(rc < 0); +} + +int main(int argc, char** argv) +{ + dix_version_compare(); + + return 0; +} diff --git a/xfixes/xfixes.c b/xfixes/xfixes.c index e8c7bf161..54f0df341 100644 --- a/xfixes/xfixes.c +++ b/xfixes/xfixes.c @@ -72,17 +72,17 @@ ProcXFixesQueryVersion(ClientPtr client) rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; - if (stuff->majorVersion < SERVER_XFIXES_MAJOR_VERSION) { + + if (version_compare(stuff->majorVersion, stuff->minorVersion, + SERVER_XFIXES_MAJOR_VERSION, SERVER_XFIXES_MAJOR_VERSION) < 0) + { rep.majorVersion = stuff->majorVersion; rep.minorVersion = stuff->minorVersion; } else { rep.majorVersion = SERVER_XFIXES_MAJOR_VERSION; - if (stuff->majorVersion == SERVER_XFIXES_MAJOR_VERSION && - stuff->minorVersion < SERVER_XFIXES_MINOR_VERSION) - rep.minorVersion = stuff->minorVersion; - else - rep.minorVersion = SERVER_XFIXES_MINOR_VERSION; + rep.minorVersion = SERVER_XFIXES_MINOR_VERSION; } + pXFixesClient->major_version = rep.majorVersion; pXFixesClient->minor_version = rep.minorVersion; if (client->swapped) { From 728d0bf20ed8e2612b100fca6526705fa6e1eef4 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 11 May 2011 13:35:39 +1000 Subject: [PATCH 28/28] dix: replace CORE_EVENT and XI2_EVENT macros with inline functions. Signed-off-by: Peter Hutterer Reviewed-by: Jamey Sharp --- dix/events.c | 78 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/dix/events.c b/dix/events.c index e67c3a254..14f6f909e 100644 --- a/dix/events.c +++ b/dix/events.c @@ -176,12 +176,23 @@ typedef const char *string; #define AllEventMasks (LastEventMask|(LastEventMask-1)) -#define CORE_EVENT(event) \ - (!((event)->u.u.type & EXTENSION_EVENT_BASE) && \ - (event)->u.u.type != GenericEvent) -#define XI2_EVENT(event) \ - (((event)->u.u.type == GenericEvent) && \ - ((xGenericEvent*)(event))->extension == IReqCode) +/* @return the core event type or 0 if the event is not a core event */ +static inline int +core_get_type(const xEvent *event) +{ + int type = event->u.u.type; + + return ((type & EXTENSION_EVENT_BASE) || type == GenericEvent) ? 0 : type; +} + +/* @return the XI2 event type or 0 if the event is not a XI2 event */ +static inline int +xi2_get_type(const xEvent *event) +{ + xGenericEvent* e = (xGenericEvent*)event; + + return (e->type != GenericEvent || e->extension != IReqCode) ? 0 : e->evtype; +} /** * Used to indicate a implicit passive grab created by a ButtonPress event. @@ -414,10 +425,12 @@ static const Mask default_filter[128] = Mask GetEventFilter(DeviceIntPtr dev, xEvent *event) { + int evtype = 0; + if (event->u.u.type != GenericEvent) return filters[dev ? dev->id : 0][event->u.u.type]; - else if (XI2_EVENT(event)) - return (1 << (((xXIDeviceEvent*)event)->evtype % 8)); + else if ((evtype = xi2_get_type(event))) + return (1 << (evtype % 8)); ErrorF("[dix] Unknown device type %d. No filter\n", event->u.u.type); return 0; } @@ -432,7 +445,7 @@ GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev) int filter; int evtype; - if (!inputMasks || !XI2_EVENT(ev)) + if (!inputMasks || xi2_get_type(ev) == 0) return 0; evtype = ((xGenericEvent*)ev)->evtype; @@ -446,14 +459,16 @@ GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev) Mask GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients* other) { + int evtype; + /* XI2 filters are only ever 8 bit, so let's return a 8 bit mask */ - if (XI2_EVENT(event)) + if ((evtype = xi2_get_type(event))) { - int byte = ((xGenericEvent*)event)->evtype / 8; + int byte = evtype / 8; return (other->xi2mask[dev->id][byte] | other->xi2mask[XIAllDevices][byte] | (IsMaster(dev)? other->xi2mask[XIAllMasterDevices][byte] : 0)); - } else if (CORE_EVENT(event)) + } else if (core_get_type(event) != 0) return other->mask[XIAllDevices]; else return other->mask[dev->id]; @@ -1952,11 +1967,8 @@ ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win, grabtype = GRABTYPE_CORE; else if (type == DeviceButtonPress) grabtype = GRABTYPE_XI; - else if (XI2_EVENT(event) && ((xGenericEvent*)event)->evtype == XI_ButtonPress) - { - type = ((xGenericEvent*)event)->evtype; + else if ((type = xi2_get_type(event)) == XI_ButtonPress) grabtype = GRABTYPE_XI2; - } else return FALSE; @@ -2040,9 +2052,9 @@ DeliverEventToClients(DeviceIntPtr dev, WindowPtr win, xEvent *events, enum EventDeliveryState rc = EVENT_SKIP; InputClients *other; - if (CORE_EVENT(events)) + if (core_get_type(events) != 0) other = (InputClients *)wOtherClients(win); - else if (XI2_EVENT(events)) + else if (xi2_get_type(events) != 0) { OtherInputMasks *inputMasks = wOtherInputMasks(win); /* Has any client selected for the event? */ @@ -2094,6 +2106,7 @@ out: return rc; } + /** * Deliver events to a window. At this point, we do not yet know if the event * actually needs to be delivered. May activate a grab if the event is a @@ -2127,7 +2140,7 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent int type = pEvents->u.u.type; /* Deliver to window owner */ - if ((filter == CantBeFiltered) || CORE_EVENT(pEvents)) + if ((filter == CantBeFiltered) || core_get_type(pEvents) != 0) { enum EventDeliveryState rc; @@ -2313,22 +2326,29 @@ FixUpEventFromWindow( Window child, Bool calcChild) { + int evtype; + if (calcChild) child = FindChildForEvent(pSprite, pWin); - if (XI2_EVENT(xE)) + if ((evtype = xi2_get_type(xE))) { xXIDeviceEvent* event = (xXIDeviceEvent*)xE; - if (event->evtype == XI_RawKeyPress || - event->evtype == XI_RawKeyRelease || - event->evtype == XI_RawButtonPress || - event->evtype == XI_RawButtonRelease || - event->evtype == XI_RawMotion || - event->evtype == XI_DeviceChanged || - event->evtype == XI_HierarchyChanged || - event->evtype == XI_PropertyEvent) - return; + switch (evtype) + { + case XI_RawKeyPress: + case XI_RawKeyRelease: + case XI_RawButtonPress: + case XI_RawButtonRelease: + case XI_RawMotion: + case XI_DeviceChanged: + case XI_HierarchyChanged: + case XI_PropertyEvent: + return; + default: + break; + } event->root = RootWindow(pSprite)->drawable.id; event->event = pWin->drawable.id;