2 #include <aros/debug.h>
4 #include <proto/bootloader.h>
5 #include <proto/exec.h>
6 #include <proto/graphics.h>
7 #include <proto/intuition.h>
8 #include <devices/keyboard.h>
9 #include <devices/rawkeycodes.h>
10 #include <devices/timer.h>
11 #include <exec/memory.h>
12 #include <graphics/gfxbase.h>
13 #include <libraries/bootmenu.h>
14 #include <libraries/expansionbase.h>
15 #include <aros/bootloader.h>
16 #include <aros/symbolsets.h>
18 #include "devs_private.h"
20 #include "bootmenu_intern.h"
22 #include LC_LIBDEFS_FILE
28 static BOOL
init_gfx(STRPTR gfxclassname
, struct BootMenuBase
*BootMenuBase
)
31 D(bug("[BootMenu] init_gfx(hiddbase='%s')\n", gfxclassname
));
33 /* Call private gfx.library call to init the HIDD.
34 Gfx library is responsable for closing the HIDD
35 library (although it will probably not be neccesary).
38 D(bug("[BootMenu] init_gfx: calling private LateGfxInit() ..\n"));
39 if (LateGfxInit(gfxclassname
))
41 D(bug("[BootMenu] init_gfx: calling private LateGfxInit Succeeded\n"));
42 if (LateIntuiInit(NULL
))
44 D(bug("[BootMenu] init_gfx: calling private LateIntuiInit Succeeded\n"));
49 D(bug("[BootMenu] init_gfx: calling private LateIntuiInit Failed!\n"));
54 D(bug("[BootMenu] init_gfx: calling private LateGfxInit Failed!\n"));
56 ReturnBool ("init_gfxhidd", success
);
59 static BOOL
init_device( STRPTR hiddclassname
, STRPTR devicename
, struct BootMenuBase
*BootMenuBase
)
62 struct MsgPort
*mp
= NULL
;
64 D(bug("[BootMenu] init_device(classname='%s', devicename='%s')\n", hiddclassname
, devicename
));
66 if ((mp
= CreateMsgPort()) != NULL
)
68 struct IORequest
*io
= NULL
;
69 if ((io
= CreateIORequest(mp
, sizeof ( struct IOStdReq
))) != NULL
)
71 if (0 == OpenDevice(devicename
, 0, io
, 0))
73 #define ioStd(x) ((struct IOStdReq *)x)
74 ioStd(io
)->io_Command
= CMD_HIDDINIT
;
75 ioStd(io
)->io_Data
= hiddclassname
;
76 ioStd(io
)->io_Length
= strlen(hiddclassname
);
78 /* Let the device init the HIDD */
80 if (0 == io
->io_Error
)
90 ReturnBool("init_device", success
);
93 static BOOL
initHidds(struct BootConfig
*bootcfg
, struct BootMenuBase
*BootMenuBase
)
95 D(bug("[BootMenu] initHidds()\n"));
97 if ((OpenLibrary(bootcfg
->defaultgfx
.libname
, 0)) != NULL
)
99 if ((init_gfx(bootcfg
->defaultgfx
.hiddname
, BootMenuBase
)) == TRUE
)
102 if (!bootcfg
->defaultmouse
.hiddname
[0])
107 if ((OpenLibrary(bootcfg
->defaultmouse
.libname
, 0)) != NULL
)
109 if ((init_device(bootcfg
->defaultmouse
.hiddname
, "gameport.device", BootMenuBase
)) == TRUE
)
112 D(bug("[BootMenu] initHidds: Hidds initialised\n"));
122 static struct Gadget
*createGadgets(struct BootMenuBase_intern
*BootMenuBase
)
124 #warning "TOD: This is very unclean! free-up resources if we fail!"
126 /* Create Option Gadgets */
127 BootMenuBase
->bm_MainGadgets
.bootopt
= createButton(
129 NULL
, "Boot Options...",
130 BUTTON_BOOT_OPTIONS
, BootMenuBase
);
131 if (BootMenuBase
->bm_MainGadgets
.bootopt
== NULL
)
134 BootMenuBase
->bm_MainGadgets
.displayopt
= createButton(
136 BootMenuBase
->bm_MainGadgets
.bootopt
->gadget
, "Display Options...",
137 BUTTON_DISPLAY_OPTIONS
, BootMenuBase
);
138 if (BootMenuBase
->bm_MainGadgets
.displayopt
== NULL
)
141 BootMenuBase
->bm_MainGadgets
.expboarddiag
= createButton(
143 BootMenuBase
->bm_MainGadgets
.displayopt
->gadget
, "Expansion Board Diagnostic...",
144 BUTTON_EXPBOARDDIAG
, BootMenuBase
);
145 if (BootMenuBase
->bm_MainGadgets
.expboarddiag
== NULL
)
148 /* Create BOOT Gadgets */
149 BootMenuBase
->bm_MainGadgets
.boot
= createButton(
151 BootMenuBase
->bm_MainGadgets
.expboarddiag
->gadget
, "Boot",
152 BUTTON_BOOT
, BootMenuBase
);
153 if (BootMenuBase
->bm_MainGadgets
.boot
== NULL
)
156 BootMenuBase
->bm_MainGadgets
.bootnss
= createButton(
158 BootMenuBase
->bm_MainGadgets
.boot
->gadget
, "Boot With No Startup-Sequence",
159 BUTTON_BOOT_WNSS
, BootMenuBase
);
160 if (BootMenuBase
->bm_MainGadgets
.bootnss
== NULL
)
163 return BootMenuBase
->bm_MainGadgets
.bootopt
->gadget
;
166 static void freeGadgets(struct BootMenuBase_intern
*BootMenuBase
)
168 if (BootMenuBase
->bm_MainGadgets
.boot
!= NULL
)
169 freeButtonGadget(BootMenuBase
->bm_MainGadgets
.boot
, BootMenuBase
);
170 if (BootMenuBase
->bm_MainGadgets
.bootnss
!= NULL
);
171 freeButtonGadget(BootMenuBase
->bm_MainGadgets
.bootnss
, BootMenuBase
);
172 if (BootMenuBase
->bm_MainGadgets
.bootopt
!= NULL
)
173 freeButtonGadget(BootMenuBase
->bm_MainGadgets
.bootopt
, BootMenuBase
);
174 if (BootMenuBase
->bm_MainGadgets
.displayopt
!= NULL
)
175 freeButtonGadget(BootMenuBase
->bm_MainGadgets
.displayopt
, BootMenuBase
);
176 if (BootMenuBase
->bm_MainGadgets
.expboarddiag
!= NULL
)
177 freeButtonGadget(BootMenuBase
->bm_MainGadgets
.expboarddiag
, BootMenuBase
);
180 static void msgLoop(struct BootMenuBase_intern
*BootMenuBase
, struct Window
*win
, struct BootConfig
*bcfg
)
183 struct IntuiMessage
*msg
;
186 D(bug("[BootMenu] msgLoop(BootMenuBase @ %p, Window @ %p, Cfg @ %p)\n", BootMenuBase
, win
, bcfg
));
192 WaitPort(win
->UserPort
);
193 while ((msg
= (struct IntuiMessage
*)GetMsg(BootMenuBase
->bm_UserPort
)))
195 if (msg
->Class
== IDCMP_GADGETUP
)
201 ExpansionBase
->Flags
&= ~EBF_DOSFLAG
;
204 case BUTTON_BOOT_WNSS
:
205 ExpansionBase
->Flags
|= EBF_DOSFLAG
;
210 ReplyMsg((struct Message
*)msg
);
215 D(bug("[BootMenu] msgLoop: Window lacks a userport!\n"));
217 } while (exit
== FALSE
);
218 while ((msg
=(struct IntuiMessage
*)GetMsg(win
->UserPort
)))
219 ReplyMsg(&msg
->ExecMessage
);
222 static BOOL
initScreen(struct BootMenuBase_intern
*BootMenuBase
, struct BootConfig
*bcfg
)
225 struct TagItem scrtags
[] =
230 {SA_Pens
, (IPTR
)pens
},
234 struct Gadget
*first
= NULL
;
236 D(bug("[BootMenu] initScreen()\n"));
238 if ((BootMenuBase
->bm_Screen
= OpenScreenTagList(NULL
, scrtags
)) != NULL
)
240 D(bug("[BootMenu] initScreen: Screen opened @ %p\n", BootMenuBase
->bm_Screen
));
241 if ((first
= createGadgets(BootMenuBase
)) != NULL
)
243 D(bug("[BootMenu] initScreen: Gadgets created @ %p\n", first
));
244 struct TagItem wintags
[] =
246 {WA_Left
, 0}, /* 0 */
248 {WA_Width
, BootMenuBase
->bm_Screen
->Width
}, /* 2 */
249 {WA_Height
, BootMenuBase
->bm_Screen
->Height
}, /* 3 */
250 {WA_CustomScreen
, (IPTR
)BootMenuBase
->bm_Screen
}, /* 4 */
251 {WA_Gadgets
, (IPTR
)first
}, /* 5 */
252 // {WA_UserPort, NULL}, /* 6 */
253 {WA_IDCMP
, (IPTR
)(IDCMP_MOUSEBUTTONS
| IDCMP_MOUSEMOVE
| IDCMP_VANILLAKEY
| IDCMP_GADGETUP
| IDCMP_GADGETDOWN
)},
254 {WA_Borderless
, TRUE
},
259 /*BootMenuBase->bm_UserPort = CreateMsgPort();
260 if (BootMenuBase->bm_UserPort)
262 wintags[6].ti_Data = BootMenuBase->bm_UserPort;
266 wintags[6].ti_Tag = TAG_IGNORE;
269 if ((BootMenuBase
->bm_Window
= OpenWindowTagList(NULL
, wintags
)) != NULL
)
271 D(bug("[BootMenu] initScreen: Window opened @ %p\n", BootMenuBase
->bm_Window
));
272 D(bug("[BootMenu] initScreen: Window RastPort @ %p\n", BootMenuBase
->bm_Window
->RPort
));
273 D(bug("[BootMenu] initScreen: Window UserPort @ %p\n", BootMenuBase
->bm_Window
->UserPort
));
274 SetAPen(BootMenuBase
->bm_Window
->RPort
, 2);
275 D(bug("[BootMenu] initScreen: SetAPen 2\n"));
276 Move(BootMenuBase
->bm_Window
->RPort
, 215, 20);
277 D(bug("[BootMenu] initScreen: Move(d) to 215, 20\n"));
278 Text(BootMenuBase
->bm_Window
->RPort
, "AROS Early Startup Control", 26);
279 D(bug("[BootMenu] initScreen: Early Startup text displayed\n"));
280 #if defined(USE_PALNTSC)
281 #warning "TODO: Check if we are using a PAL/NTSC display mode ..."
282 SetAPen(BootMenuBase
->bm_Window
->RPort
, 1);
283 Move(BootMenuBase
->bm_Window
->RPort
, 225, 40);
284 Text(BootMenuBase
->bm_Window
->RPort
, "(press a key to toggle the display between PAL and NTSC)", 23);
286 msgLoop(BootMenuBase
, BootMenuBase
->bm_Window
, bcfg
);
290 Alert(AT_DeadEnd
| AN_OpenWindow
);
292 CloseWindow(BootMenuBase
->bm_Window
);
293 freeGadgets(BootMenuBase
);
296 Alert(AT_DeadEnd
| AN_BadGadget
);
298 CloseScreen(BootMenuBase
->bm_Screen
);
301 Alert(AT_DeadEnd
| AN_OpenScreen
);
306 /* From keyboard.device/keyboard_intern.h */
307 #define KB_MAXKEYS 256
308 #define KB_MATRIXSIZE (KB_MAXKEYS/(sizeof(UBYTE)*8))
309 #define ioStd(x) ((struct IOStdReq *)x)
311 static BOOL
buttonsPressed(struct BootMenuBase
*BootMenuBase
, struct DefaultHidd
*kbd
)
313 BOOL success
= FALSE
;
314 struct MsgPort
*mp
= NULL
;
315 UBYTE matrix
[KB_MATRIXSIZE
];
317 if ((mp
= CreateMsgPort()) != NULL
)
319 struct IORequest
*io
= NULL
;
320 if ((io
= CreateIORequest(mp
, sizeof ( struct IOStdReq
))) != NULL
)
322 if (0 == OpenDevice("keyboard.device", 0, io
, 0))
324 D(bug("[BootMenu] buttonsPressed: Checking KBD_READMATRIX\n"));
325 ioStd(io
)->io_Command
= KBD_READMATRIX
;
326 ioStd(io
)->io_Data
= matrix
;
327 ioStd(io
)->io_Length
= sizeof(matrix
);
329 if (0 == io
->io_Error
)
333 bug("[BootMenu] buttonsPressed: Matrix : ");
334 for (i
= 0; i
< sizeof(matrix
); i
++)
336 bug("%2x ", matrix
[i
]);
340 if (matrix
[RAWKEY_SPACE
/8] & (1<<(RAWKEY_SPACE
%8)))
342 D(bug("[BootMenu] SPACEBAR pressed\n"));
355 int bootmenu_Init(LIBBASETYPEPTR LIBBASE
)
357 struct BootLoaderBase
*BootLoaderBase
= NULL
;
358 struct DefaultHidd
*kbd
= &LIBBASE
->bm_BootConfig
.defaultkbd
;
359 int bmi_RetVal
= (int)FALSE
;
360 D(bug("[BootMenu] bootmenu_Init()\n"));
362 LIBBASE
->bm_Force
= FALSE
; /* Set FALSE here to be sure .. */
364 if ((ExpansionBase
= OpenLibrary("expansion.library", 0)) != NULL
)
366 if ((GfxBase
= OpenLibrary("graphics.library", 37)) != NULL
)
368 if ((IntuitionBase
= OpenLibrary("intuition.library", 37)) != NULL
)
370 BootLoaderBase
= OpenResource("bootloader.resource");
371 InitBootConfig(&LIBBASE
->bm_BootConfig
, BootLoaderBase
);
374 struct List
*list
= NULL
;
375 struct Node
*node
= NULL
;
377 if ((list
= (struct List
*)GetBootInfo(BL_Args
)) != NULL
)
379 ForeachNode(list
,node
)
381 if (0 == strcmp(node
->ln_Name
,"bootmenu"))
383 D(bug("[BootMenu] bootmenu_Init: Forced with bootloader argument\n"));
384 LIBBASE
->bm_Force
= TRUE
;
390 if (!kbd
->hiddname
[0]) {
391 D(bug("[BootMenu] bootmenu_Init: This system uses no keyboard HIDD\n"));
392 bmi_RetVal
= (int)TRUE
;
394 if (OpenLibrary(kbd
->libname
, 0) != NULL
)
396 if (init_device(kbd
->hiddname
, "keyboard.device", LIBBASE
))
398 bmi_RetVal
= (int)TRUE
;
405 if ((bmi_RetVal
) && (LIBBASE
->bm_Force
|| buttonsPressed(LIBBASE
, &LIBBASE
->bm_BootConfig
.defaultkbd
)))
407 D(kprintf("[BootMenu] bootmenu_Init: Entering Boot Menu ...\n"));
408 /* init mouse + gfx */
409 if (initHidds(&LIBBASE
->bm_BootConfig
, LIBBASE
))
411 D(bug("[BootMenu] bootmenu_Init: Hidds Initialised\n"));
412 initScreen(LIBBASE
, &LIBBASE
->bm_BootConfig
);
416 D(bug("[BootMenu] bootmenu_Init: Hidds Failed to initialise!\n"));
421 D(bug("[BootMenu] bootmenu_Init: Menu not requested ..\n"));
426 ADD2INITLIB(bootmenu_Init
, 0)