Chameleon

Chameleon Svn Source Tree

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

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

Archive Download this file

Revision: 601