c32b24919403018dfae465ab00fa686d0d437bc1
[crypto.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
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 "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_use_colors;
38
39 static int force_colors;
40 static int resize_dirty;
41
42 /* Resize the terminal if needed */
43 void term_resize_dirty(void)
44 {
45 #ifdef TIOCGWINSZ
46         struct winsize ws;
47 #endif
48         int width, height;
49
50         if (!resize_dirty)
51                 return;
52
53         resize_dirty = FALSE;
54
55 #ifdef TIOCGWINSZ
56         /* Get new window size */
57         if (ioctl(0, TIOCGWINSZ, &ws) < 0)
58                 return;
59
60         if (ws.ws_row == term_height && ws.ws_col == term_width) {
61                 /* Same size, abort. */
62                 return;
63         }
64
65         if (ws.ws_col < MIN_SCREEN_WIDTH)
66                 ws.ws_col = MIN_SCREEN_WIDTH;
67
68         width = ws.ws_col;
69         height = ws.ws_row;
70 #else
71         width = height = -1;
72 #endif
73         term_resize(width, height);
74         mainwindows_resize(term_width, term_height);
75         term_resize_final(width, height);
76 }
77
78 #ifdef SIGWINCH
79 static void sig_winch(int p)
80 {
81         irssi_set_dirty();
82         resize_dirty = TRUE;
83 }
84 #endif
85
86 static void cmd_resize(void)
87 {
88         resize_dirty = TRUE;
89         term_resize_dirty();
90 }
91
92 static void read_settings(void)
93 {
94         int old_colors = term_use_colors;
95
96         term_auto_detach(settings_get_bool("term_auto_detach"));
97
98         if (force_colors != settings_get_bool("term_force_colors")) {
99                 force_colors = settings_get_bool("term_force_colors");
100                 term_force_colors(force_colors);
101         }
102
103         term_use_colors = settings_get_bool("colors") &&
104                 (force_colors || term_has_colors());
105
106         if (term_use_colors != old_colors)
107                 irssi_redraw();
108 }
109
110 void term_common_init(void)
111 {
112 #ifdef SIGWINCH
113         struct sigaction act;
114 #endif
115         settings_add_bool("lookandfeel", "colors", TRUE);
116         settings_add_bool("lookandfeel", "term_force_colors", FALSE);
117         settings_add_bool("lookandfeel", "term_auto_detach", FALSE);
118         settings_add_bool("lookandfeel", "term_utf8", FALSE);
119
120         force_colors = FALSE;
121         term_use_colors = term_has_colors() && settings_get_bool("colors");
122         read_settings();
123
124         signal_add("beep", (SIGNAL_FUNC) term_beep);
125         signal_add("setup changed", (SIGNAL_FUNC) read_settings);
126         command_bind("resize", NULL, (SIGNAL_FUNC) cmd_resize);
127
128 #ifdef SIGWINCH
129         sigemptyset (&act.sa_mask);
130         act.sa_flags = 0;
131         act.sa_handler = sig_winch;
132         sigaction(SIGWINCH, &act, NULL);
133 #endif
134 }
135
136 void term_common_deinit(void)
137 {
138         command_unbind("resize", (SIGNAL_FUNC) cmd_resize);
139         signal_remove("beep", (SIGNAL_FUNC) term_beep);
140         signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
141 }