Annotation of nono/wx/wxdumpmonitor.cpp, revision 1.1.1.15

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.11  root        7: //
                      8: // メモリダンプウィンドウ
                      9: //
                     10: 
1.1       root       11: #include "wxdumpmonitor.h"
1.1.1.13  root       12: #include "mainapp.h"
                     13: #include "mainbus.h"
1.1.1.15! root       14: #include "monitor.h"
        !            15: #include "mpu680x0.h"
1.1       root       16: 
                     17: enum {
1.1.1.11  root       18:        ID_TEXT = IDGROUP_MEMDUMP,
1.1.1.13  root       19:        ID_PREVLINE,
                     20:        ID_PREVPAGE,
                     21:        ID_NEXTLINE,
                     22:        ID_NEXTPAGE,
                     23:        ID_FORMAT,
                     24: 
                     25:        ID_EDIT,
1.1.1.11  root       26: 
                     27:        ID_local_end,   // 最後に置く (チェック用)
1.1       root       28: };
1.1.1.12  root       29: static_assert(ID_local_end - 1 <= (int)IDGROUP_MEMDUMP_END, "ID exceeded");
1.1       root       30: 
                     31: // イベントテーブル
                     32: wxBEGIN_EVENT_TABLE(WXMemdumpWindow, inherited)
                     33:        EVT_TEXT_ENTER(ID_TEXT, WXMemdumpWindow::OnTextEnter)
1.1.1.13  root       34:        EVT_COMMAND(ID_PREVLINE, NONO_EVT_BUTTON, WXMemdumpWindow::OnPrevLine)
                     35:        EVT_COMMAND(ID_PREVPAGE, NONO_EVT_BUTTON, WXMemdumpWindow::OnPrevPage)
                     36:        EVT_COMMAND(ID_NEXTLINE, NONO_EVT_BUTTON, WXMemdumpWindow::OnNextLine)
                     37:        EVT_COMMAND(ID_NEXTPAGE, NONO_EVT_BUTTON, WXMemdumpWindow::OnNextPage)
                     38:        EVT_CHOICE(ID_FORMAT, WXMemdumpWindow::OnFormat)
1.1       root       39: wxEND_EVENT_TABLE()
                     40: 
                     41: // コンストラクタ
1.1.1.9   root       42: // (タイトルは UpdateAddr() でセットする)
1.1.1.13  root       43: WXMemdumpWindow::WXMemdumpWindow(wxWindow *parent, int monid_)
1.1.1.12  root       44:        : inherited(parent, wxID_ANY, wxEmptyString,
                     45:                DEFAULT_STYLE | wxRESIZE_BORDER)
