MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "module.h"
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 */
};
KEY_REC *rec;
KEYINFO_REC *info;
GSList *tmp, *tmp2, *list, *copy, *newout;
- char *str;
+ char *str, *p;
if (start == end) {
/* single key */
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 */
rec = list->data;
+ g_slist_free(list);
return expand_key(rec->key, out);
}
}
rec = list->data;
+ g_slist_free(list);
if (!expand_key(rec->key, out)) {
/* illegal key combo, remove from list */
expand_out_free(*out);
expand_out_char(*out, *key);
expand_out_char(*out, '-');
last_hyphen = FALSE; /* optional */
- } else if (last_hyphen && i_isalnum(*key) && !i_isdigit(*key)) {
+ } else if (last_hyphen && i_isalpha(*key)) {
/* possibly beginning of keycombo */
start = key;
last_hyphen = FALSE;
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();
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();
}
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;
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;
g_free_and_null(keyboard->key_state);
rec = g_tree_search(key_states,
- (GSearchFunc) key_states_search,
+ (GCompareFunc) key_states_search,
combo);
if (rec == NULL) {
/* 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 */
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,
g_strfreev(list);
}
+static void sig_nothing(const char *data)
+{
+}
+
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;
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>]]] */
+/* SYNTAX: BIND [-list] [-delete] [<key> [<command> [<data>]]] */
static void cmd_bind(const char *data)
{
GHashTable *optlist;
"bind", &optlist, &key, &id, &keydata))
return;
+ if (g_hash_table_lookup(optlist, "list")) {
+ GSList *tmp;
+
+ for (tmp = keyinfos; tmp != NULL; tmp = tmp->next) {
+ KEYINFO_REC *rec = tmp->data;
+
+ printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_BIND_COMMAND_LIST,
+ rec->id, rec->description ? rec->description : "");
+ }
+ cmd_params_free(free_arg);
+ return;
+ }
+
if (*key != '\0' && g_hash_table_lookup(optlist, "delete")) {
/* delete key */
key_configure_remove(key);
command_id = strchr(settings_get_str("cmdchars"), *id) != NULL;
if (command_id) {
/* using shortcut to command id */
- keydata = g_strconcat(id, " ", keydata, NULL);
+ keydata = g_strconcat(id+1, " ", keydata, NULL);
id = "command";
}
key_config_frozen = 0;
memset(used_keys, 0, sizeof(used_keys));
- key_bind("command", "Run any IRC command", NULL, NULL, (SIGNAL_FUNC) sig_command);
+ key_bind("command", "Run any command", NULL, NULL, (SIGNAL_FUNC) sig_command);
key_bind("key", "Specify name for key binding", NULL, NULL, (SIGNAL_FUNC) sig_key);
key_bind("multi", "Run multiple commands", NULL, NULL, (SIGNAL_FUNC) sig_multi);
+ key_bind("nothing", "Do nothing", NULL, NULL, (SIGNAL_FUNC) sig_nothing);
/* read the keyboard config when all key binds are known */
signal_add("irssi init read settings", (SIGNAL_FUNC) read_keyboard_config);
signal_add("complete command bind", (SIGNAL_FUNC) sig_complete_bind);
command_bind("bind", NULL, (SIGNAL_FUNC) cmd_bind);
- command_set_options("bind", "delete");
+ command_set_options("bind", "delete list");
}
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);