Annotation of nono/wx/wxsoftkey.cpp, revision 1.1.1.16

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 "wxsoftkey.h"
1.1.1.11  root       12: #include "fontmanager.h"
1.1.1.4   root       13: #include "wxcolor.h"
1.1.1.13  root       14: #include "wxmainframe.h"
1.1.1.6   root       15: #include "wxmainview.h"
1.1.1.8   root       16: #include "wxuimessage.h"
1.1.1.4   root       17: #include "sram.h"
1.1       root       18: 
                     19: //
1.1.1.4   root       20: // ソフトウェアキーボード (パネル) 共通部分
1.1       root       21: //
                     22: 
1.1.1.4   root       23: // エンター記号。
                     24: // 描画の際にキー刻印文字列の半角文字数から描画幅を決定しており、
                     25: // エンター記号は半角2文字幅で描いているので実際の文字列も2文字にしておく。
                     26: // そうすると "\\n" が意味的にもちょうどいい。
                     27: // これは幅を算出するのに使うだけで表示はされない。
                     28: #define EnterMark      "\\n"
                     29: 
1.1       root       30: // イベントテーブル
1.1.1.4   root       31: wxBEGIN_EVENT_TABLE(WXSoftKeyPanel, inherited)
                     32:        EVT_LEFT_DOWN(WXSoftKeyPanel::OnLeftDown)
                     33:        EVT_LEFT_UP(WXSoftKeyPanel::OnLeftUp)
                     34:        EVT_LEFT_DCLICK(WXSoftKeyPanel::OnLeftDClick)
                     35:        EVT_RIGHT_DOWN(WXSoftKeyPanel::OnRightDown)
1.1.1.9   root       36:        EVT_TIMER(wxID_ANY, WXSoftKeyPanel::OnTimer)
1.1       root       37: wxEND_EVENT_TABLE()
                     38: 
                     39: // コンストラクタ
1.1.1.4   root       40: WXSoftKeyPanel::WXSoftKeyPanel(wxWindow *parent,
1.1.1.6   root       41:        const std::vector<keydata_t>& keydata_, int u_width_, int u_height_)
1.1       root       42:        : inherited(parent)
1.1.1.6   root       43:        , keydata(keydata_)
1.1       root       44: {
1.1.1.13  root       45:        // デバイスを取得
                     46:        keyboard = GetKeyboard();
                     47: 
1.1.1.9   root       48:        timer.SetOwner(this);
                     49: 
1.1.1.4   root       50:        u_width  = u_width_;
                     51:        u_height = u_height_;
1.1.1.6   root       52: 
1.1.1.11  root       53:        FontChanged();
1.1.1.7   root       54: 
1.1.1.10  root       55:        // トグル動作にするキー
                     56:        toggle.emplace(KC_SHIFT, 0);
                     57:        toggle.emplace(KC_SHIFT_L, 0);
                     58:        toggle.emplace(KC_SHIFT_R, 0);
                     59:        toggle.emplace(KC_CTRL, 0);
                     60: 
1.1.1.9   root       61:        // 残光の初期化。
                     62:        // persistence は keydata 分の配列ではなく共通キーコード分の配列。
                     63:        persistence.resize(KC_max);
                     64:        std::fill(persistence.begin(), persistence.end(), 0);
                     65: 
1.1.1.6   root       66:        // このパネルへのキー入力はメインビューへのキー入力と同じ。
1.1.1.13  root       67:        auto mainframe = dynamic_cast<WXMainFrame*>(GetParent()->GetParent());
                     68:        auto mainview = mainframe->GetMainView();
1.1.1.9   root       69:        Connect(wxEVT_CHAR, wxCharEventHandler(WXMainView::OnChar), NULL,
1.1.1.13  root       70:                mainview);
1.1.1.6   root       71:        Connect(wxEVT_KEY_UP, wxKeyEventHandler(WXMainView::OnKeyUp), NULL,
1.1.1.13  root       72:                mainview);
1.1.1.6   root       73:        Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(WXMainView::OnKeyDown), NULL,
1.1.1.13  root       74:                mainview);
1.1.1.6   root       75: 
1.1.1.8   root       76:        // VM からの通知を受け取る
                     77:        WXUIMessage::Connect(UIMessage::KEYBOARD, this,
                     78:                wxCommandEventHandler(WXSoftKeyPanel::OnKeyChanged));
1.1.1.11  root       79: 
                     80:        // 初期タイトルを保存しといて..
                     81:        title = dynamic_cast<wxFrame*>(parent)->GetTitle();
                     82:        // キーボードの接続状況でタイトルを更新する
                     83:        UpdateTitle();
1.1       root       84: }
                     85: 
                     86: // デストラクタ
1.1.1.4   root       87: WXSoftKeyPanel::~WXSoftKeyPanel()
1.1       root       88: {
1.1.1.10  root       89:        // ウィンドウクローズでトグルキーのワンショットは開放する
1.1.1.9   root       90:        // (長押しは開放しない)
1.1.1.10  root       91:        for (const auto& k : toggle) {
                     92:                auto code = k.second;
                     93:                if (code) {
                     94:                        KeyUp(code);
                     95:                }
                     96:        }
1.1.1.9   root       97: 
                     98:        timer.Stop();
                     99: 
1.1.1.13  root      100:        WXUIMessage::Disconnect(UIMessage::KEYBOARD, this,
1.1.1.8   root      101:                wxCommandEventHandler(WXSoftKeyPanel::OnKeyChanged));
1.1       root      102: }
                    103: 
1.1.1.11  root      104: // キーボードの接続状況によって親フレームのタイトルを更新する。
                    105: // ついでにメンバ変数を更新する。
                    106: void
                    107: WXSoftKeyPanel::UpdateTitle()
                    108: {
                    109:        auto parent = dynamic_cast<WXSoftKeyWindow *>(GetParent());
                    110:        assert(parent);
                    111: 
                    112:        // 次回比較用にメンバ変数に覚えておく
1.1.1.13  root      113:        connected = keyboard->IsConnected();
1.1.1.11  root      114: 
                    115:        if (connected) {
                    116:                parent->SetTitle(title);
                    117:        } else {
                    118:                parent->SetTitle(title + _(" (disconnected)"));
                    119:        }
                    120: }
                    121: 
1.1.1.9   root      122: // color.Keytop の初期化(補間)。
                    123: // num はキートップの種類の数。1 か 2
                    124: void
                    125: WXSoftKeyPanel::InitColorKeytop(int num)
                    126: {
1.1.1.11  root      127:        Color pressed = UD_BLUE;
1.1.1.9   root      128: 
                    129:        auto f = [](int a, int b, int x) {
                    130:                return a * x / 100 + b * (100 - x) / 100;
                    131:        };
                    132: 
                    133:        // Keytop[i][9] は押されたときの色
                    134:        // Keytop[i][0] は押されていないときの色
                    135:        for (int i = 0; i < num; i++) {
                    136:                for (int j = 1; j < 10; j++) {
                    137:                        int n = j * 100 / 9;
1.1.1.11  root      138:                        color.Keytop[i][j] = Color(
                    139:                                f(pressed.r, color.Keytop[i][0].r, n),
                    140:                                f(pressed.g, color.Keytop[i][0].g, n),
                    141:                                f(pressed.b, color.Keytop[i][0].b, n));
1.1.1.9   root      142:                }
                    143:        }
                    144: }
                    145: 
1.1.1.11  root      146: // フォントサイズ変更
1.1       root      147: void
1.1.1.11  root      148: WXSoftKeyPanel::FontChanged()
1.1       root      149: {
1.1.1.11  root      150:        inherited::FontChanged();
1.1       root      151: 
                    152:        // このパネル内の描画の基本単位
                    153:        unit = font_height / 4;
                    154: 
                    155:        // エンターキーだけ矩形でないのでここでリージョンを計算。
                    156:        // unit が確定したところで一回行う。
1.1.1.6   root      157:        // ただし SHIFT_R のキーコードはちょっと使いづらいので、ここでは SHIFT_R
                    158:        // を使わず [_] キーで代用する。
                    159:        //
                    160:        //   |   ^   |   \   |   BS  |
                    161:        //   |       |       |       |
                    162:        // --+---+---+--(A)--+------(B)
                    163:        //       |       |           |
1.1.1.11  root      164:        //       |   [   |   Enter   |
                    165:        //       |       |           |
                    166:        // --+---+---+--(F)-(E) - - (G)
1.1.1.6   root      167:        //   |       |       |       |
                    168:        //   |   :   |   ]   |       |
                    169:        //   |       |       |       |
                    170:        // --+---+---+------(D)-----(C)
                    171:        //       |                   |
                    172:        //   _   |      SHIFT        |
1.1       root      173:        //
1.1.1.11  root      174:        // Enter キーの上半分 A-B-G-F を enter_top。F-G の線分を含む。
                    175:        // Enter キーの下半分 E-G-C-D を enter_btm。E-G の線分を含む。
1.1       root      176:        const keydata_t& keybs = FindKeydata(KC_BS);
                    177:        const keydata_t& keyleft = FindKeydata(KC_bracketleft);
                    178:        const keydata_t& keyright = FindKeydata(KC_bracketright);
1.1.1.6   root      179:        const keydata_t& keyscore = FindKeydata(KC_underscore);
1.1.1.11  root      180:        enter_top.SetLTRB(
                    181:                keyleft.right() * unit, keyleft.y * unit,
                    182:                keybs.right() * unit, keyright.y * unit);
                    183:        enter_btm.SetLTRB(
                    184:                keyright.right() * unit, keyright.y * unit,
                    185:                keybs.right() * unit, keyscore.y * unit);
1.1       root      186: 
1.1.1.13  root      187:        // アイコンを変更。参照順序の関係で下のほうにおいてある…。
                    188:        InitIcon();
                    189: 
1.1.1.15  root      190:        // バックバッファの下限を固定する
1.1.1.4   root      191:        wxSize size(u_width * unit, u_height * unit);
1.1.1.15  root      192:        SetMinBitmapSize(size);
1.1.1.13  root      193: 
                    194:        // コントロールの大きさを変更
1.1.1.15  root      195:        SetSize(size);
                    196:        SetMinSize(size);
1.1       root      197: }
                    198: 
1.1.1.9   root      199: void
                    200: WXSoftKeyPanel::OnTimer(wxTimerEvent& event)
                    201: {
                    202:        Refresh();
                    203: }
                    204: 
1.1.1.8   root      205: // キー状態変更イベント (UIMessage)
1.1.1.9   root      206: //
                    207: // キー状態変更イベントは、キーの状態が変わるたびに都度通知される。
                    208: // ソフトウェアキーボード入力とパススルーモードの入力では、どのキーに変化
                    209: // (押下 or 開放)があったかの情報は付属しない。各キーの押下状態は全キーを
                    210: // 逐一調査することで判定する。人間時間で起きる事象なのでこの計算量は許容。
                    211: // Char 入力モードの場合は、イベントのパラメータ引数 (GetInt() で取得可) に
                    212: // 入力のあったキーの共通キーコードが入っている (複数のキーが同時に押される
                    213: // 場合はキーの回数分のイベントが飛んでくる)。Char 入力モードにはキー開放
                    214: // という概念はない。
