diff --git a/config/hal.c b/config/hal.c index 1b01eccaa..d3daa84cd 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 3ef0d7fb3..432ab85e9 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 46047108f..c2d9f49de 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 69f475107..c8a3c3ac2 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 9fabb22cd..7fb2866cd 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 b6d40a1f3..d79544a20 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 e3a9d716b..cb600704b 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 7a6242d08..4a845bedf 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;