qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
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
>

  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).