|
|
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"
1.1.1.3 root 9: #include "mystring.h"
1.1 root 10: #include "renderer.h"
11: #include "scheduler.h"
12: #include <wx/region.h>
13: #include <wx/event.h>
14:
15: //#define KEYDEBUG 1
1.1.1.2 root 16: //#define MOUSEDEBUG 1
1.1 root 17:
18: #if defined(KEYDEBUG)
1.1.1.2 root 19: #define DKPRINTF(...) printf(__VA_ARGS__)
1.1 root 20: #else
1.1.1.2 root 21: #define DKPRINTF(...) /**/
22: #endif
23:
24: #if defined(MOUSEDEBUG)
25: #define DMPRINTF(...) printf(__VA_ARGS__)
26: #else
27: #define DMPRINTF(...) /**/
1.1 root 28: #endif
29:
30: // 再描画矩形の指定方法について。
31: // DoRefresh() にて、VM スレッドが自発的に画面を更新する際は、
32: // パフォーマンスの観点からも更新矩形だけを再描画すべき。
33: // これを wxWidgets に指示するのが wxWindow::Refresh{,Rect}() であるが
34: // 一部のプラットフォームではこれを呼び出すと、アプリケーションウィンドウ
35: // 全体がささってしまい、MainView だけでなくメニューバーも含めたすべてが
36: // 再描画できなくなってしまう。仕方がないので、これらのプラットフォームでは
37: // Refresh{,Rect}() を呼ばず、再描画矩形を画面全体として運用する。
38: // ちょっと無駄なだけなので (動かないことに比べれば) 気にしない。
39: //
1.1.1.4 ! root 40: // 今のところ NetBSD (5.0 以降) と OpenBSD(/amd64)(-6.7)
! 41: // (と Linux (CentOS 6.3/x86_64)) が該当する。
! 42: #if defined(__NetBSD__) || defined(__OpenBSD__)
1.1 root 43: #define DONT_USE_REFRESH 1
44: #endif
45:
46: #define TIMERID_PAINTTIMER 1
47:
48: static void wxmainview_refresh();
49:
50: WXMainView *gMainView;
51:
52: wxBEGIN_EVENT_TABLE(WXMainView, inherited)
53: EVT_PAINT(WXMainView::OnPaint)
54: EVT_KEY_DOWN(WXMainView::OnKeyDown)
55: EVT_KEY_UP(WXMainView::OnKeyUp)
1.1.1.2 root 56: EVT_MOUSE_EVENTS(WXMainView::OnMouse)
1.1 root 57: EVT_TIMER(TIMERID_PAINTTIMER, WXMainView::OnTimer)
58: wxEND_EVENT_TABLE()
59:
60: WXMainView::WXMainView(wxWindow *parent)
61: : inherited(parent)
62: {
63: // 仮想画面(VM が描画する画面)
64: rendwidth = gRenderer->GetWidth();
65: rendheight = gRenderer->GetHeight();
66:
67: // レンダラバッファは常に仮想画面サイズ
68: int buflen = rendwidth * rendheight * 3;
1.1.1.4 ! root 69: ImageBuf.reset(new uint8_t[buflen]);
! 70: memset(&ImageBuf[0], 0x70, buflen);
1.1 root 71: // レンダラに通知
1.1.1.4 ! root 72: gRenderer->SetBuf(ImageBuf.get(), wxmainview_refresh);
1.1 root 73:
74: // 実画面 (ウィンドウの大きさ)
75: DoResize(screen_scale);
76:
77: paintTimer.SetOwner(this, TIMERID_PAINTTIMER);
78: paintTimer.Start(16);
79: paintRequested = true; // first paint request
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:
106: // PAINT イベントを投げる
107: // XXX んだけど mac だと投げすぎるとシステムイベントを拾えなくなってしまう
108: paintRequested = true;
109: }
110:
111: void
112: WXMainView::OnTimer(wxTimerEvent& event)
113: {
114: bool req = paintRequested.exchange(false);
115: if (req) {
116: // PAINT イベントを投げる
117: wxPaintEvent *ev = new wxPaintEvent();
118: QueueEvent(ev);
119: }
120: }
121:
122: // 描画イベント
123: void
124: WXMainView::OnPaint(wxPaintEvent& event)
125: {
126: wxClientDC dc(this);
127:
128: DoPaint(dc);
129: }
130:
131: // 描画実行
132: void
133: WXMainView::DoPaint(wxDC& dc)
134: {
135: if (viewwidth == 0 || viewheight == 0)
136: return;
137:
1.1.1.4 ! root 138: wxImage image(rendwidth, rendheight, ImageBuf.get(), true);
1.1 root 139:
140: if (viewwidth != rendwidth || viewheight != rendheight) {
141: // wxIMAGE_QUALITY_NORMAL だと速いが、品質優先。
142: image.Rescale(viewwidth, viewheight, wxIMAGE_QUALITY_HIGH);
143: }
144:
145: wxBitmap bitmap(image);
146: wxMemoryDC memDC;
147: memDC.SelectObject(bitmap);
148:
149: wxRegion region(0, 0, viewwidth, viewheight);
150: wxRegionIterator ri(region);
151: for (; ri; ri++) {
152: int dx, dy, dw, dh;
153: dx = ri.GetX();
154: dy = ri.GetY();
155: dw = ri.GetWidth();
156: dh = ri.GetHeight();
157: int sx = dx;
158: int sy = dy;
159: dc.Blit(dx, dy, dw, dh, &memDC, sx, sy, wxCOPY);
160: }
161: }
162:
163: // リサイズ (UI スレッドから呼ぶこと)
164: void
165: WXMainView::DoResize(double scale)
166: {
167: screen_scale = scale;
168: int width = (double)rendwidth * scale;
169: int height = (double)rendheight * scale;
170: if (viewwidth != width || viewheight != height) {
171: // ウィンドウサイズ変更
172: viewwidth = width;
173: viewheight = height;
174: SetClientSize(viewwidth, viewheight);
175: SetMinSize(wxSize(viewwidth, viewheight));
176: }
177: }
178:
179: // 現在のスケールを返す。
180: // screen_scale は public static なので見えるんだけど一応お行儀で。
181: double
182: WXMainView::GetScale() const
183: {
184: return screen_scale;
185: }
186:
187: // 現在のスケール
188: /*static*/ double WXMainView::screen_scale;
189:
190:
191: //
1.1.1.2 root 192: // マウス入力
193: //
194:
195: // マウスモード設定
196: void
197: WXMainView::SetMouseMode(bool mode)
198: {
199: // XXX マウスモード ON にした時の座標を記憶してそこに戻るのはどうか
200:
201: mousemode = mode;
202: if (mousemode) {
203: // マウスモードを ON にする
204: DMPRINTF("SetMouseMode ON\n");
205:
206: // マウスカーソル OFF
207: ::wxSetCursor(wxCursor(wxCURSOR_BLANK));
208:
1.1.1.4 ! root 209: CaptureMouse();
! 210:
1.1.1.2 root 211: // このウィンドウから外れないように移動を検出し続けるため、
212: // マウスカーソルをウィンドウ中央に移す。
213: // ウィンドウとメニューバーが分離してる wxOSX のために必要。
214: MyWarpPointer(GetClientSize() / 2);
215: } else {
216: // マウスモードを OFF にする
217: DMPRINTF("SetMouseMode OFF\n");
218:
1.1.1.4 ! root 219: ReleaseMouse();
! 220:
1.1.1.2 root 221: // 分かりやすさのため、マウスカーソルを中央へ戻してから復帰
1.1.1.4 ! root 222: wxSize pt = GetClientSize() / 2;
! 223: WarpPointer(pt.x, pt.y);
1.1.1.2 root 224:
225: // マウスカーソル ON
226: ::wxSetCursor(wxNullCursor);
227: }
228: }
229:
230: // マウスカーソルをクライアント座標 (x, y) に移動
231: void
232: WXMainView::MyWarpPointer(wxSize pos)
233: {
234: DMPRINTF("MyWarpPointer %d,%d\n", pos.x, pos.y);
235:
236: // この後の MDWarpPointer() でもう一度 EVT_MOTION が飛ぶので
237: // それを判別するためのフラグ。
238: motion_by_warp_pointer = true;
239:
240: WarpPointer(pos.x, pos.y);
241: }
242:
243: // マウスイベント
244: void
245: WXMainView::OnMouse(wxMouseEvent& event)
246: {
247: // マウスモードの時だけ処理。
248: // XXX 本当はイベントごと Disconnect したい
249: if (mousemode) {
250: bool leaving = event.Leaving();
251: bool moving = event.Moving();
1.1.1.3 root 252: bool dragging = event.Dragging();
1.1.1.2 root 253: // LeftDown() 等は押された時、LeftIsDown() 等は押されてる間 true。
254: bool rb = event.RightIsDown();
255: bool lb = event.LeftIsDown();
256: bool mb = event.MiddleIsDown();
257: wxPoint pos = event.GetPosition();
258: int dx = 0;
259: int dy = 0;
260:
1.1.1.3 root 261: #if defined(MOUSEDEBUG)
262: std::string dstr = "OnMouse";
263: if (moving || dragging || motion_by_warp_pointer) {
264: dstr += string_format(" (%d,%d)", pos.x, pos.y);
265: }
266: if (moving)
267: dstr += " Moving";
268: if (dragging)
269: dstr += " Dragging";
270: if (motion_by_warp_pointer)
271: dstr += " MotionByWarp";
1.1.1.4 ! root 272: if (lb || mb || rb) {
1.1.1.3 root 273: dstr += string_format(" Button(%c%c%c)",
274: (lb ? 'L' : '-'),
275: (mb ? 'M' : '-'),
276: (rb ? 'R' : '-'));
277: }
278: if (leaving)
279: dstr += " Leaving";
280: printf("%s\n", dstr.c_str());
281: #endif
1.1.1.2 root 282:
283: if (leaving) {
284: // タスクスイッチした時とかのための自動リリース
285: SetMouseMode(false);
286: }
287:
1.1.1.3 root 288: if (moving || dragging) {
1.1.1.2 root 289: // (My)WarpPointer() で自発的にマウスカーソルを移動させたことで
290: // 来る EVT_MOTION は無視する。
291: if (motion_by_warp_pointer) {
292: motion_by_warp_pointer = false;
293: // ここを基準点にする
294: prevpos = pos;
295: } else {
296: // 前回からの差を求める
297: dx = pos.x - prevpos.x;
298: dy = pos.y - prevpos.y;
299: prevpos = pos;
300:
301: // マウスカーソルを中心に戻す
302: if (dx != 0 || dy != 0) {
303: MyWarpPointer(GetClientSize() / 2);
304: }
305: }
306: }
307:
308: // VM に入力
1.1.1.3 root 309: if (dx != 0 ||
310: dy != 0 ||
311: lb != prevlb ||
312: mb != prevmb ||
313: rb != prevrb )
314: {
1.1.1.2 root 315: DMPRINTF(" Input dx=%d dy=%d %c%c%c\n",
316: dx, dy,
317: (lb ? 'L' : '-'),
318: (mb ? 'M' : '-'),
319: (rb ? 'R' : '-'));
320:
321: gKeyboard->MouseInput(dx, dy, rb, lb, mb);
322: }
1.1.1.3 root 323:
324: prevlb = lb;
325: prevmb = mb;
326: prevrb = rb;
1.1.1.2 root 327: }
328:
329: // EVT_LEFT_DOWN をデフォルト処理するため
330: event.Skip();
331: }
332:
1.1.1.4 ! root 333: // アクティベートイベント。
! 334: // この(トップレベル)ウィンドウにフォーカスが当たるか外れるかで飛んでくる。
! 335: // 実際には WXMainFrame 宛てに飛んできたイベントをこちらに転送してある。
! 336: // マウスモード中にこのウィンドウからフォーカスが外れたら (例えば ALT+TAB の
! 337: // ようなウィンドウを切り替える操作)、マウスモードを解除するため。
! 338: void
! 339: WXMainView::OnActivate(wxActivateEvent& event)
! 340: {
! 341: // フォーカスが外れる際にマウスモード中ならマウスモードを解除
! 342: if (event.GetActive() == false) {
! 343: DMPRINTF("OnActivate FocusOut\n");
! 344: if (mousemode) {
! 345: SetMouseMode(false);
! 346: }
! 347: } else {
! 348: DMPRINTF("OnActivate FocusIn\n");
! 349: }
! 350: }
! 351:
! 352:
1.1.1.2 root 353: //
1.1 root 354: // キー入力
355: //
356:
357: // wxKeyEvent でキーコードを得るためのメソッドは
358: // GetKeyCode()、GetRawKeyCode()、GetRawKeyFlags() の3つが用意されていて
359: // wxWigets の port (wxGTK、wxOSX とか) によってそれぞれ内容の定義が違う。
360: //
361: // wxGTK の場合
362: // GetKeyCode() は wxWidgets の WXK_* (/usr/pkg/include/wx-3.0/wx/defs.h)。
363: // これは左右の SHIFT が区別できないが、
364: // それ以外はだいたい使えそうではある。
365: //
366: // GetRawKeyCode() は GDK の keycode っぽい?
367: // (/usr/pkg/include/gtk-2.0/gdk/gdkkeysyms.h)。
368: // X11 の keysym から来てる? (/usr/X11R7/include/X11/keysymdef.h)。
369: // ただし [A] と [SHIFT]+[A] が違うコードを返すというか、文字コードで
370: // 表現出来る時は文字コード、みたいな感じになっているので、ここでは
371: // 使いづらい。
372: // 左右の SHIFT は区別可能。
373: // [^] と [SHIFT]+[^] もそもそも文字コードになるので '^' と '~' になる。
374: //
375: // GetRawKeyFlags() は GDK の hardware keycode らしいけど、それが何か不明。
376: // 左右の SHIFT は違うコードを返す。
377: // SHIFT を押しながらでもコードは変わらないっぽい。
378: // [^] と [SHIFT]+[^] は同じコードを返す。
379: //
380: // wxOSX の場合
381: // GetKeyCode()
382: // これは左右の SHIFT が区別できないが、
383: // それ以外はだいたい使えそうではある。
384: //
385: // GetRawKeyCode()
386: // [A] と [SHIFT]+[A] などは同じコードを返す。
387: // 左右の SHIFT は区別可能。
388: //
389: // GetRawKeyFlags() は状態フラグか何かのようだ。
390: //
391:
392: // キーを押した
393: void
394: WXMainView::OnKeyDown(wxKeyEvent& event)
395: {
1.1.1.2 root 396: DKPRINTF("KeyDown ");
1.1 root 397: int keycode = GetKeyCode(event);
398: gKeyboard->MakeKey(keycode);
1.1.1.2 root 399:
400: // メニューのアクセラレータのために必要
401: event.Skip();
1.1 root 402: }
403:
404: // キーを離した
405: void
406: WXMainView::OnKeyUp(wxKeyEvent& event)
407: {
1.1.1.2 root 408: DKPRINTF("KeyUp ");
1.1 root 409: int keycode = GetKeyCode(event);
410: gKeyboard->BreakKey(keycode);
411: }
412:
413: // 共通キーコードを取得する。
414: // 対応するキーがない場合は -1 を返す。
415: int
416: WXMainView::GetKeyCode(wxKeyEvent& event)
417: {
418: uint32 wxcode __unused = event.GetKeyCode();
419: uint32 rawcode __unused = event.GetRawKeyCode();
420: uint32 rawflags __unused = event.GetRawKeyFlags();
421: uint32 inp;
422: int keycode;
423:
424: #if defined(__WXGTK__)
425: // wxGTK では RawKeyFlags を使う
1.1.1.2 root 426: DKPRINTF("key=0x%03x raw=0x%04x <flags=0x%02x> ",
427: wxcode, rawcode, rawflags);
1.1 root 428: inp = rawflags;
429: #elif defined(__WXOSX__)
430: // wxOSX では RawKeyCode を使う
1.1.1.2 root 431: DKPRINTF("key=0x%03x <raw=0x%02x> flags=0x%06x ",
432: wxcode, rawcode, rawflags);
1.1 root 433: inp = rawcode;
434: #endif
435:
436: // どちらにしてもテーブルを引く
437: if (inp < countof(keycode_table)) {
438: keycode = keycode_table[inp];
439: } else {
440: keycode = KC_none;
441: }
1.1.1.2 root 442: DKPRINTF("keycode=%d %s\n", keycode, Keyboard::keyname[keycode]);
1.1 root 443: return keycode;
444: }
445:
446: #if defined(__WXGTK__)
447: // wxGTK の RawKeyFlags を共通キーコードに変換するテーブル。
448: /*static*/ const int
449: WXMainView::keycode_table[0xd4] = {
450: KC_none, // 0x00
451: KC_none, // 0x01
452: KC_none, // 0x02
453: KC_none, // 0x03
454: KC_none, // 0x04
455: KC_none, // 0x05
456: KC_none, // 0x06
457: KC_none, // 0x07
458: KC_none, // 0x08
459: KC_none, // 0x09
460: KC_1, // 0x0a
461: KC_2, // 0x0b
462: KC_3, // 0x0c
463: KC_4, // 0x0d
464: KC_5, // 0x0e
465: KC_6, // 0x0f
466:
467: KC_7, // 0x10
468: KC_8, // 0x11
469: KC_9, // 0x12
470: KC_0, // 0x13
471: KC_minus, // 0x14
472: KC_circum, // 0x15
473: KC_BS, // 0x16
474: KC_TAB, // 0x17
475: KC_Q, // 0x18
476: KC_W, // 0x19
477: KC_E, // 0x1a
478: KC_R, // 0x1b
479: KC_T, // 0x1c
480: KC_Y, // 0x1d
481: KC_U, // 0x1e
482: KC_I, // 0x1f
483:
484: KC_O, // 0x20
485: KC_P, // 0x21
486: KC_at, // 0x22
487: KC_bracketleft, // 0x23
488: KC_enter, // 0x24
489: KC_CTRL, // 0x25 (CTRL_L)
490: KC_A, // 0x26
491: KC_S, // 0x27
492: KC_D, // 0x28
493: KC_F, // 0x29
494: KC_G, // 0x2a
495: KC_H, // 0x2b
496: KC_J, // 0x2c
497: KC_K, // 0x2d
498: KC_L, // 0x2e
499: KC_semicolon, // 0x2f
500:
501: KC_colon, // 0x30
502: KC_ESC, // 0x31
503: KC_SHIFT_L, // 0x32 (SHIFT_L)
504: KC_bracketright,// 0x33
505: KC_Z, // 0x34
506: KC_X, // 0x35
507: KC_C, // 0x36
508: KC_V, // 0x37
509: KC_B, // 0x38
510: KC_N, // 0x39
511: KC_M, // 0x3a
512: KC_comma, // 0x3b
513: KC_period, // 0x3c
514: KC_slash, // 0x3d
515: KC_SHIFT_R, // 0x3e (SHIFT_R)
516: KC_PAD_multiply,// 0x3f
517:
518: KC_none, // 0x40
519: KC_space, // 0x41
520: KC_none, // 0x42
521: KC_F1, // 0x43
522: KC_F2, // 0x44
523: KC_F3, // 0x45
524: KC_F4, // 0x46
525: KC_F5, // 0x47
526: KC_F6, // 0x48
527: KC_F7, // 0x49
528: KC_F8, // 0x4a
529: KC_F9, // 0x4b
530: KC_F10, // 0x4c
531: KC_none, // 0x4d
532: KC_none, // 0x4e
533: KC_PAD_7, // 0x4f
534:
535: KC_PAD_8, // 0x50
536: KC_PAD_9, // 0x51
537: KC_PAD_minus, // 0x52
538: KC_PAD_4, // 0x53
539: KC_PAD_5, // 0x54
540: KC_PAD_6, // 0x55
541: KC_PAD_plus, // 0x56
542: KC_PAD_1, // 0x57
543: KC_PAD_2, // 0x58
544: KC_PAD_3, // 0x59
545: KC_PAD_0, // 0x5a
546: KC_PAD_decimal, // 0x5b
547: KC_none, // 0x5c
548: KC_none, // 0x5d
549: KC_none, // 0x5e
550: KC_none, // 0x5f
551:
552: KC_none, // 0x60
553: KC_none, // 0x61
554: KC_up, // 0x62
555: KC_none, // 0x63
556: KC_left, // 0x64
557: KC_none, // 0x65
558: KC_right, // 0x66
559: KC_none, // 0x67
560: KC_down, // 0x68
561: KC_none, // 0x69
562: KC_INS, // 0x6a
563: KC_DEL, // 0x6b
564: KC_PAD_enter, // 0x6c
565: KC_CTRL, // 0x6d (CTRL_R)
566: KC_none, // 0x6e
567: KC_none, // 0x6f
568:
569: KC_PAD_divide, // 0x70
570: KC_none, // 0x71
571: KC_none, // 0x72
572: KC_none, // 0x73
573: KC_none, // 0x74
574: KC_none, // 0x75
575: KC_none, // 0x76
576: KC_none, // 0x77
577: KC_none, // 0x78
578: KC_none, // 0x79
579: KC_none, // 0x7a
580: KC_none, // 0x7b
581: KC_none, // 0x7c
582: KC_none, // 0x7d
583: KC_none, // 0x7e
584: KC_none, // 0x7f
585:
586: KC_none, // 0x80
587: KC_none, // 0x81
588: KC_none, // 0x82
589: KC_none, // 0x83
590: KC_none, // 0x84
591: KC_backslash, // 0x85
592: KC_none, // 0x86
593: KC_none, // 0x87
594: KC_none, // 0x88
595: KC_none, // 0x89
596: KC_none, // 0x8a
597: KC_none, // 0x8b
598: KC_none, // 0x8c
599: KC_none, // 0x8d
600: KC_none, // 0x8e
601: KC_none, // 0x8f
602:
603: KC_none, KC_none, KC_none, KC_none, // 0x90
604: KC_none, KC_none, KC_none, KC_none,
605: KC_none, KC_none, KC_none, KC_none,
606: KC_none, KC_none, KC_none, KC_none,
607:
608: KC_none, KC_none, KC_none, KC_none, // 0xa0
609: KC_none, KC_none, KC_none, KC_none,
610: KC_none, KC_none, KC_none, KC_none,
611: KC_none, KC_none, KC_none, KC_none,
612:
613: KC_none, KC_none, KC_none, KC_none, // 0xb0
614: KC_none, KC_none, KC_none, KC_none,
615: KC_none, KC_none, KC_none, KC_none,
616: KC_none, KC_none, KC_none, KC_none,
617:
618: KC_none, KC_none, KC_none, KC_none, // 0xc0
619: KC_none, KC_none, KC_none, KC_none,
620: KC_none, KC_none, KC_none, KC_none,
621: KC_none, KC_none, KC_none, KC_none,
622:
623: KC_none, // 0xd0
624: KC_none, // 0xd1
625: KC_none, // 0xd2
626: KC_underscore, // 0xd3
627: };
628: #endif // __WXGTK__
629:
630: #if defined(__WXOSX__)
631: // wxOSX の RawKeyCode を共通キーコードに変換するテーブル。
632: // Mac の CAPS は押す離すで一回分の KeyDown しか来ないのでちょっと放置。
633: // [英数] と [かな] もちょっと放置。
634: /*static*/ const int
635: WXMainView::keycode_table[0x80] = {
636: KC_A, // 0x00
637: KC_S, // 0x01
638: KC_D, // 0x02
639: KC_F, // 0x03
640: KC_H, // 0x04
641: KC_G, // 0x05
642: KC_Z, // 0x06
643: KC_X, // 0x07
644: KC_C, // 0x08
645: KC_V, // 0x09
646: KC_none, // 0x0a
647: KC_B, // 0x0b
648: KC_Q, // 0x0c
649: KC_W, // 0x0d
650: KC_E, // 0x0e
651: KC_R, // 0x0f
652:
653: KC_Y, // 0x10
654: KC_T, // 0x11
655: KC_1, // 0x12
656: KC_2, // 0x13
657: KC_3, // 0x14
658: KC_4, // 0x15
659: KC_6, // 0x16
660: KC_5, // 0x17
661: KC_circum, // 0x18
662: KC_9, // 0x19
663: KC_7, // 0x1a
664: KC_minus, // 0x1b
665: KC_8, // 0x1c
666: KC_0, // 0x1d
667: KC_bracketleft, // 0x1e
668: KC_O, // 0x1f
669:
670: KC_U, // 0x20
671: KC_at, // 0x21
672: KC_I, // 0x22
673: KC_P, // 0x23
674: KC_enter, // 0x24
675: KC_L, // 0x25
676: KC_J, // 0x26
677: KC_colon, // 0x27
678: KC_K, // 0x28
679: KC_semicolon, // 0x29
680: KC_bracketright,// 0x2a
681: KC_comma, // 0x2b
682: KC_slash, // 0x2c
683: KC_N, // 0x2d
684: KC_M, // 0x2e
685: KC_period, // 0x2f
686:
687: KC_TAB, // 0x30
688: KC_space, // 0x31
689: KC_none, // 0x32
690: KC_BS, // 0x33
691: KC_none, // 0x34
692: KC_ESC, // 0x35
693: KC_none, // 0x36
694: KC_none, // 0x37
695: KC_SHIFT_L, // 0x38
696: KC_none, // 0x39
697: KC_none, // 0x3a
698: KC_CTRL, // 0x3b
699: KC_SHIFT_R, // 0x3c
700: KC_none, // 0x3d
701: KC_none, // 0x3e
702: KC_none, // 0x3f
703:
704: KC_none, // 0x40
705: KC_none, // 0x41
706: KC_none, // 0x42
707: KC_none, // 0x43
708: KC_none, // 0x44
709: KC_none, // 0x45
710: KC_none, // 0x46
711: KC_none, // 0x47
712: KC_none, // 0x48
713: KC_none, // 0x49
714: KC_none, // 0x4a
715: KC_none, // 0x4b
716: KC_none, // 0x4c
717: KC_none, // 0x4d
718: KC_none, // 0x4e
719: KC_none, // 0x4f
720:
721: KC_none, // 0x50
722: KC_none, // 0x51
723: KC_none, // 0x52
724: KC_none, // 0x53
725: KC_none, // 0x54
726: KC_none, // 0x55
727: KC_none, // 0x56
728: KC_none, // 0x57
729: KC_none, // 0x58
730: KC_none, // 0x59
731: KC_none, // 0x5a
732: KC_none, // 0x5b
733: KC_none, // 0x5c
734: KC_backslash, // 0x5d
735: KC_underscore, // 0x5e
736: KC_none, // 0x5f
737:
738: KC_F5, // 0x60
739: KC_F6, // 0x61
740: KC_F7, // 0x62
741: KC_F3, // 0x63
742: KC_F8, // 0x64
743: KC_F9, // 0x65
744: KC_none, // 0x66
745: KC_none, // 0x67 F11
746: KC_none, // 0x68
747: KC_none, // 0x69
748: KC_none, // 0x6a
749: KC_none, // 0x6b
750: KC_none, // 0x6c
751: KC_F10, // 0x6d
752: KC_none, // 0x6e
753: KC_none, // 0x6f F12
754:
755: KC_none, // 0x70
756: KC_none, // 0x71
757: KC_none, // 0x72
758: KC_none, // 0x73
759: KC_none, // 0x74
760: KC_none, // 0x75
761: KC_F4, // 0x76
762: KC_none, // 0x77
763: KC_F2, // 0x78
764: KC_none, // 0x79
765: KC_F1, // 0x7a
766: KC_left, // 0x7b
767: KC_right, // 0x7c
768: KC_down, // 0x7d
769: KC_up, // 0x7e
770: KC_none, // 0x7f
771: };
772: #endif // __WXOSX__
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.