xserver: Branch 'master' - 4 commits

Keith Packard keithp at kemper.freedesktop.org
Wed Dec 30 09:43:46 PST 2009


 Xi/stubs.c                           |    3 
 config/dbus.c                        |    2 
 config/hal.c                         |   25 +++
 configure.ac                         |    2 
 hw/dmx/dmxinput.c                    |    3 
 hw/kdrive/src/kinput.c               |    3 
 hw/xfree86/common/xf86Module.h       |    2 
 hw/xfree86/common/xf86Option.c       |   25 ---
 hw/xfree86/common/xf86Xinput.c       |   96 ++++++++++++++
 hw/xfree86/doc/man/xorg.conf.man.pre |   96 ++++++++++++++
 hw/xfree86/parser/Configint.h        |    2 
 hw/xfree86/parser/InputClass.c       |  232 +++++++++++++++++++++++++++++++++++
 hw/xfree86/parser/Makefile.am        |    1 
 hw/xfree86/parser/configProcs.h      |    4 
 hw/xfree86/parser/read.c             |    8 +
 hw/xfree86/parser/scan.c             |   30 ++++
 hw/xfree86/parser/write.c            |    2 
 hw/xfree86/parser/xf86Parser.h       |   29 ++++
 hw/xfree86/parser/xf86tokens.h       |   13 +
 hw/xquartz/darwinXinput.c            |    3 
 include/dix-config.h.in              |    3 
 include/input.h                      |   16 ++
 22 files changed, 567 insertions(+), 33 deletions(-)

New commits:
commit 9fad8f06fb89ac2ae05bea0fa24cab3df7677297
Merge: 871bbe1... 42e8c92...
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Dec 30 09:28:19 2009 -0800

    Merge remote branch 'dbn/inputclass'

commit 42e8c9224e6c54655c45f87999d37d0d67b3f7f5
Author: Dan Nicholson <dbn.lists at gmail.com>
Date:   Fri Oct 2 06:29:28 2009 -0700

    xfree86: Introduce InputClass configuration
    
    Currently Xorg uses hal's fdi files to decide what configuration options
    are applied to automatically added input devices. This is sub-optimal
    since it requires users to use a new and different configuration store
    than xorg.conf.
    
    The InputClass section attempts to provide a system similar to hal where
    configuration can be applied to all devices with certain attributes. For
    now, devices can be matched to:
    
    * A substring of the product name via a MatchProduct entry
    * A substring of the vendir name via a MatchVendor entry
    * A pathname pattern of the device file via a MatchDevicePath entry
    * A device type via boolean entries for MatchIsKeyboard, MatchIsPointer,
      MatchIsJoystick, MatchIsTablet, MatchIsTouchpad and MatchIsTouchscreen
    
    See the INPUTCLASS section in xorg.conf(5) for more details.
    
    Signed-off-by: Dan Nicholson <dbn.lists at gmail.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/configure.ac b/configure.ac
index 723c1fd..d5cf96d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -122,7 +122,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])
+AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h dlfcn.h stropts.h fnmatch.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 11b7315..e0c7830 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -57,9 +57,11 @@
 #include <X11/Xatom.h>
 #include "xf86.h"
 #include "xf86Priv.h"
+#include "xf86Config.h"
 #include "xf86Xinput.h"
 #include "XIstubs.h"
 #include "xf86Optrec.h"
+#include "xf86Parser.h"
 #include "mipointer.h"
 #include "xf86InPriv.h"
 #include "compiler.h"
@@ -74,6 +76,11 @@
 #include "exglobals.h"
 #include "eventstr.h"
 
+#include <string.h>     /* InputClassMatches */
+#ifdef HAVE_FNMATCH_H
+#include <fnmatch.h>
+#endif
+
 #include "extnsionst.h"
 
 #include "windowstr.h"	/* screenIsSaved */
@@ -466,6 +473,85 @@ AddOtherInputDevices(void)
 {
 }
 
