diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2009-01-08 11:53:30 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2009-01-15 09:28:01 +1000 |
commit | d645721170b1196e5064b397cfbffd1da8c79bb1 (patch) | |
tree | 10771fb7ebc4a14a3fae98fb40bcbce55771e360 | |
parent | 639f289dcdbe00a516820f573c01a8339e120ed4 (diff) |
mi: ensure chained button mappings from SD -> MD (#19282)
After copying the master event, flip the detail field to the mapped button of
the SD, not the physical button. This way if the SD has a mapping 1:3 and the
MD has a mapping of 3:4, a press on button 1 on the SD results in a core event
on button 4.
X.Org Bug 19282 <http://bugs.freedesktop.org/show_bug.cgi?id=19282>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r-- | mi/mieq.c | 26 | ||||
-rw-r--r-- | xkb/ddxDevBtn.c | 2 |
2 files changed, 25 insertions, 3 deletions
@@ -320,21 +320,38 @@ ChangeDeviceID(DeviceIntPtr dev, xEvent* event) ((xGenericEvent*)event)->extension, ((xGenericEvent*)event)->evtype); } else DebugF("[mi] Unknown event type (%d), cannot change id.\n", type); } +static void +FixUpEventForMaster(DeviceIntPtr mdev, DeviceIntPtr sdev, xEvent* original, + EventListPtr master, int count) +{ + /* 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->u.u.type == DeviceButtonPress || original->u.u.type == DeviceButtonRelease) + { + int btn = original->u.u.detail; + if (!sdev->button) + return; /* Should never happen */ + + master->event->u.u.detail = sdev->button->map[btn]; + } +} + /** * Copy the given event into master. * @param mdev The master device + * @param sdev The slave device the original event comes from * @param original The event as it came from the EQ * @param master The event after being copied * @param count Number of events in original. */ void -CopyGetMasterEvent(DeviceIntPtr mdev, xEvent* original, +CopyGetMasterEvent(DeviceIntPtr mdev, DeviceIntPtr sdev, xEvent* original, EventListPtr master, int count) { int len = count * sizeof(xEvent); /* Assumption: GenericEvents always have count 1 */ @@ -343,15 +360,20 @@ CopyGetMasterEvent(DeviceIntPtr mdev, xEvent* original, if (master->evlen < len) SetMinimumEventSize(master, 1, len); memcpy(master->event, original, len); while (count--) + { ChangeDeviceID(mdev, &master->event[count]); + FixUpEventForMaster(mdev, sdev, original, master, count); + } } + + /* Call this from ProcessInputEvents(). */ void mieqProcessInputEvents(void) { mieqHandler handler; EventRec *e = NULL; @@ -416,13 +438,13 @@ mieqProcessInputEvents(void) x = event->u.keyButtonPointer.rootX; y = event->u.keyButtonPointer.rootY; NewCurrentScreen (dev, DequeueScreen(dev), x, y); } else { if (master) - CopyGetMasterEvent(master, event, masterEvents, nevents); + CopyGetMasterEvent(master, dev, event, masterEvents, nevents); /* If someone's registered a custom event handler, let them * steal it. */ if (handler) { handler(DequeueScreen(dev)->myNum, event, dev, nevents); diff --git a/xkb/ddxDevBtn.c b/xkb/ddxDevBtn.c index 709efc13a..03fb440fe 100644 --- a/xkb/ddxDevBtn.c +++ b/xkb/ddxDevBtn.c @@ -113,13 +113,13 @@ DeviceIntPtr master = NULL; SetMinimumEventSize(masterEvents, 1, (1 + MAX_VALUATOR_EVENTS) * sizeof(xEvent)); } master = dev->u.master; if (!IsPointerDevice(master)) master = GetPairedDevice(dev->u.master); - CopyGetMasterEvent(master, &events, masterEvents, count); + CopyGetMasterEvent(master, dev, &events, masterEvents, count); } (*dev->public.processInputProc)((xEventPtr)btn, dev, count); if (master) { (*master->public.processInputProc)(masterEvents->event, master, count); |