Annotation of nono/wx/wxmainview.cpp, revision 1.1.1.8

1.1       root        1: //
                      2: // nono
1.1.1.4   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
1.1.1.4   root        7: #include "wxmainview.h"
1.1       root        8: #include "keyboard.h"
                      9: #include "renderer.h"
                     10: #include "scheduler.h"
                     11: #include <wx/region.h>
                     12: #include <wx/event.h>
                     13: 
                     14: //#define KEYDEBUG 1
1.1.1.2   root       15: //#define MOUSEDEBUG 1
1.1       root       16: 
                     17: #if defined(KEYDEBUG)
1.1.1.2   root       18: #define DKPRINTF(...)  printf(__VA_ARGS__)
1.1       root       19: #else
1.1.1.2   root       20: #define DKPRINTF(...) /**/
                     21: #endif
                     22: 
                     23: #if defined(MOUSEDEBUG)
                     24: #define DMPRINTF(...)  printf(__VA_ARGS__)
                     25: #else
                     26: #define DMPRINTF(...) /**/
1.1       root       27: #endif
                     28: 
                     29: // 再描画矩形の指定方法について。
                     30: // DoRefresh() にて、VM スレッドが自発的に画面を更新する際は、
                     31: // パフォーマンスの観点からも更新矩形だけを再描画すべき。
                     32: // これを wxWidgets に指示するのが wxWindow::Refresh{,Rect}() であるが
                     33: // 一部のプラットフォームではこれを呼び出すと、アプリケーションウィンドウ
                     34: // 全体がささってしまい、MainView だけでなくメニューバーも含めたすべてが
                     35: // 再描画できなくなってしまう。仕方がないので、これらのプラットフォームでは
                     36: // Refresh{,Rect}() を呼ばず、再描画矩形を画面全体として運用する。
                     37: // ちょっと無駄なだけなので (動かないことに比べれば) 気にしない。
                     38: //
1.1.1.4   root       39: // 今のところ NetBSD (5.0 以降) と OpenBSD(/amd64)(-6.7)
                     40: // (と Linux (CentOS 6.3/x86_64)) が該当する。
                     41: #if defined(__NetBSD__) || defined(__OpenBSD__)
1.1       root       42: #define DONT_USE_REFRESH 1
                     43: #endif
                     44: 
                     45: static void wxmainview_refresh();
                     46: 
                     47: WXMainView *gMainView;
                     48: 
                     49: wxBEGIN_EVENT_TABLE(WXMainView, inherited)
                     50:        EVT_PAINT(WXMainView::OnPaint)
                     51:        EVT_KEY_DOWN(WXMainView::OnKeyDown)
                     52:        EVT_KEY_UP(WXMainView::OnKeyUp)
1.1.1.2   root       53:        EVT_MOUSE_EVENTS(WXMainView::OnMouse)
1.1.1.5   root       54:        EVT_TIMER(wxID_ANY, WXMainView::OnTimer)
1.1       root       55: wxEND_EVENT_TABLE()
                     56: 
                     57: WXMainView::WXMainView(wxWindow *parent)
                     58:        : inherited(parent)
                     59: {
                     60:        // 仮想画面(VM が描画する画面)
                     61:        rendwidth  = gRenderer->GetWidth();
                     62:        rendheight = gRenderer->GetHeight();
                     63: 
                     64:        // レンダラバッファは常に仮想画面サイズ
                     65:        int buflen = rendwidth * rendheight * 3;
1.1.1.4   root       66:        ImageBuf.reset(new uint8_t[buflen]);
                     67:        memset(&ImageBuf[0], 0x70, buflen);
1.1       root       68:        // レンダラに通知
1.1.1.4   root       69:        gRenderer->SetBuf(ImageBuf.get(), wxmainview_refresh);
1.1       root       70: 
                     71:        // 実画面 (ウィンドウの大きさ)
                     72:        DoResize(screen_scale);
                     73: 
1.1.1.5   root       74:        // 描画を律速するためのタイマー
                     75:        timer.SetOwner(this);
                     76:        timer.Start(33);
                     77: 
                     78:        // 最初に一度描画
                     79:        Refresh();
1.1       root       80: }
                     81: 
                     82: WXMainView::~WXMainView()
                     83: {
                     84: }
                     85: 
                     86: // リフレッシュ要求コールバック。
                     87: // VM から呼ばれるので一旦グローバル関数を経由する。
                     88: void
                     89: wxmainview_refresh(void)
                     90: {
                     91:        gMainView->DoRefresh();
                     92: }
                     93: 
                     94: // リフレッシュ要求コールバック。こっちが実体。
                     95: void
                     96: WXMainView::DoRefresh()
                     97: {
                     98: #if defined(DONT_USE_REFRESH)
                     99:        // Refresh{,Rect}() が使えないので、再描画範囲は常に全体とする
                    100: #else
                    101:        // 再描画範囲を更新矩形に限定
                    102:        // XXX のはずだが、今の所全体
                    103:        RefreshRect(wxRect(0, 0, viewwidth, viewheight), false);
                    104: #endif
                    105: 
1.1.1.5   root      106:        // ここは VM Renderer が画面を更新した時に呼ばれるので、本来なら
                    107:        // ここで単に Refresh() を呼んで再描画を指示すればいいのだが、
                    108:        // VM 高速モードになると、VM Renderer が高速で回ってここも高速で
                    109:        // 呼ばれてしまい、その結果 Refresh() を発行しすぎて Mac では
                    110:        // システムイベントが拾えなくなってしまう。
                    111:        // それを避けるため、ここではフラグを立てるだけにしておいて、
                    112:        // こちらで管理している実時間タイマーで Refresh() を律速する。
                    113:        paint_request = true;
1.1       root      114: }
                    115: 
