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