summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Nicholson <dbn.lists@gmail.com>2010-06-07 20:39:53 -0700
committerPeter Hutterer <peter.hutterer@who-t.net>2010-06-10 14:36:36 +1000
commitd1b4beecbc16448282dcc825dd5c354e96e48eca (patch)
tree4db748a8919b167faa4c24844834a0f7910c4797
parent9b30fa9f8fedb7ddb5672f93ed1a154d13578c47 (diff)
xfree86: Add MatchOS InputClass entry for operating system matching
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@gmail.com> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--configure.ac2
-rw-r--r--hw/xfree86/common/xf86Xinput.c32
-rw-r--r--hw/xfree86/doc/man/xorg.conf.man.pre9
-rw-r--r--hw/xfree86/parser/InputClass.c19
-rw-r--r--hw/xfree86/parser/xf86Parser.h1
-rw-r--r--hw/xfree86/parser/xf86tokens.h1
-rw-r--r--include/dix-config.h.in3
7 files changed, 66 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index c8b49debb..81b6e4c1c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -123,7 +123,7 @@ 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 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 58e09cc83..0f6ccc1ab 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,31 @@ 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') {
+ if (uname(&name) >= 0)
+ strcpy(host_os, name.sysname);
+ else {
+ strncpy(host_os, "unknown", sizeof(host_os));
+ host_os[sizeof(host_os)-1] = '\0';
+ }
+ }
+ return host_os;
+#else
+ return "";
+#endif
+}
+
static int
match_substring(const char *attr, const char *pattern)
{
@@ -558,6 +586,10 @@ InputClassMatches(const XF86ConfInputClassPtr iclass,
if (!MatchAttrToken(attrs->device, iclass->match_device, match_path_pattern))
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 9075db64f..50d4f3624 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 7fb2866cd..20ebfb503 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");
@@ -217,6 +223,14 @@ xf86printInputClassSection (FILE * cf, XF86ConfInputClassPtr ptr)
*list);
fprintf(cf, "\"\n");
}
+ if (ptr->match_os) {
+ fprintf(cf, "\tMatchOS \"");
+ for (list = ptr->match_os; *list; list++)
+ fprintf(cf, "%s%s",
+ list == ptr->match_os ? "" : TOKEN_SEP,
+ *list);
+ fprintf(cf, "\"\n");
+ }
if (ptr->match_tag) {
fprintf(cf, "\tMatchTag \"");
for (list = ptr->match_tag; *list; list++)
@@ -273,6 +287,11 @@ xf86freeInputClassList (XF86ConfInputClassPtr ptr)
free(*list);
free(ptr->match_device);
}
+ if (ptr->match_os) {
+ for (list = ptr->match_os; *list; list++)
+ free(*list);
+ free(ptr->match_os);
+ }
if (ptr->match_tag) {
for (list = ptr->match_tag; *list; list++)
free(*list);
diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
index d79544a20..3623ca16d 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 cb600704b..fd13d6d95 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 7759aac6a..6a332642b 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