[PATCH v2 07/11] xfree86: Match devices based on PnP ID
Peter Hutterer
peter.hutterer at who-t.net
Wed Jun 9 21:48:48 PDT 2010
On Mon, Jun 07, 2010 at 08:39:54PM -0700, Dan Nicholson wrote:
> Serial input devices lack properties such as product or vendor name. This
> makes matching InputClass sections difficult. Add a MatchPnPID entry to
> test against the PnP ID of the device. The entry supports a shell pattern
> match on platforms that support fnmatch(3). For example:
>
> MatchPnPID "WACf*"
>
> A match type for non-path pattern matching, MatchPattern, has been added.
^ match_pattern, right?
I amended this locally, don't worry about resending.
Cheers,
Peter
> The difference between this and MatchPathPattern is the FNM_PATHNAME flag
> in fnmatch(3).
>
> Signed-off-by: Dan Nicholson <dbn.lists at gmail.com>
> ---
> config/hal.c | 9 ++++++++-
> config/udev.c | 3 +++
> dix/inpututils.c | 3 +++
> hw/xfree86/common/xf86Xinput.c | 14 ++++++++++++++
> hw/xfree86/doc/man/xorg.conf.man.pre | 6 ++++++
> hw/xfree86/parser/InputClass.c | 19 +++++++++++++++++++
> hw/xfree86/parser/xf86Parser.h | 1 +
> hw/xfree86/parser/xf86tokens.h | 1 +
> include/input.h | 1 +
> test/input.c | 12 ++++++++++++
> 10 files changed, 68 insertions(+), 1 deletions(-)
>
> diff --git a/config/hal.c b/config/hal.c
> index e3e5581..a5cc133 100644
> --- a/config/hal.c
> +++ b/config/hal.c
> @@ -129,7 +129,7 @@ static void
> device_added(LibHalContext *hal_ctx, const char *udi)
> {
> char *path = NULL, *driver = NULL, *name = NULL, *config_info = NULL;
> - char *hal_tags;
> + char *hal_tags, *parent;
> InputOption *options = NULL, *tmpo = NULL;
> InputAttributes attrs = {0};
> DeviceIntPtr dev = NULL;
> @@ -182,6 +182,12 @@ device_added(LibHalContext *hal_ctx, const char *udi)
> if (libhal_device_query_capability(hal_ctx, udi, "input.touchscreen", NULL))
> attrs.flags |= ATTR_TOUCHSCREEN;
>
> + parent = get_prop_string(hal_ctx, udi, "info.parent");
> + if (parent) {
> + attrs.pnp_id = get_prop_string(hal_ctx, parent, "pnp.id");
> + free(parent);
> + }
> +
> options = calloc(sizeof(*options), 1);
> if (!options){
> LogMessage(X_ERROR, "config/hal: couldn't allocate space for input options!\n");
> @@ -395,6 +401,7 @@ unwind:
> free(attrs.product);
> free(attrs.vendor);
> free(attrs.device);
> + free(attrs.pnp_id);
> if (attrs.tags) {
> char **tag = attrs.tags;
> while (*tag) {
> diff --git a/config/udev.c b/config/udev.c
> index 5d001de..f7ed4b2 100644
> --- a/config/udev.c
> +++ b/config/udev.c
> @@ -99,6 +99,9 @@ device_added(struct udev_device *udev_device)
> name = udev_device_get_property_value(parent, "NAME");
> LOG_PROPERTY(ppath, "NAME", name);
> }
> +
> + attrs.pnp_id = udev_device_get_sysattr_value(parent, "id");
> + LOG_SYSATTR(ppath, "id", attrs.pnp_id);
> }
> if (!name)
> name = "(unnamed)";
> diff --git a/dix/inpututils.c b/dix/inpututils.c
> index df2ace0..aa240dd 100644
> --- a/dix/inpututils.c
> +++ b/dix/inpututils.c
> @@ -357,6 +357,8 @@ DuplicateInputAttributes(InputAttributes *attrs)
> goto unwind;
> if (attrs->device && !(new_attr->device = strdup(attrs->device)))
> goto unwind;
> + if (attrs->pnp_id && !(new_attr->pnp_id = strdup(attrs->pnp_id)))
> + goto unwind;
>
> new_attr->flags = attrs->flags;
>
> @@ -401,6 +403,7 @@ FreeInputAttributes(InputAttributes *attrs)
> free(attrs->product);
> free(attrs->vendor);
> free(attrs->device);
> + free(attrs->pnp_id);
>
> if ((tags = attrs->tags))
> while(*tags)
> diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
> index 8414934..0bac0b4 100644
> --- a/hw/xfree86/common/xf86Xinput.c
> +++ b/hw/xfree86/common/xf86Xinput.c
> @@ -532,6 +532,16 @@ match_substring(const char *attr, const char *pattern)
>
> #ifdef HAVE_FNMATCH_H
> static int
> +match_pattern(const char *attr, const char *pattern)
> +{
> + return fnmatch(pattern, attr, 0);
> +}
> +#else
> +#define match_pattern match_substring
> +#endif
> +
> +#ifdef HAVE_FNMATCH_H
> +static int
> match_path_pattern(const char *attr, const char *pattern)
> {
> return fnmatch(pattern, attr, FNM_PATHNAME);
> @@ -590,6 +600,10 @@ InputClassMatches(const XF86ConfInputClassPtr iclass,
> if (!MatchAttrToken(HostOS(), iclass->match_os, strcasecmp))
> return FALSE;
>
> + /* MatchPnPID pattern */
> + if (!MatchAttrToken(attrs->pnp_id, iclass->match_pnpid, match_pattern))
> + return FALSE;
> +
> /*
> * MatchTag string
> * See if any of the device's tags match any of the MatchTag tokens.
> diff --git a/hw/xfree86/doc/man/xorg.conf.man.pre b/hw/xfree86/doc/man/xorg.conf.man.pre
> index 50d4f36..c17ecb9 100644
> --- a/hw/xfree86/doc/man/xorg.conf.man.pre
> +++ b/hw/xfree86/doc/man/xorg.conf.man.pre
> @@ -1095,6 +1095,12 @@ string. This entry is only supported on platforms providing the
> system call. Multiple operating systems can be matched by separating arguments
> with a '|' character.
> .TP 7
> +.BI "MatchPnPID \*q" matchpnp \*q
> +The device's Plug and Play (PnP) ID can be checked against the
> +.RI \*q matchpnp \*q
> +shell wildcard pattern. Multiple IDs can be matched by separating arguments
> +with a '|' character.
> +.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 20ebfb5..e5ef96c 100644
> --- a/hw/xfree86/parser/InputClass.c
> +++ b/hw/xfree86/parser/InputClass.c
> @@ -48,6 +48,7 @@ xf86ConfigSymTabRec InputClassTab[] =
> {MATCH_VENDOR, "matchvendor"},
> {MATCH_DEVICE_PATH, "matchdevicepath"},
> {MATCH_OS, "matchos"},
> + {MATCH_PNPID, "matchpnpid"},
> {MATCH_TAG, "matchtag"},
> {MATCH_IS_KEYBOARD, "matchiskeyboard"},
> {MATCH_IS_POINTER, "matchispointer"},
> @@ -114,6 +115,11 @@ xf86parseInputClassSection(void)
> Error(QUOTE_MSG, "MatchOS");
> ptr->match_os = xstrtokenize(val.str, TOKEN_SEP);
> break;
> + case MATCH_PNPID:
> + if (xf86getSubToken(&(ptr->comment)) != STRING)
> + Error(QUOTE_MSG, "MatchPnPID");
> + ptr->match_pnpid = xstrtokenize(val.str, TOKEN_SEP);
> + break;
> case MATCH_TAG:
> if (xf86getSubToken(&(ptr->comment)) != STRING)
> Error(QUOTE_MSG, "MatchTag");
> @@ -231,6 +237,14 @@ xf86printInputClassSection (FILE * cf, XF86ConfInputClassPtr ptr)
> *list);
> fprintf(cf, "\"\n");
> }
> + if (ptr->match_pnpid) {
> + fprintf(cf, "\tMatchPnPID \"");
> + for (list = ptr->match_pnpid; *list; list++)
> + fprintf(cf, "%s%s",
> + list == ptr->match_pnpid ? "" : TOKEN_SEP,
> + *list);
> + fprintf(cf, "\"\n");
> + }
> if (ptr->match_tag) {
> fprintf(cf, "\tMatchTag \"");
> for (list = ptr->match_tag; *list; list++)
> @@ -292,6 +306,11 @@ xf86freeInputClassList (XF86ConfInputClassPtr ptr)
> free(*list);
> free(ptr->match_os);
> }
> + if (ptr->match_pnpid) {
> + for (list = ptr->match_pnpid; *list; list++)
> + free(*list);
> + free(ptr->match_pnpid);
> + }
> if (ptr->match_tag) {
> for (list = ptr->match_tag; *list; list++)
> free(*list);
> diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
> index 3623ca1..87fc31c 100644
> --- a/hw/xfree86/parser/xf86Parser.h
> +++ b/hw/xfree86/parser/xf86Parser.h
> @@ -347,6 +347,7 @@ typedef struct
> char **match_vendor;
> char **match_device;
> char **match_os;
> + char **match_pnpid;
> char **match_tag;
> xf86TriState is_keyboard;
> xf86TriState is_pointer;
> diff --git a/hw/xfree86/parser/xf86tokens.h b/hw/xfree86/parser/xf86tokens.h
> index fd13d6d..aa33935 100644
> --- a/hw/xfree86/parser/xf86tokens.h
> +++ b/hw/xfree86/parser/xf86tokens.h
> @@ -280,6 +280,7 @@ typedef enum {
> MATCH_VENDOR,
> MATCH_DEVICE_PATH,
> MATCH_OS,
> + MATCH_PNPID,
> MATCH_TAG,
> MATCH_IS_KEYBOARD,
> MATCH_IS_POINTER,
> diff --git a/include/input.h b/include/input.h
> index c68a284..5969693 100644
> --- a/include/input.h
> +++ b/include/input.h
> @@ -215,6 +215,7 @@ typedef struct _InputAttributes {
> char *product;
> char *vendor;
> char *device;
> + char *pnp_id;
> char **tags; /* null-terminated */
> uint32_t flags;
> } InputAttributes;
> diff --git a/test/input.c b/test/input.c
> index 8a54af9..3ec930a 100644
> --- a/test/input.c
> +++ b/test/input.c
> @@ -801,6 +801,13 @@ static void cmp_attr_fields(InputAttributes *attr1,
> } else
> g_assert(attr2->device == NULL);
>
> + if (attr1->pnp_id != NULL)
> + {
> + g_assert(attr1->pnp_id != attr2->pnp_id);
> + g_assert(strcmp(attr1->pnp_id, attr2->pnp_id) == 0);
> + } else
> + g_assert(attr2->pnp_id == NULL);
> +
> tags1 = attr1->tags;
> tags2 = attr2->tags;
> if (!tags1)
> @@ -859,6 +866,11 @@ static void dix_input_attributes(void)
> cmp_attr_fields(&orig, new);
> FreeInputAttributes(new);
>
> + orig.pnp_id = "PnPID";
> + new = DuplicateInputAttributes(&orig);
> + cmp_attr_fields(&orig, new);
> + FreeInputAttributes(new);
> +
> orig.flags = 0xF0;
> new = DuplicateInputAttributes(&orig);
> cmp_attr_fields(&orig, new);
> --
> 1.6.6.1
>
More information about the xorg-devel
mailing list