This source file includes following definitions.
- tty_setup_sigwinch
- sigwinch_handler
- slang_reset_softkeys
- do_define_key
- load_terminfo_keys
- 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_alt_char
- tty_print_anychar
- 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 <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <sys/types.h>
38 #include <unistd.h>
39 #ifdef HAVE_SYS_IOCTL_H
40 # include <sys/ioctl.h>
41 #endif
42 #include <termios.h>
43
44 #include "lib/global.h"
45 #include "lib/strutil.h"
46 #include "lib/util.h"
47
48 #include "tty-internal.h"
49 #include "tty.h"
50 #include "color.h"
51 #include "color-slang.h"
52 #include "color-internal.h"
53 #include "mouse.h"
54 #include "key.h"
55 #include "win.h"
56
57
58
59
60
61
62 int reset_hp_softkeys = 0;
63
64
65
66 #ifndef SLTT_MAX_SCREEN_COLS
67 # define SLTT_MAX_SCREEN_COLS 512
68 #endif
69
70 #ifndef SLTT_MAX_SCREEN_ROWS
71 # define SLTT_MAX_SCREEN_ROWS 512
72 #endif
73
74
75
76
77
78
79
80
81 static struct termios boot_mode;
82 static struct termios new_mode;
83
84
85 static gboolean no_slang_delay;
86
87 static gboolean slsmg_active = FALSE;
88
89
90
91
92 static const struct
93 {
94 int key_code;
95 const char *key_name;
96 } key_table[] = {
97 { KEY_F (0), "k0" },
98 { KEY_F (1), "k1" },
99 { KEY_F (2), "k2" },
100 { KEY_F (3), "k3" },
101 { KEY_F (4), "k4" },
102 { KEY_F (5), "k5" },
103 { KEY_F (6), "k6" },
104 { KEY_F (7), "k7" },
105 { KEY_F (8), "k8" },
106 { KEY_F (9), "k9" },
107 { KEY_F (10), "k;" },
108 { KEY_F (11), "F1" },
109 { KEY_F (12), "F2" },
110 { KEY_F (13), "F3" },
111 { KEY_F (14), "F4" },
112 { KEY_F (15), "F5" },
113 { KEY_F (16), "F6" },
114 { KEY_F (17), "F7" },
115 { KEY_F (18), "F8" },
116 { KEY_F (19), "F9" },
117 { KEY_F (20), "FA" },
118 { KEY_IC, "kI" },
119 { KEY_NPAGE, "kN" },
120 { KEY_PPAGE, "kP" },
121 { KEY_LEFT, "kl" },
122 { KEY_RIGHT, "kr" },
123 { KEY_UP, "ku" },
124 { KEY_DOWN, "kd" },
125 { KEY_DC, "kD" },
126 { KEY_BACKSPACE, "kb" },
127 { KEY_HOME, "kh" },
128 { KEY_END, "@7" },
129 {
130 0,
131 NULL,
132 },
133 };
134
135
136
137
138
139 static void
140 tty_setup_sigwinch (void (*handler) (int))
141 {
142 (void) SLsignal (SIGWINCH, handler);
143 tty_create_winch_pipe ();
144 }
145
146
147
148 static void
149 sigwinch_handler (int dummy)
150 {
151 ssize_t n = 0;
152
153 (void) dummy;
154
155 n = write (sigwinch_pipe[1], "", 1);
156 (void) n;
157
158 (void) SLsignal (SIGWINCH, sigwinch_handler);
159 }
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178 static void
179 slang_reset_softkeys (void)
180 {
181 int key;
182 static const char display[] = " ";
183 char tmp[BUF_SMALL];
184
185 for (key = 1; key < 9; key++)
186 {
187 char *send;
188
189 g_snprintf (tmp, sizeof (tmp), "k%d", key);
190 send = SLtt_tgetstr (tmp);
191 if (send != NULL)
192 {
193 g_snprintf (tmp, sizeof (tmp), ESC_STR "&f%dk%dd%dL%s%s", key,
194 (int) (sizeof (display) - 1), (int) strlen (send), display, send);
195 SLtt_write_string (tmp);
196 }
197 }
198 }
199
200
201
202 static void
203 do_define_key (int code, const char *strcap)
204 {
205 char *seq;
206
207 seq = SLtt_tgetstr ((SLFUTURE_CONST char *) strcap);
208 if (seq != NULL)
209 define_sequence (code, seq, MCKEY_NOACTION);
210 }
211
212
213
214 static void
215 load_terminfo_keys (void)
216 {
217 int i;
218
219 for (i = 0; key_table[i].key_code; i++)
220 do_define_key (key_table[i].key_code, key_table[i].key_name);
221 }
222
223
224
225
226
227 int
228 mc_tty_normalize_lines_char (const char *str)
229 {
230 char *str2;
231 int res;
232
233 struct mc_tty_lines_struct
234 {
235 const char *line;
236 int line_code;
237 } const lines_codes[] = {
238 { "\342\224\214", SLSMG_ULCORN_CHAR },
239 { "\342\224\220", SLSMG_URCORN_CHAR },
240 { "\342\224\224", SLSMG_LLCORN_CHAR },
241 { "\342\224\230", SLSMG_LRCORN_CHAR },
242 { "\342\224\234", SLSMG_LTEE_CHAR },
243 { "\342\224\244", SLSMG_RTEE_CHAR },
244 { "\342\224\254", SLSMG_UTEE_CHAR },
245 { "\342\224\264", SLSMG_DTEE_CHAR },
246 { "\342\224\200", SLSMG_HLINE_CHAR },
247 { "\342\224\202", SLSMG_VLINE_CHAR },
248 { "\342\224\274", SLSMG_PLUS_CHAR },
249
250 { NULL, 0 },
251 };
252
253 if (!str)
254 return (int) ' ';
255
256 for (res = 0; lines_codes[res].line; res++)
257 {
258 if (strcmp (str, lines_codes[res].line) == 0)
259 return lines_codes[res].line_code;
260 }
261
262 str2 = mc_tty_normalize_from_utf8 (str);
263 res = g_utf8_get_char_validated (str2, -1);
264
265 if (res < 0)
266 res = (unsigned char) str2[0];
267 g_free (str2);
268
269 return res;
270 }
271
272
273
274 void
275 tty_init (gboolean mouse_enable, gboolean is_xterm)
276 {
277 SLtt_Ignore_Beep = 1;
278
279 SLutf8_enable (-1);
280 SLtt_get_terminfo ();
281
282
283
284
285
286
287
288 if ((COLS < 10)
289 || (LINES < 5)
290 #if SLANG_VERSION < 20303
291
292
293 || (COLS > SLTT_MAX_SCREEN_COLS) || (LINES > SLTT_MAX_SCREEN_ROWS)
294 #endif
295 )
296 {
297 fprintf (stderr,
298 _ ("Screen size %dx%d is not supported.\n"
299 "Check the TERM environment variable.\n"),
300 COLS, LINES);
301 exit (EXIT_FAILURE);
302 }
303
304 tcgetattr (fileno (stdin), &boot_mode);
305
306 SLang_init_tty (XCTRL ('g'), 1, 0);
307
308 if (mc_global.tty.ugly_line_drawing)
309 SLtt_Has_Alt_Charset = 0;
310
311 tcgetattr (SLang_TT_Read_FD, &new_mode);
312
313 tty_reset_prog_mode ();
314 load_terminfo_keys ();
315
316 SLtt_Blink_Mode = (tty_use_256colors (NULL) || tty_use_truecolors (NULL)) ? 1 : 0;
317
318 tty_start_interrupt_key ();
319
320
321 init_key_input_fd ();
322
323
324
325
326
327
328 tty_display_8bit (FALSE);
329
330 SLsmg_init_smg ();
331 slsmg_active = TRUE;
332 if (!mouse_enable)
333 use_mouse_p = MOUSE_DISABLED;
334 tty_init_xterm_support (is_xterm);
335 tty_enter_ca_mode ();
336 tty_keypad (TRUE);
337 tty_nodelay (FALSE);
338
339 tty_setup_sigwinch (sigwinch_handler);
340 }
341
342
343
344 void
345 tty_shutdown (void)
346 {
347 char *op_cap;
348
349 tty_destroy_winch_pipe ();
350 tty_reset_shell_mode ();
351 tty_noraw_mode ();
352 tty_keypad (FALSE);
353 tty_reset_screen ();
354 tty_exit_ca_mode ();
355 SLang_reset_tty ();
356 slsmg_active = FALSE;
357
358
359
360
361 op_cap = SLtt_tgetstr ((SLFUTURE_CONST char *) "op");
362 if (op_cap != NULL)
363 {
364 fputs (op_cap, stdout);
365 fflush (stdout);
366 }
367 }
368
369
370
371 void
372 tty_enter_ca_mode (void)
373 {
374
375 }
376
377
378
379 void
380 tty_exit_ca_mode (void)
381 {
382
383 }
384
385
386
387 void
388 tty_change_screen_size (void)
389 {
390 SLtt_get_screen_size ();
391 if (slsmg_active)
392 SLsmg_reinit_smg ();
393
394 #ifdef ENABLE_SUBSHELL
395 if (mc_global.tty.use_subshell)
396 tty_resize (mc_global.tty.subshell_pty);
397 #endif
398 }
399
400
401
402
403 void
404 tty_reset_prog_mode (void)
405 {
406 tcsetattr (SLang_TT_Read_FD, TCSANOW, &new_mode);
407 SLsmg_init_smg ();
408 slsmg_active = TRUE;
409 SLsmg_touch_lines (0, LINES);
410 }
411
412
413
414
415 void
416 tty_reset_shell_mode (void)
417 {
418 tcsetattr (SLang_TT_Read_FD, TCSANOW, &boot_mode);
419 }
420
421
422
423 void
424 tty_raw_mode (void)
425 {
426 tcsetattr (SLang_TT_Read_FD, TCSANOW, &new_mode);
427 }
428
429
430
431 void
432 tty_noraw_mode (void)
433 {
434 }
435
436
437
438 void
439 tty_noecho (void)
440 {
441 }
442
443
444
445 int
446 tty_flush_input (void)
447 {
448 return 0;
449 }
450
451
452
453 void
454 tty_keypad (gboolean set)
455 {
456 char *keypad_string;
457
458 keypad_string = SLtt_tgetstr ((SLFUTURE_CONST char *) (set ? "ks" : "ke"));
459 if (keypad_string != NULL)
460 SLtt_write_string (keypad_string);
461 if (set && reset_hp_softkeys)
462 slang_reset_softkeys ();
463 }
464
465
466
467 void
468 tty_nodelay (gboolean set)
469 {
470 no_slang_delay = set;
471 }
472
473
474
475 int
476 tty_baudrate (void)
477 {
478 return SLang_TT_Baud_Rate;
479 }
480
481
482
483 int
484 tty_lowlevel_getch (void)
485 {
486 int c;
487
488 if (no_slang_delay && (SLang_input_pending (0) == 0))
489 return -1;
490
491 c = SLang_getkey ();
492 if (c == SLANG_GETKEY_ERROR)
493 {
494 fprintf (stderr,
495 "SLang_getkey returned SLANG_GETKEY_ERROR\n"
496 "Assuming EOF on stdin and exiting\n");
497 exit (EXIT_FAILURE);
498 }
499
500 return c;
501 }
502
503
504
505 int
506 tty_reset_screen (void)
507 {
508 SLsmg_reset_smg ();
509 slsmg_active = FALSE;
510 return 0;
511 }
512
513
514
515 void
516 tty_touch_screen (void)
517 {
518 SLsmg_touch_lines (0, LINES);
519 }
520
521
522
523 void
524 tty_gotoyx (int y, int x)
525 {
526 SLsmg_gotorc (y, x);
527 }
528
529
530
531 void
532 tty_getyx (int *py, int *px)
533 {
534 *py = SLsmg_get_row ();
535 *px = SLsmg_get_column ();
536 }
537
538
539
540 void
541 tty_draw_hline (int y, int x, int ch, int len)
542 {
543 int x1;
544
545 if (y < 0 || y >= LINES || x >= COLS)
546 return;
547
548 x1 = x;
549
550 if (x < 0)
551 {
552 len += x;
553 if (len <= 0)
554 return;
555 x = 0;
556 }
557
558 if (ch == ACS_HLINE)
559 ch = mc_tty_frm[MC_TTY_FRM_HORIZ];
560 if (ch == 0)
561 ch = ACS_HLINE;
562
563 SLsmg_gotorc (y, x);
564
565 if (ch == ACS_HLINE)
566 SLsmg_draw_hline (len);
567 else
568 while (len-- != 0)
569 tty_print_char (ch);
570
571 SLsmg_gotorc (y, x1);
572 }
573
574
575
576 void
577 tty_draw_vline (int y, int x, int ch, int len)
578 {
579 int y1;
580
581 if (x < 0 || x >= COLS || y >= LINES)
582 return;
583
584 y1 = y;
585
586 if (y < 0)
587 {
588 len += y;
589 if (len <= 0)
590 return;
591 y = 0;
592 }
593
594 if (ch == ACS_VLINE)
595 ch = mc_tty_frm[MC_TTY_FRM_VERT];
596 if (ch == 0)
597 ch = ACS_VLINE;
598
599 SLsmg_gotorc (y, x);
600
601 if (ch == ACS_VLINE)
602 SLsmg_draw_vline (len);
603 else
604 {
605 int pos = 0;
606
607 while (len-- != 0)
608 {
609 SLsmg_gotorc (y + pos, x);
610 tty_print_char (ch);
611 pos++;
612 }
613 }
614
615 SLsmg_gotorc (y1, x);
616 }
617
618
619
620 void
621 tty_fill_region (int y, int x, int rows, int cols, unsigned char ch)
622 {
623 SLsmg_fill_region (y, x, rows, cols, ch);
624 }
625
626
627
628 void
629 tty_colorize_area (int y, int x, int rows, int cols, int color)
630 {
631 if (use_colors)
632 SLsmg_set_color_in_region (color, y, x, rows, cols);
633 }
634
635
636
637 void
638 tty_set_alt_charset (gboolean alt_charset)
639 {
640 SLsmg_set_char_set ((int) alt_charset);
641 }
642
643
644
645 void
646 tty_display_8bit (gboolean what)
647 {
648 SLsmg_Display_Eight_Bit = what ? 128 : 160;
649 }
650
651
652
653 void
654 tty_print_char (int c)
655 {
656 SLsmg_write_char ((SLwchar_Type) ((unsigned int) c));
657 }
658
659
660
661 void
662 tty_print_alt_char (int c, gboolean single)
663 {
664 #define DRAW(x, y) \
665 (x == y) ? SLsmg_draw_object (SLsmg_get_row (), SLsmg_get_column (), x) \
666 : SLsmg_write_char ((unsigned int) y)
667 switch (c)
668 {
669 case ACS_VLINE:
670 DRAW (c, mc_tty_frm[single ? MC_TTY_FRM_VERT : MC_TTY_FRM_DVERT]);
671 break;
672 case ACS_HLINE:
673 DRAW (c, mc_tty_frm[single ? MC_TTY_FRM_HORIZ : MC_TTY_FRM_DHORIZ]);
674 break;
675 case ACS_LTEE:
676 DRAW (c, mc_tty_frm[single ? MC_TTY_FRM_LEFTMIDDLE : MC_TTY_FRM_DLEFTMIDDLE]);
677 break;
678 case ACS_RTEE:
679 DRAW (c, mc_tty_frm[single ? MC_TTY_FRM_RIGHTMIDDLE : MC_TTY_FRM_DRIGHTMIDDLE]);
680 break;
681 case ACS_TTEE:
682 DRAW (c, mc_tty_frm[single ? MC_TTY_FRM_TOPMIDDLE : MC_TTY_FRM_DTOPMIDDLE]);
683 break;
684 case ACS_BTEE:
685 DRAW (c, mc_tty_frm[single ? MC_TTY_FRM_BOTTOMMIDDLE : MC_TTY_FRM_DBOTTOMMIDDLE]);
686 break;
687 case ACS_ULCORNER:
688 DRAW (c, mc_tty_frm[single ? MC_TTY_FRM_LEFTTOP : MC_TTY_FRM_DLEFTTOP]);
689 break;
690 case ACS_LLCORNER:
691 DRAW (c, mc_tty_frm[single ? MC_TTY_FRM_LEFTBOTTOM : MC_TTY_FRM_DLEFTBOTTOM]);
692 break;
693 case ACS_URCORNER:
694 DRAW (c, mc_tty_frm[single ? MC_TTY_FRM_RIGHTTOP : MC_TTY_FRM_DRIGHTTOP]);
695 break;
696 case ACS_LRCORNER:
697 DRAW (c, mc_tty_frm[single ? MC_TTY_FRM_RIGHTBOTTOM : MC_TTY_FRM_DRIGHTBOTTOM]);
698 break;
699 case ACS_PLUS:
700 DRAW (c, mc_tty_frm[MC_TTY_FRM_CROSS]);
701 break;
702 default:
703 SLsmg_write_char ((unsigned int) c);
704 }
705 #undef DRAW
706 }
707
708
709
710 void
711 tty_print_anychar (int c)
712 {
713 if (c > 255)
714 {
715 char str[UTF8_CHAR_LEN + 1];
716 int res;
717
718 res = g_unichar_to_utf8 (c, str);
719 if (res == 0)
720 {
721 str[0] = '.';
722 str[1] = '\0';
723 }
724 else
725 {
726 str[res] = '\0';
727 }
728 SLsmg_write_string ((char *) str_term_form (str));
729 }
730 else
731 {
732 if (!is_printable (c))
733 c = '.';
734 SLsmg_write_char ((SLwchar_Type) ((unsigned int) c));
735 }
736 }
737
738
739
740 void
741 tty_print_string (const char *s)
742 {
743 SLsmg_write_string ((char *) str_term_form (s));
744 }
745
746
747
748 void
749 tty_printf (const char *fmt, ...)
750 {
751 va_list args;
752
753 va_start (args, fmt);
754 SLsmg_vprintf ((char *) fmt, args);
755 va_end (args);
756 }
757
758
759
760 char *
761 tty_tgetstr (const char *cap)
762 {
763 return SLtt_tgetstr ((SLFUTURE_CONST char *) cap);
764 }
765
766
767
768 void
769 tty_refresh (void)
770 {
771 SLsmg_refresh ();
772 }
773
774
775
776 void
777 tty_beep (void)
778 {
779 SLtt_beep ();
780 }
781
782