From 8e22a16430b1fd09e2e2ff86f04c7274d414be3b Mon Sep 17 00:00:00 2001 From: Ilia Maslakov Date: Fri, 21 Jan 2011 21:36:29 +0000 Subject: [PATCH] Added lookup_key_by_code, now parameter is string. For example: "ctrl-w=action:code;action:code;action:code;" Signed-off-by: Ilia Maslakov Signed-off-by: Andrew Borodin --- lib/tty/key.c | 181 +++++++++++++++++++++++++++++++++++++++++++-------- lib/tty/key.h | 2 +- src/editor/editcmd.c | 38 ++++++----- 3 files changed, 175 insertions(+), 46 deletions(-) diff --git a/lib/tty/key.c b/lib/tty/key.c index a1d9619f4..90ba5a70a 100644 --- a/lib/tty/key.c +++ b/lib/tty/key.c @@ -251,6 +251,13 @@ typedef struct SelectList struct SelectList *next; } SelectList; +typedef enum KeySortType +{ + KEY_NOSORT = 0, + KEY_SORTBYNAME, + KEY_SORTBYCODE +} KeySortType; + #ifdef __QNXNTO__ typedef int (*ph_dv_f) (void *, void *); typedef int (*ph_ov_f) (void *); @@ -524,11 +531,11 @@ static Display *x11_display; static Window x11_window; #endif /* HAVE_TEXTMODE_X11_SUPPORT */ -static const size_t key_name_conv_tab_size = sizeof (key_name_conv_tab) / - sizeof (key_name_conv_tab[0]) - 1; +static KeySortType has_been_sorted = KEY_NOSORT; + +static const size_t key_conv_tab_size = G_N_ELEMENTS (key_name_conv_tab) - 1; -static const key_code_name_t *key_name_conv_tab_sorted[sizeof (key_name_conv_tab) / - sizeof (key_name_conv_tab[0]) - 1]; +static const key_code_name_t *key_conv_tab_sorted[G_N_ELEMENTS (key_name_conv_tab) - 1]; /*** file scope functions ************************************************************************/ /* --------------------------------------------------------------------------------------------- */ @@ -1144,7 +1151,7 @@ s_dispose (SelectList * sel) /* --------------------------------------------------------------------------------------------- */ static int -key_code_name_comparator (const void *p1, const void *p2) +key_code_comparator_by_name (const void *p1, const void *p2) { const key_code_name_t *n1 = *(const key_code_name_t **) p1; const key_code_name_t *n2 = *(const key_code_name_t **) p2; @@ -1154,21 +1161,37 @@ key_code_name_comparator (const void *p1, const void *p2) /* --------------------------------------------------------------------------------------------- */ -static inline void -sort_key_name_conv_tab (void) +static int +key_code_comparator_by_code (const void *p1, const void *p2) { - static gboolean has_been_sorted = FALSE; + const key_code_name_t *n1 = *(const key_code_name_t **) p1; + const key_code_name_t *n2 = *(const key_code_name_t **) p2; + + return n1->code - n2->code; +} + +/* --------------------------------------------------------------------------------------------- */ - if (!has_been_sorted) +static inline void +sort_key_conv_tab (enum KeySortType type_sort) +{ + if (has_been_sorted != type_sort) { size_t i; - for (i = 0; i < key_name_conv_tab_size; i++) - key_name_conv_tab_sorted[i] = &key_name_conv_tab[i]; + for (i = 0; i < key_conv_tab_size; i++) + key_conv_tab_sorted[i] = &key_name_conv_tab[i]; - qsort (key_name_conv_tab_sorted, - key_name_conv_tab_size, sizeof (key_name_conv_tab_sorted[0]), - &key_code_name_comparator); - has_been_sorted = TRUE; + if (type_sort == KEY_SORTBYNAME) + { + qsort (key_conv_tab_sorted, key_conv_tab_size, sizeof (key_conv_tab_sorted[0]), + &key_code_comparator_by_name); + } + else if (type_sort == KEY_SORTBYCODE) + { + qsort (key_conv_tab_sorted, key_conv_tab_size, sizeof (key_conv_tab_sorted[0]), + &key_code_comparator_by_code); + } + has_been_sorted = type_sort; } } @@ -1189,15 +1212,14 @@ lookup_keyname (const char *name, int *idx) return (int) name[0]; } - sort_key_name_conv_tab (); + sort_key_conv_tab (KEY_SORTBYNAME); - res = bsearch (&keyp, key_name_conv_tab_sorted, - key_name_conv_tab_size, - sizeof (key_name_conv_tab_sorted[0]), key_code_name_comparator); + res = bsearch (&keyp, key_conv_tab_sorted, key_conv_tab_size, + sizeof (key_conv_tab_sorted[0]), key_code_comparator_by_name); if (res != NULL) { - *idx = (int) (res - (key_code_name_t **) key_name_conv_tab_sorted); + *idx = (int) (res - (key_code_name_t **) key_conv_tab_sorted); return (*res)->code; } } @@ -1207,6 +1229,33 @@ lookup_keyname (const char *name, int *idx) } /* --------------------------------------------------------------------------------------------- */ + +static gboolean +lookup_keycode (const long code, int *idx) +{ + if (code != 0) + { + const key_code_name_t key = { code, NULL, NULL, NULL }; + const key_code_name_t *keyp = &key; + key_code_name_t **res; + + sort_key_conv_tab (KEY_SORTBYCODE); + + res = bsearch (&keyp, key_conv_tab_sorted, key_conv_tab_size, + sizeof (key_conv_tab_sorted[0]), key_code_comparator_by_code); + + if (res != NULL) + { + *idx = (int) (res - (key_code_name_t **) key_conv_tab_sorted); + return TRUE; + } + } + + *idx = -1; + return FALSE; +} + +/* --------------------------------------------------------------------------------------------- */ /*** public functions ****************************************************************************/ /* --------------------------------------------------------------------------------------------- */ /* This has to be called before init_slang or whatever routine @@ -1413,12 +1462,12 @@ lookup_key (const char *name, char **label) if (use_meta != -1) { - g_string_append (s, key_name_conv_tab_sorted[use_meta]->shortcut); + g_string_append (s, key_conv_tab_sorted[use_meta]->shortcut); g_string_append_c (s, '-'); } if (use_ctrl != -1) { - g_string_append (s, key_name_conv_tab_sorted[use_ctrl]->shortcut); + g_string_append (s, key_conv_tab_sorted[use_ctrl]->shortcut); g_string_append_c (s, '-'); } if (use_shift != -1) @@ -1427,21 +1476,21 @@ lookup_key (const char *name, char **label) g_string_append_c (s, (gchar) g_ascii_toupper ((gchar) k)); else { - g_string_append (s, key_name_conv_tab_sorted[use_shift]->shortcut); + g_string_append (s, key_conv_tab_sorted[use_shift]->shortcut); g_string_append_c (s, '-'); - g_string_append (s, key_name_conv_tab_sorted[lc_index]->shortcut); + g_string_append (s, key_conv_tab_sorted[lc_index]->shortcut); } } else if (k < 128) { if ((k >= 'A') || (lc_index < 0) - || (key_name_conv_tab_sorted[lc_index]->shortcut == NULL)) + || (key_conv_tab_sorted[lc_index]->shortcut == NULL)) g_string_append_c (s, (gchar) g_ascii_tolower ((gchar) k)); else - g_string_append (s, key_name_conv_tab_sorted[lc_index]->shortcut); + g_string_append (s, key_conv_tab_sorted[lc_index]->shortcut); } - else if ((lc_index != -1) && (key_name_conv_tab_sorted[lc_index]->shortcut != NULL)) - g_string_append (s, key_name_conv_tab_sorted[lc_index]->shortcut); + else if ((lc_index != -1) && (key_conv_tab_sorted[lc_index]->shortcut != NULL)) + g_string_append (s, key_conv_tab_sorted[lc_index]->shortcut); else g_string_append_c (s, (gchar) g_ascii_tolower ((gchar) key)); @@ -1471,6 +1520,82 @@ lookup_key (const char *name, char **label) } /* --------------------------------------------------------------------------------------------- */ + +char * +lookup_key_by_code (const int keycode) +{ + /* code without modifier */ + unsigned int k = keycode & ~KEY_M_MASK; + /* modifier */ + unsigned int mod = keycode & KEY_M_MASK; + + int use_meta = -1; + int use_ctrl = -1; + int use_shift = -1; + int key_idx = -1; + + GString *s; + int idx; + + s = g_string_sized_new (8); + + if (lookup_keycode (k, &key_idx) || (k > 0 && k < 256)) + { + if (mod & KEY_M_ALT) + { + if (lookup_keycode (KEY_M_ALT, &idx)) + { + use_meta = idx; + g_string_append (s, key_conv_tab_sorted[use_meta]->name); + g_string_append_c (s, '-'); + } + } + if (mod & KEY_M_CTRL) + { + /* non printeble chars like a CTRL-[A..Z] */ + if (k < 32) + k += 64; + + if (lookup_keycode (KEY_M_CTRL, &idx)) + { + use_ctrl = idx; + g_string_append (s, key_conv_tab_sorted[use_ctrl]->name); + g_string_append_c (s, '-'); + } + } + if (mod & KEY_M_SHIFT) + { + if (lookup_keycode (KEY_M_ALT, &idx)) + { + use_shift = idx; + if (k < 127) + g_string_append_c (s, (gchar) g_ascii_toupper ((gchar) k)); + else + { + g_string_append (s, key_conv_tab_sorted[use_shift]->name); + g_string_append_c (s, '-'); + g_string_append (s, key_conv_tab_sorted[key_idx]->name); + } + } + } + else if (k < 128) + { + if ((k >= 'A') || (key_idx < 0) + || (key_conv_tab_sorted[key_idx]->name == NULL)) + g_string_append_c (s, (gchar) k); + else + g_string_append (s, key_conv_tab_sorted[key_idx]->name); + } + else if ((key_idx != -1) && (key_conv_tab_sorted[key_idx]->name != NULL)) + g_string_append (s, key_conv_tab_sorted[key_idx]->name); + else + g_string_append_c (s, (gchar) keycode); + } + + return g_string_free (s, s->len == 0); +} + +/* --------------------------------------------------------------------------------------------- */ /** * Return TRUE on success, FALSE on error. * An error happens if SEQ is a beginning of an existing longer sequence. diff --git a/lib/tty/key.h b/lib/tty/key.h index 91b8290da..d1d4ab4cd 100644 --- a/lib/tty/key.h +++ b/lib/tty/key.h @@ -68,7 +68,7 @@ void init_key_input_fd (void); void done_key (void); long lookup_key (const char *name, char **label); - +char *lookup_key_by_code (const int keycode); /* mouse support */ int tty_get_event (struct Gpm_Event *event, gboolean redo_event, gboolean block); gboolean is_idle (void); diff --git a/src/editor/editcmd.c b/src/editor/editcmd.c index c7d05162e..14c9af622 100644 --- a/src/editor/editcmd.c +++ b/src/editor/editcmd.c @@ -1392,11 +1392,10 @@ edit_macro_comparator (gconstpointer *macro1, gconstpointer *macro2) /* --------------------------------------------------------------------------------------------- */ static void -edit_macro_sort_by_hotkey (WEdit *edit) +edit_macro_sort_by_hotkey (void) { - if (macros_list == NULL || macros_list->len == 0) - return; - g_array_sort (macros_list, (GCompareFunc) edit_macro_comparator); + if (macros_list != NULL && macros_list->len != 0) + g_array_sort (macros_list, (GCompareFunc) edit_macro_comparator); } /* --------------------------------------------------------------------------------------------- */ @@ -1407,6 +1406,9 @@ edit_get_macro (WEdit * edit, int hotkey, const macros_t **macros, guint *indx) const macros_t *array_start = &g_array_index (macros_list, struct macros_t, 0); macros_t *result; macros_t search_macro; + + (void) edit; + search_macro.hotkey = hotkey; result = bsearch (&search_macro, macros_list->data, macros_list->len, sizeof (macros_t), (GCompareFunc) edit_macro_comparator); @@ -1431,8 +1433,7 @@ edit_delete_macro (WEdit * edit, int hotkey) const char *section_name = "editor"; gchar *macros_fname; guint indx; - char keyname[8]; - + char *keyname; const macros_t *macros = NULL; /* clear array of actions for current hotkey */ @@ -1442,7 +1443,7 @@ edit_delete_macro (WEdit * edit, int hotkey) g_array_free (macros->macro, TRUE); macros = NULL; g_array_remove_index (macros_list, indx); - edit_macro_sort_by_hotkey (edit); + edit_macro_sort_by_hotkey (); } macros_fname = g_build_filename (mc_config_get_path (), MC_MACRO_FILE, NULL); @@ -1452,14 +1453,15 @@ edit_delete_macro (WEdit * edit, int hotkey) if (macros_config == NULL) return FALSE; - g_snprintf (keyname, sizeof (keyname), "%i", hotkey); - while (mc_config_del_key (macros_config, section_name, keyname)); + keyname = lookup_key_by_code (hotkey); + while (mc_config_del_key (macros_config, section_name, keyname)) + ; + g_free (keyname); mc_config_save_file (macros_config, NULL); mc_config_deinit (macros_config); return TRUE; } - /* --------------------------------------------------------------------------------------------- */ void @@ -1515,7 +1517,6 @@ edit_store_macro_cmd (WEdit * edit) { int i; int hotkey; - char keyname[8]; GString *marcros_string; mc_config_t *macros_config = NULL; const char *section_name = "editor"; @@ -1523,6 +1524,7 @@ edit_store_macro_cmd (WEdit * edit) GArray *macros; /* current macro */ int tmp_act; gboolean have_macro = FALSE; + char *keyname = NULL; hotkey = editcmd_dialog_raw_key_query (_("Save macro"), _("Press the macro's new hotkey:"), 1); if (hotkey == ESC_CHAR) @@ -1545,13 +1547,13 @@ edit_store_macro_cmd (WEdit * edit) if (macros_config == NULL) return FALSE; - g_snprintf (keyname, sizeof (keyname), "%i", hotkey); + edit_push_undo_action (edit, KEY_PRESS + edit->start_display); marcros_string = g_string_sized_new (250); + macros = g_array_new (TRUE, FALSE, sizeof (macro_action_t)); - edit_push_undo_action (edit, KEY_PRESS + edit->start_display); + keyname = lookup_key_by_code (hotkey); - macros = g_array_new (TRUE, FALSE, sizeof (macro_action_t)); for (i = 0; i < macro_index; i++) { macro_action_t m_act; @@ -1579,7 +1581,8 @@ edit_store_macro_cmd (WEdit * edit) else mc_config_del_key (macros_config, section_name, keyname); - edit_macro_sort_by_hotkey (edit); + g_free (keyname); + edit_macro_sort_by_hotkey (); g_string_free (marcros_string, TRUE); mc_config_save_file (macros_config, NULL); @@ -1658,8 +1661,9 @@ edit_load_macro_cmd (WEdit * edit) curr_values = values = mc_config_get_string_list (macros_config, section_name, *profile_keys, &values_len); - hotkey = strtol (*profile_keys, NULL, 0); + hotkey = lookup_key (*profile_keys, NULL); have_macro = FALSE; + while (*curr_values != NULL && *curr_values[0] != '\0') { char **macro_pair = NULL; @@ -1712,7 +1716,7 @@ edit_load_macro_cmd (WEdit * edit) } g_strfreev (keys); mc_config_deinit (macros_config); - edit_macro_sort_by_hotkey (edit); + edit_macro_sort_by_hotkey (); return TRUE; } -- 2.11.4.GIT