1.1.1.5   root      116: // タイマーイベント
1.1       root      117: void
                    118: WXMainView::OnTimer(wxTimerEvent& event)
                    119: {
1.1.1.5   root      120:        bool req = paint_request.exchange(false);
1.1       root      121:        if (req) {
1.1.1.5   root      122:                // 実際に再描画する
                    123:                Refresh();
1.1       root      124:        }
                    125: }
                    126: 
                    127: // 描画イベント
                    128: void
                    129: WXMainView::OnPaint(wxPaintEvent& event)
                    130: {
                    131:        if (viewwidth == 0 || viewheight == 0)
                    132:                return;
                    133: 
1.1.1.4   root      134:        wxImage image(rendwidth, rendheight, ImageBuf.get(), true);
1.1       root      135:        if (viewwidth != rendwidth || viewheight != rendheight) {
1.1.1.6   root      136:                // wxIMAGE_QUALITY_NORMAL だと速いが、ここは品質優先。
                    137: #if _BYTE_ORDER == _BIG_ENDIAN
                    138:                // XXX ..のはずだったが wxWidget 3.0.4 の QUALITY_HIGH は
                    139:                // BigEndian だとバグってるようだ。QUALITY_NORMAL のほうは大丈夫。
                    140:                auto quality = wxIMAGE_QUALITY_NORMAL;
                    141: #else
                    142:                auto quality = wxIMAGE_QUALITY_HIGH;
                    143: #endif
                    144:                image.Rescale(viewwidth, viewheight, quality);
1.1       root      145:        }
                    146: 
                    147:        wxBitmap bitmap(image);
                    148:        wxMemoryDC memDC;
                    149:        memDC.SelectObject(bitmap);
                    150: 
1.1.1.5   root      151:        wxPaintDC dc(this);
1.1       root      152:        wxRegion region(0, 0, viewwidth, viewheight);
                    153:        wxRegionIterator ri(region);
                    154:        for (; ri; ri++) {
                    155:                int dx, dy, dw, dh;
                    156:                dx = ri.GetX();
                    157:                dy = ri.GetY();
                    158:                dw = ri.GetWidth();
                    159:                dh = ri.GetHeight();
                    160:                int sx = dx;
                    161:                int sy = dy;
                    162:                dc.Blit(dx, dy, dw, dh, &memDC, sx, sy, wxCOPY);
                    163:        }
                    164: }
                    165: 
                    166: // リサイズ (UI スレッドから呼ぶこと)
                    167: void
                    168: WXMainView::DoResize(double scale)
                    169: {
                    170:        screen_scale = scale;
                    171:        int width  = (double)rendwidth  * scale;
                    172:        int height = (double)rendheight * scale;
                    173:        if (viewwidth != width || viewheight != height) {
                    174:                // ウィンドウサイズ変更
                    175:                viewwidth  = width;
                    176:                viewheight = height;
                    177:                SetClientSize(viewwidth, viewheight);
1.1.1.8 ! root      178:                SetMinClientSize(wxSize(viewwidth, viewheight));
1.1       root      179:        }
                    180: }
                    181: 
                    182: // 現在のスケールを返す。
                    183: // screen_scale は public static なので見えるんだけど一応お行儀で。
                    184: double
                    185: WXMainView::GetScale() const
                    186: {
                    187:        return screen_scale;
                    188: }
                    189: 
                    190: // 現在のスケール
                    191: /*static*/ double WXMainView::screen_scale;
                    192: 
                    193: 
                    194: //
