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

Archive Download this file

Revision: 693