OSDN Git Service

[Qt][UI][KEYBOARD][FM77AV] Use keyevent->nativeScanCode() to resolve issue of pressed...
[csp-qt/common_source_project-fm7.git] / source / src / qt / gui / qt_input.cpp
1 /*
2  *      Skelton for retropc emulator
3  *
4  *      Author : Takeda.Toshiya
5  *      Date   : 2006.08.18 -
6  *      Converted to QT by (C) 2015 K.Ohta
7  *         History:
8  *            Jan 12, 2015 (maybe) : Initial
9  *      [ Qt input -> Keyboard]
10 */
11
12 #include <Qt>
13 #include <QKeyEvent>
14 #include "emu.h"
15 #include "vm/vm.h"
16 #include "config.h"
17
18 //#include "fifo.h"
19 //#include "fileio.h"
20
21 #include "qt_input.h"
22 #include "qt_gldraw.h"
23 #include "qt_main.h"
24 #include "menuclasses.h"
25 #include "agar_logger.h"
26
27 #ifndef Ulong
28 #define Ulong unsigned long
29 #endif
30
31 #define KEY_KEEP_FRAMES 3
32
33 static int mouse_x = 0;
34 static int mouse_y = 0;
35 static int mouse_relx = 0;
36 static int mouse_rely = 0;
37 static uint32 mouse_buttons = 0;
38    
39 struct NativeScanCode {
40         uint32 vk;
41         uint32 scan;
42 };
43 struct NativeVirtualKeyCode {
44         uint32 vk;
45         uint32 key;
46 };
47
48 struct NativeScanCode convTable_QTScan106[] = {
49         // Line 0
50         {VK_ESCAPE,  9},
51         {VK_F1,  67},
52         {VK_F2,  68},
53         {VK_F3,  69},
54         {VK_F4,  70},
55         {VK_F5,  71},
56         {VK_F6,  72},
57         {VK_F7,  73},
58         {VK_F8,  74},
59         {VK_F9,  75},
60         {VK_F10, 76},
61         {VK_F11, 95},
62         {VK_F12, 96},
63         // Power, Sleep, Wake is not implemented, they are'nt safety.
64         // Line 1
65         {VK_KANJI, 49}, // Hankaku/Zenkaku
66         {'0', 19},
67         {'1', 10},
68         {'2', 11},
69         {'3', 12},
70         {'4', 13},
71         {'5', 14},
72         {'6', 15},
73         {'7', 16},
74         {'8', 17},
75         {'9', 18},
76         {VK_OEM_MINUS, 20}, // - =
77         {VK_OEM_7, 21}, // ^~
78         {VK_OEM_5, 132}, // \|
79         {VK_BACK, 22}, // Backspace
80         // Line 2
81         {VK_TAB, 23},
82         {'Q', 24},
83         {'W', 25},
84         {'E', 26},
85         {'R', 27},
86         {'T', 28},
87         {'Y', 29},
88         {'U', 30},
89         {'I', 31},
90         {'O', 32},
91         {'P', 33},
92         {VK_OEM_3, 34}, // @
93         {VK_RETURN, 36}, // Enter (Full key)
94         {VK_OEM_4, 35}, // [
95         // Line 3
96         {VK_OEM_ATTN, 66}, // CAPS Lock
97         {'A', 38},
98         {'S', 39},
99         {'D', 40},
100         {'F', 41},
101         {'G', 42},
102         {'H', 43},
103         {'J', 44},
104         {'K', 45},
105         {'L', 46},
106         {VK_OEM_PLUS, 47}, // ;
107         {VK_OEM_1, 48}, // :
108         {VK_OEM_6, 51}, // ]
109         // Line 3
110         {VK_LSHIFT, 50}, // LShift
111         {'Z', 52},
112         {'X', 53},
113         {'C', 54},
114         {'V', 55},
115         {'B', 56},
116         {'N', 57},
117         {'M', 58},
118         {VK_OEM_COMMA, 59}, // ,
119         {VK_OEM_PERIOD, 60}, // .
120         {VK_OEM_2, 61}, // /(Slash)
121         {VK_OEM_102, 97}, //\_
122         {VK_RSHIFT, 62},
123         // Line 4
124         {VK_LCONTROL, 37},
125         {VK_LWIN, 133},
126         {VK_LMENU, 64},
127         {VK_NONCONVERT, 102}, // Muhenkan
128         {VK_SPACE, 65},
129         {VK_CONVERT, 100}, // Henkan
130         {VK_OEM_COPY, 101}, // Katakana_Hiragana
131         {VK_RMENU, 108},
132         {VK_RWIN,  134},
133         {VK_APPS, 135},
134         {VK_RCONTROL, 105},
135         // Cursors
136         {VK_UP, 111},
137         {VK_DOWN, 116},
138         {VK_LEFT, 113},
139         {VK_RIGHT,114},
140         // 
141         //     {VK_PRINT, },
142         {VK_SCROLL, 78},
143         {VK_PAUSE, 127},
144         {VK_INSERT, 118},
145         {VK_HOME, 110},
146         {VK_NEXT, 112},
147         {VK_DELETE, 119},
148         {VK_END, 115},
149         {VK_PRIOR, 117},
150         // TenKey
151         {VK_NUMPAD0, 90},
152         {VK_NUMPAD1, 87},
153         {VK_NUMPAD2, 88},
154         {VK_NUMPAD3, 89},
155         {VK_NUMPAD4, 83},
156         {VK_NUMPAD5, 84},
157         {VK_NUMPAD6, 85},
158         {VK_NUMPAD7, 79},
159         {VK_NUMPAD8, 80},
160         {VK_NUMPAD9, 81},
161         //
162         {VK_DECIMAL, 77}, // NumLock     
163         {VK_DIVIDE, 106},
164         {VK_MULTIPLY, 63},
165         {VK_SUBTRACT, 82},
166         {VK_ADD, 86},
167         {VK_RETURN, 104},  // Enter(ten Key)
168         {0xffffffff, 0xffffffff}
169 };
170 #if defined(Q_OS_WIN32)
171 #else // Linux or Unix
172 const struct NativeVirtualKeyCode convTable_QTKey[] = {
173         // Line 0
174         {VK_ESCAPE,  0xff1b},
175         {VK_F1,  0xffbe},
176         {VK_F2,  0xffbf},
177         {VK_F3,  0xffc0},
178         {VK_F4,  0xffc1},
179         {VK_F5,  0xffc2},
180         {VK_F6,  0xffc3},
181         {VK_F7,  0xffc4},
182         {VK_F8,  0xffc5},
183         {VK_F9,  0xffc6},
184         {VK_F10, 0xffc7},
185         {VK_F11, 0xffc8},
186         {VK_F12, 0xffc9},
187         // Power, Sleep, Wake is not implemented, they are'nt safety.
188         // Line 1
189         {VK_KANJI, 0xff2a}, // Hankaku/Zenkaku
190         {VK_OEM_MINUS, 0x002d}, // -=
191         {VK_OEM_MINUS, 0x003d},
192         {VK_OEM_7, 0x005e}, // ^~
193         {VK_OEM_7, 0x007e},
194         {VK_OEM_5, 0x005c}, // \|
195         {VK_OEM_5, 0x007c},
196         {VK_BACK, 0xff08}, // Backspace
197         // Line 2
198         {VK_TAB, 0xff09},
199         {VK_RETURN, 0xff0d}, // Enter (Full key)
200         {VK_OEM_3, 0x0040}, // @
201         {VK_OEM_3, 0x0060}, // @
202
203         {VK_OEM_4, 0x005b}, // [
204         {VK_OEM_4, 0x007b}, // [
205         // Line 3
206         {VK_OEM_ATTN, 0xff30}, // CAPS Lock
207         {VK_OEM_PLUS, 0x002b}, // ;
208         {VK_OEM_PLUS, 0x003b}, // ;
209         {VK_OEM_1, 0x002a}, // :
210         {VK_OEM_1, 0x003a}, // :
211         {VK_OEM_6, 0x005d}, // ]
212         {VK_OEM_6, 0x007d}, // ]
213         // Line 3
214         {VK_LSHIFT, 0xffe1}, // LShift
215         {VK_OEM_COMMA, 0x2c}, // ,
216         {VK_OEM_COMMA, 0x3c}, // ,
217         {VK_OEM_PERIOD, 0x2e}, // .
218         {VK_OEM_PERIOD, 0x3e}, // .
219         {VK_OEM_2, 0x2f}, // /(Slash)
220         {VK_OEM_2, 0x3f}, // /(Slash)
221         {VK_OEM_102, 0x5f}, //\_
222         //{0xe2, 0x5c}, //\_
223         {VK_RSHIFT, 0xffe2},
224         // Line 4
225         {VK_LCONTROL, 0xffe3},
226         {VK_LWIN, 0xffeb},
227         {VK_LMENU, 0xffe9},
228         {VK_NONCONVERT, 0xff22}, // Muhenkan
229         {VK_SPACE, 0x0020},
230         //{VK_OEM_AUTO, 0xff23}, // Henkan
231         {VK_CONVERT, 0xff23}, // Henkan
232         {VK_OEM_COPY, 0xff27}, // Katakana_Hiragana
233         {VK_RMENU, 0xffea},
234         {VK_RWIN,  0xffec},
235         {VK_APPS, 0xff67},
236         {VK_RCONTROL, 0xffe4},
237         // Cursors
238         {VK_UP, 0xff52},
239         {VK_DOWN, 0xff54},
240         {VK_LEFT, 0xff51},
241         {VK_RIGHT,0xff53},
242         // 
243         //     {VK_PRINT, },
244         {VK_SCROLL, 0xff14},
245         {VK_PAUSE, 0xff13},
246         {VK_INSERT, 0xff63},
247         {VK_HOME, 0xff50},
248         {VK_NEXT, 0xff55},
249         {VK_DELETE, 0xffff},
250         {VK_END, 0xff57},
251         {VK_PRIOR, 0xff56},
252         // TenKey
253         {VK_NUMPAD0, 0xffb0},
254         {VK_NUMPAD1, 0xffb1},
255         {VK_NUMPAD2, 0xffb2},
256         {VK_NUMPAD3, 0xffb3},
257         {VK_NUMPAD4, 0xffb4},
258         {VK_NUMPAD5, 0xffb5},
259         {VK_NUMPAD6, 0xffb6},
260         {VK_NUMPAD7, 0xffb7},
261         {VK_NUMPAD8, 0xffb8},
262         {VK_NUMPAD9, 0xffb9},
263         //
264         {VK_DECIMAL, 0xff7f}, // NumLock     
265         {VK_DIVIDE, 0xffaf},
266         {VK_MULTIPLY, 0xffaa},
267         {VK_SUBTRACT, 0xffad},
268         {VK_ADD, 0xffab},
269         {VK_RETURN, 0xff8d},  // Enter(ten Key)
270         {VK_DECIMAL, 0xffae},  // Period(ten Key)
271         {0xffffffff, 0xffffffff}
272 };
273 #endif
274
275 #if defined(Q_OS_WIN32)
276 uint32_t GLDrawClass::getNativeKey2VK(uint32_t data)
277 {
278         uint32_t vk = data;
279 #if defined(ENABLE_SWAP_KANJI_PAUSE)
280         if(config.swap_kanji_pause) {
281                 if(vk == VK_KANJI) {
282                         vk = VK_PAUSE;
283                 } else if(vk == VK_PAUSE) {
284                         vk = VK_KANJI;
285                 }
286         }
287 #endif
288         return vk;
289 }
290 #else
291 uint32_t GLDrawClass::getNativeKey2VK(uint32_t data)
292 {
293         uint32 val = 0;
294         uint32 vk;
295         int i = 0;
296
297         if(data < 0x100) {
298                 if((data >= 'a') && (data <= 'z')) {
299                         return data & 0x5f;
300                 }
301                 if((data >= 'A') && (data <= 'Z')) {
302                         return data;
303                 }
304                 if((data >= '0') && (data <= '9')) {
305                         return data;
306                 }
307                 if((data > 0x20) && (data <= 0x29)) {
308                         return data | 0x10;
309                 }
310         }
311         while(convTable_QTKey[i].vk != 0xffffffff) {
312                 val = convTable_QTKey[i].key;
313                 if(val == data) break;
314                 i++;
315         }
316         vk = convTable_QTKey[i].vk;
317
318         if(vk == 0xffffffff) return 0;
319 #if defined(ENABLE_SWAP_KANJI_PAUSE)
320         if(config.swap_kanji_pause) {
321                 if(vk == VK_KANJI) {
322                         vk = VK_PAUSE;
323                 } else if(vk == VK_PAUSE) {
324                         vk = VK_KANJI;
325                 }
326         }
327 #endif     
328 #if  !defined(_FM8) && !defined(_FM7) && !defined(_FMNEW7) && !defined(_FM77_VARIANTS) && !defined(_FM77AV_VARIANTS) 
329         if((vk == VK_LSHIFT) || (vk == VK_RSHIFT)) vk = VK_SHIFT;
330         if((vk == VK_LMENU) || (vk == VK_RMENU)) vk = VK_MENU;
331 #endif   
332         if((vk == VK_LCONTROL) || (vk == VK_RCONTROL)) vk = VK_CONTROL;
333         return vk;
334 }
335 #endif
336
337 uint32_t GLDrawClass::get106Scancode2VK(uint32_t data)
338 {
339         uint32 val = 0;
340         uint32 vk;
341         int i = 0;
342         while(convTable_QTScan106[i].vk != 0xffffffff) {
343                 val = convTable_QTScan106[i].scan;
344                 if(val == data) break;
345                 i++;
346         }
347         vk = convTable_QTScan106[i].vk;
348         //printf("SCAN=%02x VK=%02x\n", val, vk);
349         if(vk == 0xffffffff) return 0;
350 #if defined(ENABLE_SWAP_KANJI_PAUSE)
351         if(config.swap_kanji_pause) {
352                 if(vk == VK_KANJI) {
353                         vk = VK_PAUSE;
354                 } else if(vk == VK_PAUSE) {
355                         vk = VK_KANJI;
356                 }
357         }
358 #endif     
359 #if  !defined(_FM8) && !defined(_FM7) && !defined(_FMNEW7) && !defined(_FM77_VARIANTS) && !defined(_FM77AV_VARIANTS) 
360         if((vk == VK_LSHIFT) || (vk == VK_RSHIFT)) vk = VK_SHIFT;
361         if((vk == VK_LMENU) || (vk == VK_RMENU)) vk = VK_MENU;
362 #endif   
363         if((vk == VK_LCONTROL) || (vk == VK_RCONTROL)) vk = VK_CONTROL;
364         return vk;
365 }
366
367 void GLDrawClass::keyReleaseEvent(QKeyEvent *event)
368 {
369         int key = event->key();
370         uint32 mod = event->modifiers();
371         uint32 scan;
372         uint32 vk;
373         if(event->isAutoRepeat()) return;
374         //scan = event->nativeVirtualKey();
375         //vk = getNativeKey2VK(scan);
376         scan = event->nativeScanCode();
377         vk = get106Scancode2VK(scan);
378
379         //printf("Key: UP: VK=%d SCAN=%04x MOD=%08x\n", vk, scan, mod);
380         emu->LockVM();
381         emu->key_mod(mod);
382         // Note: Qt4 with 106KEY, event->modifier() don't get Shift key as KEYMOD.
383         // At least, linux.
384         if(vk != 0) {
385                 emu->key_up(vk);
386         }
387         emu->UnlockVM();
388 }
389
390 void GLDrawClass::keyPressEvent(QKeyEvent *event)
391 {
392         int key = event->key();
393         uint32 mod = event->modifiers();;
394         uint32 scan;
395         uint32 vk;
396    
397         if(event->isAutoRepeat()) return;
398         //scan = event->nativeVirtualKey();
399         //vk = getNativeKey2VK(scan);
400         scan = event->nativeScanCode();
401         vk = get106Scancode2VK(scan);
402
403         if(vk == VK_APPS) { // Special key : capture/uncapture mouse.
404                 emit sig_toggle_mouse();
405                 return;
406         }
407    
408         //printf("Key: DOWN: VK=%d SCAN=%04x MOD=%08x\n", vk, scan, mod);
409         emu->LockVM();
410         emu->key_mod(mod);
411         if(vk != 0) {
412                 emu->key_down(vk, false);
413         }
414         emu->UnlockVM();
415 }
416
417
418 extern "C"{   
419 uint32_t GetAsyncKeyState(uint32_t vk, uint32_t mod)
420 {
421         vk = vk & 0xff; // OK?
422         quint32 modstate = mod;
423    //printf("Mod %d %08x\n", vk, mod);
424         switch(vk) {
425         case VK_SHIFT:
426                 if((modstate & Qt::ShiftModifier) != 0) return 0xffffffff;
427                 break;
428         case VK_LSHIFT:
429                 if((modstate & Qt::ShiftModifier) != 0) return 0xffffffff;
430                 break;
431         case VK_RSHIFT:
432                 if((modstate & Qt::ShiftModifier) != 0) return 0xffffffff;
433                 break;
434         case VK_CONTROL:
435                 if((modstate & Qt::ControlModifier) != 0) return 0xffffffff;
436                 break;
437         case VK_LCONTROL:
438                 if((modstate & Qt::ControlModifier) != 0) return 0xffffffff;
439                 break;
440         case VK_RCONTROL:
441                 if((modstate & Qt::ControlModifier) != 0) return 0xffffffff;
442                 break;
443         case VK_LMENU:
444                 if((modstate & Qt::AltModifier) != 0) return 0xffffffff;
445                 break;
446         case VK_RMENU:
447                 if((modstate & Qt::AltModifier) != 0) return 0xffffffff;
448                 break;
449         default:
450                 break;
451         }
452         return 0;
453 }
454
455
456 }
457
458