00001 #include "zkbxml.h"
00002 #include "zkbnames.h"
00003
00004 static QString Keymap_Tag("keymap");
00005 static QString Include_Tag("include");
00006 static QString Label_Tag("label");
00007 static QString State_Tag("state");
00008 static QString Map_Tag("map");
00009 static QString Event_Tag("event");
00010 static QString NextState_Tag("next-state");
00011
00012 ZkbXmlHandler::ZkbXmlHandler() {
00013 }
00014
00015 ZkbXmlHandler::~ZkbXmlHandler() {
00016 }
00017
00018 bool ZkbXmlHandler::startElement(const QString&, const QString&,
00019 const QString& name, const QXmlAttributes& attr) {
00020
00021 bool ret = false;
00022
00023 if (name == Keymap_Tag) {
00024 ret = start_keymap(attr);
00025 } else if (name == Include_Tag) {
00026 ret = start_include(attr);
00027 } else if (name == Label_Tag) {
00028 ret = start_label(attr);
00029 } else if (name == State_Tag) {
00030 ret = start_state(attr);
00031 } else if (name == Map_Tag) {
00032 ret = start_map(attr);
00033 } else if (name == Event_Tag) {
00034 ret = start_event(attr);
00035 } else if (name == NextState_Tag) {
00036 ret = start_next_state(attr);
00037 }
00038
00039 elements.prepend(name);
00040
00041 return ret;
00042 }
00043
00044 bool ZkbXmlHandler::endElement(const QString&, const QString&,
00045 const QString& name) {
00046
00047 bool ret = false;
00048
00049 elements.remove(elements.begin());
00050
00051 if (name == Keymap_Tag) {
00052 ret = end_keymap();
00053 } else if (name == Include_Tag) {
00054 ret = end_include();
00055 } else if (name == Label_Tag) {
00056 ret = end_label();
00057 } else if (name == State_Tag) {
00058 ret = end_state();
00059 } else if (name == Map_Tag) {
00060 ret = end_map();
00061 } else if (name == Event_Tag) {
00062 ret = end_event();
00063 } else if (name == NextState_Tag) {
00064 ret = end_next_state();
00065 }
00066
00067 return ret;
00068 }
00069
00070 QString ZkbXmlHandler::errorString() {
00071 return err;
00072 }
00073
00074 bool ZkbXmlHandler::startKeymapElement(int ardelay, int arperiod, const QString& author) {
00075 return false;
00076 }
00077
00078 bool ZkbXmlHandler::startIncludeElement(const QString& file,
00079 const QString& prefix) {
00080
00081 return false;
00082 }
00083
00084 bool ZkbXmlHandler::startLabelElement(const QString& label,
00085 const QString& state) {
00086
00087 return false;
00088 }
00089
00090 bool ZkbXmlHandler::startStateElement(const QString& name,
00091 const QString& parent, bool dflt) {
00092
00093 return false;
00094 }
00095
00096 bool ZkbXmlHandler::startMapElement(int keycode, bool pressed) {
00097 return false;
00098 }
00099
00100 bool ZkbXmlHandler::startEventElement(int keycode, int unicode, int modifiers,
00101 bool pressed, bool autorepeat) {
00102
00103 return false;
00104 }
00105
00106 bool ZkbXmlHandler::startNextStateElement(const QString& state) {
00107 return false;
00108 }
00109
00110
00111 bool ZkbXmlHandler::endKeymapElement() {
00112 return false;
00113 }
00114
00115 bool ZkbXmlHandler::endIncludeElement() {
00116 return false;
00117 }
00118
00119 bool ZkbXmlHandler::endLabelElement() {
00120 return false;
00121 }
00122
00123 bool ZkbXmlHandler::endStateElement() {
00124 return false;
00125 }
00126
00127 bool ZkbXmlHandler::endMapElement() {
00128 return false;
00129 }
00130
00131 bool ZkbXmlHandler::endEventElement() {
00132 return false;
00133 }
00134
00135 bool ZkbXmlHandler::endNextStateElement() {
00136 return false;
00137 }
00138
00139
00140 bool ZkbXmlHandler::start_keymap(const QXmlAttributes& attr) {
00141 int nattr = 0;
00142 int didx = attr.index("autorepeat-delay");
00143 int pidx = attr.index("autorepeat-period");
00144 int aidx = attr.index("author");
00145 int ard = -1;
00146 int arp = -1;
00147 QString author;
00148
00149 if (!elements.isEmpty()) {
00150 setError("keymap element should be top-level element");
00151 return false;
00152 }
00153
00154 if (didx >= 0) {
00155 QString s = attr.value(didx);
00156 bool ok;
00157
00158 ard = s.toInt(&ok);
00159 if (!ok) {
00160 setError("Invalid autorepeat-delay value: " + s);
00161 return false;
00162 }
00163
00164 nattr++;
00165 }
00166
00167 if (pidx >= 0) {
00168 QString s = attr.value(pidx);
00169 bool ok;
00170
00171 arp = s.toInt(&ok);
00172 if (!ok) {
00173 setError("Invalid autorepeat-period value: " + s);
00174 return false;
00175 }
00176
00177 nattr++;
00178 }
00179
00180 if (aidx >= 0) {
00181 author = attr.value(aidx);
00182 nattr++;
00183 }
00184
00185 if (attr.length() > nattr) {
00186 setError("Unsupported attributes");
00187 return false;
00188 }
00189
00190 return startKeymapElement(ard, arp, author);
00191 }
00192
00193 bool ZkbXmlHandler::start_include(const QXmlAttributes& attr) {
00194 int nattr = 0;
00195 int fidx = attr.index("file");
00196 int pidx = attr.index("prefix");
00197 QString file;
00198 QString prefix((const char*) 0);
00199
00200 if (elements.first() != Keymap_Tag) {
00201 setError("include element should be used only "
00202 "within keymap element");
00203 return false;
00204 }
00205
00206 if (fidx >= 0) {
00207 file = attr.value(fidx);
00208 nattr++;
00209 } else {
00210 setError("Missing file attribute");
00211 return false;
00212 }
00213
00214 if (pidx >= 0) {
00215 prefix = attr.value(pidx);
00216 nattr++;
00217 }
00218
00219 if (attr.length() > nattr) {
00220 setError("Unsupported attributes");
00221 return false;
00222 }
00223
00224 return startIncludeElement(file, prefix);
00225 }
00226
00227 bool ZkbXmlHandler::start_label(const QXmlAttributes& attr) {
00228 int nattr = 0;
00229 int nidx = attr.index("name");
00230 int sidx = attr.index("state");
00231 QString name;
00232 QString state;
00233
00234 if (elements.first() != Keymap_Tag) {
00235 setError("label element should be used only "
00236 "within keymap element");
00237 return false;
00238 }
00239
00240 if (nidx >= 0) {
00241 name = attr.value(nidx);
00242 nattr++;
00243 } else {
00244 setError("Missing name attribute");
00245 return false;
00246 }
00247
00248 if (sidx >= 0) {
00249 state = attr.value(sidx);
00250 nattr++;
00251 } else {
00252 setError("Missing name attribute");
00253 return false;
00254 }
00255
00256 if (attr.length() > nattr) {
00257 setError("Unsupported attributes");
00258 return false;
00259 }
00260
00261 return startLabelElement(name, state);
00262 }
00263
00264 bool ZkbXmlHandler::start_state(const QXmlAttributes& attr) {
00265 int nattr = 0;
00266 int nidx = attr.index("name");
00267 int pidx = attr.index("parent");
00268 int didx = attr.index("default");
00269 QString name;
00270 QString parent((const char*) 0);
00271 bool dflt = false;
00272
00273 if (elements.first() != Keymap_Tag) {
00274 setError("state element should be used only "
00275 "within keymap element");
00276 return false;
00277 }
00278
00279 if (nidx >= 0) {
00280 name = attr.value(nidx);
00281 nattr++;
00282 } else {
00283 setError("Missing name attribute");
00284 return false;
00285 }
00286
00287 if (pidx >= 0) {
00288 parent = attr.value(pidx);
00289 nattr++;
00290 }
00291
00292 if (didx >= 0) {
00293 dflt = str2bool(attr.value(didx));
00294 if (!err.isEmpty()) {
00295 return false;
00296 }
00297
00298 nattr++;
00299 }
00300
00301 if (attr.length() > nattr) {
00302 setError("Unsupported attributes");
00303 return false;
00304 }
00305
00306 return startStateElement(name, parent, dflt);
00307 }
00308
00309 bool ZkbXmlHandler::start_map(const QXmlAttributes& attr) {
00310 int nattr = 0;
00311 int kidx = attr.index("keycode");
00312 int pidx = attr.index("pressed");
00313 int key;
00314 bool pressed;
00315
00316 if (elements.first() != State_Tag) {
00317 setError("map element should be used only "
00318 "within state element");
00319 return false;
00320 }
00321
00322 if (kidx >= 0) {
00323 key = str2key(attr.value(kidx));
00324 if (!err.isEmpty()) {
00325 return false;
00326 }
00327 nattr++;
00328 } else {
00329 setError("Missing keycode attribute");
00330 return false;
00331 }
00332
00333 if (pidx >= 0) {
00334 pressed = str2bool(attr.value(pidx));
00335 if (!err.isEmpty()) {
00336 return false;
00337 }
00338 nattr++;
00339 } else {
00340 setError("Missing pressed attribute");
00341 return false;
00342 }
00343
00344 if (attr.length() > nattr) {
00345 setError("Unsupported attributes");
00346 return false;
00347 }
00348
00349 return startMapElement(key, pressed);
00350 }
00351
00352 bool ZkbXmlHandler::start_event(const QXmlAttributes& attr) {
00353 int nattr = 0;
00354 int kidx = attr.index("keycode");
00355 int pidx = attr.index("pressed");
00356 int uidx = attr.index("unicode");
00357 int midx = attr.index("modifiers");
00358 int aidx = attr.index("autorepeat");
00359
00360 int keycode;
00361 int unicode;
00362 int modifiers = 0;
00363 bool pressed;
00364 bool autorepeat = false;
00365
00366 if (elements.first() != Map_Tag) {
00367 setError("event element should be used only "
00368 "within map element");
00369 return false;
00370 }
00371
00372 if (kidx >= 0) {
00373 keycode = str2keycode(attr.value(kidx));
00374 if (!err.isEmpty()) {
00375 return false;
00376 }
00377 nattr++;
00378 } else {
00379 setError("Missing keycode attribute");
00380 return false;
00381 }
00382
00383 if (uidx >= 0) {
00384 unicode = str2unicode(attr.value(uidx));
00385 if (!err.isEmpty()) {
00386 return false;
00387 }
00388 nattr++;
00389 } else {
00390 setError("Missing unicode attribute");
00391 return false;
00392 }
00393
00394 if (midx >= 0) {
00395 modifiers = str2modifier(attr.value(midx));
00396 if (!err.isEmpty()) {
00397 return false;
00398 }
00399 nattr++;
00400 }
00401
00402 if (pidx >= 0) {
00403 pressed = str2bool(attr.value(pidx));
00404 if (!err.isEmpty()) {
00405 return false;
00406 }
00407 nattr++;
00408 } else {
00409 setError("Missing pressed attribute");
00410 return false;
00411 }
00412
00413 if (aidx >= 0) {
00414 autorepeat = str2bool(attr.value(aidx));
00415 if (!err.isEmpty()) {
00416 return false;
00417 }
00418 nattr++;
00419 }
00420
00421 if (attr.length() > nattr) {
00422 setError("Unsupported attributes");
00423 return false;
00424 }
00425
00426 return startEventElement(keycode, unicode, modifiers, pressed,
00427 autorepeat);
00428 }
00429
00430 bool ZkbXmlHandler::start_next_state(const QXmlAttributes& attr) {
00431 int nattr = 0;
00432 int nidx = attr.index("name");
00433 QString name;
00434
00435 if (elements.first() != Map_Tag) {
00436 setError("next-state element should be used only "
00437 "within map element");
00438 return false;
00439 }
00440
00441 if (nidx >= 0) {
00442 name = attr.value(nidx);
00443 nattr++;
00444 } else {
00445 setError("Missing name attribute");
00446 return false;
00447 }
00448
00449 if (attr.length() > nattr) {
00450 setError("Unsupported attributes");
00451 return false;
00452 }
00453
00454 return startNextStateElement(name);
00455 }
00456
00457 bool ZkbXmlHandler::end_keymap() {
00458 return endKeymapElement();
00459 }
00460
00461 bool ZkbXmlHandler::end_include() {
00462 return endIncludeElement();
00463 }
00464
00465 bool ZkbXmlHandler::end_label() {
00466 return endLabelElement();
00467 }
00468
00469 bool ZkbXmlHandler::end_state() {
00470 return endStateElement();
00471 }
00472
00473 bool ZkbXmlHandler::end_map() {
00474 return endMapElement();
00475 }
00476
00477 bool ZkbXmlHandler::end_event() {
00478 return endEventElement();
00479 }
00480
00481 bool ZkbXmlHandler::end_next_state() {
00482 return endNextStateElement();
00483 }
00484
00485 void ZkbXmlHandler::setError(const QString& e) {
00486 err = e;
00487 }
00488
00489 int ZkbXmlHandler::str2key(const QString& s) {
00490 int ret;
00491
00492 ret = KeyNames::find(s);
00493 if (ret == -1) {
00494 setError("Invalid value: " + s);
00495 }
00496
00497 return ret;
00498 }
00499
00500 int ZkbXmlHandler::str2modifier(const QString& val) {
00501 int ret;
00502
00503 int n, i;
00504 ret = 0;
00505 n = 0;
00506 do {
00507 i = val.find('|', n);
00508 if (i < 0) {
00509 i = val.length();
00510 }
00511
00512 QString s = val.mid(n, i - n);
00513 int v = ModifierNames::find(s.stripWhiteSpace());
00514
00515 if (v == -1) {
00516 setError("Invalid value: " + val);
00517 return -1;
00518 }
00519
00520 ret |= v;
00521 n = i + 1;
00522 } while (n < val.length());
00523
00524 return ret;
00525 }
00526
00527 bool ZkbXmlHandler::str2bool(const QString& s) {
00528 if (s == "true") {
00529 return true;
00530 } else {
00531 return false;
00532 }
00533 }
00534
00535 int ZkbXmlHandler::str2unicode(const QString& s) {
00536 return str2uint(s);
00537 }
00538
00539 int ZkbXmlHandler::str2keycode(const QString& s) {
00540 int ret;
00541
00542 ret = KeycodeNames::find(s);
00543 if (ret == -1) {
00544 setError("Invalid value: " + s);
00545 }
00546
00547 return ret;
00548 }
00549
00550 int ZkbXmlHandler::str2uint(const QString& s) {
00551 int ret;
00552 bool ok;
00553 QString val = s;
00554 int r;
00555
00556 if (val.left(2) == "0x") {
00557 val = s.mid(2);
00558 r = 16;
00559 } else if (val.left(1) == "0") {
00560 val = s.mid(1);
00561 r = 8;
00562 } else {
00563 r = 10;
00564 }
00565
00566 ret = val.toInt(&ok, r);
00567 if (!ok) {
00568 setError("Invalid value: " + s);
00569 ret = -1;
00570 }
00571
00572 return ret;
00573 }