input: fixes for ui input code and ps/2 keyboard (mostly sysrq key)
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJZ7bQaAAoJEEy22O7T6HE4pAIP/RiPkPy3tcYh/+Z34EWn7bS9 EWNnubKD4NooyCkcZ0nvT+RvHqz7n8M9IH2CguRMlGN4jDO/HxfXOTlEvOfy4IQv hYDfnzNWAVWNUlumEIqewhPaj6oeSNRUGSKadR/6GZh72sOggIsgbC/yXzoOHLLU Akqd7Y+cDl7nD7mIqSNZZdy3UzyPItTHDRRN48Bove8JPmrolZGs/0pEzuVfAblv fcav9ydCuk0iRquMsnV1p5njiYq4dXH62SbQKfelXJ7PTsNbHQN9Dmys616NzqG+ fqPVg0zSuSDEYNxs5YxeBB+P/SNfzxoiBIyQ8d4zIEhoZGDcDze/JniVtpbtocrt +z89FU1oryee5eWZRuFQBrUpei+1rXAbhQKU4NfkpNN78Sx/vxckBKEtFRFR1khT N7dIgc8rdObcVudLAV+/gYRpeN2v149AsRCGXshBTRsLmXT/3hQfFCPm6Jhmrqus XbS0T2FMELUIIdg51R1hNjRObvJwCyZGq9ZNoYlm6q20H6y188flnIVCuWq1DCLG 5DheppbZHB2UsgHA6SjaonsyPy+0St8RGJMc1c0OU33TzhYGHCxdl9NAZHUbQWCl rcVI1S1uMapUZ71v99zCpPWqbsect5MZzadjxAW1U4xL7BZouUWVpIYRZUsS4OM3 EiuzwnizRaJIuQpAT4Rn =2X2B -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kraxel/tags/input-20171023-pull-request' into staging input: fixes for ui input code and ps/2 keyboard (mostly sysrq key) # gpg: Signature made Mon 23 Oct 2017 10:19:22 BST # gpg: using RSA key 0x4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/input-20171023-pull-request: ui: pull in latest keycodemapdb ui: normalize the 'sysrq' key into the 'print' key ps2: fix scancodes sent for Ctrl+Pause key combination ps2: fix scancodess sent for Pause key in AT set 1 ps2: fix scancodes sent for Shift/Ctrl+Print key combination ps2: fix scancodes sent for Alt-Print key combination (aka SysRq) ui: use correct union field for key number ui: fix crash with sendkey and raw key numbers input: use hex in ps2 keycode trace events Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
328f6f79e9
207
hw/input/ps2.c
207
hw/input/ps2.c
@ -78,6 +78,14 @@
|
||||
|
||||
#define PS2_QUEUE_SIZE 16 /* Buffer size required by PS/2 protocol */
|
||||
|
||||
/* Bits for 'modifiers' field in PS2KbdState */
|
||||
#define MOD_CTRL_L (1 << 0)
|
||||
#define MOD_SHIFT_L (1 << 1)
|
||||
#define MOD_ALT_L (1 << 2)
|
||||
#define MOD_CTRL_R (1 << 3)
|
||||
#define MOD_SHIFT_R (1 << 4)
|
||||
#define MOD_ALT_R (1 << 5)
|
||||
|
||||
typedef struct {
|
||||
/* Keep the data array 256 bytes long, which compatibility
|
||||
with older qemu versions. */
|
||||
@ -99,6 +107,7 @@ typedef struct {
|
||||
int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */
|
||||
int ledstate;
|
||||
bool need_high_bit;
|
||||
unsigned int modifiers; /* bitmask of MOD_* constants above */
|
||||
} PS2KbdState;
|
||||
|
||||
typedef struct {
|
||||
@ -545,6 +554,26 @@ static uint8_t translate_table[256] = {
|
||||
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
|
||||
};
|
||||
|
||||
static unsigned int ps2_modifier_bit(QKeyCode key)
|
||||
{
|
||||
switch (key) {
|
||||
case Q_KEY_CODE_CTRL:
|
||||
return MOD_CTRL_L;
|
||||
case Q_KEY_CODE_CTRL_R:
|
||||
return MOD_CTRL_R;
|
||||
case Q_KEY_CODE_SHIFT:
|
||||
return MOD_SHIFT_L;
|
||||
case Q_KEY_CODE_SHIFT_R:
|
||||
return MOD_SHIFT_R;
|
||||
case Q_KEY_CODE_ALT:
|
||||
return MOD_ALT_L;
|
||||
case Q_KEY_CODE_ALT_R:
|
||||
return MOD_ALT_R;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void ps2_reset_queue(PS2State *s)
|
||||
{
|
||||
PS2Queue *q = &s->queue;
|
||||
@ -596,32 +625,85 @@ static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
|
||||
InputKeyEvent *key = evt->u.key.data;
|
||||
int qcode;
|
||||
uint16_t keycode;
|
||||
int mod;
|
||||
|
||||
qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
|
||||
assert(evt->type == INPUT_EVENT_KIND_KEY);
|
||||
qcode = qemu_input_key_value_to_qcode(key->key);
|
||||
|
||||
mod = ps2_modifier_bit(qcode);
|
||||
trace_ps2_keyboard_event(s, qcode, key->down, mod, s->modifiers);
|
||||
if (key->down) {
|
||||
s->modifiers |= mod;
|
||||
} else {
|
||||
s->modifiers &= ~mod;
|
||||
}
|
||||
|
||||
if (s->scancode_set == 1) {
|
||||
if (qcode == Q_KEY_CODE_PAUSE) {
|
||||
if (key->down) {
|
||||
ps2_put_keycode(s, 0xe1);
|
||||
ps2_put_keycode(s, 0x1d);
|
||||
ps2_put_keycode(s, 0x45);
|
||||
ps2_put_keycode(s, 0x91);
|
||||
ps2_put_keycode(s, 0x9d);
|
||||
ps2_put_keycode(s, 0xc5);
|
||||
if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
|
||||
if (key->down) {
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0x46);
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0xc6);
|
||||
}
|
||||
} else {
|
||||
if (key->down) {
|
||||
ps2_put_keycode(s, 0xe1);
|
||||
ps2_put_keycode(s, 0x1d);
|
||||
ps2_put_keycode(s, 0x45);
|
||||
ps2_put_keycode(s, 0xe1);
|
||||
ps2_put_keycode(s, 0x9d);
|
||||
ps2_put_keycode(s, 0xc5);
|
||||
}
|
||||
}
|
||||
} else if (qcode == Q_KEY_CODE_PRINT) {
|
||||
if (key->down) {
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0x2a);
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0x37);
|
||||
if (s->modifiers & MOD_ALT_L) {
|
||||
if (key->down) {
|
||||
ps2_put_keycode(s, 0xb8);
|
||||
ps2_put_keycode(s, 0x38);
|
||||
ps2_put_keycode(s, 0x54);
|
||||
} else {
|
||||
ps2_put_keycode(s, 0xd4);
|
||||
ps2_put_keycode(s, 0xb8);
|
||||
ps2_put_keycode(s, 0x38);
|
||||
}
|
||||
} else if (s->modifiers & MOD_ALT_R) {
|
||||
if (key->down) {
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0xb8);
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0x38);
|
||||
ps2_put_keycode(s, 0x54);
|
||||
} else {
|
||||
ps2_put_keycode(s, 0xd4);
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0xb8);
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0x38);
|
||||
}
|
||||
} else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
|
||||
MOD_SHIFT_R | MOD_CTRL_R)) {
|
||||
if (key->down) {
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0x37);
|
||||
} else {
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0xb7);
|
||||
}
|
||||
} else {
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0xb7);
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0xaa);
|
||||
if (key->down) {
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0x2a);
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0x37);
|
||||
} else {
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0xb7);
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0xaa);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
keycode = qcode_to_keycode_set1[qcode];
|
||||
@ -640,29 +722,81 @@ static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
|
||||
}
|
||||
} else if (s->scancode_set == 2) {
|
||||
if (qcode == Q_KEY_CODE_PAUSE) {
|
||||
if (key->down) {
|
||||
ps2_put_keycode(s, 0xe1);
|
||||
ps2_put_keycode(s, 0x14);
|
||||
ps2_put_keycode(s, 0x77);
|
||||
ps2_put_keycode(s, 0xe1);
|
||||
ps2_put_keycode(s, 0xf0);
|
||||
ps2_put_keycode(s, 0x14);
|
||||
ps2_put_keycode(s, 0xf0);
|
||||
ps2_put_keycode(s, 0x77);
|
||||
if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
|
||||
if (key->down) {
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0x7e);
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0xf0);
|
||||
ps2_put_keycode(s, 0x7e);
|
||||
}
|
||||
} else {
|
||||
if (key->down) {
|
||||
ps2_put_keycode(s, 0xe1);
|
||||
ps2_put_keycode(s, 0x14);
|
||||
ps2_put_keycode(s, 0x77);
|
||||
ps2_put_keycode(s, 0xe1);
|
||||
ps2_put_keycode(s, 0xf0);
|
||||
ps2_put_keycode(s, 0x14);
|
||||
ps2_put_keycode(s, 0xf0);
|
||||
ps2_put_keycode(s, 0x77);
|
||||
}
|
||||
}
|
||||
} else if (qcode == Q_KEY_CODE_PRINT) {
|
||||
if (key->down) {
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0x12);
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0x7c);
|
||||
if (s->modifiers & MOD_ALT_L) {
|
||||
if (key->down) {
|
||||
ps2_put_keycode(s, 0xf0);
|
||||
ps2_put_keycode(s, 0x11);
|
||||
ps2_put_keycode(s, 0x11);
|
||||
ps2_put_keycode(s, 0x84);
|
||||
} else {
|
||||
ps2_put_keycode(s, 0xf0);
|
||||
ps2_put_keycode(s, 0x84);
|
||||
ps2_put_keycode(s, 0xf0);
|
||||
ps2_put_keycode(s, 0x11);
|
||||
ps2_put_keycode(s, 0x11);
|
||||
}
|
||||
} else if (s->modifiers & MOD_ALT_R) {
|
||||
if (key->down) {
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0xf0);
|
||||
ps2_put_keycode(s, 0x11);
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0x11);
|
||||
ps2_put_keycode(s, 0x84);
|
||||
} else {
|
||||
ps2_put_keycode(s, 0xf0);
|
||||
ps2_put_keycode(s, 0x84);
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0xf0);
|
||||
ps2_put_keycode(s, 0x11);
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0x11);
|
||||
}
|
||||
} else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
|
||||
MOD_SHIFT_R | MOD_CTRL_R)) {
|
||||
if (key->down) {
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0x7c);
|
||||
} else {
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0xf0);
|
||||
ps2_put_keycode(s, 0x7c);
|
||||
}
|
||||
} else {
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0xf0);
|
||||
ps2_put_keycode(s, 0x7c);
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0xf0);
|
||||
ps2_put_keycode(s, 0x12);
|
||||
if (key->down) {
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0x12);
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0x7c);
|
||||
} else {
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0xf0);
|
||||
ps2_put_keycode(s, 0x7c);
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0xf0);
|
||||
ps2_put_keycode(s, 0x12);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
keycode = qcode_to_keycode_set2[qcode];
|
||||
@ -1125,6 +1259,7 @@ static void ps2_kbd_reset(void *opaque)
|
||||
s->scan_enabled = 0;
|
||||
s->translate = 0;
|
||||
s->scancode_set = 2;
|
||||
s->modifiers = 0;
|
||||
}
|
||||
|
||||
static void ps2_mouse_reset(void *opaque)
|
||||
|
@ -1,7 +1,8 @@
|
||||
# See docs/devel/tracing.txt for syntax documentation.
|
||||
|
||||
# hw/input/ps2.c
|
||||
ps2_put_keycode(void *opaque, int keycode) "%p keycode %d"
|
||||
ps2_put_keycode(void *opaque, int keycode) "%p keycode 0x%02x"
|
||||
ps2_keyboard_event(void *opaque, int qcode, int down, unsigned int modifier, unsigned int modifiers) "%p qcode %d down %d modifier 0x%x modifiers 0x%x"
|
||||
ps2_read_data(void *opaque) "%p"
|
||||
ps2_set_ledstate(void *s, int ledstate) "%p ledstate %d"
|
||||
ps2_reset_keyboard(void *s) "%p"
|
||||
|
@ -748,6 +748,13 @@
|
||||
# @ac_bookmarks: since 2.10
|
||||
# altgr, altgr_r: dropped in 2.10
|
||||
#
|
||||
# 'sysrq' was mistakenly added to hack around the fact that
|
||||
# the ps2 driver was not generating correct scancodes sequences
|
||||
# when 'alt+print' was pressed. This flaw is now fixed and the
|
||||
# 'sysrq' key serves no further purpose. Any further use of
|
||||
# 'sysrq' will be transparently changed to 'print', so they
|
||||
# are effectively synonyms.
|
||||
#
|
||||
# Since: 1.3.0
|
||||
#
|
||||
##
|
||||
|
@ -76,6 +76,11 @@ static KeyValue *copy_key_value(KeyValue *src)
|
||||
{
|
||||
KeyValue *dst = g_new(KeyValue, 1);
|
||||
memcpy(dst, src, sizeof(*src));
|
||||
if (dst->type == KEY_VALUE_KIND_NUMBER) {
|
||||
QKeyCode code = qemu_input_key_number_to_qcode(dst->u.number.data);
|
||||
dst->type = KEY_VALUE_KIND_QCODE;
|
||||
dst->u.qcode.data = code;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
16
ui/input.c
16
ui/input.c
@ -162,7 +162,7 @@ void qmp_input_send_event(bool has_device, const char *device,
|
||||
if (evt->type == INPUT_EVENT_KIND_KEY &&
|
||||
evt->u.key.data->key->type == KEY_VALUE_KIND_NUMBER) {
|
||||
KeyValue *key = evt->u.key.data->key;
|
||||
QKeyCode code = qemu_input_key_number_to_qcode(key->u.qcode.data);
|
||||
QKeyCode code = qemu_input_key_number_to_qcode(key->u.number.data);
|
||||
qemu_input_event_send_key_qcode(con, code, evt->u.key.data->down);
|
||||
} else {
|
||||
qemu_input_event_send(con, evt);
|
||||
@ -353,6 +353,20 @@ void qemu_input_event_send(QemuConsole *src, InputEvent *evt)
|
||||
assert(!(evt->type == INPUT_EVENT_KIND_KEY &&
|
||||
evt->u.key.data->key->type == KEY_VALUE_KIND_NUMBER));
|
||||
|
||||
|
||||
/*
|
||||
* 'sysrq' was mistakenly added to hack around the fact that
|
||||
* the ps2 driver was not generating correct scancodes sequences
|
||||
* when 'alt+print' was pressed. This flaw is now fixed and the
|
||||
* 'sysrq' key serves no further purpose. We normalize it to
|
||||
* 'print', so that downstream receivers of the event don't
|
||||
* neeed to deal with this mistake
|
||||
*/
|
||||
if (evt->type == INPUT_EVENT_KIND_KEY &&
|
||||
evt->u.key.data->key->u.qcode.data == Q_KEY_CODE_SYSRQ) {
|
||||
evt->u.key.data->key->u.qcode.data = Q_KEY_CODE_PRINT;
|
||||
}
|
||||
|
||||
if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
|
||||
return;
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 56ce5650d2c6ea216b4580df44b9a6dd3bc92c3b
|
||||
Subproject commit 10739aa26051a5d49d88132604539d3ed085e72e
|
Loading…
Reference in New Issue
Block a user