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 "../../src/global.h"
44 #include "../../src/tty/tty-internal.h" /* slow_tty */
45 #include "../../src/tty/tty.h"
46 #include "../../src/tty/color-slang.h"
47 #include "../../src/tty/color-internal.h"
48 #include "../../src/tty/mouse.h" /* Gpm_Event is required in key.h */
49 #include "../../src/tty/key.h" /* define_sequence */
50 #include "../../src/tty/win.h"
52 #include "../../src/strutil.h" /* str_term_form */
54 /*** global variables **************************************************/
55 extern int reset_hp_softkeys
;
57 /*** file scope macro definitions **************************************/
59 /* Taken from S-Lang's slutty.c */
60 #ifdef ultrix /* Ultrix gets _POSIX_VDISABLE wrong! */
61 # define NULL_VALUE -1
63 # ifdef _POSIX_VDISABLE
64 # define NULL_VALUE _POSIX_VDISABLE
66 # define NULL_VALUE 255
74 #ifndef SLTT_MAX_SCREEN_COLS
75 #define SLTT_MAX_SCREEN_COLS 512
78 #ifndef SLTT_MAX_SCREEN_ROWS
79 #define SLTT_MAX_SCREEN_ROWS 512
83 /*** file scope type declarations **************************************/
85 /*** file scope variables **********************************************/
87 /* Various saved termios settings that we control here */
88 static struct termios boot_mode
;
89 static struct termios new_mode
;
91 /* Controls whether we should wait for input in tty_lowlevel_getch */
92 static gboolean no_slang_delay
;
94 /* This table describes which capabilities we want and which values we
131 KEY_BACKSPACE
, "kb"}, {
137 /*** file scope functions **********************************************/
139 /* HP Terminals have capabilities (pfkey, pfloc, pfx) to program function keys.
140 elm 2.4pl15 invoked with the -K option utilizes these softkeys and the
141 consequence is that function keys don't work in MC sometimes...
142 Unfortunately I don't now the one and only escape sequence to turn off.
143 softkeys (elm uses three different capabilities to turn on softkeys and two.
144 capabilities to turn them off)..
145 Among other things elm uses the pair we already use in slang_keypad. That's.
146 the reason why I call slang_reset_softkeys from slang_keypad. In lack of
147 something better the softkeys are programmed to their defaults from the
148 termcap/terminfo database.
149 The escape sequence to program the softkeys is taken from elm and it is.
150 hardcoded because neither slang nor ncurses 4.1 know how to 'printf' this.
155 slang_reset_softkeys (void)
159 static const char display
[] = " ";
162 for (key
= 1; key
< 9; key
++) {
163 g_snprintf (tmp
, sizeof (tmp
), "k%d", key
);
164 send
= (char *) SLtt_tgetstr (tmp
);
166 g_snprintf (tmp
, sizeof (tmp
), "\033&f%dk%dd%dL%s%s", key
,
167 (int) (sizeof (display
) - 1), (int) strlen (send
), display
, send
);
168 SLtt_write_string (tmp
);
174 do_define_key (int code
, const char *strcap
)
178 seq
= (char *) SLtt_tgetstr ((char *) strcap
);
180 define_sequence (code
, seq
, MCKEY_NOACTION
);
184 load_terminfo_keys (void)
188 for (i
= 0; key_table
[i
].key_code
; i
++)
189 do_define_key (key_table
[i
].key_code
, key_table
[i
].key_name
);
192 /* --------------------------------------------------------------------------------------------- */
193 /*** public functions **************************************************/
194 /* --------------------------------------------------------------------------------------------- */
197 mc_tty_normalize_lines_char (const char *str
)
202 struct mc_tty_lines_struct
{
205 } const lines_codes
[] = {
206 {"\342\224\214", SLSMG_ULCORN_CHAR
},
207 {"\342\224\220", SLSMG_URCORN_CHAR
},
208 {"\342\224\224", SLSMG_LLCORN_CHAR
},
209 {"\342\224\230", SLSMG_LRCORN_CHAR
},
210 {"\342\224\234", SLSMG_LTEE_CHAR
},
211 {"\342\224\244", SLSMG_RTEE_CHAR
},
212 {"\342\224\254", SLSMG_UTEE_CHAR
},
213 {"\342\224\264", SLSMG_DTEE_CHAR
},
214 {"\342\224\200", SLSMG_HLINE_CHAR
},
215 {"\342\224\202", SLSMG_VLINE_CHAR
},
216 {"\342\224\274", SLSMG_PLUS_CHAR
},
224 for (res
= 0; lines_codes
[res
].line
; res
++) {
225 if (strcmp (str
, lines_codes
[res
].line
) == 0)
226 return lines_codes
[res
].line_code
;
229 str2
= mc_tty_normalize_from_utf8 (str
);
230 res
= g_utf8_get_char_validated (str2
, -1);
233 res
= (unsigned char) str2
[0];
239 /* --------------------------------------------------------------------------------------------- */
241 tty_init (gboolean slow
, gboolean ugly_lines
)
244 ugly_line_drawing
= ugly_lines
;
246 SLtt_get_terminfo ();
249 * If the terminal in not in terminfo but begins with a well-known
250 * string such as "linux" or "xterm" S-Lang will go on, but the
251 * terminal size and several other variables won't be initialized
252 * (as of S-Lang 1.4.4). Detect it and abort. Also detect extremely
253 * small, large and negative screen dimensions.
255 if ((COLS
< 10) || (LINES
< 5)
256 || (COLS
> SLTT_MAX_SCREEN_COLS
) || (LINES
> SLTT_MAX_SCREEN_ROWS
)) {
258 _("Screen size %dx%d is not supported.\n"
259 "Check the TERM environment variable.\n"), COLS
, LINES
);
263 tcgetattr (fileno (stdin
), &boot_mode
);
264 /* 255 = ignore abort char; XCTRL('g') for abort char = ^g */
265 SLang_init_tty (XCTRL ('g'), 1, 0);
268 SLtt_Has_Alt_Charset
= 0;
270 /* If SLang uses fileno(stderr) for terminal input MC will hang
271 if we call SLang_getkey between calls to open_error_pipe and
272 close_error_pipe, e.g. when we do a growing view of an gzipped
274 if (SLang_TT_Read_FD
== fileno (stderr
))
275 SLang_TT_Read_FD
= fileno (stdin
);
277 if (tcgetattr (SLang_TT_Read_FD
, &new_mode
) == 0) {
279 new_mode
.c_cc
[VDSUSP
] = NULL_VALUE
; /* to ignore ^Y */
282 new_mode
.c_cc
[VLNEXT
] = NULL_VALUE
; /* to ignore ^V */
284 tcsetattr (SLang_TT_Read_FD
, TCSADRAIN
, &new_mode
);
287 tty_reset_prog_mode ();
288 load_terminfo_keys ();
291 tty_start_interrupt_key ();
293 /* It's the small part from the previous init_key() */
294 init_key_input_fd ();
308 tty_reset_shell_mode ();
312 /* Load the op capability to reset the colors to those that were
313 * active when the program was started up
315 op_cap
= SLtt_tgetstr ((char *) "op");
316 if (op_cap
!= NULL
) {
317 fputs (op_cap
, stdout
);
322 /* Done each time we come back from done mode */
324 tty_reset_prog_mode (void)
326 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &new_mode
);
328 SLsmg_touch_lines (0, LINES
);
331 /* Called each time we want to shutdown slang screen manager */
333 tty_reset_shell_mode (void)
335 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &boot_mode
);
341 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &new_mode
);
345 tty_noraw_mode (void)
355 tty_flush_input (void)
361 tty_keypad (gboolean set
)
365 keypad_string
= (char *) SLtt_tgetstr ((char *) (set
? "ks" : "ke"));
366 if (keypad_string
!= NULL
)
367 SLtt_write_string (keypad_string
);
368 if (set
&& reset_hp_softkeys
)
369 slang_reset_softkeys ();
373 tty_nodelay (gboolean set
)
375 no_slang_delay
= set
;
381 return SLang_TT_Baud_Rate
;
385 tty_lowlevel_getch (void)
389 if (no_slang_delay
&& (SLang_input_pending (0) == 0))
393 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_ugly_frm
[MC_TTY_FRM_thinhoriz
];
436 if ((y
< 0) || (x
< 0)) {
437 y
= SLsmg_get_row ();
438 x
= SLsmg_get_column ();
446 SLsmg_draw_hline (len
);
454 /* if x < 0 or y < 0, draw line staring from current position */
456 tty_draw_vline (int y
, int x
, int ch
, int len
)
459 ch
= mc_tty_ugly_frm
[MC_TTY_FRM_thinvert
];
461 if ((y
< 0) || (x
< 0)) {
462 y
= SLsmg_get_row ();
463 x
= SLsmg_get_column ();
471 SLsmg_draw_vline (len
);
476 SLsmg_gotorc (y
+ pos
, x
);
486 tty_fill_region (int y
, int x
, int rows
, int cols
, unsigned char ch
)
488 SLsmg_fill_region (y
, x
, rows
, cols
, ch
);
492 tty_set_alt_charset (gboolean alt_charset
)
494 SLsmg_set_char_set ((int) alt_charset
);
498 tty_display_8bit (gboolean what
)
500 SLsmg_Display_Eight_Bit
= what
? 128 : 160;
504 tty_print_char (int c
)
506 SLsmg_write_char ((SLwchar_Type
) ((unsigned int) c
));
510 tty_print_alt_char (int c
)
512 #define DRAW(x, y) (x == y) \
513 ? SLsmg_draw_object (SLsmg_get_row(), SLsmg_get_column(), x) \
514 : SLsmg_write_char ((unsigned int) y)
517 DRAW (c
, mc_tty_ugly_frm
[MC_TTY_FRM_thinvert
]);
520 DRAW (c
, mc_tty_ugly_frm
[MC_TTY_FRM_thinhoriz
]);
523 DRAW (c
, mc_tty_ugly_frm
[MC_TTY_FRM_leftmiddle
]);
526 DRAW (c
, mc_tty_ugly_frm
[MC_TTY_FRM_rightmiddle
]);
529 DRAW (c
, mc_tty_ugly_frm
[MC_TTY_FRM_lefttop
]);
532 DRAW (c
, mc_tty_ugly_frm
[MC_TTY_FRM_leftbottom
]);
535 DRAW (c
, mc_tty_ugly_frm
[MC_TTY_FRM_righttop
]);
538 DRAW (c
, mc_tty_ugly_frm
[MC_TTY_FRM_rightbottom
]);
541 DRAW (c
, mc_tty_ugly_frm
[MC_TTY_FRM_centermiddle
]);
544 SLsmg_write_char ((unsigned int) c
);
550 tty_print_anychar (int c
)
555 int res
= g_unichar_to_utf8 (c
, str
);
562 SLsmg_write_string ((char *) str_term_form (str
));
564 SLsmg_write_char ((SLwchar_Type
) ((unsigned int) c
));
569 tty_print_string (const char *s
)
571 SLsmg_write_string ((char *) str_term_form (s
));
575 tty_printf (const char *fmt
, ...)
579 va_start (args
, fmt
);
580 SLsmg_vprintf ((char *) fmt
, args
);
585 tty_tgetstr (const char *cap
)
587 return SLtt_tgetstr ((char *) cap
);
597 tty_setup_sigwinch (void (*handler
) (int))
600 struct sigaction act
, oact
;
601 act
.sa_handler
= handler
;
602 sigemptyset (&act
.sa_mask
);
605 act
.sa_flags
|= SA_RESTART
;
606 #endif /* SA_RESTART */
607 sigaction (SIGWINCH
, &act
, &oact
);
608 #endif /* SIGWINCH */