1 /* Slang interface to the Midnight Commander
2 This emulates some features of ncurses on top of slang
4 Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
5 2005, 2007 Free Software Foundation, Inc.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
25 * \brief Source: slang %interface to the Midnight Commander
26 * \warning This module will be removed soon
44 #include "mouse.h" /* Gpm_Event is required in key.h */
45 #include "key.h" /* define_sequence */
46 #include "main.h" /* extern: force_colors */
47 #include "win.h" /* do_exit_ca_mode */
49 #include "background.h" /* we_are_background */
53 /* Taken from S-Lang's slutty.c */
54 #ifdef ultrix /* Ultrix gets _POSIX_VDISABLE wrong! */
55 # define NULL_VALUE -1
57 # ifdef _POSIX_VDISABLE
58 # define NULL_VALUE _POSIX_VDISABLE
60 # define NULL_VALUE 255
68 /* Various saved termios settings that we control here */
69 static struct termios boot_mode
;
70 static struct termios new_mode
;
72 /* Controls whether we should wait for input in getch */
73 static int no_slang_delay
;
75 /* Forward declarations */
76 static void load_terminfo_keys (void);
78 #ifndef HAVE_SLANG_PRIVATE
79 /* Private interfaces have been stripped, so we cannot use them */
80 #define SLang_getkey2() SLang_getkey()
81 #define SLang_input_pending2(s) SLang_input_pending(s)
83 /* Copied from ../slang/slgetkey.c, removed the DEC_8Bit_HACK. */
84 extern unsigned char SLang_Input_Buffer
[];
85 #if SLANG_VERSION >= 10000
86 extern unsigned int _SLsys_getkey (void);
87 extern int _SLsys_input_pending (int);
89 extern unsigned int SLsys_getkey (void);
90 extern int SLsys_input_pending (int);
93 static unsigned int SLang_getkey2 (void)
98 if (SLang_Input_Buffer_Len
)
100 ch
= (unsigned int) *SLang_Input_Buffer
;
101 SLang_Input_Buffer_Len
--;
102 imax
= SLang_Input_Buffer_Len
;
104 memmove ((char *) SLang_Input_Buffer
,
105 (char *) (SLang_Input_Buffer
+ 1), imax
);
108 #if SLANG_VERSION >= 10000
109 else return(_SLsys_getkey ());
111 else return(SLsys_getkey());
115 static int SLang_input_pending2 (int tsecs
)
120 if (SLang_Input_Buffer_Len
) return (int) SLang_Input_Buffer_Len
;
121 #if SLANG_VERSION >= 10000
122 n
= _SLsys_input_pending (tsecs
);
124 n
= SLsys_input_pending (tsecs
);
126 if (n
<= 0) return 0;
128 i
= SLang_getkey2 ();
129 if (i
== SLANG_GETKEY_ERROR
)
130 return 0; /* don't put crippled error codes into the input buffer */
131 c
= (unsigned char)i
;
132 SLang_ungetkey_string (&c
, 1);
136 #endif /* HAVE_SLANG_PRIVATE */
138 /* Only done the first time */
142 SLtt_get_terminfo ();
145 * If the terminal in not in terminfo but begins with a well-known
146 * string such as "linux" or "xterm" S-Lang will go on, but the
147 * terminal size and several other variables won't be initialized
148 * (as of S-Lang 1.4.4). Detect it and abort. Also detect extremely
149 * small, large and negative screen dimensions.
151 if ((COLS
< 10) || (LINES
< 5) ||
152 (SLang_Version
< 10407 && (COLS
> 255 || LINES
> 255)) ||
153 (SLang_Version
>= 10407 && (COLS
> 512 || LINES
> 512))) {
156 _("Screen size %dx%d is not supported.\n"
157 "Check the TERM environment variable.\n"),
162 tcgetattr (fileno (stdin
), &boot_mode
);
163 /* 255 = ignore abort char; XCTRL('g') for abort char = ^g */
164 SLang_init_tty (XCTRL('c'), 1, 0);
166 /* If SLang uses fileno(stderr) for terminal input MC will hang
167 if we call SLang_getkey between calls to open_error_pipe and
168 close_error_pipe, e.g. when we do a growing view of an gzipped
170 if (SLang_TT_Read_FD
== fileno (stderr
))
171 SLang_TT_Read_FD
= fileno (stdin
);
173 if (force_ugly_line_drawing
)
174 SLtt_Has_Alt_Charset
= 0;
175 if (tcgetattr (SLang_TT_Read_FD
, &new_mode
) == 0) {
177 new_mode
.c_cc
[VDSUSP
] = NULL_VALUE
; /* to ignore ^Y */
180 new_mode
.c_cc
[VLNEXT
] = NULL_VALUE
; /* to ignore ^V */
182 tcsetattr (SLang_TT_Read_FD
, TCSADRAIN
, &new_mode
);
185 load_terminfo_keys ();
190 slang_set_raw_mode (void)
192 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &new_mode
);
195 /* Done each time we come back from done mode */
197 slang_prog_mode (void)
199 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &new_mode
);
201 SLsmg_touch_lines (0, LINES
);
204 /* Called each time we want to shutdown slang screen manager */
206 slang_shell_mode (void)
208 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &boot_mode
);
212 slang_shutdown (void)
220 /* Load the op capability to reset the colors to those that were
221 * active when the program was started up
223 op_cap
= SLtt_tgetstr ("op");
225 fprintf (stdout
, "%s", op_cap
);
230 /* HP Terminals have capabilities (pfkey, pfloc, pfx) to program function keys.
231 elm 2.4pl15 invoked with the -K option utilizes these softkeys and the
232 consequence is that function keys don't work in MC sometimes.
233 Unfortunately I don't now the one and only escape sequence to turn off
234 softkeys (elm uses three different capabilities to turn on softkeys and two
235 capabilities to turn them off).
236 Among other things elm uses the pair we already use in slang_keypad. That's
237 the reason why I call slang_reset_softkeys from slang_keypad. In lack of
238 something better the softkeys are programmed to their defaults from the
239 termcap/terminfo database.
240 The escape sequence to program the softkeys is taken from elm and it is
241 hardcoded because neither slang nor ncurses 4.1 know how to 'printf' this
246 slang_reset_softkeys (void)
250 static const char display
[] = " ";
253 for (key
= 1; key
< 9; key
++) {
254 g_snprintf (tmp
, sizeof (tmp
), "k%d", key
);
255 send
= (char *) SLtt_tgetstr (tmp
);
257 g_snprintf (tmp
, sizeof (tmp
), "\033&f%dk%dd%dL%s%s", key
,
258 (int) (sizeof (display
) - 1), (int) strlen (send
),
260 SLtt_write_string (tmp
);
265 /* keypad routines */
267 slang_keypad (int set
)
270 extern int reset_hp_softkeys
;
272 keypad_string
= (char *) SLtt_tgetstr (set
? "ks" : "ke");
274 SLtt_write_string (keypad_string
);
275 if (set
&& reset_hp_softkeys
)
276 slang_reset_softkeys ();
280 set_slang_delay (int v
)
286 hline (int ch
, int len
)
290 last_x
= SLsmg_get_column ();
291 last_y
= SLsmg_get_row ();
296 if (ch
== ACS_HLINE
){
297 SLsmg_draw_hline (len
);
302 move (last_y
, last_x
);
306 vline (int character
, int len
)
309 SLsmg_draw_vline (len
);
311 int last_x
, last_y
, pos
= 0;
313 last_x
= SLsmg_get_column ();
314 last_y
= SLsmg_get_row ();
317 move (last_y
+ pos
++, last_x
);
320 move (last_x
, last_y
);
324 int has_colors (void)
326 const char *terminal
= getenv ("TERM");
327 char *cts
= color_terminal_string
, *s
;
331 SLtt_Use_Ansi_Colors
= 1;
332 if (NULL
!= getenv ("COLORTERM"))
333 SLtt_Use_Ansi_Colors
= 1;
335 /* We want to allow overwriding */
336 if (!disable_colors
){
337 /* check color_terminal_string */
342 while (*cts
== ' ' || *cts
== '\t') cts
++;
347 while (*cts
&& *cts
!= ',')
352 if (i
&& i
== strlen(terminal
) && strncmp(s
, terminal
, i
) == 0)
353 SLtt_Use_Ansi_Colors
= 1;
355 if (*cts
== ',') cts
++;
360 /* Setup emulated colors */
361 if (SLtt_Use_Ansi_Colors
){
363 mc_init_pair (A_REVERSE
, "black", "white");
364 mc_init_pair (A_BOLD
, "white", "black");
366 mc_init_pair (A_REVERSE
, "black", "lightgray");
367 mc_init_pair (A_BOLD
, "white", "black");
368 mc_init_pair (A_BOLD_REVERSE
, "white", "lightgray");
371 SLtt_set_mono (A_BOLD
, NULL
, SLTT_BOLD_MASK
);
372 SLtt_set_mono (A_REVERSE
, NULL
, SLTT_REV_MASK
);
373 SLtt_set_mono (A_BOLD
|A_REVERSE
, NULL
, SLTT_BOLD_MASK
| SLTT_REV_MASK
);
375 return SLtt_Use_Ansi_Colors
;
381 if (!SLtt_Use_Ansi_Colors
){
382 SLsmg_set_color (color
);
388 SLsmg_set_color (A_BOLD
);
390 SLsmg_set_color ((color
& (~A_BOLD
)) + 8);
394 if (color
== A_REVERSE
)
395 SLsmg_set_color (A_REVERSE
);
397 SLsmg_set_color (color
);
400 /* This table describes which capabilities we want and which values we
403 static const struct {
405 const char *key_name
;
436 { KEY_BACKSPACE
, "kb" },
443 do_define_key (int code
, const char *strcap
)
447 seq
= (char *) SLtt_tgetstr ((char*) strcap
);
449 define_sequence (code
, seq
, MCKEY_NOACTION
);
453 load_terminfo_keys (void)
457 for (i
= 0; key_table
[i
].key_code
; i
++)
458 do_define_key (key_table
[i
].key_code
, key_table
[i
].key_name
);
466 if (SLang_input_pending2 (0) == 0)
469 c
= SLang_getkey2 ();
470 if (c
== SLANG_GETKEY_ERROR
) {
472 "SLang_getkey returned SLANG_GETKEY_ERROR\n"
473 "Assuming EOF on stdin and exiting\n");
478 #endif /* HAVE_SLANG */
483 #ifdef WITH_BACKGROUND
484 if (!we_are_background
)
485 #endif /* WITH_BACKGROUND */