Chameleon

Chameleon Svn Source Tree

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

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

Archive Download this file

Revision: 735