2
* GRUB -- GRand Unified Bootloader
3
* Copyright (C) 2006,2007,2008 Free Software Foundation, Inc.
5
* GRUB is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, either version 3 of the License, or
8
* (at your option) any later version.
10
* GRUB is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
19
#include <grub/term.h>
20
#include <grub/misc.h>
21
#include <grub/types.h>
23
#include <grub/efi/efi.h>
24
#include <grub/efi/api.h>
25
#include <grub/efi/console.h>
27
static const grub_uint8_t
28
grub_console_standard_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_YELLOW,
29
GRUB_EFI_BACKGROUND_BLACK);
31
static int read_key = -1;
34
map_char (grub_uint32_t c)
36
/* Map some unicode characters to the EFI character. */
39
case GRUB_UNICODE_LEFTARROW:
40
c = GRUB_UNICODE_BLACK_LEFT_TRIANGLE;
42
case GRUB_UNICODE_UPARROW:
43
c = GRUB_UNICODE_BLACK_UP_TRIANGLE;
45
case GRUB_UNICODE_RIGHTARROW:
46
c = GRUB_UNICODE_BLACK_RIGHT_TRIANGLE;
48
case GRUB_UNICODE_DOWNARROW:
49
c = GRUB_UNICODE_BLACK_DOWN_TRIANGLE;
51
case GRUB_UNICODE_HLINE:
52
c = GRUB_UNICODE_LIGHT_HLINE;
54
case GRUB_UNICODE_VLINE:
55
c = GRUB_UNICODE_LIGHT_VLINE;
57
case GRUB_UNICODE_CORNER_UL:
58
c = GRUB_UNICODE_LIGHT_CORNER_UL;
60
case GRUB_UNICODE_CORNER_UR:
61
c = GRUB_UNICODE_LIGHT_CORNER_UR;
63
case GRUB_UNICODE_CORNER_LL:
64
c = GRUB_UNICODE_LIGHT_CORNER_LL;
66
case GRUB_UNICODE_CORNER_LR:
67
c = GRUB_UNICODE_LIGHT_CORNER_LR;
75
grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)),
76
const struct grub_unicode_glyph *c)
78
grub_efi_char16_t str[2 + c->ncomb];
79
grub_efi_simple_text_output_interface_t *o;
82
o = grub_efi_system_table->con_out;
84
/* For now, do not try to use a surrogate pair. */
88
str[0] = (grub_efi_char16_t) map_char (c->base & 0xffff);
90
for (i = 0; i < c->ncomb; i++)
92
str[j++] = c->combining[i].code;
95
/* Should this test be cached? */
96
if ((c->base > 0x7f || c->ncomb)
97
&& efi_call_2 (o->test_string, o, str) != GRUB_EFI_SUCCESS)
100
efi_call_2 (o->output_string, o, str);
104
grub_console_checkkey (struct grub_term_input *term __attribute__ ((unused)))
106
grub_efi_simple_input_interface_t *i;
107
grub_efi_input_key_t key;
108
grub_efi_status_t status;
113
i = grub_efi_system_table->con_in;
114
status = efi_call_2 (i->read_key_stroke, i, &key);
118
case GRUB_EFI_SUCCESS:
124
grub_printf ("scan_code=%x,unicode_char=%x ",
125
(unsigned) key.scan_code,
126
(unsigned) key.unicode_char);
127
grub_gotoxy (xy >> 8, xy & 0xff);
131
case GRUB_EFI_NOT_READY:
132
//grub_printf ("not ready ");
136
//grub_printf ("device error ");
141
if (status == GRUB_EFI_SUCCESS)
143
switch (key.scan_code)
146
read_key = key.unicode_char;
149
read_key = GRUB_TERM_UP;
152
read_key = GRUB_TERM_DOWN;
155
read_key = GRUB_TERM_RIGHT;
158
read_key = GRUB_TERM_LEFT;
161
read_key = GRUB_TERM_HOME;
164
read_key = GRUB_TERM_END;
169
read_key = GRUB_TERM_DC;
199
grub_console_getkey (struct grub_term_input *term)
201
grub_efi_simple_input_interface_t *i;
202
grub_efi_boot_services_t *b;
203
grub_efi_uintn_t index;
204
grub_efi_status_t status;
214
i = grub_efi_system_table->con_in;
215
b = grub_efi_system_table->boot_services;
219
status = efi_call_3 (b->wait_for_event, 1, &(i->wait_for_key), &index);
220
if (status != GRUB_EFI_SUCCESS)
223
grub_console_checkkey (term);
225
while (read_key < 0);
233
grub_console_getwh (struct grub_term_output *term __attribute__ ((unused)))
235
grub_efi_simple_text_output_interface_t *o;
236
grub_efi_uintn_t columns, rows;
238
o = grub_efi_system_table->con_out;
239
if (efi_call_4 (o->query_mode, o, o->mode->mode, &columns, &rows) != GRUB_EFI_SUCCESS)
241
/* Why does this fail? */
246
return ((columns << 8) | rows);
250
grub_console_getxy (struct grub_term_output *term __attribute__ ((unused)))
252
grub_efi_simple_text_output_interface_t *o;
254
o = grub_efi_system_table->con_out;
255
return ((o->mode->cursor_column << 8) | o->mode->cursor_row);
259
grub_console_gotoxy (struct grub_term_output *term __attribute__ ((unused)),
260
grub_uint8_t x, grub_uint8_t y)
262
grub_efi_simple_text_output_interface_t *o;
264
o = grub_efi_system_table->con_out;
265
efi_call_3 (o->set_cursor_position, o, x, y);
269
grub_console_cls (struct grub_term_output *term __attribute__ ((unused)))
271
grub_efi_simple_text_output_interface_t *o;
272
grub_efi_int32_t orig_attr;
274
o = grub_efi_system_table->con_out;
275
orig_attr = o->mode->attribute;
276
efi_call_2 (o->set_attributes, o, GRUB_EFI_BACKGROUND_BLACK);
277
efi_call_1 (o->clear_screen, o);
278
efi_call_2 (o->set_attributes, o, orig_attr);
282
grub_console_setcolorstate (struct grub_term_output *term,
283
grub_term_color_state state)
285
grub_efi_simple_text_output_interface_t *o;
287
o = grub_efi_system_table->con_out;
290
case GRUB_TERM_COLOR_STANDARD:
291
efi_call_2 (o->set_attributes, o, grub_console_standard_color);
293
case GRUB_TERM_COLOR_NORMAL:
294
efi_call_2 (o->set_attributes, o, term->normal_color);
296
case GRUB_TERM_COLOR_HIGHLIGHT:
297
efi_call_2 (o->set_attributes, o, term->highlight_color);
305
grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)),
308
grub_efi_simple_text_output_interface_t *o;
310
o = grub_efi_system_table->con_out;
311
efi_call_2 (o->enable_cursor, o, on);
315
grub_efi_console_init (struct grub_term_output *term)
317
grub_console_setcursor (term, 1);
322
grub_efi_console_fini (struct grub_term_output *term)
324
grub_console_setcursor (term, 0);
328
static struct grub_term_input grub_console_term_input =
331
.checkkey = grub_console_checkkey,
332
.getkey = grub_console_getkey,
335
static struct grub_term_output grub_console_term_output =
338
.init = grub_efi_console_init,
339
.fini = grub_efi_console_fini,
340
.putchar = grub_console_putchar,
341
.getwh = grub_console_getwh,
342
.getxy = grub_console_getxy,
343
.gotoxy = grub_console_gotoxy,
344
.cls = grub_console_cls,
345
.setcolorstate = grub_console_setcolorstate,
346
.setcursor = grub_console_setcursor,
347
.normal_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_LIGHTGRAY,
348
GRUB_EFI_BACKGROUND_BLACK),
349
.highlight_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_BLACK,
350
GRUB_EFI_BACKGROUND_LIGHTGRAY),
351
.flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS
355
grub_console_init (void)
357
/* FIXME: it is necessary to consider the case where no console control
358
is present but the default is already in text mode. */
359
if (! grub_efi_set_text_mode (1))
361
grub_error (GRUB_ERR_BAD_DEVICE, "cannot set text mode");
365
grub_term_register_input ("console", &grub_console_term_input);
366
grub_term_register_output ("console", &grub_console_term_output);
370
grub_console_fini (void)
372
grub_term_unregister_input (&grub_console_term_input);
373
grub_term_unregister_output (&grub_console_term_output);