xfree86: Allow multiple InputClass Match* entries for && matching
Currently when there multiple InputClass entries of the same type, only the last entry is used and the previous ones are ignored. Instead, multiple entries are used to create multiple matching conditions. For instance, an InputClass with MatchProduct "foo" MatchProduct "bar" will require that the device's product name contain both foo and bar. This provides a complement to the || style matching when an entry is split using the "|" token. The xorg.conf man page has added an example to hopefully clarify the two types of compound matches. 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
8426259286
commit
a71bdff47d
|
@ -551,31 +551,44 @@ match_path_pattern(const char *attr, const char *pattern)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Match an attribute against a NULL terminated list of patterns. If any
|
* Match an attribute against a list of NULL terminated arrays of patterns.
|
||||||
* pattern is matched, return TRUE.
|
* If a pattern in each list entry is matched, return TRUE.
|
||||||
*/
|
*/
|
||||||
static Bool
|
static Bool
|
||||||
MatchAttrToken(const char *attr, char **patterns,
|
MatchAttrToken(const char *attr, struct list *patterns,
|
||||||
int (*compare)(const char *attr, const char *pattern))
|
int (*compare)(const char *attr, const char *pattern))
|
||||||
{
|
{
|
||||||
char **cur;
|
const xf86MatchGroup *group;
|
||||||
|
|
||||||
/* If there are no patterns, accept the match */
|
/* If there are no patterns, accept the match */
|
||||||
if (!patterns)
|
if (list_is_empty(patterns))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* If there are patterns but no attribute, reject the match */
|
/* If there are patterns but no attribute, reject the match */
|
||||||
if (!attr)
|
if (!attr)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Otherwise, iterate the patterns looking for a match */
|
/*
|
||||||
for (cur = patterns; *cur; cur++)
|
* Otherwise, iterate the list of patterns ensuring each entry has a
|
||||||
if ((*compare)(attr, *cur) == 0)
|
* match. Each list entry is a separate Match line of the same type.
|
||||||
return TRUE;
|
*/
|
||||||
|
list_for_each_entry(group, patterns, entry) {
|
||||||
|
char * const *cur;
|
||||||
|
Bool match = FALSE;
|
||||||
|
|
||||||
|
for (cur = group->values; *cur; cur++)
|
||||||
|
if ((*compare)(attr, *cur) == 0) {
|
||||||
|
match = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!match)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* All the entries in the list matched the attribute */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Classes without any Match statements match all devices. Otherwise, all
|
* Classes without any Match statements match all devices. Otherwise, all
|
||||||
* statements must match.
|
* statements must match.
|
||||||
|
@ -585,41 +598,41 @@ InputClassMatches(const XF86ConfInputClassPtr iclass,
|
||||||
const InputAttributes *attrs)
|
const InputAttributes *attrs)
|
||||||
{
|
{
|
||||||
/* MatchProduct substring */
|
/* MatchProduct substring */
|
||||||
if (!MatchAttrToken(attrs->product, iclass->match_product, match_substring))
|
if (!MatchAttrToken(attrs->product, &iclass->match_product, match_substring))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* MatchVendor substring */
|
/* MatchVendor substring */
|
||||||
if (!MatchAttrToken(attrs->vendor, iclass->match_vendor, match_substring))
|
if (!MatchAttrToken(attrs->vendor, &iclass->match_vendor, match_substring))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* MatchDevicePath pattern */
|
/* MatchDevicePath pattern */
|
||||||
if (!MatchAttrToken(attrs->device, iclass->match_device, match_path_pattern))
|
if (!MatchAttrToken(attrs->device, &iclass->match_device, match_path_pattern))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* MatchOS case-insensitive string */
|
/* MatchOS case-insensitive string */
|
||||||
if (!MatchAttrToken(HostOS(), iclass->match_os, strcasecmp))
|
if (!MatchAttrToken(HostOS(), &iclass->match_os, strcasecmp))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* MatchPnPID pattern */
|
/* MatchPnPID pattern */
|
||||||
if (!MatchAttrToken(attrs->pnp_id, iclass->match_pnpid, match_pattern))
|
if (!MatchAttrToken(attrs->pnp_id, &iclass->match_pnpid, match_pattern))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* MatchUSBID pattern */
|
/* MatchUSBID pattern */
|
||||||
if (!MatchAttrToken(attrs->usb_id, iclass->match_usbid, match_pattern))
|
if (!MatchAttrToken(attrs->usb_id, &iclass->match_usbid, match_pattern))
|
||||||
return FALSE;
|
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.
|
||||||
*/
|
*/
|
||||||
if (iclass->match_tag) {
|
if (!list_is_empty(&iclass->match_tag)) {
|
||||||
char * const *tag;
|
char * const *tag;
|
||||||
Bool match;
|
Bool match;
|
||||||
|
|
||||||
if (!attrs->tags)
|
if (!attrs->tags)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
for (tag = attrs->tags, match = FALSE; *tag; tag++) {
|
for (tag = attrs->tags, match = FALSE; *tag; tag++) {
|
||||||
if (MatchAttrToken(*tag, iclass->match_tag, strcmp)) {
|
if (MatchAttrToken(*tag, &iclass->match_tag, strcmp)) {
|
||||||
match = TRUE;
|
match = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1065,26 +1065,42 @@ of the class. If none of the optional entries appear, the
|
||||||
.B InputClass
|
.B InputClass
|
||||||
section is generic and will match any input device. If more than one of
|
section is generic and will match any input device. If more than one of
|
||||||
these entries appear, they all must match for the configuration to apply.
|
these entries appear, they all must match for the configuration to apply.
|
||||||
The allowed matching entries are shown below.
|
|
||||||
.PP
|
.PP
|
||||||
|
There are two types of match entries used in
|
||||||
|
.B InputClass
|
||||||
|
sections. The first allows various tokens to be matched against attributes
|
||||||
|
of the device. An entry can be constructed to match attributes from different
|
||||||
|
devices by separating arguments with a '|' character. Multiple entries of the
|
||||||
|
same type may be supplied to add multiple matching conditions on the same
|
||||||
|
attribute. For example:
|
||||||
|
.PP
|
||||||
|
.RS 4
|
||||||
|
.nf
|
||||||
|
.B "Section \*qInputClass\*q"
|
||||||
|
.B " Identifier \*qMy Class\*q"
|
||||||
|
.B " # product string must contain example and
|
||||||
|
.B " # either gizmo or gadget
|
||||||
|
.B " MatchProduct \*qexample\*q
|
||||||
|
.B " MatchProduct \*qgizmo|gadget\*q
|
||||||
|
.I " ..."
|
||||||
|
.B "EndSection"
|
||||||
|
.fi
|
||||||
|
.RE
|
||||||
.TP 7
|
.TP 7
|
||||||
.BI "MatchProduct \*q" matchproduct \*q
|
.BI "MatchProduct \*q" matchproduct \*q
|
||||||
This entry can be used to check if the substring
|
This entry can be used to check if the substring
|
||||||
.RI \*q matchproduct \*q
|
.RI \*q matchproduct \*q
|
||||||
occurs in the device's product name. Multiple substrings can be matched by
|
occurs in the device's product name.
|
||||||
separating arguments with a '|' character.
|
|
||||||
.TP 7
|
.TP 7
|
||||||
.BI "MatchVendor \*q" matchvendor \*q
|
.BI "MatchVendor \*q" matchvendor \*q
|
||||||
This entry can be used to check if the substring
|
This entry can be used to check if the substring
|
||||||
.RI \*q matchvendor \*q
|
.RI \*q matchvendor \*q
|
||||||
occurs in the device's vendor name. Multiple substrings can be matched by
|
occurs in the device's vendor name.
|
||||||
separating arguments with a '|' character.
|
|
||||||
.TP 7
|
.TP 7
|
||||||
.BI "MatchDevicePath \*q" matchdevice \*q
|
.BI "MatchDevicePath \*q" matchdevice \*q
|
||||||
This entry can be used to check if the device file matches the
|
This entry can be used to check if the device file matches the
|
||||||
.RI \*q matchdevice \*q
|
.RI \*q matchdevice \*q
|
||||||
pathname pattern. Multiple patterns can be matched by separating arguments
|
pathname pattern.
|
||||||
with a '|' character.
|
|
||||||
.TP 7
|
.TP 7
|
||||||
.BI "MatchOS \*q" matchos \*q
|
.BI "MatchOS \*q" matchos \*q
|
||||||
This entry can be used to check if the operating system matches the
|
This entry can be used to check if the operating system matches the
|
||||||
|
@ -1092,14 +1108,12 @@ case-insensitive
|
||||||
.RI \*q matchos \*q
|
.RI \*q matchos \*q
|
||||||
string. This entry is only supported on platforms providing the
|
string. This entry is only supported on platforms providing the
|
||||||
.BR uname (2)
|
.BR uname (2)
|
||||||
system call. Multiple operating systems can be matched by separating arguments
|
system call.
|
||||||
with a '|' character.
|
|
||||||
.TP 7
|
.TP 7
|
||||||
.BI "MatchPnPID \*q" matchpnp \*q
|
.BI "MatchPnPID \*q" matchpnp \*q
|
||||||
The device's Plug and Play (PnP) ID can be checked against the
|
The device's Plug and Play (PnP) ID can be checked against the
|
||||||
.RI \*q matchpnp \*q
|
.RI \*q matchpnp \*q
|
||||||
shell wildcard pattern. Multiple IDs can be matched by separating arguments
|
shell wildcard pattern.
|
||||||
with a '|' character.
|
|
||||||
.TP 7
|
.TP 7
|
||||||
.BI "MatchUSBID \*q" matchusb \*q
|
.BI "MatchUSBID \*q" matchusb \*q
|
||||||
The device's USB ID can be checked against the
|
The device's USB ID can be checked against the
|
||||||
|
@ -1107,17 +1121,20 @@ The device's USB ID can be checked against the
|
||||||
shell wildcard pattern. The ID is constructed as lowercase hexadecimal numbers
|
shell wildcard pattern. The ID is constructed as lowercase hexadecimal numbers
|
||||||
separated by a ':'. This is the same format as the
|
separated by a ':'. This is the same format as the
|
||||||
.BR lsusb (8)
|
.BR lsusb (8)
|
||||||
program. Multiple IDs can be matched by separating arguments with a '|'
|
program.
|
||||||
character.
|
|
||||||
.TP 7
|
.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
|
||||||
.RI \*q matchtag \*q
|
.RI \*q matchtag \*q
|
||||||
pattern. Multiple patterns can be matched by separating arguments
|
pattern. A match is found if at least one of the tags given in
|
||||||
with a '|' character. A match is found if at least one of the tags given in
|
|
||||||
.RI \*q matchtag \*q
|
.RI \*q matchtag \*q
|
||||||
matches at least one of the tags assigned by the backend.
|
matches at least one of the tags assigned by the backend.
|
||||||
|
.PP
|
||||||
|
The second type of entry is used to match device types. These entries take a
|
||||||
|
boolean argument similar to
|
||||||
|
.B Option
|
||||||
|
entries.
|
||||||
.TP 7
|
.TP 7
|
||||||
.BI "MatchIsKeyboard \*q" bool \*q
|
.BI "MatchIsKeyboard \*q" bool \*q
|
||||||
.TP 7
|
.TP 7
|
||||||
|
@ -1130,9 +1147,6 @@ matches at least one of the tags assigned by the backend.
|
||||||
.BI "MatchIsTouchpad \*q" bool \*q
|
.BI "MatchIsTouchpad \*q" bool \*q
|
||||||
.TP 7
|
.TP 7
|
||||||
.BI "MatchIsTouchscreen \*q" bool \*q
|
.BI "MatchIsTouchscreen \*q" bool \*q
|
||||||
Match device types. These entries take a boolean argument similar to
|
|
||||||
.B Option
|
|
||||||
entries.
|
|
||||||
.PP
|
.PP
|
||||||
When an input device has been matched to the
|
When an input device has been matched to the
|
||||||
.B InputClass
|
.B InputClass
|
||||||
|
|
|
@ -64,6 +64,18 @@ xf86ConfigSymTabRec InputClassTab[] =
|
||||||
|
|
||||||
#define TOKEN_SEP "|"
|
#define TOKEN_SEP "|"
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_group_entry(struct list *head, char **values)
|
||||||
|
{
|
||||||
|
xf86MatchGroup *group;
|
||||||
|
|
||||||
|
group = malloc(sizeof(*group));
|
||||||
|
if (group) {
|
||||||
|
group->values = values;
|
||||||
|
list_add(&group->entry, head);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
XF86ConfInputClassPtr
|
XF86ConfInputClassPtr
|
||||||
xf86parseInputClassSection(void)
|
xf86parseInputClassSection(void)
|
||||||
{
|
{
|
||||||
|
@ -72,6 +84,15 @@ xf86parseInputClassSection(void)
|
||||||
|
|
||||||
parsePrologue(XF86ConfInputClassPtr, XF86ConfInputClassRec)
|
parsePrologue(XF86ConfInputClassPtr, XF86ConfInputClassRec)
|
||||||
|
|
||||||
|
/* Initialize MatchGroup lists */
|
||||||
|
list_init(&ptr->match_product);
|
||||||
|
list_init(&ptr->match_vendor);
|
||||||
|
list_init(&ptr->match_device);
|
||||||
|
list_init(&ptr->match_os);
|
||||||
|
list_init(&ptr->match_pnpid);
|
||||||
|
list_init(&ptr->match_usbid);
|
||||||
|
list_init(&ptr->match_tag);
|
||||||
|
|
||||||
while ((token = xf86getToken(InputClassTab)) != ENDSECTION) {
|
while ((token = xf86getToken(InputClassTab)) != ENDSECTION) {
|
||||||
switch (token) {
|
switch (token) {
|
||||||
case COMMENT:
|
case COMMENT:
|
||||||
|
@ -99,37 +120,44 @@ xf86parseInputClassSection(void)
|
||||||
case MATCH_PRODUCT:
|
case MATCH_PRODUCT:
|
||||||
if (xf86getSubToken(&(ptr->comment)) != STRING)
|
if (xf86getSubToken(&(ptr->comment)) != STRING)
|
||||||
Error(QUOTE_MSG, "MatchProduct");
|
Error(QUOTE_MSG, "MatchProduct");
|
||||||
ptr->match_product = xstrtokenize(val.str, TOKEN_SEP);
|
add_group_entry(&ptr->match_product,
|
||||||
|
xstrtokenize(val.str, TOKEN_SEP));
|
||||||
break;
|
break;
|
||||||
case MATCH_VENDOR:
|
case MATCH_VENDOR:
|
||||||
if (xf86getSubToken(&(ptr->comment)) != STRING)
|
if (xf86getSubToken(&(ptr->comment)) != STRING)
|
||||||
Error(QUOTE_MSG, "MatchVendor");
|
Error(QUOTE_MSG, "MatchVendor");
|
||||||
ptr->match_vendor = xstrtokenize(val.str, TOKEN_SEP);
|
add_group_entry(&ptr->match_vendor,
|
||||||
|
xstrtokenize(val.str, TOKEN_SEP));
|
||||||
break;
|
break;
|
||||||
case MATCH_DEVICE_PATH:
|
case MATCH_DEVICE_PATH:
|
||||||
if (xf86getSubToken(&(ptr->comment)) != STRING)
|
if (xf86getSubToken(&(ptr->comment)) != STRING)
|
||||||
Error(QUOTE_MSG, "MatchDevicePath");
|
Error(QUOTE_MSG, "MatchDevicePath");
|
||||||
ptr->match_device = xstrtokenize(val.str, TOKEN_SEP);
|
add_group_entry(&ptr->match_device,
|
||||||
|
xstrtokenize(val.str, TOKEN_SEP));
|
||||||
break;
|
break;
|
||||||
case MATCH_OS:
|
case MATCH_OS:
|
||||||
if (xf86getSubToken(&(ptr->comment)) != STRING)
|
if (xf86getSubToken(&(ptr->comment)) != STRING)
|
||||||
Error(QUOTE_MSG, "MatchOS");
|
Error(QUOTE_MSG, "MatchOS");
|
||||||
ptr->match_os = xstrtokenize(val.str, TOKEN_SEP);
|
add_group_entry(&ptr->match_os,
|
||||||
|
xstrtokenize(val.str, TOKEN_SEP));
|
||||||
break;
|
break;
|
||||||
case MATCH_PNPID:
|
case MATCH_PNPID:
|
||||||
if (xf86getSubToken(&(ptr->comment)) != STRING)
|
if (xf86getSubToken(&(ptr->comment)) != STRING)
|
||||||
Error(QUOTE_MSG, "MatchPnPID");
|
Error(QUOTE_MSG, "MatchPnPID");
|
||||||
ptr->match_pnpid = xstrtokenize(val.str, TOKEN_SEP);
|
add_group_entry(&ptr->match_pnpid,
|
||||||
|
xstrtokenize(val.str, TOKEN_SEP));
|
||||||
break;
|
break;
|
||||||
case MATCH_USBID:
|
case MATCH_USBID:
|
||||||
if (xf86getSubToken(&(ptr->comment)) != STRING)
|
if (xf86getSubToken(&(ptr->comment)) != STRING)
|
||||||
Error(QUOTE_MSG, "MatchUSBID");
|
Error(QUOTE_MSG, "MatchUSBID");
|
||||||
ptr->match_usbid = xstrtokenize(val.str, TOKEN_SEP);
|
add_group_entry(&ptr->match_usbid,
|
||||||
|
xstrtokenize(val.str, TOKEN_SEP));
|
||||||
break;
|
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");
|
||||||
ptr->match_tag = xstrtokenize(val.str, TOKEN_SEP);
|
add_group_entry(&ptr->match_tag,
|
||||||
|
xstrtokenize(val.str, TOKEN_SEP));
|
||||||
break;
|
break;
|
||||||
case MATCH_IS_KEYBOARD:
|
case MATCH_IS_KEYBOARD:
|
||||||
if (xf86getSubToken(&(ptr->comment)) != STRING)
|
if (xf86getSubToken(&(ptr->comment)) != STRING)
|
||||||
|
@ -201,7 +229,8 @@ xf86parseInputClassSection(void)
|
||||||
void
|
void
|
||||||
xf86printInputClassSection (FILE * cf, XF86ConfInputClassPtr ptr)
|
xf86printInputClassSection (FILE * cf, XF86ConfInputClassPtr ptr)
|
||||||
{
|
{
|
||||||
char **list;
|
const xf86MatchGroup *group;
|
||||||
|
char * const *cur;
|
||||||
|
|
||||||
while (ptr) {
|
while (ptr) {
|
||||||
fprintf(cf, "Section \"InputClass\"\n");
|
fprintf(cf, "Section \"InputClass\"\n");
|
||||||
|
@ -211,62 +240,57 @@ xf86printInputClassSection (FILE * cf, XF86ConfInputClassPtr ptr)
|
||||||
fprintf(cf, "\tIdentifier \"%s\"\n", ptr->identifier);
|
fprintf(cf, "\tIdentifier \"%s\"\n", ptr->identifier);
|
||||||
if (ptr->driver)
|
if (ptr->driver)
|
||||||
fprintf(cf, "\tDriver \"%s\"\n", ptr->driver);
|
fprintf(cf, "\tDriver \"%s\"\n", ptr->driver);
|
||||||
if (ptr->match_product) {
|
|
||||||
|
list_for_each_entry(group, &ptr->match_product, entry) {
|
||||||
fprintf(cf, "\tMatchProduct \"");
|
fprintf(cf, "\tMatchProduct \"");
|
||||||
for (list = ptr->match_product; *list; list++)
|
for (cur = group->values; *cur; cur++)
|
||||||
fprintf(cf, "%s%s",
|
fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
|
||||||
list == ptr->match_product ? "" : TOKEN_SEP,
|
*cur);
|
||||||
*list);
|
|
||||||
fprintf(cf, "\"\n");
|
fprintf(cf, "\"\n");
|
||||||
}
|
}
|
||||||
if (ptr->match_vendor) {
|
list_for_each_entry(group, &ptr->match_vendor, entry) {
|
||||||
fprintf(cf, "\tMatchVendor \"");
|
fprintf(cf, "\tMatchVendor \"");
|
||||||
for (list = ptr->match_vendor; *list; list++)
|
for (cur = group->values; *cur; cur++)
|
||||||
fprintf(cf, "%s%s",
|
fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
|
||||||
list == ptr->match_vendor ? "" : TOKEN_SEP,
|
*cur);
|
||||||
*list);
|
|
||||||
fprintf(cf, "\"\n");
|
fprintf(cf, "\"\n");
|
||||||
}
|
}
|
||||||
if (ptr->match_device) {
|
list_for_each_entry(group, &ptr->match_device, entry) {
|
||||||
fprintf(cf, "\tMatchDevicePath \"");
|
fprintf(cf, "\tMatchDevicePath \"");
|
||||||
for (list = ptr->match_device; *list; list++)
|
for (cur = group->values; *cur; cur++)
|
||||||
fprintf(cf, "%s%s",
|
fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
|
||||||
list == ptr->match_device ? "" : TOKEN_SEP,
|
*cur);
|
||||||
*list);
|
|
||||||
fprintf(cf, "\"\n");
|
fprintf(cf, "\"\n");
|
||||||
}
|
}
|
||||||
if (ptr->match_os) {
|
list_for_each_entry(group, &ptr->match_os, entry) {
|
||||||
fprintf(cf, "\tMatchOS \"");
|
fprintf(cf, "\tMatchOS \"");
|
||||||
for (list = ptr->match_os; *list; list++)
|
for (cur = group->values; *cur; cur++)
|
||||||
fprintf(cf, "%s%s",
|
fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
|
||||||
list == ptr->match_os ? "" : TOKEN_SEP,
|
*cur);
|
||||||
*list);
|
|
||||||
fprintf(cf, "\"\n");
|
fprintf(cf, "\"\n");
|
||||||
}
|
}
|
||||||
if (ptr->match_pnpid) {
|
list_for_each_entry(group, &ptr->match_pnpid, entry) {
|
||||||
fprintf(cf, "\tMatchPnPID \"");
|
fprintf(cf, "\tMatchPnPID \"");
|
||||||
for (list = ptr->match_pnpid; *list; list++)
|
for (cur = group->values; *cur; cur++)
|
||||||
fprintf(cf, "%s%s",
|
fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
|
||||||
list == ptr->match_pnpid ? "" : TOKEN_SEP,
|
*cur);
|
||||||
*list);
|
|
||||||
fprintf(cf, "\"\n");
|
fprintf(cf, "\"\n");
|
||||||
}
|
}
|
||||||
if (ptr->match_usbid) {
|
list_for_each_entry(group, &ptr->match_usbid, entry) {
|
||||||
fprintf(cf, "\tMatchUSBID \"");
|
fprintf(cf, "\tMatchUSBID \"");
|
||||||
for (list = ptr->match_usbid; *list; list++)
|
for (cur = group->values; *cur; cur++)
|
||||||
fprintf(cf, "%s%s",
|
fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
|
||||||
list == ptr->match_usbid ? "" : TOKEN_SEP,
|
*cur);
|
||||||
*list);
|
|
||||||
fprintf(cf, "\"\n");
|
fprintf(cf, "\"\n");
|
||||||
}
|
}
|
||||||
if (ptr->match_tag) {
|
list_for_each_entry(group, &ptr->match_tag, entry) {
|
||||||
fprintf(cf, "\tMatchTag \"");
|
fprintf(cf, "\tMatchTag \"");
|
||||||
for (list = ptr->match_tag; *list; list++)
|
for (cur = group->values; *cur; cur++)
|
||||||
fprintf(cf, "%s%s",
|
fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
|
||||||
list == ptr->match_tag ? "" : TOKEN_SEP,
|
*cur);
|
||||||
*list);
|
|
||||||
fprintf(cf, "\"\n");
|
fprintf(cf, "\"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ptr->is_keyboard.set)
|
if (ptr->is_keyboard.set)
|
||||||
fprintf(cf, "\tIsKeyboard \"%s\"\n",
|
fprintf(cf, "\tIsKeyboard \"%s\"\n",
|
||||||
ptr->is_keyboard.val ? "yes" : "no");
|
ptr->is_keyboard.val ? "yes" : "no");
|
||||||
|
@ -295,46 +319,57 @@ void
|
||||||
xf86freeInputClassList (XF86ConfInputClassPtr ptr)
|
xf86freeInputClassList (XF86ConfInputClassPtr ptr)
|
||||||
{
|
{
|
||||||
XF86ConfInputClassPtr prev;
|
XF86ConfInputClassPtr prev;
|
||||||
char **list;
|
|
||||||
|
|
||||||
while (ptr) {
|
while (ptr) {
|
||||||
|
xf86MatchGroup *group, *next;
|
||||||
|
char **list;
|
||||||
|
|
||||||
TestFree(ptr->identifier);
|
TestFree(ptr->identifier);
|
||||||
TestFree(ptr->driver);
|
TestFree(ptr->driver);
|
||||||
if (ptr->match_product) {
|
|
||||||
for (list = ptr->match_product; *list; list++)
|
list_for_each_entry_safe(group, next, &ptr->match_product, entry) {
|
||||||
|
list_del(&group->entry);
|
||||||
|
for (list = group->values; *list; list++)
|
||||||
free(*list);
|
free(*list);
|
||||||
free(ptr->match_product);
|
free(group);
|
||||||
}
|
}
|
||||||
if (ptr->match_vendor) {
|
list_for_each_entry_safe(group, next, &ptr->match_vendor, entry) {
|
||||||
for (list = ptr->match_vendor; *list; list++)
|
list_del(&group->entry);
|
||||||
|
for (list = group->values; *list; list++)
|
||||||
free(*list);
|
free(*list);
|
||||||
free(ptr->match_vendor);
|
free(group);
|
||||||
}
|
}
|
||||||
if (ptr->match_device) {
|
list_for_each_entry_safe(group, next, &ptr->match_device, entry) {
|
||||||
for (list = ptr->match_device; *list; list++)
|
list_del(&group->entry);
|
||||||
|
for (list = group->values; *list; list++)
|
||||||
free(*list);
|
free(*list);
|
||||||
free(ptr->match_device);
|
free(group);
|
||||||
}
|
}
|
||||||
if (ptr->match_os) {
|
list_for_each_entry_safe(group, next, &ptr->match_os, entry) {
|
||||||
for (list = ptr->match_os; *list; list++)
|
list_del(&group->entry);
|
||||||
|
for (list = group->values; *list; list++)
|
||||||
free(*list);
|
free(*list);
|
||||||
free(ptr->match_os);
|
free(group);
|
||||||
}
|
}
|
||||||
if (ptr->match_pnpid) {
|
list_for_each_entry_safe(group, next, &ptr->match_pnpid, entry) {
|
||||||
for (list = ptr->match_pnpid; *list; list++)
|
list_del(&group->entry);
|
||||||
|
for (list = group->values; *list; list++)
|
||||||
free(*list);
|
free(*list);
|
||||||
free(ptr->match_pnpid);
|
free(group);
|
||||||
}
|
}
|
||||||
if (ptr->match_usbid) {
|
list_for_each_entry_safe(group, next, &ptr->match_usbid, entry) {
|
||||||
for (list = ptr->match_usbid; *list; list++)
|
list_del(&group->entry);
|
||||||
|
for (list = group->values; *list; list++)
|
||||||
free(*list);
|
free(*list);
|
||||||
free(ptr->match_usbid);
|
free(group);
|
||||||
}
|
}
|
||||||
if (ptr->match_tag) {
|
list_for_each_entry_safe(group, next, &ptr->match_tag, entry) {
|
||||||
for (list = ptr->match_tag; *list; list++)
|
list_del(&group->entry);
|
||||||
|
for (list = group->values; *list; list++)
|
||||||
free(*list);
|
free(*list);
|
||||||
free(ptr->match_tag);
|
free(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
TestFree(ptr->comment);
|
TestFree(ptr->comment);
|
||||||
xf86optionListFree(ptr->option_lst);
|
xf86optionListFree(ptr->option_lst);
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@
|
||||||
|
|
||||||
#include <X11/Xdefs.h>
|
#include <X11/Xdefs.h>
|
||||||
#include "xf86Optrec.h"
|
#include "xf86Optrec.h"
|
||||||
|
#include "list.h"
|
||||||
|
|
||||||
#define HAVE_PARSER_DECLS
|
#define HAVE_PARSER_DECLS
|
||||||
|
|
||||||
|
@ -338,18 +339,25 @@ typedef struct
|
||||||
}
|
}
|
||||||
xf86TriState;
|
xf86TriState;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
struct list entry;
|
||||||
|
char **values;
|
||||||
|
}
|
||||||
|
xf86MatchGroup;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
GenericListRec list;
|
GenericListRec list;
|
||||||
char *identifier;
|
char *identifier;
|
||||||
char *driver;
|
char *driver;
|
||||||
char **match_product;
|
struct list match_product;
|
||||||
char **match_vendor;
|
struct list match_vendor;
|
||||||
char **match_device;
|
struct list match_device;
|
||||||
char **match_os;
|
struct list match_os;
|
||||||
char **match_pnpid;
|
struct list match_pnpid;
|
||||||
char **match_usbid;
|
struct list match_usbid;
|
||||||
char **match_tag;
|
struct list match_tag;
|
||||||
xf86TriState is_keyboard;
|
xf86TriState is_keyboard;
|
||||||
xf86TriState is_pointer;
|
xf86TriState is_pointer;
|
||||||
xf86TriState is_joystick;
|
xf86TriState is_joystick;
|
||||||
|
|
Loading…
Reference in New Issue