Hint added.
[AROS.git] / workbench / prefs / boot / booteditor.c
blob86285e9c825790d9824a357207bd648d740b7d65
1 /*
2 Copyright © 2013-2015, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define MUIMASTER_YES_INLINE_STDARG
8 #include <exec/types.h>
9 #include <utility/tagitem.h>
10 #include <libraries/locale.h>
11 #include <libraries/mui.h>
12 #include <zune/customclasses.h>
13 #include <zune/prefseditor.h>
14 #include <libraries/asl.h>
15 #include <dos/dos.h>
17 #include <proto/exec.h>
18 #include <proto/intuition.h>
19 #include <proto/utility.h>
20 #include <proto/muimaster.h>
21 #include <proto/dos.h>
23 #include <string.h>
24 #include <stdio.h>
26 #include "locale.h"
27 #include "booteditor.h"
29 #include <proto/alib.h>
31 #define DEFAULT_WIDTH 1024
32 #define DEFAULT_HEIGHT 768
33 #define DEFAULT_REFRESH 60
34 #define MAX_LINE_LENGTH 500
36 static const TEXT grub_config_path[] = "SYS:boot/pc/grub/grub.cfg";
37 static const TEXT grub_config_path_tmp[] = "SYS:boot/pc/grub/grub.cfg.tmp";
38 static const TEXT accept_nums[] = "0123456789";
39 static CONST_STRPTR ata_buses_list[5] = {NULL};
40 static CONST_STRPTR debug_output_list[4] = {NULL};
41 static CONST_STRPTR gfx_type_list[5] = {NULL};
42 static CONST_STRPTR vesa_depth_list[4] = {NULL};
43 static CONST_STRPTR entry_tabs[3] = {NULL};
45 struct BootEditor_DATA
47 Object *gfx_type,
48 *gfx_composition,
49 *vesa_group,
50 *vesa_width,
51 *vesa_height,
52 *vesa_best_res,
53 *vesa_depth,
54 *vesa_refresh,
55 *vesa_default_refresh,
56 *ata_buses,
57 *ata_dma,
58 *ata_32bit,
59 *ata_poll,
60 *ata_multi,
61 *device_name,
62 *device_delay,
63 *usb_enable,
64 *acpi_enable,
65 *floppy_enable,
66 *debug_output,
67 *debug_mungwall,
68 *debug_usb,
69 *module_list,
70 *add_button,
71 *remove_button,
72 *module_pop_string,
73 *module_path,
74 *module_active;
77 struct module_entry
79 STRPTR path;
80 BOOL active;
83 static struct Hook module_display_hook;
85 static BOOL ReadBootArgs(CONST_STRPTR line, struct BootEditor_DATA *data);
86 static BOOL WriteBootArgs(BPTR file, struct BootEditor_DATA *data);
87 static BOOL ReadModule(CONST_STRPTR line, struct BootEditor_DATA *data);
88 static BOOL WriteModule(Object *obj, BPTR file, struct module_entry *entry);
89 AROS_UFP3S(LONG, ModuleDisplayHook,
90 AROS_UFPA(struct Hook *, hook, A0),
91 AROS_UFPA(char **, array, A2),
92 AROS_UFPA(struct module_entry *, entry, A1));
94 static Object *BootEditor__OM_NEW(Class *CLASS, Object *self,
95 struct opSet *message)
97 struct BootEditor_DATA temp_data, *data = &temp_data;
99 module_display_hook.h_Entry = HookEntry;
100 module_display_hook.h_SubEntry = (HOOKFUNC)ModuleDisplayHook;
102 entry_tabs[0] = _(MSG_OPTIONS);
103 entry_tabs[1] = _(MSG_MODULES);
105 gfx_type_list[0] = _(MSG_GFX_TYPE_AUTO);
106 gfx_type_list[1] = _(MSG_GFX_TYPE_NATIVE);
107 gfx_type_list[2] = _(MSG_GFX_TYPE_VESA);
108 gfx_type_list[3] = _(MSG_GFX_TYPE_VGA);
110 vesa_depth_list[0] = _(MSG_GFX_DEPTH_TRUE);
111 vesa_depth_list[1] = _(MSG_GFX_DEPTH_HIGH);
112 vesa_depth_list[2] = _(MSG_GFX_DEPTH_LOW);
114 ata_buses_list[0] = _(MSG_ATA_BUS_ALL);
115 ata_buses_list[1] = _(MSG_ATA_BUS_PCI);
116 ata_buses_list[2] = _(MSG_ATA_BUS_LEGACY);
117 ata_buses_list[3] = _(MSG_ATA_BUS_NONE);
119 debug_output_list[0] = _(MSG_DEBUG_OUTPUT_NONE);
120 debug_output_list[1] = _(MSG_DEBUG_OUTPUT_MEMORY);
121 debug_output_list[2] = _(MSG_DEBUG_OUTPUT_SERIAL);
123 self = (Object *)DoSuperNewTags(CLASS, self, NULL,
124 MUIA_PrefsEditor_Name, __(MSG_NAME),
125 MUIA_PrefsEditor_Path, (IPTR)grub_config_path,
126 MUIA_PrefsEditor_CanTest, FALSE,
127 MUIA_PrefsEditor_CanUse, FALSE,
129 Child, (IPTR)RegisterGroup(entry_tabs),
131 /* Options tab */
133 Child, (IPTR)ColGroup(2),
134 Child, (IPTR)VGroup,
135 GroupFrameT(_(MSG_GFX)),
136 Child, (IPTR)ColGroup(2),
137 Child, (IPTR)Label2(__(MSG_GFX_TYPE)),
138 Child, (IPTR)(data->gfx_type = (Object *)CycleObject,
139 MUIA_Cycle_Entries, (IPTR)gfx_type_list,
140 End),
141 Child, (IPTR)(data->gfx_composition =
142 MUI_MakeObject(MUIO_Checkmark, NULL)),
143 Child, (IPTR)HGroup,
144 Child, (IPTR)Label2(__(MSG_GFX_COMPOSITION)),
145 Child, (IPTR)HVSpace,
146 End,
147 Child, (IPTR)HVSpace,
148 Child, (IPTR)HVSpace,
149 End,
150 Child, (IPTR)(data->vesa_group = VGroup,
151 GroupFrameT(_(MSG_GFX_VESAMODE)),
152 Child, (IPTR)HGroup,
153 Child, (IPTR)(data->vesa_best_res =
154 MUI_MakeObject(MUIO_Checkmark, NULL)),
155 Child, (IPTR)Label2(__(MSG_GFX_BESTRES)),
156 Child, (IPTR)HVSpace,
157 End,
158 Child, (IPTR)ColGroup(2),
159 Child, (IPTR)Label2(__(MSG_GFX_WIDTH)),
160 Child, (IPTR)HGroup,
161 Child, (IPTR)(data->vesa_width =
162 (Object *)StringObject,
163 StringFrame,
164 MUIA_CycleChain, 1,
165 MUIA_String_Accept, (IPTR)accept_nums,
166 MUIA_FixWidthTxt, (IPTR)"00000",
167 End),
168 Child, (IPTR)HVSpace,
169 End,
170 Child, (IPTR)Label2(__(MSG_GFX_HEIGHT)),
171 Child, (IPTR)HGroup,
172 Child, (IPTR)(data->vesa_height =
173 (Object *)StringObject,
174 StringFrame,
175 MUIA_CycleChain, 1,
176 MUIA_String_Accept, (IPTR)accept_nums,
177 MUIA_FixWidthTxt, (IPTR)"00000",
178 End),
179 Child, (IPTR)HVSpace,
180 End,
181 Child, (IPTR)Label2(__(MSG_GFX_DEPTH)),
182 Child, (IPTR)(data->vesa_depth =
183 (Object *)CycleObject,
184 MUIA_Cycle_Entries, (IPTR)vesa_depth_list,
185 End),
186 Child, (IPTR)Label2(__(MSG_GFX_REFRESH)),
187 Child, (IPTR)HGroup,
188 Child, (IPTR)(data->vesa_refresh =
189 (Object *)StringObject,
190 StringFrame,
191 MUIA_CycleChain, 1,
192 MUIA_String_Accept, (IPTR)accept_nums,
193 MUIA_FixWidthTxt, (IPTR)"0000",
194 End),
195 Child, (IPTR)Label2(__(MSG_GFX_HERTZ)),
196 Child, (IPTR)HVSpace,
197 End,
198 End,
199 Child, (IPTR)HGroup,
200 Child, (IPTR)(data->vesa_default_refresh =
201 MUI_MakeObject(MUIO_Checkmark, NULL)),
202 Child, (IPTR)Label2(__(MSG_GFX_DEFAULTREFRESH)),
203 Child, (IPTR)HVSpace,
204 End,
205 End),
206 End,
207 Child, (IPTR)VGroup,
208 Child, (IPTR)VGroup,
209 GroupFrameT(_(MSG_ATA)),
210 Child, (IPTR)HGroup,
211 Child, (IPTR)Label2(__(MSG_ATA_BUSES)),
212 Child, (IPTR)(data->ata_buses =
213 (Object *)CycleObject,
214 MUIA_Cycle_Entries, (IPTR)ata_buses_list,
215 End),
216 End,
217 Child, (IPTR)ColGroup(2),
218 Child, (IPTR)(data->ata_dma =
219 MUI_MakeObject(MUIO_Checkmark, NULL)),
220 Child, (IPTR)HGroup,
221 Child, (IPTR)Label2(__(MSG_ATA_DMA)),
222 Child, (IPTR)HVSpace,
223 End,
224 Child, (IPTR)(data->ata_multi =
225 MUI_MakeObject(MUIO_Checkmark, NULL)),
226 Child, (IPTR)HGroup,
227 Child, (IPTR)Label2(__(MSG_ATA_MULTI)),
228 Child, (IPTR)HVSpace,
229 End,
230 Child, (IPTR)(data->ata_32bit =
231 MUI_MakeObject(MUIO_Checkmark, NULL)),
232 Child, (IPTR)HGroup,
233 Child, (IPTR)Label2(__(MSG_ATA_32BIT)),
234 Child, (IPTR)HVSpace,
235 End,
236 Child, (IPTR)(data->ata_poll =
237 MUI_MakeObject(MUIO_Checkmark, NULL)),
238 Child, (IPTR)HGroup,
239 Child, (IPTR)Label2(__(MSG_ATA_POLL)),
240 Child, (IPTR)HVSpace,
241 End,
242 Child, (IPTR)HVSpace,
243 Child, (IPTR)HVSpace,
244 End,
245 End,
246 Child, (IPTR)VGroup,
247 GroupFrameT(_(MSG_DEVICE)),
248 Child, (IPTR)ColGroup(2),
249 Child, (IPTR)Label2(__(MSG_DEVICE_NAME)),
250 Child, (IPTR)HGroup,
251 Child, (IPTR)(data->device_name =
252 (Object *)StringObject,
253 StringFrame,
254 MUIA_CycleChain, 1,
255 MUIA_String_Reject, (IPTR)":; ",
256 MUIA_FixWidthTxt, (IPTR)"000000000",
257 End),
258 Child, (IPTR)HVSpace,
259 End,
260 Child, (IPTR)Label2(__(MSG_DEVICE_DELAY)),
261 Child, (IPTR)HGroup,
262 Child, (IPTR)(data->device_delay =
263 (Object *)StringObject,
264 StringFrame,
265 MUIA_CycleChain, 1,
266 MUIA_String_Accept, (IPTR)accept_nums,
267 MUIA_FixWidthTxt, (IPTR)"000",
268 End),
269 Child, (IPTR)Label2(__(MSG_DEVICE_SECONDS)),
270 Child, (IPTR)HVSpace,
271 End,
272 End,
273 End,
274 End,
275 Child, (IPTR)ColGroup(2),
276 GroupFrameT(_(MSG_MISC)),
277 Child, (IPTR)(data->usb_enable =
278 MUI_MakeObject(MUIO_Checkmark, NULL)),
279 Child, (IPTR)HGroup,
280 Child, (IPTR)Label2(__(MSG_USB_ENABLE)),
281 Child, (IPTR)HVSpace,
282 End,
283 Child, (IPTR)(data->acpi_enable =
284 MUI_MakeObject(MUIO_Checkmark, NULL)),
285 Child, (IPTR)HGroup,
286 Child, (IPTR)Label2(__(MSG_ACPI_ENABLE)),
287 Child, (IPTR)HVSpace,
288 End,
289 Child, (IPTR)(data->floppy_enable =
290 MUI_MakeObject(MUIO_Checkmark, NULL)),
291 Child, (IPTR)HGroup,
292 Child, (IPTR)Label2(__(MSG_FLOPPY_ENABLE)),
293 Child, (IPTR)HVSpace,
294 End,
295 Child, (IPTR)HVSpace,
296 Child, (IPTR)HVSpace,
297 End,
298 Child, (IPTR)VGroup,
299 GroupFrameT(_(MSG_DEBUG)),
300 Child, (IPTR)HGroup,
301 Child, (IPTR)Label2(__(MSG_DEBUG_OUTPUT)),
302 Child, (IPTR)(data->debug_output =
303 (Object *)CycleObject,
304 MUIA_Cycle_Entries, (IPTR)debug_output_list,
305 End),
306 End,
307 Child, (IPTR)ColGroup(2),
308 Child, (IPTR)(data->debug_mungwall =
309 MUI_MakeObject(MUIO_Checkmark, NULL)),
310 Child, (IPTR)HGroup,
311 Child, (IPTR)Label2(__(MSG_DEBUG_MUNGWALL)),
312 Child, (IPTR)HVSpace,
313 End,
314 Child, (IPTR)(data->debug_usb =
315 MUI_MakeObject(MUIO_Checkmark, NULL)),
316 Child, (IPTR)HGroup,
317 Child, (IPTR)Label2(__(MSG_DEBUG_USB)),
318 Child, (IPTR)HVSpace,
319 End,
320 End,
321 Child, (IPTR)HVSpace,
322 End,
323 End,
325 /* Modules tab */
327 Child, (IPTR)VGroup,
328 Child, (IPTR)ListviewObject,
329 MUIA_Listview_List, (IPTR)(data->module_list =
330 (Object *)ListObject,
331 InputListFrame,
332 MUIA_List_AutoVisible, TRUE,
333 MUIA_List_Title, TRUE,
334 MUIA_List_Format, (IPTR)"P=\033c BAR,",
335 MUIA_List_DisplayHook, (IPTR)&module_display_hook,
336 End),
337 MUIA_CycleChain, 1,
338 End,
339 Child, (IPTR)VGroup,
340 Child, (IPTR)HGroup,
341 Child, (IPTR)(data->add_button =
342 SimpleButton(_(MSG_ADD))),
343 Child, (IPTR)(data->remove_button =
344 SimpleButton(_(MSG_REMOVE))),
345 End,
346 Child, (IPTR)HGroup,
347 GroupFrame,
348 Child, (IPTR)Label2(__(MSG_PATH)),
349 Child, (IPTR)(data->module_pop_string = PopaslObject,
350 MUIA_Popasl_Type, ASL_FileRequest,
351 MUIA_Popstring_String,
352 (IPTR)(data->module_path =
353 (Object *)StringObject,
354 StringFrame,
355 MUIA_Background, MUII_TextBack,
356 MUIA_CycleChain, 1,
357 MUIA_Disabled, TRUE,
358 End),
359 MUIA_Popstring_Button,
360 (IPTR)PopButton(MUII_PopFile),
361 End),
362 Child, (IPTR)(data->module_active =
363 MUI_MakeObject(MUIO_Checkmark, NULL)),
364 Child, (IPTR)Label2(_(MSG_ACTIVE)),
365 End,
366 End,
367 End,
369 End,
370 TAG_DONE
373 if (self != NULL)
375 data = INST_DATA(CLASS, self);
376 *data = temp_data;
378 /* Set up notifications */
380 DoMethod(data->gfx_type, MUIM_Notify,
381 MUIA_Cycle_Active, MUIV_EveryTime,
382 (IPTR)self, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
383 DoMethod(data->gfx_composition, MUIM_Notify,
384 MUIA_Selected, MUIV_EveryTime,
385 (IPTR)self, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
386 DoMethod(data->vesa_width, MUIM_Notify,
387 MUIA_String_Acknowledge, MUIV_EveryTime,
388 (IPTR)self, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
389 DoMethod(data->vesa_height, MUIM_Notify,
390 MUIA_String_Acknowledge, MUIV_EveryTime,
391 (IPTR)self, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
392 DoMethod(data->vesa_depth, MUIM_Notify,
393 MUIA_Cycle_Active, MUIV_EveryTime,
394 (IPTR)self, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
395 DoMethod(data->vesa_refresh, MUIM_Notify,
396 MUIA_String_Acknowledge, MUIV_EveryTime,
397 (IPTR)self, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
398 DoMethod(data->vesa_default_refresh, MUIM_Notify,
399 MUIA_Selected, MUIV_EveryTime,
400 (IPTR)self, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
401 DoMethod(data->vesa_best_res, MUIM_Notify,
402 MUIA_Selected, MUIV_EveryTime,
403 (IPTR)self, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
404 DoMethod(data->ata_buses, MUIM_Notify,
405 MUIA_Cycle_Active, MUIV_EveryTime,
406 (IPTR)self, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
407 DoMethod(data->ata_dma, MUIM_Notify,
408 MUIA_Selected, MUIV_EveryTime,
409 (IPTR)self, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
410 DoMethod(data->ata_multi, MUIM_Notify,
411 MUIA_Selected, MUIV_EveryTime,
412 (IPTR)self, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
413 DoMethod(data->ata_32bit, MUIM_Notify,
414 MUIA_Selected, MUIV_EveryTime,
415 (IPTR)self, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
416 DoMethod(data->ata_poll, MUIM_Notify,
417 MUIA_Selected, MUIV_EveryTime,
418 (IPTR)self, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
419 DoMethod(data->device_name, MUIM_Notify,
420 MUIA_String_Acknowledge, MUIV_EveryTime,
421 (IPTR)self, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
422 DoMethod(data->device_delay, MUIM_Notify,
423 MUIA_String_Acknowledge, MUIV_EveryTime,
424 (IPTR)self, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
425 DoMethod(data->usb_enable, MUIM_Notify,
426 MUIA_Selected, MUIV_EveryTime,
427 (IPTR)self, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
428 DoMethod(data->acpi_enable, MUIM_Notify,
429 MUIA_Selected, MUIV_EveryTime,
430 (IPTR)self, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
431 DoMethod(data->floppy_enable, MUIM_Notify,
432 MUIA_Selected, MUIV_EveryTime,
433 (IPTR)self, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
434 DoMethod(data->debug_output, MUIM_Notify,
435 MUIA_Cycle_Active, MUIV_EveryTime,
436 (IPTR)self, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
437 DoMethod(data->debug_mungwall, MUIM_Notify,
438 MUIA_Selected, MUIV_EveryTime,
439 (IPTR)self, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
440 DoMethod(data->debug_usb, MUIM_Notify,
441 MUIA_Selected, MUIV_EveryTime,
442 (IPTR)self, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
444 DoMethod(data->gfx_type, MUIM_Notify,
445 MUIA_Cycle_Active, 0,
446 (IPTR)data->vesa_group, 3, MUIM_Set, MUIA_Disabled, FALSE);
447 DoMethod(data->gfx_type, MUIM_Notify,
448 MUIA_Cycle_Active, 1,
449 (IPTR)data->vesa_group, 3, MUIM_Set, MUIA_Disabled, TRUE);
450 DoMethod(data->gfx_type, MUIM_Notify,
451 MUIA_Cycle_Active, 2,
452 (IPTR)data->vesa_group, 3, MUIM_Set, MUIA_Disabled, FALSE);
453 DoMethod(data->gfx_type, MUIM_Notify,
454 MUIA_Cycle_Active, 3,
455 (IPTR)data->vesa_group, 3, MUIM_Set, MUIA_Disabled, TRUE);
457 DoMethod(data->vesa_default_refresh, MUIM_Notify,
458 MUIA_Selected, MUIV_EveryTime,
459 (IPTR)data->vesa_refresh, 3, MUIM_Set, MUIA_Disabled,
460 MUIV_TriggerValue);
461 DoMethod(data->vesa_best_res, MUIM_Notify,
462 MUIA_Selected, MUIV_EveryTime,
463 (IPTR)data->vesa_width, 3, MUIM_Set, MUIA_Disabled,
464 MUIV_TriggerValue);
465 DoMethod(data->vesa_best_res, MUIM_Notify,
466 MUIA_Selected, MUIV_EveryTime,
467 (IPTR)data->vesa_height, 3, MUIM_Set, MUIA_Disabled,
468 MUIV_TriggerValue);
470 DoMethod(data->module_list, MUIM_Notify, MUIA_List_Active,
471 MUIV_EveryTime, (IPTR)self, 1, MUIM_BootEditor_ShowModule);
472 DoMethod(data->module_path, MUIM_Notify, MUIA_String_Contents,
473 MUIV_EveryTime, (IPTR)self, 1, MUIM_BootEditor_UpdateModule);
474 DoMethod(data->module_active, MUIM_Notify, MUIA_Selected,
475 MUIV_EveryTime, (IPTR)self, 1, MUIM_BootEditor_UpdateModule);
476 DoMethod(data->add_button, MUIM_Notify, MUIA_Pressed,
477 TRUE, (IPTR)self, 1, MUIM_BootEditor_AddModule);
478 DoMethod(data->remove_button, MUIM_Notify, MUIA_Pressed, TRUE,
479 (IPTR)self, 1, MUIM_BootEditor_RemoveModule);
481 /* Set default values */
483 SET(data->gfx_composition, MUIA_Selected, TRUE);
484 SET(data->vesa_width, MUIA_String_Integer, DEFAULT_WIDTH);
485 SET(data->vesa_height, MUIA_String_Integer, DEFAULT_HEIGHT);
486 SET(data->vesa_refresh, MUIA_String_Integer, DEFAULT_REFRESH);
488 SET(data->ata_dma, MUIA_Selected, TRUE);
489 SET(data->ata_multi, MUIA_Selected, TRUE);
490 SET(data->ata_32bit, MUIA_Selected, TRUE);
492 SET(data->device_delay, MUIA_String_Integer, 0);
494 SET(data->usb_enable, MUIA_Selected, TRUE);
495 SET(data->acpi_enable, MUIA_Selected, TRUE);
497 SET(data->remove_button, MUIA_Disabled, TRUE);
498 SET(data->module_active, MUIA_Disabled, TRUE);
499 SET(data->module_pop_string, MUIA_Disabled, TRUE);
502 return self;
505 static IPTR BootEditor__MUIM_Setup(Class *CLASS, Object *self, Msg message)
507 if (!DoSuperMethodA(CLASS, self, message))
508 return FALSE;
510 return TRUE;
513 static IPTR BootEditor__MUIM_Cleanup(Class *CLASS, Object *self, Msg message)
515 return DoSuperMethodA(CLASS, self, message);
518 static IPTR BootEditor__MUIM_PrefsEditor_ImportFH(Class *CLASS, Object *self,
519 struct MUIP_PrefsEditor_ImportFH *message)
521 struct BootEditor_DATA *data = INST_DATA(CLASS, self);
522 BPTR file;
523 TEXT line_buffer[MAX_LINE_LENGTH], *line;
524 BOOL success = TRUE, done = FALSE;
526 /* Find first AROS boot entry, parse its arguments and put them in
527 * the GUI */
529 file = Open(grub_config_path, MODE_OLDFILE);
530 if (file == BNULL)
531 success = FALSE;
533 if (success)
535 while (!done)
537 line = FGets(file, line_buffer, MAX_LINE_LENGTH);
538 if (line == NULL)
539 done = TRUE;
540 else if (strstr(line, "multiboot") != NULL
541 && strstr(line, "bootstrap") != NULL)
543 if (!ReadBootArgs(line, data))
544 success = FALSE;
546 else if (strstr(line, "module ") != NULL)
548 if (!ReadModule(line, data))
549 success = FALSE;
551 if (strstr(line, "}") != NULL)
552 done = TRUE;
556 if (file != NULL)
557 Close(file);
559 return success;
562 static IPTR BootEditor__MUIM_PrefsEditor_ExportFH(Class *CLASS, Object *self,
563 struct MUIP_PrefsEditor_ExportFH *message)
565 return FALSE;
568 static IPTR BootEditor__MUIM_PrefsEditor_Save(Class *CLASS, Object *self,
569 Msg message)
571 struct BootEditor_DATA *data = INST_DATA(CLASS, self);
572 BPTR old_file, new_file;
573 TEXT line_buffer[MAX_LINE_LENGTH], *line;
574 BOOL success = TRUE, done = FALSE, found = FALSE;
575 struct module_entry *module;
576 UWORD i;
578 /* Find first AROS boot entry and replace its arguments with those
579 * chosen in the GUI */
581 old_file = Open(grub_config_path, MODE_OLDFILE);
582 new_file = Open(grub_config_path_tmp, MODE_NEWFILE);
583 if (old_file == BNULL && new_file == BNULL)
584 success = FALSE;
586 if (success)
588 while (!done)
590 line = FGets(old_file, line_buffer, MAX_LINE_LENGTH);
591 if (line == NULL)
592 done = TRUE;
593 else if (!found && strstr(line, "multiboot") != NULL
594 && strstr(line, "bootstrap") != NULL)
596 strstr(line, ".gz")[3] = '\0';
597 if (FPuts(new_file, line) != 0)
598 success = FALSE;
599 else if (!WriteBootArgs(new_file, data))
600 success = FALSE;
601 else
603 /* Skip past all module lines */
605 while (!found)
607 line = FGets(old_file, line_buffer, MAX_LINE_LENGTH);
608 if (line == NULL)
609 found = done = TRUE;
610 else if (strchr(line, '}') != NULL)
611 found = TRUE;
614 /* Write new module lines */
616 for (i = 0; success && DoMethod(data->module_list,
617 MUIM_List_GetEntry, i, &module) != (IPTR)NULL; i++)
619 if (!WriteModule(self, new_file, module))
620 success = FALSE;
623 /* Keep line with closing curly bracket */
625 if (FPuts(new_file, line) != 0)
626 success = FALSE;
629 else
630 if (FPuts(new_file, line) != 0)
631 success = FALSE;
635 /* Close both files */
637 if (old_file != NULL)
638 Close(old_file);
639 if (new_file != NULL)
640 if (!Close(new_file))
641 success = FALSE;
643 /* Replace old file with new one */
645 if (success)
646 success = DeleteFile(grub_config_path);
648 if (success)
649 success = Rename(grub_config_path_tmp, grub_config_path);
651 return success;
654 IPTR BootEditor__MUIM_BootEditor_ShowModule(Class *cl, Object *self,
655 Msg message)
657 struct BootEditor_DATA *data = INST_DATA(cl, self);
658 struct module_entry *module;
659 BOOL show;
661 DoMethod(data->module_list, MUIM_List_GetEntry,
662 MUIV_List_GetEntry_Active, &module);
663 show = module != NULL;
664 SET(data->module_pop_string, MUIA_Disabled, !show);
665 SET(data->module_active, MUIA_Disabled, !show);
666 NNSET(data->module_path, MUIA_String_Contents,
667 (IPTR)(show ? module->path : NULL));
668 NNSET(data->module_active, MUIA_Selected, show ? module->active : FALSE);
669 SET(data->remove_button, MUIA_Disabled, !show);
671 return 0;
674 IPTR BootEditor__MUIM_BootEditor_UpdateModule(Class *cl, Object *self,
675 Msg message)
677 struct BootEditor_DATA *data = INST_DATA(cl, self);
678 struct module_entry *module;
680 DoMethod(data->module_list, MUIM_List_GetEntry,
681 MUIV_List_GetEntry_Active, &module);
682 if (module != NULL)
684 FreeVec(module->path);
685 module->path =
686 StrDup((APTR)XGET(data->module_path, MUIA_String_Contents));
687 module->active = XGET(data->module_active, MUIA_Selected);
688 DoMethod(data->module_list, MUIM_List_Redraw,
689 MUIV_List_Redraw_Active);
691 return 0;
694 IPTR BootEditor__MUIM_BootEditor_AddModule(Class *cl, Object *self,
695 Msg message)
697 struct BootEditor_DATA *data = INST_DATA(cl, self);
698 struct module_entry *module;
699 BOOL success = TRUE;
701 module = AllocMem(sizeof(struct module_entry), MEMF_CLEAR);
702 if (module == NULL)
703 success = FALSE;
705 if (success)
707 module->path = StrDup("");
708 if (module->path == NULL)
709 success = FALSE;
710 module->active = TRUE;
713 if (success)
715 if (DoMethod(data->module_list, MUIM_List_InsertSingle, module,
716 MUIV_List_Insert_Bottom) == -1)
717 success = FALSE;
718 SET(data->module_list, MUIA_List_Active, MUIV_List_Active_Bottom);
721 return 0;
724 IPTR BootEditor__MUIM_BootEditor_RemoveModule(Class *cl, Object *self,
725 Msg message)
727 struct BootEditor_DATA *data = INST_DATA(cl, self);
728 struct module_entry *module;
730 /* Remove entry from list and deallocate it */
732 DoMethod(data->module_list, MUIM_List_GetEntry,
733 MUIV_List_GetEntry_Active, &module);
734 if (module != NULL)
736 DoMethod(data->module_list, MUIM_List_Remove,
737 MUIV_List_Remove_Active);
738 FreeVec(module->path);
739 FreeMem(module, sizeof(struct module_entry));
742 return 0;
745 static BOOL ReadBootArgs(CONST_STRPTR line, struct BootEditor_DATA *data)
747 UWORD choice, width = 0, height = 0, depth = 0, refresh = 0, delay = 0;
748 BOOL success = TRUE, best_res = FALSE, use_refresh = FALSE;
749 STRPTR options, p;
750 TEXT ch;
752 /* Graphics */
754 if (strstr(line, "nomonitors") != NULL
755 && strstr(line, "vesa=") == NULL)
756 choice = 3;
757 else if (strstr(line, "nomonitors") != NULL)
758 choice = 2;
759 else if (strstr(line, "vesa=") == NULL)
760 choice = 1;
761 else
762 choice = 0;
763 SET(data->gfx_type, MUIA_Cycle_Active, choice);
765 NNSET(data->gfx_composition, MUIA_Selected,
766 strstr(line, "nocomposition") == NULL);
768 /* VESA */
770 options = strstr(line, "vesa=");
771 if (options != NULL)
773 options += 5;
775 while (*options >= '0' && *options <= '9')
776 width = width * 10 + *options++ - '0';
777 if (*options++ == 'x')
779 while (*options >= '0' && *options <= '9')
780 height = height * 10 + *options++ - '0';
781 if (*options++ == 'x')
783 while (*options >= '0' && *options <= '9')
784 depth = depth * 10 + *options++ - '0';
786 else
787 depth = 32;
789 else
791 depth = width, width = DEFAULT_WIDTH, height = DEFAULT_HEIGHT;
792 best_res = TRUE;
794 NNSET(data->vesa_width, MUIA_String_Integer, width);
795 NNSET(data->vesa_height, MUIA_String_Integer, height);
796 SET(data->vesa_best_res, MUIA_Selected, best_res);
798 /* Check for user-set refresh rate */
800 if (*(options - 1) == '@')
802 while (*options >= '0' && *options <= '9')
803 refresh = refresh * 10 + *options++ - '0';
804 use_refresh = TRUE;
806 else
807 refresh = DEFAULT_REFRESH;
809 NNSET(data->vesa_refresh, MUIA_String_Integer, refresh);
810 SET(data->vesa_default_refresh, MUIA_Selected, !use_refresh);
812 if (depth > 16)
813 choice = 0;
814 else if (depth > 8)
815 choice = 1;
816 else
817 choice = 0;
818 NNSET(data->vesa_depth, MUIA_Cycle_Active, choice);
821 /* ATA */
823 options = strstr(line, "ATA=");
824 if (options != NULL)
826 if (strstr(options, "nopci") != NULL
827 && strstr(options, "nolegacy") != NULL)
828 choice = 3;
829 else if (strstr(options, "nopci") != NULL)
830 choice = 2;
831 else if (strstr(options, "nolegacy") != NULL)
832 choice = 1;
833 else
834 choice = 0;
835 NNSET(data->ata_buses, MUIA_Cycle_Active, choice);
837 if (strstr(options, "nodma") != NULL)
838 NNSET(data->ata_dma, MUIA_Selected, FALSE);
839 if (strstr(options, "nomulti") != NULL)
840 NNSET(data->ata_multi, MUIA_Selected, FALSE);
841 if (strstr(options, "32bit") == NULL)
842 NNSET(data->ata_multi, MUIA_Selected, FALSE);
843 if (strstr(options, "poll") != NULL)
844 NNSET(data->ata_poll, MUIA_Selected, TRUE);
847 /* Boot Device */
849 options = strstr(line, "bootdevice=");
850 if (options != NULL)
852 options += 11;
854 for (p = options; *p != ' ' && *p != '\n' && *p != '\0'; p++);
855 ch = *p;
856 *p = '\0';
857 NNSET(data->device_name, MUIA_String_Contents, options);
858 *p = ch;
861 options = strstr(line, "bootdelay=");
862 if (options != NULL)
864 options += 10;
866 while (*options >= '0' && *options <= '9')
867 delay = delay * 10 + *options++ - '0';
869 NNSET(data->device_delay, MUIA_String_Integer, delay);
871 /* Miscellaneous */
873 NNSET(data->usb_enable, MUIA_Selected,
874 strstr(line, "enableusb") != NULL);
875 NNSET(data->acpi_enable, MUIA_Selected,
876 strstr(line, "noacpi") == NULL);
877 NNSET(data->floppy_enable, MUIA_Selected,
878 strstr(line, "floppy=disabled") == NULL);
880 /* Debugging */
882 if (strstr(line, "debug=serial") != NULL)
883 choice = 2;
884 else if (strstr(line, "debug=memory") != NULL)
885 choice = 1;
886 else
887 choice = 0;
888 NNSET(data->debug_output, MUIA_Cycle_Active, choice);
890 NNSET(data->debug_mungwall, MUIA_Selected,
891 strstr(line, "mungwall") != NULL);
892 NNSET(data->debug_usb, MUIA_Selected,
893 strstr(line, "usbdebug") != NULL);
895 return success;
898 static BOOL WriteBootArgs(BPTR file, struct BootEditor_DATA *data)
900 UWORD count, choice, width, height, depth, delay;
901 BOOL success = TRUE;
902 CONST_STRPTR name = NULL;
904 /* VESA */
906 if((XGET(data->gfx_type, MUIA_Cycle_Active) & 1) == 0)
908 FPrintf(file, " vesa=");
909 if(!XGET(data->vesa_best_res, MUIA_Selected))
911 width = XGET(data->vesa_width, MUIA_String_Integer);
912 height = XGET(data->vesa_height, MUIA_String_Integer);
913 #if 0
914 FPrintf(file, "%ux%ux", width, height);
915 #else
916 FPrintf(file, "%ux", width);
917 FPrintf(file, "%ux", height);
918 #endif
920 choice = XGET(data->vesa_depth, MUIA_Cycle_Active);
921 if (choice == 0)
922 depth = 32;
923 else if (choice == 1)
924 depth = 16;
925 else
926 depth = 8;
927 FPrintf(file, "%u", depth);
928 if(!XGET(data->vesa_default_refresh, MUIA_Selected))
929 FPrintf(file, "@%u", XGET(data->vesa_refresh, MUIA_String_Integer));
932 /* Graphics */
934 if(XGET(data->gfx_type, MUIA_Cycle_Active) > 1)
935 FPrintf(file, " nomonitors");
936 if(!XGET(data->gfx_composition, MUIA_Selected))
937 FPrintf(file, " nocomposition");
939 /* ATA */
941 if(!XGET(data->ata_dma, MUIA_Selected) ||
942 !XGET(data->ata_multi, MUIA_Selected) ||
943 XGET(data->ata_32bit, MUIA_Selected) ||
944 XGET(data->ata_poll, MUIA_Selected) ||
945 XGET(data->ata_buses, MUIA_Cycle_Active) > 0)
947 count = 0;
948 FPrintf(file, " ATA=");
950 choice = XGET(data->ata_buses, MUIA_Cycle_Active);
951 if (choice == 1)
953 FPrintf(file, "nolegacy");
954 count++;
956 else if (choice == 2)
958 FPrintf(file, "nopci");
959 count++;
961 else if (choice == 3)
963 FPrintf(file, "nopci,nolegacy");
964 count += 2;
967 if(!XGET(data->ata_dma, MUIA_Selected))
969 if(count > 0)
970 FPrintf(file, ",");
971 FPrintf(file, "nodma");
972 count++;
974 if(!XGET(data->ata_multi, MUIA_Selected))
976 if(count > 0)
977 FPrintf(file, ",");
978 FPrintf(file, "nomulti");
979 count++;
981 if(XGET(data->ata_32bit, MUIA_Selected))
983 if(count > 0)
984 FPrintf(file, ",");
985 FPrintf(file, "32bit");
986 count++;
988 if(XGET(data->ata_poll, MUIA_Selected))
990 if(count > 0)
991 FPrintf(file, ",");
992 FPrintf(file, "poll");
993 count++;
997 /* Boot device */
999 GET(data->device_name, MUIA_String_Contents, &name);
1000 if (*name != '\0')
1001 FPrintf(file, " bootdevice=%s", name);
1002 delay = XGET(data->device_delay, MUIA_String_Integer);
1003 if(delay != 0)
1004 FPrintf(file, " bootdelay=%u", delay);
1006 /* Miscellaneous */
1008 if(XGET(data->usb_enable, MUIA_Selected))
1009 FPrintf(file, " enableusb");
1010 if(!XGET(data->acpi_enable, MUIA_Selected))
1011 FPrintf(file, " noacpi");
1012 if(!XGET(data->floppy_enable, MUIA_Selected))
1013 FPrintf(file, " floppy=disabled");
1015 /* Debugging */
1017 if(XGET(data->debug_output, MUIA_Cycle_Active) == 1)
1018 FPrintf(file, " debug=memory");
1019 else if(XGET(data->debug_output, MUIA_Cycle_Active) == 2)
1020 FPrintf(file, " debug=serial");
1021 if(XGET(data->debug_mungwall, MUIA_Selected))
1022 FPrintf(file, " mungwall");
1023 if(XGET(data->debug_usb, MUIA_Selected))
1024 FPrintf(file, " usbdebug");
1026 if (FPrintf(file, "\n") < 0)
1027 success = FALSE;
1029 return success;
1032 static BOOL ReadModule(CONST_STRPTR line, struct BootEditor_DATA *data)
1034 BOOL success = TRUE;
1035 STRPTR path, comment;
1036 struct module_entry *entry;
1038 /* Parse module line */
1040 path = strchr(line, '/');
1041 comment = strchr(line, '#');
1042 if (path == NULL)
1043 success = FALSE;
1045 /* Create module entry */
1047 if (success)
1049 entry = AllocMem(sizeof(struct module_entry), MEMF_CLEAR);
1050 if (entry == NULL)
1051 success = FALSE;
1054 if (success)
1056 path[strlen(path) - 1] = '\0';
1057 entry->path = AllocVec(strlen(path) + 4, MEMF_ANY);
1058 if (entry->path == NULL)
1059 success = FALSE;
1062 if (success)
1064 sprintf(entry->path, "SYS:%s", path + 1);
1066 /* Mark module inactive if there's a comment character before it */
1068 entry->active = comment == NULL || comment > path;
1071 /* Add module to list */
1073 if (success)
1075 if (DoMethod(data->module_list, MUIM_List_InsertSingle,
1076 (IPTR)entry, MUIV_List_Insert_Bottom) == -1)
1077 success = FALSE;
1080 return success;
1083 static BOOL WriteModule(Object *obj, BPTR file, struct module_entry *entry)
1085 BOOL success = TRUE;
1086 TEXT buffer[MAX_LINE_LENGTH], *path = buffer, *p;
1087 BPTR lock, old_dir;
1088 Object *app = NULL, *window = NULL;
1090 /* Convert path to canonical form */
1092 old_dir = CurrentDir(BNULL);
1093 lock = Lock(entry->path, SHARED_LOCK);
1094 if (lock == BNULL)
1096 GET(obj, MUIA_ApplicationObject, &app);
1097 GET(obj, MUIA_Window_Window, &window);
1099 MUI_Request(app, window, 0, "Error", _(MSG_OK), _(MSG_BAD_MODULE),
1100 entry->path);
1101 success = FALSE;
1104 if (success)
1106 if (!NameFromLock(lock, buffer, MAX_LINE_LENGTH))
1107 success = FALSE;
1108 UnLock(lock);
1111 if (success)
1113 if ((p = strchr(buffer, ':')) != NULL)
1114 path = p + 1;
1116 FPrintf(file, " ");
1117 if (!entry->active)
1118 FPrintf(file, "#");
1119 FPrintf(file, "module /%s\n", path);
1121 CurrentDir(old_dir);
1123 return success;
1126 AROS_UFH3S(LONG, ModuleDisplayHook,
1127 AROS_UFHA(struct Hook *, hook, A0),
1128 AROS_UFHA(char **, array, A2),
1129 AROS_UFHA(struct module_entry *, entry, A1))
1131 AROS_USERFUNC_INIT
1133 if (entry != NULL)
1135 *array++ = entry->active ? "*" : "";
1136 *array = entry->path;
1138 else
1140 *array++ = (STRPTR)_(MSG_ACTIVE);
1141 *array = (STRPTR)_(MSG_PATH);
1144 return 0;
1146 AROS_USERFUNC_EXIT
1149 ZUNE_CUSTOMCLASS_10
1151 BootEditor, NULL, MUIC_PrefsEditor, NULL,
1152 OM_NEW, struct opSet *,
1153 MUIM_Setup, Msg,
1154 MUIM_Cleanup, Msg,
1155 MUIM_PrefsEditor_ImportFH, struct MUIP_PrefsEditor_ImportFH *,
1156 MUIM_PrefsEditor_ExportFH, struct MUIP_PrefsEditor_ExportFH *,
1157 MUIM_PrefsEditor_Save, Msg,
1158 MUIM_BootEditor_ShowModule, Msg,
1159 MUIM_BootEditor_UpdateModule, Msg,
1160 MUIM_BootEditor_AddModule, Msg,
1161 MUIM_BootEditor_RemoveModule, Msg