* grub-core/osdep/windows/emuconsole.c: New file.
This commit is contained in:
parent
d9d68ef020
commit
69ca587652
5 changed files with 318 additions and 1 deletions
|
@ -1,3 +1,7 @@
|
|||
2013-10-14 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/osdep/windows/emuconsole.c: New file.
|
||||
|
||||
2013-10-14 Andrey Borzenkov <arvidjaar@gmail.com>
|
||||
|
||||
* conf/Makefile.extra-dist: Add osdep/*/init.c
|
||||
|
|
|
@ -252,7 +252,9 @@ kernel = {
|
|||
emu = kern/emu/mm.c;
|
||||
emu = kern/emu/time.c;
|
||||
emu = kern/emu/cache.c;
|
||||
emu = term/emu/console.c;
|
||||
emu = osdep/emuconsole.c;
|
||||
extra_dist = osdep/unix/emuconsole.c;
|
||||
extra_dist = osdep/windows/emuconsole.c;
|
||||
emu = osdep/sleep.c;
|
||||
emu = osdep/init.c;
|
||||
|
||||
|
|
5
grub-core/osdep/emuconsole.c
Normal file
5
grub-core/osdep/emuconsole.c
Normal file
|
@ -0,0 +1,5 @@
|
|||
#if defined (__MINGW32__) && !defined (__CYGWIN__)
|
||||
#include "windows/emuconsole.c"
|
||||
#else
|
||||
#include "unix/emuconsole.c"
|
||||
#endif
|
306
grub-core/osdep/windows/emuconsole.c
Normal file
306
grub-core/osdep/windows/emuconsole.c
Normal file
|
@ -0,0 +1,306 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2006,2007,2008,2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/term.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
|
||||
#include <grub/emu/console.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
static HANDLE hStdin, hStdout;
|
||||
static DWORD orig_mode;
|
||||
static int saved_orig;
|
||||
|
||||
|
||||
static void
|
||||
grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)),
|
||||
const struct grub_unicode_glyph *c)
|
||||
{
|
||||
TCHAR str[2 + c->ncomb];
|
||||
unsigned i, j;
|
||||
DWORD written;
|
||||
|
||||
/* For now, do not try to use a surrogate pair. */
|
||||
if (c->base > 0xffff)
|
||||
str[0] = '?';
|
||||
else
|
||||
str[0] = (c->base & 0xffff);
|
||||
j = 1;
|
||||
for (i = 0; i < c->ncomb; i++)
|
||||
if (c->base < 0xffff)
|
||||
str[j++] = grub_unicode_get_comb (c)[i].code;
|
||||
str[j] = 0;
|
||||
|
||||
WriteConsole (hStdout, str, j, &written, NULL);
|
||||
}
|
||||
|
||||
const unsigned windows_codes[] =
|
||||
{
|
||||
/* 0x21 */ [VK_PRIOR] = GRUB_TERM_KEY_PPAGE,
|
||||
/* 0x22 */ [VK_NEXT] = GRUB_TERM_KEY_NPAGE,
|
||||
/* 0x23 */ [VK_END] = GRUB_TERM_KEY_END,
|
||||
/* 0x24 */ [VK_HOME] = GRUB_TERM_KEY_HOME,
|
||||
/* 0x25 */ [VK_LEFT] = GRUB_TERM_KEY_LEFT,
|
||||
/* 0x26 */ [VK_UP] = GRUB_TERM_KEY_UP,
|
||||
/* 0x27 */ [VK_RIGHT] = GRUB_TERM_KEY_RIGHT,
|
||||
/* 0x28 */ [VK_DOWN] = GRUB_TERM_KEY_DOWN,
|
||||
/* 0x2e */ [VK_DELETE] = GRUB_TERM_KEY_DC,
|
||||
/* 0x70 */ [VK_F1] = GRUB_TERM_KEY_F1,
|
||||
/* 0x71 */ [VK_F2] = GRUB_TERM_KEY_F2,
|
||||
/* 0x72 */ [VK_F3] = GRUB_TERM_KEY_F3,
|
||||
/* 0x73 */ [VK_F4] = GRUB_TERM_KEY_F4,
|
||||
/* 0x74 */ [VK_F5] = GRUB_TERM_KEY_F5,
|
||||
/* 0x75 */ [VK_F6] = GRUB_TERM_KEY_F6,
|
||||
/* 0x76 */ [VK_F7] = GRUB_TERM_KEY_F7,
|
||||
/* 0x77 */ [VK_F8] = GRUB_TERM_KEY_F8,
|
||||
/* 0x78 */ [VK_F9] = GRUB_TERM_KEY_F9,
|
||||
/* 0x79 */ [VK_F10] = GRUB_TERM_KEY_F10,
|
||||
/* 0x7a */ [VK_F11] = GRUB_TERM_KEY_F11,
|
||||
/* 0x7b */ [VK_F12] = GRUB_TERM_KEY_F12,
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
grub_console_getkey (struct grub_term_input *term __attribute__ ((unused)))
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
DWORD nev;
|
||||
INPUT_RECORD ir;
|
||||
int ret;
|
||||
|
||||
if (!GetNumberOfConsoleInputEvents (hStdin, &nev))
|
||||
return GRUB_TERM_NO_KEY;
|
||||
|
||||
if (nev == 0)
|
||||
return GRUB_TERM_NO_KEY;
|
||||
|
||||
if (!ReadConsoleInput (hStdin, &ir, 1,
|
||||
&nev))
|
||||
return GRUB_TERM_NO_KEY;
|
||||
|
||||
if (ir.EventType != KEY_EVENT)
|
||||
continue;
|
||||
|
||||
if (!ir.Event.KeyEvent.bKeyDown)
|
||||
continue;
|
||||
ret = ir.Event.KeyEvent.uChar.UnicodeChar;
|
||||
if (ret == 0)
|
||||
{
|
||||
if (ir.Event.KeyEvent.wVirtualKeyCode >= 0
|
||||
&& ir.Event.KeyEvent.wVirtualKeyCode
|
||||
< ARRAY_SIZE (windows_codes)
|
||||
&& windows_codes[(int) ir.Event.KeyEvent.wVirtualKeyCode])
|
||||
ret = windows_codes[(int) ir.Event.KeyEvent.wVirtualKeyCode];
|
||||
else
|
||||
continue;
|
||||
if (ir.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED)
|
||||
ret |= GRUB_TERM_SHIFT;
|
||||
}
|
||||
/* Workaround for AltGr bug. */
|
||||
if (ir.Event.KeyEvent.dwControlKeyState & RIGHT_ALT_PRESSED)
|
||||
return ret;
|
||||
if (ir.Event.KeyEvent.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
|
||||
ret |= GRUB_TERM_ALT;
|
||||
if (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
|
||||
ret |= GRUB_TERM_CTRL;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
static grub_uint16_t
|
||||
grub_console_getwh (struct grub_term_output *term __attribute__ ((unused)))
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
|
||||
csbi.dwSize.X = 80;
|
||||
csbi.dwSize.Y = 25;
|
||||
|
||||
GetConsoleScreenBufferInfo (hStdout, &csbi);
|
||||
|
||||
return ((csbi.dwSize.X << 8) | csbi.dwSize.Y);
|
||||
}
|
||||
|
||||
static grub_uint16_t
|
||||
grub_console_getxy (struct grub_term_output *term __attribute__ ((unused)))
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
|
||||
GetConsoleScreenBufferInfo (hStdout, &csbi);
|
||||
|
||||
return ((csbi.dwCursorPosition.X << 8) | csbi.dwCursorPosition.Y);
|
||||
}
|
||||
|
||||
static void
|
||||
grub_console_gotoxy (struct grub_term_output *term __attribute__ ((unused)),
|
||||
grub_uint8_t x, grub_uint8_t y)
|
||||
{
|
||||
COORD coord = { x, y };
|
||||
|
||||
SetConsoleCursorPosition (hStdout, coord);
|
||||
}
|
||||
|
||||
static void
|
||||
grub_console_cls (struct grub_term_output *term)
|
||||
{
|
||||
int tsz;
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
|
||||
struct grub_unicode_glyph c =
|
||||
{
|
||||
.base = ' ',
|
||||
.variant = 0,
|
||||
.attributes = 0,
|
||||
.ncomb = 0,
|
||||
.estimated_width = 1
|
||||
};
|
||||
|
||||
GetConsoleScreenBufferInfo (hStdout, &csbi);
|
||||
|
||||
SetConsoleTextAttribute (hStdout, 0);
|
||||
grub_console_gotoxy (term, 0, 0);
|
||||
tsz = csbi.dwSize.X * csbi.dwSize.Y;
|
||||
|
||||
while (tsz--)
|
||||
grub_console_putchar (term, &c);
|
||||
|
||||
grub_console_gotoxy (term, 0, 0);
|
||||
SetConsoleTextAttribute (hStdout, csbi.wAttributes);
|
||||
}
|
||||
|
||||
static void
|
||||
grub_console_setcolorstate (struct grub_term_output *term
|
||||
__attribute__ ((unused)),
|
||||
grub_term_color_state state)
|
||||
{
|
||||
|
||||
|
||||
switch (state) {
|
||||
case GRUB_TERM_COLOR_STANDARD:
|
||||
SetConsoleTextAttribute (hStdout, GRUB_TERM_DEFAULT_STANDARD_COLOR
|
||||
& 0x7f);
|
||||
break;
|
||||
case GRUB_TERM_COLOR_NORMAL:
|
||||
SetConsoleTextAttribute (hStdout, grub_term_normal_color & 0x7f);
|
||||
break;
|
||||
case GRUB_TERM_COLOR_HIGHLIGHT:
|
||||
SetConsoleTextAttribute (hStdout, grub_term_highlight_color & 0x7f);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)),
|
||||
int on)
|
||||
{
|
||||
CONSOLE_CURSOR_INFO ci;
|
||||
ci.dwSize = 5;
|
||||
ci.bVisible = on;
|
||||
SetConsoleCursorInfo (hStdout, &ci);
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_efi_console_init (struct grub_term_output *term)
|
||||
{
|
||||
grub_console_setcursor (term, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_efi_console_fini (struct grub_term_output *term)
|
||||
{
|
||||
grub_console_setcursor (term, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static grub_err_t
|
||||
grub_console_init_input (struct grub_term_input *term)
|
||||
{
|
||||
if (!saved_orig)
|
||||
{
|
||||
GetConsoleMode (hStdin, &orig_mode);
|
||||
}
|
||||
|
||||
saved_orig = 1;
|
||||
|
||||
SetConsoleMode (hStdin, orig_mode & ~ENABLE_ECHO_INPUT
|
||||
& ~ENABLE_LINE_INPUT & ~ENABLE_PROCESSED_INPUT);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_console_fini_input (struct grub_term_input *term
|
||||
__attribute__ ((unused)))
|
||||
{
|
||||
SetConsoleMode (hStdin, orig_mode);
|
||||
saved_orig = 0;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
static struct grub_term_input grub_console_term_input =
|
||||
{
|
||||
.name = "console",
|
||||
.getkey = grub_console_getkey,
|
||||
.init = grub_console_init_input,
|
||||
.fini = grub_console_fini_input,
|
||||
};
|
||||
|
||||
static struct grub_term_output grub_console_term_output =
|
||||
{
|
||||
.name = "console",
|
||||
.init = grub_efi_console_init,
|
||||
.fini = grub_efi_console_fini,
|
||||
.putchar = grub_console_putchar,
|
||||
.getwh = grub_console_getwh,
|
||||
.getxy = grub_console_getxy,
|
||||
.gotoxy = grub_console_gotoxy,
|
||||
.cls = grub_console_cls,
|
||||
.setcolorstate = grub_console_setcolorstate,
|
||||
.setcursor = grub_console_setcursor,
|
||||
.flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS
|
||||
};
|
||||
|
||||
void
|
||||
grub_console_init (void)
|
||||
{
|
||||
hStdin = GetStdHandle (STD_INPUT_HANDLE);
|
||||
hStdout = GetStdHandle (STD_OUTPUT_HANDLE);
|
||||
|
||||
grub_term_register_input ("console", &grub_console_term_input);
|
||||
grub_term_register_output ("console", &grub_console_term_output);
|
||||
}
|
||||
|
||||
void
|
||||
grub_console_fini (void)
|
||||
{
|
||||
if (saved_orig)
|
||||
{
|
||||
SetConsoleMode (hStdin, orig_mode);
|
||||
saved_orig = 0;
|
||||
}
|
||||
grub_term_unregister_input (&grub_console_term_input);
|
||||
grub_term_unregister_output (&grub_console_term_output);
|
||||
}
|
Loading…
Reference in a new issue