1diff -Naur grub-0.97.orig/configure.ac grub-0.97/configure.ac 2--- grub-0.97.orig/configure.ac 2005-05-07 23:36:03.000000000 -0300 3+++ grub-0.97/configure.ac 2005-06-12 20:56:49.000000000 -0300 4@@ -595,6 +595,11 @@ 5 [ --enable-diskless enable diskless support]) 6 AM_CONDITIONAL(DISKLESS_SUPPORT, test "x$enable_diskless" = xyes) 7 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) 12+ 13 dnl Hercules terminal 14 AC_ARG_ENABLE(hercules, 15 [ --disable-hercules disable hercules terminal support]) 16diff -Naur grub-0.97.orig/stage2/asm.S grub-0.97/stage2/asm.S 17--- grub-0.97.orig/stage2/asm.S 2004-06-19 13:55:22.000000000 -0300 18+++ grub-0.97/stage2/asm.S 2005-06-13 14:05:31.000000000 -0300 19@@ -2216,7 +2216,304 @@ 20 pop %ebx 21 pop %ebp 22 ret 23- 24+ 25+ 26+/* graphics mode functions */ 27+#ifdef SUPPORT_GRAPHICS 28+VARIABLE(cursorX) 29+.word 0 30+VARIABLE(cursorY) 31+.word 0 32+VARIABLE(cursorCount) 33+.word 0 34+VARIABLE(cursorBuf) 35+.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 36+ 37+ 38+/* 39+ * set_int1c_handler(void) 40+ */ 41+ENTRY(set_int1c_handler) 42+ pushl %edi 43+ 44+ /* save the original int1c handler */ 45+ movl $0x70, %edi 46+ movw (%edi), %ax 47+ movw %ax, ABS(int1c_offset) 48+ movw 2(%edi), %ax 49+ movw %ax, ABS(int1c_segment) 50+ 51+ /* save the new int1c handler */ 52+ movw $ABS(int1c_handler), %ax 53+ movw %ax, (%edi) 54+ xorw %ax, %ax 55+ movw %ax, 2(%edi) 56+ 57+ popl %edi 58+ ret 59+ 60+ 61+/* 62+ * unset_int1c_handler(void) 63+ */ 64+ENTRY(unset_int1c_handler) 65+ pushl %edi 66+ 67+ /* check if int1c_handler is set */ 68+ movl $0x70, %edi 69+ movw $ABS(int1c_handler), %ax 70+ cmpw %ax, (%edi) 71+ jne int1c_1 72+ xorw %ax, %ax 73+ cmpw %ax, 2(%edi) 74+ jne int1c_1 75+ 76+ /* restore the original */ 77+ movw ABS(int1c_offset), %ax 78+ movw %ax, (%edi) 79+ movw ABS(int1c_segment), %ax 80+ movw %ax, 2(%edi) 81+ 82+int1c_1: 83+ popl %edi 84+ ret 85+ 86+ 87+/* 88+ * blinks graphics cursor 89+ */ 90+ .code16 91+write_data: 92+ movw $0, %ax 93+ movw %ax, %ds 94+ 95+ mov $0xA000, %ax /* video in es:di */ 96+ mov %ax, %es 97+ mov $80, %ax 98+ movw $ABS(cursorY), %si 99+ mov %ds:(%si), %bx 100+ mul %bx 101+ movw $ABS(cursorX), %si 102+ mov %ds:(%si), %bx 103+ shr $3, %bx /* %bx /= 8 */ 104+ add %bx, %ax 105+ mov %ax, %di 106+ 107+ movw $ABS(cursorBuf), %si /* fontBuf in ds:si */ 108+ 109+ /* prepare for data moving */ 110+ mov $16, %dx /* altura da fonte */ 111+ mov $80, %bx /* bytes por linha */ 112+ 113+write_loop: 114+ movb %ds:(%si), %al 115+ xorb $0xff, %al 116+ movb %al, %ds:(%si) /* invert cursorBuf */ 117+ movb %al, %es:(%di) /* write to video */ 118+ add %bx, %di 119+ inc %si 120+ dec %dx 121+ jg write_loop 122+ ret 123+ 124+int1c_handler: 125+ pusha 126+ mov $0, %ax 127+ mov %ax, %ds 128+ mov $ABS(cursorCount), %si 129+ mov %ds:(%si), %ax 130+ inc %ax 131+ mov %ax, %ds:(%si) 132+ cmp $9, %ax 133+ jne int1c_done 134+ 135+ mov $0, %ax 136+ mov %ax, %ds:(%si) 137+ call write_data 138+ 139+int1c_done: 140+ popa 141+ iret 142+ /* call previous int1c handler */ 143+ /* ljmp */ 144+ .byte 0xea 145+int1c_offset: .word 0 146+int1c_segment: .word 0 147+ .code32 148+ 149+ 150+/* 151+ * unsigned char set_videomode(unsigned char mode) 152+ * BIOS call "INT 10H Function 0h" to set video mode 153+ * Call with %ah = 0x0 154+ * %al = video mode 155+ * Returns old videomode. 156+ */ 157+ENTRY(set_videomode) 158+ pushl %ebp 159+ movl %esp,%ebp 160+ pushl %ebx 161+ pushl %ecx 162+ 163+ movb 8(%ebp), %cl 164+ 165+ call EXT_C(prot_to_real) 166+ .code16 167+ 168+ xorb %al, %al 169+ movb $0xf, %ah 170+ int $0x10 /* Get Current Video mode */ 171+ movb %al, %ch 172+ xorb %ah, %ah 173+ movb %cl, %al 174+ int $0x10 /* Set Video mode */ 175+ 176+ DATA32 call EXT_C(real_to_prot) 177+ .code32 178+ 179+ xorl %eax, %eax 180+ movb %ch, %al 181+ 182+ popl %ecx 183+ popl %ebx 184+ popl %ebp 185+ ret 186+ 187+ 188+/* 189+ * int get_videomode() 190+ * BIOS call "INT 10H Function 0Fh" to get current video mode 191+ * Call with %al = 0x0 192+ * %ah = 0xF 193+ * Returns current videomode. 194+ */ 195+ENTRY(get_videomode) 196+ pushl %ebp 197+ movl %esp,%ebp 198+ pushl %ebx 199+ pushl %ecx 200+ 201+ call EXT_C(prot_to_real) 202+ .code16 203+ 204+ xorb %al, %al 205+ movb $0xF, %ah 206+ int $0x10 /* Get Current Video mode */ 207+ movb %al, %cl /* For now we only want display mode */ 208+ 209+ DATA32 call EXT_C(real_to_prot) 210+ .code32 211+ 212+ xorl %eax, %eax 213+ movb %cl, %al 214+ 215+ popl %ecx 216+ popl %ebx 217+ popl %ebp 218+ ret 219+ 220+ 221+/* 222+ * unsigned char * graphics_get_font() 223+ * BIOS call "INT 10H Function 11h" to set font 224+ * Call with %ah = 0x11 225+ */ 226+ENTRY(graphics_get_font) 227+ push %ebp 228+ push %ebx 229+ push %ecx 230+ push %edx 231+ 232+ call EXT_C(prot_to_real) 233+ .code16 234+ 235+ movw $0x1130, %ax 236+ movb $6, %bh /* font 8x16 */ 237+ int $0x10 238+ movw %bp, %dx 239+ movw %es, %cx 240+ 241+ DATA32 call EXT_C(real_to_prot) 242+ .code32 243+ 244+ xorl %eax, %eax 245+ movw %cx, %ax 246+ shll $4, %eax 247+ movw %dx, %ax 248+ 249+ pop %edx 250+ pop %ecx 251+ pop %ebx 252+ pop %ebp 253+ ret 254+ 255+ 256+/* 257+ * graphics_set_palette(index, red, green, blue) 258+ * BIOS call "INT 10H Function 10h" to set individual dac register 259+ * Call with %ah = 0x10 260+ * %bx = register number 261+ * %ch = new value for green (0-63) 262+ * %cl = new value for blue (0-63) 263+ * %dh = new value for red (0-63) 264+ */ 265+ 266+ENTRY(graphics_set_palette) 267+ push %ebp 268+ push %eax 269+ push %ebx 270+ push %ecx 271+ push %edx 272+ 273+ movw $0x3c8, %bx /* address write mode register */ 274+ 275+ /* wait vertical retrace */ 276+ movw $0x3da, %dx 277+l1b: 278+ inb %dx, %al /* wait vertical active display */ 279+ test $8, %al 280+ jnz l1b 281+ 282+l2b: 283+ inb %dx, %al /* wait vertical retrace */ 284+ test $8, %al 285+ jnz l2b 286+ 287+ mov %bx, %dx 288+ movb 0x18(%esp), %al /* index */ 289+ outb %al, %dx 290+ inc %dx 291+ 292+ movb 0x1c(%esp), %al /* red */ 293+ outb %al, %dx 294+ 295+ movb 0x20(%esp), %al /* green */ 296+ outb %al, %dx 297+ 298+ movb 0x24(%esp), %al /* blue */ 299+ outb %al, %dx 300+ 301+ movw 0x18(%esp), %bx 302+ 303+ call EXT_C(prot_to_real) 304+ .code16 305+ 306+ movb %bl, %bh 307+ movw $0x1000, %ax 308+ int $0x10 309+ 310+ DATA32 call EXT_C(real_to_prot) 311+ .code32 312+ 313+ pop %edx 314+ pop %ecx 315+ pop %ebx 316+ pop %eax 317+ pop %ebp 318+ ret 319+#endif /* SUPPORT_GRAPHICS */ 320+ 321+ 322 /* 323 * getrtsecs() 324 * if a seconds value can be read, read it and return it (BCD), 325diff -Naur grub-0.97.orig/stage2/builtins.c grub-0.97/stage2/builtins.c 326--- grub-0.97.orig/stage2/builtins.c 2005-02-15 19:58:23.000000000 -0200 327+++ grub-0.97/stage2/builtins.c 2005-06-13 18:44:03.000000000 -0300 328@@ -28,6 +28,10 @@ 329 #include <filesys.h> 330 #include <term.h> 331 332+#ifdef SUPPORT_GRAPHICS 333+# include <graphics.h> 334+#endif 335+ 336 #ifdef SUPPORT_NETBOOT 337 # define GRUB 1 338 # include <etherboot.h> 339@@ -237,12 +241,22 @@ 340 static int 341 boot_func (char *arg, int flags) 342 { 343+ struct term_entry *prev_term = current_term; 344 /* Clear the int15 handler if we can boot the kernel successfully. 345 This assumes that the boot code never fails only if KERNEL_TYPE is 346 not KERNEL_TYPE_NONE. Is this assumption is bad? */ 347 if (kernel_type != KERNEL_TYPE_NONE) 348 unset_int15_handler (); 349 350+ /* if our terminal needed initialization, we should shut it down 351+ * before booting the kernel, but we want to save what it was so 352+ * we can come back if needed */ 353+ if (current_term->shutdown) 354+ { 355+ current_term->shutdown(); 356+ current_term = term_table; /* assumption: console is first */ 357+ } 358+ 359 #ifdef SUPPORT_NETBOOT 360 /* Shut down the networking. */ 361 cleanup_net (); 362@@ -306,6 +320,13 @@ 363 return 1; 364 } 365 366+ /* if we get back here, we should go back to what our term was before */ 367+ current_term = prev_term; 368+ if (current_term->startup) 369+ /* if our terminal fails to initialize, fall back to console since 370+ * it should always work */ 371+ if (current_term->startup() == 0) 372+ current_term = term_table; /* we know that console is first */ 373 return 0; 374 } 375 376@@ -852,6 +873,251 @@ 377 }; 378 #endif /* SUPPORT_NETBOOT */ 379 380+#ifdef SUPPORT_GRAPHICS 381+ 382+static int splashimage_func(char *arg, int flags) { 383+ int i; 384+ 385+ /* filename can only be 256 characters due to our buffer size */ 386+ if (grub_strlen(arg) > 256) { 387+ grub_printf("Splash image filename too large\n"); 388+ grub_printf("Press any key to continue..."); 389+ getkey(); 390+ return 1; 391+ } 392+ 393+ /* get rid of TERM_NEED_INIT from the graphics terminal. */ 394+ for (i = 0; term_table[i].name; i++) { 395+ if (grub_strcmp (term_table[i].name, "graphics") == 0) { 396+ term_table[i].flags &= ~TERM_NEED_INIT; 397+ break; 398+ } 399+ } 400+ 401+ graphics_set_splash(arg); 402+ 403+ if (flags == BUILTIN_CMDLINE && graphics_inited) { 404+ graphics_end(); 405+ if (graphics_init() == 0) { 406+ /* Fallback to default term */ 407+ current_term = term_table; 408+ max_lines = current_term->max_lines; 409+ if (current_term->cls) 410+ current_term->cls(); 411+ grub_printf("Failed to set splash image and/or graphics mode\n"); 412+ return 1; 413+ } 414+ graphics_cls(); 415+ } 416+ 417+ if (flags == BUILTIN_MENU) 418+ current_term = term_table + i; 419+ 420+ return 0; 421+} 422+ 423+static struct builtin builtin_splashimage = 424+{ 425+ "splashimage", 426+ splashimage_func, 427+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, 428+ "splashimage FILE", 429+ "Load FILE as the background image when in graphics mode." 430+}; 431+ 432+ 433+/* shade */ 434+static int 435+shade_func(char *arg, int flags) 436+{ 437+ int new_shade; 438+ 439+ if (!arg || safe_parse_maxint(&arg, &new_shade) == 0) 440+ return (1); 441+ 442+ if (shade != new_shade) { 443+ shade = new_shade; 444+ if (flags == BUILTIN_CMDLINE && graphics_inited) { 445+ graphics_end(); 446+ graphics_init(); 447+ graphics_cls(); 448+ } 449+ } 450+ 451+ return 0; 452+} 453+ 454+static struct builtin builtin_shade = 455+{ 456+ "shade", 457+ shade_func, 458+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, 459+ "shade INTEGER", 460+ "If set to 0, disables the use of shaded text, else enables it." 461+}; 462+ 463+ 464+/* foreground */ 465+static int 466+foreground_func(char *arg, int flags) 467+{ 468+ if (grub_strlen(arg) == 6) { 469+ int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2; 470+ int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2; 471+ int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2; 472+ 473+ foreground = (r << 16) | (g << 8) | b; 474+ if (graphics_inited) 475+ graphics_set_palette(15, r, g, b); 476+ 477+ return 0; 478+ } 479+ 480+ return 1; 481+} 482+ 483+static struct builtin builtin_foreground = 484+{ 485+ "foreground", 486+ foreground_func, 487+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, 488+ "foreground RRGGBB", 489+ "Sets the foreground color when in graphics mode." 490+ "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal." 491+}; 492+ 493+ 494+/* background */ 495+static int 496+background_func(char *arg, int flags) 497+{ 498+ if (grub_strlen(arg) == 6) { 499+ int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2; 500+ int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2; 501+ int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2; 502+ 503+ background = (r << 16) | (g << 8) | b; 504+ if (graphics_inited) 505+ graphics_set_palette(0, r, g, b); 506+ return 0; 507+ } 508+ 509+ return 1; 510+} 511+ 512+static struct builtin builtin_background = 513+{ 514+ "background", 515+ background_func, 516+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, 517+ "background RRGGBB", 518+ "Sets the background color when in graphics mode." 519+ "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal." 520+}; 521+ 522+ 523+/* border */ 524+static int 525+border_func(char *arg, int flags) 526+{ 527+ if (grub_strlen(arg) == 6) { 528+ int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2; 529+ int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2; 530+ int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2; 531+ 532+ window_border = (r << 16) | (g << 8) | b; 533+ if (graphics_inited) 534+ graphics_set_palette(0x11, r, g, b); 535+ 536+ return 0; 537+ } 538+ 539+ return 1; 540+} 541+ 542+static struct builtin builtin_border = 543+{ 544+ "border", 545+ border_func, 546+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, 547+ "border RRGGBB", 548+ "Sets the border video color when in graphics mode." 549+ "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal." 550+}; 551+ 552+ 553+/* viewport */ 554+static int 555+viewport_func (char *arg, int flags) 556+{ 557+ int i; 558+ int x0 = 0, y0 = 0, x1 = 80, y1 = 30; 559+ int *pos[4] = { &x0, &y0, &x1, &y1 }; 560+ 561+ if (!arg) 562+ return (1); 563+ for (i = 0; i < 4; i++) { 564+ if (!*arg) 565+ return (1); 566+ while (*arg && (*arg == ' ' || *arg == '\t')) 567+ ++arg; 568+ if (!safe_parse_maxint(&arg, pos[i])) 569+ return (1); 570+ while (*arg && (*arg != ' ' && *arg != '\t')) 571+ ++arg; 572+ } 573+ 574+ /* minimum size is 65 colums and 16 rows */ 575+ if (x0 > x1 - 66 || y0 > y1 - 16 || x0 < 0 || y0 < 0 || x1 > 80 || y1 > 30) 576+ return 1; 577+ 578+ view_x0 = x0; 579+ view_y0 = y0; 580+ view_x1 = x1; 581+ view_y1 = y1; 582+ 583+ if (flags == BUILTIN_CMDLINE && graphics_inited) { 584+ graphics_end(); 585+ graphics_init(); 586+ graphics_cls(); 587+ } 588+ 589+ return 0; 590+} 591+ 592+static struct builtin builtin_viewport = 593+{ 594+ "viewport", 595+ viewport_func, 596+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, 597+ "viewport x0 y0 x1 y1", 598+ "Changes grub internals to output text in the window defined by" 599+ " four parameters. The x and y parameters are 0 based. This option" 600+ " only works with the graphics interface." 601+}; 602+ 603+#endif /* SUPPORT_GRAPHICS */ 604+ 605+ 606+/* clear */ 607+static int 608+clear_func() 609+{ 610+ if (current_term->cls) 611+ current_term->cls(); 612+ 613+ return 0; 614+} 615+ 616+static struct builtin builtin_clear = 617+{ 618+ "clear", 619+ clear_func, 620+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, 621+ "clear", 622+ "Clear the screen" 623+}; 624+ 625 626 /* displayapm */ 627 static int 628@@ -1454,14 +1720,20 @@ 629 630 631 /* help */ 632-#define MAX_SHORT_DOC_LEN 39 633-#define MAX_LONG_DOC_LEN 66 634- 635 static int 636 help_func (char *arg, int flags) 637 { 638- int all = 0; 639- 640+ int all = 0, max_short_doc_len, max_long_doc_len; 641+ max_short_doc_len = 39; 642+ max_long_doc_len = 66; 643+#ifdef SUPPORT_GRAPHICS 644+ if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0) 645+ { 646+ max_short_doc_len = (view_x1 - view_x0 + 1) / 2 - 1; 647+ max_long_doc_len = (view_x1 - view_x0) - 14; 648+ } 649+#endif 650+ 651 if (grub_memcmp (arg, "--all", sizeof ("--all") - 1) == 0) 652 { 653 all = 1; 654@@ -1491,13 +1763,13 @@ 655 656 len = grub_strlen ((*builtin)->short_doc); 657 /* If the length of SHORT_DOC is too long, truncate it. */ 658- if (len > MAX_SHORT_DOC_LEN - 1) 659- len = MAX_SHORT_DOC_LEN - 1; 660+ if (len > max_short_doc_len - 1) 661+ len = max_short_doc_len - 1; 662 663 for (i = 0; i < len; i++) 664 grub_putchar ((*builtin)->short_doc[i]); 665 666- for (; i < MAX_SHORT_DOC_LEN; i++) 667+ for (; i < max_short_doc_len; i++) 668 grub_putchar (' '); 669 670 if (! left) 671@@ -1546,10 +1818,10 @@ 672 int i; 673 674 /* If LEN is too long, fold DOC. */ 675- if (len > MAX_LONG_DOC_LEN) 676+ if (len > max_long_doc_len) 677 { 678 /* Fold this line at the position of a space. */ 679- for (len = MAX_LONG_DOC_LEN; len > 0; len--) 680+ for (len = max_long_doc_len; len > 0; len--) 681 if (doc[len - 1] == ' ') 682 break; 683 } 684@@ -4085,7 +4357,7 @@ 685 }; 686 687 688-#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) 689+#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS) 690 /* terminal */ 691 static int 692 terminal_func (char *arg, int flags) 693@@ -4244,17 +4516,29 @@ 694 end: 695 current_term = term_table + default_term; 696 current_term->flags = term_flags; 697- 698+ 699 if (lines) 700 max_lines = lines; 701 else 702- /* 24 would be a good default value. */ 703- max_lines = 24; 704- 705+ max_lines = current_term->max_lines; 706+ 707 /* If the interface is currently the command-line, 708 restart it to repaint the screen. */ 709- if (current_term != prev_term && (flags & BUILTIN_CMDLINE)) 710+ if ((current_term != prev_term) && (flags & BUILTIN_CMDLINE)){ 711+ if (prev_term->shutdown) 712+ prev_term->shutdown(); 713+ if (current_term->startup) { 714+ /* If startup fails, return to previous term */ 715+ if (current_term->startup() == 0) { 716+ current_term = prev_term; 717+ max_lines = current_term->max_lines; 718+ if (current_term->cls) { 719+ current_term->cls(); 720+ } 721+ } 722+ } 723 grub_longjmp (restart_cmdline_env, 0); 724+ } 725 726 return 0; 727 } 728@@ -4264,7 +4548,7 @@ 729 "terminal", 730 terminal_func, 731 BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST, 732- "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules]", 733+ "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules] [graphics]", 734 "Select a terminal. When multiple terminals are specified, wait until" 735 " you push any key to continue. If both console and serial are specified," 736 " the terminal to which you input a key first will be selected. If no" 737@@ -4276,7 +4560,7 @@ 738 " seconds. The option --lines specifies the maximum number of lines." 739 " The option --silent is used to suppress messages." 740 }; 741-#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */ 742+#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */ 743 744 745 #ifdef SUPPORT_SERIAL 746@@ -4795,13 +5079,20 @@ 747 /* The table of builtin commands. Sorted in dictionary order. */ 748 struct builtin *builtin_table[] = 749 { 750+#ifdef SUPPORT_GRAPHICS 751+ &builtin_background, 752+#endif 753 &builtin_blocklist, 754 &builtin_boot, 755 #ifdef SUPPORT_NETBOOT 756 &builtin_bootp, 757 #endif /* SUPPORT_NETBOOT */ 758+#ifdef SUPPORT_GRAPHICS 759+ &builtin_border, 760+#endif 761 &builtin_cat, 762 &builtin_chainloader, 763+ &builtin_clear, 764 &builtin_cmp, 765 &builtin_color, 766 &builtin_configfile, 767@@ -4821,6 +5112,9 @@ 768 &builtin_embed, 769 &builtin_fallback, 770 &builtin_find, 771+#ifdef SUPPORT_GRAPHICS 772+ &builtin_foreground, 773+#endif 774 &builtin_fstest, 775 &builtin_geometry, 776 &builtin_halt, 777@@ -4864,9 +5158,13 @@ 778 #endif /* SUPPORT_SERIAL */ 779 &builtin_setkey, 780 &builtin_setup, 781-#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) 782+#ifdef SUPPORT_GRAPHICS 783+ &builtin_shade, 784+ &builtin_splashimage, 785+#endif /* SUPPORT_GRAPHICS */ 786+#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS) 787 &builtin_terminal, 788-#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */ 789+#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */ 790 #ifdef SUPPORT_SERIAL 791 &builtin_terminfo, 792 #endif /* SUPPORT_SERIAL */ 793@@ -4880,5 +5178,8 @@ 794 &builtin_unhide, 795 &builtin_uppermem, 796 &builtin_vbeprobe, 797+#ifdef SUPPORT_GRAPHICS 798+ &builtin_viewport, 799+#endif 800 0 801 }; 802diff -Naur grub-0.97.orig/stage2/char_io.c grub-0.97/stage2/char_io.c 803--- grub-0.97.orig/stage2/char_io.c 2005-02-01 18:51:23.000000000 -0200 804+++ grub-0.97/stage2/char_io.c 2005-06-12 20:56:49.000000000 -0300 805@@ -29,12 +29,17 @@ 806 # include <serial.h> 807 #endif 808 809+#ifdef SUPPORT_GRAPHICS 810+# include <graphics.h> 811+#endif 812+ 813 #ifndef STAGE1_5 814 struct term_entry term_table[] = 815 { 816 { 817 "console", 818 0, 819+ 24, 820 console_putchar, 821 console_checkkey, 822 console_getkey, 823@@ -43,13 +48,16 @@ 824 console_cls, 825 console_setcolorstate, 826 console_setcolor, 827- console_setcursor 828+ console_setcursor, 829+ 0, 830+ 0 831 }, 832 #ifdef SUPPORT_SERIAL 833 { 834 "serial", 835 /* A serial device must be initialized. */ 836 TERM_NEED_INIT, 837+ 24, 838 serial_putchar, 839 serial_checkkey, 840 serial_getkey, 841@@ -58,6 +66,8 @@ 842 serial_cls, 843 serial_setcolorstate, 844 0, 845+ 0, 846+ 0, 847 0 848 }, 849 #endif /* SUPPORT_SERIAL */ 850@@ -65,6 +75,7 @@ 851 { 852 "hercules", 853 0, 854+ 24, 855 hercules_putchar, 856 console_checkkey, 857 console_getkey, 858@@ -73,11 +84,30 @@ 859 hercules_cls, 860 hercules_setcolorstate, 861 hercules_setcolor, 862- hercules_setcursor 863+ hercules_setcursor, 864+ 0, 865+ 0 866 }, 867 #endif /* SUPPORT_HERCULES */ 868+#ifdef SUPPORT_GRAPHICS 869+ { "graphics", 870+ TERM_NEED_INIT, /* flags */ 871+ 30, /* number of lines */ 872+ graphics_putchar, /* putchar */ 873+ console_checkkey, /* checkkey */ 874+ console_getkey, /* getkey */ 875+ graphics_getxy, /* getxy */ 876+ graphics_gotoxy, /* gotoxy */ 877+ graphics_cls, /* cls */ 878+ graphics_setcolorstate, /* setcolorstate */ 879+ graphics_setcolor, /* setcolor */ 880+ graphics_setcursor, /* nocursor */ 881+ graphics_init, /* initialize */ 882+ graphics_end /* shutdown */ 883+ }, 884+#endif /* SUPPORT_GRAPHICS */ 885 /* This must be the last entry. */ 886- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 887+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 888 }; 889 890 /* This must be console. */ 891@@ -305,9 +335,10 @@ 892 893 /* XXX: These should be defined in shared.h, but I leave these here, 894 until this code is freezed. */ 895-#define CMDLINE_WIDTH 78 896 #define CMDLINE_MARGIN 10 897- 898+ 899+ /* command-line limits */ 900+ int cmdline_width = 78, col_start = 0; 901 int xpos, lpos, c, section; 902 /* The length of PROMPT. */ 903 int plen; 904@@ -338,7 +369,7 @@ 905 906 /* If the cursor is in the first section, display the first section 907 instead of the second. */ 908- if (section == 1 && plen + lpos < CMDLINE_WIDTH) 909+ if (section == 1 && plen + lpos < cmdline_width) 910 cl_refresh (1, 0); 911 else if (xpos - count < 1) 912 cl_refresh (1, 0); 913@@ -354,7 +385,7 @@ 914 grub_putchar ('\b'); 915 } 916 else 917- gotoxy (xpos, getxy () & 0xFF); 918+ gotoxy (xpos + col_start, getxy () & 0xFF); 919 } 920 } 921 922@@ -364,7 +395,7 @@ 923 lpos += count; 924 925 /* If the cursor goes outside, scroll the screen to the right. */ 926- if (xpos + count >= CMDLINE_WIDTH) 927+ if (xpos + count >= cmdline_width) 928 cl_refresh (1, 0); 929 else 930 { 931@@ -383,7 +414,7 @@ 932 } 933 } 934 else 935- gotoxy (xpos, getxy () & 0xFF); 936+ gotoxy (xpos + col_start, getxy () & 0xFF); 937 } 938 } 939 940@@ -398,14 +429,14 @@ 941 if (full) 942 { 943 /* Recompute the section number. */ 944- if (lpos + plen < CMDLINE_WIDTH) 945+ if (lpos + plen < cmdline_width) 946 section = 0; 947 else 948- section = ((lpos + plen - CMDLINE_WIDTH) 949- / (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN) + 1); 950+ section = ((lpos + plen - cmdline_width) 951+ / (cmdline_width - 1 - CMDLINE_MARGIN) + 1); 952 953 /* From the start to the end. */ 954- len = CMDLINE_WIDTH; 955+ len = cmdline_width; 956 pos = 0; 957 grub_putchar ('\r'); 958 959@@ -445,8 +476,8 @@ 960 if (! full) 961 offset = xpos - 1; 962 963- start = ((section - 1) * (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN) 964- + CMDLINE_WIDTH - plen - CMDLINE_MARGIN); 965+ start = ((section - 1) * (cmdline_width - 1 - CMDLINE_MARGIN) 966+ + cmdline_width - plen - CMDLINE_MARGIN); 967 xpos = lpos + 1 - start; 968 start += offset; 969 } 970@@ -471,7 +502,7 @@ 971 972 /* If the cursor is at the last position, put `>' or a space, 973 depending on if there are more characters in BUF. */ 974- if (pos == CMDLINE_WIDTH) 975+ if (pos == cmdline_width) 976 { 977 if (start + len < llen) 978 grub_putchar ('>'); 979@@ -488,7 +519,7 @@ 980 grub_putchar ('\b'); 981 } 982 else 983- gotoxy (xpos, getxy () & 0xFF); 984+ gotoxy (xpos + col_start, getxy () & 0xFF); 985 } 986 987 /* Initialize the command-line. */ 988@@ -518,10 +549,10 @@ 989 990 llen += l; 991 lpos += l; 992- if (xpos + l >= CMDLINE_WIDTH) 993+ if (xpos + l >= cmdline_width) 994 cl_refresh (1, 0); 995- else if (xpos + l + llen - lpos > CMDLINE_WIDTH) 996- cl_refresh (0, CMDLINE_WIDTH - xpos); 997+ else if (xpos + l + llen - lpos > cmdline_width) 998+ cl_refresh (0, cmdline_width - xpos); 999 else 1000 cl_refresh (0, l + llen - lpos); 1001 } 1002@@ -533,12 +564,22 @@ 1003 grub_memmove (buf + lpos, buf + lpos + count, llen - count + 1); 1004 llen -= count; 1005 1006- if (xpos + llen + count - lpos > CMDLINE_WIDTH) 1007- cl_refresh (0, CMDLINE_WIDTH - xpos); 1008+ if (xpos + llen + count - lpos > cmdline_width) 1009+ cl_refresh (0, cmdline_width - xpos); 1010 else 1011 cl_refresh (0, llen + count - lpos); 1012 } 1013 1014+ max_lines = current_term->max_lines; 1015+#ifdef SUPPORT_GRAPHICS 1016+ if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0) 1017+ { 1018+ cmdline_width = (view_x1 - view_x0) - 2; 1019+ col_start = view_x0; 1020+ max_lines = view_y1 - view_y0; 1021+ } 1022+#endif 1023+ 1024 plen = grub_strlen (prompt); 1025 llen = grub_strlen (cmdline); 1026 1027@@ -1006,6 +1047,48 @@ 1028 } 1029 #endif /* ! STAGE1_5 */ 1030 1031+#ifndef STAGE1_5 1032+/* Internal pager. */ 1033+int 1034+do_more (void) 1035+{ 1036+ if (count_lines >= 0) 1037+ { 1038+ count_lines++; 1039+ if (count_lines >= max_lines - 2) 1040+ { 1041+ int tmp; 1042+ 1043+ /* It's important to disable the feature temporarily, because 1044+ the following grub_printf call will print newlines. */ 1045+ count_lines = -1; 1046+ 1047+ grub_printf("\n"); 1048+ if (current_term->setcolorstate) 1049+ current_term->setcolorstate (COLOR_STATE_HIGHLIGHT); 1050+ 1051+ grub_printf ("[Hit return to continue]"); 1052+ 1053+ if (current_term->setcolorstate) 1054+ current_term->setcolorstate (COLOR_STATE_NORMAL); 1055+ 1056+ 1057+ do 1058+ { 1059+ tmp = ASCII_CHAR (getkey ()); 1060+ } 1061+ while (tmp != '\n' && tmp != '\r'); 1062+ grub_printf ("\r \r"); 1063+ 1064+ /* Restart to count lines. */ 1065+ count_lines = 0; 1066+ return 1; 1067+ } 1068+ } 1069+ return 0; 1070+} 1071+#endif 1072+ 1073 /* Display an ASCII character. */ 1074 void 1075 grub_putchar (int c) 1076@@ -1034,38 +1117,11 @@ 1077 1078 if (c == '\n') 1079 { 1080+ int flag; 1081 /* Internal `more'-like feature. */ 1082- if (count_lines >= 0) 1083- { 1084- count_lines++; 1085- if (count_lines >= max_lines - 2) 1086- { 1087- int tmp; 1088- 1089- /* It's important to disable the feature temporarily, because 1090- the following grub_printf call will print newlines. */ 1091- count_lines = -1; 1092- 1093- if (current_term->setcolorstate) 1094- current_term->setcolorstate (COLOR_STATE_HIGHLIGHT); 1095- 1096- grub_printf ("\n[Hit return to continue]"); 1097- 1098- if (current_term->setcolorstate) 1099- current_term->setcolorstate (COLOR_STATE_NORMAL); 1100- 1101- do 1102- { 1103- tmp = ASCII_CHAR (getkey ()); 1104- } 1105- while (tmp != '\n' && tmp != '\r'); 1106- grub_printf ("\r \r"); 1107- 1108- /* Restart to count lines. */ 1109- count_lines = 0; 1110- return; 1111- } 1112- } 1113+ flag = do_more (); 1114+ if (flag) 1115+ return; 1116 } 1117 1118 current_term->putchar (c); 1119@@ -1090,7 +1146,7 @@ 1120 cls (void) 1121 { 1122 /* If the terminal is dumb, there is no way to clean the terminal. */ 1123- if (current_term->flags & TERM_DUMB) 1124+ if (current_term->flags & TERM_DUMB) 1125 grub_putchar ('\n'); 1126 else 1127 current_term->cls (); 1128@@ -1217,6 +1273,16 @@ 1129 return ! errnum; 1130 } 1131 1132+void 1133+grub_memcpy(void *dest, const void *src, int len) 1134+{ 1135+ int i; 1136+ register char *d = (char*)dest, *s = (char*)src; 1137+ 1138+ for (i = 0; i < len; i++) 1139+ d[i] = s[i]; 1140+} 1141+ 1142 void * 1143 grub_memmove (void *to, const void *from, int len) 1144 { 1145diff -Naur grub-0.97.orig/stage2/cmdline.c grub-0.97/stage2/cmdline.c 1146--- grub-0.97.orig/stage2/cmdline.c 2004-08-16 20:23:01.000000000 -0300 1147+++ grub-0.97/stage2/cmdline.c 2005-06-12 20:56:49.000000000 -0300 1148@@ -50,10 +50,11 @@ 1149 void 1150 print_cmdline_message (int forever) 1151 { 1152- printf (" [ Minimal BASH-like line editing is supported. For the first word, TAB\n" 1153- " lists possible command completions. Anywhere else TAB lists the possible\n" 1154- " completions of a device/filename.%s ]\n", 1155- (forever ? "" : " ESC at any time exits.")); 1156+ grub_printf(" [ Minimal BASH-like line editing is supported. For\n" 1157+ " the first word, TAB lists possible command\n" 1158+ " completions. Anywhere else TAB lists the possible\n" 1159+ " completions of a device/filename.%s ]\n", 1160+ (forever ? "" : " ESC at any time\n exits.")); 1161 } 1162 1163 /* Find the builtin whose command name is COMMAND and return the 1164diff -Naur grub-0.97.orig/stage2/graphics.c grub-0.97/stage2/graphics.c 1165--- grub-0.97.orig/stage2/graphics.c 1969-12-31 21:00:00.000000000 -0300 1166+++ grub-0.97/stage2/graphics.c 2005-06-13 19:13:31.000000000 -0300 1167@@ -0,0 +1,584 @@ 1168+/* 1169+ * graphics.c - graphics mode support for GRUB 1170+ * Implemented as a terminal type by Jeremy Katz <katzj@redhat.com> based 1171+ * on a patch by Paulo C�sar Pereira de Andrade <pcpa@conectiva.com.br> 1172+ * Options and enhancements made by Herton Ronaldo Krzesinski 1173+ * <herton@mandriva.com> 1174+ * 1175+ * GRUB -- GRand Unified Bootloader 1176+ * Copyright (C) 2001,2002 Red Hat, Inc. 1177+ * Portions copyright (C) 2000 Conectiva, Inc. 1178+ * 1179+ * This program is free software; you can redistribute it and/or modify 1180+ * it under the terms of the GNU General Public License as published by 1181+ * the Free Software Foundation; either version 2 of the License, or 1182+ * (at your option) any later version. 1183+ * 1184+ * This program is distributed in the hope that it will be useful, 1185+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 1186+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1187+ * GNU General Public License for more details. 1188+ * 1189+ * You should have received a copy of the GNU General Public License 1190+ * along with this program; If not, see <http://www.gnu.org/licenses/> 1191+ */ 1192+ 1193+#ifdef SUPPORT_GRAPHICS 1194+ 1195+#include <term.h> 1196+#include <shared.h> 1197+#include <graphics.h> 1198+ 1199+int saved_videomode; 1200+unsigned char *font8x16; 1201+ 1202+int graphics_inited = 0; 1203+static char splashimage[256]; 1204+ 1205+int shade = 1, no_cursor = 0; 1206+ 1207+#define VSHADOW VSHADOW1 1208+unsigned char VSHADOW1[38400]; 1209+unsigned char VSHADOW2[38400]; 1210+unsigned char VSHADOW4[38400]; 1211+unsigned char VSHADOW8[38400]; 1212+ 1213+/* define the default viewable area */ 1214+int view_x0 = 0; 1215+int view_y0 = 0; 1216+int view_x1 = 80; 1217+int view_y1 = 30; 1218+ 1219+/* text buffer has to be kept around so that we can write things as we 1220+ * scroll and the like */ 1221+unsigned short text[80 * 30]; 1222+ 1223+/* graphics options */ 1224+int foreground = (63 << 16) | (63 << 8) | (63), background = 0, window_border = 0; 1225+ 1226+/* current position */ 1227+static int fontx = 0; 1228+static int fonty = 0; 1229+ 1230+/* global state so that we don't try to recursively scroll or cursor */ 1231+static int no_scroll = 0; 1232+ 1233+/* color state */ 1234+static int graphics_standard_color = A_NORMAL; 1235+static int graphics_normal_color = A_NORMAL; 1236+static int graphics_highlight_color = A_REVERSE; 1237+static int graphics_current_color = A_NORMAL; 1238+static color_state graphics_color_state = COLOR_STATE_STANDARD; 1239+ 1240+static inline void outb(unsigned short port, unsigned char val) 1241+{ 1242+ __asm __volatile ("outb %0,%1"::"a" (val), "d" (port)); 1243+} 1244+ 1245+static void MapMask(int value) { 1246+ outb(0x3c4, 2); 1247+ outb(0x3c5, value); 1248+} 1249+ 1250+/* bit mask register */ 1251+static void BitMask(int value) { 1252+ outb(0x3ce, 8); 1253+ outb(0x3cf, value); 1254+} 1255+ 1256+/* move the graphics cursor location to col, row */ 1257+static void graphics_setxy(int col, int row) { 1258+ if (col >= view_x0 && col < view_x1) { 1259+ fontx = col; 1260+ cursorX = col << 3; 1261+ } 1262+ if (row >= view_y0 && row < view_y1) { 1263+ fonty = row; 1264+ cursorY = row << 4; 1265+ } 1266+} 1267+ 1268+/* scroll the screen */ 1269+static void graphics_scroll() { 1270+ int i, j, k; 1271+ 1272+ /* we don't want to scroll recursively... that would be bad */ 1273+ if (no_scroll) 1274+ return; 1275+ no_scroll = 1; 1276+ 1277+ /* disable pager temporarily */ 1278+ k = count_lines; 1279+ count_lines = -1; 1280+ 1281+ /* move everything up a line */ 1282+ for (j = view_y0 + 1; j < view_y1; j++) { 1283+ graphics_gotoxy(view_x0, j - 1); 1284+ for (i = view_x0; i < view_x1; i++) { 1285+ graphics_putchar(text[j * 80 + i]); 1286+ } 1287+ } 1288+ 1289+ /* last line should be blank */ 1290+ graphics_gotoxy(view_x0, view_y1 - 1); 1291+ for (i = view_x0; i < view_x1; i++) 1292+ graphics_putchar(' '); 1293+ graphics_setxy(view_x0, view_y1 - 1); 1294+ 1295+ count_lines = k; 1296+ 1297+ no_scroll = 0; 1298+} 1299+ 1300+/* Set the splash image */ 1301+void graphics_set_splash(char *splashfile) { 1302+ grub_strcpy(splashimage, splashfile); 1303+} 1304+ 1305+/* Get the current splash image */ 1306+char *graphics_get_splash(void) { 1307+ return splashimage; 1308+} 1309+ 1310+/* 1311+ * Initialize a vga16 graphics display with the palette based off of 1312+ * the image in splashimage. If the image doesn't exist, leave graphics 1313+ * mode. The mode initiated is 12h. From "Ralf Brown's Interrupt List": 1314+ * text/ text pixel pixel colors disply scrn system 1315+ * grph resol box resolution pages addr 1316+ * 12h G 80x30 8x16 640x480 16/256K . A000 VGA,ATI VIP 1317+ * G 80x30 8x16 640x480 16/64 . A000 ATI EGA Wonder 1318+ * G . . 640x480 16 . . UltraVision+256K EGA 1319+ */ 1320+int graphics_init() 1321+{ 1322+ if (!graphics_inited) { 1323+ saved_videomode = set_videomode(0x12); 1324+ if (get_videomode() != 0x12) { 1325+ set_videomode(saved_videomode); 1326+ return 0; 1327+ } 1328+ graphics_inited = 1; 1329+ } 1330+ else 1331+ return 1; 1332+ 1333+ font8x16 = (unsigned char*)graphics_get_font(); 1334+ 1335+ /* make sure that the highlight color is set correctly */ 1336+ graphics_highlight_color = ((graphics_normal_color >> 4) | 1337+ ((graphics_normal_color & 0xf) << 4)); 1338+ 1339+ graphics_cls(); 1340+ 1341+ if (!read_image(splashimage)) { 1342+ grub_printf("Failed to read splash image (%s)\n", splashimage); 1343+ grub_printf("Press any key to continue..."); 1344+ getkey(); 1345+ set_videomode(saved_videomode); 1346+ graphics_inited = 0; 1347+ return 0; 1348+ } 1349+ 1350+ set_int1c_handler(); 1351+ 1352+ return 1; 1353+} 1354+ 1355+/* Leave graphics mode */ 1356+void graphics_end(void) 1357+{ 1358+ if (graphics_inited) { 1359+ unset_int1c_handler(); 1360+ set_videomode(saved_videomode); 1361+ graphics_inited = 0; 1362+ no_cursor = 0; 1363+ } 1364+} 1365+ 1366+/* Print ch on the screen. Handle any needed scrolling or the like */ 1367+void graphics_putchar(int ch) { 1368+ ch &= 0xff; 1369+ 1370+ graphics_cursor(0); 1371+ 1372+ if (ch == '\n') { 1373+ if (fonty + 1 < view_y1) 1374+ graphics_setxy(fontx, fonty + 1); 1375+ else 1376+ graphics_scroll(); 1377+ graphics_cursor(1); 1378+ return; 1379+ } else if (ch == '\r') { 1380+ graphics_setxy(view_x0, fonty); 1381+ graphics_cursor(1); 1382+ return; 1383+ } 1384+ 1385+ graphics_cursor(0); 1386+ 1387+ text[fonty * 80 + fontx] = ch; 1388+ text[fonty * 80 + fontx] &= 0x00ff; 1389+ if (graphics_current_color & 0xf0) 1390+ text[fonty * 80 + fontx] |= 0x100; 1391+ 1392+ graphics_cursor(0); 1393+ 1394+ if ((fontx + 1) >= view_x1) { 1395+ graphics_setxy(view_x0, fonty); 1396+ if (fonty + 1 < view_y1) 1397+ graphics_setxy(view_x0, fonty + 1); 1398+ else 1399+ graphics_scroll(); 1400+ graphics_cursor(1); 1401+ do_more (); 1402+ graphics_cursor(0); 1403+ } else { 1404+ graphics_setxy(fontx + 1, fonty); 1405+ } 1406+ 1407+ graphics_cursor(1); 1408+} 1409+ 1410+/* get the current location of the cursor */ 1411+int graphics_getxy(void) { 1412+ return (fontx << 8) | fonty; 1413+} 1414+ 1415+void graphics_gotoxy(int x, int y) { 1416+ graphics_cursor(0); 1417+ 1418+ graphics_setxy(x, y); 1419+ 1420+ graphics_cursor(1); 1421+} 1422+ 1423+void graphics_cls(void) { 1424+ int i; 1425+ unsigned char *mem, *s1, *s2, *s4, *s8; 1426+ 1427+ graphics_cursor(0); 1428+ graphics_gotoxy(view_x0, view_y0); 1429+ 1430+ mem = (unsigned char*)VIDEOMEM; 1431+ s1 = (unsigned char*)VSHADOW1; 1432+ s2 = (unsigned char*)VSHADOW2; 1433+ s4 = (unsigned char*)VSHADOW4; 1434+ s8 = (unsigned char*)VSHADOW8; 1435+ 1436+ for (i = 0; i < 80 * 30; i++) 1437+ text[i] = ' '; 1438+ graphics_cursor(1); 1439+ 1440+ BitMask(0xff); 1441+ 1442+ /* plane 1 */ 1443+ MapMask(1); 1444+ grub_memcpy(mem, s1, 38400); 1445+ 1446+ /* plane 2 */ 1447+ MapMask(2); 1448+ grub_memcpy(mem, s2, 38400); 1449+ 1450+ /* plane 3 */ 1451+ MapMask(4); 1452+ grub_memcpy(mem, s4, 38400); 1453+ 1454+ /* plane 4 */ 1455+ MapMask(8); 1456+ grub_memcpy(mem, s8, 38400); 1457+ 1458+ MapMask(15); 1459+ 1460+ if (no_cursor) { 1461+ no_cursor = 0; 1462+ set_int1c_handler(); 1463+ } 1464+} 1465+ 1466+void graphics_setcolorstate (color_state state) { 1467+ switch (state) { 1468+ case COLOR_STATE_STANDARD: 1469+ graphics_current_color = graphics_standard_color; 1470+ break; 1471+ case COLOR_STATE_NORMAL: 1472+ graphics_current_color = graphics_normal_color; 1473+ break; 1474+ case COLOR_STATE_HIGHLIGHT: 1475+ graphics_current_color = graphics_highlight_color; 1476+ break; 1477+ default: 1478+ graphics_current_color = graphics_standard_color; 1479+ break; 1480+ } 1481+ 1482+ graphics_color_state = state; 1483+} 1484+ 1485+void graphics_setcolor (int normal_color, int highlight_color) { 1486+ graphics_normal_color = normal_color; 1487+ graphics_highlight_color = highlight_color; 1488+ 1489+ graphics_setcolorstate (graphics_color_state); 1490+} 1491+ 1492+int graphics_setcursor (int on) { 1493+ if (!no_cursor && !on) { 1494+ no_cursor = 1; 1495+ unset_int1c_handler(); 1496+ graphics_cursor(0); 1497+ } 1498+ else if(no_cursor && on) { 1499+ no_cursor = 0; 1500+ set_int1c_handler(); 1501+ graphics_cursor(1); 1502+ } 1503+ return 0; 1504+} 1505+ 1506+/* Read in the splashscreen image and set the palette up appropriately. 1507+ * Format of splashscreen is an xpm (can be gzipped) with 16 colors and 1508+ * 640x480. */ 1509+int read_image(char *s) 1510+{ 1511+ char buf[32], pal[16], c; 1512+ unsigned char base, mask, *s1, *s2, *s4, *s8; 1513+ unsigned i, len, idx, colors, x, y, width, height; 1514+ 1515+ if (!grub_open(s)) 1516+ return 0; 1517+ 1518+ /* read header */ 1519+ if (!grub_read((char*)&buf, 10) || grub_memcmp(buf, "/* XPM */\n", 10)) { 1520+ grub_close(); 1521+ return 0; 1522+ } 1523+ 1524+ /* parse info */ 1525+ while (grub_read(&c, 1)) { 1526+ if (c == '"') 1527+ break; 1528+ } 1529+ 1530+ while (grub_read(&c, 1) && (c == ' ' || c == '\t')) 1531+ ; 1532+ 1533+ i = 0; 1534+ width = c - '0'; 1535+ while (grub_read(&c, 1)) { 1536+ if (c >= '0' && c <= '9') 1537+ width = width * 10 + c - '0'; 1538+ else 1539+ break; 1540+ } 1541+ while (grub_read(&c, 1) && (c == ' ' || c == '\t')) 1542+ ; 1543+ 1544+ height = c - '0'; 1545+ while (grub_read(&c, 1)) { 1546+ if (c >= '0' && c <= '9') 1547+ height = height * 10 + c - '0'; 1548+ else 1549+ break; 1550+ } 1551+ while (grub_read(&c, 1) && (c == ' ' || c == '\t')) 1552+ ; 1553+ 1554+ colors = c - '0'; 1555+ while (grub_read(&c, 1)) { 1556+ if (c >= '0' && c <= '9') 1557+ colors = colors * 10 + c - '0'; 1558+ else 1559+ break; 1560+ } 1561+ 1562+ base = 0; 1563+ while (grub_read(&c, 1) && c != '"') 1564+ ; 1565+ 1566+ /* palette */ 1567+ for (i = 0, idx = 1; i < colors; i++) { 1568+ len = 0; 1569+ 1570+ while (grub_read(&c, 1) && c != '"') 1571+ ; 1572+ grub_read(&c, 1); /* char */ 1573+ base = c; 1574+ grub_read(buf, 4); /* \t c # */ 1575+ 1576+ while (grub_read(&c, 1) && c != '"') { 1577+ if (len < sizeof(buf)) 1578+ buf[len++] = c; 1579+ } 1580+ 1581+ if (len == 6 && idx < 15) { 1582+ int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2; 1583+ int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2; 1584+ int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2; 1585+ 1586+ pal[idx] = base; 1587+ graphics_set_palette(idx, r, g, b); 1588+ ++idx; 1589+ } 1590+ } 1591+ 1592+ x = y = len = 0; 1593+ 1594+ s1 = (unsigned char*)VSHADOW1; 1595+ s2 = (unsigned char*)VSHADOW2; 1596+ s4 = (unsigned char*)VSHADOW4; 1597+ s8 = (unsigned char*)VSHADOW8; 1598+ 1599+ for (i = 0; i < 38400; i++) 1600+ s1[i] = s2[i] = s4[i] = s8[i] = 0; 1601+ 1602+ /* parse xpm data */ 1603+ while (y < height) { 1604+ while (1) { 1605+ if (!grub_read(&c, 1)) { 1606+ grub_close(); 1607+ return 0; 1608+ } 1609+ if (c == '"') 1610+ break; 1611+ } 1612+ 1613+ while (grub_read(&c, 1) && c != '"') { 1614+ for (i = 1; i < 15; i++) 1615+ if (pal[i] == c) { 1616+ c = i; 1617+ break; 1618+ } 1619+ 1620+ mask = 0x80 >> (x & 7); 1621+ if (c & 1) 1622+ s1[len + (x >> 3)] |= mask; 1623+ if (c & 2) 1624+ s2[len + (x >> 3)] |= mask; 1625+ if (c & 4) 1626+ s4[len + (x >> 3)] |= mask; 1627+ if (c & 8) 1628+ s8[len + (x >> 3)] |= mask; 1629+ 1630+ if (++x >= 640) { 1631+ x = 0; 1632+ 1633+ if (y < 480) 1634+ len += 80; 1635+ ++y; 1636+ } 1637+ } 1638+ } 1639+ 1640+ grub_close(); 1641+ 1642+ graphics_set_palette(0, (background >> 16), (background >> 8) & 63, 1643+ background & 63); 1644+ graphics_set_palette(15, (foreground >> 16), (foreground >> 8) & 63, 1645+ foreground & 63); 1646+ graphics_set_palette(0x11, (window_border >> 16), (window_border >> 8) & 63, 1647+ window_border & 63); 1648+ 1649+ return 1; 1650+} 1651+ 1652+/* Convert a character which is a hex digit to the appropriate integer */ 1653+int hex(int v) 1654+{ 1655+ if (v >= 'A' && v <= 'F') 1656+ return (v - 'A' + 10); 1657+ if (v >= 'a' && v <= 'f') 1658+ return (v - 'a' + 10); 1659+ return (v - '0'); 1660+} 1661+ 1662+void graphics_cursor(int set) { 1663+ unsigned char *pat, *mem, *ptr, chr[16 << 2]; 1664+ int i, ch, invert, offset; 1665+ 1666+ if (set && (no_cursor || no_scroll)) 1667+ return; 1668+ 1669+ offset = cursorY * 80 + fontx; 1670+ ch = text[fonty * 80 + fontx] & 0xff; 1671+ invert = (text[fonty * 80 + fontx] & 0xff00) != 0; 1672+ pat = font8x16 + (ch << 4); 1673+ 1674+ mem = (unsigned char*)VIDEOMEM + offset; 1675+ 1676+ if (!set) { 1677+ for (i = 0; i < 16; i++) { 1678+ unsigned char mask = pat[i]; 1679+ 1680+ if (!invert) { 1681+ chr[i ] = ((unsigned char*)VSHADOW1)[offset]; 1682+ chr[16 + i] = ((unsigned char*)VSHADOW2)[offset]; 1683+ chr[32 + i] = ((unsigned char*)VSHADOW4)[offset]; 1684+ chr[48 + i] = ((unsigned char*)VSHADOW8)[offset]; 1685+ 1686+ if (shade) { 1687+ if (ch == DISP_VERT || ch == DISP_LL || 1688+ ch == DISP_UR || ch == DISP_LR) { 1689+ unsigned char pmask = ~(pat[i] >> 1); 1690+ 1691+ chr[i ] &= pmask; 1692+ chr[16 + i] &= pmask; 1693+ chr[32 + i] &= pmask; 1694+ chr[48 + i] &= pmask; 1695+ } 1696+ if (i > 0 && ch != DISP_VERT) { 1697+ unsigned char pmask = ~(pat[i - 1] >> 1); 1698+ 1699+ chr[i ] &= pmask; 1700+ chr[16 + i] &= pmask; 1701+ chr[32 + i] &= pmask; 1702+ chr[48 + i] &= pmask; 1703+ if (ch == DISP_HORIZ || ch == DISP_UR || ch == DISP_LR) { 1704+ pmask = ~pat[i - 1]; 1705+ 1706+ chr[i ] &= pmask; 1707+ chr[16 + i] &= pmask; 1708+ chr[32 + i] &= pmask; 1709+ chr[48 + i] &= pmask; 1710+ } 1711+ } 1712+ } 1713+ chr[i ] |= mask; 1714+ chr[16 + i] |= mask; 1715+ chr[32 + i] |= mask; 1716+ chr[48 + i] |= mask; 1717+ 1718+ offset += 80; 1719+ } 1720+ else { 1721+ chr[i ] = mask; 1722+ chr[16 + i] = mask; 1723+ chr[32 + i] = mask; 1724+ chr[48 + i] = mask; 1725+ } 1726+ } 1727+ } 1728+ else { 1729+ MapMask(15); 1730+ ptr = mem; 1731+ for (i = 0; i < 16; i++, ptr += 80) { 1732+ cursorBuf[i] = pat[i]; 1733+ *ptr = ~pat[i]; 1734+ } 1735+ return; 1736+ } 1737+ 1738+ offset = 0; 1739+ for (i = 1; i < 16; i <<= 1, offset += 16) { 1740+ int j; 1741+ 1742+ MapMask(i); 1743+ ptr = mem; 1744+ for (j = 0; j < 16; j++, ptr += 80) 1745+ *ptr = chr[j + offset]; 1746+ } 1747+ 1748+ MapMask(15); 1749+} 1750+ 1751+#endif /* SUPPORT_GRAPHICS */ 1752diff -Naur grub-0.97.orig/stage2/graphics.h grub-0.97/stage2/graphics.h 1753--- grub-0.97.orig/stage2/graphics.h 1969-12-31 21:00:00.000000000 -0300 1754+++ grub-0.97/stage2/graphics.h 2005-06-12 20:56:49.000000000 -0300 1755@@ -0,0 +1,43 @@ 1756+/* graphics.h - graphics console interface */ 1757+/* 1758+ * GRUB -- GRand Unified Bootloader 1759+ * Copyright (C) 2002 Free Software Foundation, Inc. 1760+ * 1761+ * This program is free software; you can redistribute it and/or modify 1762+ * it under the terms of the GNU General Public License as published by 1763+ * the Free Software Foundation; either version 2 of the License, or 1764+ * (at your option) any later version. 1765+ * 1766+ * This program is distributed in the hope that it will be useful, 1767+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 1768+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1769+ * GNU General Public License for more details. 1770+ * 1771+ * You should have received a copy of the GNU General Public License 1772+ * along with this program; If not, see <http://www.gnu.org/licenses/> 1773+ */ 1774+ 1775+#ifndef GRAPHICS_H 1776+#define GRAPHICS_H 1777+ 1778+/* magic constant */ 1779+#define VIDEOMEM 0xA0000 1780+ 1781+/* function prototypes */ 1782+char *graphics_get_splash(void); 1783+ 1784+int read_image(char *s); 1785+void graphics_cursor(int set); 1786+ 1787+/* function prototypes for asm functions */ 1788+void * graphics_get_font(); 1789+void graphics_set_palette(int idx, int red, int green, int blue); 1790+void set_int1c_handler(); 1791+void unset_int1c_handler(); 1792+ 1793+extern short cursorX, cursorY; 1794+extern char cursorBuf[16]; 1795+extern int shade; 1796+extern int view_x0, view_y0, view_x1, view_y1; 1797+ 1798+#endif /* GRAPHICS_H */ 1799diff -Naur grub-0.97.orig/stage2/Makefile.am grub-0.97/stage2/Makefile.am 1800--- grub-0.97.orig/stage2/Makefile.am 2005-02-02 18:37:35.000000000 -0200 1801+++ grub-0.97/stage2/Makefile.am 2005-06-12 20:56:49.000000000 -0300 1802@@ -7,7 +7,7 @@ 1803 fat.h filesys.h freebsd.h fs.h hercules.h i386-elf.h \ 1804 imgact_aout.h iso9660.h jfs.h mb_header.h mb_info.h md5.h \ 1805 nbi.h pc_slice.h serial.h shared.h smp-imps.h term.h \ 1806- terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h 1807+ terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h graphics.h 1808 EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS) 1809 1810 # For <stage1.h>. 1811@@ -19,7 +19,7 @@ 1812 disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \ 1813 fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \ 1814 fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \ 1815- terminfo.c tparm.c 1816+ terminfo.c tparm.c graphics.c 1817 libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \ 1818 -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \ 1819 -DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \ 1820@@ -79,8 +79,14 @@ 1821 HERCULES_FLAGS = 1822 endif 1823 1824+if GRAPHICS_SUPPORT 1825+GRAPHICS_FLAGS = -DSUPPORT_GRAPHICS=1 1826+else 1827+GRAPHICS_FLAGS = 1828+endif 1829+ 1830 STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \ 1831- $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) 1832+ $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) $(GRAPHICS_FLAGS) 1833 1834 STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000 1835 STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1 1836@@ -90,7 +96,8 @@ 1837 cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \ 1838 fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \ 1839 fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \ 1840- hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c 1841+ hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c \ 1842+ graphics.c 1843 pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) 1844 pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) 1845 pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK) 1846diff -Naur grub-0.97.orig/stage2/shared.h grub-0.97/stage2/shared.h 1847--- grub-0.97.orig/stage2/shared.h 2004-06-19 13:40:09.000000000 -0300 1848+++ grub-0.97/stage2/shared.h 2005-06-12 20:56:49.000000000 -0300 1849@@ -792,6 +792,11 @@ 1850 /* Set the cursor position. */ 1851 void gotoxy (int x, int y); 1852 1853+/* Internal pager 1854+ Returns 1 = if pager was used 1855+ 0 = if pager wasn't used */ 1856+int do_more (void); 1857+ 1858 /* Displays an ASCII character. IBM displays will translate some 1859 characters to special graphical ones (see the DISP_* constants). */ 1860 void grub_putchar (int c); 1861@@ -871,6 +876,7 @@ 1862 int grub_tolower (int c); 1863 int grub_isspace (int c); 1864 int grub_strncat (char *s1, const char *s2, int n); 1865+void grub_memcpy(void *dest, const void *src, int len); 1866 void *grub_memmove (void *to, const void *from, int len); 1867 void *grub_memset (void *start, int c, int len); 1868 int grub_strncat (char *s1, const char *s2, int n); 1869diff -Naur grub-0.97.orig/stage2/stage2.c grub-0.97/stage2/stage2.c 1870--- grub-0.97.orig/stage2/stage2.c 2005-03-19 14:51:57.000000000 -0300 1871+++ grub-0.97/stage2/stage2.c 2005-06-13 22:38:08.000000000 -0300 1872@@ -20,6 +20,12 @@ 1873 #include <shared.h> 1874 #include <term.h> 1875 1876+#ifdef SUPPORT_GRAPHICS 1877+# include <graphics.h> 1878+#endif 1879+ 1880+int col_start, col_end, row_start, box_size; 1881+ 1882 grub_jmp_buf restart_env; 1883 1884 #if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS) 1885@@ -105,13 +111,13 @@ 1886 if (highlight && current_term->setcolorstate) 1887 current_term->setcolorstate (COLOR_STATE_HIGHLIGHT); 1888 1889- gotoxy (2, y); 1890+ gotoxy (2 + col_start, y); 1891 grub_putchar (' '); 1892- for (x = 3; x < 75; x++) 1893+ for (x = 3 + col_start; x < (col_end - 5); x++) 1894 { 1895- if (*entry && x <= 72) 1896+ if (*entry && x <= (col_end - 8)) 1897 { 1898- if (x == 72) 1899+ if (x == (col_end - 8)) 1900 grub_putchar (DISP_RIGHT); 1901 else 1902 grub_putchar (*entry++); 1903@@ -119,7 +125,7 @@ 1904 else 1905 grub_putchar (' '); 1906 } 1907- gotoxy (74, y); 1908+ gotoxy ((col_end - 6), y); 1909 1910 if (current_term->setcolorstate) 1911 current_term->setcolorstate (COLOR_STATE_STANDARD); 1912@@ -131,7 +137,7 @@ 1913 { 1914 int i; 1915 1916- gotoxy (77, y + 1); 1917+ gotoxy ((col_end - 3), y + 1); 1918 1919 if (first) 1920 grub_putchar (DISP_UP); 1921@@ -151,14 +157,14 @@ 1922 menu_entries++; 1923 } 1924 1925- gotoxy (77, y + size); 1926+ gotoxy ((col_end - 3), y + size); 1927 1928 if (*menu_entries) 1929 grub_putchar (DISP_DOWN); 1930 else 1931 grub_putchar (' '); 1932 1933- gotoxy (74, y + entryno + 1); 1934+ gotoxy ((col_end - 6), y + entryno + 1); 1935 } 1936 1937 static void 1938@@ -196,30 +202,30 @@ 1939 if (current_term->setcolorstate) 1940 current_term->setcolorstate (COLOR_STATE_NORMAL); 1941 1942- gotoxy (1, y); 1943+ gotoxy (1 + col_start, y); 1944 1945 grub_putchar (DISP_UL); 1946- for (i = 0; i < 73; i++) 1947+ for (i = col_start; i < (col_end - 7); i++) 1948 grub_putchar (DISP_HORIZ); 1949 grub_putchar (DISP_UR); 1950 1951 i = 1; 1952 while (1) 1953 { 1954- gotoxy (1, y + i); 1955+ gotoxy (1 + col_start, y + i); 1956 1957 if (i > size) 1958 break; 1959 1960 grub_putchar (DISP_VERT); 1961- gotoxy (75, y + i); 1962+ gotoxy ((col_end - 5), y + i); 1963 grub_putchar (DISP_VERT); 1964 1965 i++; 1966 } 1967 1968 grub_putchar (DISP_LL); 1969- for (i = 0; i < 73; i++) 1970+ for (i = col_start; i < (col_end - 7); i++) 1971 grub_putchar (DISP_HORIZ); 1972 grub_putchar (DISP_LR); 1973 1974@@ -233,6 +239,7 @@ 1975 { 1976 int c, time1, time2 = -1, first_entry = 0; 1977 char *cur_entry = 0; 1978+ struct term_entry *prev_term = NULL; 1979 1980 /* 1981 * Main loop for menu UI. 1982@@ -250,6 +257,22 @@ 1983 } 1984 } 1985 1986+ col_start = 0; 1987+ col_end = 80; 1988+ row_start = 0; 1989+ box_size = 12; 1990+ /* if we're using viewport we need to make sure to setup 1991+ coordinates correctly. */ 1992+#ifdef SUPPORT_GRAPHICS 1993+ if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0) 1994+ { 1995+ col_start = view_x0; 1996+ col_end = view_x1; 1997+ row_start = view_y0; 1998+ box_size = (view_y1 - view_y0) - 13; 1999+ } 2000+#endif 2001+ 2002 /* If the timeout was expired or wasn't set, force to show the menu 2003 interface. */ 2004 if (grub_timeout < 0) 2005@@ -302,36 +325,36 @@ 2006 if (current_term->flags & TERM_DUMB) 2007 print_entries_raw (num_entries, first_entry, menu_entries); 2008 else 2009- print_border (3, 12); 2010+ print_border (3 + row_start, box_size); 2011 2012 grub_printf ("\n\ 2013- Use the %c and %c keys to select which entry is highlighted.\n", 2014+ Use the %c and %c keys to select which entry is highlighted.\n", 2015 DISP_UP, DISP_DOWN); 2016 2017 if (! auth && password) 2018 { 2019 printf ("\ 2020- Press enter to boot the selected OS or \'p\' to enter a\n\ 2021- password to unlock the next set of features."); 2022+ Press enter to boot the selected OS or \'p\' to enter a\n\ 2023+ password to unlock the next set of features."); 2024 } 2025 else 2026 { 2027 if (config_entries) 2028 printf ("\ 2029- Press enter to boot the selected OS, \'e\' to edit the\n\ 2030- commands before booting, or \'c\' for a command-line."); 2031+ Press enter to boot the selected OS, \'e\' to edit the\n\ 2032+ commands before booting, or \'c\' for a command-line."); 2033 else 2034 printf ("\ 2035- Press \'b\' to boot, \'e\' to edit the selected command in the\n\ 2036- boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\ 2037- after (\'O\' for before) the selected line, \'d\' to remove the\n\ 2038- selected line, or escape to go back to the main menu."); 2039+ Press \'b\' to boot, \'e\' to edit the selected command in the\n\ 2040+ boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\ 2041+ after (\'O\' for before) the selected line, \'d\' to remove the\n\ 2042+ selected line, or escape to go back to the main menu."); 2043 } 2044 2045 if (current_term->flags & TERM_DUMB) 2046 grub_printf ("\n\nThe selected entry is %d ", entryno); 2047 else 2048- print_entries (3, 12, first_entry, entryno, menu_entries); 2049+ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries); 2050 } 2051 2052 /* XX using RT clock now, need to initialize value */ 2053@@ -358,10 +381,10 @@ 2054 entryno, grub_timeout); 2055 else 2056 { 2057- gotoxy (3, 22); 2058- grub_printf ("The highlighted entry will be booted automatically in %d seconds. ", 2059+ gotoxy (3 + col_start, 10 + box_size + row_start); 2060+ grub_printf (" The highlighted entry will be booted automatically in %d seconds. ", 2061 grub_timeout); 2062- gotoxy (74, 4 + entryno); 2063+ gotoxy ((col_end - 6), 4 + entryno + row_start); 2064 } 2065 2066 grub_timeout--; 2067@@ -387,12 +410,12 @@ 2068 if (current_term->flags & TERM_DUMB) 2069 grub_putchar ('\r'); 2070 else 2071- gotoxy (3, 22); 2072+ gotoxy (3 + col_start, 10 + box_size + row_start); 2073 printf (" "); 2074 grub_timeout = -1; 2075 fallback_entryno = -1; 2076 if (! (current_term->flags & TERM_DUMB)) 2077- gotoxy (74, 4 + entryno); 2078+ gotoxy ((col_end - 6), 4 + entryno + row_start); 2079 } 2080 2081 /* We told them above (at least in SUPPORT_SERIAL) to use 2082@@ -408,12 +431,12 @@ 2083 { 2084 if (entryno > 0) 2085 { 2086- print_entry (4 + entryno, 0, 2087+ print_entry (4 + entryno + row_start, 0, 2088 get_entry (menu_entries, 2089 first_entry + entryno, 2090 0)); 2091 entryno--; 2092- print_entry (4 + entryno, 1, 2093+ print_entry (4 + entryno + row_start, 1, 2094 get_entry (menu_entries, 2095 first_entry + entryno, 2096 0)); 2097@@ -421,7 +444,7 @@ 2098 else if (first_entry > 0) 2099 { 2100 first_entry--; 2101- print_entries (3, 12, first_entry, entryno, 2102+ print_entries (3 + row_start, box_size, first_entry, entryno, 2103 menu_entries); 2104 } 2105 } 2106@@ -433,29 +456,29 @@ 2107 entryno++; 2108 else 2109 { 2110- if (entryno < 11) 2111+ if (entryno < (box_size - 1)) 2112 { 2113- print_entry (4 + entryno, 0, 2114+ print_entry (4 + entryno + row_start, 0, 2115 get_entry (menu_entries, 2116 first_entry + entryno, 2117 0)); 2118 entryno++; 2119- print_entry (4 + entryno, 1, 2120+ print_entry (4 + entryno + row_start, 1, 2121 get_entry (menu_entries, 2122 first_entry + entryno, 2123 0)); 2124 } 2125- else if (num_entries > 12 + first_entry) 2126+ else if (num_entries > box_size + first_entry) 2127 { 2128 first_entry++; 2129- print_entries (3, 12, first_entry, entryno, menu_entries); 2130+ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries); 2131 } 2132 } 2133 } 2134 else if (c == 7) 2135 { 2136 /* Page Up */ 2137- first_entry -= 12; 2138+ first_entry -= box_size; 2139 if (first_entry < 0) 2140 { 2141 entryno += first_entry; 2142@@ -463,20 +486,20 @@ 2143 if (entryno < 0) 2144 entryno = 0; 2145 } 2146- print_entries (3, 12, first_entry, entryno, menu_entries); 2147+ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries); 2148 } 2149 else if (c == 3) 2150 { 2151 /* Page Down */ 2152- first_entry += 12; 2153+ first_entry += box_size; 2154 if (first_entry + entryno + 1 >= num_entries) 2155 { 2156- first_entry = num_entries - 12; 2157+ first_entry = num_entries - box_size; 2158 if (first_entry < 0) 2159 first_entry = 0; 2160 entryno = num_entries - first_entry - 1; 2161 } 2162- print_entries (3, 12, first_entry, entryno, menu_entries); 2163+ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries); 2164 } 2165 2166 if (config_entries) 2167@@ -489,7 +512,7 @@ 2168 if ((c == 'd') || (c == 'o') || (c == 'O')) 2169 { 2170 if (! (current_term->flags & TERM_DUMB)) 2171- print_entry (4 + entryno, 0, 2172+ print_entry (4 + entryno + row_start, 0, 2173 get_entry (menu_entries, 2174 first_entry + entryno, 2175 0)); 2176@@ -537,7 +560,7 @@ 2177 2178 if (entryno >= num_entries) 2179 entryno--; 2180- if (first_entry && num_entries < 12 + first_entry) 2181+ if (first_entry && num_entries < box_size + first_entry) 2182 first_entry--; 2183 } 2184 2185@@ -549,7 +572,7 @@ 2186 grub_printf ("\n"); 2187 } 2188 else 2189- print_entries (3, 12, first_entry, entryno, menu_entries); 2190+ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries); 2191 } 2192 2193 cur_entry = menu_entries; 2194@@ -570,7 +593,7 @@ 2195 if (current_term->flags & TERM_DUMB) 2196 grub_printf ("\r "); 2197 else 2198- gotoxy (1, 21); 2199+ gotoxy (1 + col_start, 9 + box_size + row_start); 2200 2201 /* Wipe out the previously entered password */ 2202 grub_memset (entered, 0, sizeof (entered)); 2203@@ -714,6 +737,15 @@ 2204 2205 cls (); 2206 setcursor (1); 2207+ /* if our terminal needed initialization, we should shut it down 2208+ * before booting the kernel, but we want to save what it was so 2209+ * we can come back if needed */ 2210+ prev_term = current_term; 2211+ if (current_term->shutdown) 2212+ { 2213+ current_term->shutdown(); 2214+ current_term = term_table; /* assumption: console is first */ 2215+ } 2216 2217 while (1) 2218 { 2219@@ -748,6 +780,13 @@ 2220 break; 2221 } 2222 2223+ /* if we get back here, we should go back to what our term was before */ 2224+ current_term = prev_term; 2225+ if (current_term->startup) 2226+ /* if our terminal fails to initialize, fall back to console since 2227+ * it should always work */ 2228+ if (current_term->startup() == 0) 2229+ current_term = term_table; /* we know that console is first */ 2230 show_menu = 1; 2231 goto restart; 2232 } 2233@@ -1050,6 +1089,16 @@ 2234 while (is_preset); 2235 } 2236 2237+ /* go ahead and make sure the terminal is setup */ 2238+ if (current_term->startup) 2239+ { 2240+ /* If initialization fails, go back to default terminal */ 2241+ if (current_term->startup() == 0) 2242+ { 2243+ current_term = term_table; 2244+ } 2245+ } 2246+ 2247 if (! num_entries) 2248 { 2249 /* If no acceptable config file, goto command-line, starting 2250diff -Naur grub-0.97.orig/stage2/term.h grub-0.97/stage2/term.h 2251--- grub-0.97.orig/stage2/term.h 2003-07-09 08:45:53.000000000 -0300 2252+++ grub-0.97/stage2/term.h 2005-06-13 14:07:40.000000000 -0300 2253@@ -60,6 +60,8 @@ 2254 const char *name; 2255 /* The feature flags defined above. */ 2256 unsigned long flags; 2257+ /* Default for maximum number of lines if not specified */ 2258+ unsigned short max_lines; 2259 /* Put a character. */ 2260 void (*putchar) (int c); 2261 /* Check if any input character is available. */ 2262@@ -79,6 +81,10 @@ 2263 void (*setcolor) (int normal_color, int highlight_color); 2264 /* Turn on/off the cursor. */ 2265 int (*setcursor) (int on); 2266+ /* function to start a terminal */ 2267+ int (*startup) (void); 2268+ /* function to use to shutdown a terminal */ 2269+ void (*shutdown) (void); 2270 }; 2271 2272 /* This lists up available terminals. */ 2273@@ -124,4 +130,24 @@ 2274 int hercules_setcursor (int on); 2275 #endif 2276 2277+#ifdef SUPPORT_GRAPHICS 2278+extern int foreground, background, window_border, graphics_inited, saved_videomode; 2279+ 2280+void graphics_set_splash(char *splashfile); 2281+int set_videomode(int mode); 2282+int get_videomode(void); 2283+void graphics_putchar (int c); 2284+int graphics_getxy(void); 2285+void graphics_gotoxy(int x, int y); 2286+void graphics_cls(void); 2287+void graphics_setcolorstate (color_state state); 2288+void graphics_setcolor (int normal_color, int highlight_color); 2289+int graphics_setcursor (int on); 2290+int graphics_init(void); 2291+void graphics_end(void); 2292+ 2293+int hex(int v); 2294+void graphics_set_palette(int idx, int red, int green, int blue); 2295+#endif /* SUPPORT_GRAPHICS */ 2296+ 2297 #endif /* ! GRUB_TERM_HEADER */ 2298