author | alwin <alwin> | 2004-02-26 15:33:31 (UTC) |
---|---|---|
committer | alwin <alwin> | 2004-02-26 15:33:31 (UTC) |
commit | 42eb413737eb6e911867e1b9c0f5b6cf81c677fd (patch) (unidiff) | |
tree | b32284f8cec0f584151f0826fd121c153fc07601 /noncore/apps/keyz-cfg/zkb.cpp | |
parent | d26a7814b7b454583a136a78aeb7016467ec9ff8 (diff) | |
download | opie-42eb413737eb6e911867e1b9c0f5b6cf81c677fd.zip opie-42eb413737eb6e911867e1b9c0f5b6cf81c677fd.tar.gz opie-42eb413737eb6e911867e1b9c0f5b6cf81c677fd.tar.bz2 |
Yeah - zkb fixed and working within OPIE.
Diffstat (limited to 'noncore/apps/keyz-cfg/zkb.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/apps/keyz-cfg/zkb.cpp | 590 |
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 | ||
6 | Action::Action():state(0), keycode(0), unicode(0), flags(0) { | ||
7 | } | ||
8 | |||
9 | Action::Action(State* s, ushort kc, ushort uni, int f): | ||
10 | state(s), keycode(kc), unicode(uni), flags(f) { | ||
11 | } | ||
12 | |||
13 | Action::~Action() { | ||
14 | } | ||
15 | |||
16 | State* Action::getState() const { | ||
17 | return state; | ||
18 | } | ||
19 | |||
20 | void Action::setState(State* s) { | ||
21 | state = s; | ||
22 | setDefined(true); | ||
23 | } | ||
24 | |||
25 | bool Action::hasEvent() const { | ||
26 | return flags & Event; | ||
27 | } | ||
28 | |||
29 | void 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 | |||
41 | bool Action::isDefined() const { | ||
42 | return flags & Defined; | ||
43 | } | ||
44 | |||
45 | void Action::setDefined(bool d) { | ||
46 | flags = (flags & ~Defined) | ((d) ? Defined : 0); | ||
47 | } | ||
48 | |||
49 | int Action::getKeycode() const { | ||
50 | return keycode; | ||
51 | } | ||
52 | |||
53 | void Action::setKeycode(int c) { | ||
54 | keycode = (ushort) c; | ||
55 | setEvent(true); | ||
56 | } | ||
57 | |||
58 | int Action::getUnicode() const { | ||
59 | return unicode; | ||
60 | } | ||
61 | |||
62 | void Action::setUnicode(int u) { | ||
63 | unicode = (ushort) u; | ||
64 | setEvent(true); | ||
65 | } | ||
66 | |||
67 | int 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 | |||
88 | void 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 | |||
111 | bool Action::isPressed() const { | ||
112 | return (flags & Press) != 0; | ||
113 | } | ||
114 | |||
115 | void Action::setPressed(bool p) { | ||
116 | flags = (flags & ~Press) | ((p) ? Press : 0); | ||
117 | setEvent(true); | ||
118 | } | ||
119 | |||
120 | bool Action::isAutorepeat() const { | ||
121 | return (flags & Autorepeat) != 0; | ||
122 | } | ||
123 | |||
124 | void Action::setAutorepeat(bool p) { | ||
125 | flags = (flags & ~Autorepeat) | ((p) ? Autorepeat : 0); | ||
126 | setEvent(true); | ||
127 | } | ||
128 | |||
129 | // Implementation of State class | ||
130 | const 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 | |||
145 | const 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 | |||
159 | State::State(State* p):parent(p), keys(0) { | ||
160 | keys = new Action[Key_Max * 2 + 1]; | ||
161 | } | ||
162 | |||
163 | State::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 | |||
169 | State::~State() { | ||
170 | if (keys!=0) { | ||
171 | delete [] keys; | ||
172 | } | ||
173 | } | ||
174 | |||
175 | Action* 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 | |||
195 | bool 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 | |||
210 | State* State::getParent() const { | ||
211 | return parent; | ||
212 | } | ||
213 | |||
214 | void State::setParent(State* s) { | ||
215 | parent = s; | ||
216 | } | ||
217 | |||
218 | int 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 | ||
239 | Keymap::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 | |||
245 | Keymap::~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 | |||
253 | bool 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 | |||
309 | void Keymap::enable() { | ||
310 | enabled = true; | ||
311 | } | ||
312 | |||
313 | void Keymap::disable() { | ||
314 | enabled = false; | ||
315 | } | ||
316 | |||
317 | QStringList 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 | |||
328 | State* 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 | |||
338 | QStringList 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 | |||
348 | State* 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 | |||
377 | bool 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 | |||
392 | State* Keymap::getCurrentState() const { | ||
393 | return currentState; | ||
394 | } | ||
395 | |||
396 | QString Keymap::getCurrentLabel() { | ||
397 | return currentLabel; | ||
398 | } | ||
399 | |||
400 | bool 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 | |||
431 | bool 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 | |||
465 | void 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 | |||
482 | bool 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 | |||
500 | bool 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 | |||
517 | int Keymap::getAutorepeatDelay() const { | ||
518 | return repeatDelay; | ||
519 | } | ||
520 | |||
521 | void Keymap::setAutorepeatDelay(int n) { | ||
522 | repeatDelay = n; | ||
523 | } | ||
524 | |||
525 | int Keymap::getAutorepeatPeriod() const { | ||
526 | return repeatPeriod; | ||
527 | } | ||
528 | |||
529 | void Keymap::setAutorepeatPeriod(int n) { | ||
530 | repeatPeriod = n; | ||
531 | } | ||
532 | |||
533 | QList<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 | |||
556 | void 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 | } | ||