Make all conversion handling in GPE.
This isn't quite finished yet, but at least it gives us the ability to use a tablet as a normal mouse - with all the scaling in place. Signed-off-by: Peter Hutterer <peter@cs.unisa.edu.au>
This commit is contained in:
parent
74372fd004
commit
0f15875a27
223
dix/getevents.c
223
dix/getevents.c
|
@ -155,6 +155,55 @@ CreateClassesChangedEvent(EventList* event,
|
|||
dcce->length = (len - sizeof(xEvent))/4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rescale the coord between the two axis ranges.
|
||||
*/
|
||||
static int
|
||||
rescaleValuatorAxis(int coord, int fmin, int fmax,
|
||||
int tmin, int tmax, int smax)
|
||||
{
|
||||
if(fmin >= fmax) {
|
||||
fmin = 0;
|
||||
fmax = smax;
|
||||
}
|
||||
if(tmin >= tmax) {
|
||||
tmin = 0;
|
||||
tmax = smax;
|
||||
}
|
||||
if(fmin == tmin && fmax == tmax)
|
||||
return coord;
|
||||
|
||||
return (int)(((float)(coord - fmin)) * (tmax - tmin + 1) /
|
||||
(fmax - fmin + 1)) + tmin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update all coordinates when changing to a different SD
|
||||
* to ensure that relative reporting will work as expected
|
||||
* without loss of precision.
|
||||
*/
|
||||
static void
|
||||
updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev)
|
||||
{
|
||||
ScreenPtr scr = miPointerGetScreen(pDev);
|
||||
|
||||
/* lastx/y is in screen coords and the actual position
|
||||
* of the pointer */
|
||||
pDev->lastx = master->lastx;
|
||||
pDev->lasty = master->lasty;
|
||||
/* the valuator axis is in device coords and holds the
|
||||
* position of the pointer, but in device coords. */
|
||||
if(pDev->valuator->numAxes > 0)
|
||||
pDev->valuator->axisVal[0] = rescaleValuatorAxis(pDev->lastx, 0, scr->width,
|
||||
pDev->valuator->axes[0].min_value,
|
||||
pDev->valuator->axes[0].max_value, scr->width);
|
||||
if(pDev->valuator->numAxes > 1)
|
||||
pDev->valuator->axisVal[1] = rescaleValuatorAxis(pDev->lasty, 0, scr->height,
|
||||
pDev->valuator->axes[1].min_value,
|
||||
pDev->valuator->axes[1].max_value, scr->height);
|
||||
/*TODO calculate the other axis as well based on info from the old slave-device */
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate the motion history buffer.
|
||||
*/
|
||||
|
@ -395,25 +444,23 @@ clipValuators(DeviceIntPtr pDev, int first_valuator, int num_valuators,
|
|||
* Fills events with valuator events for pDev, as given by the other
|
||||
* parameters.
|
||||
*
|
||||
* Note that we mis-use the sequence number to store the absolute bit.
|
||||
*
|
||||
* FIXME: Need to fix ValuatorClassRec to store all the valuators as
|
||||
* last posted, not just x and y; otherwise relative non-x/y
|
||||
* valuators, though a very narrow use case, will be broken.
|
||||
*/
|
||||
static EventList *
|
||||
getValuatorEvents(EventList *events, DeviceIntPtr pDev, int absolute,
|
||||
getValuatorEvents(EventList *events, DeviceIntPtr pDev,
|
||||
int first_valuator, int num_valuators, int *valuators) {
|
||||
deviceValuator *xv;
|
||||
int i = 0, final_valuator = first_valuator + num_valuators;
|
||||
int i;
|
||||
|
||||
for (i = first_valuator; i < final_valuator; i += 6, events++) {
|
||||
for (i = 0; i < num_valuators; i += 6, events++) {
|
||||
xv = (deviceValuator*)events->event;
|
||||
xv->type = DeviceValuator;
|
||||
xv->first_valuator = i;
|
||||
xv->num_valuators = ((final_valuator - i) > 6) ? 6 : (final_valuator - i);
|
||||
xv->first_valuator = first_valuator + i;
|
||||
xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i);
|
||||
xv->deviceid = pDev->id;
|
||||
switch (final_valuator - i) {
|
||||
switch (num_valuators - i) {
|
||||
case 6:
|
||||
xv->valuator5 = valuators[i + 5];
|
||||
case 5:
|
||||
|
@ -425,13 +472,11 @@ getValuatorEvents(EventList *events, DeviceIntPtr pDev, int absolute,
|
|||
case 2:
|
||||
xv->valuator1 = valuators[i + 1];
|
||||
case 1:
|
||||
xv->valuator0 = valuators[i];
|
||||
xv->valuator0 = valuators[i + 0];
|
||||
}
|
||||
|
||||
if (i + 6 < final_valuator)
|
||||
if (i + 6 < num_valuators)
|
||||
xv->deviceid |= MORE_EVENTS;
|
||||
|
||||
xv->sequenceNumber = (absolute) ? Absolute : Relative;
|
||||
}
|
||||
|
||||
return events;
|
||||
|
@ -576,8 +621,8 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
|
|||
if (num_valuators) {
|
||||
kbp->deviceid |= MORE_EVENTS;
|
||||
clipValuators(pDev, first_valuator, num_valuators, valuators);
|
||||
events = getValuatorEvents(events, pDev, FALSE /* relative */,
|
||||
first_valuator, num_valuators, valuators);
|
||||
events = getValuatorEvents(events, pDev, first_valuator,
|
||||
num_valuators, valuators);
|
||||
}
|
||||
|
||||
return numEvents;
|
||||
|
@ -674,44 +719,28 @@ _X_EXPORT int
|
|||
GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
|
||||
int flags, int first_valuator, int num_valuators,
|
||||
int *valuators) {
|
||||
int num_events = 0, final_valuator = 0;
|
||||
int num_events = 1;
|
||||
CARD32 ms = 0;
|
||||
deviceKeyButtonPointer *kbp = NULL;
|
||||
DeviceIntPtr master;
|
||||
int x = 0, y = 0;
|
||||
int x, y, cx, cy;
|
||||
ScreenPtr scr = miPointerGetScreen(pDev);
|
||||
|
||||
/* Sanity checks. */
|
||||
if (type != MotionNotify && type != ButtonPress && type != ButtonRelease)
|
||||
return 0;
|
||||
|
||||
if ((type == ButtonPress || type == ButtonRelease) && !pDev->button)
|
||||
if (type != MotionNotify && !pDev->button)
|
||||
return 0;
|
||||
|
||||
/* FIXME: I guess it should, in theory, be possible to post button events
|
||||
* from devices without valuators. */
|
||||
if (!pDev->valuator)
|
||||
/* This method require at least valuator 0&1 defined on the InputDevice */
|
||||
if (!pDev->valuator || pDev->valuator->numAxes < 2)
|
||||
return 0;
|
||||
|
||||
if (type == MotionNotify && num_valuators <= 0)
|
||||
return 0;
|
||||
|
||||
ms = GetTimeInMillis();
|
||||
|
||||
num_events = 1;
|
||||
|
||||
master = pDev->u.master;
|
||||
if (master && master->u.lastSlave != pDev)
|
||||
{
|
||||
CreateClassesChangedEvent(events, master, pDev);
|
||||
|
||||
pDev->lastx = master->lastx;
|
||||
pDev->lasty = master->lasty;
|
||||
master->u.lastSlave = pDev;
|
||||
|
||||
num_events++;
|
||||
events++;
|
||||
}
|
||||
|
||||
/* Do we need to send a DeviceValuator event? */
|
||||
if (num_valuators) {
|
||||
if ((((num_valuators - 1) / 6) + 1) > MAX_VALUATOR_EVENTS)
|
||||
|
@ -719,28 +748,34 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
|
|||
num_events += ((num_valuators - 1) / 6) + 1;
|
||||
}
|
||||
|
||||
final_valuator = num_valuators + first_valuator;
|
||||
|
||||
/* You fail. */
|
||||
if (first_valuator < 0 || final_valuator > pDev->valuator->numAxes)
|
||||
if (first_valuator < 0 ||
|
||||
(num_valuators + first_valuator) > pDev->valuator->numAxes)
|
||||
return 0;
|
||||
|
||||
master = pDev->u.master;
|
||||
if (master && master->u.lastSlave != pDev)
|
||||
{
|
||||
CreateClassesChangedEvent(events, master, pDev);
|
||||
updateSlaveDeviceCoords(master, pDev);
|
||||
master->u.lastSlave = pDev;
|
||||
num_events++;
|
||||
events++;
|
||||
}
|
||||
|
||||
/* Set x and y based on whether this is absolute or relative, and
|
||||
* accelerate if we need to. */
|
||||
x = pDev->valuator->axisVal[0];
|
||||
y = pDev->valuator->axisVal[1];
|
||||
if (flags & POINTER_ABSOLUTE) {
|
||||
if (num_valuators >= 1 && first_valuator == 0) {
|
||||
if (num_valuators >= 1 && first_valuator == 0)
|
||||
x = valuators[0];
|
||||
}
|
||||
else {
|
||||
x = pDev->lastx;
|
||||
}
|
||||
|
||||
if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) {
|
||||
if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
|
||||
y = valuators[1 - first_valuator];
|
||||
}
|
||||
else {
|
||||
y = pDev->lasty;
|
||||
}
|
||||
|
||||
/* Clip both x and y to the defined limits (usually co-ord space limit). */
|
||||
clipAxis(pDev, 0, &x);
|
||||
clipAxis(pDev, 1, &y);
|
||||
}
|
||||
else {
|
||||
if (flags & POINTER_ACCELERATE)
|
||||
|
@ -748,34 +783,69 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
|
|||
valuators);
|
||||
|
||||
if (first_valuator == 0 && num_valuators >= 1)
|
||||
x = pDev->lastx + valuators[0];
|
||||
else
|
||||
x = pDev->lastx;
|
||||
|
||||
x += valuators[0];
|
||||
if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
|
||||
y = pDev->lasty + valuators[1 - first_valuator];
|
||||
else
|
||||
y = pDev->lasty;
|
||||
y += valuators[1 - first_valuator];
|
||||
|
||||
/* if not core -> clip both x and y to the defined limits (usually
|
||||
* co-ord space limit). */
|
||||
if(!pDev->coreEvents) {
|
||||
clipAxis(pDev, 0, &x);
|
||||
clipAxis(pDev, 1, &y);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clip both x and y to the defined limits (usually co-ord space limit). */
|
||||
clipAxis(pDev, 0, &x);
|
||||
clipAxis(pDev, 1, &y);
|
||||
/* scale x&y to screen */
|
||||
pDev->lastx = cx = rescaleValuatorAxis(x, pDev->valuator->axes[0].min_value,
|
||||
pDev->valuator->axes[0].max_value,
|
||||
0, scr->width, scr->width);
|
||||
pDev->lasty = cy = rescaleValuatorAxis(y, pDev->valuator->axes[1].min_value,
|
||||
pDev->valuator->axes[1].max_value,
|
||||
0, scr->height, scr->height);
|
||||
|
||||
/* This takes care of crossing screens for us, as well as clipping
|
||||
* to the current screen. Right now, we only have one history buffer,
|
||||
* so we don't set this for both the device and core.*/
|
||||
miPointerSetPosition(pDev, &x, &y, ms);
|
||||
miPointerSetPosition(pDev, &pDev->lastx, &pDev->lasty, ms);
|
||||
|
||||
scr = miPointerGetScreen(pDev);
|
||||
if(cx != pDev->lastx)
|
||||
x = rescaleValuatorAxis(pDev->lastx, 0, scr->width,
|
||||
pDev->valuator->axes[0].min_value,
|
||||
pDev->valuator->axes[0].max_value,
|
||||
scr->width);
|
||||
if(cy != pDev->lasty)
|
||||
y = rescaleValuatorAxis(pDev->lasty, 0, scr->height,
|
||||
pDev->valuator->axes[1].min_value,
|
||||
pDev->valuator->axes[1].max_value,
|
||||
scr->height);
|
||||
|
||||
updateMotionHistory(pDev, ms, first_valuator, num_valuators, valuators);
|
||||
|
||||
pDev->lastx = x;
|
||||
pDev->lasty = y;
|
||||
if (master)
|
||||
{
|
||||
master->lastx = x;
|
||||
master->lasty = y;
|
||||
if (master) {
|
||||
master->lastx = pDev->lastx;
|
||||
master->lasty = pDev->lasty;
|
||||
}
|
||||
|
||||
/* update the contents of the valuators based on the mode of the InputDevice */
|
||||
if(1) { /*TODO Absolute mode */
|
||||
/* Update the valuators with the true value sent to the client
|
||||
* (only absolute mode on the InputDevice) */
|
||||
if (first_valuator == 0 && num_valuators >= 1)
|
||||
pDev->valuator->axisVal[0] = x;
|
||||
if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
|
||||
pDev->valuator->axisVal[1] = y;
|
||||
} else {/* Relative mode */
|
||||
/* If driver reported in absolute, calculate the relative valuator
|
||||
* values as a delta from the old absolute values of the valuator
|
||||
* values. If relative report, keep it as-is.*/
|
||||
/*TODO*/
|
||||
}
|
||||
/* Save the last calculated device axis value in the device
|
||||
* valuator for next event */
|
||||
pDev->valuator->axisVal[0] = x;
|
||||
pDev->valuator->axisVal[1] = y;
|
||||
|
||||
kbp = (deviceKeyButtonPointer *) events->event;
|
||||
kbp->time = ms;
|
||||
kbp->deviceid = pDev->id;
|
||||
|
@ -791,15 +861,15 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
|
|||
kbp->detail = pDev->button->map[buttons];
|
||||
}
|
||||
|
||||
kbp->root_x = x;
|
||||
kbp->root_y = y;
|
||||
kbp->root_x = pDev->lastx;
|
||||
kbp->root_y = pDev->lasty;
|
||||
|
||||
events++;
|
||||
if (num_valuators) {
|
||||
kbp->deviceid |= MORE_EVENTS;
|
||||
clipValuators(pDev, first_valuator, num_valuators, valuators);
|
||||
events = getValuatorEvents(events, pDev, (flags & POINTER_ABSOLUTE),
|
||||
first_valuator, num_valuators, valuators);
|
||||
events = getValuatorEvents(events, pDev, first_valuator,
|
||||
num_valuators, valuators);
|
||||
}
|
||||
|
||||
return num_events;
|
||||
|
@ -824,10 +894,8 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
|
|||
/* Sanity checks. */
|
||||
if (type != ProximityIn && type != ProximityOut)
|
||||
return 0;
|
||||
|
||||
if (!pDev->valuator)
|
||||
return 0;
|
||||
|
||||
/* Do we need to send a DeviceValuator event? */
|
||||
if ((pDev->valuator->mode & 1) == Relative)
|
||||
num_valuators = 0;
|
||||
|
@ -847,11 +915,8 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
|
|||
if (master && master->u.lastSlave != pDev)
|
||||
{
|
||||
CreateClassesChangedEvent(events, master, pDev);
|
||||
|
||||
pDev->lastx = master->lastx;
|
||||
pDev->lasty = master->lasty;
|
||||
updateSlaveDeviceCoords(master, pDev);
|
||||
master->u.lastSlave = pDev;
|
||||
|
||||
num_events++;
|
||||
events++;
|
||||
}
|
||||
|
@ -866,8 +931,8 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
|
|||
kbp->deviceid |= MORE_EVENTS;
|
||||
events++;
|
||||
clipValuators(pDev, first_valuator, num_valuators, valuators);
|
||||
events = getValuatorEvents(events, pDev, False /* relative */,
|
||||
first_valuator, num_valuators, valuators);
|
||||
events = getValuatorEvents(events, pDev, first_valuator,
|
||||
num_valuators, valuators);
|
||||
}
|
||||
|
||||
return num_events;
|
||||
|
|
Loading…
Reference in New Issue