diff options
Diffstat (limited to 'src/Keys.cc')
-rw-r--r-- | src/Keys.cc | 583 |
1 files changed, 583 insertions, 0 deletions
diff --git a/src/Keys.cc b/src/Keys.cc new file mode 100644 index 0000000..fad11af --- /dev/null +++ b/src/Keys.cc | |||
@@ -0,0 +1,583 @@ | |||
1 | // Key2.cc for Fluxbox - an X11 Window manager | ||
2 | // Copyright (c) 2001 Henrik Kinnunen (fluxgen@linuxmail.org) | ||
3 | // | ||
4 | // Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | // copy of this software and associated documentation files (the "Software"), | ||
6 | // to deal in the Software without restriction, including without limitation | ||
7 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | // and/or sell copies of the Software, and to permit persons to whom the | ||
9 | // Software is furnished to do so, subject to the following conditions: | ||
10 | // | ||
11 | // The above copyright notice and this permission notice shall be included in | ||
12 | // all copies or substantial portions of the Software. | ||
13 | // | ||
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | // DEALINGS IN THE SOFTWARE. | ||
21 | |||
22 | |||
23 | #ifdef HAVE_CONFIG_H | ||
24 | # include "config.h" | ||
25 | #endif | ||
26 | |||
27 | #ifdef HAVE_STDIO_H | ||
28 | # include <stdio.h> | ||
29 | #endif // HAVE_STDIO_H | ||
30 | |||
31 | #ifdef HAVE_CTYPE_H | ||
32 | # include <ctype.h> | ||
33 | #endif // HAVE_CTYPE_H | ||
34 | |||
35 | #ifdef STDC_HEADERS | ||
36 | # include <stdlib.h> | ||
37 | # include <string.h> | ||
38 | # include <errno.h> | ||
39 | #endif // STDC_HEADERS | ||
40 | |||
41 | #if HAVE_STRINGS_H | ||
42 | # include <strings.h> | ||
43 | #endif | ||
44 | |||
45 | #ifdef HAVE_SYS_TYPES_H | ||
46 | # include <sys/types.h> | ||
47 | #endif // HAVE_SYS_TYPES_H | ||
48 | |||
49 | #ifdef HAVE_SYS_WAIT_H | ||
50 | # include <sys/wait.h> | ||
51 | #endif // HAVE_SYS_WAIT_H | ||
52 | |||
53 | #ifdef HAVE_UNISTD_H | ||
54 | # include <unistd.h> | ||
55 | #endif // HAVE_UNISTD_H | ||
56 | |||
57 | #ifdef HAVE_SYS_STAT_H | ||
58 | # include <sys/stat.h> | ||
59 | #endif // HAVE_SYS_STAT_H | ||
60 | |||
61 | #include <X11/Xlib.h> | ||
62 | #include <X11/Xproto.h> | ||
63 | #include <X11/keysym.h> | ||
64 | |||
65 | #include "Keys.hh" | ||
66 | #include "fluxbox.hh" | ||
67 | |||
68 | #include <iostream> | ||
69 | #include <fstream> | ||
70 | |||
71 | using namespace std; | ||
72 | |||
73 | Keys::t_actionstr Keys::m_actionlist[] = { | ||
74 | {"Minimize", grabIconify}, | ||
75 | {"Raise", grabRaise}, | ||
76 | {"Lower", grabLower}, | ||
77 | {"Close", grabClose}, | ||
78 | {"AbortKeychain", grabAbortKeychain}, | ||
79 | {"Workspace1", grabWorkspace1}, | ||
80 | {"Workspace2", grabWorkspace2}, | ||
81 | {"Workspace3", grabWorkspace3}, | ||
82 | {"Workspace4", grabWorkspace4}, | ||
83 | {"Workspace5", grabWorkspace5}, | ||
84 | {"Workspace6", grabWorkspace6}, | ||
85 | {"Workspace7", grabWorkspace7}, | ||
86 | {"Workspace8", grabWorkspace8}, | ||
87 | {"Workspace9", grabWorkspace9}, | ||
88 | {"Workspace10", grabWorkspace10}, | ||
89 | {"Workspace11", grabWorkspace11}, | ||
90 | {"Workspace12", grabWorkspace12}, | ||
91 | {"NextWorkspace", grabNextWorkspace}, | ||
92 | {"PrevWorkspace", grabPrevWorkspace}, | ||
93 | {"LeftWorkspace", grabLeftWorkspace}, | ||
94 | {"RightWorkspace", grabRightWorkspace}, | ||
95 | {"KillWindow", grabKillWindow}, | ||
96 | {"NextWindow", grabNextWindow}, | ||
97 | {"PrevWindow", grabPrevWindow}, | ||
98 | {"NextTab", grabNextTab}, | ||
99 | {"PrevTab", grabPrevTab}, | ||
100 | {"ShadeWindow", grabShade}, | ||
101 | {"MaximizeWindow", grabMaximize}, | ||
102 | {"StickWindow", grabStick}, | ||
103 | {"ExecCommand", grabExecute}, | ||
104 | {"MaximizeVertical", grabVertMax}, | ||
105 | {"MaximizeHorizontal", grabHorizMax}, | ||
106 | {"NudgeRight", grabNudgeRight}, | ||
107 | {"NudgeLeft", grabNudgeLeft}, | ||
108 | {"NudgeUp", grabNudgeUp}, | ||
109 | {"NudgeDown", grabNudgeDown}, | ||
110 | {"BigNudgeRight", grabBigNudgeRight}, | ||
111 | {"BigNudgeLeft", grabBigNudgeLeft}, | ||
112 | {"BigNudgeUp", grabBigNudgeUp}, | ||
113 | {"BigNudgeDown", grabBigNudgeDown}, | ||
114 | {"HorizontalIncrement", grabHorizInc}, | ||
115 | {"VerticalIncrement", grabVertInc}, | ||
116 | {"HorizontalDecrement", grabHorizDec}, | ||
117 | {"VerticalDecrement", grabVertDec}, | ||
118 | {"ToggleDecor", grabToggleDecor}, | ||
119 | {0, lastKeygrab} | ||
120 | }; | ||
121 | |||
122 | Keys::Keys(char *filename) { | ||
123 | m_abortkey=0; | ||
124 | load(filename); | ||
125 | } | ||
126 | |||
127 | Keys::~Keys() { | ||
128 | deleteTree(); | ||
129 | } | ||
130 | //--------- deleteTree ----------- | ||
131 | // Destroys the keytree and m_abortkey | ||
132 | //-------------------------------- | ||
133 | void Keys::deleteTree() { | ||
134 | while (!m_keylist.empty()) { | ||
135 | if (m_keylist.back()) | ||
136 | delete m_keylist.back(); | ||
137 | m_keylist.pop_back(); | ||
138 | } | ||
139 | if (m_abortkey) { | ||
140 | delete m_abortkey; | ||
141 | m_abortkey=0; | ||
142 | } | ||
143 | } | ||
144 | //-------------- load ---------------- | ||
145 | // Load and grab keys | ||
146 | // Returns true on success else false | ||
147 | // TODO: error checking and nls on them? | ||
148 | // and possible replacement of strtok | ||
149 | //------------------------------------ | ||
150 | bool Keys::load(char *filename) { | ||
151 | if (!filename) | ||
152 | return false; | ||
153 | |||
154 | Fluxbox *fluxbox = Fluxbox::instance(); | ||
155 | Display *display = fluxbox->getXDisplay(); | ||
156 | ScreenInfo *screeninfo=0; | ||
157 | //ungrab all keys | ||
158 | int screen=0; | ||
159 | while ((screeninfo = fluxbox->getScreenInfo(screen++)) ) { | ||
160 | XUngrabKey(display, AnyKey, AnyModifier, | ||
161 | screeninfo->getRootWindow()); | ||
162 | } | ||
163 | |||
164 | XSync(display, False); | ||
165 | |||
166 | //open the file | ||
167 | ifstream infile(filename); | ||
168 | if (!infile) | ||
169 | return false; | ||
170 | |||
171 | |||
172 | char *linebuffer = new char[1024]; | ||
173 | int line=0; | ||
174 | int linepos=0; //position in the line | ||
175 | |||
176 | while (!infile.eof()) { | ||
177 | infile.getline(linebuffer, 1024); | ||
178 | |||
179 | line++; | ||
180 | char *val = strtok(linebuffer, " "); | ||
181 | linepos = (val==0 ? 0 : strlen(val) + 1); | ||
182 | |||
183 | int numarg = 1; | ||
184 | unsigned int key=0, mod=0; | ||
185 | char keyarg=0; | ||
186 | t_key *current_key=0, *last_key=0; | ||
187 | |||
188 | while (val) { | ||
189 | |||
190 | if (val[0]!=':') { | ||
191 | keyarg++; | ||
192 | if (keyarg==1) //first arg is modifier | ||
193 | mod = getModifier(val); | ||
194 | else if (keyarg>1) { | ||
195 | |||
196 | //keyarg=0; | ||
197 | key = getKey(val); | ||
198 | if (!key){ //if no keycode was found try the modifier | ||
199 | int tmpmod = getModifier(val); | ||
200 | if (tmpmod) | ||
201 | mod |= tmpmod; //add it to modifier | ||
202 | |||
203 | } else if (!current_key) { | ||
204 | |||
205 | current_key = new t_key(key, mod); | ||
206 | last_key = current_key; | ||
207 | |||
208 | } else { | ||
209 | |||
210 | t_key *temp_key = new t_key(key, mod); | ||
211 | last_key->keylist.push_back(temp_key); | ||
212 | last_key = temp_key; | ||
213 | } | ||
214 | |||
215 | } | ||
216 | |||
217 | } else { | ||
218 | |||
219 | val++; //ignore the ':' | ||
220 | |||
221 | unsigned int i=0; | ||
222 | |||
223 | for (i=0; i< lastKeygrab; i++) { | ||
224 | if (strcasecmp(m_actionlist[i].string, val) == 0) | ||
225 | break; | ||
226 | } | ||
227 | |||
228 | if (i < lastKeygrab ) { | ||
229 | if (!current_key) { | ||
230 | cerr<<"Error on line: "<<line<<endl; | ||
231 | cerr<<linebuffer<<endl; | ||
232 | delete current_key; | ||
233 | current_key = 0; | ||
234 | last_key = 0; | ||
235 | break; //break out and read next line | ||
236 | } | ||
237 | |||
238 | //special case for grabAbortKeychain | ||
239 | if (m_actionlist[i].action == grabAbortKeychain) { | ||
240 | if (last_key!=current_key) | ||
241 | cerr<<"Keys: "<<m_actionlist[i].string<<" cant be in chained mode"<<endl; | ||
242 | else if (m_abortkey) | ||
243 | cerr<<"Keys: "<<m_actionlist[i].string<<" is already bound."<<endl; | ||
244 | else | ||
245 | m_abortkey = new t_key(current_key->key, current_key->mod, grabAbortKeychain); | ||
246 | |||
247 | delete current_key; | ||
248 | current_key = 0; | ||
249 | last_key = 0; | ||
250 | break; //break out and read next line | ||
251 | } | ||
252 | |||
253 | last_key->action = m_actionlist[i].action; | ||
254 | if (last_key->action == grabExecute) | ||
255 | last_key->execcommand = &linebuffer[linepos]; | ||
256 | |||
257 | //add the keychain to list | ||
258 | if (!mergeTree(current_key)) | ||
259 | cerr<<"Keys: Faild to merge keytree!"<<endl; | ||
260 | |||
261 | #ifdef DEBUG | ||
262 | if (m_actionlist[i].action == Keys::grabExecute) { | ||
263 | |||
264 | cerr<<"linepos:"<<linepos<<endl; | ||
265 | cerr<<"buffer:"<<&linebuffer[linepos]<<endl; | ||
266 | cerr<<"command:"<<last_key->execcommand<<endl; | ||
267 | |||
268 | } | ||
269 | #endif | ||
270 | |||
271 | //clear keypointers now that we have them in m_keylist | ||
272 | delete current_key; | ||
273 | current_key = 0; | ||
274 | last_key = 0; | ||
275 | |||
276 | } else { //destroy list if no action is found | ||
277 | #ifdef DEBUG | ||
278 | cerr<<"Didnt find action="<<val<<endl; | ||
279 | #endif | ||
280 | //destroy current_key ... this will also destroy the last_key | ||
281 | delete current_key; | ||
282 | current_key = 0; | ||
283 | last_key = 0; | ||
284 | } | ||
285 | |||
286 | break; //dont process this linebuffer more | ||
287 | } | ||
288 | numarg++; | ||
289 | val = strtok(0, " "); | ||
290 | linepos += (val == 0 ? 0 : strlen(val) + 1); | ||
291 | } | ||
292 | } | ||
293 | |||
294 | delete linebuffer; | ||
295 | #ifdef DEBUG | ||
296 | showTree(); | ||
297 | #endif | ||
298 | return true; | ||
299 | } | ||
300 | |||
301 | //--------- grabKey --------------- | ||
302 | // Grabs a key with the modifier | ||
303 | // and with numlock,capslock and scrollock | ||
304 | //--------------------------------- | ||
305 | void Keys::grabKey(unsigned int key, unsigned int mod) { | ||
306 | |||
307 | Fluxbox *fluxbox = Fluxbox::instance(); | ||
308 | Display *display = fluxbox->getXDisplay(); | ||
309 | |||
310 | #ifdef DEBUG | ||
311 | cerr<<__FILE__<<"("<<__LINE__<<"): keycode "<<key<<" mod "<<hex<<mod<<dec<<endl; | ||
312 | #endif | ||
313 | int i=0; | ||
314 | ScreenInfo *screeninfo=0; | ||
315 | |||
316 | while ((screeninfo = fluxbox->getScreenInfo(i++)) ) { | ||
317 | Window root = screeninfo->getRootWindow(); | ||
318 | XGrabKey(display, key, mod, | ||
319 | root, True, | ||
320 | GrabModeAsync, GrabModeAsync); | ||
321 | |||
322 | // Grab with numlock, capslock and scrlock | ||
323 | |||
324 | //numlock | ||
325 | XGrabKey(display, key, mod|Mod2Mask, | ||
326 | root, True, | ||
327 | GrabModeAsync, GrabModeAsync); | ||
328 | //scrolllock | ||
329 | XGrabKey(display, key, mod|Mod5Mask, | ||
330 | root, True, | ||
331 | GrabModeAsync, GrabModeAsync); | ||
332 | //capslock | ||
333 | XGrabKey(display, key, mod|LockMask, | ||
334 | root, True, | ||
335 | GrabModeAsync, GrabModeAsync); | ||
336 | |||
337 | //capslock+numlock | ||
338 | XGrabKey(display, key, mod|LockMask|Mod2Mask, | ||
339 | root, True, | ||
340 | GrabModeAsync, GrabModeAsync); | ||
341 | |||
342 | //capslock+scrolllock | ||
343 | XGrabKey(display, key, mod|LockMask|Mod5Mask, | ||
344 | root, True, | ||
345 | GrabModeAsync, GrabModeAsync); | ||
346 | |||
347 | //capslock+numlock+scrolllock | ||
348 | XGrabKey(display, key, mod|Mod2Mask|Mod5Mask|LockMask, | ||
349 | root, True, | ||
350 | GrabModeAsync, GrabModeAsync); | ||
351 | |||
352 | //numlock+scrollLock | ||
353 | XGrabKey(display, key, mod|Mod2Mask|Mod5Mask, | ||
354 | root, True, | ||
355 | GrabModeAsync, GrabModeAsync); | ||
356 | |||
357 | } | ||
358 | |||
359 | } | ||
360 | |||
361 | //------------ getModifier --------------- | ||
362 | // Returns the modifier for the modstr | ||
363 | // else zero on failure. | ||
364 | // TODO fix more masks | ||
365 | //---------------------------------------- | ||
366 | unsigned int Keys::getModifier(char *modstr) { | ||
367 | if (!modstr) | ||
368 | return 0; | ||
369 | struct t_modlist{ | ||
370 | char *string; | ||
371 | unsigned int mask; | ||
372 | bool operator == (char *modstr) { | ||
373 | return (strcasecmp(string, modstr) == 0 && mask !=0); | ||
374 | } | ||
375 | } modlist[] = { | ||
376 | {"SHIFT", ShiftMask}, | ||
377 | {"CONTROL", ControlMask}, | ||
378 | {"MOD1", Mod1Mask}, | ||
379 | {"MOD2", Mod2Mask}, | ||
380 | {"MOD3", Mod3Mask}, | ||
381 | {"MOD4", Mod4Mask}, | ||
382 | {"MOD5", Mod5Mask}, | ||
383 | {0, 0} | ||
384 | }; | ||
385 | |||
386 | for (unsigned int i=0; modlist[i].string!=0; i++) { | ||
387 | if (modlist[i]==modstr) | ||
388 | return modlist[i].mask; | ||
389 | } | ||
390 | |||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | //----------- getKey ---------------- | ||
395 | // Returns keycode of keystr on success | ||
396 | // else it returns zero | ||
397 | //----------------------------------- | ||
398 | unsigned int Keys::getKey(char *keystr) { | ||
399 | if (!keystr) | ||
400 | return 0; | ||
401 | return XKeysymToKeycode(Fluxbox::instance()->getXDisplay(), | ||
402 | XStringToKeysym | ||
403 | (keystr)); | ||
404 | } | ||
405 | |||
406 | //--------- getAction ----------------- | ||
407 | // returns the KeyAction of the XKeyEvent | ||
408 | //------------------------------------- | ||
409 | Keys::KeyAction Keys::getAction(XKeyEvent *ke) { | ||
410 | static t_key *next_key = 0; | ||
411 | //remove numlock, capslock and scrolllock | ||
412 | ke->state &= ~Mod2Mask & ~Mod5Mask & ~LockMask; | ||
413 | |||
414 | if (m_abortkey && *m_abortkey==ke) { //abort current keychain | ||
415 | next_key = 0; | ||
416 | return m_abortkey->action; | ||
417 | } | ||
418 | |||
419 | if (!next_key) { | ||
420 | |||
421 | for (unsigned int i=0; i<m_keylist.size(); i++) { | ||
422 | if (*m_keylist[i] == ke) { | ||
423 | if (m_keylist[i]->keylist.size()) { | ||
424 | next_key = m_keylist[i]; | ||
425 | break; //end for-loop | ||
426 | } else { | ||
427 | if (m_keylist[i]->action == grabExecute) | ||
428 | m_execcmdstring = m_keylist[i]->execcommand; //update execcmdstring if action is grabExecute | ||
429 | return m_keylist[i]->action; | ||
430 | } | ||
431 | } | ||
432 | } | ||
433 | |||
434 | } else { //check the nextkey | ||
435 | t_key *temp_key = next_key->find(ke); | ||
436 | if (temp_key) { | ||
437 | if (temp_key->keylist.size()) { | ||
438 | next_key = temp_key; | ||
439 | } else { | ||
440 | next_key = 0; | ||
441 | if (temp_key->action == grabExecute) | ||
442 | m_execcmdstring = temp_key->execcommand; //update execcmdstring if action is grabExecute | ||
443 | return temp_key->action; | ||
444 | } | ||
445 | } else { | ||
446 | temp_key = next_key; | ||
447 | next_key = 0; | ||
448 | if (temp_key->action == grabExecute) | ||
449 | m_execcmdstring = temp_key->execcommand; //update execcmdstring if action is grabExecute | ||
450 | return temp_key->action; | ||
451 | } | ||
452 | |||
453 | } | ||
454 | |||
455 | return lastKeygrab; | ||
456 | } | ||
457 | |||
458 | //--------- reconfigure ------------- | ||
459 | // deletes the tree and load configuration | ||
460 | // returns true on success else false | ||
461 | //----------------------------------- | ||
462 | bool Keys::reconfigure(char *filename) { | ||
463 | deleteTree(); | ||
464 | return load(filename); | ||
465 | } | ||
466 | |||
467 | //------------- getActionStr ------------------ | ||
468 | // Tries to find the action for the key | ||
469 | // Returns actionstring on success else | ||
470 | // 0 on failure | ||
471 | //--------------------------------------------- | ||
472 | const char *Keys::getActionStr(KeyAction action) { | ||
473 | for (unsigned int i=0; m_actionlist[i].string!=0 ; i++) { | ||
474 | if (m_actionlist[i].action == action) | ||
475 | return m_actionlist[i].string; | ||
476 | } | ||
477 | |||
478 | return 0; | ||
479 | } | ||
480 | |||
481 | #ifdef DEBUG | ||
482 | //--------- showTree ----------- | ||
483 | // Debug function that show the | ||
484 | // keytree. Starts with the | ||
485 | // rootlist | ||
486 | //------------------------------ | ||
487 | void Keys::showTree() { | ||
488 | for (unsigned int i=0; i<m_keylist.size(); i++) { | ||
489 | if (m_keylist[i]) { | ||
490 | cerr<<i<<" "; | ||
491 | showKeyTree(m_keylist[i]); | ||
492 | } else | ||
493 | cerr<<"Null @ "<<i<<endl; | ||
494 | } | ||
495 | } | ||
496 | |||
497 | //---------- showKeyTree -------- | ||
498 | // Debug function to show t_key tree | ||
499 | //------------------------------- | ||
500 | void Keys::showKeyTree(t_key *key, unsigned int w) { | ||
501 | for (unsigned int i=0; i<w+1; i++) | ||
502 | cerr<<"-"; | ||
503 | if (!key->keylist.empty()) { | ||
504 | for (unsigned int i=0; i<key->keylist.size(); i++) { | ||
505 | cerr<<"( "<<(int)key->key<<" "<<(int)key->mod<<" )"; | ||
506 | showKeyTree(key->keylist[i], 4); | ||
507 | cerr<<endl; | ||
508 | } | ||
509 | } else | ||
510 | cerr<<"( "<<(int)key->key<<" "<<(int)key->mod<<" ) {"<<getActionStr(key->action)<<"}"<<endl; | ||
511 | } | ||
512 | #endif //DEBUG | ||
513 | //------------ mergeTree --------------- | ||
514 | // Merges two chains and binds new keys | ||
515 | // Returns true on success else false. | ||
516 | //--------------------------------------- | ||
517 | bool Keys::mergeTree(t_key *newtree, t_key *basetree) { | ||
518 | if (basetree==0) { | ||
519 | unsigned int baselist_i=0; | ||
520 | for (; baselist_i<m_keylist.size(); baselist_i++) { | ||
521 | if (m_keylist[baselist_i]->mod == newtree->mod && | ||
522 | m_keylist[baselist_i]->key == newtree->key) { | ||
523 | if (newtree->keylist.size() && m_keylist[baselist_i]->action == lastKeygrab) { | ||
524 | //assumes the newtree only have one branch | ||
525 | return mergeTree(newtree->keylist[0], m_keylist[baselist_i]); | ||
526 | } else | ||
527 | break; | ||
528 | } | ||
529 | } | ||
530 | |||
531 | if (baselist_i == m_keylist.size()) { | ||
532 | grabKey(newtree->key, newtree->mod); | ||
533 | m_keylist.push_back(new t_key(newtree)); | ||
534 | if (newtree->keylist.size()) | ||
535 | return mergeTree(newtree->keylist[0], m_keylist.back()); | ||
536 | return true; | ||
537 | } | ||
538 | |||
539 | } else { | ||
540 | unsigned int baselist_i = 0; | ||
541 | for (; baselist_i<basetree->keylist.size(); baselist_i++) { | ||
542 | if (basetree->keylist[baselist_i]->mod == newtree->mod && | ||
543 | basetree->keylist[baselist_i]->key == newtree->key) { | ||
544 | if (newtree->keylist.size()) { | ||
545 | //assumes the newtree only have on branch | ||
546 | return mergeTree(newtree->keylist[0], basetree->keylist[baselist_i]); | ||
547 | } else | ||
548 | return false; | ||
549 | } | ||
550 | } | ||
551 | //if it wasn't in the list grab the key and add it to the list | ||
552 | if (baselist_i==basetree->keylist.size()) { | ||
553 | grabKey(newtree->key, newtree->mod); | ||
554 | basetree->keylist.push_back(new t_key(newtree)); | ||
555 | if (newtree->keylist.size()) | ||
556 | return mergeTree(newtree->keylist[0], basetree->keylist.back()); | ||
557 | return true; | ||
558 | } | ||
559 | } | ||
560 | |||
561 | return false; | ||
562 | } | ||
563 | |||
564 | Keys::t_key::t_key(unsigned int key_, unsigned int mod_, KeyAction action_) { | ||
565 | action = action_; | ||
566 | key = key_; | ||
567 | mod = mod_; | ||
568 | } | ||
569 | |||
570 | Keys::t_key::t_key(t_key *k) { | ||
571 | action = k->action; | ||
572 | key = k->key; | ||
573 | mod = k->mod; | ||
574 | execcommand = k->execcommand; | ||
575 | } | ||
576 | |||
577 | Keys::t_key::~t_key() { | ||
578 | while (!keylist.empty()) { | ||
579 | t_key *k = keylist.back(); | ||
580 | delete k; | ||
581 | keylist.pop_back(); | ||
582 | } | ||
583 | } | ||