Annotation of nono/wx/wxmainframe.cpp, revision 1.1.1.21

1.1       root        1: //
                      2: // nono
1.1.1.4   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
1.1.1.13  root        7: //
                      8: // メインウィンドウ
                      9: //
                     10: 
1.1.1.4   root       11: #include "wxmainframe.h"
1.1.1.13  root       12: #include "fontmanager.h"
1.1.1.18  root       13: #include "wxaccstatmonitor.h"
1.1.1.15  root       14: #include "wxdipswwindow.h"
1.1.1.4   root       15: #include "wxdumpmonitor.h"
1.1.1.5   root       16: #include "wxlcdwindow.h"
1.1.1.4   root       17: #include "wxlogmonitor.h"
1.1.1.13  root       18: #include "wxlogsetting.h"
1.1.1.4   root       19: #include "wxmainview.h"
                     20: #include "wxmonitor.h"
                     21: #include "wxmpumonitor.h"
1.1.1.15  root       22: #include "wxpalettemonitor.h"
1.1.1.14  root       23: #include "wxplanemonitor.h"
                     24: #include "wxromwindow.h"
1.1.1.4   root       25: #include "wxsoftkey.h"
1.1.1.9   root       26: #include "wxstatuspanel.h"
1.1.1.11  root       27: #include "wxuimessage.h"
1.1.1.4   root       28: #include "wxversion.h"
1.1.1.13  root       29: #include "config.h"
1.1.1.14  root       30: #include "fdc.h"
                     31: #include "fdd.h"
1.1.1.3   root       32: #include "mainapp.h"
1.1.1.17  root       33: #include "mpu.h"
1.1.1.13  root       34: #include "nmi.h"
                     35: #include "power.h"
1.1.1.18  root       36: #include "scsidev.h"
1.1.1.21! root       37: #include "scsidomain.h"
1.1.1.15  root       38: #include "syncer.h"
                     39: #include <algorithm>
1.1       root       40: 
1.1.1.13  root       41: // ID は 0 から (wxID_LOWEST = 5000 未満まで) 使えるっぽい。
                     42: // メニュー ID のうちウィンドウのオープン状態を維持する必要があるものは
                     43: // (ID が 0 から使えるのなら) 0 から割り当てて配列で管理してしまうのが
                     44: // 手っ取り早い。
                     45: // ウィンドウに割り当てるウィンドウ ID とメニューイベントで飛んでくる
                     46: // メニュー ID は互いに干渉しないはずなので、同じ値を使うことでメニューと
                     47: // ウィンドウの紐付けをする。
                     48: //
                     49: // ウィンドウ(サブウィンドウ)は細かくは以下のように4つに分類できるが、
                     50: // 処理上区別が必要なのは A. (デバッガの show コマンドとも共用できる
                     51: // サブウィンドウ) とそれ以外のサブウィンドウだけ。
                     52: //
                     53: // -----------+------------+----
                     54: // モニター   | テキスト   | A. 単純なテキストモニタウィンドウ
                     55: // ウィンドウ | モニター   |    (SPC, MFP などのデバイスのモニター)
                     56: //            | ウィンドウ +----
                     57: //            |            | B. それ以外のテキストモニターウィンドウ
                     58: //            |            |    (ログ、メモリのように表示位置があるもの、
                     59: //            |            |     CMMU のように構造があるもの)
                     60: //            +------------+----
                     61: //            | それ以外の | C. ビデオモニターウィンドウなど
                     62: //            | モニター   |    (ビットマッププレーン、TVRAM など)
                     63: //            | ウィンドウ |
                     64: // -----------+------------+----
                     65: // それ以外のウィンドウ    | D. ソフトウェアキーボードウィンドウなど
                     66: // ------------------------+----
                     67: enum {
                     68:        ID_SUBWIN_END_DUMMY = ID_SUBWIN_END,
                     69: 
                     70:        // ここから (ウィンドウでない)メニュー ID
1.1.1.15  root       71:        ID_EXIT,
1.1.1.13  root       72:        ID_RESTART_VM,
1.1.1.17  root       73:        ID_POWER_BUTTON,
                     74:        ID_SOFTRESET,
                     75:        ID_RESET_BUTTON,
                     76:        ID_NMI_BUTTON,
                     77: 
1.1.1.13  root       78:        ID_FULL_SPEED,
                     79: 
                     80:        ID_INPUT_START,
                     81:        ID_INPUT_CHAR,
                     82:        ID_INPUT_JP,
                     83:        ID_INPUT_END,
                     84: 
                     85:        ID_SCALE_START,
1.1.1.15  root       86:        ID_SCALE_END = ID_SCALE_START + 6,
1.1.1.13  root       87: 
                     88:        ID_FONTSIZE_START, // START 以降は fontsize_t と同じ順に並べること
                     89:        ID_FONTSIZE_12,
                     90:        ID_FONTSIZE_16,
1.1.1.15  root       91:        ID_FONTSIZE_24,
1.1.1.13  root       92:        ID_FONTSIZE_END,
                     93: 
1.1.1.21! root       94:        ID_DEVICE_EMPTY,
        !            95: 
1.1.1.13  root       96:        ID_MONRATE_START,
1.1.1.15  root       97:        ID_MONRATE_END = ID_MONRATE_START + 4,
1.1.1.13  root       98: 
                     99:        ID_SHOW_STATPANEL,
                    100: 
1.1.1.14  root      101:        // FD
                    102:        ID_FD_INSERT_0,
                    103:        ID_FD_INSERT_1,
                    104:        ID_FD_INSERT_2,
                    105:        ID_FD_INSERT_3,
                    106:        ID_FD_MISINSERT_0,
                    107:        ID_FD_MISINSERT_1,
                    108:        ID_FD_MISINSERT_2,
                    109:        ID_FD_MISINSERT_3,
                    110:        ID_FD_EJECT_0,
                    111:        ID_FD_EJECT_1,
                    112:        ID_FD_EJECT_2,
                    113:        ID_FD_EJECT_3,
                    114:        ID_FD_FORCE_0,
                    115:        ID_FD_FORCE_1,
                    116:        ID_FD_FORCE_2,
                    117:        ID_FD_FORCE_3,
                    118: 
1.1.1.13  root      119:        // CD/MO (リムーバブルデバイス)
                    120:        ID_CD_INSERT_0,
                    121:        ID_CD_INSERT_1,
                    122:        ID_CD_INSERT_2,
                    123:        ID_CD_INSERT_3,
                    124:        ID_CD_INSERT_4,
                    125:        ID_CD_INSERT_5,
                    126:        ID_CD_INSERT_6,
                    127:        ID_CD_INSERT_7,
                    128:        ID_CD_EJECT_0,
                    129:        ID_CD_EJECT_1,
                    130:        ID_CD_EJECT_2,
                    131:        ID_CD_EJECT_3,
                    132:        ID_CD_EJECT_4,
                    133:        ID_CD_EJECT_5,
                    134:        ID_CD_EJECT_6,
                    135:        ID_CD_EJECT_7,
                    136:        ID_CD_FORCE_0,
                    137:        ID_CD_FORCE_1,
                    138:        ID_CD_FORCE_2,
                    139:        ID_CD_FORCE_3,
                    140:        ID_CD_FORCE_4,
                    141:        ID_CD_FORCE_5,
                    142:        ID_CD_FORCE_6,
                    143:        ID_CD_FORCE_7,
                    144: 
                    145:        ID_MOUSEMODE,
                    146:        ID_KEYBOARD_CONNECT,
                    147: 
                    148:        ID_local_end,   // 最後に置く (チェック用)
                    149: };
1.1.1.14  root      150: static_assert(ID_local_end - 1 <= (int)IDGROUP_MAINFRAME_END, "ID exceeded");
1.1.1.13  root      151: 
1.1.1.14  root      152: #define ID_FD_INSERT(id)       (ID_FD_INSERT_0 + (id))
                    153: #define ID_FD_MISINSERT(id)    (ID_FD_MISINSERT_0 + (id))
                    154: #define ID_FD_EJECT(id)                (ID_FD_EJECT_0 + (id))
                    155: #define ID_FD_FORCE(id)                (ID_FD_FORCE_0 + (id))
1.1.1.13  root      156: #define ID_CD_INSERT(id)       (ID_CD_INSERT_0 + (id))
                    157: #define ID_CD_EJECT(id)        (ID_CD_EJECT_0 + (id))
                    158: #define ID_CD_FORCE(id)        (ID_CD_FORCE_0 + (id))
                    159: 
1.1       root      160: wxBEGIN_EVENT_TABLE(WXMainFrame, inherited)
1.1.1.3   root      161:        EVT_CLOSE(WXMainFrame::OnClose)
1.1.1.15  root      162:        EVT_MENU(ID_EXIT, WXMainFrame::OnExit)
1.1       root      163: 
1.1.1.17  root      164:        EVT_MENU(ID_POWER_BUTTON, WXMainFrame::OnPowerButton)
                    165:        EVT_UPDATE_UI(ID_POWER_BUTTON, WXMainFrame::OnPowerButtonUI)
                    166:        EVT_MENU(ID_SOFTRESET, WXMainFrame::OnSoftReset)
                    167:        EVT_MENU(ID_RESET_BUTTON, WXMainFrame::OnResetButton)
                    168:        EVT_MENU(ID_NMI_BUTTON, WXMainFrame::OnNMIButton)
1.1.1.12  root      169:        EVT_MENU(ID_RESTART_VM, WXMainFrame::OnRestartVM)
1.1.1.17  root      170: 
1.1       root      171:        EVT_MENU(ID_FULL_SPEED, WXMainFrame::OnFullSpeed)
                    172:        EVT_UPDATE_UI(ID_FULL_SPEED, WXMainFrame::OnFullSpeedUI)
1.1.1.12  root      173:        EVT_MENU_RANGE(ID_INPUT_START + 1, ID_INPUT_END - 1,
                    174:                WXMainFrame::OnMenuInput)
                    175:        EVT_UPDATE_UI_RANGE(ID_INPUT_START + 1, ID_INPUT_END -1,
                    176:                WXMainFrame::OnMenuInputUI)
1.1.1.15  root      177:        EVT_MENU_RANGE(ID_SCALE_START, ID_SCALE_END,
1.1       root      178:                WXMainFrame::OnMenuScale)
1.1.1.15  root      179:        EVT_UPDATE_UI_RANGE(ID_SCALE_START, ID_SCALE_END,
1.1       root      180:                WXMainFrame::OnMenuScaleUI)
                    181:        EVT_MENU_RANGE(ID_FONTSIZE_START + 1, ID_FONTSIZE_END - 1,
                    182:                WXMainFrame::OnMenuFontSize)
                    183:        EVT_UPDATE_UI_RANGE(ID_FONTSIZE_START + 1, ID_FONTSIZE_END - 1,
                    184:                WXMainFrame::OnMenuFontSizeUI)
1.1.1.15  root      185:        EVT_MENU_RANGE(ID_MONRATE_START, ID_MONRATE_END,
1.1.1.5   root      186:                WXMainFrame::OnMenuMonRate)
1.1.1.15  root      187:        EVT_UPDATE_UI_RANGE(ID_MONRATE_START, ID_MONRATE_END,
1.1.1.5   root      188:                WXMainFrame::OnMenuMonRateUI)
1.1.1.9   root      189:        EVT_MENU(ID_SHOW_STATPANEL, WXMainFrame::OnShowStatusPanel)
                    190:        EVT_UPDATE_UI(ID_SHOW_STATPANEL, WXMainFrame::OnShowStatusPanelUI)
1.1.1.14  root      191:        EVT_MENU_RANGE(ID_FD_INSERT_0, ID_FD_INSERT_3,
                    192:                WXMainFrame::OnFDInsert)
                    193:        EVT_UPDATE_UI_RANGE(ID_FD_INSERT_0, ID_FD_INSERT_3,
                    194:                WXMainFrame::OnFDInsertUI)
                    195:        EVT_MENU_RANGE(ID_FD_EJECT_0, ID_FD_EJECT_3,
                    196:                WXMainFrame::OnFDEject)
                    197:        EVT_UPDATE_UI_RANGE(ID_FD_EJECT_0, ID_FD_EJECT_3,
                    198:                WXMainFrame::OnFDEjectUI)
                    199:        EVT_MENU_RANGE(ID_FD_FORCE_0, ID_FD_FORCE_3,
                    200:                WXMainFrame::OnFDForce)
                    201:        EVT_UPDATE_UI_RANGE(ID_FD_FORCE_0, ID_FD_FORCE_3,
                    202:                WXMainFrame::OnFDForceUI)
1.1.1.11  root      203:        EVT_MENU_RANGE(ID_CD_INSERT_0, ID_CD_INSERT_7,
                    204:                WXMainFrame::OnCDInsert)
                    205:        EVT_UPDATE_UI_RANGE(ID_CD_INSERT_0, ID_CD_INSERT_7,
                    206:                WXMainFrame::OnCDInsertUI)
                    207:        EVT_MENU_RANGE(ID_CD_EJECT_0, ID_CD_EJECT_7,
                    208:                WXMainFrame::OnCDEject)
                    209:        EVT_UPDATE_UI_RANGE(ID_CD_EJECT_0, ID_CD_EJECT_7,
                    210:                WXMainFrame::OnCDEjectUI)
                    211:        EVT_MENU_RANGE(ID_CD_FORCE_0, ID_CD_FORCE_7,
                    212:                WXMainFrame::OnCDForce)
                    213:        EVT_UPDATE_UI_RANGE(ID_CD_FORCE_0, ID_CD_FORCE_7,
                    214:                WXMainFrame::OnCDForceUI)
