[PATCH xserver] xfree86: add NoMatchFoo directives for InputClass sections
Benjamin Tissoires
benjamin.tissoires at gmail.com
Fri Dec 11 00:58:34 PST 2015
Hi Peter,
On Fri, Dec 11, 2015 at 12:58 AM, Peter Hutterer
<peter.hutterer at who-t.net> wrote:
> InputClass sections use various MatchFoo directives to decide which device to
> apply to. This usually works fine for specific snippets but has drawbacks for
> snippets that apply more generally to a multitude of devices.
>
> This patch adds a NoMatchFoo directive to negate a match, thus allowing
> snippets that only apply if a given condition is not set. Specifically, this
> allows for more flexible fallback driver matching, it is now possible to use a
> snippet that says "assign driver foo, but only if driver bar wasn't already
> assigned to it". For example:
>
> Section "InputClass"
> Identifier "libinput for tablets"
> MatchIsTablet "true"
> NoMatchDriver "wacom"
> Driver "libinput"
> EndSection
>
> The above only assigns libinput to tablet devices if wacom isn't already
> assigned to this device, making it possible to select a specific driver by
> installing/uninstalling it.
>
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
Thanks, that was quicker than expected :)
Just 2 nitpicks/questions:
> ---
> hw/xfree86/common/xf86Xinput.c | 15 +++++----
> hw/xfree86/man/xorg.conf.man | 15 +++++++++
> hw/xfree86/parser/InputClass.c | 76 ++++++++++++++++++++++++++++++++++++------
> hw/xfree86/parser/xf86Parser.h | 1 +
> hw/xfree86/parser/xf86tokens.h | 12 ++++++-
> 5 files changed, 102 insertions(+), 17 deletions(-)
>
> diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
> index c56a2b9..fead782 100644
> --- a/hw/xfree86/common/xf86Xinput.c
> +++ b/hw/xfree86/common/xf86Xinput.c
> @@ -540,21 +540,24 @@ MatchAttrToken(const char *attr, struct xorg_list *patterns,
> if (xorg_list_is_empty(patterns))
> return TRUE;
>
> - /* If there are patterns but no attribute, reject the match */
> - if (!attr)
> - return FALSE;
> -
> /*
> * Otherwise, iterate the list of patterns ensuring each entry has a
If we remove the previous comment, we should probably remove the
"Otherwise" here.
> * match. Each list entry is a separate Match line of the same type.
> */
> xorg_list_for_each_entry(group, patterns, entry) {
> char *const *cur;
> - Bool match = FALSE;
> + Bool is_negated = group->is_negated;
> + Bool match = is_negated;
> +
> + /* If there's a pattern but no attribute, we reject the match for a
> + * MatchFoo directive, and accept it for a NoMatchFoo directive
> + */
I don't follow the logic here. Can you explain why a MatchFoo would be
rejected while a NoMatchFoo won't? I can't find an example for this
situation.
The rest of the patch looks good to me.
Cheers,
Benjamin
> + if (!attr)
> + return is_negated;
>
> for (cur = group->values; *cur; cur++)
> if ((*compare) (attr, *cur) == 0) {
> - match = TRUE;
> + match = !is_negated;
> break;
> }
> if (!match)
> diff --git a/hw/xfree86/man/xorg.conf.man b/hw/xfree86/man/xorg.conf.man
> index 08eb7a9..d794df4 100644
> --- a/hw/xfree86/man/xorg.conf.man
> +++ b/hw/xfree86/man/xorg.conf.man
> @@ -1092,6 +1092,7 @@ attribute. For example:
> .B " # either gizmo or gadget
> .B " MatchProduct \*qexample\*q
> .B " MatchProduct \*qgizmo|gadget\*q
> +.B " NoMatchDriver \*qdrivername\*q
> .I " ..."
> .B "EndSection"
> .fi
> @@ -1160,6 +1161,20 @@ if no named
> .B ServerLayout
> sections have been found.
> .PP
> +The above directives have equivalents for negative matching with the
> +.B NoMatchProduct,
> +.B NoMatchVendor,
> +.B NoMatchDevicePath,
> +.B NoMatchOS,
> +.B NoMatchPnPID,
> +.B NoMatchUSBID,
> +.B NoMatchDriver,
> +.B NoMatchTag,
> +and
> +.B NoMatchLayout
> +directives. These NoMatch directives match if the subsequent match is not
> +met by the device.
> +.PP
> The second type of entry is used to match device types. These entries take a
> boolean argument similar to
> .B Option
> diff --git a/hw/xfree86/parser/InputClass.c b/hw/xfree86/parser/InputClass.c
> index 2b68aaa..5d3b59c 100644
> --- a/hw/xfree86/parser/InputClass.c
> +++ b/hw/xfree86/parser/InputClass.c
> @@ -55,6 +55,15 @@ xf86ConfigSymTabRec InputClassTab[] = {
> {MATCH_IS_TABLET, "matchistablet"},
> {MATCH_IS_TOUCHPAD, "matchistouchpad"},
> {MATCH_IS_TOUCHSCREEN, "matchistouchscreen"},
> + {NOMATCH_PRODUCT, "nomatchproduct"},
> + {NOMATCH_VENDOR, "nomatchvendor"},
> + {NOMATCH_DEVICE_PATH, "nomatchdevicepath"},
> + {NOMATCH_OS, "nomatchos"},
> + {NOMATCH_PNPID, "nomatchpnpid"},
> + {NOMATCH_USBID, "nomatchusbid"},
> + {NOMATCH_DRIVER, "nomatchdriver"},
> + {NOMATCH_TAG, "nomatchtag"},
> + {NOMATCH_LAYOUT, "nomatchlayout"},
> {-1, ""},
> };
>
> @@ -138,13 +147,19 @@ xf86freeInputClassList(XF86ConfInputClassPtr ptr)
>
> #define TOKEN_SEP "|"
>
> +enum MatchType {
> + MATCH_NORMAL,
> + MATCH_NEGATED,
> +};
> +
> static void
> -add_group_entry(struct xorg_list *head, char **values)
> +add_group_entry(struct xorg_list *head, char **values, enum MatchType type)
> {
> xf86MatchGroup *group;
>
> group = malloc(sizeof(*group));
> if (group) {
> + group->is_negated = (type == MATCH_NEGATED);
> group->values = values;
> xorg_list_add(&group->entry, head);
> }
> @@ -155,6 +170,7 @@ xf86parseInputClassSection(void)
> {
> int has_ident = FALSE;
> int token;
> + enum MatchType matchtype;
>
> parsePrologue(XF86ConfInputClassPtr, XF86ConfInputClassRec)
>
> @@ -170,6 +186,8 @@ xf86parseInputClassSection(void)
> xorg_list_init(&ptr->match_layout);
>
> while ((token = xf86getToken(InputClassTab)) != ENDSECTION) {
> + matchtype = MATCH_NORMAL;
> +
> switch (token) {
> case COMMENT:
> ptr->comment = xf86addComment(ptr->comment, xf86_lex_val.str);
> @@ -195,65 +213,103 @@ xf86parseInputClassSection(void)
> case OPTION:
> ptr->option_lst = xf86parseOption(ptr->option_lst);
> break;
> + case NOMATCH_PRODUCT:
> + matchtype = MATCH_NEGATED;
> + /* fallthrough */
> case MATCH_PRODUCT:
> if (xf86getSubToken(&(ptr->comment)) != STRING)
> Error(QUOTE_MSG, "MatchProduct");
> add_group_entry(&ptr->match_product,
> - xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
> + xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
> + matchtype);
> free(xf86_lex_val.str);
> break;
> + case NOMATCH_VENDOR:
> + matchtype = MATCH_NEGATED;
> + /* fallthrough */
> case MATCH_VENDOR:
> if (xf86getSubToken(&(ptr->comment)) != STRING)
> Error(QUOTE_MSG, "MatchVendor");
> add_group_entry(&ptr->match_vendor,
> - xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
> + xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
> + matchtype);
> free(xf86_lex_val.str);
> break;
> + case NOMATCH_DEVICE_PATH:
> + matchtype = MATCH_NEGATED;
> + /* fallthrough */
> case MATCH_DEVICE_PATH:
> if (xf86getSubToken(&(ptr->comment)) != STRING)
> Error(QUOTE_MSG, "MatchDevicePath");
> add_group_entry(&ptr->match_device,
> - xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
> + xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
> + matchtype);
> free(xf86_lex_val.str);
> break;
> + case NOMATCH_OS:
> + matchtype = MATCH_NEGATED;
> + /* fallthrough */
> case MATCH_OS:
> if (xf86getSubToken(&(ptr->comment)) != STRING)
> Error(QUOTE_MSG, "MatchOS");
> - add_group_entry(&ptr->match_os, xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
> + add_group_entry(&ptr->match_os, xstrtokenize(xf86_lex_val.str,
> + TOKEN_SEP),
> + matchtype);
> free(xf86_lex_val.str);
> break;
> + case NOMATCH_PNPID:
> + matchtype = MATCH_NEGATED;
> + /* fallthrough */
> case MATCH_PNPID:
> if (xf86getSubToken(&(ptr->comment)) != STRING)
> Error(QUOTE_MSG, "MatchPnPID");
> add_group_entry(&ptr->match_pnpid,
> - xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
> + xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
> + matchtype);
> free(xf86_lex_val.str);
> break;
> + case NOMATCH_USBID:
> + matchtype = MATCH_NEGATED;
> + /* fallthrough */
> case MATCH_USBID:
> if (xf86getSubToken(&(ptr->comment)) != STRING)
> Error(QUOTE_MSG, "MatchUSBID");
> add_group_entry(&ptr->match_usbid,
> - xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
> + xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
> + matchtype);
> free(xf86_lex_val.str);
> break;
> + case NOMATCH_DRIVER:
> + matchtype = MATCH_NEGATED;
> + /* fallthrough */
> case MATCH_DRIVER:
> if (xf86getSubToken(&(ptr->comment)) != STRING)
> Error(QUOTE_MSG, "MatchDriver");
> add_group_entry(&ptr->match_driver,
> - xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
> + xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
> + matchtype);
> free(xf86_lex_val.str);
> break;
> + case NOMATCH_TAG:
> + matchtype = MATCH_NEGATED;
> + /* fallthrough */
> case MATCH_TAG:
> if (xf86getSubToken(&(ptr->comment)) != STRING)
> Error(QUOTE_MSG, "MatchTag");
> - add_group_entry(&ptr->match_tag, xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
> + add_group_entry(&ptr->match_tag, xstrtokenize(xf86_lex_val.str,
> + TOKEN_SEP),
> + matchtype);
> free(xf86_lex_val.str);
> break;
> + case NOMATCH_LAYOUT:
> + matchtype = MATCH_NEGATED;
> + /* fallthrough */
> case MATCH_LAYOUT:
> if (xf86getSubToken(&(ptr->comment)) != STRING)
> Error(QUOTE_MSG, "MatchLayout");
> add_group_entry(&ptr->match_layout,
> - xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
> + xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
> + matchtype);
> free(xf86_lex_val.str);
> break;
> case MATCH_IS_KEYBOARD:
> diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
> index b3a50e5..a038f9e 100644
> --- a/hw/xfree86/parser/xf86Parser.h
> +++ b/hw/xfree86/parser/xf86Parser.h
> @@ -306,6 +306,7 @@ typedef struct {
> typedef struct {
> struct xorg_list entry;
> char **values;
> + Bool is_negated;
> } xf86MatchGroup;
>
> typedef struct {
> diff --git a/hw/xfree86/parser/xf86tokens.h b/hw/xfree86/parser/xf86tokens.h
> index bbd6b90..f955af0 100644
> --- a/hw/xfree86/parser/xf86tokens.h
> +++ b/hw/xfree86/parser/xf86tokens.h
> @@ -286,7 +286,17 @@ typedef enum {
> MATCH_IS_JOYSTICK,
> MATCH_IS_TABLET,
> MATCH_IS_TOUCHPAD,
> - MATCH_IS_TOUCHSCREEN
> + MATCH_IS_TOUCHSCREEN,
> +
> + NOMATCH_PRODUCT,
> + NOMATCH_VENDOR,
> + NOMATCH_DEVICE_PATH,
> + NOMATCH_OS,
> + NOMATCH_PNPID,
> + NOMATCH_USBID,
> + NOMATCH_DRIVER,
> + NOMATCH_TAG,
> + NOMATCH_LAYOUT,
> } ParserTokens;
>
> #endif /* _xf86_tokens_h */
> --
> 2.5.0
>
More information about the xorg-devel
mailing list