+/*
+ * Classes without any Match statements match all devices. Otherwise, all
+ * statements must match.
+ */
+static Bool
+InputClassMatches(XF86ConfInputClassPtr iclass, InputAttributes *attrs)
+{
+    if (iclass->match_product &&
+        (!attrs->product || !strstr(attrs->product, iclass->match_product)))
+        return False;
+    if (iclass->match_vendor &&
+        (!attrs->vendor || !strstr(attrs->vendor, iclass->match_vendor)))
+        return False;
+    if (iclass->match_device &&
+#ifdef HAVE_FNMATCH_H
+        (!attrs->device ||
+         fnmatch(iclass->match_device, attrs->device, 0) != 0))
+#else
+        (!attrs->device || !strstr(attrs->device, iclass->match_device)))
+#endif
+        return False;
+    if (iclass->is_keyboard.set &&
+        iclass->is_keyboard.val != !!(attrs->flags & ATTR_KEYBOARD))
+        return False;
+    if (iclass->is_pointer.set &&
+        iclass->is_pointer.val != !!(attrs->flags & ATTR_POINTER))
+        return False;
+    if (iclass->is_joystick.set &&
+        iclass->is_joystick.val != !!(attrs->flags & ATTR_JOYSTICK))
+        return False;
+    if (iclass->is_tablet.set &&
+        iclass->is_tablet.val != !!(attrs->flags & ATTR_TABLET))
+        return False;
+    if (iclass->is_touchpad.set &&
+        iclass->is_touchpad.val != !!(attrs->flags & ATTR_TOUCHPAD))
+        return False;
+    if (iclass->is_touchscreen.set &&
+        iclass->is_touchscreen.val != !!(attrs->flags & ATTR_TOUCHSCREEN))
+        return False;
+    return True;
+}
+
+/*
+ * Merge in any InputClass configurations. Each InputClass section can
+ * add to the original device configuration as well as any previous
+ * InputClass sections.
+ */
+static int
+MergeInputClasses(IDevPtr idev, InputAttributes *attrs)
+{
+    XF86ConfInputClassPtr cl;
+    XF86OptionPtr classopts;
+
+    for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) {
+        if (!InputClassMatches(cl, attrs))
+            continue;
+
+        xf86Msg(X_CONFIG, "%s: Applying InputClass \"%s\"\n",
+                idev->identifier, cl->identifier);
+        if (cl->driver && !idev->driver) {
+            idev->driver = xstrdup(cl->driver);
+            if (!idev->driver) {
+                xf86Msg(X_ERROR, "Could not allocate memory while merging "
+                        "InputClass configuration");
+                return BadAlloc;
+            }
+        }
+
+        classopts = xf86optionListDup(cl->option_lst);
+        if (idev->commonOptions)
+            idev->commonOptions = xf86optionListMerge(classopts,
+                                                      idev->commonOptions);
+        else
+            idev->commonOptions = classopts;
+    }
+
+    return Success;
+}
+
 /**
  * Create a new input device, activate and enable it.
  *
@@ -636,6 +722,13 @@ NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
         option->value = NULL;
     }
 
+    /* Apply InputClass settings */
+    if (attrs) {
+        rval = MergeInputClasses(idev, attrs);
+        if (rval != Success)
+            goto unwind;
+    }
+
     rval = xf86NewInputDevice(idev, pdev,
                 (!is_auto || (is_auto && xf86Info.autoEnableDevices)));
     if (rval == Success)
diff --git a/hw/xfree86/doc/man/xorg.conf.man.pre b/hw/xfree86/doc/man/xorg.conf.man.pre
index 84be12c..f276e9d 100644
--- a/hw/xfree86/doc/man/xorg.conf.man.pre
+++ b/hw/xfree86/doc/man/xorg.conf.man.pre
@@ -117,6 +117,7 @@ The section names are:
 .BR "Module         " "Dynamic module loading"
 .BR "Extensions     " "Extension enabling"
 .BR "InputDevice    " "Input device description"
+.BR "InputClass     " "Input class description"
 .BR "Device         " "Graphics device description"
 .BR "VideoAdaptor   " "Xv video adaptor description"
 .BR "Monitor        " "Monitor description"
@@ -882,6 +883,101 @@ may be reattached or set floating at runtime.
 .TP 7
 .BI "Option \*qSendDragEvents\*q  \*q" boolean \*q
 ???
+.SH "INPUTCLASS SECTION"
+The config file may have multiple
+.B InputClass
+sections.
+These sections are optional and are used to provide configuration for a
+class of input devices as they are automatically added. An input device can
+match more than one
+.B InputClass
+section. Each class can only supplement settings from a previous class, so
+it is best to arrange the sections with the most generic matches last.
+.PP
+.B InputClass
+sections have the following format:
+.PP
+.RS 4
+.nf
+.B  "Section \*qInputClass\*q"
+.BI "    Identifier  \*q" name \*q
+.I  "    entries"
+.I  "    ..."
+.I  "    options"
+.I  "    ..."
+.B  "EndSection"
+.fi
+.RE
+.PP
+The
+.B Identifier
+entry is required in all
+.B InputClass
+sections.
+All other entries are optional.
+.PP
+The
+.B Identifier
+entry specifies the unique name for this input class.
+The
+.B Driver
+entry specifies the name of the driver to use for this input device.
+After all classes have been examined, the
+.RI \*q inputdriver \*q
+module from the final
+.B Driver
+entry will be enabled when using the loadable server.
+.PP
+When an input device is automatically added, its characteristics are
+checked against all
+.B InputClass
+sections. Each section can contain optional entries to narrow the match
+of the class. If none of the optional entries appear, the
+.B InputClass
+section is generic and will match any input device. If more than one of
+these entries appear, they all must match for the configuration to apply.
+The allowed matching entries are shown below.
+.PP
+.TP 7
+.BI "MatchProduct  \*q" matchproduct \*q
+This entry can be used to check if the substring
+.RI \*q matchproduct \*q
+occurs in the device's product name.
+.TP 7
+.BI "MatchVendor  \*q" matchvendor \*q
+This entry can be used to check if the substring
+.RI \*q matchvendor \*q
+occurs in the device's vendor name.
+.TP 7
+.BI "MatchDevicePath \*q" matchdevice \*q
+This entry can be used to check if the device file matches the
+.RI \*q matchdevice \*q
+pathname pattern.
+.TP 7
+.BI "MatchIsKeyboard     \*q" bool \*q
+.TP 7
+.BI "MatchIsPointer      \*q" bool \*q
+.TP 7
+.BI "MatchIsJoystick     \*q" bool \*q
+.TP 7
+.BI "MatchIsTablet       \*q" bool \*q
+.TP 7
+.BI "MatchIsTouchpad     \*q" bool \*q
+.TP 7
+.BI "MatchIsTouchscreen  \*q" bool \*q
+Match device types. These entries take a boolean argument similar to
+.B Option
+entries.
+.PP
+When an input device has been matched to the
+.B InputClass
+section, any
+.B Option
+entries are applied to the device. See the
+.B InputDevice
+section above for a description of the various
+.B Option
+entries.
 .SH "DEVICE SECTION"
 The config file may have multiple
 .B Device
