2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2006,2007,2008,2013 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/>.
20 #include <config-util.h>
22 #include <grub/term.h>
23 #include <grub/misc.h>
24 #include <grub/types.h>
27 #include <grub/emu/console.h>
31 static HANDLE hStdin
, hStdout
;
32 static DWORD orig_mode
;
33 static int saved_orig
;
37 grub_console_putchar (struct grub_term_output
*term
__attribute__ ((unused
)),
38 const struct grub_unicode_glyph
*c
)
44 /* For now, do not try to use a surrogate pair. */
48 str
[0] = (c
->base
& 0xffff);
50 for (i
= 0; i
< c
->ncomb
&& j
+1 < ARRAY_SIZE (str
); i
++)
52 str
[j
++] = grub_unicode_get_comb (c
)[i
].code
;
55 WriteConsole (hStdout
, str
, j
, &written
, NULL
);
58 const unsigned windows_codes
[] =
60 /* 0x21 */ [VK_PRIOR
] = GRUB_TERM_KEY_PPAGE
,
61 /* 0x22 */ [VK_NEXT
] = GRUB_TERM_KEY_NPAGE
,
62 /* 0x23 */ [VK_END
] = GRUB_TERM_KEY_END
,
63 /* 0x24 */ [VK_HOME
] = GRUB_TERM_KEY_HOME
,
64 /* 0x25 */ [VK_LEFT
] = GRUB_TERM_KEY_LEFT
,
65 /* 0x26 */ [VK_UP
] = GRUB_TERM_KEY_UP
,
66 /* 0x27 */ [VK_RIGHT
] = GRUB_TERM_KEY_RIGHT
,
67 /* 0x28 */ [VK_DOWN
] = GRUB_TERM_KEY_DOWN
,
68 /* 0x2e */ [VK_DELETE
] = GRUB_TERM_KEY_DC
,
69 /* 0x70 */ [VK_F1
] = GRUB_TERM_KEY_F1
,
70 /* 0x71 */ [VK_F2
] = GRUB_TERM_KEY_F2
,
71 /* 0x72 */ [VK_F3
] = GRUB_TERM_KEY_F3
,
72 /* 0x73 */ [VK_F4
] = GRUB_TERM_KEY_F4
,
73 /* 0x74 */ [VK_F5
] = GRUB_TERM_KEY_F5
,
74 /* 0x75 */ [VK_F6
] = GRUB_TERM_KEY_F6
,
75 /* 0x76 */ [VK_F7
] = GRUB_TERM_KEY_F7
,
76 /* 0x77 */ [VK_F8
] = GRUB_TERM_KEY_F8
,
77 /* 0x78 */ [VK_F9
] = GRUB_TERM_KEY_F9
,
78 /* 0x79 */ [VK_F10
] = GRUB_TERM_KEY_F10
,
79 /* 0x7a */ [VK_F11
] = GRUB_TERM_KEY_F11
,
80 /* 0x7b */ [VK_F12
] = GRUB_TERM_KEY_F12
,
85 grub_console_getkey (struct grub_term_input
*term
__attribute__ ((unused
)))
93 if (!GetNumberOfConsoleInputEvents (hStdin
, &nev
))
94 return GRUB_TERM_NO_KEY
;
97 return GRUB_TERM_NO_KEY
;
99 if (!ReadConsoleInput (hStdin
, &ir
, 1,
101 return GRUB_TERM_NO_KEY
;
103 if (ir
.EventType
!= KEY_EVENT
)
106 if (!ir
.Event
.KeyEvent
.bKeyDown
)
108 ret
= ir
.Event
.KeyEvent
.uChar
.UnicodeChar
;
111 unsigned kc
= ir
.Event
.KeyEvent
.wVirtualKeyCode
;
112 if (kc
< ARRAY_SIZE (windows_codes
) && windows_codes
[kc
])
113 ret
= windows_codes
[kc
];
116 if (ir
.Event
.KeyEvent
.dwControlKeyState
& SHIFT_PRESSED
)
117 ret
|= GRUB_TERM_SHIFT
;
119 /* Workaround for AltGr bug. */
120 if (ir
.Event
.KeyEvent
.dwControlKeyState
& RIGHT_ALT_PRESSED
)
122 if (ir
.Event
.KeyEvent
.dwControlKeyState
& (LEFT_ALT_PRESSED
| RIGHT_ALT_PRESSED
))
123 ret
|= GRUB_TERM_ALT
;
124 if (ir
.Event
.KeyEvent
.dwControlKeyState
& (LEFT_CTRL_PRESSED
| RIGHT_CTRL_PRESSED
))
125 ret
|= GRUB_TERM_CTRL
;
130 static struct grub_term_coordinate
131 grub_console_getwh (struct grub_term_output
*term
__attribute__ ((unused
)))
133 CONSOLE_SCREEN_BUFFER_INFO csbi
;
138 GetConsoleScreenBufferInfo (hStdout
, &csbi
);
140 return (struct grub_term_coordinate
) { csbi
.dwSize
.X
, csbi
.dwSize
.Y
};
143 static struct grub_term_coordinate
144 grub_console_getxy (struct grub_term_output
*term
__attribute__ ((unused
)))
146 CONSOLE_SCREEN_BUFFER_INFO csbi
;
148 GetConsoleScreenBufferInfo (hStdout
, &csbi
);
150 return (struct grub_term_coordinate
) { csbi
.dwCursorPosition
.X
, csbi
.dwCursorPosition
.Y
};
154 grub_console_gotoxy (struct grub_term_output
*term
__attribute__ ((unused
)),
155 struct grub_term_coordinate pos
)
157 COORD coord
= { pos
.x
, pos
.y
};
159 SetConsoleCursorPosition (hStdout
, coord
);
163 grub_console_cls (struct grub_term_output
*term
)
166 CONSOLE_SCREEN_BUFFER_INFO csbi
;
168 struct grub_unicode_glyph c
=
177 GetConsoleScreenBufferInfo (hStdout
, &csbi
);
179 SetConsoleTextAttribute (hStdout
, 0);
180 grub_console_gotoxy (term
, (struct grub_term_coordinate
) { 0, 0 });
181 tsz
= csbi
.dwSize
.X
* csbi
.dwSize
.Y
;
184 grub_console_putchar (term
, &c
);
186 grub_console_gotoxy (term
, (struct grub_term_coordinate
) { 0, 0 });
187 SetConsoleTextAttribute (hStdout
, csbi
.wAttributes
);
191 grub_console_setcolorstate (struct grub_term_output
*term
192 __attribute__ ((unused
)),
193 grub_term_color_state state
)
198 case GRUB_TERM_COLOR_STANDARD
:
199 SetConsoleTextAttribute (hStdout
, GRUB_TERM_DEFAULT_STANDARD_COLOR
202 case GRUB_TERM_COLOR_NORMAL
:
203 SetConsoleTextAttribute (hStdout
, grub_term_normal_color
& 0x7f);
205 case GRUB_TERM_COLOR_HIGHLIGHT
:
206 SetConsoleTextAttribute (hStdout
, grub_term_highlight_color
& 0x7f);
214 grub_console_setcursor (struct grub_term_output
*term
__attribute__ ((unused
)),
217 CONSOLE_CURSOR_INFO ci
;
220 SetConsoleCursorInfo (hStdout
, &ci
);
224 grub_efi_console_init (struct grub_term_output
*term
)
226 grub_console_setcursor (term
, 1);
231 grub_efi_console_fini (struct grub_term_output
*term
)
233 grub_console_setcursor (term
, 1);
239 grub_console_init_input (struct grub_term_input
*term
)
243 GetConsoleMode (hStdin
, &orig_mode
);
248 SetConsoleMode (hStdin
, orig_mode
& ~ENABLE_ECHO_INPUT
249 & ~ENABLE_LINE_INPUT
& ~ENABLE_PROCESSED_INPUT
);
251 return GRUB_ERR_NONE
;
255 grub_console_fini_input (struct grub_term_input
*term
256 __attribute__ ((unused
)))
258 SetConsoleMode (hStdin
, orig_mode
);
260 return GRUB_ERR_NONE
;
264 static struct grub_term_input grub_console_term_input
=
267 .getkey
= grub_console_getkey
,
268 .init
= grub_console_init_input
,
269 .fini
= grub_console_fini_input
,
272 static struct grub_term_output grub_console_term_output
=
275 .init
= grub_efi_console_init
,
276 .fini
= grub_efi_console_fini
,
277 .putchar
= grub_console_putchar
,
278 .getwh
= grub_console_getwh
,
279 .getxy
= grub_console_getxy
,
280 .gotoxy
= grub_console_gotoxy
,
281 .cls
= grub_console_cls
,
282 .setcolorstate
= grub_console_setcolorstate
,
283 .setcursor
= grub_console_setcursor
,
284 .flags
= GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS
,
285 .progress_update_divisor
= GRUB_PROGRESS_FAST
289 grub_console_init (void)
291 hStdin
= GetStdHandle (STD_INPUT_HANDLE
);
292 hStdout
= GetStdHandle (STD_OUTPUT_HANDLE
);
294 grub_term_register_input ("console", &grub_console_term_input
);
295 grub_term_register_output ("console", &grub_console_term_output
);
299 grub_console_fini (void)
303 SetConsoleMode (hStdin
, orig_mode
);
306 grub_term_unregister_input (&grub_console_term_input
);
307 grub_term_unregister_output (&grub_console_term_output
);