--- nono/wx/wxapp.cpp 2026/04/29 17:04:33 1.1.1.2 +++ nono/wx/wxapp.cpp 2026/04/29 17:04:53 1.1.1.7 @@ -1,78 +1,122 @@ // // nono -// Copyright (C) 2018 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // -#include "vm.h" -#include "wxheader.h" #include "wxmainframe.h" #include "wxmainview.h" #include "wxtextpanel.h" +#include "wxversion.h" #include "mainapp.h" +#include "mpu680x0.h" +#include "mpu88xx0.h" +#include "scheduler.h" +#include // イベントタイプの定義 -DEFINE_EVENT_TYPE(WXW_EVT_CREATE); -DEFINE_EVENT_TYPE(WXW_EVT_MONITOR_UPDATE); +wxDEFINE_EVENT(WXW_EVT_CREATE, wxCommandEvent); +wxDEFINE_EVENT(WXW_EVT_HALT_NOTIFY, wxCommandEvent); class WXApp : public wxApp { + using inherited = wxApp; public: bool OnInit(); + int OnRun() override; private: bool ParseMonitors(const wxString& str); int SearchMonitorName(const char *name); + + wxLocale locale; }; +// IMPLEMENT_APP() は闇マクロすぎて clang のちからには耐えられない +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Weverything" +#endif IMPLEMENT_APP(WXApp) +#if defined(__clang__) +#pragma clang diagnostic pop +#endif bool WXApp::OnInit() { - if (!gMainApp.Init(false, argc, argv)) { - return false; + return true; +} + +int +WXApp::OnRun() +{ + int rv; + + rv = gMainApp.Init1(false, argc, argv); + if (rv != MainApp::PASS) { + return rv; + } + + // 環境変数 $NONO_BUILD_HOME が定義されていればカタログ検索パスに + // $NONO_BUILD_HOME/po を追加する (システムパスより前に挿入される)。 + // カタログ開発時にワークツリーにあるカタログを見るため。 + locale.Init(wxLANGUAGE_DEFAULT); + const char *build_home = getenv("NONO_BUILD_HOME"); + if (build_home) { + wxString path(build_home); + path += "/po"; + wxLocale::AddCatalogLookupPathPrefix(path); } + locale.AddCatalog("nono"); // --fontsize テキスト系コントロールのフォントサイズ // 紛らわしいが ::global_fontsize は 12, 16 とかいう値。 - // WXTextPanel::global_fontsize (fontsize_t) は enum 値。 - fontsize_t fontsize; + // WXTextPanel::global_fontsize (FontId) は enum 値。 + FontId fontid; switch (gMainApp.fontsize) { case 12: - fontsize = FONT_6x12; + fontid = FontId::_6x12; break; case 16: - fontsize = FONT_8x16; - break; - case 24: - fontsize = FONT_12x24; + fontid = FontId::_8x16; break; default: warnx("invalid fontsize: %d", gMainApp.fontsize); - return false; + return EXIT_FAILURE; } - WXTextPanel::global_fontsize = fontsize; + WXTextPanel::global_fontid = fontid; + + // グローバルオブジェクト (どこでやるのがいいか) + gHostInfo.reset(new HostInfoMonitor()); // -M 起動時に表示するモニタ if (!gMainApp.monitor_opt.empty()) { if (!ParseMonitors(gMainApp.monitor_opt)) { - return false; + return EXIT_FAILURE; } } // -s screen scale WXMainView::screen_scale = gMainApp.screen_scale; - // 引数処理が終わったので VM 開始。 - if (!gMainApp.Start()) { - return false; + // 引数処理が終わったので、スレッド作成を伴う初期化。 + if (!gMainApp.Init2()) { + return EXIT_FAILURE; + } + + // VM にコールバックを登録 + gScheduler->SetPowerOffCallback(wxmainframe_poweroff_callback); + if (gMPU680x0) { + gMPU680x0->SetHaltCallback(wxmainframe_halt_callback, this); } // メインウィンドウ gMainFrame = new WXMainFrame(NULL); gMainFrame->Show(true); SetTopWindow(gMainFrame); - return true; + + return inherited::OnRun(); } // -M オプションの解析。書式は @@ -82,27 +126,28 @@ WXApp::OnInit() bool WXApp::ParseMonitors(const wxString& str) { - const char *sep = ","; - char *word; - char *last; - char buf[str.Length() + 1]; + int s; + int end; - if (str == wxT("help")) { + if (str == "help") { for (int i = 0; i < WinID_MAX; i++) { - fprintf(stderr, " %s\n", WXMainFrame::monitor_names[i]); + auto& info = WXMainFrame::monitor_info[i]; + if (gMainApp.HasVMFeature(info.feature)) { + fprintf(stderr, " %s\n", info.name); + } } return false; } - // 由緒正しい C でパースしてしまう - strcpy(buf, (const char *)str.mb_str()); - for (word = strtok_r(buf, sep, &last); - word; - word = strtok_r(NULL, sep, &last)) - { + for (s = 0, end = 0; s < str.Length(); s = end + 1) { + end = str.find(',', s); + if (end == wxString::npos) { + end = str.size(); + } + wxString word = str.SubString(s, end - 1); int i = SearchMonitorName(word); if (i < 0) { - warnx("Unknown window name \"%s\"", word); + warnx("Unknown window name \"%s\"", (const char *)word.mb_str()); return false; } WXMainFrame::monitor_start[i] = true; @@ -114,7 +159,10 @@ int WXApp::SearchMonitorName(const char *name) { for (int i = 0; i < WinID_MAX; i++) { - if (strcmp(name, WXMainFrame::monitor_names[i]) == 0) { + auto& info = WXMainFrame::monitor_info[i]; + if (gMainApp.HasVMFeature(info.feature) && + strcmp(name, info.name) == 0) + { return i; } }