]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
* grub-core/osdep/windows/emuconsole.c: New file.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Mon, 14 Oct 2013 19:33:55 +0000 (21:33 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Mon, 14 Oct 2013 19:33:55 +0000 (21:33 +0200)
ChangeLog
grub-core/Makefile.core.def
grub-core/osdep/emuconsole.c [new file with mode: 0644]
grub-core/osdep/unix/emuconsole.c [moved from grub-core/term/emu/console.c with 100% similarity]
grub-core/osdep/windows/emuconsole.c [new file with mode: 0644]

index 7f428252b9f251171b6276fefd71c3f7970dc6f6..9852f06e3cad147ca764bdc67eb0471bfdb7de97 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
index 2d3ced74fda584d282fc1c8fc36e35792fa82517..d9645f3cfa93e2458350f0190669e22c2e7bf045 100644 (file)
@@ -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;
 
diff --git a/grub-core/osdep/emuconsole.c b/grub-core/osdep/emuconsole.c
new file mode 100644 (file)
index 0000000..13ede31
--- /dev/null
@@ -0,0 +1,5 @@
+#if defined (__MINGW32__) && !defined (__CYGWIN__)
+#include "windows/emuconsole.c"
+#else
+#include "unix/emuconsole.c"
+#endif
diff --git a/grub-core/osdep/windows/emuconsole.c b/grub-core/osdep/windows/emuconsole.c
new file mode 100644 (file)
index 0000000..7aca3b9
--- /dev/null
@@ -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);
+}