diff --git a/Xi/exevents.c b/Xi/exevents.c index 8f60561e9..aa2b4c9de 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -126,9 +126,6 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count) ValuatorClassPtr v = device->valuator; deviceValuator *xV = (deviceValuator *) xE; - if (grab && grab->coreGrab && !device->deviceGrab.fromPassiveGrab) - return; - CheckMotion(xE, device); if (xE->u.u.type != DeviceValuator && xE->u.u.type != GenericEvent) { diff --git a/Xi/extinit.c b/Xi/extinit.c index 70253fe82..1d23809dc 100644 --- a/Xi/extinit.c +++ b/Xi/extinit.c @@ -879,8 +879,20 @@ FixExtensionEvents(ExtensionEntry * extEntry) SetEventInfo(GetNextExtEventMask(), _deviceButton3Motion); SetEventInfo(GetNextExtEventMask(), _deviceButton4Motion); SetEventInfo(GetNextExtEventMask(), _deviceButton5Motion); + + /* If DeviceButtonMotionMask is != ButtonMotionMask, event delivery + * breaks down. The device needs the dev->button->motionMask. If DBMM is + * the same as BMM, we can ensure that both core and device events can be + * delivered, without the need for extra structures in the DeviceIntRec. + */ DeviceButtonMotionMask = GetNextExtEventMask(); SetEventInfo(DeviceButtonMotionMask, _deviceButtonMotion); + if (DeviceButtonMotionMask != ButtonMotionMask) + { + /* This should never happen, but if it does, hide under the + * bed and cry for help. */ + ErrorF("DeviceButtonMotionMask != ButtonMotionMask. Trouble!\n"); + } DeviceFocusChangeMask = GetNextExtEventMask(); SetMaskForExtEvent(DeviceFocusChangeMask, DeviceFocusIn); diff --git a/dix/devices.c b/dix/devices.c index 60825c156..fbb6cba66 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -458,8 +458,8 @@ InitCoreDevices(void) #ifdef XKB dev->public.processInputProc = CoreProcessKeyboardEvent; dev->public.realInputProc = CoreProcessKeyboardEvent; - if (!noXkbExtension) - XkbSetExtension(dev, ProcessKeyboardEvent); + /*if (!noXkbExtension)*/ + /*XkbSetExtension(dev, ProcessKeyboardEvent);*/ #else dev->public.processInputProc = ProcessKeyboardEvent; dev->public.realInputProc = ProcessKeyboardEvent; diff --git a/dix/events.c b/dix/events.c index 0f413a670..07a191fa3 100644 --- a/dix/events.c +++ b/dix/events.c @@ -3524,7 +3524,9 @@ drawable.id:0; #endif ))) #endif - XE_KBPTR.state = (keyc->state | GetPairedPointer(keybd)->button->state); + /* ProcessOtherEvent already updated the keyboard's state, so we need to + * access prev_state here! */ + XE_KBPTR.state = (keyc->prev_state | GetPairedPointer(keybd)->button->state); XE_KBPTR.rootX = keybd->spriteInfo->sprite->hot.x; XE_KBPTR.rootY = keybd->spriteInfo->sprite->hot.y; key = xE->u.u.detail; @@ -3545,31 +3547,14 @@ drawable.id:0; switch (xE->u.u.type) { case KeyPress: - if (*kptr & bit) /* allow ddx to generate multiple downs */ - { - if (!modifiers) - { - xE->u.u.type = KeyRelease; - (*keybd->public.processInputProc)(xE, keybd, count); - xE->u.u.type = KeyPress; - /* release can have side effects, don't fall through */ - (*keybd->public.processInputProc)(xE, keybd, count); - } - return; - } - GetPairedPointer(keybd)->valuator->motionHintWindow = NullWindow; - *kptr |= bit; - keyc->prev_state = keyc->state; - for (i = 0, mask = 1; modifiers; i++, mask <<= 1) - { - if (mask & modifiers) - { - /* This key affects modifier "i" */ - keyc->modifierKeyCount[i]++; - keyc->state |= mask; - modifiers &= ~mask; - } - } + /* We MUST NOT change the device itself here. All device state + * changes must be performed in ProcessOtherEvents. We're dealing + * with the same device struct, so if we change it in POE and + * here, we've just screwed up the state by setting it twice. + * + * Devices may not send core events but always send XI events, so + * the state must be changed in POE, not here. + */ if (!grab && CheckDeviceGrabs(keybd, xE, 0, count)) { grabinfo->activatingKey = key; @@ -3579,20 +3564,7 @@ drawable.id:0; case KeyRelease: if (!(*kptr & bit)) /* guard against duplicates */ return; - GetPairedPointer(keybd)->valuator->motionHintWindow = NullWindow; - *kptr &= ~bit; - keyc->prev_state = keyc->state; - for (i = 0, mask = 1; modifiers; i++, mask <<= 1) - { - if (mask & modifiers) { - /* This key affects modifier "i" */ - if (--keyc->modifierKeyCount[i] <= 0) { - keyc->state &= ~mask; - keyc->modifierKeyCount[i] = 0; - } - modifiers &= ~mask; - } - } + /* No device state changes, see comment for KeyPress */ if (grabinfo->fromPassiveGrab && (key == grabinfo->activatingKey)) deactivateGrab = TRUE; break; @@ -3729,31 +3701,21 @@ ProcessPointerEvent (xEvent *xE, DeviceIntPtr mouse, int count) switch (xE->u.u.type) { case ButtonPress: - mouse->valuator->motionHintWindow = NullWindow; - if (!(*kptr & bit)) - butc->buttonsDown++; - butc->motionMask = ButtonMotionMask; - *kptr |= bit; + /* + * We rely on the fact that ButtonMotionMask is the same as + * DeviceButtonMotionMask, so setting the motionMask + * to this value ensures correctness for both XI and core events. + */ if (xE->u.u.detail == 0) return; - if (xE->u.u.detail <= 5) - butc->state |= (Button1Mask >> 1) << xE->u.u.detail; filters[MotionNotify] = Motion_Filter(butc); if (!grab) if (CheckDeviceGrabs(mouse, xE, 0, count)) return; break; case ButtonRelease: - mouse->valuator->motionHintWindow = NullWindow; - if (*kptr & bit) - --butc->buttonsDown; - if (!butc->buttonsDown) - butc->motionMask = 0; - *kptr &= ~bit; if (xE->u.u.detail == 0) return; - if (xE->u.u.detail <= 5) - butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail); filters[MotionNotify] = Motion_Filter(butc); if (!butc->state && mouse->deviceGrab.fromPassiveGrab) deactivateGrab = TRUE;