Added missing property.
[tangerine.git] / rom / bootmenu / menu.c
blob641879e67b7a627e33ea562e44683cf9d09f1f44
1 #include <proto/bootloader.h>
2 #include <proto/exec.h>
3 #include <proto/graphics.h>
4 #include <proto/intuition.h>
5 #include <devices/keyboard.h>
6 #include <devices/rawkeycodes.h>
7 #include <devices/timer.h>
8 #include <exec/memory.h>
9 #include <graphics/gfxbase.h>
10 #include <libraries/bootmenu.h>
11 #include <aros/bootloader.h>
12 #include <aros/symbolsets.h>
13 #include <string.h>
14 #include "devs_private.h"
15 #define DEBUG 0
16 #include <aros/debug.h>
18 #include "bootmenu_intern.h"
20 #include LC_LIBDEFS_FILE
22 #define BUFSIZE 100
24 #if 0
25 struct GfxBase *GfxBase;
26 struct RastPort rp;
27 struct ViewPort vp;
29 static const ULONG coltab[] = {
30 (16L << 16) + 0, /* 16 colors, loaded at index 0 */
32 /* X11 color names */
33 0xB3B3B3B3, 0xB3B3B3B3, 0xB3B3B3B3, /* Grey70 */
34 0x00000000, 0x00000000, 0x00000000, /* Black */
35 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, /* White */
36 0x66666666, 0x88888888, 0xBBBBBBBB, /* AMIGA Blue */
38 0x00000000, 0x00000000, 0xFFFFFFFF, /* Blue */
39 0x00000000, 0xFFFFFFFF, 0x00000000, /* Green */
40 0xFFFFFFFF, 0x00000000, 0x00000000, /* Red */
41 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, /* Cyan */
43 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, /* Magenta */
44 0xEEEEEEEE, 0x82828282, 0xEEEEEEEE, /* Violet */
45 0xA5A5A5A5, 0x2A2A2A2A, 0x2A2A2A2A, /* Brown */
46 0xFFFFFFFF, 0xE4E4E4E4, 0xC4C4C4C4, /* Bisque */
48 0xE6E6E6E6, 0xE6E6E6E6, 0xFAFAFAFA, /* Lavender */
49 0x00000000, 0x00000000, 0x80808080, /* Navy */
50 0xF0F0F0F0, 0xE6E6E6E6, 0x8C8C8C8C, /* Khaki */
51 0xA0A0A0A0, 0x52525252, 0x2D2D2D2D, /* Sienna */
52 0L /* Termination */
55 static ULONG pointercoltab[] = {
57 0xE0E0E0E0, 0x40404040, 0x40404040,
58 0x00000000, 0x00000000, 0x00000000,
59 0xE0E0E0E0, 0xE0E0E0E0, 0xC0C0C0C0,
63 BOOL initScreen(STRPTR gfxhiddname, struct BootMenuBase *bootmenubase) {
64 struct TagItem modetags[] =
66 {BIDTAG_Depth, 2},
67 {BIDTAG_DesiredWidth, 640},
68 {BIDTAG_DesiredHeight, 200},
69 {TAG_DONE, 0UL}
71 ULONG modeid, depth;
73 GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 37);
74 if (GfxBase)
76 if (LateGfxInit(gfxhiddname))
78 modeid = BestModeIDA(modetags);
79 if (modeid != INVALID_ID)
81 InitRastPort(&rp);
82 InitVPort(&vp);
83 rp.BitMap = AllocScreenBitMap(modeid);
84 if (rp.BitMap)
86 vp.RasInfo = AllocMem(sizeof(struct RasInfo), MEMF_ANY | MEMF_CLEAR);
87 if (vp.RasInfo)
89 vp.RasInfo->BitMap = rp.BitMap;
90 vp.ColorMap = GetColorMap(4);
91 vp.ColorMap->VPModeID = modeid;
92 if (AttachPalExtra(vp.ColorMap, &vp) == 0)
94 LoadRGB32(&vp, (ULONG *)coltab);
95 depth = GetBitMapAttr(rp.BitMap, BMA_DEPTH);
96 if (depth > 4)
97 pointercoltab[0] = (3L << 16) + 17;
98 else
99 pointercoltab[0] = (3L << 16) + (1 << depth) - 3;
100 LoadRGB32(&vp, pointercoltab);
101 rp.BitMap->Flags |= BMF_AROS_HIDD;
102 SetFont(&rp, GfxBase->DefaultFont);
103 SetFrontBitMap(rp.BitMap, TRUE);
104 Forbid();
105 rp.Font->tf_Accessors++;
106 Permit();
107 SetAPen(&rp, 1);
108 Move(&rp, 100, 100);
109 Text(&rp, "Sucker", 6);
110 kprintf("done\n");
111 return TRUE;
113 FreeMem(vp.RasInfo, sizeof(struct RasInfo));
115 FreeBitMap(rp.BitMap);
119 CloseLibrary((struct Library *)GfxBase);
121 kprintf("no screen!\n");
122 return FALSE;
124 #else
126 /*****************
127 ** init_gfx() **
128 *****************/
130 static BOOL init_gfx(STRPTR gfxclassname, struct BootMenuBase *bootmenubase)
132 BOOL success = FALSE;
133 EnterFunc(bug("init_gfx(hiddbase=%s)\n", gfxclassname));
135 /* Call private gfx.library call to init the HIDD.
136 Gfx library is responsable for closing the HIDD
137 library (although it will probably not be neccesary).
140 D(bug("calling private gfx LateGfxInit()\n"));
141 if (LateGfxInit(gfxclassname))
143 D(bug("success\n"));
144 if (IntuitionBase)
146 if (LateIntuiInit(NULL))
148 success = TRUE;
152 ReturnBool ("init_gfxhidd", success);
156 static BOOL init_device( STRPTR hiddclassname, STRPTR devicename, struct BootMenuBase *bootmenubase)
158 BOOL success = FALSE;
159 struct MsgPort *mp;
161 EnterFunc(bug("init_device(classname=%s)\n", hiddclassname));
163 mp = CreateMsgPort();
164 if (mp)
166 struct IORequest *io;
167 io = CreateIORequest(mp, sizeof ( struct IOStdReq));
168 if (io)
170 if (0 == OpenDevice(devicename, 0, io, 0))
172 #define ioStd(x) ((struct IOStdReq *)x)
173 ioStd(io)->io_Command = CMD_HIDDINIT;
174 ioStd(io)->io_Data = hiddclassname;
175 ioStd(io)->io_Length = strlen(hiddclassname);
177 /* Let the device init the HIDD */
178 DoIO(io);
179 if (0 == io->io_Error)
181 success = TRUE;
183 CloseDevice(io);
185 DeleteIORequest(io);
187 DeleteMsgPort(mp);
189 ReturnBool("init_device", success);
192 BOOL initHidds(struct BootConfig *bootcfg, struct BootMenuBase *bootmenubase) {
194 OpenLibrary(bootcfg->defaultgfx.libname, 0);
195 init_gfx(bootcfg->defaultgfx.hiddname, bootmenubase);
196 OpenLibrary(bootcfg->defaultmouse.libname, 0);
197 init_device(bootcfg->defaultmouse.hiddname, "gameport.device", bootmenubase);
198 return TRUE;
201 struct Gadget *createGadgets(struct BootMenuBase_intern *bootmenubase) {
202 struct Gadget *first;
203 struct ButtonGadget *last;
205 last = bootmenubase->maingadgets.boot = createButton(16, 190, 280, 14, (struct Gadget *)&first, "Boot", BUTTON_BOOT, bootmenubase);
206 if (last == NULL)
207 return NULL;
208 last = bootmenubase->maingadgets.bootnss = createButton(344, 190, 280, 14, last->gadget, "Boot With No Startup-Sequence", BUTTON_BOOT_WNSS, bootmenubase);
209 if (last == NULL)
210 return NULL;
211 last = bootmenubase->maingadgets.bootopt = createButton(180, 63, 280, 14, last->gadget, "Boot Options...", BUTTON_BOOT_OPTIONS, bootmenubase);
212 if (last == NULL)
213 return NULL;
214 last = bootmenubase->maingadgets.displayopt = createButton(180, 84, 280, 14, last->gadget, "Display Options...", BUTTON_DISPLAY_OPTIONS, bootmenubase);
215 if (last == NULL)
216 return NULL;
217 last = bootmenubase->maingadgets.expboarddiag = createButton(180, 105, 280, 14, last->gadget, "Expansion Board Diagnostic...", BUTTON_EXPBOARDDIAG, bootmenubase);
218 if (last == NULL)
219 return NULL;
220 return first;
223 void freeGadgets(struct BootMenuBase_intern *bootmenubase) {
225 if (bootmenubase->maingadgets.boot != NULL)
226 freeButtonGadget(bootmenubase->maingadgets.boot, bootmenubase);
227 if (bootmenubase->maingadgets.bootnss != NULL);
228 freeButtonGadget(bootmenubase->maingadgets.bootnss, bootmenubase);
229 if (bootmenubase->maingadgets.bootopt != NULL)
230 freeButtonGadget(bootmenubase->maingadgets.bootopt, bootmenubase);
231 if (bootmenubase->maingadgets.displayopt != NULL)
232 freeButtonGadget(bootmenubase->maingadgets.displayopt, bootmenubase);
233 if (bootmenubase->maingadgets.expboarddiag != NULL)
234 freeButtonGadget(bootmenubase->maingadgets.expboarddiag, bootmenubase);
237 void msgLoop(struct BootMenuBase *bootmenubase, struct Window *win, struct BootConfig *bcfg) {
238 BOOL in=TRUE;
239 struct IntuiMessage *msg;
240 struct Gadget *g;
244 WaitPort(win->UserPort);
245 while ((msg=(struct IntuiMessage *)GetMsg(win->UserPort)))
247 if (msg->Class == IDCMP_GADGETUP)
249 g = msg->IAddress;
250 switch (g->GadgetID)
252 case BUTTON_BOOT:
253 bcfg->startup_sequence = TRUE;
254 in = FALSE;
255 break;
256 case BUTTON_BOOT_WNSS:
257 bcfg->startup_sequence = FALSE;
258 in = FALSE;
259 break;
262 ReplyMsg(&msg->ExecMessage);
264 } while (in);
265 while ((msg=(struct IntuiMessage *)GetMsg(win->UserPort)))
266 ReplyMsg(&msg->ExecMessage);
269 BOOL initScreen(struct BootMenuBase_intern *bootmenubase, struct BootConfig *bcfg) {
270 UWORD pens[] = {~0};
271 struct TagItem scrtags[] =
273 {SA_Width, 640},
274 {SA_Height, 256},
275 {SA_Depth, 4},
276 {SA_Pens, (IPTR)pens},
277 {TAG_DONE, 0UL}
279 struct TagItem wintags[] =
281 {WA_Left, 0}, /* 0 */
282 {WA_Top, 0}, /* 1 */
283 {WA_Width, 640}, /* 2 */
284 {WA_Height, 256}, /* 3 */
285 {WA_CustomScreen, 0}, /* 4 */
286 {WA_Gadgets, NULL}, /* 5 */
287 {WA_IDCMP, IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE | IDCMP_VANILLAKEY | IDCMP_GADGETUP | IDCMP_GADGETDOWN},
288 {WA_Borderless, TRUE},
289 {WA_RMBTrap, TRUE},
290 {TAG_DONE, 0UL}
292 struct Gadget *first = NULL;
294 bootmenubase->scr = OpenScreenTagList(NULL, scrtags);
295 if (bootmenubase->scr != NULL)
297 first = createGadgets(bootmenubase);
298 if (first != NULL)
300 wintags[2].ti_Data = bootmenubase->scr->Width;
301 wintags[3].ti_Data = bootmenubase->scr->Height;
302 wintags[4].ti_Data = (IPTR)bootmenubase->scr;
303 wintags[5].ti_Data = (IPTR)first;
304 bootmenubase->win = OpenWindowTagList(NULL, wintags);
305 if (bootmenubase->win != NULL)
307 SetAPen(bootmenubase->win->RPort, 2);
308 Move(bootmenubase->win->RPort, 215, 20);
309 Text(bootmenubase->win->RPort, "AROS Early Startup Control", 26);
310 SetAPen(bootmenubase->win->RPort, 1);
311 Move(bootmenubase->win->RPort, 225, 40);
312 Text(bootmenubase->win->RPort, "(what is PAL and NTSC?)", 23);
313 msgLoop(bootmenubase, bootmenubase->win, bcfg);
314 return TRUE;
316 else
317 Alert(AT_DeadEnd | AN_OpenWindow);
318 CloseWindow(bootmenubase->win);
319 freeGadgets(bootmenubase);
321 else
322 Alert(AT_DeadEnd | AN_BadGadget);
323 CloseScreen(bootmenubase->scr);
325 else
326 Alert(AT_DeadEnd | AN_OpenScreen);
327 return FALSE;
330 void delay(struct BootMenuBase *bootmenubase, LONG secs, LONG micro) {
331 struct MsgPort *mp;
333 mp = CreateMsgPort();
334 if (mp)
336 struct timerequest *tr;
337 tr = (struct timerequest *)CreateIORequest(mp, sizeof(struct timerequest));
338 if (tr)
340 if (OpenDevice("timer.device", UNIT_VBLANK, (struct IORequest *)tr, 0) == 0)
342 #define ioStd(x) ((struct IOStdReq *)x)
343 ioStd(tr)->io_Command = TR_ADDREQUEST;
344 tr->tr_time.tv_secs = secs;
345 tr->tr_time.tv_micro = micro;
346 DoIO((struct IORequest *)tr);
347 CloseDevice((struct IORequest *)tr);
349 DeleteIORequest((struct IORequest *)tr);
351 DeleteMsgPort(mp);
355 BOOL buttonsPressed(struct BootMenuBase *bootmenubase, struct DefaultHidd *kbd) {
356 BOOL success = FALSE;
357 struct MsgPort *mp;
358 UBYTE matrix[16];
360 if (OpenLibrary(kbd->libname, 0) != NULL)
362 if (init_device(kbd->hiddname, "keyboard.device", bootmenubase))
364 delay(bootmenubase, 1, 0);
365 mp = CreateMsgPort();
366 if (mp)
368 struct IORequest *io;
369 io = CreateIORequest(mp, sizeof ( struct IOStdReq));
370 if (io)
372 if (0 == OpenDevice("keyboard.device", 0, io, 0))
374 #define ioStd(x) ((struct IOStdReq *)x)
375 ioStd(io)->io_Command = KBD_READMATRIX;
376 ioStd(io)->io_Data = matrix;
377 ioStd(io)->io_Length = 16;
378 DoIO(io);
379 if (0 == io->io_Error)
381 if (matrix[RAWKEY_SPACE/8] & (1<<(RAWKEY_SPACE%8)))
382 success = TRUE;
384 CloseDevice(io);
386 DeleteIORequest(io);
388 DeleteMsgPort(mp);
392 return success;
395 #endif
398 static int CheckAndDisplay(LIBBASETYPEPTR LIBBASE)
400 struct BootLoaderBase *BootLoaderBase;
401 struct VesaInfo *vi;
402 static struct BootConfig bootcfg =
404 &bootcfg,
405 {"vgah.hidd", "hidd.gfx.vga"},
406 {"kbd.hidd", "hidd.kbd.hw"},
407 {"mouse.hidd", "hidd.bus.mouse"},
408 NULL,
409 TRUE
412 LIBBASE->bcfg = bootcfg;
414 /* init keyboard + check */
415 if (buttonsPressed(LIBBASE, &LIBBASE->bcfg.defaultkbd))
417 BootLoaderBase = OpenResource("bootloader.resource");
418 if (BootLoaderBase) {
419 vi = (struct VesaInfo *)GetBootInfo(BL_Video);
420 if (vi) {
421 if (vi->ModeNumber != 3) {
422 strcpy(LIBBASE->bcfg.defaultgfx.libname, "vesagfx.hidd");
423 strcpy(LIBBASE->bcfg.defaultgfx.hiddname, "hidd.gfx.vesa");
427 kprintf("Entering Boot Menu ...\n");
428 /* init mouse + gfx */
429 if (initHidds(&LIBBASE->bcfg, LIBBASE))
431 initScreen(LIBBASE, &LIBBASE->bcfg);
434 return TRUE;
437 ADD2INITLIB(CheckAndDisplay, 0)