forked from PsychoticNinja/ailin-nemui-irssi
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:
parent
969cfe8abc
commit
cbdaf7d06d
22
TODO
22
TODO
@ -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
|
||||
- mites se awaylogi? se /cattaamaan myös se /away:n jälkeen
|
||||
- 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
|
||||
Cannot join channel (illegal name)
|
||||
@ -19,15 +27,6 @@ lis
|
||||
- gnome versio..
|
||||
- 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..
|
||||
- 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!
|
||||
- /exec
|
||||
- autorun.ircnet
|
||||
- channel not available rejoini
|
||||
|
||||
*** Bugs
|
||||
|
||||
|
@ -201,7 +201,7 @@ dnl **
|
||||
if test "x$want_textui" = "xyes"; then
|
||||
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_DEFINE(HAVE_NCURSES_USE_DEFAULT_COLORS)
|
||||
],, $CURSES_LIBS)
|
||||
|
10
curses.m4
10
curses.m4
@ -131,13 +131,7 @@ AC_DEFUN(AC_CHECK_CURSES,[
|
||||
if test x$withval = xno ; then
|
||||
search_ncurses=false
|
||||
elif test x$withval != xyes ; then
|
||||
CURSES_LIBS="$LIBS -L$withval/lib -lncurses"
|
||||
CURSES_INCLUDEDIR="-I$withval/include"
|
||||
search_ncurses=false
|
||||
screen_manager="ncurses"
|
||||
AC_DEFINE(USE_NCURSES)
|
||||
AC_DEFINE(HAS_CURSES)
|
||||
has_curses=true
|
||||
AC_NCURSES($withval/include, ncurses.h, -L$withval/lib -lncurses, -I$withval/include, "ncurses on $withval/include")
|
||||
fi
|
||||
)
|
||||
|
||||
@ -222,6 +216,7 @@ AC_DEFUN(AC_NCURSES, [
|
||||
screen_manager=$5
|
||||
AC_DEFINE(HAS_CURSES)
|
||||
has_curses=true
|
||||
has_ncurses=true
|
||||
AC_DEFINE(USE_NCURSES)
|
||||
fi
|
||||
fi
|
||||
@ -256,6 +251,7 @@ USE_NCURSES
|
||||
CURSES_INCLUDEDIR="$CURSES_INCLUDEDIR -DRENAMED_NCURSES"
|
||||
AC_DEFINE(HAS_CURSES)
|
||||
has_curses=true
|
||||
has_ncurses=true
|
||||
AC_DEFINE(USE_NCURSES)
|
||||
search_ncurses=false
|
||||
screen_manager="ncurses installed as curses"
|
||||
|
@ -436,8 +436,24 @@ static void cmd_cd(const char *data)
|
||||
g_free(str);
|
||||
}
|
||||
|
||||
static void cmd_rehash(const char *data)
|
||||
{
|
||||
char *fname;
|
||||
|
||||
fname = *data != '\0' ? g_strdup(data) :
|
||||
g_strdup_printf("%s/.irssi/config", g_get_home_dir());
|
||||
settings_reread(fname);
|
||||
g_free(fname);
|
||||
}
|
||||
|
||||
static void cmd_save(const char *data)
|
||||
{
|
||||
settings_save(*data != '\0' ? data : NULL);
|
||||
}
|
||||
|
||||
void commands_init(void)
|
||||
{
|
||||
commands = NULL;
|
||||
cmdget_funcs = NULL;
|
||||
current_command = NULL;
|
||||
|
||||
@ -448,6 +464,8 @@ void commands_init(void)
|
||||
|
||||
command_bind("eval", NULL, (SIGNAL_FUNC) cmd_eval);
|
||||
command_bind("cd", NULL, (SIGNAL_FUNC) cmd_cd);
|
||||
command_bind("rehash", NULL, (SIGNAL_FUNC) cmd_rehash);
|
||||
command_bind("save", NULL, (SIGNAL_FUNC) cmd_save);
|
||||
}
|
||||
|
||||
void commands_deinit(void)
|
||||
@ -459,4 +477,6 @@ void commands_deinit(void)
|
||||
|
||||
command_unbind("eval", (SIGNAL_FUNC) cmd_eval);
|
||||
command_unbind("cd", (SIGNAL_FUNC) cmd_cd);
|
||||
command_unbind("rehash", (SIGNAL_FUNC) cmd_rehash);
|
||||
command_unbind("save", (SIGNAL_FUNC) cmd_save);
|
||||
}
|
||||
|
@ -10,16 +10,11 @@ typedef struct {
|
||||
COMMAND_REC;
|
||||
|
||||
enum {
|
||||
CMDERR_PARAM, /* invalid parameter */
|
||||
CMDERR_ERRNO, /* get the error from errno */
|
||||
CMDERR_NOT_ENOUGH_PARAMS, /* not enough parameters given */
|
||||
CMDERR_NOT_CONNECTED, /* not connected to IRC server */
|
||||
CMDERR_NOT_JOINED, /* not joined to any channels in this window */
|
||||
CMDERR_GETSOCKNAME, /* getsockname() failed */
|
||||
CMDERR_LISTEN, /* listen() failed */
|
||||
CMDERR_MULTIPLE_MATCHES, /* multiple matches found, didn't do anything */
|
||||
CMDERR_NICK_NOT_FOUND, /* nick not found */
|
||||
CMDERR_CHAN_NOT_FOUND, /* channel not found */
|
||||
CMDERR_SERVER_NOT_FOUND, /* server not found */
|
||||
CMDERR_CHAN_NOT_SYNCED, /* channel not fully synchronized yet */
|
||||
CMDERR_NOT_GOOD_IDEA /* not good idea to do, -yes overrides this */
|
||||
};
|
||||
|
@ -43,9 +43,9 @@ void core_init(void)
|
||||
net_disconnect_init();
|
||||
signals_init();
|
||||
settings_init();
|
||||
commands_init();
|
||||
|
||||
servers_init();
|
||||
commands_init();
|
||||
log_init();
|
||||
rawlog_init();
|
||||
special_vars_init();
|
||||
@ -56,9 +56,9 @@ void core_deinit(void)
|
||||
special_vars_deinit();
|
||||
rawlog_deinit();
|
||||
log_deinit();
|
||||
commands_deinit();
|
||||
servers_deinit();
|
||||
|
||||
commands_deinit();
|
||||
settings_deinit();
|
||||
signals_deinit();
|
||||
net_disconnect_deinit();
|
||||
|
@ -132,35 +132,26 @@ static void *data_remove(void *p, const char *file, int line)
|
||||
|
||||
void *ig_malloc(int size, const char *file, int line)
|
||||
{
|
||||
#if 1
|
||||
void *p;
|
||||
|
||||
size += BUFFER_CHECK_SIZE*2;
|
||||
p = g_malloc(size);
|
||||
data_add(p, size, file, line);
|
||||
return p+BUFFER_CHECK_SIZE;
|
||||
#else
|
||||
return g_malloc(size);
|
||||
#endif
|
||||
}
|
||||
|
||||
void *ig_malloc0(int size, const char *file, int line)
|
||||
{
|
||||
#if 1
|
||||
void *p;
|
||||
|
||||
size += BUFFER_CHECK_SIZE*2;
|
||||
p = g_malloc0(size);
|
||||
data_add(p, size, file, line);
|
||||
return p+BUFFER_CHECK_SIZE;
|
||||
#else
|
||||
return g_malloc0(size);
|
||||
#endif
|
||||
}
|
||||
|
||||
void *ig_realloc(void *mem, unsigned long size, const char *file, int line)
|
||||
{
|
||||
#if 1
|
||||
void *p;
|
||||
|
||||
size += BUFFER_CHECK_SIZE*2;
|
||||
@ -169,9 +160,6 @@ void *ig_realloc(void *mem, unsigned long size, const char *file, int line)
|
||||
p = g_realloc(mem, size);
|
||||
data_add(p, size, file, line);
|
||||
return p+BUFFER_CHECK_SIZE;
|
||||
#else
|
||||
return g_realloc(mem, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
char *ig_strdup(const char *str, const char *file, int line)
|
||||
@ -264,12 +252,11 @@ char *ig_strdup_vprintf(const char *file, int line, const char *format, va_list
|
||||
|
||||
void ig_free(void *p)
|
||||
{
|
||||
#if 1
|
||||
if (p == NULL) g_error("ig_free() : trying to free NULL");
|
||||
|
||||
p -= BUFFER_CHECK_SIZE;
|
||||
p = data_remove(p, "??", 0);
|
||||
if (p != NULL)
|
||||
#endif
|
||||
g_free(p);
|
||||
if (p != NULL) g_free(p);
|
||||
}
|
||||
|
||||
GString *ig_string_new(const char *file, int line, const char *str)
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "module.h"
|
||||
#include "signals.h"
|
||||
#include "commands.h"
|
||||
#include "misc.h"
|
||||
|
||||
#include "lib-config/iconfig.h"
|
||||
#include "settings.h"
|
||||
@ -278,15 +279,16 @@ static void init_configfile(void)
|
||||
signal(SIGTERM, sig_term);
|
||||
}
|
||||
|
||||
static void cmd_rehash(const char *data)
|
||||
void settings_reread(const char *fname)
|
||||
{
|
||||
CONFIG_REC *tempconfig;
|
||||
char *str, *fname;
|
||||
char *str;
|
||||
|
||||
fname = *data != '\0' ? g_strdup(data) :
|
||||
g_strdup_printf("%s/.irssi/config", g_get_home_dir());
|
||||
tempconfig = parse_configfile(fname);
|
||||
g_free(fname);
|
||||
if (fname == NULL) fname = "~/.irssi/config";
|
||||
|
||||
str = convert_home(fname);
|
||||
tempconfig = parse_configfile(str);
|
||||
g_free(str);
|
||||
|
||||
if (tempconfig == NULL) {
|
||||
signal_emit("gui dialog", 2, "error", g_strerror(errno));
|
||||
@ -310,11 +312,11 @@ static void cmd_rehash(const char *data)
|
||||
signal_emit("setup reread", 0);
|
||||
}
|
||||
|
||||
static void cmd_save(const char *data)
|
||||
void settings_save(const char *fname)
|
||||
{
|
||||
char *str;
|
||||
|
||||
if (config_write(mainconfig, *data == '\0' ? NULL : data, 0660) == 0)
|
||||
if (config_write(mainconfig, fname, 0660) == 0)
|
||||
return;
|
||||
|
||||
/* error */
|
||||
@ -329,8 +331,6 @@ void settings_init(void)
|
||||
settings = g_hash_table_new((GHashFunc) g_str_hash, (GCompareFunc) g_str_equal);
|
||||
|
||||
init_configfile();
|
||||
command_bind("rehash", NULL, (SIGNAL_FUNC) cmd_rehash);
|
||||
command_bind("save", NULL, (SIGNAL_FUNC) cmd_save);
|
||||
}
|
||||
|
||||
static void settings_hash_free(const char *key, SETTINGS_REC *rec)
|
||||
@ -340,9 +340,6 @@ static void settings_hash_free(const char *key, SETTINGS_REC *rec)
|
||||
|
||||
void settings_deinit(void)
|
||||
{
|
||||
command_unbind("rehash", (SIGNAL_FUNC) cmd_rehash);
|
||||
command_unbind("save", (SIGNAL_FUNC) cmd_save);
|
||||
|
||||
g_free_not_null(last_error_msg);
|
||||
g_hash_table_foreach(settings, (GHFunc) settings_hash_free, NULL);
|
||||
g_hash_table_destroy(settings);
|
||||
|
@ -53,6 +53,10 @@ GSList *settings_get_sorted(void);
|
||||
/* Get the record of the setting */
|
||||
SETTINGS_REC *settings_get_record(const char *key);
|
||||
|
||||
/* if `fname' is NULL, the default is used */
|
||||
void settings_reread(const char *fname);
|
||||
void settings_save(const char *fname);
|
||||
|
||||
void settings_init(void);
|
||||
void settings_deinit(void);
|
||||
|
||||
|
@ -17,10 +17,11 @@ libfe_common_core_la_SOURCES = \
|
||||
hilight-text.c \
|
||||
keyboard.c \
|
||||
module-formats.c \
|
||||
window-activity.c \
|
||||
printtext.c \
|
||||
themes.c \
|
||||
translation.c \
|
||||
window-activity.c \
|
||||
window-commands.c \
|
||||
window-items.c \
|
||||
windows.c
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "module.h"
|
||||
#include "module-formats.h"
|
||||
#include "levels.h"
|
||||
#include "settings.h"
|
||||
|
||||
@ -50,6 +51,9 @@ void fe_settings_deinit(void);
|
||||
void window_activity_init(void);
|
||||
void window_activity_deinit(void);
|
||||
|
||||
void window_commands_init(void);
|
||||
void window_commands_deinit(void);
|
||||
|
||||
void fe_core_commands_init(void);
|
||||
void fe_core_commands_deinit(void);
|
||||
|
||||
@ -73,8 +77,10 @@ void fe_common_core_init(void)
|
||||
settings_add_int("lookandfeel", "tab_orientation", 3);*/
|
||||
settings_add_str("lookandfeel", "current_theme", "default");
|
||||
|
||||
themes_init();
|
||||
theme_register(fecommon_core_formats);
|
||||
|
||||
autorun_init();
|
||||
window_activity_init();
|
||||
hilight_text_init();
|
||||
command_history_init();
|
||||
keyboard_init();
|
||||
@ -82,9 +88,10 @@ void fe_common_core_init(void)
|
||||
fe_log_init();
|
||||
fe_server_init();
|
||||
fe_settings_init();
|
||||
themes_init();
|
||||
translation_init();
|
||||
windows_init();
|
||||
window_activity_init();
|
||||
window_commands_init();
|
||||
window_items_init();
|
||||
fe_core_commands_init();
|
||||
}
|
||||
@ -92,7 +99,6 @@ void fe_common_core_init(void)
|
||||
void fe_common_core_deinit(void)
|
||||
{
|
||||
autorun_deinit();
|
||||
window_activity_deinit();
|
||||
hilight_text_deinit();
|
||||
command_history_deinit();
|
||||
keyboard_deinit();
|
||||
@ -100,11 +106,15 @@ void fe_common_core_deinit(void)
|
||||
fe_log_deinit();
|
||||
fe_server_deinit();
|
||||
fe_settings_deinit();
|
||||
themes_deinit();
|
||||
translation_deinit();
|
||||
windows_deinit();
|
||||
window_activity_deinit();
|
||||
window_commands_deinit();
|
||||
window_items_deinit();
|
||||
fe_core_commands_deinit();
|
||||
|
||||
theme_unregister();
|
||||
themes_deinit();
|
||||
}
|
||||
|
||||
void fe_common_core_finish_init(void)
|
||||
|
@ -30,16 +30,11 @@
|
||||
#include "windows.h"
|
||||
|
||||
static const char *ret_texts[] = {
|
||||
"Invalid parameter",
|
||||
NULL,
|
||||
"Not enough parameters given",
|
||||
"Not connected to IRC server yet",
|
||||
"Not joined to any channels yet",
|
||||
"Error: getsockname() failed",
|
||||
"Error: listen() failed",
|
||||
"Multiple matches found, be more specific",
|
||||
"Nick not found",
|
||||
"Not joined to such channel",
|
||||
"Server not found",
|
||||
"Channel not fully synchronized yet, try again after a while",
|
||||
"Doing this is not a good idea. Add -YES if you really mean it",
|
||||
};
|
||||
@ -269,9 +264,15 @@ static void cmd_unknown(const char *data, void *server, WI_ITEM_REC *item)
|
||||
signal_stop();
|
||||
}
|
||||
|
||||
static void event_cmderror(gpointer error)
|
||||
static void event_cmderror(gpointer errorp)
|
||||
{
|
||||
printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, ret_texts[GPOINTER_TO_INT(error)]);
|
||||
int error;
|
||||
|
||||
error = GPOINTER_TO_INT(errorp);
|
||||
if (error == CMDERR_ERRNO)
|
||||
printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, g_strerror(errno));
|
||||
else
|
||||
printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, ret_texts[error]);
|
||||
}
|
||||
|
||||
void fe_core_commands_init(void)
|
||||
|
@ -297,25 +297,27 @@ static void autolog_log(void *server, const char *target)
|
||||
g_free(fname);
|
||||
}
|
||||
|
||||
/* write to logs created with /WINDOW LOG */
|
||||
static void sig_printtext_stripped(void *server, const char *target, gpointer levelp, const char *text)
|
||||
static void sig_printtext_stripped(WINDOW_REC *window, void *server, const char *target, gpointer levelp, const char *text)
|
||||
{
|
||||
char windownum[MAX_INT_STRLEN];
|
||||
WINDOW_REC *window;
|
||||
LOG_REC *log;
|
||||
int level;
|
||||
|
||||
level = GPOINTER_TO_INT(levelp);
|
||||
if (level == MSGLEVEL_NEVER) return;
|
||||
|
||||
/* let autolog create the log records */
|
||||
if ((autolog_level & level) && target != NULL && *target != '\0')
|
||||
autolog_log(server, target);
|
||||
|
||||
window = window_find_closest(server, target, level);
|
||||
if (window != NULL) {
|
||||
/* save to log created with /WINDOW LOG */
|
||||
ltoa(windownum, window->refnum);
|
||||
|
||||
log = log_find_item(windownum);
|
||||
if (log != NULL) log_write_rec(log, text);
|
||||
}
|
||||
|
||||
/* save line to logs */
|
||||
if (logs != NULL)
|
||||
log_write(target, level, text);
|
||||
}
|
||||
|
||||
static int sig_autoremove(void)
|
||||
|
@ -132,7 +132,7 @@ static HILIGHT_REC *hilight_find(const char *text, char **channels)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void sig_print_text(SERVER_REC *server, const char *channel, gpointer level, const char *str)
|
||||
static void sig_print_text(WINDOW_REC *window, SERVER_REC *server, const char *channel, gpointer level, const char *str)
|
||||
{
|
||||
if (hilight_next) {
|
||||
hilight_next = FALSE;
|
||||
@ -140,7 +140,7 @@ static void sig_print_text(SERVER_REC *server, const char *channel, gpointer lev
|
||||
}
|
||||
}
|
||||
|
||||
static void sig_print_text_stripped(SERVER_REC *server, const char *channel, gpointer plevel, const char *str)
|
||||
static void sig_print_text_stripped(WINDOW_REC *window, SERVER_REC *server, const char *channel, gpointer plevel, const char *str)
|
||||
{
|
||||
GSList *tmp;
|
||||
char *color, *newstr;
|
||||
@ -184,7 +184,7 @@ static void sig_print_text_stripped(SERVER_REC *server, const char *channel, gpo
|
||||
|
||||
if (color == NULL) color = "\00316";
|
||||
newstr = g_strconcat(isdigit(*color) ? "\003" : "", color, str, NULL);
|
||||
signal_emit("print text", 4, server, channel, GINT_TO_POINTER(level | MSGLEVEL_HILIGHT), newstr);
|
||||
signal_emit("print text", 5, window, server, channel, GINT_TO_POINTER(level | MSGLEVEL_HILIGHT), newstr);
|
||||
g_free(newstr);
|
||||
|
||||
hilight_next = TRUE;
|
||||
|
@ -258,12 +258,6 @@ static void read_keyboard_config(void)
|
||||
CONFIG_NODE *node;
|
||||
GSList *tmp;
|
||||
|
||||
while (keyinfos != NULL)
|
||||
keyinfo_remove(keyinfos->data);
|
||||
if (keys != NULL) g_hash_table_destroy(keys);
|
||||
|
||||
keys = g_hash_table_new((GHashFunc) g_str_hash, (GCompareFunc) g_str_equal);
|
||||
|
||||
node = iconfig_node_traverse("keyboard", FALSE);
|
||||
if (node == NULL) return;
|
||||
|
||||
@ -280,7 +274,9 @@ static void read_keyboard_config(void)
|
||||
|
||||
void keyboard_init(void)
|
||||
{
|
||||
keyinfos = NULL; keys = NULL;
|
||||
keys = g_hash_table_new((GHashFunc) g_str_hash, (GCompareFunc) g_str_equal);
|
||||
keyinfos = NULL;
|
||||
|
||||
key_bind("command", NULL, "Run any IRC command", NULL, (SIGNAL_FUNC) sig_command);
|
||||
|
||||
read_keyboard_config();
|
||||
|
@ -21,8 +21,7 @@
|
||||
#include "module.h"
|
||||
#include "printtext.h"
|
||||
|
||||
FORMAT_REC fecommon_core_formats[] =
|
||||
{
|
||||
FORMAT_REC fecommon_core_formats[] = {
|
||||
{ MODULE_NAME, "Core", 0 },
|
||||
|
||||
/* ---- */
|
||||
@ -31,9 +30,10 @@ FORMAT_REC fecommon_core_formats[] =
|
||||
{ "line_start", "%B-%W!%B-%n ", 0 },
|
||||
{ "line_start_irssi", "%B-%W!%B- %WIrssi:%n ", 0 },
|
||||
{ "timestamp", "[$[-2.0]3:$[-2.0]4] ", 6, { 1, 1, 1, 1, 1, 1 } },
|
||||
{ "daychange", "Day changed to ${[-2.0]1}-$[-2.0]0 $2", 3, { 1, 1, 1 } },
|
||||
{ "daychange", "Day changed to $[-2.0]{0}-$[-2.0]1 $2", 3, { 1, 1, 1 } },
|
||||
{ "talking_with", "You are now talking with %_$0%_", 1, { 0 } },
|
||||
{ "refnum_too_low", "Window number must be greater than 1", 0 },
|
||||
{ "refnum_not_found", "No such window: $0", 1, { 0 } }, /*REMOVE!!!!!!!!*/
|
||||
{ "windowlist_header", "Ref Name Active item Server Level", 0 },
|
||||
{ "windowlist_line", "$[3]0 %|$[20]1 $[15]2 $[15]3 $4", 5, { 1, 0, 0, 0, 0 } },
|
||||
{ "windowlist_footer", "", 0 },
|
||||
@ -89,5 +89,7 @@ FORMAT_REC fecommon_core_formats[] =
|
||||
{ NULL, "Misc", 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 }
|
||||
};
|
||||
|
@ -65,6 +65,3 @@ enum {
|
||||
};
|
||||
|
||||
extern FORMAT_REC fecommon_core_formats[];
|
||||
#define MODULE_FORMATS fecommon_core_formats
|
||||
|
||||
#include "printformat.h"
|
||||
|
@ -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
|
@ -33,14 +33,22 @@
|
||||
#include "themes.h"
|
||||
#include "windows.h"
|
||||
|
||||
static gboolean timestamps, msgs_timestamps, hide_text_style;
|
||||
static gint printtag;
|
||||
static gchar ansitab[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
|
||||
typedef struct {
|
||||
WINDOW_REC *window;
|
||||
void *server;
|
||||
const char *channel;
|
||||
int level;
|
||||
} TEXT_DEST_REC;
|
||||
|
||||
static gint signal_gui_print_text;
|
||||
static gint signal_print_text_stripped;
|
||||
static gint signal_print_text;
|
||||
static gint signal_print_text_finished;
|
||||
static int timestamps, msgs_timestamps, hide_text_style;
|
||||
static int timestamp_timeout;
|
||||
|
||||
static int signal_gui_print_text;
|
||||
static int signal_print_text_stripped;
|
||||
static int signal_print_text;
|
||||
static int signal_print_text_finished;
|
||||
|
||||
static void print_string(TEXT_DEST_REC *dest, const char *text);
|
||||
|
||||
void printbeep(void)
|
||||
{
|
||||
@ -48,35 +56,90 @@ void printbeep(void)
|
||||
GINT_TO_POINTER(PRINTFLAG_BEEP), "", MSGLEVEL_NEVER);
|
||||
}
|
||||
|
||||
static void skip_mirc_color(char **str)
|
||||
{
|
||||
if (!isdigit((int) **str))
|
||||
return;
|
||||
|
||||
/* foreground */
|
||||
(*str)++;
|
||||
if (isdigit((int) **str)) (*str)++;
|
||||
|
||||
if (**str != ',' || !isdigit((int) (*str)[1])) return;
|
||||
|
||||
/* background */
|
||||
(*str) += 2;
|
||||
if (isdigit((int) **str)) (*str)++;
|
||||
}
|
||||
|
||||
#define is_color_code(c) \
|
||||
((c) == 2 || (c) == 3 || (c) == 4 || (c) == 6 || (c) == 7 || \
|
||||
(c) == 15 || (c) == 22 || (c) == 27 || (c) == 31)
|
||||
|
||||
char *strip_codes(const char *input)
|
||||
{
|
||||
const char *p;
|
||||
char *str, *out;
|
||||
|
||||
out = str = g_strdup(input);
|
||||
for (p = input; *p != '\0'; p++) {
|
||||
if (*p == 3) {
|
||||
p++;
|
||||
|
||||
if (*p < 17 && *p > 0) {
|
||||
/* irssi color */
|
||||
if (p[1] < 17 && p[1] > 0) p++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* mirc color */
|
||||
skip_mirc_color((char **) &p);
|
||||
p--;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*p == 4 && p[1] != '\0' && p[2] != '\0') {
|
||||
/* irssi color */
|
||||
p += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!is_color_code(*p))
|
||||
*out++ = *p;
|
||||
}
|
||||
|
||||
*out = '\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
/* parse ANSI color string */
|
||||
static char *convert_ansi(char *str, int *fgcolor, int *bgcolor, int *flags)
|
||||
{
|
||||
gchar *start;
|
||||
gint fg, bg, fl, num;
|
||||
static char ansitab[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
|
||||
char *start;
|
||||
int fg, bg, fl, num;
|
||||
|
||||
if (*str != '[') return str;
|
||||
|
||||
start = str;
|
||||
if (*str != '[')
|
||||
return str;
|
||||
start = str++;
|
||||
|
||||
fg = *fgcolor < 0 ? current_theme->default_color : *fgcolor;
|
||||
bg = *bgcolor < 0 ? -1 : *bgcolor;
|
||||
fl = *flags;
|
||||
|
||||
str++; num = 0;
|
||||
for (;; str++)
|
||||
{
|
||||
num = 0;
|
||||
for (;; str++) {
|
||||
if (*str == '\0') return start;
|
||||
|
||||
if (isdigit((gint) *str))
|
||||
{
|
||||
if (isdigit((int) *str)) {
|
||||
num = num*10 + (*str-'0');
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*str != ';' && *str != 'm') return start;
|
||||
if (*str != ';' && *str != 'm')
|
||||
return start;
|
||||
|
||||
switch (num)
|
||||
{
|
||||
switch (num) {
|
||||
case 0:
|
||||
/* reset colors back to default */
|
||||
fg = current_theme->default_color;
|
||||
@ -97,8 +160,7 @@ static char *convert_ansi(char *str, int *fgcolor, int *bgcolor, int *flags)
|
||||
default:
|
||||
if (num >= 30 && num <= 37)
|
||||
fg = (fg & 0xf8) + ansitab[num-30];
|
||||
if (num >= 40 && num <= 47)
|
||||
{
|
||||
if (num >= 40 && num <= 47) {
|
||||
if (bg == -1) bg = 0;
|
||||
bg = (bg & 0xf8) + ansitab[num-40];
|
||||
}
|
||||
@ -106,10 +168,8 @@ static char *convert_ansi(char *str, int *fgcolor, int *bgcolor, int *flags)
|
||||
}
|
||||
num = 0;
|
||||
|
||||
if (*str == 'm')
|
||||
{
|
||||
if (!hide_text_style)
|
||||
{
|
||||
if (*str == 'm') {
|
||||
if (!hide_text_style) {
|
||||
*fgcolor = fg;
|
||||
*bgcolor = bg == -1 ? -1 : bg;
|
||||
*flags = fl;
|
||||
@ -122,78 +182,14 @@ static char *convert_ansi(char *str, int *fgcolor, int *bgcolor, int *flags)
|
||||
return str;
|
||||
}
|
||||
|
||||
#define IN_COLOR_CODE 2
|
||||
#define IN_SECOND_CODE 4
|
||||
char *strip_codes(const char *input)
|
||||
static int expand_styles(GString *out, char format, TEXT_DEST_REC *dest)
|
||||
{
|
||||
const char *p;
|
||||
gchar *str, *out;
|
||||
gint loop_state;
|
||||
static const char *backs = "04261537";
|
||||
static const char *fores = "kbgcrmyw";
|
||||
static const char *boldfores = "KBGCRMYW";
|
||||
char *p;
|
||||
|
||||
loop_state = 0;
|
||||
out = str = g_strdup(input);
|
||||
for (p = input; *p != '\0'; p++) /* Going through the string till the end k? */
|
||||
{
|
||||
if (*p == '\003')
|
||||
{
|
||||
if (p[1] < 17 && p[1] > 0)
|
||||
{
|
||||
p++;
|
||||
if (p[1] < 17 && p[1] > 0) p++;
|
||||
continue;
|
||||
}
|
||||
loop_state = IN_COLOR_CODE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (loop_state & IN_COLOR_CODE)
|
||||
{
|
||||
if (isdigit( (gint) *p )) continue;
|
||||
if (*p != ',' || (loop_state & IN_SECOND_CODE))
|
||||
{
|
||||
/* we're no longer in a color code */
|
||||
*out++ = *p;
|
||||
loop_state &= ~IN_COLOR_CODE|IN_SECOND_CODE;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* we're in the second code */
|
||||
loop_state |= IN_SECOND_CODE;
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
/* we're not in a color code that means we should add the character */
|
||||
if (*p == 4 && p[1] != '\0' && p[2] != '\0')
|
||||
{
|
||||
p += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*p == 2 || *p == 22 || *p == 27 || *p == 31 || *p == 15)
|
||||
continue;
|
||||
*out++ = *p;
|
||||
}
|
||||
|
||||
*out = '\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
static gboolean expand_styles(GString *out, char format, void *server, const char *channel, int level)
|
||||
{
|
||||
static const char *backs = "01234567";
|
||||
static const char *fores = "krgybmcw";
|
||||
static const char *boldfores = "KRGYBMCW";
|
||||
gchar *p;
|
||||
|
||||
/* p/P -> m/M */
|
||||
if (format == 'p')
|
||||
format = 'm';
|
||||
else if (format == 'P')
|
||||
format = 'M';
|
||||
|
||||
switch (format)
|
||||
{
|
||||
switch (format) {
|
||||
case 'U':
|
||||
/* Underline on/off */
|
||||
g_string_append_c(out, 4);
|
||||
@ -218,62 +214,57 @@ static gboolean expand_styles(GString *out, char format, void *server, const cha
|
||||
break;
|
||||
case ':':
|
||||
/* Newline */
|
||||
printtext(server, channel, level, out->str);
|
||||
print_string(dest, out->str);
|
||||
g_string_truncate(out, 0);
|
||||
break;
|
||||
|
||||
case '|':
|
||||
/* Indent here mark */
|
||||
/* Indent here */
|
||||
g_string_append_c(out, 4);
|
||||
g_string_append_c(out, -1);
|
||||
g_string_append_c(out, 4);
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
/* flashing - ignore */
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
/* don't put clear-color tag at the end of the output - ignore */
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
/* default color */
|
||||
g_string_append_c(out, 4);
|
||||
g_string_append_c(out, -1);
|
||||
g_string_append_c(out, -1);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* check if it's a background color */
|
||||
p = strchr(backs, format);
|
||||
if (p != NULL)
|
||||
{
|
||||
if (p != NULL) {
|
||||
g_string_append_c(out, 4);
|
||||
g_string_append_c(out, -2);
|
||||
g_string_append_c(out, ansitab[(gint) (p-backs)]+1);
|
||||
g_string_append_c(out, (int) (p-backs)+1);
|
||||
break;
|
||||
}
|
||||
|
||||
/* check if it's a foreground color */
|
||||
if (format == 'p') format = 'm';
|
||||
p = strchr(fores, format);
|
||||
if (p != NULL)
|
||||
{
|
||||
if (p != NULL) {
|
||||
g_string_append_c(out, 4);
|
||||
g_string_append_c(out, ansitab[(gint) (p-fores)]+1);
|
||||
g_string_append_c(out, (int) (p-fores)+1);
|
||||
g_string_append_c(out, -2);
|
||||
break;
|
||||
}
|
||||
|
||||
/* check if it's a bold foreground color */
|
||||
if (format == 'P') format = 'M';
|
||||
p = strchr(boldfores, format);
|
||||
if (p != NULL)
|
||||
{
|
||||
if (p != NULL) {
|
||||
g_string_append_c(out, 4);
|
||||
g_string_append_c(out, 8+ansitab[(gint) (p-boldfores)]+1);
|
||||
g_string_append_c(out, 8+(int) (p-boldfores)+1);
|
||||
g_string_append_c(out, -2);
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -287,12 +278,13 @@ static void read_arglist(va_list va, FORMAT_REC *format,
|
||||
int num, len, bufpos;
|
||||
|
||||
bufpos = 0;
|
||||
arglist[format->params] = NULL;
|
||||
for (num = 0; num < format->params && num < arglist_size; num++) {
|
||||
switch (format->paramtypes[num]) {
|
||||
case FORMAT_STRING:
|
||||
arglist[num] = (char *) va_arg(va, char *);
|
||||
if (arglist[num] == NULL) {
|
||||
g_warning("output_format_text_args() : parameter %d is NULL", num);
|
||||
g_warning("read_arglist() : parameter %d is NULL", num);
|
||||
arglist[num] = "";
|
||||
}
|
||||
break;
|
||||
@ -342,28 +334,32 @@ static void read_arglist(va_list va, FORMAT_REC *format,
|
||||
}
|
||||
}
|
||||
|
||||
static void output_format_text_args(GString *out, void *server, const char *channel, int level, FORMAT_REC *format, const char *text, va_list args)
|
||||
static char *output_format_text_args(TEXT_DEST_REC *dest, FORMAT_REC *format, const char *text, va_list args)
|
||||
{
|
||||
GString *out;
|
||||
char *arglist[10];
|
||||
char buffer[200]; /* should be enough? (won't overflow even if it isn't) */
|
||||
|
||||
const char *str;
|
||||
char code;
|
||||
char code, *ret;
|
||||
int need_free;
|
||||
|
||||
str = current_theme != NULL && text != NULL ? text : format->def;
|
||||
|
||||
/* read all optional arguments to arglist[] list
|
||||
so they can be used in any order.. */
|
||||
memset(arglist, 0, sizeof(arglist)); /*REMOVE!!!!!!!*/
|
||||
read_arglist(args, format,
|
||||
arglist, sizeof(arglist)/sizeof(void*),
|
||||
buffer, sizeof(buffer));
|
||||
|
||||
out = g_string_new(NULL);
|
||||
|
||||
code = 0;
|
||||
while (*str != '\0') {
|
||||
if (code == '%') {
|
||||
/* color code */
|
||||
if (!expand_styles(out, *str, server, channel, level)) {
|
||||
if (!expand_styles(out, *str, dest)) {
|
||||
g_string_append_c(out, '%');
|
||||
g_string_append_c(out, '%');
|
||||
g_string_append_c(out, *str);
|
||||
@ -373,7 +369,8 @@ static void output_format_text_args(GString *out, void *server, const char *chan
|
||||
/* argument */
|
||||
char *ret;
|
||||
|
||||
ret = parse_special((char **) &str, active_win->active_server, active_win->active, arglist, &need_free, NULL);
|
||||
ret = parse_special((char **) &str, active_win->active_server,
|
||||
active_win->active, arglist, &need_free, NULL);
|
||||
if (ret != NULL) {
|
||||
g_string_append(out, ret);
|
||||
if (need_free) g_free(ret);
|
||||
@ -388,119 +385,171 @@ static void output_format_text_args(GString *out, void *server, const char *chan
|
||||
|
||||
str++;
|
||||
}
|
||||
|
||||
ret = out->str;
|
||||
g_string_free(out, FALSE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void output_format_text(GString *out, void *server, const char *channel, int level, int formatnum, ...)
|
||||
static char *output_format_text(TEXT_DEST_REC *dest, int formatnum, ...)
|
||||
{
|
||||
MODULE_THEME_REC *theme;
|
||||
va_list args;
|
||||
char *ret;
|
||||
|
||||
theme = g_hash_table_lookup(current_theme->modules, MODULE_FORMATS->tag);
|
||||
theme = g_hash_table_lookup(current_theme->modules, MODULE_NAME);
|
||||
|
||||
va_start(args, formatnum);
|
||||
output_format_text_args(out, server, channel, level,
|
||||
&MODULE_FORMATS[formatnum],
|
||||
theme == NULL ? NULL : theme->format[formatnum], args);
|
||||
ret = output_format_text_args(dest, &fecommon_core_formats[formatnum],
|
||||
theme == NULL ? NULL : theme->formats[formatnum], args);
|
||||
va_end(args);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void add_timestamp(WINDOW_REC *window, GString *out, void *server, const char *channel, int level)
|
||||
void printformat_module_args(const char *module, void *server, const char *channel, int level, int formatnum, va_list va)
|
||||
{
|
||||
time_t t;
|
||||
struct tm *tm;
|
||||
GString *tmp;
|
||||
MODULE_THEME_REC *theme;
|
||||
TEXT_DEST_REC dest;
|
||||
FORMAT_REC *formats;
|
||||
char *str;
|
||||
|
||||
if (!(level != MSGLEVEL_NEVER && (timestamps || (msgs_timestamps && (level & MSGLEVEL_MSGS) != 0))))
|
||||
return;
|
||||
dest.window = NULL;
|
||||
dest.server = server;
|
||||
dest.channel = channel;
|
||||
dest.level = level;
|
||||
|
||||
t = time(NULL);
|
||||
theme = g_hash_table_lookup(current_theme->modules, module);
|
||||
formats = g_hash_table_lookup(default_formats, module);
|
||||
|
||||
if ((t - window->last_timestamp) < settings_get_int("timestamp_timeout")) {
|
||||
window->last_timestamp = t;
|
||||
return;
|
||||
}
|
||||
window->last_timestamp = t;
|
||||
|
||||
tmp = g_string_new(NULL);
|
||||
tm = localtime(&t);
|
||||
output_format_text(tmp, server, channel, level, IRCTXT_TIMESTAMP,
|
||||
tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
|
||||
/* insert the timestamp right after \n */
|
||||
g_string_prepend(out, tmp->str);
|
||||
g_string_free(tmp, TRUE);
|
||||
str = output_format_text_args(&dest, &formats[formatnum],
|
||||
theme == NULL ? NULL : theme->formats[formatnum], va);
|
||||
if (*str != '\0') print_string(&dest, str);
|
||||
g_free(str);
|
||||
}
|
||||
|
||||
static void new_line_stuff(GString *out, void *server, const char *channel, int level)
|
||||
void printformat_module(const char *module, void *server, const char *channel, int level, int formatnum, ...)
|
||||
{
|
||||
if ((level & (MSGLEVEL_CLIENTERROR|MSGLEVEL_CLIENTNOTICE)) != 0)
|
||||
output_format_text(out, server, channel, level, IRCTXT_LINE_START_IRSSI);
|
||||
else if ((level & (MSGLEVEL_MSGS|MSGLEVEL_PUBLIC|MSGLEVEL_NOTICES|MSGLEVEL_SNOTES|MSGLEVEL_CTCPS|MSGLEVEL_ACTIONS|MSGLEVEL_DCC|MSGLEVEL_CLIENTCRAP)) == 0 && level != MSGLEVEL_NEVER)
|
||||
output_format_text(out, server, channel, level, IRCTXT_LINE_START);
|
||||
va_list va;
|
||||
|
||||
va_start(va, formatnum);
|
||||
printformat_module_args(module, server, channel, level, formatnum, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
/* Write text to channel - convert color codes */
|
||||
void printtext(void *server, const char *channel, int level, const char *str, ...)
|
||||
void printformat_module_window_args(const char *module, WINDOW_REC *window, int level, int formatnum, va_list va)
|
||||
{
|
||||
MODULE_THEME_REC *theme;
|
||||
TEXT_DEST_REC dest;
|
||||
FORMAT_REC *formats;
|
||||
char *str;
|
||||
|
||||
dest.window = window;
|
||||
dest.server = NULL;
|
||||
dest.channel = NULL;
|
||||
dest.level = level;
|
||||
|
||||
theme = g_hash_table_lookup(current_theme->modules, module);
|
||||
formats = g_hash_table_lookup(default_formats, module);
|
||||
|
||||
str = output_format_text_args(&dest, &formats[formatnum],
|
||||
theme == NULL ? NULL : theme->formats[formatnum], va);
|
||||
if (*str != '\0') print_string(&dest, str);
|
||||
g_free(str);
|
||||
}
|
||||
|
||||
void printformat_module_window(const char *module, WINDOW_REC *window, int level, int formatnum, ...)
|
||||
{
|
||||
va_list va;
|
||||
|
||||
va_start(va, formatnum);
|
||||
printformat_module_window_args(module, window, level, formatnum, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
/* return the "-!- " text at the start of the line */
|
||||
static char *get_line_start_text(TEXT_DEST_REC *dest)
|
||||
{
|
||||
if ((dest->level & (MSGLEVEL_CLIENTERROR|MSGLEVEL_CLIENTNOTICE)) != 0)
|
||||
return output_format_text(dest, IRCTXT_LINE_START_IRSSI);
|
||||
|
||||
if ((dest->level & (MSGLEVEL_MSGS|MSGLEVEL_PUBLIC|MSGLEVEL_NOTICES|MSGLEVEL_SNOTES|MSGLEVEL_CTCPS|MSGLEVEL_ACTIONS|MSGLEVEL_DCC|MSGLEVEL_CLIENTCRAP)) == 0 && dest->level != MSGLEVEL_NEVER)
|
||||
return output_format_text(dest, IRCTXT_LINE_START);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void print_string(TEXT_DEST_REC *dest, const char *text)
|
||||
{
|
||||
gpointer levelp;
|
||||
char *str, *tmp;
|
||||
|
||||
g_return_if_fail(dest != NULL);
|
||||
g_return_if_fail(text != NULL);
|
||||
|
||||
if (dest->window == NULL)
|
||||
dest->window = window_find_closest(dest->server, dest->channel, dest->level);
|
||||
|
||||
tmp = get_line_start_text(dest);
|
||||
str = tmp == NULL ? (char *) text :
|
||||
g_strconcat(tmp, text, NULL);
|
||||
g_free_not_null(tmp);
|
||||
|
||||
levelp = GINT_TO_POINTER(dest->level);
|
||||
|
||||
/* send the plain text version for logging etc.. */
|
||||
tmp = strip_codes(str);
|
||||
signal_emit_id(signal_print_text_stripped, 5, dest->window, dest->server, dest->channel, levelp, tmp);
|
||||
g_free(tmp);
|
||||
|
||||
signal_emit_id(signal_print_text, 5, dest->window, dest->server, dest->channel, levelp, str);
|
||||
if (str != text) g_free(str);
|
||||
}
|
||||
|
||||
static char *printtext_get_args(TEXT_DEST_REC *dest, const char *str, va_list va)
|
||||
{
|
||||
va_list args;
|
||||
GString *out;
|
||||
gchar *tmpstr;
|
||||
gint pros;
|
||||
char *ret;
|
||||
|
||||
g_return_if_fail(str != NULL);
|
||||
|
||||
va_start(args, str);
|
||||
|
||||
pros = 0;
|
||||
out = g_string_new(NULL);
|
||||
|
||||
new_line_stuff(out, server, channel, level);
|
||||
for (; *str != '\0'; str++)
|
||||
{
|
||||
if (*str != '%')
|
||||
{
|
||||
for (; *str != '\0'; str++) {
|
||||
if (*str != '%') {
|
||||
g_string_append_c(out, *str);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*++str == '\0') break;
|
||||
switch (*str)
|
||||
{
|
||||
if (*++str == '\0')
|
||||
break;
|
||||
|
||||
/* standard parameters */
|
||||
case 's':
|
||||
{
|
||||
gchar *s = (gchar *) va_arg(args, gchar *);
|
||||
switch (*str) {
|
||||
case 's': {
|
||||
char *s = (char *) va_arg(va, char *);
|
||||
if (s && *s) g_string_append(out, s);
|
||||
break;
|
||||
}
|
||||
case 'd':
|
||||
{
|
||||
gint d = (gint) va_arg(args, gint);
|
||||
case 'd': {
|
||||
int d = (int) va_arg(va, int);
|
||||
g_string_sprintfa(out, "%d", d);
|
||||
break;
|
||||
}
|
||||
case 'f':
|
||||
{
|
||||
gdouble f = (gdouble) va_arg(args, gdouble);
|
||||
case 'f': {
|
||||
double f = (double) va_arg(va, double);
|
||||
g_string_sprintfa(out, "%0.2f", f);
|
||||
break;
|
||||
}
|
||||
case 'u':
|
||||
{
|
||||
guint d = (guint) va_arg(args, guint);
|
||||
case 'u': {
|
||||
unsigned int d = (unsigned int) va_arg(va, unsigned int);
|
||||
g_string_sprintfa(out, "%u", d);
|
||||
break;
|
||||
}
|
||||
case 'l':
|
||||
{
|
||||
gulong d = (gulong) va_arg(args, gulong);
|
||||
if (*++str != 'd' && *str != 'u')
|
||||
{
|
||||
case 'l': {
|
||||
long d = (long) va_arg(va, long);
|
||||
|
||||
if (*++str != 'd' && *str != 'u') {
|
||||
g_string_sprintfa(out, "%ld", d);
|
||||
str--;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if (*str == 'd')
|
||||
g_string_sprintfa(out, "%ld", d);
|
||||
else
|
||||
@ -509,44 +558,60 @@ void printtext(void *server, const char *channel, int level, const char *str, ..
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if (!expand_styles(out, *str, server, channel, level))
|
||||
{
|
||||
if (!expand_styles(out, *str, dest)) {
|
||||
g_string_append_c(out, '%');
|
||||
g_string_append_c(out, *str);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
/* send the plain text version for logging.. */
|
||||
tmpstr = strip_codes(out->str);
|
||||
signal_emit_id(signal_print_text_stripped, 4, server, channel, GINT_TO_POINTER(level), tmpstr);
|
||||
g_free(tmpstr);
|
||||
|
||||
signal_emit_id(signal_print_text, 4, server, channel, GINT_TO_POINTER(level), out->str);
|
||||
|
||||
g_string_free(out, TRUE);
|
||||
ret = out->str;
|
||||
g_string_free(out, FALSE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void printformat_format(FORMAT_REC *formats, void *server, const char *channel, int level, int formatnum, ...)
|
||||
/* Write text to channel - convert color codes */
|
||||
void printtext(void *server, const char *channel, int level, const char *text, ...)
|
||||
{
|
||||
MODULE_THEME_REC *theme;
|
||||
GString *out;
|
||||
va_list args;
|
||||
TEXT_DEST_REC dest;
|
||||
char *str;
|
||||
va_list va;
|
||||
|
||||
va_start(args, formatnum);
|
||||
out = g_string_new(NULL);
|
||||
g_return_if_fail(text != NULL);
|
||||
|
||||
theme = g_hash_table_lookup(current_theme->modules, formats->tag);
|
||||
dest.window = NULL;
|
||||
dest.server = server;
|
||||
dest.channel = channel;
|
||||
dest.level = level;
|
||||
|
||||
output_format_text_args(out, server, channel, level,
|
||||
&formats[formatnum],
|
||||
theme == NULL ? NULL : theme->format[formatnum], args);
|
||||
if (out->len > 0) printtext(server, channel, level, "%s", out->str);
|
||||
va_start(va, text);
|
||||
str = printtext_get_args(&dest, text, va);
|
||||
va_end(va);
|
||||
|
||||
g_string_free(out, TRUE);
|
||||
va_end(args);
|
||||
print_string(&dest, str);
|
||||
g_free(str);
|
||||
}
|
||||
|
||||
void printtext_window(WINDOW_REC *window, int level, const char *text, ...)
|
||||
{
|
||||
TEXT_DEST_REC dest;
|
||||
char *str;
|
||||
va_list va;
|
||||
|
||||
g_return_if_fail(text != NULL);
|
||||
|
||||
dest.window = window != NULL ? window : active_win;
|
||||
dest.server = NULL;
|
||||
dest.channel = NULL;
|
||||
dest.level = level;
|
||||
|
||||
va_start(va, text);
|
||||
str = printtext_get_args(&dest, text, va);
|
||||
va_end(va);
|
||||
|
||||
print_string(&dest, str);
|
||||
g_free(str);
|
||||
}
|
||||
|
||||
static void newline(WINDOW_REC *window)
|
||||
@ -559,48 +624,74 @@ static void newline(WINDOW_REC *window)
|
||||
}
|
||||
}
|
||||
|
||||
static void sig_print_text(void *server, const char *target, gpointer level, const char *text)
|
||||
#define show_timestamp(level) \
|
||||
((level) != MSGLEVEL_NEVER && \
|
||||
(timestamps || (msgs_timestamps && ((level) & MSGLEVEL_MSGS))))
|
||||
|
||||
static char *get_timestamp(TEXT_DEST_REC *dest)
|
||||
{
|
||||
WINDOW_REC *window;
|
||||
GString *out;
|
||||
gchar *dup, *ptr, type, *str;
|
||||
struct tm *tm;
|
||||
time_t t;
|
||||
int diff;
|
||||
|
||||
if (!show_timestamp(dest->level))
|
||||
return NULL;
|
||||
|
||||
t = time(NULL);
|
||||
|
||||
diff = t - dest->window->last_timestamp;
|
||||
dest->window->last_timestamp = t;
|
||||
if (diff < timestamp_timeout)
|
||||
return NULL;
|
||||
|
||||
tm = localtime(&t);
|
||||
return output_format_text(dest, IRCTXT_TIMESTAMP,
|
||||
tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
}
|
||||
|
||||
static char *get_server_tag(WINDOW_REC *window, SERVER_REC *server)
|
||||
{
|
||||
if (server == NULL || servers == NULL || servers->next == NULL ||
|
||||
(window->active != NULL && window->active->server == server))
|
||||
return NULL;
|
||||
|
||||
return g_strdup_printf("[%s] ", server->tag);
|
||||
}
|
||||
|
||||
static void sig_print_text(WINDOW_REC *window, SERVER_REC *server, const char *target, gpointer level, const char *text)
|
||||
{
|
||||
TEXT_DEST_REC dest;
|
||||
gchar *dup, *ptr, type, *str, *timestamp, *servertag;
|
||||
gint fgcolor, bgcolor;
|
||||
gint flags;
|
||||
|
||||
g_return_if_fail(text != NULL);
|
||||
|
||||
window = window_find_closest(server, target, GPOINTER_TO_INT(level));
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
flags = 0; fgcolor = -1; bgcolor = -1; type = '\0';
|
||||
dest.window = window;
|
||||
dest.server = server;
|
||||
dest.channel = target;
|
||||
dest.level = GPOINTER_TO_INT(level);
|
||||
|
||||
flags = 0; fgcolor = -1; bgcolor = -1; type = '\0';
|
||||
window->last_line = time(NULL);
|
||||
newline(window);
|
||||
|
||||
out = g_string_new(text);
|
||||
if (server != NULL && servers != NULL && servers->next != NULL &&
|
||||
(window->active == NULL || window->active->server != server))
|
||||
{
|
||||
/* connected to more than one server and active server isn't the
|
||||
same where the message came or we're in status/msgs/empty window -
|
||||
prefix with a [server tag] */
|
||||
gchar *str;
|
||||
|
||||
str = g_strdup_printf("[%s] ", ((SERVER_REC *) server)->tag);
|
||||
g_string_prepend(out, str);
|
||||
g_free(str);
|
||||
}
|
||||
|
||||
add_timestamp(window, out, server, target, GPOINTER_TO_INT(level));
|
||||
|
||||
dup = str = out->str;
|
||||
g_string_free(out, FALSE);
|
||||
timestamp = get_timestamp(&dest);
|
||||
servertag = get_server_tag(window, server);
|
||||
str = g_strconcat(timestamp != NULL ? timestamp : "",
|
||||
servertag != NULL ? servertag : "",
|
||||
text, NULL);
|
||||
g_free_not_null(timestamp);
|
||||
g_free_not_null(servertag);
|
||||
|
||||
dup = str;
|
||||
while (*str != '\0')
|
||||
{
|
||||
for (ptr = str; *ptr != '\0'; ptr++)
|
||||
{
|
||||
if (*ptr == 2 || *ptr == 3 || *ptr == 4 || *ptr == 6 || *ptr == 7 || *ptr == 15 || *ptr == 22 || *ptr == 27 || *ptr == 31)
|
||||
if (is_color_code(*ptr))
|
||||
{
|
||||
type = *ptr;
|
||||
*ptr++ = '\0';
|
||||
@ -715,20 +806,7 @@ static void sig_print_text(void *server, const char *target, gpointer level, con
|
||||
if (hide_text_style)
|
||||
{
|
||||
/* don't show them. */
|
||||
if (isdigit((gint) *ptr))
|
||||
{
|
||||
ptr++;
|
||||
if (isdigit((gint) *ptr)) ptr++;
|
||||
if (*ptr == ',')
|
||||
{
|
||||
ptr++;
|
||||
if (isdigit((gint) *ptr))
|
||||
{
|
||||
ptr++;
|
||||
if (isdigit((gint) *ptr)) ptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
skip_mirc_color(&ptr);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -770,47 +848,6 @@ static void sig_print_text(void *server, const char *target, gpointer level, con
|
||||
signal_emit_id(signal_print_text_finished, 1, window);
|
||||
}
|
||||
|
||||
static int sig_check_daychange(void)
|
||||
{
|
||||
static gint lastday = -1;
|
||||
GSList *tmp;
|
||||
time_t t;
|
||||
struct tm *tm;
|
||||
|
||||
if (!timestamps)
|
||||
{
|
||||
/* display day change notice only when using timestamps */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
t = time(NULL);
|
||||
tm = localtime(&t);
|
||||
|
||||
if (lastday == -1)
|
||||
{
|
||||
/* First check, don't display. */
|
||||
lastday = tm->tm_mday;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (tm->tm_mday == lastday)
|
||||
return TRUE;
|
||||
|
||||
/* day changed, print notice about it to every window */
|
||||
for (tmp = windows; tmp != NULL; tmp = tmp->next)
|
||||
{
|
||||
WINDOW_REC *win = tmp->data;
|
||||
|
||||
if (win->active == NULL)
|
||||
continue; /* FIXME: how to print in these windows? */
|
||||
|
||||
printformat(win->active->server, win->active->name, MSGLEVEL_NEVER,
|
||||
IRCTXT_DAYCHANGE, tm->tm_mday, tm->tm_mon+1, 1900+tm->tm_year);
|
||||
}
|
||||
lastday = tm->tm_mday;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void printtext_multiline(void *server, const char *channel, int level, const char *format, const char *text)
|
||||
{
|
||||
char **lines, **tmp;
|
||||
@ -838,6 +875,7 @@ static void sig_gui_dialog(const char *type, const char *text)
|
||||
static void read_settings(void)
|
||||
{
|
||||
timestamps = settings_get_bool("timestamps");
|
||||
timestamp_timeout = settings_get_bool("timestamp_timeout");
|
||||
msgs_timestamps = settings_get_bool("msgs_timestamps");
|
||||
hide_text_style = settings_get_bool("hide_text_style");
|
||||
}
|
||||
@ -852,7 +890,6 @@ void printtext_init(void)
|
||||
signal_print_text_finished = module_get_uniq_id_str("signals", "print text finished");
|
||||
|
||||
read_settings();
|
||||
printtag = g_timeout_add(30000, (GSourceFunc) sig_check_daychange, NULL);
|
||||
signal_add("print text", (SIGNAL_FUNC) sig_print_text);
|
||||
signal_add("gui dialog", (SIGNAL_FUNC) sig_gui_dialog);
|
||||
signal_add("setup changed", (SIGNAL_FUNC) read_settings);
|
||||
@ -860,7 +897,6 @@ void printtext_init(void)
|
||||
|
||||
void printtext_deinit(void)
|
||||
{
|
||||
g_source_remove(printtag);
|
||||
signal_remove("print text", (SIGNAL_FUNC) sig_print_text);
|
||||
signal_remove("gui dialog", (SIGNAL_FUNC) sig_gui_dialog);
|
||||
signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef __PRINTTEXT_H
|
||||
#define __PRINTTEXT_H
|
||||
|
||||
#include "windows.h"
|
||||
|
||||
enum {
|
||||
FORMAT_STRING,
|
||||
FORMAT_INT,
|
||||
@ -24,9 +26,14 @@ typedef struct {
|
||||
#define PRINTFLAG_MIRC_COLOR 0x20
|
||||
#define PRINTFLAG_INDENT 0x40
|
||||
|
||||
void printformat_format(FORMAT_REC *formats, void *server, const char *channel, int level, int formatnum, ...);
|
||||
void printformat_module(const char *module, void *server, const char *channel, int level, int formatnum, ...);
|
||||
void printformat_module_window(const char *module, WINDOW_REC *window, int level, int formatnum, ...);
|
||||
|
||||
void 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 printbeep(void);
|
||||
|
||||
@ -36,4 +43,51 @@ char *strip_codes(const char *input);
|
||||
void printtext_init(void);
|
||||
void printtext_deinit(void);
|
||||
|
||||
/* printformat(...) = printformat_format(MODULE_NAME, ...)
|
||||
|
||||
Could this be any harder? :) With GNU C compiler and C99 compilers,
|
||||
use #define. With others use either inline functions if they are
|
||||
supported or static functions if they are not..
|
||||
*/
|
||||
#if defined (__GNUC__) && !defined (__STRICT_ANSI__)
|
||||
/* GCC */
|
||||
# define printformat(server, channel, level, formatnum...) \
|
||||
printformat_module(MODULE_NAME, server, channel, level, ##formatnum)
|
||||
# define printformat_window(window, level, formatnum...) \
|
||||
printformat_module_window(MODULE_NAME, window, level, ##formatnum)
|
||||
#elif defined (_ISOC99_SOURCE)
|
||||
/* C99 */
|
||||
# define printformat(server, channel, level, formatnum, ...) \
|
||||
printformat_module(MODULE_NAME, server, channel, level, formatnum, __VA_ARGS__)
|
||||
# define printformat_window(window, level, formatnum, ...) \
|
||||
printformat_module_window(MODULE_NAME, window, level, formatnum, __VA_ARGS__)
|
||||
#else
|
||||
/* inline/static */
|
||||
static
|
||||
#ifdef G_CAN_INLINE
|
||||
inline
|
||||
#endif
|
||||
void printformat(void *server, const char *channel, int level, int formatnum, ...)
|
||||
{
|
||||
va_list va;
|
||||
|
||||
va_start(va, formatnum);
|
||||
printformat_module_args(MODULE_NAME, server, channel, level, formatnum, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
static
|
||||
#ifdef G_CAN_INLINE
|
||||
inline
|
||||
#endif
|
||||
void printformat_window(WINDOW_REC *window, int level, int formatnum, ...)
|
||||
{
|
||||
va_list va;
|
||||
|
||||
va_start(va, formatnum);
|
||||
printformat_module_window_args(MODULE_NAME, window, level, formatnum, va);
|
||||
va_end(va);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -20,6 +20,8 @@
|
||||
|
||||
#include "module.h"
|
||||
#include "signals.h"
|
||||
#include "commands.h"
|
||||
#include "levels.h"
|
||||
#include "misc.h"
|
||||
#include "lib-config/iconfig.h"
|
||||
#include "settings.h"
|
||||
@ -29,6 +31,7 @@
|
||||
|
||||
GSList *themes;
|
||||
THEME_REC *current_theme;
|
||||
GHashTable *default_formats;
|
||||
|
||||
THEME_REC *theme_create(const char *path, const char *name)
|
||||
{
|
||||
@ -46,17 +49,15 @@ THEME_REC *theme_create(const char *path, const char *name)
|
||||
return rec;
|
||||
}
|
||||
|
||||
static void theme_destroy_hash(const char *key, MODULE_THEME_REC *rec)
|
||||
static void theme_module_destroy(const char *key, MODULE_THEME_REC *rec)
|
||||
{
|
||||
int n, max;
|
||||
int n;
|
||||
|
||||
max = strarray_length(rec->formatlist);
|
||||
for (n = 0; n < max; n++)
|
||||
if (rec->format[n] != NULL)
|
||||
g_free(rec->format[n]);
|
||||
g_free(rec->format);
|
||||
for (n = 0; n < rec->count; n++)
|
||||
if (rec->formats[n] != NULL)
|
||||
g_free(rec->formats[n]);
|
||||
g_free(rec->formats);
|
||||
|
||||
g_strfreev(rec->formatlist);
|
||||
g_free(rec->name);
|
||||
g_free(rec);
|
||||
}
|
||||
@ -64,7 +65,7 @@ static void theme_destroy_hash(const char *key, MODULE_THEME_REC *rec)
|
||||
void theme_destroy(THEME_REC *rec)
|
||||
{
|
||||
signal_emit("theme destroyed", 1, rec);
|
||||
g_hash_table_foreach(rec->modules, (GHFunc) theme_destroy_hash, NULL);
|
||||
g_hash_table_foreach(rec->modules, (GHFunc) theme_module_destroy, NULL);
|
||||
g_hash_table_destroy(rec->modules);
|
||||
|
||||
if (rec->bg_pixmap != NULL) g_free(rec->bg_pixmap);
|
||||
@ -74,6 +75,119 @@ void theme_destroy(THEME_REC *rec)
|
||||
g_free(rec);
|
||||
}
|
||||
|
||||
static MODULE_THEME_REC *theme_module_create(THEME_REC *theme, const char *module)
|
||||
{
|
||||
MODULE_THEME_REC *rec;
|
||||
FORMAT_REC *formats;
|
||||
|
||||
rec = g_hash_table_lookup(theme->modules, module);
|
||||
if (rec != NULL) return rec;
|
||||
|
||||
formats = g_hash_table_lookup(default_formats, module);
|
||||
g_return_val_if_fail(formats != NULL, NULL);
|
||||
|
||||
rec = g_new0(MODULE_THEME_REC, 1);
|
||||
rec->name = g_strdup(module);
|
||||
|
||||
for (rec->count = 0; formats[rec->count].def != NULL; rec->count++) ;
|
||||
rec->formats = g_new0(char *, rec->count);
|
||||
|
||||
g_hash_table_insert(theme->modules, rec->name, rec);
|
||||
return rec;
|
||||
}
|
||||
|
||||
static void theme_read_formats(CONFIG_REC *config, THEME_REC *theme, const char *module)
|
||||
{
|
||||
MODULE_THEME_REC *rec;
|
||||
FORMAT_REC *formats;
|
||||
CONFIG_NODE *node;
|
||||
GSList *tmp;
|
||||
int n;
|
||||
|
||||
formats = g_hash_table_lookup(default_formats, module);
|
||||
if (formats == NULL) return;
|
||||
|
||||
node = config_node_traverse(config, "formats", FALSE);
|
||||
if (node == NULL) return;
|
||||
node = config_node_section(node, module, -1);
|
||||
if (node == NULL) return;
|
||||
|
||||
rec = theme_module_create(theme, module);
|
||||
|
||||
for (tmp = node->value; tmp != NULL; tmp = tmp->next) {
|
||||
node = tmp->data;
|
||||
|
||||
if (node->key == NULL || node->value == NULL)
|
||||
continue;
|
||||
|
||||
for (n = 0; formats[n].def != NULL; n++) {
|
||||
if (formats[n].tag != NULL &&
|
||||
g_strcasecmp(formats[n].tag, node->key) == 0) {
|
||||
rec->formats[n] = g_strdup(node->value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void theme_read_module(THEME_REC *theme, const char *module)
|
||||
{
|
||||
CONFIG_REC *config;
|
||||
char *msg;
|
||||
|
||||
config = config_open(theme->path, -1);
|
||||
if (config == NULL) return;
|
||||
|
||||
config_parse(config);
|
||||
|
||||
if (config_last_error(mainconfig) != NULL) {
|
||||
msg = g_strdup_printf(_("Ignored errors in theme:\n%s"),
|
||||
config_last_error(mainconfig));
|
||||
signal_emit("gui dialog", 2, "error", msg);
|
||||
g_free(msg);
|
||||
}
|
||||
|
||||
theme_read_formats(config, theme, module);
|
||||
|
||||
config_close(config);
|
||||
}
|
||||
|
||||
static void theme_remove_module(THEME_REC *theme, const char *module)
|
||||
{
|
||||
MODULE_THEME_REC *rec;
|
||||
|
||||
rec = g_hash_table_lookup(theme->modules, module);
|
||||
if (rec == NULL) return;
|
||||
|
||||
g_hash_table_remove(theme->modules, module);
|
||||
theme_module_destroy(module, rec);
|
||||
}
|
||||
|
||||
void theme_register_module(const char *module, FORMAT_REC *formats)
|
||||
{
|
||||
if (g_hash_table_lookup(default_formats, module) != NULL)
|
||||
return;
|
||||
|
||||
g_hash_table_insert(default_formats, g_strdup(module), formats);
|
||||
|
||||
if (current_theme != NULL)
|
||||
theme_read_module(current_theme, module);
|
||||
}
|
||||
|
||||
void theme_unregister_module(const char *module)
|
||||
{
|
||||
gpointer key, value;
|
||||
|
||||
if (!g_hash_table_lookup_extended(default_formats, module, &key, &value))
|
||||
return;
|
||||
|
||||
g_hash_table_remove(default_formats, key);
|
||||
g_free(key);
|
||||
|
||||
if (current_theme != NULL)
|
||||
theme_remove_module(current_theme, module);
|
||||
}
|
||||
|
||||
static THEME_REC *theme_find(const char *name)
|
||||
{
|
||||
GSList *tmp;
|
||||
@ -115,49 +229,19 @@ static void find_themes(gchar *path)
|
||||
closedir(dirp);
|
||||
}
|
||||
|
||||
/* Read module texts into theme */
|
||||
static void theme_read_module_texts(const char *hashkey, MODULE_THEME_REC *rec, CONFIG_REC *config)
|
||||
static void theme_read(THEME_REC *theme, const char *path)
|
||||
{
|
||||
CONFIG_NODE *formats;
|
||||
GSList *tmp;
|
||||
char **flist;
|
||||
int n;
|
||||
|
||||
formats = config_node_traverse(config, "moduleformats", FALSE);
|
||||
if (formats == NULL) return;
|
||||
|
||||
for (tmp = formats->value; tmp != NULL; tmp = tmp->next) {
|
||||
CONFIG_NODE *node = tmp->data;
|
||||
|
||||
if (node->key == NULL || node->value == NULL)
|
||||
continue;
|
||||
|
||||
for (n = 0, flist = rec->formatlist; *flist != NULL; flist++, n++) {
|
||||
if (g_strcasecmp(*flist, node->key) == 0) {
|
||||
rec->format[n] = g_strdup(node->value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int theme_read(THEME_REC *theme, const char *path)
|
||||
{
|
||||
MODULE_THEME_REC *mrec;
|
||||
CONFIG_REC *config;
|
||||
CONFIG_NODE *formats;
|
||||
GSList *tmp;
|
||||
char *value;
|
||||
int errors;
|
||||
|
||||
config = config_open(path, -1);
|
||||
if (config == NULL) {
|
||||
/* didn't exist or no access? */
|
||||
theme->default_color = 15;
|
||||
return FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
errors = config_parse(config) == -1;
|
||||
config_parse(config);
|
||||
|
||||
/* default color */
|
||||
theme->default_color = config_get_int(config, NULL, "default_color", 15);
|
||||
@ -175,29 +259,154 @@ static int theme_read(THEME_REC *theme, const char *path)
|
||||
theme->flags |= THEME_FLAG_BG_SCALED;
|
||||
if (config_get_bool(config, NULL, "bg_shaded", FALSE))
|
||||
theme->flags |= THEME_FLAG_BG_SHADED;
|
||||
config_close(config);
|
||||
}
|
||||
|
||||
/* Read modules that are defined in this theme. */
|
||||
formats = config_node_traverse(config, "modules", FALSE);
|
||||
if (formats != NULL) {
|
||||
for (tmp = formats->value; tmp != NULL; tmp = tmp->next) {
|
||||
CONFIG_NODE *node = tmp->data;
|
||||
typedef struct {
|
||||
char *name;
|
||||
char *short_name;
|
||||
} THEME_SEARCH_REC;
|
||||
|
||||
if (node->key == NULL || node->value == NULL)
|
||||
continue;
|
||||
static int theme_search_equal(THEME_SEARCH_REC *r1, THEME_SEARCH_REC *r2)
|
||||
{
|
||||
return g_strcasecmp(r1->short_name, r2->short_name);
|
||||
}
|
||||
|
||||
mrec = g_new0(MODULE_THEME_REC, 1);
|
||||
mrec->name = g_strdup(node->key);
|
||||
mrec->formatlist = g_strsplit(node->value, " ", -1);
|
||||
mrec->format = g_new0(char*, strarray_length(mrec->formatlist));
|
||||
g_hash_table_insert(theme->modules, mrec->name, mrec);
|
||||
static 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Read the texts inside the plugin */
|
||||
g_hash_table_foreach(theme->modules, (GHFunc) theme_read_module_texts, config);
|
||||
static void cmd_format(const char *data)
|
||||
{
|
||||
char *params, *module, *key, *value;
|
||||
GSList *tmp, *modules;
|
||||
|
||||
/* /FORMAT [<module>] [<key> [<value>]] */
|
||||
params = cmd_get_params(data, 3 | PARAM_FLAG_GETREST, &module, &key, &value);
|
||||
|
||||
modules = get_sorted_modules();
|
||||
if (*module != '\0' && theme_search(modules, module) == NULL) {
|
||||
/* first argument isn't module.. */
|
||||
g_free(params);
|
||||
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &key, &value);
|
||||
module = "";
|
||||
}
|
||||
|
||||
if (*key == '\0') key = NULL;
|
||||
if (*value == '\0') value = NULL;
|
||||
|
||||
for (tmp = modules; tmp != NULL; tmp = tmp->next) {
|
||||
THEME_SEARCH_REC *rec = tmp->data;
|
||||
|
||||
if (*module == '\0' || g_strcasecmp(rec->short_name, module) == 0)
|
||||
theme_show(rec, key, value);
|
||||
}
|
||||
g_slist_foreach(modules, (GFunc) g_free, NULL);
|
||||
g_slist_free(modules);
|
||||
|
||||
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 (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
|
||||
@ -207,26 +416,15 @@ static int theme_read(THEME_REC *theme, const char *path)
|
||||
/* 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) {
|
||||
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(path));
|
||||
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);
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
static void sig_formats_error(void)
|
||||
{
|
||||
signal_emit("gui dialog", 2, "warning",
|
||||
"Your theme(s) had some old format strings, "
|
||||
"these have been changed back to their default values.");
|
||||
signal_remove("irssi init finished", (SIGNAL_FUNC) sig_formats_error);
|
||||
}
|
||||
|
||||
void themes_init(void)
|
||||
@ -235,7 +433,8 @@ void themes_init(void)
|
||||
GSList *tmp;
|
||||
const char *value;
|
||||
char *str;
|
||||
int errors;
|
||||
|
||||
default_formats = g_hash_table_new((GHashFunc) g_str_hash, (GCompareFunc) g_str_equal);
|
||||
|
||||
/* first there's default theme.. */
|
||||
str = g_strdup_printf("%s/.irssi/default.theme", g_get_home_dir());
|
||||
@ -251,22 +450,20 @@ void themes_init(void)
|
||||
find_themes(SYSCONFDIR"/irssi");
|
||||
|
||||
/* read formats for all themes */
|
||||
errors = FALSE;
|
||||
for (tmp = themes; tmp != NULL; tmp = tmp->next) {
|
||||
rec = tmp->data;
|
||||
|
||||
if (theme_read(rec, rec->path))
|
||||
errors = TRUE;
|
||||
theme_read(rec, rec->path);
|
||||
}
|
||||
|
||||
if (errors)
|
||||
signal_add("irssi init finished", (SIGNAL_FUNC) sig_formats_error);
|
||||
|
||||
/* find the current theme to use */
|
||||
value = settings_get_str("current_theme");
|
||||
|
||||
rec = theme_find(value);
|
||||
if (rec != NULL) current_theme = rec;
|
||||
|
||||
command_bind("format", NULL, (SIGNAL_FUNC) cmd_format);
|
||||
command_bind("save", NULL, (SIGNAL_FUNC) cmd_save);
|
||||
}
|
||||
|
||||
void themes_deinit(void)
|
||||
@ -275,4 +472,9 @@ void themes_deinit(void)
|
||||
g_slist_foreach(themes, (GFunc) theme_destroy, NULL);
|
||||
g_slist_free(themes);
|
||||
themes = NULL;
|
||||
|
||||
g_hash_table_destroy(default_formats);
|
||||
|
||||
command_unbind("format", (SIGNAL_FUNC) cmd_format);
|
||||
command_unbind("save", (SIGNAL_FUNC) cmd_save);
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
#ifndef __THEMES_H
|
||||
#define __THEMES_H
|
||||
|
||||
#include "printtext.h"
|
||||
|
||||
#define THEME_FLAG_BG_SCROLLABLE 0x0001
|
||||
#define THEME_FLAG_BG_SCALED 0x0002
|
||||
#define THEME_FLAG_BG_SHADED 0x0004
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
char *name;
|
||||
|
||||
char **formatlist;
|
||||
char **format;
|
||||
}
|
||||
MODULE_THEME_REC;
|
||||
int count;
|
||||
char **formats; /* in same order as in module's default formats */
|
||||
} MODULE_THEME_REC;
|
||||
|
||||
typedef struct {
|
||||
char *path;
|
||||
@ -30,10 +30,16 @@ typedef struct {
|
||||
|
||||
extern GSList *themes;
|
||||
extern THEME_REC *current_theme;
|
||||
extern GHashTable *default_formats;
|
||||
|
||||
THEME_REC *theme_create(const char *path, const char *name);
|
||||
void theme_destroy(THEME_REC *rec);
|
||||
|
||||
#define theme_register(formats) theme_register_module(MODULE_NAME, formats)
|
||||
#define theme_unregister() theme_unregister_module(MODULE_NAME)
|
||||
void theme_register_module(const char *module, FORMAT_REC *formats);
|
||||
void theme_unregister_module(const char *module);
|
||||
|
||||
void themes_init(void);
|
||||
void themes_deinit(void);
|
||||
|
||||
|
@ -26,13 +26,11 @@
|
||||
#include "windows.h"
|
||||
#include "window-items.h"
|
||||
|
||||
static void sig_hilight_text(SERVER_REC *server, const char *channel, gpointer levelptr, const char *msg)
|
||||
static void sig_hilight_text(WINDOW_REC *window, SERVER_REC *server, const char *channel, gpointer levelptr, const char *msg)
|
||||
{
|
||||
WINDOW_REC *window;
|
||||
int level, oldlevel;
|
||||
|
||||
level = GPOINTER_TO_INT(levelptr);
|
||||
window = window_find_closest(server, channel, level);
|
||||
if (window == active_win || (level & (MSGLEVEL_NEVER|MSGLEVEL_NO_ACT|MSGLEVEL_MSGS)))
|
||||
return;
|
||||
|
||||
|
370
src/fe-common/core/window-commands.c
Normal file
370
src/fe-common/core/window-commands.c
Normal 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);
|
||||
}
|
@ -27,7 +27,6 @@
|
||||
|
||||
#include "levels.h"
|
||||
|
||||
#include "printtext.h"
|
||||
#include "windows.h"
|
||||
#include "window-items.h"
|
||||
|
||||
@ -86,17 +85,6 @@ WINDOW_REC *window_item_window(WI_ITEM_REC *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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
GSList *tmp;
|
||||
|
@ -10,9 +10,12 @@ void window_remove_item(WINDOW_REC *window, WI_ITEM_REC *item);
|
||||
void window_item_create(WI_ITEM_REC *item, int automatic);
|
||||
|
||||
WINDOW_REC *window_item_window(WI_ITEM_REC *item);
|
||||
void window_item_set_active(WINDOW_REC *window, WI_ITEM_REC *item);
|
||||
void window_item_change_server(WI_ITEM_REC *item, void *server);
|
||||
|
||||
void window_item_set_active(WINDOW_REC *window, WI_ITEM_REC *item);
|
||||
void window_item_prev(WINDOW_REC *window);
|
||||
void window_item_next(WINDOW_REC *window);
|
||||
|
||||
/* Find wanted window item by name. `server' can be NULL. */
|
||||
WI_ITEM_REC *window_item_find(void *server, const char *name);
|
||||
|
||||
|
@ -37,6 +37,8 @@ GSList *windows; /* first in the list is the active window,
|
||||
next is the last active, etc. */
|
||||
WINDOW_REC *active_win;
|
||||
|
||||
static int daytag;
|
||||
|
||||
static int window_get_new_refnum(void)
|
||||
{
|
||||
WINDOW_REC *win;
|
||||
@ -247,117 +249,6 @@ WINDOW_REC *window_find_refnum(int refnum)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int windows_refnum_last(void)
|
||||
{
|
||||
GSList *tmp;
|
||||
int max;
|
||||
|
||||
max = -1;
|
||||
for (tmp = windows; tmp != NULL; tmp = tmp->next) {
|
||||
WINDOW_REC *rec = tmp->data;
|
||||
|
||||
if (rec->refnum > max)
|
||||
max = rec->refnum;
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
static int window_refnum_prev(int refnum)
|
||||
{
|
||||
GSList *tmp;
|
||||
int prev, max;
|
||||
|
||||
max = prev = -1;
|
||||
for (tmp = windows; tmp != NULL; tmp = tmp->next) {
|
||||
WINDOW_REC *rec = tmp->data;
|
||||
|
||||
if (rec->refnum < refnum && (prev == -1 || rec->refnum > prev))
|
||||
prev = rec->refnum;
|
||||
if (max == -1 || rec->refnum > max)
|
||||
max = rec->refnum;
|
||||
}
|
||||
|
||||
return prev != -1 ? prev : max;
|
||||
}
|
||||
|
||||
static int window_refnum_next(int refnum)
|
||||
{
|
||||
GSList *tmp;
|
||||
int min, next;
|
||||
|
||||
min = next = -1;
|
||||
for (tmp = windows; tmp != NULL; tmp = tmp->next) {
|
||||
WINDOW_REC *rec = tmp->data;
|
||||
|
||||
if (rec->refnum > refnum && (next == -1 || rec->refnum < next))
|
||||
next = rec->refnum;
|
||||
if (min == -1 || rec->refnum < min)
|
||||
min = rec->refnum;
|
||||
}
|
||||
|
||||
return next != -1 ? next : min;
|
||||
}
|
||||
|
||||
static void cmd_window(const char *data, void *server, WI_ITEM_REC *item)
|
||||
{
|
||||
command_runsub("window", data, server, item);
|
||||
}
|
||||
|
||||
static void cmd_window_new(const char *data, void *server, WI_ITEM_REC *item)
|
||||
{
|
||||
WINDOW_REC *window;
|
||||
int type;
|
||||
|
||||
g_return_if_fail(data != NULL);
|
||||
|
||||
type = (g_strncasecmp(data, "hid", 3) == 0 || g_strcasecmp(data, "tab") == 0) ? 1 :
|
||||
(g_strcasecmp(data, "split") == 0 ? 2 : 0);
|
||||
signal_emit("gui window create override", 1, GINT_TO_POINTER(type));
|
||||
|
||||
window = window_create(NULL, FALSE);
|
||||
window_change_server(window, server);
|
||||
}
|
||||
|
||||
static void cmd_window_close(const char *data)
|
||||
{
|
||||
/* destroy window unless it's the last one */
|
||||
if (windows->next != NULL)
|
||||
window_destroy(active_win);
|
||||
}
|
||||
|
||||
/* return the first window number with the highest activity */
|
||||
static WINDOW_REC *window_highest_activity(WINDOW_REC *window)
|
||||
{
|
||||
WINDOW_REC *rec, *max_win;
|
||||
GSList *tmp;
|
||||
int max_act, through;
|
||||
|
||||
g_return_val_if_fail(window != NULL, NULL);
|
||||
|
||||
max_win = NULL; max_act = 0; through = FALSE;
|
||||
|
||||
tmp = g_slist_find(windows, window);
|
||||
for (;; tmp = tmp->next) {
|
||||
if (tmp == NULL) {
|
||||
tmp = windows;
|
||||
through = TRUE;
|
||||
}
|
||||
|
||||
if (through && tmp->data == window)
|
||||
break;
|
||||
|
||||
rec = tmp->data;
|
||||
|
||||
if (rec->new_data && max_act < rec->new_data) {
|
||||
max_act = rec->new_data;
|
||||
max_win = rec;
|
||||
}
|
||||
}
|
||||
|
||||
return max_win;
|
||||
}
|
||||
|
||||
WINDOW_REC *window_find_name(const char *name)
|
||||
{
|
||||
GSList *tmp;
|
||||
@ -409,288 +300,56 @@ WINDOW_REC *window_find_item(WINDOW_REC *window, const char *name)
|
||||
return MODULE_DATA(item);
|
||||
}
|
||||
|
||||
static void cmd_window_refnum(const char *data)
|
||||
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;
|
||||
int prev, max;
|
||||
|
||||
window = item == NULL ? NULL : MODULE_DATA(item);
|
||||
if (window == NULL) return;
|
||||
|
||||
last = NULL;
|
||||
for (tmp = window->items; tmp != NULL; tmp = tmp->next) {
|
||||
WI_ITEM_REC *rec = tmp->data;
|
||||
|
||||
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;
|
||||
max = prev = -1;
|
||||
for (tmp = windows; tmp != NULL; tmp = tmp->next) {
|
||||
list = g_slist_insert_sorted(list, tmp->data, (GCompareFunc) windows_compare);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static void cmd_window_list(void)
|
||||
{
|
||||
GSList *tmp, *sorted;
|
||||
char *levelstr;
|
||||
|
||||
sorted = windows_get_sorted();
|
||||
printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_WINDOWLIST_HEADER);
|
||||
for (tmp = sorted; tmp != NULL; tmp = tmp->next) {
|
||||
WINDOW_REC *rec = tmp->data;
|
||||
|
||||
levelstr = bits2level(rec->level);
|
||||
printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_WINDOWLIST_LINE,
|
||||
rec->refnum, rec->name == NULL ? "" : rec->name,
|
||||
rec->active == NULL ? "" : rec->active->name,
|
||||
rec->active_server == NULL ? "" : ((SERVER_REC *) rec->active_server)->tag,
|
||||
levelstr);
|
||||
g_free(levelstr);
|
||||
if (rec->refnum < refnum && (prev == -1 || rec->refnum > prev))
|
||||
prev = rec->refnum;
|
||||
if (max == -1 || rec->refnum > max)
|
||||
max = rec->refnum;
|
||||
}
|
||||
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)
|
||||
@ -722,29 +381,46 @@ static void sig_server_disconnected(void *server)
|
||||
}
|
||||
}
|
||||
|
||||
static int sig_check_daychange(void)
|
||||
{
|
||||
static int lastday = -1;
|
||||
GSList *tmp;
|
||||
time_t t;
|
||||
struct tm *tm;
|
||||
|
||||
if (!settings_get_bool("timestamps")) {
|
||||
/* display day change notice only when using timestamps */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
t = time(NULL);
|
||||
tm = localtime(&t);
|
||||
|
||||
if (lastday == -1) {
|
||||
/* First check, don't display. */
|
||||
lastday = tm->tm_mday;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (tm->tm_mday == lastday)
|
||||
return TRUE;
|
||||
|
||||
/* day changed, print notice about it to every window */
|
||||
for (tmp = windows; tmp != NULL; tmp = tmp->next) {
|
||||
printformat_window(tmp->data, MSGLEVEL_NEVER, IRCTXT_DAYCHANGE,
|
||||
tm->tm_mday, tm->tm_mon+1, 1900+tm->tm_year);
|
||||
}
|
||||
|
||||
lastday = tm->tm_mday;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void windows_init(void)
|
||||
{
|
||||
active_win = NULL;
|
||||
settings_add_bool("lookandfeel", "window_auto_change", FALSE);
|
||||
|
||||
command_bind("window", NULL, (SIGNAL_FUNC) cmd_window);
|
||||
command_bind("window new", NULL, (SIGNAL_FUNC) cmd_window_new);
|
||||
command_bind("window close", NULL, (SIGNAL_FUNC) cmd_window_close);
|
||||
command_bind("window kill", NULL, (SIGNAL_FUNC) cmd_window_close);
|
||||
command_bind("window server", NULL, (SIGNAL_FUNC) cmd_window_server);
|
||||
command_bind("window refnum", NULL, (SIGNAL_FUNC) cmd_window_refnum);
|
||||
command_bind("window goto", NULL, (SIGNAL_FUNC) cmd_window_goto);
|
||||
command_bind("window prev", NULL, (SIGNAL_FUNC) cmd_window_prev);
|
||||
command_bind("window next", NULL, (SIGNAL_FUNC) cmd_window_next);
|
||||
command_bind("window level", NULL, (SIGNAL_FUNC) cmd_window_level);
|
||||
command_bind("window item prev", NULL, (SIGNAL_FUNC) cmd_window_item_prev);
|
||||
command_bind("window item next", NULL, (SIGNAL_FUNC) cmd_window_item_next);
|
||||
command_bind("window number", NULL, (SIGNAL_FUNC) cmd_window_number);
|
||||
command_bind("window name", NULL, (SIGNAL_FUNC) cmd_window_name);
|
||||
command_bind("window move", NULL, (SIGNAL_FUNC) cmd_window_move);
|
||||
command_bind("window move left", NULL, (SIGNAL_FUNC) cmd_window_move_left);
|
||||
command_bind("window move right", NULL, (SIGNAL_FUNC) cmd_window_move_right);
|
||||
command_bind("window list", NULL, (SIGNAL_FUNC) cmd_window_list);
|
||||
daytag = g_timeout_add(30000, (GSourceFunc) sig_check_daychange, NULL);
|
||||
signal_add("server looking", (SIGNAL_FUNC) sig_server_looking);
|
||||
signal_add("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
|
||||
signal_add("server connect failed", (SIGNAL_FUNC) sig_server_disconnected);
|
||||
@ -752,24 +428,8 @@ void windows_init(void)
|
||||
|
||||
void windows_deinit(void)
|
||||
{
|
||||
command_unbind("window", (SIGNAL_FUNC) cmd_window);
|
||||
command_unbind("window new", (SIGNAL_FUNC) cmd_window_new);
|
||||
command_unbind("window close", (SIGNAL_FUNC) cmd_window_close);
|
||||
command_unbind("window kill", (SIGNAL_FUNC) cmd_window_close);
|
||||
command_unbind("window server", (SIGNAL_FUNC) cmd_window_server);
|
||||
command_unbind("window refnum", (SIGNAL_FUNC) cmd_window_refnum);
|
||||
command_unbind("window goto", (SIGNAL_FUNC) cmd_window_goto);
|
||||
command_unbind("window prev", (SIGNAL_FUNC) cmd_window_prev);
|
||||
command_unbind("window next", (SIGNAL_FUNC) cmd_window_next);
|
||||
command_unbind("window level", (SIGNAL_FUNC) cmd_window_level);
|
||||
command_unbind("window item prev", (SIGNAL_FUNC) cmd_window_item_prev);
|
||||
command_unbind("window item next", (SIGNAL_FUNC) cmd_window_item_next);
|
||||
command_unbind("window number", (SIGNAL_FUNC) cmd_window_number);
|
||||
command_unbind("window name", (SIGNAL_FUNC) cmd_window_name);
|
||||
command_unbind("window move", (SIGNAL_FUNC) cmd_window_move);
|
||||
command_unbind("window move left", (SIGNAL_FUNC) cmd_window_move_left);
|
||||
command_unbind("window move right", (SIGNAL_FUNC) cmd_window_move_right);
|
||||
command_unbind("window list", (SIGNAL_FUNC) cmd_window_list);
|
||||
g_source_remove(daytag);
|
||||
|
||||
signal_remove("server looking", (SIGNAL_FUNC) sig_server_looking);
|
||||
signal_remove("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
|
||||
signal_remove("server connect failed", (SIGNAL_FUNC) sig_server_disconnected);
|
||||
|
@ -69,6 +69,10 @@ WINDOW_REC *window_find_refnum(int refnum);
|
||||
WINDOW_REC *window_find_name(const char *name);
|
||||
WINDOW_REC *window_find_item(WINDOW_REC *window, const char *name);
|
||||
|
||||
int window_refnum_prev(int refnum);
|
||||
int window_refnum_next(int refnum);
|
||||
int windows_refnum_last(void);
|
||||
|
||||
void windows_init(void);
|
||||
void windows_deinit(void);
|
||||
|
||||
|
@ -14,4 +14,5 @@ libfe_common_irc_dcc_la_SOURCES = \
|
||||
module-formats.c
|
||||
|
||||
noinst_HEADERS = \
|
||||
module.h \
|
||||
module-formats.h
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include "irc/dcc/dcc.h"
|
||||
|
||||
#include "themes.h"
|
||||
#include "windows.h"
|
||||
|
||||
static void dcc_connected(DCC_REC *dcc)
|
||||
@ -427,10 +428,14 @@ void fe_dcc_init(void)
|
||||
command_bind("dcc ", NULL, (SIGNAL_FUNC) cmd_dcc_list);
|
||||
command_bind("dcc list", NULL, (SIGNAL_FUNC) cmd_dcc_list);
|
||||
signal_add("window item remove", (SIGNAL_FUNC) dcc_chat_closed);
|
||||
|
||||
theme_register(fecommon_irc_dcc_formats);
|
||||
}
|
||||
|
||||
void fe_dcc_deinit(void)
|
||||
{
|
||||
theme_unregister();
|
||||
|
||||
signal_remove("dcc connected", (SIGNAL_FUNC) dcc_connected);
|
||||
signal_remove("dcc rejected", (SIGNAL_FUNC) dcc_rejected);
|
||||
signal_remove("dcc closed", (SIGNAL_FUNC) dcc_closed);
|
||||
|
@ -21,8 +21,7 @@
|
||||
#include "module.h"
|
||||
#include "printtext.h"
|
||||
|
||||
FORMAT_REC fecommon_irc_dcc_formats[] =
|
||||
{
|
||||
FORMAT_REC fecommon_irc_dcc_formats[] = {
|
||||
{ MODULE_NAME, "IRC", 0 },
|
||||
|
||||
/* ---- */
|
||||
@ -55,5 +54,7 @@ FORMAT_REC fecommon_irc_dcc_formats[] =
|
||||
{ "dcc_connect_error", "%gDCC can't connect to %_$0%_ port %_$1", 2, { 0, 1 } },
|
||||
{ "dcc_cant_create", "%gDCC can't create file %G$0%g", 1, { 0 } },
|
||||
{ "dcc_rejected", "%gDCC %G$0%g was rejected by %_$1%_ %K[%G$2%K]", 3, { 0, 0, 0 } },
|
||||
{ "dcc_close", "%gDCC %G$0%g close for %_$1%_ %K[%G$2%K]", 3, { 0, 0, 0 } }
|
||||
{ "dcc_close", "%gDCC %G$0%g close for %_$1%_ %K[%G$2%K]", 3, { 0, 0, 0 } },
|
||||
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
@ -36,6 +36,3 @@ enum {
|
||||
};
|
||||
|
||||
extern FORMAT_REC fecommon_irc_dcc_formats[];
|
||||
#define MODULE_FORMATS fecommon_irc_dcc_formats
|
||||
|
||||
#include "printformat.h"
|
||||
|
3
src/fe-common/irc/dcc/module.h
Normal file
3
src/fe-common/irc/dcc/module.h
Normal file
@ -0,0 +1,3 @@
|
||||
#include "common.h"
|
||||
|
||||
#define MODULE_NAME "fe-common/irc/dcc"
|
@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "module-formats.h"
|
||||
#include "signals.h"
|
||||
#include "args.h"
|
||||
#include "misc.h"
|
||||
@ -27,6 +28,7 @@
|
||||
|
||||
#include "server-setup.h"
|
||||
|
||||
#include "themes.h"
|
||||
#include "completion.h"
|
||||
|
||||
void fe_channels_init(void);
|
||||
@ -100,6 +102,8 @@ void fe_common_irc_init(void)
|
||||
settings_add_bool("lookandfeel", "show_away_once", TRUE);
|
||||
settings_add_bool("lookandfeel", "show_quit_once", FALSE);
|
||||
|
||||
theme_register(fecommon_irc_formats);
|
||||
|
||||
fe_channels_init();
|
||||
fe_irc_commands_init();
|
||||
fe_irc_server_init();
|
||||
@ -132,6 +136,8 @@ void fe_common_irc_deinit(void)
|
||||
fe_query_deinit();
|
||||
completion_deinit();
|
||||
irc_window_activity_deinit();
|
||||
|
||||
theme_unregister();
|
||||
}
|
||||
|
||||
void fe_common_irc_finish_init(void)
|
||||
|
@ -13,5 +13,6 @@ libfe_common_irc_flood_la_SOURCES = \
|
||||
fe-flood.c \
|
||||
module-formats.c
|
||||
|
||||
noinst_headers = \
|
||||
noinst_HEADERS = \
|
||||
module.h \
|
||||
module-formats.h
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include "irc-server.h"
|
||||
#include "irc/flood/autoignore.h"
|
||||
|
||||
#include "themes.h"
|
||||
|
||||
static void event_autoignore_new(IRC_SERVER_REC *server, AUTOIGNORE_REC *ignore)
|
||||
{
|
||||
g_return_if_fail(ignore != NULL);
|
||||
@ -45,10 +47,14 @@ void fe_flood_init(void)
|
||||
{
|
||||
signal_add("autoignore new", (SIGNAL_FUNC) event_autoignore_new);
|
||||
signal_add("autoignore remove", (SIGNAL_FUNC) event_autoignore_remove);
|
||||
|
||||
theme_register(fecommon_irc_flood_formats);
|
||||
}
|
||||
|
||||
void fe_flood_deinit(void)
|
||||
{
|
||||
theme_unregister();
|
||||
|
||||
signal_remove("autoignore new", (SIGNAL_FUNC) event_autoignore_new);
|
||||
signal_remove("autoignore remove", (SIGNAL_FUNC) event_autoignore_remove);
|
||||
}
|
||||
|
@ -29,5 +29,7 @@ FORMAT_REC fecommon_irc_flood_formats[] =
|
||||
{ NULL, "Autoignore", 0 },
|
||||
|
||||
{ "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 }
|
||||
};
|
||||
|
@ -10,6 +10,3 @@ enum {
|
||||
};
|
||||
|
||||
extern FORMAT_REC fecommon_irc_flood_formats[];
|
||||
#define MODULE_FORMATS fecommon_irc_flood_formats
|
||||
|
||||
#include "printformat.h"
|
||||
|
3
src/fe-common/irc/flood/module.h
Normal file
3
src/fe-common/irc/flood/module.h
Normal file
@ -0,0 +1,3 @@
|
||||
#include "common.h"
|
||||
|
||||
#define MODULE_NAME "fe-common/irc/flood"
|
@ -21,8 +21,7 @@
|
||||
#include "module.h"
|
||||
#include "printtext.h"
|
||||
|
||||
FORMAT_REC fecommon_irc_formats[] =
|
||||
{
|
||||
FORMAT_REC fecommon_irc_formats[] = {
|
||||
{ MODULE_NAME, "IRC", 0 },
|
||||
|
||||
/* ---- */
|
||||
@ -42,7 +41,7 @@ FORMAT_REC fecommon_irc_formats[] =
|
||||
{ "setupserver_header", "Server Port IRC Net Settings", 0 },
|
||||
{ "setupserver_line", "%|$[!20]0 $[5]1 $[10]2 $3", 4, { 0, 1, 0, 0 } },
|
||||
{ "setupserver_footer", "", 0 },
|
||||
{ "netsplit", "[%_$2%_] %RNetsplit%n detected between servers %_$0%_ and %_$1%_%:Use /NETSPLIT to see who left", 3, { 0, 0, 0 } },
|
||||
{ "netsplit", "%RNetsplit%n detected between servers %_$0%_ and %_$1%_%:Use /NETSPLIT to see who left", 2, { 0, 0 } },
|
||||
{ "no_netsplits", "There are no net splits", 0 },
|
||||
{ "netsplits_header", "Nick Channel Server Splitted server", 0 },
|
||||
{ "netsplits_line", "$[9]0 $[10]1 $[20]2 $3", 4, { 0, 0, 0, 0 } },
|
||||
@ -189,5 +188,6 @@ FORMAT_REC fecommon_irc_formats[] =
|
||||
{ "talking_in", "You are now talking in %_$0%_", 1, { 0 } },
|
||||
{ "no_query", "No query with %_$0%_", 1, { 0 } },
|
||||
{ "no_msgs_got", "You have not received a message from anyone yet", 0 },
|
||||
{ "no_msgs_sent", "You have not sent a message to anyone yet", 0 }
|
||||
};
|
||||
{ "no_msgs_sent", "You have not sent a message to anyone yet", 0 },
|
||||
|
||||
{ NULL, NULL, 0 }
|
||||
|
@ -162,6 +162,3 @@ enum {
|
||||
};
|
||||
|
||||
extern FORMAT_REC fecommon_irc_formats[];
|
||||
#define MODULE_FORMATS fecommon_irc_formats
|
||||
|
||||
#include "printformat.h"
|
||||
|
@ -13,5 +13,6 @@ libfe_common_irc_notifylist_la_SOURCES = \
|
||||
fe-notifylist.c \
|
||||
module-formats.c
|
||||
|
||||
noinst_headers = \
|
||||
noinst_HEADERS = \
|
||||
module.h \
|
||||
module-formats.h
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include "ircnet-setup.h"
|
||||
#include "irc/notifylist/notifylist.h"
|
||||
|
||||
#include "themes.h"
|
||||
|
||||
/* add the nick of a hostmask to list if it isn't there already */
|
||||
static GSList *mask_add_once(GSList *list, const char *mask)
|
||||
{
|
||||
@ -224,6 +226,8 @@ static void notifylist_unidle(IRC_SERVER_REC *server, const char *nick,
|
||||
|
||||
void fe_notifylist_init(void)
|
||||
{
|
||||
theme_register(fecommon_irc_notifylist_formats);
|
||||
|
||||
command_bind("notify", NULL, (SIGNAL_FUNC) cmd_notify);
|
||||
signal_add("notifylist joined", (SIGNAL_FUNC) notifylist_joined);
|
||||
signal_add("notifylist left", (SIGNAL_FUNC) notifylist_left);
|
||||
@ -233,6 +237,8 @@ void fe_notifylist_init(void)
|
||||
|
||||
void fe_notifylist_deinit(void)
|
||||
{
|
||||
theme_unregister();
|
||||
|
||||
command_unbind("notify", (SIGNAL_FUNC) cmd_notify);
|
||||
signal_remove("notifylist joined", (SIGNAL_FUNC) notifylist_joined);
|
||||
signal_remove("notifylist left", (SIGNAL_FUNC) notifylist_left);
|
||||
|
@ -35,5 +35,7 @@ FORMAT_REC fecommon_irc_notifylist_formats[] =
|
||||
{ "notify_unidle", "%_$0%_ %K[%n$5%K]%n %K[%n$1@$2%K] [%n%_$3%_%K]%n just stopped idling", 6, { 0, 0, 0, 0, 0, 0 } },
|
||||
{ "notify_online", "On $0: %_$1%_", 2, { 0, 0 } },
|
||||
{ "notify_offline", "Offline: $0", 1, { 0 } },
|
||||
{ "notify_list", "$0: $1 $2 $3", 4, { 0, 0, 0, 0 } }
|
||||
{ "notify_list", "$0: $1 $2 $3", 4, { 0, 0, 0, 0 } },
|
||||
|
||||
{ NULL, NULL, 0 },
|
||||
};
|
||||
|
@ -16,6 +16,3 @@ enum {
|
||||
};
|
||||
|
||||
extern FORMAT_REC fecommon_irc_notifylist_formats[];
|
||||
#define MODULE_FORMATS fecommon_irc_notifylist_formats
|
||||
|
||||
#include "printformat.h"
|
||||
|
3
src/fe-common/irc/notifylist/module.h
Normal file
3
src/fe-common/irc/notifylist/module.h
Normal file
@ -0,0 +1,3 @@
|
||||
#include "common.h"
|
||||
|
||||
#define MODULE_NAME "fe-common/irc/notifylist"
|
@ -35,25 +35,27 @@
|
||||
static gint mirc_colors[] = { 15, 0, 1, 2, 4, 6, 5, 4, 14, 10, 3, 11, 9, 13, 8, 7, 15 };
|
||||
static gint max_textwidget_lines;
|
||||
|
||||
static LINE_REC *create_line(GUI_WINDOW_REC *gui, gint level)
|
||||
#define mark_temp_eol(text) \
|
||||
memcpy((text)->buffer + (text)->pos, "\0\x80", 2);
|
||||
|
||||
static LINE_REC *create_line(GUI_WINDOW_REC *gui, int level)
|
||||
{
|
||||
g_return_val_if_fail(gui != NULL, NULL);
|
||||
g_return_val_if_fail(gui->cur_text != NULL, NULL);
|
||||
|
||||
gui->cur_line = g_mem_chunk_alloc(gui->line_chunk);
|
||||
gui->cur_line->text = gui->cur_text->buffer+gui->cur_text->pos;
|
||||
gui->cur_line->level = (gint32) GPOINTER_TO_INT(level);
|
||||
gui->cur_line->level = GPOINTER_TO_INT(level);
|
||||
gui->cur_line->time = time(NULL);
|
||||
|
||||
/* temporarily mark the end of line. */
|
||||
memcpy(gui->cur_text->buffer+gui->cur_text->pos, "\0\x80", 2);
|
||||
mark_temp_eol(gui->cur_text);
|
||||
|
||||
gui->last_color = -1;
|
||||
gui->last_flags = 0;
|
||||
|
||||
gui->lines = g_list_append(gui->lines, gui->cur_line);
|
||||
if (gui->startline == NULL)
|
||||
{
|
||||
if (gui->startline == NULL) {
|
||||
/* first line */
|
||||
gui->startline = gui->lines;
|
||||
gui->bottom_startline = gui->lines;
|
||||
}
|
||||
@ -63,8 +65,7 @@ static LINE_REC *create_line(GUI_WINDOW_REC *gui, gint level)
|
||||
static TEXT_CHUNK_REC *create_text_chunk(GUI_WINDOW_REC *gui)
|
||||
{
|
||||
TEXT_CHUNK_REC *rec;
|
||||
guchar *buffer;
|
||||
gchar *ptr;
|
||||
char *buffer, *ptr;
|
||||
|
||||
g_return_val_if_fail(gui != NULL, NULL);
|
||||
|
||||
@ -74,16 +75,15 @@ static TEXT_CHUNK_REC *create_text_chunk(GUI_WINDOW_REC *gui)
|
||||
rec->pos = 0;
|
||||
rec->lines = 0;
|
||||
|
||||
if (gui->cur_line != NULL && gui->cur_line->text != NULL)
|
||||
{
|
||||
/* mark the next block text block position.. */
|
||||
buffer = (guchar *) gui->cur_text->buffer+gui->cur_text->pos;
|
||||
if (gui->cur_text->pos+2+sizeof(gchar *) > LINE_TEXT_CHUNK_SIZE)
|
||||
g_error("create_text_chunk() : buffer overflow?!");
|
||||
*buffer++ = 0; *buffer++ = LINE_CMD_CONTINUE;
|
||||
if (gui->cur_line != NULL && gui->cur_line->text != NULL) {
|
||||
/* create a link to new block from the old block */
|
||||
buffer = gui->cur_text->buffer + gui->cur_text->pos;
|
||||
*buffer++ = 0; *buffer++ = (char) LINE_CMD_CONTINUE;
|
||||
|
||||
ptr = rec->buffer;
|
||||
memcpy(buffer, &ptr, sizeof(gchar *));
|
||||
memcpy(buffer, &ptr, sizeof(char *));
|
||||
}
|
||||
|
||||
gui->cur_text = rec;
|
||||
gui->text_chunks = g_slist_append(gui->text_chunks, rec);
|
||||
return rec;
|
||||
@ -111,13 +111,13 @@ static void remove_first_line(WINDOW_REC *window)
|
||||
if (--chunk->lines == 0)
|
||||
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->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_subline = 0;
|
||||
}
|
||||
@ -130,17 +130,14 @@ static void remove_first_line(WINDOW_REC *window)
|
||||
gui_window_redraw(window);
|
||||
}
|
||||
|
||||
static void get_colors(gint flags, gint *fg, gint *bg)
|
||||
{
|
||||
if (flags & PRINTFLAG_MIRC_COLOR)
|
||||
static void get_colors(int flags, int *fg, int *bg)
|
||||
{
|
||||
if (flags & PRINTFLAG_MIRC_COLOR) {
|
||||
/* mirc colors */
|
||||
*fg = *fg < 0 || *fg > 16 ?
|
||||
current_theme->default_color : mirc_colors[*fg];
|
||||
*bg = *bg < 0 || *bg > 16 ? 0 : mirc_colors[*bg];
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* default colors */
|
||||
*fg = *fg < 0 || *fg > 15 ?
|
||||
current_theme->default_color : *fg;
|
||||
@ -149,9 +146,8 @@ static void get_colors(gint flags, gint *fg, gint *bg)
|
||||
if (*fg > 8) *fg -= 8;
|
||||
}
|
||||
|
||||
if (flags & PRINTFLAG_REVERSE)
|
||||
{
|
||||
gint tmp;
|
||||
if (flags & PRINTFLAG_REVERSE) {
|
||||
int tmp;
|
||||
|
||||
tmp = *fg; *fg = *bg; *bg = tmp;
|
||||
}
|
||||
@ -162,18 +158,19 @@ static void get_colors(gint flags, gint *fg, gint *bg)
|
||||
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;
|
||||
|
||||
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;
|
||||
if (str[left-1] == 0) left--; /* don't split the command! */
|
||||
if (str[left-1] == 0) left--; /* don't split the commands */
|
||||
|
||||
memcpy(gui->cur_text->buffer + gui->cur_text->pos, str, left);
|
||||
gui->cur_text->pos += left;
|
||||
|
||||
create_text_chunk(gui);
|
||||
len -= left; str += left;
|
||||
}
|
||||
@ -182,54 +179,48 @@ static void linebuf_add(GUI_WINDOW_REC *gui, gchar *str, gint 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];
|
||||
gint color, pos;
|
||||
unsigned char buffer[12];
|
||||
int color, pos;
|
||||
|
||||
color = (fg & 0x0f) | (bg << 4);
|
||||
pos = 0;
|
||||
|
||||
if (((fg & ATTR_COLOR8) == 0 && (fg|(bg << 4)) != gui->last_color) ||
|
||||
((fg & ATTR_COLOR8) && (fg & 0xf0) != (gui->last_color & 0xf0)))
|
||||
{
|
||||
((fg & ATTR_COLOR8) && (fg & 0xf0) != (gui->last_color & 0xf0))) {
|
||||
buffer[pos++] = 0;
|
||||
buffer[pos++] = (gchar) color;
|
||||
buffer[pos++] = color;
|
||||
}
|
||||
|
||||
if ((flags & PRINTFLAG_UNDERLINE) != (gui->last_flags & PRINTFLAG_UNDERLINE))
|
||||
{
|
||||
if ((flags & PRINTFLAG_UNDERLINE) != (gui->last_flags & PRINTFLAG_UNDERLINE)) {
|
||||
buffer[pos++] = 0;
|
||||
buffer[pos++] = LINE_CMD_UNDERLINE;
|
||||
}
|
||||
if (fg & ATTR_COLOR8)
|
||||
{
|
||||
if (fg & ATTR_COLOR8) {
|
||||
buffer[pos++] = 0;
|
||||
buffer[pos++] = LINE_CMD_COLOR8;
|
||||
}
|
||||
if (flags & PRINTFLAG_BEEP)
|
||||
{
|
||||
if (flags & PRINTFLAG_BEEP) {
|
||||
buffer[pos++] = 0;
|
||||
buffer[pos++] = LINE_CMD_BEEP;
|
||||
}
|
||||
if (flags & PRINTFLAG_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_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;
|
||||
LINE_REC *line;
|
||||
gboolean visible;
|
||||
gint fg, bg, flags, lines, n;
|
||||
int fg, bg, flags, new_lines, n, visible, ypos;
|
||||
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
@ -246,17 +237,16 @@ static void gui_printtext(WINDOW_REC *window, gpointer fgcolor, gpointer bgcolor
|
||||
create_text_chunk(gui);
|
||||
|
||||
/* \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 */
|
||||
|
||||
line = create_line(gui, 0);
|
||||
gui_window_newline(gui, visible);
|
||||
str++;
|
||||
|
||||
gui->cur_text->lines++;
|
||||
gui->last_subline = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
line = gui->cur_line != NULL ? gui->cur_line :
|
||||
create_line(gui, 0);
|
||||
if (line->level == 0) line->level = GPOINTER_TO_INT(level);
|
||||
@ -265,42 +255,47 @@ static void gui_printtext(WINDOW_REC *window, gpointer fgcolor, gpointer bgcolor
|
||||
get_colors(flags, &fg, &bg);
|
||||
line_add_colors(gui, fg, bg, flags);
|
||||
linebuf_add(gui, str, strlen(str));
|
||||
mark_temp_eol(gui->cur_text);
|
||||
|
||||
/* temporarily mark the end of line. */
|
||||
memcpy(gui->cur_text->buffer+gui->cur_text->pos, "\0\x80", 2);
|
||||
gui_window_cache_remove(gui, line);
|
||||
new_lines = gui_window_get_linecount(gui, line)-1 - gui->last_subline;
|
||||
|
||||
if (visible)
|
||||
{
|
||||
/* draw the line to screen. */
|
||||
lines = gui_window_line_draw(gui, line, gui->parent->first_line+gui->ypos, gui->last_subline, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we still need to update the bottom's position */
|
||||
lines = gui_window_get_linecount(gui, line)-1-gui->last_subline;
|
||||
for (n = 0; n < lines; n++)
|
||||
for (n = 0; n < new_lines; n++)
|
||||
gui_window_newline(gui, visible);
|
||||
|
||||
if (visible) {
|
||||
/* draw the line to screen. */
|
||||
ypos = gui->parent->first_line+gui->ypos-new_lines;
|
||||
if (new_lines > 0) {
|
||||
set_color(0);
|
||||
move(ypos, 0); clrtoeol();
|
||||
}
|
||||
if (lines > 0) gui->last_subline += lines;
|
||||
gui_window_line_draw(gui, line, ypos, gui->last_subline, -1);
|
||||
}
|
||||
|
||||
static void cmd_clear(gchar *data)
|
||||
{
|
||||
GUI_WINDOW_REC *gui;
|
||||
gint n;
|
||||
gui->last_subline += new_lines;
|
||||
}
|
||||
|
||||
gui = WINDOW_GUI(active_win);
|
||||
static void window_clear(GUI_WINDOW_REC *gui)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (is_window_visible(active_win))
|
||||
{
|
||||
for (n = gui->parent->first_line; n <= gui->parent->last_line; n++)
|
||||
{
|
||||
for (n = gui->parent->first_line; n <= gui->parent->last_line; n++) {
|
||||
move(n, 0);
|
||||
clrtoeol();
|
||||
}
|
||||
screen_refresh();
|
||||
}
|
||||
|
||||
static void cmd_clear(void)
|
||||
{
|
||||
GUI_WINDOW_REC *gui;
|
||||
|
||||
gui = WINDOW_GUI(active_win);
|
||||
|
||||
if (is_window_visible(active_win))
|
||||
window_clear(gui);
|
||||
|
||||
gui->ypos = -1;
|
||||
gui->bottom_startline = gui->startline = g_list_last(gui->lines);
|
||||
gui->bottom_subline = gui->subline = gui->last_subline+1;
|
||||
@ -322,9 +317,9 @@ static void read_settings(void)
|
||||
void gui_printtext_init(void)
|
||||
{
|
||||
signal_add("gui print text", (SIGNAL_FUNC) gui_printtext);
|
||||
command_bind("clear", NULL, (SIGNAL_FUNC) cmd_clear);
|
||||
signal_add("print text finished", (SIGNAL_FUNC) sig_printtext_finished);
|
||||
signal_add("setup changed", (SIGNAL_FUNC) read_settings);
|
||||
command_bind("clear", NULL, (SIGNAL_FUNC) cmd_clear);
|
||||
|
||||
read_settings();
|
||||
}
|
||||
@ -332,7 +327,7 @@ void gui_printtext_init(void)
|
||||
void gui_printtext_deinit(void)
|
||||
{
|
||||
signal_remove("gui print text", (SIGNAL_FUNC) gui_printtext);
|
||||
command_unbind("clear", (SIGNAL_FUNC) cmd_clear);
|
||||
signal_remove("print text finished", (SIGNAL_FUNC) sig_printtext_finished);
|
||||
signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
|
||||
command_unbind("clear", (SIGNAL_FUNC) cmd_clear);
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ static GUI_WINDOW_REC *gui_window_init(WINDOW_REC *window, MAIN_WINDOW_REC *pare
|
||||
gui->parent = parent;
|
||||
|
||||
gui->bottom = TRUE;
|
||||
gui->line_cache = g_hash_table_new((GHashFunc) g_direct_hash, (GCompareFunc) g_direct_equal);
|
||||
gui->line_chunk = g_mem_chunk_new("line chunk", sizeof(LINE_REC),
|
||||
sizeof(LINE_REC)*100, G_ALLOC_AND_FREE);
|
||||
gui->empty_linecount = parent->last_line-parent->first_line;
|
||||
@ -53,8 +54,19 @@ static GUI_WINDOW_REC *gui_window_init(WINDOW_REC *window, MAIN_WINDOW_REC *pare
|
||||
return gui;
|
||||
}
|
||||
|
||||
int line_cache_destroy(void *key, LINE_CACHE_REC *cache)
|
||||
{
|
||||
g_free_not_null(cache->lines);
|
||||
g_free(cache);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void gui_window_deinit(GUI_WINDOW_REC *gui)
|
||||
{
|
||||
g_hash_table_foreach(gui->line_cache, (GHFunc) line_cache_destroy, NULL);
|
||||
g_hash_table_destroy(gui->line_cache);
|
||||
|
||||
g_slist_foreach(gui->text_chunks, (GFunc) g_free, NULL);
|
||||
g_slist_free(gui->text_chunks);
|
||||
|
||||
@ -106,7 +118,7 @@ static void gui_window_destroyed(WINDOW_REC *window)
|
||||
gui_window_deinit(gui);
|
||||
window->gui_data = NULL;
|
||||
|
||||
if (mainwindows->next != NULL && parent->active == window)
|
||||
if (parent->active == window && mainwindows->next != NULL)
|
||||
mainwindow_destroy(parent);
|
||||
}
|
||||
|
||||
@ -126,19 +138,20 @@ void gui_window_clear(WINDOW_REC *window)
|
||||
gui_window_redraw(window);
|
||||
}
|
||||
|
||||
int gui_window_update_bottom(GUI_WINDOW_REC *gui, int lines)
|
||||
/* update bottom_startline and bottom_subline of window. */
|
||||
static int gui_window_update_bottom(GUI_WINDOW_REC *gui, int lines)
|
||||
{
|
||||
int linecount, last_linecount;
|
||||
|
||||
if (gui->bottom_startline == NULL)
|
||||
return -1;
|
||||
|
||||
while (lines < 0)
|
||||
{
|
||||
if (gui->bottom_subline > 0)
|
||||
for (; lines < 0; lines++) {
|
||||
if (gui->bottom_subline > 0) {
|
||||
gui->bottom_subline--;
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (gui->bottom_startline->prev == NULL)
|
||||
return -1;
|
||||
gui->bottom_startline = gui->bottom_startline->prev;
|
||||
@ -146,22 +159,16 @@ int gui_window_update_bottom(GUI_WINDOW_REC *gui, int lines)
|
||||
linecount = gui_window_get_linecount(gui, gui->bottom_startline->data);
|
||||
gui->bottom_subline = linecount-1;
|
||||
}
|
||||
lines++;
|
||||
}
|
||||
|
||||
last_linecount = linecount = -1;
|
||||
while (lines > 0)
|
||||
{
|
||||
if (linecount == -1)
|
||||
last_linecount = linecount = gui_window_get_linecount(gui, gui->bottom_startline->data);
|
||||
last_linecount = -1;
|
||||
for (; lines > 0; lines--) {
|
||||
last_linecount = linecount =
|
||||
gui_window_get_linecount(gui, gui->bottom_startline->data);
|
||||
|
||||
if (linecount > gui->bottom_subline+1)
|
||||
gui->bottom_subline++;
|
||||
else
|
||||
{
|
||||
else {
|
||||
gui->bottom_subline = 0;
|
||||
linecount = -1;
|
||||
|
||||
if (gui->bottom_startline->next == NULL)
|
||||
break;
|
||||
gui->bottom_startline = gui->bottom_startline->next;
|
||||
@ -172,157 +179,86 @@ int gui_window_update_bottom(GUI_WINDOW_REC *gui, int lines)
|
||||
return last_linecount;
|
||||
}
|
||||
|
||||
void gui_window_newline(GUI_WINDOW_REC *gui, gboolean visible)
|
||||
void gui_window_newline(GUI_WINDOW_REC *gui, int visible)
|
||||
{
|
||||
gboolean last_line;
|
||||
gint linecount;
|
||||
int lines;
|
||||
|
||||
g_return_if_fail(gui != NULL);
|
||||
|
||||
gui->xpos = 0;
|
||||
last_line = gui->ypos >= gui->parent->last_line-gui->parent->first_line;
|
||||
|
||||
if (gui->empty_linecount > 0)
|
||||
{
|
||||
if (gui->empty_linecount > 0) {
|
||||
/* window buffer height isn't even the size of the screen yet */
|
||||
gui->empty_linecount--;
|
||||
linecount = gui_window_get_linecount(gui, gui->startline->data);
|
||||
}
|
||||
else
|
||||
{
|
||||
linecount = gui_window_update_bottom(gui, 1);
|
||||
gui->ypos++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!last_line || !gui->bottom)
|
||||
{
|
||||
lines = gui_window_update_bottom(gui, 1);
|
||||
|
||||
if (!gui->bottom) {
|
||||
gui->ypos++;
|
||||
return;
|
||||
}
|
||||
else if (gui->bottom)
|
||||
{
|
||||
if (gui->subline >= linecount)
|
||||
{
|
||||
|
||||
if (gui->subline >= lines) {
|
||||
/* 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);
|
||||
lines = gui_window_update_bottom(gui, 1);
|
||||
}
|
||||
|
||||
if (linecount > 1+gui->subline)
|
||||
if (lines > 1+gui->subline)
|
||||
gui->subline++;
|
||||
else
|
||||
{
|
||||
else {
|
||||
gui->startline = gui->startline->next;
|
||||
gui->subline = 0;
|
||||
}
|
||||
|
||||
if (visible)
|
||||
{
|
||||
if (visible) {
|
||||
scroll_up(gui->parent->first_line, gui->parent->last_line);
|
||||
move(gui->parent->last_line, 0); clrtoeol();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* get number of real lines that line record takes - this really should share
|
||||
at least some code with gui_window_line_draw().. */
|
||||
gint gui_window_get_linecount(GUI_WINDOW_REC *gui, LINE_REC *line)
|
||||
static LINE_CACHE_REC *gui_window_line_cache(GUI_WINDOW_REC *gui, LINE_REC *line)
|
||||
{
|
||||
gchar *ptr, *last_space_ptr, *tmp;
|
||||
gint lines, xpos, indent_pos, last_space;
|
||||
LINE_CACHE_REC *rec;
|
||||
LINE_CACHE_SUB_REC *sub;
|
||||
GSList *lines;
|
||||
unsigned char *ptr, *last_space_ptr;
|
||||
int xpos, pos, indent_pos, last_space, color;
|
||||
|
||||
g_return_val_if_fail(gui != NULL, -1);
|
||||
g_return_val_if_fail(line != NULL, -1);
|
||||
g_return_val_if_fail(line->text != NULL, NULL);
|
||||
|
||||
if (line->text == NULL)
|
||||
return 0;
|
||||
rec = g_new(LINE_CACHE_REC, 1);
|
||||
|
||||
xpos = 0; lines = 1; indent_pos = DEFAULT_INDENT_POS;
|
||||
xpos = 0; color = 0; indent_pos = DEFAULT_INDENT_POS;
|
||||
last_space = 0; last_space_ptr = NULL;
|
||||
for (ptr = line->text;; ptr++)
|
||||
{
|
||||
if (*ptr == '\0')
|
||||
{
|
||||
|
||||
rec->count = 1; lines = NULL;
|
||||
for (ptr = (unsigned char *) line->text;;) {
|
||||
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;
|
||||
if (*ptr == LINE_CMD_EOL)
|
||||
break;
|
||||
case LINE_CMD_INDENT:
|
||||
indent_pos = xpos;
|
||||
break;
|
||||
}
|
||||
|
||||
if (*ptr == LINE_CMD_CONTINUE) {
|
||||
char *tmp;
|
||||
|
||||
memcpy(&tmp, ptr+1, sizeof(char *));
|
||||
ptr = tmp;
|
||||
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)
|
||||
{
|
||||
if ((*ptr & 0x80) == 0) {
|
||||
/* set color */
|
||||
color = (color & ATTR_UNDERLINE) | *ptr;
|
||||
}
|
||||
else switch ((guchar) *ptr)
|
||||
{
|
||||
} else switch (*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;
|
||||
@ -330,117 +266,208 @@ gint gui_window_line_draw(GUI_WINDOW_REC *gui, LINE_REC *line, gint ypos, gint s
|
||||
color &= 0xfff0;
|
||||
color |= 8|ATTR_COLOR8;
|
||||
break;
|
||||
case LINE_CMD_BEEP:
|
||||
beep();
|
||||
break;
|
||||
case LINE_CMD_INDENT:
|
||||
indent_pos = xpos;
|
||||
/* set indentation position here - don't do
|
||||
it if we're too close to right border */
|
||||
if (xpos < COLS-5) indent_pos = xpos;
|
||||
break;
|
||||
}
|
||||
set_color(color);
|
||||
|
||||
ptr++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (xpos == COLS)
|
||||
{
|
||||
xpos = indent_pos >= COLS-5 ? DEFAULT_INDENT_POS : indent_pos;
|
||||
if (xpos == COLS) {
|
||||
xpos = 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 (last_space > indent_pos && last_space > 10) {
|
||||
/* go back to last space */
|
||||
ptr = last_space_ptr;
|
||||
color = last_space_color;
|
||||
if (!skip) set_color(color);
|
||||
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;
|
||||
|
||||
if (skip > 0)
|
||||
{
|
||||
if (--skip == 0) set_color(color);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lines == max)
|
||||
return lines;
|
||||
if (max != -1)
|
||||
ypos++;
|
||||
else
|
||||
{
|
||||
gui_window_newline(gui, TRUE);
|
||||
ypos = gui->parent->first_line+gui->ypos;
|
||||
}
|
||||
lines++;
|
||||
}
|
||||
move(ypos, indent_pos);
|
||||
|
||||
/* we could have \0.. */
|
||||
ptr--;
|
||||
continue;
|
||||
}
|
||||
|
||||
xpos++;
|
||||
if (*ptr == ' ')
|
||||
{
|
||||
if (*ptr++ == ' ') {
|
||||
last_space = xpos-1;
|
||||
last_space_color = color;
|
||||
last_space_ptr = ptr+1;
|
||||
last_space_ptr = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (skip) continue;
|
||||
if (lines == -1) lines = 0;
|
||||
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));
|
||||
|
||||
if ((guchar) *ptr >= 32)
|
||||
addch((guchar) *ptr);
|
||||
else
|
||||
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(*ptr+'A'-1);
|
||||
addch(*text+'A'-1);
|
||||
set_color(color);
|
||||
}
|
||||
text++;
|
||||
}
|
||||
}
|
||||
|
||||
int gui_window_line_draw(GUI_WINDOW_REC *gui, LINE_REC *line, int ypos, int skip, int max)
|
||||
{
|
||||
LINE_CACHE_REC *cache;
|
||||
LINE_CACHE_SUB_REC *sub;
|
||||
char *pos, *next_pos;
|
||||
int n;
|
||||
|
||||
g_return_val_if_fail(gui != NULL, -1);
|
||||
g_return_val_if_fail(line != NULL, -1);
|
||||
|
||||
cache = g_hash_table_lookup(gui->line_cache, line);
|
||||
if (cache == NULL)
|
||||
cache = gui_window_line_cache(gui, line);
|
||||
|
||||
if (max < 0) max = cache->count;
|
||||
|
||||
for (n = skip; n < cache->count && max > 0; n++, ypos++, max--) {
|
||||
sub = n == 0 ? NULL : &cache->lines[n-1];
|
||||
pos = sub == NULL ? line->text : sub->start;
|
||||
next_pos = (n+1 < cache->count) ?
|
||||
cache->lines[n].start : NULL;
|
||||
single_line_draw(gui, ypos, sub, pos, next_pos);
|
||||
}
|
||||
|
||||
return cache->count;
|
||||
}
|
||||
|
||||
void gui_window_redraw(WINDOW_REC *window)
|
||||
{
|
||||
GUI_WINDOW_REC *gui;
|
||||
GList *line;
|
||||
gint ypos, lines, skip, max;
|
||||
int ypos, lines, skip, max;
|
||||
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
gui = WINDOW_GUI(window);
|
||||
|
||||
for (ypos = gui->parent->first_line; ypos <= gui->parent->last_line; ypos++)
|
||||
{
|
||||
/* clear the lines first */
|
||||
set_color(0);
|
||||
for (ypos = gui->parent->first_line; ypos <= gui->parent->last_line; ypos++) {
|
||||
move(ypos, 0);
|
||||
clrtoeol();
|
||||
}
|
||||
|
||||
skip = gui->subline;
|
||||
ypos = gui->parent->first_line;
|
||||
for (line = gui->startline; line != NULL; line = line->next)
|
||||
{
|
||||
for (line = gui->startline; line != NULL; line = line->next) {
|
||||
LINE_REC *rec = line->data;
|
||||
|
||||
max = gui->parent->last_line - ypos;
|
||||
max = gui->parent->last_line - ypos+1;
|
||||
if (max < 0) break;
|
||||
|
||||
lines = gui_window_line_draw(gui, rec, ypos, skip, max);
|
||||
ypos += lines-skip;
|
||||
skip = 0;
|
||||
|
||||
ypos += lines+1;
|
||||
}
|
||||
|
||||
screen_refresh();
|
||||
}
|
||||
|
||||
@ -579,6 +606,8 @@ static void signal_window_changed(WINDOW_REC *window)
|
||||
{
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
if (quitting) return;
|
||||
|
||||
if (is_window_visible(window)) {
|
||||
/* already visible, great! */
|
||||
active_mainwin = WINDOW_GUI(window)->parent;
|
||||
@ -674,6 +703,8 @@ static void gui_window_horiz_resize(WINDOW_REC *window)
|
||||
gui = WINDOW_GUI(window);
|
||||
if (gui->lines == NULL) return;
|
||||
|
||||
g_hash_table_foreach_remove(gui->line_cache, (GHRFunc) line_cache_destroy, NULL);
|
||||
|
||||
linecount = gui_window_get_linecount(gui, g_list_last(gui->lines)->data);
|
||||
gui->last_subline = linecount-1;
|
||||
|
||||
@ -703,7 +734,8 @@ void gui_window_resize(WINDOW_REC *window, int ychange, int xchange)
|
||||
gui = WINDOW_GUI(window);
|
||||
|
||||
if (xchange) {
|
||||
/* window width changed, we'll need to recalculate a few things.. */
|
||||
/* window width changed, we'll need to recalculate a
|
||||
few things.. */
|
||||
gui_window_horiz_resize(window);
|
||||
return;
|
||||
}
|
||||
|
@ -22,6 +22,17 @@ enum {
|
||||
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 {
|
||||
/* 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
|
||||
@ -45,6 +56,7 @@ typedef struct {
|
||||
GMemChunk *line_chunk;
|
||||
GSList *text_chunks;
|
||||
GList *lines;
|
||||
GHashTable *line_cache;
|
||||
|
||||
LINE_REC *cur_line;
|
||||
TEXT_CHUNK_REC *cur_text;
|
||||
@ -74,6 +86,7 @@ GList *gui_window_find_text(WINDOW_REC *window, char *text, GList *startline, in
|
||||
|
||||
/* get number of real lines that line record takes */
|
||||
int gui_window_get_linecount(GUI_WINDOW_REC *gui, LINE_REC *line);
|
||||
void gui_window_cache_remove(GUI_WINDOW_REC *gui, LINE_REC *line);
|
||||
int gui_window_line_draw(GUI_WINDOW_REC *gui, LINE_REC *line, int ypos, int skip, int max);
|
||||
|
||||
void gui_window_clear(WINDOW_REC *window);
|
||||
@ -82,8 +95,7 @@ void gui_window_resize(WINDOW_REC *window, int ychange, int xchange);
|
||||
void gui_window_reparent(WINDOW_REC *window, MAIN_WINDOW_REC *parent);
|
||||
|
||||
void window_update_prompt(WINDOW_REC *window);
|
||||
void gui_window_newline(GUI_WINDOW_REC *gui, gboolean visible);
|
||||
int gui_window_update_bottom(GUI_WINDOW_REC *gui, int lines);
|
||||
void gui_window_newline(GUI_WINDOW_REC *gui, int visible);
|
||||
void gui_window_scroll(WINDOW_REC *window, int lines);
|
||||
|
||||
#endif
|
||||
|
@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "module-formats.h"
|
||||
#include "args.h"
|
||||
#include "signals.h"
|
||||
#include "core.h"
|
||||
@ -26,6 +27,7 @@
|
||||
#include "irc-core.h"
|
||||
#include "fe-common-core.h"
|
||||
#include "fe-common-irc.h"
|
||||
#include "themes.h"
|
||||
|
||||
#include "screen.h"
|
||||
#include "gui-entry.h"
|
||||
@ -82,6 +84,8 @@ static void textui_init(void)
|
||||
irc_init();
|
||||
fe_common_core_init();
|
||||
fe_common_irc_init();
|
||||
|
||||
theme_register(gui_text_formats);
|
||||
signal_add("gui exit", (SIGNAL_FUNC) sig_exit);
|
||||
}
|
||||
|
||||
@ -91,11 +95,11 @@ static void textui_finish_init(void)
|
||||
|
||||
screen_refresh_freeze();
|
||||
gui_entry_init();
|
||||
mainwindows_init();
|
||||
gui_printtext_init();
|
||||
gui_readline_init();
|
||||
gui_special_vars_init();
|
||||
gui_textwidget_init();
|
||||
mainwindows_init();
|
||||
gui_windows_init();
|
||||
statusbar_init();
|
||||
|
||||
@ -123,11 +127,13 @@ static void textui_deinit(void)
|
||||
statusbar_deinit();
|
||||
gui_printtext_deinit();
|
||||
gui_readline_deinit();
|
||||
mainwindows_deinit();
|
||||
gui_windows_deinit();
|
||||
mainwindows_deinit();
|
||||
gui_entry_deinit();
|
||||
deinit_screen();
|
||||
|
||||
theme_unregister();
|
||||
|
||||
fe_common_irc_deinit();
|
||||
fe_common_core_deinit();
|
||||
irc_deinit();
|
||||
|
@ -347,6 +347,17 @@ static void mainwindows_resize_bigger(int ychange, int xchange)
|
||||
g_slist_free(sorted);
|
||||
}
|
||||
|
||||
void mainwindows_resize_horiz(int xchange)
|
||||
{
|
||||
GSList *tmp;
|
||||
|
||||
for (tmp = mainwindows; tmp != NULL; tmp = tmp->next) {
|
||||
MAIN_WINDOW_REC *rec = tmp->data;
|
||||
|
||||
mainwindow_resize(rec, 0, xchange);
|
||||
}
|
||||
}
|
||||
|
||||
void mainwindows_resize(int ychange, int xchange)
|
||||
{
|
||||
screen_refresh_freeze();
|
||||
@ -354,6 +365,8 @@ void mainwindows_resize(int ychange, int xchange)
|
||||
mainwindows_resize_smaller(ychange, xchange);
|
||||
else if (ychange > 0)
|
||||
mainwindows_resize_bigger(ychange, xchange);
|
||||
else if (xchange != 0)
|
||||
mainwindows_resize_horiz(xchange);
|
||||
|
||||
irssi_redraw();
|
||||
screen_refresh_thaw();
|
||||
@ -595,6 +608,9 @@ void mainwindows_init(void)
|
||||
|
||||
void mainwindows_deinit(void)
|
||||
{
|
||||
while (mainwindows != NULL)
|
||||
mainwindow_destroy(mainwindows->data);
|
||||
|
||||
command_unbind("window grow", (SIGNAL_FUNC) cmd_window_grow);
|
||||
command_unbind("window shrink", (SIGNAL_FUNC) cmd_window_shrink);
|
||||
command_unbind("window size", (SIGNAL_FUNC) cmd_window_size);
|
||||
|
@ -29,5 +29,7 @@ FORMAT_REC gui_text_formats[] =
|
||||
{ "lastlog_end", "%_End of Lastlog", 0 },
|
||||
|
||||
{ "window_too_small", "Not enough room to resize this window", 0 },
|
||||
{ "cant_hide_last", "You can't hide the last window", 0 }
|
||||
{ "cant_hide_last", "You can't hide the last window", 0 },
|
||||
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
@ -11,6 +11,3 @@ enum {
|
||||
};
|
||||
|
||||
extern FORMAT_REC gui_text_formats[];
|
||||
#define MODULE_FORMATS gui_text_formats
|
||||
|
||||
#include "printformat.h"
|
||||
|
@ -12,6 +12,7 @@ libirc_core_la_SOURCES = \
|
||||
channels-query.c \
|
||||
channels-setup.c \
|
||||
channel-events.c \
|
||||
channel-rejoin.c \
|
||||
ignore.c \
|
||||
irc.c \
|
||||
irc-core.c \
|
||||
|
@ -54,7 +54,7 @@ static void event_target_unavailable(const char *data, IRC_SERVER_REC *server)
|
||||
|
||||
params = event_get_params(data, 2, NULL, &channel);
|
||||
if (ischannel(*channel)) {
|
||||
/* channel is unavailable. */
|
||||
/* channel is unavailable - try to join again a bit later */
|
||||
event_cannot_join(data, server);
|
||||
}
|
||||
|
||||
|
104
src/irc/core/channel-rejoin.c
Normal file
104
src/irc/core/channel-rejoin.c
Normal 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);
|
||||
}
|
@ -38,6 +38,9 @@ void channels_query_deinit(void);
|
||||
void channel_events_init(void);
|
||||
void channel_events_deinit(void);
|
||||
|
||||
void channel_rejoin_init(void);
|
||||
void channel_rejoin_deinit(void);
|
||||
|
||||
void massjoin_init(void);
|
||||
void massjoin_deinit(void);
|
||||
|
||||
@ -159,7 +162,7 @@ void channels_join(IRC_SERVER_REC *server, const char *data, int automatic)
|
||||
SETUP_CHANNEL_REC *schannel;
|
||||
CHANNEL_REC *chanrec;
|
||||
GString *outchans, *outkeys;
|
||||
char *params, *channels, *keys;
|
||||
char *params, *channels, *keys, *key;
|
||||
char **chanlist, **keylist, **tmp, **tmpkey, *channel;
|
||||
int use_keys;
|
||||
|
||||
@ -187,15 +190,17 @@ void channels_join(IRC_SERVER_REC *server, const char *data, int automatic)
|
||||
schannel = channels_setup_find(channel, server->connrec->ircnet);
|
||||
|
||||
g_string_sprintfa(outchans, "%s,", channel);
|
||||
if (schannel == NULL || schannel->password == NULL)
|
||||
g_string_sprintfa(outkeys, "%s,", get_join_key(*tmpkey));
|
||||
else {
|
||||
if (schannel == NULL || schannel->password == NULL) {
|
||||
key = *tmpkey == NULL || **tmpkey == '\0' ? NULL : *tmpkey;
|
||||
} else {
|
||||
/* get password from setup record */
|
||||
use_keys = TRUE;
|
||||
g_string_sprintfa(outkeys, "%s,", schannel->password);
|
||||
key = schannel->password;
|
||||
}
|
||||
|
||||
channel_create(server, channel + (channel[0] == '!' && channel[1] == '!'), automatic);
|
||||
g_string_sprintfa(outkeys, "%s,", get_join_key(key));
|
||||
chanrec = channel_create(server, channel + (channel[0] == '!' && channel[1] == '!'), automatic);
|
||||
if (key != NULL) chanrec->key = g_strdup(key);
|
||||
}
|
||||
g_free(channel);
|
||||
|
||||
@ -204,6 +209,8 @@ void channels_join(IRC_SERVER_REC *server, const char *data, int automatic)
|
||||
}
|
||||
|
||||
if (outchans->len > 0) {
|
||||
g_string_truncate(outchans, outchans->len-1);
|
||||
g_string_truncate(outkeys, outkeys->len-1);
|
||||
irc_send_cmdv(server, use_keys ? "JOIN %s %s" : "JOIN %s",
|
||||
outchans->str, outkeys->str);
|
||||
}
|
||||
@ -220,6 +227,7 @@ void channels_join(IRC_SERVER_REC *server, const char *data, int automatic)
|
||||
void channels_init(void)
|
||||
{
|
||||
channel_events_init();
|
||||
channel_rejoin_init();
|
||||
channels_query_init();
|
||||
channels_setup_init();
|
||||
|
||||
@ -233,6 +241,7 @@ void channels_init(void)
|
||||
void channels_deinit(void)
|
||||
{
|
||||
channel_events_deinit();
|
||||
channel_rejoin_deinit();
|
||||
channels_query_deinit();
|
||||
channels_setup_deinit();
|
||||
|
||||
|
@ -26,20 +26,6 @@
|
||||
|
||||
#include "irc-server.h"
|
||||
|
||||
static void sig_log(SERVER_REC *server, const char *channel, gpointer level, const char *str)
|
||||
{
|
||||
int loglevel;
|
||||
|
||||
g_return_if_fail(str != NULL);
|
||||
|
||||
loglevel = GPOINTER_TO_INT(level);
|
||||
if (loglevel == MSGLEVEL_NEVER || logs == NULL) return;
|
||||
|
||||
/* Check if line should be saved in logs */
|
||||
log_write(channel, loglevel, str);
|
||||
}
|
||||
|
||||
|
||||
static void event_away(const char *data, IRC_SERVER_REC *server)
|
||||
{
|
||||
const char *fname, *levelstr;
|
||||
@ -93,14 +79,12 @@ void irc_log_init(void)
|
||||
settings_add_str("log", "awaylog_file", "~/.irssi/away.log");
|
||||
settings_add_str("log", "awaylog_level", "msgs hilight");
|
||||
|
||||
signal_add("print text stripped", (SIGNAL_FUNC) sig_log);
|
||||
signal_add("event 306", (SIGNAL_FUNC) event_away);
|
||||
signal_add("event 305", (SIGNAL_FUNC) event_unaway);
|
||||
}
|
||||
|
||||
void irc_log_deinit(void)
|
||||
{
|
||||
signal_remove("print text stripped", (SIGNAL_FUNC) sig_log);
|
||||
signal_remove("event 306", (SIGNAL_FUNC) event_away);
|
||||
signal_remove("event 305", (SIGNAL_FUNC) event_unaway);
|
||||
}
|
||||
|
@ -129,6 +129,9 @@ typedef struct {
|
||||
GSList *channels;
|
||||
GSList *queries;
|
||||
|
||||
GSList *rejoin_channels; /* try to join to these channels after a while -
|
||||
channels go here if they're "temporarily unavailable"
|
||||
because of netsplits */
|
||||
gpointer chanqueries;
|
||||
} IRC_SERVER_REC;
|
||||
|
||||
|
@ -293,7 +293,7 @@ static void setupserver_destroy(SETUP_SERVER_REC *rec)
|
||||
g_free_not_null(rec->own_ip);
|
||||
g_free(rec->ircnet);
|
||||
g_free(rec->address);
|
||||
g_free(rec->password);
|
||||
g_free_not_null(rec->password);
|
||||
g_free(rec);
|
||||
}
|
||||
|
||||
|
@ -308,12 +308,12 @@ static void cmd_dcc_chat(gchar *data, IRC_SERVER_REC *server)
|
||||
cmd_return_error(CMDERR_NOT_CONNECTED);
|
||||
|
||||
if (net_getsockname(server->handle, &addr, NULL) == -1)
|
||||
cmd_return_error(CMDERR_GETSOCKNAME);
|
||||
cmd_return_error(CMDERR_ERRNO);
|
||||
|
||||
port = settings_get_int("dcc_port");
|
||||
handle = net_listen(&addr, &port);
|
||||
if (handle == -1)
|
||||
cmd_return_error(CMDERR_LISTEN);
|
||||
cmd_return_error(CMDERR_ERRNO);
|
||||
|
||||
dcc = dcc_create(DCC_TYPE_CHAT, handle, data, "chat", server, NULL);
|
||||
dcc->tagread = g_input_add(dcc->handle, G_INPUT_READ,
|
||||
|
@ -513,7 +513,7 @@ static void cmd_dcc_send(gchar *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
|
||||
if (net_getsockname(chat != NULL ? chat->handle : server->handle, &addr, NULL) == -1)
|
||||
{
|
||||
close(fh);
|
||||
cmd_param_error(CMDERR_GETSOCKNAME);
|
||||
cmd_param_error(CMDERR_ERRNO);
|
||||
}
|
||||
|
||||
/* start listening */
|
||||
@ -522,7 +522,7 @@ static void cmd_dcc_send(gchar *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
|
||||
if (h == -1)
|
||||
{
|
||||
close(fh);
|
||||
cmd_param_error(CMDERR_LISTEN);
|
||||
cmd_param_error(CMDERR_ERRNO);
|
||||
}
|
||||
|
||||
/* skip path */
|
||||
|
@ -143,6 +143,9 @@ static void signal_destroy_hash(void *key, GSList *list)
|
||||
while (list != NULL) {
|
||||
PERL_SIGNAL_REC *rec = list->data;
|
||||
|
||||
if (strncmp(rec->signal, "command ", 8) == 0)
|
||||
command_unbind(rec->signal+8, NULL);
|
||||
|
||||
list = g_slist_remove(list, rec);
|
||||
|
||||
g_free(rec->signal);
|
||||
|
Loading…
x
Reference in New Issue
Block a user