Chameleon

Chameleon Svn Source Tree

Root/tags/2.1/i386/boot2/gui.c

Source at commit 2381 created 10 years 21 days ago.
By ifabio, Apply patch: (Credits to Thomas Jansen aka tja) - Reading options from all devices during boot. The options for the boot menu are only read from the devices rd(0,0) or bt(0,0). Consequently, boot menu options (e.g. "Quiet Boot", "Timeout", etc.) in plists on other devices (like most users have) are ignored. This patch extends the list of paths to search for the options plist on all devices that can be found.
1/*
2 * gui.c
3 *
4 *
5 * Created by Jasmin Fazlic on 18.12.08.
6 * Copyright 2008/09 Jasmin Fazlic All rights reserved.
7 * Copyright 2008/09 iNDi All rights reserved.
8 *
9 */
10
11#include "gui.h"
12#include "term.h"
13#include "appleboot.h"
14#include "vers.h"
15
16#define IMG_REQUIRED -1
17#define THEME_NAME_DEFAULT"Default"
18static const char *theme_name = THEME_NAME_DEFAULT;
19
20#ifdef CONFIG_EMBED_THEME
21#include "art.h"
22#endif
23
24#define LOADPNG(img, alt_img) if (loadThemeImage(#img, alt_img) != 0) { return 1; }
25
26#define VIDEO(x) (bootArgs->Video.v_ ## x)
27
28#define vram VIDEO(baseAddr)
29
30#define TAB_PIXELS_WIDTH (font->chars[0]->width * 4) // tab = 4 spaces
31
32int lasttime = 0; // we need this for animating maybe
33
34
35/*
36 * ATTENTION: the enum and the following array images[] MUST match !!!
37 */
38enum {
39 iBackground = 0,
40 iLogo,
41
42 iDeviceGeneric,
43 iDeviceGeneric_o,
44 iDeviceHFS,
45 iDeviceHFS_o,
46 iDeviceHFS_ML,
47 iDeviceHFS_ML_o,
48 iDeviceHFS_Lion,
49 iDeviceHFS_Lion_o,
50 iDeviceHFS_SL,
51 iDeviceHFS_SL_o,
52 iDeviceHFS_Leo,
53 iDeviceHFS_Leo_o,
54 iDeviceHFS_Tiger,
55 iDeviceHFS_Tiger_o,
56 iDeviceHFSRAID,
57 iDeviceHFSRAID_o,
58 iDeviceHFSRAID_ML,
59 iDeviceHFSRAID_ML_o,
60 iDeviceHFSRAID_Lion,
61 iDeviceHFSRAID_Lion_o,
62 iDeviceHFSRAID_SL,
63 iDeviceHFSRAID_SL_o,
64 iDeviceHFSRAID_Leo,
65 iDeviceHFSRAID_Leo_o,
66 iDeviceHFSRAID_Tiger,
67 iDeviceHFSRAID_Tiger_o,
68 iDeviceEXT3,
69 iDeviceEXT3_o,
70 iDeviceFreeBSD, /* FreeBSD/OpenBSD detection,nawcom's code by valv, Icon credits to blackosx */
71 iDeviceFreeBSD_o, /* FreeBSD/OpenBSD detection,nawcom's code by valv, Icon credits to blackosx */
72 iDeviceOpenBSD, /* FreeBSD/OpenBSD detection,nawcom's code by valv, Icon credits to blackosx */
73 iDeviceOpenBSD_o, /* FreeBSD/OpenBSD detection,nawcom's code by valv, Icon credits to blackosx */
74 iDeviceBEFS, /* Haiku detection and Icon credits to scorpius */
75 iDeviceBEFS_o, /* Haiku detection and Icon credits to scorpius */
76 iDeviceFAT,
77 iDeviceFAT_o,
78 iDeviceFAT16,
79 iDeviceFAT16_o,
80 iDeviceFAT32,
81 iDeviceFAT32_o,
82 iDeviceNTFS,
83 iDeviceNTFS_o,
84 iDeviceCDROM,
85 iDeviceCDROM_o,
86
87 iSelection,
88 iDeviceScrollPrev,
89 iDeviceScrollNext,
90
91 iMenuBoot,
92 iMenuVerbose,
93 iMenuIgnoreCaches,
94 iMenuSingleUser,
95 iMenuMemoryInfo,
96 iMenuVideoInfo,
97 iMenuHelp,
98 iMenuVerboseDisabled,
99 iMenuIgnoreCachesDisabled,
100 iMenuSingleUserDisabled,
101 iMenuSelection,
102
103 iProgressBar,
104 iProgressBarBackground,
105
106 iTextScrollPrev,
107 iTextScrollNext,
108
109 iFontConsole,
110 iFontSmall,
111};
112
113image_t images[] = {
114 {.name = "background", .image = NULL},
115 {.name = "logo", .image = NULL},
116
117 {.name = "device_generic", .image = NULL},
118 {.name = "device_generic_o", .image = NULL},
119 {.name = "device_hfsplus", .image = NULL},
120 {.name = "device_hfsplus_o", .image = NULL},
121 {.name = "device_hfsplus_ml", .image = NULL},
122 {.name = "device_hfsplus_ml_o", .image = NULL},
123 {.name = "device_hfsplus_lion", .image = NULL},
124 {.name = "device_hfsplus_lion_o", .image = NULL},
125 {.name = "device_hfsplus_sl", .image = NULL},
126 {.name = "device_hfsplus_sl_o", .image = NULL},
127 {.name = "device_hfsplus_leo", .image = NULL},
128 {.name = "device_hfsplus_leo_o", .image = NULL},
129 {.name = "device_hfsplus_tiger", .image = NULL},
130 {.name = "device_hfsplus_tiger_o", .image = NULL},
131
132 {.name = "device_hfsraid", .image = NULL},
133 {.name = "device_hfsraid_o", .image = NULL},
134 {.name = "device_hfsraid_ml", .image = NULL},
135 {.name = "device_hfsraid_ml_o", .image = NULL},
136 {.name = "device_hfsraid_lion", .image = NULL},
137 {.name = "device_hfsraid_lion_o", .image = NULL},
138 {.name = "device_hfsraid_sl", .image = NULL},
139 {.name = "device_hfsraid_sl_o", .image = NULL},
140 {.name = "device_hfsraid_leo", .image = NULL},
141 {.name = "device_hfsraid_leo_o", .image = NULL},
142 {.name = "device_hfsraid_tiger", .image = NULL},
143 {.name = "device_hfsraid_tiger_o", .image = NULL},
144 {.name = "device_ext3", .image = NULL},
145 {.name = "device_ext3_o", .image = NULL},
146 {.name = "device_freebsd", .image = NULL}, /* FreeBSD/OpenBSD detection,nawcom's code by valv, Icon credits to blackosx */
147 {.name = "device_freebsd_o", .image = NULL}, /* FreeBSD/OpenBSD detection,nawcom's code by valv, Icon credits to blackosx */
148 {.name = "device_openbsd", .image = NULL}, /* FreeBSD/OpenBSD detection,nawcom's code by valv, Icon credits to blackosx */
149 {.name = "device_openbsd_o", .image = NULL}, /* FreeBSD/OpenBSD detection,nawcom's code by valv, Icon credits to blackosx */
150 {.name = "device_befs", .image = NULL}, /* Haiku detection and Icon credits to scorpius */
151 {.name = "device_befs_o", .image = NULL}, /* Haiku detection and Icon credits to scorpius */
152 {.name = "device_fat", .image = NULL},
153 {.name = "device_fat_o", .image = NULL},
154 {.name = "device_fat16", .image = NULL},
155 {.name = "device_fat16_o", .image = NULL},
156 {.name = "device_fat32", .image = NULL},
157 {.name = "device_fat32_o", .image = NULL},
158 {.name = "device_ntfs", .image = NULL},
159 {.name = "device_ntfs_o", .image = NULL},
160 {.name = "device_cdrom", .image = NULL},
161 {.name = "device_cdrom_o", .image = NULL},
162
163 {.name = "device_selection", .image = NULL},
164 {.name = "device_scroll_prev", .image = NULL},
165 {.name = "device_scroll_next", .image = NULL},
166
167 {.name = "menu_boot", .image = NULL},
168 {.name = "menu_verbose", .image = NULL},
169 {.name = "menu_ignore_caches", .image = NULL},
170 {.name = "menu_single_user", .image = NULL},
171 {.name = "menu_memory_info", .image = NULL},
172 {.name = "menu_video_info", .image = NULL},
173 {.name = "menu_help", .image = NULL},
174 {.name = "menu_verbose_disabled", .image = NULL},
175 {.name = "menu_ignore_caches_disabled", .image = NULL},
176 {.name = "menu_single_user_disabled", .image = NULL},
177 {.name = "menu_selection", .image = NULL},
178
179 {.name = "progress_bar", .image = NULL},
180 {.name = "progress_bar_background", .image = NULL},
181
182 {.name = "text_scroll_prev", .image = NULL},
183 {.name = "text_scroll_next", .image = NULL},
184
185 {.name = "font_console", .image = NULL},
186 {.name = "font_small", .image = NULL},
187};
188
189int imageCnt = 0;
190
191extern intgDeviceCount;
192extern intselectIndex;
193
194extern MenuItem *menuItems;
195
196//char prompt[BOOT_STRING_LEN];
197extern char gBootArgs[BOOT_STRING_LEN];
198
199char prompt_text[] = "boot: ";
200
201menuitem_t infoMenuItems[] =
202{
203{ .text = "Boot" },
204{ .text = "Boot Verbose" },
205{ .text = "Boot Ignore Caches" },
206{ .text = "Boot Single User" },
207{ .text = "Memory Info" },
208{ .text = "Video Info" },
209{ .text = "Help" }
210};
211
212int initFont(font_t *font, image_t *image);
213int destroyFont(font_t *font);
214void colorFont(font_t *font, uint32_t color);
215void makeRoundedCorners(pixmap_t *p);
216
217static int infoMenuSelection = 0;
218static int infoMenuItemsCount = sizeof(infoMenuItems)/sizeof(infoMenuItems[0]);
219
220static bool infoMenuNativeBoot = false;
221
222// here we store the used screen resolution
223static unsigned long screen_params[4] = {DEFAULT_SCREEN_WIDTH, DEFAULT_SCREEN_HEIGHT, 32, 0};
224
225static int getImageIndexByName(const char *name)
226{
227 int i;
228for (i = 0; i < sizeof(images) / sizeof(images[0]); i++)
229{
230 if (strcmp(name, images[i].name) == 0)
231 return i; // found the name
232}
233return -1;
234}
235
236#ifdef CONFIG_EMBED_THEME
237static int getEmbeddedImageIndexByName(const char *name)
238{
239int upperLimit = sizeof(embeddedImages) / sizeof(embeddedImages[0]) - 1;
240int lowerLimit = 0;
241int compareIndex = (upperLimit - lowerLimit) >> 1; // Midpoint
242int result;
243
244// NOTE: This algorithm assumes that the embedded images are sorted.
245// This is currently done using the make file. If the array is
246// generated manualy, this *will* fail to work properly.
247while((result = strcmp(name, embeddedImages[compareIndex].name)) != 0)
248{
249if (result > 0)// We need to search a HIGHER index
250{
251if (compareIndex != lowerLimit)
252{
253lowerLimit = compareIndex;
254}
255else
256{
257return -1;
258}
259compareIndex = (upperLimit + lowerLimit + 1) >> 1;// Midpoint, round up
260}
261else // We Need to search a LOWER index
262{
263if (compareIndex != upperLimit)
264{
265upperLimit = compareIndex;
266}
267else
268{
269return -1;
270}
271compareIndex = (upperLimit + lowerLimit) >> 1;// Midpoint, round down
272}
273}
274return compareIndex;
275}
276#endif
277
278static int loadThemeImage(const char *image, int alt_image)
279{
280chardirspec[256];
281int i;
282#ifdef CONFIG_EMBED_THEME
283int e;
284#endif
285uint16_twidth;
286uint16_theight;
287uint8_t*imagedata;
288
289if ((strlen(image) + strlen(theme_name) + 20) > sizeof(dirspec))
290return 1;
291if ((i = getImageIndexByName(image)) < 0)
292return 1;
293if (!images[i].image && !(images[i].image = malloc(sizeof(pixmap_t))))
294return 1;
295 sprintf(dirspec, "/Extra/Themes/%s/%s.png", theme_name, image);
296 width = 0;
297 height = 0;
298 imagedata = NULL;
299 if ((loadPngImage(dirspec, &width, &height, &imagedata)) == 0)
300 {
301 images[i].image->width = width;
302 images[i].image->height = height;
303 images[i].image->pixels = (pixel_t *)imagedata;
304 flipRB(images[i].image);
305 return 0;
306 }
307#ifdef CONFIG_EMBED_THEME
308 else if ((e = getEmbeddedImageIndexByName(image)) >= 0)
309 {
310 unsigned char *embed_data;
311 unsigned int embed_size;
312 embed_data = embeddedImages[e].pngdata;
313 embed_size = *embeddedImages[e].length;
314
315 if (loadEmbeddedPngImage(embed_data, embed_size, &width, &height, &imagedata) == 0)
316 {
317 images[i].image->width = width;
318 images[i].image->height = height;
319 images[i].image->pixels = (pixel_t *)imagedata;
320 flipRB(images[i].image);
321 return 0;
322 }
323 }
324#endif
325 else if (alt_image != IMG_REQUIRED && is_image_loaded(alt_image))
326 {
327 // Using the passed alternate image for non-mandatory images.
328 // We don't clone the already existing pixmap, but using its properties instead!
329 images[i].image->width = images[alt_image].image->width;
330 images[i].image->height = images[alt_image].image->height;
331 images[i].image->pixels = images[alt_image].image->pixels;
332 return 0;
333 }
334
335// If we got here it's an error
336#ifndef CONFIG_EMBED_THEME
337printf("ERROR: GUI: could not open '%s/%s.png'!\n", theme_name, image);
338sleep(2);
339#endif
340free(images[i].image);
341images[i].image = NULL;
342return 1;
343}
344
345static int loadGraphics(void)
346{
347LOADPNG(background, IMG_REQUIRED);
348LOADPNG(logo, IMG_REQUIRED);
349
350LOADPNG(device_generic, IMG_REQUIRED);
351LOADPNG(device_generic_o, iDeviceGeneric);
352LOADPNG(device_hfsplus, iDeviceGeneric);
353LOADPNG(device_hfsplus_o, iDeviceHFS);
354LOADPNG(device_hfsplus_ml, iDeviceHFS);
355LOADPNG(device_hfsplus_ml_o, iDeviceHFS_ML);
356LOADPNG(device_hfsplus_lion, iDeviceHFS);
357LOADPNG(device_hfsplus_lion_o, iDeviceHFS_Lion);
358LOADPNG(device_hfsplus_sl, iDeviceHFS);
359LOADPNG(device_hfsplus_sl_o, iDeviceHFS_SL);
360LOADPNG(device_hfsplus_leo, iDeviceHFS);
361LOADPNG(device_hfsplus_leo_o, iDeviceHFS_Leo);
362LOADPNG(device_hfsplus_tiger, iDeviceHFS);
363LOADPNG(device_hfsplus_tiger_o, iDeviceHFS_Tiger);
364
365LOADPNG(device_hfsraid, iDeviceHFS);
366LOADPNG(device_hfsraid_o, iDeviceHFSRAID);
367LOADPNG(device_hfsraid_ml, iDeviceHFSRAID);
368LOADPNG(device_hfsraid_ml_o, iDeviceHFSRAID_ML);
369LOADPNG(device_hfsraid_lion, iDeviceHFSRAID);
370LOADPNG(device_hfsraid_lion_o, iDeviceHFSRAID_Lion);
371LOADPNG(device_hfsraid_sl, iDeviceHFSRAID);
372LOADPNG(device_hfsraid_sl_o, iDeviceHFSRAID_SL);
373LOADPNG(device_hfsraid_leo, iDeviceHFSRAID);
374LOADPNG(device_hfsraid_leo_o, iDeviceHFSRAID_Leo);
375LOADPNG(device_hfsraid_tiger, iDeviceHFSRAID);
376LOADPNG(device_hfsraid_tiger_o, iDeviceHFSRAID_Tiger);
377LOADPNG(device_ext3, iDeviceGeneric);
378LOADPNG(device_ext3_o, iDeviceEXT3);
379LOADPNG(device_freebsd, iDeviceGeneric); /* FreeBSD/OpenBSD detection,nawcom's code by valv, Icon credits to blackosx */
380LOADPNG(device_freebsd_o, iDeviceFreeBSD); /* FreeBSD/OpenBSD detection,nawcom's code by valv, Icon credits to blackosx */
381LOADPNG(device_openbsd, iDeviceGeneric); /* FreeBSD/OpenBSD detection,nawcom's code by valv, Icon credits to blackosx */
382LOADPNG(device_openbsd_o, iDeviceOpenBSD); /* FreeBSD/OpenBSD detection,nawcom's code by valv, Icon credits to blackosx */
383LOADPNG(device_befs, iDeviceGeneric); /* Haiku detection and Icon credits to scorpius */
384LOADPNG(device_befs_o, iDeviceBEFS); /* Haiku detection and Icon credits to scorpius */
385LOADPNG(device_fat, iDeviceGeneric);
386LOADPNG(device_fat_o, iDeviceFAT);
387LOADPNG(device_fat16, iDeviceFAT);
388LOADPNG(device_fat16_o, iDeviceFAT16);
389LOADPNG(device_fat32, iDeviceFAT);
390LOADPNG(device_fat32_o, iDeviceFAT32);
391LOADPNG(device_ntfs, iDeviceGeneric);
392LOADPNG(device_ntfs_o, iDeviceNTFS);
393LOADPNG(device_cdrom, iDeviceGeneric);
394LOADPNG(device_cdrom_o, iDeviceCDROM);
395
396LOADPNG(device_selection, IMG_REQUIRED);
397LOADPNG(device_scroll_prev, IMG_REQUIRED);
398LOADPNG(device_scroll_next, IMG_REQUIRED);
399
400LOADPNG(menu_boot, IMG_REQUIRED);
401LOADPNG(menu_verbose, IMG_REQUIRED);
402LOADPNG(menu_ignore_caches, IMG_REQUIRED);
403LOADPNG(menu_single_user, IMG_REQUIRED);
404LOADPNG(menu_memory_info, IMG_REQUIRED);
405LOADPNG(menu_video_info, IMG_REQUIRED);
406LOADPNG(menu_help, IMG_REQUIRED);
407LOADPNG(menu_verbose_disabled, IMG_REQUIRED);
408LOADPNG(menu_ignore_caches_disabled, IMG_REQUIRED);
409LOADPNG(menu_single_user_disabled, IMG_REQUIRED);
410LOADPNG(menu_selection, IMG_REQUIRED);
411
412LOADPNG(progress_bar, IMG_REQUIRED);
413LOADPNG(progress_bar_background, IMG_REQUIRED);
414
415LOADPNG(text_scroll_prev, IMG_REQUIRED);
416LOADPNG(text_scroll_next, IMG_REQUIRED);
417
418LOADPNG(font_console, IMG_REQUIRED);
419LOADPNG(font_small, IMG_REQUIRED);
420
421initFont( &font_console, &images[iFontConsole]);
422initFont( &font_small, &images[iFontSmall]);
423
424return 0;
425}
426
427static int unloadGraphics(void)
428{
429 int i;
430
431 destroyFont(&font_console);
432 destroyFont(&font_small);
433for (i = 0; i < sizeof(images) / sizeof(images[0]); i++)
434{
435 if (images[i].image)
436 {
437 if (images[i].image->pixels) free(images[i].image->pixels);
438 free (images[i].image);
439 images[i].image = 0;
440 }
441}
442return 0;
443}
444
445int freeBackBuffer( window_t *window )
446{
447 if (gui.backbuffer && gui.backbuffer->pixels)
448 {
449 free(gui.backbuffer->pixels);
450 free(gui.backbuffer);
451 gui.backbuffer = 0;
452 return 0;
453 }
454
455 return 1;
456}
457
458pixmap_t *getCroppedPixmapAtPosition( pixmap_t *from, position_t pos, uint16_t width, uint16_t height )
459{
460
461pixmap_t *cropped = malloc( sizeof( pixmap_t ) );
462if( !cropped )
463return 0;
464cropped->pixels = malloc( width * height * 4 );
465if ( !cropped->pixels )
466return 0;
467
468cropped->width = width;
469cropped->height = height;
470
471int destx = 0, desty = 0;
472int srcx = pos.x, srcy = pos.y;
473
474for( ; desty < height; desty++, srcy++)
475{
476for( destx = 0, srcx = pos.x; destx < width; destx++, srcx++ )
477{
478pixel( cropped, destx, desty ).value = pixel( from, srcx, srcy ).value;
479}
480}
481return cropped;
482}
483
484int createBackBuffer( window_t *window )
485{
486gui.backbuffer = malloc(sizeof(pixmap_t));
487if(!gui.backbuffer)
488{
489return 1;
490}
491gui.backbuffer->pixels = malloc( window->width * window->height * 4 );
492if(!gui.backbuffer->pixels)
493{
494free(gui.backbuffer);
495gui.backbuffer = 0;
496return 1;
497}
498
499gui.backbuffer->width = gui.screen.width;
500gui.backbuffer->height = gui.screen.height;
501
502return 0;
503}
504
505int createWindowBuffer( window_t *window )
506{
507window->pixmap = malloc(sizeof(pixmap_t));
508if(!window->pixmap)
509{
510return 1;
511}
512
513window->pixmap->pixels = malloc( window->width * window->height * 4 );
514if(!window->pixmap->pixels)
515{
516free(window->pixmap);
517window->pixmap = 0;
518return 1;
519}
520
521window->pixmap->width = window->width;
522window->pixmap->height = window->height;
523
524return 0;
525}
526
527int freeWindowBuffer( window_t *window )
528{
529if (window->pixmap && window->pixmap->pixels)
530 {
531free(window->pixmap->pixels);
532free(window->pixmap);
533return 0;
534}
535
536return 1;
537}
538
539void fillPixmapWithColor(pixmap_t *pm, uint32_t color)
540{
541int x,y;
542
543// fill with given color AARRGGBB
544for( x=0; x < pm->width; x++ )
545for( y=0; y< pm->height; y++)
546pixel(pm,x,y).value = color;
547}
548
549void drawBackground()
550{
551// reset text cursor
552gui.screen.cursor.x = gui.screen.hborder;
553gui.screen.cursor.y = gui.screen.vborder;
554
555fillPixmapWithColor( gui.screen.pixmap, gui.screen.bgcolor);
556
557// draw background.png into background buffer
558blend( images[iBackground].image, gui.screen.pixmap, gui.background.pos );
559
560// draw logo.png into background buffer
561if (gui.logo.draw)
562{
563 blend( images[iLogo].image, gui.screen.pixmap, gui.logo.pos);
564}
565
566memcpy( gui.backbuffer->pixels, gui.screen.pixmap->pixels, gui.backbuffer->width * gui.backbuffer->height * 4 );
567}
568
569void setupDeviceList(config_file_t *theme)
570{
571unsigned int pixel;
572intalpha;// transparency level 0 (obligue) - 255 (transparent)
573uint32_t color;// color value formatted RRGGBB
574int val, len;
575const char *string;
576
577if(getIntForKey("devices_max_visible", &val, theme ))
578gui.maxdevices = MIN( val, gDeviceCount );
579
580if(getIntForKey("devices_iconspacing", &val, theme ))
581gui.devicelist.iconspacing = val;
582
583// check layout for horizontal or vertical
584gui.layout = HorizontalLayout;
585if(getValueForKey( "devices_layout", &string, &len, theme)) {
586if (!strcmp (string, "vertical")) {
587gui.layout = VerticalLayout;
588}
589}
590
591switch (gui.layout) {
592case VerticalLayout:
593gui.devicelist.height = ((images[iSelection].image->height + font_console.chars[0]->height + gui.devicelist.iconspacing) * MIN(gui.maxdevices, gDeviceCount) + (images[iDeviceScrollPrev].image->height + images[iDeviceScrollNext].image->height) + gui.devicelist.iconspacing);
594gui.devicelist.width = (images[iSelection].image->width + gui.devicelist.iconspacing);
595
596if(getDimensionForKey("devices_pos_x", &pixel, theme, gui.screen.width , images[iSelection].image->width ) )
597gui.devicelist.pos.x = pixel;
598
599if(getDimensionForKey("devices_pos_y", &pixel, theme, gui.screen.height , gui.devicelist.height ) )
600gui.devicelist.pos.y = pixel;
601break;
602
603case HorizontalLayout:
604default:
605gui.devicelist.width = ((images[iSelection].image->width + gui.devicelist.iconspacing) * MIN(gui.maxdevices, gDeviceCount) + (images[iDeviceScrollPrev].image->width + images[iDeviceScrollNext].image->width) + gui.devicelist.iconspacing);
606gui.devicelist.height = (images[iSelection].image->height + font_console.chars[0]->height + gui.devicelist.iconspacing);
607
608if(getDimensionForKey("devices_pos_x", &pixel, theme, gui.screen.width , gui.devicelist.width ) )
609gui.devicelist.pos.x = pixel;
610else
611gui.devicelist.pos.x = ( gui.screen.width - gui.devicelist.width ) / 2;
612
613if(getDimensionForKey("devices_pos_y", &pixel, theme, gui.screen.height , images[iSelection].image->height ) )
614gui.devicelist.pos.y = pixel;
615else
616gui.devicelist.pos.y = ( gui.screen.height - gui.devicelist.height ) / 2;
617break;
618}
619
620if(getColorForKey("devices_bgcolor", &color, theme))
621gui.devicelist.bgcolor = (color & 0x00FFFFFF);
622
623if(getIntForKey("devices_transparency", &alpha, theme))
624gui.devicelist.bgcolor = gui.devicelist.bgcolor | (( 255 - ( alpha & 0xFF) ) << 24);
625
626if (gui.devicelist.pixmap)
627{
628 freeWindowBuffer(&gui.devicelist);
629 createWindowBuffer(&gui.devicelist);
630 }
631}
632
633void loadThemeValues(config_file_t *theme)
634{
635unsigned int screen_width = gui.screen.width;
636unsigned int screen_height = gui.screen.height;
637unsigned int pixel;
638intalpha;// transparency level 0 (obligue) - 255 (transparent)
639uint32_t color;// color value formatted RRGGBB
640int val;
641
642/*
643 * Parse screen parameters
644 */
645if(getColorForKey("screen_bgcolor", &color, theme ))
646gui.screen.bgcolor = (color & 0x00FFFFFF);
647
648if(getIntForKey("screen_textmargin_h", &val, theme))
649gui.screen.hborder = MIN( gui.screen.width , val );
650
651if(getIntForKey("screen_textmargin_v", &val, theme))
652gui.screen.vborder = MIN( gui.screen.height , val );
653
654/*
655 * Parse background parameters
656 */
657if(getDimensionForKey("background_pos_x", &pixel, theme, screen_width , images[iBackground].image->width ) )
658gui.background.pos.x = pixel;
659
660if(getDimensionForKey("background_pos_y", &pixel, theme, screen_height , images[iBackground].image->height ) )
661gui.background.pos.y = pixel;
662
663/*
664 * Parse logo parameters
665 */
666if(getDimensionForKey("logo_pos_x", &pixel, theme, screen_width , images[iLogo].image->width ) )
667gui.logo.pos.x = pixel;
668
669if(getDimensionForKey("logo_pos_y", &pixel, theme, screen_height , images[iLogo].image->height ) )
670gui.logo.pos.y = pixel;
671
672/*
673 * Parse progress bar parameters
674 */
675if(getDimensionForKey("progressbar_pos_x", &pixel, theme, screen_width , 0 ) )
676gui.progressbar.pos.x = pixel;
677
678if(getDimensionForKey("progressbar_pos_y", &pixel, theme, screen_height , 0 ) )
679gui.progressbar.pos.y = pixel;
680
681/*
682 * Parse countdown text parameters
683 */
684if(getDimensionForKey("countdown_pos_x", &pixel, theme, screen_width , 0 ) )
685gui.countdown.pos.x = pixel;
686
687if(getDimensionForKey("countdown_pos_y", &pixel, theme, screen_height , 0 ) )
688gui.countdown.pos.y = pixel;
689
690 /*
691 * Parse devicelist parameters
692 */
693setupDeviceList(theme);
694
695/*
696 * Parse infobox parameters
697 */
698if(getIntForKey("infobox_width", &val, theme))
699gui.infobox.width = MIN( screen_width , val );
700
701if(getIntForKey("infobox_height", &val, theme))
702gui.infobox.height = MIN( screen_height , val );
703
704if(getDimensionForKey("infobox_pos_x", &pixel, theme, screen_width , gui.infobox.width ) )
705gui.infobox.pos.x = pixel;
706
707if(getDimensionForKey("infobox_pos_y", &pixel, theme, screen_height , gui.infobox.height ) )
708gui.infobox.pos.y = pixel;
709
710if(getIntForKey("infobox_textmargin_h", &val, theme))
711gui.infobox.hborder = MIN( gui.infobox.width , val );
712
713if(getIntForKey("infobox_textmargin_v", &val, theme))
714gui.infobox.vborder = MIN( gui.infobox.height , val );
715
716if(getColorForKey("infobox_bgcolor", &color, theme))
717gui.infobox.bgcolor = (color & 0x00FFFFFF);
718
719if(getIntForKey("infobox_transparency", &alpha, theme))
720gui.infobox.bgcolor = gui.infobox.bgcolor | (( 255 - ( alpha & 0xFF) ) << 24);
721
722/*
723 * Parse menu parameters
724 */
725if(getDimensionForKey("menu_width", &pixel, theme, gui.screen.width , 0 ) )
726gui.menu.width = pixel;
727else
728gui.menu.width = images[iMenuSelection].image->width;
729
730if(getDimensionForKey("menu_height", &pixel, theme, gui.screen.height , 0 ) )
731gui.menu.height = pixel;
732else
733gui.menu.height = (infoMenuItemsCount) * images[iMenuSelection].image->height;
734
735if(getDimensionForKey("menu_pos_x", &pixel, theme, screen_width , gui.menu.width ) )
736gui.menu.pos.x = pixel;
737
738if(getDimensionForKey("menu_pos_y", &pixel, theme, screen_height , gui.menu.height ) )
739gui.menu.pos.y = pixel;
740
741if(getIntForKey("menu_textmargin_h", &val, theme))
742gui.menu.hborder = MIN( gui.menu.width , val );
743
744if(getIntForKey("menu_textmargin_v", &val, theme))
745gui.menu.vborder = MIN( gui.menu.height , val );
746
747if(getColorForKey("menu_bgcolor", &color, theme))
748gui.menu.bgcolor = (color & 0x00FFFFFF);
749
750if(getIntForKey("menu_transparency", &alpha, theme))
751gui.menu.bgcolor = gui.menu.bgcolor | (( 255 - ( alpha & 0xFF) ) << 24);
752
753/*
754 * Parse bootprompt parameters
755 */
756if(getDimensionForKey("bootprompt_width", &pixel, theme, screen_width , 0 ) )
757gui.bootprompt.width = pixel;
758
759if(getIntForKey("bootprompt_height", &val, theme))
760gui.bootprompt.height = MIN( screen_height , val );
761
762if(getDimensionForKey("bootprompt_pos_x", &pixel, theme, screen_width , gui.bootprompt.width ) )
763gui.bootprompt.pos.x = pixel;
764
765if(getDimensionForKey("bootprompt_pos_y", &pixel, theme, screen_height , gui.bootprompt.height ) )
766gui.bootprompt.pos.y = pixel;
767
768if(getIntForKey("bootprompt_textmargin_h", &val, theme))
769gui.bootprompt.hborder = MIN( gui.bootprompt.width , val );
770
771if(getIntForKey("bootprompt_textmargin_v", &val, theme))
772gui.bootprompt.vborder = MIN( gui.bootprompt.height , val );
773
774if(getColorForKey("bootprompt_bgcolor", &color, theme))
775gui.bootprompt.bgcolor = (color & 0x00FFFFFF);
776
777if(getIntForKey("bootprompt_transparency", &alpha, theme))
778gui.bootprompt.bgcolor = gui.bootprompt.bgcolor | (( 255 - ( alpha & 0xFF) ) << 24);
779
780if(getColorForKey("font_small_color", &color, theme))
781gui.screen.font_small_color = (color & 0x00FFFFFF);
782
783if(getColorForKey("font_console_color", &color, theme))
784gui.screen.font_console_color = (color & 0x00FFFFFF);
785}
786
787int initGUI(void)
788{
789intval;
790intlen;
791chardirspec[256];
792
793getValueForKey( "Theme", &theme_name, &len, &bootInfo->chameleonConfig );
794if ((strlen(theme_name) + 27) > sizeof(dirspec)) {
795return 1;
796}
797sprintf(dirspec, "/Extra/Themes/%s/theme.plist", theme_name);
798if (loadConfigFile(dirspec, &bootInfo->themeConfig) != 0) {
799#ifdef CONFIG_EMBED_THEME
800 config_file_t*config;
801
802 config = &bootInfo->themeConfig;
803 if (ParseXMLFile((char *)__theme_plist, &config->dictionary) != 0) {
804 return 1;
805 }
806#else
807return 1;
808#endif
809}
810// parse display size parameters
811if (getIntForKey("screen_width", &val, &bootInfo->themeConfig) && val > 0) {
812screen_params[0] = val;
813}
814if (getIntForKey("screen_height", &val, &bootInfo->themeConfig) && val > 0) {
815screen_params[1] = val;
816}
817
818// Initalizing GUI strucutre.
819bzero(&gui, sizeof(gui_t));
820
821// find best matching vesa mode for our requested width & height
822getGraphicModeParams(screen_params);
823
824// set our screen structure with the mode width & height
825gui.screen.width = screen_params[0];
826gui.screen.height = screen_params[1];
827
828// load graphics otherwise fail and return
829if (loadGraphics() == 0) {
830loadThemeValues(&bootInfo->themeConfig);
831colorFont(&font_small, gui.screen.font_small_color);
832colorFont(&font_console, gui.screen.font_console_color);
833
834// create the screen & window buffers
835if (createBackBuffer(&gui.screen) == 0) {
836if (createWindowBuffer(&gui.screen) == 0) {
837if (createWindowBuffer(&gui.devicelist) == 0) {
838if (createWindowBuffer(&gui.bootprompt) == 0) {
839if (createWindowBuffer(&gui.infobox) == 0) {
840if (createWindowBuffer(&gui.menu) == 0) {
841 gui.logo.draw = true;
842drawBackground();
843// lets copy the screen into the back buffer
844memcpy( gui.backbuffer->pixels, gui.screen.pixmap->pixels, gui.backbuffer->width * gui.backbuffer->height * 4 );
845setVideoMode( GRAPHICS_MODE, 0 );
846gui.initialised = true;
847return 0;
848}
849}
850}
851}
852}
853}
854}
855
856 // not available memory, freeing resources
857 freeWindowBuffer(&gui.menu);
858 freeWindowBuffer(&gui.infobox);
859 freeWindowBuffer(&gui.bootprompt);
860 freeWindowBuffer(&gui.devicelist);
861 freeWindowBuffer(&gui.screen);
862 freeBackBuffer(&gui.screen);
863 unloadGraphics();
864
865return 1;
866}
867
868bool is_image_loaded(int i)
869{
870return (images[i].image != NULL) ? true : false;
871}
872
873void drawDeviceIcon(BVRef device, pixmap_t *buffer, position_t p, bool isSelected)
874{
875int devicetype;
876
877if( diskIsCDROM(device) )
878devicetype = iDeviceCDROM;// Use CDROM icon
879else
880{
881switch (device->part_type)
882{
883case kPartitionTypeHFS:
884{
885// Use HFS or HFSRAID icon depending on bvr flags. Fallbacks are handled by alt_image above.
886switch (device->OSVersion[3]) {
887case '8':
888devicetype = (device->flags & kBVFlagBooter ? iDeviceHFSRAID_ML : iDeviceHFS_ML);
889break;
890case '7':
891devicetype = (device->flags & kBVFlagBooter ? iDeviceHFSRAID_Lion : iDeviceHFS_Lion);
892break;
893case '6':
894devicetype = (device->flags & kBVFlagBooter ? iDeviceHFSRAID_SL : iDeviceHFS_SL);
895break;
896case '5':
897devicetype = (device->flags & kBVFlagBooter ? iDeviceHFSRAID_Leo : iDeviceHFS_Leo);
898break;
899case '4':
900devicetype = (device->flags & kBVFlagBooter ? iDeviceHFSRAID_Tiger : iDeviceHFS_Tiger);
901break;
902default:
903devicetype = (device->flags & kBVFlagBooter ? iDeviceHFSRAID : iDeviceHFS);
904break;
905}
906
907break;
908
909}
910case kPartitionTypeHPFS:
911devicetype = iDeviceNTFS;// Use HPFS / NTFS icon
912break;
913
914case kPartitionTypeFAT16:
915devicetype = iDeviceFAT16;// Use FAT16 icon
916break;
917
918case kPartitionTypeFAT32:
919devicetype = iDeviceFAT32;// Use FAT32 icon
920break;
921
922case kPartitionTypeEXT3:
923devicetype = iDeviceEXT3;// Use EXT2/3 icon
924break;
925
926case kPartitionTypeFreeBSD: /* FreeBSD/OpenBSD detection,nawcom's code by valv, Icon credits to blackosx */
927devicetype = iDeviceFreeBSD;// Use FreeBSD icon
928break;
929
930case kPartitionTypeOpenBSD: /* FreeBSD/OpenBSD detection,nawcom's code by valv, Icon credits to blackosx */
931devicetype = iDeviceOpenBSD;// Use OpenBSD icon
932break;
933
934case kPartitionTypeBEFS: /* Haiku detection and Icon credits to scorpius */
935devicetype = iDeviceBEFS;// Use BEFS / Haiku icon
936break;
937
938default:
939devicetype = iDeviceGeneric;// Use Generic icon
940break;
941}
942}
943
944// Draw the selection image and use the next (device_*_o) image for the selected item.
945if (isSelected)
946{
947blend(images[iSelection].image, buffer, centeredAt(images[iSelection].image, p));
948devicetype++; // select override image
949}
950
951// draw icon
952blend(images[devicetype].image, buffer, centeredAt(images[devicetype].image, p));
953
954p.y += (images[iSelection].image->height / 2) + font_console.chars[0]->height;
955
956// draw volume label
957drawStrCenteredAt( device->label, &font_small, buffer, p);
958
959}
960
961void drawDeviceList (int start, int end, int selection)
962{
963inti;
964boolshoWinfo = false;
965extern bool showBootBanner;
966position_tp, p_prev, p_next;
967
968//uint8_tmaxDevices = MIN( gui.maxdevices, menucount );
969
970fillPixmapWithColor( gui.devicelist.pixmap, gui.devicelist.bgcolor);
971
972makeRoundedCorners( gui.devicelist.pixmap);
973
974switch (gui.layout)
975{
976
977case VerticalLayout:
978p.x = (gui.devicelist.width /2);
979p.y = ( ( images[iSelection].image->height / 2 ) + images[iDeviceScrollPrev].image->height + gui.devicelist.iconspacing );
980
981// place scroll indicators at top & bottom edges
982p_prev = pos ( gui.devicelist.width / 2 , gui.devicelist.iconspacing );
983p_next = pos ( p_prev.x, gui.devicelist.height - gui.devicelist.iconspacing );
984
985break;
986
987default:// use Horizontal layout as the default
988
989case HorizontalLayout:
990p.x = (gui.devicelist.width - ( gui.devicelist.width / gui.maxdevices ) * gui.maxdevices ) / 2 + ( images[iSelection].image->width / 2) + images[iDeviceScrollPrev].image->width + gui.devicelist.iconspacing;
991p.y = ((gui.devicelist.height - font_console.chars[0]->height ) - images[iSelection].image->height) / 2 + ( images[iSelection].image->height / 2 );
992
993// place scroll indicators at left & right edges
994p_prev = pos ( images[iDeviceScrollPrev].image->width / 2 + gui.devicelist.iconspacing / 2, gui.devicelist.height / 2 );
995p_next = pos ( gui.devicelist.width - ( images[iDeviceScrollNext].image->width / 2 + gui.devicelist.iconspacing / 2), gui.devicelist.height / 2 );
996
997break;
998
999}
1000
1001// draw visible device icons
1002for (i = 0; i < gui.maxdevices; i++)
1003{
1004BVRef param = menuItems[start + i].param;
1005
1006 bool isSelected = ((start + i) == selection) ? true : false;
1007if (isSelected)
1008{
1009 if (param->flags & kBVFlagNativeBoot)
1010 {
1011 infoMenuNativeBoot = true;
1012 }
1013 else
1014 {
1015 infoMenuNativeBoot = false;
1016 if(infoMenuSelection >= INFOMENU_NATIVEBOOT_START && infoMenuSelection <= INFOMENU_NATIVEBOOT_END)
1017 infoMenuSelection = 0;
1018 }
1019
1020if (gui.menu.draw)
1021drawInfoMenuItems();
1022
1023getBoolForKey(kShowInfoKey, &shoWinfo, &bootInfo->chameleonConfig);
1024
1025if (shoWinfo && showBootBanner)
1026{
1027gui.debug.cursor = pos( 10, 100);
1028dprintf( &gui.screen, "label: %s\n", param->label );
1029dprintf( &gui.screen, "biosdev: 0x%x\n", param->biosdev );
1030dprintf( &gui.screen, "type: 0x%x\n", param->type );
1031dprintf( &gui.screen, "flags: 0x%x\n", param->flags );
1032dprintf( &gui.screen, "part_no: %d\n", param->part_no );
1033dprintf( &gui.screen, "part_boff: 0x%x\n", param->part_boff );
1034dprintf( &gui.screen, "part_type: 0x%x\n", param->part_type );
1035dprintf( &gui.screen, "bps: 0x%x\n", param->bps );
1036dprintf( &gui.screen, "name: %s\n", param->name );
1037dprintf( &gui.screen, "type_name: %s\n", param->type_name );
1038dprintf( &gui.screen, "modtime: %d\n", param->modTime );
1039//// res
1040dprintf( &gui.screen, "width: %d\n", gui.screen.width );
1041dprintf( &gui.screen, "height: %d\n", gui.screen.height );
1042//dprintf( &gui.screen, "attr: 0x%x\n", gui.screen.attr ); //Azi: reminder
1043//dprintf( &gui.screen, "mm: %d\n", gui.screen.mm );
1044}
1045}
1046
1047drawDeviceIcon( param, gui.devicelist.pixmap, p, isSelected);
1048
1049if (gui.layout == HorizontalLayout)
1050{
1051p.x += images[iSelection].image->width + gui.devicelist.iconspacing;
1052}
1053if (gui.layout == VerticalLayout)
1054{
1055p.y += ( images[iSelection].image->height + font_console.chars[0]->height + gui.devicelist.iconspacing );
1056}
1057}
1058
1059// draw prev indicator
1060if (start)
1061blend( images[iDeviceScrollPrev].image, gui.devicelist.pixmap, centeredAt( images[iDeviceScrollPrev].image, p_prev ) );
1062
1063// draw next indicator
1064if ( end < gDeviceCount - 1 )
1065blend( images[iDeviceScrollNext].image, gui.devicelist.pixmap, centeredAt( images[iDeviceScrollNext].image, p_next ) );
1066
1067gui.redraw = true;
1068
1069updateVRAM();
1070
1071}
1072
1073void clearGraphicBootPrompt()
1074{
1075// clear text buffer
1076//prompt[0] = '\0';
1077//prompt_pos=0;
1078
1079
1080if(gui.bootprompt.draw == true )
1081{
1082gui.bootprompt.draw = false;
1083gui.redraw = true;
1084// this causes extra frames to be drawn
1085//updateVRAM();
1086}
1087
1088return;
1089}
1090
1091void updateGraphicBootPrompt()
1092{
1093fillPixmapWithColor( gui.bootprompt.pixmap, gui.bootprompt.bgcolor);
1094
1095makeRoundedCorners( gui.bootprompt.pixmap);
1096
1097position_t p_text = pos( gui.bootprompt.hborder , ( ( gui.bootprompt.height - font_console.chars[0]->height) ) / 2 );
1098
1099// print the boot prompt text
1100drawStr(prompt_text, &font_console, gui.bootprompt.pixmap, p_text);
1101
1102// get the position of the end of the boot prompt text to display user input
1103position_t p_prompt = pos( p_text.x + ( ( strlen(prompt_text) ) * font_console.chars[0]->width ), p_text.y );
1104
1105drawStr( gBootArgs, &font_console, gui.bootprompt.pixmap, p_prompt);
1106
1107gui.menu.draw = false;
1108gui.bootprompt.draw = true;
1109gui.redraw = true;
1110
1111updateVRAM();
1112
1113return;
1114}
1115
1116static inline
1117void vramwrite (void *data, int width, int height)
1118{
1119if (VIDEO (depth) == 32 && VIDEO (rowBytes) == gui.backbuffer->width * 4)
1120memcpy((uint8_t *)vram, gui.backbuffer->pixels, VIDEO (rowBytes)*VIDEO (height));
1121else
1122{
1123uint32_t r, g, b;
1124int i, j;
1125for (i = 0; i < VIDEO (height); i++)
1126for (j = 0; j < VIDEO (width); j++)
1127{
1128b = ((uint8_t *) data)[4*i*width + 4*j];
1129g = ((uint8_t *) data)[4*i*width + 4*j + 1];
1130r = ((uint8_t *) data)[4*i*width + 4*j + 2];
1131switch (VIDEO (depth))
1132{
1133case 32:
1134*(uint32_t *)(((uint8_t *)vram)+i*VIDEO (rowBytes) + j*4) = (b&0xff) | ((g&0xff)<<8) | ((r&0xff)<<16);
1135break;
1136case 24:
1137*(uint32_t *)(((uint8_t *)vram)+i*VIDEO (rowBytes) + j*3) = ((*(uint32_t *)(((uint8_t *)vram)+i*VIDEO (rowBytes) + j*3))&0xff000000)
1138| (b&0xff) | ((g&0xff)<<8) | ((r&0xff)<<16);
1139break;
1140case 16:
1141// Somehow 16-bit is always 15-bits really
1142//*(uint16_t *)(((uint8_t *)vram)+i*VIDEO (rowBytes) + j*2) = ((b&0xf8)>>3) | ((g&0xfc)<<3) | ((r&0xf8)<<8);
1143//break;
1144case 15:
1145*(uint16_t *)(((uint8_t *)vram)+i*VIDEO (rowBytes) + j*2) = ((b&0xf8)>>3) | ((g&0xf8)<<2) | ((r&0xf8)<<7);
1146break;
1147}
1148}
1149}
1150}
1151
1152void updateVRAM()
1153{
1154if (gui.redraw)
1155{
1156if (gui.devicelist.draw)
1157blend( gui.devicelist.pixmap, gui.backbuffer, gui.devicelist.pos );
1158
1159if (gui.bootprompt.draw)
1160blend( gui.bootprompt.pixmap, gui.backbuffer, gui.bootprompt.pos );
1161
1162if (gui.menu.draw)
1163blend( gui.menu.pixmap, gui.backbuffer, gui.menu.pos );
1164
1165if (gui.infobox.draw)
1166blend( gui.infobox.pixmap, gui.backbuffer, gui.infobox.pos );
1167}
1168
1169vramwrite ( gui.backbuffer->pixels, gui.backbuffer->width, gui.backbuffer->height );
1170
1171if (gui.redraw)
1172{
1173memcpy( gui.backbuffer->pixels, gui.screen.pixmap->pixels, gui.backbuffer->width * gui.backbuffer->height * 4 );
1174gui.redraw = false;
1175}
1176}
1177
1178struct putc_info //Azi: exists on console.c & printf.c
1179{
1180 char * str;
1181 char * last_str;
1182};
1183
1184static int
1185sputc(int c, struct putc_info * pi) //Azi: same as above
1186{
1187 if (pi->last_str)
1188 if (pi->str == pi->last_str) {
1189 *(pi->str) = '\0';
1190 return 0;
1191 }
1192 *(pi->str)++ = c;
1193 return c;
1194}
1195
1196int gprintf( window_t * window, const char * fmt, ...)
1197{
1198char *formattedtext;
1199
1200va_list ap;
1201
1202struct putc_info pi;
1203
1204if ((formattedtext = malloc(1024)) != NULL) {
1205// format the text
1206va_start(ap, fmt);
1207pi.str = formattedtext;
1208pi.last_str = 0;
1209prf(fmt, ap, sputc, &pi);
1210*pi.str = '\0';
1211va_end(ap);
1212
1213position_torigin, cursor, bounds;
1214
1215int i;
1216int character;
1217
1218origin.x = MAX( window->cursor.x, window->hborder );
1219origin.y = MAX( window->cursor.y, window->vborder );
1220
1221bounds.x = ( window->width - window->hborder );
1222bounds.y = ( window->height - window->vborder );
1223
1224cursor = origin;
1225
1226font_t *font = &font_console;
1227
1228for( i=0; i< strlen(formattedtext); i++ )
1229{
1230character = formattedtext[i];
1231
1232character -= 32;
1233
1234// newline ?
1235if( formattedtext[i] == '\n' )
1236{
1237cursor.x = window->hborder;
1238cursor.y += font->height;
1239
1240if ( cursor.y > bounds.y )
1241cursor.y = origin.y;
1242
1243continue;
1244}
1245
1246// tab ?
1247if( formattedtext[i] == '\t' )
1248cursor.x += ( font->chars[0]->width * 5 );
1249
1250// draw the character
1251if( font->chars[character])
1252blend(font->chars[character], window->pixmap, cursor);
1253
1254cursor.x += font->chars[character]->width;
1255
1256// check x pos and do newline
1257if ( cursor.x > bounds.x )
1258{
1259cursor.x = origin.x;
1260cursor.y += font->height;
1261}
1262
1263// check y pos and reset to origin.y
1264if ( cursor.y > bounds.y )
1265cursor.y = origin.y;
1266}
1267
1268// update cursor postition
1269window->cursor = cursor;
1270
1271free(formattedtext);
1272
1273return 0;
1274
1275}
1276return 1;
1277}
1278
1279int dprintf( window_t * window, const char * fmt, ...)
1280{
1281char *formattedtext;
1282
1283va_list ap;
1284
1285//window = &gui.debug;
1286
1287struct putc_info pi;
1288
1289if ((formattedtext = malloc(1024)) != NULL) {
1290// format the text
1291va_start(ap, fmt);
1292pi.str = formattedtext;
1293pi.last_str = 0;
1294prf(fmt, ap, sputc, &pi);
1295*pi.str = '\0';
1296va_end(ap);
1297
1298position_torigin, cursor, bounds;
1299
1300int i;
1301int character;
1302
1303origin.x = MAX( gui.debug.cursor.x, window->hborder );
1304origin.y = MAX( gui.debug.cursor.y, window->vborder );
1305
1306bounds.x = ( window->width - window->hborder );
1307bounds.y = ( window->height - window->vborder );
1308
1309cursor = origin;
1310
1311font_t *font = &font_console;
1312
1313for( i=0; i< strlen(formattedtext); i++ )
1314{
1315character = formattedtext[i];
1316
1317character -= 32;
1318
1319// newline ?
1320if( formattedtext[i] == '\n' )
1321{
1322cursor.x = window->hborder;
1323cursor.y += font->height;
1324
1325if ( cursor.y > bounds.y )
1326cursor.y = origin.y;
1327
1328continue;
1329}
1330
1331// tab ?
1332if( formattedtext[i] == '\t' )
1333cursor.x += ( font->chars[0]->width * 5 );
1334
1335// draw the character
1336if( font->chars[character])
1337blend(font->chars[character], gui.backbuffer, cursor);
1338
1339cursor.x += font->chars[character]->width;
1340
1341// check x pos and do newline
1342if ( cursor.x > bounds.x )
1343{
1344cursor.x = origin.x;
1345cursor.y += font->height;
1346}
1347
1348// check y pos and reset to origin.y
1349if ( cursor.y > bounds.y )
1350cursor.y = origin.y;
1351}
1352
1353// update cursor postition
1354gui.debug.cursor = cursor;
1355
1356free(formattedtext);
1357
1358return 0;
1359
1360}
1361return 1;
1362}
1363
1364int vprf(const char * fmt, va_list ap)
1365{
1366int i;
1367int character;
1368
1369char *formattedtext;
1370window_t *window = &gui.screen;
1371struct putc_info pi;
1372
1373position_torigin, cursor, bounds;
1374font_t *font = &font_console;
1375
1376if ((formattedtext = malloc(1024)) != NULL) {
1377// format the text
1378pi.str = formattedtext;
1379pi.last_str = 0;
1380prf(fmt, ap, sputc, &pi);
1381*pi.str = '\0';
1382
1383origin.x = MAX( window->cursor.x, window->hborder );
1384origin.y = MAX( window->cursor.y, window->vborder );
1385bounds.x = ( window->width - ( window->hborder * 2 ) );
1386bounds.y = ( window->height - ( window->vborder * 2 ) );
1387cursor = origin;
1388
1389for( i=0; i< strlen(formattedtext); i++ )
1390{
1391character = formattedtext[i];
1392character -= 32;
1393
1394// newline ?
1395if( formattedtext[i] == '\n' )
1396{
1397cursor.x = window->hborder;
1398cursor.y += font->height;
1399if ( cursor.y > bounds.y )
1400{
1401gui.redraw = true;
1402updateVRAM();
1403cursor.y = window->vborder;
1404}
1405window->cursor.y = cursor.y;
1406continue;
1407}
1408
1409// tab ?
1410if( formattedtext[i] == '\t' )
1411{
1412cursor.x = ( cursor.x / ( font->chars[0]->width * 8 ) + 1 ) * ( font->chars[0]->width * 8 );
1413continue;
1414}
1415cursor.x += font->chars[character]->width;
1416
1417// check x pos and do newline
1418if ( cursor.x > bounds.x )
1419{
1420cursor.x = origin.x;
1421cursor.y += font->height;
1422}
1423
1424// check y pos and reset to origin.y
1425if ( cursor.y > ( bounds.y + font->chars[0]->height) )
1426{
1427gui.redraw = true;
1428updateVRAM();
1429cursor.y = window->vborder;
1430}
1431// draw the character
1432if( font->chars[character])
1433blend(font->chars[character], gui.backbuffer, cursor);
1434}
1435// save cursor postition
1436window->cursor.x = cursor.x;
1437updateVRAM();
1438free(formattedtext);
1439return 0;
1440}
1441return 1;
1442}
1443
1444pixmap_t* charToPixmap(unsigned char ch, font_t *font) {
1445unsigned int cha = (unsigned int)ch - 32;
1446if (cha >= font->count)
1447// return ? if the font for the char doesn't exists
1448cha = '?' - 32;
1449
1450return font->chars[cha] ? font->chars[cha] : NULL;
1451}
1452
1453position_t drawChar(unsigned char ch, font_t *font, pixmap_t *blendInto, position_t p) {
1454pixmap_t* pm = charToPixmap(ch, font);
1455if (pm && ((p.x + pm->width) < blendInto->width))
1456{
1457blend(pm, blendInto, p);
1458return pos(p.x + pm->width, p.y);
1459}
1460else
1461return p;
1462}
1463
1464void drawStr(char *ch, font_t *font, pixmap_t *blendInto, position_t p)
1465{
1466int i=0;
1467position_t current_pos = pos(p.x, p.y);
1468
1469for (i=0; i < strlen(ch); i++)
1470{
1471// newline ?
1472if ( ch[i] == '\n' )
1473{
1474current_pos.x = p.x;
1475current_pos.y += font->height;
1476continue;
1477}
1478
1479// tab ?
1480if ( ch[i] == '\t' )
1481{
1482current_pos.x += TAB_PIXELS_WIDTH;
1483continue;
1484}
1485
1486current_pos = drawChar(ch[i], font, blendInto, current_pos);
1487}
1488}
1489
1490void drawStrCenteredAt(char *text, font_t *font, pixmap_t *blendInto, position_t p)
1491{
1492int i = 0;
1493int width = 0;
1494int max_width = 0;
1495int height = font->height;
1496
1497// calculate the width in pixels
1498for (i=0; i < strlen(text); i++) {
1499if (text[i] == '\n')
1500{
1501width = 0;
1502height += font->height;
1503}
1504else if (text[i] == '\t')
1505width += TAB_PIXELS_WIDTH;
1506else
1507{
1508pixmap_t* pm = charToPixmap(text[i], font);
1509if (pm)
1510width += pm->width;
1511}
1512if (width > max_width)
1513max_width = width;
1514}
1515
1516p.x = ( p.x - ( max_width / 2 ) );
1517p.y = ( p.y - ( height / 2 ) );
1518
1519drawStr(text, font, blendInto, p);
1520}
1521
1522int destroyFont(font_t *font)
1523{
1524 int i;
1525 for (i = 0; i < CHARACTERS_COUNT; i++)
1526 {
1527 if (font->chars[i])
1528 {
1529 if (font->chars[i]->pixels) free (font->chars[i]->pixels);
1530 free (font->chars[i]);
1531 font->chars[i] = 0;
1532 }
1533 }
1534 return 0;
1535}
1536
1537int initFont(font_t *font, image_t *data)
1538{
1539unsigned int x = 0, y = 0, x2 = 0, x3 = 0;
1540
1541int start = 0, end = 0, count = 0, space = 0;
1542
1543bool monospaced = false;
1544
1545font->height = data->image->height;
1546
1547for( x = 0; x < data->image->width && count < CHARACTERS_COUNT; x++)
1548{
1549start = end;
1550
1551// if the pixel is red we've reached the end of the char
1552if( pixel( data->image, x, 0 ).value == 0xFFFF0000)
1553{
1554end = x + 1;
1555
1556if( (font->chars[count] = malloc(sizeof(pixmap_t)) ) )
1557{
1558font->chars[count]->width = ( end - start) - 1;
1559font->chars[count]->height = font->height;
1560
1561if ( ( font->chars[count]->pixels = malloc( font->chars[count]->width * data->image->height * 4) ) )
1562{
1563space += ( font->chars[count]->width * data->image->height * 4 );
1564// we skip the first line because there are just the red pixels for the char width
1565for( y = 1; y< (font->height); y++)
1566{
1567for( x2 = start, x3 = 0; x2 < end; x2++, x3++)
1568{
1569pixel( font->chars[count], x3, y ) = pixel( data->image, x2, y );
1570}
1571}
1572
1573// check if font is monospaced
1574if( ( count > 0 ) && ( font->width != font->chars[count]->width ) )
1575monospaced = true;
1576
1577font->width = font->chars[count]->width;
1578
1579count++;
1580}
1581}
1582}
1583}
1584
1585for (x = count; x < CHARACTERS_COUNT; x++)
1586font->chars[x] = NULL;
1587
1588if(monospaced)
1589font->width = 0;
1590
1591font->count = count;
1592
1593return 0;
1594}
1595
1596void colorFont(font_t *font, uint32_t color)
1597{
1598if( !color )
1599return;
1600
1601int x, y, width, height;
1602int count = 0;
1603pixel_t *buff;
1604
1605while( font->chars[count++] )
1606{
1607width = font->chars[count-1]->width;
1608height = font->chars[count-1]->height;
1609for( y = 0; y < height; y++ )
1610{
1611for( x = 0; x < width; x++ )
1612{
1613buff = &(pixel( font->chars[count-1], x, y ));
1614if( buff->ch.a )
1615{
1616buff->ch.r = (color & 0xFFFF0000) >> 16;
1617buff->ch.g = (color & 0xFF00FF00) >> 8;
1618buff->ch.b = (color & 0xFF0000FF);
1619}
1620}
1621}
1622}
1623}
1624
1625void makeRoundedCorners(pixmap_t *p)
1626{
1627int x,y;
1628int width=p->width-1;
1629int height=p->height-1;
1630
1631// 10px rounded corner alpha values
1632uint8_t roundedCorner[10][10] =
1633{
1634{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0xC0, 0xFF},
1635{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF},
1636{ 0x00, 0x00, 0x00, 0x40, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
1637{ 0x00, 0x00, 0x40, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
1638{ 0x00, 0x40, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
1639{ 0x00, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
1640{ 0x40, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
1641{ 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
1642{ 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
1643{ 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
1644};
1645
1646uint8_t alpha=0;
1647
1648for( y=0; y<10; y++)
1649{
1650for( x=0; x<10; x++)
1651{
1652// skip if the pixel should be visible
1653if(roundedCorner[y][x] != 0xFF)
1654{
1655alpha = ( roundedCorner[y][x] ? (uint8_t) (roundedCorner[y][x] * pixel(p, x, y).ch.a) / 255 : 0 );
1656// Upper left corner
1657pixel(p, x, y).ch.a = alpha;
1658
1659// upper right corner
1660pixel(p, width-x,y).ch.a = alpha;
1661
1662// lower left corner
1663pixel(p, x, height-y).ch.a = alpha;
1664
1665// lower right corner
1666pixel(p, width-x, height-y).ch.a = alpha;
1667}
1668}
1669}
1670}
1671
1672void showInfoBox(char *title, char *text_orig)
1673{
1674char* text;
1675int i, key, lines, visiblelines;
1676
1677int currentline=0;
1678int cnt=0;
1679int offset=0;
1680
1681if( !title || !text_orig )
1682return;
1683
1684// Create a copy so that we don't mangle the original
1685text = malloc(strlen(text_orig) + 1);
1686strcpy(text, text_orig);
1687
1688
1689position_t pos_title = pos ( gui.infobox.vborder, gui.infobox.vborder );
1690
1691// calculate number of lines in the title
1692for ( i = 0, lines = 1; i<strlen(title); i++ )
1693if( title[i] == '\n')
1694lines++;
1695
1696// y position of text is lines in title * height of font
1697position_t pos_text = pos( pos_title.x , pos_title.y + ( font_console.height * lines ));
1698
1699// calculate number of lines in the text
1700for ( i=0, lines = 1; i<strlen(text); i++ )
1701if( text[i] == '\n')
1702lines++;
1703
1704// if text ends with \n strip off
1705if( text[i] == '\n' || text[i] == '\0')
1706lines--;
1707
1708visiblelines = ( ( gui.infobox.height - ( gui.infobox.vborder * 2 ) ) / font_console.height ) - 1;
1709
1710// lets display the text and allow scroll thru using up down / arrows
1711while(1)
1712{
1713// move to current line in text
1714for( offset = 0, i = 0; offset < strlen(text); offset++ )
1715{
1716if( currentline == i)
1717break;
1718if( text[offset] =='\n')
1719i++;
1720}
1721
1722// find last visible line in text and place \0
1723for( i = offset, cnt = 0; i < strlen(text); i++)
1724{
1725if(text[i]=='\n')
1726cnt++;
1727if ( cnt == visiblelines )
1728{
1729text[i]='\0';
1730break;
1731}
1732}
1733
1734fillPixmapWithColor( gui.infobox.pixmap, gui.infobox.bgcolor);
1735
1736makeRoundedCorners( gui.infobox.pixmap);
1737
1738// print the title if present
1739if( title )
1740drawStr(title, &font_console, gui.infobox.pixmap, pos_title);
1741
1742// print the text
1743drawStr( text + offset, &font_console, gui.infobox.pixmap, pos_text);
1744
1745// restore \n in text
1746if ( cnt == visiblelines )
1747text[i] = '\n';
1748
1749position_t pos_indicator = pos( gui.infobox.width - ( images[iTextScrollPrev].image->width - ( gui.infobox.vborder / 2) ), pos_text.y );
1750
1751// draw prev indicator
1752if(offset)
1753{
1754blend( images[iTextScrollPrev].image, gui.infobox.pixmap, centeredAt( images[iTextScrollPrev].image, pos_indicator ));
1755}
1756
1757// draw next indicator
1758if( lines > ( currentline + visiblelines ) )
1759{
1760pos_indicator.y = ( gui.infobox.height - ( ( images[iTextScrollNext].image->width + gui.infobox.vborder ) / 2 ) );
1761blend( images[iTextScrollNext].image, gui.infobox.pixmap, centeredAt( images[iTextScrollNext].image, pos_indicator ) );
1762}
1763
1764gui.bootprompt.draw = false;
1765gui.infobox.draw = true;
1766gui.redraw = true;
1767
1768updateVRAM();
1769
1770key = getchar();
1771
1772if( key == KEY_UP )
1773if( currentline > 0 )
1774currentline--;
1775
1776if( key == KEY_DOWN )
1777if( lines > ( currentline + visiblelines ) )
1778currentline++;
1779
1780if( key == KEY_ESC || key == 'q' || key == 'Q')
1781{
1782gui.infobox.draw = false;
1783gui.redraw = true;
1784updateVRAM();
1785break;
1786}
1787
1788if(key == ' ') // spacebar = next page
1789{
1790if( lines > ( currentline + visiblelines ) )
1791currentline += visiblelines;
1792
1793if(lines < (currentline + visiblelines))
1794currentline = lines - visiblelines;
1795}
1796}
1797}
1798
1799void animateProgressBar()
1800{
1801int y;
1802
1803if( time18() > lasttime)
1804{
1805lasttime = time18();
1806
1807pixmap_t *buffBar = images[iProgressBar].image;
1808
1809uint32_t buff = buffBar->pixels[0].value;
1810
1811memcpy( buffBar->pixels, buffBar->pixels + 1, ( (buffBar->width*buffBar->height) - 1 ) * 4 );
1812
1813for( y = buffBar->height - 1; y > 0; y--)
1814pixel(buffBar, buffBar->width - 1, y) = pixel(buffBar, buffBar->width - 1, y - 1);
1815
1816pixel(buffBar, buffBar->width-1, 0).value = buff;
1817}
1818}
1819
1820void drawProgressBar(pixmap_t *blendInto, uint16_t width, position_t p, uint8_t progress)
1821{
1822if(progress>100)
1823return;
1824
1825p.x = ( p.x - ( width / 2 ) );
1826
1827int todraw = (width * progress) / 100;
1828
1829pixmap_t *buff = images[iProgressBar].image;
1830pixmap_t *buffBG = images[iProgressBarBackground].image;
1831if(!buff || !buffBG)
1832return;
1833
1834pixmap_t progressbar;
1835progressbar.pixels=malloc(width * 4 * buff->height);
1836if(!progressbar.pixels)
1837return;
1838
1839progressbar.width = width;
1840progressbar.height = buff->height;
1841
1842int x=0,x2=0,y=0;
1843
1844for(y=0; y<buff->height; y++)
1845{
1846for(x=0; x<todraw; x++, x2++)
1847{
1848if(x2 == (buff->width-1)) x2=0;
1849pixel(&progressbar, x,y).value = pixel(buff, x2,y).value;
1850}
1851x2=0;
1852}
1853
1854for(y=0; y<buff->height; y++)
1855{
1856for(x=todraw, x2 = 0; x < width - 1; x++, x2++)
1857{
1858if(x2 == (buffBG->width -2 )) x2 = 0;
1859pixel(&progressbar, x,y).value = pixel(buffBG, x2,y).value;
1860}
1861if(progress < 100)
1862pixel(&progressbar, width - 1, y).value = pixel(buffBG, buffBG->width - 1, y).value;
1863if(progress == 0)
1864pixel(&progressbar, 0, y).value = pixel(buffBG, buffBG->width - 1, y).value;
1865x2=0;
1866}
1867
1868blend(&progressbar, blendInto, p);
1869animateProgressBar();
1870free(progressbar.pixels);
1871}
1872
1873void drawInfoMenuItems()
1874{
1875int i,n;
1876
1877position_t position;
1878
1879pixmap_t *selection = images[iMenuSelection].image;
1880
1881pixmap_t *pbuff;
1882
1883fillPixmapWithColor(gui.menu.pixmap, gui.menu.bgcolor);
1884
1885makeRoundedCorners(gui.menu.pixmap);
1886
1887uint8_t offset = infoMenuNativeBoot ? 0 : infoMenuItemsCount - 1;
1888
1889position = pos(0,0);
1890
1891for ( i = 0, n = iMenuBoot; i < infoMenuItemsCount; i++, n++)
1892{
1893if (i == infoMenuSelection)
1894{
1895blend(selection, gui.menu.pixmap, position);
1896}
1897
1898pbuff = images[n].image;
1899if (offset && i >= INFOMENU_NATIVEBOOT_START && i <= INFOMENU_NATIVEBOOT_END)
1900{
1901blend( images[n + (iMenuHelp - iMenuBoot)].image , gui.menu.pixmap,
1902pos((position.x + (gui.menu.hborder / 2)), position.y + ((selection->height - pbuff->height) / 2)));
1903}
1904else
1905{
1906blend( pbuff, gui.menu.pixmap,
1907pos((position.x + (gui.menu.hborder / 2)), position.y + ((selection->height - pbuff->height) / 2)));
1908}
1909
1910drawStr(infoMenuItems[i].text, &font_console, gui.menu.pixmap,
1911pos(position.x + (pbuff->width + gui.menu.hborder),
1912position.y + ((selection->height - font_console.height) / 2)));
1913position.y += images[iMenuSelection].image->height;
1914
1915}
1916
1917gui.redraw = true;
1918}
1919
1920int drawInfoMenu()
1921{
1922drawInfoMenuItems();
1923
1924gui.menu.draw = true;
1925
1926updateVRAM();
1927
1928return 1;
1929}
1930
1931int updateInfoMenu(int key)
1932{
1933switch (key)
1934{
1935
1936case KEY_UP:// up arrow
1937if (infoMenuSelection > 0)
1938{
1939if(!infoMenuNativeBoot && infoMenuSelection == INFOMENU_NATIVEBOOT_END + 1)
1940{
1941infoMenuSelection -= 4;
1942}
1943else
1944{
1945infoMenuSelection--;
1946}
1947drawInfoMenuItems();
1948updateVRAM();
1949
1950}
1951else
1952{
1953
1954gui.menu.draw = false;
1955gui.redraw = true;
1956
1957updateVRAM();
1958
1959return CLOSE_INFO_MENU;
1960}
1961break;
1962
1963case KEY_DOWN:// down arrow
1964if (infoMenuSelection < infoMenuItemsCount - 1)
1965{
1966if(!infoMenuNativeBoot && infoMenuSelection == INFOMENU_NATIVEBOOT_START - 1)
1967infoMenuSelection += 4;
1968else
1969infoMenuSelection++;
1970drawInfoMenuItems();
1971updateVRAM();
1972}
1973break;
1974
1975case KEY_ENTER:
1976key = 0;
1977if( infoMenuSelection == MENU_SHOW_MEMORY_INFO )
1978showInfoBox( "Memory Info. Press q to quit.\n", getMemoryInfoString());
1979
1980else if( infoMenuSelection == MENU_SHOW_VIDEO_INFO )
1981showInfoBox( getVBEInfoString(), getVBEModeInfoString() );
1982
1983else if( infoMenuSelection == MENU_SHOW_HELP )
1984showHelp();
1985
1986else
1987{
1988int buff = infoMenuSelection;
1989infoMenuSelection = 0;
1990return buff;
1991}
1992break;
1993}
1994return DO_NOT_BOOT;
1995}
1996
1997uint16_t bootImageWidth = 0;
1998uint16_t bootImageHeight = 0;
1999uint8_t *bootImageData = NULL;
2000static bool usePngImage = true;
2001
2002//==========================================================================
2003// loadBootGraphics
2004static void loadBootGraphics(void)
2005{
2006if (bootImageData != NULL) {
2007return;
2008}
2009
2010char dirspec[256];
2011
2012if ((strlen(theme_name) + 24) > sizeof(dirspec)) {
2013usePngImage = false;
2014return;
2015}
2016sprintf(dirspec, "/Extra/Themes/%s/boot.png", theme_name);
2017if (loadPngImage(dirspec, &bootImageWidth, &bootImageHeight, &bootImageData) != 0) {
2018#ifdef CONFIG_EMBED_THEME
2019 if ((loadEmbeddedPngImage(__boot_png, __boot_png_len, &bootImageWidth, &bootImageHeight, &bootImageData)) != 0)
2020#endif
2021usePngImage = false;
2022}
2023}
2024
2025//==========================================================================
2026// drawBootGraphics
2027void drawBootGraphics(void)
2028{
2029int pos;
2030int length;
2031const char *dummyVal;
2032int oldScreenWidth, oldScreenHeight;
2033bool legacy_logo;
2034uint16_t x, y;
2035
2036if (getBoolForKey("Legacy Logo", &legacy_logo, &bootInfo->chameleonConfig) && legacy_logo) {
2037usePngImage = false;
2038} else if (bootImageData == NULL) {
2039loadBootGraphics();
2040}
2041
2042// parse screen size parameters
2043if (getIntForKey("boot_width", &pos, &bootInfo->themeConfig) && pos > 0) {
2044screen_params[0] = pos;
2045} else {
2046screen_params[0] = DEFAULT_SCREEN_WIDTH;
2047}
2048if (getIntForKey("boot_height", &pos, &bootInfo->themeConfig) && pos > 0) {
2049screen_params[1] = pos;
2050} else {
2051screen_params[1] = DEFAULT_SCREEN_HEIGHT;
2052}
2053
2054 // Save current screen resolution.
2055oldScreenWidth = gui.screen.width;
2056oldScreenHeight = gui.screen.height;
2057
2058gui.screen.width = screen_params[0];
2059gui.screen.height = screen_params[1];
2060
2061// find best matching vesa mode for our requested width & height
2062getGraphicModeParams(screen_params);
2063
2064 // Set graphics mode if the booter was in text mode or the screen resolution has changed.
2065if (bootArgs->Video.v_display == VGA_TEXT_MODE
2066|| (screen_params[0] != oldScreenWidth && screen_params[1] != oldScreenHeight) )
2067{
2068setVideoMode(GRAPHICS_MODE, 0);
2069}
2070
2071if (getValueForKey("-checkers", &dummyVal, &length, &bootInfo->chameleonConfig)) {
2072drawCheckerBoard();
2073} else {
2074// Fill the background to 75% grey (same as BootX).
2075drawColorRectangle(0, 0, screen_params[0], screen_params[1], 0x01);
2076}
2077if ((bootImageData) && (usePngImage)) {
2078x = (screen_params[0] - MIN(bootImageWidth, screen_params[0])) / 2;
2079y = (screen_params[1] - MIN(bootImageHeight, screen_params[1])) / 2;
2080
2081// Draw the image in the center of the display.
2082blendImage(x, y, bootImageWidth, bootImageHeight, bootImageData);
2083} else {
2084uint8_t *appleBootPict;
2085bootImageData = NULL;
2086bootImageWidth = kAppleBootWidth;
2087bootImageHeight = kAppleBootHeight;
2088
2089// Prepare the data for the default Apple boot image.
2090appleBootPict = (uint8_t *) decodeRLE(gAppleBootPictRLE, kAppleBootRLEBlocks, bootImageWidth * bootImageHeight);
2091if (appleBootPict) {
2092convertImage(bootImageWidth, bootImageHeight, appleBootPict, &bootImageData);
2093if (bootImageData) {
2094x = (screen_params[0] - MIN(kAppleBootWidth, screen_params[0])) / 2;
2095y = (screen_params[1] - MIN(kAppleBootHeight, screen_params[1])) / 2;
2096drawDataRectangle(x, y, kAppleBootWidth, kAppleBootHeight, bootImageData);
2097free(bootImageData);
2098}
2099free(appleBootPict);
2100}
2101}
2102}
2103

Archive Download this file

Revision: 2381