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

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.4   root        7: #include "wxmainframe.h"
                      8: #include "wxdumpmonitor.h"
1.1.1.5   root        9: #include "wxhistmonitor.h"
                     10: #include "wxlcdwindow.h"
1.1.1.4   root       11: #include "wxlogmonitor.h"
                     12: #include "wxmainview.h"
                     13: #include "wxmonitor.h"
                     14: #include "wxmpumonitor.h"
                     15: #include "wxsoftkey.h"
1.1.1.9   root       16: #include "wxstatuspanel.h"
1.1.1.4   root       17: #include "wxtextpanel.h"
1.1.1.11! root       18: #include "wxuimessage.h"
1.1.1.4   root       19: #include "wxversion.h"
                     20: #include "wxvideomonitor.h"
1.1.1.5   root       21: #include "debugger.h"
1.1.1.3   root       22: #include "mainapp.h"
1.1.1.4   root       23: #include "mpu680x0.h"
                     24: #include "mpu88xx0.h"
1.1       root       25: #include "netdriver.h"
                     26: #include "scheduler.h"
1.1.1.11! root       27: #include "spc.h"
1.1.1.4   root       28: #include "vm.h"
1.1       root       29: 
                     30: WXMainFrame *gMainFrame;
                     31: 
                     32: wxBEGIN_EVENT_TABLE(WXMainFrame, inherited)
1.1.1.3   root       33:        EVT_CLOSE(WXMainFrame::OnClose)
1.1       root       34:        EVT_MENU(wxID_EXIT, WXMainFrame::OnExit)
                     35: 
                     36:        EVT_MENU(ID_FULL_SPEED, WXMainFrame::OnFullSpeed)
                     37:        EVT_UPDATE_UI(ID_FULL_SPEED, WXMainFrame::OnFullSpeedUI)
1.1.1.9   root       38:        EVT_MENU(ID_RESTART_VM, WXMainFrame::OnRestartVM)
1.1       root       39:        EVT_MENU_RANGE(ID_SCALE_START + 1, ID_SCALE_END - 1,
                     40:                WXMainFrame::OnMenuScale)
                     41:        EVT_UPDATE_UI_RANGE(ID_SCALE_START + 1, ID_SCALE_END - 1,
                     42:                WXMainFrame::OnMenuScaleUI)
                     43:        EVT_MENU_RANGE(ID_FONTSIZE_START + 1, ID_FONTSIZE_END - 1,
                     44:                WXMainFrame::OnMenuFontSize)
                     45:        EVT_UPDATE_UI_RANGE(ID_FONTSIZE_START + 1, ID_FONTSIZE_END - 1,
                     46:                WXMainFrame::OnMenuFontSizeUI)
1.1.1.5   root       47:        EVT_MENU_RANGE(ID_MONRATE_START + 1, ID_MONRATE_END - 1,
                     48:                WXMainFrame::OnMenuMonRate)
                     49:        EVT_UPDATE_UI_RANGE(ID_MONRATE_START + 1, ID_MONRATE_END - 1,
                     50:                WXMainFrame::OnMenuMonRateUI)
1.1.1.9   root       51:        EVT_MENU(ID_SHOW_STATPANEL, WXMainFrame::OnShowStatusPanel)
                     52:        EVT_UPDATE_UI(ID_SHOW_STATPANEL, WXMainFrame::OnShowStatusPanelUI)
1.1.1.11! root       53:        EVT_MENU_RANGE(ID_CD_INSERT_0, ID_CD_INSERT_7,
        !            54:                WXMainFrame::OnCDInsert)
        !            55:        EVT_UPDATE_UI_RANGE(ID_CD_INSERT_0, ID_CD_INSERT_7,
        !            56:                WXMainFrame::OnCDInsertUI)
        !            57:        EVT_MENU_RANGE(ID_CD_EJECT_0, ID_CD_EJECT_7,
        !            58:                WXMainFrame::OnCDEject)
        !            59:        EVT_UPDATE_UI_RANGE(ID_CD_EJECT_0, ID_CD_EJECT_7,
        !            60:                WXMainFrame::OnCDEjectUI)
        !            61:        EVT_MENU_RANGE(ID_CD_FORCE_0, ID_CD_FORCE_7,
        !            62:                WXMainFrame::OnCDForce)
        !            63:        EVT_UPDATE_UI_RANGE(ID_CD_FORCE_0, ID_CD_FORCE_7,
        !            64:                WXMainFrame::OnCDForceUI)
1.1.1.2   root       65:        EVT_MENU(ID_MOUSEMODE, WXMainFrame::OnMouseMode)
                     66:        EVT_UPDATE_UI(ID_MOUSEMODE, WXMainFrame::OnMouseModeUI)
1.1.1.9   root       67:        EVT_MENU(ID_RESET_BUTTON, WXMainFrame::OnResetButton)
1.1.1.10  root       68:        EVT_MENU_RANGE(0, ID_SUBWIN_END, WXMainFrame::OnWindow)
                     69:        EVT_UPDATE_UI_RANGE(0, ID_SUBWIN_END, WXMainFrame::OnWindowUI)
1.1.1.4   root       70:        EVT_MENU(wxID_ABOUT, WXMainFrame::OnAbout)
1.1       root       71: wxEND_EVENT_TABLE()
                     72: 
                     73: WXMainFrame::WXMainFrame(wxWindow *parent)