1.1.1.2   root      195: // マウス入力
                    196: //
                    197: 
                    198: // マウスモード設定
                    199: void
                    200: WXMainView::SetMouseMode(bool mode)
                    201: {
                    202:        // XXX マウスモード ON にした時の座標を記憶してそこに戻るのはどうか
                    203: 
                    204:        mousemode = mode;
                    205:        if (mousemode) {
                    206:                // マウスモードを ON にする
                    207:                DMPRINTF("SetMouseMode ON\n");
                    208: 
                    209:                // マウスカーソル OFF
                    210:                ::wxSetCursor(wxCursor(wxCURSOR_BLANK));
                    211: 
1.1.1.4   root      212:                CaptureMouse();
                    213: 
1.1.1.2   root      214:                // このウィンドウから外れないように移動を検出し続けるため、
                    215:                // マウスカーソルをウィンドウ中央に移す。
                    216:                // ウィンドウとメニューバーが分離してる wxOSX のために必要。
                    217:                MyWarpPointer(GetClientSize() / 2);
                    218:        } else {
                    219:                // マウスモードを OFF にする
                    220:                DMPRINTF("SetMouseMode OFF\n");
                    221: 
1.1.1.4   root      222:                ReleaseMouse();
                    223: 
1.1.1.2   root      224:                // 分かりやすさのため、マウスカーソルを中央へ戻してから復帰
1.1.1.4   root      225:                wxSize pt = GetClientSize() / 2;
                    226:                WarpPointer(pt.x, pt.y);
1.1.1.2   root      227: 
                    228:                // マウスカーソル ON
                    229:                ::wxSetCursor(wxNullCursor);
                    230:        }
                    231: }
                    232: 
                    233: // マウスカーソルをクライアント座標 (x, y) に移動
                    234: void
                    235: WXMainView::MyWarpPointer(wxSize pos)
                    236: {
                    237:        DMPRINTF("MyWarpPointer %d,%d\n", pos.x, pos.y);
                    238: 
                    239:        // この後の MDWarpPointer() でもう一度 EVT_MOTION が飛ぶので
                    240:        // それを判別するためのフラグ。
                    241:        motion_by_warp_pointer = true;
                    242: 
                    243:        WarpPointer(pos.x, pos.y);
                    244: }
                    245: 
                    246: // マウスイベント
                    247: void
                    248: WXMainView::OnMouse(wxMouseEvent& event)
                    249: {
                    250:        // マウスモードの時だけ処理。
                    251:        // XXX 本当はイベントごと Disconnect したい
                    252:        if (mousemode) {
                    253:                bool leaving = event.Leaving();
                    254:                bool moving  = event.Moving();
1.1.1.3   root      255:                bool dragging = event.Dragging();
1.1.1.2   root      256:                // LeftDown() 等は押された時、LeftIsDown() 等は押されてる間 true。
                    257:                bool rb = event.RightIsDown();
                    258:                bool lb = event.LeftIsDown();
                    259:                bool mb = event.MiddleIsDown();
1.1.1.5   root      260:                const wxPoint& pos = event.GetPosition();
1.1.1.2   root      261:                int dx = 0;
                    262:                int dy = 0;
                    263: 
1.1.1.3   root      264: #if defined(MOUSEDEBUG)
                    265:                std::string dstr = "OnMouse";
                    266:                if (moving || dragging || motion_by_warp_pointer) {
                    267:                        dstr += string_format(" (%d,%d)", pos.x, pos.y);
                    268:                }
                    269:                if (moving)
                    270:                        dstr += " Moving";
                    271:                if (dragging)
                    272:                        dstr += " Dragging";
                    273:                if (motion_by_warp_pointer)
                    274:                        dstr += " MotionByWarp";
1.1.1.4   root      275:                if (lb || mb || rb) {
1.1.1.3   root      276:                        dstr += string_format(" Button(%c%c%c)",
                    277:                                (lb ? 'L' : '-'),
                    278:                                (mb ? 'M' : '-'),
                    279:                                (rb ? 'R' : '-'));
                    280:                }
                    281:                if (leaving)
                    282:                        dstr += " Leaving";
                    283:                printf("%s\n", dstr.c_str());
                    284: #endif
1.1.1.2   root      285: 
                    286:                if (leaving) {
                    287:                        // タスクスイッチした時とかのための自動リリース
                    288:                        SetMouseMode(false);
                    289:                }
                    290: 
1.1.1.3   root      291:                if (moving || dragging) {
1.1.1.2   root      292:                        // (My)WarpPointer() で自発的にマウスカーソルを移動させたことで
                    293:                        // 来る EVT_MOTION は無視する。
                    294:                        if (motion_by_warp_pointer) {
                    295:                                motion_by_warp_pointer = false;
                    296:                                // ここを基準点にする
                    297:                                prevpos = pos;
                    298:                        } else {
                    299:                                // 前回からの差を求める
                    300:                                dx = pos.x - prevpos.x;
                    301:                                dy = pos.y - prevpos.y;
                    302:                                prevpos = pos;
                    303: 
                    304:                                // マウスカーソルを中心に戻す
                    305:                                if (dx != 0 || dy != 0) {
                    306:                                        MyWarpPointer(GetClientSize() / 2);
                    307:                                }
                    308:                        }
                    309:                }
                    310: 
                    311:                // VM に入力
1.1.1.3   root      312:                if (dx != 0 ||
                    313:                    dy != 0 ||
                    314:                    lb != prevlb ||
                    315:                    mb != prevmb ||
                    316:                    rb != prevrb   )
                    317:                {
1.1.1.2   root      318:                        DMPRINTF("        Input dx=%d dy=%d %c%c%c\n",
                    319:                                dx, dy,
                    320:                                (lb ? 'L' : '-'),
                    321:                                (mb ? 'M' : '-'),
                    322:                                (rb ? 'R' : '-'));
                    323: 
                    324:                        gKeyboard->MouseInput(dx, dy, rb, lb, mb);
                    325:                }
1.1.1.3   root      326: 
                    327:                prevlb = lb;
                    328:                prevmb = mb;
                    329:                prevrb = rb;
1.1.1.2   root      330:        }
                    331: 
                    332:        // EVT_LEFT_DOWN をデフォルト処理するため
                    333:        event.Skip();
                    334: }
                    335: 
1.1.1.4   root      336: // アクティベートイベント。
                    337: // この(トップレベル)ウィンドウにフォーカスが当たるか外れるかで飛んでくる。
                    338: // 実際には WXMainFrame 宛てに飛んできたイベントをこちらに転送してある。
                    339: // マウスモード中にこのウィンドウからフォーカスが外れたら (例えば ALT+TAB の
                    340: // ようなウィンドウを切り替える操作)、マウスモードを解除するため。
                    341: void
                    342: WXMainView::OnActivate(wxActivateEvent& event)
                    343: {
                    344:        // フォーカスが外れる際にマウスモード中ならマウスモードを解除
                    345:        if (event.GetActive() == false) {
                    346:                DMPRINTF("OnActivate FocusOut\n");
                    347:                if (mousemode) {
                    348:                        SetMouseMode(false);
                    349:                }
                    350:        } else {
                    351:                DMPRINTF("OnActivate FocusIn\n");
                    352:        }
                    353: }
                    354: 
                    355: 
