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
)
40 TCHAR str
[2 + c
->ncomb
];
44 /* For now, do not try to use a surrogate pair. */
48 str
[0] = (c
->base
& 0xffff);
50 for (i
= 0; i
< c
->ncomb
; 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 if (ir
.Event
.KeyEvent
.wVirtualKeyCode
>= 0
112 && ir
.Event
.KeyEvent
.wVirtualKeyCode
113 < ARRAY_SIZE (windows_codes
)
114 && windows_codes
[(int) ir
.Event
.KeyEvent
.wVirtualKeyCode
])
115 ret
= windows_codes
[(int) ir
.Event
.KeyEvent
.wVirtualKeyCode
];
118 if (ir
.Event
.KeyEvent
.dwControlKeyState
& SHIFT_PRESSED
)
119 ret
|= GRUB_TERM_SHIFT
;
121 /* Workaround for AltGr bug. */
122 if (ir
.Event
.KeyEvent
.dwControlKeyState
& RIGHT_ALT_PRESSED
)
124 if (ir
.Event
.KeyEvent
.dwControlKeyState
& (LEFT_ALT_PRESSED
| RIGHT_ALT_PRESSED
))
125 ret
|= GRUB_TERM_ALT
;
126 if (ir
.Event
.KeyEvent
.dwControlKeyState
& (LEFT_CTRL_PRESSED
| RIGHT_CTRL_PRESSED
))
127 ret
|= GRUB_TERM_CTRL
;
132 static struct grub_term_coordinate
133 grub_console_getwh (struct grub_term_output
*term
__attribute__ ((unused
)))
135 CONSOLE_SCREEN_BUFFER_INFO csbi
;
140 GetConsoleScreenBufferInfo (hStdout
, &csbi
);
142 return (struct grub_term_coordinate
) { csbi
.dwSize
.X
, csbi
.dwSize
.Y
};
145 static struct grub_term_coordinate
146 grub_console_getxy (struct grub_term_output
*term
__attribute__ ((unused
)))
148 CONSOLE_SCREEN_BUFFER_INFO csbi
;
150 GetConsoleScreenBufferInfo (hStdout
, &csbi
);
152 return (struct grub_term_coordinate
) { csbi
.dwCursorPosition
.X
, csbi
.dwCursorPosition
.Y
};
156 grub_console_gotoxy (struct grub_term_output
*term
__attribute__ ((unused
)),
157 struct grub_term_coordinate pos
)
159 COORD coord
= { pos
.x
, pos
.y
};
161 SetConsoleCursorPosition (hStdout
, coord
);
165 grub_console_cls (struct grub_term_output
*term
)
168 CONSOLE_SCREEN_BUFFER_INFO csbi
;
170 struct grub_unicode_glyph c
=
179 GetConsoleScreenBufferInfo (hStdout
, &csbi
);
181 SetConsoleTextAttribute (hStdout
, 0);
182 grub_console_gotoxy (term
, (struct grub_term_coordinate
) { 0, 0 });
183 tsz
= csbi
.dwSize
.X
* csbi
.dwSize
.Y
;
186 grub_console_putchar (term
, &c
);
188 grub_console_gotoxy (term
, (struct grub_term_coordinate
) { 0, 0 });
189 SetConsoleTextAttribute (hStdout
, csbi
.wAttributes
);
193 grub_console_setcolorstate (struct grub_term_output
*term
194 __attribute__ ((unused
)),
195 grub_term_color_state state
)
200 case GRUB_TERM_COLOR_STANDARD
:
201 SetConsoleTextAttribute (hStdout
, GRUB_TERM_DEFAULT_STANDARD_COLOR
204 case GRUB_TERM_COLOR_NORMAL
:
205 SetConsoleTextAttribute (hStdout
, grub_term_normal_color
& 0x7f);
207 case GRUB_TERM_COLOR_HIGHLIGHT
:
208 SetConsoleTextAttribute (hStdout
, grub_term_highlight_color
& 0x7f);
216 grub_console_setcursor (struct grub_term_output
*term
__attribute__ ((unused
)),
219 CONSOLE_CURSOR_INFO ci
;
222 SetConsoleCursorInfo (hStdout
, &ci
);
226 grub_efi_console_init (struct grub_term_output
*term
)
228 grub_console_setcursor (term
, 1);
233 grub_efi_console_fini (struct grub_term_output
*term
)
235 grub_console_setcursor (term
, 1);
241 grub_console_init_input (struct grub_term_input
*term
)
245 GetConsoleMode (hStdin
, &orig_mode
);
250 SetConsoleMode (hStdin
, orig_mode
& ~ENABLE_ECHO_INPUT
251 & ~ENABLE_LINE_INPUT
& ~ENABLE_PROCESSED_INPUT
);
253 return GRUB_ERR_NONE
;
257 grub_console_fini_input (struct grub_term_input
*term
258 __attribute__ ((unused
)))
260 SetConsoleMode (hStdin
, orig_mode
);
262 return GRUB_ERR_NONE
;
266 static struct grub_term_input grub_console_term_input
=
269 .getkey
= grub_console_getkey
,
270 .init
= grub_console_init_input
,
271 .fini
= grub_console_fini_input
,
274 static struct grub_term_output grub_console_term_output
=
277 .init
= grub_efi_console_init
,
278 .fini
= grub_efi_console_fini
,
279 .putchar
= grub_console_putchar
,
280 .getwh
= grub_console_getwh
,
281 .getxy
= grub_console_getxy
,
282 .gotoxy
= grub_console_gotoxy
,
283 .cls
= grub_console_cls
,
284 .setcolorstate
= grub_console_setcolorstate
,
285 .setcursor
= grub_console_setcursor
,
286 .flags
= GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS
290 grub_console_init (void)
292 hStdin
= GetStdHandle (STD_INPUT_HANDLE
);
293 hStdout
= GetStdHandle (STD_OUTPUT_HANDLE
);
295 grub_term_register_input ("console", &grub_console_term_input
);
296 grub_term_register_output ("console", &grub_console_term_output
);
300 grub_console_fini (void)
304 SetConsoleMode (hStdin
, orig_mode
);
307 grub_term_unregister_input (&grub_console_term_input
);
308 grub_term_unregister_output (&grub_console_term_output
);