[PATCH v2 07/11] xfree86: Match devices based on PnP ID
Dan Nicholson
dbn.lists at gmail.com
Mon Jun 7 06:49:07 PDT 2010
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, match_pattern, has been added.
The difference between this and match_path_pattern 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 e0ff842..8061020 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");
@@ -384,6 +390,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 0f6ccc1..5b0ec8f 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 12771c5..dd197dd 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;
@@ -866,6 +873,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