00001 #include "zkb.h"
00002
00003
00004 #include <opie2/odebug.h>
00005 #include <opie2/okeyfilter.h>
00006
00007 #include <stdio.h>
00008
00009
00010 Action::Action():state(0), keycode(0), unicode(0), flags(0) {
00011 }
00012
00013 Action::Action(State* s, ushort kc, ushort uni, int f):
00014 state(s), keycode(kc), unicode(uni), flags(f) {
00015 }
00016
00017 Action::~Action() {
00018 }
00019
00020 State* Action::getState() const {
00021 return state;
00022 }
00023
00024 void Action::setState(State* s) {
00025 state = s;
00026 setDefined(true);
00027 }
00028
00029 bool Action::hasEvent() const {
00030 return flags & Event;
00031 }
00032
00033 void Action::setEvent(bool e) {
00034 flags = (flags & ~Event) | ((e) ? Event : 0);
00035
00036 if (e) {
00037 setDefined(true);
00038 } else {
00039 if (state == 0) {
00040 setDefined(false);
00041 }
00042 }
00043 }
00044
00045 bool Action::isDefined() const {
00046 return flags & Defined;
00047 }
00048
00049 void Action::setDefined(bool d) {
00050 flags = (flags & ~Defined) | ((d) ? Defined : 0);
00051 }
00052
00053 int Action::getKeycode() const {
00054 return keycode;
00055 }
00056
00057 void Action::setKeycode(int c) {
00058 keycode = (ushort) c;
00059 setEvent(true);
00060 }
00061
00062 int Action::getUnicode() const {
00063 return unicode;
00064 }
00065
00066 void Action::setUnicode(int u) {
00067 unicode = (ushort) u;
00068 setEvent(true);
00069 }
00070
00071 int Action::getModifiers() const {
00072 int ret = 0;
00073 if (flags & Shift_Mod) {
00074 ret |= Qt::ShiftButton;
00075 }
00076
00077 if (flags & Ctrl_Mod) {
00078 ret |= Qt::ControlButton;
00079 }
00080
00081 if (flags & Alt_Mod) {
00082 ret |= Qt::AltButton;
00083 }
00084
00085 if (flags & Keypad_Mod) {
00086 ret |= Qt::Keypad;
00087 }
00088
00089 return ret;
00090 }
00091
00092 void Action::setModifiers(int m) {
00093 int n = 0;
00094
00095 if (m & Qt::ShiftButton) {
00096 n |= Shift_Mod;
00097 }
00098
00099 if (m & Qt::ControlButton) {
00100 n |= Ctrl_Mod;
00101 }
00102
00103 if (m & Qt::AltButton) {
00104 n |= Alt_Mod;
00105 }
00106
00107 if (m & Qt::Keypad) {
00108 n |= Keypad_Mod;
00109 }
00110
00111 flags = flags & ~Mod_Bits | n;
00112 setEvent(true);
00113 }
00114
00115 bool Action::isPressed() const {
00116 return (flags & Press) != 0;
00117 }
00118
00119 void Action::setPressed(bool p) {
00120 flags = (flags & ~Press) | ((p) ? Press : 0);
00121 setEvent(true);
00122 }
00123
00124 bool Action::isAutorepeat() const {
00125 return (flags & Autorepeat) != 0;
00126 }
00127
00128 void Action::setAutorepeat(bool p) {
00129 flags = (flags & ~Autorepeat) | ((p) ? Autorepeat : 0);
00130 setEvent(true);
00131 }
00132
00133
00134 const short State::x1[] = {
00135 31, 0, 28, 3, 5, 6, 9, 28,
00136 11, 26, 10, 13, 26, 1, 29, 27,
00137 15, 16, 22, 4, 17, 19, 24, 20,
00138 8, 14, 29, 26, 29, 12, 32, 27,
00139 18, 0, 1, 2, 3, 4, 5, 6,
00140 7, 8, 9, 10, 11, 12, 13, 14,
00141 15, 16, 17, 18, 19, 20, 21, 22,
00142 23, 24, 25, 30, -1, 26, 28, 7,
00143 31, -1, -1, -1, -1, -1, -1, -1,
00144 -1, -1, -1, -1, -1, -1, -1, -1,
00145 -1, -1, -1, -1, -1, -1, -1, -1,
00146 -1, -1, -1, 29, 31, 32, 32, 28,
00147 };
00148
00149 const short State::x2[] = {
00150 42, 36, -1, 30, 32, -1, -1, -1,
00151 -1, -1, -1, -1, -1, -1, -1, -1,
00152 -1, -1, 44, 45, 46, 47, -1, -1,
00153 -1, -1, -1, -1, -1, -1, -1, -1,
00154 33, 35, 34, -1, 36, 27, -1, -1,
00155 -1, -1, -1, -1, -1, -1, -1, -1,
00156 -1, -1, -1, -1, -1, -1, -1, -1,
00157 37, 38, 40, 39, 41, -1, -1, -1,
00158 -1, -1, -1, -1, -1, 35, -1, -1,
00159 -1, -1, -1, -1, -1, 48, -1, -1,
00160 43, 49, 50, -1, -1, -1, -1, -1,
00161 };
00162
00163 State::State(State* p):parent(p), keys(0) {
00164 keys = new Action[Key_Max * 2 + 1];
00165 }
00166
00167 State::State(const State& s) {
00168 parent = s.parent;
00169 keys = new Action[Key_Max * 2 + 1];
00170 memcpy(keys, s.keys, sizeof(Action) * (Key_Max * 2 + 1));
00171 }
00172
00173 State::~State() {
00174 if (keys!=0) {
00175 delete [] keys;
00176 }
00177 }
00178
00179 Action* State::get(int keycode, bool pressed, bool follow) const {
00180 Action* ret = 0;
00181 int n = translateKeycode(keycode);
00182
00183 if (n != -1 && keys != 0) {
00184 if (pressed) {
00185 n += Key_Max;
00186 }
00187 ret = &keys[n];
00188 }
00189
00190 if (ret==0 || !ret->isDefined()) {
00191 if (follow && parent!=0) {
00192 ret = parent->get(keycode, pressed, follow);
00193 }
00194 }
00195
00196 return ret;
00197 }
00198
00199 bool State::set(int keycode, bool pressed, Action& action) {
00200 int n = translateKeycode(keycode);
00201
00202 if (n==-1 || keys==0) {
00203 return false;
00204 }
00205
00206 if (pressed) {
00207 n += Key_Max + 1;
00208 }
00209
00210 keys[n] = action;
00211 return true;
00212 }
00213
00214 State* State::getParent() const {
00215 return parent;
00216 }
00217
00218 void State::setParent(State* s) {
00219 parent = s;
00220 }
00221
00222 int State::translateKeycode(int keycode) const {
00223 if (keycode < 0x20) {
00224 return -1;
00225 }
00226
00227 if (keycode < 0x80) {
00228 return x1[keycode - 0x20];
00229 }
00230
00231 if (keycode < 0x1000) {
00232 return -1;
00233 }
00234
00235 if (keycode < 0x1057) {
00236 return x2[keycode - 0x1000];
00237 }
00238
00239 return -1;
00240 }
00241
00242
00243 Keymap::Keymap():enabled(true), currentState(0), autoRepeatAction(0), repeater(this) {
00244 repeatDelay=400;
00245 repeatPeriod=80;
00246 connect(&repeater, SIGNAL(timeout()), this, SLOT(autoRepeat()));
00247 }
00248
00249 Keymap::~Keymap() {
00250 odebug << "removing keyboard filter for zkb"<<oendl;
00251 Opie::Core::OKeyFilter::inst()->remHandler(this);
00252 QMap<QString, State*>::Iterator it;
00253 for(it = states.begin(); it != states.end(); ++it) {
00254 delete it.data();
00255 }
00256 states.clear();
00257 }
00258
00259 bool Keymap::filter(int unicode, int keycode, int modifiers,
00260 bool isPress, bool autoRepeat) {
00261
00262 if (!enabled) {
00263 return false;
00264 }
00265
00266 odebug << "filter: >>> unicode=" << unicode << ", keycode=" << keycode
00267 << ", modifiers=" << modifiers << ", ispressed=" << isPress << oendl;
00268
00269
00270
00271
00272
00273 if (autoRepeat && keycode != 4177) {
00274 return true;
00275 }
00276
00277 (void) unicode; (void) modifiers;
00278
00279 Action* action = currentState->get(keycode, isPress, true);
00280 if (action==0 || !action->isDefined()) {
00281 odebug << "no action defined for that"<<oendl;
00282 return false;
00283 }
00284
00285 if (action->hasEvent()) {
00286 odebug << "filter:<<< unicode=" << action->getUnicode() << ", keycode=" << action->getKeycode()
00287 << ", modifiers=" << action->getModifiers() << ", ispressed=" << action->isPressed() << oendl;
00288
00289 QWSServer::sendKeyEvent(action->getUnicode(),
00290 action->getKeycode(), action->getModifiers(),
00291 action->isPressed(), false);
00292 }
00293
00294 if (action->isAutorepeat()) {
00295 autoRepeatAction = action;
00296 repeater.start(repeatDelay, TRUE);
00297 } else {
00298 autoRepeatAction = 0;
00299 }
00300
00301 State* nstate = action->getState();
00302 if (nstate != 0) {
00303 setCurrentState(nstate);
00304 QString lbl = getCurrentLabel();
00305 if (!lbl.isEmpty()) {
00306 emit stateChanged(lbl);
00307 }
00308 }
00309
00310
00311 return true;
00312 }
00313
00314 void Keymap::enable() {
00315 enabled = true;
00316 }
00317
00318 void Keymap::disable() {
00319 enabled = false;
00320 }
00321
00322 QStringList Keymap::listStates() {
00323 QStringList ret;
00324
00325 QMap<QString, State*>::Iterator it;
00326 for(it = states.begin(); it != states.end(); ++it) {
00327 ret.append(it.key());
00328 }
00329
00330 return ret;
00331 }
00332
00333 State* Keymap::getStateByName(const QString& name) {
00334 QMap<QString, State*>::Iterator it = states.find(name);
00335
00336 if (it == states.end()) {
00337 return 0;
00338 }
00339
00340 return it.data();
00341 }
00342
00343 QStringList Keymap::listLabels() {
00344 QStringList ret;
00345
00346 for(uint i = 0; i < labelList.count(); i++) {
00347 ret.append(*labelList.at(i));
00348 }
00349
00350 return ret;
00351 }
00352
00353 State* Keymap::getStateByLabel(const QString& label) {
00354 QMap<QString, QString>::Iterator lit = labels.find(label);
00355 State* state = 0;
00356
00357 if (lit == labels.end()) {
00358 return 0;
00359 }
00360
00361 QString name = lit.data();
00362
00363 int n = name.find(":*");
00364 if (n>=0 && n==(int)(name.length()-2)) {
00365 name=name.left(name.length() - 1);
00366
00367 n = currentStateName.findRev(":");
00368 if (n >= 0) {
00369 name += currentStateName.mid(n+1);
00370 }
00371 }
00372
00373
00374 QMap<QString, State*>::Iterator sit = states.find(name);
00375 if (sit != states.end()) {
00376 state = sit.data();
00377 }
00378
00379 return state;
00380 }
00381
00382 bool Keymap::addState(const QString& name, State* state) {
00383 if (states.find(name) != states.end()) {
00384 return false;
00385 }
00386
00387 states.insert(name, state);
00388 lsmapInSync = false;
00389
00390 if (currentState == 0) {
00391 setCurrentState(state);
00392 }
00393
00394 return true;
00395 }
00396
00397 State* Keymap::getCurrentState() const {
00398 return currentState;
00399 }
00400
00401 QString Keymap::getCurrentLabel() {
00402 return currentLabel;
00403 }
00404
00405 bool Keymap::setCurrentState(State* state) {
00406 QMap<QString, State*>::Iterator it;
00407 for(it = states.begin(); it != states.end(); ++it) {
00408 State* s = it.data();
00409 if (s == state) {
00410 currentState = s;
00411 currentStateName = it.key();
00412
00413 odebug << "state changed: " << (const char*)currentStateName.utf8() << oendl;
00414
00415 if (!lsmapInSync) {
00416 generateLabelStateMaps();
00417 }
00418
00419 QMap<State*, QString>::Iterator tit;
00420 tit = stateLabelMap.find(state);
00421 if (tit != stateLabelMap.end()) {
00422 currentLabel = tit.data();
00423 } else {
00424
00425 currentLabel = "";
00426 }
00427
00428 return true;
00429 }
00430 }
00431
00432 return false;
00433 }
00434
00435 bool Keymap::removeState(const QString& name, bool force) {
00436 QMap<QString, State*>::Iterator it = states.find(name);
00437
00438 if (it == states.end()) {
00439 return false;
00440 }
00441
00442 State* state = it.data();
00443 QList<Action> acts = findStateUsage(state);
00444
00445 if (!acts.isEmpty()) {
00446 if (!force) {
00447 return false;
00448 } else {
00449 for(Action* a = acts.first(); a != 0; a = acts.next()) {
00450 a->setState(0);
00451 }
00452 }
00453 }
00454
00455 if (state == currentState) {
00456 if (states.begin() != states.end()) {
00457 setCurrentState(states.begin().data());
00458 }
00459 }
00460
00461 states.remove(it);
00462 delete state;
00463
00464 lsmapInSync = false;
00465
00466 return true;
00467 }
00468
00469 void Keymap::autoRepeat() {
00470 if (autoRepeatAction != 0) {
00471 odebug << "filter:<<< unicode=" << autoRepeatAction->getUnicode()
00472 << ", keycode=" << autoRepeatAction->getKeycode()
00473 << ", modifiers=" << autoRepeatAction->getModifiers()
00474 << "ispressed=" << autoRepeatAction->isPressed() << oendl;
00475
00476 QWSServer::sendKeyEvent(autoRepeatAction->getUnicode(),
00477 autoRepeatAction->getKeycode(),
00478 autoRepeatAction->getModifiers(),
00479 autoRepeatAction->isPressed(), true);
00480 }
00481
00482 repeater.start(repeatPeriod, TRUE);
00483 }
00484
00485 bool Keymap::addLabel(const QString& label, const QString& state, int index) {
00486 if (labels.find(label) != labels.end()) {
00487 return false;
00488 }
00489
00490 labels.insert(label, state);
00491 const QString& l = labels.find(label).key();
00492 if (index == -1) {
00493 labelList.append(l);
00494 } else {
00495 labelList.insert(labelList.at(index), l);
00496 }
00497
00498 lsmapInSync = false;
00499
00500 return true;
00501 }
00502
00503 bool Keymap::removeLabel(const QString& label) {
00504
00505 if (labels.find(label) == labels.end()) {
00506 return false;
00507 }
00508
00509 labels.remove(label);
00510 labelList.remove(label);
00511 lsmapInSync = false;
00512
00513 if (label == currentLabel) {
00514 currentLabel = "";
00515 }
00516
00517 return true;
00518 }
00519
00520 int Keymap::getAutorepeatDelay() const {
00521 return repeatDelay;
00522 }
00523
00524 void Keymap::setAutorepeatDelay(int n) {
00525 repeatDelay = n;
00526 }
00527
00528 int Keymap::getAutorepeatPeriod() const {
00529 return repeatPeriod;
00530 }
00531
00532 void Keymap::setAutorepeatPeriod(int n) {
00533 repeatPeriod = n;
00534 }
00535
00536 QList<Action> Keymap::findStateUsage(State* s) {
00537 QList<Action> ret;
00538
00539 QMap<QString, State*>::Iterator it;
00540 for(it = states.begin(); it != states.end(); ++it) {
00541 State* state = it.data();
00542
00543 for(int i = 0; i < 0x1100; i++) {
00544 Action* action = state->get(i, false);
00545 if (action!=0 && action->getState()==s) {
00546 ret.append(action);
00547 }
00548
00549 action = state->get(i, true);
00550 if (action!=0 && action->getState()==s) {
00551 ret.append(action);
00552 }
00553 }
00554 }
00555
00556 return ret;
00557 }
00558
00559 void Keymap::generateLabelStateMaps() {
00560 stateLabelMap.clear();
00561
00562 QMap<QString, QString>::Iterator lit;
00563 for(lit = labels.begin(); lit != labels.end(); ++lit) {
00564 QString label = lit.key();
00565 QString name = lit.data();
00566
00567 bool wc = false;
00568 int n = name.find("*");
00569 if (n>=0 && n==(int)(name.length()-1)) {
00570 name=name.left(name.length() - 1);
00571 wc = true;
00572 }
00573
00574 QMap<QString, State*>::Iterator sit;
00575 for(sit = states.begin(); sit != states.end(); ++sit) {
00576 QString sname = sit.key();
00577 State* state = sit.data();
00578
00579 if (sname.length() < name.length()) {
00580 continue;
00581 }
00582
00583 if (sname.left(name.length()) == name) {
00584 if (wc || sname.length()==name.length()) {
00585 stateLabelMap.insert(state, label);
00586 }
00587
00588 }
00589 }
00590 }
00591
00592 lsmapInSync = true;
00593 }