Lots of changes again. Biggest ones:

- window's text buffer should work better
- themes are almost working, you can change the text formats with /format
- automatically try to rejoin the channel after 5 minutes if the join there
failed because it was "temporarily unavailable" (netsplits)
- generally cleaning code..


git-svn-id: http://svn.irssi.org/repos/irssi/trunk@216 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
Timo Sirainen 2000-05-15 08:25:45 +00:00 committed by cras
parent 969cfe8abc
commit cbdaf7d06d
63 changed files with 2479 additions and 1920 deletions

22
TODO
View File

@ -1,8 +1,16 @@
- teemat
- /rehash
- teeman vaihto
- teemoihin tee jotain pientä selitystä edes!
- irssi can't find new themes in ~/.irssi/ while running - scan for new
themes when opening themes dialog? irssi-text also needs to be restarted
to use new themes..
- use different themes in different channels/queries?
- logi voisi käyttää omaa teemaa
- /IRCNET ADD/REMOVE - /IRCNET ADD/REMOVE
- mites se awaylogi? se /cattaamaan myös se /away:n jälkeen - mites se awaylogi? se /cattaamaan myös se /away:n jälkeen
- poista se common-setup.h - poista se common-setup.h
- quitissa se räpeltää ruutua liikaa..
- perli kaatui välillä ym. kivaa.
[21:48] < santo> [20:51] ¤¤¤ #twiggy,#tanum,#d2mac,#linux.nu,#sweden2k [21:48] < santo> [20:51] ¤¤¤ #twiggy,#tanum,#d2mac,#linux.nu,#sweden2k
Cannot join channel (illegal name) Cannot join channel (illegal name)
@ -19,15 +27,6 @@ lis
- gnome versio.. - gnome versio..
- pluginit - pluginit
- teemat (toimiiko ne edes?)
- teeman vaihto tekstiversiolla, tekstien muuttaminen tekstiversiolla
- teemoihin tee jotain pientä selitystä edes!
- irssi can't find new themes in ~/.irssi/ while running - scan for new
themes when opening themes dialog? irssi-text also needs to be restarted
to use new themes..
- use different themes in different channels/queries?
- logi voisi käyttää omaa teemaa
- /set hold_mode, ja /CAT toimimaan sen kanssa jotenkin nerokkaasti.. - /set hold_mode, ja /CAT toimimaan sen kanssa jotenkin nerokkaasti..
- curses sijainti jotain rikkoo, ja openbsd:ssä on -lcurses, ei -lncurses - curses sijainti jotain rikkoo, ja openbsd:ssä on -lcurses, ei -lncurses
@ -40,7 +39,6 @@ lis
- line-split.c: varmista että se 64k limitti toimii eikä esim. kaada! - line-split.c: varmista että se 64k limitti toimii eikä esim. kaada!
- /exec - /exec
- autorun.ircnet - autorun.ircnet
- channel not available rejoini
*** Bugs *** Bugs

View File

@ -201,7 +201,7 @@ dnl **
if test "x$want_textui" = "xyes"; then if test "x$want_textui" = "xyes"; then
AC_CHECK_CURSES AC_CHECK_CURSES
if test "x$ncurses_version" != "x"; then if test "x$has_ncurses" != "x"; then
AC_CHECK_LIB(ncurses, use_default_colors, [ AC_CHECK_LIB(ncurses, use_default_colors, [
AC_DEFINE(HAVE_NCURSES_USE_DEFAULT_COLORS) AC_DEFINE(HAVE_NCURSES_USE_DEFAULT_COLORS)
],, $CURSES_LIBS) ],, $CURSES_LIBS)

View File

@ -131,13 +131,7 @@ AC_DEFUN(AC_CHECK_CURSES,[
if test x$withval = xno ; then if test x$withval = xno ; then
search_ncurses=false search_ncurses=false
elif test x$withval != xyes ; then elif test x$withval != xyes ; then
CURSES_LIBS="$LIBS -L$withval/lib -lncurses" AC_NCURSES($withval/include, ncurses.h, -L$withval/lib -lncurses, -I$withval/include, "ncurses on $withval/include")
CURSES_INCLUDEDIR="-I$withval/include"
search_ncurses=false
screen_manager="ncurses"
AC_DEFINE(USE_NCURSES)
AC_DEFINE(HAS_CURSES)
has_curses=true
fi fi
) )
@ -222,6 +216,7 @@ AC_DEFUN(AC_NCURSES, [
screen_manager=$5 screen_manager=$5
AC_DEFINE(HAS_CURSES) AC_DEFINE(HAS_CURSES)
has_curses=true has_curses=true
has_ncurses=true
AC_DEFINE(USE_NCURSES) AC_DEFINE(USE_NCURSES)
fi fi
fi fi
@ -256,6 +251,7 @@ USE_NCURSES
CURSES_INCLUDEDIR="$CURSES_INCLUDEDIR -DRENAMED_NCURSES" CURSES_INCLUDEDIR="$CURSES_INCLUDEDIR -DRENAMED_NCURSES"
AC_DEFINE(HAS_CURSES) AC_DEFINE(HAS_CURSES)
has_curses=true has_curses=true
has_ncurses=true
AC_DEFINE(USE_NCURSES) AC_DEFINE(USE_NCURSES)
search_ncurses=false search_ncurses=false
screen_manager="ncurses installed as curses" screen_manager="ncurses installed as curses"

View File

@ -436,8 +436,24 @@ static void cmd_cd(const char *data)
g_free(str); 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) void commands_init(void)
{ {
commands = NULL;
cmdget_funcs = NULL; cmdget_funcs = NULL;
current_command = NULL; current_command = NULL;
@ -448,6 +464,8 @@ void commands_init(void)
command_bind("eval", NULL, (SIGNAL_FUNC) cmd_eval); command_bind("eval", NULL, (SIGNAL_FUNC) cmd_eval);
command_bind("cd", NULL, (SIGNAL_FUNC) cmd_cd); 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) void commands_deinit(void)
@ -459,4 +477,6 @@ void commands_deinit(void)
command_unbind("eval", (SIGNAL_FUNC) cmd_eval); command_unbind("eval", (SIGNAL_FUNC) cmd_eval);
command_unbind("cd", (SIGNAL_FUNC) cmd_cd); command_unbind("cd", (SIGNAL_FUNC) cmd_cd);
command_unbind("rehash", (SIGNAL_FUNC) cmd_rehash);
command_unbind("save", (SIGNAL_FUNC) cmd_save);
} }

View File

@ -10,16 +10,11 @@ typedef struct {
COMMAND_REC; COMMAND_REC;
enum { enum {
CMDERR_PARAM, /* invalid parameter */ CMDERR_ERRNO, /* get the error from errno */
CMDERR_NOT_ENOUGH_PARAMS, /* not enough parameters given */ CMDERR_NOT_ENOUGH_PARAMS, /* not enough parameters given */
CMDERR_NOT_CONNECTED, /* not connected to IRC server */ CMDERR_NOT_CONNECTED, /* not connected to IRC server */
CMDERR_NOT_JOINED, /* not joined to any channels in this window */ 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_CHAN_NOT_FOUND, /* channel not found */
CMDERR_SERVER_NOT_FOUND, /* server not found */
CMDERR_CHAN_NOT_SYNCED, /* channel not fully synchronized yet */ CMDERR_CHAN_NOT_SYNCED, /* channel not fully synchronized yet */
CMDERR_NOT_GOOD_IDEA /* not good idea to do, -yes overrides this */ CMDERR_NOT_GOOD_IDEA /* not good idea to do, -yes overrides this */
}; };

View File

@ -43,9 +43,9 @@ void core_init(void)
net_disconnect_init(); net_disconnect_init();
signals_init(); signals_init();
settings_init(); settings_init();
commands_init();
servers_init(); servers_init();
commands_init();
log_init(); log_init();
rawlog_init(); rawlog_init();
special_vars_init(); special_vars_init();
@ -56,9 +56,9 @@ void core_deinit(void)
special_vars_deinit(); special_vars_deinit();
rawlog_deinit(); rawlog_deinit();
log_deinit(); log_deinit();
commands_deinit();
servers_deinit(); servers_deinit();
commands_deinit();
settings_deinit(); settings_deinit();
signals_deinit(); signals_deinit();
net_disconnect_deinit(); net_disconnect_deinit();

View File

@ -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) void *ig_malloc(int size, const char *file, int line)
{ {
#if 1
void *p; void *p;
size += BUFFER_CHECK_SIZE*2; size += BUFFER_CHECK_SIZE*2;
p = g_malloc(size); p = g_malloc(size);
data_add(p, size, file, line); data_add(p, size, file, line);
return p+BUFFER_CHECK_SIZE; return p+BUFFER_CHECK_SIZE;
#else
return g_malloc(size);
#endif
} }
void *ig_malloc0(int size, const char *file, int line) void *ig_malloc0(int size, const char *file, int line)
{ {
#if 1
void *p; void *p;
size += BUFFER_CHECK_SIZE*2; size += BUFFER_CHECK_SIZE*2;
p = g_malloc0(size); p = g_malloc0(size);
data_add(p, size, file, line); data_add(p, size, file, line);
return p+BUFFER_CHECK_SIZE; return p+BUFFER_CHECK_SIZE;
#else
return g_malloc0(size);
#endif
} }
void *ig_realloc(void *mem, unsigned long size, const char *file, int line) void *ig_realloc(void *mem, unsigned long size, const char *file, int line)
{ {
#if 1
void *p; void *p;
size += BUFFER_CHECK_SIZE*2; 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); p = g_realloc(mem, size);
data_add(p, size, file, line); data_add(p, size, file, line);
return p+BUFFER_CHECK_SIZE; return p+BUFFER_CHECK_SIZE;
#else
return g_realloc(mem, size);
#endif
} }
char *ig_strdup(const char *str, const char *file, int line) 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) void ig_free(void *p)
{ {
#if 1 if (p == NULL) g_error("ig_free() : trying to free NULL");
p -= BUFFER_CHECK_SIZE; p -= BUFFER_CHECK_SIZE;
p = data_remove(p, "??", 0); p = data_remove(p, "??", 0);
if (p != NULL) if (p != NULL) g_free(p);
#endif
g_free(p);
} }
GString *ig_string_new(const char *file, int line, const char *str) GString *ig_string_new(const char *file, int line, const char *str)

View File

