ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/prefs_editor_amiga.cpp
Revision: 1.7
Committed: 2000-07-06T16:04:24Z (24 years ago) by cebix
Branch: MAIN
Changes since 1.6: +20 -6 lines
Log Message:
- AmigaOS: added CyberGraphX support

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.7 #include <cybergraphx/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     // Delete handle
517     LT_DeleteHandle(h);
518    
519     // Close gtlayout.library
520     CloseLibrary(GTLayoutBase);
521     return retval;
522     }
523    
524    
525     /*
526     * "Volumes" pane
527     */
528    
529     static struct List disk_list;
530 cebix 1.5 static char cdrom_name[256], extfs_name[256];
531 cebix 1.1 static ULONG cdrom_unit, cdrom_flags, cdrom_start, cdrom_size, cdrom_bsize;
532     static BYTE bootdriver_num, nocdrom;
533    
534     // Read volumes preferences
535     static void parse_volumes_prefs(void)
536     {
537     NewList(&disk_list);
538     const char *str;
539     for (int i=0; (str = PrefsFindString("disk", i)) != NULL; i++) {
540     struct Node *item = (struct Node *)AllocMem(sizeof(struct Node), MEMF_CLEAR);
541     item->ln_Name = (char *)str;
542     AddTail(&disk_list, item);
543     }
544    
545     cdrom_name[0] = 0;
546     cdrom_unit = 0; cdrom_flags = 0; cdrom_start = 0; cdrom_size = 0; cdrom_bsize = 2048;
547    
548     str = PrefsFindString("cdrom");
549     if (str)
550     sscanf(str, "/dev/%[^/]/%ld/%ld/%ld/%ld/%ld", cdrom_name, &cdrom_unit, &cdrom_flags, &cdrom_start, &cdrom_size, &cdrom_bsize);
551    
552     bootdriver_num = 0;
553    
554     int bootdriver = PrefsFindInt16("bootdriver");
555     switch (bootdriver) {
556     case 0:
557     bootdriver_num = 0;
558     break;
559     case CDROMRefNum:
560     bootdriver_num = 1;
561     break;
562     }
563    
564     nocdrom = PrefsFindBool("nocdrom");
565 cebix 1.5
566     extfs_name[0] = 0;
567     str = PrefsFindString("extfs");
568     if (str)
569     strncpy(extfs_name, str, sizeof(extfs_name) - 1);
570 cebix 1.1 }
571    
572     // Ghost/unghost "Edit" and "Remove" buttons
573     static void ghost_volumes_gadgets(struct LayoutHandle *h)
574     {
575     UWORD sel = LT_GetAttributes(h, GAD_DISK_LIST, TAG_END);
576     if (sel == 0xffff) {
577     LT_SetAttributes(h, GAD_EDIT_VOLUME, GA_Disabled, TRUE, TAG_END);
578     LT_SetAttributes(h, GAD_REMOVE_VOLUME, GA_Disabled, TRUE, TAG_END);
579     } else {
580     LT_SetAttributes(h, GAD_EDIT_VOLUME, GA_Disabled, FALSE, TAG_END);
581     LT_SetAttributes(h, GAD_REMOVE_VOLUME, GA_Disabled, FALSE, TAG_END);
582     }
583     }
584    
585     // Get device data from partition name
586     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)
587     {
588     // Remove everything after and including the ':'
589     char str[256];
590     strncpy(str, part, sizeof(str) - 1);
591     str[sizeof(str) - 1] = 0;
592     char *colon = strchr(str, ':');
593     if (colon)
594     *colon = 0;
595    
596     // Look for partition
597     struct DosList *dl = LockDosList(LDF_DEVICES | LDF_READ);
598     dl = FindDosEntry(dl, str, LDF_DEVICES);
599     if (dl) {
600     // Get File System Startup Message
601     struct FileSysStartupMsg *fssm = (struct FileSysStartupMsg *)(dl->dol_misc.dol_handler.dol_Startup << 2);
602     if (fssm) {
603     // Get DOS environment vector
604     struct DosEnvec *de = (struct DosEnvec *)(fssm->fssm_Environ << 2);
605     if (de && de->de_TableSize >= DE_UPPERCYL) {
606     // Read settings from FSSM and Envec
607     strncpy(dev_name, (char *)(fssm->fssm_Device << 2) + 1, 255);
608     dev_name[255] = 0;
609     dev_unit = fssm->fssm_Unit;
610     dev_flags = fssm->fssm_Flags;
611     dev_start = de->de_BlocksPerTrack * de->de_Surfaces * de->de_LowCyl;
612     dev_size = de->de_BlocksPerTrack * de->de_Surfaces * (de->de_HighCyl - de->de_LowCyl + 1);
613     dev_bsize = de->de_SizeBlock << 2;
614     }
615     }
616     }
617     UnLockDosList(LDF_DEVICES | LDF_READ);
618     }
619    
620     // Display and handle "Add/Edit Volume" window
621     static void add_edit_volume(struct LayoutHandle *h2, bool adding)
622     {
623     bool ok_clicked = false;
624    
625     UWORD sel = LT_GetAttributes(h2, GAD_DISK_LIST, TAG_END);
626     if ((sel == 0xffff) && !adding)
627     return;
628    
629     char dev_name[256] = "";
630     char file_name[256] = "";
631     ULONG dev_unit = 0, dev_flags = 0, dev_start = 0, dev_size = 0, dev_bsize = 512;
632     BYTE read_only = false, is_device = false;
633    
634     if (!adding) {
635     const char *str = PrefsFindString("disk", sel);
636     if (str == NULL)
637     return;
638     if (str[0] == '*') {
639     read_only = true;
640     str++;
641     }
642     if (strstr(str, "/dev/") == str) {
643     is_device = true;
644     sscanf(str, "/dev/%[^/]/%ld/%ld/%ld/%ld/%ld", dev_name, &dev_unit, &dev_flags, &dev_start, &dev_size, &dev_bsize);
645     } else {
646     strncpy(file_name, str, sizeof(file_name) - 1);
647     file_name[sizeof(file_name) - 1] = 0;
648     }
649     }
650    
651     // Create layout handle
652     struct LayoutHandle *h = NULL;
653     struct Window *win = NULL;
654     h = LT_CreateHandleTags(NULL,
655     LAHN_AutoActivate, FALSE,
656 cebix 1.2 LAHN_LocaleHook, (ULONG)&locale_hook,
657 cebix 1.1 TAG_END
658     );
659     if (h == NULL)
660     return;
661    
662     // Create window contents
663     VGROUP;
664     // Volume gadgets
665     VGROUP;
666     LT_New(h, LA_Type, CHECKBOX_KIND,
667     LA_LabelID, STR_VOL_READONLY_CTRL,
668     LA_ID, GAD_VOLUME_READONLY,
669 cebix 1.2 LA_BYTE, (ULONG)&read_only,
670 cebix 1.1 TAG_END
671     );
672     LT_New(h, LA_Type, CYCLE_KIND,
673     LA_LabelID, STR_VOL_TYPE_CTRL,
674     LA_ID, GAD_VOLUME_TYPE,
675     LACY_AutoPageID, GAD_VOLUME_PAGEGROUP,
676     LACY_FirstLabel, STR_VOL_FILE_LAB,
677     LACY_LastLabel, STR_VOL_DEVICE_LAB,
678 cebix 1.2 LA_BYTE, (ULONG)&is_device,
679 cebix 1.1 TAG_END
680     );
681     ENDGROUP;
682     LT_New(h, LA_Type, VERTICAL_KIND,
683     LA_ID, GAD_VOLUME_PAGEGROUP,
684     LAGR_ActivePage, is_device,
685     TAG_END
686     );
687     VGROUP;
688     LT_New(h, LA_Type, STRING_KIND,
689     LA_LabelID, STR_VOL_FILE_CTRL,
690     LA_ID, GAD_VOLUME_FILE,
691     LA_Chars, 20,
692 cebix 1.2 LA_STRPTR, (ULONG)file_name,
693 cebix 1.1 GTST_MaxChars, sizeof(file_name) - 1,
694     LAST_Picker, TRUE,
695     TAG_END
696     );
697     ENDGROUP;
698     VGROUP;
699     LT_New(h, LA_Type, STRING_KIND,
700     LA_LabelID, STR_DEVICE_CTRL,
701     LA_ID, GAD_VOLUME_DEVICE,
702     LA_Chars, 20,
703 cebix 1.2 LA_STRPTR, (ULONG)dev_name,
704 cebix 1.1 GTST_MaxChars, sizeof(dev_name) - 1,
705     LAST_Picker, TRUE,
706     TAG_END
707     );
708     LT_New(h, LA_Type, INTEGER_KIND,
709     LA_LabelID, STR_UNIT_CTRL,
710     LA_ID, GAD_VOLUME_UNIT,
711 cebix 1.2 LA_LONG, (ULONG)&dev_unit,
712 cebix 1.1 LAIN_UseIncrementers, TRUE,
713     GTIN_MaxChars, 8,
714     TAG_END
715     );
716     LT_New(h, LA_Type, INTEGER_KIND,
717     LA_LabelID, STR_VOL_OPENFLAGS_CTRL,
718     LA_ID, GAD_VOLUME_OPENFLAGS,
719 cebix 1.2 LA_LONG, (ULONG)&dev_flags,
720 cebix 1.1 LAIN_UseIncrementers, TRUE,
721     GTIN_MaxChars, 8,
722     TAG_END
723     );
724     LT_New(h, LA_Type, INTEGER_KIND,
725     LA_LabelID, STR_VOL_STARTBLOCK_CTRL,
726     LA_ID, GAD_VOLUME_STARTBLOCK,
727 cebix 1.2 LA_LONG, (ULONG)&dev_start,
728 cebix 1.1 LAIN_UseIncrementers, TRUE,
729     GTIN_MaxChars, 8,
730     TAG_END
731     );
732     LT_New(h, LA_Type, INTEGER_KIND,
733     LA_LabelID, STR_VOL_SIZE_CTRL,
734     LA_ID, GAD_VOLUME_SIZE,
735 cebix 1.2 LA_LONG, (ULONG)&dev_size,
736 cebix 1.1 LAIN_UseIncrementers, TRUE,
737     GTIN_MaxChars, 8,
738     TAG_END
739     );
740     LT_New(h, LA_Type, INTEGER_KIND,
741     LA_LabelID, STR_VOL_BLOCKSIZE_CTRL,
742     LA_ID, GAD_VOLUME_BLOCKSIZE,
743 cebix 1.2 LA_LONG, (ULONG)&dev_bsize,
744 cebix 1.1 LAIN_UseIncrementers, TRUE,
745     GTIN_MaxChars, 8,
746     TAG_END
747     );
748     ENDGROUP;
749     ENDGROUP;
750    
751     // Separator between gadgets and buttons
752     VGROUP;
753     LT_New(h, LA_Type, XBAR_KIND,
754     LAXB_FullSize, TRUE,
755     TAG_END
756     );
757     ENDGROUP;
758    
759     // "OK" and "Cancel" buttons
760     LT_New(h, LA_Type, HORIZONTAL_KIND,
761     LAGR_SameSize, TRUE,
762     LAGR_Spread, TRUE,
763     TAG_END
764     );
765     LT_New(h, LA_Type, BUTTON_KIND,
766     LA_LabelID, STR_OK_BUTTON,
767     LA_ID, MSG_OK,
768     LABT_ReturnKey, TRUE,
769     TAG_END
770     );
771     LT_New(h, LA_Type, BUTTON_KIND,
772     LA_LabelID, STR_CANCEL_BUTTON,
773     LA_ID, MSG_CANCEL,
774     LABT_EscKey, TRUE,
775     TAG_END
776     );
777     ENDGROUP;
778     ENDGROUP;
779    
780     // Open window
781     win = LT_Build(h,
782     LAWN_TitleID, adding ? STR_ADD_VOLUME_TITLE : STR_EDIT_VOLUME_TITLE,
783     LAWN_IDCMP, IDCMP_CLOSEWINDOW,
784     LAWN_BelowMouse, TRUE,
785     LAWN_SmartZoom, TRUE,
786     WA_SimpleRefresh, TRUE,
787     WA_Activate, TRUE,
788     WA_CloseGadget, TRUE,
789     WA_DepthGadget, TRUE,
790     WA_DragBar, TRUE,
791     TAG_END
792     );
793     if (win == NULL) {
794     LT_DeleteHandle(h);
795     return;
796     }
797    
798     // Event loop
799     bool done = false;
800     do {
801     struct IntuiMessage *msg;
802    
803     // Wait for message
804     WaitPort(win->UserPort);
805    
806     // Get pending messages
807     while (msg = LT_GetIMsg(h)) {
808    
809     // Get data from message and reply
810     ULONG cl = msg->Class;
811     UWORD code = msg->Code;
812     struct Gadget *gad = (struct Gadget *)msg->IAddress;
813     LT_ReplyIMsg(msg);
814    
815     // Handle message according to class
816     switch (cl) {
817     case IDCMP_CLOSEWINDOW:
818     done = true;
819     break;
820    
821     case IDCMP_GADGETUP:
822     switch (gad->GadgetID) {
823     case MSG_OK:
824     ok_clicked = true;
825     done = true;
826     break;
827     case MSG_CANCEL:
828     done = true;
829     break;
830     }
831     break;
832    
833     case IDCMP_IDCMPUPDATE: {
834     struct FileRequester *req = NULL;
835     switch (gad->GadgetID) {
836     case GAD_VOLUME_FILE:
837     req = file_request;
838     goto do_req;
839     case GAD_VOLUME_DEVICE:
840     req = dev_request;
841     do_req: if (req) {
842     LT_LockWindow(win);
843 cebix 1.2 BOOL result = AslRequestTags(req, ASLFR_Window, (ULONG)win, TAG_END);
844 cebix 1.1 LT_UnlockWindow(win);
845     if (result) {
846     char *str;
847 cebix 1.2 GT_GetGadgetAttrs(gad, win, NULL, GTST_String, (ULONG)&str, TAG_END);
848 cebix 1.1 if (gad->GadgetID == GAD_VOLUME_FILE) {
849     strncpy(str, req->rf_Dir, 255);
850     str[255] = 0;
851     AddPart(str, req->rf_File, 255);
852     } else {
853     if (strlen(req->rf_File)) {
854     strncpy(str, req->rf_File, 255); // Don't copy the directory part. This is usually "DEVS:" and we don't need that.
855     str[255] = 0;
856     } else if (strlen(req->rf_Dir) && req->rf_Dir[strlen(req->rf_Dir) - 1] == ':') {
857     analyze_partition(req->rf_Dir, str, dev_unit, dev_flags, dev_start, dev_size, dev_bsize);
858     LT_SetAttributes(h, GAD_VOLUME_UNIT, GTIN_Number, dev_unit, TAG_END);
859     LT_SetAttributes(h, GAD_VOLUME_OPENFLAGS, GTIN_Number, dev_flags, TAG_END);
860     LT_SetAttributes(h, GAD_VOLUME_STARTBLOCK, GTIN_Number, dev_start, TAG_END);
861     LT_SetAttributes(h, GAD_VOLUME_SIZE, GTIN_Number, dev_size, TAG_END);
862     LT_SetAttributes(h, GAD_VOLUME_BLOCKSIZE, GTIN_Number, dev_bsize, TAG_END);
863     }
864     }
865 cebix 1.2 LT_SetAttributes(h, gad->GadgetID, GTST_String, (ULONG)str, TAG_END);
866 cebix 1.1 }
867     }
868     break;
869     }
870     break;
871     }
872     }
873     }
874     } while (!done);
875    
876     // Delete handle
877     LT_DeleteHandle(h);
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     }
917    
918     // Remove volume from list
919     static void remove_volume(struct LayoutHandle *h)
920     {
921     UWORD sel = LT_GetAttributes(h, GAD_DISK_LIST, TAG_END);
922     if (sel != 0xffff) {
923    
924     // Remove item from preferences and list view
925     LT_SetAttributes(h, GAD_DISK_LIST, GTLV_Labels, ~0, TAG_END);
926     PrefsRemoveItem("disk", sel);
927     struct Node *item = disk_list.lh_Head;
928     for (int i=0; item->ln_Succ; i++) {
929     struct Node *next = item->ln_Succ;
930     if (i == sel) {
931     Remove(item);
932     FreeMem(item, sizeof(struct Node));
933     break;
934     }
935     item = next;
936     }
937 cebix 1.2 LT_SetAttributes(h, GAD_DISK_LIST, GTLV_Labels, (ULONG)&disk_list, GTLV_Selected, 0xffff, TAG_END);
938 cebix 1.1 ghost_volumes_gadgets(h);
939     }
940     }
941    
942     // Read settings from gadgets and set preferences
943     static void read_volumes_settings(void)
944     {
945     struct Node *item = disk_list.lh_Head;
946     while (item->ln_Succ) {
947     struct Node *next = item->ln_Succ;
948     Remove(item);
949     FreeMem(item, sizeof(struct Node));
950     item = next;
951     }
952    
953     if (strlen(cdrom_name)) {
954     char str[256];
955     sprintf(str, "/dev/%s/%ld/%ld/%ld/%ld/%ld", cdrom_name, cdrom_unit, cdrom_flags, cdrom_start, cdrom_size, cdrom_bsize);
956     PrefsReplaceString("cdrom", str);
957     } else
958     PrefsRemoveItem("cdrom");
959    
960     PrefsReplaceBool("nocdrom", nocdrom);
961 cebix 1.5
962     if (strlen(extfs_name))
963     PrefsReplaceString("extfs", extfs_name);
964 cebix 1.1 }
965    
966     // Create "Volumes" pane
967     static void create_volumes_pane(struct LayoutHandle *h)
968     {
969     parse_volumes_prefs();
970    
971     VGROUP;
972     LT_New(h, LA_Type, VERTICAL_KIND,
973     LA_LabelID, STR_VOLUMES_CTRL,
974     TAG_END
975     );
976     VGROUP;
977     LT_New(h, LA_Type, LISTVIEW_KIND,
978     LA_ID, GAD_DISK_LIST,
979 cebix 1.5 LA_Chars, 20,
980 cebix 1.2 GTLV_Labels, (ULONG)&disk_list,
981 cebix 1.1 LALV_Lines, 6,
982 cebix 1.2 LALV_Link, (ULONG)NIL_LINK,
983 cebix 1.1 LALV_ResizeX, TRUE,
984     LALV_ResizeY, TRUE,
985     LALV_Selected, 0,
986     TAG_END
987     );
988     ENDGROUP;
989     LT_New(h, LA_Type, HORIZONTAL_KIND,
990     LAGR_SameSize, TRUE,
991     LAGR_Spread, TRUE,
992     TAG_END
993     );
994     LT_New(h, LA_Type, BUTTON_KIND,
995     LA_LabelID, STR_ADD_VOLUME_BUTTON,
996     LA_ID, GAD_ADD_VOLUME,
997     TAG_END
998     );
999     LT_New(h, LA_Type, BUTTON_KIND,
1000     LA_LabelID, STR_EDIT_VOLUME_BUTTON,
1001     LA_ID, GAD_EDIT_VOLUME,
1002     TAG_END
1003     );
1004     LT_New(h, LA_Type, BUTTON_KIND,
1005     LA_LabelID, STR_REMOVE_VOLUME_BUTTON,
1006     LA_ID, GAD_REMOVE_VOLUME,
1007     TAG_END
1008     );
1009     ENDGROUP;
1010     ENDGROUP;
1011     LT_New(h, LA_Type, VERTICAL_KIND,
1012     LA_LabelID, STR_CDROM_DRIVE_CTRL,
1013     TAG_END
1014     );
1015     LT_New(h, LA_Type, STRING_KIND,
1016     LA_LabelID, STR_DEVICE_CTRL,
1017     LA_ID, GAD_CDROM_DEVICE,
1018     LA_Chars, 20,
1019 cebix 1.2 LA_STRPTR, (ULONG)cdrom_name,
1020 cebix 1.1 GTST_MaxChars, sizeof(cdrom_name) - 1,
1021     LAST_Picker, TRUE,
1022     TAG_END
1023     );
1024     LT_New(h, LA_Type, INTEGER_KIND,
1025     LA_LabelID, STR_UNIT_CTRL,
1026     LA_ID, GAD_CDROM_UNIT,
1027 cebix 1.2 LA_LONG, (ULONG)&cdrom_unit,
1028 cebix 1.1 LAIN_UseIncrementers, TRUE,
1029     GTIN_MaxChars, 8,
1030     TAG_END
1031     );
1032     LT_New(h, LA_Type, CYCLE_KIND,
1033     LA_LabelID, STR_BOOTDRIVER_CTRL,
1034     LA_ID, GAD_BOOTDRIVER,
1035     LACY_FirstLabel, STR_BOOT_ANY_LAB,
1036     LACY_LastLabel, STR_BOOT_CDROM_LAB,
1037 cebix 1.2 LA_BYTE, (ULONG)&bootdriver_num,
1038 cebix 1.1 TAG_END
1039     );
1040     LT_New(h, LA_Type, CHECKBOX_KIND,
1041     LA_LabelID, STR_NOCDROM_CTRL,
1042     LA_ID, GAD_NOCDROM,
1043 cebix 1.2 LA_BYTE, (ULONG)&nocdrom,
1044 cebix 1.5 TAG_END
1045     );
1046     ENDGROUP;
1047     VGROUP;
1048     LT_New(h, LA_Type, STRING_KIND,
1049     LA_LabelID, STR_EXTFS_CTRL,
1050     LA_ID, GAD_EXTFS,
1051     LA_Chars, 20,
1052     LA_STRPTR, (ULONG)extfs_name,
1053     GTST_MaxChars, sizeof(extfs_name) - 1,
1054 cebix 1.1 TAG_END
1055     );
1056     ENDGROUP;
1057     ENDGROUP;
1058     }
1059    
1060    
1061     /*
1062     * "SCSI" pane
1063     */
1064    
1065     static char scsi_dev[6][256];
1066     static LONG scsi_unit[6];
1067    
1068     // Read SCSI preferences
1069     static void parse_scsi_prefs(void)
1070     {
1071     for (int i=0; i<7; i++) {
1072     scsi_dev[i][0] = 0;
1073     scsi_unit[i] = 0;
1074    
1075     char prefs_name[16];
1076     sprintf(prefs_name, "scsi%d", i);
1077     const char *str = PrefsFindString(prefs_name);
1078     if (str)
1079     sscanf(str, "%[^/]/%ld", scsi_dev[i], &scsi_unit[i]);
1080     }
1081     }
1082    
1083     // Read settings from gadgets and set preferences
1084     static void read_scsi_settings(void)
1085     {
1086     for (int i=0; i<7; i++) {
1087     char prefs_name[16];
1088     sprintf(prefs_name, "scsi%d", i);
1089    
1090     if (strlen(scsi_dev[i])) {
1091     char str[256];
1092 cebix 1.4 sprintf(str, "%s/%ld", scsi_dev[i], scsi_unit[i]);
1093 cebix 1.1 PrefsReplaceString(prefs_name, str);
1094     } else
1095     PrefsRemoveItem(prefs_name);
1096     }
1097     }
1098    
1099     // Create "SCSI" pane
1100     static void create_scsi_pane(struct LayoutHandle *h)
1101     {
1102     parse_scsi_prefs();
1103    
1104     VGROUP;
1105     for (int i=0; i<7; i++) {
1106     HGROUP;
1107     LT_New(h, LA_Type, TEXT_KIND,
1108     LA_LabelID, STR_SCSI_ID_0 + i,
1109     TAG_END
1110     );
1111     LT_New(h, LA_Type, STRING_KIND,
1112     LA_LabelID, STR_DEVICE_CTRL,
1113     LA_ID, GAD_SCSI0_DEVICE + i,
1114     LA_Chars, 20,
1115 cebix 1.2 LA_STRPTR, (ULONG)scsi_dev[i],
1116 cebix 1.1 GTST_MaxChars, sizeof(scsi_dev[i]) - 1,
1117     LAST_Picker, TRUE,
1118     TAG_END
1119     );
1120     LT_New(h, LA_Type, INTEGER_KIND,
1121     LA_LabelID, STR_UNIT_CTRL,
1122     LA_ID, GAD_SCSI0_UNIT + i,
1123     LA_Chars, 4,
1124 cebix 1.2 LA_LONG, (ULONG)&scsi_unit[i],
1125 cebix 1.1 LAIN_UseIncrementers, TRUE,
1126     GTIN_MaxChars, 8,
1127     TAG_END
1128     );
1129     ENDGROUP;
1130     }
1131     ENDGROUP;
1132     }
1133    
1134    
1135     /*
1136     * "Graphics/Sound" pane
1137     */
1138    
1139     // Display types
1140     enum {
1141     DISPLAY_WINDOW,
1142     DISPLAY_PIP,
1143     DISPLAY_SCREEN
1144     };
1145    
1146     static BYTE display_type;
1147     static LONG dis_width, dis_height;
1148     static ULONG mode_id;
1149     static BYTE frameskip_num;
1150     static struct NameInfo mode_name;
1151     static ULONG ahi_id;
1152     static char ahi_mode_name[256];
1153     static BYTE nosound;
1154    
1155     // Read graphics preferences
1156     static void parse_graphics_prefs(void)
1157     {
1158     display_type = DISPLAY_WINDOW;
1159     dis_width = 512;
1160     dis_height = 384;
1161     mode_id = 0;
1162     ahi_id = AHI_DEFAULT_ID;
1163     ahi_mode_name[0] = 0;
1164    
1165     frameskip_num = 0;
1166     int frameskip = PrefsFindInt32("frameskip");
1167     switch (frameskip) {
1168     case 12:
1169     frameskip_num = 0;
1170     break;
1171     case 8:
1172     frameskip_num = 1;
1173     break;
1174     case 6:
1175     frameskip_num = 2;
1176     break;
1177     case 4:
1178     frameskip_num = 3;
1179     break;
1180     case 2:
1181     frameskip_num = 4;
1182     break;
1183     case 1:
1184     frameskip_num = 5;
1185     break;
1186     }
1187    
1188     const char *str = PrefsFindString("screen");
1189     if (str) {
1190     if (sscanf(str, "win/%d/%d", &dis_width, &dis_height) == 2)
1191     display_type = DISPLAY_WINDOW;
1192     else if (sscanf(str, "pip/%d/%d", &dis_width, &dis_height) == 2)
1193     display_type = DISPLAY_PIP;
1194     else if (sscanf(str, "scr/%08lx", &mode_id) == 1)
1195     display_type = DISPLAY_SCREEN;
1196     }
1197    
1198     GetDisplayInfoData(NULL, (UBYTE *)&mode_name, sizeof(mode_name), DTAG_NAME, mode_id);
1199    
1200     str = PrefsFindString("sound");
1201     if (str) {
1202     if (sscanf(str, "ahi/%08lx", &ahi_id) == 1 && AHIBase) {
1203     AHI_GetAudioAttrs(ahi_id, NULL,
1204 cebix 1.2 AHIDB_Name, (ULONG)ahi_mode_name,
1205 cebix 1.1 AHIDB_BufferLen, sizeof(ahi_mode_name) - 1,
1206     TAG_END
1207     );
1208     }
1209     }
1210     nosound = PrefsFindBool("nosound");
1211     }
1212    
1213     // Ghost/unghost graphics gadgets, depending on display type
1214     static void ghost_graphics_gadgets(struct LayoutHandle *h)
1215     {
1216     bool dis_xy, dis_skip, dis_mode;
1217     switch (display_type) {
1218     case DISPLAY_WINDOW:
1219     dis_xy = false;
1220     dis_skip = false;
1221     dis_mode = true;
1222     break;
1223     case DISPLAY_PIP:
1224     dis_xy = false;
1225     dis_skip = true;
1226     dis_mode = true;
1227     break;
1228     case DISPLAY_SCREEN:
1229     dis_xy = true;
1230     dis_skip = true;
1231     dis_mode = false;
1232     break;
1233     }
1234     LT_SetAttributes(h, GAD_DISPLAY_X, GA_Disabled, dis_xy, TAG_END);
1235     LT_SetAttributes(h, GAD_DISPLAY_Y, GA_Disabled, dis_xy, TAG_END);
1236     LT_SetAttributes(h, GAD_FRAMESKIP, GA_Disabled, dis_skip, TAG_END);
1237     LT_SetAttributes(h, GAD_SCREEN_MODE, GA_Disabled, dis_mode, TAG_END);
1238     LT_SetAttributes(h, GAD_AHI_MODE, GA_Disabled, AHIBase == NULL, TAG_END);
1239     }
1240    
1241     // Show screen mode requester
1242     static void screen_mode_req(struct Window *win, struct LayoutHandle *h)
1243     {
1244 cebix 1.7 if (P96Base == NULL && CyberGfxBase == NULL)
1245 cebix 1.1 return;
1246    
1247     LT_LockWindow(win);
1248 cebix 1.7
1249     ULONG id;
1250    
1251     if (CyberGfxBase) {
1252     UWORD model_array[] = {PIXFMT_LUT8, PIXFMT_RGB16, PIXFMT_ARGB32, 0, ~0};
1253     id = (ULONG) CModeRequestTags(NULL,
1254     CYBRMREQ_MinDepth, 8,
1255     CYBRMREQ_CModelArray, (ULONG)model_array,
1256     TAG_END
1257     );
1258     } else {
1259     id = p96RequestModeIDTags(
1260     P96MA_MinDepth, 8,
1261     P96MA_FormatsAllowed, RGBFF_CLUT | RGBFF_R5G5B5 | RGBFF_A8R8G8B8,
1262     TAG_END
1263     );
1264     }
1265 cebix 1.1 LT_UnlockWindow(win);
1266    
1267     if (id != INVALID_ID) {
1268     mode_id = id;
1269     GetDisplayInfoData(NULL, (UBYTE *)&mode_name, sizeof(mode_name), DTAG_NAME, mode_id);
1270 cebix 1.2 LT_SetAttributes(h, GAD_SCREEN_MODE, GTTX_Text, (ULONG)mode_name.Name, TAG_END);
1271 cebix 1.1 }
1272     }
1273    
1274     // Show AHI mode requester
1275     static void ahi_mode_req(struct Window *win, struct LayoutHandle *h)
1276     {
1277     if (AHIBase == NULL)
1278     return;
1279    
1280     struct AHIAudioModeRequester *req = AHI_AllocAudioRequest(
1281 cebix 1.2 AHIR_Window, (ULONG)win,
1282 cebix 1.1 TAG_END
1283     );
1284     if (req == NULL)
1285     return;
1286    
1287     LT_LockWindow(win);
1288     BOOL ok = AHI_AudioRequest(req,
1289     AHIR_InitialAudioID, ahi_id,
1290     TAG_END
1291     );
1292     LT_UnlockWindow(win);
1293    
1294     if (ok) {
1295     ahi_id = req->ahiam_AudioID;
1296     AHI_GetAudioAttrs(ahi_id, NULL,
1297 cebix 1.2 AHIDB_Name, (ULONG)ahi_mode_name,
1298 cebix 1.1 AHIDB_BufferLen, sizeof(ahi_mode_name) - 1,
1299     TAG_END
1300     );
1301 cebix 1.2 LT_SetAttributes(h, GAD_AHI_MODE, GTTX_Text, (ULONG)ahi_mode_name, TAG_END);
1302 cebix 1.1 }
1303     AHI_FreeAudioRequest(req);
1304     }
1305    
1306     // Read settings from gadgets and set preferences
1307     static void read_graphics_settings(void)
1308     {
1309     char str[256];
1310     switch (display_type) {
1311     case DISPLAY_WINDOW:
1312     sprintf(str, "win/%ld/%ld", dis_width, dis_height);
1313     break;
1314     case DISPLAY_PIP:
1315     sprintf(str, "pip/%ld/%ld", dis_width, dis_height);
1316     break;
1317     case DISPLAY_SCREEN:
1318     sprintf(str, "scr/%08lx", mode_id);
1319     break;
1320     default:
1321     PrefsRemoveItem("screen");
1322     return;
1323     }
1324     PrefsReplaceString("screen", str);
1325    
1326     sprintf(str, "ahi/%08lx", ahi_id);
1327     PrefsReplaceString("sound", str);
1328    
1329     PrefsReplaceBool("nosound", nosound);
1330     }
1331    
1332     // Create "Graphics/Sound" pane
1333     static void create_graphics_pane(struct LayoutHandle *h)
1334     {
1335     parse_graphics_prefs();
1336    
1337     VGROUP;
1338     LT_New(h, LA_Type, VERTICAL_KIND,
1339     LA_LabelID, STR_GRAPHICS_CTRL,
1340     TAG_END
1341     );
1342     static const LONG labels[] = {STR_WINDOW_LAB, STR_PIP_LAB, STR_FULLSCREEN_LAB, -1};
1343     LT_New(h, LA_Type, CYCLE_KIND,
1344     LA_LabelID, STR_VIDEO_TYPE_CTRL,
1345     LA_ID, GAD_VIDEO_TYPE,
1346 cebix 1.2 LACY_LabelTable, (ULONG)labels,
1347     LA_BYTE, (ULONG)&display_type,
1348 cebix 1.1 TAG_END
1349     );
1350     LT_New(h, LA_Type, INTEGER_KIND,
1351     LA_LabelID, STR_DISPLAY_X_CTRL,
1352     LA_ID, GAD_DISPLAY_X,
1353 cebix 1.2 LA_LONG, (ULONG)&dis_width,
1354 cebix 1.1 GTIN_MaxChars, 8,
1355     TAG_END
1356     );
1357     LT_New(h, LA_Type, INTEGER_KIND,
1358     LA_LabelID, STR_DISPLAY_Y_CTRL,
1359     LA_ID, GAD_DISPLAY_Y,
1360 cebix 1.2 LA_LONG, (ULONG)&dis_height,
1361 cebix 1.1 GTIN_MaxChars, 8,
1362     TAG_END
1363     );
1364     LT_New(h, LA_Type, POPUP_KIND,
1365     LA_LabelID, STR_FRAMESKIP_CTRL,
1366     LA_ID, GAD_FRAMESKIP,
1367     LAPU_FirstLabel, STR_REF_5HZ_LAB,
1368     LAPU_LastLabel, STR_REF_60HZ_LAB,
1369 cebix 1.2 LA_BYTE, (ULONG)&frameskip_num,
1370 cebix 1.1 TAG_END
1371     );
1372     LT_New(h, LA_Type, TEXT_KIND,
1373     LA_LabelID, STR_SCREEN_MODE_CTRL,
1374     LA_ID, GAD_SCREEN_MODE,
1375     LA_Chars, DISPLAYNAMELEN,
1376     LATX_Picker, TRUE,
1377 cebix 1.2 GTTX_Text, (ULONG)mode_name.Name,
1378 cebix 1.1 GTTX_Border, TRUE,
1379     TAG_END
1380     );
1381     ENDGROUP;
1382     LT_New(h, LA_Type, VERTICAL_KIND,
1383     LA_LabelID, STR_SOUND_CTRL,
1384     TAG_END
1385     );
1386     LT_New(h, LA_Type, TEXT_KIND,
1387     LA_LabelID, STR_AHI_MODE_CTRL,
1388     LA_ID, GAD_AHI_MODE,
1389     LA_Chars, DISPLAYNAMELEN,
1390     LATX_Picker, TRUE,
1391 cebix 1.2 GTTX_Text, (ULONG)ahi_mode_name,
1392 cebix 1.1 GTTX_Border, TRUE,
1393     TAG_END
1394     );
1395     LT_New(h, LA_Type, CHECKBOX_KIND,
1396     LA_LabelID, STR_NOSOUND_CTRL,
1397     LA_ID, GAD_NOSOUND,
1398 cebix 1.2 LA_BYTE, (ULONG)&nosound,
1399 cebix 1.1 TAG_END
1400     );
1401     ENDGROUP;
1402     ENDGROUP;
1403    
1404     ghost_graphics_gadgets(h);
1405     }
1406    
1407    
1408     /*
1409     * "Serial/Network" pane
1410     */
1411    
1412     static char seriala_dev[256], serialb_dev[256];
1413     static LONG seriala_unit, serialb_unit;
1414     static BYTE seriala_ispar, serialb_ispar;
1415    
1416     static char ether_dev[256];
1417     static ULONG ether_unit;
1418    
1419     // Read serial/network preferences
1420 cebix 1.2 static void parse_ser_prefs(const char *prefs, char *dev, LONG &unit, BYTE &ispar)
1421 cebix 1.1 {
1422     dev[0] = 0;
1423     unit = 0;
1424     ispar = false;
1425    
1426     const char *str = PrefsFindString(prefs);
1427     if (str) {
1428     if (str[0] == '*') {
1429     ispar = true;
1430     str++;
1431     }
1432     sscanf(str, "%[^/]/%ld", dev, &unit);
1433     }
1434 cebix 1.2 }
1435    
1436     static void parse_serial_prefs(void)
1437     {
1438     parse_ser_prefs("seriala", seriala_dev, seriala_unit, seriala_ispar);
1439     parse_ser_prefs("serialb", serialb_dev, serialb_unit, serialb_ispar);
1440 cebix 1.1
1441     ether_dev[0] = 0;
1442     ether_unit = 0;
1443    
1444 cebix 1.2 const char *str = PrefsFindString("ether");
1445 cebix 1.1 if (str)
1446     sscanf(str, "%[^/]/%ld", ether_dev, &ether_unit);
1447     }
1448    
1449     // Set serial preference item
1450     static void make_serial_prefs(const char *prefs, const char *dev, LONG unit, BYTE ispar)
1451     {
1452     if (strlen(dev)) {
1453     char str[256];
1454     sprintf(str, "%s%s/%ld", ispar ? "*" : "", dev, unit);
1455     PrefsReplaceString(prefs, str);
1456     } else
1457     PrefsRemoveItem(prefs);
1458     }
1459    
1460     // Read settings from gadgets and set preferences
1461     static void read_serial_settings(void)
1462     {
1463     make_serial_prefs("seriala", seriala_dev, seriala_unit, seriala_ispar);
1464     make_serial_prefs("serialb", serialb_dev, serialb_unit, serialb_ispar);
1465    
1466     if (strlen(ether_dev)) {
1467     char str[256];
1468     sprintf(str, "%s/%ld", ether_dev, ether_unit);
1469     PrefsReplaceString("ether", str);
1470     } else
1471     PrefsRemoveItem("ether");
1472     }
1473    
1474     // Create "Serial/Network" pane
1475     static void create_serial_pane(struct LayoutHandle *h)
1476     {
1477 cebix 1.2 parse_serial_prefs();
1478 cebix 1.1
1479     VGROUP;
1480     LT_New(h, LA_Type, VERTICAL_KIND,
1481     LA_LabelID, STR_SERIALA_CTRL,
1482     TAG_END
1483     );
1484     LT_New(h, LA_Type, STRING_KIND,
1485     LA_LabelID, STR_DEVICE_CTRL,
1486     LA_ID, GAD_SERIALA_DEVICE,
1487     LA_Chars, 20,
1488 cebix 1.2 LA_STRPTR, (ULONG)seriala_dev,
1489 cebix 1.1 GTST_MaxChars, sizeof(seriala_dev) - 1,
1490     LAST_Picker, TRUE,
1491     TAG_END
1492     );
1493     LT_New(h, LA_Type, INTEGER_KIND,
1494     LA_LabelID, STR_UNIT_CTRL,
1495     LA_ID, GAD_SERIALA_UNIT,
1496 cebix 1.2 LA_LONG, (ULONG)&seriala_unit,
1497 cebix 1.1 LAIN_UseIncrementers, TRUE,
1498     GTIN_MaxChars, 8,
1499     TAG_END
1500     );
1501     LT_New(h, LA_Type, CHECKBOX_KIND,
1502     LA_LabelID, STR_ISPAR_CTRL,
1503     LA_ID, GAD_SERIALA_ISPAR,
1504 cebix 1.2 LA_BYTE, (ULONG)&seriala_ispar,
1505 cebix 1.1 TAG_END
1506     );
1507     ENDGROUP;
1508    
1509     LT_New(h, LA_Type, VERTICAL_KIND,
1510     LA_LabelID, STR_SERIALB_CTRL,
1511     TAG_END
1512     );
1513     LT_New(h, LA_Type, STRING_KIND,
1514     LA_LabelID, STR_DEVICE_CTRL,
1515     LA_ID, GAD_SERIALB_DEVICE,
1516     LA_Chars, 20,
1517 cebix 1.2 LA_STRPTR, (ULONG)serialb_dev,
1518 cebix 1.1 GTST_MaxChars, sizeof(serialb_dev) - 1,
1519     LAST_Picker, TRUE,
1520     TAG_END
1521     );
1522     LT_New(h, LA_Type, INTEGER_KIND,
1523     LA_LabelID, STR_UNIT_CTRL,
1524     LA_ID, GAD_SERIALB_UNIT,
1525 cebix 1.2 LA_LONG, (ULONG)&serialb_unit,
1526 cebix 1.1 LAIN_UseIncrementers, TRUE,
1527     GTIN_MaxChars, 8,
1528     TAG_END
1529     );
1530     LT_New(h, LA_Type, CHECKBOX_KIND,
1531     LA_LabelID, STR_ISPAR_CTRL,
1532     LA_ID, GAD_SERIALB_ISPAR,
1533 cebix 1.2 LA_BYTE, (ULONG)&serialb_ispar,
1534 cebix 1.1 TAG_END
1535     );
1536     ENDGROUP;
1537    
1538     LT_New(h, LA_Type, VERTICAL_KIND,
1539     LA_LabelID, STR_ETHERNET_IF_CTRL,
1540     TAG_END
1541     );
1542     LT_New(h, LA_Type, STRING_KIND,
1543     LA_LabelID, STR_DEVICE_CTRL,
1544     LA_ID, GAD_ETHER_DEVICE,
1545     LA_Chars, 20,
1546 cebix 1.2 LA_STRPTR, (ULONG)ether_dev,
1547 cebix 1.1 GTST_MaxChars, sizeof(ether_dev) - 1,
1548     LAST_Picker, TRUE,
1549     TAG_END
1550     );
1551     LT_New(h, LA_Type, INTEGER_KIND,
1552     LA_LabelID, STR_UNIT_CTRL,
1553     LA_ID, GAD_ETHER_UNIT,
1554 cebix 1.2 LA_LONG, (ULONG)&ether_unit,
1555 cebix 1.1 LAIN_UseIncrementers, TRUE,
1556     GTIN_MaxChars, 8,
1557     TAG_END
1558     );
1559     ENDGROUP;
1560     ENDGROUP;
1561     }
1562    
1563    
1564     /*
1565     * "Memory/Misc" pane
1566     */
1567    
1568     static ULONG ramsize_mb;
1569     static BYTE model_num;
1570     static char rom_file[256];
1571    
1572     // Read memory/misc preferences
1573     static void parse_memory_prefs(void)
1574     {
1575     ramsize_mb = PrefsFindInt32("ramsize") >> 20;
1576    
1577     model_num = 0;
1578     int id = PrefsFindInt32("modelid");
1579     switch (id) {
1580     case 5:
1581     model_num = 0;
1582     break;
1583     case 14:
1584     model_num = 1;
1585     break;
1586     }
1587    
1588     rom_file[0] = 0;
1589     const char *str = PrefsFindString("rom");
1590     if (str) {
1591     strncpy(rom_file, str, sizeof(rom_file) - 1);
1592     rom_file[sizeof(rom_file) - 1] = 0;
1593     }
1594     }
1595    
1596     // Read settings from gadgets and set preferences
1597     static void read_memory_settings(void)
1598     {
1599     PrefsReplaceInt32("ramsize", ramsize_mb << 20);
1600    
1601     if (strlen(rom_file))
1602     PrefsReplaceString("rom", rom_file);
1603     else
1604     PrefsRemoveItem("rom");
1605     }
1606    
1607     // Create "Memory/Misc" pane
1608     static void create_memory_pane(struct LayoutHandle *h)
1609     {
1610     parse_memory_prefs();
1611    
1612     VGROUP;
1613     LT_New(h, LA_Type, LEVEL_KIND,
1614     LA_LabelID, STR_RAMSIZE_SLIDER,
1615     LA_ID, GAD_RAMSIZE,
1616     LA_Chars, 20,
1617 cebix 1.2 LA_LONG, (ULONG)&ramsize_mb,
1618     GTSL_LevelFormat, (ULONG)GetString(STR_RAMSIZE_FMT),
1619 cebix 1.1 GTSL_Min, 1,
1620     GTSL_Max, AvailMem(MEMF_LARGEST) >> 20,
1621     TAG_END
1622     );
1623     LT_New(h, LA_Type, CYCLE_KIND,
1624     LA_LabelID, STR_MODELID_CTRL,
1625     LA_ID, GAD_MODELID,
1626     LACY_FirstLabel, STR_MODELID_5_LAB,
1627     LACY_LastLabel, STR_MODELID_14_LAB,
1628 cebix 1.2 LA_BYTE, (ULONG)&model_num,
1629 cebix 1.1 TAG_END
1630     );
1631     LT_New(h, LA_Type, STRING_KIND,
1632     LA_LabelID, STR_ROM_FILE_CTRL,
1633     LA_ID, GAD_ROM_FILE,
1634     LA_Chars, 20,
1635 cebix 1.2 LA_STRPTR, (ULONG)rom_file,
1636 cebix 1.1 GTST_MaxChars, sizeof(rom_file) - 1,
1637     LAST_Picker, TRUE,
1638     TAG_END
1639     );
1640     ENDGROUP;
1641     }
1642    
1643    
1644     /*
1645     * Read settings from gadgets and set preferences
1646     */
1647    
1648     static void read_settings(struct LayoutHandle *h)
1649     {
1650     LT_UpdateStrings(h);
1651     read_volumes_settings();
1652     read_scsi_settings();
1653     read_graphics_settings();
1654     read_serial_settings();
1655     read_memory_settings();
1656     }