1 /*****
2 * Xnee's Not an Event Emulator
3 *
4 * Xnee enables recording and replaying of X protocol data
5 *
6 * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004,
7 * 2010 Henrik Sandklef
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 3
12 * of the License, or any later version.
13 *
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Boston,
23 * MA 02110-1301, USA.
24 ****/
25
26
27
28 #include "libxnee/xnee.h"
29 #include "libxnee/print.h"
30 #include "libxnee/xnee_keysym.h"
31 #include "libxnee/xnee_km.h"
32
33 int masks[] =
34 {
35 0,
36 ShiftMask,
37 ControlMask,
38 LockMask,
39 Mod1Mask,
40 Mod2Mask,
41 Mod3Mask,
42 Mod4Mask,
43 Mod5Mask,
44 -1
45 } ;
46
47
48
49 int
50 xnee_token_to_km (xnee_data *xd,
51 int keycode,
52 const char *str,
53 xnee_key_code *kc);
54 KeyCode
55 xnee_keysym2keycode(xnee_data* xd, KeySym ks, char * str, xnee_key_code *kc);
56
57
58 KeyCode
xnee_str2keycode(xnee_data * xd,const char * str,xnee_key_code * kc)59 xnee_str2keycode(xnee_data* xd, const char *str, xnee_key_code *kc)
60 {
61 const char *tmp;
62 if (xd->fake==NULL)
63 return -1;
64
65 tmp = xnee_symbolic_modifier2modifier(xd, str);
66 if (tmp!=NULL)
67 {
68 str=tmp;
69 }
70
71
72 /* Xnee special syntax */
73 if (strncmp(str, XNEE_XK_SPACE, strlen(XNEE_XK_SPACE))==0)
74 {
75 kc->kc = XKeysymToKeycode(xd->fake, XK_space);
76 }
77 else if (strncmp(str, XNEE_XK_RETURN, strlen(XNEE_XK_RETURN))==0)
78 {
79 kc->kc = XKeysymToKeycode(xd->fake, XK_Return);
80 }
81 else if (strncmp(str, XNEE_XK_ALT_L, strlen(XNEE_XK_ALT_L))==0)
82 {
83 kc->kc = XKeysymToKeycode(xd->fake, XK_Alt_L);
84 }
85 else if (strncmp(str, XNEE_XK_UP, strlen(XNEE_XK_UP))==0)
86 {
87 kc->kc = XKeysymToKeycode(xd->fake, XK_Up);
88 }
89 else if (strncmp(str, XNEE_XK_DOWN, strlen(XNEE_XK_DOWN))==0)
90 {
91 kc->kc = XKeysymToKeycode(xd->fake, XK_Down);
92 }
93 else if (strncmp(str, XNEE_XK_LEFT, strlen(XNEE_XK_LEFT))==0)
94 {
95 kc->kc = XKeysymToKeycode(xd->fake, XK_Left);
96 }
97 else if (strncmp(str, XNEE_XK_RIGHT, strlen(XNEE_XK_RIGHT))==0)
98 {
99 kc->kc = XKeysymToKeycode(xd->fake, XK_Right);
100 }
101 else
102 {
103 kc->kc = XKeysymToKeycode(xd->fake,XStringToKeysym(str));
104 }
105
106 if (kc!=NULL)
107 {
108 xnee_token_to_km (xd, kc->kc, str, kc);
109 }
110
111 return kc->kc;
112 }
113
114
115 KeyCode
xnee_keysym2keycode(xnee_data * xd,KeySym ks,char * str,xnee_key_code * kc)116 xnee_keysym2keycode(xnee_data* xd, KeySym ks, char * str, xnee_key_code *kc)
117 {
118 if (xd->fake==NULL)
119 return -1;
120
121 kc->kc = XKeysymToKeycode(xd->fake, ks);
122 xnee_token_to_km (xd,kc->kc,str,kc);
123 return kc->kc;
124 }
125
126
127 int
xnee_token_to_km(xnee_data * xd,int keycode,const char * str,xnee_key_code * kc)128 xnee_token_to_km (xnee_data *xd,
129 int keycode,
130 const char *str,
131 xnee_key_code *kc)
132 {
133 #define TOKEN_STRING_SIZE 20
134
135 XEvent event;
136 int size;
137 int i ;
138 int k ;
139 int ret=-1;
140 char string[TOKEN_STRING_SIZE];
141 KeySym keysym;
142 Display *dpy = xd->fake;
143
144 xnee_verbose((xd, "Finding km for %s\n", str));
145
146 memset (kc->mod_keycodes, 0, XNEE_NR_OF_MODIFIERS * sizeof(KeyCode));
147
148 for (i=0;masks[i]!=-1;i++)
149 {
150 event.xkey.type = KeyPress;
151 event.xkey.display = dpy ;
152 event.xkey.time = CurrentTime;
153 event.xkey.x = event.xkey.y = 0;
154 event.xkey.x_root = event.xkey.y_root = 0;
155 event.xkey.state = masks[i];
156 event.xkey.keycode = keycode;
157
158
159 size = XLookupString ((XKeyEvent *) &event, string, 20, &keysym, 0);
160 string [size] = 0;
161
162
163 if (strncmp(str,string, TOKEN_STRING_SIZE)==0)
164 {
165 KeySym ks ;
166 char *nm ;
167
168 xnee_verbose((xd, " i=%d\n", i ));
169 xnee_verbose((xd, " xd=%p\n", (void*)xd ));
170 xnee_verbose((xd, " map=%p\n", (void*)xd->map ));
171 xnee_verbose((xd, " max_keypermod=%d\n" ,xd->map->max_keypermod ));
172
173 k = (i-1)*xd->map->max_keypermod ;
174 xnee_verbose((xd, " k=%d\n", k ));
175
176 ks = XKeycodeToKeysym(dpy,
177 xd->map->modifiermap[k],
178 0);
179 nm = XKeysymToString(ks);
180
181 if ( ( nm != NULL ) &&
182 strncmp(nm, "Mode_switch", strlen("Mode_switch")) == 0 )
183 {
184 ks = XStringToKeysym("ISO_Level3_Shift");
185 kc->mod_keycodes[0] = XKeysymToKeycode(dpy, ks);
186 }
187 else
188 {
189 if ( (k>=0) && (i>=0 ) )
190 {
191 kc->mod_keycodes[0] = xd->map->modifiermap[k];
192 }
193 }
194 /* printf(" ------------------------------------------------------> Found. %d\n", kc->mod_keycodes[0]); */
195
196 ret = XNEE_OK ;
197 break;
198 }
199 }
200 return ret;
201 }
202
203
204
205
206
207 KeyCode
xnee_char2keycode(xnee_data * xd,char token,xnee_key_code * kc)208 xnee_char2keycode (xnee_data *xd, char token, xnee_key_code *kc)
209 {
210 char buf[2];
211 volatile KeySym ks = 0 ;
212
213 if (xd->fake==NULL)
214 {
215 return -1;
216 }
217
218 memset(kc,0,sizeof(xnee_key_code));
219 buf[0]=token;
220 buf[1]=0;
221
222 switch( token)
223 {
224 /* XK_0 --- XK_9 is skipped and solved elsewhere */
225 /* XK_A --- XK_Z is skipped and solved elsewhere */
226 /* XK_a --- XK_z is skipped and solved elsewhere ... below */
227 case ' ':
228 ks=XK_space;
229 break;
230 case '!':
231 ks=XK_exclam;
232 break;
233 /* case '!': */
234 /* ks=XK_exclamdown; */
235 /* break; */
236 case '\"':
237 ks=XK_quotedbl;
238 break;
239 case '#':
240 ks=XK_numbersign;
241 break;
242 case '$':
243 ks=XK_dollar;
244 break;
245 case '%':
246 ks=XK_percent;
247 break;
248 case '&':
249 ks=XK_ampersand;
250 break;
251 case '(':
252 ks=XK_parenleft;
253 break;
254 case ')':
255 ks=XK_parenright;
256 break;
257 case '+':
258 ks=XK_plus;
259 break;
260 case ',':
261 ks=XK_comma;
262 break;
263 case '-':
264 ks=XK_minus;
265 break;
266 case '.':
267 ks=XK_period;
268 break;
269 case '/':
270 ks=XK_slash;
271 break;
272 case ':':
273 ks=XK_colon;
274 break;
275 case ';':
276 ks=XK_semicolon;
277 break;
278 case '<':
279 ks=XK_less;
280 break;
281 case '=':
282 ks=XK_equal;
283 break;
284 case '>':
285 ks=XK_greater;
286 break;
287 case '?':
288 ks=XK_question;
289 break;
290 case '@':
291 ks=XK_at;
292 break;
293 case '*':
294 ks=XK_asterisk;
295 break;
296 case '\\':
297 ks=XK_backslash;
298 break;
299 case '[':
300 ks=XK_bracketleft;
301 break;
302 case ']':
303 ks=XK_bracketright;
304 break;
305 case '^':
306 ks=XK_asciicircum;
307 break;
308 case '_':
309 ks=XK_underscore;
310 break;
311 case '`':
312 ks=XK_grave;
313 break;
314 case '�':
315 ks=XK_quoteleft;
316 break;
317 case '\'':
318 ks=XK_quoteright;
319 break;
320 case 27:
321 ks=XK_apostrophe;
322 break;
323 case '{':
324 ks=XK_braceleft;
325 break;
326 case '}':
327 ks=XK_braceright;
328 break;
329 case '|':
330 ks=XK_bar;
331 break;
332 case '\n':
333 ks=XK_Return;
334 break;
335 case '\t':
336 ks=XK_Tab;
337 break;
338 case '~':
339 ks=XK_asciitilde;
340 break;
341 default:
342 break;
343 }
344
345
346 if ( ks != 0)
347 {
348 xnee_keysym2keycode(xd, ks, buf, kc);
349 }
350 else
351 {
352 xnee_str2keycode(xd, buf, kc);
353 }
354
355 return XNEE_OK;
356 }
357
358
359
360 #ifdef KEYSYMS_TO_USE_LATER
361 case -9:
362 ks=XK_nobreakspace;
363 break;
364 case -11:
365 /* FIX ME */
366 ks=XK_cent;
367 break;
368 case -12:
369 /* FIX ME */
370 ks=XK_sterling;
371 break;
372 case -13:
373 /* FIX ME */
374 ks=XK_currency;
375 break;
376
377
378 case -14:
379 /* FIX ME */
380 ks=XK_yen;
381 break;
382 case -15:
383 /* FIX ME */
384 ks=XK_brokenbar;
385 break;
386 case -16:
387 /* FIX ME */
388 ks=XK_section;
389 break;
390 case -17:
391 /* FIX ME */
392 ks=XK_diaeresis;
393 break;
394 case -18:
395 /* FIX ME */
396 ks=XK_copyright;
397 break;
398 case -19:
399 /* FIX ME */
400 ks=XK_ordfeminine;
401 break;
402 case -20:
403 /* FIX ME */
404 ks=XK_guillemotleft;
405 break;
406 case -21:
407 /* FIX ME */
408 ks=XK_notsign;
409 break;
410
411 case 'p':
412 /* FIX ME */
413 ks=XK_hyphen;
414 break;
415
416
417 case -23:
418 /* FIX ME */
419 ks=XK_registered;
420 break;
421 case -24:
422 /* FIX ME */
423 ks=XK_macron;
424 break;
425 case -25:
426 /* FIX ME */
427 ks=XK_degree;
428 break;
429 case -26:
430 /* FIX ME */
431 ks=XK_plusminus;
432 break;
433 case -27:
434 /* FIX ME */
435 ks=XK_twosuperior;
436 break;
437 case -28:
438 /* FIX ME */
439 ks=XK_threesuperior;
440 break;
441 case -29:
442 ks=XK_acute;
443 break;
444 case -30:
445 /* FIX ME */
446 ks=XK_mu;
447 break;
448 case -31:
449 /* FIX ME */
450 ks=XK_paragraph;
451 break;
452 case -32:
453 /* FIX ME */
454 ks=XK_periodcentered;
455 break;
456 case -33:
457 /* FIX ME */
458 ks=XK_cedilla;
459 break;
460 case -34:
461 /* FIX ME */
462 ks=XK_onesuperior;
463 break;
464 case -35:
465 /* FIX ME */
466 ks=XK_masculine;
467 break;
468 case -37:
469 /* FIX ME */
470 ks=XK_onequarter;
471 break;
472 case -38:
473 /* FIX ME */
474 ks=XK_onehalf;
475 break;
476 case -39:
477 /* FIX ME */
478 ks=XK_threequarters;
479 break;
480 case -40:
481 /* FIX ME */
482 ks=XK_questiondown;
483 break;
484 case 0:
485 /* FIX ME */
486 ks=XK_Agrave;
487 break;
488 case 0:
489 /* FIX ME */
490 ks=XK_Aacute;
491 break;
492 case 0:
493 /* FIX ME */
494 ks=XK_Acircumflex;
495 break;
496 case 0:
497 /* FIX ME */
498 ks=XK_Atilde;
499 break;
500 case 0:
501 /* FIX ME */
502 ks=XK_Adiaeresis;
503 break;
504 case 0:
505 /* FIX ME */
506 ks=XK_Aring;
507 break;
508 case 0:
509 /* FIX ME */
510 ks=XK_AE;
511 break;
512 case 0:
513 /* FIX ME */
514 ks=XK_Ccedilla;
515 break;
516 case 0:
517 /* FIX ME */
518 ks=XK_Egrave;
519 break;
520 case 0:
521 /* FIX ME */
522 ks=XK_Eacute;
523 break;
524 case 0:
525 /* FIX ME */
526 ks=XK_Ecircumflex;
527 break;
528 case 0:
529 /* FIX ME */
530 ks=XK_Ediaeresis;
531 break;
532 case 0:
533 /* FIX ME */
534 ks=XK_Igrave;
535 break;
536 case 0:
537 /* FIX ME */
538 ks=XK_Iacute;
539 break;
540 case 0:
541 /* FIX ME */
542 ks=XK_Icircumflex;
543 break;
544 case 0:
545 /* FIX ME */
546 ks=XK_Idiaeresis;
547 break;
548 case 0:
549 /* FIX ME */
550 ks=XK_ETH;
551 break;
552 case 0:
553 /* FIX ME */
554 ks=XK_Eth;
555 break;
556 case 0:
557 /* FIX ME */
558 ks=XK_Ntilde;
559 break;
560 case 0:
561 /* FIX ME */
562 ks=XK_Ograve;
563 break;
564 case 0:
565 /* FIX ME */
566 ks=XK_Oacute;
567 break;
568 case 0:
569 /* FIX ME */
570 ks=XK_Ocircumflex;
571 break;
572 case 0:
573 /* FIX ME */
574 ks=XK_Otilde;
575 break;
576 case 0:
577 /* FIX ME */
578 ks=XK_Odiaeresis;
579 break;
580 case 0:
581 /* FIX ME */
582 ks=XK_multiply;
583 break;
584 case 0:
585 /* FIX ME */
586 ks=XK_Ooblique;
587 break;
588 case 0:
589 /* FIX ME */
590 ks=XK_Oslash;
591 break;
592 case 0:
593 /* FIX ME */
594 ks=XK_Ugrave;
595 break;
596 case 0:
597 /* FIX ME */
598 ks=XK_Uacute;
599 break;
600 case 0:
601 /* FIX ME */
602 ks=XK_Ucircumflex;
603 break;
604 case 0:
605 /* FIX ME */
606 ks=XK_Udiaeresis;
607 break;
608 case 0:
609 /* FIX ME */
610 ks=XK_Yacute;
611 break;
612 case 0:
613 /* FIX ME */
614 ks=XK_THORN;
615 break;
616 case 0:
617 /* FIX ME */
618 ks=XK_Thorn;
619 break;
620 case 0:
621 /* FIX ME */
622 ks=XK_ssharp;
623 break;
624 case 0:
625 /* FIX ME */
626 ks=XK_agrave;
627 break;
628 case 0:
629 /* FIX ME */
630 ks=XK_aacute;
631 break;
632 case 0:
633 /* FIX ME */
634 ks=XK_acircumflex;
635 break;
636 case 0:
637 /* FIX ME */
638 ks=XK_atilde;
639 break;
640 case 0:
641 /* FIX ME */
642 ks=XK_adiaeresis;
643 break;
644 case 0:
645 /* FIX ME */
646 ks=XK_aring;
647 break;
648 case 0:
649 /* FIX ME */
650 ks=XK_ae;
651 break;
652 case 0:
653 /* FIX ME */
654 ks=XK_ccedilla;
655 break;
656 case 0:
657 /* FIX ME */
658 ks=XK_egrave;
659 break;
660 case 0:
661 /* FIX ME */
662 ks=XK_eacute;
663 break;
664 case 0:
665 /* FIX ME */
666 ks=XK_ecircumflex;
667 break;
668 case 0:
669 /* FIX ME */
670 ks=XK_ediaeresis;
671 break;
672 case 0:
673 /* FIX ME */
674 ks=XK_igrave;
675 break;
676 case 0:
677 /* FIX ME */
678 ks=XK_iacute;
679 break;
680 case 0:
681 /* FIX ME */
682 ks=XK_icircumflex;
683 break;
684 case 0:
685 /* FIX ME */
686 ks=XK_idiaeresis;
687 break;
688 case 0:
689 /* FIX ME */
690 ks=XK_eth;
691 break;
692 case 0:
693 /* FIX ME */
694 ks=XK_ntilde;
695 break;
696 case 0:
697 /* FIX ME */
698 ks=XK_ograve;
699 break;
700 case 0:
701 /* FIX ME */
702 ks=XK_oacute;
703 break;
704 case 0:
705 /* FIX ME */
706 ks=XK_ocircumflex;
707 break;
708 case 0:
709 /* FIX ME */
710 ks=XK_otilde;
711 break;
712 case 0:
713 /* FIX ME */
714 ks=XK_odiaeresis;
715 break;
716 case 0:
717 /* FIX ME */
718 ks=XK_division;
719 break;
720 case 0:
721 /* FIX ME */
722 ks=XK_oslash;
723 break;
724 case 0:
725 /* FIX ME */
726 ks=XK_ooblique;
727 break;
728 case 0:
729 /* FIX ME */
730 ks=XK_ugrave;
731 break;
732 case 0:
733 /* FIX ME */
734 ks=XK_uacute;
735 break;
736 case 0:
737 /* FIX ME */
738 ks=XK_ucircumflex;
739 break;
740 case 0:
741 /* FIX ME */
742 ks=XK_udiaeresis;
743 break;
744 case 0:
745 /* FIX ME */
746 ks=XK_yacute;
747 break;
748 case 0:
749 /* FIX ME */
750 ks=XK_thorn;
751 break;
752 case 0:
753 /* FIX ME */
754 ks=XK_ydiaeresis;
755 break;
756 case 0:
757 /* FIX ME */
758 ks=XK_guillemotright;
759 break;
760
761
762 #endif
763