changeset 15801:682022b8a129

Make sure unbound key-combinations are handled properly.
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Fri, 16 Mar 2007 20:53:24 +0000
parents 1dee9065e336
children 94867b2f38f5
files console/libgnt/gntkeys.c console/libgnt/gntkeys.h console/libgnt/gntmain.c console/libgnt/gntmenu.c console/libgnt/gntstyle.c
diffstat 5 files changed, 95 insertions(+), 81 deletions(-) [+]
line wrap: on
line diff
--- a/console/libgnt/gntkeys.c	Fri Mar 16 03:43:20 2007 +0000
+++ b/console/libgnt/gntkeys.c	Fri Mar 16 20:53:24 2007 +0000
@@ -10,9 +10,15 @@
 char *gnt_key_cright;
 
 static const char *term;
+static GHashTable *specials;
 
 void gnt_init_keys()
 {
+	const char *controls[] = {"", "c-", "ctrl-", "ctr-", "ctl-", NULL};
+	const char *alts[] = {"", "alt-", "a-", "m-", "meta-", NULL};
+	int c, a, ch;
+	char key[32];
+
 	if (term == NULL) {
 		term = getenv("TERM");
 		if (!term)
@@ -30,6 +36,82 @@
 		gnt_key_cright = "\033" "Oc";
 		gnt_key_cleft  = "\033" "Od";
 	}
+
+	specials = g_hash_table_new(g_str_hash, g_str_equal);
+
+#define INSERT_KEY(k, code) do { \
+		g_hash_table_insert(specials, g_strdup(k), g_strdup(code)); \
+		gnt_keys_add_combination(code); \
+	} while (0)
+
+	INSERT_KEY("home",     GNT_KEY_HOME);
+	INSERT_KEY("end",      GNT_KEY_END);
+	INSERT_KEY("pageup",   GNT_KEY_PGUP);
+	INSERT_KEY("pagedown", GNT_KEY_PGDOWN);
+	INSERT_KEY("insert",   GNT_KEY_INS);
+	INSERT_KEY("delete",   GNT_KEY_DEL);
+
+	INSERT_KEY("left",   GNT_KEY_LEFT);
+	INSERT_KEY("right",  GNT_KEY_RIGHT);
+	INSERT_KEY("up",     GNT_KEY_UP);
+	INSERT_KEY("down",   GNT_KEY_DOWN);
+
+	INSERT_KEY("tab",    "\t");
+	INSERT_KEY("menu",   GNT_KEY_POPUP);
+
+	INSERT_KEY("f1",   GNT_KEY_F1);
+	INSERT_KEY("f2",   GNT_KEY_F2);
+	INSERT_KEY("f3",   GNT_KEY_F3);
+	INSERT_KEY("f4",   GNT_KEY_F4);
+	INSERT_KEY("f5",   GNT_KEY_F5);
+	INSERT_KEY("f6",   GNT_KEY_F6);
+	INSERT_KEY("f7",   GNT_KEY_F7);
+	INSERT_KEY("f8",   GNT_KEY_F8);
+	INSERT_KEY("f9",   GNT_KEY_F9);
+	INSERT_KEY("f10",  GNT_KEY_F10);
+	INSERT_KEY("f11",  GNT_KEY_F11);
+	INSERT_KEY("f12",  GNT_KEY_F12);
+
+#define REM_LENGTH  (sizeof(key) - (cur - key))
+#define INSERT_COMB(k, code) do { \
+		snprintf(key, sizeof(key), "%s%s%s", controls[c], alts[a], k);  \
+		INSERT_KEY(key, code);  \
+	} while (0);
+
+	/* Lower-case alphabets */
+	for (a = 0, c = 0; controls[c]; c++, a = 0) {
+		if (c) {
+			INSERT_COMB("up",    gnt_key_cup);
+			INSERT_COMB("down",  gnt_key_cdown);
+			INSERT_COMB("left",  gnt_key_cleft);
+			INSERT_COMB("right", gnt_key_cright);
+		}
+
+		for (a = 0; alts[a]; a++) {
+			if (a == 0 && c == 0) continue;
+			for (ch = 0; ch < 26; ch++) {
+				char str[2] = {'a' + ch, 0}, code[4] = "\0\0\0\0";
+				int ind = 0;
+				if (a)
+					code[ind++] = '\033';
+				code[ind] = (c ? 1 : 'a') + ch;
+				INSERT_COMB(str, code);
+			}
+		}
+	}
+	c = 0;
+	for (a = 1; alts[a]; a++) {
+		/* Upper-case alphabets */
+		for (ch = 0; ch < 26; ch++) {
+			char str[2] = {'A' + ch, 0}, code[] = {'\033', 'A' + ch, 0};
+			INSERT_COMB(str, code);
+		}
+		/* Digits */
+		for (ch = 0; ch < 10; ch++) {
+			char str[2] = {'0' + ch, 0}, code[] = {'\033', '0' + ch, 0};
+			INSERT_COMB(str, code);
+		}
+	}
 }
 
 void gnt_keys_refine(char *text)
