diff options
author | Dan Nicholson <dbn.lists@gmail.com> | 2010-02-10 15:36:47 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2010-02-11 19:25:32 +1000 |
commit | 9b369f71273fb117c982e6ce16cd4462f206d365 (patch) | |
tree | cb2215696551f1896cdb0560b53be93f45b2a644 | |
parent | a378e361a5de89f0be8b68ebc3e854f56cefe666 (diff) |
xfree86: Allow multiple arguments to InputClass matches
In order to keep the number of InputClass sections manageable, allow
matches to contain multiple arguments. The arguments will be separated
by the '|' character. This allows a policy to apply to multiple types of
devices. For example:
Section "InputClass"
Identifier "Inverted Mice"
MatchProduct "Crazy Mouse|Silly Mouse"
Option "InvertX" "yes"
EndSection
This applies to the MatchProduct, MatchVendor and MatchDevicePath
entries. Currently there is no way to escape characters, so names or
patterns cannot contain '|'.
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>
-rw-r--r-- | hw/xfree86/common/xf86Xinput.c | 51 | ||||
-rw-r--r-- | hw/xfree86/doc/man/xorg.conf.man.pre | 9 | ||||
-rw-r--r-- | hw/xfree86/parser/InputClass.c | 99 | ||||
-rw-r--r-- | hw/xfree86/parser/xf86Parser.h | 6 |
4 files changed, 136 insertions, 29 deletions
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c index b37dae62a..8ac9d268f 100644 --- a/hw/xfree86/common/xf86Xinput.c +++ b/hw/xfree86/common/xf86Xinput.c @@ -502,20 +502,49 @@ AddOtherInputDevices(void) static Bool InputClassMatches(XF86ConfInputClassPtr iclass, InputAttributes *attrs) { - if (iclass->match_product && - (!attrs->product || !strstr(attrs->product, iclass->match_product))) - return FALSE; - if (iclass->match_vendor && - (!attrs->vendor || !strstr(attrs->vendor, iclass->match_vendor))) - return FALSE; - if (iclass->match_device && + char **cur; + Bool match; + + if (iclass->match_product) { + if (!attrs->product) + return FALSE; + /* see if any of the values match */ + for (cur = iclass->match_product, match = FALSE; *cur; cur++) + if (strstr(attrs->product, *cur)) { + match = TRUE; + break; + } + if (!match) + return FALSE; + } + if (iclass->match_vendor) { + if (!attrs->vendor) + return FALSE; + /* see if any of the values match */ + for (cur = iclass->match_vendor, match = FALSE; *cur; cur++) + if (strstr(attrs->vendor, *cur)) { + match = TRUE; + break; + } + if (!match) + return FALSE; + } + if (iclass->match_device) { + if (!attrs->device) + return FALSE; + /* see if any of the values match */ + for (cur = iclass->match_device, match = FALSE; *cur; cur++) #ifdef HAVE_FNMATCH_H - (!attrs->device || - fnmatch(iclass->match_device, attrs->device, 0) != 0)) + if (fnmatch(*cur, attrs->device, 0) == 0) { #else - (!attrs->device || !strstr(attrs->device, iclass->match_device))) + if (strstr(attrs->device, *cur)) { #endif - return FALSE; + 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 ee91b9afe..69f475107 100644 --- a/hw/xfree86/doc/man/xorg.conf.man.pre +++ b/hw/xfree86/doc/man/xorg.conf.man.pre @@ -1039,17 +1039,20 @@ The allowed matching entries are shown below. .BI "MatchProduct \*q" matchproduct \*q This entry can be used to check if the substring .RI \*q matchproduct \*q -occurs in the device's product name. +occurs in the device's product name. Multiple substrings can be matched by +separating arguments with a '|' character. .TP 7 .BI "MatchVendor \*q" matchvendor \*q This entry can be used to check if the substring .RI \*q matchvendor \*q -occurs in the device's vendor name. +occurs in the device's vendor name. Multiple substrings can be matched by +separating arguments with a '|' character. .TP 7 .BI "MatchDevicePath \*q" matchdevice \*q This entry can be used to check if the device file matches the .RI \*q matchdevice \*q -pathname pattern. +pathname pattern. Multiple patterns can be matched by separating arguments +with a '|' character. .TP 7 .BI "MatchIsKeyboard \*q" bool \*q .TP 7 diff --git a/hw/xfree86/parser/InputClass.c b/hw/xfree86/parser/InputClass.c index 1c9816012..8041740a8 100644 --- a/hw/xfree86/parser/InputClass.c +++ b/hw/xfree86/parser/InputClass.c @@ -29,6 +29,8 @@ #include <xorg-config.h> #endif +#include <string.h> +#include "os.h" #include "xf86Parser.h" #include "xf86tokens.h" #include "Configint.h" @@ -56,6 +58,46 @@ xf86ConfigSymTabRec InputClassTab[] = #define CLEANUP xf86freeInputClassList +#define TOKEN_SEP "|" + +/* + * Tokenize a string into a NULL terminated array of strings. Always returns + * an allocated array unless an error occurs. + */ +static char ** +tokenize(const char *str) +{ + char **list, **nlist; + char *tok, *tmp; + unsigned num = 0, n; + + list = calloc(1, sizeof(*list)); + if (!list) + return NULL; + tmp = strdup(str); + if (!tmp) + goto error; + for (tok = strtok(tmp, TOKEN_SEP); tok; tok = strtok(NULL, TOKEN_SEP)) { + nlist = realloc(list, (num + 2) * sizeof(*list)); + if (!nlist) + goto error; + list = nlist; + list[num] = strdup(tok); + if (!list[num]) + goto error; + list[++num] = NULL; + } + free(tmp); + return list; + +error: + TestFree(tmp); + for (n = 0; n < num; n++) + free(list[n]); + TestFree(list); + return NULL; +} + XF86ConfInputClassPtr xf86parseInputClassSection(void) { @@ -91,17 +133,17 @@ xf86parseInputClassSection(void) case MATCH_PRODUCT: if (xf86getSubToken(&(ptr->comment)) != STRING) Error(QUOTE_MSG, "MatchProduct"); - ptr->match_product = val.str; + ptr->match_product = tokenize(val.str); break; case MATCH_VENDOR: if (xf86getSubToken(&(ptr->comment)) != STRING) Error(QUOTE_MSG, "MatchVendor"); - ptr->match_vendor = val.str; + ptr->match_vendor = tokenize(val.str); break; case MATCH_DEVICE_PATH: if (xf86getSubToken(&(ptr->comment)) != STRING) Error(QUOTE_MSG, "MatchDevicePath"); - ptr->match_device = val.str; + ptr->match_device = tokenize(val.str); break; case MATCH_IS_KEYBOARD: if (xf86getSubToken(&(ptr->comment)) != STRING) @@ -173,6 +215,8 @@ xf86parseInputClassSection(void) void xf86printInputClassSection (FILE * cf, XF86ConfInputClassPtr ptr) { + char **list; + while (ptr) { fprintf(cf, "Section \"InputClass\"\n"); if (ptr->comment) @@ -181,12 +225,30 @@ xf86printInputClassSection (FILE * cf, XF86ConfInputClassPtr ptr) fprintf(cf, "\tIdentifier \"%s\"\n", ptr->identifier); if (ptr->driver) fprintf(cf, "\tDriver \"%s\"\n", ptr->driver); - if (ptr->match_product) - fprintf(cf, "\tMatchProduct \"%s\"\n", ptr->match_product); - if (ptr->match_vendor) - fprintf(cf, "\tMatchVendor \"%s\"\n", ptr->match_vendor); - if (ptr->match_device) - fprintf(cf, "\tMatchDevicePath \"%s\"\n", ptr->match_device); + if (ptr->match_product) { + fprintf(cf, "\tMatchProduct \""); + for (list = ptr->match_product; *list; list++) + fprintf(cf, "%s%s", + list == ptr->match_product ? "" : TOKEN_SEP, + *list); + fprintf(cf, "\"\n"); + } + if (ptr->match_vendor) { + fprintf(cf, "\tMatchVendor \""); + for (list = ptr->match_vendor; *list; list++) + fprintf(cf, "%s%s", + list == ptr->match_vendor ? "" : TOKEN_SEP, + *list); + fprintf(cf, "\"\n"); + } + if (ptr->match_device) { + fprintf(cf, "\tMatchDevicePath \""); + for (list = ptr->match_device; *list; list++) + fprintf(cf, "%s%s", + list == ptr->match_device ? "" : TOKEN_SEP, + *list); + fprintf(cf, "\"\n"); + } if (ptr->is_keyboard.set) fprintf(cf, "\tIsKeyboard \"%s\"\n", ptr->is_keyboard.val ? "yes" : "no"); @@ -215,13 +277,26 @@ void xf86freeInputClassList (XF86ConfInputClassPtr ptr) { XF86ConfInputClassPtr prev; + char **list; while (ptr) { TestFree(ptr->identifier); TestFree(ptr->driver); - TestFree(ptr->match_product); - TestFree(ptr->match_vendor); - TestFree(ptr->match_device); + if (ptr->match_product) { + for (list = ptr->match_product; *list; list++) + free(*list); + free(ptr->match_product); + } + if (ptr->match_vendor) { + for (list = ptr->match_vendor; *list; list++) + free(*list); + free(ptr->match_vendor); + } + if (ptr->match_device) { + for (list = ptr->match_device; *list; list++) + free(*list); + free(ptr->match_device); + } TestFree(ptr->comment); xf86optionListFree(ptr->option_lst); diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h index 5e8351fc4..b6d40a1f3 100644 --- a/hw/xfree86/parser/xf86Parser.h +++ b/hw/xfree86/parser/xf86Parser.h @@ -343,9 +343,9 @@ typedef struct GenericListRec list; char *identifier; char *driver; - char *match_product; - char *match_vendor; - char *match_device; + char **match_product; + char **match_vendor; + char **match_device; xf86TriState is_keyboard; xf86TriState is_pointer; xf86TriState is_joystick; |