@ -21,6 +21,7 @@
#include "module.h" #include "module.h"
#include "signals.h" #include "signals.h"
#include "commands.h" #include "commands.h"
#include "misc.h"
#include "lib-config/iconfig.h" #include "lib-config/iconfig.h"
#include "settings.h" #include "settings.h"
@ -278,15 +279,16 @@ static void init_configfile(void)
signal(SIGTERM, sig_term); signal(SIGTERM, sig_term);
} }
static void cmd_rehash(const char *data) void settings_reread(const char *fname)
{ {
CONFIG_REC *tempconfig; CONFIG_REC *tempconfig;
char *str, *fname; char *str;
fname = *data != '\0' ? g_strdup(data) : if (fname == NULL) fname = "~/.irssi/config";
g_strdup_printf("%s/.irssi/config", g_get_home_dir());
tempconfig = parse_configfile(fname); str = convert_home(fname);
g_free(fname); tempconfig = parse_configfile(str);
g_free(str);
if (tempconfig == NULL) { if (tempconfig == NULL) {
signal_emit("gui dialog", 2, "error", g_strerror(errno)); 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); signal_emit("setup reread", 0);
} }
static void cmd_save(const char *data) void settings_save(const char *fname)
{ {
char *str; char *str;
if (config_write(mainconfig, *data == '\0' ? NULL : data, 0660) == 0) if (config_write(mainconfig, fname, 0660) == 0)
return; return;
/* error */ /* error */
@ -329,8 +331,6 @@ void settings_init(void)
settings = g_hash_table_new((GHashFunc) g_str_hash, (GCompareFunc) g_str_equal); settings = g_hash_table_new((GHashFunc) g_str_hash, (GCompareFunc) g_str_equal);
init_configfile(); 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) 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) 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_free_not_null(last_error_msg);
g_hash_table_foreach(settings, (GHFunc) settings_hash_free, NULL); g_hash_table_foreach(settings, (GHFunc) settings_hash_free, NULL);
g_hash_table_destroy(settings); g_hash_table_destroy(settings);

View File

@ -53,6 +53,10 @@ GSList *settings_get_sorted(void);
/* Get the record of the setting */ /* Get the record of the setting */
SETTINGS_REC *settings_get_record(const char *key); 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_init(void);
void settings_deinit(void); void settings_deinit(void);

View File

@ -17,10 +17,11 @@ libfe_common_core_la_SOURCES = \
hilight-text.c \ hilight-text.c \
keyboard.c \ keyboard.c \
module-formats.c \ module-formats.c \
window-activity.c \
printtext.c \ printtext.c \
themes.c \ themes.c \
translation.c \ translation.c \
window-activity.c \
window-commands.c \
window-items.c \ window-items.c \
windows.c windows.c

View File

@ -18,6 +18,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "module.h" #include "module.h"
#include "module-formats.h"
#include "levels.h" #include "levels.h"
#include "settings.h" #include "settings.h"
@ -50,6 +51,9 @@ void fe_settings_deinit(void);
void window_activity_init(void); void window_activity_init(void);
void window_activity_deinit(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_init(void);
void fe_core_commands_deinit(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_int("lookandfeel", "tab_orientation", 3);*/
settings_add_str("lookandfeel", "current_theme", "default"); settings_add_str("lookandfeel", "current_theme", "default");
themes_init();
theme_register(fecommon_core_formats);
autorun_init(); autorun_init();
window_activity_init();
hilight_text_init(); hilight_text_init();
command_history_init(); command_history_init();
keyboard_init(); keyboard_init();
@ -82,9 +88,10 @@ void fe_common_core_init(void)
fe_log_init(); fe_log_init();
fe_server_init(); fe_server_init();
fe_settings_init(); fe_settings_init();
themes_init();
translation_init(); translation_init();
windows_init(); windows_init();
window_activity_init();
window_commands_init();
window_items_init(); window_items_init();
fe_core_commands_init(); fe_core_commands_init();
} }
@ -92,7 +99,6 @@ void fe_common_core_init(void)
void fe_common_core_deinit(void) void fe_common_core_deinit(void)
{ {
autorun_deinit(); autorun_deinit();
window_activity_deinit();
hilight_text_deinit(); hilight_text_deinit();
command_history_deinit(); command_history_deinit();
keyboard_deinit(); keyboard_deinit();
@ -100,11 +106,15 @@ void fe_common_core_deinit(void)
fe_log_deinit(); fe_log_deinit();
fe_server_deinit(); fe_server_deinit();
fe_settings_deinit(); fe_settings_deinit();
themes_deinit();
translation_deinit(); translation_deinit();
windows_deinit(); windows_deinit();
window_activity_deinit();
window_commands_deinit();
window_items_deinit(); window_items_deinit();
fe_core_commands_deinit(); fe_core_commands_deinit();
theme_unregister();
themes_deinit();
} }
void fe_common_core_finish_init(void) void fe_common_core_finish_init(void)

View File

@ -30,16 +30,11 @@
#include "windows.h" #include "windows.h"
static const char *ret_texts[] = { static const char *ret_texts[] = {
"Invalid parameter", NULL,
"Not enough parameters given", "Not enough parameters given",
"Not connected to IRC server yet", "Not connected to IRC server yet",
"Not joined to any channels 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", "Not joined to such channel",
"Server not found",
"Channel not fully synchronized yet, try again after a while", "Channel not fully synchronized yet, try again after a while",
"Doing this is not a good idea. Add -YES if you really mean it", "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(); 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) void fe_core_commands_init(void)

View File

@ -297,25 +297,27 @@ static void autolog_log(void *server, const char *target)
g_free(fname); g_free(fname);
} }
/* write to logs created with /WINDOW LOG */ static void sig_printtext_stripped(WINDOW_REC *window, void *server, const char *target, gpointer levelp, const char *text)
static void sig_printtext_stripped(void *server, const char *target, gpointer levelp, const char *text)
{ {
char windownum[MAX_INT_STRLEN]; char windownum[MAX_INT_STRLEN];
WINDOW_REC *window;
LOG_REC *log; LOG_REC *log;
int level; int level;
level = GPOINTER_TO_INT(levelp); level = GPOINTER_TO_INT(levelp);
if (level == MSGLEVEL_NEVER) return;
/* let autolog create the log records */
if ((autolog_level & level) && target != NULL && *target != '\0') if ((autolog_level & level) && target != NULL && *target != '\0')
autolog_log(server, target); autolog_log(server, target);
window = window_find_closest(server, target, level); /* save to log created with /WINDOW LOG */
if (window != NULL) { ltoa(windownum, window->refnum);
ltoa(windownum, window->refnum); log = log_find_item(windownum);
if (log != NULL) log_write_rec(log, text);
log = log_find_item(windownum); /* save line to logs */
if (log != NULL) log_write_rec(log, text); if (logs != NULL)
} log_write(target, level, text);
} }
static int sig_autoremove(void) static int sig_autoremove(void)

View File

@ -132,7 +132,7 @@ static HILIGHT_REC *hilight_find(const char *text, char **channels)
return NULL; 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) { if (hilight_next) {
hilight_next = FALSE; 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; GSList *tmp;
char *color, *newstr; 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"; if (color == NULL) color = "\00316";
newstr = g_strconcat(isdigit(*color) ? "\003" : "", color, str, NULL); 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); g_free(newstr);
hilight_next = TRUE; hilight_next = TRUE;

View File

@ -258,12 +258,6 @@ static void read_keyboard_config(void)
CONFIG_NODE *node; CONFIG_NODE *node;
GSList *tmp; 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); node = iconfig_node_traverse("keyboard", FALSE);
if (node == NULL) return; if (node == NULL) return;
@ -280,7 +274,9 @@ static void read_keyboard_config(void)
void keyboard_init(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); key_bind("command", NULL, "Run any IRC command", NULL, (SIGNAL_FUNC) sig_command);
read_keyboard_config(); read_keyboard_config();

View File

