2 gui-printtext.c : irssi
4 Copyright (C) 1999 Timo Sirainen
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include "printtext.h"
29 #include "gui-printtext.h"
30 #include "gui-windows.h"
32 int mirc_colors[] = { 15, 0, 1, 2, 12, 4, 5, 6, 14, 10, 3, 11, 9, 13, 8, 7 };
33 static int scrollback_lines, scrollback_hours, scrollback_burst_remove;
35 static int last_fg, last_bg, last_flags;
36 static int next_xpos, next_ypos;
38 static GHashTable *indent_functions;
39 static INDENT_FUNC default_indent_func;
41 void gui_register_indent_func(const char *name, INDENT_FUNC func)
46 if (g_hash_table_lookup_extended(indent_functions, name, &key, &value)) {
48 g_hash_table_remove(indent_functions, key);
54 list = g_slist_append(list, (void *) func);
55 g_hash_table_insert(indent_functions, key, list);
58 void gui_unregister_indent_func(const char *name, INDENT_FUNC func)
63 if (g_hash_table_lookup_extended(indent_functions, name, &key, &value)) {
66 list = g_slist_remove(list, (void *) func);
67 g_hash_table_remove(indent_functions, key);
71 g_hash_table_insert(indent_functions, key, list);
74 if (default_indent_func == func)
75 gui_set_default_indent(NULL);
77 textbuffer_views_unregister_indent_func(func);
80 void gui_set_default_indent(const char *name)
84 list = name == NULL ? NULL :
85 g_hash_table_lookup(indent_functions, name);
86 default_indent_func = list == NULL ? NULL : list->data;
87 gui_windows_reset_settings();
90 INDENT_FUNC get_default_indent_func(void)
92 return default_indent_func;
95 void gui_printtext(int xpos, int ypos, const char *str)
102 next_xpos = next_ypos = -1;
105 void gui_printtext_after(TEXT_DEST_REC *dest, LINE_REC *prev, const char *str)
109 gui = WINDOW_GUI(dest->window);
111 gui->use_insert_after = TRUE;
112 gui->insert_after = prev;
113 format_send_to_gui(dest, str);
114 gui->use_insert_after = FALSE;
117 static void remove_old_lines(TEXT_BUFFER_VIEW_REC *view)
122 old_time = time(NULL)-(scrollback_hours*3600)+1;
123 if (view->buffer->lines_count >=
124 scrollback_lines+scrollback_burst_remove) {
125 /* remove lines by line count */
126 while (view->buffer->lines_count > scrollback_lines) {
127 line = view->buffer->first_line;
128 if (line->info.time >= old_time ||
129 scrollback_lines == 0) {
130 /* too new line, don't remove yet - also
131 if scrollback_lines is 0, we want to check
132 only scrollback_hours setting. */
135 textbuffer_view_remove_line(view, line);
140 static void get_colors(int flags, int *fg, int *bg, int *attr)
142 if (flags & GUI_PRINT_FLAG_MIRC_COLOR) {
143 /* mirc colors - real range is 0..15, but after 16
144 colors wrap to 0, 1, ... */
145 if (*bg >= 0) *bg = mirc_colors[*bg % 16];
146 if (*fg >= 0) *fg = mirc_colors[*fg % 16];
149 if (*fg < 0 || *fg > 15)
150 *fg = current_theme->default_color;
151 if (*bg < 0 || *bg > 15)
155 if (flags & GUI_PRINT_FLAG_REVERSE) *attr |= ATTR_REVERSE;
156 if (flags & GUI_PRINT_FLAG_BOLD) *attr |= ATTR_BOLD;
157 if (flags & GUI_PRINT_FLAG_UNDERLINE) *attr |= ATTR_UNDERLINE;
158 if (flags & GUI_PRINT_FLAG_BLINK) *attr |= ATTR_BLINK;
161 static void line_add_colors(TEXT_BUFFER_REC *buffer, LINE_REC **line,
162 int fg, int bg, int flags)
164 unsigned char data[20];
167 /* get the fg & bg command chars */
168 fg = fg < 0 ? LINE_COLOR_DEFAULT : fg & 0x0f;
169 bg = LINE_COLOR_BG | (bg < 0 ? LINE_COLOR_DEFAULT : bg & 0x0f);
170 if (flags & GUI_PRINT_FLAG_BOLD)
171 fg |= LINE_COLOR_BOLD;
172 if (flags & GUI_PRINT_FLAG_BLINK)
173 bg |= LINE_COLOR_BLINK;
179 data[pos++] = fg == 0 ? LINE_CMD_COLOR0 : fg;
187 if ((flags & GUI_PRINT_FLAG_UNDERLINE) != (last_flags & GUI_PRINT_FLAG_UNDERLINE)) {
189 data[pos++] = LINE_CMD_UNDERLINE;
191 if ((flags & GUI_PRINT_FLAG_REVERSE) != (last_flags & GUI_PRINT_FLAG_REVERSE)) {
193 data[pos++] = LINE_CMD_REVERSE;
195 if (flags & GUI_PRINT_FLAG_INDENT) {
197 data[pos++] = LINE_CMD_INDENT;
201 *line = textbuffer_insert(buffer, *line, data, pos, NULL);
206 static void line_add_indent_func(TEXT_BUFFER_REC *buffer, LINE_REC **line,
207 const char *function)
210 unsigned char data[1+sizeof(INDENT_FUNC)];
212 list = g_hash_table_lookup(indent_functions, function);
214 data[0] = LINE_CMD_INDENT_FUNC;
215 memcpy(data+1, list->data, sizeof(INDENT_FUNC));
216 *line = textbuffer_insert(buffer, *line,
217 data, sizeof(data), NULL);
221 static void view_add_eol(TEXT_BUFFER_VIEW_REC *view, LINE_REC **line)
223 static const unsigned char eol[] = { 0, LINE_CMD_EOL };
225 *line = textbuffer_insert(view->buffer, *line, eol, 2, NULL);
226 textbuffer_view_insert_line(view, *line);
229 static void sig_gui_print_text(WINDOW_REC *window, void *fgcolor,
230 void *bgcolor, void *pflags,
231 char *str, void *level)
234 TEXT_BUFFER_VIEW_REC *view;
235 LINE_REC *insert_after;
236 LINE_INFO_REC lineinfo;
237 int fg, bg, flags, attr;
239 flags = GPOINTER_TO_INT(pflags);
240 fg = GPOINTER_TO_INT(fgcolor);
241 bg = GPOINTER_TO_INT(bgcolor);
242 get_colors(flags, &fg, &bg, &attr);
244 if (window == NULL) {
245 g_return_if_fail(next_xpos != -1);
247 attr |= fg >= 0 ? fg : ATTR_RESETFG;
248 attr |= bg >= 0 ? (bg << 4) : ATTR_RESETBG;
249 term_set_color(root_window, attr);
251 term_move(root_window, next_xpos, next_ypos);
252 if (flags & GUI_PRINT_FLAG_CLRTOEOL)
253 term_clrtoeol(root_window);
254 term_addstr(root_window, str);
255 next_xpos += strlen(str);
259 lineinfo.level = GPOINTER_TO_INT(level);
260 lineinfo.time = time(NULL);
262 gui = WINDOW_GUI(window);
264 insert_after = gui->use_insert_after ?
265 gui->insert_after : view->buffer->cur_line;
267 if (flags & GUI_PRINT_FLAG_NEWLINE)
268 view_add_eol(view, &insert_after);
269 line_add_colors(view->buffer, &insert_after, fg, bg, flags);
271 if (flags & GUI_PRINT_FLAG_INDENT_FUNC) {
272 /* specify the indentation function */
273 line_add_indent_func(view->buffer, &insert_after, str);
275 insert_after = textbuffer_insert(view->buffer, insert_after,
276 (unsigned char *) str,
277 strlen(str), &lineinfo);
279 if (gui->use_insert_after)
280 gui->insert_after = insert_after;
283 static void sig_gui_printtext_finished(WINDOW_REC *window)
285 TEXT_BUFFER_VIEW_REC *view;
286 LINE_REC *insert_after;
288 last_fg = last_bg = -1;
291 view = WINDOW_GUI(window)->view;
292 insert_after = WINDOW_GUI(window)->use_insert_after ?
293 WINDOW_GUI(window)->insert_after : view->buffer->cur_line;
295 view_add_eol(view, &insert_after);
296 remove_old_lines(view);
299 static void read_settings(void)
301 scrollback_lines = settings_get_int("scrollback_lines");
302 scrollback_hours = settings_get_int("scrollback_hours");
303 scrollback_burst_remove = settings_get_int("scrollback_burst_remove");
306 void gui_printtext_init(void)
308 next_xpos = next_ypos = -1;
309 default_indent_func = NULL;
310 indent_functions = g_hash_table_new((GHashFunc) g_str_hash,
311 (GCompareFunc) g_str_equal);
313 settings_add_int("history", "scrollback_lines", 500);
314 settings_add_int("history", "scrollback_hours", 24);
315 settings_add_int("history", "scrollback_burst_remove", 10);
317 signal_add("gui print text", (SIGNAL_FUNC) sig_gui_print_text);
318 signal_add("gui print text finished", (SIGNAL_FUNC) sig_gui_printtext_finished);
319 signal_add("setup changed", (SIGNAL_FUNC) read_settings);
324 void gui_printtext_deinit(void)
326 g_hash_table_destroy(indent_functions);
328 signal_remove("gui print text", (SIGNAL_FUNC) sig_gui_print_text);
329 signal_remove("gui print text finished", (SIGNAL_FUNC) sig_gui_printtext_finished);
330 signal_remove("setup changed", (SIGNAL_FUNC) read_settings);