ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/prefs_editor_amiga.cpp
Revision: 1.14
Committed: 2001-01-04T19:50:22Z (23 years, 5 months ago) by cebix
Branch: MAIN
Changes since 1.13: +3 -3 lines
Log Message:
- removed the INT16 prefs item type; use INT32 instead
- AmigaOS/Unix: it's now possible to specify preferences items on the
  command line
- Unix: command line options now take "--"-prefix, e.g. "--rominfo"

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