@@ -48,6 +130,11 @@
 	}
 }
 
+const char *gnt_key_translate(const char *name)
+{
+	return g_hash_table_lookup(specials, name);
+}
+
 /**
  * The key-bindings will be saved in a tree. When a keystroke happens, GNT will
  * find the sequence that matches a binding and return the length.
@@ -120,6 +207,7 @@
 	int depth = 0;
 	struct _node *n = &root;
 
+	root.flags &= ~IS_END;
 	while (*path && n->next[*path] && !(n->flags & IS_END)) {
 		if (g_utf8_find_next_char(path, NULL) - path > 1)
 			return 0;
@@ -138,7 +226,7 @@
 	int i;
 	for (i = 0; i < SIZE; i++) {
 		if (node->next[i]) {
-			g_printerr("%*c (%d:%d)\n", depth, i, node->next[i]->ref,
+			g_printerr("%*c (%d:%d)\n", depth * 4, i, node->next[i]->ref,
 						node->next[i]->flags);
 			print_path(node->next[i], depth + 1);
 		}
--- a/console/libgnt/gntkeys.h	Fri Mar 16 03:43:20 2007 +0000
+++ b/console/libgnt/gntkeys.h	Fri Mar 16 20:53:24 2007 +0000
@@ -81,6 +81,7 @@
  */
 void gnt_init_keys();
 void gnt_keys_refine(char *text);
+const char *gnt_key_translate(const char *name);
 
 void gnt_keys_add_combination(const char *path);
 void gnt_keys_del_combination(const char *path);
--- a/console/libgnt/gntmain.c	Fri Mar 16 03:43:20 2007 +0000
+++ b/console/libgnt/gntmain.c	Fri Mar 16 20:53:24 2007 +0000
@@ -360,6 +360,7 @@
 	noecho();
 	curs_set(0);
 
+	gnt_init_keys();
 	gnt_init_styles();
 
 	filename = g_build_filename(g_get_home_dir(), ".gntrc", NULL);
@@ -367,7 +368,6 @@
 	g_free(filename);
 
 	gnt_init_colors();
-	gnt_init_keys();
 
 	wbkgdset(stdscr, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL));
 	refresh();
