~ubuntu-branches/ubuntu/intrepid/irssi/intrepid-updates

« back to all changes in this revision

Viewing changes to src/fe-text/gui-printtext.c

  • Committer: Bazaar Package Importer
  • Author(s): David Pashley
  • Date: 2005-12-10 21:25:51 UTC
  • Revision ID: james.westby@ubuntu.com-20051210212551-5qwm108g7inyu2f2
Tags: upstream-0.8.10
ImportĀ upstreamĀ versionĀ 0.8.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 gui-printtext.c : irssi
 
3
 
 
4
    Copyright (C) 1999 Timo Sirainen
 
5
 
 
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.
 
10
 
 
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.
 
15
 
 
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
 
19
*/
 
20
 
 
21
#include "module.h"
 
22
#include "signals.h"
 
23
#include "settings.h"
 
24
 
 
25
#include "formats.h"
 
26
#include "printtext.h"
 
27
 
 
28
#include "term.h"
 
29
#include "gui-printtext.h"
 
30
#include "gui-windows.h"
 
31
 
 
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_time, scrollback_burst_remove;
 
34
 
 
35
static int last_fg, last_bg, last_flags;
 
36
static int next_xpos, next_ypos;
 
37
 
 
38
static GHashTable *indent_functions;
 
39
static INDENT_FUNC default_indent_func;
 
40
 
 
41
void gui_register_indent_func(const char *name, INDENT_FUNC func)
 
42
{
 
43
        gpointer key, value;
 
44
        GSList *list;
 
45
 
 
46
        if (g_hash_table_lookup_extended(indent_functions, name, &key, &value)) {
 
47
                list = value;
 
48
                g_hash_table_remove(indent_functions, key);
 
49
        } else {
 
50
                key = g_strdup(name);
 
51
                list = NULL;
 
52
        }
 
53
 
 
54
        list = g_slist_append(list, (void *) func);
 
55
        g_hash_table_insert(indent_functions, key, list);
 
56
}
 
57
 
 
58
void gui_unregister_indent_func(const char *name, INDENT_FUNC func)
 
59
{
 
60
        gpointer key, value;
 
61
        GSList *list;
 
62
 
 
63
        if (g_hash_table_lookup_extended(indent_functions, name, &key, &value)) {
 
64
                list = value;
 
65
 
 
66
                list = g_slist_remove(list, (void *) func);
 
67
                g_hash_table_remove(indent_functions, key);
 
68
                if (list == NULL)
 
69
                        g_free(key);
 
70
                else
 
71
                        g_hash_table_insert(indent_functions, key, list);
 
72
        }
 
73
 
 
74
        if (default_indent_func == func)
 
75
                gui_set_default_indent(NULL);
 
76
 
 
77
        textbuffer_views_unregister_indent_func(func);
 
78
}
 
79
 
 
80
void gui_set_default_indent(const char *name)
 
81
{
 
82
        GSList *list;
 
83
 
 
84
        list = name == NULL ? NULL :
 
85
                g_hash_table_lookup(indent_functions, name);
 
86
        default_indent_func = list == NULL ? NULL :
 
87
                (INDENT_FUNC) list->data;
 
88
        gui_windows_reset_settings();
 
89
}
 
90
 
 
91
INDENT_FUNC get_default_indent_func(void)
 
92
{
 
93
        return default_indent_func;
 
94
}
 
95
 
 
96
void gui_printtext(int xpos, int ypos, const char *str)
 
97
{
 
98
        next_xpos = xpos;
 
99
        next_ypos = ypos;
 
100
 
 
101
        printtext_gui(str);
 
102
 
 
103
        next_xpos = next_ypos = -1;
 
104
}
 
105
 
 
106
void gui_printtext_after(TEXT_DEST_REC *dest, LINE_REC *prev, const char *str)
 
107
{
 
108
        GUI_WINDOW_REC *gui;
 
109
 
 
110
        gui = WINDOW_GUI(dest->window);
 
111
 
 
112
        gui->use_insert_after = TRUE;
 
113
        gui->insert_after = prev;
 
114
        format_send_to_gui(dest, str);
 
115
        gui->use_insert_after = FALSE;
 
116
}
 
117
 
 
118
static void remove_old_lines(TEXT_BUFFER_VIEW_REC *view)
 
119
{
 
120
        LINE_REC *line;
 
121
        time_t old_time;
 
122
 
 
123
        old_time = time(NULL)-scrollback_time+1;
 
124
        if (view->buffer->lines_count >=
 
125
            scrollback_lines+scrollback_burst_remove) {
 
126
                /* remove lines by line count */
 
127
                while (view->buffer->lines_count > scrollback_lines) {
 
128
                        line = view->buffer->first_line;
 
129
                        if (line->info.time >= old_time ||
 
130
                            scrollback_lines == 0) {
 
131
                                /* too new line, don't remove yet - also
 
132
                                   if scrollback_lines is 0, we want to check
 
133
                                   only scrollback_time setting. */
 
134
                                break;
 
135
                        }
 
136
                        textbuffer_view_remove_line(view, line);
 
137
                }
 
138
        }
 
139
}
 
