From 9222a7b109bf5c20ac60466cfc293dc462989bdf Mon Sep 17 00:00:00 2001 From: Sebastien Helleu Date: Tue, 1 Jan 2008 18:22:26 +0100 Subject: [PATCH] Added group support for nicklist, fixed some bugs in plugins API and IRC plugin Added group support for nicklist (with subgroups). Partial changes in IRC protocol functions (new arguments with argv and argv_eol). Fixed some bugs: - nicklist in plugins API - problem in main loop with select() when SIGWINCH is received (terminal resize) - bug in string explode function - bug in infobar countdown. --- ChangeLog | 3 +- src/core/wee-command.c | 35 +- src/core/wee-config-file.c | 6 +- src/core/wee-config.c | 11 +- src/core/wee-config.h | 1 + src/core/wee-hook.c | 27 +- src/core/wee-hook.h | 6 +- src/core/wee-list.c | 15 + src/core/wee-list.h | 1 + src/core/wee-string.c | 4 +- src/core/wee-util.c | 15 + src/core/wee-util.h | 1 + src/core/weechat.c | 9 +- src/gui/curses/gui-curses-color.c | 1 + src/gui/curses/gui-curses-infobar.c | 5 +- src/gui/curses/gui-curses-keyboard.c | 162 +++--- src/gui/curses/gui-curses-main.c | 47 +- src/gui/curses/gui-curses-nicklist.c | 130 +++-- src/gui/curses/gui-curses-window.c | 20 +- src/gui/curses/gui-curses.h | 3 +- src/gui/gtk/gui-gtk-window.c | 6 +- src/gui/gui-buffer.c | 73 +-- src/gui/gui-buffer.h | 17 +- src/gui/gui-color.h | 1 + src/gui/gui-nicklist.c | 705 +++++++++++++++++++++------ src/gui/gui-nicklist.h | 73 ++- src/plugins/fifo/fifo.c | 2 - src/plugins/irc/irc-buffer.h | 3 - src/plugins/irc/irc-channel.c | 60 ++- src/plugins/irc/irc-channel.h | 4 +- src/plugins/irc/irc-command.c | 6 - src/plugins/irc/irc-completion.c | 12 +- src/plugins/irc/irc-dcc.c | 23 +- src/plugins/irc/irc-dcc.h | 3 - src/plugins/irc/irc-display.c | 1 + src/plugins/irc/irc-mode.h | 3 +- src/plugins/irc/irc-nick.c | 240 ++++----- src/plugins/irc/irc-nick.h | 17 +- src/plugins/irc/irc-protocol.c | 555 +++++++++++---------- src/plugins/irc/irc-protocol.h | 14 +- src/plugins/irc/irc-server.c | 93 ++-- src/plugins/irc/irc.c | 48 +- src/plugins/irc/irc.h | 3 + src/plugins/logger/logger.c | 9 - src/plugins/plugin-api.c | 60 +-- src/plugins/plugin-api.h | 3 +- src/plugins/plugin.c | 11 +- src/plugins/weechat-plugin.h | 59 ++- 48 files changed, 1619 insertions(+), 987 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2392c48c2..d04cbc19e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,10 +1,11 @@ WeeChat - Wee Enhanced Environment for Chat =========================================== -ChangeLog - 2007-12-17 +ChangeLog - 2008-01-01 Version 0.2.7 (under dev!): + * added group support in nicklist * added backlog option in logger plugin * improved main loop: higher timout in select(), less CPU usage * added /reload command to reload WeeChat and plugins config files 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 @@ -224,6 +224,21 @@ weelist_get (struct t_weelist *weelist, int position) return NULL; } +/* + * 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 #include #include +#include #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" @@ -155,83 +156,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_nick_case_sensitive (buffer, number); + 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_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 #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; - - /* sort index are the same, then use alphabetical sorting */ - if (buffer->nick_case_sensitive) - return strcmp (nick1->nick, nick2->nick); - else - return string_strcasecmp (nick1->nick, nick2->nick); -} - -/* - * gui_nicklist_find_pos: 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) -{ - struct t_gui_nick *ptr_nick; - - for (ptr_nick = buffer->nicks; ptr_nick; ptr_nick = ptr_nick->next_nick) + for (ptr_group = groups; ptr_group; ptr_group = ptr_group->next_group) { - if (gui_nicklist_compare (buffer, nick, ptr_nick) < 0) - return ptr_nick; + if (strcmp (group->name, ptr_group->name) < 0) + return ptr_group; } + + /* group will be inserted at end of list */ return NULL; } /* - * gui_nicklist_insert_sorted: insert nick into sorted list + * gui_nicklist_insert_group_sorted: insert group into sorted list */ void -gui_nicklist_insert_sorted (struct t_gui_buffer *buffer, struct t_gui_nick *nick) +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 + { + group->prev_group = NULL; + group->next_group = NULL; + *groups = group; + *last_group = group; + } +} + +/* + * 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_nick (struct t_gui_nick_group *group, + struct t_gui_nick *nick) +{ + struct t_gui_nick *ptr_nick; + + for (ptr_nick = group->nicks; ptr_nick; ptr_nick = ptr_nick->next_nick) + { + if (strcmp (nick->name, ptr_nick->name) < 0) + return ptr_nick; + } + + /* nick will be inserted at end of list */ + return NULL; +} + +/* + * gui_nicklist_insert_nick_sorted: insert nick into sorted list + */ + +void +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; - - num_color_prefix = gui_color_search_config (color_prefix); - if (num_color_prefix < 0) - num_color_prefix = GUI_COLOR_NICKLIST; - - if (new_nick) - { - free (nick->nick); - nick->nick = strdup (new_nick); - } - 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); -} - -/* - * gui_nicklist_free: remove a nick to nicklist for a buffer - */ - -void -gui_nicklist_free (struct t_gui_buffer *buffer, struct t_gui_nick *nick) -{ - if (nick->nick) - free (nick->nick); - - /* remove nick from nicks list */ + /* 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 (buffer->nicks == nick) - buffer->nicks = nick->next_nick; - if (buffer->last_nick == nick) - buffer->last_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; - if (buffer->nicks_count > 0) - buffer->nicks_count--; + /* free data */ + if (nick->name) + free (nick->name); + + if (nick->visible) + { + buffer->nicklist_refresh_needed = 1; + if (buffer->nicklist_visible_count > 0) + buffer->nicklist_visible_count--; + } + + free (nick); } /* - * gui_nicklist_free_all: remove all nicks in nicklist + * gui_nicklist_remove_group: remove a group from nicklist */ void -gui_nicklist_free_all (struct t_gui_buffer *buffer) +gui_nicklist_remove_group (struct t_gui_buffer *buffer, + struct t_gui_nick_group *group) { - while (buffer->nicks) + if (!group) + return; + + /* remove childs first */ + while (group->childs) { - gui_nicklist_free (buffer, buffer->nicks); + gui_nicklist_remove_group (buffer, group->childs); + } + + /* 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_remove_all: remove all nicks in nicklist + */ + +void +gui_nicklist_remove_all (struct t_gui_buffer *buffer) +{ + while (buffer->nicklist_root) + { + 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; - ptr_nick = gui_nicklist_search (buffer, nick); - if (!ptr_nick) - return 0; + /* root group */ + if (!*group && !*nick) + { + *group = buffer->nicklist_root; + return; + } - gui_nicklist_free (buffer, ptr_nick); - return 1; + /* 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; + + /* next group */ + if (ptr_group->next_group) + { + *group = ptr_group->next_group; + return; + } + + /* 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 #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); + /* 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 + /* 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, prefix_color; + struct t_gui_nick_group *ptr_group; + char prefix, str_prefix_color[64]; - /* - 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; + /* 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 . */ -/* 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' }; @@ -428,6 +426,57 @@ irc_protocol_replace_vars (struct t_irc_server *server, struct t_irc_channel *ch return res; } +/* + * 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 @@ -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)