summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2022-01-09 11:23:01 -0800
committerThomas E. Dickey <dickey@his.com>2022-06-20 23:07:40 +0000
commitcbbf610bfbef2f8a20c8a2886a8a9c1ec94d4a66 (patch)
treebed1927ba097d2f241066d0f5b30b6ea99bccf67
parent215b8ee1d3231dd34a9e8002832cd028a6728dc7 (diff)
Support buttons > 5 in translation tables [v2]
Add support for arbitrary button numbers by replacing the table-driven detail parsing for BtnDown/ButtonPress and BtnUp/ButtonRelease with a custom parser that allows for an arbitrary button number (1-255) after the 'Button' prefix. Document what this syntax looks like in the table of detail information. Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--specs/appB.xml4
-rw-r--r--src/TMparse.c60
2 files changed, 48 insertions, 16 deletions
diff --git a/specs/appB.xml b/specs/appB.xml
index 93a2cf6..74ac82c 100644
--- a/specs/appB.xml
+++ b/specs/appB.xml
@@ -729,11 +729,11 @@ The detail field is supported for the following event types:
</row>
<row>
<entry>ButtonPress</entry>
- <entry>button from event <emphasis>detail</emphasis></entry>
+ <entry>&ldquo;Button&rdquo; followed by button from event <emphasis>detail</emphasis> (e.g. <function>Button1</function>)</entry>
</row>
<row>
<entry>ButtonRelease</entry>
- <entry>button from event <emphasis>detail</emphasis></entry>
+ <entry>&ldquo;Button&rdquo; followed by button from event <emphasis>detail</emphasis> (e.g. <function>Button42</function>)</entry>
</row>
<row>
<entry>MotionNotify</entry>
diff --git a/src/TMparse.c b/src/TMparse.c
index 1cb75c5..b20d787 100644
--- a/src/TMparse.c
+++ b/src/TMparse.c
@@ -167,15 +167,6 @@ static ModifierRec modifiers[] = {
{"l", 0, ParseModImmed, LockMask},
};
-static NameValueRec buttonNames[] = {
- {"Button1", 0, Button1},
- {"Button2", 0, Button2},
- {"Button3", 0, Button3},
- {"Button4", 0, Button4},
- {"Button5", 0, Button5},
- {NULL, NULLQUARK, 0},
-};
-
static NameValueRec motionDetails[] = {
{"Normal", 0, NotifyNormal},
{"Hint", 0, NotifyHint},
@@ -234,6 +225,7 @@ static NameValueRec mappingNotify[] = {
static String ParseKeySym(PARSE_PROC_DECL);
static String ParseKeyAndModifiers(PARSE_PROC_DECL);
static String ParseTable(PARSE_PROC_DECL);
+static String ParseButton(PARSE_PROC_DECL);
static String ParseImmed(PARSE_PROC_DECL);
static String ParseAddModifier(PARSE_PROC_DECL);
static String ParseNone(PARSE_PROC_DECL);
@@ -253,8 +245,8 @@ static EventKey events[] = {
{"KeyUp", NULLQUARK, KeyRelease, ParseKeySym, NULL},
{"KeyRelease", NULLQUARK, KeyRelease, ParseKeySym, NULL},
-{"ButtonPress", NULLQUARK, ButtonPress, ParseTable, (Opaque)buttonNames},
-{"BtnDown", NULLQUARK, ButtonPress, ParseTable, (Opaque)buttonNames},
+{"ButtonPress", NULLQUARK, ButtonPress, ParseButton, NULL },
+{"BtnDown", NULLQUARK, ButtonPress, ParseButton, NULL },
{"Btn1Down", NULLQUARK, ButtonPress, ParseImmed, (Opaque)Button1},
{"Btn2Down", NULLQUARK, ButtonPress, ParseImmed, (Opaque)Button2},
{"Btn3Down", NULLQUARK, ButtonPress, ParseImmed, (Opaque)Button3},
@@ -263,8 +255,8 @@ static EventKey events[] = {
/* Event Name, Quark, Event Type, Detail Parser, Closure */
-{"ButtonRelease", NULLQUARK, ButtonRelease, ParseTable, (Opaque)buttonNames},
-{"BtnUp", NULLQUARK, ButtonRelease, ParseTable, (Opaque)buttonNames},
+{"ButtonRelease", NULLQUARK, ButtonRelease, ParseButton, NULL },
+{"BtnUp", NULLQUARK, ButtonRelease, ParseButton, NULL },
{"Btn1Up", NULLQUARK, ButtonRelease, ParseImmed, (Opaque)Button1},
{"Btn2Up", NULLQUARK, ButtonRelease, ParseImmed, (Opaque)Button2},
{"Btn3Up", NULLQUARK, ButtonRelease, ParseImmed, (Opaque)Button3},
@@ -1086,6 +1078,47 @@ ParseTable(register String str, Opaque closure, EventPtr event, Boolean *error)
}
static String
+ParseButton(String str, Opaque closure, EventPtr event, Boolean *error)
+{
+ String start = str;
+ char buttonStr[7];
+ size_t len;
+ static const char buttonPrefix[] = "Button";
+ unsigned long button;
+
+ event->event.eventCode = 0L;
+ if (strncmp(str, buttonPrefix, sizeof(buttonPrefix)-1) != 0) {
+ event->event.eventCodeMask = 0L;
+ return str;
+ }
+ str += sizeof(buttonPrefix)-1;
+ start = str;
+ ScanNumeric(str);
+ if (str == start) {
+ Syntax("Missing button number", "");
+ *error = TRUE;
+ return PanicModeRecovery(str);
+ }
+ len = (size_t) (str - start);
+ if (len >= sizeof buttonStr) {
+ Syntax("Button number too long", "");
+ *error = TRUE;
+ return PanicModeRecovery(str);
+ }
+ (void) memmove(buttonStr, start, len);
+ buttonStr[len] = '\0';
+ button = StrToNum(buttonStr);
+ if (button < 1 || 255 < button) {
+ Syntax("Invalid button number", buttonStr);
+ *error = TRUE;
+ return PanicModeRecovery(str);
+ }
+ event->event.eventCode = button;
+ event->event.eventCodeMask = (unsigned long) (~0L);
+ return str;
+}
+
+static String
ParseNone(String str,
Opaque closure _X_UNUSED,
EventPtr event,
@@ -2179,7 +2212,6 @@ _XtTranslateInitialize(void)
Compile_XtEventTable(events, XtNumber(events));
Compile_XtModifierTable(modifiers, XtNumber(modifiers));
- CompileNameValueTable(buttonNames);
CompileNameValueTable(notifyModes);
CompileNameValueTable(motionDetails);
#if 0