1.1.1.2   root      215:        EVT_MENU(ID_MOUSEMODE, WXMainFrame::OnMouseMode)
                    216:        EVT_UPDATE_UI(ID_MOUSEMODE, WXMainFrame::OnMouseModeUI)
1.1.1.13  root      217:        EVT_MENU(ID_KEYBOARD_CONNECT, WXMainFrame::OnKeyboardConnect)
                    218:        EVT_UPDATE_UI(ID_KEYBOARD_CONNECT, WXMainFrame::OnKeyboardConnectUI)
1.1.1.10  root      219:        EVT_MENU_RANGE(0, ID_SUBWIN_END, WXMainFrame::OnWindow)
                    220:        EVT_UPDATE_UI_RANGE(0, ID_SUBWIN_END, WXMainFrame::OnWindowUI)
1.1.1.4   root      221:        EVT_MENU(wxID_ABOUT, WXMainFrame::OnAbout)
1.1       root      222: wxEND_EVENT_TABLE()
                    223: 
                    224: WXMainFrame::WXMainFrame(wxWindow *parent)
1.1.1.10  root      225:        : inherited(parent, wxID_ANY, "nono", wxDefaultPosition, wxDefaultSize,
1.1.1.6   root      226:                wxDEFAULT_FRAME_STYLE & ~wxMAXIMIZE_BOX & ~wxRESIZE_BORDER)
1.1       root      227: {
1.1.1.15  root      228:        // デバイスを取得
                    229:        power = GetPowerDevice();
                    230:        syncer = GetSyncer();
                    231:        // デバイスを取得。こっちはあるかどうかを調べる
                    232:        keyboard = gMainApp.FindObject<Keyboard>(OBJ_KEYBOARD);
                    233: 
1.1.1.18  root      234:        // メイン MPU 名を取得。メニューとタイトルによく出てくるので。
                    235:        // "88xx0" とか "88200" は別処理。
                    236:        mpuname = GetMPUDevice()->GetMPUName();
                    237: 
1.1.1.12  root      238:        // メニュー
1.1       root      239:        wxMenuBar *menubar = new wxMenuBar();
1.1.1.17  root      240:        // メニュー > VM
                    241:        wxMenu *menuVM = new wxMenu();
                    242:        wxItemKind power_button_kind;
                    243:        if (gMainApp.Has(VMCap::LUNA)) {
                    244:                power_button_kind = wxITEM_NORMAL;
                    245:        } else {
                    246:                power_button_kind = wxITEM_CHECK;
                    247:        }
                    248:        menuVM->Append(ID_POWER_BUTTON, _("Push &Power button"),
                    249:                "", power_button_kind);
                    250:        if (gMainApp.IsX68030()) {
                    251:                menuVM->Append(ID_SOFTRESET, _("Send &CTRL+OPT.1+DEL"));
                    252:        }
                    253:        menuVM->Append(ID_RESET_BUTTON, _("Push &Reset button"));
                    254:        if (gMainApp.Has(VMCap::LUNA)) {
                    255:                menuVM->Append(ID_NMI_BUTTON, _("Push &ABORT button"));
                    256:        } else if (gMainApp.Has(VMCap::X68030)) {
                    257:                menuVM->Append(ID_NMI_BUTTON, _("Push &Interrupt button"));
1.1.1.16  root      258:        }
1.1.1.17  root      259:        menuVM->AppendSeparator();
                    260:        menuVM->Append(ID_RESTART_VM, _("&Restart VM (For developers)"), "");
                    261:        menuVM->AppendSeparator();
                    262:        menuVM->Append(ID_EXIT, _("E&xit"));
                    263:        menubar->Append(menuVM, _("&VM"));
1.1       root      264: 
1.1.1.12  root      265:        // メニュー > 設定
                    266:        wxMenu *menuSet = new wxMenu();
1.1.1.16  root      267:        menuSet->AppendCheckItem(ID_FULL_SPEED, _("Full &Speed Mode"));
1.1.1.15  root      268:        if (keyboard) {
                    269:                wxMenu *menuSetInput = new wxMenu();
                    270:                menuSetInput->AppendRadioItem(ID_INPUT_CHAR, _("By &Character"));
                    271:                menuSetInput->AppendRadioItem(ID_INPUT_JP, _("&JP Keyboard"));
                    272:                menuSet->AppendSubMenu(menuSetInput, _("&Key Input"));
                    273:        }
1.1.1.12  root      274:        menubar->Append(menuSet, _("&Setting"));
                    275: 
                    276:        // メニュー > 表示
1.1       root      277:        wxMenu *menuDisplay = new wxMenu();
                    278:        wxMenu *menuViewScale = new wxMenu();
1.1.1.15  root      279:        int user_idx = CreateMainviewScaleTable();
                    280:        for (int i = 0, end = view_scales.size(); i < end; i++) {
                    281:                std::string text;
                    282:                if (i == user_idx) {
                    283:                        // ユーザ指定値は極力指定されたまま表示。
                    284:                        text = string_format("x%g", view_scales[i]);
                    285:                } else {
                    286:                        // プリセットの数値は "0.5", "0.75", "1.0" と都合よく整形したい。
                    287:                        text = string_format("x%.2f", view_scales[i]);
                    288:                        if (text.size() == 5 && text[4] == '0') {
                    289:                                text.pop_back();
                    290:                        }
                    291:                }
                    292:                menuViewScale->AppendRadioItem(ID_SCALE_START + i, text);
                    293:        }
1.1.1.4   root      294:        menuDisplay->AppendSubMenu(menuViewScale, _("&Scale"));
1.1       root      295:        wxMenu *menuFontSize = new wxMenu();
1.1.1.4   root      296:        menuFontSize->AppendRadioItem(ID_FONTSIZE_12, "1&2");
                    297:        menuFontSize->AppendRadioItem(ID_FONTSIZE_16, "1&6");
1.1.1.15  root      298:        menuFontSize->AppendRadioItem(ID_FONTSIZE_24, "2&4");
1.1.1.4   root      299:        menuDisplay->AppendSubMenu(menuFontSize, _("&Font Size"));
1.1.1.5   root      300:        wxMenu *menuMonRate = new wxMenu();
1.1.1.21! root      301:        CreateMonRateTable();
1.1.1.15  root      302:        for (int i = 0, end = monrates.size(); i < end; i++) {
                    303:                std::string text;
                    304:                switch (monrates[i]) {
                    305:                 case 20:       text = _("High (&20Hz)");       break;
                    306:                 case  5:       text = _("Middle (&5Hz)");      break;
                    307:                 case  1:       text = _("Low (&1Hz)");         break;
                    308:                 default:
                    309:                        text = _("User specified") + string_format(" (%dHz)", monrates[i]);
                    310:                        break;
                    311:                }
                    312:                menuMonRate->AppendRadioItem(ID_MONRATE_START + i, text);
                    313:        }
1.1.1.5   root      314:        menuDisplay->AppendSubMenu(menuMonRate, _("&Monitor Speed"));
1.1.1.16  root      315:        menuDisplay->AppendCheckItem(ID_SHOW_STATPANEL, _("Show Status &Panel"));
1.1.1.17  root      316:        menubar->Append(menuDisplay, _("V&iew"));
1.1       root      317: 
1.1.1.12  root      318:        // メニュー > デバイス
1.1       root      319:        wxMenu *menuDevice = new wxMenu();
1.1.1.11  root      320:        CreateRemovableMenu(menuDevice);
1.1.1.15  root      321:        if (keyboard) {
1.1.1.16  root      322:                menuDevice->AppendCheckItem(ID_SUBWIN_SOFTKEY, _("Software &Keyboard"));
                    323:                menuDevice->AppendCheckItem(ID_MOUSEMODE, _("&Mouse Mode\tCTRL+F12"));
1.1.1.15  root      324:        }
1.1.1.16  root      325:        if (gMainApp.FindObject(OBJ_LCD)) {
                    326:                menuDevice->AppendCheckItem(ID_SUBWIN_LCDPANEL, _("Front &LCD"));
1.1.1.5   root      327:        }
1.1.1.16  root      328:        if (gMainApp.FindObject(OBJ_DIPSW)) {
                    329:                menuDevice->AppendCheckItem(ID_SUBWIN_DIPSW, "&DIPSW");
1.1.1.15  root      330:        }
1.1.1.17  root      331:        // 今はこれしかないので
1.1.1.15  root      332:        if (keyboard) {
1.1.1.17  root      333:                wxMenu *menuOper = new wxMenu();
1.1.1.16  root      334:                menuOper->AppendCheckItem(ID_KEYBOARD_CONNECT, _("Connect &Keyboard"));
1.1.1.17  root      335:                menuDevice->AppendSubMenu(menuOper, _("&Operation"));
1.1.1.15  root      336:        }
1.1.1.21! root      337:        // アイテムが何もなければ本当はメニューバーのアイテムを無効にしたいが、
        !           338:        // それは出来ないっぽい。何かアイテムを置かないと変なパネルが出たりする。
        !           339:        if (menuDevice->GetMenuItems().IsEmpty()) {
        !           340:                // TRANSLATORS: This is "Device > Nothing" in the menubar.
        !           341:                menuDevice->Append(ID_DEVICE_EMPTY, _("Nothing"));
        !           342:                menuDevice->Enable(ID_DEVICE_EMPTY, false);
        !           343:        }
1.1.1.4   root      344:        menubar->Append(menuDevice, _("&Device"));
                    345: 
1.1.1.14  root      346: #define AppendIfSeparator(menu, vmcap_)        do { \
                    347:        if (gMainApp.Has(vmcap_)) { \
1.1.1.10  root      348:                (menu)->AppendSeparator(); \
1.1.1.4   root      349:        } \
                    350: } while (0)
1.1       root      351: 
1.1.1.12  root      352:        // メニュー > モニター
1.1       root      353:        wxMenu *menuMonitor = new wxMenu();
1.1.1.10  root      354:        AppendIf(menuMonitor, ID_MONITOR_SCHEDULER,     _("&Scheduler"));
1.1.1.5   root      355: 
1.1.1.4   root      356:        wxMenu *menuMPU = new wxMenu();
1.1.1.10  root      357:        AppendIf(menuMPU, ID_MONITOR_MPUREG,            _("&Register"));
                    358:        AppendIf(menuMPU, ID_MONITOR_MPUATC,              "&ATC");
1.1.1.17  root      359:        AppendIf(menuMPU, ID_MONITOR_MPUCACHE,          _("Cache"));
1.1.1.15  root      360:        AppendIf(menuMPU, ID_MONITOR_INTERRUPT,         _("&Interrupt"));
1.1.1.14  root      361:        AppendIfSeparator(menuMPU, VMCap::M88K);
1.1.1.13  root      362:        AppendIf(menuMPU, ID_MONITOR_CMMU7,                      "CMMU#7" + _("(Inst)"));
1.1.1.10  root      363:        AppendIf(menuMPU, ID_MONITOR_ATC7,                        "ATC#7");
                    364:        AppendIf(menuMPU, ID_SUBWIN_CACHE7,                     _("Cache") + "#7");
1.1.1.14  root      365:        AppendIfSeparator(menuMPU, VMCap::M88K);
1.1.1.10  root      366:        AppendIf(menuMPU, ID_MONITOR_CMMU6,                       "CMMU#6" + _("(Data)"));
                    367:        AppendIf(menuMPU, ID_MONITOR_ATC6,                        "ATC#6");
                    368:        AppendIf(menuMPU, ID_SUBWIN_CACHE6,                     _("Cache") + "#6");
1.1.1.15  root      369:        menuMPU->AppendSeparator();
                    370:        // MEMDUMPn のラベルは UpdateUI で書き直すのでここでは適当に
                    371:        // 埋めておく。(empty だと怒られる)
1.1.1.18  root      372:        for (uint i = 0; i < MAX_MEMDUMP_MONITOR; i++) {
1.1.1.15  root      373:                AppendIf(menuMPU, ID_MONITOR_MEMDUMP(i), "memdump");
                    374:        }
                    375:        menuMPU->AppendSeparator();
                    376:        AppendIf(menuMPU, ID_SUBWIN_BRHIST,                     _("Branch &History"));
                    377:        AppendIf(menuMPU, ID_SUBWIN_EXHIST,                     _("&Exception History"));
                    378:        AppendIf(menuMPU, ID_SUBWIN_VECTOR,                     _("&Vector Table"));
1.1.1.19  root      379:        wxString mpulabel;
                    380:        if (gMainApp.Has(VMCap::M68K)) {
                    381:                mpulabel = "&MPU(" + mpuname + ")";
                    382:        } else {
                    383:                mpulabel = "&MPU(MC88xx0)";
                    384:        }
                    385:        menuMonitor->AppendSubMenu(menuMPU, mpulabel);
