Chameleon

Chameleon Svn Source Tree

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

Source at commit 583 created 10 years 3 months ago.
By meklort, Module updates, mostly bugfixes.
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 = true;
749
750// Check if "Boot Banner"=N switch is present in config file.
751getBoolForKey(kBootBannerKey, &showBootBanner, &bootInfo->bootConfig);
752if (showBootBanner)
753{
754// Display banner and show hardware info.
755gprintf(&gui.screen, bootBanner + 1, (bootInfo->convmem + bootInfo->extmem) / 1024);
756}
757
758// redraw background
759memcpy(gui.backbuffer->pixels, gui.screen.pixmap->pixels, gui.backbuffer->width * gui.backbuffer->height * 4);
760}
761}
762else
763{
764// Clear screen and hide the blinking cursor.
765clearScreenRows(kMenuTopRow, kMenuTopRow + 2);
766changeCursor(0, kMenuTopRow, kCursorTypeHidden, 0);
767}
768
769nextRow = kMenuTopRow;
770showPrompt = true;
771
772if (gDeviceCount)
773{
774if( bootArgs->Video.v_display == VGA_TEXT_MODE )
775{
776printf("Use \30\31 keys to select the startup volume.");
777}
778GUI_showMenu( menuItems, gDeviceCount, selectIndex, kMenuTopRow + 2, kMenuMaxItems );
779nextRow += min( gDeviceCount, kMenuMaxItems ) + 3;
780}
781
782// Show the boot prompt.
783showPrompt = (gDeviceCount == 0) || (menuBVR->flags & kBVFlagNativeBoot);
784GUI_showBootPrompt( nextRow, showPrompt );
785
786do {
787if (bootArgs->Video.v_display == GRAPHICS_MODE)
788{
789// redraw background
790memcpy( gui.backbuffer->pixels, gui.screen.pixmap->pixels, gui.backbuffer->width * gui.backbuffer->height * 4 );
791// reset cursor co-ords
792gui.debug.cursor = pos( gui.screen.width - 160 , 10 );
793}
794key = getc();
795GUI_updateMenu( key, (void **) &menuBVR );
796newShowPrompt = (gDeviceCount == 0) || (menuBVR->flags & kBVFlagNativeBoot);
797
798if (newShowPrompt != showPrompt)
799{
800showPrompt = newShowPrompt;
801GUI_showBootPrompt( nextRow, showPrompt );
802}
803
804if (showPrompt)
805{
806GUI_updateBootArgs(key);
807}
808
809switch (key)
810{
811case kReturnKey:
812if (gui.menu.draw)
813{
814key=0;
815break;
816}
817if (*gBootArgs == '?')
818{
819char * argPtr = gBootArgs;
820
821// Skip the leading "?" character.
822argPtr++;
823getNextArg(&argPtr, booterCommand);
824getNextArg(&argPtr, booterParam);
825
826/*
827 * TODO: this needs to be refactored.
828 */
829if (strcmp( booterCommand, "video" ) == 0)
830{
831if (bootArgs->Video.v_display == GRAPHICS_MODE)
832{
833showInfoBox(getVBEInfoString(), getVBEModeInfoString());
834}
835else
836{
837printVBEModeInfo();
838}
839}
840else if ( strcmp( booterCommand, "memory" ) == 0)
841{
842if (bootArgs->Video.v_display == GRAPHICS_MODE )
843{
844showInfoBox("Memory Map", getMemoryInfoString());
845}
846else
847{
848printMemoryInfo();
849}
850}
851else if (strcmp(booterCommand, "lspci") == 0)
852{
853lspci();
854}
855else if (strcmp(booterCommand, "more") == 0)
856{
857showTextFile(booterParam);
858}
859else if (strcmp(booterCommand, "rd") == 0)
860{
861processRAMDiskCommand(&argPtr, booterParam);
862}
863else if (strcmp(booterCommand, "norescan") == 0)
864{
865if (gEnableCDROMRescan)
866{
867gEnableCDROMRescan = false;
868break;
869}
870}
871else
872{
873showHelp();
874}
875key = 0;
876GUI_showBootPrompt(nextRow, showPrompt);
877break;
878}
879gBootVolume = menuBVR;
880setRootVolume(menuBVR);
881gBIOSDev = menuBVR->biosdev;
882break;
883
884case kEscapeKey:
885clearBootArgs();
886break;
887
888case kF5Key:
889// New behavior:
890// Clear gBootVolume to restart the loop
891// if the user enabled rescanning the optical drive.
892// Otherwise boot the default boot volume.
893if (gEnableCDROMRescan)
894{
895gBootVolume = NULL;
896clearBootArgs();
897}
898break;
899
900case kF10Key:
901gScanSingleDrive = false;
902scanDisks(gBIOSDev, &bvCount);
903gBootVolume = NULL;
904clearBootArgs();
905break;
906
907case kTabKey:
908// New behavior:
909// Switch between text & graphic interfaces
910// Only Permitted if started in graphics interface
911if (useGUI)
912{
913if (bootArgs->Video.v_display == GRAPHICS_MODE)
914{
915setVideoMode(VGA_TEXT_MODE, 0);
916
917setCursorPosition(0, 0, 0);
918clearScreenRows(0, kScreenLastRow);
919
920// Display banner and show hardware info.
921printf(bootBanner, (bootInfo->convmem + bootInfo->extmem) / 1024);
922printf(getVBEInfoString());
923
924clearScreenRows(kMenuTopRow, kMenuTopRow + 2);
925changeCursor(0, kMenuTopRow, kCursorTypeHidden, 0);
926
927nextRow = kMenuTopRow;
928showPrompt = true;
929
930if (gDeviceCount)
931{
932printf("Use \30\31 keys to select the startup volume.");
933GUI_showMenu(menuItems, gDeviceCount, selectIndex, kMenuTopRow + 2, kMenuMaxItems);
934nextRow += min(gDeviceCount, kMenuMaxItems) + 3;
935}
936
937showPrompt = (gDeviceCount == 0) || (menuBVR->flags & kBVFlagNativeBoot);
938GUI_showBootPrompt(nextRow, showPrompt);
939//changeCursor( 0, kMenuTopRow, kCursorTypeUnderline, 0 );
940}
941else
942{
943gui.redraw = true;
944setVideoMode(GRAPHICS_MODE, 0);
945updateVRAM();
946}
947}
948key = 0;
949break;
950
951default:
952key = 0;
953break;
954}
955} while (0 == key);
956
957done:
958if (bootArgs->Video.v_display == VGA_TEXT_MODE)
959{
960clearScreenRows(kMenuTopRow, kScreenLastRow);
961changeCursor(0, kMenuTopRow, kCursorTypeUnderline, 0);
962}
963shouldboot = false;
964gui.menu.draw = false;
965if (menuItems)
966{
967free(menuItems);
968menuItems = NULL;
969}
970return 0;
971}
972
973
974
975int GUI_error(const char * fmt, ...)
976{
977 va_list ap;
978 gErrors = true;
979 va_start(ap, fmt);
980
981if (bootArgs->Video.v_display == VGA_TEXT_MODE)
982{
983prf(fmt, ap, putchar, 0);
984 }
985else
986{
987vprf(fmt, ap);
988}
989
990va_end(ap);
991 return(0);
992}
993
994int GUI_verbose(const char * fmt, ...)
995{
996 va_list ap;
997
998va_start(ap, fmt);
999 if (gVerboseMode)
1000 {
1001if (bootArgs->Video.v_display == VGA_TEXT_MODE)
1002{
1003prf(fmt, ap, putchar, 0);
1004}
1005else
1006{
1007vprf(fmt, ap);
1008}
1009 }
1010
1011/* Kabyl: BooterLog */
1012struct putc_info pi;
1013
1014if (!msgbuf)
1015return 0;
1016
1017if (((cursor - msgbuf) > (BOOTER_LOG_SIZE - SAFE_LOG_SIZE)))
1018return 0;
1019pi.str = cursor;
1020pi.last_str = 0;
1021prf(fmt, ap, sputc, &pi);
1022cursor += strlen((char *)cursor);
1023
1024
1025 va_end(ap);
1026 return(0);
1027}
1028
1029int GUI_printf(const char * fmt, ...)
1030{
1031 va_list ap;
1032va_start(ap, fmt);
1033if (bootArgs->Video.v_display == VGA_TEXT_MODE)
1034{
1035prf(fmt, ap, putchar, 0);
1036}
1037else
1038{
1039vprf(fmt, ap);
1040}
1041
1042/* Kabyl: BooterLog */
1043struct putc_info pi;
1044
1045if (!msgbuf)
1046return 0;
1047
1048if (((cursor - msgbuf) > (BOOTER_LOG_SIZE - SAFE_LOG_SIZE)))
1049return 0;
1050pi.str = cursor;
1051pi.last_str = 0;
1052prf(fmt, ap, sputc, &pi);
1053cursor += strlen((char *)cursor);
1054
1055va_end(ap);
1056 return 0;
1057}
1058
1059void GUI_stop(const char * fmt, ...)
1060{
1061va_list ap;
1062
1063printf("\n");
1064va_start(ap, fmt);
1065
1066if (bootArgs->Video.v_display == VGA_TEXT_MODE)
1067{
1068prf(fmt, ap, putchar, 0);
1069}
1070else
1071{
1072vprf(fmt, ap);
1073}
1074va_end(ap);
1075
1076printf("\nThis is a non recoverable error! System HALTED!!!");
1077halt();
1078while (1);
1079}
1080
1081void GUI_showHelp(void)
1082{
1083if (bootArgs->Video.v_display == GRAPHICS_MODE) {
1084showInfoBox("Help. Press q to quit.\n", (char *)BootHelp_txt);
1085} else {
1086showTextBuffer((char *)BootHelp_txt, BootHelp_txt_len);
1087}
1088}
1089

Archive Download this file

Revision: 583