Chameleon

Chameleon Svn Source Tree

Root/branches/meklort/i386/modules/GUI/GUI_module.c

Source at commit 642 created 13 years 5 months ago.
By meklort, GUI now starts after all modules have loaded. Fixed boot banner issue
1/*
2 * Copyright (c) 2009 Evan Lojewski. All rights reserved.
3 *
4 */
5
6#include "libsaio.h"
7#include "options.h"
8#include "graphic_utils.h"
9#include "ramdisk.h"
10#include "embedded.h"
11
12#include "picopng.h"
13#include "gui.h"
14
15#include "modules.h"
16
17/* Kabyl: BooterLog */
18#define BOOTER_LOG_SIZE(64 * 1024)
19#define SAFE_LOG_SIZE80
20
21
22bool useGUI;
23
24void GUI_Kernel_Start_hook(void* kernelEntry, void* arg2, void* arg3, void* arg4);
25void GUI_PreBoot_hook(void* arg1, void* arg2, void* arg3, void* arg4);
26void GUI_ModulesLoaded_hook(void* arg1, void* arg2, void* arg3, void* arg4);
27
28int GUI_getBootOptions(bool firstRun);
29
30static void GUI_updateBootArgs( int key );
31void GUI_clearBootArgs(void);
32static void GUI_showBootPrompt(int row, bool visible);
33static void GUI_showMenu( const MenuItem * items, int count, int selection, int row, int height );
34static int GUI_updateMenu( int key, void ** paramPtr );
35static void GUI_showHelp(void);
36
37int GUI_printf(const char * fmt, ...);
38int GUI_verbose(const char * fmt, ...);
39int GUI_error(const char * fmt, ...);
40void GUI_stop(const char * fmt, ...);
41
42
43/* console.c */
44struct putc_info {
45 char * str;
46 char * last_str;
47};
48void sputc(int c, struct putc_info * pi);
49extern char *msgbuf;
50extern char *cursor;
51
52
53
54
55char GUI_bootRescanPrompt[] =
56"Press Enter to start up Darwin/x86 with no options, or you can:\n"
57" Press F5 after you swapped the media. The drive will be rescanned.\n"
58" Type -v and press Enter to start up with diagnostic messages\n"
59" Type ? and press Enter to learn about advanced startup options\n\n"
60"boot: ";
61
62
63
64/**
65 ** The kernel is about to start, draw the boot graphics if we are not in
66 ** verbose mode.
67 **/
68void GUI_ExecKernel_hook(void* kernelEntry, void* arg2, void* arg3, void* arg4)
69{
70if(!gVerboseMode)
71{
72// Note: shouldn't be needed, but just in case
73drawBootGraphics();
74}
75else
76{
77setVideoMode( GRAPHICS_MODE, 0 );
78
79}
80}
81
82/**
83 ** A boot option has been selected, disable the graphical elements on screen.
84 **/
85void GUI_PreBoot_hook(void* arg1, void* arg2, void* arg3, void* arg4)
86{
87bool legacy_logo;
88
89// Turn off any GUI elements
90if( bootArgs->Video.v_display == GRAPHICS_MODE )
91{
92gui.devicelist.draw = false;
93gui.bootprompt.draw = false;
94gui.menu.draw = false;
95gui.infobox.draw = false;
96gui.logo.draw = false;
97drawBackground();
98//updateVRAM();
99
100if(!gVerboseMode)
101{
102// Disable outputs, they will still show in the boot log.
103replace_function("_printf", &GUI_verbose);
104drawBootGraphics();
105}
106
107}
108}
109
110void GUI_ModulesLoaded_hook(void* kernelEntry, void* arg2, void* arg3, void* arg4)
111{
112// Start the gui
113useGUI = true;
114// Override useGUI default
115getBoolForKey(kGUIKey, &useGUI, &bootInfo->bootConfig);
116if (useGUI && initGUI())
117{
118// initGUI() returned with an error, disabling GUI.
119useGUI = false;
120}
121else
122{
123replace_function("_initGraphicsMode", &GUI_initGraphicsMode);
124replace_function("_getBootOptions", &GUI_getBootOptions);
125replace_function("_clearBootArgs", &GUI_clearBootArgs);
126replace_function("_showHelp", &GUI_showHelp);
127
128replace_function("_printf", &GUI_printf);
129replace_function("_verbose", &GUI_verbose);
130replace_function("_error", &GUI_error);
131replace_function("_stop", &GUI_stop);
132}
133
134}
135
136/**
137 ** Module startup code. Replace console only print functions as well as
138 ** replace various menu functions. Finaly, initialize the gui and hook
139 ** into important events.
140 **/
141void GUI_start()
142{
143// Hoot for the boot screen
144//ExecKernel register_hook_callback("Kernel Start", &GUI_Kernel_Start_hook);
145register_hook_callback("ExecKernel", &GUI_ExecKernel_hook);
146register_hook_callback("PreBoot", &GUI_PreBoot_hook);
147register_hook_callback("ModulesLoaded", &GUI_ModulesLoaded_hook);
148}
149
150/**
151 ** Overriden chameleon function. Draws the updated menu.
152 **/
153static int GUI_updateMenu( int key, void ** paramPtr )
154{
155 int moved = 0;
156
157 union {
158 struct {
159 unsigned int
160selectionUp : 1,
161selectionDown : 1,
162scrollUp : 1,
163scrollDown : 1;
164 } f;
165 unsigned int w;
166 } draw = {{0}};
167
168 if ( gMenuItems == NULL )
169return 0;
170
171if( bootArgs->Video.v_display == GRAPHICS_MODE )
172{
173int res;
174
175// set navigation keys for horizontal layout as defaults
176int previous= 0x4B00;// left arrow
177int subsequent= 0x4D00;// right arrow
178int menu= 0x5000;// down arrow
179
180if ( gui.layout == VerticalLayout )
181{
182// set navigation keys for vertical layout
183previous= 0x4800;// up arrow
184subsequent= 0x5000;// down arrow
185menu= 0x4B00;// right arrow
186}
187
188if ( key == previous )
189{
190if ( gMenuSelection > gMenuTop )
191draw.f.selectionUp = 1;
192else if ( gMenuTop > 0 )
193draw.f.scrollDown = 1;
194
195}
196
197else if ( key == subsequent )
198{
199if ( gMenuSelection != gMenuBottom)
200draw.f.selectionDown = 1;
201else if ( gMenuBottom < ( gMenuItemCount - 1 ) )
202draw.f.scrollUp = 1;
203}
204
205else if ( key == menu )
206{
207if ( gui.menu.draw )
208updateInfoMenu(key);
209else
210drawInfoMenu();
211}
212
213else if ( gui.menu.draw )
214{
215res = updateInfoMenu(key);
216
217if ( res == CLOSE_INFO_MENU )
218gui.menu.draw = false;
219else
220{
221shouldboot = ( res != DO_NOT_BOOT );
222
223if ( shouldboot )
224gui.menu.draw = false;
225
226switch (res)
227{
228case BOOT_NORMAL:
229gVerboseMode = false;
230gBootMode = kBootModeNormal;
231break;
232
233case BOOT_VERBOSE:
234gVerboseMode = true;
235gBootMode = kBootModeNormal;
236addBootArg(kVerboseModeFlag);
237break;
238
239case BOOT_IGNORECACHE:
240gVerboseMode = false;
241gBootMode = kBootModeNormal;
242addBootArg(kIgnoreCachesFlag);
243break;
244
245case BOOT_SINGLEUSER:
246gVerboseMode = true;
247gBootMode = kBootModeNormal;
248addBootArg(kSingleUserModeFlag);
249break;
250}
251
252}
253
254}
255
256} else {
257switch ( key )
258{
259 case 0x4800: // Up Arrow
260if ( gMenuSelection != gMenuTop )
261{
262draw.f.selectionUp = 1;
263}
264else if ( gMenuTop > 0 )
265{
266draw.f.scrollDown = 1;
267}
268break;
269
270case 0x5000: // Down Arrow
271if ( gMenuSelection != gMenuBottom )
272{
273draw.f.selectionDown = 1;
274}
275else if ( gMenuBottom < (gMenuItemCount - 1) )
276{
277draw.f.scrollUp = 1;
278}
279break;
280}
281}
282
283 if ( draw.w )
284 {
285 if ( draw.f.scrollUp )
286 {
287 scollPage(0, gMenuRow, 40, gMenuRow + gMenuHeight - 1, 0x07, 1, 1);
288 gMenuTop++; gMenuBottom++;
289gMenuStart++; gMenuEnd++;
290 draw.f.selectionDown = 1;
291 }
292
293 if ( draw.f.scrollDown )
294 {
295 scollPage(0, gMenuRow, 40, gMenuRow + gMenuHeight - 1, 0x07, 1, -1);
296 gMenuTop--; gMenuBottom--;
297 gMenuStart--; gMenuEnd--;
298 draw.f.selectionUp = 1;
299 }
300
301 if ( draw.f.selectionUp || draw.f.selectionDown )
302 {
303
304CursorState cursorState;
305
306// Set cursor at current position, and clear inverse video.
307
308if( bootArgs->Video.v_display == VGA_TEXT_MODE )
309{
310changeCursor( 0, (gMenuRow + gMenuSelection - gMenuTop), kCursorTypeHidden, &cursorState );
311printMenuItem( &gMenuItems[gMenuSelection], 0 );
312}
313
314if ( draw.f.selectionUp )
315{
316gMenuSelection--;
317if(( gMenuSelection - gMenuStart) == -1 )
318{
319gMenuStart--;
320gMenuEnd--;
321}
322
323} else {
324gMenuSelection++;
325if(( gMenuSelection - ( gui.maxdevices - 1) - gMenuStart) > 0 )
326{
327gMenuStart++;
328gMenuEnd++;
329}
330}
331
332if( bootArgs->Video.v_display == VGA_TEXT_MODE )
333{
334moveCursor( 0, gMenuRow + gMenuSelection - gMenuTop );
335printMenuItem( &gMenuItems[gMenuSelection], 1 );
336restoreCursor( &cursorState );
337
338}
339else
340{
341drawDeviceList (gMenuStart, gMenuEnd, gMenuSelection);
342}
343
344}
345
346 *paramPtr = gMenuItems[gMenuSelection].param;
347 moved = 1;
348 }
349
350return moved;
351}
352
353
354static void GUI_showMenu( const MenuItem * items, int count,
355 int selection, int row, int height )
356{
357 int i;
358 CursorState cursorState;
359
360 if ( items == NULL || count == 0 )
361return;
362
363 // head and tail points to the start and the end of the list.
364 // top and bottom points to the first and last visible items
365 // in the menu window.
366
367 gMenuItems= items;
368 gMenuRow= row;
369 gMenuHeight= height;
370 gMenuItemCount= count;
371 gMenuTop= 0;
372 gMenuBottom= min( count, height ) - 1;
373 gMenuSelection= selection;
374
375 gMenuStart= 0;
376 gMenuEnd = min( count, gui.maxdevices ) - 1;
377
378// If the selected item is not visible, shift the list down.
379
380 if ( gMenuSelection > gMenuBottom )
381 {
382 gMenuTop += ( gMenuSelection - gMenuBottom );
383 gMenuBottom = gMenuSelection;
384 }
385
386if ( gMenuSelection > gMenuEnd )
387 {
388gMenuStart += ( gMenuSelection - gMenuEnd );
389 gMenuEnd = gMenuSelection;
390 }
391
392// Draw the visible items.
393
394if( bootArgs->Video.v_display == GRAPHICS_MODE )
395{
396drawDeviceList(gMenuStart, gMenuEnd, gMenuSelection);
397}
398else
399{
400
401changeCursor( 0, row, kCursorTypeHidden, &cursorState );
402
403for ( i = gMenuTop; i <= gMenuBottom; i++ )
404{
405printMenuItem( &items[i], (i == gMenuSelection) );
406}
407
408restoreCursor( &cursorState );
409 }
410}
411
412
413static void GUI_updateBootArgs( int key )
414{
415 key &= kASCIIKeyMask;
416
417 switch ( key )
418 {
419 case kBackspaceKey:
420 if ( gBootArgsPtr > gBootArgs )
421 {
422 int x, y, t;
423 getCursorPositionAndType( &x, &y, &t );
424 if ( x == 0 && y )
425 {
426 x = 80; y--;
427 }
428 if (x)
429x--;
430if( bootArgs->Video.v_display == VGA_TEXT_MODE )
431{
432setCursorPosition( x, y, 0 );
433putca(' ', 0x07, 1);
434} else
435{
436updateGraphicBootPrompt(kBackspaceKey);
437}
438
439*gBootArgsPtr-- = '\0';
440}
441
442break;
443
444 default:
445 if ( key >= ' ' && gBootArgsPtr < gBootArgsEnd)
446 {
447if( bootArgs->Video.v_display == VGA_TEXT_MODE )
448{
449putchar(key); // echo to screen
450}
451else
452{
453updateGraphicBootPrompt(key);
454}
455*gBootArgsPtr++ = key;
456}
457
458break;
459 }
460}
461
462
463static void GUI_showBootPrompt(int row, bool visible)
464{
465extern char bootPrompt[];
466
467if( bootArgs->Video.v_display == VGA_TEXT_MODE )
468{
469changeCursor( 0, row, kCursorTypeUnderline, 0 );
470clearScreenRows( row, kScreenLastRow );
471}
472
473clearBootArgs();
474
475if (visible)
476{
477if (bootArgs->Video.v_display == VGA_TEXT_MODE)
478{
479if (gEnableCDROMRescan)
480{
481printf( GUI_bootRescanPrompt );
482}
483else
484{
485printf( bootPrompt );
486}
487}
488}
489else
490{
491if (bootArgs->Video.v_display == GRAPHICS_MODE)
492{
493clearGraphicBootPrompt();
494}
495else
496{
497printf("Press Enter to start up the foreign OS. ");
498}
499}
500}
501
502
503void GUI_clearBootArgs(void)
504{
505gBootArgsPtr = gBootArgs;
506memset(gBootArgs, '\0', BOOT_STRING_LEN);
507
508if (bootArgs->Video.v_display == GRAPHICS_MODE)
509{
510clearGraphicBootPrompt();
511}
512}
513
514
515int GUI_getBootOptions(bool firstRun)
516{
517int i;
518int key;
519int nextRow;
520int timeout;
521int bvCount;
522BVRef bvr;
523BVRef menuBVR;
524bool showPrompt, newShowPrompt, isCDROM;
525
526// Initialize default menu selection entry.
527gBootVolume = menuBVR = selectBootVolume(bvChain);
528
529if (biosDevIsCDROM(gBIOSDev))
530{
531isCDROM = true;
532}
533else
534{
535isCDROM = false;
536}
537
538// ensure we're in graphics mode if gui is setup
539if (gui.initialised && bootArgs->Video.v_display == VGA_TEXT_MODE)
540{
541setVideoMode(GRAPHICS_MODE, 0);
542}
543
544// Clear command line boot arguments
545clearBootArgs();
546
547// Allow user to override default timeout.
548if (!getIntForKey(kTimeoutKey, &timeout, &bootInfo->bootConfig))
549{
550/* If there is no timeout key in the file use the default timeout
551 which is different for CDs vs. hard disks. However, if not booting
552 a CD and no config file could be loaded set the timeout
553 to zero which causes the menu to display immediately.
554 This way, if no partitions can be found, that is the disk is unpartitioned
555 or simply cannot be read) then an empty menu is displayed.
556 If some partitions are found, for example a Windows partition, then
557 these will be displayed in the menu as foreign partitions.
558 */
559if (isCDROM)
560{
561timeout = kCDBootTimeout;
562}
563else
564{
565timeout = sysConfigValid ? kBootTimeout : 0;
566}
567}
568
569if (timeout < 0)
570{
571gBootMode |= kBootModeQuiet;
572}
573
574// If the user is holding down a modifier key, enter safe mode.
575if ((readKeyboardShiftFlags() & 0x0F) != 0)
576{
577
578//gBootMode |= kBootModeSafe;
579}
580
581// Checking user pressed keys
582bool f8press = false, spress = false, vpress = false;
583while (readKeyboardStatus())
584{
585key = bgetc ();
586if (key == 0x4200) f8press = true;
587if ((key & 0xff) == 's' || (key & 0xff) == 'S') spress = true;
588if ((key & 0xff) == 'v' || (key & 0xff) == 'V') vpress = true;
589}
590// If user typed F8, abort quiet mode, and display the menu.
591if (f8press)
592{
593gBootMode &= ~kBootModeQuiet;
594timeout = 0;
595}
596// If user typed 'v' or 'V', boot in verbose mode.
597if ((gBootMode & kBootModeQuiet) && firstRun && vpress)
598{
599addBootArg(kVerboseModeFlag);
600}
601// If user typed 's' or 'S', boot in single user mode.
602if ((gBootMode & kBootModeQuiet) && firstRun && spress)
603{
604addBootArg(kSingleUserModeFlag);
605}
606
607if (bootArgs->Video.v_display == VGA_TEXT_MODE)
608{
609setCursorPosition(0, 0, 0);
610clearScreenRows(0, kScreenLastRow);
611if (!(gBootMode & kBootModeQuiet))
612{
613// Display banner and show hardware info.
614printf(bootBanner, (bootInfo->convmem + bootInfo->extmem) / 1024);
615printf(getVBEInfoString());
616}
617changeCursor(0, kMenuTopRow, kCursorTypeUnderline, 0);
618verbose("Scanning device %x...", gBIOSDev);
619}
620
621// When booting from CD, default to hard drive boot when possible.
622if (isCDROM && firstRun)
623{
624const char *val;
625char *prompt = NULL;
626char *name = NULL;
627int cnt;
628int optionKey;
629
630if (getValueForKey(kCDROMPromptKey, &val, &cnt, &bootInfo->bootConfig))
631{
632prompt = malloc(cnt + 1);
633strncat(prompt, val, cnt);
634}
635else
636{
637name = malloc(80);
638getBootVolumeDescription(gBootVolume, name, 79, false);
639prompt = malloc(256);
640sprintf(prompt, "Press any key to start up from %s, or press F8 to enter startup options.", name);
641free(name);
642}
643
644if (getIntForKey( kCDROMOptionKey, &optionKey, &bootInfo->bootConfig ))
645{
646// The key specified is a special key.
647}
648else
649{
650// Default to F8.
651optionKey = 0x4200;
652}
653
654// If the timeout is zero then it must have been set above due to the
655// early catch of F8 which means the user wants to set boot options
656// which we ought to interpret as meaning he wants to boot the CD.
657if (timeout != 0) {
658key = GUI_countdown(prompt, kMenuTopRow, timeout);
659}
660else
661{
662key = optionKey;
663}
664
665if (prompt != NULL)
666{
667free(prompt);
668}
669
670clearScreenRows( kMenuTopRow, kMenuTopRow + 2 );
671
672// Hit the option key ?
673if (key == optionKey)
674{
675gBootMode &= ~kBootModeQuiet;
676timeout = 0;
677}
678else
679{
680key = key & 0xFF;
681
682// Try booting hard disk if user pressed 'h'
683if (biosDevIsCDROM(gBIOSDev) && key == 'h')
684{
685BVRef bvr;
686
687// Look at partitions hosting OS X other than the CD-ROM
688for (bvr = bvChain; bvr; bvr=bvr->next)
689{
690if ((bvr->flags & kBVFlagSystemVolume) && bvr->biosdev != gBIOSDev)
691{
692gBootVolume = bvr;
693}
694}
695}
696goto done;
697}
698}
699
700if (gBootMode & kBootModeQuiet)
701{
702// No input allowed from user.
703goto done;
704}
705
706if (firstRun && timeout > 0 && GUI_countdown("Press any key to enter startup options.", kMenuTopRow, timeout) == 0)
707{
708// If the user is holding down a modifier key,
709// enter safe mode.
710if ((readKeyboardShiftFlags() & 0x0F) != 0)
711{
712gBootMode |= kBootModeSafe;
713}
714goto done;
715}
716
717if (gDeviceCount)
718{
719// Allocate memory for an array of menu items.
720menuItems = malloc(sizeof(MenuItem) * gDeviceCount);
721if (menuItems == NULL)
722{
723goto done;
724}
725
726// Associate a menu item for each BVRef.
727for (bvr=bvChain, i=gDeviceCount-1, selectIndex=0; bvr; bvr=bvr->next)
728{
729if (bvr->visible)
730{
731getBootVolumeDescription(bvr, menuItems[i].name, sizeof(menuItems[i].name) - 1, true);
732menuItems[i].param = (void *) bvr;
733if (bvr == menuBVR)
734{
735selectIndex = i;
736}
737i--;
738}
739}
740}
741
742if (bootArgs->Video.v_display == GRAPHICS_MODE)
743{
744// redraw the background buffer
745gui.logo.draw = true;
746drawBackground();
747gui.devicelist.draw = true;
748gui.redraw = true;
749if (!(gBootMode & kBootModeQuiet))
750{
751bool showBootBanner = false;
752
753// Check if "Boot Banner"=N switch is present in config file.
754if (getBoolForKey(kBootBannerKey, &showBootBanner, &bootInfo->bootConfig) && showBootBanner)
755{
756// Display banner and show hardware info.
757gprintf(&gui.screen, bootBanner + 1, (bootInfo->convmem + bootInfo->extmem) / 1024);
758}
759
760// redraw background
761memcpy(gui.backbuffer->pixels, gui.screen.pixmap->pixels, gui.backbuffer->width * gui.backbuffer->height * 4);
762}
763}
764else
765{
766// Clear screen and hide the blinking cursor.
767clearScreenRows(kMenuTopRow, kMenuTopRow + 2);
768changeCursor(0, kMenuTopRow, kCursorTypeHidden, 0);
769}
770
771nextRow = kMenuTopRow;
772showPrompt = true;
773
774if (gDeviceCount)
775{
776if( bootArgs->Video.v_display == VGA_TEXT_MODE )
777{
778printf("Use \30\31 keys to select the startup volume.");
779}
780GUI_showMenu( menuItems, gDeviceCount, selectIndex, kMenuTopRow + 2, kMenuMaxItems );
781nextRow += min( gDeviceCount, kMenuMaxItems ) + 3;
782}
783
784// Show the boot prompt.
785showPrompt = (gDeviceCount == 0) || (menuBVR->flags & kBVFlagNativeBoot);
786GUI_showBootPrompt( nextRow, showPrompt );
787
788do {
789if (bootArgs->Video.v_display == GRAPHICS_MODE)
790{
791// redraw background
792memcpy( gui.backbuffer->pixels, gui.screen.pixmap->pixels, gui.backbuffer->width * gui.backbuffer->height * 4 );
793// reset cursor co-ords
794gui.debug.cursor = pos( gui.screen.width - 160 , 10 );
795}
796key = getc();
797GUI_updateMenu( key, (void **) &menuBVR );
798newShowPrompt = (gDeviceCount == 0) || (menuBVR->flags & kBVFlagNativeBoot);
799
800if (newShowPrompt != showPrompt)
801{
802showPrompt = newShowPrompt;
803GUI_showBootPrompt( nextRow, showPrompt );
804}
805
806if (showPrompt)
807{
808GUI_updateBootArgs(key);
809}
810
811switch (key)
812{
813case kReturnKey:
814if (gui.menu.draw)
815{
816key=0;
817break;
818}
819if (*gBootArgs == '?')
820{
821char * argPtr = gBootArgs;
822
823// Skip the leading "?" character.
824argPtr++;
825getNextArg(&argPtr, booterCommand);
826getNextArg(&argPtr, booterParam);
827
828/*
829 * TODO: this needs to be refactored.
830 */
831if (strcmp( booterCommand, "video" ) == 0)
832{
833if (bootArgs->Video.v_display == GRAPHICS_MODE)
834{
835showInfoBox(getVBEInfoString(), getVBEModeInfoString());
836}
837else
838{
839printVBEModeInfo();
840}
841}
842else if ( strcmp( booterCommand, "memory" ) == 0)
843{
844if (bootArgs->Video.v_display == GRAPHICS_MODE )
845{
846showInfoBox("Memory Map", getMemoryInfoString());
847}
848else
849{
850printMemoryInfo();
851}
852}
853else if (strcmp(booterCommand, "lspci") == 0)
854{
855lspci();
856}
857else if (strcmp(booterCommand, "more") == 0)
858{
859showTextFile(booterParam);
860}
861else if (strcmp(booterCommand, "rd") == 0)
862{
863processRAMDiskCommand(&argPtr, booterParam);
864}
865else if (strcmp(booterCommand, "norescan") == 0)
866{
867if (gEnableCDROMRescan)
868{
869gEnableCDROMRescan = false;
870break;
871}
872}
873else
874{
875showHelp();
876}
877key = 0;
878GUI_showBootPrompt(nextRow, showPrompt);
879break;
880}
881gBootVolume = menuBVR;
882setRootVolume(menuBVR);
883gBIOSDev = menuBVR->biosdev;
884break;
885
886case kEscapeKey:
887clearBootArgs();
888break;
889
890case kF5Key:
891// New behavior:
892// Clear gBootVolume to restart the loop
893// if the user enabled rescanning the optical drive.
894// Otherwise boot the default boot volume.
895if (gEnableCDROMRescan)
896{
897gBootVolume = NULL;
898clearBootArgs();
899}
900break;
901
902case kF10Key:
903gScanSingleDrive = false;
904scanDisks(gBIOSDev, &bvCount);
905gBootVolume = NULL;
906clearBootArgs();
907break;
908
909case kTabKey:
910// New behavior:
911// Switch between text & graphic interfaces
912// Only Permitted if started in graphics interface
913if (useGUI)
914{
915if (bootArgs->Video.v_display == GRAPHICS_MODE)
916{
917setVideoMode(VGA_TEXT_MODE, 0);
918
919setCursorPosition(0, 0, 0);
920clearScreenRows(0, kScreenLastRow);
921
922// Display banner and show hardware info.
923printf(bootBanner, (bootInfo->convmem + bootInfo->extmem) / 1024);
924printf(getVBEInfoString());
925
926clearScreenRows(kMenuTopRow, kMenuTopRow + 2);
927changeCursor(0, kMenuTopRow, kCursorTypeHidden, 0);
928
929nextRow = kMenuTopRow;
930showPrompt = true;
931
932if (gDeviceCount)
933{
934printf("Use \30\31 keys to select the startup volume.");
935GUI_showMenu(menuItems, gDeviceCount, selectIndex, kMenuTopRow + 2, kMenuMaxItems);
936nextRow += min(gDeviceCount, kMenuMaxItems) + 3;
937}
938
939showPrompt = (gDeviceCount == 0) || (menuBVR->flags & kBVFlagNativeBoot);
940GUI_showBootPrompt(nextRow, showPrompt);
941//changeCursor( 0, kMenuTopRow, kCursorTypeUnderline, 0 );
942}
943else
944{
945gui.redraw = true;
946setVideoMode(GRAPHICS_MODE, 0);
947updateVRAM();
948}
949}
950key = 0;
951break;
952
953default:
954key = 0;
955break;
956}
957} while (0 == key);
958
959done:
960if (bootArgs->Video.v_display == VGA_TEXT_MODE)
961{
962clearScreenRows(kMenuTopRow, kScreenLastRow);
963changeCursor(0, kMenuTopRow, kCursorTypeUnderline, 0);
964}
965shouldboot = false;
966gui.menu.draw = false;
967if (menuItems)
968{
969free(menuItems);
970menuItems = NULL;
971}
972return 0;
973}
974
975
976
977int GUI_error(const char * fmt, ...)
978{
979 va_list ap;
980 gErrors = true;
981 va_start(ap, fmt);
982
983if (bootArgs->Video.v_display == VGA_TEXT_MODE)
984{
985prf(fmt, ap, putchar, 0);
986 }
987else
988{
989vprf(fmt, ap);
990}
991
992va_end(ap);
993 return(0);
994}
995
996int GUI_verbose(const char * fmt, ...)
997{
998 va_list ap;
999
1000va_start(ap, fmt);
1001 if (gVerboseMode)
1002 {
1003if (bootArgs->Video.v_display == VGA_TEXT_MODE)
1004{
1005prf(fmt, ap, putchar, 0);
1006}
1007else
1008{
1009vprf(fmt, ap);
1010}
1011 }
1012
1013/* Kabyl: BooterLog */
1014struct putc_info pi;
1015
1016if (!msgbuf)
1017return 0;
1018
1019if (((cursor - msgbuf) > (BOOTER_LOG_SIZE - SAFE_LOG_SIZE)))
1020return 0;
1021pi.str = cursor;
1022pi.last_str = 0;
1023prf(fmt, ap, sputc, &pi);
1024cursor += strlen((char *)cursor);
1025
1026
1027 va_end(ap);
1028 return(0);
1029}
1030
1031int GUI_printf(const char * fmt, ...)
1032{
1033 va_list ap;
1034va_start(ap, fmt);
1035if (bootArgs->Video.v_display == VGA_TEXT_MODE)
1036{
1037prf(fmt, ap, putchar, 0);
1038}
1039else
1040{
1041vprf(fmt, ap);
1042}
1043
1044/* Kabyl: BooterLog */
1045struct putc_info pi;
1046
1047if (!msgbuf)
1048return 0;
1049
1050if (((cursor - msgbuf) > (BOOTER_LOG_SIZE - SAFE_LOG_SIZE)))
1051return 0;
1052pi.str = cursor;
1053pi.last_str = 0;
1054prf(fmt, ap, sputc, &pi);
1055cursor += strlen((char *)cursor);
1056
1057va_end(ap);
1058 return 0;
1059}
1060
1061void GUI_stop(const char * fmt, ...)
1062{
1063va_list ap;
1064
1065printf("\n");
1066va_start(ap, fmt);
1067
1068if (bootArgs->Video.v_display == VGA_TEXT_MODE)
1069{
1070prf(fmt, ap, putchar, 0);
1071}
1072else
1073{
1074vprf(fmt, ap);
1075}
1076va_end(ap);
1077
1078printf("\nThis is a non recoverable error! System HALTED!!!");
1079halt();
1080while (1);
1081}
1082
1083void GUI_showHelp(void)
1084{
1085if (bootArgs->Video.v_display == GRAPHICS_MODE) {
1086showInfoBox("Help. Press q to quit.\n", (char *)BootHelp_txt);
1087} else {
1088showTextBuffer((char *)BootHelp_txt, BootHelp_txt_len);
1089}
1090}
1091

Archive Download this file

Revision: 642