1.1       root       46: {
1.1.1.13  root       47:        monid = monid_;
                     48:        if (IS_MONITOR_XPMEMDUMP(monid)) {
                     49:                myidx = monid - ID_MONITOR_XPMEMDUMP0;
                     50:        } else {
                     51:                myidx = monid - ID_MONITOR_MEMDUMP0;
                     52:        }
                     53: 
                     54:        // ↓ topsizer
                     55:        //   +--------------------------------------------+
                     56:        //   |上枠 →                                     |
                     57:        //   |+-----+------+-----+----------+-----+------+|
                     58:        //   ||余白 | "<<" | "<" | アドレス | ">" | ">>" ||
                     59:        //   |+-----+------+-----+----------+-----+------+|
                     60:        //   +--------------------------------------------+
                     61:        //   | TextScreen                                 |
                     62:        //   +--------------------------------------------+
1.1.1.11  root       63: 
                     64:        auto *topsizer = new wxBoxSizer(wxVERTICAL);
1.1.1.5   root       65: 
1.1.1.9   root       66:        // 上枠用の下敷きパネル
1.1.1.13  root       67:        auto *ctrlpanel = new wxPanel(this);
1.1.1.15! root       68:        ctrlpanel->SetName("WXMemdumpWindow.CtrlPanel");
1.1.1.11  root       69:        topsizer->Add(ctrlpanel, 0, wxEXPAND);
1.1.1.9   root       70: 
1.1.1.5   root       71:        // 上枠用の横 sizer
                     72:        ctrlbox = new wxBoxSizer(wxHORIZONTAL);
1.1       root       73: 
                     74:        // アドレスコントロール
1.1.1.13  root       75:        addrctrl = new wxTextCtrl(ctrlpanel, ID_TEXT,
1.1       root       76:                wxEmptyString, wxDefaultPosition, wxDefaultSize,
                     77:                wxTE_PROCESS_ENTER);
1.1.1.13  root       78:        buttons[0] = new WXButton(ctrlpanel, ID_PREVPAGE, wxDefaultSize, "<<");
                     79:        buttons[1] = new WXButton(ctrlpanel, ID_PREVLINE, wxDefaultSize, "<");
                     80:        buttons[2] = new WXButton(ctrlpanel, ID_NEXTLINE, wxDefaultSize, ">");
                     81:        buttons[3] = new WXButton(ctrlpanel, ID_NEXTPAGE, wxDefaultSize, ">>");
                     82: 
                     83:        ctrlbox->AddSpacer(3);
                     84:        ctrlbox->Add(buttons[0], 0, wxALIGN_CENTER);
                     85:        ctrlbox->Add(buttons[1], 0, wxALIGN_CENTER);
                     86:        ctrlbox->AddSpacer(3);
                     87:        ctrlbox->Add(addrctrl, 0, wxALIGN_CENTER);
                     88:        ctrlbox->AddSpacer(3);
                     89:        ctrlbox->Add(buttons[2], 0, wxALIGN_CENTER);
                     90:        ctrlbox->Add(buttons[3], 0, wxALIGN_CENTER);
                     91:        ctrlbox->AddSpacer(3);
                     92: 
                     93:        // 表示形式 (機種によって選択肢と名前が異なる)
                     94:        if (gMainApp.Has(VMCap::M68K)) {
1.1.1.15! root       95:                auto mpu680x0 = GetMPU680x0Device(GetMPUDevice());
1.1.1.13  root       96:                fmts.emplace_back(Memdump::Byte, _("Byte"));
                     97:                fmts.emplace_back(Memdump::Word, _("Word"));
                     98:                fmts.emplace_back(Memdump::Long, _("Long Word"));
1.1.1.15! root       99:                switch (mpu680x0->GetMPUType()) {
        !           100:                 case m680x0MPUType::M68030:
        !           101:                        fmts.emplace_back(Memdump::M68030PageShort,
        !           102:                                _("MMU Descriptor (Short Format)"));
        !           103:                        break;
        !           104:                 case m680x0MPUType::M68040:
        !           105:                        fmts.emplace_back(Memdump::M68040TableDesc,
        !           106:                                _("MMU Table Descriptor"));
        !           107:                        fmts.emplace_back(Memdump::M68040PageDesc,
        !           108:                                _("MMU Page Descriptor"));
        !           109:                        break;
        !           110:                 default:
        !           111:                        break;
        !           112:                }
        !           113:                fmts.emplace_back(Memdump::M680x0Disasm, _("680x0 Disassemble"));
1.1.1.13  root      114:        } else {
                    115:                fmts.emplace_back(Memdump::Byte, _("Byte"));
                    116:                fmts.emplace_back(Memdump::Word, _("Half Word"));
                    117:                fmts.emplace_back(Memdump::Long, _("Word"));
                    118:                fmts.emplace_back(Memdump::M88200Page, _("88200 Descriptor"));
                    119:                fmts.emplace_back(Memdump::M88100Disasm, _("88100 Disassemble"));
                    120:        }
                    121:        if (gMainApp.Has(VMCap::LUNA)) {
                    122:                fmts.emplace_back(Memdump::HD64180Disasm, _("HD64180 Disassemble"));
                    123:        }
                    124: 
                    125:        // fmts から名前だけの配列を作る
                    126:        std::vector<wxString> fmt_choice;
                    127:        for (auto p : fmts) {
                    128:                fmt_choice.push_back(p.second);
                    129:        }
                    130:        fmtctrl = new wxChoice(ctrlpanel, ID_FORMAT,
                    131:                wxDefaultPosition, wxDefaultSize,
                    132:                fmt_choice.size(), &fmt_choice[0]);
                    133:        ctrlbox->Add(fmtctrl, 0, wxALIGN_CENTER);
1.1       root      134: 
1.1.1.9   root      135:        // 上枠の sizer と下敷きを紐付ける
                    136:        ctrlpanel->SetSizer(ctrlbox);
                    137:        ctrlbox->SetSizeHints(ctrlpanel);
                    138: 
1.1.1.13  root      139:        screen = new WXMonitorPanel(this, gMonitorManager->Get(monid));
1.1.1.11  root      140:        topsizer->Add(screen, 1, wxEXPAND);
1.1       root      141: 
1.1.1.4   root      142:        SetSizer(topsizer);
1.1       root      143: 
1.1.1.11  root      144:        // ウィンドウサイズを確定させる
                    145:        fixed_height = ctrlbox->GetSize().y;
1.1.1.13  root      146:        FontChanged();
1.1.1.11  root      147:        DoSize();
                    148: 
1.1.1.13  root      149:        // パネルに来るマウスイベントをこっちに回す
                    150:        screen->Connect(wxEVT_MOUSEWHEEL,
                    151:                wxMouseEventHandler(WXMemdumpWindow::OnMouseWheel), NULL, this);
                    152:        screen->Connect(wxEVT_LEFT_DCLICK,
                    153:                wxMouseEventHandler(WXMemdumpWindow::OnDClick), NULL, this);
                    154: 
                    155:        // メモリダンプオブジェクトを取得
                    156:        auto mon = screen->GetMonitor();
1.1.1.15! root      157:        memdump = dynamic_cast<MemdumpMonitor *>(mon->obj);
1.1.1.13  root      158:        assert(memdump);
                    159: 
                    160:        // 初期値をコントロールに設定
                    161:        auto fmt = memdump->GetFormat();
                    162:        fmtctrl->SetSelection(Format2Selection(fmt));
                    163:        DoFormat(fmt);
1.1.1.9   root      164:        UpdateAddr();
1.1       root      165: }
                    166: 
                    167: // デストラクタ
                    168: WXMemdumpWindow::~WXMemdumpWindow()
                    169: {
                    170: }
                    171: 
