mirror of
https://github.com/irssi/irssi.git
synced 2026-08-10 12:23:37 +02:00
..adding new files..
git-svn-id: http://svn.irssi.org/repos/irssi/trunk@171 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
parent
d01b094151
commit
c95034c6de
206 changed files with 31247 additions and 0 deletions
46
src/fe-text/Makefile.am
Normal file
46
src/fe-text/Makefile.am
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
bin_PROGRAMS = irssi-text
|
||||
|
||||
INCLUDES = \
|
||||
$(GLIB_CFLAGS) \
|
||||
-I$(top_srcdir)/src \
|
||||
-I$(top_srcdir)/src/core/ \
|
||||
-I$(top_srcdir)/src/irc/core/ \
|
||||
-I$(top_srcdir)/src/fe-common/core/ \
|
||||
-I$(top_srcdir)/src/fe-common/irc/ \
|
||||
$(CURSES_INCLUDEDIR)
|
||||
|
||||
irssi_text_DEPENDENCIES = @COMMON_LIBS@
|
||||
|
||||
irssi_text_LDADD = \
|
||||
@COMMON_LIBS@ \
|
||||
$(PROG_LIBS) \
|
||||
$(CURSES_LIBS) \
|
||||
$(INTLLIBS) \
|
||||
$(PERL_LDFLAGS)
|
||||
|
||||
irssi_text_SOURCES = \
|
||||
gui-entry.c \
|
||||
gui-mainwindows.c \
|
||||
gui-printtext.c \
|
||||
gui-readline.c \
|
||||
gui-special-vars.c \
|
||||
gui-statusbar.c \
|
||||
gui-statusbar-items.c \
|
||||
gui-textwidget.c \
|
||||
gui-windows.c \
|
||||
irssi.c \
|
||||
module-formats.c \
|
||||
screen.c
|
||||
|
||||
noinst_HEADERS = \
|
||||
gui-entry.h \
|
||||
gui-mainwindows.h \
|
||||
gui-printtext.h \
|
||||
gui-readline.h \
|
||||
gui-special-vars.h \
|
||||
gui-statusbar.h \
|
||||
gui-statusbar-items.h \
|
||||
gui-textwidget.h \
|
||||
gui-windows.h \
|
||||
module-formats.h \
|
||||
screen.h
|
||||
177
src/fe-text/gui-entry.c
Normal file
177
src/fe-text/gui-entry.c
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
gui-entry.c : irssi
|
||||
|
||||
Copyright (C) 1999 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 "screen.h"
|
||||
|
||||
static GString *entry;
|
||||
static int promptlen, pos, scrstart, scrpos;
|
||||
static char *prompt;
|
||||
|
||||
static void entry_screenpos(void)
|
||||
{
|
||||
if (pos-scrstart < COLS-1-promptlen && pos-scrstart > 0) {
|
||||
scrpos = pos-scrstart;
|
||||
return;
|
||||
}
|
||||
|
||||
if (pos < COLS-1-promptlen) {
|
||||
scrstart = 0;
|
||||
scrpos = pos;
|
||||
} else {
|
||||
scrpos = COLS-1-promptlen;
|
||||
scrstart = pos-scrpos;
|
||||
}
|
||||
}
|
||||
|
||||
static void entry_update(void)
|
||||
{
|
||||
char *p;
|
||||
int n, len;
|
||||
|
||||
len = entry->len-scrstart > COLS-promptlen ?
|
||||
COLS-promptlen : entry->len-scrstart;
|
||||
|
||||
set_color(0);
|
||||
move(LINES-1, promptlen);
|
||||
|
||||
for (p = entry->str+scrstart, n = 0; n < len; n++, p++) {
|
||||
if ((unsigned char) *p >= 32)
|
||||
addch((unsigned char) *p);
|
||||
else {
|
||||
set_color(ATTR_REVERSE);
|
||||
addch(*p+'A'-1);
|
||||
set_color(0);
|
||||
}
|
||||
}
|
||||
clrtoeol();
|
||||
|
||||
move_cursor(LINES-1, scrpos+promptlen);
|
||||
screen_refresh();
|
||||
}
|
||||
|
||||
void gui_entry_set_prompt(const char *str)
|
||||
{
|
||||
if (str != NULL) {
|
||||
if (prompt != NULL) g_free(prompt);
|
||||
prompt = g_strdup(str);
|
||||
|
||||
promptlen = strlen(prompt);
|
||||
if (promptlen > 20) {
|
||||
promptlen = 20;
|
||||
prompt[20] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
set_color(0);
|
||||
mvaddstr(LINES-1, 0, prompt);
|
||||
|
||||
entry_screenpos();
|
||||
entry_update();
|
||||
}
|
||||
|
||||
void gui_entry_set_text(const char *str)
|
||||
{
|
||||
g_return_if_fail(str != NULL);
|
||||
|
||||
g_string_assign(entry, str);
|
||||
pos = entry->len;
|
||||
|
||||
entry_screenpos();
|
||||
entry_update();
|
||||
}
|
||||
|
||||
char *gui_entry_get_text(void)
|
||||
{
|
||||
return entry->str;
|
||||
}
|
||||
|
||||
void gui_entry_insert_text(const char *str)
|
||||
{
|
||||
g_return_if_fail(str != NULL);
|
||||
|
||||
g_string_insert(entry, pos, str);
|
||||
pos += strlen(str);
|
||||
|
||||
entry_screenpos();
|
||||
entry_update();
|
||||
}
|
||||
|
||||
void gui_entry_insert_char(char chr)
|
||||
{
|
||||
g_string_insert_c(entry, pos, chr);
|
||||
pos++;
|
||||
|
||||
entry_screenpos();
|
||||
entry_update();
|
||||
}
|
||||
|
||||
void gui_entry_erase(int size)
|
||||
{
|
||||
if (pos < size) return;
|
||||
|
||||
pos -= size;
|
||||
g_string_erase(entry, pos, size);
|
||||
|
||||
entry_screenpos();
|
||||
entry_update();
|
||||
}
|
||||
|
||||
int gui_entry_get_pos(void)
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
|
||||
void gui_entry_set_pos(int p)
|
||||
{
|
||||
if (p >= 0 && p <= entry->len)
|
||||
pos = p;
|
||||
}
|
||||
|
||||
void gui_entry_move_pos(int p)
|
||||
{
|
||||
if (pos+p >= 0 && pos+p <= entry->len)
|
||||
pos += p;
|
||||
|
||||
entry_screenpos();
|
||||
entry_update();
|
||||
}
|
||||
|
||||
void gui_entry_redraw(void)
|
||||
{
|
||||
gui_entry_set_prompt(NULL);
|
||||
|
||||
entry_screenpos();
|
||||
entry_update();
|
||||
}
|
||||
|
||||
void gui_entry_init(void)
|
||||
{
|
||||
entry = g_string_new(NULL);
|
||||
pos = scrpos = 0;
|
||||
prompt = NULL; promptlen = 0;
|
||||
}
|
||||
|
||||
void gui_entry_deinit(void)
|
||||
{
|
||||
if (prompt != NULL) g_free(prompt);
|
||||
g_string_free(entry, TRUE);
|
||||
}
|
||||
22
src/fe-text/gui-entry.h
Normal file
22
src/fe-text/gui-entry.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef __GUI_ENTRY_H
|
||||
#define __GUI_ENTRY_H
|
||||
|
||||
void gui_entry_set_prompt(const char *str);
|
||||
|
||||
void gui_entry_set_text(const char *str);
|
||||
char *gui_entry_get_text(void);
|
||||
|
||||
void gui_entry_insert_text(const char *str);
|
||||
void gui_entry_insert_char(char chr);
|
||||
void gui_entry_erase(int size);
|
||||
|
||||
int gui_entry_get_pos(void);
|
||||
void gui_entry_set_pos(int pos);
|
||||
void gui_entry_move_pos(int pos);
|
||||
|
||||
void gui_entry_redraw(void);
|
||||
|
||||
void gui_entry_init(void);
|
||||
void gui_entry_deinit(void);
|
||||
|
||||
#endif
|
||||
66
src/fe-text/gui-mainwindows.c
Normal file
66
src/fe-text/gui-mainwindows.c
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
gui-mainwindows.c : irssi
|
||||
|
||||
Copyright (C) 1999 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 "windows.h"
|
||||
#include "gui-mainwindows.h"
|
||||
|
||||
GList *mainwindows;
|
||||
|
||||
MAIN_WINDOW_REC *gui_mainwindow_create(void)
|
||||
{
|
||||
MAIN_WINDOW_REC *window;
|
||||
|
||||
window = g_new0(MAIN_WINDOW_REC, 1);
|
||||
mainwindows = g_list_append(mainwindows, window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
void gui_mainwindow_destroy(MAIN_WINDOW_REC *window)
|
||||
{
|
||||
g_return_if_fail(window != NULL);
|
||||
if (window->destroying) return;
|
||||
|
||||
mainwindows = g_list_remove(mainwindows, window);
|
||||
|
||||
window->destroying = TRUE;
|
||||
while (window->children != NULL)
|
||||
window_destroy(window->children->data);
|
||||
window->destroying = FALSE;
|
||||
|
||||
g_free(window);
|
||||
|
||||
if (mainwindows == NULL)
|
||||
signal_emit("gui exit", 0);
|
||||
}
|
||||
|
||||
void gui_mainwindows_init(void)
|
||||
{
|
||||
mainwindows = NULL;
|
||||
}
|
||||
|
||||
void gui_mainwindows_deinit(void)
|
||||
{
|
||||
while (mainwindows != NULL)
|
||||
gui_mainwindow_destroy(mainwindows->data);
|
||||
}
|
||||
21
src/fe-text/gui-mainwindows.h
Normal file
21
src/fe-text/gui-mainwindows.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef __GUI_MAINWINDOWS_H
|
||||
#define __GUI_MAINWINDOWS_H
|
||||
|
||||
#include "windows.h"
|
||||
|
||||
typedef struct {
|
||||
WINDOW_REC *active;
|
||||
GList *children;
|
||||
|
||||
int destroying;
|
||||
} MAIN_WINDOW_REC;
|
||||
|
||||
extern GList *mainwindows;
|
||||
|
||||
void gui_mainwindows_init(void);
|
||||
void gui_mainwindows_deinit(void);
|
||||
|
||||
MAIN_WINDOW_REC *gui_mainwindow_create(void);
|
||||
void gui_mainwindow_destroy(MAIN_WINDOW_REC *window);
|
||||
|
||||
#endif
|
||||
334
src/fe-text/gui-printtext.c
Normal file
334
src/fe-text/gui-printtext.c
Normal file
|
|
@ -0,0 +1,334 @@
|
|||
/*
|
||||
gui-printtext.c : irssi
|
||||
|
||||
Copyright (C) 1999 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 "commands.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include "printtext.h"
|
||||
#include "windows.h"
|
||||
#include "themes.h"
|
||||
|
||||
#include "screen.h"
|
||||
#include "gui-mainwindows.h"
|
||||
#include "gui-windows.h"
|
||||
|
||||
#define TEXT_CHUNK_USABLE_SIZE (LINE_TEXT_CHUNK_SIZE-2-sizeof(char*))
|
||||
|
||||
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)
|
||||
{
|
||||
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->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;
|
||||
}
|
||||
|
||||
static TEXT_CHUNK_REC *create_text_chunk(GUI_WINDOW_REC *gui)
|
||||
{
|
||||
TEXT_CHUNK_REC *rec;
|
||||
guchar *buffer;
|
||||
gchar *ptr;
|
||||
|
||||
g_return_val_if_fail(gui != NULL, NULL);
|
||||
|
||||
rec = g_new(TEXT_CHUNK_REC, 1);
|
||||
rec->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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
gui->text_chunks = g_slist_remove(gui->text_chunks, chunk);
|
||||
g_free(chunk);
|
||||
}
|
||||
|
||||
static void remove_first_line(WINDOW_REC *window)
|
||||
{
|
||||
GUI_WINDOW_REC *gui;
|
||||
TEXT_CHUNK_REC *chunk;
|
||||
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
gui = WINDOW_GUI(window);
|
||||
chunk = gui->text_chunks->data;
|
||||
|
||||
if (--chunk->lines == 0)
|
||||
text_chunk_free(gui, chunk);
|
||||
|
||||
if (gui->startline->prev == NULL)
|
||||
{
|
||||
gui->startline = gui->startline->next;
|
||||
gui->subline = 0;
|
||||
}
|
||||
if (gui->bottom_startline->prev == NULL)
|
||||
{
|
||||
gui->bottom_startline = gui->bottom_startline->next;
|
||||
gui->bottom_subline = 0;
|
||||
}
|
||||
|
||||
window->lines--;
|
||||
g_mem_chunk_free(gui->line_chunk, gui->lines->data);
|
||||
gui->lines = g_list_remove(gui->lines, gui->lines->data);
|
||||
|
||||
if (gui->startline->prev == NULL && is_window_visible(window))
|
||||
gui_window_redraw(window);
|
||||
}
|
||||
|
||||
static void get_colors(gint flags, gint *fg, gint *bg)
|
||||
{
|
||||
if (flags & PRINTFLAG_MIRC_COLOR)
|
||||
{
|
||||
/* mirc colors */
|
||||
*fg = *fg < 0 || *fg > 16 ?
|
||||
current_theme->default_color : mirc_colors[*fg];
|
||||
*bg = *bg < 0 || *bg > 16 ? 0 : mirc_colors[*bg];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* default colors */
|
||||
*fg = *fg < 0 || *fg > 15 ?
|
||||
current_theme->default_color : *fg;
|
||||
*bg = *bg < 0 || *bg > 15 ? 0 : *bg;
|
||||
|
||||
if (*fg > 8) *fg -= 8;
|
||||
}
|
||||
|
||||
if (flags & PRINTFLAG_REVERSE)
|
||||
{
|
||||
gint tmp;
|
||||
|
||||
tmp = *fg; *fg = *bg; *bg = tmp;
|
||||
}
|
||||
|
||||
if (*fg == 8) *fg |= ATTR_COLOR8;
|
||||
if (flags & PRINTFLAG_BOLD) *fg |= 8;
|
||||
if (flags & PRINTFLAG_UNDERLINE) *fg |= ATTR_UNDERLINE;
|
||||
if (flags & PRINTFLAG_BLINK) *bg |= 0x80;
|
||||
}
|
||||
|
||||
static void linebuf_add(GUI_WINDOW_REC *gui, gchar *str, gint len)
|
||||
{
|
||||
gint left;
|
||||
|
||||
if (len == 0) return;
|
||||
|
||||
while (gui->cur_text->pos+len >= TEXT_CHUNK_USABLE_SIZE)
|
||||
{
|
||||
left = TEXT_CHUNK_USABLE_SIZE-gui->cur_text->pos;
|
||||
if (str[left-1] == 0) left--; /* don't split the command! */
|
||||
memcpy(gui->cur_text->buffer+gui->cur_text->pos, str, left);
|
||||
gui->cur_text->pos += left;
|
||||
create_text_chunk(gui);
|
||||
len -= left; str += left;
|
||||
}
|
||||
|
||||
memcpy(gui->cur_text->buffer+gui->cur_text->pos, str, len);
|
||||
gui->cur_text->pos += len;
|
||||
}
|
||||
|
||||
static void line_add_colors(GUI_WINDOW_REC *gui, gint fg, gint bg, gint flags)
|
||||
{
|
||||
guchar buffer[12];
|
||||
gint color, pos;
|
||||
|
||||
color = (fg & 0x0f) | (bg << 4);
|
||||
pos = 0;
|
||||
|
||||
if (((fg & ATTR_COLOR8) == 0 && (fg|(bg << 4)) != gui->last_color) ||
|
||||
((fg & ATTR_COLOR8) && (fg & 0xf0) != (gui->last_color & 0xf0)))
|
||||
{
|
||||
buffer[pos++] = 0;
|
||||
buffer[pos++] = (gchar) color;
|
||||
}
|
||||
|
||||
if ((flags & PRINTFLAG_UNDERLINE) != (gui->last_flags & PRINTFLAG_UNDERLINE))
|
||||
{
|
||||
buffer[pos++] = 0;
|
||||
buffer[pos++] = LINE_CMD_UNDERLINE;
|
||||
}
|
||||
if (fg & ATTR_COLOR8)
|
||||
{
|
||||
buffer[pos++] = 0;
|
||||
buffer[pos++] = LINE_CMD_COLOR8;
|
||||
}
|
||||
if (flags & PRINTFLAG_BEEP)
|
||||
{
|
||||
buffer[pos++] = 0;
|
||||
buffer[pos++] = LINE_CMD_BEEP;
|
||||
}
|
||||
if (flags & PRINTFLAG_INDENT)
|
||||
{
|
||||
buffer[pos++] = 0;
|
||||
buffer[pos++] = LINE_CMD_INDENT;
|
||||
}
|
||||
|
||||
linebuf_add(gui, (gchar *) buffer, pos);
|
||||
|
||||
gui->last_flags = flags;
|
||||
gui->last_color = fg | (bg << 4);
|
||||
}
|
||||
|
||||
static void gui_printtext(WINDOW_REC *window, gpointer fgcolor, gpointer bgcolor, gpointer pflags, gchar *str, gpointer level)
|
||||
{
|
||||
GUI_WINDOW_REC *gui;
|
||||
LINE_REC *line;
|
||||
gboolean visible;
|
||||
gint fg, bg, flags, lines, n;
|
||||
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
gui = WINDOW_GUI(window);
|
||||
if (max_textwidget_lines > 0 && max_textwidget_lines <= window->lines)
|
||||
remove_first_line(window);
|
||||
|
||||
visible = is_window_visible(window) && gui->bottom;
|
||||
flags = GPOINTER_TO_INT(pflags);
|
||||
fg = GPOINTER_TO_INT(fgcolor);
|
||||
bg = GPOINTER_TO_INT(bgcolor);
|
||||
|
||||
if (gui->cur_text == NULL)
|
||||
create_text_chunk(gui);
|
||||
|
||||
/* \n can be only at the start of the line.. */
|
||||
if (*str == '\n')
|
||||
{
|
||||
linebuf_add(gui, "\0\x80", 2); /* mark EOL */
|
||||
line = create_line(gui, 0);
|
||||
gui_window_newline(gui, visible);
|
||||
str++;
|
||||
gui->cur_text->lines++;
|
||||
gui->last_subline = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
line = gui->cur_line != NULL ? gui->cur_line :
|
||||
create_line(gui, 0);
|
||||
if (line->level == 0) line->level = GPOINTER_TO_INT(level);
|
||||
}
|
||||
|
||||
get_colors(flags, &fg, &bg);
|
||||
line_add_colors(gui, fg, bg, flags);
|
||||
linebuf_add(gui, str, strlen(str));
|
||||
|
||||
/* temporarily mark the end of line. */
|
||||
memcpy(gui->cur_text->buffer+gui->cur_text->pos, "\0\x80", 2);
|
||||
|
||||
if (visible)
|
||||
{
|
||||
/* draw the line to screen. */
|
||||
lines = gui_window_line_draw(gui, line, first_text_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;
|
||||
}
|
||||
|
||||
static void cmd_clear(gchar *data)
|
||||
{
|
||||
GUI_WINDOW_REC *gui;
|
||||
gint n;
|
||||
|
||||
gui = WINDOW_GUI(active_win);
|
||||
|
||||
if (is_window_visible(active_win))
|
||||
{
|
||||
for (n = first_text_line; n < last_text_line; n++)
|
||||
{
|
||||
move(n, 0);
|
||||
clrtoeol();
|
||||
}
|
||||
screen_refresh();
|
||||
}
|
||||
|
||||
gui->ypos = -1;
|
||||
gui->bottom_startline = gui->startline = g_list_last(gui->lines);
|
||||
gui->bottom_subline = gui->subline = gui->last_subline+1;
|
||||
gui->empty_linecount = last_text_line-first_text_line;
|
||||
gui->bottom = TRUE;
|
||||
}
|
||||
|
||||
static void sig_printtext_finished(WINDOW_REC *window)
|
||||
{
|
||||
if (is_window_visible(window))
|
||||
screen_refresh();
|
||||
}
|
||||
|
||||
static void read_settings(void)
|
||||
{
|
||||
max_textwidget_lines = settings_get_int("max_textwidget_lines");
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
28
src/fe-text/gui-printtext.h
Normal file
28
src/fe-text/gui-printtext.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef __GUI_PRINTTEXT_H
|
||||
#define __GUI_PRINTTEXT_H
|
||||
|
||||
enum
|
||||
{
|
||||
BLACK = 0,
|
||||
BLUE,
|
||||
GREEN,
|
||||
CYAN,
|
||||
RED,
|
||||
MAGENTA,
|
||||
YELLOW,
|
||||
WHITE,
|
||||
BBLACK,
|
||||
BBLUE,
|
||||
BGREEN,
|
||||
BCYAN,
|
||||
BRED,
|
||||
BMAGENTA,
|
||||
BYELLOW,
|
||||
BWHITE,
|
||||
NUM_COLORS
|
||||
};
|
||||
|
||||
void gui_printtext_init(void);
|
||||
void gui_printtext_deinit(void);
|
||||
|
||||
#endif
|
||||
374
src/fe-text/gui-readline.c
Normal file
374
src/fe-text/gui-readline.c
Normal file
|
|
@ -0,0 +1,374 @@
|
|||
/*
|
||||
gui-readline.c : irssi
|
||||
|
||||
Copyright (C) 1999 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 "server.h"
|
||||
#include "misc.h"
|
||||
|
||||
#include "completion.h"
|
||||
#include "command-history.h"
|
||||
#include "keyboard.h"
|
||||
#include "translation.h"
|
||||
#include "windows.h"
|
||||
|
||||
#include "screen.h"
|
||||
#include "gui-entry.h"
|
||||
#include "gui-mainwindows.h"
|
||||
#include "gui-windows.h"
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
static gint readtag, sigint_count = 0;
|
||||
static time_t idle_time;
|
||||
|
||||
static void window_prev_page(void)
|
||||
{
|
||||
gui_window_scroll(active_win, -(last_text_line-first_text_line)/2);
|
||||
}
|
||||
|
||||
static void window_next_page(void)
|
||||
{
|
||||
gui_window_scroll(active_win, (last_text_line-first_text_line)/2);
|
||||
}
|
||||
|
||||
static char *get_key_name(int key)
|
||||
{
|
||||
static char str[MAX_INT_STRLEN];
|
||||
|
||||
switch (key) {
|
||||
case KEY_HOME:
|
||||
return "Home";
|
||||
case KEY_END:
|
||||
return "End";
|
||||
case KEY_PPAGE:
|
||||
return "Prior";
|
||||
case KEY_NPAGE:
|
||||
return "Next";
|
||||
case KEY_UP:
|
||||
return "Up";
|
||||
case KEY_DOWN:
|
||||
return "Down";
|
||||
case KEY_LEFT:
|
||||
return "Left";
|
||||
case KEY_RIGHT:
|
||||
return "Right";
|
||||
default:
|
||||
ltoa(str, key);
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
void handle_key(gint key)
|
||||
{
|
||||
const char *text;
|
||||
char *str;
|
||||
int c;
|
||||
|
||||
/* Quit if we get 5 CTRL-C's in a row. */
|
||||
if (key != 3)
|
||||
sigint_count = 0;
|
||||
else if (++sigint_count >= 5)
|
||||
raise(SIGTERM);
|
||||
|
||||
idle_time = time(NULL);
|
||||
switch (key)
|
||||
{
|
||||
case 27:
|
||||
c = getch();
|
||||
if (c == toupper(c) && c != tolower(c))
|
||||
str = g_strdup_printf("ALT-SHIFT-%c", c);
|
||||
else {
|
||||
if (c < 256)
|
||||
str = g_strdup_printf("ALT-%c", toupper(c));
|
||||
else
|
||||
str = g_strdup_printf("ALT-%s", get_key_name(c));
|
||||
}
|
||||
key_pressed(str, NULL);
|
||||
g_free(str);
|
||||
break;
|
||||
|
||||
case KEY_HOME:
|
||||
/* home */
|
||||
gui_entry_set_pos(0);
|
||||
gui_entry_move_pos(0);
|
||||
break;
|
||||
case KEY_END:
|
||||
/* end */
|
||||
gui_entry_set_pos(strlen(gui_entry_get_text()));
|
||||
gui_entry_move_pos(0);
|
||||
break;
|
||||
case KEY_PPAGE:
|
||||
/* page up */
|
||||
window_prev_page();
|
||||
break;
|
||||
case KEY_NPAGE:
|
||||
/* page down */
|
||||
window_next_page();
|
||||
break;
|
||||
|
||||
case KEY_UP:
|
||||
/* up */
|
||||
text = command_history_prev(active_win, gui_entry_get_text());
|
||||
gui_entry_set_text(text);
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
/* down */
|
||||
text = command_history_next(active_win, gui_entry_get_text());
|
||||
gui_entry_set_text(text);
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
/* right */
|
||||
gui_entry_move_pos(1);
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
/* left */
|
||||
gui_entry_move_pos(-1);
|
||||
break;
|
||||
|
||||
case 21:
|
||||
/* Ctrl-U, clear line */
|
||||
gui_entry_set_text("");
|
||||
break;
|
||||
|
||||
case 9:
|
||||
key_pressed("Tab", NULL);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
case 127:
|
||||
case KEY_BACKSPACE:
|
||||
gui_entry_erase(1);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
/* Ctrl-space - ignore */
|
||||
break;
|
||||
case 1:
|
||||
/* C-A, home */
|
||||
gui_entry_set_pos(0);
|
||||
gui_entry_move_pos(0);
|
||||
break;
|
||||
case 5:
|
||||
/* C-E, end */
|
||||
gui_entry_set_pos(strlen(gui_entry_get_text()));
|
||||
gui_entry_move_pos(0);
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
case 13:
|
||||
key_pressed("Return", NULL);
|
||||
|
||||
str = gui_entry_get_text();
|
||||
if (*str == '\0') break;
|
||||
|
||||
translate_output(str);
|
||||
signal_emit("send command", 3, str, active_win->active_server, active_win->active);
|
||||
|
||||
command_history_add(active_win, gui_entry_get_text(), FALSE);
|
||||
gui_entry_set_text("");
|
||||
command_history_clear_pos(active_win);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (key > 0 && key < 32)
|
||||
{
|
||||
str = g_strdup_printf("CTRL-%c", key == 31 ? '-' : key+'A'-1);
|
||||
key_pressed(str, NULL);
|
||||
g_free(str);
|
||||
break;
|
||||
}
|
||||
|
||||
if (key < 256)
|
||||
{
|
||||
gchar str[2];
|
||||
|
||||
str[0] = toupper(key); str[1] = '\0';
|
||||
key_pressed(str, NULL);
|
||||
gui_entry_insert_char((gchar) key);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void readline(void)
|
||||
{
|
||||
gint key;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
key = getch();
|
||||
if (key == ERR) break;
|
||||
|
||||
handle_key(key);
|
||||
}
|
||||
}
|
||||
|
||||
time_t get_idle_time(void)
|
||||
{
|
||||
return idle_time;
|
||||
}
|
||||
|
||||
static void sig_prev_page(void)
|
||||
{
|
||||
window_prev_page();
|
||||
}
|
||||
|
||||
static void sig_next_page(void)
|
||||
{
|
||||
window_next_page();
|
||||
}
|
||||
|
||||
static void sig_change_window(gchar *data)
|
||||
{
|
||||
signal_emit("command window goto", 3, data, active_win->active_server, active_win->active);
|
||||
}
|
||||
|
||||
static void sig_completion(void)
|
||||
{
|
||||
gchar *line;
|
||||
gint pos;
|
||||
|
||||
pos = gui_entry_get_pos();
|
||||
|
||||
line = completion_line(active_win, gui_entry_get_text(), &pos);
|
||||
if (line != NULL)
|
||||
{
|
||||
gui_entry_set_text(line);
|
||||
gui_entry_set_pos(pos);
|
||||
g_free(line);
|
||||
}
|
||||
}
|
||||
|
||||
static void sig_replace(void)
|
||||
{
|
||||
gchar *line;
|
||||
gint pos;
|
||||
|
||||
pos = gui_entry_get_pos();
|
||||
|
||||
line = auto_completion(gui_entry_get_text(), &pos);
|
||||
if (line != NULL)
|
||||
{
|
||||
gui_entry_set_text(line);
|
||||
gui_entry_set_pos(pos);
|
||||
g_free(line);
|
||||
}
|
||||
}
|
||||
|
||||
static void sig_prev_window(void)
|
||||
{
|
||||
signal_emit("command window prev", 3, "", active_win->active_server, active_win->active);
|
||||
}
|
||||
|
||||
static void sig_next_window(void)
|
||||
{
|
||||
signal_emit("command window next", 3, "", active_win->active_server, active_win->active);
|
||||
}
|
||||
|
||||
static void sig_window_goto_active(void)
|
||||
{
|
||||
signal_emit("command window goto", 3, "active", active_win->active_server, active_win->active);
|
||||
}
|
||||
|
||||
static void sig_prev_channel(void)
|
||||
{
|
||||
signal_emit("command channel prev", 3, "", active_win->active_server, active_win->active);
|
||||
}
|
||||
|
||||
static void sig_next_channel(void)
|
||||
{
|
||||
signal_emit("command channel next", 3, "", active_win->active_server, active_win->active);
|
||||
}
|
||||
|
||||
static void sig_addchar(gchar *data)
|
||||
{
|
||||
gui_entry_insert_char(*data);
|
||||
}
|
||||
|
||||
static void signal_window_auto_changed(WINDOW_REC *window)
|
||||
{
|
||||
command_history_next(active_win, gui_entry_get_text());
|
||||
gui_entry_set_text("");
|
||||
}
|
||||
|
||||
void gui_readline_init(void)
|
||||
{
|
||||
static gchar changekeys[] = "1234567890QWERTYUIO";
|
||||
gchar *key, *data;
|
||||
gint n;
|
||||
|
||||
idle_time = time(NULL);
|
||||
readtag = g_input_add(0, G_INPUT_READ, (GInputFunction) readline, NULL);
|
||||
|
||||
key_bind("completion", NULL, "Nick completion", "Tab", (SIGNAL_FUNC) sig_completion);
|
||||
key_bind("check replaces", NULL, "Check word replaces", " ", (SIGNAL_FUNC) sig_replace);
|
||||
key_bind("check replaces", NULL, NULL, "Return", (SIGNAL_FUNC) sig_replace);
|
||||
key_bind("window prev", NULL, "Previous window", "CTRL-P", (SIGNAL_FUNC) sig_prev_window);
|
||||
key_bind("window prev", NULL, NULL, "ALT-Left", (SIGNAL_FUNC) sig_prev_window);
|
||||
key_bind("window next", NULL, "Next window", "CTRL-N", (SIGNAL_FUNC) sig_next_window);
|
||||
key_bind("window next", NULL, NULL, "ALT-Right", (SIGNAL_FUNC) sig_next_window);
|
||||
key_bind("window active", NULL, "Go to next window with the highest activity", "ALT-A", (SIGNAL_FUNC) sig_window_goto_active);
|
||||
key_bind("channel next", NULL, "Next channel", "CTRL-X", (SIGNAL_FUNC) sig_next_channel);
|
||||
key_bind("channel prev", NULL, "Next channel", NULL, (SIGNAL_FUNC) sig_prev_channel);
|
||||
|
||||
key_bind("redraw", NULL, "Redraw window", "CTRL-L", (SIGNAL_FUNC) irssi_redraw);
|
||||
key_bind("prev page", NULL, "Previous page", "ALT-P", (SIGNAL_FUNC) sig_prev_page);
|
||||
key_bind("next page", NULL, "Next page", "ALT-N", (SIGNAL_FUNC) sig_next_page);
|
||||
|
||||
key_bind("special char", "\x02", "Insert special character", "CTRL-B", (SIGNAL_FUNC) sig_addchar);
|
||||
key_bind("special char", "\x1f", NULL, "CTRL--", (SIGNAL_FUNC) sig_addchar);
|
||||
key_bind("special char", "\x03", NULL, "CTRL-C", (SIGNAL_FUNC) sig_addchar);
|
||||
key_bind("special char", "\x16", NULL, "CTRL-V", (SIGNAL_FUNC) sig_addchar);
|
||||
key_bind("special char", "\x07", NULL, "CTRL-G", (SIGNAL_FUNC) sig_addchar);
|
||||
key_bind("special char", "\x0f", NULL, "CTRL-O", (SIGNAL_FUNC) sig_addchar);
|
||||
|
||||
for (n = 0; changekeys[n] != '\0'; n++)
|
||||
{
|
||||
key = g_strdup_printf("ALT-%c", changekeys[n]);
|
||||
data = g_strdup_printf("%d", n+1);
|
||||
key_bind("change window", data, "Change window", key, (SIGNAL_FUNC) sig_change_window);
|
||||
g_free(data); g_free(key);
|
||||
}
|
||||
|
||||
signal_add("window changed automatic", (SIGNAL_FUNC) signal_window_auto_changed);
|
||||
}
|
||||
|
||||
void gui_readline_deinit(void)
|
||||
{
|
||||
g_source_remove(readtag);
|
||||
|
||||
key_unbind("completion", (SIGNAL_FUNC) sig_completion);
|
||||
key_unbind("check replaces", (SIGNAL_FUNC) sig_replace);
|
||||
key_unbind("window prev", (SIGNAL_FUNC) sig_prev_window);
|
||||
key_unbind("window next", (SIGNAL_FUNC) sig_next_window);
|
||||
key_unbind("window active", (SIGNAL_FUNC) sig_window_goto_active);
|
||||
key_unbind("channel next", (SIGNAL_FUNC) sig_next_channel);
|
||||
key_unbind("channel prev", (SIGNAL_FUNC) sig_prev_channel);
|
||||
|
||||
key_unbind("redraw", (SIGNAL_FUNC) irssi_redraw);
|
||||
key_unbind("prev page", (SIGNAL_FUNC) sig_prev_page);
|
||||
key_unbind("next page", (SIGNAL_FUNC) sig_next_page);
|
||||
|
||||
key_unbind("special char", (SIGNAL_FUNC) sig_addchar);
|
||||
key_unbind("change window", (SIGNAL_FUNC) sig_change_window);
|
||||
|
||||
signal_remove("window changed automatic", (SIGNAL_FUNC) signal_window_auto_changed);
|
||||
}
|
||||
10
src/fe-text/gui-readline.h
Normal file
10
src/fe-text/gui-readline.h
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef __GUI_READLINE_H
|
||||
#define __GUI_READLINE_H
|
||||
|
||||
void readline(void);
|
||||
time_t get_idle_time(void);
|
||||
|
||||
void gui_readline_init(void);
|
||||
void gui_readline_deinit(void);
|
||||
|
||||
#endif
|
||||
61
src/fe-text/gui-special-vars.c
Normal file
61
src/fe-text/gui-special-vars.c
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
gui-special-vars.c : irssi
|
||||
|
||||
Copyright (C) 2000 Timo Sirainen
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "special-vars.h"
|
||||
|
||||
#include "gui-entry.h"
|
||||
#include "gui-readline.h"
|
||||
|
||||
/* idle time */
|
||||
static char *expando_idletime(void *server, void *item, int *free_ret)
|
||||
{
|
||||
int diff;
|
||||
|
||||
*free_ret = TRUE;
|
||||
diff = (int) (time(NULL) - get_idle_time());
|
||||
return g_strdup_printf("%d", diff);
|
||||
}
|
||||
|
||||
/* current contents of the input line */
|
||||
static char *expando_inputline(void *server, void *item, int *free_ret)
|
||||
{
|
||||
return gui_entry_get_text();
|
||||
}
|
||||
|
||||
/* FIXME: value of cutbuffer */
|
||||
static char *expando_cutbuffer(void *server, void *item, int *free_ret)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void gui_special_vars_init(void)
|
||||
{
|
||||
expando_create("E", expando_idletime);
|
||||
expando_create("L", expando_inputline);
|
||||
expando_create("U", expando_cutbuffer);
|
||||
}
|
||||
|
||||
void gui_special_vars_deinit(void)
|
||||
{
|
||||
expando_destroy("E", expando_idletime);
|
||||
expando_destroy("L", expando_inputline);
|
||||
expando_destroy("U", expando_cutbuffer);
|
||||
}
|
||||
7
src/fe-text/gui-special-vars.h
Normal file
7
src/fe-text/gui-special-vars.h
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef __GUI_SPECIAL_VARS_H
|
||||
#define __GUI_SPECIAL_VARS_H
|
||||
|
||||
void gui_special_vars_init(void);
|
||||
void gui_special_vars_deinit(void);
|
||||
|
||||
#endif
|
||||
691
src/fe-text/gui-statusbar-items.c
Normal file
691
src/fe-text/gui-statusbar-items.c
Normal file
|
|
@ -0,0 +1,691 @@
|
|||
/*
|
||||
gui-statusbar-items.c : irssi
|
||||
|
||||
Copyright (C) 1999 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 "server.h"
|
||||
#include "misc.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include "irc.h"
|
||||
#include "channels.h"
|
||||
#include "query.h"
|
||||
#include "irc-server.h"
|
||||
#include "nicklist.h"
|
||||
|
||||
#include "windows.h"
|
||||
|
||||
#include "screen.h"
|
||||
#include "gui-statusbar.h"
|
||||
#include "gui-mainwindows.h"
|
||||
#include "gui-windows.h"
|
||||
|
||||
/* how often to redraw lagging time */
|
||||
#define LAG_REFRESH_TIME 10
|
||||
/* If we haven't been able to check lag for this long, "(??)" is added after
|
||||
the lag */
|
||||
#define MAX_LAG_UNKNOWN_TIME 30
|
||||
|
||||
/* clock */
|
||||
static int clock_tag, clock_timetag;
|
||||
static time_t clock_last;
|
||||
|
||||
/* nick */
|
||||
static int nick_tag;
|
||||
|
||||
/* channel */
|
||||
static int channel_tag;
|
||||
|
||||
/* activity */
|
||||
static int activity_tag;
|
||||
static GList *activity_list;
|
||||
|
||||
/* more */
|
||||
static int more_tag;
|
||||
|
||||
/* lag */
|
||||
static int lag_tag, lag_timetag, lag_min_show;
|
||||
static time_t lag_last_draw;
|
||||
|
||||
/* topic */
|
||||
static int topic_tag;
|
||||
|
||||
/* redraw clock */
|
||||
static void statusbar_clock(int xpos, int ypos, int size)
|
||||
{
|
||||
struct tm *tm;
|
||||
gchar str[5];
|
||||
|
||||
clock_last = time(NULL);
|
||||
tm = localtime(&clock_last);
|
||||
|
||||
sprintf(str, "%02d:%02d", tm->tm_hour, tm->tm_min);
|
||||
|
||||
move(ypos, xpos);
|
||||
set_color((1 << 4)+3); addch('[');
|
||||
set_color((1 << 4)+15); addstr(str);
|
||||
set_color((1 << 4)+3); addch(']');
|
||||
|
||||
screen_refresh();
|
||||
}
|
||||
|
||||
/* 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! */
|
||||
gui_statusbar_redraw(clock_tag);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* redraw nick */
|
||||
static void statusbar_nick(int xpos, int ypos, int size)
|
||||
{
|
||||
CHANNEL_REC *channel;
|
||||
IRC_SERVER_REC *server;
|
||||
NICK_REC *nickrec;
|
||||
int size_needed;
|
||||
int umode_size;
|
||||
gchar nick[10];
|
||||
|
||||
server = (IRC_SERVER_REC *) (active_win == NULL ? NULL : active_win->active_server);
|
||||
|
||||
umode_size = server == NULL || server->usermode == NULL ? 0 : strlen(server->usermode)+3;
|
||||
|
||||
/* nick */
|
||||
if (server == NULL || server->nick == NULL)
|
||||
{
|
||||
nick[0] = '\0';
|
||||
nickrec = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(nick, server->nick, 9);
|
||||
nick[9] = '\0';
|
||||
|
||||
channel = irc_item_channel(active_win->active);
|
||||
nickrec = channel == NULL ? NULL : nicklist_find(channel, server->nick);
|
||||
}
|
||||
|
||||
size_needed = 2 + strlen(nick) + umode_size +
|
||||
(server != NULL && server->usermode_away ? 7 : 0) +
|
||||
(nickrec != NULL && (nickrec->op || nickrec->voice) ? 1 : 0); /* @ + */
|
||||
|
||||
if (size != size_needed)
|
||||
{
|
||||
/* we need more (or less..) space! */
|
||||
gui_statusbar_resize(nick_tag, size_needed);
|
||||
return;
|
||||
}
|
||||
|
||||
/* size ok, draw the nick */
|
||||
move(ypos, xpos);
|
||||
|
||||
set_color((1 << 4)+3); addch('[');
|
||||
if (nickrec != NULL && (nickrec->op || nickrec->voice))
|
||||
{
|
||||
set_color((1 << 4)+15); addch(nickrec->op ? '@' : '+');
|
||||
}
|
||||
set_color((1 << 4)+7); addstr(nick);
|
||||
if (umode_size)
|
||||
{
|
||||
set_color((1 << 4)+15); addch('(');
|
||||
set_color((1 << 4)+3); addch('+');
|
||||
set_color((1 << 4)+7); addstr(server->usermode);
|
||||
set_color((1 << 4)+15); addch(')');
|
||||
if (server->usermode_away)
|
||||
{
|
||||
set_color((1 << 4)+7); addstr(" (");
|
||||
set_color((1 << 4)+10); addstr("zZzZ");
|
||||
set_color((1 << 4)+7); addch(')');
|
||||
}
|
||||
}
|
||||
set_color((1 << 4)+3); addch(']');
|
||||
screen_refresh();
|
||||
}
|
||||
|
||||
static void sig_statusbar_nick_redraw(void)
|
||||
{
|
||||
gui_statusbar_redraw(nick_tag);
|
||||
}
|
||||
|
||||
/* redraw channel */
|
||||
static void statusbar_channel(int xpos, int ypos, int size)
|
||||
{
|
||||
WI_ITEM_REC *item;
|
||||
CHANNEL_REC *channel;
|
||||
SERVER_REC *server;
|
||||
gchar channame[21], window[MAX_INT_STRLEN], *mode;
|
||||
int size_needed;
|
||||
int mode_size;
|
||||
|
||||
server = active_win == NULL ? NULL : active_win->active_server;
|
||||
|
||||
ltoa(window, active_win == NULL ? 0 :
|
||||
g_slist_index(windows, active_win)+1);
|
||||
|
||||
item = active_win != NULL && irc_item_check(active_win->active) ?
|
||||
active_win->active : NULL;
|
||||
if (item == NULL)
|
||||
{
|
||||
/* display server tag */
|
||||
channame[0] = '\0';
|
||||
mode = NULL;
|
||||
mode_size = 0;
|
||||
|
||||
size_needed = 3 + strlen(window) + (server == NULL ? 0 : strlen(server->tag));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* display channel + mode */
|
||||
strncpy(channame, item->name, 20); channame[20] = '\0';
|
||||
|
||||
channel = irc_item_channel(item);
|
||||
if (channel == NULL) {
|
||||
mode_size = 0;
|
||||
mode = NULL;
|
||||
} else {
|
||||
mode = channel_get_mode(channel);
|
||||
mode_size = strlen(mode);
|
||||
if (mode_size > 0) mode_size += 3; /* (+) */
|
||||
}
|
||||
|
||||
size_needed = 3 + strlen(window) + strlen(channame) + mode_size;
|
||||
}
|
||||
|
||||
if (size != size_needed)
|
||||
{
|
||||
/* we need more (or less..) space! */
|
||||
gui_statusbar_resize(channel_tag, size_needed);
|
||||
if (mode != NULL) g_free(mode);
|
||||
return;
|
||||
}
|
||||
|
||||
move(ypos, xpos);
|
||||
set_color((1 << 4)+3); addch('[');
|
||||
|
||||
/* window number */
|
||||
set_color((1 << 4)+7); addstr(window);
|
||||
set_color((1 << 4)+3); addch(':');
|
||||
|
||||
if (channame[0] == '\0' && server != NULL)
|
||||
{
|
||||
/* server tag */
|
||||
set_color((1 << 4)+7); addstr(server->tag);
|
||||
}
|
||||
else if (channame[0] != '\0')
|
||||
{
|
||||
/* channel + mode */
|
||||
set_color((1 << 4)+7); addstr(channame);
|
||||
if (mode_size)
|
||||
{
|
||||
set_color((1 << 4)+15); addch('(');
|
||||
set_color((1 << 4)+3); addch('+');
|
||||
set_color((1 << 4)+7); addstr(mode);
|
||||
set_color((1 << 4)+15); addch(')');
|
||||
}
|
||||
}
|
||||
set_color((1 << 4)+3); addch(']');
|
||||
screen_refresh();
|
||||
|
||||
if (mode != NULL) g_free(mode);
|
||||
}
|
||||
|
||||
static void sig_statusbar_channel_redraw(void)
|
||||
{
|
||||
gui_statusbar_redraw(channel_tag);
|
||||
}
|
||||
|
||||
static void draw_activity(gchar *title, gboolean act, gboolean det)
|
||||
{
|
||||
WINDOW_REC *window;
|
||||
GList *tmp;
|
||||
gchar str[(sizeof(int) * CHAR_BIT + 2) / 3 + 1];
|
||||
gboolean first, is_det;
|
||||
|
||||
set_color((1 << 4)+7); addstr(title);
|
||||
|
||||
first = TRUE;
|
||||
for (tmp = activity_list; tmp != NULL; tmp = tmp->next)
|
||||
{
|
||||
window = tmp->data;
|
||||
|
||||
is_det = window->new_data == NEWDATA_MSG_FORYOU;
|
||||
if (is_det && !det) continue;
|
||||
if (!is_det && !act) continue;
|
||||
|
||||
if (first)
|
||||
first = FALSE;
|
||||
else
|
||||
{
|
||||
set_color((1 << 4)+3);
|
||||
addch(',');
|
||||
}
|
||||
|
||||
sprintf(str, "%d", g_slist_index(windows, window)+1);
|
||||
switch (window->new_data)
|
||||
{
|
||||
case NEWDATA_TEXT:
|
||||
set_color((1 << 4)+3);
|
||||
break;
|
||||
case NEWDATA_MSG:
|
||||
set_color((1 << 4)+15);
|
||||
break;
|
||||
case NEWDATA_MSG_FORYOU:
|
||||
set_color((1 << 4)+13);
|
||||
break;
|
||||
}
|
||||
addstr(str);
|
||||
}
|
||||
}
|
||||
|
||||
/* redraw activity */
|
||||
static void statusbar_activity(int xpos, int ypos, int size)
|
||||
{
|
||||
WINDOW_REC *window;
|
||||
GList *tmp;
|
||||
gchar str[MAX_INT_STRLEN];
|
||||
int size_needed;
|
||||
gboolean act, det;
|
||||
|
||||
size_needed = 0; act = det = FALSE;
|
||||
for (tmp = activity_list; tmp != NULL; tmp = tmp->next)
|
||||
{
|
||||
window = tmp->data;
|
||||
|
||||
size_needed += 1+g_snprintf(str, sizeof(str), "%d", g_slist_index(windows, window)+1);
|
||||
|
||||
if (!use_colors && window->new_data == NEWDATA_MSG_FORYOU)
|
||||
det = TRUE;
|
||||
else
|
||||
act = TRUE;
|
||||
}
|
||||
|
||||
if (act) size_needed += 6; /* [Act: ], -1 */
|
||||
if (det) size_needed += 6; /* [Det: ], -1 */
|
||||
if (act && det) size_needed--;
|
||||
|
||||
if (size != size_needed)
|
||||
{
|
||||
/* we need more (or less..) space! */
|
||||
gui_statusbar_resize(activity_tag, size_needed);
|
||||
return;
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
move(ypos, xpos);
|
||||
set_color((1 << 4)+3); addch('[');
|
||||
if (act) draw_activity("Act: ", TRUE, !det);
|
||||
if (act && det) addch(' ');
|
||||
if (det) draw_activity("Det: ", FALSE, TRUE);
|
||||
set_color((1 << 4)+3); addch(']');
|
||||
|
||||
screen_refresh();
|
||||
}
|
||||
|
||||
static void sig_statusbar_activity_hilight(WINDOW_REC *window, gpointer oldlevel)
|
||||
{
|
||||
int pos, inspos;
|
||||
GList *tmp;
|
||||
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
if (settings_get_bool("toggle_actlist_moves"))
|
||||
{
|
||||
/* Move the window to the first in the activity list */
|
||||
if (g_list_find(activity_list, window) != NULL)
|
||||
activity_list = g_list_remove(activity_list, window);
|
||||
if (window->new_data != 0)
|
||||
activity_list = g_list_prepend(activity_list, window);
|
||||
gui_statusbar_redraw(activity_tag);
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_list_find(activity_list, window) != NULL)
|
||||
{
|
||||
/* already in activity list */
|
||||
if (window->new_data == 0)
|
||||
{
|
||||
/* remove from activity list */
|
||||
activity_list = g_list_remove(activity_list, window);
|
||||
gui_statusbar_redraw(activity_tag);
|
||||
}
|
||||
else if (window->new_data != GPOINTER_TO_INT(oldlevel))
|
||||
{
|
||||
/* different level as last time, just redraw it. */
|
||||
gui_statusbar_redraw(activity_tag);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (window->new_data == 0)
|
||||
return;
|
||||
|
||||
/* add window to activity list .. */
|
||||
pos = g_slist_index(windows, window);
|
||||
|
||||
inspos = 0;
|
||||
for (tmp = activity_list; tmp != NULL; tmp = tmp->next, inspos++)
|
||||
{
|
||||
if (pos < g_slist_index(windows, tmp->data))
|
||||
{
|
||||
activity_list = g_list_insert(activity_list, window, inspos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tmp == NULL)
|
||||
activity_list = g_list_append(activity_list, window);
|
||||
|
||||
gui_statusbar_redraw(activity_tag);
|
||||
}
|
||||
|
||||
static void sig_statusbar_activity_window_destroyed(WINDOW_REC *window)
|
||||
{
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
if (g_list_find(activity_list, window) != NULL)
|
||||
{
|
||||
activity_list = g_list_remove(activity_list, window);
|
||||
gui_statusbar_redraw(activity_tag);
|
||||
}
|
||||
}
|
||||
|
||||
/* redraw -- more -- */
|
||||
static void statusbar_more(int xpos, int ypos, int size)
|
||||
{
|
||||
if (size != 10) return;
|
||||
|
||||
move(ypos, xpos);
|
||||
set_color((1 << 4)+15); addstr("-- more --");
|
||||
screen_refresh();
|
||||
}
|
||||
|
||||
static void sig_statusbar_more_check_remove(WINDOW_REC *window)
|
||||
{
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
if (!is_window_visible(window))
|
||||
return;
|
||||
|
||||
if (more_tag != -1 && WINDOW_GUI(window)->bottom)
|
||||
{
|
||||
gui_statusbar_remove(more_tag);
|
||||
more_tag = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void sig_statusbar_more_check(WINDOW_REC *window)
|
||||
{
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
if (WINDOW_GUI(window)->parent->active != window)
|
||||
return;
|
||||
|
||||
if (!WINDOW_GUI(window)->bottom)
|
||||
{
|
||||
if (more_tag == -1)
|
||||
more_tag = gui_statusbar_allocate(10, FALSE, FALSE, 0, statusbar_more);
|
||||
}
|
||||
else if (more_tag != -1)
|
||||
{
|
||||
gui_statusbar_remove(more_tag);
|
||||
more_tag = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void statusbar_lag(int xpos, int ypos, int size)
|
||||
{
|
||||
IRC_SERVER_REC *server;
|
||||
GString *str;
|
||||
int size_needed, lag_unknown;
|
||||
time_t now;
|
||||
|
||||
now = time(NULL);
|
||||
str = g_string_new(NULL);
|
||||
|
||||
server = (IRC_SERVER_REC *) (active_win == NULL ? NULL : active_win->active_server);
|
||||
if (server == NULL || server->lag_last_check == 0)
|
||||
size_needed = 0;
|
||||
else if (server->lag_sent == 0 || now-server->lag_sent < 5) {
|
||||
lag_unknown = now-server->lag_last_check > MAX_LAG_UNKNOWN_TIME;
|
||||
|
||||
if (server->lag < lag_min_show && !lag_unknown)
|
||||
size_needed = 0; /* small lag, don't display */
|
||||
else {
|
||||
g_string_sprintf(str, "%d.%02d", server->lag/1000, (server->lag % 1000)/10);
|
||||
if (lag_unknown)
|
||||
g_string_append(str, " (??)");
|
||||
size_needed = str->len+7;
|
||||
}
|
||||
} else {
|
||||
/* big lag, still waiting .. */
|
||||
g_string_sprintf(str, "%ld (??)", now-server->lag_sent);
|
||||
size_needed = str->len+7;
|
||||
}
|
||||
|
||||
if (size != size_needed)
|
||||
{
|
||||
/* we need more (or less..) space! */
|
||||
gui_statusbar_resize(lag_tag, size_needed);
|
||||
g_string_free(str, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (size != 0)
|
||||
{
|
||||
lag_last_draw = now;
|
||||
move(ypos, xpos);
|
||||
set_color((1 << 4)+3); addch('[');
|
||||
set_color((1 << 4)+7); addstr("Lag: ");
|
||||
|
||||
set_color((1 << 4)+15); addstr(str->str);
|
||||
set_color((1 << 4)+3); addch(']');
|
||||
|
||||
screen_refresh();
|
||||
}
|
||||
g_string_free(str, TRUE);
|
||||
}
|
||||
|
||||
static void sig_statusbar_lag_redraw(void)
|
||||
{
|
||||
gui_statusbar_redraw(lag_tag);
|
||||
}
|
||||
|
||||
static int statusbar_lag_timeout(void)
|
||||
{
|
||||
/* refresh statusbar every 10 seconds */
|
||||
if (time(NULL)-lag_last_draw < LAG_REFRESH_TIME)
|
||||
return 1;
|
||||
|
||||
gui_statusbar_redraw(lag_tag);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void statusbar_topic(int xpos, int ypos, int size)
|
||||
{
|
||||
CHANNEL_REC *channel;
|
||||
QUERY_REC *query;
|
||||
char *str, *topic;
|
||||
|
||||
if (size != COLS-2) {
|
||||
/* get all space for topic */
|
||||
gui_statusbar_resize(topic_tag, COLS-2);
|
||||
return;
|
||||
}
|
||||
|
||||
move(ypos, xpos);
|
||||
set_bg((1<<4)+7); clrtoeol(); set_bg(0);
|
||||
|
||||
if (active_win == NULL)
|
||||
return;
|
||||
|
||||
topic = NULL;
|
||||
channel = irc_item_channel(active_win->active);
|
||||
query = irc_item_query(active_win->active);
|
||||
if (channel != NULL && channel->topic != NULL) topic = channel->topic;
|
||||
if (query != NULL && query->address != NULL) topic = query->address;
|
||||
if (topic == NULL) return;
|
||||
|
||||
str = g_strdup_printf("%.*s", size, topic);
|
||||
set_color((1<<4)+15); addstr(str);
|
||||
g_free(str);
|
||||
|
||||
screen_refresh();
|
||||
}
|
||||
|
||||
static void sig_statusbar_topic_redraw(void)
|
||||
{
|
||||
gui_statusbar_redraw(topic_tag);
|
||||
}
|
||||
|
||||
static void read_settings(void)
|
||||
{
|
||||
int ypos;
|
||||
|
||||
if (topic_tag == -1 && settings_get_bool("toggle_show_topicbar")) {
|
||||
ypos = gui_statusbar_create(TRUE);
|
||||
topic_tag = gui_statusbar_allocate(0, FALSE, TRUE, ypos, statusbar_topic);
|
||||
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);
|
||||
} else if (topic_tag != -1 && !settings_get_bool("toggle_show_topicbar")) {
|
||||
gui_statusbar_delete(TRUE, 0);
|
||||
topic_tag = -1;
|
||||
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);
|
||||
}
|
||||
|
||||
lag_min_show = settings_get_int("lag_min_show")*10;
|
||||
}
|
||||
|
||||
void gui_statusbar_items_init(void)
|
||||
{
|
||||
settings_add_int("misc", "lag_min_show", 100);
|
||||
|
||||
/* clock */
|
||||
clock_tag = gui_statusbar_allocate(7, FALSE, FALSE, 0, statusbar_clock);
|
||||
clock_timetag = g_timeout_add(1000, (GSourceFunc) statusbar_clock_timeout, NULL);
|
||||
|
||||
/* nick */
|
||||
nick_tag = gui_statusbar_allocate(2, FALSE, FALSE, 0, statusbar_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);
|
||||
|
||||
/* channel */
|
||||
channel_tag = gui_statusbar_allocate(2, FALSE, FALSE, 0, statusbar_channel);
|
||||
signal_add("window changed", (SIGNAL_FUNC) sig_statusbar_channel_redraw);
|
||||
signal_add("window item changed", (SIGNAL_FUNC) sig_statusbar_channel_redraw);
|
||||
signal_add("channel mode changed", (SIGNAL_FUNC) sig_statusbar_channel_redraw);
|
||||
signal_add("window server changed", (SIGNAL_FUNC) sig_statusbar_channel_redraw);
|
||||
|
||||
/* activity */
|
||||
activity_list = NULL;
|
||||
activity_tag = gui_statusbar_allocate(0, FALSE, FALSE, 0, statusbar_activity);
|
||||
signal_add("window activity", (SIGNAL_FUNC) sig_statusbar_activity_hilight);
|
||||
signal_add("window destroyed", (SIGNAL_FUNC) sig_statusbar_activity_window_destroyed);
|
||||
|
||||
/* more */
|
||||
more_tag = -1;
|
||||
signal_add("gui page scrolled", (SIGNAL_FUNC) sig_statusbar_more_check_remove);
|
||||
signal_add("window item changed", (SIGNAL_FUNC) sig_statusbar_more_check);
|
||||
signal_add("gui print text", (SIGNAL_FUNC) sig_statusbar_more_check);
|
||||
|
||||
/* lag */
|
||||
lag_tag = gui_statusbar_allocate(0, FALSE, FALSE, 0, statusbar_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);
|
||||
|
||||
/* topic bar */
|
||||
topic_tag = -1;
|
||||
signal_add("setup changed", (SIGNAL_FUNC) read_settings);
|
||||
|
||||
read_settings();
|
||||
}
|
||||
|
||||
void gui_statusbar_items_deinit(void)
|
||||
{
|
||||
/* clock */
|
||||
gui_statusbar_remove(clock_tag);
|
||||
|
||||
/* nick */
|
||||
gui_statusbar_remove(nick_tag);
|
||||
g_source_remove(clock_timetag);
|
||||
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 */
|
||||
gui_statusbar_remove(channel_tag);
|
||||
signal_remove("window changed", (SIGNAL_FUNC) sig_statusbar_channel_redraw);
|
||||
signal_remove("window item changed", (SIGNAL_FUNC) sig_statusbar_channel_redraw);
|
||||
signal_remove("channel mode changed", (SIGNAL_FUNC) sig_statusbar_channel_redraw);
|
||||
signal_remove("window server changed", (SIGNAL_FUNC) sig_statusbar_channel_redraw);
|
||||
|
||||
/* activity */
|
||||
gui_statusbar_remove(activity_tag);
|
||||
signal_remove("window activity", (SIGNAL_FUNC) sig_statusbar_activity_hilight);
|
||||
signal_remove("window destroyed", (SIGNAL_FUNC) sig_statusbar_activity_window_destroyed);
|
||||
g_list_free(activity_list);
|
||||
|
||||
/* more */
|
||||
if (more_tag != -1) gui_statusbar_remove(more_tag);
|
||||
signal_remove("gui page scrolled", (SIGNAL_FUNC) sig_statusbar_more_check_remove);
|
||||
signal_remove("window item changed", (SIGNAL_FUNC) sig_statusbar_more_check);
|
||||
signal_remove("gui print text", (SIGNAL_FUNC) sig_statusbar_more_check);
|
||||
|
||||
/* lag */
|
||||
gui_statusbar_remove(lag_tag);
|
||||
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);
|
||||
|
||||
/* topic */
|
||||
if (topic_tag != -1) gui_statusbar_delete(TRUE, 0);
|
||||
signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
|
||||
}
|
||||
7
src/fe-text/gui-statusbar-items.h
Normal file
7
src/fe-text/gui-statusbar-items.h
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef __GUI_STATUSBAR_ITEMS_H
|
||||
#define __GUI_STATUSBAR_ITEMS_H
|
||||
|
||||
void gui_statusbar_items_init(void);
|
||||
void gui_statusbar_items_deinit(void);
|
||||
|
||||
#endif
|
||||
237
src/fe-text/gui-statusbar.c
Normal file
237
src/fe-text/gui-statusbar.c
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
gui-statusbar.c : irssi
|
||||
|
||||
Copyright (C) 1999 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 "server.h"
|
||||
|
||||
#include "windows.h"
|
||||
|
||||
#include "screen.h"
|
||||
#include "gui-statusbar.h"
|
||||
#include "gui-mainwindows.h"
|
||||
#include "gui-windows.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gint tag;
|
||||
|
||||
gint xpos, ypos;
|
||||
gint size;
|
||||
gboolean right_justify, up;
|
||||
STATUSBAR_FUNC func;
|
||||
}
|
||||
STATUSBAR_REC;
|
||||
|
||||
static GList *sbars;
|
||||
static gint sbars_tag;
|
||||
|
||||
static void gui_statusbar_redraw_line(gboolean up, gint ypos)
|
||||
{
|
||||
GList *tmp;
|
||||
gint xpos, rxpos;
|
||||
|
||||
xpos = 1;
|
||||
for (tmp = sbars; tmp != NULL; tmp = tmp->next)
|
||||
{
|
||||
STATUSBAR_REC *rec = tmp->data;
|
||||
|
||||
if (!rec->right_justify)
|
||||
{
|
||||
if (rec->up == up && rec->ypos == ypos && xpos+rec->size < COLS)
|
||||
{
|
||||
rec->xpos = xpos;
|
||||
rec->func(xpos, rec->ypos + (rec->up ? 0 : last_text_line), rec->size);
|
||||
if (rec->size > 0) xpos += rec->size+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rxpos = COLS-1;
|
||||
for (tmp = sbars; tmp != NULL; tmp = tmp->next)
|
||||
{
|
||||
STATUSBAR_REC *rec = tmp->data;
|
||||
|
||||
if (rec->right_justify)
|
||||
{
|
||||
if (rec->up == up && rec->ypos == ypos && rxpos-rec->size > xpos)
|
||||
{
|
||||
rec->xpos = rxpos-rec->size;
|
||||
rec->func(rec->xpos, rec->ypos + (rec->up ? 0 : last_text_line), rec->size);
|
||||
if (rec->size > 0) rxpos -= rec->size+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gui_statusbar_redraw_all(void)
|
||||
{
|
||||
gint n;
|
||||
|
||||
screen_refresh_freeze();
|
||||
set_bg((1<<4)+15);
|
||||
for (n = 0; n < first_text_line; n++)
|
||||
{
|
||||
move(n, 0); clrtoeol();
|
||||
}
|
||||
for (n = last_text_line; n < LINES-1; n++)
|
||||
{
|
||||
move(n, 0); clrtoeol();
|
||||
}
|
||||
set_bg(0);
|
||||
|
||||
for (n = 0; n < LINES-1; n++)
|
||||
{
|
||||
gui_statusbar_redraw_line(FALSE, n);
|
||||
gui_statusbar_redraw_line(TRUE, n);
|
||||
}
|
||||
screen_refresh_thaw();
|
||||
}
|
||||
|
||||
void gui_statusbar_redraw(gint tag)
|
||||
{
|
||||
GList *tmp;
|
||||
|
||||
if (tag == -1)
|
||||
{
|
||||
gui_statusbar_redraw_all();
|
||||
return;
|
||||
}
|
||||
|
||||
for (tmp = sbars; tmp != NULL; tmp = tmp->next)
|
||||
{
|
||||
STATUSBAR_REC *rec = tmp->data;
|
||||
|
||||
if (rec->tag == tag)
|
||||
{
|
||||
rec->func(rec->xpos, rec->ypos + (rec->up ? 0 : last_text_line), rec->size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* create new statusbar, return position */
|
||||
gint gui_statusbar_create(gboolean up)
|
||||
{
|
||||
gint pos;
|
||||
|
||||
pos = up ? first_text_line++ :
|
||||
(LINES-2)-last_text_line--;
|
||||
|
||||
set_bg((1<<4)+15);
|
||||
move(up ? pos : last_text_line+pos, 0); clrtoeol();
|
||||
set_bg(0);
|
||||
|
||||
gui_windows_resize(-1, FALSE);
|
||||
return pos;
|
||||
}
|
||||
|
||||
void gui_statusbar_delete(gboolean up, gint ypos)
|
||||
{
|
||||
GList *tmp, *next;
|
||||
|
||||
if (up && first_text_line > 0)
|
||||
first_text_line--;
|
||||
else if (!up && last_text_line < LINES-1)
|
||||
last_text_line++;
|
||||
|
||||
for (tmp = sbars; tmp != NULL; tmp = next)
|
||||
{
|
||||
STATUSBAR_REC *rec = tmp->data;
|
||||
|
||||
next = tmp->next;
|
||||
if (rec->up == up && rec->ypos == ypos)
|
||||
gui_statusbar_remove(rec->tag);
|
||||
else if (rec->up == up && rec->ypos > ypos)
|
||||
rec->ypos--;
|
||||
}
|
||||
|
||||
gui_windows_resize(1, FALSE);
|
||||
}
|
||||
|
||||
/* allocate area in statusbar, returns tag or -1 if failed */
|
||||
gint gui_statusbar_allocate(gint size, gboolean right_justify, gboolean up, gint ypos, STATUSBAR_FUNC func)
|
||||
{
|
||||
STATUSBAR_REC *rec;
|
||||
|
||||
g_return_val_if_fail(func != NULL, -1);
|
||||
|
||||
rec = g_new0(STATUSBAR_REC, 1);
|
||||
sbars = g_list_append(sbars, rec);
|
||||
|
||||
rec->tag = ++sbars_tag;
|
||||
rec->xpos = -1;
|
||||
rec->up = up;
|
||||
rec->ypos = ypos;
|
||||
rec->size = size;
|
||||
rec->right_justify = right_justify;
|
||||
rec->func = func;
|
||||
|
||||
gui_statusbar_redraw_all();
|
||||
return rec->tag;
|
||||
}
|
||||
|
||||
void gui_statusbar_resize(gint tag, gint size)
|
||||
{
|
||||
GList *tmp;
|
||||
|
||||
for (tmp = sbars; tmp != NULL; tmp = tmp->next)
|
||||
{
|
||||
STATUSBAR_REC *rec = tmp->data;
|
||||
|
||||
if (rec->tag == tag)
|
||||
{
|
||||
rec->size = size;
|
||||
gui_statusbar_redraw_all();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gui_statusbar_remove(gint tag)
|
||||
{
|
||||
GList *tmp;
|
||||
|
||||
for (tmp = sbars; tmp != NULL; tmp = tmp->next)
|
||||
{
|
||||
STATUSBAR_REC *rec = tmp->data;
|
||||
|
||||
if (rec->tag == tag)
|
||||
{
|
||||
g_free(rec);
|
||||
sbars = g_list_remove(sbars, rec);
|
||||
if (!quitting) gui_statusbar_redraw_all();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gui_statusbar_init(void)
|
||||
{
|
||||
sbars = NULL;
|
||||
sbars_tag = 0;
|
||||
|
||||
gui_statusbar_create(FALSE);
|
||||
}
|
||||
|
||||
void gui_statusbar_deinit(void)
|
||||
{
|
||||
gui_statusbar_delete(FALSE, 0);
|
||||
}
|
||||
21
src/fe-text/gui-statusbar.h
Normal file
21
src/fe-text/gui-statusbar.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef __GUI_STATUSBAR_H
|
||||
#define __GUI_STATUSBAR_H
|
||||
|
||||
typedef void (*STATUSBAR_FUNC) (gint xpos, gint ypos, gint size);
|
||||
|
||||
/* create new statusbar, return position */
|
||||
gint gui_statusbar_create(gboolean up);
|
||||
void gui_statusbar_delete(gboolean up, gint ypos);
|
||||
|
||||
/* allocate area in statusbar, returns tag or -1 if failed */
|
||||
gint gui_statusbar_allocate(gint size, gboolean right_justify, gboolean up, gint ypos, STATUSBAR_FUNC func);
|
||||
void gui_statusbar_resize(gint tag, gint size);
|
||||
void gui_statusbar_remove(gint tag);
|
||||
|
||||
/* redraw item, -1 = all */
|
||||
void gui_statusbar_redraw(gint tag);
|
||||
|
||||
void gui_statusbar_init(void);
|
||||
void gui_statusbar_deinit(void);
|
||||
|
||||
#endif
|
||||
390
src/fe-text/gui-textwidget.c
Normal file
390
src/fe-text/gui-textwidget.c
Normal file
|
|
@ -0,0 +1,390 @@
|
|||
/*
|
||||
gui-textwidget.c : irssi
|
||||
|
||||
Copyright (C) 1999 Timo Sirainen
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "module-formats.h"
|
||||
#include "signals.h"
|
||||
#include "commands.h"
|
||||
#include "misc.h"
|
||||
#include "levels.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include "windows.h"
|
||||
|
||||
#include "screen.h"
|
||||
#include "gui-mainwindows.h"
|
||||
#include "gui-windows.h"
|
||||
|
||||
static gchar *gui_window_line2text(LINE_REC *line)
|
||||
{
|
||||
GString *str;
|
||||
gint color;
|
||||
gchar *ret, *ptr, *tmp;
|
||||
|
||||
g_return_val_if_fail(line != NULL, NULL);
|
||||
|
||||
str = g_string_new(NULL);
|
||||
|
||||
color = 0;
|
||||
for (ptr = line->text; ; ptr++)
|
||||
{
|
||||
if (*ptr != 0)
|
||||
{
|
||||
g_string_append_c(str, *ptr);
|
||||
continue;
|
||||
}
|
||||
|
||||
ptr++;
|
||||
if ((*ptr & 0x80) == 0)
|
||||
{
|
||||
/* set color */
|
||||
color = *ptr;
|
||||
g_string_sprintfa(str, "\003%c%c", (color & 0x07)+1, ((color & 0xf0) >> 4)+1);
|
||||
if (color & 0x08) g_string_sprintfa(str, "\002");
|
||||
}
|
||||
else switch ((guchar) *ptr)
|
||||
{
|
||||
case LINE_CMD_EOL:
|
||||
ret = str->str;
|
||||
g_string_free(str, FALSE);
|
||||
return ret;
|
||||
case LINE_CMD_CONTINUE:
|
||||
memcpy(&tmp, ptr+1, sizeof(gchar *));
|
||||
ptr = tmp-1;
|
||||
break;
|
||||
case LINE_CMD_UNDERLINE:
|
||||
g_string_append_c(str, 31);
|
||||
break;
|
||||
case LINE_CMD_COLOR8:
|
||||
g_string_sprintfa(str, "\003%c%c", 9, ((color & 0xf0) >> 4)+1);
|
||||
color &= 0xfff0;
|
||||
color |= 8|ATTR_COLOR8;
|
||||
break;
|
||||
case LINE_CMD_BEEP:
|
||||
break;
|
||||
case LINE_CMD_INDENT:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define LASTLOG_FLAG_NEW 0x01
|
||||
#define LASTLOG_FLAG_NOHEADERS 0x02
|
||||
#define LASTLOG_FLAG_WORD 0x04
|
||||
#define LASTLOG_FLAG_REGEXP 0x08
|
||||
|
||||
static int lastlog_parse_args(char *args, int *flags)
|
||||
{
|
||||
char **arglist, **tmp;
|
||||
int level;
|
||||
|
||||
/* level can be specified in arguments.. */
|
||||
level = 0; *flags = 0;
|
||||
arglist = g_strsplit(args, " ", -1);
|
||||
for (tmp = arglist; *tmp != NULL; tmp++) {
|
||||
if (strcmp(*tmp, "-") == 0)
|
||||
*flags |= LASTLOG_FLAG_NOHEADERS;
|
||||
else if (g_strcasecmp(*tmp, "-new") == 0)
|
||||
*flags |= LASTLOG_FLAG_NEW;
|
||||
else if (g_strcasecmp(*tmp, "-word") == 0)
|
||||
*flags |= LASTLOG_FLAG_WORD;
|
||||
else if (g_strcasecmp(*tmp, "-regexp") == 0)
|
||||
*flags |= LASTLOG_FLAG_REGEXP;
|
||||
else
|
||||
level |= level2bits(tmp[0]+1);
|
||||
}
|
||||
if (level == 0) level = MSGLEVEL_ALL;
|
||||
g_strfreev(arglist);
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
#define lastlog_match(line, level) \
|
||||
(((line)->level & level) != 0 && ((line)->level & MSGLEVEL_LASTLOG) == 0)
|
||||
|
||||
static GList *lastlog_window_startline(int only_new)
|
||||
{
|
||||
GList *startline, *tmp;
|
||||
|
||||
startline = WINDOW_GUI(active_win)->lines;
|
||||
if (!only_new) return startline;
|
||||
|
||||
for (tmp = startline; tmp != NULL; tmp = tmp->next) {
|
||||
LINE_REC *rec = tmp->data;
|
||||
|
||||
if (rec->level & MSGLEVEL_LASTLOG)
|
||||
startline = tmp;
|
||||
}
|
||||
|
||||
return startline;
|
||||
}
|
||||
|
||||
static GList *lastlog_find_startline(GList *list, int count, int start, int level)
|
||||
{
|
||||
GList *tmp;
|
||||
|
||||
if (count <= 0) return list;
|
||||
|
||||
for (tmp = g_list_last(list); tmp != NULL; tmp = tmp->prev) {
|
||||
LINE_REC *rec = tmp->data;
|
||||
|
||||
if (!lastlog_match(rec, level))
|
||||
continue;
|
||||
|
||||
if (start > 0) {
|
||||
start--;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (--count == 0)
|
||||
return tmp;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static void cmd_lastlog(const char *data)
|
||||
{
|
||||
GList *startline, *list, *tmp;
|
||||
char *params, *str, *args, *text, *countstr, *start;
|
||||
struct tm *tm;
|
||||
int level, flags, count;
|
||||
|
||||
g_return_if_fail(data != NULL);
|
||||
|
||||
params = cmd_get_params(data, 4 | PARAM_FLAG_OPTARGS, &args, &text, &countstr, &start);
|
||||
if (*start == '\0' && is_numeric(text, 0)) {
|
||||
if (is_numeric(countstr, 0))
|
||||
start = countstr;
|
||||
countstr = text;
|
||||
text = "";
|
||||
}
|
||||
count = atol(countstr);
|
||||
if (count == 0) count = -1;
|
||||
|
||||
level = lastlog_parse_args(args, &flags);
|
||||
startline = lastlog_window_startline(flags & LASTLOG_FLAG_NEW);
|
||||
|
||||
if ((flags & LASTLOG_FLAG_NOHEADERS) == 0)
|
||||
printformat(NULL, NULL, MSGLEVEL_LASTLOG, IRCTXT_LASTLOG_START);
|
||||
|
||||
list = gui_window_find_text(active_win, text, startline, flags & LASTLOG_FLAG_REGEXP, flags & LASTLOG_FLAG_WORD);
|
||||
tmp = lastlog_find_startline(list, count, atol(start), level);
|
||||
|
||||
for (; tmp != NULL && (count < 0 || count > 0); tmp = tmp->next, count--) {
|
||||
LINE_REC *rec = tmp->data;
|
||||
|
||||
if (!lastlog_match(rec, level))
|
||||
continue;
|
||||
|
||||
text = gui_window_line2text(rec);
|
||||
if (settings_get_bool("toggle_show_timestamps"))
|
||||
printtext(NULL, NULL, MSGLEVEL_LASTLOG, text);
|
||||
else {
|
||||
tm = localtime(&rec->time);
|
||||
|
||||
str = g_strdup_printf("[%02d:%02d] %s", tm->tm_hour, tm->tm_min, text);
|
||||
printtext(NULL, NULL, MSGLEVEL_LASTLOG, str);
|
||||
g_free(str);
|
||||
}
|
||||
g_free(text);
|
||||
}
|
||||
|
||||
if ((flags & LASTLOG_FLAG_NOHEADERS) == 0)
|
||||
printformat(NULL, NULL, MSGLEVEL_LASTLOG, IRCTXT_LASTLOG_END);
|
||||
|
||||
g_list_free(list);
|
||||
g_free(params);
|
||||
}
|
||||
|
||||
static void cmd_scrollback(gchar *data, SERVER_REC *server, WI_ITEM_REC *item)
|
||||
{
|
||||
command_runsub("scrollback", data, server, item);
|
||||
}
|
||||
|
||||
static void cmd_scrollback_clear(gchar *data)
|
||||
{
|
||||
gui_window_clear(active_win);
|
||||
}
|
||||
|
||||
static void scrollback_goto_pos(WINDOW_REC *window, GList *pos)
|
||||
{
|
||||
GUI_WINDOW_REC *gui;
|
||||
|
||||
g_return_if_fail(window != NULL);
|
||||
g_return_if_fail(pos != NULL);
|
||||
|
||||
gui = WINDOW_GUI(window);
|
||||
|
||||
if (g_list_find(gui->bottom_startline, pos->data) == NULL)
|
||||
{
|
||||
gui->startline = pos;
|
||||
gui->subline = 0;
|
||||
gui->bottom = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* reached the last line */
|
||||
if (gui->bottom) return;
|
||||
|
||||
gui->bottom = TRUE;
|
||||
gui->startline = gui->bottom_startline;
|
||||
gui->subline = gui->bottom_subline;
|
||||
gui->ypos = last_text_line-first_text_line-1;
|
||||
}
|
||||
|
||||
if (is_window_visible(window))
|
||||
gui_window_redraw(window);
|
||||
signal_emit("gui page scrolled", 1, window);
|
||||
}
|
||||
|
||||
static void cmd_scrollback_goto(gchar *data)
|
||||
{
|
||||
GList *pos;
|
||||
gchar *params, *arg1, *arg2;
|
||||
gint lines;
|
||||
|
||||
params = cmd_get_params(data, 2, &arg1, &arg2);
|
||||
if (*arg2 == '\0' && (*arg1 == '-' || *arg1 == '+'))
|
||||
{
|
||||
/* go forward/backward n lines */
|
||||
if (sscanf(arg1 + (*arg1 == '-' ? 0 : 1), "%d", &lines) == 1)
|
||||
gui_window_scroll(active_win, lines);
|
||||
}
|
||||
else if (*arg2 == '\0' && strchr(arg1, ':') == NULL && strchr(arg1, '.') == NULL &&
|
||||
sscanf(arg1, "%d", &lines) == 1)
|
||||
{
|
||||
/* go to n'th line. */
|
||||
pos = g_list_nth(WINDOW_GUI(active_win)->lines, lines);
|
||||
if (pos != NULL)
|
||||
scrollback_goto_pos(active_win, pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct tm tm;
|
||||
time_t stamp;
|
||||
gint day, month;
|
||||
|
||||
/* [dd.mm | -<days ago>] hh:mi[:ss] */
|
||||
stamp = time(NULL);
|
||||
if (*arg1 == '-')
|
||||
{
|
||||
/* -<days ago> */
|
||||
if (sscanf(arg1+1, "%d", &day) == 1)
|
||||
stamp -= day*3600*24;
|
||||
memcpy(&tm, localtime(&stamp), sizeof(struct tm));
|
||||
}
|
||||
else if (*arg2 != '\0')
|
||||
{
|
||||
/* dd.mm */
|
||||
if (sscanf(arg1, "%d.%d", &day, &month) == 2)
|
||||
{
|
||||
month--;
|
||||
memcpy(&tm, localtime(&stamp), sizeof(struct tm));
|
||||
|
||||
if (tm.tm_mon < month)
|
||||
tm.tm_year--;
|
||||
tm.tm_mon = month;
|
||||
tm.tm_mday = day;
|
||||
stamp = mktime(&tm);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* move time argument to arg2 */
|
||||
arg2 = arg1;
|
||||
}
|
||||
|
||||
/* hh:mi[:ss] */
|
||||
memcpy(&tm, localtime(&stamp), sizeof(struct tm));
|
||||
tm.tm_sec = 0;
|
||||
sscanf(arg2, "%d:%d:%d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
|
||||
stamp = mktime(&tm);
|
||||
|
||||
/* find the first line after timestamp */
|
||||
for (pos = WINDOW_GUI(active_win)->lines; pos != NULL; pos = pos->next)
|
||||
{
|
||||
LINE_REC *rec = pos->data;
|
||||
|
||||
if (rec->time >= stamp)
|
||||
{
|
||||
scrollback_goto_pos(active_win, pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
g_free(params);
|
||||
}
|
||||
|
||||
static void cmd_scrollback_home(gchar *data)
|
||||
{
|
||||
GUI_WINDOW_REC *gui;
|
||||
|
||||
gui = WINDOW_GUI(active_win);
|
||||
|
||||
if (gui->bottom_startline == gui->startline)
|
||||
return;
|
||||
|
||||
gui->bottom = FALSE;
|
||||
gui->startline = gui->lines;
|
||||
gui->subline = 0;
|
||||
|
||||
if (is_window_visible(active_win))
|
||||
gui_window_redraw(active_win);
|
||||
signal_emit("gui page scrolled", 1, active_win);
|
||||
}
|
||||
|
||||
static void cmd_scrollback_end(gchar *data)
|
||||
{
|
||||
GUI_WINDOW_REC *gui;
|
||||
|
||||
gui = WINDOW_GUI(active_win);
|
||||
|
||||
gui->bottom = TRUE;
|
||||
gui->startline = gui->bottom_startline;
|
||||
gui->subline = gui->bottom_subline;
|
||||
gui->ypos = last_text_line-first_text_line-1;
|
||||
|
||||
if (is_window_visible(active_win))
|
||||
gui_window_redraw(active_win);
|
||||
signal_emit("gui page scrolled", 1, active_win);
|
||||
}
|
||||
|
||||
void gui_textwidget_init(void)
|
||||
{
|
||||
command_bind("lastlog", NULL, (SIGNAL_FUNC) cmd_lastlog);
|
||||
command_bind("scrollback", NULL, (SIGNAL_FUNC) cmd_scrollback);
|
||||
command_bind("scrollback clear", NULL, (SIGNAL_FUNC) cmd_scrollback_clear);
|
||||
command_bind("scrollback goto", NULL, (SIGNAL_FUNC) cmd_scrollback_goto);
|
||||
command_bind("scrollback home", NULL, (SIGNAL_FUNC) cmd_scrollback_home);
|
||||
command_bind("scrollback end", NULL, (SIGNAL_FUNC) cmd_scrollback_end);
|
||||
}
|
||||
|
||||
void gui_textwidget_deinit(void)
|
||||
{
|
||||
command_unbind("lastlog", (SIGNAL_FUNC) cmd_lastlog);
|
||||
command_unbind("scrollback", (SIGNAL_FUNC) cmd_scrollback);
|
||||
command_unbind("scrollback clear", (SIGNAL_FUNC) cmd_scrollback_clear);
|
||||
command_unbind("scrollback goto", (SIGNAL_FUNC) cmd_scrollback_goto);
|
||||
command_unbind("scrollback home", (SIGNAL_FUNC) cmd_scrollback_home);
|
||||
command_unbind("scrollback end", (SIGNAL_FUNC) cmd_scrollback_end);
|
||||
}
|
||||
7
src/fe-text/gui-textwidget.h
Normal file
7
src/fe-text/gui-textwidget.h
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef __GUI_TEXTWIDGET_H
|
||||
#define __GUI_TEXTWIDGET_H
|
||||
|
||||
void gui_textwidget_init(void);
|
||||
void gui_textwidget_deinit(void);
|
||||
|
||||
#endif
|
||||
780
src/fe-text/gui-windows.c
Normal file
780
src/fe-text/gui-windows.c
Normal file
|
|
@ -0,0 +1,780 @@
|
|||
/*
|
||||
gui-windows.c : irssi
|
||||
|
||||
Copyright (C) 1999 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 "commands.h"
|
||||
#include "server.h"
|
||||
#include "misc.h"
|
||||
|
||||
#include "irc.h"
|
||||
#include "channels.h"
|
||||
#include "windows.h"
|
||||
|
||||
#include "screen.h"
|
||||
#include "gui-entry.h"
|
||||
#include "gui-mainwindows.h"
|
||||
#include "gui-windows.h"
|
||||
|
||||
#include <regex.h>
|
||||
|
||||
#define DEFAULT_INDENT_POS 10
|
||||
|
||||
int first_text_line = 0, last_text_line = 0;
|
||||
|
||||
static GUI_WINDOW_REC *gui_window_init(WINDOW_REC *window, MAIN_WINDOW_REC *parent)
|
||||
{
|
||||
GUI_WINDOW_REC *gui;
|
||||
|
||||
gui = g_new0(GUI_WINDOW_REC, 1);
|
||||
gui->parent = parent;
|
||||
|
||||
gui->bottom = TRUE;
|
||||
gui->line_chunk = g_mem_chunk_new("line chunk", sizeof(LINE_REC),
|
||||
sizeof(LINE_REC)*100, G_ALLOC_AND_FREE);
|
||||
gui->empty_linecount = last_text_line-first_text_line-1;
|
||||
|
||||
return gui;
|
||||
}
|
||||
|
||||
static void gui_window_deinit(GUI_WINDOW_REC *gui)
|
||||
{
|
||||
g_slist_foreach(gui->text_chunks, (GFunc) g_free, NULL);
|
||||
g_slist_free(gui->text_chunks);
|
||||
|
||||
g_mem_chunk_destroy(gui->line_chunk);
|
||||
g_list_free(gui->lines);
|
||||
|
||||
g_free(gui);
|
||||
}
|
||||
|
||||
static void gui_window_created(WINDOW_REC *window)
|
||||
{
|
||||
MAIN_WINDOW_REC *parent;
|
||||
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
parent = (active_win == NULL || WINDOW_GUI(active_win) == NULL) ?
|
||||
gui_mainwindow_create() : WINDOW_GUI(active_win)->parent;
|
||||
if (parent->children == NULL) parent->active = window;
|
||||
parent->children = g_list_append(parent->children, window);
|
||||
|
||||
window->gui_data = gui_window_init(window, parent);
|
||||
signal_emit("gui window created", 1, window);
|
||||
}
|
||||
|
||||
static void gui_window_destroyed(WINDOW_REC *window)
|
||||
{
|
||||
MAIN_WINDOW_REC *parent;
|
||||
GUI_WINDOW_REC *gui;
|
||||
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
gui = WINDOW_GUI(window);
|
||||
parent = gui->parent;
|
||||
parent->children = g_list_remove(parent->children, window);
|
||||
|
||||
signal_emit("gui window destroyed", 1, window);
|
||||
|
||||
gui_window_deinit(gui);
|
||||
window->gui_data = NULL;
|
||||
|
||||
if (parent->children == NULL)
|
||||
gui_mainwindow_destroy(parent);
|
||||
|
||||
if (windows != NULL && active_win == window && !quitting)
|
||||
window_set_active(windows->data);
|
||||
}
|
||||
|
||||
void gui_window_clear(WINDOW_REC *window)
|
||||
{
|
||||
MAIN_WINDOW_REC *parent;
|
||||
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
parent = WINDOW_GUI(window)->parent;
|
||||
gui_window_deinit(WINDOW_GUI(window));
|
||||
window->gui_data = gui_window_init(window, parent);
|
||||
|
||||
window->lines = 0;
|
||||
|
||||
if (is_window_visible(window))
|
||||
gui_window_redraw(window);
|
||||
}
|
||||
|
||||
gint gui_window_update_bottom(GUI_WINDOW_REC *gui, gint lines)
|
||||
{
|
||||
gint 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)
|
||||
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 >= last_text_line-first_text_line-1;
|
||||
|
||||
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(first_text_line, last_text_line-1);
|
||||
move(last_text_line-1, 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_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_EOL:
|
||||
return lines;
|
||||
case LINE_CMD_CONTINUE:
|
||||
memcpy(&tmp, ptr+1, sizeof(gchar *));
|
||||
ptr = tmp-1;
|
||||
break;
|
||||
case LINE_CMD_UNDERLINE:
|
||||
color ^= ATTR_UNDERLINE;
|
||||
break;
|
||||
case LINE_CMD_COLOR8:
|
||||
color &= 0xfff0;
|
||||
color |= 8|ATTR_COLOR8;
|
||||
break;
|
||||
case LINE_CMD_BEEP:
|
||||
beep();
|
||||
break;
|
||||
case LINE_CMD_INDENT:
|
||||
indent_pos = xpos;
|
||||
break;
|
||||
}
|
||||
set_color(color);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (xpos == COLS)
|
||||
{
|
||||
xpos = indent_pos >= COLS-5 ? DEFAULT_INDENT_POS : indent_pos;
|
||||
|
||||
if (last_space > indent_pos && last_space > 10)
|
||||
{
|
||||
/* remove the last word */
|
||||
if (!skip)
|
||||
{
|
||||
move(ypos, last_space);
|
||||
set_color(0);
|
||||
clrtoeol();
|
||||
}
|
||||
|
||||
/* skip backwards to draw the line again. */
|
||||
ptr = last_space_ptr;
|
||||
color = last_space_color;
|
||||
if (!skip) set_color(color);
|
||||
while (*ptr == ' ') ptr++;
|
||||
}
|
||||
last_space = 0;
|
||||
|
||||
if (skip > 0)
|
||||
{
|
||||
if (--skip == 0) set_color(color);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lines == max)
|
||||
return lines;
|
||||
if (max != -1)
|
||||
ypos++;
|
||||
else
|
||||
{
|
||||
gui_window_newline(gui, TRUE);
|
||||
ypos = first_text_line+gui->ypos;
|
||||
}
|
||||
lines++;
|
||||
}
|
||||
move(ypos, indent_pos);
|
||||
|
||||
/* we could have \0.. */
|
||||
ptr--;
|
||||
continue;
|
||||
}
|
||||
|
||||
xpos++;
|
||||
if (*ptr == ' ')
|
||||
{
|
||||
last_space = xpos-1;
|
||||
last_space_color = color;
|
||||
last_space_ptr = ptr+1;
|
||||
}
|
||||
|
||||
if (skip) continue;
|
||||
if (lines == -1) lines = 0;
|
||||
|
||||
if ((guchar) *ptr >= 32)
|
||||
addch((guchar) *ptr);
|
||||
else
|
||||
{
|
||||
/* low-ascii */
|
||||
set_color(ATTR_REVERSE);
|
||||
addch(*ptr+'A'-1);
|
||||
set_color(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gui_window_redraw(WINDOW_REC *window)
|
||||
{
|
||||
GUI_WINDOW_REC *gui;
|
||||
GList *line;
|
||||
gint ypos, lines, skip, max;
|
||||
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
gui = WINDOW_GUI(window);
|
||||
|
||||
for (ypos = first_text_line; ypos < last_text_line; ypos++)
|
||||
{
|
||||
set_color(0);
|
||||
move(ypos, 0);
|
||||
clrtoeol();
|
||||
}
|
||||
|
||||
skip = gui->subline;
|
||||
ypos = first_text_line;
|
||||
for (line = gui->startline; line != NULL; line = line->next)
|
||||
{
|
||||
LINE_REC *rec = line->data;
|
||||
|
||||
max = last_text_line - ypos-1;
|
||||
if (max < 0) break;
|
||||
|
||||
lines = gui_window_line_draw(gui, rec, ypos, skip, max);
|
||||
skip = 0;
|
||||
|
||||
ypos += lines+1;
|
||||
}
|
||||
screen_refresh();
|
||||
}
|
||||
|
||||
static void gui_window_scroll_up(GUI_WINDOW_REC *gui, gint lines)
|
||||
{
|
||||
LINE_REC *line;
|
||||
gint count, linecount;
|
||||
|
||||
if (gui->startline == NULL)
|
||||
return;
|
||||
|
||||
count = lines-gui->subline; gui->ypos += gui->subline;
|
||||
gui->subline = 0;
|
||||
|
||||
while (gui->startline->prev != NULL && count > 0)
|
||||
{
|
||||
gui->startline = gui->startline->prev;
|
||||
|
||||
line = gui->startline->data;
|
||||
linecount = gui_window_get_linecount(gui, line);
|
||||
count -= linecount;
|
||||
gui->ypos += linecount;
|
||||
}
|
||||
|
||||
if (count < 0)
|
||||
{
|
||||
gui->subline = -count;
|
||||
gui->ypos -= -count;
|
||||
}
|
||||
|
||||
gui->bottom = (gui->ypos >= -1 && gui->ypos <= last_text_line-first_text_line-1);
|
||||
}
|
||||
|
||||
static void gui_window_scroll_down(GUI_WINDOW_REC *gui, gint lines)
|
||||
{
|
||||
LINE_REC *line;
|
||||
gint count, linecount;
|
||||
|
||||
if (gui->startline == gui->bottom_startline && gui->subline == gui->bottom_subline)
|
||||
return;
|
||||
|
||||
count = lines+gui->subline; gui->ypos += gui->subline;
|
||||
gui->subline = 0;
|
||||
|
||||
while (count > 0)
|
||||
{
|
||||
line = gui->startline->data;
|
||||
|
||||
linecount = gui_window_get_linecount(gui, line);
|
||||
count -= linecount;
|
||||
gui->ypos -= linecount;
|
||||
|
||||
if (gui->startline == gui->bottom_startline &&
|
||||
linecount+count > gui->bottom_subline)
|
||||
{
|
||||
/* reached the last screenful of text */
|
||||
gui->subline = gui->bottom_subline;
|
||||
gui->ypos += linecount;
|
||||
gui->ypos -= gui->subline;
|
||||
break;
|
||||
}
|
||||
|
||||
if (count <= 0)
|
||||
{
|
||||
gui->subline = linecount+count;
|
||||
gui->ypos += -count;
|
||||
break;
|
||||
}
|
||||
|
||||
if (gui->startline->next == NULL)
|
||||
{
|
||||
gui->subline = linecount;
|
||||
break;
|
||||
}
|
||||
gui->startline = gui->startline->next;
|
||||
}
|
||||
|
||||
gui->bottom = (gui->ypos >= -1 && gui->ypos <= last_text_line-first_text_line-1);
|
||||
}
|
||||
|
||||
void gui_window_scroll(WINDOW_REC *window, gint lines)
|
||||
{
|
||||
GUI_WINDOW_REC *gui;
|
||||
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
gui = WINDOW_GUI(window);
|
||||
|
||||
if (lines < 0)
|
||||
gui_window_scroll_up(gui, -lines);
|
||||
else
|
||||
gui_window_scroll_down(gui, lines);
|
||||
|
||||
if (is_window_visible(window))
|
||||
gui_window_redraw(window);
|
||||
signal_emit("gui page scrolled", 1, window);
|
||||
}
|
||||
|
||||
static void window_update_prompt(WINDOW_REC *window)
|
||||
{
|
||||
WI_ITEM_REC *item;
|
||||
char *text, *str;
|
||||
|
||||
item = window->active;
|
||||
if (item != NULL)
|
||||
text = item->name;
|
||||
else if (window->name != NULL)
|
||||
text = window->name;
|
||||
else {
|
||||
gui_entry_set_prompt("");
|
||||
return;
|
||||
}
|
||||
|
||||
/* set prompt */
|
||||
str = g_strdup_printf("[%1.17s] ", text);
|
||||
gui_entry_set_prompt(str);
|
||||
if (*str != '\0') g_free(str);
|
||||
}
|
||||
|
||||
static void signal_window_changed(WINDOW_REC *window)
|
||||
{
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
WINDOW_GUI(window)->parent->active = window;
|
||||
|
||||
screen_refresh_freeze();
|
||||
window_update_prompt(window);
|
||||
gui_window_redraw(window);
|
||||
screen_refresh_thaw();
|
||||
}
|
||||
|
||||
static void signal_window_item_update(WINDOW_REC *window)
|
||||
{
|
||||
CHANNEL_REC *channel;
|
||||
|
||||
channel = irc_item_channel(window->active);
|
||||
if (channel != NULL) {
|
||||
/* redraw channel widgets */
|
||||
signal_emit("channel topic changed", 1, channel);
|
||||
signal_emit("channel mode changed", 1, channel);
|
||||
}
|
||||
|
||||
window_update_prompt(window);
|
||||
}
|
||||
|
||||
GList *gui_window_find_text(WINDOW_REC *window, gchar *text, GList *startline, int regexp, int fullword)
|
||||
{
|
||||
regex_t preg;
|
||||
GList *tmp;
|
||||
GList *matches;
|
||||
gchar *str, *ptr;
|
||||
gint n, size;
|
||||
|
||||
g_return_val_if_fail(window != NULL, NULL);
|
||||
g_return_val_if_fail(text != NULL, NULL);
|
||||
|
||||
text = g_strdup(text); g_strup(text);
|
||||
matches = NULL; size = 1024; str = g_malloc(1024);
|
||||
|
||||
if (regcomp(&preg, text, REG_EXTENDED|REG_NOSUB) != 0) {
|
||||
g_free(text);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (startline == NULL) startline = WINDOW_GUI(window)->lines;
|
||||
for (tmp = startline; tmp != NULL; tmp = tmp->next)
|
||||
{
|
||||
LINE_REC *rec = tmp->data;
|
||||
|
||||
for (n = 0, ptr = rec->text; ; ptr++)
|
||||
{
|
||||
if (*ptr != 0)
|
||||
{
|
||||
if (n+2 > size)
|
||||
{
|
||||
size += 1024;
|
||||
str = g_realloc(str, size);
|
||||
}
|
||||
str[n++] = toupper(*ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr++;
|
||||
|
||||
if ((guchar) *ptr == LINE_CMD_CONTINUE)
|
||||
{
|
||||
gchar *tmp;
|
||||
|
||||
memcpy(&tmp, ptr+1, sizeof(gchar *));
|
||||
ptr = tmp-1;
|
||||
}
|
||||
else if ((guchar) *ptr == LINE_CMD_EOL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
str[n] = '\0';
|
||||
|
||||
if (regexp ? /*regexec(&preg, str, 0, NULL, 0) == 0*/regexp_match(str, text) :
|
||||
fullword ? stristr_full(str, text) != NULL :
|
||||
strstr(str, text) != NULL) {
|
||||
/* matched */
|
||||
matches = g_list_append(matches, rec);
|
||||
}
|
||||
}
|
||||
regfree(&preg);
|
||||
|
||||
if (str != NULL) g_free(str);
|
||||
g_free(text);
|
||||
return matches;
|
||||
}
|
||||
|
||||
static void gui_window_horiz_resize(WINDOW_REC *window)
|
||||
{
|
||||
GUI_WINDOW_REC *gui;
|
||||
gint linecount;
|
||||
|
||||
gui = WINDOW_GUI(window);
|
||||
if (gui->lines == NULL) return;
|
||||
|
||||
linecount = gui_window_get_linecount(gui, g_list_last(gui->lines)->data);
|
||||
gui->last_subline = linecount-1;
|
||||
|
||||
/* fake a /CLEAR and scroll window up one page */
|
||||
gui->ypos = -1;
|
||||
gui->bottom = TRUE;
|
||||
gui->empty_linecount = last_text_line-first_text_line-1;
|
||||
|
||||
gui->bottom_startline = gui->startline = g_list_last(gui->lines);
|
||||
gui->bottom_subline = gui->subline = gui->last_subline+1;
|
||||
gui_window_scroll(window, -gui->empty_linecount-1);
|
||||
|
||||
gui->bottom_startline = gui->startline;
|
||||
gui->bottom_subline = gui->subline;
|
||||
|
||||
/* remove the empty lines from the end */
|
||||
if (gui->bottom && gui->startline == gui->lines)
|
||||
gui->empty_linecount = (last_text_line-first_text_line-1);
|
||||
else
|
||||
gui->empty_linecount = 0;
|
||||
}
|
||||
|
||||
void gui_windows_resize(gint ychange, gboolean xchange)
|
||||
{
|
||||
GUI_WINDOW_REC *gui;
|
||||
WINDOW_REC *window;
|
||||
GSList *tmp;
|
||||
|
||||
screen_refresh_freeze();
|
||||
for (tmp = windows; tmp != NULL; tmp = tmp->next)
|
||||
{
|
||||
window = tmp->data;
|
||||
|
||||
gui = WINDOW_GUI(window);
|
||||
|
||||
if (xchange)
|
||||
{
|
||||
/* window width changed, we'll need to recalculate a few things.. */
|
||||
gui_window_horiz_resize(window);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ychange < 0 && gui->empty_linecount > 0)
|
||||
{
|
||||
/* empty space at the bottom of the screen - just eat it. */
|
||||
gui->empty_linecount += ychange;
|
||||
if (gui->empty_linecount < 0)
|
||||
gui->empty_linecount = 0;
|
||||
}
|
||||
else if (gui->bottom && gui->startline == gui->lines && ychange > 0)
|
||||
{
|
||||
/* less than screenful of text, add empty space */
|
||||
gui->empty_linecount += ychange;
|
||||
}
|
||||
else
|
||||
{
|
||||
gui_window_update_bottom(WINDOW_GUI(window), -ychange);
|
||||
gui_window_scroll(window, -ychange);
|
||||
}
|
||||
}
|
||||
|
||||
irssi_redraw();
|
||||
screen_refresh_thaw();
|
||||
}
|
||||
|
||||
static void cmd_window_move(gchar *data)
|
||||
{
|
||||
GSList *w1, *w2;
|
||||
WINDOW_REC *window;
|
||||
|
||||
g_return_if_fail(data != NULL);
|
||||
|
||||
window = active_win;
|
||||
w1 = g_slist_find(windows, window);
|
||||
if (g_strcasecmp(data, "LEFT") == 0 || g_strncasecmp(data, "PREV", 4) == 0)
|
||||
{
|
||||
w2 = g_slist_nth(windows, g_slist_index(windows, window)-1);
|
||||
if (w2 == NULL)
|
||||
{
|
||||
window = w1->data;
|
||||
windows = g_slist_remove(windows, window);
|
||||
windows = g_slist_append(windows, window);
|
||||
w2 = g_slist_last(windows);
|
||||
}
|
||||
}
|
||||
else if (g_strcasecmp(data, "RIGHT") == 0 || g_strcasecmp(data, "NEXT") == 0)
|
||||
{
|
||||
w2 = w1->next;
|
||||
if (w2 == NULL)
|
||||
{
|
||||
window = w1->data;
|
||||
windows = g_slist_remove(windows, window);
|
||||
windows = g_slist_prepend(windows, window);
|
||||
}
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
if (w2 != NULL)
|
||||
{
|
||||
window = w1->data;
|
||||
w1->data = w2->data;
|
||||
w2->data = window;
|
||||
}
|
||||
|
||||
window_set_active(window);
|
||||
}
|
||||
|
||||
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("window changed", (SIGNAL_FUNC) signal_window_changed);
|
||||
signal_add("window item changed", (SIGNAL_FUNC) signal_window_item_update);
|
||||
signal_add("window name changed", (SIGNAL_FUNC) signal_window_item_update);
|
||||
signal_add("window item remove", (SIGNAL_FUNC) signal_window_item_update);
|
||||
command_bind("window move", NULL, (SIGNAL_FUNC) cmd_window_move);
|
||||
}
|
||||
|
||||
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 changed", (SIGNAL_FUNC) signal_window_item_update);
|
||||
signal_remove("window name changed", (SIGNAL_FUNC) signal_window_item_update);
|
||||
signal_remove("window item remove", (SIGNAL_FUNC) signal_window_item_update);
|
||||
command_unbind("window move", (SIGNAL_FUNC) cmd_window_move);
|
||||
}
|
||||
93
src/fe-text/gui-windows.h
Normal file
93
src/fe-text/gui-windows.h
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
#ifndef __GUI_WINDOWS_H
|
||||
#define __GUI_WINDOWS_H
|
||||
|
||||
#include "server.h"
|
||||
#include "gui-mainwindows.h"
|
||||
|
||||
#define WINDOW_GUI(a) ((GUI_WINDOW_REC *) ((a)->gui_data))
|
||||
|
||||
#define is_window_visible(win) \
|
||||
(WINDOW_GUI(win)->parent->active == (win))
|
||||
|
||||
#define LINE_TEXT_CHUNK_SIZE 2048
|
||||
|
||||
/* 7 first bits of LINE_REC's info byte. */
|
||||
enum
|
||||
{
|
||||
LINE_CMD_EOL=0x80, /* line ends here. */
|
||||
LINE_CMD_CONTINUE, /* line continues in next block */
|
||||
LINE_CMD_COLOR8, /* change to dark grey, normally 8 = bold black */
|
||||
LINE_CMD_UNDERLINE, /* enable/disable underlining */
|
||||
LINE_CMD_BEEP, /* beep */
|
||||
LINE_CMD_INDENT /* if line is split, indent it at this position */
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gchar *text; /* text in the line. \0 means that the next char will be a
|
||||
color or command. <= 127 = color or if 8.bit is set, the
|
||||
first 7 bits are the command. See LINE_CMD_xxxx. */
|
||||
|
||||
gint32 level;
|
||||
time_t time;
|
||||
}
|
||||
LINE_REC;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gchar buffer[LINE_TEXT_CHUNK_SIZE];
|
||||
gint pos;
|
||||
gint lines;
|
||||
}
|
||||
TEXT_CHUNK_REC;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MAIN_WINDOW_REC *parent;
|
||||
|
||||
GMemChunk *line_chunk;
|
||||
GSList *text_chunks;
|
||||
GList *lines;
|
||||
|
||||
LINE_REC *cur_line;
|
||||
TEXT_CHUNK_REC *cur_text;
|
||||
|
||||
gint xpos, ypos; /* cursor position in screen */
|
||||
GList *startline; /* line at the top of the screen */
|
||||
gint subline; /* number of "real lines" to skip from `startline' */
|
||||
|
||||
GList *bottom_startline; /* marks the bottom of the text buffer */
|
||||
gint bottom_subline;
|
||||
gint empty_linecount; /* how many empty lines are in screen.
|
||||
a screenful when started or used /CLEAR */
|
||||
gboolean bottom; /* window is at the bottom of the text buffer */
|
||||
|
||||
/* for gui-printtext.c */
|
||||
gint last_subline;
|
||||
gint last_color, last_flags;
|
||||
}
|
||||
GUI_WINDOW_REC;
|
||||
|
||||
extern gint first_text_line, last_text_line;
|
||||
|
||||
void gui_windows_init(void);
|
||||
void gui_windows_deinit(void);
|
||||
|
||||
WINDOW_REC *gui_window_create(MAIN_WINDOW_REC *parent);
|
||||
|
||||
void gui_window_set_server(WINDOW_REC *window, SERVER_REC *server);
|
||||
GList *gui_window_find_text(WINDOW_REC *window, gchar *text, GList *startline, int regexp, int fullword);
|
||||
|
||||
/* get number of real lines that line record takes */
|
||||
gint gui_window_get_linecount(GUI_WINDOW_REC *gui, LINE_REC *line);
|
||||
gint gui_window_line_draw(GUI_WINDOW_REC *gui, LINE_REC *line, gint ypos, gint skip, gint max);
|
||||
|
||||
void gui_window_clear(WINDOW_REC *window);
|
||||
void gui_window_redraw(WINDOW_REC *window);
|
||||
void gui_windows_resize(gint ychange, gboolean xchange);
|
||||
|
||||
void gui_window_newline(GUI_WINDOW_REC *gui, gboolean visible);
|
||||
gint gui_window_update_bottom(GUI_WINDOW_REC *gui, gint lines);
|
||||
void gui_window_scroll(WINDOW_REC *window, gint lines);
|
||||
|
||||
#endif
|
||||
156
src/fe-text/irssi.c
Normal file
156
src/fe-text/irssi.c
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
irssi.c : irssi
|
||||
|
||||
Copyright (C) 1999-2000 Timo Sirainen
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "args.h"
|
||||
#include "signals.h"
|
||||
#include "core.h"
|
||||
|
||||
#include "irc-core.h"
|
||||
#include "fe-common-core.h"
|
||||
#include "fe-common-irc.h"
|
||||
|
||||
#include "screen.h"
|
||||
#include "gui-entry.h"
|
||||
#include "gui-mainwindows.h"
|
||||
#include "gui-printtext.h"
|
||||
#include "gui-readline.h"
|
||||
#include "gui-special-vars.h"
|
||||
#include "gui-statusbar.h"
|
||||
#include "gui-statusbar-items.h"
|
||||
#include "gui-textwidget.h"
|
||||
#include "gui-windows.h"
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
void irc_init(void);
|
||||
void irc_deinit(void);
|
||||
|
||||
static GMainLoop *main_loop;
|
||||
int quitting;
|
||||
|
||||
static void sig_exit(void)
|
||||
{
|
||||
g_main_quit(main_loop);
|
||||
}
|
||||
|
||||
/* redraw irssi's screen.. */
|
||||
void irssi_redraw(void)
|
||||
{
|
||||
clear();
|
||||
|
||||
/* current window */
|
||||
gui_window_redraw(active_win);
|
||||
/* statusbar */
|
||||
gui_statusbar_redraw(-1);
|
||||
/* entry line */
|
||||
gui_entry_redraw();
|
||||
}
|
||||
|
||||
static void textui_init(void)
|
||||
{
|
||||
static struct poptOption options[] = {
|
||||
POPT_AUTOHELP
|
||||
{ NULL, '\0', 0, NULL }
|
||||
};
|
||||
|
||||
args_register(options);
|
||||
|
||||
irssi_gui = IRSSI_GUI_TEXT;
|
||||
core_init();
|
||||
irc_init();
|
||||
fe_common_core_init();
|
||||
fe_common_irc_init();
|
||||
signal_add("gui exit", (SIGNAL_FUNC) sig_exit);
|
||||
}
|
||||
|
||||
static void textui_finish_init(void)
|
||||
{
|
||||
quitting = FALSE;
|
||||
|
||||
screen_refresh_freeze();
|
||||
gui_entry_init();
|
||||
gui_mainwindows_init();
|
||||
gui_printtext_init();
|
||||
gui_readline_init();
|
||||
gui_special_vars_init();
|
||||
gui_textwidget_init();
|
||||
gui_windows_init();
|
||||
|
||||
fe_common_core_finish_init();
|
||||
fe_common_irc_finish_init();
|
||||
|
||||
gui_statusbar_init();
|
||||
gui_statusbar_items_init();
|
||||
|
||||
signal_emit("irssi init finished", 0);
|
||||
screen_refresh_thaw();
|
||||
}
|
||||
|
||||
static void textui_deinit(void)
|
||||
{
|
||||
quitting = TRUE;
|
||||
signal(SIGINT, SIG_DFL);
|
||||
|
||||
signal_remove("gui exit", (SIGNAL_FUNC) sig_exit);
|
||||
gui_textwidget_deinit();
|
||||
gui_special_vars_deinit();
|
||||
gui_statusbar_items_deinit();
|
||||
gui_statusbar_deinit();
|
||||
gui_printtext_deinit();
|
||||
gui_readline_deinit();
|
||||
gui_mainwindows_deinit();
|
||||
gui_windows_deinit();
|
||||
gui_entry_deinit();
|
||||
deinit_screen();
|
||||
|
||||
fe_common_irc_deinit();
|
||||
fe_common_core_deinit();
|
||||
irc_deinit();
|
||||
core_deinit();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#ifdef HAVE_SOCKS
|
||||
SOCKSinit(argv[0]);
|
||||
#endif
|
||||
|
||||
textui_init();
|
||||
args_execute(argc, argv);
|
||||
|
||||
if (!init_screen())
|
||||
{
|
||||
printf("Can't initialize screen handling, quitting.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
textui_finish_init();
|
||||
main_loop = g_main_new(TRUE);
|
||||
g_main_run(main_loop);
|
||||
g_main_destroy(main_loop);
|
||||
textui_deinit();
|
||||
|
||||
#ifdef MEM_DEBUG
|
||||
ig_mem_profile();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
30
src/fe-text/module-formats.c
Normal file
30
src/fe-text/module-formats.c
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
module-formats.c : irssi
|
||||
|
||||
Copyright (C) 2000 Timo Sirainen
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "printtext.h"
|
||||
|
||||
FORMAT_REC gui_text_formats[] =
|
||||
{
|
||||
{ MODULE_NAME, N_("Text user interface"), 0 },
|
||||
|
||||
{ "lastlog_start", N_("%_Lastlog:"), 0 },
|
||||
{ "lastlog_end", N_("%_End of Lastlog"), 0 },
|
||||
};
|
||||
11
src/fe-text/module-formats.h
Normal file
11
src/fe-text/module-formats.h
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#include "printtext.h"
|
||||
|
||||
enum {
|
||||
IRCTXT_MODULE_NAME,
|
||||
|
||||
IRCTXT_LASTLOG_START,
|
||||
IRCTXT_LASTLOG_END
|
||||
};
|
||||
|
||||
extern FORMAT_REC gui_text_formats[];
|
||||
#define MODULE_FORMATS gui_text_formats
|
||||
6
src/fe-text/module.h
Normal file
6
src/fe-text/module.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#include "common.h"
|
||||
|
||||
#define MODULE_NAME "gui-text"
|
||||
|
||||
extern int quitting;
|
||||
void irssi_redraw(void);
|
||||
254
src/fe-text/screen.c
Normal file
254
src/fe-text/screen.c
Normal file
|
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
screen.c : All virtual screen management, real screen management is in
|
||||
con_???.c files.
|
||||
|
||||
Copyright (C) 1999 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 "screen.h"
|
||||
#include "gui-readline.h"
|
||||
#include "gui-windows.h"
|
||||
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
|
||||
#ifndef COLOR_PAIRS
|
||||
#define COLOR_PAIRS 64
|
||||
#endif
|
||||
|
||||
#define MIN_SCREEN_WIDTH 20
|
||||
|
||||
static gint scrx, scry;
|
||||
gboolean use_colors;
|
||||
static gint freeze_refresh;
|
||||
|
||||
#ifdef SIGWINCH
|
||||
|
||||
static void sig_winch(int p)
|
||||
{
|
||||
#ifdef TIOCGWINSZ
|
||||
struct winsize ws;
|
||||
gint ychange, xchange;
|
||||
|
||||
/* Get new window size */
|
||||
if (ioctl(0, TIOCGWINSZ, &ws) < 0)
|
||||
return;
|
||||
|
||||
if (ws.ws_row == LINES && ws.ws_col == COLS)
|
||||
{
|
||||
/* Same size, abort. */
|
||||
return;
|
||||
}
|
||||
|
||||
if (ws.ws_col < MIN_SCREEN_WIDTH)
|
||||
ws.ws_col = MIN_SCREEN_WIDTH;
|
||||
|
||||
/* Resize curses terminal */
|
||||
ychange = ws.ws_row-LINES;
|
||||
xchange = ws.ws_col-COLS;
|
||||
#ifdef HAVE_CURSES_RESIZETERM
|
||||
resizeterm(ws.ws_row, ws.ws_col);
|
||||
#else
|
||||
deinit_screen();
|
||||
init_screen();
|
||||
#endif
|
||||
|
||||
last_text_line += ychange;
|
||||
gui_windows_resize(ychange, xchange != 0);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* SIGINT != ^C .. any better way to make this work? */
|
||||
void sigint_handler(int p)
|
||||
{
|
||||
ungetch(3);
|
||||
readline();
|
||||
}
|
||||
|
||||
static void read_settings(void)
|
||||
{
|
||||
use_colors = settings_get_bool("colors");
|
||||
irssi_redraw();
|
||||
}
|
||||
|
||||
/* Initialize screen, detect screen length */
|
||||
gint init_screen(void)
|
||||
{
|
||||
gchar ansi_tab[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
|
||||
gint num;
|
||||
|
||||
if (!initscr()) return 0;
|
||||
|
||||
if (COLS < MIN_SCREEN_WIDTH)
|
||||
COLS = MIN_SCREEN_WIDTH;
|
||||
|
||||
signal(SIGINT, sigint_handler);
|
||||
cbreak(); noecho(); idlok(stdscr, 1);
|
||||
#ifdef HAVE_CURSES_IDCOK
|
||||
idcok(stdscr, 1);
|
||||
#endif
|
||||
intrflush(stdscr, FALSE); halfdelay(1); keypad(stdscr, 1);
|
||||
|
||||
settings_add_bool("lookandfeel", "colors", TRUE);
|
||||
|
||||
use_colors = settings_get_bool("colors") && has_colors();
|
||||
if (has_colors()) start_color();
|
||||
|
||||
#ifdef HAVE_NCURSES_USE_DEFAULT_COLORS
|
||||
/* this lets us to use the "default" background color for colors <= 7 so
|
||||
background pixmaps etc. show up right */
|
||||
use_default_colors();
|
||||
|
||||
for (num = 1; num < COLOR_PAIRS; num++)
|
||||
init_pair(num, ansi_tab[num & 7], num <= 7 ? -1 : ansi_tab[num >> 3]);
|
||||
|
||||
init_pair(63, 0, -1); /* hm.. not THAT good idea, but probably more people
|
||||
want dark grey than white on white.. */
|
||||
#else
|
||||
for (num = 1; num < COLOR_PAIRS; num++)
|
||||
init_pair(num, ansi_tab[num & 7], ansi_tab[num >> 3]);
|
||||
init_pair(63, 0, 0);
|
||||
#endif
|
||||
|
||||
scrx = scry = 0;
|
||||
if (last_text_line == 0)
|
||||
{
|
||||
first_text_line = 0;
|
||||
last_text_line = LINES-1;
|
||||
}
|
||||
#ifdef SIGWINCH
|
||||
signal(SIGWINCH, sig_winch);
|
||||
#endif
|
||||
|
||||
freeze_refresh = 0;
|
||||
clear();
|
||||
|
||||
signal_add("setup changed", (SIGNAL_FUNC) read_settings);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Deinitialize screen */
|
||||
void deinit_screen(void)
|
||||
{
|
||||
signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
|
||||
endwin();
|
||||
}
|
||||
|
||||
void set_color(gint col)
|
||||
{
|
||||
gint attr;
|
||||
|
||||
if (!use_colors)
|
||||
{
|
||||
if ((col & 0x70) != 0)
|
||||
attr = A_REVERSE;
|
||||
else
|
||||
attr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (col & ATTR_COLOR8)
|
||||
attr = A_DIM | COLOR_PAIR(63);
|
||||
else
|
||||
attr = COLOR_PAIR((col&7) + (col&0x70)/2);
|
||||
}
|
||||
|
||||
if (col & 0x08) attr |= A_BOLD;
|
||||
if (col & 0x80) attr |= A_BLINK;
|
||||
|
||||
if (col & ATTR_UNDERLINE) attr |= A_UNDERLINE;
|
||||
if (col & ATTR_REVERSE) attr |= A_REVERSE;
|
||||
|
||||
attrset(attr);
|
||||
}
|
||||
|
||||
void set_bg(gint col)
|
||||
{
|
||||
gint attr;
|
||||
|
||||
if (!use_colors)
|
||||
{
|
||||
if ((col & 0x70) != 0)
|
||||
attr = A_REVERSE;
|
||||
else
|
||||
attr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (col == 8)
|
||||
attr = A_DIM | COLOR_PAIR(63);
|
||||
else
|
||||
attr = COLOR_PAIR((col&7) + (col&0x70)/2);
|
||||
}
|
||||
|
||||
if (col & 0x08) attr |= A_BOLD;
|
||||
if (col & 0x80) attr |= A_BLINK;
|
||||
|
||||
bkgdset(' ' | attr);
|
||||
}
|
||||
|
||||
/* Scroll area up */
|
||||
void scroll_up(gint y1, gint y2)
|
||||
{
|
||||
scrollok(stdscr, TRUE);
|
||||
setscrreg(y1, y2); scrl(1);
|
||||
scrollok(stdscr, FALSE);
|
||||
}
|
||||
|
||||
/* Scroll area down */
|
||||
void scroll_down(gint y1, gint y2)
|
||||
{
|
||||
scrollok(stdscr, TRUE);
|
||||
setscrreg(y1, y2); scrl(-1);
|
||||
scrollok(stdscr, FALSE);
|
||||
}
|
||||
|
||||
void move_cursor(gint y, gint x)
|
||||
{
|
||||
scry = y;
|
||||
scrx = x;
|
||||
}
|
||||
|
||||
void screen_refresh_freeze(void)
|
||||
{
|
||||
freeze_refresh++;
|
||||
}
|
||||
|
||||
void screen_refresh_thaw(void)
|
||||
{
|
||||
if (freeze_refresh > 0)
|
||||
{
|
||||
freeze_refresh--;
|
||||
if (freeze_refresh == 0) screen_refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void screen_refresh(void)
|
||||
{
|
||||
if (freeze_refresh == 0)
|
||||
{
|
||||
move(scry, scrx);
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
31
src/fe-text/screen.h
Normal file
31
src/fe-text/screen.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef __SCREEN_H
|
||||
#define __SCREEN_H
|
||||
|
||||
#if defined(USE_NCURSES) && !defined(RENAMED_NCURSES)
|
||||
#include <ncurses.h>
|
||||
#else
|
||||
#include <curses.h>
|
||||
#endif
|
||||
|
||||
#define ATTR_UNDERLINE 0x100
|
||||
#define ATTR_COLOR8 0x200
|
||||
#define ATTR_REVERSE 0x400
|
||||
|
||||
extern gboolean use_colors;
|
||||
|
||||
gint init_screen(void); /* Initialize screen, detect screen length */
|
||||
void deinit_screen(void); /* Deinitialize screen */
|
||||
|
||||
void set_color(gint col);
|
||||
void set_bg(gint col);
|
||||
|
||||
void scroll_up(gint y1, gint y2); /* Scroll area up */
|
||||
void scroll_down(gint y1, gint y2); /* Scroll area down */
|
||||
|
||||
void move_cursor(gint y, gint x);
|
||||
|
||||
void screen_refresh_freeze(void);
|
||||
void screen_refresh_thaw(void);
|
||||
void screen_refresh(void);
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue