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 28 Jan 2008 11:57:05 -0000 @@ -290,11 +290,10 @@ 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); - buttons = 0; + int buttons = 0; + if (state & SDL_BUTTON(SDL_BUTTON_LEFT)) buttons |= MOUSE_EVENT_LBUTTON; if (state & SDL_BUTTON(SDL_BUTTON_RIGHT)) @@ -311,7 +310,7 @@ static void sdl_send_mouse_event(int dz) absolute_enabled = 1; } - SDL_GetMouseState(&dx, &dy); + SDL_GetMouseState(&dx, &dy); dx = dx * 0x7FFF / width; dy = dy * 0x7FFF / height; } else if (absolute_enabled) { @@ -474,11 +473,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_MOUSEBUTTONDOWN: 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: { SDL_MouseButtonEvent *bev = &ev->button; if (!gui_grab && !kbd_mouse_is_absolute()) { @@ -488,16 +495,21 @@ 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; Index: hw/usb-hid.c =================================================================== RCS file: /sources/qemu/qemu/hw/usb-hid.c,v retrieving revision 1.16 diff -u -p -r1.16 usb-hid.c --- hw/usb-hid.c 14 Jan 2008 02:25:44 -0000 1.16 +++ hw/usb-hid.c 28 Jan 2008 11:57:06 -0000 @@ -384,17 +384,39 @@ static const uint8_t usb_hid_usage_keys[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +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) { USBHIDState *hs = opaque; USBMouseState *s = &hs->ptr; + if (hs->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; hs->changed = 1; + currentbutton = buttons_state; } static void usb_tablet_event(void *opaque, @@ -403,11 +425,24 @@ static void usb_tablet_event(void *opaqu USBHIDState *hs = opaque; USBMouseState *s = &hs->ptr; + if (hs->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; hs->changed = 1; + currentbutton = buttons_state; } static void usb_keyboard_event(void *opaque, int keycode) @@ -776,13 +811,26 @@ static int usb_hid_handle_data(USBDevice /* TODO: Implement finite idle delays. */ if (!(s->changed || s->idle)) return USB_RET_NAK; - s->changed = 0; + if (s->kind == USB_MOUSE) ret = usb_mouse_poll(s, p->data, p->len); else if (s->kind == USB_TABLET) ret = usb_tablet_poll(s, p->data, p->len); else if (s->kind == USB_KEYBOARD) ret = usb_keyboard_poll(&s->kbd, p->data, p->len); + + if ((s->kind == USB_MOUSE || s->kind == USB_TABLET) && s->changed) { + USBMouseState *ms = &s->ptr; + if (head != tail) { + ms->buttons_state = head->button_state; + head = head->next; + } + else { + s->changed = 0; + } + } else { + s->changed = 0; + } } else { goto fail; } @@ -808,8 +856,16 @@ static void usb_hid_handle_destroy(USBDe USBDevice *usb_tablet_init(void) { + int i; USBHIDState *s; + 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(USBHIDState)); if (!s) return NULL; @@ -831,8 +887,16 @@ USBDevice *usb_tablet_init(void) USBDevice *usb_mouse_init(void) { + int i; USBHIDState *s; + 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(USBHIDState)); if (!s) return NULL;