1.1.1.2   root      356: //
1.1       root      357: // キー入力
                    358: //
                    359: 
                    360: // wxKeyEvent でキーコードを得るためのメソッドは
                    361: // GetKeyCode()、GetRawKeyCode()、GetRawKeyFlags() の3つが用意されていて
                    362: // wxWigets の port (wxGTK、wxOSX とか) によってそれぞれ内容の定義が違う。
                    363: //
                    364: // wxGTK の場合
1.1.1.8 ! root      365: //  GetKeyCode() が論理キーコードなのでこれをメインに使う。ただし左右 [SHIFT]
        !           366: //  のように論理キーコードだけでは区別の付かないものについては物理キー番号で
        !           367: //  ある GetRawKeyFlags() を併用する。
        !           368: //
        !           369: //  以下詳細。
1.1       root      370: //  GetKeyCode() は wxWidgets の WXK_* (/usr/pkg/include/wx-3.0/wx/defs.h)。
1.1.1.8 ! root      371: //  これは概ね論理キーコードであり、xorg.conf の swapcaps 設定や Xmodmap の
        !           372: //  影響をうける。
        !           373: //   o 基本的に [SHIFT] キーの影響を受けないが、一部例外がある。
        !           374: //     - [^] (0x5e) と [SHIFT]+[^] (0x30)
        !           375: //     - [,] (0x2c) と [SHIFT]+[,] (0x3c)
        !           376: //   o [\] と [_] は同じ 0x5c になる ([SHIFT] 押しながらでも同様)。
        !           377: //   o [SHIFT], [CTRL], [ALT] の各左右キーは同じコードになる。
        !           378: //
        !           379: //  GetRawKeyFlags() は物理キー番号ようだ。GDK の hardware keycode らしいが、
        !           380: //  それ以上の詳細は不明。
        !           381: //   o [SHIFT] キーの影響を受けない。
        !           382: //     GetKeyCode() では影響を受けた例外キーもここでは影響を受けない。
        !           383: //   o [SHIFT], [CTRL], [ALT] の各左右キーは違うコードになる。
1.1       root      384: //
                    385: //  GetRawKeyCode() は GDK の keycode っぽい?
                    386: //   (/usr/pkg/include/gtk-2.0/gdk/gdkkeysyms.h)。
                    387: //   X11 の keysym から来てる? (/usr/X11R7/include/X11/keysymdef.h)。
1.1.1.8 ! root      388: //   ただし [A] と [SHIFT]+[A] が違うコードを返すというか、文字コードで表現
        !           389: //   出来る時は文字コード、みたいな感じになっているのでここでは使いづらい。
1.1       root      390: //   左右の SHIFT は区別可能。
                    391: //
                    392: // wxOSX の場合
                    393: //  GetKeyCode()
1.1.1.8 ! root      394: //   英字キー [A] と [SHIFT]+[A] は同じコードになるが、
        !           395: //   記号キー [1] と [SHIFT]+[1] は別になる体系のようだ。
        !           396: //   左右の [SHIFT] は区別できない。
1.1       root      397: //
                    398: //  GetRawKeyCode()
1.1.1.8 ! root      399: //   これがたぶん物理キー番号。
        !           400: //   [1] と [SHIFT]+[1] は同じコードを返す。
        !           401: //   左右の [SHIFT] は区別可能。