1.1.1.10  root       74:        : inherited(parent, wxID_ANY, "nono", wxDefaultPosition, wxDefaultSize,
1.1.1.6   root       75:                wxDEFAULT_FRAME_STYLE & ~wxMAXIMIZE_BOX & ~wxRESIZE_BORDER)
1.1       root       76: {
1.1.1.3   root       77:        vmtype_t vmtype;
                     78:        vmtype = gMainApp.GetVMType();
1.1       root       79: 
                     80:        // とりあえずメニュー
                     81:        // XXX すぐにメニューファクトリーになる
                     82:        wxMenuBar *menubar = new wxMenuBar();
                     83:        wxMenu *menuFile = new wxMenu();
                     84:        // XXX とりあえず適当なところにおいとく
1.1.1.4   root       85:        menuFile->Append(ID_FULL_SPEED, _("Full &Speed Mode"), "", wxITEM_CHECK);
1.1.1.9   root       86:        menuFile->AppendSeparator();
                     87:        menuFile->Append(ID_RESTART_VM, _("&Restart VM"), "");
1.1.1.4   root       88:        menuFile->Append(wxID_EXIT, _("E&xit"));
                     89:        menubar->Append(menuFile, _("&File"));
1.1       root       90: 
                     91:        wxMenu *menuDisplay = new wxMenu();
                     92:        wxMenu *menuViewScale = new wxMenu();
1.1.1.4   root       93:        menuViewScale->Append(ID_SCALE_1_00, _("x1.&0"), "", wxITEM_CHECK);
                     94:        menuViewScale->Append(ID_SCALE_0_75, _("x0.&75"), "", wxITEM_CHECK);
                     95:        menuViewScale->Append(ID_SCALE_0_50, _("x0.&5"), "", wxITEM_CHECK);
                     96:        menuDisplay->AppendSubMenu(menuViewScale, _("&Scale"));
1.1       root       97:        wxMenu *menuFontSize = new wxMenu();
1.1.1.4   root       98:        menuFontSize->AppendRadioItem(ID_FONTSIZE_12, "1&2");
                     99:        menuFontSize->AppendRadioItem(ID_FONTSIZE_16, "1&6");
                    100:        menuDisplay->AppendSubMenu(menuFontSize, _("&Font Size"));
1.1.1.5   root      101:        wxMenu *menuMonRate = new wxMenu();
                    102:        menuMonRate->AppendRadioItem(ID_MONRATE_20, _("High (&20Hz)"));
                    103:        menuMonRate->AppendRadioItem(ID_MONRATE_5, _("Middle (&5Hz)"));
                    104:        menuMonRate->AppendRadioItem(ID_MONRATE_1, _("Low (&1Hz)"));
                    105:        menuDisplay->AppendSubMenu(menuMonRate, _("&Monitor Speed"));
1.1.1.9   root      106:        menuDisplay->Append(ID_SHOW_STATPANEL, _("Show Status &Panel"), "",
                    107:                wxITEM_CHECK);
1.1.1.4   root      108:        menubar->Append(menuDisplay, _("&View"));
1.1       root      109: 
                    110:        wxMenu *menuDevice = new wxMenu();
1.1.1.11! root      111:        CreateRemovableMenu(menuDevice);
1.1.1.10  root      112:        menuDevice->Append(ID_SUBWIN_SOFTKEY, _("Software &Keyboard"),
1.1.1.2   root      113:                "", wxITEM_CHECK);
1.1.1.4   root      114:        menuDevice->Append(ID_MOUSEMODE, _("&Mouse Mode\tCTRL+F12"),
1.1.1.2   root      115:                "", wxITEM_CHECK);
1.1.1.5   root      116:        if (gMainApp.HasVMFeature(VMF_LUNA)) {
1.1.1.10  root      117:                menuDevice->Append(ID_SUBWIN_LCDPANEL, _("Front &LCD"),
1.1.1.5   root      118:                        "", wxITEM_CHECK);
                    119:        }
1.1.1.9   root      120:        menuDevice->AppendSeparator();
1.1.1.10  root      121:        wxMenu *menuOper = new wxMenu();
                    122:        menuOper->Append(ID_RESET_BUTTON, _("Push &Reset button"));
                    123:        menuDevice->AppendSubMenu(menuOper, _("Operation"));
1.1.1.4   root      124:        menubar->Append(menuDevice, _("&Device"));
                    125: 
                    126:        // 機種によってモニタウィンドウを追加する
                    127: #define AppendIf(menu, id, label)      do { \
1.1.1.10  root      128:        vmf_t feature_ = gMonitorManager.GetFeature(id); \
                    129:        if (gMainApp.HasVMFeature(feature_)) { \
                    130:                (menu)->Append((id), (label), "", wxITEM_CHECK); \
                    131:        } \
                    132: } while (0)
                    133: #define AppendIfSeparator(menu, feature_)      do { \
                    134:        if (gMainApp.HasVMFeature(feature_)) { \
                    135:                (menu)->AppendSeparator(); \
1.1.1.4   root      136:        } \
                    137: } while (0)
1.1       root      138: 
                    139:        wxMenu *menuMonitor = new wxMenu();
1.1.1.10  root      140:        AppendIf(menuMonitor, ID_MONITOR_SCHEDULER,     _("&Scheduler"));
                    141:        AppendIf(menuMonitor, ID_SUBWIN_LOG,            _("&Log"));
1.1.1.4   root      142: 
1.1.1.5   root      143:        wxMenu *menuDebug = new wxMenu();
1.1.1.10  root      144:        AppendIf(menuDebug, ID_MONITOR_BREAKPOINT,      _("&Breakpoint"));
                    145:        AppendIf(menuDebug, ID_SUBWIN_BRHIST,           _("Branch &History"));
                    146:        AppendIf(menuDebug, ID_SUBWIN_EXHIST,           _("&Exception History"));
1.1.1.5   root      147:        menuMonitor->AppendSubMenu(menuDebug, _("&Debug"));
                    148: 
1.1.1.4   root      149:        wxMenu *menuMPU = new wxMenu();
1.1.1.10  root      150:        AppendIf(menuMPU, ID_MONITOR_MPUREG,            _("&Register"));
                    151:        AppendIf(menuMPU, ID_MONITOR_MPUATC,              "&ATC");
                    152:        AppendIfSeparator(menuMPU, VMF_M88K);
                    153:        AppendIf(menuMPU, ID_MONITOR_CMMU7,                      "CMMU#7" + _("(Inst)"));
                    154:        AppendIf(menuMPU, ID_MONITOR_ATC7,                        "ATC#7");
                    155:        AppendIf(menuMPU, ID_SUBWIN_CACHE7,                     _("Cache") + "#7");
                    156:        AppendIfSeparator(menuMPU, VMF_M88K);
                    157:        AppendIf(menuMPU, ID_MONITOR_CMMU6,                       "CMMU#6" + _("(Data)"));
                    158:        AppendIf(menuMPU, ID_MONITOR_ATC6,                        "ATC#6");
                    159:        AppendIf(menuMPU, ID_SUBWIN_CACHE6,                     _("Cache") + "#6");
                    160:        menuMonitor->AppendSubMenu(menuMPU, "MP&U");
                    161: 
                    162:        wxMenu *menuMemdump = new wxMenu();
                    163:        // MEMDUMPn のラベルは UpdateUI で書き直すのでここでは適当に埋めておく。
                    164:        // (empty だと怒られる)
                    165:        // MONITOR_RTC は X68k の RTC、LUNA では MONITOR_MK48T02 だが今の所
                    166:        // NVRAM 側のことは表示してないのでラベルも RTC にしてある。
                    167:        for (int i = 0; i < MAX_MEMDUMP_MONITOR; i++) {
                    168:                AppendIf(menuMemdump, ID_MONITOR_MEMDUMP0 + i, "memdump");
                    169:        }
                    170:        menuMonitor->AppendSubMenu(menuMemdump, _("&Memory Dump"));
                    171:        AppendIf(menuMonitor, ID_MONITOR_INTERRUPT,     _("&Interrupt"));
                    172:        AppendIf(menuMonitor, ID_MONITOR_SPC,             "S&PC");
