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;
|
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.
|
* 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
|
* Fills events with valuator events for pDev, as given by the other
|
||||||
* parameters.
|
* 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
|
* FIXME: Need to fix ValuatorClassRec to store all the valuators as
|
||||||
* last posted, not just x and y; otherwise relative non-x/y
|
* last posted, not just x and y; otherwise relative non-x/y
|
||||||
* valuators, though a very narrow use case, will be broken.
|
* valuators, though a very narrow use case, will be broken.
|
||||||
*/
|
*/
|
||||||
static EventList *
|
static EventList *
|
||||||
getValuatorEvents(EventList *events, DeviceIntPtr pDev, int absolute,
|
getValuatorEvents(EventList *events, DeviceIntPtr pDev,
|
||||||
int first_valuator, int num_valuators, int *valuators) {
|
int first_valuator, int num_valuators, int *valuators) {
|
||||||
deviceValuator *xv;
|
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 = (deviceValuator*)events->event;
|
||||||
xv->type = DeviceValuator;
|
xv->type = DeviceValuator;
|
||||||
xv->first_valuator = i;
|
xv->first_valuator = first_valuator + i;
|
||||||
xv->num_valuators = ((final_valuator - i) > 6) ? 6 : (final_valuator - i);
|
xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i);
|
||||||
xv->deviceid = pDev->id;
|
xv->deviceid = pDev->id;
|
||||||
switch (final_valuator - i) {
|
switch (num_valuators - i) {
|
||||||
case 6:
|
case 6:
|
||||||
xv->valuator5 = valuators[i + 5];
|
xv->valuator5 = valuators[i + 5];
|
||||||
case 5:
|
case 5:
|
||||||
|
@ -425,13 +472,11 @@ getValuatorEvents(EventList *events, DeviceIntPtr pDev, int absolute,
|
||||||
case 2:
|
case 2:
|
||||||
xv->valuator1 = valuators[i + 1];
|
xv->valuator1 = valuators[i + 1];
|
||||||
case 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->deviceid |= MORE_EVENTS;
|
||||||
|
|
||||||
xv->sequenceNumber = (absolute) ? Absolute : Relative;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return events;
|
return events;
|
||||||
|
@ -576,8 +621,8 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
|
||||||
if (num_valuators) {
|
if (num_valuators) {
|
||||||
kbp->deviceid |= MORE_EVENTS;
|
kbp->deviceid |= MORE_EVENTS;
|
||||||
clipValuators(pDev, first_valuator, num_valuators, valuators);
|
clipValuators(pDev, first_valuator, num_valuators, valuators);
|
||||||
events = getValuatorEvents(events, pDev, FALSE /* relative */,
|
events = getValuatorEvents(events, pDev, first_valuator,
|
||||||
first_valuator, num_valuators, valuators);
|
num_valuators, valuators);
|
||||||
}
|
}
|
||||||
|
|
||||||
return numEvents;
|
return numEvents;
|
||||||
|
@ -674,44 +719,28 @@ _X_EXPORT int
|
||||||
GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
|
GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
|
||||||
int flags, int first_valuator, int num_valuators,
|
int flags, int first_valuator, int num_valuators,
|
||||||
int *valuators) {
|
int *valuators) {
|
||||||
int num_events = 0, final_valuator = 0;
|
int num_events = 1;
|
||||||
CARD32 ms = 0;
|
CARD32 ms = 0;
|
||||||
deviceKeyButtonPointer *kbp = NULL;
|
deviceKeyButtonPointer *kbp = NULL;
|
||||||
DeviceIntPtr master;
|
DeviceIntPtr master;
|
||||||
int x = 0, y = 0;
|
int x, y, cx, cy;
|
||||||
|
ScreenPtr scr = miPointerGetScreen(pDev);
|
||||||
|
|
||||||
/* Sanity checks. */
|
/* Sanity checks. */
|
||||||
if (type != MotionNotify && type != ButtonPress && type != ButtonRelease)
|
if (type != MotionNotify && type != ButtonPress && type != ButtonRelease)
|
||||||
return 0;
|
return 0;
|
||||||
|
if (type != MotionNotify && !pDev->button)
|
||||||
if ((type == ButtonPress || type == ButtonRelease) && !pDev->button)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* FIXME: I guess it should, in theory, be possible to post button events
|
/* FIXME: I guess it should, in theory, be possible to post button events
|
||||||
* from devices without valuators. */
|
* 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;
|
return 0;
|
||||||
|
|
||||||
if (type == MotionNotify && num_valuators <= 0)
|
if (type == MotionNotify && num_valuators <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ms = GetTimeInMillis();
|
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? */
|
/* Do we need to send a DeviceValuator event? */
|
||||||
if (num_valuators) {
|
if (num_valuators) {
|
||||||
if ((((num_valuators - 1) / 6) + 1) > MAX_VALUATOR_EVENTS)
|
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;
|
num_events += ((num_valuators - 1) / 6) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
final_valuator = num_valuators + first_valuator;
|
|
||||||
|
|
||||||
/* You fail. */
|
/* You fail. */
|
||||||
if (first_valuator < 0 || final_valuator > pDev->valuator->numAxes)
|
if (first_valuator < 0 ||
|
||||||
|
(num_valuators + first_valuator) > pDev->valuator->numAxes)
|
||||||
return 0;
|
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
|
/* Set x and y based on whether this is absolute or relative, and
|
||||||
* accelerate if we need to. */
|
* accelerate if we need to. */
|
||||||
|
x = pDev->valuator->axisVal[0];
|
||||||
|
y = pDev->valuator->axisVal[1];
|
||||||
if (flags & POINTER_ABSOLUTE) {
|
if (flags & POINTER_ABSOLUTE) {
|
||||||
if (num_valuators >= 1 && first_valuator == 0) {
|
if (num_valuators >= 1 && first_valuator == 0)
|
||||||
x = valuators[0];
|
x = valuators[0];
|
||||||
}
|
if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
|
||||||
else {
|
|
||||||
x = pDev->lastx;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) {
|
|
||||||
y = valuators[1 - first_valuator];
|
y = valuators[1 - first_valuator];
|
||||||
}
|
|
||||||
else {
|
/* Clip both x and y to the defined limits (usually co-ord space limit). */
|
||||||
y = pDev->lasty;
|
clipAxis(pDev, 0, &x);
|
||||||
}
|
clipAxis(pDev, 1, &y);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (flags & POINTER_ACCELERATE)
|
if (flags & POINTER_ACCELERATE)
|
||||||
|
@ -748,34 +783,69 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
|
||||||
valuators);
|
valuators);
|
||||||
|
|
||||||
if (first_valuator == 0 && num_valuators >= 1)
|
if (first_valuator == 0 && num_valuators >= 1)
|
||||||
x = pDev->lastx + valuators[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 = pDev->lasty + valuators[1 - first_valuator];
|
y += valuators[1 - first_valuator];
|
||||||
else
|
|
||||||
y = pDev->lasty;
|
/* 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). */
|
/* scale x&y to screen */
|
||||||
clipAxis(pDev, 0, &x);
|
pDev->lastx = cx = rescaleValuatorAxis(x, pDev->valuator->axes[0].min_value,
|
||||||
clipAxis(pDev, 1, &y);
|
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
|
/* 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, &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);
|
updateMotionHistory(pDev, ms, first_valuator, num_valuators, valuators);
|
||||||
|
|
||||||
pDev->lastx = x;
|
if (master) {
|
||||||
pDev->lasty = y;
|
master->lastx = pDev->lastx;
|
||||||
if (master)
|
master->lasty = pDev->lasty;
|
||||||
{
|
|
||||||
master->lastx = x;
|
|
||||||
master->lasty = y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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 = (deviceKeyButtonPointer *) events->event;
|
||||||
kbp->time = ms;
|
kbp->time = ms;
|
||||||
kbp->deviceid = pDev->id;
|
kbp->deviceid = pDev->id;
|
||||||
|
@ -791,15 +861,15 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
|
||||||
kbp->detail = pDev->button->map[buttons];
|
kbp->detail = pDev->button->map[buttons];
|
||||||
}
|
}
|
||||||
|
|
||||||
kbp->root_x = x;
|
kbp->root_x = pDev->lastx;
|
||||||
kbp->root_y = y;
|
kbp->root_y = pDev->lasty;
|
||||||
|
|
||||||
events++;
|
events++;
|
||||||
if (num_valuators) {
|
if (num_valuators) {
|
||||||
kbp->deviceid |= MORE_EVENTS;
|
kbp->deviceid |= MORE_EVENTS;
|
||||||
clipValuators(pDev, first_valuator, num_valuators, valuators);
|
clipValuators(pDev, first_valuator, num_valuators, valuators);
|
||||||
events = getValuatorEvents(events, pDev, (flags & POINTER_ABSOLUTE),
|
events = getValuatorEvents(events, pDev, first_valuator,
|
||||||
first_valuator, num_valuators, valuators);
|
num_valuators, valuators);
|
||||||
}
|
}
|
||||||
|
|
||||||
return num_events;
|
return num_events;
|
||||||
|
@ -824,10 +894,8 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
|
||||||
/* Sanity checks. */
|
/* Sanity checks. */
|
||||||
if (type != ProximityIn && type != ProximityOut)
|
if (type != ProximityIn && type != ProximityOut)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!pDev->valuator)
|
if (!pDev->valuator)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Do we need to send a DeviceValuator event? */
|
/* Do we need to send a DeviceValuator event? */
|
||||||
if ((pDev->valuator->mode & 1) == Relative)
|
if ((pDev->valuator->mode & 1) == Relative)
|
||||||
num_valuators = 0;
|
num_valuators = 0;
|
||||||
|
@ -847,11 +915,8 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
|
||||||
if (master && master->u.lastSlave != pDev)
|
if (master && master->u.lastSlave != pDev)
|
||||||
{
|
{
|
||||||
CreateClassesChangedEvent(events, master, pDev);
|
CreateClassesChangedEvent(events, master, pDev);
|
||||||
|
updateSlaveDeviceCoords(master, pDev);
|
||||||
pDev->lastx = master->lastx;
|
|
||||||
pDev->lasty = master->lasty;
|
|
||||||
master->u.lastSlave = pDev;
|
master->u.lastSlave = pDev;
|
||||||
|
|
||||||
num_events++;
|
num_events++;
|
||||||
events++;
|
events++;
|
||||||
}
|
}
|
||||||
|
@ -866,8 +931,8 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
|
||||||
kbp->deviceid |= MORE_EVENTS;
|
kbp->deviceid |= MORE_EVENTS;
|
||||||
events++;
|
events++;
|
||||||
clipValuators(pDev, first_valuator, num_valuators, valuators);
|
clipValuators(pDev, first_valuator, num_valuators, valuators);
|
||||||
events = getValuatorEvents(events, pDev, False /* relative */,
|
events = getValuatorEvents(events, pDev, first_valuator,
|
||||||
first_valuator, num_valuators, valuators);
|
num_valuators, valuators);
|
||||||
}
|
}
|
||||||
|
|
||||||
return num_events;
|
return num_events;
|
||||||
|
|
Loading…
Reference in New Issue