ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/prefs_editor_amiga.cpp
Revision: 1.19
Committed: 2008-01-01T09:40:31Z (16 years, 5 months ago) by gbeauche
Branch: MAIN
CVS Tags: HEAD
Changes since 1.18: +1 -1 lines
Log Message:
Happy New Year!

File Contents

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