Merge remote-tracking branch 'whot/unreviewed'

This commit is contained in:
Keith Packard 2013-05-23 19:58:46 -06:00
commit cb3018d8a1
2 changed files with 40 additions and 24 deletions

View File

@ -112,8 +112,8 @@ DeviceSetTransform(DeviceIntPtr dev, float *transform_data)
* Transform is the user supplied (affine) transform * Transform is the user supplied (affine) transform
* InvScale scales coordinates back up into their native range * InvScale scales coordinates back up into their native range
*/ */
sx = dev->valuator->axes[0].max_value - dev->valuator->axes[0].min_value; sx = dev->valuator->axes[0].max_value - dev->valuator->axes[0].min_value + 1;
sy = dev->valuator->axes[1].max_value - dev->valuator->axes[1].min_value; sy = dev->valuator->axes[1].max_value - dev->valuator->axes[1].min_value + 1;
/* invscale */ /* invscale */
pixman_f_transform_init_scale(&scale, sx, sy); pixman_f_transform_init_scale(&scale, sx, sy);

View File

@ -298,11 +298,11 @@ rescaleValuatorAxis(double coord, AxisInfoPtr from, AxisInfoPtr to,
if (from && from->min_value < from->max_value) { if (from && from->min_value < from->max_value) {
fmin = from->min_value; fmin = from->min_value;
fmax = from->max_value; fmax = from->max_value + 1;
} }
if (to && to->min_value < to->max_value) { if (to && to->min_value < to->max_value) {
tmin = to->min_value; tmin = to->min_value;
tmax = to->max_value; tmax = to->max_value + 1;
} }
if (fmin == tmin && fmax == tmax) if (fmin == tmin && fmax == tmax)
@ -770,6 +770,29 @@ add_to_scroll_valuator(DeviceIntPtr dev, ValuatorMask *mask, int valuator, doubl
} }
static void
scale_for_device_resolution(DeviceIntPtr dev, ValuatorMask *mask)
{
double x;
ValuatorClassPtr v = dev->valuator;
int xrange = v->axes[0].max_value - v->axes[0].min_value + 1;
int yrange = v->axes[1].max_value - v->axes[1].min_value + 1;
double screen_ratio = 1.0 * screenInfo.width/screenInfo.height;
double device_ratio = 1.0 * xrange/yrange;
double resolution_ratio = 1.0;
double ratio;
if (!valuator_mask_fetch_double(mask, 0, &x))
return;
if (v->axes[0].resolution != 0 && v->axes[1].resolution != 0)
resolution_ratio = 1.0 * v->axes[0].resolution/v->axes[1].resolution;
ratio = device_ratio/resolution_ratio/screen_ratio;
valuator_mask_set_double(mask, 0, x * ratio);
}
/** /**
* Move the device's pointer by the values given in @valuators. * Move the device's pointer by the values given in @valuators.
* *
@ -781,27 +804,14 @@ moveRelative(DeviceIntPtr dev, int flags, ValuatorMask *mask)
{ {
int i; int i;
Bool clip_xy = IsMaster(dev) || !IsFloating(dev); Bool clip_xy = IsMaster(dev) || !IsFloating(dev);
ValuatorClassPtr v = dev->valuator;
/* for abs devices in relative mode, we've just scaled wrong, since we /* for abs devices in relative mode, we've just scaled wrong, since we
mapped the device's shape into the screen shape. Undo this. */ mapped the device's shape into the screen shape. Undo this. */
if ((flags & POINTER_ABSOLUTE) == 0 && dev->valuator && if ((flags & POINTER_ABSOLUTE) == 0 && v && v->numAxes > 1 &&
dev->valuator->axes[0].min_value < dev->valuator->axes[0].max_value) { v->axes[0].min_value < v->axes[0].max_value &&
v->axes[1].min_value < v->axes[1].max_value) {
double ratio = 1.0 * screenInfo.width/screenInfo.height; scale_for_device_resolution(dev, mask);
if (ratio > 1.0) {
double y;
if (valuator_mask_fetch_double(mask, 1, &y)) {
y *= ratio;
valuator_mask_set_double(mask, 1, y);
}
} else {
double x;
if (valuator_mask_fetch_double(mask, 0, &x)) {
x *= ratio;
valuator_mask_set_double(mask, 0, x);
}
}
} }
/* calc other axes, clip, drop back into valuators */ /* calc other axes, clip, drop back into valuators */
@ -914,9 +924,9 @@ scale_to_desktop(DeviceIntPtr dev, ValuatorMask *mask,
/* scale x&y to desktop coordinates */ /* scale x&y to desktop coordinates */
*screenx = rescaleValuatorAxis(x, dev->valuator->axes + 0, NULL, *screenx = rescaleValuatorAxis(x, dev->valuator->axes + 0, NULL,
screenInfo.x, screenInfo.width - 1); screenInfo.x, screenInfo.width);
*screeny = rescaleValuatorAxis(y, dev->valuator->axes + 1, NULL, *screeny = rescaleValuatorAxis(y, dev->valuator->axes + 1, NULL,
screenInfo.y, screenInfo.height - 1); screenInfo.y, screenInfo.height);
*devx = x; *devx = x;
*devy = y; *devy = y;
@ -1356,6 +1366,12 @@ QueuePointerEvents(DeviceIntPtr device, int type,
* is the last coordinate on the first screen and must be rescaled for the * is the last coordinate on the first screen and must be rescaled for the
* event to be m. XI2 clients that do their own coordinate mapping would * event to be m. XI2 clients that do their own coordinate mapping would
* otherwise interpret the position of the device elsewere to the cursor. * otherwise interpret the position of the device elsewere to the cursor.
* However, this scaling leads to losses:
* if we have two ScreenRecs we scale from e.g. [0..44704] (Wacom I4) to
* [0..2048[. that gives us 2047.954 as desktop coord, or the per-screen
* coordinate 1023.954. Scaling that back into the device coordinate range
* gives us 44703. So off by one device unit. It's a bug, but we'll have to
* live with it because with all this scaling, we just cannot win.
* *
* @return the number of events written into events. * @return the number of events written into events.
*/ */