[PATCH 7/7] Add tag matching to input attributes.

Peter Hutterer peter.hutterer at who-t.net
Tue Feb 9 21:36:50 PST 2010


Tags may be a list of comma-separated strings that match against a MatchTag
InputClass section. If any of the tags specified for a device match against
the MatchTag of the section, this match is evaluated true and passed on to
the next match condition.

Tags are specified as "input.tags" (hal) or "ID_INPUT.tags" (udev), the
value of the tags is case-sensitive and require an exact match (not a
substring match).

i.e. "quirk" will not match "QUIRK", "need_quirk" or "quirk_needed".

Example configuration:
udev:
    ENV{ID_INPUT.tags}="foo,bar"

hal:
    <merge key="input.tags" type="string">foo,bar</merge>

xorg.conf:
    Section "InputClass"
            Identifier "foobar quirks"
            MatchTag "foo|foobar"
            Option "Foobar" "on"
    EndSection

Where the xorg.conf section matches against any device with the tag "foo"
or tag "foobar" set.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 config/hal.c                         |    9 +++++++++
 config/udev.c                        |   10 ++++++++++
 hw/xfree86/common/xf86Xinput.c       |   18 ++++++++++++++++++
 hw/xfree86/doc/man/xorg.conf.man.pre |    9 +++++++++
 hw/xfree86/parser/InputClass.c       |   19 +++++++++++++++++++
 hw/xfree86/parser/xf86Parser.h       |    1 +
 hw/xfree86/parser/xf86tokens.h       |    1 +
 include/input.h                      |    1 +
 8 files changed, 68 insertions(+), 0 deletions(-)

diff --git a/config/hal.c b/config/hal.c
index 1b01ecc..d3daa84 100644
--- a/config/hal.c
+++ b/config/hal.c
@@ -164,6 +164,7 @@ device_added(LibHalContext *hal_ctx, const char *udi)
         attrs.product = xstrdup(name);
 
     attrs.vendor = get_prop_string(hal_ctx, udi, "info.vendor");
+    attrs.tags = xstrtokenize(get_prop_string(hal_ctx, udi, "input.tags"), ",");
 
     if (libhal_device_query_capability(hal_ctx, udi, "input.keys", NULL))
         attrs.flags |= ATTR_KEYBOARD;
@@ -391,6 +392,14 @@ unwind:
     xfree(attrs.product);
     xfree(attrs.vendor);
     xfree(attrs.device);
+    if (attrs.tags) {
+        char **tag = attrs.tags;
+        while (*tag) {
+            xfree(*tag);
+            tag++;
+        }
+        xfree(attrs.tags);
+    }
 
     if (xkb_opts.layout)
         xfree(xkb_opts.layout);
diff --git a/config/udev.c b/config/udev.c
index 3ef0d7f..432ab85 100644
--- a/config/udev.c
+++ b/config/udev.c
@@ -84,6 +84,7 @@ device_added(struct udev_device *udev_device)
     add_option(&options, "path", path);
     add_option(&options, "device", path);
     attrs.device = path;
+    attrs.tags = xstrtokenize(udev_device_get_property_value(udev_device, "ID_INPUT.tags"), ",");
 
     config_info = Xprintf("udev:%s", syspath);
     if (!config_info)
@@ -150,6 +151,15 @@ device_added(struct udev_device *udev_device)
         xfree(tmpo);
     }
 
+    if (attrs.tags) {
+        char **tag = attrs.tags;
+        while (*tag) {
+            xfree(*tag);
+            tag++;
+        }
+        xfree(attrs.tags);
+    }
+
     return;
 }
 
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 4604710..c2d9f49 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -545,6 +545,24 @@ InputClassMatches(XF86ConfInputClassPtr iclass, InputAttributes *attrs)
         if (!match)
             return FALSE;
     }
+    if (iclass->match_tag) {
+        if (!attrs->tags)
+            return FALSE;
+
+        for (cur = iclass->match_tag, match = FALSE; *cur && !match; cur++) {
+            const char *tag;
+            for(tag = *attrs->tags; *tag; tag++) {
+                if (!strcmp(tag, *cur)) {
+                    match = TRUE;
+                    break;
+                }
+            }
+        }
+
+        if (!match)
+            return FALSE;
+    }
+
     if (iclass->is_keyboard.set &&
         iclass->is_keyboard.val != !!(attrs->flags & ATTR_KEYBOARD))
         return FALSE;