1.1       root      402: //
                    403: //  GetRawKeyFlags() は状態フラグか何かのようだ。
                    404: //
                    405: 
                    406: // キーを押した
                    407: void
                    408: WXMainView::OnKeyDown(wxKeyEvent& event)
                    409: {
1.1.1.2   root      410:        DKPRINTF("KeyDown ");
1.1       root      411:        int keycode = GetKeyCode(event);
                    412:        gKeyboard->MakeKey(keycode);
1.1.1.2   root      413: 
                    414:        // メニューのアクセラレータのために必要
                    415:        event.Skip();
1.1       root      416: }
                    417: 
                    418: // キーを離した
                    419: void
                    420: WXMainView::OnKeyUp(wxKeyEvent& event)
                    421: {
1.1.1.2   root      422:        DKPRINTF("KeyUp   ");
1.1       root      423:        int keycode = GetKeyCode(event);
                    424:        gKeyboard->BreakKey(keycode);
                    425: }
                    426: 
                    427: // 共通キーコードを取得する。
                    428: // 対応するキーがない場合は -1 を返す。
                    429: int
                    430: WXMainView::GetKeyCode(wxKeyEvent& event)
                    431: {
                    432:        uint32 wxcode   __unused = event.GetKeyCode();
                    433:        uint32 rawcode  __unused = event.GetRawKeyCode();
                    434:        uint32 rawflags __unused = event.GetRawKeyFlags();
1.1.1.8 ! root      435:        uint32 raw;
1.1       root      436:        int keycode;
                    437: 
1.1.1.8 ! root      438:        // wx キーコードは10進、16進併記しないと読みづらい
        !           439:        DKPRINTF("key=%3d(0x%03x) ", wxcode, wxcode);
        !           440: #if defined(__WXOSX__)
        !           441:        // wxOSX では raw が物理キー、flags はフラグっぽいものなので不要
        !           442:        DKPRINTF("raw=0x%02x (flags=0x%06x) ", rawcode, rawflags);
        !           443:        raw = rawcode;
        !           444: #else
        !           445:        // wxGTK では flags が物理キー、raw は文字コードっぽいものなので不要
        !           446:        DKPRINTF("flags=0x%02x (raw=0x%04x) ", rawflags, rawcode);
        !           447:        raw = rawflags;
1.1       root      448: #endif
                    449: 
1.1.1.8 ! root      450:        // まず wx キーコードでテーブルを引く
        !           451:        if (wxcode < countof(keycode_table)) {
        !           452:                keycode = keycode_table[wxcode];
1.1       root      453:        } else {
                    454:                keycode = KC_none;
                    455:        }
1.1.1.8 ! root      456: 
        !           457:        // wx キーコードは論理キーコードなので [SHIFT] キーの左右を区別できないが
        !           458:        // ここでは左右を区別したいので、物理キー番号を見て区別する。
        !           459:        if (keycode == KC_SHIFT) {
        !           460: #if defined(__WXOSX__)
        !           461:                if (raw == 0x3c)
        !           462: #else
        !           463:                if (raw == 0x3e)
        !           464: #endif
        !           465:                {
        !           466:                        keycode = KC_SHIFT_R;
        !           467:                } else {
        !           468:                        keycode = KC_SHIFT_L;
        !           469:                }
        !           470:        }
1.1       root      471: 
                    472: #if defined(__WXGTK__)
1.1.1.8 ! root      473:        // wxGTK では日本語キーボードの一部のキーが論理キーコードだけでは
        !           474:        // 判定できないようだ
1.1       root      475: 
1.1.1.8 ! root      476:        // [0] と [SHIFT]+[^] が同じキーコードになるようだ
        !           477:        if (keycode == KC_0) {
        !           478:                if (raw == 0x15) {
        !           479:                        keycode = KC_circum;
        !           480:                } else {
        !           481:                        keycode = KC_0;
        !           482:                }
        !           483:        }
        !           484:        // [\] と [_] が同じキーコードになるようだ
        !           485:        if (keycode == KC_backslash) {
        !           486:                if (raw == 0xd3) {
        !           487:                        keycode = KC_underscore;
        !           488:                } else {
        !           489:                        keycode = KC_backslash;
        !           490:                }
        !           491:        }
        !           492: #endif
        !           493: 
        !           494:        DKPRINTF("keycode=%d %s\n", keycode, gKeyboard->GetName(keycode).c_str());
        !           495:        return keycode;
        !           496: }
        !           497: 
        !           498: // wx キーコード(WXK_*)を共通キーコードに変換するテーブル。
        !           499: // 一部このテーブルだけでは判定できないものがある。すぐ上の GetKeyCode() 参照。
        !           500: // 値 0 は本当は KC_none と書くべきだが、こっちのほうが読みやすいので。
        !           501: //
        !           502: // XXX: OSX の [CAPS] は押す離すで一回分の Down しか来ないのでちょっと放置。
        !           503: // XXX: OSX の [英数] と [かな] もちょっと放置。
