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 ();
143 #if SLANG_VERSION >= 20000
147 * If the terminal in not in terminfo but begins with a well-known
148 * string such as "linux" or "xterm" S-Lang will go on, but the
149 * terminal size and several other variables won't be initialized
150 * (as of S-Lang 1.4.4). Detect it and abort. Also detect extremely
151 * small, large and negative screen dimensions.
153 if ((COLS
< 10) || (LINES
< 5) ||
154 (SLang_Version
< 10407 && (COLS
> 255 || LINES
> 255)) ||
155 (SLang_Version
>= 10407 && (COLS
> 512 || LINES
> 512))) {
158 _("Screen size %dx%d is not supported.\n"
159 "Check the TERM environment variable.\n"),
164 tcgetattr (fileno (stdin
), &boot_mode
);
165 /* 255 = ignore abort char; XCTRL('g') for abort char = ^g */
166 SLang_init_tty (XCTRL('c'), 1, 0);
168 /* If SLang uses fileno(stderr) for terminal input MC will hang
169 if we call SLang_getkey between calls to open_error_pipe and
170 close_error_pipe, e.g. when we do a growing view of an gzipped
172 if (SLang_TT_Read_FD
== fileno (stderr
))
173 SLang_TT_Read_FD
= fileno (stdin
);
175 if (force_ugly_line_drawing
)
176 SLtt_Has_Alt_Charset
= 0;
177 if (tcgetattr (SLang_TT_Read_FD
, &new_mode
) == 0) {
179 new_mode
.c_cc
[VDSUSP
] = NULL_VALUE
; /* to ignore ^Y */
182 new_mode
.c_cc
[VLNEXT
] = NULL_VALUE
; /* to ignore ^V */
184 tcsetattr (SLang_TT_Read_FD
, TCSADRAIN
, &new_mode
);
187 load_terminfo_keys ();
192 slang_set_raw_mode (void)
194 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &new_mode
);
197 /* Done each time we come back from done mode */
199 slang_prog_mode (void)
201 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &new_mode
);
203 SLsmg_touch_lines (0, LINES
);
206 /* Called each time we want to shutdown slang screen manager */
208 slang_shell_mode (void)
210 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &boot_mode
);
214 slang_shutdown (void)
222 /* Load the op capability to reset the colors to those that were
223 * active when the program was started up
225 op_cap
= SLtt_tgetstr ("op");
227 fprintf (stdout
, "%s", op_cap
);
232 /* HP Terminals have capabilities (pfkey, pfloc, pfx) to program function keys.
233 elm 2.4pl15 invoked with the -K option utilizes these softkeys and the
234 consequence is that function keys don't work in MC sometimes.
235 Unfortunately I don't now the one and only escape sequence to turn off
236 softkeys (elm uses three different capabilities to turn on softkeys and two
237 capabilities to turn them off).
238 Among other things elm uses the pair we already use in slang_keypad. That's
239 the reason why I call slang_reset_softkeys from slang_keypad. In lack of
240 something better the softkeys are programmed to their defaults from the
241 termcap/terminfo database.
242 The escape sequence to program the softkeys is taken from elm and it is
243 hardcoded because neither slang nor ncurses 4.1 know how to 'printf' this
248 slang_reset_softkeys (void)
252 static const char display
[] = " ";
255 for (key
= 1; key
< 9; key
++) {
256 g_snprintf (tmp
, sizeof (tmp
), "k%d", key
);
257 send
= (char *) SLtt_tgetstr (tmp
);
259 g_snprintf (tmp
, sizeof (tmp
), "\033&f%dk%dd%dL%s%s", key
,
260 (int) (sizeof (display
) - 1), (int) strlen (send
),
262 SLtt_write_string (tmp
);
267 /* keypad routines */
269 slang_keypad (int set
)
272 extern int reset_hp_softkeys
;
274 keypad_string
= (char *) SLtt_tgetstr (set
? "ks" : "ke");
276 SLtt_write_string (keypad_string
);
277 if (set
&& reset_hp_softkeys
)
278 slang_reset_softkeys ();
282 set_slang_delay (int v
)
288 hline (int ch
, int len
)
292 last_x
= SLsmg_get_column ();
293 last_y
= SLsmg_get_row ();
298 if (ch
== ACS_HLINE
){
299 SLsmg_draw_hline (len
);
304 move (last_y
, last_x
);
308 vline (int character
, int len
)
312 SLsmg_draw_vline (len
);
314 int last_x
, last_y
, pos
= 0;
316 last_x
= SLsmg_get_column ();
317 last_y
= SLsmg_get_row ();
320 move (last_y
+ pos
++, last_x
);
323 move (last_x
, last_y
);
327 int has_colors (void)
329 const char *terminal
= getenv ("TERM");
330 char *cts
= color_terminal_string
, *s
;
334 SLtt_Use_Ansi_Colors
= 1;
335 if (NULL
!= getenv ("COLORTERM"))
336 SLtt_Use_Ansi_Colors
= 1;
338 /* We want to allow overwriding */
339 if (!disable_colors
){
340 /* check color_terminal_string */
345 while (*cts
== ' ' || *cts
== '\t') cts
++;
350 while (*cts
&& *cts
!= ',')
355 if (i
&& i
== strlen(terminal
) && strncmp(s
, terminal
, i
) == 0)
356 SLtt_Use_Ansi_Colors
= 1;
358 if (*cts
== ',') cts
++;
363 /* Setup emulated colors */
364 if (SLtt_Use_Ansi_Colors
){
366 mc_init_pair (A_REVERSE
, "black", "white");
367 mc_init_pair (A_BOLD
, "white", "black");
369 mc_init_pair (A_REVERSE
, "black", "lightgray");
370 mc_init_pair (A_BOLD
, "white", "black");
371 mc_init_pair (A_BOLD_REVERSE
, "white", "lightgray");
374 SLtt_set_mono (A_BOLD
, NULL
, SLTT_BOLD_MASK
);
375 SLtt_set_mono (A_REVERSE
, NULL
, SLTT_REV_MASK
);
376 SLtt_set_mono (A_BOLD
|A_REVERSE
, NULL
, SLTT_BOLD_MASK
| SLTT_REV_MASK
);
378 return SLtt_Use_Ansi_Colors
;
384 if (!SLtt_Use_Ansi_Colors
){
385 SLsmg_set_color (color
);
391 SLsmg_set_color (A_BOLD
);
393 SLsmg_set_color ((color
& (~A_BOLD
)) + 8);
397 if (color
== A_REVERSE
)
398 SLsmg_set_color (A_REVERSE
);
400 SLsmg_set_color (color
);
403 /* This table describes which capabilities we want and which values we
406 static const struct {
408 const char *key_name
;
439 { KEY_BACKSPACE
, "kb" },
446 do_define_key (int code
, const char *strcap
)
450 seq
= (char *) SLtt_tgetstr ((char*) strcap
);
452 define_sequence (code
, seq
, MCKEY_NOACTION
);
456 load_terminfo_keys (void)
460 for (i
= 0; key_table
[i
].key_code
; i
++)
461 do_define_key (key_table
[i
].key_code
, key_table
[i
].key_name
);
469 if (SLang_input_pending2 (0) == 0)
472 c
= SLang_getkey2 ();
473 if (c
== SLANG_GETKEY_ERROR
) {
475 "SLang_getkey returned SLANG_GETKEY_ERROR\n"
476 "Assuming EOF on stdin and exiting\n");
481 #endif /* HAVE_SLANG */
486 #ifdef WITH_BACKGROUND
487 if (!we_are_background
)
488 #endif /* WITH_BACKGROUND */