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 <hdegoede@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Hans de Goede 2014-01-31 15:21:38 +01:00
parent cac3921989
commit 687afa3f64
3 changed files with 49 additions and 4 deletions

View File

@ -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 */

View File

@ -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);

View File

@ -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