summaryrefslogtreecommitdiff
path: root/noncore/apps/keyz-cfg/zkb.cpp
Unidiff
Diffstat (limited to 'noncore/apps/keyz-cfg/zkb.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/keyz-cfg/zkb.cpp590
1 files changed, 590 insertions, 0 deletions
diff --git a/noncore/apps/keyz-cfg/zkb.cpp b/noncore/apps/keyz-cfg/zkb.cpp
new file mode 100644
index 0000000..abe1f5f
--- a/dev/null
+++ b/noncore/apps/keyz-cfg/zkb.cpp
@@ -0,0 +1,590 @@
1#include <qnamespace.h>
2#include "zkb.h"
3#include <stdio.h>
4
5// Implementation of Action class
6Action::Action():state(0), keycode(0), unicode(0), flags(0) {
7}
8
9Action::Action(State* s, ushort kc, ushort uni, int f):
10 state(s), keycode(kc), unicode(uni), flags(f) {
11}
12
13Action::~Action() {
14}
15
16State* Action::getState() const {
17 return state;
18}
19
20void Action::setState(State* s) {
21 state = s;
22 setDefined(true);
23}
24
25bool Action::hasEvent() const {
26 return flags & Event;
27}
28
29void Action::setEvent(bool e) {
30 flags = (flags & ~Event) | ((e) ? Event : 0);
31
32 if (e) {
33 setDefined(true);
34 } else {
35 if (state == 0) {
36 setDefined(false);
37 }
38 }
39}
40
41bool Action::isDefined() const {
42 return flags & Defined;
43}
44
45void Action::setDefined(bool d) {
46 flags = (flags & ~Defined) | ((d) ? Defined : 0);
47}
48
49int Action::getKeycode() const {
50 return keycode;
51}
52
53void Action::setKeycode(int c) {
54 keycode = (ushort) c;
55 setEvent(true);
56}
57
58int Action::getUnicode() const {
59 return unicode;
60}
61
62void Action::setUnicode(int u) {
63 unicode = (ushort) u;
64 setEvent(true);
65}
66
67int Action::getModifiers() const {
68 int ret = 0;
69 if (flags & Shift_Mod) {
70 ret |= Qt::ShiftButton;
71 }
72
73 if (flags & Ctrl_Mod) {
74 ret |= Qt::ControlButton;
75 }
76
77 if (flags & Alt_Mod) {
78 ret |= Qt::AltButton;
79 }
80
81 if (flags & Keypad_Mod) {
82 ret |= Qt::Keypad;
83 }
84
85 return ret;
86}
87
88void Action::setModifiers(int m) {
89 int n = 0;
90
91 if (m & Qt::ShiftButton) {
92 n |= Shift_Mod;
93 }
94
95 if (m & Qt::ControlButton) {
96 n |= Ctrl_Mod;
97 }
98
99 if (m & Qt::AltButton) {
100 n |= Alt_Mod;
101 }
102
103 if (m & Qt::Keypad) {
104 n |= Keypad_Mod;
105 }
106
107 flags = flags & ~Mod_Bits | n;
108 setEvent(true);
109}
110
111bool Action::isPressed() const {
112 return (flags & Press) != 0;
113}
114
115void Action::setPressed(bool p) {
116 flags = (flags & ~Press) | ((p) ? Press : 0);
117 setEvent(true);
118}
119
120bool Action::isAutorepeat() const {
121 return (flags & Autorepeat) != 0;
122}
123
124void Action::setAutorepeat(bool p) {
125 flags = (flags & ~Autorepeat) | ((p) ? Autorepeat : 0);
126 setEvent(true);
127}
128
129// Implementation of State class
130const short State::x1[] = { /* from 0x20 to 0x5f */
131 31, 0, 28, 3, 5, 6, 9, 28, /* 0x20 - 0x27 */
132 11, 26, 10, 13, 26, 1, 29, 27, /* 0x28 - 0x2f */
133 15, 16, 22, 4, 17, 19, 24, 20, /* 0x30 - 0x37 */
134 8, 14, 29, 26, 29, 12, 32, 27, /* 0x38 - 0x3f */
135 18, 0, 1, 2, 3, 4, 5, 6, /* 0x40 - 0x47 */
136 7, 8, 9, 10, 11, 12, 13, 14, /* 0x48 - 0x4f */
137 15, 16, 17, 18, 19, 20, 21, 22, /* 0x50 - 0x57 */
138 23, 24, 25, 30, -1, 26, 28, 7, /* 0x58 - 0x5f */
139 31, -1, -1, -1, -1, -1, -1, -1, /* 0x60 - 0x67 */
140 -1, -1, -1, -1, -1, -1, -1, -1, /* 0x68 - 0x6f */
141 -1, -1, -1, -1, -1, -1, -1, -1, /* 0x70 - 0x77 */
142 -1, -1, -1, 29, 31, 32, 32, 28, /* 0x78 - 0x7f */
143};
144
145const short State::x2[] = { /* from 0x1000 to 0x1057*/
146 42, 36, -1, 30, 32, -1, -1, -1, /* 0x1000 - 0x1007 */
147 -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1008 - 0x100f */
148 -1, -1, 44, 45, 46, 47, -1, -1, /* 0x1010 - 0x1017 */
149 -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1018 - 0x101f */
150 33, 35, 34, -1, 36, 27, -1, -1, /* 0x1020 - 0x1027 */
151 -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1028 - 0x102f */
152 -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1030 - 0x1037 */
153 37, 38, 40, 39, 41, -1, -1, -1, /* 0x1038 - 0x103f */
154 -1, -1, -1, -1, -1, 35, -1, -1, /* 0x1040 - 0x1047 */
155 -1, -1, -1, -1, -1, 48, -1, -1, /* 0x1048 - 0x104f */
156 43, 49, 50, -1, -1, -1, -1, -1, /* 0x1050 - 0x1057 */
157};
158
159State::State(State* p):parent(p), keys(0) {
160 keys = new Action[Key_Max * 2 + 1];
161}
162
163State::State(const State& s) {
164 parent = s.parent;
165 keys = new Action[Key_Max * 2 + 1];
166 memcpy(keys, s.keys, sizeof(Action) * (Key_Max * 2 + 1));
167}
168
169State::~State() {
170 if (keys!=0) {
171 delete [] keys;
172 }
173}
174
175Action* State::get(int keycode, bool pressed, bool follow) const {
176 Action* ret = 0;
177 int n = translateKeycode(keycode);
178
179 if (n != -1 && keys != 0) {
180 if (pressed) {
181 n += Key_Max;
182 }
183 ret = &keys[n];
184 }
185
186 if (ret==0 || !ret->isDefined()) {
187 if (follow && parent!=0) {
188 ret = parent->get(keycode, pressed, follow);
189 }
190 }
191
192 return ret;
193}
194
195bool State::set(int keycode, bool pressed, Action& action) {
196 int n = translateKeycode(keycode);
197
198 if (n==-1 || keys==0) {
199 return false;
200 }
201
202 if (pressed) {
203 n += Key_Max + 1;
204 }
205
206 keys[n] = action;
207 return true;
208}
209
210State* State::getParent() const {
211 return parent;
212}
213
214void State::setParent(State* s) {
215 parent = s;
216}
217
218int State::translateKeycode(int keycode) const {
219 if (keycode < 0x20) {
220 return -1;
221 }
222
223 if (keycode < 0x80) {
224 return x1[keycode - 0x20];
225 }
226
227 if (keycode < 0x1000) {
228 return -1;
229 }
230
231 if (keycode < 0x1057) {
232 return x2[keycode - 0x1000];
233 }
234
235 return -1;
236}
237
238// Implementation of Keymap class
239Keymap::Keymap():enabled(true), currentState(0), autoRepeatAction(0), repeater(this) {
240 repeatDelay=400;
241 repeatPeriod=80;
242 connect(&repeater, SIGNAL(timeout()), this, SLOT(autoRepeat()));
243}
244
245Keymap::~Keymap() {
246 QMap<QString, State*>::Iterator it;
247 for(it = states.begin(); it != states.end(); ++it) {
248 delete it.data();
249 }
250 states.clear();
251}
252
253bool Keymap::filter(int unicode, int keycode, int modifiers,
254 bool isPress, bool autoRepeat) {
255
256 qDebug("filter: >>> unicode=%x, keycode=%x, modifiers=%x, "
257 "ispressed=%x\n", unicode, keycode, modifiers, isPress);
258
259 if (!enabled) {
260 return false;
261 }
262
263 // the second check is workaround to make suspend work if
264 // the user pressed it right after he did resume. for some
265 // reason the event sent by qt has autoRepeat true in this
266 // case
267 if (autoRepeat && keycode != 4177) {
268 return true;
269 }
270
271 (void) unicode; (void) modifiers;
272
273 Action* action = currentState->get(keycode, isPress, true);
274 if (action==0 || !action->isDefined()) {
275 return true;
276 }
277
278 if (action->hasEvent()) {
279 qDebug("filter:<<< unicode=%x, keycode=%x, modifiers=%x, "
280 "ispressed=%x\n", action->getUnicode(),
281 action->getKeycode(), action->getModifiers(),
282 action->isPressed());
283
284 QWSServer::sendKeyEvent(action->getUnicode(),
285 action->getKeycode(), action->getModifiers(),
286 action->isPressed(), false);
287 }
288
289 if (action->isAutorepeat()) {
290 autoRepeatAction = action;
291 repeater.start(repeatDelay, TRUE);
292 } else {
293 autoRepeatAction = 0;
294 }
295
296 State* nstate = action->getState();
297 if (nstate != 0) {
298 setCurrentState(nstate);
299 QString lbl = getCurrentLabel();
300 if (!lbl.isEmpty()) {
301 emit stateChanged(lbl);
302 }
303 }
304
305
306 return true;
307}
308
309void Keymap::enable() {
310 enabled = true;
311}
312
313void Keymap::disable() {
314 enabled = false;
315}
316
317QStringList Keymap::listStates() {
318 QStringList ret;
319
320 QMap<QString, State*>::Iterator it;
321 for(it = states.begin(); it != states.end(); ++it) {
322 ret.append(it.key());
323 }
324
325 return ret;
326}
327
328State* Keymap::getStateByName(const QString& name) {
329 QMap<QString, State*>::Iterator it = states.find(name);
330
331 if (it == states.end()) {
332 return 0;
333 }
334
335 return it.data();
336}
337
338QStringList Keymap::listLabels() {
339 QStringList ret;
340
341 for(uint i = 0; i < labelList.count(); i++) {
342 ret.append(*labelList.at(i));
343 }
344
345 return ret;
346}
347
348State* Keymap::getStateByLabel(const QString& label) {
349 QMap<QString, QString>::Iterator lit = labels.find(label);
350 State* state = 0;
351
352 if (lit == labels.end()) {
353 return 0;
354 }
355
356 QString name = lit.data();
357
358 int n = name.find(":*");
359 if (n>=0 && n==(int)(name.length()-2)) {
360 name=name.left(name.length() - 1);
361
362 n = currentStateName.findRev(":");
363 if (n >= 0) {
364 name += currentStateName.mid(n+1);
365 }
366 }
367
368 //qDebug("look for: %s\n", (const char*) name.utf8());
369 QMap<QString, State*>::Iterator sit = states.find(name);
370 if (sit != states.end()) {
371 state = sit.data();
372 }
373
374 return state;
375}
376
377bool Keymap::addState(const QString& name, State* state) {
378 if (states.find(name) != states.end()) {
379 return false;
380 }
381
382 states.insert(name, state);
383 lsmapInSync = false;
384
385 if (currentState == 0) {
386 setCurrentState(state);
387 }
388
389 return true;
390}
391
392State* Keymap::getCurrentState() const {
393 return currentState;
394}
395
396QString Keymap::getCurrentLabel() {
397 return currentLabel;
398}
399
400bool Keymap::setCurrentState(State* state) {
401 QMap<QString, State*>::Iterator it;
402 for(it = states.begin(); it != states.end(); ++it) {
403 State* s = it.data();
404 if (s == state) {
405 currentState = s;
406 currentStateName = it.key();
407
408 qDebug("state changed: %s\n", (const char*)
409 currentStateName.utf8());
410
411 if (!lsmapInSync) {
412 generateLabelStateMaps();
413 }
414
415 QMap<State*, QString>::Iterator tit;
416 tit = stateLabelMap.find(state);
417 if (tit != stateLabelMap.end()) {
418 currentLabel = tit.data();
419 } else {
420 // qDebug("no label for: " + currentStateName + "\n");
421 currentLabel = "";
422 }
423
424 return true;
425 }
426 }
427
428 return false;
429}
430
431bool Keymap::removeState(const QString& name, bool force) {
432 QMap<QString, State*>::Iterator it = states.find(name);
433
434 if (it == states.end()) {
435 return false;
436 }
437
438 State* state = it.data();
439 QList<Action> acts = findStateUsage(state);
440
441 if (!acts.isEmpty()) {
442 if (!force) {
443 return false;
444 } else {
445 for(Action* a = acts.first(); a != 0; a = acts.next()) {
446 a->setState(0);
447 }
448 }
449 }
450
451 if (state == currentState) {
452 if (states.begin() != states.end()) {
453 setCurrentState(states.begin().data());
454 }
455 }
456
457 states.remove(it);
458 delete state;
459
460 lsmapInSync = false;
461
462 return true;
463}
464
465void Keymap::autoRepeat() {
466 if (autoRepeatAction != 0) {
467 qDebug("filter:<<< unicode=%x, keycode=%x, modifiers=%x, "
468 "ispressed=%x\n", autoRepeatAction->getUnicode(),
469 autoRepeatAction->getKeycode(),
470 autoRepeatAction->getModifiers(),
471 autoRepeatAction->isPressed());
472
473 QWSServer::sendKeyEvent(autoRepeatAction->getUnicode(),
474 autoRepeatAction->getKeycode(),
475 autoRepeatAction->getModifiers(),
476 autoRepeatAction->isPressed(), true);
477 }
478
479 repeater.start(repeatPeriod, TRUE);
480}
481
482bool Keymap::addLabel(const QString& label, const QString& state, int index) {
483 if (labels.find(label) != labels.end()) {
484 return false;
485 }
486
487 labels.insert(label, state);
488 const QString& l = labels.find(label).key();
489 if (index == -1) {
490 labelList.append(l);
491 } else {
492 labelList.insert(labelList.at(index), l);
493 }
494
495 lsmapInSync = false;
496
497 return true;
498}
499
500bool Keymap::removeLabel(const QString& label) {
501
502 if (labels.find(label) == labels.end()) {
503 return false;
504 }
505
506 labels.remove(label);
507 labelList.remove(label);
508 lsmapInSync = false;
509
510 if (label == currentLabel) {
511 currentLabel = "";
512 }
513
514 return true;
515}
516
517int Keymap::getAutorepeatDelay() const {
518 return repeatDelay;
519}
520
521void Keymap::setAutorepeatDelay(int n) {
522 repeatDelay = n;
523}
524
525int Keymap::getAutorepeatPeriod() const {
526 return repeatPeriod;
527}
528
529void Keymap::setAutorepeatPeriod(int n) {
530 repeatPeriod = n;
531}
532
533QList<Action> Keymap::findStateUsage(State* s) {
534 QList<Action> ret;
535
536 QMap<QString, State*>::Iterator it;
537 for(it = states.begin(); it != states.end(); ++it) {
538 State* state = it.data();
539
540 for(int i = 0; i < 0x1100; i++) {
541 Action* action = state->get(i, false);
542 if (action!=0 && action->getState()==s) {
543 ret.append(action);
544 }
545
546 action = state->get(i, true);
547 if (action!=0 && action->getState()==s) {
548 ret.append(action);
549 }
550 }
551 }
552
553 return ret;
554}
555
556void Keymap::generateLabelStateMaps() {
557 stateLabelMap.clear();
558
559 QMap<QString, QString>::Iterator lit;
560 for(lit = labels.begin(); lit != labels.end(); ++lit) {
561 QString label = lit.key();
562 QString name = lit.data();
563
564 bool wc = false;
565 int n = name.find("*");
566 if (n>=0 && n==(int)(name.length()-1)) {
567 name=name.left(name.length() - 1);
568 wc = true;
569 }
570
571 QMap<QString, State*>::Iterator sit;
572 for(sit = states.begin(); sit != states.end(); ++sit) {
573 QString sname = sit.key();
574 State* state = sit.data();
575
576 if (sname.length() < name.length()) {
577 continue;
578 }
579
580 if (sname.left(name.length()) == name) {
581 if (wc || sname.length()==name.length()) {
582 stateLabelMap.insert(state, label);
583 }
584
585 }
586 }
587 }
588
589 lsmapInSync = true;
590}