forked from pool/grub2
b05b350108
- snapper rollback support (fate#317062) * add btrfs_follow_default.patch * add suse_btrfs_grub2_install.sh * add 80_suse_btrfs_snapshot * refresh grub2-snapper-plugin.sh - add grub2-x86_64-xen subpackage (bnc#863821) - ieee1275: check for IBM pseries emulated machine (bnc#869964) - added patches: * grub2-ppc64-build-ppc64-32bit.patch - Build ppc64 as 32bit - added patches: * grub2-ppc64-build-ppc64-32bit.patch - Rename PowerPC patches so it will have architecture in it's name - added patches: * grub2-ppc64le-01-Add-Little-Endian-support-for-Power64-to-the-build.patch * grub2-ppc64le-02-Build-grub-as-O1-until-we-add-savegpr-and-restgpr-ro.patch * grub2-ppc64le-03-disable-creation-of-vsx-and-altivec-instructions.patch * grub2-ppc64le-04-powerpc64-LE-s-linker-knows-how-to-handle-the-undefi.patch * grub2-ppc64le-05-grub-install-can-now-recognize-and-install-a-LE-grub.patch * grub2-ppc64le-06-set-the-ABI-version-to-0x02-in-the-e_flag-of-the-PPC.patch * grub2-ppc64le-07-Add-IEEE1275_ADDR-helper.patch * grub2-ppc64le-08-Fix-some-more-warnings-when-casting.patch * grub2-ppc64le-09-Add-powerpc64-types.patch * grub2-ppc64le-10-powerpc64-is-not-necessarily-BigEndian-anymore.patch * grub2-ppc64le-11-Fix-warnings-when-building-powerpc-linux-loader-64bi.patch * grub2-ppc64le-12-GRUB_ELF_R_PPC_-processing-is-applicable-only-for-32.patch OBS-URL: https://build.opensuse.org/request/show/228323 OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=81
440 lines
12 KiB
Diff
440 lines
12 KiB
Diff
---
|
|
grub-core/normal/menu_text.c | 43 ++++++-
|
|
grub-core/normal/term.c | 2
|
|
grub-core/osdep/unix/emuconsole.c | 224 ++++++++++++++++++++++++++++++++++++--
|
|
3 files changed, 257 insertions(+), 12 deletions(-)
|
|
|
|
--- a/grub-core/osdep/unix/emuconsole.c
|
|
+++ b/grub-core/osdep/unix/emuconsole.c
|
|
@@ -39,17 +39,61 @@
|
|
|
|
#include <grub/emu/console.h>
|
|
|
|
+#include <stdio.h>
|
|
+#include <errno.h>
|
|
+
|
|
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 int console_mode = 0;
|
|
+
|
|
+#define MAX_LEN 1023
|
|
+#if defined(__s390x__)
|
|
+static int
|
|
+dummy (void)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
+#endif
|
|
+#if 0
|
|
+static char msg[MAX_LEN+1];
|
|
+static void
|
|
+dprint (int len)
|
|
+{
|
|
+ if (len < 0)
|
|
+ return;
|
|
+ if (len > MAX_LEN)
|
|
+ len = MAX_LEN;
|
|
+ write (2, msg, len);
|
|
+}
|
|
+#define dprintf(fmt, vargs...) dprint(snprintf(msg, MAX_LEN, fmt, ## vargs))
|
|
+#else
|
|
+#define dprintf(fmt, vargs...) {}
|
|
+#endif
|
|
|
|
static void
|
|
-put (struct grub_term_output *term __attribute__ ((unused)), const int c)
|
|
+put (struct grub_term_output *term, const int c)
|
|
{
|
|
char chr = c;
|
|
ssize_t actual;
|
|
+ struct grub_terminfo_output_state *data
|
|
+ = (struct grub_terminfo_output_state *) term->data;
|
|
+
|
|
+ if (term->flags & GRUB_TERM_DUMB) {
|
|
+ if (c == '\n') {
|
|
+ data->pos.y++;
|
|
+ data->pos.x = 0;
|
|
+ } else {
|
|
+ data->pos.x++;
|
|
+ }
|
|
+ if (0) {
|
|
+ if (c == ' ') chr = '_';
|
|
+ if (c == GRUB_TERM_BACKSPACE) chr = '{';
|
|
+ if (c == '\b') chr = '<';
|
|
+ }
|
|
+ }
|
|
|
|
actual = write (STDOUT_FILENO, &chr, 1);
|
|
if (actual < 1)
|
|
@@ -60,20 +104,145 @@ put (struct grub_term_output *term __att
|
|
}
|
|
|
|
static int
|
|
-readkey (struct grub_term_input *term __attribute__ ((unused)))
|
|
+readkey (struct grub_term_input *term)
|
|
{
|
|
grub_uint8_t c;
|
|
ssize_t actual;
|
|
|
|
+ fd_set readfds;
|
|
+ struct timeval timeout;
|
|
+ int sel;
|
|
+ FD_SET (0, &readfds);
|
|
+ timeout.tv_sec = 0;
|
|
+ timeout.tv_usec = 500000;
|
|
+ if ((sel=select (1, &readfds, (fd_set *)0, (fd_set *)0, &timeout)) <= 0)
|
|
+ return -1;
|
|
+
|
|
actual = read (STDIN_FILENO, &c, 1);
|
|
- if (actual > 0)
|
|
- return c;
|
|
- return -1;
|
|
+ if (actual <= 0)
|
|
+ return -1;
|
|
+ return c;
|
|
+}
|
|
+
|
|
+static int
|
|
+readkey_dumb (struct grub_term_input *term)
|
|
+{
|
|
+ grub_uint8_t c;
|
|
+ static grub_uint8_t p = 0;
|
|
+
|
|
+ c = readkey (term);
|
|
+ if (c == (grub_uint8_t)-1)
|
|
+ return -1;
|
|
+ if ((c == '\n' || c == '^') && p != c)
|
|
+ {
|
|
+ p = c;
|
|
+ return -1;
|
|
+ }
|
|
+ if (p == '^' && c != '^')
|
|
+ c &= 0x1F;
|
|
+ p = c;
|
|
+ return c;
|
|
+}
|
|
+
|
|
+static void
|
|
+grub_dumb_putchar (struct grub_term_output *term,
|
|
+ const struct grub_unicode_glyph *c)
|
|
+{
|
|
+ unsigned i;
|
|
+
|
|
+ /* For now, do not try to use a surrogate pair. */
|
|
+ if (c->base > 0xffff)
|
|
+ put (term, '?');
|
|
+ else
|
|
+ put (term, (c->base & 0xffff));
|
|
+
|
|
+ if (0) {
|
|
+ for (i = 0; i < c->ncomb; i++)
|
|
+ if (c->base < 0xffff)
|
|
+ put (term, grub_unicode_get_comb (c)[i].code);
|
|
+ }
|
|
+}
|
|
+
|
|
+static struct grub_term_coordinate
|
|
+grub_dumb_getxy (struct grub_term_output *term)
|
|
+{
|
|
+ struct grub_terminfo_output_state *data
|
|
+ = (struct grub_terminfo_output_state *) term->data;
|
|
+
|
|
+ dprintf ("<%d,%d>", data->pos.x, data->pos.y);
|
|
+ return data->pos;
|
|
+}
|
|
+
|
|
+static struct grub_term_coordinate
|
|
+grub_dumb_getwh (struct grub_term_output *term)
|
|
+{
|
|
+ static int once = 0;
|
|
+ struct grub_terminfo_output_state *data
|
|
+ = (struct grub_terminfo_output_state *) term->data;
|
|
+
|
|
+ if (!once++)
|
|
+ dprintf ("dumb_getwh: w=%d h=%d\n", data->size.x, data->size.y);
|
|
+ return data->size;
|
|
+}
|
|
+
|
|
+static void
|
|
+grub_dumb_gotoxy (struct grub_term_output *term,
|
|
+ struct grub_term_coordinate pos)
|
|
+{
|
|
+ struct grub_terminfo_output_state *data
|
|
+ = (struct grub_terminfo_output_state *) term->data;
|
|
+
|
|
+ if (pos.x > grub_term_width (term) || pos.y > grub_term_height (term))
|
|
+ {
|
|
+ grub_error (GRUB_ERR_BUG, "invalid point (%u,%u)", pos.x, pos.y);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ dprintf("goto(%d,%d)", pos.x, pos.y);
|
|
+ if (pos.x > (grub_term_width (term) - 4)) {
|
|
+ dprintf (" really?");
|
|
+ //return;
|
|
+ }
|
|
+
|
|
+ if (data->gotoxy)
|
|
+ {
|
|
+ int i;
|
|
+ dprintf ("data-gotoxy");
|
|
+ if (data->pos.y != pos.y) {
|
|
+ put (term, '\n');
|
|
+
|
|
+ for (i = 1; i < pos.x; i++ )
|
|
+ put (term, ' ');
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ int i = 0;
|
|
+ if (data->pos.y != pos.y || data->pos.x > pos.x) {
|
|
+ if (data->pos.y >= pos.y) data->pos.y = pos.y - 1;
|
|
+ if (pos.y - data->pos.y > 3) data->pos.y = pos.y - 2;
|
|
+ dprintf (" <%dnl>+%d", (pos.y - data->pos.y), pos.x);
|
|
+ for (i = data->pos.y; i < pos.y; i++ )
|
|
+ put (term, '\n');
|
|
+ }
|
|
+ for (i = data->pos.x; i < pos.x; i++ )
|
|
+ put (term, ' ');
|
|
+ dprintf ("#%d", i);
|
|
+ grub_dumb_getxy (term);
|
|
+ }
|
|
+
|
|
+ dprintf ("\n");
|
|
+ data->pos = pos;
|
|
}
|
|
|
|
static grub_err_t
|
|
grub_console_init_input (struct grub_term_input *term)
|
|
{
|
|
+ if (console_mode > 3200)
|
|
+ {
|
|
+ new_tty = orig_tty;
|
|
+ return GRUB_ERR_NONE;
|
|
+ }
|
|
if (!saved_orig)
|
|
{
|
|
original_fl = fcntl (STDIN_FILENO, F_GETFL);
|
|
@@ -105,7 +274,8 @@ static grub_err_t
|
|
grub_console_init_output (struct grub_term_output *term)
|
|
{
|
|
struct winsize size;
|
|
- if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &size) >= 0)
|
|
+ if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &size) >= 0 &&
|
|
+ size.ws_col > 0 && size.ws_row > 0)
|
|
{
|
|
grub_console_terminfo_output.size.x = size.ws_col;
|
|
grub_console_terminfo_output.size.y = size.ws_row;
|
|
@@ -115,6 +285,8 @@ grub_console_init_output (struct grub_te
|
|
grub_console_terminfo_output.size.x = 80;
|
|
grub_console_terminfo_output.size.y = 24;
|
|
}
|
|
+ if (console_mode == 3215)
|
|
+ grub_console_terminfo_output.size.x -= 1;
|
|
|
|
grub_terminfo_output_init (term);
|
|
|
|
@@ -161,15 +333,53 @@ static struct grub_term_output grub_cons
|
|
void
|
|
grub_console_init (void)
|
|
{
|
|
+#if ! defined(__s390x__)
|
|
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;
|
|
+#else
|
|
+ char link[MAX_LEN+1];
|
|
+ ssize_t len = readlink ("/proc/self/fd/0", link, MAX_LEN);
|
|
+
|
|
+ if (len > 0)
|
|
+ link[len] = 0;
|
|
+ else
|
|
+ link[0] = 0;
|
|
+ if (grub_strncmp ("/dev/ttyS", link, 9) == 0 )
|
|
+ console_mode = 3215;
|
|
+ if (grub_strncmp ("/dev/3270/tty", link, 13) == 0 )
|
|
+ console_mode = 3270;
|
|
+ grub_console_term_output.flags = GRUB_TERM_CODE_TYPE_ASCII;
|
|
+ switch (console_mode)
|
|
+ {
|
|
+ case 3215:
|
|
+ grub_console_term_output.flags |= GRUB_TERM_DUMB;
|
|
+ /* FALLTHROUGH */
|
|
+ case 3270:
|
|
+ grub_console_terminfo_input.readkey = readkey_dumb;
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+#endif
|
|
+ if (grub_console_term_output.flags & GRUB_TERM_DUMB)
|
|
+ {
|
|
+ grub_console_term_output.putchar = grub_dumb_putchar,
|
|
+ grub_console_term_output.getxy = grub_dumb_getxy;
|
|
+ grub_console_term_output.getwh = grub_dumb_getwh;
|
|
+ grub_console_term_output.gotoxy = grub_dumb_gotoxy;
|
|
+ grub_console_term_output.cls = (void *) dummy;
|
|
+ grub_console_term_output.setcolorstate = (void *) dummy;
|
|
+ grub_console_term_output.setcursor = (void *) dummy;
|
|
+ grub_console_term_output.progress_update_divisor = GRUB_PROGRESS_NO_UPDATE;
|
|
+ }
|
|
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");
|
|
+ grub_terminfo_output_register (&grub_console_term_output,
|
|
+ (grub_console_term_output.flags & GRUB_TERM_DUMB)?"dumb":"vt100-color");
|
|
}
|
|
|
|
void
|
|
--- a/grub-core/normal/menu_text.c
|
|
+++ b/grub-core/normal/menu_text.c
|
|
@@ -113,6 +113,7 @@ draw_border (struct grub_term_output *te
|
|
{
|
|
int i;
|
|
|
|
+ if (! (term->flags & GRUB_TERM_DUMB)) {
|
|
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
|
|
|
|
grub_term_gotoxy (term, (struct grub_term_coordinate) { geo->first_entry_x - 1,
|
|
@@ -142,7 +143,7 @@ draw_border (struct grub_term_output *te
|
|
grub_putcode (GRUB_UNICODE_CORNER_LR, term);
|
|
|
|
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
|
|
-
|
|
+ }
|
|
grub_term_gotoxy (term,
|
|
(struct grub_term_coordinate) { geo->first_entry_x - 1,
|
|
(geo->first_entry_y - 1 + geo->num_entries
|
|
@@ -165,6 +166,11 @@ command-line or ESC to discard edits and
|
|
}
|
|
else
|
|
{
|
|
+#if defined(__s390x__hotkey)
|
|
+ ret += grub_print_message_indented_real
|
|
+ (_("Select a menu option by pressing the hotkey specified."),
|
|
+ STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
|
|
+#else
|
|
char *msg_translated;
|
|
|
|
msg_translated = grub_xasprintf (_("Use the %C and %C keys to select which "
|
|
@@ -177,6 +183,7 @@ command-line or ESC to discard edits and
|
|
STANDARD_MARGIN, term, dry_run);
|
|
|
|
grub_free (msg_translated);
|
|
+#endif
|
|
|
|
if (nested)
|
|
{
|
|
@@ -211,6 +218,10 @@ print_entry (int y, int highlight, grub_
|
|
|
|
title = entry ? entry->title : "";
|
|
title_len = grub_strlen (title);
|
|
+
|
|
+ if ((data->term->flags & GRUB_TERM_DUMB) && title[0] == '\0')
|
|
+ return;
|
|
+
|
|
unicode_title = grub_malloc (title_len * sizeof (*unicode_title));
|
|
if (! unicode_title)
|
|
/* XXX How to show this error? */
|
|
@@ -244,6 +255,14 @@ print_entry (int y, int highlight, grub_
|
|
if (data->geo.num_entries > 1)
|
|
grub_putcode (highlight ? '*' : ' ', data->term);
|
|
|
|
+ if ((data->term->flags & GRUB_TERM_DUMB) && title[0] != '\0') {
|
|
+ grub_putcode('(', data->term);
|
|
+ grub_putcode((entry && entry->hotkey >= '0' && entry->hotkey <= 'z') ?
|
|
+ entry->hotkey : ' ', data->term);
|
|
+ grub_putcode(')', data->term);
|
|
+ grub_putcode(' ', data->term);
|
|
+ }
|
|
+
|
|
grub_print_ucs4_menu (unicode_title,
|
|
unicode_title + len,
|
|
0,
|
|
@@ -413,6 +432,8 @@ grub_menu_init_page (int nested, int edi
|
|
grub_term_highlight_color = old_color_highlight;
|
|
geo->timeout_y = geo->first_entry_y + geo->num_entries
|
|
+ geo->border + empty_lines;
|
|
+ if (term->flags & GRUB_TERM_DUMB)
|
|
+ geo->timeout_y = 1;
|
|
if (bottom_message)
|
|
{
|
|
grub_term_gotoxy (term,
|
|
@@ -422,6 +443,8 @@ grub_menu_init_page (int nested, int edi
|
|
print_message (nested, edit, term, 0);
|
|
geo->timeout_y += msg_num_lines;
|
|
}
|
|
+ if (term->flags & GRUB_TERM_DUMB)
|
|
+ geo->timeout_y = 1;
|
|
geo->right_margin = grub_term_width (term)
|
|
- geo->first_entry_x
|
|
- geo->entry_width - 1;
|
|
@@ -433,12 +456,19 @@ menu_text_print_timeout (int timeout, vo
|
|
struct menu_viewer_data *data = dataptr;
|
|
char *msg_translated = 0;
|
|
|
|
- grub_term_gotoxy (data->term,
|
|
+ if (data->geo.timeout_y)
|
|
+ grub_term_gotoxy (data->term,
|
|
(struct grub_term_coordinate) { 0, data->geo.timeout_y });
|
|
|
|
+ if (data->term->flags & GRUB_TERM_DUMB)
|
|
+ {
|
|
+ if (! data->geo.timeout_y)
|
|
+ data->timeout_msg = TIMEOUT_TERSE;
|
|
+ data->geo.timeout_y = 0;
|
|
+ }
|
|
if (data->timeout_msg == TIMEOUT_TERSE
|
|
|| data->timeout_msg == TIMEOUT_TERSE_NO_MARGIN)
|
|
- msg_translated = grub_xasprintf (_("%ds"), timeout);
|
|
+ msg_translated = grub_xasprintf (_(" %ds"), timeout);
|
|
else
|
|
msg_translated = grub_xasprintf (_("The highlighted entry will be executed automatically in %ds."), timeout);
|
|
if (!msg_translated)
|
|
@@ -468,6 +498,8 @@ menu_text_print_timeout (int timeout, vo
|
|
data->term);
|
|
grub_free (msg_translated);
|
|
|
|
+ if (data->term->flags & GRUB_TERM_DUMB)
|
|
+ return;
|
|
grub_term_gotoxy (data->term,
|
|
(struct grub_term_coordinate) {
|
|
grub_term_cursor_x (&data->geo),
|
|
@@ -495,7 +527,7 @@ menu_text_set_chosen_entry (int entry, v
|
|
data->first = entry;
|
|
complete_redraw = 1;
|
|
}
|
|
- if (complete_redraw)
|
|
+ if (complete_redraw || (data->term->flags & GRUB_TERM_DUMB))
|
|
print_entries (data->menu, data);
|
|
else
|
|
{
|
|
@@ -525,6 +557,9 @@ menu_text_clear_timeout (void *dataptr)
|
|
struct menu_viewer_data *data = dataptr;
|
|
int i;
|
|
|
|
+ if ((data->term->flags & GRUB_TERM_DUMB))
|
|
+ return;
|
|
+
|
|
for (i = 0; i < data->geo.timeout_lines;i++)
|
|
{
|
|
grub_term_gotoxy (data->term, (struct grub_term_coordinate) {
|
|
--- a/grub-core/normal/term.c
|
|
+++ b/grub-core/normal/term.c
|
|
@@ -981,7 +981,7 @@ grub_print_ucs4_menu (const grub_uint32_
|
|
{
|
|
print_ucs4_real (str, last_position, margin_left, margin_right,
|
|
term, 0, 0, 1, skip_lines, max_lines,
|
|
- contchar, 1, pos);
|
|
+ contchar, (term->flags & GRUB_TERM_DUMB)? 0 : 1, pos);
|
|
}
|
|
|
|
void
|