Merge Irssi 0.8.16-rc1
[silc.git] / apps / irssi / src / fe-text / term.c
1 /*
2  term.c : irssi
3
4     Copyright (C) 2001 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 along
17     with this program; if not, write to the Free Software Foundation, Inc.,
18     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include "module.h"
22 #include "signals.h"
23 #include "commands.h"
24 #include "settings.h"
25
26 #include "term.h"
27 #include "mainwindows.h"
28
29 #ifdef HAVE_SYS_IOCTL_H
30 #  include <sys/ioctl.h>
31 #endif
32 #include <signal.h>
33 #include <termios.h>
34
35 #define MIN_SCREEN_WIDTH 20
36
37 int term_width, term_height;
38
39 int term_use_colors;
40 int term_type;
41
42 static int force_colors;
43 static int resize_dirty;
44
45 int term_get_size(int *width, int *height)
46 {
47 #ifdef TIOCGWINSZ
48         struct winsize ws;
49
50         /* Get new window size */
51         if (ioctl(0, TIOCGWINSZ, &ws) < 0)
52                 return FALSE;
53
54         if (ws.ws_row == 0 && ws.ws_col == 0)
55                 return FALSE;
56
57         *width = ws.ws_col;
58         *height = ws.ws_row;
59
60         if (*width < MIN_SCREEN_WIDTH)
61                 *width = MIN_SCREEN_WIDTH;
62         if (*height < 1)
63                 *height = 1;
64         return TRUE;
65 #else
66         return FALSE;
67 #endif
68 }
69
70 /* Resize the terminal if needed */
71 void term_resize_dirty(void)
72 {
73         int width, height;
74
75         if (!resize_dirty)
76                 return;
77
78         resize_dirty = FALSE;
79
80         if (!term_get_size(&width, &height))
81                 width = height = -1;
82
83         if (height != term_height || width != term_width) {
84                 term_resize(width, height);
85                 mainwindows_resize(term_width, term_height);
86                 term_resize_final(width, height);
87         }
88 }
89
90 #ifdef SIGWINCH
91 static void sig_winch(int p)
92 {
93         irssi_set_dirty();
94         resize_dirty = TRUE;
95 }
96 #endif
97
98 static void cmd_resize(void)
99 {
100         resize_dirty = TRUE;
101         term_resize_dirty();
102 }
103
104 static void cmd_redraw(void)
105 {
106         irssi_redraw();
107 }
108
109 static void read_settings(void)
110 {
111         const char *str;
112         int old_colors = term_use_colors;
113         int old_type = term_type;
114
115         /* set terminal type */
116         str = settings_get_str("term_charset");
117         if (g_ascii_strcasecmp(str, "utf-8") == 0)
118                 term_type = TERM_TYPE_UTF8;
119         else if (g_ascii_strcasecmp(str, "big5") == 0)
120                 term_type = TERM_TYPE_BIG5;
121         else
122                 term_type = TERM_TYPE_8BIT;
123
124         if (old_type != term_type)
125                 term_set_input_type(term_type);
126
127         /* change color stuff */
128         if (force_colors != settings_get_bool("term_force_colors")) {
129                 force_colors = settings_get_bool("term_force_colors");
130                 term_force_colors(force_colors);
131         }
132
133         term_use_colors = settings_get_bool("colors") &&
134                 (force_colors || term_has_colors());
135
136         if (term_use_colors != old_colors)
137                 irssi_redraw();
138 }
139
140 void term_common_init(void)
141 {
142         const char *dummy;
143 #ifdef SIGWINCH
144         struct sigaction act;
145 #endif
146         settings_add_bool("lookandfeel", "colors", TRUE);
147         settings_add_bool("lookandfeel", "term_force_colors", FALSE);
148         settings_add_bool("lookandfeel", "mirc_blink_fix", FALSE);
149
150         force_colors = FALSE;
151         term_use_colors = term_has_colors() && settings_get_bool("colors");
152         read_settings();
153
154         if (g_get_charset(&dummy)) {
155                 term_type = TERM_TYPE_UTF8;
156                 term_set_input_type(TERM_TYPE_UTF8);
157         }
158
159         signal_add("beep", (SIGNAL_FUNC) term_beep);
160         signal_add("setup changed", (SIGNAL_FUNC) read_settings);
161         command_bind("resize", NULL, (SIGNAL_FUNC) cmd_resize);
162         command_bind("redraw", NULL, (SIGNAL_FUNC) cmd_redraw);
163
164 #ifdef SIGWINCH
165         sigemptyset (&act.sa_mask);
166         act.sa_flags = 0;
167         act.sa_handler = sig_winch;
168         sigaction(SIGWINCH, &act, NULL);
169 #endif
170 }
171
172 void term_common_deinit(void)
173 {
174         command_unbind("resize", (SIGNAL_FUNC) cmd_resize);
175         command_unbind("redraw", (SIGNAL_FUNC) cmd_redraw);
176         signal_remove("beep", (SIGNAL_FUNC) term_beep);
177         signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
178 }