void gui_nicklist_send_signal (const char *signal, struct t_gui_buffer *buffer, const char *arguments) { char *str_args; int length; if (buffer) { length = 128 + ((arguments) ? strlen (arguments) : 0) + 1 + 1; str_args = malloc (length); if (str_args) { snprintf (str_args, length, "0x%lx,%s", (long unsigned int)(buffer), (arguments) ? arguments : ""); (void) hook_signal_send (signal, WEECHAT_HOOK_SIGNAL_STRING, str_args); free (str_args); } } else { (void) hook_signal_send (signal, WEECHAT_HOOK_SIGNAL_STRING, (char *)arguments); } }
void gui_filter_free (struct t_gui_filter *filter) { int i; (void) hook_signal_send ("filter_removing", WEECHAT_HOOK_SIGNAL_POINTER, filter); /* free data */ if (filter->name) free (filter->name); if (filter->buffer_name) free (filter->buffer_name); if (filter->buffers) string_free_split (filter->buffers); if (filter->tags) free (filter->tags); if (filter->tags_array) { for (i = 0; i < filter->tags_count; i++) { string_free_split (filter->tags_array[i]); } free (filter->tags_array); } if (filter->regex) free (filter->regex); if (filter->regex_prefix) { regfree (filter->regex_prefix); free (filter->regex_prefix); } if (filter->regex_message) { regfree (filter->regex_message); free (filter->regex_message); } /* remove filter from filters list */ if (filter->prev_filter) (filter->prev_filter)->next_filter = filter->next_filter; if (filter->next_filter) (filter->next_filter)->prev_filter = filter->prev_filter; if (gui_filters == filter) gui_filters = filter->next_filter; if (last_gui_filter == filter) last_gui_filter = filter->prev_filter; free (filter); (void) hook_signal_send ("filter_removed", WEECHAT_HOOK_SIGNAL_STRING, NULL); }
void gui_input_text_changed_modifier_and_signal (struct t_gui_buffer *buffer) { char str_buffer[128], *new_input; /* send modifier, and change input if needed */ snprintf (str_buffer, sizeof (str_buffer), "0x%lx", (long unsigned int)buffer); new_input = hook_modifier_exec (NULL, "input_text_content", str_buffer, (buffer->input_buffer) ? buffer->input_buffer : ""); if (new_input) { if (strcmp (new_input, buffer->input_buffer) != 0) { /* input has been changed by modifier, use it */ gui_input_replace_input (buffer, new_input); } free (new_input); } /* send signal */ hook_signal_send ("input_text_changed", WEECHAT_HOOK_SIGNAL_STRING, NULL); }
void upgrade_weechat_end () { struct timeval tv_now; long long time_diff; /* remove .upgrade files */ util_exec_on_files (weechat_home, 0, NULL, &upgrade_weechat_remove_file_cb); /* display message for end of /upgrade with duration */ gettimeofday (&tv_now, NULL); time_diff = util_timeval_diff (&weechat_current_start_timeval, &tv_now); gui_chat_printf (NULL, /* TRANSLATORS: %.02fs is a float number + "s" ("seconds") */ _("Upgrade done (%.02fs)"), ((float)time_diff) / 1000000); /* upgrading ended */ weechat_upgrading = 0; /* send signal for end of /upgrade */ (void) hook_signal_send ("upgrade_ended", WEECHAT_HOOK_SIGNAL_STRING, NULL); }
void weechat_sigterm () { log_printf (_("Signal %s received, exiting WeeChat..."), "SIGTERM"); (void) hook_signal_send ("quit", WEECHAT_HOOK_SIGNAL_STRING, NULL); weechat_quit = 1; }
void gui_main_signal_sigquit () { log_printf (_("Signal %s received, exiting WeeChat..."), "SIGQUIT"); (void) hook_signal_send ("quit", WEECHAT_HOOK_SIGNAL_STRING, NULL); weechat_quit = 1; }
void gui_mouse_enable () { gui_mouse_enabled = 1; fprintf (stderr, "\033[?1005h\033[?1000h\033[?1002h"); fflush (stderr); (void) hook_signal_send ("mouse_enabled", WEECHAT_HOOK_SIGNAL_STRING, NULL); }
void gui_filter_global_disable () { if (gui_filters_enabled) { gui_filters_enabled = 0; gui_filter_all_buffers (); hook_signal_send ("filters_disabled", WEECHAT_HOOK_SIGNAL_STRING, NULL); } }
void gui_filter_global_enable () { if (!gui_filters_enabled) { gui_filters_enabled = 1; gui_filter_all_buffers (); (void) hook_signal_send ("filters_enabled", DOGECHAT_HOOK_SIGNAL_STRING, NULL); } }
void gui_main_signal_sighup () { /* * SIGHUP signal is received when terminal is closed (exit of WeeChat * without using /quit command), that's why we set only flag to reload * configuration files later (when terminal is closed, config files are NOT * reloaded, but they are if signal SIGHUP is sent to WeeChat by user) */ gui_reload_config = 1; (void) hook_signal_send ("signal_sighup", WEECHAT_HOOK_SIGNAL_STRING, NULL); }
void gui_main_loop () { struct t_hook *hook_fd_keyboard; /* catch SIGWINCH signal: redraw screen */ util_catch_signal (SIGWINCH, &gui_main_signal_sigwinch); /* hook stdin (read keyboard) */ hook_fd_keyboard = hook_fd (NULL, STDIN_FILENO, 1, 0, 0, &gui_key_read_cb, NULL); gui_window_ask_refresh (1); while (!dogechat_quit) { /* execute timer hooks */ hook_timer_exec (); /* auto reset of color pairs */ if (gui_color_pairs_auto_reset) { gui_color_reset_pairs (); gui_color_pairs_auto_reset_last = time (NULL); gui_color_pairs_auto_reset = 0; gui_color_pairs_auto_reset_pending = 1; } gui_main_refreshs (); if (gui_window_refresh_needed && !gui_window_bare_display) gui_main_refreshs (); if (gui_signal_sigwinch_received) { (void) hook_signal_send ("signal_sigwinch", DOGECHAT_HOOK_SIGNAL_STRING, NULL); gui_signal_sigwinch_received = 0; } gui_color_pairs_auto_reset_pending = 0; /* execute fd hooks */ hook_fd_exec (); } /* remove keyboard hook */ unhook (hook_fd_keyboard); }
void gui_completion_stop (struct t_gui_completion *completion) { if (!completion) return; completion->context = GUI_COMPLETION_NULL; completion->position = -1; if (completion->partial_list->size > 0) { arraylist_clear (completion->partial_list); (void) hook_signal_send ("partial_completion", WEECHAT_HOOK_SIGNAL_STRING, NULL); } }
void gui_completion_stop (struct t_gui_completion *completion) { if (!completion) return; completion->context = GUI_COMPLETION_NULL; completion->position = -1; if (completion->partial_completion_list) { gui_completion_partial_list_free_all (completion); hook_signal_send ("partial_completion", WEECHAT_HOOK_SIGNAL_STRING, NULL); } }
void gui_window_switch (struct t_gui_window *window) { if (gui_current_window == window) return; /* remove unused bars from current window */ /* ... */ gui_current_window = window; gui_window_switch_to_buffer (gui_current_window, gui_current_window->buffer, 1); gui_window_redraw_buffer (gui_current_window->buffer); hook_signal_send ("window_switch", WEECHAT_HOOK_SIGNAL_POINTER, window); }
void gui_keyboard_flush () { int i, key, insert_ok; char key_str[32], *key_utf, *input_old; /* if there's no paste pending, then we use buffer and do actions according to keys */ if (!gui_keyboard_paste_pending) { if (gui_keyboard_buffer_size > 0) gui_keyboard_last_activity_time = time (NULL); for (i = 0; i < gui_keyboard_buffer_size; i++) { key = gui_keyboard_buffer[i]; insert_ok = 1; if (key < 32) { insert_ok = 0; key_str[0] = '^'; key_str[1] = (char) key + '@'; key_str[2] = '\0'; } else if (key == 127) { key_str[0] = '^'; key_str[1] = '?'; key_str[2] = '\0'; } else { if (local_utf8) { /* 1 char: 0vvvvvvv */ if (key < 0x80) { key_str[0] = (char) key; key_str[1] = '\0'; } /* 2 chars: 110vvvvv 10vvvvvv */ else if ((key & 0xE0) == 0xC0) { key_str[0] = (char) key; if (i < gui_keyboard_buffer_size - 1) { key_str[1] = (char) (gui_keyboard_buffer[++i]); key_str[2] = '\0'; } else key_str[1] = '\0'; } /* 3 chars: 1110vvvv 10vvvvvv 10vvvvvv */ else if ((key & 0xF0) == 0xE0) { key_str[0] = (char) key; if (i < gui_keyboard_buffer_size - 1) { key_str[1] = (char) (gui_keyboard_buffer[++i]); if (i < gui_keyboard_buffer_size - 1) { key_str[2] = (char) (gui_keyboard_buffer[++i]); key_str[3] = '\0'; } else key_str[2] = '\0'; } else key_str[1] = '\0'; } /* 4 chars: 11110vvv 10vvvvvv 10vvvvvv 10vvvvvv */ else if ((key & 0xF8) == 0xF0) { key_str[0] = (char) key; if (i < gui_keyboard_buffer_size - 1) { key_str[1] = (char) (gui_keyboard_buffer[++i]); if (i < gui_keyboard_buffer_size - 1) { key_str[2] = (char) (gui_keyboard_buffer[++i]); if (i < gui_keyboard_buffer_size - 1) { key_str[3] = (char) (gui_keyboard_buffer[++i]); key_str[4] = '\0'; } else key_str[3] = '\0'; } else key_str[2] = '\0'; } else key_str[1] = '\0'; } } else { key_str[0] = (char) key; key_str[1] = '\0'; /* convert input to UTF-8 is user is not using UTF-8 as locale */ if (!local_utf8) { key_utf = string_iconv_to_internal (NULL, key_str); strncpy (key_str, key_utf, sizeof (key_str)); key_str[sizeof (key_str) - 1] = '\0'; } } } if (strcmp (key_str, "^") == 0) { key_str[1] = '^'; key_str[2] = '\0'; } /*gui_printf (gui_current_window->buffer, "gui_input_read: key = %s (%d)\n", key_str, key);*/ hook_signal_send ("key_pressed", WEECHAT_HOOK_SIGNAL_STRING, key_str); if (gui_current_window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED) input_old = (gui_current_window->buffer->input_buffer) ? strdup (gui_current_window->buffer->input_buffer) : strdup (""); else input_old = NULL; if ((gui_keyboard_pressed (key_str) != 0) && (insert_ok)) { if (strcmp (key_str, "^^") == 0) key_str[1] = '\0'; gui_input_insert_string (gui_current_window->buffer, key_str, -1); if (gui_current_window->buffer->completion) gui_completion_stop (gui_current_window->buffer->completion, 0); gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); } /* incremental text search in buffer */ if ((gui_current_window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED) && ((input_old == NULL) || (gui_current_window->buffer->input_buffer == NULL) || (strcmp (input_old, gui_current_window->buffer->input_buffer) != 0))) { gui_window_search_restart (gui_current_window); } if (input_old) free (input_old); } if (gui_key_grab && (gui_key_grab_count > 0)) gui_keyboard_grab_end (); gui_keyboard_buffer_reset (); } }
void gui_hotlist_changed_signal () { (void) hook_signal_send ("hotlist_changed", WEECHAT_HOOK_SIGNAL_STRING, NULL); }
int gui_keyboard_read_cb (void *data, int fd) { int ret, i, accept_paste, cancel_paste, text_added_to_buffer, paste_lines; unsigned char buffer[4096]; /* make C compiler happy */ (void) data; (void) fd; accept_paste = 0; cancel_paste = 0; text_added_to_buffer = 0; if (gui_keyboard_paste_pending) { ret = read (STDIN_FILENO, buffer, 1); if (ret == 0) { /* no data on stdin, terminal lost */ log_printf (_("Terminal lost, exiting WeeChat...")); hook_signal_send ("quit", WEECHAT_HOOK_SIGNAL_STRING, NULL); weechat_quit = 1; return WEECHAT_RC_OK; } if (ret <= 0) return WEECHAT_RC_OK; /* ctrl-Y: accept paste */ if (buffer[0] == 25) accept_paste = 1; /* ctrl-N: cancel paste */ if (buffer[0] == 14) cancel_paste = 1; } else { ret = read (STDIN_FILENO, buffer, sizeof (buffer)); if (ret == 0) { /* no data on stdin, terminal lost */ log_printf (_("Terminal lost, exiting WeeChat...")); hook_signal_send ("quit", WEECHAT_HOOK_SIGNAL_STRING, NULL); weechat_quit = 1; return WEECHAT_RC_OK; } if (ret < 0) return WEECHAT_RC_OK; for (i = 0; i < ret; i++) { gui_keyboard_buffer_add (buffer[i]); } text_added_to_buffer = 1; } if (gui_keyboard_paste_pending) { /* user is ok for pasting text, let's paste! */ if (accept_paste) gui_keyboard_paste_accept (); /* user doesn't want to paste text: clear whole buffer! */ else if (cancel_paste) gui_keyboard_paste_cancel (); else if (text_added_to_buffer) gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); } else { /* detect user paste or large amount of text if so, ask user what to do */ if (CONFIG_INTEGER(config_look_paste_max_lines) > 0) { paste_lines = gui_keyboard_get_paste_lines (); if (paste_lines > CONFIG_INTEGER(config_look_paste_max_lines)) { gui_keyboard_paste_pending = 1; gui_input_paste_pending_signal (); } } } gui_keyboard_flush (); return WEECHAT_RC_OK; }
void gui_main_loop () { struct t_hook *hook_fd_keyboard; struct timeval tv_timeout; fd_set read_fds, write_fds, except_fds; int max_fd; int ready; /* catch SIGTERM signal: quit program */ util_catch_signal (SIGTERM, &gui_main_signal_sigterm); util_catch_signal (SIGQUIT, &gui_main_signal_sigquit); /* catch SIGHUP signal: reload configuration */ util_catch_signal (SIGHUP, &gui_main_signal_sighup); /* catch SIGWINCH signal: redraw screen */ util_catch_signal (SIGWINCH, &gui_main_signal_sigwinch); /* hook stdin (read keyboard) */ hook_fd_keyboard = hook_fd (NULL, STDIN_FILENO, 1, 0, 0, &gui_key_read_cb, NULL); gui_window_ask_refresh (1); while (!weechat_quit) { /* reload config, if SIGHUP received */ if (gui_reload_config) { gui_reload_config = 0; log_printf (_("Signal SIGHUP received, reloading configuration " "files")); command_reload (NULL, NULL, 0, NULL, NULL); } /* execute hook timers */ hook_timer_exec (); /* auto reset of color pairs */ if (gui_color_pairs_auto_reset) { gui_color_reset_pairs (); gui_color_pairs_auto_reset_last = time (NULL); gui_color_pairs_auto_reset = 0; gui_color_pairs_auto_reset_pending = 1; } gui_main_refreshs (); if (gui_window_refresh_needed && !gui_window_bare_display) gui_main_refreshs (); if (gui_signal_sigwinch_received) { (void) hook_signal_send ("signal_sigwinch", WEECHAT_HOOK_SIGNAL_STRING, NULL); gui_signal_sigwinch_received = 0; } gui_color_pairs_auto_reset_pending = 0; /* wait for keyboard or network activity */ FD_ZERO (&read_fds); FD_ZERO (&write_fds); FD_ZERO (&except_fds); max_fd = hook_fd_set (&read_fds, &write_fds, &except_fds); hook_timer_time_to_next (&tv_timeout); ready = select (max_fd + 1, &read_fds, &write_fds, &except_fds, &tv_timeout); if (ready > 0) { hook_fd_exec (&read_fds, &write_fds, &except_fds); } } /* remove keyboard hook */ unhook (hook_fd_keyboard); }
int gui_key_read_cb (const void *pointer, void *data, int fd) { int ret, i, accept_paste, cancel_paste, text_added_to_buffer, pos; unsigned char buffer[4096]; /* make C compiler happy */ (void) pointer; (void) data; (void) fd; accept_paste = 0; cancel_paste = 0; text_added_to_buffer = 0; ret = read (STDIN_FILENO, buffer, sizeof (buffer)); if (ret == 0) { /* no data on stdin, terminal lost */ if (!weechat_quit) { log_printf (_("Terminal lost, exiting WeeChat...")); (void) hook_signal_send ("quit", WEECHAT_HOOK_SIGNAL_STRING, NULL); weechat_quit = 1; } return WEECHAT_RC_OK; } if (ret < 0) return WEECHAT_RC_OK; for (i = 0; i < ret; i++) { /* * add all chars, but ignore a newline ('\r' or '\n') after * another one) */ if ((i == 0) || ((buffer[i] != '\r') && (buffer[i] != '\n')) || ((buffer[i - 1] != '\r') && (buffer[i - 1] != '\n'))) { if (gui_key_paste_pending && (buffer[i] == 25)) { /* ctrl-Y: accept paste */ accept_paste = 1; } else if (gui_key_paste_pending && (buffer[i] == 14)) { /* ctrl-N: cancel paste */ cancel_paste = 1; } else { gui_key_buffer_add (buffer[i]); text_added_to_buffer = 1; } } } if (gui_key_paste_pending) { if (accept_paste) { /* user is OK for pasting text, let's paste! */ gui_key_paste_accept (); } else if (cancel_paste) { /* user doesn't want to paste text: clear whole buffer! */ gui_key_paste_cancel (); } else if (text_added_to_buffer) { /* new text received while asking for paste, update message */ gui_input_paste_pending_signal (); } } else { if (!gui_key_paste_bracketed) { pos = gui_key_buffer_search (0, -1, GUI_KEY_BRACKETED_PASTE_START); if (pos >= 0) { gui_key_buffer_remove (pos, GUI_KEY_BRACKETED_PASTE_LENGTH); gui_key_paste_bracketed_start (); } } if (!gui_key_paste_bracketed) gui_key_paste_check (0); } gui_key_flush ((accept_paste) ? 1 : 0); if (gui_key_paste_bracketed) { pos = gui_key_buffer_search (0, -1, GUI_KEY_BRACKETED_PASTE_END); if (pos >= 0) { /* remove the code for end of bracketed paste (ESC[201~) */ gui_key_buffer_remove (pos, GUI_KEY_BRACKETED_PASTE_LENGTH); /* remove final newline (if needed) */ gui_key_paste_remove_newline (); /* replace tabs by spaces */ gui_key_paste_replace_tabs (); /* stop bracketed mode */ gui_key_paste_bracketed_timer_remove (); gui_key_paste_bracketed_stop (); /* if paste confirmation not displayed, flush buffer now */ if (!gui_key_paste_pending) gui_key_flush (1); } } return WEECHAT_RC_OK; }
void gui_key_flush (int paste) { int i, key, last_key_used, insert_ok, undo_done; static char key_str[64] = { '\0' }; static int length_key_str = 0; char key_temp[2], *key_utf, *input_old, *ptr_char, *next_char, *ptr_error; char utf_partial_char[16]; struct t_gui_buffer *old_buffer; /* if paste pending or bracketed paste detected, just return */ if (gui_key_paste_pending || gui_key_paste_bracketed) return; /* if buffer is empty, just return */ if (gui_key_buffer_size == 0) return; /* * if there's no paste pending, then we use buffer and do actions * according to keys */ gui_key_last_activity_time = time (NULL); last_key_used = -1; undo_done = 0; old_buffer = NULL; for (i = 0; i < gui_key_buffer_size; i++) { key = gui_key_buffer[i]; insert_ok = 1; utf_partial_char[0] = '\0'; if (gui_mouse_event_pending || (key < 32) || (key == 127)) { if (gui_mouse_event_pending) { insert_ok = 0; key_str[0] = (char)key; key_str[1] = '\0'; length_key_str = 1; } else if (key < 32) { insert_ok = 0; key_str[0] = '\x01'; key_str[1] = (char)key + '@'; key_str[2] = '\0'; length_key_str = 2; } else if (key == 127) { key_str[0] = '\x01'; key_str[1] = '?'; key_str[2] = '\0'; length_key_str = 2; } } else { if (local_utf8) { key_str[length_key_str] = (char)key; key_str[length_key_str + 1] = '\0'; length_key_str++; /* * replace invalid chars by "?", but NOT last char of * string, if it is incomplete UTF-8 char (another char * will be added to the string on next iteration) */ ptr_char = key_str; while (ptr_char && ptr_char[0]) { (void) utf8_is_valid (ptr_char, -1, &ptr_error); if (!ptr_error) break; next_char = (char *)utf8_next_char (ptr_error); if (next_char && next_char[0]) { ptr_char = ptr_error; while (ptr_char < next_char) { ptr_char[0] = '?'; ptr_char++; } } else { strcpy (utf_partial_char, ptr_char); ptr_char[0] = '\0'; break; } ptr_char = next_char; } } else { /* convert input to UTF-8 */ key_temp[0] = (char)key; key_temp[1] = '\0'; key_utf = string_iconv_to_internal (NULL, key_temp); strcat (key_str, key_utf); } } if (key_str[0]) { (void) hook_signal_send ("key_pressed", WEECHAT_HOOK_SIGNAL_STRING, key_str); if (gui_current_window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED) input_old = (gui_current_window->buffer->input_buffer) ? strdup (gui_current_window->buffer->input_buffer) : strdup (""); else input_old = NULL; old_buffer = gui_current_window->buffer; if ((gui_key_pressed (key_str) != 0) && (insert_ok) && (!gui_cursor_mode)) { if (!paste || !undo_done) gui_buffer_undo_snap (gui_current_window->buffer); gui_input_insert_string (gui_current_window->buffer, key_str, -1); gui_input_text_changed_modifier_and_signal (gui_current_window->buffer, (!paste || !undo_done) ? 1 : 0, 1); /* stop completion */ undo_done = 1; } /* incremental text search in buffer */ if ((old_buffer == gui_current_window->buffer) && (gui_current_window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED) && ((input_old == NULL) || (gui_current_window->buffer->input_buffer == NULL) || (strcmp (input_old, gui_current_window->buffer->input_buffer) != 0))) { /* * if following conditions are all true, then do not search * again (search will not find any result and can take some time * on a buffer with many lines): * - old search was not successful * - searching a string (not a regex) * - current input is longer than old input * - beginning of current input is exactly equal to old input. */ if (!gui_current_window->buffer->text_search_found && !gui_current_window->buffer->text_search_regex && (input_old != NULL) && (input_old[0]) && (gui_current_window->buffer->input_buffer != NULL) && (gui_current_window->buffer->input_buffer[0]) && (strlen (gui_current_window->buffer->input_buffer) > strlen (input_old)) && (strncmp (gui_current_window->buffer->input_buffer, input_old, strlen (input_old)) == 0)) { /* * do not search text in buffer, just alert about text not * found */ if (CONFIG_BOOLEAN(config_look_search_text_not_found_alert)) { fprintf (stderr, "\a"); fflush (stderr); } } else { gui_window_search_restart (gui_current_window); } } if (input_old) free (input_old); } /* prepare incomplete UTF-8 char for next iteration */ if (utf_partial_char[0]) strcpy (key_str, utf_partial_char); else key_str[0] = '\0'; length_key_str = strlen (key_str); /* set last key used in buffer if combo buffer is empty */ if (gui_key_grab || gui_mouse_event_pending || !gui_key_combo_buffer[0]) last_key_used = i; } if (last_key_used == gui_key_buffer_size - 1) gui_key_buffer_reset (); else if (last_key_used >= 0) gui_key_buffer_remove (0, last_key_used + 1); if (!gui_key_grab && !gui_mouse_event_pending) gui_key_combo_buffer[0] = '\0'; }
struct t_gui_filter * gui_filter_new (int enabled, const char *name, const char *buffer_name, const char *tags, const char *regex) { struct t_gui_filter *new_filter; regex_t *regex1, *regex2; char *pos_tab, *regex_prefix, **tags_array, buf[512], str_error[512]; const char *ptr_start_regex, *pos_regex_message; int i, rc; if (!name || !buffer_name || !tags || !regex) { gui_filter_new_error (name, _("not enough arguments")); return NULL; } if (gui_filter_search_by_name (name)) { gui_filter_new_error (name, _("a filter with same name already exists")); return NULL; } ptr_start_regex = regex; if ((ptr_start_regex[0] == '!') || ((ptr_start_regex[0] == '\\') && (ptr_start_regex[1] == '!'))) { ptr_start_regex++; } regex1 = NULL; regex2 = NULL; if (strcmp (ptr_start_regex, "*") != 0) { pos_tab = strstr (ptr_start_regex, "\\t"); if (pos_tab) { regex_prefix = string_strndup (ptr_start_regex, pos_tab - ptr_start_regex); pos_regex_message = pos_tab + 2; } else { regex_prefix = NULL; pos_regex_message = ptr_start_regex; } if (regex_prefix && regex_prefix[0]) { regex1 = malloc (sizeof (*regex1)); if (regex1) { rc = string_regcomp (regex1, regex_prefix, REG_EXTENDED | REG_ICASE | REG_NOSUB); if (rc != 0) { regerror (rc, regex1, buf, sizeof (buf)); snprintf (str_error, sizeof (str_error), /* TRANSLATORS: %s is the error returned by regerror */ _("invalid regular expression (%s)"), buf); gui_filter_new_error (name, str_error); free (regex_prefix); free (regex1); return NULL; } } } if (pos_regex_message && pos_regex_message[0]) { regex2 = malloc (sizeof (*regex2)); if (regex2) { rc = string_regcomp (regex2, pos_regex_message, REG_EXTENDED | REG_ICASE | REG_NOSUB); if (rc != 0) { regerror (rc, regex2, buf, sizeof (buf)); snprintf (str_error, sizeof (str_error), /* TRANSLATORS: %s is the error returned by regerror */ _("invalid regular expression (%s)"), buf); gui_filter_new_error (name, str_error); if (regex_prefix) free (regex_prefix); if (regex1) { regfree (regex1); free (regex1); } free (regex2); return NULL; } } } if (regex_prefix) free (regex_prefix); } /* create new filter */ new_filter = malloc (sizeof (*new_filter)); if (new_filter) { /* init filter */ new_filter->enabled = enabled; new_filter->name = strdup (name); new_filter->buffer_name = strdup ((buffer_name) ? buffer_name : "*"); new_filter->buffers = string_split (new_filter->buffer_name, ",", 0, 0, &new_filter->num_buffers); new_filter->tags = (tags) ? strdup (tags) : NULL; new_filter->tags_count = 0; new_filter->tags_array = NULL; if (new_filter->tags) { tags_array = string_split (new_filter->tags, ",", 0, 0, &new_filter->tags_count); if (tags_array) { new_filter->tags_array = malloc (new_filter->tags_count * sizeof (*new_filter->tags_array)); if (new_filter->tags_array) { for (i = 0; i < new_filter->tags_count; i++) { new_filter->tags_array[i] = string_split (tags_array[i], "+", 0, 0, NULL); } } string_free_split (tags_array); } } new_filter->regex = strdup (regex); new_filter->regex_prefix = regex1; new_filter->regex_message = regex2; /* add filter to filters list */ new_filter->prev_filter = last_gui_filter; if (gui_filters) last_gui_filter->next_filter = new_filter; else gui_filters = new_filter; last_gui_filter = new_filter; new_filter->next_filter = NULL; (void) hook_signal_send ("filter_added", WEECHAT_HOOK_SIGNAL_POINTER, new_filter); } else { gui_filter_new_error (name, _("not enough memory")); } return new_filter; }
struct t_gui_filter * gui_filter_new (int enabled, const char *name, const char *buffer_name, const char *tags, const char *regex) { struct t_gui_filter *new_filter; regex_t *regex1, *regex2; char *pos_tab, *regex_prefix; const char *ptr_start_regex, *pos_regex_message; if (!name || !buffer_name || !tags || !regex) return NULL; if (gui_filter_search_by_name (name)) return NULL; ptr_start_regex = regex; if ((ptr_start_regex[0] == '!') || ((ptr_start_regex[0] == '\\') && (ptr_start_regex[1] == '!'))) { ptr_start_regex++; } regex1 = NULL; regex2 = NULL; if (strcmp (ptr_start_regex, "*") != 0) { pos_tab = strstr (ptr_start_regex, "\\t"); if (pos_tab) { regex_prefix = string_strndup (ptr_start_regex, pos_tab - ptr_start_regex); pos_regex_message = pos_tab + 2; } else { regex_prefix = NULL; pos_regex_message = ptr_start_regex; } if (regex_prefix) { regex1 = malloc (sizeof (*regex1)); if (regex1) { if (string_regcomp (regex1, regex_prefix, REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0) { free (regex_prefix); free (regex1); return NULL; } } } regex2 = malloc (sizeof (*regex2)); if (regex2) { if (string_regcomp (regex2, pos_regex_message, REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0) { if (regex_prefix) free (regex_prefix); if (regex1) free (regex1); free (regex2); return NULL; } } if (regex_prefix) free (regex_prefix); } /* create new filter */ new_filter = malloc (sizeof (*new_filter)); if (new_filter) { /* init filter */ new_filter->enabled = enabled; new_filter->name = strdup (name); new_filter->buffer_name = strdup ((buffer_name) ? buffer_name : "*"); new_filter->buffers = string_split (new_filter->buffer_name, ",", 0, 0, &new_filter->num_buffers); if (tags) { new_filter->tags = (tags) ? strdup (tags) : NULL; new_filter->tags_array = string_split (tags, ",", 0, 0, &new_filter->tags_count); } else { new_filter->tags = NULL; new_filter->tags_count = 0; new_filter->tags_array = NULL; } new_filter->regex = strdup (regex); new_filter->regex_prefix = regex1; new_filter->regex_message = regex2; /* add filter to filters list */ new_filter->prev_filter = last_gui_filter; if (gui_filters) last_gui_filter->next_filter = new_filter; else gui_filters = new_filter; last_gui_filter = new_filter; new_filter->next_filter = NULL; hook_signal_send ("filter_added", WEECHAT_HOOK_SIGNAL_POINTER, new_filter); } return new_filter; }
void gui_input_paste_pending_signal () { hook_signal_send ("input_paste_pending", WEECHAT_HOOK_SIGNAL_STRING, NULL); }
void gui_filter_buffer (struct t_gui_buffer *buffer, struct t_gui_line_data *line_data) { struct t_gui_line *ptr_line; struct t_gui_line_data *ptr_line_data; struct t_gui_window *ptr_window; int lines_changed, line_displayed, lines_hidden; lines_changed = 0; lines_hidden = buffer->lines->lines_hidden; if (!line_data) buffer->lines->prefix_max_length = CONFIG_INTEGER(config_look_prefix_align_min); ptr_line = buffer->lines->first_line; while (ptr_line || line_data) { ptr_line_data = (line_data) ? line_data : ptr_line->data; line_displayed = gui_filter_check_line (ptr_line_data); if (line_displayed && (ptr_line_data->prefix_length > buffer->lines->prefix_max_length)) { buffer->lines->prefix_max_length = ptr_line_data->prefix_length; } if (ptr_line_data->displayed != line_displayed) { lines_changed = 1; lines_hidden += (line_displayed) ? -1 : 1; } ptr_line_data->displayed = line_displayed; if (line_data) break; ptr_line = ptr_line->next_line; } if (line_data) line_data->buffer->lines->prefix_max_length_refresh = 1; if (buffer->lines->lines_hidden != lines_hidden) { buffer->lines->lines_hidden = lines_hidden; hook_signal_send ("buffer_lines_hidden", WEECHAT_HOOK_SIGNAL_POINTER, buffer); } if (lines_changed) { /* force a full refresh of buffer */ gui_buffer_ask_chat_refresh (buffer, 2); /* * check that a scroll in a window displaying this buffer is not on a * hidden line (if this happens, use the previous displayed line as * scroll) */ for (ptr_window = gui_windows; ptr_window; ptr_window = ptr_window->next_window) { if ((ptr_window->buffer == buffer) && ptr_window->scroll->start_line && !ptr_window->scroll->start_line->data->displayed) { ptr_window->scroll->start_line = gui_line_get_prev_displayed (ptr_window->scroll->start_line); ptr_window->scroll->start_line_pos = 0; } } } }
void gui_input_text_cursor_moved_signal () { hook_signal_send ("input_text_cursor_moved", WEECHAT_HOOK_SIGNAL_STRING, NULL); }
void gui_line_add_y (struct t_gui_buffer *buffer, int y, const char *message) { struct t_gui_line *ptr_line, *new_line; struct t_gui_line_data *new_line_data; struct t_gui_window *ptr_win; /* search if line exists for "y" */ for (ptr_line = buffer->own_lines->first_line; ptr_line; ptr_line = ptr_line->next_line) { if (ptr_line->data->y >= y) break; } if (!ptr_line || (ptr_line->data->y > y)) { new_line = malloc (sizeof (*new_line)); if (!new_line) { log_printf (_("Not enough memory for new line")); return; } new_line_data = malloc (sizeof (*(new_line->data))); if (!new_line_data) { free (new_line); log_printf (_("Not enough memory for new line")); return; } new_line->data = new_line_data; buffer->own_lines->lines_count++; /* fill data in new line */ new_line->data->buffer = buffer; new_line->data->y = y; new_line->data->date = 0; new_line->data->date_printed = 0; new_line->data->str_time = NULL; new_line->data->tags_count = 0; new_line->data->tags_array = NULL; new_line->data->refresh_needed = 1; new_line->data->prefix = NULL; new_line->data->prefix_length = 0; new_line->data->message = NULL; new_line->data->highlight = 0; /* add line to lines list */ if (ptr_line) { /* add before line found */ new_line->prev_line = ptr_line->prev_line; new_line->next_line = ptr_line; if (ptr_line->prev_line) (ptr_line->prev_line)->next_line = new_line; else buffer->own_lines->first_line = new_line; ptr_line->prev_line = new_line; } else { /* add at end of list */ new_line->prev_line = buffer->own_lines->last_line; if (buffer->own_lines->first_line) buffer->own_lines->last_line->next_line = new_line; else buffer->own_lines->first_line = new_line; buffer->own_lines->last_line = new_line; new_line->next_line = NULL; } ptr_line = new_line; } /* set message for line */ if (ptr_line->data->message) { /* remove line from coords if the content is changing */ for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window) { gui_window_coords_remove_line (ptr_win, ptr_line); } /* free message in line */ free (ptr_line->data->message); } ptr_line->data->message = (message) ? strdup (message) : strdup (""); /* check if line is filtered or not */ ptr_line->data->displayed = gui_filter_check_line (ptr_line->data); if (!ptr_line->data->displayed) { buffer->own_lines->lines_hidden++; hook_signal_send ("buffer_lines_hidden", WEECHAT_HOOK_SIGNAL_POINTER, buffer); } ptr_line->data->refresh_needed = 1; }
struct t_gui_line * gui_line_add (struct t_gui_buffer *buffer, time_t date, time_t date_printed, const char *tags, const char *prefix, const char *message) { struct t_gui_line *new_line; struct t_gui_line_data *new_line_data; struct t_gui_window *ptr_win; char *message_for_signal; const char *nick; int notify_level, *max_notify_level, lines_removed; time_t current_time; /* * remove line(s) if necessary, according to history options: * max_lines: if > 0, keep only N lines in buffer * max_minutes: if > 0, keep only lines from last N minutes */ lines_removed = 0; current_time = time (NULL); while (buffer->own_lines->first_line && (((CONFIG_INTEGER(config_history_max_buffer_lines_number) > 0) && (buffer->own_lines->lines_count + 1 > CONFIG_INTEGER(config_history_max_buffer_lines_number))) || ((CONFIG_INTEGER(config_history_max_buffer_lines_minutes) > 0) && (current_time - buffer->own_lines->first_line->data->date_printed > CONFIG_INTEGER(config_history_max_buffer_lines_minutes) * 60)))) { gui_line_free (buffer, buffer->own_lines->first_line); lines_removed++; } /* create new line */ new_line = malloc (sizeof (*new_line)); if (!new_line) { log_printf (_("Not enough memory for new line")); return NULL; } /* create data for line */ new_line_data = malloc (sizeof (*(new_line->data))); if (!new_line_data) { free (new_line); log_printf (_("Not enough memory for new line")); return NULL; } new_line->data = new_line_data; /* fill data in new line */ new_line->data->buffer = buffer; new_line->data->y = -1; new_line->data->date = date; new_line->data->date_printed = date_printed; new_line->data->str_time = gui_chat_get_time_string (date); gui_line_tags_alloc (new_line->data, tags); new_line->data->refresh_needed = 0; new_line->data->prefix = (prefix) ? (char *)string_shared_get (prefix) : ((date != 0) ? (char *)string_shared_get ("") : NULL); new_line->data->prefix_length = (prefix) ? gui_chat_strlen_screen (prefix) : 0; new_line->data->message = (message) ? strdup (message) : strdup (""); /* get notify level and max notify level for nick in buffer */ notify_level = gui_line_get_notify_level (new_line); max_notify_level = NULL; nick = gui_line_get_nick_tag (new_line); if (nick) max_notify_level = hashtable_get (buffer->hotlist_max_level_nicks, nick); if (max_notify_level && (*max_notify_level < notify_level)) notify_level = *max_notify_level; if (notify_level == GUI_HOTLIST_HIGHLIGHT) new_line->data->highlight = 1; else if (max_notify_level && (*max_notify_level < GUI_HOTLIST_HIGHLIGHT)) new_line->data->highlight = 0; else new_line->data->highlight = gui_line_has_highlight (new_line); /* check if line is filtered or not */ new_line->data->displayed = gui_filter_check_line (new_line->data); /* add line to lines list */ gui_line_add_to_list (buffer->own_lines, new_line); /* update hotlist and/or send signals for line */ if (new_line->data->displayed) { if (new_line->data->highlight) { (void) gui_hotlist_add (buffer, GUI_HOTLIST_HIGHLIGHT, NULL); if (!weechat_upgrading) { message_for_signal = gui_chat_build_string_prefix_message (new_line); if (message_for_signal) { hook_signal_send ("weechat_highlight", WEECHAT_HOOK_SIGNAL_STRING, message_for_signal); free (message_for_signal); } } } else { if (!weechat_upgrading && (notify_level == GUI_HOTLIST_PRIVATE)) { message_for_signal = gui_chat_build_string_prefix_message (new_line); if (message_for_signal) { hook_signal_send ("weechat_pv", WEECHAT_HOOK_SIGNAL_STRING, message_for_signal); free (message_for_signal); } } if (notify_level >= GUI_HOTLIST_MIN) (void) gui_hotlist_add (buffer, notify_level, NULL); } } else { buffer->own_lines->lines_hidden++; if (buffer->mixed_lines) buffer->mixed_lines->lines_hidden++; hook_signal_send ("buffer_lines_hidden", WEECHAT_HOOK_SIGNAL_POINTER, buffer); } /* add mixed line, if buffer is attached to at least one other buffer */ if (buffer->mixed_lines) { gui_line_mixed_add (buffer->mixed_lines, new_line->data); } /* * if some lines were removed, force a full refresh if at least one window * is displaying buffer and that number of lines in buffer is lower than * window height */ if (lines_removed > 0) { for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window) { if ((ptr_win->buffer == buffer) && (buffer->own_lines->lines_count < ptr_win->win_chat_height)) { gui_buffer_ask_chat_refresh (buffer, 2); break; } } } hook_signal_send ("buffer_line_added", WEECHAT_HOOK_SIGNAL_POINTER, new_line); return new_line; }
void gui_hotlist_changed_signal (struct t_gui_buffer *buffer) { (void) hook_signal_send ("hotlist_changed", WEECHAT_HOOK_SIGNAL_POINTER, buffer); }
void gui_input_search_signal () { hook_signal_send ("input_search", WEECHAT_HOOK_SIGNAL_STRING, NULL); }