ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/prefs_editor_amiga.cpp
Revision: 1.19
Committed: 2008-01-01T09:40:31Z (16 years, 4 months ago) by gbeauche
Branch: MAIN
CVS Tags: HEAD
Changes since 1.18: +1 -1 lines
Log Message:
Happy New Year!

File Contents

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