1.1.1.12  root      172: bool
                    173: WXMemdumpWindow::Layout()
                    174: {
                    175:        // 縦リサイズ可能レイアウト
                    176:        return LayoutTextVResize(screen, fixed_height);
                    177: }
                    178: 
1.1.1.13  root      179: void
                    180: WXMemdumpWindow::FontChanged()
                    181: {
                    182:        inherited::FontChanged();
                    183: 
                    184:        // 最小 24x24 にしてみる
                    185:        wxSize sz(screen->GetFontWidth() * 2 + 4,
                    186:                      screen->GetFontHeight() + 4);
                    187:        if (sz.x < 24)
                    188:                sz.x = 24;
                    189:        if (sz.y < 24)
                    190:                sz.y = 24;
                    191:        for (auto *btn : buttons) {
                    192:                btn->SetClientSize(sz);
                    193:                btn->SetMinClientSize(sz);
                    194:                btn->FontChanged();
                    195:        }
                    196: }
                    197: 
1.1       root      198: // テキスト入力イベント
                    199: void
                    200: WXMemdumpWindow::OnTextEnter(wxCommandEvent& event)
                    201: {
                    202:        // 入力文字列(16進文字列)を数値に変換
1.1.1.5   root      203:        const wxString& wstr = event.GetString();
1.1.1.6   root      204:        uint32 val = strtoul((const char *)wstr.mb_str(), NULL, 16);
1.1       root      205: 
1.1.1.9   root      206:        // アドレスを更新
1.1.1.13  root      207:        memdump->SetAddr(val);
1.1.1.9   root      208:        UpdateAddr();
1.1       root      209: }
                    210: 
