Chameleon

Chameleon Svn Source Tree

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

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

Archive Download this file

Revision: 789