diff --git a/src/intl/charsets.c b/src/intl/charsets.c index dc8d25e0..867bfdc9 100644 --- a/src/intl/charsets.c +++ b/src/intl/charsets.c @@ -495,7 +495,6 @@ cp2u_shared(const struct codepage_desc *from, unsigned char c) return UCS_NO_CHAR; } -#ifdef CONFIG_UTF_8 /* Slow algorithm, used for converting input from the terminal. */ unicode_val_T cp2u(int from, unsigned char c) @@ -510,7 +509,6 @@ cp2u(int from, unsigned char c) if (c < 0x80) return c; else return cp2u_shared(&codepages[from], c); } -#endif /* CONFIG_UTF_8 */ /* This slow and ugly code is used by the terminal utf_8_io */ unsigned char * diff --git a/src/intl/charsets.h b/src/intl/charsets.h index ae8fe97f..16bc8664 100644 --- a/src/intl/charsets.h +++ b/src/intl/charsets.h @@ -65,9 +65,9 @@ inline int unicode_to_cell(unicode_val_T); unicode_val_T unicode_fold_label_case(unicode_val_T); inline int strlen_utf8(unsigned char **); inline unicode_val_T utf_8_to_unicode(unsigned char **, unsigned char *); -unicode_val_T cp2u(int, unsigned char); #endif /* CONFIG_UTF_8 */ +unicode_val_T cp2u(int, unsigned char); unsigned char *cp2utf_8(int, int); unsigned char *u2cp_(unicode_val_T, int, int no_nbsp_hack); diff --git a/src/terminal/kbd.h b/src/terminal/kbd.h index 4bb25fc0..a4aeb153 100644 --- a/src/terminal/kbd.h +++ b/src/terminal/kbd.h @@ -61,6 +61,12 @@ static inline int is_kbd_fkey(term_event_key_T key) { return key <= KBD_F1 && ke #define KBD_CTRL_C (-0x200) +/* int is_kbd_character(term_event_key_T key); + * Return true if @key is a character in some charset, rather than a + * special key. The character is not necessarily printable. As for + * which charset it is in, see the definition of term_event_key_T. */ +#define is_kbd_character(key) ((key) >= 0) + /* Values for term_event_keyboard.modifier and * interlink_event_keyboard.modifier */ #define KBD_MOD_NONE 0 diff --git a/src/viewer/text/link.c b/src/viewer/text/link.c index 8042f5e0..99163fa1 100644 --- a/src/viewer/text/link.c +++ b/src/viewer/text/link.c @@ -1178,31 +1178,37 @@ enum frame_event_status try_document_key(struct session *ses, struct document_view *doc_view, struct term_event *ev) { - term_event_key_T key; + unicode_val_T key; int passed = -1; int i; /* GOD I HATE C! --FF */ /* YEAH, BRAINFUCK RULEZ! --pasky */ assert(ses && doc_view && doc_view->document && doc_view->vs && ev); if_assert_failed return FRAME_EVENT_IGNORED; - if (!check_kbd_modifier(ev, KBD_MOD_ALT)) { - /* We accept those only in alt-combo. */ + if (!check_kbd_modifier(ev, KBD_MOD_ALT) + || !is_kbd_character(get_kbd_key(ev))) { + /* We accept only alt-character combos. */ return FRAME_EVENT_IGNORED; } + /* The key is a character. Convert it to Unicode so that it + * can be compared with link.accesskey. */ +#ifdef CONFIG_UTF_8 + key = get_kbd_key(ev); +#else /* !CONFIG_UTF_8 */ + key = cp2u(get_opt_codepage_tree(ses->tab->term->spec, + "charset"), + get_kbd_key(ev)); +#endif /* !CONFIG_UTF_8 */ + /* If @key now is 0 (which is used in link.accesskey if there + * is no access key) or UCS_REPLACEMENT_CHARACTER, then the + * results may be a little odd, but not really harmful. */ + /* Run through all the links and see if one of them is bound to the * key we test.. */ - key = get_kbd_key(ev); - for (i = 0; i < doc_view->document->nlinks; i++) { struct link *link = &doc_view->document->links[i]; - /* FIXME: charset mismatch. @link->accesskey is always - * unicode_val_T; if CONFIG_UTF_8 is not defined, @key - * can be a byte from the charset of the terminal, in - * which case one of them should be converted for - * comparison. When implementing this, note that @key - * can also be a special key. */ if (key == link->accesskey) { if (passed != i && i <= doc_view->vs->current_link) { /* This is here in order to rotate between