Chameleon

Chameleon Svn Source Tree

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

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

Archive Download this file

Revision: 1119