OSDN Git Service

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