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