diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c index fa0ed8592..b2a1d1ffc 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 f6b90be2c..6b3636fff 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 f2b46bb1c..ce611d990 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 26d9a5b33..337ad0718 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 23460dd73..c16a8f551 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,