1.1.1.6   root      215: void
1.1.1.8   root      216: WXSoftKeyPanel::OnKeyChanged(wxCommandEvent& event)
1.1.1.6   root      217: {
1.1.1.9   root      218:        // Char 入力モードでキーが押された場合は、共通キーコードが送られてくるので、
                    219:        // persistence[] をここでセットする。
                    220:        // Char 入力モードでは、キーの Make/Break が一瞬で終わるため、このイベント
                    221:        // を受け取って Refresh() を発行 -> OnPaint() -> Draw() 内で IsPressed()
                    222:        // を調べた頃にはタイミング問題でもうキーが離されている可能性があるので、
                    223:        // 描画時に全キーを調べる方法は使えない。
                    224:        uint keycode = event.GetInt();
                    225:        if (keycode != 0) {
                    226:                assert(keycode < persistence.size());
                    227:                // 9 が減光時の初期値 (10 は減光しない点灯)
                    228:                persistence[keycode] = 9;
1.1.1.6   root      229:        }
1.1.1.9   root      230: 
1.1.1.10  root      231:        // トグルキーが開放されていたらトグル情報をクリアする。
                    232:        // ハードウェアキーボードを含む VM 側で開放された場合と、
                    233:        // ソフトウェアキーボードの KeyUp() で開放された場合のどちらも
                    234:        // ここでクリア。
                    235:        for (auto& k : toggle) {
1.1.1.13  root      236:                if (keyboard->IsPressed(k.first) == false) {
1.1.1.10  root      237:                        k.second = 0;
                    238:                }
                    239:        }
                    240: 
1.1.1.11  root      241:        // 接続状況が変わっていたらタイトルを更新。
1.1.1.13  root      242:        if (keyboard->IsConnected() != connected) {
1.1.1.11  root      243:                UpdateTitle();
                    244:        }
1.1.1.6   root      245: 
1.1.1.11  root      246:        Refresh();
1.1       root      247: }
                    248: 
                    249: // 描画本体
                    250: void
1.1.1.11  root      251: WXSoftKeyPanel::Draw()
1.1       root      252: {
1.1.1.9   root      253:        bool timer_start = false;
                    254: 
                    255:        // キー刻印の表示更新用に修飾キーの状態を更新。
                    256:        // 本来は IsShift() だけで判定すべきだが、Char 入力モードでいずれかの
                    257:        // SHIFT キーが減光中は SHIFT 刻印を継続してみるのはどうか。
                    258:        // 0 まで待つとうちの環境だと消灯した少し後に刻印が戻るように見えるため、
                    259:        // ある程度暗くなったところでもう切り替えてみる。閾値は適当。
                    260:        if ((2 < persistence[KC_SHIFT_L] && persistence[KC_SHIFT_L] < 10) ||
                    261:            (2 < persistence[KC_SHIFT_R] && persistence[KC_SHIFT_R] < 10) ||
                    262:                (2 < persistence[KC_SHIFT]   && persistence[KC_SHIFT]   < 10) ||
1.1.1.13  root      263:                keyboard->IsShift())
1.1.1.9   root      264:        {
                    265:                modifier = ModShift;
                    266:        } else {
                    267:                modifier = ModNormal;
                    268:        }
                    269: 
1.1.1.11  root      270:        auto text_color = color.Text;
                    271: 
                    272:        // キーボードが接続されていないときは刻印をグレーにしておく
1.1.1.13  root      273:        if (keyboard->IsConnected() == false) {
1.1.1.11  root      274:                text_color = UD_GREY;
                    275:        }
                    276:        SetTextForeColor(text_color);
1.1       root      277: 
1.1.1.6   root      278:        for (const auto& key : keydata) {
1.1.1.9   root      279:                int c = persistence[key.keycode];
                    280:                if (0 < c && c < 10) {
                    281:                        // Char 入力モードで減光中
                    282:                        c--;
                    283:                        timer_start = true;
1.1       root      284:                } else {
1.1.1.9   root      285:                        // そうでない場合に限り、現在の状態を問い合わせる
1.1.1.13  root      286:                        bool is_pressed = keyboard->IsPressed(key.keycode);
1.1.1.9   root      287:                        if (is_pressed) {
                    288:                                // 押されている
                    289:                                c = 10;
                    290:                        } else {
                    291:                                // 押されていない
                    292:                                c = 0;
                    293:                        }
                    294:                }
                    295:                // persistence[] は 10 が(減光しない)点灯、9..1 が減光中を示す。
                    296:                persistence[key.keycode] = c;
                    297:                // ただし色配列は 0..9 で 9 が最大点灯色
                    298:                if (c > 9) {
                    299:                        c = 9;
1.1       root      300:                }
                    301: 
1.1.1.9   root      302:                SetTextBackColor(color.Keytop[key.coltype][c]);
                    303: 
1.1.1.13  root      304:                // エンターキーとブザー表示は描き方が違うので別処理
                    305:                if (__predict_false(key.keycode == KC_enter)) {
1.1.1.11  root      306:                        DrawEnterKey();
1.1.1.13  root      307:                } else if (__predict_false(key.keycode == KC_buzzer)) {
                    308:                        DrawBuzzer(key);
1.1       root      309:                } else {
1.1.1.11  root      310:                        DrawKey(key);
1.1       root      311:                }
                    312:        }
                    313: 
1.1.1.9   root      314:        if (timer_start) {
                    315:                timer.Start(25);
                    316:        } else {
                    317:                timer.Stop();
                    318:        }
1.1       root      319: }
                    320: 
                    321: // 指定のキーを一つ (枠から刻印まで) 描画する。
1.1.1.16! root      322: // palette[FG] はテキスト色 (キーボード非接続ならグレー)。
        !           323: // palette[BG] はこのキーの背景色 (押されているか、減光中か、
        !           324: // 押されていない時の二色あるかも知れないキートップ色)。
1.1       root      325: void
1.1.1.11  root      326: WXSoftKeyPanel::DrawKey(const keydata_t& key)
1.1       root      327: {
1.1.1.10  root      328:        uint attr = TA::Normal;
                    329: 
1.1       root      330:        // 枠
1.1.1.16! root      331:        DrawKeyBox(key, palette[0], color.Text);
1.1       root      332: 
                    333:        // 刻印を選択
                    334:        const char *disp = key.disp[modifier];
                    335:        if (disp == NULL) {
                    336:                disp = key.disp[0];
                    337:        }
                    338: 
1.1.1.10  root      339:        // トグルキーのワンショット押しは太字で表示を区別したい
                    340:        const auto it = toggle.find(key.keycode);
                    341:        if (it != toggle.end()) {
                    342:                if (it->second) {
                    343:                        attr = TA::Em;
                    344:                }
                    345:        }
                    346: 
1.1       root      347:        // Shift_JIS に変換
                    348:        wxString utfstr(disp, wxConvUTF8);
1.1.1.11  root      349:        // mb_str() をキャストせずに一度保持しておく必要がある (scan-build 対策)
                    350:        auto mbstr = utfstr.mb_str(conv);
                    351:        const char *sjis = (const char *)mbstr;
1.1.1.4   root      352:        // 改行があれば2行に分割
                    353:        char sjis1[8] {};
                    354:        char sjis2[8] {};
                    355:        int sjislen;
                    356:        int row;
                    357:        const char *lf = strchr(sjis, '\n');
                    358:        if (lf == NULL) {
                    359:                // 1行なら、Shift_JIS での文字数は半角換算の文字数と一致する。
                    360:                sjislen = strlen(sjis);
                    361:                row = 1;
                    362:        } else {
                    363:                // 2行に分割。センタリングは1行目の長さだけで調べる。
                    364:                strncpy(sjis1, sjis, lf - sjis);
1.1.1.14  root      365:                strlcpy(sjis2, lf + 1, sizeof(sjis2));
1.1.1.4   root      366:                sjislen = strlen(sjis1);
                    367:                row = 2;
                    368:        }
1.1       root      369: 
1.1.1.16! root      370:        // X 方向のセンタリング。
        !           371:        // unit 単位の計算では精度が足りないのでドット単位で計算する。
        !           372:        int x = key.x * unit + (key.w - sjislen * 2) * unit / 2 + 1;
1.1       root      373: 
1.1.1.16! root      374:        // Y 方向のセンタリングは、端数が出ないのと LED 用オフセットが
        !           375:        // unit 単位なので、unit 単位のまま計算して、後でドット単位にする。
        !           376:        int y = key.y + (key.h - row * 4) / 2;
1.1.1.4   root      377:        // LED を描画 (機種によって色々違うので個別クラス側で処理)
                    378:        if (key.led >= 0) {
1.1.1.11  root      379:                y += DrawLED(key);
1.1       root      380:        }
1.1.1.16! root      381:        y = y * unit + 1;
1.1       root      382: 
                    383:        // 文字を描画
1.1.1.4   root      384:        if (strcmp(disp, EnterMark) == 0) {
1.1.1.14  root      385:                bitmap.DrawBitmapI1(x, y, *enter_icon, palette);
1.1       root      386:        } else {
1.1.1.4   root      387:                if (lf == NULL) {
                    388:                        // 1行の場合
1.1.1.11  root      389:                        DrawStringSJIS(x, y, sjis, attr);
1.1.1.4   root      390:                } else {
                    391:                        // 2行の場合
1.1.1.11  root      392:                        DrawStringSJIS(x, y, sjis1);
                    393:                        y += 4 * unit;
                    394:                        DrawStringSJIS(x, y, sjis2);
1.1.1.4   root      395:                }
1.1       root      396:        }
                    397: }
                    398: 
1.1.1.16! root      399: // キーの枠と背景色を描画する。
        !           400: void
        !           401: WXSoftKeyPanel::DrawKeyBox(const keydata_t& key, Color bg, Color bd)
        !           402: {
        !           403:        Rect rect(
        !           404:                key.x * unit,     key.y * unit,
        !           405:                key.w * unit + 1, key.h * unit + 1);
        !           406:        bitmap.FillRect(bg, rect);
        !           407:        bitmap.DrawRect(bd, rect);
        !           408: }
        !           409: 
1.1       root      410: // エンターキー
                    411: void
