mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
This commit is contained in:
commit
c5005ceeb3
@ -285,16 +285,27 @@ select_button_by_flag(struct dialog_data *dlg_data, int flag)
|
|||||||
static void
|
static void
|
||||||
select_button_by_key(struct dialog_data *dlg_data)
|
select_button_by_key(struct dialog_data *dlg_data)
|
||||||
{
|
{
|
||||||
unsigned char key;
|
term_event_char_T key;
|
||||||
|
#ifdef CONFIG_UTF_8
|
||||||
|
int codepage;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct widget_data *widget_data;
|
struct widget_data *widget_data;
|
||||||
struct term_event *ev = dlg_data->term_event;
|
struct term_event *ev = dlg_data->term_event;
|
||||||
|
|
||||||
if (!check_kbd_label_key(ev)) return;
|
if (!check_kbd_label_key(ev)) return;
|
||||||
|
|
||||||
|
#ifdef CONFIG_UTF_8
|
||||||
|
key = unicode_fold_label_case(get_kbd_key(ev));
|
||||||
|
codepage = get_opt_codepage_tree(dlg_data->win->term->spec, "charset");
|
||||||
|
#else
|
||||||
key = toupper(get_kbd_key(ev));
|
key = toupper(get_kbd_key(ev));
|
||||||
|
#endif
|
||||||
|
|
||||||
foreach_widget(dlg_data, widget_data) {
|
foreach_widget(dlg_data, widget_data) {
|
||||||
int hk_pos;
|
int hk_pos;
|
||||||
|
unsigned char *hk_ptr;
|
||||||
|
term_event_char_T hk_char;
|
||||||
|
|
||||||
if (widget_data->widget->type != WIDGET_BUTTON)
|
if (widget_data->widget->type != WIDGET_BUTTON)
|
||||||
continue;
|
continue;
|
||||||
@ -303,16 +314,23 @@ select_button_by_key(struct dialog_data *dlg_data)
|
|||||||
* one else we fallback to first character in button
|
* one else we fallback to first character in button
|
||||||
* name. */
|
* name. */
|
||||||
hk_pos = widget_data->widget->info.button.hotkey_pos;
|
hk_pos = widget_data->widget->info.button.hotkey_pos;
|
||||||
if (hk_pos >= 0) {
|
if (hk_pos >= 0)
|
||||||
if (toupper(widget_data->widget->text[hk_pos + 1]) != key)
|
hk_ptr = &widget_data->widget->text[hk_pos + 1];
|
||||||
continue;
|
else
|
||||||
} else {
|
hk_ptr = widget_data->widget->text;
|
||||||
if (toupper(widget_data->widget->text[0]) != key)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
select_dlg_item(dlg_data, widget_data);
|
#ifdef CONFIG_UTF_8
|
||||||
break;
|
hk_char = cp_to_unicode(codepage, &hk_ptr,
|
||||||
|
strchr(hk_ptr, '\0'));
|
||||||
|
hk_char = unicode_fold_label_case(hk_char);
|
||||||
|
#else
|
||||||
|
hk_char = toupper(*hk_ptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (hk_char == key) {
|
||||||
|
select_dlg_item(dlg_data, widget_data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,10 +122,15 @@ refresh_hotkeys(struct terminal *term, struct menu *menu)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
check_hotkeys_common(struct menu *menu, unsigned char hotkey, struct terminal *term,
|
check_hotkeys_common(struct menu *menu, term_event_char_T hotkey, struct terminal *term,
|
||||||
int check_mode)
|
int check_mode)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_UTF_8
|
||||||
|
unicode_val_T key = unicode_fold_label_case(hotkey);
|
||||||
|
int codepage = get_opt_codepage_tree(term->spec, "charset");
|
||||||
|
#else
|
||||||
unsigned char key = toupper(hotkey);
|
unsigned char key = toupper(hotkey);
|
||||||
|
#endif
|
||||||
int i = menu->selected;
|
int i = menu->selected;
|
||||||
int start;
|
int start;
|
||||||
|
|
||||||
@ -138,6 +143,9 @@ check_hotkeys_common(struct menu *menu, unsigned char hotkey, struct terminal *t
|
|||||||
do {
|
do {
|
||||||
struct menu_item *item;
|
struct menu_item *item;
|
||||||
unsigned char *text;
|
unsigned char *text;
|
||||||
|
#ifdef CONFIG_UTF_8
|
||||||
|
unicode_val_T items_hotkey;
|
||||||
|
#endif
|
||||||
int found;
|
int found;
|
||||||
|
|
||||||
if (++i == menu->size) i = 0;
|
if (++i == menu->size) i = 0;
|
||||||
@ -150,6 +158,8 @@ check_hotkeys_common(struct menu *menu, unsigned char hotkey, struct terminal *t
|
|||||||
if (mi_text_translate(item)) text = _(text, term);
|
if (mi_text_translate(item)) text = _(text, term);
|
||||||
if (!text || !*text) continue;
|
if (!text || !*text) continue;
|
||||||
|
|
||||||
|
/* Change @text to point to the character that should
|
||||||
|
* be compared to @key. */
|
||||||
if (check_mode == 0) {
|
if (check_mode == 0) {
|
||||||
/* Does the key (upcased) matches one of the
|
/* Does the key (upcased) matches one of the
|
||||||
* hotkeys in menu ? */
|
* hotkeys in menu ? */
|
||||||
@ -158,14 +168,22 @@ check_hotkeys_common(struct menu *menu, unsigned char hotkey, struct terminal *t
|
|||||||
#ifdef CONFIG_DEBUG
|
#ifdef CONFIG_DEBUG
|
||||||
if (key_pos < 0) key_pos = -key_pos;
|
if (key_pos < 0) key_pos = -key_pos;
|
||||||
#endif
|
#endif
|
||||||
found = (key_pos && (toupper(text[key_pos]) == key));
|
if (!key_pos) continue;
|
||||||
|
text += key_pos;
|
||||||
} else {
|
} else {
|
||||||
/* Does the key (upcased) matches first letter
|
/* Does the key (upcased) matches first letter
|
||||||
* of menu item left text ? */
|
* of menu item left text ? */
|
||||||
found = (toupper(*text) == key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Compare @key to the character to which @text points. */
|
||||||
|
#ifdef CONFIG_UTF_8
|
||||||
|
items_hotkey = cp_to_unicode(codepage, &text,
|
||||||
|
strchr(text, '\0'));
|
||||||
|
found = (unicode_fold_label_case(items_hotkey) == key);
|
||||||
|
#else
|
||||||
|
found = (toupper(*text) == key);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
menu->selected = i;
|
menu->selected = i;
|
||||||
return 1;
|
return 1;
|
||||||
@ -178,7 +196,7 @@ check_hotkeys_common(struct menu *menu, unsigned char hotkey, struct terminal *t
|
|||||||
|
|
||||||
/* Returns true if a hotkey was found in the menu, and set menu->selected. */
|
/* Returns true if a hotkey was found in the menu, and set menu->selected. */
|
||||||
int
|
int
|
||||||
check_hotkeys(struct menu *menu, unsigned char key, struct terminal *term)
|
check_hotkeys(struct menu *menu, term_event_char_T key, struct terminal *term)
|
||||||
{
|
{
|
||||||
return check_hotkeys_common(menu, key, term, 0);
|
return check_hotkeys_common(menu, key, term, 0);
|
||||||
}
|
}
|
||||||
@ -188,7 +206,7 @@ check_hotkeys(struct menu *menu, unsigned char key, struct terminal *term)
|
|||||||
* to selected entry.
|
* to selected entry.
|
||||||
* It returns 1 if found and set menu->selected. */
|
* It returns 1 if found and set menu->selected. */
|
||||||
int
|
int
|
||||||
check_not_so_hot_keys(struct menu *menu, unsigned char key, struct terminal *term)
|
check_not_so_hot_keys(struct menu *menu, term_event_char_T key, struct terminal *term)
|
||||||
{
|
{
|
||||||
return check_hotkeys_common(menu, key, term, 1);
|
return check_hotkeys_common(menu, key, term, 1);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
#ifndef EL__BFU_HOTKEY_H
|
#ifndef EL__BFU_HOTKEY_H
|
||||||
#define EL__BFU_HOTKEY_H
|
#define EL__BFU_HOTKEY_H
|
||||||
|
|
||||||
|
#include "terminal/kbd.h"
|
||||||
|
|
||||||
struct menu;
|
struct menu;
|
||||||
struct terminal;
|
struct terminal;
|
||||||
|
|
||||||
@ -13,7 +15,7 @@ void clear_hotkeys_cache(struct menu *menu);
|
|||||||
#endif
|
#endif
|
||||||
void refresh_hotkeys(struct terminal *term, struct menu *menu);
|
void refresh_hotkeys(struct terminal *term, struct menu *menu);
|
||||||
/* int is_hotkey(struct menu_item *item, unsigned char key, struct terminal *term); */
|
/* int is_hotkey(struct menu_item *item, unsigned char key, struct terminal *term); */
|
||||||
int check_hotkeys(struct menu *menu, unsigned char hotkey, struct terminal *term);
|
int check_hotkeys(struct menu *menu, term_event_char_T hotkey, struct terminal *term);
|
||||||
int check_not_so_hot_keys(struct menu *menu, unsigned char key, struct terminal *term);
|
int check_not_so_hot_keys(struct menu *menu, term_event_char_T key, struct terminal *term);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -408,8 +408,7 @@ unicode_to_cell(unicode_val_T c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Fold the case of a Unicode character, so that hotkeys in labels can
|
/* Fold the case of a Unicode character, so that hotkeys in labels can
|
||||||
* be compared case-insensitively. This should be called only if
|
* be compared case-insensitively. It is unspecified whether the
|
||||||
* check_kbd_label_key(c) is true. It is unspecified whether the
|
|
||||||
* result will be in upper or lower case. */
|
* result will be in upper or lower case. */
|
||||||
unicode_val_T
|
unicode_val_T
|
||||||
unicode_fold_label_case(unicode_val_T c)
|
unicode_fold_label_case(unicode_val_T c)
|
||||||
@ -522,6 +521,25 @@ cp2utf_8(int from, int c)
|
|||||||
return encode_utf_8(cp2u_shared(&codepages[from], c));
|
return encode_utf_8(cp2u_shared(&codepages[from], c));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_UTF_8
|
||||||
|
unicode_val_T
|
||||||
|
cp_to_unicode(int codepage, unsigned char **string, unsigned char *end)
|
||||||
|
{
|
||||||
|
if (is_cp_utf8(codepage))
|
||||||
|
return utf_8_to_unicode(string, end);
|
||||||
|
else {
|
||||||
|
if (*string >= end)
|
||||||
|
return UCS_NO_CHAR;
|
||||||
|
else {
|
||||||
|
unicode_val_T ret = cp2u(codepage, **string);
|
||||||
|
++*string;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_UTF_8 */
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_utf_8(struct conv_table *ct, unicode_val_T u, unsigned char *str)
|
add_utf_8(struct conv_table *ct, unicode_val_T u, unsigned char *str)
|
||||||
{
|
{
|
||||||
|
@ -65,6 +65,7 @@ inline int unicode_to_cell(unicode_val_T);
|
|||||||
unicode_val_T unicode_fold_label_case(unicode_val_T);
|
unicode_val_T unicode_fold_label_case(unicode_val_T);
|
||||||
inline int strlen_utf8(unsigned char **);
|
inline int strlen_utf8(unsigned char **);
|
||||||
inline unicode_val_T utf_8_to_unicode(unsigned char **, unsigned char *);
|
inline unicode_val_T utf_8_to_unicode(unsigned char **, unsigned char *);
|
||||||
|
unicode_val_T cp_to_unicode(int, unsigned char **, unsigned char *);
|
||||||
#endif /* CONFIG_UTF_8 */
|
#endif /* CONFIG_UTF_8 */
|
||||||
|
|
||||||
unicode_val_T cp2u(int, unsigned char);
|
unicode_val_T cp2u(int, unsigned char);
|
||||||
|
@ -170,17 +170,7 @@ void in_term(struct terminal *);
|
|||||||
#define check_kbd_modifier(event, mod) (kbd_modifier_is(&(event)->info.keyboard, (mod)))
|
#define check_kbd_modifier(event, mod) (kbd_modifier_is(&(event)->info.keyboard, (mod)))
|
||||||
|
|
||||||
#define check_kbd_textinput_key(event) (get_kbd_key(event) >= ' ' && check_kbd_modifier(event, KBD_MOD_NONE))
|
#define check_kbd_textinput_key(event) (get_kbd_key(event) >= ' ' && check_kbd_modifier(event, KBD_MOD_NONE))
|
||||||
#ifdef CONFIG_UTF_8
|
|
||||||
/* We must currently limit hotkeys of labels to ASCII, because
|
|
||||||
* get_kbd_key(event) is in UCS-4 and various event handlers pass it
|
|
||||||
* to toupper() if check_kbd_label_key() returns true.
|
|
||||||
* TO DO: Change the event handlers to use unicode_fold_label_case()
|
|
||||||
* instead. The code that extracts the hotkey from the label string
|
|
||||||
* will also have to be changed. */
|
|
||||||
#define check_kbd_label_key(event) (get_kbd_key(event) > ' ' && get_kbd_key(event) <= 0x7F && (check_kbd_modifier(event, KBD_MOD_NONE) || check_kbd_modifier(event, KBD_MOD_ALT)))
|
|
||||||
#else /* !CONFIG_UTF_8 */
|
|
||||||
#define check_kbd_label_key(event) (get_kbd_key(event) > ' ' && (check_kbd_modifier(event, KBD_MOD_NONE) || check_kbd_modifier(event, KBD_MOD_ALT)))
|
#define check_kbd_label_key(event) (get_kbd_key(event) > ' ' && (check_kbd_modifier(event, KBD_MOD_NONE) || check_kbd_modifier(event, KBD_MOD_ALT)))
|
||||||
#endif /* !CONFIG_UTF_8 */
|
|
||||||
|
|
||||||
|
|
||||||
/* For mouse events handling */
|
/* For mouse events handling */
|
||||||
|
@ -1,13 +1,25 @@
|
|||||||
#ifndef EL__TERMINAL_KBD_H
|
#ifndef EL__TERMINAL_KBD_H
|
||||||
#define EL__TERMINAL_KBD_H
|
#define EL__TERMINAL_KBD_H
|
||||||
|
|
||||||
|
#include "intl/charsets.h"
|
||||||
|
|
||||||
struct itrm;
|
struct itrm;
|
||||||
|
|
||||||
/* Values <= -0x100 are special; from enum term_event_special_key.
|
/* A character received from a terminal. */
|
||||||
|
#ifdef CONFIG_UTF_8
|
||||||
|
typedef unicode_val_T term_event_char_T; /* in UCS-4 */
|
||||||
|
#else
|
||||||
|
typedef unsigned char term_event_char_T; /* in the charset of the terminal */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* A key received from a terminal, without modifiers. The value is
|
||||||
|
* either from term_event_char_T or from enum term_event_special_key.
|
||||||
|
* To check which one it is, use is_kbd_character().
|
||||||
|
*
|
||||||
|
* Values <= -0x100 are special; from enum term_event_special_key.
|
||||||
* Values between -0xFF and -2 are not used yet; treat as special.
|
* Values between -0xFF and -2 are not used yet; treat as special.
|
||||||
* Value == -1 is KBD_UNDEF; not sent via socket.
|
* Value == -1 is KBD_UNDEF; not sent via socket.
|
||||||
* Values >= 0 are characters received from the terminal;
|
* Values >= 0 are characters; from term_event_char_T.
|
||||||
* in UCS-4 #ifdef CONFIG_UTF_8. Test with is_kbd_character().
|
|
||||||
*
|
*
|
||||||
* Any at least 32-bit signed integer type would work here; using an
|
* Any at least 32-bit signed integer type would work here; using an
|
||||||
* exact-width type hurts portability in principle, but some other
|
* exact-width type hurts portability in principle, but some other
|
||||||
@ -23,13 +35,24 @@ typedef enum {
|
|||||||
KBD_MOD_ALT = 4
|
KBD_MOD_ALT = 4
|
||||||
} term_event_modifier_T;
|
} term_event_modifier_T;
|
||||||
|
|
||||||
|
/* A key received from a terminal, with modifiers. */
|
||||||
struct term_event_keyboard {
|
struct term_event_keyboard {
|
||||||
term_event_key_T key;
|
term_event_key_T key;
|
||||||
term_event_modifier_T modifier;
|
term_event_modifier_T modifier;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Like struct term_event_keyboard but used in the interlink protocol
|
||||||
|
* between ELinks processes. Because the processes may be running
|
||||||
|
* different versions of ELinks, especially if a new version has just
|
||||||
|
* been installed, this structure should be kept binary compatible as
|
||||||
|
* long as possible. See bug 793 for a list of pending changes to the
|
||||||
|
* protocol. */
|
||||||
struct interlink_event_keyboard {
|
struct interlink_event_keyboard {
|
||||||
/* Values <= -2 are not used, for ELinks 0.11 compatibility.
|
/* This is like term_event_key_T but carries individual bytes
|
||||||
|
* rather than entire characters, and uses different values
|
||||||
|
* for special keys.
|
||||||
|
*
|
||||||
|
* Values <= -2 are not used, for ELinks 0.11 compatibility.
|
||||||
* Value == -1 is KBD_UNDEF; not sent via socket.
|
* Value == -1 is KBD_UNDEF; not sent via socket.
|
||||||
* Values between 0 and 0xFF are bytes received from the terminal.
|
* Values between 0 and 0xFF are bytes received from the terminal.
|
||||||
* Values >= 0x100 are special; absolute values of constants
|
* Values >= 0x100 are special; absolute values of constants
|
||||||
@ -84,9 +107,10 @@ static inline int is_kbd_fkey(term_event_key_T key) { return key <= KBD_F1 && ke
|
|||||||
#define kbd_fkey_to_number(key) (KBD_F1 - (key) + 1)
|
#define kbd_fkey_to_number(key) (KBD_F1 - (key) + 1)
|
||||||
|
|
||||||
/* int is_kbd_character(term_event_key_T key);
|
/* int is_kbd_character(term_event_key_T key);
|
||||||
* Return true if @key is a character in some charset, rather than a
|
* Check whether @key is a character or a special key.
|
||||||
* special key. The character is not necessarily printable. As for
|
* Return true if @key is a character from term_event_char_T.
|
||||||
* which charset it is in, see the definition of term_event_key_T. */
|
* (The character is not necessarily printable.)
|
||||||
|
* Return false if @key is a special key from enum term_event_special_key. */
|
||||||
#define is_kbd_character(key) ((key) >= 0)
|
#define is_kbd_character(key) ((key) >= 0)
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user