ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/prefs_editor_amiga.cpp
Revision: 1.4
Committed: 1999-10-25T19:01:32Z (25 years, 1 month ago) by cebix
Branch: MAIN
Changes since 1.3: +1 -1 lines
Log Message:
- fixes to audio_oss_esd.cpp from Alexander R. Pruss (8-bit mode)
- added configuration summary to configure script
- prefs_editor_amiga.cpp: output of SCSI prefs was broken

File Contents

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