2 Interface to the terminal controlling library.
5 Copyright (C) 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
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,
30 * \brief Source: NCurses-based tty layer of Midnight-commander
39 #include "lib/global.h"
40 #include "lib/strutil.h" /* str_term_form */
46 #include "tty-internal.h" /* mc_tty_normalize_from_utf8() */
48 #include "color-internal.h"
52 /* include at last !!! */
54 #ifdef HAVE_NCURSES_TERM_H
55 #include <ncurses/term.h>
58 #endif /* HAVE_NCURSES_TERM_H */
59 #endif /* WANT_TERM_H */
61 /*** global variables ****************************************************************************/
63 /*** file scope macro definitions ****************************************************************/
65 #if defined(_AIX) && !defined(CTRL)
66 #define CTRL(x) ((x) & 0x1f)
69 /*** global variables ****************************************************************************/
71 /*** file scope type declarations ****************************************************************/
73 /*** file scope variables ************************************************************************/
75 /*** file scope functions ************************************************************************/
76 /* --------------------------------------------------------------------------------------------- */
78 /* --------------------------------------------------------------------------------------------- */
81 tty_setup_sigwinch (void (*handler
) (int))
83 #if (NCURSES_VERSION_MAJOR >= 4) && defined (SIGWINCH)
84 struct sigaction act
, oact
;
85 act
.sa_handler
= handler
;
86 sigemptyset (&act
.sa_mask
);
89 act
.sa_flags
|= SA_RESTART
;
90 #endif /* SA_RESTART */
91 sigaction (SIGWINCH
, &act
, &oact
);
95 /* --------------------------------------------------------------------------------------------- */
98 sigwinch_handler (int dummy
)
102 mc_global
.tty
.winch_flag
= TRUE
;
105 /* --------------------------------------------------------------------------------------------- */
106 /*** public functions ****************************************************************************/
107 /* --------------------------------------------------------------------------------------------- */
110 mc_tty_normalize_lines_char (const char *ch
)
115 struct mc_tty_lines_struct
119 } const lines_codes
[] = {
120 {"\342\224\230", ACS_LRCORNER
}, /* ┌ */
121 {"\342\224\224", ACS_LLCORNER
}, /* └ */
122 {"\342\224\220", ACS_URCORNER
}, /* ┐ */
123 {"\342\224\214", ACS_ULCORNER
}, /* ┘ */
124 {"\342\224\234", ACS_LTEE
}, /* ├ */
125 {"\342\224\244", ACS_RTEE
}, /* ┤ */
126 {"\342\224\254", ACS_TTEE
}, /* ┬ */
127 {"\342\224\264", ACS_BTEE
}, /* ┴ */
128 {"\342\224\200", ACS_HLINE
}, /* ─ */
129 {"\342\224\202", ACS_VLINE
}, /* │ */
130 {"\342\224\274", ACS_PLUS
}, /* ┼ */
132 {"\342\225\235", ACS_LRCORNER
| A_BOLD
}, /* ╔ */
133 {"\342\225\232", ACS_LLCORNER
| A_BOLD
}, /* ╚ */
134 {"\342\225\227", ACS_URCORNER
| A_BOLD
}, /* ╗ */
135 {"\342\225\224", ACS_ULCORNER
| A_BOLD
}, /* ╝ */
136 {"\342\225\237", ACS_LTEE
| A_BOLD
}, /* ╟ */
137 {"\342\225\242", ACS_RTEE
| A_BOLD
}, /* ╢ */
138 {"\342\225\244", ACS_TTEE
| A_BOLD
}, /* ╤ */
139 {"\342\225\247", ACS_BTEE
| A_BOLD
}, /* ╧ */
140 {"\342\225\220", ACS_HLINE
| A_BOLD
}, /* ═ */
141 {"\342\225\221", ACS_VLINE
| A_BOLD
}, /* ║ */
149 for (res
= 0; lines_codes
[res
].line
; res
++)
151 if (strcmp (ch
, lines_codes
[res
].line
) == 0)
152 return lines_codes
[res
].line_code
;
155 str2
= mc_tty_normalize_from_utf8 (ch
);
156 res
= g_utf8_get_char_validated (str2
, -1);
159 res
= (unsigned char) str2
[0];
165 /* --------------------------------------------------------------------------------------------- */
168 tty_init (gboolean mouse_enable
, gboolean is_xterm
)
174 * If ncurses exports the ESCDELAY variable, it should be set to
175 * a low value, or you'll experience a delay in processing escape
176 * sequences that are recognized by mc (e.g. Esc-Esc). On the other
177 * hand, making ESCDELAY too small can result in some sequences
178 * (e.g. cursor arrows) being reported as separate keys under heavy
179 * processor load, and this can be a problem if mc hasn't learned
180 * them in the "Learn Keys" dialog. The value is in milliseconds.
183 #endif /* HAVE_ESCDELAY */
185 /* use Ctrl-g to generate SIGINT */
186 cur_term
->Nttyb
.c_cc
[VINTR
] = CTRL ('g'); /* ^g */
187 /* disable SIGQUIT to allow use Ctrl-\ key */
188 cur_term
->Nttyb
.c_cc
[VQUIT
] = NULL_VALUE
;
189 tcsetattr (cur_term
->Filedes
, TCSANOW
, &cur_term
->Nttyb
);
191 tty_start_interrupt_key ();
194 use_mouse_p
= MOUSE_DISABLED
;
195 tty_init_xterm_support (is_xterm
); /* do it before do_enter_ca_mode() call */
200 keypad (stdscr
, TRUE
);
201 nodelay (stdscr
, FALSE
);
203 tty_setup_sigwinch (sigwinch_handler
);
206 /* --------------------------------------------------------------------------------------------- */
212 tty_reset_shell_mode ();
219 /* --------------------------------------------------------------------------------------------- */
222 tty_reset_prog_mode (void)
227 /* --------------------------------------------------------------------------------------------- */
230 tty_reset_shell_mode (void)
235 /* --------------------------------------------------------------------------------------------- */
240 raw (); /* FIXME: uneeded? */
244 /* --------------------------------------------------------------------------------------------- */
247 tty_noraw_mode (void)
249 nocbreak (); /* FIXME: unneeded? */
253 /* --------------------------------------------------------------------------------------------- */
261 /* --------------------------------------------------------------------------------------------- */
264 tty_flush_input (void)
269 /* --------------------------------------------------------------------------------------------- */
272 tty_keypad (gboolean set
)
274 keypad (stdscr
, (bool) set
);
277 /* --------------------------------------------------------------------------------------------- */
280 tty_nodelay (gboolean set
)
282 nodelay (stdscr
, (bool) set
);
285 /* --------------------------------------------------------------------------------------------- */
293 /* --------------------------------------------------------------------------------------------- */
296 tty_lowlevel_getch (void)
301 /* --------------------------------------------------------------------------------------------- */
304 tty_reset_screen (void)
309 /* --------------------------------------------------------------------------------------------- */
312 tty_touch_screen (void)
317 /* --------------------------------------------------------------------------------------------- */
320 tty_gotoyx (int y
, int x
)
325 /* --------------------------------------------------------------------------------------------- */
328 tty_getyx (int *py
, int *px
)
330 getyx (stdscr
, *py
, *px
);
333 /* --------------------------------------------------------------------------------------------- */
334 /* if x < 0 or y < 0, draw line starting from current position */
337 tty_draw_hline (int y
, int x
, int ch
, int len
)
339 if ((chtype
) ch
== ACS_HLINE
)
340 ch
= mc_tty_frm
[MC_TTY_FRM_HORIZ
];
342 if ((y
>= 0) && (x
>= 0))
347 /* --------------------------------------------------------------------------------------------- */
348 /* if x < 0 or y < 0, draw line starting from current position */
351 tty_draw_vline (int y
, int x
, int ch
, int len
)
353 if ((chtype
) ch
== ACS_VLINE
)
354 ch
= mc_tty_frm
[MC_TTY_FRM_VERT
];
356 if ((y
>= 0) && (x
>= 0))
361 /* --------------------------------------------------------------------------------------------- */
364 tty_fill_region (int y
, int x
, int rows
, int cols
, unsigned char ch
)
388 if (y
+ rows
> LINES
)
393 for (i
= 0; i
< rows
; i
++)
402 /* --------------------------------------------------------------------------------------------- */
405 tty_set_alt_charset (gboolean alt_charset
)
410 /* --------------------------------------------------------------------------------------------- */
413 tty_display_8bit (gboolean what
)
415 meta (stdscr
, (int) what
);
418 /* --------------------------------------------------------------------------------------------- */
421 tty_print_char (int c
)
426 /* --------------------------------------------------------------------------------------------- */
429 tty_print_anychar (int c
)
431 unsigned char str
[6 + 1];
433 if (mc_global
.utf8_display
|| c
> 255)
435 int res
= g_unichar_to_utf8 (c
, (char *) str
);
443 addstr (str_term_form ((char *) str
));
450 /* --------------------------------------------------------------------------------------------- */
453 tty_print_alt_char (int c
, gboolean single
)
455 if ((chtype
) c
== ACS_VLINE
)
456 c
= mc_tty_frm
[single
? MC_TTY_FRM_VERT
: MC_TTY_FRM_DVERT
];
457 else if ((chtype
) c
== ACS_HLINE
)
458 c
= mc_tty_frm
[single
? MC_TTY_FRM_HORIZ
: MC_TTY_FRM_DHORIZ
];
459 else if ((chtype
) c
== ACS_LTEE
)
460 c
= mc_tty_frm
[single
? MC_TTY_FRM_LEFTMIDDLE
: MC_TTY_FRM_DLEFTMIDDLE
];
461 else if ((chtype
) c
== ACS_RTEE
)
462 c
= mc_tty_frm
[single
? MC_TTY_FRM_RIGHTMIDDLE
: MC_TTY_FRM_DRIGHTMIDDLE
];
463 else if ((chtype
) c
== ACS_ULCORNER
)
464 c
= mc_tty_frm
[single
? MC_TTY_FRM_LEFTTOP
: MC_TTY_FRM_DLEFTTOP
];
465 else if ((chtype
) c
== ACS_LLCORNER
)
466 c
= mc_tty_frm
[single
? MC_TTY_FRM_LEFTBOTTOM
: MC_TTY_FRM_DLEFTBOTTOM
];
467 else if ((chtype
) c
== ACS_URCORNER
)
468 c
= mc_tty_frm
[single
? MC_TTY_FRM_RIGHTTOP
: MC_TTY_FRM_DRIGHTTOP
];
469 else if ((chtype
) c
== ACS_LRCORNER
)
470 c
= mc_tty_frm
[single
? MC_TTY_FRM_RIGHTBOTTOM
: MC_TTY_FRM_DRIGHTBOTTOM
];
471 else if ((chtype
) c
== ACS_PLUS
)
472 c
= mc_tty_frm
[MC_TTY_FRM_CROSS
];
477 /* --------------------------------------------------------------------------------------------- */
480 tty_print_string (const char *s
)
482 addstr (str_term_form (s
));
485 /* --------------------------------------------------------------------------------------------- */
488 tty_printf (const char *fmt
, ...)
492 va_start (args
, fmt
);
493 vw_printw (stdscr
, fmt
, args
);
497 /* --------------------------------------------------------------------------------------------- */
500 tty_tgetstr (const char *cap
)
503 return tgetstr ((char *) cap
, &unused
);
506 /* --------------------------------------------------------------------------------------------- */
515 /* --------------------------------------------------------------------------------------------- */
523 /* --------------------------------------------------------------------------------------------- */