1.1.1.11! root      173:        AppendIf(menuMonitor, ID_MONITOR_SCSIDEVS,      _("SCSI Devices"));
1.1.1.10  root      174:        AppendIf(menuMonitor, ID_MONITOR_RTC,             "&RTC");
                    175:        AppendIf(menuMonitor, ID_MONITOR_MK48T02,         "&RTC");
                    176:        AppendIf(menuMonitor, ID_MONITOR_DMAC,            "DM&AC");
                    177:        AppendIf(menuMonitor, ID_MONITOR_MFP,             "M&FP");
                    178:        AppendIf(menuMonitor, ID_MONITOR_SCC,             "SCC(&Z)");
                    179:        AppendIf(menuMonitor, ID_MONITOR_SIO,             "SIO(&U)");
                    180:        AppendIf(menuMonitor, ID_MONITOR_PIO0,            "PIO0");
                    181:        AppendIf(menuMonitor, ID_MONITOR_KEYBOARD,      _("&Keyboard/Mouse"));
                    182:        AppendIf(menuMonitor, ID_MONITOR_LANCE,           "Lance(&E)");
                    183:        AppendIf(menuMonitor, ID_MONITOR_LCD,             "LCD(&J)");
                    184:        AppendIf(menuMonitor, ID_MONITOR_SYSCLK,        _("S&ystem Clock"));
                    185:        AppendIf(menuMonitor, ID_MONITOR_LUNAFB,        _("&Bitmap Control"));
                    186:        AppendIf(menuMonitor, ID_SUBWIN_LUNAFB0,        _("Bitmap #&0"));
1.1.1.5   root      187: 
                    188:        wxMenu *menuHost = new wxMenu();
1.1.1.10  root      189:        AppendIf(menuHost, ID_MONITOR_WXHOSTINFO,       _("Host &Information"));
                    190:        AppendIf(menuHost, ID_MONITOR_HOSTNET,          _("Host &Network"));
1.1.1.5   root      191:        menuMonitor->AppendSubMenu(menuHost, _("&Host"));
                    192: 
1.1.1.4   root      193:        menubar->Append(menuMonitor, _("&Monitor"));
                    194: 
                    195: #if defined(__WXOSX__)
                    196:        // OSX では wxID_ABOUT はリンゴメニューに入れるしきたりになっている。
                    197:        // Append() すると Quit より下に来てしまうので、Prepend() で上に追加。
                    198:        // 今のところヘルプメニューから About ダイアログを抜くとメニューが空に
                    199:        // なってしまうので、ヘルプメニューの追加ごと抑制する。
                    200:        menubar->OSXGetAppleMenu()->Prepend(wxID_ABOUT, _("About nono"));
                    201: #else
                    202:        wxMenu *menuHelp = new wxMenu();
                    203:        menuHelp->Append(wxID_ABOUT, _("About nono"));
                    204:        menubar->Append(menuHelp, _("&Help"));
                    205: #endif
                    206: 
1.1       root      207:        SetMenuBar(menubar);
                    208: 
                    209:        wxString title("nono");
                    210:        switch (vmtype) {
1.1.1.3   root      211:         case VMTYPE_X68030:
                    212:                title += "(X68030)";
                    213:                break;
1.1.1.4   root      214:         case VMTYPE_LUNA1:
1.1       root      215:                title += "(LUNA-I)";
                    216:                break;
1.1.1.3   root      217:         case VMTYPE_LUNA88K:
                    218:                title += "(LUNA88K)";
                    219:                break;
                    220:         default:
1.1       root      221:                break;
                    222:        }
                    223:        SetTitle(title);
                    224: 
                    225:        // UpdateUI イベントは Idle 時に時折チェックされるらしいが、
                    226:        // (メインビューとサブウィンドウを合わせた) タイマーイベントの粒度が
                    227:        // 小さいためか、秒間120回とかいうレベルで UpdateUIEvent が飛んでくる
                    228:        // っぽい (全タイマーをとめたら治る模様)。
                    229:        // さすがにそんなに来られても気持ち悪いのと、どうせメニュー開いた瞬間
                    230:        // 表示しようとする前には一度飛んでくるのだから、アイドル時のチェックは
                    231:        // いらない気がする。間隔広げておいても、ぱっと見副作用はなさそうだけど
                    232:        // 念のため事象が分かりやすいように 10秒くらいにしておく。
                    233:        wxUpdateUIEvent::SetUpdateInterval(10000);
                    234: 
                    235:        wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
                    236: 
1.1.1.10  root      237:        // WXStatusPanel コンストラクタが gMainView を参照するので
                    238:        // gMainView のほうを先に作成すること。
                    239:        gMainView = new WXMainView(this);
1.1.1.9   root      240:        gStatusPanel = new WXStatusPanel(this);
                    241:        vbox->Add(gStatusPanel, 0, wxEXPAND);
1.1       root      242:        vbox->Add(gMainView, 1, wxEXPAND | wxFIXED_MINSIZE);
                    243: 
1.1.1.9   root      244:        // SHOW イベントを最初にも一度起こしたいため
                    245:        // ステータスパネルを一旦非表示にする (これで SHOW(false) イベントが飛ぶ)
                    246:        gStatusPanel->Hide();
                    247:        const ConfigItem& item_show = gConfig->Find("show-statuspanel");
                    248:        if (item_show.AsInt() != 0) {
                    249:                // 必要なら改めて表示 (これで SHOW(true) イベントが飛ぶ)
                    250:                gStatusPanel->Show();
                    251:        }
                    252: 
1.1       root      253:        SetSizer(vbox);
                    254: 
                    255:        Fit();
                    256: 
1.1.1.5   root      257:        // モニタの更新頻度は初期値だけ設定から読んで、あとはここで管理する。
                    258:        // 不正値ならデフォルトの 15Hz にしておくか
1.1.1.9   root      259:        const ConfigItem& item_rate = gConfig->Find("monitor-rate");
                    260:        monitor_rate = item_rate.AsInt();
1.1.1.5   root      261:        if (monitor_rate < 1 || monitor_rate > 60) {
                    262:                monitor_rate = 15;
                    263:        }
                    264: 
1.1.1.4   root      265:        // Activate イベントは、このトップレベルウィンドウにウィンドウフォーカスが
                    266:        // 来た or 外れたことを示すので、wxFrame (というかたぶん wxTopLevelWindow)
                    267:        // を継承している WXMainFrameに飛んでくるのだが、処理の都合上 WXMainView で
                    268:        // 扱いたいので、そちらに回す。
                    269:        Connect(wxEVT_ACTIVATE, wxActivateEventHandler(WXMainView::OnActivate),
                    270:                NULL, gMainView);
                    271: 
1.1.1.11! root      272:        // ウィンドウ表示後に続きの処理をするための単発アイドルイベント。
        !           273:        Connect(wxEVT_IDLE, wxIdleEventHandler(WXMainFrame::OnIdle));
        !           274: 
        !           275:        // VM からの通知を接続
        !           276:        WXUIMessage::Connect(UIMessage::POWEROFF, this,
        !           277:                wxCommandEventHandler(WXMainFrame::OnExit));
        !           278:        WXUIMessage::Connect(UIMessage::SCSI_MEDIA_FAILED, this,
        !           279:                wxCommandEventHandler(WXMainFrame::OnInsertCDFailed));
        !           280:        if (gMPU680x0) {
        !           281:                WXUIMessage::Connect(UIMessage::HALT, this,
        !           282:                        wxCommandEventHandler(WXMainFrame::OnHaltNotify));
        !           283:        }
