From: Anthony Liguori <aliguori@us.ibm.com>
To: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] USB Tablet Emulation
Date: Mon, 10 Apr 2006 10:27:32 -0500 [thread overview]
Message-ID: <443A7964.7050704@us.ibm.com> (raw)
In-Reply-To: <443A72A4.4090608@win4lin.com>
Leonardo E. Reiter wrote:
> Anthony,
>
> your patch works perfectly, even with Windows XP as well.
Make sure to give credit where credit's due. Brad Campbell figured out
the hard stuff :-)
> 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 haven't tried it but Brad has. Perhaps he can comment here.
Regards,
Anthony Liguori
> 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
>
next prev parent reply other threads:[~2006-04-10 15:29 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 ` [Qemu-devel] USB Tablet Emulation Leonardo E. Reiter
2006-04-10 15:27 ` Anthony Liguori [this message]
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=443A7964.7050704@us.ibm.com \
--to=aliguori@us.ibm.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).