]> Dogcows Code - chaz/openbox/blob - src/bindings.cc
keybindings underway. dont work yet
[chaz/openbox] / src / bindings.cc
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2
3 #ifdef HAVE_CONFIG_H
4 # include "../config.h"
5 #endif
6
7 #include "bindings.hh"
8 #include "otk/display.hh"
9
10 extern "C" {
11 #include <X11/Xlib.h>
12 }
13
14 namespace ob {
15
16 #include <stdio.h>
17 static void print_branch(BindingTree *first, std::string str)
18 {
19 BindingTree *p = first;
20
21 while (p) {
22 if (p->first_child)
23 print_branch(p->first_child, str + " " + p->text);
24 printf("%d%s\n", p->id, (str + " " + p->text).c_str());
25 BindingTree *s = p->next_sibling;
26 delete p;
27 p = s;
28 }
29 }
30
31
32 void OBBindings::display()
33 {
34 if (_bindings.first_child)
35 print_branch(_bindings.first_child, "");
36 }
37
38
39
40 static bool translate(const std::string str, Binding &b)
41 {
42 KeySym sym = XStringToKeysym(const_cast<char *>(str.c_str()));
43 if (sym == NoSymbol) return false;
44 b.modifiers = Mod1Mask;
45 b.key = XKeysymToKeycode(otk::OBDisplay::display, sym);
46 return b.key != 0;
47 }
48
49 static BindingTree *buildtree(const OBBindings::StringVect &keylist, int id)
50 {
51 if (keylist.empty()) return 0; // nothing in the list.. return 0
52
53 BindingTree *ret = new BindingTree(id), *p = 0;
54
55 OBBindings::StringVect::const_iterator it, end = keylist.end();
56 for (it = keylist.begin(); it != end; ++it) {
57 if (p)
58 p = p->first_child = new BindingTree(id);
59 else
60 p = ret; // the first node
61
62 if (!translate(*it, p->binding))
63 break;
64 p->text = *it;
65 }
66 if (it != end) {
67 // build failed.. clean up and return 0
68 p = ret;
69 while (p->first_child) {
70 BindingTree *c = p->first_child;
71 delete p;
72 p = c;
73 }
74 delete p;
75 return 0;
76 } else {
77 // set the proper chain status on the last node
78 p->chain = false;
79 }
80
81 printf("<BUILDING>\n");
82 print_branch(ret);
83 printf("</BUILDING>\n");
84
85 // successfully built a tree
86 return ret;
87 }
88
89 static void destroytree(BindingTree *tree)
90 {
91 while (tree) {
92 BindingTree *c = tree->first_child;
93 delete tree;
94 tree = c;
95 }
96 }
97
98 OBBindings::OBBindings()
99 {
100 }
101
102
103 OBBindings::~OBBindings()
104 {
105 remove_all();
106 }
107
108
109 static void assimilate(BindingTree *parent, BindingTree *node)
110 {
111 BindingTree *p, *lastsib, *nextparent, *nextnode = node->first_child;
112
113 if (!parent->first_child) {
114 // there are no nodes at this level yet
115 parent->first_child = node;
116 nextparent = node;
117 } else {
118 p = lastsib = parent->first_child;
119
120 while (p->next_sibling) {
121 p = p->next_sibling;
122 lastsib = p; // finds the last sibling
123 if (p->binding == node->binding) {
124 // found an identical binding..
125 assert(node->chain && p->chain);
126 delete node; // kill the one we aren't using
127 break;
128 }
129 }
130 if (!p) {
131 // couldn't find an existing binding, use this new one, and insert it
132 // into the list
133 p = lastsib->next_sibling = node;
134 }
135 nextparent = p;
136 }
137
138 if (nextnode)
139 assimilate(nextparent, nextnode);
140 }
141
142
143 static int find_bind(BindingTree *tree, BindingTree *search) {
144 BindingTree *a, *b;
145 a = tree;
146 b = search;
147 while (a && b) {
148 if (a->binding != b->binding) {
149 a = a->next_sibling;
150 } else {
151 if (a->chain == b->chain) {
152 if (!a->chain)
153 return a->id; // found it! (return the actual id, not the search's)
154 } else
155 return -2; // the chain status' don't match (conflict!)
156 b = b->first_child;
157 a = a->first_child;
158 }
159 }
160 return -1; // it just isn't in here
161 }
162
163 /*
164 static int find(BindingTree *parent, BindingTree *node) {
165 BindingTree *p, *lastsib, *nextparent, *nextnode = node->first_child;
166
167 if (!parent->first_child)
168 return -1;
169
170 p = parent->first_child;
171 while (p) {
172 if (node->binding == p->binding) {
173 if (node->chain == p->chain) {
174 if (!node->chain) {
175 return p->id; // found it! (return the actual id, not the search's)
176 } else {
177 break; // go on to the next child in the chain
178 }
179 } else {
180 return -2; // the chain status' don't match (conflict!)
181 }
182 }
183 p = p->next_sibling;
184 }
185 if (!p) return -1; // doesn't exist
186
187 if (node->chain) {
188 assert(node->first_child);
189 return find(p, node->first_child);
190 } else
191 return -1; // it just isnt in here
192 }
193 */
194
195 bool OBBindings::add(const StringVect &keylist, int id)
196 {
197 BindingTree *tree;
198
199 if (!(tree = buildtree(keylist, id)))
200 return false; // invalid binding requested
201
202 if (find_bind(_bindings.first_child, tree) < -1) {
203 // conflicts with another binding
204 destroytree(tree);
205 return false;
206 }
207
208 // assimilate this built tree into the main tree
209 assimilate(&_bindings, tree); // assimilation destroys/uses the tree
210 return true;
211 }
212
213
214 int OBBindings::find(const StringVect &keylist)
215 {
216 BindingTree *tree;
217 bool ret;
218
219 if (!(tree = buildtree(keylist, 0)))
220 return false; // invalid binding requested
221
222 ret = find_bind(_bindings.first_child, tree) >= 0;
223
224 destroytree(tree);
225
226 return ret;
227 }
228
229
230 int OBBindings::remove(const StringVect &keylist)
231 {
232 (void)keylist;
233 assert(false); // XXX: function not implemented yet
234 }
235
236
237 static void remove_branch(BindingTree *first)
238 {
239 BindingTree *p = first;
240
241 while (p) {
242 if (p->first_child)
243 remove_branch(p->first_child);
244 BindingTree *s = p->next_sibling;
245 delete p;
246 p = s;
247 }
248 }
249
250
251 void OBBindings::remove_all()
252 {
253 if (_bindings.first_child)
254 remove_branch(_bindings.first_child);
255 }
256
257 }
This page took 0.043386 seconds and 4 git commands to generate.