diff options
Diffstat (limited to 'src/fe-common')
30 files changed, 1101 insertions, 291 deletions
diff --git a/src/fe-common/core/Makefile.am b/src/fe-common/core/Makefile.am index 025a9dda..c8931435 100644 --- a/src/fe-common/core/Makefile.am +++ b/src/fe-common/core/Makefile.am @@ -17,7 +17,7 @@ libfe_common_core_la_SOURCES = \ hilight-text.c \ keyboard.c \ module-formats.c \ - nick-hilight.c \ + window-activity.c \ printtext.c \ themes.c \ translation.c \ diff --git a/src/fe-common/core/autorun.c b/src/fe-common/core/autorun.c index f1e5d88d..506e45ff 100644 --- a/src/fe-common/core/autorun.c +++ b/src/fe-common/core/autorun.c @@ -44,7 +44,7 @@ static void sig_autorun(void) recvlen = read(f, tmpbuf, sizeof(tmpbuf)); ret = line_split(tmpbuf, recvlen, &str, &buffer); - eval_special_string(str, "", active_win->active_server, active_win->active); + if (ret > 0) eval_special_string(str, "", active_win->active_server, active_win->active); } while (ret > 0); line_split_free(buffer); diff --git a/src/fe-common/core/command-history.c b/src/fe-common/core/command-history.c index 01ae46d7..fa7a1375 100644 --- a/src/fe-common/core/command-history.c +++ b/src/fe-common/core/command-history.c @@ -151,7 +151,7 @@ static char *special_history_func(const char *text, void *item, int *free_ret) static void read_settings(void) { - window_history = settings_get_bool("toggle_window_history"); + window_history = settings_get_bool("window_history"); } void command_history_init(void) @@ -159,7 +159,7 @@ void command_history_init(void) settings_add_int("history", "max_textwidget_lines", 1000); settings_add_int("history", "block_remove_lines", 20); settings_add_int("history", "max_command_history", 100); - settings_add_bool("history", "toggle_window_history", FALSE); + settings_add_bool("history", "window_history", FALSE); special_history_func_set(special_history_func); diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index d111584d..a348583d 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -47,37 +47,34 @@ void fe_server_deinit(void); void fe_settings_init(void); void fe_settings_deinit(void); -void nick_hilight_init(void); -void nick_hilight_deinit(void); +void window_activity_init(void); +void window_activity_deinit(void); void fe_core_commands_init(void); void fe_core_commands_deinit(void); void fe_common_core_init(void) { - settings_add_bool("lookandfeel", "toggle_show_menubar", TRUE); - settings_add_bool("lookandfeel", "toggle_show_toolbar", FALSE); - settings_add_bool("lookandfeel", "toggle_show_statusbar", TRUE); - settings_add_bool("lookandfeel", "toggle_show_nicklist", TRUE); - settings_add_bool("lookandfeel", "toggle_show_timestamps", FALSE); - settings_add_bool("lookandfeel", "toggle_show_msgs_timestamps", FALSE); - settings_add_bool("lookandfeel", "toggle_hide_text_style", FALSE); - settings_add_bool("lookandfeel", "toggle_bell_beeps", FALSE); - settings_add_bool("lookandfeel", "toggle_actlist_moves", FALSE); - settings_add_bool("lookandfeel", "toggle_show_nickmode", TRUE); - settings_add_bool("lookandfeel", "toggle_show_topicbar", TRUE); - - settings_add_bool("lookandfeel", "toggle_use_status_window", FALSE); - settings_add_bool("lookandfeel", "toggle_use_msgs_window", TRUE); - settings_add_bool("lookandfeel", "toggle_autoraise_msgs_window", FALSE); - settings_add_bool("lookandfeel", "toggle_autocreate_query", TRUE); - settings_add_bool("lookandfeel", "toggle_notifylist_popups", FALSE); - settings_add_bool("lookandfeel", "toggle_use_tabbed_windows", TRUE); - settings_add_int("lookandfeel", "tab_orientation", 3); + /*settings_add_bool("lookandfeel", "show_menubar", TRUE); + settings_add_bool("lookandfeel", "show_toolbar", FALSE); + settings_add_bool("lookandfeel", "show_statusbar", TRUE); + settings_add_bool("lookandfeel", "show_nicklist", TRUE);*/ + settings_add_bool("lookandfeel", "timestamps", TRUE); + settings_add_bool("lookandfeel", "msgs_timestamps", FALSE); + settings_add_bool("lookandfeel", "hide_text_style", FALSE); + settings_add_bool("lookandfeel", "bell_beeps", FALSE); + settings_add_bool("lookandfeel", "show_nickmode", TRUE); + + settings_add_bool("lookandfeel", "use_status_window", FALSE); + settings_add_bool("lookandfeel", "use_msgs_window", TRUE); + /*settings_add_bool("lookandfeel", "autoraise_msgs_window", FALSE);*/ + settings_add_bool("lookandfeel", "autocreate_query", TRUE); + /*settings_add_bool("lookandfeel", "use_tabbed_windows", TRUE); + settings_add_int("lookandfeel", "tab_orientation", 3);*/ settings_add_str("lookandfeel", "current_theme", "default"); autorun_init(); - nick_hilight_init(); + window_activity_init(); hilight_text_init(); command_history_init(); keyboard_init(); @@ -95,7 +92,7 @@ void fe_common_core_init(void) void fe_common_core_deinit(void) { autorun_deinit(); - nick_hilight_deinit(); + window_activity_deinit(); hilight_text_deinit(); command_history_deinit(); keyboard_deinit(); @@ -116,13 +113,15 @@ void fe_common_core_finish_init(void) signal(SIGPIPE, SIG_IGN); - if (settings_get_bool("toggle_use_status_window")) { + if (settings_get_bool("use_status_window")) { window = window_create(NULL, TRUE); window_set_name(window, "(status)"); - window_set_level(window, MSGLEVEL_ALL ^ (settings_get_bool("toggle_use_msgs_window") ? (MSGLEVEL_MSGS|MSGLEVEL_ACTIONS) : 0)); + window_set_level(window, MSGLEVEL_ALL ^ + (settings_get_bool("use_msgs_window") ? + (MSGLEVEL_MSGS|MSGLEVEL_ACTIONS) : 0)); } - if (settings_get_bool("toggle_use_msgs_window")) { + if (settings_get_bool("use_msgs_window")) { window = window_create(NULL, TRUE); window_set_name(window, "(msgs)"); window_set_level(window, MSGLEVEL_MSGS|MSGLEVEL_ACTIONS); diff --git a/src/fe-common/core/fe-core-commands.c b/src/fe-common/core/fe-core-commands.c index b036385d..41320eed 100644 --- a/src/fe-common/core/fe-core-commands.c +++ b/src/fe-common/core/fe-core-commands.c @@ -23,35 +23,35 @@ #include "signals.h" #include "commands.h" #include "levels.h" +#include "misc.h" #include "line-split.h" #include "irssi-version.h" #include "windows.h" -static gchar *ret_texts[] = -{ - "Invalid parameter", - "Not enough parameters given", - "Not connected to IRC server yet", - "Not joined to any channels yet", - "Error: getsockname() failed", - "Error: listen() failed", - "Multiple matches found, be more specific", - "Nick not found", - "Not joined to such channel", - "Server not found", - "Channel not fully synchronized yet, try again after a while", - "Doing this is not a good idea. Add -YES if you really mean it", +static const char *ret_texts[] = { + "Invalid parameter", + "Not enough parameters given", + "Not connected to IRC server yet", + "Not joined to any channels yet", + "Error: getsockname() failed", + "Error: listen() failed", + "Multiple matches found, be more specific", + "Nick not found", + "Not joined to such channel", + "Server not found", + "Channel not fully synchronized yet, try again after a while", + "Doing this is not a good idea. Add -YES if you really mean it", }; -static gint commands_compare(COMMAND_REC *rec, COMMAND_REC *rec2) +static int commands_compare(COMMAND_REC *rec, COMMAND_REC *rec2) { - if (rec->category == NULL && rec2->category != NULL) - return -1; - if (rec2->category == NULL && rec->category != NULL) - return 1; + if (rec->category == NULL && rec2->category != NULL) + return -1; + if (rec2->category == NULL && rec->category != NULL) + return 1; - return strcmp(rec->cmd, rec2->cmd); + return strcmp(rec->cmd, rec2->cmd); } static void help_category(GSList *cmdlist, gint items, gint max) @@ -118,7 +118,7 @@ static int show_help(COMMAND_REC *cmd) recvlen = read(f, tmpbuf, sizeof(tmpbuf)); ret = line_split(tmpbuf, recvlen, &str, &buffer); - printtext(NULL, NULL, MSGLEVEL_NEVER, str); + if (ret > 0) printtext(NULL, NULL, MSGLEVEL_NEVER, str); } while (ret > 0); line_split_free(buffer); @@ -227,6 +227,37 @@ static void cmd_version(char *data) printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE, "Client: "PACKAGE" " IRSSI_VERSION); } +static void cmd_cat(const char *data) +{ + char tmpbuf[1024], *str, *fname; + LINEBUF_REC *buffer = NULL; + int f, ret, recvlen; + + fname = convert_home(data); + f = open(fname, O_RDONLY); + g_free(fname); + if (f == -1) { + /* file not found */ + printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "%s", g_strerror(errno)); + return; + } + + do { + recvlen = read(f, tmpbuf, sizeof(tmpbuf)); + + ret = line_split(tmpbuf, recvlen, &str, &buffer); + if (ret > 0) printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "%s", str); + } while (ret > 0); + line_split_free(buffer); + + close(f); +} + +static void cmd_beep(void) +{ + printbeep(); +} + static void cmd_unknown(const char *data, void *server, WI_ITEM_REC *item) { char *cmd; @@ -248,6 +279,8 @@ void fe_core_commands_init(void) command_bind("help", NULL, (SIGNAL_FUNC) cmd_help); command_bind("echo", NULL, (SIGNAL_FUNC) cmd_echo); command_bind("version", NULL, (SIGNAL_FUNC) cmd_version); + command_bind("cat", NULL, (SIGNAL_FUNC) cmd_cat); + command_bind("beep", NULL, (SIGNAL_FUNC) cmd_beep); signal_add("unknown command", (SIGNAL_FUNC) cmd_unknown); signal_add("default command", (SIGNAL_FUNC) cmd_unknown); @@ -259,6 +292,8 @@ void fe_core_commands_deinit(void) command_unbind("help", (SIGNAL_FUNC) cmd_help); command_unbind("echo", (SIGNAL_FUNC) cmd_echo); command_unbind("version", (SIGNAL_FUNC) cmd_version); + command_unbind("cat", (SIGNAL_FUNC) cmd_cat); + command_unbind("beep", (SIGNAL_FUNC) cmd_beep); signal_remove("unknown command", (SIGNAL_FUNC) cmd_unknown); signal_remove("default command", (SIGNAL_FUNC) cmd_unknown); diff --git a/src/fe-common/core/fe-log.c b/src/fe-common/core/fe-log.c index 636c461b..11fe5b2f 100644 --- a/src/fe-common/core/fe-log.c +++ b/src/fe-common/core/fe-log.c @@ -43,16 +43,16 @@ static const char *autolog_path; static void cmd_log_open(const char *data) { - /* /LOG OPEN [-noopen] [-autoopen] [-channels <channels>] [-window] + /* /LOG OPEN [-noopen] [-autoopen] [-targets <targets>] [-window] [-rotate hour|day|week|month] <fname> [<levels>] */ - char *params, *args, *itemarg, *rotatearg, *fname, *levels; + char *params, *args, *targetarg, *rotatearg, *fname, *levels; char window[MAX_INT_STRLEN]; LOG_REC *log; int opened, level, rotate; - args = "channels rotate"; + args = "targets rotate"; params = cmd_get_params(data, 5 | PARAM_FLAG_MULTIARGS | PARAM_FLAG_GETREST, - &args, &itemarg, &rotatearg, &fname, &levels); + &args, &targetarg, &rotatearg, &fname, &levels); if (*fname == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); rotate = LOG_ROTATE_NEVER; @@ -67,10 +67,10 @@ static void cmd_log_open(const char *data) if (stristr(args, "-window")) { /* log by window ref# */ ltoa(window, active_win->refnum); - itemarg = window; + targetarg = window; } - log = log_create_rec(fname, level, itemarg); + log = log_create_rec(fname, level, targetarg); if (log != NULL && log->handle == -1 && stristr(args, "-noopen") == NULL) { /* start logging */ opened = log_start_logging(log); @@ -193,7 +193,7 @@ static void cmd_window_log(const char *data) open_log = log == NULL; close_log = log != NULL; } else { - printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_NOT_TOGGLE); + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_NOT_TOGGLE); g_free(params); return; } @@ -230,17 +230,34 @@ static void cmd_window_logfile(const char *data) log = log_find_item(window); if (log != NULL) { - printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_WINDOWLOG_FILE_LOGGING); + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_WINDOWLOG_FILE_LOGGING); return; } log = log_create_rec(data, MSGLEVEL_ALL, window); if (log == NULL) - printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_WINDOWLOG_FILE, data); + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_WINDOWLOG_FILE, data); else log_update(log); } +/* window's refnum changed - update the logs to log the new window refnum */ +static void sig_window_refnum_changed(WINDOW_REC *window, gpointer old_refnum) +{ + char winnum[MAX_INT_STRLEN]; + LOG_REC *log; + + ltoa(winnum, GPOINTER_TO_INT(old_refnum)); + log = log_find_item(winnum); + + if (log != NULL) { + ltoa(winnum, window->refnum); + + g_strfreev(log->items); + log->items = g_strsplit(winnum, " ", -1); + } +} + static void autologs_close_all(void) { GSList *tmp, *next; @@ -379,6 +396,7 @@ void fe_log_init(void) command_bind("window logfile", NULL, (SIGNAL_FUNC) cmd_window_logfile); signal_add_first("print text stripped", (SIGNAL_FUNC) sig_printtext_stripped); signal_add("window item remove", (SIGNAL_FUNC) sig_window_item_remove); + signal_add("window refnum changed", (SIGNAL_FUNC) sig_window_refnum_changed); signal_add("log locked", (SIGNAL_FUNC) sig_log_locked); signal_add("setup changed", (SIGNAL_FUNC) read_settings); } @@ -397,6 +415,7 @@ void fe_log_deinit(void) command_unbind("window logfile", (SIGNAL_FUNC) cmd_window_logfile); signal_remove("print text stripped", (SIGNAL_FUNC) sig_printtext_stripped); signal_remove("window item remove", (SIGNAL_FUNC) sig_window_item_remove); + signal_remove("window refnum changed", (SIGNAL_FUNC) sig_window_refnum_changed); signal_remove("log locked", (SIGNAL_FUNC) sig_log_locked); signal_remove("setup changed", (SIGNAL_FUNC) read_settings); } diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index 960b94f9..fff3d1fc 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -77,6 +77,14 @@ static void sig_server_disconnected(SERVER_REC *server) IRCTXT_CONNECTION_LOST, server->connrec->address); } +static void sig_server_quit(SERVER_REC *server, const char *msg) +{ + g_return_if_fail(server != NULL); + + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, + IRCTXT_SERVER_QUIT, server->connrec->address, msg); +} + void fe_server_init(void) { signal_add("server looking", (SIGNAL_FUNC) sig_server_looking); @@ -84,6 +92,7 @@ void fe_server_init(void) signal_add("server connected", (SIGNAL_FUNC) sig_server_connected); signal_add("server connect failed", (SIGNAL_FUNC) sig_connect_failed); signal_add("server disconnected", (SIGNAL_FUNC) sig_server_disconnected); + signal_add("server quit", (SIGNAL_FUNC) sig_server_quit); } void fe_server_deinit(void) @@ -93,4 +102,5 @@ void fe_server_deinit(void) signal_remove("server connected", (SIGNAL_FUNC) sig_server_connected); signal_remove("server connect failed", (SIGNAL_FUNC) sig_connect_failed); signal_remove("server disconnected", (SIGNAL_FUNC) sig_server_disconnected); + signal_remove("server quit", (SIGNAL_FUNC) sig_server_quit); } diff --git a/src/fe-common/core/fe-settings.c b/src/fe-common/core/fe-settings.c index 5e4b6df6..f05faad0 100644 --- a/src/fe-common/core/fe-settings.c +++ b/src/fe-common/core/fe-settings.c @@ -23,6 +23,7 @@ #include "signals.h" #include "commands.h" #include "server.h" +#include "misc.h" #include "lib-config/iconfig.h" #include "settings.h" @@ -66,19 +67,17 @@ static void cmd_set(char *data) { GSList *sets, *tmp; char *params, *key, *value, *last_section; - int keylen, found; + int found; params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &key, &value); - keylen = strlen(key); last_section = ""; found = 0; - sets = settings_get_sorted(); for (tmp = sets; tmp != NULL; tmp = tmp->next) { SETTINGS_REC *rec = tmp->data; if ((*value != '\0' && g_strcasecmp(rec->key, key) != 0) || - (*value == '\0' && keylen != 0 && g_strncasecmp(rec->key, key, keylen) != 0)) + (*value == '\0' && *key != '\0' && stristr(rec->key, key) == NULL)) continue; if (strcmp(last_section, rec->section) != 0) { @@ -140,7 +139,7 @@ static void show_aliases(const char *alias) GSList *tmp; int aliaslen; - printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_ALIASLIST_HEADER); + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_ALIASLIST_HEADER); node = iconfig_node_traverse("aliases", FALSE); tmp = node == NULL ? NULL : node->value; @@ -155,11 +154,11 @@ static void show_aliases(const char *alias) if (aliaslen != 0 && g_strncasecmp(node->key, alias, aliaslen) != 0) continue; - printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_ALIASLIST_LINE, + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_ALIASLIST_LINE, node->key, node->value); } - printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_ALIASLIST_FOOTER); + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_ALIASLIST_FOOTER); } static void alias_remove(const char *alias) diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index a96f7395..61156e01 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -314,7 +314,7 @@ static void cmd_dehilight(const char *data) if (is_numeric(data, ' ')) { /* with index number */ - tmp = g_slist_nth(hilights, atol(data)-1); + tmp = g_slist_nth(hilights, atoi(data)-1); rec = tmp == NULL ? NULL : tmp->data; } else { /* with mask */ diff --git a/src/fe-common/core/module-formats.c b/src/fe-common/core/module-formats.c index e8287a98..358f467c 100644 --- a/src/fe-common/core/module-formats.c +++ b/src/fe-common/core/module-formats.c @@ -31,8 +31,13 @@ FORMAT_REC fecommon_core_formats[] = { "line_start", "%B-%W!%B-%n ", 0 }, { "line_start_irssi", "%B-%W!%B- %WIrssi:%n ", 0 }, { "timestamp", "[$[-2.0]3:$[-2.0]4] ", 6, { 1, 1, 1, 1, 1, 1 } }, - { "daychange", "Day changed to $[-2.0]1-$[-2.0]0 $2", 3, { 1, 1, 1 } }, + { "daychange", "Day changed to ${[-2.0]1}-$[-2.0]0 $2", 3, { 1, 1, 1 } }, { "talking_with", "You are now talking with %_$0%_", 1, { 0 } }, + { "refnum_too_low", "Window number must be greater than 1", 0 }, + { "refnum_not_found", "No such window: $0", 1, { 0 } }, + { "windowlist_header", "Ref Name Active item Server Level", 0 }, + { "windowlist_line", "$[3]0 %|$[20]1 $[15]2 $[15]3 $4", 5, { 1, 0, 0, 0, 0 } }, + { "windowlist_footer", "", 0 }, /* ---- */ { NULL, "Server", 0 }, @@ -42,6 +47,7 @@ FORMAT_REC fecommon_core_formats[] = { "connection_established", "Connection to %_$0%_ established", 1, { 0 } }, { "cant_connect", "Unable to connect server %_$0%_ port %_$1%_ %K[%n$2%K]", 3, { 0, 1, 0 } }, { "connection_lost", "Connection lost to %_$0%_", 1, { 0 } }, + { "server_quit", "Disconnecting from server $0: %K[%n$1%K]", 2, { 0, 0 } }, { "server_changed", "Changed to %_$2%_ server %_$1%_", 3, { 0, 0, 0 } }, { "unknown_server_tag", "Unknown server tag %_$0%_", 1, { 0 } }, diff --git a/src/fe-common/core/module-formats.h b/src/fe-common/core/module-formats.h index 6730f413..db94140e 100644 --- a/src/fe-common/core/module-formats.h +++ b/src/fe-common/core/module-formats.h @@ -10,6 +10,11 @@ enum { IRCTXT_TIMESTAMP, IRCTXT_DAYCHANGE, IRCTXT_TALKING_WITH, + IRCTXT_REFNUM_TOO_LOW, + IRCTXT_REFNUM_NOT_FOUND, + IRCTXT_WINDOWLIST_HEADER, + IRCTXT_WINDOWLIST_LINE, + IRCTXT_WINDOWLIST_FOOTER, IRCTXT_FILL_2, @@ -18,6 +23,7 @@ enum { IRCTXT_CONNECTION_ESTABLISHED, IRCTXT_CANT_CONNECT, IRCTXT_CONNECTION_LOST, + IRCTXT_SERVER_QUIT, IRCTXT_SERVER_CHANGED, IRCTXT_UNKNOWN_SERVER_TAG, diff --git a/src/fe-common/core/printtext.c b/src/fe-common/core/printtext.c index a80177b6..7152e910 100644 --- a/src/fe-common/core/printtext.c +++ b/src/fe-common/core/printtext.c @@ -1,7 +1,7 @@ /* printtext.c : irssi - Copyright (C) 1999 Timo Sirainen + Copyright (C) 1999-2000 Timo Sirainen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -33,7 +33,7 @@ #include "themes.h" #include "windows.h" -static gboolean toggle_show_timestamps, toggle_show_msgs_timestamps, toggle_hide_text_style; +static gboolean timestamps, msgs_timestamps, hide_text_style; static gint printtag; static gchar ansitab[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; @@ -108,7 +108,7 @@ static char *convert_ansi(char *str, int *fgcolor, int *bgcolor, int *flags) if (*str == 'm') { - if (!toggle_hide_text_style) + if (!hide_text_style) { *fgcolor = fg; *bgcolor = bg == -1 ? -1 : bg; @@ -410,7 +410,7 @@ static void add_timestamp(WINDOW_REC *window, GString *out, void *server, const struct tm *tm; GString *tmp; - if (!(level != MSGLEVEL_NEVER && (toggle_show_timestamps || (toggle_show_msgs_timestamps && (level & MSGLEVEL_MSGS) != 0)))) + if (!(level != MSGLEVEL_NEVER && (timestamps || (msgs_timestamps && (level & MSGLEVEL_MSGS) != 0)))) return; t = time(NULL); @@ -574,6 +574,7 @@ static void sig_print_text(void *server, const char *target, gpointer level, con flags = 0; fgcolor = -1; bgcolor = -1; type = '\0'; + window->last_line = time(NULL); newline(window); out = g_string_new(text); @@ -612,7 +613,7 @@ static void sig_print_text(void *server, const char *target, gpointer level, con if (type == 7) { /* bell */ - if (settings_get_bool("toggle_bell_beeps")) + if (settings_get_bool("bell_beeps")) flags |= PRINTFLAG_BEEP; } if (*str != '\0' || flags & PRINTFLAG_BEEP) @@ -628,12 +629,12 @@ static void sig_print_text(void *server, const char *target, gpointer level, con { case 2: /* bold */ - if (!toggle_hide_text_style) + if (!hide_text_style) flags ^= PRINTFLAG_BOLD; break; case 6: /* blink */ - if (!toggle_hide_text_style) + if (!hide_text_style) flags ^= PRINTFLAG_BLINK; break; case 15: @@ -643,12 +644,12 @@ static void sig_print_text(void *server, const char *target, gpointer level, con break; case 22: /* reverse */ - if (!toggle_hide_text_style) + if (!hide_text_style) flags ^= PRINTFLAG_REVERSE; break; case 31: /* underline */ - if (!toggle_hide_text_style) + if (!hide_text_style) flags ^= PRINTFLAG_UNDERLINE; case 27: /* ansi color code */ @@ -711,7 +712,7 @@ static void sig_print_text(void *server, const char *target, gpointer level, con } /* MIRC color */ - if (toggle_hide_text_style) + if (hide_text_style) { /* don't show them. */ if (isdigit((gint) *ptr)) @@ -776,7 +777,7 @@ static int sig_check_daychange(void) time_t t; struct tm *tm; - if (!toggle_show_timestamps) + if (!timestamps) { /* display day change notice only when using timestamps */ return TRUE; @@ -800,6 +801,9 @@ static int sig_check_daychange(void) { WINDOW_REC *win = tmp->data; + if (win->active == NULL) + continue; /* FIXME: how to print in these windows? */ + printformat(win->active->server, win->active->name, MSGLEVEL_NEVER, IRCTXT_DAYCHANGE, tm->tm_mday, tm->tm_mon+1, 1900+tm->tm_year); } @@ -833,9 +837,9 @@ static void sig_gui_dialog(const char *type, const char *text) static void read_settings(void) { - toggle_show_timestamps = settings_get_bool("toggle_show_timestamps"); - toggle_show_msgs_timestamps = settings_get_bool("toggle_show_msgs_timestamps"); - toggle_hide_text_style = settings_get_bool("toggle_hide_text_style"); + timestamps = settings_get_bool("timestamps"); + msgs_timestamps = settings_get_bool("msgs_timestamps"); + hide_text_style = settings_get_bool("hide_text_style"); } void printtext_init(void) @@ -852,7 +856,6 @@ void printtext_init(void) signal_add("print text", (SIGNAL_FUNC) sig_print_text); signal_add("gui dialog", (SIGNAL_FUNC) sig_gui_dialog); signal_add("setup changed", (SIGNAL_FUNC) read_settings); - command_bind("beep", NULL, (SIGNAL_FUNC) printbeep); } void printtext_deinit(void) @@ -861,5 +864,4 @@ void printtext_deinit(void) signal_remove("print text", (SIGNAL_FUNC) sig_print_text); signal_remove("gui dialog", (SIGNAL_FUNC) sig_gui_dialog); signal_remove("setup changed", (SIGNAL_FUNC) read_settings); - command_unbind("beep", (SIGNAL_FUNC) printbeep); } diff --git a/src/fe-common/core/printtext.h b/src/fe-common/core/printtext.h index 6c32522e..18f3246e 100644 --- a/src/fe-common/core/printtext.h +++ b/src/fe-common/core/printtext.h @@ -56,6 +56,9 @@ void printtext(void *server, const char *channel, int level, const char *str, .. void printtext_multiline(void *server, const char *channel, int level, const char *format, const char *text); void printbeep(void); +/* strip all color (etc.) codes from `input'. returns newly allocated string. */ +char *strip_codes(const char *input); + void printtext_init(void); void printtext_deinit(void); diff --git a/src/fe-common/core/nick-hilight.c b/src/fe-common/core/window-activity.c index 8244ff50..ba3adb13 100644 --- a/src/fe-common/core/nick-hilight.c +++ b/src/fe-common/core/window-activity.c @@ -1,5 +1,5 @@ /* - nick-hilight.c : irssi + window-activity.c : irssi Copyright (C) 1999-2000 Timo Sirainen @@ -57,6 +57,7 @@ static void sig_dehilight(WINDOW_REC *window, WI_ITEM_REC *item) static void sig_dehilight_window(WINDOW_REC *window) { + GSList *tmp; int oldlevel; g_return_if_fail(window != NULL); @@ -71,7 +72,8 @@ static void sig_dehilight_window(WINDOW_REC *window) } signal_emit("window activity", 2, window, GINT_TO_POINTER(oldlevel)); - g_slist_foreach(window->items, (GFunc) sig_dehilight, NULL); + for (tmp = window->items; tmp != NULL; tmp = tmp->next) + sig_dehilight(window, tmp->data); } static void sig_hilight_window_item(WI_ITEM_REC *item) @@ -96,7 +98,7 @@ static void sig_hilight_window_item(WI_ITEM_REC *item) signal_emit("window activity", 2, window, GINT_TO_POINTER(oldlevel)); } -void nick_hilight_init(void) +void window_activity_init(void) { signal_add("print text", (SIGNAL_FUNC) sig_hilight_text); signal_add("window item changed", (SIGNAL_FUNC) sig_dehilight); @@ -105,7 +107,7 @@ void nick_hilight_init(void) signal_add("window item hilight", (SIGNAL_FUNC) sig_hilight_window_item); } -void nick_hilight_deinit(void) +void window_activity_deinit(void) { signal_remove("print text", (SIGNAL_FUNC) sig_hilight_text); signal_remove("window item changed", (SIGNAL_FUNC) sig_dehilight); diff --git a/src/fe-common/core/windows.c b/src/fe-common/core/windows.c index 3a88833b..6587a4e8 100644 --- a/src/fe-common/core/windows.c +++ b/src/fe-common/core/windows.c @@ -24,6 +24,7 @@ #include "signals.h" #include "commands.h" #include "server.h" +#include "misc.h" #include "settings.h" #include "levels.h" @@ -32,7 +33,8 @@ #include "windows.h" #include "window-items.h" -GSList *windows; +GSList *windows; /* first in the list is the active window, + next is the last active, etc. */ WINDOW_REC *active_win; static int window_get_new_refnum(void) @@ -65,7 +67,7 @@ WINDOW_REC *window_create(WI_ITEM_REC *item, int automatic) rec = g_new0(WINDOW_REC, 1); rec->refnum = window_get_new_refnum(); - windows = g_slist_append(windows, rec); + windows = g_slist_prepend(windows, rec); signal_emit("window created", 2, rec, GINT_TO_POINTER(automatic)); if (item != NULL) window_add_item(rec, item, automatic); @@ -77,8 +79,26 @@ WINDOW_REC *window_create(WI_ITEM_REC *item, int automatic) return rec; } +/* removed_refnum was removed from the windows list, pack the windows so + there won't be any holes. If there is any holes after removed_refnum, + leave the windows behind it alone. */ +static void windows_pack(int removed_refnum) +{ + WINDOW_REC *window; + int refnum; + + for (refnum = removed_refnum+1;; refnum++) { + window = window_find_refnum(refnum); + if (window == NULL) break; + + window_set_refnum(window, refnum-1); + } +} + void window_destroy(WINDOW_REC *window) { + int refnum; + g_return_if_fail(window != NULL); if (window->destroying) return; @@ -93,29 +113,25 @@ void window_destroy(WINDOW_REC *window) g_slist_foreach(window->waiting_channels, (GFunc) g_free, NULL); g_slist_free(window->waiting_channels); + refnum = window->refnum; g_free_not_null(window->name); g_free(window); -} -void window_set_active_num(int number) -{ - GSList *win; - - win = g_slist_nth(windows, number); - if (win == NULL) return; + if (active_win == window && windows != NULL) + window_set_active(windows->data); - active_win = win->data; - signal_emit("window changed", 1, active_win); + windows_pack(refnum); } void window_set_active(WINDOW_REC *window) { - int number; - - number = g_slist_index(windows, window); - if (number == -1) return; + if (window == active_win) + return; active_win = window; + windows = g_slist_remove(windows, active_win); + windows = g_slist_prepend(windows, active_win); + signal_emit("window changed", 1, active_win); } @@ -125,6 +141,30 @@ void window_change_server(WINDOW_REC *window, void *server) signal_emit("window server changed", 2, window, server); } +void window_set_refnum(WINDOW_REC *window, int refnum) +{ + GSList *tmp; + int old_refnum; + + g_return_if_fail(window != NULL); + g_return_if_fail(refnum >= 1); + if (window->refnum == refnum) return; + + for (tmp = windows; tmp != NULL; tmp = tmp->next) { + WINDOW_REC *rec = tmp->data; + + if (rec->refnum == refnum) { + rec->refnum = window->refnum; + signal_emit("window refnum changed", 2, rec, GINT_TO_POINTER(refnum)); + break; + } + } + + old_refnum = window->refnum; + window->refnum = refnum; + signal_emit("window refnum changed", 2, window, GINT_TO_POINTER(old_refnum)); +} + void window_set_name(WINDOW_REC *window, const char *name) { g_free_not_null(window->name); @@ -182,6 +222,68 @@ WINDOW_REC *window_find_closest(void *server, const char *name, int level) return active_win; } +WINDOW_REC *window_find_refnum(int refnum) +{ + GSList *tmp; + + for (tmp = windows; tmp != NULL; tmp = tmp->next) { + WINDOW_REC *rec = tmp->data; + + if (rec->refnum == refnum) + return rec; + } + + return NULL; +} + +static int windows_refnum_last(void) +{ + GSList *tmp; + int max; + + max = -1; + for (tmp = windows; tmp != NULL; tmp = tmp->next) { + WINDOW_REC *rec = tmp->data; + + if (rec->refnum > max) + max = rec->refnum; + } + + return max; +} + +static int window_refnum_prev(int refnum) +{ + GSList *tmp; + int max; + + max = -1; + for (tmp = windows; tmp != NULL; tmp = tmp->next) { + WINDOW_REC *rec = tmp->data; + + if (rec->refnum < refnum && (max == -1 || rec->refnum > max)) + max = rec->refnum; + } + + return max; +} + +static int window_refnum_next(int refnum) +{ + GSList *tmp; + int min; + + min = -1; + for (tmp = windows; tmp != NULL; tmp = tmp->next) { + WINDOW_REC *rec = tmp->data; + + if (rec->refnum > refnum && (min == -1 || rec->refnum < min)) + min = rec->refnum; + } + + return min; +} + static void cmd_window(const char *data, void *server, WI_ITEM_REC *item) { command_runsub("window", data, server, item); @@ -194,7 +296,7 @@ static void cmd_window_new(const char *data, void *server, WI_ITEM_REC *item) g_return_if_fail(data != NULL); - type = (g_strcasecmp(data, "hide") == 0 || g_strcasecmp(data, "tab") == 0) ? 1 : + type = (g_strncasecmp(data, "hid", 3) == 0 || g_strcasecmp(data, "tab") == 0) ? 1 : (g_strcasecmp(data, "split") == 0 ? 2 : 0); signal_emit("gui window create override", 1, GINT_TO_POINTER(type)); @@ -210,13 +312,15 @@ static void cmd_window_close(const char *data) } /* return the first window number with the highest activity */ -static int window_highest_activity(WINDOW_REC *window) +static WINDOW_REC *window_highest_activity(WINDOW_REC *window) { - WINDOW_REC *rec; + WINDOW_REC *rec, *max_win; GSList *tmp; - int max_num, max_act, through; + int max_act, through; + + g_return_val_if_fail(window != NULL, NULL); - max_num = 0; max_act = 0; through = FALSE; + max_win = NULL; max_act = 0; through = FALSE; tmp = g_slist_find(windows, window); for (;; tmp = tmp->next) { @@ -232,20 +336,41 @@ static int window_highest_activity(WINDOW_REC *window) if (rec->new_data && max_act < rec->new_data) { max_act = rec->new_data; - max_num = g_slist_index(windows, rec)+1; + max_win = rec; } } - return max_num; + return max_win; } -/* channel name - first try channel from same server */ -static int window_find_name(WINDOW_REC *window, const char *name) +WINDOW_REC *window_find_name(const char *name) { + GSList *tmp; + + g_return_val_if_fail(name != NULL, NULL); + + for (tmp = windows; tmp != NULL; tmp = tmp->next) { + WINDOW_REC *rec = tmp->data; + + if (rec->name != NULL && g_strcasecmp(rec->name, name) == 0) + return rec; + } + + return NULL; +} + +WINDOW_REC *window_find_item(WINDOW_REC *window, const char *name) +{ + WINDOW_REC *rec; WI_ITEM_REC *item; - int num; - item = window_item_find(window->active_server, name); + g_return_val_if_fail(name != NULL, NULL); + + rec = window_find_name(name); + if (rec != NULL) return rec; + + item = window == NULL ? NULL : + window_item_find(window->active_server, name); if (item == NULL && window->active_server != NULL) { /* not found from the active server - any server? */ item = window_item_find(NULL, name); @@ -257,7 +382,8 @@ static int window_find_name(WINDOW_REC *window, const char *name) /* still nothing? maybe user just left the # in front of channel, try again with it.. */ chan = g_strdup_printf("#%s", name); - item = window_item_find(window->active_server, chan); + item = window == NULL ? NULL : + window_item_find(window->active_server, chan); if (item == NULL) item = window_item_find(NULL, chan); g_free(chan); } @@ -265,48 +391,63 @@ static int window_find_name(WINDOW_REC *window, const char *name) if (item == NULL) return 0; - /* get the window number */ - window = MODULE_DATA(item); - if (window == NULL) return 0; + return MODULE_DATA(item); +} - num = g_slist_index(windows, window); - return num < 0 ? 0 : num+1; +static void cmd_window_refnum(const char *data) +{ + WINDOW_REC *window; + + if (!is_numeric(data, 0)) { + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_REFNUM_NOT_FOUND, data); + return; + } + + window = window_find_refnum(atoi(data)); + if (window == NULL) + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_REFNUM_NOT_FOUND, data); + else + window_set_active(window); } static void cmd_window_goto(const char *data) { - int num; + WINDOW_REC *window; g_return_if_fail(data != NULL); - num = 0; + if (is_numeric(data, 0)) { + cmd_window_refnum(data); + return; + } + if (g_strcasecmp(data, "active") == 0) - num = window_highest_activity(active_win); - else if (isdigit(*data)) - num = atol(data); + window = window_highest_activity(active_win); else - num = window_find_name(active_win, data); + window = window_find_item(active_win, data); - if (num > 0) - window_set_active_num(num-1); + if (window != NULL) + window_set_active(window); } -static void cmd_window_next(const char *data) +static void cmd_window_next(void) { int num; - num = g_slist_index(windows, active_win)+1; - if (num >= g_slist_length(windows)) num = 0; - window_set_active_num(num); + num = window_refnum_next(active_win->refnum); + if (num < 1) num = windows_refnum_last(); + + window_set_active(window_find_refnum(num)); } -static void cmd_window_prev(const char *data) +static void cmd_window_prev(void) { int num; - num = g_slist_index(windows, active_win)-1; - if (num < 0) num = g_slist_length(windows)-1; - window_set_active_num(num); + num = window_refnum_prev(active_win->refnum); + if (num < 1) num = window_refnum_next(0); + + window_set_active(window_find_refnum(num)); } static void cmd_window_level(const char *data) @@ -392,11 +533,155 @@ static void cmd_window_item_next(const char *data, void *server, WI_ITEM_REC *it window_item_set_active(window, next); } +static void cmd_window_number(const char *data) +{ + int num; + + num = atoi(data); + if (num < 1) + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_REFNUM_TOO_LOW); + else + window_set_refnum(active_win, num); +} + static void cmd_window_name(const char *data) { window_set_name(active_win, data); } +/* we're moving the first window to last - move the first contiguous block + of refnums to left. Like if there's windows 1..5 and 7..10, move 1 to + 11, 2..5 to 1..4 and leave 7..10 alone */ +static void windows_move_left(WINDOW_REC *move_window) +{ + WINDOW_REC *window; + int refnum; + + window_set_refnum(move_window, windows_refnum_last()+1); + for (refnum = 2;; refnum++) { + window = window_find_refnum(refnum); + if (window == NULL) break; + + window_set_refnum(window, refnum-1); + } +} + +/* we're moving the last window to first - make some space so we can use the + refnum 1 */ +static void windows_move_right(WINDOW_REC *move_window) +{ + WINDOW_REC *window; + int refnum; + + /* find the first unused refnum, like if there's windows + 1..5 and 7..10, we only need to move 1..5 to 2..6 */ + refnum = 1; + while (window_find_refnum(refnum) != NULL) refnum++; + + refnum--; + while (refnum > 0) { + window = window_find_refnum(refnum); + g_return_if_fail(window != NULL); + window_set_refnum(window, window == move_window ? 1 : refnum+1); + + refnum--; + } +} + +static void cmd_window_move_left(void) +{ + int refnum; + + refnum = window_refnum_prev(active_win->refnum); + if (refnum != -1) { + window_set_refnum(active_win, active_win->refnum-1); + return; + } + + windows_move_left(active_win); +} + +static void cmd_window_move_right(void) +{ + int refnum; + + refnum = window_refnum_next(active_win->refnum); + if (refnum != -1) { + window_set_refnum(active_win, active_win->refnum+1); + return; + } + + windows_move_right(active_win); +} + +static void cmd_window_move(const char *data, SERVER_REC *server, WI_ITEM_REC *item) +{ + int new_refnum, refnum; + + if (!is_numeric(data, 0)) { + command_runsub("window move", data, server, item); + return; + } + + new_refnum = atoi(data); + if (new_refnum > active_win->refnum) { + for (;;) { + refnum = window_refnum_next(active_win->refnum); + if (refnum == -1 || refnum > new_refnum) + break; + + window_set_refnum(active_win, refnum); + } + } else { + for (;;) { + refnum = window_refnum_prev(active_win->refnum); + if (refnum == -1 || refnum < new_refnum) + break; + + window_set_refnum(active_win, refnum); + } + } +} + +static int windows_compare(WINDOW_REC *w1, WINDOW_REC *w2) +{ + return w1->refnum < w2->refnum ? -1 : 1; +} + +GSList *windows_get_sorted(void) +{ + GSList *tmp, *list; + + list = NULL; + for (tmp = windows; tmp != NULL; tmp = tmp->next) { + list = g_slist_insert_sorted(list, tmp->data, (GCompareFunc) windows_compare); + } + + return list; +} + +static void cmd_window_list(void) +{ + GSList *tmp, *sorted; + char *levelstr; + + sorted = windows_get_sorted(); + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_WINDOWLIST_HEADER); + for (tmp = sorted; tmp != NULL; tmp = tmp->next) { + WINDOW_REC *rec = tmp->data; + + levelstr = bits2level(rec->level); + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_WINDOWLIST_LINE, + rec->refnum, rec->name == NULL ? "" : rec->name, + rec->active == NULL ? "" : rec->active->name, + rec->active_server == NULL ? "" : ((SERVER_REC *) rec->active_server)->tag, + levelstr); + g_free(levelstr); + } + g_slist_free(sorted); + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_WINDOWLIST_FOOTER); +} + static void sig_server_looking(void *server) { GSList *tmp; @@ -434,14 +719,21 @@ void windows_init(void) command_bind("window", NULL, (SIGNAL_FUNC) cmd_window); command_bind("window new", NULL, (SIGNAL_FUNC) cmd_window_new); command_bind("window close", NULL, (SIGNAL_FUNC) cmd_window_close); + command_bind("window kill", NULL, (SIGNAL_FUNC) cmd_window_close); command_bind("window server", NULL, (SIGNAL_FUNC) cmd_window_server); + command_bind("window refnum", NULL, (SIGNAL_FUNC) cmd_window_refnum); command_bind("window goto", NULL, (SIGNAL_FUNC) cmd_window_goto); command_bind("window prev", NULL, (SIGNAL_FUNC) cmd_window_prev); command_bind("window next", NULL, (SIGNAL_FUNC) cmd_window_next); command_bind("window level", NULL, (SIGNAL_FUNC) cmd_window_level); command_bind("window item prev", NULL, (SIGNAL_FUNC) cmd_window_item_prev); command_bind("window item next", NULL, (SIGNAL_FUNC) cmd_window_item_next); + command_bind("window number", NULL, (SIGNAL_FUNC) cmd_window_number); command_bind("window name", NULL, (SIGNAL_FUNC) cmd_window_name); + command_bind("window move", NULL, (SIGNAL_FUNC) cmd_window_move); + command_bind("window move left", NULL, (SIGNAL_FUNC) cmd_window_move_left); + command_bind("window move right", NULL, (SIGNAL_FUNC) cmd_window_move_right); + command_bind("window list", NULL, (SIGNAL_FUNC) cmd_window_list); signal_add("server looking", (SIGNAL_FUNC) sig_server_looking); signal_add("server disconnected", (SIGNAL_FUNC) sig_server_disconnected); signal_add("server connect failed", (SIGNAL_FUNC) sig_server_disconnected); @@ -452,14 +744,21 @@ void windows_deinit(void) command_unbind("window", (SIGNAL_FUNC) cmd_window); command_unbind("window new", (SIGNAL_FUNC) cmd_window_new); command_unbind("window close", (SIGNAL_FUNC) cmd_window_close); + command_unbind("window kill", (SIGNAL_FUNC) cmd_window_close); command_unbind("window server", (SIGNAL_FUNC) cmd_window_server); + command_unbind("window refnum", (SIGNAL_FUNC) cmd_window_refnum); command_unbind("window goto", (SIGNAL_FUNC) cmd_window_goto); command_unbind("window prev", (SIGNAL_FUNC) cmd_window_prev); command_unbind("window next", (SIGNAL_FUNC) cmd_window_next); command_unbind("window level", (SIGNAL_FUNC) cmd_window_level); command_unbind("window item prev", (SIGNAL_FUNC) cmd_window_item_prev); command_unbind("window item next", (SIGNAL_FUNC) cmd_window_item_next); + command_unbind("window number", (SIGNAL_FUNC) cmd_window_number); command_unbind("window name", (SIGNAL_FUNC) cmd_window_name); + command_unbind("window move", (SIGNAL_FUNC) cmd_window_move); + command_unbind("window move left", (SIGNAL_FUNC) cmd_window_move_left); + command_unbind("window move right", (SIGNAL_FUNC) cmd_window_move_right); + command_unbind("window list", (SIGNAL_FUNC) cmd_window_list); signal_remove("server looking", (SIGNAL_FUNC) sig_server_looking); signal_remove("server disconnected", (SIGNAL_FUNC) sig_server_disconnected); signal_remove("server connect failed", (SIGNAL_FUNC) sig_server_disconnected); diff --git a/src/fe-common/core/windows.h b/src/fe-common/core/windows.h index f279e888..a3b06d86 100644 --- a/src/fe-common/core/windows.h +++ b/src/fe-common/core/windows.h @@ -41,6 +41,7 @@ typedef struct { int level; int new_data; time_t last_timestamp; /* When was last timestamp printed */ + time_t last_line; /* When was last line printed */ gpointer gui_data; } WINDOW_REC; @@ -55,11 +56,15 @@ void window_set_active_num(int number); void window_set_active(WINDOW_REC *window); void window_change_server(WINDOW_REC *window, void *server); +void window_set_refnum(WINDOW_REC *window, int refnum); void window_set_name(WINDOW_REC *window, const char *name); void window_set_level(WINDOW_REC *window, int level); WINDOW_REC *window_find_level(void *server, int level); WINDOW_REC *window_find_closest(void *server, const char *name, int level); +WINDOW_REC *window_find_refnum(int refnum); +WINDOW_REC *window_find_name(const char *name); +WINDOW_REC *window_find_item(WINDOW_REC *window, const char *name); void windows_init(void); void windows_deinit(void); diff --git a/src/fe-common/irc/Makefile.am b/src/fe-common/irc/Makefile.am index 440f14bd..d4ca3f70 100644 --- a/src/fe-common/irc/Makefile.am +++ b/src/fe-common/irc/Makefile.am @@ -15,13 +15,15 @@ libfe_common_irc_la_SOURCES = \ completion.c \ fe-channels.c \ fe-irc-commands.c \ + fe-irc-server.c \ fe-ctcp.c \ fe-events.c \ fe-events-numeric.c \ fe-ignore.c \ + fe-netsplit.c \ fe-query.c \ fe-common-irc.c \ - irc-nick-hilight.c \ + irc-window-activity.c \ irc-hilight-text.c \ module-formats.c diff --git a/src/fe-common/irc/dcc/module-formats.h b/src/fe-common/irc/dcc/module-formats.h index 40d6f090..bc58035e 100644 --- a/src/fe-common/irc/dcc/module-formats.h +++ b/src/fe-common/irc/dcc/module-formats.h @@ -6,9 +6,9 @@ enum { IRCTXT_FILL_1, IRCTXT_OWN_DCC, - IRCTXT_DCC_MSG, IRCTXT_OWN_DCC_ME, IRCTXT_OWN_DCC_CTCP, + IRCTXT_DCC_MSG, IRCTXT_ACTION_DCC, IRCTXT_DCC_CTCP, IRCTXT_DCC_CHAT, diff --git a/src/fe-common/irc/fe-channels.c b/src/fe-common/irc/fe-channels.c index c95e6411..6403412a 100644 --- a/src/fe-common/irc/fe-channels.c +++ b/src/fe-common/irc/fe-channels.c @@ -24,9 +24,12 @@ #include "signals.h" #include "commands.h" #include "levels.h" +#include "misc.h" #include "irc.h" #include "channels.h" +#include "channels-setup.h" +#include "nicklist.h" #include "windows.h" #include "window-items.h" @@ -100,6 +103,134 @@ static void cmd_wjoin(const char *data, void *server, WI_ITEM_REC *item) signal_remove("channel created", (SIGNAL_FUNC) signal_channel_created_curwin); } +static void cmd_channel_list_joined(void) +{ + CHANNEL_REC *channel; + GString *nicks; + GSList *nicklist, *tmp, *ntmp; + char *mode; + + if (channels == NULL) { + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_NOT_IN_CHANNELS); + return; + } + + /* print active channel */ + channel = irc_item_channel(active_win->active); + if (channel != NULL) + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_CURRENT_CHANNEL, channel->name); + + /* print list of all channels, their modes, server tags and nicks */ + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_CHANLIST_HEADER); + for (tmp = channels; tmp != NULL; tmp = tmp->next) { + channel = tmp->data; + + nicklist = nicklist_getnicks(channel); + mode = channel_get_mode(channel); + nicks = g_string_new(NULL); + for (ntmp = nicklist; ntmp != NULL; ntmp = ntmp->next) { + NICK_REC *rec = ntmp->data; + + g_string_sprintfa(nicks, "%s ", rec->nick); + } + + g_string_truncate(nicks, nicks->len-1); + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_CHANLIST_LINE, + channel->name, mode, channel->server->tag, nicks->str); + + g_free(mode); + g_slist_free(nicklist); + g_string_free(nicks, TRUE); + } +} + +static void cmd_channel_list(void) +{ + GString *str; + GSList *tmp; + + str = g_string_new(NULL); + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_CHANSETUP_HEADER); + for (tmp = setupchannels; tmp != NULL; tmp = tmp->next) { + SETUP_CHANNEL_REC *rec = tmp->data; + + g_string_truncate(str, 0); + if (rec->autojoin) + g_string_append(str, "autojoin "); + if (rec->botmasks != NULL && *rec->botmasks != '\0') + g_string_sprintfa(str, "bots: %s ", rec->botmasks); + if (rec->autosendcmd != NULL && *rec->autosendcmd != '\0') + g_string_sprintfa(str, "botcmd: %s ", rec->autosendcmd); + + g_string_truncate(str, str->len-1); + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_CHANSETUP_LINE, + rec->name, rec->ircnet == NULL ? "" : rec->ircnet, + rec->password == NULL ? "" : rec->password, str->str); + } + g_string_free(str, TRUE); + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_CHANSETUP_FOOTER); +} + +static void cmd_channel(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) +{ + if (ischannel(*data)) { + signal_emit("command join", 2, data, server); + return; + } + + command_runsub("channel", data, server, item); +} + +static void cmd_channel_add(const char *data) +{ + char *params, *args, *botarg, *botcmdarg, *ircnet, *channel, *password; + SETUP_CHANNEL_REC *rec; + + args = "bots botcmd"; + params = cmd_get_params(data, 6 | PARAM_FLAG_MULTIARGS, &args, + &botarg, &botcmdarg, &channel, &ircnet, &password); + + if (*ircnet == '\0' || *channel == '\0') + cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + rec = channels_setup_find(channel, ircnet); + if (rec == NULL) { + rec = g_new0(SETUP_CHANNEL_REC, 1); + rec->name = g_strdup(channel); + rec->ircnet = g_strdup(ircnet); + } else { + g_free_not_null(rec->botmasks); + g_free_not_null(rec->autosendcmd); + g_free_not_null(rec->password); + } + rec->autojoin = stristr(args, "-auto") != NULL; + rec->botmasks = *botarg == '\0' ? NULL : g_strdup(botarg); + rec->autosendcmd = *botcmdarg == '\0' ? NULL : g_strdup(botcmdarg); + rec->password = *password == '\0' ? NULL : g_strdup(password); + channels_setup_create(rec); + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_CHANSETUP_ADDED, channel, ircnet); + + g_free(params); +} + +static void cmd_channel_remove(const char *data) +{ + char *params, *ircnet, *channel; + SETUP_CHANNEL_REC *rec; + + params = cmd_get_params(data, 2, &channel, &ircnet); + if (*ircnet == '\0' || *channel == '\0') + cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + + rec = channels_setup_find(channel, ircnet); + if (rec == NULL) + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_CHANSETUP_NOT_FOUND, channel, ircnet); + else { + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_CHANSETUP_REMOVED, channel, ircnet); + channels_setup_destroy(rec); + } + g_free(params); +} + void fe_channels_init(void) { signal_add("channel created", (SIGNAL_FUNC) signal_channel_created); @@ -109,6 +240,11 @@ void fe_channels_init(void) signal_add_last("server disconnected", (SIGNAL_FUNC) sig_disconnected); command_bind("wjoin", NULL, (SIGNAL_FUNC) cmd_wjoin); + command_bind("channel ", NULL, (SIGNAL_FUNC) cmd_channel_list_joined); + command_bind("channel", NULL, (SIGNAL_FUNC) cmd_channel); + command_bind("channel add", NULL, (SIGNAL_FUNC) cmd_channel_add); + command_bind("channel remove", NULL, (SIGNAL_FUNC) cmd_channel_remove); + command_bind("channel list", NULL, (SIGNAL_FUNC) cmd_channel_list); } void fe_channels_deinit(void) @@ -120,4 +256,9 @@ void fe_channels_deinit(void) signal_remove("server disconnected", (SIGNAL_FUNC) sig_disconnected); command_unbind("wjoin", (SIGNAL_FUNC) cmd_wjoin); + command_unbind("channel", (SIGNAL_FUNC) cmd_channel); + command_unbind("channel ", (SIGNAL_FUNC) cmd_channel_list_joined); + command_unbind("channel add", (SIGNAL_FUNC) cmd_channel_add); + command_unbind("channel remove", (SIGNAL_FUNC) cmd_channel_remove); + command_unbind("channel list", (SIGNAL_FUNC) cmd_channel_list); } diff --git a/src/fe-common/irc/fe-common-irc.c b/src/fe-common/irc/fe-common-irc.c index b8166f5e..bde1d9fe 100644 --- a/src/fe-common/irc/fe-common-irc.c +++ b/src/fe-common/irc/fe-common-irc.c @@ -35,6 +35,9 @@ void fe_channels_deinit(void); void fe_irc_commands_init(void); void fe_irc_commands_deinit(void); +void fe_irc_server_init(void); +void fe_irc_server_deinit(void); + void fe_ctcp_init(void); void fe_ctcp_deinit(void); @@ -53,8 +56,8 @@ void fe_ignore_deinit(void); void fe_query_init(void); void fe_query_deinit(void); -void irc_nick_hilight_init(void); -void irc_nick_hilight_deinit(void); +void irc_window_activity_init(void); +void irc_window_activity_deinit(void); void fe_notifylist_init(void); void fe_notifylist_deinit(void); @@ -62,6 +65,9 @@ void fe_notifylist_deinit(void); void fe_flood_init(void); void fe_flood_deinit(void); +void fe_netsplit_init(void); +void fe_netsplit_deinit(void); + static char *autocon_server; static char *autocon_password; static int autocon_port; @@ -96,6 +102,7 @@ void fe_common_irc_init(void) fe_channels_init(); fe_irc_commands_init(); + fe_irc_server_init(); fe_ctcp_init(); fe_dcc_init(); fe_events_init(); @@ -103,15 +110,17 @@ void fe_common_irc_init(void) fe_ignore_init(); fe_notifylist_init(); fe_flood_init(); + fe_netsplit_init(); fe_query_init(); completion_init(); - irc_nick_hilight_init(); + irc_window_activity_init(); } void fe_common_irc_deinit(void) { fe_channels_deinit(); fe_irc_commands_deinit(); + fe_irc_server_deinit(); fe_ctcp_deinit(); fe_dcc_deinit(); fe_events_deinit(); @@ -119,9 +128,10 @@ void fe_common_irc_deinit(void) fe_ignore_deinit(); fe_notifylist_deinit(); fe_flood_deinit(); + fe_netsplit_deinit(); fe_query_deinit(); completion_deinit(); - irc_nick_hilight_deinit(); + irc_window_activity_deinit(); } void fe_common_irc_finish_init(void) @@ -162,7 +172,7 @@ void fe_common_irc_finish_init(void) if (*rec->ircnet != '\0') ircnets = g_slist_append(ircnets, rec->ircnet); - str = g_strdup_printf("%s %d", rec->server, rec->port); + str = g_strdup_printf("%s %d", rec->address, rec->port); signal_emit("command connect", 1, str); g_free(str); } diff --git a/src/fe-common/irc/fe-events-numeric.c b/src/fe-common/irc/fe-events-numeric.c index 44169fe8..5b692e58 100644 --- a/src/fe-common/irc/fe-events-numeric.c +++ b/src/fe-common/irc/fe-events-numeric.c @@ -607,7 +607,7 @@ static void event_motd(gchar *data, SERVER_REC *server, gchar *nick, gchar *addr /* numeric event. */ gchar *params, *args, *ptr; - if (settings_get_bool("toggle_skip_motd")) + if (settings_get_bool("skip_motd")) return; params = event_get_params(data, 2 | PARAM_FLAG_GETREST, NULL, &args); diff --git a/src/fe-common/irc/fe-events.c b/src/fe-common/irc/fe-events.c index c846211a..f6a2557c 100644 --- a/src/fe-common/irc/fe-events.c +++ b/src/fe-common/irc/fe-events.c @@ -32,6 +32,7 @@ #include "query.h" #include "nicklist.h" #include "ignore.h" +#include "netsplit.h" #include "irc-hilight-text.h" #include "windows.h" @@ -83,7 +84,7 @@ static void event_privmsg(gchar *data, IRC_SERVER_REC *server, gchar *nick, gcha color = irc_hilight_find_nick(target, nick, addr); nickrec = chanrec == NULL ? NULL : nicklist_find(chanrec, nick); - nickmode = !settings_get_bool("toggle_show_nickmode") || nickrec == NULL ? "" : + nickmode = !settings_get_bool("show_nickmode") || nickrec == NULL ? "" : nickrec->op ? "@" : nickrec->voice ? "+" : " "; window = chanrec == NULL ? NULL : window_item_window((WI_ITEM_REC *) chanrec); @@ -125,7 +126,7 @@ static void event_privmsg(gchar *data, IRC_SERVER_REC *server, gchar *nick, gcha else { /* private message */ - if (settings_get_bool("toggle_autocreate_query") && query_find(server, nick) == NULL) + if (settings_get_bool("autocreate_query") && query_find(server, nick) == NULL) item = (WI_ITEM_REC *) query_create(server, nick, TRUE); else item = (WI_ITEM_REC *) query_find(server, nick); @@ -183,7 +184,7 @@ static void ctcp_action_msg(gchar *data, IRC_SERVER_REC *server, gchar *nick, gc else { /* private action */ - if (settings_get_bool("toggle_autocreate_query") && query_find(server, nick) == NULL) + if (settings_get_bool("autocreate_query") && query_find(server, nick) == NULL) item = (WI_ITEM_REC *) query_create(server, nick, TRUE); else item = (WI_ITEM_REC *) channel_find(server, nick); @@ -280,6 +281,9 @@ static void event_quit(const char *data, IRC_SERVER_REC *server, const char *nic if (ignore_check(server, nick, addr, NULL, data, MSGLEVEL_QUITS)) return; + if (settings_get_bool("hide_netsplit_quits") && quitmsg_is_split(data)) + return; + print_channel = NULL; once = settings_get_bool("show_quit_once"); chans = !once ? NULL : g_string_new(NULL); @@ -558,46 +562,46 @@ static void event_ban_type_changed(gchar *bantype) static void sig_server_lag_disconnected(IRC_SERVER_REC *server) { - g_return_if_fail(server != NULL); + g_return_if_fail(server != NULL); - printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, - IRCTXT_LAG_DISCONNECTED, server->connrec->address, time(NULL)-server->lag_sent); + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, + IRCTXT_LAG_DISCONNECTED, server->connrec->address, time(NULL)-server->lag_sent); } static void sig_server_reconnect_removed(RECONNECT_REC *reconnect) { - g_return_if_fail(reconnect != NULL); + g_return_if_fail(reconnect != NULL); - printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, - IRCTXT_RECONNECT_REMOVED, reconnect->conn->address, reconnect->conn->port, - reconnect->conn->ircnet == NULL ? "" : reconnect->conn->ircnet); + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, + IRCTXT_RECONNECT_REMOVED, reconnect->conn->address, reconnect->conn->port, + reconnect->conn->ircnet == NULL ? "" : reconnect->conn->ircnet); } static void sig_server_reconnect_not_found(gchar *tag) { - g_return_if_fail(tag != NULL); + g_return_if_fail(tag != NULL); - printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, - IRCTXT_RECONNECT_NOT_FOUND, tag); + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, + IRCTXT_RECONNECT_NOT_FOUND, tag); } static void event_received(gchar *data, IRC_SERVER_REC *server, gchar *nick, gchar *addr) { - g_return_if_fail(data != NULL); + char *params, *cmd, *args, *ptr; - if (!isdigit((gint) *data)) - printtext(server, NULL, MSGLEVEL_CRAP, "%s", data); - else - { - /* numeric event. */ - gchar *params, *cmd, *args, *ptr; + g_return_if_fail(data != NULL); - params = event_get_params(data, 3 | PARAM_FLAG_GETREST, &cmd, NULL, &args); - ptr = strstr(args, " :"); + if (!isdigit((gint) *data)) { + printtext(server, NULL, MSGLEVEL_CRAP, "%s", data); + return; + } + + /* numeric event. */ + params = event_get_params(data, 3 | PARAM_FLAG_GETREST, &cmd, NULL, &args); + ptr = strstr(args, " :"); if (ptr != NULL) *(ptr+1) = ' '; printtext(server, NULL, MSGLEVEL_CRAP, "%s", args); g_free(params); - } } static void sig_empty(void) @@ -612,6 +616,7 @@ static void read_settings(void) void fe_events_init(void) { + settings_add_bool("misc", "hide_netsplit_quits", TRUE); beep_msg_level = 0; read_settings(); diff --git a/src/fe-common/irc/fe-ignore.c b/src/fe-common/irc/fe-ignore.c index 35da7c84..db91826e 100644 --- a/src/fe-common/irc/fe-ignore.c +++ b/src/fe-common/irc/fe-ignore.c @@ -191,7 +191,7 @@ static void cmd_ignore(const char *data) else { key = ignore_get_key(rec); levels = ignore_get_levels(rec->level, rec->except_level); - printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_IGNORED, key, levels); + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_IGNORED, key, levels); g_free(key); g_free(levels); } @@ -212,7 +212,7 @@ static void cmd_unignore(const char *data) if (is_numeric(data, ' ')) { /* with index number */ - tmp = g_slist_nth(ignores, atol(data)-1); + tmp = g_slist_nth(ignores, atoi(data)-1); rec = tmp == NULL ? NULL : tmp->data; } else { /* with mask */ diff --git a/src/fe-common/irc/fe-irc-commands.c b/src/fe-common/irc/fe-irc-commands.c index bc6097cf..dc844346 100644 --- a/src/fe-common/irc/fe-irc-commands.c +++ b/src/fe-common/irc/fe-irc-commands.c @@ -28,7 +28,6 @@ #include "levels.h" #include "irc.h" #include "server.h" -#include "server-reconnect.h" #include "mode-lists.h" #include "nicklist.h" #include "channels.h" @@ -37,66 +36,6 @@ #include "windows.h" #include "window-items.h" -static void cmd_server(const char *data) -{ - if (*data == '+' && data[1] != '\0') - window_create(NULL, FALSE); -} - -static void print_servers(void) -{ - GSList *tmp; - - for (tmp = servers; tmp != NULL; tmp = tmp->next) { - IRC_SERVER_REC *rec = tmp->data; - - printformat(NULL, NULL, MSGLEVEL_CRAP, IRCTXT_SERVER_LIST, - rec->tag, rec->connrec->address, rec->connrec->port, - rec->connrec->ircnet == NULL ? "" : rec->connrec->ircnet, rec->connrec->nick); - } -} - -static void print_lookup_servers(void) -{ - GSList *tmp; - for (tmp = lookup_servers; tmp != NULL; tmp = tmp->next) { - IRC_SERVER_REC *rec = tmp->data; - - printformat(NULL, NULL, MSGLEVEL_CRAP, IRCTXT_SERVER_LOOKUP_LIST, - rec->tag, rec->connrec->address, rec->connrec->port, - rec->connrec->ircnet == NULL ? "" : rec->connrec->ircnet, rec->connrec->nick); - } -} - -static void print_reconnects(void) -{ - GSList *tmp; - char *tag, *next_connect; - int left; - - for (tmp = reconnects; tmp != NULL; tmp = tmp->next) { - RECONNECT_REC *rec = tmp->data; - IRC_SERVER_CONNECT_REC *conn = rec->conn; - - tag = g_strdup_printf("RECON-%d", rec->tag); - left = rec->next_connect-time(NULL); - next_connect = g_strdup_printf("%02d:%02d", left/60, left%60); - printformat(NULL, NULL, MSGLEVEL_CRAP, IRCTXT_SERVER_RECONNECT_LIST, - tag, conn->address, conn->port, - conn->ircnet == NULL ? "" : conn->ircnet, - conn->nick, next_connect); - g_free(next_connect); - g_free(tag); - } -} - -static void cmd_servers(void) -{ - print_servers(); - print_lookup_servers(); - print_reconnects(); -} - static void cmd_unquery(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item) { QUERY_REC *query; @@ -196,7 +135,7 @@ static void cmd_msg(gchar *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { /* msg to channel */ nickrec = channel == NULL ? NULL : nicklist_find(channel, server->nick); - nickmode = !settings_get_bool("toggle_show_nickmode") || nickrec == NULL ? "" : + nickmode = !settings_get_bool("show_nickmode") || nickrec == NULL ? "" : nickrec->op ? "@" : nickrec->voice ? "+" : " "; window = channel == NULL ? NULL : window_item_window((WI_ITEM_REC *) channel); @@ -329,8 +268,8 @@ static void cmd_ban(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item) GSList *tmp; g_return_if_fail(data != NULL); - if (*data == '\0') - return; /* setting ban - don't handle here */ + if (*data != '\0') + return; /* setting ban - don't handle here */ if (server == NULL || !server->connected) cmd_return_error(CMDERR_NOT_CONNECTED); @@ -415,52 +354,6 @@ static void cmd_join(const char *data, IRC_SERVER_REC *server) } } -static void cmd_channel(const char *data, IRC_SERVER_REC *server) -{ - CHANNEL_REC *channel; - GString *nicks; - GSList *nicklist, *tmp, *ntmp; - char *mode; - - if (*data != '\0') { - cmd_join(data, server); - return; - } - - if (channels == NULL) { - printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_NOT_IN_CHANNELS); - return; - } - - /* print active channel */ - channel = irc_item_channel(active_win->active); - if (channel != NULL) - printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_CURRENT_CHANNEL, channel->name); - - /* print list of all channels, their modes, server tags and nicks */ - printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_CHANLIST_HEADER); - for (tmp = channels; tmp != NULL; tmp = tmp->next) { - channel = tmp->data; - - nicklist = nicklist_getnicks(channel); - mode = channel_get_mode(channel); - nicks = g_string_new(NULL); - for (ntmp = nicklist; ntmp != NULL; ntmp = ntmp->next) { - NICK_REC *rec = ntmp->data; - - g_string_sprintfa(nicks, "%s ", rec->nick); - } - - g_string_truncate(nicks, nicks->len-1); - printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_CHANLIST_LINE, - channel->name, mode, channel->server->tag, nicks->str); - - g_free(mode); - g_slist_free(nicklist); - g_string_free(nicks, TRUE); - } -} - static void cmd_nick(const char *data, IRC_SERVER_REC *server) { g_return_if_fail(data != NULL); @@ -506,8 +399,6 @@ static void cmd_ts(const char *data) void fe_irc_commands_init(void) { - command_bind("server", NULL, (SIGNAL_FUNC) cmd_server); - command_bind("servers", NULL, (SIGNAL_FUNC) cmd_servers); command_bind("query", NULL, (SIGNAL_FUNC) cmd_query); command_bind("unquery", NULL, (SIGNAL_FUNC) cmd_unquery); command_bind("msg", NULL, (SIGNAL_FUNC) cmd_msg); @@ -519,7 +410,6 @@ void fe_irc_commands_init(void) command_bind("ban", NULL, (SIGNAL_FUNC) cmd_ban); command_bind("invitelist", NULL, (SIGNAL_FUNC) cmd_invitelist); command_bind("join", NULL, (SIGNAL_FUNC) cmd_join); - command_bind("channel", NULL, (SIGNAL_FUNC) cmd_channel); command_bind("nick", NULL, (SIGNAL_FUNC) cmd_nick); command_bind("ver", NULL, (SIGNAL_FUNC) cmd_ver); command_bind("ts", NULL, (SIGNAL_FUNC) cmd_ts); @@ -527,8 +417,6 @@ void fe_irc_commands_init(void) void fe_irc_commands_deinit(void) { - command_unbind("server", (SIGNAL_FUNC) cmd_server); - command_unbind("servers", (SIGNAL_FUNC) cmd_servers); command_unbind("query", (SIGNAL_FUNC) cmd_query); command_unbind("unquery", (SIGNAL_FUNC) cmd_unquery); command_unbind("msg", (SIGNAL_FUNC) cmd_msg); @@ -540,7 +428,6 @@ void fe_irc_commands_deinit(void) command_unbind("ban", (SIGNAL_FUNC) cmd_ban); command_unbind("invitelist", (SIGNAL_FUNC) cmd_invitelist); command_unbind("join", (SIGNAL_FUNC) cmd_join); - command_unbind("channel", (SIGNAL_FUNC) cmd_channel); command_unbind("nick", (SIGNAL_FUNC) cmd_nick); command_unbind("ver", (SIGNAL_FUNC) cmd_ver); command_unbind("ts", (SIGNAL_FUNC) cmd_ts); diff --git a/src/fe-common/irc/fe-irc-server.c b/src/fe-common/irc/fe-irc-server.c new file mode 100644 index 00000000..30e09886 --- /dev/null +++ b/src/fe-common/irc/fe-irc-server.c @@ -0,0 +1,215 @@ +/* + fe-irc-server.c : irssi + + Copyright (C) 1999-2000 Timo Sirainen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "module.h" +#include "module-formats.h" +#include "signals.h" +#include "commands.h" +#include "misc.h" + +#include "levels.h" +#include "irc-server.h" +#include "server-reconnect.h" +#include "server-setup.h" + +#include "windows.h" + +static void print_servers(void) +{ + GSList *tmp; + + for (tmp = servers; tmp != NULL; tmp = tmp->next) { + IRC_SERVER_REC *rec = tmp->data; + + printformat(NULL, NULL, MSGLEVEL_CRAP, IRCTXT_SERVER_LIST, + rec->tag, rec->connrec->address, rec->connrec->port, + rec->connrec->ircnet == NULL ? "" : rec->connrec->ircnet, rec->connrec->nick); + } +} + +static void print_lookup_servers(void) +{ + GSList *tmp; + for (tmp = lookup_servers; tmp != NULL; tmp = tmp->next) { + IRC_SERVER_REC *rec = tmp->data; + + printformat(NULL, NULL, MSGLEVEL_CRAP, IRCTXT_SERVER_LOOKUP_LIST, + rec->tag, rec->connrec->address, rec->connrec->port, + rec->connrec->ircnet == NULL ? "" : rec->connrec->ircnet, rec->connrec->nick); + } +} + +static void print_reconnects(void) +{ + GSList *tmp; + char *tag, *next_connect; + int left; + + for (tmp = reconnects; tmp != NULL; tmp = tmp->next) { + RECONNECT_REC *rec = tmp->data; + IRC_SERVER_CONNECT_REC *conn = rec->conn; + + tag = g_strdup_printf("RECON-%d", rec->tag); + left = rec->next_connect-time(NULL); + next_connect = g_strdup_printf("%02d:%02d", left/60, left%60); + printformat(NULL, NULL, MSGLEVEL_CRAP, IRCTXT_SERVER_RECONNECT_LIST, + tag, conn->address, conn->port, + conn->ircnet == NULL ? "" : conn->ircnet, + conn->nick, next_connect); + g_free(next_connect); + g_free(tag); + } +} + +static void server_add(const char *data) +{ + SETUP_SERVER_REC *rec; + char *params, *args, *ircnet, *host, *cmdspeed, *cmdmax; + char *addr, *portstr, *password, *nick; + int port; + + args = "ircnet host cmdspeed cmdmax"; + params = cmd_get_params(data, 9 | PARAM_FLAG_MULTIARGS, + &args, &ircnet, &host, &cmdspeed, &cmdmax, + &addr, &portstr, &password, &nick); + if (*addr == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + port = *portstr == '\0' ? 6667 : atoi(portstr); + + rec = server_setup_find(addr, port); + if (rec == NULL) { + rec = g_new0(SETUP_SERVER_REC, 1); + rec->address = g_strdup(addr); + rec->port = port; + } else { + g_free_and_null(rec->ircnet); + g_free_and_null(rec->password); + g_free_and_null(rec->own_host); + } + + rec->autoconnect = stristr(args, "-auto") != NULL; + if (*ircnet != '\0') rec->ircnet = g_strdup(ircnet); + if (*password != '\0') rec->password = g_strdup(password); + if (*host != '\0') rec->own_host = g_strdup(host); + rec->cmd_queue_speed = atoi(cmdspeed); + rec->max_cmds_at_once = atoi(cmdmax); + + server_setup_add(rec); + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_SETUPSERVER_ADDED, addr, port); + + g_free(params); +} + +static void server_remove(const char *data) +{ + SETUP_SERVER_REC *rec; + char *params, *args, *addr, *portstr; + int port; + + params = cmd_get_params(data, 3 | PARAM_FLAG_OPTARGS, &args, &addr, &portstr); + if (*addr == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + port = *portstr == '\0' ? 6667 : atoi(portstr); + + rec = server_setup_find(addr, port); + if (rec == NULL) + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_SETUPSERVER_NOT_FOUND, addr, port); + else { + server_setup_remove(rec); + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_SETUPSERVER_REMOVED, addr, port); + } + + g_free(params); +} + +static void server_list(const char *data) +{ + GString *str; + GSList *tmp; + + str = g_string_new(NULL); + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_SETUPSERVER_HEADER); + for (tmp = setupservers; tmp != NULL; tmp = tmp->next) { + SETUP_SERVER_REC *rec = tmp->data; + + g_string_truncate(str, 0); + if (rec->password != NULL) + g_string_append(str, "(pass) "); + if (rec->autoconnect) + g_string_append(str, "autoconnect "); + if (rec->max_cmds_at_once > 0) + g_string_sprintfa(str, "cmdmax: %d ", rec->max_cmds_at_once); + if (rec->cmd_queue_speed > 0) + g_string_sprintfa(str, "cmdspeed: %d ", rec->cmd_queue_speed); + if (rec->own_host != NULL) + g_string_sprintfa(str, "host: %s ", rec->own_host); + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_SETUPSERVER_LINE, + rec->address, rec->port, + rec->ircnet == NULL ? "" : rec->ircnet, + str->str); + } + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_SETUPSERVER_FOOTER); + g_string_free(str, TRUE); +} + +static void cmd_server(const char *data) +{ + char *params, *args, *ircnetarg, *hostarg, *addr; + + if (*data == '\0') { + print_servers(); + print_lookup_servers(); + print_reconnects(); + + signal_stop(); + return; + } + + args = "ircnet host"; + params = cmd_get_params(data, 4 | PARAM_FLAG_MULTIARGS, + &args, &ircnetarg, &hostarg, &addr); + + if (stristr(args, "-list") != NULL) { + server_list(data); + signal_stop(); + } else if (stristr(args, "-add") != NULL) { + if (*addr == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + server_add(data); + signal_stop(); + } else if (stristr(args, "-remove") != NULL) { + if (*addr == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + server_remove(data); + signal_stop(); + } else { + if (*addr == '\0' || strcmp(addr, "+") == 0) + cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + if (*addr == '+') window_create(NULL, FALSE); + } + + g_free(params); +} + +void fe_irc_server_init(void) +{ + command_bind("server", NULL, (SIGNAL_FUNC) cmd_server); +} + +void fe_irc_server_deinit(void) +{ + command_unbind("server", (SIGNAL_FUNC) cmd_server); +} diff --git a/src/fe-common/irc/fe-netsplit.c b/src/fe-common/irc/fe-netsplit.c new file mode 100644 index 00000000..b13ae437 --- /dev/null +++ b/src/fe-common/irc/fe-netsplit.c @@ -0,0 +1,69 @@ +/* + fe-netsplit.c : irssi + + Copyright (C) 2000 Timo Sirainen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "module.h" +#include "module-formats.h" +#include "signals.h" +#include "commands.h" + +#include "levels.h" +#include "netsplit.h" + +static void sig_netsplit_servers(NETSPLIT_SERVER_REC *rec) +{ + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_NETSPLIT, rec->server, rec->destserver); +} + +static void split_print(const char *nick, NETSPLIT_REC *rec) +{ + NETSPLIT_CHAN_REC *chan; + + chan = rec->channels->data; + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_NETSPLITS_LINE, + rec->nick, chan == NULL ? "" : chan->name, + rec->server->server, rec->server->destserver); +} + +static void cmd_netsplit(const char *data, IRC_SERVER_REC *server) +{ + if (server == NULL || !server->connected) + cmd_return_error(CMDERR_NOT_CONNECTED); + + if (server->split_servers == NULL) { + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_NO_NETSPLITS); + return; + } + + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_NETSPLITS_HEADER); + g_hash_table_foreach(server->splits, (GHFunc) split_print, NULL); + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_NETSPLITS_FOOTER); +} + +void fe_netsplit_init(void) +{ + signal_add("netsplit new server", (SIGNAL_FUNC) sig_netsplit_servers); + command_bind("netsplit", NULL, (SIGNAL_FUNC) cmd_netsplit); +} + +void fe_netsplit_deinit(void) +{ + signal_remove("netsplit new server", (SIGNAL_FUNC) sig_netsplit_servers); + command_unbind("netsplit", (SIGNAL_FUNC) cmd_netsplit); +} diff --git a/src/fe-common/irc/fe-query.c b/src/fe-common/irc/fe-query.c index be46ea0b..5444a031 100644 --- a/src/fe-common/irc/fe-query.c +++ b/src/fe-common/irc/fe-query.c @@ -23,6 +23,7 @@ #include "modules.h" #include "signals.h" #include "commands.h" +#include "settings.h" #include "irc.h" #include "levels.h" @@ -31,6 +32,8 @@ #include "windows.h" #include "window-items.h" +static int queryclose_tag, query_auto_close; + static void signal_query_created(QUERY_REC *query, gpointer automatic) { window_item_create((WI_ITEM_REC *) query, GPOINTER_TO_INT(automatic)); @@ -110,12 +113,67 @@ static void cmd_wquery(const char *data, void *server, WI_ITEM_REC *item) signal_remove("query created", (SIGNAL_FUNC) signal_query_created_curwin); } +static void sig_window_changed(WINDOW_REC *window) +{ + GSList *tmp; + + if (query_auto_close <= 0) + return; + + for (tmp = window->items; tmp != NULL; tmp = tmp->next) { + if (irc_item_query(tmp->data)) + break; + } + if (tmp == NULL) return; /* no queries in window */ + + /* reset the window's last_line timestamp so that query doesn't get + closed immediately after switched to the window. */ + window->last_line = time(NULL); +} + +static int sig_query_autoclose(void) +{ + WINDOW_REC *window; + GSList *tmp, *next; + time_t now; + + now = time(NULL); + for (tmp = queries; tmp != NULL; tmp = next) { + QUERY_REC *rec = tmp->data; + + next = tmp->next; + window = window_item_window((WI_ITEM_REC *) rec); + if (window != active_win && rec->new_data == 0 && + now-window->last_line > query_auto_close) + query_destroy(rec); + } + return 1; +} + +static void read_settings(void) +{ + query_auto_close = settings_get_int("query_auto_close"); + if (query_auto_close > 0 && queryclose_tag == -1) + queryclose_tag = g_timeout_add(5000, (GSourceFunc) sig_query_autoclose, NULL); + else if (query_auto_close <= 0 && queryclose_tag != -1) { + g_source_remove(queryclose_tag); + queryclose_tag = -1; + } +} + void fe_query_init(void) { + settings_add_int("lookandfeel", "query_auto_close", 0); + + queryclose_tag = -1; + read_settings(); + signal_add("query created", (SIGNAL_FUNC) signal_query_created); signal_add("query destroyed", (SIGNAL_FUNC) signal_query_destroyed); signal_add("window item remove", (SIGNAL_FUNC) signal_window_item_removed); signal_add("server connected", (SIGNAL_FUNC) sig_server_connected); + signal_add("window changed", (SIGNAL_FUNC) sig_window_changed); + signal_add("setup changed", (SIGNAL_FUNC) read_settings); command_bind("wquery", NULL, (SIGNAL_FUNC) cmd_wquery); command_bind("window server", NULL, (SIGNAL_FUNC) cmd_window_server); @@ -123,10 +181,14 @@ void fe_query_init(void) void fe_query_deinit(void) { + if (queryclose_tag != -1) g_source_remove(queryclose_tag); + signal_remove("query created", (SIGNAL_FUNC) signal_query_created); signal_remove("query destroyed", (SIGNAL_FUNC) signal_query_destroyed); signal_remove("window item remove", (SIGNAL_FUNC) signal_window_item_removed); signal_remove("server connected", (SIGNAL_FUNC) sig_server_connected); + signal_remove("window changed", (SIGNAL_FUNC) sig_window_changed); + signal_remove("setup changed", (SIGNAL_FUNC) read_settings); command_unbind("wquery", (SIGNAL_FUNC) cmd_wquery); command_unbind("window server", (SIGNAL_FUNC) cmd_window_server); diff --git a/src/fe-common/irc/irc-nick-hilight.c b/src/fe-common/irc/irc-window-activity.c index 0d790822..5a9aa86f 100644 --- a/src/fe-common/irc/irc-nick-hilight.c +++ b/src/fe-common/irc/irc-window-activity.c @@ -1,5 +1,5 @@ /* - irc-nick-hilight.c : irssi + irc-window-activity.c : irssi Copyright (C) 1999-2000 Timo Sirainen @@ -78,12 +78,12 @@ static void event_privmsg(const char *data, IRC_SERVER_REC *server, const char * g_free(params); } -void irc_nick_hilight_init(void) +void irc_window_activity_init(void) { signal_add_last("event privmsg", (SIGNAL_FUNC) event_privmsg); } -void irc_nick_hilight_deinit(void) +void irc_window_activity_deinit(void) { signal_remove("event privmsg", (SIGNAL_FUNC) event_privmsg); } diff --git a/src/fe-common/irc/module-formats.c b/src/fe-common/irc/module-formats.c index 4b46959c..b1040d40 100644 --- a/src/fe-common/irc/module-formats.c +++ b/src/fe-common/irc/module-formats.c @@ -36,6 +36,17 @@ FORMAT_REC fecommon_irc_formats[] = { "server_reconnect_removed", "Removed reconnection to server %_$0%_ port %_$1%_", 3, { 0, 1, 0 } }, { "server_reconnect_not_found", "Reconnection tag %_$0%_ not found", 1, { 0 } }, { "query_server_changed", "Query with %_$2%_ changed to server %_$1%_", 3, { 0, 0, 0 } }, + { "setupserver_added", "Server $0 saved", 2, { 0, 0 } }, + { "setupserver_removed", "Server $0 removed", 2, { 0, 0 } }, + { "setupserver_not_found", "Server $0 not found", 2, { 0, 0 } }, + { "setupserver_header", "Server Port IRC Net Settings", 0 }, + { "setupserver_line", "%|$[!20]0 $[5]1 $[10]2 $3", 4, { 0, 1, 0, 0 } }, + { "setupserver_footer", "", 0 }, + { "netsplit", "%RNetsplit%n detected between servers %_$0%_ and %_$1%_%:Use /NETSPLIT to see who left", 2, { 0, 0 } }, + { "no_netsplits", "There are no net splits", 0 }, + { "netsplits_header", "Nick Channel Server Splitted server", 0 }, + { "netsplits_line", "$[9]0 $[10]1 $[20]2 $3", 4, { 0, 0, 0, 0 } }, + { "netsplits_footer", "", 0 }, /* ---- */ { NULL, "Channels", 0 }, @@ -73,11 +84,17 @@ FORMAT_REC fecommon_irc_formats[] = { "ebanlist_long", "%_$0%_: ban exception %c$1 %K[%nby %_$2%_, $3 secs ago%K]", 4, { 0, 0, 0, 1 } }, { "invitelist", "%_$0%_: invite %c$1", 2, { 0, 0 } }, { "no_such_channel", "$0: No such channel", 1, { 0 } }, + { "channel_synced", "Join to %_$0%_ was synced in %_$1%_ secs", 2, { 0, 2 } }, { "not_in_channels", "You are not on any channels", 0 }, { "current_channel", "Current channel $0", 1, { 0 } }, { "chanlist_header", "You are on the following channels:", 0 }, { "chanlist_line", "$[-10]0 %|+$1 ($2): $3", 4, { 0, 0, 0, 0 } }, - { "channel_synced", "Join to %_$0%_ was synced in %_$1%_ secs", 2, { 0, 2 } }, + { "chansetup_not_found", "Channel $0 not found", 2, { 0, 0 } }, + { "chansetup_added", "Channel $0 saved", 2, { 0, 0 } }, + { "chansetup_removed", "Channel $0 removed", 2, { 0, 0 } }, + { "chansetup_header", "Channel IRC net Password Settings", 0 }, + { "chansetup_line", "$[15]0 %|$[10]1 $[10]2 $3", 4, { 0, 0, 0, 0 } }, + { "chansetup_footer", "", 0 }, /* ---- */ { NULL, "Nick", 0 }, diff --git a/src/fe-common/irc/module-formats.h b/src/fe-common/irc/module-formats.h index 325d3f4a..c7dc5bf8 100644 --- a/src/fe-common/irc/module-formats.h +++ b/src/fe-common/irc/module-formats.h @@ -13,6 +13,17 @@ enum { IRCTXT_RECONNECT_REMOVED, IRCTXT_RECONNECT_NOT_FOUND, IRCTXT_QUERY_SERVER_CHANGED, + IRCTXT_SETUPSERVER_ADDED, + IRCTXT_SETUPSERVER_REMOVED, + IRCTXT_SETUPSERVER_NOT_FOUND, + IRCTXT_SETUPSERVER_HEADER, + IRCTXT_SETUPSERVER_LINE, + IRCTXT_SETUPSERVER_FOOTER, + IRCTXT_NETSPLIT, + IRCTXT_NO_NETSPLITS, + IRCTXT_NETSPLITS_HEADER, + IRCTXT_NETSPLITS_LINE, + IRCTXT_NETSPLITS_FOOTER, IRCTXT_FILL_2, @@ -49,11 +60,17 @@ enum { IRCTXT_EBANLIST_LONG, IRCTXT_INVITELIST, IRCTXT_NO_SUCH_CHANNEL, + IRCTXT_CHANNEL_SYNCED, IRCTXT_NOT_IN_CHANNELS, IRCTXT_CURRENT_CHANNEL, IRCTXT_CHANLIST_HEADER, IRCTXT_CHANLIST_LINE, - IRCTXT_CHANNEL_SYNCED, + IRCTXT_CHANSETUP_NOT_FOUND, + IRCTXT_CHANSETUP_ADDED, + IRCTXT_CHANSETUP_REMOVED, + IRCTXT_CHANSETUP_HEADER, + IRCTXT_CHANSETUP_LINE, + IRCTXT_CHANSETUP_FOOTER, IRCTXT_FILL_4, |