466 |
} |
} |
467 |
|
|
468 |
unsigned short keycodes[] = { |
unsigned short keycodes[] = { |
469 |
KEY_LEFT, |
KEY_SPC, KEY_DEL, KEY_RET, KEY_ESC, KEY_TAB, KEY_SHIFT_TAB, |
470 |
KEY_RIGHT, |
KEY_CTRL(' '), KEY_DEL, KEY_CTRL('\\'), |
471 |
KEY_UP, |
KEY_CTRL(']'), KEY_CTRL('^'), KEY_CTRL('_'), |
472 |
KEY_DOWN, |
KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN, |
473 |
KEY_CTRL_LEFT, |
KEY_HOME, KEY_END, KEY_PAGEUP, KEY_PAGEDOWN, |
474 |
KEY_CTRL_RIGHT, |
KEY_CTRL_LEFT, KEY_CTRL_RIGHT, KEY_CTRL_UP, KEY_CTRL_DOWN, |
475 |
KEY_CTRL_UP, |
KEY_CTRL_HOME, KEY_CTRL_END, KEY_CTRL_PAGEUP, KEY_CTRL_PAGEDOWN, |
476 |
KEY_CTRL_DOWN, |
KEY_PAGEUP, KEY_PAGEDOWN, KEY_CTRL_PAGEUP, KEY_CTRL_PAGEDOWN, |
477 |
KEY_CTRL_HOME, |
KEY_INSERT, KEY_DELETE, KEY_DEFAULT, |
478 |
KEY_CTRL_END, |
KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, |
479 |
KEY_CTRL(' '), |
KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, |
480 |
KEY_CTRL('\\'), |
KEY_F11, KEY_F12, KEY_F13, KEY_F14, KEY_F15, |
481 |
KEY_CTRL(']'), |
KEY_F16, KEY_F17, KEY_F18, KEY_F19, KEY_F20, |
|
KEY_CTRL('^'), |
|
|
KEY_CTRL('_'), |
|
|
KEY_BACKSPACE, |
|
|
KEY_INSERT, |
|
|
KEY_DELETE, |
|
|
KEY_PAGEUP, |
|
|
KEY_PAGEDOWN, |
|
|
KEY_HOME, |
|
|
KEY_END, |
|
|
' ', |
|
|
KEY_RET, |
|
|
KEY_ESC, |
|
|
KEY_TAB, |
|
|
KEY_SHIFT_TAB, |
|
|
KEY_DEFAULT, |
|
482 |
}; |
}; |
483 |
|
|
484 |
const char *keystr[] = { |
const char *keystr[] = { |
485 |
|
"SPC", "DEL", "RET", "ESC", "TAB", "S-TAB", |
486 |
|
"C-SPC", "C-?", "C-\\", "C-]", "C-^", "C-_", |
487 |
"left", "right", "up", "down", |
"left", "right", "up", "down", |
488 |
"C-left", "C-right", "C-up", "C-down", |
"home", "end", "prior", "next", |
489 |
"C-home", "C-end", |
"C-left", "C-right", "C-up", "C-down", |
490 |
"C-space", "C-\\", "C-]", "C-^", "C-_", |
"C-home", "C-end", "C-prior", "C-next", |
491 |
"backspace", "insert", "delete", "prior", "next", |
"pageup", "pagedown", "C-pageup", "C-pagedown", |
492 |
"home", "end", |
"insert", "delete", "default", |
493 |
"SPC", "RET", "ESC", |
"f1", "f2", "f3", "f4", "f5", |
494 |
"TAB", "S-TAB", |
"f6", "f7", "f8", "f9", "f10", |
495 |
"default", |
"f11", "f12", "f13", "f14", "f15", |
496 |
|
"f16", "f17", "f18", "f19", "f20", |
497 |
}; |
}; |
498 |
|
|
499 |
static int strtokey1(const char *p) |
int compose_keys(int *keys, int *nb_keys) |
500 |
{ |
{ |
501 |
int i, n; |
int *keyp; |
502 |
|
|
503 |
for (i = 0; i < (int)(sizeof(keycodes)/sizeof(keycodes[0])); i++) { |
if (*nb_keys < 2) |
504 |
if (!strcmp(p, keystr[i])) |
return 0; |
505 |
return keycodes[i]; |
|
506 |
|
/* compose KEY_ESC as META prefix */ |
507 |
|
keyp = keys + *nb_keys - 2; |
508 |
|
if (keyp[0] == KEY_ESC) { |
509 |
|
if (keyp[1] <= 0xff) { |
510 |
|
keyp[0] = KEY_META(keyp[1]); |
511 |
|
--*nb_keys; |
512 |
|
return 1; |
513 |
|
} |
514 |
} |
} |
515 |
|
return 0; |
516 |
|
} |
517 |
|
|
518 |
|
/* CG: this code is still quite inelegant */ |
519 |
|
static int strtokey1(const char **pp) |
520 |
|
{ |
521 |
|
const char *p, *p1, *q; |
522 |
|
int i, key; |
523 |
|
|
524 |
|
/* should return KEY_NONE at end and KEY_UNKNOWN if unrecognized */ |
525 |
|
p = *pp; |
526 |
|
|
527 |
|
/* scan for separator */ |
528 |
|
for (p1 = p; *p1 && *p1 != ' '; p1++) |
529 |
|
continue; |
530 |
|
|
531 |
|
for (i = 0; i < sizeof(keycodes)/sizeof(keycodes[0]); i++) { |
532 |
|
if (strstart(p, keystr[i], &q) && q == p1) { |
533 |
|
key = keycodes[i]; |
534 |
|
*pp = p1; |
535 |
|
return key; |
536 |
|
} |
537 |
|
} |
538 |
|
#if 0 |
539 |
if (p[0] == 'f' && p[1] >= '1' && p[1] <= '9') { |
if (p[0] == 'f' && p[1] >= '1' && p[1] <= '9') { |
540 |
p++; |
i = p[1] - '0'; |
541 |
n = *p - '0'; |
p += 2; |
542 |
if (isdigit((unsigned char)p[1])) |
if (p1 == isdigit((unsigned char)*p)) |
543 |
n = n * 10 + p[1] - '0'; |
i = i * 10 + *p++ - '0'; |
544 |
return KEY_F1 + n - 1; |
key = KEY_F1 + i - 1; |
545 |
|
*pp = p1; |
546 |
|
return key; |
547 |
|
} |
548 |
|
#endif |
549 |
|
if (p[0] == 'C' && p[1] == '-' && p1 == p + 3) { |
550 |
|
/* control */ |
551 |
|
key = KEY_CTRL(p[2]); |
552 |
|
} else { |
553 |
|
key = utf8_decode(&p); |
554 |
} |
} |
555 |
return utf8_decode(&p); |
*pp = p1; |
556 |
|
|
557 |
|
return key; |
558 |
} |
} |
559 |
|
|
560 |
int strtokey(const char **pp) |
int strtokey(const char **pp) |
562 |
const char *p; |
const char *p; |
563 |
int key; |
int key; |
564 |
|
|
|
/* XXX: handle all cases */ |
|
565 |
p = *pp; |
p = *pp; |
566 |
if (p[0] == 'C' && p[1] == '-') { |
if (p[0] == 'M' && p[1] == '-') { |
|
/* control */ |
|
|
p += 2; |
|
|
key = strtokey1(p); |
|
|
if (key >= 'a' && key <= 'z') |
|
|
key = KEY_CTRL(key); |
|
|
} else if (p[0] == 'M' && p[1] == '-') { |
|
567 |
p += 2; |
p += 2; |
568 |
key = strtokey1(p); |
key = KEY_META(strtokey1(&p)); |
569 |
if ((key >= 'a' && key <= 'z') || |
} else |
570 |
key == KEY_BACKSPACE) |
if (p[0] == 'C' && p[1] == '-' && p[0] == 'M' && p[1] == '-') { |
571 |
key = KEY_META(key); |
p += 4; |
572 |
|
key = KEY_META(KEY_CTRL(strtokey1(&p))); |
573 |
} else { |
} else { |
574 |
key = strtokey1(p); |
key = strtokey1(&p); |
575 |
} |
} |
|
while (*p != ' ' && *p != '\0') |
|
|
p++; |
|
576 |
*pp = p; |
*pp = p; |
577 |
return key; |
return key; |
578 |
} |
} |
579 |
|
|
580 |
|
int strtokeys(const char *keystr, unsigned int *keys, int max_keys) |
581 |
|
{ |
582 |
|
int key, nb_keys; |
583 |
|
const char *p; |
584 |
|
|
585 |
|
p = keystr; |
586 |
|
nb_keys = 0; |
587 |
|
|
588 |
|
for (;;) { |
589 |
|
skip_spaces(&p); |
590 |
|
if (*p == '\0') |
591 |
|
break; |
592 |
|
key = strtokey(&p); |
593 |
|
keys[nb_keys++] = key; |
594 |
|
compose_keys(keys, &nb_keys); |
595 |
|
if (nb_keys >= max_keys) |
596 |
|
break; |
597 |
|
} |
598 |
|
return nb_keys; |
599 |
|
} |
600 |
|
|
601 |
void keytostr(char *buf, int buf_size, int key) |
void keytostr(char *buf, int buf_size, int key) |
602 |
{ |
{ |
603 |
int i; |
int i; |
609 |
return; |
return; |
610 |
} |
} |
611 |
} |
} |
612 |
if (key >= KEY_META(' ') && key <= KEY_META(127)) { |
if (key >= KEY_META(0) && key <= KEY_META(0xff)) { |
613 |
keytostr(buf1, sizeof(buf1), key & 0xff); |
keytostr(buf1, sizeof(buf1), key & 0xff); |
614 |
snprintf(buf, buf_size, "M-%s", buf1); |
snprintf(buf, buf_size, "M-%s", buf1); |
615 |
} else if (key >= 1 && key <= 31) { |
} else if (key >= KEY_CTRL('a') && key <= KEY_CTRL('z')) { |
616 |
snprintf(buf, buf_size, "C-%c", key + 'a' - 1); |
snprintf(buf, buf_size, "C-%c", key + 'a' - 1); |
617 |
} else if (key >= KEY_F1 && key <= KEY_F12) { |
} else if (key >= KEY_F1 && key <= KEY_F20) { |
618 |
snprintf(buf, buf_size, "F%d", key - KEY_F1 + 1); |
snprintf(buf, buf_size, "f%d", key - KEY_F1 + 1); |
619 |
|
} else if (key > 32 && key < 127 && buf_size >= 2) { |
620 |
|
buf[0] = key; |
621 |
|
buf[1] = '\0'; |
622 |
} else { |
} else { |
623 |
char *q; |
char *q; |
624 |
/* CG: assuming buf_size > 5 */ |
q = utf8_encode(buf1, key); |
|
q = utf8_encode(buf, key); |
|
625 |
*q = '\0'; |
*q = '\0'; |
626 |
|
pstrcpy(buf, buf_size, buf1); |
627 |
} |
} |
628 |
} |
} |
629 |
|
|