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 "../../src/global.h"
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 !!! */
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 /* --------------------------------------------------------------------------------------------- */
75 mc_tty_normalize_lines_char (const char *ch
)
80 struct mc_tty_lines_struct
{
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
}, /* ║ */
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);
122 res
= (unsigned char) str2
[0];
128 /* --------------------------------------------------------------------------------------------- */
132 tty_init (gboolean slow
, gboolean ugly_lines
)
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.
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 ();
161 keypad (stdscr
, TRUE
);
162 nodelay (stdscr
, FALSE
);
172 tty_reset_prog_mode (void)
178 tty_reset_shell_mode (void)
186 raw (); /* FIXME: uneeded? */
191 tty_noraw_mode (void)
193 nocbreak (); /* FIXME: unneeded? */
204 tty_flush_input (void)
210 tty_keypad (gboolean set
)
212 keypad (stdscr
, (bool) set
);
216 tty_nodelay (gboolean set
)
218 nodelay (stdscr
, (bool) set
);
228 tty_lowlevel_getch (void)
234 tty_reset_screen (void)
240 tty_touch_screen (void)
246 tty_gotoyx (int y
, int x
)
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 */
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))
269 /* if x < 0 or y < 0, draw line starting from current position */
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))
282 tty_fill_region (int y
, int x
, int rows
, int cols
, unsigned char ch
)
286 for (i
= 0; i
< rows
; i
++) {
295 tty_set_alt_charset (gboolean alt_charset
)
301 tty_display_8bit (gboolean what
)
303 meta (stdscr
, (int) what
);
307 tty_print_char (int c
)
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
);
325 addstr (str_term_form ((char *) str
));
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
];
358 tty_print_string (const char *s
)
360 addstr (str_term_form (s
));
364 tty_printf (const char *fmt
, ...)
368 va_start (args
, fmt
);
369 vw_printw (stdscr
, fmt
, args
);
374 tty_tgetstr (const char *cap
)
377 return tgetstr ((char *) cap
, &unused
);
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
);
396 act
.sa_flags
|= SA_RESTART
;
397 #endif /* SA_RESTART */
398 sigaction (SIGWINCH
, &act
, &oact
);
399 #endif /* SIGWINCH */