This source file includes following definitions.
- tty_setup_sigwinch
- sigwinch_handler
- tty_clip
- mc_tty_normalize_lines_char
- tty_init
- tty_shutdown
- tty_enter_ca_mode
- tty_exit_ca_mode
- tty_change_screen_size
- tty_reset_prog_mode
- tty_reset_shell_mode
- tty_raw_mode
- tty_noraw_mode
- tty_noecho
- tty_flush_input
- tty_keypad
- tty_nodelay
- tty_baudrate
- tty_lowlevel_getch
- tty_reset_screen
- tty_touch_screen
- tty_gotoyx
- tty_getyx
- tty_draw_hline
- tty_draw_vline
- tty_fill_region
- tty_colorize_area
- tty_set_alt_charset
- tty_display_8bit
- tty_print_char
- tty_print_anychar
- tty_print_alt_char
- tty_print_string
- tty_printf
- tty_tgetstr
- tty_refresh
- tty_beep
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
32 #include <config.h>
33
34 #include <stdlib.h>
35 #include <stdarg.h>
36 #include <signal.h>
37 #ifdef HAVE_SYS_IOCTL_H
38 #include <sys/ioctl.h>
39 #endif
40 #include <termios.h>
41
42 #include "lib/global.h"
43 #include "lib/strutil.h"
44 #include "lib/util.h"
45
46 #ifndef WANT_TERM_H
47 #define WANT_TERM_H
48 #endif
49
50 #include "tty-internal.h"
51 #include "tty.h"
52 #include "color.h"
53 #include "color-internal.h"
54 #include "key.h"
55 #include "mouse.h"
56 #include "win.h"
57
58
59 #ifdef WANT_TERM_H
60 #ifdef HAVE_NCURSES_TERM_H
61 #include <ncurses/term.h>
62 #else
63 #include <term.h>
64 #endif
65 #endif
66
67
68
69
70
71 #if !defined(CTRL)
72 #define CTRL(x) ((x) & 0x1f)
73 #endif
74
75 #define yx_in_screen(y, x) \
76 (y >= 0 && y < LINES && x >= 0 && x < COLS)
77
78
79
80
81
82
83
84
85
86
87
88 static int mc_curs_row, mc_curs_col;
89
90
91
92
93
94 static void
95 tty_setup_sigwinch (void (*handler) (int))
96 {
97 #if (NCURSES_VERSION_MAJOR >= 4) && defined (SIGWINCH)
98 struct sigaction act, oact;
99
100 memset (&act, 0, sizeof (act));
101 act.sa_handler = handler;
102 sigemptyset (&act.sa_mask);
103 #ifdef SA_RESTART
104 act.sa_flags = SA_RESTART;
105 #endif
106 my_sigaction (SIGWINCH, &act, &oact);
107 #endif
108
109 tty_create_winch_pipe ();
110 }
111
112
113
114 static void
115 sigwinch_handler (int dummy)
116 {
117 ssize_t n = 0;
118
119 (void) dummy;
120
121 n = write (sigwinch_pipe[1], "", 1);
122 (void) n;
123 }
124
125
126
127
128
129
130
131
132 static gboolean
133 tty_clip (int *y, int *x, int *rows, int *cols)
134 {
135 if (*y < 0)
136 {
137 *rows += *y;
138
139 if (*rows <= 0)
140 return FALSE;
141
142 *y = 0;
143 }
144
145 if (*x < 0)
146 {
147 *cols += *x;
148
149 if (*cols <= 0)
150 return FALSE;
151
152 *x = 0;
153 }
154
155 if (*y + *rows > LINES)
156 *rows = LINES - *y;
157
158 if (*rows <= 0)
159 return FALSE;
160
161 if (*x + *cols > COLS)
162 *cols = COLS - *x;
163
164 if (*cols <= 0)
165 return FALSE;
166
167 return TRUE;
168 }
169
170
171
172
173
174 int
175 mc_tty_normalize_lines_char (const char *ch)
176 {
177 char *str2;
178 int res;
179
180 struct mc_tty_lines_struct
181 {
182 const char *line;
183 int line_code;
184 } const lines_codes[] = {
185 {"\342\224\230", ACS_LRCORNER},
186 {"\342\224\224", ACS_LLCORNER},
187 {"\342\224\220", ACS_URCORNER},
188 {"\342\224\214", ACS_ULCORNER},
189 {"\342\224\234", ACS_LTEE},
190 {"\342\224\244", ACS_RTEE},
191 {"\342\224\254", ACS_TTEE},
192 {"\342\224\264", ACS_BTEE},
193 {"\342\224\200", ACS_HLINE},
194 {"\342\224\202", ACS_VLINE},
195 {"\342\224\274", ACS_PLUS},
196
197 {"\342\225\235", ACS_LRCORNER | A_BOLD},
198 {"\342\225\232", ACS_LLCORNER | A_BOLD},
199 {"\342\225\227", ACS_URCORNER | A_BOLD},
200 {"\342\225\224", ACS_ULCORNER | A_BOLD},
201 {"\342\225\237", ACS_LTEE | A_BOLD},
202 {"\342\225\242", ACS_RTEE | A_BOLD},
203 {"\342\225\244", ACS_TTEE | A_BOLD},
204 {"\342\225\247", ACS_BTEE | A_BOLD},
205 {"\342\225\220", ACS_HLINE | A_BOLD},
206 {"\342\225\221", ACS_VLINE | A_BOLD},
207
208 {NULL, 0}
209 };
210
211 if (ch == NULL)
212 return (int) ' ';
213
214 for (res = 0; lines_codes[res].line; res++)
215 {
216 if (strcmp (ch, lines_codes[res].line) == 0)
217 return lines_codes[res].line_code;
218 }
219
220 str2 = mc_tty_normalize_from_utf8 (ch);
221 res = g_utf8_get_char_validated (str2, -1);
222
223 if (res < 0)
224 res = (unsigned char) str2[0];
225 g_free (str2);
226
227 return res;
228 }
229
230
231
232 void
233 tty_init (gboolean mouse_enable, gboolean is_xterm)
234 {
235 struct termios mode;
236
237 initscr ();
238
239 #ifdef HAVE_ESCDELAY
240
241
242
243
244
245
246
247
248
249 ESCDELAY = 200;
250 #endif
251
252 tcgetattr (STDIN_FILENO, &mode);
253
254 mode.c_cc[VINTR] = CTRL ('g');
255
256 mode.c_cc[VQUIT] = NULL_VALUE;
257 tcsetattr (STDIN_FILENO, TCSANOW, &mode);
258
259
260 def_prog_mode ();
261
262 tty_start_interrupt_key ();
263
264 if (!mouse_enable)
265 use_mouse_p = MOUSE_DISABLED;
266 tty_init_xterm_support (is_xterm);
267 tty_enter_ca_mode ();
268 tty_raw_mode ();
269 noecho ();
270 keypad (stdscr, TRUE);
271 nodelay (stdscr, FALSE);
272
273 tty_setup_sigwinch (sigwinch_handler);
274 }
275
276
277
278 void
279 tty_shutdown (void)
280 {
281 tty_destroy_winch_pipe ();
282 tty_reset_shell_mode ();
283 tty_noraw_mode ();
284 tty_keypad (FALSE);
285 tty_reset_screen ();
286 tty_exit_ca_mode ();
287 }
288
289
290
291 void
292 tty_enter_ca_mode (void)
293 {
294 if (mc_global.tty.xterm_flag && smcup != NULL)
295 {
296 fprintf (stdout, ESC_STR "7" ESC_STR "[?47h");
297 fflush (stdout);
298 }
299 }
300
301
302
303 void
304 tty_exit_ca_mode (void)
305 {
306 if (mc_global.tty.xterm_flag && rmcup != NULL)
307 {
308 fprintf (stdout, ESC_STR "[?47l" ESC_STR "8" ESC_STR "[m");
309 fflush (stdout);
310 }
311 }
312
313
314
315 void
316 tty_change_screen_size (void)
317 {
318 #if defined(TIOCGWINSZ) && NCURSES_VERSION_MAJOR >= 4
319 struct winsize winsz;
320
321 winsz.ws_col = winsz.ws_row = 0;
322
323 #ifndef NCURSES_VERSION
324 tty_noraw_mode ();
325 tty_reset_screen ();
326 #endif
327
328
329 ioctl (fileno (stdout), TIOCGWINSZ, &winsz);
330 if (winsz.ws_col != 0 && winsz.ws_row != 0)
331 {
332 #if defined(NCURSES_VERSION) && defined(HAVE_RESIZETERM)
333 resizeterm (winsz.ws_row, winsz.ws_col);
334 clearok (stdscr, TRUE);
335 #else
336 COLS = winsz.ws_col;
337 LINES = winsz.ws_row;
338 #endif
339 }
340 #endif
341
342 #ifdef ENABLE_SUBSHELL
343 if (mc_global.tty.use_subshell)
344 tty_resize (mc_global.tty.subshell_pty);
345 #endif
346 }
347
348
349
350 void
351 tty_reset_prog_mode (void)
352 {
353 reset_prog_mode ();
354 }
355
356
357
358 void
359 tty_reset_shell_mode (void)
360 {
361 reset_shell_mode ();
362 }
363
364
365
366 void
367 tty_raw_mode (void)
368 {
369 raw ();
370 cbreak ();
371 }
372
373
374
375 void
376 tty_noraw_mode (void)
377 {
378 nocbreak ();
379 noraw ();
380 }
381
382
383
384 void
385 tty_noecho (void)
386 {
387 noecho ();
388 }
389
390
391
392 int
393 tty_flush_input (void)
394 {
395 return flushinp ();
396 }
397
398
399
400 void
401 tty_keypad (gboolean set)
402 {
403 keypad (stdscr, (bool) set);
404 }
405
406
407
408 void
409 tty_nodelay (gboolean set)
410 {
411 nodelay (stdscr, (bool) set);
412 }
413
414
415
416 int
417 tty_baudrate (void)
418 {
419 return baudrate ();
420 }
421
422
423
424 int
425 tty_lowlevel_getch (void)
426 {
427 return getch ();
428 }
429
430
431
432 int
433 tty_reset_screen (void)
434 {
435 return endwin ();
436 }
437
438
439
440 void
441 tty_touch_screen (void)
442 {
443 touchwin (stdscr);
444 }
445
446
447
448 void
449 tty_gotoyx (int y, int x)
450 {
451 mc_curs_row = y;
452 mc_curs_col = x;
453
454 if (y < 0)
455 y = 0;
456 if (y >= LINES)
457 y = LINES - 1;
458
459 if (x < 0)
460 x = 0;
461 if (x >= COLS)
462 x = COLS - 1;
463
464 move (y, x);
465 }
466
467
468
469 void
470 tty_getyx (int *py, int *px)
471 {
472 *py = mc_curs_row;
473 *px = mc_curs_col;
474 }
475
476
477
478 void
479 tty_draw_hline (int y, int x, int ch, int len)
480 {
481 int x1;
482
483 if (y < 0 || y >= LINES || x >= COLS)
484 return;
485
486 x1 = x;
487
488 if (x < 0)
489 {
490 len += x;
491 if (len <= 0)
492 return;
493 x = 0;
494 }
495
496 if ((chtype) ch == ACS_HLINE)
497 ch = mc_tty_frm[MC_TTY_FRM_HORIZ];
498
499 move (y, x);
500 hline (ch, len);
501 move (y, x1);
502
503 mc_curs_row = y;
504 mc_curs_col = x1;
505 }
506
507
508
509 void
510 tty_draw_vline (int y, int x, int ch, int len)
511 {
512 int y1;
513
514 if (x < 0 || x >= COLS || y >= LINES)
515 return;
516
517 y1 = y;
518
519 if (y < 0)
520 {
521 len += y;
522 if (len <= 0)
523 return;
524 y = 0;
525 }
526
527 if ((chtype) ch == ACS_VLINE)
528 ch = mc_tty_frm[MC_TTY_FRM_VERT];
529
530 move (y, x);
531 vline (ch, len);
532 move (y1, x);
533
534 mc_curs_row = y1;
535 mc_curs_col = x;
536 }
537
538
539
540 void
541 tty_fill_region (int y, int x, int rows, int cols, unsigned char ch)
542 {
543 int i;
544
545 if (!tty_clip (&y, &x, &rows, &cols))
546 return;
547
548 for (i = 0; i < rows; i++)
549 {
550 move (y + i, x);
551 hline (ch, cols);
552 }
553
554 move (y, x);
555
556 mc_curs_row = y;
557 mc_curs_col = x;
558 }
559
560
561
562 void
563 tty_colorize_area (int y, int x, int rows, int cols, int color)
564 {
565 #ifdef ENABLE_SHADOWS
566 cchar_t *ctext;
567 wchar_t wch[10];
568 attr_t attrs;
569 short color_pair;
570
571 if (!use_colors || !tty_clip (&y, &x, &rows, &cols))
572 return;
573
574 tty_setcolor (color);
575 ctext = g_malloc (sizeof (cchar_t) * (cols + 1));
576
577 for (int row = 0; row < rows; row++)
578 {
579 mvin_wchnstr (y + row, x, ctext, cols);
580
581 for (int col = 0; col < cols; col++)
582 {
583 getcchar (&ctext[col], wch, &attrs, &color_pair, NULL);
584 setcchar (&ctext[col], wch, attrs, color, NULL);
585 }
586
587 mvadd_wchnstr (y + row, x, ctext, cols);
588 }
589
590 g_free (ctext);
591 #else
592 (void) y;
593 (void) x;
594 (void) rows;
595 (void) cols;
596 (void) color;
597 #endif
598 }
599
600
601
602 void
603 tty_set_alt_charset (gboolean alt_charset)
604 {
605 (void) alt_charset;
606 }
607
608
609
610 void
611 tty_display_8bit (gboolean what)
612 {
613 meta (stdscr, (int) what);
614 }
615
616
617
618 void
619 tty_print_char (int c)
620 {
621 if (yx_in_screen (mc_curs_row, mc_curs_col))
622 addch (c);
623 mc_curs_col++;
624 }
625
626
627
628 void
629 tty_print_anychar (int c)
630 {
631 if (mc_global.utf8_display || c > 255)
632 {
633 int res;
634 unsigned char str[UTF8_CHAR_LEN + 1];
635
636 res = g_unichar_to_utf8 (c, (char *) str);
637 if (res == 0)
638 {
639 if (yx_in_screen (mc_curs_row, mc_curs_col))
640 addch ('.');
641 mc_curs_col++;
642 }
643 else
644 {
645 const char *s;
646
647 str[res] = '\0';
648 s = str_term_form ((char *) str);
649
650 if (yx_in_screen (mc_curs_row, mc_curs_col))
651 addstr (s);
652
653 if (g_unichar_iswide (c))
654 mc_curs_col += 2;
655 else if (!g_unichar_iszerowidth (c))
656 mc_curs_col++;
657 }
658 }
659 else
660 {
661 if (yx_in_screen (mc_curs_row, mc_curs_col))
662 addch (c);
663 mc_curs_col++;
664 }
665 }
666
667
668
669 void
670 tty_print_alt_char (int c, gboolean single)
671 {
672 if (yx_in_screen (mc_curs_row, mc_curs_col))
673 {
674 if ((chtype) c == ACS_VLINE)
675 c = mc_tty_frm[single ? MC_TTY_FRM_VERT : MC_TTY_FRM_DVERT];
676 else if ((chtype) c == ACS_HLINE)
677 c = mc_tty_frm[single ? MC_TTY_FRM_HORIZ : MC_TTY_FRM_DHORIZ];
678 else if ((chtype) c == ACS_LTEE)
679 c = mc_tty_frm[single ? MC_TTY_FRM_LEFTMIDDLE : MC_TTY_FRM_DLEFTMIDDLE];
680 else if ((chtype) c == ACS_RTEE)
681 c = mc_tty_frm[single ? MC_TTY_FRM_RIGHTMIDDLE : MC_TTY_FRM_DRIGHTMIDDLE];
682 else if ((chtype) c == ACS_ULCORNER)
683 c = mc_tty_frm[single ? MC_TTY_FRM_LEFTTOP : MC_TTY_FRM_DLEFTTOP];
684 else if ((chtype) c == ACS_LLCORNER)
685 c = mc_tty_frm[single ? MC_TTY_FRM_LEFTBOTTOM : MC_TTY_FRM_DLEFTBOTTOM];
686 else if ((chtype) c == ACS_URCORNER)
687 c = mc_tty_frm[single ? MC_TTY_FRM_RIGHTTOP : MC_TTY_FRM_DRIGHTTOP];
688 else if ((chtype) c == ACS_LRCORNER)
689 c = mc_tty_frm[single ? MC_TTY_FRM_RIGHTBOTTOM : MC_TTY_FRM_DRIGHTBOTTOM];
690 else if ((chtype) c == ACS_PLUS)
691 c = mc_tty_frm[MC_TTY_FRM_CROSS];
692
693 addch (c);
694 }
695
696 mc_curs_col++;
697 }
698
699
700
701 void
702 tty_print_string (const char *s)
703 {
704 int len;
705 int start = 0;
706
707 s = str_term_form (s);
708 len = str_term_width1 (s);
709
710
711 if (mc_curs_row < 0 || mc_curs_row >= LINES || mc_curs_col + len <= 0 || mc_curs_col >= COLS)
712 {
713 mc_curs_col += len;
714 return;
715 }
716
717
718 if (mc_curs_col < 0)
719 {
720 start = -mc_curs_col;
721 len += mc_curs_col;
722 mc_curs_col = 0;
723 }
724
725 mc_curs_col += len;
726 if (mc_curs_col >= COLS)
727 len = COLS - (mc_curs_col - len);
728
729 addstr (str_term_substring (s, start, len));
730 }
731
732
733
734 void
735 tty_printf (const char *fmt, ...)
736 {
737 va_list args;
738 char buf[BUF_1K];
739
740 va_start (args, fmt);
741 g_vsnprintf (buf, sizeof (buf), fmt, args);
742 va_end (args);
743 tty_print_string (buf);
744 }
745
746
747
748 char *
749 tty_tgetstr (const char *cap)
750 {
751 char *unused = NULL;
752
753 return tgetstr ((NCURSES_CONST char *) cap, &unused);
754 }
755
756
757
758 void
759 tty_refresh (void)
760 {
761 refresh ();
762 doupdate ();
763 }
764
765
766
767 void
768 tty_beep (void)
769 {
770 beep ();
771 }
772
773