1
0
mirror of https://git.FreeBSD.org/ports.git synced 2024-11-26 00:55:14 +00:00
freebsd-ports/sysutils/grub/files/patch-graphics
Sergey Matveychuk ceec5295a9 - Fix grub-install for 5.x and -CURRENT
- Put more useful info into pkg-messages
- Apply a patch from Mandrake for showing
  a graphical splashscreen on booting (*)

PR:		ports/74478 (*)
Submitted by:	Manuel Rabade Garcia <mig(at)mig-29.net> (*)
2004-12-03 21:11:03 +00:00

1284 lines
33 KiB
Plaintext
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.

--- stage2/asm.S.graphics 2004-06-18 17:35:51.932054040 -0400
+++ stage2/asm.S 2004-06-18 17:35:52.473971656 -0400
@@ -2215,6 +2215,156 @@
pop %ebx
pop %ebp
ret
+
+/* graphics mode functions */
+#ifdef SUPPORT_GRAPHICS
+VARIABLE(cursorX)
+.word 0
+VARIABLE(cursorY)
+.word 0
+VARIABLE(cursorCount)
+.word 0
+VARIABLE(cursorBuf)
+.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+
+
+/*
+ * int set_videomode(mode)
+ * BIOS call "INT 10H Function 0h" to set video mode
+ * Call with %ah = 0x0
+ * %al = video mode
+ * Returns old videomode.
+ */
+ENTRY(set_videomode)
+ push %ebp
+ push %ebx
+ push %ecx
+
+ movb 0x10(%esp), %cl
+
+ call EXT_C(prot_to_real)
+ .code16
+
+ xorw %bx, %bx
+ movb $0xf, %ah
+ int $0x10 /* Get Current Video mode */
+ movb %al, %ch
+ xorb %ah, %ah
+ movb %cl, %al
+ int $0x10 /* Set Video mode */
+
+ DATA32 call EXT_C(real_to_prot)
+ .code32
+
+ xorb %ah, %ah
+ movb %ch, %al
+
+ pop %ecx
+ pop %ebx
+ pop %ebp
+ ret
+
+
+/*
+ * unsigned char * graphics_get_font()
+ * BIOS call "INT 10H Function 11h" to set font
+ * Call with %ah = 0x11
+ */
+ENTRY(graphics_get_font)
+ push %ebp
+ push %ebx
+ push %ecx
+ push %edx
+
+ call EXT_C(prot_to_real)
+ .code16
+
+ movw $0x1130, %ax
+ movb $6, %bh /* font 8x16 */
+ int $0x10
+ movw %bp, %dx
+ movw %es, %cx
+
+ DATA32 call EXT_C(real_to_prot)
+ .code32
+
+ xorl %eax, %eax
+ movw %cx, %ax
+ shll $4, %eax
+ movw %dx, %ax
+
+ pop %edx
+ pop %ecx
+ pop %ebx
+ pop %ebp
+ ret
+
+
+
+/*
+ * graphics_set_palette(index, red, green, blue)
+ * BIOS call "INT 10H Function 10h" to set individual dac register
+ * Call with %ah = 0x10
+ * %bx = register number
+ * %ch = new value for green (0-63)
+ * %cl = new value for blue (0-63)
+ * %dh = new value for red (0-63)
+ */
+
+ENTRY(graphics_set_palette)
+ push %ebp
+ push %eax
+ push %ebx
+ push %ecx
+ push %edx
+
+ movw $0x3c8, %bx /* address write mode register */
+
+ /* wait vertical retrace */
+
+ movw $0x3da, %dx
+l1b: inb %dx, %al /* wait vertical active display */
+ test $8, %al
+ jnz l1b
+
+l2b: inb %dx, %al /* wait vertical retrace */
+ test $8, %al
+ jnz l2b
+
+ mov %bx, %dx
+ movb 0x18(%esp), %al /* index */
+ outb %al, %dx
+ inc %dx
+
+ movb 0x1c(%esp), %al /* red */
+ outb %al, %dx
+
+ movb 0x20(%esp), %al /* green */
+ outb %al, %dx
+
+ movb 0x24(%esp), %al /* blue */
+ outb %al, %dx
+
+ movw 0x18(%esp), %bx
+
+ call EXT_C(prot_to_real)
+ .code16
+
+ movb %bl, %bh
+ movw $0x1000, %ax
+ int $0x10
+
+ DATA32 call EXT_C(real_to_prot)
+ .code32
+
+ pop %edx
+ pop %ecx
+ pop %ebx
+ pop %eax
+ pop %ebp
+ ret
+
+#endif /* SUPPORT_GRAPHICS */
/*
* getrtsecs()
--- stage2/stage2.c.graphics 2004-06-18 17:35:52.314995824 -0400
+++ stage2/stage2.c 2004-06-18 17:35:52.494968464 -0400
@@ -233,6 +233,7 @@
{
int c, time1, time2 = -1, first_entry = 0;
char *cur_entry = 0;
+ struct term_entry *prev_term = NULL;
/*
* Main loop for menu UI.
@@ -807,6 +808,15 @@
cls ();
setcursor (1);
+ /* if our terminal needed initialization, we should shut it down
+ * before booting the kernel, but we want to save what it was so
+ * we can come back if needed */
+ prev_term = current_term;
+ if (current_term->shutdown)
+ {
+ (*current_term->shutdown)();
+ current_term = term_table; /* assumption: console is first */
+ }
while (1)
{
@@ -838,6 +848,13 @@
break;
}
+ /* if we get back here, we should go back to what our term was before */
+ current_term = prev_term;
+ if (current_term->startup)
+ /* if our terminal fails to initialize, fall back to console since
+ * it should always work */
+ if ((*current_term->startup)() == 0)
+ current_term = term_table; /* we know that console is first */
show_menu = 1;
goto restart;
}
@@ -1082,6 +1099,10 @@
while (is_preset);
}
+ /* go ahead and make sure the terminal is setup */
+ if (current_term->startup)
+ (*current_term->startup)();
+
if (! num_entries)
{
/* If no acceptable config file, goto command-line, starting
--- stage2/builtins.c.graphics 2004-06-18 17:35:52.370987312 -0400
+++ stage2/builtins.c 2004-06-18 17:35:52.482970288 -0400
@@ -858,6 +858,138 @@
};
#endif /* SUPPORT_NETBOOT */
+static int terminal_func (char *arg, int flags);
+
+#ifdef SUPPORT_GRAPHICS
+
+static int splashimage_func(char *arg, int flags) {
+ char splashimage[64];
+ int i;
+
+ /* filename can only be 64 characters due to our buffer size */
+ if (strlen(arg) > 63)
+ return 1;
+ if (flags == BUILTIN_CMDLINE) {
+ if (!grub_open(arg))
+ return 1;
+ grub_close();
+ }
+
+ strcpy(splashimage, arg);
+
+ /* get rid of TERM_NEED_INIT from the graphics terminal. */
+ for (i = 0; term_table[i].name; i++) {
+ if (grub_strcmp (term_table[i].name, "graphics") == 0) {
+ term_table[i].flags &= ~TERM_NEED_INIT;
+ break;
+ }
+ }
+
+ graphics_set_splash(splashimage);
+
+ if (flags == BUILTIN_CMDLINE && graphics_inited) {
+ graphics_end();
+ graphics_init();
+ graphics_cls();
+ }
+
+ /* FIXME: should we be explicitly switching the terminal as a
+ * side effect here? */
+ terminal_func("graphics", flags);
+
+ return 0;
+}
+
+static struct builtin builtin_splashimage =
+{
+ "splashimage",
+ splashimage_func,
+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
+ "splashimage FILE",
+ "Load FILE as the background image when in graphics mode."
+};
+
+
+/* foreground */
+static int
+foreground_func(char *arg, int flags)
+{
+ if (grub_strlen(arg) == 6) {
+ int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
+ int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
+ int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
+
+ foreground = (r << 16) | (g << 8) | b;
+ if (graphics_inited)
+ graphics_set_palette(15, r, g, b);
+
+ return (0);
+ }
+
+ return (1);
+}
+
+static struct builtin builtin_foreground =
+{
+ "foreground",
+ foreground_func,
+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
+ "foreground RRGGBB",
+ "Sets the foreground color when in graphics mode."
+ "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
+};
+
+
+/* background */
+static int
+background_func(char *arg, int flags)
+{
+ if (grub_strlen(arg) == 6) {
+ int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
+ int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
+ int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
+
+ background = (r << 16) | (g << 8) | b;
+ if (graphics_inited)
+ graphics_set_palette(0, r, g, b);
+ return (0);
+ }
+
+ return (1);
+}
+
+static struct builtin builtin_background =
+{
+ "background",
+ background_func,
+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
+ "background RRGGBB",
+ "Sets the background color when in graphics mode."
+ "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
+};
+
+#endif /* SUPPORT_GRAPHICS */
+
+
+/* clear */
+static int
+clear_func()
+{
+ if (current_term->cls)
+ current_term->cls();
+
+ return 0;
+}
+
+static struct builtin builtin_clear =
+{
+ "clear",
+ clear_func,
+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+ "clear",
+ "Clear the screen"
+};
+
/* displayapm */
static int
@@ -4090,7 +4222,7 @@
};
-#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
+#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS)
/* terminal */
static int
terminal_func (char *arg, int flags)
@@ -4249,17 +4381,21 @@
end:
current_term = term_table + default_term;
current_term->flags = term_flags;
-
+
if (lines)
max_lines = lines;
else
- /* 24 would be a good default value. */
- max_lines = 24;
-
+ max_lines = current_term->max_lines;
+
/* If the interface is currently the command-line,
restart it to repaint the screen. */
- if (current_term != prev_term && (flags & BUILTIN_CMDLINE))
+ if ((current_term != prev_term) && (flags & BUILTIN_CMDLINE)){
+ if (prev_term->shutdown)
+ prev_term->shutdown();
+ if (current_term->startup)
+ current_term->startup();
grub_longjmp (restart_cmdline_env, 0);
+ }
return 0;
}
@@ -4269,7 +4405,7 @@
"terminal",
terminal_func,
BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
- "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules]",
+ "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules] [graphics]",
"Select a terminal. When multiple terminals are specified, wait until"
" you push any key to continue. If both console and serial are specified,"
" the terminal to which you input a key first will be selected. If no"
@@ -4281,7 +4417,7 @@
" seconds. The option --lines specifies the maximum number of lines."
" The option --silent is used to suppress messages."
};
-#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */
+#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */
#ifdef SUPPORT_SERIAL
@@ -4809,6 +4945,9 @@
/* The table of builtin commands. Sorted in dictionary order. */
struct builtin *builtin_table[] =
{
+#ifdef SUPPORT_GRAPHICS
+ &builtin_background,
+#endif
&builtin_blocklist,
&builtin_boot,
#ifdef SUPPORT_NETBOOT
@@ -4816,6 +4955,7 @@
#endif /* SUPPORT_NETBOOT */
&builtin_cat,
&builtin_chainloader,
+ &builtin_clear,
&builtin_cmp,
&builtin_color,
&builtin_configfile,
@@ -4835,6 +4975,9 @@
&builtin_embed,
&builtin_fallback,
&builtin_find,
+#ifdef SUPPORT_GRAPHICS
+ &builtin_foreground,
+#endif
&builtin_fstest,
&builtin_geometry,
&builtin_halt,
@@ -4878,9 +5021,12 @@
#endif /* SUPPORT_SERIAL */
&builtin_setkey,
&builtin_setup,
-#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
+#ifdef SUPPORT_GRAPHICS
+ &builtin_splashimage,
+#endif /* SUPPORT_GRAPHICS */
+#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS)
&builtin_terminal,
-#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */
+#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */
#ifdef SUPPORT_SERIAL
&builtin_terminfo,
#endif /* SUPPORT_SERIAL */
--- /dev/null 2004-02-23 16:02:56.000000000 -0500
+++ stage2/graphics.c 2004-06-18 17:35:52.488969376 -0400
@@ -0,0 +1,552 @@
+/* graphics.c - graphics mode support for GRUB */
+/* Implemented as a terminal type by Jeremy Katz <katzj@redhat.com> based
+ * on a patch by Paulo C<>sar Pereira de Andrade <pcpa@conectiva.com.br>
+ */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2001,2002 Red Hat, Inc.
+ * Portions copyright (C) 2000 Conectiva, Inc.
+ *
+ * This program 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+
+#ifdef SUPPORT_GRAPHICS
+
+#include <term.h>
+#include <shared.h>
+#include <graphics.h>
+
+int saved_videomode;
+unsigned char *font8x16;
+
+int graphics_inited = 0;
+static char splashimage[64];
+
+#define VSHADOW VSHADOW1
+unsigned char VSHADOW1[38400];
+unsigned char VSHADOW2[38400];
+unsigned char VSHADOW4[38400];
+unsigned char VSHADOW8[38400];
+
+/* constants to define the viewable area */
+const int x0 = 0;
+const int x1 = 80;
+const int y0 = 0;
+const int y1 = 30;
+
+/* text buffer has to be kept around so that we can write things as we
+ * scroll and the like */
+unsigned short text[80 * 30];
+
+/* why do these have to be kept here? */
+int foreground = (63 << 16) | (63 << 8) | (63), background = 0, border = 0;
+
+/* current position */
+static int fontx = 0;
+static int fonty = 0;
+
+/* global state so that we don't try to recursively scroll or cursor */
+static int no_scroll = 0;
+
+/* color state */
+static int graphics_standard_color = A_NORMAL;
+static int graphics_normal_color = A_NORMAL;
+static int graphics_highlight_color = A_REVERSE;
+static int graphics_current_color = A_NORMAL;
+static color_state graphics_color_state = COLOR_STATE_STANDARD;
+
+
+/* graphics local functions */
+static void graphics_setxy(int col, int row);
+static void graphics_scroll();
+
+/* FIXME: where do these really belong? */
+static inline void outb(unsigned short port, unsigned char val)
+{
+ __asm __volatile ("outb %0,%1"::"a" (val), "d" (port));
+}
+
+static void MapMask(int value) {
+ outb(0x3c4, 2);
+ outb(0x3c5, value);
+}
+
+/* bit mask register */
+static void BitMask(int value) {
+ outb(0x3ce, 8);
+ outb(0x3cf, value);
+}
+
+
+
+/* Set the splash image */
+void graphics_set_splash(char *splashfile) {
+ grub_strcpy(splashimage, splashfile);
+}
+
+/* Get the current splash image */
+char *graphics_get_splash(void) {
+ return splashimage;
+}
+
+/* Initialize a vga16 graphics display with the palette based off of
+ * the image in splashimage. If the image doesn't exist, leave graphics
+ * mode. */
+int graphics_init()
+{
+ if (!graphics_inited) {
+ saved_videomode = set_videomode(0x12);
+ }
+
+ if (!read_image(splashimage)) {
+ set_videomode(saved_videomode);
+ grub_printf("failed to read image\n");
+ return 0;
+ }
+
+ font8x16 = (unsigned char*)graphics_get_font();
+
+ graphics_inited = 1;
+
+ /* make sure that the highlight color is set correctly */
+ graphics_highlight_color = ((graphics_normal_color >> 4) |
+ ((graphics_normal_color & 0xf) << 4));
+
+ return 1;
+}
+
+/* Leave graphics mode */
+void graphics_end(void)
+{
+ if (graphics_inited) {
+ set_videomode(saved_videomode);
+ graphics_inited = 0;
+ }
+}
+
+/* Print ch on the screen. Handle any needed scrolling or the like */
+void graphics_putchar(int ch) {
+ ch &= 0xff;
+
+ graphics_cursor(0);
+
+ if (ch == '\n') {
+ if (fonty + 1 < y1)
+ graphics_setxy(fontx, fonty + 1);
+ else
+ graphics_scroll();
+ graphics_cursor(1);
+ return;
+ } else if (ch == '\r') {
+ graphics_setxy(x0, fonty);
+ graphics_cursor(1);
+ return;
+ }
+
+ graphics_cursor(0);
+
+ text[fonty * 80 + fontx] = ch;
+ text[fonty * 80 + fontx] &= 0x00ff;
+ if (graphics_current_color & 0xf0)
+ text[fonty * 80 + fontx] |= 0x100;
+
+ graphics_cursor(0);
+
+ if ((fontx + 1) >= x1) {
+ graphics_setxy(x0, fonty);
+ if (fonty + 1 < y1)
+ graphics_setxy(x0, fonty + 1);
+ else
+ graphics_scroll();
+ } else {
+ graphics_setxy(fontx + 1, fonty);
+ }
+
+ graphics_cursor(1);
+}
+
+/* get the current location of the cursor */
+int graphics_getxy(void) {
+ return (fontx << 8) | fonty;
+}
+
+void graphics_gotoxy(int x, int y) {
+ graphics_cursor(0);
+
+ graphics_setxy(x, y);
+
+ graphics_cursor(1);
+}
+
+void graphics_cls(void) {
+ int i;
+ unsigned char *mem, *s1, *s2, *s4, *s8;
+
+ graphics_cursor(0);
+ graphics_gotoxy(x0, y0);
+
+ mem = (unsigned char*)VIDEOMEM;
+ s1 = (unsigned char*)VSHADOW1;
+ s2 = (unsigned char*)VSHADOW2;
+ s4 = (unsigned char*)VSHADOW4;
+ s8 = (unsigned char*)VSHADOW8;
+
+ for (i = 0; i < 80 * 30; i++)
+ text[i] = ' ';
+ graphics_cursor(1);
+
+ BitMask(0xff);
+
+ /* plano 1 */
+ MapMask(1);
+ grub_memcpy(mem, s1, 38400);
+
+ /* plano 2 */
+ MapMask(2);
+ grub_memcpy(mem, s2, 38400);
+
+ /* plano 3 */
+ MapMask(4);
+ grub_memcpy(mem, s4, 38400);
+
+ /* plano 4 */
+ MapMask(8);
+ grub_memcpy(mem, s8, 38400);
+
+ MapMask(15);
+
+}
+
+void graphics_setcolorstate (color_state state) {
+ switch (state) {
+ case COLOR_STATE_STANDARD:
+ graphics_current_color = graphics_standard_color;
+ break;
+ case COLOR_STATE_NORMAL:
+ graphics_current_color = graphics_normal_color;
+ break;
+ case COLOR_STATE_HIGHLIGHT:
+ graphics_current_color = graphics_highlight_color;
+ break;
+ default:
+ graphics_current_color = graphics_standard_color;
+ break;
+ }
+
+ graphics_color_state = state;
+}
+
+void graphics_setcolor (int normal_color, int highlight_color) {
+ graphics_normal_color = normal_color;
+ graphics_highlight_color = highlight_color;
+
+ graphics_setcolorstate (graphics_color_state);
+}
+
+void graphics_setcursor (int on) {
+ /* FIXME: we don't have a cursor in graphics */
+ return;
+}
+
+/* Read in the splashscreen image and set the palette up appropriately.
+ * Format of splashscreen is an xpm (can be gzipped) with 16 colors and
+ * 640x480. */
+int read_image(char *s)
+{
+ char buf[32], pal[16];
+ unsigned char c, base, mask, *s1, *s2, *s4, *s8;
+ unsigned i, len, idx, colors, x, y, width, height;
+
+ if (!grub_open(s))
+ return 0;
+
+ /* read header */
+ if (!grub_read((char*)&buf, 10) || grub_memcmp(buf, "/* XPM */\n", 10)) {
+ grub_close();
+ return 0;
+ }
+
+ /* parse info */
+ while (grub_read(&c, 1)) {
+ if (c == '"')
+ break;
+ }
+
+ while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
+ ;
+
+ i = 0;
+ width = c - '0';
+ while (grub_read(&c, 1)) {
+ if (c >= '0' && c <= '9')
+ width = width * 10 + c - '0';
+ else
+ break;
+ }
+ while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
+ ;
+
+ height = c - '0';
+ while (grub_read(&c, 1)) {
+ if (c >= '0' && c <= '9')
+ height = height * 10 + c - '0';
+ else
+ break;
+ }
+ while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
+ ;
+
+ colors = c - '0';
+ while (grub_read(&c, 1)) {
+ if (c >= '0' && c <= '9')
+ colors = colors * 10 + c - '0';
+ else
+ break;
+ }
+
+ base = 0;
+ while (grub_read(&c, 1) && c != '"')
+ ;
+
+ /* palette */
+ for (i = 0, idx = 1; i < colors; i++) {
+ len = 0;
+
+ while (grub_read(&c, 1) && c != '"')
+ ;
+ grub_read(&c, 1); /* char */
+ base = c;
+ grub_read(buf, 4); /* \t c # */
+
+ while (grub_read(&c, 1) && c != '"') {
+ if (len < sizeof(buf))
+ buf[len++] = c;
+ }
+
+ if (len == 6 && idx < 15) {
+ int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2;
+ int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2;
+ int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2;
+
+ pal[idx] = base;
+ graphics_set_palette(idx, r, g, b);
+ ++idx;
+ }
+ }
+
+ x = y = len = 0;
+
+ s1 = (unsigned char*)VSHADOW1;
+ s2 = (unsigned char*)VSHADOW2;
+ s4 = (unsigned char*)VSHADOW4;
+ s8 = (unsigned char*)VSHADOW8;
+
+ for (i = 0; i < 38400; i++)
+ s1[i] = s2[i] = s4[i] = s8[i] = 0;
+
+ /* parse xpm data */
+ while (y < height) {
+ while (1) {
+ if (!grub_read(&c, 1)) {
+ grub_close();
+ return 0;
+ }
+ if (c == '"')
+ break;
+ }
+
+ while (grub_read(&c, 1) && c != '"') {
+ for (i = 1; i < 15; i++)
+ if (pal[i] == c) {
+ c = i;
+ break;
+ }
+
+ mask = 0x80 >> (x & 7);
+ if (c & 1)
+ s1[len + (x >> 3)] |= mask;
+ if (c & 2)
+ s2[len + (x >> 3)] |= mask;
+ if (c & 4)
+ s4[len + (x >> 3)] |= mask;
+ if (c & 8)
+ s8[len + (x >> 3)] |= mask;
+
+ if (++x >= 640) {
+ x = 0;
+
+ if (y < 480)
+ len += 80;
+ ++y;
+ }
+ }
+ }
+
+ grub_close();
+
+ graphics_set_palette(0, (background >> 16), (background >> 8) & 63,
+ background & 63);
+ graphics_set_palette(15, (foreground >> 16), (foreground >> 8) & 63,
+ foreground & 63);
+ graphics_set_palette(0x11, (border >> 16), (border >> 8) & 63,
+ border & 63);
+
+ return 1;
+}
+
+
+/* Convert a character which is a hex digit to the appropriate integer */
+int hex(int v)
+{
+ if (v >= 'A' && v <= 'F')
+ return (v - 'A' + 10);
+ if (v >= 'a' && v <= 'f')
+ return (v - 'a' + 10);
+ return (v - '0');
+}
+
+
+/* move the graphics cursor location to col, row */
+static void graphics_setxy(int col, int row) {
+ if (col >= x0 && col < x1) {
+ fontx = col;
+ cursorX = col << 3;
+ }
+ if (row >= y0 && row < y1) {
+ fonty = row;
+ cursorY = row << 4;
+ }
+}
+
+/* scroll the screen */
+static void graphics_scroll() {
+ int i, j;
+
+ /* we don't want to scroll recursively... that would be bad */
+ if (no_scroll)
+ return;
+ no_scroll = 1;
+
+ /* move everything up a line */
+ for (j = y0 + 1; j < y1; j++) {
+ graphics_gotoxy(x0, j - 1);
+ for (i = x0; i < x1; i++) {
+ graphics_putchar(text[j * 80 + i]);
+ }
+ }
+
+ /* last line should be blank */
+ graphics_gotoxy(x0, y1 - 1);
+ for (i = x0; i < x1; i++)
+ graphics_putchar(' ');
+ graphics_setxy(x0, y1 - 1);
+
+ no_scroll = 0;
+}
+
+
+void graphics_cursor(int set) {
+ unsigned char *pat, *mem, *ptr, chr[16 << 2];
+ int i, ch, invert, offset;
+
+ if (set && no_scroll)
+ return;
+
+ offset = cursorY * 80 + fontx;
+ ch = text[fonty * 80 + fontx] & 0xff;
+ invert = (text[fonty * 80 + fontx] & 0xff00) != 0;
+ pat = font8x16 + (ch << 4);
+
+ mem = (unsigned char*)VIDEOMEM + offset;
+
+ if (!set) {
+ for (i = 0; i < 16; i++) {
+ unsigned char mask = pat[i];
+
+ if (!invert) {
+ chr[i ] = ((unsigned char*)VSHADOW1)[offset];
+ chr[16 + i] = ((unsigned char*)VSHADOW2)[offset];
+ chr[32 + i] = ((unsigned char*)VSHADOW4)[offset];
+ chr[48 + i] = ((unsigned char*)VSHADOW8)[offset];
+
+ /* FIXME: if (shade) */
+ if (1) {
+ if (ch == DISP_VERT || ch == DISP_LL ||
+ ch == DISP_UR || ch == DISP_LR) {
+ unsigned char pmask = ~(pat[i] >> 1);
+
+ chr[i ] &= pmask;
+ chr[16 + i] &= pmask;
+ chr[32 + i] &= pmask;
+ chr[48 + i] &= pmask;
+ }
+ if (i > 0 && ch != DISP_VERT) {
+ unsigned char pmask = ~(pat[i - 1] >> 1);
+
+ chr[i ] &= pmask;
+ chr[16 + i] &= pmask;
+ chr[32 + i] &= pmask;
+ chr[48 + i] &= pmask;
+ if (ch == DISP_HORIZ || ch == DISP_UR || ch == DISP_LR) {
+ pmask = ~pat[i - 1];
+
+ chr[i ] &= pmask;
+ chr[16 + i] &= pmask;
+ chr[32 + i] &= pmask;
+ chr[48 + i] &= pmask;
+ }
+ }
+ }
+ chr[i ] |= mask;
+ chr[16 + i] |= mask;
+ chr[32 + i] |= mask;
+ chr[48 + i] |= mask;
+
+ offset += 80;
+ }
+ else {
+ chr[i ] = mask;
+ chr[16 + i] = mask;
+ chr[32 + i] = mask;
+ chr[48 + i] = mask;
+ }
+ }
+ }
+ else {
+ MapMask(15);
+ ptr = mem;
+ for (i = 0; i < 16; i++, ptr += 80) {
+ cursorBuf[i] = pat[i];
+ *ptr = ~pat[i];
+ }
+ return;
+ }
+
+ offset = 0;
+ for (i = 1; i < 16; i <<= 1, offset += 16) {
+ int j;
+
+ MapMask(i);
+ ptr = mem;
+ for (j = 0; j < 16; j++, ptr += 80)
+ *ptr = chr[j + offset];
+ }
+
+ MapMask(15);
+}
+
+#endif /* SUPPORT_GRAPHICS */
--- stage2/Makefile.am.graphics 2004-06-13 13:57:27.000000000 -0400
+++ stage2/Makefile.am 2004-06-18 17:36:58.289966104 -0400
@@ -7,7 +7,7 @@
fat.h filesys.h freebsd.h fs.h hercules.h i386-elf.h \
imgact_aout.h iso9660.h jfs.h mb_header.h mb_info.h md5.h \
nbi.h pc_slice.h serial.h shared.h smp-imps.h term.h \
- terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h
+ terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h graphics.h
EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS)
# For <stage1.h>.
@@ -19,7 +19,7 @@
disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \
fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \
fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \
- terminfo.c tparm.c
+ terminfo.c tparm.c graphics.c
libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \
-DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
-DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
@@ -80,8 +80,14 @@
HERCULES_FLAGS =
endif
+if GRAPHICS_SUPPORT
+GRAPHICS_FLAGS = -DSUPPORT_GRAPHICS=1
+else
+GRAPHICS_FLAGS =
+endif
+
STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
- $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS)
+ $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) $(GRAPHICS_FLAGS)
STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000
STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1
@@ -91,7 +97,8 @@
cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \
fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \
fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \
- hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c
+ hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c \
+ graphics.c
pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK)
--- stage2/term.h.graphics 2003-07-09 07:45:53.000000000 -0400
+++ stage2/term.h 2004-06-18 17:35:52.496968160 -0400
@@ -60,6 +60,8 @@
const char *name;
/* The feature flags defined above. */
unsigned long flags;
+ /* Default for maximum number of lines if not specified */
+ unsigned short max_lines;
/* Put a character. */
void (*putchar) (int c);
/* Check if any input character is available. */
@@ -79,6 +81,11 @@
void (*setcolor) (int normal_color, int highlight_color);
/* Turn on/off the cursor. */
int (*setcursor) (int on);
+
+ /* function to start a terminal */
+ int (*startup) (void);
+ /* function to use to shutdown a terminal */
+ void (*shutdown) (void);
};
/* This lists up available terminals. */
@@ -124,4 +131,23 @@
int hercules_setcursor (int on);
#endif
+#ifdef SUPPORT_GRAPHICS
+extern int foreground, background, border, graphics_inited;
+
+void graphics_set_splash(char *splashfile);
+int set_videomode (int mode);
+void graphics_putchar (int c);
+int graphics_getxy(void);
+void graphics_gotoxy(int x, int y);
+void graphics_cls(void);
+void graphics_setcolorstate (color_state state);
+void graphics_setcolor (int normal_color, int highlight_color);
+void graphics_setcursor (int on);
+int graphics_init(void);
+void graphics_end(void);
+
+int hex(int v);
+void graphics_set_palette(int idx, int red, int green, int blue);
+#endif /* SUPPORT_GRAPHICS */
+
#endif /* ! GRUB_TERM_HEADER */
--- /dev/null 2004-02-23 16:02:56.000000000 -0500
+++ stage2/graphics.h 2004-06-18 17:35:52.490969072 -0400
@@ -0,0 +1,42 @@
+/* graphics.h - graphics console interface */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2002 Free Software Foundation, Inc.
+ *
+ * This program 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef GRAPHICS_H
+#define GRAPHICS_H
+
+/* magic constant */
+#define VIDEOMEM 0xA0000
+
+/* function prototypes */
+char *graphics_get_splash(void);
+
+int read_image(char *s);
+void graphics_cursor(int set);
+
+/* function prototypes for asm functions */
+void * graphics_get_font();
+void graphics_set_palette(int idx, int red, int green, int blue);
+void set_int1c_handler();
+void unset_int1c_handler();
+
+extern short cursorX, cursorY;
+extern char cursorBuf[16];
+
+#endif /* GRAPHICS_H */
--- stage2/shared.h.graphics 2004-06-18 17:35:52.372987008 -0400
+++ stage2/shared.h 2004-06-18 17:35:52.492968768 -0400
@@ -873,6 +873,7 @@
int grub_tolower (int c);
int grub_isspace (int c);
int grub_strncat (char *s1, const char *s2, int n);
+void grub_memcpy(void *dest, const void *src, int len);
void *grub_memmove (void *to, const void *from, int len);
void *grub_memset (void *start, int c, int len);
int grub_strncat (char *s1, const char *s2, int n);
--- stage2/char_io.c.graphics 2004-05-23 12:45:43.000000000 -0400
+++ stage2/char_io.c 2004-06-18 17:35:52.485969832 -0400
@@ -35,6 +35,7 @@
{
"console",
0,
+ 24,
console_putchar,
console_checkkey,
console_getkey,
@@ -43,13 +44,16 @@
console_cls,
console_setcolorstate,
console_setcolor,
- console_setcursor
+ console_setcursor,
+ 0,
+ 0
},
#ifdef SUPPORT_SERIAL
{
"serial",
/* A serial device must be initialized. */
TERM_NEED_INIT,
+ 24,
serial_putchar,
serial_checkkey,
serial_getkey,
@@ -58,6 +62,8 @@
serial_cls,
serial_setcolorstate,
0,
+ 0,
+ 0,
0
},
#endif /* SUPPORT_SERIAL */
@@ -65,6 +71,7 @@
{
"hercules",
0,
+ 24,
hercules_putchar,
console_checkkey,
console_getkey,
@@ -73,9 +80,28 @@
hercules_cls,
hercules_setcolorstate,
hercules_setcolor,
- hercules_setcursor
+ hercules_setcursor,
+ 0,
+ 0
},
#endif /* SUPPORT_HERCULES */
+#ifdef SUPPORT_GRAPHICS
+ { "graphics",
+ TERM_NEED_INIT, /* flags */
+ 30, /* number of lines */
+ graphics_putchar, /* putchar */
+ console_checkkey, /* checkkey */
+ console_getkey, /* getkey */
+ graphics_getxy, /* getxy */
+ graphics_gotoxy, /* gotoxy */
+ graphics_cls, /* cls */
+ graphics_setcolorstate, /* setcolorstate */
+ graphics_setcolor, /* setcolor */
+ graphics_setcursor, /* nocursor */
+ graphics_init, /* initialize */
+ graphics_end /* shutdown */
+ },
+#endif /* SUPPORT_GRAPHICS */
/* This must be the last entry. */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
@@ -1046,13 +1072,15 @@
the following grub_printf call will print newlines. */
count_lines = -1;
+ grub_printf("\n");
if (current_term->setcolorstate)
current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
- grub_printf ("\n[Hit return to continue]");
+ grub_printf ("[Hit return to continue]");
if (current_term->setcolorstate)
current_term->setcolorstate (COLOR_STATE_NORMAL);
+
do
{
@@ -1090,7 +1118,7 @@
cls (void)
{
/* If the terminal is dumb, there is no way to clean the terminal. */
- if (current_term->flags & TERM_DUMB)
+ if (current_term->flags & TERM_DUMB)
grub_putchar ('\n');
else
current_term->cls ();
@@ -1214,6 +1242,16 @@
return ! errnum;
}
+void
+grub_memcpy(void *dest, const void *src, int len)
+{
+ int i;
+ register char *d = (char*)dest, *s = (char*)src;
+
+ for (i = 0; i < len; i++)
+ d[i] = s[i];
+}
+
void *
grub_memmove (void *to, const void *from, int len)
{
--- configure.ac.graphics 2004-06-18 17:35:52.211011632 -0400
+++ configure.ac 2004-06-18 17:35:52.498967856 -0400
@@ -595,6 +595,11 @@
[ --enable-diskless enable diskless support])
AM_CONDITIONAL(DISKLESS_SUPPORT, test "x$enable_diskless" = xyes)
+dnl Graphical splashscreen support
+AC_ARG_ENABLE(graphics,
+ [ --disable-graphics disable graphics terminal support])
+AM_CONDITIONAL(GRAPHICS_SUPPORT, test "x$enable_graphics" != xno)
+
dnl Hercules terminal
AC_ARG_ENABLE(hercules,
[ --disable-hercules disable hercules terminal support])