2009-11-21 Samuel Thibault <samuel.thibault@ens-lyon.org>
[grub2.git] / util / console.c
blob9d8bb1a634140137fc9796940b4358e268b1b451
1 /* console.c -- Ncurses console for GRUB. */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2003,2005,2007,2008 Free Software Foundation, Inc.
6 * GRUB 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 3 of the License, or
9 * (at your option) any later version.
11 * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
20 #include <config.h>
22 #if defined(HAVE_NCURSES_CURSES_H)
23 # include <ncurses/curses.h>
24 #elif defined(HAVE_NCURSES_H)
25 # include <ncurses.h>
26 #elif defined(HAVE_CURSES_H)
27 # include <curses.h>
28 #endif
30 /* For compatibility. */
31 #ifndef A_NORMAL
32 # define A_NORMAL 0
33 #endif /* ! A_NORMAL */
34 #ifndef A_STANDOUT
35 # define A_STANDOUT 0
36 #endif /* ! A_STANDOUT */
38 #include <grub/util/console.h>
39 #include <grub/term.h>
40 #include <grub/types.h>
42 static int grub_console_attr = A_NORMAL;
44 grub_uint8_t grub_console_cur_color = 7;
46 static grub_uint8_t grub_console_standard_color = 0x7;
47 static grub_uint8_t grub_console_normal_color = 0x7;
48 static grub_uint8_t grub_console_highlight_color = 0x70;
50 #define NUM_COLORS 8
52 static grub_uint8_t color_map[NUM_COLORS] =
54 COLOR_BLACK,
55 COLOR_BLUE,
56 COLOR_GREEN,
57 COLOR_CYAN,
58 COLOR_RED,
59 COLOR_MAGENTA,
60 COLOR_YELLOW,
61 COLOR_WHITE
64 static int use_color;
66 static void
67 grub_ncurses_putchar (grub_uint32_t c)
69 /* Better than nothing. */
70 switch (c)
72 case GRUB_TERM_DISP_LEFT:
73 c = '<';
74 break;
76 case GRUB_TERM_DISP_UP:
77 c = '^';
78 break;
80 case GRUB_TERM_DISP_RIGHT:
81 c = '>';
82 break;
84 case GRUB_TERM_DISP_DOWN:
85 c = 'v';
86 break;
88 case GRUB_TERM_DISP_HLINE:
89 c = '-';
90 break;
92 case GRUB_TERM_DISP_VLINE:
93 c = '|';
94 break;
96 case GRUB_TERM_DISP_UL:
97 case GRUB_TERM_DISP_UR:
98 case GRUB_TERM_DISP_LL:
99 case GRUB_TERM_DISP_LR:
100 c = '+';
101 break;
103 default:
104 /* ncurses does not support Unicode. */
105 if (c > 0x7f)
106 c = '?';
107 break;
110 addch (c | grub_console_attr);
113 static grub_ssize_t
114 grub_ncurses_getcharwidth (grub_uint32_t code __attribute__ ((unused)))
116 return 1;
119 static void
120 grub_ncurses_setcolorstate (grub_term_color_state state)
122 switch (state)
124 case GRUB_TERM_COLOR_STANDARD:
125 grub_console_cur_color = grub_console_standard_color;
126 grub_console_attr = A_NORMAL;
127 break;
128 case GRUB_TERM_COLOR_NORMAL:
129 grub_console_cur_color = grub_console_normal_color;
130 grub_console_attr = A_NORMAL;
131 break;
132 case GRUB_TERM_COLOR_HIGHLIGHT:
133 grub_console_cur_color = grub_console_highlight_color;
134 grub_console_attr = A_STANDOUT;
135 break;
136 default:
137 break;
140 if (use_color)
142 grub_uint8_t fg, bg;
144 fg = (grub_console_cur_color & 7);
145 bg = (grub_console_cur_color >> 4) & 7;
147 grub_console_attr = (grub_console_cur_color & 8) ? A_BOLD : A_NORMAL;
148 color_set ((bg << 3) + fg, 0);
152 /* XXX: This function is never called. */
153 static void
154 grub_ncurses_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
156 grub_console_normal_color = normal_color;
157 grub_console_highlight_color = highlight_color;
160 static void
161 grub_ncurses_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
163 *normal_color = grub_console_normal_color;
164 *highlight_color = grub_console_highlight_color;
167 static int saved_char = ERR;
169 static int
170 grub_ncurses_checkkey (void)
172 int c;
174 /* Check for SAVED_CHAR. This should not be true, because this
175 means checkkey is called twice continuously. */
176 if (saved_char != ERR)
177 return saved_char;
179 wtimeout (stdscr, 100);
180 c = getch ();
181 /* If C is not ERR, then put it back in the input queue. */
182 if (c != ERR)
184 saved_char = c;
185 return c;
188 return -1;
191 static int
192 grub_ncurses_getkey (void)
194 int c;
196 /* If checkkey has already got a character, then return it. */
197 if (saved_char != ERR)
199 c = saved_char;
200 saved_char = ERR;
202 else
204 wtimeout (stdscr, -1);
205 c = getch ();
208 switch (c)
210 case KEY_LEFT:
211 c = 2;
212 break;
214 case KEY_RIGHT:
215 c = 6;
216 break;
218 case KEY_UP:
219 c = 16;
220 break;
222 case KEY_DOWN:
223 c = 14;
224 break;
226 case KEY_IC:
227 c = 24;
228 break;
230 case KEY_DC:
231 c = 4;
232 break;
234 case KEY_BACKSPACE:
235 /* XXX: For some reason ncurses on xterm does not return
236 KEY_BACKSPACE. */
237 case 127:
238 c = 8;
239 break;
241 case KEY_HOME:
242 c = 1;
243 break;
245 case KEY_END:
246 c = 5;
247 break;
249 case KEY_NPAGE:
250 c = 3;
251 break;
253 case KEY_PPAGE:
254 c = 7;
255 break;
258 return c;
261 static grub_uint16_t
262 grub_ncurses_getxy (void)
264 int x;
265 int y;
267 getyx (stdscr, y, x);
269 return (x << 8) | y;
272 static grub_uint16_t
273 grub_ncurses_getwh (void)
275 int x;
276 int y;
278 getmaxyx (stdscr, y, x);
280 return (x << 8) | y;
283 static void
284 grub_ncurses_gotoxy (grub_uint8_t x, grub_uint8_t y)
286 move (y, x);
289 static void
290 grub_ncurses_cls (void)
292 clear ();
293 refresh ();
296 static void
297 grub_ncurses_setcursor (int on)
299 curs_set (on ? 1 : 0);
302 static void
303 grub_ncurses_refresh (void)
305 refresh ();
308 static grub_err_t
309 grub_ncurses_init (void)
311 initscr ();
312 raw ();
313 noecho ();
314 scrollok (stdscr, TRUE);
316 nonl ();
317 intrflush (stdscr, FALSE);
318 keypad (stdscr, TRUE);
320 if (has_colors ())
322 start_color ();
324 if ((COLORS >= NUM_COLORS) && (COLOR_PAIRS >= NUM_COLORS * NUM_COLORS))
326 int i, j, n;
328 n = 0;
329 for (i = 0; i < NUM_COLORS; i++)
330 for (j = 0; j < NUM_COLORS; j++)
331 init_pair(n++, color_map[j], color_map[i]);
333 use_color = 1;
337 return 0;
340 static grub_err_t
341 grub_ncurses_fini (void)
343 endwin ();
344 return 0;
348 static struct grub_term_input grub_ncurses_term_input =
350 .name = "console",
351 .checkkey = grub_ncurses_checkkey,
352 .getkey = grub_ncurses_getkey,
355 static struct grub_term_output grub_ncurses_term_output =
357 .name = "console",
358 .init = grub_ncurses_init,
359 .fini = grub_ncurses_fini,
360 .putchar = grub_ncurses_putchar,
361 .getcharwidth = grub_ncurses_getcharwidth,
362 .getxy = grub_ncurses_getxy,
363 .getwh = grub_ncurses_getwh,
364 .gotoxy = grub_ncurses_gotoxy,
365 .cls = grub_ncurses_cls,
366 .setcolorstate = grub_ncurses_setcolorstate,
367 .setcolor = grub_ncurses_setcolor,
368 .getcolor = grub_ncurses_getcolor,
369 .setcursor = grub_ncurses_setcursor,
370 .refresh = grub_ncurses_refresh,
371 .flags = 0,
374 void
375 grub_console_init (void)
377 grub_term_register_output ("console", &grub_ncurses_term_output);
378 grub_term_register_input ("console", &grub_ncurses_term_input);
379 grub_term_set_current_output (&grub_ncurses_term_output);
380 grub_term_set_current_input (&grub_ncurses_term_input);
383 void
384 grub_console_fini (void)
386 grub_ncurses_fini ();