Partial rewrite of the optional keyboard handling. Now the BX_KEY_* events are
directly sent to the optional keyboard (USB keypad). It is now independent from the legacy keyboard and the check for supported keys is simplified. The legacy keyboard still receives the unhandled key event, but now sent from the common devices code.
This commit is contained in:
parent
e351aaa28a
commit
e023b5896f
@ -138,7 +138,7 @@ void bx_devices_c::init(BX_MEM_C *newmem)
|
||||
|
||||
// removable devices init
|
||||
bx_keyboard.dev = NULL;
|
||||
bx_keyboard.enq_event = NULL;
|
||||
bx_keyboard.gen_scancode = NULL;
|
||||
for (i=0; i < 2; i++) {
|
||||
bx_mouse[i].dev = NULL;
|
||||
bx_mouse[i].enq_event = NULL;
|
||||
@ -1056,11 +1056,11 @@ bx_bool bx_devices_c::is_usb_enabled(void)
|
||||
}
|
||||
|
||||
// removable keyboard/mouse registration
|
||||
void bx_devices_c::register_removable_keyboard(void *dev, bx_keyb_enq_t keyb_enq)
|
||||
void bx_devices_c::register_removable_keyboard(void *dev, bx_kbd_gen_scancode_t kbd_gen_scancode)
|
||||
{
|
||||
if (bx_keyboard.dev == NULL) {
|
||||
bx_keyboard.dev = dev;
|
||||
bx_keyboard.enq_event = keyb_enq;
|
||||
bx_keyboard.gen_scancode = kbd_gen_scancode;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1068,7 +1068,7 @@ void bx_devices_c::unregister_removable_keyboard(void *dev)
|
||||
{
|
||||
if (dev == bx_keyboard.dev) {
|
||||
bx_keyboard.dev = NULL;
|
||||
bx_keyboard.enq_event = NULL;
|
||||
bx_keyboard.gen_scancode = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1101,12 +1101,17 @@ void bx_devices_c::unregister_removable_mouse(void *dev)
|
||||
}
|
||||
}
|
||||
|
||||
bx_bool bx_devices_c::optional_key_enq(Bit8u *scan_code)
|
||||
// common keyboard device handler
|
||||
void bx_devices_c::gen_scancode(Bit32u key)
|
||||
{
|
||||
bx_bool ret = 0;
|
||||
|
||||
if (bx_keyboard.dev != NULL) {
|
||||
return bx_keyboard.enq_event(bx_keyboard.dev, scan_code);
|
||||
ret = bx_keyboard.gen_scancode(bx_keyboard.dev, key);
|
||||
}
|
||||
if (ret == 0) {
|
||||
pluginKeyboard->gen_scancode(key);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// common mouse device handlers
|
||||
|
@ -45,7 +45,7 @@
|
||||
typedef Bit32u (*bx_read_handler_t)(void *, Bit32u, unsigned);
|
||||
typedef void (*bx_write_handler_t)(void *, Bit32u, Bit32u, unsigned);
|
||||
|
||||
typedef bx_bool (*bx_keyb_enq_t)(void *, Bit8u *);
|
||||
typedef bx_bool (*bx_kbd_gen_scancode_t)(void *, Bit32u);
|
||||
typedef void (*bx_mouse_enq_t)(void *, int, int, int, unsigned, bx_bool);
|
||||
typedef void (*bx_mouse_enabled_changed_t)(void *, bx_bool);
|
||||
|
||||
@ -380,12 +380,12 @@ public:
|
||||
Bit32u inp(Bit16u addr, unsigned io_len) BX_CPP_AttrRegparmN(2);
|
||||
void outp(Bit16u addr, Bit32u value, unsigned io_len) BX_CPP_AttrRegparmN(3);
|
||||
|
||||
void register_removable_keyboard(void *dev, bx_keyb_enq_t keyb_enq);
|
||||
void register_removable_keyboard(void *dev, bx_kbd_gen_scancode_t kbd_gen_scancode);
|
||||
void unregister_removable_keyboard(void *dev);
|
||||
void register_default_mouse(void *dev, bx_mouse_enq_t mouse_enq, bx_mouse_enabled_changed_t mouse_enabled_changed);
|
||||
void register_removable_mouse(void *dev, bx_mouse_enq_t mouse_enq, bx_mouse_enabled_changed_t mouse_enabled_changed);
|
||||
void unregister_removable_mouse(void *dev);
|
||||
bx_bool optional_key_enq(Bit8u *scan_code);
|
||||
void gen_scancode(Bit32u key);
|
||||
void mouse_enabled_changed(bx_bool enabled);
|
||||
void mouse_motion(int delta_x, int delta_y, int delta_z, unsigned button_state, bx_bool absxy);
|
||||
|
||||
@ -507,7 +507,7 @@ private:
|
||||
} bx_mouse[2];
|
||||
struct {
|
||||
void *dev;
|
||||
bx_keyb_enq_t enq_event;
|
||||
bx_kbd_gen_scancode_t gen_scancode;
|
||||
} bx_keyboard;
|
||||
|
||||
struct {
|
||||
|
@ -804,11 +804,6 @@ void bx_keyb_c::gen_scancode(Bit32u key)
|
||||
else
|
||||
scancode=(unsigned char *)scancodes[(key&0xFF)][BX_KEY_THIS s.kbd_controller.current_scancodes_set].make;
|
||||
|
||||
// if we have a removable keyboard installed, we need to call its handler first
|
||||
if (DEV_optional_key_enq(scancode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (BX_KEY_THIS s.kbd_controller.scancodes_translate) {
|
||||
// Translate before send
|
||||
Bit8u escaped=0x00;
|
||||
|
@ -67,9 +67,9 @@
|
||||
#define SET_IDLE 0x210a
|
||||
#define SET_PROTOCOL 0x210b
|
||||
|
||||
#define KEYPAD_LEN 128
|
||||
#define KEYPAD_LEN 16
|
||||
struct KEYPAD {
|
||||
Bit8u scan_code[8];
|
||||
Bit32u bxkey;
|
||||
Bit8u keypad_packet[8];
|
||||
};
|
||||
|
||||
@ -600,24 +600,24 @@ static const Bit8u bx_keypad_hid_report_descriptor2[] = {
|
||||
0x01, 0xC0
|
||||
};
|
||||
|
||||
// this interface has a key conversion table of len = 18
|
||||
// this interface has a key conversion table of len = 16
|
||||
struct KEYPAD keypad_lookup[KEYPAD_LEN] = {
|
||||
{ { 0x6C, }, { 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 7
|
||||
{ { 0x6B, }, { 0x00, 0x00, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 4
|
||||
{ { 0x69, }, { 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 1
|
||||
{ { 0x70, }, { 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 0
|
||||
{ { 0xE0, 0x4A, }, { 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // /
|
||||
{ { 0x75, }, { 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 8
|
||||
{ { 0x73, }, { 0x00, 0x00, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 5
|
||||
{ { 0x72, }, { 0x00, 0x00, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 2
|
||||
{ { 0x7C, }, { 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // *
|
||||
{ { 0x7D, }, { 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 9
|
||||
{ { 0x74, }, { 0x00, 0x00, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 6
|
||||
{ { 0x7A, }, { 0x00, 0x00, 0x5B, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 3
|
||||
{ { 0x71, }, { 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // -
|
||||
{ { 0x7B, }, { 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // +
|
||||
{ { 0x79, }, { 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // .
|
||||
{ { 0xE0, 0x5A }, { 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // Enter
|
||||
{ BX_KEY_KP_HOME, { 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 7
|
||||
{ BX_KEY_KP_LEFT, { 0x00, 0x00, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 4
|
||||
{ BX_KEY_KP_END, { 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 1
|
||||
{ BX_KEY_KP_INSERT, { 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 0
|
||||
{ BX_KEY_KP_DIVIDE, { 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // /
|
||||
{ BX_KEY_KP_UP, { 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 8
|
||||
{ BX_KEY_KP_5, { 0x00, 0x00, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 5
|
||||
{ BX_KEY_KP_DOWN, { 0x00, 0x00, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 2
|
||||
{ BX_KEY_KP_MULTIPLY, { 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // *
|
||||
{ BX_KEY_KP_PAGE_UP, { 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 9
|
||||
{ BX_KEY_KP_RIGHT, { 0x00, 0x00, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 6
|
||||
{ BX_KEY_KP_PAGE_DOWN, { 0x00, 0x00, 0x5B, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 3
|
||||
{ BX_KEY_KP_SUBTRACT, { 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // -
|
||||
{ BX_KEY_KP_ADD, { 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // +
|
||||
{ BX_KEY_KP_DELETE, { 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // .
|
||||
{ BX_KEY_KP_ENTER, { 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // Enter
|
||||
};
|
||||
|
||||
usb_hid_device_c::usb_hid_device_c(usbdev_type type)
|
||||
@ -668,13 +668,16 @@ usb_hid_device_c::usb_hid_device_c(usbdev_type type)
|
||||
d.device_desc_size = sizeof(bx_keypad_dev_descriptor);
|
||||
d.config_desc_size = sizeof(bx_keypad_config_descriptor);
|
||||
}
|
||||
DEV_register_removable_keyboard((void*)this, key_enq_static);
|
||||
DEV_register_removable_keyboard((void*)this, gen_scancode_static);
|
||||
}
|
||||
d.vendor_desc = "BOCHS";
|
||||
d.product_desc = d.devname;
|
||||
d.serial_num = "1";
|
||||
d.connected = 1;
|
||||
memset((void*)&s, 0, sizeof(s));
|
||||
if (d.type == USB_DEV_TYPE_KEYPAD) {
|
||||
s.saved_key = BX_KEY_UNHANDLED;
|
||||
}
|
||||
|
||||
put("usb_hid", "USBHID");
|
||||
}
|
||||
@ -704,7 +707,7 @@ void usb_hid_device_c::register_state_specific(bx_list_c *parent)
|
||||
BXRS_HEX_PARAM_FIELD(list, idle, s.idle);
|
||||
BXRS_PARAM_BOOL(list, has_events, s.has_events);
|
||||
if (d.type == USB_DEV_TYPE_KEYPAD) {
|
||||
new bx_shadow_data_c(list, "saved_key", s.saved_key, 8, 1);
|
||||
BXRS_DEC_PARAM_FIELD(list, saved_key, s.saved_key);
|
||||
new bx_shadow_data_c(list, "key_pad_packet", s.key_pad_packet, 8, 1);
|
||||
}
|
||||
}
|
||||
@ -1008,63 +1011,46 @@ int usb_hid_device_c::keypad_poll(Bit8u *buf, int len, bx_bool force)
|
||||
if (s.has_events || (s.idle != 0) || force) {
|
||||
memcpy(buf, s.key_pad_packet, len);
|
||||
l = 8;
|
||||
s.has_events = 0;
|
||||
if (s.saved_key == BX_KEY_UNHANDLED) {
|
||||
s.has_events = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
bx_bool usb_hid_device_c::key_enq_static(void *dev, Bit8u *scan_code)
|
||||
bx_bool usb_hid_device_c::gen_scancode_static(void *dev, Bit32u key)
|
||||
{
|
||||
return ((usb_hid_device_c*)dev)->key_enq(scan_code);
|
||||
return ((usb_hid_device_c*)dev)->gen_scancode(key);
|
||||
}
|
||||
|
||||
bx_bool usb_hid_device_c::key_enq(Bit8u *scan_code)
|
||||
bx_bool usb_hid_device_c::gen_scancode(Bit32u key)
|
||||
{
|
||||
bx_bool is_break_code = 0;
|
||||
Bit8u our_scan_code[8];
|
||||
|
||||
memset(our_scan_code, 0, 8);
|
||||
int os = 0;
|
||||
for (int sc=0; sc<8; sc++) {
|
||||
if ((scan_code[sc] == 0xF0) && ((sc == 0) || ((sc == 1) && (scan_code[0] == 0xE0)))) {
|
||||
is_break_code = 1;
|
||||
} else {
|
||||
if (!(our_scan_code[os++] = scan_code[sc])) break;
|
||||
}
|
||||
}
|
||||
|
||||
// if it is the break code of the saved key, then clear our packet key.
|
||||
if (is_break_code && !memcmp(s.saved_key, our_scan_code, 8)) {
|
||||
memset(s.saved_key, 0, 8);
|
||||
memset(s.key_pad_packet, 0, 8);
|
||||
return 1; // tell the keyboard handler that we used it, and to return with out processing key
|
||||
if (key & BX_KEY_RELEASED) {
|
||||
key &= ~BX_KEY_RELEASED;
|
||||
if (key == s.saved_key) {
|
||||
s.saved_key = BX_KEY_UNHANDLED;
|
||||
memset(s.key_pad_packet, 0, 8);
|
||||
BX_DEBUG(("Routing Bochs key release (%d) to USB keypad", key));
|
||||
return 1; // tell the keyboard handler that we used it, and to return with out processing key
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bx_bool fnd = 0;
|
||||
for (int m = 0; m < 18; m++) {
|
||||
if (!memcmp(keypad_lookup[m].scan_code, our_scan_code, 8)) {
|
||||
for (int m = 0; m < KEYPAD_LEN; m++) {
|
||||
if (key == keypad_lookup[m].bxkey) {
|
||||
memcpy(s.key_pad_packet, keypad_lookup[m].keypad_packet, 8);
|
||||
fnd = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fnd) {
|
||||
memset(s.key_pad_packet, 0, 8);
|
||||
memset(s.saved_key, 0, 8);
|
||||
} else {
|
||||
memcpy(s.saved_key, our_scan_code, 8);
|
||||
if (fnd) {
|
||||
s.saved_key = key;
|
||||
s.has_events = 1;
|
||||
// print a debug line to the log file
|
||||
char bx_debug_code[128] = "";
|
||||
char value[8];
|
||||
for (unsigned i=0; i<strlen((char *) our_scan_code); i++) {
|
||||
sprintf(value, "0x%02x", our_scan_code[i]);
|
||||
if (i) strcat(bx_debug_code, " ");
|
||||
strcat(bx_debug_code, value);
|
||||
}
|
||||
BX_DEBUG(("Re-routing scan code (%s) to USB keypad", bx_debug_code));
|
||||
BX_DEBUG(("Routing Bochs key press (%d) to USB keypad", key));
|
||||
}
|
||||
|
||||
// tell the keyboard handler whether we used it or not. (0 = no, 1 = yes and keyboard.cc ignores keystoke)
|
||||
|
@ -7,7 +7,7 @@
|
||||
//
|
||||
// Copyright (c) 2005 Fabrice Bellard
|
||||
// Copyright (c) 2007 OpenMoko, Inc. (andrew@openedhand.com)
|
||||
// Copyright (C) 2009-2016 The Bochs Project
|
||||
// Copyright (C) 2009-2017 The Bochs Project
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@ -51,14 +51,14 @@ private:
|
||||
Bit16s mouse_y;
|
||||
Bit8s mouse_z;
|
||||
Bit8u b_state;
|
||||
Bit8u saved_key[8];
|
||||
Bit32u saved_key;
|
||||
Bit8u key_pad_packet[8];
|
||||
Bit8u idle;
|
||||
bx_bool has_events;
|
||||
} s;
|
||||
|
||||
static bx_bool key_enq_static(void *dev, Bit8u *scan_code);
|
||||
bx_bool key_enq(Bit8u *scan_code);
|
||||
static bx_bool gen_scancode_static(void *dev, Bit32u key);
|
||||
bx_bool gen_scancode(Bit32u key);
|
||||
static void mouse_enabled_changed(void *dev, bx_bool enabled);
|
||||
static void mouse_enq_static(void *dev, int delta_x, int delta_y, int delta_z, unsigned button_state, bx_bool absxy);
|
||||
void mouse_enq(int delta_x, int delta_y, int delta_z, unsigned button_state, bx_bool absxy);
|
||||
|
@ -163,8 +163,7 @@ extern "C" {
|
||||
#define DEV_cmos_checksum() (bx_devices.pluginCmosDevice->checksum_cmos())
|
||||
|
||||
///////// keyboard macros
|
||||
#define DEV_kbd_gen_scancode(key) \
|
||||
(bx_devices.pluginKeyboard->gen_scancode(key))
|
||||
#define DEV_kbd_gen_scancode(key) (bx_devices.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())
|
||||
|
Loading…
Reference in New Issue
Block a user