1.1.1.11  root      412: WXSoftKeyPanel::DrawEnterKey()
1.1       root      413: {
1.1.1.11  root      414:        // 矩形の内側を背景色で塗りつぶす。
                    415:        bitmap.FillRect(palette[0], enter_top);
                    416:        bitmap.FillRect(palette[0], enter_btm);
                    417: 
                    418:        // 周囲の線分
                    419:        // (A)-(B)
                    420:        bitmap.DrawLineH(color.Text,
                    421:                enter_top.x, enter_top.y, enter_top.GetRight());
                    422:        // (B)-(C)
                    423:        bitmap.DrawLineV(color.Text,
                    424:                enter_top.GetRight(), enter_top.y, enter_btm.GetBottom());
                    425:        // (C)-(D)
                    426:        bitmap.DrawLineH(color.Text,
                    427:                enter_btm.GetRight(), enter_btm.GetBottom(), enter_btm.x);
                    428:        // (D)-(E)
                    429:        bitmap.DrawLineV(color.Text,
                    430:                enter_btm.x, enter_btm.GetBottom(), enter_btm.y);
                    431:        // (E)-(F)
                    432:        bitmap.DrawLineH(color.Text,
                    433:                enter_btm.x, enter_top.GetBottom(), enter_top.x);
                    434:        // (F)-(A)
                    435:        bitmap.DrawLineV(color.Text,
                    436:                enter_top.x, enter_top.GetBottom(), enter_top.y);
1.1       root      437: 
                    438:        // エンター記号を描画
1.1.1.14  root      439:        bitmap.DrawBitmapI1(
1.1.1.11  root      440:                (enter_top.x + enter_top.GetRight())  / 2 - (4 / 2),
1.1.1.13  root      441:                (enter_top.y + enter_btm.GetBottom()) / 2 - (4 / 2),
                    442:                *enter_icon, palette);
1.1.1.11  root      443: }
                    444: 
