3554bc507321b23d5951d8d0ee4728a41913fe2b
2 Interface to the terminal controlling library.
5 Copyright (C) 2005, 2006, 2007, 2009, 2010, 2011
6 The Free Software Foundation, Inc.
9 Andrew Borodin <aborodin@vmail.ru>, 2009
10 Egmont Koblinger <egmont@gmail.com>, 2010
12 This file is part of the Midnight Commander.
14 The Midnight Commander is free software: you can redistribute it
15 and/or modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation, either version 3 of the License,
17 or (at your option) any later version.
19 The Midnight Commander is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program. If not, see <http://www.gnu.org/licenses/>.
29 * \brief Source: S-Lang-based tty layer of Midnight Commander
37 #include <sys/types.h> /* size_t */
40 #ifdef HAVE_SYS_IOCTL_H
41 #include <sys/ioctl.h>
45 #include "lib/global.h"
46 #include "lib/strutil.h" /* str_term_form */
47 #include "lib/util.h" /* is_printable() */
49 #include "tty-internal.h" /* mc_tty_normalize_from_utf8() */
52 #include "color-slang.h"
53 #include "color-internal.h"
54 #include "mouse.h" /* Gpm_Event is required in key.h */
55 #include "key.h" /* define_sequence */
59 /*** global variables ****************************************************************************/
61 extern int reset_hp_softkeys
;
63 /*** file scope macro definitions ****************************************************************/
69 #ifndef SLTT_MAX_SCREEN_COLS
70 #define SLTT_MAX_SCREEN_COLS 512
73 #ifndef SLTT_MAX_SCREEN_ROWS
74 #define SLTT_MAX_SCREEN_ROWS 512
77 /*** file scope type declarations ****************************************************************/
79 /*** file scope variables ************************************************************************/
81 /* Various saved termios settings that we control here */
82 static struct termios boot_mode
;
83 static struct termios new_mode
;
85 /* Controls whether we should wait for input in tty_lowlevel_getch */
86 static gboolean no_slang_delay
;
88 /* This table describes which capabilities we want and which values we
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" },
127 { KEY_BACKSPACE
, "kb" },
134 /*** file scope functions ************************************************************************/
135 /* --------------------------------------------------------------------------------------------- */
138 tty_setup_sigwinch (void (*handler
) (int))
141 struct sigaction act
, oact
;
142 act
.sa_handler
= handler
;
143 sigemptyset (&act
.sa_mask
);
146 act
.sa_flags
|= SA_RESTART
;
147 #endif /* SA_RESTART */
148 sigaction (SIGWINCH
, &act
, &oact
);
149 #endif /* SIGWINCH */
152 /* --------------------------------------------------------------------------------------------- */
155 sigwinch_handler (int dummy
)
159 mc_global
.tty
.winch_flag
= TRUE
;
162 /* --------------------------------------------------------------------------------------------- */
164 /* HP Terminals have capabilities (pfkey, pfloc, pfx) to program function keys.
165 elm 2.4pl15 invoked with the -K option utilizes these softkeys and the
166 consequence is that function keys don't work in MC sometimes...
167 Unfortunately I don't now the one and only escape sequence to turn off.
168 softkeys (elm uses three different capabilities to turn on softkeys and two.
169 capabilities to turn them off)..
170 Among other things elm uses the pair we already use in slang_keypad. That's.
171 the reason why I call slang_reset_softkeys from slang_keypad. In lack of
172 something better the softkeys are programmed to their defaults from the
173 termcap/terminfo database.
174 The escape sequence to program the softkeys is taken from elm and it is.
175 hardcoded because neither slang nor ncurses 4.1 know how to 'printf' this.
180 slang_reset_softkeys (void)
184 static const char display
[] = " ";
187 for (key
= 1; key
< 9; key
++)
189 g_snprintf (tmp
, sizeof (tmp
), "k%d", key
);
190 send
= (char *) SLtt_tgetstr (tmp
);
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
);
200 /* --------------------------------------------------------------------------------------------- */
203 do_define_key (int code
, const char *strcap
)
207 seq
= (char *) SLtt_tgetstr ((char *) strcap
);
209 define_sequence (code
, seq
, MCKEY_NOACTION
);
212 /* --------------------------------------------------------------------------------------------- */
215 load_terminfo_keys (void)
219 for (i
= 0; key_table
[i
].key_code
; i
++)
220 do_define_key (key_table
[i
].key_code
, key_table
[i
].key_name
);
223 /* --------------------------------------------------------------------------------------------- */
224 /*** public functions ****************************************************************************/
225 /* --------------------------------------------------------------------------------------------- */
228 mc_tty_normalize_lines_char (const char *str
)
233 struct mc_tty_lines_struct
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
},
256 for (res
= 0; lines_codes
[res
].line
; res
++)
258 if (strcmp (str
, lines_codes
[res
].line
) == 0)
259 return lines_codes
[res
].line_code
;
262 str2
= mc_tty_normalize_from_utf8 (str
);
263 res
= g_utf8_get_char_validated (str2
, -1);
266 res
= (unsigned char) str2
[0];
272 /* --------------------------------------------------------------------------------------------- */
275 tty_init (gboolean mouse_enable
, gboolean is_xterm
)
277 SLtt_Ignore_Beep
= 1;
279 SLutf8_enable (-1); /* has to be called first before any of the other functions. */
280 SLtt_get_terminfo ();
282 * If the terminal in not in terminfo but begins with a well-known
283 * string such as "linux" or "xterm" S-Lang will go on, but the
284 * terminal size and several other variables won't be initialized
285 * (as of S-Lang 1.4.4). Detect it and abort. Also detect extremely
286 * small, large and negative screen dimensions.
288 if ((COLS
< 10) || (LINES
< 5)
289 || (COLS
> SLTT_MAX_SCREEN_COLS
) || (LINES
> SLTT_MAX_SCREEN_ROWS
))
292 _("Screen size %dx%d is not supported.\n"
293 "Check the TERM environment variable.\n"), COLS
, LINES
);
297 tcgetattr (fileno (stdin
), &boot_mode
);
298 /* 255 = ignore abort char; XCTRL('g') for abort char = ^g */
299 SLang_init_tty (XCTRL ('g'), 1, 0);
301 if (mc_global
.tty
.ugly_line_drawing
)
302 SLtt_Has_Alt_Charset
= 0;
304 /* If SLang uses fileno(stderr) for terminal input MC will hang
305 if we call SLang_getkey between calls to open_error_pipe and
306 close_error_pipe, e.g. when we do a growing view of an gzipped
308 if (SLang_TT_Read_FD
== fileno (stderr
))
309 SLang_TT_Read_FD
= fileno (stdin
);
311 if (tcgetattr (SLang_TT_Read_FD
, &new_mode
) == 0)
314 new_mode
.c_cc
[VDSUSP
] = NULL_VALUE
; /* to ignore ^Y */
317 new_mode
.c_cc
[VLNEXT
] = NULL_VALUE
; /* to ignore ^V */
319 tcsetattr (SLang_TT_Read_FD
, TCSADRAIN
, &new_mode
);
322 tty_reset_prog_mode ();
323 load_terminfo_keys ();
325 SLtt_Blink_Mode
= tty_use_256colors ()? 1 : 0;
327 tty_start_interrupt_key ();
329 /* It's the small part from the previous init_key() */
330 init_key_input_fd ();
332 /* For 8-bit locales, NCurses handles 154 (0x9A) symbol properly, while S-Lang
333 * requires SLsmg_Display_Eight_Bit >= 154 (OR manual filtering if xterm display
334 * detected - but checking TERM would fail under screen, OR running xterm
335 * with allowC1Printable).
337 tty_display_8bit (FALSE
);
341 use_mouse_p
= MOUSE_DISABLED
;
342 tty_init_xterm_support (is_xterm
); /* do it before do_enter_ca_mode() call */
348 tty_setup_sigwinch (sigwinch_handler
);
351 /* --------------------------------------------------------------------------------------------- */
359 tty_reset_shell_mode ();
366 /* Load the op capability to reset the colors to those that were
367 * active when the program was started up
369 op_cap
= SLtt_tgetstr ((char *) "op");
372 fputs (op_cap
, stdout
);
377 /* --------------------------------------------------------------------------------------------- */
380 tty_change_screen_size (void)
382 SLtt_get_screen_size ();
390 /* --------------------------------------------------------------------------------------------- */
391 /* Done each time we come back from done mode */
394 tty_reset_prog_mode (void)
396 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &new_mode
);
398 SLsmg_touch_lines (0, LINES
);
401 /* --------------------------------------------------------------------------------------------- */
402 /* Called each time we want to shutdown slang screen manager */
405 tty_reset_shell_mode (void)
407 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &boot_mode
);
410 /* --------------------------------------------------------------------------------------------- */
415 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &new_mode
);
418 /* --------------------------------------------------------------------------------------------- */
421 tty_noraw_mode (void)
425 /* --------------------------------------------------------------------------------------------- */
432 /* --------------------------------------------------------------------------------------------- */
435 tty_flush_input (void)
440 /* --------------------------------------------------------------------------------------------- */
443 tty_keypad (gboolean set
)
447 keypad_string
= (char *) SLtt_tgetstr ((char *) (set
? "ks" : "ke"));
448 if (keypad_string
!= NULL
)
449 SLtt_write_string (keypad_string
);
450 if (set
&& reset_hp_softkeys
)
451 slang_reset_softkeys ();
454 /* --------------------------------------------------------------------------------------------- */
457 tty_nodelay (gboolean set
)
459 no_slang_delay
= set
;
462 /* --------------------------------------------------------------------------------------------- */
467 return SLang_TT_Baud_Rate
;
470 /* --------------------------------------------------------------------------------------------- */
473 tty_lowlevel_getch (void)
477 if (no_slang_delay
&& (SLang_input_pending (0) == 0))
481 if (c
== SLANG_GETKEY_ERROR
)
484 "SLang_getkey returned SLANG_GETKEY_ERROR\n"
485 "Assuming EOF on stdin and exiting\n");
492 /* --------------------------------------------------------------------------------------------- */
495 tty_reset_screen (void)
501 /* --------------------------------------------------------------------------------------------- */
504 tty_touch_screen (void)
506 SLsmg_touch_lines (0, LINES
);
509 /* --------------------------------------------------------------------------------------------- */
512 tty_gotoyx (int y
, int x
)
517 /* --------------------------------------------------------------------------------------------- */
520 tty_getyx (int *py
, int *px
)
522 *py
= SLsmg_get_row ();
523 *px
= SLsmg_get_column ();
526 /* --------------------------------------------------------------------------------------------- */
529 tty_draw_hline (int y
, int x
, int ch
, int len
)
533 if (y
< 0 || y
>= LINES
|| x
>= COLS
)
547 ch
= mc_tty_frm
[MC_TTY_FRM_HORIZ
];
554 SLsmg_draw_hline (len
);
559 SLsmg_gotorc (y
, x1
);
562 /* --------------------------------------------------------------------------------------------- */
565 tty_draw_vline (int y
, int x
, int ch
, int len
)
569 if (x
< 0 || x
>= COLS
|| y
>= LINES
)
583 ch
= mc_tty_frm
[MC_TTY_FRM_VERT
];
590 SLsmg_draw_vline (len
);
597 SLsmg_gotorc (y
+ pos
, x
);
603 SLsmg_gotorc (y1
, x
);
606 /* --------------------------------------------------------------------------------------------- */
609 tty_fill_region (int y
, int x
, int rows
, int cols
, unsigned char ch
)
611 SLsmg_fill_region (y
, x
, rows
, cols
, ch
);
614 /* --------------------------------------------------------------------------------------------- */
617 tty_set_alt_charset (gboolean alt_charset
)
619 SLsmg_set_char_set ((int) alt_charset
);
622 /* --------------------------------------------------------------------------------------------- */
625 tty_display_8bit (gboolean what
)
627 SLsmg_Display_Eight_Bit
= what
? 128 : 160;
630 /* --------------------------------------------------------------------------------------------- */
633 tty_print_char (int c
)
635 SLsmg_write_char ((SLwchar_Type
) ((unsigned int) c
));
638 /* --------------------------------------------------------------------------------------------- */
641 tty_print_alt_char (int c
, gboolean single
)
643 #define DRAW(x, y) (x == y) \
644 ? SLsmg_draw_object (SLsmg_get_row(), SLsmg_get_column(), x) \
645 : SLsmg_write_char ((unsigned int) y)
649 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_VERT
: MC_TTY_FRM_DVERT
]);
652 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_HORIZ
: MC_TTY_FRM_DHORIZ
]);
655 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_LEFTMIDDLE
: MC_TTY_FRM_DLEFTMIDDLE
]);
658 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_RIGHTMIDDLE
: MC_TTY_FRM_DRIGHTMIDDLE
]);
661 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_LEFTTOP
: MC_TTY_FRM_DLEFTTOP
]);
664 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_LEFTBOTTOM
: MC_TTY_FRM_DLEFTBOTTOM
]);
667 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_RIGHTTOP
: MC_TTY_FRM_DRIGHTTOP
]);
670 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_RIGHTBOTTOM
: MC_TTY_FRM_DRIGHTBOTTOM
]);
673 DRAW (c
, mc_tty_frm
[MC_TTY_FRM_CROSS
]);
676 SLsmg_write_char ((unsigned int) c
);
681 /* --------------------------------------------------------------------------------------------- */
684 tty_print_anychar (int c
)
690 int res
= g_unichar_to_utf8 (c
, str
);
700 SLsmg_write_string ((char *) str_term_form (str
));
704 if (!is_printable (c
))
706 SLsmg_write_char ((SLwchar_Type
) ((unsigned int) c
));
710 /* --------------------------------------------------------------------------------------------- */
713 tty_print_string (const char *s
)
715 SLsmg_write_string ((char *) str_term_form (s
));
718 /* --------------------------------------------------------------------------------------------- */
721 tty_printf (const char *fmt
, ...)
725 va_start (args
, fmt
);
726 SLsmg_vprintf ((char *) fmt
, args
);
730 /* --------------------------------------------------------------------------------------------- */
733 tty_tgetstr (const char *cap
)
735 return SLtt_tgetstr ((char *) cap
);
738 /* --------------------------------------------------------------------------------------------- */
746 /* --------------------------------------------------------------------------------------------- */
754 /* --------------------------------------------------------------------------------------------- */