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