1.1.1.15  root      386: 
                    387:        if (gMainApp.Has(VMCap::LUNA)) {
                    388:                wxMenu *menuXP = new wxMenu();
                    389:                AppendIf(menuXP, ID_MONITOR_XPREG,              _("&Register"));
                    390:                AppendIf(menuXP, ID_MONITOR_XPINTR,             _("&Interrupt"));
                    391:                AppendIf(menuXP, ID_MONITOR_XPIO,               _("Internal &Devices"));
                    392:                menuXP->AppendSeparator();
1.1.1.18  root      393:                for (uint i = 0; i < MAX_XPMEMDUMP_MONITOR; i++) {
1.1.1.15  root      394:                        AppendIf(menuXP, ID_MONITOR_XPMEMDUMP(i), "memdump");
                    395:                }
                    396:                menuXP->AppendSeparator();
                    397:                AppendIf(menuXP, ID_SUBWIN_XPBRHIST,    _("Branch &History"));
                    398:                AppendIf(menuXP, ID_SUBWIN_XPEXHIST,    _("&Exception History"));
                    399:                menuMonitor->AppendSubMenu(menuXP, "XP(HD647180)");
                    400:        }
1.1.1.10  root      401: 
                    402:        // MONITOR_RTC は X68k の RTC、LUNA では MONITOR_MK48T02 だが今の所
                    403:        // NVRAM 側のことは表示してないのでラベルも RTC にしてある。
1.1.1.15  root      404:        wxMenu *menuDev = new wxMenu();
1.1.1.16  root      405:        // X68030 は基本が 24bit のほうなので区別しておく。
                    406:        if (gMainApp.IsX68030()) {
                    407:                AppendIf(menuDev, ID_MONITOR_MAINBUS,   _("Device Map (32bit space)"));
                    408:                AppendIf(menuDev, ID_SUBWIN_X68KIO,             _("Device Map (24bit space)"));
                    409:        } else {
                    410:                AppendIf(menuDev, ID_MONITOR_MAINBUS,   _("Device Map"));
                    411:        }
1.1.1.17  root      412:        AppendIf(menuDev, ID_SUBWIN_NEWSIO,                     _("Device Map (NEWS)"));
                    413:        AppendIf(menuDev, ID_MONITOR_ACCSTAT,           _("Access Status"));
1.1.1.16  root      414:        menuDev->AppendSeparator();
1.1.1.15  root      415:        AppendIf(menuDev, ID_MONITOR_SPC,                         "SPC");
                    416:        AppendIf(menuDev, ID_MONITOR_SCSIDEVS,          _("SCSI Devices"));
                    417:        AppendIf(menuDev, ID_MONITOR_RTC,                         "RTC");
                    418:        AppendIf(menuDev, ID_MONITOR_MK48T02,             "RTC");
                    419:        AppendIf(menuDev, ID_MONITOR_DMAC,                        "DMAC");
                    420:        AppendIf(menuDev, ID_MONITOR_MFP,                         "MFP");
                    421:        AppendIf(menuDev, ID_MONITOR_FDC,                         "FDC");
                    422:        AppendIf(menuDev, ID_MONITOR_SCC,                         "SCC");
                    423:        AppendIf(menuDev, ID_MONITOR_SIO,                         "SIO");
                    424:        AppendIf(menuDev, ID_MONITOR_PIO,                         "PIO0/PIO1");
                    425:        AppendIf(menuDev, ID_MONITOR_KEYBOARD,          _("Keyboard/Mouse"));
                    426:        AppendIf(menuDev, ID_MONITOR_LANCE,                       "Lance");
1.1.1.16  root      427:        AppendIf(menuDev, ID_MONITOR_NEREID,              "Nereid");
1.1.1.18  root      428:        for (uint i = 0; i < 2; i++) {
                    429:                uint id = ID_MONITOR_RTL8019AS(i);
                    430:                wxString name = string_format("Nereid(RTL8019AS) #%u", i);
1.1.1.17  root      431:                AppendIf(menuDev, id, name);
1.1.1.16  root      432:        }
1.1.1.17  root      433:        AppendIf(menuDev, ID_MONITOR_SYSPORT,           _("System Port"));
                    434:        AppendIf(menuDev, ID_MONITOR_AREASET,           _("Areaset"));
1.1.1.15  root      435:        AppendIf(menuDev, ID_MONITOR_LCD,                         "LCD");
                    436:        AppendIf(menuDev, ID_MONITOR_SYSCLK,            _("System Clock"));
1.1.1.18  root      437:        for (uint i = 0; i < 8; i++) {
                    438:                uint id = ID_MONITOR_VIRTIO_BLOCK(i);
                    439:                wxString name = _("VirtIO Block") + string_format(" #%u", i);
1.1.1.17  root      440:                AppendIf(menuDev, id, name);
                    441:        }
                    442:        AppendIf(menuDev, ID_MONITOR_VIRTIO_NET,        _("VirtIO Network"));
1.1.1.21! root      443:        AppendIf(menuDev, ID_MONITOR_VIRTIO_SCSI,         "VirtIO SCSI");
1.1.1.18  root      444:        AppendIf(menuDev, ID_MONITOR_VIRTIO_ENTROPY,_("VirtIO Entropy"));
1.1.1.15  root      445:        AppendIf(menuDev, ID_MONITOR_CRTC,                        "CRTC");
                    446:        AppendIf(menuDev, ID_MONITOR_LUNAVC,            _("Video Control"));
                    447:        AppendIf(menuDev, ID_MONITOR_BT45x,                       "Bt454/458");
                    448:        AppendIf(menuDev, ID_SUBWIN_PALETTE,            _("Palette Colormap"));
                    449:        AppendIf(menuDev, ID_SUBWIN_TEXTPAL,            _("Text Palette Colormap"));
                    450:        AppendIf(menuDev, ID_MONITOR_RENDERER,          _("Renderer"));
                    451:        AppendIf(menuDev, ID_SUBWIN_LUNAFB,                     _("Bitmap Plane"));
                    452:        AppendIf(menuDev, ID_SUBWIN_TVRAM,                      _("Text VRAM"));
1.1.1.18  root      453:        AppendIf(menuDev, ID_MONITOR_SSG,                         "SSG");
1.1.1.15  root      454:        AppendIf(menuDev, ID_MONITOR_ROMCONS,           _("ROM Console (provisional)"));
                    455:        AppendIf(menuDev, ID_SUBWIN_ROM,                          "ROM");
1.1.1.16  root      456:        // LUNA はバスが複数あるので Mainbus Device とする。
                    457:        // 他の機種ではメインて言われても困るので Device とする。
                    458:        if (gMainApp.Has(VMCap::LUNA)) {
                    459:                menuMonitor->AppendSubMenu(menuDev, _("Mainbus De&vice"));
                    460:        } else {
                    461:                menuMonitor->AppendSubMenu(menuDev, _("De&vice"));
                    462:        }
1.1.1.5   root      463: 
                    464:        wxMenu *menuHost = new wxMenu();
1.1.1.10  root      465:        AppendIf(menuHost, ID_MONITOR_WXHOSTINFO,       _("Host &Information"));
1.1.1.16  root      466:        if (gMainApp.IsX68030()) {
                    467:                // X68030 ではネットワークは最大2つあるのでナンバリングが必要。
                    468:                // あれば表示ではなく、なければ Disable。
1.1.1.18  root      469:                for (uint i = 0; i < 2; i++) {
                    470:                        uint id = ID_MONITOR_HOSTNET(i);
                    471:                        wxString name = _("Host Network") + string_format(" #%u", i);
1.1.1.16  root      472:                        menuHost->AppendCheckItem(id, name);
                    473:                        if (gMonitorManager->Find(id) == NULL) {
                    474:                                menuHost->Enable(id, false);
                    475:                        }
                    476:                }
                    477:        } else {
                    478:                // それ以外ではネットワークは1つ固定なのでナンバリング不要
                    479:                AppendIf(menuHost, ID_MONITOR_HOSTNET(0),       _("Host Network"));
                    480:        }
1.1.1.20  root      481:        AppendIf(menuHost, ID_MONITOR_SLIRP,            _("SLIRP Internal States"));
1.1.1.13  root      482:        AppendIf(menuHost, ID_MONITOR_HOSTCOM,          _("Host &Serial Port"));
1.1.1.5   root      483:        menuMonitor->AppendSubMenu(menuHost, _("&Host"));
                    484: 
1.1.1.15  root      485:        wxMenu *menuDebug = new wxMenu();
                    486:        AppendIf(menuDebug, ID_SUBWIN_LOG,                      _("&Log"));
                    487:        AppendIf(menuDebug, ID_MONITOR_BREAKPOINT,      _("&Breakpoint"));
                    488:        menuDebug->AppendSeparator();
                    489:        AppendIf(menuDebug, ID_SUBWIN_LOGSETTING,       _("Log Level &Setting"));
                    490:        menuMonitor->AppendSubMenu(menuDebug, _("&Debug"));
                    491: 
1.1.1.4   root      492:        menubar->Append(menuMonitor, _("&Monitor"));
                    493: 
1.1.1.12  root      494:        // メニュー > ヘルプ
1.1.1.4   root      495: #if defined(__WXOSX__)
                    496:        // OSX では wxID_ABOUT はリンゴメニューに入れるしきたりになっている。
                    497:        // Append() すると Quit より下に来てしまうので、Prepend() で上に追加。
                    498:        // 今のところヘルプメニューから About ダイアログを抜くとメニューが空に
                    499:        // なってしまうので、ヘルプメニューの追加ごと抑制する。
                    500:        menubar->OSXGetAppleMenu()->Prepend(wxID_ABOUT, _("About nono"));
                    501: #else
                    502:        wxMenu *menuHelp = new wxMenu();
                    503:        menuHelp->Append(wxID_ABOUT, _("About nono"));
                    504:        menubar->Append(menuHelp, _("&Help"));
                    505: #endif
                    506: 
1.1       root      507:        SetMenuBar(menubar);
                    508: 
1.1.1.18  root      509:        frame_title = wxString("nono");
1.1.1.17  root      510:        const char *vmname = gMainApp.GetVMName();
                    511:        if (vmname) {
1.1.1.18  root      512:                frame_title += '(';
                    513:                frame_title += wxString(vmname);
                    514:                frame_title += ')';
1.1       root      515:        }
1.1.1.18  root      516:        SetTitle(frame_title);
1.1       root      517: 
                    518:        // UpdateUI イベントは Idle 時に時折チェックされるらしいが、
                    519:        // (メインビューとサブウィンドウを合わせた) タイマーイベントの粒度が
                    520:        // 小さいためか、秒間120回とかいうレベルで UpdateUIEvent が飛んでくる
                    521:        // っぽい (全タイマーをとめたら治る模様)。
                    522:        // さすがにそんなに来られても気持ち悪いのと、どうせメニュー開いた瞬間
                    523:        // 表示しようとする前には一度飛んでくるのだから、アイドル時のチェックは
                    524:        // いらない気がする。間隔広げておいても、ぱっと見副作用はなさそうだけど
                    525:        // 念のため事象が分かりやすいように 10秒くらいにしておく。
                    526:        wxUpdateUIEvent::SetUpdateInterval(10000);
                    527: 
1.1.1.15  root      528:        // WXStatusPanel コンストラクタが mainview を参照するので
                    529:        // mainview のほうを先に作成すること。
                    530:        mainview = new WXMainView(this);
                    531:        statuspanel = new WXStatusPanel(this);
1.1       root      532: 
1.1.1.9   root      533:        // SHOW イベントを最初にも一度起こしたいため
                    534:        // ステータスパネルを一旦非表示にする (これで SHOW(false) イベントが飛ぶ)
1.1.1.15  root      535:        statuspanel->Hide();
1.1.1.9   root      536:        const ConfigItem& item_show = gConfig->Find("show-statuspanel");
                    537:        if (item_show.AsInt() != 0) {
                    538:                // 必要なら改めて表示 (これで SHOW(true) イベントが飛ぶ)
1.1.1.15  root      539:                statuspanel->Show();
1.1.1.9   root      540:        }
                    541: 
1.1.1.13  root      542:        // Sizer 使わず自前でレイアウトする。
                    543:        SetAutoLayout(true);
1.1       root      544: 
1.1.1.4   root      545:        // Activate イベントは、このトップレベルウィンドウにウィンドウフォーカスが
                    546:        // 来た or 外れたことを示すので、wxFrame (というかたぶん wxTopLevelWindow)
                    547:        // を継承している WXMainFrameに飛んでくるのだが、処理の都合上 WXMainView で
                    548:        // 扱いたいので、そちらに回す。
                    549:        Connect(wxEVT_ACTIVATE, wxActivateEventHandler(WXMainView::OnActivate),
1.1.1.15  root      550:                NULL, mainview);
1.1.1.4   root      551: 
1.1.1.11  root      552:        // ウィンドウ表示後に続きの処理をするための単発アイドルイベント。
                    553:        Connect(wxEVT_IDLE, wxIdleEventHandler(WXMainFrame::OnIdle));
                    554: 
                    555:        // VM からの通知を接続
1.1.1.13  root      556:        WXUIMessage::Connect(UIMessage::APPEXIT, this,
1.1.1.11  root      557:                wxCommandEventHandler(WXMainFrame::OnExit));
                    558:        WXUIMessage::Connect(UIMessage::SCSI_MEDIA_FAILED, this,
1.1.1.14  root      559:                wxCommandEventHandler(WXMainFrame::OnInsertFailed));
                    560:        WXUIMessage::Connect(UIMessage::FDD_MEDIA_FAILED, this,
                    561:                wxCommandEventHandler(WXMainFrame::OnInsertFailed));
1.1.1.15  root      562:        if (gMainApp.Has(VMCap::M68K)) {
1.1.1.11  root      563:                WXUIMessage::Connect(UIMessage::HALT, this,
                    564:                        wxCommandEventHandler(WXMainFrame::OnHaltNotify));
                    565:        }
