diff options
-rw-r--r-- | doc/de/autogen/user/weechat_commands.txt | 3 | ||||
-rw-r--r-- | doc/en/autogen/user/weechat_commands.txt | 3 | ||||
-rw-r--r-- | doc/fr/autogen/user/weechat_commands.txt | 3 | ||||
-rw-r--r-- | doc/it/autogen/user/weechat_commands.txt | 3 | ||||
-rw-r--r-- | po/cs.po | 6 | ||||
-rw-r--r-- | po/de.po | 6 | ||||
-rw-r--r-- | po/es.po | 6 | ||||
-rw-r--r-- | po/fr.po | 12 | ||||
-rw-r--r-- | po/hu.po | 6 | ||||
-rw-r--r-- | po/it.po | 6 | ||||
-rw-r--r-- | po/pl.po | 6 | ||||
-rw-r--r-- | po/pt_BR.po | 6 | ||||
-rw-r--r-- | po/ru.po | 6 | ||||
-rw-r--r-- | po/weechat.pot | 6 | ||||
-rw-r--r-- | src/core/wee-command.c | 4 | ||||
-rw-r--r-- | src/gui/gui-key.c | 255 | ||||
-rw-r--r-- | src/gui/gui-key.h | 10 |
17 files changed, 217 insertions, 130 deletions
diff --git a/doc/de/autogen/user/weechat_commands.txt b/doc/de/autogen/user/weechat_commands.txt index 600633d10..5ba1df83e 100644 --- a/doc/de/autogen/user/weechat_commands.txt +++ b/doc/de/autogen/user/weechat_commands.txt @@ -357,7 +357,8 @@ When binding a command to a key, it is recommended to use key alt+k (or Esc then For context "mouse" (possible in context "cursor" too), key has format: "@area:key" where area can be: *: any area on screen - chat: chat area + chat: chat area (any buffer) + chat(xxx): char area for buffer with name "xxx" (full name including plugin) bar(*): any bar bar(xxx): bar "xxx" item(*): any bar item diff --git a/doc/en/autogen/user/weechat_commands.txt b/doc/en/autogen/user/weechat_commands.txt index 466bc80ad..cdb73b5e6 100644 --- a/doc/en/autogen/user/weechat_commands.txt +++ b/doc/en/autogen/user/weechat_commands.txt @@ -357,7 +357,8 @@ When binding a command to a key, it is recommended to use key alt+k (or Esc then For context "mouse" (possible in context "cursor" too), key has format: "@area:key" where area can be: *: any area on screen - chat: chat area + chat: chat area (any buffer) + chat(xxx): char area for buffer with name "xxx" (full name including plugin) bar(*): any bar bar(xxx): bar "xxx" item(*): any bar item diff --git a/doc/fr/autogen/user/weechat_commands.txt b/doc/fr/autogen/user/weechat_commands.txt index 3d8c69ab6..90af566c5 100644 --- a/doc/fr/autogen/user/weechat_commands.txt +++ b/doc/fr/autogen/user/weechat_commands.txt @@ -357,7 +357,8 @@ Lors de l'association d'une commande à une touche, il est recommandé d'utilise Pour le contexte "mouse" (possible aussi pour le contexte "cursor"), la touche a le format: "@zone:touche" où la zone peut être : *: n'importe quelle zone à l'écran - chat: la zone de discussion + chat: la zone de discussion (n'importe quel tampon) + chat(xxx): la zone de discussion pour le tampon avec le nom "xxx" (nom complet incluant l'extension) bar(*): n'importe quelle barre bar(xxx): la barre "xxx" item(*): n'importe quel objet de barre diff --git a/doc/it/autogen/user/weechat_commands.txt b/doc/it/autogen/user/weechat_commands.txt index 61e46e257..5e3cc722e 100644 --- a/doc/it/autogen/user/weechat_commands.txt +++ b/doc/it/autogen/user/weechat_commands.txt @@ -357,7 +357,8 @@ When binding a command to a key, it is recommended to use key alt+k (or Esc then For context "mouse" (possible in context "cursor" too), key has format: "@area:key" where area can be: *: any area on screen - chat: chat area + chat: chat area (any buffer) + chat(xxx): char area for buffer with name "xxx" (full name including plugin) bar(*): any bar bar(xxx): bar "xxx" item(*): any bar item @@ -20,7 +20,7 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.6-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2011-08-07 11:20+0200\n" +"POT-Creation-Date: 2011-08-08 11:19+0200\n" "PO-Revision-Date: 2011-07-05 15:37+0200\n" "Last-Translator: Jiri Golembiovsky <golemj@gmail.com>\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" @@ -1457,7 +1457,9 @@ msgid "" "For context \"mouse\" (possible in context \"cursor\" too), key has format: " "\"@area:key\" where area can be:\n" " *: any area on screen\n" -" chat: chat area\n" +" chat: chat area (any buffer)\n" +" chat(xxx): char area for buffer with name \"xxx\" (full name including " +"plugin)\n" " bar(*): any bar\n" " bar(xxx): bar \"xxx\"\n" " item(*): any bar item\n" @@ -22,7 +22,7 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.6-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2011-08-07 11:20+0200\n" +"POT-Creation-Date: 2011-08-08 11:19+0200\n" "PO-Revision-Date: 2011-07-14 20:53+0100\n" "Last-Translator: Nils Görs\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" @@ -1508,7 +1508,9 @@ msgid "" "For context \"mouse\" (possible in context \"cursor\" too), key has format: " "\"@area:key\" where area can be:\n" " *: any area on screen\n" -" chat: chat area\n" +" chat: chat area (any buffer)\n" +" chat(xxx): char area for buffer with name \"xxx\" (full name including " +"plugin)\n" " bar(*): any bar\n" " bar(xxx): bar \"xxx\"\n" " item(*): any bar item\n" @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.6-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2011-08-07 11:20+0200\n" +"POT-Creation-Date: 2011-08-08 11:19+0200\n" "PO-Revision-Date: 2011-07-05 15:37+0200\n" "Last-Translator: Elián Hanisch <lambdae2@gmail.com>\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" @@ -1467,7 +1467,9 @@ msgid "" "For context \"mouse\" (possible in context \"cursor\" too), key has format: " "\"@area:key\" where area can be:\n" " *: any area on screen\n" -" chat: chat area\n" +" chat: chat area (any buffer)\n" +" chat(xxx): char area for buffer with name \"xxx\" (full name including " +"plugin)\n" " bar(*): any bar\n" " bar(xxx): bar \"xxx\"\n" " item(*): any bar item\n" @@ -21,8 +21,8 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.6-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2011-08-07 11:20+0200\n" -"PO-Revision-Date: 2011-08-07 11:20+0200\n" +"POT-Creation-Date: 2011-08-08 11:19+0200\n" +"PO-Revision-Date: 2011-08-08 11:20+0200\n" "Last-Translator: Sebastien Helleu <flashcode@flashtux.org>\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" "Language: French\n" @@ -1498,7 +1498,9 @@ msgid "" "For context \"mouse\" (possible in context \"cursor\" too), key has format: " "\"@area:key\" where area can be:\n" " *: any area on screen\n" -" chat: chat area\n" +" chat: chat area (any buffer)\n" +" chat(xxx): char area for buffer with name \"xxx\" (full name including " +"plugin)\n" " bar(*): any bar\n" " bar(xxx): bar \"xxx\"\n" " item(*): any bar item\n" @@ -1545,7 +1547,9 @@ msgstr "" "Pour le contexte \"mouse\" (possible aussi pour le contexte \"cursor\"), la " "touche a le format: \"@zone:touche\" où la zone peut être :\n" " *: n'importe quelle zone à l'écran\n" -" chat: la zone de discussion\n" +" chat: la zone de discussion (n'importe quel tampon)\n" +" chat(xxx): la zone de discussion pour le tampon avec le nom \"xxx\" (nom " +"complet incluant l'extension)\n" " bar(*): n'importe quelle barre\n" " bar(xxx): la barre \"xxx\"\n" " item(*): n'importe quel objet de barre\n" @@ -20,7 +20,7 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.6-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2011-08-07 11:20+0200\n" +"POT-Creation-Date: 2011-08-08 11:19+0200\n" "PO-Revision-Date: 2011-05-15 10:51+0200\n" "Last-Translator: Andras Voroskoi <voroskoi@frugalware.org>\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" @@ -1293,7 +1293,9 @@ msgid "" "For context \"mouse\" (possible in context \"cursor\" too), key has format: " "\"@area:key\" where area can be:\n" " *: any area on screen\n" -" chat: chat area\n" +" chat: chat area (any buffer)\n" +" chat(xxx): char area for buffer with name \"xxx\" (full name including " +"plugin)\n" " bar(*): any bar\n" " bar(xxx): bar \"xxx\"\n" " item(*): any bar item\n" @@ -20,7 +20,7 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.6-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2011-08-07 11:20+0200\n" +"POT-Creation-Date: 2011-08-08 11:19+0200\n" "PO-Revision-Date: 2011-07-16 11:32+0200\n" "Last-Translator: Marco Paolone <marcopaolone@gmail.com>\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" @@ -1473,7 +1473,9 @@ msgid "" "For context \"mouse\" (possible in context \"cursor\" too), key has format: " "\"@area:key\" where area can be:\n" " *: any area on screen\n" -" chat: chat area\n" +" chat: chat area (any buffer)\n" +" chat(xxx): char area for buffer with name \"xxx\" (full name including " +"plugin)\n" " bar(*): any bar\n" " bar(xxx): bar \"xxx\"\n" " item(*): any bar item\n" @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.6-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2011-08-07 11:20+0200\n" +"POT-Creation-Date: 2011-08-08 11:19+0200\n" "PO-Revision-Date: 2011-07-05 15:38+0200\n" "Last-Translator: Krzysztof Koroscik <soltys@szluug.org>\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" @@ -1471,7 +1471,9 @@ msgid "" "For context \"mouse\" (possible in context \"cursor\" too), key has format: " "\"@area:key\" where area can be:\n" " *: any area on screen\n" -" chat: chat area\n" +" chat: chat area (any buffer)\n" +" chat(xxx): char area for buffer with name \"xxx\" (full name including " +"plugin)\n" " bar(*): any bar\n" " bar(xxx): bar \"xxx\"\n" " item(*): any bar item\n" diff --git a/po/pt_BR.po b/po/pt_BR.po index e6c71e029..248654878 100644 --- a/po/pt_BR.po +++ b/po/pt_BR.po @@ -20,7 +20,7 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.6-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2011-08-07 11:20+0200\n" +"POT-Creation-Date: 2011-08-08 11:19+0200\n" "PO-Revision-Date: 2011-05-15 10:52+0200\n" "Last-Translator: Ivan Sichmann Freitas <ivansichfreitas@gmail.com>\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" @@ -1464,7 +1464,9 @@ msgid "" "For context \"mouse\" (possible in context \"cursor\" too), key has format: " "\"@area:key\" where area can be:\n" " *: any area on screen\n" -" chat: chat area\n" +" chat: chat area (any buffer)\n" +" chat(xxx): char area for buffer with name \"xxx\" (full name including " +"plugin)\n" " bar(*): any bar\n" " bar(xxx): bar \"xxx\"\n" " item(*): any bar item\n" @@ -20,7 +20,7 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.6-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2011-08-07 11:20+0200\n" +"POT-Creation-Date: 2011-08-08 11:19+0200\n" "PO-Revision-Date: 2011-05-15 10:52+0200\n" "Last-Translator: Pavel Shevchuk <stlwrt@gmail.com>\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" @@ -1301,7 +1301,9 @@ msgid "" "For context \"mouse\" (possible in context \"cursor\" too), key has format: " "\"@area:key\" where area can be:\n" " *: any area on screen\n" -" chat: chat area\n" +" chat: chat area (any buffer)\n" +" chat(xxx): char area for buffer with name \"xxx\" (full name including " +"plugin)\n" " bar(*): any bar\n" " bar(xxx): bar \"xxx\"\n" " item(*): any bar item\n" diff --git a/po/weechat.pot b/po/weechat.pot index dfb3f310b..b9ad20b39 100644 --- a/po/weechat.pot +++ b/po/weechat.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2011-08-07 11:20+0200\n" +"POT-Creation-Date: 2011-08-08 11:19+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -1145,7 +1145,9 @@ msgid "" "For context \"mouse\" (possible in context \"cursor\" too), key has format: " "\"@area:key\" where area can be:\n" " *: any area on screen\n" -" chat: chat area\n" +" chat: chat area (any buffer)\n" +" chat(xxx): char area for buffer with name \"xxx\" (full name including " +"plugin)\n" " bar(*): any bar\n" " bar(xxx): bar \"xxx\"\n" " item(*): any bar item\n" diff --git a/src/core/wee-command.c b/src/core/wee-command.c index 55bc34b79..1ed072476 100644 --- a/src/core/wee-command.c +++ b/src/core/wee-command.c @@ -5541,7 +5541,9 @@ command_init () "For context \"mouse\" (possible in context \"cursor\" " "too), key has format: \"@area:key\" where area can be:\n" " *: any area on screen\n" - " chat: chat area\n" + " chat: chat area (any buffer)\n" + " chat(xxx): char area for buffer with name \"xxx\" (full " + "name including plugin)\n" " bar(*): any bar\n" " bar(xxx): bar \"xxx\"\n" " item(*): any bar item\n" diff --git a/src/gui/gui-key.c b/src/gui/gui-key.c index 0506df7de..32a7879d4 100644 --- a/src/gui/gui-key.c +++ b/src/gui/gui-key.c @@ -65,6 +65,9 @@ int gui_default_keys_count[GUI_KEY_NUM_CONTEXTS]; /* default keys number */ char *gui_key_context_string[GUI_KEY_NUM_CONTEXTS] = { "default", "search", "cursor", "mouse" }; +char *gui_key_focus_string[GUI_KEY_NUM_FOCUS] = +{ "*", "chat", "bar", "item" }; + int gui_key_verbose = 0; /* 1 to see some messages */ char gui_key_combo_buffer[1024]; /* buffer used for combos */ @@ -621,63 +624,110 @@ gui_key_unbind (struct t_gui_buffer *buffer, int context, const char *key, */ int -gui_key_focus_matching (const char *key, +gui_key_focus_matching (int area_type, const char *area_name, + int focus_specific, int focus_any, struct t_gui_focus_info *focus_info) { - int match, area_chat; - char *area_bar, *area_item, *pos; + int match, match_any; + char buffer_full_name[512]; + + match_any = (strcmp (area_name, "*") == 0) ? 1 : 0; - if (key[1] == '*') + if (!focus_specific && !match_any) + return 0; + + if (!focus_any && match_any) + return 0; + + if (area_type == GUI_KEY_FOCUS_ANY) return 1; match = 0; - - pos = strchr (key, ':'); - if (pos) + + switch (area_type) { - area_chat = 0; - area_bar = NULL; - area_item = NULL; - if (strncmp (key + 1, "chat:", 5) == 0) - area_chat = 1; - else if (strncmp (key + 1, "bar(", 4) == 0) - { - area_bar = string_strndup (key + 5, pos - key - 6); - } - else if (strncmp (key + 1, "item(", 5) == 0) - { - area_item = string_strndup (key + 6, pos - key - 7); - } - if (area_chat || area_bar || area_item) - { - if (area_chat && focus_info->chat) + case GUI_KEY_FOCUS_ANY: + match = 1; + break; + case GUI_KEY_FOCUS_CHAT: + if (focus_info->chat && focus_info->window) { - match = 1; + snprintf (buffer_full_name, sizeof (buffer_full_name), "%s.%s", + gui_buffer_get_plugin_name ((focus_info->window)->buffer), + ((focus_info->window)->buffer)->name); + if (string_match (buffer_full_name, area_name, 0)) + { + match = 1; + } } - else if (area_bar && focus_info->bar_window - && ((strcmp (area_bar, "*") == 0) - || (strcmp (area_bar, (focus_info->bar_window)->bar->name) == 0))) + break; + case GUI_KEY_FOCUS_BAR: + if (focus_info->bar_window + && (string_match ((focus_info->bar_window)->bar->name, area_name, 0))) { match = 1; } - else if (area_item && focus_info->bar_item - && ((strcmp (area_item, "*") == 0) - || (strcmp (area_item, focus_info->bar_item) == 0))) + break; + case GUI_KEY_FOCUS_ITEM: + if (focus_info->bar_item + && (string_match (focus_info->bar_item, area_name, 0))) { match = 1; } - } - - if (area_bar) - free (area_bar); - if (area_item) - free (area_item); + break; + case GUI_KEY_NUM_FOCUS: + break; } return match; } /* + * gui_key_focus_get_area: get area focus (any, chat, bar or item) and name + */ + +void +gui_key_focus_get_area (const char *key, int *area_type, char **area_name) +{ + int i, length; + char *pos_end; + + *area_type = GUI_KEY_FOCUS_ANY; + *area_name = NULL; + + for (i = 0; i < GUI_KEY_NUM_FOCUS; i++) + { + length = strlen (gui_key_focus_string[i]); + if (strncmp (key + 1, gui_key_focus_string[i], length) == 0) + { + if (i == GUI_KEY_FOCUS_ANY) + { + *area_type = i; + *area_name = strdup ("*"); + return; + } + if (key[1 + length] == ':') + { + *area_type = i; + *area_name = strdup ("*"); + return; + } + if ((key[1 + length] == '(') && key[1 + length + 1]) + { + pos_end = strchr (key + 1 + length, ')'); + if (pos_end) + { + *area_type = i; + *area_name = string_strndup (key + 1 + length + 1, + pos_end - key - length - 2); + return; + } + } + } + } +} + +/* * gui_key_focus_command: run command according to focus * return 1 if a command was executed, otherwise 0 */ @@ -689,86 +739,85 @@ gui_key_focus_command (const char *key, int context, struct t_gui_focus_info *focus_info2) { struct t_gui_key *ptr_key; - int i, errors; - char *pos, *pos_joker, *command, **commands; + int i, errors, matching, area_type; + char *pos, *command, **commands, *area_name; struct t_hashtable *hashtable; for (ptr_key = gui_keys[context]; ptr_key; ptr_key = ptr_key->next_key) { - if (ptr_key->key && (ptr_key->key[0] == '@')) + if (ptr_key->key && (ptr_key->key[0] != '@')) + continue; + + pos = strchr (ptr_key->key, ':'); + if (!pos) + continue; + + if (gui_key_cmp (key, pos + 1, context) != 0) + continue; + + gui_key_focus_get_area (ptr_key->key, &area_type, &area_name); + if (!area_name) + continue; + + matching = gui_key_focus_matching (area_type, area_name, + focus_specific, focus_any, + focus_info1); + free (area_name); + + if (!matching) + continue; + + hashtable = hook_focus_get_data (focus_info1, + focus_info2, + key); + if (gui_cursor_debug || gui_mouse_debug) { - pos = strchr (ptr_key->key, ':'); - if (pos) + gui_chat_printf (NULL, "Hashtable focus: %s", + hashtable_get_string (hashtable, + "keys_values_sorted")); + } + command = string_replace_with_hashtable (ptr_key->command, + hashtable, + &errors); + if (command) + { + if (errors == 0) { - pos_joker = strchr (ptr_key->key, '*'); - if (!focus_specific && (!pos_joker || (pos_joker > pos))) - continue; - if (!focus_any && pos_joker && (pos_joker < pos)) - continue; - - pos++; - if (gui_key_cmp (key, pos, context) == 0) + if (gui_cursor_debug || gui_mouse_debug) + { + gui_chat_printf (NULL, + "Command executed: %s (%s)", + command, ptr_key->command); + } + if ((context == GUI_KEY_CONTEXT_CURSOR) && gui_cursor_debug) { - if (gui_key_focus_matching (ptr_key->key, focus_info1)) + gui_input_delete_line (gui_current_window->buffer); + } + commands = string_split_command (command, ';'); + if (commands) + { + for (i = 0; commands[i]; i++) { - hashtable = hook_focus_get_data (focus_info1, - focus_info2, - key); - if (gui_cursor_debug || gui_mouse_debug) - { - gui_chat_printf (NULL, "Hashtable focus: %s", - hashtable_get_string (hashtable, - "keys_values_sorted")); - } - command = string_replace_with_hashtable (ptr_key->command, - hashtable, - &errors); - if (command) - { - if (errors == 0) - { - if (gui_cursor_debug || gui_mouse_debug) - { - gui_chat_printf (NULL, - "Command executed: %s (%s)", - command, - ptr_key->command); - } - if ((context == GUI_KEY_CONTEXT_CURSOR) - && gui_cursor_debug) - { - gui_input_delete_line (gui_current_window->buffer); - } - commands = string_split_command (command, - ';'); - if (commands) - { - for (i = 0; commands[i]; i++) - { - input_data (gui_current_window->buffer, commands[i]); - } - string_free_split_command (commands); - } - } - else - { - if (gui_cursor_debug || gui_mouse_debug) - { - gui_chat_printf (NULL, - "Command NOT executed (%s)", - ptr_key->command); - } - } - free (command); - } - if (hashtable) - hashtable_free (hashtable); - return 1; + input_data (gui_current_window->buffer, commands[i]); } + string_free_split_command (commands); + } + } + else + { + if (gui_cursor_debug || gui_mouse_debug) + { + gui_chat_printf (NULL, + "Command NOT executed (%s)", + ptr_key->command); } } + free (command); } + if (hashtable) + hashtable_free (hashtable); + return 1; } return 0; diff --git a/src/gui/gui-key.h b/src/gui/gui-key.h index c1f3ffd1c..d6642f32f 100644 --- a/src/gui/gui-key.h +++ b/src/gui/gui-key.h @@ -34,6 +34,16 @@ enum t_gui_key_context GUI_KEY_NUM_CONTEXTS, }; +enum t_gui_key_focus +{ + GUI_KEY_FOCUS_ANY = 0, + GUI_KEY_FOCUS_CHAT, + GUI_KEY_FOCUS_BAR, + GUI_KEY_FOCUS_ITEM, + /* number of key focus */ + GUI_KEY_NUM_FOCUS, +}; + /* key structures */ struct t_gui_key |