[PATCH v2 11/11] xfree86: Match devices based on current driver setting

Dan Nicholson dbn.lists at gmail.com
Mon Jun 7 20:39:58 PDT 2010


Often we want to apply a driver specific option to a set of devices and
don't care how the driver was selected for that device. The MatchDriver
entry can be used to match the current driver string:

	MatchDriver "evdev|mouse"
	Option "Emulate3Buttons" "yes"

The driver string is a case sensitive match.

Signed-off-by: Dan Nicholson <dbn.lists at gmail.com>
---
 hw/xfree86/common/xf86Xinput.c       |   47 ++++++++++++++++++----------------
 hw/xfree86/doc/man/xorg.conf.man.pre |    9 ++++++
 hw/xfree86/parser/InputClass.c       |   21 +++++++++++++++
 hw/xfree86/parser/xf86Parser.h       |    1 +
 hw/xfree86/parser/xf86tokens.h       |    1 +
 5 files changed, 57 insertions(+), 22 deletions(-)

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index be1b8a5..4bd6459 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -594,7 +594,7 @@ MatchAttrToken(const char *attr, struct list *patterns,
  * statements must match.
  */
 static Bool
-InputClassMatches(const XF86ConfInputClassPtr iclass,
+InputClassMatches(const XF86ConfInputClassPtr iclass, const IDevPtr idev,
                   const InputAttributes *attrs)
 {
     /* MatchProduct substring */
@@ -621,6 +621,10 @@ InputClassMatches(const XF86ConfInputClassPtr iclass,
     if (!MatchAttrToken(attrs->usb_id, &iclass->match_usbid, match_pattern))
         return FALSE;
 
+    /* MatchDriver string */
+    if (!MatchAttrToken(idev->driver, &iclass->match_driver, strcmp))
+        return FALSE;
+
     /*
      * MatchTag string
      * See if any of the device's tags match any of the MatchTag tokens.
@@ -673,34 +677,33 @@ static int
 MergeInputClasses(const IDevPtr idev, const InputAttributes *attrs)
 {
     XF86ConfInputClassPtr cl;
-    XF86OptionPtr classopts, mergedopts = NULL;
-    char *classdriver = NULL;
+    XF86OptionPtr classopts;
 
     for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) {
-        if (!InputClassMatches(cl, attrs))
+        if (!InputClassMatches(cl, idev, attrs))
             continue;
 
-        /* Collect class options and merge over previous classes */
+        /* Collect class options and driver settings */
+        classopts = xf86optionListDup(cl->option_lst);
+        if (cl->driver) {
+            free(idev->driver);
+            idev->driver = xstrdup(cl->driver);
+            if (!idev->driver) {
+                xf86Msg(X_ERROR, "Failed to allocate memory while merging "
+                        "InputClass configuration");
+                return BadAlloc;
+            }
+            classopts = xf86ReplaceStrOption(classopts, "driver",
+                                             idev->driver);
+        }
+
+        /* Apply options to device with InputClass settings preferred. */
         xf86Msg(X_CONFIG, "%s: Applying InputClass \"%s\"\n",
                 idev->identifier, cl->identifier);
-        if (cl->driver)
-            classdriver = cl->driver;
-        classopts = xf86optionListDup(cl->option_lst);
-        mergedopts = xf86optionListMerge(mergedopts, classopts);
+        idev->commonOptions = xf86optionListMerge(idev->commonOptions,
+                                                  classopts);
     }
 
-    /* Apply options to device with InputClass settings preferred. */
-    if (classdriver) {
-        free(idev->driver);
-        idev->driver = xstrdup(classdriver);
-        if (!idev->driver) {
-            xf86Msg(X_ERROR, "Failed to allocate memory while merging "
-                    "InputClass configuration");
-            return BadAlloc;
-        }
-        mergedopts = xf86ReplaceStrOption(mergedopts, "driver", idev->driver);
-    }
-    idev->commonOptions = xf86optionListMerge(idev->commonOptions, mergedopts);
     return Success;
 }
 
@@ -716,7 +719,7 @@ IgnoreInputClass(const IDevPtr idev, const InputAttributes *attrs)
     const char *ignore_class;
 
     for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) {
-        if (!InputClassMatches(cl, attrs))
+        if (!InputClassMatches(cl, idev, attrs))
             continue;
         if (xf86findOption(cl->option_lst, "Ignore")) {
             ignore = xf86CheckBoolOption(cl->option_lst, "Ignore", FALSE);
diff --git a/hw/xfree86/doc/man/xorg.conf.man.pre b/hw/xfree86/doc/man/xorg.conf.man.pre
index f6b90be..6b3636f 100644
--- a/hw/xfree86/doc/man/xorg.conf.man.pre
+++ b/hw/xfree86/doc/man/xorg.conf.man.pre
@@ -1123,6 +1123,15 @@ separated by a ':'. This is the same format as the
 .BR lsusb (8)
 program.
 .TP 7
+.BI "MatchDriver \*q" matchdriver \*q
+Check the case-sensitive string
+.RI \*q matchdriver \*q
+against the currently configured driver of the device. Ordering of sections
+using this entry is important since it will not match unless the driver has
+been set by the config backend or a previous
+.B InputClass
+section.
+.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 f2b46bb..ce611d9 100644
--- a/hw/xfree86/parser/InputClass.c
+++ b/hw/xfree86/parser/InputClass.c
@@ -50,6 +50,7 @@ xf86ConfigSymTabRec InputClassTab[] =
     {MATCH_OS, "matchos"},
     {MATCH_PNPID, "matchpnpid"},
     {MATCH_USBID, "matchusbid"},
+    {MATCH_DRIVER, "matchdriver"},
     {MATCH_TAG, "matchtag"},
     {MATCH_IS_KEYBOARD, "matchiskeyboard"},
     {MATCH_IS_POINTER, "matchispointer"},
@@ -91,6 +92,7 @@ xf86parseInputClassSection(void)
     list_init(&ptr->match_os);
     list_init(&ptr->match_pnpid);
     list_init(&ptr->match_usbid);
+    list_init(&ptr->match_driver);
     list_init(&ptr->match_tag);
 
     while ((token = xf86getToken(InputClassTab)) != ENDSECTION) {
@@ -153,6 +155,12 @@ xf86parseInputClassSection(void)
             add_group_entry(&ptr->match_usbid,
                             xstrtokenize(val.str, TOKEN_SEP));
             break;
+        case MATCH_DRIVER:
+            if (xf86getSubToken(&(ptr->comment)) != STRING)
+                Error(QUOTE_MSG, "MatchDriver");
+            add_group_entry(&ptr->match_driver,
+                            xstrtokenize(val.str, TOKEN_SEP));
+            break;
         case MATCH_TAG:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchTag");
@@ -283,6 +291,13 @@ xf86printInputClassSection (FILE * cf, XF86ConfInputClassPtr ptr)
                         *cur);
             fprintf(cf, "\"\n");
         }
+        list_for_each_entry(group, &ptr->match_driver, entry) {
+            fprintf(cf, "\tMatchDriver     \"");
+            for (cur = group->values; *cur; cur++)
+                fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
+                        *cur);
+            fprintf(cf, "\"\n");
+        }
         list_for_each_entry(group, &ptr->match_tag, entry) {
             fprintf(cf, "\tMatchTag        \"");
             for (cur = group->values; *cur; cur++)
@@ -363,6 +378,12 @@ xf86freeInputClassList (XF86ConfInputClassPtr ptr)
                 free(*list);
             free(group);
         }
+        list_for_each_entry_safe(group, next, &ptr->match_driver, entry) {
+            list_del(&group->entry);
+            for (list = group->values; *list; list++)
+                free(*list);
+            free(group);
+        }
         list_for_each_entry_safe(group, next, &ptr->match_tag, entry) {
             list_del(&group->entry);
             for (list = group->values; *list; list++)
diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
index 26d9a5b..337ad07 100644
--- a/hw/xfree86/parser/xf86Parser.h
+++ b/hw/xfree86/parser/xf86Parser.h
@@ -357,6 +357,7 @@ typedef struct
 	struct list match_os;
 	struct list match_pnpid;
 	struct list match_usbid;
+	struct list match_driver;
 	struct list match_tag;
 	xf86TriState is_keyboard;
 	xf86TriState is_pointer;
diff --git a/hw/xfree86/parser/xf86tokens.h b/hw/xfree86/parser/xf86tokens.h
index 23460dd..c16a8f5 100644
--- a/hw/xfree86/parser/xf86tokens.h
+++ b/hw/xfree86/parser/xf86tokens.h
@@ -282,6 +282,7 @@ typedef enum {
     MATCH_OS,
     MATCH_PNPID,
     MATCH_USBID,
+    MATCH_DRIVER,
     MATCH_TAG,
     MATCH_IS_KEYBOARD,
     MATCH_IS_POINTER,
-- 
1.6.6.1



More information about the xorg-devel mailing list