[PATCH 2/3 v2'] xserver: Introduce negated conditions in Match patterns
Oleh Nykyforchyn
oleh.nyk at gmail.com
Fri Jun 17 06:57:58 PDT 2011
xserver: Introduce negated conditions in Match patterns
When processing input devices, it is useful to determine not only which
attributes are to be accepted, but also which are to be rejected. Hence we introduce
an '!' prefix, before a pattern, which means that if an attribute matches this
pattern, then the respective device is rejected by this InputClass. To allow
statements like
MatchVendor "!Asus|!Logitech"
we also accept the rule of "last pattern": if the end of an entry is reached,
then the last pattern is decisive.
Signed-off-by: Oleh Nykyforchyn <oleh.nyk at gmail.com>
---
hw/xfree86/common/xf86Xinput.c | 15 ++++++++++++---
hw/xfree86/man/xorg.conf.man | 19 ++++++++++++-------
hw/xfree86/parser/InputClass.c | 10 ++++++++++
hw/xfree86/parser/xf86Parser.h | 1 +
4 files changed, 35 insertions(+), 10 deletions(-)
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 22e58a5..2cd1508 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -509,10 +509,19 @@ MatchAttrToken(const char *attr, struct list *groups)
Bool match = FALSE;
list_for_each_entry(pattern, &group->patterns, entry) {
- if (match_token(attr, pattern)) {
- match = TRUE;
- break;
+ match = match_token(attr, pattern);
+ if (match) { /* success? */
+ if (pattern->is_negated) /* negated pattern matched */
+ match = FALSE; /* failure */
+ break; /* leave the entry */
+ }
+ else {
+ if (pattern->is_negated) /* at least negated pattern not */
+ match = TRUE; /* matched - partial success */
+ /* else non-negated pattern not matched */
+ /* match = FALSE; */
}
+ /* no success yet, continue */
}
if (!match)
return FALSE;
diff --git a/hw/xfree86/man/xorg.conf.man b/hw/xfree86/man/xorg.conf.man
index df35178..d88db61 100644
--- a/hw/xfree86/man/xorg.conf.man
+++ b/hw/xfree86/man/xorg.conf.man
@@ -1072,9 +1072,13 @@ There are two types of match entries used in
sections. The first allows attributes of the device to be matched against
various patterns. An entry can be constructed to match attributes from
different devices by supplying several (at least one) patterns, which are
-applied to each attribute in the order of appearance in the entry. Hence
+applied to each attribute in the order of appearance in the entry. Usually,
an attribute that matches a pattern is accepted, and further patterns
-are not considered.
+are not considered. A pattern prepended with '!' is negated, which means
+that an attribute that matches it is rejected (this does not affect
+attributes accepted by previous patterns). If the end of an entry is
+reached, everything is determined by the last (not matched) pattern: if it
+is negated, the attribute is accepted, otherwise it is rejected.
.PP
Multiple entries of the same type may appear in one
.B InputClass
@@ -1085,9 +1089,10 @@ attribute. For example:
.nf
.B "Section \*qInputClass\*q"
.B " Identifier \*qMy Class\*q"
-.B " # product string must contain example
-.B " # and either gizmo or gadget
-.B " MatchProduct \*qexample\*q
+.B " # product string must not contain wrong,
+.B " # must contain example, and
+.B " # either gizmo or gadget
+.B " MatchProduct \*q!wrong\*q \*qexample\*q
.B " MatchProduct \*qgizmo\*q \*qgadget\*q
.I " ..."
.B "EndSection"
@@ -1162,11 +1167,11 @@ entry can look like
.PP
.RS 4
.nf
-.B " MatchProduct \*qUSB Optical Mouse|Touchpad\*q"
+.B " MatchProduct \*q!USB|Optical Mouse|Touchpad\*q"
.fi
.RE
.PP
-and select USB optical mice and touchpads.
+and select non-USB optical mice and touchpads.
The second type of entry is used to match device types. These entries take a
boolean argument similar to
diff --git a/hw/xfree86/parser/InputClass.c b/hw/xfree86/parser/InputClass.c
index 1d9051c..dc641d1 100644
--- a/hw/xfree86/parser/InputClass.c
+++ b/hw/xfree86/parser/InputClass.c
@@ -66,6 +66,8 @@ xf86ConfigSymTabRec InputClassTab[] =
#define TOKEN_SEP '|'
+#define NEG_FLAG '!'
+
static void
add_to_group(xf86MatchGroup **group, const char *str,
@@ -90,6 +92,12 @@ add_to_group(xf86MatchGroup **group, const char *str,
return;
list_add(&pattern->entry, &(*group)->patterns);
+ /* Pattern starting with '!' should NOT be matched */
+ if (*str == NEG_FLAG) {
+ pattern->is_negated = TRUE;
+ str++;
+ }
+
pattern->mode = pref_mode;
if ((next = index(str, TOKEN_SEP)))
@@ -329,6 +337,8 @@ print_pattern(FILE * cf, const xf86MatchPattern *pattern)
if (!pattern) return;
fprintf(cf, "\"");
+ if (pattern->is_negated)
+ fprintf(cf, "%c", NEG_FLAG);
if (pattern->mode == MATCH_IS_INVALID)
fprintf(cf, "invalid:");
if (pattern->str)
diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
index b02923f..faf5ab8 100644
--- a/hw/xfree86/parser/xf86Parser.h
+++ b/hw/xfree86/parser/xf86Parser.h
@@ -360,6 +360,7 @@ xf86MatchMode;
typedef struct
{
struct list entry;
+ Bool is_negated;
xf86MatchMode mode;
char *str;
}
--
1.6.4
--
Oleh Nykyforchyn <oleh.nyk at gmail.com>
More information about the xorg-devel
mailing list