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

Dan Nicholson dbn.lists at gmail.com
Wed Feb 10 20:55:22 PST 2010


On Tue, Feb 9, 2010 at 9:36 PM, Peter Hutterer <peter.hutterer at who-t.net> wrote:
> 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++) {

Space after for.

> +                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

Nitpick: git complains about a trailing space here.

> +.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

Looks good. I tested on hal and it seems to work. Take your pick:

Tested-by: Dan Nicholson <dbn.lists at gmail.com>
Reviewed-by: Dan Nicholson <dbn.lists at gmail.com>


More information about the xorg-devel mailing list