aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/dix
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/dix')
-rw-r--r--xorg-server/dix/devices.c46
-rw-r--r--xorg-server/dix/events.c6
-rw-r--r--xorg-server/dix/getevents.c75
-rw-r--r--xorg-server/dix/ptrveloc.c38
4 files changed, 127 insertions, 38 deletions
diff --git a/xorg-server/dix/devices.c b/xorg-server/dix/devices.c
index 3c7d480c6..be236dd70 100644
--- a/xorg-server/dix/devices.c
+++ b/xorg-server/dix/devices.c
@@ -93,9 +93,10 @@ SOFTWARE.
static void RecalculateMasterButtons(DeviceIntPtr slave);
static void
-DeviceSetTransform(DeviceIntPtr dev, float *transform)
+DeviceSetTransform(DeviceIntPtr dev, float *transform_data)
{
struct pixman_f_transform scale;
+ struct pixman_f_transform transform;
double sx, sy;
int x, y;
@@ -122,16 +123,21 @@ DeviceSetTransform(DeviceIntPtr dev, float *transform)
/* transform */
for (y = 0; y < 3; y++)
for (x = 0; x < 3; x++)
- dev->transform.m[y][x] = *transform++;
+ transform.m[y][x] = *transform_data++;
- pixman_f_transform_multiply(&dev->transform, &scale, &dev->transform);
+ pixman_f_transform_multiply(&dev->scale_and_transform, &scale, &transform);
/* scale */
pixman_f_transform_init_scale(&scale, 1.0 / sx, 1.0 / sy);
scale.m[0][2] = -dev->valuator->axes[0].min_value / sx;
scale.m[1][2] = -dev->valuator->axes[1].min_value / sy;
- pixman_f_transform_multiply(&dev->transform, &dev->transform, &scale);
+ pixman_f_transform_multiply(&dev->scale_and_transform, &dev->scale_and_transform, &scale);
+
+ /* remove translation component for relative movements */
+ dev->relative_transform = transform;
+ dev->relative_transform.m[0][2] = 0;
+ dev->relative_transform.m[1][2] = 0;
}
/**
@@ -308,9 +314,10 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
/* unity matrix */
memset(transform, 0, sizeof(transform));
transform[0] = transform[4] = transform[8] = 1.0f;
- dev->transform.m[0][0] = 1.0;
- dev->transform.m[1][1] = 1.0;
- dev->transform.m[2][2] = 1.0;
+ dev->relative_transform.m[0][0] = 1.0;
+ dev->relative_transform.m[1][1] = 1.0;
+ dev->relative_transform.m[2][2] = 1.0;
+ dev->scale_and_transform = dev->relative_transform;
XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_TRANSFORM),
XIGetKnownProperty(XATOM_FLOAT), 32,
@@ -516,6 +523,12 @@ DisableAllDevices(void)
{
DeviceIntPtr dev, tmp;
+ /* Disable slave devices first, excluding XTest devices */
+ nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
+ if (!IsXTestDevice(dev, NULL) && !IsMaster(dev))
+ DisableDevice(dev, FALSE);
+ }
+ /* Disable XTest devices */
nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
if (!IsMaster(dev))
DisableDevice(dev, FALSE);
@@ -1043,6 +1056,25 @@ CloseDownDevices(void)
}
/**
+ * Signal all devices that we're in the process of aborting.
+ * This function is called from a signal handler.
+ */
+void
+AbortDevices(void)
+{
+ DeviceIntPtr dev;
+ nt_list_for_each_entry(dev, inputInfo.devices, next) {
+ if (!IsMaster(dev))
+ (*dev->deviceProc) (dev, DEVICE_ABORT);
+ }
+
+ nt_list_for_each_entry(dev, inputInfo.off_devices, next) {
+ if (!IsMaster(dev))
+ (*dev->deviceProc) (dev, DEVICE_ABORT);
+ }
+}
+
+/**
* Remove the cursor sprite for all devices. This needs to be done before any
* resources are freed or any device is deleted.
*/
diff --git a/xorg-server/dix/events.c b/xorg-server/dix/events.c
index f72cdc7c4..2682ecd46 100644
--- a/xorg-server/dix/events.c
+++ b/xorg-server/dix/events.c
@@ -4569,6 +4569,7 @@ DeviceEnterLeaveEvent(DeviceIntPtr mouse,
{
GrabPtr grab = mouse->deviceGrab.grab;
xXIEnterEvent *event;
+ WindowPtr focus;
int filter;
int btlen, len, i;
DeviceIntPtr kbd;
@@ -4610,6 +4611,11 @@ DeviceEnterLeaveEvent(DeviceIntPtr mouse,
event->group.locked_group = kbd->key->xkbInfo->state.locked_group;
}
+ focus = (kbd) ? kbd->focus->win : None;
+ if ((focus != NoneWin) &&
+ ((pWin == focus) || (focus == PointerRootWin) || IsParent(focus, pWin)))
+ event->focus = TRUE;
+
FixUpEventFromWindow(mouse->spriteInfo->sprite, (xEvent *) event, pWin,
None, FALSE);
diff --git a/xorg-server/dix/getevents.c b/xorg-server/dix/getevents.c
index a1e193815..a4f192cf0 100644
--- a/xorg-server/dix/getevents.c
+++ b/xorg-server/dix/getevents.c
@@ -776,11 +776,33 @@ add_to_scroll_valuator(DeviceIntPtr dev, ValuatorMask *mask, int valuator, doubl
* @param[in,out] mask Valuator data for this event, modified in-place.
*/
static void
-moveRelative(DeviceIntPtr dev, ValuatorMask *mask)
+moveRelative(DeviceIntPtr dev, int flags, ValuatorMask *mask)
{
int i;
Bool clip_xy = IsMaster(dev) || !IsFloating(dev);
+ /* for abs devices in relative mode, we've just scaled wrong, since we
+ mapped the device's shape into the screen shape. Undo this. */
+ if ((flags & POINTER_ABSOLUTE) == 0 && dev->valuator &&
+ dev->valuator->axes[0].min_value < dev->valuator->axes[0].max_value) {
+
+ double ratio = 1.0 * screenInfo.width/screenInfo.height;
+
+ 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 */
for (i = 0; i < valuator_mask_size(mask); i++) {
double val = dev->last.valuators[i];
@@ -820,27 +842,33 @@ accelPointer(DeviceIntPtr dev, ValuatorMask *valuators, CARD32 ms)
* device's coordinate range.
*
* @param dev The device to scale for.
- * @param[in, out] mask The mask in desktop coordinates, modified in place
+ * @param[in, out] mask The mask in desktop/screen coordinates, modified in place
* to contain device coordinate range.
+ * @param flags If POINTER_SCREEN is set, mask is in per-screen coordinates.
+ * Otherwise, mask is in desktop coords.
*/
static void
-scale_from_screen(DeviceIntPtr dev, ValuatorMask *mask)
+scale_from_screen(DeviceIntPtr dev, ValuatorMask *mask, int flags)
{
double scaled;
ScreenPtr scr = miPointerGetScreen(dev);
if (valuator_mask_isset(mask, 0)) {
- scaled = valuator_mask_get_double(mask, 0) + scr->x;
+ scaled = valuator_mask_get_double(mask, 0);
+ if (flags & POINTER_SCREEN)
+ scaled += scr->x;
scaled = rescaleValuatorAxis(scaled,
NULL, dev->valuator->axes + 0,
- 0, scr->width);
+ screenInfo.x, screenInfo.width);
valuator_mask_set_double(mask, 0, scaled);
}
if (valuator_mask_isset(mask, 1)) {
- scaled = valuator_mask_get_double(mask, 1) + scr->y;
+ scaled = valuator_mask_get_double(mask, 1);
+ if (flags & POINTER_SCREEN)
+ scaled += scr->y;
scaled = rescaleValuatorAxis(scaled,
NULL, dev->valuator->axes + 1,
- 0, scr->height);
+ screenInfo.y, screenInfo.height);
valuator_mask_set_double(mask, 1, scaled);
}
}
@@ -1174,6 +1202,27 @@ transform(struct pixman_f_transform *m, double *x, double *y)
*y = p.v[1];
}
+static void
+transformRelative(DeviceIntPtr dev, ValuatorMask *mask)
+{
+ double x = 0, y = 0;
+
+ valuator_mask_fetch_double(mask, 0, &x);
+ valuator_mask_fetch_double(mask, 1, &y);
+
+ transform(&dev->relative_transform, &x, &y);
+
+ if (x)
+ valuator_mask_set_double(mask, 0, x);
+ else
+ valuator_mask_unset(mask, 0);
+
+ if (y)
+ valuator_mask_set_double(mask, 1, y);
+ else
+ valuator_mask_unset(mask, 1);
+}
+
/**
* Apply the device's transformation matrix to the valuator mask and replace
* the scaled values in mask. This transformation only applies to valuators
@@ -1201,7 +1250,7 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
ox = dev->last.valuators[0];
oy = dev->last.valuators[1];
- pixman_f_transform_invert(&invert, &dev->transform);
+ pixman_f_transform_invert(&invert, &dev->scale_and_transform);
transform(&invert, &ox, &oy);
x = ox;
@@ -1214,7 +1263,7 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
if (valuator_mask_isset(mask, 1))
oy = y = valuator_mask_get_double(mask, 1);
- transform(&dev->transform, &x, &y);
+ transform(&dev->scale_and_transform, &x, &y);
if (valuator_mask_isset(mask, 0) || ox != x)
valuator_mask_set_double(mask, 0, x);
@@ -1363,10 +1412,10 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
/* valuators are in driver-native format (rel or abs) */
if (flags & POINTER_ABSOLUTE) {
- if (flags & POINTER_SCREEN) { /* valuators are in screen coords */
+ if (flags & (POINTER_SCREEN | POINTER_DESKTOP)) { /* valuators are in screen/desktop coords */
sx = valuator_mask_get(&mask, 0);
sy = valuator_mask_get(&mask, 1);
- scale_from_screen(pDev, &mask);
+ scale_from_screen(pDev, &mask, flags);
}
transformAbsolute(pDev, &mask);
@@ -1375,12 +1424,14 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
set_raw_valuators(raw, &mask, raw->valuators.data);
}
else {
+ transformRelative(pDev, &mask);
+
if (flags & POINTER_ACCELERATE)
accelPointer(pDev, &mask, ms);
if ((flags & POINTER_NORAW) == 0)
set_raw_valuators(raw, &mask, raw->valuators.data);
- moveRelative(pDev, &mask);
+ moveRelative(pDev, flags, &mask);
}
/* valuators are in device coordinate system in absolute coordinates */
diff --git a/xorg-server/dix/ptrveloc.c b/xorg-server/dix/ptrveloc.c
index c7994b03d..d6fef9cf3 100644
--- a/xorg-server/dix/ptrveloc.c
+++ b/xorg-server/dix/ptrveloc.c
@@ -77,7 +77,7 @@ DeletePredictableAccelerationProperties(DeviceIntPtr,
/*#define PTRACCEL_DEBUGGING*/
#ifdef PTRACCEL_DEBUGGING
-#define DebugAccelF ErrorF
+#define DebugAccelF(...) ErrorFSigSafe("dix/ptraccel: " __VA_ARGS__)
#else
#define DebugAccelF(...) /* */
#endif
@@ -421,7 +421,7 @@ void
InitTrackers(DeviceVelocityPtr vel, int ntracker)
{
if (ntracker < 1) {
- ErrorF("(dix ptracc) invalid number of trackers\n");
+ ErrorF("invalid number of trackers\n");
return;
}
free(vel->tracker);
@@ -566,7 +566,7 @@ FeedTrackers(DeviceVelocityPtr vel, double dx, double dy, int cur_t)
vel->tracker[n].dy = 0.0;
vel->tracker[n].time = cur_t;
vel->tracker[n].dir = GetDirection(dx, dy);
- DebugAccelF("(dix prtacc) motion [dx: %i dy: %i dir:%i diff: %i]\n",
+ DebugAccelF("motion [dx: %f dy: %f dir:%d diff: %d]\n",
dx, dy, vel->tracker[n].dir,
cur_t - vel->tracker[vel->cur_tracker].time);
vel->cur_tracker = n;
@@ -614,7 +614,8 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
/* bail out if data is too old and protect from overrun */
if (age_ms >= vel->reset_time || age_ms < 0) {
- DebugAccelF("(dix prtacc) query: tracker too old\n");
+ DebugAccelF("query: tracker too old (reset after %d, age is %d)\n",
+ vel->reset_time, age_ms);
break;
}
@@ -626,7 +627,7 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
*/
dir &= tracker->dir;
if (dir == 0) { /* we've changed octant of movement (e.g. NE → NW) */
- DebugAccelF("(dix prtacc) query: no longer linear\n");
+ DebugAccelF("query: no longer linear\n");
/* instead of breaking it we might also inspect the partition after,
* but actual improvement with this is probably rare. */
break;
@@ -647,7 +648,7 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
velocity_diff / (initial_velocity + tracker_velocity) >=
vel->max_rel_diff) {
/* we're not in range, quit - it won't get better. */
- DebugAccelF("(dix prtacc) query: tracker too different:"
+ DebugAccelF("query: tracker too different:"
" old %2.2f initial %2.2f diff: %2.2f\n",
tracker_velocity, initial_velocity, velocity_diff);
break;
@@ -660,14 +661,14 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
}
}
if (offset == vel->num_tracker) {
- DebugAccelF("(dix prtacc) query: last tracker in effect\n");
+ DebugAccelF("query: last tracker in effect\n");
used_offset = vel->num_tracker - 1;
}
if (used_offset >= 0) {
#ifdef PTRACCEL_DEBUGGING
MotionTracker *tracker = TRACKER(vel, used_offset);
- DebugAccelF("(dix prtacc) result: offset %i [dx: %i dy: %i diff: %i]\n",
+ DebugAccelF("result: offset %i [dx: %f dy: %f diff: %i]\n",
used_offset, tracker->dx, tracker->dy,
cur_t - tracker->time);
#endif
@@ -693,6 +694,8 @@ ProcessVelocityData2D(DeviceVelocityPtr vel, double dx, double dy, int time)
velocity = QueryTrackers(vel, time);
+ DebugAccelF("velocity is %f\n", velocity);
+
vel->velocity = velocity;
return velocity == 0;
}
@@ -768,7 +771,7 @@ ComputeAcceleration(DeviceIntPtr dev,
double result;
if (vel->velocity <= 0) {
- DebugAccelF("(dix ptracc) profile skipped\n");
+ DebugAccelF("profile skipped\n");
/*
* If we have no idea about device velocity, don't pretend it.
*/
@@ -792,14 +795,14 @@ ComputeAcceleration(DeviceIntPtr dev,
threshold,
acc);
result /= 6.0f;
- DebugAccelF("(dix ptracc) profile average [%.2f ... %.2f] is %.3f\n",
+ DebugAccelF("profile average [%.2f ... %.2f] is %.3f\n",
vel->velocity, vel->last_velocity, result);
}
else {
result = BasicComputeAcceleration(dev, vel,
vel->velocity, threshold, acc);
- DebugAccelF("(dix ptracc) profile sample [%.2f] is %.3f\n",
- vel->velocity, res);
+ DebugAccelF("profile sample [%.2f] is %.3f\n",
+ vel->velocity, result);
}
return result;
@@ -1050,11 +1053,8 @@ SetDeviceSpecificAccelerationProfile(DeviceVelocityPtr vel,
DeviceVelocityPtr
GetDevicePredictableAccelData(DeviceIntPtr dev)
{
- /*sanity check */
- if (!dev) {
- ErrorF("[dix] accel: DeviceIntPtr was NULL");
- return NULL;
- }
+ BUG_RETURN_VAL(!dev, NULL);
+
if (dev->valuator &&
dev->valuator->accelScheme.AccelSchemeProc ==
acceleratePointerPredictable &&
@@ -1113,6 +1113,7 @@ acceleratePointerPredictable(DeviceIntPtr dev, ValuatorMask *val, CARD32 evtime)
(double) dev->ptrfeed->ctrl.num /
(double) dev->ptrfeed->ctrl.den);
+ DebugAccelF("mult is %f\n", mult);
if (mult != 1.0f || velocitydata->const_acceleration != 1.0f) {
if (mult > 1.0f && soften)
ApplySoftening(velocitydata, &dx, &dy);
@@ -1122,8 +1123,7 @@ acceleratePointerPredictable(DeviceIntPtr dev, ValuatorMask *val, CARD32 evtime)
valuator_mask_set_double(val, 0, mult * dx);
if (dy != 0.0)
valuator_mask_set_double(val, 1, mult * dy);
- DebugAccelF("pos (%i | %i) delta x:%.3f y:%.3f\n", mult * dx,
- mult * dy);
+ DebugAccelF("delta x:%.3f y:%.3f\n", mult * dx, mult * dy);
}
}
}