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.
|
* statements must match.
|
||||||
*/
|
*/
|
||||||
static Bool
|
static Bool
|
||||||
InputClassMatches(const XF86ConfInputClassPtr iclass,
|
InputClassMatches(const XF86ConfInputClassPtr iclass, const IDevPtr idev,
|
||||||
const InputAttributes *attrs)
|
const InputAttributes *attrs)
|
||||||
{
|
{
|
||||||
/* MatchProduct substring */
|
/* MatchProduct substring */
|
||||||
|
@ -621,6 +621,10 @@ InputClassMatches(const XF86ConfInputClassPtr iclass,
|
||||||
if (!MatchAttrToken(attrs->usb_id, &iclass->match_usbid, match_pattern))
|
if (!MatchAttrToken(attrs->usb_id, &iclass->match_usbid, match_pattern))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
/* MatchDriver string */
|
||||||
|
if (!MatchAttrToken(idev->driver, &iclass->match_driver, strcmp))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MatchTag string
|
* MatchTag string
|
||||||
* See if any of the device's tags match any of the MatchTag tokens.
|
* 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)
|
MergeInputClasses(const IDevPtr idev, const InputAttributes *attrs)
|
||||||
{
|
{
|
||||||
XF86ConfInputClassPtr cl;
|
XF86ConfInputClassPtr cl;
|
||||||
XF86OptionPtr classopts, mergedopts = NULL;
|
XF86OptionPtr classopts;
|
||||||
char *classdriver = NULL;
|
|
||||||
|
|
||||||
for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) {
|
for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) {
|
||||||
if (!InputClassMatches(cl, attrs))
|
if (!InputClassMatches(cl, idev, attrs))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Collect class options and merge over previous classes */
|
/* Collect class options and driver settings */
|
||||||
xf86Msg(X_CONFIG, "%s: Applying InputClass \"%s\"\n",
|
|
||||||
idev->identifier, cl->identifier);
|
|
||||||
if (cl->driver)
|
|
||||||
classdriver = cl->driver;
|
|
||||||
classopts = xf86optionListDup(cl->option_lst);
|
classopts = xf86optionListDup(cl->option_lst);
|
||||||
mergedopts = xf86optionListMerge(mergedopts, classopts);
|
if (cl->driver) {
|
||||||
}
|
|
||||||
|
|
||||||
/* Apply options to device with InputClass settings preferred. */
|
|
||||||
if (classdriver) {
|
|
||||||
free(idev->driver);
|
free(idev->driver);
|
||||||
idev->driver = xstrdup(classdriver);
|
idev->driver = xstrdup(cl->driver);
|
||||||
if (!idev->driver) {
|
if (!idev->driver) {
|
||||||
xf86Msg(X_ERROR, "Failed to allocate memory while merging "
|
xf86Msg(X_ERROR, "Failed to allocate memory while merging "
|
||||||
"InputClass configuration");
|
"InputClass configuration");
|
||||||
return BadAlloc;
|
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;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -716,7 +719,7 @@ IgnoreInputClass(const IDevPtr idev, const InputAttributes *attrs)
|
||||||
const char *ignore_class;
|
const char *ignore_class;
|
||||||
|
|
||||||
for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) {
|
for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) {
|
||||||
if (!InputClassMatches(cl, attrs))
|
if (!InputClassMatches(cl, idev, attrs))
|
||||||
continue;
|
continue;
|
||||||
if (xf86findOption(cl->option_lst, "Ignore")) {
|
if (xf86findOption(cl->option_lst, "Ignore")) {
|
||||||
ignore = xf86CheckBoolOption(cl->option_lst, "Ignore", FALSE);
|
ignore = xf86CheckBoolOption(cl->option_lst, "Ignore", FALSE);
|
||||||
|
|
|
@ -1123,6 +1123,15 @@ separated by a ':'. This is the same format as the
|
||||||
.BR lsusb (8)
|
.BR lsusb (8)
|
||||||
program.
|
program.
|
||||||
.TP 7
|
.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
|
.BI "MatchTag \*q" matchtag \*q
|
||||||
This entry can be used to check if tags assigned by the config backend
|
This entry can be used to check if tags assigned by the config backend
|
||||||
matches the
|
matches the
|
||||||
|
|
|
@ -50,6 +50,7 @@ xf86ConfigSymTabRec InputClassTab[] =
|
||||||
{MATCH_OS, "matchos"},
|
{MATCH_OS, "matchos"},
|
||||||
{MATCH_PNPID, "matchpnpid"},
|
{MATCH_PNPID, "matchpnpid"},
|
||||||
{MATCH_USBID, "matchusbid"},
|
{MATCH_USBID, "matchusbid"},
|
||||||
|
{MATCH_DRIVER, "matchdriver"},
|
||||||
{MATCH_TAG, "matchtag"},
|
{MATCH_TAG, "matchtag"},
|
||||||
{MATCH_IS_KEYBOARD, "matchiskeyboard"},
|
{MATCH_IS_KEYBOARD, "matchiskeyboard"},
|
||||||
{MATCH_IS_POINTER, "matchispointer"},
|
{MATCH_IS_POINTER, "matchispointer"},
|
||||||
|
@ -91,6 +92,7 @@ xf86parseInputClassSection(void)
|
||||||
list_init(&ptr->match_os);
|
list_init(&ptr->match_os);
|
||||||
list_init(&ptr->match_pnpid);
|
list_init(&ptr->match_pnpid);
|
||||||
list_init(&ptr->match_usbid);
|
list_init(&ptr->match_usbid);
|
||||||
|
list_init(&ptr->match_driver);
|
||||||
list_init(&ptr->match_tag);
|
list_init(&ptr->match_tag);
|
||||||
|
|
||||||
while ((token = xf86getToken(InputClassTab)) != ENDSECTION) {
|
while ((token = xf86getToken(InputClassTab)) != ENDSECTION) {
|
||||||
|
@ -153,6 +155,12 @@ xf86parseInputClassSection(void)
|
||||||
add_group_entry(&ptr->match_usbid,
|
add_group_entry(&ptr->match_usbid,
|
||||||
xstrtokenize(val.str, TOKEN_SEP));
|
xstrtokenize(val.str, TOKEN_SEP));
|
||||||
break;
|
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:
|
case MATCH_TAG:
|
||||||
if (xf86getSubToken(&(ptr->comment)) != STRING)
|
if (xf86getSubToken(&(ptr->comment)) != STRING)
|
||||||
Error(QUOTE_MSG, "MatchTag");
|
Error(QUOTE_MSG, "MatchTag");
|
||||||
|
@ -283,6 +291,13 @@ xf86printInputClassSection (FILE * cf, XF86ConfInputClassPtr ptr)
|
||||||
*cur);
|
*cur);
|
||||||
fprintf(cf, "\"\n");
|
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) {
|
list_for_each_entry(group, &ptr->match_tag, entry) {
|
||||||
fprintf(cf, "\tMatchTag \"");
|
fprintf(cf, "\tMatchTag \"");
|
||||||
for (cur = group->values; *cur; cur++)
|
for (cur = group->values; *cur; cur++)
|
||||||
|
@ -363,6 +378,12 @@ xf86freeInputClassList (XF86ConfInputClassPtr ptr)
|
||||||
free(*list);
|
free(*list);
|
||||||
free(group);
|
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_for_each_entry_safe(group, next, &ptr->match_tag, entry) {
|
||||||
list_del(&group->entry);
|
list_del(&group->entry);
|
||||||
for (list = group->values; *list; list++)
|
for (list = group->values; *list; list++)
|
||||||
|
|
|
@ -357,6 +357,7 @@ typedef struct
|
||||||
struct list match_os;
|
struct list match_os;
|
||||||
struct list match_pnpid;
|
struct list match_pnpid;
|
||||||
struct list match_usbid;
|
struct list match_usbid;
|
||||||
|
struct list match_driver;
|
||||||
struct list match_tag;
|
struct list match_tag;
|
||||||
xf86TriState is_keyboard;
|
xf86TriState is_keyboard;
|
||||||
xf86TriState is_pointer;
|
xf86TriState is_pointer;
|
||||||
|
|
|
@ -282,6 +282,7 @@ typedef enum {
|
||||||
MATCH_OS,
|
MATCH_OS,
|
||||||
MATCH_PNPID,
|
MATCH_PNPID,
|
||||||
MATCH_USBID,
|
MATCH_USBID,
|
||||||
|
MATCH_DRIVER,
|
||||||
MATCH_TAG,
|
MATCH_TAG,
|
||||||
MATCH_IS_KEYBOARD,
|
MATCH_IS_KEYBOARD,
|
||||||
MATCH_IS_POINTER,
|
MATCH_IS_POINTER,
|
||||||
|
|
Loading…
Reference in New Issue