ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/prefs_editor_amiga.cpp
Revision: 1.9
Committed: 2000-07-14T21:29:11Z (23 years, 11 months ago) by cebix
Branch: MAIN
Changes since 1.8: +6 -3 lines
Log Message:
- AmigaOS bug fixes by J.Lachmann (floppy, 2060scsi.device, "Add Volume" in
  prefs editor)
- imported some changes from the Windows source (1Hz interrupt, FPU fixes)

File Contents

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