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 (was: Gentlemen we have absolute movement! was:Absolute USB-HID device musings (was Re: VNC Terminal Server))
Date: Sun, 09 Apr 2006 22:40:06 -0500	[thread overview]
Message-ID: <4439D396.6010006@us.ibm.com> (raw)
In-Reply-To: <4439954C.1050609@wasp.net.au>

[-- Attachment #1: Type: text/plain, Size: 3502 bytes --]

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
>   


[-- Attachment #2: qemu-usb-tablet.diff --]
[-- Type: text/plain, Size: 16563 bytes --]

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) */

  reply	other threads:[~2006-04-10  3:40 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                             ` Anthony Liguori [this message]
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
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=4439D396.6010006@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).