]> xenbits.xensource.com Git - qemu-xen-3.3-testing.git/commitdiff
Dynamic handling of guest mice, by Lonnie Mendez.
authorths <ths>
Fri, 5 Jan 2007 16:42:13 +0000 (16:42 +0000)
committerths <ths>
Fri, 5 Jan 2007 16:42:13 +0000 (16:42 +0000)
hw/adb.c
hw/ps2.c
hw/slavio_serial.c
hw/usb-hid.c
monitor.c
qemu-doc.texi
sdl.c
vl.c
vl.h

index 8e08cb143a5afa6a795aabcaf88d4ed1b4560e6a..3f664a9c5e1a10c5560ef5363d622c5c9cbc9c04 100644 (file)
--- a/hw/adb.c
+++ b/hw/adb.c
@@ -406,5 +406,5 @@ void adb_mouse_init(ADBBusState *bus)
     d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request,
                             adb_mouse_reset, s);
     adb_mouse_reset(d);
-    qemu_add_mouse_event_handler(adb_mouse_event, d, 0);
+    qemu_add_mouse_event_handler(adb_mouse_event, d, 0, "QEMU ADB Mouse");
 }
index 8438a5e853b5a47c07100c5b71a0c1b209ef5ef5..3794c603662b2f49c9c9e723ff671b3d6d137030 100644 (file)
--- a/hw/ps2.c
+++ b/hw/ps2.c
@@ -560,7 +560,7 @@ void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
     s->common.update_arg = update_arg;
     ps2_reset(&s->common);
     register_savevm("ps2mouse", 0, 2, ps2_mouse_save, ps2_mouse_load, s);
-    qemu_add_mouse_event_handler(ps2_mouse_event, s, 0);
+    qemu_add_mouse_event_handler(ps2_mouse_event, s, 0, "QEMU PS/2 Mouse");
     qemu_register_reset(ps2_reset, &s->common);
     return s;
 }
index 404138d4b00efb608ea8063e82e32c34f8c99b8d..928ff4c9170a657000837980a0b8e25f28be422e 100644 (file)
@@ -682,7 +682,7 @@ void slavio_serial_ms_kbd_init(int base, int irq)
     slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
     cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory);
 
-    qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0);
+    qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0, "QEMU Sun Mouse");
     qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
     qemu_register_reset(slavio_serial_reset, s);
     slavio_serial_reset(s);
index 095fcb3e6c590b8fa96f5ccec5ae6a06064d7516..bde3a7c67ceba7cee940f02f14f6f32463897487 100644 (file)
@@ -39,6 +39,7 @@ typedef struct USBMouseState {
     int x, y;
     int kind;
     int mouse_grabbed;
+    QEMUPutMouseEntry *eh_entry;
 } USBMouseState;
 
 /* mostly the same values as the Bochs USB Mouse device */
@@ -259,7 +260,8 @@ static int usb_mouse_poll(USBMouseState *s, uint8_t *buf, int len)
     int dx, dy, dz, b, l;
 
     if (!s->mouse_grabbed) {
-       qemu_add_mouse_event_handler(usb_mouse_event, s, 0);
+       s->eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, s,
+                                                  0, "QEMU USB Mouse");
        s->mouse_grabbed = 1;
     }
     
@@ -295,7 +297,8 @@ static int usb_tablet_poll(USBMouseState *s, uint8_t *buf, int len)
     int dz, b, l;
 
     if (!s->mouse_grabbed) {
-       qemu_add_mouse_event_handler(usb_tablet_event, s, 1);
+       s->eh_entry = qemu_add_mouse_event_handler(usb_tablet_event, s,
+                                                  1, "QEMU USB Tablet");
        s->mouse_grabbed = 1;
     }
     
@@ -503,7 +506,7 @@ static void usb_mouse_handle_destroy(USBDevice *dev)
 {
     USBMouseState *s = (USBMouseState *)dev;
 
-    qemu_add_mouse_event_handler(NULL, NULL, 0);
+    qemu_remove_mouse_event_handler(s->eh_entry);
     qemu_free(s);
 }
 
index 127c0c5e1043e2f6cda50208dc72c0a387c8acd3..da9b49239cae55be2c8ef1e8acd0bbb1e1774b86 100644 (file)
--- a/monitor.c
+++ b/monitor.c
@@ -1241,6 +1241,8 @@ static term_cmd_t term_cmds[] = {
       "dx dy [dz]", "send mouse move events" },
     { "mouse_button", "i", do_mouse_button, 
       "state", "change mouse button state (1=L, 2=M, 4=R)" },
