FreeBSD Bugzilla – Attachment 48684 Details for
Bug 74478
UPDATE: sysutils/grub patch to handle splashscreens
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
patch-graphics
patch-graphics (text/plain), 32.69 KB, created by
Manuel Rábade - MiG
on 2004-11-28 16:50:17 UTC
(
hide
)
Description:
patch-graphics
Filename:
MIME Type:
Creator:
Manuel Rábade - MiG
Created:
2004-11-28 16:50:17 UTC
Size:
32.69 KB
patch
obsolete
>--- 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])
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 74478
: 48684