Commit 455204eb1a0880a5e4474acf07d4641f51123a1d
1 parent
6f30fa85
Dynamic handling of guest mice, by Lonnie Mendez.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2290 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
9 changed files
with
176 additions
and
19 deletions
hw/adb.c
@@ -406,5 +406,5 @@ void adb_mouse_init(ADBBusState *bus) | @@ -406,5 +406,5 @@ void adb_mouse_init(ADBBusState *bus) | ||
406 | d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request, | 406 | d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request, |
407 | adb_mouse_reset, s); | 407 | adb_mouse_reset, s); |
408 | adb_mouse_reset(d); | 408 | adb_mouse_reset(d); |
409 | - qemu_add_mouse_event_handler(adb_mouse_event, d, 0); | 409 | + qemu_add_mouse_event_handler(adb_mouse_event, d, 0, "QEMU ADB Mouse"); |
410 | } | 410 | } |
hw/ps2.c
@@ -560,7 +560,7 @@ void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg) | @@ -560,7 +560,7 @@ void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg) | ||
560 | s->common.update_arg = update_arg; | 560 | s->common.update_arg = update_arg; |
561 | ps2_reset(&s->common); | 561 | ps2_reset(&s->common); |
562 | register_savevm("ps2mouse", 0, 2, ps2_mouse_save, ps2_mouse_load, s); | 562 | register_savevm("ps2mouse", 0, 2, ps2_mouse_save, ps2_mouse_load, s); |
563 | - qemu_add_mouse_event_handler(ps2_mouse_event, s, 0); | 563 | + qemu_add_mouse_event_handler(ps2_mouse_event, s, 0, "QEMU PS/2 Mouse"); |
564 | qemu_register_reset(ps2_reset, &s->common); | 564 | qemu_register_reset(ps2_reset, &s->common); |
565 | return s; | 565 | return s; |
566 | } | 566 | } |
hw/slavio_serial.c
@@ -682,7 +682,7 @@ void slavio_serial_ms_kbd_init(int base, int irq) | @@ -682,7 +682,7 @@ void slavio_serial_ms_kbd_init(int base, int irq) | ||
682 | slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s); | 682 | slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s); |
683 | cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory); | 683 | cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory); |
684 | 684 | ||
685 | - qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0); | 685 | + qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0, "QEMU Sun Mouse"); |
686 | qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]); | 686 | qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]); |
687 | qemu_register_reset(slavio_serial_reset, s); | 687 | qemu_register_reset(slavio_serial_reset, s); |
688 | slavio_serial_reset(s); | 688 | slavio_serial_reset(s); |
hw/usb-hid.c
@@ -39,6 +39,7 @@ typedef struct USBMouseState { | @@ -39,6 +39,7 @@ typedef struct USBMouseState { | ||
39 | int x, y; | 39 | int x, y; |
40 | int kind; | 40 | int kind; |
41 | int mouse_grabbed; | 41 | int mouse_grabbed; |
42 | + QEMUPutMouseEntry *eh_entry; | ||
42 | } USBMouseState; | 43 | } USBMouseState; |
43 | 44 | ||
44 | /* mostly the same values as the Bochs USB Mouse device */ | 45 | /* 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) | @@ -259,7 +260,8 @@ static int usb_mouse_poll(USBMouseState *s, uint8_t *buf, int len) | ||
259 | int dx, dy, dz, b, l; | 260 | int dx, dy, dz, b, l; |
260 | 261 | ||
261 | if (!s->mouse_grabbed) { | 262 | if (!s->mouse_grabbed) { |
262 | - qemu_add_mouse_event_handler(usb_mouse_event, s, 0); | 263 | + s->eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, s, |
264 | + 0, "QEMU USB Mouse"); | ||
263 | s->mouse_grabbed = 1; | 265 | s->mouse_grabbed = 1; |
264 | } | 266 | } |
265 | 267 | ||
@@ -295,7 +297,8 @@ static int usb_tablet_poll(USBMouseState *s, uint8_t *buf, int len) | @@ -295,7 +297,8 @@ static int usb_tablet_poll(USBMouseState *s, uint8_t *buf, int len) | ||
295 | int dz, b, l; | 297 | int dz, b, l; |
296 | 298 | ||
297 | if (!s->mouse_grabbed) { | 299 | if (!s->mouse_grabbed) { |
298 | - qemu_add_mouse_event_handler(usb_tablet_event, s, 1); | 300 | + s->eh_entry = qemu_add_mouse_event_handler(usb_tablet_event, s, |
301 | + 1, "QEMU USB Tablet"); | ||
299 | s->mouse_grabbed = 1; | 302 | s->mouse_grabbed = 1; |
300 | } | 303 | } |
301 | 304 | ||
@@ -503,7 +506,7 @@ static void usb_mouse_handle_destroy(USBDevice *dev) | @@ -503,7 +506,7 @@ static void usb_mouse_handle_destroy(USBDevice *dev) | ||
503 | { | 506 | { |
504 | USBMouseState *s = (USBMouseState *)dev; | 507 | USBMouseState *s = (USBMouseState *)dev; |
505 | 508 | ||
506 | - qemu_add_mouse_event_handler(NULL, NULL, 0); | 509 | + qemu_remove_mouse_event_handler(s->eh_entry); |
507 | qemu_free(s); | 510 | qemu_free(s); |
508 | } | 511 | } |
509 | 512 |
monitor.c
@@ -1241,6 +1241,8 @@ static term_cmd_t term_cmds[] = { | @@ -1241,6 +1241,8 @@ static term_cmd_t term_cmds[] = { | ||
1241 | "dx dy [dz]", "send mouse move events" }, | 1241 | "dx dy [dz]", "send mouse move events" }, |
1242 | { "mouse_button", "i", do_mouse_button, | 1242 | { "mouse_button", "i", do_mouse_button, |
1243 | "state", "change mouse button state (1=L, 2=M, 4=R)" }, | 1243 | "state", "change mouse button state (1=L, 2=M, 4=R)" }, |
1244 | + { "mouse_set", "i", do_mouse_set, | ||
1245 | + "index", "set which mouse device receives events" }, | ||
1244 | #ifdef HAS_AUDIO | 1246 | #ifdef HAS_AUDIO |
1245 | { "wavcapture", "si?i?i?", do_wav_capture, | 1247 | { "wavcapture", "si?i?i?", do_wav_capture, |
1246 | "path [frequency bits channels]", | 1248 | "path [frequency bits channels]", |
@@ -1292,6 +1294,8 @@ static term_cmd_t info_cmds[] = { | @@ -1292,6 +1294,8 @@ static term_cmd_t info_cmds[] = { | ||
1292 | "", "show capture information" }, | 1294 | "", "show capture information" }, |
1293 | { "snapshots", "", do_info_snapshots, | 1295 | { "snapshots", "", do_info_snapshots, |
1294 | "", "show the currently saved VM snapshots" }, | 1296 | "", "show the currently saved VM snapshots" }, |
1297 | + { "mice", "", do_info_mice, | ||
1298 | + "", "show which guest mouse is receiving events" }, | ||
1295 | { NULL, NULL, }, | 1299 | { NULL, NULL, }, |
1296 | }; | 1300 | }; |
1297 | 1301 |
qemu-doc.texi
@@ -781,6 +781,8 @@ show all USB host devices | @@ -781,6 +781,8 @@ show all USB host devices | ||
781 | show information about active capturing | 781 | show information about active capturing |
782 | @item info snapshots | 782 | @item info snapshots |
783 | show list of VM snapshots | 783 | show list of VM snapshots |
784 | +@item info mice | ||
785 | +show which guest mouse is receiving events | ||
784 | @end table | 786 | @end table |
785 | 787 | ||
786 | @item q or quit | 788 | @item q or quit |
@@ -795,6 +797,20 @@ Change a removable media. | @@ -795,6 +797,20 @@ Change a removable media. | ||
795 | @item screendump filename | 797 | @item screendump filename |
796 | Save screen into PPM image @var{filename}. | 798 | Save screen into PPM image @var{filename}. |
797 | 799 | ||
800 | +@item mouse_move dx dy [dz] | ||
801 | +Move the active mouse to the specified coordinates @var{dx} @var{dy} | ||
802 | +with optional scroll axis @var{dz}. | ||
803 | + | ||
804 | +@item mouse_button val | ||
805 | +Change the active mouse button state @var{val} (1=L, 2=M, 4=R). | ||
806 | + | ||
807 | +@item mouse_set index | ||
808 | +Set which mouse device receives events at given @var{index}, index | ||
809 | +can be obtained with | ||
810 | +@example | ||
811 | +info mice | ||
812 | +@end example | ||
813 | + | ||
798 | @item wavcapture filename [frequency [bits [channels]]] | 814 | @item wavcapture filename [frequency [bits [channels]]] |
799 | Capture audio into @var{filename}. Using sample rate @var{frequency} | 815 | Capture audio into @var{filename}. Using sample rate @var{frequency} |
800 | bits per sample @var{bits} and number of channels @var{channels}. | 816 | bits per sample @var{bits} and number of channels @var{channels}. |
sdl.c
@@ -319,6 +319,7 @@ static void sdl_show_cursor(void) | @@ -319,6 +319,7 @@ static void sdl_show_cursor(void) | ||
319 | { | 319 | { |
320 | if (!kbd_mouse_is_absolute()) { | 320 | if (!kbd_mouse_is_absolute()) { |
321 | SDL_ShowCursor(1); | 321 | SDL_ShowCursor(1); |
322 | + SDL_SetCursor(sdl_cursor_normal); | ||
322 | } | 323 | } |
323 | } | 324 | } |
324 | 325 | ||
@@ -364,6 +365,9 @@ static void sdl_send_mouse_event(int dz) | @@ -364,6 +365,9 @@ static void sdl_send_mouse_event(int dz) | ||
364 | SDL_GetMouseState(&dx, &dy); | 365 | SDL_GetMouseState(&dx, &dy); |
365 | dx = dx * 0x7FFF / width; | 366 | dx = dx * 0x7FFF / width; |
366 | dy = dy * 0x7FFF / height; | 367 | dy = dy * 0x7FFF / height; |
368 | + } else if (absolute_enabled) { | ||
369 | + sdl_show_cursor(); | ||
370 | + absolute_enabled = 0; | ||
367 | } | 371 | } |
368 | 372 | ||
369 | kbd_mouse_event(dx, dy, dz, buttons); | 373 | kbd_mouse_event(dx, dy, dz, buttons); |
@@ -501,7 +505,8 @@ static void sdl_refresh(DisplayState *ds) | @@ -501,7 +505,8 @@ static void sdl_refresh(DisplayState *ds) | ||
501 | } | 505 | } |
502 | break; | 506 | break; |
503 | case SDL_MOUSEMOTION: | 507 | case SDL_MOUSEMOTION: |
504 | - if (gui_grab || kbd_mouse_is_absolute()) { | 508 | + if (gui_grab || kbd_mouse_is_absolute() || |
509 | + absolute_enabled) { | ||
505 | sdl_send_mouse_event(0); | 510 | sdl_send_mouse_event(0); |
506 | } | 511 | } |
507 | break; | 512 | break; |
vl.c
@@ -463,9 +463,8 @@ void hw_error(const char *fmt, ...) | @@ -463,9 +463,8 @@ void hw_error(const char *fmt, ...) | ||
463 | 463 | ||
464 | static QEMUPutKBDEvent *qemu_put_kbd_event; | 464 | static QEMUPutKBDEvent *qemu_put_kbd_event; |
465 | static void *qemu_put_kbd_event_opaque; | 465 | static void *qemu_put_kbd_event_opaque; |
466 | -static QEMUPutMouseEvent *qemu_put_mouse_event; | ||
467 | -static void *qemu_put_mouse_event_opaque; | ||
468 | -static int qemu_put_mouse_event_absolute; | 466 | +static QEMUPutMouseEntry *qemu_put_mouse_event_head; |
467 | +static QEMUPutMouseEntry *qemu_put_mouse_event_current; | ||
469 | 468 | ||
470 | void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque) | 469 | void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque) |
471 | { | 470 | { |
@@ -473,11 +472,68 @@ void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque) | @@ -473,11 +472,68 @@ void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque) | ||
473 | qemu_put_kbd_event = func; | 472 | qemu_put_kbd_event = func; |
474 | } | 473 | } |
475 | 474 | ||
476 | -void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute) | 475 | +QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, |
476 | + void *opaque, int absolute, | ||
477 | + const char *name) | ||
477 | { | 478 | { |
478 | - qemu_put_mouse_event_opaque = opaque; | ||
479 | - qemu_put_mouse_event = func; | ||
480 | - qemu_put_mouse_event_absolute = absolute; | 479 | + QEMUPutMouseEntry *s, *cursor; |
480 | + | ||
481 | + s = qemu_mallocz(sizeof(QEMUPutMouseEntry)); | ||
482 | + if (!s) | ||
483 | + return NULL; | ||
484 | + | ||
485 | + s->qemu_put_mouse_event = func; | ||
486 | + s->qemu_put_mouse_event_opaque = opaque; | ||
487 | + s->qemu_put_mouse_event_absolute = absolute; | ||
488 | + s->qemu_put_mouse_event_name = qemu_strdup(name); | ||
489 | + s->next = NULL; | ||
490 | + | ||
491 | + if (!qemu_put_mouse_event_head) { | ||
492 | + qemu_put_mouse_event_head = qemu_put_mouse_event_current = s; | ||
493 | + return s; | ||
494 | + } | ||
495 | + | ||
496 | + cursor = qemu_put_mouse_event_head; | ||
497 | + while (cursor->next != NULL) | ||
498 | + cursor = cursor->next; | ||
499 | + | ||
500 | + cursor->next = s; | ||
501 | + qemu_put_mouse_event_current = s; | ||
502 | + | ||
503 | + return s; | ||
504 | +} | ||
505 | + | ||
506 | +void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry) | ||
507 | +{ | ||
508 | + QEMUPutMouseEntry *prev = NULL, *cursor; | ||
509 | + | ||
510 | + if (!qemu_put_mouse_event_head || entry == NULL) | ||
511 | + return; | ||
512 | + | ||
513 | + cursor = qemu_put_mouse_event_head; | ||
514 | + while (cursor != NULL && cursor != entry) { | ||
515 | + prev = cursor; | ||
516 | + cursor = cursor->next; | ||
517 | + } | ||
518 | + | ||
519 | + if (cursor == NULL) // does not exist or list empty | ||
520 | + return; | ||
521 | + else if (prev == NULL) { // entry is head | ||
522 | + qemu_put_mouse_event_head = cursor->next; | ||
523 | + if (qemu_put_mouse_event_current == entry) | ||
524 | + qemu_put_mouse_event_current = cursor->next; | ||
525 | + qemu_free(entry->qemu_put_mouse_event_name); | ||
526 | + qemu_free(entry); | ||
527 | + return; | ||
528 | + } | ||
529 | + | ||
530 | + prev->next = entry->next; | ||
531 | + | ||
532 | + if (qemu_put_mouse_event_current == entry) | ||
533 | + qemu_put_mouse_event_current = prev; | ||
534 | + | ||
535 | + qemu_free(entry->qemu_put_mouse_event_name); | ||
536 | + qemu_free(entry); | ||
481 | } | 537 | } |
482 | 538 | ||
483 | void kbd_put_keycode(int keycode) | 539 | void kbd_put_keycode(int keycode) |
@@ -489,15 +545,72 @@ void kbd_put_keycode(int keycode) | @@ -489,15 +545,72 @@ void kbd_put_keycode(int keycode) | ||
489 | 545 | ||
490 | void kbd_mouse_event(int dx, int dy, int dz, int buttons_state) | 546 | void kbd_mouse_event(int dx, int dy, int dz, int buttons_state) |
491 | { | 547 | { |
492 | - if (qemu_put_mouse_event) { | ||
493 | - qemu_put_mouse_event(qemu_put_mouse_event_opaque, | ||
494 | - dx, dy, dz, buttons_state); | 548 | + QEMUPutMouseEvent *mouse_event; |
549 | + void *mouse_event_opaque; | ||
550 | + | ||
551 | + if (!qemu_put_mouse_event_current) { | ||
552 | + return; | ||
553 | + } | ||
554 | + | ||
555 | + mouse_event = | ||
556 | + qemu_put_mouse_event_current->qemu_put_mouse_event; | ||
557 | + mouse_event_opaque = | ||
558 | + qemu_put_mouse_event_current->qemu_put_mouse_event_opaque; | ||
559 | + | ||
560 | + if (mouse_event) { | ||
561 | + mouse_event(mouse_event_opaque, dx, dy, dz, buttons_state); | ||
495 | } | 562 | } |
496 | } | 563 | } |
497 | 564 | ||
498 | int kbd_mouse_is_absolute(void) | 565 | int kbd_mouse_is_absolute(void) |
499 | { | 566 | { |
500 | - return qemu_put_mouse_event_absolute; | 567 | + if (!qemu_put_mouse_event_current) |
568 | + return 0; | ||
569 | + | ||
570 | + return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute; | ||
571 | +} | ||
572 | + | ||
573 | +void do_info_mice(void) | ||
574 | +{ | ||
575 | + QEMUPutMouseEntry *cursor; | ||
576 | + int index = 0; | ||
577 | + | ||
578 | + if (!qemu_put_mouse_event_head) { | ||
579 | + term_printf("No mouse devices connected\n"); | ||
580 | + return; | ||
581 | + } | ||
582 | + | ||
583 | + term_printf("Mouse devices available:\n"); | ||
584 | + cursor = qemu_put_mouse_event_head; | ||
585 | + while (cursor != NULL) { | ||
586 | + term_printf("%c Mouse #%d: %s\n", | ||
587 | + (cursor == qemu_put_mouse_event_current ? '*' : ' '), | ||
588 | + index, cursor->qemu_put_mouse_event_name); | ||
589 | + index++; | ||
590 | + cursor = cursor->next; | ||
591 | + } | ||
592 | +} | ||
593 | + | ||
594 | +void do_mouse_set(int index) | ||
595 | +{ | ||
596 | + QEMUPutMouseEntry *cursor; | ||
597 | + int i = 0; | ||
598 | + | ||
599 | + if (!qemu_put_mouse_event_head) { | ||
600 | + term_printf("No mouse devices connected\n"); | ||
601 | + return; | ||
602 | + } | ||
603 | + | ||
604 | + cursor = qemu_put_mouse_event_head; | ||
605 | + while (cursor != NULL && index != i) { | ||
606 | + i++; | ||
607 | + cursor = cursor->next; | ||
608 | + } | ||
609 | + | ||
610 | + if (cursor != NULL) | ||
611 | + qemu_put_mouse_event_current = cursor; | ||
612 | + else | ||
613 | + term_printf("Mouse at given index not found\n"); | ||
501 | } | 614 | } |
502 | 615 | ||
503 | /* compute with 96 bit intermediate result: (a*b)/c */ | 616 | /* compute with 96 bit intermediate result: (a*b)/c */ |
vl.h
@@ -172,13 +172,29 @@ extern int no_quit; | @@ -172,13 +172,29 @@ extern int no_quit; | ||
172 | typedef void QEMUPutKBDEvent(void *opaque, int keycode); | 172 | typedef void QEMUPutKBDEvent(void *opaque, int keycode); |
173 | typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state); | 173 | typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state); |
174 | 174 | ||
175 | +typedef struct QEMUPutMouseEntry { | ||
176 | + QEMUPutMouseEvent *qemu_put_mouse_event; | ||
177 | + void *qemu_put_mouse_event_opaque; | ||
178 | + int qemu_put_mouse_event_absolute; | ||
179 | + char *qemu_put_mouse_event_name; | ||
180 | + | ||
181 | + /* used internally by qemu for handling mice */ | ||
182 | + struct QEMUPutMouseEntry *next; | ||
183 | +} QEMUPutMouseEntry; | ||
184 | + | ||
175 | void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque); | 185 | void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque); |
176 | -void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute); | 186 | +QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, |
187 | + void *opaque, int absolute, | ||
188 | + const char *name); | ||
189 | +void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry); | ||
177 | 190 | ||
178 | void kbd_put_keycode(int keycode); | 191 | void kbd_put_keycode(int keycode); |
179 | void kbd_mouse_event(int dx, int dy, int dz, int buttons_state); | 192 | void kbd_mouse_event(int dx, int dy, int dz, int buttons_state); |
180 | int kbd_mouse_is_absolute(void); | 193 | int kbd_mouse_is_absolute(void); |
181 | 194 | ||
195 | +void do_info_mice(void); | ||
196 | +void do_mouse_set(int index); | ||
197 | + | ||
182 | /* keysym is a unicode code except for special keys (see QEMU_KEY_xxx | 198 | /* keysym is a unicode code except for special keys (see QEMU_KEY_xxx |
183 | constants) */ | 199 | constants) */ |
184 | #define QEMU_KEY_ESC1(c) ((c) | 0xe100) | 200 | #define QEMU_KEY_ESC1(c) ((c) | 0xe100) |