1.1.1.13  root      211: // "<"(前行) ボタン押下イベント
1.1       root      212: void
1.1.1.13  root      213: WXMemdumpWindow::OnPrevLine(wxCommandEvent& event)
1.1       root      214: {
1.1.1.13  root      215:        // 1行戻る
                    216:        memdump->Offset(memdump->GetLineOffset(-1));
1.1.1.9   root      217: 
1.1.1.13  root      218:        UpdateAddr();
                    219: }
                    220: 
                    221: // "<<"(前ページ) ボタン押下イベント
                    222: void
                    223: WXMemdumpWindow::OnPrevPage(wxCommandEvent& event)
                    224: {
                    225:        // 1ページ戻る
                    226:        memdump->Offset(memdump->GetPageOffset(-1));
1.1.1.9   root      227: 
                    228:        UpdateAddr();
1.1       root      229: }
                    230: 
1.1.1.13  root      231: // ">"(次行) ボタン押下イベント
1.1       root      232: void
1.1.1.13  root      233: WXMemdumpWindow::OnNextLine(wxCommandEvent& event)
1.1       root      234: {
1.1.1.13  root      235:        // 1行進む
                    236:        memdump->Offset(memdump->GetLineOffset(1));
                    237: 
                    238:        UpdateAddr();
                    239: }
1.1.1.9   root      240: 
1.1.1.13  root      241: // ">>"(次ページ) ボタン押下イベント
                    242: void
                    243: WXMemdumpWindow::OnNextPage(wxCommandEvent& event)
                    244: {
                    245:        // 1ページ進む
                    246:        memdump->Offset(memdump->GetPageOffset(1));
1.1.1.9   root      247: 
                    248:        UpdateAddr();
1.1       root      249: }
                    250: 
1.1.1.9   root      251: // アドレス欄の表示を更新する
                    252: void
                    253: WXMemdumpWindow::UpdateAddr()
                    254: {
1.1.1.13  root      255:        int width;
                    256:        std::string title;
                    257:        if (IS_MONITOR_XPMEMDUMP(monid)) {
                    258:                width = 5;
                    259:                title = _("XP Memory Dump");
                    260:        } else {
                    261:                width = 8;
                    262:                title = _("Main Memory Dump");
                    263:        }
1.1.1.9   root      264: 
1.1.1.14  root      265:        uint32 addr = memdump->GetAddr().Addr();
1.1.1.13  root      266:        std::string addrstr = strhex(addr, width);
1.1.1.9   root      267: 
                    268:        // EVT_TEXT を起こさず変更する
1.1.1.13  root      269:        addrctrl->ChangeValue(addrstr);
1.1.1.9   root      270: 
                    271:        // カーソルを末尾に
                    272:        addrctrl->SetInsertionPointEnd();
                    273: 
                    274:        // タイトルを変更
1.1.1.13  root      275:        title += string_format(" %d: $", myidx);
                    276:        title += addrstr;
                    277:        SetTitle(title);
                    278: 
                    279:        // 即更新
                    280:        Refresh();
1.1.1.9   root      281: }
                    282: 
1.1.1.13  root      283: // 表示フォーマット変更イベント
                    284: void
                    285: WXMemdumpWindow::OnFormat(wxCommandEvent& event)
