added virtual USB mouse support
[qemu] / hw / pckbd.c
index ee83e0f..be559eb 100644 (file)
@@ -139,7 +139,6 @@ typedef struct KBDState {
 } KBDState;
 
 KBDState kbd_state;
-int reset_requested;
 
 /* update irq and KBD_STAT_[MOUSE_]OBF */
 /* XXX: not generating the irqs if KBD_MODE_DISABLE_KBD is set may be
@@ -190,9 +189,9 @@ static void kbd_queue(KBDState *s, int b, int aux)
     kbd_update_irq(s);
 }
 
-void kbd_put_keycode(int keycode)
+static void pc_kbd_put_keycode(void *opaque, int keycode)
 {
-    KBDState *s = &kbd_state;
+    KBDState *s = opaque;
     kbd_queue(s, keycode, 0);
 }
 
@@ -274,8 +273,7 @@ static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val)
         break;
 #endif
     case KBD_CCMD_RESET:
-        reset_requested = 1;
-        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
+        qemu_system_reset_request();
         break;
     case 0xff:
         /* ignore that - I don't know what is its use */
@@ -434,9 +432,10 @@ static void kbd_mouse_send_packet(KBDState *s)
     s->mouse_dz -= dz1;
 }
 
-void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
+static void pc_kbd_mouse_event(void *opaque, 
+                               int dx, int dy, int dz, int buttons_state)
 {
-    KBDState *s = &kbd_state;
+    KBDState *s = opaque;
 
     /* check if deltas are recorded when disabled */
     if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
@@ -540,6 +539,7 @@ static void kbd_write_mouse(KBDState *s, int val)
             s->mouse_sample_rate = 100;
             s->mouse_resolution = 2;
             s->mouse_status = 0;
+            s->mouse_type = 0;
             kbd_queue(s, AUX_ACK, 1);
             kbd_queue(s, 0xaa, 1);
             kbd_queue(s, s->mouse_type, 1);
@@ -550,7 +550,6 @@ static void kbd_write_mouse(KBDState *s, int val)
         break;
     case AUX_SET_SAMPLE:
         s->mouse_sample_rate = val;
-#if 0
         /* detect IMPS/2 or IMEX */
         switch(s->mouse_detect_state) {
         default:
@@ -577,7 +576,6 @@ static void kbd_write_mouse(KBDState *s, int val)
             s->mouse_detect_state = 0;
             break;
         }
-#endif
         kbd_queue(s, AUX_ACK, 1);
         s->mouse_write_cmd = -1;
         break;
@@ -616,8 +614,7 @@ void kbd_write_data(void *opaque, uint32_t addr, uint32_t val)
         cpu_x86_set_a20(cpu_single_env, (val >> 1) & 1);
 #endif
         if (!(val & 1)) {
-            reset_requested = 1;
-            cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
+            qemu_system_reset_request();
         }
         break;
     case KBD_CCMD_WRITE_MOUSE:
@@ -629,8 +626,9 @@ void kbd_write_data(void *opaque, uint32_t addr, uint32_t val)
     s->write_cmd = 0;
 }
 
-void kbd_reset(KBDState *s)
+static void kbd_reset(void *opaque)
 {
+    KBDState *s = opaque;
     KBDQueue *q;
 
     s->kbd_write_cmd = -1;
@@ -643,13 +641,65 @@ void kbd_reset(KBDState *s)
     q->count = 0;
 }
 
+static void kbd_save(QEMUFile* f, void* opaque)
+{
+    KBDState *s = (KBDState*)opaque;
+    
+    qemu_put_8s(f, &s->write_cmd);
+    qemu_put_8s(f, &s->status);
+    qemu_put_8s(f, &s->mode);
+    qemu_put_be32s(f, &s->kbd_write_cmd);
+    qemu_put_be32s(f, &s->scan_enabled);
+    qemu_put_be32s(f, &s->mouse_write_cmd);
+    qemu_put_8s(f, &s->mouse_status);
+    qemu_put_8s(f, &s->mouse_resolution);
+    qemu_put_8s(f, &s->mouse_sample_rate);
+    qemu_put_8s(f, &s->mouse_wrap);
+    qemu_put_8s(f, &s->mouse_type);
+    qemu_put_8s(f, &s->mouse_detect_state);
+    qemu_put_be32s(f, &s->mouse_dx);
+    qemu_put_be32s(f, &s->mouse_dy);
+    qemu_put_be32s(f, &s->mouse_dz);
+    qemu_put_8s(f, &s->mouse_buttons);
+}
+
+static int kbd_load(QEMUFile* f, void* opaque, int version_id)
+{
+    KBDState *s = (KBDState*)opaque;
+    
+    if (version_id != 1)
+        return -EINVAL;
+    qemu_get_8s(f, &s->write_cmd);
+    qemu_get_8s(f, &s->status);
+    qemu_get_8s(f, &s->mode);
+    qemu_get_be32s(f, &s->kbd_write_cmd);
+    qemu_get_be32s(f, &s->scan_enabled);
+    qemu_get_be32s(f, &s->mouse_write_cmd);
+    qemu_get_8s(f, &s->mouse_status);
+    qemu_get_8s(f, &s->mouse_resolution);
+    qemu_get_8s(f, &s->mouse_sample_rate);
+    qemu_get_8s(f, &s->mouse_wrap);
+    qemu_get_8s(f, &s->mouse_type);
+    qemu_get_8s(f, &s->mouse_detect_state);
+    qemu_get_be32s(f, &s->mouse_dx);
+    qemu_get_be32s(f, &s->mouse_dy);
+    qemu_get_be32s(f, &s->mouse_dz);
+    qemu_get_8s(f, &s->mouse_buttons);
+    return 0;
+}
+
 void kbd_init(void)
 {
     KBDState *s = &kbd_state;
     
     kbd_reset(s);
+    register_savevm("pckbd", 0, 1, kbd_save, kbd_load, s);
     register_ioport_read(0x60, 1, 1, kbd_read_data, s);
     register_ioport_write(0x60, 1, 1, kbd_write_data, s);
     register_ioport_read(0x64, 1, 1, kbd_read_status, s);
     register_ioport_write(0x64, 1, 1, kbd_write_command, s);
+
+    qemu_add_kbd_event_handler(pc_kbd_put_keycode, s);
+    qemu_add_mouse_event_handler(pc_kbd_mouse_event, s);
+    qemu_register_reset(kbd_reset, s);
 }