Chameleon

Chameleon Svn Source Tree

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

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

Archive Download this file

Revision: 749