]> git.proxmox.com Git - grub2.git/blob - grub-core/kern/emu/console.c
merge with mainline
[grub2.git] / grub-core / kern / emu / console.c
1 /* console.c -- Ncurses console for GRUB. */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2003,2005,2007,2008 Free Software Foundation, Inc.
5 *
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.
10 *
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.
15 *
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/>.
18 */
19
20 #include <config.h>
21
22 /* For compatibility. */
23 #ifndef A_NORMAL
24 # define A_NORMAL 0
25 #endif /* ! A_NORMAL */
26 #ifndef A_STANDOUT
27 # define A_STANDOUT 0
28 #endif /* ! A_STANDOUT */
29
30 #include <grub/emu/console.h>
31 #include <grub/term.h>
32 #include <grub/types.h>
33
34 #if defined(HAVE_NCURSES_CURSES_H)
35 # include <ncurses/curses.h>
36 #elif defined(HAVE_NCURSES_H)
37 # include <ncurses.h>
38 #elif defined(HAVE_CURSES_H)
39 # include <curses.h>
40 #endif
41
42 static int grub_console_attr = A_NORMAL;
43
44 grub_uint8_t grub_console_cur_color = 7;
45
46 static const grub_uint8_t grub_console_standard_color = 0x7;
47
48 #define NUM_COLORS 8
49
50 static grub_uint8_t color_map[NUM_COLORS] =
51 {
52 COLOR_BLACK,
53 COLOR_BLUE,
54 COLOR_GREEN,
55 COLOR_CYAN,
56 COLOR_RED,
57 COLOR_MAGENTA,
58 COLOR_YELLOW,
59 COLOR_WHITE
60 };
61
62 static int use_color;
63
64 static void
65 grub_ncurses_putchar (struct grub_term_output *term __attribute__ ((unused)),
66 const struct grub_unicode_glyph *c)
67 {
68 addch (c->base | grub_console_attr);
69 }
70
71 static void
72 grub_ncurses_setcolorstate (struct grub_term_output *term,
73 grub_term_color_state state)
74 {
75 switch (state)
76 {
77 case GRUB_TERM_COLOR_STANDARD:
78 grub_console_cur_color = grub_console_standard_color;
79 grub_console_attr = A_NORMAL;
80 break;
81 case GRUB_TERM_COLOR_NORMAL:
82 grub_console_cur_color = term->normal_color;
83 grub_console_attr = A_NORMAL;
84 break;
85 case GRUB_TERM_COLOR_HIGHLIGHT:
86 grub_console_cur_color = term->highlight_color;
87 grub_console_attr = A_STANDOUT;
88 break;
89 default:
90 break;
91 }
92
93 if (use_color)
94 {
95 grub_uint8_t fg, bg;
96
97 fg = (grub_console_cur_color & 7);
98 bg = (grub_console_cur_color >> 4) & 7;
99
100 grub_console_attr = (grub_console_cur_color & 8) ? A_BOLD : A_NORMAL;
101 color_set ((bg << 3) + fg, 0);
102 }
103 }
104
105 static int saved_char = ERR;
106
107 static int
108 grub_ncurses_checkkey (struct grub_term_input *term __attribute__ ((unused)))
109 {
110 int c;
111
112 /* Check for SAVED_CHAR. This should not be true, because this
113 means checkkey is called twice continuously. */
114 if (saved_char != ERR)
115 return saved_char;
116
117 wtimeout (stdscr, 100);
118 c = getch ();
119 /* If C is not ERR, then put it back in the input queue. */
120 if (c != ERR)
121 {
122 saved_char = c;
123 return c;
124 }
125
126 return -1;
127 }
128
129 static int
130 grub_ncurses_getkey (struct grub_term_input *term __attribute__ ((unused)))
131 {
132 int c;
133
134 /* If checkkey has already got a character, then return it. */
135 if (saved_char != ERR)
136 {
137 c = saved_char;
138 saved_char = ERR;
139 }
140 else
141 {
142 wtimeout (stdscr, -1);
143 c = getch ();
144 }
145
146 switch (c)
147 {
148 case KEY_LEFT:
149 c = GRUB_TERM_LEFT;
150 break;
151
152 case KEY_RIGHT:
153 c = GRUB_TERM_RIGHT;
154 break;
155
156 case KEY_UP:
157 c = GRUB_TERM_UP;
158 break;
159
160 case KEY_DOWN:
161 c = GRUB_TERM_DOWN;
162 break;
163
164 case KEY_IC:
165 c = 24;
166 break;
167
168 case KEY_DC:
169 c = GRUB_TERM_DC;
170 break;
171
172 case KEY_BACKSPACE:
173 /* XXX: For some reason ncurses on xterm does not return
174 KEY_BACKSPACE. */
175 case 127:
176 c = GRUB_TERM_BACKSPACE;
177 break;
178
179 case KEY_HOME:
180 c = GRUB_TERM_HOME;
181 break;
182
183 case KEY_END:
184 c = GRUB_TERM_END;
185 break;
186
187 case KEY_NPAGE:
188 c = GRUB_TERM_NPAGE;
189 break;
190
191 case KEY_PPAGE:
192 c = GRUB_TERM_PPAGE;
193 break;
194 }
195
196 return c;
197 }
198
199 static grub_uint16_t
200 grub_ncurses_getxy (struct grub_term_output *term __attribute__ ((unused)))
201 {
202 int x;
203 int y;
204
205 getyx (stdscr, y, x);
206
207 return (x << 8) | y;
208 }
209
210 static grub_uint16_t
211 grub_ncurses_getwh (struct grub_term_output *term __attribute__ ((unused)))
212 {
213 int x;
214 int y;
215
216 getmaxyx (stdscr, y, x);
217
218 return (x << 8) | y;
219 }
220
221 static void
222 grub_ncurses_gotoxy (struct grub_term_output *term __attribute__ ((unused)),
223 grub_uint8_t x, grub_uint8_t y)
224 {
225 move (y, x);
226 }
227
228 static void
229 grub_ncurses_cls (struct grub_term_output *term __attribute__ ((unused)))
230 {
231 clear ();
232 refresh ();
233 }
234
235 static void
236 grub_ncurses_setcursor (struct grub_term_output *term __attribute__ ((unused)),
237 int on)
238 {
239 curs_set (on ? 1 : 0);
240 }
241
242 static void
243 grub_ncurses_refresh (struct grub_term_output *term __attribute__ ((unused)))
244 {
245 refresh ();
246 }
247
248 static grub_err_t
249 grub_ncurses_init (struct grub_term_output *term __attribute__ ((unused)))
250 {
251 initscr ();
252 raw ();
253 noecho ();
254 scrollok (stdscr, TRUE);
255
256 nonl ();
257 intrflush (stdscr, FALSE);
258 keypad (stdscr, TRUE);
259
260 if (has_colors ())
261 {
262 start_color ();
263
264 if ((COLORS >= NUM_COLORS) && (COLOR_PAIRS >= NUM_COLORS * NUM_COLORS))
265 {
266 int i, j, n;
267
268 n = 0;
269 for (i = 0; i < NUM_COLORS; i++)
270 for (j = 0; j < NUM_COLORS; j++)
271 init_pair(n++, color_map[j], color_map[i]);
272
273 use_color = 1;
274 }
275 }
276
277 return 0;
278 }
279
280 static grub_err_t
281 grub_ncurses_fini (struct grub_term_output *term __attribute__ ((unused)))
282 {
283 endwin ();
284 return 0;
285 }
286
287 \f
288 static struct grub_term_input grub_ncurses_term_input =
289 {
290 .name = "console",
291 .checkkey = grub_ncurses_checkkey,
292 .getkey = grub_ncurses_getkey,
293 };
294
295 static struct grub_term_output grub_ncurses_term_output =
296 {
297 .name = "console",
298 .init = grub_ncurses_init,
299 .fini = grub_ncurses_fini,
300 .putchar = grub_ncurses_putchar,
301 .getxy = grub_ncurses_getxy,
302 .getwh = grub_ncurses_getwh,
303 .gotoxy = grub_ncurses_gotoxy,
304 .cls = grub_ncurses_cls,
305 .setcolorstate = grub_ncurses_setcolorstate,
306 .setcursor = grub_ncurses_setcursor,
307 .refresh = grub_ncurses_refresh,
308 .flags = GRUB_TERM_CODE_TYPE_ASCII
309 };
310
311 void
312 grub_console_init (void)
313 {
314 grub_term_register_output ("console", &grub_ncurses_term_output);
315 grub_term_register_input ("console", &grub_ncurses_term_input);
316 }
317
318 void
319 grub_console_fini (void)
320 {
321 grub_ncurses_fini (&grub_ncurses_term_output);
322 }