--- a/console/libgnt/gntmenu.c	Fri Mar 16 03:43:20 2007 +0000
+++ b/console/libgnt/gntmenu.c	Fri Mar 16 20:53:24 2007 +0000
@@ -134,7 +134,8 @@
 	int current = menu->selected;
 
 	if (menu->submenu) {
-		return (gnt_widget_key_pressed(GNT_WIDGET(menu->submenu), text));
+		do menu = menu->submenu; while (menu->submenu);
+		return (gnt_widget_key_pressed(GNT_WIDGET(menu), text));
 	}
 
 	if (text[0] == 27 && text[1] == 0) {
--- a/console/libgnt/gntstyle.c	Fri Mar 16 03:43:20 2007 +0000
+++ b/console/libgnt/gntstyle.c	Fri Mar 16 20:53:24 2007 +0000
@@ -84,82 +84,7 @@
 static char *
 parse_key(const char *key)
 {
-	char *ret = NULL;
-	int ctrl = 0, alt = 0;
-	char k;
-
-	/* XXX: Need to do something about ctrl/alt+home, end etc. */
-
-#define SPECIAL_KEY(k, code) do { \
-		if (strcasecmp(key, k) == 0) \
-			return g_strdup(code); \
-	} while (0)
-
-	SPECIAL_KEY("home",     GNT_KEY_HOME);
-	SPECIAL_KEY("end",      GNT_KEY_END);
-	SPECIAL_KEY("pageup",   GNT_KEY_PGUP);
-	SPECIAL_KEY("pagedown", GNT_KEY_PGDOWN);
-	SPECIAL_KEY("insert",   GNT_KEY_INS);
-	SPECIAL_KEY("delete",   GNT_KEY_DEL);
-
-	SPECIAL_KEY("left",   GNT_KEY_LEFT);
-	SPECIAL_KEY("right",  GNT_KEY_RIGHT);
-	SPECIAL_KEY("up",     GNT_KEY_UP);
-	SPECIAL_KEY("down",   GNT_KEY_DOWN);
-
-	SPECIAL_KEY("tab",    "\t");
-	SPECIAL_KEY("menu",   GNT_KEY_POPUP);
-
-	SPECIAL_KEY("f1",   GNT_KEY_F1);
-	SPECIAL_KEY("f2",   GNT_KEY_F2);
-	SPECIAL_KEY("f3",   GNT_KEY_F3);
-	SPECIAL_KEY("f4",   GNT_KEY_F4);
-	SPECIAL_KEY("f5",   GNT_KEY_F5);
-	SPECIAL_KEY("f6",   GNT_KEY_F6);
-	SPECIAL_KEY("f7",   GNT_KEY_F7);
-	SPECIAL_KEY("f8",   GNT_KEY_F8);
-	SPECIAL_KEY("f9",   GNT_KEY_F9);
-	SPECIAL_KEY("f10",  GNT_KEY_F10);
-	SPECIAL_KEY("f11",  GNT_KEY_F11);
-	SPECIAL_KEY("f12",  GNT_KEY_F12);
-
-#undef SPECIAL_KEY
-
-#define MATCH(string, var)	do { \
-		if (strncasecmp(key, string, sizeof(string) - 1) == 0) { \
-			key += sizeof(string) - 1; \
-			var = 1; \
-		} \
-	}while (0)
-
-	MATCH("c-", ctrl);
-	MATCH("ctl-", ctrl);
-	MATCH("ctr-", ctrl);
-	MATCH("ctrl-", ctrl);
-
-	MATCH("alt-", alt);
-	MATCH("a-", alt);
-	MATCH("m-", alt);
-	MATCH("meta-", alt);
-
-	if (strlen(key) != 1)  /* We can only have stuff like "ctrl-alt-a" */
-		return NULL;
-
-	if (ctrl && !isalpha(*key)) {
-		/* These keys cannot be used with ctrl */
-		return NULL;
-	}
-
-	if (ctrl)
-		k = *key | 0x20;
-	else
-		k = *key;
-
-	ret = g_strdup_printf("%s%c", alt ? "\033" : "", ctrl ? k - 0x60 : k);
-
-#undef MATCH
-
-	return ret;
+	return gnt_key_translate(key);
 }
 
 void gnt_style_read_actions(GType type, GntBindableClass *klass)
@@ -199,12 +124,11 @@
 			}
 			else
 			{
-				char *keycode = parse_key(key);
+				const char *keycode = parse_key(key);
 				if (keycode == NULL) {
 					g_printerr("GntStyle: Invalid key-binding %s\n", key);
 				} else {
 					gnt_bindable_register_binding(klass, action, keycode, NULL);
-					g_free(keycode);
 				}
 			}
 			g_free(key);