Hi all,
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.
I am attaching a patch that implements a simple queue for left mouse
click events.
Best Regards,
Stefano Stabellini
Index: sdl.c
===================================================================
RCS file: /sources/qemu/qemu/sdl.c,v
retrieving revision 1.45
diff -r1.45 sdl.c
293c293
< static void sdl_send_mouse_event(int dz)
---
> static void sdl_send_mouse_event(int dx, int dy, int dz, int state)
295,297c295,296
< int dx, dy, state, buttons;
< state = SDL_GetRelativeMouseState(&dx, &dy);
< buttons = 0;
---
> int buttons = 0;
>
314c313
< SDL_GetMouseState(&dx, &dy);
---
> SDL_GetMouseState(&dx, &dy);
477c476,478
< sdl_send_mouse_event(0);
---
> int dx, dy, state;
> state = SDL_GetRelativeMouseState(&dx, &dy);
> sdl_send_mouse_event(dx, dy, 0, state);
480d480
< case SDL_MOUSEBUTTONDOWN:
481a482,488
> 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:
491c498
< int dz;
---
> int dx, dy, dz, state;
492a500
> state = SDL_GetRelativeMouseState(&dx, &dy);
494c502
< if (bev->button == SDL_BUTTON_WHEELUP && ev->type == SDL_MOUSEBUTTONDOWN) {
---
> if (bev->button == SDL_BUTTON_WHEELUP) {
496c504,505
< } else if (bev->button == SDL_BUTTON_WHEELDOWN && ev->type == SDL_MOUSEBUTTONDOWN) {
---
> }
> else if (bev->button == SDL_BUTTON_WHEELDOWN) {
498a508,510
> else {
> state = bev->button | state;
> }
500c512
< sdl_send_mouse_event(dz);
---
> sdl_send_mouse_event(dx, dy, dz, state);
Index: hw/usb-hid.c
===================================================================
RCS file: /sources/qemu/qemu/hw/usb-hid.c,v
retrieving revision 1.16
diff -r1.16 usb-hid.c
386a387,395
> 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;
>
392a402,414
> 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;
> }
>
396d417
< s->buttons_state = buttons_state;
397a419
> currentbutton = buttons_state;
405a428,440
> 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;
> }
>
409d443
< s->buttons_state = buttons_state;
410a445
> currentbutton = buttons_state;
779c814
< s->changed = 0;
---
>
785a821,833
>
> 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;
> }
810a859
> int i;
812a862,868
> 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;
>
833a890
> int i;
835a893,899
> 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;
>