terminal kbd: Support Ctrl-Alt-letter key combinations.

Actions can now be bound to e.g. Ctrl-Alt-A.  The keybinding code also
supports other combinations of modifiers, like Shift-Ctrl-Up, but the
escape sequence decoder doesn't yet.

Allow only letter and Alt-letter combinations to trigger accelerators
in menus and dialogs.  Ignore other key combinations unless they are
individually bound to actions.  And don't let Ctrl-Alt-F open the File
menu.

---
commit fc23a55d905403a7d0d5114f2ee2e181ed306ad3
tree 28ca20748b0ee4cc40d526c3a0d67ec814599fb9
parent fef230a0e1b60b48e6b767da966f091843206b8f
author Kalle Olavi Niemitalo <[EMAIL PROTECTED]> Fri, 28 Jul 2006 19:58:54 +0300
committer Kalle Olavi Niemitalo <[EMAIL PROTECTED]> Fri, 28 Jul 2006 19:58:54 +0300

 src/config/kbdbind.c   |   64 ++++++++++++++++++++++++++----------------------
 src/terminal/event.h   |    2 +-
 src/terminal/kbd.c     |    2 +-
 src/viewer/text/view.c |    3 ++
 4 files changed, 39 insertions(+), 32 deletions(-)

diff --git a/src/config/kbdbind.c b/src/config/kbdbind.c
index 09c7ceb..a90a3d7 100644
--- a/src/config/kbdbind.c
+++ b/src/config/kbdbind.c
@@ -369,34 +369,41 @@ read_key(unsigned char *key_str)
 	return -1;
 }
 
+struct modifier {
+	const unsigned char *name_and_dash;
+	size_t name_len;	/* does not include the dash */
+	int bitmask;
+};
+static const struct modifier modifiers[] = {
+	{ "Shift-", 5, KBD_MOD_SHIFT },
+	{ "Ctrl-",  4, KBD_MOD_CTRL },
+	{ "Alt-",   3, KBD_MOD_ALT },
+	{ NULL }
+};
+
 int
 parse_keystroke(unsigned char *s, struct term_event_keyboard *kbd)
 {
-	if (!strncasecmp(s, "Shift", 5) && (s[5] == '-' || s[5] == '+')) {
-		/* Shift+a == shiFt-a == Shift-a */
-		memcpy(s, "Shift-", 6);
-		kbd->modifier = KBD_MOD_SHIFT;
-		s += 6;
-
-	} else if (!strncasecmp(s, "Ctrl", 4) && (s[4] == '-' || s[4] == '+')) {
-		/* Ctrl+a == ctRl-a == Ctrl-a */
-		memcpy(s, "Ctrl-", 5);
-		kbd->modifier = KBD_MOD_CTRL;
-		s += 5;
-		/* Ctrl-a == Ctrl-A */
-		if (s[0] && !s[1]) s[0] = toupper(s[0]);
-
-	} else if (!strncasecmp(s, "Alt", 3) && (s[3] == '-' || s[3] == '+')) {
-		/* Alt+a == aLt-a == Alt-a */
-		memcpy(s, "Alt-", 4);
-		kbd->modifier = KBD_MOD_ALT;
-		s += 4;
-
-	} else {
-		/* No modifier. */
-		kbd->modifier = KBD_MOD_NONE;
+	const struct modifier *modp;
+
+	kbd->modifier = KBD_MOD_NONE;
+ more_modifiers:
+	for (modp = modifiers; modp->name_and_dash != NULL; ++modp) {
+		if ((kbd->modifier & modp->bitmask) == 0
+		    && !strncasecmp(s, modp->name_and_dash, modp->name_len)
+		    && (s[modp->name_len] == '-' || s[modp->name_len] == '+')) {
+			/* Shift+a == shiFt-a == Shift-a */
+			memcpy(s, modp->name_and_dash, modp->name_len + 1);
+			kbd->modifier |= modp->bitmask;
+			s += modp->name_len + 1;
+			goto more_modifiers;
+		}
 	}
 
+	/* Ctrl-a == Ctrl-A */
+	if ((kbd->modifier & KBD_MOD_CTRL) != 0 && s[0] && !s[1])
+		s[0] = toupper(s[0]);
+
 	kbd->key = read_key(s);
 	return (kbd->key < 0) ? -1 : 0;
 }
@@ -408,15 +415,14 @@ add_keystroke_to_string(struct string *s
 	unsigned char key_buffer[3] = "\\x";
 	unsigned char *key_string = NULL;
 	struct key *key;
+	const struct modifier *modp;
 
 	if (kbd->key < 0) return;
 
-	if (kbd->modifier & KBD_MOD_SHIFT)
-		add_to_string(str, "Shift-");
-	if (kbd->modifier & KBD_MOD_CTRL)
-		add_to_string(str, "Ctrl-");
-	if (kbd->modifier & KBD_MOD_ALT)
-		add_to_string(str, "Alt-");
+	for (modp = modifiers; modp->name_and_dash != NULL; ++modp) {
+		if (kbd->modifier & modp->bitmask)
+			add_to_string(str, modp->name_and_dash);
+	}
 
 	for (key = key_table; key->str; key++) {
 		if (kbd->key == key->num) {
diff --git a/src/terminal/event.h b/src/terminal/event.h
index ffd3590..284c4ae 100644
--- a/src/terminal/event.h
+++ b/src/terminal/event.h
@@ -119,7 +119,7 @@ #define get_kbd_modifier(event)		(kbd_ge
 #define check_kbd_modifier(event, mod)	(kbd_modifier_is(&(event)->info.keyboard, (mod)))
 
 #define check_kbd_textinput_key(event)	(get_kbd_key(event) >= ' ' && get_kbd_key(event) < 256 && check_kbd_modifier(event, KBD_MOD_NONE))
-#define check_kbd_label_key(event)	(get_kbd_key(event) > ' ' && get_kbd_key(event) < 256)
+#define check_kbd_label_key(event)	(get_kbd_key(event) > ' ' && get_kbd_key(event) < 256 && (check_kbd_modifier(event, KBD_MOD_NONE) || check_kbd_modifier(event, KBD_MOD_ALT)))
 
 
 /* For mouse events handling */
diff --git a/src/terminal/kbd.c b/src/terminal/kbd.c
index ca94ad4..98bd645 100644
--- a/src/terminal/kbd.c
+++ b/src/terminal/kbd.c
@@ -864,7 +864,7 @@ #endif
 	default:
 		if (key < ' ') {
 			key += 'A' - 1;
-			modifier = KBD_MOD_CTRL;
+			modifier |= KBD_MOD_CTRL;
 		}
 	}
 
diff --git a/src/viewer/text/view.c b/src/viewer/text/view.c
index 6ab45a4..cbb91ff 100644
--- a/src/viewer/text/view.c
+++ b/src/viewer/text/view.c
@@ -1157,7 +1157,8 @@ #endif
 
 	if (check_kbd_key(ev, KBD_CTRL_C)) goto quit;
 
-	if (get_kbd_modifier(ev) & KBD_MOD_ALT) {
+	/* Ctrl-Alt-F should not open the File menu like Alt-f does.  */
+	if (check_kbd_modifier(ev, KBD_MOD_ALT)) {
 		struct window *win;
 
 		get_kbd_modifier(ev) &= ~KBD_MOD_ALT;

Attachment: pgp3mX2XXruge.pgp
Description: PGP signature

_______________________________________________
elinks-dev mailing list
[email protected]
http://linuxfromscratch.org/mailman/listinfo/elinks-dev

Reply via email to