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