1.1       root      504: /*static*/ const int
1.1.1.8 ! root      505: WXMainView::keycode_table[0x190] = {
        !           506:        0,                              // 0x00
        !           507:        0,                              // 0x01
        !           508:        0,                              // 0x02
        !           509:        0,                              // 0x03
        !           510:        0,                              // 0x04
        !           511:        0,                              // 0x05
        !           512:        0,                              // 0x06
        !           513:        0,                              // 0x07
        !           514:        KC_BS,                  // 0x08 WXK_BACK
        !           515:        KC_TAB,                 // 0x09 WXK_TAB
        !           516:        0,                              // 0x0a
        !           517:        0,                              // 0x0b
        !           518:        0,                              // 0x0c
        !           519:        KC_enter,               // 0x0d WXK_RETURN
        !           520:        0,                              // 0x0e
        !           521:        0,                              // 0x0f
        !           522: 
        !           523:        0,                              // 0x10
        !           524:        0,                              // 0x11
        !           525:        0,                              // 0x12
        !           526:        0,                              // 0x13
        !           527:        0,                              // 0x14
        !           528:        0,                              // 0x15
        !           529:        0,                              // 0x16
        !           530:        0,                              // 0x17
        !           531:        0,                              // 0x18
        !           532:        0,                              // 0x19
        !           533:        0,                              // 0x1a
        !           534:        KC_ESC,                 // 0x1b WXK_ESCAPE
        !           535:        0,                              // 0x1c
        !           536:        0,                              // 0x1d
        !           537:        0,                              // 0x1e
        !           538:        0,                              // 0x1f
        !           539: 
        !           540:        KC_space,               // 0x20 WXK_SPACE
        !           541:        KC_1,                   // 0x21         (OSX: [SHIFT]+[1])
        !           542:        KC_2,                   // 0x22         (OSX: [SHIFT]+[2])
        !           543:        KC_3,                   // 0x23         (OSX: [SHIFT]+[3])
        !           544:        KC_4,                   // 0x24         (OSX: [SHIFT]+[4])
        !           545:        KC_5,                   // 0x25         (OSX: [SHIFT]+[5])
        !           546:        KC_6,                   // 0x26         (OSX: [SHIFT]+[6])
        !           547:        KC_7,                   // 0x27         (OSX: [SHIFT]+[7])
        !           548:        KC_8,                   // 0x28         (OSX: [SHIFT]+[8])
        !           549:        KC_9,                   // 0x29         (OSX: [SHIFT]+[9])
        !           550:        KC_colon,               // 0x2a         (OSX: [SHIFT]+[:])
        !           551:        KC_semicolon,   // 0x2b         (OSX: [SHIFT]+[;])
        !           552:        KC_comma,               // 0x2c
        !           553:        KC_minus,               // 0x2d
        !           554:        KC_period,              // 0x2e
        !           555:        KC_slash,               // 0x2f
        !           556: 
        !           557:        KC_0,                   // 0x30         (GTK: [0] と [SHIFT]+[^])
        !           558:        KC_1,                   // 0x31
        !           559:        KC_2,                   // 0x32
        !           560:        KC_3,                   // 0x33
        !           561:        KC_4,                   // 0x34
        !           562:        KC_5,                   // 0x35
        !           563:        KC_6,                   // 0x36
        !           564:        KC_7,                   // 0x37
        !           565:        KC_8,                   // 0x38
        !           566:        KC_9,                   // 0x39
        !           567:        KC_colon,               // 0x3a
        !           568:        KC_semicolon,   // 0x3b
        !           569:        KC_comma,               // 0x3c         (GTK: [,]は0x2c だが [SHIFT]+[,]は0x3c)
        !           570:        KC_minus,               // 0x3d         (OSX: [SHIFT]+[-])
        !           571:        KC_period,              // 0x3e         (OSX: [SHIFT]+[.])
        !           572:        KC_slash,               // 0x3f         (OSX: [SHIFT]+[/])
        !           573: 
        !           574:        KC_at,                  // 0x40
        !           575:        KC_A,                   // 0x41
        !           576:        KC_B,                   // 0x42
        !           577:        KC_C,                   // 0x43
        !           578:        KC_D,                   // 0x44
        !           579:        KC_E,                   // 0x45
        !           580:        KC_F,                   // 0x46
        !           581:        KC_G,                   // 0x47
        !           582:        KC_H,                   // 0x48
        !           583:        KC_I,                   // 0x49
        !           584:        KC_J,                   // 0x4a
        !           585:        KC_K,                   // 0x4b
        !           586:        KC_L,                   // 0x4c
        !           587:        KC_M,                   // 0x4d
        !           588:        KC_N,                   // 0x4e
        !           589:        KC_O,                   // 0x4f
        !           590: 
        !           591:        KC_P,                   // 0x50
        !           592:        KC_Q,                   // 0x51
        !           593:        KC_R,                   // 0x52
        !           594:        KC_S,                   // 0x53
        !           595:        KC_T,                   // 0x54
        !           596:        KC_U,                   // 0x55
        !           597:        KC_V,                   // 0x56
        !           598:        KC_W,                   // 0x57
        !           599:        KC_X,                   // 0x58
        !           600:        KC_Y,                   // 0x59
        !           601:        KC_Z,                   // 0x5a
        !           602:        KC_bracketleft, // 0x5b
        !           603:        KC_backslash,   // 0x5c         (GTK: [\] と [_])
        !           604:        KC_bracketright,// 0x5d
        !           605:        KC_circum,              // 0x5e
        !           606:        KC_underscore,  // 0x5f         (OSX: [_])
        !           607: 
        !           608:        KC_at,                  // 0x60         (OSX: [SHIFT]+[@])
        !           609:        0,                              // 0x61
        !           610:        0,                              // 0x62
        !           611:        0,                              // 0x63
        !           612:        0,                              // 0x64
        !           613:        0,                              // 0x65
        !           614:        0,                              // 0x66
        !           615:        0,                              // 0x67
        !           616:        0,                              // 0x68
        !           617:        0,                              // 0x69
        !           618:        0,                              // 0x6a
        !           619:        0,                              // 0x6b
        !           620:        0,                              // 0x6c
        !           621:        0,                              // 0x6d
        !           622:        0,                              // 0x6e
        !           623:        0,                              // 0x6f
        !           624: 
        !           625:        0,                              // 0x70
        !           626:        0,                              // 0x71
        !           627:        0,                              // 0x72
        !           628:        0,                              // 0x73
        !           629:        0,                              // 0x74
        !           630:        0,                              // 0x75
        !           631:        0,                              // 0x76
        !           632:        0,                              // 0x77
        !           633:        0,                              // 0x78
        !           634:        0,                              // 0x79
        !           635:        0,                              // 0x7a
        !           636:        KC_bracketleft, // 0x7b         (OSX: [SHIFT]+[[])
        !           637:        KC_backslash,   // 0x7c         (OSX: [SHIFT]+[\])
        !           638:        KC_bracketright,// 0x7d         (OSX: [SHIFT]+[]])
        !           639:        KC_circum,              // 0x7e         (OSX: [SHIFT]+[^])
        !           640:        KC_DEL,                 // 0x7f
        !           641: 
        !           642:        0,0,0,0, 0,0,0,0,       // 0x80
        !           643:        0,0,0,0, 0,0,0,0,       // 0x88
        !           644:        0,0,0,0, 0,0,0,0,       // 0x90
        !           645:        0,0,0,0, 0,0,0,0,       // 0x98
        !           646: 
        !           647:        0,                              // 0xa0
        !           648:        0,                              // 0xa1
        !           649:        0,                              // 0xa2
        !           650:        0,                              // 0xa3
        !           651:        0,                              // 0xa4
        !           652:        KC_backslash,   // 0xa5         (OSX: [\])
        !           653:        0,                              // 0xa6
        !           654:        0,                              // 0xa7
        !           655:        0,                              // 0xa8
        !           656:        0,                              // 0xa9
        !           657:        0,                              // 0xaa
        !           658:        0,                              // 0xab
        !           659:        0,                              // 0xac
        !           660:        0,                              // 0xad
        !           661:        0,                              // 0xae
        !           662:        0,                              // 0xaf
        !           663: 
        !           664:        0,0,0,0, 0,0,0,0,       // 0xb0
        !           665:        0,0,0,0, 0,0,0,0,       // 0xb8
        !           666: 
        !           667:        0,                              // 0xc0=192
        !           668:        0,                              // 193 WXK_SPECIAL1
        !           669:        0,                              // 194 WXK_SPECIAL2
        !           670:        0,                              // 195 WXK_SPECIAL3
        !           671:        0,                              // 196 WXK_SPECIAL4
        !           672:        0,                              // 197 WXK_SPECIAL5
        !           673:        0,                              // 198 WXK_SPECIAL6
        !           674:        0,                              // 199 WXK_SPECIAL7
        !           675: 
        !           676:        0,                              // 200 WXK_SPECIAL8
        !           677:        0,                              // 201 WXK_SPECIAL9
        !           678:        0,                              // 202 WXK_SPECIAL10
        !           679:        0,                              // 203 WXK_SPECIAL11
        !           680:        0,                              // 204 WXK_SPECIAL12
        !           681:        0,                              // 205 WXK_SPECIAL13
        !           682:        0,                              // 206 WXK_SPECIAL14
        !           683:        0,                              // 207 WXK_SPECIAL15
        !           684:        0,                              // 208 WXK_SPECIAL16
        !           685:        0,                              // 209 WXK_SPECIAL17
        !           686: 
        !           687:        0,                              // 210 WXK_SPECIAL18
        !           688:        0,                              // 211 WXK_SPECIAL19
        !           689:        0,                              // 212 WXK_SPECIAL20
        !           690:        0,                              // 0xd5
        !           691:        0,                              // 0xd6
        !           692:        0,                              // 0xd7
        !           693: 
        !           694:        0,0,0,0, 0,0,0,0,       // 0xd8
        !           695:        0,0,0,0, 0,0,0,0,       // 0xe0
        !           696:        0,0,0,0, 0,0,0,0,       // 0xe8
        !           697:        0,0,0,0, 0,0,0,0,       // 0xf0
        !           698:        0,0,0,0, 0,0,0,0,       // 0xf8
        !           699:        0,0,0,0, 0,0,0,0,       // 0x100
        !           700:        0,0,0,0, 0,0,0,0,       // 0x108
        !           701:        0,0,0,0, 0,0,0,0,       // 0x110
        !           702:        0,0,0,0, 0,0,0,0,       // 0x118
        !           703:        0,0,0,0, 0,0,0,0,       // 0x120
        !           704: 
        !           705:        0,                              // 0x128
        !           706:        0,                              // 0x129
        !           707:        0,                              // 0x12a
        !           708:        0,                              // 0x12b
        !           709:        //
        !           710:        // WXK_* は10進数で定義されていて、特殊キーは 300 (=0x12c) から。
        !           711:        //
        !           712:        0,                              // 300 WXK_START
        !           713:        0,                              // 301 WXK_LBUTTON
        !           714:        0,                              // 302 WXK_RBUTTON
        !           715:        0,                              // 303 WXK_CANCEL
        !           716:        0,                              // 304 WXK_MBUTTON
        !           717:        0,                              // 305 WXK_CLEAR
        !           718:        KC_SHIFT,               // 306 WXK_SHIFT        (左右[SHIFT])
        !           719:        0,                              // 307 WXK_ALT
        !           720:        KC_CTRL,                // 308 WXK_CONTROL      (ゲストに右[CTRL]はないので区別不要)
        !           721:        0,                              // 309 WXK_MENU
        !           722: 
        !           723:        0,                              // 310 WXK_PAUSE
        !           724:        0,                              // 311 WXK_CAPITAL
        !           725:        0,                              // 312 WXK_END
        !           726:        0,                              // 313 WXK_HOME
        !           727:        KC_left,                // 314 WXK_LEFT
        !           728:        KC_up,                  // 315 WXK_UP
        !           729:        KC_right,               // 316 WXK_RIGHT
        !           730:        KC_down,                // 317 WXK_DOWN
        !           731:        0,                              // 318 WXK_SELECT
        !           732:        0,                              // 319 WXK_PRINT
        !           733: 
        !           734:        0,                              // 320 WXK_EXECUTE
        !           735:        0,                              // 321 WXK_SNAPSHOT
        !           736:        KC_INS,                 // 322 WXK_INSERT
        !           737:        0,                              // 323 WXK_HELP
        !           738:        KC_PAD_0,               // 324 WXK_NUMPAD0
        !           739:        KC_PAD_1,               // 325 WXK_NUMPAD1
        !           740:        KC_PAD_2,               // 326 WXK_NUMPAD2
        !           741:        KC_PAD_3,               // 327 WXK_NUMPAD3
        !           742:        KC_PAD_4,               // 328 WXK_NUMPAD4
        !           743:        KC_PAD_5,               // 329 WXK_NUMPAD5
        !           744: 
        !           745:        KC_PAD_6,               // 330 WXK_NUMPAD6
        !           746:        KC_PAD_7,               // 331 WXK_NUMPAD7
        !           747:        KC_PAD_8,               // 332 WXK_NUMPAD8
        !           748:        KC_PAD_9,               // 333 WXK_NUMPAD9
        !           749:        0,                              // 334 WXK_MULTIPLY
        !           750:        0,                              // 335 WXK_ADD
        !           751:        0,                              // 336 WXK_SEPARATOR
        !           752:        0,                              // 337 WXK_SUBTRACT
        !           753:        0,                              // 338 WXK_DECIMAL
        !           754:        0,                              // 339 WXK_DIVIDE
        !           755: 
        !           756:        KC_F1,                  // 340 WXK_F1
        !           757:        KC_F2,                  // 341 WXK_F2
        !           758:        KC_F3,                  // 342 WXK_F3
        !           759:        KC_F4,                  // 343 WXK_F4
        !           760:        KC_F5,                  // 344 WXK_F5
        !           761:        KC_F6,                  // 345 WXK_F6
        !           762:        KC_F7,                  // 346 WXK_F7
        !           763:        KC_F8,                  // 347 WXK_F8
        !           764:        KC_F9,                  // 348 WXK_F9
        !           765:        KC_F10,                 // 349 WXK_F10
        !           766: 
        !           767:        0,                              // 350 WXK_F11
        !           768:        0,                              // 351 WXK_F12
        !           769:        0,                              // 352 WXK_F13
        !           770:        0,                              // 353 WXK_F14
        !           771:        0,                              // 354 WXK_F15
        !           772:        0,                              // 355 WXK_F16
        !           773:        0,                              // 356 WXK_F17
        !           774:        0,                              // 357 WXK_F18
        !           775:        0,                              // 358 WXK_F19
        !           776:        0,                              // 359 WXK_F20
        !           777: 
        !           778:        0,                              // 360 WXK_F21
        !           779:        0,                              // 361 WXK_F22
        !           780:        0,                              // 362 WXK_F23
        !           781:        0,                              // 363 WXK_F24
        !           782:        0,                              // 364 WXK_NUMLOCK
        !           783:        0,                              // 365 WXK_SCROLL
        !           784:        0,                              // 366 WXK_PAGEUP
        !           785:        0,                              // 367 WXK_PAGEDOWN
        !           786:        0,                              // 368 WXK_NUMPAD_SPACE
        !           787:        0,                              // 369 WXK_NUMPAD_TAB
        !           788: 
        !           789:        KC_PAD_enter,   // 370 WXK_NUMPAD_ENTER
        !           790:        0,                              // 371 WXK_NUMPAD_F1
        !           791:        0,                              // 372 WXK_NUMPAD_F2
        !           792:        0,                              // 373 WXK_NUMPAD_F3
        !           793:        0,                              // 374 WXK_NUMPAD_F4
        !           794:        0,                              // 375 WXK_NUMPAD_HOME
        !           795:        0,                              // 376 WXK_NUMPAD_LEFT
        !           796:        0,                              // 377 WXK_NUMPAD_UP
        !           797:        0,                              // 378 WXK_NUMPAD_RIGHT
        !           798:        0,                              // 379 WXK_NUMPAD_DOWN
        !           799: 
        !           800:        0,                              // 380 WXK_NUMPAD_PAGEUP
        !           801:        0,                              // 381 WXK_NUMPAD_PAGEDOWN
        !           802:        0,                              // 382 WXK_NUMPAD_END
        !           803:        0,                              // 383 WXK_NUMPAD_BEGIN
        !           804:        0,                              // 384 WXK_NUMPAD_INSERT
        !           805:        0,                              // 385 WXK_NUMPAD_DELETE
        !           806:        0,                              // 386 WXK_NUMPAD_EQUAL
        !           807:        KC_PAD_multiply,// 387 WXK_NUMPAD_MULTIPLY
        !           808:        KC_PAD_plus,    // 388 WXK_NUMPAD_ADD
        !           809:        0,                              // 389 WXK_NUMPAD_SEPARATOR
        !           810: 
        !           811:        KC_PAD_minus,   // 390 WXK_NUMPAD_SUBTRACT
        !           812:        KC_PAD_decimal, // 391 WXK_NUMPAD_DECIMAL
        !           813:        KC_PAD_divide,  // 392 WXK_NUMPAD_DIVIDE
        !           814:        0,                              // 393 WXK_WINDOWS_LEFT
        !           815:        0,                              // 394 WXK_WINDOWS_RIGHT
        !           816:        0,                              // 395 WXK_WINDOWS_MENU
        !           817:        // WXK_RAW_CONTROL は wxOSX でのみ定義してあり (wxOSX 以外では別名)、
        !           818:        // wxOSX とそれ以外とで定義済みキーの最大値が違う。そこが可変だとこの
        !           819:        // テーブルが困るので、wxOSX 以外でも常に WXK_RAW_CONTROL 分の枠は用意
        !           820:        // することにする。wxOSX 以外だと飛んでこないというだけで害はない。
        !           821:        KC_CTRL,                // 396 WXK_RAW_CONTROL  (OSX)
        !           822: 
        !           823:        0,                              // 397
        !           824:        0,                              // 398
        !           825:        0,                              // 399=0x18f
1.1       root      826: };

unix.superglobalmegacorp.com

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