140
 
 
141
static void get_colors(int flags, int *fg, int *bg, int *attr)
 
142
{
 
143
        if (flags & GUI_PRINT_FLAG_MIRC_COLOR) {
 
144
                /* mirc colors - real range is 0..15, but after 16
 
145
                   colors wrap to 0, 1, ... */
 
146
                if (*bg >= 0) *bg = mirc_colors[*bg % 16];
 
147
                if (*fg >= 0) *fg = mirc_colors[*fg % 16];
 
148
                if (settings_get_bool("mirc_blink_fix"))
 
149
                        *bg &= ~0x08;
 
150
        }
 
151
 
 
152
        if (*fg < 0 || *fg > 15)
 
153
                *fg = -1;
 
154
        if (*bg < 0 || *bg > 15)
 
155
                *bg = -1;
 
156
 
 
157
        *attr = 0;
 
158
        if (flags & GUI_PRINT_FLAG_REVERSE) *attr |= ATTR_REVERSE;
 
159
        if (flags & GUI_PRINT_FLAG_BOLD) *attr |= ATTR_BOLD;
 
160
        if (flags & GUI_PRINT_FLAG_UNDERLINE) *attr |= ATTR_UNDERLINE;
 
161
        if (flags & GUI_PRINT_FLAG_BLINK) *attr |= ATTR_BLINK;
 
162
}
 
163
 
 
164
static void line_add_colors(TEXT_BUFFER_REC *buffer, LINE_REC **line,
 
165
                            int fg, int bg, int flags)
 
166
{
 
167
        unsigned char data[20];
 
168
        int pos;
 
169
 
 
170
        /* get the fg & bg command chars */
 
171
        fg = fg < 0 ? LINE_COLOR_DEFAULT : fg & 0x0f;
 
172
        bg = LINE_COLOR_BG | (bg < 0 ? LINE_COLOR_DEFAULT : bg & 0x0f);
 
173
        if (flags & GUI_PRINT_FLAG_BOLD)
 
174
                fg |= LINE_COLOR_BOLD;
 
175
        if (flags & GUI_PRINT_FLAG_BLINK)
 
176
                bg |= LINE_COLOR_BLINK;
 
177
 
 
178
        pos = 0;
 
179
        if (fg != last_fg) {
 
180
                last_fg = fg;
 
181
                data[pos++] = 0;
 
182
                data[pos++] = fg == 0 ? LINE_CMD_COLOR0 : fg;
 
183
        }
 
184
        if (bg != last_bg) {
 
185
                last_bg = bg;
 
186
                data[pos++] = 0;
 
187
                data[pos++] = bg;
 
188
        }
 
189
 
 
190
        if ((flags & GUI_PRINT_FLAG_UNDERLINE) != (last_flags & GUI_PRINT_FLAG_UNDERLINE)) {
 
191
                data[pos++] = 0;
 
192
                data[pos++] = LINE_CMD_UNDERLINE;
 
193
        }
 
194
        if ((flags & GUI_PRINT_FLAG_REVERSE) != (last_flags & GUI_PRINT_FLAG_REVERSE)) {
 
195
                data[pos++] = 0;
 
196
                data[pos++] = LINE_CMD_REVERSE;
 
197
        }
 
198
        if (flags & GUI_PRINT_FLAG_INDENT) {
 
199
                data[pos++] = 0;
 
200
                data[pos++] = LINE_CMD_INDENT;
 
201
        }
 
202
 
 
203
        if (pos > 0)
 
204
                *line = textbuffer_insert(buffer, *line, data, pos, NULL);
 
205
 
 
206
        last_flags = flags;
 
207
}
 
208
 
 
209
static void line_add_indent_func(TEXT_BUFFER_REC *buffer, LINE_REC **line,
 
210
                                 const char *function)
 
211
{
 
212
        GSList *list;
 
213
        unsigned char data[1+sizeof(INDENT_FUNC)];
 
214
 
 
215
        list = g_hash_table_lookup(indent_functions, function);
 
216
        if (list != NULL) {
 
217
                data[0] = LINE_CMD_INDENT_FUNC;
 
218
                memcpy(data+1, list->data, sizeof(INDENT_FUNC));
 
219
                *line = textbuffer_insert(buffer, *line,
 
220
                                          data, sizeof(data), NULL);
 
221
        }
 
222
}
 
223
 
 
224
static void view_add_eol(TEXT_BUFFER_VIEW_REC *view, LINE_REC **line)
 
225
{
 
226
        static const unsigned char eol[] = { 0, LINE_CMD_EOL };
 
227
 
 
228
        *line = textbuffer_insert(view->buffer, *line, eol, 2, NULL);
 
229
        textbuffer_view_insert_line(view, *line);
 
230
}
 
