input: instead of lastx/y, use a last.valuators[] array on the device.

During GetPointerEvents (and others), we need to access the last coordinates
posted for this device from the driver (not as posted to the client!). Lastx/y
is ok if we only have two axes, but with more complex devices we also need to
transition between all other axes.

ABI break, recompile your input drivers.
This commit is contained in:
Peter Hutterer 2008-05-23 11:51:53 +09:30
parent fb146cbb0f
commit 6c9e9f8a40
7 changed files with 49 additions and 37 deletions

View File

@ -470,16 +470,16 @@ ProcXTestFakeInput(client)
ev->u.keyButtonPointer.rootX, ev->u.keyButtonPointer.rootX,
ev->u.keyButtonPointer.rootY, FALSE); ev->u.keyButtonPointer.rootY, FALSE);
} }
dev->lastx = ev->u.keyButtonPointer.rootX; dev->last.valuators[0] = ev->u.keyButtonPointer.rootX;
dev->lasty = ev->u.keyButtonPointer.rootY; dev->last.valuators[1] = ev->u.keyButtonPointer.rootY;
break; break;
case ButtonPress: case ButtonPress:
case ButtonRelease: case ButtonRelease:
if (!extension) if (!extension)
dev = PickPointer(client); dev = PickPointer(client);
ev->u.keyButtonPointer.rootX = dev->lastx; ev->u.keyButtonPointer.rootX = dev->last.valuators[0];
ev->u.keyButtonPointer.rootY = dev->lasty; ev->u.keyButtonPointer.rootY = dev->last.valuators[1];
if (!ev->u.u.detail || ev->u.u.detail > dev->button->numButtons) if (!ev->u.u.detail || ev->u.u.detail > dev->button->numButtons)
{ {
client->errorValue = ev->u.u.detail; client->errorValue = ev->u.u.detail;

View File

@ -166,8 +166,8 @@ ProcXWarpDevicePointer(ClientPtr client)
} }
/* if we don't update the device, we get a jump next time it moves */ /* if we don't update the device, we get a jump next time it moves */
pDev->lastx = x; pDev->last.valuators[0] = x;
pDev->lasty = x; pDev->last.valuators[1] = x;
miPointerUpdateSprite(pDev); miPointerUpdateSprite(pDev);
/* FIXME: XWarpPointer is supposed to generate an event. It doesn't do it /* FIXME: XWarpPointer is supposed to generate an event. It doesn't do it

View File

@ -168,6 +168,10 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
dev->spriteInfo->sprite = NULL; dev->spriteInfo->sprite = NULL;
dev->spriteInfo->spriteOwner = FALSE; dev->spriteInfo->spriteOwner = FALSE;
/* last valuators */
memset(dev->last.valuators, 0, sizeof(dev->last.valuators));
dev->last.numValuators = 0;
/* security creation/labeling check /* security creation/labeling check
*/ */
if (XaceHook(XACE_DEVICE_ACCESS, client, dev, DixCreateAccess)) { if (XaceHook(XACE_DEVICE_ACCESS, client, dev, DixCreateAccess)) {
@ -491,9 +495,9 @@ CorePointerProc(DeviceIntPtr pDev, int what)
GetMotionHistory, (PtrCtrlProcPtr)NoopDDA, GetMotionHistory, (PtrCtrlProcPtr)NoopDDA,
GetMotionHistorySize(), 2); GetMotionHistorySize(), 2);
pDev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2; pDev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2;
pDev->lastx = pDev->valuator->axisVal[0]; pDev->last.valuators[0] = pDev->valuator->axisVal[0];
pDev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2; pDev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
pDev->lasty = pDev->valuator->axisVal[1]; pDev->last.valuators[1] = pDev->valuator->axisVal[1];
break; break;
case DEVICE_CLOSE: case DEVICE_CLOSE:
@ -1192,6 +1196,8 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes,
0, 0, 0); 0, 0, 0);
valc->axisVal[i]=0; valc->axisVal[i]=0;
} }
dev->last.numValuators = numAxes;
return TRUE; return TRUE;
} }

View File

