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