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