1.1.1.9   root      286: {
1.1.1.13  root      287:        int idx = event.GetSelection();
                    288:        DoFormat(Selection2Format(idx));
1.1       root      289: }
1.1.1.9   root      290: 
1.1.1.13  root      291: // 表示フォーマット変更処理
1.1.1.9   root      292: void
1.1.1.13  root      293: WXMemdumpWindow::DoFormat(Memdump::Format fmt)
1.1.1.9   root      294: {
1.1.1.13  root      295:        memdump->SetFormat(fmt);
                    296: 
                    297:        // SetFormat() によってアドレスが切り捨てられる場合があるので
                    298:        // アドレス欄の表示ごと更新。
                    299:        UpdateAddr();
                    300: }
                    301: 
                    302: // マウスホイールイベント
                    303: void
                    304: WXMemdumpWindow::OnMouseWheel(wxMouseEvent& event)
                    305: {
                    306:        int delta = event.GetWheelRotation();
                    307: 
                    308:        // 1回の変化で +/-120 が来る。
                    309:        // たいていのアプリケーションで3行ずつの移動に換算することが多いようだが
                    310:        // ここはメモリダンプなので 4行ずつにする。
                    311: 
                    312:        if (delta != 0) {
                    313:                memdump->Offset(memdump->GetLineOffset(-delta / 30));
                    314:                UpdateAddr();
                    315:        }
                    316: }
                    317: 
                    318: // ダブルクリックイベント
                    319: void
                    320: WXMemdumpWindow::OnDClick(wxMouseEvent& event)
                    321: {
                    322:        event.Skip();
                    323: 
                    324:        auto fmt = memdump->GetFormat();
                    325: 
                    326:        // テキストの桁数、行数にする
                    327:        wxPoint tpos = screen->GetTextPosition(event.GetPosition());
                    328:        int x = tpos.x;
                    329:        int y = tpos.y;
                    330: 
                    331:        // ウィンドウサイズを変えた時に出来る下の空き地にはヒットさせない
                    332:        if (y >= screen->GetRow()) {
                    333:                return;
                    334:        }
                    335: 
                    336:        // アドレス部分は常に除外でいいか
                    337:        if (x < 19) {
                    338:                return;
                    339:        }
                    340: 
                    341:        // 現在のフォーマットでのクリック位置のアドレスを求める
                    342:        int len = 0;
                    343:        uint64 addr = -1;
                    344:        switch (fmt) {
                    345:         case Memdump::Byte:
                    346:                len = 1;
                    347:                addr = GetAddrAtHexdump(x, y, len);
                    348:                break;
                    349:         case Memdump::Word:
                    350:                len = 2;
                    351:                addr = GetAddrAtHexdump(x, y, len);
                    352:                break;
                    353:         case Memdump::Long:
                    354:                len = 4;
                    355:                addr = GetAddrAtHexdump(x, y, len);
                    356:                break;
                    357:         case Memdump::M68030PageShort:
                    358:         case Memdump::M88200Page:
                    359:                len = 4;
                    360:                addr = GetAddrAtPageShort(x, y);
                    361:                break;
                    362: 
                    363:         case Memdump::M68030PageLong:
                    364:                PANIC("not supported");
                    365:                break;
                    366: 
1.1.1.15! root      367:         case Memdump::M680x0Disasm:
1.1.1.13  root      368:                len = 2;
                    369:                addr = GetAddrAtDisasm(x, y, len);
                    370:                break;
                    371: 
                    372:         case Memdump::M88100Disasm:
                    373:                len = 4;
                    374:                addr = GetAddrAtDisasm(x, y, len);
                    375:                break;
                    376: 
                    377:         case Memdump::HD64180Disasm:
                    378:                len = 1;
                    379:                addr = GetAddrAtDisasm(x, y, len);
                    380:                break;
                    381: 
                    382:         default:
                    383:                break;
                    384:        }
                    385:        if ((int64)addr < 0) {
                    386:                return;
                    387:        }
                    388:        addr &= ~(len - 1);
                    389: 
                    390:        // このアドレスが編集可能 (≒メモリ) か?
                    391:        if (memdump->CanPoke(addr) == false) {
                    392:                ::wxMessageBox(_("Can not edit here"), _("Memory Edit"),
                    393:                        wxICON_EXCLAMATION | wxOK | wxOK_DEFAULT, this);
                    394:                return;
                    395:        }
                    396: 
                    397:        // 出来ればここをハイライトとかしたい
                    398: 
                    399:        // 現在値を(再)取得。
                    400:        uint32 val = memdump->Peek(addr, len);
                    401: 
                    402:        // sizestr は表示形式ではなく単なるサイズ。(DescShort なら Long)
                    403:        std::string sizestr;
                    404:        switch (len) {
                    405:         case 1:
                    406:                sizestr = Format2String(Memdump::Byte);
                    407:                break;
                    408:         case 2:
                    409:                sizestr = Format2String(Memdump::Word);
                    410:                break;
                    411:         case 4:
                    412:                sizestr = Format2String(Memdump::Long);
                    413:                break;
                    414:         default:
                    415:                PANIC("corrupted len=%d", len);
                    416:        }
                    417: 
                    418:        // 編集
                    419:        auto dlg = new MemEditDialog(this, addr, val, len, sizestr);
                    420:        if (dlg->ShowModal() == wxID_OK) {
                    421:                uint32 data = dlg->GetData();
                    422: 
                    423:                // 更新
1.1.1.14  root      424:                if (memdump->Poke(addr, data, len) == false) {
1.1.1.13  root      425:                        ::wxMessageBox(_("Could not edit"), _("Memory Edit"),
                    426:                                wxICON_EXCLAMATION | wxOK | wxOK_DEFAULT, this);
                    427:                }
                    428:        }
                    429: }
                    430: 
                    431: // 16進ダンプ画面のテキスト座標 (x, y) に対応するアドレスを返す。
                    432: // 対応するアドレスがない場合は (uint64)-1 を返す。
                    433: uint64
                    434: WXMemdumpWindow::GetAddrAtHexdump(int x, int y, int len)
                    435: {
                    436:        if (x < 68) {
                    437:                // 16進ダンプ部分
                    438: 
                    439:                // 空白部分なら除外
                    440:                x -= 19;
                    441:                if (x % (len * 2 + 1) == len * 2) {
                    442:                        return (uint64)-1;
                    443:                }
                    444:                x = (x / (len * 2 + 1)) * len;
                    445:        } else {
                    446:                // 文字ダンプ部分
                    447:                x -= 68;
                    448:        }
                    449: 
                    450:        if (x > 15) {
                    451:                return (uint64)-1;
                    452:        }
                    453: 
1.1.1.14  root      454:        return memdump->GetAddr().Addr() + (y * memdump->GetStride()) + x;
1.1.1.9   root      455: }
                    456: 