1.1       root      566: }
                    567: 
                    568: WXMainFrame::~WXMainFrame()
                    569: {
1.1.1.15  root      570:        WXUIMessage::Disconnect(UIMessage::APPEXIT, this,
1.1.1.13  root      571:                wxCommandEventHandler(WXMainFrame::OnExit));
1.1.1.15  root      572:        WXUIMessage::Disconnect(UIMessage::SCSI_MEDIA_FAILED, this,
1.1.1.14  root      573:                wxCommandEventHandler(WXMainFrame::OnInsertFailed));
1.1.1.15  root      574:        WXUIMessage::Disconnect(UIMessage::FDD_MEDIA_FAILED, this,
1.1.1.14  root      575:                wxCommandEventHandler(WXMainFrame::OnInsertFailed));
1.1.1.15  root      576:        if (gMainApp.Has(VMCap::M68K)) {
                    577:                WXUIMessage::Disconnect(UIMessage::HALT, this,
1.1.1.13  root      578:                        wxCommandEventHandler(WXMainFrame::OnHaltNotify));
                    579:        }
1.1       root      580: }
                    581: 
1.1.1.17  root      582: // 指定のモニタ/サブウィンドウがあればメニューに追加する
                    583: void
                    584: WXMainFrame::AppendIf(wxMenu *menu, int id, const wxString& label)
                    585: {
                    586:        if (id >= ID_SUBWIN_START) {
                    587:                // サブウィンドウなら機種から判定する。機種情報は必ず持っているため。
                    588:                // 一方、サブウィンドウは必ずしもモニタと紐付いているわけではないので
                    589:                // モニタマネージャに問い合わせる方法は使えない。
                    590:                VMCap vmcap = gMonitorManager->GetVMCap(id);
                    591:                if (gMainApp.Has(vmcap)) {
                    592:                        menu->AppendCheckItem(id, label);
                    593:                }
                    594:        } else {
                    595:                // モニタならインスタンスの有無で判定する。
                    596:                // モニタは機種情報は持ってないが、存在すべきインスタンスはこの時点で
                    597:                // すべて出揃っているため。
                    598:                if (gMonitorManager->Find(id)) {
                    599:                        menu->AppendCheckItem(id, label);
                    600:                }
                    601:        }
                    602: }
                    603: 
1.1.1.11  root      604: // リムーバブルデバイス用のメニューを作成して menuDevice に追加する
                    605: void
                    606: WXMainFrame::CreateRemovableMenu(wxMenu *menuDevice)
                    607: {
                    608:        wxMenu *menu;
                    609:        bool added = false;
                    610: 
                    611:        // FD
1.1.1.15  root      612:        for (int unit = 0; unit < FDCDevice::MAX_DRIVE; unit++) {
                    613:                fdd_array[unit] = gMainApp.FindObject<FDDDevice>(OBJ_FDD(unit));
                    614:                if (fdd_array[unit]) {
1.1.1.14  root      615:                        menu = CreateFDMenu(unit);
                    616:                        std::string label = string_format("FD%d", unit);
                    617:                        menuDevice->AppendSubMenu(menu, label);
                    618:                        added = true;
                    619:                }
                    620:        }
1.1.1.11  root      621: 
                    622:        // CD, MO
1.1.1.21! root      623:        auto scsi = gMainApp.FindObject<SCSIDomain>(OBJ_SCSI);
1.1.1.18  root      624:        if (scsi) {
1.1.1.15  root      625:                for (int id = 0; id < 8; id++) {
1.1.1.18  root      626:                        scsidev[id] = scsi->GetTarget(id);
1.1.1.15  root      627:                        if (scsidev[id]) {
                    628:                                menu = CreateSCSIRemovableMenu(id);
                    629:                                if (menu) {
                    630:                                        std::string label = string_format("%s (ID%d)",
                    631:                                                SCSI::GetDevTypeName(scsidev[id]->GetDevType()), id);
                    632:                                        menuDevice->AppendSubMenu(menu, label);
                    633:                                        added = true;
                    634:                                }
1.1.1.11  root      635:                        }
                    636:                }
                    637:        }
                    638: 
                    639:        // 1つでも追加したらセパレータ
                    640:        if (added) {
                    641:                menuDevice->AppendSeparator();
                    642:        }
                    643: }
                    644: 
1.1.1.14  root      645: // FD 用のメニューを作成して返す。
                    646: wxMenu *
                    647: WXMainFrame::CreateFDMenu(int unit) const
                    648: {
                    649:        wxMenu *menu = new wxMenu();
                    650:        // Insert の実際のラベルは UpdateUI でセットする。
                    651:        // ただし何か入れておかないといけないので適当にセット。
                    652:        menu->Append(ID_FD_INSERT(unit), "Insert", "");
                    653:        // XXX 未実装
                    654:        //menu->Append(ID_FD_MISINSERT(unit), _("Insert incorrectly"), "");
                    655:        menu->Append(ID_FD_EJECT(unit), _("&Eject"), "");
                    656:        menu->Append(ID_FD_FORCE(unit), _("&Force Eject"), "");
                    657:        return menu;
                    658: }
                    659: 
1.1.1.11  root      660: // SCSI リムーバブルデバイス用のメニューを作成して返す。
                    661: // id はデバイスが接続されていること (リムーバブルデバイスであるかは問わない)。
                    662: // リムーバブルデバイスでなければ NULL を返す。
                    663: // メニューバーとポップアップメニュー共通。
                    664: wxMenu *
                    665: WXMainFrame::CreateSCSIRemovableMenu(uint id) const
                    666: {
                    667:        const auto *dev = scsidev[id];
                    668:        assert(dev);
                    669: 
                    670:        switch (dev->GetDevType()) {
                    671:         case SCSI::DevType::CD:
                    672:         case SCSI::DevType::MO:
                    673:         {
                    674:                wxMenu *menu = new wxMenu();
                    675:                // Insert の実際のラベルは UpdateUI でセットする。
                    676:                // ただし何か入れておかないといけないので適当にセット。
                    677:                menu->Append(ID_CD_INSERT(id), "Insert", "");
                    678:                menu->Append(ID_CD_EJECT(id), _("&Eject"), "");
                    679:                menu->Append(ID_CD_FORCE(id), _("&Force Eject"), "");
                    680:                return menu;
                    681:         }
                    682:         default:
                    683:                return NULL;
                    684:        }
                    685: }
                    686: 
1.1.1.12  root      687: // (設定反映などの) 初期化。
                    688: // 成功すれば true、失敗すれば false を返す。
                    689: bool
                    690: WXMainFrame::Init()
                    691: {
1.1.1.15  root      692:        if (!mainview->Init()) {
1.1.1.12  root      693:                return false;
                    694:        }
                    695: 
                    696:        return true;
                    697: }
                    698: 
1.1.1.13  root      699: bool
                    700: WXMainFrame::Layout()
                    701: {
                    702:        if (inherited::Layout() == false) {
                    703:                return false;
                    704:        }
                    705: 
1.1.1.15  root      706:        wxSize msize = statuspanel->GetMinClientSize();
                    707:        wxSize ssize = statuspanel->GetClientSize();
                    708:        wxSize vsize = mainview->GetClientSize();
1.1.1.13  root      709: 
1.1.1.15  root      710:        if (statuspanel->IsShown()) {
1.1.1.13  root      711:                ssize.y = msize.y;
                    712:        } else {
                    713:                ssize.y = 0;
                    714:        }
                    715: 
                    716:        wxSize size;
                    717:        size.x = std::max(msize.x, vsize.x);
                    718:        size.y = ssize.y + vsize.y;
                    719: 
                    720:        if (ssize.y != 0) {
1.1.1.15  root      721:                statuspanel->SetSize(0, 0, size.x, ssize.y);
1.1.1.13  root      722:        }
1.1.1.15  root      723:        mainview->SetSize(0, ssize.y, size.x, vsize.y);
1.1.1.13  root      724:        SetClientSize(size);
                    725: 
                    726:        return true;
                    727: }
                    728: 
1.1.1.11  root      729: // ウィンドウ作成イベント (を実現するためここではアイドルイベントを使う)
1.1.1.10  root      730: //
1.1.1.11  root      731: // 初期化(っぽい)もののうちコンストラクタでは早すぎるものは、コンストラクタ
                    732: // 直後に起こすこのイベント内で処理する。使えそうなイベントはいくつかあり、
                    733: // 自前の Create (今はもうない) -> WindowCreate -> Idle -> Paint の順で
                    734: // 起きるようだ。
                    735: // 自前の Create 時点では早すぎて、ここでサブウィンドウを作成するとサイズが 0
                    736: // みたいなウィンドウが一瞬出来てしまい GTK のワーニングが出る (その後サイズを
                    737: // 矯正すれば表示自体は出来る)。
1.1.1.10  root      738: // WindowCreate 時点ではその問題は起きないが、ここはまだメインウィンドウ表示
                    739: // 前なので、ここでサブウィンドウを表示した後メインウィンドウを表示すると
                    740: // (ウィンドウマネージャにもよるかもだが)、メインウィンドウがサブウィンドウを
                    741: // 隠してしまう。
1.1.1.11  root      742: // Idle イベント時点まで来ると上の2つの問題は回避できるようだ。
                    743: // Paint イベントの時点でもタイミング的には問題ないが、環境によっては(?)
                    744: // このイベント自体が飛んで来ないことがあるようだ。WXMainFrame の再描画は
1.1.1.13  root      745: // 子コントロールが行っており、そのため WXMainFrame 自身が再描画しなければ
                    746: // ならない領域は存在しないからかも知れないが詳細未調査。
1.1.1.11  root      747: void
                    748: WXMainFrame::OnIdle(wxIdleEvent& ev)
1.1       root      749: {
1.1.1.11  root      750:        // UIMessage の処理を開始する。
                    751:        // 少なくとも WXMainFrame のコンストラクタが完了した後のほうがいいはず。
                    752:        UIMessage::Attach(&WXUIMessage::Process);
                    753: 
1.1       root      754:        // ウィンドウを表示
1.1.1.10  root      755:        for (int i = 0; i < subwindow_start.size(); i++) {
                    756:                if (subwindow_start[i]) {
1.1       root      757:                        DoWindow(i, true);
                    758:                }
                    759:        }
                    760: 
1.1.1.9   root      761:        // 電源投入
1.1.1.17  root      762:        power->PushPowerButton();
1.1.1.10  root      763: 
                    764:        // 一度処理したら、このイベントを外す
1.1.1.11  root      765:        Disconnect(wxEVT_IDLE, wxIdleEventHandler(WXMainFrame::OnIdle));
1.1       root      766: }
                    767: 
1.1.1.3   root      768: // ウィンドウクローズイベント
                    769: void
                    770: WXMainFrame::OnClose(wxCloseEvent& event)
                    771: {
1.1.1.9   root      772:        // ステータスパネルの更新を停止
1.1.1.15  root      773:        statuspanel->Close();
1.1.1.13  root      774:        // メインビューの描画を停止
1.1.1.15  root      775:        mainview->Close();
1.1.1.9   root      776: 
1.1.1.3   root      777:        // サブウィンドウを全部閉じる
1.1.1.10  root      778:        for (int i = 0; i < ID_SUBWIN_MAX; i++) {
1.1.1.4   root      779:                if ((bool)windows[i]) {
1.1.1.3   root      780:                        windows[i]->Close();
                    781:                }
                    782:        }
                    783: 
                    784:        // 後はデフォルト処理
                    785:        event.Skip();
                    786: }
                    787: 
1.1.1.17  root      788: // メニューの「VM > Push Power Button」イベント
                    789: void
                    790: WXMainFrame::OnPowerButton(wxCommandEvent& event)
                    791: {
                    792:        // LUNA はモーメンタリ動作、X68030 はオルタネート動作のスイッチ。
                    793:        // この違いは VM 側で吸収するのでここはボタンを押したという動作だけ
                    794:        // 通知する。
                    795:        power->PushPowerButton();
                    796: }
                    797: 
                    798: // メニューの「VM > Push Power Button」UI
                    799: void
                    800: WXMainFrame::OnPowerButtonUI(wxUpdateUIEvent& event)
                    801: {
                    802:        PowerButtonState state = power->GetPowerButtonState();
                    803:        if (state == PowerButtonState::NoState) {
                    804:                // LUNA など電源ボタンに電源オフを指示する機構がないので、
                    805:                // メニューを無効にする。
                    806:                event.Enable(false);
                    807:        } else {
                    808:                // オルタネートスイッチならチェックで状態を表す。(X68030)
                    809:                event.Check((bool)state);
                    810:        }
                    811: }
                    812: 
                    813: // メニューの「VM > Send CTRL+OPT.1+DEL」イベント
                    814: void
                    815: WXMainFrame::OnSoftReset(wxCommandEvent& event)
                    816: {
                    817:        keyboard->MakeKey(KC_CTRL);
                    818:        keyboard->MakeKey(KC_OPT1);
                    819:        keyboard->MakeKey(KC_DEL);
                    820:        keyboard->BreakKey(KC_DEL);
                    821:        keyboard->BreakKey(KC_OPT1);
                    822:        keyboard->BreakKey(KC_CTRL);
                    823: }
                    824: 
                    825: // メニューの「VM > Push Reset Button」イベント
                    826: // こっちは本体リセットボタンによるリセット
                    827: void
                    828: WXMainFrame::OnResetButton(wxCommandEvent& event)
                    829: {
                    830:        power->MakeResetHard();
                    831: }
                    832: 
                    833: // メニューの「VM > Push ABORT(Interrupt) Button」イベント
                    834: void
                    835: WXMainFrame::OnNMIButton(wxCommandEvent& event)
                    836: {
                    837:        auto nmi = GetNMIDevice();
                    838:        nmi->PressNMI();
                    839: }
                    840: 
                    841: // メニューの「VM > Restart VM」イベント