231
 
 
232
static void sig_gui_print_text(WINDOW_REC *window, void *fgcolor,
 
233
                               void *bgcolor, void *pflags,
 
234
                               char *str, TEXT_DEST_REC *dest)
 
235
{
 
236
        GUI_WINDOW_REC *gui;
 
237
        TEXT_BUFFER_VIEW_REC *view;
 
238
        LINE_REC *insert_after;
 
239
        LINE_INFO_REC lineinfo;
 
240
        int fg, bg, flags, attr;
 
241
 
 
242
        flags = GPOINTER_TO_INT(pflags);
 
243
        fg = GPOINTER_TO_INT(fgcolor);
 
244
        bg = GPOINTER_TO_INT(bgcolor);
 
245
        get_colors(flags, &fg, &bg, &attr);
 
246
 
 
247
        if (window == NULL) {
 
248
                g_return_if_fail(next_xpos != -1);
 
249
 
 
250
                attr |= fg >= 0 ? fg : ATTR_RESETFG;
 
251
                attr |= bg >= 0 ? (bg << 4) : ATTR_RESETBG;
 
252
                term_set_color(root_window, attr);
 
253
 
 
254
                term_move(root_window, next_xpos, next_ypos);
 
255
                if (flags & GUI_PRINT_FLAG_CLRTOEOL)
 
256
                        term_clrtoeol(root_window);
 
257
                term_addstr(root_window, str);
 
258
                next_xpos += strlen(str); /* FIXME utf8 or big5 */
 
259
                return;
 
260
        }
 
261
 
 
262
        lineinfo.level = dest == NULL ? 0 : dest->level;
 
263
        lineinfo.time = time(NULL);
 
264
 
 
265
        gui = WINDOW_GUI(window);
 
266
        view = gui->view;
 
267
        insert_after = gui->use_insert_after ?
 
268
                gui->insert_after : view->buffer->cur_line;
 
269
 
 
270
        if (flags & GUI_PRINT_FLAG_NEWLINE)
 
271
                view_add_eol(view, &insert_after);
 
272
        line_add_colors(view->buffer, &insert_after, fg, bg, flags);
 
273
 
 
274
        if (flags & GUI_PRINT_FLAG_INDENT_FUNC) {
 
275
                /* specify the indentation function */
 
276
                line_add_indent_func(view->buffer, &insert_after, str);
 
277
        } else {
 
278
                insert_after = textbuffer_insert(view->buffer, insert_after,
 
279
                                                 (unsigned char *) str,
 
280
                                                 strlen(str), &lineinfo);
 
281
        }
 
282
        if (gui->use_insert_after)
 
283
                gui->insert_after = insert_after;
 
284
}
 
285
 
 
286
static void sig_gui_printtext_finished(WINDOW_REC *window)
 
287
{
 
288
        TEXT_BUFFER_VIEW_REC *view;
 
289
        LINE_REC *insert_after;
 
290
 
 
291
        last_fg = last_bg = -1;
 
292
        last_flags = 0;
 
293
 
 
294
        view = WINDOW_GUI(window)->view;
 
295
        insert_after = WINDOW_GUI(window)->use_insert_after ?
 
296
                WINDOW_GUI(window)->insert_after : view->buffer->cur_line;
 
297
 
 
298
        view_add_eol(view, &insert_after);
 
299
        remove_old_lines(view);
 
300
}
 
301
 
 
302
static void read_settings(void)
 
303
{
 
304
        scrollback_lines = settings_get_int("scrollback_lines");
 
305
        scrollback_time = settings_get_time("scrollback_time")/1000;
 
306
        scrollback_burst_remove = settings_get_int("scrollback_burst_remove");
 
307
}
 
308
 
 
309
void gui_printtext_init(void)
 
310
{
 
311
        next_xpos = next_ypos = -1;
 
312
        default_indent_func = NULL;
 
313
        indent_functions = g_hash_table_new((GHashFunc) g_str_hash,
 
314
                                            (GCompareFunc) g_str_equal);
 
315
 
 
316
        settings_add_int("history", "scrollback_lines", 500);
 
317
        settings_add_time("history", "scrollback_time", "1day");
 
318
        settings_add_int("history", "scrollback_burst_remove", 10);
 
319
 
 
320
        signal_add("gui print text", (SIGNAL_FUNC) sig_gui_print_text);
 
321
        signal_add("gui print text finished", (SIGNAL_FUNC) sig_gui_printtext_finished);
 
322
        signal_add("setup changed", (SIGNAL_FUNC) read_settings);
 
323
 
 
324
        read_settings();
 
325
}
 
326
 
 
327
void gui_printtext_deinit(void)
 
328
{
 
329
        g_hash_table_destroy(indent_functions);
 
330
 
 
331
        signal_remove("gui print text", (SIGNAL_FUNC) sig_gui_print_text);
 
332
        signal_remove("gui print text finished", (SIGNAL_FUNC) sig_gui_printtext_finished);
 
333
        signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
 
334
}