diff options
Diffstat (limited to 'xorg-server')
-rw-r--r-- | xorg-server/Xext/xtest.c | 17 | ||||
-rw-r--r-- | xorg-server/Xi/exevents.c | 2 | ||||
-rw-r--r-- | xorg-server/dix/devices.c | 46 | ||||
-rw-r--r-- | xorg-server/dix/events.c | 6 | ||||
-rw-r--r-- | xorg-server/dix/getevents.c | 75 | ||||
-rw-r--r-- | xorg-server/dix/ptrveloc.c | 38 | ||||
-rw-r--r-- | xorg-server/hw/dmx/config/xdmxconfig.c | 3 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/common/xf86Module.h | 2 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/os-support/linux/lnx_acpi.c | 9 | ||||
-rw-r--r-- | xorg-server/include/input.h | 3 | ||||
-rw-r--r-- | xorg-server/include/inputstr.h | 8 | ||||
-rw-r--r-- | xorg-server/include/list.h | 2 | ||||
-rw-r--r-- | xorg-server/include/misc.h | 1 | ||||
-rw-r--r-- | xorg-server/include/protocol-versions.h | 2 | ||||
-rw-r--r-- | xorg-server/os/log.c | 21 | ||||
-rwxr-xr-x | xorg-server/os/utils.c | 32 | ||||
-rw-r--r-- | xorg-server/randr/randrstr.h | 2 | ||||
-rw-r--r-- | xorg-server/test/signal-logging.c | 200 | ||||
-rw-r--r-- | xorg-server/xkb/xkbActions.c | 147 |
19 files changed, 398 insertions, 218 deletions
diff --git a/xorg-server/Xext/xtest.c b/xorg-server/Xext/xtest.c index e7f94d3d9..b0b974c78 100644 --- a/xorg-server/Xext/xtest.c +++ b/xorg-server/Xext/xtest.c @@ -153,7 +153,6 @@ ProcXTestFakeInput(ClientPtr client) DeviceIntPtr dev = NULL; WindowPtr root; Bool extension = FALSE; - deviceValuator *dv = NULL; ValuatorMask mask; int valuators[MAX_VALUATORS] = { 0 }; int numValuators = 0; @@ -238,14 +237,14 @@ ProcXTestFakeInput(ClientPtr client) } if (nev > 1 && !dev->valuator) { - client->errorValue = dv->first_valuator; + client->errorValue = firstValuator; return BadValue; } /* check validity of valuator events */ base = firstValuator; for (n = 1; n < nev; n++) { - dv = (deviceValuator *) (ev + n); + deviceValuator *dv = (deviceValuator *) (ev + n); if (dv->type != DeviceValuator) { client->errorValue = dv->type; return BadValue; @@ -303,7 +302,7 @@ ProcXTestFakeInput(ClientPtr client) numValuators = 2; firstValuator = 0; if (ev->u.u.detail == xFalse) - flags = POINTER_ABSOLUTE | POINTER_SCREEN; + flags = POINTER_ABSOLUTE | POINTER_DESKTOP; break; default: client->errorValue = ev->u.u.type; @@ -374,6 +373,14 @@ ProcXTestFakeInput(ClientPtr client) client->errorValue = ev->u.keyButtonPointer.root; return BadValue; } + + /* Add the root window's offset to the valuators */ + if ((flags & POINTER_ABSOLUTE) && firstValuator <= 1 && numValuators > 0) { + if (firstValuator == 0) + valuators[0] += root->drawable.pScreen->x; + if (firstValuator < 2 && firstValuator + numValuators > 1) + valuators[1 - firstValuator] += root->drawable.pScreen->y; + } } if (ev->u.u.detail != xTrue && ev->u.u.detail != xFalse) { client->errorValue = ev->u.u.detail; @@ -416,7 +423,7 @@ ProcXTestFakeInput(ClientPtr client) } for (i = 0; i < nevents; i++) - mieqProcessDeviceEvent(dev, &xtest_evlist[i], NULL); + mieqProcessDeviceEvent(dev, &xtest_evlist[i], miPointerGetScreen(inputInfo.pointer)); if (need_ptr_update) miPointerUpdateSprite(dev); diff --git a/xorg-server/Xi/exevents.c b/xorg-server/Xi/exevents.c index 2ff2471c5..079de15bf 100644 --- a/xorg-server/Xi/exevents.c +++ b/xorg-server/Xi/exevents.c @@ -1265,7 +1265,7 @@ TouchCopyValuatorData(DeviceEvent *ev, TouchPointInfoPtr ti) { int i; - for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) + for (i = 0; i < ARRAY_SIZE(ev->valuators.data); i++) if (BitIsOn(ev->valuators.mask, i)) valuator_mask_set_double(ti->valuators, i, ev->valuators.data[i]); } diff --git a/xorg-server/dix/devices.c b/xorg-server/dix/devices.c index f82b81ec0..0df1d3834 100644 --- a/xorg-server/dix/devices.c +++ b/xorg-server/dix/devices.c @@ -97,9 +97,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; @@ -126,16 +127,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; } /** @@ -312,9 +318,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, @@ -521,6 +528,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); @@ -1052,6 +1065,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 cb9440b7c..f895365d6 100644 --- a/xorg-server/dix/events.c +++ b/xorg-server/dix/events.c @@ -4575,6 +4575,7 @@ DeviceEnterLeaveEvent(DeviceIntPtr mouse, { GrabPtr grab = mouse->deviceGrab.grab; xXIEnterEvent *event; + WindowPtr focus; int filter; int btlen, len, i; DeviceIntPtr kbd; @@ -4616,6 +4617,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 ad45149d2..8d9f9a54e 100644 --- a/xorg-server/dix/getevents.c +++ b/xorg-server/dix/getevents.c @@ -791,11 +791,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]; @@ -835,27 +857,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); } } @@ -1194,6 +1222,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 @@ -1221,7 +1270,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; @@ -1234,7 +1283,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); @@ -1383,10 +1432,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); @@ -1395,12 +1444,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 7d3d9f938..844e18538 100644 --- a/xorg-server/dix/ptrveloc.c +++ b/xorg-server/dix/ptrveloc.c @@ -86,7 +86,7 @@ DeletePredictableAccelerationProperties(DeviceIntPtr, /*#define PTRACCEL_DEBUGGING*/ #ifdef PTRACCEL_DEBUGGING -#define DebugAccelF ErrorF +#define DebugAccelF(...) ErrorFSigSafe("dix/ptraccel: " __VA_ARGS__) #else #define DebugAccelF(...) /* */ #endif @@ -430,7 +430,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); @@ -575,7 +575,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; @@ -623,7 +623,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; } @@ -635,7 +636,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; @@ -656,7 +657,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; @@ -669,14 +670,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 @@ -702,6 +703,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; } @@ -777,7 +780,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. */ @@ -801,14 +804,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; @@ -1059,11 +1062,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 && @@ -1122,6 +1122,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); @@ -1131,8 +1132,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); } } } diff --git a/xorg-server/hw/dmx/config/xdmxconfig.c b/xorg-server/hw/dmx/config/xdmxconfig.c index f30841244..2121dd781 100644 --- a/xorg-server/hw/dmx/config/xdmxconfig.c +++ b/xorg-server/hw/dmx/config/xdmxconfig.c @@ -31,9 +31,6 @@ * */ -#ifdef HAVE_DMX_CONFIG_H -#include <dmx-config.h> -#endif #include <stdio.h> #include <stdlib.h> diff --git a/xorg-server/hw/xfree86/common/xf86Module.h b/xorg-server/hw/xfree86/common/xf86Module.h index e545c1498..1393427f8 100644 --- a/xorg-server/hw/xfree86/common/xf86Module.h +++ b/xorg-server/hw/xfree86/common/xf86Module.h @@ -81,7 +81,7 @@ typedef enum { */ #define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 4) #define ABI_VIDEODRV_VERSION SET_ABI_VERSION(14, 1) -#define ABI_XINPUT_VERSION SET_ABI_VERSION(19, 0) +#define ABI_XINPUT_VERSION SET_ABI_VERSION(19, 1) #define ABI_EXTENSION_VERSION SET_ABI_VERSION(7, 0) #define ABI_FONT_VERSION SET_ABI_VERSION(0, 6) diff --git a/xorg-server/hw/xfree86/os-support/linux/lnx_acpi.c b/xorg-server/hw/xfree86/os-support/linux/lnx_acpi.c index d98efa247..dcaa19ee1 100644 --- a/xorg-server/hw/xfree86/os-support/linux/lnx_acpi.c +++ b/xorg-server/hw/xfree86/os-support/linux/lnx_acpi.c @@ -82,18 +82,21 @@ lnxACPIGetEventFromOs(int fd, pmEvent * events, int num) video = strtok(ev, " "); - GFX = strtok(NULL, " "); + if (!(GFX = strtok(NULL, " "))) + return 0; #if 0 ErrorF("GFX: %s\n", GFX); #endif - notify = strtok(NULL, " "); + if (!(notify = strtok(NULL, " "))) + return 0; notify_l = strtoul(notify, NULL, 16); #if 0 ErrorF("notify: 0x%lx\n", notify_l); #endif - data = strtok(NULL, " "); + if (!(data = strtok(NULL, " "))) + return 0; data_l = strtoul(data, NULL, 16); #if 0 ErrorF("data: 0x%lx\n", data_l); diff --git a/xorg-server/include/input.h b/xorg-server/include/input.h index f53ed9905..5c65597e4 100644 --- a/xorg-server/include/input.h +++ b/xorg-server/include/input.h @@ -62,6 +62,7 @@ SOFTWARE. #define DEVICE_ON 1 #define DEVICE_OFF 2 #define DEVICE_CLOSE 3 +#define DEVICE_ABORT 4 #define POINTER_RELATIVE (1 << 1) #define POINTER_ABSOLUTE (1 << 2) @@ -69,6 +70,7 @@ SOFTWARE. #define POINTER_SCREEN (1 << 4) /* Data in screen coordinates */ #define POINTER_NORAW (1 << 5) /* Don't generate RawEvents */ #define POINTER_EMULATED (1 << 6) /* Event was emulated from another event */ +#define POINTER_DESKTOP (1 << 7) /* Data in desktop coordinates */ /* GetTouchEvent flags */ #define TOUCH_ACCEPT (1 << 0) @@ -268,6 +270,7 @@ extern void DisableAllDevices(void); extern int InitAndStartDevices(void); extern void CloseDownDevices(void); +extern void AbortDevices(void); extern void UndisplayDevices(void); diff --git a/xorg-server/include/inputstr.h b/xorg-server/include/inputstr.h index 48a29bede..de96faeda 100644 --- a/xorg-server/include/inputstr.h +++ b/xorg-server/include/inputstr.h @@ -588,8 +588,12 @@ typedef struct _DeviceIntRec { XIPropertyHandlerPtr handlers; /* NULL-terminated */ } properties; - /* coordinate transformation matrix for absolute input devices */ - struct pixman_f_transform transform; + /* coordinate transformation matrix for relative movement. Matrix with + * the translation component dropped */ + struct pixman_f_transform relative_transform; + /* scale matrix for absolute devices, this is the combined matrix of + [1/scale] . [transform] . [scale]. See DeviceSetTransform */ + struct pixman_f_transform scale_and_transform; /* XTest related master device id */ int xtest_master_id; diff --git a/xorg-server/include/list.h b/xorg-server/include/list.h index 61b10bd2a..cb5caf881 100644 --- a/xorg-server/include/list.h +++ b/xorg-server/include/list.h @@ -358,7 +358,7 @@ xorg_list_is_empty(struct xorg_list *head) * struct foo *element = list; * while ((element = nt_list_next(element, next)) { } * - * This macro is not safe for node deletion. Use xorg_list_for_each_entry_safe + * This macro is not safe for node deletion. Use nt_list_for_each_entry_safe * instead. * * @param list The list or current element. diff --git a/xorg-server/include/misc.h b/xorg-server/include/misc.h index 9ed54b1a8..664e02cae 100644 --- a/xorg-server/include/misc.h +++ b/xorg-server/include/misc.h @@ -260,6 +260,7 @@ extern char **xstrtokenize(const char *str, const char *separators); extern void FormatInt64(int64_t num, char *string); extern void FormatUInt64(uint64_t num, char *string); extern void FormatUInt64Hex(uint64_t num, char *string); +extern void FormatDouble(double dbl, char *string); /** * Compare the two version numbers comprising of major.minor. diff --git a/xorg-server/include/protocol-versions.h b/xorg-server/include/protocol-versions.h index 10f5117f2..5ceaeb012 100644 --- a/xorg-server/include/protocol-versions.h +++ b/xorg-server/include/protocol-versions.h @@ -65,7 +65,7 @@ /* RandR */ #define SERVER_RANDR_MAJOR_VERSION 1 -#define SERVER_RANDR_MINOR_VERSION 3 +#define SERVER_RANDR_MINOR_VERSION 4 /* Record */ #define SERVER_RECORD_MAJOR_VERSION 1 diff --git a/xorg-server/os/log.c b/xorg-server/os/log.c index 23f181d8d..a65b03c66 100644 --- a/xorg-server/os/log.c +++ b/xorg-server/os/log.c @@ -304,7 +304,13 @@ pnprintf(char *string, size_t size, const char *f, va_list args) continue; } - switch (f[++f_idx]) { + f_idx++; + + /* silently swallow length modifiers */ + while (f_idx < f_len && ((f[f_idx] >= '0' && f[f_idx] <= '9') || f[f_idx] == '.')) + f_idx++; + + switch (f[f_idx]) { case 's': string_arg = va_arg(args, char*); p_len = strlen_sigsafe(string_arg); @@ -351,7 +357,16 @@ pnprintf(char *string, size_t size, const char *f, va_list args) for (i = 0; i < p_len && s_idx < size - 1; i++) string[s_idx++] = number[i]; break; - + case 'f': + { + double d = va_arg(args, double); + FormatDouble(d, number); + p_len = strlen_sigsafe(number); + + for (i = 0; i < p_len && s_idx < size - 1; i++) + string[s_idx++] = number[i]; + } + break; default: va_arg(args, char*); string[s_idx++] = '%'; @@ -654,7 +669,7 @@ AbortServer(void) #endif CloseWellKnownConnections(); OsCleanup(TRUE); - CloseDownDevices(); + AbortDevices(); AbortDDX(EXIT_ERR_ABORT); fflush(stderr); if (CoreDump) diff --git a/xorg-server/os/utils.c b/xorg-server/os/utils.c index 518400cfd..750bd8dfb 100755 --- a/xorg-server/os/utils.c +++ b/xorg-server/os/utils.c @@ -2048,6 +2048,38 @@ FormatUInt64(uint64_t num, char *string) string[len] = '\0'; } +/** + * Format a double number as %.2f. + */ +void +FormatDouble(double dbl, char *string) +{ + int slen = 0; + uint64_t frac; + + frac = (dbl > 0 ? dbl : -dbl) * 100.0 + 0.5; + frac %= 100; + + /* write decimal part to string */ + if (dbl < 0 && dbl > -1) + string[slen++] = '-'; + FormatInt64((int64_t)dbl, &string[slen]); + + while(string[slen] != '\0') + slen++; + + /* append fractional part, but only if we have enough characters. We + * expect string to be 21 chars (incl trailing \0) */ + if (slen <= 17) { + string[slen++] = '.'; + if (frac < 10) + string[slen++] = '0'; + + FormatUInt64(frac, &string[slen]); + } +} + + /* Format a number into a hexadecimal string in a signal safe manner. The string * should be at least 17 characters in order to handle all uint64_t values. */ void diff --git a/xorg-server/randr/randrstr.h b/xorg-server/randr/randrstr.h index a16302f4d..f52d0f284 100644 --- a/xorg-server/randr/randrstr.h +++ b/xorg-server/randr/randrstr.h @@ -57,7 +57,7 @@ #define RANDR_13_INTERFACE 1 /* requires RANDR_12_INTERFACE */ #define RANDR_GET_CRTC_INTERFACE 1 -#define RANDR_INTERFACE_VERSION 0x0103 +#define RANDR_INTERFACE_VERSION 0x0104 typedef XID RRMode; typedef XID RROutput; diff --git a/xorg-server/test/signal-logging.c b/xorg-server/test/signal-logging.c index 810bd20ed..1ef17af2c 100644 --- a/xorg-server/test/signal-logging.c +++ b/xorg-server/test/signal-logging.c @@ -41,15 +41,41 @@ struct signed_number_format_test { char string[21]; }; +struct float_number_format_test { + double number; + char string[21]; +}; + +static Bool +check_signed_number_format_test(long int number) +{ + char string[21]; + char expected[21]; + + sprintf(expected, "%ld", number); + FormatInt64(number, string); + if(strncmp(string, expected, 21) != 0) { + fprintf(stderr, "Failed to convert %jd to decimal string (expected %s but got %s)\n", + number, expected, string); + return FALSE; + } + + return TRUE; +} + static Bool -check_signed_number_format_test(const struct signed_number_format_test *test) +check_float_format_test(double number) { char string[21]; + char expected[21]; + + /* we currently always print float as .2f */ + sprintf(expected, "%.2f", number); - FormatInt64(test->number, string); - if(strncmp(string, test->string, 21) != 0) { - fprintf(stderr, "Failed to convert %jd to decimal string (%s vs %s)\n", - test->number, test->string, string); + FormatDouble(number, string); + if(strncmp(string, expected, 21) != 0) { + fprintf(stderr, "Failed to convert %f to string (%s vs %s)\n", + number, expected, string); return FALSE; } @@ -57,125 +83,71 @@ check_signed_number_format_test(const struct signed_number_format_test *test) } static Bool -check_number_format_test(const struct number_format_test *test) +check_number_format_test(long unsigned int number) { char string[21]; + char expected[21]; - FormatUInt64(test->number, string); - if(strncmp(string, test->string, 21) != 0) { + sprintf(expected, "%lu", number); + + FormatUInt64(number, string); + if(strncmp(string, expected, 21) != 0) { fprintf(stderr, "Failed to convert %ju to decimal string (%s vs %s)\n", - test->number, test->string, string); + number, expected, string); return FALSE; } - FormatUInt64Hex(test->number, string); - if(strncmp(string, test->hex_string, 17) != 0) { - fprintf(stderr, - "Failed to convert %ju to hexadecimal string (%s vs %s)\n", - test->number, test->hex_string, string); + + sprintf(expected, "%lx", number); + FormatUInt64Hex(number, string); + if(strncmp(string, expected, 17) != 0) { + fprintf(stderr, "Failed to convert %ju to hexadecimal string (%s vs %s)\n", + number, expected, string); return FALSE; } return TRUE; } +/* FIXME: max range stuff */ +double float_tests[] = { 0, 5, 0.1, 0.01, 5.2342, 10.2301, + -1, -2.00, -0.6023, -1203.30 + }; + static void number_formatting(void) { int i; - struct number_format_test unsigned_tests[] = { - { /* Zero */ - 0, - "0", - "0", - }, - { /* Single digit number */ - 5, - "5", - "5", - }, - { /* Two digit decimal number */ - 12, - "12", - "c", - }, - { /* Two digit hex number */ - 37, - "37", - "25", - }, - { /* Large < 32 bit number */ - 0xC90B2, - "823474", - "c90b2", - }, - { /* Large > 32 bit number */ - 0x15D027BF211B37A, - "98237498237498234", - "15d027bf211b37a", - }, - { /* Maximum 64-bit number */ - 0xFFFFFFFFFFFFFFFF, - "18446744073709551615", - "ffffffffffffffff", - }, + long unsigned int unsigned_tests[] = { 0,/* Zero */ + 5, /* Single digit number */ + 12, /* Two digit decimal number */ + 37, /* Two digit hex number */ + 0xC90B2, /* Large < 32 bit number */ + 0x15D027BF211B37A, /* Large > 32 bit number */ + 0xFFFFFFFFFFFFFFFF, /* Maximum 64-bit number */ }; - struct signed_number_format_test signed_tests[] = { - { /* Zero */ - 0, - "0", - }, - { /* Single digit number */ - 5, - "5", - }, - { /* Two digit decimal number */ - 12, - "12", - }, - { /* Two digit hex number */ - 37, - "37", - }, - { /* Large < 32 bit number */ - 0xC90B2, - "823474", - }, - { /* Large > 32 bit number */ - 0x15D027BF211B37A, - "98237498237498234", - }, - { /* Maximum 64-bit signed number */ - 0x7FFFFFFFFFFFFFFF, - "9223372036854775807", - }, - { /* Single digit number */ - -1, - "-1", - }, - { /* Two digit decimal number */ - -12, - "-12", - }, - { /* Large < 32 bit number */ - -0xC90B2, - "-823474", - }, - { /* Large > 32 bit number */ - -0x15D027BF211B37A, - "-98237498237498234", - }, - { /* Maximum 64-bit number */ - -0x7FFFFFFFFFFFFFFF, - "-9223372036854775807", - }, - }; + long int signed_tests[] = { 0,/* Zero */ + 5, /* Single digit number */ + 12, /* Two digit decimal number */ + 37, /* Two digit hex number */ + 0xC90B2, /* Large < 32 bit number */ + 0x15D027BF211B37A, /* Large > 32 bit number */ + 0x7FFFFFFFFFFFFFFF, /* Maximum 64-bit signed number */ + -1, /* Single digit number */ + -12, /* Two digit decimal number */ + -0xC90B2, /* Large < 32 bit number */ + -0x15D027BF211B37A, /* Large > 32 bit number */ + -0x7FFFFFFFFFFFFFFF, /* Maximum 64-bit signed number */ + } ; for (i = 0; i < sizeof(unsigned_tests) / sizeof(unsigned_tests[0]); i++) - assert(check_number_format_test(unsigned_tests + i)); + assert(check_number_format_test(unsigned_tests[i])); for (i = 0; i < sizeof(unsigned_tests) / sizeof(signed_tests[0]); i++) - assert(check_signed_number_format_test(signed_tests + i)); + assert(check_signed_number_format_test(signed_tests[i])); + + for (i = 0; i < sizeof(float_tests) / sizeof(float_tests[0]); i++) + assert(check_float_format_test(float_tests[i])); } #pragma GCC diagnostic ignored "-Wformat-security" @@ -292,6 +264,30 @@ static void logging_format(void) ptr <<= 1; } while(ptr); + + for (i = 0; i < sizeof(float_tests)/sizeof(float_tests[0]); i++) { + double d = float_tests[i]; + char expected[30]; + sprintf(expected, "(EE) %.2f\n", d); + LogMessageVerbSigSafe(X_ERROR, -1, "%f\n", d); + read_log_msg(logmsg); + assert(strcmp(logmsg, expected) == 0); + + /* test for length modifiers, we just ignore them atm */ + LogMessageVerbSigSafe(X_ERROR, -1, "%.3f\n", d); + read_log_msg(logmsg); + assert(strcmp(logmsg, expected) == 0); + + LogMessageVerbSigSafe(X_ERROR, -1, "%3f\n", d); + read_log_msg(logmsg); + assert(strcmp(logmsg, expected) == 0); + + LogMessageVerbSigSafe(X_ERROR, -1, "%.0f\n", d); + read_log_msg(logmsg); + assert(strcmp(logmsg, expected) == 0); + } + + LogClose(EXIT_NO_ERROR); unlink(log_file_path); diff --git a/xorg-server/xkb/xkbActions.c b/xorg-server/xkb/xkbActions.c index c1edeea55..f089bf0fa 100644 --- a/xorg-server/xkb/xkbActions.c +++ b/xorg-server/xkb/xkbActions.c @@ -747,6 +747,15 @@ _XkbFilterActionMessage(XkbSrvInfoPtr xkbi, XkbMessageAction *pMsg; DeviceIntPtr kbd; + if ((filter->keycode != 0) && (filter->keycode != keycode)) + return 1; + + /* This can happen if the key repeats, and the state (modifiers or group) + changes meanwhile. */ + if ((filter->keycode == keycode) && pAction && + (pAction->type != XkbSA_ActionMessage)) + return 1; + kbd = xkbi->device; if (filter->keycode == 0) { /* initial press */ pMsg = &pAction->msg; @@ -774,20 +783,27 @@ _XkbFilterActionMessage(XkbSrvInfoPtr xkbi, } else if (filter->keycode == keycode) { pMsg = &filter->upAction.msg; - if (pMsg->flags & XkbSA_MessageOnRelease) { - xkbActionMessage msg; - - msg.keycode = keycode; - msg.press = 0; - msg.keyEventFollows = - ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0); - memcpy((char *) msg.message, (char *) pMsg->message, - XkbActionMessageLength); - XkbSendActionMessage(kbd, &msg); + if (pAction == NULL) { + if (pMsg->flags & XkbSA_MessageOnRelease) { + xkbActionMessage msg; + + msg.keycode = keycode; + msg.press = 0; + msg.keyEventFollows = + ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0); + memcpy((char *) msg.message, (char *) pMsg->message, + XkbActionMessageLength); + XkbSendActionMessage(kbd, &msg); + } + filter->keycode = 0; + filter->active = 0; + return ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0); + } else if (memcmp(pMsg, pAction, 8) == 0) { + /* Repeat: If we send the same message, avoid multiple messages + on release from piling up. */ + filter->keycode = 0; + filter->active = 0; } - filter->keycode = 0; - filter->active = 0; - return ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0); } return 1; } @@ -803,15 +819,21 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi, xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device); ProcessInputProc backupproc; + if ((filter->keycode != 0) && (filter->keycode != keycode)) + return 1; + + /* This can happen if the key repeats, and the state (modifiers or group) + changes meanwhile. */ + if ((filter->keycode == keycode) && pAction && + (pAction->type != XkbSA_RedirectKey)) + return 1; + /* never actually used uninitialised, but gcc isn't smart enough * to work that out. */ memset(&old, 0, sizeof(old)); memset(&old_prev, 0, sizeof(old_prev)); memset(&ev, 0, sizeof(ev)); - if ((filter->keycode != 0) && (filter->keycode != keycode)) - return 1; - GetSpritePosition(xkbi->device, &x, &y); ev.header = ET_Internal; ev.length = sizeof(DeviceEvent); @@ -870,49 +892,60 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi, xkbi->state = old; xkbi->prev_state = old_prev; } + return 0; } - else if (filter->keycode == keycode) { - - ev.type = ET_KeyRelease; - ev.detail.key = filter->upAction.redirect.new_key; - - mask = XkbSARedirectVModsMask(&filter->upAction.redirect); - mods = XkbSARedirectVMods(&filter->upAction.redirect); - if (mask) - XkbVirtualModsToReal(xkbi->desc, mask, &mask); - if (mods) - XkbVirtualModsToReal(xkbi->desc, mods, &mods); - mask |= filter->upAction.redirect.mods_mask; - mods |= filter->upAction.redirect.mods; - - if (mask || mods) { - old = xkbi->state; - old_prev = xkbi->prev_state; - xkbi->state.base_mods &= ~mask; - xkbi->state.base_mods |= (mods & mask); - xkbi->state.latched_mods &= ~mask; - xkbi->state.latched_mods |= (mods & mask); - xkbi->state.locked_mods &= ~mask; - xkbi->state.locked_mods |= (mods & mask); - XkbComputeDerivedState(xkbi); - xkbi->prev_state = xkbi->state; - } - - UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc); - xkbi->device->public.processInputProc((InternalEvent *) &ev, - xkbi->device); - COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc, - xkbUnwrapProc); - - if (mask || mods) { - xkbi->state = old; - xkbi->prev_state = old_prev; - } - - filter->keycode = 0; - filter->active = 0; + else { + /* If it is a key release, or we redirect to another key, release the + previous new_key. Otherwise, repeat. */ + ev.detail.key = filter->upAction.redirect.new_key; + if (pAction == NULL || ev.detail.key != pAction->redirect.new_key) { + ev.type = ET_KeyRelease; + filter->active = 0; + } + else { + ev.type = ET_KeyPress; + ev.key_repeat = TRUE; + } + + mask = XkbSARedirectVModsMask(&filter->upAction.redirect); + mods = XkbSARedirectVMods(&filter->upAction.redirect); + if (mask) + XkbVirtualModsToReal(xkbi->desc, mask, &mask); + if (mods) + XkbVirtualModsToReal(xkbi->desc, mods, &mods); + mask |= filter->upAction.redirect.mods_mask; + mods |= filter->upAction.redirect.mods; + + if (mask || mods) { + old = xkbi->state; + old_prev = xkbi->prev_state; + xkbi->state.base_mods &= ~mask; + xkbi->state.base_mods |= (mods & mask); + xkbi->state.latched_mods &= ~mask; + xkbi->state.latched_mods |= (mods & mask); + xkbi->state.locked_mods &= ~mask; + xkbi->state.locked_mods |= (mods & mask); + XkbComputeDerivedState(xkbi); + xkbi->prev_state = xkbi->state; + } + + UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc); + xkbi->device->public.processInputProc((InternalEvent *) &ev, + xkbi->device); + COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc, + xkbUnwrapProc); + + if (mask || mods) { + xkbi->state = old; + xkbi->prev_state = old_prev; + } + + /* We return 1 in case we have sent a release event because the new_key + has changed. Then, subsequently, we will call this function again + with the same pAction, which will create the press for the new + new_key. */ + return (pAction && ev.detail.key != pAction->redirect.new_key); } - return 0; } static int |