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
   scale them to device coordinates in GPE before continuing. 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 <http://bugs.freedesktop.org/show_bug.cgi?id=19297>

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2009-01-12 15:29:36 +10:00
parent 488d452951
commit d36adf52a2
4 changed files with 27 additions and 9 deletions

View File

@ -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;
}

View File

@ -999,8 +999,20 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
events = updateFromMaster(events, pDev, &num_events);
if (flags & POINTER_ABSOLUTE)
{
if (flags & POINTER_SCREEN) /* valuators are in screen coords */
{
valuators[0] = rescaleValuatorAxis(valuators[0], NULL,
pDev->valuator->axes + 0,
scr->width);
valuators[1] = rescaleValuatorAxis(valuators[1], NULL,
pDev->valuator->axes + 1,
scr->height);
}
moveAbsolute(pDev, &x, &y, first_valuator, num_valuators, valuators);
else {
} else {
if (flags & POINTER_ACCELERATE)
accelPointer(pDev, first_valuator, num_valuators, valuators, ms);
moveRelative(pDev, &x, &y, first_valuator, num_valuators, valuators);

View File

@ -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

View File

@ -576,7 +576,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();
#ifdef XQUARTZ