2 * QEMU PS/2 keyboard/mouse emulation
4 * Copyright (c) 2003 Fabrice Bellard
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 #include "qemu/osdep.h"
26 #include "hw/input/ps2.h"
27 #include "ui/console.h"
29 #include "sysemu/sysemu.h"
33 /* debug PC keyboard */
36 /* debug PC keyboard : only mouse */
39 /* Keyboard Commands */
40 #define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
41 #define KBD_CMD_ECHO 0xEE
42 #define KBD_CMD_SCANCODE 0xF0 /* Get/set scancode set */
43 #define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */
44 #define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
45 #define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
46 #define KBD_CMD_RESET_DISABLE 0xF5 /* reset and disable scanning */
47 #define KBD_CMD_RESET_ENABLE 0xF6 /* reset and enable scanning */
48 #define KBD_CMD_RESET 0xFF /* Reset */
50 /* Keyboard Replies */
51 #define KBD_REPLY_POR 0xAA /* Power on reset */
52 #define KBD_REPLY_ID 0xAB /* Keyboard ID */
53 #define KBD_REPLY_ACK 0xFA /* Command ACK */
54 #define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
57 #define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
58 #define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
59 #define AUX_SET_RES 0xE8 /* Set resolution */
60 #define AUX_GET_SCALE 0xE9 /* Get scaling factor */
61 #define AUX_SET_STREAM 0xEA /* Set stream mode */
62 #define AUX_POLL 0xEB /* Poll */
63 #define AUX_RESET_WRAP 0xEC /* Reset wrap mode */
64 #define AUX_SET_WRAP 0xEE /* Set wrap mode */
65 #define AUX_SET_REMOTE 0xF0 /* Set remote mode */
66 #define AUX_GET_TYPE 0xF2 /* Get type */
67 #define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
68 #define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
69 #define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
70 #define AUX_SET_DEFAULT 0xF6
71 #define AUX_RESET 0xFF /* Reset aux device */
72 #define AUX_ACK 0xFA /* Command byte ACK. */
74 #define MOUSE_STATUS_REMOTE 0x40
75 #define MOUSE_STATUS_ENABLED 0x20
76 #define MOUSE_STATUS_SCALE21 0x10
78 #define PS2_QUEUE_SIZE 16 /* Buffer size required by PS/2 protocol */
81 /* Keep the data array 256 bytes long, which compatibility
82 with older qemu versions. */
84 int rptr, wptr, count;
90 void (*update_irq)(void *, int);
97 /* QEMU uses translated PC scancodes internally. To avoid multiple
98 conversions we do the translation (if any) in the PS/2 emulation
99 not the keyboard controller. */
101 int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */
107 uint8_t mouse_status;
108 uint8_t mouse_resolution;
109 uint8_t mouse_sample_rate;
111 uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
112 uint8_t mouse_detect_state;
113 int mouse_dx; /* current values, needed for 'poll' mode */
116 uint8_t mouse_buttons;
119 /* Table to convert from PC scancodes to raw scancodes. */
120 static const unsigned char ps2_raw_keycode[128] = {
121 0, 118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85, 102, 13,
122 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
123 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
124 50, 49, 58, 65, 73, 74, 89, 124, 17, 41, 88, 5, 6, 4, 12, 3,
125 11, 2, 10, 1, 9, 119, 126, 108, 117, 125, 123, 107, 115, 116, 121, 105,
126 114, 122, 112, 113, 127, 96, 97, 120, 7, 15, 23, 31, 39, 47, 55, 63,
127 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87, 111,
128 19, 25, 57, 81, 83, 92, 95, 98, 99, 100, 101, 103, 104, 106, 109, 110
130 static const unsigned char ps2_raw_keycode_set3[128] = {
131 0, 8, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85, 102, 13,
132 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 17, 28, 27,
133 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 92, 26, 34, 33, 42,
134 50, 49, 58, 65, 73, 74, 89, 126, 25, 41, 20, 7, 15, 23, 31, 39,
135 47, 2, 63, 71, 79, 118, 95, 108, 117, 125, 132, 107, 115, 116, 124, 105,
136 114, 122, 112, 113, 127, 96, 97, 86, 94, 15, 23, 31, 39, 47, 55, 63,
137 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87, 111,
138 19, 25, 57, 81, 83, 92, 95, 98, 99, 100, 101, 103, 104, 106, 109, 110
141 void ps2_queue(void *opaque, int b)
143 PS2State *s = (PS2State *)opaque;
144 PS2Queue *q = &s->queue;
146 if (q->count >= PS2_QUEUE_SIZE - 1)
148 q->data[q->wptr] = b;
149 if (++q->wptr == PS2_QUEUE_SIZE)
152 s->update_irq(s->update_arg, 1);
156 keycode is expressed as follow:
157 bit 7 - 0 key pressed, 1 = key released
158 bits 6-0 - translated scancode set 2
160 static void ps2_put_keycode(void *opaque, int keycode)
162 PS2KbdState *s = opaque;
164 trace_ps2_put_keycode(opaque, keycode);
165 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
166 /* XXX: add support for scancode set 1 */
167 if (!s->translate && keycode < 0xe0 && s->scancode_set > 1) {
168 if (keycode & 0x80) {
169 ps2_queue(&s->common, 0xf0);
171 if (s->scancode_set == 2) {
172 keycode = ps2_raw_keycode[keycode & 0x7f];
173 } else if (s->scancode_set == 3) {
174 keycode = ps2_raw_keycode_set3[keycode & 0x7f];
177 ps2_queue(&s->common, keycode);
180 static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
183 PS2KbdState *s = (PS2KbdState *)dev;
184 int scancodes[3], i, count;
186 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
187 count = qemu_input_key_value_to_scancode(evt->u.key->key,
190 for (i = 0; i < count; i++) {
191 ps2_put_keycode(s, scancodes[i]);
195 uint32_t ps2_read_data(void *opaque)
197 PS2State *s = (PS2State *)opaque;
201 trace_ps2_read_data(opaque);
204 /* NOTE: if no data left, we return the last keyboard one
205 (needed for EMM386) */
206 /* XXX: need a timer to do things correctly */
209 index = PS2_QUEUE_SIZE - 1;
210 val = q->data[index];
212 val = q->data[q->rptr];
213 if (++q->rptr == PS2_QUEUE_SIZE)
216 /* reading deasserts IRQ */
217 s->update_irq(s->update_arg, 0);
218 /* reassert IRQs if data left */
219 s->update_irq(s->update_arg, q->count != 0);
224 static void ps2_set_ledstate(PS2KbdState *s, int ledstate)
226 trace_ps2_set_ledstate(s, ledstate);
227 s->ledstate = ledstate;
228 kbd_put_ledstate(ledstate);
231 static void ps2_reset_keyboard(PS2KbdState *s)
233 trace_ps2_reset_keyboard(s);
236 ps2_set_ledstate(s, 0);
239 void ps2_write_keyboard(void *opaque, int val)
241 PS2KbdState *s = (PS2KbdState *)opaque;
243 trace_ps2_write_keyboard(opaque, val);
244 switch(s->common.write_cmd) {
249 ps2_queue(&s->common, KBD_REPLY_ACK);
252 ps2_queue(&s->common, KBD_REPLY_RESEND);
255 ps2_queue(&s->common, KBD_REPLY_ACK);
256 /* We emulate a MF2 AT keyboard here */
257 ps2_queue(&s->common, KBD_REPLY_ID);
259 ps2_queue(&s->common, 0x41);
261 ps2_queue(&s->common, 0x83);
264 ps2_queue(&s->common, KBD_CMD_ECHO);
268 ps2_queue(&s->common, KBD_REPLY_ACK);
270 case KBD_CMD_SCANCODE:
271 case KBD_CMD_SET_LEDS:
272 case KBD_CMD_SET_RATE:
273 s->common.write_cmd = val;
274 ps2_queue(&s->common, KBD_REPLY_ACK);
276 case KBD_CMD_RESET_DISABLE:
277 ps2_reset_keyboard(s);
279 ps2_queue(&s->common, KBD_REPLY_ACK);
281 case KBD_CMD_RESET_ENABLE:
282 ps2_reset_keyboard(s);
284 ps2_queue(&s->common, KBD_REPLY_ACK);
287 ps2_reset_keyboard(s);
288 ps2_queue(&s->common, KBD_REPLY_ACK);
289 ps2_queue(&s->common, KBD_REPLY_POR);
292 ps2_queue(&s->common, KBD_REPLY_ACK);
296 case KBD_CMD_SCANCODE:
298 if (s->scancode_set == 1)
299 ps2_put_keycode(s, 0x43);
300 else if (s->scancode_set == 2)
301 ps2_put_keycode(s, 0x41);
302 else if (s->scancode_set == 3)
303 ps2_put_keycode(s, 0x3f);
305 if (val >= 1 && val <= 3)
306 s->scancode_set = val;
307 ps2_queue(&s->common, KBD_REPLY_ACK);
309 s->common.write_cmd = -1;
311 case KBD_CMD_SET_LEDS:
312 ps2_set_ledstate(s, val);
313 ps2_queue(&s->common, KBD_REPLY_ACK);
314 s->common.write_cmd = -1;
316 case KBD_CMD_SET_RATE:
317 ps2_queue(&s->common, KBD_REPLY_ACK);
318 s->common.write_cmd = -1;
323 /* Set the scancode translation mode.
325 1 = translated scancodes (used by qemu internally). */
327 void ps2_keyboard_set_translation(void *opaque, int mode)
329 PS2KbdState *s = (PS2KbdState *)opaque;
330 trace_ps2_keyboard_set_translation(opaque, mode);
334 static void ps2_mouse_send_packet(PS2MouseState *s)
342 /* XXX: increase range to 8 bits ? */
351 b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
352 ps2_queue(&s->common, b);
353 ps2_queue(&s->common, dx1 & 0xff);
354 ps2_queue(&s->common, dy1 & 0xff);
355 /* extra byte for IMPS/2 or IMEX */
356 switch(s->mouse_type) {
364 ps2_queue(&s->common, dz1 & 0xff);
371 b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
372 ps2_queue(&s->common, b);
376 trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b);
383 static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
386 static const int bmap[INPUT_BUTTON__MAX] = {
387 [INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON,
388 [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
389 [INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON,
391 PS2MouseState *s = (PS2MouseState *)dev;
393 /* check if deltas are recorded when disabled */
394 if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
398 case INPUT_EVENT_KIND_REL:
399 if (evt->u.rel->axis == INPUT_AXIS_X) {
400 s->mouse_dx += evt->u.rel->value;
401 } else if (evt->u.rel->axis == INPUT_AXIS_Y) {
402 s->mouse_dy -= evt->u.rel->value;
406 case INPUT_EVENT_KIND_BTN:
407 if (evt->u.btn->down) {
408 s->mouse_buttons |= bmap[evt->u.btn->button];
409 if (evt->u.btn->button == INPUT_BUTTON_WHEEL_UP) {
411 } else if (evt->u.btn->button == INPUT_BUTTON_WHEEL_DOWN) {
415 s->mouse_buttons &= ~bmap[evt->u.btn->button];
425 static void ps2_mouse_sync(DeviceState *dev)
427 PS2MouseState *s = (PS2MouseState *)dev;
429 if (s->mouse_buttons) {
430 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
432 if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) {
433 while (s->common.queue.count < PS2_QUEUE_SIZE - 4) {
434 /* if not remote, send event. Multiple events are sent if
436 ps2_mouse_send_packet(s);
437 if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
443 void ps2_mouse_fake_event(void *opaque)
445 PS2MouseState *s = opaque;
446 trace_ps2_mouse_fake_event(opaque);
448 ps2_mouse_sync(opaque);
451 void ps2_write_mouse(void *opaque, int val)
453 PS2MouseState *s = (PS2MouseState *)opaque;
455 trace_ps2_write_mouse(opaque, val);
457 printf("kbd: write mouse 0x%02x\n", val);
459 switch(s->common.write_cmd) {
464 if (val == AUX_RESET_WRAP) {
466 ps2_queue(&s->common, AUX_ACK);
468 } else if (val != AUX_RESET) {
469 ps2_queue(&s->common, val);
474 case AUX_SET_SCALE11:
475 s->mouse_status &= ~MOUSE_STATUS_SCALE21;
476 ps2_queue(&s->common, AUX_ACK);
478 case AUX_SET_SCALE21:
479 s->mouse_status |= MOUSE_STATUS_SCALE21;
480 ps2_queue(&s->common, AUX_ACK);
483 s->mouse_status &= ~MOUSE_STATUS_REMOTE;
484 ps2_queue(&s->common, AUX_ACK);
488 ps2_queue(&s->common, AUX_ACK);
491 s->mouse_status |= MOUSE_STATUS_REMOTE;
492 ps2_queue(&s->common, AUX_ACK);
495 ps2_queue(&s->common, AUX_ACK);
496 ps2_queue(&s->common, s->mouse_type);
500 s->common.write_cmd = val;
501 ps2_queue(&s->common, AUX_ACK);
504 ps2_queue(&s->common, AUX_ACK);
505 ps2_queue(&s->common, s->mouse_status);
506 ps2_queue(&s->common, s->mouse_resolution);
507 ps2_queue(&s->common, s->mouse_sample_rate);
510 ps2_queue(&s->common, AUX_ACK);
511 ps2_mouse_send_packet(s);
514 s->mouse_status |= MOUSE_STATUS_ENABLED;
515 ps2_queue(&s->common, AUX_ACK);
517 case AUX_DISABLE_DEV:
518 s->mouse_status &= ~MOUSE_STATUS_ENABLED;
519 ps2_queue(&s->common, AUX_ACK);
521 case AUX_SET_DEFAULT:
522 s->mouse_sample_rate = 100;
523 s->mouse_resolution = 2;
525 ps2_queue(&s->common, AUX_ACK);
528 s->mouse_sample_rate = 100;
529 s->mouse_resolution = 2;
532 ps2_queue(&s->common, AUX_ACK);
533 ps2_queue(&s->common, 0xaa);
534 ps2_queue(&s->common, s->mouse_type);
541 s->mouse_sample_rate = val;
542 /* detect IMPS/2 or IMEX */
543 switch(s->mouse_detect_state) {
547 s->mouse_detect_state = 1;
551 s->mouse_detect_state = 2;
553 s->mouse_detect_state = 3;
555 s->mouse_detect_state = 0;
559 s->mouse_type = 3; /* IMPS/2 */
560 s->mouse_detect_state = 0;
564 s->mouse_type = 4; /* IMEX */
565 s->mouse_detect_state = 0;
568 ps2_queue(&s->common, AUX_ACK);
569 s->common.write_cmd = -1;
572 s->mouse_resolution = val;
573 ps2_queue(&s->common, AUX_ACK);
574 s->common.write_cmd = -1;
579 static void ps2_common_reset(PS2State *s)
587 s->update_irq(s->update_arg, 0);
590 static void ps2_common_post_load(PS2State *s)
592 PS2Queue *q = &s->queue;
595 int tmp_data[PS2_QUEUE_SIZE];
597 /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */
598 size = q->count > PS2_QUEUE_SIZE ? 0 : q->count;
600 /* move the queue elements to the start of data array */
602 for (i = 0; i < size; i++) {
603 /* move the queue elements to the temporary buffer */
604 tmp_data[i] = q->data[q->rptr];
605 if (++q->rptr == 256) {
609 memcpy(q->data, tmp_data, size);
611 /* reset rptr/wptr/count */
615 s->update_irq(s->update_arg, q->count != 0);
618 static void ps2_kbd_reset(void *opaque)
620 PS2KbdState *s = (PS2KbdState *) opaque;
622 trace_ps2_kbd_reset(opaque);
623 ps2_common_reset(&s->common);
629 static void ps2_mouse_reset(void *opaque)
631 PS2MouseState *s = (PS2MouseState *) opaque;
633 trace_ps2_mouse_reset(opaque);
634 ps2_common_reset(&s->common);
636 s->mouse_resolution = 0;
637 s->mouse_sample_rate = 0;
640 s->mouse_detect_state = 0;
644 s->mouse_buttons = 0;
647 static const VMStateDescription vmstate_ps2_common = {
648 .name = "PS2 Common State",
650 .minimum_version_id = 2,
651 .fields = (VMStateField[]) {
652 VMSTATE_INT32(write_cmd, PS2State),
653 VMSTATE_INT32(queue.rptr, PS2State),
654 VMSTATE_INT32(queue.wptr, PS2State),
655 VMSTATE_INT32(queue.count, PS2State),
656 VMSTATE_BUFFER(queue.data, PS2State),
657 VMSTATE_END_OF_LIST()
661 static bool ps2_keyboard_ledstate_needed(void *opaque)
663 PS2KbdState *s = opaque;
665 return s->ledstate != 0; /* 0 is default state */
668 static int ps2_kbd_ledstate_post_load(void *opaque, int version_id)
670 PS2KbdState *s = opaque;
672 kbd_put_ledstate(s->ledstate);
676 static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
677 .name = "ps2kbd/ledstate",
679 .minimum_version_id = 2,
680 .post_load = ps2_kbd_ledstate_post_load,
681 .needed = ps2_keyboard_ledstate_needed,
682 .fields = (VMStateField[]) {
683 VMSTATE_INT32(ledstate, PS2KbdState),
684 VMSTATE_END_OF_LIST()
688 static int ps2_kbd_post_load(void* opaque, int version_id)
690 PS2KbdState *s = (PS2KbdState*)opaque;
691 PS2State *ps2 = &s->common;
696 ps2_common_post_load(ps2);
701 static void ps2_kbd_pre_save(void *opaque)
703 PS2KbdState *s = (PS2KbdState *)opaque;
704 PS2State *ps2 = &s->common;
706 ps2_common_post_load(ps2);
709 static const VMStateDescription vmstate_ps2_keyboard = {
712 .minimum_version_id = 2,
713 .post_load = ps2_kbd_post_load,
714 .pre_save = ps2_kbd_pre_save,
715 .fields = (VMStateField[]) {
716 VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State),
717 VMSTATE_INT32(scan_enabled, PS2KbdState),
718 VMSTATE_INT32(translate, PS2KbdState),
719 VMSTATE_INT32_V(scancode_set, PS2KbdState,3),
720 VMSTATE_END_OF_LIST()
722 .subsections = (const VMStateDescription*[]) {
723 &vmstate_ps2_keyboard_ledstate,
728 static int ps2_mouse_post_load(void *opaque, int version_id)
730 PS2MouseState *s = (PS2MouseState *)opaque;
731 PS2State *ps2 = &s->common;
733 ps2_common_post_load(ps2);
738 static void ps2_mouse_pre_save(void *opaque)
740 PS2MouseState *s = (PS2MouseState *)opaque;
741 PS2State *ps2 = &s->common;
743 ps2_common_post_load(ps2);
746 static const VMStateDescription vmstate_ps2_mouse = {
749 .minimum_version_id = 2,
750 .post_load = ps2_mouse_post_load,
751 .pre_save = ps2_mouse_pre_save,
752 .fields = (VMStateField[]) {
753 VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State),
754 VMSTATE_UINT8(mouse_status, PS2MouseState),
755 VMSTATE_UINT8(mouse_resolution, PS2MouseState),
756 VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
757 VMSTATE_UINT8(mouse_wrap, PS2MouseState),
758 VMSTATE_UINT8(mouse_type, PS2MouseState),
759 VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
760 VMSTATE_INT32(mouse_dx, PS2MouseState),
761 VMSTATE_INT32(mouse_dy, PS2MouseState),
762 VMSTATE_INT32(mouse_dz, PS2MouseState),
763 VMSTATE_UINT8(mouse_buttons, PS2MouseState),
764 VMSTATE_END_OF_LIST()
768 static QemuInputHandler ps2_keyboard_handler = {
769 .name = "QEMU PS/2 Keyboard",
770 .mask = INPUT_EVENT_MASK_KEY,
771 .event = ps2_keyboard_event,
774 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
776 PS2KbdState *s = (PS2KbdState *)g_malloc0(sizeof(PS2KbdState));
778 trace_ps2_kbd_init(s);
779 s->common.update_irq = update_irq;
780 s->common.update_arg = update_arg;
782 vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s);
783 qemu_input_handler_register((DeviceState *)s,
784 &ps2_keyboard_handler);
785 qemu_register_reset(ps2_kbd_reset, s);
789 static QemuInputHandler ps2_mouse_handler = {
790 .name = "QEMU PS/2 Mouse",
791 .mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
792 .event = ps2_mouse_event,
793 .sync = ps2_mouse_sync,
796 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
798 PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState));
800 trace_ps2_mouse_init(s);
801 s->common.update_irq = update_irq;
802 s->common.update_arg = update_arg;
803 vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
804 qemu_input_handler_register((DeviceState *)s,
806 qemu_register_reset(ps2_mouse_reset, s);