OSDN Git Service

[UI][Qt] Update to upstream 2017-06-22.Some parts are temporally.
[csp-qt/common_source_project-fm7.git] / source / src / qt / osd_input.cpp
1 /*
2         Skelton for retropc emulator
3
4         Author : K.Ohta <whatisthis.sowhat _at_ gmail.com>
5         Date   : 2015.11.30-
6
7         [Qt input ]
8 */
9
10 #include <Qt>
11 #include <QApplication>
12 #include <SDL.h>
13
14 //#include "../emu.h"
15 #include "../fifo.h"
16 #include "../fileio.h"
17 //#include "osd.h"
18
19 #include "qt_input.h"
20 #include "qt_gldraw.h"
21 #include "qt_main.h"
22
23 #include "osd.h"
24 //#include "mainwidget.h"
25 //#include "csp_logger.h"
26 #include "dropdown_keyset.h"
27
28 #define KEY_KEEP_FRAMES 3
29
30 static const int numpad_table[256] = {
31         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00,
32         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33 //      0x00, 0x69, 0x63, 0x61, 0x67, 0x64, 0x68, 0x66, 0x62, 0x00, 0x00, 0x00, 0x00, 0x60, 0x6e, 0x00,
34         0x00, 0x69, 0x63, 0x61, 0x67, 0x64, 0x68, 0x66, 0x62, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, // remove shift + period
35         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
38         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
42         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
48 };
49
50
51 void OSD_BASE::initialize_input()
52 {
53         // initialize status
54         memset(key_status, 0, sizeof(key_status));
55         memset(joy_status, 0, sizeof(joy_status));
56         memset(mouse_status, 0, sizeof(mouse_status));
57         // mouse emulation is disenabled
58         mouse_enabled = false;
59         mouse_ptrx = mouse_oldx = get_screen_width() / 2;
60         mouse_ptry = mouse_oldy = get_screen_height() / 2;
61         // initialize keycode convert table
62         FILEIO* fio = new FILEIO();
63         if(fio->Fopen(bios_path(_T("keycode.cfg")), FILEIO_READ_BINARY)) {
64                 fio->Fread(keycode_conv, sizeof(keycode_conv), 1);
65                 fio->Fclose();
66         } else {
67                 for(int i = 0; i < 256; i++) {
68                         keycode_conv[i] = i;
69                 }
70         }
71         delete fio;
72         now_auto_key = false;
73         
74         // initialize shift+numpad conversion
75         memset(key_converted, 0, sizeof(key_converted));
76         key_shift_pressed = key_shift_released = false;
77         lost_focus = false;
78 }
79
80 void OSD_BASE::release_input()
81 {
82         // release mouse
83         if(mouse_enabled) {
84                 disable_mouse();
85         }
86 }
87
88 void OSD_BASE::do_assign_js_setting(int jsnum, int axis_idx, int assigned_value)
89 {
90         if((jsnum < 0) || (jsnum >= 4)) return;
91         if((axis_idx < 0) || (axis_idx >= 16)) return;
92         if((assigned_value < -256) || (assigned_value >= 0x10000)) return;
93         p_config->joy_buttons[jsnum][axis_idx] = assigned_value;
94 }
95
96 void OSD_BASE::update_input()
97 {
98         bool press_flag = false;
99         bool release_flag = false;
100         if(get_use_shift_numpad_key()) {
101                 //update numpad key status
102                 if(key_shift_pressed && !key_shift_released) {
103                         if(key_status[VK_SHIFT] == 0) {
104                                 // shift key is newly pressed
105                                 key_status[VK_SHIFT] = 0x80;
106                                 if(!this->get_notify_key_down_lr_shift()) key_status[VK_LSHIFT] = 0x80;
107                                 if(this->get_notify_key_down()) vm_key_down(VK_SHIFT, false);
108                         }
109                 } else if(!key_shift_pressed && key_shift_released) {
110                         if(key_status[VK_SHIFT] != 0) {
111                         // shift key is newly released
112                                 key_status[VK_SHIFT] = 0;
113                                 if(!this->get_notify_key_down_lr_shift()) key_status[VK_LSHIFT] = 0;
114                                 if(this->get_notify_key_down()) vm_key_up(VK_SHIFT);
115                                 // check l/r shift
116                                 if(!(GetAsyncKeyState(VK_LSHIFT) & 0x8000)) key_status[VK_LSHIFT] &= 0x7f;
117                                 if(!(GetAsyncKeyState(VK_RSHIFT) & 0x8000)) key_status[VK_RSHIFT] &= 0x7f;
118                         }
119                         if(key_status[VK_LSHIFT] != 0) {
120                                 // shift key is newly released
121                                 key_status[VK_LSHIFT] = 0;
122                         if(this->get_notify_key_down()) vm_key_up(VK_LSHIFT);
123                         // check l/r shift
124                         if(!(GetAsyncKeyState(VK_LSHIFT) & 0x8000)) key_status[VK_LSHIFT] &= 0x7f;
125                         }
126                         if(key_status[VK_RSHIFT] != 0) {
127                                 // shift key is newly released
128                                 key_status[VK_RSHIFT] = 0;
129                                 if(this->get_notify_key_down()) vm_key_up(VK_RSHIFT);
130                                 // check l/r shift
131                                 if(!(GetAsyncKeyState(VK_RSHIFT) & 0x8000)) key_status[VK_RSHIFT] &= 0x7f;
132                         }
133                 }
134                 key_shift_pressed = key_shift_released = false;
135         }
136             
137         // release keys
138         if(lost_focus && !now_auto_key) {
139                 // we lost key focus so release all pressed keys
140                 for(int i = 0; i < 256; i++) {
141                         if(key_status[i] & 0x80) {
142                                 key_status[i] &= 0x7f;
143                                 release_flag = true;
144                                 if(this->get_notify_key_down()) {
145                                         if(!key_status[i]) {
146                                                 vm_key_up(i);
147                                         }
148                                 }
149                         }
150                 }
151         } else {
152                 for(int i = 0; i < 256; i++) {
153                         if(key_status[i] & 0x7f) {
154                                 key_status[i] = (key_status[i] & 0x80) | ((key_status[i] & 0x7f) - 1);
155                                 press_flag = true;
156                                 if(this->get_notify_key_down()) {
157                                         if(!key_status[i]) {
158                                                 vm_key_up(i);
159                                         }
160                                 }
161                         }
162                 }
163         }
164         lost_focus = false;
165
166         update_buttons(press_flag, release_flag);
167         // update mouse status
168         if(mouse_enabled) {
169                 //bool hid = false;
170                 memset(mouse_status, 0, sizeof(mouse_status));
171                 mouse_status[0] = mouse_ptrx - mouse_oldx;
172                 mouse_status[1] = mouse_ptry - mouse_oldy;
173                 mouse_status[2] = mouse_button;
174                 mouse_oldx = mouse_ptrx;
175                 mouse_oldy = mouse_ptry;
176         }
177 }
178
179 void OSD_BASE::key_down(int code, bool extended, bool repeat)
180 {
181         if((code >= 256) || (code < 0)) return; // WORKAROUND
182 //#ifdef USE_AUTO_KEY
183         if(!__USE_AUTO_KEY || (!now_auto_key && !p_config->romaji_to_kana)) {
184 //#endif
185                 //if(!dinput_key_available) {
186                         if(code == VK_SHIFT) {
187                                 if(!(key_status[VK_LSHIFT] & 0x80) && (GetAsyncKeyState(VK_LSHIFT) & 0x8000)) {
188                                         code = VK_LSHIFT;
189                                 } else if(!(key_status[VK_RSHIFT] & 0x80) && (GetAsyncKeyState(VK_RSHIFT) & 0x8000)) {
190                                         code = VK_RSHIFT;
191                                 } else {
192                                         return;
193                                 }
194                         } else if(code == VK_CONTROL) {
195                                 if(!(key_status[VK_LCONTROL] & 0x80) && (GetAsyncKeyState(VK_LCONTROL) & 0x8000)) {
196                                         code = VK_LCONTROL;
197                                 } else if(!(key_status[VK_RCONTROL] & 0x80) && (GetAsyncKeyState(VK_RCONTROL) & 0x8000)) {
198                                         code = VK_RCONTROL;
199                                 } else {
200                                         return;
201                                 }
202                         } else if(code == VK_MENU) {
203                                 if(!(key_status[VK_LMENU] & 0x80) && (GetAsyncKeyState(VK_LMENU) & 0x8000)) {
204                                         code = VK_LMENU;
205                                 } else if(!(key_status[VK_RMENU] & 0x80) && (GetAsyncKeyState(VK_RMENU) & 0x8000)) {
206                                         code = VK_RMENU;
207                                 } else {
208                                         return;
209                                 }
210                         }
211                    
212 //#ifdef USE_SHIFT_NUMPAD_KEY
213                         if(__USE_SHIFT_NUMPAD_KEY) {
214 //                      if(code == VK_LSHIFT || code == VK_RSHIFT) {
215                         if(code == VK_LSHIFT) {
216                                 key_shift_pressed = true;
217                                 return;
218                         }
219                         if(!extended) {
220                                 switch(code) {
221                                 case VK_INSERT:
222                                         if(key_shift_pressed || key_shift_released || key_status[VK_NUMPAD0]) {
223                                                 code = VK_NUMPAD0;
224                                                 key_shift_pressed = true;
225                                         }
226                                         break;
227                                 case VK_END:
228                                         if(key_shift_pressed || key_shift_released || key_status[VK_NUMPAD1]) {
229                                                 code = VK_NUMPAD1;
230                                                 key_shift_pressed = true;
231                                         }
232                                         break;
233                                 case VK_DOWN:
234                                         if(key_shift_pressed || key_shift_released || key_status[VK_NUMPAD2]) {
235                                                 code = VK_NUMPAD2;
236                                                 key_shift_pressed = true;
237                                         }
238                                         break;
239                                 case VK_NEXT:
240                                         if(key_shift_pressed || key_shift_released || key_status[VK_NUMPAD3]) {
241                                                 code = VK_NUMPAD3;
242                                                 key_shift_pressed = true;
243                                         }
244                                         break;
245                                 case VK_LEFT:
246                                         if(key_shift_pressed || key_shift_released || key_status[VK_NUMPAD4]) {
247                                                 code = VK_NUMPAD4;
248                                                 key_shift_pressed = true;
249                                         }
250                                         break;
251                                 case VK_CLEAR:
252                                         if(key_shift_pressed || key_shift_released || key_status[VK_NUMPAD5]) {
253                                                 code = VK_NUMPAD5;
254                                                 key_shift_pressed = true;
255                                         }
256                                         break;
257                                 case VK_RIGHT:
258                                         if(key_shift_pressed || key_shift_released || key_status[VK_NUMPAD6]) {
259                                                 code = VK_NUMPAD6;
260                                                 key_shift_pressed = true;
261                                         }
262                                         break;
263                                 case VK_HOME:
264                                         if(key_shift_pressed || key_shift_released || key_status[VK_NUMPAD7]) {
265                                                 code = VK_NUMPAD7;
266                                                 key_shift_pressed = true;
267                                         }
268                                         break;
269                                 case VK_UP:
270                                         if(key_shift_pressed || key_shift_released || key_status[VK_NUMPAD8]) {
271                                                 code = VK_NUMPAD8;
272                                                 key_shift_pressed = true;
273                                         }
274                                         break;
275                                 case VK_PRIOR:
276                                         if(key_shift_pressed || key_shift_released || key_status[VK_NUMPAD9]) {
277                                                 code = VK_NUMPAD9;
278                                                 key_shift_pressed = true;
279                                         }
280                                         break;
281                                 }
282                         }
283                    }
284                    
285 //#endif
286                         key_down_native(code, repeat);
287                 //} else {
288                 //      if(repeat || code == 0xf0 || code == 0xf1 || code == 0xf2 || code == 0xf3 || code == 0xf4) {
289                 //              key_down_native(code, repeat);
290                 //      }
291                 //}
292 //#ifdef USE_AUTO_KEY
293         }
294 //#endif
295 #if 0
296         if(code == VK_SHIFT) {
297                 if(!(key_status[VK_LSHIFT] & 0x80) && (GetAsyncKeyState(VK_LSHIFT) & 0x8000)) {
298                         code = VK_LSHIFT;
299                 } else if(!(key_status[VK_RSHIFT] & 0x80) && (GetAsyncKeyState(VK_RSHIFT) & 0x8000)) {
300                         code = VK_RSHIFT;
301                 } else {
302                         return;
303                 }
304         } else if(code == VK_CONTROL) {
305                 if(!(key_status[VK_LCONTROL] & 0x80) && (GetAsyncKeyState(VK_LCONTROL) & 0x8000)) {
306                         code = VK_LCONTROL;
307                 } else if(!(key_status[VK_RCONTROL] & 0x80) && (GetAsyncKeyState(VK_RCONTROL) & 0x8000)) {
308                         code = VK_RCONTROL;
309                 } else {
310                         return;
311                 }
312         } else if(code == VK_MENU) {
313                 if(!(key_status[VK_LMENU] & 0x80) && (GetAsyncKeyState(VK_LMENU) & 0x8000)) {
314                         code = VK_LMENU;
315                 } else if(!(key_status[VK_RMENU] & 0x80) && (GetAsyncKeyState(VK_RMENU) & 0x8000)) {
316                         code = VK_RMENU;
317                 } else {
318                         return;
319                 }
320         }
321         if(get_use_shift_numpad_key()) {
322                 if(code == VK_LSHIFT) {
323                         key_shift_pressed = true;
324                         return;
325                 } else if(numpad_table[code] != 0) {
326                         if(key_shift_pressed || key_shift_released) {
327                                 key_converted[code] = 1;
328                                 key_shift_pressed = true;
329                                 code = numpad_table[code];
330                         }
331                 }
332         }
333         key_down_native(code, repeat);
334 #endif
335 }
336
337 void OSD_BASE::key_up(int code, bool extended)
338 {
339         if((code >= 256) || (code < 0)) return; // WORKAROUND
340 //#ifdef USE_AUTO_KEY
341         if(!__USE_AUTO_KEY || (!now_auto_key && !p_config->romaji_to_kana)) {
342 //#endif
343                 //if(!dinput_key_available) {
344                         if(code == VK_SHIFT) {
345                                 if((key_status[VK_LSHIFT] & 0x80) && !(GetAsyncKeyState(VK_LSHIFT) & 0x8000)) {
346                                         code = VK_LSHIFT;
347                                 } else if((key_status[VK_RSHIFT] & 0x80) && !(GetAsyncKeyState(VK_RSHIFT) & 0x8000)) {
348                                         code = VK_RSHIFT;
349                                 } else {
350                                         return;
351                                 }
352                         } else if(code == VK_CONTROL) {
353                                 if((key_status[VK_LCONTROL] & 0x80) && !(GetAsyncKeyState(VK_LCONTROL) & 0x8000)) {
354                                         code = VK_LCONTROL;
355                                 } else if((key_status[VK_RCONTROL] & 0x80) && !(GetAsyncKeyState(VK_RCONTROL) & 0x8000)) {
356                                         code = VK_RCONTROL;
357                                 } else {
358                                         return;
359                                 }
360                         } else if(code == VK_MENU) {
361                                 if((key_status[VK_LMENU] & 0x80) && !(GetAsyncKeyState(VK_LMENU) & 0x8000)) {
362                                         code = VK_LMENU;
363                                 } else if((key_status[VK_RMENU] & 0x80) && !(GetAsyncKeyState(VK_RMENU) & 0x8000)) {
364                                         code = VK_RMENU;
365                                 } else {
366                                         return;
367                                 }
368                         }
369 //#ifdef USE_SHIFT_NUMPAD_KEY
370                         if(__USE_SHIFT_NUMPAD_KEY) {
371                         
372 //                      if(code == VK_LSHIFT || code == VK_RSHIFT) {
373                         if(code == VK_LSHIFT) {
374                                 key_shift_pressed = false;
375                                 key_shift_released = true;
376                                 return;
377                         }
378                         if(!extended) {
379                                 switch(code) {
380                                 case VK_NUMPAD0: case VK_INSERT:
381                                         key_up_native(VK_NUMPAD0);
382                                         key_up_native(VK_INSERT);
383                                         return;
384                                 case VK_NUMPAD1: case VK_END:
385                                         key_up_native(VK_NUMPAD1);
386                                         key_up_native(VK_END);
387                                         return;
388                                 case VK_NUMPAD2: case VK_DOWN:
389                                         key_up_native(VK_NUMPAD2);
390                                         key_up_native(VK_DOWN);
391                                         return;
392                                 case VK_NUMPAD3: case VK_NEXT:
393                                         key_up_native(VK_NUMPAD3);
394                                         key_up_native(VK_NEXT);
395                                         return;
396                                 case VK_NUMPAD4: case VK_LEFT:
397                                         key_up_native(VK_NUMPAD4);
398                                         key_up_native(VK_LEFT);
399                                         return;
400                                 case VK_NUMPAD5: case VK_CLEAR:
401                                         key_up_native(VK_NUMPAD5);
402                                         key_up_native(VK_CLEAR);
403                                         return;
404                                 case VK_NUMPAD6: case VK_RIGHT:
405                                         key_up_native(VK_NUMPAD6);
406                                         key_up_native(VK_RIGHT);
407                                         return;
408                                 case VK_NUMPAD7: case VK_HOME:
409                                         key_up_native(VK_NUMPAD7);
410                                         key_up_native(VK_HOME);
411                                         return;
412                                 case VK_NUMPAD8: case VK_UP:
413                                         key_up_native(VK_NUMPAD8);
414                                         key_up_native(VK_UP);
415                                         return;
416                                 case VK_NUMPAD9: case VK_PRIOR:
417                                         key_up_native(VK_NUMPAD9);
418                                         key_up_native(VK_PRIOR);
419                                         return;
420                                 }
421                         }
422                         }
423 //#endif
424                         key_up_native(code);
425                 }
426 //#ifdef USE_AUTO_KEY
427 //}
428 //#endif
429 #if 0
430         if(code == VK_SHIFT) {
431                 if((key_status[VK_LSHIFT] & 0x80) && !(GetAsyncKeyState(VK_LSHIFT) & 0x8000)) {
432                         code = VK_LSHIFT;
433                 } else if((key_status[VK_RSHIFT] & 0x80) && !(GetAsyncKeyState(VK_RSHIFT) & 0x8000)) {
434                         code = VK_RSHIFT;
435                 } else {
436                         return;
437                 }
438         } else if(code == VK_CONTROL) {
439                 if((key_status[VK_LCONTROL] & 0x80) && !(GetAsyncKeyState(VK_LCONTROL) & 0x8000)) {
440                         code = VK_LCONTROL;
441                 } else if((key_status[VK_RCONTROL] & 0x80) && !(GetAsyncKeyState(VK_RCONTROL) & 0x8000)) {
442                         code = VK_RCONTROL;
443                 } else {
444                         return;
445                 }
446         } else if(code == VK_MENU) {
447                 if((key_status[VK_LMENU] & 0x80) && !(GetAsyncKeyState(VK_LMENU) & 0x8000)) {
448                         code = VK_LMENU;
449                 } else if((key_status[VK_RMENU] & 0x80) && !(GetAsyncKeyState(VK_RMENU) & 0x8000)) {
450                         code = VK_RMENU;
451                 } else {
452                         return;
453                 }
454         }
455         if(get_use_shift_numpad_key()) {
456                 if(code == VK_LSHIFT) {
457                         key_shift_pressed = false;
458                         key_shift_released = true;
459                         return;
460                 } else if(key_converted[code] != 0) {
461                         key_converted[code] = 0;
462                         code = numpad_table[code];
463                 }
464         }
465         key_up_native(code);
466 #endif
467 }
468
469
470 void OSD_BASE::key_down_native(int code, bool repeat)
471 {
472         bool keep_frames = false;
473         
474         if(code == 0xf0) {
475                 code = VK_CAPITAL;
476                 keep_frames = true;
477         } else if(code == 0xf2) {
478                 code = VK_KANA;
479                 keep_frames = true;
480         } else if(code == 0xf3 || code == 0xf4) {
481                 code = VK_KANJI;
482                 keep_frames = true;
483         }
484         code = keycode_conv[code];
485         
486         if(get_dont_keeep_key_pressed()) {
487                 if(!(code == VK_LSHIFT || code == VK_RSHIFT || code == VK_LCONTROL || code == VK_RCONTROL || code == VK_LMENU || code == VK_RMENU)) {
488                         key_status[code] = KEY_KEEP_FRAMES;
489                 } else {
490                         key_status[code] = keep_frames ? KEY_KEEP_FRAMES : 0x80;
491                 }
492         } else {
493                 key_status[code] = keep_frames ? KEY_KEEP_FRAMES : 0x80;
494         }
495
496         uint8_t prev_shift = key_status[VK_SHIFT];
497         uint8_t prev_control = key_status[VK_CONTROL];
498         uint8_t prev_menu = key_status[VK_MENU];
499         key_status[VK_SHIFT] = key_status[VK_LSHIFT] | key_status[VK_RSHIFT];
500         key_status[VK_CONTROL] = key_status[VK_LCONTROL] | key_status[VK_RCONTROL];
501         key_status[VK_MENU] = key_status[VK_LMENU] | key_status[VK_RMENU];
502         
503         if(get_notify_key_down()) {
504                 if(keep_frames) {
505                         repeat = false;
506                 }
507                 if(!get_notify_key_down_lr_shift()) {
508                         if(code == VK_LSHIFT || code == VK_RSHIFT) {
509                                 if(prev_shift == 0 && key_status[VK_SHIFT] != 0) {
510                                         vm_key_down(VK_SHIFT, repeat);
511                                 }
512                                 return;
513                         }
514                 }
515                 if(!get_notify_key_down_lr_control()) {
516                         if(code == VK_LCONTROL|| code == VK_RCONTROL) {
517                                 if(prev_control == 0 && key_status[VK_CONTROL] != 0) {
518                                         vm_key_down(VK_CONTROL, repeat);
519                                 }
520                                 return;
521                         }
522                 }
523                 if(!get_notify_key_down_lr_menu()) {
524                         if(code == VK_LMENU|| code == VK_RMENU) {
525                                 if(prev_menu == 0 && key_status[VK_MENU] != 0) {
526                                         vm_key_down(VK_MENU, repeat);
527                                 }
528                                 return;
529                         }
530                 }
531                 vm_key_down(code, repeat);
532         }
533 }
534
535 void OSD_BASE::key_up_native(int code)
536 {
537         if(!(code == VK_LSHIFT || code == VK_RSHIFT || code == VK_LCONTROL || code == VK_RCONTROL || code == VK_LMENU || code == VK_RMENU)) {
538                 code = keycode_conv[code];
539         }
540         if(key_status[code] == 0) {
541                 return;
542         }
543         if((key_status[code] &= 0x7f) != 0) {
544                 return;
545         }
546         
547         uint8_t prev_shift = key_status[VK_SHIFT];
548         uint8_t prev_control = key_status[VK_CONTROL];
549         uint8_t prev_menu = key_status[VK_MENU];
550         key_status[VK_SHIFT] = key_status[VK_LSHIFT] | key_status[VK_RSHIFT];
551         key_status[VK_CONTROL] = key_status[VK_LCONTROL] | key_status[VK_RCONTROL];
552         key_status[VK_MENU] = key_status[VK_LMENU] | key_status[VK_RMENU];
553         
554
555         if(get_notify_key_down()) {
556                 if(!get_notify_key_down_lr_shift()) {
557                         if(code == VK_LSHIFT || code == VK_RSHIFT) {
558                                 if(prev_shift != 0 && key_status[VK_SHIFT] == 0) {
559                                         vm_key_up(VK_SHIFT);
560                                 }
561                                 return;
562                         }
563                 }
564                 if(!get_notify_key_down_lr_control()) {
565                         if(code == VK_LCONTROL|| code == VK_RCONTROL) {
566                                 if(prev_control != 0 && key_status[VK_CONTROL] == 0) {
567                                         vm_key_up(VK_CONTROL);
568                                 }
569                                 return;
570                         }
571                 }
572                 if(!get_notify_key_down_lr_menu()) {
573                         if(code == VK_LMENU || code == VK_RMENU) {
574                                 if(prev_menu != 0 && key_status[VK_MENU] == 0) {
575                                         vm_key_up(VK_MENU);
576                                 }
577                                 return;
578                         }
579                 }
580                 vm_key_up(code);
581         }
582 }
583
584 void OSD_BASE::key_down_sub(int code, bool repeat)
585 {
586         bool keep_frames = false;
587         
588         if(code == 0xf0) {
589                 code = VK_CAPITAL;
590                 keep_frames = true;
591         } else if(code == 0xf2) {
592                 code = VK_KANA;
593                 keep_frames = true;
594         } else if(code == 0xf3 || code == 0xf4) {
595                 code = VK_KANJI;
596                 keep_frames = true;
597         }
598         if(!(code == VK_LSHIFT || code == VK_RSHIFT || code == VK_LCONTROL || code == VK_RCONTROL || code == VK_LMENU || code == VK_RMENU)) {
599                 code = keycode_conv[code];
600         }
601         
602
603         if(get_dont_keeep_key_pressed()) {
604                 if(!(code == VK_LSHIFT || code == VK_RSHIFT || code == VK_LCONTROL || code == VK_RCONTROL || code == VK_LMENU || code == VK_RMENU)) {
605                         key_status[code] = KEY_KEEP_FRAMES;
606                 } else {
607                         key_status[code] = keep_frames ? KEY_KEEP_FRAMES : 0x80;
608                 }
609         } else {
610                 key_status[code] = keep_frames ? KEY_KEEP_FRAMES : 0x80;
611         }
612
613         uint8_t prev_shift = key_status[VK_SHIFT];
614         uint8_t prev_control = key_status[VK_CONTROL];
615         uint8_t prev_menu = key_status[VK_MENU];
616         
617         key_status[VK_SHIFT] = key_status[VK_LSHIFT] | key_status[VK_RSHIFT];
618         key_status[VK_CONTROL] = key_status[VK_LCONTROL] | key_status[VK_RCONTROL];
619         key_status[VK_MENU] = key_status[VK_LMENU] | key_status[VK_RMENU];
620         
621         if(get_notify_key_down()) {
622                 if(keep_frames) {
623                         repeat = false;
624                 }
625                 if(!get_notify_key_down_lr_shift()) {
626                         if(code == VK_LSHIFT || code == VK_RSHIFT) {
627                                 if(prev_shift == 0 && key_status[VK_SHIFT] != 0) {
628                                         vm_key_down(VK_SHIFT, repeat);
629                                 }
630                                 return;
631                         }
632                 }
633                 if(!get_notify_key_down_lr_control()) {
634                         if(code == VK_LCONTROL|| code == VK_RCONTROL) {
635                                 if(prev_control == 0 && key_status[VK_CONTROL] != 0) {
636                                         vm_key_down(VK_CONTROL, repeat);
637                                 }
638                                 return;
639                         }
640                 }
641                 if(!get_notify_key_down_lr_menu()) {
642                         if(code == VK_LMENU|| code == VK_RMENU) {
643                                 if(prev_menu == 0 && key_status[VK_MENU] != 0) {
644                                         vm_key_down(VK_MENU, repeat);
645                                 }
646                                 return;
647                         }
648                 }
649                 vm_key_down(code, repeat);
650         }
651 }
652
653 void OSD_BASE::key_up_sub(int code)
654 {
655         if(!(code == VK_LSHIFT || code == VK_RSHIFT || code == VK_LCONTROL || code == VK_RCONTROL || code == VK_LMENU || code == VK_RMENU)) {
656                 code = keycode_conv[code];
657         }
658         if(key_status[code] == 0) {
659                 return;
660         }
661         if((key_status[code] &= 0x7f) != 0) {
662                 return;
663         }
664         
665         uint8_t prev_shift = key_status[VK_SHIFT];
666         uint8_t prev_control = key_status[VK_CONTROL];
667         uint8_t prev_menu = key_status[VK_MENU];
668         key_status[VK_SHIFT] = key_status[VK_LSHIFT] | key_status[VK_RSHIFT];
669         key_status[VK_CONTROL] = key_status[VK_LCONTROL] | key_status[VK_RCONTROL];
670         key_status[VK_MENU] = key_status[VK_LMENU] | key_status[VK_RMENU];
671         if(get_notify_key_down()) {
672                 if(!get_notify_key_down_lr_shift()) {
673                         if(code == VK_LSHIFT || code == VK_RSHIFT) {
674                                 if(prev_shift != 0 && key_status[VK_SHIFT] == 0) {
675                                         vm_key_up(VK_SHIFT);
676                                 }
677                                 return;
678                         }
679                 }
680                 if(!get_notify_key_down_lr_control()) {
681                         if(code == VK_LCONTROL|| code == VK_RCONTROL) {
682                                 if(prev_control != 0 && key_status[VK_CONTROL] == 0) {
683                                         vm_key_up(VK_CONTROL);
684                                 }
685                                 return;
686                         }
687                 }
688                 if(!get_notify_key_down_lr_menu()) {
689                         if(code == VK_LMENU || code == VK_RMENU) {
690                                 if(prev_menu != 0 && key_status[VK_MENU] == 0) {
691                                         vm_key_up(VK_MENU);
692                                 }
693                                 return;
694                         }
695                 }
696                 vm_key_up(code);
697         }
698 }
699
700
701 void OSD_BASE::key_modifiers(uint32_t mod)
702 {
703         modkey_status = mod;
704 }
705
706
707 void OSD_BASE::modify_key_buffer(int code, uint8_t val)
708 {
709         key_status[code] = val;
710 }
711
712 void OSD_BASE::key_lost_focus()
713 {
714         lost_focus = true;
715 }
716
717 uint8_t* OSD_BASE::get_key_buffer()
718 {
719         return key_status;
720 }
721
722 uint32_t* OSD_BASE::get_joy_buffer()
723 {
724         return joy_status;
725 }
726
727 int* OSD_BASE::get_mouse_buffer()
728 {
729         return mouse_status;
730 }
731
732 void OSD_BASE::press_button(int num)
733 {
734         if(get_one_board_micro_computer()) {
735                 int code = get_vm_buttons_code(num);
736                 
737                 if(code) {
738                         key_down_sub(code, false);
739                         key_status[code] = KEY_KEEP_FRAMES;
740                 } else {
741                         // code=0: reset virtual machine
742                         vm_reset();
743                 }
744         }
745 }
746
747
748 void OSD_BASE::enable_mouse()
749 {
750         // enable mouse emulation
751         if(!mouse_enabled) {
752                 mouse_oldx = mouse_ptrx = get_screen_width() / 2;
753                 mouse_oldy = mouse_ptry = get_screen_height() / 2;
754                 mouse_status[0] = 0;
755                 mouse_status[1] = 0;
756                 mouse_status[2] = mouse_button;
757                 emit sig_enable_mouse();
758         }
759         mouse_enabled = true;
760 }
761
762 void OSD_BASE::disable_mouse()
763 {
764         // disenable mouse emulation
765         if(mouse_enabled) {
766                 emit sig_disable_mouse();
767         }
768         mouse_enabled = false;
769 }
770
771 void OSD_BASE::toggle_mouse()
772 {
773         // toggle mouse enable / disenable
774         if(mouse_enabled) {
775                 disable_mouse();
776         } else {
777                 enable_mouse();
778         }
779 }
780
781 bool OSD_BASE::is_mouse_enabled()
782 {
783         return mouse_enabled;
784 }
785
786 void OSD_BASE::set_mouse_pointer(int x, int y)
787 {
788         mouse_ptrx = x;
789         mouse_ptry = y;
790 }
791
792 void OSD_BASE::set_mouse_button(int button) 
793 {
794         mouse_button = button;
795 }
796
797 int OSD_BASE::get_mouse_button() 
798 {
799         return mouse_button;
800 }
801
802 #if !defined(Q_OS_WIN) && !defined(Q_OS_CYGWIN)
803 uint16_t OSD_BASE::GetAsyncKeyState(uint32_t vk)
804 {
805         vk = vk & 0xff; // OK?
806         quint32 modstate = modkey_status;
807    //printf("Mod %d %08x\n", vk, mod);
808         switch(vk) {
809         case VK_SHIFT:
810                 if((modstate & Qt::ShiftModifier) != 0) return 0xffff;
811                 break;
812         case VK_LSHIFT:
813                 if((modstate & Qt::ShiftModifier) != 0) return 0xffff;
814                 break;
815         case VK_RSHIFT:
816                 if((modstate & Qt::ShiftModifier) != 0) return 0xffff;
817                 break;
818         case VK_CONTROL:
819                 if((modstate & Qt::ControlModifier) != 0) return 0xffff;
820                 break;
821         case VK_LCONTROL:
822                 if((modstate & Qt::ControlModifier) != 0) return 0xffff;
823                 break;
824         case VK_RCONTROL:
825                 if((modstate & Qt::ControlModifier) != 0) return 0xffff;
826                 break;
827         case VK_LMENU:
828                 if((modstate & Qt::AltModifier) != 0) return 0xffff;
829                 break;
830         case VK_RMENU:
831                 if((modstate & Qt::AltModifier) != 0) return 0xffff;
832                 break;
833         default:
834                 break;
835         }
836         return 0;
837 }
838 #endif