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