qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH] SDL mouse events smoothness


From: Samuel Thibault
Subject: [Qemu-devel] [PATCH] SDL mouse events smoothness
Date: Tue, 26 Feb 2008 12:51:18 +0000
User-agent: Mutt/1.5.12-2006-07-14

Hello,

I was having a look at the mouse events that the guest receives, and was
surprised to get

pos x:452 y:220 z:0                                                             
pos x:452 y:220 z:0                                                             
pos x:452 y:220 z:0                                                             
pos x:452 y:220 z:0                                                             
pos x:452 y:220 z:0                                                             
pos x:430 y:304 z:0                                                             
pos x:430 y:304 z:0                                                             
pos x:430 y:304 z:0                                                             
pos x:430 y:304 z:0                                                             
pos x:430 y:304 z:0                                                             
pos x:430 y:304 z:0                                                             
pos x:430 y:304 z:0                                                             
pos x:430 y:304 z:0                                                             
pos x:430 y:304 z:0                                                             
pos x:350 y:344 z:0                                                             
pos x:350 y:344 z:0                                                             
pos x:350 y:344 z:0      

i.e. the guest receives the same position several times.  This revealed
to be because sdl.c uses SDL_GetRelativeMouseState() instead of just
using the value from the event, and thus when several X11 events are
processed in one execution of sdl_refresh(), the intermediate positions
are not taken into account.  I asked on the SDL mailing list, and they
answered that qemu should indeed not use SDL_GetRelativeMouseState(),
since that only provides the latest mouse position, not the position at
the time of the event.  The patch below fixes this, and now I am getting

pos x:401 y:457 z:0                                                             
pos x:393 y:461 z:0                                                             
pos x:387 y:465 z:0                                                             
pos x:384 y:465 z:0                                                             
pos x:378 y:469 z:0                                                             
pos x:378 y:470 z:0                                                             
pos x:379 y:472 z:0                                                             
pos x:387 y:478 z:0                                                             
pos x:385 y:494 z:0                                                             
pos x:381 y:512 z:0        

which provides a much more smooth feedback of the mouse cursor.  It also
permits accessibility features such as mouse trail to work much better.
It also fixes some of the double-clic issues noticed when the machine is
sluggish (since it now always uses the button state at the time of the
event, not the current button state).

Samuel

Index: sdl.c
===================================================================
RCS file: /sources/qemu/qemu/sdl.c,v
retrieving revision 1.45
diff -u -p -r1.45 sdl.c
--- sdl.c       17 Nov 2007 17:14:38 -0000      1.45
+++ sdl.c       26 Feb 2008 12:24:33 -0000
@@ -276,8 +276,6 @@ static void sdl_grab_start(void)
     } else
         sdl_hide_cursor();
     SDL_WM_GrabInput(SDL_GRAB_ON);
-    /* dummy read to avoid moving the mouse */
-    SDL_GetRelativeMouseState(NULL, NULL);
     gui_grab = 1;
     sdl_update_caption();
 }
@@ -290,10 +288,9 @@ static void sdl_grab_end(void)
     sdl_update_caption();
 }
 
-static void sdl_send_mouse_event(int dz)
+static void sdl_send_mouse_event(int dx, int dy, int dz, int x, int y, int 
state)
 {
-    int dx, dy, state, buttons;
-    state = SDL_GetRelativeMouseState(&dx, &dy);
+    int buttons;
     buttons = 0;
     if (state & SDL_BUTTON(SDL_BUTTON_LEFT))
         buttons |= MOUSE_EVENT_LBUTTON;
@@ -311,18 +308,18 @@ static void sdl_send_mouse_event(int dz)
            absolute_enabled = 1;
        }
 
-       SDL_GetMouseState(&dx, &dy);
-       dx = dx * 0x7FFF / width;
-       dy = dy * 0x7FFF / height;
+       dx = x * 0x7FFF / width;
+       dy = y * 0x7FFF / height;
     } else if (absolute_enabled) {
        sdl_show_cursor();
        absolute_enabled = 0;
     } else if (guest_cursor) {
-        SDL_GetMouseState(&dx, &dy);
-        dx -= guest_x;
-        dy -= guest_y;
-        guest_x += dx;
-        guest_y += dy;
+        x -= guest_x;
+        y -= guest_y;
+        guest_x += x;
+        guest_y += y;
+        dx = x;
+        dy = y;
     }
 
     kbd_mouse_event(dx, dy, dz, buttons);
@@ -347,6 +344,7 @@ static void sdl_refresh(DisplayState *ds
 {
     SDL_Event ev1, *ev = &ev1;
     int mod_state;
+    int buttonstate = SDL_GetMouseState(NULL, NULL);
 
     if (last_vm_running != vm_running) {
         last_vm_running = vm_running;
@@ -474,7 +472,8 @@ static void sdl_refresh(DisplayState *ds
         case SDL_MOUSEMOTION:
             if (gui_grab || kbd_mouse_is_absolute() ||
                 absolute_enabled) {
-                sdl_send_mouse_event(0);
+                sdl_send_mouse_event(ev->motion.xrel, ev->motion.yrel, 0,
+                       ev->motion.x, ev->motion.y, ev->motion.state);
             }
             break;
         case SDL_MOUSEBUTTONDOWN:
@@ -483,13 +482,18 @@ static void sdl_refresh(DisplayState *ds
                 SDL_MouseButtonEvent *bev = &ev->button;
                 if (!gui_grab && !kbd_mouse_is_absolute()) {
                     if (ev->type == SDL_MOUSEBUTTONDOWN &&
-                        (bev->state & SDL_BUTTON_LMASK)) {
+                        (bev->button == SDL_BUTTON_LEFT)) {
                         /* start grabbing all events */
                         sdl_grab_start();
                     }
                 } else {
                     int dz;
                     dz = 0;
+                    if (ev->type == SDL_MOUSEBUTTONDOWN) {
+                        buttonstate |= SDL_BUTTON(bev->button);
+                    } else {
+                        buttonstate &= ~SDL_BUTTON(bev->button);
+                    }
 #ifdef SDL_BUTTON_WHEELUP
                     if (bev->button == SDL_BUTTON_WHEELUP && ev->type == 
SDL_MOUSEBUTTONDOWN) {
                         dz = -1;
@@ -497,7 +501,7 @@ static void sdl_refresh(DisplayState *ds
                         dz = 1;
                     }
 #endif
-                    sdl_send_mouse_event(dz);
+                    sdl_send_mouse_event(0, 0, dz, bev->x, bev->y, 
buttonstate);
                 }
             }
             break;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]