4 Copyright (C) 1999 Timo Sirainen
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "module-formats.h"
26 #include "special-vars.h"
30 #include "completion.h"
31 #include "command-history.h"
33 #include "translation.h"
34 #include "printtext.h"
37 #include "gui-entry.h"
38 #include "gui-windows.h"
43 typedef void (*ENTRY_REDIRECT_KEY_FUNC) (int key, void *data, SERVER_REC *server, WI_ITEM_REC *item);
44 typedef void (*ENTRY_REDIRECT_ENTRY_FUNC) (const char *line, void *data, SERVER_REC *server, WI_ITEM_REC *item);
52 static KEYBOARD_REC *keyboard;
53 static ENTRY_REDIRECT_REC *redir;
54 static int escape_next_key;
57 static unichar prev_key;
58 static GTimeVal last_keypress;
60 static int paste_detect_time, paste_detect_keycount, paste_verify_line_count;
61 static int paste_state, paste_keycount;
62 static char *paste_entry, *prev_entry;
63 static int paste_entry_pos, prev_entry_pos;
64 static GArray *paste_buffer;
66 static char *paste_old_prompt;
67 static int paste_prompt, paste_line_count;
68 static int paste_join_multiline;
70 static void sig_input(void);
72 void input_listen_init(int handle)
74 GIOChannel *stdin_channel;
76 stdin_channel = g_io_channel_unix_new(handle);
77 readtag = g_input_add_full(stdin_channel,
78 G_PRIORITY_HIGH, G_INPUT_READ,
79 (GInputFunction) sig_input, NULL);
80 g_io_channel_unref(stdin_channel);
83 void input_listen_deinit(void)
85 g_source_remove(readtag);
89 static void handle_key_redirect(int key)
91 ENTRY_REDIRECT_KEY_FUNC func;
94 func = (ENTRY_REDIRECT_KEY_FUNC) redir->func;
96 g_free_and_null(redir);
98 gui_entry_set_prompt(active_entry, "");
101 func(key, data, active_win->active_server, active_win->active);
104 static void handle_entry_redirect(const char *line)
106 ENTRY_REDIRECT_ENTRY_FUNC func;
109 gui_entry_set_hidden(active_entry, FALSE);
111 func = (ENTRY_REDIRECT_ENTRY_FUNC) redir->func;
113 g_free_and_null(redir);
115 gui_entry_set_prompt(active_entry, "");
118 func(line, data, active_win->active_server,
123 static int get_scroll_count(void)
128 str = settings_get_str("scroll_page_count");
129 count = atof(str + (*str == '/'));
133 count = active_mainwin->height-active_mainwin->statusbar_lines+count;
138 count = (active_mainwin->height-active_mainwin->statusbar_lines)/count;
143 static void window_prev_page(void)
145 gui_window_scroll(active_win, -get_scroll_count());
148 static void window_next_page(void)
150 gui_window_scroll(active_win, get_scroll_count());
153 static void paste_buffer_join_lines(GArray *buf)
155 #define IS_WHITE(c) ((c) == ' ' || (c) == '\t')
156 unsigned int i, count, indent, line_len;
157 unichar *arr, *dest, *last_lf_pos;
160 /* first check if we actually want to join anything. This is assuming
161 that we only want to join lines if
163 a) first line doesn't begin with whitespace
164 b) subsequent lines begin with same amount of whitespace
165 c) whenever there's no whitespace, goto a)
185 arr = (unichar *) paste_buffer->data;
188 if (IS_WHITE(arr[0]))
191 /* find the first beginning of indented line */
192 for (i = 1; i < buf->len; i++) {
193 if (arr[i-1] == '\n' && IS_WHITE(arr[i]))
199 /* get how much indentation we have.. */
200 for (indent = 0; i < buf->len; i++, indent++) {
201 if (!IS_WHITE(arr[i]))
207 /* now, enforce these to all subsequent lines */
208 count = indent; last_lf = TRUE;
209 for (; i < buf->len; i++) {
211 if (IS_WHITE(arr[i]))
215 if (count != 0 && count != indent)
224 /* all looks fine - now remove the whitespace, but don't let lines
225 get longer than 400 chars */
226 dest = arr; last_lf = TRUE; last_lf_pos = NULL; line_len = 0;
227 for (i = 0; i < buf->len; i++) {
228 if (last_lf && IS_WHITE(arr[i])) {
229 /* whitespace, ignore */
230 } else if (arr[i] == '\n') {
231 if (!last_lf && i+1 != buf->len &&
232 IS_WHITE(arr[i+1])) {
236 *dest++ = '\n'; /* double-LF */
243 if (++line_len >= 400 && last_lf_pos != NULL) {
244 memmove(last_lf_pos+1, last_lf_pos,
246 *last_lf_pos = '\n'; last_lf_pos = NULL;
253 g_array_set_size(buf, dest - arr);
256 static void paste_send(void)
258 HISTORY_REC *history;
264 if (paste_join_multiline)
265 paste_buffer_join_lines(paste_buffer);
267 arr = (unichar *) paste_buffer->data;
268 if (active_entry->text_len == 0)
271 /* first line has to be kludged kind of to get pasting in the
272 middle of line right.. */
273 for (i = 0; i < paste_buffer->len; i++) {
274 if (arr[i] == '\r' || arr[i] == '\n') {
279 gui_entry_insert_char(active_entry, arr[i]);
282 text = gui_entry_get_text(active_entry);
283 history = command_history_current(active_win);
284 command_history_add(history, text);
286 translate_output(text);
287 signal_emit("send command", 3, text,
288 active_win->active_server, active_win->active);
292 /* rest of the lines */
293 str = g_string_new(NULL);
294 for (; i < paste_buffer->len; i++) {
295 if (arr[i] == '\r' || arr[i] == '\n') {
296 history = command_history_current(active_win);
297 command_history_add(history, str->str);
299 translate_output(str->str);
300 signal_emit("send command", 3, str->str,
301 active_win->active_server,
303 g_string_truncate(str, 0);
304 } else if (active_entry->utf8) {
305 out[utf16_char_to_utf8(arr[i], out)] = '\0';
306 g_string_append(str, out);
307 } else if (term_type == TERM_TYPE_BIG5) {
309 g_string_append_c(str, (arr[i] >> 8) & 0xff);
310 g_string_append_c(str, arr[i] & 0xff);
312 g_string_append_c(str, arr[i]);
316 gui_entry_set_text(active_entry, str->str);
317 g_string_free(str, TRUE);
320 static void paste_flush(int send)
322 gui_entry_set_text(active_entry, paste_entry);
323 gui_entry_set_pos(active_entry, paste_entry_pos);
327 g_array_set_size(paste_buffer, 0);
329 gui_entry_set_prompt(active_entry,
330 paste_old_prompt == NULL ? "" : paste_old_prompt);
331 g_free(paste_old_prompt); paste_old_prompt = NULL;
332 paste_prompt = FALSE;
334 paste_line_count = 0;
338 gui_entry_redraw(active_entry);
341 static gboolean paste_timeout(gpointer data)
347 if (paste_state == 0) {
352 g_get_current_time(&now);
353 diff = (now.tv_sec - last_keypress.tv_sec) * 1000 +
354 (now.tv_usec - last_keypress.tv_usec)/1000;
356 if (diff < paste_detect_time) {
361 if (paste_line_count < paste_verify_line_count ||
362 active_win->active == NULL) {
363 /* paste without asking */
365 } else if (!paste_prompt) {
367 paste_old_prompt = g_strdup(active_entry->prompt);
368 printformat_window(active_win, MSGLEVEL_CLIENTNOTICE,
371 active_win->active == NULL ? "window" :
372 active_win->active->visible_name);
374 str = format_get_text(MODULE_NAME, active_win, NULL, NULL,
375 TXT_PASTE_PROMPT, 0, 0);
376 gui_entry_set_prompt(active_entry, str);
377 gui_entry_set_text(active_entry, "");
383 static int check_pasting(unichar key, int diff)
388 if (paste_state == 0) {
389 /* two keys hit together quick. possibly pasting */
390 if (diff > paste_detect_time)
394 paste_entry = g_strdup(prev_entry);
395 paste_entry_pos = prev_entry_pos;
398 paste_line_count = 0;
400 g_array_set_size(paste_buffer, 0);
401 if (prev_key != '\r' && prev_key != '\n')
402 g_array_append_val(paste_buffer, prev_key);
403 } else if (paste_state > 0 && diff > paste_detect_time &&
404 paste_line_count == 0) {
405 /* reset paste state */
411 /* continuing quick hits */
412 if ((key == 11 || key == 3) && paste_prompt) {
413 paste_flush(key == 11);
417 g_array_append_val(paste_buffer, key);
418 if (key == '\r' || key == '\n') {
419 if (paste_state == 1 &&
420 paste_keycount < paste_detect_keycount) {
421 /* not enough keypresses to determine if this is
422 pasting or not. don't reset paste keycount, but
423 send this line as non-pasted */
424 g_array_set_size(paste_buffer, 0);
428 /* newline - assume this line was pasted */
429 if (paste_state == 1) {
431 gui_entry_set_text(active_entry, paste_entry);
432 gui_entry_set_pos(active_entry, paste_entry_pos);
433 if (paste_verify_line_count > 0)
434 g_timeout_add(100, paste_timeout, NULL);
437 if (paste_verify_line_count <= 0) {
438 /* paste previous line */
440 g_array_set_size(paste_buffer, 0);
446 return paste_state == 2;
449 static void sig_gui_key_pressed(gpointer keyp)
456 key = GPOINTER_TO_INT(keyp);
458 if (redir != NULL && redir->flags & ENTRY_REDIRECT_FLAG_HOTKEY) {
459 handle_key_redirect(key);
463 g_get_current_time(&now);
464 diff = (now.tv_sec - last_keypress.tv_sec) * 1000 +
465 (now.tv_usec - last_keypress.tv_usec)/1000;
467 if (check_pasting(key, diff)) {
475 str[1] = (char)key+'@';
477 } else if (key == 127) {
481 } else if (!active_entry->utf8) {
486 str[0] = (char) (key >> 8);
487 str[1] = (char) (key & 0xff);
491 /* need to convert to utf8 */
492 str[utf16_char_to_utf8(key, str)] = '\0';
495 if (strcmp(str, "^") == 0) {
496 /* change it as ^^ */
502 prev_entry = gui_entry_get_text(active_entry);
503 prev_entry_pos = gui_entry_get_pos(active_entry);
505 if (escape_next_key) {
506 escape_next_key = FALSE;
507 gui_entry_insert_char(active_entry, key);
510 ret = key_pressed(keyboard, str);
512 /* key wasn't used for anything, print it */
513 gui_entry_insert_char(active_entry, key);
517 /* ret = 0 : some key create multiple characters - we're in the middle
518 of one. try to detect the keycombo as a single keypress rather than
519 multiple small onces to avoid incorrect paste detection.
521 don't count repeated keys so paste detection won't go on when
522 you're holding some key down */
523 if (ret != 0 && key != prev_key) {
530 static void key_send_line(void)
532 HISTORY_REC *history;
533 char *str, *add_history;
535 str = gui_entry_get_text(active_entry);
537 /* we can't use gui_entry_get_text() later, since the entry might
538 have been destroyed after we get back */
539 add_history = *str == '\0' ? NULL : g_strdup(str);
540 history = command_history_current(active_win);
542 translate_output(str);
545 signal_emit("send command", 3, str,
546 active_win->active_server,
549 if (redir->flags & ENTRY_REDIRECT_FLAG_HIDDEN)
550 g_free_and_null(add_history);
551 handle_entry_redirect(str);
554 if (add_history != NULL) {
555 history = command_history_find(history);
557 command_history_add(history, add_history);
561 if (active_entry != NULL)
562 gui_entry_set_text(active_entry, "");
563 command_history_clear_pos(active_win);
568 static void key_combo(void)
572 static void key_backward_history(void)
577 line = gui_entry_get_text(active_entry);
578 text = command_history_prev(active_win, line);
579 gui_entry_set_text(active_entry, text);
583 static void key_forward_history(void)
588 line = gui_entry_get_text(active_entry);
589 text = command_history_next(active_win, line);
590 gui_entry_set_text(active_entry, text);
594 static void key_beginning_of_line(void)
596 gui_entry_set_pos(active_entry, 0);
599 static void key_end_of_line(void)
601 gui_entry_set_pos(active_entry, active_entry->text_len);
604 static void key_backward_character(void)
606 gui_entry_move_pos(active_entry, -1);
609 static void key_forward_character(void)
611 gui_entry_move_pos(active_entry, 1);
614 static void key_backward_word(void)
616 gui_entry_move_words(active_entry, -1, FALSE);
619 static void key_forward_word(void)
621 gui_entry_move_words(active_entry, 1, FALSE);
624 static void key_backward_to_space(void)
626 gui_entry_move_words(active_entry, -1, TRUE);
629 static void key_forward_to_space(void)
631 gui_entry_move_words(active_entry, 1, TRUE);
634 static void key_erase_line(void)
636 gui_entry_set_pos(active_entry, active_entry->text_len);
637 gui_entry_erase(active_entry, active_entry->text_len, TRUE);
640 static void key_erase_to_beg_of_line(void)
644 pos = gui_entry_get_pos(active_entry);
645 gui_entry_erase(active_entry, pos, TRUE);
648 static void key_erase_to_end_of_line(void)
652 pos = gui_entry_get_pos(active_entry);
653 gui_entry_set_pos(active_entry, active_entry->text_len);
654 gui_entry_erase(active_entry, active_entry->text_len - pos, TRUE);
657 static void key_yank_from_cutbuffer(void)
661 cutbuffer = gui_entry_get_cutbuffer(active_entry);
662 if (cutbuffer != NULL) {
663 gui_entry_insert_text(active_entry, cutbuffer);
668 static void key_transpose_characters(void)
670 gui_entry_transpose_chars(active_entry);
673 static void key_transpose_words(void)
675 gui_entry_transpose_words(active_entry);
678 static void key_capitalize_word(void)
680 gui_entry_capitalize_word(active_entry);
683 static void key_downcase_word(void)
685 gui_entry_downcase_word(active_entry);
687 static void key_upcase_word(void)
689 gui_entry_upcase_word(active_entry);
692 static void key_delete_character(void)
694 if (gui_entry_get_pos(active_entry) < active_entry->text_len) {
695 gui_entry_move_pos(active_entry, 1);
696 gui_entry_erase(active_entry, 1, FALSE);
700 static void key_backspace(void)
702 gui_entry_erase(active_entry, 1, FALSE);
705 static void key_delete_previous_word(void)
707 gui_entry_erase_word(active_entry, FALSE);
710 static void key_delete_next_word(void)
712 gui_entry_erase_next_word(active_entry, FALSE);
715 static void key_delete_to_previous_space(void)
717 gui_entry_erase_word(active_entry, TRUE);
720 static void key_delete_to_next_space(void)
722 gui_entry_erase_next_word(active_entry, TRUE);
725 static void sig_input(void)
731 /* no active entry yet - wait until we have it */
735 ret = term_gets(buffer, sizeof(buffer)/sizeof(buffer[0]));
739 signal_emit("command quit", 1, "Lost terminal");
741 for (i = 0; i < ret; i++) {
742 signal_emit("gui key pressed", 1,
743 GINT_TO_POINTER(buffer[i]));
748 time_t get_idle_time(void)
750 return last_keypress.tv_sec;
753 static void key_scroll_backward(void)
758 static void key_scroll_forward(void)
763 static void key_scroll_start(void)
765 signal_emit("command scrollback home", 3, NULL, active_win->active_server, active_win->active);
768 static void key_scroll_end(void)
770 signal_emit("command scrollback end", 3, NULL, active_win->active_server, active_win->active);
773 static void key_change_window(const char *data)
775 signal_emit("command window goto", 3, data, active_win->active_server, active_win->active);
778 static void key_completion(int erase)
783 text = gui_entry_get_text_and_pos(active_entry, &pos);
784 line = word_complete(active_win, text, &pos, erase);
788 gui_entry_set_text(active_entry, line);
789 gui_entry_set_pos(active_entry, pos);
794 static void key_word_completion(void)
796 key_completion(FALSE);
799 static void key_erase_completion(void)
801 key_completion(TRUE);
804 static void key_check_replaces(void)
809 text = gui_entry_get_text_and_pos(active_entry, &pos);
810 line = auto_word_complete(text, &pos);
814 gui_entry_set_text(active_entry, line);
815 gui_entry_set_pos(active_entry, pos);
820 static void key_previous_window(void)
822 signal_emit("command window previous", 3, "", active_win->active_server, active_win->active);
825 static void key_next_window(void)
827 signal_emit("command window next", 3, "", active_win->active_server, active_win->active);
830 static void key_left_window(void)
832 signal_emit("command window left", 3, "", active_win->active_server, active_win->active);
835 static void key_right_window(void)
837 signal_emit("command window right", 3, "", active_win->active_server, active_win->active);
840 static void key_upper_window(void)
842 signal_emit("command window up", 3, "", active_win->active_server, active_win->active);
845 static void key_lower_window(void)
847 signal_emit("command window down", 3, "", active_win->active_server, active_win->active);
850 static void key_active_window(void)
852 signal_emit("command window goto", 3, "active", active_win->active_server, active_win->active);
855 static SERVER_REC *get_prev_server(SERVER_REC *current)
859 if (current == NULL) {
860 return servers != NULL ? g_slist_last(servers)->data :
861 lookup_servers != NULL ?
862 g_slist_last(lookup_servers)->data : NULL;
865 /* connect2 -> connect1 -> server2 -> server1 -> connect2 -> .. */
867 pos = g_slist_index(servers, current);
870 return g_slist_nth(servers, pos-1)->data;
871 if (lookup_servers != NULL)
872 return g_slist_last(lookup_servers)->data;
873 return g_slist_last(servers)->data;
876 pos = g_slist_index(lookup_servers, current);
880 return g_slist_nth(lookup_servers, pos-1)->data;
882 return g_slist_last(servers)->data;
883 return g_slist_last(lookup_servers)->data;
886 static SERVER_REC *get_next_server(SERVER_REC *current)
890 if (current == NULL) {
891 return servers != NULL ? servers->data :
892 lookup_servers != NULL ? lookup_servers->data : NULL;
895 /* server1 -> server2 -> connect1 -> connect2 -> server1 -> .. */
897 pos = g_slist_find(servers, current);
899 if (pos->next != NULL)
900 return pos->next->data;
901 if (lookup_servers != NULL)
902 return lookup_servers->data;
903 return servers->data;
906 pos = g_slist_find(lookup_servers, current);
907 g_assert(pos != NULL);
909 if (pos->next != NULL)
910 return pos->next->data;
912 return servers->data;
913 return lookup_servers->data;
916 static void key_previous_window_item(void)
920 if (active_win->items != NULL) {
921 signal_emit("command window item prev", 3, "",
922 active_win->active_server, active_win->active);
923 } else if (servers != NULL || lookup_servers != NULL) {
925 server = active_win->active_server;
927 server = active_win->connect_server;
928 server = get_prev_server(server);
929 signal_emit("command window server", 3, server->tag,
930 active_win->active_server, active_win->active);
934 static void key_next_window_item(void)
938 if (active_win->items != NULL) {
939 signal_emit("command window item next", 3, "",
940 active_win->active_server, active_win->active);
941 } else if (servers != NULL || lookup_servers != NULL) {
943 server = active_win->active_server;
945 server = active_win->connect_server;
946 server = get_next_server(server);
947 signal_emit("command window server", 3, server->tag,
948 active_win->active_server, active_win->active);
952 static void key_escape(void)
954 escape_next_key = TRUE;
957 static void key_insert_text(const char *data)
961 str = parse_special_string(data, active_win->active_server,
962 active_win->active, "", NULL, 0);
963 gui_entry_insert_text(active_entry, str);
967 static void key_sig_stop(void)
972 static void sig_window_auto_changed(void)
976 if (active_entry == NULL)
979 text = gui_entry_get_text(active_entry);
980 command_history_next(active_win, text);
981 gui_entry_set_text(active_entry, "");
985 static void sig_gui_entry_redirect(SIGNAL_FUNC func, const char *entry,
986 void *flags, void *data)
988 redir = g_new0(ENTRY_REDIRECT_REC, 1);
990 redir->flags = GPOINTER_TO_INT(flags);
993 if (redir->flags & ENTRY_REDIRECT_FLAG_HIDDEN)
994 gui_entry_set_hidden(active_entry, TRUE);
995 gui_entry_set_prompt(active_entry, entry);
998 static void setup_changed(void)
1000 paste_detect_time = settings_get_time("paste_detect_time");
1001 if (paste_detect_time == 0)
1003 else if (paste_state == -1)
1006 paste_detect_keycount = settings_get_int("paste_detect_keycount");
1007 if (paste_detect_keycount < 2)
1010 paste_verify_line_count = settings_get_int("paste_verify_line_count");
1011 paste_join_multiline = settings_get_bool("paste_join_multiline");
1014 void gui_readline_init(void)
1016 static char changekeys[] = "1234567890qwertyuio";
1017 char *key, data[MAX_INT_STRLEN];
1020 escape_next_key = FALSE;
1026 paste_entry_pos = 0;
1027 paste_buffer = g_array_new(FALSE, FALSE, sizeof(unichar));
1028 paste_old_prompt = NULL;
1029 g_get_current_time(&last_keypress);
1030 input_listen_init(STDIN_FILENO);
1032 settings_add_str("history", "scroll_page_count", "/2");
1033 settings_add_time("misc", "paste_detect_time", "5msecs");
1034 settings_add_int("misc", "paste_detect_keycount", 5);
1035 /* NOTE: function keys can generate at least 5 characters long
1036 keycodes. this must be larger to allow them to work. */
1037 settings_add_int("misc", "paste_verify_line_count", 5);
1038 settings_add_bool("misc", "paste_join_multiline", TRUE);
1041 keyboard = keyboard_create(NULL);
1042 key_configure_freeze();
1044 key_bind("key", NULL, " ", "space", (SIGNAL_FUNC) key_combo);
1045 key_bind("key", NULL, "^M", "return", (SIGNAL_FUNC) key_combo);
1046 key_bind("key", NULL, "^J", "return", (SIGNAL_FUNC) key_combo);
1047 key_bind("key", NULL, "^H", "backspace", (SIGNAL_FUNC) key_combo);
1048 key_bind("key", NULL, "^?", "backspace", (SIGNAL_FUNC) key_combo);
1049 key_bind("key", NULL, "^I", "tab", (SIGNAL_FUNC) key_combo);
1052 key_bind("key", NULL, "^[", "meta", (SIGNAL_FUNC) key_combo);
1053 key_bind("key", NULL, "meta-[", "meta2", (SIGNAL_FUNC) key_combo);
1054 key_bind("key", NULL, "meta-O", "meta2", (SIGNAL_FUNC) key_combo);
1055 key_bind("key", NULL, "meta-[O", "meta2", (SIGNAL_FUNC) key_combo);
1058 key_bind("key", NULL, "meta2-A", "up", (SIGNAL_FUNC) key_combo);
1059 key_bind("key", NULL, "meta2-B", "down", (SIGNAL_FUNC) key_combo);
1060 key_bind("key", NULL, "meta2-C", "right", (SIGNAL_FUNC) key_combo);
1061 key_bind("key", NULL, "meta2-D", "left", (SIGNAL_FUNC) key_combo);
1063 key_bind("key", NULL, "meta2-1~", "home", (SIGNAL_FUNC) key_combo);
1064 key_bind("key", NULL, "meta2-7~", "home", (SIGNAL_FUNC) key_combo);
1065 key_bind("key", NULL, "meta2-H", "home", (SIGNAL_FUNC) key_combo);
1067 key_bind("key", NULL, "meta2-4~", "end", (SIGNAL_FUNC) key_combo);
1068 key_bind("key", NULL, "meta2-8~", "end", (SIGNAL_FUNC) key_combo);
1069 key_bind("key", NULL, "meta2-F", "end", (SIGNAL_FUNC) key_combo);
1071 key_bind("key", NULL, "meta2-5~", "prior", (SIGNAL_FUNC) key_combo);
1072 key_bind("key", NULL, "meta2-I", "prior", (SIGNAL_FUNC) key_combo);
1073 key_bind("key", NULL, "meta2-6~", "next", (SIGNAL_FUNC) key_combo);
1074 key_bind("key", NULL, "meta2-G", "next", (SIGNAL_FUNC) key_combo);
1076 key_bind("key", NULL, "meta2-2~", "insert", (SIGNAL_FUNC) key_combo);
1077 key_bind("key", NULL, "meta2-3~", "delete", (SIGNAL_FUNC) key_combo);
1079 key_bind("key", NULL, "meta2-d", "cleft", (SIGNAL_FUNC) key_combo);
1080 key_bind("key", NULL, "meta2-c", "cright", (SIGNAL_FUNC) key_combo);
1081 key_bind("key", NULL, "meta2-5D", "cleft", (SIGNAL_FUNC) key_combo);
1082 key_bind("key", NULL, "meta2-5C", "cright", (SIGNAL_FUNC) key_combo);
1084 /* cursor movement */
1085 key_bind("backward_character", "", "left", NULL, (SIGNAL_FUNC) key_backward_character);
1086 key_bind("forward_character", "", "right", NULL, (SIGNAL_FUNC) key_forward_character);
1087 key_bind("backward_word", "", "cleft", NULL, (SIGNAL_FUNC) key_backward_word);
1088 key_bind("backward_word", NULL, "meta-b", NULL, (SIGNAL_FUNC) key_backward_word);
1089 key_bind("forward_word", "", "cright", NULL, (SIGNAL_FUNC) key_forward_word);
1090 key_bind("forward_word", NULL, "meta-f", NULL, (SIGNAL_FUNC) key_forward_word);
1091 key_bind("backward_to_space", "", NULL, NULL, (SIGNAL_FUNC) key_backward_to_space);
1092 key_bind("forward_to_space", "", NULL, NULL, (SIGNAL_FUNC) key_forward_to_space);
1093 key_bind("beginning_of_line", "", "home", NULL, (SIGNAL_FUNC) key_beginning_of_line);
1094 key_bind("beginning_of_line", NULL, "^A", NULL, (SIGNAL_FUNC) key_beginning_of_line);
1095 key_bind("end_of_line", "", "end", NULL, (SIGNAL_FUNC) key_end_of_line);
1096 key_bind("end_of_line", NULL, "^E", NULL, (SIGNAL_FUNC) key_end_of_line);
1099 key_bind("backward_history", "", "up", NULL, (SIGNAL_FUNC) key_backward_history);
1100 key_bind("forward_history", "", "down", NULL, (SIGNAL_FUNC) key_forward_history);
1103 key_bind("backspace", "", "backspace", NULL, (SIGNAL_FUNC) key_backspace);
1104 key_bind("delete_character", "", "delete", NULL, (SIGNAL_FUNC) key_delete_character);
1105 key_bind("delete_character", NULL, "^D", NULL, (SIGNAL_FUNC) key_delete_character);
1106 key_bind("delete_next_word", "", "meta-d", NULL, (SIGNAL_FUNC) key_delete_next_word);
1107 key_bind("delete_previous_word", "", "meta-backspace", NULL, (SIGNAL_FUNC) key_delete_previous_word);
1108 key_bind("delete_to_previous_space", "", "^W", NULL, (SIGNAL_FUNC) key_delete_to_previous_space);
1109 key_bind("delete_to_next_space", "", "", NULL, (SIGNAL_FUNC) key_delete_to_next_space);
1110 key_bind("erase_line", "", "^U", NULL, (SIGNAL_FUNC) key_erase_line);
1111 key_bind("erase_to_beg_of_line", "", NULL, NULL, (SIGNAL_FUNC) key_erase_to_beg_of_line);
1112 key_bind("erase_to_end_of_line", "", "^K", NULL, (SIGNAL_FUNC) key_erase_to_end_of_line);
1113 key_bind("yank_from_cutbuffer", "", "^Y", NULL, (SIGNAL_FUNC) key_yank_from_cutbuffer);
1114 key_bind("transpose_characters", "Swap current and previous character", "^T", NULL, (SIGNAL_FUNC) key_transpose_characters);
1115 key_bind("transpose_words", "Swap current and previous word", NULL, NULL, (SIGNAL_FUNC) key_transpose_words);
1116 key_bind("capitalize_word", "Capitalize word", NULL, NULL, (SIGNAL_FUNC) key_capitalize_word);
1117 key_bind("downcase_word", "Downcase word", NULL, NULL, (SIGNAL_FUNC) key_downcase_word);
1118 key_bind("upcase_word", "Upcase word", NULL, NULL, (SIGNAL_FUNC) key_upcase_word);
1120 /* line transmitting */
1121 key_bind("send_line", "Execute the input line", "return", NULL, (SIGNAL_FUNC) key_send_line);
1122 key_bind("word_completion", "", "tab", NULL, (SIGNAL_FUNC) key_word_completion);
1123 key_bind("erase_completion", "", "meta-k", NULL, (SIGNAL_FUNC) key_erase_completion);
1124 key_bind("check_replaces", "Check word replaces", NULL, NULL, (SIGNAL_FUNC) key_check_replaces);
1126 /* window managing */
1127 key_bind("previous_window", "Previous window", "^P", NULL, (SIGNAL_FUNC) key_previous_window);
1128 key_bind("next_window", "Next window", "^N", NULL, (SIGNAL_FUNC) key_next_window);
1129 key_bind("upper_window", "Upper window", "meta-up", NULL, (SIGNAL_FUNC) key_upper_window);
1130 key_bind("lower_window", "Lower window", "meta-down", NULL, (SIGNAL_FUNC) key_lower_window);
1131 key_bind("left_window", "Window in left", "meta-left", NULL, (SIGNAL_FUNC) key_left_window);
1132 key_bind("right_window", "Window in right", "meta-right", NULL, (SIGNAL_FUNC) key_right_window);
1133 key_bind("active_window", "Go to next window with the highest activity", "meta-a", NULL, (SIGNAL_FUNC) key_active_window);
1134 key_bind("next_window_item", "Next channel/query", "^X", NULL, (SIGNAL_FUNC) key_next_window_item);
1135 key_bind("previous_window_item", "Previous channel/query", NULL, NULL, (SIGNAL_FUNC) key_previous_window_item);
1137 key_bind("refresh_screen", "Redraw screen", "^L", NULL, (SIGNAL_FUNC) irssi_redraw);
1138 key_bind("scroll_backward", "Previous page", "prior", NULL, (SIGNAL_FUNC) key_scroll_backward);
1139 key_bind("scroll_backward", NULL, "meta-p", NULL, (SIGNAL_FUNC) key_scroll_backward);
1140 key_bind("scroll_forward", "Next page", "next", NULL, (SIGNAL_FUNC) key_scroll_forward);
1141 key_bind("scroll_forward", NULL, "meta-n", NULL, (SIGNAL_FUNC) key_scroll_forward);
1142 key_bind("scroll_start", "Beginning of the window", "", NULL, (SIGNAL_FUNC) key_scroll_start);
1143 key_bind("scroll_end", "End of the window", "", NULL, (SIGNAL_FUNC) key_scroll_end);
1145 /* inserting special input characters to line.. */
1146 key_bind("escape_char", "Escape the next keypress", NULL, NULL, (SIGNAL_FUNC) key_escape);
1147 key_bind("insert_text", "Append text to line", NULL, NULL, (SIGNAL_FUNC) key_insert_text);
1150 key_bind("multi", NULL, "return", "check_replaces;send_line", NULL);
1151 key_bind("multi", NULL, "space", "check_replaces;insert_text ", NULL);
1153 /* moving between windows */
1154 for (n = 0; changekeys[n] != '\0'; n++) {
1155 key = g_strdup_printf("meta-%c", changekeys[n]);
1157 key_bind("change_window", "Change window", key, data, (SIGNAL_FUNC) key_change_window);
1162 key_bind("stop_irc", "Send SIGSTOP to client", "^Z", NULL, (SIGNAL_FUNC) key_sig_stop);
1164 key_configure_thaw();
1166 signal_add("window changed automatic", (SIGNAL_FUNC) sig_window_auto_changed);
1167 signal_add("gui entry redirect", (SIGNAL_FUNC) sig_gui_entry_redirect);
1168 signal_add("gui key pressed", (SIGNAL_FUNC) sig_gui_key_pressed);
1169 signal_add("setup changed", (SIGNAL_FUNC) setup_changed);
1172 void gui_readline_deinit(void)
1174 input_listen_deinit();
1176 key_configure_freeze();
1178 key_unbind("backward_character", (SIGNAL_FUNC) key_backward_character);
1179 key_unbind("forward_character", (SIGNAL_FUNC) key_forward_character);
1180 key_unbind("backward_word", (SIGNAL_FUNC) key_backward_word);
1181 key_unbind("forward_word", (SIGNAL_FUNC) key_forward_word);
1182 key_unbind("backward_to_space", (SIGNAL_FUNC) key_backward_to_space);
1183 key_unbind("forward_to_space", (SIGNAL_FUNC) key_forward_to_space);
1184 key_unbind("beginning_of_line", (SIGNAL_FUNC) key_beginning_of_line);
1185 key_unbind("end_of_line", (SIGNAL_FUNC) key_end_of_line);
1187 key_unbind("backward_history", (SIGNAL_FUNC) key_backward_history);
1188 key_unbind("forward_history", (SIGNAL_FUNC) key_forward_history);
1190 key_unbind("backspace", (SIGNAL_FUNC) key_backspace);
1191 key_unbind("delete_character", (SIGNAL_FUNC) key_delete_character);
1192 key_unbind("delete_next_word", (SIGNAL_FUNC) key_delete_next_word);
1193 key_unbind("delete_previous_word", (SIGNAL_FUNC) key_delete_previous_word);
1194 key_unbind("delete_to_next_space", (SIGNAL_FUNC) key_delete_to_next_space);
1195 key_unbind("delete_to_previous_space", (SIGNAL_FUNC) key_delete_to_previous_space);
1196 key_unbind("erase_line", (SIGNAL_FUNC) key_erase_line);
1197 key_unbind("erase_to_beg_of_line", (SIGNAL_FUNC) key_erase_to_beg_of_line);
1198 key_unbind("erase_to_end_of_line", (SIGNAL_FUNC) key_erase_to_end_of_line);
1199 key_unbind("yank_from_cutbuffer", (SIGNAL_FUNC) key_yank_from_cutbuffer);
1200 key_unbind("transpose_characters", (SIGNAL_FUNC) key_transpose_characters);
1201 key_unbind("transpose_words", (SIGNAL_FUNC) key_transpose_words);
1203 key_unbind("capitalize_word", (SIGNAL_FUNC) key_capitalize_word);
1204 key_unbind("downcase_word", (SIGNAL_FUNC) key_downcase_word);
1205 key_unbind("upcase_word", (SIGNAL_FUNC) key_upcase_word);
1207 key_unbind("send_line", (SIGNAL_FUNC) key_send_line);
1208 key_unbind("word_completion", (SIGNAL_FUNC) key_word_completion);
1209 key_unbind("erase_completion", (SIGNAL_FUNC) key_erase_completion);
1210 key_unbind("check_replaces", (SIGNAL_FUNC) key_check_replaces);
1212 key_unbind("previous_window", (SIGNAL_FUNC) key_previous_window);
1213 key_unbind("next_window", (SIGNAL_FUNC) key_next_window);
1214 key_unbind("upper_window", (SIGNAL_FUNC) key_upper_window);
1215 key_unbind("lower_window", (SIGNAL_FUNC) key_lower_window);
1216 key_unbind("left_window", (SIGNAL_FUNC) key_left_window);
1217 key_unbind("right_window", (SIGNAL_FUNC) key_right_window);
1218 key_unbind("active_window", (SIGNAL_FUNC) key_active_window);
1219 key_unbind("next_window_item", (SIGNAL_FUNC) key_next_window_item);
1220 key_unbind("previous_window_item", (SIGNAL_FUNC) key_previous_window_item);
1222 key_unbind("refresh_screen", (SIGNAL_FUNC) irssi_redraw);
1223 key_unbind("scroll_backward", (SIGNAL_FUNC) key_scroll_backward);
1224 key_unbind("scroll_forward", (SIGNAL_FUNC) key_scroll_forward);
1225 key_unbind("scroll_start", (SIGNAL_FUNC) key_scroll_start);
1226 key_unbind("scroll_end", (SIGNAL_FUNC) key_scroll_end);
1228 key_unbind("escape_char", (SIGNAL_FUNC) key_escape);
1229 key_unbind("insert_text", (SIGNAL_FUNC) key_insert_text);
1230 key_unbind("change_window", (SIGNAL_FUNC) key_change_window);
1231 key_unbind("stop_irc", (SIGNAL_FUNC) key_sig_stop);
1232 keyboard_destroy(keyboard);
1233 g_array_free(paste_buffer, TRUE);
1235 key_configure_thaw();
1237 signal_remove("window changed automatic", (SIGNAL_FUNC) sig_window_auto_changed);
1238 signal_remove("gui entry redirect", (SIGNAL_FUNC) sig_gui_entry_redirect);
1239 signal_remove("gui key pressed", (SIGNAL_FUNC) sig_gui_key_pressed);
1240 signal_remove("setup changed", (SIGNAL_FUNC) setup_changed);