@ -21,73 +21,75 @@
#include "module.h" #include "module.h"
#include "printtext.h" #include "printtext.h"
FORMAT_REC fecommon_core_formats[] = FORMAT_REC fecommon_core_formats[] = {
{ { MODULE_NAME, "Core", 0 },
{ MODULE_NAME, "Core", 0 },
/* ---- */ /* ---- */
{ NULL, "Windows", 0 }, { NULL, "Windows", 0 },
{ "line_start", "%B-%W!%B-%n ", 0 }, { "line_start", "%B-%W!%B-%n ", 0 },
{ "line_start_irssi", "%B-%W!%B- %WIrssi:%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 } }, { "timestamp", "[$[-2.0]3:$[-2.0]4] ", 6, { 1, 1, 1, 1, 1, 1 } },
{ "daychange", "Day changed to ${[-2.0]1}-$[-2.0]0 $2", 3, { 1, 1, 1 } }, { "daychange", "Day changed to $[-2.0]{0}-$[-2.0]1 $2", 3, { 1, 1, 1 } },
{ "talking_with", "You are now talking with %_$0%_", 1, { 0 } }, { "talking_with", "You are now talking with %_$0%_", 1, { 0 } },
{ "refnum_too_low", "Window number must be greater than 1", 0 }, { "refnum_too_low", "Window number must be greater than 1", 0 },
{ "windowlist_header", "Ref Name Active item Server Level", 0 }, { "refnum_not_found", "No such window: $0", 1, { 0 } }, /*REMOVE!!!!!!!!*/
{ "windowlist_line", "$[3]0 %|$[20]1 $[15]2 $[15]3 $4", 5, { 1, 0, 0, 0, 0 } }, { "windowlist_header", "Ref Name Active item Server Level", 0 },
{ "windowlist_footer", "", 0 }, { "windowlist_line", "$[3]0 %|$[20]1 $[15]2 $[15]3 $4", 5, { 1, 0, 0, 0, 0 } },
{ "windowlist_footer", "", 0 },
/* ---- */ /* ---- */
{ NULL, "Server", 0 }, { NULL, "Server", 0 },
{ "looking_up", "Looking up %_$0%_", 1, { 0 } }, { "looking_up", "Looking up %_$0%_", 1, { 0 } },
{ "connecting", "Connecting to %_$0%_ %K[%n$1%K]%n port %_$2%_", 3, { 0, 0, 1 } }, { "connecting", "Connecting to %_$0%_ %K[%n$1%K]%n port %_$2%_", 3, { 0, 0, 1 } },
{ "connection_established", "Connection to %_$0%_ established", 1, { 0 } }, { "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 } }, { "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 } }, { "connection_lost", "Connection lost to %_$0%_", 1, { 0 } },
{ "server_quit", "Disconnecting from server $0: %K[%n$1%K]", 2, { 0, 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 } }, { "server_changed", "Changed to %_$2%_ server %_$1%_", 3, { 0, 0, 0 } },
{ "unknown_server_tag", "Unknown server tag %_$0%_", 1, { 0 } }, { "unknown_server_tag", "Unknown server tag %_$0%_", 1, { 0 } },
/* ---- */ /* ---- */
{ NULL, "Highlighting", 0 }, { NULL, "Highlighting", 0 },
{ "hilight_header", "Highlights:", 0 }, { "hilight_header", "Highlights:", 0 },
{ "hilight_line", "$[-4]0 $1 $2 $3$3$4$5", 7, { 1, 0, 0, 0, 0, 0, 0 } }, { "hilight_line", "$[-4]0 $1 $2 $3$3$4$5", 7, { 1, 0, 0, 0, 0, 0, 0 } },
{ "hilight_footer", "", 0 }, { "hilight_footer", "", 0 },
{ "hilight_not_found", "Highlight not found: $0", 1, { 0 } }, { "hilight_not_found", "Highlight not found: $0", 1, { 0 } },
{ "hilight_removed", "Highlight removed: $0", 1, { 0 } }, { "hilight_removed", "Highlight removed: $0", 1, { 0 } },
/* ---- */ /* ---- */
{ NULL, "Aliases", 0 }, { NULL, "Aliases", 0 },
{ "alias_added", "Alias $0 added", 1, { 0 } }, { "alias_added", "Alias $0 added", 1, { 0 } },
{ "alias_removed", "Alias $0 removed", 1, { 0 } }, { "alias_removed", "Alias $0 removed", 1, { 0 } },
{ "alias_not_found", "No such alias: $0", 1, { 0 } }, { "alias_not_found", "No such alias: $0", 1, { 0 } },
{ "aliaslist_header", "Aliases:", 0 }, { "aliaslist_header", "Aliases:", 0 },
{ "aliaslist_line", "$[10]0 $1", 2, { 0, 0 } }, { "aliaslist_line", "$[10]0 $1", 2, { 0, 0 } },
{ "aliaslist_footer", "", 0 }, { "aliaslist_footer", "", 0 },
/* ---- */ /* ---- */
{ NULL, "Logging", 0 }, { NULL, "Logging", 0 },
{ "log_opened", "Log file %W$0%n opened", 1, { 0 } }, { "log_opened", "Log file %W$0%n opened", 1, { 0 } },
{ "log_closed", "Log file %W$0%n closed", 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_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_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_not_open", "Log file %W$0%n not open", 1, { 0 } },
{ "log_started", "Started logging to file %W$0", 1, { 0 } }, { "log_started", "Started logging to file %W$0", 1, { 0 } },
{ "log_stopped", "Stopped logging to file %W$0", 1, { 0 } }, { "log_stopped", "Stopped logging to file %W$0", 1, { 0 } },
{ "log_list_header", "Logs:", 0 }, { "log_list_header", "Logs:", 0 },
{ "log_list", "$0: $1 $2$3$4", 5, { 0, 0, 0, 0, 0 } }, { "log_list", "$0: $1 $2$3$4", 5, { 0, 0, 0, 0, 0 } },
{ "log_list_footer", "", 0 }, { "log_list_footer", "", 0 },
{ "windowlog_file", "Window LOGFILE set to $0", 1, { 0 } }, { "windowlog_file", "Window LOGFILE set to $0", 1, { 0 } },
{ "windowlog_file_logging", "Can't change window's logfile while log is on", 0 }, { "windowlog_file_logging", "Can't change window's logfile while log is on", 0 },
/* ---- */ /* ---- */
{ NULL, "Misc", 0 }, { NULL, "Misc", 0 },
{ "not_toggle", "Value must be either ON, OFF or TOGGLE", 0 }, { "not_toggle", "Value must be either ON, OFF or TOGGLE", 0 },
{ "perl_error", "Perl error: $0", 1, { 0 } } { "perl_error", "Perl error: $0", 1, { 0 } },
{ NULL, NULL, 0 }
}; };

View File

@ -65,6 +65,3 @@ enum {
}; };
extern FORMAT_REC fecommon_core_formats[]; extern FORMAT_REC fecommon_core_formats[];
#define MODULE_FORMATS fecommon_core_formats
#include "printformat.h"

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,8 @@
#ifndef __PRINTTEXT_H #ifndef __PRINTTEXT_H
#define __PRINTTEXT_H #define __PRINTTEXT_H
#include "windows.h"
enum { enum {
FORMAT_STRING, FORMAT_STRING,
FORMAT_INT, FORMAT_INT,
@ -24,9 +26,14 @@ typedef struct {
#define PRINTFLAG_MIRC_COLOR 0x20 #define PRINTFLAG_MIRC_COLOR 0x20
#define PRINTFLAG_INDENT 0x40 #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 printtext(void *server, const char *channel, int level, const char *str, ...); 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 *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 printtext_multiline(void *server, const char *channel, int level, const char *format, const char *text);
void printbeep(void); void printbeep(void);
@ -36,4 +43,51 @@ char *strip_codes(const char *input);
void printtext_init(void); void printtext_init(void);
void printtext_deinit(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 #endif

View File

@ -20,6 +20,8 @@
#include "module.h" #include "module.h"
#include "signals.h" #include "signals.h"
#include "commands.h"
#include "levels.h"
#include "misc.h" #include "misc.h"
#include "lib-config/iconfig.h" #include "lib-config/iconfig.h"
#include "settings.h" #include "settings.h"
@ -29,6 +31,7 @@
GSList *themes; GSList *themes;
THEME_REC *current_theme; THEME_REC *current_theme;
GHashTable *default_formats;
THEME_REC *theme_create(const char *path, const char *name) 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; 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 < rec->count; n++)
for (n = 0; n < max; n++) if (rec->formats[n] != NULL)
if (rec->format[n] != NULL) g_free(rec->formats[n]);
g_free(rec->format[n]); g_free(rec->formats);
g_free(rec->format);
g_strfreev(rec->formatlist);
g_free(rec->name); g_free(rec->name);
g_free(rec); 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) void theme_destroy(THEME_REC *rec)
{ {
signal_emit("theme destroyed", 1, 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); g_hash_table_destroy(rec->modules);
if (rec->bg_pixmap != NULL) g_free(rec->bg_pixmap); if (rec->bg_pixmap != NULL) g_free(rec->bg_pixmap);
@ -74,6 +75,119 @@ void theme_destroy(THEME_REC *rec)
g_free(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) static THEME_REC *theme_find(const char *name)
{ {
GSList *tmp; GSList *tmp;
@ -115,49 +229,19 @@ static void find_themes(gchar *path)
closedir(dirp); closedir(dirp);
} }
/* Read module texts into theme */ static void theme_read(THEME_REC *theme, const char *path)
static void theme_read_module_texts(const char *hashkey, MODULE_THEME_REC *rec, CONFIG_REC *config)
{ {
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_REC *config;
CONFIG_NODE *formats;
GSList *tmp;
char *value; char *value;
int errors;
config = config_open(path, -1); config = config_open(path, -1);
if (config == NULL) { if (config == NULL) {
/* didn't exist or no access? */ /* didn't exist or no access? */
theme->default_color = 15; theme->default_color = 15;
return FALSE; return;
} }
errors = config_parse(config) == -1; config_parse(config);
/* default color */ /* default color */
theme->default_color = config_get_int(config, NULL, "default_color", 15); 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; theme->flags |= THEME_FLAG_BG_SCALED;
if (config_get_bool(config, NULL, "bg_shaded", FALSE)) if (config_get_bool(config, NULL, "bg_shaded", FALSE))
theme->flags |= THEME_FLAG_BG_SHADED; theme->flags |= THEME_FLAG_BG_SHADED;
/* 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;
if (node->key == NULL || node->value == NULL)
continue;
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);
}
}
/* 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);
}
g_free(str);
}
}
config_close(config); config_close(config);
return errors;
} }
static void sig_formats_error(void) typedef struct {
char *name;
char *short_name;
} THEME_SEARCH_REC;
static int theme_search_equal(THEME_SEARCH_REC *r1, THEME_SEARCH_REC *r2)
{ {
signal_emit("gui dialog", 2, "warning", return g_strcasecmp(r1->short_name, r2->short_name);
"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); 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);
}
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;
}
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;
}
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;
}
}
}
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);
g_free(params);
}
static void module_save(const char *module, MODULE_THEME_REC *rec, CONFIG_NODE *fnode)
{
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) void themes_init(void)
@ -235,7 +433,8 @@ void themes_init(void)
GSList *tmp; GSList *tmp;
const char *value; const char *value;
char *str; char *str;
int errors;
default_formats = g_hash_table_new((GHashFunc) g_str_hash, (GCompareFunc) g_str_equal);
/* first there's default theme.. */ /* first there's default theme.. */
str = g_strdup_printf("%s/.irssi/default.theme", g_get_home_dir()); str = g_strdup_printf("%s/.irssi/default.theme", g_get_home_dir());
@ -251,22 +450,20 @@ void themes_init(void)
find_themes(SYSCONFDIR"/irssi"); find_themes(SYSCONFDIR"/irssi");
/* read formats for all themes */ /* read formats for all themes */
errors = FALSE;
for (tmp = themes; tmp != NULL; tmp = tmp->next) { for (tmp = themes; tmp != NULL; tmp = tmp->next) {
rec = tmp->data; rec = tmp->data;
if (theme_read(rec, rec->path)) theme_read(rec, rec->path);
errors = TRUE;
} }
if (errors)
signal_add("irssi init finished", (SIGNAL_FUNC) sig_formats_error);
/* find the current theme to use */ /* find the current theme to use */
value = settings_get_str("current_theme"); value = settings_get_str("current_theme");
rec = theme_find(value); rec = theme_find(value);
if (rec != NULL) current_theme = rec; 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) void themes_deinit(void)
@ -275,4 +472,9 @@ void themes_deinit(void)
g_slist_foreach(themes, (GFunc) theme_destroy, NULL); g_slist_foreach(themes, (GFunc) theme_destroy, NULL);
g_slist_free(themes); g_slist_free(themes);
themes = NULL; themes = NULL;
g_hash_table_destroy(default_formats);
command_unbind("format", (SIGNAL_FUNC) cmd_format);
command_unbind("save", (SIGNAL_FUNC) cmd_save);
} }

View File

@ -1,18 +1,18 @@
#ifndef __THEMES_H #ifndef __THEMES_H
#define __THEMES_H #define __THEMES_H
#include "printtext.h"
#define THEME_FLAG_BG_SCROLLABLE 0x0001 #define THEME_FLAG_BG_SCROLLABLE 0x0001
#define THEME_FLAG_BG_SCALED 0x0002 #define THEME_FLAG_BG_SCALED 0x0002
#define THEME_FLAG_BG_SHADED 0x0004 #define THEME_FLAG_BG_SHADED 0x0004
typedef struct typedef struct {
{
char *name; char *name;
char **formatlist; int count;
char **format; char **formats; /* in same order as in module's default formats */
} } MODULE_THEME_REC;
MODULE_THEME_REC;
typedef struct { typedef struct {
char *path; char *path;
@ -30,10 +30,16 @@ typedef struct {
extern GSList *themes; extern GSList *themes;
extern THEME_REC *current_theme; extern THEME_REC *current_theme;
extern GHashTable *default_formats;
THEME_REC *theme_create(const char *path, const char *name); THEME_REC *theme_create(const char *path, const char *name);
void theme_destroy(THEME_REC *rec); 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_init(void);
void themes_deinit(void); void themes_deinit(void);

View File

@ -26,13 +26,11 @@
#include "windows.h" #include "windows.h"
#include "window-items.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; int level, oldlevel;
level = GPOINTER_TO_INT(levelptr); level = GPOINTER_TO_INT(levelptr);
window = window_find_closest(server, channel, level);
if (window == active_win || (level & (MSGLEVEL_NEVER|MSGLEVEL_NO_ACT|MSGLEVEL_MSGS))) if (window == active_win || (level & (MSGLEVEL_NEVER|MSGLEVEL_NO_ACT|MSGLEVEL_MSGS)))
return; return;

View File

@ -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);
}

View File

@ -27,7 +27,6 @@
#include "levels.h" #include "levels.h"
#include "printtext.h"
#include "windows.h" #include "windows.h"
#include "window-items.h" #include "window-items.h"
@ -86,17 +85,6 @@ WINDOW_REC *window_item_window(WI_ITEM_REC *item)
return MODULE_DATA(item); return MODULE_DATA(item);
} }
void window_item_set_active(WINDOW_REC *window, WI_ITEM_REC *item)
{
g_return_if_fail(window != NULL);
if (window->active != item) {
window->active = item;
if (item != NULL) window_change_server(window, window->active_server);
signal_emit("window item changed", 2, window, item);
}
}
void window_item_change_server(WI_ITEM_REC *item, void *server) void window_item_change_server(WI_ITEM_REC *item, void *server)
{ {
WINDOW_REC *window; WINDOW_REC *window;
@ -110,6 +98,71 @@ void window_item_change_server(WI_ITEM_REC *item, void *server)
if (window->active == item) window_change_server(window, item->server); 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);
if (window->active != item) {
window->active = item;
if (item != NULL) window_change_server(window, window->active_server);
signal_emit("window item changed", 2, window, item);
}
}
void window_item_prev(WINDOW_REC *window)
{
WI_ITEM_REC *last;
GSList *tmp;
g_return_if_fail(window != NULL);
last = NULL;
for (tmp = window->items; tmp != NULL; tmp = tmp->next) {
WI_ITEM_REC *rec = tmp->data;
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) static WI_ITEM_REC *window_item_find_window(WINDOW_REC *window, void *server, const char *name)
{ {
GSList *tmp; GSList *tmp;

View File

@ -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); void window_item_create(WI_ITEM_REC *item, int automatic);
WINDOW_REC *window_item_window(WI_ITEM_REC *item); 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_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. */ /* Find wanted window item by name. `server' can be NULL. */
WI_ITEM_REC *window_item_find(void *server, const char *name); WI_ITEM_REC *window_item_find(void *server, const char *name);

View File

@ -37,6 +37,8 @@ GSList *windows; /* first in the list is the active window,
next is the last active, etc. */ next is the last active, etc. */
WINDOW_REC *active_win; WINDOW_REC *active_win;
static int daytag;
static int window_get_new_refnum(void) static int window_get_new_refnum(void)
{ {
WINDOW_REC *win; WINDOW_REC *win;
@ -247,117 +249,6 @@ WINDOW_REC *window_find_refnum(int refnum)
return NULL; 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) WINDOW_REC *window_find_name(const char *name)
{ {
GSList *tmp; GSList *tmp;
@ -409,288 +300,56 @@ WINDOW_REC *window_find_item(WINDOW_REC *window, const char *name)
return MODULE_DATA(item); return MODULE_DATA(item);
} }
static void cmd_window_refnum(const char *data) int window_refnum_prev(int refnum)
{ {
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)
{
WINDOW_REC *window;
WI_ITEM_REC *last;
GSList *tmp; GSList *tmp;
int prev, max;
window = item == NULL ? NULL : MODULE_DATA(item); max = prev = -1;
if (window == NULL) return;
last = NULL;
for (tmp = window->items; tmp != NULL; tmp = tmp->next) {
WI_ITEM_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 (last != NULL)
window_item_set_active(window, last);
}
static void cmd_window_item_next(const char *data, void *server, WI_ITEM_REC *item)
{
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;
window_set_refnum(active_win, refnum);
}
} else {
for (;;) {
refnum = window_refnum_prev(active_win->refnum);
if (refnum == -1 || refnum < new_refnum)
break;
window_set_refnum(active_win, refnum);
}
}
}
static int windows_compare(WINDOW_REC *w1, WINDOW_REC *w2)
{
return w1->refnum < w2->refnum ? -1 : 1;
}
GSList *windows_get_sorted(void)
{
GSList *tmp, *list;
list = NULL;
for (tmp = windows; tmp != NULL; tmp = tmp->next) { 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; WINDOW_REC *rec = tmp->data;
levelstr = bits2level(rec->level); if (rec->refnum < refnum && (prev == -1 || rec->refnum > prev))
printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_WINDOWLIST_LINE, prev = rec->refnum;
rec->refnum, rec->name == NULL ? "" : rec->name, if (max == -1 || rec->refnum > max)
rec->active == NULL ? "" : rec->active->name, max = rec->refnum;
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); return prev != -1 ? prev : max;
}
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;
}
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 void sig_server_looking(void *server) 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) void windows_init(void)
{ {
active_win = NULL; active_win = NULL;
settings_add_bool("lookandfeel", "window_auto_change", FALSE); settings_add_bool("lookandfeel", "window_auto_change", FALSE);
command_bind("window", NULL, (SIGNAL_FUNC) cmd_window); daytag = g_timeout_add(30000, (GSourceFunc) sig_check_daychange, NULL);
command_bind("window new", NULL, (SIGNAL_FUNC) cmd_window_new);
command_bind("window close", NULL, (SIGNAL_FUNC) cmd_window_close);
command_bind("window kill", NULL, (SIGNAL_FUNC) cmd_window_close);
command_bind("window server", NULL, (SIGNAL_FUNC) cmd_window_server);
command_bind("window refnum", NULL, (SIGNAL_FUNC) cmd_window_refnum);
command_bind("window goto", NULL, (SIGNAL_FUNC) cmd_window_goto);
command_bind("window prev", NULL, (SIGNAL_FUNC) cmd_window_prev);
command_bind("window next", NULL, (SIGNAL_FUNC) cmd_window_next);
command_bind("window level", NULL, (SIGNAL_FUNC) cmd_window_level);
command_bind("window item prev", NULL, (SIGNAL_FUNC) cmd_window_item_prev);
command_bind("window item next", NULL, (SIGNAL_FUNC) cmd_window_item_next);
command_bind("window number", NULL, (SIGNAL_FUNC) cmd_window_number);
command_bind("window name", NULL, (SIGNAL_FUNC) cmd_window_name);
command_bind("window move", NULL, (SIGNAL_FUNC) cmd_window_move);
command_bind("window move left", NULL, (SIGNAL_FUNC) cmd_window_move_left);
command_bind("window move right", NULL, (SIGNAL_FUNC) cmd_window_move_right);
command_bind("window list", NULL, (SIGNAL_FUNC) cmd_window_list);
signal_add("server looking", (SIGNAL_FUNC) sig_server_looking); signal_add("server looking", (SIGNAL_FUNC) sig_server_looking);
signal_add("server disconnected", (SIGNAL_FUNC) sig_server_disconnected); signal_add("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
signal_add("server connect failed", (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) void windows_deinit(void)
{ {
command_unbind("window", (SIGNAL_FUNC) cmd_window); g_source_remove(daytag);
command_unbind("window new", (SIGNAL_FUNC) cmd_window_new);
command_unbind("window close", (SIGNAL_FUNC) cmd_window_close);
command_unbind("window kill", (SIGNAL_FUNC) cmd_window_close);
command_unbind("window server", (SIGNAL_FUNC) cmd_window_server);
command_unbind("window refnum", (SIGNAL_FUNC) cmd_window_refnum);
command_unbind("window goto", (SIGNAL_FUNC) cmd_window_goto);
command_unbind("window prev", (SIGNAL_FUNC) cmd_window_prev);
command_unbind("window next", (SIGNAL_FUNC) cmd_window_next);
command_unbind("window level", (SIGNAL_FUNC) cmd_window_level);
command_unbind("window item prev", (SIGNAL_FUNC) cmd_window_item_prev);
command_unbind("window item next", (SIGNAL_FUNC) cmd_window_item_next);
command_unbind("window number", (SIGNAL_FUNC) cmd_window_number);
command_unbind("window name", (SIGNAL_FUNC) cmd_window_name);
command_unbind("window move", (SIGNAL_FUNC) cmd_window_move);
command_unbind("window move left", (SIGNAL_FUNC) cmd_window_move_left);
command_unbind("window move right", (SIGNAL_FUNC) cmd_window_move_right);
command_unbind("window list", (SIGNAL_FUNC) cmd_window_list);
signal_remove("server looking", (SIGNAL_FUNC) sig_server_looking); signal_remove("server looking", (SIGNAL_FUNC) sig_server_looking);
signal_remove("server disconnected", (SIGNAL_FUNC) sig_server_disconnected); signal_remove("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
signal_remove("server connect failed", (SIGNAL_FUNC) sig_server_disconnected); signal_remove("server connect failed", (SIGNAL_FUNC) sig_server_disconnected);

View File

@ -69,6 +69,10 @@ WINDOW_REC *window_find_refnum(int refnum);
WINDOW_REC *window_find_name(const char *name); WINDOW_REC *window_find_name(const char *name);
WINDOW_REC *window_find_item(WINDOW_REC *window, 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_init(void);
void windows_deinit(void); void windows_deinit(void);

View File

@ -14,4 +14,5 @@ libfe_common_irc_dcc_la_SOURCES = \
module-formats.c module-formats.c
noinst_HEADERS = \ noinst_HEADERS = \
module.h \
module-formats.h module-formats.h

View File

@ -30,6 +30,7 @@
#include "irc/dcc/dcc.h" #include "irc/dcc/dcc.h"
#include "themes.h"
#include "windows.h" #include "windows.h"
static void dcc_connected(DCC_REC *dcc) 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 ", NULL, (SIGNAL_FUNC) cmd_dcc_list);
command_bind("dcc list", 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); signal_add("window item remove", (SIGNAL_FUNC) dcc_chat_closed);
theme_register(fecommon_irc_dcc_formats);
} }
void fe_dcc_deinit(void) void fe_dcc_deinit(void)
{ {
theme_unregister();
signal_remove("dcc connected", (SIGNAL_FUNC) dcc_connected); signal_remove("dcc connected", (SIGNAL_FUNC) dcc_connected);
signal_remove("dcc rejected", (SIGNAL_FUNC) dcc_rejected); signal_remove("dcc rejected", (SIGNAL_FUNC) dcc_rejected);
signal_remove("dcc closed", (SIGNAL_FUNC) dcc_closed); signal_remove("dcc closed", (SIGNAL_FUNC) dcc_closed);

View File

@ -21,39 +21,40 @@
#include "module.h" #include "module.h"
#include "printtext.h" #include "printtext.h"
FORMAT_REC fecommon_irc_dcc_formats[] = FORMAT_REC fecommon_irc_dcc_formats[] = {
{ { MODULE_NAME, "IRC", 0 },
{ MODULE_NAME, "IRC", 0 },
/* ---- */ /* ---- */
{ NULL, "DCC", 0 }, { NULL, "DCC", 0 },
{ "own_dcc", "%K[%rdcc%K(%R$0%K)]%n $1", 2, { 0, 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_me", "%W * $0%n $1", 2, { 0, 0 } },
{ "own_dcc_ctcp", "%K[%rctcp%K(%R$0%K)]%n $1 $2", 3, { 0, 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 } }, { "dcc_msg", "%K[%G$0%K(%gdcc%K)]%n $1", 2, { 0, 0 } },
{ "action_dcc", "%W (*dcc*) $0%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_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", "%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_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_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_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", "%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_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_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_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_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_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_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_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_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_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_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_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_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_unknown_type", "%gDCC unknown type %_$0", 1, { 0 } },
{ "dcc_connect_error", "%gDCC can't connect to %_$0%_ port %_$1", 2, { 0, 1 } }, { "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_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_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 } } { "dcc_close", "%gDCC %G$0%g close for %_$1%_ %K[%G$2%K]", 3, { 0, 0, 0 } },
{ NULL, NULL, 0 }
}; };

View File

@ -36,6 +36,3 @@ enum {
}; };
extern FORMAT_REC fecommon_irc_dcc_formats[]; extern FORMAT_REC fecommon_irc_dcc_formats[];
#define MODULE_FORMATS fecommon_irc_dcc_formats
#include "printformat.h"

View File

@ -0,0 +1,3 @@
#include "common.h"
#define MODULE_NAME "fe-common/irc/dcc"

View File

@ -19,6 +19,7 @@
*/ */
#include "module.h" #include "module.h"
#include "module-formats.h"
#include "signals.h" #include "signals.h"
#include "args.h" #include "args.h"
#include "misc.h" #include "misc.h"
@ -27,6 +28,7 @@
#include "server-setup.h" #include "server-setup.h"
#include "themes.h"
#include "completion.h" #include "completion.h"
void fe_channels_init(void); 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_away_once", TRUE);
settings_add_bool("lookandfeel", "show_quit_once", FALSE); settings_add_bool("lookandfeel", "show_quit_once", FALSE);
theme_register(fecommon_irc_formats);
fe_channels_init(); fe_channels_init();
fe_irc_commands_init(); fe_irc_commands_init();
fe_irc_server_init(); fe_irc_server_init();
@ -132,6 +136,8 @@ void fe_common_irc_deinit(void)
fe_query_deinit(); fe_query_deinit();
completion_deinit(); completion_deinit();
irc_window_activity_deinit(); irc_window_activity_deinit();
theme_unregister();
} }
void fe_common_irc_finish_init(void) void fe_common_irc_finish_init(void)

View File

@ -13,5 +13,6 @@ libfe_common_irc_flood_la_SOURCES = \
fe-flood.c \ fe-flood.c \
module-formats.c module-formats.c
noinst_headers = \ noinst_HEADERS = \
module.h \
module-formats.h module-formats.h

View File

@ -26,6 +26,8 @@
#include "irc-server.h" #include "irc-server.h"
#include "irc/flood/autoignore.h" #include "irc/flood/autoignore.h"
#include "themes.h"
static void event_autoignore_new(IRC_SERVER_REC *server, AUTOIGNORE_REC *ignore) static void event_autoignore_new(IRC_SERVER_REC *server, AUTOIGNORE_REC *ignore)
{ {
g_return_if_fail(ignore != NULL); 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 new", (SIGNAL_FUNC) event_autoignore_new);
signal_add("autoignore remove", (SIGNAL_FUNC) event_autoignore_remove); signal_add("autoignore remove", (SIGNAL_FUNC) event_autoignore_remove);
theme_register(fecommon_irc_flood_formats);
} }
void fe_flood_deinit(void) void fe_flood_deinit(void)
{ {
theme_unregister();
signal_remove("autoignore new", (SIGNAL_FUNC) event_autoignore_new); signal_remove("autoignore new", (SIGNAL_FUNC) event_autoignore_new);
signal_remove("autoignore remove", (SIGNAL_FUNC) event_autoignore_remove); signal_remove("autoignore remove", (SIGNAL_FUNC) event_autoignore_remove);
} }

View File

@ -23,11 +23,13 @@
FORMAT_REC fecommon_irc_flood_formats[] = 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 } }, { "autoignore", "Flood detected from %_$0%_, autoignoring for %_$1%_ minutes", 2, { 0, 1 } },
{ "autounignore", "Unignoring %_$0", 1, { 0 } } { "autounignore", "Unignoring %_$0", 1, { 0 } },
{ NULL, NULL, 0 }
}; };

View File

@ -10,6 +10,3 @@ enum {
}; };
extern FORMAT_REC fecommon_irc_flood_formats[]; extern FORMAT_REC fecommon_irc_flood_formats[];
#define MODULE_FORMATS fecommon_irc_flood_formats
#include "printformat.h"

View File

@ -0,0 +1,3 @@
#include "common.h"
#define MODULE_NAME "fe-common/irc/flood"

View File

@ -21,173 +21,173 @@
#include "module.h" #include "module.h"
#include "printtext.h" #include "printtext.h"
FORMAT_REC fecommon_irc_formats[] = FORMAT_REC fecommon_irc_formats[] = {
{ { MODULE_NAME, "IRC", 0 },
{ MODULE_NAME, "IRC", 0 },
/* ---- */ /* ---- */
{ NULL, "Server", 0 }, { NULL, "Server", 0 },
{ "lag_disconnected", "No PONG reply from server %_$0%_ in $1 seconds, disconnecting", 2, { 0, 1 } }, { "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 } }, { "disconnected", "Disconnected from %_$0%_ %K[%n$1%K]", 2, { 0, 0 } },
{ "server_list", "%_$0%_: $1:$2 ($3)", 5, { 0, 0, 1, 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_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_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_removed", "Removed reconnection to server %_$0%_ port %_$1%_", 3, { 0, 1, 0 } },
{ "server_reconnect_not_found", "Reconnection tag %_$0%_ not found", 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 } }, { "query_server_changed", "Query with %_$2%_ changed to server %_$1%_", 3, { 0, 0, 0 } },
{ "setupserver_added", "Server $0 saved", 2, { 0, 0 } }, { "setupserver_added", "Server $0 saved", 2, { 0, 0 } },
{ "setupserver_removed", "Server $0 removed", 2, { 0, 0 } }, { "setupserver_removed", "Server $0 removed", 2, { 0, 0 } },
{ "setupserver_not_found", "Server $0 not found", 2, { 0, 0 } }, { "setupserver_not_found", "Server $0 not found", 2, { 0, 0 } },
{ "setupserver_header", "Server Port IRC Net Settings", 0 }, { "setupserver_header", "Server Port IRC Net Settings", 0 },
{ "setupserver_line", "%|$[!20]0 $[5]1 $[10]2 $3", 4, { 0, 1, 0, 0 } }, { "setupserver_line", "%|$[!20]0 $[5]1 $[10]2 $3", 4, { 0, 1, 0, 0 } },
{ "setupserver_footer", "", 0 }, { "setupserver_footer", "", 0 },
{ "netsplit", "[%_$2%_] %RNetsplit%n detected between servers %_$0%_ and %_$1%_%:Use /NETSPLIT to see who left", 3, { 0, 0, 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 }, { "no_netsplits", "There are no net splits", 0 },
{ "netsplits_header", "Nick Channel Server Splitted server", 0 }, { "netsplits_header", "Nick Channel Server Splitted server", 0 },
{ "netsplits_line", "$[9]0 $[10]1 $[20]2 $3", 4, { 0, 0, 0, 0 } }, { "netsplits_line", "$[9]0 $[10]1 $[20]2 $3", 4, { 0, 0, 0, 0 } },
{ "netsplits_footer", "", 0 }, { "netsplits_footer", "", 0 },
/* ---- */ /* ---- */
{ NULL, "Channels", 0 }, { NULL, "Channels", 0 },
{ "join", "%c%_$0%_ %K[%c$1%K]%n has joined %_$2", 3, { 0, 0, 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 } }, { "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_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_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_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_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_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_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 } }, { "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 } }, { "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", "%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 } }, { "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 } }, { "invite", "%_$0%_ invites you to %_$1", 2, { 0, 0 } },
{ "inviting", "Inviting $0 to %_$1", 2, { 0, 0 } }, { "inviting", "Inviting $0 to %_$1", 2, { 0, 0 } },
{ "not_invited", "You have not been invited to a channel!", 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 } }, { "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 } }, { "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 } }, { "channel_created", "Channel %_$0%_ created $1", 2, { 0, 0 } },
{ "topic", "Topic for %c$0%K:%n $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 } }, { "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 } }, { "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_unset", "Topic unset by %_$0%_ on %c$1", 2, { 0, 0 } },
{ "topic_info", "Topic set by %_$0%_ %K[%n$1%K]", 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 } }, { "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 } }, { "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 } }, { "channel_mode", "mode/%c$0 %K[%n$1%K]", 2, { 0, 0 } },
{ "bantype", "Ban type changed to %_$0", 1, { 0 } }, { "bantype", "Ban type changed to %_$0", 1, { 0 } },
{ "banlist", "%_$0%_: ban %c$1", 2, { 0, 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 } }, { "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", "%_$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 } }, { "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 } }, { "invitelist", "%_$0%_: invite %c$1", 2, { 0, 0 } },
{ "no_such_channel", "$0: No such channel", 1, { 0 } }, { "no_such_channel", "$0: No such channel", 1, { 0 } },
{ "channel_synced", "Join to %_$0%_ was synced in %_$1%_ secs", 2, { 0, 2 } }, { "channel_synced", "Join to %_$0%_ was synced in %_$1%_ secs", 2, { 0, 2 } },
{ "not_in_channels", "You are not on any channels", 0 }, { "not_in_channels", "You are not on any channels", 0 },
{ "current_channel", "Current channel $0", 1, { 0 } }, { "current_channel", "Current channel $0", 1, { 0 } },
{ "chanlist_header", "You are on the following channels:", 0 }, { "chanlist_header", "You are on the following channels:", 0 },
{ "chanlist_line", "$[-10]0 %|+$1 ($2): $3", 4, { 0, 0, 0, 0 } }, { "chanlist_line", "$[-10]0 %|+$1 ($2): $3", 4, { 0, 0, 0, 0 } },
{ "chansetup_not_found", "Channel $0 not found", 2, { 0, 0 } }, { "chansetup_not_found", "Channel $0 not found", 2, { 0, 0 } },
{ "chansetup_added", "Channel $0 saved", 2, { 0, 0 } }, { "chansetup_added", "Channel $0 saved", 2, { 0, 0 } },
{ "chansetup_removed", "Channel $0 removed", 2, { 0, 0 } }, { "chansetup_removed", "Channel $0 removed", 2, { 0, 0 } },
{ "chansetup_header", "Channel IRC net Password Settings", 0 }, { "chansetup_header", "Channel IRC net Password Settings", 0 },
{ "chansetup_line", "$[15]0 %|$[10]1 $[10]2 $3", 4, { 0, 0, 0, 0 } }, { "chansetup_line", "$[15]0 %|$[10]1 $[10]2 $3", 4, { 0, 0, 0, 0 } },
{ "chansetup_footer", "", 0 }, { "chansetup_footer", "", 0 },
/* ---- */ /* ---- */
{ NULL, "Nick", 0 }, { NULL, "Nick", 0 },
{ "usermode_change", "Mode change %K[%n%_$0%_%K]%n for user %c$1", 2, { 0, 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 } }, { "user_mode", "Your user mode is %K[%n%_$0%_%K]", 1, { 0 } },
{ "away", "You have been marked as being away", 0 }, { "away", "You have been marked as being away", 0 },
{ "unaway", "You are no longer marked as being away", 0 }, { "unaway", "You are no longer marked as being away", 0 },
{ "nick_away", "$0 is away: $1", 2, { 0, 0 } }, { "nick_away", "$0 is away: $1", 2, { 0, 0 } },
{ "no_such_nick", "$0: No such nick/channel", 1, { 0 } }, { "no_such_nick", "$0: No such nick/channel", 1, { 0 } },
{ "your_nick", "Your nickname is $0", 1, { 0 } }, { "your_nick", "Your nickname is $0", 1, { 0 } },
{ "your_nick_changed", "You're now known as %c$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_changed", "%_$0%_ is now known as %c$1", 2, { 0, 0 } },
{ "nick_in_use", "Nick %_$0%_ is already in use", 1, { 0 } }, { "nick_in_use", "Nick %_$0%_ is already in use", 1, { 0 } },
{ "nick_unavailable", "Nick %_$0%_ is temporarily unavailable", 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 } }, { "your_nick_owned", "Your nick is owned by %_$3%_ %K[%n$1@$2%K]", 4, { 0, 0, 0, 0 } },
/* ---- */ /* ---- */
{ NULL, "Who queries", 0 }, { NULL, "Who queries", 0 },
{ "whois", "%_$0%_ %K[%n$1@$2%K]%n%: ircname : $3", 4, { 0, 0, 0, 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", " 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_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_server", " server : $1 %K[%n$2%K]", 3, { 0, 0, 0 } },
{ "whois_oper", " : %_IRC operator%_", 1, { 0 } }, { "whois_oper", " : %_IRC operator%_", 1, { 0 } },
{ "whois_channels", " channels : $1", 2, { 0, 0 } }, { "whois_channels", " channels : $1", 2, { 0, 0 } },
{ "whois_away", " away : $1", 2, { 0, 0 } }, { "whois_away", " away : $1", 2, { 0, 0 } },
{ "end_of_whois", "End of WHOIS", 1, { 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 } }, { "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 } }, { "end_of_who", "End of /WHO list", 1, { 0 } },
/* ---- */ /* ---- */
{ NULL, "Your messages", 0 }, { NULL, "Your messages", 0 },
{ "own_msg", "%K<%n$2%W$0%K>%n %|$1", 3, { 0, 0, 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_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", "%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_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_notice", "%K[%rnotice%K(%R$0%K)]%n $1", 2, { 0, 0 } },
{ "own_me", "%W * $0%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 } }, { "own_ctcp", "%K[%rctcp%K(%R$0%K)]%n $1 $2", 3, { 0, 0, 0 } },
/* ---- */ /* ---- */
{ NULL, "Received messages", 0 }, { NULL, "Received messages", 0 },
{ "pubmsg_me", "%K<%n$2%Y$0%K>%n %|$1", 3, { 0, 0, 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_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", "%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_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", "%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 } }, { "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", "%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 } }, { "msg_private_query", "%K<%R$0%K>%n %|$2", 3, { 0, 0, 0 } },
{ "notice_server", "%g!$0%n $1", 2, { 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", "%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_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 } }, { "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", "%W (*) $0%n $2", 3, { 0, 0, 0 } },
{ "action_private_query", "%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", "%W * $0%n $1", 2, { 0, 0 } },
{ "action_public_channel", "%W * $0%K:%c$1%n $2", 3, { 0, 0, 0 } }, { "action_public_channel", "%W * $0%K:%c$1%n $2", 3, { 0, 0, 0 } },
/* ---- */ /* ---- */
{ NULL, "CTCPs", 0 }, { NULL, "CTCPs", 0 },
{ "ctcp_reply", "CTCP %_$0%_ reply from %_$1%_%K:%n $2", 3, { 0, 0, 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_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_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 } }, { "ctcp_requested", "%g>>> %_$0%_ %K[%g$1%K] %grequested %_$2%_ from %_$3", 4, { 0, 0, 0, 0 } },
/* ---- */ /* ---- */
{ NULL, "Other server events", 0 }, { NULL, "Other server events", 0 },
{ "online", "Users online: %_$0", 1, { 0 } }, { "online", "Users online: %_$0", 1, { 0 } },
{ "pong", "PONG received from $0: $1", 2, { 0, 0 } }, { "pong", "PONG received from $0: $1", 2, { 0, 0 } },
{ "wallops", "%WWALLOP%n $0: $1", 2, { 0, 0 } }, { "wallops", "%WWALLOP%n $0: $1", 2, { 0, 0 } },
{ "action_wallops", "%WWALLOP * $0%n $1", 2, { 0, 0 } }, { "action_wallops", "%WWALLOP * $0%n $1", 2, { 0, 0 } },
{ "error", "%_ERROR%_ $0", 1, { 0 } }, { "error", "%_ERROR%_ $0", 1, { 0 } },
{ "unknown_mode", "Unknown mode character $0", 1, { 0 } }, { "unknown_mode", "Unknown mode character $0", 1, { 0 } },
{ "not_chanop", "You're not channel operator in $0", 1, { 0 } }, { "not_chanop", "You're not channel operator in $0", 1, { 0 } },
/* ---- */ /* ---- */
{ NULL, "Misc", 0 }, { NULL, "Misc", 0 },
{ "ignored", "Ignoring %_$1%_ from %_$0%_", 2, { 0, 0 } }, { "ignored", "Ignoring %_$1%_ from %_$0%_", 2, { 0, 0 } },
{ "unignored", "Unignored %_$0%_", 1, { 0 } }, { "unignored", "Unignored %_$0%_", 1, { 0 } },
{ "ignore_not_found", "%_$0%_ is not being ignored", 1, { 0 } }, { "ignore_not_found", "%_$0%_ is not being ignored", 1, { 0 } },
{ "ignore_no_ignores", "There are no ignores", 0 }, { "ignore_no_ignores", "There are no ignores", 0 },
{ "ignore_header", "Ignorance List:", 0 }, { "ignore_header", "Ignorance List:", 0 },
{ "ignore_line", "$[-4]0 $1: $2 $3 $4", 5, { 1, 0, 0, 0, 0 } }, { "ignore_line", "$[-4]0 $1: $2 $3 $4", 5, { 1, 0, 0, 0, 0 } },
{ "ignore_footer", "", 0 }, { "ignore_footer", "", 0 },
{ "talking_in", "You are now talking in %_$0%_", 1, { 0 } }, { "talking_in", "You are now talking in %_$0%_", 1, { 0 } },
{ "no_query", "No query with %_$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_got", "You have not received a message from anyone yet", 0 },
{ "no_msgs_sent", "You have not sent a message to anyone yet", 0 } { "no_msgs_sent", "You have not sent a message to anyone yet", 0 },
};
{ NULL, NULL, 0 }

View File

@ -162,6 +162,3 @@ enum {
}; };
extern FORMAT_REC fecommon_irc_formats[]; extern FORMAT_REC fecommon_irc_formats[];
#define MODULE_FORMATS fecommon_irc_formats
#include "printformat.h"

View File

@ -13,5 +13,6 @@ libfe_common_irc_notifylist_la_SOURCES = \
fe-notifylist.c \ fe-notifylist.c \
module-formats.c module-formats.c
noinst_headers = \ noinst_HEADERS = \
module.h \
module-formats.h module-formats.h

View File

@ -31,6 +31,8 @@
#include "ircnet-setup.h" #include "ircnet-setup.h"
#include "irc/notifylist/notifylist.h" #include "irc/notifylist/notifylist.h"
#include "themes.h"
/* add the nick of a hostmask to list if it isn't there already */ /* add the nick of a hostmask to list if it isn't there already */
static GSList *mask_add_once(GSList *list, const char *mask) 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) void fe_notifylist_init(void)
{ {
theme_register(fecommon_irc_notifylist_formats);
command_bind("notify", NULL, (SIGNAL_FUNC) cmd_notify); command_bind("notify", NULL, (SIGNAL_FUNC) cmd_notify);
signal_add("notifylist joined", (SIGNAL_FUNC) notifylist_joined); signal_add("notifylist joined", (SIGNAL_FUNC) notifylist_joined);
signal_add("notifylist left", (SIGNAL_FUNC) notifylist_left); signal_add("notifylist left", (SIGNAL_FUNC) notifylist_left);
@ -233,6 +237,8 @@ void fe_notifylist_init(void)
void fe_notifylist_deinit(void) void fe_notifylist_deinit(void)
{ {
theme_unregister();
command_unbind("notify", (SIGNAL_FUNC) cmd_notify); command_unbind("notify", (SIGNAL_FUNC) cmd_notify);
signal_remove("notifylist joined", (SIGNAL_FUNC) notifylist_joined); signal_remove("notifylist joined", (SIGNAL_FUNC) notifylist_joined);
signal_remove("notifylist left", (SIGNAL_FUNC) notifylist_left); signal_remove("notifylist left", (SIGNAL_FUNC) notifylist_left);

View File

@ -23,17 +23,19 @@
FORMAT_REC fecommon_irc_notifylist_formats[] = FORMAT_REC fecommon_irc_notifylist_formats[] =
{ {
{ MODULE_NAME, "Notifylist", 0 }, { MODULE_NAME, "Notifylist", 0 },
/* ---- */ /* ---- */
{ NULL, "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_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_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_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_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_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_online", "On $0: %_$1%_", 2, { 0, 0 } },
{ "notify_offline", "Offline: $0", 1, { 0 } }, { "notify_offline", "Offline: $0", 1, { 0 } },
{ "notify_list", "$0: $1 $2 $3", 4, { 0, 0, 0, 0 } } { "notify_list", "$0: $1 $2 $3", 4, { 0, 0, 0, 0 } },
{ NULL, NULL, 0 },
}; };

View File

@ -16,6 +16,3 @@ enum {
}; };
extern FORMAT_REC fecommon_irc_notifylist_formats[]; extern FORMAT_REC fecommon_irc_notifylist_formats[];
#define MODULE_FORMATS fecommon_irc_notifylist_formats
#include "printformat.h"

View File

@ -0,0 +1,3 @@
#include "common.h"
#define MODULE_NAME "fe-common/irc/notifylist"

View File

@ -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 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 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 != NULL, NULL);
g_return_val_if_fail(gui->cur_text != 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 = g_mem_chunk_alloc(gui->line_chunk);
gui->cur_line->text = gui->cur_text->buffer+gui->cur_text->pos; gui->cur_line->text = gui->cur_text->buffer+gui->cur_text->pos;
gui->cur_line->level = (gint32) GPOINTER_TO_INT(level); gui->cur_line->level = GPOINTER_TO_INT(level);
gui->cur_line->time = time(NULL); gui->cur_line->time = time(NULL);
/* temporarily mark the end of line. */ mark_temp_eol(gui->cur_text);
memcpy(gui->cur_text->buffer+gui->cur_text->pos, "\0\x80", 2);
gui->last_color = -1; gui->last_color = -1;
gui->last_flags = 0; gui->last_flags = 0;
gui->lines = g_list_append(gui->lines, gui->cur_line); gui->lines = g_list_append(gui->lines, gui->cur_line);
if (gui->startline == NULL) if (gui->startline == NULL) {
{ /* first line */
gui->startline = gui->lines; gui->startline = gui->lines;
gui->bottom_startline = gui->lines; gui->bottom_startline = gui->lines;
} }
return gui->cur_line; return gui->cur_line;
} }
static TEXT_CHUNK_REC *create_text_chunk(GUI_WINDOW_REC *gui) static TEXT_CHUNK_REC *create_text_chunk(GUI_WINDOW_REC *gui)
{ {
TEXT_CHUNK_REC *rec; TEXT_CHUNK_REC *rec;
guchar *buffer; char *buffer, *ptr;
gchar *ptr;
g_return_val_if_fail(gui != NULL, NULL); g_return_val_if_fail(gui != NULL, NULL);
rec = g_new(TEXT_CHUNK_REC, 1); rec = g_new(TEXT_CHUNK_REC, 1);
rec->overflow[0] = 0; rec->overflow[0] = 0;
rec->overflow[1] = (char) LINE_CMD_OVERFLOW; rec->overflow[1] = (char) LINE_CMD_OVERFLOW;
rec->pos = 0; rec->pos = 0;
rec->lines = 0; rec->lines = 0;
if (gui->cur_line != NULL && gui->cur_line->text != NULL) if (gui->cur_line != NULL && gui->cur_line->text != NULL) {
{ /* create a link to new block from the old block */
/* mark the next block text block position.. */ buffer = gui->cur_text->buffer + gui->cur_text->pos;
buffer = (guchar *) gui->cur_text->buffer+gui->cur_text->pos; *buffer++ = 0; *buffer++ = (char) LINE_CMD_CONTINUE;
if (gui->cur_text->pos+2+sizeof(gchar *) > LINE_TEXT_CHUNK_SIZE)
g_error("create_text_chunk() : buffer overflow?!"); ptr = rec->buffer;
*buffer++ = 0; *buffer++ = LINE_CMD_CONTINUE; memcpy(buffer, &ptr, sizeof(char *));
ptr = rec->buffer; }
memcpy(buffer, &ptr, sizeof(gchar *));
} gui->cur_text = rec;
gui->cur_text = rec; gui->text_chunks = g_slist_append(gui->text_chunks, rec);
gui->text_chunks = g_slist_append(gui->text_chunks, rec); return rec;
return rec;
} }
static void text_chunk_free(GUI_WINDOW_REC *gui, TEXT_CHUNK_REC *chunk) static void text_chunk_free(GUI_WINDOW_REC *gui, TEXT_CHUNK_REC *chunk)
{ {
g_return_if_fail(gui != NULL); g_return_if_fail(gui != NULL);
g_return_if_fail(chunk != NULL); g_return_if_fail(chunk != NULL);
gui->text_chunks = g_slist_remove(gui->text_chunks, chunk); gui->text_chunks = g_slist_remove(gui->text_chunks, chunk);
g_free(chunk); g_free(chunk);
} }
static void remove_first_line(WINDOW_REC *window) static void remove_first_line(WINDOW_REC *window)
{ {
GUI_WINDOW_REC *gui; GUI_WINDOW_REC *gui;
TEXT_CHUNK_REC *chunk; TEXT_CHUNK_REC *chunk;
g_return_if_fail(window != NULL); g_return_if_fail(window != NULL);
gui = WINDOW_GUI(window); gui = WINDOW_GUI(window);
chunk = gui->text_chunks->data; chunk = gui->text_chunks->data;
if (--chunk->lines == 0) if (--chunk->lines == 0)
text_chunk_free(gui, chunk); text_chunk_free(gui, chunk);
if (gui->startline->prev == NULL) if (gui->startline->prev == NULL) {
{ /* first line in screen removed */
gui->startline = gui->startline->next; gui->startline = gui->startline->next;
gui->subline = 0; gui->subline = 0;
} }
if (gui->bottom_startline->prev == NULL) if (gui->bottom_startline->prev == NULL) {
{ /* bottom line removed (shouldn't happen?) */
gui->bottom_startline = gui->bottom_startline->next; gui->bottom_startline = gui->bottom_startline->next;
gui->bottom_subline = 0; gui->bottom_subline = 0;
} }
window->lines--; window->lines--;
g_mem_chunk_free(gui->line_chunk, gui->lines->data); g_mem_chunk_free(gui->line_chunk, gui->lines->data);
gui->lines = g_list_remove(gui->lines, gui->lines->data); gui->lines = g_list_remove(gui->lines, gui->lines->data);
if (gui->startline->prev == NULL && is_window_visible(window)) if (gui->startline->prev == NULL && is_window_visible(window))
gui_window_redraw(window); gui_window_redraw(window);
} }
static void get_colors(gint flags, gint *fg, gint *bg) static void get_colors(int flags, int *fg, int *bg)
{ {
if (flags & PRINTFLAG_MIRC_COLOR) if (flags & PRINTFLAG_MIRC_COLOR) {
{ /* mirc colors */
/* mirc colors */ *fg = *fg < 0 || *fg > 16 ?
*fg = *fg < 0 || *fg > 16 ? current_theme->default_color : mirc_colors[*fg];
current_theme->default_color : mirc_colors[*fg]; *bg = *bg < 0 || *bg > 16 ? 0 : mirc_colors[*bg];
*bg = *bg < 0 || *bg > 16 ? 0 : mirc_colors[*bg]; } else {
} /* default colors */
else *fg = *fg < 0 || *fg > 15 ?
{ current_theme->default_color : *fg;
/* default colors */ *bg = *bg < 0 || *bg > 15 ? 0 : *bg;
*fg = *fg < 0 || *fg > 15 ?
current_theme->default_color : *fg;
*bg = *bg < 0 || *bg > 15 ? 0 : *bg;
if (*fg > 8) *fg -= 8; if (*fg > 8) *fg -= 8;
} }
if (flags & PRINTFLAG_REVERSE) if (flags & PRINTFLAG_REVERSE) {
{ int tmp;
gint tmp;
tmp = *fg; *fg = *bg; *bg = tmp; tmp = *fg; *fg = *bg; *bg = tmp;
} }
if (*fg == 8) *fg |= ATTR_COLOR8; if (*fg == 8) *fg |= ATTR_COLOR8;
if (flags & PRINTFLAG_BOLD) *fg |= 8; if (flags & PRINTFLAG_BOLD) *fg |= 8;
if (flags & PRINTFLAG_UNDERLINE) *fg |= ATTR_UNDERLINE; if (flags & PRINTFLAG_UNDERLINE) *fg |= ATTR_UNDERLINE;
if (flags & PRINTFLAG_BLINK) *bg |= 0x80; if (flags & PRINTFLAG_BLINK) *bg |= 0x80;
} }
static void linebuf_add(GUI_WINDOW_REC *gui, gchar *str, gint len) static void linebuf_add(GUI_WINDOW_REC *gui, char *str, int len)
{ {
gint left; int left;
if (len == 0) return; if (len == 0) return;
while (gui->cur_text->pos+len >= TEXT_CHUNK_USABLE_SIZE) while (gui->cur_text->pos + len >= TEXT_CHUNK_USABLE_SIZE) {
{ left = TEXT_CHUNK_USABLE_SIZE - gui->cur_text->pos;
left = TEXT_CHUNK_USABLE_SIZE-gui->cur_text->pos; if (str[left-1] == 0) left--; /* don't split the commands */
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); memcpy(gui->cur_text->buffer + gui->cur_text->pos, str, left);
gui->cur_text->pos += len; 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 line_add_colors(GUI_WINDOW_REC *gui, gint fg, gint bg, gint flags) static void line_add_colors(GUI_WINDOW_REC *gui, int fg, int bg, int flags)
{ {
guchar buffer[12]; unsigned char buffer[12];
gint color, pos; int color, pos;
color = (fg & 0x0f) | (bg << 4); color = (fg & 0x0f) | (bg << 4);
pos = 0; pos = 0;
if (((fg & ATTR_COLOR8) == 0 && (fg|(bg << 4)) != gui->last_color) || if (((fg & ATTR_COLOR8) == 0 && (fg|(bg << 4)) != gui->last_color) ||
((fg & ATTR_COLOR8) && (fg & 0xf0) != (gui->last_color & 0xf0))) ((fg & ATTR_COLOR8) && (fg & 0xf0) != (gui->last_color & 0xf0))) {
{ buffer[pos++] = 0;
buffer[pos++] = 0; buffer[pos++] = color;
buffer[pos++] = (gchar) color; }
}
if ((flags & PRINTFLAG_UNDERLINE) != (gui->last_flags & PRINTFLAG_UNDERLINE)) if ((flags & PRINTFLAG_UNDERLINE) != (gui->last_flags & PRINTFLAG_UNDERLINE)) {
{ buffer[pos++] = 0;
buffer[pos++] = 0; buffer[pos++] = LINE_CMD_UNDERLINE;
buffer[pos++] = LINE_CMD_UNDERLINE; }
} if (fg & ATTR_COLOR8) {
if (fg & ATTR_COLOR8) buffer[pos++] = 0;
{ buffer[pos++] = LINE_CMD_COLOR8;
buffer[pos++] = 0; }
buffer[pos++] = LINE_CMD_COLOR8; if (flags & PRINTFLAG_BEEP) {
} buffer[pos++] = 0;
if (flags & PRINTFLAG_BEEP) buffer[pos++] = LINE_CMD_BEEP;
{ }
buffer[pos++] = 0; if (flags & PRINTFLAG_INDENT) {
buffer[pos++] = LINE_CMD_BEEP; buffer[pos++] = 0;
} buffer[pos++] = LINE_CMD_INDENT;
if (flags & PRINTFLAG_INDENT) }
{
buffer[pos++] = 0;
buffer[pos++] = LINE_CMD_INDENT;
}
linebuf_add(gui, (gchar *) buffer, pos); linebuf_add(gui, (char *) buffer, pos);
gui->last_flags = flags; gui->last_flags = flags;
gui->last_color = fg | (bg << 4); gui->last_color = fg | (bg << 4);
} }
static void gui_printtext(WINDOW_REC *window, gpointer fgcolor, gpointer bgcolor, gpointer pflags, gchar *str, gpointer level) static void gui_printtext(WINDOW_REC *window, gpointer fgcolor, gpointer bgcolor, gpointer pflags, char *str, gpointer level)
{ {
GUI_WINDOW_REC *gui; GUI_WINDOW_REC *gui;
LINE_REC *line; LINE_REC *line;
gboolean visible; int fg, bg, flags, new_lines, n, visible, ypos;
gint fg, bg, flags, lines, n;
g_return_if_fail(window != NULL); g_return_if_fail(window != NULL);
gui = WINDOW_GUI(window); gui = WINDOW_GUI(window);
if (max_textwidget_lines > 0 && max_textwidget_lines <= window->lines) if (max_textwidget_lines > 0 && max_textwidget_lines <= window->lines)
remove_first_line(window); remove_first_line(window);
visible = is_window_visible(window) && gui->bottom; visible = is_window_visible(window) && gui->bottom;
flags = GPOINTER_TO_INT(pflags); flags = GPOINTER_TO_INT(pflags);
fg = GPOINTER_TO_INT(fgcolor); fg = GPOINTER_TO_INT(fgcolor);
bg = GPOINTER_TO_INT(bgcolor); bg = GPOINTER_TO_INT(bgcolor);
if (gui->cur_text == NULL) if (gui->cur_text == NULL)
create_text_chunk(gui); create_text_chunk(gui);
/* \n can be only at the start of the line.. */ /* \n can be only at the start of the line.. */
if (*str == '\n') if (*str == '\n') {
{ str++;
linebuf_add(gui, "\0\x80", 2); /* mark EOL */ 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 = create_line(gui, 0);
line_add_colors(gui, fg, bg, flags); gui_window_newline(gui, visible);
linebuf_add(gui, str, strlen(str));
/* temporarily mark the end of line. */ gui->cur_text->lines++;
memcpy(gui->cur_text->buffer+gui->cur_text->pos, "\0\x80", 2); 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);
}
if (visible) get_colors(flags, &fg, &bg);
{ line_add_colors(gui, fg, bg, flags);
/* draw the line to screen. */ linebuf_add(gui, str, strlen(str));
lines = gui_window_line_draw(gui, line, gui->parent->first_line+gui->ypos, gui->last_subline, -1); mark_temp_eol(gui->cur_text);
}
else gui_window_cache_remove(gui, line);
{ new_lines = gui_window_get_linecount(gui, line)-1 - gui->last_subline;
/* we still need to update the bottom's position */
lines = gui_window_get_linecount(gui, line)-1-gui->last_subline; for (n = 0; n < new_lines; n++)
for (n = 0; n < lines; n++) gui_window_newline(gui, visible);
gui_window_newline(gui, visible);
} if (visible) {
if (lines > 0) gui->last_subline += lines; /* 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 cmd_clear(gchar *data) static void window_clear(GUI_WINDOW_REC *gui)
{ {
GUI_WINDOW_REC *gui; int n;
gint n;
gui = WINDOW_GUI(active_win); for (n = gui->parent->first_line; n <= gui->parent->last_line; n++) {
move(n, 0);
clrtoeol();
}
screen_refresh();
}
if (is_window_visible(active_win)) static void cmd_clear(void)
{ {
for (n = gui->parent->first_line; n <= gui->parent->last_line; n++) GUI_WINDOW_REC *gui;
{
move(n, 0);
clrtoeol();
}
screen_refresh();
}
gui->ypos = -1; gui = WINDOW_GUI(active_win);
gui->bottom_startline = gui->startline = g_list_last(gui->lines);
gui->bottom_subline = gui->subline = gui->last_subline+1; if (is_window_visible(active_win))
gui->empty_linecount = gui->parent->last_line-gui->parent->first_line+1; window_clear(gui);
gui->bottom = TRUE;
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) static void sig_printtext_finished(WINDOW_REC *window)
@ -321,18 +316,18 @@ static void read_settings(void)
void gui_printtext_init(void) void gui_printtext_init(void)
{ {
signal_add("gui print text", (SIGNAL_FUNC) gui_printtext); 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("print text finished", (SIGNAL_FUNC) sig_printtext_finished); signal_add("setup changed", (SIGNAL_FUNC) read_settings);
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) void gui_printtext_deinit(void)
{ {
signal_remove("gui print text", (SIGNAL_FUNC) gui_printtext); 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("print text finished", (SIGNAL_FUNC) sig_printtext_finished); signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
signal_remove("setup changed", (SIGNAL_FUNC) read_settings); command_unbind("clear", (SIGNAL_FUNC) cmd_clear);
} }

View File

@ -46,6 +46,7 @@ static GUI_WINDOW_REC *gui_window_init(WINDOW_REC *window, MAIN_WINDOW_REC *pare
gui->parent = parent; gui->parent = parent;
gui->bottom = TRUE; 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), gui->line_chunk = g_mem_chunk_new("line chunk", sizeof(LINE_REC),
sizeof(LINE_REC)*100, G_ALLOC_AND_FREE); sizeof(LINE_REC)*100, G_ALLOC_AND_FREE);
gui->empty_linecount = parent->last_line-parent->first_line; 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; 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) 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_foreach(gui->text_chunks, (GFunc) g_free, NULL);
g_slist_free(gui->text_chunks); g_slist_free(gui->text_chunks);
@ -106,7 +118,7 @@ static void gui_window_destroyed(WINDOW_REC *window)
gui_window_deinit(gui); gui_window_deinit(gui);
window->gui_data = NULL; window->gui_data = NULL;
if (mainwindows->next != NULL && parent->active == window) if (parent->active == window && mainwindows->next != NULL)
mainwindow_destroy(parent); mainwindow_destroy(parent);
} }
@ -126,322 +138,337 @@ void gui_window_clear(WINDOW_REC *window)
gui_window_redraw(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; int linecount, last_linecount;
if (gui->bottom_startline == NULL) if (gui->bottom_startline == NULL)
return -1;
while (lines < 0)
{
if (gui->bottom_subline > 0)
gui->bottom_subline--;
else
{
if (gui->bottom_startline->prev == NULL)
return -1; return -1;
gui->bottom_startline = gui->bottom_startline->prev;
linecount = gui_window_get_linecount(gui, gui->bottom_startline->data); for (; lines < 0; lines++) {
gui->bottom_subline = linecount-1; if (gui->bottom_subline > 0) {
} gui->bottom_subline--;
lines++; continue;
}
last_linecount = linecount = -1;
while (lines > 0)
{
if (linecount == -1)
last_linecount = linecount = gui_window_get_linecount(gui, gui->bottom_startline->data);
if (linecount > gui->bottom_subline+1)
gui->bottom_subline++;
else
{
gui->bottom_subline = 0;
linecount = -1;
if (gui->bottom_startline->next == NULL)
break;
gui->bottom_startline = gui->bottom_startline->next;
}
lines--;
}
return last_linecount;
}
void gui_window_newline(GUI_WINDOW_REC *gui, gboolean visible)
{
gboolean last_line;
gint linecount;
g_return_if_fail(gui != NULL);
gui->xpos = 0;
last_line = gui->ypos >= gui->parent->last_line-gui->parent->first_line;
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 (!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;
linecount = gui_window_update_bottom(gui, 1);
}
if (linecount > 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)
{
gchar *ptr, *last_space_ptr, *tmp;
gint lines, xpos, indent_pos, last_space;
g_return_val_if_fail(gui != NULL, -1);
g_return_val_if_fail(line != NULL, -1);
if (line->text == NULL)
return 0;
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;
}
if (xpos == COLS)
{
xpos = indent_pos >= COLS-5 ? DEFAULT_INDENT_POS : indent_pos;
if (last_space > indent_pos && last_space > 10)
{
ptr = last_space_ptr;
while (*ptr == ' ') ptr++;
}
last_space = 0;
lines++;
ptr--;
continue;
}
xpos++;
if (*ptr == ' ')
{
last_space = xpos-1;
last_space_ptr = ptr+1;
}
}
}
/* draw line - ugly code.. */
gint gui_window_line_draw(GUI_WINDOW_REC *gui, LINE_REC *line, gint ypos, gint skip, gint max)
{
gchar *ptr, *last_space_ptr, *tmp;
gint lines, xpos, color, indent_pos, last_space, last_space_color;
g_return_val_if_fail(gui != NULL, -1);
g_return_val_if_fail(line != NULL, -1);
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;
}
if (xpos == COLS)
{
xpos = indent_pos >= COLS-5 ? DEFAULT_INDENT_POS : indent_pos;
if (last_space > indent_pos && last_space > 10)
{
/* remove the last word */
if (!skip)
{
move(ypos, last_space);
set_color(0);
clrtoeol();
} }
/* skip backwards to draw the line again. */ if (gui->bottom_startline->prev == NULL)
ptr = last_space_ptr; return -1;
color = last_space_color; gui->bottom_startline = gui->bottom_startline->prev;
if (!skip) set_color(color);
while (*ptr == ' ') ptr++;
}
last_space = 0;
if (skip > 0) linecount = gui_window_get_linecount(gui, gui->bottom_startline->data);
{ gui->bottom_subline = linecount-1;
if (--skip == 0) set_color(color); }
}
else last_linecount = -1;
{ for (; lines > 0; lines--) {
if (lines == max) last_linecount = linecount =
return lines; gui_window_get_linecount(gui, gui->bottom_startline->data);
if (max != -1)
ypos++; if (linecount > gui->bottom_subline+1)
else gui->bottom_subline++;
{ else {
gui_window_newline(gui, TRUE); gui->bottom_subline = 0;
ypos = gui->parent->first_line+gui->ypos; if (gui->bottom_startline->next == NULL)
break;
gui->bottom_startline = gui->bottom_startline->next;
} }
lines++; lines--;
}
move(ypos, indent_pos);
/* we could have \0.. */
ptr--;
continue;
} }
xpos++; return last_linecount;
if (*ptr == ' ') }
{
last_space = xpos-1; void gui_window_newline(GUI_WINDOW_REC *gui, int visible)
last_space_color = color; {
last_space_ptr = ptr+1; int lines;
g_return_if_fail(gui != NULL);
gui->xpos = 0;
if (gui->empty_linecount > 0) {
/* window buffer height isn't even the size of the screen yet */
gui->empty_linecount--;
gui->ypos++;
return;
} }
if (skip) continue; lines = gui_window_update_bottom(gui, 1);
if (lines == -1) lines = 0;
if ((guchar) *ptr >= 32) if (!gui->bottom) {
addch((guchar) *ptr); gui->ypos++;
else return;
{
/* low-ascii */
set_color(ATTR_REVERSE);
addch(*ptr+'A'-1);
set_color(color);
} }
}
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 (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();
}
}
static LINE_CACHE_REC *gui_window_line_cache(GUI_WINDOW_REC *gui, LINE_REC *line)
{
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;
}
if (xpos == COLS) {
xpos = indent_pos;
if (last_space > indent_pos && last_space > 10) {
/* go back to last space */
ptr = last_space_ptr;
while (*ptr == ' ') ptr++;
}
sub = g_new(LINE_CACHE_SUB_REC, 1);
sub->start = ptr;
sub->indent = indent_pos;
sub->color = color;
lines = g_slist_append(lines, sub);
rec->count++;
last_space = 0;
continue;
}
xpos++;
if (*ptr++ == ' ') {
last_space = xpos-1;
last_space_ptr = ptr;
}
}
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;
}
void gui_window_cache_remove(GUI_WINDOW_REC *gui, LINE_REC *line)
{
LINE_CACHE_REC *cache;
g_return_if_fail(gui != NULL);
g_return_if_fail(line != NULL);
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);
}
}
int gui_window_get_linecount(GUI_WINDOW_REC *gui, LINE_REC *line)
{
LINE_CACHE_REC *cache;
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);
return cache->count;
}
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;
if (rec == NULL) {
xpos = 0; color = 0;
} else {
xpos = rec->indent;
color = rec->color;
}
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 (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) void gui_window_redraw(WINDOW_REC *window)
{ {
GUI_WINDOW_REC *gui; GUI_WINDOW_REC *gui;
GList *line; GList *line;
gint ypos, lines, skip, max; 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); set_color(0);
move(ypos, 0); for (ypos = gui->parent->first_line; ypos <= gui->parent->last_line; ypos++) {
clrtoeol(); move(ypos, 0);
} clrtoeol();
}
skip = gui->subline; skip = gui->subline;
ypos = gui->parent->first_line; ypos = gui->parent->first_line;
for (line = gui->startline; line != NULL; line = line->next) for (line = gui->startline; line != NULL; line = line->next) {
{ LINE_REC *rec = line->data;
LINE_REC *rec = line->data;
max = gui->parent->last_line - ypos; max = gui->parent->last_line - ypos+1;
if (max < 0) break; if (max < 0) break;
lines = gui_window_line_draw(gui, rec, ypos, skip, max); lines = gui_window_line_draw(gui, rec, ypos, skip, max);
skip = 0; ypos += lines-skip;
skip = 0;
}
ypos += lines+1; screen_refresh();
}
screen_refresh();
} }
static void gui_window_scroll_up(GUI_WINDOW_REC *gui, gint lines) 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); g_return_if_fail(window != NULL);
if (quitting) return;
if (is_window_visible(window)) { if (is_window_visible(window)) {
/* already visible, great! */ /* already visible, great! */
active_mainwin = WINDOW_GUI(window)->parent; active_mainwin = WINDOW_GUI(window)->parent;
@ -674,6 +703,8 @@ static void gui_window_horiz_resize(WINDOW_REC *window)
gui = WINDOW_GUI(window); gui = WINDOW_GUI(window);
if (gui->lines == NULL) return; 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); linecount = gui_window_get_linecount(gui, g_list_last(gui->lines)->data);
gui->last_subline = linecount-1; gui->last_subline = linecount-1;
@ -703,7 +734,8 @@ void gui_window_resize(WINDOW_REC *window, int ychange, int xchange)
gui = WINDOW_GUI(window); gui = WINDOW_GUI(window);
if (xchange) { 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); gui_window_horiz_resize(window);
return; return;
} }

