updated on Wed Jan 18 04:00:29 UTC 2012
[aur-mirror.git] / grub-ext / grub-0.97-graphics.patch
blobe0baa902484bc6ddb4b993ae2c77c7dab96d88d3
1 diff -urpN grub-0.97/configure.ac grub-0.97-gfx/configure.ac
2 --- grub-0.97/configure.ac 2005-10-13 16:27:23.000000000 -0400
3 +++ grub-0.97-gfx/configure.ac 2005-10-13 16:27:35.000000000 -0400
4 @@ -595,6 +595,11 @@ AC_ARG_ENABLE(diskless,
5 [ --enable-diskless enable diskless support])
6 AM_CONDITIONAL(DISKLESS_SUPPORT, test "x$enable_diskless" = xyes)
8 +dnl Graphical splashscreen support
9 +AC_ARG_ENABLE(graphics,
10 + [ --disable-graphics disable graphics terminal support])
11 +AM_CONDITIONAL(GRAPHICS_SUPPORT, test "x$enable_graphics" != xno)
13 dnl Hercules terminal
14 AC_ARG_ENABLE(hercules,
15 [ --disable-hercules disable hercules terminal support])
16 diff -urpN grub-0.97/stage2/Makefile.am grub-0.97-gfx/stage2/Makefile.am
17 --- grub-0.97/stage2/Makefile.am 2005-10-13 16:27:23.000000000 -0400
18 +++ grub-0.97-gfx/stage2/Makefile.am 2005-10-13 16:27:35.000000000 -0400
19 @@ -7,7 +7,7 @@ noinst_HEADERS = apic.h defs.h dir.h dis
20 fat.h filesys.h freebsd.h fs.h hercules.h i386-elf.h \
21 imgact_aout.h iso9660.h jfs.h mb_header.h mb_info.h md5.h \
22 nbi.h pc_slice.h serial.h shared.h smp-imps.h term.h \
23 - terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h
24 + terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h graphics.h
25 EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS)
27 # For <stage1.h>.
28 @@ -19,7 +19,7 @@ libgrub_a_SOURCES = boot.c builtins.c ch
29 disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \
30 fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \
31 fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \
32 - terminfo.c tparm.c
33 + terminfo.c tparm.c graphics.c
34 libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \
35 -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
36 -DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
37 @@ -79,8 +79,14 @@ else
38 HERCULES_FLAGS =
39 endif
41 +if GRAPHICS_SUPPORT
42 +GRAPHICS_FLAGS = -DSUPPORT_GRAPHICS=1
43 +else
44 +GRAPHICS_FLAGS =
45 +endif
47 STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
48 - $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS)
49 + $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) $(GRAPHICS_FLAGS)
51 STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000
52 STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1
53 @@ -90,7 +96,8 @@ pre_stage2_exec_SOURCES = asm.S bios.c b
54 cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \
55 fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \
56 fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \
57 - hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c
58 + hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c \
59 + graphics.c
60 pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
61 pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
62 pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK)
63 diff -urpN grub-0.97/stage2/asm.S grub-0.97-gfx/stage2/asm.S
64 --- grub-0.97/stage2/asm.S 2005-10-13 16:27:23.000000000 -0400
65 +++ grub-0.97-gfx/stage2/asm.S 2005-10-13 16:27:35.000000000 -0400
66 @@ -2216,6 +2216,156 @@ ENTRY(console_setcursor)
67 pop %ebx
68 pop %ebp
69 ret
71 +/* graphics mode functions */
72 +#ifdef SUPPORT_GRAPHICS
73 +VARIABLE(cursorX)
74 +.word 0
75 +VARIABLE(cursorY)
76 +.word 0
77 +VARIABLE(cursorCount)
78 +.word 0
79 +VARIABLE(cursorBuf)
80 +.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
83 +/*
84 + * int set_videomode(mode)
85 + * BIOS call "INT 10H Function 0h" to set video mode
86 + * Call with %ah = 0x0
87 + * %al = video mode
88 + * Returns old videomode.
89 + */
90 +ENTRY(set_videomode)
91 + push %ebp
92 + push %ebx
93 + push %ecx
95 + movb 0x10(%esp), %cl
97 + call EXT_C(prot_to_real)
98 + .code16
100 + xorw %bx, %bx
101 + movb $0xf, %ah
102 + int $0x10 /* Get Current Video mode */
103 + movb %al, %ch
104 + xorb %ah, %ah
105 + movb %cl, %al
106 + int $0x10 /* Set Video mode */
108 + DATA32 call EXT_C(real_to_prot)
109 + .code32
111 + xorb %ah, %ah
112 + movb %ch, %al
114 + pop %ecx
115 + pop %ebx
116 + pop %ebp
117 + ret
121 + * unsigned char * graphics_get_font()
122 + * BIOS call "INT 10H Function 11h" to set font
123 + * Call with %ah = 0x11
124 + */
125 +ENTRY(graphics_get_font)
126 + push %ebp
127 + push %ebx
128 + push %ecx
129 + push %edx
131 + call EXT_C(prot_to_real)
132 + .code16
134 + movw $0x1130, %ax
135 + movb $6, %bh /* font 8x16 */
136 + int $0x10
137 + movw %bp, %dx
138 + movw %es, %cx
140 + DATA32 call EXT_C(real_to_prot)
141 + .code32
143 + xorl %eax, %eax
144 + movw %cx, %ax
145 + shll $4, %eax
146 + movw %dx, %ax
148 + pop %edx
149 + pop %ecx
150 + pop %ebx
151 + pop %ebp
152 + ret
157 + * graphics_set_palette(index, red, green, blue)
158 + * BIOS call "INT 10H Function 10h" to set individual dac register
159 + * Call with %ah = 0x10
160 + * %bx = register number
161 + * %ch = new value for green (0-63)
162 + * %cl = new value for blue (0-63)
163 + * %dh = new value for red (0-63)
164 + */
166 +ENTRY(graphics_set_palette)
167 + push %ebp
168 + push %eax
169 + push %ebx
170 + push %ecx
171 + push %edx
173 + movw $0x3c8, %bx /* address write mode register */
175 + /* wait vertical retrace */
177 + movw $0x3da, %dx
178 +l1b: inb %dx, %al /* wait vertical active display */
179 + test $8, %al
180 + jnz l1b
182 +l2b: inb %dx, %al /* wait vertical retrace */
183 + test $8, %al
184 + jnz l2b
186 + mov %bx, %dx
187 + movb 0x18(%esp), %al /* index */
188 + outb %al, %dx
189 + inc %dx
191 + movb 0x1c(%esp), %al /* red */
192 + outb %al, %dx
194 + movb 0x20(%esp), %al /* green */
195 + outb %al, %dx
197 + movb 0x24(%esp), %al /* blue */
198 + outb %al, %dx
200 + movw 0x18(%esp), %bx
202 + call EXT_C(prot_to_real)
203 + .code16
205 + movb %bl, %bh
206 + movw $0x1000, %ax
207 + int $0x10
209 + DATA32 call EXT_C(real_to_prot)
210 + .code32
212 + pop %edx
213 + pop %ecx
214 + pop %ebx
215 + pop %eax
216 + pop %ebp
217 + ret
219 +#endif /* SUPPORT_GRAPHICS */
222 * getrtsecs()
223 diff -urpN grub-0.97/stage2/builtins.c grub-0.97-gfx/stage2/builtins.c
224 --- grub-0.97/stage2/builtins.c 2005-10-13 16:27:23.000000000 -0400
225 +++ grub-0.97-gfx/stage2/builtins.c 2005-10-13 16:27:35.000000000 -0400
226 @@ -852,6 +852,138 @@ static struct builtin builtin_dhcp =
228 #endif /* SUPPORT_NETBOOT */
230 +static int terminal_func (char *arg, int flags);
232 +#ifdef SUPPORT_GRAPHICS
234 +static int splashimage_func(char *arg, int flags) {
235 + char splashimage[64];
236 + int i;
238 + /* filename can only be 64 characters due to our buffer size */
239 + if (strlen(arg) > 63)
240 + return 1;
241 + if (flags == BUILTIN_CMDLINE) {
242 + if (!grub_open(arg))
243 + return 1;
244 + grub_close();
247 + strcpy(splashimage, arg);
249 + /* get rid of TERM_NEED_INIT from the graphics terminal. */
250 + for (i = 0; term_table[i].name; i++) {
251 + if (grub_strcmp (term_table[i].name, "graphics") == 0) {
252 + term_table[i].flags &= ~TERM_NEED_INIT;
253 + break;
257 + graphics_set_splash(splashimage);
259 + if (flags == BUILTIN_CMDLINE && graphics_inited) {
260 + graphics_end();
261 + graphics_init();
262 + graphics_cls();
265 + /* FIXME: should we be explicitly switching the terminal as a
266 + * side effect here? */
267 + terminal_func("graphics", flags);
269 + return 0;
272 +static struct builtin builtin_splashimage =
274 + "splashimage",
275 + splashimage_func,
276 + BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
277 + "splashimage FILE",
278 + "Load FILE as the background image when in graphics mode."
282 +/* foreground */
283 +static int
284 +foreground_func(char *arg, int flags)
286 + if (grub_strlen(arg) == 6) {
287 + int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
288 + int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
289 + int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
291 + foreground = (r << 16) | (g << 8) | b;
292 + if (graphics_inited)
293 + graphics_set_palette(15, r, g, b);
295 + return (0);
298 + return (1);
301 +static struct builtin builtin_foreground =
303 + "foreground",
304 + foreground_func,
305 + BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
306 + "foreground RRGGBB",
307 + "Sets the foreground color when in graphics mode."
308 + "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
312 +/* background */
313 +static int
314 +background_func(char *arg, int flags)
316 + if (grub_strlen(arg) == 6) {
317 + int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
318 + int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
319 + int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
321 + background = (r << 16) | (g << 8) | b;
322 + if (graphics_inited)
323 + graphics_set_palette(0, r, g, b);
324 + return (0);
327 + return (1);
330 +static struct builtin builtin_background =
332 + "background",
333 + background_func,
334 + BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
335 + "background RRGGBB",
336 + "Sets the background color when in graphics mode."
337 + "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
340 +#endif /* SUPPORT_GRAPHICS */
343 +/* clear */
344 +static int
345 +clear_func()
347 + if (current_term->cls)
348 + current_term->cls();
350 + return 0;
353 +static struct builtin builtin_clear =
355 + "clear",
356 + clear_func,
357 + BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
358 + "clear",
359 + "Clear the screen"
363 /* displayapm */
364 static int
365 @@ -4085,7 +4217,7 @@ static struct builtin builtin_setup =
369 -#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
370 +#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS)
371 /* terminal */
372 static int
373 terminal_func (char *arg, int flags)
374 @@ -4244,17 +4376,21 @@ terminal_func (char *arg, int flags)
375 end:
376 current_term = term_table + default_term;
377 current_term->flags = term_flags;
380 if (lines)
381 max_lines = lines;
382 else
383 - /* 24 would be a good default value. */
384 - max_lines = 24;
386 + max_lines = current_term->max_lines;
388 /* If the interface is currently the command-line,
389 restart it to repaint the screen. */
390 - if (current_term != prev_term && (flags & BUILTIN_CMDLINE))
391 + if ((current_term != prev_term) && (flags & BUILTIN_CMDLINE)){
392 + if (prev_term->shutdown)
393 + prev_term->shutdown();
394 + if (current_term->startup)
395 + current_term->startup();
396 grub_longjmp (restart_cmdline_env, 0);
399 return 0;
401 @@ -4264,7 +4400,7 @@ static struct builtin builtin_terminal =
402 "terminal",
403 terminal_func,
404 BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
405 - "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules]",
406 + "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules] [graphics]",
407 "Select a terminal. When multiple terminals are specified, wait until"
408 " you push any key to continue. If both console and serial are specified,"
409 " the terminal to which you input a key first will be selected. If no"
410 @@ -4276,7 +4412,7 @@ static struct builtin builtin_terminal =
411 " seconds. The option --lines specifies the maximum number of lines."
412 " The option --silent is used to suppress messages."
414 -#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */
415 +#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */
418 #ifdef SUPPORT_SERIAL
419 @@ -4795,6 +4931,9 @@ static struct builtin builtin_vbeprobe =
420 /* The table of builtin commands. Sorted in dictionary order. */
421 struct builtin *builtin_table[] =
423 +#ifdef SUPPORT_GRAPHICS
424 + &builtin_background,
425 +#endif
426 &builtin_blocklist,
427 &builtin_boot,
428 #ifdef SUPPORT_NETBOOT
429 @@ -4802,6 +4941,7 @@ struct builtin *builtin_table[] =
430 #endif /* SUPPORT_NETBOOT */
431 &builtin_cat,
432 &builtin_chainloader,
433 + &builtin_clear,
434 &builtin_cmp,
435 &builtin_color,
436 &builtin_configfile,
437 @@ -4821,6 +4961,9 @@ struct builtin *builtin_table[] =
438 &builtin_embed,
439 &builtin_fallback,
440 &builtin_find,
441 +#ifdef SUPPORT_GRAPHICS
442 + &builtin_foreground,
443 +#endif
444 &builtin_fstest,
445 &builtin_geometry,
446 &builtin_halt,
447 @@ -4864,9 +5007,12 @@ struct builtin *builtin_table[] =
448 #endif /* SUPPORT_SERIAL */
449 &builtin_setkey,
450 &builtin_setup,
451 -#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
452 +#ifdef SUPPORT_GRAPHICS
453 + &builtin_splashimage,
454 +#endif /* SUPPORT_GRAPHICS */
455 +#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS)
456 &builtin_terminal,
457 -#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */
458 +#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */
459 #ifdef SUPPORT_SERIAL
460 &builtin_terminfo,
461 #endif /* SUPPORT_SERIAL */
462 diff -urpN grub-0.97/stage2/char_io.c grub-0.97-gfx/stage2/char_io.c
463 --- grub-0.97/stage2/char_io.c 2005-10-13 16:27:23.000000000 -0400
464 +++ grub-0.97-gfx/stage2/char_io.c 2005-10-13 16:27:35.000000000 -0400
465 @@ -35,6 +35,7 @@ struct term_entry term_table[] =
467 "console",
469 + 24,
470 console_putchar,
471 console_checkkey,
472 console_getkey,
473 @@ -43,13 +44,16 @@ struct term_entry term_table[] =
474 console_cls,
475 console_setcolorstate,
476 console_setcolor,
477 - console_setcursor
478 + console_setcursor,
479 + 0,
482 #ifdef SUPPORT_SERIAL
484 "serial",
485 /* A serial device must be initialized. */
486 TERM_NEED_INIT,
487 + 24,
488 serial_putchar,
489 serial_checkkey,
490 serial_getkey,
491 @@ -58,6 +62,8 @@ struct term_entry term_table[] =
492 serial_cls,
493 serial_setcolorstate,
495 + 0,
496 + 0,
499 #endif /* SUPPORT_SERIAL */
500 @@ -65,6 +71,7 @@ struct term_entry term_table[] =
502 "hercules",
504 + 24,
505 hercules_putchar,
506 console_checkkey,
507 console_getkey,
508 @@ -73,9 +80,28 @@ struct term_entry term_table[] =
509 hercules_cls,
510 hercules_setcolorstate,
511 hercules_setcolor,
512 - hercules_setcursor
513 + hercules_setcursor,
514 + 0,
517 #endif /* SUPPORT_HERCULES */
518 +#ifdef SUPPORT_GRAPHICS
519 + { "graphics",
520 + TERM_NEED_INIT, /* flags */
521 + 30, /* number of lines */
522 + graphics_putchar, /* putchar */
523 + console_checkkey, /* checkkey */
524 + console_getkey, /* getkey */
525 + graphics_getxy, /* getxy */
526 + graphics_gotoxy, /* gotoxy */
527 + graphics_cls, /* cls */
528 + graphics_setcolorstate, /* setcolorstate */
529 + graphics_setcolor, /* setcolor */
530 + graphics_setcursor, /* nocursor */
531 + graphics_init, /* initialize */
532 + graphics_end /* shutdown */
533 + },
534 +#endif /* SUPPORT_GRAPHICS */
535 /* This must be the last entry. */
536 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
538 @@ -1046,13 +1072,15 @@ grub_putchar (int c)
539 the following grub_printf call will print newlines. */
540 count_lines = -1;
542 + grub_printf("\n");
543 if (current_term->setcolorstate)
544 current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
546 - grub_printf ("\n[Hit return to continue]");
547 + grub_printf ("[Hit return to continue]");
549 if (current_term->setcolorstate)
550 current_term->setcolorstate (COLOR_STATE_NORMAL);
555 @@ -1090,7 +1118,7 @@ void
556 cls (void)
558 /* If the terminal is dumb, there is no way to clean the terminal. */
559 - if (current_term->flags & TERM_DUMB)
560 + if (current_term->flags & TERM_DUMB)
561 grub_putchar ('\n');
562 else
563 current_term->cls ();
564 @@ -1217,6 +1245,16 @@ memcheck (int addr, int len)
565 return ! errnum;
568 +void
569 +grub_memcpy(void *dest, const void *src, int len)
571 + int i;
572 + register char *d = (char*)dest, *s = (char*)src;
574 + for (i = 0; i < len; i++)
575 + d[i] = s[i];
578 void *
579 grub_memmove (void *to, const void *from, int len)
581 diff -urpN grub-0.97/stage2/graphics.c grub-0.97-gfx/stage2/graphics.c
582 --- grub-0.97/stage2/graphics.c 1969-12-31 20:00:00.000000000 -0400
583 +++ grub-0.97-gfx/stage2/graphics.c 2005-10-13 16:27:35.000000000 -0400
584 @@ -0,0 +1,552 @@
585 +/* graphics.c - graphics mode support for GRUB */
586 +/* Implemented as a terminal type by Jeremy Katz <katzj@redhat.com> based
587 + * on a patch by Paulo César Pereira de Andrade <pcpa@conectiva.com.br>
588 + */
590 + * GRUB -- GRand Unified Bootloader
591 + * Copyright (C) 2001,2002 Red Hat, Inc.
592 + * Portions copyright (C) 2000 Conectiva, Inc.
594 + * This program is free software; you can redistribute it and/or modify
595 + * it under the terms of the GNU General Public License as published by
596 + * the Free Software Foundation; either version 2 of the License, or
597 + * (at your option) any later version.
599 + * This program is distributed in the hope that it will be useful,
600 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
601 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
602 + * GNU General Public License for more details.
604 + * You should have received a copy of the GNU General Public License
605 + * along with this program; if not, write to the Free Software
606 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
607 + */
611 +#ifdef SUPPORT_GRAPHICS
613 +#include <term.h>
614 +#include <shared.h>
615 +#include <graphics.h>
617 +int saved_videomode;
618 +unsigned char *font8x16;
620 +int graphics_inited = 0;
621 +static char splashimage[64];
623 +#define VSHADOW VSHADOW1
624 +unsigned char VSHADOW1[38400];
625 +unsigned char VSHADOW2[38400];
626 +unsigned char VSHADOW4[38400];
627 +unsigned char VSHADOW8[38400];
629 +/* constants to define the viewable area */
630 +const int x0 = 0;
631 +const int x1 = 80;
632 +const int y0 = 0;
633 +const int y1 = 30;
635 +/* text buffer has to be kept around so that we can write things as we
636 + * scroll and the like */
637 +unsigned short text[80 * 30];
639 +/* why do these have to be kept here? */
640 +int foreground = (63 << 16) | (63 << 8) | (63), background = 0, border = 0;
642 +/* current position */
643 +static int fontx = 0;
644 +static int fonty = 0;
646 +/* global state so that we don't try to recursively scroll or cursor */
647 +static int no_scroll = 0;
649 +/* color state */
650 +static int graphics_standard_color = A_NORMAL;
651 +static int graphics_normal_color = A_NORMAL;
652 +static int graphics_highlight_color = A_REVERSE;
653 +static int graphics_current_color = A_NORMAL;
654 +static color_state graphics_color_state = COLOR_STATE_STANDARD;
657 +/* graphics local functions */
658 +static void graphics_setxy(int col, int row);
659 +static void graphics_scroll();
661 +/* FIXME: where do these really belong? */
662 +static inline void outb(unsigned short port, unsigned char val)
664 + __asm __volatile ("outb %0,%1"::"a" (val), "d" (port));
667 +static void MapMask(int value) {
668 + outb(0x3c4, 2);
669 + outb(0x3c5, value);
672 +/* bit mask register */
673 +static void BitMask(int value) {
674 + outb(0x3ce, 8);
675 + outb(0x3cf, value);
680 +/* Set the splash image */
681 +void graphics_set_splash(char *splashfile) {
682 + grub_strcpy(splashimage, splashfile);
685 +/* Get the current splash image */
686 +char *graphics_get_splash(void) {
687 + return splashimage;
690 +/* Initialize a vga16 graphics display with the palette based off of
691 + * the image in splashimage. If the image doesn't exist, leave graphics
692 + * mode. */
693 +int graphics_init()
695 + if (!graphics_inited) {
696 + saved_videomode = set_videomode(0x12);
699 + if (!read_image(splashimage)) {
700 + set_videomode(saved_videomode);
701 + grub_printf("failed to read image\n");
702 + return 0;
705 + font8x16 = (unsigned char*)graphics_get_font();
707 + graphics_inited = 1;
709 + /* make sure that the highlight color is set correctly */
710 + graphics_highlight_color = ((graphics_normal_color >> 4) |
711 + ((graphics_normal_color & 0xf) << 4));
713 + return 1;
716 +/* Leave graphics mode */
717 +void graphics_end(void)
719 + if (graphics_inited) {
720 + set_videomode(saved_videomode);
721 + graphics_inited = 0;
725 +/* Print ch on the screen. Handle any needed scrolling or the like */
726 +void graphics_putchar(int ch) {
727 + ch &= 0xff;
729 + graphics_cursor(0);
731 + if (ch == '\n') {
732 + if (fonty + 1 < y1)
733 + graphics_setxy(fontx, fonty + 1);
734 + else
735 + graphics_scroll();
736 + graphics_cursor(1);
737 + return;
738 + } else if (ch == '\r') {
739 + graphics_setxy(x0, fonty);
740 + graphics_cursor(1);
741 + return;
744 + graphics_cursor(0);
746 + text[fonty * 80 + fontx] = ch;
747 + text[fonty * 80 + fontx] &= 0x00ff;
748 + if (graphics_current_color & 0xf0)
749 + text[fonty * 80 + fontx] |= 0x100;
751 + graphics_cursor(0);
753 + if ((fontx + 1) >= x1) {
754 + graphics_setxy(x0, fonty);
755 + if (fonty + 1 < y1)
756 + graphics_setxy(x0, fonty + 1);
757 + else
758 + graphics_scroll();
759 + } else {
760 + graphics_setxy(fontx + 1, fonty);
763 + graphics_cursor(1);
766 +/* get the current location of the cursor */
767 +int graphics_getxy(void) {
768 + return (fontx << 8) | fonty;
771 +void graphics_gotoxy(int x, int y) {
772 + graphics_cursor(0);
774 + graphics_setxy(x, y);
776 + graphics_cursor(1);
779 +void graphics_cls(void) {
780 + int i;
781 + unsigned char *mem, *s1, *s2, *s4, *s8;
783 + graphics_cursor(0);
784 + graphics_gotoxy(x0, y0);
786 + mem = (unsigned char*)VIDEOMEM;
787 + s1 = (unsigned char*)VSHADOW1;
788 + s2 = (unsigned char*)VSHADOW2;
789 + s4 = (unsigned char*)VSHADOW4;
790 + s8 = (unsigned char*)VSHADOW8;
792 + for (i = 0; i < 80 * 30; i++)
793 + text[i] = ' ';
794 + graphics_cursor(1);
796 + BitMask(0xff);
798 + /* plano 1 */
799 + MapMask(1);
800 + grub_memcpy(mem, s1, 38400);
802 + /* plano 2 */
803 + MapMask(2);
804 + grub_memcpy(mem, s2, 38400);
806 + /* plano 3 */
807 + MapMask(4);
808 + grub_memcpy(mem, s4, 38400);
810 + /* plano 4 */
811 + MapMask(8);
812 + grub_memcpy(mem, s8, 38400);
814 + MapMask(15);
818 +void graphics_setcolorstate (color_state state) {
819 + switch (state) {
820 + case COLOR_STATE_STANDARD:
821 + graphics_current_color = graphics_standard_color;
822 + break;
823 + case COLOR_STATE_NORMAL:
824 + graphics_current_color = graphics_normal_color;
825 + break;
826 + case COLOR_STATE_HIGHLIGHT:
827 + graphics_current_color = graphics_highlight_color;
828 + break;
829 + default:
830 + graphics_current_color = graphics_standard_color;
831 + break;
834 + graphics_color_state = state;
837 +void graphics_setcolor (int normal_color, int highlight_color) {
838 + graphics_normal_color = normal_color;
839 + graphics_highlight_color = highlight_color;
841 + graphics_setcolorstate (graphics_color_state);
844 +void graphics_setcursor (int on) {
845 + /* FIXME: we don't have a cursor in graphics */
846 + return;
849 +/* Read in the splashscreen image and set the palette up appropriately.
850 + * Format of splashscreen is an xpm (can be gzipped) with 16 colors and
851 + * 640x480. */
852 +int read_image(char *s)
854 + char buf[32], pal[16];
855 + unsigned char c, base, mask, *s1, *s2, *s4, *s8;
856 + unsigned i, len, idx, colors, x, y, width, height;
858 + if (!grub_open(s))
859 + return 0;
861 + /* read header */
862 + if (!grub_read((char*)&buf, 10) || grub_memcmp(buf, "/* XPM */\n", 10)) {
863 + grub_close();
864 + return 0;
867 + /* parse info */
868 + while (grub_read(&c, 1)) {
869 + if (c == '"')
870 + break;
873 + while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
876 + i = 0;
877 + width = c - '0';
878 + while (grub_read(&c, 1)) {
879 + if (c >= '0' && c <= '9')
880 + width = width * 10 + c - '0';
881 + else
882 + break;
884 + while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
887 + height = c - '0';
888 + while (grub_read(&c, 1)) {
889 + if (c >= '0' && c <= '9')
890 + height = height * 10 + c - '0';
891 + else
892 + break;
894 + while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
897 + colors = c - '0';
898 + while (grub_read(&c, 1)) {
899 + if (c >= '0' && c <= '9')
900 + colors = colors * 10 + c - '0';
901 + else
902 + break;
905 + base = 0;
906 + while (grub_read(&c, 1) && c != '"')
909 + /* palette */
910 + for (i = 0, idx = 1; i < colors; i++) {
911 + len = 0;
913 + while (grub_read(&c, 1) && c != '"')
915 + grub_read(&c, 1); /* char */
916 + base = c;
917 + grub_read(buf, 4); /* \t c # */
919 + while (grub_read(&c, 1) && c != '"') {
920 + if (len < sizeof(buf))
921 + buf[len++] = c;
924 + if (len == 6 && idx < 15) {
925 + int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2;
926 + int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2;
927 + int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2;
929 + pal[idx] = base;
930 + graphics_set_palette(idx, r, g, b);
931 + ++idx;
935 + x = y = len = 0;
937 + s1 = (unsigned char*)VSHADOW1;
938 + s2 = (unsigned char*)VSHADOW2;
939 + s4 = (unsigned char*)VSHADOW4;
940 + s8 = (unsigned char*)VSHADOW8;
942 + for (i = 0; i < 38400; i++)
943 + s1[i] = s2[i] = s4[i] = s8[i] = 0;
945 + /* parse xpm data */
946 + while (y < height) {
947 + while (1) {
948 + if (!grub_read(&c, 1)) {
949 + grub_close();
950 + return 0;
952 + if (c == '"')
953 + break;
956 + while (grub_read(&c, 1) && c != '"') {
957 + for (i = 1; i < 15; i++)
958 + if (pal[i] == c) {
959 + c = i;
960 + break;
963 + mask = 0x80 >> (x & 7);
964 + if (c & 1)
965 + s1[len + (x >> 3)] |= mask;
966 + if (c & 2)
967 + s2[len + (x >> 3)] |= mask;
968 + if (c & 4)
969 + s4[len + (x >> 3)] |= mask;
970 + if (c & 8)
971 + s8[len + (x >> 3)] |= mask;
973 + if (++x >= 640) {
974 + x = 0;
976 + if (y < 480)
977 + len += 80;
978 + ++y;
983 + grub_close();
985 + graphics_set_palette(0, (background >> 16), (background >> 8) & 63,
986 + background & 63);
987 + graphics_set_palette(15, (foreground >> 16), (foreground >> 8) & 63,
988 + foreground & 63);
989 + graphics_set_palette(0x11, (border >> 16), (border >> 8) & 63,
990 + border & 63);
992 + return 1;
996 +/* Convert a character which is a hex digit to the appropriate integer */
997 +int hex(int v)
999 + if (v >= 'A' && v <= 'F')
1000 + return (v - 'A' + 10);
1001 + if (v >= 'a' && v <= 'f')
1002 + return (v - 'a' + 10);
1003 + return (v - '0');
1007 +/* move the graphics cursor location to col, row */
1008 +static void graphics_setxy(int col, int row) {
1009 + if (col >= x0 && col < x1) {
1010 + fontx = col;
1011 + cursorX = col << 3;
1013 + if (row >= y0 && row < y1) {
1014 + fonty = row;
1015 + cursorY = row << 4;
1019 +/* scroll the screen */
1020 +static void graphics_scroll() {
1021 + int i, j;
1023 + /* we don't want to scroll recursively... that would be bad */
1024 + if (no_scroll)
1025 + return;
1026 + no_scroll = 1;
1028 + /* move everything up a line */
1029 + for (j = y0 + 1; j < y1; j++) {
1030 + graphics_gotoxy(x0, j - 1);
1031 + for (i = x0; i < x1; i++) {
1032 + graphics_putchar(text[j * 80 + i]);
1036 + /* last line should be blank */
1037 + graphics_gotoxy(x0, y1 - 1);
1038 + for (i = x0; i < x1; i++)
1039 + graphics_putchar(' ');
1040 + graphics_setxy(x0, y1 - 1);
1042 + no_scroll = 0;
1046 +void graphics_cursor(int set) {
1047 + unsigned char *pat, *mem, *ptr, chr[16 << 2];
1048 + int i, ch, invert, offset;
1050 + if (set && no_scroll)
1051 + return;
1053 + offset = cursorY * 80 + fontx;
1054 + ch = text[fonty * 80 + fontx] & 0xff;
1055 + invert = (text[fonty * 80 + fontx] & 0xff00) != 0;
1056 + pat = font8x16 + (ch << 4);
1058 + mem = (unsigned char*)VIDEOMEM + offset;
1060 + if (!set) {
1061 + for (i = 0; i < 16; i++) {
1062 + unsigned char mask = pat[i];
1064 + if (!invert) {
1065 + chr[i ] = ((unsigned char*)VSHADOW1)[offset];
1066 + chr[16 + i] = ((unsigned char*)VSHADOW2)[offset];
1067 + chr[32 + i] = ((unsigned char*)VSHADOW4)[offset];
1068 + chr[48 + i] = ((unsigned char*)VSHADOW8)[offset];
1070 + /* FIXME: if (shade) */
1071 + if (1) {
1072 + if (ch == DISP_VERT || ch == DISP_LL ||
1073 + ch == DISP_UR || ch == DISP_LR) {
1074 + unsigned char pmask = ~(pat[i] >> 1);
1076 + chr[i ] &= pmask;
1077 + chr[16 + i] &= pmask;
1078 + chr[32 + i] &= pmask;
1079 + chr[48 + i] &= pmask;
1081 + if (i > 0 && ch != DISP_VERT) {
1082 + unsigned char pmask = ~(pat[i - 1] >> 1);
1084 + chr[i ] &= pmask;
1085 + chr[16 + i] &= pmask;
1086 + chr[32 + i] &= pmask;
1087 + chr[48 + i] &= pmask;
1088 + if (ch == DISP_HORIZ || ch == DISP_UR || ch == DISP_LR) {
1089 + pmask = ~pat[i - 1];
1091 + chr[i ] &= pmask;
1092 + chr[16 + i] &= pmask;
1093 + chr[32 + i] &= pmask;
1094 + chr[48 + i] &= pmask;
1098 + chr[i ] |= mask;
1099 + chr[16 + i] |= mask;
1100 + chr[32 + i] |= mask;
1101 + chr[48 + i] |= mask;
1103 + offset += 80;
1105 + else {
1106 + chr[i ] = mask;
1107 + chr[16 + i] = mask;
1108 + chr[32 + i] = mask;
1109 + chr[48 + i] = mask;
1113 + else {
1114 + MapMask(15);
1115 + ptr = mem;
1116 + for (i = 0; i < 16; i++, ptr += 80) {
1117 + cursorBuf[i] = pat[i];
1118 + *ptr = ~pat[i];
1120 + return;
1123 + offset = 0;
1124 + for (i = 1; i < 16; i <<= 1, offset += 16) {
1125 + int j;
1127 + MapMask(i);
1128 + ptr = mem;
1129 + for (j = 0; j < 16; j++, ptr += 80)
1130 + *ptr = chr[j + offset];
1133 + MapMask(15);
1136 +#endif /* SUPPORT_GRAPHICS */
1137 diff -urpN grub-0.97/stage2/graphics.h grub-0.97-gfx/stage2/graphics.h
1138 --- grub-0.97/stage2/graphics.h 1969-12-31 20:00:00.000000000 -0400
1139 +++ grub-0.97-gfx/stage2/graphics.h 2005-10-13 16:27:35.000000000 -0400
1140 @@ -0,0 +1,42 @@
1141 +/* graphics.h - graphics console interface */
1143 + * GRUB -- GRand Unified Bootloader
1144 + * Copyright (C) 2002 Free Software Foundation, Inc.
1146 + * This program is free software; you can redistribute it and/or modify
1147 + * it under the terms of the GNU General Public License as published by
1148 + * the Free Software Foundation; either version 2 of the License, or
1149 + * (at your option) any later version.
1151 + * This program is distributed in the hope that it will be useful,
1152 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1153 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1154 + * GNU General Public License for more details.
1156 + * You should have received a copy of the GNU General Public License
1157 + * along with this program; if not, write to the Free Software
1158 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1159 + */
1161 +#ifndef GRAPHICS_H
1162 +#define GRAPHICS_H
1164 +/* magic constant */
1165 +#define VIDEOMEM 0xA0000
1167 +/* function prototypes */
1168 +char *graphics_get_splash(void);
1170 +int read_image(char *s);
1171 +void graphics_cursor(int set);
1173 +/* function prototypes for asm functions */
1174 +void * graphics_get_font();
1175 +void graphics_set_palette(int idx, int red, int green, int blue);
1176 +void set_int1c_handler();
1177 +void unset_int1c_handler();
1179 +extern short cursorX, cursorY;
1180 +extern char cursorBuf[16];
1182 +#endif /* GRAPHICS_H */
1183 diff -urpN grub-0.97/stage2/shared.h grub-0.97-gfx/stage2/shared.h
1184 --- grub-0.97/stage2/shared.h 2005-10-13 16:27:23.000000000 -0400
1185 +++ grub-0.97-gfx/stage2/shared.h 2005-10-13 16:27:35.000000000 -0400
1186 @@ -871,6 +871,7 @@ int grub_sprintf (char *buffer, const ch
1187 int grub_tolower (int c);
1188 int grub_isspace (int c);
1189 int grub_strncat (char *s1, const char *s2, int n);
1190 +void grub_memcpy(void *dest, const void *src, int len);
1191 void *grub_memmove (void *to, const void *from, int len);
1192 void *grub_memset (void *start, int c, int len);
1193 int grub_strncat (char *s1, const char *s2, int n);
1194 diff -urpN grub-0.97/stage2/stage2.c grub-0.97-gfx/stage2/stage2.c
1195 --- grub-0.97/stage2/stage2.c 2005-10-13 16:27:23.000000000 -0400
1196 +++ grub-0.97-gfx/stage2/stage2.c 2005-10-13 16:27:35.000000000 -0400
1197 @@ -233,6 +233,7 @@ run_menu (char *menu_entries, char *conf
1199 int c, time1, time2 = -1, first_entry = 0;
1200 char *cur_entry = 0;
1201 + struct term_entry *prev_term = NULL;
1204 * Main loop for menu UI.
1205 @@ -714,6 +715,15 @@ restart:
1207 cls ();
1208 setcursor (1);
1209 + /* if our terminal needed initialization, we should shut it down
1210 + * before booting the kernel, but we want to save what it was so
1211 + * we can come back if needed */
1212 + prev_term = current_term;
1213 + if (current_term->shutdown)
1215 + (*current_term->shutdown)();
1216 + current_term = term_table; /* assumption: console is first */
1219 while (1)
1221 @@ -748,6 +758,13 @@ restart:
1222 break;
1225 + /* if we get back here, we should go back to what our term was before */
1226 + current_term = prev_term;
1227 + if (current_term->startup)
1228 + /* if our terminal fails to initialize, fall back to console since
1229 + * it should always work */
1230 + if ((*current_term->startup)() == 0)
1231 + current_term = term_table; /* we know that console is first */
1232 show_menu = 1;
1233 goto restart;
1235 @@ -1050,6 +1067,10 @@ cmain (void)
1236 while (is_preset);
1239 + /* go ahead and make sure the terminal is setup */
1240 + if (current_term->startup)
1241 + (*current_term->startup)();
1243 if (! num_entries)
1245 /* If no acceptable config file, goto command-line, starting
1246 diff -urpN grub-0.97/stage2/term.h grub-0.97-gfx/stage2/term.h
1247 --- grub-0.97/stage2/term.h 2005-10-13 16:27:23.000000000 -0400
1248 +++ grub-0.97-gfx/stage2/term.h 2005-10-13 16:27:35.000000000 -0400
1249 @@ -60,6 +60,8 @@ struct term_entry
1250 const char *name;
1251 /* The feature flags defined above. */
1252 unsigned long flags;
1253 + /* Default for maximum number of lines if not specified */
1254 + unsigned short max_lines;
1255 /* Put a character. */
1256 void (*putchar) (int c);
1257 /* Check if any input character is available. */
1258 @@ -79,6 +81,11 @@ struct term_entry
1259 void (*setcolor) (int normal_color, int highlight_color);
1260 /* Turn on/off the cursor. */
1261 int (*setcursor) (int on);
1263 + /* function to start a terminal */
1264 + int (*startup) (void);
1265 + /* function to use to shutdown a terminal */
1266 + void (*shutdown) (void);
1269 /* This lists up available terminals. */
1270 @@ -124,4 +131,23 @@ void hercules_setcolor (int normal_color
1271 int hercules_setcursor (int on);
1272 #endif
1274 +#ifdef SUPPORT_GRAPHICS
1275 +extern int foreground, background, border, graphics_inited;
1277 +void graphics_set_splash(char *splashfile);
1278 +int set_videomode (int mode);
1279 +void graphics_putchar (int c);
1280 +int graphics_getxy(void);
1281 +void graphics_gotoxy(int x, int y);
1282 +void graphics_cls(void);
1283 +void graphics_setcolorstate (color_state state);
1284 +void graphics_setcolor (int normal_color, int highlight_color);
1285 +void graphics_setcursor (int on);
1286 +int graphics_init(void);
1287 +void graphics_end(void);
1289 +int hex(int v);
1290 +void graphics_set_palette(int idx, int red, int green, int blue);
1291 +#endif /* SUPPORT_GRAPHICS */
1293 #endif /* ! GRUB_TERM_HEADER */