[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] qemu: Queue mouse clicks.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1202723858 0
# Node ID 96b418cf047e6d869740efd3660ab175303a3148
# Parent  c68ce89542c7fbba9d00fd3a7d4e190476554e55
qemu: Queue mouse clicks.

qemu doesn't enqueue mouse events, just records the latest mouse
state. This can cause some lost mouse double clicks if the events are
not processed fast enought. This patch implements a simple queue for
left mouse click events.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
---
 tools/ioemu/hw/usb-hid.c |   68 +++++++++++++++++++++++++++++++++++++++++++----
 tools/ioemu/sdl.c        |   31 +++++++++++++--------
 2 files changed, 83 insertions(+), 16 deletions(-)

diff -r c68ce89542c7 -r 96b418cf047e tools/ioemu/hw/usb-hid.c
--- a/tools/ioemu/hw/usb-hid.c  Mon Feb 11 09:47:19 2008 +0000
+++ b/tools/ioemu/hw/usb-hid.c  Mon Feb 11 09:57:38 2008 +0000
@@ -224,15 +224,37 @@ static const uint8_t qemu_tablet_hid_rep
         0xC0,       /* End Collection */
 };
 
+static int currentbutton = 0;
+typedef struct _mouseclick {
+    int button_state;
+    struct _mouseclick *next;
+} mouseclick; 
+static mouseclick mousequeue[20];
+static mouseclick *head = mousequeue;
+static mouseclick *tail = mousequeue;
+
 static void usb_mouse_event(void *opaque,
                             int dx1, int dy1, int dz1, int buttons_state)
 {
     USBMouseState *s = opaque;
+
+    if (s->status_changed == 1){
+        //A mouse event is lost
+        if (buttons_state != currentbutton && tail->next != head) {
+            //A left click event is lost: let's add it to the queue
+            //counter++;
+            tail->button_state = buttons_state;
+            tail = tail->next;
+        }
+    }
+    else {
+        s->buttons_state = buttons_state;
+    }
 
     s->dx += dx1;
     s->dy += dy1;
     s->dz += dz1;
-    s->buttons_state = buttons_state;
+    currentbutton = buttons_state;
     s->status_changed = 1;
 }
 
@@ -240,11 +262,24 @@ static void usb_tablet_event(void *opaqu
                             int x, int y, int dz, int buttons_state)
 {
     USBMouseState *s = opaque;
+    
+    if (s->status_changed == 1){
+        //A mouse event is lost
+        if (buttons_state != currentbutton && tail->next != head) {
+            //A left click event is lost: let's add it to the queue
+            //counter++;
+            tail->button_state = buttons_state;
+            tail = tail->next;
+        }
+    }
+    else {
+        s->buttons_state = buttons_state;
+    }
 
     s->x = x;
     s->y = y;
     s->dz += dz;
-    s->buttons_state = buttons_state;
+    currentbutton = buttons_state;
     s->status_changed = 1;
 }
 
@@ -493,10 +528,17 @@ static int usb_mouse_handle_data(USBDevi
             else if (s->kind == USB_TABLET)
                 ret = usb_tablet_poll(s, p->data, p->len);
 
-            if (!s->status_changed)
+            if (!s->status_changed) {
                 ret = USB_RET_NAK;
-            else
-                s->status_changed = 0;
+            } else {
+                if (head != tail) {
+                    s->buttons_state = head->button_state;
+                    head = head->next;
+                }
+                else {
+                    s->status_changed = 0;
+                }
+            }
 
         } else {
             goto fail;
@@ -567,6 +609,14 @@ USBDevice *usb_tablet_init(void)
 USBDevice *usb_tablet_init(void)
 {
     USBMouseState *s;
+    int i;
+    
+    for (i = 0; i < 19; i++) {
+        mousequeue[i].button_state = 0;
+        mousequeue[i].next = &(mousequeue[i + 1]);
+    }
+    mousequeue[i].button_state = 0;
+    mousequeue[i].next = mousequeue;
 
     s = qemu_mallocz(sizeof(USBMouseState));
     if (!s)
@@ -591,6 +641,14 @@ USBDevice *usb_mouse_init(void)
 USBDevice *usb_mouse_init(void)
 {
     USBMouseState *s;
+    int i;
+    
+    for (i = 0; i < 19; i++) {
+        mousequeue[i].button_state = 0;
+        mousequeue[i].next = &(mousequeue[i + 1]);
+    }
+    mousequeue[i].button_state = 0;
+    mousequeue[i].next = mousequeue;
 
     s = qemu_mallocz(sizeof(USBMouseState));
     if (!s)
diff -r c68ce89542c7 -r 96b418cf047e tools/ioemu/sdl.c
--- a/tools/ioemu/sdl.c Mon Feb 11 09:47:19 2008 +0000
+++ b/tools/ioemu/sdl.c Mon Feb 11 09:57:38 2008 +0000
@@ -259,11 +259,9 @@ static void sdl_grab_end(void)
     sdl_update_caption();
 }
 
-static void sdl_send_mouse_event(int dz)
-{
-    int dx, dy, state, buttons;
-    state = SDL_GetRelativeMouseState(&dx, &dy);
-    buttons = 0;
+static void sdl_send_mouse_event(int dx, int dy, int dz, int state)
+{
+    int buttons = 0;
     if (state & SDL_BUTTON(SDL_BUTTON_LEFT))
         buttons |= MOUSE_EVENT_LBUTTON;
     if (state & SDL_BUTTON(SDL_BUTTON_RIGHT))
@@ -425,11 +423,19 @@ static void sdl_refresh(DisplayState *ds
         case SDL_MOUSEMOTION:
             if (gui_grab || kbd_mouse_is_absolute() ||
                 absolute_enabled) {
-                sdl_send_mouse_event(0);
+                int dx, dy, state;
+                state = SDL_GetRelativeMouseState(&dx, &dy);
+                sdl_send_mouse_event(dx, dy, 0, state);
+            }
+            break;
+        case SDL_MOUSEBUTTONUP:
+            if (gui_grab || kbd_mouse_is_absolute()) {
+                int dx, dy, state;
+                state = SDL_GetRelativeMouseState(&dx, &dy);
+                sdl_send_mouse_event(dx, dy, 0, state);
             }
             break;
         case SDL_MOUSEBUTTONDOWN:
-        case SDL_MOUSEBUTTONUP:
             {
                 SDL_MouseButtonEvent *bev = &ev->button;
                 if (!gui_grab && !kbd_mouse_is_absolute()) {
@@ -439,16 +445,19 @@ static void sdl_refresh(DisplayState *ds
                         sdl_grab_start();
                     }
                 } else {
-                    int dz;
+                    int dx, dy, dz, state;
                     dz = 0;
+                    state = SDL_GetRelativeMouseState(&dx, &dy);
 #ifdef SDL_BUTTON_WHEELUP
-                    if (bev->button == SDL_BUTTON_WHEELUP && ev->type == 
SDL_MOUSEBUTTONDOWN) {
+                    if (bev->button == SDL_BUTTON_WHEELUP) {
                         dz = -1;
-                    } else if (bev->button == SDL_BUTTON_WHEELDOWN && ev->type 
== SDL_MOUSEBUTTONDOWN) {
+                    } else if (bev->button == SDL_BUTTON_WHEELDOWN) {
                         dz = 1;
+                    } else {
+                        state = bev->button | state;
                     }
 #endif               
-                    sdl_send_mouse_event(dz);
+                    sdl_send_mouse_event(dx, dy, dz, state);
                 }
             }
             break;

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.