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

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

unix.superglobalmegacorp.com

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