View File

@ -22,6 +22,17 @@ enum {
LINE_CMD_INDENT /* if line is split, indent it at this position */ LINE_CMD_INDENT /* if line is split, indent it at this position */
}; };
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 { typedef struct {
/* text in the line. \0 means that the next char will be a /* 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 color or command. <= 127 = color or if 8.bit is set, the
@ -45,6 +56,7 @@ typedef struct {
GMemChunk *line_chunk; GMemChunk *line_chunk;
GSList *text_chunks; GSList *text_chunks;
GList *lines; GList *lines;
GHashTable *line_cache;
LINE_REC *cur_line; LINE_REC *cur_line;
TEXT_CHUNK_REC *cur_text; 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 */ /* get number of real lines that line record takes */
int gui_window_get_linecount(GUI_WINDOW_REC *gui, LINE_REC *line); 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); 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); 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 gui_window_reparent(WINDOW_REC *window, MAIN_WINDOW_REC *parent);
void window_update_prompt(WINDOW_REC *window); void window_update_prompt(WINDOW_REC *window);
void gui_window_newline(GUI_WINDOW_REC *gui, gboolean visible); void gui_window_newline(GUI_WINDOW_REC *gui, int visible);
int gui_window_update_bottom(GUI_WINDOW_REC *gui, int lines);
void gui_window_scroll(WINDOW_REC *window, int lines); void gui_window_scroll(WINDOW_REC *window, int lines);
#endif #endif

