lo list. The attached patch allows qemu to have several mouse handlers. The reason for this is that adding a usb mouse/tablet will override the primary mouse event handler so there needs to be a way of restoring a previous mouse input handler such as the ps/2 device on the PC system target (and/or perhaps selecting amongst the available inputs).
What this doesn't do is multiplex mouse inputs from all devices - as before only one device is actively giving input. Test case with windows xp guest. qemu -hda winxp.qcow2 -localtime -usbdevice tablet -no-acpi -kernel-kqemu (qemu) usb_del 0.1 <address of usb tablet in guest> Once the usb tablet device is removed the ps/2 input was functional again.
--- qemu/vl.c 2006-10-31 19:44:16.000000000 -0600 +++ qemu/vl.c 2006-11-24 23:07:26.000000000 -0600 @@ -451,9 +451,11 @@ 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; +#define QEMU_MAX_MICE_EVENTS 3 +static int qemu_mouse_current = -1; +static QEMUPutMouseEvent *qemu_put_mouse_event[QEMU_MAX_MICE_EVENTS]; +static void *qemu_put_mouse_event_opaque[QEMU_MAX_MICE_EVENTS]; +static int qemu_put_mouse_event_absolute[QEMU_MAX_MICE_EVENTS]; void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque) { @@ -461,11 +463,26 @@ qemu_put_kbd_event = func; } -void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute) +void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, + int absolute) { - qemu_put_mouse_event_opaque = opaque; - qemu_put_mouse_event = func; - qemu_put_mouse_event_absolute = absolute; + /* revert to previous event handler */ + if (func == NULL && + opaque == NULL) { + if (qemu_mouse_current >= 0) { + qemu_put_mouse_event[qemu_mouse_current] = NULL; + qemu_put_mouse_event_opaque[qemu_mouse_current] = NULL; + --qemu_mouse_current; + } + return; + } + + ++qemu_mouse_current; + if (qemu_mouse_current == QEMU_MAX_MICE_EVENTS) + qemu_mouse_current = QEMU_MAX_MICE_EVENTS - 1; + qemu_put_mouse_event_opaque[qemu_mouse_current] = opaque; + qemu_put_mouse_event[qemu_mouse_current] = func; + qemu_put_mouse_event_absolute[qemu_mouse_current] = absolute; } void kbd_put_keycode(int keycode) @@ -477,15 +494,25 @@ 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_func; + + if (qemu_mouse_current < 0) + return; + + mouse_event_func = qemu_put_mouse_event[qemu_mouse_current]; + + if (mouse_event_func) { + mouse_event_func(qemu_put_mouse_event_opaque[qemu_mouse_current], + dx, dy, dz, buttons_state); } } int kbd_mouse_is_absolute(void) { - return qemu_put_mouse_event_absolute; + if (qemu_mouse_current < 0) + return 0; + + return qemu_put_mouse_event_absolute[qemu_mouse_current]; } /* compute with 96 bit intermediate result: (a*b)/c */ --- qemu/sdl.c 2006-08-19 09:27:30.000000000 -0500 +++ qemu/sdl.c 2006-11-24 23:14:55.000000000 -0600 @@ -319,6 +319,7 @@ { if (!kbd_mouse_is_absolute()) { SDL_ShowCursor(1); + SDL_SetCursor(sdl_cursor_normal); } } @@ -364,6 +365,9 @@ 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); @@ -499,7 +503,8 @@ qemu_system_shutdown_request(); 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;
_______________________________________________ Qemu-devel mailing list Qemu-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/qemu-devel