Updated italian translation
[midnight-commander.git] / src / slint.c
blob45b0ec7c5f572f33e3969b884b0279da3ca3411c
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.
6 Author Miguel de Icaza
7 Norbert Warmuth
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
23 #include <config.h>
25 #include <signal.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
30 #ifdef HAVE_TERMIOS_H
31 #include <termios.h>
32 #endif
33 #include <unistd.h>
35 #include "global.h"
36 #include "tty.h"
37 #include "color.h"
38 #include "mouse.h" /* Gpm_Event is required in key.h */
39 #include "key.h" /* define_sequence */
40 #include "main.h" /* extern: force_colors */
41 #include "win.h" /* do_exit_ca_mode */
42 #include "setup.h"
43 #include "background.h" /* we_are_background */
45 #ifdef HAVE_SLANG
47 /* Taken from S-Lang's slutty.c */
48 #ifdef ultrix /* Ultrix gets _POSIX_VDISABLE wrong! */
49 # define NULL_VALUE -1
50 #else
51 # ifdef _POSIX_VDISABLE
52 # define NULL_VALUE _POSIX_VDISABLE
53 # else
54 # define NULL_VALUE 255
55 # endif
56 #endif
58 /* Taken from S-Lang's sldisply.c file */
59 #ifndef USE_TERMCAP
60 # define tgetstr(a,b) SLtt_tgetstr (a)
61 #else
62 extern char *tgetstr(char *, char **);
63 #endif
65 #ifndef SA_RESTART
66 # define SA_RESTART 0
67 #endif
69 /* Various saved termios settings that we control here */
70 static struct termios boot_mode;
71 static struct termios new_mode;
73 /* Controls whether we should wait for input in getch */
74 static int no_slang_delay;
76 /* Forward declarations */
77 static void load_terminfo_keys (void);
79 #ifndef HAVE_SLANG_PRIVATE
80 /* Private interfaces have been stripped, so we cannot use them */
81 #define SLang_getkey2() SLang_getkey()
82 #define SLang_input_pending2(s) SLang_input_pending(s)
83 #else
84 /* Copied from ../slang/slgetkey.c, removed the DEC_8Bit_HACK. */
85 extern unsigned char SLang_Input_Buffer [];
86 #if SLANG_VERSION >= 10000
87 extern unsigned int _SLsys_getkey (void);
88 extern int _SLsys_input_pending (int);
89 #else
90 extern unsigned int SLsys_getkey (void);
91 extern int SLsys_input_pending (int);
92 #endif
94 static unsigned int SLang_getkey2 (void)
96 unsigned int imax;
97 unsigned int ch;
99 if (SLang_Input_Buffer_Len)
101 ch = (unsigned int) *SLang_Input_Buffer;
102 SLang_Input_Buffer_Len--;
103 imax = SLang_Input_Buffer_Len;
105 memmove ((char *) SLang_Input_Buffer,
106 (char *) (SLang_Input_Buffer + 1), imax);
107 return(ch);
109 #if SLANG_VERSION >= 10000
110 else return(_SLsys_getkey ());
111 #else
112 else return(SLsys_getkey());
113 #endif
116 static int SLang_input_pending2 (int tsecs)
118 int n, i;
119 unsigned char c;
121 if (SLang_Input_Buffer_Len) return (int) SLang_Input_Buffer_Len;
122 #if SLANG_VERSION >= 10000
123 n = _SLsys_input_pending (tsecs);
124 #else
125 n = SLsys_input_pending (tsecs);
126 #endif
127 if (n <= 0) return 0;
129 i = SLang_getkey2 ();
130 if (i == SLANG_GETKEY_ERROR)
131 return 0; /* don't put crippled error codes into the input buffer */
132 c = (unsigned char)i;
133 SLang_ungetkey_string (&c, 1);
135 return n;
137 #endif /* HAVE_SLANG_PRIVATE */
139 /* Only done the first time */
140 void
141 slang_init (void)
143 SLtt_get_terminfo ();
146 * If the terminal in not in terminfo but begins with a well-known
147 * string such as "linux" or "xterm" S-Lang will go on, but the
148 * terminal size and several other variables won't be initialized
149 * (as of S-Lang 1.4.4). Detect it and abort. Also detect extremely
150 * small, large and negative screen dimensions.
152 if ((COLS < 10) || (LINES < 5) ||
153 (SLang_Version < 10407 && (COLS > 255 || LINES > 255)) ||
154 (SLang_Version >= 10407 && (COLS > 512 || LINES > 512))) {
156 fprintf (stderr,
157 _("Screen size %dx%d is not supported.\n"
158 "Check the TERM environment variable.\n"),
159 COLS, LINES);
160 exit (1);
163 tcgetattr (fileno (stdin), &boot_mode);
164 /* 255 = ignore abort char; XCTRL('g') for abort char = ^g */
165 SLang_init_tty (XCTRL('c'), 1, 0);
167 /* If SLang uses fileno(stderr) for terminal input MC will hang
168 if we call SLang_getkey between calls to open_error_pipe and
169 close_error_pipe, e.g. when we do a growing view of an gzipped
170 file. */
171 if (SLang_TT_Read_FD == fileno (stderr))
172 SLang_TT_Read_FD = fileno (stdin);
174 if (force_ugly_line_drawing)
175 SLtt_Has_Alt_Charset = 0;
176 if (tcgetattr (SLang_TT_Read_FD, &new_mode) == 0) {
177 #ifdef VDSUSP
178 new_mode.c_cc[VDSUSP] = NULL_VALUE; /* to ignore ^Y */
179 #endif
180 #ifdef VLNEXT
181 new_mode.c_cc[VLNEXT] = NULL_VALUE; /* to ignore ^V */
182 #endif
183 tcsetattr (SLang_TT_Read_FD, TCSADRAIN, &new_mode);
185 slang_prog_mode ();
186 load_terminfo_keys ();
187 SLtt_Blink_Mode = 0;
190 void
191 slang_set_raw_mode (void)
193 tcsetattr (SLang_TT_Read_FD, TCSANOW, &new_mode);
196 /* Done each time we come back from done mode */
197 void
198 slang_prog_mode (void)
200 tcsetattr (SLang_TT_Read_FD, TCSANOW, &new_mode);
201 SLsmg_init_smg ();
202 SLsmg_touch_lines (0, LINES);
205 /* Called each time we want to shutdown slang screen manager */
206 void
207 slang_shell_mode (void)
209 tcsetattr (SLang_TT_Read_FD, TCSANOW, &boot_mode);
212 void
213 slang_shutdown (void)
215 char *op_cap;
217 slang_shell_mode ();
218 do_exit_ca_mode ();
219 SLang_reset_tty ();
221 /* Load the op capability to reset the colors to those that were
222 * active when the program was started up
224 op_cap = SLtt_tgetstr ("op");
225 if (op_cap){
226 fprintf (stdout, "%s", op_cap);
227 fflush (stdout);
231 /* HP Terminals have capabilities (pfkey, pfloc, pfx) to program function keys.
232 elm 2.4pl15 invoked with the -K option utilizes these softkeys and the
233 consequence is that function keys don't work in MC sometimes.
234 Unfortunately I don't now the one and only escape sequence to turn off
235 softkeys (elm uses three different capabilities to turn on softkeys and two
236 capabilities to turn them off).
237 Among other things elm uses the pair we already use in slang_keypad. That's
238 the reason why I call slang_reset_softkeys from slang_keypad. In lack of
239 something better the softkeys are programmed to their defaults from the
240 termcap/terminfo database.
241 The escape sequence to program the softkeys is taken from elm and it is
242 hardcoded because neither slang nor ncurses 4.1 know how to 'printf' this
243 sequence. -- Norbert
246 static void
247 slang_reset_softkeys (void)
249 int key;
250 char *send;
251 static const char display[] = " ";
252 char tmp[BUF_SMALL];
254 for (key = 1; key < 9; key++) {
255 g_snprintf (tmp, sizeof (tmp), "k%d", key);
256 send = (char *) SLtt_tgetstr (tmp);
257 if (send) {
258 g_snprintf (tmp, sizeof (tmp), "\033&f%dk%dd%dL%s%s", key,
259 (int) (sizeof (display) - 1), (int) strlen (send),
260 display, send);
261 SLtt_write_string (tmp);
266 /* keypad routines */
267 void
268 slang_keypad (int set)
270 char *keypad_string;
271 extern int reset_hp_softkeys;
273 keypad_string = (char *) SLtt_tgetstr (set ? "ks" : "ke");
274 if (keypad_string)
275 SLtt_write_string (keypad_string);
276 if (set && reset_hp_softkeys)
277 slang_reset_softkeys ();
280 void
281 set_slang_delay (int v)
283 no_slang_delay = v;
286 void
287 hline (int ch, int len)
289 int last_x, last_y;
291 last_x = SLsmg_get_column ();
292 last_y = SLsmg_get_row ();
294 if (ch == 0)
295 ch = ACS_HLINE;
297 if (ch == ACS_HLINE){
298 SLsmg_draw_hline (len);
299 } else {
300 while (len--)
301 addch (ch);
303 move (last_y, last_x);
306 void
307 vline (int character, int len)
309 if (!slow_terminal){
310 SLsmg_draw_vline (len);
311 } else {
312 int last_x, last_y, pos = 0;
314 last_x = SLsmg_get_column ();
315 last_y = SLsmg_get_row ();
317 while (len--){
318 move (last_y + pos++, last_x);
319 addch (' ');
321 move (last_x, last_y);
325 int has_colors (void)
327 const char *terminal = getenv ("TERM");
328 char *cts = color_terminal_string, *s;
329 size_t i;
331 if (force_colors)
332 SLtt_Use_Ansi_Colors = 1;
333 if (NULL != getenv ("COLORTERM"))
334 SLtt_Use_Ansi_Colors = 1;
336 /* We want to allow overwriding */
337 if (!disable_colors){
338 /* check color_terminal_string */
339 if (*cts)
341 while (*cts)
343 while (*cts == ' ' || *cts == '\t') cts++;
345 s = cts;
346 i = 0;
348 while (*cts && *cts != ',')
350 cts++;
351 i++;
353 if (i && i == strlen(terminal) && strncmp(s, terminal, i) == 0)
354 SLtt_Use_Ansi_Colors = 1;
356 if (*cts == ',') cts++;
361 /* Setup emulated colors */
362 if (SLtt_Use_Ansi_Colors){
363 if (use_colors){
364 mc_init_pair (A_REVERSE, "black", "white");
365 mc_init_pair (A_BOLD, "white", "black");
366 } else {
367 mc_init_pair (A_REVERSE, "black", "lightgray");
368 mc_init_pair (A_BOLD, "white", "black");
369 mc_init_pair (A_BOLD_REVERSE, "white", "lightgray");
371 } else {
372 SLtt_set_mono (A_BOLD, NULL, SLTT_BOLD_MASK);
373 SLtt_set_mono (A_REVERSE, NULL, SLTT_REV_MASK);
374 SLtt_set_mono (A_BOLD|A_REVERSE, NULL, SLTT_BOLD_MASK | SLTT_REV_MASK);
376 return SLtt_Use_Ansi_Colors;
379 void
380 attrset (int color)
382 if (!SLtt_Use_Ansi_Colors){
383 SLsmg_set_color (color);
384 return;
387 if (color & A_BOLD){
388 if (color == A_BOLD)
389 SLsmg_set_color (A_BOLD);
390 else
391 SLsmg_set_color ((color & (~A_BOLD)) + 8);
392 return;
395 if (color == A_REVERSE)
396 SLsmg_set_color (A_REVERSE);
397 else
398 SLsmg_set_color (color);
401 /* This table describes which capabilities we want and which values we
402 * assign to them.
404 static const struct {
405 int key_code;
406 const char *key_name;
407 } key_table [] = {
408 { KEY_F(0), "k0" },
409 { KEY_F(1), "k1" },
410 { KEY_F(2), "k2" },
411 { KEY_F(3), "k3" },
412 { KEY_F(4), "k4" },
413 { KEY_F(5), "k5" },
414 { KEY_F(6), "k6" },
415 { KEY_F(7), "k7" },
416 { KEY_F(8), "k8" },
417 { KEY_F(9), "k9" },
418 { KEY_F(10), "k;" },
419 { KEY_F(11), "F1" },
420 { KEY_F(12), "F2" },
421 { KEY_F(13), "F3" },
422 { KEY_F(14), "F4" },
423 { KEY_F(15), "F5" },
424 { KEY_F(16), "F6" },
425 { KEY_F(17), "F7" },
426 { KEY_F(18), "F8" },
427 { KEY_F(19), "F9" },
428 { KEY_F(20), "FA" },
429 { KEY_IC, "kI" },
430 { KEY_NPAGE, "kN" },
431 { KEY_PPAGE, "kP" },
432 { KEY_LEFT, "kl" },
433 { KEY_RIGHT, "kr" },
434 { KEY_UP, "ku" },
435 { KEY_DOWN, "kd" },
436 { KEY_DC, "kD" },
437 { KEY_BACKSPACE, "kb" },
438 { KEY_HOME, "kh" },
439 { KEY_END, "@7" },
440 { 0, 0}
443 static void
444 do_define_key (int code, const char *strcap)
446 char *seq;
448 seq = (char *) SLtt_tgetstr ((char*) strcap);
449 if (seq)
450 define_sequence (code, seq, MCKEY_NOACTION);
453 static void
454 load_terminfo_keys (void)
456 int i;
458 for (i = 0; key_table [i].key_code; i++)
459 do_define_key (key_table [i].key_code, key_table [i].key_name);
463 getch (void)
465 int c;
466 if (no_slang_delay)
467 if (SLang_input_pending2 (0) == 0)
468 return -1;
470 c = SLang_getkey2 ();
471 if (c == SLANG_GETKEY_ERROR) {
472 fprintf (stderr,
473 "SLang_getkey returned SLANG_GETKEY_ERROR\n"
474 "Assuming EOF on stdin and exiting\n");
475 exit (1);
477 return c;
479 #endif /* HAVE_SLANG */
481 void
482 mc_refresh (void)
484 #ifdef WITH_BACKGROUND
485 if (!we_are_background)
486 #endif /* WITH_BACKGROUND */
487 refresh ();