diff --git a/hw/xfree86/parser/InputClass.c b/hw/xfree86/parser/InputClass.c
new file mode 100644
index 0000000..1c98160
--- /dev/null
+++ b/hw/xfree86/parser/InputClass.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2009 Dan Nicholson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* View/edit this file with tab stops set to 4 */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "Configint.h"
+
+extern LexRec val;
+
+static
+xf86ConfigSymTabRec InputClassTab[] =
+{
+    {ENDSECTION, "endsection"},
+    {IDENTIFIER, "identifier"},
+    {OPTION, "option"},
+    {DRIVER, "driver"},
+    {MATCH_PRODUCT, "matchproduct"},
+    {MATCH_VENDOR, "matchvendor"},
+    {MATCH_DEVICE_PATH, "matchdevicepath"},
+    {MATCH_IS_KEYBOARD, "matchiskeyboard"},
+    {MATCH_IS_POINTER, "matchispointer"},
+    {MATCH_IS_JOYSTICK, "matchisjoystick"},
+    {MATCH_IS_TABLET, "matchistablet"},
+    {MATCH_IS_TOUCHPAD, "matchistouchpad"},
+    {MATCH_IS_TOUCHSCREEN, "matchistouchscreen"},
+    {-1, ""},
+};
+
+#define CLEANUP xf86freeInputClassList
+
+XF86ConfInputClassPtr
+xf86parseInputClassSection(void)
+{
+    int has_ident = FALSE;
+    int token;
+
+    parsePrologue(XF86ConfInputClassPtr, XF86ConfInputClassRec)
+
+    while ((token = xf86getToken(InputClassTab)) != ENDSECTION) {
+        switch (token) {
+        case COMMENT:
+            ptr->comment = xf86addComment(ptr->comment, val.str);
+            break;
+        case IDENTIFIER:
+            if (xf86getSubToken(&(ptr->comment)) != STRING)
+                Error(QUOTE_MSG, "Identifier");
+            if (has_ident == TRUE)
+                Error(MULTIPLE_MSG, "Identifier");
+            ptr->identifier = val.str;
+            has_ident = TRUE;
+            break;
+        case DRIVER:
+            if (xf86getSubToken(&(ptr->comment)) != STRING)
+                Error(QUOTE_MSG, "Driver");
+            if (strcmp(val.str, "keyboard") == 0)
+                ptr->driver = "kbd";
+            else
+                ptr->driver = val.str;
+            break;
+        case OPTION:
+            ptr->option_lst = xf86parseOption(ptr->option_lst);
+            break;
+        case MATCH_PRODUCT:
+            if (xf86getSubToken(&(ptr->comment)) != STRING)
+                Error(QUOTE_MSG, "MatchProduct");
+            ptr->match_product = val.str;
+            break;
+        case MATCH_VENDOR:
+            if (xf86getSubToken(&(ptr->comment)) != STRING)
+                Error(QUOTE_MSG, "MatchVendor");
+            ptr->match_vendor = val.str;
+            break;
+        case MATCH_DEVICE_PATH:
+            if (xf86getSubToken(&(ptr->comment)) != STRING)
+                Error(QUOTE_MSG, "MatchDevicePath");
+            ptr->match_device = val.str;
+            break;
+        case MATCH_IS_KEYBOARD:
+            if (xf86getSubToken(&(ptr->comment)) != STRING)
+                Error(QUOTE_MSG, "MatchIsKeyboard");
+            ptr->is_keyboard.set = xf86getBoolValue(&ptr->is_keyboard.val,
+                                                    val.str);
+            if (!ptr->is_keyboard.set)
+                Error(BOOL_MSG, "MatchIsKeyboard");
+            break;
+        case MATCH_IS_POINTER:
+            if (xf86getSubToken(&(ptr->comment)) != STRING)
+                Error(QUOTE_MSG, "MatchIsPointer");
+            ptr->is_pointer.set = xf86getBoolValue(&ptr->is_pointer.val,
+                                                   val.str);
+            if (!ptr->is_pointer.set)
+                Error(BOOL_MSG, "MatchIsPointer");
+            break;
+        case MATCH_IS_JOYSTICK:
+            if (xf86getSubToken(&(ptr->comment)) != STRING)
+                Error(QUOTE_MSG, "MatchIsJoystick");
+            ptr->is_joystick.set = xf86getBoolValue(&ptr->is_joystick.val,
+                                                    val.str);
+            if (!ptr->is_joystick.set)
+                Error(BOOL_MSG, "MatchIsJoystick");
+            break;
+        case MATCH_IS_TABLET:
+            if (xf86getSubToken(&(ptr->comment)) != STRING)
+                Error(QUOTE_MSG, "MatchIsTablet");
+            ptr->is_tablet.set = xf86getBoolValue(&ptr->is_tablet.val,
+                                                  val.str);
+            if (!ptr->is_tablet.set)
+                Error(BOOL_MSG, "MatchIsTablet");
+            break;
+        case MATCH_IS_TOUCHPAD:
+            if (xf86getSubToken(&(ptr->comment)) != STRING)
+                Error(QUOTE_MSG, "MatchIsTouchpad");
+            ptr->is_touchpad.set = xf86getBoolValue(&ptr->is_touchpad.val,
+                                                    val.str);
+            if (!ptr->is_touchpad.set)
+                Error(BOOL_MSG, "MatchIsTouchpad");
+            break;
+        case MATCH_IS_TOUCHSCREEN:
+            if (xf86getSubToken(&(ptr->comment)) != STRING)
+                Error(QUOTE_MSG, "MatchIsTouchscreen");
+            ptr->is_touchscreen.set = xf86getBoolValue(&ptr->is_touchscreen.val,
+                                                       val.str);
+            if (!ptr->is_touchscreen.set)
+                Error(BOOL_MSG, "MatchIsTouchscreen");
+            break;
+        case EOF_TOKEN:
+            Error(UNEXPECTED_EOF_MSG, NULL);
+            break;
+        default:
+            Error(INVALID_KEYWORD_MSG, xf86tokenString ());
+            break;
+        }
+    }
+
+    if (!has_ident)
+        Error(NO_IDENT_MSG, NULL);
+
+#ifdef DEBUG
+    printf("InputClass section parsed\n");
+#endif
+
+    return ptr;
+}
+
+void
+xf86printInputClassSection (FILE * cf, XF86ConfInputClassPtr ptr)
+{
+    while (ptr) {
+        fprintf(cf, "Section \"InputClass\"\n");
+        if (ptr->comment)
+            fprintf(cf, "%s", ptr->comment);
+        if (ptr->identifier)
+            fprintf(cf, "\tIdentifier      \"%s\"\n", ptr->identifier);
+        if (ptr->driver)
+            fprintf(cf, "\tDriver          \"%s\"\n", ptr->driver);
+        if (ptr->match_product)
+            fprintf(cf, "\tMatchProduct    \"%s\"\n", ptr->match_product);
+        if (ptr->match_vendor)
+            fprintf(cf, "\tMatchVendor     \"%s\"\n", ptr->match_vendor);
+        if (ptr->match_device)
+            fprintf(cf, "\tMatchDevicePath \"%s\"\n", ptr->match_device);
+        if (ptr->is_keyboard.set)
+            fprintf(cf, "\tIsKeyboard      \"%s\"\n",
+                    ptr->is_keyboard.val ? "yes" : "no");
+        if (ptr->is_pointer.set)
+            fprintf(cf, "\tIsPointer       \"%s\"\n",
+                    ptr->is_pointer.val ? "yes" : "no");
+        if (ptr->is_joystick.set)
+            fprintf(cf, "\tIsJoystick      \"%s\"\n",
+                    ptr->is_joystick.val ? "yes" : "no");
+        if (ptr->is_tablet.set)
+            fprintf(cf, "\tIsTablet        \"%s\"\n",
+                    ptr->is_tablet.val ? "yes" : "no");
+        if (ptr->is_touchpad.set)
+            fprintf(cf, "\tIsTouchpad      \"%s\"\n",
+                    ptr->is_touchpad.val ? "yes" : "no");
+        if (ptr->is_touchscreen.set)
+            fprintf(cf, "\tIsTouchscreen   \"%s\"\n",
+                    ptr->is_touchscreen.val ? "yes" : "no");
+        xf86printOptionList(cf, ptr->option_lst, 1);
+        fprintf(cf, "EndSection\n\n");
+        ptr = ptr->list.next;
+    }
+}
+
+void
+xf86freeInputClassList (XF86ConfInputClassPtr ptr)
+{
+    XF86ConfInputClassPtr prev;
+
+    while (ptr) {
+        TestFree(ptr->identifier);
+        TestFree(ptr->driver);
+        TestFree(ptr->match_product);
+        TestFree(ptr->match_vendor);
+        TestFree(ptr->match_device);
+        TestFree(ptr->comment);
+        xf86optionListFree(ptr->option_lst);
+
+        prev = ptr;
+        ptr = ptr->list.next;
+        free(prev);
+    }
+}
diff --git a/hw/xfree86/parser/Makefile.am b/hw/xfree86/parser/Makefile.am
index b8fab28..49c191f 100644
--- a/hw/xfree86/parser/Makefile.am
+++ b/hw/xfree86/parser/Makefile.am
@@ -13,6 +13,7 @@ INTERNAL_SOURCES= \
 	Files.c \
 	Flags.c \
 	Input.c \
