summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/commands.c20
-rw-r--r--src/core/commands.h7
-rw-r--r--src/core/core.c4
-rw-r--r--src/core/memdebug.c19
-rw-r--r--src/core/settings.c23
-rw-r--r--src/core/settings.h4
-rw-r--r--src/fe-common/core/Makefile.am3
-rw-r--r--src/fe-common/core/fe-common-core.c18
-rw-r--r--src/fe-common/core/fe-core-commands.c17
-rw-r--r--src/fe-common/core/fe-log.c20
-rw-r--r--src/fe-common/core/hilight-text.c6
-rw-r--r--src/fe-common/core/keyboard.c10
-rw-r--r--src/fe-common/core/module-formats.c140
-rw-r--r--src/fe-common/core/module-formats.h3
-rw-r--r--src/fe-common/core/printformat.h25
-rw-r--r--src/fe-common/core/printtext.c888
-rw-r--r--src/fe-common/core/printtext.h58
-rw-r--r--src/fe-common/core/themes.c380
-rw-r--r--src/fe-common/core/themes.h18
-rw-r--r--src/fe-common/core/window-activity.c4
-rw-r--r--src/fe-common/core/window-commands.c370
-rw-r--r--src/fe-common/core/window-items.c69
-rw-r--r--src/fe-common/core/window-items.h5
-rw-r--r--src/fe-common/core/windows.c474
-rw-r--r--src/fe-common/core/windows.h4
-rw-r--r--src/fe-common/irc/dcc/Makefile.am1
-rw-r--r--src/fe-common/irc/dcc/fe-dcc.c5
-rw-r--r--src/fe-common/irc/dcc/module-formats.c71
-rw-r--r--src/fe-common/irc/dcc/module-formats.h3
-rw-r--r--src/fe-common/irc/dcc/module.h3
-rw-r--r--src/fe-common/irc/fe-common-irc.c6
-rw-r--r--src/fe-common/irc/flood/Makefile.am3
-rw-r--r--src/fe-common/irc/flood/fe-flood.c6
-rw-r--r--src/fe-common/irc/flood/module-formats.c12
-rw-r--r--src/fe-common/irc/flood/module-formats.h3
-rw-r--r--src/fe-common/irc/flood/module.h3
-rw-r--r--src/fe-common/irc/module-formats.c340
-rw-r--r--src/fe-common/irc/module-formats.h3
-rw-r--r--src/fe-common/irc/notifylist/Makefile.am3
-rw-r--r--src/fe-common/irc/notifylist/fe-notifylist.c6
-rw-r--r--src/fe-common/irc/notifylist/module-formats.c28
-rw-r--r--src/fe-common/irc/notifylist/module-formats.h3
-rw-r--r--src/fe-common/irc/notifylist/module.h3
-rw-r--r--src/fe-text/gui-printtext.c497
-rw-r--r--src/fe-text/gui-windows.c544
-rw-r--r--src/fe-text/gui-windows.h16
-rw-r--r--src/fe-text/irssi.c10
-rw-r--r--src/fe-text/mainwindows.c16
-rw-r--r--src/fe-text/module-formats.c12
-rw-r--r--src/fe-text/module-formats.h3
-rw-r--r--src/irc/core/Makefile.am1
-rw-r--r--src/irc/core/channel-events.c2
-rw-r--r--src/irc/core/channel-rejoin.c104
-rw-r--r--src/irc/core/channels.c21
-rw-r--r--src/irc/core/irc-log.c16
-rw-r--r--src/irc/core/irc-server.h3
-rw-r--r--src/irc/core/server-setup.c2
-rw-r--r--src/irc/dcc/dcc-chat.c4
-rw-r--r--src/irc/dcc/dcc-files.c4
-rw-r--r--src/perl/irssi-perl.c3
60 files changed, 2457 insertions, 1892 deletions
diff --git a/src/core/commands.c b/src/core/commands.c
index 8f02db89..1dfd8b71 100644
--- a/src/core/commands.c
+++ b/src/core/commands.c
@@ -436,8 +436,24 @@ static void cmd_cd(const char *data)
g_free(str);
}
+static void cmd_rehash(const char *data)
+{
+ char *fname;
+
+ fname = *data != '\0' ? g_strdup(data) :
+ g_strdup_printf("%s/.irssi/config", g_get_home_dir());
+ settings_reread(fname);
+ g_free(fname);
+}
+
+static void cmd_save(const char *data)
+{
+ settings_save(*data != '\0' ? data : NULL);
+}
+
void commands_init(void)
{
+ commands = NULL;
cmdget_funcs = NULL;
current_command = NULL;
@@ -448,6 +464,8 @@ void commands_init(void)
command_bind("eval", NULL, (SIGNAL_FUNC) cmd_eval);
command_bind("cd", NULL, (SIGNAL_FUNC) cmd_cd);
+ command_bind("rehash", NULL, (SIGNAL_FUNC) cmd_rehash);
+ command_bind("save", NULL, (SIGNAL_FUNC) cmd_save);
}
void commands_deinit(void)
@@ -459,4 +477,6 @@ void commands_deinit(void)
command_unbind("eval", (SIGNAL_FUNC) cmd_eval);
command_unbind("cd", (SIGNAL_FUNC) cmd_cd);
+ command_unbind("rehash", (SIGNAL_FUNC) cmd_rehash);
+ command_unbind("save", (SIGNAL_FUNC) cmd_save);
}
diff --git a/src/core/commands.h b/src/core/commands.h
index b4577e70..554a60e5 100644
--- a/src/core/commands.h
+++ b/src/core/commands.h
@@ -10,16 +10,11 @@ typedef struct {
COMMAND_REC;
enum {
- CMDERR_PARAM, /* invalid parameter */
+ CMDERR_ERRNO, /* get the error from errno */
CMDERR_NOT_ENOUGH_PARAMS, /* not enough parameters given */
CMDERR_NOT_CONNECTED, /* not connected to IRC server */
CMDERR_NOT_JOINED, /* not joined to any channels in this window */
- CMDERR_GETSOCKNAME, /* getsockname() failed */
- CMDERR_LISTEN, /* listen() failed */
- CMDERR_MULTIPLE_MATCHES, /* multiple matches found, didn't do anything */
- CMDERR_NICK_NOT_FOUND, /* nick not found */
CMDERR_CHAN_NOT_FOUND, /* channel not found */
- CMDERR_SERVER_NOT_FOUND, /* server not found */
CMDERR_CHAN_NOT_SYNCED, /* channel not fully synchronized yet */
CMDERR_NOT_GOOD_IDEA /* not good idea to do, -yes overrides this */
};
diff --git a/src/core/core.c b/src/core/core.c
index c850a572..2102ebcd 100644
--- a/src/core/core.c
+++ b/src/core/core.c
@@ -43,9 +43,9 @@ void core_init(void)
net_disconnect_init();
signals_init();
settings_init();
+ commands_init();
servers_init();
- commands_init();
log_init();
rawlog_init();
special_vars_init();
@@ -56,9 +56,9 @@ void core_deinit(void)
special_vars_deinit();
rawlog_deinit();
log_deinit();
- commands_deinit();
servers_deinit();
+ commands_deinit();
settings_deinit();
signals_deinit();
net_disconnect_deinit();
diff --git a/src/core/memdebug.c b/src/core/memdebug.c
index 1be7bbd8..fcd92659 100644
--- a/src/core/memdebug.c
+++ b/src/core/memdebug.c
@@ -132,35 +132,26 @@ static void *data_remove(void *p, const char *file, int line)
void *ig_malloc(int size, const char *file, int line)
{
-#if 1
void *p;
size += BUFFER_CHECK_SIZE*2;
p = g_malloc(size);
data_add(p, size, file, line);
return p+BUFFER_CHECK_SIZE;
-#else
- return g_malloc(size);
-#endif
}
void *ig_malloc0(int size, const char *file, int line)
{
-#if 1
void *p;
size += BUFFER_CHECK_SIZE*2;
p = g_malloc0(size);
data_add(p, size, file, line);
return p+BUFFER_CHECK_SIZE;
-#else
- return g_malloc0(size);
-#endif
}
void *ig_realloc(void *mem, unsigned long size, const char *file, int line)
{
-#if 1
void *p;
size += BUFFER_CHECK_SIZE*2;
@@ -169,9 +160,6 @@ void *ig_realloc(void *mem, unsigned long size, const char *file, int line)
p = g_realloc(mem, size);
data_add(p, size, file, line);
return p+BUFFER_CHECK_SIZE;
-#else
- return g_realloc(mem, size);
-#endif
}
char *ig_strdup(const char *str, const char *file, int line)
@@ -264,12 +252,11 @@ char *ig_strdup_vprintf(const char *file, int line, const char *format, va_list
void ig_free(void *p)
{
-#if 1
+ if (p == NULL) g_error("ig_free() : trying to free NULL");
+
p -= BUFFER_CHECK_SIZE;
p = data_remove(p, "??", 0);
- if (p != NULL)
-#endif
- g_free(p);
+ if (p != NULL) g_free(p);
}
GString *ig_string_new(const char *file, int line, const char *str)
diff --git a/src/core/settings.c b/src/core/settings.c
index a7e27a63..5133dd6b 100644
--- a/src/core/settings.c
+++ b/src/core/settings.c
@@ -21,6 +21,7 @@
#include "module.h"
#include "signals.h"
#include "commands.h"
+#include "misc.h"
#include "lib-config/iconfig.h"
#include "settings.h"
@@ -278,15 +279,16 @@ static void init_configfile(void)
signal(SIGTERM, sig_term);
}
-static void cmd_rehash(const char *data)
+void settings_reread(const char *fname)
{
CONFIG_REC *tempconfig;
- char *str, *fname;
+ char *str;
- fname = *data != '\0' ? g_strdup(data) :
- g_strdup_printf("%s/.irssi/config", g_get_home_dir());
- tempconfig = parse_configfile(fname);
- g_free(fname);
+ if (fname == NULL) fname = "~/.irssi/config";
+
+ str = convert_home(fname);
+ tempconfig = parse_configfile(str);
+ g_free(str);
if (tempconfig == NULL) {
signal_emit("gui dialog", 2, "error", g_strerror(errno));
@@ -310,11 +312,11 @@ static void cmd_rehash(const char *data)
signal_emit("setup reread", 0);
}
-static void cmd_save(const char *data)
+void settings_save(const char *fname)
{
char *str;
- if (config_write(mainconfig, *data == '\0' ? NULL : data, 0660) == 0)
+ if (config_write(mainconfig, fname, 0660) == 0)
return;
/* error */
@@ -329,8 +331,6 @@ void settings_init(void)
settings = g_hash_table_new((GHashFunc) g_str_hash, (GCompareFunc) g_str_equal);
init_configfile();
- command_bind("rehash", NULL, (SIGNAL_FUNC) cmd_rehash);
- command_bind("save", NULL, (SIGNAL_FUNC) cmd_save);
}
static void settings_hash_free(const char *key, SETTINGS_REC *rec)
@@ -340,9 +340,6 @@ static void settings_hash_free(const char *key, SETTINGS_REC *rec)
void settings_deinit(void)
{
- command_unbind("rehash", (SIGNAL_FUNC) cmd_rehash);
- command_unbind("save", (SIGNAL_FUNC) cmd_save);
-
g_free_not_null(last_error_msg);
g_hash_table_foreach(settings, (GHFunc) settings_hash_free, NULL);
g_hash_table_destroy(settings);
diff --git a/src/core/settings.h b/src/core/settings.h
index 6f29de6e..583e0dd6 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -53,6 +53,10 @@ GSList *settings_get_sorted(void);
/* Get the record of the setting */
SETTINGS_REC *settings_get_record(const char *key);
+/* if `fname' is NULL, the default is used */
+void settings_reread(const char *fname);
+void settings_save(const char *fname);
+
void settings_init(void);
void settings_deinit(void);
diff --git a/src/fe-common/core/Makefile.am b/src/fe-common/core/Makefile.am
index c8931435..c8e24dad 100644
--- a/src/fe-common/core/Makefile.am
+++ b/src/fe-common/core/Makefile.am
@@ -17,10 +17,11 @@ libfe_common_core_la_SOURCES = \
hilight-text.c \
keyboard.c \
module-formats.c \
- window-activity.c \
printtext.c \
themes.c \
translation.c \
+ window-activity.c \
+ window-commands.c \
window-items.c \
windows.c
diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c
index a348583d..02c67010 100644
--- a/src/fe-common/core/fe-common-core.c
+++ b/src/fe-common/core/fe-common-core.c
@@ -18,6 +18,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "module.h"
+#include "module-formats.h"
#include "levels.h"
#include "settings.h"
@@ -50,6 +51,9 @@ void fe_settings_deinit(void);
void window_activity_init(void);
void window_activity_deinit(void);
+void window_commands_init(void);
+void window_commands_deinit(void);
+
void fe_core_commands_init(void);
void fe_core_commands_deinit(void);
@@ -73,8 +77,10 @@ void fe_common_core_init(void)
settings_add_int("lookandfeel", "tab_orientation", 3);*/
settings_add_str("lookandfeel", "current_theme", "default");
+ themes_init();
+ theme_register(fecommon_core_formats);
+
autorun_init();
- window_activity_init();
hilight_text_init();
command_history_init();
keyboard_init();
@@ -82,9 +88,10 @@ void fe_common_core_init(void)
fe_log_init();
fe_server_init();
fe_settings_init();
- themes_init();
translation_init();
windows_init();
+ window_activity_init();
+ window_commands_init();
window_items_init();
fe_core_commands_init();
}
@@ -92,7 +99,6 @@ void fe_common_core_init(void)
void fe_common_core_deinit(void)
{
autorun_deinit();
- window_activity_deinit();
hilight_text_deinit();
command_history_deinit();
keyboard_deinit();
@@ -100,11 +106,15 @@ void fe_common_core_deinit(void)
fe_log_deinit();
fe_server_deinit();
fe_settings_deinit();
- themes_deinit();
translation_deinit();
windows_deinit();
+ window_activity_deinit();
+ window_commands_deinit();
window_items_deinit();
fe_core_commands_deinit();
+
+ theme_unregister();
+ themes_deinit();
}
void fe_common_core_finish_init(void)
diff --git a/src/fe-common/core/fe-core-commands.c b/src/fe-common/core/fe-core-commands.c
index 41320eed..c4af0f7c 100644
--- a/src/fe-common/core/fe-core-commands.c
+++ b/src/fe-common/core/fe-core-commands.c
@@ -30,16 +30,11 @@
#include "windows.h"
static const char *ret_texts[] = {
- "Invalid parameter",
+ NULL,
"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",
};
@@ -269,9 +264,15 @@ static void cmd_unknown(const char *data, void *server, WI_ITEM_REC *item)
signal_stop();
}
-static void event_cmderror(gpointer error)
+static void event_cmderror(gpointer errorp)
{
- printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, ret_texts[GPOINTER_TO_INT(error)]);
+ int error;
+
+ error = GPOINTER_TO_INT(errorp);
+ if (error == CMDERR_ERRNO)
+ printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, g_strerror(errno));
+ else
+ printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, ret_texts[error]);
}
void fe_core_commands_init(void)
diff --git a/src/fe-common/core/fe-log.c b/src/fe-common/core/fe-log.c
index f3fc6f56..58cd28fe 100644
--- a/src/fe-common/core/fe-log.c
+++ b/src/fe-common/core/fe-log.c
@@ -297,25 +297,27 @@ static void autolog_log(void *server, const char *target)
g_free(fname);
}
-/* write to logs created with /WINDOW LOG */
-static void sig_printtext_stripped(void *server, const char *target, gpointer levelp, const char *text)
+static void sig_printtext_stripped(WINDOW_REC *window, void *server, const char *target, gpointer levelp, const char *text)
{
char windownum[MAX_INT_STRLEN];
- WINDOW_REC *window;
LOG_REC *log;
int level;
level = GPOINTER_TO_INT(levelp);
+ if (level == MSGLEVEL_NEVER) return;
+
+ /* let autolog create the log records */
if ((autolog_level & level) && target != NULL && *target != '\0')
autolog_log(server, target);
- window = window_find_closest(server, target, level);
- if (window != NULL) {
- ltoa(windownum, window->refnum);
+ /* save to log created with /WINDOW LOG */
+ ltoa(windownum, window->refnum);
+ log = log_find_item(windownum);
+ if (log != NULL) log_write_rec(log, text);
- log = log_find_item(windownum);
- if (log != NULL) log_write_rec(log, text);
- }
+ /* save line to logs */
+ if (logs != NULL)
+ log_write(target, level, text);
}
static int sig_autoremove(void)
diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c
index 307f9f02..6b5735b0 100644
--- a/src/fe-common/core/hilight-text.c
+++ b/src/fe-common/core/hilight-text.c
@@ -132,7 +132,7 @@ static HILIGHT_REC *hilight_find(const char *text, char **channels)
return NULL;
}
-static void sig_print_text(SERVER_REC *server, const char *channel, gpointer level, const char *str)
+static void sig_print_text(WINDOW_REC *window, SERVER_REC *server, const char *channel, gpointer level, const char *str)
{
if (hilight_next) {
hilight_next = FALSE;
@@ -140,7 +140,7 @@ static void sig_print_text(SERVER_REC *server, const char *channel, gpointer lev
}
}
-static void sig_print_text_stripped(SERVER_REC *server, const char *channel, gpointer plevel, const char *str)
+static void sig_print_text_stripped(WINDOW_REC *window, SERVER_REC *server, const char *channel, gpointer plevel, const char *str)
{
GSList *tmp;
char *color, *newstr;
@@ -184,7 +184,7 @@ static void sig_print_text_stripped(SERVER_REC *server, const char *channel, gpo
if (color == NULL) color = "\00316";
newstr = g_strconcat(isdigit(*color) ? "\003" : "", color, str, NULL);
- signal_emit("print text", 4, server, channel, GINT_TO_POINTER(level | MSGLEVEL_HILIGHT), newstr);
+ signal_emit("print text", 5, window, server, channel, GINT_TO_POINTER(level | MSGLEVEL_HILIGHT), newstr);
g_free(newstr);
hilight_next = TRUE;
diff --git a/src/fe-common/core/keyboard.c b/src/fe-common/core/keyboard.c
index 854d4d7e..0406c758 100644
--- a/src/fe-common/core/keyboard.c
+++ b/src/fe-common/core/keyboard.c
@@ -258,12 +258,6 @@ static void read_keyboard_config(void)
CONFIG_NODE *node;
GSList *tmp;
- while (keyinfos != NULL)
- keyinfo_remove(keyinfos->data);
- if (keys != NULL) g_hash_table_destroy(keys);
-
- keys = g_hash_table_new((GHashFunc) g_str_hash, (GCompareFunc) g_str_equal);
-
node = iconfig_node_traverse("keyboard", FALSE);
if (node == NULL) return;
@@ -280,7 +274,9 @@ static void read_keyboard_config(void)
void keyboard_init(void)
{
- keyinfos = NULL; keys = NULL;
+ keys = g_hash_table_new((GHashFunc) g_str_hash, (GCompareFunc) g_str_equal);
+ keyinfos = NULL;
+
key_bind("command", NULL, "Run any IRC command", NULL, (SIGNAL_FUNC) sig_command);
read_keyboard_config();
diff --git a/src/fe-common/core/module-formats.c b/src/fe-common/core/module-formats.c
index 5a12f6fc..a224a809 100644
--- a/src/fe-common/core/module-formats.c
+++ b/src/fe-common/core/module-formats.c
@@ -21,73 +21,75 @@
#include "module.h"
#include "printtext.h"
-FORMAT_REC fecommon_core_formats[] =
-{
- { MODULE_NAME, "Core", 0 },
-
- /* ---- */
- { NULL, "Windows", 0 },
-
- { "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 } },
- { "talking_with", "You are now talking with %_$0%_", 1, { 0 } },
- { "refnum_too_low", "Window number must be greater than 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 },
-
- { "looking_up", "Looking up %_$0%_", 1, { 0 } },
- { "connecting", "Connecting to %_$0%_ %K[%n$1%K]%n port %_$2%_", 3, { 0, 0, 1 } },
- { "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 } },
-
- /* ---- */
- { NULL, "Highlighting", 0 },
-
- { "hilight_header", "Highlights:", 0 },
- { "hilight_line", "$[-4]0 $1 $2 $3$3$4$5", 7, { 1, 0, 0, 0, 0, 0, 0 } },
- { "hilight_footer", "", 0 },
- { "hilight_not_found", "Highlight not found: $0", 1, { 0 } },
- { "hilight_removed", "Highlight removed: $0", 1, { 0 } },
-
- /* ---- */
- { NULL, "Aliases", 0 },
-
- { "alias_added", "Alias $0 added", 1, { 0 } },
- { "alias_removed", "Alias $0 removed", 1, { 0 } },
- { "alias_not_found", "No such alias: $0", 1, { 0 } },
- { "aliaslist_header", "Aliases:", 0 },
- { "aliaslist_line", "$[10]0 $1", 2, { 0, 0 } },
- { "aliaslist_footer", "", 0 },
-
- /* ---- */
- { NULL, "Logging", 0 },
-
- { "log_opened", "Log file %W$0%n opened", 1, { 0 } },
- { "log_closed", "Log file %W$0%n closed", 1, { 0 } },
- { "log_create_failed", "Couldn't create log file %W$0", 1, { 0 } },
- { "log_locked", "Log file %W$0%n is locked, probably by another running Irssi", 1, { 0 } },
- { "log_not_open", "Log file %W$0%n not open", 1, { 0 } },
- { "log_started", "Started logging to file %W$0", 1, { 0 } },
- { "log_stopped", "Stopped logging to file %W$0", 1, { 0 } },
- { "log_list_header", "Logs:", 0 },
- { "log_list", "$0: $1 $2$3$4", 5, { 0, 0, 0, 0, 0 } },
- { "log_list_footer", "", 0 },
- { "windowlog_file", "Window LOGFILE set to $0", 1, { 0 } },
- { "windowlog_file_logging", "Can't change window's logfile while log is on", 0 },
-
- /* ---- */
- { NULL, "Misc", 0 },
-
- { "not_toggle", "Value must be either ON, OFF or TOGGLE", 0 },
- { "perl_error", "Perl error: $0", 1, { 0 } }
+FORMAT_REC fecommon_core_formats[] = {
+ { MODULE_NAME, "Core", 0 },
+
+ /* ---- */
+ { NULL, "Windows", 0 },
+
+ { "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]{0}-$[-2.0]1 $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 } }, /*REMOVE!!!!!!!!*/
+ { "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 },
+
+ { "looking_up", "Looking up %_$0%_", 1, { 0 } },
+ { "connecting", "Connecting to %_$0%_ %K[%n$1%K]%n port %_$2%_", 3, { 0, 0, 1 } },
+ { "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 } },
+
+ /* ---- */
+ { NULL, "Highlighting", 0 },
+
+ { "hilight_header", "Highlights:", 0 },
+ { "hilight_line", "$[-4]0 $1 $2 $3$3$4$5", 7, { 1, 0, 0, 0, 0, 0, 0 } },
+ { "hilight_footer", "", 0 },
+ { "hilight_not_found", "Highlight not found: $0", 1, { 0 } },
+ { "hilight_removed", "Highlight removed: $0", 1, { 0 } },
+
+ /* ---- */
+ { NULL, "Aliases", 0 },
+
+ { "alias_added", "Alias $0 added", 1, { 0 } },
+ { "alias_removed", "Alias $0 removed", 1, { 0 } },
+ { "alias_not_found", "No such alias: $0", 1, { 0 } },
+ { "aliaslist_header", "Aliases:", 0 },
+ { "aliaslist_line", "$[10]0 $1", 2, { 0, 0 } },
+ { "aliaslist_footer", "", 0 },
+
+ /* ---- */
+ { NULL, "Logging", 0 },
+
+ { "log_opened", "Log file %W$0%n opened", 1, { 0 } },
+ { "log_closed", "Log file %W$0%n closed", 1, { 0 } },
+ { "log_create_failed", "Couldn't create log file %W$0", 1, { 0 } },
+ { "log_locked", "Log file %W$0%n is locked, probably by another running Irssi", 1, { 0 } },
+ { "log_not_open", "Log file %W$0%n not open", 1, { 0 } },
+ { "log_started", "Started logging to file %W$0", 1, { 0 } },
+ { "log_stopped", "Stopped logging to file %W$0", 1, { 0 } },
+ { "log_list_header", "Logs:", 0 },
+ { "log_list", "$0: $1 $2$3$4", 5, { 0, 0, 0, 0, 0 } },
+ { "log_list_footer", "", 0 },
+ { "windowlog_file", "Window LOGFILE set to $0", 1, { 0 } },
+ { "windowlog_file_logging", "Can't change window's logfile while log is on", 0 },
+
+ /* ---- */
+ { NULL, "Misc", 0 },
+
+ { "not_toggle", "Value must be either ON, OFF or TOGGLE", 0 },
+ { "perl_error", "Perl error: $0", 1, { 0 } },
+
+ { NULL, NULL, 0 }
};
diff --git a/src/fe-common/core/module-formats.h b/src/fe-common/core/module-formats.h
index 94392763..137c718f 100644
--- a/src/fe-common/core/module-formats.h
+++ b/src/fe-common/core/module-formats.h
@@ -65,6 +65,3 @@ enum {
};
extern FORMAT_REC fecommon_core_formats[];
-#define MODULE_FORMATS fecommon_core_formats
-
-#include "printformat.h"
diff --git a/src/fe-common/core/printformat.h b/src/fe-common/core/printformat.h
deleted file mode 100644
index e1dcf761..00000000
--- a/src/fe-common/core/printformat.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* printformat(...) = printformat_format(module_formats, ...)
-
- Could this be any harder? :) With GNU C compiler and C99 compilers,
- use #define. With others use either inline functions if they are
- supported or static functions if they are not..
- */
-#if defined (__GNUC__) && !defined (__STRICT_ANSI__)
-/* GCC */
-# define printformat(server, channel, level, formatnum...) \
- printformat_format(MODULE_FORMATS, server, channel, level, ##formatnum)
-#elif defined (_ISOC99_SOURCE)
-/* C99 */
-# define printformat(server, channel, level, formatnum, ...) \
- printformat_format(MODULE_FORMATS, server, channel, level, formatnum, __VA_ARGS__)
-#else
-/* inline/static */
-static
-#ifdef G_CAN_INLINE
-inline
-#endif
-void printformat(void *server, const char *channel, int level, int formatnum, ...)
-{
- printformat_format(MODULE_FORMATS, server, channel, level, formatnum);
-}
-#endif
diff --git a/src/fe-common/core/printtext.c b/src/fe-common/core/printtext.c
index 7152e910..c499388f 100644
--- a/src/fe-common/core/printtext.c
+++ b/src/fe-common/core/printtext.c
@@ -33,251 +33,242 @@
#include "themes.h"
#include "windows.h"
-static gboolean timestamps, msgs_timestamps, hide_text_style;
-static gint printtag;
-static gchar ansitab[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+typedef struct {
+ WINDOW_REC *window;
+ void *server;
+ const char *channel;
+ int level;
+} TEXT_DEST_REC;
-static gint signal_gui_print_text;
-static gint signal_print_text_stripped;
-static gint signal_print_text;
-static gint signal_print_text_finished;
+static int timestamps, msgs_timestamps, hide_text_style;
+static int timestamp_timeout;
+
+static int signal_gui_print_text;
+static int signal_print_text_stripped;
+static int signal_print_text;
+static int signal_print_text_finished;
+
+static void print_string(TEXT_DEST_REC *dest, const char *text);
void printbeep(void)
{
- signal_emit_id(signal_gui_print_text, 6, active_win, NULL, NULL,
- GINT_TO_POINTER(PRINTFLAG_BEEP), "", MSGLEVEL_NEVER);
+ signal_emit_id(signal_gui_print_text, 6, active_win, NULL, NULL,
+ GINT_TO_POINTER(PRINTFLAG_BEEP), "", MSGLEVEL_NEVER);
}
-/* parse ANSI color string */
-static char *convert_ansi(char *str, int *fgcolor, int *bgcolor, int *flags)
+static void skip_mirc_color(char **str)
{
- gchar *start;
- gint fg, bg, fl, num;
+ if (!isdigit((int) **str))
+ return;
- if (*str != '[') return str;
+ /* foreground */
+ (*str)++;
+ if (isdigit((int) **str)) (*str)++;
- start = str;
+ if (**str != ',' || !isdigit((int) (*str)[1])) return;
- fg = *fgcolor < 0 ? current_theme->default_color : *fgcolor;
- bg = *bgcolor < 0 ? -1 : *bgcolor;
- fl = *flags;
+ /* background */
+ (*str) += 2;
+ if (isdigit((int) **str)) (*str)++;
+}
- str++; num = 0;
- for (;; str++)
- {
- if (*str == '\0') return start;
+#define is_color_code(c) \
+ ((c) == 2 || (c) == 3 || (c) == 4 || (c) == 6 || (c) == 7 || \
+ (c) == 15 || (c) == 22 || (c) == 27 || (c) == 31)
- if (isdigit((gint) *str))
- {
- num = num*10 + (*str-'0');
- continue;
- }
+char *strip_codes(const char *input)
+{
+ const char *p;
+ char *str, *out;
+
+ out = str = g_strdup(input);
+ for (p = input; *p != '\0'; p++) {
+ if (*p == 3) {
+ p++;
+
+ if (*p < 17 && *p > 0) {
+ /* irssi color */
+ if (p[1] < 17 && p[1] > 0) p++;
+ continue;
+ }
- if (*str != ';' && *str != 'm') return start;
+ /* mirc color */
+ skip_mirc_color((char **) &p);
+ p--;
+ continue;
+ }
- switch (num)
- {
- case 0:
- /* reset colors back to default */
- fg = current_theme->default_color;
- bg = -1;
- break;
- case 1:
- /* hilight */
- fg |= 8;
- break;
- case 5:
- /* blink */
- bg = bg == -1 ? 8 : bg | 8;
- break;
- case 7:
- /* reverse */
- fl |= PRINTFLAG_REVERSE;
- break;
- default:
- if (num >= 30 && num <= 37)
- fg = (fg & 0xf8) + ansitab[num-30];
- if (num >= 40 && num <= 47)
- {
- if (bg == -1) bg = 0;
- bg = (bg & 0xf8) + ansitab[num-40];
- }
- break;
- }
- num = 0;
+ if (*p == 4 && p[1] != '\0' && p[2] != '\0') {
+ /* irssi color */
+ p += 2;
+ continue;
+ }
- if (*str == 'm')
- {
- if (!hide_text_style)
- {
- *fgcolor = fg;
- *bgcolor = bg == -1 ? -1 : bg;
- *flags = fl;
- }
- str++;
- break;
- }
- }
+ if (!is_color_code(*p))
+ *out++ = *p;
+ }
- return str;
+ *out = '\0';
+ return str;
}
-#define IN_COLOR_CODE 2
-#define IN_SECOND_CODE 4
-char *strip_codes(const char *input)
+/* parse ANSI color string */
+static char *convert_ansi(char *str, int *fgcolor, int *bgcolor, int *flags)
{
- const char *p;
- gchar *str, *out;
- gint loop_state;
+ static char ansitab[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+ char *start;
+ int fg, bg, fl, num;
- loop_state = 0;
- out = str = g_strdup(input);
- for (p = input; *p != '\0'; p++) /* Going through the string till the end k? */
- {
- if (*p == '\003')
- {
- if (p[1] < 17 && p[1] > 0)
- {
- p++;
- if (p[1] < 17 && p[1] > 0) p++;
- continue;
- }
- loop_state = IN_COLOR_CODE;
- continue;
- }
+ if (*str != '[')
+ return str;
+ start = str++;
- if (loop_state & IN_COLOR_CODE)
- {
- if (isdigit( (gint) *p )) continue;
- if (*p != ',' || (loop_state & IN_SECOND_CODE))
- {
- /* we're no longer in a color code */
- *out++ = *p;
- loop_state &= ~IN_COLOR_CODE|IN_SECOND_CODE;
- continue;
- }
+ fg = *fgcolor < 0 ? current_theme->default_color : *fgcolor;
+ bg = *bgcolor < 0 ? -1 : *bgcolor;
+ fl = *flags;
- /* we're in the second code */
- loop_state |= IN_SECOND_CODE;
- continue;
+ num = 0;
+ for (;; str++) {
+ if (*str == '\0') return start;
- }
+ if (isdigit((int) *str)) {
+ num = num*10 + (*str-'0');
+ continue;
+ }
- /* we're not in a color code that means we should add the character */
- if (*p == 4 && p[1] != '\0' && p[2] != '\0')
- {
- p += 2;
- continue;
- }
+ if (*str != ';' && *str != 'm')
+ return start;
- if (*p == 2 || *p == 22 || *p == 27 || *p == 31 || *p == 15)
- continue;
- *out++ = *p;
- }
+ switch (num) {
+ case 0:
+ /* reset colors back to default */
+ fg = current_theme->default_color;
+ bg = -1;
+ break;
+ case 1:
+ /* hilight */
+ fg |= 8;
+ break;
+ case 5:
+ /* blink */
+ bg = bg == -1 ? 8 : bg | 8;
+ break;
+ case 7:
+ /* reverse */
+ fl |= PRINTFLAG_REVERSE;
+ break;
+ default:
+ if (num >= 30 && num <= 37)
+ fg = (fg & 0xf8) + ansitab[num-30];
+ if (num >= 40 && num <= 47) {
+ if (bg == -1) bg = 0;
+ bg = (bg & 0xf8) + ansitab[num-40];
+ }
+ break;
+ }
+ num = 0;
+
+ if (*str == 'm') {
+ if (!hide_text_style) {
+ *fgcolor = fg;
+ *bgcolor = bg == -1 ? -1 : bg;
+ *flags = fl;
+ }
+ str++;
+ break;
+ }
+ }
- *out = '\0';
- return str;
+ return str;
}
-static gboolean expand_styles(GString *out, char format, void *server, const char *channel, int level)
+static int expand_styles(GString *out, char format, TEXT_DEST_REC *dest)
{
- static const char *backs = "01234567";
- static const char *fores = "krgybmcw";
- static const char *boldfores = "KRGYBMCW";
- gchar *p;
-
- /* p/P -> m/M */
- if (format == 'p')
- format = 'm';
- else if (format == 'P')
- format = 'M';
-
- switch (format)
- {
- case 'U':
- /* Underline on/off */
- g_string_append_c(out, 4);
- g_string_append_c(out, -1);
- g_string_append_c(out, 2);
- break;
+ static const char *backs = "04261537";
+ static const char *fores = "kbgcrmyw";
+ static const char *boldfores = "KBGCRMYW";
+ char *p;
+
+ switch (format) {
+ case 'U':
+ /* Underline on/off */
+ g_string_append_c(out, 4);
+ g_string_append_c(out, -1);
+ g_string_append_c(out, 2);
+ break;
case '9':
case '_':
- /* bold on/off */
- g_string_append_c(out, 4);
- g_string_append_c(out, -1);
- g_string_append_c(out, 1);
- break;
+ /* bold on/off */
+ g_string_append_c(out, 4);
+ g_string_append_c(out, -1);
+ g_string_append_c(out, 1);
+ break;
case '8':
- /* reverse */
- g_string_append_c(out, 4);
- g_string_append_c(out, -1);
- g_string_append_c(out, 3);
- break;
+ /* reverse */
+ g_string_append_c(out, 4);
+ g_string_append_c(out, -1);
+ g_string_append_c(out, 3);
+ break;
case '%':
- g_string_append_c(out, '%');
- break;
+ g_string_append_c(out, '%');
+ break;
case ':':
- /* Newline */
- printtext(server, channel, level, out->str);
- g_string_truncate(out, 0);
- break;
-
+ /* Newline */
+ print_string(dest, out->str);
+ g_string_truncate(out, 0);
+ break;
case '|':
- /* Indent here mark */
- g_string_append_c(out, 4);
- g_string_append_c(out, -1);
- g_string_append_c(out, 4);
- break;
-
+ /* Indent here */
+ g_string_append_c(out, 4);
+ g_string_append_c(out, -1);
+ g_string_append_c(out, 4);
+ break;
case 'F':
- /* flashing - ignore */
- break;
-
+ /* flashing - ignore */
+ break;
case 'N':
- /* don't put clear-color tag at the end of the output - ignore */
- break;
-
+ /* don't put clear-color tag at the end of the output - ignore */
+ break;
case 'n':
- /* default color */
- g_string_append_c(out, 4);
- g_string_append_c(out, -1);
- g_string_append_c(out, -1);
- break;
-
- default:
- /* check if it's a background color */
- p = strchr(backs, format);
- if (p != NULL)
- {
+ /* default color */
g_string_append_c(out, 4);
- g_string_append_c(out, -2);
- g_string_append_c(out, ansitab[(gint) (p-backs)]+1);
+ g_string_append_c(out, -1);
+ g_string_append_c(out, -1);
break;
- }
+ default:
+ /* check if it's a background color */
+ p = strchr(backs, format);
+ if (p != NULL) {
+ g_string_append_c(out, 4);
+ g_string_append_c(out, -2);
+ g_string_append_c(out, (int) (p-backs)+1);
+ break;
+ }
- /* check if it's a foreground color */
- p = strchr(fores, format);
- if (p != NULL)
- {
- g_string_append_c(out, 4);
- g_string_append_c(out, ansitab[(gint) (p-fores)]+1);
- g_string_append_c(out, -2);
- break;
- }
+ /* check if it's a foreground color */
+ if (format == 'p') format = 'm';
+ p = strchr(fores, format);
+ if (p != NULL) {
+ g_string_append_c(out, 4);
+ g_string_append_c(out, (int) (p-fores)+1);
+ g_string_append_c(out, -2);
+ break;
+ }
- /* check if it's a bold foreground color */
- p = strchr(boldfores, format);
- if (p != NULL)
- {
- g_string_append_c(out, 4);
- g_string_append_c(out, 8+ansitab[(gint) (p-boldfores)]+1);
- g_string_append_c(out, -2);
- break;
- }
- return FALSE;
- }
+ /* check if it's a bold foreground color */
+ if (format == 'P') format = 'M';
+ p = strchr(boldfores, format);
+ if (p != NULL) {
+ g_string_append_c(out, 4);
+ g_string_append_c(out, 8+(int) (p-boldfores)+1);
+ g_string_append_c(out, -2);
+ break;
+ }
+
+ return FALSE;
+ }
- return TRUE;
+ return TRUE;
}
static void read_arglist(va_list va, FORMAT_REC *format,
@@ -287,12 +278,13 @@ static void read_arglist(va_list va, FORMAT_REC *format,
int num, len, bufpos;
bufpos = 0;
+ arglist[format->params] = NULL;
for (num = 0; num < format->params && num < arglist_size; num++) {
switch (format->paramtypes[num]) {
case FORMAT_STRING:
arglist[num] = (char *) va_arg(va, char *);
if (arglist[num] == NULL) {
- g_warning("output_format_text_args() : parameter %d is NULL", num);
+ g_warning("read_arglist() : parameter %d is NULL", num);
arglist[num] = "";
}
break;
@@ -342,28 +334,32 @@ static void read_arglist(va_list va, FORMAT_REC *format,
}
}
-static void output_format_text_args(GString *out, void *server, const char *channel, int level, FORMAT_REC *format, const char *text, va_list args)
+static char *output_format_text_args(TEXT_DEST_REC *dest, FORMAT_REC *format, const char *text, va_list args)
{
+ GString *out;
char *arglist[10];
char buffer[200]; /* should be enough? (won't overflow even if it isn't) */
const char *str;
- char code;
+ char code, *ret;
int need_free;
str = current_theme != NULL && text != NULL ? text : format->def;
/* read all optional arguments to arglist[] list
so they can be used in any order.. */
+ memset(arglist, 0, sizeof(arglist)); /*REMOVE!!!!!!!*/
read_arglist(args, format,
arglist, sizeof(arglist)/sizeof(void*),
buffer, sizeof(buffer));
+ out = g_string_new(NULL);
+
code = 0;
while (*str != '\0') {
if (code == '%') {
/* color code */
- if (!expand_styles(out, *str, server, channel, level)) {
+ if (!expand_styles(out, *str, dest)) {
g_string_append_c(out, '%');
g_string_append_c(out, '%');
g_string_append_c(out, *str);
@@ -373,7 +369,8 @@ static void output_format_text_args(GString *out, void *server, const char *chan
/* argument */
char *ret;
- ret = parse_special((char **) &str, active_win->active_server, active_win->active, arglist, &need_free, NULL);
+ ret = parse_special((char **) &str, active_win->active_server,
+ active_win->active, arglist, &need_free, NULL);
if (ret != NULL) {
g_string_append(out, ret);
if (need_free) g_free(ret);
@@ -388,165 +385,233 @@ static void output_format_text_args(GString *out, void *server, const char *chan
str++;
}
+
+ ret = out->str;
+ g_string_free(out, FALSE);
+ return ret;
}
-static void output_format_text(GString *out, void *server, const char *channel, int level, int formatnum, ...)
+static char *output_format_text(TEXT_DEST_REC *dest, int formatnum, ...)
{
MODULE_THEME_REC *theme;
va_list args;
+ char *ret;
- theme = g_hash_table_lookup(current_theme->modules, MODULE_FORMATS->tag);
+ theme = g_hash_table_lookup(current_theme->modules, MODULE_NAME);
va_start(args, formatnum);
- output_format_text_args(out, server, channel, level,
- &MODULE_FORMATS[formatnum],
- theme == NULL ? NULL : theme->format[formatnum], args);
+ ret = output_format_text_args(dest, &fecommon_core_formats[formatnum],
+ theme == NULL ? NULL : theme->formats[formatnum], args);
va_end(args);
+
+ return ret;
}
-static void add_timestamp(WINDOW_REC *window, GString *out, void *server, const char *channel, int level)
+void printformat_module_args(const char *module, void *server, const char *channel, int level, int formatnum, va_list va)
{
- time_t t;
- struct tm *tm;
- GString *tmp;
+ MODULE_THEME_REC *theme;
+ TEXT_DEST_REC dest;
+ FORMAT_REC *formats;
+ char *str;
- if (!(level != MSGLEVEL_NEVER && (timestamps || (msgs_timestamps && (level & MSGLEVEL_MSGS) != 0))))
- return;
+ dest.window = NULL;
+ dest.server = server;
+ dest.channel = channel;
+ dest.level = level;
- t = time(NULL);
+ theme = g_hash_table_lookup(current_theme->modules, module);
+ formats = g_hash_table_lookup(default_formats, module);
- if ((t - window->last_timestamp) < settings_get_int("timestamp_timeout")) {
- window->last_timestamp = t;
- return;
- }
- window->last_timestamp = t;
+ str = output_format_text_args(&dest, &formats[formatnum],
+ theme == NULL ? NULL : theme->formats[formatnum], va);
+ if (*str != '\0') print_string(&dest, str);
+ g_free(str);
+}
- tmp = g_string_new(NULL);
- tm = localtime(&t);
- output_format_text(tmp, server, channel, level, IRCTXT_TIMESTAMP,
- tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
+void printformat_module(const char *module, void *server, const char *channel, int level, int formatnum, ...)
+{
+ va_list va;
- /* insert the timestamp right after \n */
- g_string_prepend(out, tmp->str);
- g_string_free(tmp, TRUE);
+ va_start(va, formatnum);
+ printformat_module_args(module, server, channel, level, formatnum, va);
+ va_end(va);
}
-static void new_line_stuff(GString *out, void *server, const char *channel, int level)
+void printformat_module_window_args(const char *module, WINDOW_REC *window, int level, int formatnum, va_list va)
{
- if ((level & (MSGLEVEL_CLIENTERROR|MSGLEVEL_CLIENTNOTICE)) != 0)
- output_format_text(out, server, channel, level, IRCTXT_LINE_START_IRSSI);
- else if ((level & (MSGLEVEL_MSGS|MSGLEVEL_PUBLIC|MSGLEVEL_NOTICES|MSGLEVEL_SNOTES|MSGLEVEL_CTCPS|MSGLEVEL_ACTIONS|MSGLEVEL_DCC|MSGLEVEL_CLIENTCRAP)) == 0 && level != MSGLEVEL_NEVER)
- output_format_text(out, server, channel, level, IRCTXT_LINE_START);
+ MODULE_THEME_REC *theme;
+ TEXT_DEST_REC dest;
+ FORMAT_REC *formats;
+ char *str;
+
+ dest.window = window;
+ dest.server = NULL;
+ dest.channel = NULL;
+ dest.level = level;
+
+ theme = g_hash_table_lookup(current_theme->modules, module);
+ formats = g_hash_table_lookup(default_formats, module);
+
+ str = output_format_text_args(&dest, &formats[formatnum],
+ theme == NULL ? NULL : theme->formats[formatnum], va);
+ if (*str != '\0') print_string(&dest, str);
+ g_free(str);
}
-/* Write text to channel - convert color codes */
-void printtext(void *server, const char *channel, int level, const char *str, ...)
+void printformat_module_window(const char *module, WINDOW_REC *window, int level, int formatnum, ...)
+{
+ va_list va;
+
+ va_start(va, formatnum);
+ printformat_module_window_args(module, window, level, formatnum, va);
+ va_end(va);
+}
+
+/* return the "-!- " text at the start of the line */
+static char *get_line_start_text(TEXT_DEST_REC *dest)
{
- va_list args;
- GString *out;
- gchar *tmpstr;
- gint pros;
+ if ((dest->level & (MSGLEVEL_CLIENTERROR|MSGLEVEL_CLIENTNOTICE)) != 0)
+ return output_format_text(dest, IRCTXT_LINE_START_IRSSI);
- g_return_if_fail(str != NULL);
+ if ((dest->level & (MSGLEVEL_MSGS|MSGLEVEL_PUBLIC|MSGLEVEL_NOTICES|MSGLEVEL_SNOTES|MSGLEVEL_CTCPS|MSGLEVEL_ACTIONS|MSGLEVEL_DCC|MSGLEVEL_CLIENTCRAP)) == 0 && dest->level != MSGLEVEL_NEVER)
+ return output_format_text(dest, IRCTXT_LINE_START);
- va_start(args, str);
+ return NULL;
+}
- pros = 0;
- out = g_string_new(NULL);
+static void print_string(TEXT_DEST_REC *dest, const char *text)
+{
+ gpointer levelp;
+ char *str, *tmp;
- new_line_stuff(out, server, channel, level);
- for (; *str != '\0'; str++)
- {
- if (*str != '%')
- {
- g_string_append_c(out, *str);
- continue;
- }
+ g_return_if_fail(dest != NULL);
+ g_return_if_fail(text != NULL);
- if (*++str == '\0') break;
- switch (*str)
- {
- /* standard parameters */
- case 's':
- {
- gchar *s = (gchar *) va_arg(args, gchar *);
- if (s && *s) g_string_append(out, s);
- break;
- }
- case 'd':
- {
- gint d = (gint) va_arg(args, gint);
- g_string_sprintfa(out, "%d", d);
- break;
- }
- case 'f':
- {
- gdouble f = (gdouble) va_arg(args, gdouble);
- g_string_sprintfa(out, "%0.2f", f);
- break;
- }
- case 'u':
- {
- guint d = (guint) va_arg(args, guint);
- g_string_sprintfa(out, "%u", d);
- break;
- }
- case 'l':
- {
- gulong d = (gulong) va_arg(args, gulong);
- if (*++str != 'd' && *str != 'u')
- {
- g_string_sprintfa(out, "%ld", d);
- str--;
- }
- else
- {
- if (*str == 'd')
- g_string_sprintfa(out, "%ld", d);
- else
- g_string_sprintfa(out, "%lu", d);
- }
- break;
- }
- default:
- if (!expand_styles(out, *str, server, channel, level))
- {
- g_string_append_c(out, '%');
- g_string_append_c(out, *str);
- }
- break;
- }
- }
- va_end(args);
+ if (dest->window == NULL)
+ dest->window = window_find_closest(dest->server, dest->channel, dest->level);
+
+ tmp = get_line_start_text(dest);
+ str = tmp == NULL ? (char *) text :
+ g_strconcat(tmp, text, NULL);
+ g_free_not_null(tmp);
- /* send the plain text version for logging.. */
- tmpstr = strip_codes(out->str);
- signal_emit_id(signal_print_text_stripped, 4, server, channel, GINT_TO_POINTER(level), tmpstr);
- g_free(tmpstr);
+ levelp = GINT_TO_POINTER(dest->level);
- signal_emit_id(signal_print_text, 4, server, channel, GINT_TO_POINTER(level), out->str);
+ /* send the plain text version for logging etc.. */
+ tmp = strip_codes(str);
+ signal_emit_id(signal_print_text_stripped, 5, dest->window, dest->server, dest->channel, levelp, tmp);
+ g_free(tmp);
- g_string_free(out, TRUE);
+ signal_emit_id(signal_print_text, 5, dest->window, dest->server, dest->channel, levelp, str);
+ if (str != text) g_free(str);
}
-void printformat_format(FORMAT_REC *formats, void *server, const char *channel, int level, int formatnum, ...)
+static char *printtext_get_args(TEXT_DEST_REC *dest, const char *str, va_list va)
{
- MODULE_THEME_REC *theme;
GString *out;
- va_list args;
+ char *ret;
- va_start(args, formatnum);
out = g_string_new(NULL);
+ for (; *str != '\0'; str++) {
+ if (*str != '%') {
+ g_string_append_c(out, *str);
+ continue;
+ }
- theme = g_hash_table_lookup(current_theme->modules, formats->tag);
+ if (*++str == '\0')
+ break;
- output_format_text_args(out, server, channel, level,
- &formats[formatnum],
- theme == NULL ? NULL : theme->format[formatnum], args);
- if (out->len > 0) printtext(server, channel, level, "%s", out->str);
+ /* standard parameters */
+ switch (*str) {
+ case 's': {
+ char *s = (char *) va_arg(va, char *);
+ if (s && *s) g_string_append(out, s);
+ break;
+ }
+ case 'd': {
+ int d = (int) va_arg(va, int);
+ g_string_sprintfa(out, "%d", d);
+ break;
+ }
+ case 'f': {
+ double f = (double) va_arg(va, double);
+ g_string_sprintfa(out, "%0.2f", f);
+ break;
+ }
+ case 'u': {
+ unsigned int d = (unsigned int) va_arg(va, unsigned int);
+ g_string_sprintfa(out, "%u", d);
+ break;
+ }
+ case 'l': {
+ long d = (long) va_arg(va, long);
+
+ if (*++str != 'd' && *str != 'u') {
+ g_string_sprintfa(out, "%ld", d);
+ str--;
+ } else {
+ if (*str == 'd')
+ g_string_sprintfa(out, "%ld", d);
+ else
+ g_string_sprintfa(out, "%lu", d);
+ }
+ break;
+ }
+ default:
+ if (!expand_styles(out, *str, dest)) {
+ g_string_append_c(out, '%');
+ g_string_append_c(out, *str);
+ }
+ break;
+ }
+ }
- g_string_free(out, TRUE);
- va_end(args);
+ ret = out->str;
+ g_string_free(out, FALSE);
+ return ret;
+}
+
+/* Write text to channel - convert color codes */
+void printtext(void *server, const char *channel, int level, const char *text, ...)
+{
+ TEXT_DEST_REC dest;
+ char *str;
+ va_list va;
+
+ g_return_if_fail(text != NULL);
+
+ dest.window = NULL;
+ dest.server = server;
+ dest.channel = channel;
+ dest.level = level;
+
+ va_start(va, text);
+ str = printtext_get_args(&dest, text, va);
+ va_end(va);
+
+ print_string(&dest, str);
+ g_free(str);
+}
+
+void printtext_window(WINDOW_REC *window, int level, const char *text, ...)
+{
+ TEXT_DEST_REC dest;
+ char *str;
+ va_list va;
+
+ g_return_if_fail(text != NULL);
+
+ dest.window = window != NULL ? window : active_win;
+ dest.server = NULL;
+ dest.channel = NULL;
+ dest.level = level;
+
+ va_start(va, text);
+ str = printtext_get_args(&dest, text, va);
+ va_end(va);
+
+ print_string(&dest, str);
+ g_free(str);
}
static void newline(WINDOW_REC *window)
@@ -559,48 +624,74 @@ static void newline(WINDOW_REC *window)
}
}
-static void sig_print_text(void *server, const char *target, gpointer level, const char *text)
+#define show_timestamp(level) \
+ ((level) != MSGLEVEL_NEVER && \
+ (timestamps || (msgs_timestamps && ((level) & MSGLEVEL_MSGS))))
+
+static char *get_timestamp(TEXT_DEST_REC *dest)
{
- WINDOW_REC *window;
- GString *out;
- gchar *dup, *ptr, type, *str;
+ struct tm *tm;
+ time_t t;
+ int diff;
+
+ if (!show_timestamp(dest->level))
+ return NULL;
+
+ t = time(NULL);
+
+ diff = t - dest->window->last_timestamp;
+ dest->window->last_timestamp = t;
+ if (diff < timestamp_timeout)
+ return NULL;
+
+ tm = localtime(&t);
+ return output_format_text(dest, IRCTXT_TIMESTAMP,
+ tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+}
+
+static char *get_server_tag(WINDOW_REC *window, SERVER_REC *server)
+{
+ if (server == NULL || servers == NULL || servers->next == NULL ||
+ (window->active != NULL && window->active->server == server))
+ return NULL;
+
+ return g_strdup_printf("[%s] ", server->tag);
+}
+
+static void sig_print_text(WINDOW_REC *window, SERVER_REC *server, const char *target, gpointer level, const char *text)
+{
+ TEXT_DEST_REC dest;
+ gchar *dup, *ptr, type, *str, *timestamp, *servertag;
gint fgcolor, bgcolor;
gint flags;
g_return_if_fail(text != NULL);
-
- window = window_find_closest(server, target, GPOINTER_TO_INT(level));
g_return_if_fail(window != NULL);
- flags = 0; fgcolor = -1; bgcolor = -1; type = '\0';
+ dest.window = window;
+ dest.server = server;
+ dest.channel = target;
+ dest.level = GPOINTER_TO_INT(level);
+ flags = 0; fgcolor = -1; bgcolor = -1; type = '\0';
window->last_line = time(NULL);
newline(window);
- out = g_string_new(text);
- if (server != NULL && servers != NULL && servers->next != NULL &&
- (window->active == NULL || window->active->server != server))
- {
- /* connected to more than one server and active server isn't the
- same where the message came or we're in status/msgs/empty window -
- prefix with a [server tag] */
- gchar *str;
-
- str = g_strdup_printf("[%s] ", ((SERVER_REC *) server)->tag);
- g_string_prepend(out, str);
- g_free(str);
- }
-
- add_timestamp(window, out, server, target, GPOINTER_TO_INT(level));
-
- dup = str = out->str;
- g_string_free(out, FALSE);
+ timestamp = get_timestamp(&dest);
+ servertag = get_server_tag(window, server);
+ str = g_strconcat(timestamp != NULL ? timestamp : "",
+ servertag != NULL ? servertag : "",
+ text, NULL);
+ g_free_not_null(timestamp);
+ g_free_not_null(servertag);
+ dup = str;
while (*str != '\0')
{
for (ptr = str; *ptr != '\0'; ptr++)
{
- if (*ptr == 2 || *ptr == 3 || *ptr == 4 || *ptr == 6 || *ptr == 7 || *ptr == 15 || *ptr == 22 || *ptr == 27 || *ptr == 31)
+ if (is_color_code(*ptr))
{
type = *ptr;
*ptr++ = '\0';
@@ -715,20 +806,7 @@ static void sig_print_text(void *server, const char *target, gpointer level, con
if (hide_text_style)
{
/* don't show them. */
- if (isdigit((gint) *ptr))
- {
- ptr++;
- if (isdigit((gint) *ptr)) ptr++;
- if (*ptr == ',')
- {
- ptr++;
- if (isdigit((gint) *ptr))
- {
- ptr++;
- if (isdigit((gint) *ptr)) ptr++;
- }
- }
- }
+ skip_mirc_color(&ptr);
break;
}
@@ -770,47 +848,6 @@ static void sig_print_text(void *server, const char *target, gpointer level, con
signal_emit_id(signal_print_text_finished, 1, window);
}
-static int sig_check_daychange(void)
-{
- static gint lastday = -1;
- GSList *tmp;
- time_t t;
- struct tm *tm;
-
- if (!timestamps)
- {
- /* display day change notice only when using timestamps */
- return TRUE;
- }
-
- t = time(NULL);
- tm = localtime(&t);
-
- if (lastday == -1)
- {
- /* First check, don't display. */
- lastday = tm->tm_mday;
- return TRUE;
- }
-
- if (tm->tm_mday == lastday)
- return TRUE;
-
- /* day changed, print notice about it to every window */
- for (tmp = windows; tmp != NULL; tmp = tmp->next)
- {
- 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);
- }
- lastday = tm->tm_mday;
- return TRUE;
-}
-
void printtext_multiline(void *server, const char *channel, int level, const char *format, const char *text)
{
char **lines, **tmp;
@@ -837,31 +874,30 @@ static void sig_gui_dialog(const char *type, const char *text)
static void read_settings(void)
{
- timestamps = settings_get_bool("timestamps");
- msgs_timestamps = settings_get_bool("msgs_timestamps");
- hide_text_style = settings_get_bool("hide_text_style");
+ timestamps = settings_get_bool("timestamps");
+ timestamp_timeout = settings_get_bool("timestamp_timeout");
+ msgs_timestamps = settings_get_bool("msgs_timestamps");
+ hide_text_style = settings_get_bool("hide_text_style");
}
void printtext_init(void)
{
- settings_add_int("misc", "timestamp_timeout", 0);
-
- signal_gui_print_text = module_get_uniq_id_str("signals", "gui print text");
- signal_print_text_stripped = module_get_uniq_id_str("signals", "print text stripped");
- signal_print_text = module_get_uniq_id_str("signals", "print text");
- signal_print_text_finished = module_get_uniq_id_str("signals", "print text finished");
-
- read_settings();
- printtag = g_timeout_add(30000, (GSourceFunc) sig_check_daychange, NULL);
- 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);
+ settings_add_int("misc", "timestamp_timeout", 0);
+
+ signal_gui_print_text = module_get_uniq_id_str("signals", "gui print text");
+ signal_print_text_stripped = module_get_uniq_id_str("signals", "print text stripped");
+ signal_print_text = module_get_uniq_id_str("signals", "print text");
+ signal_print_text_finished = module_get_uniq_id_str("signals", "print text finished");
+
+ read_settings();
+ 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);
}
void printtext_deinit(void)
{
- g_source_remove(printtag);
- 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);
+ 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);
}
diff --git a/src/fe-common/core/printtext.h b/src/fe-common/core/printtext.h
index acd6a03e..71c5d88e 100644
--- a/src/fe-common/core/printtext.h
+++ b/src/fe-common/core/printtext.h
@@ -1,6 +1,8 @@
#ifndef __PRINTTEXT_H
#define __PRINTTEXT_H
+#include "windows.h"
+
enum {
FORMAT_STRING,
FORMAT_INT,
@@ -24,9 +26,14 @@ typedef struct {
#define PRINTFLAG_MIRC_COLOR 0x20
#define PRINTFLAG_INDENT 0x40
-void printformat_format(FORMAT_REC *formats, void *server, const char *channel, int level, int formatnum, ...);
+void printformat_module(const char *module, void *server, const char *channel, int level, int formatnum, ...);
+void printformat_module_window(const char *module, WINDOW_REC *window, int level, int formatnum, ...);
+
+void printformat_module_args(const char *module, void *server, const char *channel, int level, int formatnum, va_list va);
+void printformat_module_window_args(const char *module, WINDOW_REC *window, int level, int formatnum, va_list va);
-void printtext(void *server, const char *channel, int level, const char *str, ...);
+void printtext(void *server, const char *channel, int level, const char *text, ...);
+void printtext_window(WINDOW_REC *window, int level, const char *text, ...);
void printtext_multiline(void *server, const char *channel, int level, const char *format, const char *text);
void printbeep(void);
@@ -36,4 +43,51 @@ char *strip_codes(const char *input);
void printtext_init(void);
void printtext_deinit(void);
+/* printformat(...) = printformat_format(MODULE_NAME, ...)
+
+ Could this be any harder? :) With GNU C compiler and C99 compilers,
+ use #define. With others use either inline functions if they are
+ supported or static functions if they are not..
+ */
+#if defined (__GNUC__) && !defined (__STRICT_ANSI__)
+/* GCC */
+# define printformat(server, channel, level, formatnum...) \
+ printformat_module(MODULE_NAME, server, channel, level, ##formatnum)
+# define printformat_window(window, level, formatnum...) \
+ printformat_module_window(MODULE_NAME, window, level, ##formatnum)
+#elif defined (_ISOC99_SOURCE)
+/* C99 */
+# define printformat(server, channel, level, formatnum, ...) \
+ printformat_module(MODULE_NAME, server, channel, level, formatnum, __VA_ARGS__)
+# define printformat_window(window, level, formatnum, ...) \
+ printformat_module_window(MODULE_NAME, window, level, formatnum, __VA_ARGS__)
+#else
+/* inline/static */
+static
+#ifdef G_CAN_INLINE
+inline
+#endif
+void printformat(void *server, const char *channel, int level, int formatnum, ...)
+{
+ va_list va;
+
+ va_start(va, formatnum);
+ printformat_module_args(MODULE_NAME, server, channel, level, formatnum, va);
+ va_end(va);
+}
+
+static
+#ifdef G_CAN_INLINE
+inline
+#endif
+void printformat_window(WINDOW_REC *window, int level, int formatnum, ...)
+{
+ va_list va;
+
+ va_start(va, formatnum);
+ printformat_module_window_args(MODULE_NAME, window, level, formatnum, va);
+ va_end(va);
+}
+#endif
+
#endif
diff --git a/src/fe-common/core/themes.c b/src/fe-common/core/themes.c
index 0d9735ab..879f558c 100644
--- a/src/fe-common/core/themes.c
+++ b/src/fe-common/core/themes.c
@@ -20,6 +20,8 @@
#include "module.h"
#include "signals.h"
+#include "commands.h"
+#include "levels.h"
#include "misc.h"
#include "lib-config/iconfig.h"
#include "settings.h"
@@ -29,6 +31,7 @@
GSList *themes;
THEME_REC *current_theme;
+GHashTable *default_formats;
THEME_REC *theme_create(const char *path, const char *name)
{
@@ -46,17 +49,15 @@ THEME_REC *theme_create(const char *path, const char *name)
return rec;
}
-static void theme_destroy_hash(const char *key, MODULE_THEME_REC *rec)
+static void theme_module_destroy(const char *key, MODULE_THEME_REC *rec)
{
- int n, max;
+ int n;
- max = strarray_length(rec->formatlist);
- for (n = 0; n < max; n++)
- if (rec->format[n] != NULL)
- g_free(rec->format[n]);
- g_free(rec->format);
+ for (n = 0; n < rec->count; n++)
+ if (rec->formats[n] != NULL)
+ g_free(rec->formats[n]);
+ g_free(rec->formats);
- g_strfreev(rec->formatlist);
g_free(rec->name);
g_free(rec);
}
@@ -64,7 +65,7 @@ static void theme_destroy_hash(const char *key, MODULE_THEME_REC *rec)
void theme_destroy(THEME_REC *rec)
{
signal_emit("theme destroyed", 1, rec);
- g_hash_table_foreach(rec->modules, (GHFunc) theme_destroy_hash, NULL);
+ g_hash_table_foreach(rec->modules, (GHFunc) theme_module_destroy, NULL);
g_hash_table_destroy(rec->modules);
if (rec->bg_pixmap != NULL) g_free(rec->bg_pixmap);
@@ -74,6 +75,119 @@ void theme_destroy(THEME_REC *rec)
g_free(rec);
}
+static MODULE_THEME_REC *theme_module_create(THEME_REC *theme, const char *module)
+{
+ MODULE_THEME_REC *rec;
+ FORMAT_REC *formats;
+
+ rec = g_hash_table_lookup(theme->modules, module);
+ if (rec != NULL) return rec;
+
+ formats = g_hash_table_lookup(default_formats, module);
+ g_return_val_if_fail(formats != NULL, NULL);
+
+ rec = g_new0(MODULE_THEME_REC, 1);
+ rec->name = g_strdup(module);
+
+ for (rec->count = 0; formats[rec->count].def != NULL; rec->count++) ;
+ rec->formats = g_new0(char *, rec->count);
+
+ g_hash_table_insert(theme->modules, rec->name, rec);
+ return rec;
+}
+
+static void theme_read_formats(CONFIG_REC *config, THEME_REC *theme, const char *module)
+{
+ MODULE_THEME_REC *rec;
+ FORMAT_REC *formats;
+ CONFIG_NODE *node;
+ GSList *tmp;
+ int n;
+
+ formats = g_hash_table_lookup(default_formats, module);
+ if (formats == NULL) return;
+
+ node = config_node_traverse(config, "formats", FALSE);
+ if (node == NULL) return;
+ node = config_node_section(node, module, -1);
+ if (node == NULL) return;
+
+ rec = theme_module_create(theme, module);
+
+ for (tmp = node->value; tmp != NULL; tmp = tmp->next) {
+ node = tmp->data;
+
+ if (node->key == NULL || node->value == NULL)
+ continue;
+
+ for (n = 0; formats[n].def != NULL; n++) {
+ if (formats[n].tag != NULL &&
+ g_strcasecmp(formats[n].tag, node->key) == 0) {
+ rec->formats[n] = g_strdup(node->value);
+ break;
+ }
+ }
+ }
+}
+
+static void theme_read_module(THEME_REC *theme, const char *module)
+{
+ CONFIG_REC *config;
+ char *msg;
+
+ config = config_open(theme->path, -1);
+ if (config == NULL) return;
+
+ config_parse(config);
+
+ if (config_last_error(mainconfig) != NULL) {
+ msg = g_strdup_printf(_("Ignored errors in theme:\n%s"),
+ config_last_error(mainconfig));
+ signal_emit("gui dialog", 2, "error", msg);
+ g_free(msg);
+ }
+
+ theme_read_formats(config, theme, module);
+
+ config_close(config);
+}
+
+static void theme_remove_module(THEME_REC *theme, const char *module)
+{
+ MODULE_THEME_REC *rec;
+
+ rec = g_hash_table_lookup(theme->modules, module);
+ if (rec == NULL) return;
+
+ g_hash_table_remove(theme->modules, module);
+ theme_module_destroy(module, rec);
+}
+
+void theme_register_module(const char *module, FORMAT_REC *formats)
+{
+ if (g_hash_table_lookup(default_formats, module) != NULL)
+ return;
+
+ g_hash_table_insert(default_formats, g_strdup(module), formats);
+
+ if (current_theme != NULL)
+ theme_read_module(current_theme, module);
+}
+
+void theme_unregister_module(const char *module)
+{
+ gpointer key, value;
+
+ if (!g_hash_table_lookup_extended(default_formats, module, &key, &value))
+ return;
+
+ g_hash_table_remove(default_formats, key);
+ g_free(key);
+
+ if (current_theme != NULL)
+ theme_remove_module(current_theme, module);
+}
+
static THEME_REC *theme_find(const char *name)
{
GSList *tmp;
@@ -115,49 +229,19 @@ static void find_themes(gchar *path)
closedir(dirp);
}
-/* Read module texts into theme */
-static void theme_read_module_texts(const char *hashkey, MODULE_THEME_REC *rec, CONFIG_REC *config)
+static void theme_read(THEME_REC *theme, const char *path)
{
- CONFIG_NODE *formats;
- GSList *tmp;
- char **flist;
- int n;
-
- formats = config_node_traverse(config, "moduleformats", FALSE);
- if (formats == NULL) return;
-
- for (tmp = formats->value; tmp != NULL; tmp = tmp->next) {
- CONFIG_NODE *node = tmp->data;
-
- if (node->key == NULL || node->value == NULL)
- continue;
-
- for (n = 0, flist = rec->formatlist; *flist != NULL; flist++, n++) {
- if (g_strcasecmp(*flist, node->key) == 0) {
- rec->format[n] = g_strdup(node->value);
- break;
- }
- }
- }
-}
-
-static int theme_read(THEME_REC *theme, const char *path)
-{
- MODULE_THEME_REC *mrec;
CONFIG_REC *config;
- CONFIG_NODE *formats;
- GSList *tmp;
char *value;
- int errors;
config = config_open(path, -1);
if (config == NULL) {
/* didn't exist or no access? */
theme->default_color = 15;
- return FALSE;
+ return;
}
- errors = config_parse(config) == -1;
+ config_parse(config);
/* default color */
theme->default_color = config_get_int(config, NULL, "default_color", 15);
@@ -175,58 +259,172 @@ static int theme_read(THEME_REC *theme, const char *path)
theme->flags |= THEME_FLAG_BG_SCALED;
if (config_get_bool(config, NULL, "bg_shaded", FALSE))
theme->flags |= THEME_FLAG_BG_SHADED;
+ config_close(config);
+}
- /* Read modules that are defined in this theme. */
- formats = config_node_traverse(config, "modules", FALSE);
- if (formats != NULL) {
- for (tmp = formats->value; tmp != NULL; tmp = tmp->next) {
- CONFIG_NODE *node = tmp->data;
+typedef struct {
+ char *name;
+ char *short_name;
+} THEME_SEARCH_REC;
+
+static int theme_search_equal(THEME_SEARCH_REC *r1, THEME_SEARCH_REC *r2)
+{
+ return g_strcasecmp(r1->short_name, r2->short_name);
+}
- if (node->key == NULL || node->value == NULL)
- continue;
+static void theme_get_modules(char *module, FORMAT_REC *formats, GSList **list)
+{
+ THEME_SEARCH_REC *rec;
+
+ rec = g_new(THEME_SEARCH_REC, 1);
+ rec->name = module;
+ rec->short_name = strrchr(module, '/');
+ if (rec->short_name != NULL)
+ rec->short_name++; else rec->short_name = module;
+ *list = g_slist_insert_sorted(*list, rec, (GCompareFunc) theme_search_equal);
+}
- mrec = g_new0(MODULE_THEME_REC, 1);
- mrec->name = g_strdup(node->key);
- mrec->formatlist = g_strsplit(node->value, " ", -1);
- mrec->format = g_new0(char*, strarray_length(mrec->formatlist));
- g_hash_table_insert(theme->modules, mrec->name, mrec);
- }
+static GSList *get_sorted_modules(void)
+{
+ GSList *list;
+
+ list = NULL;
+ g_hash_table_foreach(default_formats, (GHFunc) theme_get_modules, &list);
+ return list;
+}
+
+static THEME_SEARCH_REC *theme_search(GSList *list, const char *module)
+{
+ THEME_SEARCH_REC *rec;
+
+ while (list != NULL) {
+ rec = list->data;
+
+ if (g_strcasecmp(rec->short_name, module) == 0)
+ return rec;
+ list = list->next;
}
- /* Read the texts inside the plugin */
- g_hash_table_foreach(theme->modules, (GHFunc) theme_read_module_texts, config);
-
- if (errors) {
- /* errors fixed - save the theme */
- if (config_write(config, NULL, 0660) == -1) {
- /* we probably tried to save to global directory
- where we didn't have access.. try saving it to
- home dir instead. */
- char *str;
-
- /* check that we really didn't try to save
- it to home dir.. */
- str = g_strdup_printf("%s/.irssi/", g_get_home_dir());
- if (strncmp(path, str, strlen(str)) != 0) {
- g_free(str);
- str = g_strdup_printf("%s/.irssi/%s", g_get_home_dir(), g_basename(path));
-
- config_write(config, str, 0660);
+ return NULL;
+}
+
+static void theme_show(THEME_SEARCH_REC *rec, const char *key, const char *value)
+{
+ MODULE_THEME_REC *theme;
+ FORMAT_REC *formats;
+ const char *text, *last_title;
+ int n, first;
+
+ formats = g_hash_table_lookup(default_formats, rec->name);
+ theme = g_hash_table_lookup(current_theme->modules, rec->name);
+
+ last_title = NULL; first = TRUE;
+ for (n = 1; formats[n].def != NULL; n++) {
+ text = theme != NULL && theme->formats[n] != NULL ?
+ theme->formats[n] : formats[n].def;
+
+ if (formats[n].tag == NULL)
+ last_title = text;
+ else if ((value != NULL && key != NULL && g_strcasecmp(formats[n].tag, key) == 0) ||
+ (value == NULL && (key == NULL || stristr(formats[n].tag, key) != NULL))) {
+ if (first) {
+ printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "");
+ printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "%K[%W%s%K] - [%W%s%K]", rec->short_name, formats[0].def);
+ printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "");
+ first = FALSE;
}
- g_free(str);
+ if (last_title != NULL)
+ printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "%K[%W%s%K]", last_title);
+ if (value != NULL) {
+ theme = theme_module_create(current_theme, rec->name);
+ theme->formats[n] = g_strdup(value);
+ text = value;
+ }
+ printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "%s %K=%n %s", formats[n].tag, text);
+ last_title = NULL;
}
}
- config_close(config);
+}
+
+static void cmd_format(const char *data)
+{
+ char *params, *module, *key, *value;
+ GSList *tmp, *modules;
+
+ /* /FORMAT [<module>] [<key> [<value>]] */
+ params = cmd_get_params(data, 3 | PARAM_FLAG_GETREST, &module, &key, &value);
+
+ modules = get_sorted_modules();
+ if (*module != '\0' && theme_search(modules, module) == NULL) {
+ /* first argument isn't module.. */
+ g_free(params);
+ params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &key, &value);
+ module = "";
+ }
+
+ if (*key == '\0') key = NULL;
+ if (*value == '\0') value = NULL;
+
+ for (tmp = modules; tmp != NULL; tmp = tmp->next) {
+ THEME_SEARCH_REC *rec = tmp->data;
+
+ if (*module == '\0' || g_strcasecmp(rec->short_name, module) == 0)
+ theme_show(rec, key, value);
+ }
+ g_slist_foreach(modules, (GFunc) g_free, NULL);
+ g_slist_free(modules);
- return errors;
+ g_free(params);
}
-static void sig_formats_error(void)
+static void module_save(const char *module, MODULE_THEME_REC *rec, CONFIG_NODE *fnode)
{
- signal_emit("gui dialog", 2, "warning",
- "Your theme(s) had some old format strings, "
- "these have been changed back to their default values.");
- signal_remove("irssi init finished", (SIGNAL_FUNC) sig_formats_error);
+ CONFIG_NODE *node;
+ FORMAT_REC *formats;
+ int n;
+
+ formats = g_hash_table_lookup(default_formats, rec->name);
+ if (formats == NULL) return;
+
+ node = config_node_section(fnode, rec->name, NODE_TYPE_BLOCK);
+ for (n = 0; formats[n].def != NULL; n++) {
+ if (rec->formats[n] != NULL)
+ iconfig_node_set_str(node, formats[n].tag, rec->formats[n]);
+ }
+}
+
+/* save changed formats */
+static void cmd_save(void)
+{
+ CONFIG_REC *config;
+ CONFIG_NODE *fnode;
+
+ config = config_open(current_theme->path, 0660);
+ if (config == NULL) return;
+
+ config_parse(config);
+
+ fnode = config_node_traverse(config, "formats", TRUE);
+ g_hash_table_foreach(current_theme->modules, (GHFunc) module_save, fnode);
+
+ if (config_write(config, NULL, 0660) == -1) {
+ /* we probably tried to save to global directory
+ where we didn't have access.. try saving it to
+ home dir instead. */
+ char *str;
+
+ /* check that we really didn't try to save
+ it to home dir.. */
+ str = g_strdup_printf("%s/.irssi/", g_get_home_dir());
+ if (strncmp(current_theme->path, str, strlen(str)) != 0) {
+ g_free(str);
+ str = g_strdup_printf("%s/.irssi/%s", g_get_home_dir(), g_basename(current_theme->path));
+
+ config_write(config, str, 0660);
+ }
+ g_free(str);
+ }
+ config_close(config);
}
void themes_init(void)
@@ -235,7 +433,8 @@ void themes_init(void)
GSList *tmp;
const char *value;
char *str;
- int errors;
+
+ default_formats = g_hash_table_new((GHashFunc) g_str_hash, (GCompareFunc) g_str_equal);
/* first there's default theme.. */
str = g_strdup_printf("%s/.irssi/default.theme", g_get_home_dir());
@@ -251,22 +450,20 @@ void themes_init(void)
find_themes(SYSCONFDIR"/irssi");
/* read formats for all themes */
- errors = FALSE;
for (tmp = themes; tmp != NULL; tmp = tmp->next) {
rec = tmp->data;
- if (theme_read(rec, rec->path))
- errors = TRUE;
+ theme_read(rec, rec->path);
}
- if (errors)
- signal_add("irssi init finished", (SIGNAL_FUNC) sig_formats_error);
-
/* find the current theme to use */
value = settings_get_str("current_theme");
rec = theme_find(value);
if (rec != NULL) current_theme = rec;
+
+ command_bind("format", NULL, (SIGNAL_FUNC) cmd_format);
+ command_bind("save", NULL, (SIGNAL_FUNC) cmd_save);
}
void themes_deinit(void)
@@ -275,4 +472,9 @@ void themes_deinit(void)
g_slist_foreach(themes, (GFunc) theme_destroy, NULL);
g_slist_free(themes);
themes = NULL;
+
+ g_hash_table_destroy(default_formats);
+
+ command_unbind("format", (SIGNAL_FUNC) cmd_format);
+ command_unbind("save", (SIGNAL_FUNC) cmd_save);
}
diff --git a/src/fe-common/core/themes.h b/src/fe-common/core/themes.h
index 7bd4a8f8..5b5331f8 100644
--- a/src/fe-common/core/themes.h
+++ b/src/fe-common/core/themes.h
@@ -1,18 +1,18 @@
#ifndef __THEMES_H
#define __THEMES_H
+#include "printtext.h"
+
#define THEME_FLAG_BG_SCROLLABLE 0x0001
#define THEME_FLAG_BG_SCALED 0x0002
#define THEME_FLAG_BG_SHADED 0x0004
-typedef struct
-{
+typedef struct {
char *name;
- char **formatlist;
- char **format;
-}
-MODULE_THEME_REC;
+ int count;
+ char **formats; /* in same order as in module's default formats */
+} MODULE_THEME_REC;
typedef struct {
char *path;
@@ -30,10 +30,16 @@ typedef struct {
extern GSList *themes;
extern THEME_REC *current_theme;
+extern GHashTable *default_formats;
THEME_REC *theme_create(const char *path, const char *name);
void theme_destroy(THEME_REC *rec);
+#define theme_register(formats) theme_register_module(MODULE_NAME, formats)
+#define theme_unregister() theme_unregister_module(MODULE_NAME)
+void theme_register_module(const char *module, FORMAT_REC *formats);
+void theme_unregister_module(const char *module);
+
void themes_init(void);
void themes_deinit(void);
diff --git a/src/fe-common/core/window-activity.c b/src/fe-common/core/window-activity.c
index ba3adb13..420261a0 100644
--- a/src/fe-common/core/window-activity.c
+++ b/src/fe-common/core/window-activity.c
@@ -26,13 +26,11 @@
#include "windows.h"
#include "window-items.h"
-static void sig_hilight_text(SERVER_REC *server, const char *channel, gpointer levelptr, const char *msg)
+static void sig_hilight_text(WINDOW_REC *window, SERVER_REC *server, const char *channel, gpointer levelptr, const char *msg)
{
- WINDOW_REC *window;
int level, oldlevel;
level = GPOINTER_TO_INT(levelptr);
- window = window_find_closest(server, channel, level);
if (window == active_win || (level & (MSGLEVEL_NEVER|MSGLEVEL_NO_ACT|MSGLEVEL_MSGS)))
return;
diff --git a/src/fe-common/core/window-commands.c b/src/fe-common/core/window-commands.c
new file mode 100644
index 00000000..507cfe90
--- /dev/null
+++ b/src/fe-common/core/window-commands.c
@@ -0,0 +1,370 @@
+/*
+ window-commands.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 "misc.h"
+#include "server.h"
+
+#include "levels.h"
+
+#include "windows.h"
+#include "window-items.h"
+
+static void cmd_window(const char *data, void *server, WI_ITEM_REC *item)
+{
+ command_runsub("window", data, server, item);
+}
+
+static void cmd_window_new(const char *data, void *server, WI_ITEM_REC *item)
+{
+ WINDOW_REC *window;
+ int type;
+
+ g_return_if_fail(data != NULL);
+
+ 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));
+
+ window = window_create(NULL, FALSE);
+ window_change_server(window, server);
+}
+
+static void cmd_window_close(const char *data)
+{
+ /* destroy window unless it's the last one */
+ if (windows->next != NULL)
+ window_destroy(active_win);
+}
+
+static void cmd_window_refnum(const char *data)
+{
+ WINDOW_REC *window;
+
+ if (!is_numeric(data, 0))
+ return;
+
+ window = window_find_refnum(atoi(data));
+ if (window != NULL)
+ window_set_active(window);
+}
+
+/* return the first window number with the highest activity */
+static WINDOW_REC *window_highest_activity(WINDOW_REC *window)
+{
+ WINDOW_REC *rec, *max_win;
+ GSList *tmp;
+ int max_act, through;
+
+ g_return_val_if_fail(window != NULL, NULL);
+
+ max_win = NULL; max_act = 0; through = FALSE;
+
+ tmp = g_slist_find(windows, window);
+ for (;; tmp = tmp->next) {
+ if (tmp == NULL) {
+ tmp = windows;
+ through = TRUE;
+ }
+
+ if (through && tmp->data == window)
+ break;
+
+ rec = tmp->data;
+
+ if (rec->new_data && max_act < rec->new_data) {
+ max_act = rec->new_data;
+ max_win = rec;
+ }
+ }
+
+ return max_win;
+}
+
+static void cmd_window_goto(const char *data)
+{
+ WINDOW_REC *window;
+
+ g_return_if_fail(data != NULL);
+
+ if (is_numeric(data, 0)) {
+ cmd_window_refnum(data);
+ return;
+ }
+
+ if (g_strcasecmp(data, "active") == 0)
+ window = window_highest_activity(active_win);
+ else
+ window = window_find_item(active_win, data);
+
+ if (window != NULL)
+ window_set_active(window);
+}
+
+static void cmd_window_next(void)
+{
+ int 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(void)
+{
+ int 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)
+{
+ g_return_if_fail(data != NULL);
+
+ window_set_level(active_win, combine_level(active_win->level, data));
+ printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE, "Window level is now %s",
+ bits2level(active_win->level));
+}
+
+static void cmd_window_server(const char *data)
+{
+ SERVER_REC *server;
+
+ g_return_if_fail(data != NULL);
+
+ server = server_find_tag(data);
+ if (server == NULL)
+ printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_UNKNOWN_SERVER_TAG, data);
+ else if (active_win->active == NULL) {
+ window_change_server(active_win, server);
+ printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_SERVER_CHANGED, server->tag, server->connrec->address,
+ server->connrec->ircnet == NULL ? "" : server->connrec->ircnet);
+ }
+}
+
+static void cmd_window_item_prev(void)
+{
+ window_item_prev(active_win);
+}
+
+static void cmd_window_item_next(void)
+{
+ window_item_next(active_win);
+}
+
+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;
+}
+
+static 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);
+}
+
+void window_commands_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);
+}
+
+void window_commands_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);
+}
diff --git a/src/fe-common/core/window-items.c b/src/fe-common/core/window-items.c
index ac4c30d5..b8633461 100644
--- a/src/fe-common/core/window-items.c
+++ b/src/fe-common/core/window-items.c
@@ -27,7 +27,6 @@
#include "levels.h"
-#include "printtext.h"
#include "windows.h"
#include "window-items.h"
@@ -86,6 +85,19 @@ WINDOW_REC *window_item_window(WI_ITEM_REC *item)
return MODULE_DATA(item);
}
+void window_item_change_server(WI_ITEM_REC *item, void *server)
+{
+ WINDOW_REC *window;
+
+ g_return_if_fail(item != NULL);
+
+ window = MODULE_DATA(item);
+ item->server = server;
+
+ signal_emit("window item server changed", 2, window, item);
+ if (window->active == item) window_change_server(window, item->server);
+}
+
void window_item_set_active(WINDOW_REC *window, WI_ITEM_REC *item)
{
g_return_if_fail(window != NULL);
@@ -97,17 +109,58 @@ void window_item_set_active(WINDOW_REC *window, WI_ITEM_REC *item)
}
}
-void window_item_change_server(WI_ITEM_REC *item, void *server)
+void window_item_prev(WINDOW_REC *window)
{
- WINDOW_REC *window;
+ WI_ITEM_REC *last;
+ GSList *tmp;
- g_return_if_fail(item != NULL);
+ g_return_if_fail(window != NULL);
- window = MODULE_DATA(item);
- item->server = server;
+ last = NULL;
+ for (tmp = window->items; tmp != NULL; tmp = tmp->next) {
+ WI_ITEM_REC *rec = tmp->data;
- signal_emit("window item server changed", 2, window, item);
- if (window->active == item) window_change_server(window, item->server);
+ if (rec != window->active)
+ last = rec;
+ else {
+ /* current channel. did we find anything?
+ if not, go to the last channel */
+ if (last != NULL) break;
+ }
+ }
+
+ if (last != NULL)
+ window_item_set_active(window, last);
+}
+
+void window_item_next(WINDOW_REC *window)
+{
+ WI_ITEM_REC *next;
+ GSList *tmp;
+ int gone;
+
+ g_return_if_fail(window != NULL);
+
+ next = NULL; gone = FALSE;
+ for (tmp = window->items; tmp != NULL; tmp = tmp->next) {
+ WI_ITEM_REC *rec = tmp->data;
+
+ if (rec == window->active)
+ gone = TRUE;
+ else {
+ if (gone) {
+ /* found the next channel */
+ next = rec;
+ break;
+ }
+
+ if (next == NULL)
+ next = rec; /* fallback to first channel */
+ }
+ }
+
+ if (next != NULL)
+ window_item_set_active(window, next);
}
static WI_ITEM_REC *window_item_find_window(WINDOW_REC *window, void *server, const char *name)
diff --git a/src/fe-common/core/window-items.h b/src/fe-common/core/window-items.h
index c760ee36..34d61c2e 100644
--- a/src/fe-common/core/window-items.h
+++ b/src/fe-common/core/window-items.h
@@ -10,9 +10,12 @@ void window_remove_item(WINDOW_REC *window, WI_ITEM_REC *item);
void window_item_create(WI_ITEM_REC *item, int automatic);
WINDOW_REC *window_item_window(WI_ITEM_REC *item);
-void window_item_set_active(WINDOW_REC *window, WI_ITEM_REC *item);
void window_item_change_server(WI_ITEM_REC *item, void *server);
+void window_item_set_active(WINDOW_REC *window, WI_ITEM_REC *item);
+void window_item_prev(WINDOW_REC *window);
+void window_item_next(WINDOW_REC *window);
+
/* Find wanted window item by name. `server' can be NULL. */
WI_ITEM_REC *window_item_find(void *server, const char *name);
diff --git a/src/fe-common/core/windows.c b/src/fe-common/core/windows.c
index bbe6a740..da6de6aa 100644
--- a/src/fe-common/core/windows.c
+++ b/src/fe-common/core/windows.c
@@ -37,6 +37,8 @@ GSList *windows; /* first in the list is the active window,
next is the last active, etc. */
WINDOW_REC *active_win;
+static int daytag;
+
static int window_get_new_refnum(void)
{
WINDOW_REC *win;
@@ -247,117 +249,6 @@ WINDOW_REC *window_find_refnum(int refnum)
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 prev, max;
-
- max = prev = -1;
- for (tmp = windows; tmp != NULL; tmp = tmp->next) {
- WINDOW_REC *rec = tmp->data;
-
- if (rec->refnum < refnum && (prev == -1 || rec->refnum > prev))
- prev = rec->refnum;
- if (max == -1 || rec->refnum > max)
- max = rec->refnum;
- }
-
- return prev != -1 ? prev : max;
-}
-
-static int window_refnum_next(int refnum)
-{
- GSList *tmp;
- int min, next;
-
- min = next = -1;
- for (tmp = windows; tmp != NULL; tmp = tmp->next) {
- WINDOW_REC *rec = tmp->data;
-
- if (rec->refnum > refnum && (next == -1 || rec->refnum < next))
- next = rec->refnum;
- if (min == -1 || rec->refnum < min)
- min = rec->refnum;
- }
-
- return next != -1 ? next : min;
-}
-
-static void cmd_window(const char *data, void *server, WI_ITEM_REC *item)
-{
- command_runsub("window", data, server, item);
-}
-
-static void cmd_window_new(const char *data, void *server, WI_ITEM_REC *item)
-{
- WINDOW_REC *window;
- int type;
-
- g_return_if_fail(data != NULL);
-
- 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));
-
- window = window_create(NULL, FALSE);
- window_change_server(window, server);
-}
-
-static void cmd_window_close(const char *data)
-{
- /* destroy window unless it's the last one */
- if (windows->next != NULL)
- window_destroy(active_win);
-}
-
-/* return the first window number with the highest activity */
-static WINDOW_REC *window_highest_activity(WINDOW_REC *window)
-{
- WINDOW_REC *rec, *max_win;
- GSList *tmp;
- int max_act, through;
-
- g_return_val_if_fail(window != NULL, NULL);
-
- max_win = NULL; max_act = 0; through = FALSE;
-
- tmp = g_slist_find(windows, window);
- for (;; tmp = tmp->next) {
- if (tmp == NULL) {
- tmp = windows;
- through = TRUE;
- }
-
- if (through && tmp->data == window)
- break;
-
- rec = tmp->data;
-
- if (rec->new_data && max_act < rec->new_data) {
- max_act = rec->new_data;
- max_win = rec;
- }
- }
-
- return max_win;
-}
-
WINDOW_REC *window_find_name(const char *name)
{
GSList *tmp;
@@ -409,288 +300,56 @@ WINDOW_REC *window_find_item(WINDOW_REC *window, const char *name)
return MODULE_DATA(item);
}
-static void cmd_window_refnum(const char *data)
-{
- WINDOW_REC *window;
-
- if (!is_numeric(data, 0))
- return;
-
- window = window_find_refnum(atoi(data));
- if (window != NULL)
- window_set_active(window);
-}
-
-static void cmd_window_goto(const char *data)
-{
- WINDOW_REC *window;
-
- g_return_if_fail(data != NULL);
-
- if (is_numeric(data, 0)) {
- cmd_window_refnum(data);
- return;
- }
-
- if (g_strcasecmp(data, "active") == 0)
- window = window_highest_activity(active_win);
- else
- window = window_find_item(active_win, data);
-
- if (window != NULL)
- window_set_active(window);
-}
-
-static void cmd_window_next(void)
-{
- int 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(void)
-{
- int 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)
-{
- g_return_if_fail(data != NULL);
-
- window_set_level(active_win, combine_level(active_win->level, data));
- printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE, "Window level is now %s",
- bits2level(active_win->level));
-}
-
-static void cmd_window_server(const char *data)
-{
- SERVER_REC *server;
-
- g_return_if_fail(data != NULL);
-
- server = server_find_tag(data);
- if (server == NULL)
- printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_UNKNOWN_SERVER_TAG, data);
- else if (active_win->active == NULL) {
- window_change_server(active_win, server);
- printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_SERVER_CHANGED, server->tag, server->connrec->address,
- server->connrec->ircnet == NULL ? "" : server->connrec->ircnet);
- }
-}
-
-static void cmd_window_item_prev(const char *data, void *server, WI_ITEM_REC *item)
+int window_refnum_prev(int refnum)
{
- WINDOW_REC *window;
- WI_ITEM_REC *last;
GSList *tmp;
+ int prev, max;
- window = item == NULL ? NULL : MODULE_DATA(item);
- if (window == NULL) return;
-
- last = NULL;
- for (tmp = window->items; tmp != NULL; tmp = tmp->next) {
- WI_ITEM_REC *rec = tmp->data;
+ max = prev = -1;
+ for (tmp = windows; tmp != NULL; tmp = tmp->next) {
+ WINDOW_REC *rec = tmp->data;
- if (rec != item)
- last = rec;
- else {
- /* current channel. did we find anything?
- if not, go to the last channel */
- if (last != NULL) break;
- }
+ if (rec->refnum < refnum && (prev == -1 || rec->refnum > prev))
+ prev = rec->refnum;
+ if (max == -1 || rec->refnum > max)
+ max = rec->refnum;
}
- if (last != NULL)
- window_item_set_active(window, last);
+ return prev != -1 ? prev : max;
}
-static void cmd_window_item_next(const char *data, void *server, WI_ITEM_REC *item)
+int window_refnum_next(int refnum)
{
- WINDOW_REC *window;
- WI_ITEM_REC *next;
GSList *tmp;
- int gone;
-
- window = item == NULL ? NULL : MODULE_DATA(item);
- if (window == NULL) return;
-
- next = NULL; gone = FALSE;
- for (tmp = window->items; tmp != NULL; tmp = tmp->next) {
- WI_ITEM_REC *rec = tmp->data;
-
- if (rec == item)
- gone = TRUE;
- else {
- if (gone) {
- /* found the next channel */
- next = rec;
- break;
- }
-
- if (next == NULL)
- next = rec; /* fallback to first channel */
- }
- }
-
- if (next != NULL)
- 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;
+ int min, next;
- window_set_refnum(active_win, refnum);
- }
- } else {
- for (;;) {
- refnum = window_refnum_prev(active_win->refnum);
- if (refnum == -1 || refnum < new_refnum)
- break;
+ min = next = -1;
+ for (tmp = windows; tmp != NULL; tmp = tmp->next) {
+ WINDOW_REC *rec = tmp->data;
- window_set_refnum(active_win, refnum);
- }
+ if (rec->refnum > refnum && (next == -1 || rec->refnum < next))
+ next = rec->refnum;
+ if (min == -1 || rec->refnum < min)
+ min = rec->refnum;
}
-}
-static int windows_compare(WINDOW_REC *w1, WINDOW_REC *w2)
-{
- return w1->refnum < w2->refnum ? -1 : 1;
+ return next != -1 ? next : min;
}
-GSList *windows_get_sorted(void)
+int windows_refnum_last(void)
{
- GSList *tmp, *list;
+ GSList *tmp;
+ int max;
- list = NULL;
+ max = -1;
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);
+ if (rec->refnum > max)
+ max = rec->refnum;
}
- g_slist_free(sorted);
- printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_WINDOWLIST_FOOTER);
+
+ return max;
}
static void sig_server_looking(void *server)
@@ -722,29 +381,46 @@ static void sig_server_disconnected(void *server)
}
}
+static int sig_check_daychange(void)
+{
+ static int lastday = -1;
+ GSList *tmp;
+ time_t t;
+ struct tm *tm;
+
+ if (!settings_get_bool("timestamps")) {
+ /* display day change notice only when using timestamps */
+ return TRUE;
+ }
+
+ t = time(NULL);
+ tm = localtime(&t);
+
+ if (lastday == -1) {
+ /* First check, don't display. */
+ lastday = tm->tm_mday;
+ return TRUE;
+ }
+
+ if (tm->tm_mday == lastday)
+ return TRUE;
+
+ /* day changed, print notice about it to every window */
+ for (tmp = windows; tmp != NULL; tmp = tmp->next) {
+ printformat_window(tmp->data, MSGLEVEL_NEVER, IRCTXT_DAYCHANGE,
+ tm->tm_mday, tm->tm_mon+1, 1900+tm->tm_year);
+ }
+
+ lastday = tm->tm_mday;
+ return TRUE;
+}
+
void windows_init(void)
{
active_win = NULL;
settings_add_bool("lookandfeel", "window_auto_change", FALSE);
- 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);
+ daytag = g_timeout_add(30000, (GSourceFunc) sig_check_daychange, NULL);
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);
@@ -752,24 +428,8 @@ void windows_init(void)
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);
+ g_source_remove(daytag);
+
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 2b13101b..98ef9425 100644
--- a/src/fe-common/core/windows.h
+++ b/src/fe-common/core/windows.h
@@ -69,6 +69,10 @@ 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);
+int window_refnum_prev(int refnum);
+int window_refnum_next(int refnum);
+int windows_refnum_last(void);
+
void windows_init(void);
void windows_deinit(void);
diff --git a/src/fe-common/irc/dcc/Makefile.am b/src/fe-common/irc/dcc/Makefile.am
index 0424c7b2..54647bc9 100644
--- a/src/fe-common/irc/dcc/Makefile.am
+++ b/src/fe-common/irc/dcc/Makefile.am
@@ -14,4 +14,5 @@ libfe_common_irc_dcc_la_SOURCES = \
module-formats.c
noinst_HEADERS = \
+ module.h \
module-formats.h
diff --git a/src/fe-common/irc/dcc/fe-dcc.c b/src/fe-common/irc/dcc/fe-dcc.c
index b89e44b9..5cdcd28d 100644
--- a/src/fe-common/irc/dcc/fe-dcc.c
+++ b/src/fe-common/irc/dcc/fe-dcc.c
@@ -30,6 +30,7 @@
#include "irc/dcc/dcc.h"
+#include "themes.h"
#include "windows.h"
static void dcc_connected(DCC_REC *dcc)
@@ -427,10 +428,14 @@ void fe_dcc_init(void)
command_bind("dcc ", NULL, (SIGNAL_FUNC) cmd_dcc_list);
command_bind("dcc list", NULL, (SIGNAL_FUNC) cmd_dcc_list);
signal_add("window item remove", (SIGNAL_FUNC) dcc_chat_closed);
+
+ theme_register(fecommon_irc_dcc_formats);
}
void fe_dcc_deinit(void)
{
+ theme_unregister();
+
signal_remove("dcc connected", (SIGNAL_FUNC) dcc_connected);
signal_remove("dcc rejected", (SIGNAL_FUNC) dcc_rejected);
signal_remove("dcc closed", (SIGNAL_FUNC) dcc_closed);
diff --git a/src/fe-common/irc/dcc/module-formats.c b/src/fe-common/irc/dcc/module-formats.c
index 40313010..4dee15f7 100644
--- a/src/fe-common/irc/dcc/module-formats.c
+++ b/src/fe-common/irc/dcc/module-formats.c
@@ -21,39 +21,40 @@
#include "module.h"
#include "printtext.h"
-FORMAT_REC fecommon_irc_dcc_formats[] =
-{
- { MODULE_NAME, "IRC", 0 },
-
- /* ---- */
- { NULL, "DCC", 0 },
-
- { "own_dcc", "%K[%rdcc%K(%R$0%K)]%n $1", 2, { 0, 0 } },
- { "own_dcc_me", "%W * $0%n $1", 2, { 0, 0 } },
- { "own_dcc_ctcp", "%K[%rctcp%K(%R$0%K)]%n $1 $2", 3, { 0, 0, 0 } },
- { "dcc_msg", "%K[%G$0%K(%gdcc%K)]%n $1", 2, { 0, 0 } },
- { "action_dcc", "%W (*dcc*) $0%n $1", 2, { 0, 0 } },
- { "dcc_ctcp", "%g>>> DCC CTCP received from %_$0%_%K: %g$1", 2, { 0, 0 } },
- { "dcc_chat", "%gDCC CHAT from %_$0%_ %K[%g$1 port $2%K]", 3, { 0, 0, 1 } },
- { "dcc_chat_not_found", "%gNo DCC CHAT connection open to %_$0", 1, { 0 } },
- { "dcc_chat_connected", "%gDCC %_CHAT%_ connection with %_$0%_ %K%K[%g$1 port $2%K]%g established", 3, { 0, 0, 1 } },
- { "dcc_chat_disconnected", "%gDCC lost chat to %_$0", 1, { 0 } },
- { "dcc_send", "%gDCC SEND from %_$0%_ %K[%g$1 port $2%K]: %g$3 %K[%g$4 bytes%K]", 5, { 0, 0, 1, 0, 2 } },
- { "dcc_send_exists", "%gDCC already sending file %G$0%g for %_$1%_", 2, { 0, 0 } },
- { "dcc_send_not_found", "%gDCC not sending file %G$1%g to %_$0", 2, { 0, 0 } },
- { "dcc_send_file_not_found", "%gDCC file not found: %G$0%g", 1, { 0 } },
- { "dcc_send_connected", "%gDCC sending file %G$0%g for %_$1%_ %K[%g$2 port $3%K]", 4, { 0, 0, 0, 1 } },
- { "dcc_send_complete", "%gDCC sent file $0 %K[%g%_$1%_kb%K]%g for %_$2%_ in %_$3%_ secs %K[%g%_$4kb/s%_%K]", 5, { 0, 2, 0, 2, 3 } },
- { "dcc_send_aborted", "%gDCC aborted sending file $0 for %_$1%_", 2, { 0, 0 } },
- { "dcc_get_not_found", "%gDCC no file offered by %_$0", 1, { 0 } },
- { "dcc_get_connected", "%gDCC receiving file %G$0%g from %_$1%_ %K[%g$2 port $3%K]", 4, { 0, 0, 0, 1 } },
- { "dcc_get_complete", "%gDCC received file %G$0%g %K[%g$1kb%K]%g from %_$2%_ in %_$3%_ secs %K[%g$4kb/s%K]", 5, { 0, 2, 0, 2, 3 } },
- { "dcc_get_aborted", "%gDCC aborted receiving file $0 from %_$1%_", 2, { 0, 0 } },
- { "dcc_unknown_ctcp", "%gDCC unknown ctcp %G$0%g from %_$1%_ %K[%g$2%K]", 3, { 0, 0, 0 } },
- { "dcc_unknown_reply", "%gDCC unknown reply %G$0%g from %_$1%_ %K[%g$2%K]", 3, { 0, 0, 0 } },
- { "dcc_unknown_type", "%gDCC unknown type %_$0", 1, { 0 } },
- { "dcc_connect_error", "%gDCC can't connect to %_$0%_ port %_$1", 2, { 0, 1 } },
- { "dcc_cant_create", "%gDCC can't create file %G$0%g", 1, { 0 } },
- { "dcc_rejected", "%gDCC %G$0%g was rejected by %_$1%_ %K[%G$2%K]", 3, { 0, 0, 0 } },
- { "dcc_close", "%gDCC %G$0%g close for %_$1%_ %K[%G$2%K]", 3, { 0, 0, 0 } }
+FORMAT_REC fecommon_irc_dcc_formats[] = {
+ { MODULE_NAME, "IRC", 0 },
+
+ /* ---- */
+ { NULL, "DCC", 0 },
+
+ { "own_dcc", "%K[%rdcc%K(%R$0%K)]%n $1", 2, { 0, 0 } },
+ { "own_dcc_me", "%W * $0%n $1", 2, { 0, 0 } },
+ { "own_dcc_ctcp", "%K[%rctcp%K(%R$0%K)]%n $1 $2", 3, { 0, 0, 0 } },
+ { "dcc_msg", "%K[%G$0%K(%gdcc%K)]%n $1", 2, { 0, 0 } },
+ { "action_dcc", "%W (*dcc*) $0%n $1", 2, { 0, 0 } },
+ { "dcc_ctcp", "%g>>> DCC CTCP received from %_$0%_%K: %g$1", 2, { 0, 0 } },
+ { "dcc_chat", "%gDCC CHAT from %_$0%_ %K[%g$1 port $2%K]", 3, { 0, 0, 1 } },
+ { "dcc_chat_not_found", "%gNo DCC CHAT connection open to %_$0", 1, { 0 } },
+ { "dcc_chat_connected", "%gDCC %_CHAT%_ connection with %_$0%_ %K%K[%g$1 port $2%K]%g established", 3, { 0, 0, 1 } },
+ { "dcc_chat_disconnected", "%gDCC lost chat to %_$0", 1, { 0 } },
+ { "dcc_send", "%gDCC SEND from %_$0%_ %K[%g$1 port $2%K]: %g$3 %K[%g$4 bytes%K]", 5, { 0, 0, 1, 0, 2 } },
+ { "dcc_send_exists", "%gDCC already sending file %G$0%g for %_$1%_", 2, { 0, 0 } },
+ { "dcc_send_not_found", "%gDCC not sending file %G$1%g to %_$0", 2, { 0, 0 } },
+ { "dcc_send_file_not_found", "%gDCC file not found: %G$0%g", 1, { 0 } },
+ { "dcc_send_connected", "%gDCC sending file %G$0%g for %_$1%_ %K[%g$2 port $3%K]", 4, { 0, 0, 0, 1 } },
+ { "dcc_send_complete", "%gDCC sent file $0 %K[%g%_$1%_kb%K]%g for %_$2%_ in %_$3%_ secs %K[%g%_$4kb/s%_%K]", 5, { 0, 2, 0, 2, 3 } },
+ { "dcc_send_aborted", "%gDCC aborted sending file $0 for %_$1%_", 2, { 0, 0 } },
+ { "dcc_get_not_found", "%gDCC no file offered by %_$0", 1, { 0 } },
+ { "dcc_get_connected", "%gDCC receiving file %G$0%g from %_$1%_ %K[%g$2 port $3%K]", 4, { 0, 0, 0, 1 } },
+ { "dcc_get_complete", "%gDCC received file %G$0%g %K[%g$1kb%K]%g from %_$2%_ in %_$3%_ secs %K[%g$4kb/s%K]", 5, { 0, 2, 0, 2, 3 } },
+ { "dcc_get_aborted", "%gDCC aborted receiving file $0 from %_$1%_", 2, { 0, 0 } },
+ { "dcc_unknown_ctcp", "%gDCC unknown ctcp %G$0%g from %_$1%_ %K[%g$2%K]", 3, { 0, 0, 0 } },
+ { "dcc_unknown_reply", "%gDCC unknown reply %G$0%g from %_$1%_ %K[%g$2%K]", 3, { 0, 0, 0 } },
+ { "dcc_unknown_type", "%gDCC unknown type %_$0", 1, { 0 } },
+ { "dcc_connect_error", "%gDCC can't connect to %_$0%_ port %_$1", 2, { 0, 1 } },
+ { "dcc_cant_create", "%gDCC can't create file %G$0%g", 1, { 0 } },
+ { "dcc_rejected", "%gDCC %G$0%g was rejected by %_$1%_ %K[%G$2%K]", 3, { 0, 0, 0 } },
+ { "dcc_close", "%gDCC %G$0%g close for %_$1%_ %K[%G$2%K]", 3, { 0, 0, 0 } },
+
+ { NULL, NULL, 0 }
};
diff --git a/src/fe-common/irc/dcc/module-formats.h b/src/fe-common/irc/dcc/module-formats.h
index de01511f..d7fe8eff 100644
--- a/src/fe-common/irc/dcc/module-formats.h
+++ b/src/fe-common/irc/dcc/module-formats.h
@@ -36,6 +36,3 @@ enum {
};
extern FORMAT_REC fecommon_irc_dcc_formats[];
-#define MODULE_FORMATS fecommon_irc_dcc_formats
-
-#include "printformat.h"
diff --git a/src/fe-common/irc/dcc/module.h b/src/fe-common/irc/dcc/module.h
new file mode 100644
index 00000000..966a37cb
--- /dev/null
+++ b/src/fe-common/irc/dcc/module.h
@@ -0,0 +1,3 @@
+#include "common.h"
+
+#define MODULE_NAME "fe-common/irc/dcc"
diff --git a/src/fe-common/irc/fe-common-irc.c b/src/fe-common/irc/fe-common-irc.c
index bde1d9fe..87a0655e 100644
--- a/src/fe-common/irc/fe-common-irc.c
+++ b/src/fe-common/irc/fe-common-irc.c
@@ -19,6 +19,7 @@
*/
#include "module.h"
+#include "module-formats.h"
#include "signals.h"
#include "args.h"
#include "misc.h"
@@ -27,6 +28,7 @@
#include "server-setup.h"
+#include "themes.h"
#include "completion.h"
void fe_channels_init(void);
@@ -100,6 +102,8 @@ void fe_common_irc_init(void)
settings_add_bool("lookandfeel", "show_away_once", TRUE);
settings_add_bool("lookandfeel", "show_quit_once", FALSE);
+ theme_register(fecommon_irc_formats);
+
fe_channels_init();
fe_irc_commands_init();
fe_irc_server_init();
@@ -132,6 +136,8 @@ void fe_common_irc_deinit(void)
fe_query_deinit();
completion_deinit();
irc_window_activity_deinit();
+
+ theme_unregister();
}
void fe_common_irc_finish_init(void)
diff --git a/src/fe-common/irc/flood/Makefile.am b/src/fe-common/irc/flood/Makefile.am
index c802dfd9..46ca4f25 100644
--- a/src/fe-common/irc/flood/Makefile.am
+++ b/src/fe-common/irc/flood/Makefile.am
@@ -13,5 +13,6 @@ libfe_common_irc_flood_la_SOURCES = \
fe-flood.c \
module-formats.c
-noinst_headers = \
+noinst_HEADERS = \
+ module.h \
module-formats.h
diff --git a/src/fe-common/irc/flood/fe-flood.c b/src/fe-common/irc/flood/fe-flood.c
index d21d6952..b7937fe9 100644
--- a/src/fe-common/irc/flood/fe-flood.c
+++ b/src/fe-common/irc/flood/fe-flood.c
@@ -26,6 +26,8 @@
#include "irc-server.h"
#include "irc/flood/autoignore.h"
+#include "themes.h"
+
static void event_autoignore_new(IRC_SERVER_REC *server, AUTOIGNORE_REC *ignore)
{
g_return_if_fail(ignore != NULL);
@@ -45,10 +47,14 @@ void fe_flood_init(void)
{
signal_add("autoignore new", (SIGNAL_FUNC) event_autoignore_new);
signal_add("autoignore remove", (SIGNAL_FUNC) event_autoignore_remove);
+
+ theme_register(fecommon_irc_flood_formats);
}
void fe_flood_deinit(void)
{
+ theme_unregister();
+
signal_remove("autoignore new", (SIGNAL_FUNC) event_autoignore_new);
signal_remove("autoignore remove", (SIGNAL_FUNC) event_autoignore_remove);
}
diff --git a/src/fe-common/irc/flood/module-formats.c b/src/fe-common/irc/flood/module-formats.c
index ea8ec653..2d0293bc 100644
--- a/src/fe-common/irc/flood/module-formats.c
+++ b/src/fe-common/irc/flood/module-formats.c
@@ -23,11 +23,13 @@
FORMAT_REC fecommon_irc_flood_formats[] =
{
- { MODULE_NAME, "Flood", 0 },
+ { MODULE_NAME, "Flood", 0 },
- /* ---- */
- { NULL, "Autoignore", 0 },
+ /* ---- */
+ { NULL, "Autoignore", 0 },
- { "autoignore", "Flood detected from %_$0%_, autoignoring for %_$1%_ minutes", 2, { 0, 1 } },
- { "autounignore", "Unignoring %_$0", 1, { 0 } }
+ { "autoignore", "Flood detected from %_$0%_, autoignoring for %_$1%_ minutes", 2, { 0, 1 } },
+ { "autounignore", "Unignoring %_$0", 1, { 0 } },
+
+ { NULL, NULL, 0 }
};
diff --git a/src/fe-common/irc/flood/module-formats.h b/src/fe-common/irc/flood/module-formats.h
index 8311b021..7386dd2a 100644
--- a/src/fe-common/irc/flood/module-formats.h
+++ b/src/fe-common/irc/flood/module-formats.h
@@ -10,6 +10,3 @@ enum {
};
extern FORMAT_REC fecommon_irc_flood_formats[];
-#define MODULE_FORMATS fecommon_irc_flood_formats
-
-#include "printformat.h"
diff --git a/src/fe-common/irc/flood/module.h b/src/fe-common/irc/flood/module.h
new file mode 100644
index 00000000..a5d9528f
--- /dev/null
+++ b/src/fe-common/irc/flood/module.h
@@ -0,0 +1,3 @@
+#include "common.h"
+
+#define MODULE_NAME "fe-common/irc/flood"
diff --git a/src/fe-common/irc/module-formats.c b/src/fe-common/irc/module-formats.c
index 0a76bb22..403c1a52 100644
--- a/src/fe-common/irc/module-formats.c
+++ b/src/fe-common/irc/module-formats.c
@@ -21,173 +21,173 @@
#include "module.h"
#include "printtext.h"
-FORMAT_REC fecommon_irc_formats[] =
-{
- { MODULE_NAME, "IRC", 0 },
-
- /* ---- */
- { NULL, "Server", 0 },
-
- { "lag_disconnected", "No PONG reply from server %_$0%_ in $1 seconds, disconnecting", 2, { 0, 1 } },
- { "disconnected", "Disconnected from %_$0%_ %K[%n$1%K]", 2, { 0, 0 } },
- { "server_list", "%_$0%_: $1:$2 ($3)", 5, { 0, 0, 1, 0, 0 } },
- { "server_lookup_list", "%_$0%_: $1:$2 ($3) (connecting...)", 5, { 0, 0, 1, 0, 0 } },
- { "server_reconnect_list", "%_$0%_: $1:$2 ($3) ($5 left before reconnecting)", 6, { 0, 0, 1, 0, 0, 0 } },
- { "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", "[%_$2%_] %RNetsplit%n detected between servers %_$0%_ and %_$1%_%:Use /NETSPLIT to see who left", 3, { 0, 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 },
-
- { "join", "%c%_$0%_ %K[%c$1%K]%n has joined %_$2", 3, { 0, 0, 0 } },
- { "part", "%c$0 %K[%n$1%K]%n has left %_$2%_ %K[%n$3%K]", 4, { 0, 0, 0, 0 } },
- { "joinerror_toomany", "Cannot join to channel %_$0%_ %K(%nYou have joined to too many channels%K)", 1, { 0 } },
- { "joinerror_full", "Cannot join to channel %_$0%_ %K(%nChannel is full%K)", 1, { 0 } },
- { "joinerror_invite", "Cannot join to channel %_$0%_ %K(%nYou must be invited%K)", 1, { 0 } },
- { "joinerror_banned", "Cannot join to channel %_$0%_ %K(%nYou are banned%K)", 1, { 0 } },
- { "joinerror_bad_key", "Cannot join to channel %_$0%_ %K(%nBad channel key%K)", 1, { 0 } },
- { "joinerror_bad_mask", "Cannot join to channel %_$0%_ %K(%nBad channel mask%K)", 1, { 0 } },
- { "joinerror_unavail", "Cannot join to channel %_$0%_ %K(%nChannel is temporarily unavailable%K)", 1, { 0 } },
- { "kick", "%c$0%n was kicked from %_$1%_ by %_$2%_ %K[%n$3%K]", 4, { 0, 0, 0, 0 } },
- { "quit", "%c$0 %K[%n$1%K]%n has quit IRC %K[%n$2%K]", 3, { 0, 0, 0 } },
- { "quit_once", "%_$3%_ %c$0 %K[%n$1%K]%n has quit IRC %K[%n$2%K]", 4, { 0, 0, 0, 0 } },
- { "invite", "%_$0%_ invites you to %_$1", 2, { 0, 0 } },
- { "inviting", "Inviting $0 to %_$1", 2, { 0, 0 } },
- { "not_invited", "You have not been invited to a channel!", 0 },
- { "names", "%K[%g%_Users%_%K(%g$0%K)]%n $1", 2, { 0, 0 } },
- { "endofnames", "%g%_$0%_%K:%n Total of %_$1%_ nicks %K[%n%_$2%_ ops, %_$3%_ voices, %_$4%_ normal%K]", 5, { 0, 1, 1, 1, 1 } },
- { "channel_created", "Channel %_$0%_ created $1", 2, { 0, 0 } },
- { "topic", "Topic for %c$0%K:%n $1", 2, { 0, 0 } },
- { "no_topic", "No topic set for %c$0", 1, { 0 } },
- { "new_topic", "%_$0%_ changed the topic of %c$1%n to%K:%n $2", 3, { 0, 0, 0 } },
- { "topic_unset", "Topic unset by %_$0%_ on %c$1", 2, { 0, 0 } },
- { "topic_info", "Topic set by %_$0%_ %K[%n$1%K]", 2, { 0, 0 } },
- { "chanmode_change", "mode/%c$0 %K[%n$1%K]%n by %_$2", 3, { 0, 0, 0 } },
- { "server_chanmode_change", "%RServerMode/%c$0 %K[%n$1%K]%n by %_$2", 3, { 0, 0, 0 } },
- { "channel_mode", "mode/%c$0 %K[%n$1%K]", 2, { 0, 0 } },
- { "bantype", "Ban type changed to %_$0", 1, { 0 } },
- { "banlist", "%_$0%_: ban %c$1", 2, { 0, 0 } },
- { "banlist_long", "%_$0%_: ban %c$1 %K[%nby %_$2%_, $3 secs ago%K]", 4, { 0, 0, 0, 1 } },
- { "ebanlist", "%_$0%_: ban exception %c$1", 2, { 0, 0 } },
- { "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 } },
- { "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 },
-
- { "usermode_change", "Mode change %K[%n%_$0%_%K]%n for user %c$1", 2, { 0, 0 } },
- { "user_mode", "Your user mode is %K[%n%_$0%_%K]", 1, { 0 } },
- { "away", "You have been marked as being away", 0 },
- { "unaway", "You are no longer marked as being away", 0 },
- { "nick_away", "$0 is away: $1", 2, { 0, 0 } },
- { "no_such_nick", "$0: No such nick/channel", 1, { 0 } },
- { "your_nick", "Your nickname is $0", 1, { 0 } },
- { "your_nick_changed", "You're now known as %c$0", 1, { 0 } },
- { "nick_changed", "%_$0%_ is now known as %c$1", 2, { 0, 0 } },
- { "nick_in_use", "Nick %_$0%_ is already in use", 1, { 0 } },
- { "nick_unavailable", "Nick %_$0%_ is temporarily unavailable", 1, { 0 } },
- { "your_nick_owned", "Your nick is owned by %_$3%_ %K[%n$1@$2%K]", 4, { 0, 0, 0, 0 } },
-
- /* ---- */
- { NULL, "Who queries", 0 },
-
- { "whois", "%_$0%_ %K[%n$1@$2%K]%n%: ircname : $3", 4, { 0, 0, 0, 0 } },
- { "whois_idle", " idle : $1 hours $2 mins $3 secs", 4, { 0, 1, 1, 1 } },
- { "whois_idle_signon", " idle : $1 hours $2 mins $3 secs %K[%nsignon: $4%K]", 5, { 0, 1, 1, 1, 0 } },
- { "whois_server", " server : $1 %K[%n$2%K]", 3, { 0, 0, 0 } },
- { "whois_oper", " : %_IRC operator%_", 1, { 0 } },
- { "whois_channels", " channels : $1", 2, { 0, 0 } },
- { "whois_away", " away : $1", 2, { 0, 0 } },
- { "end_of_whois", "End of WHOIS", 1, { 0 } },
- { "who", "$[-10]0 %|%_$[!9]1%_ $[!3]2 $[!2]3 $4@$5 %K(%W$6%K)", 7, { 0, 0, 0, 0, 0, 0, 0 } },
- { "end_of_who", "End of /WHO list", 1, { 0 } },
-
- /* ---- */
- { NULL, "Your messages", 0 },
-
- { "own_msg", "%K<%n$2%W$0%K>%n %|$1", 3, { 0, 0, 0 } },
- { "own_msg_channel", "%K<%n$3%W$0%K:%c$1%K>%n %|$2", 4, { 0, 0, 0, 0 } },
- { "own_msg_private", "%K[%rmsg%K(%R$0%K)]%n $1", 2, { 0, 0 } },
- { "own_msg_private_query", "%K<%W$2%K>%n %|$1", 3, { 0, 0, 0 } },
- { "own_notice", "%K[%rnotice%K(%R$0%K)]%n $1", 2, { 0, 0 } },
- { "own_me", "%W * $0%n $1", 2, { 0, 0 } },
- { "own_ctcp", "%K[%rctcp%K(%R$0%K)]%n $1 $2", 3, { 0, 0, 0 } },
-
- /* ---- */
- { NULL, "Received messages", 0 },
-
- { "pubmsg_me", "%K<%n$2%Y$0%K>%n %|$1", 3, { 0, 0, 0 } },
- { "pubmsg_me_channel", "%K<%n$3%Y$0%K:%c$1%K>%n %|$2", 4, { 0, 0, 0, 0 } },
- { "pubmsg_hilight", "%K<%n$3$0$1%K>%n %|$2", 4, { 0, 0, 0, 0 } },
- { "pubmsg_hilight_channel", "%K<%n$4$0$1%K:%c$2%K>%n %|$3", 5, { 0, 0, 0, 0, 0 } },
- { "pubmsg", "%K<%n$2$0%K>%n %|$1", 3, { 0, 0, 0 } },
- { "pubmsg_channel", "%K<%n$3$0%K:%c$1%K>%n %|$2", 4, { 0, 0, 0, 0 } },
- { "msg_private", "%K[%R$0%K(%r$1%K)]%n $2", 3, { 0, 0, 0 } },
- { "msg_private_query", "%K<%R$0%K>%n %|$2", 3, { 0, 0, 0 } },
- { "notice_server", "%g!$0%n $1", 2, { 0, 0 } },
- { "notice_public", "%K-%M$0%K:%m$1%K-%n $2", 3, { 0, 0, 0 } },
- { "notice_public_ops", "%K-%M$0%K:%m@$1%K-%n $2", 3, { 0, 0, 0 } },
- { "notice_private", "%K-%M$0%K(%m$1%K)-%n $2", 3, { 0, 0, 0 } },
- { "action_private", "%W (*) $0%n $2", 3, { 0, 0, 0 } },
- { "action_private_query", "%W * $0%n $2", 3, { 0, 0, 0 } },
- { "action_public", "%W * $0%n $1", 2, { 0, 0 } },
- { "action_public_channel", "%W * $0%K:%c$1%n $2", 3, { 0, 0, 0 } },
-
- /* ---- */
- { NULL, "CTCPs", 0 },
-
- { "ctcp_reply", "CTCP %_$0%_ reply from %_$1%_%K:%n $2", 3, { 0, 0, 0 } },
- { "ctcp_reply_channel", "CTCP %_$0%_ reply from %_$1%_ in channel %_$4%_%K:%n $2", 4, { 0, 0, 0, 0 } },
- { "ctcp_ping_reply", "CTCP %_PING%_ reply from %_$0%_: $1.$2 seconds", 3, { 0, 2, 2 } },
- { "ctcp_requested", "%g>>> %_$0%_ %K[%g$1%K] %grequested %_$2%_ from %_$3", 4, { 0, 0, 0, 0 } },
-
- /* ---- */
- { NULL, "Other server events", 0 },
-
- { "online", "Users online: %_$0", 1, { 0 } },
- { "pong", "PONG received from $0: $1", 2, { 0, 0 } },
- { "wallops", "%WWALLOP%n $0: $1", 2, { 0, 0 } },
- { "action_wallops", "%WWALLOP * $0%n $1", 2, { 0, 0 } },
- { "error", "%_ERROR%_ $0", 1, { 0 } },
- { "unknown_mode", "Unknown mode character $0", 1, { 0 } },
- { "not_chanop", "You're not channel operator in $0", 1, { 0 } },
-
- /* ---- */
- { NULL, "Misc", 0 },
-
- { "ignored", "Ignoring %_$1%_ from %_$0%_", 2, { 0, 0 } },
- { "unignored", "Unignored %_$0%_", 1, { 0 } },
- { "ignore_not_found", "%_$0%_ is not being ignored", 1, { 0 } },
- { "ignore_no_ignores", "There are no ignores", 0 },
- { "ignore_header", "Ignorance List:", 0 },
- { "ignore_line", "$[-4]0 $1: $2 $3 $4", 5, { 1, 0, 0, 0, 0 } },
- { "ignore_footer", "", 0 },
- { "talking_in", "You are now talking in %_$0%_", 1, { 0 } },
- { "no_query", "No query with %_$0%_", 1, { 0 } },
- { "no_msgs_got", "You have not received a message from anyone yet", 0 },
- { "no_msgs_sent", "You have not sent a message to anyone yet", 0 }
-};
+FORMAT_REC fecommon_irc_formats[] = {
+ { MODULE_NAME, "IRC", 0 },
+
+ /* ---- */
+ { NULL, "Server", 0 },
+
+ { "lag_disconnected", "No PONG reply from server %_$0%_ in $1 seconds, disconnecting", 2, { 0, 1 } },
+ { "disconnected", "Disconnected from %_$0%_ %K[%n$1%K]", 2, { 0, 0 } },
+ { "server_list", "%_$0%_: $1:$2 ($3)", 5, { 0, 0, 1, 0, 0 } },
+ { "server_lookup_list", "%_$0%_: $1:$2 ($3) (connecting...)", 5, { 0, 0, 1, 0, 0 } },
+ { "server_reconnect_list", "%_$0%_: $1:$2 ($3) ($5 left before reconnecting)", 6, { 0, 0, 1, 0, 0, 0 } },
+ { "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 },
+
+ { "join", "%c%_$0%_ %K[%c$1%K]%n has joined %_$2", 3, { 0, 0, 0 } },
+ { "part", "%c$0 %K[%n$1%K]%n has left %_$2%_ %K[%n$3%K]", 4, { 0, 0, 0, 0 } },
+ { "joinerror_toomany", "Cannot join to channel %_$0%_ %K(%nYou have joined to too many channels%K)", 1, { 0 } },
+ { "joinerror_full", "Cannot join to channel %_$0%_ %K(%nChannel is full%K)", 1, { 0 } },
+ { "joinerror_invite", "Cannot join to channel %_$0%_ %K(%nYou must be invited%K)", 1, { 0 } },
+ { "joinerror_banned", "Cannot join to channel %_$0%_ %K(%nYou are banned%K)", 1, { 0 } },
+ { "joinerror_bad_key", "Cannot join to channel %_$0%_ %K(%nBad channel key%K)", 1, { 0 } },
+ { "joinerror_bad_mask", "Cannot join to channel %_$0%_ %K(%nBad channel mask%K)", 1, { 0 } },
+ { "joinerror_unavail", "Cannot join to channel %_$0%_ %K(%nChannel is temporarily unavailable%K)", 1, { 0 } },
+ { "kick", "%c$0%n was kicked from %_$1%_ by %_$2%_ %K[%n$3%K]", 4, { 0, 0, 0, 0 } },
+ { "quit", "%c$0 %K[%n$1%K]%n has quit IRC %K[%n$2%K]", 3, { 0, 0, 0 } },
+ { "quit_once", "%_$3%_ %c$0 %K[%n$1%K]%n has quit IRC %K[%n$2%K]", 4, { 0, 0, 0, 0 } },
+ { "invite", "%_$0%_ invites you to %_$1", 2, { 0, 0 } },
+ { "inviting", "Inviting $0 to %_$1", 2, { 0, 0 } },
+ { "not_invited", "You have not been invited to a channel!", 0 },
+ { "names", "%K[%g%_Users%_%K(%g$0%K)]%n $1", 2, { 0, 0 } },
+ { "endofnames", "%g%_$0%_%K:%n Total of %_$1%_ nicks %K[%n%_$2%_ ops, %_$3%_ voices, %_$4%_ normal%K]", 5, { 0, 1, 1, 1, 1 } },
+ { "channel_created", "Channel %_$0%_ created $1", 2, { 0, 0 } },
+ { "topic", "Topic for %c$0%K:%n $1", 2, { 0, 0 } },
+ { "no_topic", "No topic set for %c$0", 1, { 0 } },
+ { "new_topic", "%_$0%_ changed the topic of %c$1%n to%K:%n $2", 3, { 0, 0, 0 } },
+ { "topic_unset", "Topic unset by %_$0%_ on %c$1", 2, { 0, 0 } },
+ { "topic_info", "Topic set by %_$0%_ %K[%n$1%K]", 2, { 0, 0 } },
+ { "chanmode_change", "mode/%c$0 %K[%n$1%K]%n by %_$2", 3, { 0, 0, 0 } },
+ { "server_chanmode_change", "%RServerMode/%c$0 %K[%n$1%K]%n by %_$2", 3, { 0, 0, 0 } },
+ { "channel_mode", "mode/%c$0 %K[%n$1%K]", 2, { 0, 0 } },
+ { "bantype", "Ban type changed to %_$0", 1, { 0 } },
+ { "banlist", "%_$0%_: ban %c$1", 2, { 0, 0 } },
+ { "banlist_long", "%_$0%_: ban %c$1 %K[%nby %_$2%_, $3 secs ago%K]", 4, { 0, 0, 0, 1 } },
+ { "ebanlist", "%_$0%_: ban exception %c$1", 2, { 0, 0 } },
+ { "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 } },
+ { "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 },
+
+ { "usermode_change", "Mode change %K[%n%_$0%_%K]%n for user %c$1", 2, { 0, 0 } },
+ { "user_mode", "Your user mode is %K[%n%_$0%_%K]", 1, { 0 } },
+ { "away", "You have been marked as being away", 0 },
+ { "unaway", "You are no longer marked as being away", 0 },
+ { "nick_away", "$0 is away: $1", 2, { 0, 0 } },
+ { "no_such_nick", "$0: No such nick/channel", 1, { 0 } },
+ { "your_nick", "Your nickname is $0", 1, { 0 } },
+ { "your_nick_changed", "You're now known as %c$0", 1, { 0 } },
+ { "nick_changed", "%_$0%_ is now known as %c$1", 2, { 0, 0 } },
+ { "nick_in_use", "Nick %_$0%_ is already in use", 1, { 0 } },
+ { "nick_unavailable", "Nick %_$0%_ is temporarily unavailable", 1, { 0 } },
+ { "your_nick_owned", "Your nick is owned by %_$3%_ %K[%n$1@$2%K]", 4, { 0, 0, 0, 0 } },
+
+ /* ---- */
+ { NULL, "Who queries", 0 },
+
+ { "whois", "%_$0%_ %K[%n$1@$2%K]%n%: ircname : $3", 4, { 0, 0, 0, 0 } },
+ { "whois_idle", " idle : $1 hours $2 mins $3 secs", 4, { 0, 1, 1, 1 } },
+ { "whois_idle_signon", " idle : $1 hours $2 mins $3 secs %K[%nsignon: $4%K]", 5, { 0, 1, 1, 1, 0 } },
+ { "whois_server", " server : $1 %K[%n$2%K]", 3, { 0, 0, 0 } },
+ { "whois_oper", " : %_IRC operator%_", 1, { 0 } },
+ { "whois_channels", " channels : $1", 2, { 0, 0 } },
+ { "whois_away", " away : $1", 2, { 0, 0 } },
+ { "end_of_whois", "End of WHOIS", 1, { 0 } },
+ { "who", "$[-10]0 %|%_$[!9]1%_ $[!3]2 $[!2]3 $4@$5 %K(%W$6%K)", 7, { 0, 0, 0, 0, 0, 0, 0 } },
+ { "end_of_who", "End of /WHO list", 1, { 0 } },
+
+ /* ---- */
+ { NULL, "Your messages", 0 },
+
+ { "own_msg", "%K<%n$2%W$0%K>%n %|$1", 3, { 0, 0, 0 } },
+ { "own_msg_channel", "%K<%n$3%W$0%K:%c$1%K>%n %|$2", 4, { 0, 0, 0, 0 } },
+ { "own_msg_private", "%K[%rmsg%K(%R$0%K)]%n $1", 2, { 0, 0 } },
+ { "own_msg_private_query", "%K<%W$2%K>%n %|$1", 3, { 0, 0, 0 } },
+ { "own_notice", "%K[%rnotice%K(%R$0%K)]%n $1", 2, { 0, 0 } },
+ { "own_me", "%W * $0%n $1", 2, { 0, 0 } },
+ { "own_ctcp", "%K[%rctcp%K(%R$0%K)]%n $1 $2", 3, { 0, 0, 0 } },
+
+ /* ---- */
+ { NULL, "Received messages", 0 },
+
+ { "pubmsg_me", "%K<%n$2%Y$0%K>%n %|$1", 3, { 0, 0, 0 } },
+ { "pubmsg_me_channel", "%K<%n$3%Y$0%K:%c$1%K>%n %|$2", 4, { 0, 0, 0, 0 } },
+ { "pubmsg_hilight", "%K<%n$3$0$1%K>%n %|$2", 4, { 0, 0, 0, 0 } },
+ { "pubmsg_hilight_channel", "%K<%n$4$0$1%K:%c$2%K>%n %|$3", 5, { 0, 0, 0, 0, 0 } },
+ { "pubmsg", "%K<%n$2$0%K>%n %|$1", 3, { 0, 0, 0 } },
+ { "pubmsg_channel", "%K<%n$3$0%K:%c$1%K>%n %|$2", 4, { 0, 0, 0, 0 } },
+ { "msg_private", "%K[%R$0%K(%r$1%K)]%n $2", 3, { 0, 0, 0 } },
+ { "msg_private_query", "%K<%R$0%K>%n %|$2", 3, { 0, 0, 0 } },
+ { "notice_server", "%g!$0%n $1", 2, { 0, 0 } },
+ { "notice_public", "%K-%M$0%K:%m$1%K-%n $2", 3, { 0, 0, 0 } },
+ { "notice_public_ops", "%K-%M$0%K:%m@$1%K-%n $2", 3, { 0, 0, 0 } },
+ { "notice_private", "%K-%M$0%K(%m$1%K)-%n $2", 3, { 0, 0, 0 } },
+ { "action_private", "%W (*) $0%n $2", 3, { 0, 0, 0 } },
+ { "action_private_query", "%W * $0%n $2", 3, { 0, 0, 0 } },
+ { "action_public", "%W * $0%n $1", 2, { 0, 0 } },
+ { "action_public_channel", "%W * $0%K:%c$1%n $2", 3, { 0, 0, 0 } },
+
+ /* ---- */
+ { NULL, "CTCPs", 0 },
+
+ { "ctcp_reply", "CTCP %_$0%_ reply from %_$1%_%K:%n $2", 3, { 0, 0, 0 } },
+ { "ctcp_reply_channel", "CTCP %_$0%_ reply from %_$1%_ in channel %_$4%_%K:%n $2", 4, { 0, 0, 0, 0 } },
+ { "ctcp_ping_reply", "CTCP %_PING%_ reply from %_$0%_: $1.$2 seconds", 3, { 0, 2, 2 } },
+ { "ctcp_requested", "%g>>> %_$0%_ %K[%g$1%K] %grequested %_$2%_ from %_$3", 4, { 0, 0, 0, 0 } },
+
+ /* ---- */
+ { NULL, "Other server events", 0 },
+
+ { "online", "Users online: %_$0", 1, { 0 } },
+ { "pong", "PONG received from $0: $1", 2, { 0, 0 } },
+ { "wallops", "%WWALLOP%n $0: $1", 2, { 0, 0 } },
+ { "action_wallops", "%WWALLOP * $0%n $1", 2, { 0, 0 } },
+ { "error", "%_ERROR%_ $0", 1, { 0 } },
+ { "unknown_mode", "Unknown mode character $0", 1, { 0 } },
+ { "not_chanop", "You're not channel operator in $0", 1, { 0 } },
+
+ /* ---- */
+ { NULL, "Misc", 0 },
+
+ { "ignored", "Ignoring %_$1%_ from %_$0%_", 2, { 0, 0 } },
+ { "unignored", "Unignored %_$0%_", 1, { 0 } },
+ { "ignore_not_found", "%_$0%_ is not being ignored", 1, { 0 } },
+ { "ignore_no_ignores", "There are no ignores", 0 },
+ { "ignore_header", "Ignorance List:", 0 },
+ { "ignore_line", "$[-4]0 $1: $2 $3 $4", 5, { 1, 0, 0, 0, 0 } },
+ { "ignore_footer", "", 0 },
+ { "talking_in", "You are now talking in %_$0%_", 1, { 0 } },
+ { "no_query", "No query with %_$0%_", 1, { 0 } },
+ { "no_msgs_got", "You have not received a message from anyone yet", 0 },
+ { "no_msgs_sent", "You have not sent a message to anyone yet", 0 },
+
+ { NULL, NULL, 0 }
diff --git a/src/fe-common/irc/module-formats.h b/src/fe-common/irc/module-formats.h
index ea615d2d..b811a2de 100644
--- a/src/fe-common/irc/module-formats.h
+++ b/src/fe-common/irc/module-formats.h
@@ -162,6 +162,3 @@ enum {
};
extern FORMAT_REC fecommon_irc_formats[];
-#define MODULE_FORMATS fecommon_irc_formats
-
-#include "printformat.h"
diff --git a/src/fe-common/irc/notifylist/Makefile.am b/src/fe-common/irc/notifylist/Makefile.am
index c44da278..53dd7374 100644
--- a/src/fe-common/irc/notifylist/Makefile.am
+++ b/src/fe-common/irc/notifylist/Makefile.am
@@ -13,5 +13,6 @@ libfe_common_irc_notifylist_la_SOURCES = \
fe-notifylist.c \
module-formats.c
-noinst_headers = \
+noinst_HEADERS = \
+ module.h \
module-formats.h
diff --git a/src/fe-common/irc/notifylist/fe-notifylist.c b/src/fe-common/irc/notifylist/fe-notifylist.c
index 7520cdb8..3a799de3 100644
--- a/src/fe-common/irc/notifylist/fe-notifylist.c
+++ b/src/fe-common/irc/notifylist/fe-notifylist.c
@@ -31,6 +31,8 @@
#include "ircnet-setup.h"
#include "irc/notifylist/notifylist.h"
+#include "themes.h"
+
/* add the nick of a hostmask to list if it isn't there already */
static GSList *mask_add_once(GSList *list, const char *mask)
{
@@ -224,6 +226,8 @@ static void notifylist_unidle(IRC_SERVER_REC *server, const char *nick,
void fe_notifylist_init(void)
{
+ theme_register(fecommon_irc_notifylist_formats);
+
command_bind("notify", NULL, (SIGNAL_FUNC) cmd_notify);
signal_add("notifylist joined", (SIGNAL_FUNC) notifylist_joined);
signal_add("notifylist left", (SIGNAL_FUNC) notifylist_left);
@@ -233,6 +237,8 @@ void fe_notifylist_init(void)
void fe_notifylist_deinit(void)
{
+ theme_unregister();
+
command_unbind("notify", (SIGNAL_FUNC) cmd_notify);
signal_remove("notifylist joined", (SIGNAL_FUNC) notifylist_joined);
signal_remove("notifylist left", (SIGNAL_FUNC) notifylist_left);
diff --git a/src/fe-common/irc/notifylist/module-formats.c b/src/fe-common/irc/notifylist/module-formats.c
index 7a673457..e369d52c 100644
--- a/src/fe-common/irc/notifylist/module-formats.c
+++ b/src/fe-common/irc/notifylist/module-formats.c
@@ -23,17 +23,19 @@
FORMAT_REC fecommon_irc_notifylist_formats[] =
{
- { MODULE_NAME, "Notifylist", 0 },
-
- /* ---- */
- { NULL, "Notifylist", 0 },
-
- { "notify_join", "%_$0%_ %K[%n$1@$2%K] [%n%_$3%_%K]%n has joined to $4", 5, { 0, 0, 0, 0, 0 } },
- { "notify_part", "%_$0%_ has left $4", 5, { 0, 0, 0, 0, 0 } },
- { "notify_away", "%_$0%_ %K[%n$5%K]%n %K[%n$1@$2%K] [%n%_$3%_%K]%n is now away: $4", 6, { 0, 0, 0, 0, 0, 0 } },
- { "notify_unaway", "%_$0%_ %K[%n$4%K]%n %K[%n$1@$2%K] [%n%_$3%_%K]%n is now unaway", 5, { 0, 0, 0, 0, 0 } },
- { "notify_unidle", "%_$0%_ %K[%n$5%K]%n %K[%n$1@$2%K] [%n%_$3%_%K]%n just stopped idling", 6, { 0, 0, 0, 0, 0, 0 } },
- { "notify_online", "On $0: %_$1%_", 2, { 0, 0 } },
- { "notify_offline", "Offline: $0", 1, { 0 } },
- { "notify_list", "$0: $1 $2 $3", 4, { 0, 0, 0, 0 } }
+ { MODULE_NAME, "Notifylist", 0 },
+
+ /* ---- */
+ { NULL, "Notifylist", 0 },
+
+ { "notify_join", "%_$0%_ %K[%n$1@$2%K] [%n%_$3%_%K]%n has joined to $4", 5, { 0, 0, 0, 0, 0 } },
+ { "notify_part", "%_$0%_ has left $4", 5, { 0, 0, 0, 0, 0 } },
+ { "notify_away", "%_$0%_ %K[%n$5%K]%n %K[%n$1@$2%K] [%n%_$3%_%K]%n is now away: $4", 6, { 0, 0, 0, 0, 0, 0 } },
+ { "notify_unaway", "%_$0%_ %K[%n$4%K]%n %K[%n$1@$2%K] [%n%_$3%_%K]%n is now unaway", 5, { 0, 0, 0, 0, 0 } },
+ { "notify_unidle", "%_$0%_ %K[%n$5%K]%n %K[%n$1@$2%K] [%n%_$3%_%K]%n just stopped idling", 6, { 0, 0, 0, 0, 0, 0 } },
+ { "notify_online", "On $0: %_$1%_", 2, { 0, 0 } },
+ { "notify_offline", "Offline: $0", 1, { 0 } },
+ { "notify_list", "$0: $1 $2 $3", 4, { 0, 0, 0, 0 } },
+
+ { NULL, NULL, 0 },
};
diff --git a/src/fe-common/irc/notifylist/module-formats.h b/src/fe-common/irc/notifylist/module-formats.h
index f5f855dc..e37045f1 100644
--- a/src/fe-common/irc/notifylist/module-formats.h
+++ b/src/fe-common/irc/notifylist/module-formats.h
@@ -16,6 +16,3 @@ enum {
};
extern FORMAT_REC fecommon_irc_notifylist_formats[];
-#define MODULE_FORMATS fecommon_irc_notifylist_formats
-
-#include "printformat.h"
diff --git a/src/fe-common/irc/notifylist/module.h b/src/fe-common/irc/notifylist/module.h
new file mode 100644
index 00000000..00aa01e3
--- /dev/null
+++ b/src/fe-common/irc/notifylist/module.h
@@ -0,0 +1,3 @@
+#include "common.h"
+
+#define MODULE_NAME "fe-common/irc/notifylist"
diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c
index 59e00d52..c68b257d 100644
--- a/src/fe-text/gui-printtext.c
+++ b/src/fe-text/gui-printtext.c
@@ -35,277 +35,272 @@
static gint mirc_colors[] = { 15, 0, 1, 2, 4, 6, 5, 4, 14, 10, 3, 11, 9, 13, 8, 7, 15 };
static gint max_textwidget_lines;
-static LINE_REC *create_line(GUI_WINDOW_REC *gui, gint level)
+#define mark_temp_eol(text) \
+ memcpy((text)->buffer + (text)->pos, "\0\x80", 2);
+
+static LINE_REC *create_line(GUI_WINDOW_REC *gui, int level)
{
- g_return_val_if_fail(gui != NULL, NULL);
- g_return_val_if_fail(gui->cur_text != NULL, NULL);
-
- gui->cur_line = g_mem_chunk_alloc(gui->line_chunk);
- gui->cur_line->text = gui->cur_text->buffer+gui->cur_text->pos;
- gui->cur_line->level = (gint32) GPOINTER_TO_INT(level);
- gui->cur_line->time = time(NULL);
-
- /* temporarily mark the end of line. */
- memcpy(gui->cur_text->buffer+gui->cur_text->pos, "\0\x80", 2);
-
- gui->last_color = -1;
- gui->last_flags = 0;
-
- gui->lines = g_list_append(gui->lines, gui->cur_line);
- if (gui->startline == NULL)
- {
- gui->startline = gui->lines;
- gui->bottom_startline = gui->lines;
- }
- return gui->cur_line;
+ g_return_val_if_fail(gui != NULL, NULL);
+ g_return_val_if_fail(gui->cur_text != NULL, NULL);
+
+ gui->cur_line = g_mem_chunk_alloc(gui->line_chunk);
+ gui->cur_line->text = gui->cur_text->buffer+gui->cur_text->pos;
+ gui->cur_line->level = GPOINTER_TO_INT(level);
+ gui->cur_line->time = time(NULL);
+
+ mark_temp_eol(gui->cur_text);
+
+ gui->last_color = -1;
+ gui->last_flags = 0;
+
+ gui->lines = g_list_append(gui->lines, gui->cur_line);
+ if (gui->startline == NULL) {
+ /* first line */
+ gui->startline = gui->lines;
+ gui->bottom_startline = gui->lines;
+ }
+ return gui->cur_line;
}
static TEXT_CHUNK_REC *create_text_chunk(GUI_WINDOW_REC *gui)
{
- TEXT_CHUNK_REC *rec;
- guchar *buffer;
- gchar *ptr;
-
- g_return_val_if_fail(gui != NULL, NULL);
-
- rec = g_new(TEXT_CHUNK_REC, 1);
- rec->overflow[0] = 0;
- rec->overflow[1] = (char) LINE_CMD_OVERFLOW;
- rec->pos = 0;
- rec->lines = 0;
-
- if (gui->cur_line != NULL && gui->cur_line->text != NULL)
- {
- /* mark the next block text block position.. */
- buffer = (guchar *) gui->cur_text->buffer+gui->cur_text->pos;
- if (gui->cur_text->pos+2+sizeof(gchar *) > LINE_TEXT_CHUNK_SIZE)
- g_error("create_text_chunk() : buffer overflow?!");
- *buffer++ = 0; *buffer++ = LINE_CMD_CONTINUE;
- ptr = rec->buffer;
- memcpy(buffer, &ptr, sizeof(gchar *));
- }
- gui->cur_text = rec;
- gui->text_chunks = g_slist_append(gui->text_chunks, rec);
- return rec;
+ TEXT_CHUNK_REC *rec;
+ char *buffer, *ptr;
+
+ g_return_val_if_fail(gui != NULL, NULL);
+
+ rec = g_new(TEXT_CHUNK_REC, 1);
+ rec->overflow[0] = 0;
+ rec->overflow[1] = (char) LINE_CMD_OVERFLOW;
+ rec->pos = 0;
+ rec->lines = 0;
+
+ if (gui->cur_line != NULL && gui->cur_line->text != NULL) {
+ /* create a link to new block from the old block */
+ buffer = gui->cur_text->buffer + gui->cur_text->pos;
+ *buffer++ = 0; *buffer++ = (char) LINE_CMD_CONTINUE;
+
+ ptr = rec->buffer;
+ memcpy(buffer, &ptr, sizeof(char *));
+ }
+
+ gui->cur_text = rec;
+ gui->text_chunks = g_slist_append(gui->text_chunks, rec);
+ return rec;
}
static void text_chunk_free(GUI_WINDOW_REC *gui, TEXT_CHUNK_REC *chunk)
{
- g_return_if_fail(gui != NULL);
- g_return_if_fail(chunk != NULL);
+ g_return_if_fail(gui != NULL);
+ g_return_if_fail(chunk != NULL);
- gui->text_chunks = g_slist_remove(gui->text_chunks, chunk);
- g_free(chunk);
+ gui->text_chunks = g_slist_remove(gui->text_chunks, chunk);
+ g_free(chunk);
}
static void remove_first_line(WINDOW_REC *window)
{
- GUI_WINDOW_REC *gui;
- TEXT_CHUNK_REC *chunk;
-
- g_return_if_fail(window != NULL);
-
- gui = WINDOW_GUI(window);
- chunk = gui->text_chunks->data;
-
- if (--chunk->lines == 0)
- text_chunk_free(gui, chunk);
-
- if (gui->startline->prev == NULL)
- {
- gui->startline = gui->startline->next;
- gui->subline = 0;
- }
- if (gui->bottom_startline->prev == NULL)
- {
- gui->bottom_startline = gui->bottom_startline->next;
- gui->bottom_subline = 0;
- }
-
- window->lines--;
- g_mem_chunk_free(gui->line_chunk, gui->lines->data);
- gui->lines = g_list_remove(gui->lines, gui->lines->data);
-
- if (gui->startline->prev == NULL && is_window_visible(window))
- gui_window_redraw(window);
+ GUI_WINDOW_REC *gui;
+ TEXT_CHUNK_REC *chunk;
+
+ g_return_if_fail(window != NULL);
+
+ gui = WINDOW_GUI(window);
+ chunk = gui->text_chunks->data;
+
+ if (--chunk->lines == 0)
+ text_chunk_free(gui, chunk);
+
+ if (gui->startline->prev == NULL) {
+ /* first line in screen removed */
+ gui->startline = gui->startline->next;
+ gui->subline = 0;
+ }
+ if (gui->bottom_startline->prev == NULL) {
+ /* bottom line removed (shouldn't happen?) */
+ gui->bottom_startline = gui->bottom_startline->next;
+ gui->bottom_subline = 0;
+ }
+
+ window->lines--;
+ g_mem_chunk_free(gui->line_chunk, gui->lines->data);
+ gui->lines = g_list_remove(gui->lines, gui->lines->data);
+
+ if (gui->startline->prev == NULL && is_window_visible(window))
+ gui_window_redraw(window);
+}
+
+static void get_colors(int flags, int *fg, int *bg)
+{
+ if (flags & PRINTFLAG_MIRC_COLOR) {
+ /* mirc colors */
+ *fg = *fg < 0 || *fg > 16 ?
+ current_theme->default_color : mirc_colors[*fg];
+ *bg = *bg < 0 || *bg > 16 ? 0 : mirc_colors[*bg];
+ } else {
+ /* default colors */
+ *fg = *fg < 0 || *fg > 15 ?
+ current_theme->default_color : *fg;
+ *bg = *bg < 0 || *bg > 15 ? 0 : *bg;
+
+ if (*fg > 8) *fg -= 8;
+ }
+
+ if (flags & PRINTFLAG_REVERSE) {
+ int tmp;
+
+ tmp = *fg; *fg = *bg; *bg = tmp;
+ }
+
+ if (*fg == 8) *fg |= ATTR_COLOR8;
+ if (flags & PRINTFLAG_BOLD) *fg |= 8;
+ if (flags & PRINTFLAG_UNDERLINE) *fg |= ATTR_UNDERLINE;
+ if (flags & PRINTFLAG_BLINK) *bg |= 0x80;
}
-static void get_colors(gint flags, gint *fg, gint *bg)
+static void linebuf_add(GUI_WINDOW_REC *gui, char *str, int len)
{
- if (flags & PRINTFLAG_MIRC_COLOR)
- {
- /* mirc colors */
- *fg = *fg < 0 || *fg > 16 ?
- current_theme->default_color : mirc_colors[*fg];
- *bg = *bg < 0 || *bg > 16 ? 0 : mirc_colors[*bg];
- }
- else
- {
- /* default colors */
- *fg = *fg < 0 || *fg > 15 ?
- current_theme->default_color : *fg;
- *bg = *bg < 0 || *bg > 15 ? 0 : *bg;
-
- if (*fg > 8) *fg -= 8;
- }
-
- if (flags & PRINTFLAG_REVERSE)
- {
- gint tmp;
-
- tmp = *fg; *fg = *bg; *bg = tmp;
- }
-
- if (*fg == 8) *fg |= ATTR_COLOR8;
- if (flags & PRINTFLAG_BOLD) *fg |= 8;
- if (flags & PRINTFLAG_UNDERLINE) *fg |= ATTR_UNDERLINE;
- if (flags & PRINTFLAG_BLINK) *bg |= 0x80;
+ int left;
+
+ if (len == 0) return;
+
+ while (gui->cur_text->pos + len >= TEXT_CHUNK_USABLE_SIZE) {
+ left = TEXT_CHUNK_USABLE_SIZE - gui->cur_text->pos;
+ if (str[left-1] == 0) left--; /* don't split the commands */
+
+ memcpy(gui->cur_text->buffer + gui->cur_text->pos, str, left);
+ gui->cur_text->pos += left;
+
+ create_text_chunk(gui);
+ len -= left; str += left;
+ }
+
+ memcpy(gui->cur_text->buffer + gui->cur_text->pos, str, len);
+ gui->cur_text->pos += len;
}
-static void linebuf_add(GUI_WINDOW_REC *gui, gchar *str, gint len)
+static void line_add_colors(GUI_WINDOW_REC *gui, int fg, int bg, int flags)
{
- gint left;
-
- if (len == 0) return;
-
- while (gui->cur_text->pos+len >= TEXT_CHUNK_USABLE_SIZE)
- {
- left = TEXT_CHUNK_USABLE_SIZE-gui->cur_text->pos;
- if (str[left-1] == 0) left--; /* don't split the command! */
- memcpy(gui->cur_text->buffer+gui->cur_text->pos, str, left);
- gui->cur_text->pos += left;
- create_text_chunk(gui);
- len -= left; str += left;
- }
-
- memcpy(gui->cur_text->buffer+gui->cur_text->pos, str, len);
- gui->cur_text->pos += len;
+ unsigned char buffer[12];
+ int color, pos;
+
+ color = (fg & 0x0f) | (bg << 4);
+ pos = 0;
+
+ if (((fg & ATTR_COLOR8) == 0 && (fg|(bg << 4)) != gui->last_color) ||
+ ((fg & ATTR_COLOR8) && (fg & 0xf0) != (gui->last_color & 0xf0))) {
+ buffer[pos++] = 0;
+ buffer[pos++] = color;
+ }
+
+ if ((flags & PRINTFLAG_UNDERLINE) != (gui->last_flags & PRINTFLAG_UNDERLINE)) {
+ buffer[pos++] = 0;
+ buffer[pos++] = LINE_CMD_UNDERLINE;
+ }
+ if (fg & ATTR_COLOR8) {
+ buffer[pos++] = 0;
+ buffer[pos++] = LINE_CMD_COLOR8;
+ }
+ if (flags & PRINTFLAG_BEEP) {
+ buffer[pos++] = 0;
+ buffer[pos++] = LINE_CMD_BEEP;
+ }
+ if (flags & PRINTFLAG_INDENT) {
+ buffer[pos++] = 0;
+ buffer[pos++] = LINE_CMD_INDENT;
+ }
+
+ linebuf_add(gui, (char *) buffer, pos);
+
+ gui->last_flags = flags;
+ gui->last_color = fg | (bg << 4);
}
-static void line_add_colors(GUI_WINDOW_REC *gui, gint fg, gint bg, gint flags)
+static void gui_printtext(WINDOW_REC *window, gpointer fgcolor, gpointer bgcolor, gpointer pflags, char *str, gpointer level)
{
- guchar buffer[12];
- gint color, pos;
-
- color = (fg & 0x0f) | (bg << 4);
- pos = 0;
-
- if (((fg & ATTR_COLOR8) == 0 && (fg|(bg << 4)) != gui->last_color) ||
- ((fg & ATTR_COLOR8) && (fg & 0xf0) != (gui->last_color & 0xf0)))
- {
- buffer[pos++] = 0;
- buffer[pos++] = (gchar) color;
- }
-
- if ((flags & PRINTFLAG_UNDERLINE) != (gui->last_flags & PRINTFLAG_UNDERLINE))
- {
- buffer[pos++] = 0;
- buffer[pos++] = LINE_CMD_UNDERLINE;
- }
- if (fg & ATTR_COLOR8)
- {
- buffer[pos++] = 0;
- buffer[pos++] = LINE_CMD_COLOR8;
- }
- if (flags & PRINTFLAG_BEEP)
- {
- buffer[pos++] = 0;
- buffer[pos++] = LINE_CMD_BEEP;
- }
- if (flags & PRINTFLAG_INDENT)
- {
- buffer[pos++] = 0;
- buffer[pos++] = LINE_CMD_INDENT;
- }
-
- linebuf_add(gui, (gchar *) buffer, pos);
-
- gui->last_flags = flags;
- gui->last_color = fg | (bg << 4);
+ GUI_WINDOW_REC *gui;
+ LINE_REC *line;
+ int fg, bg, flags, new_lines, n, visible, ypos;
+
+ g_return_if_fail(window != NULL);
+
+ gui = WINDOW_GUI(window);
+ if (max_textwidget_lines > 0 && max_textwidget_lines <= window->lines)
+ remove_first_line(window);
+
+ visible = is_window_visible(window) && gui->bottom;
+ flags = GPOINTER_TO_INT(pflags);
+ fg = GPOINTER_TO_INT(fgcolor);
+ bg = GPOINTER_TO_INT(bgcolor);
+
+ if (gui->cur_text == NULL)
+ create_text_chunk(gui);
+
+ /* \n can be only at the start of the line.. */
+ if (*str == '\n') {
+ str++;
+ linebuf_add(gui, "\0\x80", 2); /* mark EOL */
+
+ line = create_line(gui, 0);
+ gui_window_newline(gui, visible);
+
+ gui->cur_text->lines++;
+ gui->last_subline = 0;
+ } else {
+ line = gui->cur_line != NULL ? gui->cur_line :
+ create_line(gui, 0);
+ if (line->level == 0) line->level = GPOINTER_TO_INT(level);
+ }
+
+ get_colors(flags, &fg, &bg);
+ line_add_colors(gui, fg, bg, flags);
+ linebuf_add(gui, str, strlen(str));
+ mark_temp_eol(gui->cur_text);
+
+ gui_window_cache_remove(gui, line);
+ new_lines = gui_window_get_linecount(gui, line)-1 - gui->last_subline;
+
+ for (n = 0; n < new_lines; n++)
+ gui_window_newline(gui, visible);
+
+ if (visible) {
+ /* draw the line to screen. */
+ ypos = gui->parent->first_line+gui->ypos-new_lines;
+ if (new_lines > 0) {
+ set_color(0);
+ move(ypos, 0); clrtoeol();
+ }
+ gui_window_line_draw(gui, line, ypos, gui->last_subline, -1);
+ }
+
+ gui->last_subline += new_lines;
}
-static void gui_printtext(WINDOW_REC *window, gpointer fgcolor, gpointer bgcolor, gpointer pflags, gchar *str, gpointer level)
+static void window_clear(GUI_WINDOW_REC *gui)
{
- GUI_WINDOW_REC *gui;
- LINE_REC *line;
- gboolean visible;
- gint fg, bg, flags, lines, n;
-
- g_return_if_fail(window != NULL);
-
- gui = WINDOW_GUI(window);
- if (max_textwidget_lines > 0 && max_textwidget_lines <= window->lines)
- remove_first_line(window);
-
- visible = is_window_visible(window) && gui->bottom;
- flags = GPOINTER_TO_INT(pflags);
- fg = GPOINTER_TO_INT(fgcolor);
- bg = GPOINTER_TO_INT(bgcolor);
-
- if (gui->cur_text == NULL)
- create_text_chunk(gui);
-
- /* \n can be only at the start of the line.. */
- if (*str == '\n')
- {
- linebuf_add(gui, "\0\x80", 2); /* mark EOL */
- line = create_line(gui, 0);
- gui_window_newline(gui, visible);
- str++;
- gui->cur_text->lines++;
- gui->last_subline = 0;
- }
- else
- {
- line = gui->cur_line != NULL ? gui->cur_line :
- create_line(gui, 0);
- if (line->level == 0) line->level = GPOINTER_TO_INT(level);
- }
-
- get_colors(flags, &fg, &bg);
- line_add_colors(gui, fg, bg, flags);
- linebuf_add(gui, str, strlen(str));
-
- /* temporarily mark the end of line. */
- memcpy(gui->cur_text->buffer+gui->cur_text->pos, "\0\x80", 2);
-
- if (visible)
- {
- /* draw the line to screen. */
- lines = gui_window_line_draw(gui, line, gui->parent->first_line+gui->ypos, gui->last_subline, -1);
- }
- else
- {
- /* we still need to update the bottom's position */
- lines = gui_window_get_linecount(gui, line)-1-gui->last_subline;
- for (n = 0; n < lines; n++)
- gui_window_newline(gui, visible);
- }
- if (lines > 0) gui->last_subline += lines;
+ int n;
+
+ for (n = gui->parent->first_line; n <= gui->parent->last_line; n++) {
+ move(n, 0);
+ clrtoeol();
+ }
+ screen_refresh();
}
-static void cmd_clear(gchar *data)
+static void cmd_clear(void)
{
- GUI_WINDOW_REC *gui;
- gint n;
-
- gui = WINDOW_GUI(active_win);
-
- if (is_window_visible(active_win))
- {
- for (n = gui->parent->first_line; n <= gui->parent->last_line; n++)
- {
- move(n, 0);
- clrtoeol();
- }
- screen_refresh();
- }
-
- gui->ypos = -1;
- gui->bottom_startline = gui->startline = g_list_last(gui->lines);
- gui->bottom_subline = gui->subline = gui->last_subline+1;
- gui->empty_linecount = gui->parent->last_line-gui->parent->first_line+1;
- gui->bottom = TRUE;
+ GUI_WINDOW_REC *gui;
+
+ gui = WINDOW_GUI(active_win);
+
+ if (is_window_visible(active_win))
+ window_clear(gui);
+
+ gui->ypos = -1;
+ gui->bottom_startline = gui->startline = g_list_last(gui->lines);
+ gui->bottom_subline = gui->subline = gui->last_subline+1;
+ gui->empty_linecount = gui->parent->last_line-gui->parent->first_line+1;
+ gui->bottom = TRUE;
}
static void sig_printtext_finished(WINDOW_REC *window)
@@ -321,18 +316,18 @@ static void read_settings(void)
void gui_printtext_init(void)
{
- signal_add("gui print text", (SIGNAL_FUNC) gui_printtext);
- command_bind("clear", NULL, (SIGNAL_FUNC) cmd_clear);
- signal_add("print text finished", (SIGNAL_FUNC) sig_printtext_finished);
- signal_add("setup changed", (SIGNAL_FUNC) read_settings);
+ signal_add("gui print text", (SIGNAL_FUNC) gui_printtext);
+ signal_add("print text finished", (SIGNAL_FUNC) sig_printtext_finished);
+ signal_add("setup changed", (SIGNAL_FUNC) read_settings);
+ command_bind("clear", NULL, (SIGNAL_FUNC) cmd_clear);
- read_settings();
+ read_settings();
}
void gui_printtext_deinit(void)
{
- signal_remove("gui print text", (SIGNAL_FUNC) gui_printtext);
- command_unbind("clear", (SIGNAL_FUNC) cmd_clear);
- signal_remove("print text finished", (SIGNAL_FUNC) sig_printtext_finished);
- signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
+ signal_remove("gui print text", (SIGNAL_FUNC) gui_printtext);
+ signal_remove("print text finished", (SIGNAL_FUNC) sig_printtext_finished);
+ signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
+ command_unbind("clear", (SIGNAL_FUNC) cmd_clear);
}
diff --git a/src/fe-text/gui-windows.c b/src/fe-text/gui-windows.c
index 60956cce..64d06e98 100644
--- a/src/fe-text/gui-windows.c
+++ b/src/fe-text/gui-windows.c
@@ -46,6 +46,7 @@ static GUI_WINDOW_REC *gui_window_init(WINDOW_REC *window, MAIN_WINDOW_REC *pare
gui->parent = parent;
gui->bottom = TRUE;
+ gui->line_cache = g_hash_table_new((GHashFunc) g_direct_hash, (GCompareFunc) g_direct_equal);
gui->line_chunk = g_mem_chunk_new("line chunk", sizeof(LINE_REC),
sizeof(LINE_REC)*100, G_ALLOC_AND_FREE);
gui->empty_linecount = parent->last_line-parent->first_line;
@@ -53,8 +54,19 @@ static GUI_WINDOW_REC *gui_window_init(WINDOW_REC *window, MAIN_WINDOW_REC *pare
return gui;
}
+int line_cache_destroy(void *key, LINE_CACHE_REC *cache)
+{
+ g_free_not_null(cache->lines);
+ g_free(cache);
+
+ return TRUE;
+}
+
static void gui_window_deinit(GUI_WINDOW_REC *gui)
{
+ g_hash_table_foreach(gui->line_cache, (GHFunc) line_cache_destroy, NULL);
+ g_hash_table_destroy(gui->line_cache);
+
g_slist_foreach(gui->text_chunks, (GFunc) g_free, NULL);
g_slist_free(gui->text_chunks);
@@ -106,7 +118,7 @@ static void gui_window_destroyed(WINDOW_REC *window)
gui_window_deinit(gui);
window->gui_data = NULL;
- if (mainwindows->next != NULL && parent->active == window)
+ if (parent->active == window && mainwindows->next != NULL)
mainwindow_destroy(parent);
}
@@ -126,322 +138,337 @@ void gui_window_clear(WINDOW_REC *window)
gui_window_redraw(window);
}
-int gui_window_update_bottom(GUI_WINDOW_REC *gui, int lines)
+/* update bottom_startline and bottom_subline of window. */
+static int gui_window_update_bottom(GUI_WINDOW_REC *gui, int lines)
{
- int linecount, last_linecount;
-
- if (gui->bottom_startline == NULL)
- return -1;
+ int linecount, last_linecount;
- while (lines < 0)
- {
- if (gui->bottom_subline > 0)
- gui->bottom_subline--;
- else
- {
- if (gui->bottom_startline->prev == NULL)
+ if (gui->bottom_startline == NULL)
return -1;
- gui->bottom_startline = gui->bottom_startline->prev;
- linecount = gui_window_get_linecount(gui, gui->bottom_startline->data);
- gui->bottom_subline = linecount-1;
- }
- lines++;
- }
+ for (; lines < 0; lines++) {
+ if (gui->bottom_subline > 0) {
+ gui->bottom_subline--;
+ continue;
+ }
- last_linecount = linecount = -1;
- while (lines > 0)
- {
- if (linecount == -1)
- last_linecount = linecount = gui_window_get_linecount(gui, gui->bottom_startline->data);
+ if (gui->bottom_startline->prev == NULL)
+ return -1;
+ gui->bottom_startline = gui->bottom_startline->prev;
- if (linecount > gui->bottom_subline+1)
- gui->bottom_subline++;
- else
- {
- gui->bottom_subline = 0;
- linecount = -1;
+ linecount = gui_window_get_linecount(gui, gui->bottom_startline->data);
+ gui->bottom_subline = linecount-1;
+ }
+
+ last_linecount = -1;
+ for (; lines > 0; lines--) {
+ last_linecount = linecount =
+ gui_window_get_linecount(gui, gui->bottom_startline->data);
- if (gui->bottom_startline->next == NULL)
- break;
- gui->bottom_startline = gui->bottom_startline->next;
+ if (linecount > gui->bottom_subline+1)
+ gui->bottom_subline++;
+ else {
+ gui->bottom_subline = 0;
+ if (gui->bottom_startline->next == NULL)
+ break;
+ gui->bottom_startline = gui->bottom_startline->next;
+ }
+ lines--;
}
- lines--;
- }
- return last_linecount;
+ return last_linecount;
}
-void gui_window_newline(GUI_WINDOW_REC *gui, gboolean visible)
+void gui_window_newline(GUI_WINDOW_REC *gui, int visible)
{
- gboolean last_line;
- gint linecount;
+ int lines;
- g_return_if_fail(gui != NULL);
+ g_return_if_fail(gui != NULL);
- gui->xpos = 0;
- last_line = gui->ypos >= gui->parent->last_line-gui->parent->first_line;
+ gui->xpos = 0;
- if (gui->empty_linecount > 0)
- {
- /* window buffer height isn't even the size of the screen yet */
- gui->empty_linecount--;
- linecount = gui_window_get_linecount(gui, gui->startline->data);
- }
- else
- {
- linecount = gui_window_update_bottom(gui, 1);
- }
+ if (gui->empty_linecount > 0) {
+ /* window buffer height isn't even the size of the screen yet */
+ gui->empty_linecount--;
+ gui->ypos++;
+ return;
+ }
- if (!last_line || !gui->bottom)
- {
- gui->ypos++;
- }
- else if (gui->bottom)
- {
- if (gui->subline >= linecount)
- {
- /* after screen gets full after /CLEAR we end up here.. */
- gui->startline = gui->startline->next;
- gui->subline = 0;
+ lines = gui_window_update_bottom(gui, 1);
- linecount = gui_window_update_bottom(gui, 1);
+ if (!gui->bottom) {
+ gui->ypos++;
+ return;
}
- if (linecount > 1+gui->subline)
- gui->subline++;
- else
- {
- gui->startline = gui->startline->next;
- gui->subline = 0;
+ if (gui->subline >= lines) {
+ /* after screen gets full after /CLEAR we end up here.. */
+ gui->startline = gui->startline->next;
+ gui->subline = 0;
+
+ lines = gui_window_update_bottom(gui, 1);
}
- if (visible)
- {
- scroll_up(gui->parent->first_line, gui->parent->last_line);
- move(gui->parent->last_line, 0); clrtoeol();
+ if (lines > 1+gui->subline)
+ gui->subline++;
+ else {
+ gui->startline = gui->startline->next;
+ gui->subline = 0;
+ }
+
+ if (visible) {
+ scroll_up(gui->parent->first_line, gui->parent->last_line);
+ move(gui->parent->last_line, 0); clrtoeol();
}
- }
}
-/* get number of real lines that line record takes - this really should share
- at least some code with gui_window_line_draw().. */
-gint gui_window_get_linecount(GUI_WINDOW_REC *gui, LINE_REC *line)
+static LINE_CACHE_REC *gui_window_line_cache(GUI_WINDOW_REC *gui, LINE_REC *line)
{
- gchar *ptr, *last_space_ptr, *tmp;
- gint lines, xpos, indent_pos, last_space;
+ LINE_CACHE_REC *rec;
+ LINE_CACHE_SUB_REC *sub;
+ GSList *lines;
+ unsigned char *ptr, *last_space_ptr;
+ int xpos, pos, indent_pos, last_space, color;
+
+ g_return_val_if_fail(line->text != NULL, NULL);
+
+ rec = g_new(LINE_CACHE_REC, 1);
+
+ xpos = 0; color = 0; indent_pos = DEFAULT_INDENT_POS;
+ last_space = 0; last_space_ptr = NULL;
+
+ rec->count = 1; lines = NULL;
+ for (ptr = (unsigned char *) line->text;;) {
+ if (*ptr == '\0') {
+ /* command */
+ ptr++;
+ if (*ptr == LINE_CMD_EOL)
+ break;
+
+ if (*ptr == LINE_CMD_CONTINUE) {
+ char *tmp;
+
+ memcpy(&tmp, ptr+1, sizeof(char *));
+ ptr = tmp;
+ continue;
+ }
+
+ if ((*ptr & 0x80) == 0) {
+ /* set color */
+ color = (color & ATTR_UNDERLINE) | *ptr;
+ } else switch (*ptr) {
+ case LINE_CMD_OVERFLOW:
+ g_error("buffer overflow!");
+ case LINE_CMD_UNDERLINE:
+ color ^= ATTR_UNDERLINE;
+ break;
+ case LINE_CMD_COLOR8:
+ color &= 0xfff0;
+ color |= 8|ATTR_COLOR8;
+ break;
+ case LINE_CMD_INDENT:
+ /* set indentation position here - don't do
+ it if we're too close to right border */
+ if (xpos < COLS-5) indent_pos = xpos;
+ break;
+ }
+
+ ptr++;
+ continue;
+ }
- g_return_val_if_fail(gui != NULL, -1);
- g_return_val_if_fail(line != NULL, -1);
+ if (xpos == COLS) {
+ xpos = indent_pos;
- if (line->text == NULL)
- return 0;
+ if (last_space > indent_pos && last_space > 10) {
+ /* go back to last space */
+ ptr = last_space_ptr;
+ while (*ptr == ' ') ptr++;
+ }
- xpos = 0; lines = 1; indent_pos = DEFAULT_INDENT_POS;
- last_space = 0; last_space_ptr = NULL;
- for (ptr = line->text;; ptr++)
- {
- if (*ptr == '\0')
- {
- /* command */
- ptr++;
- switch ((guchar) *ptr)
- {
- case LINE_CMD_OVERFLOW:
- g_error("buffer overflow!");
- case LINE_CMD_EOL:
- return lines;
- case LINE_CMD_CONTINUE:
- memcpy(&tmp, ptr+1, sizeof(gchar *));
- ptr = tmp-1;
- break;
- case LINE_CMD_INDENT:
- indent_pos = xpos;
- break;
- }
- continue;
- }
+ sub = g_new(LINE_CACHE_SUB_REC, 1);
+ sub->start = ptr;
+ sub->indent = indent_pos;
+ sub->color = color;
- if (xpos == COLS)
- {
- xpos = indent_pos >= COLS-5 ? DEFAULT_INDENT_POS : indent_pos;
+ lines = g_slist_append(lines, sub);
+ rec->count++;
- if (last_space > indent_pos && last_space > 10)
- {
- ptr = last_space_ptr;
- while (*ptr == ' ') ptr++;
- }
+ last_space = 0;
+ continue;
+ }
- last_space = 0;
- lines++;
- ptr--;
- continue;
+ xpos++;
+ if (*ptr++ == ' ') {
+ last_space = xpos-1;
+ last_space_ptr = ptr;
+ }
}
- xpos++;
- if (*ptr == ' ')
- {
- last_space = xpos-1;
- last_space_ptr = ptr+1;
+ if (rec->count < 2)
+ rec->lines = NULL;
+ else {
+ rec->lines = g_new(LINE_CACHE_SUB_REC, rec->count-1);
+ for (pos = 0; lines != NULL; pos++) {
+ memcpy(&rec->lines[pos], lines->data, sizeof(LINE_CACHE_SUB_REC));
+
+ g_free(lines->data);
+ lines = g_slist_remove(lines, lines->data);
+ }
}
- }
+
+ g_hash_table_insert(gui->line_cache, line, rec);
+ return rec;
}
-/* draw line - ugly code.. */
-gint gui_window_line_draw(GUI_WINDOW_REC *gui, LINE_REC *line, gint ypos, gint skip, gint max)
+void gui_window_cache_remove(GUI_WINDOW_REC *gui, LINE_REC *line)
{
- gchar *ptr, *last_space_ptr, *tmp;
- gint lines, xpos, color, indent_pos, last_space, last_space_color;
+ LINE_CACHE_REC *cache;
- g_return_val_if_fail(gui != NULL, -1);
- g_return_val_if_fail(line != NULL, -1);
+ g_return_if_fail(gui != NULL);
+ g_return_if_fail(line != NULL);
- if (line->text == NULL)
- return 0;
-
- move(ypos, 0);
- xpos = 0; color = 0; lines = -1; indent_pos = DEFAULT_INDENT_POS;
- last_space = last_space_color = 0; last_space_ptr = NULL;
- for (ptr = line->text;; ptr++)
- {
- if (*ptr == '\0')
- {
- /* command */
- ptr++;
- if ((*ptr & 0x80) == 0)
- {
- /* set color */
- color = (color & ATTR_UNDERLINE) | *ptr;
- }
- else switch ((guchar) *ptr)
- {
- case LINE_CMD_OVERFLOW:
- g_error("buffer overflow!");
- case LINE_CMD_EOL:
- return lines;
- case LINE_CMD_CONTINUE:
- memcpy(&tmp, ptr+1, sizeof(gchar *));
- ptr = tmp-1;
- break;
- case LINE_CMD_UNDERLINE:
- color ^= ATTR_UNDERLINE;
- break;
- case LINE_CMD_COLOR8:
- color &= 0xfff0;
- color |= 8|ATTR_COLOR8;
- break;
- case LINE_CMD_BEEP:
- beep();
- break;
- case LINE_CMD_INDENT:
- indent_pos = xpos;
- break;
- }
- set_color(color);
- continue;
+ cache = g_hash_table_lookup(gui->line_cache, line);
+ if (cache != NULL) {
+ g_hash_table_remove(gui->line_cache, line);
+ g_free_not_null(cache->lines);
+ g_free(cache);
}
+}
- if (xpos == COLS)
- {
- xpos = indent_pos >= COLS-5 ? DEFAULT_INDENT_POS : indent_pos;
+int gui_window_get_linecount(GUI_WINDOW_REC *gui, LINE_REC *line)
+{
+ LINE_CACHE_REC *cache;
- if (last_space > indent_pos && last_space > 10)
- {
- /* remove the last word */
- if (!skip)
- {
- move(ypos, last_space);
- set_color(0);
- clrtoeol();
- }
+ g_return_val_if_fail(gui != NULL, -1);
+ g_return_val_if_fail(line != NULL, -1);
- /* skip backwards to draw the line again. */
- ptr = last_space_ptr;
- color = last_space_color;
- if (!skip) set_color(color);
- while (*ptr == ' ') ptr++;
- }
- last_space = 0;
+ cache = g_hash_table_lookup(gui->line_cache, line);
+ if (cache == NULL)
+ cache = gui_window_line_cache(gui, line);
- if (skip > 0)
- {
- if (--skip == 0) set_color(color);
- }
- else
- {
- if (lines == max)
- return lines;
- if (max != -1)
- ypos++;
- else
- {
- gui_window_newline(gui, TRUE);
- ypos = gui->parent->first_line+gui->ypos;
- }
- lines++;
- }
- move(ypos, indent_pos);
+ return cache->count;
+}
- /* we could have \0.. */
- ptr--;
- continue;
- }
+static void single_line_draw(GUI_WINDOW_REC *gui, int ypos, LINE_CACHE_SUB_REC *rec, const char *text, const char *text_end)
+{
+ char *tmp;
+ int xpos, color;
- xpos++;
- if (*ptr == ' ')
- {
- last_space = xpos-1;
- last_space_color = color;
- last_space_ptr = ptr+1;
+ if (rec == NULL) {
+ xpos = 0; color = 0;
+ } else {
+ xpos = rec->indent;
+ color = rec->color;
}
- if (skip) continue;
- if (lines == -1) lines = 0;
+ move(ypos, xpos);
+ while (text != text_end) {
+ if (*text == '\0') {
+ /* command */
+ text++;
+ if ((*text & 0x80) == 0) {
+ /* set color */
+ color = (color & ATTR_UNDERLINE) | *text;
+ } else if (*text == (char) LINE_CMD_CONTINUE) {
+ /* jump to next block */
+ memcpy(&tmp, text+1, sizeof(char *));
+ text = tmp;
+ continue;
+ } else switch ((unsigned char) *text) {
+ case LINE_CMD_OVERFLOW:
+ g_error("buffer overflow!");
+ case LINE_CMD_EOL:
+ return;
+ case LINE_CMD_UNDERLINE:
+ color ^= ATTR_UNDERLINE;
+ break;
+ case LINE_CMD_COLOR8:
+ color &= 0xfff0;
+ color |= 8|ATTR_COLOR8;
+ break;
+ }
+ set_color(color);
+ text++;
+ continue;
+ }
- if ((guchar) *ptr >= 32)
- addch((guchar) *ptr);
- else
- {
- /* low-ascii */
- set_color(ATTR_REVERSE);
- addch(*ptr+'A'-1);
- set_color(color);
+ if (xpos == COLS) {
+ /* there should be only spaces left */
+ text++;
+ continue;
+ }
+
+ if ((unsigned char) *text >= 32)
+ addch((unsigned char) *text);
+ else {
+ /* low-ascii */
+ set_color(ATTR_REVERSE);
+ addch(*text+'A'-1);
+ set_color(color);
+ }
+ text++;
}
- }
+}
+
+int gui_window_line_draw(GUI_WINDOW_REC *gui, LINE_REC *line, int ypos, int skip, int max)
+{
+ LINE_CACHE_REC *cache;
+ LINE_CACHE_SUB_REC *sub;
+ char *pos, *next_pos;
+ int n;
+
+ g_return_val_if_fail(gui != NULL, -1);
+ g_return_val_if_fail(line != NULL, -1);
+
+ cache = g_hash_table_lookup(gui->line_cache, line);
+ if (cache == NULL)
+ cache = gui_window_line_cache(gui, line);
+
+ if (max < 0) max = cache->count;
+
+ for (n = skip; n < cache->count && max > 0; n++, ypos++, max--) {
+ sub = n == 0 ? NULL : &cache->lines[n-1];
+ pos = sub == NULL ? line->text : sub->start;
+ next_pos = (n+1 < cache->count) ?
+ cache->lines[n].start : NULL;
+ single_line_draw(gui, ypos, sub, pos, next_pos);
+ }
+
+ return cache->count;
}
void gui_window_redraw(WINDOW_REC *window)
{
- GUI_WINDOW_REC *gui;
- GList *line;
- gint ypos, lines, skip, max;
+ GUI_WINDOW_REC *gui;
+ GList *line;
+ int ypos, lines, skip, max;
- g_return_if_fail(window != NULL);
+ g_return_if_fail(window != NULL);
- gui = WINDOW_GUI(window);
+ gui = WINDOW_GUI(window);
- for (ypos = gui->parent->first_line; ypos <= gui->parent->last_line; ypos++)
- {
+ /* clear the lines first */
set_color(0);
- move(ypos, 0);
- clrtoeol();
- }
+ for (ypos = gui->parent->first_line; ypos <= gui->parent->last_line; ypos++) {
+ move(ypos, 0);
+ clrtoeol();
+ }
- skip = gui->subline;
- ypos = gui->parent->first_line;
- for (line = gui->startline; line != NULL; line = line->next)
- {
- LINE_REC *rec = line->data;
+ skip = gui->subline;
+ ypos = gui->parent->first_line;
+ for (line = gui->startline; line != NULL; line = line->next) {
+ LINE_REC *rec = line->data;
- max = gui->parent->last_line - ypos;
- if (max < 0) break;
+ max = gui->parent->last_line - ypos+1;
+ if (max < 0) break;
- lines = gui_window_line_draw(gui, rec, ypos, skip, max);
- skip = 0;
+ lines = gui_window_line_draw(gui, rec, ypos, skip, max);
+ ypos += lines-skip;
+ skip = 0;
+ }
- ypos += lines+1;
- }
- screen_refresh();
+ screen_refresh();
}
static void gui_window_scroll_up(GUI_WINDOW_REC *gui, gint lines)
@@ -579,6 +606,8 @@ static void signal_window_changed(WINDOW_REC *window)
{
g_return_if_fail(window != NULL);
+ if (quitting) return;
+
if (is_window_visible(window)) {
/* already visible, great! */
active_mainwin = WINDOW_GUI(window)->parent;
@@ -674,6 +703,8 @@ static void gui_window_horiz_resize(WINDOW_REC *window)
gui = WINDOW_GUI(window);
if (gui->lines == NULL) return;
+ g_hash_table_foreach_remove(gui->line_cache, (GHRFunc) line_cache_destroy, NULL);
+
linecount = gui_window_get_linecount(gui, g_list_last(gui->lines)->data);
gui->last_subline = linecount-1;
@@ -703,7 +734,8 @@ void gui_window_resize(WINDOW_REC *window, int ychange, int xchange)
gui = WINDOW_GUI(window);
if (xchange) {
- /* window width changed, we'll need to recalculate a few things.. */
+ /* window width changed, we'll need to recalculate a
+ few things.. */
gui_window_horiz_resize(window);
return;
}
diff --git a/src/fe-text/gui-windows.h b/src/fe-text/gui-windows.h
index 28dde1e9..622b5f4a 100644
--- a/src/fe-text/gui-windows.h
+++ b/src/fe-text/gui-windows.h
@@ -23,6 +23,17 @@ enum {
};
typedef struct {
+ char *start;
+ int indent;
+ int color;
+} LINE_CACHE_SUB_REC;
+
+typedef struct {
+ int count; /* number of real lines */
+ LINE_CACHE_SUB_REC *lines;
+} LINE_CACHE_REC;
+
+typedef struct {
/* text in the line. \0 means that the next char will be a
color or command. <= 127 = color or if 8.bit is set, the
first 7 bits are the command. See LINE_CMD_xxxx. */
@@ -45,6 +56,7 @@ typedef struct {
GMemChunk *line_chunk;
GSList *text_chunks;
GList *lines;
+ GHashTable *line_cache;
LINE_REC *cur_line;
TEXT_CHUNK_REC *cur_text;
@@ -74,6 +86,7 @@ GList *gui_window_find_text(WINDOW_REC *window, char *text, GList *startline, in
/* get number of real lines that line record takes */
int gui_window_get_linecount(GUI_WINDOW_REC *gui, LINE_REC *line);
+void gui_window_cache_remove(GUI_WINDOW_REC *gui, LINE_REC *line);
int gui_window_line_draw(GUI_WINDOW_REC *gui, LINE_REC *line, int ypos, int skip, int max);
void gui_window_clear(WINDOW_REC *window);
@@ -82,8 +95,7 @@ void gui_window_resize(WINDOW_REC *window, int ychange, int xchange);
void gui_window_reparent(WINDOW_REC *window, MAIN_WINDOW_REC *parent);
void window_update_prompt(WINDOW_REC *window);
-void gui_window_newline(GUI_WINDOW_REC *gui, gboolean visible);
-int gui_window_update_bottom(GUI_WINDOW_REC *gui, int lines);
+void gui_window_newline(GUI_WINDOW_REC *gui, int visible);
void gui_window_scroll(WINDOW_REC *window, int lines);
#endif
diff --git a/src/fe-text/irssi.c b/src/fe-text/irssi.c
index 2c95b87d..ee8e3bf5 100644
--- a/src/fe-text/irssi.c
+++ b/src/fe-text/irssi.c
@@ -19,6 +19,7 @@
*/
#include "module.h"
+#include "module-formats.h"
#include "args.h"
#include "signals.h"
#include "core.h"
@@ -26,6 +27,7 @@
#include "irc-core.h"
#include "fe-common-core.h"
#include "fe-common-irc.h"
+#include "themes.h"
#include "screen.h"
#include "gui-entry.h"
@@ -82,6 +84,8 @@ static void textui_init(void)
irc_init();
fe_common_core_init();
fe_common_irc_init();
+
+ theme_register(gui_text_formats);
signal_add("gui exit", (SIGNAL_FUNC) sig_exit);
}
@@ -91,11 +95,11 @@ static void textui_finish_init(void)
screen_refresh_freeze();
gui_entry_init();
- mainwindows_init();
gui_printtext_init();
gui_readline_init();
gui_special_vars_init();
gui_textwidget_init();
+ mainwindows_init();
gui_windows_init();
statusbar_init();
@@ -123,11 +127,13 @@ static void textui_deinit(void)
statusbar_deinit();
gui_printtext_deinit();
gui_readline_deinit();
- mainwindows_deinit();
gui_windows_deinit();
+ mainwindows_deinit();
gui_entry_deinit();
deinit_screen();
+ theme_unregister();
+
fe_common_irc_deinit();
fe_common_core_deinit();
irc_deinit();
diff --git a/src/fe-text/mainwindows.c b/src/fe-text/mainwindows.c
index 35bf4ecd..e30c0eb4 100644
--- a/src/fe-text/mainwindows.c
+++ b/src/fe-text/mainwindows.c
@@ -347,6 +347,17 @@ static void mainwindows_resize_bigger(int ychange, int xchange)
g_slist_free(sorted);
}
+void mainwindows_resize_horiz(int xchange)
+{
+ GSList *tmp;
+
+ for (tmp = mainwindows; tmp != NULL; tmp = tmp->next) {
+ MAIN_WINDOW_REC *rec = tmp->data;
+
+ mainwindow_resize(rec, 0, xchange);
+ }
+}
+
void mainwindows_resize(int ychange, int xchange)
{
screen_refresh_freeze();
@@ -354,6 +365,8 @@ void mainwindows_resize(int ychange, int xchange)
mainwindows_resize_smaller(ychange, xchange);
else if (ychange > 0)
mainwindows_resize_bigger(ychange, xchange);
+ else if (xchange != 0)
+ mainwindows_resize_horiz(xchange);
irssi_redraw();
screen_refresh_thaw();
@@ -595,6 +608,9 @@ void mainwindows_init(void)
void mainwindows_deinit(void)
{
+ while (mainwindows != NULL)
+ mainwindow_destroy(mainwindows->data);
+
command_unbind("window grow", (SIGNAL_FUNC) cmd_window_grow);
command_unbind("window shrink", (SIGNAL_FUNC) cmd_window_shrink);
command_unbind("window size", (SIGNAL_FUNC) cmd_window_size);
diff --git a/src/fe-text/module-formats.c b/src/fe-text/module-formats.c
index 9b38fecb..f81088df 100644
--- a/src/fe-text/module-formats.c
+++ b/src/fe-text/module-formats.c
@@ -23,11 +23,13 @@
FORMAT_REC gui_text_formats[] =
{
- { MODULE_NAME, "Text user interface", 0 },
+ { MODULE_NAME, "Text user interface", 0 },
- { "lastlog_start", "%_Lastlog:", 0 },
- { "lastlog_end", "%_End of Lastlog", 0 },
+ { "lastlog_start", "%_Lastlog:", 0 },
+ { "lastlog_end", "%_End of Lastlog", 0 },
- { "window_too_small", "Not enough room to resize this window", 0 },
- { "cant_hide_last", "You can't hide the last window", 0 }
+ { "window_too_small", "Not enough room to resize this window", 0 },
+ { "cant_hide_last", "You can't hide the last window", 0 },
+
+ { NULL, NULL, 0 }
};
diff --git a/src/fe-text/module-formats.h b/src/fe-text/module-formats.h
index 39d29182..2af040eb 100644
--- a/src/fe-text/module-formats.h
+++ b/src/fe-text/module-formats.h
@@ -11,6 +11,3 @@ enum {
};
extern FORMAT_REC gui_text_formats[];
-#define MODULE_FORMATS gui_text_formats
-
-#include "printformat.h"
diff --git a/src/irc/core/Makefile.am b/src/irc/core/Makefile.am
index e0d49197..fa5f5f1f 100644
--- a/src/irc/core/Makefile.am
+++ b/src/irc/core/Makefile.am
@@ -12,6 +12,7 @@ libirc_core_la_SOURCES = \
channels-query.c \
channels-setup.c \
channel-events.c \
+ channel-rejoin.c \
ignore.c \
irc.c \
irc-core.c \
diff --git a/src/irc/core/channel-events.c b/src/irc/core/channel-events.c
index 8de80cbd..02af3c0f 100644
--- a/src/irc/core/channel-events.c
+++ b/src/irc/core/channel-events.c
@@ -54,7 +54,7 @@ static void event_target_unavailable(const char *data, IRC_SERVER_REC *server)
params = event_get_params(data, 2, NULL, &channel);
if (ischannel(*channel)) {
- /* channel is unavailable. */
+ /* channel is unavailable - try to join again a bit later */
event_cannot_join(data, server);
}
diff --git a/src/irc/core/channel-rejoin.c b/src/irc/core/channel-rejoin.c
new file mode 100644
index 00000000..89abae0c
--- /dev/null
+++ b/src/irc/core/channel-rejoin.c
@@ -0,0 +1,104 @@
+/*
+ channel-rejoin.c : rejoin to channel if it's "temporarily unavailable"
+ this has nothing to do with autorejoin if kicked
+
+ 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 "signals.h"
+
+#include "misc.h"
+#include "channels.h"
+#include "irc.h"
+
+#define REJOIN_TIMEOUT (1000*60*5) /* try to rejoin every 5 minutes */
+
+static int rejoin_tag;
+
+static void channel_rejoin(IRC_SERVER_REC *server, const char *channel)
+{
+ CHANNEL_REC *chanrec;
+ char *str;
+
+ chanrec = channel_find(server, channel);
+ str = chanrec == NULL || chanrec->key == NULL || *chanrec->key == '\0' ?
+ g_strdup(channel) : g_strdup_printf("%s %s", channel, chanrec->key);
+
+ server->rejoin_channels = g_slist_append(server->rejoin_channels, str);
+}
+
+static void event_target_unavailable(const char *data, IRC_SERVER_REC *server)
+{
+ char *params, *channel;
+
+ g_return_if_fail(data != NULL);
+
+ params = event_get_params(data, 2, NULL, &channel);
+ if (ischannel(*channel)) {
+ /* channel is unavailable - try to join again a bit later */
+ channel_rejoin(server, channel);
+ }
+
+ g_free(params);
+}
+
+static void sig_disconnected(IRC_SERVER_REC *server)
+{
+ g_slist_foreach(server->rejoin_channels, (GFunc) g_free, NULL);
+ g_slist_free(server->rejoin_channels);
+}
+
+static void server_rejoin_channels(IRC_SERVER_REC *server)
+{
+ while (server->rejoin_channels != NULL) {
+ char *channel = server->rejoin_channels->data;
+
+ channels_join(server, channel, TRUE);
+ server->rejoin_channels = g_slist_remove(server->rejoin_channels, channel);
+ }
+}
+
+static int sig_rejoin(void)
+{
+ GSList *tmp;
+
+ for (tmp = servers; tmp != NULL; tmp = tmp->next) {
+ IRC_SERVER_REC *rec = tmp->data;
+
+ if (irc_server_check(rec))
+ server_rejoin_channels(rec);
+ }
+
+ return TRUE;
+}
+
+void channel_rejoin_init(void)
+{
+ rejoin_tag = g_timeout_add(REJOIN_TIMEOUT, (GSourceFunc) sig_rejoin, NULL);
+
+ signal_add_first("event 437", (SIGNAL_FUNC) event_target_unavailable);
+ signal_add("server disconnected", (SIGNAL_FUNC) sig_disconnected);
+}
+
+void channel_rejoin_deinit(void)
+{
+ g_source_remove(rejoin_tag);
+
+ signal_remove("event 437", (SIGNAL_FUNC) event_target_unavailable);
+ signal_remove("server disconnected", (SIGNAL_FUNC) sig_disconnected);
+}
diff --git a/src/irc/core/channels.c b/src/irc/core/channels.c
index 4c50ab7b..6943952e 100644
--- a/src/irc/core/channels.c
+++ b/src/irc/core/channels.c
@@ -38,6 +38,9 @@ void channels_query_deinit(void);
void channel_events_init(void);
void channel_events_deinit(void);
+void channel_rejoin_init(void);
+void channel_rejoin_deinit(void);
+
void massjoin_init(void);
void massjoin_deinit(void);
@@ -159,7 +162,7 @@ void channels_join(IRC_SERVER_REC *server, const char *data, int automatic)
SETUP_CHANNEL_REC *schannel;
CHANNEL_REC *chanrec;
GString *outchans, *outkeys;
- char *params, *channels, *keys;
+ char *params, *channels, *keys, *key;
char **chanlist, **keylist, **tmp, **tmpkey, *channel;
int use_keys;
@@ -187,15 +190,17 @@ void channels_join(IRC_SERVER_REC *server, const char *data, int automatic)
schannel = channels_setup_find(channel, server->connrec->ircnet);
g_string_sprintfa(outchans, "%s,", channel);
- if (schannel == NULL || schannel->password == NULL)
- g_string_sprintfa(outkeys, "%s,", get_join_key(*tmpkey));
- else {
+ if (schannel == NULL || schannel->password == NULL) {
+ key = *tmpkey == NULL || **tmpkey == '\0' ? NULL : *tmpkey;
+ } else {
/* get password from setup record */
use_keys = TRUE;
- g_string_sprintfa(outkeys, "%s,", schannel->password);
+ key = schannel->password;
}
- channel_create(server, channel + (channel[0] == '!' && channel[1] == '!'), automatic);
+ g_string_sprintfa(outkeys, "%s,", get_join_key(key));
+ chanrec = channel_create(server, channel + (channel[0] == '!' && channel[1] == '!'), automatic);
+ if (key != NULL) chanrec->key = g_strdup(key);
}
g_free(channel);
@@ -204,6 +209,8 @@ void channels_join(IRC_SERVER_REC *server, const char *data, int automatic)
}
if (outchans->len > 0) {
+ g_string_truncate(outchans, outchans->len-1);
+ g_string_truncate(outkeys, outkeys->len-1);
irc_send_cmdv(server, use_keys ? "JOIN %s %s" : "JOIN %s",
outchans->str, outkeys->str);
}
@@ -220,6 +227,7 @@ void channels_join(IRC_SERVER_REC *server, const char *data, int automatic)
void channels_init(void)
{
channel_events_init();
+ channel_rejoin_init();
channels_query_init();
channels_setup_init();
@@ -233,6 +241,7 @@ void channels_init(void)
void channels_deinit(void)
{
channel_events_deinit();
+ channel_rejoin_deinit();
channels_query_deinit();
channels_setup_deinit();
diff --git a/src/irc/core/irc-log.c b/src/irc/core/irc-log.c
index 9871ee64..accf6014 100644
--- a/src/irc/core/irc-log.c
+++ b/src/irc/core/irc-log.c
@@ -26,20 +26,6 @@
#include "irc-server.h"
-static void sig_log(SERVER_REC *server, const char *channel, gpointer level, const char *str)
-{
- int loglevel;
-
- g_return_if_fail(str != NULL);
-
- loglevel = GPOINTER_TO_INT(level);
- if (loglevel == MSGLEVEL_NEVER || logs == NULL) return;
-
- /* Check if line should be saved in logs */
- log_write(channel, loglevel, str);
-}
-
-
static void event_away(const char *data, IRC_SERVER_REC *server)
{
const char *fname, *levelstr;
@@ -93,14 +79,12 @@ void irc_log_init(void)
settings_add_str("log", "awaylog_file", "~/.irssi/away.log");
settings_add_str("log", "awaylog_level", "msgs hilight");
- signal_add("print text stripped", (SIGNAL_FUNC) sig_log);
signal_add("event 306", (SIGNAL_FUNC) event_away);
signal_add("event 305", (SIGNAL_FUNC) event_unaway);
}
void irc_log_deinit(void)
{
- signal_remove("print text stripped", (SIGNAL_FUNC) sig_log);
signal_remove("event 306", (SIGNAL_FUNC) event_away);
signal_remove("event 305", (SIGNAL_FUNC) event_unaway);
}
diff --git a/src/irc/core/irc-server.h b/src/irc/core/irc-server.h
index 11172bea..8d780e30 100644
--- a/src/irc/core/irc-server.h
+++ b/src/irc/core/irc-server.h
@@ -129,6 +129,9 @@ typedef struct {
GSList *channels;
GSList *queries;
+ GSList *rejoin_channels; /* try to join to these channels after a while -
+ channels go here if they're "temporarily unavailable"
+ because of netsplits */
gpointer chanqueries;
} IRC_SERVER_REC;
diff --git a/src/irc/core/server-setup.c b/src/irc/core/server-setup.c
index 9c27c101..91bafd81 100644
--- a/src/irc/core/server-setup.c
+++ b/src/irc/core/server-setup.c
@@ -293,7 +293,7 @@ static void setupserver_destroy(SETUP_SERVER_REC *rec)
g_free_not_null(rec->own_ip);
g_free(rec->ircnet);
g_free(rec->address);
- g_free(rec->password);
+ g_free_not_null(rec->password);
g_free(rec);
}
diff --git a/src/irc/dcc/dcc-chat.c b/src/irc/dcc/dcc-chat.c
index c01077d3..6a38e93c 100644
--- a/src/irc/dcc/dcc-chat.c
+++ b/src/irc/dcc/dcc-chat.c
@@ -308,12 +308,12 @@ static void cmd_dcc_chat(gchar *data, IRC_SERVER_REC *server)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (net_getsockname(server->handle, &addr, NULL) == -1)
- cmd_return_error(CMDERR_GETSOCKNAME);
+ cmd_return_error(CMDERR_ERRNO);
port = settings_get_int("dcc_port");
handle = net_listen(&addr, &port);
if (handle == -1)
- cmd_return_error(CMDERR_LISTEN);
+ cmd_return_error(CMDERR_ERRNO);
dcc = dcc_create(DCC_TYPE_CHAT, handle, data, "chat", server, NULL);
dcc->tagread = g_input_add(dcc->handle, G_INPUT_READ,
diff --git a/src/irc/dcc/dcc-files.c b/src/irc/dcc/dcc-files.c
index 8ccdb11a..5acd35c9 100644
--- a/src/irc/dcc/dcc-files.c
+++ b/src/irc/dcc/dcc-files.c
@@ -513,7 +513,7 @@ static void cmd_dcc_send(gchar *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
if (net_getsockname(chat != NULL ? chat->handle : server->handle, &addr, NULL) == -1)
{
close(fh);
- cmd_param_error(CMDERR_GETSOCKNAME);
+ cmd_param_error(CMDERR_ERRNO);
}
/* start listening */
@@ -522,7 +522,7 @@ static void cmd_dcc_send(gchar *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
if (h == -1)
{
close(fh);
- cmd_param_error(CMDERR_LISTEN);
+ cmd_param_error(CMDERR_ERRNO);
}
/* skip path */
diff --git a/src/perl/irssi-perl.c b/src/perl/irssi-perl.c
index e4f616e9..edf4ea5e 100644
--- a/src/perl/irssi-perl.c
+++ b/src/perl/irssi-perl.c
@@ -143,6 +143,9 @@ static void signal_destroy_hash(void *key, GSList *list)
while (list != NULL) {
PERL_SIGNAL_REC *rec = list->data;
+ if (strncmp(rec->signal, "command ", 8) == 0)
+ command_unbind(rec->signal+8, NULL);
+
list = g_slist_remove(list, rec);
g_free(rec->signal);