Release all pressed keys when the simulation window gets back the keyboard

focus. This change will fix some keyboard-related bug reports (DONE for the
x and sdl2 guis / TODO for all others).
This commit is contained in:
Volker Ruppert 2014-12-26 20:25:27 +00:00
parent d01a6176a8
commit 227da0c6de
6 changed files with 34 additions and 2 deletions

View File

@ -782,6 +782,9 @@ void bx_sdl2_gui_c::handle_events(void)
if (sdl_event.window.event == SDL_WINDOWEVENT_EXPOSED) {
SDL_UpdateWindowSurface(window);
}
if (sdl_event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) {
DEV_kbd_release_keys();;
}
break;
case SDL_MOUSEMOTION:

View File

@ -583,7 +583,7 @@ void bx_x_gui_c::specific_init(int argc, char **argv, unsigned headerbar_y)
/* Select event types wanted */
XSelectInput(bx_x_display, win, ExposureMask | KeyPressMask | KeyReleaseMask |
ButtonPressMask | ButtonReleaseMask | StructureNotifyMask | PointerMotionMask |
EnterWindowMask | LeaveWindowMask);
EnterWindowMask | LeaveWindowMask | FocusChangeMask);
/* Create default Graphics Context */
gc = XCreateGC(bx_x_display, win, valuemask, &values);
@ -984,6 +984,10 @@ void bx_x_gui_c::handle_events(void)
//retval = 1;
break;
case FocusIn:
DEV_kbd_release_keys();
break;
case ClientMessage:
if (!strcmp(XGetAtomName(bx_x_display, report.xclient.message_type), "WM_PROTOCOLS")) {
bx_stop_simulation();

View File

@ -131,6 +131,9 @@ public:
virtual void paste_bytes(Bit8u *data, Bit32s length) {
STUBFUNC(keyboard, paste_bytes);
}
virtual void release_keys(void) {
STUBFUNC(keyboard, release_keys);
}
};
class BOCHSAPI bx_hard_drive_stub_c : public bx_devmodel_c {

View File

@ -207,6 +207,10 @@ void bx_keyb_c::init(void)
DEV_register_default_mouse(this, mouse_enq_static, mouse_enabled_changed_static);
}
for (i = 0; i < BX_KEY_NBKEYS; i++) {
bxkey_state[i] = 0;
}
// init runtime parameter
SIM->get_param_num(BXPN_KBD_PASTE_DELAY)->set_handler(kbd_param_handler);
SIM->get_param_num(BXPN_MOUSE_ENABLED)->set_handler(kbd_param_handler);
@ -217,6 +221,10 @@ void bx_keyb_c::reset(unsigned type)
if (BX_KEY_THIS pastebuf != NULL) {
BX_KEY_THIS stop_paste = 1;
}
release_keys();
for (int i = 0; i < BX_KEY_NBKEYS; i++) {
bxkey_state[i] = 0;
}
}
void bx_keyb_c::register_state(void)
@ -772,6 +780,16 @@ void bx_keyb_c::paste_bytes(Bit8u *bytes, Bit32s length)
BX_KEY_THIS service_paste_buf();
}
void bx_keyb_c::release_keys()
{
for (int i = 0; i < BX_KEY_NBKEYS; i++) {
if (bxkey_state[i]) {
BX_KEY_THIS gen_scancode(i | BX_KEY_RELEASED);
bxkey_state[i] = 0;
}
}
}
void bx_keyb_c::gen_scancode(Bit32u key)
{
unsigned char *scancode;
@ -783,6 +801,7 @@ void bx_keyb_c::gen_scancode(Bit32u key)
}
BX_DEBUG(("gen_scancode(): %s %s", bx_keymap.getBXKeyName(key), (key >> 31)?"released":"pressed"));
bxkey_state[key & 0xff] = ((key & BX_KEY_RELEASED) == 0);
if (!BX_KEY_THIS s.kbd_controller.scancodes_translate)
BX_DEBUG(("keyboard: gen_scancode with scancode_translate cleared"));

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002-2009 The Bochs Project
// Copyright (C) 2002-2014 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -47,6 +47,7 @@ public:
// override stubs from bx_keyb_stub_c
virtual void gen_scancode(Bit32u key);
virtual void paste_bytes(Bit8u *data, Bit32s length);
virtual void release_keys(void);
virtual void register_state(void);
virtual void after_restore_state(void);
@ -229,6 +230,7 @@ private:
void timer(void);
int timer_handle;
int statusbar_id[3];
bx_bool bxkey_state[BX_KEY_NBKEYS];
};
#endif // #ifndef _PCKEY_H

View File

@ -164,6 +164,7 @@ extern "C" {
(bx_devices.pluginKeyboard->gen_scancode(key))
#define DEV_kbd_paste_bytes(bytes, count) \
(bx_devices.pluginKeyboard->paste_bytes(bytes,count))
#define DEV_kbd_release_keys() (bx_devices.pluginKeyboard->release_keys())
///////// hard drive macros
#define DEV_hd_read_handler(a, b, c) \