This source file includes following definitions.
- sigintr_handler
- tty_check_xterm_compat
- 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_xterm_compat (const gboolean force_xterm)
112 {
113 static const char *xterm_compatible_terminals[] = {
114 "alacritty",
115 "contour",
116 "dtterm",
117 "Eterm",
118 "foot",
119 "konsole",
120 "rxvt",
121 "screen",
122 "tmux",
123 "xterm",
124 NULL,
125 };
126
127 const char *termvalue = getenv ("TERM");
128 if (termvalue == NULL || *termvalue == '\0')
129 {
130 fputs (_ ("The TERM environment variable is unset!\n"), stderr);
131 my_exit (EXIT_FAILURE);
132 }
133
134 if (force_xterm)
135 return TRUE;
136
137 for (const char **p = xterm_compatible_terminals; *p != NULL; p++)
138 if (strncmp (termvalue, *p, strlen (*p)) == 0)
139 return TRUE;
140
141 return FALSE;
142 }
143
144
145 extern void
146 tty_start_interrupt_key (void)
147 {
148 struct sigaction act;
149
150 memset (&act, 0, sizeof (act));
151 act.sa_handler = sigintr_handler;
152 sigemptyset (&act.sa_mask);
153 #ifdef SA_RESTART
154 act.sa_flags = SA_RESTART;
155 #endif
156 my_sigaction (SIGINT, &act, NULL);
157 }
158
159
160
161 extern void
162 tty_enable_interrupt_key (void)
163 {
164 struct sigaction act;
165
166 memset (&act, 0, sizeof (act));
167 act.sa_handler = sigintr_handler;
168 sigemptyset (&act.sa_mask);
169 my_sigaction (SIGINT, &act, NULL);
170 got_interrupt = 0;
171 }
172
173
174
175 extern void
176 tty_disable_interrupt_key (void)
177 {
178 struct sigaction act;
179
180 memset (&act, 0, sizeof (act));
181 act.sa_handler = SIG_IGN;
182 sigemptyset (&act.sa_mask);
183 my_sigaction (SIGINT, &act, NULL);
184 }
185
186
187
188 extern gboolean
189 tty_got_interrupt (void)
190 {
191 gboolean rv;
192
193 rv = (got_interrupt != 0);
194 got_interrupt = 0;
195 return rv;
196 }
197
198
199
200 gboolean
201 tty_got_winch (void)
202 {
203 fd_set fdset;
204
205 struct timeval timeout = { .tv_sec = 0, .tv_usec = 0 };
206 int ok;
207
208 FD_ZERO (&fdset);
209 FD_SET (sigwinch_pipe[0], &fdset);
210
211 while ((ok = select (sigwinch_pipe[0] + 1, &fdset, NULL, NULL, &timeout)) < 0)
212 if (errno != EINTR)
213 {
214 perror (_ ("Cannot check SIGWINCH pipe"));
215 exit (EXIT_FAILURE);
216 }
217
218 return (ok != 0 && FD_ISSET (sigwinch_pipe[0], &fdset));
219 }
220
221
222
223 gboolean
224 tty_flush_winch (void)
225 {
226 ssize_t n;
227 gboolean ret = FALSE;
228
229
230 do
231 {
232 char x[16];
233
234
235 n = read (sigwinch_pipe[0], &x, sizeof (x));
236
237
238 if (n > 0)
239 ret = TRUE;
240 }
241 while (n > 0 || (n == -1 && errno == EINTR));
242
243 return ret;
244 }
245
246
247
248 void
249 tty_print_one_hline (gboolean single)
250 {
251 tty_print_alt_char (ACS_HLINE, single);
252 }
253
254
255
256 void
257 tty_print_one_vline (gboolean single)
258 {
259 tty_print_alt_char (ACS_VLINE, single);
260 }
261
262
263
264 void
265 tty_draw_box (int y, int x, int ys, int xs, gboolean single)
266 {
267 int y2, x2;
268
269 if (ys <= 0 || xs <= 0)
270 return;
271
272 ys--;
273 xs--;
274
275 y2 = y + ys;
276 x2 = x + xs;
277
278 tty_draw_vline (y, x, mc_tty_frm[single ? MC_TTY_FRM_VERT : MC_TTY_FRM_DVERT], ys);
279 tty_draw_vline (y, x2, mc_tty_frm[single ? MC_TTY_FRM_VERT : MC_TTY_FRM_DVERT], ys);
280 tty_draw_hline (y, x, mc_tty_frm[single ? MC_TTY_FRM_HORIZ : MC_TTY_FRM_DHORIZ], xs);
281 tty_draw_hline (y2, x, mc_tty_frm[single ? MC_TTY_FRM_HORIZ : MC_TTY_FRM_DHORIZ], xs);
282 tty_gotoyx (y, x);
283 tty_print_alt_char (ACS_ULCORNER, single);
284 tty_gotoyx (y2, x);
285 tty_print_alt_char (ACS_LLCORNER, single);
286 tty_gotoyx (y, x2);
287 tty_print_alt_char (ACS_URCORNER, single);
288 tty_gotoyx (y2, x2);
289 tty_print_alt_char (ACS_LRCORNER, single);
290 }
291
292
293
294 void
295 tty_draw_box_shadow (int y, int x, int rows, int cols, int shadow_color)
296 {
297
298 tty_colorize_area (y + 1, x + cols, rows - 1, 2, shadow_color);
299
300 tty_colorize_area (y + rows, x + 2, 1, cols, shadow_color);
301 }
302
303
304
305 char *
306 mc_tty_normalize_from_utf8 (const char *str)
307 {
308 GIConv conv;
309 GString *buffer;
310 const char *_system_codepage = str_detect_termencoding ();
311
312 if (str_isutf8 (_system_codepage))
313 return g_strdup (str);
314
315 conv = g_iconv_open (_system_codepage, "UTF-8");
316 if (conv == INVALID_CONV)
317 return g_strdup (str);
318
319 buffer = g_string_new ("");
320
321 if (str_convert (conv, str, buffer) == ESTR_FAILURE)
322 {
323 g_string_free (buffer, TRUE);
324 str_close_conv (conv);
325 return g_strdup (str);
326 }
327 str_close_conv (conv);
328
329 return g_string_free (buffer, FALSE);
330 }
331
332
333
334
335 int
336 tty_resize (int fd)
337 {
338 #if defined TIOCSWINSZ
339 struct winsize tty_size;
340
341 tty_size.ws_row = LINES;
342 tty_size.ws_col = COLS;
343 tty_size.ws_xpixel = tty_size.ws_ypixel = 0;
344
345 return ioctl (fd, TIOCSWINSZ, &tty_size);
346 #else
347 return 0;
348 #endif
349 }
350
351
352
353
354 void
355 tty_clear_screen (void)
356 {
357 tty_set_normal_attrs ();
358 tty_fill_region (0, 0, LINES, COLS, ' ');
359 tty_refresh ();
360 }
361
362
363
364 void
365 tty_init_xterm_support (gboolean is_xterm)
366 {
367 const char *termvalue;
368
369 termvalue = getenv ("TERM");
370
371
372
373
374
375 xmouse_seq = tty_tgetstr ("kmous");
376 if (xmouse_seq == NULL)
377 xmouse_seq = tty_tgetstr ("Km");
378 smcup = tty_tgetstr ("smcup");
379 if (smcup == NULL)
380 smcup = tty_tgetstr ("ti");
381 rmcup = tty_tgetstr ("rmcup");
382 if (rmcup == NULL)
383 rmcup = tty_tgetstr ("te");
384
385 if (strcmp (termvalue, "cygwin") == 0)
386 {
387 is_xterm = TRUE;
388 use_mouse_p = MOUSE_DISABLED;
389 }
390
391 if (is_xterm)
392 {
393
394 if (xmouse_seq == NULL)
395 xmouse_seq = ESC_STR "[M";
396
397
398 if (use_mouse_p != MOUSE_DISABLED)
399 {
400 if (mc_global.tty.old_mouse)
401 use_mouse_p = MOUSE_XTERM_NORMAL_TRACKING;
402 else
403 {
404
405 const char *color_term = getenv ("COLORTERM");
406 if (strncmp (termvalue, "rxvt", 4) == 0
407 || (color_term != NULL && strncmp (color_term, "rxvt", 4) == 0)
408 || strcmp (termvalue, "Eterm") == 0)
409 use_mouse_p = MOUSE_XTERM_NORMAL_TRACKING;
410 else
411 use_mouse_p = MOUSE_XTERM_BUTTON_EVENT_TRACKING;
412 }
413 }
414 }
415
416
417
418
419 if (xmouse_seq != NULL)
420 {
421 if (strcmp (xmouse_seq, ESC_STR "[<") == 0)
422 xmouse_seq = ESC_STR "[M";
423
424 xmouse_extended_seq = ESC_STR "[<";
425 }
426 }
427
428