1.1       root      284: }
                    285: 
                    286: WXMainFrame::~WXMainFrame()
                    287: {
                    288: }
                    289: 
1.1.1.11! root      290: // リムーバブルデバイス用のメニューを作成して menuDevice に追加する
        !           291: void
        !           292: WXMainFrame::CreateRemovableMenu(wxMenu *menuDevice)
        !           293: {
        !           294:        wxMenu *menu;
        !           295:        bool added = false;
        !           296: 
        !           297:        // FD
        !           298: 
        !           299:        // CD, MO
        !           300:        for (int id = 0; id < 8; id++) {
        !           301:                scsidev[id] = gSPC->GetTarget(id);
        !           302:                if (scsidev[id]) {
        !           303:                        menu = CreateSCSIRemovableMenu(id);
        !           304:                        if (menu) {
        !           305:                                std::string label = string_format("%s (ID%d)",
        !           306:                                        SCSI::GetDevTypeName(scsidev[id]->GetDevType()), id);
        !           307:                                menuDevice->AppendSubMenu(menu, label);
        !           308:                                added = true;
        !           309:                        }
        !           310:                }
        !           311:        }
        !           312: 
        !           313:        // 1つでも追加したらセパレータ
        !           314:        if (added) {
        !           315:                menuDevice->AppendSeparator();
        !           316:        }
        !           317: }
        !           318: 
        !           319: // SCSI リムーバブルデバイス用のメニューを作成して返す。
        !           320: // id はデバイスが接続されていること (リムーバブルデバイスであるかは問わない)。
        !           321: // リムーバブルデバイスでなければ NULL を返す。
        !           322: // メニューバーとポップアップメニュー共通。
        !           323: wxMenu *
        !           324: WXMainFrame::CreateSCSIRemovableMenu(uint id) const
        !           325: {
        !           326:        const auto *dev = scsidev[id];
        !           327:        assert(dev);
        !           328: 
        !           329:        switch (dev->GetDevType()) {
        !           330:         case SCSI::DevType::CD:
        !           331:         case SCSI::DevType::MO:
        !           332:         {
        !           333:                wxMenu *menu = new wxMenu();
        !           334:                // Insert の実際のラベルは UpdateUI でセットする。
        !           335:                // ただし何か入れておかないといけないので適当にセット。
        !           336:                menu->Append(ID_CD_INSERT(id), "Insert", "");
        !           337:                menu->Append(ID_CD_EJECT(id), _("&Eject"), "");
        !           338:                menu->Append(ID_CD_FORCE(id), _("&Force Eject"), "");
        !           339:                return menu;
        !           340:         }
        !           341:         default:
        !           342:                return NULL;
        !           343:        }
        !           344: }
        !           345: 
        !           346: // ウィンドウ作成イベント (を実現するためここではアイドルイベントを使う)
1.1.1.10  root      347: //
1.1.1.11! root      348: // 初期化(っぽい)もののうちコンストラクタでは早すぎるものは、コンストラクタ
        !           349: // 直後に起こすこのイベント内で処理する。使えそうなイベントはいくつかあり、
        !           350: // 自前の Create (今はもうない) -> WindowCreate -> Idle -> Paint の順で
        !           351: // 起きるようだ。
        !           352: // 自前の Create 時点では早すぎて、ここでサブウィンドウを作成するとサイズが 0
        !           353: // みたいなウィンドウが一瞬出来てしまい GTK のワーニングが出る (その後サイズを
        !           354: // 矯正すれば表示自体は出来る)。
1.1.1.10  root      355: // WindowCreate 時点ではその問題は起きないが、ここはまだメインウィンドウ表示
                    356: // 前なので、ここでサブウィンドウを表示した後メインウィンドウを表示すると
                    357: // (ウィンドウマネージャにもよるかもだが)、メインウィンドウがサブウィンドウを
                    358: // 隠してしまう。
1.1.1.11! root      359: // Idle イベント時点まで来ると上の2つの問題は回避できるようだ。
        !           360: // Paint イベントの時点でもタイミング的には問題ないが、環境によっては(?)
        !           361: // このイベント自体が飛んで来ないことがあるようだ。WXMainFrame の再描画は
        !           362: // Sizer の子コントロールが行っており、そのため WXMainFrame 自身が再描画
        !           363: // しなければならない領域は存在しないからかも知れないが詳細未調査。
        !           364: void
        !           365: WXMainFrame::OnIdle(wxIdleEvent& ev)
1.1       root      366: {
1.1.1.11! root      367:        Fit();
        !           368: 
        !           369:        // UIMessage の処理を開始する。
        !           370:        // 少なくとも WXMainFrame のコンストラクタが完了した後のほうがいいはず。
        !           371:        UIMessage::Attach(&WXUIMessage::Process);
        !           372: 
1.1       root      373:        // ウィンドウを表示
1.1.1.10  root      374:        for (int i = 0; i < subwindow_start.size(); i++) {
                    375:                if (subwindow_start[i]) {
1.1       root      376:                        DoWindow(i, true);
                    377:                }
                    378:        }
                    379: 
1.1.1.9   root      380:        // 電源投入
1.1       root      381:        gVM->PowerButton();
1.1.1.10  root      382: 
                    383:        // 一度処理したら、このイベントを外す
1.1.1.11! root      384:        Disconnect(wxEVT_IDLE, wxIdleEventHandler(WXMainFrame::OnIdle));
1.1       root      385: }
                    386: 
1.1.1.3   root      387: // ウィンドウクローズイベント
                    388: void
                    389: WXMainFrame::OnClose(wxCloseEvent& event)
                    390: {
1.1.1.9   root      391:        // ステータスパネルの更新を停止
                    392:        gStatusPanel->Close();
                    393: 
1.1.1.3   root      394:        // サブウィンドウを全部閉じる
1.1.1.10  root      395:        for (int i = 0; i < ID_SUBWIN_MAX; i++) {
1.1.1.4   root      396:                if ((bool)windows[i]) {
1.1.1.3   root      397:                        windows[i]->Close();
                    398:                }
                    399:        }
                    400: 
                    401:        // VM を解放
1.1.1.4   root      402:        gVM->Dispose();
1.1.1.3   root      403:        gVM.reset();
                    404: 
                    405:        // 後はデフォルト処理
                    406:        event.Skip();
                    407: }
                    408: 
1.1       root      409: // メニューの「高速モード」イベント
                    410: void
                    411: WXMainFrame::OnFullSpeed(wxCommandEvent& event)
                    412: {
                    413:        if (event.IsChecked()) {
                    414:                // チェックが入ったので、高速モードにする
                    415:                gScheduler->SetFullSpeed(true);
                    416:        } else {
                    417:                // チェックが消えたので、通常モードにする
                    418:                gScheduler->SetFullSpeed(false);
                    419:        }
                    420: }
                    421: 
                    422: // メニューの「高速モード」UI
                    423: void
                    424: WXMainFrame::OnFullSpeedUI(wxUpdateUIEvent& event)
                    425: {
                    426:        bool is_fullspeed = gScheduler->GetFullSpeed();
                    427:        event.Check(is_fullspeed);
                    428: }
                    429: 
