From 87559ccfc67a98a75fa8068066871c35caa88e30 Mon Sep 17 00:00:00 2001 From: marha Date: Thu, 1 Jul 2010 06:37:06 +0000 Subject: git update 1/7/2010 --- xorg-server/xkb/xkbAccessX.c | 18 +++++++++++++++++- xorg-server/xkb/xkbActions.c | 10 ++++++++++ xorg-server/xkb/xkbUtils.c | 26 ++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) (limited to 'xorg-server/xkb') diff --git a/xorg-server/xkb/xkbAccessX.c b/xorg-server/xkb/xkbAccessX.c index be12e5d83..22178b862 100644 --- a/xorg-server/xkb/xkbAccessX.c +++ b/xorg-server/xkb/xkbAccessX.c @@ -707,8 +707,24 @@ DeviceEvent *event = &ev->device_event; changed |= XkbPointerButtonMask; } else if (event->type == ET_ButtonRelease) { - if (xkbi) + if (xkbi) { xkbi->lockedPtrButtons&= ~(1 << (event->detail.key & 0x7)); + + /* Merge this MD's lockedPtrButtons with the one of all + * attached slave devices. + * The DIX uses a merged button state for MDs, not + * releasing buttons until the last SD has released + * thenm. If we unconditionally clear the + * lockedPtrButtons bit on the MD, a PointerKeys button + * release on the SD keyboard won't generate the required fake button + * event on the XTEST pointer, thus never processing the + * button event in the DIX and the XTEST pointer's + * buttons stay down - result is a stuck button. + */ + if (IsMaster(dev)) + XkbMergeLockedPtrBtns(dev); + } + changed |= XkbPointerButtonMask; } diff --git a/xorg-server/xkb/xkbActions.c b/xorg-server/xkb/xkbActions.c index 48eeeb772..1274f4871 100644 --- a/xorg-server/xkb/xkbActions.c +++ b/xorg-server/xkb/xkbActions.c @@ -633,6 +633,16 @@ _XkbFilterPointerBtn( XkbSrvInfoPtr xkbi, break; } xkbi->lockedPtrButtons&= ~(1<device)) + { + XkbMergeLockedPtrBtns(xkbi->device); + /* One SD still has lock set, don't post event */ + if ((xkbi->lockedPtrButtons & (1 << button)) != 0) + break; + } + + /* fallthrough */ case XkbSA_PtrBtn: XkbFakeDeviceButton(xkbi->device, 0, button); break; diff --git a/xorg-server/xkb/xkbUtils.c b/xorg-server/xkb/xkbUtils.c index b0e643e62..9db94773f 100644 --- a/xorg-server/xkb/xkbUtils.c +++ b/xorg-server/xkb/xkbUtils.c @@ -2094,3 +2094,29 @@ XkbGetEffectiveGroup(XkbSrvInfoPtr xkbi, XkbStatePtr xkbState, CARD8 keycode) return effectiveGroup; } + +/* Merge the lockedPtrButtons from all attached SDs for the given master + * device into the MD's state. + */ +void +XkbMergeLockedPtrBtns(DeviceIntPtr master) +{ + DeviceIntPtr d = inputInfo.devices; + XkbSrvInfoPtr xkbi = NULL; + + if (!IsMaster(master)) + return; + + if (!master->key) + return; + + xkbi = master->key->xkbInfo; + xkbi->lockedPtrButtons = 0; + + for (; d; d = d->next) { + if (IsMaster(d) || GetMaster(d, MASTER_KEYBOARD) != master || !d->key) + continue; + + xkbi->lockedPtrButtons |= d->key->xkbInfo->lockedPtrButtons; + } +} -- cgit v1.2.3