diff -r e6cf98edf0c5 tools/ioemu/hw/usb-hid.c --- a/tools/ioemu/hw/usb-hid.c Thu Feb 07 13:21:38 2008 +0000 +++ b/tools/ioemu/hw/usb-hid.c Fri Feb 08 10:36:17 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 e6cf98edf0c5 tools/ioemu/sdl.c --- a/tools/ioemu/sdl.c Thu Feb 07 13:21:38 2008 +0000 +++ b/tools/ioemu/sdl.c Fri Feb 08 11:42:05 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;