+	InputClass.c \
 	Layout.c \
 	Module.c \
 	Video.c \
diff --git a/hw/xfree86/parser/configProcs.h b/hw/xfree86/parser/configProcs.h
index 26ba40e..7d8a8e5 100644
--- a/hw/xfree86/parser/configProcs.h
+++ b/hw/xfree86/parser/configProcs.h
@@ -48,6 +48,10 @@ XF86ConfInputPtr xf86parseInputSection(void);
 void xf86printInputSection(FILE *f, XF86ConfInputPtr ptr);
 void xf86freeInputList(XF86ConfInputPtr ptr);
 int xf86validateInput (XF86ConfigPtr p);
+/* InputClass.c */
+XF86ConfInputClassPtr xf86parseInputClassSection(void);
+void xf86printInputClassSection(FILE *f, XF86ConfInputClassPtr ptr);
+void xf86freeInputClassList(XF86ConfInputClassPtr ptr);
 /* Layout.c */
 XF86ConfLayoutPtr xf86parseLayoutSection(void);
 void xf86printLayoutSection(FILE *cf, XF86ConfLayoutPtr ptr);
diff --git a/hw/xfree86/parser/read.c b/hw/xfree86/parser/read.c
index e965d20..1091be5 100644
--- a/hw/xfree86/parser/read.c
+++ b/hw/xfree86/parser/read.c
@@ -177,6 +177,14 @@ xf86readConfigFile (void)
 				HANDLE_LIST (conf_input_lst, xf86parseInputSection,
 							 XF86ConfInputPtr);
 			}
