Chameleon

Chameleon Svn Source Tree

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

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

Archive Download this file

Revision: 532