From 37da3931460a1af1700b8189004b37a238c2c82c Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 8 Jan 2009 13:37:26 +1000 Subject: [PATCH] dix: fix WarpPointer calls for devices with custom valuator ranges (#19297) If the MD's lastSlave was a devices with custom axes ranges, then a WarpPointer would position the cursor at the wrong location. A WarpPointer request provides screen coordinates and these coordinates were scaled to the device range before warping. This patch consists of two parts: 1) in the WarpPointer handling, get the lastSlave and post the event through this device. 2) assume that WarpPointer coordinates are always in screen coordinates and prevent GPE from scaling them. Note that this breaks device-coordinate based XWarpDevicePointer calls (for which the spec isn't nailed down yet anyway) until a better solution is found. X.Org Bug 19297 Signed-off-by: Peter Hutterer --- dix/events.c | 19 ++++++++++++------- dix/getevents.c | 12 +++++++----- include/input.h | 1 + mi/mipointer.c | 2 +- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/dix/events.c b/dix/events.c index c1ca4e0..3889c4a 100644 --- a/dix/events.c +++ b/dix/events.c @@ -3139,8 +3139,8 @@ ProcWarpPointer(ClientPtr client) WindowPtr dest = NULL; int x, y, rc; ScreenPtr newScreen; - DeviceIntPtr dev = PickPointer(client); - SpritePtr pSprite = dev->spriteInfo->sprite; + DeviceIntPtr dev; + SpritePtr pSprite; REQUEST(xWarpPointerReq); REQUEST_SIZE_MATCH(xWarpPointerReq); @@ -3153,6 +3153,12 @@ ProcWarpPointer(ClientPtr client) return rc; } } + + dev = PickPointer(client); + if (dev->u.lastSlave) + dev = dev->u.lastSlave; + pSprite = dev->spriteInfo->sprite; + #ifdef PANORAMIX if(!noPanoramiXExtension) return XineramaWarpPointer(client); @@ -3219,13 +3225,12 @@ ProcWarpPointer(ClientPtr client) else if (y >= pSprite->physLimits.y2) y = pSprite->physLimits.y2 - 1; if (pSprite->hotShape) - ConfineToShape(PickPointer(client), pSprite->hotShape, &x, &y); - (*newScreen->SetCursorPosition)(PickPointer(client), newScreen, x, y, - TRUE); + ConfineToShape(dev, pSprite->hotShape, &x, &y); + (*newScreen->SetCursorPosition)(dev, newScreen, x, y, TRUE); } - else if (!PointerConfinedToScreen(PickPointer(client))) + else if (!PointerConfinedToScreen(dev)) { - NewCurrentScreen(PickPointer(client), newScreen, x, y); + NewCurrentScreen(dev, newScreen, x, y); } return Success; } diff --git a/dix/getevents.c b/dix/getevents.c index 40d7b84..d9a2ce5 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -684,14 +684,16 @@ accelPointer(DeviceIntPtr dev, int first, int num, int *valuators, CARD32 ms) * @param scr Screen the device's sprite is currently on. * @param screenx Screen x coordinate the sprite is on after the update. * @param screeny Screen y coordinate the sprite is on after the update. + * @param screen TRUE if the @x and @y are in screen coordinates. */ static void positionSprite(DeviceIntPtr dev, int *x, int *y, - ScreenPtr scr, int *screenx, int *screeny) + ScreenPtr scr, int *screenx, int *screeny, + BOOL screen) { - /* scale x&y to screen */ - *screenx = rescaleValuatorAxis(*x, dev->valuator->axes + 0, NULL, scr->width); - *screeny = rescaleValuatorAxis(*y, dev->valuator->axes + 1, NULL, scr->height); + /* scale x&y to screen if necessary */ + *screenx = (screen) ? *x : rescaleValuatorAxis(*x, dev->valuator->axes + 0, NULL, scr->width); + *screeny = (screen) ? *y : rescaleValuatorAxis(*y, dev->valuator->axes + 1, NULL, scr->height); dev->last.valuators[0] = *screenx; dev->last.valuators[1] = *screeny; @@ -1002,7 +1004,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons, moveRelative(pDev, &x, &y, first_valuator, num_valuators, valuators); } - positionSprite(pDev, &x, &y, scr, &cx, &cy); + positionSprite(pDev, &x, &y, scr, &cx, &cy, flags & POINTER_SCREEN); updateHistory(pDev, first_valuator, num_valuators, ms); /* dropy x/y (device coordinates) back into valuators for next event */ diff --git a/include/input.h b/include/input.h index 3a9bfa2..2dd29f8 100644 --- a/include/input.h +++ b/include/input.h @@ -62,6 +62,7 @@ SOFTWARE. #define POINTER_RELATIVE (1 << 1) #define POINTER_ABSOLUTE (1 << 2) #define POINTER_ACCELERATE (1 << 3) +#define POINTER_SCREEN (1 << 4) /* Data in screen coordinates */ /*int constants for pointer acceleration schemes*/ #define PtrAccelNoOp 0 diff --git a/mi/mipointer.c b/mi/mipointer.c index acfcb1b..c0c03ae 100644 --- a/mi/mipointer.c +++ b/mi/mipointer.c @@ -569,7 +569,7 @@ miPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) } } - nevents = GetPointerEvents(events, pDev, MotionNotify, 0, POINTER_ABSOLUTE, 0, 2, valuators); + nevents = GetPointerEvents(events, pDev, MotionNotify, 0, POINTER_SCREEN | POINTER_ABSOLUTE, 0, 2, valuators); OsBlockSignals(); for (i = 0; i < nevents; i++) -- 1.6.0.6