View File

@ -19,6 +19,7 @@
*/ */
#include "module.h" #include "module.h"
#include "module-formats.h"
#include "args.h" #include "args.h"
#include "signals.h" #include "signals.h"
#include "core.h" #include "core.h"
@ -26,6 +27,7 @@
#include "irc-core.h" #include "irc-core.h"
#include "fe-common-core.h" #include "fe-common-core.h"
#include "fe-common-irc.h" #include "fe-common-irc.h"
#include "themes.h"
#include "screen.h" #include "screen.h"
#include "gui-entry.h" #include "gui-entry.h"
@ -82,6 +84,8 @@ static void textui_init(void)
irc_init(); irc_init();
fe_common_core_init(); fe_common_core_init();
fe_common_irc_init(); fe_common_irc_init();
theme_register(gui_text_formats);
signal_add("gui exit", (SIGNAL_FUNC) sig_exit); signal_add("gui exit", (SIGNAL_FUNC) sig_exit);
} }
@ -91,11 +95,11 @@ static void textui_finish_init(void)
screen_refresh_freeze(); screen_refresh_freeze();
gui_entry_init(); gui_entry_init();
mainwindows_init();
gui_printtext_init(); gui_printtext_init();
gui_readline_init(); gui_readline_init();
gui_special_vars_init(); gui_special_vars_init();
gui_textwidget_init(); gui_textwidget_init();
mainwindows_init();
gui_windows_init(); gui_windows_init();
statusbar_init(); statusbar_init();
@ -123,11 +127,13 @@ static void textui_deinit(void)
statusbar_deinit(); statusbar_deinit();
gui_printtext_deinit(); gui_printtext_deinit();
gui_readline_deinit(); gui_readline_deinit();
mainwindows_deinit();
gui_windows_deinit(); gui_windows_deinit();
mainwindows_deinit();
gui_entry_deinit(); gui_entry_deinit();
deinit_screen(); deinit_screen();
theme_unregister();
fe_common_irc_deinit(); fe_common_irc_deinit();
fe_common_core_deinit(); fe_common_core_deinit();
irc_deinit(); irc_deinit();

