Refactored IPV4/IPV6 FTP connection setup code
[midnight-commander.git] / lib / tty / tty-ncurses.c
blobb7a521385061711a174cb7c848ddc657ade41d0d
1 /*
2 Interface to the terminal controlling library.
3 Ncurses wrapper.
5 Copyright (C) 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
7 Written by:
8 Andrew Borodin <aborodin@vmail.ru>, 2009.
9 Ilia Maslakov <il.smind@gmail.com>, 2009.
11 This file is part of the Midnight Commander.
13 The Midnight Commander is free software; you can redistribute it
14 and/or modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
18 The Midnight Commander is distributed in the hope that it will be
19 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
20 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 MA 02110-1301, USA.
29 /** \file
30 * \brief Source: NCurses-based tty layer of Midnight-commander
33 #include <config.h>
35 #include <stdlib.h>
36 #include <stdarg.h>
37 #include <signal.h>
39 #include "lib/global.h"
40 #include "lib/strutil.h" /* str_term_form */
42 #include "src/main.h"
44 #ifndef WANT_TERM_H
45 # define WANT_TERM_H
46 #endif
48 #include "tty-internal.h" /* slow_tty */
49 #include "tty.h"
50 #include "color-internal.h"
51 #include "win.h"
53 /* include at last !!! */
54 #ifdef WANT_TERM_H
55 #ifdef HAVE_NCURSES_TERM_H
56 # include <ncurses/term.h>
57 #else
58 # include <term.h>
59 #endif /* HAVE_NCURSES_TERM_H */
60 #endif /* WANT_TERM_H */
62 /*** global variables **************************************************/
64 /*** file scope macro definitions **************************************/
66 #if defined(_AIX) && !defined(CTRL)
67 # define CTRL(x) ((x) & 0x1f)
68 #endif
70 /*** global variables **************************************************/
72 /*** file scope type declarations **************************************/
74 /*** file scope variables **********************************************/
76 /*** file scope functions **********************************************/
78 /* --------------------------------------------------------------------------------------------- */
79 /*** public functions **************************************************/
80 /* --------------------------------------------------------------------------------------------- */
82 int
83 mc_tty_normalize_lines_char (const char *ch)
85 char *str2;
86 int res;
88 struct mc_tty_lines_struct
90 const char *line;
91 int line_code;
92 } const lines_codes[] = {
93 {"\342\224\230", ACS_LRCORNER}, /* ┌ */
94 {"\342\224\224", ACS_LLCORNER}, /* └ */
95 {"\342\224\220", ACS_URCORNER}, /* ┐ */
96 {"\342\224\214", ACS_ULCORNER}, /* ┘ */
97 {"\342\224\234", ACS_LTEE}, /* ├ */
98 {"\342\224\244", ACS_RTEE}, /* ┤ */
99 {"\342\224\254", ACS_TTEE}, /* ┬ */
100 {"\342\224\264", ACS_BTEE}, /* ┴ */
101 {"\342\224\200", ACS_HLINE}, /* ─ */
102 {"\342\224\202", ACS_VLINE}, /* │ */
103 {"\342\224\274", ACS_PLUS}, /* ┼ */
105 {"\342\225\235", ACS_LRCORNER | A_BOLD}, /* ╔ */
106 {"\342\225\232", ACS_LLCORNER | A_BOLD}, /* ╚ */
107 {"\342\225\227", ACS_URCORNER | A_BOLD}, /* ╗ */
108 {"\342\225\224", ACS_ULCORNER | A_BOLD}, /* ╝ */
109 {"\342\225\237", ACS_LTEE | A_BOLD}, /* ╟ */
110 {"\342\225\242", ACS_RTEE | A_BOLD}, /* ╢ */
111 {"\342\225\244", ACS_TTEE | A_BOLD}, /* ╤ */
112 {"\342\225\247", ACS_BTEE | A_BOLD}, /* ╧ */
113 {"\342\225\220", ACS_HLINE | A_BOLD}, /* ═ */
114 {"\342\225\221", ACS_VLINE | A_BOLD}, /* ║ */
116 {NULL, 0}
119 if (ch == NULL)
120 return (int) ' ';
122 for (res = 0; lines_codes[res].line; res++)
124 if (strcmp (ch, lines_codes[res].line) == 0)
125 return lines_codes[res].line_code;
128 str2 = mc_tty_normalize_from_utf8 (ch);
129 res = g_utf8_get_char_validated (str2, -1);
131 if (res < 0)
132 res = (unsigned char) str2[0];
133 g_free (str2);
135 return res;
138 /* --------------------------------------------------------------------------------------------- */
141 void
142 tty_init (gboolean slow, gboolean ugly_lines)
144 slow_tty = slow;
145 (void) ugly_lines;
147 initscr ();
149 #ifdef HAVE_ESCDELAY
151 * If ncurses exports the ESCDELAY variable, it should be set to
152 * a low value, or you'll experience a delay in processing escape
153 * sequences that are recognized by mc (e.g. Esc-Esc). On the other
154 * hand, making ESCDELAY too small can result in some sequences
155 * (e.g. cursor arrows) being reported as separate keys under heavy
156 * processor load, and this can be a problem if mc hasn't learned
157 * them in the "Learn Keys" dialog. The value is in milliseconds.
159 ESCDELAY = 200;
160 #endif /* HAVE_ESCDELAY */
162 /* use Ctrl-g to generate SIGINT */
163 cur_term->Nttyb.c_cc[VINTR] = CTRL ('g'); /* ^g */
164 /* disable SIGQUIT to allow use Ctrl-\ key */
165 cur_term->Nttyb.c_cc[VQUIT] = NULL_VALUE;
166 tcsetattr (cur_term->Filedes, TCSANOW, &cur_term->Nttyb);
168 tty_start_interrupt_key ();
170 do_enter_ca_mode ();
171 tty_raw_mode ();
172 noecho ();
173 keypad (stdscr, TRUE);
174 nodelay (stdscr, FALSE);
177 void
178 tty_shutdown (void)
180 endwin ();
183 void
184 tty_reset_prog_mode (void)
186 reset_prog_mode ();
189 void
190 tty_reset_shell_mode (void)
192 reset_shell_mode ();
195 void
196 tty_raw_mode (void)
198 raw (); /* FIXME: uneeded? */
199 cbreak ();
202 void
203 tty_noraw_mode (void)
205 nocbreak (); /* FIXME: unneeded? */
206 noraw ();
209 void
210 tty_noecho (void)
212 noecho ();
216 tty_flush_input (void)
218 return flushinp ();
221 void
222 tty_keypad (gboolean set)
224 keypad (stdscr, (bool) set);
227 void
228 tty_nodelay (gboolean set)
230 nodelay (stdscr, (bool) set);
234 tty_baudrate (void)
236 return baudrate ();
240 tty_lowlevel_getch (void)
242 return getch ();
246 tty_reset_screen (void)
248 return endwin ();
251 void
252 tty_touch_screen (void)
254 touchwin (stdscr);
257 void
258 tty_gotoyx (int y, int x)
260 move (y, x);
263 void
264 tty_getyx (int *py, int *px)
266 getyx (stdscr, *py, *px);
269 /* if x < 0 or y < 0, draw line starting from current position */
270 void
271 tty_draw_hline (int y, int x, int ch, int len)
273 if ((chtype) ch == ACS_HLINE)
274 ch = mc_tty_frm[MC_TTY_FRM_HORIZ];
276 if ((y >= 0) && (x >= 0))
277 move (y, x);
278 hline (ch, len);
281 /* if x < 0 or y < 0, draw line starting from current position */
282 void
283 tty_draw_vline (int y, int x, int ch, int len)
285 if ((chtype) ch == ACS_VLINE)
286 ch = mc_tty_frm[MC_TTY_FRM_VERT];
288 if ((y >= 0) && (x >= 0))
289 move (y, x);
290 vline (ch, len);
293 void
294 tty_fill_region (int y, int x, int rows, int cols, unsigned char ch)
296 int i;
298 if (y < 0)
300 rows += y;
302 if (rows <= 0)
303 return;
305 y = 0;
308 if (x < 0)
310 cols += x;
312 if (cols <= 0)
313 return;
315 x = 0;
318 if (y + rows > LINES)
319 rows = LINES - y;
320 if (x + cols > COLS)
321 cols = COLS - x;
323 for (i = 0; i < rows; i++)
325 move (y + i, x);
326 hline (ch, cols);
329 move (y, x);
332 void
333 tty_set_alt_charset (gboolean alt_charset)
335 (void) alt_charset;
338 void
339 tty_display_8bit (gboolean what)
341 meta (stdscr, (int) what);
344 void
345 tty_print_char (int c)
347 addch (c);
350 void
351 tty_print_anychar (int c)
353 unsigned char str[6 + 1];
355 if (utf8_display || c > 255)
357 int res = g_unichar_to_utf8 (c, (char *) str);
358 if (res == 0)
360 str[0] = '.';
361 str[1] = '\0';
363 else
364 str[res] = '\0';
365 addstr (str_term_form ((char *) str));
367 else
368 addch (c);
372 void
373 tty_print_alt_char (int c, gboolean single)
375 if ((chtype) c == ACS_VLINE)
376 c = mc_tty_frm[single ? MC_TTY_FRM_VERT : MC_TTY_FRM_DVERT];
377 else if ((chtype) c == ACS_HLINE)
378 c = mc_tty_frm[single ? MC_TTY_FRM_HORIZ : MC_TTY_FRM_DHORIZ];
379 else if ((chtype) c == ACS_LTEE)
380 c = mc_tty_frm[single ? MC_TTY_FRM_LEFTMIDDLE : MC_TTY_FRM_DLEFTMIDDLE];
381 else if ((chtype) c == ACS_RTEE)
382 c = mc_tty_frm[single ? MC_TTY_FRM_RIGHTMIDDLE : MC_TTY_FRM_DRIGHTMIDDLE];
383 else if ((chtype) c == ACS_ULCORNER)
384 c = mc_tty_frm[single ? MC_TTY_FRM_LEFTTOP : MC_TTY_FRM_DLEFTTOP];
385 else if ((chtype) c == ACS_LLCORNER)
386 c = mc_tty_frm[single ? MC_TTY_FRM_LEFTBOTTOM : MC_TTY_FRM_DLEFTBOTTOM];
387 else if ((chtype) c == ACS_URCORNER)
388 c = mc_tty_frm[single ? MC_TTY_FRM_RIGHTTOP : MC_TTY_FRM_DRIGHTTOP];
389 else if ((chtype) c == ACS_LRCORNER)
390 c = mc_tty_frm[single ? MC_TTY_FRM_RIGHTBOTTOM : MC_TTY_FRM_DRIGHTBOTTOM];
391 else if ((chtype) c == ACS_PLUS)
392 c = mc_tty_frm[MC_TTY_FRM_CROSS];
394 addch (c);
397 void
398 tty_print_string (const char *s)
400 addstr (str_term_form (s));
403 void
404 tty_printf (const char *fmt, ...)
406 va_list args;
408 va_start (args, fmt);
409 vw_printw (stdscr, fmt, args);
410 va_end (args);
413 char *
414 tty_tgetstr (const char *cap)
416 char *unused = NULL;
417 return tgetstr ((char *) cap, &unused);
420 void
421 tty_refresh (void)
423 refresh ();
424 doupdate ();
427 void
428 tty_setup_sigwinch (void (*handler) (int))
430 #if (NCURSES_VERSION_MAJOR >= 4) && defined (SIGWINCH)
431 struct sigaction act, oact;
432 act.sa_handler = handler;
433 sigemptyset (&act.sa_mask);
434 act.sa_flags = 0;
435 #ifdef SA_RESTART
436 act.sa_flags |= SA_RESTART;
437 #endif /* SA_RESTART */
438 sigaction (SIGWINCH, &act, &oact);
439 #endif /* SIGWINCH */
442 void
443 tty_beep (void)
445 beep ();