version 1.13, 2010/01/14 21:53:40 |
version 1.14, 2010/04/21 21:17:33 |
|
|
#include "tmux.h" |
#include "tmux.h" |
|
|
int key_string_search_table(const char *); |
int key_string_search_table(const char *); |
|
int key_string_get_modifiers(const char **); |
|
|
struct { |
struct { |
const char *string; |
const char *string; |
int key; |
int key; |
} key_string_table[] = { |
} key_string_table[] = { |
/* Function keys. */ |
/* Function keys. */ |
{ "F1", KEYC_F1 }, |
{ "F1", KEYC_F1 }, |
|
|
return (KEYC_NONE); |
return (KEYC_NONE); |
} |
} |
|
|
/* Lookup a string and convert to a key value, handling C-/M-/S- prefix. */ |
/* Find modifiers. */ |
int |
int |
key_string_lookup_string(const char *string) |
key_string_get_modifiers(const char **string) |
{ |
{ |
int key; |
int modifiers; |
const char *ptr; |
|
|
|
if (string[0] == '\0') |
modifiers = 0; |
return (KEYC_NONE); |
while (((*string)[0] != '\0') && (*string)[1] == '-') { |
if (string[1] == '\0') |
switch ((*string)[0]) { |
return ((u_char) string[0]); |
case 'C': |
|
case 'c': |
ptr = NULL; |
modifiers |= KEYC_CTRL; |
if ((string[0] == 'C' || string[0] == 'c') && string[1] == '-') |
break; |
ptr = string + 2; |
case 'M': |
else if (string[0] == '^') |
case 'm': |
ptr = string + 1; |
modifiers |= KEYC_ESCAPE; |
if (ptr != NULL) { |
break; |
if (ptr[0] == '\0') |
case 'S': |
return (KEYC_NONE); |
case 's': |
/* |
modifiers |= KEYC_SHIFT; |
* Lookup as a named key. If a function key (>= KEYC_BASE), |
break; |
* return it with the ctrl modifier, otherwise fallthrough with |
|
* the key value from the table (eg for C-Space). If not a |
|
* named key, check for single character keys and try that. |
|
*/ |
|
key = key_string_search_table(ptr); |
|
if (key != KEYC_NONE) { |
|
if (key >= KEYC_BASE) |
|
return (key | KEYC_CTRL); |
|
} else { |
|
if (ptr[1] != '\0') |
|
return (KEYC_NONE); |
|
key = (u_char) ptr[0]; |
|
} |
} |
|
*string += 2; |
/* |
|
* Figure out if the single character in key is a valid ctrl |
|
* key. |
|
*/ |
|
if (key == 32) |
|
return (0); |
|
if (key == 63) |
|
return (KEYC_BSPACE); |
|
if (key >= 64 && key <= 95) |
|
return (key - 64); |
|
if (key >= 97 && key <= 122) |
|
return (key - 96); |
|
return (KEYC_NONE); |
|
} |
} |
|
return (modifiers); |
|
} |
|
|
if ((string[0] == 'M' || string[0] == 'm') && string[1] == '-') { |
/* Lookup a string and convert to a key value. */ |
ptr = string + 2; |
int |
if (ptr[0] == '\0') |
key_string_lookup_string(const char *string) |
return (KEYC_NONE); |
{ |
key = key_string_lookup_string(ptr); |
int key, modifiers; |
if (key != KEYC_NONE) { |
|
if (key >= KEYC_BASE) |
|
return (key | KEYC_ESCAPE); |
|
} else { |
|
if (ptr[1] == '\0') |
|
return (KEYC_NONE); |
|
key = (u_char) ptr[0]; |
|
} |
|
|
|
if (key >= 32 && key <= 127) |
/* Check for modifiers. */ |
return (key | KEYC_ESCAPE); |
modifiers = 0; |
return (KEYC_NONE); |
if (string[0] == '^' && string[1] != '\0') { |
|
modifiers |= KEYC_CTRL; |
|
string++; |
} |
} |
|
modifiers |= key_string_get_modifiers(&string); |
|
if (string[0] == '\0') |
|
return (KEYC_NONE); |
|
|
if ((string[0] == 'S' || string[0] == 's') && string[1] == '-') { |
/* Is this a standard ASCII key? */ |
ptr = string + 2; |
if (string[1] == '\0') { |
if (ptr[0] == '\0') |
key = (u_char) string[0]; |
|
if (key < 32 || key > 126) |
return (KEYC_NONE); |
return (KEYC_NONE); |
key = key_string_lookup_string(ptr); |
|
if (key != KEYC_NONE) { |
/* Convert the standard control keys. */ |
if (key >= KEYC_BASE) |
if (modifiers & KEYC_CTRL) { |
return (key | KEYC_SHIFT); |
if (key >= 97 && key <= 122) |
} else { |
key -= 96; |
if (ptr[1] == '\0') |
else if (key >= 65 && key <= 90) |
|
key -= 65; |
|
else if (key == 32) |
|
key = 0; |
|
else if (key == 63) |
|
key = KEYC_BSPACE; |
|
else |
return (KEYC_NONE); |
return (KEYC_NONE); |
key = (u_char) ptr[0]; |
modifiers &= ~KEYC_CTRL; |
} |
} |
|
|
if (key >= 32 && key <= 127) |
return (key | modifiers); |
return (key | KEYC_SHIFT); |
|
return (KEYC_NONE); |
|
} |
} |
|
|
return (key_string_search_table(string)); |
/* Otherwise look the key up in the table. */ |
|
key = key_string_search_table(string); |
|
if (key == KEYC_NONE) |
|
return (KEYC_NONE); |
|
return (key | modifiers); |
} |
} |
|
|
/* Convert a key code into string format, with prefix if necessary. */ |
/* Convert a key code into string format, with prefix if necessary. */ |
const char * |
const char * |
key_string_lookup_key(int key) |
key_string_lookup_key(int key) |
{ |
{ |
static char tmp[24], tmp2[24]; |
static char out[24]; |
const char *s; |
char tmp[8]; |
u_int i; |
u_int i; |
|
|
if (key == 127) |
*out = '\0'; |
return (NULL); |
|
|
|
if (key & KEYC_ESCAPE) { |
/* Fill in the modifiers. */ |
if ((s = key_string_lookup_key(key & ~KEYC_ESCAPE)) == NULL) |
if (key & KEYC_CTRL) |
return (NULL); |
strlcat(out, "C-", sizeof out); |
xsnprintf(tmp2, sizeof tmp2, "M-%s", s); |
if (key & KEYC_ESCAPE) |
return (tmp2); |
strlcat(out, "M-", sizeof out); |
} |
if (key & KEYC_SHIFT) |
if (key & KEYC_CTRL) { |
strlcat(out, "S-", sizeof out); |
if ((s = key_string_lookup_key(key & ~KEYC_CTRL)) == NULL) |
key &= ~(KEYC_CTRL|KEYC_ESCAPE|KEYC_SHIFT); |
return (NULL); |
|
xsnprintf(tmp2, sizeof tmp2, "C-%s", s); |
|
return (tmp2); |
|
} |
|
if (key & KEYC_SHIFT) { |
|
if ((s = key_string_lookup_key(key & ~KEYC_SHIFT)) == NULL) |
|
return (NULL); |
|
xsnprintf(tmp2, sizeof tmp2, "S-%s", s); |
|
return (tmp2); |
|
} |
|
|
|
|
/* Try the key against the string table. */ |
for (i = 0; i < nitems(key_string_table); i++) { |
for (i = 0; i < nitems(key_string_table); i++) { |
if (key == key_string_table[i].key) |
if (key == key_string_table[i].key) |
return (key_string_table[i].string); |
break; |
} |
} |
|
if (i != nitems(key_string_table)) { |
if (key >= 32 && key <= 255) { |
strlcat(out, key_string_table[i].string, sizeof out); |
tmp[0] = (char) key; |
return (out); |
tmp[1] = '\0'; |
|
return (tmp); |
|
} |
} |
|
|
|
/* Invalid keys are errors. */ |
|
if (key >= 127) |
|
return (NULL); |
|
|
|
/* Check for standard or control key. */ |
if (key >= 0 && key <= 32) { |
if (key >= 0 && key <= 32) { |
if (key == 0 || key > 26) |
if (key == 0 || key > 26) |
xsnprintf(tmp, sizeof tmp, "C-%c", 64 + key); |
xsnprintf(tmp, sizeof tmp, "C-%c", 64 + key); |
else |
else |
xsnprintf(tmp, sizeof tmp, "C-%c", 96 + key); |
xsnprintf(tmp, sizeof tmp, "C-%c", 96 + key); |
return (tmp); |
} else if (key >= 32 && key <= 126) { |
|
tmp[0] = key; |
|
tmp[1] = '\0'; |
} |
} |
|
strlcat(out, tmp, sizeof out); |
return (NULL); |
return (out); |
} |
} |