ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/prefs_editor_amiga.cpp
Revision: 1.17
Committed: 2002-01-15T14:58:34Z (22 years, 10 months ago) by cebix
Branch: MAIN
CVS Tags: snapshot-15012002
Changes since 1.16: +1 -1 lines
Log Message:
- documentation updates
- 2001 -> 2002
- version 0.9 -> 1.0

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * prefs_editor_amiga.cpp - Preferences editor, AmigaOS implementation (using gtlayout.library)
3     *
4 cebix 1.17 * Basilisk II (C) 1997-2002 Christian Bauer
5 cebix 1.1 *
6     * This program is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19     */
20    
21     #include <exec/types.h>
22     #include <exec/memory.h>
23     #include <dos/dos.h>
24     #include <dos/dosextens.h>
25     #include <dos/filehandler.h>
26     #include <intuition/intuition.h>
27     #include <libraries/asl.h>
28     #include <libraries/gtlayout.h>
29     #include <libraries/Picasso96.h>
30 cebix 1.13 #include <cybergraphics/cybergraphics.h>
31 cebix 1.1 #include <graphics/displayinfo.h>
32     #include <devices/ahi.h>
33     #include <proto/exec.h>
34     #include <proto/dos.h>
35     #include <proto/intuition.h>
36     #include <proto/gadtools.h>
37     #include <proto/gtlayout.h>
38     #include <proto/graphics.h>
39     #include <proto/asl.h>
40     #include <proto/Picasso96.h>
41 cebix 1.12 #include <proto/cybergraphics.h>
42 cebix 1.1 #include <proto/ahi.h>
43    
44     #include "sysdeps.h"
45     #include "main.h"
46     #include "xpram.h"
47     #include "cdrom.h"
48     #include "user_strings.h"
49     #include "version.h"
50     #include "prefs.h"
51     #include "prefs_editor.h"
52    
53    
54     // Gadget/menu IDs
55     const int MSG_OK = 0x0100; // "Start" button
56     const int MSG_CANCEL = 0x0101; // "Quit" button
57     const int MSG_ABOUT = 0x0102; // "About..." menu item
58     const int MSG_ZAP_PRAM = 0x0103; // "Zap PRAM" menu item
59    
60     const int GAD_PAGEGROUP = 0x0200;
61    
62     const int GAD_DISK_LIST = 0x0300; // "Volumes" pane
63     const int GAD_ADD_VOLUME = 0x0301;
64     const int GAD_EDIT_VOLUME = 0x0302;
65     const int GAD_REMOVE_VOLUME = 0x0303;
66     const int GAD_CDROM_DEVICE = 0x0304;
67     const int GAD_CDROM_UNIT = 0x0305;
68     const int GAD_BOOTDRIVER = 0x0306;
69     const int GAD_NOCDROM = 0x0307;
70 cebix 1.5 const int GAD_EXTFS = 0x0308;
71 cebix 1.1
72     const int GAD_VOLUME_READONLY = 0x0310; // "Add/Edit Volume" window
73     const int GAD_VOLUME_TYPE = 0x0311;
74     const int GAD_VOLUME_FILE = 0x0312;
75     const int GAD_VOLUME_DEVICE = 0x0313;
76     const int GAD_VOLUME_UNIT = 0x0314;
77     const int GAD_VOLUME_OPENFLAGS = 0x0315;
78     const int GAD_VOLUME_STARTBLOCK = 0x0316;
79     const int GAD_VOLUME_SIZE = 0x0317;
80     const int GAD_VOLUME_BLOCKSIZE = 0x0318;
81     const int GAD_VOLUME_PAGEGROUP = 0x0319;
82    
83     const int GAD_SCSI0_DEVICE = 0x0400; // "SCSI" pane
84     const int GAD_SCSI1_DEVICE = 0x0401;
85     const int GAD_SCSI2_DEVICE = 0x0402;
86     const int GAD_SCSI3_DEVICE = 0x0403;
87     const int GAD_SCSI4_DEVICE = 0x0404;
88     const int GAD_SCSI5_DEVICE = 0x0405;
89     const int GAD_SCSI6_DEVICE = 0x0406;
90     const int GAD_SCSI0_UNIT = 0x0410;
91     const int GAD_SCSI1_UNIT = 0x0411;
92     const int GAD_SCSI2_UNIT = 0x0412;
93     const int GAD_SCSI3_UNIT = 0x0413;
94     const int GAD_SCSI4_UNIT = 0x0414;
95     const int GAD_SCSI5_UNIT = 0x0415;
96     const int GAD_SCSI6_UNIT = 0x0416;
97 cebix 1.16 const int GAD_SCSI_MEMTYPE = 0x0420;
98 cebix 1.1
99     const int GAD_VIDEO_TYPE = 0x0500; // "Graphics/Sound" pane
100     const int GAD_DISPLAY_X = 0x0501;
101     const int GAD_DISPLAY_Y = 0x0502;
102     const int GAD_FRAMESKIP = 0x0503;
103     const int GAD_SCREEN_MODE = 0x0504;
104     const int GAD_AHI_MODE = 0x0505;
105     const int GAD_NOSOUND = 0x0506;
106    
107     const int GAD_SERIALA_DEVICE = 0x0600; // "Serial/Network" pane
108     const int GAD_SERIALA_UNIT = 0x0601;
109     const int GAD_SERIALA_ISPAR = 0x0602;
110     const int GAD_SERIALB_DEVICE = 0x0603;
111     const int GAD_SERIALB_UNIT = 0x0604;
112     const int GAD_SERIALB_ISPAR = 0x0605;
113     const int GAD_ETHER_DEVICE = 0x0606;
114     const int GAD_ETHER_UNIT = 0x00607;
115    
116     const int GAD_RAMSIZE = 0x0700; // "Memory/Misc" pane
117     const int GAD_MODELID = 0x0701;
118     const int GAD_ROM_FILE = 0x0702;
119    
120    
121     // Global variables
122     struct Library *GTLayoutBase = NULL;
123     static struct FileRequester *dev_request = NULL, *file_request = NULL;
124    
125     // gtlayout.library macros
126     #define VGROUP LT_New(h, LA_Type, VERTICAL_KIND, TAG_END)
127     #define HGROUP LT_New(h, LA_Type, HORIZONTAL_KIND, TAG_END)
128     #define ENDGROUP LT_EndGroup(h)
129    
130     // Prototypes
131     static void create_volumes_pane(struct LayoutHandle *h);
132     static void create_scsi_pane(struct LayoutHandle *h);
133     static void create_graphics_pane(struct LayoutHandle *h);
134     static void create_serial_pane(struct LayoutHandle *h);
135     static void create_memory_pane(struct LayoutHandle *h);
136     static void add_edit_volume(struct LayoutHandle *h, bool adding);
137     static void remove_volume(struct LayoutHandle *h);
138     static void ghost_volumes_gadgets(struct LayoutHandle *h);
139     static void ghost_graphics_gadgets(struct LayoutHandle *h);
140     static void screen_mode_req(struct Window *win, struct LayoutHandle *h);
141     static void ahi_mode_req(struct Window *win, struct LayoutHandle *h);
142     static void read_settings(struct LayoutHandle *h);
143    
144    
145     /*
146 cebix 1.2 * Locale hook - returns string for given ID
147 cebix 1.1 */
148    
149 cebix 1.3 static __saveds __attribute__((regparm(3))) const char *locale_hook_func(struct Hook *hook /*a0*/, void *id /*a1*/, struct LayoutHandle *h /*a2*/)
150 cebix 1.1 {
151 cebix 1.2 return GetString((uint32)id);
152 cebix 1.1 }
153    
154     struct Hook locale_hook = {{NULL, NULL}, (HOOKFUNC)locale_hook_func, NULL, NULL};
155    
156    
157     /*
158     * Show preferences editor
159     * Returns true when user clicked on "Start", false otherwise
160     */
161    
162     bool PrefsEditor(void)
163     {
164     bool retval = true, done = false;
165     struct LayoutHandle *h = NULL;
166     struct Window *win = NULL;
167     struct Menu *menu = NULL;
168    
169 cebix 1.2 // Pane tabs
170     static const LONG labels[] = {
171     STR_VOLUMES_PANE_TITLE,
172     STR_SCSI_PANE_TITLE,
173     STR_GRAPHICS_SOUND_PANE_TITLE,
174     STR_SERIAL_NETWORK_PANE_TITLE,
175     STR_MEMORY_MISC_PANE_TITLE,
176     -1
177     };
178    
179 cebix 1.1 // Open gtlayout.library
180     GTLayoutBase = (struct Library *)OpenLibrary((UBYTE *)"gtlayout.library", 39);
181     if (GTLayoutBase == NULL) {
182     WarningAlert(GetString(STR_NO_GTLAYOUT_LIB_WARN));
183 cebix 1.2 return true;
184 cebix 1.1 }
185    
186     // Create layout handle
187     h = LT_CreateHandleTags(NULL,
188     LAHN_AutoActivate, FALSE,
189 cebix 1.2 LAHN_LocaleHook, (ULONG)&locale_hook,
190 cebix 1.1 TAG_END
191     );
192     if (h == NULL)
193     goto quit;
194    
195     // Create menus
196     menu = LT_NewMenuTags(
197 cebix 1.2 LAMN_LayoutHandle, (ULONG)h,
198 cebix 1.1 LAMN_TitleID, STR_PREFS_MENU,
199     LAMN_ItemID, STR_PREFS_ITEM_ABOUT,
200     LAMN_UserData, MSG_ABOUT,
201 cebix 1.2 LAMN_ItemText, (ULONG)NM_BARLABEL,
202 cebix 1.1 LAMN_ItemID, STR_PREFS_ITEM_START,
203     LAMN_UserData, MSG_OK,
204     LAMN_ItemID, STR_PREFS_ITEM_ZAP_PRAM,
205     LAMN_UserData, MSG_ZAP_PRAM,
206 cebix 1.2 LAMN_ItemText, (ULONG)NM_BARLABEL,
207 cebix 1.1 LAMN_ItemID, STR_PREFS_ITEM_QUIT,
208     LAMN_UserData, MSG_CANCEL,
209 cebix 1.2 LAMN_KeyText, (ULONG)"Q",
210 cebix 1.1 TAG_END
211     );
212    
213     // Create window contents
214     VGROUP;
215     VGROUP;
216     LT_New(h, LA_Type, TAB_KIND,
217 cebix 1.2 LATB_LabelTable, (ULONG)labels,
218 cebix 1.1 LATB_AutoPageID, GAD_PAGEGROUP,
219     LATB_FullWidth, TRUE,
220     TAG_END
221     );
222     ENDGROUP;
223    
224     // Panes
225     LT_New(h, LA_Type, VERTICAL_KIND,
226     LA_ID, GAD_PAGEGROUP,
227     LAGR_ActivePage, 0,
228     TAG_END
229     );
230     create_volumes_pane(h);
231     create_scsi_pane(h);
232     create_graphics_pane(h);
233     create_serial_pane(h);
234     create_memory_pane(h);
235     ENDGROUP;
236    
237     // Separator between tabs and buttons
238     VGROUP;
239     LT_New(h, LA_Type, XBAR_KIND,
240     LAXB_FullSize, TRUE,
241     TAG_END
242     );
243     ENDGROUP;
244    
245     // "Start" and "Quit" buttons
246     LT_New(h, LA_Type, HORIZONTAL_KIND,
247     LAGR_SameSize, TRUE,
248     LAGR_Spread, TRUE,
249     TAG_END
250     );
251     LT_New(h, LA_Type, BUTTON_KIND,
252     LA_LabelID, STR_START_BUTTON,
253     LA_ID, MSG_OK,
254     LABT_ReturnKey, TRUE,
255     TAG_END
256     );
257     LT_New(h, LA_Type, BUTTON_KIND,
258     LA_LabelID, STR_QUIT_BUTTON,
259     LA_ID, MSG_CANCEL,
260     LABT_EscKey, TRUE,
261     TAG_END
262     );
263     ENDGROUP;
264     ENDGROUP;
265    
266     // Open window
267     win = LT_Build(h,
268     LAWN_TitleID, STR_PREFS_TITLE,
269 cebix 1.2 LAWN_Menu, (ULONG)menu,
270 cebix 1.1 LAWN_IDCMP, IDCMP_CLOSEWINDOW,
271     LAWN_BelowMouse, TRUE,
272     LAWN_SmartZoom, TRUE,
273     WA_SimpleRefresh, TRUE,
274     WA_Activate, TRUE,
275     WA_CloseGadget, TRUE,
276     WA_DepthGadget, TRUE,
277     WA_DragBar, TRUE,
278     TAG_END
279     );
280     if (win == NULL)
281     goto quit;
282    
283     // Create file requesters
284     dev_request = (struct FileRequester *)AllocAslRequestTags(ASL_FileRequest,
285     ASLFR_DoPatterns, TRUE,
286     ASLFR_RejectIcons, TRUE,
287 cebix 1.2 ASLFR_InitialDrawer, (ULONG)"DEVS:",
288     ASLFR_InitialPattern, (ULONG)"#?.device",
289 cebix 1.1 TAG_END
290     );
291     file_request = (struct FileRequester *)AllocAslRequestTags(ASL_FileRequest,
292     ASLFR_DoPatterns, TRUE,
293     ASLFR_RejectIcons, TRUE,
294 cebix 1.2 ASLFR_InitialPattern, (ULONG)"#?",
295 cebix 1.1 TAG_END
296     );
297    
298     // Event loop
299     do {
300     struct IntuiMessage *msg;
301    
302     // Wait for message
303     WaitPort(win->UserPort);
304    
305     // Get pending messages
306     while (msg = LT_GetIMsg(h)) {
307    
308     // Get data from message and reply
309     ULONG cl = msg->Class;
310     UWORD code = msg->Code;
311     struct Gadget *gad = (struct Gadget *)msg->IAddress;
312     LT_ReplyIMsg(msg);
313    
314     // Handle message according to class
315     switch (cl) {
316     case IDCMP_CLOSEWINDOW:
317     retval = false;
318     done = true;
319     break;
320    
321     case IDCMP_GADGETUP:
322     switch (gad->GadgetID) {
323     case MSG_OK:
324     read_settings(h);
325     SavePrefs();
326     retval = true;
327     done = true;
328     break;
329    
330     case MSG_CANCEL:
331     retval = false;
332     done = true;
333     break;
334    
335     case GAD_DISK_LIST:
336     ghost_volumes_gadgets(h);
337     break;
338    
339     case GAD_ADD_VOLUME:
340     LT_LockWindow(win);
341     add_edit_volume(h, true);
342     LT_UnlockWindow(win);
343     break;
344    
345     case GAD_EDIT_VOLUME:
346     LT_LockWindow(win);
347     add_edit_volume(h, false);
348     LT_UnlockWindow(win);
349     break;
350    
351     case GAD_REMOVE_VOLUME:
352     remove_volume(h);
353     break;
354    
355     case GAD_BOOTDRIVER:
356     switch (code) {
357     case 0:
358 cebix 1.14 PrefsReplaceInt32("bootdriver", 0);
359 cebix 1.1 break;
360     case 1:
361 cebix 1.14 PrefsReplaceInt32("bootdriver", CDROMRefNum);
362 cebix 1.1 break;
363     }
364     break;
365    
366 cebix 1.16 case GAD_SCSI_MEMTYPE:
367     PrefsReplaceInt32("scsimemtype", code);
368     break;
369    
370 cebix 1.1 case GAD_VIDEO_TYPE:
371     ghost_graphics_gadgets(h);
372     break;
373    
374     case GAD_FRAMESKIP:
375     switch (code) {
376     case 0:
377     PrefsReplaceInt32("frameskip", 12);
378     break;
379     case 1:
380     PrefsReplaceInt32("frameskip", 8);
381     break;
382     case 2:
383     PrefsReplaceInt32("frameskip", 6);
384     break;
385     case 3:
386     PrefsReplaceInt32("frameskip", 4);
387     break;
388     case 4:
389     PrefsReplaceInt32("frameskip", 2);
390     break;
391     case 5:
392     PrefsReplaceInt32("frameskip", 1);
393     break;
394     }
395     break;
396    
397     case GAD_MODELID:
398     switch (code) {
399     case 0:
400     PrefsReplaceInt32("modelid", 5);
401     break;
402     case 1:
403     PrefsReplaceInt32("modelid", 14);
404     break;
405     }
406     break;
407     }
408     break;
409    
410     case IDCMP_IDCMPUPDATE:
411     switch (gad->GadgetID) {
412     case GAD_DISK_LIST: // Double-click on volumes list = edit volume
413     LT_LockWindow(win);
414     add_edit_volume(h, false);
415     LT_UnlockWindow(win);
416     break;
417    
418     case GAD_SCREEN_MODE:
419     screen_mode_req(win, h);
420     break;
421    
422     case GAD_AHI_MODE:
423     ahi_mode_req(win, h);
424     break;
425    
426     case GAD_CDROM_DEVICE:
427     case GAD_SCSI0_DEVICE:
428     case GAD_SCSI1_DEVICE:
429     case GAD_SCSI2_DEVICE:
430     case GAD_SCSI3_DEVICE:
431     case GAD_SCSI4_DEVICE:
432     case GAD_SCSI5_DEVICE:
433     case GAD_SCSI6_DEVICE:
434     case GAD_SERIALA_DEVICE:
435     case GAD_SERIALB_DEVICE:
436 jlachmann 1.11 if (dev_request) {
437     LT_LockWindow(win);
438     BOOL result = AslRequestTags(dev_request,
439     ASLFR_Window, (ULONG)win,
440     ASLFR_InitialDrawer, (ULONG) "Devs:",
441     TAG_END);
442     LT_UnlockWindow(win);
443     if (result) {
444     char *str;
445     GT_GetGadgetAttrs(gad, win, NULL, GTST_String, (ULONG)&str, TAG_END);
446     strncpy(str, dev_request->rf_File, 255); // Don't copy the directory part. This is usually "DEVS:" and we don't need that.
447     str[255] = 0;
448     LT_SetAttributes(h, gad->GadgetID, GTST_String, (ULONG)str, TAG_END);
449     }
450     }
451     break;
452    
453 cebix 1.1 case GAD_ETHER_DEVICE:
454     if (dev_request) {
455     LT_LockWindow(win);
456 jlachmann 1.11 BOOL result = AslRequestTags(dev_request,
457     ASLFR_Window, (ULONG)win,
458     ASLFR_InitialDrawer, (ULONG) "Devs:Networks",
459     TAG_END);
460 cebix 1.1 LT_UnlockWindow(win);
461     if (result) {
462     char *str;
463 cebix 1.2 GT_GetGadgetAttrs(gad, win, NULL, GTST_String, (ULONG)&str, TAG_END);
464 cebix 1.1 strncpy(str, dev_request->rf_File, 255); // Don't copy the directory part. This is usually "DEVS:" and we don't need that.
465     str[255] = 0;
466 cebix 1.2 LT_SetAttributes(h, gad->GadgetID, GTST_String, (ULONG)str, TAG_END);
467 cebix 1.1 }
468     }
469     break;
470    
471     case GAD_ROM_FILE:
472     if (file_request) {
473     LT_LockWindow(win);
474 cebix 1.2 BOOL result = AslRequestTags(file_request, ASLFR_Window, (ULONG)win, TAG_END);
475 cebix 1.1 LT_UnlockWindow(win);
476     if (result) {
477     char *str;
478 cebix 1.2 GT_GetGadgetAttrs(gad, win, NULL, GTST_String, (ULONG)&str, TAG_END);
479 cebix 1.1 strncpy(str, file_request->rf_Dir, 255);
480     str[255] = 0;
481     AddPart(str, file_request->rf_File, 255);
482 cebix 1.2 LT_SetAttributes(h, gad->GadgetID, GTST_String, (ULONG)str, TAG_END);
483 cebix 1.1 }
484     }
485     break;
486     }
487     break;
488    
489     case IDCMP_MENUPICK:
490     while (code != MENUNULL) {
491     struct MenuItem *item = ItemAddress(menu, code);
492     if (item == NULL)
493     break;
494     switch ((ULONG)GTMENUITEM_USERDATA(item)) {
495     case MSG_OK:
496     read_settings(h);
497     SavePrefs();
498     retval = true;
499     done = true;
500     break;
501    
502     case MSG_CANCEL:
503     retval = false;
504     done = true;
505     break;
506    
507     case MSG_ABOUT: {
508     char str[256];
509     sprintf(str, GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR);
510     strncat(str, "\n", 255);
511     strncat(str, GetString(STR_ABOUT_TEXT2), 255);
512    
513     EasyStruct req;
514     req.es_StructSize = sizeof(EasyStruct);
515     req.es_Flags = 0;
516     req.es_Title = (UBYTE *)GetString(STR_ABOUT_TITLE);
517     req.es_TextFormat = (UBYTE *)str;
518     req.es_GadgetFormat = (UBYTE *)GetString(STR_OK_BUTTON);
519     LT_LockWindow(win);
520     EasyRequest(win, &req, NULL);
521     LT_UnlockWindow(win);
522     break;
523     }
524    
525     case MSG_ZAP_PRAM:
526     ZapPRAM();
527     break;
528     }
529     code = item->NextSelect;
530     }
531     break;
532     }
533     }
534     } while (!done);
535    
536     quit:
537     // Free requesters
538     FreeAslRequest(dev_request);
539     FreeAslRequest(file_request);
540    
541 cebix 1.12 // Delete Menus
542 cebix 1.9 LT_DisposeMenu(menu);
543    
544 cebix 1.1 // Delete handle
545     LT_DeleteHandle(h);
546    
547     // Close gtlayout.library
548     CloseLibrary(GTLayoutBase);
549     return retval;
550     }
551    
552    
553     /*
554     * "Volumes" pane
555     */
556    
557     static struct List disk_list;
558 cebix 1.5 static char cdrom_name[256], extfs_name[256];
559 cebix 1.1 static ULONG cdrom_unit, cdrom_flags, cdrom_start, cdrom_size, cdrom_bsize;
560     static BYTE bootdriver_num, nocdrom;
561    
562     // Read volumes preferences
563     static void parse_volumes_prefs(void)
564     {
565     NewList(&disk_list);
566     const char *str;
567     for (int i=0; (str = PrefsFindString("disk", i)) != NULL; i++) {
568     struct Node *item = (struct Node *)AllocMem(sizeof(struct Node), MEMF_CLEAR);
569     item->ln_Name = (char *)str;
570     AddTail(&disk_list, item);
571     }
572    
573     cdrom_name[0] = 0;
574     cdrom_unit = 0; cdrom_flags = 0; cdrom_start = 0; cdrom_size = 0; cdrom_bsize = 2048;
575    
576     str = PrefsFindString("cdrom");
577     if (str)
578     sscanf(str, "/dev/%[^/]/%ld/%ld/%ld/%ld/%ld", cdrom_name, &cdrom_unit, &cdrom_flags, &cdrom_start, &cdrom_size, &cdrom_bsize);
579    
580     bootdriver_num = 0;
581    
582 cebix 1.14 int bootdriver = PrefsFindInt32("bootdriver");
583 cebix 1.1 switch (bootdriver) {
584     case 0:
585     bootdriver_num = 0;
586     break;
587     case CDROMRefNum:
588     bootdriver_num = 1;
589     break;
590     }
591    
592     nocdrom = PrefsFindBool("nocdrom");
593 cebix 1.5
594     extfs_name[0] = 0;
595     str = PrefsFindString("extfs");
596     if (str)
597     strncpy(extfs_name, str, sizeof(extfs_name) - 1);
598 cebix 1.1 }
599    
600     // Ghost/unghost "Edit" and "Remove" buttons
601     static void ghost_volumes_gadgets(struct LayoutHandle *h)
602     {
603     UWORD sel = LT_GetAttributes(h, GAD_DISK_LIST, TAG_END);
604     if (sel == 0xffff) {
605     LT_SetAttributes(h, GAD_EDIT_VOLUME, GA_Disabled, TRUE, TAG_END);
606     LT_SetAttributes(h, GAD_REMOVE_VOLUME, GA_Disabled, TRUE, TAG_END);
607     } else {
608     LT_SetAttributes(h, GAD_EDIT_VOLUME, GA_Disabled, FALSE, TAG_END);
609     LT_SetAttributes(h, GAD_REMOVE_VOLUME, GA_Disabled, FALSE, TAG_END);
610     }
611     }
612    
613     // Get device data from partition name
614     static void analyze_partition(const char *part, char *dev_name, ULONG &dev_unit, ULONG &dev_flags, ULONG &dev_start, ULONG &dev_size, ULONG &dev_bsize)
615     {
616     // Remove everything after and including the ':'
617     char str[256];
618     strncpy(str, part, sizeof(str) - 1);
619     str[sizeof(str) - 1] = 0;
620     char *colon = strchr(str, ':');
621     if (colon)
622     *colon = 0;
623    
624     // Look for partition
625     struct DosList *dl = LockDosList(LDF_DEVICES | LDF_READ);
626     dl = FindDosEntry(dl, str, LDF_DEVICES);
627     if (dl) {
628     // Get File System Startup Message
629     struct FileSysStartupMsg *fssm = (struct FileSysStartupMsg *)(dl->dol_misc.dol_handler.dol_Startup << 2);
630     if (fssm) {
631     // Get DOS environment vector
632     struct DosEnvec *de = (struct DosEnvec *)(fssm->fssm_Environ << 2);
633     if (de && de->de_TableSize >= DE_UPPERCYL) {
634     // Read settings from FSSM and Envec
635     strncpy(dev_name, (char *)(fssm->fssm_Device << 2) + 1, 255);
636     dev_name[255] = 0;
637     dev_unit = fssm->fssm_Unit;
638     dev_flags = fssm->fssm_Flags;
639     dev_start = de->de_BlocksPerTrack * de->de_Surfaces * de->de_LowCyl;
640     dev_size = de->de_BlocksPerTrack * de->de_Surfaces * (de->de_HighCyl - de->de_LowCyl + 1);
641     dev_bsize = de->de_SizeBlock << 2;
642     }
643     }
644     }
645     UnLockDosList(LDF_DEVICES | LDF_READ);
646     }
647    
648     // Display and handle "Add/Edit Volume" window
649     static void add_edit_volume(struct LayoutHandle *h2, bool adding)
650     {
651     bool ok_clicked = false;
652    
653     UWORD sel = LT_GetAttributes(h2, GAD_DISK_LIST, TAG_END);
654     if ((sel == 0xffff) && !adding)
655     return;
656    
657     char dev_name[256] = "";
658     char file_name[256] = "";
659     ULONG dev_unit = 0, dev_flags = 0, dev_start = 0, dev_size = 0, dev_bsize = 512;
660     BYTE read_only = false, is_device = false;
661    
662     if (!adding) {
663     const char *str = PrefsFindString("disk", sel);
664     if (str == NULL)
665     return;
666     if (str[0] == '*') {
667     read_only = true;
668     str++;
669     }
670     if (strstr(str, "/dev/") == str) {
671     is_device = true;
672     sscanf(str, "/dev/%[^/]/%ld/%ld/%ld/%ld/%ld", dev_name, &dev_unit, &dev_flags, &dev_start, &dev_size, &dev_bsize);
673     } else {
674     strncpy(file_name, str, sizeof(file_name) - 1);
675     file_name[sizeof(file_name) - 1] = 0;
676     }
677     }
678    
679     // Create layout handle
680     struct LayoutHandle *h = NULL;
681     struct Window *win = NULL;
682     h = LT_CreateHandleTags(NULL,
683     LAHN_AutoActivate, FALSE,
684 cebix 1.2 LAHN_LocaleHook, (ULONG)&locale_hook,
685 cebix 1.1 TAG_END
686     );
687     if (h == NULL)
688     return;
689    
690     // Create window contents
691     VGROUP;
692     // Volume gadgets
693     VGROUP;
694     LT_New(h, LA_Type, CHECKBOX_KIND,
695     LA_LabelID, STR_VOL_READONLY_CTRL,
696     LA_ID, GAD_VOLUME_READONLY,
697 cebix 1.2 LA_BYTE, (ULONG)&read_only,
698 cebix 1.1 TAG_END
699     );
700     LT_New(h, LA_Type, CYCLE_KIND,
701     LA_LabelID, STR_VOL_TYPE_CTRL,
702     LA_ID, GAD_VOLUME_TYPE,
703     LACY_AutoPageID, GAD_VOLUME_PAGEGROUP,
704     LACY_FirstLabel, STR_VOL_FILE_LAB,
705     LACY_LastLabel, STR_VOL_DEVICE_LAB,
706 cebix 1.2 LA_BYTE, (ULONG)&is_device,
707 cebix 1.1 TAG_END
708     );
709     ENDGROUP;
710     LT_New(h, LA_Type, VERTICAL_KIND,
711     LA_ID, GAD_VOLUME_PAGEGROUP,
712     LAGR_ActivePage, is_device,
713     TAG_END
714     );
715     VGROUP;
716     LT_New(h, LA_Type, STRING_KIND,
717     LA_LabelID, STR_VOL_FILE_CTRL,
718     LA_ID, GAD_VOLUME_FILE,
719     LA_Chars, 20,
720 cebix 1.2 LA_STRPTR, (ULONG)file_name,
721 cebix 1.1 GTST_MaxChars, sizeof(file_name) - 1,
722     LAST_Picker, TRUE,
723     TAG_END
724     );
725     ENDGROUP;
726     VGROUP;
727     LT_New(h, LA_Type, STRING_KIND,
728     LA_LabelID, STR_DEVICE_CTRL,
729     LA_ID, GAD_VOLUME_DEVICE,
730     LA_Chars, 20,
731 cebix 1.2 LA_STRPTR, (ULONG)dev_name,
732 cebix 1.1 GTST_MaxChars, sizeof(dev_name) - 1,
733     LAST_Picker, TRUE,
734     TAG_END
735     );
736     LT_New(h, LA_Type, INTEGER_KIND,
737     LA_LabelID, STR_UNIT_CTRL,
738     LA_ID, GAD_VOLUME_UNIT,
739 cebix 1.2 LA_LONG, (ULONG)&dev_unit,
740 cebix 1.1 LAIN_UseIncrementers, TRUE,
741     GTIN_MaxChars, 8,
742     TAG_END
743     );
744     LT_New(h, LA_Type, INTEGER_KIND,
745     LA_LabelID, STR_VOL_OPENFLAGS_CTRL,
746     LA_ID, GAD_VOLUME_OPENFLAGS,
747 cebix 1.2 LA_LONG, (ULONG)&dev_flags,
748 cebix 1.1 LAIN_UseIncrementers, TRUE,
749     GTIN_MaxChars, 8,
750     TAG_END
751     );
752     LT_New(h, LA_Type, INTEGER_KIND,
753     LA_LabelID, STR_VOL_STARTBLOCK_CTRL,
754     LA_ID, GAD_VOLUME_STARTBLOCK,
755 cebix 1.2 LA_LONG, (ULONG)&dev_start,
756 cebix 1.1 LAIN_UseIncrementers, TRUE,
757     GTIN_MaxChars, 8,
758     TAG_END
759     );
760     LT_New(h, LA_Type, INTEGER_KIND,
761     LA_LabelID, STR_VOL_SIZE_CTRL,
762     LA_ID, GAD_VOLUME_SIZE,
763 cebix 1.2 LA_LONG, (ULONG)&dev_size,
764 cebix 1.1 LAIN_UseIncrementers, TRUE,
765     GTIN_MaxChars, 8,
766     TAG_END
767     );
768     LT_New(h, LA_Type, INTEGER_KIND,
769     LA_LabelID, STR_VOL_BLOCKSIZE_CTRL,
770     LA_ID, GAD_VOLUME_BLOCKSIZE,
771 cebix 1.2 LA_LONG, (ULONG)&dev_bsize,
772 cebix 1.1 LAIN_UseIncrementers, TRUE,
773     GTIN_MaxChars, 8,
774     TAG_END
775     );
776     ENDGROUP;
777     ENDGROUP;
778    
779     // Separator between gadgets and buttons
780     VGROUP;
781     LT_New(h, LA_Type, XBAR_KIND,
782     LAXB_FullSize, TRUE,
783     TAG_END
784     );
785     ENDGROUP;
786    
787     // "OK" and "Cancel" buttons
788     LT_New(h, LA_Type, HORIZONTAL_KIND,
789     LAGR_SameSize, TRUE,
790     LAGR_Spread, TRUE,
791     TAG_END
792     );
793     LT_New(h, LA_Type, BUTTON_KIND,
794     LA_LabelID, STR_OK_BUTTON,
795     LA_ID, MSG_OK,
796     LABT_ReturnKey, TRUE,
797     TAG_END
798     );
799     LT_New(h, LA_Type, BUTTON_KIND,
800     LA_LabelID, STR_CANCEL_BUTTON,
801     LA_ID, MSG_CANCEL,
802     LABT_EscKey, TRUE,
803     TAG_END
804     );
805     ENDGROUP;
806     ENDGROUP;
807    
808     // Open window
809     win = LT_Build(h,
810     LAWN_TitleID, adding ? STR_ADD_VOLUME_TITLE : STR_EDIT_VOLUME_TITLE,
811     LAWN_IDCMP, IDCMP_CLOSEWINDOW,
812     LAWN_BelowMouse, TRUE,
813     LAWN_SmartZoom, TRUE,
814     WA_SimpleRefresh, TRUE,
815     WA_Activate, TRUE,
816     WA_CloseGadget, TRUE,
817     WA_DepthGadget, TRUE,
818     WA_DragBar, TRUE,
819     TAG_END
820     );
821     if (win == NULL) {
822     LT_DeleteHandle(h);
823     return;
824     }
825    
826     // Event loop
827     bool done = false;
828     do {
829     struct IntuiMessage *msg;
830    
831     // Wait for message
832     WaitPort(win->UserPort);
833    
834     // Get pending messages
835     while (msg = LT_GetIMsg(h)) {
836    
837     // Get data from message and reply
838     ULONG cl = msg->Class;
839     UWORD code = msg->Code;
840     struct Gadget *gad = (struct Gadget *)msg->IAddress;
841     LT_ReplyIMsg(msg);
842    
843     // Handle message according to class
844     switch (cl) {
845     case IDCMP_CLOSEWINDOW:
846     done = true;
847     break;
848    
849     case IDCMP_GADGETUP:
850     switch (gad->GadgetID) {
851     case MSG_OK:
852     ok_clicked = true;
853     done = true;
854     break;
855     case MSG_CANCEL:
856     done = true;
857     break;
858     }
859     break;
860    
861     case IDCMP_IDCMPUPDATE: {
862     struct FileRequester *req = NULL;
863     switch (gad->GadgetID) {
864     case GAD_VOLUME_FILE:
865     req = file_request;
866     goto do_req;
867     case GAD_VOLUME_DEVICE:
868     req = dev_request;
869     do_req: if (req) {
870     LT_LockWindow(win);
871 cebix 1.2 BOOL result = AslRequestTags(req, ASLFR_Window, (ULONG)win, TAG_END);
872 cebix 1.1 LT_UnlockWindow(win);
873     if (result) {
874     char *str;
875 cebix 1.2 GT_GetGadgetAttrs(gad, win, NULL, GTST_String, (ULONG)&str, TAG_END);
876 cebix 1.1 if (gad->GadgetID == GAD_VOLUME_FILE) {
877     strncpy(str, req->rf_Dir, 255);
878     str[255] = 0;
879     AddPart(str, req->rf_File, 255);
880     } else {
881     if (strlen(req->rf_File)) {
882     strncpy(str, req->rf_File, 255); // Don't copy the directory part. This is usually "DEVS:" and we don't need that.
883     str[255] = 0;
884     } else if (strlen(req->rf_Dir) && req->rf_Dir[strlen(req->rf_Dir) - 1] == ':') {
885     analyze_partition(req->rf_Dir, str, dev_unit, dev_flags, dev_start, dev_size, dev_bsize);
886     LT_SetAttributes(h, GAD_VOLUME_UNIT, GTIN_Number, dev_unit, TAG_END);
887     LT_SetAttributes(h, GAD_VOLUME_OPENFLAGS, GTIN_Number, dev_flags, TAG_END);
888     LT_SetAttributes(h, GAD_VOLUME_STARTBLOCK, GTIN_Number, dev_start, TAG_END);
889     LT_SetAttributes(h, GAD_VOLUME_SIZE, GTIN_Number, dev_size, TAG_END);
890     LT_SetAttributes(h, GAD_VOLUME_BLOCKSIZE, GTIN_Number, dev_bsize, TAG_END);
891     }
892     }
893 cebix 1.2 LT_SetAttributes(h, gad->GadgetID, GTST_String, (ULONG)str, TAG_END);
894 cebix 1.1 }
895     }
896     break;
897     }
898     break;
899     }
900     }
901     }
902     } while (!done);
903    
904     // Update preferences and list view
905     if (ok_clicked) {
906     char str[256];
907     LT_UpdateStrings(h);
908    
909     if (is_device)
910     sprintf(str, "%s/dev/%s/%ld/%ld/%ld/%ld/%ld", read_only ? "*" : "", dev_name, dev_unit, dev_flags, dev_start, dev_size, dev_bsize);
911     else
912     sprintf(str, "%s%s", read_only ? "*" : "", file_name);
913     LT_SetAttributes(h2, GAD_DISK_LIST, GTLV_Labels, ~0, TAG_END);
914    
915     if (adding) {
916    
917     // Add new item
918 cebix 1.2 int i;
919 cebix 1.1 PrefsAddString("disk", str);
920     struct Node *item = (struct Node *)AllocMem(sizeof(struct Node), MEMF_CLEAR);
921 cebix 1.2 for (i=0; PrefsFindString("disk", i); i++) ;
922 cebix 1.1 item->ln_Name = (char *)PrefsFindString("disk", i - 1);
923     AddTail(&disk_list, item);
924    
925     } else {
926    
927     // Replace existing item
928     PrefsReplaceString("disk", str, sel);
929     struct Node *item = disk_list.lh_Head;
930     for (int i=0; item->ln_Succ; i++) {
931     if (i == sel) {
932     item->ln_Name = (char *)PrefsFindString("disk", sel);
933     break;
934     }
935     item = item->ln_Succ;
936     }
937     }
938 cebix 1.2 LT_SetAttributes(h2, GAD_DISK_LIST, GTLV_Labels, (ULONG)&disk_list, TAG_END);
939 cebix 1.1 ghost_volumes_gadgets(h2);
940     }
941 cebix 1.9
942     // Delete handle
943     LT_DeleteHandle(h);
944 cebix 1.1 }
945    
946     // Remove volume from list
947     static void remove_volume(struct LayoutHandle *h)
948     {
949     UWORD sel = LT_GetAttributes(h, GAD_DISK_LIST, TAG_END);
950     if (sel != 0xffff) {
951    
952     // Remove item from preferences and list view
953     LT_SetAttributes(h, GAD_DISK_LIST, GTLV_Labels, ~0, TAG_END);
954     PrefsRemoveItem("disk", sel);
955     struct Node *item = disk_list.lh_Head;
956     for (int i=0; item->ln_Succ; i++) {
957     struct Node *next = item->ln_Succ;
958     if (i == sel) {
959     Remove(item);
960     FreeMem(item, sizeof(struct Node));
961     break;
962     }
963     item = next;
964     }
965 cebix 1.2 LT_SetAttributes(h, GAD_DISK_LIST, GTLV_Labels, (ULONG)&disk_list, GTLV_Selected, 0xffff, TAG_END);
966 cebix 1.1 ghost_volumes_gadgets(h);
967     }
968     }
969    
970     // Read settings from gadgets and set preferences
971     static void read_volumes_settings(void)
972     {
973     struct Node *item = disk_list.lh_Head;
974     while (item->ln_Succ) {
975     struct Node *next = item->ln_Succ;
976     Remove(item);
977     FreeMem(item, sizeof(struct Node));
978     item = next;
979     }
980    
981     if (strlen(cdrom_name)) {
982     char str[256];
983     sprintf(str, "/dev/%s/%ld/%ld/%ld/%ld/%ld", cdrom_name, cdrom_unit, cdrom_flags, cdrom_start, cdrom_size, cdrom_bsize);
984     PrefsReplaceString("cdrom", str);
985     } else
986     PrefsRemoveItem("cdrom");
987    
988     PrefsReplaceBool("nocdrom", nocdrom);
989 cebix 1.5
990     if (strlen(extfs_name))
991     PrefsReplaceString("extfs", extfs_name);
992 cebix 1.1 }
993    
994     // Create "Volumes" pane
995     static void create_volumes_pane(struct LayoutHandle *h)
996     {
997     parse_volumes_prefs();
998    
999     VGROUP;
1000     LT_New(h, LA_Type, VERTICAL_KIND,
1001     LA_LabelID, STR_VOLUMES_CTRL,
1002     TAG_END
1003     );
1004     VGROUP;
1005     LT_New(h, LA_Type, LISTVIEW_KIND,
1006     LA_ID, GAD_DISK_LIST,
1007 cebix 1.5 LA_Chars, 20,
1008 cebix 1.2 GTLV_Labels, (ULONG)&disk_list,
1009 cebix 1.1 LALV_Lines, 6,
1010 cebix 1.2 LALV_Link, (ULONG)NIL_LINK,
1011 cebix 1.1 LALV_ResizeX, TRUE,
1012     LALV_ResizeY, TRUE,
1013     LALV_Selected, 0,
1014     TAG_END
1015     );
1016     ENDGROUP;
1017     LT_New(h, LA_Type, HORIZONTAL_KIND,
1018     LAGR_SameSize, TRUE,
1019     LAGR_Spread, TRUE,
1020     TAG_END
1021     );
1022     LT_New(h, LA_Type, BUTTON_KIND,
1023     LA_LabelID, STR_ADD_VOLUME_BUTTON,
1024     LA_ID, GAD_ADD_VOLUME,
1025     TAG_END
1026     );
1027     LT_New(h, LA_Type, BUTTON_KIND,
1028     LA_LabelID, STR_EDIT_VOLUME_BUTTON,
1029     LA_ID, GAD_EDIT_VOLUME,
1030     TAG_END
1031     );
1032     LT_New(h, LA_Type, BUTTON_KIND,
1033     LA_LabelID, STR_REMOVE_VOLUME_BUTTON,
1034     LA_ID, GAD_REMOVE_VOLUME,
1035     TAG_END
1036     );
1037     ENDGROUP;
1038     ENDGROUP;
1039     LT_New(h, LA_Type, VERTICAL_KIND,
1040     LA_LabelID, STR_CDROM_DRIVE_CTRL,
1041     TAG_END
1042     );
1043     LT_New(h, LA_Type, STRING_KIND,
1044     LA_LabelID, STR_DEVICE_CTRL,
1045     LA_ID, GAD_CDROM_DEVICE,
1046     LA_Chars, 20,
1047 cebix 1.2 LA_STRPTR, (ULONG)cdrom_name,
1048 cebix 1.1 GTST_MaxChars, sizeof(cdrom_name) - 1,
1049     LAST_Picker, TRUE,
1050     TAG_END
1051     );
1052     LT_New(h, LA_Type, INTEGER_KIND,
1053     LA_LabelID, STR_UNIT_CTRL,
1054     LA_ID, GAD_CDROM_UNIT,
1055 cebix 1.2 LA_LONG, (ULONG)&cdrom_unit,
1056 cebix 1.1 LAIN_UseIncrementers, TRUE,
1057     GTIN_MaxChars, 8,
1058     TAG_END
1059     );
1060     LT_New(h, LA_Type, CYCLE_KIND,
1061     LA_LabelID, STR_BOOTDRIVER_CTRL,
1062     LA_ID, GAD_BOOTDRIVER,
1063     LACY_FirstLabel, STR_BOOT_ANY_LAB,
1064     LACY_LastLabel, STR_BOOT_CDROM_LAB,
1065 cebix 1.2 LA_BYTE, (ULONG)&bootdriver_num,
1066 cebix 1.1 TAG_END
1067     );
1068     LT_New(h, LA_Type, CHECKBOX_KIND,
1069     LA_LabelID, STR_NOCDROM_CTRL,
1070     LA_ID, GAD_NOCDROM,
1071 cebix 1.2 LA_BYTE, (ULONG)&nocdrom,
1072 cebix 1.5 TAG_END
1073     );
1074     ENDGROUP;
1075     VGROUP;
1076     LT_New(h, LA_Type, STRING_KIND,
1077     LA_LabelID, STR_EXTFS_CTRL,
1078     LA_ID, GAD_EXTFS,
1079     LA_Chars, 20,
1080     LA_STRPTR, (ULONG)extfs_name,
1081     GTST_MaxChars, sizeof(extfs_name) - 1,
1082 cebix 1.1 TAG_END
1083     );
1084     ENDGROUP;
1085     ENDGROUP;
1086     }
1087    
1088    
1089     /*
1090     * "SCSI" pane
1091     */
1092    
1093     static char scsi_dev[6][256];
1094     static LONG scsi_unit[6];
1095 cebix 1.16 static LONG scsi_memtype;
1096 cebix 1.1
1097     // Read SCSI preferences
1098     static void parse_scsi_prefs(void)
1099     {
1100     for (int i=0; i<7; i++) {
1101     scsi_dev[i][0] = 0;
1102     scsi_unit[i] = 0;
1103    
1104     char prefs_name[16];
1105     sprintf(prefs_name, "scsi%d", i);
1106     const char *str = PrefsFindString(prefs_name);
1107     if (str)
1108     sscanf(str, "%[^/]/%ld", scsi_dev[i], &scsi_unit[i]);
1109     }
1110 cebix 1.16
1111     scsi_memtype = PrefsFindInt32("scsimemtype");
1112 cebix 1.1 }
1113    
1114     // Read settings from gadgets and set preferences
1115     static void read_scsi_settings(void)
1116     {
1117     for (int i=0; i<7; i++) {
1118     char prefs_name[16];
1119     sprintf(prefs_name, "scsi%d", i);
1120    
1121     if (strlen(scsi_dev[i])) {
1122     char str[256];
1123 cebix 1.4 sprintf(str, "%s/%ld", scsi_dev[i], scsi_unit[i]);
1124 cebix 1.1 PrefsReplaceString(prefs_name, str);
1125     } else
1126     PrefsRemoveItem(prefs_name);
1127     }
1128     }
1129    
1130     // Create "SCSI" pane
1131     static void create_scsi_pane(struct LayoutHandle *h)
1132     {
1133     parse_scsi_prefs();
1134    
1135     VGROUP;
1136 cebix 1.16 LT_New(h, LA_Type, VERTICAL_KIND,
1137     LA_LabelID, STR_SCSI_DEVICES_CTRL,
1138     TAG_END
1139     );
1140     for (int i=0; i<7; i++) {
1141     HGROUP;
1142     LT_New(h, LA_Type, TEXT_KIND,
1143     LA_LabelID, STR_SCSI_ID_0 + i,
1144     TAG_END
1145     );
1146     LT_New(h, LA_Type, STRING_KIND,
1147     LA_LabelID, STR_DEVICE_CTRL,
1148     LA_ID, GAD_SCSI0_DEVICE + i,
1149     LA_Chars, 20,
1150     LA_STRPTR, (ULONG)scsi_dev[i],
1151     GTST_MaxChars, sizeof(scsi_dev[i]) - 1,
1152     LAST_Picker, TRUE,
1153     TAG_END
1154     );
1155     LT_New(h, LA_Type, INTEGER_KIND,
1156     LA_LabelID, STR_UNIT_CTRL,
1157     LA_ID, GAD_SCSI0_UNIT + i,
1158     LA_Chars, 4,
1159     LA_LONG, (ULONG)&scsi_unit[i],
1160     LAIN_UseIncrementers, TRUE,
1161     GTIN_MaxChars, 8,
1162     TAG_END
1163     );
1164     ENDGROUP;
1165     }
1166     ENDGROUP;
1167     VGROUP;
1168     LT_New(h, LA_Type, CYCLE_KIND,
1169     LA_LabelID, STR_SCSI_MEMTYPE_CTRL,
1170     LA_ID, GAD_SCSI_MEMTYPE,
1171     LACY_FirstLabel, STR_MEMTYPE_CHIP_LAB,
1172     LACY_LastLabel, STR_MEMTYPE_ANY_LAB,
1173     LA_LONG, (ULONG)&scsi_memtype,
1174     TAG_END
1175     );
1176     ENDGROUP;
1177 cebix 1.1 ENDGROUP;
1178     }
1179    
1180    
1181     /*
1182     * "Graphics/Sound" pane
1183     */
1184    
1185     // Display types
1186     enum {
1187     DISPLAY_WINDOW,
1188     DISPLAY_PIP,
1189     DISPLAY_SCREEN
1190     };
1191    
1192 cebix 1.16 static LONG display_type;
1193 cebix 1.1 static LONG dis_width, dis_height;
1194     static ULONG mode_id;
1195     static BYTE frameskip_num;
1196     static struct NameInfo mode_name;
1197     static ULONG ahi_id;
1198     static char ahi_mode_name[256];
1199     static BYTE nosound;
1200    
1201     // Read graphics preferences
1202     static void parse_graphics_prefs(void)
1203     {
1204     display_type = DISPLAY_WINDOW;
1205     dis_width = 512;
1206     dis_height = 384;
1207     mode_id = 0;
1208     ahi_id = AHI_DEFAULT_ID;
1209     ahi_mode_name[0] = 0;
1210    
1211     frameskip_num = 0;
1212     int frameskip = PrefsFindInt32("frameskip");
1213     switch (frameskip) {
1214     case 12:
1215     frameskip_num = 0;
1216     break;
1217     case 8:
1218     frameskip_num = 1;
1219     break;
1220     case 6:
1221     frameskip_num = 2;
1222     break;
1223     case 4:
1224     frameskip_num = 3;
1225     break;
1226     case 2:
1227     frameskip_num = 4;
1228     break;
1229     case 1:
1230     frameskip_num = 5;
1231     break;
1232     }
1233    
1234     const char *str = PrefsFindString("screen");
1235     if (str) {
1236 cebix 1.16 if (sscanf(str, "win/%ld/%ld", &dis_width, &dis_height) == 2)
1237 cebix 1.1 display_type = DISPLAY_WINDOW;
1238 cebix 1.16 else if (sscanf(str, "pip/%ld/%ld", &dis_width, &dis_height) == 2)
1239 cebix 1.1 display_type = DISPLAY_PIP;
1240     else if (sscanf(str, "scr/%08lx", &mode_id) == 1)
1241     display_type = DISPLAY_SCREEN;
1242     }
1243    
1244     GetDisplayInfoData(NULL, (UBYTE *)&mode_name, sizeof(mode_name), DTAG_NAME, mode_id);
1245    
1246     str = PrefsFindString("sound");
1247     if (str) {
1248     if (sscanf(str, "ahi/%08lx", &ahi_id) == 1 && AHIBase) {
1249     AHI_GetAudioAttrs(ahi_id, NULL,
1250 cebix 1.2 AHIDB_Name, (ULONG)ahi_mode_name,
1251 cebix 1.1 AHIDB_BufferLen, sizeof(ahi_mode_name) - 1,
1252     TAG_END
1253     );
1254     }
1255     }
1256     nosound = PrefsFindBool("nosound");
1257     }
1258    
1259     // Ghost/unghost graphics gadgets, depending on display type
1260     static void ghost_graphics_gadgets(struct LayoutHandle *h)
1261     {
1262     bool dis_xy, dis_skip, dis_mode;
1263     switch (display_type) {
1264     case DISPLAY_WINDOW:
1265     dis_xy = false;
1266     dis_skip = false;
1267     dis_mode = true;
1268     break;
1269     case DISPLAY_PIP:
1270     dis_xy = false;
1271     dis_skip = true;
1272     dis_mode = true;
1273     break;
1274     case DISPLAY_SCREEN:
1275     dis_xy = true;
1276     dis_skip = true;
1277     dis_mode = false;
1278     break;
1279     }
1280     LT_SetAttributes(h, GAD_DISPLAY_X, GA_Disabled, dis_xy, TAG_END);
1281     LT_SetAttributes(h, GAD_DISPLAY_Y, GA_Disabled, dis_xy, TAG_END);
1282     LT_SetAttributes(h, GAD_FRAMESKIP, GA_Disabled, dis_skip, TAG_END);
1283     LT_SetAttributes(h, GAD_SCREEN_MODE, GA_Disabled, dis_mode, TAG_END);
1284     LT_SetAttributes(h, GAD_AHI_MODE, GA_Disabled, AHIBase == NULL, TAG_END);
1285     }
1286    
1287     // Show screen mode requester
1288     static void screen_mode_req(struct Window *win, struct LayoutHandle *h)
1289     {
1290 cebix 1.7 if (P96Base == NULL && CyberGfxBase == NULL)
1291 cebix 1.1 return;
1292    
1293     LT_LockWindow(win);
1294 cebix 1.7
1295     ULONG id;
1296    
1297 cebix 1.12 // Try P96 first, because it also provides a (fake) cybergraphics.library
1298     if (P96Base) {
1299     id = p96RequestModeIDTags(
1300     P96MA_MinDepth, 8,
1301     P96MA_FormatsAllowed, RGBFF_CLUT | RGBFF_R5G5B5 | RGBFF_A8R8G8B8,
1302     TAG_END
1303     );
1304     } else {
1305 jlachmann 1.11 UWORD ModelArray[] = { PIXFMT_LUT8, PIXFMT_RGB15, PIXFMT_ARGB32, 0, ~0 };
1306     id = (ULONG) CModeRequestTags(NULL,
1307     CYBRMREQ_MinDepth, 8,
1308     CYBRMREQ_CModelArray, (ULONG) ModelArray,
1309     TAG_END
1310 cebix 1.8 );
1311 cebix 1.12 }
1312 cebix 1.1 LT_UnlockWindow(win);
1313    
1314     if (id != INVALID_ID) {
1315     mode_id = id;
1316     GetDisplayInfoData(NULL, (UBYTE *)&mode_name, sizeof(mode_name), DTAG_NAME, mode_id);
1317 cebix 1.2 LT_SetAttributes(h, GAD_SCREEN_MODE, GTTX_Text, (ULONG)mode_name.Name, TAG_END);
1318 cebix 1.1 }
1319     }
1320    
1321     // Show AHI mode requester
1322     static void ahi_mode_req(struct Window *win, struct LayoutHandle *h)
1323     {
1324     if (AHIBase == NULL)
1325     return;
1326    
1327     struct AHIAudioModeRequester *req = AHI_AllocAudioRequest(
1328 cebix 1.2 AHIR_Window, (ULONG)win,
1329 cebix 1.1 TAG_END
1330     );
1331     if (req == NULL)
1332     return;
1333    
1334     LT_LockWindow(win);
1335     BOOL ok = AHI_AudioRequest(req,
1336     AHIR_InitialAudioID, ahi_id,
1337     TAG_END
1338     );
1339     LT_UnlockWindow(win);
1340    
1341     if (ok) {
1342     ahi_id = req->ahiam_AudioID;
1343     AHI_GetAudioAttrs(ahi_id, NULL,
1344 cebix 1.2 AHIDB_Name, (ULONG)ahi_mode_name,
1345 cebix 1.1 AHIDB_BufferLen, sizeof(ahi_mode_name) - 1,
1346     TAG_END
1347     );
1348 cebix 1.2 LT_SetAttributes(h, GAD_AHI_MODE, GTTX_Text, (ULONG)ahi_mode_name, TAG_END);
1349 cebix 1.1 }
1350     AHI_FreeAudioRequest(req);
1351     }
1352    
1353     // Read settings from gadgets and set preferences
1354     static void read_graphics_settings(void)
1355     {
1356     char str[256];
1357     switch (display_type) {
1358     case DISPLAY_WINDOW:
1359     sprintf(str, "win/%ld/%ld", dis_width, dis_height);
1360     break;
1361     case DISPLAY_PIP:
1362     sprintf(str, "pip/%ld/%ld", dis_width, dis_height);
1363     break;
1364     case DISPLAY_SCREEN:
1365     sprintf(str, "scr/%08lx", mode_id);
1366     break;
1367     default:
1368     PrefsRemoveItem("screen");
1369     return;
1370     }
1371     PrefsReplaceString("screen", str);
1372    
1373     sprintf(str, "ahi/%08lx", ahi_id);
1374     PrefsReplaceString("sound", str);
1375    
1376     PrefsReplaceBool("nosound", nosound);
1377     }
1378    
1379     // Create "Graphics/Sound" pane
1380     static void create_graphics_pane(struct LayoutHandle *h)
1381     {
1382     parse_graphics_prefs();
1383    
1384     VGROUP;
1385     LT_New(h, LA_Type, VERTICAL_KIND,
1386     LA_LabelID, STR_GRAPHICS_CTRL,
1387     TAG_END
1388     );
1389     static const LONG labels[] = {STR_WINDOW_LAB, STR_PIP_LAB, STR_FULLSCREEN_LAB, -1};
1390     LT_New(h, LA_Type, CYCLE_KIND,
1391     LA_LabelID, STR_VIDEO_TYPE_CTRL,
1392     LA_ID, GAD_VIDEO_TYPE,
1393 cebix 1.2 LACY_LabelTable, (ULONG)labels,
1394 cebix 1.16 LA_LONG, (ULONG)&display_type,
1395 cebix 1.1 TAG_END
1396     );
1397     LT_New(h, LA_Type, INTEGER_KIND,
1398     LA_LabelID, STR_DISPLAY_X_CTRL,
1399     LA_ID, GAD_DISPLAY_X,
1400 cebix 1.2 LA_LONG, (ULONG)&dis_width,
1401 cebix 1.1 GTIN_MaxChars, 8,
1402     TAG_END
1403     );
1404     LT_New(h, LA_Type, INTEGER_KIND,
1405     LA_LabelID, STR_DISPLAY_Y_CTRL,
1406     LA_ID, GAD_DISPLAY_Y,
1407 cebix 1.2 LA_LONG, (ULONG)&dis_height,
1408 cebix 1.1 GTIN_MaxChars, 8,
1409     TAG_END
1410     );
1411     LT_New(h, LA_Type, POPUP_KIND,
1412     LA_LabelID, STR_FRAMESKIP_CTRL,
1413     LA_ID, GAD_FRAMESKIP,
1414     LAPU_FirstLabel, STR_REF_5HZ_LAB,
1415     LAPU_LastLabel, STR_REF_60HZ_LAB,
1416 cebix 1.2 LA_BYTE, (ULONG)&frameskip_num,
1417 cebix 1.1 TAG_END
1418     );
1419     LT_New(h, LA_Type, TEXT_KIND,
1420     LA_LabelID, STR_SCREEN_MODE_CTRL,
1421     LA_ID, GAD_SCREEN_MODE,
1422     LA_Chars, DISPLAYNAMELEN,
1423     LATX_Picker, TRUE,
1424 cebix 1.2 GTTX_Text, (ULONG)mode_name.Name,
1425 cebix 1.1 GTTX_Border, TRUE,
1426     TAG_END
1427     );
1428     ENDGROUP;
1429     LT_New(h, LA_Type, VERTICAL_KIND,
1430     LA_LabelID, STR_SOUND_CTRL,
1431     TAG_END
1432     );
1433     LT_New(h, LA_Type, TEXT_KIND,
1434     LA_LabelID, STR_AHI_MODE_CTRL,
1435     LA_ID, GAD_AHI_MODE,
1436     LA_Chars, DISPLAYNAMELEN,
1437     LATX_Picker, TRUE,
1438 cebix 1.2 GTTX_Text, (ULONG)ahi_mode_name,
1439 cebix 1.1 GTTX_Border, TRUE,
1440     TAG_END
1441     );
1442     LT_New(h, LA_Type, CHECKBOX_KIND,
1443     LA_LabelID, STR_NOSOUND_CTRL,
1444     LA_ID, GAD_NOSOUND,
1445 cebix 1.2 LA_BYTE, (ULONG)&nosound,
1446 cebix 1.1 TAG_END
1447     );
1448     ENDGROUP;
1449     ENDGROUP;
1450    
1451     ghost_graphics_gadgets(h);
1452     }
1453    
1454    
1455     /*
1456     * "Serial/Network" pane
1457     */
1458    
1459     static char seriala_dev[256], serialb_dev[256];
1460     static LONG seriala_unit, serialb_unit;
1461     static BYTE seriala_ispar, serialb_ispar;
1462    
1463     static char ether_dev[256];
1464     static ULONG ether_unit;
1465    
1466     // Read serial/network preferences
1467 cebix 1.2 static void parse_ser_prefs(const char *prefs, char *dev, LONG &unit, BYTE &ispar)
1468 cebix 1.1 {
1469     dev[0] = 0;
1470     unit = 0;
1471     ispar = false;
1472    
1473     const char *str = PrefsFindString(prefs);
1474     if (str) {
1475     if (str[0] == '*') {
1476     ispar = true;
1477     str++;
1478     }
1479     sscanf(str, "%[^/]/%ld", dev, &unit);
1480     }
1481 cebix 1.2 }
1482    
1483     static void parse_serial_prefs(void)
1484     {
1485     parse_ser_prefs("seriala", seriala_dev, seriala_unit, seriala_ispar);
1486     parse_ser_prefs("serialb", serialb_dev, serialb_unit, serialb_ispar);
1487 cebix 1.1
1488     ether_dev[0] = 0;
1489     ether_unit = 0;
1490    
1491 cebix 1.2 const char *str = PrefsFindString("ether");
1492 cebix 1.12 if (str) {
1493 jlachmann 1.11 const char *FirstSlash = strchr(str, '/');
1494     const char *LastSlash = strrchr(str, '/');
1495    
1496 cebix 1.12 if (FirstSlash && FirstSlash && FirstSlash != LastSlash) {
1497 jlachmann 1.11 // Device name contains path, i.e. "Networks/xyzzy.device"
1498     const char *lp = str;
1499     char *dp = ether_dev;
1500    
1501     while (lp != LastSlash)
1502     *dp++ = *lp++;
1503     *dp = '\0';
1504    
1505     sscanf(LastSlash, "/%ld", &ether_unit);
1506    
1507     // printf("dev=<%s> unit=%d\n", ether_dev, ether_unit);
1508 cebix 1.12 } else {
1509 jlachmann 1.11 sscanf(str, "%[^/]/%ld", ether_dev, &ether_unit);
1510     }
1511 cebix 1.12 }
1512 cebix 1.1 }
1513    
1514     // Set serial preference item
1515     static void make_serial_prefs(const char *prefs, const char *dev, LONG unit, BYTE ispar)
1516     {
1517     if (strlen(dev)) {
1518     char str[256];
1519     sprintf(str, "%s%s/%ld", ispar ? "*" : "", dev, unit);
1520     PrefsReplaceString(prefs, str);
1521     } else
1522     PrefsRemoveItem(prefs);
1523     }
1524    
1525     // Read settings from gadgets and set preferences
1526     static void read_serial_settings(void)
1527     {
1528     make_serial_prefs("seriala", seriala_dev, seriala_unit, seriala_ispar);
1529     make_serial_prefs("serialb", serialb_dev, serialb_unit, serialb_ispar);
1530    
1531     if (strlen(ether_dev)) {
1532     char str[256];
1533 jlachmann 1.11
1534 cebix 1.1 sprintf(str, "%s/%ld", ether_dev, ether_unit);
1535     PrefsReplaceString("ether", str);
1536     } else
1537     PrefsRemoveItem("ether");
1538     }
1539    
1540     // Create "Serial/Network" pane
1541     static void create_serial_pane(struct LayoutHandle *h)
1542     {
1543 cebix 1.2 parse_serial_prefs();
1544 cebix 1.1
1545     VGROUP;
1546     LT_New(h, LA_Type, VERTICAL_KIND,
1547     LA_LabelID, STR_SERIALA_CTRL,
1548     TAG_END
1549     );
1550     LT_New(h, LA_Type, STRING_KIND,
1551     LA_LabelID, STR_DEVICE_CTRL,
1552     LA_ID, GAD_SERIALA_DEVICE,
1553     LA_Chars, 20,
1554 cebix 1.2 LA_STRPTR, (ULONG)seriala_dev,
1555 cebix 1.1 GTST_MaxChars, sizeof(seriala_dev) - 1,
1556     LAST_Picker, TRUE,
1557     TAG_END
1558     );
1559     LT_New(h, LA_Type, INTEGER_KIND,
1560     LA_LabelID, STR_UNIT_CTRL,
1561     LA_ID, GAD_SERIALA_UNIT,
1562 cebix 1.2 LA_LONG, (ULONG)&seriala_unit,
1563 cebix 1.1 LAIN_UseIncrementers, TRUE,
1564     GTIN_MaxChars, 8,
1565     TAG_END
1566     );
1567     LT_New(h, LA_Type, CHECKBOX_KIND,
1568     LA_LabelID, STR_ISPAR_CTRL,
1569     LA_ID, GAD_SERIALA_ISPAR,
1570 cebix 1.2 LA_BYTE, (ULONG)&seriala_ispar,
1571 cebix 1.1 TAG_END
1572     );
1573     ENDGROUP;
1574    
1575     LT_New(h, LA_Type, VERTICAL_KIND,
1576     LA_LabelID, STR_SERIALB_CTRL,
1577     TAG_END
1578     );
1579     LT_New(h, LA_Type, STRING_KIND,
1580     LA_LabelID, STR_DEVICE_CTRL,
1581     LA_ID, GAD_SERIALB_DEVICE,
1582     LA_Chars, 20,
1583 cebix 1.2 LA_STRPTR, (ULONG)serialb_dev,
1584 cebix 1.1 GTST_MaxChars, sizeof(serialb_dev) - 1,
1585     LAST_Picker, TRUE,
1586     TAG_END
1587     );
1588     LT_New(h, LA_Type, INTEGER_KIND,
1589     LA_LabelID, STR_UNIT_CTRL,
1590     LA_ID, GAD_SERIALB_UNIT,
1591 cebix 1.2 LA_LONG, (ULONG)&serialb_unit,
1592 cebix 1.1 LAIN_UseIncrementers, TRUE,
1593     GTIN_MaxChars, 8,
1594     TAG_END
1595     );
1596     LT_New(h, LA_Type, CHECKBOX_KIND,
1597     LA_LabelID, STR_ISPAR_CTRL,
1598     LA_ID, GAD_SERIALB_ISPAR,
1599 cebix 1.2 LA_BYTE, (ULONG)&serialb_ispar,
1600 cebix 1.1 TAG_END
1601     );
1602     ENDGROUP;
1603    
1604     LT_New(h, LA_Type, VERTICAL_KIND,
1605     LA_LabelID, STR_ETHERNET_IF_CTRL,
1606     TAG_END
1607     );
1608     LT_New(h, LA_Type, STRING_KIND,
1609     LA_LabelID, STR_DEVICE_CTRL,
1610     LA_ID, GAD_ETHER_DEVICE,
1611     LA_Chars, 20,
1612 cebix 1.2 LA_STRPTR, (ULONG)ether_dev,
1613 cebix 1.1 GTST_MaxChars, sizeof(ether_dev) - 1,
1614     LAST_Picker, TRUE,
1615     TAG_END
1616     );
1617     LT_New(h, LA_Type, INTEGER_KIND,
1618     LA_LabelID, STR_UNIT_CTRL,
1619     LA_ID, GAD_ETHER_UNIT,
1620 cebix 1.2 LA_LONG, (ULONG)&ether_unit,
1621 cebix 1.1 LAIN_UseIncrementers, TRUE,
1622     GTIN_MaxChars, 8,
1623     TAG_END
1624     );
1625     ENDGROUP;
1626     ENDGROUP;
1627     }
1628    
1629    
1630     /*
1631     * "Memory/Misc" pane
1632     */
1633    
1634     static ULONG ramsize_mb;
1635     static BYTE model_num;
1636     static char rom_file[256];
1637    
1638     // Read memory/misc preferences
1639     static void parse_memory_prefs(void)
1640     {
1641     ramsize_mb = PrefsFindInt32("ramsize") >> 20;
1642    
1643     model_num = 0;
1644     int id = PrefsFindInt32("modelid");
1645     switch (id) {
1646     case 5:
1647     model_num = 0;
1648     break;
1649     case 14:
1650     model_num = 1;
1651     break;
1652     }
1653    
1654     rom_file[0] = 0;
1655     const char *str = PrefsFindString("rom");
1656     if (str) {
1657     strncpy(rom_file, str, sizeof(rom_file) - 1);
1658     rom_file[sizeof(rom_file) - 1] = 0;
1659     }
1660     }
1661    
1662     // Read settings from gadgets and set preferences
1663     static void read_memory_settings(void)
1664     {
1665     PrefsReplaceInt32("ramsize", ramsize_mb << 20);
1666    
1667     if (strlen(rom_file))
1668     PrefsReplaceString("rom", rom_file);
1669     else
1670     PrefsRemoveItem("rom");
1671     }
1672    
1673     // Create "Memory/Misc" pane
1674     static void create_memory_pane(struct LayoutHandle *h)
1675     {
1676     parse_memory_prefs();
1677    
1678     VGROUP;
1679     LT_New(h, LA_Type, LEVEL_KIND,
1680     LA_LabelID, STR_RAMSIZE_SLIDER,
1681     LA_ID, GAD_RAMSIZE,
1682     LA_Chars, 20,
1683 cebix 1.2 LA_LONG, (ULONG)&ramsize_mb,
1684     GTSL_LevelFormat, (ULONG)GetString(STR_RAMSIZE_FMT),
1685 cebix 1.1 GTSL_Min, 1,
1686     GTSL_Max, AvailMem(MEMF_LARGEST) >> 20,
1687     TAG_END
1688     );
1689     LT_New(h, LA_Type, CYCLE_KIND,
1690     LA_LabelID, STR_MODELID_CTRL,
1691     LA_ID, GAD_MODELID,
1692     LACY_FirstLabel, STR_MODELID_5_LAB,
1693     LACY_LastLabel, STR_MODELID_14_LAB,
1694 cebix 1.2 LA_BYTE, (ULONG)&model_num,
1695 cebix 1.1 TAG_END
1696     );
1697     LT_New(h, LA_Type, STRING_KIND,
1698     LA_LabelID, STR_ROM_FILE_CTRL,
1699     LA_ID, GAD_ROM_FILE,
1700     LA_Chars, 20,
1701 cebix 1.2 LA_STRPTR, (ULONG)rom_file,
1702 cebix 1.1 GTST_MaxChars, sizeof(rom_file) - 1,
1703     LAST_Picker, TRUE,
1704     TAG_END
1705     );
1706     ENDGROUP;
1707     }
1708    
1709    
1710     /*
1711     * Read settings from gadgets and set preferences
1712     */
1713    
1714     static void read_settings(struct LayoutHandle *h)
1715     {
1716     LT_UpdateStrings(h);
1717     read_volumes_settings();
1718     read_scsi_settings();
1719     read_graphics_settings();
1720     read_serial_settings();
1721     read_memory_settings();
1722     }