From: "Leonardo E. Reiter" <lreiter@win4lin.com>
To: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] USB Tablet Emulation
Date: Mon, 10 Apr 2006 10:58:44 -0400 [thread overview]
Message-ID: <443A72A4.4090608@win4lin.com> (raw)
In-Reply-To: <4439D396.6010006@us.ibm.com>
Anthony,
your patch works perfectly, even with Windows XP as well. The
transition from the boot-time PS/2 mouse is perfect, and the way the
cursor grab logic is handled is seamless. I haven't been able to test
the scroll wheel because I have some hardware restrictions today (laptop
only for a while)... does that still work as well?
I also tested it as a normal X11 application on top of an Xvnc server,
and that works great, even with -full-screen set.
Thank you,
Leo Reiter
Anthony Liguori wrote:
> I spent some time cleaning this all up. The following integrates Brad's
> patches and the patch from
> http://gnome.dnsalias.net/patches/qemu-hidmousexp.patch
>
> It adds a new emulated USB device that reports absolute coordinates. It
> also modifies SDL to operate in grabless mode when an absolute input
> device is enabled. I think it's pretty close to apply-able. To use,
> just specify: -usbdevice tablet
>
> With Xorg from CVS, the evdev driver segfaults. This is apparently
> expected behavior. Hopefully it will be fixed soon. It works quite
> nicely under Win2k.
>
> Regards,
>
> Anthony Liguori
>
> Brad Campbell wrote:
>
>> Anthony Liguori wrote:
>>
>>>
>>> Final one of the night. This patch disables relative mouse reporting
>>> and disables grab automatically the first time SDL detects that the
>>> absolute mouse was enabled. Needs a lot of cleanup but I'm very
>>> happy with the user experience on this one.
>>>
>>
>> Wish I'd just gone to bed now..
>> Heres a patch against your last one to implement wheel support.
>>
>> Brad
>> ------------------------------------------------------------------------
>>
>> diff -ur qemu-clean/hw/usb-hid.c qemu/hw/usb-hid.c
>> --- qemu-clean/hw/usb-hid.c 2006-04-10 02:57:46.000000000 +0400
>> +++ qemu/hw/usb-hid.c 2006-04-10 03:11:58.000000000 +0400
>> @@ -101,7 +101,7 @@
>> 0x00, /* u8 country_code */
>> 0x01, /* u8 num_descriptors */
>> 0x22, /* u8 type; Report */
>> - 53, 0, /* u16 len */
>> + 65, 0, /* u16 len */
>>
>> /* one endpoint (status change endpoint) */
>> 0x07, /* u8 ep_bLength; */
>> @@ -145,14 +145,15 @@
>> 0x09, 0x31, /* Usage Y */
>> 0x15, 0x00, /* Logical Minimum 0 */
>> 0x27, 0xFF, 0xFF, 0x00, 0x00, /* Logical Maximum 0xffff */
>> - 0x75, 0x10, /* Report Size 32 */
>> + 0x75, 0x10, /* Report Size 16 */
>> 0x95, 0x02, /* Report Count 2 */
>> 0x81, 0x02, /* Input (Data, Var, Abs) */
>> -// 0x09, 0x32, /* Usage Z */
>> -// 0x15, 0x81, /* Logical Minimum -127 */
>> -// 0x25, 0x7F, /* Logical Maximum 127 */
>> -// 0x75, 0x08, /* Report Size 8 */
>> -// 0x95, 0x01, /* Report Count 1 */
>> + 0x09, 0x38, /* Usage Wheel */
>> + 0x15, 0x81, /* Logical Minimum -127 */
>> + 0x25, 0x7F, /* Logical Maximum 127 */
>> + 0x75, 0x08, /* Report Size 8 */
>> + 0x95, 0x01, /* Report Count 1 */
>> + 0x81, 0x02, /* Input (Data, Var, Rel) */
>> 0xC0, /* End Collection */
>> 0xC0, /* End Collection */
>> };
>> @@ -224,14 +225,18 @@
>> qemu_add_mouse_event_handler(NULL, NULL);
>> absolute_mouse = 1;
>> }
>> -
>> +/*
>> dx = int_clamp(s->dx, -128, 127);
>> dy = int_clamp(s->dy, -128, 127);
>> - dz = int_clamp(s->dz, -128, 127);
>>
>> s->dx -= dx;
>> s->dy -= dy;
>> +*/
>> +
>> + dz = int_clamp(s->dz, -128, 127);
>> s->dz -= dz;
>> +/* Appears we have to invert the wheel direction */
>> + dz = 0 - dz;
>> b = 0;
>> if (s->buttons_state & MOUSE_EVENT_LBUTTON)
>> b |= 0x01;
>> @@ -245,7 +250,8 @@
>> buf[2] = s->X >> 8;
>> buf[3] = s->Y & 0xff;
>> buf[4] = s->Y >> 8;
>> - l = 5;
>> + buf[5] = dz;
>> + l = 6;
>>
>> return l;
>> }
>>
>> ------------------------------------------------------------------------
>>
>> _______________________________________________
>> Qemu-devel mailing list
>> Qemu-devel@nongnu.org
>> http://lists.nongnu.org/mailman/listinfo/qemu-devel
>>
>
>
>
> ------------------------------------------------------------------------
>
> diff -r 6a786a97b822 hw/ps2.c
> --- a/hw/ps2.c Mon Apr 10 01:47:35 2006 +0000
> +++ b/hw/ps2.c Sun Apr 9 22:34:20 2006 -0500
> @@ -560,7 +560,7 @@
> 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);
> + qemu_add_mouse_event_handler(ps2_mouse_event, s, 0);
> qemu_register_reset(ps2_reset, &s->common);
> return s;
> }
> diff -r 6a786a97b822 hw/usb-hid.c
> --- a/hw/usb-hid.c Mon Apr 10 01:47:35 2006 +0000
> +++ b/hw/usb-hid.c Sun Apr 9 22:34:20 2006 -0500
> @@ -30,9 +30,15 @@
> #define SET_IDLE 0x210a
> #define SET_PROTOCOL 0x210b
>
> +#define USB_MOUSE 1
> +#define USB_TABLET 2
> +
> typedef struct USBMouseState {
> USBDevice dev;
> int dx, dy, dz, buttons_state;
> + int x, y;
> + int kind;
> + int mouse_grabbed;
> } USBMouseState;
>
> /* mostly the same values as the Bochs USB Mouse device */
> @@ -93,14 +99,6 @@
> 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
> 0x05, /* u8 if_iInterface; */
>
> - /* one endpoint (status change endpoint) */
> - 0x07, /* u8 ep_bLength; */
> - 0x05, /* u8 ep_bDescriptorType; Endpoint */
> - 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
> - 0x03, /* u8 ep_bmAttributes; Interrupt */
> - 0x03, 0x00, /* u16 ep_wMaxPacketSize; */
> - 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
> -
> /* HID descriptor */
> 0x09, /* u8 bLength; */
> 0x21, /* u8 bDescriptorType; */
> @@ -109,6 +107,69 @@
> 0x01, /* u8 num_descriptors */
> 0x22, /* u8 type; Report */
> 50, 0, /* u16 len */
> +
> + /* one endpoint (status change endpoint) */
> + 0x07, /* u8 ep_bLength; */
> + 0x05, /* u8 ep_bDescriptorType; Endpoint */
> + 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
> + 0x03, /* u8 ep_bmAttributes; Interrupt */
> + 0x03, 0x00, /* u16 ep_wMaxPacketSize; */
> + 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
> +};
> +
> +static const uint8_t qemu_tablet_config_descriptor[] = {
> + /* one configuration */
> + 0x09, /* u8 bLength; */
> + 0x02, /* u8 bDescriptorType; Configuration */
> + 0x22, 0x00, /* u16 wTotalLength; */
> + 0x01, /* u8 bNumInterfaces; (1) */
> + 0x01, /* u8 bConfigurationValue; */
> + 0x04, /* u8 iConfiguration; */
> + 0xa0, /* u8 bmAttributes;
> + Bit 7: must be set,
> + 6: Self-powered,
> + 5: Remote wakeup,
> + 4..0: resvd */
> + 50, /* u8 MaxPower; */
> +
> + /* USB 1.1:
> + * USB 2.0, single TT organization (mandatory):
> + * one interface, protocol 0
> + *
> + * USB 2.0, multiple TT organization (optional):
> + * two interfaces, protocols 1 (like single TT)
> + * and 2 (multiple TT mode) ... config is
> + * sometimes settable
> + * NOT IMPLEMENTED
> + */
> +
> + /* one interface */
> + 0x09, /* u8 if_bLength; */
> + 0x04, /* u8 if_bDescriptorType; Interface */
> + 0x00, /* u8 if_bInterfaceNumber; */
> + 0x00, /* u8 if_bAlternateSetting; */
> + 0x01, /* u8 if_bNumEndpoints; */
> + 0x03, /* u8 if_bInterfaceClass; */
> + 0x01, /* u8 if_bInterfaceSubClass; */
> + 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
> + 0x05, /* u8 if_iInterface; */
> +
> + /* HID descriptor */
> + 0x09, /* u8 bLength; */
> + 0x21, /* u8 bDescriptorType; */
> + 0x01, 0x00, /* u16 HID_class */
> + 0x00, /* u8 country_code */
> + 0x01, /* u8 num_descriptors */
> + 0x22, /* u8 type; Report */
> + 65, 0, /* u16 len */
> +
> + /* one endpoint (status change endpoint) */
> + 0x07, /* u8 ep_bLength; */
> + 0x05, /* u8 ep_bDescriptorType; Endpoint */
> + 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
> + 0x03, /* u8 ep_bmAttributes; Interrupt */
> + 0x08, 0x00, /* u16 ep_wMaxPacketSize; */
> + 0x03, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
> };
>
> static const uint8_t qemu_mouse_hid_report_descriptor[] = {
> @@ -121,6 +182,41 @@
> 0xC0, 0xC0,
> };
>
> +static const uint8_t qemu_tablet_hid_report_descriptor[] = {
> + 0x05, 0x01, /* Usage Page Generic Desktop */
> + 0x09, 0x01, /* Usage Mouse */
> + 0xA1, 0x01, /* Collection Application */
> + 0x09, 0x01, /* Usage Pointer */
> + 0xA1, 0x00, /* Collection Physical */
> + 0x05, 0x09, /* Usage Page Button */
> + 0x19, 0x01, /* Usage Minimum Button 1 */
> + 0x29, 0x03, /* Usage Maximum Button 3 */
> + 0x15, 0x00, /* Logical Minimum 0 */
> + 0x25, 0x01, /* Logical Maximum 1 */
> + 0x95, 0x03, /* Report Count 3 */
> + 0x75, 0x01, /* Report Size 1 */
> + 0x81, 0x02, /* Input (Data, Var, Abs) */
> + 0x95, 0x01, /* Report Count 1 */
> + 0x75, 0x05, /* Report Size 5 */
> + 0x81, 0x01, /* Input (Cnst, Var, Abs) */
> + 0x05, 0x01, /* Usage Page Generic Desktop */
> + 0x09, 0x30, /* Usage X */
> + 0x09, 0x31, /* Usage Y */
> + 0x15, 0x00, /* Logical Minimum 0 */
> + 0x27, 0xFF, 0xFF, 0x00, 0x00, /* Logical Maximum 0xffff */
> + 0x75, 0x10, /* Report Size 16 */
> + 0x95, 0x02, /* Report Count 2 */
> + 0x81, 0x02, /* Input (Data, Var, Abs) */
> + 0x09, 0x38, /* Usage Wheel */
> + 0x15, 0x81, /* Logical Minimum -127 */
> + 0x25, 0x7F, /* Logical Maximum 127 */
> + 0x75, 0x08, /* Report Size 8 */
> + 0x95, 0x01, /* Report Count 1 */
> + 0x81, 0x02, /* Input (Data, Var, Rel) */
> + 0xC0, /* End Collection */
> + 0xC0, /* End Collection */
> +};
> +
> static void usb_mouse_event(void *opaque,
> int dx1, int dy1, int dz1, int buttons_state)
> {
> @@ -129,6 +225,17 @@
> s->dx += dx1;
> s->dy += dy1;
> s->dz += dz1;
> + s->buttons_state = buttons_state;
> +}
> +
> +static void usb_tablet_event(void *opaque,
> + int x, int y, int dz, int buttons_state)
> +{
> + USBMouseState *s = opaque;
> +
> + s->x = x;
> + s->y = y;
> + s->dz += dz;
> s->buttons_state = buttons_state;
> }
>
> @@ -146,6 +253,11 @@
> {
> int dx, dy, dz, b, l;
>
> + if (!s->mouse_grabbed) {
> + qemu_add_mouse_event_handler(usb_mouse_event, s, 0);
> + s->mouse_grabbed = 1;
> + }
> +
> dx = int_clamp(s->dx, -128, 127);
> dy = int_clamp(s->dy, -128, 127);
> dz = int_clamp(s->dz, -128, 127);
> @@ -173,6 +285,39 @@
> return l;
> }
>
> +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->mouse_grabbed = 1;
> + }
> +
> + dz = int_clamp(s->dz, -128, 127);
> + s->dz -= dz;
> +
> + /* Appears we have to invert the wheel direction */
> + dz = 0 - dz;
> + b = 0;
> + if (s->buttons_state & MOUSE_EVENT_LBUTTON)
> + b |= 0x01;
> + if (s->buttons_state & MOUSE_EVENT_RBUTTON)
> + b |= 0x02;
> + if (s->buttons_state & MOUSE_EVENT_MBUTTON)
> + b |= 0x04;
> +
> + buf[0] = b;
> + buf[1] = s->x & 0xff;
> + buf[2] = s->x >> 8;
> + buf[3] = s->y & 0xff;
> + buf[4] = s->y >> 8;
> + buf[5] = dz;
> + l = 6;
> +
> + return l;
> +}
> +
> static void usb_mouse_handle_reset(USBDevice *dev)
> {
> USBMouseState *s = (USBMouseState *)dev;
> @@ -180,6 +325,8 @@
> s->dx = 0;
> s->dy = 0;
> s->dz = 0;
> + s->x = 0;
> + s->y = 0;
> s->buttons_state = 0;
> }
>
> @@ -187,7 +334,7 @@
> int index, int length, uint8_t *data)
> {
> USBMouseState *s = (USBMouseState *)dev;
> - int ret;
> + int ret = 0;
>
> switch(request) {
> case DeviceRequest | USB_REQ_GET_STATUS:
> @@ -224,9 +371,15 @@
> ret = sizeof(qemu_mouse_dev_descriptor);
> break;
> case USB_DT_CONFIG:
> - memcpy(data, qemu_mouse_config_descriptor,
> - sizeof(qemu_mouse_config_descriptor));
> - ret = sizeof(qemu_mouse_config_descriptor);
> + if (s->kind == USB_MOUSE) {
> + memcpy(data, qemu_mouse_config_descriptor,
> + sizeof(qemu_mouse_config_descriptor));
> + ret = sizeof(qemu_mouse_config_descriptor);
> + } else if (s->kind == USB_TABLET) {
> + memcpy(data, qemu_tablet_config_descriptor,
> + sizeof(qemu_tablet_config_descriptor));
> + ret = sizeof(qemu_tablet_config_descriptor);
> + }
> break;
> case USB_DT_STRING:
> switch(value & 0xff) {
> @@ -244,7 +397,10 @@
> break;
> case 2:
> /* product description */
> - ret = set_usb_string(data, "QEMU USB Mouse");
> + if (s->kind == USB_MOUSE)
> + ret = set_usb_string(data, "QEMU USB Mouse");
> + else if (s->kind == USB_TABLET)
> + ret = set_usb_string(data, "QEMU USB Tablet");
> break;
> case 3:
> /* vendor description */
> @@ -282,16 +438,25 @@
> case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
> switch(value >> 8) {
> case 0x22:
> - memcpy(data, qemu_mouse_hid_report_descriptor,
> - sizeof(qemu_mouse_hid_report_descriptor));
> - ret = sizeof(qemu_mouse_hid_report_descriptor);
> - break;
> + if (s->kind == USB_MOUSE) {
> + memcpy(data, qemu_mouse_hid_report_descriptor,
> + sizeof(qemu_mouse_hid_report_descriptor));
> + ret = sizeof(qemu_mouse_hid_report_descriptor);
> + } else if (s->kind == USB_TABLET) {
> + memcpy(data, qemu_tablet_hid_report_descriptor,
> + sizeof(qemu_tablet_hid_report_descriptor));
> + ret = sizeof(qemu_tablet_hid_report_descriptor);
> + }
> + break;
> default:
> goto fail;
> }
> break;
> case GET_REPORT:
> - ret = usb_mouse_poll(s, data, length);
> + if (s->kind == USB_MOUSE)
> + ret = usb_mouse_poll(s, data, length);
> + else if (s->kind == USB_TABLET)
> + ret = usb_tablet_poll(s, data, length);
> break;
> case SET_IDLE:
> ret = 0;
> @@ -308,12 +473,15 @@
> uint8_t devep, uint8_t *data, int len)
> {
> USBMouseState *s = (USBMouseState *)dev;
> - int ret;
> + int ret = 0;
>
> switch(pid) {
> case USB_TOKEN_IN:
> if (devep == 1) {
> - ret = usb_mouse_poll(s, data, len);
> + if (s->kind == USB_MOUSE)
> + ret = usb_mouse_poll(s, data, len);
> + else if (s->kind == USB_TABLET)
> + ret = usb_tablet_poll(s, data, len);
> } else {
> goto fail;
> }
> @@ -327,7 +495,7 @@
> return ret;
> }
>
> -USBDevice *usb_mouse_init(void)
> +USBDevice *usb_tablet_init(void)
> {
> USBMouseState *s;
>
> @@ -340,8 +508,25 @@
> s->dev.handle_reset = usb_mouse_handle_reset;
> s->dev.handle_control = usb_mouse_handle_control;
> s->dev.handle_data = usb_mouse_handle_data;
> -
> - qemu_add_mouse_event_handler(usb_mouse_event, s);
> -
> + s->kind = USB_TABLET;
> +
> return (USBDevice *)s;
> }
> +
> +USBDevice *usb_mouse_init(void)
> +{
> + USBMouseState *s;
> +
> + s = qemu_mallocz(sizeof(USBMouseState));
> + if (!s)
> + return NULL;
> + s->dev.speed = USB_SPEED_FULL;
> + s->dev.handle_packet = usb_generic_handle_packet;
> +
> + s->dev.handle_reset = usb_mouse_handle_reset;
> + s->dev.handle_control = usb_mouse_handle_control;
> + s->dev.handle_data = usb_mouse_handle_data;
> + s->kind = USB_MOUSE;
> +
> + return (USBDevice *)s;
> +}
> diff -r 6a786a97b822 hw/usb.h
> --- a/hw/usb.h Mon Apr 10 01:47:35 2006 +0000
> +++ b/hw/usb.h Sun Apr 9 22:34:20 2006 -0500
> @@ -163,3 +163,4 @@
>
> /* usb-hid.c */
> USBDevice *usb_mouse_init(void);
> +USBDevice *usb_tablet_init(void);
> diff -r 6a786a97b822 sdl.c
> --- a/sdl.c Mon Apr 10 01:47:35 2006 +0000
> +++ b/sdl.c Sun Apr 9 22:34:20 2006 -0500
> @@ -39,6 +39,10 @@
> static int gui_fullscreen_initial_grab;
> static int gui_grab_code = KMOD_LALT | KMOD_LCTRL;
> static uint8_t modifiers_state[256];
> +static int width, height;
> +static SDL_Cursor *sdl_cursor_normal;
> +static SDL_Cursor *sdl_cursor_hidden;
> +static int absolute_enabled = 0;
>
> static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
> {
> @@ -55,6 +59,9 @@
> flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
> if (gui_fullscreen)
> flags |= SDL_FULLSCREEN;
> +
> + width = w;
> + height = h;
>
> again:
> screen = SDL_SetVideoMode(w, h, 0, flags);
> @@ -271,9 +278,21 @@
> SDL_WM_SetCaption(buf, "QEMU");
> }
>
> +static void sdl_hide_cursor(void)
> +{
> + SDL_SetCursor(sdl_cursor_hidden);
> +}
> +
> +static void sdl_show_cursor(void)
> +{
> + if (!kbd_mouse_is_absolute()) {
> + SDL_SetCursor(sdl_cursor_normal);
> + }
> +}
> +
> static void sdl_grab_start(void)
> {
> - SDL_ShowCursor(0);
> + sdl_hide_cursor();
> SDL_WM_GrabInput(SDL_GRAB_ON);
> /* dummy read to avoid moving the mouse */
> SDL_GetRelativeMouseState(NULL, NULL);
> @@ -284,7 +303,7 @@
> static void sdl_grab_end(void)
> {
> SDL_WM_GrabInput(SDL_GRAB_OFF);
> - SDL_ShowCursor(1);
> + sdl_show_cursor();
> gui_grab = 0;
> sdl_update_caption();
> }
> @@ -300,6 +319,21 @@
> buttons |= MOUSE_EVENT_RBUTTON;
> if (state & SDL_BUTTON(SDL_BUTTON_MIDDLE))
> buttons |= MOUSE_EVENT_MBUTTON;
> +
> + if (kbd_mouse_is_absolute()) {
> + if (!absolute_enabled) {
> + sdl_hide_cursor();
> + if (gui_grab) {
> + sdl_grab_end();
> + }
> + absolute_enabled = 1;
> + }
> +
> + SDL_GetMouseState(&dx, &dy);
> + dx = dx * 0x7FFF / width;
> + dy = dy * 0x7FFF / height;
> + }
> +
> kbd_mouse_event(dx, dy, dz, buttons);
> }
>
> @@ -423,7 +457,7 @@
> qemu_system_shutdown_request();
> break;
> case SDL_MOUSEMOTION:
> - if (gui_grab) {
> + if (gui_grab || kbd_mouse_is_absolute()) {
> sdl_send_mouse_event(0);
> }
> break;
> @@ -431,7 +465,7 @@
> case SDL_MOUSEBUTTONUP:
> {
> SDL_MouseButtonEvent *bev = &ev->button;
> - if (!gui_grab) {
> + if (!gui_grab && !kbd_mouse_is_absolute()) {
> if (ev->type == SDL_MOUSEBUTTONDOWN &&
> (bev->state & SDL_BUTTON_LMASK)) {
> /* start grabbing all events */
> @@ -471,6 +505,7 @@
> void sdl_display_init(DisplayState *ds, int full_screen)
> {
> int flags;
> + uint8_t data = 0;
>
> #if defined(__APPLE__)
> /* always use generic keymaps */
> @@ -504,6 +539,9 @@
> SDL_EnableUNICODE(1);
> gui_grab = 0;
>
> + sdl_cursor_hidden = SDL_CreateCursor(&data, &data, 8, 1, 0, 0);
> + sdl_cursor_normal = SDL_GetCursor();
> +
> atexit(sdl_cleanup);
> if (full_screen) {
> gui_fullscreen = 1;
> diff -r 6a786a97b822 vl.c
> --- a/vl.c Mon Apr 10 01:47:35 2006 +0000
> +++ b/vl.c Sun Apr 9 22:34:20 2006 -0500
> @@ -474,6 +474,7 @@
> 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;
>
> void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
> {
> @@ -481,10 +482,11 @@
> qemu_put_kbd_event = func;
> }
>
> -void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque)
> +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;
> }
>
> void kbd_put_keycode(int keycode)
> @@ -500,6 +502,11 @@
> qemu_put_mouse_event(qemu_put_mouse_event_opaque,
> dx, dy, dz, buttons_state);
> }
> +}
> +
> +int kbd_mouse_is_absolute(void)
> +{
> + return qemu_put_mouse_event_absolute;
> }
>
> /***********************************************************/
> @@ -2855,6 +2862,10 @@
> dev = usb_mouse_init();
> if (!dev)
> return -1;
> + } else if (!strcmp(devname, "tablet")) {
> + dev = usb_tablet_init();
> + if (!dev)
> + return -1;
> } else {
> return -1;
> }
> diff -r 6a786a97b822 vl.h
> --- a/vl.h Mon Apr 10 01:47:35 2006 +0000
> +++ b/vl.h Sun Apr 9 22:34:20 2006 -0500
> @@ -158,10 +158,11 @@
> typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state);
>
> void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
> -void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque);
> +void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute);
>
> 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);
>
> /* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
> constants) */
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Qemu-devel mailing list
> Qemu-devel@nongnu.org
> http://lists.nongnu.org/mailman/listinfo/qemu-devel
--
Leonardo E. Reiter
Vice President of Product Development, CTO
Win4Lin, Inc.
Virtual Computing from Desktop to Data Center
Main: +1 512 339 7979
Fax: +1 512 532 6501
http://www.win4lin.com
next prev parent reply other threads:[~2006-04-10 14:58 UTC|newest]
Thread overview: 68+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-04-08 16:20 [Qemu-devel] VNC terminal server? Samuel Hunt
2006-04-08 18:12 ` Brad Campbell
2006-04-21 15:31 ` Troy Benjegerdes
2006-04-21 15:58 ` WaxDragon
2006-04-08 18:24 ` Johannes Schindelin
2006-04-08 18:37 ` Leonardo E. Reiter
2006-04-08 19:04 ` Johannes Schindelin
2006-04-08 19:15 ` Leonardo E. Reiter
2006-04-09 2:54 ` Anthony Liguori
2006-04-08 20:19 ` Brad Campbell
2006-04-08 20:29 ` Leonardo E. Reiter
2006-04-08 21:06 ` [Qemu-devel] Absolute USB-HID device musings (was Re: VNC Terminal Server) Leonardo E. Reiter
2006-04-08 21:18 ` Leonardo E. Reiter
2006-04-08 21:22 ` Brad Campbell
2006-04-08 21:36 ` Leonardo E. Reiter
2006-04-09 4:36 ` Anthony Liguori
2006-04-09 15:14 ` Jim C. Brown
2006-04-09 16:03 ` Leonardo E. Reiter
2006-04-09 16:49 ` Brad Campbell
2006-04-09 18:07 ` andrzej zaborowski
2006-04-09 18:35 ` Brad Campbell
2006-04-09 18:41 ` Lonnie Mendez
2006-04-09 19:22 ` Brad Campbell
2006-04-09 20:27 ` [Qemu-devel] Gentlemen we have absolute movement! was:Absolute " Brad Campbell
2006-04-09 20:31 ` Anthony Liguori
2006-04-09 20:57 ` Anthony Liguori
2006-04-09 21:02 ` Brad Campbell
2006-04-09 21:10 ` Brad Campbell
2006-04-09 21:20 ` Johannes Schindelin
2006-04-09 21:35 ` Brad Campbell
2006-04-09 21:39 ` Anthony Liguori
2006-04-09 22:01 ` Brad Campbell
2006-04-09 22:08 ` Anthony Liguori
2006-04-09 22:12 ` Brad Campbell
2006-04-09 22:18 ` Brad Campbell
2006-04-09 23:14 ` Brad Campbell
2006-04-10 3:40 ` [Qemu-devel] USB Tablet Emulation (was: Gentlemen we have absolute movement! was:Absolute USB-HID device musings (was Re: VNC Terminal Server)) Anthony Liguori
2006-04-10 8:23 ` [Qemu-devel] USB Tablet Emulation Brad Campbell
2006-04-10 8:32 ` Johannes Schindelin
2006-04-10 10:27 ` Brad Campbell
2006-04-10 11:27 ` Johannes Schindelin
2006-04-19 17:18 ` [Qemu-devel] USB Tablet Emulation + VNC patch Troy Benjegerdes
2006-04-21 21:13 ` Brad Campbell
2006-04-26 0:55 ` Troy Benjegerdes
2006-04-26 7:37 ` Brad Campbell
2006-04-10 14:58 ` Leonardo E. Reiter [this message]
2006-04-10 15:27 ` [Qemu-devel] USB Tablet Emulation Anthony Liguori
2006-04-10 15:39 ` Leonardo E. Reiter
2006-04-10 16:08 ` Brad Campbell
2006-04-10 19:28 ` Brad Campbell
2006-04-10 19:44 ` Brad Campbell
2006-04-10 21:27 ` Brad Campbell
2006-04-10 21:39 ` Brad Campbell
2006-04-08 18:38 ` [Qemu-devel] VNC terminal server? Mark Williamson
2006-04-08 18:53 ` Johannes Schindelin
2006-04-08 19:01 ` Jim C. Brown
2006-04-08 19:12 ` Johannes Schindelin
2006-04-08 19:30 ` Jim C. Brown
2006-04-08 19:40 ` Johannes Schindelin
2006-04-09 2:55 ` Anthony Liguori
2006-04-09 2:53 ` Anthony Liguori
2006-04-08 19:21 ` andrzej zaborowski
2006-04-08 19:33 ` Leonardo E. Reiter
2006-04-09 2:59 ` Anthony Liguori
2006-04-09 16:06 ` Leonardo E. Reiter
2006-04-09 16:40 ` Anthony Liguori
2006-04-09 2:57 ` Anthony Liguori
2006-04-09 2:52 ` Anthony Liguori
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=443A72A4.4090608@win4lin.com \
--to=lreiter@win4lin.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).