ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/prefs_editor_amiga.cpp
Revision: 1.17
Committed: 2002-01-15T14:58:34Z (22 years, 5 months ago) by cebix
Branch: MAIN
CVS Tags: snapshot-15012002
Changes since 1.16: +1 -1 lines
Log Message:
- documentation updates
- 2001 -> 2002
- version 0.9 -> 1.0

File Contents

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