[PATCH/RFC evdev] Use a new "Virtual Device" boolean property to mark virtual devices

Peter Hutterer peter.hutterer at who-t.net
Mon Oct 24 17:05:33 PDT 2011


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 at who-t.net>
---
The server's XTest devices should have the same property and the property
should also be added to xserver-properties.h. 

https://bugzilla.gnome.org/show_bug.cgi?id=337367

Cheers,
  Peter

 configure.ac |    1 +
 src/evdev.c  |   52 ++++++++++++++++++++++++++++++++++++++++++-
 src/udev.c   |   70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 122 insertions(+), 1 deletions(-)
 create mode 100644 src/udev.c

diff --git a/configure.ac b/configure.ac
index 3b422d4..c930f63 100644
--- a/configure.ac
+++ b/configure.ac
@@ -46,6 +46,7 @@ XORG_DEFAULT_OPTIONS
 
 # Obtain compiler/linker options from server and required extensions
 PKG_CHECK_MODULES(XORG, [xorg-server >= 1.10] xproto inputproto)
+PKG_CHECK_MODULES(UDEV, udev)
 
 # Define a configure option for an alternate input module directory
 AC_ARG_WITH(xorg-module-dir,
diff --git a/src/evdev.c b/src/evdev.c
index f99e0d5..a25ff7d 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,38 @@ 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;
+}
 static int wheel_up_button = 4;
 static int wheel_down_button = 5;
 static int wheel_left_button = 6;
@@ -2302,6 +2340,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))
@@ -2411,7 +2460,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;
diff --git a/src/udev.c b/src/udev.c
new file mode 100644
index 0000000..8ba94b1
--- /dev/null
+++ b/src/udev.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright © 2011 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Red Hat
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.  Red
+ * Hat makes no representations about the suitability of this software
+ * for any purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ *	Peter Hutterer (peter.hutterer at redhat.com)
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "evdev.h"
+
+#include <libudev.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+Bool
+udev_device_is_virtual(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;
+}
+
-- 
1.7.7



More information about the xorg-devel mailing list