View File

@ -347,6 +347,17 @@ static void mainwindows_resize_bigger(int ychange, int xchange)
g_slist_free(sorted); 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) void mainwindows_resize(int ychange, int xchange)
{ {
screen_refresh_freeze(); screen_refresh_freeze();
@ -354,6 +365,8 @@ void mainwindows_resize(int ychange, int xchange)
mainwindows_resize_smaller(ychange, xchange); mainwindows_resize_smaller(ychange, xchange);
else if (ychange > 0) else if (ychange > 0)
mainwindows_resize_bigger(ychange, xchange); mainwindows_resize_bigger(ychange, xchange);
else if (xchange != 0)
mainwindows_resize_horiz(xchange);
irssi_redraw(); irssi_redraw();
screen_refresh_thaw(); screen_refresh_thaw();
@ -595,6 +608,9 @@ void mainwindows_init(void)
void mainwindows_deinit(void) void mainwindows_deinit(void)
{ {
while (mainwindows != NULL)
mainwindow_destroy(mainwindows->data);
command_unbind("window grow", (SIGNAL_FUNC) cmd_window_grow); command_unbind("window grow", (SIGNAL_FUNC) cmd_window_grow);
command_unbind("window shrink", (SIGNAL_FUNC) cmd_window_shrink); command_unbind("window shrink", (SIGNAL_FUNC) cmd_window_shrink);
command_unbind("window size", (SIGNAL_FUNC) cmd_window_size); command_unbind("window size", (SIGNAL_FUNC) cmd_window_size);

View File

@ -23,11 +23,13 @@
FORMAT_REC gui_text_formats[] = FORMAT_REC gui_text_formats[] =
{ {
{ MODULE_NAME, "Text user interface", 0 }, { MODULE_NAME, "Text user interface", 0 },
{ "lastlog_start", "%_Lastlog:", 0 }, { "lastlog_start", "%_Lastlog:", 0 },
{ "lastlog_end", "%_End of Lastlog", 0 }, { "lastlog_end", "%_End of Lastlog", 0 },
{ "window_too_small", "Not enough room to resize this window", 0 }, { "window_too_small", "Not enough room to resize this window", 0 },
{ "cant_hide_last", "You can't hide the last window", 0 } { "cant_hide_last", "You can't hide the last window", 0 },
{ NULL, NULL, 0 }
}; };

View File

@ -11,6 +11,3 @@ enum {
}; };
extern FORMAT_REC gui_text_formats[]; extern FORMAT_REC gui_text_formats[];
#define MODULE_FORMATS gui_text_formats
#include "printformat.h"

View File

@ -12,6 +12,7 @@ libirc_core_la_SOURCES = \
channels-query.c \ channels-query.c \
channels-setup.c \ channels-setup.c \
channel-events.c \ channel-events.c \
channel-rejoin.c \
ignore.c \ ignore.c \
irc.c \ irc.c \
irc-core.c \ irc-core.c \

View File

@ -54,7 +54,7 @@ static void event_target_unavailable(const char *data, IRC_SERVER_REC *server)
params = event_get_params(data, 2, NULL, &channel); params = event_get_params(data, 2, NULL, &channel);
if (ischannel(*channel)) { if (ischannel(*channel)) {
/* channel is unavailable. */ /* channel is unavailable - try to join again a bit later */
event_cannot_join(data, server); event_cannot_join(data, server);
} }

View File

@ -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);
}

View File

@ -38,6 +38,9 @@ void channels_query_deinit(void);
void channel_events_init(void); void channel_events_init(void);
void channel_events_deinit(void); void channel_events_deinit(void);
void channel_rejoin_init(void);
void channel_rejoin_deinit(void);
void massjoin_init(void); void massjoin_init(void);
void massjoin_deinit(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; SETUP_CHANNEL_REC *schannel;
CHANNEL_REC *chanrec; CHANNEL_REC *chanrec;
GString *outchans, *outkeys; GString *outchans, *outkeys;
char *params, *channels, *keys; char *params, *channels, *keys, *key;
char **chanlist, **keylist, **tmp, **tmpkey, *channel; char **chanlist, **keylist, **tmp, **tmpkey, *channel;
int use_keys; 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); schannel = channels_setup_find(channel, server->connrec->ircnet);
g_string_sprintfa(outchans, "%s,", channel); g_string_sprintfa(outchans, "%s,", channel);
if (schannel == NULL || schannel->password == NULL) if (schannel == NULL || schannel->password == NULL) {
g_string_sprintfa(outkeys, "%s,", get_join_key(*tmpkey)); key = *tmpkey == NULL || **tmpkey == '\0' ? NULL : *tmpkey;
else { } else {
/* get password from setup record */ /* get password from setup record */
use_keys = TRUE; 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); g_free(channel);
@ -204,6 +209,8 @@ void channels_join(IRC_SERVER_REC *server, const char *data, int automatic)
} }
if (outchans->len > 0) { 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", irc_send_cmdv(server, use_keys ? "JOIN %s %s" : "JOIN %s",
outchans->str, outkeys->str); outchans->str, outkeys->str);
} }
@ -220,6 +227,7 @@ void channels_join(IRC_SERVER_REC *server, const char *data, int automatic)
void channels_init(void) void channels_init(void)
{ {
channel_events_init(); channel_events_init();
channel_rejoin_init();
channels_query_init(); channels_query_init();
channels_setup_init(); channels_setup_init();
@ -233,6 +241,7 @@ void channels_init(void)
void channels_deinit(void) void channels_deinit(void)
{ {
channel_events_deinit(); channel_events_deinit();
channel_rejoin_deinit();
channels_query_deinit(); channels_query_deinit();
channels_setup_deinit(); channels_setup_deinit();

View File

@ -26,20 +26,6 @@
#include "irc-server.h" #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) static void event_away(const char *data, IRC_SERVER_REC *server)
{ {
const char *fname, *levelstr; 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_file", "~/.irssi/away.log");
settings_add_str("log", "awaylog_level", "msgs hilight"); 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 306", (SIGNAL_FUNC) event_away);
signal_add("event 305", (SIGNAL_FUNC) event_unaway); signal_add("event 305", (SIGNAL_FUNC) event_unaway);
} }
void irc_log_deinit(void) 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 306", (SIGNAL_FUNC) event_away);
signal_remove("event 305", (SIGNAL_FUNC) event_unaway); signal_remove("event 305", (SIGNAL_FUNC) event_unaway);
} }

View File

@ -129,6 +129,9 @@ typedef struct {
GSList *channels; GSList *channels;
GSList *queries; 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; gpointer chanqueries;
} IRC_SERVER_REC; } IRC_SERVER_REC;

View File

@ -293,7 +293,7 @@ static void setupserver_destroy(SETUP_SERVER_REC *rec)
g_free_not_null(rec->own_ip); g_free_not_null(rec->own_ip);
g_free(rec->ircnet); g_free(rec->ircnet);
g_free(rec->address); g_free(rec->address);
g_free(rec->password); g_free_not_null(rec->password);
g_free(rec); g_free(rec);
} }

