[ubuntu-x] Natty bug when using input coordinate transformation matrix
Chase Douglas
chase.douglas at canonical.com
Fri Apr 29 18:21:22 UTC 2011
Hi Robert,
There's a bug in Natty in the part of the code that handles input coordinate
translation. Unfortunately, it's in the part of the code that has changes for
XInput 2.1, so we can't operate through upstream for the fix for Natty.
The problem relates to the values input to the transformation matrix when an
event occurs. When there is any rotation involved, the correct values for both
the X and Y axes are needed, even if only one of them has changed. The correct
values are the new event values or the previous untransformed event values if
there has been no change in the axis. Unfortunately, the X server does not
store the previous untransformed values, so I had to add variables to the device
structs. The patch below ensures that the correct valuator values are used when
transforming coordinates both for absolute pointer and touch events.
I would appreciate it if you could add the patch to the xorg-edgers ppa for
testing before we push it as an SRU. In the meantime, I will try to get a
similar fix pushed upstream for mainline.
Thanks,
-- Chase
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -1177,15 +1177,29 @@ GetPointerEvents(EventList *events, Devi
}
}
- x = (valuator_mask_isset(&mask, 0) ? valuator_mask_get(&mask, 0) :
- pDev->last.valuators[0]);
- y = (valuator_mask_isset(&mask, 1) ? valuator_mask_get(&mask, 1) :
- pDev->last.valuators[1]);
- transformAbsolute(pDev, &mask, &x, &y);
if (valuator_mask_isset(&mask, 0))
- valuator_mask_set(&mask, 0, x);
+ {
+ x = valuator_mask_get(&mask, 0);
+ pDev->last.untransformed_x = x;
+ } else
+ x = pDev->last.untransformed_x;
if (valuator_mask_isset(&mask, 1))
+ {
+ y = valuator_mask_get(&mask, 1);
+ pDev->last.untransformed_y = y;
+ } else
+ y = pDev->last.untransformed_y;
+
+ transformAbsolute(pDev, &mask, &x, &y);
+
+ if (x != pDev->last.valuators[0])
+ valuator_mask_set(&mask, 0, x);
+ else
+ valuator_mask_unset(&mask, 0);
+ if (y != pDev->last.valuators[1])
valuator_mask_set(&mask, 1, y);
+ else
+ valuator_mask_unset(&mask, 1);
moveAbsolute(pDev, &x, &y, &mask);
} else {
@@ -1392,22 +1406,27 @@ GetTouchEvents(EventList *events, Device
* Relative. */
if (t->mode == XIDirectTouch) {
if (valuator_mask_isset(&mask, t->x_axis))
+ {
x = valuator_mask_get(&mask, t->x_axis);
- else
- x = ti->valuators[t->x_axis];
- x = rescaleValuatorAxis(x, 0.0, &x_frac,
- (AxisInfoPtr)(t->axes + t->x_axis),
- NULL, scr->width);
+ ti->untransformed_x = x;
+ } else
+ x = ti->untransformed_x;
if (valuator_mask_isset(&mask, t->y_axis))
+ {
y = valuator_mask_get(&mask, t->y_axis);
- else
- y = ti->valuators[t->y_axis];
+ ti->untransformed_y = y;
+ } else
+ y = ti->untransformed_y;
+
+ transformAbsolute(pDev, &mask, &x, &y);
+
+ x = rescaleValuatorAxis(x, 0.0, &x_frac,
+ (AxisInfoPtr)(t->axes + t->x_axis),
+ NULL, scr->width);
y = rescaleValuatorAxis(y, 0.0, &y_frac,
(AxisInfoPtr)(t->axes + t->y_axis),
NULL, scr->height);
-
- transformAbsolute(pDev, &mask, &x, &y);
}
else {
x = pDev->spriteInfo->sprite->hotPhys.x;
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -335,6 +335,8 @@ typedef struct _TouchPointInfo {
unsigned int history_size; /* Size of history ring buffer */
InternalEvent *first_history; /* Pointer to first event in history */
InternalEvent *next_history; /* Pointer to next available event */
+ int untransformed_x;
+ int untransformed_y;
} TouchPointInfoRec;
typedef struct _TouchAxisInfo {
@@ -623,6 +625,8 @@ typedef struct _DeviceIntRec {
float remainder[MAX_VALUATORS];
int numValuators;
DeviceIntPtr slave;
+ int untransformed_x;
+ int untransformed_y;
} last;
/* Input device property handling. */
More information about the Ubuntu-x
mailing list