Wrap core event handling through ProcessOtherEvents.
When processing events from the EQ, _always_ call the processInputProc of the matching device. For XI devices, this proc is wrapped in three layers. Core event handling is wrapped by XI event handling, which is wrapped by XKB. A core event now passes through XKB -> XI -> DIX. This gets rid of a sync'd grab problem: with the previous code, core events did disappear during a sync'd device grab on account of mieqProcessInputEvents calling the processInputProc of the VCP/VCK instead of the actual device. This lead to the event being processed as normal instead of being enqueued for later replaying.
This commit is contained in:
parent
b2a4883bd8
commit
340911d724
|
@ -89,26 +89,56 @@ Bool ShouldFreeInputMasks(WindowPtr /* pWin */ ,
|
||||||
static Bool MakeInputMasks(WindowPtr /* pWin */
|
static Bool MakeInputMasks(WindowPtr /* pWin */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static int xiDevPrivateIndex = 0;
|
||||||
|
static int _xiServerGeneration = -1;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ProcessInputProc processInputProc;
|
||||||
|
ProcessInputProc realInputProc;
|
||||||
|
} xiDevPrivateRec, *xiDevPrivatePtr;
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
*
|
*
|
||||||
* Procedures for extension device event routing.
|
* Procedures for extension device event routing.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define WRAP_PROCESS_INPUT_PROC(device, saveprocs, newproc) \
|
||||||
|
saveprocs->processInputProc = device->public.processInputProc; \
|
||||||
|
saveprocs->realInputProc = device->public.realInputProc; \
|
||||||
|
device->public.processInputProc = newproc; \
|
||||||
|
device->public.realInputProc = newproc;
|
||||||
|
|
||||||
|
#define UNWRAP_PROCESS_INPUT_PROC(device, saveprocs) \
|
||||||
|
device->public.processInputProc = saveprocs->processInputProc; \
|
||||||
|
device->public.realInputProc = saveprocs->realInputProc;
|
||||||
|
|
||||||
void
|
void
|
||||||
RegisterOtherDevice(DeviceIntPtr device)
|
RegisterOtherDevice(DeviceIntPtr device)
|
||||||
{
|
{
|
||||||
device->public.processInputProc = ProcessOtherEvent;
|
xiDevPrivatePtr xiPrivPtr;
|
||||||
device->public.realInputProc = ProcessOtherEvent;
|
|
||||||
if (DeviceIsPointerType(device))
|
if (serverGeneration != _xiServerGeneration)
|
||||||
{
|
{
|
||||||
(device)->deviceGrab.ActivateGrab = ActivatePointerGrab;
|
xiDevPrivateIndex = AllocateDevicePrivateIndex();
|
||||||
(device)->deviceGrab.DeactivateGrab = DeactivatePointerGrab;
|
if (xiDevPrivateIndex == 1)
|
||||||
} else
|
|
||||||
{
|
{
|
||||||
(device)->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
|
FatalError("[Xi] Could not allocate private index.\n");
|
||||||
(device)->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
|
|
||||||
}
|
}
|
||||||
|
_xiServerGeneration = serverGeneration;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AllocateDevicePrivate(device, xiDevPrivateIndex))
|
||||||
|
FatalError("[Xi] Dev private allocation failed.\n");
|
||||||
|
|
||||||
|
|
||||||
|
xiPrivPtr = (xiDevPrivatePtr)xcalloc(1, sizeof(xiDevPrivateRec));
|
||||||
|
if (!xiPrivPtr)
|
||||||
|
FatalError("[Xi] Cannot get memory for dev private.\n");
|
||||||
|
|
||||||
|
device->devPrivates[xiDevPrivateIndex].ptr = xiPrivPtr;
|
||||||
|
|
||||||
|
WRAP_PROCESS_INPUT_PROC(device, xiPrivPtr, ProcessOtherEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*ARGSUSED*/ void
|
/*ARGSUSED*/ void
|
||||||
|
@ -126,6 +156,17 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
|
||||||
ValuatorClassPtr v = device->valuator;
|
ValuatorClassPtr v = device->valuator;
|
||||||
deviceValuator *xV = (deviceValuator *) xE;
|
deviceValuator *xV = (deviceValuator *) xE;
|
||||||
|
|
||||||
|
/* Handle core events. */
|
||||||
|
if (xE->u.u.type < LASTEvent && xE->u.u.type != GenericEvent)
|
||||||
|
{
|
||||||
|
xiDevPrivatePtr xiPrivPtr =
|
||||||
|
(xiDevPrivatePtr)device->devPrivates[xiDevPrivateIndex].ptr;
|
||||||
|
UNWRAP_PROCESS_INPUT_PROC(device, xiPrivPtr);
|
||||||
|
device->public.processInputProc(xE, device, count);
|
||||||
|
WRAP_PROCESS_INPUT_PROC(device, xiPrivPtr, ProcessOtherEvent);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CheckMotion(xE, device);
|
CheckMotion(xE, device);
|
||||||
|
|
||||||
if (xE->u.u.type != DeviceValuator && xE->u.u.type != GenericEvent) {
|
if (xE->u.u.type != DeviceValuator && xE->u.u.type != GenericEvent) {
|
||||||
|
|
|
@ -179,15 +179,33 @@ xf86ActivateDevice(LocalDevicePtr local)
|
||||||
dev->coreEvents = local->flags & XI86_ALWAYS_CORE;
|
dev->coreEvents = local->flags & XI86_ALWAYS_CORE;
|
||||||
dev->spriteInfo->spriteOwner = !(local->flags & XI86_SHARED_POINTER);
|
dev->spriteInfo->spriteOwner = !(local->flags & XI86_SHARED_POINTER);
|
||||||
|
|
||||||
RegisterOtherDevice(dev);
|
if (DeviceIsPointerType(dev))
|
||||||
|
|
||||||
#ifdef XKB
|
|
||||||
if (!DeviceIsPointerType(dev) && !noXkbExtension)
|
|
||||||
{
|
{
|
||||||
XkbSetExtension(dev, ProcessKeyboardEvent);
|
#ifdef XKB
|
||||||
}
|
dev->public.processInputProc = CoreProcessPointerEvent;
|
||||||
|
dev->public.realInputProc = CoreProcessPointerEvent;
|
||||||
|
#else
|
||||||
|
dev->public.processInputProc = ProcessPointerEvent;
|
||||||
|
dev->public.realInputProc = ProcessPointerEvent;
|
||||||
#endif
|
#endif
|
||||||
|
dev->deviceGrab.ActivateGrab = ActivatePointerGrab;
|
||||||
|
dev->deviceGrab.DeactivateGrab = DeactivatePointerGrab;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
#ifdef XKB
|
||||||
|
dev->public.processInputProc = CoreProcessKeyboardEvent;
|
||||||
|
dev->public.realInputProc = CoreProcessKeyboardEvent;
|
||||||
|
#else
|
||||||
|
dev->public.processInputProc = ProcessKeyboardEvent;
|
||||||
|
dev->public.realInputProc = ProcessKeyboardEvent;
|
||||||
|
#endif
|
||||||
|
dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
|
||||||
|
dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegisterOtherDevice(dev);
|
||||||
|
if (!noXkbExtension)
|
||||||
|
XkbSetExtension(dev, ProcessOtherEvent);
|
||||||
|
|
||||||
if (serverGeneration == 1)
|
if (serverGeneration == 1)
|
||||||
xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n",
|
xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n",
|
||||||
|
|
20
mi/mieq.c
20
mi/mieq.c
|
@ -232,7 +232,6 @@ mieqProcessInputEvents(void)
|
||||||
{
|
{
|
||||||
EventRec *e = NULL;
|
EventRec *e = NULL;
|
||||||
int x = 0, y = 0;
|
int x = 0, y = 0;
|
||||||
DeviceIntPtr dev = NULL;
|
|
||||||
xEvent* event;
|
xEvent* event;
|
||||||
|
|
||||||
while (miEventQueue.head != miEventQueue.tail) {
|
while (miEventQueue.head != miEventQueue.tail) {
|
||||||
|
@ -262,7 +261,8 @@ mieqProcessInputEvents(void)
|
||||||
if (miEventQueue.handlers[e->events->event->u.u.type]) {
|
if (miEventQueue.handlers[e->events->event->u.u.type]) {
|
||||||
miEventQueue.handlers[e->events->event->u.u.type](
|
miEventQueue.handlers[e->events->event->u.u.type](
|
||||||
DequeueScreen(e->pDev)->myNum,
|
DequeueScreen(e->pDev)->myNum,
|
||||||
e->events->event, dev,
|
e->events->event,
|
||||||
|
e->pDev,
|
||||||
e->nevents);
|
e->nevents);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -272,17 +272,7 @@ mieqProcessInputEvents(void)
|
||||||
if (e->events->event[0].u.u.type == KeyPress ||
|
if (e->events->event[0].u.u.type == KeyPress ||
|
||||||
e->events->event[0].u.u.type == KeyRelease) {
|
e->events->event[0].u.u.type == KeyRelease) {
|
||||||
SwitchCoreKeyboard(e->pDev);
|
SwitchCoreKeyboard(e->pDev);
|
||||||
dev = inputInfo.keyboard;
|
|
||||||
}
|
}
|
||||||
else if (e->events->event[0].u.u.type == MotionNotify ||
|
|
||||||
e->events->event[0].u.u.type == ButtonPress ||
|
|
||||||
e->events->event[0].u.u.type == ButtonRelease) {
|
|
||||||
dev = inputInfo.pointer;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dev = e->pDev;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* FIXME: Bad hack. The only event where we actually get multiple
|
/* FIXME: Bad hack. The only event where we actually get multiple
|
||||||
* events at once is a DeviceMotionNotify followed by
|
* events at once is a DeviceMotionNotify followed by
|
||||||
|
@ -303,11 +293,7 @@ mieqProcessInputEvents(void)
|
||||||
event = e->events->event;
|
event = e->events->event;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MPX devices send both core and Xi events.
|
e->pDev->public.processInputProc(event, e->pDev, e->nevents);
|
||||||
* Use dev to get the correct processing function but supply
|
|
||||||
* e->pDev to pass the correct device
|
|
||||||
*/
|
|
||||||
dev->public.processInputProc(event, e->pDev, e->nevents);
|
|
||||||
|
|
||||||
if (e->nevents > 1)
|
if (e->nevents > 1)
|
||||||
xfree(event);
|
xfree(event);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user