Ticket #1930: src/strutil8bit.c: fixed missing include of fs.h
[free-mc.git] / src / tty / tty-ncurses.c
blob76b0f5fb99ed613669f63443c4304c163f581102
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 "../../src/global.h"
41 #ifndef WANT_TERM_H
42 # define WANT_TERM_H
43 #endif
45 #include "../../src/tty/tty-internal.h" /* slow_tty */
46 #include "../../src/tty/tty.h"
47 #include "../../src/tty/color-internal.h"
48 #include "../../src/tty/win.h"
49 #include "../../src/main.h"
51 #include "../../src/strutil.h" /* str_term_form */
53 /* include at last !!! */
54 #ifdef WANT_TERM_H
55 # include <term.h>
56 #endif /* WANT_TERM_H */
58 /*** global variables **************************************************/
60 /*** file scope macro definitions **************************************/
62 /*** global variables **************************************************/
64 /*** file scope type declarations **************************************/
66 /*** file scope variables **********************************************/
68 /*** file scope functions **********************************************/
70 /* --------------------------------------------------------------------------------------------- */
71 /*** public functions **************************************************/
72 /* --------------------------------------------------------------------------------------------- */
74 int
75 mc_tty_normalize_lines_char (const char *ch)
77 char *str2;
78 int res;
80 struct mc_tty_lines_struct {
81 const char *line;
82 int line_code;
83 } const lines_codes[] = {
84 {"\342\224\214", ACS_LRCORNER}, /* ┌ */
85 {"\342\224\220", ACS_LLCORNER}, /* ┐ */
86 {"\342\224\224", ACS_URCORNER}, /* └ */
87 {"\342\224\230", ACS_ULCORNER}, /* ┘ */
88 {"\342\224\234", ACS_LTEE}, /* ├ */
89 {"\342\224\244", ACS_RTEE}, /* ┤ */
90 {"\342\224\254", ACS_TTEE}, /* ┬ */
91 {"\342\224\264", ACS_BTEE}, /* ┴ */
92 {"\342\224\200", ACS_HLINE}, /* ─ */
93 {"\342\224\202", ACS_VLINE}, /* │ */
94 {"\342\224\274", ACS_PLUS}, /* ┼ */
96 {"\342\225\235", ACS_LRCORNER | A_BOLD}, /* ╔ */
97 {"\342\225\232", ACS_LLCORNER | A_BOLD}, /* ╗ */
98 {"\342\225\227", ACS_URCORNER | A_BOLD}, /* ╚ */
99 {"\342\225\224", ACS_ULCORNER | A_BOLD}, /* ╝ */
100 {"\342\225\237", ACS_LTEE | A_BOLD}, /* ╟ */
101 {"\342\225\242", ACS_RTEE | A_BOLD}, /* ╢ */
102 {"\342\225\244", ACS_TTEE | A_BOLD}, /* ╤ */
103 {"\342\225\247", ACS_BTEE | A_BOLD}, /* ╧ */
104 {"\342\225\220", ACS_HLINE | A_BOLD}, /* ═ */
105 {"\342\225\221", ACS_VLINE | A_BOLD}, /* ║ */
107 {NULL, 0}
110 if (ch == NULL)
111 return (int) ' ';
113 for (res = 0; lines_codes[res].line; res++) {
114 if (strcmp (ch, lines_codes[res].line) == 0)
115 return lines_codes[res].line_code;
118 str2 = mc_tty_normalize_from_utf8 (ch);
119 res = g_utf8_get_char_validated (str2, -1);
121 if (res < 0)
122 res = (unsigned char) str2[0];
123 g_free (str2);
125 return res;
128 /* --------------------------------------------------------------------------------------------- */
131 void
132 tty_init (gboolean slow, gboolean ugly_lines)
134 slow_tty = slow;
135 (void) ugly_lines;
137 initscr ();
139 #ifdef HAVE_ESCDELAY
141 * If ncurses exports the ESCDELAY variable, it should be set to
142 * a low value, or you'll experience a delay in processing escape
143 * sequences that are recognized by mc (e.g. Esc-Esc). On the other
144 * hand, making ESCDELAY too small can result in some sequences
145 * (e.g. cursor arrows) being reported as separate keys under heavy
146 * processor load, and this can be a problem if mc hasn't learned
147 * them in the "Learn Keys" dialog. The value is in milliseconds.
149 ESCDELAY = 200;
150 #endif /* HAVE_ESCDELAY */
152 /* use Ctrl-g to generate SIGINT */
153 cur_term->Nttyb.c_cc[VINTR] = CTRL ('g'); /* ^g */
154 tcsetattr (cur_term->Filedes, TCSANOW, &cur_term->Nttyb);
156 tty_start_interrupt_key ();
158 do_enter_ca_mode ();
159 tty_raw_mode ();
160 noecho ();
161 keypad (stdscr, TRUE);
162 nodelay (stdscr, FALSE);
165 void
166 tty_shutdown (void)
168 endwin ();
171 void
172 tty_reset_prog_mode (void)
174 reset_prog_mode ();
177 void
178 tty_reset_shell_mode (void)
180 reset_shell_mode ();
183 void
184 tty_raw_mode (void)
186 raw (); /* FIXME: uneeded? */
187 cbreak ();
190 void
191 tty_noraw_mode (void)
193 nocbreak (); /* FIXME: unneeded? */
194 noraw ();
197 void
198 tty_noecho (void)
200 noecho ();
204 tty_flush_input (void)
206 return flushinp ();
209 void
210 tty_keypad (gboolean set)
212 keypad (stdscr, (bool) set);
215 void
216 tty_nodelay (gboolean set)
218 nodelay (stdscr, (bool) set);
222 tty_baudrate (void)
224 return baudrate ();
228 tty_lowlevel_getch (void)
230 return getch ();
234 tty_reset_screen (void)
236 return endwin ();
239 void
240 tty_touch_screen (void)
242 touchwin (stdscr);
245 void
246 tty_gotoyx (int y, int x)
248 move (y, x);
251 void
252 tty_getyx (int *py, int *px)
254 getyx (stdscr, *py, *px);
257 /* if x < 0 or y < 0, draw line starting from current position */
258 void
259 tty_draw_hline (int y, int x, int ch, int len)
261 if ((chtype) ch == ACS_HLINE)
262 ch = mc_tty_ugly_frm[MC_TTY_FRM_thinhoriz];
264 if ((y >= 0) && (x >= 0))
265 move (y, x);
266 hline (ch, len);
269 /* if x < 0 or y < 0, draw line starting from current position */
270 void
271 tty_draw_vline (int y, int x, int ch, int len)
273 if ((chtype) ch == ACS_VLINE)
274 ch = mc_tty_ugly_frm[MC_TTY_FRM_thinvert];
276 if ((y >= 0) && (x >= 0))
277 move (y, x);
278 vline (ch, len);
281 void
282 tty_fill_region (int y, int x, int rows, int cols, unsigned char ch)
284 int i;
286 for (i = 0; i < rows; i++) {
287 move (y + i, x);
288 hline (ch, cols);
291 move (y, x);
294 void
295 tty_set_alt_charset (gboolean alt_charset)
297 (void) alt_charset;
300 void
301 tty_display_8bit (gboolean what)
303 meta (stdscr, (int) what);
306 void
307 tty_print_char (int c)
309 addch (c);
312 void
313 tty_print_anychar (int c)
315 unsigned char str[6 + 1];
317 if (utf8_display || c > 255) {
318 int res = g_unichar_to_utf8 (c, (char *) str);
319 if (res == 0) {
320 str[0] = '.';
321 str[1] = '\0';
322 } else {
323 str[res] = '\0';
325 addstr (str_term_form ((char *) str));
326 } else {
327 addch (c);
332 void
333 tty_print_alt_char (int c)
335 if ((chtype) c == ACS_VLINE)
336 c = mc_tty_ugly_frm[MC_TTY_FRM_thinvert];
337 else if ((chtype) c == ACS_HLINE)
338 c = mc_tty_ugly_frm[MC_TTY_FRM_thinhoriz];
339 else if ((chtype) c == ACS_LTEE)
340 c = mc_tty_ugly_frm[MC_TTY_FRM_leftmiddle];
341 else if ((chtype) c == ACS_RTEE)
342 c = mc_tty_ugly_frm[MC_TTY_FRM_rightmiddle];
343 else if ((chtype) c == ACS_ULCORNER)
344 c = mc_tty_ugly_frm[MC_TTY_FRM_lefttop];
345 else if ((chtype) c == ACS_LLCORNER)
346 c = mc_tty_ugly_frm[MC_TTY_FRM_leftbottom];
347 else if ((chtype) c == ACS_URCORNER)
348 c = mc_tty_ugly_frm[MC_TTY_FRM_righttop];
349 else if ((chtype) c == ACS_LRCORNER)
350 c = mc_tty_ugly_frm[MC_TTY_FRM_rightbottom];
351 else if ((chtype) c == ACS_PLUS)
352 c = mc_tty_ugly_frm[MC_TTY_FRM_centermiddle];
354 addch (c);
357 void
358 tty_print_string (const char *s)
360 addstr (str_term_form (s));
363 void
364 tty_printf (const char *fmt, ...)
366 va_list args;
368 va_start (args, fmt);
369 vw_printw (stdscr, fmt, args);
370 va_end (args);
373 char *
374 tty_tgetstr (const char *cap)
376 char *unused = NULL;
377 return tgetstr ((char *) cap, &unused);
380 void
381 tty_refresh (void)
383 refresh ();
384 doupdate ();
387 void
388 tty_setup_sigwinch (void (*handler) (int))
390 #if (NCURSES_VERSION_MAJOR >= 4) && defined (SIGWINCH)
391 struct sigaction act, oact;
392 act.sa_handler = handler;
393 sigemptyset (&act.sa_mask);
394 act.sa_flags = 0;
395 #ifdef SA_RESTART
396 act.sa_flags |= SA_RESTART;
397 #endif /* SA_RESTART */
398 sigaction (SIGWINCH, &act, &oact);
399 #endif /* SIGWINCH */
402 void
403 tty_beep (void)
405 beep ();