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>
28 grub_console_standard_color
= GRUB_EFI_TEXT_ATTR (GRUB_EFI_YELLOW
,
29 GRUB_EFI_BACKGROUND_BLACK
);
31 grub_console_normal_color
= GRUB_EFI_TEXT_ATTR (GRUB_EFI_LIGHTGRAY
,
32 GRUB_EFI_BACKGROUND_BLACK
);
34 grub_console_highlight_color
= GRUB_EFI_TEXT_ATTR (GRUB_EFI_BLACK
,
35 GRUB_EFI_BACKGROUND_LIGHTGRAY
);
37 static int read_key
= -1;
40 map_char (grub_uint32_t c
)
44 /* Map some unicode characters to the EFI character. */
47 case 0x2190: /* left arrow */
50 case 0x2191: /* up arrow */
53 case 0x2192: /* right arrow */
56 case 0x2193: /* down arrow */
59 case 0x2501: /* horizontal line */
62 case 0x2503: /* vertical line */
65 case 0x250F: /* upper-left corner */
68 case 0x2513: /* upper-right corner */
71 case 0x2517: /* lower-left corner */
74 case 0x251B: /* lower-right corner */
88 grub_console_putchar (grub_uint32_t c
)
90 grub_efi_char16_t str
[2];
91 grub_efi_simple_text_output_interface_t
*o
;
93 o
= grub_efi_system_table
->con_out
;
95 /* For now, do not try to use a surrogate pair. */
99 str
[0] = (grub_efi_char16_t
) map_char (c
& 0xffff);
102 /* Should this test be cached? */
103 if (c
> 0x7f && efi_call_2 (o
->test_string
, o
, str
) != GRUB_EFI_SUCCESS
)
106 efi_call_2 (o
->output_string
, o
, str
);
110 grub_console_getcharwidth (grub_uint32_t c
__attribute__ ((unused
)))
112 /* For now, every printable character has the width 1. */
117 grub_console_checkkey (void)
119 grub_efi_simple_input_interface_t
*i
;
120 grub_efi_input_key_t key
;
121 grub_efi_status_t status
;
126 i
= grub_efi_system_table
->con_in
;
127 status
= efi_call_2 (i
->read_key_stroke
, i
, &key
);
131 case GRUB_EFI_SUCCESS
:
137 grub_printf ("scan_code=%x,unicode_char=%x ",
138 (unsigned) key
.scan_code
,
139 (unsigned) key
.unicode_char
);
140 grub_gotoxy (xy
>> 8, xy
& 0xff);
144 case GRUB_EFI_NOT_READY
:
145 //grub_printf ("not ready ");
149 //grub_printf ("device error ");
154 if (status
== GRUB_EFI_SUCCESS
)
156 switch (key
.scan_code
)
159 read_key
= key
.unicode_char
;
209 grub_console_getkey (void)
211 grub_efi_simple_input_interface_t
*i
;
212 grub_efi_boot_services_t
*b
;
213 grub_efi_uintn_t index
;
214 grub_efi_status_t status
;
224 i
= grub_efi_system_table
->con_in
;
225 b
= grub_efi_system_table
->boot_services
;
229 status
= efi_call_3 (b
->wait_for_event
, 1, &(i
->wait_for_key
), &index
);
230 if (status
!= GRUB_EFI_SUCCESS
)
233 grub_console_checkkey ();
235 while (read_key
< 0);
243 grub_console_getwh (void)
245 grub_efi_simple_text_output_interface_t
*o
;
246 grub_efi_uintn_t columns
, rows
;
248 o
= grub_efi_system_table
->con_out
;
249 if (efi_call_4 (o
->query_mode
, o
, o
->mode
->mode
, &columns
, &rows
) != GRUB_EFI_SUCCESS
)
251 /* Why does this fail? */
256 return ((columns
<< 8) | rows
);
260 grub_console_getxy (void)
262 grub_efi_simple_text_output_interface_t
*o
;
264 o
= grub_efi_system_table
->con_out
;
265 return ((o
->mode
->cursor_column
<< 8) | o
->mode
->cursor_row
);
269 grub_console_gotoxy (grub_uint8_t x
, grub_uint8_t y
)
271 grub_efi_simple_text_output_interface_t
*o
;
273 o
= grub_efi_system_table
->con_out
;
274 efi_call_3 (o
->set_cursor_position
, o
, x
, y
);
278 grub_console_cls (void)
280 grub_efi_simple_text_output_interface_t
*o
;
281 grub_efi_int32_t orig_attr
;
283 o
= grub_efi_system_table
->con_out
;
284 orig_attr
= o
->mode
->attribute
;
285 efi_call_2 (o
->set_attributes
, o
, GRUB_EFI_BACKGROUND_BLACK
);
286 efi_call_1 (o
->clear_screen
, o
);
287 efi_call_2 (o
->set_attributes
, o
, orig_attr
);
291 grub_console_setcolorstate (grub_term_color_state state
)
293 grub_efi_simple_text_output_interface_t
*o
;
295 o
= grub_efi_system_table
->con_out
;
298 case GRUB_TERM_COLOR_STANDARD
:
299 efi_call_2 (o
->set_attributes
, o
, grub_console_standard_color
);
301 case GRUB_TERM_COLOR_NORMAL
:
302 efi_call_2 (o
->set_attributes
, o
, grub_console_normal_color
);
304 case GRUB_TERM_COLOR_HIGHLIGHT
:
305 efi_call_2 (o
->set_attributes
, o
, grub_console_highlight_color
);
313 grub_console_setcolor (grub_uint8_t normal_color
, grub_uint8_t highlight_color
)
315 grub_console_normal_color
= normal_color
;
316 grub_console_highlight_color
= highlight_color
;
320 grub_console_getcolor (grub_uint8_t
*normal_color
, grub_uint8_t
*highlight_color
)
322 *normal_color
= grub_console_normal_color
;
323 *highlight_color
= grub_console_highlight_color
;
327 grub_console_setcursor (int on
)
329 grub_efi_simple_text_output_interface_t
*o
;
331 o
= grub_efi_system_table
->con_out
;
332 efi_call_2 (o
->enable_cursor
, o
, on
);
335 static struct grub_term_input grub_console_term_input
=
338 .checkkey
= grub_console_checkkey
,
339 .getkey
= grub_console_getkey
,
342 static struct grub_term_output grub_console_term_output
=
345 .putchar
= grub_console_putchar
,
346 .getcharwidth
= grub_console_getcharwidth
,
347 .getwh
= grub_console_getwh
,
348 .getxy
= grub_console_getxy
,
349 .gotoxy
= grub_console_gotoxy
,
350 .cls
= grub_console_cls
,
351 .setcolorstate
= grub_console_setcolorstate
,
352 .setcolor
= grub_console_setcolor
,
353 .getcolor
= grub_console_getcolor
,
354 .setcursor
= grub_console_setcursor
,
359 grub_console_init (void)
361 /* FIXME: it is necessary to consider the case where no console control
362 is present but the default is already in text mode. */
363 if (! grub_efi_set_text_mode (1))
365 grub_error (GRUB_ERR_BAD_DEVICE
, "cannot set text mode");
369 grub_term_register_input ("console", &grub_console_term_input
);
370 grub_term_register_output ("console", &grub_console_term_output
);
374 grub_console_fini (void)
376 grub_term_unregister_input (&grub_console_term_input
);
377 grub_term_unregister_output (&grub_console_term_output
);