+    { "mouse_set", "i", do_mouse_set,
+      "index", "set which mouse device receives events" },
 #ifdef HAS_AUDIO
     { "wavcapture", "si?i?i?", do_wav_capture,
       "path [frequency bits channels]",
@@ -1292,6 +1294,8 @@ static term_cmd_t info_cmds[] = {
       "", "show capture information" },
     { "snapshots", "", do_info_snapshots,
       "", "show the currently saved VM snapshots" },
+    { "mice", "", do_info_mice,
+      "", "show which guest mouse is receiving events" },
     { NULL, NULL, },
 };
 
index 9b9df33053febad4d2445aff3b246b6b05c19fde..f76ffd003286fa523da435036297c124bcb59194 100644 (file)
@@ -781,6 +781,8 @@ show all USB host devices
 show information about active capturing
 @item info snapshots
 show list of VM snapshots
+@item info mice
+show which guest mouse is receiving events
 @end table
 
 @item q or quit
@@ -795,6 +797,20 @@ Change a removable media.
 @item screendump filename
 Save screen into PPM image @var{filename}.
 
+@item mouse_move dx dy [dz]
+Move the active mouse to the specified coordinates @var{dx} @var{dy}
+with optional scroll axis @var{dz}.
+
+@item mouse_button val
+Change the active mouse button state @var{val} (1=L, 2=M, 4=R).
+
+@item mouse_set index
+Set which mouse device receives events at given @var{index}, index
+can be obtained with
+@example
+info mice
+@end example
+
 @item wavcapture filename [frequency [bits [channels]]]
 Capture audio into @var{filename}. Using sample rate @var{frequency}
 bits per sample @var{bits} and number of channels @var{channels}.
diff --git a/sdl.c b/sdl.c
index b58e9d67949821e6a4da312f92bbf766d1b30931..5ec0f67ef95b614a492f32b814e0cefc303929f2 100644 (file)
--- a/sdl.c
+++ b/sdl.c
@@ -319,6 +319,7 @@ static void sdl_show_cursor(void)
 {
     if (!kbd_mouse_is_absolute()) {
         SDL_ShowCursor(1);
+        SDL_SetCursor(sdl_cursor_normal);
     }
 }
 
@@ -364,6 +365,9 @@ static void sdl_send_mouse_event(int dz)
        SDL_GetMouseState(&dx, &dy);
        dx = dx * 0x7FFF / width;
        dy = dy * 0x7FFF / height;
+    } else if (absolute_enabled) {
+       sdl_show_cursor();
+       absolute_enabled = 0;
     }
 
     kbd_mouse_event(dx, dy, dz, buttons);
@@ -501,7 +505,8 @@ static void sdl_refresh(DisplayState *ds)
             }
             break;
         case SDL_MOUSEMOTION:
-            if (gui_grab || kbd_mouse_is_absolute()) {
+            if (gui_grab || kbd_mouse_is_absolute() ||
+                absolute_enabled) {
                 sdl_send_mouse_event(0);
             }
             break;
diff --git a/vl.c b/vl.c
index aea96387d673eae204dda9b13070a3e8440e8cf4..5e06b0d77c86ccaa89627f5faba6caf02c937c3b 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -463,9 +463,8 @@ void hw_error(const char *fmt, ...)
 
 static QEMUPutKBDEvent *qemu_put_kbd_event;
 static void *qemu_put_kbd_event_opaque;
-static QEMUPutMouseEvent *qemu_put_mouse_event;
-static void *qemu_put_mouse_event_opaque;
-static int qemu_put_mouse_event_absolute;
+static QEMUPutMouseEntry *qemu_put_mouse_event_head;
+static QEMUPutMouseEntry *qemu_put_mouse_event_current;
 
 void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
 {
@@ -473,11 +472,68 @@ void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
     qemu_put_kbd_event = func;
 }
 
-void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute)
+QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
+                                                void *opaque, int absolute,
+                                                const char *name)
 {
-    qemu_put_mouse_event_opaque = opaque;
-    qemu_put_mouse_event = func;
-    qemu_put_mouse_event_absolute = absolute;
+    QEMUPutMouseEntry *s, *cursor;
+
+    s = qemu_mallocz(sizeof(QEMUPutMouseEntry));
+    if (!s)
+        return NULL;
+
+    s->qemu_put_mouse_event = func;
+    s->qemu_put_mouse_event_opaque = opaque;
+    s->qemu_put_mouse_event_absolute = absolute;
+    s->qemu_put_mouse_event_name = qemu_strdup(name);
+    s->next = NULL;
+
+    if (!qemu_put_mouse_event_head) {
+        qemu_put_mouse_event_head = qemu_put_mouse_event_current = s;
+        return s;
+    }
+
+    cursor = qemu_put_mouse_event_head;
+    while (cursor->next != NULL)
+        cursor = cursor->next;
+
+    cursor->next = s;
+    qemu_put_mouse_event_current = s;
+
+    return s;
+}
+
+void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
+{
+    QEMUPutMouseEntry *prev = NULL, *cursor;
+
+    if (!qemu_put_mouse_event_head || entry == NULL)
+        return;
+
+    cursor = qemu_put_mouse_event_head;
+    while (cursor != NULL && cursor != entry) {
+        prev = cursor;
+        cursor = cursor->next;
+    }
+
+    if (cursor == NULL) // does not exist or list empty
+        return;
+    else if (prev == NULL) { // entry is head
+        qemu_put_mouse_event_head = cursor->next;
+        if (qemu_put_mouse_event_current == entry)
+            qemu_put_mouse_event_current = cursor->next;
+        qemu_free(entry->qemu_put_mouse_event_name);
+        qemu_free(entry);
+        return;
+    }
+
+    prev->next = entry->next;
+
+    if (qemu_put_mouse_event_current == entry)
+        qemu_put_mouse_event_current = prev;
+
+    qemu_free(entry->qemu_put_mouse_event_name);
+    qemu_free(entry);
 }
 
 void kbd_put_keycode(int keycode)
