xfree86: Match devices based on current driver setting
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@gmail.com> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
a71bdff47d
commit
66b21b2f45
@ -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 */
|
||||
xf86Msg(X_CONFIG, "%s: Applying InputClass \"%s\"\n",
|
||||
idev->identifier, cl->identifier);
|
||||
if (cl->driver)
|
||||
classdriver = cl->driver;
|
||||
/* Collect class options and driver settings */
|
||||
classopts = xf86optionListDup(cl->option_lst);
|
||||
mergedopts = xf86optionListMerge(mergedopts, classopts);
|
||||
}
|
||||
|
||||
/* Apply options to device with InputClass settings preferred. */
|
||||
if (classdriver) {
|
||||
if (cl->driver) {
|
||||
free(idev->driver);
|
||||
idev->driver = xstrdup(classdriver);
|
||||
idev->driver = xstrdup(cl->driver);
|
||||
if (!idev->driver) {
|
||||
xf86Msg(X_ERROR, "Failed to allocate memory while merging "
|
||||
"InputClass configuration");
|
||||
return BadAlloc;
|
||||
}
|
||||
mergedopts = xf86ReplaceStrOption(mergedopts, "driver", idev->driver);
|
||||
classopts = xf86ReplaceStrOption(classopts, "driver",
|
||||
idev->driver);
|
||||
}
|
||||
idev->commonOptions = xf86optionListMerge(idev->commonOptions, mergedopts);
|
||||
|
||||
/* Apply options to device with InputClass settings preferred. */
|
||||
xf86Msg(X_CONFIG, "%s: Applying InputClass \"%s\"\n",
|
||||
idev->identifier, cl->identifier);
|
||||
idev->commonOptions = xf86optionListMerge(idev->commonOptions,
|
||||
classopts);
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -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
|
||||
|
@ -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++)
|
||||
|
@ -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;
|
||||
|
@ -282,6 +282,7 @@ typedef enum {
|
||||
MATCH_OS,
|
||||
MATCH_PNPID,
|
||||
MATCH_USBID,
|
||||
MATCH_DRIVER,
|
||||
MATCH_TAG,
|
||||
MATCH_IS_KEYBOARD,
|
||||
MATCH_IS_POINTER,
|
||||
|
Loading…
Reference in New Issue
Block a user