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
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "mainwindows.h"
30 #include "term-curses.h"
36 # define COLOR_PAIRS 64
39 #if defined (TIOCGWINSZ) && defined (HAVE_CURSES_RESIZETERM)
40 # define USE_RESIZE_TERM
43 #ifndef _POSIX_VDISABLE
44 # define _POSIX_VDISABLE 0
47 TERM_WINDOW *root_window;
49 static int curs_x, curs_y;
50 static int freeze_refresh;
51 static struct termios old_tio;
53 static int init_curses(void)
55 char ansi_tab[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
62 cbreak(); noecho(); idlok(stdscr, 1);
63 #ifdef HAVE_CURSES_IDCOK
64 /*idcok(stdscr, 1); - disabled currently, causes redrawing problems with NetBSD */
66 intrflush(stdscr, FALSE); nodelay(stdscr, TRUE);
68 /* Disable INTR, QUIT, VDSUSP and SUSP keys */
69 if (tcgetattr(0, &old_tio) == 0) {
70 memcpy(&tio, &old_tio, sizeof(tio));
71 tio.c_cc[VINTR] = _POSIX_VDISABLE;
72 tio.c_cc[VQUIT] = _POSIX_VDISABLE;
74 tio.c_cc[VDSUSP] = _POSIX_VDISABLE;
77 tio.c_cc[VSUSP] = _POSIX_VDISABLE;
79 tcsetattr(0, TCSADRAIN, &tio);
84 else if (term_use_colors)
85 term_use_colors = FALSE;
87 #ifdef HAVE_NCURSES_USE_DEFAULT_COLORS
88 /* this lets us to use the "default" background color for colors <= 7 so
89 background pixmaps etc. show up right */
92 for (num = 1; num < COLOR_PAIRS; num++)
93 init_pair(num, ansi_tab[num & 7], num <= 7 ? -1 : ansi_tab[num >> 3]);
95 init_pair(63, 0, -1); /* hm.. not THAT good idea, but probably more
96 people want dark grey than white on white.. */
98 for (num = 1; num < COLOR_PAIRS; num++)
99 init_pair(num, ansi_tab[num & 7], ansi_tab[num >> 3]);
107 static int term_init_int(void)
117 root_window = g_new0(TERM_WINDOW, 1);
118 root_window->win = stdscr;
125 static void term_deinit_int(void)
127 tcsetattr(0, TCSADRAIN, &old_tio);
130 g_free_and_null(root_window);
135 if (!term_init_int())
138 settings_add_int("lookandfeel", "default_color", 7);
143 void term_deinit(void)
145 term_common_deinit();
149 /* Resize terminal - if width or height is negative,
150 the new size is unknown and should be figured out somehow */
151 void term_resize(int width, int height)
153 #ifdef HAVE_CURSES_RESIZETERM
154 if (width < 0 || height < 0) {
158 #ifdef HAVE_CURSES_RESIZETERM
159 } else if (term_width != width || term_height != height) {
161 term_height = height;
162 resizeterm(term_height, term_width);
167 void term_resize_final(int width, int height)
169 #ifdef HAVE_CURSES_RESIZETERM
170 if (width < 0 || height < 0)
171 mainwindows_recreate();
173 mainwindows_recreate();
177 /* Returns TRUE if terminal has colors */
178 int term_has_colors(void)
183 /* Force the colors on any way you can */
184 void term_force_colors(int set)
186 /* don't do anything with curses */
190 void term_clear(void)
192 term_set_color(root_window, 0);
202 /* Create a new window in terminal */
203 TERM_WINDOW *term_window_create(int x, int y, int width, int height)
207 window = g_new0(TERM_WINDOW, 1);
208 window->x = x; window->y = y;
209 window->width = width; window->height = height;
210 window->win = newwin(height, width, y, x);
211 if (window->win == NULL)
212 g_error("newwin() failed: %d,%d %d,%d", x, y, width, height);
213 idlok(window->win, 1);
218 /* Destroy a terminal window */
219 void term_window_destroy(TERM_WINDOW *window)
225 /* Move/resize a window */
226 void term_window_move(TERM_WINDOW *window, int x, int y,
227 int width, int height)
229 /* some checks to make sure the window is visible in screen,
230 otherwise curses could get nasty and not show our window anymore. */
231 if (width < 1) width = 1;
232 if (height < 1) height = 1;
233 if (x+width > term_width) x = term_width-width;
234 if (y+height > term_height) y = term_height-height;
236 #ifdef HAVE_CURSES_WRESIZE
237 if (window->width != width || window->height != height)
238 wresize(window->win, height, width);
239 if (window->x != x || window->y != y)
240 mvwin(window->win, y, x);
242 if (window->width != width || window->height != height ||
243 window->x != x || window->y != y) {
245 window->win = newwin(height, width, y, x);
246 idlok(window->win, 1);
249 window->x = x; window->y = y;
250 window->width = width; window->height = height;
254 void term_window_clear(TERM_WINDOW *window)
259 /* Scroll window up/down */
260 void term_window_scroll(TERM_WINDOW *window, int count)
262 scrollok(window->win, TRUE);
263 wscrl(window->win, count);
264 scrollok(window->win, FALSE);
267 static int get_attr(int color)
271 if (!term_use_colors)
272 attr = (color & 0x70) ? A_REVERSE : 0;
273 else if ((color & 0xff) == 8 || (color & (0xff | ATTR_RESETFG)) == 0)
274 attr = COLOR_PAIR(63);
275 else if ((color & 0x77) == 0)
278 if (color & ATTR_RESETFG) {
280 color |= settings_get_int("default_color");
282 attr = COLOR_PAIR((color&7) | ((color&0x70)>>1));
285 if ((color & 0x08) || (color & ATTR_BOLD)) attr |= A_BOLD;
286 if (color & ATTR_BLINK) attr |= A_BLINK;
288 if (color & ATTR_UNDERLINE) attr |= A_UNDERLINE;
289 if (color & ATTR_REVERSE) attr |= A_REVERSE;
293 /* Change active color */
294 void term_set_color(TERM_WINDOW *window, int col)
296 wattrset(window->win, get_attr(col));
297 wbkgdset(window->win, ' ' | get_attr(col));
300 void term_move(TERM_WINDOW *window, int x, int y)
302 wmove(window->win, y, x);
305 void term_addch(TERM_WINDOW *window, int chr)
307 waddch(window->win, chr);
310 void term_add_unichar(TERM_WINDOW *window, unichar chr)
317 if (setcchar(&wch, temp, A_NORMAL, 0, NULL) == OK)
318 wadd_wch(window->win, &wch);
321 waddch(window->win, chr);
324 void term_addstr(TERM_WINDOW *window, const char *str)
326 waddstr(window->win, (const char *) str);
329 void term_clrtoeol(TERM_WINDOW *window)
331 wclrtoeol(window->win);
334 void term_move_cursor(int x, int y)
340 void term_refresh_freeze(void)
345 void term_refresh_thaw(void)
347 if (freeze_refresh > 0) {
349 if (freeze_refresh == 0) term_refresh(NULL);
353 void term_refresh(TERM_WINDOW *window)
359 wnoutrefresh(window->win);
361 if (freeze_refresh == 0) {
362 move(curs_y, curs_x);
363 wnoutrefresh(stdscr);
380 kill(getpid(), SIGTSTP);
385 void term_auto_detach(int set)
389 void term_set_input_type(int type)
393 int term_gets(unichar *buffer, int size)
402 for (count = 0; count < size; ) {
404 if (get_wch(&key) == ERR)
406 if ((key = getch()) == ERR)
410 if (key == KEY_RESIZE)
414 buffer[count++] = key;