1.1.1.13  root      457: // 32bit ページテーブル画面のテキスト座標 (x, y) に対応するアドレスを返す。
                    458: // 対応するアドレスがない場合は (uint64)-1 を返す。
                    459: uint64
                    460: WXMemdumpWindow::GetAddrAtPageShort(int x, int y)
                    461: {
                    462:        // 32bit ページテーブルなら1行で1ロングワード。
                    463:        // 16進の場合との親和性のため、ダンプ値のところだけ反応。
                    464:        if (x >= 19 + 8) {
                    465:                return (uint64)-1;
                    466:        }
1.1.1.14  root      467:        return memdump->GetAddr().Addr() + y * 4;
1.1.1.13  root      468: }
                    469: 
                    470: // 逆アセンブル画面のテキスト座標 (x, y) に対応するアドレスを返す。
                    471: // minlen は命令の最小バイト数。
                    472: // 対応するアドレスがない場合は (uint64)-1 を返す。
                    473: uint64
                    474: WXMemdumpWindow::GetAddrAtDisasm(int x, int y, int minlen)
                    475: {
                    476:        // 先頭から y 行目のアドレス
                    477:        uint32 yaddr = memdump->GetLineOffset(y);
                    478: 
                    479:        // y 行目の命令のバイト数
                    480:        uint32 y1addr = memdump->GetLineOffset(y + 1);
                    481:        uint32 bytes = y1addr - yaddr;
                    482: 
                    483:        // 空白部分なら除外
                    484:        x -= 19;
                    485: 
                    486:        if (x % (minlen * 2 + 1) == minlen * 2) {
                    487:                return (uint64)-1;
                    488:        }
                    489:        x = (x / (minlen * 2 + 1)) * minlen;
                    490: 
                    491:        if (x >= bytes) {
                    492:                return (uint64)-1;
                    493:        }
                    494: 
1.1.1.14  root      495:        return memdump->GetAddr().Addr() + yaddr + x;
1.1.1.13  root      496: }
                    497: 
                    498: // セレクション番号からフォーマット番号への変換
                    499: Memdump::Format
                    500: WXMemdumpWindow::Selection2Format(int idx)
                    501: {
                    502:        assert(idx < fmts.size());
                    503:        return fmts[idx].first;
                    504: }
                    505: 
                    506: // フォーマット番号からセレクション番号への変換
                    507: int
                    508: WXMemdumpWindow::Format2Selection(Memdump::Format fmt_)
                    509: {
                    510:        for (int idx = 0, end = fmts.size(); idx < end; idx++) {
                    511:                auto p = fmts[idx];
                    512:                if (fmt_ == p.first) {
                    513:                        return idx;
                    514:                }
                    515:        }
                    516:        // ?
                    517:        return 0;
                    518: }
                    519: 
                    520: // フォーマット番号から文字列への変換
                    521: wxString
                    522: WXMemdumpWindow::Format2String(Memdump::Format fmt_)
                    523: {
                    524:        for (int idx = 0, end = fmts.size(); idx < end; idx++) {
                    525:                auto p = fmts[idx];
                    526:                if (fmt_ == p.first) {
                    527:                        return p.second;
                    528:                }
                    529:        }
                    530:        // ?
                    531:        return wxEmptyString;
                    532: }
                    533: 
                    534: 
                    535: //
                    536: // 編集ダイアログ
                    537: //
                    538: 
                    539: wxBEGIN_EVENT_TABLE(MemEditDialog, inherited)
                    540:        EVT_TEXT_ENTER(ID_EDIT, MemEditDialog::OnTextEnter)
                    541: wxEND_EVENT_TABLE()
                    542: 
                    543: // コンストラクタ
                    544: MemEditDialog::MemEditDialog(wxWindow *parent, uint32 addr, uint32 oldval,
                    545:        int len, const std::string& sizestr)
                    546:        : inherited(parent, wxID_ANY, _("Edit memory"))
                    547: {
                    548:        auto topsizer = new wxBoxSizer(wxVERTICAL);
                    549: 
                    550:        auto gridsizer = new wxFlexGridSizer(2);
                    551:        topsizer->Add(gridsizer, 0, wxEXPAND | wxALL, 3);
                    552: 
                    553:        gridsizer->Add(new wxStaticText(this, wxID_ANY, _("Address:")),
                    554:                0, wxEXPAND);
                    555: 
                    556:        std::string addrstr = "$";
                    557:        addrstr += strhex(addr);
                    558:        auto addrctrl = new wxStaticText(this, wxID_ANY, addrstr,
                    559:                wxDefaultPosition, wxDefaultSize, wxBORDER_SUNKEN);
                    560:        gridsizer->Add(addrctrl, 0, wxEXPAND);
                    561: 
                    562:        gridsizer->Add(new wxStaticText(this, wxID_ANY, _("Size:")),
                    563:                0, wxEXPAND);
                    564:        gridsizer->Add(new wxStaticText(this, wxID_ANY, sizestr),
                    565:                0, wxEXPAND);
                    566: 
                    567:        gridsizer->Add(new wxStaticText(this, wxID_ANY, _("Data:")),
                    568:                0, wxEXPAND);
                    569: 
                    570:        std::string oldstr = strhex(oldval, len * 2);
                    571:        datactrl = new wxTextCtrl(this, ID_EDIT, oldstr,
                    572:                wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
                    573:        gridsizer->Add(datactrl, 0, wxEXPAND);
                    574: 
                    575:        topsizer->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL | wxNO_DEFAULT),
                    576:                0, wxEXPAND | wxALL, 3);
                    577: 
                    578:        SetSizer(topsizer);
                    579:        wxSize sz = topsizer->Fit(this);
                    580:        SetClientSize(sz);
                    581:        SetMinClientSize(sz);
                    582: }
                    583: 
                    584: // デストラクタ
                    585: MemEditDialog::~MemEditDialog()
                    586: {
                    587: }
                    588: 
                    589: // テキスト入力
                    590: void
                    591: MemEditDialog::OnTextEnter(wxCommandEvent& event)
                    592: {
                    593:        EndModal(wxID_OK);
                    594: }
                    595: 
                    596: // テキストコントロールの値を返す。
                    597: // 変換できなければ (uint64)-1 を返す。
                    598: uint64
                    599: MemEditDialog::GetData() const
                    600: {
                    601:        unsigned long int ul;
                    602:        char *end;
                    603: 
                    604:        // wxString だと地味にめんどい
                    605:        wxString wtext = datactrl->GetValue();
                    606:        std::string text((const char *)wtext.mb_str());
                    607: 
                    608:        errno = 0;
                    609:        ul = strtoul(&text[0], &end, 16);
                    610:        if (end == &text[0] || *end != '\0' || errno != 0) {
                    611:                return (uint64)-1;
                    612:        }
                    613:        return (uint32)ul;
                    614: }

unix.superglobalmegacorp.com

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