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

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