+			else if (xf86nameCompare(val.str, "inputclass") == 0)
+			{
+				free(val.str);
+				val.str = NULL;
+				HANDLE_LIST (conf_inputclass_lst,
+						xf86parseInputClassSection,
+						XF86ConfInputClassPtr);
+			}
 			else if (xf86nameCompare (val.str, "module") == 0)
 			{
 				free(val.str);
diff --git a/hw/xfree86/parser/write.c b/hw/xfree86/parser/write.c
index 3b77b93..083203c 100644
--- a/hw/xfree86/parser/write.c
+++ b/hw/xfree86/parser/write.c
@@ -117,6 +117,8 @@ doWriteConfigFile (const char *filename, XF86ConfigPtr cptr)
 
 	xf86printInputSection (cf, cptr->conf_input_lst);
 
+	xf86printInputClassSection (cf, cptr->conf_inputclass_lst);
+
 	xf86printVideoAdaptorSection (cf, cptr->conf_videoadaptor_lst);
 
 	xf86printModesSection (cf, cptr->conf_modes_lst);
diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
index 72beb5f..4e30993 100644
--- a/hw/xfree86/parser/xf86Parser.h
+++ b/hw/xfree86/parser/xf86Parser.h
@@ -338,6 +338,25 @@ typedef struct
 }
 xf86TriState;
 
+typedef struct
+{
+	GenericListRec list;
+	char *identifier;
+	char *driver;
+	char *match_product;
+	char *match_vendor;
+	char *match_device;
+	xf86TriState is_keyboard;
+	xf86TriState is_pointer;
+	xf86TriState is_joystick;
+	xf86TriState is_tablet;
+	xf86TriState is_touchpad;
+	xf86TriState is_touchscreen;
+	XF86OptionPtr option_lst;
+	char *comment;
+}
+XF86ConfInputClassRec, *XF86ConfInputClassPtr;
+
 /* Values for adj_where */
 #define CONF_ADJ_OBSOLETE	-1
 #define CONF_ADJ_ABSOLUTE	0
@@ -446,6 +465,7 @@ typedef struct
 	XF86ConfDevicePtr conf_device_lst;
 	XF86ConfScreenPtr conf_screen_lst;
 	XF86ConfInputPtr conf_input_lst;
+	XF86ConfInputClassPtr conf_inputclass_lst;
 	XF86ConfLayoutPtr conf_layout_lst;
 	XF86ConfVendorPtr conf_vendor_lst;
 	XF86ConfDRIPtr conf_dri;
diff --git a/hw/xfree86/parser/xf86tokens.h b/hw/xfree86/parser/xf86tokens.h
index 4c1d38c..e3a9d71 100644
--- a/hw/xfree86/parser/xf86tokens.h
+++ b/hw/xfree86/parser/xf86tokens.h
@@ -273,7 +273,18 @@ typedef enum {
 
     /* DRI Tokens */
     GROUP,
-    BUFFERS
+    BUFFERS,
+
+    /* InputClass Tokens */
+    MATCH_PRODUCT,
+    MATCH_VENDOR,
+    MATCH_DEVICE_PATH,
+    MATCH_IS_KEYBOARD,
+    MATCH_IS_POINTER,
+    MATCH_IS_JOYSTICK,
+    MATCH_IS_TABLET,
+    MATCH_IS_TOUCHPAD,
+    MATCH_IS_TOUCHSCREEN
 } ParserTokens;
 
 #endif /* _xf86_tokens_h */
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 1096371..ab04414 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -231,6 +231,9 @@
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
+/* Define to 1 if you have the <fnmatch.h> header file. */
+#undef HAVE_FNMATCH_H
+
 /* Have /dev/urandom */
 #undef HAVE_URANDOM
 
