grub2/0359-Replace-libcurses-with-our-own-vt100-handling-for-th.patch
Peter Jones f74b50e380 Rebase to upstream, fix a pile of bugs. The usual.
Signed-off-by: Peter Jones <pjones@redhat.com>
2013-06-12 15:37:08 -04:00

603 lines
18 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From 1314381c929134bfe80ecf100571875dcc35adff Mon Sep 17 00:00:00 2001
From: Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Date: Sat, 27 Apr 2013 00:02:23 +0200
Subject: [PATCH 359/482] Replace libcurses with our own vt100 handling
for the ease of testing and decreasing prerequisites.
---
ChangeLog | 5 +
INSTALL | 6 +-
configure.ac | 16 ---
docs/grub.texi | 45 +++---
gentpl.py | 2 +-
grub-core/Makefile.am | 1 +
grub-core/Makefile.core.def | 4 +-
grub-core/term/emu/console.c | 329 ++++++++++++++-----------------------------
include/grub/terminfo.h | 2 -
9 files changed, 146 insertions(+), 264 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index f554ba8..237ca05 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
2013-04-26 Vladimir Serbinenko <phcoder@gmail.com>
+ Replace libcurses with our own vt100 handling for the ease of testing
+ and decreasing prerequisites.
+
+2013-04-26 Vladimir Serbinenko <phcoder@gmail.com>
+
* grub-core/Makefile.core.def: Fix grub-emu and grub-emu-lite sources.
2013-04-26 Vladimir Serbinenko <phcoder@gmail.com>
diff --git a/INSTALL b/INSTALL
index 3333686..a626395 100644
--- a/INSTALL
+++ b/INSTALL
@@ -23,11 +23,11 @@ On GNU/Linux, you also need:
* libdevmapper 1.02.34 or later (recommended)
-To build grub-emu, you need:
+For optional grub-emu features, you need:
-* ncurses
-* libusb (recommended)
* SDL (recommended)
+* libpciaccess (optional)
+* libusb (optional)
To build GRUB's graphical terminal (gfxterm), you need:
diff --git a/configure.ac b/configure.ac
index 7d3aeac..5ff7f25 100644
--- a/configure.ac
+++ b/configure.ac
@@ -842,22 +842,6 @@ AC_ARG_ENABLE([grub-emu-pci],
[build and install the `grub-emu' debugging utility with PCI support (potentially dangerous) (default=no)])])
if test "$platform" = emu; then
- missing_ncurses=
-[# Check for curses libraries.]
- AC_CHECK_LIB([ncurses], [wgetch], [LIBCURSES="-lncurses"],
- [AC_CHECK_LIB([curses], [wgetch], [LIBCURSES="-lcurses"],
- [missing_ncurses=[true]])])
- AC_SUBST([LIBCURSES])
-[if [ x"$missing_ncurses" = x ]; then ]
- [# Check for headers.]
- AC_CHECK_HEADERS([ncurses/curses.h], [],
- [AC_CHECK_HEADERS([ncurses.h], [],
- [AC_CHECK_HEADERS([curses.h], [],
- [missing_ncurses=[true]])])])
-[fi]
-if test x"$missing_ncurses" = xtrue ; then
- AC_MSG_ERROR([grub-emu can't be compiled without ncurses])
-fi
if test x"$enable_grub_emu_usb" != xyes ; then
grub_emu_usb_excuse="not enabled"
diff --git a/docs/grub.texi b/docs/grub.texi
index 920a558..754e191 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -4586,26 +4586,35 @@ On normalized ZFS subvolumes filenames out of normalisation are inaccessible.
@chapter Output terminal
Firmware output console ``console'' on ARC and IEEE1275 are limited to ASCII.
+
BIOS firmware console and VGA text are limited to ASCII and some pseudographics.
+
None of above mentioned is appropriate for displaying international and any
unsupported character is replaced with question mark except pseudographics
-which we attempt to approximate with ASCII. EFI console on the other hand
-nominally supports UTF-16 but actual language coverage depends on firmware and
-may be very limited. The encoding used on serial can be chosen with
-@command{terminfo} as either ASCII, UTF-8 or ``visual UTF-8''. Last one is
-against the specification but results in correct rendering of right-to-left
-on some readers which don't have own bidi implementation. When using gfxterm
-or gfxmenu GRUB itself is responsible for rendering the text. In this case
-GRUB is limited by loaded fonts. If fonts contain all required characters
-then bidirectional text, cursive variants and combining marks other than
-enclosing, half (e.g. left half tilde or combining overline) and double ones.
-Ligatures aren't supported though. This should cover European, Middle Eastern
-(if you don't mind lack of lam-alif ligature in Arabic) and East Asian scripts.
-Notable unsupported scripts are Brahmic family and derived as well as
-Mongolian, Tifinagh, Korean Jamo (precomposed characters have no problem)
-and tonal writing (2e5-2e9). GRUB also ignores deprecated (as specified
-in Unicode) characters (e.g. tags). GRUB also doesn't handle so called
-``annotation characters'' If you can complete either of
+which we attempt to approximate with ASCII.
+
+EFI console on the other hand nominally supports UTF-16 but actual language
+coverage depends on firmware and may be very limited.
+
+The encoding used on serial can be chosen with @command{terminfo} as
+either ASCII, UTF-8 or ``visual UTF-8''. Last one is against the specification
+but results in correct rendering of right-to-left on some readers which don't
+have own bidi implementation.
+
+On emu GRUB checks if charset is UTF-8 and uses it if so and uses ASCII
+otherwise.
+
+When using gfxterm or gfxmenu GRUB itself is responsible for rendering the
+text. In this case GRUB is limited by loaded fonts. If fonts contain all
+required characters then bidirectional text, cursive variants and combining
+marks other than enclosing, half (e.g. left half tilde or combining overline)
+and double ones. Ligatures aren't supported though. This should cover European,
+Middle Eastern (if you don't mind lack of lam-alif ligature in Arabic) and
+East Asian scripts. Notable unsupported scripts are Brahmic family and
+derived as well as Mongolian, Tifinagh, Korean Jamo (precomposed characters
+have no problem) and tonal writing (2e5-2e9). GRUB also ignores deprecated
+(as specified in Unicode) characters (e.g. tags). GRUB also doesn't handle so
+called ``annotation characters'' If you can complete either of
two lists or, better, propose a patch to improve rendering, please contact
developer team.
@@ -4826,7 +4835,7 @@ and mips-qemu_mips can use only memory up to first hole.
@multitable @columnfractions .20 .20 .20 .20 .20
@item @tab MIPS qemu @tab emu
@item video @tab no @tab yes
-@item console charset @tab CP437 @tab ASCII
+@item console charset @tab CP437 @tab Unicode (*)
@item network @tab no @tab yes
@item ATA/AHCI @tab yes @tab no
@item AT keyboard @tab yes @tab no
diff --git a/gentpl.py b/gentpl.py
index b159795..8674622 100644
--- a/gentpl.py
+++ b/gentpl.py
@@ -57,7 +57,7 @@ GROUPS["videomodules"] = GRUB_PLATFORMS[:];
for i in GROUPS["videoinkernel"]: GROUPS["videomodules"].remove(i)
# Similar for terminfo
-GROUPS["terminfoinkernel"] = ["mips_loongson", "mips_arc", "mips_qemu_mips" ] + GROUPS["ieee1275"];
+GROUPS["terminfoinkernel"] = [ "emu", "mips_loongson", "mips_arc", "mips_qemu_mips" ] + GROUPS["ieee1275"];
GROUPS["terminfomodule"] = GRUB_PLATFORMS[:];
for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i)
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
index 07aad50..fa6afcf 100644
--- a/grub-core/Makefile.am
+++ b/grub-core/Makefile.am
@@ -216,6 +216,7 @@ if COND_emu
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/datetime.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/misc.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/export.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
if COND_GRUB_EMU_SDL
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sdl.h
endif
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index e2ecff1..2a8ac6f 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -250,7 +250,7 @@ program = {
ldadd = 'kernel.exec$(EXEEXT)';
ldadd = '$(MODULE_FILES)';
- ldadd = 'gnulib/libgnu.a $(LIBCURSES) $(LIBINTL) $(LIBUTIL) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
+ ldadd = 'gnulib/libgnu.a $(LIBINTL) $(LIBUTIL) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
enable = emu;
};
@@ -262,7 +262,7 @@ program = {
emu_nodist = symlist.c;
ldadd = 'kernel.exec$(EXEEXT)';
- ldadd = 'gnulib/libgnu.a $(LIBCURSES) $(LIBINTL) $(LIBUTIL) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
+ ldadd = 'gnulib/libgnu.a $(LIBINTL) $(LIBUTIL) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
enable = emu;
};
diff --git a/grub-core/term/emu/console.c b/grub-core/term/emu/console.c
index 5bd5db1..d61ade1 100644
--- a/grub-core/term/emu/console.c
+++ b/grub-core/term/emu/console.c
@@ -1,7 +1,7 @@
-/* console.c -- Ncurses console for GRUB. */
+/* console.c -- console for GRUB. */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2003,2005,2007,2008 Free Software Foundation, Inc.
+ * Copyright (C) 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
@@ -20,274 +20,159 @@
#include <config.h>
#include <config-util.h>
-/* For compatibility. */
-#ifndef A_NORMAL
-# define A_NORMAL 0
-#endif /* ! A_NORMAL */
-#ifndef A_STANDOUT
-# define A_STANDOUT 0
-#endif /* ! A_STANDOUT */
-
-#include <grub/emu/console.h>
#include <grub/term.h>
#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/time.h>
+#include <grub/terminfo.h>
+#include <grub/dl.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <termios.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <langinfo.h>
-#if defined(HAVE_NCURSES_CURSES_H)
-# include <ncurses/curses.h>
-#elif defined(HAVE_NCURSES_H)
-# include <ncurses.h>
-#elif defined(HAVE_CURSES_H)
-# include <curses.h>
-#else
-#error What the hell?
-#endif
-
-static int grub_console_attr = A_NORMAL;
-
-grub_uint8_t grub_console_cur_color = 7;
-
-static const grub_uint8_t grub_console_standard_color = 0x7;
-
-#define NUM_COLORS 8
-
-static grub_uint8_t color_map[NUM_COLORS] =
-{
- COLOR_BLACK,
- COLOR_BLUE,
- COLOR_GREEN,
- COLOR_CYAN,
- COLOR_RED,
- COLOR_MAGENTA,
- COLOR_YELLOW,
- COLOR_WHITE
-};
+#include <grub/emu/console.h>
-static int use_color;
+extern struct grub_terminfo_output_state grub_console_terminfo_output;
+static int original_fl;
+static int saved_orig;
+static struct termios orig_tty;
+static struct termios new_tty;
static void
-grub_ncurses_putchar (struct grub_term_output *term __attribute__ ((unused)),
- const struct grub_unicode_glyph *c)
+put (struct grub_term_output *term __attribute__ ((unused)), const int c)
{
- addch (c->base | grub_console_attr);
-}
+ char chr = c;
-static void
-grub_ncurses_setcolorstate (struct grub_term_output *term,
- grub_term_color_state state)
-{
- switch (state)
- {
- case GRUB_TERM_COLOR_STANDARD:
- grub_console_cur_color = grub_console_standard_color;
- grub_console_attr = A_NORMAL;
- break;
- case GRUB_TERM_COLOR_NORMAL:
- grub_console_cur_color = grub_term_normal_color;
- grub_console_attr = A_NORMAL;
- break;
- case GRUB_TERM_COLOR_HIGHLIGHT:
- grub_console_cur_color = grub_term_highlight_color;
- grub_console_attr = A_STANDOUT;
- break;
- default:
- break;
- }
-
- if (use_color)
- {
- grub_uint8_t fg, bg;
-
- fg = (grub_console_cur_color & 7);
- bg = (grub_console_cur_color >> 4) & 7;
-
- grub_console_attr = (grub_console_cur_color & 8) ? A_BOLD : A_NORMAL;
- color_set ((bg << 3) + fg, 0);
- }
+ write (STDOUT_FILENO, &chr, 1);
}
static int
-grub_ncurses_getkey (struct grub_term_input *term __attribute__ ((unused)))
-{
- int c;
-
- wtimeout (stdscr, 100);
- c = getch ();
-
- switch (c)
- {
- case ERR:
- return GRUB_TERM_NO_KEY;
- case KEY_LEFT:
- c = GRUB_TERM_KEY_LEFT;
- break;
-
- case KEY_RIGHT:
- c = GRUB_TERM_KEY_RIGHT;
- break;
-
- case KEY_UP:
- c = GRUB_TERM_KEY_UP;
- break;
-
- case KEY_DOWN:
- c = GRUB_TERM_KEY_DOWN;
- break;
-
- case KEY_IC:
- c = 24;
- break;
-
- case KEY_DC:
- c = GRUB_TERM_KEY_DC;
- break;
-
- case KEY_BACKSPACE:
- /* XXX: For some reason ncurses on xterm does not return
- KEY_BACKSPACE. */
- case 127:
- c = '\b';
- break;
-
- case KEY_HOME:
- c = GRUB_TERM_KEY_HOME;
- break;
-
- case KEY_END:
- c = GRUB_TERM_KEY_END;
- break;
-
- case KEY_NPAGE:
- c = GRUB_TERM_KEY_NPAGE;
- break;
-
- case KEY_PPAGE:
- c = GRUB_TERM_KEY_PPAGE;
- break;
- }
-
- return c;
-}
-
-static grub_uint16_t
-grub_ncurses_getxy (struct grub_term_output *term __attribute__ ((unused)))
+readkey (struct grub_term_input *term __attribute__ ((unused)))
{
- int x;
- int y;
+ grub_uint8_t c;
+ ssize_t actual;
- getyx (stdscr, y, x);
-
- return (x << 8) | y;
+ actual = read (STDIN_FILENO, &c, 1);
+ if (actual > 0)
+ return c;
+ return -1;
}
-static grub_uint16_t
-grub_ncurses_getwh (struct grub_term_output *term __attribute__ ((unused)))
+static grub_err_t
+grub_console_init_input (struct grub_term_input *term)
{
- int x;
- int y;
+ if (!saved_orig)
+ {
+ original_fl = fcntl (STDIN_FILENO, F_GETFL);
+ fcntl (STDIN_FILENO, F_SETFL, original_fl | O_NONBLOCK);
+ }
- getmaxyx (stdscr, y, x);
+ saved_orig = 1;
- return (x << 8) | y;
-}
+ tcgetattr(STDIN_FILENO, &orig_tty);
+ new_tty = orig_tty;
+ new_tty.c_lflag &= ~(ICANON | ECHO);
+ new_tty.c_cc[VMIN] = 1;
+ tcsetattr(STDIN_FILENO, TCSANOW, &new_tty);
-static void
-grub_ncurses_gotoxy (struct grub_term_output *term __attribute__ ((unused)),
- grub_uint8_t x, grub_uint8_t y)
-{
- move (y, x);
+ return grub_terminfo_input_init (term);
}
-static void
-grub_ncurses_cls (struct grub_term_output *term __attribute__ ((unused)))
-{
- clear ();
- refresh ();
-}
-
-static void
-grub_ncurses_setcursor (struct grub_term_output *term __attribute__ ((unused)),
- int on)
-{
- curs_set (on ? 1 : 0);
-}
-
-static void
-grub_ncurses_refresh (struct grub_term_output *term __attribute__ ((unused)))
+static grub_err_t
+grub_console_fini_input (struct grub_term_input *term
+ __attribute__ ((unused)))
{
- refresh ();
+ fcntl (STDIN_FILENO, F_SETFL, original_fl);
+ tcsetattr(STDIN_FILENO, TCSANOW, &orig_tty);
+ saved_orig = 0;
+ return GRUB_ERR_NONE;
}
static grub_err_t
-grub_ncurses_init (struct grub_term_output *term __attribute__ ((unused)))
+grub_console_init_output (struct grub_term_output *term)
{
- initscr ();
- raw ();
- noecho ();
- scrollok (stdscr, TRUE);
-
- nonl ();
- intrflush (stdscr, FALSE);
- keypad (stdscr, TRUE);
-
- if (has_colors ())
+ struct winsize size;
+ if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &size) >= 0)
{
- start_color ();
-
- if ((COLORS >= NUM_COLORS) && (COLOR_PAIRS >= NUM_COLORS * NUM_COLORS))
- {
- int i, j, n;
-
- n = 0;
- for (i = 0; i < NUM_COLORS; i++)
- for (j = 0; j < NUM_COLORS; j++)
- init_pair(n++, color_map[j], color_map[i]);
-
- use_color = 1;
- }
+ grub_console_terminfo_output.width = size.ws_col;
+ grub_console_terminfo_output.height = size.ws_row;
+ }
+ else
+ {
+ grub_console_terminfo_output.width = 80;
+ grub_console_terminfo_output.height = 24;
}
- return 0;
-}
+ grub_terminfo_output_init (term);
-static grub_err_t
-grub_ncurses_fini (struct grub_term_output *term __attribute__ ((unused)))
-{
- endwin ();
return 0;
}
-static struct grub_term_input grub_ncurses_term_input =
+
+struct grub_terminfo_input_state grub_console_terminfo_input =
+ {
+ .readkey = readkey
+ };
+
+struct grub_terminfo_output_state grub_console_terminfo_output =
+ {
+ .put = put,
+ .width = 80,
+ .height = 24
+ };
+
+static struct grub_term_input grub_console_term_input =
{
.name = "console",
- .getkey = grub_ncurses_getkey,
+ .init = grub_console_init_input,
+ .fini = grub_console_fini_input,
+ .getkey = grub_terminfo_getkey,
+ .data = &grub_console_terminfo_input
};
-static struct grub_term_output grub_ncurses_term_output =
+static struct grub_term_output grub_console_term_output =
{
.name = "console",
- .init = grub_ncurses_init,
- .fini = grub_ncurses_fini,
- .putchar = grub_ncurses_putchar,
- .getxy = grub_ncurses_getxy,
- .getwh = grub_ncurses_getwh,
- .gotoxy = grub_ncurses_gotoxy,
- .cls = grub_ncurses_cls,
- .setcolorstate = grub_ncurses_setcolorstate,
- .setcursor = grub_ncurses_setcursor,
- .refresh = grub_ncurses_refresh,
- .flags = GRUB_TERM_CODE_TYPE_ASCII
+ .init = grub_console_init_output,
+ .putchar = grub_terminfo_putchar,
+ .getxy = grub_terminfo_getxy,
+ .getwh = grub_terminfo_getwh,
+ .gotoxy = grub_terminfo_gotoxy,
+ .cls = grub_terminfo_cls,
+ .setcolorstate = grub_terminfo_setcolorstate,
+ .setcursor = grub_terminfo_setcursor,
+ .data = &grub_console_terminfo_output,
};
void
grub_console_init (void)
{
- grub_term_register_output ("console", &grub_ncurses_term_output);
- grub_term_register_input ("console", &grub_ncurses_term_input);
+ const char *cs = nl_langinfo (CODESET);
+ if (cs && grub_strcasecmp (cs, "UTF-8"))
+ grub_console_term_output.flags = GRUB_TERM_CODE_TYPE_UTF8_LOGICAL;
+ else
+ grub_console_term_output.flags = GRUB_TERM_CODE_TYPE_ASCII;
+ grub_term_register_input ("console", &grub_console_term_input);
+ grub_term_register_output ("console", &grub_console_term_output);
+ grub_terminfo_init ();
+ grub_terminfo_output_register (&grub_console_term_output, "vt100-color");
}
void
grub_console_fini (void)
{
- grub_ncurses_fini (&grub_ncurses_term_output);
+ if (saved_orig)
+ {
+ fcntl (STDIN_FILENO, F_SETFL, original_fl);
+ tcsetattr(STDIN_FILENO, TCSANOW, &orig_tty);
+ }
+ saved_orig = 0;
}
diff --git a/include/grub/terminfo.h b/include/grub/terminfo.h
index 20541a9..2bbae1f 100644
--- a/include/grub/terminfo.h
+++ b/include/grub/terminfo.h
@@ -82,9 +82,7 @@ grub_err_t EXPORT_FUNC (grub_terminfo_output_register) (struct grub_term_output
const char *type);
grub_err_t EXPORT_FUNC (grub_terminfo_output_unregister) (struct grub_term_output *term);
-#ifndef GRUB_MACHINE_EMU
void grub_terminfo_init (void);
void grub_terminfo_fini (void);
-#endif
#endif /* ! GRUB_TERMINFO_HEADER */
--
1.8.2.1