1.1.1.12  root      842: void
                    843: WXMainFrame::OnRestartVM(wxCommandEvent& event)
                    844: {
1.1.1.15  root      845:        power->MakeRestart();
1.1.1.12  root      846: }
                    847: 
1.1.1.17  root      848: // メニューの「VM > 終了」イベント
1.1.1.12  root      849: void
                    850: WXMainFrame::OnExit(wxCommandEvent& event)
                    851: {
                    852:        // ウィンドウを閉じる
                    853:        Close();
                    854: }
                    855: 
1.1       root      856: // メニューの「高速モード」イベント
                    857: void
                    858: WXMainFrame::OnFullSpeed(wxCommandEvent& event)
                    859: {
                    860:        if (event.IsChecked()) {
                    861:                // チェックが入ったので、高速モードにする
1.1.1.15  root      862:                syncer->RequestFullSpeed(true);
1.1       root      863:        } else {
                    864:                // チェックが消えたので、通常モードにする
1.1.1.15  root      865:                syncer->RequestFullSpeed(false);
1.1       root      866:        }
                    867: }
                    868: 
                    869: // メニューの「高速モード」UI
                    870: void
                    871: WXMainFrame::OnFullSpeedUI(wxUpdateUIEvent& event)
                    872: {
1.1.1.15  root      873:        bool is_fullspeed = syncer->GetFullSpeed();
1.1       root      874:        event.Check(is_fullspeed);
                    875: }
                    876: 
1.1.1.12  root      877: // メニューの「設定 > 入力 > *」の共通イベント
1.1.1.6   root      878: void
1.1.1.12  root      879: WXMainFrame::OnMenuInput(wxCommandEvent& event)
1.1.1.6   root      880: {
1.1.1.12  root      881:        bool char_mode = (event.GetId() == ID_INPUT_CHAR);
                    882: 
1.1.1.15  root      883:        mainview->SetCharInputMode(char_mode);
1.1.1.6   root      884: }
                    885: 
1.1.1.12  root      886: // メニューの「設定 > 入力 > *」の共通 UI
1.1       root      887: void
1.1.1.12  root      888: WXMainFrame::OnMenuInputUI(wxUpdateUIEvent& event)
1.1       root      889: {
1.1.1.15  root      890:        bool char_mode = mainview->GetCharInputMode();
1.1.1.12  root      891: 
                    892:        if (char_mode) {
                    893:                event.Check(event.GetId() == ID_INPUT_CHAR);
                    894:        } else {
                    895:                event.Check(event.GetId() == ID_INPUT_JP);
                    896:        }
1.1       root      897: }
                    898: 
1.1.1.15  root      899: // スケール一覧
                    900: /*static*/ std::vector<double>
                    901: WXMainFrame::view_scales {
                    902:        0.50,
                    903:        0.75,
                    904:        1.00,
                    905:        1.50,
                    906:        2.00,
                    907: };
                    908: 
                    909: #define contains(v, key)       (std::find(v.begin(), v.end(), key) != v.end())
                    910: 
                    911: // 「表示 > スケール」のメニュー項目作成に必要な view_scale を作成し、
                    912: // ユーザ指定値があれば view_scales[] 内でのインデックスを返す。
                    913: // ユーザ指定値がなければ -1 を返す。
                    914: int
                    915: WXMainFrame::CreateMainviewScaleTable()
                    916: {
                    917:        // 設定ファイル mainview-scale で指定されたサイズを追加。
                    918:        // 値はこの時点で WXMainView::screen_scale にセットされている。
                    919:        double user_scale = WXMainView::screen_scale;
                    920:        if (contains(view_scales, user_scale)) {
                    921:                // プリセットと同じなら、このままでよい。
                    922:        } else {
                    923:                // 追加したらソート。
                    924:                view_scales.push_back(user_scale);
                    925:                std::sort(view_scales.begin(), view_scales.end());
                    926: 
                    927:                // ユーザ指定の値が何番目かを返す。指定されてなければ -1。
                    928:                for (int i = 0, end = view_scales.size(); i < end; i++) {
                    929:                        if (view_scales[i] == user_scale) {
                    930:                                return i;
                    931:                        }
                    932:                }
                    933:                // 見付からないことはないはずだが
                    934:        }
                    935:        return -1;
                    936: }
                    937: 
1.1       root      938: // メニューの「表示 > スケール > *」の共通イベント
                    939: void
                    940: WXMainFrame::OnMenuScale(wxCommandEvent& event)
                    941: {
1.1.1.15  root      942:        int idx = event.GetId() - ID_SCALE_START;
                    943:        mainview->DoResize(view_scales[idx]);
1.1       root      944:        // 再レイアウト
1.1.1.13  root      945:        Layout();
1.1       root      946: }
                    947: 
                    948: // メニューの「表示 > スケール > *」の共通 UI
                    949: void
                    950: WXMainFrame::OnMenuScaleUI(wxUpdateUIEvent& event)
                    951: {
1.1.1.15  root      952:        int idx = event.GetId() - ID_SCALE_START;
                    953:        double current_scale = mainview->GetScale();
1.1       root      954: 
1.1.1.15  root      955:        event.Check(view_scales[idx] == current_scale);
1.1       root      956: }
                    957: 
                    958: // メニューの「表示 > フォントサイズ > *」の共通イベント
                    959: void
                    960: WXMainFrame::OnMenuFontSize(wxCommandEvent& event)
                    961: {
1.1.1.5   root      962:        FontId fontid;
1.1       root      963: 
1.1.1.3   root      964:        assertmsg(
1.1.1.15  root      965:                ID_FONTSIZE_12 <= event.GetId() && event.GetId() <= ID_FONTSIZE_24,
1.1.1.3   root      966:                "event.GetId()=%d", event.GetId());
1.1       root      967:        switch (event.GetId()) {
                    968:         case ID_FONTSIZE_12:
1.1.1.5   root      969:                fontid = FontId::_6x12;
1.1       root      970:                break;
                    971:         case ID_FONTSIZE_16:
1.1.1.5   root      972:                fontid = FontId::_8x16;
1.1       root      973:                break;
1.1.1.15  root      974:         case ID_FONTSIZE_24:
                    975:                fontid = FontId::_12x24;
                    976:                break;
1.1       root      977:         default:
                    978:                __unreachable();
                    979:                break;
                    980:        }
                    981: 
1.1.1.13  root      982:        if (fontid != gFontManager->GetFontId()) {
                    983:                gFontManager->SetFont(fontid);
1.1       root      984: 
1.1.1.13  root      985:                // アクティブなサブウィンドウ全員にフォント変更通知
1.1.1.10  root      986:                for (int i = 0; i < ID_SUBWIN_MAX; i++) {
1.1.1.4   root      987:                        if ((bool)windows[i]) {
                    988:                                WXSubWindow *subwin =
                    989:                                        dynamic_cast<WXSubWindow *>(windows[i].get());
1.1.1.13  root      990:                                subwin->FontChanged();
1.1       root      991:                        }
                    992:                }
1.1.1.13  root      993:                // メインウィンドウはここで直接ステータスパネルに通知
1.1.1.15  root      994:                statuspanel->FontChanged();
1.1.1.9   root      995: 
                    996:                // ステータスパネルの大きさが変わるので再レイアウト
1.1.1.13  root      997:                Layout();
1.1       root      998:        }
                    999: }
                   1000: 
                   1001: // メニューの「表示 > フォントサイズ > *」共通 UI
                   1002: void
                   1003: WXMainFrame::OnMenuFontSizeUI(wxUpdateUIEvent& event)
                   1004: {
1.1.1.13  root     1005:        FontId current_size = gFontManager->GetFontId();
1.1.1.5   root     1006:        FontId event_size = (FontId)(event.GetId() - (ID_FONTSIZE_START+1));
1.1       root     1007: 
                   1008:        event.Check(current_size == event_size);
                   1009: }
                   1010: 
1.1.1.15  root     1011: // 更新頻度一覧
                   1012: /*static*/ std::vector<int>
                   1013: WXMainFrame::monrates {
                   1014:        20,
                   1015:        5,
                   1016:        1,
1.1.1.5   root     1017: };
                   1018: 
1.1.1.21! root     1019: // 「表示 > モニタ更新頻度」のメニュー項目作成に必要な monrates を作成する。
        !          1020: void
1.1.1.15  root     1021: WXMainFrame::CreateMonRateTable()
                   1022: {
                   1023:        // 設定ファイル monitor-rate で指定された値を追加。
                   1024:        // 値はこの時点で monitor_rate にセットされている。
                   1025:        int user_rate = monitor_rate;
                   1026:        if (contains(monrates, user_rate)) {
                   1027:                // プリセットと同じなら、このままでよい。
                   1028:        } else {
                   1029:                // 追加したら降順にソート。
                   1030:                monrates.push_back(user_rate);
                   1031:                std::sort(monrates.begin(), monrates.end(),
                   1032:                        [](int a, int b) { return a > b; }
                   1033:                );
                   1034:        }
                   1035: }
                   1036: 
1.1.1.5   root     1037: // メニューの「表示 > モニタ更新頻度 > *」の共通イベント
                   1038: void
                   1039: WXMainFrame::OnMenuMonRate(wxCommandEvent& event)
                   1040: {
1.1.1.15  root     1041:        int idx = event.GetId() - ID_MONRATE_START;
                   1042:        monitor_rate = monrates[idx];
1.1.1.5   root     1043: 
                   1044:        // アクティブなサブウィンドウのテキストパネル全員に通知
1.1.1.10  root     1045:        for (int i = 0; i < ID_SUBWIN_MAX; i++) {
1.1.1.5   root     1046:                if ((bool)windows[i]) {
                   1047:                        auto *subwin = dynamic_cast<WXSubWindow *>(windows[i].get());
                   1048:                        for (wxWindow *child : subwin->GetChildren()) {
1.1.1.14  root     1049:                                auto *panel = dynamic_cast<WXMonitorPanel*>(child);
1.1.1.5   root     1050:                                if (panel) {
                   1051:                                        panel->SetRate(monitor_rate);
                   1052:                                }
                   1053:                        }
                   1054:                }
                   1055:        }
                   1056: }
                   1057: 
                   1058: // メニューの「表示 > モニタ更新頻度 > *」共通 UI
                   1059: void
                   1060: WXMainFrame::OnMenuMonRateUI(wxUpdateUIEvent& event)
                   1061: {
1.1.1.15  root     1062:        int idx = event.GetId() - ID_MONRATE_START;
1.1.1.5   root     1063: 
1.1.1.15  root     1064:        event.Check(monrates[idx] == monitor_rate);
1.1.1.5   root     1065: }
                   1066: 
1.1.1.9   root     1067: // メニューの「表示 > ステータスパネルを表示」
                   1068: void
                   1069: WXMainFrame::OnShowStatusPanel(wxCommandEvent& event)
                   1070: {
                   1071:        // enable ならチェックを付けようとして呼ばれた
                   1072:        bool enable = event.IsChecked();
                   1073: 
1.1.1.15  root     1074:        statuspanel->Show(enable);
1.1.1.9   root     1075: 
                   1076:        // 再レイアウト
1.1.1.13  root     1077:        Layout();
1.1.1.9   root     1078: }
                   1079: 
                   1080: // メニューの「表示 > ステータスパネルを表示」UI
                   1081: void
                   1082: WXMainFrame::OnShowStatusPanelUI(wxUpdateUIEvent& event)
                   1083: {
1.1.1.15  root     1084:        event.Check(statuspanel->IsShown());
1.1.1.9   root     1085: }
                   1086: 
