1
0
mirror of https://github.com/irssi/irssi.git synced 2024-12-04 14:46:39 -05:00

Configurable statusbar - see default config file (irssi.conf) for example

how to configure it. Added %> format which clears to end of line using the
current bg color. Added support for multiple input lines (just the core, not
used anywhere yet).


git-svn-id: http://svn.irssi.org/repos/irssi/trunk@1821 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
Timo Sirainen 2001-10-13 16:11:13 +00:00 committed by cras
parent b32a9a9585
commit dbe49236d2
20 changed files with 1682 additions and 1157 deletions

View File

@ -144,6 +144,11 @@ int format_expand_styles(GString *out, const char **format, int *flags)
g_string_append_c(out, 4);
g_string_append_c(out, FORMAT_STYLE_DEFAULTS);
break;
case '>':
/* clear to end of line */
g_string_append_c(out, 4);
g_string_append_c(out, FORMAT_STYLE_CLRTOEOL);
break;
case '[':
/* code */
format_expand_code(format, flags);
@ -882,16 +887,19 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text)
/* bell */
if (settings_get_bool("bell_beeps"))
signal_emit("beep", 0);
} else if (type == 4 && *ptr == FORMAT_STYLE_CLRTOEOL) {
/* clear to end of line */
flags |= GUI_PRINT_FLAG_CLRTOEOL;
}
if (*str != '\0') {
if (*str != '\0' || (flags & GUI_PRINT_FLAG_CLRTOEOL)) {
/* send the text to gui handler */
signal_emit_id(signal_gui_print_text, 6, dest->window,
GINT_TO_POINTER(fgcolor),
GINT_TO_POINTER(bgcolor),
GINT_TO_POINTER(flags), str,
dest->level);
flags &= ~GUI_PRINT_FLAG_INDENT;
flags &= ~(GUI_PRINT_FLAG_INDENT|GUI_PRINT_FLAG_CLRTOEOL);
}
if (type == '\n')
@ -938,6 +946,8 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text)
fgcolor = bgcolor = -1;
flags &= GUI_PRINT_FLAG_INDENT;
break;
case FORMAT_STYLE_CLRTOEOL:
break;
default:
if (*ptr != FORMAT_COLOR_NOCHANGE) {
fgcolor = (unsigned char) *ptr-'0';

View File

@ -11,6 +11,7 @@
#define GUI_PRINT_FLAG_MIRC_COLOR 0x10
#define GUI_PRINT_FLAG_INDENT 0x20
#define GUI_PRINT_FLAG_NEWLINE 0x40
#define GUI_PRINT_FLAG_CLRTOEOL 0x80
#define MAX_FORMAT_PARAMS 10
#define DEFAULT_FORMAT_ARGLIST_SIZE 200
@ -121,6 +122,7 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text);
#define FORMAT_STYLE_REVERSE (0x04 + FORMAT_STYLE_SPECIAL)
#define FORMAT_STYLE_INDENT (0x05 + FORMAT_STYLE_SPECIAL)
#define FORMAT_STYLE_DEFAULTS (0x06 + FORMAT_STYLE_SPECIAL)
#define FORMAT_STYLE_CLRTOEOL (0x07 + FORMAT_STYLE_SPECIAL)
int format_expand_styles(GString *out, const char **format, int *flags);
void formats_init(void);

View File

@ -35,6 +35,7 @@ irssi_SOURCES = \
mainwindows-layout.c \
screen.c \
statusbar.c \
statusbar-config.c \
statusbar-items.c \
textbuffer.c \
textbuffer-commands.c \
@ -49,8 +50,10 @@ noinst_HEADERS = \
gui-readline.h \
gui-windows.h \
mainwindows.h \
statusbar.h \
screen.h \
statusbar.h \
statusbar-config.h \
statusbar-items.h \
textbuffer.h \
textbuffer-view.h \
textbuffer-reformat.h \

View File

