input layer rework continued
v2 cover input layer rework continued
Hi,
Series adds some keyboard mapping helpers and starts switching over devices to the new input api.
New in v2:
- sparc kbd fixes, according to reports by Olivier Danet, please verify.
- picked up ps/2 buffer size fix by Gonglei.
cheers,
Gerd
Gerd Hoffmann (9):
input: key mapping helpers
input: add qemu_input_handler_deactivate
input: use KeyValue directly in sendkey monitor command
input: switch ps/2 kbd to new input api
input: switch ps/2 mouse to new input api
input: switch sparc32 kbd to new input api
input: remove sparc keymap hack
input: sparc32 kbd: fix some key mappings
input: sparc32 kbd: claim en-us layout
Gonglei (1):
ps2: set ps/2 output buffer size as the same as kernel
hw/char/escc.c | 233 +++++++++++++++++++++++++++++++++++++++-------------- hw/input/ps2.c | 166 +++++++++++++++++++++++++++++++++----- include/ui/input.h | 5 ++ trace-events | 4 +- ui/Makefile.objs | 3 +- ui/input-keymap.c | 191 +++++++++++++++++++++++++++++++++++++++++++ ui/input-legacy.c | 226 +++++++-------------------------------------------- ui/input.c | 7 ++ 8 files changed, 553 insertions(+), 282 deletions(-) create mode 100644 ui/input-keymap.c
Signature · 1 line
1.8.3.1
PATCH v2 1/10 ps2: set ps/2 output buffer size as the same as kernel
From: Gonglei <[email protected]>
According to the PS/2 Mouse/Keyboard Protocol, the keyboard outupt buffer size is 16 bytes. And the PS2_QUEUE_SIZE 256 was introduced in Qemu from the very beginning.
When I started a redhat5.6 32bit guest, meanwhile tapped the keyboard as quickly as possible, the screen would show me "i8042.c: No controller found". As a result, I couldn't use the keyboard in the VNC client.
Previous discussion about the issue in maillist:
http://thread.gmane.org/gmane.comp.emulators.qemu/43294/focus=47180
This patch has been tested on redhat5.6 32-bit/suse11sp3 64-bit guests. More easy meathod to reproduce:
1.boot a guest with libvirt.
2.connect to VNC client.
3.as you see the BIOS, bootloader, Linux booting, run the follow simply shell script:
for((i=0;i<10000000;i++)) do virsh send-key redhat5.6 KEY_A; done
Actual results:
dmesg show "i8042.c: No controller found." And the keyboard is out of work.
--- hw/input/ps2.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 6 deletions(-)
hw/input/ps2.c +68 -6
@@ -71,10 +71,12 @@#define MOUSE_STATUS_ENABLED 0x20#define MOUSE_STATUS_SCALE21 0x10 -#define PS2_QUEUE_SIZE 256 +#define PS2_QUEUE_SIZE 16/* Buffer size required by PS/2 protocol */ typedef struct { -uint8_t data[PS2_QUEUE_SIZE ]; +/* Keep the data array 256 bytes long, which compatibility +with older qemu versions. */ +uint8_t data[256 ];int rptr, wptr, count; }PS2Queue ;
@@ -137,7 +139,7 @@ void ps2_queue(void *opaque, int b)PS2State *s = (PS2State *)opaque;PS2Queue *q = &s->queue; -if (q->count >=PS2_QUEUE_SIZE ) +if (q->count >=PS2_QUEUE_SIZE -1 )return ; q->data[q->wptr] = b;if (++q->wptr ==PS2_QUEUE_SIZE )
@@ -374,9 +376,8 @@ static void ps2_mouse_event(void *opaque,qemu_system_wakeup_request (QEMU_WAKEUP_REASON_OTHER ); } -if (!(s->mouse_status &MOUSE_STATUS_REMOTE ) && - (s->common.queue.count < (PS2_QUEUE_SIZE -16 ))) { -for (;;) { +if (!(s->mouse_status &MOUSE_STATUS_REMOTE )) { +while (s->common.queue.count <PS2_QUEUE_SIZE -4 ) {/* if not remote, send event. Multiple events are sent if too big deltas */ ps2_mouse_send_packet (s);
@@ -528,6 +529,34 @@ static void ps2_common_reset(PS2State *s) s->update_irq (s->update_arg,0 ); } +static void ps2_common_post_load (PS2State *s) +{ +PS2Queue *q = &s->queue; +int size; +int i; +int tmp_data[PS2_QUEUE_SIZE ]; + +/* set the useful data buffer queue size, < PS2_QUEUE_SIZE */ + size = q->count >PS2_QUEUE_SIZE ?0 : q->count; + +/* move the queue elements to the start of data array */ +if (size >0 ) { +for (i =0 ; i < size; i++) { +/* move the queue elements to the temporary buffer */ + tmp_data[i] = q->data[q->rptr]; +if (++q->rptr ==256 ) { + q->rptr =0 ; + } + } +memcpy (q->data, tmp_data, size); + } +/* reset rptr/wptr/count */ + q->rptr =0 ; + q->wptr = size; + q->count = size; + s->update_irq (s->update_arg, q->count !=0 ); +} +static void ps2_kbd_reset (void *opaque) {PS2KbdState *s = (PS2KbdState *) opaque;
@@ -600,18 +629,31 @@ static const VMStateDescription vmstate_ps2_keyboard_ledstate = {static int ps2_kbd_post_load (void * opaque,int version_id) {PS2KbdState *s = (PS2KbdState *)opaque; +PS2State *ps2 = &s->common;if (version_id ==2 ) s->scancode_set=2 ; + +ps2_common_post_load (ps2); +return 0 ; } +static void ps2_kbd_pre_save (void *opaque) +{ +PS2KbdState *s = (PS2KbdState *)opaque; +PS2State *ps2 = &s->common; + +ps2_common_post_load (ps2); +} +static const VMStateDescription vmstate_ps2_keyboard = { .name ="ps2kbd" , .version_id =3 , .minimum_version_id =2 , .minimum_version_id_old =2 , .post_load = ps2_kbd_post_load, + .pre_save = ps2_kbd_pre_save, .fields = (VMStateField []) {VMSTATE_STRUCT (common, PS2KbdState,0 , vmstate_ps2_common, PS2State),VMSTATE_INT32 (scan_enabled, PS2KbdState),
@@ -629,11 +671,31 @@ static const VMStateDescription vmstate_ps2_keyboard = { } }; +static int ps2_mouse_post_load (void *opaque,int version_id) +{ +PS2MouseState *s = (PS2MouseState *)opaque; +PS2State *ps2 = &s->common; + +ps2_common_post_load (ps2); + +return 0 ; +} + +static void ps2_mouse_pre_save (void *opaque) +{ +PS2MouseState *s = (PS2MouseState *)opaque; +PS2State *ps2 = &s->common; + +ps2_common_post_load (ps2); +} +static const VMStateDescription vmstate_ps2_mouse = { .name ="ps2mouse" , .version_id =2 , .minimum_version_id =2 , .minimum_version_id_old =2 , + .post_load = ps2_mouse_post_load, + .pre_save = ps2_mouse_pre_save, .fields = (VMStateField []) {VMSTATE_STRUCT (common, PS2MouseState,0 , vmstate_ps2_common, PS2State),VMSTATE_UINT8 (mouse_status, PS2MouseState),
Signature · 1 line
1.8.3.1
PATCH v2 2/10 input: key mapping helpers
In reply to Gerd HoffmannAdd helper functions to translate KeyValue (qapi key representation) into other representations: traditional qemu key numbers, qapi key codes (Q_KEY_CODE_*) and scancode sequences.
--- include/ui/input.h | 4 + ui/Makefile.objs | 3 +- ui/input-keymap.c | 210 +++++++++++++++++++++++++++++++++++++++++++++++++++++ ui/input-legacy.c | 181 ++------------------------------------------- 4 files changed, 223 insertions(+), 175 deletions(-) create mode 100644 ui/input-keymap.c
include/ui/input.h +4 -0
@@ -35,6 +35,10 @@ InputEvent *qemu_input_event_new_key(KeyValue *key, bool down);void qemu_input_event_send_key (QemuConsole *src,KeyValue *key,bool down);void qemu_input_event_send_key_number (QemuConsole *src,int num,bool down);void qemu_input_event_send_key_qcode (QemuConsole *src,QKeyCode q,bool down); +int qemu_input_key_value_to_number (const KeyValue *value); +int qemu_input_key_value_to_qcode (const KeyValue *value); +int qemu_input_key_value_to_scancode (const KeyValue *value,bool down, +int *codes);InputEvent *qemu_input_event_new_btn (InputButton btn,bool down);void qemu_input_queue_btn (QemuConsole *src,InputButton btn,bool down);
ui/Makefile.objs +2 -1
@@ -7,7 +7,8 @@ vnc-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o vnc-obj-$(CONFIG_VNC_WS) += vnc-ws.o vnc-obj-y += vnc-jobs.o -common-obj-y += keymaps.o console.o cursor.o input.o input-legacy.o qemu-pixman.o +common-obj-y += keymaps.o console.o cursor.o qemu-pixman.o +common-obj-y += input.o input-keymap.o input-legacy.o common-obj-$(CONFIG_SPICE) += spice-core.o spice-input.o spice-display.o common-obj-$(CONFIG_SDL) += sdl.o sdl_zoom.o x_keymap.o sdl2.o common-obj-$(CONFIG_COCOA) += cocoa.o
ui/input-keymap.c new file +210 -0
210 lines not on this page · raw message
ui/input-legacy.c +7 -174
210 lines not on this page · raw message
Signature · 1 line
1.8.3.1
PATCH v2 3/10 input: add qemu_input_handler_deactivate
In reply to Gerd Hoffmann--- include/ui/input.h | 1 + ui/input.c | 7 +++++++ 2 files changed, 8 insertions(+)
include/ui/input.h +1 -0
@@ -27,6 +27,7 @@ struct QemuInputHandler {QemuInputHandlerState *qemu_input_handler_register (DeviceState *dev,QemuInputHandler *handler);void qemu_input_handler_activate (QemuInputHandlerState *s); +void qemu_input_handler_deactivate (QemuInputHandlerState *s);void qemu_input_handler_unregister (QemuInputHandlerState *s);void qemu_input_event_send (QemuConsole *src,InputEvent *evt);void qemu_input_event_sync (void );
ui/input.c +7 -0
@@ -39,6 +39,13 @@ void qemu_input_handler_activate(QemuInputHandlerState *s)qemu_input_check_mode_change (); } +void qemu_input_handler_deactivate (QemuInputHandlerState *s) +{ +QTAILQ_REMOVE (&handlers, s, node); +QTAILQ_INSERT_TAIL (&handlers, s, node); +qemu_input_check_mode_change (); +} +void qemu_input_handler_unregister (QemuInputHandlerState *s) {QTAILQ_REMOVE (&handlers, s, node);
Signature · 1 line
1.8.3.1
PATCH v2 4/10 input: use KeyValue directly in sendkey monitor command
In reply to Gerd Hoffmann--- ui/input-legacy.c | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-)
ui/input-legacy.c +23 -24
@@ -74,38 +74,44 @@ int index_from_key(const char *key)return i; } -static int *keycodes; -static int keycodes_size; +static KeyValue **keyvalues; +static int keyvalues_size;static QEMUTimer *key_timer; -static void free_keycodes (void ) +static void free_keyvalues (void ) { -g_free (keycodes); - keycodes =NULL ; - keycodes_size =0 ; +g_free (keyvalues); + keyvalues =NULL ; + keyvalues_size =0 ; }static void release_keys (void *opaque) { -while (keycodes_size >0 ) { -qemu_input_event_send_key_number (NULL , keycodes[--keycodes_size], - false); +while (keyvalues_size >0 ) { +qemu_input_event_send_key (NULL , keyvalues[--keyvalues_size], + false); } -free_keycodes (); +free_keyvalues (); +} + +static KeyValue *copy_key_value (KeyValue *src) +{ +KeyValue *dst =g_new (KeyValue,1 ); +memcpy (dst, src,sizeof (*src)); +return dst; }void qmp_send_key (KeyValueList *keys,bool has_hold_time,int64_t hold_time,Error **errp) { -int keycode;KeyValueList *p;if (!key_timer) { key_timer =timer_new_ns (QEMU_CLOCK_VIRTUAL , release_keys,NULL ); } -if (keycodes !=NULL ) { +if (keyvalues !=NULL ) {timer_del (key_timer);release_keys (NULL ); }
@@ -115,23 +121,16 @@ void qmp_send_key(KeyValueList *keys, bool has_hold_time, int64_t hold_time, }for (p = keys; p !=NULL ; p = p->next) { -/* key down events */ - keycode =qemu_input_key_value_to_number (p->value); -if (keycode <0x01 || keycode >0xff ) { -error_setg (errp,"invalid hex keycode 0x%x" , keycode); -free_keycodes (); -return ; - } - -qemu_input_event_send_key_number (NULL , keycode, true); +qemu_input_event_send_key (NULL ,copy_key_value (p->value), true); - keycodes =g_realloc (keycodes,sizeof (int ) * (keycodes_size +1 )); - keycodes[keycodes_size++] = keycode; + keyvalues =g_realloc (keyvalues,sizeof (KeyValue *) * + (keyvalues_size +1 )); + keyvalues[keyvalues_size++] =copy_key_value (p->value); }/* delayed key up events */ timer_mod (key_timer,qemu_clock_get_ns (QEMU_CLOCK_VIRTUAL ) + -muldiv64 (get_ticks_per_sec (), hold_time,1000 )); +muldiv64 (get_ticks_per_sec (), hold_time,1000 )); } static void legacy_kbd_event(DeviceState *dev, QemuConsole *src,
Signature · 1 line
1.8.3.1
PATCH v2 5/10 input: switch ps/2 kbd to new input api
In reply to Gerd Hoffmann--- hw/input/ps2.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-)
hw/input/ps2.c +24 -1
@@ -24,6 +24,7 @@#include "hw/hw.h" #include "hw/input/ps2.h" #include "ui/console.h" +#include "ui/input.h" #include "sysemu/sysemu.h" /* debug PC keyboard */
@@ -172,6 +173,21 @@ static void ps2_put_keycode(void *opaque, int keycode)ps2_queue (&s->common, keycode); } +static void ps2_keyboard_event (DeviceState *dev,QemuConsole *src, +InputEvent *evt) +{ +PS2KbdState *s = (PS2KbdState *)dev; +int scancodes[3 ], i, count; + +qemu_system_wakeup_request (QEMU_WAKEUP_REASON_OTHER ); + count =qemu_input_key_value_to_scancode (evt->key->key, + evt->key->down, + scancodes); +for (i =0 ; i < count; i++) { +ps2_put_keycode (s, scancodes[i]); + } +} +uint32_t ps2_read_data (void *opaque) {PS2State *s = (PS2State *)opaque;
@@ -712,6 +728,12 @@ static const VMStateDescription vmstate_ps2_mouse = { } }; +static QemuInputHandler ps2_keyboard_handler = { + .name ="QEMU PS/2 Keyboard" , + .mask =INPUT_EVENT_MASK_KEY , + .event = ps2_keyboard_event, +}; +void *ps2_kbd_init (void (*update_irq)(void *,int ),void *update_arg) {PS2KbdState *s = (PS2KbdState *)g_malloc0 (sizeof (PS2KbdState));
@@ -720,7 +742,8 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg) s->common.update_arg = update_arg; s->scancode_set =2 ;vmstate_register (NULL ,0 , &vmstate_ps2_keyboard, s); -qemu_add_kbd_event_handler (ps2_put_keycode, s); +qemu_input_handler_register ((DeviceState *)s, + &ps2_keyboard_handler);qemu_register_reset (ps2_kbd_reset, s);return s; }
Signature · 1 line
1.8.3.1
PATCH v2 6/10 input: switch ps/2 mouse to new input api
In reply to Gerd Hoffmann--- hw/input/ps2.c | 67 +++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 15 deletions(-)
hw/input/ps2.c +52 -15
@@ -370,28 +370,55 @@ static void ps2_mouse_send_packet(PS2MouseState *s) s->mouse_dz -= dz1; } -static void ps2_mouse_event (void *opaque, -int dx,int dy,int dz,int buttons_state) +static void ps2_mouse_event (DeviceState *dev,QemuConsole *src, +InputEvent *evt) { -PS2MouseState *s = opaque; +static const int bmap[INPUT_BUTTON_MAX ] = { + [INPUT_BUTTON_LEFT ] =MOUSE_EVENT_LBUTTON , + [INPUT_BUTTON_MIDDLE ] =MOUSE_EVENT_MBUTTON , + [INPUT_BUTTON_RIGHT ] =MOUSE_EVENT_RBUTTON , + }; +PS2MouseState *s = (PS2MouseState *)dev;/* check if deltas are recorded when disabled */ if (!(s->mouse_status &MOUSE_STATUS_ENABLED ))return ; - s->mouse_dx += dx; - s->mouse_dy -= dy; - s->mouse_dz += dz; -/* XXX: SDL sometimes generates nul events: we delete them */ -if (s->mouse_dx ==0 && s->mouse_dy ==0 && s->mouse_dz ==0 && - s->mouse_buttons == buttons_state) -return ; - s->mouse_buttons = buttons_state; +switch (evt->kind) { +case INPUT_EVENT_KIND_REL : +if (evt->rel->axis ==INPUT_AXIS_X ) { + s->mouse_dx += evt->rel->value; + }else if (evt->rel->axis ==INPUT_AXIS_Y ) { + s->mouse_dy -= evt->rel->value; + } +break ; -if (buttons_state) { -qemu_system_wakeup_request (QEMU_WAKEUP_REASON_OTHER ); +case INPUT_EVENT_KIND_BTN : +if (evt->btn->down) { + s->mouse_buttons |= bmap[evt->btn->button]; +if (evt->btn->button ==INPUT_BUTTON_WHEEL_UP ) { + s->mouse_dz--; + }else if (evt->btn->button ==INPUT_BUTTON_WHEEL_DOWN ) { + s->mouse_dz++; + } + }else { + s->mouse_buttons &= ~bmap[evt->btn->button]; + } +break ; + +default : +/* keep gcc happy */ +break ; } +} +static void ps2_mouse_sync (DeviceState *dev) +{ +PS2MouseState *s = (PS2MouseState *)dev; + +if (s->mouse_buttons) { +qemu_system_wakeup_request (QEMU_WAKEUP_REASON_OTHER ); + }if (!(s->mouse_status &MOUSE_STATUS_REMOTE )) {while (s->common.queue.count <PS2_QUEUE_SIZE -4 ) {/* if not remote, send event. Multiple events are sent if
@@ -405,7 +432,9 @@ static void ps2_mouse_event(void *opaque,void ps2_mouse_fake_event (void *opaque) { -ps2_mouse_event (opaque,1 ,0 ,0 ,0 ); +PS2MouseState *s = opaque; + s->mouse_dx++; +ps2_mouse_sync (opaque); }void ps2_write_mouse (void *opaque,int val)
@@ -748,6 +777,13 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)return s; } +static QemuInputHandler ps2_mouse_handler = { + .name ="QEMU PS/2 Mouse" , + .mask =INPUT_EVENT_MASK_BTN |INPUT_EVENT_MASK_REL , + .event = ps2_mouse_event, + .sync = ps2_mouse_sync, +}; +void *ps2_mouse_init (void (*update_irq)(void *,int ),void *update_arg) {PS2MouseState *s = (PS2MouseState *)g_malloc0 (sizeof (PS2MouseState));
@@ -755,7 +791,8 @@ void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg) s->common.update_irq = update_irq; s->common.update_arg = update_arg;vmstate_register (NULL ,0 , &vmstate_ps2_mouse, s); -qemu_add_mouse_event_handler (ps2_mouse_event, s,0 ,"QEMU PS/2 Mouse" ); +qemu_input_handler_register ((DeviceState *)s, + &ps2_mouse_handler);qemu_register_reset (ps2_mouse_reset, s);return s; }
Signature · 1 line
1.8.3.1
PATCH v2 7/10 input: switch sparc32 kbd to new input api
In reply to Gerd HoffmannNasty 0xe0 logic is gone. We map through QKeyCode now, giving us a nice, readable mapping table.
Quick smoke test in OpenFirmware looks ok. Careful check from arch maintainers would be very nice, especially on the capslock and numlock logic. I'm not fully sure whenever I got it translated correctly and also what it is supposed to do in the first place ...
--- hw/char/escc.c | 229 ++++++++++++++++++++++++++++++++++++++++++--------------- trace-events | 4 +- 2 files changed, 172 insertions(+), 61 deletions(-)
hw/char/escc.c +170 -59
@@ -27,6 +27,7 @@#include "hw/char/escc.h" #include "sysemu/char.h" #include "ui/console.h" +#include "ui/input.h" #include "trace.h" /*
@@ -94,6 +95,7 @@ typedef struct ChannelState {ChnID chn;// this channel, A (base+4) or B (base+0) ChnType type;uint8_t rx, tx; +QemuInputHandlerState *hs; } ChannelState;#define ESCC (obj) OBJECT_CHECK(ESCCState, (obj), TYPE_ESCC)
@@ -714,71 +716,179 @@ MemoryRegion *escc_init(hwaddr base, qemu_irq irqA, qemu_irq irqB,return &d->mmio; } -static const uint8_t keycodes[128 ] = { -127 ,29 ,30 ,31 ,32 ,33 ,34 ,35 ,36 ,37 ,38 ,39 ,40 ,41 ,43 ,53 , -54 ,55 ,56 ,57 ,58 ,59 ,60 ,61 ,62 ,63 ,64 ,65 ,89 ,76 ,77 ,78 , -79 ,80 ,81 ,82 ,83 ,84 ,85 ,86 ,87 ,42 ,99 ,88 ,100 ,101 ,102 ,103 , -104 ,105 ,106 ,107 ,108 ,109 ,110 ,47 ,19 ,121 ,119 ,5 ,6 ,8 ,10 ,12 , -14 ,16 ,17 ,18 ,7 ,98 ,23 ,68 ,69 ,70 ,71 ,91 ,92 ,93 ,125 ,112 , -113 ,114 ,94 ,50 ,0 ,0 ,124 ,9 ,11 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , -90 ,0 ,46 ,22 ,13 ,111 ,52 ,20 ,96 ,24 ,28 ,74 ,27 ,123 ,44 ,66 , -0 ,45 ,2 ,4 ,48 ,0 ,0 ,21 ,0 ,0 ,0 ,0 ,0 ,120 ,122 ,67 , +static const uint8_t qcode_to_keycode[Q_KEY_CODE_MAX ] = { + [Q_KEY_CODE_SHIFT ] =99 , + [Q_KEY_CODE_SHIFT_R ] =110 , + [Q_KEY_CODE_ALT ] =19 , + [Q_KEY_CODE_ALT_R ] =13 , + [Q_KEY_CODE_ALTGR ] =13 , + [Q_KEY_CODE_CTRL ] =76 , + [Q_KEY_CODE_CTRL_R ] =76 , + [Q_KEY_CODE_ESC ] =29 , + [Q_KEY_CODE_1 ] =30 , + [Q_KEY_CODE_2 ] =31 , + [Q_KEY_CODE_3 ] =32 , + [Q_KEY_CODE_4 ] =33 , + [Q_KEY_CODE_5 ] =34 , + [Q_KEY_CODE_6 ] =35 , + [Q_KEY_CODE_7 ] =36 , + [Q_KEY_CODE_8 ] =37 , + [Q_KEY_CODE_9 ] =38 , + [Q_KEY_CODE_0 ] =39 , + [Q_KEY_CODE_MINUS ] =40 , + [Q_KEY_CODE_EQUAL ] =41 , + [Q_KEY_CODE_BACKSPACE ] =43 , + [Q_KEY_CODE_TAB ] =53 , + [Q_KEY_CODE_Q ] =54 , + [Q_KEY_CODE_W ] =55 , + [Q_KEY_CODE_E ] =56 , + [Q_KEY_CODE_R ] =57 , + [Q_KEY_CODE_T ] =58 , + [Q_KEY_CODE_Y ] =59 , + [Q_KEY_CODE_U ] =60 , + [Q_KEY_CODE_I ] =61 , + [Q_KEY_CODE_O ] =62 , + [Q_KEY_CODE_P ] =63 , + [Q_KEY_CODE_BRACKET_LEFT ] =64 , + [Q_KEY_CODE_BRACKET_RIGHT ] =65 , + [Q_KEY_CODE_RET ] =89 , + [Q_KEY_CODE_A ] =77 , + [Q_KEY_CODE_S ] =78 , + [Q_KEY_CODE_D ] =79 , + [Q_KEY_CODE_F ] =80 , + [Q_KEY_CODE_G ] =81 , + [Q_KEY_CODE_H ] =82 , + [Q_KEY_CODE_J ] =83 , + [Q_KEY_CODE_K ] =84 , + [Q_KEY_CODE_L ] =85 , + [Q_KEY_CODE_SEMICOLON ] =86 , + [Q_KEY_CODE_APOSTROPHE ] =87 , + [Q_KEY_CODE_GRAVE_ACCENT ] =42 , + [Q_KEY_CODE_BACKSLASH ] =88 , + [Q_KEY_CODE_Z ] =100 , + [Q_KEY_CODE_X ] =101 , + [Q_KEY_CODE_C ] =102 , + [Q_KEY_CODE_V ] =103 , + [Q_KEY_CODE_B ] =104 , + [Q_KEY_CODE_N ] =105 , + [Q_KEY_CODE_M ] =106 , + [Q_KEY_CODE_COMMA ] =107 , + [Q_KEY_CODE_DOT ] =108 , + [Q_KEY_CODE_SLASH ] =109 , + [Q_KEY_CODE_ASTERISK ] =47 , + [Q_KEY_CODE_SPC ] =121 , + [Q_KEY_CODE_CAPS_LOCK ] =119 , + [Q_KEY_CODE_F1 ] =5 , + [Q_KEY_CODE_F2 ] =6 , + [Q_KEY_CODE_F3 ] =8 , + [Q_KEY_CODE_F4 ] =10 , + [Q_KEY_CODE_F5 ] =12 , + [Q_KEY_CODE_F6 ] =14 , + [Q_KEY_CODE_F7 ] =16 , + [Q_KEY_CODE_F8 ] =17 , + [Q_KEY_CODE_F9 ] =18 , + [Q_KEY_CODE_F10 ] =7 , + [Q_KEY_CODE_NUM_LOCK ] =98 , + [Q_KEY_CODE_SCROLL_LOCK ] =23 , + [Q_KEY_CODE_KP_DIVIDE ] =109 , + [Q_KEY_CODE_KP_MULTIPLY ] =47 , + [Q_KEY_CODE_KP_SUBTRACT ] =71 , + [Q_KEY_CODE_KP_ADD ] =125 , + [Q_KEY_CODE_KP_ENTER ] =90 , + [Q_KEY_CODE_KP_DECIMAL ] =50 , + [Q_KEY_CODE_KP_0 ] =94 , + [Q_KEY_CODE_KP_1 ] =112 , + [Q_KEY_CODE_KP_2 ] =113 , + [Q_KEY_CODE_KP_3 ] =114 , + [Q_KEY_CODE_KP_4 ] =91 , + [Q_KEY_CODE_KP_5 ] =92 , + [Q_KEY_CODE_KP_6 ] =93 , + [Q_KEY_CODE_KP_7 ] =68 , + [Q_KEY_CODE_KP_8 ] =69 , + [Q_KEY_CODE_KP_9 ] =70 , + [Q_KEY_CODE_LESS ] =124 , + [Q_KEY_CODE_F11 ] =9 , + [Q_KEY_CODE_F12 ] =11 , + [Q_KEY_CODE_HOME ] =68 , + [Q_KEY_CODE_PGUP ] =70 , + [Q_KEY_CODE_PGDN ] =114 , + [Q_KEY_CODE_END ] =112 , + [Q_KEY_CODE_LEFT ] =91 , + [Q_KEY_CODE_UP ] =69 , + [Q_KEY_CODE_DOWN ] =113 , + [Q_KEY_CODE_RIGHT ] =93 , + [Q_KEY_CODE_INSERT ] =94 , + [Q_KEY_CODE_DELETE ] =50 , + [Q_KEY_CODE_STOP ] =1 , + [Q_KEY_CODE_AGAIN ] =3 , + [Q_KEY_CODE_PROPS ] =25 , + [Q_KEY_CODE_UNDO ] =26 , + [Q_KEY_CODE_FRONT ] =49 , + [Q_KEY_CODE_COPY ] =52 , + [Q_KEY_CODE_OPEN ] =72 , + [Q_KEY_CODE_PASTE ] =73 , + [Q_KEY_CODE_FIND ] =97 , + [Q_KEY_CODE_CUT ] =99 , + [Q_KEY_CODE_LF ] =111 , + [Q_KEY_CODE_HELP ] =118 , + [Q_KEY_CODE_META_L ] =120 , + [Q_KEY_CODE_META_R ] =122 , + [Q_KEY_CODE_COMPOSE ] =67 , }; -static const uint8_t e0_keycodes[128 ] = { -0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , -0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,90 ,76 ,0 ,0 , -0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , -0 ,0 ,0 ,0 ,0 ,109 ,0 ,0 ,13 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , -0 ,0 ,0 ,0 ,0 ,0 ,0 ,68 ,69 ,70 ,0 ,91 ,0 ,93 ,0 ,112 , -113 ,114 ,94 ,50 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , -0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , -1 ,3 ,25 ,26 ,49 ,52 ,72 ,73 ,97 ,99 ,111 ,118 ,120 ,122 ,67 ,0 , -}; - -static void sunkbd_event (void *opaque,int ch) +static void sunkbd_handle_event (DeviceState *dev,QemuConsole *src, +InputEvent *evt) { -ChannelState *s = opaque; -int release = ch &0x80 ; - -trace_escc_sunkbd_event_in (ch); -switch (ch) { -case 58 :// Caps lock press - s->caps_lock_mode ^=1 ; -if (s->caps_lock_mode ==2 ) -return ;// Drop second press -break ; -case 69 :// Num lock press - s->num_lock_mode ^=1 ; -if (s->num_lock_mode ==2 ) -return ;// Drop second press -break ; -case 186 :// Caps lock release - s->caps_lock_mode ^=2 ; -if (s->caps_lock_mode ==3 ) -return ;// Drop first release -break ; -case 197 :// Num lock release - s->num_lock_mode ^=2 ; -if (s->num_lock_mode ==3 ) -return ;// Drop first release -break ; -case 0xe0 : - s->e0_mode =1 ; -return ; -default : -break ; +ChannelState *s = (ChannelState *)dev; +int qcode, keycode; + +assert (evt->kind ==INPUT_EVENT_KIND_KEY ); + qcode =qemu_input_key_value_to_qcode (evt->key->key); +trace_escc_sunkbd_event_in (qcode, QKeyCode_lookup[qcode], + evt->key->down); + +if (qcode ==Q_KEY_CODE_CAPS_LOCK ) { +if (evt->key->down) { + s->caps_lock_mode ^=1 ; +if (s->caps_lock_mode ==2 ) { +return ;/* Drop second press */ + } + }else { + s->caps_lock_mode ^=2 ; +if (s->caps_lock_mode ==3 ) { +return ;/* Drop first release */ + } + } } -if (s->e0_mode) { - s->e0_mode =0 ; - ch = e0_keycodes[ch &0x7f ]; - }else { - ch = keycodes[ch &0x7f ]; + +if (qcode ==Q_KEY_CODE_NUM_LOCK ) { +if (evt->key->down) { + s->num_lock_mode ^=1 ; +if (s->num_lock_mode ==2 ) { +return ;/* Drop second press */ + } + }else { + s->num_lock_mode ^=2 ; +if (s->num_lock_mode ==3 ) { +return ;/* Drop first release */ + } + } + } + + keycode = qcode_to_keycode[qcode]; +if (!evt->key->down) { + keycode |=0x80 ; } -trace_escc_sunkbd_event_out (ch); -put_queue (s, ch | release); +trace_escc_sunkbd_event_out (keycode); +put_queue (s, keycode); } +static QemuInputHandler sunkbd_handler = { + .name ="sun keyboard" , + .mask =INPUT_EVENT_MASK_KEY , + .event = sunkbd_handle_event, +}; +static void handle_kbd_command (ChannelState *s,int val) {trace_escc_kbd_command (val);
@@ -898,7 +1008,8 @@ static int escc_init1(SysBusDevice *dev) "QEMU Sun Mouse"); }if (s->chn[1 ].type == kbd) { -qemu_add_kbd_event_handler (sunkbd_event, &s->chn[1 ]); + s->chn[1 ].hs =qemu_input_handler_register ((DeviceState *)(&s->chn[1 ]), + &sunkbd_handler); }return 0 ;
trace-events +2 -2
@@ -859,8 +859,8 @@ escc_mem_writeb_data(char channel, uint32_t val) "Write channel %c, ch %d" escc_mem_readb_ctrl(char channel, uint32_t reg, uint8_t val) "Read channel %c, reg[%d] = %2.2x" escc_mem_readb_data(char channel, uint32_t ret) "Read channel %c, ch %d" escc_serial_receive_byte(char channel, int ch) "channel %c put ch %d" -escc_sunkbd_event_in(int ch) "Untranslated keycode %2.2x" -escc_sunkbd_event_out(int ch) "Translated keycode %2.2x" +escc_sunkbd_event_in(int ch, const char *name, int down) "QKeyCode 0x%2.2x [%s], down %d" +escc_sunkbd_event_out(int ch) "Translated keycode 0x%2.2x" escc_kbd_command(int val) "Command %d" escc_sunmouse_event(int dx, int dy, int buttons_state) "dx=%d dy=%d buttons=%01x"
Signature · 1 line
1.8.3.1
PATCH v2 8/10 input: remove sparc keymap hack
In reply to Gerd HoffmannWith sparc keyboard going directly from QKeyValue to sparc keycodes this should not be needed any more.
--- ui/input-keymap.c | 19 ------------------- 1 file changed, 19 deletions(-)
ui/input-keymap.c +0 -19
@@ -126,25 +126,6 @@ static const int qcode_to_number[] = { [Q_KEY_CODE_INSERT] = 0xd2, [Q_KEY_CODE_DELETE] = 0xd3, -#ifdef NEED_CPU_H -#if defined(TARGET_SPARC) && !defined(TARGET_SPARC64) - [Q_KEY_CODE_STOP] = 0xf0, - [Q_KEY_CODE_AGAIN] = 0xf1, - [Q_KEY_CODE_PROPS] = 0xf2, - [Q_KEY_CODE_UNDO] = 0xf3, - [Q_KEY_CODE_FRONT] = 0xf4, - [Q_KEY_CODE_COPY] = 0xf5, - [Q_KEY_CODE_OPEN] = 0xf6, - [Q_KEY_CODE_PASTE] = 0xf7, - [Q_KEY_CODE_FIND] = 0xf8, - [Q_KEY_CODE_CUT] = 0xf9, - [Q_KEY_CODE_LF] = 0xfa, - [Q_KEY_CODE_HELP] = 0xfb, - [Q_KEY_CODE_META_L] = 0xfc, - [Q_KEY_CODE_META_R] = 0xfd, - [Q_KEY_CODE_COMPOSE ] =0xfe , -#endif -#endif [Q_KEY_CODE_MAX] = 0, };
Signature · 1 line
1.8.3.1
PATCH v2 9/10 input: sparc32 kbd: fix some key mappings
In reply to Gerd Hoffmann--- hw/char/escc.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-)
hw/char/escc.c +16 -14
@@ -790,7 +790,7 @@ static const uint8_t qcode_to_keycode[Q_KEY_CODE_MAX] = { [Q_KEY_CODE_F10] = 7, [Q_KEY_CODE_NUM_LOCK] = 98, [Q_KEY_CODE_SCROLL_LOCK] = 23, - [Q_KEY_CODE_KP_DIVIDE] = 109, + [Q_KEY_CODE_KP_DIVIDE] = 46, [Q_KEY_CODE_KP_MULTIPLY] = 47, [Q_KEY_CODE_KP_SUBTRACT] = 71, [Q_KEY_CODE_KP_ADD] = 125,
@@ -809,31 +809,33 @@ static const uint8_t qcode_to_keycode[Q_KEY_CODE_MAX] = { [Q_KEY_CODE_LESS] = 124, [Q_KEY_CODE_F11] = 9, [Q_KEY_CODE_F12] = 11, - [Q_KEY_CODE_HOME] = 68, - [Q_KEY_CODE_PGUP] = 70, - [Q_KEY_CODE_PGDN] = 114, - [Q_KEY_CODE_END] = 112, - [Q_KEY_CODE_LEFT] = 91, - [Q_KEY_CODE_UP] = 69, - [Q_KEY_CODE_DOWN] = 113, - [Q_KEY_CODE_RIGHT] = 93, - [Q_KEY_CODE_INSERT] = 94, - [Q_KEY_CODE_DELETE] = 50, + [Q_KEY_CODE_HOME] = 52, + [Q_KEY_CODE_PGUP] = 96, + [Q_KEY_CODE_PGDN] = 123, + [Q_KEY_CODE_END] = 74, + [Q_KEY_CODE_LEFT] = 24, + [Q_KEY_CODE_UP] = 20, + [Q_KEY_CODE_DOWN] = 27, + [Q_KEY_CODE_RIGHT] = 28, + [Q_KEY_CODE_INSERT] = 44, + [Q_KEY_CODE_DELETE] = 66, [Q_KEY_CODE_STOP] = 1, [Q_KEY_CODE_AGAIN] = 3, [Q_KEY_CODE_PROPS] = 25, [Q_KEY_CODE_UNDO] = 26, [Q_KEY_CODE_FRONT] = 49, - [Q_KEY_CODE_COPY] = 52, + [Q_KEY_CODE_COPY] = 51, [Q_KEY_CODE_OPEN] = 72, [Q_KEY_CODE_PASTE] = 73, - [Q_KEY_CODE_FIND] = 97, - [Q_KEY_CODE_CUT] = 99, + [Q_KEY_CODE_FIND] = 95, + [Q_KEY_CODE_CUT] = 97, [Q_KEY_CODE_LF] = 111, [Q_KEY_CODE_HELP] = 118, [Q_KEY_CODE_META_L] = 120, [Q_KEY_CODE_META_R] = 122, [Q_KEY_CODE_COMPOSE] = 67, + [Q_KEY_CODE_PRINT] = 22, + [Q_KEY_CODE_SYSRQ] = 21, }; static void sunkbd_handle_event(DeviceState *dev, QemuConsole *src,
Signature · 1 line
1.8.3.1
PATCH v2 10/10 input: sparc32 kbd: claim en-us layout
In reply to Gerd Hoffmann--- hw/char/escc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
hw/char/escc.c +1 -1
@@ -912,7 +912,7 @@ static void handle_kbd_command(ChannelState *s, int val)case 0xf :clear_queue (s);put_queue (s,0xfe ); -put_queue (s,0 );// XXX, layout? +put_queue (s,0x21 );/* en-us layout */ break ;default :break ;
Signature · 1 line
1.8.3.1