diff options
Diffstat (limited to 'src')
47 files changed, 1599 insertions, 968 deletions
diff --git a/src/core/wee-command.c b/src/core/wee-command.c index d25571736..ee56040ec 100644 --- a/src/core/wee-command.c +++ b/src/core/wee-command.c @@ -399,15 +399,22 @@ command_clear (void *data, struct t_gui_buffer *buffer, void command_debug_display_windows (struct t_gui_window_tree *tree, int indent) { + char format[128]; + if (tree) { if (tree->window) { /* leaf */ + snprintf (format, + sizeof (format), + "%%-%dsleaf: 0x%%X (parent:0x%%X), win=0x%%X, " + "child1=0x%%X, child2=0x%%X, %%d,%%d %%dx%%d, " + "%%d%%%%x%%d%%%%", + indent * 2); gui_chat_printf (NULL, - "leaf: %X (parent:%X), win=%X, child1=%X, " - "child2=%X, %d,%d %dx%d, %d%%x%d%%", - tree, tree->parent_node, tree->window, + format, + " ", tree, tree->parent_node, tree->window, tree->child1, tree->child2, tree->window->win_x, tree->window->win_y, tree->window->win_width, tree->window->win_height, @@ -417,10 +424,14 @@ command_debug_display_windows (struct t_gui_window_tree *tree, int indent) else { /* node */ + snprintf (format, + sizeof (format), + "%%-%dsnode: 0x%%X (parent:0x%%X), win=0x%%X, " + "child1=0x%%X, child2=0x%%X)", + indent * 2); gui_chat_printf (NULL, - "node: %X (parent:%X), win=%X, child1=%X, " - "child2=%X)", - tree, tree->parent_node, tree->window, + format, + " ", tree, tree->parent_node, tree->window, tree->child1, tree->child2); } @@ -464,11 +475,7 @@ command_debug (void *data, struct t_gui_buffer *buffer, } else { - gui_chat_printf (NULL, - _("%sError: unknown option for \"%s\" command"), - gui_chat_prefix[GUI_CHAT_PREFIX_ERROR], - "debug"); - return WEECHAT_RC_ERROR; + hook_signal_send ("debug", argv_eol[1]); } } @@ -1928,12 +1935,14 @@ command_init () command_clear, NULL); hook_command (NULL, "debug", N_("print debug messages"), - N_("dump | buffer | windows"), + N_("dump | buffer | windows | text"), N_(" dump: save memory dump in WeeChat log file (same " "dump is written when WeeChat crashes)\n" " buffer: dump buffer content with hexadecimal values " "in log file\n" - "windows: display windows tree"), + "windows: display windows tree\n" + " text: send \"debug\" signal with \"text\" as " + "arguments"), "dump|buffer|windows", command_debug, NULL); hook_command (NULL, "help", diff --git a/src/core/wee-config-file.c b/src/core/wee-config-file.c index 5753a16e3..7d888b6bc 100644 --- a/src/core/wee-config-file.c +++ b/src/core/wee-config-file.c @@ -273,10 +273,8 @@ config_file_new_option (struct t_config_section *section, char *name, *((int *)new_option->value) = int_value; break; case CONFIG_OPTION_INTEGER: - if (string_values) - new_option->string_values = string_explode (string_values, - "|", 0, 0, - &argc); + new_option->string_values = (string_values) ? + string_explode (string_values, "|", 0, 0, &argc) : NULL; if (new_option->string_values) { new_option->min = 0; diff --git a/src/core/wee-config.c b/src/core/wee-config.c index c74d96f1a..c3bb529d7 100644 --- a/src/core/wee-config.c +++ b/src/core/wee-config.c @@ -145,6 +145,7 @@ struct t_config_option *config_color_input_text_not_found; struct t_config_option *config_color_input_actions; struct t_config_option *config_color_nicklist; struct t_config_option *config_color_nicklist_bg; +struct t_config_option *config_color_nicklist_group; struct t_config_option *config_color_nicklist_away; struct t_config_option *config_color_nicklist_prefix1; struct t_config_option *config_color_nicklist_prefix2; @@ -309,9 +310,10 @@ config_change_color () void config_change_nicks_colors () { + /* struct t_gui_buffer *ptr_buffer; struct t_gui_nick *ptr_nick; - + for (ptr_buffer = gui_buffers; ptr_buffer; ptr_buffer = ptr_buffer->next_buffer) { @@ -320,10 +322,11 @@ config_change_nicks_colors () for (ptr_nick = ptr_buffer->nicks; ptr_nick; ptr_nick = ptr_nick->next_nick) { - //gui_nick_find_color (ptr_nick); + gui_nick_find_color (ptr_nick); } } } + */ } /* @@ -954,6 +957,10 @@ config_weechat_init () ptr_section, "color_nicklist_bg", "color", N_("background color for nicklist"), NULL, -1, 0, "default", &config_change_color); + config_color_nicklist_group = config_file_new_option ( + ptr_section, "color_nicklist_group", "color", + N_("text color for groups in nicklist"), + NULL, GUI_COLOR_NICKLIST_GROUP, 0, "green", &config_change_color); config_color_nicklist_away = config_file_new_option ( ptr_section, "color_nicklist_away", "color", N_("text color for away nicknames"), diff --git a/src/core/wee-config.h b/src/core/wee-config.h index 15de988d6..0787f5613 100644 --- a/src/core/wee-config.h +++ b/src/core/wee-config.h @@ -131,6 +131,7 @@ extern struct t_config_option *config_color_input_text_not_found; extern struct t_config_option *config_color_input_actions; extern struct t_config_option *config_color_nicklist; extern struct t_config_option *config_color_nicklist_bg; +extern struct t_config_option *config_color_nicklist_group; extern struct t_config_option *config_color_nicklist_away; extern struct t_config_option *config_color_nicklist_prefix1; extern struct t_config_option *config_color_nicklist_prefix2; diff --git a/src/core/wee-hook.c b/src/core/wee-hook.c index db2b3dd72..ab4b6c093 100644 --- a/src/core/wee-hook.c +++ b/src/core/wee-hook.c @@ -638,26 +638,43 @@ hook_fd (struct t_weechat_plugin *plugin, int fd, int flag_read, /* * hook_fd_set: fill sets according to hd hooked + * return highest fd set */ -void +int hook_fd_set (fd_set *read_fds, fd_set *write_fds, fd_set *exception_fds) { struct t_hook *ptr_hook; - + int max_fd; + + max_fd = 0; for (ptr_hook = weechat_hooks[HOOK_TYPE_FD]; ptr_hook; ptr_hook = ptr_hook->next_hook) { if (!ptr_hook->deleted) { if (HOOK_FD(ptr_hook, flags) & HOOK_FD_FLAG_READ) + { FD_SET (HOOK_FD(ptr_hook, fd), read_fds); + if (HOOK_FD(ptr_hook, fd) > max_fd) + max_fd = HOOK_FD(ptr_hook, fd); + } if (HOOK_FD(ptr_hook, flags) & HOOK_FD_FLAG_WRITE) + { FD_SET (HOOK_FD(ptr_hook, fd), write_fds); + if (HOOK_FD(ptr_hook, fd) > max_fd) + max_fd = HOOK_FD(ptr_hook, fd); + } if (HOOK_FD(ptr_hook, flags) & HOOK_FD_FLAG_EXCEPTION) + { FD_SET (HOOK_FD(ptr_hook, fd), exception_fds); + if (HOOK_FD(ptr_hook, fd) > max_fd) + max_fd = HOOK_FD(ptr_hook, fd); + } } } + + return max_fd; } /* @@ -678,7 +695,7 @@ hook_fd_exec (fd_set *read_fds, fd_set *write_fds, fd_set *exception_fds) if (!ptr_hook->deleted && !ptr_hook->running - && (((HOOK_FD(ptr_hook, flags)& HOOK_FD_FLAG_READ) + && (((HOOK_FD(ptr_hook, flags) & HOOK_FD_FLAG_READ) && (FD_ISSET(HOOK_FD(ptr_hook, fd), read_fds))) || ((HOOK_FD(ptr_hook, flags) & HOOK_FD_FLAG_WRITE) && (FD_ISSET(HOOK_FD(ptr_hook, fd), write_fds))) @@ -1172,7 +1189,9 @@ hook_print_log () { log_printf (""); log_printf ("[hook (addr:0x%X)]", ptr_hook); - log_printf (" plugin . . . . . . . . : 0x%X", ptr_hook->plugin); + log_printf (" plugin . . . . . . . . : 0x%X ('%s')", + ptr_hook->plugin, + (ptr_hook->plugin) ? ptr_hook->plugin->name : ""); log_printf (" deleted. . . . . . . . : %d", ptr_hook->deleted); log_printf (" running. . . . . . . . : %d", ptr_hook->running); switch (ptr_hook->type) diff --git a/src/core/wee-hook.h b/src/core/wee-hook.h index c725d8661..2af874dd9 100644 --- a/src/core/wee-hook.h +++ b/src/core/wee-hook.h @@ -173,8 +173,8 @@ extern struct t_hook *hook_fd (struct t_weechat_plugin *plugin, int fd, int flag_exception, t_hook_callback_fd * callback, void *callback_data); -extern void hook_fd_set (fd_set *read_fds, fd_set *write_fds, - fd_set *exception_fds); +extern int hook_fd_set (fd_set *read_fds, fd_set *write_fds, + fd_set *exception_fds); extern void hook_fd_exec (fd_set *read_fds, fd_set *write_fds, fd_set *exception_fds); extern struct t_hook *hook_print (struct t_weechat_plugin *plugin, @@ -188,7 +188,7 @@ extern struct t_hook *hook_signal (struct t_weechat_plugin *plugin, char *signal, t_hook_callback_signal *callback, void *callback_data); -extern void hook_signal_send (char *signal, void *signal_date); +extern void hook_signal_send (char *signal, void *signal_data); extern struct t_hook *hook_config (struct t_weechat_plugin *, char *type, char *option, t_hook_callback_config *callback, diff --git a/src/core/wee-list.c b/src/core/wee-list.c index 77e3c1533..5b6f6d0ba 100644 --- a/src/core/wee-list.c +++ b/src/core/wee-list.c @@ -225,6 +225,21 @@ weelist_get (struct t_weelist *weelist, int position) } /* + * weelist_set: set a new value for an item + */ + +void +weelist_set (struct t_weelist_item *item, char *new_value) +{ + if (!item || !new_value) + return; + + if (item->data) + free (item->data); + item->data = strdup (new_value); +} + +/* * weelist_next: get next item */ diff --git a/src/core/wee-list.h b/src/core/wee-list.h index 852026aba..c1bae7233 100644 --- a/src/core/wee-list.h +++ b/src/core/wee-list.h @@ -47,6 +47,7 @@ extern struct t_weelist_item *weelist_casesearch (struct t_weelist *weelist, char *data); extern struct t_weelist_item *weelist_get (struct t_weelist *weelist, int position); +extern void weelist_set (struct t_weelist_item *item, char *new_value); extern struct t_weelist_item *weelist_next (struct t_weelist_item *item); extern struct t_weelist_item *weelist_prev (struct t_weelist_item *item); extern char *weelist_string (struct t_weelist_item *item); diff --git a/src/core/wee-string.c b/src/core/wee-string.c index 902d57764..22128117f 100644 --- a/src/core/wee-string.c +++ b/src/core/wee-string.c @@ -385,7 +385,7 @@ string_explode (char *string, char *separators, int keep_eol, i = 1; while ((ptr = strpbrk (ptr, separators))) { - while (strchr (separators, ptr[0]) != NULL) + while (ptr[0] && (strchr (separators, ptr[0]) != NULL)) ptr++; i++; } @@ -402,7 +402,7 @@ string_explode (char *string, char *separators, int keep_eol, for (i = 0; i < n_items; i++) { - while (strchr (separators, ptr1[0]) != NULL) + while (ptr1[0] && (strchr (separators, ptr1[0]) != NULL)) ptr1++; if (i == (n_items - 1) || (ptr2 = strpbrk (ptr1, separators)) == NULL) if ((ptr2 = strchr (ptr1, '\r')) == NULL) diff --git a/src/core/wee-util.c b/src/core/wee-util.c index 86f5f6b93..4223e7f34 100644 --- a/src/core/wee-util.c +++ b/src/core/wee-util.c @@ -29,6 +29,7 @@ #include <sys/types.h> #include <sys/stat.h> #include <dirent.h> +#include <signal.h> #include "weechat.h" #include "wee-util.h" @@ -119,6 +120,20 @@ util_get_time_length (char *time_format) return strlen (text_time); } +/* + * util_catch_signal: catch a signal + */ + +void +util_catch_signal (int signum, void (*handler)(int)) +{ + struct sigaction act; + + sigemptyset (&act.sa_mask); + act.sa_flags = 0; + act.sa_handler = handler; + sigaction(signum, &act, NULL); +} /* * util_create_dir: create a directory diff --git a/src/core/wee-util.h b/src/core/wee-util.h index 66d4bce0f..5f65666a2 100644 --- a/src/core/wee-util.h +++ b/src/core/wee-util.h @@ -24,6 +24,7 @@ extern int util_timeval_cmp (struct timeval *tv1, struct timeval *tv2); extern long util_timeval_diff (struct timeval *tv1, struct timeval *tv2); extern void util_timeval_add (struct timeval *tv, long interval); extern int util_get_time_length (char *time_format); +extern void util_catch_signal (int signum, void (*handler)(int)); extern int util_create_dir (char *directory, int permissions); extern void util_exec_on_files (char *directory, void *data, int (*callback)(void *data, char *filename)); diff --git a/src/core/weechat.c b/src/core/weechat.c index abe39e365..37b4cfb16 100644 --- a/src/core/weechat.c +++ b/src/core/weechat.c @@ -582,10 +582,11 @@ main (int argc, char *argv[]) #endif utf8_init (); - signal (SIGINT, SIG_IGN); /* ignore SIGINT signal */ - signal (SIGQUIT, SIG_IGN); /* ignore SIGQUIT signal */ - signal (SIGPIPE, SIG_IGN); /* ignore SIGPIPE signal */ - signal (SIGSEGV, weechat_sigsegv); /* crash dump when SIGSEGV received */ + util_catch_signal (SIGINT, SIG_IGN); /* ignore SIGINT signal */ + util_catch_signal (SIGQUIT, SIG_IGN); /* ignore SIGQUIT signal */ + util_catch_signal (SIGPIPE, SIG_IGN); /* ignore SIGPIPE signal */ + util_catch_signal (SIGSEGV, + &weechat_sigsegv); /* crash dump for SIGSEGV signal */ hook_init (); /* initialize hooks */ gui_main_pre_init (&argc, &argv); /* pre-initiliaze interface */ weechat_init_vars (); /* initialize some variables */ diff --git a/src/gui/curses/gui-curses-color.c b/src/gui/curses/gui-curses-color.c index 71a9c63f4..c850f4a82 100644 --- a/src/gui/curses/gui-curses-color.c +++ b/src/gui/curses/gui-curses-color.c @@ -398,6 +398,7 @@ gui_color_init_weechat () gui_color[GUI_COLOR_INPUT_ACTIONS] = gui_color_build (GUI_COLOR_INPUT_ACTIONS, CONFIG_COLOR(config_color_input_actions), CONFIG_COLOR(config_color_input_bg)); gui_color[GUI_COLOR_NICKLIST] = gui_color_build (GUI_COLOR_NICKLIST, CONFIG_COLOR(config_color_nicklist), CONFIG_COLOR(config_color_nicklist_bg)); + gui_color[GUI_COLOR_NICKLIST_GROUP] = gui_color_build (GUI_COLOR_NICKLIST_GROUP, CONFIG_COLOR(config_color_nicklist_group), CONFIG_COLOR(config_color_nicklist_bg)); gui_color[GUI_COLOR_NICKLIST_AWAY] = gui_color_build (GUI_COLOR_NICKLIST_AWAY, CONFIG_COLOR(config_color_nicklist_away), CONFIG_COLOR(config_color_nicklist_bg)); gui_color[GUI_COLOR_NICKLIST_PREFIX1] = gui_color_build (GUI_COLOR_NICKLIST_PREFIX1, CONFIG_COLOR(config_color_nicklist_prefix1), CONFIG_COLOR(config_color_nicklist_bg)); gui_color[GUI_COLOR_NICKLIST_PREFIX2] = gui_color_build (GUI_COLOR_NICKLIST_PREFIX2, CONFIG_COLOR(config_color_nicklist_prefix2), CONFIG_COLOR(config_color_nicklist_bg)); diff --git a/src/gui/curses/gui-curses-infobar.c b/src/gui/curses/gui-curses-infobar.c index c26db5840..9ad599d0b 100644 --- a/src/gui/curses/gui-curses-infobar.c +++ b/src/gui/curses/gui-curses-infobar.c @@ -185,7 +185,7 @@ gui_infobar_highlight_timer_cb (void *data) if (gui_ok) { - if (gui_infobar && gui_infobar->remaining_time > 0) + if (gui_infobar && (gui_infobar->remaining_time > 0)) { gui_infobar->remaining_time--; if (gui_infobar->remaining_time == 0) @@ -196,7 +196,10 @@ gui_infobar_highlight_timer_cb (void *data) } /* remove this timer if there's no more data for infobar */ if (!gui_infobar) + { unhook (gui_infobar_highlight_timer); + gui_infobar_highlight_timer = NULL; + } } return WEECHAT_RC_OK; diff --git a/src/gui/curses/gui-curses-keyboard.c b/src/gui/curses/gui-curses-keyboard.c index 89b5ed35b..179ce48c0 100644 --- a/src/gui/curses/gui-curses-keyboard.c +++ b/src/gui/curses/gui-curses-keyboard.c @@ -30,6 +30,7 @@ #include "../../core/wee-config.h" #include "../../core/wee-utf8.h" #include "../../core/wee-string.h" +#include "../../plugins/plugin.h" #include "../gui-keyboard.h" #include "../gui-buffer.h" #include "../gui-color.h" @@ -156,83 +157,6 @@ gui_keyboard_default_bindings () } /* - * gui_keyboard_read: read keyboard chars - */ - -void -gui_keyboard_read () -{ - int key, accept_paste, cancel_paste, text_added_to_buffer, paste_lines; - - accept_paste = 0; - cancel_paste = 0; - text_added_to_buffer = 0; - - while (1) - { - key = getch (); - - if (key == ERR) - break; - -#ifdef KEY_RESIZE - if (key == KEY_RESIZE) - continue; -#endif - if (gui_keyboard_paste_pending) - { - /* ctrl-Y: accept paste */ - if (key == 25) - { - accept_paste = 1; - break; - } - /* ctrl-N: cancel paste */ - else if (key == 14) - { - cancel_paste = 1; - break; - } - } - - gui_keyboard_buffer_add (key); - 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 (); - gui_input_draw (gui_current_window->buffer, 1); - } - /* user doesn't want to paste text: clear whole buffer! */ - else if (cancel_paste) - { - gui_keyboard_paste_cancel (); - gui_input_draw (gui_current_window->buffer, 1); - } - else if (text_added_to_buffer) - gui_input_draw (gui_current_window->buffer, 1); - } - 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_draw (gui_current_window->buffer, 1); - } - } - } -} - -/* * gui_keyboard_flush: flush keyboard buffer */ @@ -410,3 +334,87 @@ gui_keyboard_flush () gui_keyboard_buffer_reset (); } } + +/* + * gui_keyboard_read_cb: read keyboard chars + */ + +int +gui_keyboard_read_cb (void *data) +{ + int key, accept_paste, cancel_paste, text_added_to_buffer, paste_lines; + + /* make C compiler happy */ + (void) data; + + accept_paste = 0; + cancel_paste = 0; + text_added_to_buffer = 0; + + while (1) + { + key = getch (); + + if (key == ERR) + break; + +#ifdef KEY_RESIZE + if (key == KEY_RESIZE) + continue; +#endif + if (gui_keyboard_paste_pending) + { + /* ctrl-Y: accept paste */ + if (key == 25) + { + accept_paste = 1; + break; + } + /* ctrl-N: cancel paste */ + else if (key == 14) + { + cancel_paste = 1; + break; + } + } + + gui_keyboard_buffer_add (key); + 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 (); + gui_input_draw (gui_current_window->buffer, 1); + } + /* user doesn't want to paste text: clear whole buffer! */ + else if (cancel_paste) + { + gui_keyboard_paste_cancel (); + gui_input_draw (gui_current_window->buffer, 1); + } + else if (text_added_to_buffer) + gui_input_draw (gui_current_window->buffer, 1); + } + 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_draw (gui_current_window->buffer, 1); + } + } + } + + gui_keyboard_flush (); + + return WEECHAT_RC_OK; +} diff --git a/src/gui/curses/gui-curses-main.c b/src/gui/curses/gui-curses-main.c index 53af9a02e..22bd6be4e 100644 --- a/src/gui/curses/gui-curses-main.c +++ b/src/gui/curses/gui-curses-main.c @@ -43,6 +43,7 @@ #include "../gui-infobar.h" #include "../gui-input.h" #include "../gui-history.h" +#include "../gui-nicklist.h" #include "../gui-window.h" #include "gui-curses.h" @@ -113,8 +114,6 @@ gui_main_init () if (CONFIG_BOOLEAN(config_look_set_title)) gui_window_title_set (); - - signal (SIGWINCH, gui_window_refresh_screen_sigwinch); } } @@ -135,24 +134,33 @@ gui_main_quit () void gui_main_loop () { + struct t_hook *hook_fd_keyboard; struct t_gui_buffer *ptr_buffer; struct timeval tv_timeout; fd_set read_fds, write_fds, except_fds; + int max_fd; + int ready; quit_weechat = 0; - /* if SIGTERM or SIGHUP received => quit */ - signal (SIGTERM, gui_main_quit); - signal (SIGHUP, gui_main_quit); + /* catch SIGTERM signal: quit program */ + util_catch_signal (SIGTERM, &gui_main_quit); + + /* cach SIGHUP signal: reload configuration */ + util_catch_signal (SIGHUP, &gui_main_quit); + + /* catch SIGWINCH signal: redraw screen */ + util_catch_signal (SIGWINCH, &gui_window_refresh_screen_sigwinch); + + /* hook stdin (read keyboard) */ + hook_fd_keyboard = hook_fd (NULL, STDIN_FILENO, 1, 0, 0, + &gui_keyboard_read_cb, NULL); while (!quit_weechat) { /* execute hook timers */ hook_timer_exec (); - /* infobar count down */ - - /* refresh needed ? */ if (gui_refresh_screen_needed) gui_window_refresh_screen (0); @@ -165,25 +173,32 @@ gui_main_loop () gui_chat_draw (ptr_buffer, 0); ptr_buffer->chat_refresh_needed = 0; } + if (ptr_buffer->nicklist_refresh_needed) + { + gui_nicklist_draw (ptr_buffer, 0); + ptr_buffer->nicklist_refresh_needed = 0; + } } /* wait for keyboard or network activity */ FD_ZERO (&read_fds); FD_ZERO (&write_fds); FD_ZERO (&except_fds); - hook_fd_set (&read_fds, &write_fds, &except_fds); - FD_SET (STDIN_FILENO, &read_fds); + max_fd = hook_fd_set (&read_fds, &write_fds, &except_fds); if (hook_timer_time_to_next (&tv_timeout)) - select (FD_SETSIZE, &read_fds, &write_fds, &except_fds, &tv_timeout); + ready = select (max_fd + 1, &read_fds, &write_fds, &except_fds, + &tv_timeout); else - select (FD_SETSIZE, &read_fds, &write_fds, &except_fds, NULL); - if (FD_ISSET (STDIN_FILENO, &read_fds)) + ready = select (max_fd + 1, &read_fds, &write_fds, &except_fds, + NULL); + if (ready > 0) { - gui_keyboard_read (); - gui_keyboard_flush (); + hook_fd_exec (&read_fds, &write_fds, &except_fds); } - hook_fd_exec (&read_fds, &write_fds, &except_fds); } + + /* remove keyboard hook */ + unhook (hook_fd_keyboard); } /* diff --git a/src/gui/curses/gui-curses-nicklist.c b/src/gui/curses/gui-curses-nicklist.c index c97484076..6868c089b 100644 --- a/src/gui/curses/gui-curses-nicklist.c +++ b/src/gui/curses/gui-curses-nicklist.c @@ -46,9 +46,10 @@ void gui_nicklist_draw (struct t_gui_buffer *buffer, int erase) { struct t_gui_window *ptr_win; + struct t_gui_nick_group *ptr_group; struct t_gui_nick *ptr_nick; int i, j, k, x, y, x2, max_y, column, max_length, max_chars; - int nicks_displayed; + int nicks_displayed, chars_left; char format_empty[32], *buf, *ptr_buf, *ptr_next, saved_char; if (!gui_ok || (!buffer->nicklist)) @@ -58,12 +59,12 @@ gui_nicklist_draw (struct t_gui_buffer *buffer, int erase) { if ((ptr_win->buffer == buffer) && (buffer->num_displayed > 0)) { - max_length = gui_nicklist_get_max_length (buffer); - if ((max_length != buffer->nick_max_length) + max_length = gui_nicklist_get_max_length (buffer, NULL); + if ((max_length != buffer->nicklist_max_length) || (buffer->nicklist && !GUI_CURSES(ptr_win)->win_nick) || (!buffer->nicklist && GUI_CURSES(ptr_win)->win_nick)) { - buffer->nick_max_length = max_length; + buffer->nicklist_max_length = max_length; if (gui_window_calculate_pos_size (ptr_win, 0)) { delwin (GUI_CURSES(ptr_win)->win_chat); @@ -134,8 +135,6 @@ gui_nicklist_draw (struct t_gui_buffer *buffer, int erase) } } - gui_window_set_weechat_color (GUI_CURSES(ptr_win)->win_nick, - GUI_COLOR_NICKLIST); x = 0; y = (CONFIG_BOOLEAN(config_look_nicklist_separator) && (CONFIG_INTEGER(config_look_nicklist_position) == CONFIG_LOOK_NICKLIST_BOTTOM)) ? @@ -165,17 +164,26 @@ gui_nicklist_draw (struct t_gui_buffer *buffer, int erase) else nicks_displayed = ptr_win->win_nick_height; - ptr_nick = buffer->nicks; - for (i = 0; i < ptr_win->win_nick_start; i++) + ptr_group = NULL; + ptr_nick = NULL; + gui_nicklist_get_next_item (buffer, &ptr_group, &ptr_nick); + i = 0; + while ((ptr_group || ptr_nick) && (i < ptr_win->win_nick_start)) { - if (!ptr_nick) - break; - ptr_nick = ptr_nick->next_nick; + if ((ptr_nick && ptr_nick->visible) + || (ptr_group && buffer->nicklist_display_groups + && ptr_group->visible)) + i++; + gui_nicklist_get_next_item (buffer, &ptr_group, &ptr_nick); } - if (ptr_nick) + i = 0; + while ((ptr_group || ptr_nick) && (i < nicks_displayed)) { - for (i = 0; i < nicks_displayed; i++) + if ((ptr_nick && ptr_nick->visible) + || (ptr_group && buffer->nicklist_display_groups + && ptr_group->visible)) { + i++; switch (CONFIG_INTEGER(config_look_nicklist_position)) { case CONFIG_LOOK_NICKLIST_LEFT: @@ -202,70 +210,47 @@ gui_nicklist_draw (struct t_gui_buffer *buffer, int erase) else { gui_window_set_weechat_color (GUI_CURSES(ptr_win)->win_nick, - ptr_nick->color_prefix); - mvwprintw (GUI_CURSES(ptr_win)->win_nick, y, x, "%c", - ptr_nick->prefix); - x++; - - /*if (ptr_nick->flags & IRC_NICK_CHANOWNER) + GUI_COLOR_NICKLIST); + if (ptr_nick) { + /* display spaces and prefix for nick */ + if (buffer->nicklist_display_groups) + { + for (k = 0; k < ptr_nick->group->level; k++) + { + mvwprintw (GUI_CURSES(ptr_win)->win_nick, + y, x, " "); + x++; + } + } gui_window_set_weechat_color (GUI_CURSES(ptr_win)->win_nick, - GUI_COLOR_WIN_NICK_CHANOWNER); - mvwprintw (GUI_CURSES(ptr_win)->win_nick, y, x, "~"); - x++; - } - else if (ptr_nick->flags & IRC_NICK_CHANADMIN) - { - gui_window_set_weechat_color (GUI_CURSES(ptr_win)->win_nick, GUI_COLOR_WIN_NICK_CHANADMIN); - mvwprintw (GUI_CURSES(ptr_win)->win_nick, y, x, "&"); - x++; - } - else if (ptr_nick->flags & IRC_NICK_CHANADMIN2) - { - gui_window_set_weechat_color (GUI_CURSES(ptr_win)->win_nick, GUI_COLOR_WIN_NICK_CHANADMIN); - mvwprintw (GUI_CURSES(ptr_win)->win_nick, y, x, "!"); - x++; - } - else if (ptr_nick->flags & IRC_NICK_OP) - { - gui_window_set_weechat_color (GUI_CURSES(ptr_win)->win_nick, GUI_COLOR_WIN_NICK_OP); - mvwprintw (GUI_CURSES(ptr_win)->win_nick, y, x, "@"); - x++; - } - else if (ptr_nick->flags & IRC_NICK_HALFOP) - { - gui_window_set_weechat_color (GUI_CURSES(ptr_win)->win_nick, GUI_COLOR_WIN_NICK_HALFOP); - mvwprintw (GUI_CURSES(ptr_win)->win_nick, y, x, "%%"); - x++; - } - else if (ptr_nick->flags & IRC_NICK_VOICE) - { - gui_window_set_weechat_color (GUI_CURSES(ptr_win)->win_nick, GUI_COLOR_WIN_NICK_VOICE); - mvwprintw (GUI_CURSES(ptr_win)->win_nick, y, x, "+"); - x++; - } - else if (ptr_nick->flags & IRC_NICK_CHANUSER) - { - gui_window_set_weechat_color (GUI_CURSES(ptr_win)->win_nick, GUI_COLOR_WIN_NICK_CHANUSER); - mvwprintw (GUI_CURSES(ptr_win)->win_nick, y, x, "-"); + ptr_nick->prefix_color); + mvwprintw (GUI_CURSES(ptr_win)->win_nick, + y, x, "%c", ptr_nick->prefix); x++; + + gui_window_set_weechat_color (GUI_CURSES(ptr_win)->win_nick, + ptr_nick->color); + ptr_buf = ptr_nick->name; } else { - gui_window_set_weechat_color (GUI_CURSES(ptr_win)->win_nick, GUI_COLOR_WIN_NICK); - mvwprintw (GUI_CURSES(ptr_win)->win_nick, y, x, " "); - x++; + /* display group name */ + for (k = 0; k < ptr_group->level - 1; k++) + { + mvwprintw (GUI_CURSES(ptr_win)->win_nick, + y, x, " "); + x++; + } + gui_window_set_weechat_color (GUI_CURSES(ptr_win)->win_nick, + ptr_group->color); + //wattron (GUI_CURSES(ptr_win)->win_nick, A_UNDERLINE); + ptr_buf = gui_nicklist_get_group_start (ptr_group->name); } - gui_window_set_weechat_color (GUI_CURSES(ptr_win)->win_nick, - ((config_irc_away_check > 0) && (ptr_nick->flags & IRC_NICK_AWAY)) ? - GUI_COLOR_WIN_NICK_AWAY : GUI_COLOR_WIN_NICK);*/ - - gui_window_set_weechat_color (GUI_CURSES(ptr_win)->win_nick, - ptr_nick->color_nick); wmove (GUI_CURSES(ptr_win)->win_nick, y, x); - ptr_buf = ptr_nick->nick; saved_char = '\0'; - for (k = 0; k < max_chars; k++) + chars_left = max_chars - ((ptr_nick) ? 1 : 0); + for (k = 0; k < chars_left; k++) { if (ptr_buf && ptr_buf[0]) { @@ -284,15 +269,13 @@ gui_nicklist_draw (struct t_gui_buffer *buffer, int erase) if (ptr_next) ptr_next[0] = saved_char; ptr_buf = ptr_next; + //if (!ptr_buf || !ptr_buf[0]) + // wattroff (GUI_CURSES(ptr_win)->win_nick, + // A_UNDERLINE); } else wprintw (GUI_CURSES(ptr_win)->win_nick, " "); } - - ptr_nick = ptr_nick->next_nick; - - if (!ptr_nick) - break; } y++; if ((CONFIG_INTEGER(config_look_nicklist_position) == CONFIG_LOOK_NICKLIST_TOP) || @@ -307,6 +290,7 @@ gui_nicklist_draw (struct t_gui_buffer *buffer, int erase) } } } + gui_nicklist_get_next_item (buffer, &ptr_group, &ptr_nick); } wnoutrefresh (GUI_CURSES(ptr_win)->win_nick); refresh (); diff --git a/src/gui/curses/gui-curses-window.c b/src/gui/curses/gui-curses-window.c index cdc650ca3..b84e22cf4 100644 --- a/src/gui/curses/gui-curses-window.c +++ b/src/gui/curses/gui-curses-window.c @@ -205,7 +205,7 @@ gui_window_calculate_pos_size (struct t_gui_window *window, int force_calculate) /* init chat & nicklist settings */ if (window->buffer->nicklist) { - max_length = gui_nicklist_get_max_length (window->buffer); + max_length = window->buffer->nicklist_max_length; lines = 0; @@ -226,10 +226,10 @@ gui_window_calculate_pos_size (struct t_gui_window *window, int force_calculate) else { width_used = window->win_width - (window->win_width % (max_length + 2)); - if (((max_length + 2) * window->buffer->nicks_count) % width_used == 0) - lines = ((max_length + 2) * window->buffer->nicks_count) / width_used; + if (((max_length + 2) * window->buffer->nicklist_visible_count) % width_used == 0) + lines = ((max_length + 2) * window->buffer->nicklist_visible_count) / width_used; else - lines = (((max_length + 2) * window->buffer->nicks_count) / width_used) + 1; + lines = (((max_length + 2) * window->buffer->nicklist_visible_count) / width_used) + 1; if ((CONFIG_INTEGER(config_look_nicklist_max_size) > 0) && (lines > CONFIG_INTEGER(config_look_nicklist_max_size))) lines = CONFIG_INTEGER(config_look_nicklist_max_size); @@ -808,7 +808,7 @@ gui_window_nick_end (struct t_gui_window *window) if (window->buffer->nicklist) { new_start = - window->buffer->nicks_count - window->win_nick_num_max; + window->buffer->nicklist_visible_count - window->win_nick_num_max; if (new_start < 0) new_start = 0; else if (new_start >= 1) @@ -856,9 +856,9 @@ gui_window_nick_page_down (struct t_gui_window *window) if (window->buffer->nicklist) { - if ((window->buffer->nicks_count > window->win_nick_num_max) + if ((window->buffer->nicklist_visible_count > window->win_nick_num_max) && (window->win_nick_start + window->win_nick_num_max - 1 - < window->buffer->nicks_count)) + < window->buffer->nicklist_visible_count)) { if (window->win_nick_start == 0) window->win_nick_start += (window->win_nick_num_max - 1); @@ -1335,9 +1335,9 @@ gui_window_refresh_screen (int force) void gui_window_refresh_screen_sigwinch () { - if (gui_refresh_screen_needed < 2) - gui_refresh_screen_needed++; - signal (SIGWINCH, gui_window_refresh_screen_sigwinch); + gui_refresh_screen_needed = 1; + //gui_window_refresh_screen (0); + signal (SIGWINCH, &gui_window_refresh_screen_sigwinch); } /* diff --git a/src/gui/curses/gui-curses.h b/src/gui/curses/gui-curses.h index f1e6aea17..7d3316168 100644 --- a/src/gui/curses/gui-curses.h +++ b/src/gui/curses/gui-curses.h @@ -60,8 +60,7 @@ extern void gui_chat_calculate_line_diff (struct t_gui_window *window, /* keyboard functions */ extern void gui_keyboard_default_bindings (); -extern void gui_keyboard_read (); -extern void gui_keyboard_flush (); +extern int gui_keyboard_read_cb (void *data); /* window functions */ extern void gui_window_wprintw (WINDOW *window, char *data, ...); diff --git a/src/gui/gtk/gui-gtk-window.c b/src/gui/gtk/gui-gtk-window.c index bbb11c326..f757b8896 100644 --- a/src/gui/gtk/gui-gtk-window.c +++ b/src/gui/gtk/gui-gtk-window.c @@ -451,7 +451,7 @@ gui_window_nick_end (struct t_gui_window *window) if (window->buffer->nicklist) { new_start = - window->buffer->nicks_count - window->win_nick_height; + window->buffer->nicklist_visible_count - window->win_nick_height; if (new_start < 0) new_start = 0; else if (new_start >= 1) @@ -499,9 +499,9 @@ gui_window_nick_page_down (struct t_gui_window *window) if (window->buffer->nicklist) { - if ((window->buffer->nicks_count > window->win_nick_height) + if ((window->buffer->nicklist_visible_count > window->win_nick_height) && (window->win_nick_start + window->win_nick_height - 1 - < window->buffer->nicks_count)) + < window->buffer->nicklist_visible_count)) { if (window->win_nick_start == 0) window->win_nick_start += (window->win_nick_height - 1); diff --git a/src/gui/gui-buffer.c b/src/gui/gui-buffer.c index 74f7d6514..f29c4d657 100644 --- a/src/gui/gui-buffer.c +++ b/src/gui/gui-buffer.c @@ -113,11 +113,13 @@ gui_buffer_new (struct t_weechat_plugin *plugin, char *category, char *name, /* nicklist */ new_buffer->nicklist = 0; - new_buffer->nick_case_sensitive = 0; - new_buffer->nicks = NULL; - new_buffer->last_nick = NULL; - new_buffer->nick_max_length = -1; - new_buffer->nicks_count = 0; + new_buffer->nicklist_case_sensitive = 0; + new_buffer->nicklist_root = NULL; + new_buffer->nicklist_max_length = -1; + new_buffer->nicklist_display_groups = 1; + new_buffer->nicklist_visible_count = 0; + new_buffer->nicklist_refresh_needed = 0; + gui_nicklist_add_group (new_buffer, NULL, "root", NULL, 0); /* input */ new_buffer->input = 1; @@ -282,14 +284,27 @@ gui_buffer_set_nicklist (struct t_gui_buffer *buffer, int nicklist) } /* - * gui_buffer_set_nick_case_sensitive: set nick_case_sensitive flag for a buffer + * gui_buffer_set_nicklist_case_sensitive: set case_sensitive flag for a buffer */ void -gui_buffer_set_nick_case_sensitive (struct t_gui_buffer *buffer, - int nick_case_sensitive) +gui_buffer_set_nicklist_case_sensitive (struct t_gui_buffer *buffer, + int case_sensitive) { - buffer->nick_case_sensitive = (nick_case_sensitive) ? 1 : 0; + buffer->nicklist_case_sensitive = (case_sensitive) ? 1 : 0; +} + +/* + * gui_buffer_set_nicklist_display_groups: set display_groups flag for a buffer + */ + +void +gui_buffer_set_nicklist_display_groups (struct t_gui_buffer *buffer, + int display_groups) +{ + buffer->nicklist_display_groups = (display_groups) ? 1 : 0; + buffer->nicklist_visible_count = 0; + gui_nicklist_compute_visible_count (buffer, buffer->nicklist_root); } /* @@ -344,12 +359,19 @@ gui_buffer_set (struct t_gui_buffer *buffer, char *property, char *value) gui_window_refresh_windows (); } } - else if (string_strcasecmp (property, "nick_case_sensitive") == 0) + else if (string_strcasecmp (property, "nicklist_case_sensitive") == 0) + { + error = NULL; + number = strtol (value, &error, 10); + if (error && (error[0] == '\0')) + gui_buffer_set_nicklist_case_sensitive (buffer, number); + } + else if (string_strcasecmp (property, "nicklist_display_groups") == 0) { error = NULL; number = strtol (value, &error, 10); if (error && (error[0] == '\0')) - gui_buffer_set_nick_case_sensitive (buffer, number); + gui_buffer_set_nicklist_display_groups (buffer, number); } else if (string_strcasecmp (property, "nick") == 0) { @@ -641,6 +663,7 @@ gui_buffer_close (struct t_gui_buffer *buffer, int switch_to_another) gui_history_buffer_free (buffer); if (buffer->text_search_input) free (buffer->text_search_input); + gui_nicklist_remove_all (buffer); /* remove buffer from buffers list */ if (buffer->prev_buffer) @@ -962,7 +985,6 @@ void gui_buffer_print_log () { struct t_gui_buffer *ptr_buffer; - struct t_gui_nick *ptr_nick; struct t_gui_line *ptr_line; int num; @@ -986,10 +1008,12 @@ gui_buffer_print_log () log_printf (" prefix_max_length. . . : %d", ptr_buffer->prefix_max_length); log_printf (" chat_refresh_needed. . : %d", ptr_buffer->chat_refresh_needed); log_printf (" nicklist . . . . . . . : %d", ptr_buffer->nicklist); - log_printf (" nick_case_sensitive. . : %d", ptr_buffer->nick_case_sensitive); - log_printf (" nicks. . . . . . . . . : 0x%X", ptr_buffer->nicks); - log_printf (" last_nick. . . . . . . : 0x%X", ptr_buffer->last_nick); - log_printf (" nicks_count. . . . . . : %d", ptr_buffer->nicks_count); + log_printf (" nicklist_case_sensitive: %d", ptr_buffer->nicklist_case_sensitive); + log_printf (" nicklist_root. . . . . : 0x%X", ptr_buffer->nicklist_root); + log_printf (" nicklist_max_length. . : %d", ptr_buffer->nicklist_max_length); + log_printf (" nicklist_display_groups: %d", ptr_buffer->nicklist_display_groups); + log_printf (" nicklist_visible_count.: %d", ptr_buffer->nicklist_visible_count); + log_printf (" nicklist_refresh_needed: %d", ptr_buffer->nicklist_refresh_needed); log_printf (" input. . . . . . . . . : %d", ptr_buffer->input); log_printf (" input_data_cb. . . . . : 0x%X", ptr_buffer->input_data_cb); log_printf (" input_nick . . . . . . : '%s'", ptr_buffer->input_nick); @@ -1011,19 +1035,10 @@ gui_buffer_print_log () log_printf (" text_search_input. . . : '%s'", ptr_buffer->text_search_input); log_printf (" prev_buffer. . . . . . : 0x%X", ptr_buffer->prev_buffer); log_printf (" next_buffer. . . . . . : 0x%X", ptr_buffer->next_buffer); - - for (ptr_nick = ptr_buffer->nicks; ptr_nick; - ptr_nick = ptr_nick->next_nick) - { - log_printf (""); - log_printf (" => nick %s (addr:0x%X):", ptr_nick->nick, ptr_nick); - log_printf (" sort_index. . . . . . : %d", ptr_nick->sort_index); - log_printf (" color_nick. . . . . . : %d", ptr_nick->color_nick); - log_printf (" prefix. . . . . . . . : '%c'", ptr_nick->prefix); - log_printf (" color_prefix. . . . . : %d", ptr_nick->color_prefix); - log_printf (" prev_nick . . . . . . : 0x%X", ptr_nick->prev_nick); - log_printf (" next_nick . . . . . . : 0x%X", ptr_nick->next_nick); - } + + log_printf (""); + log_printf (" => nicklist_root (addr:0x%X):", ptr_buffer->nicklist_root); + gui_nicklist_print_log (ptr_buffer->nicklist_root, 0); log_printf (""); log_printf (" => last 100 lines:"); diff --git a/src/gui/gui-buffer.h b/src/gui/gui-buffer.h index 7ffb52e0e..a79fac3d7 100644 --- a/src/gui/gui-buffer.h +++ b/src/gui/gui-buffer.h @@ -73,15 +73,16 @@ struct t_gui_buffer struct t_gui_line *last_read_line; /* last read line before jump */ int lines_count; /* number of lines in the buffer */ int prefix_max_length; /* length for prefix align */ - int chat_refresh_needed; /* if refresh is needed (printf) */ + int chat_refresh_needed; /* refresh for chat is needed ? */ /* nicklist */ int nicklist; /* = 1 if nicklist is enabled */ - int nick_case_sensitive; /* nicks are case sensitive ? */ - struct t_gui_nick *nicks; /* pointer to nicks for nicklist */ - struct t_gui_nick *last_nick; /* last nick in nicklist */ - int nick_max_length; /* max length for a nick */ - int nicks_count; /* number of nicks on buffer */ + int nicklist_case_sensitive; /* nicks are case sensitive ? */ + struct t_gui_nick_group *nicklist_root; /* pointer to groups root */ + int nicklist_max_length; /* max length for a nick */ + int nicklist_display_groups; /* display groups ? */ + int nicklist_visible_count; /* number of nicks/groups to display */ + int nicklist_refresh_needed; /* refresh for nicklist is needed ? */ /* inupt */ int input; /* = 1 if input is enabled */ @@ -139,8 +140,8 @@ extern void gui_buffer_set_category (struct t_gui_buffer *buffer, extern void gui_buffer_set_name (struct t_gui_buffer *buffer, char *name); extern void gui_buffer_set_title (struct t_gui_buffer *buffer, char *new_title); extern void gui_buffer_set_nicklist (struct t_gui_buffer *buffer, int nicklist); -extern void gui_buffer_set_nick_case_sensitive (struct t_gui_buffer * buffer, - int nick_case_sensitive); +extern void gui_buffer_set_nicklist_case_sensitive (struct t_gui_buffer * buffer, + int case_sensitive); extern void gui_buffer_set_nick (struct t_gui_buffer *buffer, char *new_nick); extern void gui_buffer_set (struct t_gui_buffer *buffer, char *property, char *value); diff --git a/src/gui/gui-color.h b/src/gui/gui-color.h index 263805c0e..5ee667d50 100644 --- a/src/gui/gui-color.h +++ b/src/gui/gui-color.h @@ -83,6 +83,7 @@ enum t_gui_color_enum GUI_COLOR_INPUT_ACTIONS, GUI_COLOR_NICKLIST, + GUI_COLOR_NICKLIST_GROUP, GUI_COLOR_NICKLIST_AWAY, GUI_COLOR_NICKLIST_PREFIX1, GUI_COLOR_NICKLIST_PREFIX2, diff --git a/src/gui/gui-nicklist.c b/src/gui/gui-nicklist.c index 1433c5641..0c82a162b 100644 --- a/src/gui/gui-nicklist.c +++ b/src/gui/gui-nicklist.c @@ -33,6 +33,7 @@ #include <ctype.h> #include "../core/weechat.h" +#include "../core/wee-log.h" #include "../core/wee-string.h" #include "../core/wee-utf8.h" #include "gui-nicklist.h" @@ -41,58 +42,198 @@ /* - * gui_nicklist_compare: compare two nicks - * return: -1 is nick1 < nick2 - * 0 if nick1 = nick2 - * +1 if nick1 > nick2 + * gui_nicklist_find_pos_group: find position for a group (for sorting nicklist) */ -int -gui_nicklist_compare (struct t_gui_buffer *buffer, - struct t_gui_nick *nick1, struct t_gui_nick *nick2) +struct t_gui_nick_group * +gui_nicklist_find_pos_group (struct t_gui_nick_group *groups, + struct t_gui_nick_group *group) { - if (nick1->sort_index > nick2->sort_index) - return 1; + struct t_gui_nick_group *ptr_group; - if (nick1->sort_index < nick2->sort_index) - return -1; + for (ptr_group = groups; ptr_group; ptr_group = ptr_group->next_group) + { + if (strcmp (group->name, ptr_group->name) < 0) + return ptr_group; + } - /* sort index are the same, then use alphabetical sorting */ - if (buffer->nick_case_sensitive) - return strcmp (nick1->nick, nick2->nick); + /* group will be inserted at end of list */ + return NULL; +} + +/* + * gui_nicklist_insert_group_sorted: insert group into sorted list + */ + +void +gui_nicklist_insert_group_sorted (struct t_gui_nick_group **groups, + struct t_gui_nick_group **last_group, + struct t_gui_nick_group *group) +{ + struct t_gui_nick_group *pos_group; + + if (*groups) + { + pos_group = gui_nicklist_find_pos_group (*groups, group); + + if (pos_group) + { + /* insert group into the list (before group found) */ + group->prev_group = pos_group->prev_group; + group->next_group = pos_group; + if (pos_group->prev_group) + pos_group->prev_group->next_group = group; + else + *groups = group; + pos_group->prev_group = group; + } + else + { + /* add group to the end */ + group->prev_group = *last_group; + group->next_group = NULL; + (*last_group)->next_group = group; + *last_group = group; + } + } else - return string_strcasecmp (nick1->nick, nick2->nick); + { + group->prev_group = NULL; + group->next_group = NULL; + *groups = group; + *last_group = group; + } } /* - * gui_nicklist_find_pos: find position for a nick (for sorting nicklist) + * gui_nicklist_search_group: search a group in buffer nicklist + */ + +struct t_gui_nick_group * +gui_nicklist_search_group (struct t_gui_buffer *buffer, + struct t_gui_nick_group *from_group, + char *name) +{ + struct t_gui_nick_group *ptr_group; + + if (!from_group) + from_group = buffer->nicklist_root; + + if (!from_group) + return NULL; + + if (from_group->childs) + { + ptr_group = gui_nicklist_search_group (buffer, from_group->childs, name); + if (ptr_group) + return ptr_group; + } + + ptr_group = from_group; + while (ptr_group) + { + if (strcmp (ptr_group->name, name) == 0) + return ptr_group; + ptr_group = ptr_group->next_group; + } + + /* group not found */ + return NULL; +} + +/* + * gui_nicklist_add_group: add a group to nicklist for a buffer + */ + +struct t_gui_nick_group * +gui_nicklist_add_group (struct t_gui_buffer *buffer, + struct t_gui_nick_group *parent_group, char *name, + char *color, int visible) +{ + struct t_gui_nick_group *new_group; + int num_color; + + if (!name || gui_nicklist_search_group (buffer, parent_group, name)) + return NULL; + + new_group = (struct t_gui_nick_group *)malloc (sizeof (struct t_gui_nick_group)); + if (!new_group) + return NULL; + + if (color) + { + num_color = gui_color_search_config (color); + if (num_color < 0) + num_color = GUI_COLOR_NICKLIST; + } + else + num_color = GUI_COLOR_NICKLIST; + + new_group->name = strdup (name); + new_group->color = num_color; + new_group->visible = visible; + new_group->parent = (parent_group) ? parent_group : buffer->nicklist_root; + new_group->level = (new_group->parent) ? new_group->parent->level + 1 : 0; + new_group->childs = NULL; + new_group->last_child = NULL; + new_group->nicks = NULL; + new_group->last_nick = NULL; + new_group->prev_group = NULL; + new_group->next_group = NULL; + + if (new_group->parent) + { + gui_nicklist_insert_group_sorted (&(new_group->parent->childs), + &(new_group->parent->last_child), + new_group); + } + else + { + buffer->nicklist_root = new_group; + } + + if (buffer->nicklist_display_groups && visible) + { + buffer->nicklist_refresh_needed = 1; + buffer->nicklist_visible_count++; + } + + return new_group; +} + +/* + * gui_nicklist_find_pos_nick: find position for a nick (for sorting nicklist) */ struct t_gui_nick * -gui_nicklist_find_pos (struct t_gui_buffer *buffer, struct t_gui_nick *nick) +gui_nicklist_find_pos_nick (struct t_gui_nick_group *group, + struct t_gui_nick *nick) { struct t_gui_nick *ptr_nick; - for (ptr_nick = buffer->nicks; ptr_nick; ptr_nick = ptr_nick->next_nick) + for (ptr_nick = group->nicks; ptr_nick; ptr_nick = ptr_nick->next_nick) { - if (gui_nicklist_compare (buffer, nick, ptr_nick) < 0) + if (strcmp (nick->name, ptr_nick->name) < 0) return ptr_nick; } + + /* nick will be inserted at end of list */ return NULL; } /* - * gui_nicklist_insert_sorted: insert nick into sorted list + * gui_nicklist_insert_nick_sorted: insert nick into sorted list */ void -gui_nicklist_insert_sorted (struct t_gui_buffer *buffer, struct t_gui_nick *nick) +gui_nicklist_insert_nick_sorted (struct t_gui_nick_group *group, + struct t_gui_nick *nick) { struct t_gui_nick *pos_nick; - if (buffer->nicks) + if (group->nicks) { - pos_nick = gui_nicklist_find_pos (buffer, nick); + pos_nick = gui_nicklist_find_pos_nick (group, nick); if (pos_nick) { @@ -102,64 +243,42 @@ gui_nicklist_insert_sorted (struct t_gui_buffer *buffer, struct t_gui_nick *nick if (pos_nick->prev_nick) pos_nick->prev_nick->next_nick = nick; else - buffer->nicks = nick; + group->nicks = nick; pos_nick->prev_nick = nick; } else { /* add nick to the end */ - nick->prev_nick = buffer->last_nick; + nick->prev_nick = group->last_nick; nick->next_nick = NULL; - buffer->last_nick->next_nick = nick; - buffer->last_nick = nick; + group->last_nick->next_nick = nick; + group->last_nick = nick; } } else { nick->prev_nick = NULL; nick->next_nick = NULL; - buffer->nicks = nick; - buffer->last_nick = nick; + group->nicks = nick; + group->last_nick = nick; } } /* - * gui_nicklist_resort: resort a nick in nicklist - */ - -void -gui_nicklist_resort (struct t_gui_buffer *buffer, struct t_gui_nick *nick) -{ - /* temporarly remove nick from list */ - if (nick == buffer->nicks) - buffer->nicks = nick->next_nick; - else - nick->prev_nick->next_nick = nick->next_nick; - if (nick->next_nick) - nick->next_nick->prev_nick = nick->prev_nick; - if (nick == buffer->last_nick) - buffer->last_nick = nick->prev_nick; - - /* insert again nick into sorted list */ - gui_nicklist_insert_sorted (buffer, nick); -} - -/* - * gui_nicklist_search: search a nick in buffer nicklist + * gui_nicklist_search_nick: search a nick in buffer nicklist */ struct t_gui_nick * -gui_nicklist_search (struct t_gui_buffer *buffer, char *nick) +gui_nicklist_search_nick (struct t_gui_buffer *buffer, + struct t_gui_nick_group *from_group, + char *name) { struct t_gui_nick *ptr_nick; - - for (ptr_nick = buffer->nicks; ptr_nick; - ptr_nick = ptr_nick->next_nick) + + for (ptr_nick = (from_group) ? from_group->nicks : buffer->nicklist_root->nicks; + ptr_nick; ptr_nick = ptr_nick->next_nick) { - if ((buffer->nick_case_sensitive - && (strcmp (ptr_nick->nick, nick) == 0)) - || (!buffer->nick_case_sensitive - && (string_strcasecmp (ptr_nick->nick, nick) == 0))) + if (strcmp (ptr_nick->name, name) == 0) return ptr_nick; } @@ -168,132 +287,257 @@ gui_nicklist_search (struct t_gui_buffer *buffer, char *nick) } /* - * gui_nicklist_add: add a nick to nicklist for a buffer + * gui_nicklist_add_nick: add a nick to nicklist for a buffer */ struct t_gui_nick * -gui_nicklist_add (struct t_gui_buffer *buffer, char *nick, int sort_index, - char *color_nick, char prefix, char *color_prefix) +gui_nicklist_add_nick (struct t_gui_buffer *buffer, + struct t_gui_nick_group *group, char *name, + char *color, char prefix, char *prefix_color, + int visible) { struct t_gui_nick *new_nick; - int num_color_nick, num_color_prefix; + int num_color, num_color_prefix; - if (!nick || gui_nicklist_search (buffer, nick)) + if (!name || gui_nicklist_search_nick (buffer, NULL, name)) return NULL; new_nick = (struct t_gui_nick *)malloc (sizeof (struct t_gui_nick)); if (!new_nick) return NULL; - - num_color_nick = gui_color_search_config (color_nick); - if (num_color_nick < 0) - num_color_nick = GUI_COLOR_NICKLIST; - - num_color_prefix = gui_color_search_config (color_prefix); - if (num_color_prefix < 0) + + if (color) + { + num_color = gui_color_search_config (color); + if (num_color < 0) + num_color = GUI_COLOR_NICKLIST; + } + else + num_color = GUI_COLOR_NICKLIST; + + if (prefix_color) + { + num_color_prefix = gui_color_search_config (prefix_color); + if (num_color_prefix < 0) + num_color_prefix = GUI_COLOR_NICKLIST; + } + else num_color_prefix = GUI_COLOR_NICKLIST; - - new_nick->nick = strdup (nick); - new_nick->sort_index = sort_index; - new_nick->color_nick = num_color_nick; + + new_nick->group = (group) ? group : buffer->nicklist_root; + new_nick->name = strdup (name); + new_nick->color = num_color; new_nick->prefix = prefix; - new_nick->color_prefix = num_color_prefix; + new_nick->prefix_color = num_color_prefix; + new_nick->visible = visible; - gui_nicklist_insert_sorted (buffer, new_nick); + gui_nicklist_insert_nick_sorted (new_nick->group, new_nick); - buffer->nicks_count++; + if (visible) + { + buffer->nicklist_refresh_needed = 1; + buffer->nicklist_visible_count++; + } return new_nick; } /* - * gui_nicklist_update: update a nick in nicklist + * gui_nicklist_remove_nick: remove a nick from a group */ void -gui_nicklist_update (struct t_gui_buffer *buffer, struct t_gui_nick *nick, - char *new_nick, int sort_index, - char *color_nick, char prefix, char *color_prefix) +gui_nicklist_remove_nick (struct t_gui_buffer *buffer, + struct t_gui_nick *nick) { - int num_color_nick, num_color_prefix; - if (!nick) return; - num_color_nick = gui_color_search_config (color_nick); - if (num_color_nick < 0) - num_color_nick = GUI_COLOR_NICKLIST; + /* remove nick from list */ + if (nick->prev_nick) + nick->prev_nick->next_nick = nick->next_nick; + if (nick->next_nick) + nick->next_nick->prev_nick = nick->prev_nick; + if (nick->group->nicks == nick) + nick->group->nicks = nick->next_nick; + if (nick->group->last_nick == nick) + nick->group->last_nick = nick->prev_nick; - num_color_prefix = gui_color_search_config (color_prefix); - if (num_color_prefix < 0) - num_color_prefix = GUI_COLOR_NICKLIST; + /* free data */ + if (nick->name) + free (nick->name); - if (new_nick) + if (nick->visible) { - free (nick->nick); - nick->nick = strdup (new_nick); + buffer->nicklist_refresh_needed = 1; + if (buffer->nicklist_visible_count > 0) + buffer->nicklist_visible_count--; } - nick->sort_index = sort_index; - nick->color_nick = num_color_nick; - nick->prefix = prefix; - nick->color_prefix = num_color_prefix; - gui_nicklist_resort (buffer, nick); + free (nick); } /* - * gui_nicklist_free: remove a nick to nicklist for a buffer + * gui_nicklist_remove_group: remove a group from nicklist */ void -gui_nicklist_free (struct t_gui_buffer *buffer, struct t_gui_nick *nick) +gui_nicklist_remove_group (struct t_gui_buffer *buffer, + struct t_gui_nick_group *group) { - if (nick->nick) - free (nick->nick); + if (!group) + return; - /* remove nick from nicks list */ - if (nick->prev_nick) - nick->prev_nick->next_nick = nick->next_nick; - if (nick->next_nick) - nick->next_nick->prev_nick = nick->prev_nick; - if (buffer->nicks == nick) - buffer->nicks = nick->next_nick; - if (buffer->last_nick == nick) - buffer->last_nick = nick->prev_nick; + /* remove childs first */ + while (group->childs) + { + gui_nicklist_remove_group (buffer, group->childs); + } - if (buffer->nicks_count > 0) - buffer->nicks_count--; + /* remove nicks from group */ + while (group->nicks) + { + gui_nicklist_remove_nick (buffer, group->nicks); + } + + if (group->parent) + { + /* remove group from list */ + if (group->prev_group) + group->prev_group->next_group = group->next_group; + if (group->next_group) + group->next_group->prev_group = group->prev_group; + if (group->parent->childs == group) + group->parent->childs = group->next_group; + if (group->parent->last_child == group) + group->parent->last_child = group->prev_group; + } + else + { + buffer->nicklist_root = NULL; + } + + /* free data */ + if (group->name) + free (group->name); + + if (group->visible) + { + buffer->nicklist_refresh_needed = 1; + if (buffer->nicklist_display_groups + && (buffer->nicklist_visible_count > 0)) + buffer->nicklist_visible_count--; + } + + free (group); } /* - * gui_nicklist_free_all: remove all nicks in nicklist + * gui_nicklist_remove_all: remove all nicks in nicklist */ void -gui_nicklist_free_all (struct t_gui_buffer *buffer) +gui_nicklist_remove_all (struct t_gui_buffer *buffer) { - while (buffer->nicks) + while (buffer->nicklist_root) { - gui_nicklist_free (buffer, buffer->nicks); + gui_nicklist_remove_group (buffer, buffer->nicklist_root); } } /* - * gui_nicklist_remove: remove a nickname to nicklist for a buffer - * return 1 if a nick was removed, 0 otherwise + * gui_nicklist_get_next_item: get next item (group or nick) of a group/nick */ -int -gui_nicklist_remove (struct t_gui_buffer *buffer, char *nick) +void +gui_nicklist_get_next_item (struct t_gui_buffer *buffer, + struct t_gui_nick_group **group, + struct t_gui_nick **nick) { - struct t_gui_nick *ptr_nick; + struct t_gui_nick_group *ptr_group; + + /* root group */ + if (!*group && !*nick) + { + *group = buffer->nicklist_root; + return; + } + + /* next nick */ + if (*nick && (*nick)->next_nick) + { + *nick = (*nick)->next_nick; + return; + } + + if (*group && !*nick) + { + /* first child */ + if ((*group)->childs) + { + *group = (*group)->childs; + return; + } + /* first nick of current group */ + if ((*group)->nicks) + { + *nick = (*group)->nicks; + return; + } + if ((*group)->next_group) + { + *group = (*group)->next_group; + return; + } + } + + *nick = NULL; + ptr_group = (*group) ? *group : buffer->nicklist_root; - ptr_nick = gui_nicklist_search (buffer, nick); - if (!ptr_nick) - return 0; + /* next group */ + if (ptr_group->next_group) + { + *group = ptr_group->next_group; + return; + } - gui_nicklist_free (buffer, ptr_nick); - return 1; + /* find next group by parents */ + while ((ptr_group = ptr_group->parent)) + { + if (ptr_group->next_group) + { + *group = ptr_group->next_group; + return; + } + } + + /* nothing found */ + *group = NULL; +} + +/* + * gui_nicklist_get_group_start: return first char of a group that will be + * displayed on screen: if name begins with + * some digits followed by '|', then start is + * after '|', otherwise it's beginning of name + */ + +char * +gui_nicklist_get_group_start (char *name) +{ + char *ptr_name; + + ptr_name = name; + while (isdigit (ptr_name[0])) + { + if (ptr_name[0] == '|') + break; + ptr_name++; + } + if ((ptr_name[0] == '|') && (ptr_name != name)) + return ptr_name + 1; + else + return name; } /* @@ -301,17 +545,172 @@ gui_nicklist_remove (struct t_gui_buffer *buffer, char *nick) */ int -gui_nicklist_get_max_length (struct t_gui_buffer *buffer) +gui_nicklist_get_max_length (struct t_gui_buffer *buffer, + struct t_gui_nick_group *group) { int length, max_length; + struct t_gui_nick_group *ptr_group; struct t_gui_nick *ptr_nick; max_length = 0; - for (ptr_nick = buffer->nicks; ptr_nick; ptr_nick = ptr_nick->next_nick) + for (ptr_group = (group) ? group : buffer->nicklist_root; + ptr_group; ptr_group = ptr_group->next_group) { - length = utf8_strlen_screen (ptr_nick->nick); - if (length > max_length) - max_length = length; + if (buffer->nicklist_display_groups && ptr_group->visible) + { + length = utf8_strlen_screen (gui_nicklist_get_group_start (ptr_group->name)) + + ptr_group->level - 1; + if (length > max_length) + max_length = length; + } + for (ptr_nick = ptr_group->nicks; ptr_nick; + ptr_nick = ptr_nick->next_nick) + { + if (ptr_nick->visible) + { + if (buffer->nicklist_display_groups) + length = utf8_strlen_screen (ptr_nick->name) + ptr_group->level + 1; + else + length = utf8_strlen_screen (ptr_nick->name) + 1; + if (length > max_length) + max_length = length; + } + } + if (ptr_group->childs) + { + length = gui_nicklist_get_max_length (buffer, ptr_group->childs); + if (length > max_length) + max_length = length; + } } return max_length; } + +/* + * gui_nicklist_compute_visible_count: compute visible_count variable for a buffer + */ + +void +gui_nicklist_compute_visible_count (struct t_gui_buffer *buffer, + struct t_gui_nick_group *group) +{ + if (!group) + return; + + /* count for childs */ + if (group->childs) + gui_nicklist_compute_visible_count (buffer, group->childs); + + /* count current group */ + if (buffer->nicklist_display_groups && group->visible) + buffer->nicklist_visible_count++; +} + +/* + * gui_nicklist_print_log: print nicklist infos in log (usually for crash dump) + */ + +void +gui_nicklist_print_log (struct t_gui_nick_group *group, int indent) +{ + char format[128]; + struct t_gui_nick_group *ptr_group; + struct t_gui_nick *ptr_nick; + + snprintf (format, sizeof (format), + "%%-%ds=> group (addr:0x%%X)", + (indent * 2) + 4); + log_printf (format, " ", group); + snprintf (format, sizeof (format), + "%%-%dsname. . . . : '%%s'", + (indent * 2) + 6); + log_printf (format, " ", group->name); + snprintf (format, sizeof (format), + "%%-%dscolor . . . : %%d", + (indent * 2) + 6); + log_printf (format, " ", group->color); + snprintf (format, sizeof (format), + "%%-%dsvisible . . : %%d", + (indent * 2) + 6); + log_printf (format, " ", group->visible); + snprintf (format, sizeof (format), + "%%-%dsparent. . . : 0x%%X", + (indent * 2) + 6); + log_printf (format, " ", group->parent); + snprintf (format, sizeof (format), + "%%-%dschilds. . . : 0x%%X", + (indent * 2) + 6); + log_printf (format, " ", group->childs); + snprintf (format, sizeof (format), + "%%-%dslast_child. : 0x%%X", + (indent * 2) + 6); + log_printf (format, " ", group->last_child); + snprintf (format, sizeof (format), + "%%-%dsnicks . . . : 0x%%X", + (indent * 2) + 6); + log_printf (format, " ", group->nicks); + snprintf (format, sizeof (format), + "%%-%dslast_nick . : 0x%%X", + (indent * 2) + 6); + log_printf (format, " ", group->last_nick); + snprintf (format, sizeof (format), + "%%-%dsprev_group. : 0x%%X", + (indent * 2) + 6); + log_printf (format, " ", group->prev_group); + snprintf (format, sizeof (format), + "%%-%dsnext_group. : 0x%%X", + (indent * 2) + 6); + log_printf (format, " ", group->next_group); + + /* display child groups first */ + if (group->childs) + { + for (ptr_group = group->childs; ptr_group; + ptr_group = ptr_group->next_group) + { + gui_nicklist_print_log (ptr_group, indent + 1); + } + } + + /* then display nicks in group */ + for (ptr_nick = group->nicks; ptr_nick; + ptr_nick = ptr_nick->next_nick) + { + snprintf (format, sizeof (format), + "%%-%ds=> nick (addr:0x%%X)", + (indent * 2) + 4); + log_printf (format, " ", ptr_nick); + snprintf (format, sizeof (format), + "%%-%dsgroup . . . : 0x%%X", + (indent * 2) + 6); + log_printf (format, " ", ptr_nick->group); + snprintf (format, sizeof (format), + "%%-%dsname. . . . : '%%s'", + (indent * 2) + 6); + log_printf (format, " ", ptr_nick->name); + snprintf (format, sizeof (format), + "%%-%dscolor . . . : %%d", + (indent * 2) + 6); + log_printf (format, " ", ptr_nick->color); + snprintf (format, sizeof (format), + "%%-%dsprefix. . . : '%%c'", + (indent * 2) + 6); + log_printf (format, " ", ptr_nick->prefix); + snprintf (format, sizeof (format), + "%%-%dsprefix_color: %%d", + (indent * 2) + 6); + log_printf (format, " ", ptr_nick->prefix_color); + snprintf (format, sizeof (format), + "%%-%dsvisible . . : %%d", + (indent * 2) + 6); + log_printf (format, " ", ptr_nick->visible); + snprintf (format, sizeof (format), + "%%-%dsprev_nick . : 0x%%X", + (indent * 2) + 6); + log_printf (format, " ", ptr_nick->prev_nick); + snprintf (format, sizeof (format), + "%%-%dsnext_nick . : 0x%%X", + (indent * 2) + 6); + log_printf (format, " ", ptr_nick->next_nick); + } +} diff --git a/src/gui/gui-nicklist.h b/src/gui/gui-nicklist.h index a69a086b6..90bef3d58 100644 --- a/src/gui/gui-nicklist.h +++ b/src/gui/gui-nicklist.h @@ -22,35 +22,64 @@ struct t_gui_buffer; +struct t_gui_nick_group +{ + char *name; /* group name */ + int color; /* color for group in nicklist */ + int visible; /* 1 if group is displayed */ + int level; /* group level (root is 0) */ + struct t_gui_nick_group *parent; /* parent */ + struct t_gui_nick_group *childs; /* childs */ + struct t_gui_nick_group *last_child; /* last child */ + struct t_gui_nick *nicks; /* nicks for group */ + struct t_gui_nick *last_nick; /* last nick for group */ + struct t_gui_nick_group *prev_group; /* link to previous group */ + struct t_gui_nick_group *next_group; /* link to next group */ +}; + struct t_gui_nick { - char *nick; /* nickname */ - int sort_index; /* index to force sort */ - int color_nick; /* color for nick in nicklist */ + struct t_gui_nick_group *group; /* group which contains nick */ + char *name; /* nick name */ + int color; /* color for nick in nicklist */ char prefix; /* prefix for nick (for admins, ..) */ - int color_prefix; /* color for prefix */ - struct t_gui_nick *prev_nick; /* link to previous nick in nicklist */ - struct t_gui_nick *next_nick; /* link to next nick in nicklist */ + int prefix_color; /* color for prefix */ + int visible; /* 1 if nick is displayed */ + struct t_gui_nick *prev_nick; /* link to previous nick */ + struct t_gui_nick *next_nick; /* link to next nick */ }; /* nicklist functions */ -extern struct t_gui_nick *gui_nicklist_search (struct t_gui_buffer *buffer, - char *nick); -extern struct t_gui_nick *gui_nicklist_add (struct t_gui_buffer *buffer, - char *nick, - int sort_index, char *color_nick, - char prefix, char *color_prefix); -extern void gui_nicklist_update (struct t_gui_buffer *buffer, - struct t_gui_nick *nick, - char *new_nick, int sort_index, - char *color_nick, char prefix, - char *color_prefix); -extern void gui_nicklist_free (struct t_gui_buffer *buffer, - struct t_gui_nick *nick); -extern void gui_nicklist_free_all (struct t_gui_buffer *buffer); -extern int gui_nicklist_remove (struct t_gui_buffer *buffer, char *nick); -extern int gui_nicklist_get_max_length (struct t_gui_buffer *buffer); +extern struct t_gui_nick_group *gui_nicklist_search_group (struct t_gui_buffer *buffer, + struct t_gui_nick_group *from_group, + char *name); +extern struct t_gui_nick_group *gui_nicklist_add_group (struct t_gui_buffer *buffer, + struct t_gui_nick_group *parent_group, + char *name, char *color, + int visible); +extern struct t_gui_nick *gui_nicklist_search_nick (struct t_gui_buffer *buffer, + struct t_gui_nick_group *from_group, + char *name); +extern struct t_gui_nick *gui_nicklist_add_nick (struct t_gui_buffer *buffer, + struct t_gui_nick_group *group, + char *name, char *color, + char prefix, char *prefix_color, + int visible); +extern void gui_nicklist_remove_group (struct t_gui_buffer *buffer, + struct t_gui_nick_group *group); +extern void gui_nicklist_remove_nick (struct t_gui_buffer *buffer, + struct t_gui_nick *nick); +extern void gui_nicklist_remove_all (struct t_gui_buffer *buffer); +extern void gui_nicklist_get_next_item (struct t_gui_buffer *buffer, + struct t_gui_nick_group **group, + struct t_gui_nick **nick); +extern char *gui_nicklist_get_group_start (char *name); +extern int gui_nicklist_get_max_length (struct t_gui_buffer *buffer, + struct t_gui_nick_group *group); +extern void gui_nicklist_compute_visible_count (struct t_gui_buffer *buffer, + struct t_gui_nick_group *group); +extern void gui_nicklist_print_log (struct t_gui_nick_group *group, int indent); /* nicklist functions (GUI dependent) */ diff --git a/src/plugins/fifo/fifo.c b/src/plugins/fifo/fifo.c index c1dd8a5fc..7878e67d8 100644 --- a/src/plugins/fifo/fifo.c +++ b/src/plugins/fifo/fifo.c @@ -115,8 +115,6 @@ fifo_create () fifo_filename); } } - if (weechat_home) - free (weechat_home); return rc; } diff --git a/src/plugins/irc/irc-buffer.h b/src/plugins/irc/irc-buffer.h index 600493bf5..4286a21fb 100644 --- a/src/plugins/irc/irc-buffer.h +++ b/src/plugins/irc/irc-buffer.h @@ -20,9 +20,6 @@ #ifndef __WEECHAT_IRC_BUFFER_H #define __WEECHAT_IRC_BUFFER_H 1 -#include "irc-server.h" -#include "irc-channel.h" - #define IRC_BUFFER_SERVER(buffer) (((t_irc_buffer_data *)(buffer->protocol_data))->server) #define IRC_BUFFER_CHANNEL(buffer) (((t_irc_buffer_data *)(buffer->protocol_data))->channel) #define IRC_BUFFER_ALL_SERVERS(buffer) (((t_irc_buffer_data *)(buffer->protocol_data))->all_servers) diff --git a/src/plugins/irc/irc-channel.c b/src/plugins/irc/irc-channel.c index 635fc0df4..40f55e354 100644 --- a/src/plugins/irc/irc-channel.c +++ b/src/plugins/irc/irc-channel.c @@ -64,7 +64,20 @@ irc_channel_new (struct t_irc_server *server, int channel_type, return NULL; } if (channel_type == IRC_CHANNEL_TYPE_CHANNEL) + { weechat_buffer_set (new_buffer, "nicklist", "1"); + weechat_buffer_set (new_buffer, "nicklist_display_groups", "0"); + weechat_nicklist_add_group (new_buffer, NULL, IRC_NICK_GROUP_OP, + "color_nicklist_group", 1); + weechat_nicklist_add_group (new_buffer, NULL, IRC_NICK_GROUP_HALFOP, + "color_nicklist_group", 1); + weechat_nicklist_add_group (new_buffer, NULL, IRC_NICK_GROUP_VOICE, + "color_nicklist_group", 1); + weechat_nicklist_add_group (new_buffer, NULL, IRC_NICK_GROUP_CHANUSER, + "color_nicklist_group", 1); + weechat_nicklist_add_group (new_buffer, NULL, IRC_NICK_GROUP_NORMAL, + "color_nicklist_group", 1); + } /* initialize new channel */ new_channel->type = channel_type; @@ -450,6 +463,9 @@ void irc_channel_add_nick_speaking (struct t_irc_channel *channel, char *nick) { int size, to_remove, i; + + if (!channel->nicks_speaking) + channel->nicks_speaking = weechat_list_new (); weechat_list_add (channel->nicks_speaking, nick, "end"); @@ -474,25 +490,27 @@ irc_channel_print_log (struct t_irc_channel *channel) { struct t_weelist_item *ptr_item; int i; + struct t_irc_nick *ptr_nick; - weechat_log_printf ("=> channel %s (addr:0x%X)]", channel->name, channel); - weechat_log_printf (" type . . . . . . . . : %d", channel->type); - weechat_log_printf (" dcc_chat . . . . . . : 0x%X", channel->dcc_chat); - weechat_log_printf (" topic. . . . . . . . : '%s'", channel->topic); - weechat_log_printf (" modes. . . . . . . . : '%s'", channel->modes); - weechat_log_printf (" limit. . . . . . . . : %d", channel->limit); - weechat_log_printf (" key. . . . . . . . . : '%s'", channel->key); - weechat_log_printf (" checking_away. . . . : %d", channel->checking_away); - weechat_log_printf (" away_message . . . . : '%s'", channel->away_message); - weechat_log_printf (" cycle. . . . . . . . : %d", channel->cycle); - weechat_log_printf (" close. . . . . . . . : %d", channel->close); - weechat_log_printf (" display_creation_date: %d", channel->display_creation_date); - weechat_log_printf (" nicks. . . . . . . . : 0x%X", channel->nicks); - weechat_log_printf (" last_nick. . . . . . : 0x%X", channel->last_nick); - weechat_log_printf (" buffer . . . . . . . : 0x%X", channel->buffer); - weechat_log_printf (" nicks_speaking . . . : 0x%X", channel->nicks_speaking); - weechat_log_printf (" prev_channel . . . . : 0x%X", channel->prev_channel); - weechat_log_printf (" next_channel . . . . : 0x%X", channel->next_channel); + weechat_log_printf (""); + weechat_log_printf (" => channel %s (addr:0x%X)]", channel->name, channel); + weechat_log_printf (" type . . . . . . . . : %d", channel->type); + weechat_log_printf (" dcc_chat . . . . . . : 0x%X", channel->dcc_chat); + weechat_log_printf (" topic. . . . . . . . : '%s'", channel->topic); + weechat_log_printf (" modes. . . . . . . . : '%s'", channel->modes); + weechat_log_printf (" limit. . . . . . . . : %d", channel->limit); + weechat_log_printf (" key. . . . . . . . . : '%s'", channel->key); + weechat_log_printf (" checking_away. . . . : %d", channel->checking_away); + weechat_log_printf (" away_message . . . . : '%s'", channel->away_message); + weechat_log_printf (" cycle. . . . . . . . : %d", channel->cycle); + weechat_log_printf (" close. . . . . . . . : %d", channel->close); + weechat_log_printf (" display_creation_date: %d", channel->display_creation_date); + weechat_log_printf (" nicks. . . . . . . . : 0x%X", channel->nicks); + weechat_log_printf (" last_nick. . . . . . : 0x%X", channel->last_nick); + weechat_log_printf (" buffer . . . . . . . : 0x%X", channel->buffer); + weechat_log_printf (" nicks_speaking . . . : 0x%X", channel->nicks_speaking); + weechat_log_printf (" prev_channel . . . . : 0x%X", channel->prev_channel); + weechat_log_printf (" next_channel . . . . : 0x%X", channel->next_channel); if (channel->nicks_speaking) { weechat_log_printf (""); @@ -500,9 +518,13 @@ irc_channel_print_log (struct t_irc_channel *channel) for (ptr_item = weechat_list_get (channel->nicks_speaking, 0); ptr_item; ptr_item = weechat_list_next (ptr_item)) { - weechat_log_printf (" nick speaking %d: '%s'", + weechat_log_printf (" nick speaking %d: '%s'", i, weechat_list_string (ptr_item)); i++; } } + for (ptr_nick = channel->nicks; ptr_nick; ptr_nick = ptr_nick->next_nick) + { + irc_nick_print_log (ptr_nick); + } } diff --git a/src/plugins/irc/irc-channel.h b/src/plugins/irc/irc-channel.h index cd3c453e7..d7a30073d 100644 --- a/src/plugins/irc/irc-channel.h +++ b/src/plugins/irc/irc-channel.h @@ -20,8 +20,6 @@ #ifndef __WEECHAT_IRC_CHANNEL_H #define __WEECHAT_IRC_CHANNEL_H 1 -#include "irc-server.h" - #define IRC_CHANNEL_PREFIX "#&+!" /* channel types */ @@ -32,6 +30,8 @@ #define IRC_CHANNEL_NICKS_SPEAKING_LIMIT 32 +struct t_irc_server; + struct t_irc_channel { int type; /* channel type */ diff --git a/src/plugins/irc/irc-command.c b/src/plugins/irc/irc-command.c index aac4448c2..435290693 100644 --- a/src/plugins/irc/irc-command.c +++ b/src/plugins/irc/irc-command.c @@ -849,8 +849,6 @@ irc_command_cycle (void *data, struct t_gui_buffer *buffer, int argc, (buf) ? buf : ptr_arg); if (buf) free (buf); - if (version) - free (version); } else irc_server_sendf (ptr_server, "PART %s", channel_name); @@ -1085,8 +1083,6 @@ irc_command_quit_server (struct t_irc_server *server, char *arguments) (buf) ? buf : ptr_arg); if (buf) free (buf); - if (version) - free (version); } else irc_server_sendf (server, "QUIT"); @@ -2182,8 +2178,6 @@ irc_command_part (void *data, struct t_gui_buffer *buffer, int argc, (buf) ? buf : ptr_arg); if (buf) free (buf); - if (version) - free (version); } else irc_server_sendf (ptr_server, "PART %s", channel_name); diff --git a/src/plugins/irc/irc-completion.c b/src/plugins/irc/irc-completion.c index 82eb4e46f..f9c1f5f7b 100644 --- a/src/plugins/irc/irc-completion.c +++ b/src/plugins/irc/irc-completion.c @@ -90,7 +90,7 @@ irc_completion_server_nicks_cb (void *data, char *completion, for (ptr_nick = ptr_channel2->nicks; ptr_nick; ptr_nick = ptr_nick->next_nick) { - weechat_list_add (list, ptr_nick->nick, "sort"); + weechat_list_add (list, ptr_nick->name, "sort"); } } } @@ -102,7 +102,7 @@ irc_completion_server_nicks_cb (void *data, char *completion, for (ptr_nick = ptr_channel->nicks; ptr_nick; ptr_nick = ptr_nick->next_nick) { - weechat_list_add (list, ptr_nick->nick, "beginning"); + weechat_list_add (list, ptr_nick->name, "beginning"); } } @@ -184,7 +184,7 @@ irc_completion_channel_nicks_cb (void *data, char *completion, for (ptr_nick = ptr_channel->nicks; ptr_nick; ptr_nick = ptr_nick->next_nick) { - weechat_list_add (list, ptr_nick->nick, "sort"); + weechat_list_add (list, ptr_nick->name, "sort"); } /* add nicks speaking recently on this channel */ @@ -241,16 +241,16 @@ irc_completion_channel_nicks_hosts_cb (void *data, char *completion, for (ptr_nick = ptr_channel->nicks; ptr_nick; ptr_nick = ptr_nick->next_nick) { - weechat_list_add (list, ptr_nick->nick, "sort"); + weechat_list_add (list, ptr_nick->name, "sort"); if (ptr_nick->host) { - length = strlen (ptr_nick->nick) + 1 + + length = strlen (ptr_nick->name) + 1 + strlen (ptr_nick->host) + 1; buf = (char *)malloc (length); if (buf) { snprintf (buf, length, "%s!%s", - ptr_nick->nick, ptr_nick->host); + ptr_nick->name, ptr_nick->host); weechat_list_add (list, buf, "sort"); free (buf); } diff --git a/src/plugins/irc/irc-dcc.c b/src/plugins/irc/irc-dcc.c index 4c84000aa..cc7f7b928 100644 --- a/src/plugins/irc/irc-dcc.c +++ b/src/plugins/irc/irc-dcc.c @@ -124,7 +124,7 @@ irc_dcc_file_is_resumable (struct t_irc_dcc *ptr_dcc, char *filename) { struct stat st; - if (!irc_cfg_dcc_auto_resume) + if (!weechat_config_boolean (irc_config_dcc_auto_resume)) return 0; if (access (filename, W_OK) == 0) @@ -154,15 +154,24 @@ irc_dcc_file_is_resumable (struct t_irc_dcc *ptr_dcc, char *filename) void irc_dcc_find_filename (struct t_irc_dcc *ptr_dcc) { - char *dir1, *dir2, *filename2; + char *weechat_home, *dir1, *dir2, *filename2, *dir_separator; if (!IRC_DCC_IS_FILE(ptr_dcc->type)) return; - dir1 = weechat_strreplace (irc_cfg_dcc_download_path, "~", getenv ("HOME")); + dir1 = weechat_string_replace (weechat_config_string (irc_config_dcc_download_path), + "~", + getenv ("HOME")); if (!dir1) return; - dir2 = weechat_strreplace (dir1, "%h", weechat_home); + + weechat_home = weechat_info_get ("weechat_dir"); + if (!weechat_home) + { + free (dir1); + return; + } + dir2 = weechat_string_replace (dir1, "%h", weechat_home); if (!dir2) { free (dir1); @@ -176,8 +185,10 @@ irc_dcc_find_filename (struct t_irc_dcc *ptr_dcc) return; strcpy (ptr_dcc->local_filename, dir2); - if (ptr_dcc->local_filename[strlen (ptr_dcc->local_filename) - 1] != DIR_SEPARATOR_CHAR) - strcat (ptr_dcc->local_filename, DIR_SEPARATOR); + dir_separator = weechat_info_get("dir_separator"); + if (dir_separator + && (ptr_dcc->local_filename[strlen (ptr_dcc->local_filename) - 1] != dir_separator[0])) + strcat (ptr_dcc->local_filename, dir_separator); strcat (ptr_dcc->local_filename, ptr_dcc->nick); strcat (ptr_dcc->local_filename, "."); strcat (ptr_dcc->local_filename, ptr_dcc->filename); diff --git a/src/plugins/irc/irc-dcc.h b/src/plugins/irc/irc-dcc.h index f36bb0c51..00ebcc9cc 100644 --- a/src/plugins/irc/irc-dcc.h +++ b/src/plugins/irc/irc-dcc.h @@ -20,9 +20,6 @@ #ifndef __WEECHAT_IRC_DCC_H #define __WEECHAT_IRC_DCC_H 1 -#include "irc-server.h" -#include "irc-channel.h" - /* DCC types */ #define IRC_DCC_CHAT_RECV 0 /* receiving DCC chat */ diff --git a/src/plugins/irc/irc-display.c b/src/plugins/irc/irc-display.c index 6d48de902..a7ea8cb61 100644 --- a/src/plugins/irc/irc-display.c +++ b/src/plugins/irc/irc-display.c @@ -29,6 +29,7 @@ #include <string.h> #include "irc.h" +#include "irc-channel.h" #include "irc-command.h" #include "irc-config.h" #include "irc-server.h" diff --git a/src/plugins/irc/irc-mode.h b/src/plugins/irc/irc-mode.h index c53612f55..1d32ca806 100644 --- a/src/plugins/irc/irc-mode.h +++ b/src/plugins/irc/irc-mode.h @@ -20,7 +20,8 @@ #ifndef __WEECHAT_IRC_MODE_H #define __WEECHAT_IRC_MODE_H 1 -#include "irc-server.h" +struct t_irc_server; +struct t_irc_channel; extern void irc_mode_channel_set (struct t_irc_server *server, struct t_irc_channel *channel, char *modes); diff --git a/src/plugins/irc/irc-nick.c b/src/plugins/irc/irc-nick.c index d51fde31f..cdd3757fa 100644 --- a/src/plugins/irc/irc-nick.c +++ b/src/plugins/irc/irc-nick.c @@ -39,20 +39,24 @@ * irc_nick_find_color: find a color for a nick (according to nick letters) */ -int +char * irc_nick_find_color (struct t_irc_nick *nick) { int i, color; + char color_name[64]; color = 0; - for (i = strlen (nick->nick) - 1; i >= 0; i--) + for (i = strlen (nick->name) - 1; i >= 0; i--) { - color += (int)(nick->nick[i]); + color += (int)(nick->name[i]); } color = (color % weechat_config_integer (weechat_config_get_weechat ("look_color_nicks_number"))); + + snprintf (color_name, sizeof (color_name), + "color_chat_nick_color%d", color); - return color; + return weechat_color (color_name); } /* @@ -61,56 +65,66 @@ irc_nick_find_color (struct t_irc_nick *nick) */ void -irc_nick_get_gui_infos (struct t_irc_nick *nick, - int *sort_index, char *prefix, int *color_prefix) +irc_nick_get_gui_infos (struct t_gui_buffer *buffer, + struct t_irc_nick *nick, + char *prefix, int *color_prefix, + struct t_gui_nick_group **group) { if (nick->flags & IRC_NICK_CHANOWNER) { - *sort_index = 1; *prefix = '~'; *color_prefix = 1; + *group = weechat_nicklist_search_group (buffer, NULL, + IRC_NICK_GROUP_OP); } else if (nick->flags & IRC_NICK_CHANADMIN) { - *sort_index = 2; *prefix = '&'; *color_prefix = 1; + *group = weechat_nicklist_search_group (buffer, NULL, + IRC_NICK_GROUP_OP); } else if (nick->flags & IRC_NICK_CHANADMIN2) { - *sort_index = 3; *prefix = '!'; *color_prefix = 1; + *group = weechat_nicklist_search_group (buffer, NULL, + IRC_NICK_GROUP_OP); } else if (nick->flags & IRC_NICK_OP) { - *sort_index = 4; *prefix = '@'; *color_prefix = 1; + *group = weechat_nicklist_search_group (buffer, NULL, + IRC_NICK_GROUP_OP); } else if (nick->flags & IRC_NICK_HALFOP) { - *sort_index = 5; *prefix = '%'; *color_prefix = 2; + *group = weechat_nicklist_search_group (buffer, NULL, + IRC_NICK_GROUP_HALFOP); } else if (nick->flags & IRC_NICK_VOICE) { - *sort_index = 6; *prefix = '+'; *color_prefix = 3; + *group = weechat_nicklist_search_group (buffer, NULL, + IRC_NICK_GROUP_VOICE); } else if (nick->flags & IRC_NICK_CHANUSER) { - *sort_index = 7; *prefix = '-'; *color_prefix = 4; + *group = weechat_nicklist_search_group (buffer, NULL, + IRC_NICK_GROUP_CHANUSER); } else { - *sort_index = 8; *prefix = ' '; *color_prefix = 0; + *group = weechat_nicklist_search_group (buffer, NULL, + IRC_NICK_GROUP_NORMAL); } } @@ -124,52 +138,46 @@ irc_nick_new (struct t_irc_server *server, struct t_irc_channel *channel, int is_chanadmin2, int is_op, int is_halfop, int has_voice, int is_chanuser) { - (void) server; - (void) channel; - (void) nick_name; - (void) is_chanowner; - (void) is_chanadmin; - (void) is_chanadmin2; - (void) is_op; - (void) is_halfop; - (void) has_voice; - (void) is_chanuser; + struct t_irc_nick *new_nick, *ptr_nick; + char prefix, str_prefix_color[64]; + int prefix_color; + struct t_gui_nick_group *ptr_group; - /* - struct t_irc_nick *new_nick; - struct t_gui_nick *ptr_gui_nick; - int sort_index, color_prefix; - char prefix; - - // nick already exists on this channel? - if ((new_nick = irc_nick_search (channel, nick_name))) + /* nick already exists on this channel? */ + ptr_nick = irc_nick_search (channel, nick_name); + if (ptr_nick) { - // update nick - IRC_NICK_SET_FLAG(new_nick, is_chanowner, IRC_NICK_CHANOWNER); - IRC_NICK_SET_FLAG(new_nick, is_chanadmin, IRC_NICK_CHANADMIN); - IRC_NICK_SET_FLAG(new_nick, is_chanadmin2, IRC_NICK_CHANADMIN2); - IRC_NICK_SET_FLAG(new_nick, is_op, IRC_NICK_OP); - IRC_NICK_SET_FLAG(new_nick, is_halfop, IRC_NICK_HALFOP); - IRC_NICK_SET_FLAG(new_nick, has_voice, IRC_NICK_VOICE); - IRC_NICK_SET_FLAG(new_nick, is_chanuser, IRC_NICK_CHANUSER); - irc_nick_get_gui_infos (new_nick, &sort_index, &prefix, &color_prefix); - ptr_gui_nick = gui_nicklist_search (channel->buffer, new_nick->nick); - if (ptr_gui_nick) - gui_nicklist_update (channel->buffer, ptr_gui_nick, NULL, - sort_index, - ptr_gui_nick->color_nick, - prefix, - color_prefix); - - return new_nick; + /* update nick */ + IRC_NICK_SET_FLAG(ptr_nick, is_chanowner, IRC_NICK_CHANOWNER); + IRC_NICK_SET_FLAG(ptr_nick, is_chanadmin, IRC_NICK_CHANADMIN); + IRC_NICK_SET_FLAG(ptr_nick, is_chanadmin2, IRC_NICK_CHANADMIN2); + IRC_NICK_SET_FLAG(ptr_nick, is_op, IRC_NICK_OP); + IRC_NICK_SET_FLAG(ptr_nick, is_halfop, IRC_NICK_HALFOP); + IRC_NICK_SET_FLAG(ptr_nick, has_voice, IRC_NICK_VOICE); + IRC_NICK_SET_FLAG(ptr_nick, is_chanuser, IRC_NICK_CHANUSER); + + irc_nick_get_gui_infos (channel->buffer, ptr_nick, &prefix, + &prefix_color, &ptr_group); + weechat_nicklist_remove_nick (channel->buffer, + weechat_nicklist_search_nick (channel->buffer, + ptr_group, + ptr_nick->name)); + snprintf (str_prefix_color, sizeof (str_prefix_color), + "color_nicklist_prefix%d", + prefix_color); + weechat_nicklist_add_nick (channel->buffer, ptr_group, + ptr_nick->name, ptr_nick->color, + prefix, str_prefix_color, 1); + + return ptr_nick; } - // alloc memory for new nick + /* alloc memory for new nick */ if ((new_nick = (struct t_irc_nick *)malloc (sizeof (struct t_irc_nick))) == NULL) return NULL; - // initialize new nick - new_nick->nick = strdup (nick_name); + /* initialize new nick */ + new_nick->name = strdup (nick_name); new_nick->host = NULL; new_nick->flags = 0; IRC_NICK_SET_FLAG(new_nick, is_chanowner, IRC_NICK_CHANOWNER); @@ -179,12 +187,12 @@ irc_nick_new (struct t_irc_server *server, struct t_irc_channel *channel, IRC_NICK_SET_FLAG(new_nick, is_halfop, IRC_NICK_HALFOP); IRC_NICK_SET_FLAG(new_nick, has_voice, IRC_NICK_VOICE); IRC_NICK_SET_FLAG(new_nick, is_chanuser, IRC_NICK_CHANUSER); - if (weechat_strcasecmp (new_nick->nick, server->nick) == 0) - new_nick->color = GUI_COLOR_CHAT_NICK_SELF; + if (weechat_strcasecmp (new_nick->name, server->nick) == 0) + new_nick->color = IRC_COLOR_CHAT_NICK_SELF; else new_nick->color = irc_nick_find_color (new_nick); - // add nick to end of list + /* add nick to end of list */ new_nick->prev_nick = channel->last_nick; if (channel->nicks) channel->last_nick->next_nick = new_nick; @@ -197,15 +205,18 @@ irc_nick_new (struct t_irc_server *server, struct t_irc_channel *channel, channel->nick_completion_reset = 1; - // add nick to buffer nicklist - irc_nick_get_gui_infos (new_nick, &sort_index, &prefix, &color_prefix); - gui_nicklist_add (channel->buffer, new_nick->nick, sort_index, - GUI_COLOR_NICKLIST, prefix, color_prefix); - - // all is ok, return address of new nick + /* add nick to buffer nicklist */ + irc_nick_get_gui_infos (channel->buffer, new_nick, &prefix, &prefix_color, + &ptr_group); + snprintf (str_prefix_color, sizeof (str_prefix_color), + "color_nicklist_prefix%d", + prefix_color); + weechat_nicklist_add_nick (channel->buffer, ptr_group, + new_nick->name, new_nick->color, + prefix, str_prefix_color, 1); + + /* all is ok, return address of new nick */ return new_nick; - */ - return NULL; } /* @@ -216,46 +227,45 @@ void irc_nick_change (struct t_irc_server *server, struct t_irc_channel *channel, struct t_irc_nick *nick, char *new_nick) { - (void) server; - (void) channel; - (void) nick; - (void) new_nick; - - /* - int nick_is_me; - struct t_weelist *ptr_weelist; - struct t_gui_nick *ptr_nick; - - // update buffer nick - ptr_nick = gui_nicklist_search (channel->buffer, nick->nick); - if (ptr_nick) - gui_nicklist_update (channel->buffer, ptr_nick, new_nick, - ptr_nick->sort_index, - ptr_nick->color_nick, - ptr_nick->prefix, - ptr_nick->color_prefix); - - nick_is_me = (strcmp (nick->nick, server->nick) == 0) ? 1 : 0; - + int nick_is_me, prefix_color; + struct t_gui_nick_group *ptr_group; + char prefix, str_prefix_color[64]; + + /* remove nick from nicklist */ + irc_nick_get_gui_infos (channel->buffer, nick, &prefix, &prefix_color, + &ptr_group); + weechat_nicklist_remove_nick (channel->buffer, + weechat_nicklist_search_nick (channel->buffer, + ptr_group, + nick->name)); + + /* update nicks speaking */ + nick_is_me = (strcmp (nick->name, server->nick) == 0) ? 1 : 0; if (!nick_is_me && channel->nicks_speaking) { - ptr_weelist = weelist_search (channel->nicks_speaking, nick->nick); - if (ptr_weelist && ptr_weelist->data) - { - free (ptr_weelist->data); - ptr_weelist->data = strdup (new_nick); - } + weechat_list_set (weechat_list_search (channel->nicks_speaking, + nick->name), + new_nick); } - // change nickname - if (nick->nick) - free (nick->nick); - nick->nick = strdup (new_nick); + /* change nickname */ + if (nick->name) + free (nick->name); + nick->name = strdup (new_nick); if (nick_is_me) - nick->color = GUI_COLOR_CHAT_NICK_SELF; + nick->color = IRC_COLOR_CHAT_NICK_SELF; else nick->color = irc_nick_find_color (nick); - */ + + /* add nick in nicklist */ + irc_nick_get_gui_infos (channel->buffer, nick, &prefix, &prefix_color, + &ptr_group); + snprintf (str_prefix_color, sizeof (str_prefix_color), + "color_nicklist_prefix%d", + prefix_color); + weechat_nicklist_add_nick (channel->buffer, ptr_group, + nick->name, nick->color, + prefix, str_prefix_color, 1); } /* @@ -265,19 +275,23 @@ irc_nick_change (struct t_irc_server *server, struct t_irc_channel *channel, void irc_nick_free (struct t_irc_channel *channel, struct t_irc_nick *nick) { - (void) channel; - (void) nick; - - /* struct t_irc_nick *new_nicks; + char prefix; + int prefix_color; + struct t_gui_nick_group *ptr_group; if (!channel || !nick) return; - // remove nick from buffer nicklist - (void) gui_nicklist_remove (channel->buffer, nick->nick); + /* remove nick from nicklist */ + irc_nick_get_gui_infos (channel->buffer, nick, &prefix, &prefix_color, + &ptr_group); + weechat_nicklist_remove_nick (channel->buffer, + weechat_nicklist_search_nick (channel->buffer, + ptr_group, + nick->name)); - // remove nick from nicks list + /* remove nick */ if (channel->last_nick == nick) channel->last_nick = nick->prev_nick; if (nick->prev_nick) @@ -293,16 +307,15 @@ irc_nick_free (struct t_irc_channel *channel, struct t_irc_nick *nick) channel->nicks_count--; - // free data - if (nick->nick) - free (nick->nick); + /* free data */ + if (nick->name) + free (nick->name); if (nick->host) free (nick->host); free (nick); channel->nicks = new_nicks; channel->nick_completion_reset = 1; - */ } /* @@ -338,7 +351,7 @@ irc_nick_search (struct t_irc_channel *channel, char *nickname) for (ptr_nick = channel->nicks; ptr_nick; ptr_nick = ptr_nick->next_nick) { - if (weechat_strcasecmp (ptr_nick->nick, nickname) == 0) + if (weechat_strcasecmp (ptr_nick->name, nickname) == 0) return ptr_nick; } return NULL; @@ -438,7 +451,7 @@ irc_nick_as_prefix (struct t_irc_nick *nick, char *nickname, char *force_color) && weechat_config_string (irc_config_irc_nick_prefix)[0]) ? weechat_config_string (irc_config_irc_nick_prefix) : "", (force_color) ? force_color : ((nick) ? nick->color : IRC_COLOR_CHAT_NICK), - (nick) ? nick->nick : nickname, + (nick) ? nick->name : nickname, (weechat_config_string (irc_config_irc_nick_suffix) && weechat_config_string (irc_config_irc_nick_suffix)[0]) ? IRC_COLOR_CHAT_DELIMITERS : "", @@ -456,10 +469,11 @@ irc_nick_as_prefix (struct t_irc_nick *nick, char *nickname, char *force_color) void irc_nick_print_log (struct t_irc_nick *nick) { - weechat_log_printf ("=> nick %s (addr:0x%X):", nick->nick, nick); - weechat_log_printf (" host . . . . . : %s", nick->host); - weechat_log_printf (" flags. . . . . : %d", nick->flags); - weechat_log_printf (" color. . . . . : %d", nick->color); - weechat_log_printf (" prev_nick. . . : 0x%X", nick->prev_nick); - weechat_log_printf (" next_nick. . . : 0x%X", nick->next_nick); + weechat_log_printf (""); + weechat_log_printf (" => nick %s (addr:0x%X):", nick->name, nick); + weechat_log_printf (" host . . . . . : %s", nick->host); + weechat_log_printf (" flags. . . . . : %d", nick->flags); + weechat_log_printf (" color. . . . . : '%s'", nick->color); + weechat_log_printf (" prev_nick. . . : 0x%X", nick->prev_nick); + weechat_log_printf (" next_nick. . . : 0x%X", nick->next_nick); } diff --git a/src/plugins/irc/irc-nick.h b/src/plugins/irc/irc-nick.h index f0bc5ecd5..f26561370 100644 --- a/src/plugins/irc/irc-nick.h +++ b/src/plugins/irc/irc-nick.h @@ -20,9 +20,6 @@ #ifndef __WEECHAT_IRC_NICK_H #define __WEECHAT_IRC_NICK_H 1 -#include "irc-server.h" -#include "irc-channel.h" - #define IRC_NICK_DEFAULT_PREFIXES_LIST "@%+~&!-" #define IRC_NICK_CHANOWNER 1 @@ -39,9 +36,18 @@ else \ nick->flags &= 0xFFFF - flag; +#define IRC_NICK_GROUP_OP "1|op" +#define IRC_NICK_GROUP_HALFOP "2|halfop" +#define IRC_NICK_GROUP_VOICE "3|voice" +#define IRC_NICK_GROUP_CHANUSER "4|chanuser" +#define IRC_NICK_GROUP_NORMAL "5|normal" + +struct t_irc_server; +struct t_irc_channel; + struct t_irc_nick { - char *nick; /* nickname */ + char *name; /* nickname */ char *host; /* full hostname */ int flags; /* chanowner/chanadmin (unrealircd), */ /* op, halfop, voice, away */ @@ -50,9 +56,6 @@ struct t_irc_nick struct t_irc_nick *next_nick; /* link to next nick on channel */ }; -extern int irc_nick_find_color (struct t_irc_nick *nick); -extern void irc_nick_get_gui_infos (struct t_irc_nick *nick, int *sort_index, - char *prefix, int *color_prefix); extern struct t_irc_nick *irc_nick_new (struct t_irc_server *server, struct t_irc_channel *channel, char *nick_name, int is_chanowner, diff --git a/src/plugins/irc/irc-protocol.c b/src/plugins/irc/irc-protocol.c index 87d7415e3..1494a123c 100644 --- a/src/plugins/irc/irc-protocol.c +++ b/src/plugins/irc/irc-protocol.c @@ -16,8 +16,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* irc-protocol.c: description of IRC commands, according to - RFC 1459,2810,2811,2812 */ +/* irc-protocol.c: description of IRC commands, according to RFC 1459, 2810, + 2811 2812 */ #ifdef HAVE_CONFIG_H @@ -54,129 +54,126 @@ struct t_irc_protocol_msg irc_protocol_messages[] = -{ { "error", N_("error received from IRC server"), irc_protocol_cmd_error }, - { "invite", N_("invite a nick on a channel"), irc_protocol_cmd_invite }, - { "join", N_("join a channel"), irc_protocol_cmd_join }, - { "kick", N_("forcibly remove a user from a channel"), irc_protocol_cmd_kick }, - { "kill", N_("close client-server connection"), irc_protocol_cmd_kill }, - { "mode", N_("change channel or user mode"), irc_protocol_cmd_mode }, - { "nick", N_("change current nickname"), irc_protocol_cmd_nick }, - { "notice", N_("send notice message to user"), irc_protocol_cmd_notice }, - { "part", N_("leave a channel"), irc_protocol_cmd_part }, - { "ping", N_("ping server"), irc_protocol_cmd_ping }, - { "pong", N_("answer to a ping message"), irc_protocol_cmd_pong }, - { "privmsg", N_("message received"), irc_protocol_cmd_privmsg }, - { "quit", N_("close all connections and quit"), irc_protocol_cmd_quit }, - { "topic", N_("get/set channel topic"), irc_protocol_cmd_topic }, +{ { "error", N_("error received from IRC server"), NULL, irc_protocol_cmd_error }, + { "invite", N_("invite a nick on a channel"), NULL, irc_protocol_cmd_invite }, + { "join", N_("join a channel"), NULL, irc_protocol_cmd_join }, + { "kick", N_("forcibly remove a user from a channel"), irc_protocol_cmd_kick, NULL }, + { "kill", N_("close client-server connection"), irc_protocol_cmd_kill, NULL }, + { "mode", N_("change channel or user mode"), irc_protocol_cmd_mode, NULL }, + { "nick", N_("change current nickname"), irc_protocol_cmd_nick, NULL }, + { "notice", N_("send notice message to user"), irc_protocol_cmd_notice, NULL }, + { "part", N_("leave a channel"), irc_protocol_cmd_part, NULL }, + { "ping", N_("ping server"), irc_protocol_cmd_ping, NULL }, + { "pong", N_("answer to a ping message"), irc_protocol_cmd_pong, NULL }, + { "privmsg", N_("message received"), irc_protocol_cmd_privmsg, NULL }, + { "quit", N_("close all connections and quit"), irc_protocol_cmd_quit, NULL }, + { "topic", N_("get/set channel topic"), irc_protocol_cmd_topic, NULL }, { "wallops", N_("send a message to all currently connected users who have " - "set the 'w' user mode for themselves"), irc_protocol_cmd_wallops }, - { "001", N_("a server message"), irc_protocol_cmd_001 }, - { "005", N_("a server message"), irc_protocol_cmd_005 }, - { "221", N_("user mode string"), irc_protocol_cmd_221 }, - { "301", N_("away message"), irc_protocol_cmd_301 }, - { "302", N_("userhost"), irc_protocol_cmd_302 }, - { "303", N_("ison"), irc_protocol_cmd_303 }, - { "305", N_("unaway"), irc_protocol_cmd_305 }, - { "306", N_("now away"), irc_protocol_cmd_306 }, - { "307", N_("whois (registered nick)"), irc_protocol_cmd_whois_nick_msg }, - { "310", N_("whois (help mode)"), irc_protocol_cmd_310 }, - { "311", N_("whois (user)"), irc_protocol_cmd_311 }, - { "312", N_("whois (server)"), irc_protocol_cmd_312 }, - { "313", N_("whois (operator)"), irc_protocol_cmd_whois_nick_msg }, - { "314", N_("whowas"), irc_protocol_cmd_314 }, - { "315", N_("end of /who list"), irc_protocol_cmd_315 }, - { "317", N_("whois (idle)"), irc_protocol_cmd_317 }, - { "318", N_("whois (end)"), irc_protocol_cmd_whois_nick_msg }, - { "319", N_("whois (channels)"), irc_protocol_cmd_319 }, - { "320", N_("whois (identified user)"), irc_protocol_cmd_whois_nick_msg }, - { "321", N_("/list start"), irc_protocol_cmd_321 }, - { "322", N_("channel (for /list)"), irc_protocol_cmd_322 }, - { "323", N_("/list end"), irc_protocol_cmd_323 }, - { "324", N_("channel mode"), irc_protocol_cmd_324 }, - { "326", N_("whois (has oper privs)"), irc_protocol_cmd_whois_nick_msg }, - { "327", N_("whois (host)"), irc_protocol_cmd_327 }, - { "329", N_("channel creation date"), irc_protocol_cmd_329 }, - { "331", N_("no topic for channel"), irc_protocol_cmd_331 }, - { "332", N_("topic of channel"), irc_protocol_cmd_332 }, - { "333", N_("infos about topic (nick and date changed)"), irc_protocol_cmd_333 }, - { "338", N_("whois (host)"), irc_protocol_cmd_338 }, - { "341", N_("inviting"), irc_protocol_cmd_341 }, - { "344", N_("channel reop"), irc_protocol_cmd_344 }, - { "345", N_("end of channel reop list"), irc_protocol_cmd_345 }, - { "348", N_("channel exception list"), irc_protocol_cmd_348 }, - { "349", N_("end of channel exception list"), irc_protocol_cmd_349 }, - { "351", N_("server version"), irc_protocol_cmd_351 }, - { "352", N_("who"), irc_protocol_cmd_352 }, - { "353", N_("list of nicks on channel"), irc_protocol_cmd_353 }, - { "366", N_("end of /names list"), irc_protocol_cmd_366 }, - { "367", N_("banlist"), irc_protocol_cmd_367 }, - { "368", N_("end of banlist"), irc_protocol_cmd_368 }, - { "378", N_("whois (connecting from)"), irc_protocol_cmd_whois_nick_msg }, - { "379", N_("whois (using modes)"), irc_protocol_cmd_whois_nick_msg }, - { "401", N_("no such nick/channel"), irc_protocol_cmd_error }, - { "402", N_("no such server"), irc_protocol_cmd_error }, - { "403", N_("no such channel"), irc_protocol_cmd_error }, - { "404", N_("cannot send to channel"), irc_protocol_cmd_error }, - { "405", N_("too many channels"), irc_protocol_cmd_error }, - { "406", N_("was no such nick"), irc_protocol_cmd_error }, - { "407", N_("was no such nick"), irc_protocol_cmd_error }, - { "409", N_("no origin"), irc_protocol_cmd_error }, - { "410", N_("no services"), irc_protocol_cmd_error }, - { "411", N_("no recipient"), irc_protocol_cmd_error }, - { "412", N_("no text to send"), irc_protocol_cmd_error }, - { "413", N_("no toplevel"), irc_protocol_cmd_error }, - { "414", N_("wilcard in toplevel domain"), irc_protocol_cmd_error }, - { "421", N_("unknown command"), irc_protocol_cmd_error }, - { "422", N_("MOTD is missing"), irc_protocol_cmd_error }, - { "423", N_("no administrative info"), irc_protocol_cmd_error }, - { "424", N_("file error"), irc_protocol_cmd_error }, - { "431", N_("no nickname given"), irc_protocol_cmd_error }, - { "432", N_("erroneous nickname"), irc_protocol_cmd_432 }, - { "433", N_("nickname already in use"), irc_protocol_cmd_433 }, - { "436", N_("nickname collision"), irc_protocol_cmd_error }, - { "437", N_("resource unavailable"), irc_protocol_cmd_error }, - { "438", N_("not authorized to change nickname"), irc_protocol_cmd_438 }, - { "441", N_("user not in channel"), irc_protocol_cmd_error }, - { "442", N_("not on channel"), irc_protocol_cmd_error }, - { "443", N_("user already on channel"), irc_protocol_cmd_error }, - { "444", N_("user not logged in"), irc_protocol_cmd_error }, - { "445", N_("summon has been disabled"), irc_protocol_cmd_error }, - { "446", N_("users has been disabled"), irc_protocol_cmd_error }, - { "451", N_("you are not registered"), irc_protocol_cmd_error }, - { "461", N_("not enough parameters"), irc_protocol_cmd_error }, - { "462", N_("you may not register"), irc_protocol_cmd_error }, - { "463", N_("your host isn't among the privileged"), irc_protocol_cmd_error }, - { "464", N_("password incorrect"), irc_protocol_cmd_error }, - { "465", N_("you are banned from this server"), irc_protocol_cmd_error }, - { "467", N_("channel key already set"), irc_protocol_cmd_error }, - { "470", N_("forwarding to another channel"), irc_protocol_cmd_error }, - { "471", N_("channel is already full"), irc_protocol_cmd_error }, - { "472", N_("unknown mode char to me"), irc_protocol_cmd_error }, - { "473", N_("cannot join channel (invite only)"), irc_protocol_cmd_error }, - { "474", N_("cannot join channel (banned from channel)"), irc_protocol_cmd_error }, - { "475", N_("cannot join channel (bad channel key)"), irc_protocol_cmd_error }, - { "476", N_("bad channel mask"), irc_protocol_cmd_error }, - { "477", N_("channel doesn't support modes"), irc_protocol_cmd_error }, - { "481", N_("you're not an IRC operator"), irc_protocol_cmd_error }, - { "482", N_("you're not channel operator"), irc_protocol_cmd_error }, - { "483", N_("you can't kill a server!"), irc_protocol_cmd_error }, - { "484", N_("your connection is restricted!"), irc_protocol_cmd_error }, - { "485", N_("user is immune from kick/deop"), irc_protocol_cmd_error }, - { "487", N_("network split"), irc_protocol_cmd_error }, - { "491", N_("no O-lines for your host"), irc_protocol_cmd_error }, - { "501", N_("unknown mode flag"), irc_protocol_cmd_error }, - { "502", N_("can't change mode for other users"), irc_protocol_cmd_error }, - { "671", N_("whois (secure connection)"), irc_protocol_cmd_671 }, - { "973", N_("whois (secure connection)"), irc_protocol_cmd_server_mode_reason }, - { "974", N_("whois (secure connection)"), irc_protocol_cmd_server_mode_reason }, - { "975", N_("whois (secure connection)"), irc_protocol_cmd_server_mode_reason }, - { NULL, NULL, NULL } + "set the 'w' user mode for themselves"), irc_protocol_cmd_wallops, NULL }, + { "001", N_("a server message"), irc_protocol_cmd_001, NULL }, + { "005", N_("a server message"), irc_protocol_cmd_005, NULL }, + { "221", N_("user mode string"), irc_protocol_cmd_221, NULL }, + { "301", N_("away message"), irc_protocol_cmd_301, NULL }, + { "302", N_("userhost"), irc_protocol_cmd_302, NULL }, + { "303", N_("ison"), irc_protocol_cmd_303, NULL }, + { "305", N_("unaway"), irc_protocol_cmd_305, NULL }, + { "306", N_("now away"), irc_protocol_cmd_306, NULL }, + { "307", N_("whois (registered nick)"), irc_protocol_cmd_whois_nick_msg, NULL }, + { "310", N_("whois (help mode)"), irc_protocol_cmd_310, NULL }, + { "311", N_("whois (user)"), irc_protocol_cmd_311, NULL }, + { "312", N_("whois (server)"), irc_protocol_cmd_312, NULL }, + { "313", N_("whois (operator)"), irc_protocol_cmd_whois_nick_msg, NULL }, + { "314", N_("whowas"), irc_protocol_cmd_314, NULL }, + { "315", N_("end of /who list"), irc_protocol_cmd_315, NULL }, + { "317", N_("whois (idle)"), irc_protocol_cmd_317, NULL }, + { "318", N_("whois (end)"), irc_protocol_cmd_whois_nick_msg, NULL }, + { "319", N_("whois (channels)"), irc_protocol_cmd_319, NULL }, + { "320", N_("whois (identified user)"), irc_protocol_cmd_whois_nick_msg, NULL }, + { "321", N_("/list start"), irc_protocol_cmd_321, NULL }, + { "322", N_("channel (for /list)"), irc_protocol_cmd_322, NULL }, + { "323", N_("/list end"), irc_protocol_cmd_323, NULL }, + { "324", N_("channel mode"), irc_protocol_cmd_324, NULL }, + { "326", N_("whois (has oper privs)"), irc_protocol_cmd_whois_nick_msg, NULL }, + { "327", N_("whois (host)"), irc_protocol_cmd_327, NULL }, + { "329", N_("channel creation date"), irc_protocol_cmd_329, NULL }, + { "331", N_("no topic for channel"), irc_protocol_cmd_331, NULL }, + { "332", N_("topic of channel"), irc_protocol_cmd_332, NULL }, + { "333", N_("infos about topic (nick and date changed)"), irc_protocol_cmd_333, NULL }, + { "338", N_("whois (host)"), irc_protocol_cmd_338, NULL }, + { "341", N_("inviting"), irc_protocol_cmd_341, NULL }, + { "344", N_("channel reop"), irc_protocol_cmd_344, NULL }, + { "345", N_("end of channel reop list"), irc_protocol_cmd_345, NULL }, + { "348", N_("channel exception list"), irc_protocol_cmd_348, NULL }, + { "349", N_("end of channel exception list"), irc_protocol_cmd_349, NULL }, + { "351", N_("server version"), irc_protocol_cmd_351, NULL }, + { "352", N_("who"), irc_protocol_cmd_352, NULL }, + { "353", N_("list of nicks on channel"), irc_protocol_cmd_353, NULL }, + { "366", N_("end of /names list"), irc_protocol_cmd_366, NULL }, + { "367", N_("banlist"), irc_protocol_cmd_367, NULL }, + { "368", N_("end of banlist"), irc_protocol_cmd_368, NULL }, + { "378", N_("whois (connecting from)"), irc_protocol_cmd_whois_nick_msg, NULL }, + { "379", N_("whois (using modes)"), irc_protocol_cmd_whois_nick_msg, NULL }, + { "401", N_("no such nick/channel"), NULL, irc_protocol_cmd_error }, + { "402", N_("no such server"), NULL, irc_protocol_cmd_error }, + { "403", N_("no such channel"), NULL, irc_protocol_cmd_error }, + { "404", N_("cannot send to channel"), NULL, irc_protocol_cmd_error }, + { "405", N_("too many channels"), NULL, irc_protocol_cmd_error }, + { "406", N_("was no such nick"), NULL, irc_protocol_cmd_error }, + { "407", N_("was no such nick"), NULL, irc_protocol_cmd_error }, + { "409", N_("no origin"), NULL, irc_protocol_cmd_error }, + { "410", N_("no services"), NULL, irc_protocol_cmd_error }, + { "411", N_("no recipient"), NULL, irc_protocol_cmd_error }, + { "412", N_("no text to send"), NULL, irc_protocol_cmd_error }, + { "413", N_("no toplevel"), NULL, irc_protocol_cmd_error }, + { "414", N_("wilcard in toplevel domain"), NULL, irc_protocol_cmd_error }, + { "421", N_("unknown command"), NULL, irc_protocol_cmd_error }, + { "422", N_("MOTD is missing"), NULL, irc_protocol_cmd_error }, + { "423", N_("no administrative info"), NULL, irc_protocol_cmd_error }, + { "424", N_("file error"), NULL, irc_protocol_cmd_error }, + { "431", N_("no nickname given"), NULL, irc_protocol_cmd_error }, + { "432", N_("erroneous nickname"), NULL, irc_protocol_cmd_432 }, + { "433", N_("nickname already in use"), NULL, irc_protocol_cmd_433 }, + { "436", N_("nickname collision"), NULL, irc_protocol_cmd_error }, + { "437", N_("resource unavailable"), NULL, irc_protocol_cmd_error }, + { "438", N_("not authorized to change nickname"), irc_protocol_cmd_438, NULL }, + { "441", N_("user not in channel"), NULL, irc_protocol_cmd_error }, + { "442", N_("not on channel"), NULL, irc_protocol_cmd_error }, + { "443", N_("user already on channel"), NULL, irc_protocol_cmd_error }, + { "444", N_("user not logged in"), NULL, irc_protocol_cmd_error }, + { "445", N_("summon has been disabled"), NULL, irc_protocol_cmd_error }, + { "446", N_("users has been disabled"), NULL, irc_protocol_cmd_error }, + { "451", N_("you are not registered"), NULL, irc_protocol_cmd_error }, + { "461", N_("not enough parameters"), NULL, irc_protocol_cmd_error }, + { "462", N_("you may not register"), NULL, irc_protocol_cmd_error }, + { "463", N_("your host isn't among the privileged"), NULL, irc_protocol_cmd_error }, + { "464", N_("password incorrect"), NULL, irc_protocol_cmd_error }, + { "465", N_("you are banned from this server"), NULL, irc_protocol_cmd_error }, + { "467", N_("channel key already set"), NULL, irc_protocol_cmd_error }, + { "470", N_("forwarding to another channel"), NULL, irc_protocol_cmd_error }, + { "471", N_("channel is already full"), NULL, irc_protocol_cmd_error }, + { "472", N_("unknown mode char to me"), NULL, irc_protocol_cmd_error }, + { "473", N_("cannot join channel (invite only)"), NULL, irc_protocol_cmd_error }, + { "474", N_("cannot join channel (banned from channel)"), NULL, irc_protocol_cmd_error }, + { "475", N_("cannot join channel (bad channel key)"), NULL, irc_protocol_cmd_error }, + { "476", N_("bad channel mask"), NULL, irc_protocol_cmd_error }, + { "477", N_("channel doesn't support modes"), NULL, irc_protocol_cmd_error }, + { "481", N_("you're not an IRC operator"), NULL, irc_protocol_cmd_error }, + { "482", N_("you're not channel operator"), NULL, irc_protocol_cmd_error }, + { "483", N_("you can't kill a server!"), NULL, irc_protocol_cmd_error }, + { "484", N_("your connection is restricted!"), NULL, irc_protocol_cmd_error }, + { "485", N_("user is immune from kick/deop"), NULL, irc_protocol_cmd_error }, + { "487", N_("network split"), NULL, irc_protocol_cmd_error }, + { "491", N_("no O-lines for your host"), NULL, irc_protocol_cmd_error }, + { "501", N_("unknown mode flag"), NULL, irc_protocol_cmd_error }, + { "502", N_("can't change mode for other users"), NULL, irc_protocol_cmd_error }, + { "671", N_("whois (secure connection)"), irc_protocol_cmd_671, NULL }, + { "973", N_("whois (secure connection)"), irc_protocol_cmd_server_mode_reason, NULL }, + { "974", N_("whois (secure connection)"), irc_protocol_cmd_server_mode_reason, NULL }, + { "975", N_("whois (secure connection)"), irc_protocol_cmd_server_mode_reason, NULL }, + { NULL, NULL, NULL, NULL } }; -char *irc_message = NULL; - - /* * irc_protocol_get_wide_char: get wide char from string (first char) */ @@ -394,7 +391,8 @@ irc_protocol_is_highlight (char *message, char *nick) */ char * -irc_protocol_replace_vars (struct t_irc_server *server, struct t_irc_channel *channel, char *string) +irc_protocol_replace_vars (struct t_irc_server *server, + struct t_irc_channel *channel, char *string) { char *var_nick, *var_channel, *var_server; char empty_string[1] = { '\0' }; @@ -429,6 +427,57 @@ irc_protocol_replace_vars (struct t_irc_server *server, struct t_irc_channel *ch } /* + * irc_protocol_get_nick_from_host: get nick from host in an IRC message + */ + +char * +irc_protocol_get_nick_from_host (char *host) +{ + static char nick[128]; + char *pos; + + nick[0] = '\0'; + if (host) + { + if (host[0] == ':') + host++; + pos = strchr (host, '!'); + if (pos && (pos - host < (int)sizeof (nick))) + { + strncpy (nick, host, pos - host); + nick[pos - host] = '\0'; + } + else + snprintf (nick, sizeof (nick), "%s", host); + } + return nick; +} + +/* + * irc_protocol_get_address_from_host: get address from host in an IRC message + */ + +char * +irc_protocol_get_address_from_host (char *host) +{ + static char address[256]; + char *pos; + + address[0] = '\0'; + if (host) + { + if (host[0] == ':') + host++; + pos = strchr (host, '!'); + if (pos) + snprintf (address, sizeof (address), "%s", pos + 1); + else + snprintf (address, sizeof (address), "%s", host); + } + return address; +} + +/* * irc_protocol_recv_command: executes action when receiving IRC command * return: 0 = all ok, command executed * -1 = command failed @@ -440,11 +489,12 @@ int irc_protocol_recv_command (struct t_irc_server *server, char *entire_line, char *host, char *command, char *arguments) { - int i, cmd_found, return_code, ignore, highlight; + int i, cmd_found, return_code, ignore, highlight, argc; char *pos, *nick; char *dup_entire_line, *dup_host, *dup_arguments, *irc_message; t_irc_recv_func *cmd_recv_func; - char *cmd_name; + t_irc_recv_func2 *cmd_recv_func2; + char *cmd_name, **argv, **argv_eol; if (!command) return -2; @@ -468,6 +518,7 @@ irc_protocol_recv_command (struct t_irc_server *server, char *entire_line, { cmd_name = command; cmd_recv_func = irc_protocol_cmd_server_msg; + cmd_recv_func2 = NULL; } else return -3; @@ -476,10 +527,13 @@ irc_protocol_recv_command (struct t_irc_server *server, char *entire_line, { cmd_name = irc_protocol_messages[cmd_found].name; cmd_recv_func = irc_protocol_messages[cmd_found].recv_function; + cmd_recv_func2 = irc_protocol_messages[cmd_found].recv_function2; } - if (cmd_recv_func != NULL) + if ((cmd_recv_func != NULL) || (cmd_recv_func2 != NULL)) { + argv = weechat_string_explode (entire_line, " ", 0, 0, &argc); + argv_eol = weechat_string_explode (entire_line, " ", 1, 0, NULL); dup_entire_line = (entire_line) ? strdup (entire_line) : NULL; dup_host = (host) ? strdup (host) : NULL; dup_arguments = (arguments) ? strdup (arguments) : NULL; @@ -505,10 +559,19 @@ irc_protocol_recv_command (struct t_irc_server *server, char *entire_line, if (pos) pos[0] = '!'; irc_message = strdup (dup_entire_line); - return_code = (int) (cmd_recv_func) (server, irc_message, - dup_host, nick, - dup_arguments, - ignore, highlight); + + if (cmd_recv_func2 != NULL) + { + return_code = (int) (cmd_recv_func2) (server, argc, argv, argv_eol, + ignore, highlight); + } + else + { + return_code = (int) (cmd_recv_func) (server, irc_message, + dup_host, nick, + dup_arguments, + ignore, highlight); + } if (irc_message) free (irc_message); if (nick) @@ -519,6 +582,10 @@ irc_protocol_recv_command (struct t_irc_server *server, char *entire_line, free (dup_host); if (dup_arguments) free (dup_arguments); + if (argv) + weechat_string_free_exploded (argv); + if (argv_eol) + weechat_string_free_exploded (argv_eol); return return_code; } @@ -530,53 +597,41 @@ irc_protocol_recv_command (struct t_irc_server *server, char *entire_line, */ int -irc_protocol_cmd_error (struct t_irc_server *server, char *irc_message, char *host, - char *nick, char *arguments, int ignore, int highlight) +irc_protocol_cmd_error (struct t_irc_server *server, int argc, char **argv, + char **argv_eol, int ignore, int highlight) { - char *pos_args, *pos; - int first; + int first_arg; + char *chan_nick, *args; /* make C compiler happy */ - (void) irc_message; - (void) host; - (void) nick; + (void) argc; (void) ignore; (void) highlight; - first = 1; + first_arg = (strcmp (argv[2], server->nick) == 0) ? 3 : 2; - pos_args = strstr (arguments, " :"); - if (pos_args) + if ((argv[first_arg][0] != ':') && argv[first_arg + 1]) { - pos_args[0] = '\0'; - if (weechat_strncasecmp (arguments, server->nick, - strlen (server->nick)) == 0) - { - pos = strchr (arguments, ' '); - if (pos) - { - while (pos[0] == ' ') - pos++; - } - else - pos = arguments; - } - else - { - pos = arguments; - } - weechat_printf (server->buffer, "%s%s: %s", - weechat_prefix ("error"), - pos, pos_args + 2); - if (strncmp (arguments, "Closing Link", 12) == 0) - irc_server_disconnect (server, 1); + chan_nick = argv[first_arg]; + args = argv_eol[first_arg + 1]; } else { - weechat_printf (server->buffer, "%s%s", - weechat_prefix ("error"), - arguments); + chan_nick = NULL; + args = argv_eol[first_arg]; } + if (args[0] == ':') + args++; + + weechat_printf (server->buffer, + "%s%s%s%s", + weechat_prefix ("error"), + (chan_nick) ? chan_nick : "", + (chan_nick) ? ": " : "", + args); + + if (strncmp (args, "Closing Link", 12) == 0) + irc_server_disconnect (server, 1); return WEECHAT_RC_OK; } @@ -586,47 +641,34 @@ irc_protocol_cmd_error (struct t_irc_server *server, char *irc_message, char *ho */ int -irc_protocol_cmd_invite (struct t_irc_server *server, char *irc_message, char *host, - char *nick, char *arguments, int ignore, int highlight) +irc_protocol_cmd_invite (struct t_irc_server *server, int argc, char **argv, + char **argv_eol, int ignore, int highlight) { - char *pos_channel; - /* make C compiler happy */ - (void) irc_message; - (void) host; + (void) argc; + (void) argv_eol; (void) highlight; - pos_channel = strchr (arguments, ' '); - if (pos_channel) + if (!ignore && argv[3]) { - pos_channel[0] = '\0'; - pos_channel++; - while (pos_channel[0] == ' ') - pos_channel++; - if (pos_channel[0] == ':') - pos_channel++; - - if (!ignore) - { - weechat_printf (server->buffer, - _("You have been invited to %s%s%s by " - "%s%s"), - IRC_COLOR_CHAT_CHANNEL, - pos_channel, - IRC_COLOR_CHAT, - IRC_COLOR_CHAT_NICK, - nick); - /* - if (gui_add_hotlist - && ((server->buffer->num_displayed == 0) - || (gui_buffer_is_scrolled (server->buffer)))) - { - gui_hotlist_add (GUI_HOTLIST_HIGHLIGHT, NULL, - server->buffer, 0); - gui_status_draw (gui_current_window->buffer, 1); - } - */ - } + weechat_printf (server->buffer, + _("You have been invited to %s%s%s by " + "%s%s"), + IRC_COLOR_CHAT_CHANNEL, + (argv[3][0] == ':') ? argv[3] + 1 : argv[3], + IRC_COLOR_CHAT, + IRC_COLOR_CHAT_NICK, + irc_protocol_get_nick_from_host (argv[0])); + /* + if (gui_add_hotlist + && ((server->buffer->num_displayed == 0) + || (gui_buffer_is_scrolled (server->buffer)))) + { + gui_hotlist_add (GUI_HOTLIST_HIGHLIGHT, NULL, + server->buffer, 0); + gui_status_draw (gui_current_window->buffer, 1); + } + */ } else { @@ -646,19 +688,20 @@ irc_protocol_cmd_invite (struct t_irc_server *server, char *irc_message, char *h */ int -irc_protocol_cmd_join (struct t_irc_server *server, char *irc_message, char *host, - char *nick, char *arguments, int ignore, int highlight) +irc_protocol_cmd_join (struct t_irc_server *server, int argc, char **argv, + char **argv_eol, int ignore, int highlight) { struct t_irc_channel *ptr_channel; struct t_irc_nick *ptr_nick; - char *pos; - + char *pos_channel; + /* make C compiler happy */ - (void) irc_message; + (void) argc; + (void) argv_eol; (void) highlight; /* no host => we can't identify sender of message! */ - if (!host) + if (argv[0][0] != ':') { weechat_printf (server->buffer, _("%s%s: \"%s\" command received without host"), @@ -666,38 +709,35 @@ irc_protocol_cmd_join (struct t_irc_server *server, char *irc_message, char *hos return WEECHAT_RC_ERROR; } - if (arguments[0] == ':') - arguments++; - - ptr_channel = irc_channel_search (server, arguments); + pos_channel = (argv[2][0] == ':') ? argv[2] + 1 : argv[2]; + ptr_channel = irc_channel_search (server, pos_channel); if (!ptr_channel) { ptr_channel = irc_channel_new (server, IRC_CHANNEL_TYPE_CHANNEL, - arguments, 1); + pos_channel, 1); if (!ptr_channel) { weechat_printf (server->buffer, _("%s%s: cannot create new channel \"%s\""), - weechat_prefix ("error"), "irc", arguments); + weechat_prefix ("error"), "irc", pos_channel); return WEECHAT_RC_ERROR; } } - pos = strchr (host, '!'); if (!ignore) { weechat_printf (ptr_channel->buffer, _("%s%s%s %s(%s%s%s)%s has joined %s%s"), weechat_prefix ("join"), IRC_COLOR_CHAT_NICK, - nick, + irc_protocol_get_nick_from_host (argv[0]), IRC_COLOR_CHAT_DELIMITERS, IRC_COLOR_CHAT_HOST, - (pos) ? pos + 1 : host, + irc_protocol_get_address_from_host (argv[0]), IRC_COLOR_CHAT_DELIMITERS, IRC_COLOR_CHAT, IRC_COLOR_CHAT_CHANNEL, - arguments); + pos_channel); } /* remove topic and display channel creation date if joining new channel */ @@ -713,9 +753,11 @@ irc_protocol_cmd_join (struct t_irc_server *server, char *irc_message, char *hos } /* add nick in channel */ - ptr_nick = irc_nick_new (server, ptr_channel, nick, 0, 0, 0, 0, 0, 0, 0); + ptr_nick = irc_nick_new (server, ptr_channel, + irc_protocol_get_nick_from_host (argv[0]), + 0, 0, 0, 0, 0, 0, 0); if (ptr_nick) - ptr_nick->host = strdup ((pos) ? pos + 1 : host); + ptr_nick->host = strdup (irc_protocol_get_address_from_host (argv[0])); /* redraw nicklist and status bar */ //gui_nicklist_draw (ptr_channel->buffer, 1, 1); @@ -1082,7 +1124,7 @@ irc_protocol_cmd_nick (struct t_irc_server *server, char *irc_message, char *hos ptr_nick = irc_nick_search (ptr_channel, nick); if (ptr_nick) { - nick_is_me = (strcmp (ptr_nick->nick, server->nick) == 0) ? 1 : 0; + nick_is_me = (strcmp (ptr_nick->name, server->nick) == 0) ? 1 : 0; //if (nick_is_me) // gui_add_hotlist = 0; irc_nick_change (server, ptr_channel, ptr_nick, arguments); @@ -1403,7 +1445,8 @@ irc_protocol_cmd_part (struct t_irc_server *server, char *irc_message, char *hos if (pos_args && pos_args[0]) { weechat_printf (ptr_channel->buffer, - _("%s%s %s(%s%s%s)%s has left %s%s %s(%s%s%s)"), + _("%s%s%s %s(%s%s%s)%s has left %s%s %s(%s%s%s)"), + weechat_prefix ("quit"), IRC_COLOR_CHAT_NICK, nick, IRC_COLOR_CHAT_DELIMITERS, @@ -1421,7 +1464,8 @@ irc_protocol_cmd_part (struct t_irc_server *server, char *irc_message, char *hos else { weechat_printf (ptr_channel->buffer, - _("%s%s %s(%s%s%s)%s has left %s%s"), + _("%s%s%s %s(%s%s%s)%s has left %s%s"), + weechat_prefix ("quit"), IRC_COLOR_CHAT_NICK, nick, IRC_COLOR_CHAT_DELIMITERS, @@ -1435,7 +1479,7 @@ irc_protocol_cmd_part (struct t_irc_server *server, char *irc_message, char *hos } /* part request was issued by local client ? */ - if (strcmp (ptr_nick->nick, server->nick) == 0) + if (strcmp (ptr_nick->name, server->nick) == 0) { irc_nick_free_all (ptr_channel); @@ -1630,10 +1674,6 @@ irc_protocol_reply_version (struct t_irc_server *server, struct t_irc_channel *c nick); } } - if (version) - free (version); - if (date) - free (date); //(void) plugin_msg_handler_exec (server->name, // "weechat_ctcp", // irc_message); @@ -2451,7 +2491,8 @@ irc_protocol_cmd_quit (struct t_irc_server *server, char *irc_message, char *hos { pos = strchr (host, '!'); weechat_printf (ptr_channel->buffer, - _("%s%s %s(%s%s%s)%s has quit %s(%s%s%s)"), + _("%s%s%s %s(%s%s%s)%s has quit %s(%s%s%s)"), + weechat_prefix ("quit"), IRC_COLOR_CHAT_NICK, nick, IRC_COLOR_CHAT_DELIMITERS, @@ -4079,6 +4120,8 @@ irc_protocol_cmd_332 (struct t_irc_server *server, char *irc_message, char *host if (ptr_channel->topic) free (ptr_channel->topic); ptr_channel->topic = strdup (pos2); + weechat_buffer_set (ptr_channel->buffer, "title", + ptr_channel->topic); } if (!ignore) @@ -4092,9 +4135,6 @@ irc_protocol_cmd_332 (struct t_irc_server *server, char *irc_message, char *host pos2, IRC_COLOR_CHAT); } - - //if (ptr_channel) - // gui_chat_draw_title (ptr_buffer, 1); } } else @@ -4823,12 +4863,12 @@ irc_protocol_cmd_353 (struct t_irc_server *server, char *irc_message, char *host if (!ignore && !ptr_channel) { /* display users on channel */ - weechat_printf (ptr_buffer, - _("Nicks %s%s%s: %s["), - IRC_COLOR_CHAT_CHANNEL, - arguments, - IRC_COLOR_CHAT, - IRC_COLOR_CHAT_DELIMITERS); + //weechat_printf (ptr_buffer, + // _("Nicks %s%s%s: %s["), + // IRC_COLOR_CHAT_CHANNEL, + // arguments, + // IRC_COLOR_CHAT, + // IRC_COLOR_CHAT_DELIMITERS); } pos++; @@ -4987,12 +5027,12 @@ irc_protocol_cmd_366 (struct t_irc_server *server, char *irc_message, char *host if (!ignore) { /* display users on channel */ - weechat_printf (ptr_channel->buffer, - _("Nicks %s%s%s: %s["), - IRC_COLOR_CHAT_CHANNEL, - ptr_channel->name, - IRC_COLOR_CHAT, - IRC_COLOR_CHAT_DELIMITERS); + //weechat_printf (ptr_channel->buffer, + // _("Nicks %s%s%s: %s["), + // IRC_COLOR_CHAT_CHANNEL, + // ptr_channel->name, + // IRC_COLOR_CHAT, + // IRC_COLOR_CHAT_DELIMITERS); /* for (ptr_nick = ptr_channel->nicks; ptr_nick; ptr_nick = ptr_nick->next_nick) @@ -5004,8 +5044,8 @@ irc_protocol_cmd_366 (struct t_irc_server *server, char *irc_message, char *host gui_chat_printf (ptr_channel->buffer, " "); } */ - weechat_printf (ptr_channel->buffer, "%s]", - IRC_COLOR_CHAT_DELIMITERS); + //weechat_printf (ptr_channel->buffer, "%s]", + // IRC_COLOR_CHAT_DELIMITERS); /* display number of nicks, ops, halfops & voices on the channel */ irc_nick_count (ptr_channel, &num_nicks, &num_op, &num_halfop, &num_voice, @@ -5047,12 +5087,12 @@ irc_protocol_cmd_366 (struct t_irc_server *server, char *irc_message, char *host { if (!ignore) { - weechat_printf (server->buffer, - "%s%s%s: %s", - IRC_COLOR_CHAT_CHANNEL, - pos, - IRC_COLOR_CHAT, - pos2); + //weechat_printf (server->buffer, + // "%s%s%s: %s", + // IRC_COLOR_CHAT_CHANNEL, + // pos, + // IRC_COLOR_CHAT, + // pos2); } return WEECHAT_RC_OK; } @@ -5259,13 +5299,12 @@ irc_protocol_cmd_368 (struct t_irc_server *server, char *irc_message, char *host */ int -irc_protocol_cmd_432 (struct t_irc_server *server, char *irc_message, char *host, - char *nick, char *arguments, int ignore, int highlight) +irc_protocol_cmd_432 (struct t_irc_server *server, int argc, char **argv, + char **argv_eol, int ignore, int highlight) { /* Note: this IRC command can not be ignored */ - irc_protocol_cmd_error (server, irc_message, host, nick, arguments, - ignore, highlight); + irc_protocol_cmd_error (server, argc, argv, argv_eol, ignore, highlight); if (!server->is_connected) { @@ -5326,8 +5365,8 @@ irc_protocol_cmd_432 (struct t_irc_server *server, char *irc_message, char *host */ int -irc_protocol_cmd_433 (struct t_irc_server *server, char *irc_message, char *host, - char *nick, char *arguments, int ignore, int highlight) +irc_protocol_cmd_433 (struct t_irc_server *server, int argc, char **argv, + char **argv_eol, int ignore, int highlight) { /* Note: this IRC command can not be ignored */ @@ -5382,8 +5421,8 @@ irc_protocol_cmd_433 (struct t_irc_server *server, char *irc_message, char *host irc_server_sendf (server, "NICK %s", server->nick); } else - return irc_protocol_cmd_error (server, irc_message, host, nick, arguments, - ignore, highlight); + return irc_protocol_cmd_error (server, argc, argv, argv_eol, ignore, + highlight); return WEECHAT_RC_OK; } diff --git a/src/plugins/irc/irc-protocol.h b/src/plugins/irc/irc-protocol.h index d76911657..788007e28 100644 --- a/src/plugins/irc/irc-protocol.h +++ b/src/plugins/irc/irc-protocol.h @@ -25,19 +25,23 @@ typedef int (t_irc_recv_func)(struct t_irc_server *server, char *irc_message, char *host, char *nick, char *arguments, int ignore, int highlight); +typedef int (t_irc_recv_func2)(struct t_irc_server *server, int argc, + char **argv, char **argv_eol, + int ignore, int highlight); struct t_irc_protocol_msg { char *name; /* IRC message name */ char *description; /* message description */ t_irc_recv_func *recv_function; /* function called when msg is received */ + t_irc_recv_func2 *recv_function2; /* function called when msg is received */ }; extern int irc_protocol_is_highlight (char *, char *); extern int irc_protocol_recv_command (struct t_irc_server *, char *, char *, char *, char *); -extern int irc_protocol_cmd_error (struct t_irc_server *server, char *irc_message, char *host, char *nick, char *arguments, int ignore, int highlight); -extern int irc_protocol_cmd_invite (struct t_irc_server *server, char *irc_message, char *host, char *nick, char *arguments, int ignore, int highlight); -extern int irc_protocol_cmd_join (struct t_irc_server *server, char *irc_message, char *host, char *nick, char *arguments, int ignore, int highlight); +extern int irc_protocol_cmd_error (struct t_irc_server *server, int argc, char **argv, char **argv_eol, int ignore, int highlight); +extern int irc_protocol_cmd_invite (struct t_irc_server *server, int argc, char **argv, char **argv_eol, int ignore, int highlight); +extern int irc_protocol_cmd_join (struct t_irc_server *server, int argc, char **argv, char **argv_eol, int ignore, int highlight); extern int irc_protocol_cmd_kick (struct t_irc_server *server, char *irc_message, char *host, char *nick, char *arguments, int ignore, int highlight); extern int irc_protocol_cmd_kill (struct t_irc_server *server, char *irc_message, char *host, char *nick, char *arguments, int ignore, int highlight); extern int irc_protocol_cmd_mode (struct t_irc_server *server, char *irc_message, char *host, char *nick, char *arguments, int ignore, int highlight); @@ -91,8 +95,8 @@ extern int irc_protocol_cmd_365 (struct t_irc_server *server, char *irc_message, extern int irc_protocol_cmd_366 (struct t_irc_server *server, char *irc_message, char *host, char *nick, char *arguments, int ignore, int highlight); extern int irc_protocol_cmd_367 (struct t_irc_server *server, char *irc_message, char *host, char *nick, char *arguments, int ignore, int highlight); extern int irc_protocol_cmd_368 (struct t_irc_server *server, char *irc_message, char *host, char *nick, char *arguments, int ignore, int highlight); -extern int irc_protocol_cmd_432 (struct t_irc_server *server, char *irc_message, char *host, char *nick, char *arguments, int ignore, int highlight); -extern int irc_protocol_cmd_433 (struct t_irc_server *server, char *irc_message, char *host, char *nick, char *arguments, int ignore, int highlight); +extern int irc_protocol_cmd_432 (struct t_irc_server *server, int argc, char **argv, char **argv_eol, int ignore, int highlight); +extern int irc_protocol_cmd_433 (struct t_irc_server *server, int argc, char **argv, char **argv_eol, int ignore, int highlight); extern int irc_protocol_cmd_438 (struct t_irc_server *server, char *irc_message, char *host, char *nick, char *arguments, int ignore, int highlight); extern int irc_protocol_cmd_671 (struct t_irc_server *server, char *irc_message, char *host, char *nick, char *arguments, int ignore, int highlight); diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c index 4257a1a11..3391fb130 100644 --- a/src/plugins/irc/irc-server.c +++ b/src/plugins/irc/irc-server.c @@ -47,6 +47,7 @@ #include "irc.h" #include "irc-server.h" #include "irc-channel.h" +#include "irc-command.h" #include "irc-config.h" #include "irc-nick.h" #include "irc-protocol.h" @@ -632,18 +633,23 @@ irc_server_new (char *name, int autoconnect, int autoreconnect, if (!name || !address || (port < 0)) return NULL; -#ifdef DEBUG - weechat_log_printf ("Creating new server (name:%s, address:%s, port:%d, pwd:%s, " - "nick1:%s, nick2:%s, nick3:%s, username:%s, realname:%s, " - "hostname: %s, command:%s, autojoin:%s, autorejoin:%s, " - "notify_levels:%s)", - name, address, port, (password) ? password : "", - (nick1) ? nick1 : "", (nick2) ? nick2 : "", (nick3) ? nick3 : "", - (username) ? username : "", (realname) ? realname : "", - (hostname) ? hostname : "", (command) ? command : "", - (autojoin) ? autojoin : "", (autorejoin) ? "on" : "off", - (notify_levels) ? notify_levels : ""); -#endif + if (irc_debug) + { + weechat_log_printf ("Creating new server (name:%s, address:%s, " + "port:%d, pwd:%s, nick1:%s, nick2:%s, nick3:%s, " + "username:%s, realname:%s, hostname: %s, " + "command:%s, autojoin:%s, autorejoin:%s, " + "notify_levels:%s)", + name, address, port, (password) ? password : "", + (nick1) ? nick1 : "", (nick2) ? nick2 : "", + (nick3) ? nick3 : "", (username) ? username : "", + (realname) ? realname : "", + (hostname) ? hostname : "", + (command) ? command : "", + (autojoin) ? autojoin : "", + (autorejoin) ? "on" : "off", + (notify_levels) ? notify_levels : ""); + } if ((new_server = irc_server_alloc ())) { @@ -850,12 +856,13 @@ irc_server_send_one_msg (struct t_irc_server *server, char *message) time_t time_now; rc = 1; - -#ifdef DEBUG - weechat_printf (server->buffer, - "[DEBUG] Sending to server >>> %s", - message); -#endif + + if (irc_debug) + { + weechat_printf (server->buffer, + "[DEBUG] Sending to server >>> %s", + message); + } /*new_msg = plugin_modifier_exec (PLUGIN_MODIFIER_IRC_OUT, server->name, message) @@ -1169,11 +1176,12 @@ irc_server_msgq_flush () { if (irc_recv_msgq->data) { -#ifdef DEBUG - weechat_printf (irc_recv_msgq->server->buffer, - "[DEBUG] %s", - irc_recv_msgq->data); -#endif + if (irc_debug) + { + weechat_printf (irc_recv_msgq->server->buffer, + "[DEBUG] %s", + irc_recv_msgq->data); + } ptr_data = irc_recv_msgq->data; while (ptr_data[0] == ' ') ptr_data++; @@ -1182,11 +1190,12 @@ irc_server_msgq_flush () { //gui_chat_printf_raw_data (irc_recv_msgq->server, 0, 0, // ptr_data); -#ifdef DEBUG - weechat_printf (irc_recv_msgq->server->buffer, - "[DEBUG] data received from server: %s", - ptr_data); -#endif + if (irc_debug) + { + weechat_printf (irc_recv_msgq->server->buffer, + "[DEBUG] data received from server: %s", + ptr_data); + } /*new_msg = plugin_modifier_exec (PLUGIN_MODIFIER_IRC_IN, irc_recv_msgq->server->name, ptr_data);*/ @@ -1293,7 +1302,7 @@ irc_server_recv_cb (void *arg_server) static char buffer[4096 + 2]; int num_read; - + if (!server) return WEECHAT_RC_ERROR; @@ -1319,7 +1328,7 @@ irc_server_recv_cb (void *arg_server) weechat_prefix ("error"), "irc"); irc_server_disconnect (server, 1); } - + return WEECHAT_RC_OK; } @@ -1443,6 +1452,11 @@ irc_server_child_kill (struct t_irc_server *server) void irc_server_close_connection (struct t_irc_server *server) { + if (server->hook_fd) + { + weechat_unhook (server->hook_fd); + server->hook_fd = NULL; + } irc_server_child_kill (server); /* close network socket */ @@ -1555,9 +1569,9 @@ irc_server_child_read (void *arg_server) } #endif /* kill child and login to server */ + weechat_unhook (server->hook_fd); irc_server_child_kill (server); irc_server_login (server); - weechat_unhook (server->hook_fd); server->hook_fd = weechat_hook_fd (server->sock, 1, 0, 0, irc_server_recv_cb, @@ -2260,9 +2274,9 @@ irc_server_connect (struct t_irc_server *server, int disable_autojoin) /* create socket and set options */ if (config_proxy_use) - server->sock = socket ((config_proxy_ipv6) ? AF_INET6 : AF_INET, SOCK_STREAM, 0); + server->sock = socket ((config_proxy_ipv6) ? AF_INET6 : AF_INET, SOCK_STREAM, 0); else - server->sock = socket ((server->ipv6) ? AF_INET6 : AF_INET, SOCK_STREAM, 0); + server->sock = socket ((server->ipv6) ? AF_INET6 : AF_INET, SOCK_STREAM, 0); if (server->sock == -1) { weechat_printf (server->buffer, @@ -2473,8 +2487,8 @@ irc_server_autojoin_channels (struct t_irc_server *server) else { /* auto-join when connecting to server for first time */ - //if (!server->disable_autojoin && server->autojoin && server->autojoin[0]) - // irc_cmd_join_server (server, server->autojoin); + if (!server->disable_autojoin && server->autojoin && server->autojoin[0]) + irc_command_join_server (server, server->autojoin); } server->disable_autojoin = 0; @@ -2713,7 +2727,8 @@ void irc_server_print_log () { struct t_irc_server *ptr_server; - + struct t_irc_channel *ptr_channel; + for (ptr_server = irc_servers; ptr_server; ptr_server = ptr_server->next_server) { @@ -2774,5 +2789,11 @@ irc_server_print_log () weechat_log_printf (" last_channel. . . . : 0x%X", ptr_server->last_channel); weechat_log_printf (" prev_server . . . . : 0x%X", ptr_server->prev_server); weechat_log_printf (" next_server . . . . : 0x%X", ptr_server->next_server); + + for (ptr_channel = ptr_server->channels; ptr_channel; + ptr_channel = ptr_channel->next_channel) + { + irc_channel_print_log (ptr_channel); + } } } diff --git a/src/plugins/irc/irc.c b/src/plugins/irc/irc.c index cc808eb0f..b84a3f541 100644 --- a/src/plugins/irc/irc.c +++ b/src/plugins/irc/irc.c @@ -45,9 +45,11 @@ char plugin_description[] = "IRC (Internet Relay Chat)"; struct t_weechat_plugin *weechat_irc_plugin = NULL; -struct t_hook *irc_hook_timer = NULL; + struct t_hook *irc_hook_timer = NULL; struct t_hook *irc_hook_timer_check_away = NULL; +int irc_debug = 0; + #ifdef HAVE_GNUTLS gnutls_certificate_credentials gnutls_xcred; /* gnutls client credentials */ #endif @@ -60,10 +62,6 @@ gnutls_certificate_credentials gnutls_xcred; /* gnutls client credentials */ int irc_dump_data_cb (void *data, char *signal, void *pointer) { - struct t_irc_server *ptr_server; - struct t_irc_channel *ptr_channel; - struct t_irc_nick *ptr_nick; - /* make C compiler happy */ (void) data; (void) signal; @@ -72,23 +70,7 @@ irc_dump_data_cb (void *data, char *signal, void *pointer) weechat_log_printf (""); weechat_log_printf ("***** IRC plugin dump *****"); - for (ptr_server = irc_servers; ptr_server; - ptr_server = ptr_server->next_server) - { - irc_server_print_log (ptr_server); - - for (ptr_channel = ptr_server->channels; ptr_channel; - ptr_channel = ptr_channel->next_channel) - { - irc_channel_print_log (ptr_channel); - - for (ptr_nick = ptr_channel->nicks; ptr_nick; - ptr_nick = ptr_nick->next_nick) - { - irc_nick_print_log (ptr_nick); - } - } - } + irc_server_print_log (); //irc_dcc_print_log (); @@ -120,7 +102,6 @@ irc_create_directories () free (dir1); if (dir2) free (dir2); - free (weechat_dir); } } @@ -147,6 +128,22 @@ irc_quit_cb (void *data, char *signal, void *pointer) return WEECHAT_RC_OK; } +/* + * irc_debug_cb: callback for "debug" signal + */ + +int +irc_debug_cb (void *data, char *signal, void *pointer) +{ + /* make C compiler happy */ + (void) data; + (void) signal; + + if (weechat_strcasecmp ((char *)pointer, "irc") == 0) + irc_debug ^= 1; + + return WEECHAT_RC_OK; +} /* * weechat_plugin_init: initialize IRC plugin @@ -178,12 +175,13 @@ weechat_plugin_init (struct t_weechat_plugin *plugin) weechat_hook_signal ("dump_data", &irc_dump_data_cb, NULL); weechat_hook_signal ("config_reload", &irc_config_reload_cb, NULL); weechat_hook_signal ("quit", &irc_quit_cb, NULL); + weechat_hook_signal ("debug", &irc_debug_cb, NULL); /* hook completions */ irc_completion_init (); - //irc_server_auto_connect (1, 0); - + irc_server_auto_connect (1, 0); + /* irc_timer = weechat_hook_timer (1 * 1000, 0, &irc_server_timer, diff --git a/src/plugins/irc/irc.h b/src/plugins/irc/irc.h index c859c0760..cf627bce0 100644 --- a/src/plugins/irc/irc.h +++ b/src/plugins/irc/irc.h @@ -55,6 +55,7 @@ #define IRC_COLOR_CHAT_HIGHLIGHT weechat_color("color_chat_highlight") #define IRC_COLOR_CHAT_HOST weechat_color("color_chat_host") #define IRC_COLOR_CHAT_NICK weechat_color("color_chat_nick") +#define IRC_COLOR_CHAT_NICK_SELF weechat_color("color_chat_nick_self") #define IRC_COLOR_CHAT_NICK_OTHER weechat_color("color_chat_nick_other") #define IRC_COLOR_CHAT_SERVER weechat_color("color_chat_server") #define IRC_COLOR_INFOBAR_HIGHLIGHT weechat_color("color_infobar_highlight") @@ -67,6 +68,8 @@ extern struct t_weechat_plugin *weechat_irc_plugin; extern struct t_hook *irc_hook_timer_check_away; +extern int irc_debug; + extern gnutls_certificate_credentials gnutls_xcred; #endif /* irc.h */ diff --git a/src/plugins/logger/logger.c b/src/plugins/logger/logger.c index cfb1f77b8..a75a90fee 100644 --- a/src/plugins/logger/logger.c +++ b/src/plugins/logger/logger.c @@ -147,7 +147,6 @@ logger_create_directory () } else rc = 0; - free (weechat_dir); } else rc = 0; @@ -226,10 +225,6 @@ logger_get_filename (struct t_gui_buffer *buffer) } } - if (dir_separator) - free (dir_separator); - if (weechat_dir) - free (weechat_dir); if (log_path) free (log_path); if (log_path2) @@ -267,8 +262,6 @@ logger_write_line (struct t_logger_buffer *logger_buffer, char *format, ...) logger_buffer->log_filename); free (logger_buffer->log_filename); logger_buffer->log_filename = NULL; - if (charset) - free (charset); return; } @@ -304,8 +297,6 @@ logger_write_line (struct t_logger_buffer *logger_buffer, char *format, ...) fflush (logger_buffer->log_file); if (message) free (message); - if (charset) - free (charset); } } diff --git a/src/plugins/plugin-api.c b/src/plugins/plugin-api.c index 418460f8a..ce48509ae 100644 --- a/src/plugins/plugin-api.c +++ b/src/plugins/plugin-api.c @@ -310,50 +310,48 @@ plugin_api_command (struct t_weechat_plugin *plugin, /* * plugin_api_info_get: get info about WeeChat - * WARNING: caller has to free string returned - * by this function after use */ char * plugin_api_info_get (struct t_weechat_plugin *plugin, char *info) { time_t inactivity; - char *return_str; + static char keyboard_inactivity[32]; if (!plugin || !info) return NULL; if (string_strcasecmp (info, "version") == 0) { - return strdup (PACKAGE_VERSION); + return PACKAGE_VERSION; } if (string_strcasecmp (info, "date") == 0) { - return strdup (__DATE__); + return __DATE__; } else if (string_strcasecmp (info, "dir_separator") == 0) { - return strdup (DIR_SEPARATOR); + return DIR_SEPARATOR; } else if (string_strcasecmp (info, "weechat_dir") == 0) { - return strdup (weechat_home); + return weechat_home; } else if (string_strcasecmp (info, "weechat_libdir") == 0) { - return strdup (WEECHAT_LIBDIR); + return WEECHAT_LIBDIR; } else if (string_strcasecmp (info, "weechat_sharedir") == 0) { - return strdup (WEECHAT_SHAREDIR); + return WEECHAT_SHAREDIR; } else if (string_strcasecmp (info, "charset_terminal") == 0) { - return strdup (local_charset); + return local_charset; } else if (string_strcasecmp (info, "charset_internal") == 0) { - return strdup (WEECHAT_INTERNAL_CHARSET); + return WEECHAT_INTERNAL_CHARSET; } else if (string_strcasecmp (info, "inactivity") == 0) { @@ -361,43 +359,9 @@ plugin_api_info_get (struct t_weechat_plugin *plugin, char *info) inactivity = 0; else inactivity = time (NULL) - gui_keyboard_last_activity_time; - return_str = (char *)malloc (32); - if (!return_str) - return NULL; - snprintf (return_str, 32, "%ld", (long int)inactivity); - return return_str; - } - else if (string_strcasecmp (info, "input") == 0) - { - if (gui_current_window->buffer->input) - { - return_str = string_iconv_from_internal (plugin->charset, - gui_current_window->buffer->input_buffer); - return (return_str) ? return_str : strdup (""); - } - else - return strdup (""); - } - else if (string_strcasecmp (info, "input_mask") == 0) - { - if (gui_current_window->buffer->input) - return strdup (gui_current_window->buffer->input_buffer_color_mask); - else - return strdup (""); - } - else if (string_strcasecmp (info, "input_pos") == 0) - { - if (gui_current_window->buffer->input) - { - return_str = (char *)malloc (32); - if (!return_str) - return NULL; - snprintf (return_str, 32, "%d", - gui_current_window->buffer->input_buffer_pos); - return return_str; - } - else - return strdup (""); + snprintf (keyboard_inactivity, sizeof (keyboard_inactivity), + "%ld", (long int)inactivity); + return keyboard_inactivity; } /* info not found */ diff --git a/src/plugins/plugin-api.h b/src/plugins/plugin-api.h index 7f9fb66c7..a1d5c0b03 100644 --- a/src/plugins/plugin-api.h +++ b/src/plugins/plugin-api.h @@ -40,7 +40,8 @@ extern int plugin_api_config_set_plugin (struct t_weechat_plugin *plugin, /* display */ extern char *plugin_api_prefix (char *prefix); extern char *plugin_api_color (char *color_name); -extern void plugin_api_infobar_printf (int delay, char *color_name, +extern void plugin_api_infobar_printf (struct t_weechat_plugin *plugin, + int delay, char *color_name, char *format, ...); extern void plugin_api_infobar_remove (int how_many); diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c index 625e9fe2e..36bb3ed6d 100644 --- a/src/plugins/plugin.c +++ b/src/plugins/plugin.c @@ -238,6 +238,7 @@ plugin_load (char *filename) new_plugin->list_search = &weelist_search; new_plugin->list_casesearch = &weelist_casesearch; new_plugin->list_get = &weelist_get; + new_plugin->list_set = &weelist_set; new_plugin->list_next = &weelist_next; new_plugin->list_prev = &weelist_prev; new_plugin->list_string = &weelist_string; @@ -289,8 +290,14 @@ plugin_load (char *filename) new_plugin->buffer_close = &gui_buffer_close; new_plugin->buffer_get = &gui_buffer_get; new_plugin->buffer_set = &gui_buffer_set; - new_plugin->buffer_nick_add = &gui_nicklist_add; - new_plugin->buffer_nick_remove = &gui_nicklist_remove; + + new_plugin->nicklist_add_group = &gui_nicklist_add_group; + new_plugin->nicklist_search_group = &gui_nicklist_search_group; + new_plugin->nicklist_add_nick = &gui_nicklist_add_nick; + new_plugin->nicklist_search_nick = &gui_nicklist_search_nick; + new_plugin->nicklist_remove_group = &gui_nicklist_remove_group; + new_plugin->nicklist_remove_nick = &gui_nicklist_remove_nick; + new_plugin->nicklist_remove_all = &gui_nicklist_remove_all; new_plugin->command = &plugin_api_command; diff --git a/src/plugins/weechat-plugin.h b/src/plugins/weechat-plugin.h index 0cd9cacc1..7bc9089c9 100644 --- a/src/plugins/weechat-plugin.h +++ b/src/plugins/weechat-plugin.h @@ -115,6 +115,7 @@ struct t_weechat_plugin char *data); struct t_weelist_item *(*list_get) (struct t_weelist *weelist, int position); + void (*list_set) (struct t_weelist_item *item, char *new_value); struct t_weelist_item *(*list_next) (struct t_weelist_item *item); struct t_weelist_item *(*list_prev) (struct t_weelist_item *item); char *(*list_string) (struct t_weelist_item *item); @@ -176,7 +177,8 @@ struct t_weechat_plugin void (*printf_date) (struct t_gui_buffer *buffer, time_t date, char *message, ...); void (*log_printf) (char *message, ...); - void (*infobar_printf) (int delay, char *color_name, char *format, ...); + void (*infobar_printf) (struct t_weechat_plugin *plugin, int delay, + char *color_name, char *format, ...); void (*infobar_remove) (int how_many); /* hooks */ @@ -238,11 +240,28 @@ struct t_weechat_plugin void *(*buffer_get) (struct t_gui_buffer *buffer, char *property); void (*buffer_set) (struct t_gui_buffer *buffer, char *property, char *value); - struct t_gui_nick *(*buffer_nick_add) (struct t_gui_buffer *buffer, - char *nick, int sort_index, - char *color_nick, char prefix, - char *color_prefix); - int (*buffer_nick_remove) (struct t_gui_buffer *buffer, char *nick); + + /* nicklist */ + struct t_gui_nick_group *(*nicklist_add_group) (struct t_gui_buffer *buffer, + struct t_gui_nick_group *parent_group, + char *name, char *color, + int visible); + struct t_gui_nick_group *(*nicklist_search_group) (struct t_gui_buffer *buffer, + struct t_gui_nick_group *from_group, + char *name); + struct t_gui_nick *(*nicklist_add_nick) (struct t_gui_buffer *buffer, + struct t_gui_nick_group *group, + char *name, char *color, + char prefix, char *prefix_color, + int visible); + struct t_gui_nick *(*nicklist_search_nick) (struct t_gui_buffer *buffer, + struct t_gui_nick_group *from_group, + char *name); + void (*nicklist_remove_group) (struct t_gui_buffer *buffer, + struct t_gui_nick_group *group); + void (*nicklist_remove_nick) (struct t_gui_buffer *buffer, + struct t_gui_nick *nick); + void (*nicklist_remove_all) (struct t_gui_buffer *buffer); /* command */ void (*command) (struct t_weechat_plugin *plugin, @@ -356,6 +375,8 @@ struct t_weechat_plugin weechat_plugin->list_casesearch(__list, __string) #define weechat_list_get(__list, __index) \ weechat_plugin->list_get(__list, __index) +#define weechat_list_set(__item, __new_value) \ + weechat_plugin->list_set(__item, __new_value) #define weechat_list_next(__item) \ weechat_plugin->list_next(__item) #define weechat_list_prev(__item) \ @@ -434,8 +455,8 @@ struct t_weechat_plugin weechat_plugin->log_printf(__message, ##__argz) #define weechat_infobar_printf(__delay, __color_name, __message, \ __argz...) \ - weechat_plugin->infobar_printf(__delay, __color_name, __message, \ - ##__argz) + weechat_plugin->infobar_printf(weechat_plugin, __delay, \ + __color_name, __message, ##__argz) #define weechat_infobar_remove(__how_many) \ weechat_plugin->infobar_remove(__how_many) @@ -491,6 +512,28 @@ struct t_weechat_plugin #define weechat_buffer_set(__buffer, __property, __value) \ weechat_plugin->buffer_set(__buffer, __property, __value) +/* nicklist */ +#define weechat_nicklist_add_group(__buffer, __parent_group, __name, \ + __color, __visible) \ + weechat_plugin->nicklist_add_group(__buffer, __parent_group, \ + __name, __color, __visible) +#define weechat_nicklist_search_group(__buffer, __from_group, __name) \ + weechat_plugin->nicklist_search_group(__buffer, __from_group, \ + __name) +#define weechat_nicklist_add_nick(__buffer, __group, __name, __color, \ + __prefix, __prefix_color, __visible) \ + weechat_plugin->nicklist_add_nick(__buffer, __group, __name, \ + __color, __prefix, __prefix_color, \ + __visible) +#define weechat_nicklist_search_nick(__buffer, __from_group, __name) \ + weechat_plugin->nicklist_search_nick(__buffer, __from_group, __name) +#define weechat_nicklist_remove_group(__buffer, __group) \ + weechat_plugin->nicklist_remove_group(__buffer, __group) +#define weechat_nicklist_remove_nick(__buffer, __nick) \ + weechat_plugin->nicklist_remove_nick(__buffer, __nick) +#define weechat_nicklist_remove_all(__buffer) \ + weechat_plugin->nicklist_remove_all(__buffer) + /* command */ #define weechat_command(__buffer, __command) \ weechat_plugin->command(weechat_plugin, __buffer, __command) |