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_use_colors24;
41 int term_type;
42
43 static int force_colors;
44 static int resize_dirty;
45
term_get_size(int * width,int * height)46 int term_get_size(int *width, int *height)
47 {
48 #ifdef TIOCGWINSZ
49 struct winsize ws;
50
51 /* Get new window size */
52 if (ioctl(0, TIOCGWINSZ, &ws) < 0)
53 return FALSE;
54
55 if (ws.ws_row == 0 && ws.ws_col == 0)
56 return FALSE;
57
58 *width = ws.ws_col;
59 *height = ws.ws_row;
60
61 if (*width < MIN_SCREEN_WIDTH)
62 *width = MIN_SCREEN_WIDTH;
63 if (*height < 1)
64 *height = 1;
65 return TRUE;
66 #else
67 return FALSE;
68 #endif
69 }
70
71 /* Resize the terminal if needed */
term_resize_dirty(void)72 void term_resize_dirty(void)
73 {
74 int width, height;
75
76 if (!resize_dirty)
77 return;
78
79 resize_dirty = FALSE;
80
81 if (!term_get_size(&width, &height))
82 width = height = -1;
83
84 term_resize(width, height);
85 mainwindows_resize(term_width, term_height);
86 term_resize_final(width, height);
87 }
88
89 #ifdef SIGWINCH
sig_winch(int p)90 static void sig_winch(int p)
91 {
92 irssi_set_dirty();
93 resize_dirty = TRUE;
94 }
95 #endif
96
cmd_resize(void)97 static void cmd_resize(void)
98 {
99 resize_dirty = TRUE;
100 term_resize_dirty();
101 }
102
cmd_redraw(void)103 static void cmd_redraw(void)
104 {
105 irssi_redraw();
106 }
107
108 int term_color256map[] = {
109 0, 4, 2, 6, 1, 5, 3, 7, 8,12,10,14, 9,13,11,15,
110 0, 0, 1, 1, 1, 1, 0, 0, 3, 1, 1, 9, 2, 2, 3, 3, 3, 3,
111 2, 2, 3, 3, 3, 3, 2, 2, 3, 3, 3,11,10,10, 3, 3,11,11,
112 0, 0, 5, 1, 1, 9, 0, 8, 8, 8, 9, 9, 2, 8, 8, 8, 9, 9,
113 2, 8, 8, 8, 9, 9, 2, 8, 8, 3, 3,11,10,10, 3, 3,11,11,
114 4, 4, 5, 5, 5, 5, 4, 8, 8, 8, 9, 9, 6, 8, 8, 8, 9, 9,
115 6, 8, 8, 8, 8, 9, 6, 8, 8, 8, 7, 7, 6, 6, 8, 7, 7, 7,
116 4, 4, 5, 5, 5, 5, 4, 8, 8, 8, 9, 9, 6, 8, 8, 8, 8, 9,
117 6, 8, 8, 8, 7, 7, 6, 6, 8, 7, 7, 7, 6, 6, 7, 7, 7, 7,
118 4, 4, 5, 5, 5,13, 4, 8, 8, 5, 5,13, 6, 8, 8, 8, 7, 7,
119 6, 6, 8, 7, 7, 7, 6, 6, 7, 7, 7, 7,14,14, 7, 7, 7, 7,
120 12,12, 5, 5,13,13,12,12, 5, 5,13,13, 6, 6, 8, 7, 7, 7,
121 6, 6, 7, 7, 7, 7,14,14, 7, 7, 7, 7,14,14, 7, 7, 7,15,
122 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
123 7, 7, 7, 7, 7, 7, 0 };
124
read_settings(void)125 static void read_settings(void)
126 {
127 const char *str;
128 int old_colors = term_use_colors;
129 int old_colors24 = term_use_colors24;
130 int old_type = term_type;
131
132 /* set terminal type */
133 str = settings_get_str("term_charset");
134 if (g_ascii_strcasecmp(str, "utf-8") == 0)
135 term_type = TERM_TYPE_UTF8;
136 else if (g_ascii_strcasecmp(str, "big5") == 0)
137 term_type = TERM_TYPE_BIG5;
138 else
139 term_type = TERM_TYPE_8BIT;
140
141 if (old_type != term_type)
142 term_set_input_type(term_type);
143
144 /* change color stuff */
145 if (force_colors != settings_get_bool("term_force_colors")) {
146 force_colors = settings_get_bool("term_force_colors");
147 term_force_colors(force_colors);
148 }
149
150 term_use_colors = settings_get_bool("colors") &&
151 (force_colors || term_has_colors());
152
153 #ifdef TERM_TRUECOLOR
154 term_use_colors24 = settings_get_bool("colors_ansi_24bit") &&
155 (force_colors || term_has_colors());
156 #else
157 term_use_colors24 = FALSE;
158 #endif
159
160 if (term_use_colors != old_colors || term_use_colors24 != old_colors24)
161 irssi_redraw();
162 }
163
term_common_init(void)164 void term_common_init(void)
165 {
166 const char *dummy;
167 #ifdef SIGWINCH
168 struct sigaction act;
169 #endif
170 settings_add_bool("lookandfeel", "colors", TRUE);
171 settings_add_bool("lookandfeel", "term_force_colors", FALSE);
172 settings_add_bool("lookandfeel", "mirc_blink_fix", FALSE);
173
174 force_colors = FALSE;
175 term_use_colors = term_has_colors() && settings_get_bool("colors");
176 #ifdef TERM_TRUECOLOR
177 settings_add_bool("lookandfeel", "colors_ansi_24bit", FALSE);
178 term_use_colors24 = term_has_colors() && settings_get_bool("colors_ansi_24bit");
179 #else
180 term_use_colors24 = FALSE;
181 #endif
182 read_settings();
183
184 if (g_get_charset(&dummy)) {
185 term_type = TERM_TYPE_UTF8;
186 term_set_input_type(TERM_TYPE_UTF8);
187 }
188
189 signal_add("beep", (SIGNAL_FUNC) term_beep);
190 signal_add("setup changed", (SIGNAL_FUNC) read_settings);
191 command_bind("resize", NULL, (SIGNAL_FUNC) cmd_resize);
192 command_bind("redraw", NULL, (SIGNAL_FUNC) cmd_redraw);
193
194 #ifdef SIGWINCH
195 sigemptyset (&act.sa_mask);
196 act.sa_flags = 0;
197 act.sa_handler = sig_winch;
198 sigaction(SIGWINCH, &act, NULL);
199 #endif
200 }
201
term_common_deinit(void)202 void term_common_deinit(void)
203 {
204 command_unbind("resize", (SIGNAL_FUNC) cmd_resize);
205 command_unbind("redraw", (SIGNAL_FUNC) cmd_redraw);
206 signal_remove("beep", (SIGNAL_FUNC) term_beep);
207 signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
208 }
209