# HG changeset patch # User Sadrul Habib Chowdhury # Date 1211861443 0 # Node ID 7b7af53e136a67bf92bca566d876be5494b2a75d # Parent 02b6569d99e96c21f6ef47170f479dab91a49e24 disapproval of revision '79699160e06b69f70db91eef65287f15685ec2bf' diff -r 02b6569d99e9 -r 7b7af53e136a finch/libgnt/gntkeys.c --- a/finch/libgnt/gntkeys.c Tue May 27 03:24:19 2008 +0000 +++ b/finch/libgnt/gntkeys.c Tue May 27 04:10:43 2008 +0000 @@ -34,158 +34,6 @@ static const char *term; static GHashTable *specials; -void gnt_keys_refine(char *text) -{ - if (*text == 27 && *(text + 1) == '[' && - (*(text + 2) >= 'A' && *(text + 2) <= 'D')) { - /* Apparently this is necessary for urxvt and screen and xterm */ - if (strcmp(term, "screen") == 0 || strcmp(term, "rxvt-unicode") == 0 || - strcmp(term, "xterm") == 0) - *(text + 1) = 'O'; - } else if (*(unsigned char*)text == 195) { - if (*(text + 2) == 0 && strcmp(term, "xterm") == 0) { - *(text) = 27; - *(text + 1) -= 64; /* Say wha? */ - } - } -} - -const char *gnt_key_translate(const char *name) -{ - return name ? g_hash_table_lookup(specials, name) : NULL; -} - -typedef struct { - const char *name; - const char *key; -} gntkey; - -static void -get_key_name(gpointer key, gpointer value, gpointer data) -{ - gntkey *k = data; - if (k->name) - return; - if (g_utf8_collate(value, k->key) == 0) - k->name = key; -} - -const char *gnt_key_lookup(const char *key) -{ - gntkey k = {NULL, key}; - g_hash_table_foreach(specials, get_key_name, &k); - return k.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. - * A sequence should not be a prefix of another sequence. If it is, then only - * the shortest one will be processed. If we want to change that, we will need - * to allow getting the k-th prefix that matches the input, and pay attention - * to the return value of gnt_wm_process_input in gntmain.c. - */ -#define SIZE 256 - -#define IS_END 1 << 0 -struct _node -{ - struct _node *next[SIZE]; - int ref; - int flags; -}; - -struct _node root; - -static void add_path(struct _node *node, const char *path) -{ - struct _node *n = NULL; - if (!path || !*path) { - node->flags |= IS_END; - return; - } - while (*path && node->next[(unsigned char)*path]) { - node = node->next[(unsigned char)*path]; - node->ref++; - path++; - } - if (!*path) - return; - n = g_new0(struct _node, 1); - n->ref = 1; - node->next[(unsigned char)*path++] = n; - add_path(n, path); -} - -void gnt_keys_add_combination(const char *path) -{ - add_path(&root, path); -} - -static void del_path(struct _node *node, const char *path) -{ - struct _node *next = NULL; - - if (!*path) - return; - next = node->next[(unsigned char)*path]; - if (!next) - return; - del_path(next, path + 1); - next->ref--; - if (next->ref == 0) { - node->next[(unsigned char)*path] = NULL; - g_free(next); - } -} - -void gnt_keys_del_combination(const char *path) -{ - del_path(&root, path); -} - -int gnt_keys_find_combination(const char *path) -{ - int depth = 0; - struct _node *n = &root; - - root.flags &= ~IS_END; - while (*path && n->next[(unsigned char)*path] && !(n->flags & IS_END)) { - if (!g_ascii_isspace(*path) && - !g_ascii_iscntrl(*path) && - !g_ascii_isgraph(*path)) - return 0; - n = n->next[(unsigned char)*path++]; - depth++; - } - - if (!(n->flags & IS_END)) - depth = 0; - return depth; -} - -static void -print_path(struct _node *node, int depth) -{ - int i; - for (i = 0; i < SIZE; i++) { - if (node->next[i]) { - g_printerr("%*c (%d:%d)\n", depth * 4, i, node->next[i]->ref, - node->next[i]->flags); - print_path(node->next[i], depth + 1); - } - } -} - -/* this is purely for debugging purposes. */ -void gnt_keys_print_combinations(void); -void gnt_keys_print_combinations() -{ - g_printerr("--------\n"); - print_path(&root, 1); - g_printerr("--------\n"); -} - void gnt_init_keys() { const char *controls[] = {"", "c-", "ctrl-", "ctr-", "ctl-", NULL}; @@ -193,9 +41,6 @@ int c, a, ch; char key[32]; - memset(&root, 0, sizeof(root)); - root.ref = 1; - if (term == NULL) { term = getenv("TERM"); if (!term) @@ -291,3 +136,155 @@ } } +void gnt_keys_refine(char *text) +{ + if (*text == 27 && *(text + 1) == '[' && + (*(text + 2) >= 'A' && *(text + 2) <= 'D')) { + /* Apparently this is necessary for urxvt and screen and xterm */ + if (strcmp(term, "screen") == 0 || strcmp(term, "rxvt-unicode") == 0 || + strcmp(term, "xterm") == 0) + *(text + 1) = 'O'; + } else if (*(unsigned char*)text == 195) { + if (*(text + 2) == 0 && strcmp(term, "xterm") == 0) { + *(text) = 27; + *(text + 1) -= 64; /* Say wha? */ + } + } +} + +const char *gnt_key_translate(const char *name) +{ + return name ? g_hash_table_lookup(specials, name) : NULL; +} + +typedef struct { + const char *name; + const char *key; +} gntkey; + +static void +get_key_name(gpointer key, gpointer value, gpointer data) +{ + gntkey *k = data; + if (k->name) + return; + if (g_utf8_collate(value, k->key) == 0) + k->name = key; +} + +const char *gnt_key_lookup(const char *key) +{ + gntkey k = {NULL, key}; + g_hash_table_foreach(specials, get_key_name, &k); + return k.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. + * A sequence should not be a prefix of another sequence. If it is, then only + * the shortest one will be processed. If we want to change that, we will need + * to allow getting the k-th prefix that matches the input, and pay attention + * to the return value of gnt_wm_process_input in gntmain.c. + */ +#define SIZE 256 + +#define IS_END 1 << 0 +struct _node +{ + struct _node *next[SIZE]; + int ref; + int flags; +}; + +static struct _node root = {.ref = 1, .flags = 0}; + +static void add_path(struct _node *node, const char *path) +{ + struct _node *n = NULL; + if (!path || !*path) { + node->flags |= IS_END; + return; + } + while (*path && node->next[(unsigned char)*path]) { + node = node->next[(unsigned char)*path]; + node->ref++; + path++; + } + if (!*path) + return; + n = g_new0(struct _node, 1); + n->ref = 1; + node->next[(unsigned char)*path++] = n; + add_path(n, path); +} + +void gnt_keys_add_combination(const char *path) +{ + add_path(&root, path); +} + +static void del_path(struct _node *node, const char *path) +{ + struct _node *next = NULL; + + if (!*path) + return; + next = node->next[(unsigned char)*path]; + if (!next) + return; + del_path(next, path + 1); + next->ref--; + if (next->ref == 0) { + node->next[(unsigned char)*path] = NULL; + g_free(next); + } +} + +void gnt_keys_del_combination(const char *path) +{ + del_path(&root, path); +} + +int gnt_keys_find_combination(const char *path) +{ + int depth = 0; + struct _node *n = &root; + + root.flags &= ~IS_END; + while (*path && n->next[(unsigned char)*path] && !(n->flags & IS_END)) { + if (!g_ascii_isspace(*path) && + !g_ascii_iscntrl(*path) && + !g_ascii_isgraph(*path)) + return 0; + n = n->next[(unsigned char)*path++]; + depth++; + } + + if (!(n->flags & IS_END)) + depth = 0; + return depth; +} + +static void +print_path(struct _node *node, int depth) +{ + int i; + for (i = 0; i < SIZE; i++) { + if (node->next[i]) { + g_printerr("%*c (%d:%d)\n", depth * 4, i, node->next[i]->ref, + node->next[i]->flags); + print_path(node->next[i], depth + 1); + } + } +} + +/* this is purely for debugging purposes. */ +void gnt_keys_print_combinations(void); +void gnt_keys_print_combinations() +{ + g_printerr("--------\n"); + print_path(&root, 1); + g_printerr("--------\n"); +} +