1.1.1.9   root      430: // メニューの「Restart VM」イベント
1.1.1.6   root      431: void
1.1.1.9   root      432: WXMainFrame::OnRestartVM(wxCommandEvent& event)
1.1.1.6   root      433: {
1.1.1.9   root      434:        gScheduler->RequestRestartVM();
1.1.1.6   root      435: }
                    436: 
1.1       root      437: // メニューの「終了」イベント
                    438: void
                    439: WXMainFrame::OnExit(wxCommandEvent& event)
                    440: {
                    441:        // ウィンドウを閉じる
                    442:        Close();
                    443: }
                    444: 
                    445: // メニューの「表示 > スケール > *」の共通イベント
                    446: void
                    447: WXMainFrame::OnMenuScale(wxCommandEvent& event)
                    448: {
                    449:        double scale;
                    450: 
                    451:        switch (event.GetId()) {
                    452:         default:
                    453:         case ID_SCALE_1_00:
                    454:                scale = 1.0;
                    455:                break;
                    456:         case ID_SCALE_0_75:
                    457:                scale = 0.75;
                    458:                break;
                    459:         case ID_SCALE_0_50:
                    460:                scale = 0.5;
                    461:                break;
                    462:        }
                    463:        gMainView->DoResize(scale);
                    464: 
                    465:        // 再レイアウト
                    466:        Fit();
                    467: }
                    468: 
                    469: // メニューの「表示 > スケール > *」の共通 UI
                    470: void
                    471: WXMainFrame::OnMenuScaleUI(wxUpdateUIEvent& event)
                    472: {
                    473:        double current_scale = gMainView->GetScale();
                    474: 
1.1.1.2   root      475:        if (current_scale == 1.0) {
                    476:                event.Check(event.GetId() == ID_SCALE_1_00);
                    477:        } else if (current_scale == 0.75) {
                    478:                event.Check(event.GetId() == ID_SCALE_0_75);
                    479:        } else if (current_scale == 0.5) {
                    480:                event.Check(event.GetId() == ID_SCALE_0_50);
1.1       root      481:        }
                    482: }
                    483: 
                    484: // メニューの「表示 > フォントサイズ > *」の共通イベント
                    485: void
                    486: WXMainFrame::OnMenuFontSize(wxCommandEvent& event)
                    487: {
1.1.1.5   root      488:        FontId fontid;
1.1       root      489: 
1.1.1.3   root      490:        assertmsg(
1.1.1.4   root      491:                ID_FONTSIZE_12 <= event.GetId() && event.GetId() <= ID_FONTSIZE_16,
1.1.1.3   root      492:                "event.GetId()=%d", event.GetId());
1.1       root      493:        switch (event.GetId()) {
                    494:         case ID_FONTSIZE_12:
1.1.1.5   root      495:                fontid = FontId::_6x12;
1.1       root      496:                break;
                    497:         case ID_FONTSIZE_16:
1.1.1.5   root      498:                fontid = FontId::_8x16;
1.1       root      499:                break;
                    500:         default:
                    501:                __unreachable();
                    502:                break;
                    503:        }
                    504: 
1.1.1.5   root      505:        if (fontid != WXTextPanel::global_fontid) {
                    506:                WXTextPanel::global_fontid = fontid;
1.1       root      507: 
                    508:                // アクティブなサブウィンドウ全員に通知
1.1.1.10  root      509:                for (int i = 0; i < ID_SUBWIN_MAX; i++) {
1.1.1.4   root      510:                        if ((bool)windows[i]) {
                    511:                                WXSubWindow *subwin =
                    512:                                        dynamic_cast<WXSubWindow *>(windows[i].get());
1.1.1.5   root      513:                                subwin->SetFontSize(fontid);
1.1       root      514:                        }
                    515:                }
1.1.1.9   root      516: 
                    517:                // ステータスパネルに通知
                    518:                gStatusPanel->SetFontSize(fontid);
                    519: 
                    520:                // ステータスパネルの大きさが変わるので再レイアウト
                    521:                Fit();
1.1       root      522:        }
                    523: }
                    524: 
                    525: // メニューの「表示 > フォントサイズ > *」共通 UI
                    526: void
                    527: WXMainFrame::OnMenuFontSizeUI(wxUpdateUIEvent& event)
                    528: {
1.1.1.5   root      529:        FontId current_size = WXTextPanel::global_fontid;
                    530:        FontId event_size = (FontId)(event.GetId() - (ID_FONTSIZE_START+1));
1.1       root      531: 
                    532:        event.Check(current_size == event_size);
                    533: }
                    534: 
1.1.1.5   root      535: // 更新頻度 ID -> 数値 (メニューのテキスト、ID と一致させること)
                    536: /*static*/ const int
                    537: WXMainFrame::IDtoMonRate[] = {
                    538:        20,             // ID_MONRATE_20
                    539:        5,              // ID_MONRATE_5
                    540:        1,              // ID_MONRATE_1
                    541: };
                    542: 
                    543: // メニューの「表示 > モニタ更新頻度 > *」の共通イベント
                    544: void
                    545: WXMainFrame::OnMenuMonRate(wxCommandEvent& event)
                    546: {
                    547:        int id = event.GetId();
                    548:        assert(ID_MONRATE_START < id && id < ID_MONRATE_END);
                    549:        monitor_rate = IDtoMonRate[id - (ID_MONRATE_START + 1)];
                    550: 
                    551:        // アクティブなサブウィンドウのテキストパネル全員に通知
1.1.1.10  root      552:        for (int i = 0; i < ID_SUBWIN_MAX; i++) {
1.1.1.5   root      553:                if ((bool)windows[i]) {
                    554:                        auto *subwin = dynamic_cast<WXSubWindow *>(windows[i].get());
                    555:                        for (wxWindow *child : subwin->GetChildren()) {
                    556:                                auto *panel = dynamic_cast<WXTextScreen*>(child);
                    557:                                if (panel) {
                    558:                                        panel->SetRate(monitor_rate);
                    559:                                }
                    560:                        }
                    561:                }
                    562:        }
                    563: }
                    564: 
                    565: // メニューの「表示 > モニタ更新頻度 > *」共通 UI
                    566: void
                    567: WXMainFrame::OnMenuMonRateUI(wxUpdateUIEvent& event)
                    568: {
                    569:        int id = event.GetId();
                    570:        assert(ID_MONRATE_START < id && id < ID_MONRATE_END);
                    571:        int event_rate = IDtoMonRate[id - (ID_MONRATE_START + 1)];
                    572: 
                    573:        event.Check(monitor_rate == event_rate);
                    574: }
                    575: 
