diff --git a/Xi/exevents.c b/Xi/exevents.c index aa2b4c9de..2baaa58e3 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -89,26 +89,56 @@ Bool ShouldFreeInputMasks(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. * */ +#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 RegisterOtherDevice(DeviceIntPtr device) { - device->public.processInputProc = ProcessOtherEvent; - device->public.realInputProc = ProcessOtherEvent; - if (DeviceIsPointerType(device)) + xiDevPrivatePtr xiPrivPtr; + + if (serverGeneration != _xiServerGeneration) { - (device)->deviceGrab.ActivateGrab = ActivatePointerGrab; - (device)->deviceGrab.DeactivateGrab = DeactivatePointerGrab; - } else - { - (device)->deviceGrab.ActivateGrab = ActivateKeyboardGrab; - (device)->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab; + xiDevPrivateIndex = AllocateDevicePrivateIndex(); + if (xiDevPrivateIndex == 1) + { + FatalError("[Xi] Could not allocate private index.\n"); + } + _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 @@ -126,6 +156,17 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count) ValuatorClassPtr v = device->valuator; 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); if (xE->u.u.type != DeviceValuator && xE->u.u.type != GenericEvent) { diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c index 243623166..31c300811 100644 --- a/hw/xfree86/common/xf86Xinput.c +++ b/hw/xfree86/common/xf86Xinput.c @@ -179,15 +179,33 @@ xf86ActivateDevice(LocalDevicePtr local) dev->coreEvents = local->flags & XI86_ALWAYS_CORE; dev->spriteInfo->spriteOwner = !(local->flags & XI86_SHARED_POINTER); - RegisterOtherDevice(dev); - -#ifdef XKB - if (!DeviceIsPointerType(dev) && !noXkbExtension) + if (DeviceIsPointerType(dev)) { - XkbSetExtension(dev, ProcessKeyboardEvent); - } +#ifdef XKB + dev->public.processInputProc = CoreProcessPointerEvent; + dev->public.realInputProc = CoreProcessPointerEvent; +#else + dev->public.processInputProc = ProcessPointerEvent; + dev->public.realInputProc = ProcessPointerEvent; #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) xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n", diff --git a/mi/mieq.c b/mi/mieq.c index c3f63fb8b..78e57adc4 100644 --- a/mi/mieq.c +++ b/mi/mieq.c @@ -232,7 +232,6 @@ mieqProcessInputEvents(void) { EventRec *e = NULL; int x = 0, y = 0; - DeviceIntPtr dev = NULL; xEvent* event; while (miEventQueue.head != miEventQueue.tail) { @@ -262,7 +261,8 @@ mieqProcessInputEvents(void) if (miEventQueue.handlers[e->events->event->u.u.type]) { miEventQueue.handlers[e->events->event->u.u.type]( DequeueScreen(e->pDev)->myNum, - e->events->event, dev, + e->events->event, + e->pDev, e->nevents); return; } @@ -272,17 +272,7 @@ mieqProcessInputEvents(void) if (e->events->event[0].u.u.type == KeyPress || e->events->event[0].u.u.type == KeyRelease) { 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 * events at once is a DeviceMotionNotify followed by @@ -303,11 +293,7 @@ mieqProcessInputEvents(void) event = e->events->event; } - /* MPX devices send both core and Xi events. - * 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); + e->pDev->public.processInputProc(event, e->pDev, e->nevents); if (e->nevents > 1) xfree(event);