]> Dogcows Code - chaz/openbox/blob - plugins/keyboard/tree.c
mouse and key bindings plugins work. segfault somewhere still on shutdown
[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_new(KeyBindingTree, 1);
35 ret->next_sibling = NULL;
36 if (p == NULL) {
37 GList *it;
38
39 /* this is the first built node, the bottom node of the tree */
40 ret->keylist = g_list_copy(keylist); /* shallow copy */
41 for (it = ret->keylist; it != NULL; it = it->next) /* deep copy */
42 it->data = g_strdup(it->data);
43 }
44 ret->first_child = p;
45 if (!translate_key(it->data, &ret->state, &ret->key)) {
46 tree_destroy(ret);
47 return NULL;
48 }
49 }
50 return ret;
51 }
52
53 void tree_assimilate(KeyBindingTree *node)
54 {
55 KeyBindingTree *a, *b, *tmp, *last;
56
57 if (firstnode == NULL) {
58 /* there are no nodes at this level yet */
59 firstnode = node;
60 } else {
61 a = firstnode;
62 last = a;
63 b = node;
64 while (a) {
65 last = a;
66 if (!(a->state == b->state && a->key == b->key)) {
67 a = a->next_sibling;
68 } else {
69 tmp = b;
70 b = b->first_child;
71 g_free(tmp);
72 a = a->first_child;
73 }
74 }
75 if (!(last->state == b->state && last->key == b->key))
76 last->next_sibling = b;
77 else {
78 last->first_child = b->first_child;
79 g_free(b);
80 }
81 }
82 }
83
84 KeyBindingTree *tree_find(KeyBindingTree *search, gboolean *conflict)
85 {
86 KeyBindingTree *a, *b;
87
88 *conflict = FALSE;
89
90 a = firstnode;
91 b = search;
92 while (a && b) {
93 if (!(a->state == b->state && a->key == b->key)) {
94 a = a->next_sibling;
95 } else {
96 if ((a->first_child == NULL) == (b->first_child == NULL)) {
97 if (a->first_child == NULL) {
98 /* found it! (return the actual node, not the search's) */
99 return a;
100 }
101 } else {
102 *conflict = TRUE;
103 return NULL; /* the chain status' don't match (conflict!) */
104 }
105 b = b->first_child;
106 a = a->first_child;
107 }
108 }
109 return NULL; /* it just isn't in here */
110 }
This page took 0.04406 seconds and 5 git commands to generate.