mirror of
https://github.com/irssi/irssi.git
synced 2026-08-10 12:23:37 +02:00
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
63 changed files with 2471 additions and 1912 deletions
|
|
@ -35,277 +35,272 @@
|
|||
static gint mirc_colors[] = { 15, 0, 1, 2, 4, 6, 5, 4, 14, 10, 3, 11, 9, 13, 8, 7, 15 };
|
||||
static gint max_textwidget_lines;
|
||||
|
||||
static LINE_REC *create_line(GUI_WINDOW_REC *gui, gint level)
|
||||
#define mark_temp_eol(text) \
|
||||
memcpy((text)->buffer + (text)->pos, "\0\x80", 2);
|
||||
|
||||
static LINE_REC *create_line(GUI_WINDOW_REC *gui, int level)
|
||||
{
|
||||
g_return_val_if_fail(gui != NULL, NULL);
|
||||
g_return_val_if_fail(gui->cur_text != NULL, NULL);
|
||||
g_return_val_if_fail(gui != NULL, NULL);
|
||||
g_return_val_if_fail(gui->cur_text != NULL, NULL);
|
||||
|
||||
gui->cur_line = g_mem_chunk_alloc(gui->line_chunk);
|
||||
gui->cur_line->text = gui->cur_text->buffer+gui->cur_text->pos;
|
||||
gui->cur_line->level = (gint32) GPOINTER_TO_INT(level);
|
||||
gui->cur_line->time = time(NULL);
|
||||
gui->cur_line = g_mem_chunk_alloc(gui->line_chunk);
|
||||
gui->cur_line->text = gui->cur_text->buffer+gui->cur_text->pos;
|
||||
gui->cur_line->level = GPOINTER_TO_INT(level);
|
||||
gui->cur_line->time = time(NULL);
|
||||
|
||||
/* 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->last_color = -1;
|
||||
gui->last_flags = 0;
|
||||
|
||||
gui->lines = g_list_append(gui->lines, gui->cur_line);
|
||||
if (gui->startline == NULL)
|
||||
{
|
||||
gui->startline = gui->lines;
|
||||
gui->bottom_startline = gui->lines;
|
||||
}
|
||||
return gui->cur_line;
|
||||
gui->lines = g_list_append(gui->lines, gui->cur_line);
|
||||
if (gui->startline == NULL) {
|
||||
/* first line */
|
||||
gui->startline = gui->lines;
|
||||
gui->bottom_startline = gui->lines;
|
||||
}
|
||||
return gui->cur_line;
|
||||
}
|
||||
|
||||
static TEXT_CHUNK_REC *create_text_chunk(GUI_WINDOW_REC *gui)
|
||||
{
|
||||
TEXT_CHUNK_REC *rec;
|
||||
guchar *buffer;
|
||||
gchar *ptr;
|
||||
TEXT_CHUNK_REC *rec;
|
||||
char *buffer, *ptr;
|
||||
|
||||
g_return_val_if_fail(gui != NULL, NULL);
|
||||
g_return_val_if_fail(gui != NULL, NULL);
|
||||
|
||||
rec = g_new(TEXT_CHUNK_REC, 1);
|
||||
rec->overflow[0] = 0;
|
||||
rec->overflow[1] = (char) LINE_CMD_OVERFLOW;
|
||||
rec->pos = 0;
|
||||
rec->lines = 0;
|
||||
rec = g_new(TEXT_CHUNK_REC, 1);
|
||||
rec->overflow[0] = 0;
|
||||
rec->overflow[1] = (char) LINE_CMD_OVERFLOW;
|
||||
rec->pos = 0;
|
||||
rec->lines = 0;
|
||||
|
||||
if (gui->cur_line != NULL && gui->cur_line->text != NULL)
|
||||
{
|
||||
/* mark the next block text block position.. */
|
||||
buffer = (guchar *) gui->cur_text->buffer+gui->cur_text->pos;
|
||||
if (gui->cur_text->pos+2+sizeof(gchar *) > LINE_TEXT_CHUNK_SIZE)
|
||||
g_error("create_text_chunk() : buffer overflow?!");
|
||||
*buffer++ = 0; *buffer++ = LINE_CMD_CONTINUE;
|
||||
ptr = rec->buffer;
|
||||
memcpy(buffer, &ptr, sizeof(gchar *));
|
||||
}
|
||||
gui->cur_text = rec;
|
||||
gui->text_chunks = g_slist_append(gui->text_chunks, rec);
|
||||
return rec;
|
||||
if (gui->cur_line != NULL && gui->cur_line->text != NULL) {
|
||||
/* create a link to new block from the old block */
|
||||
buffer = gui->cur_text->buffer + gui->cur_text->pos;
|
||||
*buffer++ = 0; *buffer++ = (char) LINE_CMD_CONTINUE;
|
||||
|
||||
ptr = rec->buffer;
|
||||
memcpy(buffer, &ptr, sizeof(char *));
|
||||
}
|
||||
|
||||
gui->cur_text = rec;
|
||||
gui->text_chunks = g_slist_append(gui->text_chunks, rec);
|
||||
return rec;
|
||||
}
|
||||
|
||||
static void text_chunk_free(GUI_WINDOW_REC *gui, TEXT_CHUNK_REC *chunk)
|
||||
{
|
||||
g_return_if_fail(gui != NULL);
|
||||
g_return_if_fail(chunk != NULL);
|
||||
g_return_if_fail(gui != NULL);
|
||||
g_return_if_fail(chunk != NULL);
|
||||
|
||||
gui->text_chunks = g_slist_remove(gui->text_chunks, chunk);
|
||||
g_free(chunk);
|
||||
gui->text_chunks = g_slist_remove(gui->text_chunks, chunk);
|
||||
g_free(chunk);
|
||||
}
|
||||
|
||||
static void remove_first_line(WINDOW_REC *window)
|
||||
{
|
||||
GUI_WINDOW_REC *gui;
|
||||
TEXT_CHUNK_REC *chunk;
|
||||
GUI_WINDOW_REC *gui;
|
||||
TEXT_CHUNK_REC *chunk;
|
||||
|
||||
g_return_if_fail(window != NULL);
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
gui = WINDOW_GUI(window);
|
||||
chunk = gui->text_chunks->data;
|
||||
gui = WINDOW_GUI(window);
|
||||
chunk = gui->text_chunks->data;
|
||||
|
||||
if (--chunk->lines == 0)
|
||||
text_chunk_free(gui, chunk);
|
||||
if (--chunk->lines == 0)
|
||||
text_chunk_free(gui, chunk);
|
||||
|
||||
if (gui->startline->prev == NULL)
|
||||
{
|
||||
gui->startline = gui->startline->next;
|
||||
gui->subline = 0;
|
||||
}
|
||||
if (gui->bottom_startline->prev == NULL)
|
||||
{
|
||||
gui->bottom_startline = gui->bottom_startline->next;
|
||||
gui->bottom_subline = 0;
|
||||
}
|
||||
if (gui->startline->prev == NULL) {
|
||||
/* first line in screen removed */
|
||||
gui->startline = gui->startline->next;
|
||||
gui->subline = 0;
|
||||
}
|
||||
if (gui->bottom_startline->prev == NULL) {
|
||||
/* bottom line removed (shouldn't happen?) */
|
||||
gui->bottom_startline = gui->bottom_startline->next;
|
||||
gui->bottom_subline = 0;
|
||||
}
|
||||
|
||||
window->lines--;
|
||||
g_mem_chunk_free(gui->line_chunk, gui->lines->data);
|
||||
gui->lines = g_list_remove(gui->lines, gui->lines->data);
|
||||
window->lines--;
|
||||
g_mem_chunk_free(gui->line_chunk, gui->lines->data);
|
||||
gui->lines = g_list_remove(gui->lines, gui->lines->data);
|
||||
|
||||
if (gui->startline->prev == NULL && is_window_visible(window))
|
||||
gui_window_redraw(window);
|
||||
if (gui->startline->prev == NULL && is_window_visible(window))
|
||||
gui_window_redraw(window);
|
||||
}
|
||||
|
||||
static void get_colors(gint flags, gint *fg, gint *bg)
|
||||
static void get_colors(int flags, int *fg, int *bg)
|
||||
{
|
||||
if (flags & PRINTFLAG_MIRC_COLOR)
|
||||
{
|
||||
/* mirc colors */
|
||||
*fg = *fg < 0 || *fg > 16 ?
|
||||
current_theme->default_color : mirc_colors[*fg];
|
||||
*bg = *bg < 0 || *bg > 16 ? 0 : mirc_colors[*bg];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* default colors */
|
||||
*fg = *fg < 0 || *fg > 15 ?
|
||||
current_theme->default_color : *fg;
|
||||
*bg = *bg < 0 || *bg > 15 ? 0 : *bg;
|
||||
if (flags & PRINTFLAG_MIRC_COLOR) {
|
||||
/* mirc colors */
|
||||
*fg = *fg < 0 || *fg > 16 ?
|
||||
current_theme->default_color : mirc_colors[*fg];
|
||||
*bg = *bg < 0 || *bg > 16 ? 0 : mirc_colors[*bg];
|
||||
} else {
|
||||
/* default colors */
|
||||
*fg = *fg < 0 || *fg > 15 ?
|
||||
current_theme->default_color : *fg;
|
||||
*bg = *bg < 0 || *bg > 15 ? 0 : *bg;
|
||||
|
||||
if (*fg > 8) *fg -= 8;
|
||||
}
|
||||
if (*fg > 8) *fg -= 8;
|
||||
}
|
||||
|
||||
if (flags & PRINTFLAG_REVERSE)
|
||||
{
|
||||
gint tmp;
|
||||
if (flags & PRINTFLAG_REVERSE) {
|
||||
int tmp;
|
||||
|
||||
tmp = *fg; *fg = *bg; *bg = tmp;
|
||||
}
|
||||
tmp = *fg; *fg = *bg; *bg = tmp;
|
||||
}
|
||||
|
||||
if (*fg == 8) *fg |= ATTR_COLOR8;
|
||||
if (flags & PRINTFLAG_BOLD) *fg |= 8;
|
||||
if (flags & PRINTFLAG_UNDERLINE) *fg |= ATTR_UNDERLINE;
|
||||
if (flags & PRINTFLAG_BLINK) *bg |= 0x80;
|
||||
if (*fg == 8) *fg |= ATTR_COLOR8;
|
||||
if (flags & PRINTFLAG_BOLD) *fg |= 8;
|
||||
if (flags & PRINTFLAG_UNDERLINE) *fg |= ATTR_UNDERLINE;
|
||||
if (flags & PRINTFLAG_BLINK) *bg |= 0x80;
|
||||
}
|
||||
|
||||
static void linebuf_add(GUI_WINDOW_REC *gui, gchar *str, gint len)
|
||||
static void linebuf_add(GUI_WINDOW_REC *gui, char *str, int len)
|
||||
{
|
||||
gint left;
|
||||
int left;
|
||||
|
||||
if (len == 0) return;
|
||||
if (len == 0) return;
|
||||
|
||||
while (gui->cur_text->pos+len >= TEXT_CHUNK_USABLE_SIZE)
|
||||
{
|
||||
left = TEXT_CHUNK_USABLE_SIZE-gui->cur_text->pos;
|
||||
if (str[left-1] == 0) left--; /* don't split the command! */
|
||||
memcpy(gui->cur_text->buffer+gui->cur_text->pos, str, left);
|
||||
gui->cur_text->pos += left;
|
||||
create_text_chunk(gui);
|
||||
len -= left; str += left;
|
||||
}
|
||||
while (gui->cur_text->pos + len >= TEXT_CHUNK_USABLE_SIZE) {
|
||||
left = TEXT_CHUNK_USABLE_SIZE - gui->cur_text->pos;
|
||||
if (str[left-1] == 0) left--; /* don't split the commands */
|
||||
|
||||
memcpy(gui->cur_text->buffer+gui->cur_text->pos, str, len);
|
||||
gui->cur_text->pos += len;
|
||||
memcpy(gui->cur_text->buffer + gui->cur_text->pos, str, left);
|
||||
gui->cur_text->pos += left;
|
||||
|
||||
create_text_chunk(gui);
|
||||
len -= left; str += left;
|
||||
}
|
||||
|
||||
memcpy(gui->cur_text->buffer + gui->cur_text->pos, str, len);
|
||||
gui->cur_text->pos += len;
|
||||
}
|
||||
|
||||
static void 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;
|
||||
color = (fg & 0x0f) | (bg << 4);
|
||||
pos = 0;
|
||||
|
||||
if (((fg & ATTR_COLOR8) == 0 && (fg|(bg << 4)) != gui->last_color) ||
|
||||
((fg & ATTR_COLOR8) && (fg & 0xf0) != (gui->last_color & 0xf0)))
|
||||
{
|
||||
buffer[pos++] = 0;
|
||||
buffer[pos++] = (gchar) color;
|
||||
}
|
||||
if (((fg & ATTR_COLOR8) == 0 && (fg|(bg << 4)) != gui->last_color) ||
|
||||
((fg & ATTR_COLOR8) && (fg & 0xf0) != (gui->last_color & 0xf0))) {
|
||||
buffer[pos++] = 0;
|
||||
buffer[pos++] = color;
|
||||
}
|
||||
|
||||
if ((flags & PRINTFLAG_UNDERLINE) != (gui->last_flags & PRINTFLAG_UNDERLINE))
|
||||
{
|
||||
buffer[pos++] = 0;
|
||||
buffer[pos++] = LINE_CMD_UNDERLINE;
|
||||
}
|
||||
if (fg & ATTR_COLOR8)
|
||||
{
|
||||
buffer[pos++] = 0;
|
||||
buffer[pos++] = LINE_CMD_COLOR8;
|
||||
}
|
||||
if (flags & PRINTFLAG_BEEP)
|
||||
{
|
||||
buffer[pos++] = 0;
|
||||
buffer[pos++] = LINE_CMD_BEEP;
|
||||
}
|
||||
if (flags & PRINTFLAG_INDENT)
|
||||
{
|
||||
buffer[pos++] = 0;
|
||||
buffer[pos++] = LINE_CMD_INDENT;
|
||||
}
|
||||
if ((flags & PRINTFLAG_UNDERLINE) != (gui->last_flags & PRINTFLAG_UNDERLINE)) {
|
||||
buffer[pos++] = 0;
|
||||
buffer[pos++] = LINE_CMD_UNDERLINE;
|
||||
}
|
||||
if (fg & ATTR_COLOR8) {
|
||||
buffer[pos++] = 0;
|
||||
buffer[pos++] = LINE_CMD_COLOR8;
|
||||
}
|
||||
if (flags & PRINTFLAG_BEEP) {
|
||||
buffer[pos++] = 0;
|
||||
buffer[pos++] = LINE_CMD_BEEP;
|
||||
}
|
||||
if (flags & PRINTFLAG_INDENT) {
|
||||
buffer[pos++] = 0;
|
||||
buffer[pos++] = LINE_CMD_INDENT;
|
||||
}
|
||||
|
||||
linebuf_add(gui, (gchar *) buffer, pos);
|
||||
linebuf_add(gui, (char *) buffer, pos);
|
||||
|
||||
gui->last_flags = flags;
|
||||
gui->last_color = fg | (bg << 4);
|
||||
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;
|
||||
GUI_WINDOW_REC *gui;
|
||||
LINE_REC *line;
|
||||
int fg, bg, flags, new_lines, n, visible, ypos;
|
||||
|
||||
g_return_if_fail(window != NULL);
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
gui = WINDOW_GUI(window);
|
||||
if (max_textwidget_lines > 0 && max_textwidget_lines <= window->lines)
|
||||
remove_first_line(window);
|
||||
gui = WINDOW_GUI(window);
|
||||
if (max_textwidget_lines > 0 && max_textwidget_lines <= window->lines)
|
||||
remove_first_line(window);
|
||||
|
||||
visible = is_window_visible(window) && gui->bottom;
|
||||
flags = GPOINTER_TO_INT(pflags);
|
||||
fg = GPOINTER_TO_INT(fgcolor);
|
||||
bg = GPOINTER_TO_INT(bgcolor);
|
||||
visible = is_window_visible(window) && gui->bottom;
|
||||
flags = GPOINTER_TO_INT(pflags);
|
||||
fg = GPOINTER_TO_INT(fgcolor);
|
||||
bg = GPOINTER_TO_INT(bgcolor);
|
||||
|
||||
if (gui->cur_text == NULL)
|
||||
create_text_chunk(gui);
|
||||
if (gui->cur_text == NULL)
|
||||
create_text_chunk(gui);
|
||||
|
||||
/* \n can be only at the start of the line.. */
|
||||
if (*str == '\n')
|
||||
{
|
||||
linebuf_add(gui, "\0\x80", 2); /* mark EOL */
|
||||
line = create_line(gui, 0);
|
||||
gui_window_newline(gui, visible);
|
||||
str++;
|
||||
gui->cur_text->lines++;
|
||||
gui->last_subline = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
line = gui->cur_line != NULL ? gui->cur_line :
|
||||
create_line(gui, 0);
|
||||
if (line->level == 0) line->level = GPOINTER_TO_INT(level);
|
||||
}
|
||||
/* \n can be only at the start of the line.. */
|
||||
if (*str == '\n') {
|
||||
str++;
|
||||
linebuf_add(gui, "\0\x80", 2); /* mark EOL */
|
||||
|
||||
get_colors(flags, &fg, &bg);
|
||||
line_add_colors(gui, fg, bg, flags);
|
||||
linebuf_add(gui, str, strlen(str));
|
||||
line = create_line(gui, 0);
|
||||
gui_window_newline(gui, visible);
|
||||
|
||||
/* temporarily mark the end of line. */
|
||||
memcpy(gui->cur_text->buffer+gui->cur_text->pos, "\0\x80", 2);
|
||||
gui->cur_text->lines++;
|
||||
gui->last_subline = 0;
|
||||
} else {
|
||||
line = gui->cur_line != NULL ? gui->cur_line :
|
||||
create_line(gui, 0);
|
||||
if (line->level == 0) line->level = GPOINTER_TO_INT(level);
|
||||
}
|
||||
|
||||
if (visible)
|
||||
{
|
||||
/* draw the line to screen. */
|
||||
lines = gui_window_line_draw(gui, line, gui->parent->first_line+gui->ypos, gui->last_subline, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we still need to update the bottom's position */
|
||||
lines = gui_window_get_linecount(gui, line)-1-gui->last_subline;
|
||||
for (n = 0; n < lines; n++)
|
||||
gui_window_newline(gui, visible);
|
||||
}
|
||||
if (lines > 0) gui->last_subline += lines;
|
||||
get_colors(flags, &fg, &bg);
|
||||
line_add_colors(gui, fg, bg, flags);
|
||||
linebuf_add(gui, str, strlen(str));
|
||||
mark_temp_eol(gui->cur_text);
|
||||
|
||||
gui_window_cache_remove(gui, line);
|
||||
new_lines = gui_window_get_linecount(gui, line)-1 - gui->last_subline;
|
||||
|
||||
for (n = 0; n < new_lines; n++)
|
||||
gui_window_newline(gui, visible);
|
||||
|
||||
if (visible) {
|
||||
/* draw the line to screen. */
|
||||
ypos = gui->parent->first_line+gui->ypos-new_lines;
|
||||
if (new_lines > 0) {
|
||||
set_color(0);
|
||||
move(ypos, 0); clrtoeol();
|
||||
}
|
||||
gui_window_line_draw(gui, line, ypos, gui->last_subline, -1);
|
||||
}
|
||||
|
||||
gui->last_subline += new_lines;
|
||||
}
|
||||
|
||||
static void cmd_clear(gchar *data)
|
||||
static void window_clear(GUI_WINDOW_REC *gui)
|
||||
{
|
||||
GUI_WINDOW_REC *gui;
|
||||
gint n;
|
||||
int n;
|
||||
|
||||
gui = WINDOW_GUI(active_win);
|
||||
for (n = gui->parent->first_line; n <= gui->parent->last_line; n++) {
|
||||
move(n, 0);
|
||||
clrtoeol();
|
||||
}
|
||||
screen_refresh();
|
||||
}
|
||||
|
||||
if (is_window_visible(active_win))
|
||||
{
|
||||
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->ypos = -1;
|
||||
gui->bottom_startline = gui->startline = g_list_last(gui->lines);
|
||||
gui->bottom_subline = gui->subline = gui->last_subline+1;
|
||||
gui->empty_linecount = gui->parent->last_line-gui->parent->first_line+1;
|
||||
gui->bottom = TRUE;
|
||||
gui = WINDOW_GUI(active_win);
|
||||
|
||||
if (is_window_visible(active_win))
|
||||
window_clear(gui);
|
||||
|
||||
gui->ypos = -1;
|
||||
gui->bottom_startline = gui->startline = g_list_last(gui->lines);
|
||||
gui->bottom_subline = gui->subline = gui->last_subline+1;
|
||||
gui->empty_linecount = gui->parent->last_line-gui->parent->first_line+1;
|
||||
gui->bottom = TRUE;
|
||||
}
|
||||
|
||||
static void sig_printtext_finished(WINDOW_REC *window)
|
||||
|
|
@ -321,18 +316,18 @@ static void read_settings(void)
|
|||
|
||||
void gui_printtext_init(void)
|
||||
{
|
||||
signal_add("gui print text", (SIGNAL_FUNC) gui_printtext);
|
||||
command_bind("clear", NULL, (SIGNAL_FUNC) cmd_clear);
|
||||
signal_add("print text finished", (SIGNAL_FUNC) sig_printtext_finished);
|
||||
signal_add("setup changed", (SIGNAL_FUNC) read_settings);
|
||||
signal_add("gui print text", (SIGNAL_FUNC) gui_printtext);
|
||||
signal_add("print text finished", (SIGNAL_FUNC) sig_printtext_finished);
|
||||
signal_add("setup changed", (SIGNAL_FUNC) read_settings);
|
||||
command_bind("clear", NULL, (SIGNAL_FUNC) cmd_clear);
|
||||
|
||||
read_settings();
|
||||
read_settings();
|
||||
}
|
||||
|
||||
void gui_printtext_deinit(void)
|
||||
{
|
||||
signal_remove("gui print text", (SIGNAL_FUNC) gui_printtext);
|
||||
command_unbind("clear", (SIGNAL_FUNC) cmd_clear);
|
||||
signal_remove("print text finished", (SIGNAL_FUNC) sig_printtext_finished);
|
||||
signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
|
||||
signal_remove("gui print text", (SIGNAL_FUNC) gui_printtext);
|
||||
signal_remove("print text finished", (SIGNAL_FUNC) sig_printtext_finished);
|
||||
signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
|
||||
command_unbind("clear", (SIGNAL_FUNC) cmd_clear);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ static GUI_WINDOW_REC *gui_window_init(WINDOW_REC *window, MAIN_WINDOW_REC *pare
|
|||
gui->parent = parent;
|
||||
|
||||
gui->bottom = TRUE;
|
||||
gui->line_cache = g_hash_table_new((GHashFunc) g_direct_hash, (GCompareFunc) g_direct_equal);
|
||||
gui->line_chunk = g_mem_chunk_new("line chunk", sizeof(LINE_REC),
|
||||
sizeof(LINE_REC)*100, G_ALLOC_AND_FREE);
|
||||
gui->empty_linecount = parent->last_line-parent->first_line;
|
||||
|
|
@ -53,8 +54,19 @@ static GUI_WINDOW_REC *gui_window_init(WINDOW_REC *window, MAIN_WINDOW_REC *pare
|
|||
return gui;
|
||||
}
|
||||
|
||||
int line_cache_destroy(void *key, LINE_CACHE_REC *cache)
|
||||
{
|
||||
g_free_not_null(cache->lines);
|
||||
g_free(cache);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void gui_window_deinit(GUI_WINDOW_REC *gui)
|
||||
{
|
||||
g_hash_table_foreach(gui->line_cache, (GHFunc) line_cache_destroy, NULL);
|
||||
g_hash_table_destroy(gui->line_cache);
|
||||
|
||||
g_slist_foreach(gui->text_chunks, (GFunc) g_free, NULL);
|
||||
g_slist_free(gui->text_chunks);
|
||||
|
||||
|
|
@ -106,7 +118,7 @@ static void gui_window_destroyed(WINDOW_REC *window)
|
|||
gui_window_deinit(gui);
|
||||
window->gui_data = NULL;
|
||||
|
||||
if (mainwindows->next != NULL && parent->active == window)
|
||||
if (parent->active == window && mainwindows->next != NULL)
|
||||
mainwindow_destroy(parent);
|
||||
}
|
||||
|
||||
|
|
@ -126,322 +138,337 @@ void gui_window_clear(WINDOW_REC *window)
|
|||
gui_window_redraw(window);
|
||||
}
|
||||
|
||||
int gui_window_update_bottom(GUI_WINDOW_REC *gui, int lines)
|
||||
/* update bottom_startline and bottom_subline of window. */
|
||||
static int gui_window_update_bottom(GUI_WINDOW_REC *gui, int lines)
|
||||
{
|
||||
int linecount, last_linecount;
|
||||
int linecount, last_linecount;
|
||||
|
||||
if (gui->bottom_startline == NULL)
|
||||
return -1;
|
||||
|
||||
while (lines < 0)
|
||||
{
|
||||
if (gui->bottom_subline > 0)
|
||||
gui->bottom_subline--;
|
||||
else
|
||||
{
|
||||
if (gui->bottom_startline->prev == NULL)
|
||||
if (gui->bottom_startline == NULL)
|
||||
return -1;
|
||||
gui->bottom_startline = gui->bottom_startline->prev;
|
||||
|
||||
linecount = gui_window_get_linecount(gui, gui->bottom_startline->data);
|
||||
gui->bottom_subline = linecount-1;
|
||||
}
|
||||
lines++;
|
||||
}
|
||||
|
||||
last_linecount = linecount = -1;
|
||||
while (lines > 0)
|
||||
{
|
||||
if (linecount == -1)
|
||||
last_linecount = linecount = gui_window_get_linecount(gui, gui->bottom_startline->data);
|
||||
|
||||
if (linecount > gui->bottom_subline+1)
|
||||
gui->bottom_subline++;
|
||||
else
|
||||
{
|
||||
gui->bottom_subline = 0;
|
||||
linecount = -1;
|
||||
|
||||
if (gui->bottom_startline->next == NULL)
|
||||
break;
|
||||
gui->bottom_startline = gui->bottom_startline->next;
|
||||
}
|
||||
lines--;
|
||||
}
|
||||
|
||||
return last_linecount;
|
||||
}
|
||||
|
||||
void gui_window_newline(GUI_WINDOW_REC *gui, gboolean visible)
|
||||
{
|
||||
gboolean last_line;
|
||||
gint linecount;
|
||||
|
||||
g_return_if_fail(gui != NULL);
|
||||
|
||||
gui->xpos = 0;
|
||||
last_line = gui->ypos >= gui->parent->last_line-gui->parent->first_line;
|
||||
|
||||
if (gui->empty_linecount > 0)
|
||||
{
|
||||
/* window buffer height isn't even the size of the screen yet */
|
||||
gui->empty_linecount--;
|
||||
linecount = gui_window_get_linecount(gui, gui->startline->data);
|
||||
}
|
||||
else
|
||||
{
|
||||
linecount = gui_window_update_bottom(gui, 1);
|
||||
}
|
||||
|
||||
if (!last_line || !gui->bottom)
|
||||
{
|
||||
gui->ypos++;
|
||||
}
|
||||
else if (gui->bottom)
|
||||
{
|
||||
if (gui->subline >= linecount)
|
||||
{
|
||||
/* after screen gets full after /CLEAR we end up here.. */
|
||||
gui->startline = gui->startline->next;
|
||||
gui->subline = 0;
|
||||
|
||||
linecount = gui_window_update_bottom(gui, 1);
|
||||
}
|
||||
|
||||
if (linecount > 1+gui->subline)
|
||||
gui->subline++;
|
||||
else
|
||||
{
|
||||
gui->startline = gui->startline->next;
|
||||
gui->subline = 0;
|
||||
}
|
||||
|
||||
if (visible)
|
||||
{
|
||||
scroll_up(gui->parent->first_line, gui->parent->last_line);
|
||||
move(gui->parent->last_line, 0); clrtoeol();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* get number of real lines that line record takes - this really should share
|
||||
at least some code with gui_window_line_draw().. */
|
||||
gint gui_window_get_linecount(GUI_WINDOW_REC *gui, LINE_REC *line)
|
||||
{
|
||||
gchar *ptr, *last_space_ptr, *tmp;
|
||||
gint lines, xpos, indent_pos, last_space;
|
||||
|
||||
g_return_val_if_fail(gui != NULL, -1);
|
||||
g_return_val_if_fail(line != NULL, -1);
|
||||
|
||||
if (line->text == NULL)
|
||||
return 0;
|
||||
|
||||
xpos = 0; lines = 1; indent_pos = DEFAULT_INDENT_POS;
|
||||
last_space = 0; last_space_ptr = NULL;
|
||||
for (ptr = line->text;; ptr++)
|
||||
{
|
||||
if (*ptr == '\0')
|
||||
{
|
||||
/* command */
|
||||
ptr++;
|
||||
switch ((guchar) *ptr)
|
||||
{
|
||||
case LINE_CMD_OVERFLOW:
|
||||
g_error("buffer overflow!");
|
||||
case LINE_CMD_EOL:
|
||||
return lines;
|
||||
case LINE_CMD_CONTINUE:
|
||||
memcpy(&tmp, ptr+1, sizeof(gchar *));
|
||||
ptr = tmp-1;
|
||||
break;
|
||||
case LINE_CMD_INDENT:
|
||||
indent_pos = xpos;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (xpos == COLS)
|
||||
{
|
||||
xpos = indent_pos >= COLS-5 ? DEFAULT_INDENT_POS : indent_pos;
|
||||
|
||||
if (last_space > indent_pos && last_space > 10)
|
||||
{
|
||||
ptr = last_space_ptr;
|
||||
while (*ptr == ' ') ptr++;
|
||||
}
|
||||
|
||||
last_space = 0;
|
||||
lines++;
|
||||
ptr--;
|
||||
continue;
|
||||
}
|
||||
|
||||
xpos++;
|
||||
if (*ptr == ' ')
|
||||
{
|
||||
last_space = xpos-1;
|
||||
last_space_ptr = ptr+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* draw line - ugly code.. */
|
||||
gint gui_window_line_draw(GUI_WINDOW_REC *gui, LINE_REC *line, gint ypos, gint skip, gint max)
|
||||
{
|
||||
gchar *ptr, *last_space_ptr, *tmp;
|
||||
gint lines, xpos, color, indent_pos, last_space, last_space_color;
|
||||
|
||||
g_return_val_if_fail(gui != NULL, -1);
|
||||
g_return_val_if_fail(line != NULL, -1);
|
||||
|
||||
if (line->text == NULL)
|
||||
return 0;
|
||||
|
||||
move(ypos, 0);
|
||||
xpos = 0; color = 0; lines = -1; indent_pos = DEFAULT_INDENT_POS;
|
||||
last_space = last_space_color = 0; last_space_ptr = NULL;
|
||||
for (ptr = line->text;; ptr++)
|
||||
{
|
||||
if (*ptr == '\0')
|
||||
{
|
||||
/* command */
|
||||
ptr++;
|
||||
if ((*ptr & 0x80) == 0)
|
||||
{
|
||||
/* set color */
|
||||
color = (color & ATTR_UNDERLINE) | *ptr;
|
||||
}
|
||||
else switch ((guchar) *ptr)
|
||||
{
|
||||
case LINE_CMD_OVERFLOW:
|
||||
g_error("buffer overflow!");
|
||||
case LINE_CMD_EOL:
|
||||
return lines;
|
||||
case LINE_CMD_CONTINUE:
|
||||
memcpy(&tmp, ptr+1, sizeof(gchar *));
|
||||
ptr = tmp-1;
|
||||
break;
|
||||
case LINE_CMD_UNDERLINE:
|
||||
color ^= ATTR_UNDERLINE;
|
||||
break;
|
||||
case LINE_CMD_COLOR8:
|
||||
color &= 0xfff0;
|
||||
color |= 8|ATTR_COLOR8;
|
||||
break;
|
||||
case LINE_CMD_BEEP:
|
||||
beep();
|
||||
break;
|
||||
case LINE_CMD_INDENT:
|
||||
indent_pos = xpos;
|
||||
break;
|
||||
}
|
||||
set_color(color);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (xpos == COLS)
|
||||
{
|
||||
xpos = indent_pos >= COLS-5 ? DEFAULT_INDENT_POS : indent_pos;
|
||||
|
||||
if (last_space > indent_pos && last_space > 10)
|
||||
{
|
||||
/* remove the last word */
|
||||
if (!skip)
|
||||
{
|
||||
move(ypos, last_space);
|
||||
set_color(0);
|
||||
clrtoeol();
|
||||
for (; lines < 0; lines++) {
|
||||
if (gui->bottom_subline > 0) {
|
||||
gui->bottom_subline--;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* skip backwards to draw the line again. */
|
||||
ptr = last_space_ptr;
|
||||
color = last_space_color;
|
||||
if (!skip) set_color(color);
|
||||
while (*ptr == ' ') ptr++;
|
||||
}
|
||||
last_space = 0;
|
||||
if (gui->bottom_startline->prev == NULL)
|
||||
return -1;
|
||||
gui->bottom_startline = gui->bottom_startline->prev;
|
||||
|
||||
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;
|
||||
linecount = gui_window_get_linecount(gui, gui->bottom_startline->data);
|
||||
gui->bottom_subline = linecount-1;
|
||||
}
|
||||
|
||||
last_linecount = -1;
|
||||
for (; lines > 0; lines--) {
|
||||
last_linecount = linecount =
|
||||
gui_window_get_linecount(gui, gui->bottom_startline->data);
|
||||
|
||||
if (linecount > gui->bottom_subline+1)
|
||||
gui->bottom_subline++;
|
||||
else {
|
||||
gui->bottom_subline = 0;
|
||||
if (gui->bottom_startline->next == NULL)
|
||||
break;
|
||||
gui->bottom_startline = gui->bottom_startline->next;
|
||||
}
|
||||
lines++;
|
||||
}
|
||||
move(ypos, indent_pos);
|
||||
|
||||
/* we could have \0.. */
|
||||
ptr--;
|
||||
continue;
|
||||
lines--;
|
||||
}
|
||||
|
||||
xpos++;
|
||||
if (*ptr == ' ')
|
||||
{
|
||||
last_space = xpos-1;
|
||||
last_space_color = color;
|
||||
last_space_ptr = ptr+1;
|
||||
return last_linecount;
|
||||
}
|
||||
|
||||
void gui_window_newline(GUI_WINDOW_REC *gui, int visible)
|
||||
{
|
||||
int lines;
|
||||
|
||||
g_return_if_fail(gui != NULL);
|
||||
|
||||
gui->xpos = 0;
|
||||
|
||||
if (gui->empty_linecount > 0) {
|
||||
/* window buffer height isn't even the size of the screen yet */
|
||||
gui->empty_linecount--;
|
||||
gui->ypos++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (skip) continue;
|
||||
if (lines == -1) lines = 0;
|
||||
lines = gui_window_update_bottom(gui, 1);
|
||||
|
||||
if ((guchar) *ptr >= 32)
|
||||
addch((guchar) *ptr);
|
||||
else
|
||||
{
|
||||
/* low-ascii */
|
||||
set_color(ATTR_REVERSE);
|
||||
addch(*ptr+'A'-1);
|
||||
set_color(color);
|
||||
if (!gui->bottom) {
|
||||
gui->ypos++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (gui->subline >= lines) {
|
||||
/* after screen gets full after /CLEAR we end up here.. */
|
||||
gui->startline = gui->startline->next;
|
||||
gui->subline = 0;
|
||||
|
||||
lines = gui_window_update_bottom(gui, 1);
|
||||
}
|
||||
|
||||
if (lines > 1+gui->subline)
|
||||
gui->subline++;
|
||||
else {
|
||||
gui->startline = gui->startline->next;
|
||||
gui->subline = 0;
|
||||
}
|
||||
|
||||
if (visible) {
|
||||
scroll_up(gui->parent->first_line, gui->parent->last_line);
|
||||
move(gui->parent->last_line, 0); clrtoeol();
|
||||
}
|
||||
}
|
||||
|
||||
static LINE_CACHE_REC *gui_window_line_cache(GUI_WINDOW_REC *gui, LINE_REC *line)
|
||||
{
|
||||
LINE_CACHE_REC *rec;
|
||||
LINE_CACHE_SUB_REC *sub;
|
||||
GSList *lines;
|
||||
unsigned char *ptr, *last_space_ptr;
|
||||
int xpos, pos, indent_pos, last_space, color;
|
||||
|
||||
g_return_val_if_fail(line->text != NULL, NULL);
|
||||
|
||||
rec = g_new(LINE_CACHE_REC, 1);
|
||||
|
||||
xpos = 0; color = 0; indent_pos = DEFAULT_INDENT_POS;
|
||||
last_space = 0; last_space_ptr = NULL;
|
||||
|
||||
rec->count = 1; lines = NULL;
|
||||
for (ptr = (unsigned char *) line->text;;) {
|
||||
if (*ptr == '\0') {
|
||||
/* command */
|
||||
ptr++;
|
||||
if (*ptr == LINE_CMD_EOL)
|
||||
break;
|
||||
|
||||
if (*ptr == LINE_CMD_CONTINUE) {
|
||||
char *tmp;
|
||||
|
||||
memcpy(&tmp, ptr+1, sizeof(char *));
|
||||
ptr = tmp;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((*ptr & 0x80) == 0) {
|
||||
/* set color */
|
||||
color = (color & ATTR_UNDERLINE) | *ptr;
|
||||
} else switch (*ptr) {
|
||||
case LINE_CMD_OVERFLOW:
|
||||
g_error("buffer overflow!");
|
||||
case LINE_CMD_UNDERLINE:
|
||||
color ^= ATTR_UNDERLINE;
|
||||
break;
|
||||
case LINE_CMD_COLOR8:
|
||||
color &= 0xfff0;
|
||||
color |= 8|ATTR_COLOR8;
|
||||
break;
|
||||
case LINE_CMD_INDENT:
|
||||
/* set indentation position here - don't do
|
||||
it if we're too close to right border */
|
||||
if (xpos < COLS-5) indent_pos = xpos;
|
||||
break;
|
||||
}
|
||||
|
||||
ptr++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (xpos == COLS) {
|
||||
xpos = indent_pos;
|
||||
|
||||
if (last_space > indent_pos && last_space > 10) {
|
||||
/* go back to last space */
|
||||
ptr = last_space_ptr;
|
||||
while (*ptr == ' ') ptr++;
|
||||
}
|
||||
|
||||
sub = g_new(LINE_CACHE_SUB_REC, 1);
|
||||
sub->start = ptr;
|
||||
sub->indent = indent_pos;
|
||||
sub->color = color;
|
||||
|
||||
lines = g_slist_append(lines, sub);
|
||||
rec->count++;
|
||||
|
||||
last_space = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
xpos++;
|
||||
if (*ptr++ == ' ') {
|
||||
last_space = xpos-1;
|
||||
last_space_ptr = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (rec->count < 2)
|
||||
rec->lines = NULL;
|
||||
else {
|
||||
rec->lines = g_new(LINE_CACHE_SUB_REC, rec->count-1);
|
||||
for (pos = 0; lines != NULL; pos++) {
|
||||
memcpy(&rec->lines[pos], lines->data, sizeof(LINE_CACHE_SUB_REC));
|
||||
|
||||
g_free(lines->data);
|
||||
lines = g_slist_remove(lines, lines->data);
|
||||
}
|
||||
}
|
||||
|
||||
g_hash_table_insert(gui->line_cache, line, rec);
|
||||
return rec;
|
||||
}
|
||||
|
||||
void gui_window_cache_remove(GUI_WINDOW_REC *gui, LINE_REC *line)
|
||||
{
|
||||
LINE_CACHE_REC *cache;
|
||||
|
||||
g_return_if_fail(gui != NULL);
|
||||
g_return_if_fail(line != NULL);
|
||||
|
||||
cache = g_hash_table_lookup(gui->line_cache, line);
|
||||
if (cache != NULL) {
|
||||
g_hash_table_remove(gui->line_cache, line);
|
||||
g_free_not_null(cache->lines);
|
||||
g_free(cache);
|
||||
}
|
||||
}
|
||||
|
||||
int gui_window_get_linecount(GUI_WINDOW_REC *gui, LINE_REC *line)
|
||||
{
|
||||
LINE_CACHE_REC *cache;
|
||||
|
||||
g_return_val_if_fail(gui != NULL, -1);
|
||||
g_return_val_if_fail(line != NULL, -1);
|
||||
|
||||
cache = g_hash_table_lookup(gui->line_cache, line);
|
||||
if (cache == NULL)
|
||||
cache = gui_window_line_cache(gui, line);
|
||||
|
||||
return cache->count;
|
||||
}
|
||||
|
||||
static void single_line_draw(GUI_WINDOW_REC *gui, int ypos, LINE_CACHE_SUB_REC *rec, const char *text, const char *text_end)
|
||||
{
|
||||
char *tmp;
|
||||
int xpos, color;
|
||||
|
||||
if (rec == NULL) {
|
||||
xpos = 0; color = 0;
|
||||
} else {
|
||||
xpos = rec->indent;
|
||||
color = rec->color;
|
||||
}
|
||||
|
||||
move(ypos, xpos);
|
||||
while (text != text_end) {
|
||||
if (*text == '\0') {
|
||||
/* command */
|
||||
text++;
|
||||
if ((*text & 0x80) == 0) {
|
||||
/* set color */
|
||||
color = (color & ATTR_UNDERLINE) | *text;
|
||||
} else if (*text == (char) LINE_CMD_CONTINUE) {
|
||||
/* jump to next block */
|
||||
memcpy(&tmp, text+1, sizeof(char *));
|
||||
text = tmp;
|
||||
continue;
|
||||
} else switch ((unsigned char) *text) {
|
||||
case LINE_CMD_OVERFLOW:
|
||||
g_error("buffer overflow!");
|
||||
case LINE_CMD_EOL:
|
||||
return;
|
||||
case LINE_CMD_UNDERLINE:
|
||||
color ^= ATTR_UNDERLINE;
|
||||
break;
|
||||
case LINE_CMD_COLOR8:
|
||||
color &= 0xfff0;
|
||||
color |= 8|ATTR_COLOR8;
|
||||
break;
|
||||
}
|
||||
set_color(color);
|
||||
text++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (xpos == COLS) {
|
||||
/* there should be only spaces left */
|
||||
text++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((unsigned char) *text >= 32)
|
||||
addch((unsigned char) *text);
|
||||
else {
|
||||
/* low-ascii */
|
||||
set_color(ATTR_REVERSE);
|
||||
addch(*text+'A'-1);
|
||||
set_color(color);
|
||||
}
|
||||
text++;
|
||||
}
|
||||
}
|
||||
|
||||
int gui_window_line_draw(GUI_WINDOW_REC *gui, LINE_REC *line, int ypos, int skip, int max)
|
||||
{
|
||||
LINE_CACHE_REC *cache;
|
||||
LINE_CACHE_SUB_REC *sub;
|
||||
char *pos, *next_pos;
|
||||
int n;
|
||||
|
||||
g_return_val_if_fail(gui != NULL, -1);
|
||||
g_return_val_if_fail(line != NULL, -1);
|
||||
|
||||
cache = g_hash_table_lookup(gui->line_cache, line);
|
||||
if (cache == NULL)
|
||||
cache = gui_window_line_cache(gui, line);
|
||||
|
||||
if (max < 0) max = cache->count;
|
||||
|
||||
for (n = skip; n < cache->count && max > 0; n++, ypos++, max--) {
|
||||
sub = n == 0 ? NULL : &cache->lines[n-1];
|
||||
pos = sub == NULL ? line->text : sub->start;
|
||||
next_pos = (n+1 < cache->count) ?
|
||||
cache->lines[n].start : NULL;
|
||||
single_line_draw(gui, ypos, sub, pos, next_pos);
|
||||
}
|
||||
|
||||
return cache->count;
|
||||
}
|
||||
|
||||
void gui_window_redraw(WINDOW_REC *window)
|
||||
{
|
||||
GUI_WINDOW_REC *gui;
|
||||
GList *line;
|
||||
gint ypos, lines, skip, max;
|
||||
GUI_WINDOW_REC *gui;
|
||||
GList *line;
|
||||
int ypos, lines, skip, max;
|
||||
|
||||
g_return_if_fail(window != NULL);
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
gui = WINDOW_GUI(window);
|
||||
gui = WINDOW_GUI(window);
|
||||
|
||||
for (ypos = gui->parent->first_line; ypos <= gui->parent->last_line; ypos++)
|
||||
{
|
||||
/* clear the lines first */
|
||||
set_color(0);
|
||||
move(ypos, 0);
|
||||
clrtoeol();
|
||||
}
|
||||
for (ypos = gui->parent->first_line; ypos <= gui->parent->last_line; ypos++) {
|
||||
move(ypos, 0);
|
||||
clrtoeol();
|
||||
}
|
||||
|
||||
skip = gui->subline;
|
||||
ypos = gui->parent->first_line;
|
||||
for (line = gui->startline; line != NULL; line = line->next)
|
||||
{
|
||||
LINE_REC *rec = line->data;
|
||||
skip = gui->subline;
|
||||
ypos = gui->parent->first_line;
|
||||
for (line = gui->startline; line != NULL; line = line->next) {
|
||||
LINE_REC *rec = line->data;
|
||||
|
||||
max = gui->parent->last_line - ypos;
|
||||
if (max < 0) break;
|
||||
max = gui->parent->last_line - ypos+1;
|
||||
if (max < 0) break;
|
||||
|
||||
lines = gui_window_line_draw(gui, rec, ypos, skip, max);
|
||||
skip = 0;
|
||||
lines = gui_window_line_draw(gui, rec, ypos, skip, max);
|
||||
ypos += lines-skip;
|
||||
skip = 0;
|
||||
}
|
||||
|
||||
ypos += lines+1;
|
||||
}
|
||||
screen_refresh();
|
||||
screen_refresh();
|
||||
}
|
||||
|
||||
static void gui_window_scroll_up(GUI_WINDOW_REC *gui, gint lines)
|
||||
|
|
@ -579,6 +606,8 @@ static void signal_window_changed(WINDOW_REC *window)
|
|||
{
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
if (quitting) return;
|
||||
|
||||
if (is_window_visible(window)) {
|
||||
/* already visible, great! */
|
||||
active_mainwin = WINDOW_GUI(window)->parent;
|
||||
|
|
@ -674,6 +703,8 @@ static void gui_window_horiz_resize(WINDOW_REC *window)
|
|||
gui = WINDOW_GUI(window);
|
||||
if (gui->lines == NULL) return;
|
||||
|
||||
g_hash_table_foreach_remove(gui->line_cache, (GHRFunc) line_cache_destroy, NULL);
|
||||
|
||||
linecount = gui_window_get_linecount(gui, g_list_last(gui->lines)->data);
|
||||
gui->last_subline = linecount-1;
|
||||
|
||||
|
|
@ -703,7 +734,8 @@ void gui_window_resize(WINDOW_REC *window, int ychange, int xchange)
|
|||
gui = WINDOW_GUI(window);
|
||||
|
||||
if (xchange) {
|
||||
/* window width changed, we'll need to recalculate a few things.. */
|
||||
/* window width changed, we'll need to recalculate a
|
||||
few things.. */
|
||||
gui_window_horiz_resize(window);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -23,11 +23,13 @@
|
|||
|
||||
FORMAT_REC gui_text_formats[] =
|
||||
{
|
||||
{ MODULE_NAME, "Text user interface", 0 },
|
||||
{ MODULE_NAME, "Text user interface", 0 },
|
||||
|
||||
{ "lastlog_start", "%_Lastlog:", 0 },
|
||||
{ "lastlog_end", "%_End of Lastlog", 0 },
|
||||
{ "lastlog_start", "%_Lastlog:", 0 },
|
||||
{ "lastlog_end", "%_End of Lastlog", 0 },
|
||||
|
||||
{ "window_too_small", "Not enough room to resize this window", 0 },
|
||||
{ "cant_hide_last", "You can't hide the last window", 0 }
|
||||
{ "window_too_small", "Not enough room to resize this window", 0 },
|
||||
{ "cant_hide_last", "You can't hide the last window", 0 },
|
||||
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -11,6 +11,3 @@ enum {
|
|||
};
|
||||
|
||||
extern FORMAT_REC gui_text_formats[];
|
||||
#define MODULE_FORMATS gui_text_formats
|
||||
|
||||
#include "printformat.h"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue