diff options
| author | Dana Jansens <danakj@orodu.net> | 2003-03-18 08:38:33 +0000 |
|---|---|---|
| committer | Dana Jansens <danakj@orodu.net> | 2003-03-18 08:38:33 +0000 |
| commit | 739c958ac58154f8b1896113701e1c7f580d4cde (patch) | |
| tree | 0f4ea545addb1b432efc3fe880906f0fa244cb12 /plugins/keyboard/tree.c | |
| parent | eeba457231e3823171716b47a1a4d0900907269e (diff) | |
keyboard bindings are functional
Diffstat (limited to 'plugins/keyboard/tree.c')
| -rw-r--r-- | plugins/keyboard/tree.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/plugins/keyboard/tree.c b/plugins/keyboard/tree.c new file mode 100644 index 00000000..b7f51888 --- /dev/null +++ b/plugins/keyboard/tree.c @@ -0,0 +1,111 @@ +#include "keyboard.h" +#include "translate.h" +#include "keyaction.h" +#include <glib.h> + +void tree_destroy(KeyBindingTree *tree) +{ + KeyBindingTree *c; + + while (tree) { + tree_destroy(tree->next_sibling); + c = tree->first_child; + if (c == NULL) { + GList *it; + for (it = tree->keylist; it != NULL; it = it->next) + g_free(it->data); + g_list_free(tree->keylist); + keyaction_free(&tree->action); + } + g_free(tree); + tree = c; + } +} + +KeyBindingTree *tree_build(GList *keylist) +{ + GList *it; + KeyBindingTree *ret = NULL, *p; + + if (g_list_length(keylist) <= 0) + return NULL; /* nothing in the list.. */ + + for (it = g_list_last(keylist); it != NULL; it = it->prev) { + p = ret; + ret = g_new(KeyBindingTree, 1); + ret->next_sibling = NULL; + if (p == NULL) { + GList *it; + + /* this is the first built node, the bottom node of the tree */ + ret->keylist = g_list_copy(keylist); /* shallow copy */ + for (it = ret->keylist; it != NULL; it = it->next) /* deep copy */ + it->data = g_strdup(it->data); + } + ret->first_child = p; + if (!translate_key(it->data, &ret->state, &ret->key)) { + tree_destroy(ret); + return NULL; + } + } + return ret; +} + +void tree_assimilate(KeyBindingTree *node) +{ + KeyBindingTree *a, *b, *tmp, *last; + + if (firstnode == NULL) { + /* there are no nodes at this level yet */ + firstnode = node; + } else { + a = firstnode; + last = a; + b = node; + while (a) { + last = a; + if (!(a->state == b->state && a->key == b->key)) { + a = a->next_sibling; + } else { + tmp = b; + b = b->first_child; + g_free(tmp); + a = a->first_child; + } + } + if (!(last->state == b->state && last->key == b->key)) + last->next_sibling = b; + else { + last->first_child = b->first_child; + g_free(b); + } + } +} + +KeyBindingTree *tree_find(KeyBindingTree *search, gboolean *conflict) +{ + KeyBindingTree *a, *b; + + *conflict = FALSE; + + a = firstnode; + b = search; + while (a && b) { + if (!(a->state == b->state && a->key == b->key)) { + a = a->next_sibling; + } else { + if ((a->first_child == NULL) == (b->first_child == NULL)) { + if (a->first_child == NULL) { + /* found it! (return the actual node, not the search's) */ + return a; + } + } else { + *conflict = TRUE; + return NULL; /* the chain status' don't match (conflict!) */ + } + b = b->first_child; + a = a->first_child; + } + } + return NULL; /* it just isn't in here */ +} |
