some fixes to accented characters
[tangerine.git] / rom / bootmenu / menu.c
blob1dda733755043be9485227597e2c16e46d6c2bf7
1 #define DEBUG 0
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>
17 #include <string.h>
18 #include "devs_private.h"
20 #include "bootmenu_intern.h"
22 #include LC_LIBDEFS_FILE
24 /*****************
25 ** init_gfx() **
26 *****************/
28 static BOOL init_gfx(STRPTR gfxclassname, struct BootMenuBase *BootMenuBase)
30 BOOL success = FALSE;
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"));
45 success = TRUE;
47 else
49 D(bug("[BootMenu] init_gfx: calling private LateIntuiInit Failed!\n"));
52 else
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)
61 BOOL success = FALSE;
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 */
79 DoIO(io);
80 if (0 == io->io_Error)
82 success = TRUE;
84 CloseDevice(io);
86 DeleteIORequest(io);
88 DeleteMsgPort(mp);
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])
104 return TRUE;
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"));
114 return TRUE;
119 return FALSE;
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(
128 180, 63, 280, 14,
129 NULL, "Boot Options...",
130 BUTTON_BOOT_OPTIONS, BootMenuBase);
131 if (BootMenuBase->bm_MainGadgets.bootopt == NULL)
132 return NULL;
134 BootMenuBase->bm_MainGadgets.displayopt = createButton(
135 180, 84, 280, 14,
136 BootMenuBase->bm_MainGadgets.bootopt->gadget, "Display Options...",
137 BUTTON_DISPLAY_OPTIONS, BootMenuBase);
138 if (BootMenuBase->bm_MainGadgets.displayopt == NULL)
139 return NULL;
141 BootMenuBase->bm_MainGadgets.expboarddiag = createButton(
142 180, 105, 280, 14,
143 BootMenuBase->bm_MainGadgets.displayopt->gadget, "Expansion Board Diagnostic...",
144 BUTTON_EXPBOARDDIAG, BootMenuBase);
145 if (BootMenuBase->bm_MainGadgets.expboarddiag == NULL)
146 return NULL;
148 /* Create BOOT Gadgets */
149 BootMenuBase->bm_MainGadgets.boot = createButton(
150 16, 190, 280, 14,
151 BootMenuBase->bm_MainGadgets.expboarddiag->gadget, "Boot",
152 BUTTON_BOOT, BootMenuBase);
153 if (BootMenuBase->bm_MainGadgets.boot == NULL)
154 return NULL;
156 BootMenuBase->bm_MainGadgets.bootnss = createButton(
157 344, 190, 280, 14,
158 BootMenuBase->bm_MainGadgets.boot->gadget, "Boot With No Startup-Sequence",
159 BUTTON_BOOT_WNSS, BootMenuBase);
160 if (BootMenuBase->bm_MainGadgets.bootnss == NULL)
161 return 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)
182 BOOL exit = FALSE;
183 struct IntuiMessage *msg;
184 struct Gadget *g;
186 D(bug("[BootMenu] msgLoop(BootMenuBase @ %p, Window @ %p, Cfg @ %p)\n", BootMenuBase, win, bcfg));
190 if (win->UserPort)
192 WaitPort(win->UserPort);
193 while ((msg = (struct IntuiMessage *)GetMsg(BootMenuBase->bm_UserPort)))
195 if (msg->Class == IDCMP_GADGETUP)
197 g = msg->IAddress;
198 switch (g->GadgetID)
200 case BUTTON_BOOT:
201 ExpansionBase->Flags &= ~EBF_DOSFLAG;
202 exit = TRUE;
203 break;
204 case BUTTON_BOOT_WNSS:
205 ExpansionBase->Flags |= EBF_DOSFLAG;
206 exit = TRUE;
207 break;
210 ReplyMsg((struct Message *)msg);
213 else
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)
224 UWORD pens[] = {~0};
225 struct TagItem scrtags[] =
227 {SA_Width, 640},
228 {SA_Height, 256},
229 {SA_Depth, 4},
230 {SA_Pens, (IPTR)pens},
231 {TAG_DONE, 0UL}
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 */
247 {WA_Top, 0}, /* 1 */
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},
255 {WA_RMBTrap, TRUE},
256 {TAG_DONE, 0UL}
259 /*BootMenuBase->bm_UserPort = CreateMsgPort();
260 if (BootMenuBase->bm_UserPort)
262 wintags[6].ti_Data = BootMenuBase->bm_UserPort;
264 else
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);
285 #endif
286 msgLoop(BootMenuBase, BootMenuBase->bm_Window, bcfg);
287 return TRUE;
289 else
290 Alert(AT_DeadEnd | AN_OpenWindow);
292 CloseWindow(BootMenuBase->bm_Window);
293 freeGadgets(BootMenuBase);
295 else
296 Alert(AT_DeadEnd | AN_BadGadget);
298 CloseScreen(BootMenuBase->bm_Screen);
300 else
301 Alert(AT_DeadEnd | AN_OpenScreen);
303 return FALSE;
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);
328 DoIO(io);
329 if (0 == io->io_Error)
332 int i;
333 bug("[BootMenu] buttonsPressed: Matrix : ");
334 for (i = 0; i < sizeof(matrix); i ++)
336 bug("%2x ", matrix[i]);
338 bug("\n");
340 if (matrix[RAWKEY_SPACE/8] & (1<<(RAWKEY_SPACE%8)))
342 D(bug("[BootMenu] SPACEBAR pressed\n"));
343 success = TRUE;
346 CloseDevice(io);
348 DeleteIORequest(io);
350 DeleteMsgPort(mp);
352 return success;
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);
372 if (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;
404 /* check keyboard */
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);
414 else
416 D(bug("[BootMenu] bootmenu_Init: Hidds Failed to initialise!\n"));
419 else
421 D(bug("[BootMenu] bootmenu_Init: Menu not requested ..\n"));
423 return bmi_RetVal;
426 ADD2INITLIB(bootmenu_Init, 0)