Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

zkb.cpp

Go to the documentation of this file.
00001 #include "zkb.h"
00002 
00003 /* OPIE */
00004 #include <opie2/odebug.h>
00005 #include <opie2/okeyfilter.h>
00006 
00007 #include <stdio.h>
00008 
00009 // Implementation of Action class
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 // Implementation of State class
00134 const short State::x1[] = { /* from 0x20 to 0x5f */
00135     31,  0, 28,  3,  5,  6,  9, 28,     /* 0x20 - 0x27 */
00136     11, 26, 10, 13, 26,  1, 29, 27,     /* 0x28 - 0x2f */
00137     15, 16, 22,  4, 17, 19, 24, 20,     /* 0x30 - 0x37 */
00138      8, 14, 29, 26, 29, 12, 32, 27,     /* 0x38 - 0x3f */
00139     18,  0,  1,  2,  3,  4,  5,  6,     /* 0x40 - 0x47 */
00140      7,  8,  9, 10, 11, 12, 13, 14,     /* 0x48 - 0x4f */
00141     15, 16, 17, 18, 19, 20, 21, 22,     /* 0x50 - 0x57 */
00142     23, 24, 25, 30, -1, 26, 28,  7,     /* 0x58 - 0x5f */
00143     31, -1, -1, -1, -1, -1, -1, -1,     /* 0x60 - 0x67 */
00144     -1, -1, -1, -1, -1, -1, -1, -1,     /* 0x68 - 0x6f */
00145     -1, -1, -1, -1, -1, -1, -1, -1,     /* 0x70 - 0x77 */
00146     -1, -1, -1, 29, 31, 32, 32, 28,     /* 0x78 - 0x7f */
00147 };
00148 
00149 const short State::x2[] = { /* from 0x1000 to 0x1057*/
00150     42, 36, -1, 30, 32, -1, -1, -1,     /* 0x1000 - 0x1007 */
00151     -1, -1, -1, -1, -1, -1, -1, -1,     /* 0x1008 - 0x100f */
00152     -1, -1, 44, 45, 46, 47, -1, -1,     /* 0x1010 - 0x1017 */
00153     -1, -1, -1, -1, -1, -1, -1, -1,     /* 0x1018 - 0x101f */
00154     33, 35, 34, -1, 36, 27, -1, -1,     /* 0x1020 - 0x1027 */
00155     -1, -1, -1, -1, -1, -1, -1, -1,     /* 0x1028 - 0x102f */
00156     -1, -1, -1, -1, -1, -1, -1, -1,     /* 0x1030 - 0x1037 */
00157     37, 38, 40, 39, 41, -1, -1, -1,     /* 0x1038 - 0x103f */
00158     -1, -1, -1, -1, -1, 35, -1, -1,     /* 0x1040 - 0x1047 */
00159     -1, -1, -1, -1, -1, 48, -1, -1,     /* 0x1048 - 0x104f */
00160     43, 49, 50, -1, -1, -1, -1, -1,     /* 0x1050 - 0x1057 */
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 // Implementation of Keymap class
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     // the second check is workaround to make suspend work if
00270     // the user pressed it right after he did resume. for some
00271     // reason the event sent by qt has autoRepeat true in this
00272     // case
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 //  odebug << "look for: " << name.utf8() << "\n" << oendl;
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 //              odebug << "no label for: " + currentStateName + "\n" << oendl;
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 }

Generated on Sat Nov 5 16:16:46 2005 for OPIE by  doxygen 1.4.2