Reduced fragment size.
[wine/multimedia.git] / console / ncurses.c
blob84a4f210377e723c1e47d9a18325a28a4a19866c
1 /* ncurses.c */
2 /* Copyright 1999 - Joseph Pranevich */
4 #include <stdio.h>
5 #include "config.h"
6 #include "console.h" /* Must define WINE_NCURSES */
8 #ifdef WINE_NCURSES
10 /* This is the console driver for systems that support the ncurses
11 interface.
14 /* Actually, this should work for curses, as well. But there may be
15 individual functions that are unsupported in plain curses or other
16 variants. Those should be detected and special-cased by autoconf.
19 /* When creating new drivers, you need to assign all the functions that
20 that driver supports into the driver struct. If it is a supplementary
21 driver, it should make sure to perserve the old values.
24 #include "debug.h"
25 #include "options.h"
27 #undef ERR /* Use ncurses's err() */
28 #ifdef HAVE_NCURSES_H
29 # include <ncurses.h>
30 #else
31 # ifdef HAVE_CURSES_H
32 # include <curses.h>
33 # endif
34 #endif
36 SCREEN *ncurses_screen;
38 static int get_color_pair(int fg_color, int bg_color);
40 const char *color_names[] = {"null", "black", "blue", "green",
41 "cyan", "magenta", "brown", "red", "light gray", "dark gray",
42 "light blue", "light green", "light red", "light magenta",
43 "light cyan", "yellow", "white"};
45 void NCURSES_Start()
47 /* This should be the root driver so we can ignore anything
48 already in the struct. */
50 driver.norefresh = FALSE;
52 driver.init = NCURSES_Init;
53 driver.write = NCURSES_Write;
54 driver.close = NCURSES_Close;
55 driver.moveCursor = NCURSES_MoveCursor;
56 driver.getCursorPosition = NCURSES_GetCursorPosition;
57 driver.getCharacterAtCursor = NCURSES_GetCharacterAtCursor;
58 driver.clearScreen = NCURSES_ClearScreen;
59 driver.allocColor = NCURSES_AllocColor;
60 #ifdef HAVE_GETBKGD
61 driver.setBackgroundColor = NCURSES_SetBackgroundColor;
62 #endif
63 #ifdef HAVE_RESIZETERM
64 driver.notifyResizeScreen = NCURSES_NotifyResizeScreen;
65 #endif /* HAVE_RESIZETERM */
67 driver.checkForKeystroke = NCURSES_CheckForKeystroke;
68 driver.getKeystroke = NCURSES_GetKeystroke;
70 driver.refresh = NCURSES_Refresh;
73 void NCURSES_Init()
75 char terminal_type[80];
77 PROFILE_GetWineIniString("console", "TerminalType",
78 "xterm", terminal_type, 79);
80 ncurses_screen = newterm(terminal_type, driver.console_out,
81 driver.console_in);
82 set_term(ncurses_screen);
83 start_color();
84 raw();
85 noecho();
86 nonl();
87 intrflush(stdscr, FALSE);
88 keypad(stdscr, TRUE);
89 nodelay(stdscr, TRUE);
92 void NCURSES_Write(char output, int fg, int bg, int attribute)
94 char row, col;
95 int pair;
97 if (!fg)
98 fg = COLOR_WHITE; /* Default */
100 if (!bg)
101 bg = COLOR_BLACK; /* Default */
103 pair = get_color_pair(fg, bg);
105 if (waddch(stdscr, output | COLOR_PAIR(pair)) == ERR)
107 NCURSES_GetCursorPosition(&row, &col);
108 FIXME(console, "NCURSES: waddch() failed at %d, %d.\n", row, col);
112 void NCURSES_Close()
114 endwin();
117 void NCURSES_GetKeystroke(char *scan, char *ascii)
119 while (!NCURSES_CheckForKeystroke(scan, ascii))
120 {} /* Wait until keystroke is detected */
122 /* When it is detected, we will already have the right value
123 in scan and ascii, but we need to take this keystroke
124 out of the buffer. */
125 wgetch(stdscr);
128 int NCURSES_CheckForKeystroke(char *scan, char *ascii)
130 /* We don't currently support scan codes here */
131 /* FIXME */
132 int temp;
133 temp = wgetch(stdscr);
134 if (temp == ERR)
136 return FALSE;
138 else
140 ungetch(temp); /* Keystroke not removed from buffer */
141 *ascii = (char) temp;
142 return TRUE;
146 void NCURSES_MoveCursor(char row, char col)
148 if (wmove(stdscr, row, col) == ERR)
149 FIXME(console, "NCURSES: wmove() failed to %d, %d.\n", row, col);
152 void NCURSES_GetCursorPosition(char *row, char *col)
154 int trow, tcol;
156 getyx(stdscr, trow, tcol); /* MACRO, no need to pass pointer */
158 *row = (char) trow;
159 *col = (char) tcol;
162 void NCURSES_GetCharacterAtCursor(char *ch, int *fg_color, int
163 *bg_color, int *attribute)
165 /* If any of the pointers are NULL, ignore them */
166 /* We will eventually have to convert the color data */
167 if (ch)
168 *ch = (char) winch(stdscr);
169 if (fg_color)
170 *fg_color = WINE_WHITE;
171 if (bg_color)
172 *bg_color = WINE_BLACK;
173 if (attribute)
174 *attribute = 0;
177 void NCURSES_Refresh()
179 wrefresh(stdscr);
182 void NCURSES_ClearScreen()
184 werase(stdscr);
187 int NCURSES_AllocColor(int color)
189 /* Currently support only internal colors */
190 switch (color)
192 case WINE_BLACK: return COLOR_BLACK;
193 case WINE_WHITE: return COLOR_WHITE;
194 case WINE_RED: return COLOR_RED;
195 case WINE_GREEN: return COLOR_GREEN;
196 case WINE_YELLOW: return COLOR_YELLOW;
197 case WINE_BLUE: return COLOR_BLUE;
198 case WINE_MAGENTA: return COLOR_MAGENTA;
199 case WINE_CYAN: return COLOR_CYAN;
202 FIXME(console, "Unable to allocate color %d (%s)\n", color,
203 color_names[color]);
205 /* Don't allocate a color... yet */
206 return 0;
209 void NCURSES_SetBackgroundColor(int fg, int bg)
211 int pair;
213 pair = get_color_pair(fg, bg);
215 wbkgd(stdscr, COLOR_PAIR(pair));
218 #ifdef HAVE_GETBKGD
219 void NCURSES_GetBackgroundColor(int *fg, int *bg)
221 chtype background;
222 short pair, sfg, sbg;
224 background = getbkgd(stdscr);
226 pair = (!A_CHARTEXT & background);
228 pair_content(pair, &sfg, &sbg);
230 *fg = sfg;
231 *bg = sbg;
233 #endif /* HAVE_GETBKGD */
235 #ifdef HAVE_RESIZETERM
237 void NCURSES_NotifyResizeScreen(int x, int y)
239 /* Note: This function gets called *after* another driver in the chain
240 calls ResizeScreen(). It is meant to resize the ncurses internal
241 data structures to know about the new window dimensions. */
243 TRACE(console, "Terminal resized to y: %d, x: %d\n", y, x);
245 resizeterm(y, x);
248 #endif /* HAVE_RESIZETERM */
250 static int get_color_pair(int fg_color, int bg_color)
252 /* ncurses internally uses "color pairs" in addition to the "pallet" */
253 /* This isn't the best way to do this. Or even close */
255 static int current = 0;
256 static int fg[255]; /* 16 x 16 is enough */
257 static int bg[255];
258 int x;
260 /* The first pair is hardwired into ncurses */
261 fg[0] = COLOR_WHITE;
262 bg[0] = COLOR_BLACK;
264 for (x = 0; x <= current; x++)
266 if ((fg_color == fg[x]) && (bg_color == bg[x]))
268 TRACE(console, "Color pair: already allocated\n");
269 return x;
273 /* Need to allocate new color */
274 current++;
275 fg[current] = fg_color;
276 bg[current] = bg_color;
277 TRACE(console, "Color pair: allocated.\n");
278 return init_pair(current, fg_color, bg_color);
281 #endif /* WINE_NCURSES */