]> Dogcows Code - chaz/openbox/blobdiff - openbox/keytree.c
move the keyboard and mouse plugins into the kernel for mucho sexiness.
[chaz/openbox] / openbox / keytree.c
diff --git a/openbox/keytree.c b/openbox/keytree.c
new file mode 100644 (file)
index 0000000..9aa2ea9
--- /dev/null
@@ -0,0 +1,112 @@
+#include "keyboard.h"
+#include "translate.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;
+            GSList *sit;
+           for (it = tree->keylist; it != NULL; it = it->next)
+               g_free(it->data);
+           g_list_free(tree->keylist);
+           for (sit = tree->actions; sit != NULL; sit = sit->next)
+                action_free(sit->data);
+           g_slist_free(tree->actions);
+       }
+       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_new0(KeyBindingTree, 1);
+       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 (keyboard_firstnode == NULL) {
+       /* there are no nodes at this level yet */
+       keyboard_firstnode = node;
+    } else {
+       a = keyboard_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 = keyboard_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 */
+}
This page took 0.027554 seconds and 4 git commands to generate.