1.1.1.14  root     1087: // メニューの「デバイス > FD > 挿入」
                   1088: void
                   1089: WXMainFrame::OnFDInsert(wxCommandEvent& event)
                   1090: {
                   1091:        int unit = event.GetId() - ID_FD_INSERT_0;
                   1092:        const auto *fdd = fdd_array[unit];
                   1093:        assert(fdd);
                   1094: 
                   1095:        std::string title(_("Open a FD image"));
                   1096:        std::string wildcard("FD images (*.xdf;*.img;*.fs)"
                   1097:                "|*.xdf;*.XDF;*.img;*.IMG;*.fs;*.FS"
                   1098:                "|All files (*.*)|*.*");
                   1099: 
                   1100:        // ディレクトリは、まだ一度も使ってなければ VM ディレクトリにする
                   1101:        if (current_dir.empty()) {
                   1102:                current_dir = gMainApp.GetVMDir();
                   1103:        }
                   1104: 
                   1105:        wxFileDialog dialog(this, title, current_dir, "", wildcard,
                   1106:                wxFD_OPEN | wxFD_FILE_MUST_EXIST);
                   1107:        if (dialog.ShowModal() == wxID_CANCEL) {
                   1108:                return;
                   1109:        }
                   1110:        auto path = std::string(dialog.GetPath());
                   1111:        InsertFD(unit, path);
                   1112: }
                   1113: 
                   1114: // メニューの「デバイス > FD > 挿入」UI
                   1115: void
                   1116: WXMainFrame::OnFDInsertUI(wxUpdateUIEvent& event)
                   1117: {
                   1118:        int unit = event.GetId() - ID_FD_INSERT_0;
                   1119:        const auto *fdd = fdd_array[unit];
                   1120:        assert(fdd);
                   1121: 
                   1122:        if (fdd->IsMediumLoaded()) {
                   1123:                event.SetText(_("Ex&change"));
                   1124:        } else {
                   1125:                event.SetText(_("&Insert"));
                   1126:        }
                   1127: }
                   1128: 
                   1129: // メニューの「デバイス > FD > 取り出し」
                   1130: void
                   1131: WXMainFrame::OnFDEject(wxCommandEvent& event)
                   1132: {
                   1133:        int unit = event.GetId() - ID_FD_EJECT_0;
                   1134: 
                   1135:        EjectFD(unit, false);
                   1136: }
                   1137: 
                   1138: // メニューの「デバイス > FD > 取り出し」UI
                   1139: void
                   1140: WXMainFrame::OnFDEjectUI(wxUpdateUIEvent& event)
                   1141: {
                   1142:        int unit = event.GetId() - ID_FD_EJECT_0;
                   1143:        FDDDevice *fdd = fdd_array[unit];
                   1144:        assert(fdd);
                   1145: 
                   1146:        // 挿入されてて取り出し可能な時のみ有効
                   1147:        event.Enable(fdd->IsMediumLoaded() && fdd->IsEjectEnable());
                   1148: }
                   1149: 
                   1150: // メニューの「デバイス > FD > 強制取り出し」
                   1151: void
                   1152: WXMainFrame::OnFDForce(wxCommandEvent& event)
                   1153: {
                   1154:        int unit = event.GetId() - ID_FD_FORCE_0;
                   1155: 
                   1156:        EjectFD(unit, true);
                   1157: }
                   1158: 
                   1159: // メニューの「デバイス > FD > 強制取り出し」UI
                   1160: void
                   1161: WXMainFrame::OnFDForceUI(wxUpdateUIEvent& event)
                   1162: {
                   1163:        int unit = event.GetId() - ID_FD_FORCE_0;
                   1164:        FDDDevice *fdd = fdd_array[unit];
                   1165:        assert(fdd);
                   1166: 
                   1167:        // 挿入されてて取り出し禁止の時のみ有効
                   1168:        event.Enable(fdd->IsMediumLoaded() && fdd->IsEjectEnable() == false);
                   1169: }
                   1170: 
1.1.1.11  root     1171: // メニューの「デバイス > CD/MO > 挿入」
                   1172: void
                   1173: WXMainFrame::OnCDInsert(wxCommandEvent& event)
                   1174: {
                   1175:        std::string title;
                   1176:        std::string wildcard;
                   1177: 
                   1178:        int id = event.GetId() - ID_CD_INSERT_0;
                   1179:        const auto *dev = scsidev[id];
                   1180:        assert(dev);
                   1181: 
                   1182:        switch (dev->GetDevType()) {
                   1183:         case SCSI::DevType::CD:
                   1184:                title = _("Open a CD image");
                   1185:                wildcard = "ISO images (*.iso;*.img)|*.iso;*.img;*.ISO;*.IMG";
                   1186:                break;
                   1187:         case SCSI::DevType::MO:
                   1188:                title = _("Open an MO image");
                   1189:                wildcard = "MO images (*.img;*.mos)|*.img;*.mos;*.IMG;*.MOS";
                   1190:                break;
                   1191:         default:
1.1.1.15  root     1192:                break;
1.1.1.11  root     1193:        }
                   1194:        wildcard += "|All files (*.*)|*.*";
                   1195: 
                   1196:        // ディレクトリは、まだ一度も使ってなければ VM ディレクトリにする
                   1197:        if (current_dir.empty()) {
                   1198:                current_dir = gMainApp.GetVMDir();
                   1199:        }
                   1200: 
                   1201:        wxFileDialog dialog(this, title, current_dir, "", wildcard,
                   1202:                wxFD_OPEN | wxFD_FILE_MUST_EXIST);
                   1203:        if (dialog.ShowModal() == wxID_CANCEL) {
                   1204:                return;
                   1205:        }
                   1206:        auto path = std::string(dialog.GetPath());
                   1207:        InsertCD(id, path);
                   1208: }
                   1209: 
                   1210: // メニューの「デバイス > CD/MO > 挿入」UI
                   1211: void
                   1212: WXMainFrame::OnCDInsertUI(wxUpdateUIEvent& event)
                   1213: {
                   1214:        int id = event.GetId() - ID_CD_INSERT_0;
                   1215:        SCSIDisk *disk = dynamic_cast<SCSIDisk *>(scsidev[id]);
                   1216:        assert(disk);
                   1217: 
                   1218:        if (disk->IsMediumLoaded()) {
                   1219:                event.SetText(_("Ex&change"));
                   1220:        } else {
                   1221:                event.SetText(_("&Insert"));
                   1222:        }
                   1223: }
                   1224: 
                   1225: // メニューの「デバイス > CD/MO > 取り出し」
                   1226: void
                   1227: WXMainFrame::OnCDEject(wxCommandEvent& event)
                   1228: {
                   1229:        int id = event.GetId() - ID_CD_EJECT_0;
                   1230: 
                   1231:        EjectCD(id, false);
                   1232: }
                   1233: 
                   1234: // メニューの「デバイス > CD/MO > 取り出し」UI
                   1235: void
                   1236: WXMainFrame::OnCDEjectUI(wxUpdateUIEvent& event)
                   1237: {
                   1238:        int id = event.GetId() - ID_CD_EJECT_0;
                   1239:        SCSIDisk *disk = dynamic_cast<SCSIDisk *>(scsidev[id]);
                   1240:        assert(disk);
                   1241: 
                   1242:        // 挿入されてて取り出し可能な時のみ有効
                   1243:        event.Enable(disk->IsMediumLoaded() &&
                   1244:                     disk->IsMediumRemovalAllowed());
                   1245: }
                   1246: 
                   1247: // メニューの「デバイス > CD/MO > 強制取り出し」
                   1248: void
                   1249: WXMainFrame::OnCDForce(wxCommandEvent& event)
                   1250: {
                   1251:        int id = event.GetId() - ID_CD_FORCE_0;
                   1252: 
                   1253:        EjectCD(id, true);
                   1254: }
                   1255: 
                   1256: // メニューの「デバイス > CD/MO > 強制取り出し」UI
                   1257: void
                   1258: WXMainFrame::OnCDForceUI(wxUpdateUIEvent& event)
                   1259: {
                   1260:        int id = event.GetId() - ID_CD_FORCE_0;
                   1261:        SCSIDisk *disk = dynamic_cast<SCSIDisk *>(scsidev[id]);
                   1262:        assert(disk);
                   1263: 
                   1264:        // 挿入されてて取り出し禁止の時のみ有効
                   1265:        event.Enable(disk->IsMediumLoaded() &&
                   1266:                     disk->IsMediumRemovalPrevented());
                   1267: }
                   1268: 
1.1.1.2   root     1269: // メニューの「デバイス > マウスモード」
                   1270: void
                   1271: WXMainFrame::OnMouseMode(wxCommandEvent& event)
                   1272: {
                   1273:        // enable ならチェックを付けようとして呼ばれた
                   1274:        bool enable = event.IsChecked();
                   1275: 
1.1.1.18  root     1276:        wxString new_title = frame_title;
1.1.1.2   root     1277:        if (enable) {
                   1278:                // メッセージを表示したい
1.1.1.18  root     1279:                new_title += " (CTRL + F12 to quit mouse mode)";
1.1.1.2   root     1280:        }
1.1.1.18  root     1281:        SetTitle(new_title);
1.1.1.2   root     1282: 
                   1283:        // マウスモードを設定
1.1.1.15  root     1284:        wxCommandEvent newev(NONO_EVT_MOUSEMODE, GetId());
                   1285:        newev.SetEventObject(this);
                   1286:        newev.SetInt(enable);
                   1287:        ::wxPostEvent(mainview, newev);
1.1.1.2   root     1288: }
                   1289: 
                   1290: // メニューの「デバイス > マウスモード」UI
                   1291: void
                   1292: WXMainFrame::OnMouseModeUI(wxUpdateUIEvent& event)
                   1293: {
1.1.1.15  root     1294:        event.Check(mainview->GetMouseMode());
1.1.1.2   root     1295: }
                   1296: 
1.1.1.13  root     1297: // メニューの「デバイス > Operation > Keyboard Connect」イベント
                   1298: void
                   1299: WXMainFrame::OnKeyboardConnect(wxCommandEvent& event)
                   1300: {
                   1301:        // enable ならチェックを付けようとして呼ばれた
                   1302:        bool enable = event.IsChecked();
                   1303: 
                   1304:        // キーボード接続を設定
1.1.1.15  root     1305:        keyboard->Connect(enable);
1.1.1.13  root     1306: }
                   1307: 
                   1308: // メニューの「デバイス > Operation > Keyboard Connect」UI
                   1309: void
                   1310: WXMainFrame::OnKeyboardConnectUI(wxUpdateUIEvent& event)
                   1311: {
1.1.1.15  root     1312:        event.Check(keyboard->IsConnected());
1.1.1.9   root     1313: }
                   1314: 
1.1       root     1315: // メニューのウィンドウ ID 共通イベント
                   1316: // チェックが入る方なら、ウィンドウを作成して表示。
                   1317: // チェックが消える方なら、ウィンドウを削除。
                   1318: void
                   1319: WXMainFrame::OnWindow(wxCommandEvent& event)
                   1320: {
                   1321:        int id = event.GetId();
                   1322: 
                   1323:        DoWindow(id, event.IsChecked());
                   1324: }
                   1325: 
1.1.1.21! root     1326: #define SetMonitor(id, name)   do {    \
        !          1327:        try {   \
        !          1328:                windows[id].reset(new WXMonitorWindow(this, (name), \
        !          1329:                        gMonitorManager->Get(id)));     \
        !          1330:        } catch (...) { }       \
        !          1331: } while (0)
        !          1332: 
