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