patches for AIX with ncurses support
[midnight-commander.git] / lib / tty / tty-ncurses.c
blob9e93408976984017ca2efabc17bb1324d997a4b2
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 **************************************/
65 #if defined(_AIX) && !defined(CTRL)
66 # define CTRL(x) ((x) & 0x1f)
67 #endif
69 /*** global variables **************************************************/
71 /*** file scope type declarations **************************************/
73 /*** file scope variables **********************************************/
75 /*** file scope functions **********************************************/
77 /* --------------------------------------------------------------------------------------------- */
78 /*** public functions **************************************************/
79 /* --------------------------------------------------------------------------------------------- */
81 int
82 mc_tty_normalize_lines_char (const char *ch)
84 char *str2;
85 int res;
87 struct mc_tty_lines_struct {
88 const char *line;
89 int line_code;
90 } const lines_codes[] = {
91 {"\342\224\214", ACS_LRCORNER}, /* ┌ */
92 {"\342\224\220", ACS_LLCORNER}, /* ┐ */
93 {"\342\224\224", ACS_URCORNER}, /* └ */
94 {"\342\224\230", ACS_ULCORNER}, /* ┘ */
95 {"\342\224\234", ACS_LTEE}, /* ├ */
96 {"\342\224\244", ACS_RTEE}, /* ┤ */
97 {"\342\224\254", ACS_TTEE}, /* ┬ */
98 {"\342\224\264", ACS_BTEE}, /* ┴ */
99 {"\342\224\200", ACS_HLINE}, /* ─ */
100 {"\342\224\202", ACS_VLINE}, /* │ */
101 {"\342\224\274", ACS_PLUS}, /* ┼ */
103 {"\342\225\235", ACS_LRCORNER | A_BOLD}, /* ╔ */
104 {"\342\225\232", ACS_LLCORNER | A_BOLD}, /* ╗ */
105 {"\342\225\227", ACS_URCORNER | A_BOLD}, /* ╚ */
106 {"\342\225\224", ACS_ULCORNER | A_BOLD}, /* ╝ */
107 {"\342\225\237", ACS_LTEE | A_BOLD}, /* ╟ */
108 {"\342\225\242", ACS_RTEE | A_BOLD}, /* ╢ */
109 {"\342\225\244", ACS_TTEE | A_BOLD}, /* ╤ */
110 {"\342\225\247", ACS_BTEE | A_BOLD}, /* ╧ */
111 {"\342\225\220", ACS_HLINE | A_BOLD}, /* ═ */
112 {"\342\225\221", ACS_VLINE | A_BOLD}, /* ║ */
114 {NULL, 0}
117 if (ch == NULL)
118 return (int) ' ';
120 for (res = 0; lines_codes[res].line; res++) {
121 if (strcmp (ch, lines_codes[res].line) == 0)
122 return lines_codes[res].line_code;
125 str2 = mc_tty_normalize_from_utf8 (ch);
126 res = g_utf8_get_char_validated (str2, -1);
128 if (res < 0)
129 res = (unsigned char) str2[0];
130 g_free (str2);
132 return res;
135 /* --------------------------------------------------------------------------------------------- */
138 void
139 tty_init (gboolean slow, gboolean ugly_lines)
141 slow_tty = slow;
142 (void) ugly_lines;
144 initscr ();
146 #ifdef HAVE_ESCDELAY
148 * If ncurses exports the ESCDELAY variable, it should be set to
149 * a low value, or you'll experience a delay in processing escape
150 * sequences that are recognized by mc (e.g. Esc-Esc). On the other
151 * hand, making ESCDELAY too small can result in some sequences
152 * (e.g. cursor arrows) being reported as separate keys under heavy
153 * processor load, and this can be a problem if mc hasn't learned
154 * them in the "Learn Keys" dialog. The value is in milliseconds.
156 ESCDELAY = 200;
157 #endif /* HAVE_ESCDELAY */
159 /* use Ctrl-g to generate SIGINT */
160 cur_term->Nttyb.c_cc[VINTR] = CTRL ('g'); /* ^g */
161 tcsetattr (cur_term->Filedes, TCSANOW, &cur_term->Nttyb);
163 tty_start_interrupt_key ();
165 do_enter_ca_mode ();
166 tty_raw_mode ();
167 noecho ();
168 keypad (stdscr, TRUE);
169 nodelay (stdscr, FALSE);
172 void
173 tty_shutdown (void)
175 endwin ();
178 void
179 tty_reset_prog_mode (void)
181 reset_prog_mode ();
184 void
185 tty_reset_shell_mode (void)
187 reset_shell_mode ();
190 void
191 tty_raw_mode (void)
193 raw (); /* FIXME: uneeded? */
194 cbreak ();
197 void
198 tty_noraw_mode (void)
200 nocbreak (); /* FIXME: unneeded? */
201 noraw ();
204 void
205 tty_noecho (void)
207 noecho ();
211 tty_flush_input (void)
213 return flushinp ();
216 void
217 tty_keypad (gboolean set)
219 keypad (stdscr, (bool) set);
222 void
223 tty_nodelay (gboolean set)
225 nodelay (stdscr, (bool) set);
229 tty_baudrate (void)
231 return baudrate ();
235 tty_lowlevel_getch (void)
237 return getch ();
241 tty_reset_screen (void)
243 return endwin ();
246 void
247 tty_touch_screen (void)
249 touchwin (stdscr);
252 void
253 tty_gotoyx (int y, int x)
255 move (y, x);
258 void
259 tty_getyx (int *py, int *px)
261 getyx (stdscr, *py, *px);
264 /* if x < 0 or y < 0, draw line starting from current position */
265 void
266 tty_draw_hline (int y, int x, int ch, int len)
268 if ((chtype) ch == ACS_HLINE)
269 ch = mc_tty_ugly_frm[MC_TTY_FRM_thinhoriz];
271 if ((y >= 0) && (x >= 0))
272 move (y, x);
273 hline (ch, len);
276 /* if x < 0 or y < 0, draw line starting from current position */
277 void
278 tty_draw_vline (int y, int x, int ch, int len)
280 if ((chtype) ch == ACS_VLINE)
281 ch = mc_tty_ugly_frm[MC_TTY_FRM_thinvert];
283 if ((y >= 0) && (x >= 0))
284 move (y, x);
285 vline (ch, len);
288 void
289 tty_fill_region (int y, int x, int rows, int cols, unsigned char ch)
291 int i;
293 for (i = 0; i < rows; i++) {
294 move (y + i, x);
295 hline (ch, cols);
298 move (y, x);
301 void
302 tty_set_alt_charset (gboolean alt_charset)
304 (void) alt_charset;
307 void
308 tty_display_8bit (gboolean what)
310 meta (stdscr, (int) what);
313 void
314 tty_print_char (int c)
316 addch (c);
319 void
320 tty_print_anychar (int c)
322 unsigned char str[6 + 1];
324 if (utf8_display || c > 255) {
325 int res = g_unichar_to_utf8 (c, (char *) str);
326 if (res == 0) {
327 str[0] = '.';
328 str[1] = '\0';
329 } else {
330 str[res] = '\0';
332 addstr (str_term_form ((char *) str));
333 } else {
334 addch (c);
339 void
340 tty_print_alt_char (int c)
342 if ((chtype) c == ACS_VLINE)
343 c = mc_tty_ugly_frm[MC_TTY_FRM_thinvert];
344 else if ((chtype) c == ACS_HLINE)
345 c = mc_tty_ugly_frm[MC_TTY_FRM_thinhoriz];
346 else if ((chtype) c == ACS_LTEE)
347 c = mc_tty_ugly_frm[MC_TTY_FRM_leftmiddle];
348 else if ((chtype) c == ACS_RTEE)
349 c = mc_tty_ugly_frm[MC_TTY_FRM_rightmiddle];
350 else if ((chtype) c == ACS_ULCORNER)
351 c = mc_tty_ugly_frm[MC_TTY_FRM_lefttop];
352 else if ((chtype) c == ACS_LLCORNER)
353 c = mc_tty_ugly_frm[MC_TTY_FRM_leftbottom];
354 else if ((chtype) c == ACS_URCORNER)
355 c = mc_tty_ugly_frm[MC_TTY_FRM_righttop];
356 else if ((chtype) c == ACS_LRCORNER)
357 c = mc_tty_ugly_frm[MC_TTY_FRM_rightbottom];
358 else if ((chtype) c == ACS_PLUS)
359 c = mc_tty_ugly_frm[MC_TTY_FRM_centermiddle];
361 addch (c);
364 void
365 tty_print_string (const char *s)
367 addstr (str_term_form (s));
370 void
371 tty_printf (const char *fmt, ...)
373 va_list args;
375 va_start (args, fmt);
376 vw_printw (stdscr, fmt, args);
377 va_end (args);
380 char *
381 tty_tgetstr (const char *cap)
383 char *unused = NULL;
384 return tgetstr ((char *) cap, &unused);
387 void
388 tty_refresh (void)
390 refresh ();
391 doupdate ();
394 void
395 tty_setup_sigwinch (void (*handler) (int))
397 #if (NCURSES_VERSION_MAJOR >= 4) && defined (SIGWINCH)
398 struct sigaction act, oact;
399 act.sa_handler = handler;
400 sigemptyset (&act.sa_mask);
401 act.sa_flags = 0;
402 #ifdef SA_RESTART
403 act.sa_flags |= SA_RESTART;
404 #endif /* SA_RESTART */
405 sigaction (SIGWINCH, &act, &oact);
406 #endif /* SIGWINCH */
409 void
410 tty_beep (void)
412 beep ();