commit 0711598dd3e8366217676f462f1af7d0899656d9
Author: Dan Nicholson <dbn.lists at gmail.com>
Date:   Wed Sep 2 06:47:13 2009 -0700

    config: Introduce InputAttributes in NewInputDeviceRequest
    
    In order to give NewInputDeviceRequest more information, a new
    InputAttributes type is introduced. Currently, this collects the product
    and vendor name, device path, and sets booleans for attributes such as
    having keys and/or a pointer. Only the HAL backend fills in the
    attributes, though.
    
    Signed-off-by: Dan Nicholson <dbn.lists at gmail.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/stubs.c b/Xi/stubs.c
index 400e937..04ba976 100644
--- a/Xi/stubs.c
+++ b/Xi/stubs.c
@@ -227,7 +227,8 @@ ChangeDeviceControl(ClientPtr client, DeviceIntPtr dev,
  *
  */
 int
-NewInputDeviceRequest(InputOption *options, DeviceIntPtr *pdev)
+NewInputDeviceRequest(InputOption *options, InputAttributes *attrs,
+                      DeviceIntPtr *pdev)
 {
     return BadValue;
 }
diff --git a/config/dbus.c b/config/dbus.c
index 37462ac..86d9d28 100644
--- a/config/dbus.c
+++ b/config/dbus.c
@@ -147,7 +147,7 @@ add_device(DBusMessage *message, DBusMessage *reply, DBusError *error)
         dbus_message_iter_next(&iter);
     }
 
