ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/prefs_editor_amiga.cpp
Revision: 1.10
Committed: 2000-07-22T16:20:54Z (23 years, 11 months ago) by cebix
Branch: MAIN
Changes since 1.9: +1 -1 lines
Log Message:
- fixed compilation problems with CyberGraphX code

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