@@ -489,15 +545,72 @@ void kbd_put_keycode(int keycode)
 
 void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
 {
-    if (qemu_put_mouse_event) {
-        qemu_put_mouse_event(qemu_put_mouse_event_opaque, 
-                             dx, dy, dz, buttons_state);
+    QEMUPutMouseEvent *mouse_event;
+    void *mouse_event_opaque;
+
+    if (!qemu_put_mouse_event_current) {
+        return;
+    }
+
+    mouse_event =
+        qemu_put_mouse_event_current->qemu_put_mouse_event;
+    mouse_event_opaque =
+        qemu_put_mouse_event_current->qemu_put_mouse_event_opaque;
+
+    if (mouse_event) {
+        mouse_event(mouse_event_opaque, dx, dy, dz, buttons_state);
     }
 }
 
 int kbd_mouse_is_absolute(void)
 {
-    return qemu_put_mouse_event_absolute;
+    if (!qemu_put_mouse_event_current)
+        return 0;
+
+    return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute;
+}
+
+void do_info_mice(void)
+{
+    QEMUPutMouseEntry *cursor;
+    int index = 0;
+
+    if (!qemu_put_mouse_event_head) {
+        term_printf("No mouse devices connected\n");
+        return;
+    }
+
+    term_printf("Mouse devices available:\n");
+    cursor = qemu_put_mouse_event_head;
+    while (cursor != NULL) {
+        term_printf("%c Mouse #%d: %s\n",
+                    (cursor == qemu_put_mouse_event_current ? '*' : ' '),
+                    index, cursor->qemu_put_mouse_event_name);
+        index++;
+        cursor = cursor->next;
+    }
+}
+
+void do_mouse_set(int index)
+{
+    QEMUPutMouseEntry *cursor;
+    int i = 0;
+
+    if (!qemu_put_mouse_event_head) {
+        term_printf("No mouse devices connected\n");
+        return;
+    }
+
+    cursor = qemu_put_mouse_event_head;
+    while (cursor != NULL && index != i) {
+        i++;
+        cursor = cursor->next;
+    }
+
+    if (cursor != NULL)
+        qemu_put_mouse_event_current = cursor;
+    else
+        term_printf("Mouse at given index not found\n");
 }
 
 /* compute with 96 bit intermediate result: (a*b)/c */
diff --git a/vl.h b/vl.h
index 6d0e7a7694fa74b5b35075e97e6eff0c027d3466..5561a27c990724d57a7b1d5ef4ec397c1dd0be06 100644 (file)
--- a/vl.h
+++ b/vl.h
@@ -172,13 +172,29 @@ extern int no_quit;
 typedef void QEMUPutKBDEvent(void *opaque, int keycode);
 typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state);
 
+typedef struct QEMUPutMouseEntry {
+    QEMUPutMouseEvent *qemu_put_mouse_event;
+    void *qemu_put_mouse_event_opaque;
+    int qemu_put_mouse_event_absolute;
+    char *qemu_put_mouse_event_name;
+
+    /* used internally by qemu for handling mice */
+    struct QEMUPutMouseEntry *next;
+} QEMUPutMouseEntry;
+
 void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
-void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute);
+QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
+                                                void *opaque, int absolute,
+                                                const char *name);
+void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry);
 
 void kbd_put_keycode(int keycode);
 void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
 int kbd_mouse_is_absolute(void);
 
+void do_info_mice(void);
+void do_mouse_set(int index);
+
 /* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
    constants) */
 #define QEMU_KEY_ESC1(c) ((c) | 0xe100)