diff --git a/dix/devices.c b/dix/devices.c index 034d5e6d2..ac5806a28 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -1239,7 +1239,7 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels, if (!dev) return FALSE; - if (numAxes >= MAX_VALUATORS) + if (numAxes > MAX_VALUATORS) { LogMessage(X_WARNING, "Device '%s' has %d axes, only using first %d.\n", diff --git a/dix/events.c b/dix/events.c index ae9847c93..e1c3d0a02 100644 --- a/dix/events.c +++ b/dix/events.c @@ -3420,7 +3420,6 @@ CheckPassiveGrabsOnWindow( { DeviceIntPtr gdev; XkbSrvInfoPtr xkbi = NULL; - Mask mask = 0; gdev= grab->modifierDevice; if (grab->grabtype == GRABTYPE_CORE) @@ -3535,9 +3534,6 @@ CheckPassiveGrabsOnWindow( } xE = &core; count = 1; - mask = grab->eventMask; - if (grab->ownerEvents) - mask |= pWin->eventMask; } else if (match & XI2_MATCH) { rc = EventToXI2((InternalEvent*)event, &xE); @@ -3549,34 +3545,6 @@ CheckPassiveGrabsOnWindow( continue; } count = 1; - - /* FIXME: EventToXI2 returns NULL for enter events, so - * dereferencing the event is bad. Internal event types are - * aligned with core events, so the else clause is valid. - * long-term we should use internal events for enter/focus - * as well */ - if (xE) - mask = grab->xi2mask[device->id][((xGenericEvent*)xE)->evtype/8]; - else if (event->type == XI_Enter || event->type == XI_FocusIn) - mask = grab->xi2mask[device->id][event->type/8]; - - if (grab->ownerEvents && wOtherInputMasks(grab->window)) - { - InputClientsPtr icp = - wOtherInputMasks(grab->window)->inputClients; - - while(icp) - { - if (rClient(icp) == rClient(grab)) - { - int evtype = (xE) ? ((xGenericEvent*)xE)->evtype : event->type; - mask |= icp->xi2mask[device->id][evtype/8]; - break; - } - - icp = icp->next; - } - } } else { rc = EventToXI((InternalEvent*)event, &xE, &count); @@ -3587,23 +3555,6 @@ CheckPassiveGrabsOnWindow( "(%d, %d).\n", device->name, event->type, rc); continue; } - mask = grab->eventMask; - if (grab->ownerEvents && wOtherInputMasks(grab->window)) - { - InputClientsPtr icp = - wOtherInputMasks(grab->window)->inputClients; - - while(icp) - { - if (rClient(icp) == rClient(grab)) - { - mask |= icp->mask[device->id]; - break; - } - - icp = icp->next; - } - } } (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE); @@ -3612,7 +3563,8 @@ CheckPassiveGrabsOnWindow( { FixUpEventFromWindow(device, xE, grab->window, None, TRUE); - TryClientEvents(rClient(grab), device, xE, count, mask, + TryClientEvents(rClient(grab), device, xE, count, + GetEventFilter(device, xE), GetEventFilter(device, xE), grab); } diff --git a/include/xkbsrv.h b/include/xkbsrv.h index 5847e6395..9f1507e8e 100644 --- a/include/xkbsrv.h +++ b/include/xkbsrv.h @@ -924,6 +924,15 @@ extern int XkbGetEffectiveGroup( XkbStatePtr /* xkbstate */, CARD8 /* keycode */); +extern void XkbMergeLockedPtrBtns( + DeviceIntPtr /* master */); + +extern void XkbFakeDeviceButton( + DeviceIntPtr /* dev */, + int /* press */, + int /* button */); + + #include "xkbfile.h" #include "xkbrules.h" diff --git a/xkb/xkbAccessX.c b/xkb/xkbAccessX.c index b5486b73b..10c38ca47 100644 --- a/xkb/xkbAccessX.c +++ b/xkb/xkbAccessX.c @@ -707,27 +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)); + + if (IsMaster(dev)) + { + DeviceIntPtr source; + int rc; + rc = dixLookupDevice(&source, event->sourceid, serverClient, DixWriteAccess); + if (rc != Success) + ErrorF("[xkb] bad sourceid '%d' on button release event.\n", event->sourceid); + else if (!IsXTestDevice(source, GetMaster(dev, MASTER_POINTER))) + XkbFakeDeviceButton(dev, FALSE, event->detail.key); + } + } + changed |= XkbPointerButtonMask; } - /* Guesswork. mostly. - * xkb actuall goes through some effort to transparently wrap the - * processInputProcs (see XkbSetExtension). But we all love fun, so the - * previous XKB implementation just hardcoded the CPPE call here instead - * of unwrapping like anybody with any sense of decency would do. - * I got no clue what the correct thing to do is, but my guess is that - * it's not hardcoding. I may be wrong. whatever it is, don't come whining - * to me. I just work here. - * - * Anyway. here's the old call, if you don't like the wrapping, revert it. - * - * CoreProcessPointerEvent(xE,mouse,count); - * - * see. it's still steaming. told you. (whot) - */ - UNWRAP_PROCESS_INPUT_PROC(mouse, xkbPrivPtr, backupproc); mouse->public.processInputProc(ev, mouse); COND_WRAP_PROCESS_INPUT_PROC(mouse, xkbPrivPtr, diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c index c5030d04d..96d3847b9 100644 --- a/xkb/xkbActions.c +++ b/xkb/xkbActions.c @@ -45,7 +45,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. DevPrivateKeyRec xkbDevicePrivateKeyRec; -static void XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button); +void XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button); static void XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y); void @@ -500,9 +500,6 @@ _XkbFilterPointerMove( XkbSrvInfoPtr xkbi, int x,y; Bool accel; - if (xkbi->device == inputInfo.keyboard) - return 0; - if (filter->keycode==0) { /* initial press */ filter->keycode = keycode; filter->active = 1; @@ -633,6 +630,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; @@ -1332,10 +1339,12 @@ XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y) DeviceIntPtr ptr; int gpe_flags = 0; - if (!dev->u.master) + if (IsMaster(dev)) + ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER)); + else if (!dev->u.master) ptr = dev; else - ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER)); + return; if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY) gpe_flags = POINTER_ABSOLUTE; @@ -1355,7 +1364,7 @@ XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y) FreeEventList(events, GetMaximumEventsNum()); } -static void +void XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button) { EventListPtr events; diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c index 3344e5088..14dc784b8 100644 --- a/xkb/xkbUtils.c +++ b/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; + } +}