@ -21,43 +21,65 @@
#include "module.h"
#include "formats.h"
#include "gui-entry.h"
#include "gui-printtext.h"
#include "screen.h"
static GString *entry;
static int promptlen, permanent_prompt, pos, scrstart, scrpos;
static int prompt_hidden;
static char *prompt;
GUI_ENTRY_REC *active_entry;
static void entry_screenpos(void)
GUI_ENTRY_REC *gui_entry_create(int xpos, int ypos, int width)
{
if (pos-scrstart < screen_width-2-promptlen && pos-scrstart > 0) {
scrpos = pos-scrstart;
return;
}
GUI_ENTRY_REC *rec;
if (pos < screen_width-1-promptlen) {
scrstart = 0;
scrpos = pos;
rec = g_new0(GUI_ENTRY_REC, 1);
rec->xpos = xpos;
rec->ypos = ypos;
rec->width = width;
rec->text = g_string_new(NULL);
return rec;
}
void gui_entry_destroy(GUI_ENTRY_REC *entry)
{
g_return_if_fail(entry != NULL);
g_free_not_null(entry->prompt);
g_string_free(entry->text, TRUE);
g_free(entry);
}
/* Fixes the cursor position in screen */
static void gui_entry_fix_cursor(GUI_ENTRY_REC *entry)
{
if (entry->pos - entry->scrstart < entry->width-2 - entry->promptlen &&
entry->pos - entry->scrstart > 0) {
entry->scrpos = entry->pos - entry->scrstart;
} else if (entry->pos < entry->width-1 - entry->promptlen) {
entry->scrstart = 0;
entry->scrpos = entry->pos;
} else {
scrpos = (screen_width-promptlen)*2/3;
scrstart = pos-scrpos;
entry->scrpos = (entry->width - entry->promptlen)*2/3;
entry->scrstart = entry->pos - entry->scrpos;
}
}
static void entry_update(void)
static void gui_entry_draw_from(GUI_ENTRY_REC *entry, int pos)
{
char *p;
int n, len;
int xpos, end_xpos;
len = entry->len-scrstart > screen_width-1-promptlen ?
screen_width-1-promptlen : entry->len-scrstart;
xpos = entry->xpos + entry->promptlen + pos;
end_xpos = entry->xpos + entry->width;
if (xpos > end_xpos)
return;
screen_set_color(screen_root, 0);
screen_move(screen_root, promptlen, screen_height-1);
screen_move(screen_root, xpos, entry->ypos);
for (p = entry->str+scrstart, n = 0; n < len; n++, p++) {
if (prompt_hidden)
p = entry->scrstart + pos >= entry->text->len ? "" :
entry->text->str + entry->scrstart + pos;
for (; *p != '\0' && xpos < end_xpos; p++, xpos++) {
if (entry->hidden)
screen_addch(screen_root, ' ');
else if ((unsigned char) *p >= 32)
screen_addch(screen_root, (unsigned char) *p);
@ -67,234 +89,299 @@ static void entry_update(void)
screen_set_color(screen_root, 0);
}
}
screen_clrtoeol(screen_root);
screen_move_cursor(scrpos+promptlen, screen_height-1);
/* clear the rest of the input line */
if (entry->xpos + entry->width == screen_width)
screen_clrtoeol(screen_root);
else {
while (xpos < end_xpos) {
screen_addch(screen_root, ' ');
xpos++;
}
}
screen_move_cursor(entry->xpos + entry->scrpos + entry->promptlen,
entry->ypos);
screen_refresh(NULL);
}
void gui_entry_set_prompt(const char *str)
static void gui_entry_draw(GUI_ENTRY_REC *entry)
{
if (str != NULL) {
if (permanent_prompt) return;
gui_entry_draw_from(entry, 0);
}
g_free_not_null(prompt);
prompt = g_strdup(str);
promptlen = format_get_length(prompt);
void gui_entry_move(GUI_ENTRY_REC *entry, int xpos, int ypos, int width)
{
int old_width;
g_return_if_fail(entry != NULL);
if (entry->xpos != xpos || entry->ypos != ypos) {
/* position in screen changed - needs a full redraw */
entry->xpos = xpos;
entry->ypos = ypos;
entry->width = width;
gui_entry_redraw(entry);
return;
}
if (prompt != NULL)
gui_printtext(0, screen_height-1, prompt);
if (entry->width == width)
return; /* no changes */
entry_screenpos();
entry_update();
if (width > entry->width) {
/* input line grew - need to draw text at the end */
old_width = width;
entry->width = width;
gui_entry_draw_from(entry, old_width);
} else {
/* input line shrinked - make sure the cursor
is inside the input line */
if (entry->pos - entry->scrstart >
entry->width-2 - entry->promptlen) {
gui_entry_fix_cursor(entry);
gui_entry_draw(entry);
}
}
}
void gui_entry_set_perm_prompt(const char *str)
void gui_entry_set_active(GUI_ENTRY_REC *entry)
{
active_entry = entry;
screen_move_cursor(entry->xpos + entry->scrpos + entry->promptlen,
entry->ypos);
screen_refresh(NULL);
}
void gui_entry_set_prompt(GUI_ENTRY_REC *entry, const char *str)
{
int oldlen;
g_return_if_fail(entry != NULL);
oldlen = entry->promptlen;
if (str != NULL) {
g_free_not_null(entry->prompt);
entry->prompt = g_strdup(str);
entry->promptlen = format_get_length(str);
}
if (entry->prompt != NULL)
gui_printtext(entry->xpos, entry->ypos, entry->prompt);
if (entry->promptlen != oldlen) {
gui_entry_fix_cursor(entry);
gui_entry_draw(entry);
}
}
void gui_entry_set_hidden(GUI_ENTRY_REC *entry, int hidden)
{
g_return_if_fail(entry != NULL);
entry->hidden = hidden;
}
void gui_entry_set_text(GUI_ENTRY_REC *entry, const char *str)
{
g_return_if_fail(entry != NULL);
g_return_if_fail(str != NULL);
g_free_not_null(prompt);
prompt = g_strdup(str);
promptlen = format_get_length(prompt);
g_string_assign(entry->text, str);
entry->pos = entry->text->len;
permanent_prompt = TRUE;
gui_entry_set_prompt(NULL);
gui_entry_fix_cursor(entry);
gui_entry_draw(entry);
}
void gui_entry_set_hidden(int hidden)
char *gui_entry_get_text(GUI_ENTRY_REC *entry)
{
prompt_hidden = hidden;
g_return_val_if_fail(entry != NULL, NULL);
return entry->text->str;
}
void gui_entry_remove_perm_prompt(void)
{
permanent_prompt = FALSE;
}
void gui_entry_set_text(const char *str)
void gui_entry_insert_text(GUI_ENTRY_REC *entry, const char *str)
{
g_return_if_fail(entry != NULL);
g_return_if_fail(str != NULL);
g_string_assign(entry, str);
pos = entry->len;
g_string_insert(entry->text, entry->pos, str);
entry->pos += strlen(str);
entry_screenpos();
entry_update();
gui_entry_fix_cursor(entry);
gui_entry_draw(entry);
}
char *gui_entry_get_text(void)
void gui_entry_insert_char(GUI_ENTRY_REC *entry, char chr)
{
return entry->str;
g_return_if_fail(entry != NULL);
if (chr == 0)
return; /* never insert NUL characters */
g_string_insert_c(entry->text, entry->pos, chr);
entry->pos++;
gui_entry_fix_cursor(entry);
gui_entry_draw(entry);
}
void gui_entry_insert_text(const char *str)
void gui_entry_erase(GUI_ENTRY_REC *entry, int size)
{
g_return_if_fail(str != NULL);
g_return_if_fail(entry != NULL);
g_string_insert(entry, pos, str);
pos += strlen(str);
entry_screenpos();
entry_update();
}
void gui_entry_insert_char(char chr)
{
if (chr == 0) return; /* never insert NUL characters */
g_string_insert_c(entry, pos, chr);
pos++;
entry_screenpos();
entry_update();
}
void gui_entry_erase(int size)
{
if (pos < size) return;
if (entry->pos < size)
return;
#ifdef WANT_BIG5
if (is_big5(entry->str[pos-2], entry->str[pos-1]))
if (is_big5(entry->text->str[entry->pos-2],
entry->text->str[entry->pos-1]))
size++;
#endif
pos -= size;
g_string_erase(entry, pos, size);
entry->pos -= size;
g_string_erase(entry->text, entry->pos, size);
entry_screenpos();
entry_update();
gui_entry_fix_cursor(entry);
gui_entry_draw(entry);
}
void gui_entry_erase_word(void)
void gui_entry_erase_word(GUI_ENTRY_REC *entry)
{
int to;
if (pos == 0) return;
to = pos - 1;
g_return_if_fail(entry != NULL);
if (entry->pos == 0)
return;
while (entry->str[to] == ' ' && to > 0)
to = entry->pos - 1;
while (entry->text->str[to] == ' ' && to > 0)
to--;
while (entry->str[to] != ' ' && to > 0)
while (entry->text->str[to] != ' ' && to > 0)
to--;
if (entry->str[to] == ' ' && to > 0)
if (entry->text->str[to] == ' ' && to > 0)
to++;
g_string_erase(entry, to, pos - to);
pos = to;
g_string_erase(entry->text, to, entry->pos - to);
entry->pos = to;
entry_screenpos();
entry_update();
gui_entry_fix_cursor(entry);
gui_entry_draw(entry);
}
void gui_entry_erase_next_word(void)
void gui_entry_erase_next_word(GUI_ENTRY_REC *entry)
{
int to = pos;
if (pos == entry->len) return;
int to;
while (entry->str[to] == ' ' && to < entry->len)
g_return_if_fail(entry != NULL);
if (entry->pos == entry->text->len)
return;
to = entry->pos;
while (entry->text->str[to] == ' ' && to < entry->text->len)
to++;
while (entry->str[to] != ' ' && to < entry->len)
while (entry->text->str[to] != ' ' && to < entry->text->len)
to++;
g_string_erase(entry, pos, to - pos);
g_string_erase(entry->text, entry->pos, to - entry->pos);
entry_screenpos();
entry_update();
gui_entry_fix_cursor(entry);
gui_entry_draw(entry);
}
int gui_entry_get_pos(void)
int gui_entry_get_pos(GUI_ENTRY_REC *entry)
{
return pos;
g_return_val_if_fail(entry != NULL, 0);
return entry->pos;
}
void gui_entry_set_pos(int p)
void gui_entry_set_pos(GUI_ENTRY_REC *entry, int pos)
{
if (p >= 0 && p <= entry->len)
pos = p;
g_return_if_fail(entry != NULL);
entry_screenpos();
entry_update();
if (pos >= 0 && pos <= entry->text->len)
entry->pos = pos;
gui_entry_fix_cursor(entry);
gui_entry_draw(entry);
}
void gui_entry_move_pos(int p)
void gui_entry_move_pos(GUI_ENTRY_REC *entry, int pos)
{
g_return_if_fail(entry != NULL);
#ifdef WANT_BIG5
if (p > 0 && is_big5 (entry->str[pos], entry->str[pos+1]))
p++;
else if (p < 0 && is_big5 (entry->str[pos-1], entry->str[pos]))
p--;
if (pos > 0 && is_big5(entry->text->str[entry->pos],
entry->text->str[entry->pos+1]))
pos++;
else if (pos < 0 && is_big5(entry->text->str[entry->pos-1],
entry->text->str[entry->pos]))
pos--;
#endif
if (pos+p >= 0 && pos+p <= entry->len)
pos += p;
if (entry->pos+pos >= 0 && entry->pos+pos <= entry->text->len)
entry->pos += pos;
entry_screenpos();
entry_update();
gui_entry_fix_cursor(entry);
gui_entry_draw(entry);
}
static void gui_entry_move_words_left(int count)
static void gui_entry_move_words_left(GUI_ENTRY_REC *entry, int count)
{
if (pos == 0) return;
int pos;
pos = entry->pos;
while (count > 0 && pos > 0) {
while (pos > 0 && entry->str[pos-1] == ' ')
while (pos > 0 && entry->text->str[pos-1] == ' ')
pos--;
while (pos > 0 && entry->str[pos-1] != ' ')
while (pos > 0 && entry->text->str[pos-1] != ' ')
pos--;
count--;
}
entry->pos = pos;
}
static void gui_entry_move_words_right(int count)
static void gui_entry_move_words_right(GUI_ENTRY_REC *entry, int count)
{
if (pos == entry->len) return;
int pos;
while (count > 0 && pos < entry->len) {
while (pos < entry->len && entry->str[pos] != ' ')
pos = entry->pos;
while (count > 0 && pos < entry->text->len) {
while (pos < entry->text->len && entry->text->str[pos] != ' ')
pos++;
while (pos < entry->len && entry->str[pos] == ' ')
while (pos < entry->text->len && entry->text->str[pos] == ' ')
pos++;
count--;
}
entry->pos = pos;
}
void gui_entry_move_words(int count)
void gui_entry_move_words(GUI_ENTRY_REC *entry, int count)
{
g_return_if_fail(entry != NULL);
if (count < 0)
gui_entry_move_words_left(-count);
gui_entry_move_words_left(entry, -count);
else if (count > 0)
gui_entry_move_words_right(count);
gui_entry_move_words_right(entry, count);
entry_screenpos();
entry_update();
gui_entry_fix_cursor(entry);
gui_entry_draw(entry);
}
void gui_entry_redraw(void)
void gui_entry_redraw(GUI_ENTRY_REC *entry)
{
gui_entry_set_prompt(NULL);
g_return_if_fail(entry != NULL);
entry_screenpos();
entry_update();
}
void gui_entry_init(void)
{
entry = g_string_new(NULL);
pos = scrpos = 0;
prompt = NULL; promptlen = 0;
permanent_prompt = FALSE;
prompt_hidden = FALSE;
}
void gui_entry_deinit(void)
{
if (prompt != NULL) g_free(prompt);
g_string_free(entry, TRUE);
gui_entry_set_prompt(entry, NULL);
gui_entry_fix_cursor(entry);
gui_entry_draw(entry);
}

View File

@ -1,31 +1,42 @@
#ifndef __GUI_ENTRY_H
#define __GUI_ENTRY_H
void gui_entry_set_prompt(const char *str);
typedef struct {
GString *text;
int xpos, ypos, width; /* entry position in screen */
int pos, scrstart, scrpos; /* cursor position */
int hidden; /* print the chars as spaces in input line (useful for passwords) */
/* permanent prompt can't be overwritten with gui_entry_set_prompt() */
void gui_entry_set_perm_prompt(const char *str);
void gui_entry_remove_perm_prompt(void);
void gui_entry_set_hidden(int hidden);
int promptlen;
char *prompt;
} GUI_ENTRY_REC;
void gui_entry_set_text(const char *str);
char *gui_entry_get_text(void);
extern GUI_ENTRY_REC *active_entry;
void gui_entry_insert_text(const char *str);
void gui_entry_insert_char(char chr);
GUI_ENTRY_REC *gui_entry_create(int xpos, int ypos, int width);
void gui_entry_destroy(GUI_ENTRY_REC *entry);
void gui_entry_move(GUI_ENTRY_REC *entry, int xpos, int ypos, int width);
void gui_entry_erase(int size);
void gui_entry_erase_word(void);
void gui_entry_erase_next_word(void);
void gui_entry_set_active(GUI_ENTRY_REC *entry);
int gui_entry_get_pos(void);
void gui_entry_set_pos(int pos);
void gui_entry_move_pos(int pos);
void gui_entry_move_words(int count);
void gui_entry_set_prompt(GUI_ENTRY_REC *entry, const char *str);
void gui_entry_set_hidden(GUI_ENTRY_REC *entry, int hidden);
void gui_entry_redraw(void);
void gui_entry_set_text(GUI_ENTRY_REC *entry, const char *str);
char *gui_entry_get_text(GUI_ENTRY_REC *entry);
void gui_entry_init(void);
void gui_entry_deinit(void);
void gui_entry_insert_text(GUI_ENTRY_REC *entry, const char *str);
void gui_entry_insert_char(GUI_ENTRY_REC *entry, char chr);
void gui_entry_erase(GUI_ENTRY_REC *entry, int size);
void gui_entry_erase_word(GUI_ENTRY_REC *entry);
void gui_entry_erase_next_word(GUI_ENTRY_REC *entry);
int gui_entry_get_pos(GUI_ENTRY_REC *entry);
void gui_entry_set_pos(GUI_ENTRY_REC *entry, int pos);
void gui_entry_move_pos(GUI_ENTRY_REC *entry, int pos);
void gui_entry_move_words(GUI_ENTRY_REC *entry, int count);
void gui_entry_redraw(GUI_ENTRY_REC *entry);
#endif

View File

@ -37,7 +37,7 @@ static char *expando_idletime(SERVER_REC *server, void *item, int *free_ret)
/* current contents of the input line */
static char *expando_inputline(SERVER_REC *server, void *item, int *free_ret)
{
return gui_entry_get_text();
return gui_entry_get_text(active_entry);
}
/* value of cutbuffer */

View File

@ -97,11 +97,8 @@ static void get_colors(int flags, int *fg, int *bg)
current_theme->default_real_color;
}
if (flags & GUI_PRINT_FLAG_REVERSE) {
int tmp;
tmp = *fg; *fg = *bg; *bg = tmp;
}
if (flags & GUI_PRINT_FLAG_REVERSE)
*fg |= ATTR_REVERSE;
if (*fg == 8) *fg |= ATTR_COLOR8;
if (flags & GUI_PRINT_FLAG_BOLD) {
@ -180,8 +177,13 @@ static void sig_gui_print_text(WINDOW_REC *window, void *fgcolor,
g_return_if_fail(next_xpos != -1);
screen_move(screen_root, next_xpos, next_ypos);
if (flags & GUI_PRINT_FLAG_CLRTOEOL) {
screen_set_bg(screen_root, fg | (bg << 4));
screen_clrtoeol(screen_root);
screen_set_bg(screen_root, 0);
}
screen_set_color(screen_root, fg | (bg << 4));
screen_addstr(screen_root, str);
screen_addstr(screen_root, str);
next_xpos += strlen(str);
return;
}

View File

@ -63,8 +63,7 @@ static void handle_key_redirect(int key)
if (func != NULL)
func(key, data, active_win->active_server, active_win->active);
gui_entry_remove_perm_prompt();
window_update_prompt();
gui_entry_set_prompt(active_entry, "");
}
static void handle_entry_redirect(const char *line)
@ -72,7 +71,7 @@ static void handle_entry_redirect(const char *line)
ENTRY_REDIRECT_ENTRY_FUNC func;
void *data;
gui_entry_set_hidden(FALSE);
gui_entry_set_hidden(active_entry, FALSE);
func = (ENTRY_REDIRECT_ENTRY_FUNC) redir->func;
data = redir->data;
@ -83,8 +82,7 @@ static void handle_entry_redirect(const char *line)
active_win->active);
}
gui_entry_remove_perm_prompt();
window_update_prompt();
gui_entry_set_prompt(active_entry, "");
}
static int get_scroll_count(void)
@ -141,7 +139,7 @@ void handle_key(int key)
if (!key_pressed(keyboard, str)) {
/* key wasn't used for anything, print it */
gui_entry_insert_char((char) key);
gui_entry_insert_char(active_entry, (char) key);
}
}
@ -150,7 +148,7 @@ static void key_send_line(void)
int add_history;
char *str;
str = gui_entry_get_text();
str = gui_entry_get_text(active_entry);
if (*str == '\0') return;
translate_output(str);
@ -167,10 +165,10 @@ static void key_send_line(void)
}
if (add_history) {
command_history_add(active_win, gui_entry_get_text(),
command_history_add(active_win, gui_entry_get_text(active_entry),
FALSE);
}
gui_entry_set_text("");
gui_entry_set_text(active_entry, "");
command_history_clear_pos(active_win);
}
@ -182,83 +180,83 @@ static void key_backward_history(void)
{
const char *text;
text = command_history_prev(active_win, gui_entry_get_text());
gui_entry_set_text(text);
text = command_history_prev(active_win, gui_entry_get_text(active_entry));
gui_entry_set_text(active_entry, text);
}
static void key_forward_history(void)
{
const char *text;
text = command_history_next(active_win, gui_entry_get_text());
gui_entry_set_text(text);
text = command_history_next(active_win, gui_entry_get_text(active_entry));
gui_entry_set_text(active_entry, text);
}
static void key_beginning_of_line(void)
{
gui_entry_set_pos(0);
gui_entry_set_pos(active_entry, 0);
}
static void key_end_of_line(void)
{
gui_entry_set_pos(strlen(gui_entry_get_text()));
gui_entry_set_pos(active_entry, strlen(gui_entry_get_text(active_entry)));
}
static void key_backward_character(void)
{
gui_entry_move_pos(-1);
gui_entry_move_pos(active_entry, -1);
}
static void key_forward_character(void)
{
gui_entry_move_pos(1);
gui_entry_move_pos(active_entry, 1);
}
static void key_backward_word(void)
{
gui_entry_move_words(-1);
gui_entry_move_words(active_entry, -1);
}
static void key_forward_word(void)
{
gui_entry_move_words(1);
gui_entry_move_words(active_entry, 1);
}
static void key_erase_line(void)
{
g_free_not_null(cutbuffer);
cutbuffer = g_strdup(gui_entry_get_text());
cutbuffer = g_strdup(gui_entry_get_text(active_entry));
gui_entry_set_text("");
gui_entry_set_text(active_entry, "");
}
static void key_erase_to_beg_of_line(void)
{
int pos;
pos = gui_entry_get_pos();
pos = gui_entry_get_pos(active_entry);
g_free_not_null(cutbuffer);
cutbuffer = g_strndup(gui_entry_get_text(), pos);
cutbuffer = g_strndup(gui_entry_get_text(active_entry), pos);
gui_entry_erase(pos);
gui_entry_erase(active_entry, pos);
}
static void key_erase_to_end_of_line(void)
{
int pos;
pos = gui_entry_get_pos();
pos = gui_entry_get_pos(active_entry);
g_free_not_null(cutbuffer);
cutbuffer = g_strdup(gui_entry_get_text()+pos);
cutbuffer = g_strdup(gui_entry_get_text(active_entry)+pos);
gui_entry_set_pos(strlen(gui_entry_get_text()));
gui_entry_erase(strlen(gui_entry_get_text()) - pos);
gui_entry_set_pos(active_entry, strlen(gui_entry_get_text(active_entry)));
gui_entry_erase(active_entry, strlen(gui_entry_get_text(active_entry)) - pos);
}
static void key_yank_from_cutbuffer(void)
{
if (cutbuffer != NULL)
gui_entry_insert_text(cutbuffer);
gui_entry_insert_text(active_entry, cutbuffer);
}
static void key_transpose_characters(void)
@ -266,46 +264,46 @@ static void key_transpose_characters(void)
char *line, c;
int pos;
pos = gui_entry_get_pos();
line = gui_entry_get_text();
pos = gui_entry_get_pos(active_entry);
line = gui_entry_get_text(active_entry);
if (pos == 0 || strlen(line) < 2)
return;
if (line[pos] != '\0')
gui_entry_move_pos(1);
c = line[gui_entry_get_pos()-1];
gui_entry_erase(1);
gui_entry_move_pos(-1);
gui_entry_insert_char(c);
gui_entry_set_pos(pos);
gui_entry_move_pos(active_entry, 1);
c = line[gui_entry_get_pos(active_entry)-1];
gui_entry_erase(active_entry, 1);
gui_entry_move_pos(active_entry, -1);
gui_entry_insert_char(active_entry, c);
gui_entry_set_pos(active_entry, pos);
}
static void key_delete_character(void)
{
if (gui_entry_get_pos() < (int)strlen(gui_entry_get_text())) {
gui_entry_move_pos(1);
gui_entry_erase(1);
if (gui_entry_get_pos(active_entry) < (int)strlen(gui_entry_get_text(active_entry))) {
gui_entry_move_pos(active_entry, 1);
gui_entry_erase(active_entry, 1);
}
}
static void key_backspace(void)
{
gui_entry_erase(1);
gui_entry_erase(active_entry, 1);
}
static void key_delete_previous_word(void)
{
gui_entry_erase_word();
gui_entry_erase_word(active_entry);
}
static void key_delete_next_word(void)
{
gui_entry_erase_next_word();
gui_entry_erase_next_word(active_entry);
}
static void key_delete_to_previous_space(void)
{
gui_entry_erase_word();
gui_entry_erase_word(active_entry);
}
void readline(void)
@ -356,12 +354,12 @@ static void key_word_completion(void)
char *line;
int pos;
pos = gui_entry_get_pos();
pos = gui_entry_get_pos(active_entry);
line = word_complete(active_win, gui_entry_get_text(), &pos);
line = word_complete(active_win, gui_entry_get_text(active_entry), &pos);
if (line != NULL) {
gui_entry_set_text(line);
gui_entry_set_pos(pos);
gui_entry_set_text(active_entry, line);
gui_entry_set_pos(active_entry, pos);
g_free(line);
}
}
@ -371,12 +369,12 @@ static void key_check_replaces(void)
char *line;
int pos;
pos = gui_entry_get_pos();
pos = gui_entry_get_pos(active_entry);
line = auto_word_complete(gui_entry_get_text(), &pos);
line = auto_word_complete(gui_entry_get_text(active_entry), &pos);
if (line != NULL) {
gui_entry_set_text(line);
gui_entry_set_pos(pos);
gui_entry_set_text(active_entry, line);
gui_entry_set_pos(active_entry, pos);
g_free(line);
}
}
@ -464,14 +462,14 @@ static void key_insert_text(const char *data)
str = parse_special_string(data, active_win->active_server,
active_win->active, "", NULL, 0);
gui_entry_insert_text(str);
gui_entry_insert_text(active_entry, str);
g_free(str);
}
static void sig_window_auto_changed(void)
{
command_history_next(active_win, gui_entry_get_text());
gui_entry_set_text("");
command_history_next(active_win, gui_entry_get_text(active_entry));
gui_entry_set_text(active_entry, "");
}
static void sig_gui_entry_redirect(SIGNAL_FUNC func, const char *entry,
@ -483,8 +481,8 @@ static void sig_gui_entry_redirect(SIGNAL_FUNC func, const char *entry,
redir->data = data;
if (redir->flags & ENTRY_REDIRECT_FLAG_HIDDEN)
gui_entry_set_hidden(TRUE);
gui_entry_set_perm_prompt(entry);
gui_entry_set_hidden(active_entry, TRUE);
gui_entry_set_prompt(active_entry, entry);
}
void gui_readline_init(void)

View File

@ -31,15 +31,13 @@
static int window_create_override;
static char *prompt, *prompt_window;
static GUI_WINDOW_REC *gui_window_init(WINDOW_REC *window,
MAIN_WINDOW_REC *parent)
{
GUI_WINDOW_REC *gui;
window->width = parent->width;
window->height = parent->height;
window->height = MAIN_WINDOW_TEXT_HEIGHT(parent);
gui = g_new0(GUI_WINDOW_REC, 1);
gui->parent = parent;
@ -161,54 +159,6 @@ void gui_window_set_unsticky(WINDOW_REC *window)
}
}
void window_update_prompt(void)
{
const char *special;
char *prompt, *text;
int var_used;
special = settings_get_str(active_win->active != NULL ?
"prompt" : "prompt_window");
if (*special == '\0') {
gui_entry_set_prompt("");
return;
}
prompt = parse_special_string(special, active_win->active_server,
active_win->active, "", &var_used,
PARSE_FLAG_ISSET_ANY |
PARSE_FLAG_ESCAPE_VARS);
if (!var_used && strchr(special, '$') != NULL) {
/* none of the $vars had non-empty values, use empty prompt */
*prompt = '\0';
}
/* set prompt */
text = show_lowascii(prompt);
gui_entry_set_prompt(text);
g_free(text);
g_free(prompt);
}
static void window_update_prompt_server(SERVER_REC *server)
{
if (server == active_win->active_server)
window_update_prompt();
}
static void window_update_prompt_window(WINDOW_REC *window)
{
if (window == active_win)
window_update_prompt();
}
static void window_update_prompt_window_item(WI_ITEM_REC *item)
{
if (item == active_win->active)
window_update_prompt();
}
void gui_window_reparent(WINDOW_REC *window, MAIN_WINDOW_REC *parent)
{
MAIN_WINDOW_REC *oldparent;
@ -224,9 +174,12 @@ void gui_window_reparent(WINDOW_REC *window, MAIN_WINDOW_REC *parent)
if (parent->sticky_windows)
gui_window_set_sticky(window);
if (parent->height != oldparent->height ||
parent->width != oldparent->width)
gui_window_resize(window, parent->width, parent->height);
if (MAIN_WINDOW_TEXT_HEIGHT(parent) !=
MAIN_WINDOW_TEXT_HEIGHT(oldparent) ||
parent->width != oldparent->width) {
gui_window_resize(window, parent->width,
MAIN_WINDOW_TEXT_HEIGHT(parent));
}
}
static MAIN_WINDOW_REC *mainwindow_find_unsticky(void)
@ -282,36 +235,12 @@ static void signal_window_changed(WINDOW_REC *window)
textbuffer_view_set_window(WINDOW_GUI(window)->view,
parent->screen_win);
window_update_prompt();
}
static void sig_check_window_update(WINDOW_REC *window)
{
if (window == active_win)
window_update_prompt();
}
static void read_settings(void)
{
GSList *tmp;
SIGNAL_FUNC funcs[] = {
(SIGNAL_FUNC) window_update_prompt,
(SIGNAL_FUNC) window_update_prompt_server,
(SIGNAL_FUNC) window_update_prompt_window,
(SIGNAL_FUNC) window_update_prompt_window_item
};
if (prompt != NULL) {
special_vars_remove_signals(prompt, 4, funcs);
special_vars_remove_signals(prompt_window, 4, funcs);
g_free(prompt);
g_free(prompt_window);
}
prompt = g_strdup(settings_get_str("prompt"));
prompt_window = g_strdup(settings_get_str("prompt_window"));
for (tmp = windows; tmp != NULL; tmp = tmp->next) {
WINDOW_REC *rec = tmp->data;
GUI_WINDOW_REC *gui = WINDOW_GUI(rec);
@ -324,11 +253,6 @@ static void read_settings(void)
gui->use_scroll ? gui->scroll :
settings_get_bool("scroll"));
}
special_vars_add_signals(prompt, 4, funcs);
special_vars_add_signals(prompt_window, 4, funcs);
if (active_win != NULL) window_update_prompt();
}
void gui_windows_init(void)
@ -336,11 +260,8 @@ void gui_windows_init(void)
settings_add_bool("lookandfeel", "autostick_split_windows", TRUE);
settings_add_int("lookandfeel", "indent", 10);
settings_add_bool("lookandfeel", "indent_always", FALSE);
settings_add_str("lookandfeel", "prompt", "[$[.15]T] ");
settings_add_str("lookandfeel", "prompt_window", "[$winname] ");
settings_add_bool("lookandfeel", "scroll", TRUE);
prompt = NULL; prompt_window = NULL;
window_create_override = -1;
read_settings();
@ -348,15 +269,11 @@ void gui_windows_init(void)
signal_add("window created", (SIGNAL_FUNC) gui_window_created);
signal_add("window destroyed", (SIGNAL_FUNC) gui_window_destroyed);
signal_add_first("window changed", (SIGNAL_FUNC) signal_window_changed);
signal_add("window item remove", (SIGNAL_FUNC) sig_check_window_update);
signal_add("setup changed", (SIGNAL_FUNC) read_settings);
}
void gui_windows_deinit(void)
{
g_free_not_null(prompt);
g_free_not_null(prompt_window);
while (windows != NULL)
window_destroy(windows->data);
@ -364,6 +281,5 @@ void gui_windows_deinit(void)
signal_remove("window created", (SIGNAL_FUNC) gui_window_created);
signal_remove("window destroyed", (SIGNAL_FUNC) gui_window_destroyed);
signal_remove("window changed", (SIGNAL_FUNC) signal_window_changed);
signal_remove("window item remove", (SIGNAL_FUNC) sig_check_window_update);
signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
}

