# HG changeset patch # User Sadrul Habib Chowdhury # Date 1174078404 0 # Node ID 682022b8a1294f8c56ec7a3117a1097d0be16a90 # Parent 1dee9065e3361f5df8c0c5837bbf16b068bab3bd Make sure unbound key-combinations are handled properly. diff -r 1dee9065e336 -r 682022b8a129 console/libgnt/gntkeys.c --- 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); } diff -r 1dee9065e336 -r 682022b8a129 console/libgnt/gntkeys.h --- 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); diff -r 1dee9065e336 -r 682022b8a129 console/libgnt/gntmain.c --- 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(); diff -r 1dee9065e336 -r 682022b8a129 console/libgnt/gntmenu.c --- 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) { diff -r 1dee9065e336 -r 682022b8a129 console/libgnt/gntstyle.c --- 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);