Chameleon

Chameleon Svn Source Tree

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

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

Archive Download this file

Revision: 533