View File

@ -308,12 +308,12 @@ static void cmd_dcc_chat(gchar *data, IRC_SERVER_REC *server)
cmd_return_error(CMDERR_NOT_CONNECTED); cmd_return_error(CMDERR_NOT_CONNECTED);
if (net_getsockname(server->handle, &addr, NULL) == -1) if (net_getsockname(server->handle, &addr, NULL) == -1)
cmd_return_error(CMDERR_GETSOCKNAME); cmd_return_error(CMDERR_ERRNO);
port = settings_get_int("dcc_port"); port = settings_get_int("dcc_port");
handle = net_listen(&addr, &port); handle = net_listen(&addr, &port);
if (handle == -1) 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 = dcc_create(DCC_TYPE_CHAT, handle, data, "chat", server, NULL);
dcc->tagread = g_input_add(dcc->handle, G_INPUT_READ, dcc->tagread = g_input_add(dcc->handle, G_INPUT_READ,

View File

@ -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) if (net_getsockname(chat != NULL ? chat->handle : server->handle, &addr, NULL) == -1)
{ {
close(fh); close(fh);
cmd_param_error(CMDERR_GETSOCKNAME); cmd_param_error(CMDERR_ERRNO);
} }
/* start listening */ /* start listening */
@ -522,7 +522,7 @@ static void cmd_dcc_send(gchar *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
if (h == -1) if (h == -1)
{ {
close(fh); close(fh);
cmd_param_error(CMDERR_LISTEN); cmd_param_error(CMDERR_ERRNO);
} }
/* skip path */ /* skip path */

View File

@ -143,6 +143,9 @@ static void signal_destroy_hash(void *key, GSList *list)
while (list != NULL) { while (list != NULL) {
PERL_SIGNAL_REC *rec = list->data; 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); list = g_slist_remove(list, rec);
g_free(rec->signal); g_free(rec->signal);