[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