[PATCH 07/11] xfree86: Add MatchOS InputClass entry for operating system matching

Dan Nicholson dbn.lists at gmail.com
Thu May 20 07:09:09 PDT 2010


Allow InputClass sections to match against the running operating system
to narrow the application of rules. An example where this could be used
is to specify that the default input driver on Linux is evdev while it's
mouse/kbd everywhere else.

The operating system name is the same as `uname -s`, and matching is
case-insensitive.

Signed-off-by: Dan Nicholson <dbn.lists at gmail.com>
---
 configure.ac                         |    3 ++-
 hw/xfree86/common/xf86Xinput.c       |   26 ++++++++++++++++++++++++++
 hw/xfree86/doc/man/xorg.conf.man.pre |    9 +++++++++
 hw/xfree86/parser/InputClass.c       |    6 ++++++
 hw/xfree86/parser/xf86Parser.h       |    1 +
 hw/xfree86/parser/xf86tokens.h       |    1 +
 include/dix-config.h.in              |    3 +++
 7 files changed, 48 insertions(+), 1 deletions(-)

diff --git a/configure.ac b/configure.ac
index 1c7875e..86c3991 100644
--- a/configure.ac
+++ b/configure.ac
@@ -123,7 +123,8 @@ AM_CONDITIONAL(SPECIAL_DTRACE_OBJECTS, [test "x$SPECIAL_DTRACE_OBJECTS" = "xyes"
 
 AC_HEADER_DIRENT
 AC_HEADER_STDC
-AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h dlfcn.h stropts.h fnmatch.h])
+AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h dlfcn.h stropts.h]dnl
+	[fnmatch.h sys/utsname.h])
 
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index d72150b..2396e33 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -80,6 +80,9 @@
 #ifdef HAVE_FNMATCH_H
 #include <fnmatch.h>
 #endif
+#ifdef HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>
+#endif
 
 #include "extnsionst.h"
 
@@ -496,6 +499,25 @@ AddOtherInputDevices(void)
 {
 }
 
+/*
+ * Get the operating system name from uname and store it statically to avoid
+ * repeating the system call each time MatchOS is checked.
+ */
+static const char *
+HostOS(void)
+{
+#ifdef HAVE_SYS_UTSNAME_H
+    struct utsname name;
+    static char host_os[sizeof(name.sysname)] = "";
+
+    if (*host_os == '\0' && uname(&name) >= 0)
+        strcpy(host_os, name.sysname);
+    return host_os;
+#else
+    return "";
+#endif
+}
+
 static int
 MatchSubstring(const char *attr, const char *pattern)
 {
@@ -561,6 +583,10 @@ InputClassMatches(XF86ConfInputClassPtr iclass, InputAttributes *attrs)
     if (!MatchAttrToken(attrs->device, iclass->match_device, MatchPathPattern))
         return FALSE;
 
+    /* MatchOS case-insensitive string */
+    if (!MatchAttrToken(HostOS(), iclass->match_os, strcasecmp))
+        return FALSE;
+
     /*
      * MatchTag string
      * See if any of the device's tags match any of the MatchTag tokens.
diff --git a/hw/xfree86/doc/man/xorg.conf.man.pre b/hw/xfree86/doc/man/xorg.conf.man.pre
index f7ff6f6..7b66b7e 100644
--- a/hw/xfree86/doc/man/xorg.conf.man.pre
+++ b/hw/xfree86/doc/man/xorg.conf.man.pre
@@ -1086,6 +1086,15 @@ This entry can be used to check if the device file matches the
 pathname pattern. Multiple patterns can be matched by separating arguments
 with a '|' character.
 .TP 7
+.BI "MatchOS \*q" matchos \*q
+This entry can be used to check if the operating system matches the
+case-insensitive
+.RI \*q matchos \*q
+string. This entry is only supported on platforms providing the
+.BR uname (2)
+system call. Multiple operating systems can be matched by separating arguments
+with a '|' character.
+.TP 7
 .BI "MatchTag \*q" matchtag \*q
 This entry can be used to check if tags assigned by the config backend
 matches the
diff --git a/hw/xfree86/parser/InputClass.c b/hw/xfree86/parser/InputClass.c
index 7fb2866..0332c31 100644
--- a/hw/xfree86/parser/InputClass.c
+++ b/hw/xfree86/parser/InputClass.c
@@ -47,6 +47,7 @@ xf86ConfigSymTabRec InputClassTab[] =
     {MATCH_PRODUCT, "matchproduct"},
     {MATCH_VENDOR, "matchvendor"},
     {MATCH_DEVICE_PATH, "matchdevicepath"},
+    {MATCH_OS, "matchos"},
     {MATCH_TAG, "matchtag"},
     {MATCH_IS_KEYBOARD, "matchiskeyboard"},
     {MATCH_IS_POINTER, "matchispointer"},
@@ -108,6 +109,11 @@ xf86parseInputClassSection(void)
                 Error(QUOTE_MSG, "MatchDevicePath");
             ptr->match_device = xstrtokenize(val.str, TOKEN_SEP);
             break;
+        case MATCH_OS:
+            if (xf86getSubToken(&(ptr->comment)) != STRING)
+                Error(QUOTE_MSG, "MatchOS");
+            ptr->match_os = xstrtokenize(val.str, TOKEN_SEP);
+            break;
         case MATCH_TAG:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchTag");
diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
index d79544a..3623ca1 100644
--- a/hw/xfree86/parser/xf86Parser.h
+++ b/hw/xfree86/parser/xf86Parser.h
@@ -346,6 +346,7 @@ typedef struct
 	char **match_product;
 	char **match_vendor;
 	char **match_device;
+	char **match_os;
 	char **match_tag;
 	xf86TriState is_keyboard;
 	xf86TriState is_pointer;
diff --git a/hw/xfree86/parser/xf86tokens.h b/hw/xfree86/parser/xf86tokens.h
index cb60070..fd13d6d 100644
--- a/hw/xfree86/parser/xf86tokens.h
+++ b/hw/xfree86/parser/xf86tokens.h
@@ -279,6 +279,7 @@ typedef enum {
     MATCH_PRODUCT,
     MATCH_VENDOR,
     MATCH_DEVICE_PATH,
+    MATCH_OS,
     MATCH_TAG,
     MATCH_IS_KEYBOARD,
     MATCH_IS_POINTER,
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 7759aac..6a33264 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -222,6 +222,9 @@
 /* Define to 1 if you have the <sys/types.h> header file. */
 #undef HAVE_SYS_TYPES_H
 
+/* Define to 1 if you have the <sys/utsname.h> header file. */
+#undef HAVE_SYS_UTSNAME_H
+
 /* Define to 1 if you have the <sys/vm86.h> header file. */
 #undef HAVE_SYS_VM86_H
 
-- 
1.6.6.1



More information about the xorg-devel mailing list