1 /*
2 
3   Copyright (c) 2003-2013 uim Project https://github.com/uim/uim
4 
5   All rights reserved.
6 
7   Redistribution and use in source and binary forms, with or without
8   modification, are permitted provided that the following conditions
9   are met:
10 
11   1. Redistributions of source code must retain the above copyright
12      notice, this list of conditions and the following disclaimer.
13   2. Redistributions in binary form must reproduce the above copyright
14      notice, this list of conditions and the following disclaimer in the
15      documentation and/or other materials provided with the distribution.
16   3. Neither the name of authors nor the names of its contributors
17      may be used to endorse or promote products derived from this software
18      without specific prior written permission.
19 
20   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
21   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
24   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26   OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29   OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30   SUCH DAMAGE.
31 
32 */
33 
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37 #if (!defined(DEBUG) && !defined(NDEBUG))
38 #define NDEBUG
39 #endif
40 
41 #include <uim/uim.h>
42 
43 #ifdef HAVE_CURSES_H
44 #include <curses.h>
45 #endif
46 #ifdef HAVE_TERM_H
47 #include <term.h>
48 #elif HAVE_NCURSES_TERM_H
49 #include <ncurses/term.h>
50 #endif
51 #ifdef HAVE_STRING_H
52 #include <string.h>
53 #endif
54 #ifdef HAVE_STDLIB_H
55 #include <stdlib.h>
56 #endif
57 #ifdef HAVE_ASSERT_H
58 #include <assert.h>
59 #endif
60 #include "key.h"
61 #include "uim-fep.h"
62 
63 #define _KEY_UP    "\033[A"
64 #define _KEY_DOWN  "\033[B"
65 #define _KEY_RIGHT "\033[C"
66 #define _KEY_LEFT  "\033[D"
67 
68 static int strcmp_prefix(const char *str, int str_len, const char *prefix);
69 
tty2key(char key)70 int tty2key(char key)
71 {
72   key &= 0x7f;
73   switch (key) {
74   /* c-space */
75   case 0:
76     return ' ';
77   case '\t':
78     return UKey_Tab;
79   case '\r':
80     return UKey_Return;
81   /* c-[ */
82   case ESCAPE_CODE:
83     return UKey_Escape;
84   /* c-? */
85   case 0x7f:
86     return UKey_Delete;
87   }
88   /* c-a から c-z */
89   if (key >= 1 && key <= 26) {
90     return key + ('a' - 1);
91   }
92   /* c-\ c-] c-^ c-_ */
93   if (key >= 28 && key <= 31) {
94     return key + ('A' - 1);
95   }
96   return key;
97 }
98 
tty2key_state(char key)99 int tty2key_state(char key)
100 {
101   int key_state = (key & 0x80) ? UMod_Meta : 0;
102   key &= 0x7f;
103   if (key == '\t' ||
104       key == '\r' ||
105       key == ESCAPE_CODE ||
106       key == 0x7f) {
107     return key_state;
108   }
109   if (key >= 'A' && key <= 'Z') {
110     key_state += UMod_Shift;
111   }
112   if (key <= 31) {
113     key_state +=  UMod_Control;
114   }
115   return key_state;
116 }
117 
118 /*
119  * strに対応するキーコードとエスケープシーケンスの長さを返す
120  * 見つからなかったらUKey_Escapeと、途中まで一致しているエスケープシー
121  * ケンスがある場合はTRUEない場合はFALSEを返す
122  */
escape_sequence2key(const char * str,int str_len)123 int *escape_sequence2key(const char *str, int str_len)
124 {
125   static int rval[2];
126   int len;
127   int not_enough = 0;
128   if        (                         (not_enough += len = strcmp_prefix(str, str_len, _KEY_UP      )), len > 0) { rval[0] = UKey_Up;
129   } else if (                         (not_enough += len = strcmp_prefix(str, str_len, _KEY_DOWN    )), len > 0) { rval[0] = UKey_Down;
130   } else if (                         (not_enough += len = strcmp_prefix(str, str_len, _KEY_RIGHT   )), len > 0) { rval[0] = UKey_Right;
131   } else if (                         (not_enough += len = strcmp_prefix(str, str_len, _KEY_LEFT    )), len > 0) { rval[0] = UKey_Left;
132   } else if (key_backspace != NULL && ((not_enough += len = strcmp_prefix(str, str_len, key_backspace)), len > 0)) { rval[0] = UKey_Backspace;
133   } else if (key_dc        != NULL && ((not_enough += len = strcmp_prefix(str, str_len, key_dc       )), len > 0)) { rval[0] = UKey_Delete;
134   } else if (key_left      != NULL && ((not_enough += len = strcmp_prefix(str, str_len, key_left     )), len > 0)) { rval[0] = UKey_Left;
135   } else if (key_up        != NULL && ((not_enough += len = strcmp_prefix(str, str_len, key_up       )), len > 0)) { rval[0] = UKey_Up;
136   } else if (key_right     != NULL && ((not_enough += len = strcmp_prefix(str, str_len, key_right    )), len > 0)) { rval[0] = UKey_Right;
137   } else if (key_down      != NULL && ((not_enough += len = strcmp_prefix(str, str_len, key_down     )), len > 0)) { rval[0] = UKey_Down;
138   } else if (key_ppage     != NULL && ((not_enough += len = strcmp_prefix(str, str_len, key_ppage    )), len > 0)) { rval[0] = UKey_Prior;
139   } else if (key_npage     != NULL && ((not_enough += len = strcmp_prefix(str, str_len, key_npage    )), len > 0)) { rval[0] = UKey_Next;
140   } else if (key_home      != NULL && ((not_enough += len = strcmp_prefix(str, str_len, key_home     )), len > 0)) { rval[0] = UKey_Home;
141   } else if (key_end       != NULL && ((not_enough += len = strcmp_prefix(str, str_len, key_end      )), len > 0)) { rval[0] = UKey_End;
142   } else if (key_ic        != NULL && ((not_enough += len = strcmp_prefix(str, str_len, key_ic       )), len > 0)) { rval[0] = UKey_Insert;
143   } else if (key_f1        != NULL && ((not_enough += len = strcmp_prefix(str, str_len, key_f1       )), len > 0)) { rval[0] = UKey_F1;
144   } else if (key_f2        != NULL && ((not_enough += len = strcmp_prefix(str, str_len, key_f2       )), len > 0)) { rval[0] = UKey_F2;
145   } else if (key_f3        != NULL && ((not_enough += len = strcmp_prefix(str, str_len, key_f3       )), len > 0)) { rval[0] = UKey_F3;
146   } else if (key_f4        != NULL && ((not_enough += len = strcmp_prefix(str, str_len, key_f4       )), len > 0)) { rval[0] = UKey_F4;
147   } else if (key_f5        != NULL && ((not_enough += len = strcmp_prefix(str, str_len, key_f5       )), len > 0)) { rval[0] = UKey_F5;
148   } else if (key_f6        != NULL && ((not_enough += len = strcmp_prefix(str, str_len, key_f6       )), len > 0)) { rval[0] = UKey_F6;
149   } else if (key_f7        != NULL && ((not_enough += len = strcmp_prefix(str, str_len, key_f7       )), len > 0)) { rval[0] = UKey_F7;
150   } else if (key_f8        != NULL && ((not_enough += len = strcmp_prefix(str, str_len, key_f8       )), len > 0)) { rval[0] = UKey_F8;
151   } else if (key_f9        != NULL && ((not_enough += len = strcmp_prefix(str, str_len, key_f9       )), len > 0)) { rval[0] = UKey_F9;
152   } else if (key_f10       != NULL && ((not_enough += len = strcmp_prefix(str, str_len, key_f10      )), len > 0)) { rval[0] = UKey_F10;
153   } else if (key_f11       != NULL && ((not_enough += len = strcmp_prefix(str, str_len, key_f11      )), len > 0)) { rval[0] = UKey_F11;
154   } else if (key_f12       != NULL && ((not_enough += len = strcmp_prefix(str, str_len, key_f12      )), len > 0)) { rval[0] = UKey_F12;
155   } else {
156     rval[0] = UKey_Other;
157     len = not_enough < 0 ? TRUE : FALSE;
158   }
159   rval[1] = len;
160   return rval;
161 }
162 
163 /*
164  * prefixがstrの語頭のときstrlen(prefix)を返す
165  * strがprefixの語頭のとき-strlen(str)を返す
166  * それ以外は0を返す
167  */
strcmp_prefix(const char * str,int str_len,const char * prefix)168 static int strcmp_prefix(const char *str, int str_len, const char *prefix)
169 {
170   int i;
171   assert(str != NULL && prefix != NULL);
172   for (i = 0; i < str_len && prefix[i] != '\0'; i++) {
173     if (str[i] != prefix[i]) {
174       break;
175     }
176   }
177   if (prefix[i] == '\0') {
178     return i;
179   }
180   if (i == str_len) {
181     return -i;
182   }
183   return 0;
184 }
185 
186 
print_key(int key,int key_state)187 void print_key(int key, int key_state)
188 {
189   if (key == 'q' && key_state == 0) {
190     done(EXIT_SUCCESS);
191   }
192   printf("\"");
193   if (key_state & UMod_Alt) {
194     printf("<Alt>");
195   }
196   if (key_state & UMod_Meta) {
197     printf("<Meta>");
198   }
199   if (key_state & UMod_Control) {
200     printf("<Control>");
201   }
202 
203   if (key == '"' || key == '\\') {
204     printf("\\%c", key);
205   } else if (key >= ' ' && key <= 127) {
206     printf("%c", key);
207   } else {
208     switch (key) {
209     case UKey_Escape:
210       printf("escape");
211       break;
212     case UKey_Tab:
213       printf("tab");
214       break;
215     case UKey_Backspace:
216       printf("backspace");
217       break;
218     case UKey_Delete:
219       printf("delete");
220       break;
221     case UKey_Return:
222       printf("return");
223       break;
224     case UKey_Left:
225       printf("left");
226       break;
227     case UKey_Up:
228       printf("up");
229       break;
230     case UKey_Right:
231       printf("right");
232       break;
233     case UKey_Down:
234       printf("down");
235       break;
236     case UKey_Prior:
237       printf("prior");
238       break;
239     case UKey_Next:
240       printf("next");
241       break;
242     case UKey_Home:
243       printf("home");
244       break;
245     case UKey_End:
246       printf("end");
247       break;
248     case UKey_Insert:
249       printf("insert");
250       break;
251     case UKey_Multi_key:
252       printf("Multi_key");
253       break;
254     case UKey_Mode_switch:
255       printf("Mode_switch");
256       break;
257     case UKey_Kanji:
258       printf("Kanji");
259       break;
260     case UKey_Muhenkan:
261       printf("Muhenkan");
262       break;
263     case UKey_Henkan_Mode:
264       printf("Henkan_Mode");
265       break;
266     case UKey_Romaji:
267       printf("romaji");
268       break;
269     case UKey_Hiragana:
270       printf("hiragana");
271       break;
272     case UKey_Katakana:
273       printf("katakana");
274       break;
275     case UKey_Hiragana_Katakana:
276       printf("hiragana-katakana");
277       break;
278     case UKey_Zenkaku:
279       printf("zenkaku");
280       break;
281     case UKey_Hankaku:
282       printf("hankaku");
283       break;
284     case UKey_Zenkaku_Hankaku:
285       printf("zenkaku-hankaku");
286       break;
287     case UKey_Touroku:
288       printf("touroku");
289       break;
290     case UKey_Massyo:
291       printf("massyo");
292       break;
293     case UKey_Kana_Lock:
294       printf("kana-lock");
295       break;
296     case UKey_Kana_Shift:
297       printf("kana-shift");
298       break;
299     case UKey_Eisu_Shift:
300       printf("eisu-shift");
301       break;
302     case UKey_Eisu_toggle:
303       printf("eisu-toggle");
304       break;
305     case UKey_F1:
306       printf("F1");
307       break;
308     case UKey_F2:
309       printf("F2");
310       break;
311     case UKey_F3:
312       printf("F3");
313       break;
314     case UKey_F4:
315       printf("F4");
316       break;
317     case UKey_F5:
318       printf("F5");
319       break;
320     case UKey_F6:
321       printf("F6");
322       break;
323     case UKey_F7:
324       printf("F7");
325       break;
326     case UKey_F8:
327       printf("F8");
328       break;
329     case UKey_F9:
330       printf("F9");
331       break;
332     case UKey_F10:
333       printf("F10");
334       break;
335     case UKey_F11:
336       printf("F11");
337       break;
338     case UKey_F12:
339       printf("F12");
340       break;
341     case UKey_F13:
342       printf("F13");
343       break;
344     case UKey_F14:
345       printf("F14");
346       break;
347     case UKey_F15:
348       printf("F15");
349       break;
350     case UKey_F16:
351       printf("F16");
352       break;
353     case UKey_F17:
354       printf("F17");
355       break;
356     case UKey_F18:
357       printf("F18");
358       break;
359     case UKey_F19:
360       printf("F19");
361       break;
362     case UKey_F20:
363       printf("F20");
364       break;
365     case UKey_F21:
366       printf("F21");
367       break;
368     case UKey_F22:
369       printf("F22");
370       break;
371     case UKey_F23:
372       printf("F23");
373       break;
374     case UKey_F24:
375       printf("F24");
376       break;
377     case UKey_F25:
378       printf("F25");
379       break;
380     case UKey_F26:
381       printf("F26");
382       break;
383     case UKey_F27:
384       printf("F27");
385       break;
386     case UKey_F28:
387       printf("F28");
388       break;
389     case UKey_F29:
390       printf("F29");
391       break;
392     case UKey_F30:
393       printf("F30");
394       break;
395     case UKey_F31:
396       printf("F31");
397       break;
398     case UKey_F32:
399       printf("F32");
400       break;
401     case UKey_F33:
402       printf("F33");
403       break;
404     case UKey_F34:
405       printf("F34");
406       break;
407     case UKey_F35:
408       printf("F35");
409       break;
410     case UKey_Private1:
411       printf("Private1");
412       break;
413     case UKey_Private2:
414       printf("Private2");
415       break;
416     case UKey_Private3:
417       printf("Private3");
418       break;
419     case UKey_Private4:
420       printf("Private4");
421       break;
422     case UKey_Private5:
423       printf("Private5");
424       break;
425     case UKey_Private6:
426       printf("Private6");
427       break;
428     case UKey_Private7:
429       printf("Private7");
430       break;
431     case UKey_Private8:
432       printf("Private8");
433       break;
434     case UKey_Private9:
435       printf("Private9");
436       break;
437     case UKey_Private10:
438       printf("Private10");
439       break;
440     case UKey_Private11:
441       printf("Private11");
442       break;
443     case UKey_Private12:
444       printf("Private12");
445       break;
446     case UKey_Private13:
447       printf("Private13");
448       break;
449     case UKey_Private14:
450       printf("Private14");
451       break;
452     case UKey_Private15:
453       printf("Private15");
454       break;
455     case UKey_Private16:
456       printf("Private16");
457       break;
458     case UKey_Private17:
459       printf("Private17");
460       break;
461     case UKey_Private18:
462       printf("Private18");
463       break;
464     case UKey_Private19:
465       printf("Private19");
466       break;
467     case UKey_Private20:
468       printf("Private20");
469       break;
470     case UKey_Private21:
471       printf("Private21");
472       break;
473     case UKey_Private22:
474       printf("Private22");
475       break;
476     case UKey_Private23:
477       printf("Private23");
478       break;
479     case UKey_Private24:
480       printf("Private24");
481       break;
482     case UKey_Private25:
483       printf("Private25");
484       break;
485     case UKey_Private26:
486       printf("Private26");
487       break;
488     case UKey_Private27:
489       printf("Private27");
490       break;
491     case UKey_Private28:
492       printf("Private28");
493       break;
494     case UKey_Private29:
495       printf("Private29");
496       break;
497     case UKey_Private30:
498       printf("Private30");
499       break;
500     case UKey_Shift_key:
501       printf("Shift_key");
502       break;
503     case UKey_Control_key:
504       printf("Control_key");
505       break;
506     case UKey_Alt_key:
507       printf("Alt_key");
508       break;
509     case UKey_Meta_key:
510       printf("Meta_key");
511       break;
512     case UKey_Super_key:
513       printf("Super_key");
514       break;
515     case UKey_Hyper_key:
516       printf("Hyper_key");
517       break;
518     }
519   }
520   printf("\"\r\n");
521 }
522 
523