Updates for UTF-8 key bindings

Code point mapping adjusted for multibyte characters to avoid the
ncurses range 0-KEY_MAX.

This includes three fixes:

1) test sequence in keys_assign_binding(),
2) reassemble multi-byte character in keys_wgetch(),
3) check for already in use in keys_assign_binding().

Rearrangement of code. The introduction of allocated memory in
keys_int2str() has as a consequence that check for recognized ncurses
pseudo characters now are in two places: keys_str2int() and
custom_keys_config(). The latter was moved from keys_wgetch() to improve
user information.

More informative warning messages in custom_keys_config().

Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
This commit is contained in:
Lars Henriksen 2017-09-27 21:45:33 +02:00 committed by Lukas Fleischer
parent efd76a0d99
commit dd5af2f7f4
2 changed files with 39 additions and 39 deletions

View File

@ -998,11 +998,14 @@ void custom_keys_config(void)
keys_get_label(selrow), 0); keys_get_label(selrow), 0);
ch = keys_wgetch(grabwin); ch = keys_wgetch(grabwin);
/* First check if this key would be recognized by calcurse. */ /* Check if this is a ncurses pseudo key accepted by calcurse. */
if (ch < 0) { if (ch >= KEY_MIN && ch <= KEY_MAX && !(
ch == KEY_UP || ch == KEY_DOWN ||
ch == KEY_LEFT || ch == KEY_RIGHT ||
ch == KEY_HOME || ch == KEY_END)) {
not_recognized = 1; not_recognized = 1;
WARN_MSG(_("This key is not yet recognized by calcurse, " WARN_MSG(_("The key '%s' is not accepted by calcurse. "
"please choose another one.")); "Choose another one."), keyname(ch));
werase(kwin.inner); werase(kwin.inner);
nbrowelm = nbrowelm =
print_keys_bindings(kwin.inner, print_keys_bindings(kwin.inner,
@ -1026,9 +1029,12 @@ void custom_keys_config(void)
enum key action; enum key action;
action = keys_get_action(ch); action = keys_get_action(ch);
WARN_MSG(_("This key is already in use for %s, " char *keystr = keys_int2str(ch);
"please choose another one."), WARN_MSG(_("The key '%s' is already used for %s. "
"Choose another one."),
keystr,
keys_get_label(action)); keys_get_label(action));
mem_free(keystr);
werase(kwin.inner); werase(kwin.inner);
nbrowelm = nbrowelm =
print_keys_bindings(kwin.inner, print_keys_bindings(kwin.inner,

View File

@ -214,29 +214,22 @@ int keys_wgetch(WINDOW *win)
int ch, i; int ch, i;
char buf[UTF8_MAXLEN]; char buf[UTF8_MAXLEN];
ch = wgetch(win); /* Handle curses pseudo characters. */
if ((ch = wgetch(win)) >= KEY_MIN)
if (ch > 255) {
if (ch == KEY_UP || ch == KEY_DOWN || ch == KEY_LEFT ||
ch == KEY_RIGHT || ch == KEY_HOME || ch == KEY_END) {
return ch; return ch;
}
return -1;
}
if (UTF8_ISMULTI(ch) && !UTF8_ISCONT(ch)) { /* Handle 1-byte UTF-8 characters. */
if (UTF8_LENGTH(ch) == 1)
return ch;
/*
* Map multibyte UTF-8 characters to code point values
* and add KEY_MAX to avoid the curses range.
*/
buf[0] = ch; buf[0] = ch;
for (i = 1; i < UTF8_LENGTH(ch); i++) { for (i = 1; i < UTF8_LENGTH(buf[0]); i++)
ch = wgetch(win); buf[i] = wgetch(win);
if (!UTF8_ISCONT(ch)) return utf8_ord(buf) + KEY_MAX;
return -1;
buf[i] = ch;
}
return utf8_ord(buf);
} else {
return ch;
}
} }
void keys_wait_for_any_key(WINDOW *win) void keys_wait_for_any_key(WINDOW *win)
@ -294,19 +287,22 @@ static void add_key_str(enum key action, int key)
int keys_assign_binding(int key, enum key action) int keys_assign_binding(int key, enum key action)
{ {
if (key < 0 || actions[key] != KEY_UNDEF) { if (key < 0)
return 1;
if (key > KEY_MAX) {
llist_item_t *i = LLIST_FIND_FIRST(&actions_ext, &key, key_ext_hasch);
if (i)
return 1; return 1;
} else if (key > MAXKEYVAL) {
struct key_ext *k = mem_malloc(sizeof(struct key_ext)); struct key_ext *k = mem_malloc(sizeof(struct key_ext));
k->ch = key; k->ch = key;
k->action = action; k->action = action;
LLIST_ADD(&actions_ext, k); LLIST_ADD(&actions_ext, k);
} else { } else {
if (actions[key] != KEY_UNDEF)
return 1;
actions[key] = action; actions[key] = action;
} }
add_key_str(action, key); add_key_str(action, key);
return 0; return 0;
} }
@ -362,7 +358,7 @@ int keys_str2int(const char *key)
else if (starts_with(key, "C-")) else if (starts_with(key, "C-"))
return CTRL((int)key[strlen("C-")]); return CTRL((int)key[strlen("C-")]);
else if (starts_with(key, "U+")) else if (starts_with(key, "U+"))
return strtol(&key[2], NULL, 16); return strtol(&key[2], NULL, 16) + KEY_MAX;
else if (!strcmp(key, "TAB")) else if (!strcmp(key, "TAB"))
return TAB; return TAB;
else if (!strcmp(key, "ESC")) else if (!strcmp(key, "ESC"))
@ -387,6 +383,7 @@ int keys_str2int(const char *key)
char *keys_int2str(int key) char *keys_int2str(int key)
{ {
const char *ch;
char *res; char *res;
switch (key) { switch (key) {
@ -409,13 +406,10 @@ char *keys_int2str(int key)
case KEY_END: case KEY_END:
return strdup("KEY_END"); return strdup("KEY_END");
} }
if ((ch = keyname(key)))
if (key >= 0x80) { return mem_strdup(ch);
asprintf(&res, "U+%04X", key); asprintf(&res, "U+%04X", key - KEY_MAX);
return res; return res;
} else {
return strdup((char *)keyname(key));
}
} }
int keys_action_count_keys(enum key action) int keys_action_count_keys(enum key action)