]> Dogcows Code - chaz/openbox/blob - src/bindings.cc
the bindings tree might work now
[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 if (!p->chain)
25 printf("%d%s\n", p->id, (str + " " + p->text).c_str());
26 BindingTree *s = p->next_sibling;
27 delete p;
28 p = s;
29 }
30 }
31
32
33 void OBBindings::display()
34 {
35 if (_tree.first_child)
36 print_branch(_tree.first_child, "");
37 }
38
39
40
41 bool OBBindings::translate(const std::string &str, Binding &b)
42 {
43 unsigned int mods = 0;
44
45 // parse out the base key name
46 std::string::size_type keybegin = str.find_last_of('-');
47 keybegin = (keybegin == std::string::npos) ? 0 : keybegin + 1;
48 std::string key(str, keybegin);
49
50 // XXX: get some modifiers up in the hizzie
51 // parse out the requested modifier keys
52 std::string::size_type begin = 0, end;
53 while (begin != keybegin) {
54 end = str.find_first_of('-', begin);
55
56 std::string mod(str, begin, end-begin);
57
58 if (mod == "C") { // control
59 mods |= ControlMask;
60 } else if (mod == "S") { // shift
61 mods |= ShiftMask;
62 } else if (mod == "A" || // alt/mod1
63 mod == "M" ||
64 mod == "M1" ||
65 mod == "Mod1") {
66 mods |= Mod1Mask;
67 } else if (mod == "M2" || // mod2
68 mod == "Mod2") {
69 mods |= Mod2Mask;
70 } else if (mod == "M3" || // mod3
71 mod == "Mod3") {
72 mods |= Mod3Mask;
73 } else if (mod == "W" || // windows/mod4
74 mod == "M4" ||
75 mod == "Mod4") {
76 mods |= Mod4Mask;
77 } else if (mod == "M5" || // mod5
78 mod == "Mod5") {
79 mods |= Mod5Mask;
80 }
81 printf("got modifier: got modifier: %s\n", mod.c_str());
82
83 begin = end + 1;
84 }
85
86 KeySym sym = XStringToKeysym(const_cast<char *>(key.c_str()));
87 if (sym == NoSymbol) return false;
88 b.modifiers = mods;
89 b.key = XKeysymToKeycode(otk::OBDisplay::display, sym);
90 return b.key != 0;
91 }
92
93 BindingTree *OBBindings::buildtree(const StringVect &keylist, int id)
94 {
95 if (keylist.empty()) return 0; // nothing in the list.. return 0
96
97 BindingTree *ret = new BindingTree(id), *p = 0;
98
99 StringVect::const_iterator it, end = keylist.end();
100 for (it = keylist.begin(); it != end; ++it) {
101 if (p)
102 p = p->first_child = new BindingTree(id);
103 else
104 p = ret; // the first node
105
106 if (!translate(*it, p->binding))
107 break;
108 p->text = *it;
109 }
110 if (it != end) {
111 // build failed.. clean up and return 0
112 p = ret;
113 while (p->first_child) {
114 BindingTree *c = p->first_child;
115 delete p;
116 p = c;
117 }
118 delete p;
119 return 0;
120 } else {
121 // set the proper chain status on the last node
122 p->chain = false;
123 }
124
125 printf("BUILDING:\n");
126 print_branch(ret, "");
127
128 // successfully built a tree
129 return ret;
130 }
131
132 static void destroytree(BindingTree *tree)
133 {
134 while (tree) {
135 BindingTree *c = tree->first_child;
136 delete tree;
137 tree = c;
138 }
139 }
140
141 OBBindings::OBBindings()
142 {
143 }
144
145
146 OBBindings::~OBBindings()
147 {
148 remove_all();
149 }
150
151
152 void OBBindings::assimilate(BindingTree *node)
153 {
154 BindingTree *a, *b, *tmp, *last;
155
156 if (!parent->first_child) {
157 // there are no nodes at this level yet
158 parent->first_child = node;
159 return;
160 } else {
161 a = parent->first_child;
162 last = a;
163 b = node;
164 while (a->first_child) {
165 last = a;
166 if (a->binding != b->binding) {
167 a = a->next_sibling;
168 } else {
169 tmp = b;
170 b = b->first_child;
171 delete tmp;
172 a = a->first_child;
173 }
174 }
175 last->first_child = b->first_child;
176 delete b;
177 }
178 }
179
180
181 int OBBindings::find(BindingTree *search) {
182 BindingTree *a, *b;
183 a = _tree.first_child;
184 b = search;
185 while (a && b) {
186 if (a->binding != b->binding) {
187 a = a->next_sibling;
188 } else {
189 if (a->chain == b->chain) {
190 if (!a->chain)
191 return a->id; // found it! (return the actual id, not the search's)
192 } else
193 return -2; // the chain status' don't match (conflict!)
194 b = b->first_child;
195 a = a->first_child;
196 }
197 }
198 return -1; // it just isn't in here
199 }
200
201 /*
202 static int find(BindingTree *parent, BindingTree *node) {
203 BindingTree *p, *lastsib, *nextparent, *nextnode = node->first_child;
204
205 if (!parent->first_child)
206 return -1;
207
208 p = parent->first_child;
209 while (p) {
210 if (node->binding == p->binding) {
211 if (node->chain == p->chain) {
212 if (!node->chain) {
213 return p->id; // found it! (return the actual id, not the search's)
214 } else {
215 break; // go on to the next child in the chain
216 }
217 } else {
218 return -2; // the chain status' don't match (conflict!)
219 }
220 }
221 p = p->next_sibling;
222 }
223 if (!p) return -1; // doesn't exist
224
225 if (node->chain) {
226 assert(node->first_child);
227 return find(p, node->first_child);
228 } else
229 return -1; // it just isnt in here
230 }
231 */
232
233 bool OBBindings::add(const StringVect &keylist, int id)
234 {
235 BindingTree *tree;
236
237 if (!(tree = buildtree(keylist, id)))
238 return false; // invalid binding requested
239
240 if (find(tree) < -1) {
241 // conflicts with another binding
242 destroytree(tree);
243 return false;
244 }
245
246 // assimilate this built tree into the main tree
247 assimilate(tree); // assimilation destroys/uses the tree
248 return true;
249 }
250
251
252 int OBBindings::find(const StringVect &keylist)
253 {
254 BindingTree *tree;
255 bool ret;
256
257 if (!(tree = buildtree(keylist, 0)))
258 return false; // invalid binding requested
259
260 ret = find(tree) >= 0;
261
262 destroytree(tree);
263
264 return ret;
265 }
266
267
268 int OBBindings::remove(const StringVect &keylist)
269 {
270 (void)keylist;
271 assert(false); // XXX: function not implemented yet
272 }
273
274
275 static void remove_branch(BindingTree *first)
276 {
277 BindingTree *p = first;
278
279 while (p) {
280 if (p->first_child)
281 remove_branch(p->first_child);
282 BindingTree *s = p->next_sibling;
283 delete p;
284 p = s;
285 }
286 }
287
288
289 void OBBindings::remove_all()
290 {
291 if (_tree.first_child)
292 remove_branch(_tree.first_child);
293 }
294
295 }
This page took 0.047193 seconds and 5 git commands to generate.