Added SILC Thread Queue API
[crypto.git] / apps / irssi / src / fe-common / core / keyboard.c
index 3c0efade7b5d47de73529de8fcecf46e1df03f59..717bed1f6248ab6602559dc4b0dbc0f9d4c84d9e 100644 (file)
@@ -44,7 +44,7 @@ static char used_keys[256];
 static GTree *key_states;
 static int key_config_frozen;
 
-struct KEYBOARD_REC {
+struct _KEYBOARD_REC {
        char *key_state; /* the ongoing key combo */
         void *gui_data; /* GUI specific data sent in "key pressed" signal */
 };
@@ -193,7 +193,7 @@ static int expand_combo(const char *start, const char *end, GSList **out)
         KEY_REC *rec;
        KEYINFO_REC *info;
         GSList *tmp, *tmp2, *list, *copy, *newout;
-       char *str;
+       char *str, *p;
 
        if (start == end) {
                /* single key */
@@ -214,10 +214,16 @@ static int expand_combo(const char *start, const char *end, GSList **out)
                if (strcmp(rec->data, str) == 0)
                         list = g_slist_append(list, rec);
        }
-       g_free(str);
 
-       if (list == NULL)
-               return FALSE;
+       if (list == NULL) {
+               /* unknown keycombo - add it as-is, maybe the GUI will
+                  feed it to us as such */
+               for (p = str; *p != '\0'; p++)
+                       expand_out_char(*out, *p);
+               g_free(str);
+               return TRUE;
+       }
+       g_free(str);
 
        if (list->next == NULL) {
                 /* only one way to generate the combo, good */
@@ -382,6 +388,8 @@ static void key_configure_destroy(KEY_REC *rec)
        rec->info->keys = g_slist_remove(rec->info->keys, rec);
        g_hash_table_remove(keys, rec->key);
 
+       signal_emit("key destroyed", 1, rec);
+
        if (!key_config_frozen)
                 key_states_rescan();
 
@@ -415,6 +423,8 @@ static void key_configure_create(const char *id, const char *key,
        info->keys = g_slist_append(info->keys, rec);
        g_hash_table_insert(keys, rec->key, rec);
 
+       signal_emit("key created", 1, rec);
+
        if (!key_config_frozen)
                 key_states_rescan();
 }
@@ -541,8 +551,6 @@ static int key_states_search(const unsigned char *combo,
         return 0;
 }
 
-/* Returns TRUE if key press was consumed. Control characters should be sent
-   as "^@" .. "^_" instead of #0..#31 chars, #127 should be sent as ^? */
 int key_pressed(KEYBOARD_REC *keyboard, const char *key)
 {
        KEY_REC *rec;
@@ -555,7 +563,7 @@ int key_pressed(KEYBOARD_REC *keyboard, const char *key)
        if (keyboard->key_state == NULL && key[1] == '\0' &&
            !used_keys[(int) (unsigned char) key[0]]) {
                /* fast check - key not used */
-               return FALSE;
+               return -1;
        }
 
         first_key = keyboard->key_state == NULL;
@@ -563,6 +571,9 @@ int key_pressed(KEYBOARD_REC *keyboard, const char *key)
                 g_strconcat(keyboard->key_state, "-", key, NULL);
        g_free_and_null(keyboard->key_state);
 
+#if GLIB_MAJOR_VERSION == 2
+#  define GSearchFunc GCompareFunc
+#endif
        rec = g_tree_search(key_states,
                            (GSearchFunc) key_states_search,
                            combo);
@@ -570,13 +581,13 @@ int key_pressed(KEYBOARD_REC *keyboard, const char *key)
                /* unknown key combo, eat the invalid key
                   unless it was the first key pressed */
                 g_free(combo);
-               return !first_key;
+               return first_key ? -1 : 1;
        }
 
        if (g_tree_lookup(key_states, combo) != rec) {
                /* key combo continues.. */
                keyboard->key_state = combo;
-                return TRUE;
+                return 0;
        }
 
         /* finished key combo, execute */
@@ -584,7 +595,7 @@ int key_pressed(KEYBOARD_REC *keyboard, const char *key)
        consumed = key_emit_signal(keyboard, rec);
 
        /* never consume non-control characters */
-       return consumed;
+       return consumed ? 1 : -1;
 }
 
 void keyboard_entry_redirect(SIGNAL_FUNC func, const char *entry,
@@ -642,6 +653,8 @@ static void cmd_show_keys(const char *searchkey, int full)
        GSList *info, *key;
         int len;
 
+       printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_BIND_HEADER);
+
        len = searchkey == NULL ? 0 : strlen(searchkey);
        for (info = keyinfos; info != NULL; info = info->next) {
                KEYINFO_REC *rec = info->data;
@@ -651,11 +664,13 @@ static void cmd_show_keys(const char *searchkey, int full)
 
                        if ((len == 0 || g_strncasecmp(rec->key, searchkey, len) == 0) &&
                            (!full || rec->key[len] == '\0')) {
-                               printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_BIND_KEY,
+                               printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_BIND_LIST,
                                            rec->key, rec->info->id, rec->data == NULL ? "" : rec->data);
                        }
                }
        }
+
+       printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_BIND_FOOTER);
 }
 
 /* SYNTAX: BIND [-delete] [<key> [<command> [<data>]]] */
@@ -833,6 +848,11 @@ void keyboard_init(void)
 
 void keyboard_deinit(void)
 {
+       key_unbind("command", (SIGNAL_FUNC) sig_command);
+       key_unbind("key", (SIGNAL_FUNC) sig_key);
+       key_unbind("multi", (SIGNAL_FUNC) sig_multi);
+       key_unbind("nothing", (SIGNAL_FUNC) sig_nothing);
+
        while (keyinfos != NULL)
                keyinfo_remove(keyinfos->data);
        g_hash_table_destroy(keys);