|
|
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: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.