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

Archive Download this file

Revision: 713