2 Interface to the terminal controlling library.
5 Copyright (C) 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
8 Andrew Borodin <aborodin@vmail.ru>, 2009.
10 This file is part of the Midnight Commander.
12 The Midnight Commander is free software; you can redistribute it
13 and/or modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version.
17 The Midnight Commander is distributed in the hope that it will be
18 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
19 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
29 * \brief Source: S-Lang-based tty layer of Midnight Commander
38 #include <sys/types.h> /* size_t */
42 #include "lib/global.h"
43 #include "lib/strutil.h" /* str_term_form */
45 #include "tty-internal.h" /* slow_tty */
47 #include "color-slang.h"
48 #include "color-internal.h"
49 #include "mouse.h" /* Gpm_Event is required in key.h */
50 #include "key.h" /* define_sequence */
54 /*** global variables **************************************************/
56 extern int reset_hp_softkeys
;
58 /*** file scope macro definitions **************************************/
64 #ifndef SLTT_MAX_SCREEN_COLS
65 #define SLTT_MAX_SCREEN_COLS 512
68 #ifndef SLTT_MAX_SCREEN_ROWS
69 #define SLTT_MAX_SCREEN_ROWS 512
72 /*** file scope type declarations **************************************/
74 /*** file scope variables **********************************************/
76 /* Various saved termios settings that we control here */
77 static struct termios boot_mode
;
78 static struct termios new_mode
;
80 /* Controls whether we should wait for input in tty_lowlevel_getch */
81 static gboolean no_slang_delay
;
83 /* This table describes which capabilities we want and which values we
103 { KEY_F (10), "k;" },
104 { KEY_F (11), "F1" },
105 { KEY_F (12), "F2" },
106 { KEY_F (13), "F3" },
107 { KEY_F (14), "F4" },
108 { KEY_F (15), "F5" },
109 { KEY_F (16), "F6" },
110 { KEY_F (17), "F7" },
111 { KEY_F (18), "F8" },
112 { KEY_F (19), "F9" },
113 { KEY_F (20), "FA" },
122 { KEY_BACKSPACE
, "kb" },
129 /*** file scope functions **********************************************/
131 /* HP Terminals have capabilities (pfkey, pfloc, pfx) to program function keys.
132 elm 2.4pl15 invoked with the -K option utilizes these softkeys and the
133 consequence is that function keys don't work in MC sometimes...
134 Unfortunately I don't now the one and only escape sequence to turn off.
135 softkeys (elm uses three different capabilities to turn on softkeys and two.
136 capabilities to turn them off)..
137 Among other things elm uses the pair we already use in slang_keypad. That's.
138 the reason why I call slang_reset_softkeys from slang_keypad. In lack of
139 something better the softkeys are programmed to their defaults from the
140 termcap/terminfo database.
141 The escape sequence to program the softkeys is taken from elm and it is.
142 hardcoded because neither slang nor ncurses 4.1 know how to 'printf' this.
147 slang_reset_softkeys (void)
151 static const char display
[] = " ";
154 for (key
= 1; key
< 9; key
++)
156 g_snprintf (tmp
, sizeof (tmp
), "k%d", key
);
157 send
= (char *) SLtt_tgetstr (tmp
);
160 g_snprintf (tmp
, sizeof (tmp
), "\033&f%dk%dd%dL%s%s", key
,
161 (int) (sizeof (display
) - 1), (int) strlen (send
), display
, send
);
162 SLtt_write_string (tmp
);
168 do_define_key (int code
, const char *strcap
)
172 seq
= (char *) SLtt_tgetstr ((char *) strcap
);
174 define_sequence (code
, seq
, MCKEY_NOACTION
);
178 load_terminfo_keys (void)
182 for (i
= 0; key_table
[i
].key_code
; i
++)
183 do_define_key (key_table
[i
].key_code
, key_table
[i
].key_name
);
186 /* --------------------------------------------------------------------------------------------- */
187 /*** public functions **************************************************/
188 /* --------------------------------------------------------------------------------------------- */
191 mc_tty_normalize_lines_char (const char *str
)
196 struct mc_tty_lines_struct
200 } const lines_codes
[] = {
201 {"\342\224\214", SLSMG_ULCORN_CHAR
},
202 {"\342\224\220", SLSMG_URCORN_CHAR
},
203 {"\342\224\224", SLSMG_LLCORN_CHAR
},
204 {"\342\224\230", SLSMG_LRCORN_CHAR
},
205 {"\342\224\234", SLSMG_LTEE_CHAR
},
206 {"\342\224\244", SLSMG_RTEE_CHAR
},
207 {"\342\224\254", SLSMG_UTEE_CHAR
},
208 {"\342\224\264", SLSMG_DTEE_CHAR
},
209 {"\342\224\200", SLSMG_HLINE_CHAR
},
210 {"\342\224\202", SLSMG_VLINE_CHAR
},
211 {"\342\224\274", SLSMG_PLUS_CHAR
},
219 for (res
= 0; lines_codes
[res
].line
; res
++)
221 if (strcmp (str
, lines_codes
[res
].line
) == 0)
222 return lines_codes
[res
].line_code
;
225 str2
= mc_tty_normalize_from_utf8 (str
);
226 res
= g_utf8_get_char_validated (str2
, -1);
229 res
= (unsigned char) str2
[0];
235 /* --------------------------------------------------------------------------------------------- */
237 tty_init (gboolean slow
, gboolean ugly_lines
)
240 ugly_line_drawing
= ugly_lines
;
242 SLtt_get_terminfo ();
245 * If the terminal in not in terminfo but begins with a well-known
246 * string such as "linux" or "xterm" S-Lang will go on, but the
247 * terminal size and several other variables won't be initialized
248 * (as of S-Lang 1.4.4). Detect it and abort. Also detect extremely
249 * small, large and negative screen dimensions.
251 if ((COLS
< 10) || (LINES
< 5)
252 || (COLS
> SLTT_MAX_SCREEN_COLS
) || (LINES
> SLTT_MAX_SCREEN_ROWS
))
255 _("Screen size %dx%d is not supported.\n"
256 "Check the TERM environment variable.\n"), COLS
, LINES
);
260 tcgetattr (fileno (stdin
), &boot_mode
);
261 /* 255 = ignore abort char; XCTRL('g') for abort char = ^g */
262 SLang_init_tty (XCTRL ('g'), 1, 0);
265 SLtt_Has_Alt_Charset
= 0;
267 /* If SLang uses fileno(stderr) for terminal input MC will hang
268 if we call SLang_getkey between calls to open_error_pipe and
269 close_error_pipe, e.g. when we do a growing view of an gzipped
271 if (SLang_TT_Read_FD
== fileno (stderr
))
272 SLang_TT_Read_FD
= fileno (stdin
);
274 if (tcgetattr (SLang_TT_Read_FD
, &new_mode
) == 0)
277 new_mode
.c_cc
[VDSUSP
] = NULL_VALUE
; /* to ignore ^Y */
280 new_mode
.c_cc
[VLNEXT
] = NULL_VALUE
; /* to ignore ^V */
282 tcsetattr (SLang_TT_Read_FD
, TCSADRAIN
, &new_mode
);
285 tty_reset_prog_mode ();
286 load_terminfo_keys ();
289 tty_start_interrupt_key ();
291 /* It's the small part from the previous init_key() */
292 init_key_input_fd ();
306 tty_reset_shell_mode ();
310 /* Load the op capability to reset the colors to those that were
311 * active when the program was started up
313 op_cap
= SLtt_tgetstr ((char *) "op");
316 fputs (op_cap
, stdout
);
321 /* Done each time we come back from done mode */
323 tty_reset_prog_mode (void)
325 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &new_mode
);
327 SLsmg_touch_lines (0, LINES
);
330 /* Called each time we want to shutdown slang screen manager */
332 tty_reset_shell_mode (void)
334 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &boot_mode
);
340 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &new_mode
);
344 tty_noraw_mode (void)
354 tty_flush_input (void)
360 tty_keypad (gboolean set
)
364 keypad_string
= (char *) SLtt_tgetstr ((char *) (set
? "ks" : "ke"));
365 if (keypad_string
!= NULL
)
366 SLtt_write_string (keypad_string
);
367 if (set
&& reset_hp_softkeys
)
368 slang_reset_softkeys ();
372 tty_nodelay (gboolean set
)
374 no_slang_delay
= set
;
380 return SLang_TT_Baud_Rate
;
384 tty_lowlevel_getch (void)
388 if (no_slang_delay
&& (SLang_input_pending (0) == 0))
392 if (c
== SLANG_GETKEY_ERROR
)
395 "SLang_getkey returned SLANG_GETKEY_ERROR\n"
396 "Assuming EOF on stdin and exiting\n");
404 tty_reset_screen (void)
411 tty_touch_screen (void)
413 SLsmg_touch_lines (0, LINES
);
417 tty_gotoyx (int y
, int x
)
423 tty_getyx (int *py
, int *px
)
425 *py
= SLsmg_get_row ();
426 *px
= SLsmg_get_column ();
429 /* if x < 0 or y < 0, draw line staring from current position */
431 tty_draw_hline (int y
, int x
, int ch
, int len
)
434 ch
= mc_tty_frm
[MC_TTY_FRM_HORIZ
];
436 if ((y
< 0) || (x
< 0))
438 y
= SLsmg_get_row ();
439 x
= SLsmg_get_column ();
448 SLsmg_draw_hline (len
);
456 /* if x < 0 or y < 0, draw line staring from current position */
458 tty_draw_vline (int y
, int x
, int ch
, int len
)
461 ch
= mc_tty_frm
[MC_TTY_FRM_VERT
];
463 if ((y
< 0) || (x
< 0))
465 y
= SLsmg_get_row ();
466 x
= SLsmg_get_column ();
475 SLsmg_draw_vline (len
);
482 SLsmg_gotorc (y
+ pos
, x
);
492 tty_fill_region (int y
, int x
, int rows
, int cols
, unsigned char ch
)
494 SLsmg_fill_region (y
, x
, rows
, cols
, ch
);
498 tty_set_alt_charset (gboolean alt_charset
)
500 SLsmg_set_char_set ((int) alt_charset
);
504 tty_display_8bit (gboolean what
)
506 SLsmg_Display_Eight_Bit
= what
? 128 : 160;
510 tty_print_char (int c
)
512 SLsmg_write_char ((SLwchar_Type
) ((unsigned int) c
));
516 tty_print_alt_char (int c
, gboolean single
)
518 #define DRAW(x, y) (x == y) \
519 ? SLsmg_draw_object (SLsmg_get_row(), SLsmg_get_column(), x) \
520 : SLsmg_write_char ((unsigned int) y)
524 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_VERT
: MC_TTY_FRM_DVERT
]);
527 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_HORIZ
: MC_TTY_FRM_DHORIZ
]);
530 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_LEFTMIDDLE
: MC_TTY_FRM_DLEFTMIDDLE
]);
533 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_RIGHTMIDDLE
: MC_TTY_FRM_DRIGHTMIDDLE
]);
536 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_LEFTTOP
: MC_TTY_FRM_DLEFTTOP
]);
539 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_LEFTBOTTOM
: MC_TTY_FRM_DLEFTBOTTOM
]);
542 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_RIGHTTOP
: MC_TTY_FRM_DRIGHTTOP
]);
545 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_RIGHTBOTTOM
: MC_TTY_FRM_DRIGHTBOTTOM
]);
548 DRAW (c
, mc_tty_frm
[MC_TTY_FRM_CROSS
]);
551 SLsmg_write_char ((unsigned int) c
);
557 tty_print_anychar (int c
)
563 int res
= g_unichar_to_utf8 (c
, str
);
573 SLsmg_write_string ((char *) str_term_form (str
));
577 SLsmg_write_char ((SLwchar_Type
) ((unsigned int) c
));
582 tty_print_string (const char *s
)
584 SLsmg_write_string ((char *) str_term_form (s
));
588 tty_printf (const char *fmt
, ...)
592 va_start (args
, fmt
);
593 SLsmg_vprintf ((char *) fmt
, args
);
598 tty_tgetstr (const char *cap
)
600 return SLtt_tgetstr ((char *) cap
);
610 tty_setup_sigwinch (void (*handler
) (int))
613 struct sigaction act
, oact
;
614 act
.sa_handler
= handler
;
615 sigemptyset (&act
.sa_mask
);
618 act
.sa_flags
|= SA_RESTART
;
619 #endif /* SA_RESTART */
620 sigaction (SIGWINCH
, &act
, &oact
);
621 #endif /* SIGWINCH */