1.1.1.9   root      576: // メニューの「表示 > ステータスパネルを表示」
                    577: void
                    578: WXMainFrame::OnShowStatusPanel(wxCommandEvent& event)
                    579: {
                    580:        // enable ならチェックを付けようとして呼ばれた
                    581:        bool enable = event.IsChecked();
                    582: 
                    583:        gStatusPanel->Show(enable);
                    584: 
                    585:        // 再レイアウト
                    586:        Fit();
                    587: }
                    588: 
                    589: // メニューの「表示 > ステータスパネルを表示」UI
                    590: void
                    591: WXMainFrame::OnShowStatusPanelUI(wxUpdateUIEvent& event)
                    592: {
                    593:        event.Check(gStatusPanel->IsShown());
                    594: }
                    595: 
1.1.1.11! root      596: // メニューの「デバイス > CD/MO > 挿入」
        !           597: void
        !           598: WXMainFrame::OnCDInsert(wxCommandEvent& event)
        !           599: {
        !           600:        std::string title;
        !           601:        std::string wildcard;
        !           602: 
        !           603:        int id = event.GetId() - ID_CD_INSERT_0;
        !           604:        const auto *dev = scsidev[id];
        !           605:        assert(dev);
        !           606: 
        !           607:        switch (dev->GetDevType()) {
        !           608:         case SCSI::DevType::CD:
        !           609:                title = _("Open a CD image");
        !           610:                wildcard = "ISO images (*.iso;*.img)|*.iso;*.img;*.ISO;*.IMG";
        !           611:                break;
        !           612:         case SCSI::DevType::MO:
        !           613:                title = _("Open an MO image");
        !           614:                wildcard = "MO images (*.img;*.mos)|*.img;*.mos;*.IMG;*.MOS";
        !           615:                break;
        !           616:         default:
        !           617:                __unreachable();
        !           618:        }
        !           619:        wildcard += "|All files (*.*)|*.*";
        !           620: 
        !           621:        // ディレクトリは、まだ一度も使ってなければ VM ディレクトリにする
        !           622:        if (current_dir.empty()) {
        !           623:                current_dir = gMainApp.GetVMDir();
        !           624:        }
        !           625: 
        !           626:        wxFileDialog dialog(this, title, current_dir, "", wildcard,
        !           627:                wxFD_OPEN | wxFD_FILE_MUST_EXIST);
        !           628:        if (dialog.ShowModal() == wxID_CANCEL) {
        !           629:                return;
        !           630:        }
        !           631:        auto path = std::string(dialog.GetPath());
        !           632:        InsertCD(id, path);
        !           633: }
        !           634: 
        !           635: // メニューの「デバイス > CD/MO > 挿入」UI
        !           636: void
        !           637: WXMainFrame::OnCDInsertUI(wxUpdateUIEvent& event)
        !           638: {
        !           639:        int id = event.GetId() - ID_CD_INSERT_0;
        !           640:        SCSIDisk *disk = dynamic_cast<SCSIDisk *>(scsidev[id]);
        !           641:        assert(disk);
        !           642: 
        !           643:        if (disk->IsMediumLoaded()) {
        !           644:                event.SetText(_("Ex&change"));
        !           645:        } else {
        !           646:                event.SetText(_("&Insert"));
        !           647:        }
        !           648: }
        !           649: 
        !           650: // メニューの「デバイス > CD/MO > 取り出し」
        !           651: void
        !           652: WXMainFrame::OnCDEject(wxCommandEvent& event)
        !           653: {
        !           654:        int id = event.GetId() - ID_CD_EJECT_0;
        !           655: 
        !           656:        EjectCD(id, false);
        !           657: }
        !           658: 
        !           659: // メニューの「デバイス > CD/MO > 取り出し」UI
        !           660: void
        !           661: WXMainFrame::OnCDEjectUI(wxUpdateUIEvent& event)
        !           662: {
        !           663:        int id = event.GetId() - ID_CD_EJECT_0;
        !           664:        SCSIDisk *disk = dynamic_cast<SCSIDisk *>(scsidev[id]);
        !           665:        assert(disk);
        !           666: 
        !           667:        // 挿入されてて取り出し可能な時のみ有効
        !           668:        event.Enable(disk->IsMediumLoaded() &&
        !           669:                     disk->IsMediumRemovalAllowed());
        !           670: }
        !           671: 
        !           672: // メニューの「デバイス > CD/MO > 強制取り出し」
        !           673: void
        !           674: WXMainFrame::OnCDForce(wxCommandEvent& event)
        !           675: {
        !           676:        int id = event.GetId() - ID_CD_FORCE_0;
        !           677: 
        !           678:        EjectCD(id, true);
        !           679: }
        !           680: 
        !           681: // メニューの「デバイス > CD/MO > 強制取り出し」UI
        !           682: void
        !           683: WXMainFrame::OnCDForceUI(wxUpdateUIEvent& event)
        !           684: {
        !           685:        int id = event.GetId() - ID_CD_FORCE_0;
        !           686:        SCSIDisk *disk = dynamic_cast<SCSIDisk *>(scsidev[id]);
        !           687:        assert(disk);
        !           688: 
        !           689:        // 挿入されてて取り出し禁止の時のみ有効
        !           690:        event.Enable(disk->IsMediumLoaded() &&
        !           691:                     disk->IsMediumRemovalPrevented());
        !           692: }
        !           693: 
1.1.1.2   root      694: // メニューの「デバイス > マウスモード」
                    695: void
                    696: WXMainFrame::OnMouseMode(wxCommandEvent& event)
                    697: {
                    698:        // enable ならチェックを付けようとして呼ばれた
                    699:        bool enable = event.IsChecked();
                    700: 
                    701:        if (enable) {
                    702:                // メッセージを表示したい
                    703:        } else {
                    704:                // メッセージを表示したい
                    705:        }
                    706: 
                    707:        // マウスモードを設定
                    708:        gMainView->SetMouseMode(enable);
                    709: }
                    710: 
                    711: // メニューの「デバイス > マウスモード」UI
                    712: void
                    713: WXMainFrame::OnMouseModeUI(wxUpdateUIEvent& event)
                    714: {
                    715:        event.Check(gMainView->GetMouseMode());
                    716: }
                    717: 
1.1.1.9   root      718: // メニューの「デバイス > Push Reset Button」イベント
                    719: // こっちは本体リセットボタンによるリセット
                    720: void
                    721: WXMainFrame::OnResetButton(wxCommandEvent& event)
                    722: {
                    723:        gScheduler->RequestResetHard();
                    724: }
                    725: 
