Chameleon

Chameleon Svn Source Tree

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

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

Archive Download this file

Revision: 574