1.1       root     1333: void
                   1334: WXMainFrame::DoWindow(int id, bool enable)
                   1335: {
1.1.1.10  root     1336:        // モニタウィンドウを作成する共通部分。
                   1337:        // id はモニター ID であると同時に、windows[] 配列の添字、さらにこの
                   1338:        // モニタウィンドウの wxWindowID としても使っている
                   1339:        // (WXSubWindow::OnClose() 参照)。
1.1.1.4   root     1340: 
1.1       root     1341:        if (enable) {
                   1342:                // チェックが入ったのでウィンドウを作成
                   1343:                switch (id) {
1.1.1.17  root     1344:                 case ID_MONITOR_ACCSTAT:
1.1.1.18  root     1345:                        // こいつだけモニタ ID を持ちつつ上位互換のサブウィンドウがある。
1.1.1.21! root     1346:                        try {
        !          1347:                                windows[id].reset(new
        !          1348:                                        WXAccStatWindow(this, gMonitorManager->Get(id)));
        !          1349:                        } catch (...) { }
1.1.1.17  root     1350:                        break;
                   1351: 
                   1352:                 case ID_MONITOR_AREASET:
                   1353:                        SetMonitor(id, _("Areaset"));
                   1354:                        break;
                   1355: 
1.1.1.10  root     1356:                 case ID_MONITOR_ATC0:
                   1357:                 case ID_MONITOR_ATC1:
                   1358:                 case ID_MONITOR_ATC2:
                   1359:                 case ID_MONITOR_ATC3:
                   1360:                 case ID_MONITOR_ATC4:
                   1361:                 case ID_MONITOR_ATC5:
                   1362:                 case ID_MONITOR_ATC6:
                   1363:                 case ID_MONITOR_ATC7:
                   1364:                 {
1.1.1.18  root     1365:                        uint n = id - ID_MONITOR_ATC0;
                   1366:                        wxString name(string_format("ATC#%u", n));
1.1.1.10  root     1367:                        if ((n & 1) == 0) {
                   1368:                                name += _("(Data)");
                   1369:                        } else {
                   1370:                                name += _("(Inst)");
                   1371:                        }
                   1372:                        SetMonitor(id, name);
1.1.1.4   root     1373:                        break;
1.1.1.10  root     1374:                 }
                   1375: 
                   1376:                 case ID_MONITOR_BREAKPOINT:
                   1377:                        SetMonitor(id, _("Breakpoint"));
1.1.1.5   root     1378:                        break;
1.1.1.10  root     1379: 
1.1.1.15  root     1380:                 case ID_MONITOR_BT45x:
                   1381:                        SetMonitor(id, "Bt454/458");
                   1382:                        break;
                   1383: 
1.1.1.10  root     1384:                 case ID_MONITOR_CMMU0:
                   1385:                 case ID_MONITOR_CMMU1:
                   1386:                 case ID_MONITOR_CMMU2:
                   1387:                 case ID_MONITOR_CMMU3:
                   1388:                 case ID_MONITOR_CMMU4:
                   1389:                 case ID_MONITOR_CMMU5:
                   1390:                 case ID_MONITOR_CMMU6:
                   1391:                 case ID_MONITOR_CMMU7:
                   1392:                 {
1.1.1.18  root     1393:                        uint n = id - ID_MONITOR_CMMU0;
                   1394:                        wxString name(string_format("CMMU#%u", n));
1.1.1.10  root     1395:                        if ((n & 1) == 0) {
                   1396:                                name += _("(Data)");
                   1397:                        } else {
                   1398:                                name += _("(Inst)");
                   1399:                        }
                   1400:                        SetMonitor(id, name);
1.1.1.4   root     1401:                        break;
1.1.1.10  root     1402:                 }
                   1403: 
1.1.1.13  root     1404:                 case ID_MONITOR_CRTC:
                   1405:                        SetMonitor(id, "CRTC");
                   1406:                        break;
                   1407: 
1.1.1.10  root     1408:                 case ID_MONITOR_DMAC:
1.1.1.15  root     1409:                        SetMonitor(id, "DMAC (HD63450)");
1.1.1.5   root     1410:                        break;
1.1.1.10  root     1411: 
1.1.1.14  root     1412:                 case ID_MONITOR_FDC:
1.1.1.15  root     1413:                        SetMonitor(id, "FDC (uPD72065B)");
1.1.1.14  root     1414:                        break;
                   1415: 
1.1.1.13  root     1416:                 case ID_MONITOR_HOSTCOM:
                   1417:                        SetMonitor(id, _("Host Serial Port"));
                   1418:                        break;
                   1419: 
1.1.1.16  root     1420:                 case ID_MONITOR_HOSTNET0:
                   1421:                 case ID_MONITOR_HOSTNET1:
1.1.1.17  root     1422:                 {
                   1423:                        wxString name = _("Host Network");
1.1.1.16  root     1424:                        if (gMainApp.IsX68030()) {
1.1.1.18  root     1425:                                uint n = id - ID_MONITOR_HOSTNET0;
                   1426:                                name += string_format(" #%u", n);
1.1.1.16  root     1427:                        }
1.1.1.17  root     1428:                        SetMonitor(id, name);
1.1.1.13  root     1429:                        break;
1.1.1.17  root     1430:                 }
1.1.1.13  root     1431: 
1.1.1.10  root     1432:                 case ID_MONITOR_INTERRUPT:
1.1.1.15  root     1433:                 {
                   1434:                        wxString name;
                   1435:                        if (gMainApp.Has(VMCap::M88K)) {
                   1436:                                // 実際はほぼシステムコントローラなのでややこしい。
                   1437:                                name = "MPU " + _("Interrupt");
                   1438:                        } else {
                   1439:                                name = MPUName() + " " + _("Interrupt");
                   1440:                        }
                   1441:                        SetMonitor(id, name);
1.1.1.5   root     1442:                        break;
1.1.1.15  root     1443:                 }
1.1.1.10  root     1444: 
                   1445:                 case ID_MONITOR_KEYBOARD:
                   1446:                        SetMonitor(id, _("Keyboard/Mouse"));
1.1.1.4   root     1447:                        break;
1.1.1.10  root     1448: 
                   1449:                 case ID_MONITOR_LANCE:
1.1.1.15  root     1450:                        SetMonitor(id, "LANCE (AM7990)");
1.1       root     1451:                        break;
1.1.1.10  root     1452: 
                   1453:                 case ID_MONITOR_LCD:
1.1.1.21! root     1454:                        try {
        !          1455:                                windows[id].reset(new WXLCDMonitor(this));
        !          1456:                        } catch (...) { }
1.1.1.4   root     1457:                        break;
1.1.1.10  root     1458: 
1.1.1.13  root     1459:                 case ID_MONITOR_LUNAVC:
                   1460:                        SetMonitor(id, _("Video Control"));
1.1.1.4   root     1461:                        break;
1.1.1.10  root     1462: 
1.1.1.16  root     1463:                 case ID_MONITOR_MAINBUS:
                   1464:                 {
                   1465:                        wxString name;
                   1466:                        if (gMainApp.IsX68030()) {
                   1467:                                name = _("Device Map (32bit space)");
                   1468:                        } else {
                   1469:                                name = _("Device Map");
                   1470:                        }
                   1471:                        SetMonitor(id, name);
                   1472:                        break;
                   1473:                 }
                   1474: 
1.1.1.10  root     1475:                 case ID_MONITOR_MEMDUMP0 ...
1.1.1.15  root     1476:                      ID_MONITOR_MEMDUMP(MAX_MEMDUMP_MONITOR - 1):
                   1477:                 case ID_MONITOR_XPMEMDUMP0 ...
                   1478:                      ID_MONITOR_XPMEMDUMP(MAX_XPMEMDUMP_MONITOR - 1):
1.1.1.10  root     1479:                 {
1.1.1.21! root     1480:                        try {
        !          1481:                                windows[id].reset(new WXMemdumpWindow(this, id));
        !          1482:                        } catch (...) { }
1.1.1.4   root     1483:                        break;
1.1.1.10  root     1484:                 }
                   1485: 
                   1486:                 case ID_MONITOR_MFP:
1.1.1.15  root     1487:                        SetMonitor(id, "MFP (MC68901)");
1.1.1.4   root     1488:                        break;
1.1.1.10  root     1489: 
                   1490:                 case ID_MONITOR_MK48T02:
1.1.1.15  root     1491:                        SetMonitor(id, "RTC (MK48T02)");
1.1       root     1492:                        break;
1.1.1.10  root     1493: 
                   1494:                 case ID_MONITOR_MPUATC:
1.1.1.17  root     1495:                        SetMonitor(id, MPUName() + " ATC");
                   1496:                        break;
                   1497: 
                   1498:                 case ID_MONITOR_MPUCACHE:
                   1499:                        SetMonitor(id, MPUName() + " " + _("Cache"));
1.1       root     1500:                        break;
1.1.1.10  root     1501: 
                   1502:                 case ID_MONITOR_MPUREG:
1.1.1.17  root     1503:                        SetMonitor(id, MPUName() + " " + _("Register"));
1.1.1.15  root     1504:                        break;
                   1505: 
1.1.1.16  root     1506:                 case ID_MONITOR_NEREID:
                   1507:                        SetMonitor(id, "Nereid");
                   1508:                        break;
                   1509: 
1.1.1.15  root     1510:                 case ID_MONITOR_ROMCONS:
                   1511:                        SetMonitor(id, _("ROM Console (provisional)"));
1.1.1.7   root     1512:                        break;
1.1.1.10  root     1513: 
1.1.1.15  root     1514:                 case ID_MONITOR_PIO:
                   1515:                        SetMonitor(id, "PIO0/PIO1");
1.1.1.3   root     1516:                        break;
1.1.1.10  root     1517: 
1.1.1.13  root     1518:                 case ID_MONITOR_RENDERER:
                   1519:                        SetMonitor(id, _("Renderer"));
                   1520:                        break;
                   1521: 
1.1.1.10  root     1522:                 case ID_MONITOR_RTC:
1.1.1.17  root     1523:                 {
                   1524:                        // X68k と virt68k が RTC のモニタ ID を共有している。
                   1525:                        // MK48T02 は NVRAM のモニタ ID を使っているのでここではない。
                   1526:                        wxString name;
                   1527:                        if (gMainApp.IsX68030()) {
                   1528:                                name = "RTC (RP5C15)";
                   1529:                        } else if (gMainApp.IsVIRT68K()) {
                   1530:                                name = "RTC (Goldfish RTC/Timer)";
                   1531:                        } else {
                   1532:                                name = "RTC";
                   1533:                        }
                   1534:                        SetMonitor(id, name);
1.1.1.3   root     1535:                        break;
1.1.1.17  root     1536:                 }
1.1.1.10  root     1537: 
1.1.1.16  root     1538:                 case ID_MONITOR_RTL8019AS0:
                   1539:                 case ID_MONITOR_RTL8019AS1:
                   1540:                 {
1.1.1.18  root     1541:                        uint n = id - ID_MONITOR_RTL8019AS0;
                   1542:                        wxString name = string_format("Nereid (RTL8019AS) #%u", n);
1.1.1.16  root     1543:                        SetMonitor(id, name);
                   1544:                        break;
                   1545:                 }
                   1546: 
1.1.1.10  root     1547:                 case ID_MONITOR_SCC:
1.1.1.15  root     1548:                        SetMonitor(id, "SCC (Z8530)");
1.1.1.3   root     1549:                        break;
1.1.1.10  root     1550: 
                   1551:                 case ID_MONITOR_SCHEDULER:
                   1552:                        SetMonitor(id, _("Scheduler"));
1.1       root     1553:                        break;
1.1.1.10  root     1554: 
1.1.1.11  root     1555:                 case ID_MONITOR_SCSIDEVS:
                   1556:                        SetMonitor(id, _("SCSI Devices"));
                   1557:                        break;
                   1558: 
1.1.1.10  root     1559:                 case ID_MONITOR_SIO:
1.1.1.15  root     1560:                        SetMonitor(id, "SIO (uPD7201)");
1.1.1.4   root     1561:                        break;
1.1.1.10  root     1562: 
1.1.1.20  root     1563:                 case ID_MONITOR_SLIRP:
                   1564:                        SetMonitor(id, _("SLIRP Internal States"));
                   1565:                        break;
                   1566: 
1.1.1.10  root     1567:                 case ID_MONITOR_SPC:
1.1.1.15  root     1568:                        SetMonitor(id, "SPC (MB89352)");
1.1.1.2   root     1569:                        break;
1.1.1.10  root     1570: 
1.1.1.18  root     1571:                 case ID_MONITOR_SSG:
                   1572:                        SetMonitor(id, "SSG (YM2149)");
                   1573:                        break;
                   1574: 
1.1.1.10  root     1575:                 case ID_MONITOR_SYSCLK:
                   1576:                        SetMonitor(id, _("System Clock"));
1.1       root     1577:                        break;
1.1.1.10  root     1578: 
1.1.1.17  root     1579:                 case ID_MONITOR_SYSPORT:
                   1580:                        SetMonitor(id, _("System Port"));
                   1581:                        break;
                   1582: 
                   1583:                 case ID_MONITOR_VIRTIO_BLOCK0 ...
                   1584:                      ID_MONITOR_VIRTIO_BLOCK7:
                   1585:                 {
1.1.1.18  root     1586:                        uint n = id - ID_MONITOR_VIRTIO_BLOCK0;
                   1587:                        wxString name = _("VirtIO Block") + string_format(" #%u", n);
1.1.1.17  root     1588:                        SetMonitor(id, name);
                   1589:                        break;
                   1590:                 }
                   1591: 
                   1592:                 case ID_MONITOR_VIRTIO_NET:
                   1593:                        SetMonitor(id, _("VirtIO Network"));
                   1594:                        break;
                   1595: 
1.1.1.21! root     1596:                 case ID_MONITOR_VIRTIO_SCSI:
        !          1597:                        SetMonitor(id, "VirtIO SCSI");
        !          1598:                        break;
        !          1599: 
1.1.1.18  root     1600:                 case ID_MONITOR_VIRTIO_ENTROPY:
                   1601:                        SetMonitor(id, _("VirtIO Entropy"));
                   1602:                        break;
                   1603: 
1.1.1.10  root     1604:                 case ID_MONITOR_WXHOSTINFO:
                   1605:                        SetMonitor(id, _("Host Information"));
1.1       root     1606:                        break;
1.1.1.10  root     1607: 
1.1.1.15  root     1608:                 case ID_MONITOR_XPREG:
                   1609:                        SetMonitor(id, "HD647180 " + _("Register"));
                   1610:                        break;
                   1611: 
                   1612:                 case ID_MONITOR_XPINTR:
                   1613:                        SetMonitor(id, "HD647180 " + _("Interrupt"));
                   1614:                        break;
                   1615: 
                   1616:                 case ID_MONITOR_XPIO:
                   1617:                        SetMonitor(id, _("HD647180 Internal Devices"));
                   1618:                        break;
                   1619: 
1.1.1.10  root     1620:                 case ID_SUBWIN_BRHIST:
1.1.1.15  root     1621:                 {
                   1622:                        wxString name = MPUName() + " " + _("Branch History");
1.1.1.21! root     1623:                        try {
        !          1624:                                windows[id].reset(new WXScrollMonitorWindow(this, name,
        !          1625:                                        gMonitorManager->Get(id)));
        !          1626:                        } catch (...) { }
1.1.1.4   root     1627:                        break;
1.1.1.15  root     1628:                 }
1.1.1.10  root     1629: 
                   1630:                 case ID_SUBWIN_EXHIST:
1.1.1.15  root     1631:                 {
                   1632:                        wxString name = MPUName() + " " + _("Exception History");
1.1.1.21! root     1633:                        try {
        !          1634:                                windows[id].reset(new WXScrollMonitorWindow(this, name,
        !          1635:                                        gMonitorManager->Get(id)));
        !          1636:                        } catch (...) { }
1.1.1.5   root     1637:                        break;
1.1.1.15  root     1638:                 }
1.1.1.10  root     1639: 
                   1640:                 case ID_SUBWIN_CACHE0:
                   1641:                 case ID_SUBWIN_CACHE1:
                   1642:                 case ID_SUBWIN_CACHE2:
                   1643:                 case ID_SUBWIN_CACHE3:
                   1644:                 case ID_SUBWIN_CACHE4:
                   1645:                 case ID_SUBWIN_CACHE5:
                   1646:                 case ID_SUBWIN_CACHE6:
                   1647:                 case ID_SUBWIN_CACHE7:
                   1648:                 {
1.1.1.18  root     1649:                        uint n = id - ID_SUBWIN_CACHE0;
1.1.1.10  root     1650:                        wxString name = _("Cache");
1.1.1.18  root     1651:                        name += string_format("#%u", n);
1.1.1.10  root     1652:                        if ((n & 1) == 0) {
                   1653:                                name += _("(Data)");
                   1654:                        } else {
                   1655:                                name += _("(Inst)");
                   1656:                        }
1.1.1.21! root     1657:                        try {
        !          1658:                                windows[id].reset(new WXCacheWindow(this, name,
        !          1659:                                        gMonitorManager->Get(id)));
        !          1660:                        } catch (...) { }
1.1       root     1661:                        break;
1.1.1.10  root     1662:                 }
                   1663: 
1.1.1.15  root     1664:                 case ID_SUBWIN_DIPSW:
1.1.1.21! root     1665:                        try {
        !          1666:                                windows[id].reset(new WXDipswWindow(this));
        !          1667:                        } catch (...) { }
1.1.1.15  root     1668:                        break;
                   1669: 
1.1.1.10  root     1670:                 case ID_SUBWIN_LCDPANEL:
1.1.1.21! root     1671:                        try {
        !          1672:                                windows[id].reset(new WXLCDWindow(this));
        !          1673:                        } catch (...) { }
1.1       root     1674:                        break;
1.1.1.21! root     1675: 
1.1.1.10  root     1676:                 case ID_SUBWIN_LOG:
1.1.1.21! root     1677:                        try {
        !          1678:                                windows[id].reset(new WXLogMonitor(this));
        !          1679:                        } catch (...) { }
1.1       root     1680:                        break;
1.1.1.21! root     1681: 
1.1.1.13  root     1682:                 case ID_SUBWIN_LOGSETTING:
1.1.1.21! root     1683:                        try {
        !          1684:                                windows[id].reset(new WXLogSettingWindow(this));
        !          1685:                        } catch (...) { }
1.1.1.13  root     1686:                        break;
1.1.1.14  root     1687: 
1.1.1.13  root     1688:                 case ID_SUBWIN_LUNAFB:
1.1.1.14  root     1689:                 case ID_SUBWIN_TVRAM:
                   1690:                 {
                   1691:                        // 呼び方が違うので名前と ID が違う
                   1692:                        wxString name;
                   1693:                        if (id == ID_SUBWIN_LUNAFB) {
                   1694:                                name = _("Bitmap Plane");
                   1695:                        } else {
                   1696:                                name = _("Text VRAM");
                   1697:                        }
1.1.1.21! root     1698:                        try {
        !          1699:                                windows[id].reset(new WXPlaneVRAMWindow(this, name));
        !          1700:                        } catch (...) { }
1.1.1.14  root     1701:                        break;
                   1702:                 }
                   1703: 
1.1.1.17  root     1704:                 case ID_SUBWIN_NEWSIO:
1.1.1.21! root     1705:                        try {
        !          1706:                                windows[id].reset(new WXScrollMonitorWindow(this,
        !          1707:                                        _("Device Map (NEWS)"),
        !          1708:                                        gMonitorManager->Get(id)));
        !          1709:                        } catch (...) { }
1.1.1.17  root     1710:                        break;
                   1711: 
1.1.1.15  root     1712:                 case ID_SUBWIN_PALETTE:
                   1713:                 case ID_SUBWIN_TEXTPAL:
                   1714:                 {
                   1715:                        // 呼び方が違うので名前と ID が違う
                   1716:                        wxString name;
                   1717:                        if (id == ID_SUBWIN_TEXTPAL) {
                   1718:                                name = _("Text Palette Colormap");
                   1719:                        } else {
                   1720:                                name = _("Palette Colormap");
                   1721:                        }
1.1.1.21! root     1722:                        try {
        !          1723:                                windows[id].reset(new WXPaletteWindow(this, name));
        !          1724:                        } catch (...) { }
1.1.1.15  root     1725:                        break;
                   1726:                 }
                   1727: 
1.1.1.14  root     1728:                 case ID_SUBWIN_ROM:
1.1.1.21! root     1729:                        try {
        !          1730:                                windows[id].reset(new WXROMWindow(this));
        !          1731:                        } catch (...) { }
1.1       root     1732:                        break;
1.1.1.10  root     1733: 
                   1734:                 case ID_SUBWIN_SOFTKEY:
1.1.1.21! root     1735:                        try {
        !          1736:                                windows[id].reset(new WXSoftKeyWindow(this,
        !          1737:                                        gMainApp.GetVMType()));
        !          1738:                        } catch (...) { }
1.1.1.5   root     1739:                        break;
1.1.1.10  root     1740: 
1.1.1.13  root     1741:                 case ID_SUBWIN_VECTOR:
1.1.1.15  root     1742:                 {
                   1743:                        wxString name = MPUName() + " " + _("Vector Table");
1.1.1.21! root     1744:                        try {
        !          1745:                                windows[id].reset(new WXScrollMonitorWindow(this, name,
        !          1746:                                        gMonitorManager->Get(id)));
        !          1747:                        } catch (...) { }
1.1.1.13  root     1748:                        break;
1.1.1.15  root     1749:                 }
                   1750: 
1.1.1.16  root     1751:                 case ID_SUBWIN_X68KIO:
1.1.1.21! root     1752:                        try {
        !          1753:                                windows[id].reset(new WXScrollMonitorWindow(this,
        !          1754:                                        _("Device Map (24bit space)"),
        !          1755:                                        gMonitorManager->Get(id)));
        !          1756:                        } catch (...) { }
1.1.1.16  root     1757:                        break;
                   1758: 
1.1.1.15  root     1759:                 case ID_SUBWIN_XPBRHIST:
                   1760:                 {
                   1761:                        wxString name = "HD647180 " + _("Branch History");
1.1.1.21! root     1762:                        try {
        !          1763:                                windows[id].reset(new WXScrollMonitorWindow(this, name,
        !          1764:                                        gMonitorManager->Get(id)));
        !          1765:                        } catch (...) { }
1.1.1.15  root     1766:                        break;
                   1767:                 }
                   1768: 
                   1769:                 case ID_SUBWIN_XPEXHIST:
                   1770:                 {
                   1771:                        wxString name = "HD647180 " + _("Exception History");
1.1.1.21! root     1772:                        try {
        !          1773:                                windows[id].reset(new WXScrollMonitorWindow(this, name,
        !          1774:                                        gMonitorManager->Get(id)));
        !          1775:                        } catch (...) { }
1.1.1.15  root     1776:                        break;
                   1777:                 }
1.1.1.13  root     1778: 
1.1.1.10  root     1779:                 default:
1.1.1.15  root     1780:                        PANIC("'%s' not listed", Monitor::GetIdText(id));
1.1       root     1781:                }
                   1782:                windows[id]->Show();
                   1783:        } else {
                   1784:                // チェックが消えたのでウィンドウを終了
                   1785:                windows[id]->Close();
                   1786:                // (削除自体はこの少し下の DeleteWindow() で行なっている)
                   1787:        }
                   1788: }
                   1789: 
                   1790: // Update UI イベント
                   1791: void
                   1792: WXMainFrame::OnWindowUI(wxUpdateUIEvent& event)
                   1793: {
                   1794:        int id = event.GetId();
                   1795: 
                   1796:        // ウィンドウが存在していればチェックを表示
1.1.1.4   root     1797:        event.Check((bool)windows[id]);
1.1.1.10  root     1798: 
1.1.1.15  root     1799:        if (IS_MONITOR_MEMDUMP(id) || IS_MONITOR_XPMEMDUMP(id)) {
1.1.1.10  root     1800:                // メニューに現在のアドレスを載せる
1.1.1.15  root     1801:                // (ウィンドウの生存期間外にも呼ばれることに注意)
                   1802:                auto mon = gMonitorManager->Get(id);
1.1.1.19  root     1803:                auto *memdump = dynamic_cast<Memdump *>(mon->obj);
1.1.1.15  root     1804:                assert(memdump);
1.1.1.18  root     1805:                uint32 addr = memdump->GetAddr().Addr();
1.1.1.15  root     1806: 
1.1.1.18  root     1807:                uint n;
1.1.1.15  root     1808:                wxString text = _("Memory Dump");
                   1809:                if (IS_MONITOR_XPMEMDUMP(id)) {
                   1810:                        n = id - ID_MONITOR_XPMEMDUMP0;
1.1.1.18  root     1811:                        text += string_format(" &%u: $%05x", n, addr);
1.1.1.15  root     1812:                } else {
                   1813:                        n = id - ID_MONITOR_MEMDUMP0;
1.1.1.18  root     1814:                        text += string_format(" &%u: $%08x", n, addr);
1.1.1.15  root     1815:                }
                   1816:                event.SetText(text);
1.1.1.10  root     1817:        }
1.1.1.4   root     1818: }
                   1819: 
                   1820: // バージョンダイアログ
                   1821: void
                   1822: WXMainFrame::OnAbout(wxCommandEvent& event)
                   1823: {
                   1824:        WXVersionDlg dlg(this);
                   1825:        dlg.ShowModal();
1.1       root     1826: }
                   1827: 
