From 59056e656c6475816ab45b2798bd4d4466482f6a Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 13 Oct 2009 14:51:49 +1000 Subject: Remove the reopen timer logic. This logic was needed in older kernels that sometimes gave error messages after coming back from resume (2.6.27 release kernels). I haven't seen any log files that needed this reopen timer in a long time, suggesting that need for it is gone. Signed-off-by: Peter Hutterer --- src/evdev.c | 137 ++++++++++-------------------------------------------------- 1 file changed, 23 insertions(+), 114 deletions(-) (limited to 'src/evdev.c') diff --git a/src/evdev.c b/src/evdev.c index 0dff271..cc44d51 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -125,7 +125,6 @@ static void EvdevInitProperty(DeviceIntPtr dev); static int EvdevSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, BOOL checkonly); static Atom prop_invert = 0; -static Atom prop_reopen = 0; static Atom prop_calibration = 0; static Atom prop_swap = 0; static Atom prop_axis_label = 0; @@ -340,56 +339,6 @@ EvdevQueueButtonClicks(InputInfoPtr pInfo, int button, int count) } } -/** - * Coming back from resume may leave us with a file descriptor that can be - * opened but fails on the first read (ENODEV). - * In this case, try to open the device until it becomes available or until - * the predefined count expires. - */ -static CARD32 -EvdevReopenTimer(OsTimerPtr timer, CARD32 time, pointer arg) -{ - InputInfoPtr pInfo = (InputInfoPtr)arg; - EvdevPtr pEvdev = pInfo->private; - - do { - pInfo->fd = open(pEvdev->device, O_RDWR | O_NONBLOCK, 0); - } while (pInfo->fd < 0 && errno == EINTR); - - if (pInfo->fd != -1) - { - if (EvdevCacheCompare(pInfo, TRUE) == Success) - { - xf86Msg(X_INFO, "%s: Device reopened after %d attempts.\n", pInfo->name, - pEvdev->reopen_attempts - pEvdev->reopen_left + 1); - EvdevOn(pInfo->dev); - } else - { - xf86Msg(X_ERROR, "%s: Device has changed - disabling.\n", - pInfo->name); - xf86DisableDevice(pInfo->dev, FALSE); - close(pInfo->fd); - pInfo->fd = -1; - pEvdev->min_maj = 0; /* don't hog the device */ - } - pEvdev->reopen_left = 0; - return 0; - } - - pEvdev->reopen_left--; - - if (!pEvdev->reopen_left) - { - xf86Msg(X_ERROR, "%s: Failed to reopen device after %d attempts.\n", - pInfo->name, pEvdev->reopen_attempts); - xf86DisableDevice(pInfo->dev, FALSE); - pEvdev->min_maj = 0; /* don't hog the device */ - return 0; - } - - return 100; /* come back in 100 ms */ -} - #define ABS_X_VALUE 0x1 #define ABS_Y_VALUE 0x2 #define ABS_VALUE 0x4 @@ -761,7 +710,6 @@ EvdevReadInput(InputInfoPtr pInfo) { struct input_event ev[NUM_EVENTS]; int i, len = sizeof(ev); - EvdevPtr pEvdev = pInfo->private; while (len == sizeof(ev)) { @@ -774,11 +722,6 @@ EvdevReadInput(InputInfoPtr pInfo) xf86RemoveEnabledDevice(pInfo); close(pInfo->fd); pInfo->fd = -1; - if (pEvdev->reopen_timer) - { - pEvdev->reopen_left = pEvdev->reopen_attempts; - pEvdev->reopen_timer = TimerSet(pEvdev->reopen_timer, 0, 100, EvdevReopenTimer, pInfo); - } } else if (errno != EAGAIN) { /* We use X_NONE here because it doesn't alloc */ @@ -1551,9 +1494,6 @@ EvdevInit(DeviceIntPtr device) /** * Init all extras (wheel emulation, etc.) and grab the device. - * - * Coming from a resume, the grab may fail with ENODEV. In this case, we set a - * timer to wake up and try to reopen the device later. */ static int EvdevOn(DeviceIntPtr device) @@ -1565,43 +1505,37 @@ EvdevOn(DeviceIntPtr device) pInfo = device->public.devicePrivate; pEvdev = pInfo->private; - if (pInfo->fd != -1 && pEvdev->grabDevice && - (rc = ioctl(pInfo->fd, EVIOCGRAB, (void *)1))) + if (pInfo->fd == -1) /* after PreInit fd is still open */ { - xf86Msg(X_WARNING, "%s: Grab failed (%s)\n", pInfo->name, - strerror(errno)); + do { + pInfo->fd = open(pEvdev->device, O_RDWR | O_NONBLOCK, 0); + } while (pInfo->fd < 0 && errno == EINTR); - /* ENODEV - device has disappeared after resume */ - if (rc && errno == ENODEV) - { - close(pInfo->fd); - pInfo->fd = -1; - } - } - - if (pInfo->fd == -1) - { - pEvdev->reopen_left = pEvdev->reopen_attempts; - pEvdev->reopen_timer = TimerSet(pEvdev->reopen_timer, 0, 100, EvdevReopenTimer, pInfo); - } else - { - pEvdev->min_maj = EvdevGetMajorMinor(pInfo); - if (EvdevIsDuplicate(pInfo)) - { - xf86Msg(X_WARNING, "%s: Refusing to enable duplicate device.\n", - pInfo->name); + if (pInfo->fd < 0) { + xf86Msg(X_ERROR, "Unable to open evdev device \"%s\".\n", + pEvdev->device); return !Success; } + } - pEvdev->reopen_timer = TimerSet(pEvdev->reopen_timer, 0, 0, NULL, NULL); + if (pEvdev->grabDevice && (rc = ioctl(pInfo->fd, EVIOCGRAB, (void *)1))) + xf86Msg(X_WARNING, "%s: Grab failed (%s)\n", pInfo->name, + strerror(errno)); - xf86FlushInput(pInfo->fd); - xf86AddEnabledDevice(pInfo); - EvdevMBEmuOn(pInfo); - pEvdev->flags |= EVDEV_INITIALIZED; - device->public.on = TRUE; + pEvdev->min_maj = EvdevGetMajorMinor(pInfo); + if (EvdevIsDuplicate(pInfo)) + { + xf86Msg(X_WARNING, "%s: Refusing to enable duplicate device.\n", + pInfo->name); + return !Success; } + xf86FlushInput(pInfo->fd); + xf86AddEnabledDevice(pInfo); + EvdevMBEmuOn(pInfo); + pEvdev->flags |= EVDEV_INITIALIZED; + device->public.on = TRUE; + return Success; } @@ -1638,11 +1572,6 @@ EvdevProc(DeviceIntPtr device, int what) pEvdev->min_maj = 0; pEvdev->flags &= ~EVDEV_INITIALIZED; device->public.on = FALSE; - if (pEvdev->reopen_timer) - { - TimerFree(pEvdev->reopen_timer); - pEvdev->reopen_timer = NULL; - } break; case DEVICE_CLOSE: @@ -2076,7 +2005,6 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags) return NULL; } - pEvdev->reopen_attempts = xf86SetIntOption(pInfo->options, "ReopenAttempts", 10); pEvdev->invert_x = xf86SetBoolOption(pInfo->options, "InvertX", FALSE); pEvdev->invert_y = xf86SetBoolOption(pInfo->options, "InvertY", FALSE); pEvdev->swap_axes = xf86SetBoolOption(pInfo->options, "SwapAxes", FALSE); @@ -2464,18 +2392,6 @@ EvdevInitProperty(DeviceIntPtr dev) EvdevPtr pEvdev = pInfo->private; int rc; BOOL invert[2]; - char reopen; - - prop_reopen = MakeAtom(EVDEV_PROP_REOPEN, strlen(EVDEV_PROP_REOPEN), - TRUE); - - reopen = pEvdev->reopen_attempts; - rc = XIChangeDeviceProperty(dev, prop_reopen, XA_INTEGER, 8, - PropModeReplace, 1, &reopen, FALSE); - if (rc != Success) - return; - - XISetDevicePropertyDeletable(dev, prop_reopen, FALSE); if (pEvdev->flags & (EVDEV_RELATIVE_EVENTS | EVDEV_ABSOLUTE_EVENTS)) { @@ -2554,13 +2470,6 @@ EvdevSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, pEvdev->invert_x = data[0]; pEvdev->invert_y = data[1]; } - } else if (atom == prop_reopen) - { - if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER) - return BadMatch; - - if (!checkonly) - pEvdev->reopen_attempts = *((CARD8*)val->data); } else if (atom == prop_calibration) { if (val->format != 32 || val->type != XA_INTEGER) -- cgit v1.2.3 From 9cbffda91009001ab6aab84efd2ffb4e35561958 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 22 Oct 2009 15:13:02 +1000 Subject: Forward keycodes > 255 The server doesn't handle them yet but eventually it should learn. Signed-off-by: Peter Hutterer --- src/evdev.c | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'src/evdev.c') diff --git a/src/evdev.c b/src/evdev.c index cc44d51..7013400 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -255,7 +255,6 @@ void EvdevQueueKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value) { int code = ev->code + MIN_KEYCODE; - static char warned[KEY_CNT]; EventQueuePtr pQueue; EvdevPtr pEvdev = pInfo->private; @@ -273,19 +272,6 @@ EvdevQueueKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value) ) return; - if (code > 255) - { - if (ev->code <= KEY_MAX && !warned[ev->code]) - { - xf86Msg(X_WARNING, "%s: unable to handle keycode %d\n", - pInfo->name, ev->code); - warned[ev->code] = 1; - } - - /* The X server can't handle keycodes > 255. */ - return; - } - if (pEvdev->num_queue >= EVDEV_MAXQUEUE) { xf86Msg(X_NONE, "%s: dropping event due to full queue!\n", pInfo->name); -- cgit v1.2.3 From a0f7f34dc5effc5822c618bfbf3a0872669c30ad Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 2 Nov 2009 23:11:55 -0800 Subject: Relax checks when reopening devices When checking whether we are dealing with the same device as before when we try to reopen it evdev should not require exact match of entire keymap. Users should be allowed to adjust keymaps to better match their hardware even after X starts. However we don't expect changes in [BTN_MISC, KEY_OK) range since these codes are reserved for mice, joysticks, tablets and so forth, so we will limit the check to this range. The same goes for absinfo - limits can change and it should not result in device being disabled. Also check the length of the data returned by ioctl and don't try to compare more than we were given. [peter: moved the key comparison below the led+abs comparison] Signed-off-by: Dmitry Torokhov Signed-off-by: Peter Hutterer --- src/evdev.c | 126 ++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 71 insertions(+), 55 deletions(-) (limited to 'src/evdev.c') diff --git a/src/evdev.c b/src/evdev.c index 7013400..06ea83b 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -1586,6 +1586,7 @@ static int EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare) { EvdevPtr pEvdev = pInfo->private; + size_t len; int i; char name[1024] = {0}; @@ -1594,107 +1595,122 @@ EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare) unsigned long rel_bitmask[NLONGS(REL_CNT)] = {0}; unsigned long abs_bitmask[NLONGS(ABS_CNT)] = {0}; unsigned long led_bitmask[NLONGS(LED_CNT)] = {0}; - struct input_absinfo absinfo[ABS_CNT]; - if (ioctl(pInfo->fd, - EVIOCGNAME(sizeof(name) - 1), name) < 0) { + if (ioctl(pInfo->fd, EVIOCGNAME(sizeof(name) - 1), name) < 0) { xf86Msg(X_ERROR, "ioctl EVIOCGNAME failed: %s\n", strerror(errno)); goto error; } - if (compare && strcmp(pEvdev->name, name)) { - xf86Msg(X_ERROR, "%s: device name changed: %s != %s\n", pInfo->name, pEvdev->name, name); + if (!compare) { + strcpy(pEvdev->name, name); + } else if (strcmp(pEvdev->name, name)) { + xf86Msg(X_ERROR, "%s: device name changed: %s != %s\n", + pInfo->name, pEvdev->name, name); goto error; } - if (ioctl(pInfo->fd, - EVIOCGBIT(0, sizeof(bitmask)), bitmask) < 0) { - xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n", pInfo->name, strerror(errno)); + len = ioctl(pInfo->fd, EVIOCGBIT(0, sizeof(bitmask)), bitmask); + if (len < 0) { + xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n", + pInfo->name, strerror(errno)); goto error; } - if (compare && memcmp(pEvdev->bitmask, bitmask, sizeof(bitmask))) { + if (!compare) { + memcpy(pEvdev->bitmask, bitmask, len); + } else if (memcmp(pEvdev->bitmask, bitmask, len)) { xf86Msg(X_ERROR, "%s: device bitmask has changed\n", pInfo->name); goto error; } - - if (ioctl(pInfo->fd, - EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask) < 0) { - xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n", pInfo->name, strerror(errno)); + len = ioctl(pInfo->fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask); + if (len < 0) { + xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n", + pInfo->name, strerror(errno)); goto error; } - if (compare && memcmp(pEvdev->rel_bitmask, rel_bitmask, sizeof(rel_bitmask))) { + if (!compare) { + memcpy(pEvdev->rel_bitmask, rel_bitmask, len); + } else if (memcmp(pEvdev->rel_bitmask, rel_bitmask, len)) { xf86Msg(X_ERROR, "%s: device rel_bitmask has changed\n", pInfo->name); goto error; } - if (ioctl(pInfo->fd, - EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) < 0) { - xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n", pInfo->name, strerror(errno)); + len = ioctl(pInfo->fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask); + if (len < 0) { + xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n", + pInfo->name, strerror(errno)); goto error; } - if (compare && memcmp(pEvdev->abs_bitmask, abs_bitmask, sizeof(abs_bitmask))) { + if (!compare) { + memcpy(pEvdev->abs_bitmask, abs_bitmask, len); + } else if (memcmp(pEvdev->abs_bitmask, abs_bitmask, len)) { xf86Msg(X_ERROR, "%s: device abs_bitmask has changed\n", pInfo->name); goto error; } - if (ioctl(pInfo->fd, - EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) < 0) { - xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n", pInfo->name, strerror(errno)); - goto error; - } - - if (compare && memcmp(pEvdev->key_bitmask, key_bitmask, sizeof(key_bitmask))) { - xf86Msg(X_ERROR, "%s: device key_bitmask has changed\n", pInfo->name); - goto error; - } - - if (ioctl(pInfo->fd, - EVIOCGBIT(EV_LED, sizeof(led_bitmask)), led_bitmask) < 0) { - xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n", pInfo->name, strerror(errno)); + len = ioctl(pInfo->fd, EVIOCGBIT(EV_LED, sizeof(led_bitmask)), led_bitmask); + if (len < 0) { + xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n", + pInfo->name, strerror(errno)); goto error; } - if (compare && memcmp(pEvdev->led_bitmask, led_bitmask, sizeof(led_bitmask))) { + if (!compare) { + memcpy(pEvdev->led_bitmask, led_bitmask, len); + } else if (memcmp(pEvdev->led_bitmask, led_bitmask, len)) { xf86Msg(X_ERROR, "%s: device led_bitmask has changed\n", pInfo->name); goto error; } - memset(absinfo, 0, sizeof(absinfo)); - - for (i = ABS_X; i <= ABS_MAX; i++) - { - if (TestBit(i, abs_bitmask)) - { - if (ioctl(pInfo->fd, EVIOCGABS(i), &absinfo[i]) < 0) { - xf86Msg(X_ERROR, "%s: ioctl EVIOCGABS failed: %s\n", pInfo->name, strerror(errno)); + /* + * Do not try to validate absinfo data since it is not expected + * to be static, always refresh it in evdev structure. + */ + for (i = ABS_X; i <= ABS_MAX; i++) { + if (TestBit(i, abs_bitmask)) { + len = ioctl(pInfo->fd, EVIOCGABS(i), &pEvdev->absinfo[i]); + if (len < 0) { + xf86Msg(X_ERROR, "%s: ioctl EVIOCGABSi(%d) failed: %s\n", + pInfo->name, i, strerror(errno)); goto error; } - /* ignore current position (value) in comparison (bug #19819) */ - absinfo[i].value = pEvdev->absinfo[i].value; } } - if (compare && memcmp(pEvdev->absinfo, absinfo, sizeof(absinfo))) { - xf86Msg(X_ERROR, "%s: device absinfo has changed\n", pInfo->name); + len = ioctl(pInfo->fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask); + if (len < 0) { + xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n", + pInfo->name, strerror(errno)); goto error; } - /* cache info */ - if (!compare) - { - strcpy(pEvdev->name, name); - memcpy(pEvdev->bitmask, bitmask, sizeof(bitmask)); - memcpy(pEvdev->key_bitmask, key_bitmask, sizeof(key_bitmask)); - memcpy(pEvdev->rel_bitmask, rel_bitmask, sizeof(rel_bitmask)); - memcpy(pEvdev->abs_bitmask, abs_bitmask, sizeof(abs_bitmask)); - memcpy(pEvdev->led_bitmask, led_bitmask, sizeof(led_bitmask)); - memcpy(pEvdev->absinfo, absinfo, sizeof(absinfo)); + if (compare) { + /* + * Keys are special as user can adjust keymap at any time (on + * devices that support EVIOCSKEYCODE. However we do not expect + * buttons reserved for mice/tablets/digitizers and so on to + * appear/disappear so we will check only those in + * [BTN_MISC, KEY_OK) range. + */ + size_t start_word = BTN_MISC / LONG_BITS; + size_t start_byte = start_word * sizeof(unsigned long); + size_t end_word = KEY_OK / LONG_BITS; + size_t end_byte = end_word * sizeof(unsigned long); + + if (len >= start_byte && + memcmp(&pEvdev->key_bitmask[start_word], &key_bitmask[start_word], + min(len, end_byte) - start_byte + 1)) { + xf86Msg(X_ERROR, "%s: device key_bitmask has changed\n", pInfo->name); + goto error; + } } + /* Copy the data so we have reasonably up-to-date info */ + memcpy(pEvdev->key_bitmask, key_bitmask, len); + return Success; error: -- cgit v1.2.3 From c1f16a4f59a584ab4546c2f16e20b06703042057 Mon Sep 17 00:00:00 2001 From: Bartosz Brachaczek Date: Fri, 13 Nov 2009 00:18:00 +1000 Subject: Set all valuators for relative motion events (#24737) We should process all the deltas reported by a relative motion device, otherwise some devices such as A4Tech X-750F or similar may trigger a situation when the `v` array contains random values (it isn't initialized anywhere) and later we process them and in effect the mouse cursor "jumps" on the screen. I'm not sure why, but we also must be sure that the `first` and `last` variables reflect the axis map, otherwise the mouse cursor "jumps" on the screen when clicking mouse buttons in some rare cases reported by Bartek Iwaniec on Bugzilla. That's why a simple initialization of the `v` array with zeros isn't sufficient. X.Org Bug 24737 Signed-off-by: Bartosz Brachaczek Signed-off-by: Peter Hutterer --- src/evdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/evdev.c') diff --git a/src/evdev.c b/src/evdev.c index 06ea83b..81a0bd5 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -375,7 +375,7 @@ EvdevProcessValuators(InputInfoPtr pInfo, int v[MAX_VALUATORS], int *num_v, for (i = 0; i < REL_CNT; i++) { int map = pEvdev->axis_map[i]; - if (pEvdev->delta[i] && map != -1) + if (map != -1) { v[map] = pEvdev->delta[i]; if (map < first) -- cgit v1.2.3 From f187badb71554a73bf9ca30ce75c9d166e688f03 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 1 Dec 2009 00:12:36 +0000 Subject: Swap axes before applying touch screen calibration. When the SwapAxes option is set, the X and Y axes in calibration should be labelled as the user perceives them -- not as the kernel sends them. Currently, we apply the X-axis calibration to the X-axis of the input, and then do the axis swapping so we've actually applied the X-axis calibration to what the user sees as the Y-axis. This patch changes the order of the operations, so that the axes are swapped before the calibration is applied. Signed-off-by: David Woodhouse Acked-by: Peter Hutterer Signed-off-by: Peter Hutterer --- src/evdev.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/evdev.c') diff --git a/src/evdev.c b/src/evdev.c index 81a0bd5..f4b2b2e 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -399,6 +399,13 @@ EvdevProcessValuators(InputInfoPtr pInfo, int v[MAX_VALUATORS], int *num_v, */ else if (pEvdev->abs && pEvdev->tool) { memcpy(v, pEvdev->vals, sizeof(int) * pEvdev->num_vals); + + if (pEvdev->swap_axes) { + int tmp = v[0]; + v[0] = v[1]; + v[1] = tmp; + } + if (pEvdev->flags & EVDEV_CALIBRATED) { v[0] = xf86ScaleAxis(v[0], @@ -411,12 +418,6 @@ EvdevProcessValuators(InputInfoPtr pInfo, int v[MAX_VALUATORS], int *num_v, pEvdev->calibration.max_y, pEvdev->calibration.min_y); } - if (pEvdev->swap_axes) { - int tmp = v[0]; - v[0] = v[1]; - v[1] = tmp; - } - if (pEvdev->invert_x) v[0] = (pEvdev->absinfo[ABS_X].maximum - v[0] + pEvdev->absinfo[ABS_X].minimum); -- cgit v1.2.3 From 7b285a802b8ccddd1edcf40ab345c4a96bcdf43c Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 1 Dec 2009 00:14:54 +0000 Subject: Report initial calibration parameters. Where an initial calibration is provided through the Calibration option to the driver, it wasn't being exposed in the 'Evdev Axis Calibration' property. Remedy that... Signed-off-by: David Woodhouse Acked-by: Peter Hutterer Signed-off-by: Peter Hutterer --- src/evdev.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'src/evdev.c') diff --git a/src/evdev.c b/src/evdev.c index f4b2b2e..afa9bc5 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -2413,8 +2413,22 @@ EvdevInitProperty(DeviceIntPtr dev) prop_calibration = MakeAtom(EVDEV_PROP_CALIBRATION, strlen(EVDEV_PROP_CALIBRATION), TRUE); - rc = XIChangeDeviceProperty(dev, prop_calibration, XA_INTEGER, 32, - PropModeReplace, 0, NULL, FALSE); + if (pEvdev->flags & EVDEV_CALIBRATED) { + int calibration[4]; + + calibration[0] = pEvdev->calibration.min_x; + calibration[1] = pEvdev->calibration.max_x; + calibration[2] = pEvdev->calibration.min_y; + calibration[3] = pEvdev->calibration.max_y; + + rc = XIChangeDeviceProperty(dev, prop_calibration, XA_INTEGER, + 32, PropModeReplace, 4, calibration, + FALSE); + } else { + rc = XIChangeDeviceProperty(dev, prop_calibration, XA_INTEGER, + 32, PropModeReplace, 0, NULL, + FALSE); + } if (rc != Success) return; -- cgit v1.2.3 From 2ca24a16f08095f35d5610f16e202c525b3075e9 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 1 Dec 2009 14:16:10 +1000 Subject: Only init the calibration property for absolute devices. Relative devices can't be calibrated anyway so why bother. Signed-off-by: Peter Hutterer --- src/evdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/evdev.c') diff --git a/src/evdev.c b/src/evdev.c index afa9bc5..85503bf 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -2424,7 +2424,7 @@ EvdevInitProperty(DeviceIntPtr dev) rc = XIChangeDeviceProperty(dev, prop_calibration, XA_INTEGER, 32, PropModeReplace, 4, calibration, FALSE); - } else { + } else if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS) { rc = XIChangeDeviceProperty(dev, prop_calibration, XA_INTEGER, 32, PropModeReplace, 0, NULL, FALSE); -- cgit v1.2.3 From 1b0df04abe329433658c95debdafdf1714173814 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 1 Dec 2009 15:44:39 +1000 Subject: Fix up BTN_TOUCH handling for non-button tablets. BTN_TOOL_* is treated as tool, just like before. BTN_TOUCH on the other hand may need to be treated as a button left press. This again requires a button class. Tested on an HP Touchsmart and a Wacom tablet. Signed-off-by: Peter Hutterer --- src/evdev.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/evdev.c') diff --git a/src/evdev.c b/src/evdev.c index 85503bf..17c0f01 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -552,7 +552,6 @@ EvdevProcessKeyEvent(InputInfoPtr pInfo, struct input_event *ev) return; switch (ev->code) { - case BTN_TOUCH: case BTN_TOOL_PEN: case BTN_TOOL_RUBBER: case BTN_TOOL_BRUSH: @@ -562,7 +561,11 @@ EvdevProcessKeyEvent(InputInfoPtr pInfo, struct input_event *ev) case BTN_TOOL_MOUSE: case BTN_TOOL_LENS: pEvdev->tool = value ? ev->code : 0; - if (!(pEvdev->flags & EVDEV_TOUCHSCREEN)) + break; + + case BTN_TOUCH: + pEvdev->tool = value ? ev->code : 0; + if (!(pEvdev->flags & (EVDEV_TOUCHSCREEN | EVDEV_TABLET))) break; /* Treat BTN_TOUCH from devices that only have BTN_TOUCH as * BTN_LEFT. */ @@ -1844,6 +1847,11 @@ EvdevProbe(InputInfoPtr pInfo) { xf86Msg(X_INFO, "%s: Found absolute tablet.\n", pInfo->name); pEvdev->flags |= EVDEV_TABLET; + if (!pEvdev->num_buttons) + { + pEvdev->num_buttons = 7; /* LMR + scroll wheels */ + pEvdev->flags |= EVDEV_BUTTON_EVENTS; + } } else if (TestBit(ABS_PRESSURE, pEvdev->abs_bitmask) || TestBit(BTN_TOUCH, pEvdev->key_bitmask)) { if (num_buttons || TestBit(BTN_TOOL_FINGER, pEvdev->key_bitmask)) { -- cgit v1.2.3 From 2f5a0fb6988809a91c4e6821aaed46ba27c9855c Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sat, 5 Dec 2009 02:08:32 -0800 Subject: removed unnecessary static declarations Signed-off-by: Dima Kogan Signed-off-by: Peter Hutterer --- src/evdev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/evdev.c') diff --git a/src/evdev.c b/src/evdev.c index 17c0f01..9345d96 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -467,7 +467,7 @@ EvdevProcessButtonEvent(InputInfoPtr pInfo, struct input_event *ev) static void EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev) { - static int value; + int value; EvdevPtr pEvdev = pInfo->private; /* Get the signed value, earlier kernels had this as unsigned */ @@ -512,7 +512,7 @@ EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev) static void EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev) { - static int value; + int value; EvdevPtr pEvdev = pInfo->private; /* Get the signed value, earlier kernels had this as unsigned */ @@ -540,7 +540,7 @@ EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev) static void EvdevProcessKeyEvent(InputInfoPtr pInfo, struct input_event *ev) { - static int value; + int value; EvdevPtr pEvdev = pInfo->private; /* Get the signed value, earlier kernels had this as unsigned */ -- cgit v1.2.3 From d6beb16be26df65cd65eaeb146fde0d355521535 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sat, 5 Dec 2009 02:05:19 -0800 Subject: allow wheel emulation to work with absolute-position devices Signed-off-by: Dima Kogan Signed-off-by: Peter Hutterer --- src/evdev.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/evdev.c') diff --git a/src/evdev.c b/src/evdev.c index 9345d96..7e65c69 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -525,6 +525,9 @@ EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev) if (ev->code > ABS_MAX) return; + if (EvdevWheelEmuFilterMotion(pInfo, ev)) + return; + pEvdev->vals[pEvdev->axis_map[ev->code]] = value; if (ev->code == ABS_X) pEvdev->abs |= ABS_X_VALUE; -- cgit v1.2.3 From e81cd935cfff18d3c387eed3e8083977c19c92f0 Mon Sep 17 00:00:00 2001 From: Andrej Gelenberg Date: Tue, 12 Jan 2010 11:22:16 +0100 Subject: Implement XSetDeviceMode request handler Implement XSetDeviceMode request handler for evdev. Devices with absolute axes can be switched in relative mode or absolute mode. Devices with relative axes can be switched only in relative mode. Other devices return BadMatch, cause they have no valuators and don't report motion events. New option "Mode" force devices with absolute axes to work in relative or absolute mode. Need xinputproto. Signed-off-by: Andrej Gelenberg --- src/evdev.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) (limited to 'src/evdev.c') diff --git a/src/evdev.c b/src/evdev.c index 7e65c69..58ffcea 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -32,6 +32,7 @@ #endif #include +#include #include #include @@ -92,6 +93,7 @@ #define EVDEV_TABLET (1 << 8) /* device looks like a tablet? */ #define EVDEV_UNIGNORE_ABSOLUTE (1 << 9) /* explicitly unignore abs axes */ #define EVDEV_UNIGNORE_RELATIVE (1 << 10) /* explicitly unignore rel axes */ +#define EVDEV_RELATIVE_MODE (1 << 11) /* Force relative events for devices with absolute axes */ #define MIN_KEYCODE 8 #define GLYPHS_PER_KEY 2 @@ -117,6 +119,7 @@ static const char *evdevDefaults[] = { static int EvdevOn(DeviceIntPtr); static int EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare); static void EvdevKbdCtrl(DeviceIntPtr device, KeybdCtrl *ctrl); +static int EvdevSwitchMode(ClientPtr client, DeviceIntPtr device, int mode); #ifdef HAVE_PROPERTIES static void EvdevInitAxesLabels(EvdevPtr pEvdev, int natoms, Atom *atoms); @@ -136,6 +139,38 @@ static Atom prop_btn_label = 0; * cannot be used by evdev, leaving us with a space of 2 at the end. */ static EvdevPtr evdev_devices[MAXDEVICES] = {NULL}; +static int EvdevSwitchMode(ClientPtr client, DeviceIntPtr device, int mode) +{ + InputInfoPtr pInfo; + EvdevPtr pEvdev; + + pInfo = device->public.devicePrivate; + pEvdev = pInfo->private; + + if (pEvdev->flags & EVDEV_RELATIVE_EVENTS) + { + if (mode == Relative) + return Success; + else + return XI_BadMode; + } + + switch (mode) { + case Absolute: + pEvdev->flags &= ~EVDEV_RELATIVE_MODE; + break; + + case Relative: + pEvdev->flags |= EVDEV_RELATIVE_MODE; + break; + + default: + return XI_BadMode; + } + + return Success; +} + static size_t CountBits(unsigned long *array, size_t nlongs) { unsigned int i; @@ -341,7 +376,7 @@ EvdevProcessValuators(InputInfoPtr pInfo, int v[MAX_VALUATORS], int *num_v, *num_v = *first_v = 0; /* convert to relative motion for touchpads */ - if (pEvdev->abs && (pEvdev->flags & EVDEV_TOUCHPAD)) { + if (pEvdev->abs && (pEvdev->flags & EVDEV_RELATIVE_MODE)) { if (pEvdev->tool) { /* meaning, touch is active */ if (pEvdev->old_vals[0] != -1) pEvdev->delta[REL_X] = pEvdev->vals[0] - pEvdev->old_vals[0]; @@ -1129,6 +1164,7 @@ EvdevAddAbsClass(DeviceIntPtr device) EvdevPtr pEvdev; int num_axes, axis, i = 0; Atom *atoms; + const char *mode; pInfo = device->public.devicePrivate; pEvdev = pInfo->private; @@ -1200,6 +1236,22 @@ EvdevAddAbsClass(DeviceIntPtr device) TestBit(ABS_TILT_Y, pEvdev->abs_bitmask))) pInfo->flags |= XI86_POINTER_CAPABLE; + if (pEvdev->flags & EVDEV_TOUCHPAD) + pEvdev->flags |= EVDEV_RELATIVE_MODE; + else + pEvdev->flags &= ~EVDEV_RELATIVE_MODE; + + if (xf86FindOption(pInfo->options, "Mode")) + { + mode = xf86SetStrOption(pInfo->options, "Mode", NULL); + if (!strcasecmp("absolute", mode)) + pEvdev->flags &= ~EVDEV_RELATIVE_MODE; + else if (!strcasecmp("relative", mode)) + pEvdev->flags |= EVDEV_RELATIVE_MODE; + else + xf86Msg(X_INFO, "%s: unknown mode, use default\n", pInfo->name); + } + return Success; } @@ -1966,7 +2018,7 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags) pInfo->history_size = 0; pInfo->control_proc = NULL; pInfo->close_proc = NULL; - pInfo->switch_mode = NULL; + pInfo->switch_mode = EvdevSwitchMode; pInfo->conversion_proc = NULL; pInfo->reverse_conversion_proc = NULL; pInfo->dev = NULL; -- cgit v1.2.3 From 801778c3106fc7e409369b4500253a38be6a5795 Mon Sep 17 00:00:00 2001 From: Oliver McFadden Date: Thu, 25 Feb 2010 07:11:21 +0200 Subject: emuMB: default to disabled mouse button emulation for touchscreens. Because touchscreens only use one button (see EvdevProcessKeyEvent()) EvdevMBEmuFilterEvent() never calls EvdevMBEmuEnable(..., FALSE) to disable emulation. This results in touchscreen devices incurring a delay of Emulate3Timeout (typically 50 ms.) Default to MBEMU_DISABLED for touchscreen devices (unless overwritten by Xorg.conf.) Signed-off-by: Oliver McFadden Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- src/evdev.c | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'src/evdev.c') diff --git a/src/evdev.c b/src/evdev.c index 58ffcea..3051462 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -81,20 +81,6 @@ #define ArrayLength(a) (sizeof(a) / (sizeof((a)[0]))) -/* evdev flags */ -#define EVDEV_KEYBOARD_EVENTS (1 << 0) -#define EVDEV_BUTTON_EVENTS (1 << 1) -#define EVDEV_RELATIVE_EVENTS (1 << 2) -#define EVDEV_ABSOLUTE_EVENTS (1 << 3) -#define EVDEV_TOUCHPAD (1 << 4) -#define EVDEV_INITIALIZED (1 << 5) /* WheelInit etc. called already? */ -#define EVDEV_TOUCHSCREEN (1 << 6) -#define EVDEV_CALIBRATED (1 << 7) /* run-time calibrated? */ -#define EVDEV_TABLET (1 << 8) /* device looks like a tablet? */ -#define EVDEV_UNIGNORE_ABSOLUTE (1 << 9) /* explicitly unignore abs axes */ -#define EVDEV_UNIGNORE_RELATIVE (1 << 10) /* explicitly unignore rel axes */ -#define EVDEV_RELATIVE_MODE (1 << 11) /* Force relative events for devices with absolute axes */ - #define MIN_KEYCODE 8 #define GLYPHS_PER_KEY 2 #define AltMask Mod1Mask -- cgit v1.2.3 From d525b48a2ffeeb63fd248e21324e33156ed61ed0 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 15 Mar 2010 11:08:05 +1000 Subject: When labeling a device as touchpad, only check for LMR buttons. Touchpads that have physical buttons have either LMR or BTN_TOOL_FINGER. Other buttons in the range evdev recognises shouldn't be taken into account here - they skew the detection towards touchpads and away from touchscreens. Fedora Bug 571639 Signed-off-by: Peter Hutterer Reviewed-by: Simon Thum --- src/evdev.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/evdev.c') diff --git a/src/evdev.c b/src/evdev.c index 3051462..b532639 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -1767,6 +1767,7 @@ static int EvdevProbe(InputInfoPtr pInfo) { int i, has_rel_axes, has_abs_axes, has_keys, num_buttons, has_scroll; + int has_lmr; /* left middle right */ int kernel24 = 0; int ignore_abs = 0, ignore_rel = 0; EvdevPtr pEvdev = pInfo->private; @@ -1809,6 +1810,7 @@ EvdevProbe(InputInfoPtr pInfo) has_abs_axes = FALSE; has_keys = FALSE; has_scroll = FALSE; + has_lmr = FALSE; num_buttons = 0; /* count all buttons */ @@ -1823,6 +1825,10 @@ EvdevProbe(InputInfoPtr pInfo) } } + has_lmr = TestBit(BTN_LEFT, pEvdev->key_bitmask) || + TestBit(BTN_MIDDLE, pEvdev->key_bitmask) || + TestBit(BTN_RIGHT, pEvdev->key_bitmask); + if (num_buttons) { pEvdev->flags |= EVDEV_BUTTON_EVENTS; @@ -1895,7 +1901,7 @@ EvdevProbe(InputInfoPtr pInfo) } } else if (TestBit(ABS_PRESSURE, pEvdev->abs_bitmask) || TestBit(BTN_TOUCH, pEvdev->key_bitmask)) { - if (num_buttons || TestBit(BTN_TOOL_FINGER, pEvdev->key_bitmask)) { + if (has_lmr || TestBit(BTN_TOOL_FINGER, pEvdev->key_bitmask)) { xf86Msg(X_INFO, "%s: Found absolute touchpad.\n", pInfo->name); pEvdev->flags |= EVDEV_TOUCHPAD; memset(pEvdev->old_vals, -1, sizeof(int) * pEvdev->num_vals); -- cgit v1.2.3 From 0dc931e1acee6ea3afd032be887f85ce1121f325 Mon Sep 17 00:00:00 2001 From: Simon Thum Date: Tue, 16 Mar 2010 16:00:21 +0100 Subject: move feedback initialization up This allows the backend to propery initialize the feedback from options, as it works with most other drivers. This is the hacky equivalent of fixing the initialization of pointer acceleration, which would require changes to most drivers however. Signed-off-by: Simon Thum Signed-off-by: Peter Hutterer --- src/evdev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/evdev.c') diff --git a/src/evdev.c b/src/evdev.c index b532639..66b746a 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -1299,6 +1299,9 @@ EvdevAddRelClass(DeviceIntPtr device) GetMotionHistorySize(), Relative)) return !Success; + if (!InitPtrFeedbackClassDeviceStruct(device, EvdevPtrCtrlProc)) + return !Success; + for (axis = REL_X; axis <= REL_MAX; axis++) { int axnum = pEvdev->axis_map[axis]; @@ -1315,9 +1318,6 @@ EvdevAddRelClass(DeviceIntPtr device) xfree(atoms); - if (!InitPtrFeedbackClassDeviceStruct(device, EvdevPtrCtrlProc)) - return !Success; - pInfo->flags |= XI86_POINTER_CAPABLE; return Success; -- cgit v1.2.3