@ -189,17 +189,17 @@ updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev)
{ {
ScreenPtr scr = miPointerGetScreen(pDev); ScreenPtr scr = miPointerGetScreen(pDev);
/* lastx/y is in screen coords and the actual position /* last.valuators[0]/[1] is in screen coords and the actual position
* of the pointer */ * of the pointer */
pDev->lastx = master->lastx; pDev->last.valuators[0] = master->last.valuators[0];
pDev->lasty = master->lasty; pDev->last.valuators[1] = master->last.valuators[1];
/* the valuator axis is in device coords and holds the /* the valuator axis is in device coords and holds the
* position of the pointer, but in device coords. */ * position of the pointer, but in device coords. */
if(pDev->valuator->numAxes > 0) if(pDev->valuator->numAxes > 0)
pDev->valuator->axisVal[0] = rescaleValuatorAxis(pDev->lastx, NULL, pDev->valuator->axisVal[0] = rescaleValuatorAxis(pDev->last.valuators[0], NULL,
pDev->valuator->axes + 0, scr->width); pDev->valuator->axes + 0, scr->width);
if(pDev->valuator->numAxes > 1) if(pDev->valuator->numAxes > 1)
pDev->valuator->axisVal[1] = rescaleValuatorAxis(pDev->lasty, NULL, pDev->valuator->axisVal[1] = rescaleValuatorAxis(pDev->last.valuators[1], NULL,
pDev->valuator->axes + 1, scr->height); pDev->valuator->axes + 1, scr->height);
/*TODO calculate the other axis as well based on info from the old slave-device */ /*TODO calculate the other axis as well based on info from the old slave-device */
} }
@ -542,8 +542,8 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
if (master->valuator && pDev->valuator) if (master->valuator && pDev->valuator)
{ {
pDev->lastx = master->lastx; pDev->last.valuators[0] = master->last.valuators[0];
pDev->lasty = master->lasty; pDev->last.valuators[1] = master->last.valuators[1];
} }
master->u.lastSlave = pDev; master->u.lastSlave = pDev;
numEvents++; numEvents++;
@ -709,8 +709,8 @@ FreeEventList(EventListPtr list, int num_events)
* *
* In the generated events rootX/Y will be in absolute screen coords and * In the generated events rootX/Y will be in absolute screen coords and
* the valuator information in the absolute or relative device coords. * the valuator information in the absolute or relative device coords.
* lastx/y of the device is always in absolute screen coords while the * last.valuators[0]/[1] of the device is always in absolute screen coords
* device valuator struct contain the absolute device coords. * while the device valuator struct contain the absolute device coords.
*/ */
_X_EXPORT int _X_EXPORT int
GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons, GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
@ -801,29 +801,29 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
} }
/* scale x&y to screen */ /* scale x&y to screen */
pDev->lastx = cx = rescaleValuatorAxis(x, pDev->valuator->axes + 0, pDev->last.valuators[0] = cx = rescaleValuatorAxis(x, pDev->valuator->axes + 0,
NULL, scr->width); NULL, scr->width);
pDev->lasty = cy = rescaleValuatorAxis(y, pDev->valuator->axes + 1, pDev->last.valuators[1] = cy = rescaleValuatorAxis(y, pDev->valuator->axes + 1,
NULL, scr->height); NULL, scr->height);
/* This takes care of crossing screens for us, as well as clipping /* This takes care of crossing screens for us, as well as clipping
* to the current screen. Right now, we only have one history buffer, * to the current screen. Right now, we only have one history buffer,
* so we don't set this for both the device and core.*/ * so we don't set this for both the device and core.*/
miPointerSetPosition(pDev, &pDev->lastx, &pDev->lasty, ms); miPointerSetPosition(pDev, &pDev->last.valuators[0], &pDev->last.valuators[1], ms);
scr = miPointerGetScreen(pDev); scr = miPointerGetScreen(pDev);
if(cx != pDev->lastx) if(cx != pDev->last.valuators[0])
x = rescaleValuatorAxis(pDev->lastx, NULL, x = rescaleValuatorAxis(pDev->last.valuators[0], NULL,
pDev->valuator->axes + 0, scr->width); pDev->valuator->axes + 0, scr->width);
if(cy != pDev->lasty) if(cy != pDev->last.valuators[1])
y = rescaleValuatorAxis(pDev->lasty, NULL, y = rescaleValuatorAxis(pDev->last.valuators[1], NULL,
pDev->valuator->axes + 1, scr->height); pDev->valuator->axes + 1, scr->height);
updateMotionHistory(pDev, ms, first_valuator, num_valuators, valuators); updateMotionHistory(pDev, ms, first_valuator, num_valuators, valuators);
if (master) { if (master) {
master->lastx = pDev->lastx; master->last.valuators[0] = pDev->last.valuators[0];
master->lasty = pDev->lasty; master->last.valuators[1] = pDev->last.valuators[1];
} }
/* update the valuators based on the mode of the InputDevice */ /* update the valuators based on the mode of the InputDevice */
@ -862,12 +862,13 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
kbp->detail = pDev->button->map[buttons]; kbp->detail = pDev->button->map[buttons];
} }
kbp->root_x = pDev->lastx; kbp->root_x = pDev->last.valuators[0];
kbp->root_y = pDev->lasty; kbp->root_y = pDev->last.valuators[1];
events++; events++;
if (num_valuators) { if (num_valuators) {
kbp->deviceid |= MORE_EVENTS; kbp->deviceid |= MORE_EVENTS;
if (flags & POINTER_ABSOLUTE)
clipValuators(pDev, first_valuator, num_valuators, valuators); clipValuators(pDev, first_valuator, num_valuators, valuators);
events = getValuatorEvents(events, pDev, first_valuator, events = getValuatorEvents(events, pDev, first_valuator,
num_valuators, valuators); num_valuators, valuators);

View File

@ -505,8 +505,6 @@ DeleteInputDeviceRequest(DeviceIntPtr pDev)
* convenient functions to post events * convenient functions to post events
*/ */
#define MAX_VALUATORS 36 /* XXX from comment in dix/getevents.c */
_X_EXPORT void _X_EXPORT void
xf86PostMotionEvent(DeviceIntPtr device, xf86PostMotionEvent(DeviceIntPtr device,
int is_absolute, int is_absolute,
@ -566,14 +564,14 @@ xf86PostMotionEventP(DeviceIntPtr device,
{ {
dx = valuators[0]; dx = valuators[0];
if (is_absolute) if (is_absolute)
dx -= device->lastx; dx -= device->last.valuators[0];
} }
if (first_valuator == 1 || num_valuators >= 2) if (first_valuator == 1 || num_valuators >= 2)
{ {
dy = valuators[1 - first_valuator]; dy = valuators[1 - first_valuator];
if (is_absolute) if (is_absolute)
dy -= device->lasty; dy -= device->last.valuators[1];
} }
if (DGAStealMotionEvent(device, index, dx, dy)) if (DGAStealMotionEvent(device, index, dx, dy))
@ -833,11 +831,11 @@ xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum)
{ {
if (axnum == 0) { if (axnum == 0) {
dev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2; dev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2;
dev->lastx = dev->valuator->axisVal[0]; dev->last.valuators[0] = dev->valuator->axisVal[0];
} }
else if (axnum == 1) { else if (axnum == 1) {
dev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2; dev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
dev->lasty = dev->valuator->axisVal[1]; dev->last.valuators[1] = dev->valuator->axisVal[1];
} }
} }

View File

@ -63,6 +63,8 @@ SOFTWARE.
#define POINTER_ABSOLUTE (1 << 2) #define POINTER_ABSOLUTE (1 << 2)
#define POINTER_ACCELERATE (1 << 3) #define POINTER_ACCELERATE (1 << 3)
#define MAX_VALUATORS 36 /* XXX from comment in dix/getevents.c */
#define NO_AXIS_LIMITS -1 #define NO_AXIS_LIMITS -1
#define MAP_LENGTH 256 #define MAP_LENGTH 256

View File

@ -420,8 +420,13 @@ typedef struct _DeviceIntRec {
DeviceIntPtr master; /* master device */ DeviceIntPtr master; /* master device */
DeviceIntPtr lastSlave; /* last slave device used */ DeviceIntPtr lastSlave; /* last slave device used */
} u; } u;
int lastx, lasty; /* last event recorded, not posted to
* client; see dix/devices.c */ /* last valuator values recorded, not posted to client;
* see dix/getevents.c */
struct {
int valuators[MAX_VALUATORS];
int numValuators;
} last;
} DeviceIntRec; } DeviceIntRec;
typedef struct { typedef struct {