]> git.proxmox.com Git - grub2.git/blob - grub-core/osdep/windows/emuconsole.c
Lift 255x255 erminal sie restriction to 65535x65535. Also change from
[grub2.git] / grub-core / osdep / windows / emuconsole.c
1 /*
2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2006,2007,2008,2013 Free Software Foundation, Inc.
4 *
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.
9 *
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.
14 *
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/>.
17 */
18
19 #include <config.h>
20 #include <config-util.h>
21
22 #include <grub/term.h>
23 #include <grub/misc.h>
24 #include <grub/types.h>
25 #include <grub/err.h>
26
27 #include <grub/emu/console.h>
28
29 #include <windows.h>
30
31 static HANDLE hStdin, hStdout;
32 static DWORD orig_mode;
33 static int saved_orig;
34
35
36 static void
37 grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)),
38 const struct grub_unicode_glyph *c)
39 {
40 TCHAR str[2 + c->ncomb];
41 unsigned i, j;
42 DWORD written;
43
44 /* For now, do not try to use a surrogate pair. */
45 if (c->base > 0xffff)
46 str[0] = '?';
47 else
48 str[0] = (c->base & 0xffff);
49 j = 1;
50 for (i = 0; i < c->ncomb; i++)
51 if (c->base < 0xffff)
52 str[j++] = grub_unicode_get_comb (c)[i].code;
53 str[j] = 0;
54
55 WriteConsole (hStdout, str, j, &written, NULL);
56 }
57
58 const unsigned windows_codes[] =
59 {
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,
81 };
82
83
84 static int
85 grub_console_getkey (struct grub_term_input *term __attribute__ ((unused)))
86 {
87 while (1)
88 {
89 DWORD nev;
90 INPUT_RECORD ir;
91 int ret;
92
93 if (!GetNumberOfConsoleInputEvents (hStdin, &nev))
94 return GRUB_TERM_NO_KEY;
95
96 if (nev == 0)
97 return GRUB_TERM_NO_KEY;
98
99 if (!ReadConsoleInput (hStdin, &ir, 1,
100 &nev))
101 return GRUB_TERM_NO_KEY;
102
103 if (ir.EventType != KEY_EVENT)
104 continue;
105
106 if (!ir.Event.KeyEvent.bKeyDown)
107 continue;
108 ret = ir.Event.KeyEvent.uChar.UnicodeChar;
109 if (ret == 0)
110 {
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];
116 else
117 continue;
118 if (ir.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED)
119 ret |= GRUB_TERM_SHIFT;
120 }
121 /* Workaround for AltGr bug. */
122 if (ir.Event.KeyEvent.dwControlKeyState & RIGHT_ALT_PRESSED)
123 return ret;
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;
128 return ret;
129 }
130 }
131
132 static struct grub_term_coordinate
133 grub_console_getwh (struct grub_term_output *term __attribute__ ((unused)))
134 {
135 CONSOLE_SCREEN_BUFFER_INFO csbi;
136
137 csbi.dwSize.X = 80;
138 csbi.dwSize.Y = 25;
139
140 GetConsoleScreenBufferInfo (hStdout, &csbi);
141
142 return (struct grub_term_coordinate) { csbi.dwSize.X, csbi.dwSize.Y };
143 }
144
145 static struct grub_term_coordinate
146 grub_console_getxy (struct grub_term_output *term __attribute__ ((unused)))
147 {
148 CONSOLE_SCREEN_BUFFER_INFO csbi;
149
150 GetConsoleScreenBufferInfo (hStdout, &csbi);
151
152 return (struct grub_term_coordinate) { csbi.dwCursorPosition.X, csbi.dwCursorPosition.Y };
153 }
154
155 static void
156 grub_console_gotoxy (struct grub_term_output *term __attribute__ ((unused)),
157 struct grub_term_coordinate pos)
158 {
159 COORD coord = { pos.x, pos.y };
160
161 SetConsoleCursorPosition (hStdout, coord);
162 }
163
164 static void
165 grub_console_cls (struct grub_term_output *term)
166 {
167 int tsz;
168 CONSOLE_SCREEN_BUFFER_INFO csbi;
169
170 struct grub_unicode_glyph c =
171 {
172 .base = ' ',
173 .variant = 0,
174 .attributes = 0,
175 .ncomb = 0,
176 .estimated_width = 1
177 };
178
179 GetConsoleScreenBufferInfo (hStdout, &csbi);
180
181 SetConsoleTextAttribute (hStdout, 0);
182 grub_console_gotoxy (term, (struct grub_term_coordinate) { 0, 0 });
183 tsz = csbi.dwSize.X * csbi.dwSize.Y;
184
185 while (tsz--)
186 grub_console_putchar (term, &c);
187
188 grub_console_gotoxy (term, (struct grub_term_coordinate) { 0, 0 });
189 SetConsoleTextAttribute (hStdout, csbi.wAttributes);
190 }
191
192 static void
193 grub_console_setcolorstate (struct grub_term_output *term
194 __attribute__ ((unused)),
195 grub_term_color_state state)
196 {
197
198
199 switch (state) {
200 case GRUB_TERM_COLOR_STANDARD:
201 SetConsoleTextAttribute (hStdout, GRUB_TERM_DEFAULT_STANDARD_COLOR
202 & 0x7f);
203 break;
204 case GRUB_TERM_COLOR_NORMAL:
205 SetConsoleTextAttribute (hStdout, grub_term_normal_color & 0x7f);
206 break;
207 case GRUB_TERM_COLOR_HIGHLIGHT:
208 SetConsoleTextAttribute (hStdout, grub_term_highlight_color & 0x7f);
209 break;
210 default:
211 break;
212 }
213 }
214
215 static void
216 grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)),
217 int on)
218 {
219 CONSOLE_CURSOR_INFO ci;
220 ci.dwSize = 5;
221 ci.bVisible = on;
222 SetConsoleCursorInfo (hStdout, &ci);
223 }
224
225 static grub_err_t
226 grub_efi_console_init (struct grub_term_output *term)
227 {
228 grub_console_setcursor (term, 1);
229 return 0;
230 }
231
232 static grub_err_t
233 grub_efi_console_fini (struct grub_term_output *term)
234 {
235 grub_console_setcursor (term, 1);
236 return 0;
237 }
238
239
240 static grub_err_t
241 grub_console_init_input (struct grub_term_input *term)
242 {
243 if (!saved_orig)
244 {
245 GetConsoleMode (hStdin, &orig_mode);
246 }
247
248 saved_orig = 1;
249
250 SetConsoleMode (hStdin, orig_mode & ~ENABLE_ECHO_INPUT
251 & ~ENABLE_LINE_INPUT & ~ENABLE_PROCESSED_INPUT);
252
253 return GRUB_ERR_NONE;
254 }
255
256 static grub_err_t
257 grub_console_fini_input (struct grub_term_input *term
258 __attribute__ ((unused)))
259 {
260 SetConsoleMode (hStdin, orig_mode);
261 saved_orig = 0;
262 return GRUB_ERR_NONE;
263 }
264
265
266 static struct grub_term_input grub_console_term_input =
267 {
268 .name = "console",
269 .getkey = grub_console_getkey,
270 .init = grub_console_init_input,
271 .fini = grub_console_fini_input,
272 };
273
274 static struct grub_term_output grub_console_term_output =
275 {
276 .name = "console",
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
287 };
288
289 void
290 grub_console_init (void)
291 {
292 hStdin = GetStdHandle (STD_INPUT_HANDLE);
293 hStdout = GetStdHandle (STD_OUTPUT_HANDLE);
294
295 grub_term_register_input ("console", &grub_console_term_input);
296 grub_term_register_output ("console", &grub_console_term_output);
297 }
298
299 void
300 grub_console_fini (void)
301 {
302 if (saved_orig)
303 {
304 SetConsoleMode (hStdin, orig_mode);
305 saved_orig = 0;
306 }
307 grub_term_unregister_input (&grub_console_term_input);
308 grub_term_unregister_output (&grub_console_term_output);
309 }