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