ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/prefs_editor_amiga.cpp
Revision: 1.8
Committed: 2000-07-13T17:45:32Z (23 years, 11 months ago) by cebix
Branch: MAIN
CVS Tags: snapshot-13072000
Changes since 1.7: +7 -7 lines
Log Message:
- Picasso 96 is given preference over CyberGfx because of P96's CyberGfx
  emulation

File Contents

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