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

1.1     ! root        1: //
        !             2: // nono
        !             3: // Copyright (C) 2018 [email protected]
        !             4: //
        !             5: 
        !             6: #include "wxheader.h"
        !             7: #include "keyboard.h"
        !             8: #include "renderer.h"
        !             9: #include "scheduler.h"
        !            10: #include "wxmainview.h"
        !            11: #include <wx/region.h>
        !            12: #include <wx/event.h>
        !            13: #if defined(__NetBSD__)
        !            14: #include <sys/param.h> // __NetBSD_Version__
        !            15: #endif
        !            16: 
        !            17: //#define KEYDEBUG 1
        !            18: 
        !            19: #if defined(KEYDEBUG)
        !            20: #define DPRINTF(...)   printf(__VA_ARGS__)
        !            21: #else
        !            22: #define DPRINTF(...) /**/
        !            23: #endif
        !            24: 
        !            25: // 再描画矩形の指定方法について。
        !            26: // DoRefresh() にて、VM スレッドが自発的に画面を更新する際は、
        !            27: // パフォーマンスの観点からも更新矩形だけを再描画すべき。
        !            28: // これを wxWidgets に指示するのが wxWindow::Refresh{,Rect}() であるが
        !            29: // 一部のプラットフォームではこれを呼び出すと、アプリケーションウィンドウ
        !            30: // 全体がささってしまい、MainView だけでなくメニューバーも含めたすべてが
        !            31: // 再描画できなくなってしまう。仕方がないので、これらのプラットフォームでは
        !            32: // Refresh{,Rect}() を呼ばず、再描画矩形を画面全体として運用する。
        !            33: // ちょっと無駄なだけなので (動かないことに比べれば) 気にしない。
        !            34: //
        !            35: // 今のところ NetBSD 5.0 以上(と Linux (CentOS 6.3/x86_64)) が該当する。
        !            36: #if defined(__NetBSD__) && __NetBSD_Version__ >= 500000000
        !            37: #define DONT_USE_REFRESH 1
        !            38: #endif
        !            39: 
        !            40: #define TIMERID_PAINTTIMER 1
        !            41: 
        !            42: static void wxmainview_refresh();
        !            43: 
        !            44: WXMainView *gMainView;
        !            45: 
        !            46: wxBEGIN_EVENT_TABLE(WXMainView, inherited)
        !            47:        EVT_PAINT(WXMainView::OnPaint)
        !            48:        EVT_KEY_DOWN(WXMainView::OnKeyDown)
        !            49:        EVT_KEY_UP(WXMainView::OnKeyUp)
        !            50:        EVT_TIMER(TIMERID_PAINTTIMER, WXMainView::OnTimer)
        !            51: wxEND_EVENT_TABLE()
        !            52: 
        !            53: WXMainView::WXMainView(wxWindow *parent)
        !            54:        : inherited(parent)
        !            55: {
        !            56:        // 仮想画面(VM が描画する画面)
        !            57:        rendwidth  = gRenderer->GetWidth();
        !            58:        rendheight = gRenderer->GetHeight();
        !            59: 
        !            60:        // レンダラバッファは常に仮想画面サイズ
        !            61:        int buflen = rendwidth * rendheight * 3;
        !            62:        ImageBuf = new uint8_t[buflen];
        !            63:        memset(ImageBuf, 0x70, buflen);
        !            64:        // レンダラに通知
        !            65:        gRenderer->SetBuf(ImageBuf, wxmainview_refresh);
        !            66: 
        !            67:        // 実画面 (ウィンドウの大きさ)
        !            68:        DoResize(screen_scale);
        !            69: 
        !            70:        paintTimer.SetOwner(this, TIMERID_PAINTTIMER);
        !            71:        paintTimer.Start(16);
        !            72:        paintRequested = true;          // first paint request
        !            73: }
        !            74: 
        !            75: WXMainView::~WXMainView()
        !            76: {
        !            77:        delete[] ImageBuf;
        !            78: }
        !            79: 
        !            80: // リフレッシュ要求コールバック。
        !            81: // VM から呼ばれるので一旦グローバル関数を経由する。
        !            82: void
        !            83: wxmainview_refresh(void)
        !            84: {
        !            85:        gMainView->DoRefresh();
        !            86: }
        !            87: 
        !            88: // リフレッシュ要求コールバック。こっちが実体。
        !            89: void
        !            90: WXMainView::DoRefresh()
        !            91: {
        !            92: #if defined(DONT_USE_REFRESH)
        !            93:        // Refresh{,Rect}() が使えないので、再描画範囲は常に全体とする
        !            94: #else
        !            95:        // 再描画範囲を更新矩形に限定
        !            96:        // XXX のはずだが、今の所全体
        !            97:        RefreshRect(wxRect(0, 0, viewwidth, viewheight), false);
        !            98: #endif
        !            99: 
        !           100:        // PAINT イベントを投げる
        !           101:        // XXX んだけど mac だと投げすぎるとシステムイベントを拾えなくなってしまう
        !           102:        paintRequested = true;
        !           103: }
        !           104: 
        !           105: void
        !           106: WXMainView::OnTimer(wxTimerEvent& event)
        !           107: {
        !           108:        bool req = paintRequested.exchange(false);
        !           109:        if (req) {
        !           110:                // PAINT イベントを投げる
        !           111:                wxPaintEvent *ev = new wxPaintEvent();
        !           112:                QueueEvent(ev);
        !           113:        }
        !           114: }
        !           115: 
        !           116: // 描画イベント
        !           117: void
        !           118: WXMainView::OnPaint(wxPaintEvent& event)
        !           119: {
        !           120:        wxClientDC dc(this);
        !           121: 
        !           122:        DoPaint(dc);
        !           123: }
        !           124: 
        !           125: // 描画実行
        !           126: void
        !           127: WXMainView::DoPaint(wxDC& dc)
        !           128: {
        !           129:        if (viewwidth == 0 || viewheight == 0)
        !           130:                return;
        !           131: 
        !           132:        wxImage image(rendwidth, rendheight, ImageBuf, true);
        !           133: 
        !           134:        if (viewwidth != rendwidth || viewheight != rendheight) {
        !           135:                // wxIMAGE_QUALITY_NORMAL だと速いが、品質優先。
        !           136:                image.Rescale(viewwidth, viewheight, wxIMAGE_QUALITY_HIGH);
        !           137:        }
        !           138: 
        !           139:        wxBitmap bitmap(image);
        !           140:        wxMemoryDC memDC;
        !           141:        memDC.SelectObject(bitmap);
        !           142: 
        !           143:        wxRegion region(0, 0, viewwidth, viewheight);
        !           144:        wxRegionIterator ri(region);
        !           145:        for (; ri; ri++) {
        !           146:                int dx, dy, dw, dh;
        !           147:                dx = ri.GetX();
        !           148:                dy = ri.GetY();
        !           149:                dw = ri.GetWidth();
        !           150:                dh = ri.GetHeight();
        !           151:                int sx = dx;
        !           152:                int sy = dy;
        !           153:                dc.Blit(dx, dy, dw, dh, &memDC, sx, sy, wxCOPY);
        !           154:        }
        !           155: }
        !           156: 
        !           157: // リサイズ (UI スレッドから呼ぶこと)
        !           158: void
        !           159: WXMainView::DoResize(double scale)
        !           160: {
        !           161:        screen_scale = scale;
        !           162:        int width  = (double)rendwidth  * scale;
        !           163:        int height = (double)rendheight * scale;
        !           164:        if (viewwidth != width || viewheight != height) {
        !           165:                // ウィンドウサイズ変更
        !           166:                viewwidth  = width;
        !           167:                viewheight = height;
        !           168:                SetClientSize(viewwidth, viewheight);
        !           169:                SetMinSize(wxSize(viewwidth, viewheight));
        !           170:        }
        !           171: }
        !           172: 
        !           173: // 現在のスケールを返す。
        !           174: // screen_scale は public static なので見えるんだけど一応お行儀で。
        !           175: double
        !           176: WXMainView::GetScale() const
        !           177: {
        !           178:        return screen_scale;
        !           179: }
        !           180: 
        !           181: // 現在のスケール
        !           182: /*static*/ double WXMainView::screen_scale;
        !           183: 
        !           184: 
        !           185: //
        !           186: // キー入力
        !           187: //
        !           188: 
        !           189: // wxKeyEvent でキーコードを得るためのメソッドは
        !           190: // GetKeyCode()、GetRawKeyCode()、GetRawKeyFlags() の3つが用意されていて
        !           191: // wxWigets の port (wxGTK、wxOSX とか) によってそれぞれ内容の定義が違う。
        !           192: //
        !           193: // wxGTK の場合
        !           194: //  GetKeyCode() は wxWidgets の WXK_* (/usr/pkg/include/wx-3.0/wx/defs.h)。
        !           195: //   これは左右の SHIFT が区別できないが、
        !           196: //   それ以外はだいたい使えそうではある。
        !           197: //
        !           198: //  GetRawKeyCode() は GDK の keycode っぽい?
        !           199: //   (/usr/pkg/include/gtk-2.0/gdk/gdkkeysyms.h)。
        !           200: //   X11 の keysym から来てる? (/usr/X11R7/include/X11/keysymdef.h)。
        !           201: //   ただし [A] と [SHIFT]+[A] が違うコードを返すというか、文字コードで
        !           202: //   表現出来る時は文字コード、みたいな感じになっているので、ここでは
        !           203: //   使いづらい。
        !           204: //   左右の SHIFT は区別可能。
        !           205: //   [^] と [SHIFT]+[^] もそもそも文字コードになるので '^' と '~' になる。
        !           206: //
        !           207: //  GetRawKeyFlags() は GDK の hardware keycode らしいけど、それが何か不明。
        !           208: //   左右の SHIFT は違うコードを返す。
        !           209: //   SHIFT を押しながらでもコードは変わらないっぽい。
        !           210: //   [^] と [SHIFT]+[^] は同じコードを返す。
        !           211: //
        !           212: // wxOSX の場合
        !           213: //  GetKeyCode()
        !           214: //   これは左右の SHIFT が区別できないが、
        !           215: //   それ以外はだいたい使えそうではある。
        !           216: //
        !           217: //  GetRawKeyCode()
        !           218: //   [A] と [SHIFT]+[A] などは同じコードを返す。
        !           219: //   左右の SHIFT は区別可能。
        !           220: //
        !           221: //  GetRawKeyFlags() は状態フラグか何かのようだ。
        !           222: //
        !           223: 
        !           224: // キーを押した
        !           225: void
        !           226: WXMainView::OnKeyDown(wxKeyEvent& event)
        !           227: {
        !           228:        DPRINTF("KeyDown ");
        !           229:        int keycode = GetKeyCode(event);
        !           230:        gKeyboard->MakeKey(keycode);
        !           231: }
        !           232: 
        !           233: // キーを離した
        !           234: void
        !           235: WXMainView::OnKeyUp(wxKeyEvent& event)
        !           236: {
        !           237:        DPRINTF("KeyUp   ");
        !           238:        int keycode = GetKeyCode(event);
        !           239:        gKeyboard->BreakKey(keycode);
        !           240: }
        !           241: 
        !           242: // 共通キーコードを取得する。
        !           243: // 対応するキーがない場合は -1 を返す。
        !           244: int
        !           245: WXMainView::GetKeyCode(wxKeyEvent& event)
        !           246: {
        !           247:        uint32 wxcode   __unused = event.GetKeyCode();
        !           248:        uint32 rawcode  __unused = event.GetRawKeyCode();
        !           249:        uint32 rawflags __unused = event.GetRawKeyFlags();
        !           250:        uint32 inp;
        !           251:        int keycode;
        !           252: 
        !           253: #if defined(__WXGTK__)
        !           254:        // wxGTK では RawKeyFlags を使う
        !           255:        DPRINTF("key=0x%03x raw=0x%04x <flags=0x%02x> ", wxcode, rawcode, rawflags);
        !           256:        inp = rawflags;
        !           257: #elif defined(__WXOSX__)
        !           258:        // wxOSX では RawKeyCode を使う
        !           259:        DPRINTF("key=0x%03x <raw=0x%02x> flags=0x%06x ", wxcode, rawcode, rawflags);
        !           260:        inp = rawcode;
        !           261: #endif
        !           262: 
        !           263:        // どちらにしてもテーブルを引く
        !           264:        if (inp < countof(keycode_table)) {
        !           265:                keycode = keycode_table[inp];
        !           266:        } else {
        !           267:                keycode = KC_none;
        !           268:        }
        !           269:        DPRINTF("keycode=%d %s\n", keycode, Keyboard::keyname[keycode]);
        !           270:        return keycode;
        !           271: }
        !           272: 
        !           273: #if defined(__WXGTK__)
        !           274: // wxGTK の RawKeyFlags を共通キーコードに変換するテーブル。
        !           275: /*static*/ const int
        !           276: WXMainView::keycode_table[0xd4] = {
        !           277:        KC_none,                // 0x00
        !           278:        KC_none,                // 0x01
        !           279:        KC_none,                // 0x02
        !           280:        KC_none,                // 0x03
        !           281:        KC_none,                // 0x04
        !           282:        KC_none,                // 0x05
        !           283:        KC_none,                // 0x06
        !           284:        KC_none,                // 0x07
        !           285:        KC_none,                // 0x08
        !           286:        KC_none,                // 0x09
        !           287:        KC_1,                   // 0x0a
        !           288:        KC_2,                   // 0x0b
        !           289:        KC_3,                   // 0x0c
        !           290:        KC_4,                   // 0x0d
        !           291:        KC_5,                   // 0x0e
        !           292:        KC_6,                   // 0x0f
        !           293: 
        !           294:        KC_7,                   // 0x10
        !           295:        KC_8,                   // 0x11
        !           296:        KC_9,                   // 0x12
        !           297:        KC_0,                   // 0x13
        !           298:        KC_minus,               // 0x14
        !           299:        KC_circum,              // 0x15
        !           300:        KC_BS,                  // 0x16
        !           301:        KC_TAB,                 // 0x17
        !           302:        KC_Q,                   // 0x18
        !           303:        KC_W,                   // 0x19
        !           304:        KC_E,                   // 0x1a
        !           305:        KC_R,                   // 0x1b
        !           306:        KC_T,                   // 0x1c
        !           307:        KC_Y,                   // 0x1d
        !           308:        KC_U,                   // 0x1e
        !           309:        KC_I,                   // 0x1f
        !           310: 
        !           311:        KC_O,                   // 0x20
        !           312:        KC_P,                   // 0x21
        !           313:        KC_at,                  // 0x22
        !           314:        KC_bracketleft, // 0x23
        !           315:        KC_enter,               // 0x24
        !           316:        KC_CTRL,                // 0x25 (CTRL_L)
        !           317:        KC_A,                   // 0x26
        !           318:        KC_S,                   // 0x27
        !           319:        KC_D,                   // 0x28
        !           320:        KC_F,                   // 0x29
        !           321:        KC_G,                   // 0x2a
        !           322:        KC_H,                   // 0x2b
        !           323:        KC_J,                   // 0x2c
        !           324:        KC_K,                   // 0x2d
        !           325:        KC_L,                   // 0x2e
        !           326:        KC_semicolon,   // 0x2f
        !           327: 
        !           328:        KC_colon,               // 0x30
        !           329:        KC_ESC,                 // 0x31
        !           330:        KC_SHIFT_L,             // 0x32 (SHIFT_L)
        !           331:        KC_bracketright,// 0x33
        !           332:        KC_Z,                   // 0x34
        !           333:        KC_X,                   // 0x35
        !           334:        KC_C,                   // 0x36
        !           335:        KC_V,                   // 0x37
        !           336:        KC_B,                   // 0x38
        !           337:        KC_N,                   // 0x39
        !           338:        KC_M,                   // 0x3a
        !           339:        KC_comma,               // 0x3b
        !           340:        KC_period,              // 0x3c
        !           341:        KC_slash,               // 0x3d
        !           342:        KC_SHIFT_R,             // 0x3e (SHIFT_R)
        !           343:        KC_PAD_multiply,// 0x3f
        !           344: 
        !           345:        KC_none,                // 0x40
        !           346:        KC_space,               // 0x41
        !           347:        KC_none,                // 0x42
        !           348:        KC_F1,                  // 0x43
        !           349:        KC_F2,                  // 0x44
        !           350:        KC_F3,                  // 0x45
        !           351:        KC_F4,                  // 0x46
        !           352:        KC_F5,                  // 0x47
        !           353:        KC_F6,                  // 0x48
        !           354:        KC_F7,                  // 0x49
        !           355:        KC_F8,                  // 0x4a
        !           356:        KC_F9,                  // 0x4b
        !           357:        KC_F10,                 // 0x4c
        !           358:        KC_none,                // 0x4d
        !           359:        KC_none,                // 0x4e
        !           360:        KC_PAD_7,               // 0x4f
        !           361: 
        !           362:        KC_PAD_8,               // 0x50
        !           363:        KC_PAD_9,               // 0x51
        !           364:        KC_PAD_minus,   // 0x52
        !           365:        KC_PAD_4,               // 0x53
        !           366:        KC_PAD_5,               // 0x54
        !           367:        KC_PAD_6,               // 0x55
        !           368:        KC_PAD_plus,    // 0x56
        !           369:        KC_PAD_1,               // 0x57
        !           370:        KC_PAD_2,               // 0x58
        !           371:        KC_PAD_3,               // 0x59
        !           372:        KC_PAD_0,               // 0x5a
        !           373:        KC_PAD_decimal, // 0x5b
        !           374:        KC_none,                // 0x5c
        !           375:        KC_none,                // 0x5d
        !           376:        KC_none,                // 0x5e
        !           377:        KC_none,                // 0x5f
        !           378: 
        !           379:        KC_none,                // 0x60
        !           380:        KC_none,                // 0x61
        !           381:        KC_up,                  // 0x62
        !           382:        KC_none,                // 0x63
        !           383:        KC_left,                // 0x64
        !           384:        KC_none,                // 0x65
        !           385:        KC_right,               // 0x66
        !           386:        KC_none,                // 0x67
        !           387:        KC_down,                // 0x68
        !           388:        KC_none,                // 0x69
        !           389:        KC_INS,                 // 0x6a
        !           390:        KC_DEL,                 // 0x6b
        !           391:        KC_PAD_enter,   // 0x6c
        !           392:        KC_CTRL,                // 0x6d (CTRL_R)
        !           393:        KC_none,                // 0x6e
        !           394:        KC_none,                // 0x6f
        !           395: 
        !           396:        KC_PAD_divide,  // 0x70
        !           397:        KC_none,                // 0x71
        !           398:        KC_none,                // 0x72
        !           399:        KC_none,                // 0x73
        !           400:        KC_none,                // 0x74
        !           401:        KC_none,                // 0x75
        !           402:        KC_none,                // 0x76
        !           403:        KC_none,                // 0x77
        !           404:        KC_none,                // 0x78
        !           405:        KC_none,                // 0x79
        !           406:        KC_none,                // 0x7a
        !           407:        KC_none,                // 0x7b
        !           408:        KC_none,                // 0x7c
        !           409:        KC_none,                // 0x7d
        !           410:        KC_none,                // 0x7e
        !           411:        KC_none,                // 0x7f
        !           412: 
        !           413:        KC_none,                // 0x80
        !           414:        KC_none,                // 0x81
        !           415:        KC_none,                // 0x82
        !           416:        KC_none,                // 0x83
        !           417:        KC_none,                // 0x84
        !           418:        KC_backslash,   // 0x85
        !           419:        KC_none,                // 0x86
        !           420:        KC_none,                // 0x87
        !           421:        KC_none,                // 0x88
        !           422:        KC_none,                // 0x89
        !           423:        KC_none,                // 0x8a
        !           424:        KC_none,                // 0x8b
        !           425:        KC_none,                // 0x8c
        !           426:        KC_none,                // 0x8d
        !           427:        KC_none,                // 0x8e
        !           428:        KC_none,                // 0x8f
        !           429: 
        !           430:        KC_none, KC_none, KC_none, KC_none, // 0x90
        !           431:        KC_none, KC_none, KC_none, KC_none,
        !           432:        KC_none, KC_none, KC_none, KC_none,
        !           433:        KC_none, KC_none, KC_none, KC_none,
        !           434: 
        !           435:        KC_none, KC_none, KC_none, KC_none, // 0xa0
        !           436:        KC_none, KC_none, KC_none, KC_none,
        !           437:        KC_none, KC_none, KC_none, KC_none,
        !           438:        KC_none, KC_none, KC_none, KC_none,
        !           439: 
        !           440:        KC_none, KC_none, KC_none, KC_none, // 0xb0
        !           441:        KC_none, KC_none, KC_none, KC_none,
        !           442:        KC_none, KC_none, KC_none, KC_none,
        !           443:        KC_none, KC_none, KC_none, KC_none,
        !           444: 
        !           445:        KC_none, KC_none, KC_none, KC_none, // 0xc0
        !           446:        KC_none, KC_none, KC_none, KC_none,
        !           447:        KC_none, KC_none, KC_none, KC_none,
        !           448:        KC_none, KC_none, KC_none, KC_none,
        !           449: 
        !           450:        KC_none,                // 0xd0
        !           451:        KC_none,                // 0xd1
        !           452:        KC_none,                // 0xd2
        !           453:        KC_underscore,  // 0xd3
        !           454: };
        !           455: #endif // __WXGTK__
        !           456: 
        !           457: #if defined(__WXOSX__)
        !           458: // wxOSX の RawKeyCode を共通キーコードに変換するテーブル。
        !           459: // Mac の CAPS は押す離すで一回分の KeyDown しか来ないのでちょっと放置。
        !           460: // [英数] と [かな] もちょっと放置。
        !           461: /*static*/ const int
        !           462: WXMainView::keycode_table[0x80] = {
        !           463:        KC_A,                   // 0x00
        !           464:        KC_S,                   // 0x01
        !           465:        KC_D,                   // 0x02
        !           466:        KC_F,                   // 0x03
        !           467:        KC_H,                   // 0x04
        !           468:        KC_G,                   // 0x05
        !           469:        KC_Z,                   // 0x06
        !           470:        KC_X,                   // 0x07
        !           471:        KC_C,                   // 0x08
        !           472:        KC_V,                   // 0x09
        !           473:        KC_none,                // 0x0a
        !           474:        KC_B,                   // 0x0b
        !           475:        KC_Q,                   // 0x0c
        !           476:        KC_W,                   // 0x0d
        !           477:        KC_E,                   // 0x0e
        !           478:        KC_R,                   // 0x0f
        !           479: 
        !           480:        KC_Y,                   // 0x10
        !           481:        KC_T,                   // 0x11
        !           482:        KC_1,                   // 0x12
        !           483:        KC_2,                   // 0x13
        !           484:        KC_3,                   // 0x14
        !           485:        KC_4,                   // 0x15
        !           486:        KC_6,                   // 0x16
        !           487:        KC_5,                   // 0x17
        !           488:        KC_circum,              // 0x18
        !           489:        KC_9,                   // 0x19
        !           490:        KC_7,                   // 0x1a
        !           491:        KC_minus,               // 0x1b
        !           492:        KC_8,                   // 0x1c
        !           493:        KC_0,                   // 0x1d
        !           494:        KC_bracketleft, // 0x1e
        !           495:        KC_O,                   // 0x1f
        !           496: 
        !           497:        KC_U,                   // 0x20
        !           498:        KC_at,                  // 0x21
        !           499:        KC_I,                   // 0x22
        !           500:        KC_P,                   // 0x23
        !           501:        KC_enter,               // 0x24
        !           502:        KC_L,                   // 0x25
        !           503:        KC_J,                   // 0x26
        !           504:        KC_colon,               // 0x27
        !           505:        KC_K,                   // 0x28
        !           506:        KC_semicolon,   // 0x29
        !           507:        KC_bracketright,// 0x2a
        !           508:        KC_comma,               // 0x2b
        !           509:        KC_slash,               // 0x2c
        !           510:        KC_N,                   // 0x2d
        !           511:        KC_M,                   // 0x2e
        !           512:        KC_period,              // 0x2f
        !           513: 
        !           514:        KC_TAB,                 // 0x30
        !           515:        KC_space,               // 0x31
        !           516:        KC_none,                // 0x32
        !           517:        KC_BS,                  // 0x33
        !           518:        KC_none,                // 0x34
        !           519:        KC_ESC,                 // 0x35
        !           520:        KC_none,                // 0x36
        !           521:        KC_none,                // 0x37
        !           522:        KC_SHIFT_L,             // 0x38
        !           523:        KC_none,                // 0x39
        !           524:        KC_none,                // 0x3a
        !           525:        KC_CTRL,                // 0x3b
        !           526:        KC_SHIFT_R,             // 0x3c
        !           527:        KC_none,                // 0x3d
        !           528:        KC_none,                // 0x3e
        !           529:        KC_none,                // 0x3f
        !           530: 
        !           531:        KC_none,                // 0x40
        !           532:        KC_none,                // 0x41
        !           533:        KC_none,                // 0x42
        !           534:        KC_none,                // 0x43
        !           535:        KC_none,                // 0x44
        !           536:        KC_none,                // 0x45
        !           537:        KC_none,                // 0x46
        !           538:        KC_none,                // 0x47
        !           539:        KC_none,                // 0x48
        !           540:        KC_none,                // 0x49
        !           541:        KC_none,                // 0x4a
        !           542:        KC_none,                // 0x4b
        !           543:        KC_none,                // 0x4c
        !           544:        KC_none,                // 0x4d
        !           545:        KC_none,                // 0x4e
        !           546:        KC_none,                // 0x4f
        !           547: 
        !           548:        KC_none,                // 0x50
        !           549:        KC_none,                // 0x51
        !           550:        KC_none,                // 0x52
        !           551:        KC_none,                // 0x53
        !           552:        KC_none,                // 0x54
        !           553:        KC_none,                // 0x55
        !           554:        KC_none,                // 0x56
        !           555:        KC_none,                // 0x57
        !           556:        KC_none,                // 0x58
        !           557:        KC_none,                // 0x59
        !           558:        KC_none,                // 0x5a
        !           559:        KC_none,                // 0x5b
        !           560:        KC_none,                // 0x5c
        !           561:        KC_backslash,   // 0x5d
        !           562:        KC_underscore,  // 0x5e
        !           563:        KC_none,                // 0x5f
        !           564: 
        !           565:        KC_F5,                  // 0x60
        !           566:        KC_F6,                  // 0x61
        !           567:        KC_F7,                  // 0x62
        !           568:        KC_F3,                  // 0x63
        !           569:        KC_F8,                  // 0x64
        !           570:        KC_F9,                  // 0x65
        !           571:        KC_none,                // 0x66
        !           572:        KC_none,                // 0x67 F11
        !           573:        KC_none,                // 0x68
        !           574:        KC_none,                // 0x69
        !           575:        KC_none,                // 0x6a
        !           576:        KC_none,                // 0x6b
        !           577:        KC_none,                // 0x6c
        !           578:        KC_F10,                 // 0x6d
        !           579:        KC_none,                // 0x6e
        !           580:        KC_none,                // 0x6f F12
        !           581: 
        !           582:        KC_none,                // 0x70
        !           583:        KC_none,                // 0x71
        !           584:        KC_none,                // 0x72
        !           585:        KC_none,                // 0x73
        !           586:        KC_none,                // 0x74
        !           587:        KC_none,                // 0x75
        !           588:        KC_F4,                  // 0x76
        !           589:        KC_none,                // 0x77
        !           590:        KC_F2,                  // 0x78
        !           591:        KC_none,                // 0x79
        !           592:        KC_F1,                  // 0x7a
        !           593:        KC_left,                // 0x7b
        !           594:        KC_right,               // 0x7c
        !           595:        KC_down,                // 0x7d
        !           596:        KC_up,                  // 0x7e
        !           597:        KC_none,                // 0x7f
        !           598: };
        !           599: #endif // __WXOSX__

unix.superglobalmegacorp.com

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