From 455204eb1a0880a5e4474acf07d4641f51123a1d Mon Sep 17 00:00:00 2001 From: ths Date: Fri, 5 Jan 2007 16:42:13 +0000 Subject: Dynamic handling of guest mice, by Lonnie Mendez. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2290 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/adb.c | 2 +- hw/ps2.c | 2 +- hw/slavio_serial.c | 2 +- hw/usb-hid.c | 9 ++-- monitor.c | 4 ++ qemu-doc.texi | 16 +++++++ sdl.c | 7 ++- vl.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++----- vl.h | 18 ++++++- 9 files changed, 176 insertions(+), 19 deletions(-) diff --git a/hw/adb.c b/hw/adb.c index 8e08cb143a..3f664a9c5e 100644 --- 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"); } diff --git a/hw/ps2.c b/hw/ps2.c index 8438a5e853..3794c60366 100644 --- 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; } diff --git a/hw/slavio_serial.c b/hw/slavio_serial.c index 404138d4b0..928ff4c917 100644 --- a/hw/slavio_serial.c +++ b/hw/slavio_serial.c @@ -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); diff --git a/hw/usb-hid.c b/hw/usb-hid.c index 095fcb3e6c..bde3a7c67c 100644 --- a/hw/usb-hid.c +++ b/hw/usb-hid.c @@ -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); } diff --git a/monitor.c b/monitor.c index 127c0c5e10..da9b49239c 100644 --- 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, }, }; diff --git a/qemu-doc.texi b/qemu-doc.texi index 9b9df33053..f76ffd0032 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -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 b58e9d6794..5ec0f67ef9 100644 --- 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 aea96387d6..5e06b0d77c 100644 --- 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 6d0e7a7694..5561a27c99 100644 --- 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) -- cgit v1.2.3