ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/prefs_editor_amiga.cpp
Revision: 1.5
Committed: 1999-11-01T16:24:10Z (24 years, 8 months ago) by cebix
Branch: MAIN
CVS Tags: snapshot-22121999, release-0_8-1, snapshot-02111999
Changes since 1.4: +21 -5 lines
Log Message:
- AmigaOS: removed support for SAS/C
- AmigaOS: sys_amiga.cpp: supports 64-bit device access and respects
  device block size on writes
- AmigaOS: added support for resource forks and Finder info for ExtFS
- AmigaOS: added "ExtFS" gadget to prefs editor
- protection mask for all open()/creat()/mkdir() calls is now 0666 or
  0777

File Contents

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