From 9809715afaafee9baf2aef348c1ebda7e8b3f076 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 9 Jul 2007 10:42:03 +0930 Subject: [PATCH] Change CheckMotion to ignore non-pointer events but acknowledge XI events. Call CheckMotion from ProcessOtherEvents() to make sure absolute XI events update the sprite before an event is sent. --- Xi/exevents.c | 2 ++ dix/events.c | 72 +++++++++++++++++++++++++++++++++++---------------- 2 files changed, 52 insertions(+), 22 deletions(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index c13b74705..8f60561e9 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -129,6 +129,8 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count) if (grab && grab->coreGrab && !device->deviceGrab.fromPassiveGrab) return; + CheckMotion(xE, device); + if (xE->u.u.type != DeviceValuator && xE->u.u.type != GenericEvent) { DeviceIntPtr mouse = NULL, kbd = NULL; GetSpritePosition(device, &rootX, &rootY); diff --git a/dix/events.c b/dix/events.c index 8fcbec76a..097ebba69 100644 --- a/dix/events.c +++ b/dix/events.c @@ -2449,10 +2449,16 @@ XYToWindow(DeviceIntPtr pDev, int x, int y) * position, then update the event with the new coordinates that may have been * changed. If the window underneath the sprite has changed, change to new * cursor and send enter/leave events. + * + * CheckMotion() will not do anything and return FALSE if the event is not a + * pointer event. + * + * @return TRUE if the sprite has moved or FALSE otherwise. */ Bool CheckMotion(xEvent *xE, DeviceIntPtr pDev) { + INT16 *rootX, *rootY; WindowPtr prevSpriteWin; SpritePtr pSprite = pDev->spriteInfo->sprite; @@ -2465,21 +2471,44 @@ CheckMotion(xEvent *xE, DeviceIntPtr pDev) if (xE && !syncEvents.playingEvents) { - if (pSprite->hot.pScreen != pSprite->hotPhys.pScreen) - { - pSprite->hot.pScreen = pSprite->hotPhys.pScreen; - RootWindow(pDev) = WindowTable[pSprite->hot.pScreen->myNum]; - } - pSprite->hot.x = XE_KBPTR.rootX; - pSprite->hot.y = XE_KBPTR.rootY; - if (pSprite->hot.x < pSprite->physLimits.x1) - pSprite->hot.x = pSprite->physLimits.x1; - else if (pSprite->hot.x >= pSprite->physLimits.x2) - pSprite->hot.x = pSprite->physLimits.x2 - 1; - if (pSprite->hot.y < pSprite->physLimits.y1) - pSprite->hot.y = pSprite->physLimits.y1; - else if (pSprite->hot.y >= pSprite->physLimits.y2) - pSprite->hot.y = pSprite->physLimits.y2 - 1; + /* GetPointerEvents() guarantees that pointer events have the correct + rootX/Y set already. */ + switch(xE->u.u.type) + { + case ButtonPress: + case ButtonRelease: + case MotionNotify: + rootX = &XE_KBPTR.rootX; + rootY = &XE_KBPTR.rootY; + break; + default: + if (xE->u.u.type == DeviceButtonPress || + xE->u.u.type == DeviceButtonRelease || + xE->u.u.type == DeviceMotionNotify) + { + rootX = &((deviceKeyButtonPointer*)xE)->root_x; + rootY = &((deviceKeyButtonPointer*)xE)->root_y; + break; + } + /* all other events return FALSE */ + return FALSE; + } + + if (pSprite->hot.pScreen != pSprite->hotPhys.pScreen) + { + pSprite->hot.pScreen = pSprite->hotPhys.pScreen; + RootWindow(pDev) = WindowTable[pSprite->hot.pScreen->myNum]; + } + pSprite->hot.x = *rootX; + pSprite->hot.y = *rootY; + if (pSprite->hot.x < pSprite->physLimits.x1) + pSprite->hot.x = pSprite->physLimits.x1; + else if (pSprite->hot.x >= pSprite->physLimits.x2) + pSprite->hot.x = pSprite->physLimits.x2 - 1; + if (pSprite->hot.y < pSprite->physLimits.y1) + pSprite->hot.y = pSprite->physLimits.y1; + else if (pSprite->hot.y >= pSprite->physLimits.y2) + pSprite->hot.y = pSprite->physLimits.y2 - 1; #ifdef SHAPE if (pSprite->hotShape) ConfineToShape(pDev, pSprite->hotShape, &pSprite->hot.x, &pSprite->hot.y); @@ -2490,16 +2519,16 @@ CheckMotion(xEvent *xE, DeviceIntPtr pDev) #endif pSprite->hotPhys = pSprite->hot; - if ((pSprite->hotPhys.x != XE_KBPTR.rootX) || - (pSprite->hotPhys.y != XE_KBPTR.rootY)) + if ((pSprite->hotPhys.x != *rootX) || + (pSprite->hotPhys.y != *rootY)) { (*pSprite->hotPhys.pScreen->SetCursorPosition)( pDev, pSprite->hotPhys.pScreen, pSprite->hotPhys.x, pSprite->hotPhys.y, FALSE); } - XE_KBPTR.rootX = pSprite->hot.x; - XE_KBPTR.rootY = pSprite->hot.y; + *rootX = pSprite->hot.x; + *rootY = pSprite->hot.y; } #ifdef XEVIE @@ -3635,9 +3664,8 @@ ProcessPointerEvent (xEvent *xE, DeviceIntPtr mouse, int count) } } /* We need to call CheckMotion for each event. It doesn't really give us - any benefit for relative devices, but absolute devices won't send - button events to the right position. - */ + any benefit for relative devices, but absolute devices may not send + button events to the right position otherwise. */ if (!CheckMotion(xE, mouse) && xE->u.u.type == MotionNotify) return; if (xE->u.u.type != MotionNotify)