From 512a9750c197437889ff7f26a8d2bd242e030745 Mon Sep 17 00:00:00 2001 From: Cyril Brulebois Date: Sun, 5 Jun 2011 03:03:47 +0200 Subject: [PATCH 01/11] xkb: Fix case checks for Latin 1. That one was missing _XkbKSLower: XK_ssharp: U+00DF LATIN SMALL LETTER SHARP S That one was getting _XkbKSLower for no reasons: XK_division: U+00F7 DIVISION SIGN For reference, XK_multiply was already excluded from the _XkbKSUpper check, it's no big surprise XK_division has to be excluded from the _XkbKSLower check. Reviewed-by: Daniel Stone Signed-off-by: Cyril Brulebois --- xkb/xkbfmisc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xkb/xkbfmisc.c b/xkb/xkbfmisc.c index 1ac9d8262..c36cc7bec 100644 --- a/xkb/xkbfmisc.c +++ b/xkb/xkbfmisc.c @@ -62,7 +62,7 @@ unsigned set,rtrn; rtrn|= _XkbKSUpper; } if (((ks>=XK_a)&&(ks<=XK_z))|| - ((ks>=XK_agrave)&&(ks<=XK_ydiaeresis))) { + ((ks>=XK_ssharp)&&(ks<=XK_ydiaeresis)&&(ks!=XK_division))) { rtrn|= _XkbKSLower; } break; From 0b56a7f0ad01d3a86cdd7a14d5e567a00a3553f6 Mon Sep 17 00:00:00 2001 From: Cyril Brulebois Date: Sun, 5 Jun 2011 03:12:44 +0200 Subject: [PATCH 02/11] xkb: Fix case checks for Latin 2. Those ones were getting _XkbKSLower for no reasons: XK_ogonek: U+02DB OGONEK XK_doubleacute: U+02DD DOUBLE ACUTE ACCENT Reviewed-by: Daniel Stone Signed-off-by: Cyril Brulebois --- xkb/xkbfmisc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xkb/xkbfmisc.c b/xkb/xkbfmisc.c index c36cc7bec..e0426718f 100644 --- a/xkb/xkbfmisc.c +++ b/xkb/xkbfmisc.c @@ -71,7 +71,7 @@ unsigned set,rtrn; ((ks>=XK_Racute)&&(ks<=XK_Tcedilla))) { rtrn|= _XkbKSUpper; } - if (((ks>=XK_aogonek)&&(ks<=XK_zabovedot)&&(ks!=XK_caron))|| + if (((ks>=XK_aogonek)&&(ks<=XK_zabovedot)&&(ks!=XK_ogonek)&&(ks!=XK_caron)&&(ks!=XK_doubleacute))|| ((ks>=XK_racute)&&(ks<=XK_tcedilla))) { rtrn|= _XkbKSLower; } From 537c5f631d1f8d526e63355b7d88cb1fb2793492 Mon Sep 17 00:00:00 2001 From: Cyril Brulebois Date: Sun, 5 Jun 2011 03:21:18 +0200 Subject: [PATCH 03/11] xkb: Fix case checks for Latin 4. That one was missing _XkbKSLower: XK_kra: U+0138 LATIN SMALL LETTER KRA Reviewed-by: Daniel Stone Signed-off-by: Cyril Brulebois --- xkb/xkbfmisc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xkb/xkbfmisc.c b/xkb/xkbfmisc.c index e0426718f..d8202b496 100644 --- a/xkb/xkbfmisc.c +++ b/xkb/xkbfmisc.c @@ -92,7 +92,8 @@ unsigned set,rtrn; ((ks>=XK_Amacron)&&(ks<=XK_Umacron))) { rtrn|= _XkbKSUpper; } - if (((ks>=XK_rcedilla)&&(ks<=XK_tslash))|| + if ((ks==XK_kra)|| + ((ks>=XK_rcedilla)&&(ks<=XK_tslash))|| (ks==XK_eng)|| ((ks>=XK_amacron)&&(ks<=XK_umacron))) { rtrn|= _XkbKSLower; From 016413dae947fe4e8e918f728c87354fa4928275 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 27 May 2011 11:40:56 +1000 Subject: [PATCH 04/11] dix: split client list retrieval out of DeliverEventToClients No functional change, but "other" was renamed to "clients". Signed-off-by: Peter Hutterer Reviewed-by: Jeremy Huddleston Reviewed-by: Daniel Stone --- dix/events.c | 58 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/dix/events.c b/dix/events.c index 3c7bd50cd..20754f0c5 100644 --- a/dix/events.c +++ b/dix/events.c @@ -2037,6 +2037,44 @@ DeliverToWindowOwner(DeviceIntPtr dev, WindowPtr win, return EVENT_NOT_DELIVERED; } + +/** + * Get the list of clients that should be tried for event delivery on the + * given window. + * + * @return 1 if the client list should be traversed, zero if the event + * should be skipped. + */ +static Bool +GetClientsForDelivery(DeviceIntPtr dev, WindowPtr win, + xEvent *events, Mask filter, InputClients **clients) +{ + int rc = 0; + + if (core_get_type(events) != 0) + *clients = (InputClients *)wOtherClients(win); + else if (xi2_get_type(events) != 0) + { + OtherInputMasks *inputMasks = wOtherInputMasks(win); + /* Has any client selected for the event? */ + if (!GetWindowXI2Mask(dev, win, events)) + goto out; + *clients = inputMasks->inputClients; + } else { + OtherInputMasks *inputMasks = wOtherInputMasks(win); + /* Has any client selected for the event? */ + if (!inputMasks || + !(inputMasks->inputEvents[dev->id] & filter)) + goto out; + + *clients = inputMasks->inputClients; + } + + rc = 1; +out: + return rc; +} + /** * Deliver events to clients registered on the window. * @@ -2053,24 +2091,8 @@ DeliverEventToClients(DeviceIntPtr dev, WindowPtr win, xEvent *events, enum EventDeliveryState rc = EVENT_SKIP; InputClients *other; - if (core_get_type(events) != 0) - other = (InputClients *)wOtherClients(win); - else if (xi2_get_type(events) != 0) - { - 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; - } + if (!GetClientsForDelivery(dev, win, events, filter, &other)) + goto out; rc = EVENT_NOT_DELIVERED; From 5ea2fb389fce235366e9fce83d20abdc8874f4e2 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 27 May 2011 11:43:50 +1000 Subject: [PATCH 05/11] dix: rename DeliverEventsToClients to DeliverEventsToWindowMask To avoid confusion with a future patch and it better describes what this does anyway - delivering events to all clients that have the event mask on the window. Signed-off-by: Peter Hutterer Reviewed-by: Jeremy Huddleston Reviewed-by: Daniel Stone --- dix/events.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dix/events.c b/dix/events.c index 20754f0c5..66fbe9a47 100644 --- a/dix/events.c +++ b/dix/events.c @@ -2083,9 +2083,9 @@ out: * 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) +DeliverEventToWindowMask(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; @@ -2192,8 +2192,8 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent { enum EventDeliveryState rc; - rc = DeliverEventToClients(pDev, pWin, pEvents, count, filter, grab, - &client, &deliveryMask); + rc = DeliverEventToWindowMask(pDev, pWin, pEvents, count, filter, + grab, &client, &deliveryMask); switch(rc) { From ac0850e86f22191091a1eb07237cae9de49ee00d Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 27 May 2011 12:14:32 +1000 Subject: [PATCH 06/11] dix: split DeliverEventToWindowMask up a bit more. Move out the actual event delivery, it needs to be used from elsewhere. Signed-off-by: Peter Hutterer Reviewed-by: Jeremy Huddleston Reviewed-by: Daniel Stone --- dix/events.c | 52 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/dix/events.c b/dix/events.c index 66fbe9a47..9063c28f5 100644 --- a/dix/events.c +++ b/dix/events.c @@ -2076,35 +2076,27 @@ out: } /** - * 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. + * Try delivery on each client in inputclients, provided the event mask + * accepts it and there is no interfering core grab.. */ static enum EventDeliveryState -DeliverEventToWindowMask(DeviceIntPtr dev, WindowPtr win, xEvent *events, - int count, Mask filter, GrabPtr grab, - ClientPtr *client_return, Mask *mask_return) +DeliverEventToInputClients(DeviceIntPtr dev, InputClients *inputclients, + 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; + enum EventDeliveryState rc = EVENT_NOT_DELIVERED; - if (!GetClientsForDelivery(dev, win, events, filter, &other)) - goto out; - - rc = EVENT_NOT_DELIVERED; - - for (; other; other = other->next) + for (; inputclients; inputclients = inputclients->next) { Mask mask; - ClientPtr client = rClient(other); + ClientPtr client = rClient(inputclients); if (IsInterferingGrab(client, dev, events)) continue; - mask = GetEventMask(dev, events, other); + mask = GetEventMask(dev, events, inputclients); if (XaceHook(XACE_RECEIVE_ACCESS, client, win, events, count)) @@ -2125,11 +2117,33 @@ DeliverEventToWindowMask(DeviceIntPtr dev, WindowPtr win, xEvent *events, } } -out: return rc; } +/** + * 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 +DeliverEventToWindowMask(DeviceIntPtr dev, WindowPtr win, xEvent *events, + int count, Mask filter, GrabPtr grab, + ClientPtr *client_return, Mask *mask_return) +{ + InputClients *clients; + + if (!GetClientsForDelivery(dev, win, events, filter, &clients)) + return EVENT_SKIP; + + return DeliverEventToInputClients(dev, clients, win, events, count, filter, + grab, client_return, mask_return); + +} + + /** * 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 From c48133f133c64d356a1208f185619bfdf7e9a5f2 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 27 May 2011 14:19:45 +1000 Subject: [PATCH 07/11] Xi: use temporary variable for filter. Signed-off-by: Peter Hutterer Reviewed-by: Jeremy Huddleston Reviewed-by: Daniel Stone --- Xi/exevents.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index 3b0411d61..042ea69bb 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -886,6 +886,7 @@ ProcessRawEvent(RawDeviceEvent *ev, DeviceIntPtr device) else { /* deliver to all root windows */ xEvent *xi; int i; + int filter; i = EventToXI2((InternalEvent*)ev, (xEvent**)&xi); if (i != Success) @@ -895,9 +896,11 @@ ProcessRawEvent(RawDeviceEvent *ev, DeviceIntPtr device) return; } + filter = GetEventFilter(device, xi); + for (i = 0; i < screenInfo.numScreens; i++) DeliverEventsToWindow(device, screenInfo.screens[i]->root, xi, 1, - GetEventFilter(device, xi), NULL); + filter, NullGrab); free(xi); } } From 54e05d80a122bac57920fce1704c0f57492b849c Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 27 May 2011 14:21:39 +1000 Subject: [PATCH 08/11] dix: rename ProcessRawEvents to dix/events.c:DeliverRawEvent No functional changes, prep work for future changes. Signed-off-by: Peter Hutterer Reviewed-by: Cyril Brulebois Reviewed-by: Jeremy Huddleston Reviewed-by: Daniel Stone --- Xi/exevents.c | 31 +------------------------------ dix/events.c | 29 +++++++++++++++++++++++++++++ include/dix.h | 5 +++++ 3 files changed, 35 insertions(+), 30 deletions(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index 042ea69bb..3e3c67b63 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -876,35 +876,6 @@ UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event) return DEFAULT; } -static void -ProcessRawEvent(RawDeviceEvent *ev, DeviceIntPtr device) -{ - GrabPtr grab = device->deviceGrab.grab; - - if (grab) - DeliverGrabbedEvent((InternalEvent*)ev, device, FALSE); - else { /* deliver to all root windows */ - xEvent *xi; - int i; - int filter; - - i = EventToXI2((InternalEvent*)ev, (xEvent**)&xi); - if (i != Success) - { - ErrorF("[Xi] %s: XI2 conversion failed in %s (%d)\n", - __func__, device->name, i); - return; - } - - filter = GetEventFilter(device, xi); - - for (i = 0; i < screenInfo.numScreens; i++) - DeliverEventsToWindow(device, screenInfo.screens[i]->root, xi, 1, - filter, NullGrab); - free(xi); - } -} - /** * Main device event processing function. * Called from when processing the events from the event queue. @@ -932,7 +903,7 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device) ev->any.type == ET_RawButtonRelease || ev->any.type == ET_RawMotion) { - ProcessRawEvent(&ev->raw_event, device); + DeliverRawEvent(&ev->raw_event, device); return; } diff --git a/dix/events.c b/dix/events.c index 9063c28f5..8a4c6b9ac 100644 --- a/dix/events.c +++ b/dix/events.c @@ -2243,6 +2243,35 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent return nondeliveries; } +void +DeliverRawEvent(RawDeviceEvent *ev, DeviceIntPtr device) +{ + GrabPtr grab = device->deviceGrab.grab; + + if (grab) + DeliverGrabbedEvent((InternalEvent*)ev, device, FALSE); + else { /* deliver to all root windows */ + xEvent *xi; + int i; + int filter; + + i = EventToXI2((InternalEvent*)ev, (xEvent**)&xi); + if (i != Success) + { + ErrorF("[Xi] %s: XI2 conversion failed in %s (%d)\n", + __func__, device->name, i); + return; + } + + filter = GetEventFilter(device, xi); + + for (i = 0; i < screenInfo.numScreens; i++) + DeliverEventsToWindow(device, screenInfo.screens[i]->root, xi, 1, + filter, NullGrab); + free(xi); + } +} + /* If the event goes to dontClient, don't send it and return 0. if send works, return 1 or if send didn't work, return 2. Only works for core events. diff --git a/include/dix.h b/include/dix.h index 9a111e8a7..b1bf9ed82 100644 --- a/include/dix.h +++ b/include/dix.h @@ -387,6 +387,11 @@ extern _X_EXPORT int DeliverEventsToWindow( Mask /* filter */, GrabPtr /* grab */); +extern _X_EXPORT void DeliverRawEvent( + RawDeviceEvent* /* ev */, + DeviceIntPtr /* dev */ +); + extern int DeliverDeviceEvents( WindowPtr /* pWin */, InternalEvent* /* event */, From 16244fba001826190445302f56784f5de9c59c01 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 2 Jun 2011 13:50:13 +1000 Subject: [PATCH 09/11] Support (and require) XI 2.1 Signed-off-by: Peter Hutterer Reviewed-by: Jeremy Huddleston Reviewed-by: Daniel Stone --- configure.ac | 2 +- include/protocol-versions.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 22566c9ef..da33c1626 100644 --- a/configure.ac +++ b/configure.ac @@ -785,7 +785,7 @@ WINDOWSWMPROTO="windowswmproto" APPLEWMPROTO="applewmproto >= 1.4" dnl Core modules for most extensions, et al. -SDK_REQUIRED_MODULES="[xproto >= 7.0.17] [randrproto >= 1.2.99.3] [renderproto >= 0.11] [xextproto >= 7.1.99] [inputproto >= 1.9.99.902] [kbproto >= 1.0.3] fontsproto" +SDK_REQUIRED_MODULES="[xproto >= 7.0.17] [randrproto >= 1.2.99.3] [renderproto >= 0.11] [xextproto >= 7.1.99] [inputproto >= 2.0.99.1] [kbproto >= 1.0.3] fontsproto" # Make SDK_REQUIRED_MODULES available for inclusion in xorg-server.pc AC_SUBST(SDK_REQUIRED_MODULES) diff --git a/include/protocol-versions.h b/include/protocol-versions.h index 7b7a9f53c..832bcf756 100644 --- a/include/protocol-versions.h +++ b/include/protocol-versions.h @@ -127,7 +127,7 @@ /* X Input */ #define SERVER_XI_MAJOR_VERSION 2 -#define SERVER_XI_MINOR_VERSION 0 +#define SERVER_XI_MINOR_VERSION 1 /* XKB */ #define SERVER_XKB_MAJOR_VERSION 1 From b6b1f1b514bf14ddf6b265b8d4551f892ded0dd2 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 11 May 2011 13:56:08 +1000 Subject: [PATCH 10/11] input: deliver raw events unconditionally for XI 2.1 clients. Deliver raw events regardless whether there is a grab on or not for clients supporting 2.1 or later. Signed-off-by: Peter Hutterer Reviewed-by: Jeremy Huddleston Reviewed-by: Daniel Stone --- dix/events.c | 93 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 77 insertions(+), 16 deletions(-) diff --git a/dix/events.c b/dix/events.c index 8a4c6b9ac..2112a47db 100644 --- a/dix/events.c +++ b/dix/events.c @@ -2243,35 +2243,96 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent return nondeliveries; } +/** + * Filter out raw events for XI 2.0 and XI 2.1 clients. + * + * If there is a grab on the device, 2.0 clients only get raw events if they + * have the grab. 2.1+ clients get raw events in all cases. + * + * @return TRUE if the event should be discarded, FALSE otherwise. + */ +static BOOL +FilterRawEvents(const ClientPtr client, const GrabPtr grab) +{ + XIClientPtr client_xi_version; + int cmp; + + /* device not grabbed -> don't filter */ + if (!grab) + return FALSE; + + client_xi_version = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey); + + cmp = version_compare(client_xi_version->major_version, + client_xi_version->minor_version, 2, 0); + /* XI 2.0: if device is grabbed, skip + XI 2.1: if device is grabbed by us, skip, we've already delivered */ + return (cmp == 0) ? TRUE : SameClient(grab, client); +} + +/** + * Deliver a raw event to the grab owner (if any) and to all root windows. + * + * Raw event delivery differs between XI 2.0 and XI 2.1. + * XI 2.0: events delivered to the grabbing client (if any) OR to all root + * windows + * XI 2.1: events delivered to all root windows, regardless of grabbing + * state. + */ void DeliverRawEvent(RawDeviceEvent *ev, DeviceIntPtr device) { GrabPtr grab = device->deviceGrab.grab; + xEvent *xi; + int i; + int filter; + + i = EventToXI2((InternalEvent*)ev, (xEvent**)&xi); + if (i != Success) + { + ErrorF("[Xi] %s: XI2 conversion failed in %s (%d)\n", + __func__, device->name, i); + return; + } if (grab) DeliverGrabbedEvent((InternalEvent*)ev, device, FALSE); - else { /* deliver to all root windows */ - xEvent *xi; - int i; - int filter; - i = EventToXI2((InternalEvent*)ev, (xEvent**)&xi); - if (i != Success) + filter = GetEventFilter(device, xi); + + for (i = 0; i < screenInfo.numScreens; i++) + { + WindowPtr root; + InputClients *inputclients; + + root = screenInfo.screens[i]->root; + if (!GetClientsForDelivery(device, root, xi, filter, &inputclients)) + continue; + + for (; inputclients; inputclients = inputclients->next) { - ErrorF("[Xi] %s: XI2 conversion failed in %s (%d)\n", - __func__, device->name, i); - return; + ClientPtr c; /* unused */ + Mask m; /* unused */ + InputClients ic = *inputclients; + + /* Because we run through the list manually, copy the actual + * list, shorten the copy to only have one client and then pass + * that down to DeliverEventToInputClients. This way we avoid + * double events on XI 2.1 clients that have a grab on the + * device. + */ + ic.next = NULL; + + if (!FilterRawEvents(rClient(&ic), grab)) + DeliverEventToInputClients(device, &ic, root, xi, 1, + filter, NULL, &c, &m); } - - filter = GetEventFilter(device, xi); - - for (i = 0; i < screenInfo.numScreens; i++) - DeliverEventsToWindow(device, screenInfo.screens[i]->root, xi, 1, - filter, NullGrab); - free(xi); } + + free(xi); } + /* If the event goes to dontClient, don't send it and return 0. if send works, return 1 or if send didn't work, return 2. Only works for core events. From 52c9b59a9fed6abfeca775a7a04133cee18eac0b Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 30 May 2011 09:47:06 +1000 Subject: [PATCH 11/11] dix: use 'rc' for return code in DeliverRawEvent Reported-by: Walter Harms Signed-off-by: Peter Hutterer Reviewed-by: Cyril Brulebois Reviewed-by: Jeremy Huddleston Reviewed-by: Daniel Stone --- dix/events.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dix/events.c b/dix/events.c index 2112a47db..6b74b1aa9 100644 --- a/dix/events.c +++ b/dix/events.c @@ -2284,14 +2284,14 @@ DeliverRawEvent(RawDeviceEvent *ev, DeviceIntPtr device) { GrabPtr grab = device->deviceGrab.grab; xEvent *xi; - int i; + int i, rc; int filter; - i = EventToXI2((InternalEvent*)ev, (xEvent**)&xi); - if (i != Success) + rc = EventToXI2((InternalEvent*)ev, (xEvent**)&xi); + if (rc != Success) { ErrorF("[Xi] %s: XI2 conversion failed in %s (%d)\n", - __func__, device->name, i); + __func__, device->name, rc); return; }