diff --git a/hw/xfree86/doc/man/xorg.conf.man.pre b/hw/xfree86/doc/man/xorg.conf.man.pre
index 69f4751..270c057 100644
--- a/hw/xfree86/doc/man/xorg.conf.man.pre
+++ b/hw/xfree86/doc/man/xorg.conf.man.pre
@@ -1054,6 +1054,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 "MatchTag \*q" matchtag \*q
+This entry can be used to check if tags assigned by the config backend
+matches the
+.RI \*q matchtag \*q
+pattern.  Multiple patterns can be matched by separating arguments
+with a '|' character. A match is found if at least one of the tags given in 
+.RI \*q matchtag \*q
+matches at least one of the tags assigned by the backend.
+.TP 7
 .BI "MatchIsKeyboard     \*q" bool \*q
 .TP 7
 .BI "MatchIsPointer      \*q" bool \*q
diff --git a/hw/xfree86/parser/InputClass.c b/hw/xfree86/parser/InputClass.c
index 9fabb22..7fb2866 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_TAG, "matchtag"},
     {MATCH_IS_KEYBOARD, "matchiskeyboard"},
     {MATCH_IS_POINTER, "matchispointer"},
     {MATCH_IS_JOYSTICK, "matchisjoystick"},
@@ -107,6 +108,11 @@ xf86parseInputClassSection(void)
                 Error(QUOTE_MSG, "MatchDevicePath");
             ptr->match_device = xstrtokenize(val.str, TOKEN_SEP);
             break;
+        case MATCH_TAG:
+            if (xf86getSubToken(&(ptr->comment)) != STRING)
+                Error(QUOTE_MSG, "MatchTag");
+            ptr->match_tag = xstrtokenize(val.str, TOKEN_SEP);
+            break;
         case MATCH_IS_KEYBOARD:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchIsKeyboard");
@@ -211,6 +217,14 @@ xf86printInputClassSection (FILE * cf, XF86ConfInputClassPtr ptr)
                         *list);
             fprintf(cf, "\"\n");
         }
+        if (ptr->match_tag) {
+            fprintf(cf, "\tMatchTag \"");
+            for (list = ptr->match_tag; *list; list++)
+                fprintf(cf, "%s%s",
+                        list == ptr->match_tag ? "" : TOKEN_SEP,
+                        *list);
+            fprintf(cf, "\"\n");
+        }
         if (ptr->is_keyboard.set)
             fprintf(cf, "\tIsKeyboard      \"%s\"\n",
                     ptr->is_keyboard.val ? "yes" : "no");
@@ -259,6 +273,11 @@ xf86freeInputClassList (XF86ConfInputClassPtr ptr)
                 free(*list);
             free(ptr->match_device);
         }
+        if (ptr->match_tag) {
+            for (list = ptr->match_tag; *list; list++)
+                free(*list);
+            free(ptr->match_tag);
+        }
         TestFree(ptr->comment);
         xf86optionListFree(ptr->option_lst);
 
diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
index b6d40a1..d79544a 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_tag;
 	xf86TriState is_keyboard;
 	xf86TriState is_pointer;
 	xf86TriState is_joystick;
diff --git a/hw/xfree86/parser/xf86tokens.h b/hw/xfree86/parser/xf86tokens.h
index e3a9d71..cb60070 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_TAG,
     MATCH_IS_KEYBOARD,
     MATCH_IS_POINTER,
     MATCH_IS_JOYSTICK,
diff --git a/include/input.h b/include/input.h
index 7a6242d..4a845be 100644
--- a/include/input.h
+++ b/include/input.h
@@ -215,6 +215,7 @@ typedef struct _InputAttributes {
     char                *product;
     char                *vendor;
     char                *device;
+    char                **tags; /* null-terminated */
     uint32_t            flags;
 } InputAttributes;
 
-- 
1.6.6



More information about the xorg-devel mailing list