Here is a revamped patch:

This fixes SDL mouse events processing:
- GetRelativeMouseState() always returns the last position, so when the
  polling loop gets several mouse events in one go, we would send
  useless 'no move' events, let's avoid that.
- So as to make sure we don't miss any mouse click / double click, we
  should not use GetRelativeMouseState() to get the button state, but
  rather keep records of the button state ourselves (I've requested SDL
  developers to provide it directly in the event in SDL 1.3).
- bev->state doesn't contain the button state but whether the event is a press
  or a release. Use bev->button instead.

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       5 Mar 2008 11:53:55 -0000
@@ -290,10 +290,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 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;
@@ -347,6 +346,7 @@ static void sdl_refresh(DisplayState *ds
 {
     SDL_Event ev1, *ev = &ev1;
     int mod_state;
+    int button_state;
 
     if (last_vm_running != vm_running) {
         last_vm_running = vm_running;
@@ -355,6 +355,7 @@ static void sdl_refresh(DisplayState *ds
 
     vga_hw_update();
 
+    button_state = SDL_GetMouseState(NULL, NULL);
     while (SDL_PollEvent(ev)) {
         switch (ev->type) {
         case SDL_VIDEOEXPOSE:
@@ -474,16 +475,23 @@ 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;
+                SDL_GetRelativeMouseState(&dx, &dy);
+                if (dx || dy)
+                    sdl_send_mouse_event(dx, dy, 0, button_state);
             }
             break;
         case SDL_MOUSEBUTTONDOWN:
         case SDL_MOUSEBUTTONUP:
             {
                 SDL_MouseButtonEvent *bev = &ev->button;
+                if (ev->type == SDL_MOUSEBUTTONDOWN)
+                    button_state |= SDL_BUTTON(bev->button);
+                else
+                    button_state &= ~SDL_BUTTON(ev->button.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();
                     }
@@ -497,7 +505,7 @@ static void sdl_refresh(DisplayState *ds
                         dz = 1;
                     }
 #endif
-                    sdl_send_mouse_event(dz);
+                    sdl_send_mouse_event(0, 0, dz, button_state);
                 }
             }
             break;


Reply via email to