This source file includes following definitions.
- sigintr_handler
- tty_check_term
- tty_start_interrupt_key
- tty_enable_interrupt_key
- tty_disable_interrupt_key
- tty_got_interrupt
- tty_got_winch
- tty_flush_winch
- tty_print_one_hline
- tty_print_one_vline
- tty_draw_box
- tty_draw_box_shadow
- mc_tty_normalize_from_utf8
- tty_resize
- tty_clear_screen
- tty_init_xterm_support
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 #include <config.h>
32
33 #include <errno.h>
34 #include <signal.h>
35 #include <stdarg.h>
36 #include <stdlib.h>
37 #include <string.h>
38
39 #ifdef HAVE_SYS_SELECT_H
40 #include <sys/select.h>
41 #else
42 #include <sys/time.h>
43 #include <sys/types.h>
44 #endif
45 #include <unistd.h>
46
47 #ifdef HAVE_SYS_IOCTL_H
48 #include <sys/ioctl.h>
49 #endif
50
51
52 #include <termios.h>
53
54 #include "lib/global.h"
55 #include "lib/strutil.h"
56 #include "lib/util.h"
57
58 #include "tty.h"
59 #include "tty-internal.h"
60 #include "color.h"
61 #include "mouse.h"
62 #include "win.h"
63
64
65
66 int mc_tty_frm[MC_TTY_FRM_MAX];
67
68
69
70
71
72
73
74
75
76 static SIG_ATOMIC_VOLATILE_T got_interrupt = 0;
77
78
79
80
81
82 static void
83 sigintr_handler (int signo)
84 {
85 (void) &signo;
86 got_interrupt = 1;
87 }
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110 gboolean
111 tty_check_term (gboolean force_xterm)
112 {
113 const char *termvalue;
114
115 termvalue = getenv ("TERM");
116 if (termvalue == NULL || *termvalue == '\0')
117 {
118 fputs (_("The TERM environment variable is unset!\n"), stderr);
119 exit (EXIT_FAILURE);
120 }
121
122
123 return force_xterm
124 || strncmp (termvalue, "xterm", 5) == 0
125 || strncmp (termvalue, "konsole", 7) == 0
126 || strncmp (termvalue, "rxvt", 4) == 0
127 || strcmp (termvalue, "Eterm") == 0
128 || strcmp (termvalue, "dtterm") == 0
129 || strncmp (termvalue, "alacritty", 9) == 0
130 || strncmp (termvalue, "foot", 4) == 0
131 || strncmp (termvalue, "screen", 6) == 0
132 || strncmp (termvalue, "tmux", 4) == 0
133 || strncmp (termvalue, "contour", 7) == 0;
134
135 }
136
137
138
139 extern void
140 tty_start_interrupt_key (void)
141 {
142 struct sigaction act;
143
144 memset (&act, 0, sizeof (act));
145 act.sa_handler = sigintr_handler;
146 sigemptyset (&act.sa_mask);
147 #ifdef SA_RESTART
148 act.sa_flags = SA_RESTART;
149 #endif
150 my_sigaction (SIGINT, &act, NULL);
151 }
152
153
154
155 extern void
156 tty_enable_interrupt_key (void)
157 {
158 struct sigaction act;
159
160 memset (&act, 0, sizeof (act));
161 act.sa_handler = sigintr_handler;
162 sigemptyset (&act.sa_mask);
163 my_sigaction (SIGINT, &act, NULL);
164 got_interrupt = 0;
165 }
166
167
168
169 extern void
170 tty_disable_interrupt_key (void)
171 {
172 struct sigaction act;
173
174 memset (&act, 0, sizeof (act));
175 act.sa_handler = SIG_IGN;
176 sigemptyset (&act.sa_mask);
177 my_sigaction (SIGINT, &act, NULL);
178 }
179
180
181
182 extern gboolean
183 tty_got_interrupt (void)
184 {
185 gboolean rv;
186
187 rv = (got_interrupt != 0);
188 got_interrupt = 0;
189 return rv;
190 }
191
192
193
194 gboolean
195 tty_got_winch (void)
196 {
197 fd_set fdset;
198
199
200 struct timeval timeout = { .tv_sec = 0, .tv_usec = 0 };
201
202 int ok;
203
204 FD_ZERO (&fdset);
205 FD_SET (sigwinch_pipe[0], &fdset);
206
207 while ((ok = select (sigwinch_pipe[0] + 1, &fdset, NULL, NULL, &timeout)) < 0)
208 if (errno != EINTR)
209 {
210 perror (_("Cannot check SIGWINCH pipe"));
211 exit (EXIT_FAILURE);
212 }
213
214 return (ok != 0 && FD_ISSET (sigwinch_pipe[0], &fdset));
215 }
216
217
218
219 void
220 tty_flush_winch (void)
221 {
222 ssize_t n;
223
224
225 do
226 {
227 char x[16];
228
229
230 n = read (sigwinch_pipe[0], &x, sizeof (x));
231 }
232 while (n > 0 || (n == -1 && errno == EINTR));
233 }
234
235
236
237 void
238 tty_print_one_hline (gboolean single)
239 {
240 tty_print_alt_char (ACS_HLINE, single);
241 }
242
243
244
245 void
246 tty_print_one_vline (gboolean single)
247 {
248 tty_print_alt_char (ACS_VLINE, single);
249 }
250
251
252
253 void
254 tty_draw_box (int y, int x, int ys, int xs, gboolean single)
255 {
256 int y2, x2;
257
258 if (ys <= 0 || xs <= 0)
259 return;
260
261 ys--;
262 xs--;
263
264 y2 = y + ys;
265 x2 = x + xs;
266
267 tty_draw_vline (y, x, mc_tty_frm[single ? MC_TTY_FRM_VERT : MC_TTY_FRM_DVERT], ys);
268 tty_draw_vline (y, x2, mc_tty_frm[single ? MC_TTY_FRM_VERT : MC_TTY_FRM_DVERT], ys);
269 tty_draw_hline (y, x, mc_tty_frm[single ? MC_TTY_FRM_HORIZ : MC_TTY_FRM_DHORIZ], xs);
270 tty_draw_hline (y2, x, mc_tty_frm[single ? MC_TTY_FRM_HORIZ : MC_TTY_FRM_DHORIZ], xs);
271 tty_gotoyx (y, x);
272 tty_print_alt_char (ACS_ULCORNER, single);
273 tty_gotoyx (y2, x);
274 tty_print_alt_char (ACS_LLCORNER, single);
275 tty_gotoyx (y, x2);
276 tty_print_alt_char (ACS_URCORNER, single);
277 tty_gotoyx (y2, x2);
278 tty_print_alt_char (ACS_LRCORNER, single);
279 }
280
281
282
283 void
284 tty_draw_box_shadow (int y, int x, int rows, int cols, int shadow_color)
285 {
286
287 tty_colorize_area (y + 1, x + cols, rows - 1, 2, shadow_color);
288
289 tty_colorize_area (y + rows, x + 2, 1, cols, shadow_color);
290 }
291
292
293
294 char *
295 mc_tty_normalize_from_utf8 (const char *str)
296 {
297 GIConv conv;
298 GString *buffer;
299 const char *_system_codepage = str_detect_termencoding ();
300
301 if (str_isutf8 (_system_codepage))
302 return g_strdup (str);
303
304 conv = g_iconv_open (_system_codepage, "UTF-8");
305 if (conv == INVALID_CONV)
306 return g_strdup (str);
307
308 buffer = g_string_new ("");
309
310 if (str_convert (conv, str, buffer) == ESTR_FAILURE)
311 {
312 g_string_free (buffer, TRUE);
313 str_close_conv (conv);
314 return g_strdup (str);
315 }
316 str_close_conv (conv);
317
318 return g_string_free (buffer, FALSE);
319 }
320
321
322
323
324 int
325 tty_resize (int fd)
326 {
327 #if defined TIOCSWINSZ
328 struct winsize tty_size;
329
330 tty_size.ws_row = LINES;
331 tty_size.ws_col = COLS;
332 tty_size.ws_xpixel = tty_size.ws_ypixel = 0;
333
334 return ioctl (fd, TIOCSWINSZ, &tty_size);
335 #else
336 return 0;
337 #endif
338 }
339
340
341
342
343 void
344 tty_clear_screen (void)
345 {
346 tty_set_normal_attrs ();
347 tty_fill_region (0, 0, LINES, COLS, ' ');
348 tty_refresh ();
349 }
350
351
352
353 void
354 tty_init_xterm_support (gboolean is_xterm)
355 {
356 const char *termvalue;
357
358 termvalue = getenv ("TERM");
359
360
361
362
363
364 xmouse_seq = tty_tgetstr ("kmous");
365 if (xmouse_seq == NULL)
366 xmouse_seq = tty_tgetstr ("Km");
367 smcup = tty_tgetstr ("smcup");
368 if (smcup == NULL)
369 smcup = tty_tgetstr ("ti");
370 rmcup = tty_tgetstr ("rmcup");
371 if (rmcup == NULL)
372 rmcup = tty_tgetstr ("te");
373
374 if (strcmp (termvalue, "cygwin") == 0)
375 {
376 is_xterm = TRUE;
377 use_mouse_p = MOUSE_DISABLED;
378 }
379
380 if (is_xterm)
381 {
382
383 if (xmouse_seq == NULL)
384 xmouse_seq = ESC_STR "[M";
385
386
387 if (use_mouse_p != MOUSE_DISABLED)
388 {
389 if (mc_global.tty.old_mouse)
390 use_mouse_p = MOUSE_XTERM_NORMAL_TRACKING;
391 else
392 {
393
394 const char *color_term = getenv ("COLORTERM");
395 if (strncmp (termvalue, "rxvt", 4) == 0 ||
396 (color_term != NULL && strncmp (color_term, "rxvt", 4) == 0) ||
397 strcmp (termvalue, "Eterm") == 0)
398 use_mouse_p = MOUSE_XTERM_NORMAL_TRACKING;
399 else
400 use_mouse_p = MOUSE_XTERM_BUTTON_EVENT_TRACKING;
401 }
402 }
403 }
404
405
406
407
408 if (xmouse_seq != NULL)
409 {
410 if (strcmp (xmouse_seq, ESC_STR "[<") == 0)
411 xmouse_seq = ESC_STR "[M";
412
413 xmouse_extended_seq = ESC_STR "[<";
414 }
415 }
416
417