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