ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/prefs_editor_amiga.cpp
Revision: 1.15
Committed: 2001-02-02T20:52:57Z (23 years, 9 months ago) by cebix
Branch: MAIN
CVS Tags: snapshot-17022001
Changes since 1.14: +1 -1 lines
Log Message:
- bumped version number to 0.9
- updated copyright dates

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