View File

@ -39,6 +39,4 @@ void gui_window_scroll_line(WINDOW_REC *window, LINE_REC *line);
void gui_window_set_sticky(WINDOW_REC *window);
void gui_window_set_unsticky(WINDOW_REC *window);
void window_update_prompt(void);
#endif

View File

@ -98,8 +98,6 @@ void irssi_redraw(void)
mainwindows_redraw();
/* statusbar */
statusbar_redraw(NULL);
/* entry line */
gui_entry_redraw();
}
static void textui_init(void)
@ -123,7 +121,6 @@ static void textui_finish_init(void)
textbuffer_view_init();
textbuffer_commands_init();
textbuffer_reformat_init();
gui_entry_init();
gui_expandos_init();
gui_printtext_init();
gui_readline_init();
@ -173,7 +170,6 @@ static void textui_deinit(void)
mainwindow_activity_deinit();
mainwindows_deinit();
gui_expandos_deinit();
gui_entry_deinit();
textbuffer_reformat_deinit();
textbuffer_commands_deinit();
textbuffer_view_deinit();

View File

@ -28,7 +28,6 @@
#include "printtext.h"
#include "screen.h"
#include "statusbar.h"
#include "gui-windows.h"
#define NEW_WINDOW_SIZE (WINDOW_MIN_SIZE + 1)
@ -36,12 +35,21 @@
GSList *mainwindows;
MAIN_WINDOW_REC *active_mainwin;
static int reserved_up, reserved_down;
static int reserved_top, reserved_bottom;
static int old_screen_width, old_screen_height;
#define mainwindow_create_screen(window) \
screen_window_create(0, (window)->first_line, \
(window)->width, (window)->height)
screen_window_create(0, \
(window)->first_line + (window)->statusbar_lines_top, \
(window)->width, \
(window)->height + (window)->statusbar_lines_bottom)
#define mainwindow_set_screen_size(window) \
screen_window_move((window)->screen_win, 0, \
(window)->first_line + (window)->statusbar_lines_top, \
(window)->width, \
(window)->height - (window)->statusbar_lines_bottom);
static MAIN_WINDOW_REC *find_window_with_room(void)
{
@ -67,13 +75,12 @@ static void mainwindow_resize(MAIN_WINDOW_REC *window, int xdiff, int ydiff)
{
GSList *tmp;
if (xdiff == 0 && ydiff == 0)
if (quitting || (xdiff == 0 && ydiff == 0))
return;
window->width += xdiff;
window->height = window->last_line-window->first_line+1;
screen_window_move(window->screen_win, 0, window->first_line,
window->width, window->height);
mainwindow_set_screen_size(window);
for (tmp = windows; tmp != NULL; tmp = tmp->next) {
WINDOW_REC *rec = tmp->data;
@ -161,14 +168,12 @@ MAIN_WINDOW_REC *mainwindow_create(void)
rec = g_new0(MAIN_WINDOW_REC, 1);
rec->width = screen_width;
rec->statusbar_lines = 1;
if (mainwindows == NULL) {
active_mainwin = rec;
rec->first_line = reserved_up;
rec->last_line = screen_height-1 -
reserved_down-rec->statusbar_lines;
rec->first_line = reserved_top;
rec->last_line = screen_height-1 - reserved_bottom;
rec->height = rec->last_line-rec->first_line+1;
} else {
parent = WINDOW_MAIN(active_win);
@ -177,11 +182,12 @@ MAIN_WINDOW_REC *mainwindow_create(void)
if (parent == NULL)
return NULL; /* not enough space */
space = (parent->height-parent->statusbar_lines)/2;
space = parent->height / 2;
rec->first_line = parent->first_line;
rec->last_line = rec->first_line + space-rec->statusbar_lines;
rec->last_line = rec->first_line + space;
rec->height = rec->last_line-rec->first_line+1;
parent->first_line = rec->last_line+1+rec->statusbar_lines;
parent->first_line = rec->last_line+1;
parent->height = parent->last_line-parent->first_line+1;
mainwindow_resize(parent, 0, -space-1);
@ -248,7 +254,7 @@ static void mainwindows_add_space(int first_line, int last_line)
rec = mainwindows_find_upper(first_line);
if (rec != NULL) {
rec->last_line = last_line-rec->statusbar_lines;
rec->last_line = last_line;
mainwindow_resize(rec, 0, size);
}
}
@ -278,10 +284,9 @@ void mainwindow_destroy(MAIN_WINDOW_REC *window)
if (!quitting && mainwindows != NULL) {
gui_windows_remove_parent(window);
mainwindows_add_space(window->first_line, window->last_line+window->statusbar_lines);
mainwindows_add_space(window->first_line, window->last_line);
mainwindows_redraw();
statusbar_redraw(NULL);
}
g_free(window);
@ -468,35 +473,68 @@ void mainwindows_resize(int width, int height)
irssi_redraw();
}
int mainwindows_reserve_lines(int count, int up)
int mainwindows_reserve_lines(int top, int bottom)
{
MAIN_WINDOW_REC *window;
int ret;
if (up) {
g_return_val_if_fail(count > 0 || reserved_up > count, -1);
ret = -1;
if (top != 0) {
g_return_val_if_fail(top > 0 || reserved_top > top, -1);
ret = reserved_up;
reserved_up += count;
ret = reserved_top;
reserved_top += top;
window = mainwindows_find_lower(-1);
if (window != NULL) window->first_line += count;
} else {
g_return_val_if_fail(count > 0 || reserved_down > count, -1);
ret = reserved_down;
reserved_down += count;
window = mainwindows_find_upper(screen_height);
if (window != NULL) window->last_line -= count;
if (window != NULL) {
window->first_line += top;
mainwindow_resize(window, 0, -top);
}
}
if (window != NULL)
mainwindow_resize(window, 0, -count);
if (bottom != 0) {
g_return_val_if_fail(bottom > 0 || reserved_bottom > bottom, -1);
ret = reserved_bottom;
reserved_bottom += bottom;
window = mainwindows_find_upper(screen_height);
if (window != NULL) {
window->last_line -= bottom;
mainwindow_resize(window, 0, -bottom);
}
}
return ret;
}
int mainwindow_set_statusbar_lines(MAIN_WINDOW_REC *window,
int top, int bottom)
{
int ret;
ret = -1;
if (top != 0) {
ret = window->statusbar_lines_top;
window->statusbar_lines_top += top;
window->statusbar_lines += top;
}
if (bottom != 0) {
ret = window->statusbar_lines_bottom;
window->statusbar_lines_bottom += bottom;
window->statusbar_lines += bottom;
}
if (top+bottom != 0) {
mainwindow_set_screen_size(window);
gui_window_resize(window->active, window->width,
MAIN_WINDOW_TEXT_HEIGHT(window));
}
return ret;
}
static void mainwindows_resize_two(MAIN_WINDOW_REC *grow_win,
MAIN_WINDOW_REC *shrink_win, int count)
{
@ -504,8 +542,6 @@ static void mainwindows_resize_two(MAIN_WINDOW_REC *grow_win,
mainwindow_resize(shrink_win, 0, -count);
gui_window_redraw(grow_win->active);
gui_window_redraw(shrink_win->active);
statusbar_redraw(grow_win->statusbar);
statusbar_redraw(shrink_win->statusbar);
}
static int mainwindow_grow(MAIN_WINDOW_REC *window, int count)
@ -620,33 +656,31 @@ static void cmd_window_balance(void)
windows = g_slist_length(mainwindows);
if (windows == 1) return;
avail_size = screen_height - reserved_up-reserved_down;
avail_size = screen_height - reserved_top-reserved_bottom;
unit_size = avail_size/windows;
bigger_units = avail_size%windows;
sorted = mainwindows_get_sorted(FALSE);
last_line = reserved_up;
last_line = reserved_top;
for (tmp = sorted; tmp != NULL; tmp = tmp->next) {
MAIN_WINDOW_REC *rec = tmp->data;
old_size = rec->height;
rec->first_line = last_line;
rec->last_line = rec->first_line + unit_size-1 -
rec->statusbar_lines;
rec->last_line = rec->first_line + unit_size-1;
rec->height = rec->last_line-rec->first_line+1;
if (bigger_units > 0) {
rec->last_line++;
bigger_units--;
}
last_line = rec->last_line+1 + rec->statusbar_lines;
last_line = rec->last_line+1;
mainwindow_resize(rec, 0, rec->height-old_size);
}
g_slist_free(sorted);
mainwindows_redraw();
statusbar_redraw(NULL);
}
/* SYNTAX: WINDOW HIDE [<number>|<name>] */
@ -954,10 +988,7 @@ void mainwindows_init(void)
mainwindows = NULL;
active_mainwin = NULL;
reserved_up = reserved_down = 0;
/* for entry line */
mainwindows_reserve_lines(1, FALSE);
reserved_top = reserved_bottom = 0;
command_bind("window grow", NULL, (SIGNAL_FUNC) cmd_window_grow);
command_bind("window shrink", NULL, (SIGNAL_FUNC) cmd_window_shrink);

View File

@ -6,18 +6,22 @@
#define WINDOW_MIN_SIZE 2
#define MAIN_WINDOW_TEXT_HEIGHT(window) \
((window)->height-(window)->statusbar_lines)
typedef struct {
WINDOW_REC *active;
SCREEN_WINDOW *screen_win;
int sticky_windows; /* number of sticky windows */
int first_line, last_line; /* first/last line used by this window (0..x), not including statusbar */
int width, height; /* width/height of the window, not including statusbar */
int first_line, last_line; /* first/last line used by this window (0..x) (includes statusbars) */
int width, height; /* width/height of the window (includes statusbars) */
int statusbar_lines; /* number of lines the statusbar takes below the window */
void *statusbar;
void *statusbar_window_item;
GSList *statusbars;
int statusbar_lines_top;
int statusbar_lines_bottom;
int statusbar_lines; /* top+bottom */
} MAIN_WINDOW_REC;
extern GSList *mainwindows;
@ -38,7 +42,10 @@ void mainwindows_resize(int width, int height);
void mainwindow_change_active(MAIN_WINDOW_REC *mainwin,
WINDOW_REC *skip_window);
int mainwindows_reserve_lines(int count, int up);
int mainwindows_reserve_lines(int top, int bottom);
int mainwindow_set_statusbar_lines(MAIN_WINDOW_REC *window,
int top, int bottom);
GSList *mainwindows_get_sorted(int reverse);
#endif

View File

@ -52,7 +52,9 @@
#define MIN_SCREEN_WIDTH 20
struct _SCREEN_WINDOW {
WINDOW *win;
int x, y;
int width, height;
WINDOW *win;
};
SCREEN_WINDOW *screen_root;
@ -255,13 +257,15 @@ void screen_clear(void)
SCREEN_WINDOW *screen_window_create(int x, int y, int width, int height)
{
SCREEN_WINDOW *scrwin;
SCREEN_WINDOW *window;
scrwin = g_new0(SCREEN_WINDOW, 1);
scrwin->win = newwin(height, width, y, x);
idlok(scrwin->win, 1);
window = g_new0(SCREEN_WINDOW, 1);
window->x = x; window->y = y;
window->width = width; window->height = height;
window->win = newwin(height, width, y, x);
idlok(window->win, 1);
return scrwin;
return window;
}
void screen_window_destroy(SCREEN_WINDOW *window)
@ -279,13 +283,20 @@ void screen_window_move(SCREEN_WINDOW *window, int x, int y,
int width, int height)
{
#ifdef HAVE_CURSES_WRESIZE
wresize(window->win, height, width);
mvwin(window->win, y, x);
if (window->width != width || window->height != height)
wresize(window->win, height, width);
if (window->x != x || window->y != y)
mvwin(window->win, y, x);
#else
delwin(window->win);
window->win = newwin(height, width, y, x);
idlok(window->win, 1);
if (window->width != width || window->height != height ||
window->x != x || window->y != y) {
delwin(window->win);
window->win = newwin(height, width, y, x);
idlok(window->win, 1);
}
#endif
window->x = x; window->y = y;
window->width = width; window->height = height;
}
void screen_window_scroll(SCREEN_WINDOW *window, int count)
@ -295,44 +306,35 @@ void screen_window_scroll(SCREEN_WINDOW *window, int count)
scrollok(window->win, FALSE);
}
void screen_set_color(SCREEN_WINDOW *window, int col)
static int get_attr(int color)
{
int attr;
if (!use_colors)
attr = (col & 0x70) ? A_REVERSE : 0;
else if (col & ATTR_COLOR8)
attr = (color & 0x70) ? A_REVERSE : 0;
else if (color & ATTR_COLOR8)
attr = (A_DIM | COLOR_PAIR(63));
else if ((col & 0x77) == 0)
else if ((color & 0x77) == 0)
attr = A_NORMAL;
else
attr = (COLOR_PAIR((col&7) + (col&0x70)/2));
attr = (COLOR_PAIR((color&7) + (color&0x70)/2));
if (col & 0x08) attr |= A_BOLD;
if (col & 0x80) attr |= A_BLINK;
if (color & 0x08) attr |= A_BOLD;
if (color & 0x80) attr |= A_BLINK;
if (col & ATTR_UNDERLINE) attr |= A_UNDERLINE;
if (col & ATTR_REVERSE) attr |= A_REVERSE;
wattrset(window->win, attr);
if (color & ATTR_UNDERLINE) attr |= A_UNDERLINE;
if (color & ATTR_REVERSE) attr |= A_REVERSE;
return attr;
}
void screen_set_bg(SCREEN_WINDOW *window, int col)
void screen_set_color(SCREEN_WINDOW *window, int color)
{
int attr;
wattrset(window->win, get_attr(color));
}
if (!use_colors)
attr = (col & 0x70) ? A_REVERSE : 0;
else {
attr = (col == 8) ?
(A_DIM | COLOR_PAIR(63)) :
(COLOR_PAIR((col&7) + (col&0x70)/2));
}
if (col & 0x08) attr |= A_BOLD;
if (col & 0x80) attr |= A_BLINK;
wbkgdset(window->win, ' ' | attr);
void screen_set_bg(SCREEN_WINDOW *window, int color)
{
wbkgdset(window->win, ' ' | get_attr(color));
}
void screen_move(SCREEN_WINDOW *window, int x, int y)

View File

@ -0,0 +1,263 @@
/*
statusbar-config.c : irssi
Copyright (C) 2001 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 "settings.h"
#include "lib-config/iconfig.h"
#include "statusbar.h"
static void read_statusbar_config_from_node(CONFIG_NODE *node);
static STATUSBAR_CONFIG_REC *
statusbar_config_create(STATUSBAR_GROUP_REC *group, const char *name)
{
STATUSBAR_CONFIG_REC *bar;
g_return_val_if_fail(group != NULL, NULL);
g_return_val_if_fail(name != NULL, NULL);
bar = g_new0(STATUSBAR_CONFIG_REC, 1);
group->config_bars = g_slist_append(group->config_bars, bar);
bar->name = g_strdup(name);
return bar;
}
static SBAR_ITEM_CONFIG_REC *
statusbar_item_config_create(STATUSBAR_CONFIG_REC *bar, const char *name,
int priority, int right_alignment)
{
SBAR_ITEM_CONFIG_REC *rec;
g_return_val_if_fail(bar != NULL, NULL);
g_return_val_if_fail(name != NULL, NULL);
rec = g_new0(SBAR_ITEM_CONFIG_REC, 1);
bar->items = g_slist_append(bar->items, rec);
rec->name = g_strdup(name);
rec->priority = priority;
rec->right_alignment = right_alignment;
return rec;
}
static void statusbar_config_item_destroy(STATUSBAR_CONFIG_REC *barconfig,
SBAR_ITEM_CONFIG_REC *itemconfig)
{
barconfig->items = g_slist_remove(barconfig->items, itemconfig);
g_free(itemconfig->name);
g_free(itemconfig);
}
void statusbar_config_destroy(STATUSBAR_GROUP_REC *group,
STATUSBAR_CONFIG_REC *config)
{
group->config_bars = g_slist_remove(group->config_bars, config);
while (config->items != NULL)
statusbar_config_item_destroy(config, config->items->data);
g_free(config->name);
g_free(config);
}
static STATUSBAR_CONFIG_REC *
statusbar_config_find(STATUSBAR_GROUP_REC *group, const char *name)
{
GSList *tmp;
for (tmp = group->config_bars; tmp != NULL; tmp = tmp->next) {
STATUSBAR_CONFIG_REC *config = tmp->data;
if (strcmp(config->name, name) == 0)
return config;
}
return NULL;
}
static void statusbar_reset_defaults(void)
{
CONFIG_REC *config;
CONFIG_NODE *node;
while (statusbar_groups != NULL)
statusbar_group_destroy(statusbar_groups->data);
active_statusbar_group = NULL;
/* read the default statusbar settings from internal config */
config = config_open(NULL, -1);
config_parse_data(config, default_config, "internal");
node = config_node_traverse(config, "statusbar", FALSE);
if (node != NULL)
read_statusbar_config_from_node(node);
config_close(config);
}
static void statusbar_read_items(CONFIG_NODE *items)
{
GSList *tmp;
tmp = config_node_first(items->value);
for (; tmp != NULL; tmp = config_node_next(tmp)) {
CONFIG_NODE *node = tmp->data;
statusbar_item_register(node->key, node->value, NULL);
}
}
static void statusbar_read_item(STATUSBAR_CONFIG_REC *bar, CONFIG_NODE *node)
{
int priority, right_alignment;
priority = config_node_get_int(node, "priority", 0);
right_alignment = strcmp(config_node_get_str(node, "alignment", ""), "right") == 0;
statusbar_item_config_create(bar, node->key,
priority, right_alignment);
}
static void statusbar_read(STATUSBAR_GROUP_REC *group, CONFIG_NODE *node)
{
STATUSBAR_CONFIG_REC *bar;
GSList *tmp;
int type, placement, position, visible;
const char *visible_str;
bar = statusbar_config_find(group, node->key);
type = STATUSBAR_TYPE_ROOT;
placement = STATUSBAR_BOTTOM;
position = 0;
visible = STATUSBAR_VISIBLE_ALWAYS;
visible_str = config_node_get_str(node, "visible", "");
if (strcmp(visible_str, "active") == 0)
visible = STATUSBAR_VISIBLE_ACTIVE;
else if (strcmp(visible_str, "inactive") == 0)
visible = STATUSBAR_VISIBLE_INACTIVE;
else if (strcmp(visible_str, "never") == 0) {
/* we don't want this statusbar -
destroy it if it already exists */
if (bar != NULL)
statusbar_config_destroy(group, bar);
return;
}
if (strcmp(config_node_get_str(node, "type", ""), "window") == 0)
type = STATUSBAR_TYPE_WINDOW;
if (strcmp(config_node_get_str(node, "placement", ""), "top") == 0)
placement = STATUSBAR_TOP;
position = config_node_get_int(node, "position", 0);
if (bar == NULL)
bar = statusbar_config_create(group, node->key);
bar->type = type;
bar->placement = placement;
bar->position = position;
bar->visible = visible;
node = config_node_section(node, "items", -1);
if (node != NULL) {
/* we're overriding the items - destroy the old */
while (bar->items != NULL)
statusbar_config_item_destroy(bar, bar->items->data);
tmp = config_node_first(node->value);
for (; tmp != NULL; tmp = config_node_next(tmp))
statusbar_read_item(bar, tmp->data);
}
}
static void statusbar_read_group(CONFIG_NODE *node)
{
STATUSBAR_GROUP_REC *group;
GSList *tmp;
group = statusbar_group_find(node->key);
if (group == NULL) {
group = statusbar_group_create(node->key);
if (active_statusbar_group == NULL)
active_statusbar_group = group;
}
tmp = config_node_first(node->value);
for (; tmp != NULL; tmp = config_node_next(tmp))
statusbar_read(group, tmp->data);
}
static void create_root_statusbars(void)
{
STATUSBAR_REC *bar;
GSList *tmp;
tmp = active_statusbar_group->config_bars;
for (; tmp != NULL; tmp = tmp->next) {
STATUSBAR_CONFIG_REC *rec = tmp->data;
if (rec->type == STATUSBAR_TYPE_ROOT) {
bar = statusbar_create(active_statusbar_group, rec, NULL);
statusbar_redraw(bar);
}
}
}
static void read_statusbar_config_from_node(CONFIG_NODE *node)
{
CONFIG_NODE *items;
GSList *tmp;
items = config_node_section(node, "items", -1);
if (items != NULL)
statusbar_read_items(items);
tmp = config_node_first(node->value);
for (; tmp != NULL; tmp = config_node_next(tmp)) {
if (tmp->data != items)
statusbar_read_group(tmp->data);
}
}
static void read_statusbar_config(void)
{
CONFIG_NODE *node;
statusbar_reset_defaults();
node = iconfig_node_traverse("statusbar", FALSE);
if (node != NULL)
read_statusbar_config_from_node(node);
create_root_statusbars();
}
void statusbar_config_init(void)
{
read_statusbar_config();
signal_add("setup reread", (SIGNAL_FUNC) read_statusbar_config);
}
void statusbar_config_deinit(void)
{
}

View File

@ -0,0 +1,12 @@
#ifndef __STATUSBAR_CONFIG_H
#define __STATUSBAR_CONFIG_H
#include "statusbar.h"
void statusbar_config_destroy(STATUSBAR_GROUP_REC *group,
STATUSBAR_CONFIG_REC *config);
void statusbar_config_init(void);
void statusbar_config_deinit(void);
#endif

View File

@ -20,183 +20,103 @@
#include "module.h"
#include "signals.h"
#include "misc.h"
#include "settings.h"
#include "special-vars.h"
#include "window-items.h"
#include "formats.h"
#include "statusbar.h"
#include "gui-printtext.h"
#include "gui-entry.h"
/* how often to redraw lagging time (seconds) */
#define LAG_REFRESH_TIME 10
/* how often to check for new mail (seconds) */
#define MAIL_REFRESH_TIME 60
/* If we haven't been able to check lag for this long, "(??)" is added after
the lag */
#define MAX_LAG_UNKNOWN_TIME 30
static STATUSBAR_REC *mainbar;
static MAIN_WINDOW_REC *mainbar_window;
static int use_colors;
/* clock */
static SBAR_ITEM_REC *clock_item;
static int clock_timetag;
static time_t clock_last;
/* nick */
static SBAR_ITEM_REC *nick_item;
/* channel */
static SBAR_ITEM_REC *window_item;
/* activity */
static SBAR_ITEM_REC *activity_item;
static GSList *activity_items;
static GList *activity_list;
/* more */
static SBAR_ITEM_REC *more_item;
static GHashTable *input_entries;
/* lag */
static SBAR_ITEM_REC *lag_item;
static int lag_timetag, lag_min_show;
static time_t lag_last_draw;
/* mbox counter */
static SBAR_ITEM_REC *mail_item;
static int mail_timetag, mail_last_count;
static time_t mail_last_mtime = -1;
static off_t mail_last_size = -1;
/* topic */
static SBAR_ITEM_REC *topic_item;
static STATUSBAR_REC *topic_bar;
static void item_default(SBAR_ITEM_REC *item, int get_size_only,
const char *str, const char *data)
{
SERVER_REC *server;
WI_ITEM_REC *wiitem;
char *tmpstr, *tmpstr2;
int len;
if (active_win == NULL) {
server = NULL;
wiitem = NULL;
} else {
server = active_win->active_server;
wiitem = active_win->active;
}
/* expand $variables */
tmpstr = parse_special_string(str, server, wiitem, data, NULL,
PARSE_FLAG_ESCAPE_VARS |
PARSE_FLAG_ESCAPE_THEME);
/* expand templates */
str = tmpstr;
tmpstr2 = theme_format_expand_data(current_theme, &str,
'n', '0' + item->bar->color,
NULL, NULL,
EXPAND_FLAG_ROOT |
EXPAND_FLAG_IGNORE_REPLACES |
EXPAND_FLAG_IGNORE_EMPTY);
g_free(tmpstr);
/* remove color codes */
tmpstr = strip_codes(tmpstr2);
g_free(tmpstr2);
if (get_size_only) {
item->min_size = item->max_size = format_get_length(tmpstr);
} else {
if (item->size < item->min_size) {
/* they're forcing us smaller than minimum size.. */
len = format_real_length(tmpstr, item->size);
tmpstr[len] = '\0';
}
tmpstr2 = g_strconcat(item->bar->color_string, tmpstr, NULL);
gui_printtext(item->xpos, item->bar->ypos, tmpstr2);
g_free(tmpstr2);
}
g_free(tmpstr);
}
/* redraw clock */
static void statusbar_clock(SBAR_ITEM_REC *item, int get_size_only)
{
item_default(item, get_size_only, "{sb $Z}", "");
}
/* check if we need to redraw clock.. */
static int statusbar_clock_timeout(void)
{
struct tm *tm;
time_t t;
int min;
tm = localtime(&clock_last);
min = tm->tm_min;
t = time(NULL);
tm = localtime(&t);
if (tm->tm_min != min) {
/* minute changed, redraw! */
clock_last = t;
statusbar_item_redraw(clock_item);
}
return 1;
}
/* redraw nick */
static void statusbar_nick(SBAR_ITEM_REC *item, int get_size_only)
{
item_default(item, get_size_only,
"{sb $cumode$N{sbmode $usermode}{sbaway $A}}", "");
}
static void sig_statusbar_nick_redraw(void)
{
statusbar_item_redraw(nick_item);
}
/* redraw window */
static void statusbar_window(SBAR_ITEM_REC *item, int get_size_only)
{
if (active_win->active != NULL) {
item_default(item, get_size_only,
"{sb $winref:$T{sbmode $M}}", "");
} else {
item_default(item, get_size_only,
"{sb $winref{sbservertag $tag}}", "");
}
}
static void sig_statusbar_window_redraw(void)
{
statusbar_item_redraw(window_item);
}
static void sig_statusbar_window_redraw_window(WINDOW_REC *window)
{
if (is_window_visible(window))
statusbar_item_redraw(window_item);
}
static void sig_statusbar_window_redraw_window_item(WI_ITEM_REC *item)
static void item_window_active(SBAR_ITEM_REC *item, int get_size_only)
{
WINDOW_REC *window;
window = window_item_window(item);
if (window->active == item && is_window_visible(window))
statusbar_item_redraw(window_item);
window = active_win;
if (item->bar->parent_window != NULL)
window = item->bar->parent_window->active;
if (window != NULL && window->active != NULL) {
statusbar_item_default_handler(item, get_size_only,
NULL, "", TRUE);
} else if (get_size_only) {
item->min_size = item->max_size = 0;
}
}
static void item_window_empty(SBAR_ITEM_REC *item, int get_size_only)
{
WINDOW_REC *window;
window = active_win;
if (item->bar->parent_window != NULL)
window = item->bar->parent_window->active;
if (window != NULL && window->active == NULL) {
statusbar_item_default_handler(item, get_size_only,
NULL, "", TRUE);
} else if (get_size_only) {
item->min_size = item->max_size = 0;
}
}
static void item_lag(SBAR_ITEM_REC *item, int get_size_only)
{
SERVER_REC *server;
GString *str;
int lag_unknown, lag_min_show;
time_t now;
server = active_win == NULL ? NULL : active_win->active_server;
if (server == NULL || server->lag_last_check == 0) {
/* No lag information */
if (get_size_only)
item->min_size = item->max_size = 0;
return;
}
now = time(NULL);
str = g_string_new(NULL);
/* FIXME: ugly ugly.. */
if (server->lag_sent == 0 || now-server->lag_sent < 5) {
lag_unknown = now-server->lag_last_check >
MAX_LAG_UNKNOWN_TIME+settings_get_int("lag_check_time");
lag_min_show = settings_get_int("lag_min_show");
if (lag_min_show < 0 || (server->lag < lag_min_show && !lag_unknown)) {
/* small lag, don't display */
} else {
g_string_sprintfa(str, "%d.%02d", server->lag/1000,
(server->lag % 1000)/10);
if (lag_unknown)
g_string_append(str, " (?""?)");
}
} else {
/* big lag, still waiting .. */
g_string_sprintfa(str, "%ld (?""?)",
(long) (now-server->lag_sent));
}
if (str->len != 0) {
statusbar_item_default_handler(item, get_size_only,
NULL, str->str, TRUE);
} else {
if (get_size_only)
item->min_size = item->max_size = 0;
}
g_string_free(str, TRUE);
}
static char *get_activity_list(int normal, int hilight)
@ -245,31 +165,21 @@ static char *get_activity_list(int normal, int hilight)
/* redraw activity, FIXME: if we didn't get enough size, this gets buggy.
At least "Det:" isn't printed properly. also we should rearrange the
act list so that the highest priority items comes first. */
static void statusbar_activity(SBAR_ITEM_REC *item, int get_size_only)
static void item_act(SBAR_ITEM_REC *item, int get_size_only)
{
char *actlist, *detlist, *data;
char *actlist;
if (use_colors) {
actlist = get_activity_list(TRUE, TRUE);
detlist = NULL;
} else {
actlist = get_activity_list(TRUE, FALSE);
detlist = get_activity_list(FALSE, TRUE);
}
if (actlist == NULL && detlist == NULL) {
actlist = get_activity_list(TRUE, TRUE);
if (actlist == NULL) {
if (get_size_only)
item->min_size = item->max_size = 0;
return;
}
data = g_strconcat("{sbact ", actlist != NULL ? actlist : "",
" ", detlist != NULL ? detlist : "", "}", NULL);
item_default(item, get_size_only, data, "");
g_free(data);
statusbar_item_default_handler(item, get_size_only,
NULL, actlist, FALSE);
g_free_not_null(actlist);
g_free_not_null(detlist);
}
static void sig_statusbar_activity_hilight(WINDOW_REC *window, gpointer oldlevel)
@ -285,7 +195,7 @@ static void sig_statusbar_activity_hilight(WINDOW_REC *window, gpointer oldlevel
activity_list = g_list_remove(activity_list, window);
if (window->data_level != 0)
activity_list = g_list_prepend(activity_list, window);
statusbar_item_redraw(activity_item);
statusbar_items_redraw(activity_items);
return;
}
@ -294,12 +204,12 @@ static void sig_statusbar_activity_hilight(WINDOW_REC *window, gpointer oldlevel
if (window->data_level == 0) {
/* remove from activity list */
activity_list = g_list_remove(activity_list, window);
statusbar_item_redraw(activity_item);
statusbar_items_redraw(activity_items);
} else if (window->data_level != GPOINTER_TO_INT(oldlevel) ||
window->hilight_color != 0) {
/* different level as last time (or maybe different
hilight color?), just redraw it. */
statusbar_item_redraw(activity_item);
statusbar_items_redraw(activity_items);
}
return;
}
@ -321,7 +231,7 @@ static void sig_statusbar_activity_hilight(WINDOW_REC *window, gpointer oldlevel
if (tmp == NULL)
activity_list = g_list_append(activity_list, window);
statusbar_item_redraw(activity_item);
statusbar_items_redraw(activity_items);
}
static void sig_statusbar_activity_window_destroyed(WINDOW_REC *window)
@ -330,444 +240,97 @@ static void sig_statusbar_activity_window_destroyed(WINDOW_REC *window)
if (g_list_find(activity_list, window) != NULL)
activity_list = g_list_remove(activity_list, window);
statusbar_item_redraw(activity_item);
statusbar_items_redraw(activity_items);
}
static void sig_statusbar_activity_updated(void)
{
statusbar_item_redraw(activity_item);
statusbar_items_redraw(activity_items);
}
/* redraw -- more -- */
static void statusbar_more(SBAR_ITEM_REC *item, int get_size_only)
static void item_more(SBAR_ITEM_REC *item, int get_size_only)
{
item_default(item, get_size_only, "{sbmore}", "");
}
static void sig_statusbar_more_check_remove(WINDOW_REC *window)
static void item_input(SBAR_ITEM_REC *item, int get_size_only)
{
g_return_if_fail(window != NULL);
GUI_ENTRY_REC *rec;
if (!is_window_visible(window))
return;
if (more_item != NULL && WINDOW_GUI(window)->view->bottom) {
statusbar_item_remove(more_item);
more_item = NULL;
}
}
static void sig_statusbar_more_check(WINDOW_REC *window)
{
if (window == NULL || !is_window_visible(window))
return;
if (!WINDOW_GUI(window)->view->bottom) {
if (more_item == NULL) {
more_item = statusbar_item_create(mainbar, SBAR_PRIORITY_LOW, FALSE, statusbar_more);
statusbar_redraw(mainbar);
}
} else if (more_item != NULL) {
statusbar_item_remove(more_item);
more_item = NULL;
}
}
static void statusbar_lag(SBAR_ITEM_REC *item, int get_size_only)
{
SERVER_REC *server;
GString *str;
int lag_unknown;
time_t now;
server = active_win == NULL ? NULL : active_win->active_server;
if (server == NULL || server->lag_last_check == 0) {
/* No lag information */
if (get_size_only)
item->min_size = item->max_size = 0;
return;
if (get_size_only) {
item->min_size = 2+screen_width/10;
item->max_size = screen_width;
return;
}
now = time(NULL);
str = g_string_new(NULL);
/* FIXME: ugly ugly.. */
if (server->lag_sent == 0 || now-server->lag_sent < 5) {
lag_unknown = now-server->lag_last_check >
MAX_LAG_UNKNOWN_TIME+settings_get_int("lag_check_time");
if (lag_min_show < 0 || (server->lag < lag_min_show && !lag_unknown)) {
/* small lag, don't display */
} else {
g_string_sprintfa(str, "%d.%02d", server->lag/1000,
(server->lag % 1000)/10);
if (lag_unknown)
g_string_append(str, " (?""?)");
}
rec = g_hash_table_lookup(input_entries, item);
if (rec == NULL) {
rec = gui_entry_create(item->xpos, item->bar->real_ypos,
item->size);
if (active_entry == NULL)
gui_entry_set_active(rec);
g_hash_table_insert(input_entries, item, rec);
} else {
/* big lag, still waiting .. */
g_string_sprintfa(str, "%ld (?""?)",
(long) (now-server->lag_sent));
}
item_default(item, get_size_only, "{sblag $0-}", str->str);
g_string_free(str, TRUE);
}
static void sig_statusbar_lag_redraw(void)
{
statusbar_item_redraw(lag_item);
}
static int statusbar_lag_timeout(void)
{
/* refresh statusbar every 10 seconds */
if (time(NULL)-lag_last_draw < LAG_REFRESH_TIME)
return 1;
statusbar_item_redraw(lag_item);
return 1;
}
/* FIXME: this isn't very good.. it handles only mbox mailboxes.
this whole mail feature should really be in it's own module with lots
of other mail formats supported and people who don't want to use it
wouldn't need to.. */
static int get_mail_count(void)
{
struct stat statbuf;
FILE *f;
char str[512], *fname;
int count;
fname = g_getenv("MAIL");
if (fname == NULL) return 0;
if (stat(fname, &statbuf) != 0) {
mail_last_mtime = -1;
mail_last_size = -1;
mail_last_count = 0;
return 0;
}
if (statbuf.st_mtime == mail_last_mtime &&
statbuf.st_size == mail_last_size)
return mail_last_count;
mail_last_mtime = statbuf.st_mtime;
mail_last_size = statbuf.st_size;
f = fopen(fname, "r");
if (f == NULL) {
mail_last_count = 0;
return 0;
}
count = 0;
while (fgets(str, sizeof(str), f) != NULL) {
if (strncmp(str, "From ", 5) == 0)
count++;
if (strncmp(str, "Subject: ", 9) == 0 &&
strstr(str, "FOLDER INTERNAL DATA")) {
/* don't count these. */
count--;
}
}
fclose(f);
if (mail_last_count != count)
signal_emit("mail counter", 0);
mail_last_count = count;
return count;
}
static void statusbar_mail(SBAR_ITEM_REC *item, int get_size_only)
{
char countstr[MAX_INT_STRLEN];
int mail_count;
mail_count = settings_get_bool("mail_counter") ? get_mail_count() : 0;
if (mail_count <= 0) {
if (get_size_only)
item->min_size = item->max_size = 0;
return;
}
ltoa(countstr, mail_count);
item_default(item, get_size_only, "{sbmail $0-}", countstr);
}
static int statusbar_mail_timeout(void)
{
statusbar_item_redraw(mail_item);
return 1;
}
static void statusbar_topic(SBAR_ITEM_REC *item, int get_size_only)
{
item_default(item, get_size_only, "$topic", "");
}
static void sig_statusbar_topic_redraw(void)
{
if (topic_item != NULL) statusbar_item_redraw(topic_item);
}
static void sig_sidebars_redraw(void)
{
GSList *tmp;
for (tmp = mainwindows; tmp != NULL; tmp = tmp->next) {
MAIN_WINDOW_REC *rec = tmp->data;
if (rec->statusbar_window_item != NULL)
statusbar_item_redraw(rec->statusbar_window_item);
gui_entry_move(rec, item->xpos, item->bar->real_ypos,
item->size);
gui_entry_redraw(rec); /* FIXME: this is only necessary with ^L.. */
}
}
static void topicbar_create(void)
static void sig_statusbar_item_created(SBAR_ITEM_REC *item)
{
if (topic_bar != NULL)
return;
topic_bar = statusbar_create(STATUSBAR_POS_UP, 0);
topic_item = statusbar_item_create(topic_bar, SBAR_PRIORITY_NORMAL, FALSE, statusbar_topic);
topic_item->max_size = TRUE;
statusbar_redraw(topic_bar);
signal_add("window changed", (SIGNAL_FUNC) sig_statusbar_topic_redraw);
signal_add("window item changed", (SIGNAL_FUNC) sig_statusbar_topic_redraw);
signal_add("channel topic changed", (SIGNAL_FUNC) sig_statusbar_topic_redraw);
signal_add("query address changed", (SIGNAL_FUNC) sig_statusbar_topic_redraw);
if (item->func == item_act)
activity_items = g_slist_prepend(activity_items, item);
}
static void topicbar_destroy(void)
static void sig_statusbar_item_destroyed(SBAR_ITEM_REC *item)
{
if (topic_bar == NULL)
return;
if (item->func == item_act)
activity_items = g_slist_remove(activity_items, item);
else {
GUI_ENTRY_REC *rec;
statusbar_destroy(topic_bar);
topic_item = NULL;
topic_bar = NULL;
signal_remove("window changed", (SIGNAL_FUNC) sig_statusbar_topic_redraw);
signal_remove("window item changed", (SIGNAL_FUNC) sig_statusbar_topic_redraw);
signal_remove("channel topic changed", (SIGNAL_FUNC) sig_statusbar_topic_redraw);
signal_remove("query address changed", (SIGNAL_FUNC) sig_statusbar_topic_redraw);
}
static void mainbar_remove_items(void)
{
statusbar_item_remove(clock_item);
statusbar_item_remove(nick_item);
statusbar_item_remove(window_item);
statusbar_item_remove(mail_item);
statusbar_item_remove(lag_item);
statusbar_item_remove(activity_item);
}
static void mainbar_add_items(MAIN_WINDOW_REC *window)
{
mainbar = window->statusbar;
mainbar_window = window;
clock_item = statusbar_item_create(mainbar, SBAR_PRIORITY_HIGH, FALSE, statusbar_clock);
nick_item = statusbar_item_create(mainbar, SBAR_PRIORITY_NORMAL, FALSE, statusbar_nick);
window_item = statusbar_item_create(mainbar, SBAR_PRIORITY_NORMAL, FALSE, statusbar_window);
mail_item = statusbar_item_create(mainbar, SBAR_PRIORITY_LOW, FALSE, statusbar_mail);
lag_item = statusbar_item_create(mainbar, SBAR_PRIORITY_LOW, FALSE, statusbar_lag);
activity_item = statusbar_item_create(mainbar, SBAR_PRIORITY_HIGH, FALSE, statusbar_activity);
}
static void sidebar_add_items(MAIN_WINDOW_REC *window)
{
window->statusbar_window_item =
statusbar_item_create(window->statusbar, SBAR_PRIORITY_NORMAL, FALSE, statusbar_window);
}
static void sidebar_remove_items(MAIN_WINDOW_REC *window)
{
if (window->statusbar_window_item != NULL) {
statusbar_item_remove(window->statusbar_window_item);
window->statusbar_window_item = NULL;
rec = g_hash_table_lookup(input_entries, item);
if (rec != NULL) gui_entry_destroy(rec);
}
}
static void sig_mainwindow_created(MAIN_WINDOW_REC *window)
{
window->statusbar =
statusbar_create(STATUSBAR_POS_MIDDLE,
window->first_line+window->height);
((STATUSBAR_REC *) window->statusbar)->window = window;
sidebar_add_items(window);
}
static void sig_mainwindow_destroyed(MAIN_WINDOW_REC *window)
{
if (window == mainbar_window) {
statusbar_destroy(mainbar);
window->statusbar = NULL;
mainbar = NULL;
mainbar_window = NULL;
}
if (window->statusbar != NULL)
statusbar_destroy(window->statusbar);
}
static void sig_main_statusbar_changed(WINDOW_REC *window)
{
MAIN_WINDOW_REC *parent;
if (window == NULL)
return;
parent = WINDOW_GUI(window)->parent;
if (mainbar == parent->statusbar)
return;
if (mainbar != NULL) {
mainbar_remove_items();
sidebar_add_items(mainbar_window);
}
sidebar_remove_items(parent);
mainbar_add_items(parent);
}
static void read_settings(void)
{
use_colors = settings_get_bool("colors") && screen_has_colors();
if (settings_get_bool("topicbar"))
topicbar_create();
else
topicbar_destroy();
lag_min_show = settings_get_int("lag_min_show")*10;
statusbar_redraw(NULL);
}
void statusbar_items_init(void)
{
GSList *tmp;
settings_add_int("misc", "lag_min_show", 100);
settings_add_bool("lookandfeel", "topicbar", TRUE);
settings_add_bool("lookandfeel", "actlist_moves", FALSE);
settings_add_bool("misc", "mail_counter", TRUE);
/* clock */
clock_timetag = g_timeout_add(1000, (GSourceFunc) statusbar_clock_timeout, NULL);
statusbar_item_register("window", NULL, item_window_active);
statusbar_item_register("window_empty", NULL, item_window_empty);
statusbar_item_register("prompt", NULL, item_window_active);
statusbar_item_register("prompt_empty", NULL, item_window_empty);
statusbar_item_register("lag", NULL, item_lag);
statusbar_item_register("act", NULL, item_act);
statusbar_item_register("more", NULL, item_more);
statusbar_item_register("input", NULL, item_input);
/* nick */
signal_add("server connected", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
signal_add("channel wholist", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
signal_add("window changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
signal_add("window item changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
signal_add("nick mode changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
signal_add("user mode changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
signal_add("server nick changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
signal_add("window server changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
signal_add("away mode changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
input_entries = g_hash_table_new((GHashFunc) g_direct_hash,
(GCompareFunc) g_direct_equal);
/* channel */
signal_add("window changed", (SIGNAL_FUNC) sig_statusbar_window_redraw);
signal_add("window item changed", (SIGNAL_FUNC) sig_statusbar_window_redraw_window);
signal_add("channel mode changed", (SIGNAL_FUNC) sig_statusbar_window_redraw_window_item);
signal_add("window server changed", (SIGNAL_FUNC) sig_statusbar_window_redraw_window);
signal_add("window refnum changed", (SIGNAL_FUNC) sig_statusbar_window_redraw_window);
/* activity */
activity_list = NULL;
signal_add("window activity", (SIGNAL_FUNC) sig_statusbar_activity_hilight);
signal_add("window destroyed", (SIGNAL_FUNC) sig_statusbar_activity_window_destroyed);
signal_add("window refnum changed", (SIGNAL_FUNC) sig_statusbar_activity_updated);
/* more */
more_item = NULL;
signal_add("gui page scrolled", (SIGNAL_FUNC) sig_statusbar_more_check_remove);
signal_add("window changed", (SIGNAL_FUNC) sig_statusbar_more_check);
signal_add_last("gui print text finished", (SIGNAL_FUNC) sig_statusbar_more_check);
/* lag */
lag_timetag = g_timeout_add(1000*LAG_REFRESH_TIME, (GSourceFunc) statusbar_lag_timeout, NULL);
signal_add("server lag", (SIGNAL_FUNC) sig_statusbar_lag_redraw);
signal_add("window server changed", (SIGNAL_FUNC) sig_statusbar_lag_redraw);
/* mail */
mail_timetag = g_timeout_add(1000*MAIL_REFRESH_TIME, (GSourceFunc) statusbar_mail_timeout, NULL);
/* topic */
topic_item = NULL; topic_bar = NULL;
signal_add("setup changed", (SIGNAL_FUNC) read_settings);
read_settings();
statusbar_redraw(NULL);
/* middle bars */
signal_add("mainwindow created", (SIGNAL_FUNC) sig_mainwindow_created);
signal_add("mainwindow destroyed", (SIGNAL_FUNC) sig_mainwindow_destroyed);
signal_add("window changed", (SIGNAL_FUNC) sig_main_statusbar_changed);
signal_add("window refnum changed", (SIGNAL_FUNC) sig_sidebars_redraw);
/* add statusbars to existing windows */
for (tmp = mainwindows; tmp != NULL; tmp = tmp->next)
sig_mainwindow_created(tmp->data);
sig_main_statusbar_changed(active_win);
signal_add("statusbar item created", (SIGNAL_FUNC) sig_statusbar_item_created);
signal_add("statusbar item destroyed", (SIGNAL_FUNC) sig_statusbar_item_destroyed);
}
void statusbar_items_deinit(void)
{
/* clock */
g_source_remove(clock_timetag);
g_hash_table_destroy(input_entries);
/* nick */
signal_remove("server connected", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
signal_remove("channel wholist", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
signal_remove("window changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
signal_remove("window item changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
signal_remove("nick mode changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
signal_remove("user mode changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
signal_remove("server nick changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
signal_remove("window server changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
signal_remove("away mode changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
/* channel */
signal_remove("window changed", (SIGNAL_FUNC) sig_statusbar_window_redraw);
signal_remove("window item changed", (SIGNAL_FUNC) sig_statusbar_window_redraw_window);
signal_remove("channel mode changed", (SIGNAL_FUNC) sig_statusbar_window_redraw_window_item);
signal_remove("window server changed", (SIGNAL_FUNC) sig_statusbar_window_redraw_window);
signal_remove("window refnum changed", (SIGNAL_FUNC) sig_statusbar_window_redraw_window);
/* activity */
signal_remove("window activity", (SIGNAL_FUNC) sig_statusbar_activity_hilight);
signal_remove("window destroyed", (SIGNAL_FUNC) sig_statusbar_activity_window_destroyed);
signal_remove("window refnum changed", (SIGNAL_FUNC) sig_statusbar_activity_updated);
g_list_free(activity_list);
activity_list = NULL;
/* more */
signal_remove("gui page scrolled", (SIGNAL_FUNC) sig_statusbar_more_check_remove);
signal_remove("window changed", (SIGNAL_FUNC) sig_statusbar_more_check);
signal_remove("gui print text finished", (SIGNAL_FUNC) sig_statusbar_more_check);
/* lag */
g_source_remove(lag_timetag);
signal_remove("server lag", (SIGNAL_FUNC) sig_statusbar_lag_redraw);
signal_remove("window server changed", (SIGNAL_FUNC) sig_statusbar_lag_redraw);
/* mail */
g_source_remove(mail_timetag);
/* topic */
topicbar_destroy();
signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
/* middle bars */
signal_remove("mainwindow created", (SIGNAL_FUNC) sig_mainwindow_created);
signal_remove("mainwindow destroyed", (SIGNAL_FUNC) sig_mainwindow_destroyed);
signal_remove("window changed", (SIGNAL_FUNC) sig_main_statusbar_changed);
signal_remove("window refnum changed", (SIGNAL_FUNC) sig_sidebars_redraw);
signal_remove("statusbar item created", (SIGNAL_FUNC) sig_statusbar_item_created);
signal_remove("statusbar item destroyed", (SIGNAL_FUNC) sig_statusbar_item_destroyed);
}

View File

@ -0,0 +1,7 @@
#ifndef __STATUSBAR_ITEMS_H
#define __STATUSBAR_ITEMS_H
void statusbar_items_init(void);
void statusbar_items_deinit(void);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -3,59 +3,105 @@
#include "mainwindows.h"
#define SBAR_PRIORITY_HIGH 100
#define SBAR_PRIORITY_NORMAL 0
#define SBAR_PRIORITY_LOW -100
enum {
STATUSBAR_POS_UP,
STATUSBAR_POS_MIDDLE,
STATUSBAR_POS_DOWN
};
#define STATUSBAR_PRIORITY_HIGH 100
#define STATUSBAR_PRIORITY_NORMAL 0
#define STATUSBAR_PRIORITY_LOW -100
typedef struct SBAR_ITEM_REC SBAR_ITEM_REC;
typedef void (*STATUSBAR_FUNC) (SBAR_ITEM_REC *item, int get_size_only);
/* type */
#define STATUSBAR_TYPE_ROOT 1
#define STATUSBAR_TYPE_WINDOW 2
/* placement */
#define STATUSBAR_TOP 1
#define STATUSBAR_BOTTOM 2
/* visible */
#define STATUSBAR_VISIBLE_ALWAYS 1
#define STATUSBAR_VISIBLE_ACTIVE 2
#define STATUSBAR_VISIBLE_INACTIVE 3
typedef struct {
MAIN_WINDOW_REC *window;
char *name;
GSList *config_bars;
GSList *bars;
} STATUSBAR_GROUP_REC;
int pos;
int line;
typedef struct {
char *name;
char *color_string;
int color;
int type; /* root/window */
int placement; /* top/bottom */
int position; /* the higher the number, the lower it is in screen */
int visible; /* active/inactive/always */
int ypos; /* real position in screen at the moment */
GSList *items;
} STATUSBAR_CONFIG_REC;
typedef struct {
STATUSBAR_GROUP_REC *group;
STATUSBAR_CONFIG_REC *config;
MAIN_WINDOW_REC *parent_window; /* if config->type == STATUSBAR_TYPE_WINDOW */
GSList *items;
char *color; /* background color */
int real_ypos; /* real Y-position in screen at the moment */
} STATUSBAR_REC;
typedef struct {
char *name;
char *value; /* if non-NULL, overrides the default */
int priority;
unsigned int right_alignment:1;
} SBAR_ITEM_CONFIG_REC;
struct SBAR_ITEM_REC {
STATUSBAR_REC *bar;
STATUSBAR_FUNC func;
SBAR_ITEM_CONFIG_REC *config;
STATUSBAR_FUNC func;
/* what item wants */
int priority;
int min_size, max_size;
unsigned int right_justify:1;
/* what item gets */
int xpos, size;
int xpos, size;
};
/* ypos is used only when pos == STATUSBAR_POS_MIDDLE */
STATUSBAR_REC *statusbar_create(int pos, int ypos);
void statusbar_destroy(STATUSBAR_REC *bar);
extern GSList *statusbar_groups;
extern STATUSBAR_GROUP_REC *active_statusbar_group;
STATUSBAR_REC *statusbar_find(int pos, int line);
void statusbar_item_register(const char *name, const char *value,
STATUSBAR_FUNC func);
void statusbar_item_unregister(const char *name);
STATUSBAR_GROUP_REC *statusbar_group_create(const char *name);
void statusbar_group_destroy(STATUSBAR_GROUP_REC *rec);
STATUSBAR_GROUP_REC *statusbar_group_find(const char *name);
STATUSBAR_REC *statusbar_create(STATUSBAR_GROUP_REC *group,
STATUSBAR_CONFIG_REC *config,
MAIN_WINDOW_REC *parent_window);
void statusbar_destroy(STATUSBAR_REC *bar);
STATUSBAR_REC *statusbar_find(STATUSBAR_GROUP_REC *group, const char *name,
MAIN_WINDOW_REC *window);
SBAR_ITEM_REC *statusbar_item_create(STATUSBAR_REC *bar,
int priority, int right_justify,
STATUSBAR_FUNC func);
void statusbar_item_remove(SBAR_ITEM_REC *item);
SBAR_ITEM_CONFIG_REC *config);
void statusbar_item_destroy(SBAR_ITEM_REC *item);
void statusbar_item_default_handler(SBAR_ITEM_REC *item, int get_size_only,
const char *str, const char *data,
int escape_vars);
/* redraw statusbar, NULL = all */
void statusbar_redraw(STATUSBAR_REC *bar);
void statusbar_item_redraw(SBAR_ITEM_REC *item);
#define statusbar_items_redraw(list) \
g_slist_foreach(list, (GFunc) statusbar_item_redraw, NULL);
void statusbar_init(void);
void statusbar_deinit(void);