/* * prefs_editor_amiga.cpp - Preferences editor, AmigaOS implementation (using gtlayout.library) * * Basilisk II (C) 1997-2001 Christian Bauer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #define __USE_SYSBASE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "sysdeps.h" #include "main.h" #include "xpram.h" #include "cdrom.h" #include "user_strings.h" #include "version.h" #include "prefs.h" #include "prefs_editor.h" // Gadget/menu IDs const int MSG_OK = 0x0100; // "Start" button const int MSG_CANCEL = 0x0101; // "Quit" button const int MSG_ABOUT = 0x0102; // "About..." menu item const int MSG_ZAP_PRAM = 0x0103; // "Zap PRAM" menu item const int GAD_PAGEGROUP = 0x0200; const int GAD_DISK_LIST = 0x0300; // "Volumes" pane const int GAD_ADD_VOLUME = 0x0301; const int GAD_EDIT_VOLUME = 0x0302; const int GAD_REMOVE_VOLUME = 0x0303; const int GAD_CDROM_DEVICE = 0x0304; const int GAD_CDROM_UNIT = 0x0305; const int GAD_BOOTDRIVER = 0x0306; const int GAD_NOCDROM = 0x0307; const int GAD_EXTFS = 0x0308; const int GAD_VOLUME_READONLY = 0x0310; // "Add/Edit Volume" window const int GAD_VOLUME_TYPE = 0x0311; const int GAD_VOLUME_FILE = 0x0312; const int GAD_VOLUME_DEVICE = 0x0313; const int GAD_VOLUME_UNIT = 0x0314; const int GAD_VOLUME_OPENFLAGS = 0x0315; const int GAD_VOLUME_STARTBLOCK = 0x0316; const int GAD_VOLUME_SIZE = 0x0317; const int GAD_VOLUME_BLOCKSIZE = 0x0318; const int GAD_VOLUME_PAGEGROUP = 0x0319; const int GAD_SCSI0_DEVICE = 0x0400; // "SCSI" pane const int GAD_SCSI1_DEVICE = 0x0401; const int GAD_SCSI2_DEVICE = 0x0402; const int GAD_SCSI3_DEVICE = 0x0403; const int GAD_SCSI4_DEVICE = 0x0404; const int GAD_SCSI5_DEVICE = 0x0405; const int GAD_SCSI6_DEVICE = 0x0406; const int GAD_SCSI0_UNIT = 0x0410; const int GAD_SCSI1_UNIT = 0x0411; const int GAD_SCSI2_UNIT = 0x0412; const int GAD_SCSI3_UNIT = 0x0413; const int GAD_SCSI4_UNIT = 0x0414; const int GAD_SCSI5_UNIT = 0x0415; const int GAD_SCSI6_UNIT = 0x0416; const int GAD_SCSI_MEMTYPE = 0x0420; const int GAD_VIDEO_TYPE = 0x0500; // "Graphics/Sound" pane const int GAD_DISPLAY_X = 0x0501; const int GAD_DISPLAY_Y = 0x0502; const int GAD_FRAMESKIP = 0x0503; const int GAD_SCREEN_MODE = 0x0504; const int GAD_AHI_MODE = 0x0505; const int GAD_NOSOUND = 0x0506; const int GAD_SERIALA_DEVICE = 0x0600; // "Serial/Network" pane const int GAD_SERIALA_UNIT = 0x0601; const int GAD_SERIALA_ISPAR = 0x0602; const int GAD_SERIALB_DEVICE = 0x0603; const int GAD_SERIALB_UNIT = 0x0604; const int GAD_SERIALB_ISPAR = 0x0605; const int GAD_ETHER_DEVICE = 0x0606; const int GAD_ETHER_UNIT = 0x00607; const int GAD_RAMSIZE = 0x0700; // "Memory/Misc" pane const int GAD_MODELID = 0x0701; const int GAD_ROM_FILE = 0x0702; // Global variables struct Library *GTLayoutBase = NULL; static struct FileRequester *dev_request = NULL, *file_request = NULL; // gtlayout.library macros #define VGROUP LT_New(h, LA_Type, VERTICAL_KIND, TAG_END) #define HGROUP LT_New(h, LA_Type, HORIZONTAL_KIND, TAG_END) #define ENDGROUP LT_EndGroup(h) // Prototypes static void create_volumes_pane(struct LayoutHandle *h); static void create_scsi_pane(struct LayoutHandle *h); static void create_graphics_pane(struct LayoutHandle *h); static void create_serial_pane(struct LayoutHandle *h); static void create_memory_pane(struct LayoutHandle *h); static void add_edit_volume(struct LayoutHandle *h, bool adding); static void remove_volume(struct LayoutHandle *h); static void ghost_volumes_gadgets(struct LayoutHandle *h); static void ghost_graphics_gadgets(struct LayoutHandle *h); static void screen_mode_req(struct Window *win, struct LayoutHandle *h); static void ahi_mode_req(struct Window *win, struct LayoutHandle *h); static void read_settings(struct LayoutHandle *h); /* * Locale hook - returns string for given ID */ static __saveds __attribute__((regparm(3))) const char *locale_hook_func(struct Hook *hook /*a0*/, void *id /*a1*/, struct LayoutHandle *h /*a2*/) { return GetString((uint32)id); } struct Hook locale_hook = {{NULL, NULL}, (HOOKFUNC)locale_hook_func, NULL, NULL}; /* * Show preferences editor * Returns true when user clicked on "Start", false otherwise */ bool PrefsEditor(void) { bool retval = true, done = false; struct LayoutHandle *h = NULL; struct Window *win = NULL; struct Menu *menu = NULL; // Pane tabs static const LONG labels[] = { STR_VOLUMES_PANE_TITLE, STR_SCSI_PANE_TITLE, STR_GRAPHICS_SOUND_PANE_TITLE, STR_SERIAL_NETWORK_PANE_TITLE, STR_MEMORY_MISC_PANE_TITLE, -1 }; // Open gtlayout.library GTLayoutBase = (struct Library *)OpenLibrary("gtlayout.library", 39); if (GTLayoutBase == NULL) { WarningAlert(GetString(STR_NO_GTLAYOUT_LIB_WARN)); return true; } // Create layout handle h = LT_CreateHandleTags(NULL, LAHN_AutoActivate, FALSE, LAHN_LocaleHook, (ULONG)&locale_hook, TAG_END ); if (h == NULL) goto quit; // Create menus menu = LT_NewMenuTags( LAMN_LayoutHandle, (ULONG)h, LAMN_TitleID, STR_PREFS_MENU, LAMN_ItemID, STR_PREFS_ITEM_ABOUT, LAMN_UserData, MSG_ABOUT, LAMN_ItemText, (ULONG)NM_BARLABEL, LAMN_ItemID, STR_PREFS_ITEM_START, LAMN_UserData, MSG_OK, LAMN_ItemID, STR_PREFS_ITEM_ZAP_PRAM, LAMN_UserData, MSG_ZAP_PRAM, LAMN_ItemText, (ULONG)NM_BARLABEL, LAMN_ItemID, STR_PREFS_ITEM_QUIT, LAMN_UserData, MSG_CANCEL, LAMN_KeyText, (ULONG)"Q", TAG_END ); // Create window contents VGROUP; VGROUP; LT_New(h, LA_Type, TAB_KIND, LATB_LabelTable, (ULONG)labels, LATB_AutoPageID, GAD_PAGEGROUP, LATB_FullWidth, TRUE, TAG_END ); ENDGROUP; // Panes LT_New(h, LA_Type, VERTICAL_KIND, LA_ID, GAD_PAGEGROUP, LAGR_ActivePage, 0, TAG_END ); create_volumes_pane(h); create_scsi_pane(h); create_graphics_pane(h); create_serial_pane(h); create_memory_pane(h); ENDGROUP; // Separator between tabs and buttons VGROUP; LT_New(h, LA_Type, XBAR_KIND, LAXB_FullSize, TRUE, TAG_END ); ENDGROUP; // "Start" and "Quit" buttons LT_New(h, LA_Type, HORIZONTAL_KIND, LAGR_SameSize, TRUE, LAGR_Spread, TRUE, TAG_END ); LT_New(h, LA_Type, BUTTON_KIND, LA_LabelID, STR_START_BUTTON, LA_ID, MSG_OK, LABT_ReturnKey, TRUE, TAG_END ); LT_New(h, LA_Type, BUTTON_KIND, LA_LabelID, STR_QUIT_BUTTON, LA_ID, MSG_CANCEL, LABT_EscKey, TRUE, TAG_END ); ENDGROUP; ENDGROUP; // Open window win = LT_Build(h, LAWN_TitleID, STR_PREFS_TITLE, LAWN_Menu, (ULONG)menu, LAWN_IDCMP, IDCMP_CLOSEWINDOW, LAWN_BelowMouse, TRUE, LAWN_SmartZoom, TRUE, WA_SimpleRefresh, TRUE, WA_Activate, TRUE, WA_CloseGadget, TRUE, WA_DepthGadget, TRUE, WA_DragBar, TRUE, TAG_END ); if (win == NULL) goto quit; // Create file requesters dev_request = (struct FileRequester *)AllocAslRequestTags(ASL_FileRequest, ASLFR_DoPatterns, TRUE, ASLFR_RejectIcons, TRUE, ASLFR_InitialDrawer, (ULONG)"DEVS:", ASLFR_InitialPattern, (ULONG)"#?.device", TAG_END ); file_request = (struct FileRequester *)AllocAslRequestTags(ASL_FileRequest, ASLFR_DoPatterns, TRUE, ASLFR_RejectIcons, TRUE, ASLFR_InitialPattern, (ULONG)"#?", TAG_END ); // Event loop do { struct IntuiMessage *msg; // Wait for message WaitPort(win->UserPort); // Get pending messages while (msg = LT_GetIMsg(h)) { // Get data from message and reply ULONG cl = msg->Class; UWORD code = msg->Code; struct Gadget *gad = (struct Gadget *)msg->IAddress; LT_ReplyIMsg(msg); // Handle message according to class switch (cl) { case IDCMP_CLOSEWINDOW: retval = false; done = true; break; case IDCMP_GADGETUP: switch (gad->GadgetID) { case MSG_OK: read_settings(h); SavePrefs(); retval = true; done = true; break; case MSG_CANCEL: retval = false; done = true; break; case GAD_DISK_LIST: ghost_volumes_gadgets(h); break; case GAD_ADD_VOLUME: LT_LockWindow(win); add_edit_volume(h, true); LT_UnlockWindow(win); break; case GAD_EDIT_VOLUME: LT_LockWindow(win); add_edit_volume(h, false); LT_UnlockWindow(win); break; case GAD_REMOVE_VOLUME: remove_volume(h); break; case GAD_BOOTDRIVER: switch (code) { case 0: PrefsReplaceInt32("bootdriver", 0); break; case 1: PrefsReplaceInt32("bootdriver", CDROMRefNum); break; } break; case GAD_SCSI_MEMTYPE: PrefsReplaceInt32("scsimemtype", code); break; case GAD_VIDEO_TYPE: ghost_graphics_gadgets(h); break; case GAD_FRAMESKIP: switch (code) { case 0: PrefsReplaceInt32("frameskip", 12); break; case 1: PrefsReplaceInt32("frameskip", 8); break; case 2: PrefsReplaceInt32("frameskip", 6); break; case 3: PrefsReplaceInt32("frameskip", 4); break; case 4: PrefsReplaceInt32("frameskip", 2); break; case 5: PrefsReplaceInt32("frameskip", 1); break; } break; case GAD_MODELID: switch (code) { case 0: PrefsReplaceInt32("modelid", 5); break; case 1: PrefsReplaceInt32("modelid", 14); break; } break; } break; case IDCMP_IDCMPUPDATE: switch (gad->GadgetID) { case GAD_DISK_LIST: // Double-click on volumes list = edit volume LT_LockWindow(win); add_edit_volume(h, false); LT_UnlockWindow(win); break; case GAD_SCREEN_MODE: screen_mode_req(win, h); break; case GAD_AHI_MODE: ahi_mode_req(win, h); break; case GAD_CDROM_DEVICE: case GAD_SCSI0_DEVICE: case GAD_SCSI1_DEVICE: case GAD_SCSI2_DEVICE: case GAD_SCSI3_DEVICE: case GAD_SCSI4_DEVICE: case GAD_SCSI5_DEVICE: case GAD_SCSI6_DEVICE: case GAD_SERIALA_DEVICE: case GAD_SERIALB_DEVICE: if (dev_request) { LT_LockWindow(win); BOOL result = AslRequestTags(dev_request, ASLFR_Window, (ULONG)win, ASLFR_InitialDrawer, (ULONG) "Devs:", TAG_END); LT_UnlockWindow(win); if (result) { char *str; GT_GetGadgetAttrs(gad, win, NULL, GTST_String, (ULONG)&str, TAG_END); strncpy(str, dev_request->rf_File, 255); // Don't copy the directory part. This is usually "DEVS:" and we don't need that. str[255] = 0; LT_SetAttributes(h, gad->GadgetID, GTST_String, (ULONG)str, TAG_END); } } break; case GAD_ETHER_DEVICE: if (dev_request) { LT_LockWindow(win); BOOL result = AslRequestTags(dev_request, ASLFR_Window, (ULONG)win, ASLFR_InitialDrawer, (ULONG) "Devs:Networks", TAG_END); LT_UnlockWindow(win); if (result) { char *str; GT_GetGadgetAttrs(gad, win, NULL, GTST_String, (ULONG)&str, TAG_END); strncpy(str, dev_request->rf_File, 255); // Don't copy the directory part. This is usually "DEVS:" and we don't need that. str[255] = 0; LT_SetAttributes(h, gad->GadgetID, GTST_String, (ULONG)str, TAG_END); } } break; case GAD_ROM_FILE: if (file_request) { LT_LockWindow(win); BOOL result = AslRequestTags(file_request, ASLFR_Window, (ULONG)win, TAG_END); LT_UnlockWindow(win); if (result) { char *str; GT_GetGadgetAttrs(gad, win, NULL, GTST_String, (ULONG)&str, TAG_END); strncpy(str, file_request->rf_Dir, 255); str[255] = 0; AddPart(str, file_request->rf_File, 255); LT_SetAttributes(h, gad->GadgetID, GTST_String, (ULONG)str, TAG_END); } } break; } break; case IDCMP_MENUPICK: while (code != MENUNULL) { struct MenuItem *item = ItemAddress(menu, code); if (item == NULL) break; switch ((ULONG)GTMENUITEM_USERDATA(item)) { case MSG_OK: read_settings(h); SavePrefs(); retval = true; done = true; break; case MSG_CANCEL: retval = false; done = true; break; case MSG_ABOUT: { char str[256]; sprintf(str, GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR); strncat(str, "\n", 255); strncat(str, GetString(STR_ABOUT_TEXT2), 255); EasyStruct req; req.es_StructSize = sizeof(EasyStruct); req.es_Flags = 0; req.es_Title = (UBYTE *)GetString(STR_ABOUT_TITLE); req.es_TextFormat = (UBYTE *)str; req.es_GadgetFormat = (UBYTE *)GetString(STR_OK_BUTTON); LT_LockWindow(win); EasyRequest(win, &req, NULL); LT_UnlockWindow(win); break; } case MSG_ZAP_PRAM: ZapPRAM(); break; } code = item->NextSelect; } break; } } } while (!done); quit: // Free requesters FreeAslRequest(dev_request); FreeAslRequest(file_request); // Delete Menus LT_DisposeMenu(menu); // Delete handle LT_DeleteHandle(h); // Close gtlayout.library CloseLibrary(GTLayoutBase); return retval; } /* * "Volumes" pane */ static struct List disk_list; static char cdrom_name[256], extfs_name[256]; static ULONG cdrom_unit, cdrom_flags, cdrom_start, cdrom_size, cdrom_bsize; static BYTE bootdriver_num, nocdrom; // Read volumes preferences static void parse_volumes_prefs(void) { NewList(&disk_list); const char *str; for (int i=0; (str = PrefsFindString("disk", i)) != NULL; i++) { struct Node *item = (struct Node *)AllocMem(sizeof(struct Node), MEMF_CLEAR); item->ln_Name = (char *)str; AddTail(&disk_list, item); } cdrom_name[0] = 0; cdrom_unit = 0; cdrom_flags = 0; cdrom_start = 0; cdrom_size = 0; cdrom_bsize = 2048; str = PrefsFindString("cdrom"); if (str) sscanf(str, "/dev/%[^/]/%ld/%ld/%ld/%ld/%ld", cdrom_name, &cdrom_unit, &cdrom_flags, &cdrom_start, &cdrom_size, &cdrom_bsize); bootdriver_num = 0; int bootdriver = PrefsFindInt32("bootdriver"); switch (bootdriver) { case 0: bootdriver_num = 0; break; case CDROMRefNum: bootdriver_num = 1; break; } nocdrom = PrefsFindBool("nocdrom"); extfs_name[0] = 0; str = PrefsFindString("extfs"); if (str) strncpy(extfs_name, str, sizeof(extfs_name) - 1); } // Ghost/unghost "Edit" and "Remove" buttons static void ghost_volumes_gadgets(struct LayoutHandle *h) { UWORD sel = LT_GetAttributes(h, GAD_DISK_LIST, TAG_END); if (sel == 0xffff) { LT_SetAttributes(h, GAD_EDIT_VOLUME, GA_Disabled, TRUE, TAG_END); LT_SetAttributes(h, GAD_REMOVE_VOLUME, GA_Disabled, TRUE, TAG_END); } else { LT_SetAttributes(h, GAD_EDIT_VOLUME, GA_Disabled, FALSE, TAG_END); LT_SetAttributes(h, GAD_REMOVE_VOLUME, GA_Disabled, FALSE, TAG_END); } } // Get device data from partition name 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) { // Remove everything after and including the ':' char str[256]; strncpy(str, part, sizeof(str) - 1); str[sizeof(str) - 1] = 0; char *colon = strchr(str, ':'); if (colon) *colon = 0; // Look for partition struct DosList *dl = LockDosList(LDF_DEVICES | LDF_READ); dl = FindDosEntry(dl, str, LDF_DEVICES); if (dl) { // Get File System Startup Message struct FileSysStartupMsg *fssm = (struct FileSysStartupMsg *)(dl->dol_misc.dol_handler.dol_Startup << 2); if (fssm) { // Get DOS environment vector struct DosEnvec *de = (struct DosEnvec *)(fssm->fssm_Environ << 2); if (de && de->de_TableSize >= DE_UPPERCYL) { // Read settings from FSSM and Envec strncpy(dev_name, (char *)(fssm->fssm_Device << 2) + 1, 255); dev_name[255] = 0; dev_unit = fssm->fssm_Unit; dev_flags = fssm->fssm_Flags; dev_start = de->de_BlocksPerTrack * de->de_Surfaces * de->de_LowCyl; dev_size = de->de_BlocksPerTrack * de->de_Surfaces * (de->de_HighCyl - de->de_LowCyl + 1); dev_bsize = de->de_SizeBlock << 2; } } } UnLockDosList(LDF_DEVICES | LDF_READ); } // Display and handle "Add/Edit Volume" window static void add_edit_volume(struct LayoutHandle *h2, bool adding) { bool ok_clicked = false; UWORD sel = LT_GetAttributes(h2, GAD_DISK_LIST, TAG_END); if ((sel == 0xffff) && !adding) return; char dev_name[256] = ""; char file_name[256] = ""; ULONG dev_unit = 0, dev_flags = 0, dev_start = 0, dev_size = 0, dev_bsize = 512; BYTE read_only = false, is_device = false; if (!adding) { const char *str = PrefsFindString("disk", sel); if (str == NULL) return; if (str[0] == '*') { read_only = true; str++; } if (strstr(str, "/dev/") == str) { is_device = true; sscanf(str, "/dev/%[^/]/%ld/%ld/%ld/%ld/%ld", dev_name, &dev_unit, &dev_flags, &dev_start, &dev_size, &dev_bsize); } else { strncpy(file_name, str, sizeof(file_name) - 1); file_name[sizeof(file_name) - 1] = 0; } } // Create layout handle struct LayoutHandle *h = NULL; struct Window *win = NULL; h = LT_CreateHandleTags(NULL, LAHN_AutoActivate, FALSE, LAHN_LocaleHook, (ULONG)&locale_hook, TAG_END ); if (h == NULL) return; // Create window contents VGROUP; // Volume gadgets VGROUP; LT_New(h, LA_Type, CHECKBOX_KIND, LA_LabelID, STR_VOL_READONLY_CTRL, LA_ID, GAD_VOLUME_READONLY, LA_BYTE, (ULONG)&read_only, TAG_END ); LT_New(h, LA_Type, CYCLE_KIND, LA_LabelID, STR_VOL_TYPE_CTRL, LA_ID, GAD_VOLUME_TYPE, LACY_AutoPageID, GAD_VOLUME_PAGEGROUP, LACY_FirstLabel, STR_VOL_FILE_LAB, LACY_LastLabel, STR_VOL_DEVICE_LAB, LA_BYTE, (ULONG)&is_device, TAG_END ); ENDGROUP; LT_New(h, LA_Type, VERTICAL_KIND, LA_ID, GAD_VOLUME_PAGEGROUP, LAGR_ActivePage, is_device, TAG_END ); VGROUP; LT_New(h, LA_Type, STRING_KIND, LA_LabelID, STR_VOL_FILE_CTRL, LA_ID, GAD_VOLUME_FILE, LA_Chars, 20, LA_STRPTR, (ULONG)file_name, GTST_MaxChars, sizeof(file_name) - 1, LAST_Picker, TRUE, TAG_END ); ENDGROUP; VGROUP; LT_New(h, LA_Type, STRING_KIND, LA_LabelID, STR_DEVICE_CTRL, LA_ID, GAD_VOLUME_DEVICE, LA_Chars, 20, LA_STRPTR, (ULONG)dev_name, GTST_MaxChars, sizeof(dev_name) - 1, LAST_Picker, TRUE, TAG_END ); LT_New(h, LA_Type, INTEGER_KIND, LA_LabelID, STR_UNIT_CTRL, LA_ID, GAD_VOLUME_UNIT, LA_LONG, (ULONG)&dev_unit, LAIN_UseIncrementers, TRUE, GTIN_MaxChars, 8, TAG_END ); LT_New(h, LA_Type, INTEGER_KIND, LA_LabelID, STR_VOL_OPENFLAGS_CTRL, LA_ID, GAD_VOLUME_OPENFLAGS, LA_LONG, (ULONG)&dev_flags, LAIN_UseIncrementers, TRUE, GTIN_MaxChars, 8, TAG_END ); LT_New(h, LA_Type, INTEGER_KIND, LA_LabelID, STR_VOL_STARTBLOCK_CTRL, LA_ID, GAD_VOLUME_STARTBLOCK, LA_LONG, (ULONG)&dev_start, LAIN_UseIncrementers, TRUE, GTIN_MaxChars, 8, TAG_END ); LT_New(h, LA_Type, INTEGER_KIND, LA_LabelID, STR_VOL_SIZE_CTRL, LA_ID, GAD_VOLUME_SIZE, LA_LONG, (ULONG)&dev_size, LAIN_UseIncrementers, TRUE, GTIN_MaxChars, 8, TAG_END ); LT_New(h, LA_Type, INTEGER_KIND, LA_LabelID, STR_VOL_BLOCKSIZE_CTRL, LA_ID, GAD_VOLUME_BLOCKSIZE, LA_LONG, (ULONG)&dev_bsize, LAIN_UseIncrementers, TRUE, GTIN_MaxChars, 8, TAG_END ); ENDGROUP; ENDGROUP; // Separator between gadgets and buttons VGROUP; LT_New(h, LA_Type, XBAR_KIND, LAXB_FullSize, TRUE, TAG_END ); ENDGROUP; // "OK" and "Cancel" buttons LT_New(h, LA_Type, HORIZONTAL_KIND, LAGR_SameSize, TRUE, LAGR_Spread, TRUE, TAG_END ); LT_New(h, LA_Type, BUTTON_KIND, LA_LabelID, STR_OK_BUTTON, LA_ID, MSG_OK, LABT_ReturnKey, TRUE, TAG_END ); LT_New(h, LA_Type, BUTTON_KIND, LA_LabelID, STR_CANCEL_BUTTON, LA_ID, MSG_CANCEL, LABT_EscKey, TRUE, TAG_END ); ENDGROUP; ENDGROUP; // Open window win = LT_Build(h, LAWN_TitleID, adding ? STR_ADD_VOLUME_TITLE : STR_EDIT_VOLUME_TITLE, LAWN_IDCMP, IDCMP_CLOSEWINDOW, LAWN_BelowMouse, TRUE, LAWN_SmartZoom, TRUE, WA_SimpleRefresh, TRUE, WA_Activate, TRUE, WA_CloseGadget, TRUE, WA_DepthGadget, TRUE, WA_DragBar, TRUE, TAG_END ); if (win == NULL) { LT_DeleteHandle(h); return; } // Event loop bool done = false; do { struct IntuiMessage *msg; // Wait for message WaitPort(win->UserPort); // Get pending messages while (msg = LT_GetIMsg(h)) { // Get data from message and reply ULONG cl = msg->Class; UWORD code = msg->Code; struct Gadget *gad = (struct Gadget *)msg->IAddress; LT_ReplyIMsg(msg); // Handle message according to class switch (cl) { case IDCMP_CLOSEWINDOW: done = true; break; case IDCMP_GADGETUP: switch (gad->GadgetID) { case MSG_OK: ok_clicked = true; done = true; break; case MSG_CANCEL: done = true; break; } break; case IDCMP_IDCMPUPDATE: { struct FileRequester *req = NULL; switch (gad->GadgetID) { case GAD_VOLUME_FILE: req = file_request; goto do_req; case GAD_VOLUME_DEVICE: req = dev_request; do_req: if (req) { LT_LockWindow(win); BOOL result = AslRequestTags(req, ASLFR_Window, (ULONG)win, TAG_END); LT_UnlockWindow(win); if (result) { char *str; GT_GetGadgetAttrs(gad, win, NULL, GTST_String, (ULONG)&str, TAG_END); if (gad->GadgetID == GAD_VOLUME_FILE) { strncpy(str, req->rf_Dir, 255); str[255] = 0; AddPart(str, req->rf_File, 255); } else { if (strlen(req->rf_File)) { strncpy(str, req->rf_File, 255); // Don't copy the directory part. This is usually "DEVS:" and we don't need that. str[255] = 0; } else if (strlen(req->rf_Dir) && req->rf_Dir[strlen(req->rf_Dir) - 1] == ':') { analyze_partition(req->rf_Dir, str, dev_unit, dev_flags, dev_start, dev_size, dev_bsize); LT_SetAttributes(h, GAD_VOLUME_UNIT, GTIN_Number, dev_unit, TAG_END); LT_SetAttributes(h, GAD_VOLUME_OPENFLAGS, GTIN_Number, dev_flags, TAG_END); LT_SetAttributes(h, GAD_VOLUME_STARTBLOCK, GTIN_Number, dev_start, TAG_END); LT_SetAttributes(h, GAD_VOLUME_SIZE, GTIN_Number, dev_size, TAG_END); LT_SetAttributes(h, GAD_VOLUME_BLOCKSIZE, GTIN_Number, dev_bsize, TAG_END); } } LT_SetAttributes(h, gad->GadgetID, GTST_String, (ULONG)str, TAG_END); } } break; } break; } } } } while (!done); // Update preferences and list view if (ok_clicked) { char str[256]; LT_UpdateStrings(h); if (is_device) sprintf(str, "%s/dev/%s/%ld/%ld/%ld/%ld/%ld", read_only ? "*" : "", dev_name, dev_unit, dev_flags, dev_start, dev_size, dev_bsize); else sprintf(str, "%s%s", read_only ? "*" : "", file_name); LT_SetAttributes(h2, GAD_DISK_LIST, GTLV_Labels, ~0, TAG_END); if (adding) { // Add new item int i; PrefsAddString("disk", str); struct Node *item = (struct Node *)AllocMem(sizeof(struct Node), MEMF_CLEAR); for (i=0; PrefsFindString("disk", i); i++) ; item->ln_Name = (char *)PrefsFindString("disk", i - 1); AddTail(&disk_list, item); } else { // Replace existing item PrefsReplaceString("disk", str, sel); struct Node *item = disk_list.lh_Head; for (int i=0; item->ln_Succ; i++) { if (i == sel) { item->ln_Name = (char *)PrefsFindString("disk", sel); break; } item = item->ln_Succ; } } LT_SetAttributes(h2, GAD_DISK_LIST, GTLV_Labels, (ULONG)&disk_list, TAG_END); ghost_volumes_gadgets(h2); } // Delete handle LT_DeleteHandle(h); } // Remove volume from list static void remove_volume(struct LayoutHandle *h) { UWORD sel = LT_GetAttributes(h, GAD_DISK_LIST, TAG_END); if (sel != 0xffff) { // Remove item from preferences and list view LT_SetAttributes(h, GAD_DISK_LIST, GTLV_Labels, ~0, TAG_END); PrefsRemoveItem("disk", sel); struct Node *item = disk_list.lh_Head; for (int i=0; item->ln_Succ; i++) { struct Node *next = item->ln_Succ; if (i == sel) { Remove(item); FreeMem(item, sizeof(struct Node)); break; } item = next; } LT_SetAttributes(h, GAD_DISK_LIST, GTLV_Labels, (ULONG)&disk_list, GTLV_Selected, 0xffff, TAG_END); ghost_volumes_gadgets(h); } } // Read settings from gadgets and set preferences static void read_volumes_settings(void) { struct Node *item = disk_list.lh_Head; while (item->ln_Succ) { struct Node *next = item->ln_Succ; Remove(item); FreeMem(item, sizeof(struct Node)); item = next; } if (strlen(cdrom_name)) { char str[256]; sprintf(str, "/dev/%s/%ld/%ld/%ld/%ld/%ld", cdrom_name, cdrom_unit, cdrom_flags, cdrom_start, cdrom_size, cdrom_bsize); PrefsReplaceString("cdrom", str); } else PrefsRemoveItem("cdrom"); PrefsReplaceBool("nocdrom", nocdrom); if (strlen(extfs_name)) PrefsReplaceString("extfs", extfs_name); } // Create "Volumes" pane static void create_volumes_pane(struct LayoutHandle *h) { parse_volumes_prefs(); VGROUP; LT_New(h, LA_Type, VERTICAL_KIND, LA_LabelID, STR_VOLUMES_CTRL, TAG_END ); VGROUP; LT_New(h, LA_Type, LISTVIEW_KIND, LA_ID, GAD_DISK_LIST, LA_Chars, 20, GTLV_Labels, (ULONG)&disk_list, LALV_Lines, 6, LALV_Link, (ULONG)NIL_LINK, LALV_ResizeX, TRUE, LALV_ResizeY, TRUE, LALV_Selected, 0, TAG_END ); ENDGROUP; LT_New(h, LA_Type, HORIZONTAL_KIND, LAGR_SameSize, TRUE, LAGR_Spread, TRUE, TAG_END ); LT_New(h, LA_Type, BUTTON_KIND, LA_LabelID, STR_ADD_VOLUME_BUTTON, LA_ID, GAD_ADD_VOLUME, TAG_END ); LT_New(h, LA_Type, BUTTON_KIND, LA_LabelID, STR_EDIT_VOLUME_BUTTON, LA_ID, GAD_EDIT_VOLUME, TAG_END ); LT_New(h, LA_Type, BUTTON_KIND, LA_LabelID, STR_REMOVE_VOLUME_BUTTON, LA_ID, GAD_REMOVE_VOLUME, TAG_END ); ENDGROUP; ENDGROUP; LT_New(h, LA_Type, VERTICAL_KIND, LA_LabelID, STR_CDROM_DRIVE_CTRL, TAG_END ); LT_New(h, LA_Type, STRING_KIND, LA_LabelID, STR_DEVICE_CTRL, LA_ID, GAD_CDROM_DEVICE, LA_Chars, 20, LA_STRPTR, (ULONG)cdrom_name, GTST_MaxChars, sizeof(cdrom_name) - 1, LAST_Picker, TRUE, TAG_END ); LT_New(h, LA_Type, INTEGER_KIND, LA_LabelID, STR_UNIT_CTRL, LA_ID, GAD_CDROM_UNIT, LA_LONG, (ULONG)&cdrom_unit, LAIN_UseIncrementers, TRUE, GTIN_MaxChars, 8, TAG_END ); LT_New(h, LA_Type, CYCLE_KIND, LA_LabelID, STR_BOOTDRIVER_CTRL, LA_ID, GAD_BOOTDRIVER, LACY_FirstLabel, STR_BOOT_ANY_LAB, LACY_LastLabel, STR_BOOT_CDROM_LAB, LA_BYTE, (ULONG)&bootdriver_num, TAG_END ); LT_New(h, LA_Type, CHECKBOX_KIND, LA_LabelID, STR_NOCDROM_CTRL, LA_ID, GAD_NOCDROM, LA_BYTE, (ULONG)&nocdrom, TAG_END ); ENDGROUP; VGROUP; LT_New(h, LA_Type, STRING_KIND, LA_LabelID, STR_EXTFS_CTRL, LA_ID, GAD_EXTFS, LA_Chars, 20, LA_STRPTR, (ULONG)extfs_name, GTST_MaxChars, sizeof(extfs_name) - 1, TAG_END ); ENDGROUP; ENDGROUP; } /* * "SCSI" pane */ static char scsi_dev[6][256]; static LONG scsi_unit[6]; static LONG scsi_memtype; // Read SCSI preferences static void parse_scsi_prefs(void) { for (int i=0; i<7; i++) { scsi_dev[i][0] = 0; scsi_unit[i] = 0; char prefs_name[16]; sprintf(prefs_name, "scsi%d", i); const char *str = PrefsFindString(prefs_name); if (str) sscanf(str, "%[^/]/%ld", scsi_dev[i], &scsi_unit[i]); } scsi_memtype = PrefsFindInt32("scsimemtype"); } // Read settings from gadgets and set preferences static void read_scsi_settings(void) { for (int i=0; i<7; i++) { char prefs_name[16]; sprintf(prefs_name, "scsi%d", i); if (strlen(scsi_dev[i])) { char str[256]; sprintf(str, "%s/%ld", scsi_dev[i], scsi_unit[i]); PrefsReplaceString(prefs_name, str); } else PrefsRemoveItem(prefs_name); } } // Create "SCSI" pane static void create_scsi_pane(struct LayoutHandle *h) { parse_scsi_prefs(); VGROUP; LT_New(h, LA_Type, VERTICAL_KIND, LA_LabelID, STR_SCSI_DEVICES_CTRL, TAG_END ); for (int i=0; i<7; i++) { HGROUP; LT_New(h, LA_Type, TEXT_KIND, LA_LabelID, STR_SCSI_ID_0 + i, TAG_END ); LT_New(h, LA_Type, STRING_KIND, LA_LabelID, STR_DEVICE_CTRL, LA_ID, GAD_SCSI0_DEVICE + i, LA_Chars, 20, LA_STRPTR, (ULONG)scsi_dev[i], GTST_MaxChars, sizeof(scsi_dev[i]) - 1, LAST_Picker, TRUE, TAG_END ); LT_New(h, LA_Type, INTEGER_KIND, LA_LabelID, STR_UNIT_CTRL, LA_ID, GAD_SCSI0_UNIT + i, LA_Chars, 4, LA_LONG, (ULONG)&scsi_unit[i], LAIN_UseIncrementers, TRUE, GTIN_MaxChars, 8, TAG_END ); ENDGROUP; } ENDGROUP; VGROUP; LT_New(h, LA_Type, CYCLE_KIND, LA_LabelID, STR_SCSI_MEMTYPE_CTRL, LA_ID, GAD_SCSI_MEMTYPE, LACY_FirstLabel, STR_MEMTYPE_CHIP_LAB, LACY_LastLabel, STR_MEMTYPE_ANY_LAB, LA_LONG, (ULONG)&scsi_memtype, TAG_END ); ENDGROUP; ENDGROUP; } /* * "Graphics/Sound" pane */ // Display types enum { DISPLAY_WINDOW, DISPLAY_PIP, DISPLAY_SCREEN }; static LONG display_type; static LONG dis_width, dis_height; static ULONG mode_id; static BYTE frameskip_num; static struct NameInfo mode_name; static ULONG ahi_id; static char ahi_mode_name[256]; static BYTE nosound; // Read graphics preferences static void parse_graphics_prefs(void) { display_type = DISPLAY_WINDOW; dis_width = 512; dis_height = 384; mode_id = 0; ahi_id = AHI_DEFAULT_ID; ahi_mode_name[0] = 0; frameskip_num = 0; int frameskip = PrefsFindInt32("frameskip"); switch (frameskip) { case 12: frameskip_num = 0; break; case 8: frameskip_num = 1; break; case 6: frameskip_num = 2; break; case 4: frameskip_num = 3; break; case 2: frameskip_num = 4; break; case 1: frameskip_num = 5; break; } const char *str = PrefsFindString("screen"); if (str) { if (sscanf(str, "win/%ld/%ld", &dis_width, &dis_height) == 2) display_type = DISPLAY_WINDOW; else if (sscanf(str, "pip/%ld/%ld", &dis_width, &dis_height) == 2) display_type = DISPLAY_PIP; else if (sscanf(str, "scr/%08lx", &mode_id) == 1) display_type = DISPLAY_SCREEN; } GetDisplayInfoData(NULL, (UBYTE *)&mode_name, sizeof(mode_name), DTAG_NAME, mode_id); str = PrefsFindString("sound"); if (str) { if (sscanf(str, "ahi/%08lx", &ahi_id) == 1 && AHIBase) { AHI_GetAudioAttrs(ahi_id, NULL, AHIDB_Name, (ULONG)ahi_mode_name, AHIDB_BufferLen, sizeof(ahi_mode_name) - 1, TAG_END ); } } nosound = PrefsFindBool("nosound"); } // Ghost/unghost graphics gadgets, depending on display type static void ghost_graphics_gadgets(struct LayoutHandle *h) { bool dis_xy, dis_skip, dis_mode; switch (display_type) { case DISPLAY_WINDOW: dis_xy = false; dis_skip = false; dis_mode = true; break; case DISPLAY_PIP: dis_xy = false; dis_skip = true; dis_mode = true; break; case DISPLAY_SCREEN: dis_xy = true; dis_skip = true; dis_mode = false; break; } LT_SetAttributes(h, GAD_DISPLAY_X, GA_Disabled, dis_xy, TAG_END); LT_SetAttributes(h, GAD_DISPLAY_Y, GA_Disabled, dis_xy, TAG_END); LT_SetAttributes(h, GAD_FRAMESKIP, GA_Disabled, dis_skip, TAG_END); LT_SetAttributes(h, GAD_SCREEN_MODE, GA_Disabled, dis_mode, TAG_END); LT_SetAttributes(h, GAD_AHI_MODE, GA_Disabled, AHIBase == NULL, TAG_END); } // Show screen mode requester static void screen_mode_req(struct Window *win, struct LayoutHandle *h) { if (P96Base == NULL && CyberGfxBase == NULL) return; LT_LockWindow(win); ULONG id; // Try P96 first, because it also provides a (fake) cybergraphics.library if (P96Base) { id = p96RequestModeIDTags( P96MA_MinDepth, 8, P96MA_FormatsAllowed, RGBFF_CLUT | RGBFF_R5G5B5 | RGBFF_A8R8G8B8, TAG_END ); } else { UWORD ModelArray[] = { PIXFMT_LUT8, PIXFMT_RGB15, PIXFMT_ARGB32, 0, ~0 }; id = (ULONG) CModeRequestTags(NULL, CYBRMREQ_MinDepth, 8, CYBRMREQ_CModelArray, (ULONG) ModelArray, TAG_END ); } LT_UnlockWindow(win); if (id != INVALID_ID) { mode_id = id; GetDisplayInfoData(NULL, (UBYTE *)&mode_name, sizeof(mode_name), DTAG_NAME, mode_id); LT_SetAttributes(h, GAD_SCREEN_MODE, GTTX_Text, (ULONG)mode_name.Name, TAG_END); } } // Show AHI mode requester static void ahi_mode_req(struct Window *win, struct LayoutHandle *h) { if (AHIBase == NULL) return; struct AHIAudioModeRequester *req = AHI_AllocAudioRequest( AHIR_Window, (ULONG)win, TAG_END ); if (req == NULL) return; LT_LockWindow(win); BOOL ok = AHI_AudioRequest(req, AHIR_InitialAudioID, ahi_id, TAG_END ); LT_UnlockWindow(win); if (ok) { ahi_id = req->ahiam_AudioID; AHI_GetAudioAttrs(ahi_id, NULL, AHIDB_Name, (ULONG)ahi_mode_name, AHIDB_BufferLen, sizeof(ahi_mode_name) - 1, TAG_END ); LT_SetAttributes(h, GAD_AHI_MODE, GTTX_Text, (ULONG)ahi_mode_name, TAG_END); } AHI_FreeAudioRequest(req); } // Read settings from gadgets and set preferences static void read_graphics_settings(void) { char str[256]; switch (display_type) { case DISPLAY_WINDOW: sprintf(str, "win/%ld/%ld", dis_width, dis_height); break; case DISPLAY_PIP: sprintf(str, "pip/%ld/%ld", dis_width, dis_height); break; case DISPLAY_SCREEN: sprintf(str, "scr/%08lx", mode_id); break; default: PrefsRemoveItem("screen"); return; } PrefsReplaceString("screen", str); sprintf(str, "ahi/%08lx", ahi_id); PrefsReplaceString("sound", str); PrefsReplaceBool("nosound", nosound); } // Create "Graphics/Sound" pane static void create_graphics_pane(struct LayoutHandle *h) { parse_graphics_prefs(); VGROUP; LT_New(h, LA_Type, VERTICAL_KIND, LA_LabelID, STR_GRAPHICS_CTRL, TAG_END ); static const LONG labels[] = {STR_WINDOW_LAB, STR_PIP_LAB, STR_FULLSCREEN_LAB, -1}; LT_New(h, LA_Type, CYCLE_KIND, LA_LabelID, STR_VIDEO_TYPE_CTRL, LA_ID, GAD_VIDEO_TYPE, LACY_LabelTable, (ULONG)labels, LA_LONG, (ULONG)&display_type, TAG_END ); LT_New(h, LA_Type, INTEGER_KIND, LA_LabelID, STR_DISPLAY_X_CTRL, LA_ID, GAD_DISPLAY_X, LA_LONG, (ULONG)&dis_width, GTIN_MaxChars, 8, TAG_END ); LT_New(h, LA_Type, INTEGER_KIND, LA_LabelID, STR_DISPLAY_Y_CTRL, LA_ID, GAD_DISPLAY_Y, LA_LONG, (ULONG)&dis_height, GTIN_MaxChars, 8, TAG_END ); LT_New(h, LA_Type, POPUP_KIND, LA_LabelID, STR_FRAMESKIP_CTRL, LA_ID, GAD_FRAMESKIP, LAPU_FirstLabel, STR_REF_5HZ_LAB, LAPU_LastLabel, STR_REF_60HZ_LAB, LA_BYTE, (ULONG)&frameskip_num, TAG_END ); LT_New(h, LA_Type, TEXT_KIND, LA_LabelID, STR_SCREEN_MODE_CTRL, LA_ID, GAD_SCREEN_MODE, LA_Chars, DISPLAYNAMELEN, LATX_Picker, TRUE, GTTX_Text, (ULONG)mode_name.Name, GTTX_Border, TRUE, TAG_END ); ENDGROUP; LT_New(h, LA_Type, VERTICAL_KIND, LA_LabelID, STR_SOUND_CTRL, TAG_END ); LT_New(h, LA_Type, TEXT_KIND, LA_LabelID, STR_AHI_MODE_CTRL, LA_ID, GAD_AHI_MODE, LA_Chars, DISPLAYNAMELEN, LATX_Picker, TRUE, GTTX_Text, (ULONG)ahi_mode_name, GTTX_Border, TRUE, TAG_END ); LT_New(h, LA_Type, CHECKBOX_KIND, LA_LabelID, STR_NOSOUND_CTRL, LA_ID, GAD_NOSOUND, LA_BYTE, (ULONG)&nosound, TAG_END ); ENDGROUP; ENDGROUP; ghost_graphics_gadgets(h); } /* * "Serial/Network" pane */ static char seriala_dev[256], serialb_dev[256]; static LONG seriala_unit, serialb_unit; static BYTE seriala_ispar, serialb_ispar; static char ether_dev[256]; static ULONG ether_unit; // Read serial/network preferences static void parse_ser_prefs(const char *prefs, char *dev, LONG &unit, BYTE &ispar) { dev[0] = 0; unit = 0; ispar = false; const char *str = PrefsFindString(prefs); if (str) { if (str[0] == '*') { ispar = true; str++; } sscanf(str, "%[^/]/%ld", dev, &unit); } } static void parse_serial_prefs(void) { parse_ser_prefs("seriala", seriala_dev, seriala_unit, seriala_ispar); parse_ser_prefs("serialb", serialb_dev, serialb_unit, serialb_ispar); ether_dev[0] = 0; ether_unit = 0; const char *str = PrefsFindString("ether"); if (str) { const char *FirstSlash = strchr(str, '/'); const char *LastSlash = strrchr(str, '/'); if (FirstSlash && FirstSlash && FirstSlash != LastSlash) { // Device name contains path, i.e. "Networks/xyzzy.device" const char *lp = str; char *dp = ether_dev; while (lp != LastSlash) *dp++ = *lp++; *dp = '\0'; sscanf(LastSlash, "/%ld", ðer_unit); // printf("dev=<%s> unit=%d\n", ether_dev, ether_unit); } else { sscanf(str, "%[^/]/%ld", ether_dev, ðer_unit); } } } // Set serial preference item static void make_serial_prefs(const char *prefs, const char *dev, LONG unit, BYTE ispar) { if (strlen(dev)) { char str[256]; sprintf(str, "%s%s/%ld", ispar ? "*" : "", dev, unit); PrefsReplaceString(prefs, str); } else PrefsRemoveItem(prefs); } // Read settings from gadgets and set preferences static void read_serial_settings(void) { make_serial_prefs("seriala", seriala_dev, seriala_unit, seriala_ispar); make_serial_prefs("serialb", serialb_dev, serialb_unit, serialb_ispar); if (strlen(ether_dev)) { char str[256]; sprintf(str, "%s/%ld", ether_dev, ether_unit); PrefsReplaceString("ether", str); } else PrefsRemoveItem("ether"); } // Create "Serial/Network" pane static void create_serial_pane(struct LayoutHandle *h) { parse_serial_prefs(); VGROUP; LT_New(h, LA_Type, VERTICAL_KIND, LA_LabelID, STR_SERIALA_CTRL, TAG_END ); LT_New(h, LA_Type, STRING_KIND, LA_LabelID, STR_DEVICE_CTRL, LA_ID, GAD_SERIALA_DEVICE, LA_Chars, 20, LA_STRPTR, (ULONG)seriala_dev, GTST_MaxChars, sizeof(seriala_dev) - 1, LAST_Picker, TRUE, TAG_END ); LT_New(h, LA_Type, INTEGER_KIND, LA_LabelID, STR_UNIT_CTRL, LA_ID, GAD_SERIALA_UNIT, LA_LONG, (ULONG)&seriala_unit, LAIN_UseIncrementers, TRUE, GTIN_MaxChars, 8, TAG_END ); LT_New(h, LA_Type, CHECKBOX_KIND, LA_LabelID, STR_ISPAR_CTRL, LA_ID, GAD_SERIALA_ISPAR, LA_BYTE, (ULONG)&seriala_ispar, TAG_END ); ENDGROUP; LT_New(h, LA_Type, VERTICAL_KIND, LA_LabelID, STR_SERIALB_CTRL, TAG_END ); LT_New(h, LA_Type, STRING_KIND, LA_LabelID, STR_DEVICE_CTRL, LA_ID, GAD_SERIALB_DEVICE, LA_Chars, 20, LA_STRPTR, (ULONG)serialb_dev, GTST_MaxChars, sizeof(serialb_dev) - 1, LAST_Picker, TRUE, TAG_END ); LT_New(h, LA_Type, INTEGER_KIND, LA_LabelID, STR_UNIT_CTRL, LA_ID, GAD_SERIALB_UNIT, LA_LONG, (ULONG)&serialb_unit, LAIN_UseIncrementers, TRUE, GTIN_MaxChars, 8, TAG_END ); LT_New(h, LA_Type, CHECKBOX_KIND, LA_LabelID, STR_ISPAR_CTRL, LA_ID, GAD_SERIALB_ISPAR, LA_BYTE, (ULONG)&serialb_ispar, TAG_END ); ENDGROUP; LT_New(h, LA_Type, VERTICAL_KIND, LA_LabelID, STR_ETHERNET_IF_CTRL, TAG_END ); LT_New(h, LA_Type, STRING_KIND, LA_LabelID, STR_DEVICE_CTRL, LA_ID, GAD_ETHER_DEVICE, LA_Chars, 20, LA_STRPTR, (ULONG)ether_dev, GTST_MaxChars, sizeof(ether_dev) - 1, LAST_Picker, TRUE, TAG_END ); LT_New(h, LA_Type, INTEGER_KIND, LA_LabelID, STR_UNIT_CTRL, LA_ID, GAD_ETHER_UNIT, LA_LONG, (ULONG)ðer_unit, LAIN_UseIncrementers, TRUE, GTIN_MaxChars, 8, TAG_END ); ENDGROUP; ENDGROUP; } /* * "Memory/Misc" pane */ static ULONG ramsize_mb; static BYTE model_num; static char rom_file[256]; // Read memory/misc preferences static void parse_memory_prefs(void) { ramsize_mb = PrefsFindInt32("ramsize") >> 20; model_num = 0; int id = PrefsFindInt32("modelid"); switch (id) { case 5: model_num = 0; break; case 14: model_num = 1; break; } rom_file[0] = 0; const char *str = PrefsFindString("rom"); if (str) { strncpy(rom_file, str, sizeof(rom_file) - 1); rom_file[sizeof(rom_file) - 1] = 0; } } // Read settings from gadgets and set preferences static void read_memory_settings(void) { PrefsReplaceInt32("ramsize", ramsize_mb << 20); if (strlen(rom_file)) PrefsReplaceString("rom", rom_file); else PrefsRemoveItem("rom"); } // Create "Memory/Misc" pane static void create_memory_pane(struct LayoutHandle *h) { parse_memory_prefs(); VGROUP; LT_New(h, LA_Type, LEVEL_KIND, LA_LabelID, STR_RAMSIZE_SLIDER, LA_ID, GAD_RAMSIZE, LA_Chars, 20, LA_LONG, (ULONG)&ramsize_mb, GTSL_LevelFormat, (ULONG)GetString(STR_RAMSIZE_FMT), GTSL_Min, 1, GTSL_Max, AvailMem(MEMF_LARGEST) >> 20, TAG_END ); LT_New(h, LA_Type, CYCLE_KIND, LA_LabelID, STR_MODELID_CTRL, LA_ID, GAD_MODELID, LACY_FirstLabel, STR_MODELID_5_LAB, LACY_LastLabel, STR_MODELID_14_LAB, LA_BYTE, (ULONG)&model_num, TAG_END ); LT_New(h, LA_Type, STRING_KIND, LA_LabelID, STR_ROM_FILE_CTRL, LA_ID, GAD_ROM_FILE, LA_Chars, 20, LA_STRPTR, (ULONG)rom_file, GTST_MaxChars, sizeof(rom_file) - 1, LAST_Picker, TRUE, TAG_END ); ENDGROUP; } /* * Read settings from gadgets and set preferences */ static void read_settings(struct LayoutHandle *h) { LT_UpdateStrings(h); read_volumes_settings(); read_scsi_settings(); read_graphics_settings(); read_serial_settings(); read_memory_settings(); }