4 Copyright (C) 1999-2001 Timo Sirainen
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include "mainwindows.h"
28 #if defined(USE_NCURSES) && !defined(RENAMED_NCURSES)
37 # define COLOR_PAIRS 64
40 #if defined (TIOCGWINSZ) && defined (HAVE_CURSES_RESIZETERM)
41 # define USE_RESIZE_TERM
44 #ifndef _POSIX_VDISABLE
45 # define _POSIX_VDISABLE 0
54 TERM_WINDOW *root_window;
56 static int curs_x, curs_y;
57 static int freeze_refresh;
58 static struct termios old_tio;
60 static int init_curses(void)
62 char ansi_tab[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
69 cbreak(); noecho(); idlok(stdscr, 1);
70 #ifdef HAVE_CURSES_IDCOK
71 /*idcok(stdscr, 1); - disabled currently, causes redrawing problems with NetBSD */
73 intrflush(stdscr, FALSE); nodelay(stdscr, TRUE);
75 /* Disable INTR, QUIT, VDSUSP and SUSP keys */
76 if (tcgetattr(0, &old_tio) == 0) {
77 memcpy(&tio, &old_tio, sizeof(tio));
78 tio.c_cc[VINTR] = _POSIX_VDISABLE;
79 tio.c_cc[VQUIT] = _POSIX_VDISABLE;
81 tio.c_cc[VDSUSP] = _POSIX_VDISABLE;
84 tio.c_cc[VSUSP] = _POSIX_VDISABLE;
86 tcsetattr(0, TCSADRAIN, &tio);
91 else if (term_use_colors)
92 term_use_colors = FALSE;
94 #ifdef HAVE_NCURSES_USE_DEFAULT_COLORS
95 /* this lets us to use the "default" background color for colors <= 7 so
96 background pixmaps etc. show up right */
99 for (num = 1; num < COLOR_PAIRS; num++)
100 init_pair(num, ansi_tab[num & 7], num <= 7 ? -1 : ansi_tab[num >> 3]);
102 init_pair(63, 0, -1); /* hm.. not THAT good idea, but probably more
103 people want dark grey than white on white.. */
105 for (num = 1; num < COLOR_PAIRS; num++)
106 init_pair(num, ansi_tab[num & 7], ansi_tab[num >> 3]);
114 static int term_init_int(void)
124 root_window = g_new0(TERM_WINDOW, 1);
125 root_window->win = stdscr;
132 static void term_deinit_int(void)
134 tcsetattr(0, TCSADRAIN, &old_tio);
137 g_free_and_null(root_window);
142 if (!term_init_int())
145 settings_add_int("lookandfeel", "default_color", 7);
150 void term_deinit(void)
152 term_common_deinit();
156 /* Resize terminal - if width or height is negative,
157 the new size is unknown and should be figured out somehow */
158 void term_resize(int width, int height)
160 #ifdef HAVE_CURSES_RESIZETERM
161 if (width < 0 || height < 0) {
165 #ifdef HAVE_CURSES_RESIZETERM
166 } else if (term_width != width || term_height != height) {
168 term_height = height;
169 resizeterm(term_height, term_width);
174 void term_resize_final(int width, int height)
176 #ifdef HAVE_CURSES_RESIZETERM
177 if (width < 0 || height < 0)
178 mainwindows_recreate();
180 mainwindows_recreate();
184 /* Returns TRUE if terminal has colors */
185 int term_has_colors(void)
190 /* Force the colors on any way you can */
191 void term_force_colors(int set)
193 /* don't do anything with curses */
197 void term_clear(void)
199 term_set_color(root_window, 0);
209 /* Create a new window in terminal */
210 TERM_WINDOW *term_window_create(int x, int y, int width, int height)
214 window = g_new0(TERM_WINDOW, 1);
215 window->x = x; window->y = y;
216 window->width = width; window->height = height;
217 window->win = newwin(height, width, y, x);
218 if (window->win == NULL)
219 g_error("newwin() failed: %d,%d %d,%d", x, y, width, height);
220 idlok(window->win, 1);
225 /* Destroy a terminal window */
226 void term_window_destroy(TERM_WINDOW *window)
232 /* Move/resize a window */
233 void term_window_move(TERM_WINDOW *window, int x, int y,
234 int width, int height)
236 /* some checks to make sure the window is visible in screen,
237 otherwise curses could get nasty and not show our window anymore. */
238 if (width < 1) width = 1;
239 if (height < 1) height = 1;
240 if (x+width > term_width) x = term_width-width;
241 if (y+height > term_height) y = term_height-height;
243 #ifdef HAVE_CURSES_WRESIZE
244 if (window->width != width || window->height != height)
245 wresize(window->win, height, width);
246 if (window->x != x || window->y != y)
247 mvwin(window->win, y, x);
249 if (window->width != width || window->height != height ||
250 window->x != x || window->y != y) {
252 window->win = newwin(height, width, y, x);
253 idlok(window->win, 1);
256 window->x = x; window->y = y;
257 window->width = width; window->height = height;
261 void term_window_clear(TERM_WINDOW *window)
266 /* Scroll window up/down */
267 void term_window_scroll(TERM_WINDOW *window, int count)
269 scrollok(window->win, TRUE);
270 wscrl(window->win, count);
271 scrollok(window->win, FALSE);
274 static int get_attr(int color)
278 if (!term_use_colors)
279 attr = (color & 0x70) ? A_REVERSE : 0;
280 else if ((color & 0xff) == 8 || (color & (0xff | ATTR_RESETFG)) == 0)
281 attr = COLOR_PAIR(63);
282 else if ((color & 0x77) == 0)
285 if (color & ATTR_RESETFG) {
287 color |= settings_get_int("default_color");
289 attr = COLOR_PAIR((color&7) | ((color&0x70)>>1));
292 if ((color & 0x08) || (color & ATTR_BOLD)) attr |= A_BOLD;
293 if (color & ATTR_BLINK) attr |= A_BLINK;
295 if (color & ATTR_UNDERLINE) attr |= A_UNDERLINE;
296 if (color & ATTR_REVERSE) attr |= A_REVERSE;
300 /* Change active color */
301 void term_set_color(TERM_WINDOW *window, int col)
303 wattrset(window->win, get_attr(col));
304 wbkgdset(window->win, ' ' | get_attr(col));
307 void term_move(TERM_WINDOW *window, int x, int y)
309 wmove(window->win, y, x);
312 void term_addch(TERM_WINDOW *window, char chr)
314 waddch(window->win, chr);
317 void term_add_unichar(TERM_WINDOW *window, unichar chr)
324 if (setcchar(&wch, temp, A_NORMAL, 0, NULL) == OK)
325 wadd_wch(window->win, &wch);
328 waddch(window->win, chr);
331 void term_addstr(TERM_WINDOW *window, const char *str)
333 waddstr(window->win, (const char *) str);
336 void term_clrtoeol(TERM_WINDOW *window)
338 wclrtoeol(window->win);
341 void term_move_cursor(int x, int y)
347 void term_refresh_freeze(void)
352 void term_refresh_thaw(void)
354 if (freeze_refresh > 0) {
356 if (freeze_refresh == 0) term_refresh(NULL);
360 void term_refresh(TERM_WINDOW *window)
363 wnoutrefresh(window->win);
365 if (freeze_refresh == 0) {
366 move(curs_y, curs_x);
367 wnoutrefresh(stdscr);
375 kill(getpid(), SIGTSTP);
380 void term_set_input_type(int type)
384 void term_gets(GArray *buffer, int *line_count)
394 if (get_wch(&key) == ERR)
396 if ((key = getch()) == ERR)
400 if (key == KEY_RESIZE)
404 g_array_append_val(buffer, key);
405 if (key == '\r' || key == '\n')