diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2011-10-25 09:59:50 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2011-11-11 15:42:31 +1000 |
commit | 683a55e504f4fc2d1c847c54986439a0c61b2f20 (patch) | |
tree | 90738a5c7c402e1e1ab7c847efdb4dda28f11525 /src/evdev.c | |
parent | a9cdb6590cdf72917cdfeb17e2fcc6a110b2c7d1 (diff) |
Use a new "Virtual Device" boolean property to mark virtual devices
Use udev to check for the device's sysfs path, if it contains LNXSYSTM it's
a kernel-emulated device. This property can then be used to determine if
there are any real devices connected, allowing the desktop environment to
e.g. turn off the touchpad whenever there's a mouse attached.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'src/evdev.c')
-rw-r--r-- | src/evdev.c | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/src/evdev.c b/src/evdev.c index 428d3c1..5e65e35 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -38,6 +38,7 @@ #include <linux/version.h> #include <sys/stat.h> +#include <libudev.h> #include <unistd.h> #include <errno.h> #include <fcntl.h> @@ -56,6 +57,10 @@ #define XI_PROP_PRODUCT_ID "Device Product ID" #endif +#ifndef XI_PROP_VIRTUAL_DEVICE +#define XI_PROP_VIRTUAL_DEVICE "Virtual Device" +#endif + /* removed from server, purge when dropping support for server 1.10 */ #define XI86_SEND_DRAG_EVENTS 0x08 @@ -119,6 +124,7 @@ static Atom prop_swap; static Atom prop_axis_label; static Atom prop_btn_label; static Atom prop_device; +static Atom prop_virtual; /* All devices the evdev driver has allocated and knows about. * MAXDEVICES is safe as null-terminated array, as two devices (VCP and VCK) @@ -277,6 +283,39 @@ SetXkbOption(InputInfoPtr pInfo, char *name, char **option) } } +static BOOL +EvdevDeviceIsVirtual(const char* devicenode) +{ + struct udev *udev = NULL; + struct udev_device *device = NULL; + struct stat st; + int rc = FALSE; + const char *devpath; + + udev = udev_new(); + if (!udev) + goto out; + + stat(devicenode, &st); + device = udev_device_new_from_devnum(udev, 'c', st.st_rdev); + + if (!device) + goto out; + + + devpath = udev_device_get_devpath(device); + if (!devpath) + goto out; + + if (strstr(devpath, "LNXSYSTM")) + rc = TRUE; + +out: + udev_device_unref(device); + udev_unref(udev); + return rc; +} + #ifndef HAVE_SMOOTH_SCROLLING static int wheel_up_button = 4; static int wheel_down_button = 5; @@ -2317,6 +2356,17 @@ EvdevInitProperty(DeviceIntPtr dev) if (rc != Success) return; + if (EvdevDeviceIsVirtual(pEvdev->device)) + { + BOOL virtual = 1; + prop_virtual = MakeAtom(XI_PROP_VIRTUAL_DEVICE, + strlen(XI_PROP_VIRTUAL_DEVICE), TRUE); + rc = XIChangeDeviceProperty(dev, prop_virtual, XA_INTEGER, 8, + PropModeReplace, 1, &virtual, FALSE); + XISetDevicePropertyDeletable(dev, prop_virtual, FALSE); + } + + XISetDevicePropertyDeletable(dev, prop_device, FALSE); if (pEvdev->flags & (EVDEV_RELATIVE_EVENTS | EVDEV_ABSOLUTE_EVENTS)) @@ -2426,7 +2476,8 @@ EvdevSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, if (!checkonly) pEvdev->swap_axes = *((BOOL*)val->data); } else if (atom == prop_axis_label || atom == prop_btn_label || - atom == prop_product_id || atom == prop_device) + atom == prop_product_id || atom == prop_device || + atom == prop_virtual) return BadAccess; /* Read-only properties */ return Success; |