2 Interface to the terminal controlling library.
5 Copyright (C) 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
8 Andrew Borodin <aborodin@vmail.ru>, 2009
9 Egmont Koblinger <egmont@gmail.com>, 2010
11 This file is part of the Midnight Commander.
13 The Midnight Commander is free software; you can redistribute it
14 and/or modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
18 The Midnight Commander is distributed in the hope that it will be
19 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
20 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
30 * \brief Source: S-Lang-based tty layer of Midnight Commander
39 #include <sys/types.h> /* size_t */
43 #include "lib/global.h"
44 #include "lib/strutil.h" /* str_term_form */
45 #include "lib/util.h" /* is_printable() */
47 #include "tty-internal.h" /* slow_tty */
50 #include "color-slang.h"
51 #include "color-internal.h"
52 #include "mouse.h" /* Gpm_Event is required in key.h */
53 #include "key.h" /* define_sequence */
57 /*** global variables ****************************************************************************/
59 extern int reset_hp_softkeys
;
61 /*** file scope macro definitions ****************************************************************/
67 #ifndef SLTT_MAX_SCREEN_COLS
68 #define SLTT_MAX_SCREEN_COLS 512
71 #ifndef SLTT_MAX_SCREEN_ROWS
72 #define SLTT_MAX_SCREEN_ROWS 512
75 /*** file scope type declarations ****************************************************************/
77 /*** file scope variables ************************************************************************/
79 /* Various saved termios settings that we control here */
80 static struct termios boot_mode
;
81 static struct termios new_mode
;
83 /* Controls whether we should wait for input in tty_lowlevel_getch */
84 static gboolean no_slang_delay
;
86 /* This table describes which capabilities we want and which values we
106 { KEY_F (10), "k;" },
107 { KEY_F (11), "F1" },
108 { KEY_F (12), "F2" },
109 { KEY_F (13), "F3" },
110 { KEY_F (14), "F4" },
111 { KEY_F (15), "F5" },
112 { KEY_F (16), "F6" },
113 { KEY_F (17), "F7" },
114 { KEY_F (18), "F8" },
115 { KEY_F (19), "F9" },
116 { KEY_F (20), "FA" },
125 { KEY_BACKSPACE
, "kb" },
132 /*** file scope functions ************************************************************************/
133 /* --------------------------------------------------------------------------------------------- */
135 /* HP Terminals have capabilities (pfkey, pfloc, pfx) to program function keys.
136 elm 2.4pl15 invoked with the -K option utilizes these softkeys and the
137 consequence is that function keys don't work in MC sometimes...
138 Unfortunately I don't now the one and only escape sequence to turn off.
139 softkeys (elm uses three different capabilities to turn on softkeys and two.
140 capabilities to turn them off)..
141 Among other things elm uses the pair we already use in slang_keypad. That's.
142 the reason why I call slang_reset_softkeys from slang_keypad. In lack of
143 something better the softkeys are programmed to their defaults from the
144 termcap/terminfo database.
145 The escape sequence to program the softkeys is taken from elm and it is.
146 hardcoded because neither slang nor ncurses 4.1 know how to 'printf' this.
151 slang_reset_softkeys (void)
155 static const char display
[] = " ";
158 for (key
= 1; key
< 9; key
++)
160 g_snprintf (tmp
, sizeof (tmp
), "k%d", key
);
161 send
= (char *) SLtt_tgetstr (tmp
);
164 g_snprintf (tmp
, sizeof (tmp
), "\033&f%dk%dd%dL%s%s", key
,
165 (int) (sizeof (display
) - 1), (int) strlen (send
), display
, send
);
166 SLtt_write_string (tmp
);
171 /* --------------------------------------------------------------------------------------------- */
174 do_define_key (int code
, const char *strcap
)
178 seq
= (char *) SLtt_tgetstr ((char *) strcap
);
180 define_sequence (code
, seq
, MCKEY_NOACTION
);
183 /* --------------------------------------------------------------------------------------------- */
186 load_terminfo_keys (void)
190 for (i
= 0; key_table
[i
].key_code
; i
++)
191 do_define_key (key_table
[i
].key_code
, key_table
[i
].key_name
);
194 /* --------------------------------------------------------------------------------------------- */
195 /*** public functions ****************************************************************************/
196 /* --------------------------------------------------------------------------------------------- */
199 mc_tty_normalize_lines_char (const char *str
)
204 struct mc_tty_lines_struct
208 } const lines_codes
[] = {
209 {"\342\224\214", SLSMG_ULCORN_CHAR
},
210 {"\342\224\220", SLSMG_URCORN_CHAR
},
211 {"\342\224\224", SLSMG_LLCORN_CHAR
},
212 {"\342\224\230", SLSMG_LRCORN_CHAR
},
213 {"\342\224\234", SLSMG_LTEE_CHAR
},
214 {"\342\224\244", SLSMG_RTEE_CHAR
},
215 {"\342\224\254", SLSMG_UTEE_CHAR
},
216 {"\342\224\264", SLSMG_DTEE_CHAR
},
217 {"\342\224\200", SLSMG_HLINE_CHAR
},
218 {"\342\224\202", SLSMG_VLINE_CHAR
},
219 {"\342\224\274", SLSMG_PLUS_CHAR
},
227 for (res
= 0; lines_codes
[res
].line
; res
++)
229 if (strcmp (str
, lines_codes
[res
].line
) == 0)
230 return lines_codes
[res
].line_code
;
233 str2
= mc_tty_normalize_from_utf8 (str
);
234 res
= g_utf8_get_char_validated (str2
, -1);
237 res
= (unsigned char) str2
[0];
243 /* --------------------------------------------------------------------------------------------- */
246 tty_init (gboolean slow
, gboolean ugly_lines
)
249 ugly_line_drawing
= ugly_lines
;
251 SLtt_Ignore_Beep
= 1;
253 SLutf8_enable (-1); /* has to be called first before any of the other functions. */
254 SLtt_get_terminfo ();
256 * If the terminal in not in terminfo but begins with a well-known
257 * string such as "linux" or "xterm" S-Lang will go on, but the
258 * terminal size and several other variables won't be initialized
259 * (as of S-Lang 1.4.4). Detect it and abort. Also detect extremely
260 * small, large and negative screen dimensions.
262 if ((COLS
< 10) || (LINES
< 5)
263 || (COLS
> SLTT_MAX_SCREEN_COLS
) || (LINES
> SLTT_MAX_SCREEN_ROWS
))
266 _("Screen size %dx%d is not supported.\n"
267 "Check the TERM environment variable.\n"), COLS
, LINES
);
271 tcgetattr (fileno (stdin
), &boot_mode
);
272 /* 255 = ignore abort char; XCTRL('g') for abort char = ^g */
273 SLang_init_tty (XCTRL ('g'), 1, 0);
276 SLtt_Has_Alt_Charset
= 0;
278 /* If SLang uses fileno(stderr) for terminal input MC will hang
279 if we call SLang_getkey between calls to open_error_pipe and
280 close_error_pipe, e.g. when we do a growing view of an gzipped
282 if (SLang_TT_Read_FD
== fileno (stderr
))
283 SLang_TT_Read_FD
= fileno (stdin
);
285 if (tcgetattr (SLang_TT_Read_FD
, &new_mode
) == 0)
288 new_mode
.c_cc
[VDSUSP
] = NULL_VALUE
; /* to ignore ^Y */
291 new_mode
.c_cc
[VLNEXT
] = NULL_VALUE
; /* to ignore ^V */
293 tcsetattr (SLang_TT_Read_FD
, TCSADRAIN
, &new_mode
);
296 tty_reset_prog_mode ();
297 load_terminfo_keys ();
299 SLtt_Blink_Mode
= tty_use_256colors ()? 1 : 0;
301 tty_start_interrupt_key ();
303 /* It's the small part from the previous init_key() */
304 init_key_input_fd ();
312 /* --------------------------------------------------------------------------------------------- */
320 tty_reset_shell_mode ();
324 /* Load the op capability to reset the colors to those that were
325 * active when the program was started up
327 op_cap
= SLtt_tgetstr ((char *) "op");
330 fputs (op_cap
, stdout
);
335 /* --------------------------------------------------------------------------------------------- */
336 /* Done each time we come back from done mode */
339 tty_reset_prog_mode (void)
341 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &new_mode
);
343 SLsmg_touch_lines (0, LINES
);
346 /* --------------------------------------------------------------------------------------------- */
347 /* Called each time we want to shutdown slang screen manager */
350 tty_reset_shell_mode (void)
352 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &boot_mode
);
355 /* --------------------------------------------------------------------------------------------- */
360 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &new_mode
);
363 /* --------------------------------------------------------------------------------------------- */
366 tty_noraw_mode (void)
370 /* --------------------------------------------------------------------------------------------- */
377 /* --------------------------------------------------------------------------------------------- */
380 tty_flush_input (void)
385 /* --------------------------------------------------------------------------------------------- */
388 tty_keypad (gboolean set
)
392 keypad_string
= (char *) SLtt_tgetstr ((char *) (set
? "ks" : "ke"));
393 if (keypad_string
!= NULL
)
394 SLtt_write_string (keypad_string
);
395 if (set
&& reset_hp_softkeys
)
396 slang_reset_softkeys ();
399 /* --------------------------------------------------------------------------------------------- */
402 tty_nodelay (gboolean set
)
404 no_slang_delay
= set
;
407 /* --------------------------------------------------------------------------------------------- */
412 return SLang_TT_Baud_Rate
;
415 /* --------------------------------------------------------------------------------------------- */
418 tty_lowlevel_getch (void)
422 if (no_slang_delay
&& (SLang_input_pending (0) == 0))
426 if (c
== SLANG_GETKEY_ERROR
)
429 "SLang_getkey returned SLANG_GETKEY_ERROR\n"
430 "Assuming EOF on stdin and exiting\n");
437 /* --------------------------------------------------------------------------------------------- */
440 tty_reset_screen (void)
446 /* --------------------------------------------------------------------------------------------- */
449 tty_touch_screen (void)
451 SLsmg_touch_lines (0, LINES
);
454 /* --------------------------------------------------------------------------------------------- */
457 tty_touch_lines (int start
, int num
)
459 SLsmg_touch_lines (start
, num
);
462 /* --------------------------------------------------------------------------------------------- */
465 tty_gotoyx (int y
, int x
)
470 /* --------------------------------------------------------------------------------------------- */
473 tty_getyx (int *py
, int *px
)
475 *py
= SLsmg_get_row ();
476 *px
= SLsmg_get_column ();
479 /* --------------------------------------------------------------------------------------------- */
480 /* if x < 0 or y < 0, draw line staring from current position */
483 tty_draw_hline (int y
, int x
, int ch
, int len
)
486 ch
= mc_tty_frm
[MC_TTY_FRM_HORIZ
];
488 if ((y
< 0) || (x
< 0))
490 y
= SLsmg_get_row ();
491 x
= SLsmg_get_column ();
500 SLsmg_draw_hline (len
);
508 /* --------------------------------------------------------------------------------------------- */
509 /* if x < 0 or y < 0, draw line staring from current position */
512 tty_draw_vline (int y
, int x
, int ch
, int len
)
515 ch
= mc_tty_frm
[MC_TTY_FRM_VERT
];
517 if ((y
< 0) || (x
< 0))
519 y
= SLsmg_get_row ();
520 x
= SLsmg_get_column ();
529 SLsmg_draw_vline (len
);
536 SLsmg_gotorc (y
+ pos
, x
);
545 /* --------------------------------------------------------------------------------------------- */
548 tty_fill_region (int y
, int x
, int rows
, int cols
, unsigned char ch
)
550 SLsmg_fill_region (y
, x
, rows
, cols
, ch
);
553 /* --------------------------------------------------------------------------------------------- */
556 tty_set_alt_charset (gboolean alt_charset
)
558 SLsmg_set_char_set ((int) alt_charset
);
561 /* --------------------------------------------------------------------------------------------- */
564 tty_display_8bit (gboolean what
)
566 SLsmg_Display_Eight_Bit
= what
? 128 : 160;
569 /* --------------------------------------------------------------------------------------------- */
572 tty_print_char (int c
)
574 SLsmg_write_char ((SLwchar_Type
) ((unsigned int) c
));
577 /* --------------------------------------------------------------------------------------------- */
580 tty_print_alt_char (int c
, gboolean single
)
582 #define DRAW(x, y) (x == y) \
583 ? SLsmg_draw_object (SLsmg_get_row(), SLsmg_get_column(), x) \
584 : SLsmg_write_char ((unsigned int) y)
588 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_VERT
: MC_TTY_FRM_DVERT
]);
591 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_HORIZ
: MC_TTY_FRM_DHORIZ
]);
594 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_LEFTMIDDLE
: MC_TTY_FRM_DLEFTMIDDLE
]);
597 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_RIGHTMIDDLE
: MC_TTY_FRM_DRIGHTMIDDLE
]);
600 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_LEFTTOP
: MC_TTY_FRM_DLEFTTOP
]);
603 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_LEFTBOTTOM
: MC_TTY_FRM_DLEFTBOTTOM
]);
606 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_RIGHTTOP
: MC_TTY_FRM_DRIGHTTOP
]);
609 DRAW (c
, mc_tty_frm
[single
? MC_TTY_FRM_RIGHTBOTTOM
: MC_TTY_FRM_DRIGHTBOTTOM
]);
612 DRAW (c
, mc_tty_frm
[MC_TTY_FRM_CROSS
]);
615 SLsmg_write_char ((unsigned int) c
);
620 /* --------------------------------------------------------------------------------------------- */
623 tty_print_anychar (int c
)
629 int res
= g_unichar_to_utf8 (c
, str
);
639 SLsmg_write_string ((char *) str_term_form (str
));
643 if (!is_printable (c
))
645 SLsmg_write_char ((SLwchar_Type
) ((unsigned int) c
));
649 /* --------------------------------------------------------------------------------------------- */
652 tty_print_string (const char *s
)
654 SLsmg_write_string ((char *) str_term_form (s
));
657 /* --------------------------------------------------------------------------------------------- */
660 tty_printf (const char *fmt
, ...)
664 va_start (args
, fmt
);
665 SLsmg_vprintf ((char *) fmt
, args
);
669 /* --------------------------------------------------------------------------------------------- */
672 tty_tgetstr (const char *cap
)
674 return SLtt_tgetstr ((char *) cap
);
677 /* --------------------------------------------------------------------------------------------- */
685 /* --------------------------------------------------------------------------------------------- */
688 tty_setup_sigwinch (void (*handler
) (int))
691 struct sigaction act
, oact
;
692 act
.sa_handler
= handler
;
693 sigemptyset (&act
.sa_mask
);
696 act
.sa_flags
|= SA_RESTART
;
697 #endif /* SA_RESTART */
698 sigaction (SIGWINCH
, &act
, &oact
);
699 #endif /* SIGWINCH */
702 /* --------------------------------------------------------------------------------------------- */
710 /* --------------------------------------------------------------------------------------------- */