1 /* Slang interface to the Midnight Commander
2 This emulates some features of ncurses on top of slang
4 Copyright (C) 1995, 1996 The Free Software Foundation.
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
35 #include "mouse.h" /* Gpm_Event is required in key.h */
36 #include "key.h" /* define_sequence */
37 #include "main.h" /* extern: force_colors */
38 #include "win.h" /* do_exit_ca_mode */
43 /* Taken from S-Lang's slutty.c */
44 #ifdef ultrix /* Ultrix gets _POSIX_VDISABLE wrong! */
45 # define NULL_VALUE -1
47 # ifdef _POSIX_VDISABLE
48 # define NULL_VALUE _POSIX_VDISABLE
50 # define NULL_VALUE 255
54 /* Taken from S-Lang's sldisply.c file */
56 # define tgetstr(a,b) SLtt_tgetstr (a)
58 extern char *tgetstr(char *, char **);
65 /* Various saved termios settings that we control here */
66 static struct termios boot_mode
;
67 static struct termios new_mode
;
69 /* Set if we get an interrupt */
70 static int slinterrupt
;
72 /* Controls whether we should wait for input in getch */
73 static int no_slang_delay
;
75 /* {{{ Copied from ../slang/slgetkey.c, removed the DEC_8Bit_HACK, */
76 extern unsigned int SLang_Input_Buffer_Len
;
77 extern unsigned char SLang_Input_Buffer
[];
78 #if SLANG_VERSION >= 10000
79 extern unsigned int _SLsys_getkey (void);
80 extern int _SLsys_input_pending (int);
82 extern unsigned int SLsys_getkey (void);
83 extern int SLsys_input_pending (int);
86 /* Forward declarations */
87 static void load_terminfo_keys (void);
89 static unsigned int SLang_getkey2 (void)
94 if (SLang_Input_Buffer_Len
)
96 ch
= (unsigned int) *SLang_Input_Buffer
;
97 SLang_Input_Buffer_Len
--;
98 imax
= SLang_Input_Buffer_Len
;
100 memcpy ((char *) SLang_Input_Buffer
,
101 (char *) (SLang_Input_Buffer
+ 1), imax
);
104 #if SLANG_VERSION >= 10000
105 else return(_SLsys_getkey ());
107 else return(SLsys_getkey());
111 static int SLang_input_pending2 (int tsecs
)
116 if (SLang_Input_Buffer_Len
) return (int) SLang_Input_Buffer_Len
;
117 #if SLANG_VERSION >= 10000
118 n
= _SLsys_input_pending (tsecs
);
120 n
= SLsys_input_pending (tsecs
);
122 if (n
<= 0) return 0;
124 i
= SLang_getkey2 ();
125 if (i
== SLANG_GETKEY_ERROR
)
126 return 0; /* don't put crippled error codes into the input buffer */
127 c
= (unsigned char)i
;
128 SLang_ungetkey_string (&c
, 1);
135 slang_intr (int signo
)
141 enable_interrupt_key(void)
143 struct sigaction act
;
145 act
.sa_handler
= slang_intr
;
146 sigemptyset (&act
.sa_mask
);
148 sigaction (SIGINT
, &act
, NULL
);
153 disable_interrupt_key(void)
155 struct sigaction act
;
157 act
.sa_handler
= SIG_IGN
;
159 sigemptyset (&act
.sa_mask
);
160 sigaction (SIGINT
, &act
, NULL
);
173 /* Only done the first time */
177 extern int SLtt_Blink_Mode
;
178 extern int SLtt_Has_Alt_Charset
;
179 extern int force_ugly_line_drawing
;
180 struct sigaction act
, oact
;
182 SLtt_get_terminfo ();
185 * If the terminal in not in terminfo but begins with a well-known
186 * string such as "linux" or "xterm" S-Lang will go on, but the
187 * terminal size and several other variables won't be initialized
188 * (as of S-Lang 1.4.4). Detect it and abort. Also detect extremely
189 * small, large and negative screen dimensions.
191 if ((COLS
< 10) || (LINES
< 5) || (COLS
> 1024) || (LINES
> 1024)) {
193 _("Screen size %dx%d is not supported.\n"
194 "Check the TERM environment variable.\n"),
199 tcgetattr (fileno (stdin
), &boot_mode
);
200 /* 255 = ignore abort char; XCTRL('g') for abort char = ^g */
201 SLang_init_tty (XCTRL('c'), 1, 0);
203 /* If SLang uses fileno(stderr) for terminal input MC will hang
204 if we call SLang_getkey between calls to open_error_pipe and
205 close_error_pipe, e.g. when we do a growing view of an gzipped
207 if (SLang_TT_Read_FD
== fileno (stderr
))
208 SLang_TT_Read_FD
= fileno (stdin
);
210 if (force_ugly_line_drawing
)
211 SLtt_Has_Alt_Charset
= 0;
212 if (tcgetattr (SLang_TT_Read_FD
, &new_mode
) == 0) {
214 new_mode
.c_cc
[VDSUSP
] = NULL_VALUE
; /* to ignore ^Y */
217 new_mode
.c_cc
[VLNEXT
] = NULL_VALUE
; /* to ignore ^V */
219 tcsetattr (SLang_TT_Read_FD
, TCSADRAIN
, &new_mode
);
222 load_terminfo_keys ();
223 act
.sa_handler
= slang_intr
;
224 sigemptyset (&act
.sa_mask
);
225 act
.sa_flags
= SA_RESTART
;
226 sigaction (SIGINT
, &act
, &oact
);
231 slang_set_raw_mode (void)
233 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &new_mode
);
236 /* Done each time we come back from done mode */
238 slang_prog_mode (void)
240 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &new_mode
);
242 SLsmg_touch_lines (0, LINES
);
245 /* Called each time we want to shutdown slang screen manager */
247 slang_shell_mode (void)
249 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &boot_mode
);
253 slang_shutdown (void)
260 dealloc_color_pairs ();
262 /* Load the op capability to reset the colors to those that were
263 * active when the program was started up
265 op_cap
= SLtt_tgetstr ("op");
267 fprintf (stdout
, "%s", op_cap
);
272 /* HP Terminals have capabilities (pfkey, pfloc, pfx) to program function keys.
273 elm 2.4pl15 invoked with the -K option utilizes these softkeys and the
274 consequence is that function keys don't work in MC sometimes.
275 Unfortunately I don't now the one and only escape sequence to turn off
276 softkeys (elm uses three different capabilities to turn on softkeys and two
277 capabilities to turn them off).
278 Among other things elm uses the pair we already use in slang_keypad. That's
279 the reason why I call slang_reset_softkeys from slang_keypad. In lack of
280 something better the softkeys are programmed to their defaults from the
281 termcap/terminfo database.
282 The escape sequence to program the softkeys is taken from elm and it is
283 hardcoded because neither slang nor ncurses 4.1 know how to 'printf' this
288 slang_reset_softkeys (void)
292 static const char display
[] = " ";
295 for ( key
= 1; key
< 9; key
++ ) {
296 g_snprintf (tmp
, sizeof (tmp
), "k%d", key
);
297 send
= (char *) SLtt_tgetstr (tmp
);
299 g_snprintf(tmp
, sizeof (tmp
), "\033&f%dk%dd%dL%s%s", key
,
300 sizeof (display
) - 1, strlen(send
), display
, send
);
301 SLtt_write_string (tmp
);
306 /* keypad routines */
308 slang_keypad (int set
)
311 extern int reset_hp_softkeys
;
313 keypad_string
= (char *) SLtt_tgetstr (set
? "ks" : "ke");
315 SLtt_write_string (keypad_string
);
316 if (set
&& reset_hp_softkeys
)
317 slang_reset_softkeys ();
321 set_slang_delay (int v
)
327 hline (int ch
, int len
)
331 last_x
= SLsmg_get_column ();
332 last_y
= SLsmg_get_row ();
337 if (ch
== ACS_HLINE
){
338 SLsmg_draw_hline (len
);
343 move (last_y
, last_x
);
347 vline (int character
, int len
)
350 SLsmg_draw_vline (len
);
352 int last_x
, last_y
, pos
= 0;
354 last_x
= SLsmg_get_column ();
355 last_y
= SLsmg_get_row ();
358 move (last_y
+ pos
++, last_x
);
361 move (last_x
, last_y
);
365 int has_colors (void)
367 char *terminal
= getenv ("TERM");
368 char *cts
= color_terminal_string
, *s
;
372 SLtt_Use_Ansi_Colors
= 1;
373 if (NULL
!= getenv ("COLORTERM"))
374 SLtt_Use_Ansi_Colors
= 1;
376 /* We want to allow overwriding */
377 if (!disable_colors
){
378 /* check color_terminal_string */
383 while (*cts
== ' ' || *cts
== '\t') cts
++;
388 while (*cts
&& *cts
!= ',')
393 if (i
&& i
== strlen(terminal
) && strncmp(s
, terminal
, i
) == 0)
394 SLtt_Use_Ansi_Colors
= 1;
396 if (*cts
== ',') cts
++;
401 /* Setup emulated colors */
402 if (SLtt_Use_Ansi_Colors
){
404 mc_init_pair (A_REVERSE
, "black", "white");
405 mc_init_pair (A_BOLD
, "white", "black");
407 mc_init_pair (A_REVERSE
, "black", "lightgray");
408 mc_init_pair (A_BOLD
, "white", "black");
409 mc_init_pair (A_BOLD_REVERSE
, "white", "lightgray");
412 SLtt_set_mono (A_BOLD
, NULL
, SLTT_BOLD_MASK
);
413 SLtt_set_mono (A_REVERSE
, NULL
, SLTT_REV_MASK
);
414 SLtt_set_mono (A_BOLD
|A_REVERSE
, NULL
, SLTT_BOLD_MASK
| SLTT_REV_MASK
);
416 return SLtt_Use_Ansi_Colors
;
422 if (!SLtt_Use_Ansi_Colors
){
423 SLsmg_set_color (color
);
429 SLsmg_set_color (A_BOLD
);
431 SLsmg_set_color ((color
& (~A_BOLD
)) + 8);
435 if (color
== A_REVERSE
)
436 SLsmg_set_color (A_REVERSE
);
438 SLsmg_set_color (color
);
441 /* This table describes which capabilities we want and which values we
444 static const struct {
477 { KEY_BACKSPACE
, "kb" },
484 do_define_key (int code
, char *strcap
)
488 seq
= (char *) SLtt_tgetstr (strcap
);
490 define_sequence (code
, seq
, MCKEY_NOACTION
);
494 load_terminfo_keys (void)
498 for (i
= 0; key_table
[i
].key_code
; i
++)
499 do_define_key (key_table
[i
].key_code
, key_table
[i
].key_name
);
506 if (SLang_input_pending2 (0) == 0)
509 c
= SLang_getkey2 ();
510 if (c
== SLANG_GETKEY_ERROR
) {
511 fprintf (stderr
, "SLang_getkey returned SLANG_GETKEY_ERROR\n"
512 "Assuming EOF on stdin and exiting\n");
520 /* Non slang builds do not understand got_interrupt */
521 int got_interrupt (void)
525 #endif /* HAVE_SLANG */
530 if (!we_are_background
)