summaryrefslogtreecommitdiff
path: root/noncore/applets/zkbapplet/keyzcfg/zkbxml.cpp
Unidiff
Diffstat (limited to 'noncore/applets/zkbapplet/keyzcfg/zkbxml.cpp') (more/less context) (show whitespace changes)
-rw-r--r--noncore/applets/zkbapplet/keyzcfg/zkbxml.cpp573
1 files changed, 573 insertions, 0 deletions
diff --git a/noncore/applets/zkbapplet/keyzcfg/zkbxml.cpp b/noncore/applets/zkbapplet/keyzcfg/zkbxml.cpp
new file mode 100644
index 0000000..5b0084c
--- a/dev/null
+++ b/noncore/applets/zkbapplet/keyzcfg/zkbxml.cpp
@@ -0,0 +1,573 @@
1#include "zkbxml.h"
2#include "zkbnames.h"
3
4static QString Keymap_Tag("keymap");
5static QString Include_Tag("include");
6static QString Label_Tag("label");
7static QString State_Tag("state");
8static QString Map_Tag("map");
9static QString Event_Tag("event");
10static QString NextState_Tag("next-state");
11
12ZkbXmlHandler::ZkbXmlHandler() {
13}
14
15ZkbXmlHandler::~ZkbXmlHandler() {
16}
17
18bool ZkbXmlHandler::startElement(const QString&, const QString&,
19 const QString& name, const QXmlAttributes& attr) {
20
21 bool ret = false;
22
23 if (name == Keymap_Tag) {
24 ret = start_keymap(attr);
25 } else if (name == Include_Tag) {
26 ret = start_include(attr);
27 } else if (name == Label_Tag) {
28 ret = start_label(attr);
29 } else if (name == State_Tag) {
30 ret = start_state(attr);
31 } else if (name == Map_Tag) {
32 ret = start_map(attr);
33 } else if (name == Event_Tag) {
34 ret = start_event(attr);
35 } else if (name == NextState_Tag) {
36 ret = start_next_state(attr);
37 }
38
39 elements.prepend(name);
40
41 return ret;
42}
43
44bool ZkbXmlHandler::endElement(const QString&, const QString&,
45 const QString& name) {
46
47 bool ret = false;
48
49 elements.remove(elements.begin());
50
51 if (name == Keymap_Tag) {
52 ret = end_keymap();
53 } else if (name == Include_Tag) {
54 ret = end_include();
55 } else if (name == Label_Tag) {
56 ret = end_label();
57 } else if (name == State_Tag) {
58 ret = end_state();
59 } else if (name == Map_Tag) {
60 ret = end_map();
61 } else if (name == Event_Tag) {
62 ret = end_event();
63 } else if (name == NextState_Tag) {
64 ret = end_next_state();
65 }
66
67 return ret;
68}
69
70QString ZkbXmlHandler::errorString() {
71 return err;
72}
73
74bool ZkbXmlHandler::startKeymapElement(int ardelay, int arperiod, const QString& author) {
75 return false;
76}
77
78bool ZkbXmlHandler::startIncludeElement(const QString& file,
79 const QString& prefix) {
80
81 return false;
82}
83
84bool ZkbXmlHandler::startLabelElement(const QString& label,
85 const QString& state) {
86
87 return false;
88}
89
90bool ZkbXmlHandler::startStateElement(const QString& name,
91 const QString& parent, bool dflt) {
92
93 return false;
94}
95
96bool ZkbXmlHandler::startMapElement(int keycode, bool pressed) {
97 return false;
98}
99
100bool ZkbXmlHandler::startEventElement(int keycode, int unicode, int modifiers,
101 bool pressed, bool autorepeat) {
102
103 return false;
104}
105
106bool ZkbXmlHandler::startNextStateElement(const QString& state) {
107 return false;
108}
109
110
111bool ZkbXmlHandler::endKeymapElement() {
112 return false;
113}
114
115bool ZkbXmlHandler::endIncludeElement() {
116 return false;
117}
118
119bool ZkbXmlHandler::endLabelElement() {
120 return false;
121}
122
123bool ZkbXmlHandler::endStateElement() {
124 return false;
125}
126
127bool ZkbXmlHandler::endMapElement() {
128 return false;
129}
130
131bool ZkbXmlHandler::endEventElement() {
132 return false;
133}
134
135bool ZkbXmlHandler::endNextStateElement() {
136 return false;
137}
138
139
140bool ZkbXmlHandler::start_keymap(const QXmlAttributes& attr) {
141 int nattr = 0;
142 int didx = attr.index("autorepeat-delay");
143 int pidx = attr.index("autorepeat-period");
144 int aidx = attr.index("author");
145 int ard = -1;
146 int arp = -1;
147 QString author;
148
149 if (!elements.isEmpty()) {
150 setError("keymap element should be top-level element");
151 return false;
152 }
153
154 if (didx >= 0) {
155 QString s = attr.value(didx);
156 bool ok;
157
158 ard = s.toInt(&ok);
159 if (!ok) {
160 setError("Invalid autorepeat-delay value: " + s);
161 return false;
162 }
163
164 nattr++;
165 }
166
167 if (pidx >= 0) {
168 QString s = attr.value(pidx);
169 bool ok;
170
171 arp = s.toInt(&ok);
172 if (!ok) {
173 setError("Invalid autorepeat-period value: " + s);
174 return false;
175 }
176
177 nattr++;
178 }
179
180 if (aidx >= 0) {
181 author = attr.value(aidx);
182 nattr++;
183 }
184
185 if (attr.length() > nattr) {
186 setError("Unsupported attributes");
187 return false;
188 }
189
190 return startKeymapElement(ard, arp, author);
191}
192
193bool ZkbXmlHandler::start_include(const QXmlAttributes& attr) {
194 int nattr = 0;
195 int fidx = attr.index("file");
196 int pidx = attr.index("prefix");
197 QString file;
198 QString prefix((const char*) 0);
199
200 if (elements.first() != Keymap_Tag) {
201 setError("include element should be used only "
202 "within keymap element");
203 return false;
204 }
205
206 if (fidx >= 0) {
207 file = attr.value(fidx);
208 nattr++;
209 } else {
210 setError("Missing file attribute");
211 return false;
212 }
213
214 if (pidx >= 0) {
215 prefix = attr.value(pidx);
216 nattr++;
217 }
218
219 if (attr.length() > nattr) {
220 setError("Unsupported attributes");
221 return false;
222 }
223
224 return startIncludeElement(file, prefix);
225}
226
227bool ZkbXmlHandler::start_label(const QXmlAttributes& attr) {
228 int nattr = 0;
229 int nidx = attr.index("name");
230 int sidx = attr.index("state");
231 QString name;
232 QString state;
233
234 if (elements.first() != Keymap_Tag) {
235 setError("label element should be used only "
236 "within keymap element");
237 return false;
238 }
239
240 if (nidx >= 0) {
241 name = attr.value(nidx);
242 nattr++;
243 } else {
244 setError("Missing name attribute");
245 return false;
246 }
247
248 if (sidx >= 0) {
249 state = attr.value(sidx);
250 nattr++;
251 } else {
252 setError("Missing name attribute");
253 return false;
254 }
255
256 if (attr.length() > nattr) {
257 setError("Unsupported attributes");
258 return false;
259 }
260
261 return startLabelElement(name, state);
262}
263
264bool ZkbXmlHandler::start_state(const QXmlAttributes& attr) {
265 int nattr = 0;
266 int nidx = attr.index("name");
267 int pidx = attr.index("parent");
268 int didx = attr.index("default");
269 QString name;
270 QString parent((const char*) 0);
271 bool dflt = false;
272
273 if (elements.first() != Keymap_Tag) {
274 setError("state element should be used only "
275 "within keymap element");
276 return false;
277 }
278
279 if (nidx >= 0) {
280 name = attr.value(nidx);
281 nattr++;
282 } else {
283 setError("Missing name attribute");
284 return false;
285 }
286
287 if (pidx >= 0) {
288 parent = attr.value(pidx);
289 nattr++;
290 }
291
292 if (didx >= 0) {
293 dflt = str2bool(attr.value(didx));
294 if (!err.isEmpty()) {
295 return false;
296 }
297
298 nattr++;
299 }
300
301 if (attr.length() > nattr) {
302 setError("Unsupported attributes");
303 return false;
304 }
305
306 return startStateElement(name, parent, dflt);
307}
308
309bool ZkbXmlHandler::start_map(const QXmlAttributes& attr) {
310 int nattr = 0;
311 int kidx = attr.index("keycode");
312 int pidx = attr.index("pressed");
313 int key;
314 bool pressed;
315
316 if (elements.first() != State_Tag) {
317 setError("map element should be used only "
318 "within state element");
319 return false;
320 }
321
322 if (kidx >= 0) {
323 key = str2key(attr.value(kidx));
324 if (!err.isEmpty()) {
325 return false;
326 }
327 nattr++;
328 } else {
329 setError("Missing keycode attribute");
330 return false;
331 }
332
333 if (pidx >= 0) {
334 pressed = str2bool(attr.value(pidx));
335 if (!err.isEmpty()) {
336 return false;
337 }
338 nattr++;
339 } else {
340 setError("Missing pressed attribute");
341 return false;
342 }
343
344 if (attr.length() > nattr) {
345 setError("Unsupported attributes");
346 return false;
347 }
348
349 return startMapElement(key, pressed);
350}
351
352bool ZkbXmlHandler::start_event(const QXmlAttributes& attr) {
353 int nattr = 0;
354 int kidx = attr.index("keycode");
355 int pidx = attr.index("pressed");
356 int uidx = attr.index("unicode");
357 int midx = attr.index("modifiers");
358 int aidx = attr.index("autorepeat");
359
360 int keycode;
361 int unicode;
362 int modifiers = 0;
363 bool pressed;
364 bool autorepeat = false;
365
366 if (elements.first() != Map_Tag) {
367 setError("event element should be used only "
368 "within map element");
369 return false;
370 }
371
372 if (kidx >= 0) {
373 keycode = str2keycode(attr.value(kidx));
374 if (!err.isEmpty()) {
375 return false;
376 }
377 nattr++;
378 } else {
379 setError("Missing keycode attribute");
380 return false;
381 }
382
383 if (uidx >= 0) {
384 unicode = str2unicode(attr.value(uidx));
385 if (!err.isEmpty()) {
386 return false;
387 }
388 nattr++;
389 } else {
390 setError("Missing unicode attribute");
391 return false;
392 }
393
394 if (midx >= 0) {
395 modifiers = str2modifier(attr.value(midx));
396 if (!err.isEmpty()) {
397 return false;
398 }
399 nattr++;
400 }
401
402 if (pidx >= 0) {
403 pressed = str2bool(attr.value(pidx));
404 if (!err.isEmpty()) {
405 return false;
406 }
407 nattr++;
408 } else {
409 setError("Missing pressed attribute");
410 return false;
411 }
412
413 if (aidx >= 0) {
414 autorepeat = str2bool(attr.value(aidx));
415 if (!err.isEmpty()) {
416 return false;
417 }
418 nattr++;
419 }
420
421 if (attr.length() > nattr) {
422 setError("Unsupported attributes");
423 return false;
424 }
425
426 return startEventElement(keycode, unicode, modifiers, pressed,
427 autorepeat);
428}
429
430bool ZkbXmlHandler::start_next_state(const QXmlAttributes& attr) {
431 int nattr = 0;
432 int nidx = attr.index("name");
433 QString name;
434
435 if (elements.first() != Map_Tag) {
436 setError("next-state element should be used only "
437 "within map element");
438 return false;
439 }
440
441 if (nidx >= 0) {
442 name = attr.value(nidx);
443 nattr++;
444 } else {
445 setError("Missing name attribute");
446 return false;
447 }
448
449 if (attr.length() > nattr) {
450 setError("Unsupported attributes");
451 return false;
452 }
453
454 return startNextStateElement(name);
455}
456
457bool ZkbXmlHandler::end_keymap() {
458 return endKeymapElement();
459}
460
461bool ZkbXmlHandler::end_include() {
462 return endIncludeElement();
463}
464
465bool ZkbXmlHandler::end_label() {
466 return endLabelElement();
467}
468
469bool ZkbXmlHandler::end_state() {
470 return endStateElement();
471}
472
473bool ZkbXmlHandler::end_map() {
474 return endMapElement();
475}
476
477bool ZkbXmlHandler::end_event() {
478 return endEventElement();
479}
480
481bool ZkbXmlHandler::end_next_state() {
482 return endNextStateElement();
483}
484
485void ZkbXmlHandler::setError(const QString& e) {
486 err = e;
487}
488
489int ZkbXmlHandler::str2key(const QString& s) {
490 int ret;
491
492 ret = KeyNames::find(s);
493 if (ret == -1) {
494 setError("Invalid value: " + s);
495 }
496
497 return ret;
498}
499
500int ZkbXmlHandler::str2modifier(const QString& val) {
501 int ret;
502
503 int n, i;
504 ret = 0;
505 n = 0;
506 do {
507 i = val.find('|', n);
508 if (i < 0) {
509 i = val.length();
510 }
511
512 QString s = val.mid(n, i - n);
513 int v = ModifierNames::find(s.stripWhiteSpace());
514
515 if (v == -1) {
516 setError("Invalid value: " + val);
517 return -1;
518 }
519
520 ret |= v;
521 n = i + 1;
522 } while (n < val.length());
523
524 return ret;
525}
526
527bool ZkbXmlHandler::str2bool(const QString& s) {
528 if (s == "true") {
529 return true;
530 } else {
531 return false;
532 }
533}
534
535int ZkbXmlHandler::str2unicode(const QString& s) {
536 return str2uint(s);
537}
538
539int ZkbXmlHandler::str2keycode(const QString& s) {
540 int ret;
541
542 ret = KeycodeNames::find(s);
543 if (ret == -1) {
544 setError("Invalid value: " + s);
545 }
546
547 return ret;
548}
549
550int ZkbXmlHandler::str2uint(const QString& s) {
551 int ret;
552 bool ok;
553 QString val = s;
554 int r;
555
556 if (val.left(2) == "0x") {
557 val = s.mid(2);
558 r = 16;
559 } else if (val.left(1) == "0") {
560 val = s.mid(1);
561 r = 8;
562 } else {
563 r = 10;
564 }
565
566 ret = val.toInt(&ok, r);
567 if (!ok) {
568 setError("Invalid value: " + s);
569 ret = -1;
570 }
571
572 return ret;
573}