1.1       root      726: // メニューのウィンドウ ID 共通イベント
                    727: // チェックが入る方なら、ウィンドウを作成して表示。
                    728: // チェックが消える方なら、ウィンドウを削除。
                    729: void
                    730: WXMainFrame::OnWindow(wxCommandEvent& event)
                    731: {
                    732:        int id = event.GetId();
                    733: 
                    734:        DoWindow(id, event.IsChecked());
                    735: }
                    736: 
                    737: void
                    738: WXMainFrame::DoWindow(int id, bool enable)
                    739: {
1.1.1.10  root      740:        // モニタウィンドウを作成する共通部分。
                    741:        // id はモニター ID であると同時に、windows[] 配列の添字、さらにこの
                    742:        // モニタウィンドウの wxWindowID としても使っている
                    743:        // (WXSubWindow::OnClose() 参照)。
                    744: #define SetMonitor(id, name)   \
                    745:        windows[id].reset(new WXMonitorWindow(this, (name), \
                    746:                gMonitorManager.Get(id)))
1.1.1.4   root      747: 
1.1       root      748:        if (enable) {
                    749:                // チェックが入ったのでウィンドウを作成
                    750:                switch (id) {
1.1.1.10  root      751:                 case ID_MONITOR_ATC0:
                    752:                 case ID_MONITOR_ATC1:
                    753:                 case ID_MONITOR_ATC2:
                    754:                 case ID_MONITOR_ATC3:
                    755:                 case ID_MONITOR_ATC4:
                    756:                 case ID_MONITOR_ATC5:
                    757:                 case ID_MONITOR_ATC6:
                    758:                 case ID_MONITOR_ATC7:
                    759:                 {
                    760:                        int n = id - ID_MONITOR_ATC0;
                    761:                        wxString name(string_format("ATC#%d", n));
                    762:                        if ((n & 1) == 0) {
                    763:                                name += _("(Data)");
                    764:                        } else {
                    765:                                name += _("(Inst)");
                    766:                        }
                    767:                        SetMonitor(id, name);
1.1.1.4   root      768:                        break;
1.1.1.10  root      769:                 }
                    770: 
                    771:                 case ID_MONITOR_BREAKPOINT:
                    772:                        SetMonitor(id, _("Breakpoint"));
1.1.1.5   root      773:                        break;
1.1.1.10  root      774: 
                    775:                 case ID_MONITOR_CMMU0:
                    776:                 case ID_MONITOR_CMMU1:
                    777:                 case ID_MONITOR_CMMU2:
                    778:                 case ID_MONITOR_CMMU3:
                    779:                 case ID_MONITOR_CMMU4:
                    780:                 case ID_MONITOR_CMMU5:
                    781:                 case ID_MONITOR_CMMU6:
                    782:                 case ID_MONITOR_CMMU7:
                    783:                 {
                    784:                        int n = id - ID_MONITOR_CMMU0;
                    785:                        wxString name(string_format("CMMU#%d", n));
                    786:                        if ((n & 1) == 0) {
                    787:                                name += _("(Data)");
                    788:                        } else {
                    789:                                name += _("(Inst)");
                    790:                        }
                    791:                        SetMonitor(id, name);
1.1.1.4   root      792:                        break;
1.1.1.10  root      793:                 }
                    794: 
                    795:                 case ID_MONITOR_DMAC:
                    796:                        SetMonitor(id, "DMAC");
1.1.1.5   root      797:                        break;
1.1.1.10  root      798: 
                    799:                 case ID_MONITOR_INTERRUPT:
                    800:                        SetMonitor(id, _("Interrupt"));
1.1.1.5   root      801:                        break;
1.1.1.10  root      802: 
                    803:                 case ID_MONITOR_KEYBOARD:
                    804:                        SetMonitor(id, _("Keyboard/Mouse"));
1.1.1.4   root      805:                        break;
1.1.1.10  root      806: 
                    807:                 case ID_MONITOR_LANCE:
                    808:                        SetMonitor(id, "LANCE");
1.1       root      809:                        break;
1.1.1.10  root      810: 
                    811:                 case ID_MONITOR_LCD:
                    812:                        windows[id].reset(new WXLCDMonitor(this));
1.1.1.4   root      813:                        break;
1.1.1.10  root      814: 
                    815:                 case ID_MONITOR_LUNAFB:
                    816:                        SetMonitor(id, _("Bitmap Control"));
1.1.1.4   root      817:                        break;
1.1.1.10  root      818: 
                    819:                 case ID_MONITOR_MEMDUMP0 ...
                    820:                     (ID_MONITOR_MEMDUMP0 + MAX_MEMDUMP_MONITOR - 1):
                    821:                 {
                    822:                        int n = id - ID_MONITOR_MEMDUMP0;
                    823:                        windows[id].reset(new WXMemdumpWindow(this, n));
1.1.1.4   root      824:                        break;
1.1.1.10  root      825:                 }
                    826: 
                    827:                 case ID_MONITOR_MFP:
                    828:                        SetMonitor(id, "MFP");
1.1.1.4   root      829:                        break;
1.1.1.10  root      830: 
                    831:                 case ID_MONITOR_MK48T02:
                    832:                        SetMonitor(id, "MK48T02");
1.1       root      833:                        break;
1.1.1.10  root      834: 
                    835:                 case ID_MONITOR_MPUATC:
                    836:                        SetMonitor(id, _("MPU (ATC)"));
1.1       root      837:                        break;
1.1.1.10  root      838: 
                    839:                 case ID_MONITOR_MPUREG:
                    840:                        SetMonitor(id, _("MPU (Register)"));
1.1.1.7   root      841:                        break;
1.1.1.10  root      842: 
                    843:                 case ID_MONITOR_HOSTNET:
                    844:                        SetMonitor(id, _("Host Network"));
1.1       root      845:                        break;
1.1.1.10  root      846: 
                    847:                 case ID_MONITOR_PIO0:
                    848:                        SetMonitor(id, "PIO");
1.1.1.3   root      849:                        break;
1.1.1.10  root      850: 
                    851:                 case ID_MONITOR_RTC:
                    852:                        SetMonitor(id, "RTC");
1.1.1.3   root      853:                        break;
1.1.1.10  root      854: 
                    855:                 case ID_MONITOR_SCC:
                    856:                        SetMonitor(id, "SCC");
1.1.1.3   root      857:                        break;
1.1.1.10  root      858: 
                    859:                 case ID_MONITOR_SCHEDULER:
                    860:                        SetMonitor(id, _("Scheduler"));
1.1       root      861:                        break;
1.1.1.10  root      862: 
1.1.1.11! root      863:                 case ID_MONITOR_SCSIDEVS:
        !           864:                        SetMonitor(id, _("SCSI Devices"));
        !           865:                        break;
        !           866: 
1.1.1.10  root      867:                 case ID_MONITOR_SIO:
                    868:                        SetMonitor(id, "SIO");
1.1.1.4   root      869:                        break;
1.1.1.10  root      870: 
                    871:                 case ID_MONITOR_SPC:
                    872:                        SetMonitor(id, "SPC");
1.1.1.2   root      873:                        break;
1.1.1.10  root      874: 
                    875:                 case ID_MONITOR_SYSCLK:
                    876:                        SetMonitor(id, _("System Clock"));
1.1       root      877:                        break;
1.1.1.10  root      878: 
                    879:                 case ID_MONITOR_WXHOSTINFO:
                    880:                        SetMonitor(id, _("Host Information"));
1.1       root      881:                        break;
1.1.1.10  root      882: 
                    883:                 case ID_SUBWIN_BRHIST:
                    884:                        windows[id].reset(new WXBranchHistoryMonitor(this,
                    885:                                gMonitorManager.Get(id)));
1.1.1.4   root      886:                        break;
1.1.1.10  root      887: 
                    888:                 case ID_SUBWIN_EXHIST:
                    889:                        windows[id].reset(new WXExceptionHistoryMonitor(this,
                    890:                                gMonitorManager.Get(id)));
1.1.1.5   root      891:                        break;
1.1.1.10  root      892: 
                    893:                 case ID_SUBWIN_CACHE0:
                    894:                 case ID_SUBWIN_CACHE1:
                    895:                 case ID_SUBWIN_CACHE2:
                    896:                 case ID_SUBWIN_CACHE3:
                    897:                 case ID_SUBWIN_CACHE4:
                    898:                 case ID_SUBWIN_CACHE5:
                    899:                 case ID_SUBWIN_CACHE6:
                    900:                 case ID_SUBWIN_CACHE7:
                    901:                 {
                    902:                        int n = id - ID_SUBWIN_CACHE0;
                    903:                        wxString name = _("Cache");
                    904:                        name += string_format("#%d", n);
                    905:                        if ((n & 1) == 0) {
                    906:                                name += _("(Data)");
                    907:                        } else {
                    908:                                name += _("(Inst)");
                    909:                        }
                    910:                        windows[id].reset(new WXCacheWindow(this, name,
                    911:                                gMonitorManager.Get(id)));
1.1       root      912:                        break;
1.1.1.10  root      913:                 }
                    914: 
                    915:                 case ID_SUBWIN_LCDPANEL:
                    916:                        windows[id].reset(new WXLCDWindow(this));
1.1       root      917:                        break;
1.1.1.10  root      918:                 case ID_SUBWIN_LOG:
                    919:                        windows[id].reset(new WXLogMonitor(this));
1.1       root      920:                        break;
1.1.1.10  root      921:                 case ID_SUBWIN_LUNAFB0:
                    922:                        windows[id].reset(new WXLunaBitmapWindow(this, _("Bitmap #0")));
1.1       root      923:                        break;
1.1.1.10  root      924: 
                    925:                 case ID_SUBWIN_SOFTKEY:
                    926:                        windows[id].reset(new WXSoftKeyWindow(this, gMainApp.GetVMType()));
1.1.1.5   root      927:                        break;
1.1.1.10  root      928: 
                    929:                 default:
                    930:                        assert(false);
1.1       root      931:                }
                    932:                windows[id]->Show();
                    933:        } else {
                    934:                // チェックが消えたのでウィンドウを終了
                    935:                windows[id]->Close();
                    936:                // (削除自体はこの少し下の DeleteWindow() で行なっている)
                    937:        }
                    938: }
                    939: 
                    940: // Update UI イベント
                    941: void
                    942: WXMainFrame::OnWindowUI(wxUpdateUIEvent& event)
                    943: {
                    944:        int id = event.GetId();
                    945: 
                    946:        // ウィンドウが存在していればチェックを表示
1.1.1.4   root      947:        event.Check((bool)windows[id]);
1.1.1.10  root      948: 
                    949:        if (IS_MONITOR_MEMDUMP(id)) {
                    950:                // メニューに現在のアドレスを載せる
                    951:                int n = id - ID_MONITOR_MEMDUMP0;
                    952:                event.SetText(string_format("%d: $%08x", n,
                    953:                        WXMemdumpWindow::GetStickyAddr(id)));
                    954:        }
1.1.1.4   root      955: }
                    956: 
                    957: // バージョンダイアログ
                    958: void
                    959: WXMainFrame::OnAbout(wxCommandEvent& event)
                    960: {
                    961:        WXVersionDlg dlg(this);
                    962:        dlg.ShowModal();
1.1       root      963: }
                    964: 