-    ret = NewInputDeviceRequest(options, &dev);
+    ret = NewInputDeviceRequest(options, NULL, &dev);
     if (ret != Success) {
         DebugF("[config/dbus] NewInputDeviceRequest failed\n");
         goto unwind;
diff --git a/config/hal.c b/config/hal.c
index 28f55a0..6bebbdf 100644
--- a/config/hal.c
+++ b/config/hal.c
@@ -191,6 +191,7 @@ device_added(LibHalContext *hal_ctx, const char *udi)
 {
     char *path = NULL, *driver = NULL, *name = NULL, *config_info = NULL;
     InputOption *options = NULL, *tmpo = NULL;
+    InputAttributes attrs = {0};
     DeviceIntPtr dev = NULL;
     DBusError error;
     struct xkb_options xkb_opts = {0};
@@ -215,10 +216,28 @@ device_added(LibHalContext *hal_ctx, const char *udi)
         LogMessage(X_WARNING,"config/hal: no driver or path specified for %s\n", udi);
         goto unwind;
     }
+    attrs.device = xstrdup(path);
 
     name = get_prop_string(hal_ctx, udi, "info.product");
     if (!name)
         name = xstrdup("(unnamed)");
+    else
+        attrs.product = xstrdup(name);
+
+    attrs.vendor = get_prop_string(hal_ctx, udi, "info.vendor");
+
+    if (libhal_device_query_capability(hal_ctx, udi, "input.keys", NULL))
+        attrs.flags |= ATTR_KEYBOARD;
+    if (libhal_device_query_capability(hal_ctx, udi, "input.mouse", NULL))
+        attrs.flags |= ATTR_POINTER;
+    if (libhal_device_query_capability(hal_ctx, udi, "input.joystick", NULL))
+        attrs.flags |= ATTR_JOYSTICK;
+    if (libhal_device_query_capability(hal_ctx, udi, "input.tablet", NULL))
+        attrs.flags |= ATTR_TABLET;
+    if (libhal_device_query_capability(hal_ctx, udi, "input.touchpad", NULL))
+        attrs.flags |= ATTR_TOUCHPAD;
+    if (libhal_device_query_capability(hal_ctx, udi, "input.touchscreen", NULL))
+        attrs.flags |= ATTR_TOUCHSCREEN;
 
     options = xcalloc(sizeof(*options), 1);
     if (!options){
@@ -400,7 +419,7 @@ device_added(LibHalContext *hal_ctx, const char *udi)
 
     /* this isn't an error, but how else do you output something that the user can see? */
     LogMessage(X_INFO, "config/hal: Adding input device %s\n", name);
-    if ((rc = NewInputDeviceRequest(options, &dev)) != Success) {
+    if ((rc = NewInputDeviceRequest(options, &attrs, &dev)) != Success) {
         LogMessage(X_ERROR, "config/hal: NewInputDeviceRequest failed (%d)\n", rc);
         dev = NULL;
         goto unwind;
@@ -430,6 +449,10 @@ unwind:
         xfree(tmpo);
     }
 
+    xfree(attrs.product);
+    xfree(attrs.vendor);
+    xfree(attrs.device);
+
     if (xkb_opts.layout)
         xfree(xkb_opts.layout);
     if (xkb_opts.rules)
diff --git a/hw/dmx/dmxinput.c b/hw/dmx/dmxinput.c
index d9118b6..c099349 100644
--- a/hw/dmx/dmxinput.c
+++ b/hw/dmx/dmxinput.c
@@ -103,7 +103,8 @@ void dmxUpdateWindowInfo(DMXUpdateType type, WindowPtr pWindow)
 }
 
 int
-NewInputDeviceRequest (InputOption *options, DeviceIntPtr *pdev)
+NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
+                       DeviceIntPtr *pdev)
 {
     return BadRequest;
 }
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index 65fc75a..c084591 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -2249,7 +2249,8 @@ ChangeDeviceControl(register ClientPtr client, DeviceIntPtr pDev,
 }
 
 int
-NewInputDeviceRequest(InputOption *options, DeviceIntPtr *pdev)
+NewInputDeviceRequest(InputOption *options, InputAttributes *attrs,
+                      DeviceIntPtr *pdev)
 {
     InputOption *option = NULL;
     KdPointerInfo *pi = NULL;
diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h
index 8e5d5cf..bbf5786 100644
--- a/hw/xfree86/common/xf86Module.h
+++ b/hw/xfree86/common/xf86Module.h
@@ -83,7 +83,7 @@ typedef enum {
  */
 #define ABI_ANSIC_VERSION	SET_ABI_VERSION(0, 4)
 #define ABI_VIDEODRV_VERSION	SET_ABI_VERSION(7, 0)
-#define ABI_XINPUT_VERSION	SET_ABI_VERSION(8, 0)
+#define ABI_XINPUT_VERSION	SET_ABI_VERSION(9, 0)
 #define ABI_EXTENSION_VERSION	SET_ABI_VERSION(3, 0)
 #define ABI_FONT_VERSION	SET_ABI_VERSION(0, 6)
 
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index f637cfe..11b7315 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -568,7 +568,8 @@ unwind:
 }
 
 int
-NewInputDeviceRequest (InputOption *options, DeviceIntPtr *pdev)
+NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
+                       DeviceIntPtr *pdev)
 {
     IDevRec *idev = NULL;
     InputOption *option = NULL;
diff --git a/hw/xquartz/darwinXinput.c b/hw/xquartz/darwinXinput.c
index 8af9fc7..43aea61 100644
--- a/hw/xquartz/darwinXinput.c
+++ b/hw/xquartz/darwinXinput.c
@@ -230,7 +230,8 @@ ChangeDeviceControl(ClientPtr client, DeviceIntPtr dev,
  *
  */
 int
-NewInputDeviceRequest(InputOption *options, DeviceIntPtr *pdev)
+NewInputDeviceRequest(InputOption *options, InputAttributes *attrs,
+                      DeviceIntPtr *pdev)
 {
   DEBUG_LOG("NewInputDeviceRequest(%p, %p)\n", options, pdev);
   return BadValue;
diff --git a/include/input.h b/include/input.h
index afcc006..7a6242d 100644
--- a/include/input.h
+++ b/include/input.h
@@ -52,6 +52,7 @@ SOFTWARE.
 #include "screenint.h"
 #include <X11/Xmd.h>
 #include <X11/Xproto.h>
+#include <stdint.h>
 #include "window.h"     /* for WindowPtr */
 #include "xkbrules.h"
 #include "events.h"
@@ -210,6 +211,20 @@ typedef struct _InputOption {
     struct _InputOption *next;
 } InputOption;
 
+typedef struct _InputAttributes {
+    char                *product;
+    char                *vendor;
+    char                *device;
+    uint32_t            flags;
+} InputAttributes;
+
+#define ATTR_KEYBOARD (1<<0)
+#define ATTR_POINTER (1<<1)
+#define ATTR_JOYSTICK (1<<2)
+#define ATTR_TABLET (1<<3)
+#define ATTR_TOUCHPAD (1<<4)
+#define ATTR_TOUCHSCREEN (1<<5)
+
 /* Key has been run through all input processing and events sent to clients. */
 #define KEY_PROCESSED 1
 /* Key has not been fully processed, no events have been sent. */
@@ -514,6 +529,7 @@ void FixUpEventFromWindow(DeviceIntPtr pDev,
 /* Implemented by the DDX. */
 extern _X_EXPORT int NewInputDeviceRequest(
     InputOption *options,
+    InputAttributes *attrs,
     DeviceIntPtr *dev);
 extern  _X_EXPORT void DeleteInputDeviceRequest(
     DeviceIntPtr dev);
commit c6e8637e29e0ca11dfb35c02da7ca6002ac8c597
Author: Dan Nicholson <dbn.lists at gmail.com>
Date:   Fri Oct 2 06:28:03 2009 -0700

    xfree86: Support non-Option boolean entries in configuration
    
    Refactored code into the parser to allow the freeform boolean types used
    in Option entries to be used in other configuration entries. This isn't
    as powerful as allowing "No" to precede the option names, but it atleast
    gives a common handling of "yes", "no", etc.
    
    A type xf86TriState has been added to support an optional boolean. This
    allows the boolean sense of the value to be kept while providing a means
    to signal that it is unset.
    
    Signed-off-by: Dan Nicholson <dbn.lists at gmail.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/common/xf86Option.c b/hw/xfree86/common/xf86Option.c
index ad8d1c4..a2868bf 100644
--- a/hw/xfree86/common/xf86Option.c
+++ b/hw/xfree86/common/xf86Option.c
@@ -42,6 +42,7 @@
 #include "xf86.h"
 #include "xf86Xinput.h"
 #include "xf86Optrec.h"
+#include "xf86Parser.h"
 
 static Bool ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p,
 			     Bool markUsed);
@@ -456,29 +457,7 @@ xf86ShowUnusedOptions(int scrnIndex, pointer options)
 static Bool
 GetBoolValue(OptionInfoPtr p, const char *s)
 {
-    if (*s == '\0') {
-	p->value.bool = TRUE;
-    } else {
-	if (xf86NameCmp(s, "1") == 0)
-	    p->value.bool = TRUE;
-	else if (xf86NameCmp(s, "on") == 0)
-	    p->value.bool = TRUE;
-	else if (xf86NameCmp(s, "true") == 0)
-	    p->value.bool = TRUE;
-	else if (xf86NameCmp(s, "yes") == 0)
-	    p->value.bool = TRUE;
-	else if (xf86NameCmp(s, "0") == 0)
-	    p->value.bool = FALSE;
-	else if (xf86NameCmp(s, "off") == 0)
-	    p->value.bool = FALSE;
-	else if (xf86NameCmp(s, "false") == 0)
-	    p->value.bool = FALSE;
-	else if (xf86NameCmp(s, "no") == 0)
-	    p->value.bool = FALSE;
-	else
-	    return FALSE;
-    }
-    return TRUE;
+    return xf86getBoolValue(&p->value.bool, s);
 }
 
 static Bool
diff --git a/hw/xfree86/parser/Configint.h b/hw/xfree86/parser/Configint.h
index cdc7be8..03509b3 100644
--- a/hw/xfree86/parser/Configint.h
+++ b/hw/xfree86/parser/Configint.h
@@ -148,6 +148,8 @@ else\
 "The %s keyword requires a number to follow it."
 #define POSITIVE_INT_MSG \
 "The %s keyword requires a positive integer to follow it."
+#define BOOL_MSG \
+"The %s keyword requires a boolean to follow it."
 #define ZAXISMAPPING_MSG \
 "The ZAxisMapping keyword requires 2 positive numbers or X or Y to follow it."
 #define AUTOREPEAT_MSG \
diff --git a/hw/xfree86/parser/scan.c b/hw/xfree86/parser/scan.c
index d2e8b6d..270dbd5 100644
--- a/hw/xfree86/parser/scan.c
+++ b/hw/xfree86/parser/scan.c
@@ -1028,3 +1028,33 @@ xf86addComment(char *cur, char *add)
 
 	return (cur);
 }
+
+Bool
+xf86getBoolValue(Bool *val, const char *str)
+{
+	if (!val || !str)
+		return FALSE;
+	if (*str == '\0') {
+		*val = TRUE;
+	} else {
+		if (strcmp(str, "1") == 0)
+			*val = TRUE;
+		else if (strcmp(str, "on") == 0)
+			*val = TRUE;
+		else if (strcmp(str, "true") == 0)
+			*val = TRUE;
+		else if (strcmp(str, "yes") == 0)
+			*val = TRUE;
+		else if (strcmp(str, "0") == 0)
+			*val = FALSE;
+		else if (strcmp(str, "off") == 0)
+			*val = FALSE;
+		else if (strcmp(str, "false") == 0)
+			*val = FALSE;
+		else if (strcmp(str, "no") == 0)
+			*val = FALSE;
+		else
+			return FALSE;
+	}
+	return TRUE;
+}
diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
index 6030800..72beb5f 100644
--- a/hw/xfree86/parser/xf86Parser.h
+++ b/hw/xfree86/parser/xf86Parser.h
@@ -64,6 +64,7 @@
 #ifndef _xf86Parser_h_
 #define _xf86Parser_h_
 
+#include <X11/Xdefs.h>
 #include "xf86Optrec.h"
 
 #define HAVE_PARSER_DECLS
@@ -330,6 +331,13 @@ typedef struct
 }
 XF86ConfInputrefRec, *XF86ConfInputrefPtr;
 
+typedef struct
+{
+	Bool set;
+	Bool val;
+}
+xf86TriState;
+
 /* Values for adj_where */
 #define CONF_ADJ_OBSOLETE	-1
 #define CONF_ADJ_ABSOLUTE	0
@@ -480,5 +488,6 @@ extern _X_EXPORT int xf86itemNotSublist(GenericListPtr list_1, GenericListPtr li
 extern _X_EXPORT int xf86pathIsAbsolute(const char *path);
 extern _X_EXPORT int xf86pathIsSafe(const char *path);
 extern _X_EXPORT char *xf86addComment(char *cur, char *add);
+extern _X_EXPORT Bool xf86getBoolValue(Bool *val, const char *str);
 
 #endif /* _xf86Parser_h_ */


More information about the xorg-commit mailing list