]> Dogcows Code - chaz/openbox/blob - plugins/keyboard/tree.c
keyboard bindings are functional
[chaz/openbox] / plugins / keyboard / tree.c
1 #include "keyboard.h"
2 #include "translate.h"
3 #include "keyaction.h"
4 #include <glib.h>
5
6 void tree_destroy(KeyBindingTree *tree)
7 {
8 KeyBindingTree *c;
9
10 while (tree) {
11 tree_destroy(tree->next_sibling);
12 c = tree->first_child;
13 if (c == NULL) {
14 GList *it;
15 for (it = tree->keylist; it != NULL; it = it->next)
16 g_free(it->data);
17 g_list_free(tree->keylist);
18 keyaction_free(&tree->action);
19 }
20 g_free(tree);
21 tree = c;
22 }
23 }
24
25 KeyBindingTree *tree_build(GList *keylist)
26 {
27 GList *it;
28 KeyBindingTree *ret = NULL, *p;
29
30 if (g_list_length(keylist) <= 0)
31 return NULL; /* nothing in the list.. */
32
33 for (it = g_list_last(keylist); it != NULL; it = it->prev) {
34 p = ret;
35 ret = g_new(KeyBindingTree, 1);
36 ret->next_sibling = NULL;
37 if (p == NULL) {
38 GList *it;
39
40 /* this is the first built node, the bottom node of the tree */
41 ret->keylist = g_list_copy(keylist); /* shallow copy */
42 for (it = ret->keylist; it != NULL; it = it->next) /* deep copy */
43 it->data = g_strdup(it->data);
44 }
45 ret->first_child = p;
46 if (!translate_key(it->data, &ret->state, &ret->key)) {
47 tree_destroy(ret);
48 return NULL;
49 }
50 }
51 return ret;
52 }
53
54 void tree_assimilate(KeyBindingTree *node)
55 {
56 KeyBindingTree *a, *b, *tmp, *last;
57
58 if (firstnode == NULL) {
59 /* there are no nodes at this level yet */
60 firstnode = node;
61 } else {
62 a = firstnode;
63 last = a;
64 b = node;
65 while (a) {
66 last = a;
67 if (!(a->state == b->state && a->key == b->key)) {
68 a = a->next_sibling;
69 } else {
70 tmp = b;
71 b = b->first_child;
72 g_free(tmp);
73 a = a->first_child;
74 }
75 }
76 if (!(last->state == b->state && last->key == b->key))
77 last->next_sibling = b;
78 else {
79 last->first_child = b->first_child;
80 g_free(b);
81 }
82 }
83 }
84
85 KeyBindingTree *tree_find(KeyBindingTree *search, gboolean *conflict)
86 {
87 KeyBindingTree *a, *b;
88
89 *conflict = FALSE;
90
91 a = firstnode;
92 b = search;
93 while (a && b) {
94 if (!(a->state == b->state && a->key == b->key)) {
95 a = a->next_sibling;
96 } else {
97 if ((a->first_child == NULL) == (b->first_child == NULL)) {
98 if (a->first_child == NULL) {
99 /* found it! (return the actual node, not the search's) */
100 return a;
101 }
102 } else {
103 *conflict = TRUE;
104 return NULL; /* the chain status' don't match (conflict!) */
105 }
106 b = b->first_child;
107 a = a->first_child;
108 }
109 }
110 return NULL; /* it just isn't in here */
111 }
This page took 0.039346 seconds and 5 git commands to generate.