1.1.1.11! root      965: // CD/MO を挿入する。
1.1       root      966: void
1.1.1.11! root      967: WXMainFrame::InsertCD(int id, const std::string& path)
1.1       root      968: {
1.1.1.11! root      969:        SCSIDisk *scsidisk = dynamic_cast<SCSIDisk*>(scsidev[id]);
        !           970:        assert(scsidisk);
1.1       root      971: 
1.1.1.11! root      972:        // VM に依頼
        !           973:        // (エラーが起きれば別途 UI メッセージが飛んでくる)
        !           974:        scsidisk->LoadDiskUI(path);
        !           975: 
        !           976:        // 次回以降のダイアログのカレントディレクトリをここに更新
        !           977:        auto pos = path.rfind('/');
        !           978:        current_dir = path.substr(0, pos);
1.1       root      979: }
                    980: 
1.1.1.11! root      981: // CD/MO をイジェクトする。
1.1       root      982: void
1.1.1.11! root      983: WXMainFrame::EjectCD(int id, bool force)
1.1       root      984: {
1.1.1.11! root      985:        SCSIDisk *scsidisk = dynamic_cast<SCSIDisk*>(scsidev[id]);
        !           986:        assert(scsidisk);
        !           987: 
        !           988:        scsidisk->UnloadDisk(force);
1.1       root      989: }
                    990: 
1.1.1.11! root      991: // CD/MO の挿入失敗メッセージ
1.1.1.4   root      992: void
1.1.1.11! root      993: WXMainFrame::OnInsertCDFailed(wxCommandEvent& event)
1.1.1.4   root      994: {
1.1.1.11! root      995:        ::wxMessageBox(_("Cannot load the image file"));
1.1.1.4   root      996: }
                    997: 
1.1.1.11! root      998: // ウィンドウをリストから削除する
        !           999: // (ウィンドウの Close() から呼ばれる)
1.1.1.4   root     1000: void
1.1.1.11! root     1001: WXMainFrame::DeleteWindow(wxWindow *win)
1.1.1.4   root     1002: {
1.1.1.11! root     1003:        for (int id = 0; id < ID_SUBWIN_MAX; id++) {
        !          1004:                if (windows[id].get() == win) {
        !          1005:                        windows[id].reset();
        !          1006:                        break;
        !          1007:                }
        !          1008:        }
1.1.1.4   root     1009: }
                   1010: 
                   1011: // m680x0 ダブルバスフォールト処理
                   1012: void
                   1013: WXMainFrame::OnHaltNotify(wxCommandEvent& event)
                   1014: {
                   1015:        ::wxMessageBox(_("Double bus fault has occurred in VM"),
                   1016:                wxEmptyString,
                   1017:                wxICON_EXCLAMATION);
                   1018: }
                   1019: 
1.1.1.10  root     1020: // 起動時にオープンするサブウィンドウ (-M オプション)
                   1021: /*static*/ std::array<bool, ID_SUBWIN_MAX> WXMainFrame::subwindow_start;

unix.superglobalmegacorp.com

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