ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/prefs_editor_amiga.cpp
Revision: 1.3
Committed: 1999-10-21T22:39:57Z (24 years, 8 months ago) by cebix
Branch: MAIN
Changes since 1.2: +4 -0 lines
Log Message:
- ExtFS works under AmigaOS
- fixed erroneous __regargs attributes in prefs_editor_amiga.cpp
  and audio_amiga.cpp for GCC

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