From 687afa3f6475060e6c460aa9496ba1a6a7982102 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 31 Jan 2014 15:21:38 +0100 Subject: [PATCH] systemd-logind: Add delayed input device probing With systemd-logind we cannot probe input devices while switched away, so if we're switched away, put the pInfo on a list, and probe everything on that list on VT-Enter. This is using an array grown by re-alloc, rather than a xorg_list since creating a new data-type to store a pInfo + list-entry just for this seems overkill. Signed-off-by: Hans de Goede Reviewed-by: Peter Hutterer --- hw/xfree86/common/xf86Xinput.c | 49 ++++++++++++++++++-- hw/xfree86/common/xf86Xinput.h | 1 + hw/xfree86/os-support/linux/systemd-logind.c | 3 ++ 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c index 9d6b3ca04..7c3e479e5 100644 --- a/hw/xfree86/common/xf86Xinput.c +++ b/hw/xfree86/common/xf86Xinput.c @@ -105,6 +105,9 @@ static int xf86InputDevicePostInit(DeviceIntPtr dev); +static InputInfoPtr *new_input_devices; +static int new_input_devices_count; + /** * Eval config and modify DeviceVelocityRec accordingly */ @@ -839,10 +842,20 @@ xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable) } if (drv->capabilities & XI86_DRV_CAP_SERVER_FD) { - pInfo->fd = systemd_logind_take_fd(pInfo->major, pInfo->minor, - pInfo->attrs->device, &paused); - if (pInfo->fd != -1) { - /* FIXME handle paused */ + int fd = systemd_logind_take_fd(pInfo->major, pInfo->minor, + pInfo->attrs->device, &paused); + if (fd != -1) { + if (paused) { + /* Put on new_input_devices list for delayed probe */ + new_input_devices = xnfrealloc(new_input_devices, + sizeof(pInfo) * (new_input_devices_count + 1)); + new_input_devices[new_input_devices_count] = pInfo; + new_input_devices_count++; + systemd_logind_release_fd(pInfo->major, pInfo->minor); + close(fd); + return BadMatch; + } + pInfo->fd = fd; pInfo->flags |= XI86_SERVER_FD; pInfo->options = xf86ReplaceIntOption(pInfo->options, "fd", fd); } @@ -1493,4 +1506,32 @@ xf86PostTouchEvent(DeviceIntPtr dev, uint32_t touchid, uint16_t type, QueueTouchEvents(dev, type, touchid, flags, mask); } +void +xf86InputEnableVTProbe(void) +{ + int i, is_auto = 0; + InputOption *option = NULL; + DeviceIntPtr pdev; + + for (i = 0; i < new_input_devices_count; i++) { + InputInfoPtr pInfo = new_input_devices[i]; + + is_auto = 0; + nt_list_for_each_entry(option, pInfo->options, list.next) { + const char *key = input_option_get_key(option); + const char *value = input_option_get_value(option); + + if (strcmp(key, "_source") == 0 && + (strcmp(value, "server/hal") == 0 || + strcmp(value, "server/udev") == 0 || + strcmp(value, "server/wscons") == 0)) + is_auto = 1; + } + xf86NewInputDevice(pInfo, &pdev, + (!is_auto || + (is_auto && xf86Info.autoEnableDevices))); + } + new_input_devices_count = 0; +} + /* end of xf86Xinput.c */ diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h index 784e14e5c..9fe8c87b6 100644 --- a/hw/xfree86/common/xf86Xinput.h +++ b/hw/xfree86/common/xf86Xinput.h @@ -179,6 +179,7 @@ extern _X_EXPORT void xf86AddEnabledDevice(InputInfoPtr pInfo); extern _X_EXPORT void xf86RemoveEnabledDevice(InputInfoPtr pInfo); extern _X_EXPORT void xf86DisableDevice(DeviceIntPtr dev, Bool panic); extern _X_EXPORT void xf86EnableDevice(DeviceIntPtr dev); +extern _X_EXPORT void xf86InputEnableVTProbe(void); /* not exported */ int xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL is_auto); diff --git a/hw/xfree86/os-support/linux/systemd-logind.c b/hw/xfree86/os-support/linux/systemd-logind.c index 4732c0832..abb8e44d9 100644 --- a/hw/xfree86/os-support/linux/systemd-logind.c +++ b/hw/xfree86/os-support/linux/systemd-logind.c @@ -198,6 +198,9 @@ systemd_logind_vtenter(void) for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next) if ((pInfo->flags & XI86_SERVER_FD) && pInfo->fd != -1) xf86EnableInputDeviceForVTSwitch(pInfo); + + /* Do delayed input probing, this must be done after the above enabling */ + xf86InputEnableVTProbe(); } static InputInfoPtr