1.1.1.13  root      445: // ブザー表示(キーに相当)を描画
                    446: void
                    447: WXSoftKeyPanel::DrawBuzzer(const keydata_t& key)
                    448: {
                    449:        Color fg;
                    450: 
                    451:        // 枠。キーではないので薄くしておく。
1.1.1.16! root      452:        DrawKeyBox(key, palette[0], UD_GREY);
1.1.1.13  root      453: 
                    454:        // テキスト色は本来呼び出し元の DrawKey() で設定してあるが、
                    455:        // ここはキーではないので非発声時の文字色だけ薄くしたい。
                    456:        // 発声時はキー押下と同じにする。
                    457:        fg = GetTextForeColor();
                    458:        if (persistence[key.keycode] == 0) {
                    459:                SetTextForeColor(UD_GREY);
                    460:        }
1.1.1.11  root      461: 
1.1.1.13  root      462:        // 刻印 (モディファイヤの影響を受けないと分かっているので常に [0])
                    463:        const char *disp = key.disp[0];
                    464:        assert(disp);
                    465: 
                    466:        // センタリング
                    467:        int x = key.x + (key.w - strlen(disp) * 2) / 2;
                    468:        int y = key.y + (key.h - 4) / 2;
                    469: 
                    470:        // 文字を描画
                    471:        x = x * unit + 1;
                    472:        y = y * unit + 1;
                    473:        DrawStringSJIS(x, y, disp, TA::Normal);
                    474: 
                    475:        // 前景色を元に戻す
                    476:        SetTextForeColor(fg);
                    477: }
                    478: 
                    479: #define B(x)   (0b##x)
                    480: #define B2(x)  (B(x) >> 8), (B(x) & 0xff)
                    481: #define B3(x)  (B(x) >> 16), ((B(x) >> 8) & 0xff), (B(x) & 0xff)
                    482: 
                    483: static const uint8 EnterIcon12[] = {   // 12x12
                    484:        B2(000000000000'0000),  // 0
                    485:        B2(000000001110'0000),  // 1
                    486:        B2(000000001010'0000),  // 2
                    487:        B2(000000001010'0000),  // 3
                    488:        B2(000000001010'0000),  // 4
                    489:        B2(001100001010'0000),  // 5
                    490:        B2(010111110010'0000),  // 6
                    491:        B2(100000000010'0000),  // 7
                    492:        B2(010111111100'0000),  // 8
                    493:        B2(001100000000'0000),  // 9
                    494:        B2(000000000000'0000),  // a
                    495:        B2(000000000000'0000),  // b
1.1.1.11  root      496: };
1.1.1.13  root      497: 
                    498: static const uint8 EnterIcon16[] = {   // 16x16
                    499:        B2(0000000000111110),   // 0
                    500:        B2(0000000000100010),   // 1
                    501:        B2(0000000000100010),   // 2
                    502:        B2(0000000000100010),   // 3
                    503:        B2(0000000000100010),   // 4
                    504:        B2(0000000000100010),   // 5
                    505:        B2(0000000000100010),   // 6
                    506:        B2(0000110000100010),   // 7
                    507:        B2(0001010000100010),   // 8
                    508:        B2(0010011111000010),   // 9
                    509:        B2(0100000000000010),   // a
                    510:        B2(1000000000000010),   // b
                    511:        B2(0100000000000010),   // c
                    512:        B2(0010011111111100),   // d
                    513:        B2(0001010000000000),   // e
                    514:        B2(0000110000000000),   // f
1.1.1.11  root      515: };
1.1       root      516: 
1.1.1.13  root      517: static const uint8 EnterIcon24[] = {   // 24x24
                    518:        B3(00000000'00000001'11111100), // 0
                    519:        B3(00000000'00000001'11111100), // 1
                    520:        B3(00000000'00000001'10001100), // 2
                    521:        B3(00000000'00000001'10001100), // 3
                    522:        B3(00000000'00000001'10001100), // 4
                    523:        B3(00000000'00000001'10001100), // 5
                    524:        B3(00000000'00000001'10001100), // 6
                    525:        B3(00000000'00000001'10001100), // 7
                    526:        B3(00000000'00000001'10001100), // 8
                    527:        B3(00000000'11000001'10001100), // 9
                    528:        B3(00000001'11000001'10001100), // 10
                    529:        B3(00000011'11000001'10001100), // 11
                    530:        B3(00000110'11000001'10001100), // 12
                    531:        B3(00001100'11111111'10001100), // 13
                    532:        B3(00011000'11111111'10001100), // 14
                    533:        B3(00110000'00000000'00001100), // 15
                    534:        B3(01100000'00000000'00001100), // 16
                    535:        B3(00110000'00000000'00001100), // 17
                    536:        B3(00011000'11111111'11111100), // 18
                    537:        B3(00001100'11111111'11111000), // 19
                    538:        B3(00000110'11000000'00000000), // 20
                    539:        B3(00000011'11000000'00000000), // 21
                    540:        B3(00000001'11000000'00000000), // 22
                    541:        B3(00000000'11000000'00000000), // 23
                    542: };
                    543: 
                    544: // アイコンを初期化する。FontChanged() から呼ばれる。
                    545: // ソース先頭のほうにデータの羅列を置きたくないが、
                    546: // 容量不詳の配列の解決が面倒なのでこれだけ下のほうのここに置いてある。
1.1       root      547: void
1.1.1.13  root      548: WXSoftKeyPanel::InitIcon()
1.1       root      549: {
1.1.1.13  root      550:        const int width  = font_width;
                    551:        const int height = font_height;
                    552:        const uint8 *icon;
1.1.1.11  root      553: 
1.1.1.13  root      554:        switch (height) {
1.1.1.11  root      555:         case 12:
1.1.1.13  root      556:                icon = EnterIcon12;
1.1.1.11  root      557:                break;
                    558:         case 16:
1.1.1.13  root      559:                icon = EnterIcon16;
                    560:                break;
                    561:         case 24:
                    562:                icon = EnterIcon24;
1.1.1.11  root      563:                break;
                    564:         default:
1.1.1.13  root      565:                PANIC("Unexpected font_height=%d", height);
1.1       root      566:        }
1.1.1.13  root      567: 
                    568:        enter_icon.reset(new BitmapI1(icon, width * 2, height));
1.1       root      569: }
                    570: 
                    571: // keycode に対応する keydata を返す
                    572: const keydata_t&
1.1.1.4   root      573: WXSoftKeyPanel::FindKeydata(uint keycode) const
1.1       root      574: {
1.1.1.6   root      575:        for (const auto& key : keydata) {
1.1       root      576:                if (key.keycode == keycode) {
                    577:                        return key;
                    578:                }
                    579:        }
                    580:        // 見付からないはずはない
1.1.1.11  root      581:        PANIC("keycode %d not found", keycode);
1.1       root      582: }
                    583: 
                    584: // マウス左クリック (Down) イベント
                    585: void
1.1.1.4   root      586: WXSoftKeyPanel::OnLeftDown(wxMouseEvent& event)
1.1       root      587: {
1.1.1.5   root      588:        const wxPoint& pt = event.GetPosition();
1.1.1.4   root      589:        const keydata_t *key = GetKeydataFromPoint(pt);
1.1       root      590: 
1.1.1.9   root      591:        if (key != NULL) {
1.1.1.10  root      592:                DoLeftDown(key->keycode);
1.1.1.9   root      593:        }
1.1       root      594: }
                    595: 
                    596: // マウス左クリック (Down) 処理
                    597: void
1.1.1.10  root      598: WXSoftKeyPanel::DoLeftDown(uint code)
1.1       root      599: {
1.1.1.10  root      600:        auto it = toggle.find(code);
                    601:        if (it != toggle.end()) {
                    602:                // トグルキーはここで完結。LeftUp では何もしない。
                    603:                // second のクリアは KeyUp() からコールバックされる OnKeyChanged()
                    604:                // で行っている。
1.1.1.13  root      605:                if (keyboard->IsPressed(code)) {
1.1.1.10  root      606:                        KeyUp(code);
1.1.1.9   root      607:                } else {
1.1.1.10  root      608:                        KeyDown(code);
                    609:                        it->second = code;
1.1.1.9   root      610:                }
1.1.1.10  root      611:                leftdown_key = KC_none;
1.1.1.9   root      612:        } else {
1.1.1.10  root      613:                // トグルでない通常キーはここで押下して LeftUp のために覚えておく
                    614:                KeyDown(code);
                    615:                leftdown_key = code;
1.1       root      616:        }
                    617: }
                    618: 
                    619: // マウス左クリック (Up) イベント
                    620: void
1.1.1.4   root      621: WXSoftKeyPanel::OnLeftUp(wxMouseEvent& event)
1.1       root      622: {
                    623:        // Up 時は、これが起きた地点のキーコードではなく
                    624:        // 直近に LeftDown したキーコードをターゲットにする。
1.1.1.10  root      625:        uint code = leftdown_key;
1.1       root      626: 
1.1.1.10  root      627:        if (code != KC_none) {
                    628:                KeyUp(code);
1.1.1.9   root      629: 
1.1.1.10  root      630:                // 通常キーが離されたら、トグルキーはすべて開放
                    631:                for (const auto& k : toggle) {
                    632:                        auto tcode = k.second;
                    633:                        if (tcode) {
                    634:                                KeyUp(tcode);
1.1.1.9   root      635:                        }
                    636:                }
1.1       root      637:        }
1.1.1.9   root      638: 
1.1.1.10  root      639:        leftdown_key = KC_none;
1.1       root      640: }
                    641: 
                    642: // マウス左ダブルクリックイベント
                    643: // ダブルクリックという操作に特別何かを割り当ててはいないが、
                    644: // キーを連打するとその間隔によってはダブルクリックと扱われるため、
                    645: // 受け取ってここで処理する。
                    646: //
                    647: // DClick イベントは LeftDown、LeftUp、LeftDClick、LeftUp の順で
                    648: // 飛んでくるので、ここでは2回目の押下だけ処理すればよい。というか
                    649: // 処理自体は LeftDown とまったく同じになるので、イベントテーブルで
                    650: // 直接 EVT_LEFT_DCLICK => OnLeftDown に割り付けることも出来そうだが
                    651: // デバッグが紛らわしくなりそうなので独立したイベントとしておく。
                    652: void
1.1.1.4   root      653: WXSoftKeyPanel::OnLeftDClick(wxMouseEvent& event)
1.1       root      654: {
1.1.1.5   root      655:        const wxPoint& pt = event.GetPosition();
1.1.1.4   root      656:        const keydata_t *key = GetKeydataFromPoint(pt);
1.1       root      657: 
1.1.1.9   root      658:        if (key != NULL) {
1.1.1.10  root      659:                DoLeftDown(key->keycode);
1.1.1.9   root      660:        }
1.1       root      661: }
                    662: 
                    663: // マウス右クリック (Down) イベント
                    664: // 長押し開始/解除。
                    665: // 右クリックのほうは Down だけで Up は使わない。
                    666: void
1.1.1.4   root      667: WXSoftKeyPanel::OnRightDown(wxMouseEvent& event)
1.1       root      668: {
1.1.1.5   root      669:        const wxPoint& pt = event.GetPosition();
1.1.1.4   root      670:        const keydata_t *key = GetKeydataFromPoint(pt);
1.1       root      671: 
1.1.1.4   root      672:        if (key != NULL) {
                    673:                uint code = key->keycode;
1.1.1.13  root      674:                if (keyboard->IsPressed(code)) {
1.1       root      675:                        // 押されていたら開放
1.1.1.10  root      676:                        KeyUp(code);
1.1       root      677:                } else {
                    678:                        // 押されてなければ長押し開始
1.1.1.10  root      679:                        KeyDown(code);
1.1       root      680:                }
                    681:        }
                    682: }
                    683: 
1.1.1.4   root      684: // 座標からキーデータを返す。
                    685: // キーに当たっていなければ NULL を返す。
                    686: const keydata_t *
                    687: WXSoftKeyPanel::GetKeydataFromPoint(const wxPoint& pt) const
1.1       root      688: {
1.1.1.4   root      689:        // エンターキーだけ先に別判定
1.1.1.11  root      690:        if (enter_top.Contains(pt.x, pt.y) || enter_btm.Contains(pt.x, pt.y)) {
1.1.1.4   root      691:                return &FindKeydata(KC_enter);
                    692:        }
1.1       root      693: 
1.1.1.6   root      694:        for (const auto& key : keydata) {
1.1.1.4   root      695:                if (key.x < 0) {
                    696:                        continue;
1.1       root      697:                }
1.1.1.4   root      698:                // 始点と幅の +1/-1 は罫線の分
                    699:                wxRect rect(
                    700:                        (key.x * unit) + 1,
                    701:                        (key.y * unit) + 1,
                    702:                        (key.w * unit) - 1,
                    703:                        (key.h * unit) - 1);
                    704:                if (rect.Contains(pt)) {
                    705:                        return &key;
1.1       root      706:                }
1.1.1.4   root      707:        }
                    708:        return NULL;
                    709: }
                    710: 
1.1.1.6   root      711: // このキーが押された処理
                    712: void
1.1.1.10  root      713: WXSoftKeyPanel::KeyDown(uint code)
1.1.1.6   root      714: {
1.1.1.9   root      715:        // VM に通知 (Keyboard がホストに通知する)
1.1.1.13  root      716:        keyboard->MakeKey(code);
1.1.1.6   root      717: }
                    718: 
                    719: // このキーが放された処理
                    720: void
1.1.1.10  root      721: WXSoftKeyPanel::KeyUp(uint code)
1.1.1.6   root      722: {
1.1.1.9   root      723:        // VM に通知 (Keyboard がホストに通知する)
1.1.1.13  root      724:        keyboard->BreakKey(code);
1.1.1.6   root      725: }
                    726: 
1.1.1.16! root      727: // LUNA-I、LUNA-88K のコンストラクタ共通部分。
        !           728: // クラス階層を増やすのも手間なので。
        !           729: void
        !           730: WXSoftKeyPanel::InitLunaCommon()
1.1.1.4   root      731: {
                    732:        // LUNA では
                    733:        // BS キーの左隣 (0x5c) は円記号ではなくバックスラッシュ。
                    734:        // それを SHIFT したやつ(0x7c) は破線でないパイプ。
                    735:        // そのもう一つ左隣 (0x7e) はオーバーラインではなくチルダ。
1.1.1.11  root      736:        gFontManager->SetGlyph5C(true);
                    737:        gFontManager->SetGlyph7E(true);
1.1.1.4   root      738: 
1.1.1.9   root      739:        // 白黒モデル共通
1.1.1.11  root      740:        color.Border = UD_BLACK;
1.1.1.9   root      741:        color.LED[0] = UD_RED;
                    742: 
1.1.1.4   root      743:        // キートップの濃淡はユニバーサルデザインの推奨色ではないけど
                    744:        // ここは見分けを付けるためではなくただのデザインなので。
                    745:        if (1) {
                    746:                // 白モデル
1.1.1.9   root      747:                color.Background        = UD_LIGHT_GREY;        // 現物新品は何色だったんだろう
1.1.1.11  root      748:                color.Text                      = UD_BLACK;
                    749:                color.Keytop[0][0]      = UD_WHITE;
                    750:                color.Keytop[1][0]      = Color(200, 200, 203);
1.1.1.4   root      751:        } else {
                    752:                // 黒モデル
1.1.1.11  root      753:                color.Background        = UD_BLACK;
                    754:                color.Text                      = UD_WHITE;
                    755:                color.Keytop[0][0]      = Color(50, 50, 53);
                    756:                color.Keytop[1][0]      = UD_BLACK;
1.1.1.4   root      757:        }
1.1.1.9   root      758:        InitColorKeytop(2);
1.1.1.11  root      759: 
                    760:        SetBitmapBGColor(color.Background);
1.1.1.13  root      761:        Fill();
1.1.1.4   root      762: }
                    763: 
1.1.1.16! root      764: 
        !           765: //
        !           766: // LUNA-I ソフトウェアキーボード (パネル)
        !           767: //
        !           768: 
        !           769: // コンストラクタ
        !           770: WXLuna1SoftKeyPanel::WXLuna1SoftKeyPanel(wxWindow *parent)
        !           771:        : inherited(parent, keydata, 226, 54)
        !           772: {
        !           773:        InitLunaCommon();
        !           774: }
        !           775: 
1.1.1.4   root      776: // デストラクタ
1.1.1.16! root      777: WXLuna1SoftKeyPanel::~WXLuna1SoftKeyPanel()
1.1.1.4   root      778: {
                    779: }
                    780: 
                    781: // LED を描画して刻印描画のための y offset を返す。
                    782: int
1.1.1.16! root      783: WXLuna1SoftKeyPanel::DrawLED(const keydata_t& key)
1.1.1.4   root      784: {
1.1.1.13  root      785:        const std::vector<bool>& led = keyboard->GetLED();
1.1.1.11  root      786:        Color fg;
                    787:        Color bg;
1.1.1.4   root      788: 
                    789:        if (led[key.led]) {
                    790:                // 点灯時は赤、枠は黒
1.1.1.11  root      791:                fg = color.Border;
                    792:                bg = color.LED[0];
1.1       root      793:        } else {
1.1.1.4   root      794:                // 消灯時は元のキートップの色で、枠は薄めにしたい
1.1.1.6   root      795:                // (枠の色は今の所全モデル共通なので ColorPalette に含めていない)
1.1.1.11  root      796:                fg = UD_GREY;
                    797:                bg = color.Keytop[key.coltype][0];
1.1       root      798:        }
                    799: 
1.1.1.4   root      800:        // LED を左肩に描く
1.1.1.11  root      801:        Rect rect(key.x * unit + 2, key.y * unit + 2, 4 * unit - 2, 3 * unit - 2);
                    802:        bitmap.FillRect(bg, rect);
                    803:        bitmap.DrawRect(fg, rect);
1.1.1.4   root      804: 
                    805:        // そのため文字は少し下げる
                    806:        return +1;
                    807: }
                    808: 
1.1.1.16! root      809: // LUNA-I のファンクションキーは ESC 行との間が少し空いている。
        !           810: // LUNA-88K のファンクションキー行は ESC 行とぴったりついていて、キーの
        !           811: // 縦の長さも他のキーと同じ感じ。
        !           812: // X68030 のファンクションキーは ESC 行との間が空いていて、キーの長さは
        !           813: // 他より短い。
        !           814: //
        !           815: //  2 - +--------+
        !           816: //  4 - | LUNA-I | +-------+ +--------+
        !           817: //  6 - |        | | 88K   | | X68030 |
        !           818: //  8 - |        | |       | |        |
        !           819: // 10 - +--------+ |       | +--------+
        !           820: // 12 - +--------+ +-------+ +--------+  <- ESC 行の上辺
        !           821: // 14 - |  ESC   | |   1   | |   2    |
        !           822: //
1.1       root      823: #define H       (8)    // キーの高さ
1.1.1.16! root      824: #define LH      (2)    // ファンクションキーの行 (ESC 行との間に空き)
        !           825: #define L0      (4)    // ファンクションキーは少し低い(横長い)
1.1       root      826: #define L1     (12)    // ESC の行
                    827: #define L2     (20)    // TAB の行
                    828: #define L3     (28)    // CTRL の行
                    829: #define L4     (36)    // SHIFT の行
                    830: #define L5     (44)    // space の行
1.1.1.16! root      831: 
        !           832: // キーデータ
1.1       root      833: /*static*/ std::vector<keydata_t>
1.1.1.16! root      834: WXLuna1SoftKeyPanel::keydata {
1.1.1.4   root      835:        //                +---- キートップの色(1:濃)
                    836:        //                |  +- 0 以上なら LED 番号
                    837:        //  X   Y   W  H  C  L  KeyCode                         通常  SHIFT
1.1.1.16! root      838:        {   2, LH, 15, H, 1,-1, KC_F1,                          { "PF1" } },
        !           839:        {  17, LH, 15, H, 1,-1, KC_F2,                          { "PF2" } },
        !           840:        {  32, LH, 15, H, 1,-1, KC_F3,                          { "PF3" } },
        !           841:        {  47, LH, 15, H, 1,-1, KC_F4,                          { "PF4" } },
        !           842:        {  62, LH, 15, H, 1,-1, KC_F5,                          { "PF5" } },
        !           843:        {  81, LH, 15, H, 1,-1, KC_F6,                          { "PF6" } },
        !           844:        {  96, LH, 15, H, 1,-1, KC_F7,                          { "PF7" } },
        !           845:        { 111, LH, 15, H, 1,-1, KC_F8,                          { "PF8" } },
        !           846:        { 126, LH, 15, H, 1,-1, KC_F9,                          { "PF9" } },
        !           847:        { 141, LH, 15, H, 1,-1, KC_F10,                         { "PF10" } },
        !           848:        { 210, LH+1, 14, H-2, 1,-1, KC_buzzer,          { "Buzzer" } },
1.1.1.4   root      849: 
                    850:        {   2, L1, 12, H, 1,-1, KC_ESC,                         { "ESC" } },
                    851:        {  14, L1, 10, H, 0,-1, KC_1,                           { "1",  "!" } },
                    852:        {  24, L1, 10, H, 0,-1, KC_2,                           { "2",  "\"" } },
                    853:        {  34, L1, 10, H, 0,-1, KC_3,                           { "3",  "#" } },
                    854:        {  44, L1, 10, H, 0,-1, KC_4,                           { "4",  "$" } },
                    855:        {  54, L1, 10, H, 0,-1, KC_5,                           { "5",  "%" } },
                    856:        {  64, L1, 10, H, 0,-1, KC_6,                           { "6",  "&" } },
                    857:        {  74, L1, 10, H, 0,-1, KC_7,                           { "7",  "'" } },
                    858:        {  84, L1, 10, H, 0,-1, KC_8,                           { "8",  "(" } },
                    859:        {  94, L1, 10, H, 0,-1, KC_9,                           { "9",  ")" } },
                    860:        { 104, L1, 10, H, 0,-1, KC_0,                           { "0",  " " } },
                    861:        { 114, L1, 10, H, 0,-1, KC_minus,                       { "-",  "=" } },
                    862:        { 124, L1, 10, H, 0,-1, KC_circum,                      { "^",  "~" } },
                    863:        { 134, L1, 10, H, 0,-1, KC_backslash,           { "\\", "|" } },
                    864:        { 144, L1, 12, H, 1,-1, KC_BS,                          { "BS" } },
                    865: 
                    866:        {   2, L2, 17, H, 1,-1, KC_TAB,                         { "TAB" } },
                    867:        {  19, L2, 10, H, 0,-1, KC_Q,                           { "q",  "Q" } },
                    868:        {  29, L2, 10, H, 0,-1, KC_W,                           { "w",  "W" } },
                    869:        {  39, L2, 10, H, 0,-1, KC_E,                           { "e",  "E" } },
                    870:        {  49, L2, 10, H, 0,-1, KC_R,                           { "r",  "R" } },
                    871:        {  59, L2, 10, H, 0,-1, KC_T,                           { "t",  "T" } },
                    872:        {  69, L2, 10, H, 0,-1, KC_Y,                           { "y",  "Y" } },
                    873:        {  79, L2, 10, H, 0,-1, KC_U,                           { "u",  "U" } },
                    874:        {  89, L2, 10, H, 0,-1, KC_I,                           { "i",  "I" } },
                    875:        {  99, L2, 10, H, 0,-1, KC_O,                           { "o",  "O" } },
                    876:        { 109, L2, 10, H, 0,-1, KC_P,                           { "p",  "P" } },
                    877:        { 119, L2, 10, H, 0,-1, KC_at,                          { "@",  "`" } },
                    878:        { 129, L2, 10, H, 0,-1, KC_bracketleft,         { "[",  "{" } },
                    879: 
                    880:        {   2, L3, 20, H, 1,-1, KC_CTRL,                        { "CTRL" } },
                    881:        {  22, L3, 10, H, 0,-1, KC_A,                           { "a",  "A" } },
                    882:        {  32, L3, 10, H, 0,-1, KC_S,                           { "s",  "S" } },
                    883:        {  42, L3, 10, H, 0,-1, KC_D,                           { "d",  "D" } },
                    884:        {  52, L3, 10, H, 0,-1, KC_F,                           { "f",  "F" } },
                    885:        {  62, L3, 10, H, 0,-1, KC_G,                           { "g",  "G" } },
                    886:        {  72, L3, 10, H, 0,-1, KC_H,                           { "h",  "H" } },
                    887:        {  82, L3, 10, H, 0,-1, KC_J,                           { "j",  "J" } },
                    888:        {  92, L3, 10, H, 0,-1, KC_K,                           { "k",  "K" } },
                    889:        { 102, L3, 10, H, 0,-1, KC_L,                           { "l",  "L" } },
                    890:        { 112, L3, 10, H, 0,-1, KC_semicolon,           { ";",  "+" } },
                    891:        { 122, L3, 10, H, 0,-1, KC_colon,                       { ":",  "*" } },
                    892:        { 132, L3, 10, H, 0,-1, KC_bracketright,        { "]",  "}" } },
                    893: 
                    894:        {   2, L4, 25, H, 1,-1, KC_SHIFT_L,                     { "SHIFT" } },
                    895:        {  27, L4, 10, H, 0,-1, KC_Z,                           { "z",  "Z" } },
                    896:        {  37, L4, 10, H, 0,-1, KC_X,                           { "x",  "X" } },
                    897:        {  47, L4, 10, H, 0,-1, KC_C,                           { "c",  "C" } },
                    898:        {  57, L4, 10, H, 0,-1, KC_V,                           { "v",  "V" } },
                    899:        {  67, L4, 10, H, 0,-1, KC_B,                           { "b",  "B" } },
                    900:        {  77, L4, 10, H, 0,-1, KC_N,                           { "n",  "N" } },
                    901:        {  87, L4, 10, H, 0,-1, KC_M,                           { "m",  "M" } },
                    902:        {  97, L4, 10, H, 0,-1, KC_comma,                       { ",",  "<" } },
                    903:        { 107, L4, 10, H, 0,-1, KC_period,                      { ".",  ">" } },
                    904:        { 117, L4, 10, H, 0,-1, KC_slash,                       { "/",  "?" } },
                    905:        { 127, L4, 10, H, 0,-1, KC_underscore,          { " ",  "_" } },
                    906:        { 137, L4, 19, H, 1,-1, KC_SHIFT_R,                     { "SHIFT" } },
                    907: 
                    908:        {   2, L5, 20, H, 1,-1, KC_VALID,                       { "確定" } },
                    909:        {  22, L5, 10, H, 1,-1, KC_SF,                          { "前面" } },
                    910:        {  32, L5, 10, H, 1, 1, KC_CAPS,                        { "CAP" } },
                    911:        {  42, L5, 80, H, 0,-1, KC_space,                       { " " } },
                    912:        { 122, L5, 10, H, 1, 0, KC_kana,                        { "かな" } },
                    913:        { 132, L5, 24, H, 1,-1, KC_XFER,                        { "変換" } },
1.1       root      914: 
                    915:        // カーソルキー島
1.1.1.4   root      916:        { 160, L1, 10, H, 1,-1, KC_PF11,                        { "消去" } },
                    917:        { 170, L1, 10, H, 1,-1, KC_PF12,                        { "呼出" } },
                    918:        { 160, L2, 10, H, 1,-1, KC_PF13,                        { "文節\n←" } },
                    919:        { 170, L2, 10, H, 1,-1, KC_PF14,                        { "文節\n→" } },
                    920:        { 160, L3, 20, H, 1,-1, KC_up,                          { "↑" } },
                    921:        { 160, L4, 10, H, 1,-1, KC_left,                        { "←" } },
                    922:        { 170, L4, 10, H, 1,-1, KC_right,                       { "→" } },
                    923:        { 160, L5, 20, H, 1,-1, KC_down,                        { "↓" } },
1.1       root      924: 
                    925:        // テンキー島
1.1.1.4   root      926:        { 184, L1, 10, H, 1,-1, KC_DEL,                         { "DEL" } },
                    927:        { 194, L1, 10, H, 1,-1, KC_PAD_plus,            { "+" } },
                    928:        { 204, L1, 10, H, 1,-1, KC_PAD_minus,           { "-" } },
                    929:        { 214, L1, 10, H, 1,-1, KC_PAD_multiply,        { "*" } },
                    930: 
                    931:        { 184, L2, 10, H, 0,-1, KC_PAD_7,                       { "7" } },
                    932:        { 194, L2, 10, H, 0,-1, KC_PAD_8,                       { "8" } },
                    933:        { 204, L2, 10, H, 0,-1, KC_PAD_9,                       { "9" } },
                    934:        { 214, L2, 10, H, 1,-1, KC_PAD_divide,          { "/" } },
                    935: 
                    936:        { 184, L3, 10, H, 0,-1, KC_PAD_4,                       { "4" } },
                    937:        { 194, L3, 10, H, 0,-1, KC_PAD_5,                       { "5" } },
                    938:        { 204, L3, 10, H, 0,-1, KC_PAD_6,                       { "6" } },
                    939:        { 214, L3, 10, H, 1,-1, KC_PAD_equal,           { "=" } },
                    940: 
                    941:        { 184, L4, 10, H, 0,-1, KC_PAD_1,                       { "1" } },
                    942:        { 194, L4, 10, H, 0,-1, KC_PAD_2,                       { "2" } },
                    943:        { 204, L4, 10, H, 0,-1, KC_PAD_3,                       { "3" } },
                    944:        { 214, L4, 10, H, 1,-1, KC_PAD_comma,           { "," } },
                    945: 
                    946:        { 184, L5, 10, H, 0,-1, KC_PAD_0,                       { "0" } },
                    947:        { 194, L5, 10, H, 0,-1, KC_PAD_decimal,         { "." } },
                    948:        { 204, L5, 20, H, 1,-1, KC_PAD_enter,           { EnterMark } },
1.1       root      949: 
                    950:        // Enter だけ矩形でないので別処理するが
                    951:        // この構造体には全部のキー情報が統一的に並んでいるほうがよかろう。
1.1.1.4   root      952:        { -1, -1, -1, -1, 1,-1, KC_enter,                       { EnterMark } },
1.1       root      953: };
                    954: 
                    955: 
                    956: //
1.1.1.16! root      957: // LUNA-88K ソフトウェアキーボード (パネル)
        !           958: //
        !           959: 
        !           960: // コンストラクタ
        !           961: WXLuna88kSoftKeyPanel::WXLuna88kSoftKeyPanel(wxWindow *parent)
        !           962:        : inherited(parent, keydata, 226, 54)
        !           963: {
        !           964:        InitLunaCommon();
        !           965: }
        !           966: 
        !           967: // デストラクタ
        !           968: WXLuna88kSoftKeyPanel::~WXLuna88kSoftKeyPanel()
        !           969: {
        !           970: }
        !           971: 
        !           972: // LED を描画する。
        !           973: // 独立 LED なので戻り値は使わないので 0 でいい。
        !           974: int
        !           975: WXLuna88kSoftKeyPanel::DrawLED(const keydata_t& basekey)
        !           976: {
        !           977:        const std::vector<bool>& led = keyboard->GetLED();
        !           978:        Color fg_backup;
        !           979:        Color bg_backup;
        !           980:        Color fg;
        !           981:        TA attr;
        !           982: 
        !           983:        fg_backup = GetTextForeColor();
        !           984:        bg_backup = GetTextBackColor();
        !           985: 
        !           986:        if (led[basekey.led]) {
        !           987:                // 点灯時、文字は LED 色でボールド。
        !           988:                fg = color.LED[0];
        !           989:                attr = TA::Bold;
        !           990:        } else {
        !           991:                // 消灯時、文字はグレーで通常体。
        !           992:                fg = UD_GREY;
        !           993:                attr = TA::Normal;
        !           994:        }
        !           995:        SetTextForeColor(fg);
        !           996:        // 背景はキーの押し下げ状態ではなく常にキー開放色のままとする。
        !           997:        SetTextBackColor(color.Keytop[1][0]);
        !           998: 
        !           999:        // LUNA-88K キーボードは LED 入りキーではなく、別のところに
        !          1000:        // LED だけがあるタイプ。(今どきの PC キーボードに近い)
        !          1001:        static const keydata_t led_caps = {
        !          1002:                184, L0+1, 10, H-2, 1, -1, 0, { "Caps" }
        !          1003:        };
        !          1004:        static const keydata_t led_kana = {
        !          1005:                194, L0+1, 10, H-2, 1, -1, 0, { "Kana" }
        !          1006:        };
        !          1007:        const keydata_t& key = (basekey.keycode == KC_CAPS)
        !          1008:                ? led_caps
        !          1009:                : led_kana;
        !          1010: 
        !          1011:        // 枠を描画。
        !          1012:        // 2つの LED で枠が重なるため状態によって色を変えられない。
        !          1013:        DrawKeyBox(key, color.Keytop[1][0], UD_GREY);
        !          1014: 
        !          1015:        // ラベルをセンタリング。
        !          1016:        const char *disp = key.disp[0];
        !          1017:        int x = key.x + (key.w - strlen(disp) * 2) / 2;
        !          1018:        int y = key.y + (key.h - 4) / 2;
        !          1019: 
        !          1020:        // ラベルを描画。
        !          1021:        x = x * unit + 1;
        !          1022:        y = y * unit + 1;
        !          1023:        DrawStringSJIS(x, y, disp, attr);
        !          1024: 
        !          1025:        // 前景色、背景色を元に戻す。
        !          1026:        SetTextForeColor(fg_backup);
        !          1027:        SetTextBackColor(bg_backup);
        !          1028: 
        !          1029:        // 元のキーの文字描画オフセットは無し。
        !          1030:        return 0;
        !          1031: }
        !          1032: 
        !          1033: 
        !          1034: // キーデータ
        !          1035: /*static*/ std::vector<keydata_t>
        !          1036: WXLuna88kSoftKeyPanel::keydata {
        !          1037:        //                +---- キートップの色(1:濃)
        !          1038:        //                |  +- 0 以上なら LED 番号
        !          1039:        //  X   Y   W  H  C  L  KeyCode                         通常  SHIFT
        !          1040:        {   2, L0, 10, H, 1,-1, KC_F1,                          { "PF1" } },
        !          1041:        {  12, L0, 10, H, 1,-1, KC_F2,                          { "PF2" } },
        !          1042:        {  22, L0, 10, H, 1,-1, KC_F3,                          { "PF3" } },
        !          1043:        {  32, L0, 10, H, 1,-1, KC_F4,                          { "PF4" } },
        !          1044:        {  42, L0, 10, H, 1,-1, KC_F5,                          { "PF5" } },
        !          1045:        {  52, L0, 10, H, 1,-1, KC_F6,                          { "PF6" } },
        !          1046:        {  62, L0, 10, H, 1,-1, KC_F7,                          { "PF7" } },
        !          1047:        {  72, L0, 10, H, 1,-1, KC_F8,                          { "PF8" } },
        !          1048:        {  82, L0, 10, H, 1,-1, KC_F9,                          { "PF9" } },
        !          1049:        {  92, L0, 10, H, 1,-1, KC_F10,                         { "PF10" } },
        !          1050:        { 102, L0, 10, H, 1,-1, KC_PF11,                        { "消去" } },
        !          1051:        { 112, L0, 10, H, 1,-1, KC_PF12,                        { "呼出" } },
        !          1052:        { 122, L0, 10, H, 1,-1, KC_PF13,                        { "文節\n←" } },
        !          1053:        { 132, L0, 10, H, 1,-1, KC_PF14,                        { "文節\n→" } },
        !          1054:        { 142, L0, 14, H, 1,-1, KC_BS,                          { "BS" } },
        !          1055: 
        !          1056:        { 210, L0+1, 14, H-2, 1,-1, KC_buzzer,          { "Buzzer" } },
        !          1057: 
        !          1058:        {   2, L1, 12, H, 1,-1, KC_ESC,                         { "ESC" } },
        !          1059:        {  14, L1, 10, H, 0,-1, KC_1,                           { "1",  "!" } },
        !          1060:        {  24, L1, 10, H, 0,-1, KC_2,                           { "2",  "\"" } },
        !          1061:        {  34, L1, 10, H, 0,-1, KC_3,                           { "3",  "#" } },
        !          1062:        {  44, L1, 10, H, 0,-1, KC_4,                           { "4",  "$" } },
        !          1063:        {  54, L1, 10, H, 0,-1, KC_5,                           { "5",  "%" } },
        !          1064:        {  64, L1, 10, H, 0,-1, KC_6,                           { "6",  "&" } },
        !          1065:        {  74, L1, 10, H, 0,-1, KC_7,                           { "7",  "'" } },
        !          1066:        {  84, L1, 10, H, 0,-1, KC_8,                           { "8",  "(" } },
        !          1067:        {  94, L1, 10, H, 0,-1, KC_9,                           { "9",  ")" } },
        !          1068:        { 104, L1, 10, H, 0,-1, KC_0,                           { "0",  " " } },
        !          1069:        { 114, L1, 10, H, 0,-1, KC_minus,                       { "-",  "=" } },
        !          1070:        { 124, L1, 10, H, 0,-1, KC_circum,                      { "^",  "~" } },
        !          1071:        { 134, L1, 10, H, 0,-1, KC_backslash,           { "\\", "|" } },
        !          1072:        { 144, L1, 12, H, 1,-1, KC_DEL,                         { "DEL" } },
        !          1073: 
        !          1074:        {   2, L2, 17, H, 1,-1, KC_TAB,                         { "TAB" } },
        !          1075:        {  19, L2, 10, H, 0,-1, KC_Q,                           { "q",  "Q" } },
        !          1076:        {  29, L2, 10, H, 0,-1, KC_W,                           { "w",  "W" } },
        !          1077:        {  39, L2, 10, H, 0,-1, KC_E,                           { "e",  "E" } },
        !          1078:        {  49, L2, 10, H, 0,-1, KC_R,                           { "r",  "R" } },
        !          1079:        {  59, L2, 10, H, 0,-1, KC_T,                           { "t",  "T" } },
        !          1080:        {  69, L2, 10, H, 0,-1, KC_Y,                           { "y",  "Y" } },
        !          1081:        {  79, L2, 10, H, 0,-1, KC_U,                           { "u",  "U" } },
        !          1082:        {  89, L2, 10, H, 0,-1, KC_I,                           { "i",  "I" } },
        !          1083:        {  99, L2, 10, H, 0,-1, KC_O,                           { "o",  "O" } },
        !          1084:        { 109, L2, 10, H, 0,-1, KC_P,                           { "p",  "P" } },
        !          1085:        { 119, L2, 10, H, 0,-1, KC_at,                          { "@",  "`" } },
        !          1086:        { 129, L2, 10, H, 0,-1, KC_bracketleft,         { "[",  "{" } },
        !          1087: 
        !          1088:        {   2, L3, 20, H, 1,-1, KC_CTRL,                        { "CTRL" } },
        !          1089:        {  22, L3, 10, H, 0,-1, KC_A,                           { "a",  "A" } },
        !          1090:        {  32, L3, 10, H, 0,-1, KC_S,                           { "s",  "S" } },
        !          1091:        {  42, L3, 10, H, 0,-1, KC_D,                           { "d",  "D" } },
        !          1092:        {  52, L3, 10, H, 0,-1, KC_F,                           { "f",  "F" } },
        !          1093:        {  62, L3, 10, H, 0,-1, KC_G,                           { "g",  "G" } },
        !          1094:        {  72, L3, 10, H, 0,-1, KC_H,                           { "h",  "H" } },
        !          1095:        {  82, L3, 10, H, 0,-1, KC_J,                           { "j",  "J" } },
        !          1096:        {  92, L3, 10, H, 0,-1, KC_K,                           { "k",  "K" } },
        !          1097:        { 102, L3, 10, H, 0,-1, KC_L,                           { "l",  "L" } },
        !          1098:        { 112, L3, 10, H, 0,-1, KC_semicolon,           { ";",  "+" } },
        !          1099:        { 122, L3, 10, H, 0,-1, KC_colon,                       { ":",  "*" } },
        !          1100:        { 132, L3, 10, H, 0,-1, KC_bracketright,        { "]",  "}" } },
        !          1101: 
        !          1102:        {   2, L4, 25, H, 1,-1, KC_SHIFT_L,                     { "SHIFT" } },
        !          1103:        {  27, L4, 10, H, 0,-1, KC_Z,                           { "z",  "Z" } },
        !          1104:        {  37, L4, 10, H, 0,-1, KC_X,                           { "x",  "X" } },
        !          1105:        {  47, L4, 10, H, 0,-1, KC_C,                           { "c",  "C" } },
        !          1106:        {  57, L4, 10, H, 0,-1, KC_V,                           { "v",  "V" } },
        !          1107:        {  67, L4, 10, H, 0,-1, KC_B,                           { "b",  "B" } },
        !          1108:        {  77, L4, 10, H, 0,-1, KC_N,                           { "n",  "N" } },
        !          1109:        {  87, L4, 10, H, 0,-1, KC_M,                           { "m",  "M" } },
        !          1110:        {  97, L4, 10, H, 0,-1, KC_comma,                       { ",",  "<" } },
        !          1111:        { 107, L4, 10, H, 0,-1, KC_period,                      { ".",  ">" } },
        !          1112:        { 117, L4, 10, H, 0,-1, KC_slash,                       { "/",  "?" } },
        !          1113:        { 127, L4, 10, H, 0,-1, KC_underscore,          { " ",  "_" } },
        !          1114:        { 137, L4, 19, H, 1,-1, KC_SHIFT_R,                     { "SHIFT" } },
        !          1115: 
        !          1116:        {   2, L5, 10, H, 1,-1, KC_SF,                          { "META" } },
        !          1117:        {  12, L5, 20, H, 1,-1, KC_VALID,                       { "確定" } },
        !          1118:        {  32, L5, 10, H, 1, 1, KC_CAPS,                        { "CAPS" } },
        !          1119:        {  42, L5, 80, H, 0,-1, KC_space,                       { " " } },
        !          1120:        { 122, L5, 10, H, 1, 0, KC_kana,                        { "かな" } },
        !          1121:        { 132, L5, 24, H, 1,-1, KC_XFER,                        { "変換" } },
        !          1122: 
        !          1123:        // カーソルキー島
        !          1124:        { 159, L1, 11, H, 1,-1, KC_INS,                         { "INS" } },
        !          1125:        { 170, L1, 11, H, 1,-1, KC_COPY,                        { "COPY" } },
        !          1126:        { 159, L2, 11, H, 1,-1, KC_CUT,                         { "CUT" } },
        !          1127:        { 170, L2, 11, H, 1,-1, KC_PASTE,                       { "PASTE" } },
        !          1128:        { 159, L3, 22, H, 1,-1, KC_up,                          { "↑" } },
        !          1129:        { 159, L4, 11, H, 1,-1, KC_left,                        { "←" } },
        !          1130:        { 170, L4, 11, H, 1,-1, KC_right,                       { "→" } },
        !          1131:        { 159, L5, 22, H, 1,-1, KC_down,                        { "↓" } },
        !          1132: 
        !          1133:        // テンキー島
        !          1134:        { 184, L1, 10, H, 1,-1, KC_HOME,                        { "HOME" } },
        !          1135:        { 194, L1, 10, H, 1,-1, KC_PAD_plus,            { "+" } },
        !          1136:        { 204, L1, 10, H, 1,-1, KC_PAD_minus,           { "-" } },
        !          1137:        { 214, L1, 10, H, 1,-1, KC_PAD_multiply,        { "*" } },
        !          1138: 
        !          1139:        { 184, L2, 10, H, 0,-1, KC_PAD_7,                       { "7" } },
        !          1140:        { 194, L2, 10, H, 0,-1, KC_PAD_8,                       { "8" } },
        !          1141:        { 204, L2, 10, H, 0,-1, KC_PAD_9,                       { "9" } },
        !          1142:        { 214, L2, 10, H, 1,-1, KC_PAD_divide,          { "/" } },
        !          1143: 
        !          1144:        { 184, L3, 10, H, 0,-1, KC_PAD_4,                       { "4" } },
        !          1145:        { 194, L3, 10, H, 0,-1, KC_PAD_5,                       { "5" } },
        !          1146:        { 204, L3, 10, H, 0,-1, KC_PAD_6,                       { "6" } },
        !          1147:        { 214, L3, 10, H, 1,-1, KC_PAD_equal,           { "=" } },
        !          1148: 
        !          1149:        { 184, L4, 10, H, 0,-1, KC_PAD_1,                       { "1" } },
        !          1150:        { 194, L4, 10, H, 0,-1, KC_PAD_2,                       { "2" } },
        !          1151:        { 204, L4, 10, H, 0,-1, KC_PAD_3,                       { "3" } },
        !          1152:        { 214, L4, 10, H, 1,-1, KC_PAD_comma,           { "," } },
        !          1153: 
        !          1154:        { 184, L5, 10, H, 0,-1, KC_PAD_0,                       { "0" } },
        !          1155:        { 194, L5, 10, H, 0,-1, KC_PAD_decimal,         { "." } },
        !          1156:        { 204, L5, 20, H, 1,-1, KC_PAD_enter,           { EnterMark } },
        !          1157: 
        !          1158:        // Enter だけ矩形でないので別処理するが
        !          1159:        // この構造体には全部のキー情報が統一的に並んでいるほうがよかろう。
        !          1160:        { -1, -1, -1, -1, 1,-1, KC_enter,                       { EnterMark } },
        !          1161: };
        !          1162: 
        !          1163: 
        !          1164: //
1.1.1.4   root     1165: // X68k ソフトウェアキーボード (パネル)
                   1166: //
                   1167: 
                   1168: // コンストラクタ
                   1169: WXX68kSoftKeyPanel::WXX68kSoftKeyPanel(wxWindow *parent)
1.1.1.6   root     1170:        : inherited(parent, keydata, 235, 54)
1.1.1.4   root     1171: {
                   1172:        // X68k では SRAM 設定に同期させる。
1.1.1.13  root     1173:        const auto sram = GetSRAMDevice();
1.1.1.14  root     1174:        uint8 sw = sram->Peek1(0xed0059);
1.1.1.11  root     1175:        gFontManager->SetGlyph5C((sw & 0x01));
                   1176:        gFontManager->SetGlyph7E((sw & 0x02));
                   1177:        gFontManager->SetGlyph7C((sw & 0x04));
1.1.1.4   root     1178: 
                   1179:        // とりあえず黒のみ
1.1.1.11  root     1180:        color.Background        = Color(50, 50, 53);
                   1181:        color.Text                      = UD_WHITE;
                   1182:        color.Border            = UD_BLACK;
1.1.1.9   root     1183:        color.LED[0]            = UD_RED;
                   1184:        color.LED[1]            = UD_YELLOW_GREEN;
1.1.1.11  root     1185:        color.Keytop[0][0]      = UD_BLACK;
1.1.1.9   root     1186:        InitColorKeytop(1);
1.1.1.11  root     1187: 
                   1188:        SetBitmapBGColor(color.Background);
1.1.1.13  root     1189:        Fill();
1.1.1.4   root     1190: }
                   1191: 
                   1192: // デストラクタ
                   1193: WXX68kSoftKeyPanel::~WXX68kSoftKeyPanel()
                   1194: {
                   1195: }
                   1196: 
                   1197: // LED を描画して刻印描画のための y offset を返す。
                   1198: int
1.1.1.11  root     1199: WXX68kSoftKeyPanel::DrawLED(const keydata_t& key)
1.1.1.4   root     1200: {
1.1.1.13  root     1201:        const std::vector<bool>& led = keyboard->GetLED();
1.1.1.11  root     1202:        Color fg;
                   1203:        Color bg;
1.1.1.4   root     1204: 
                   1205:        // 色を選択
                   1206:        // idx  刻印  色
                   1207:        // ----------------
                   1208:        //  0   かな  赤
                   1209:        //  1   ローマ       赤
                   1210:        //  2   コード       赤
                   1211:        //  3   CAPS    赤
                   1212:        //  4   INS             赤
                   1213:        //  5   ひら  緑
                   1214:        //  6   全角  緑
                   1215:        if (led[key.led]) {
                   1216:                int n = (key.led < 5) ? 0 : 1;
1.1.1.11  root     1217:                fg = color.LED[n];
                   1218:                bg = color.LED[n];
1.1.1.4   root     1219:        } else {
                   1220:                // 消灯時は元のキートップの色で、枠は薄めにしたい
1.1.1.6   root     1221:                // (枠の色は今の所全モデル共通なので ColorPalette に含めていない)
1.1.1.11  root     1222:                fg = UD_GREY;
                   1223:                bg = color.Keytop[key.coltype][0];
1.1.1.4   root     1224:        }
                   1225: 
                   1226:        // LED は中央前方(画面でいうと下)
1.1.1.11  root     1227:        Rect rect((key.x + 3) * unit, (key.y + key.h - 2) * unit,
                   1228:                4 * unit, 2 * unit);
                   1229:        bitmap.FillRect(bg, rect);
                   1230:        bitmap.DrawRect(fg, rect);
1.1.1.4   root     1231: 
                   1232:        // そのため文字は少し上げる
                   1233:        return -1;
                   1234: }
                   1235: 
                   1236: #define HT (H * 2)             // 縦2倍角のキー
                   1237: /*static*/ std::vector<keydata_t>
                   1238: WXX68kSoftKeyPanel::keydata {
                   1239:        //                   +- 0以上なら LED 番号
                   1240:        //  X   Y   W  H  C  L  KeyCode                         通常  SHIFT
1.1.1.16! root     1241:        {   2, LH, 10, H, 0,-1, KC_BREAK,                       { "\x4\x5\x6\x7" } },
        !          1242:        {  15, LH, 10, H, 0,-1, KC_COPY,                        { "COPY" } },
        !          1243:        {  29, L0, 12, 6, 0,-1, KC_F1,                          { "F1" } },
        !          1244:        {  41, L0, 12, 6, 0,-1, KC_F2,                          { "F2" } },
        !          1245:        {  53, L0, 12, 6, 0,-1, KC_F3,                          { "F3" } },
        !          1246:        {  65, L0, 12, 6, 0,-1, KC_F4,                          { "F4" } },
        !          1247:        {  77, L0, 13, 6, 0,-1, KC_F5,                          { "F5" } },
        !          1248:        {  94, L0, 13, 6, 0,-1, KC_F6,                          { "F6" } },
        !          1249:        { 106, L0, 12, 6, 0,-1, KC_F7,                          { "F7" } },
        !          1250:        { 118, L0, 12, 6, 0,-1, KC_F8,                          { "F8" } },
        !          1251:        { 130, L0, 12, 6, 0,-1, KC_F9,                          { "F9" } },
        !          1252:        { 142, L0, 13, 6, 0,-1, KC_F10,                         { "F10" } },
1.1.1.4   root     1253: 
                   1254:        {   2, L1, 10, H, 0,-1, KC_ESC,                         { "ESC" } },
                   1255:        {  12, L1, 10, H, 0,-1, KC_1,                           { "1",  "!" } },
                   1256:        {  22, L1, 10, H, 0,-1, KC_2,                           { "2",  "\"" } },
                   1257:        {  32, L1, 10, H, 0,-1, KC_3,                           { "3",  "#" } },
                   1258:        {  42, L1, 10, H, 0,-1, KC_4,                           { "4",  "$" } },
                   1259:        {  52, L1, 10, H, 0,-1, KC_5,                           { "5",  "%" } },
                   1260:        {  62, L1, 10, H, 0,-1, KC_6,                           { "6",  "&" } },
                   1261:        {  72, L1, 10, H, 0,-1, KC_7,                           { "7",  "'" } },
                   1262:        {  82, L1, 10, H, 0,-1, KC_8,                           { "8",  "(" } },
                   1263:        {  92, L1, 10, H, 0,-1, KC_9,                           { "9",  ")" } },
                   1264:        { 102, L1, 10, H, 0,-1, KC_0,                           { "0",  " " } },
                   1265:        { 112, L1, 10, H, 0,-1, KC_minus,                       { "-",  "=" } },
                   1266:        { 122, L1, 10, H, 0,-1, KC_circum,                      { "^",  "~" } },
                   1267:        { 132, L1, 10, H, 0,-1, KC_backslash,           { "\\", "|" } },
                   1268:        { 142, L1, 13, H, 0,-1, KC_BS,                          { "BS" } },
                   1269: 
                   1270:        {   2, L2, 16, H, 0,-1, KC_TAB,                         { "TAB" } },
                   1271:        {  18, L2, 10, H, 0,-1, KC_Q,                           { "q",  "Q" } },
                   1272:        {  28, L2, 10, H, 0,-1, KC_W,                           { "w",  "W" } },
                   1273:        {  38, L2, 10, H, 0,-1, KC_E,                           { "e",  "E" } },
                   1274:        {  48, L2, 10, H, 0,-1, KC_R,                           { "r",  "R" } },
                   1275:        {  58, L2, 10, H, 0,-1, KC_T,                           { "t",  "T" } },
                   1276:        {  68, L2, 10, H, 0,-1, KC_Y,                           { "y",  "Y" } },
                   1277:        {  78, L2, 10, H, 0,-1, KC_U,                           { "u",  "U" } },
                   1278:        {  88, L2, 10, H, 0,-1, KC_I,                           { "i",  "I" } },
                   1279:        {  98, L2, 10, H, 0,-1, KC_O,                           { "o",  "O" } },
                   1280:        { 108, L2, 10, H, 0,-1, KC_P,                           { "p",  "P" } },
                   1281:        { 118, L2, 10, H, 0,-1, KC_at,                          { "@",  "`" } },
                   1282:        { 128, L2, 10, H, 0,-1, KC_bracketleft,         { "[",  "{" } },
                   1283: 
                   1284:        {   2, L3, 19, H, 0,-1, KC_CTRL,                        { "CTRL" } },
                   1285:        {  21, L3, 10, H, 0,-1, KC_A,                           { "a",  "A" } },
                   1286:        {  31, L3, 10, H, 0,-1, KC_S,                           { "s",  "S" } },
                   1287:        {  41, L3, 10, H, 0,-1, KC_D,                           { "d",  "D" } },
                   1288:        {  51, L3, 10, H, 0,-1, KC_F,                           { "f",  "F" } },
                   1289:        {  61, L3, 10, H, 0,-1, KC_G,                           { "g",  "G" } },
                   1290:        {  71, L3, 10, H, 0,-1, KC_H,                           { "h",  "H" } },
                   1291:        {  81, L3, 10, H, 0,-1, KC_J,                           { "j",  "J" } },
                   1292:        {  91, L3, 10, H, 0,-1, KC_K,                           { "k",  "K" } },
                   1293:        { 101, L3, 10, H, 0,-1, KC_L,                           { "l",  "L" } },
                   1294:        { 111, L3, 10, H, 0,-1, KC_semicolon,           { ";",  "+" } },
                   1295:        { 121, L3, 10, H, 0,-1, KC_colon,                       { ":",  "*" } },
                   1296:        { 131, L3, 10, H, 0,-1, KC_bracketright,        { "]",  "}" } },
                   1297: 
1.1.1.6   root     1298:        {   2, L4, 24, H, 0,-1, KC_SHIFT,                       { "SHIFT" } },
1.1.1.4   root     1299:        {  26, L4, 10, H, 0,-1, KC_Z,                           { "z",  "Z" } },
                   1300:        {  36, L4, 10, H, 0,-1, KC_X,                           { "x",  "X" } },
                   1301:        {  46, L4, 10, H, 0,-1, KC_C,                           { "c",  "C" } },
                   1302:        {  56, L4, 10, H, 0,-1, KC_V,                           { "v",  "V" } },
                   1303:        {  66, L4, 10, H, 0,-1, KC_B,                           { "b",  "B" } },
                   1304:        {  76, L4, 10, H, 0,-1, KC_N,                           { "n",  "N" } },
                   1305:        {  86, L4, 10, H, 0,-1, KC_M,                           { "m",  "M" } },
                   1306:        {  96, L4, 10, H, 0,-1, KC_comma,                       { ",",  "<" } },
                   1307:        { 106, L4, 10, H, 0,-1, KC_period,                      { ".",  ">" } },
                   1308:        { 116, L4, 10, H, 0,-1, KC_slash,                       { "/",  "?" } },
                   1309:        { 126, L4, 10, H, 0,-1, KC_underscore,          { " ",  "_" } },
1.1.1.6   root     1310:        { 136, L4, 19, H, 0,-1, KC_SHIFT,                       { "SHIFT" } },
1.1.1.4   root     1311: 
                   1312:        {  21, L5, 10, H, 0, 5, KC_hira,                        { "ひら" } },
                   1313:        {  31, L5, 12, H, 0,-1, KC_XF1,                         { "XF1" } },
                   1314:        {  43, L5, 13, H, 0,-1, KC_XF2,                         { "XF2" } },
                   1315:        {  56, L5, 36, H, 0,-1, KC_space,                       { " " } },
                   1316:        {  92, L5, 12, H, 0,-1, KC_XF3,                         { "XF3" } },
                   1317:        { 104, L5, 12, H, 0,-1, KC_XF4,                         { "XF4" } },
                   1318:        { 116, L5, 12, H, 0,-1, KC_XF5,                         { "XF5" } },
                   1319:        { 128, L5, 10, H, 0, 6, KC_zenkaku,                     { "全角" } },
                   1320: 
                   1321:        // カーソルキー島
                   1322:        { 159, L0, 10, H, 0, 0, KC_kana,                        { "かな" } },
                   1323:        { 169, L0, 10, H, 0, 1, KC_romaji,                      { "ローマ" } },
                   1324:        { 179, L0, 10, H, 0, 2, KC_code,                        { "コード" } },
                   1325:        { 159, L1, 10, H, 0,-1, KC_HOME,                        { "HOME" } },
                   1326:        { 169, L1, 10, H, 0, 4, KC_INS,                         { "INS" } },
                   1327:        { 179, L1, 10, H, 0,-1, KC_DEL,                         { "DEL" } },
                   1328:        { 159, L2, 10, H, 0,-1, KC_ROLLUP,                      { "ROLL\n UP" } },
                   1329:        { 169, L2, 10, H, 0,-1, KC_ROLLDOWN,            { "ROLL\nDOWN" } },
                   1330:        { 179, L2, 10, H, 0,-1, KC_UNDO,                        { "UNDO" } },
                   1331:        { 169, L3, 10, H, 0,-1, KC_up,                          { "↑" } },
                   1332:        { 159, L3, 10, HT,0,-1, KC_left,                        { "←" } },
                   1333:        { 179, L3, 10, HT,0,-1, KC_right,                       { "→" } },
                   1334:        { 169, L4, 10, H, 0,-1, KC_down,                        { "↓" } },
                   1335:        { 159, L5, 15, H, 0,-1, KC_OPT1,                        { "OPT.1" } },
                   1336:        { 174, L5, 15, H, 0,-1, KC_OPT2,                        { "OPT.2" } },
                   1337: 
                   1338:        // テンキー島
                   1339:        { 193, L0, 10, H, 0, 3, KC_CAPS,                        { "CAPS" } },
                   1340:        { 203, L0, 10, H, 0,-1, KC_kigou,                       { "記号" } },
                   1341:        { 213, L0, 10, H, 0,-1, KC_touroku,                     { "登録" } },
                   1342:        { 223, L0, 10, H, 0,-1, KC_HELP,                        { "HELP" } },
                   1343:        { 193, L1, 10, H, 0,-1, KC_PAD_CLR,                     { "CLR" } },
                   1344:        { 203, L1, 10, H, 0,-1, KC_PAD_divide,          { "/" } },
                   1345:        { 213, L1, 10, H, 0,-1, KC_PAD_multiply,        { "*" } },
                   1346:        { 223, L1, 10, H, 0,-1, KC_PAD_minus,           { "-" } },
                   1347:        { 193, L2, 10, H, 0,-1, KC_PAD_7,                       { "7" } },
                   1348:        { 203, L2, 10, H, 0,-1, KC_PAD_8,                       { "8" } },
                   1349:        { 213, L2, 10, H, 0,-1, KC_PAD_9,                       { "9" } },
                   1350:        { 223, L2, 10, H, 0,-1, KC_PAD_plus,            { "+" } },
                   1351:        { 193, L3, 10, H, 0,-1, KC_PAD_4,                       { "4" } },
                   1352:        { 203, L3, 10, H, 0,-1, KC_PAD_5,                       { "5" } },
                   1353:        { 213, L3, 10, H, 0,-1, KC_PAD_6,                       { "6" } },
                   1354:        { 223, L3, 10, H, 0,-1, KC_PAD_equal,           { "=" } },
                   1355:        { 193, L4, 10, H, 0,-1, KC_PAD_1,                       { "1" } },
                   1356:        { 203, L4, 10, H, 0,-1, KC_PAD_2,                       { "2" } },
                   1357:        { 213, L4, 10, H, 0,-1, KC_PAD_3,                       { "3" } },
1.1.1.13  root     1358:        { 223, L4, 10, HT,0,-1, KC_PAD_enter,           { "\xb\xc\xe\xf" } },
1.1.1.4   root     1359:        { 193, L5, 10, H, 0,-1, KC_PAD_0,                       { "0" } },
                   1360:        { 203, L5, 10, H, 0,-1, KC_PAD_comma,           { "," } },
                   1361:        { 213, L5, 10, H, 0,-1, KC_PAD_decimal,         { "." } },
                   1362: 
                   1363:        // Enter だけ矩形でないので別処理するが
                   1364:        // この構造体には全部のキー情報が統一的に並んでいるほうがよかろう。
                   1365:        { -1, -1, -1, -1, 0,-1, KC_enter,                       { EnterMark } },
                   1366: };
                   1367: 
1.1.1.16! root     1368: 
1.1.1.4   root     1369: //
1.1.1.6   root     1370: // ソフトウェアキーボード (ウィンドウ)
1.1.1.4   root     1371: //
                   1372: 
                   1373: // コンストラクタ
1.1.1.12  root     1374: WXSoftKeyWindow::WXSoftKeyWindow(wxWindow *parent, VMType vmtype)
1.1.1.7   root     1375:        : inherited(parent, wxID_ANY, _("Software Keyboard"))
1.1.1.4   root     1376: {
1.1.1.16! root     1377:        switch (vmtype) {
        !          1378:         case VMType::X68030:
1.1.1.15  root     1379:                new WXX68kSoftKeyPanel(this);
1.1.1.16! root     1380:                break;
        !          1381:         case VMType::LUNA1:
        !          1382:                new WXLuna1SoftKeyPanel(this);
        !          1383:                break;
        !          1384:         case VMType::LUNA88K:
        !          1385:                new WXLuna88kSoftKeyPanel(this);
        !          1386:                break;
        !          1387:         default:
        !          1388:                assert(false);
1.1.1.6   root     1389:        }
1.1.1.4   root     1390: 
1.1.1.15  root     1391:        Fit();
1.1.1.4   root     1392: }
                   1393: 
                   1394: // デストラクタ
1.1.1.6   root     1395: WXSoftKeyWindow::~WXSoftKeyWindow()
1.1.1.4   root     1396: {
                   1397: }

unix.superglobalmegacorp.com

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