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