cvs commit: patches/grub grub-0.94-graphics.patch

jim at linuxfromscratch.org jim at linuxfromscratch.org
Wed Mar 3 11:03:09 PST 2004


jim         04/03/03 12:03:09

  Added:       grub     grub-0.94-graphics.patch
  Log:
  Added: grub-0.94-graphics.patch
  
  Revision  Changes    Path
  1.1                  patches/grub/grub-0.94-graphics.patch
  
  Index: grub-0.94-graphics.patch
  ===================================================================
  Submitted By: Remy Bosch	remybosch at zonnet dot nl
  Date: 2004-03-03
  Initial Package Version: grub-0.94
  Origin: http://www.momonga-linux.org/cvsweb/cvsweb.cgi/pkgs/grub/grub-0.94-graphics.patch
  Description: This patch implements support for XPM Pixmaps on the grub boot
  	      screen.  Pixmaps must be in XPM format, 640x480 resolution,
  	      utilizing no more than 14 colors.
  
  After this patch has been applied, it is REQUIRED to run the following:
  aclocal
  autoheader
  autoconf
  automake
  
  --- grub-0.93/stage2/Makefile.am.graphics	2002-12-28 23:37:03.000000000 -0500
  +++ grub-0.93/stage2/Makefile.am	2002-12-28 23:37:03.000000000 -0500
  @@ -7,7 +7,7 @@
           fat.h filesys.h freebsd.h fs.h hercules.h i386-elf.h \
   	imgact_aout.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 vstafs.h xfs.h
  +	tparm.h nbi.h vstafs.h xfs.h graphics.h
   EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS)
   
   # For <stage1.h>.
  @@ -18,7 +18,7 @@
   libgrub_a_SOURCES = boot.c builtins.c char_io.c cmdline.c common.c \
   	disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_jfs.c \
   	fsys_minix.c fsys_reiserfs.c fsys_vstafs.c fsys_xfs.c gunzip.c \
  -	md5.c serial.c stage2.c terminfo.c tparm.c
  +	md5.c serial.c stage2.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_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 -DFSYS_VSTAFS=1 \
  @@ -75,8 +75,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
  @@ -86,7 +92,7 @@
   	cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \
   	fsys_fat.c fsys_ffs.c fsys_jfs.c fsys_minix.c fsys_reiserfs.c \
   	fsys_vstafs.c fsys_xfs.c gunzip.c hercules.c md5.c serial.c \
  -	smp-imps.c stage2.c terminfo.c tparm.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)
  --- grub-0.93/stage2/asm.S.graphics	2002-12-28 23:37:03.000000000 -0500
  +++ grub-0.93/stage2/asm.S	2002-12-28 23:37:03.000000000 -0500
  @@ -2224,6 +2224,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()
  --- grub-0.93/stage2/builtins.c.graphics	2002-12-28 23:37:03.000000000 -0500
  +++ grub-0.93/stage2/builtins.c	2002-12-28 23:37:03.000000000 -0500
  @@ -857,6 +857,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
  @@ -4071,7 +4203,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)
  @@ -4230,17 +4362,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;
   }
  @@ -4250,7 +4386,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"
  @@ -4262,7 +4398,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
  @@ -4785,6 +4921,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
  @@ -4792,6 +4931,7 @@
   #endif /* SUPPORT_NETBOOT */
     &builtin_cat,
     &builtin_chainloader,
  +  &builtin_clear,
     &builtin_cmp,
     &builtin_color,
     &builtin_configfile,
  @@ -4811,6 +4951,9 @@
     &builtin_embed,
     &builtin_fallback,
     &builtin_find,
  +#ifdef SUPPORT_GRAPHICS
  +  &builtin_foreground,
  +#endif
     &builtin_fstest,
     &builtin_geometry,
     &builtin_halt,
  @@ -4854,9 +4997,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 */
  --- grub-0.93/stage2/char_io.c.graphics	2002-12-02 18:49:07.000000000 -0500
  +++ grub-0.93/stage2/char_io.c	2002-12-28 23:37:03.000000000 -0500
  @@ -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 }
     };
  @@ -1039,13 +1065,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
   		{
  @@ -1083,7 +1111,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 ();
  @@ -1207,6 +1235,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)
   {
  --- /dev/null	2002-10-04 14:48:04.000000000 -0400
  +++ grub-0.93/stage2/graphics.c	2002-12-28 23:37:03.000000000 -0500
  @@ -0,0 +1,552 @@
  +/* graphics.c - graphics mode support for GRUB */
  +/* Implemented as a terminal type by Jeremy Katz <katzj at redhat.com> based
  + * on a patch by Paulo César Pereira de Andrade <pcpa at 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 */
  --- /dev/null	2002-10-04 14:48:04.000000000 -0400
  +++ grub-0.93/stage2/graphics.h	2002-12-28 23:37:03.000000000 -0500
  @@ -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 */
  --- grub-0.93/stage2/shared.h.graphics	2002-12-28 23:37:03.000000000 -0500
  +++ grub-0.93/stage2/shared.h	2002-12-28 23:37:03.000000000 -0500
  @@ -856,6 +856,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);
  --- grub-0.93/stage2/stage2.c.graphics	2002-12-28 23:37:03.000000000 -0500
  +++ grub-0.93/stage2/stage2.c	2002-12-28 23:37:03.000000000 -0500
  @@ -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
  --- grub-0.93/stage2/term.h.graphics	2002-12-02 17:55:13.000000000 -0500
  +++ grub-0.93/stage2/term.h	2002-12-28 23:37:03.000000000 -0500
  @@ -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 */
  --- grub-0.94.orig/configure.ac	2003-10-20 02:25:30.000000000 +0900
  +++ grub-0.94/configure.ac	2004-02-05 14:23:41.000000000 +0900
  @@ -630,6 +630,10 @@
   CCASFLAGS='$(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)'
   AC_SUBST(CCASFLAGS)
   
  +dnl Graphical splashscreen support
  +AC_ARG_ENABLE(graphics,
  +  [  --disable-graphics      disable graphics terminal support])
  +AM_CONDITIONAL(GRAPHICS_SUPPORT, test "x$enable_graphics" != xno)
   
   dnl Output.
   AC_CONFIG_FILES([Makefile stage1/Makefile stage2/Makefile \
  
  
  



More information about the patches mailing list