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