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.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
33 #include "mouse.h" /* Gpm_Event is required in key.h */
34 #include "key.h" /* define_sequence */
35 #include "main.h" /* extern: force_colors */
36 #include "win.h" /* do_exit_ca_mode */
37 #include "background.h" /* we_are_background definition */
42 /* Taken from S-Lang's slutty.c */
43 #ifdef ultrix /* Ultrix gets _POSIX_VDISABLE wrong! */
44 # define NULL_VALUE -1
46 # ifdef _POSIX_VDISABLE
47 # define NULL_VALUE _POSIX_VDISABLE
49 # define NULL_VALUE 255
53 /* Taken from S-Lang's sldisply.c file */
55 # define tgetstr(a,b) SLtt_tgetstr (a)
57 extern char *tgetstr(char *, char **);
64 /* Various saved termios settings that we control here */
65 static struct termios boot_mode
;
66 static struct termios new_mode
;
68 /* Set if we get an interrupt */
69 static int slinterrupt
;
71 /* Controls whether we should wait for input in getch */
72 static int no_slang_delay
;
74 /* {{{ Copied from ../slang/slgetkey.c, removed the DEC_8Bit_HACK, */
75 extern unsigned int SLang_Input_Buffer_Len
;
76 extern unsigned char SLang_Input_Buffer
[];
77 #if SLANG_VERSION >= 10000
78 extern unsigned int _SLsys_getkey (void);
79 extern int _SLsys_input_pending (int);
81 extern unsigned int SLsys_getkey (void);
82 extern int SLsys_input_pending (int);
85 static unsigned int SLang_getkey2 (void)
90 if (SLang_Input_Buffer_Len
)
92 ch
= (unsigned int) *SLang_Input_Buffer
;
93 SLang_Input_Buffer_Len
--;
94 imax
= SLang_Input_Buffer_Len
;
96 memcpy ((char *) SLang_Input_Buffer
,
97 (char *) (SLang_Input_Buffer
+ 1), imax
);
100 #if SLANG_VERSION >= 10000
101 else return(_SLsys_getkey ());
103 else return(SLsys_getkey());
107 static int SLang_input_pending2 (int tsecs
)
111 if (SLang_Input_Buffer_Len
) return (int) SLang_Input_Buffer_Len
;
112 #if SLANG_VERSION >= 10000
113 n
= _SLsys_input_pending (tsecs
);
115 n
= SLsys_input_pending (tsecs
);
117 if (n
<= 0) return 0;
119 c
= (unsigned char) SLang_getkey2 ();
120 SLang_ungetkey_string (&c
, 1);
127 slang_intr (int signo
)
133 interrupts_enabled (void)
135 struct sigaction current_act
;
137 sigaction (SIGINT
, NULL
, ¤t_act
);
138 return current_act
.sa_handler
== slang_intr
;
142 enable_interrupt_key(void)
144 struct sigaction act
;
146 act
.sa_handler
= slang_intr
;
147 sigemptyset (&act
.sa_mask
);
149 sigaction (SIGINT
, &act
, NULL
);
154 disable_interrupt_key(void)
156 struct sigaction act
;
158 act
.sa_handler
= SIG_IGN
;
160 sigemptyset (&act
.sa_mask
);
161 sigaction (SIGINT
, &act
, NULL
);
174 /* Only done the first time */
178 extern int SLtt_Blink_Mode
;
179 extern int SLtt_Has_Alt_Charset
;
180 extern int force_ugly_line_drawing
;
181 struct sigaction act
, oact
;
183 SLtt_get_terminfo ();
184 tcgetattr (fileno (stdin
), &boot_mode
);
185 /* 255 = ignore abort char; XCTRL('g') for abort char = ^g */
186 SLang_init_tty (XCTRL('c'), 1, 0);
188 /* If SLang uses fileno(stderr) for terminal input MC will hang
189 if we call SLang_getkey between calls to open_error_pipe and
190 close_error_pipe, e.g. when we do a growing view of an gzipped
192 if (SLang_TT_Read_FD
== fileno (stderr
))
193 SLang_TT_Read_FD
= fileno (stdin
);
195 if (force_ugly_line_drawing
)
196 SLtt_Has_Alt_Charset
= 0;
197 if (tcgetattr (SLang_TT_Read_FD
, &new_mode
) == 0) {
199 new_mode
.c_cc
[VDSUSP
] = NULL_VALUE
; /* to ignore ^Y */
202 new_mode
.c_cc
[VLNEXT
] = NULL_VALUE
; /* to ignore ^V */
204 tcsetattr (SLang_TT_Read_FD
, TCSADRAIN
, &new_mode
);
207 load_terminfo_keys ();
208 act
.sa_handler
= slang_intr
;
209 sigemptyset (&act
.sa_mask
);
210 act
.sa_flags
= SA_RESTART
;
211 sigaction (SIGINT
, &act
, &oact
);
216 slang_set_raw_mode (void)
218 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &new_mode
);
221 /* Done each time we come back from done mode */
223 slang_prog_mode (void)
225 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &new_mode
);
227 SLsmg_touch_lines (0, LINES
);
230 /* Called each time we want to shutdown slang screen manager */
232 slang_shell_mode (void)
234 tcsetattr (SLang_TT_Read_FD
, TCSANOW
, &boot_mode
);
246 /* Load the op capability to reset the colors to those that were
247 * active when the program was started up
249 op_cap
= SLtt_tgetstr ("op");
251 fprintf (stdout
, "%s", op_cap
);
256 /* HP Terminals have capabilities (pfkey, pfloc, pfx) to program function keys.
257 elm 2.4pl15 invoked with the -K option utilizes these softkeys and the
258 consequence is that function keys don't work in MC sometimes.
259 Unfortunately I don't now the one and only escape sequence to turn off
260 softkeys (elm uses three different capabilities to turn on softkeys and two
261 capabilities to turn them off).
262 Among other things elm uses the pair we already use in slang_keypad. That's
263 the reason why I call slang_reset_softkeys from slang_keypad. In lack of
264 something better the softkeys are programmed to their defaults from the
265 termcap/terminfo database.
266 The escape sequence to program the softkeys is taken from elm and it is
267 hardcoded because neither slang nor ncurses 4.1 know how to 'printf' this
272 slang_reset_softkeys (void)
279 for ( key
= 1; key
< 9; key
++ ) {
280 sprintf ( tmp
, "k%d", key
);
281 send
= (char *) SLtt_tgetstr (tmp
);
283 sprintf(tmp
, "\033&f%dk%dd%dL%s%s", key
,
284 strlen(display
), strlen(send
), display
, send
);
285 SLtt_write_string (tmp
);
290 /* keypad routines */
292 slang_keypad (int set
)
295 extern int reset_hp_softkeys
;
297 keypad_string
= (char *) SLtt_tgetstr (set
? "ks" : "ke");
299 SLtt_write_string (keypad_string
);
300 if (set
&& reset_hp_softkeys
)
301 slang_reset_softkeys ();
305 set_slang_delay (int v
)
311 hline (int ch
, int len
)
315 last_x
= SLsmg_get_column ();
316 last_y
= SLsmg_get_row ();
321 if (ch
== ACS_HLINE
){
322 SLsmg_draw_hline (len
);
327 move (last_y
, last_x
);
331 vline (int character
, int len
)
334 SLsmg_draw_vline (len
);
336 int last_x
, last_y
, pos
= 0;
338 last_x
= SLsmg_get_column ();
339 last_y
= SLsmg_get_row ();
342 move (last_y
+ pos
++, last_x
);
345 move (last_x
, last_y
);
352 init_pair (int index
, char *foreground
, char *background
)
355 SLtt_set_color (index
, "", foreground
, background
);
356 if (index
> max_index
)
361 alloc_color_pair (char *foreground
, char *background
)
363 init_pair (++max_index
, foreground
, background
);
368 try_alloc_color_pair (char *fg
, char *bg
)
370 static struct colors_avail
{
371 struct colors_avail
*next
;
379 c
.index
= NORMAL_COLOR
;
382 if (((fg
&& p
->fg
) ? !strcmp (fg
, p
->fg
) : fg
== p
->fg
) != 0
383 && ((bg
&& p
->bg
) ? !strcmp (bg
, p
->bg
) : bg
== p
->bg
) != 0)
389 p
->next
= malloc (sizeof (c
));
392 p
->fg
= fg
? strdup (fg
) : 0;
393 p
->bg
= bg
? strdup (bg
) : 0;
398 p
->index
= alloc_color_pair (fg
, bg
);
402 char *color_terminals
[] = {
412 /* 'qnx*' terminals have non-ANSI-compatible color sequences... */
423 char *terminal
= getenv ("TERM");
424 char *cts
= color_terminal_string
, *s
;
427 SLtt_Use_Ansi_Colors
= force_colors
;
428 if (NULL
!= getenv ("COLORTERM"))
429 SLtt_Use_Ansi_Colors
= 1;
431 /* We want to allow overwriding */
432 if (!disable_colors
){
435 /* check hard-coded terminals */
436 for (i
= 0; color_terminals
[i
]; i
++)
437 if (strcmp (color_terminals
[i
], terminal
) == 0)
438 SLtt_Use_Ansi_Colors
= 1;
441 /* check color_terminal_string */
445 while (*cts
== ' ' || *cts
== '\t') cts
++;
450 while (*cts
&& *cts
!= ',')
455 if (i
&& i
== strlen(terminal
) && strncmp(s
, terminal
, i
) == 0)
456 SLtt_Use_Ansi_Colors
= 1;
458 if (*cts
== ',') cts
++;
463 /* Setup emulated colors */
464 if (SLtt_Use_Ansi_Colors
){
466 init_pair (A_REVERSE
, "black", "white");
467 init_pair (A_BOLD
, "white", "black");
469 init_pair (A_REVERSE
, "black", "lightgray");
470 init_pair (A_BOLD
, "white", "black");
471 init_pair (A_BOLD_REVERSE
, "white", "lightgray");
474 SLtt_set_mono (A_BOLD
, NULL
, SLTT_BOLD_MASK
);
475 SLtt_set_mono (A_REVERSE
, NULL
, SLTT_REV_MASK
);
476 SLtt_set_mono (A_BOLD
|A_REVERSE
, NULL
, SLTT_BOLD_MASK
| SLTT_REV_MASK
);
478 return SLtt_Use_Ansi_Colors
;
484 if (!SLtt_Use_Ansi_Colors
){
485 SLsmg_set_color (color
);
491 SLsmg_set_color (A_BOLD
);
493 SLsmg_set_color ((color
& (~A_BOLD
)) + 8);
497 if (color
== A_REVERSE
)
498 SLsmg_set_color (A_REVERSE
);
500 SLsmg_set_color (color
);
503 /* This table describes which capabilities we want and which values we
539 { KEY_BACKSPACE
, "kb" },
546 do_define_key (int code
, char *strcap
)
550 seq
= (char *) SLtt_tgetstr (strcap
);
552 define_sequence (code
, seq
, MCKEY_NOACTION
);
556 load_terminfo_keys ()
560 for (i
= 0; key_table
[i
].key_code
; i
++)
561 do_define_key (key_table
[i
].key_code
, key_table
[i
].key_name
);
567 if (SLang_input_pending2 (0) == 0)
570 return (SLang_getkey2 ());
573 extern int slow_terminal
;
577 /* Non slang builds do not understand got_interrupt */
582 #endif /* HAVE_SLANG */
587 if (!we_are_background
)