1.1.1.14  root     1828: // FD を挿入する。
                   1829: void
                   1830: WXMainFrame::InsertFD(int unit, const std::string& path)
                   1831: {
                   1832:        FDDDevice *fdd = fdd_array[unit];
                   1833:        assert(fdd);
                   1834: 
                   1835:        // VM に依頼
                   1836:        // (エラーが起きれば別途 UI メッセージが飛んでくる)
                   1837:        fdd->LoadDiskUI(path);
                   1838: 
                   1839:        // 次回以降のダイアログのカレントディレクトリをここに更新
                   1840:        auto pos = path.rfind('/');
                   1841:        current_dir = path.substr(0, pos);
                   1842: }
                   1843: 
                   1844: // FD をイジェクトする。
                   1845: void
                   1846: WXMainFrame::EjectFD(int unit, bool force)
                   1847: {
                   1848:        FDDDevice *fdd = fdd_array[unit];
                   1849:        assert(fdd);
                   1850: 
                   1851:        fdd->UnloadDiskUI(force);
                   1852: }
                   1853: 
1.1.1.11  root     1854: // CD/MO を挿入する。
1.1       root     1855: void
1.1.1.11  root     1856: WXMainFrame::InsertCD(int id, const std::string& path)
1.1       root     1857: {
1.1.1.11  root     1858:        SCSIDisk *scsidisk = dynamic_cast<SCSIDisk*>(scsidev[id]);
                   1859:        assert(scsidisk);
1.1       root     1860: 
1.1.1.11  root     1861:        // VM に依頼
                   1862:        // (エラーが起きれば別途 UI メッセージが飛んでくる)
                   1863:        scsidisk->LoadDiskUI(path);
                   1864: 
                   1865:        // 次回以降のダイアログのカレントディレクトリをここに更新
                   1866:        auto pos = path.rfind('/');
                   1867:        current_dir = path.substr(0, pos);
1.1       root     1868: }
                   1869: 
1.1.1.11  root     1870: // CD/MO をイジェクトする。
1.1       root     1871: void
1.1.1.11  root     1872: WXMainFrame::EjectCD(int id, bool force)
1.1       root     1873: {
1.1.1.11  root     1874:        SCSIDisk *scsidisk = dynamic_cast<SCSIDisk*>(scsidev[id]);
                   1875:        assert(scsidisk);
                   1876: 
1.1.1.13  root     1877:        scsidisk->UnloadDiskUI(force);
1.1       root     1878: }
                   1879: 
1.1.1.14  root     1880: // CD/MO/FD の挿入失敗メッセージ。
                   1881: // CD/MO と FD でメッセージが同じなので共用する。
1.1.1.4   root     1882: void
1.1.1.14  root     1883: WXMainFrame::OnInsertFailed(wxCommandEvent& event)
1.1.1.4   root     1884: {
1.1.1.11  root     1885:        ::wxMessageBox(_("Cannot load the image file"));
1.1.1.4   root     1886: }
                   1887: 
1.1.1.11  root     1888: // ウィンドウをリストから削除する
                   1889: // (ウィンドウの Close() から呼ばれる)
1.1.1.4   root     1890: void
1.1.1.11  root     1891: WXMainFrame::DeleteWindow(wxWindow *win)
1.1.1.4   root     1892: {
1.1.1.11  root     1893:        for (int id = 0; id < ID_SUBWIN_MAX; id++) {
                   1894:                if (windows[id].get() == win) {
                   1895:                        windows[id].reset();
                   1896:                        break;
                   1897:                }
                   1898:        }
1.1.1.4   root     1899: }
                   1900: 
                   1901: // m680x0 ダブルバスフォールト処理
                   1902: void
                   1903: WXMainFrame::OnHaltNotify(wxCommandEvent& event)
                   1904: {
                   1905:        ::wxMessageBox(_("Double bus fault has occurred in VM"),
                   1906:                wxEmptyString,
                   1907:                wxICON_EXCLAMATION);
                   1908: }
                   1909: 
1.1.1.10  root     1910: // 起動時にオープンするサブウィンドウ (-M オプション)
                   1911: /*static*/ std::array<bool, ID_SUBWIN_MAX> WXMainFrame::subwindow_start;
1.1.1.15  root     1912: 
                   1913: // モニタの更新頻度
                   1914: /*static*/ int WXMainFrame::monitor_rate;

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.