* [Qemu-devel] [PATCH] mouse click simple queue @ 2008-01-28 11:48 Stefano Stabellini 2008-01-28 11:59 ` Stefano Stabellini 2008-01-28 12:24 ` Ronan Keryell 0 siblings, 2 replies; 5+ messages in thread From: Stefano Stabellini @ 2008-01-28 11:48 UTC (permalink / raw) To: qemu-devel [-- Attachment #1: Type: text/plain, Size: 292 bytes --] 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 [-- Attachment #2: mouseclick-queue.patch --] [-- Type: text/x-patch, Size: 4342 bytes --] 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; > ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH] mouse click simple queue 2008-01-28 11:48 [Qemu-devel] [PATCH] mouse click simple queue Stefano Stabellini @ 2008-01-28 11:59 ` Stefano Stabellini 2008-01-28 12:24 ` Ronan Keryell 1 sibling, 0 replies; 5+ messages in thread From: Stefano Stabellini @ 2008-01-28 11:59 UTC (permalink / raw) To: qemu-devel [-- Attachment #1: Type: text/plain, Size: 428 bytes --] Sorry for the format of the patch, this time I have generated it using diff -uNp. Stefano Stabellini wrote: > 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 > [-- Attachment #2: mouseclick-queue.patch --] [-- Type: text/x-patch, Size: 6970 bytes --] 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; ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH] mouse click simple queue 2008-01-28 11:48 [Qemu-devel] [PATCH] mouse click simple queue Stefano Stabellini 2008-01-28 11:59 ` Stefano Stabellini @ 2008-01-28 12:24 ` Ronan Keryell 2008-01-28 12:31 ` Samuel Thibault 1 sibling, 1 reply; 5+ messages in thread From: Ronan Keryell @ 2008-01-28 12:24 UTC (permalink / raw) To: qemu-devel >>>>> On Mon, 28 Jan 2008 11:48:00 +0000, Stefano Stabellini <stefano.stabellini@citrix.com> said: Stefano> Hi all, qemu doesn't enqueue mouse events, just records the Stefano> latest mouse state. This can cause some lost mouse double Stefano> clicks if the events are not processed fast enought. I am Stefano> attaching a patch that implements a simple queue for left Stefano> mouse click events. Good point! :-) But is it possible to use higher-level queue constructions rather than inlining the queue behaviour in the code? Because it will be hard to maintain if everybody introduces her own queue, list or whatever structure each time it is needed... It reminds me the MINIX source code, quite hard to modify because of this kind of stuff... :-) Thank you! -- Ronan KERYELL |\/ Tel: (+33|0) 2.29.00.14.15 Département Informatique |/) Fax: (+33|0) 2.29.00.12.82 TÉLÉCOM Bretagne, CS 83818 K GSM: (+33|0) 6.13.14.37.66 F-29238 PLOUZANÉ CEDEX 3 |\ E-mail: rk@enstb.org FRANCE | \ http://enstb.org/~keryell ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH] mouse click simple queue 2008-01-28 12:24 ` Ronan Keryell @ 2008-01-28 12:31 ` Samuel Thibault 2008-01-28 15:08 ` Stefano Stabellini 0 siblings, 1 reply; 5+ messages in thread From: Samuel Thibault @ 2008-01-28 12:31 UTC (permalink / raw) To: qemu-devel Ronan Keryell, le Mon 28 Jan 2008 13:24:27 +0100, a écrit : > But is it possible to use higher-level queue constructions rather than > inlining the queue behaviour in the code? There is QEMUFIFO code in console.c which could be shared for instance, yes. Samuel ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH] mouse click simple queue 2008-01-28 12:31 ` Samuel Thibault @ 2008-01-28 15:08 ` Stefano Stabellini 0 siblings, 0 replies; 5+ messages in thread From: Stefano Stabellini @ 2008-01-28 15:08 UTC (permalink / raw) To: qemu-devel Samuel Thibault wrote: > Ronan Keryell, le Mon 28 Jan 2008 13:24:27 +0100, a écrit : >> But is it possible to use higher-level queue constructions rather than >> inlining the queue behaviour in the code? > > There is QEMUFIFO code in console.c which could be shared for instance, > yes. > QEMUFIFO cannot be used directly for the mouse click queue. What can be done is writing a generic queue library independent from the type of the elements. Then we could use the library wherever needed. If you think that it is a good idea I'll post a patch that implements this kind of library. ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2008-01-28 15:09 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-01-28 11:48 [Qemu-devel] [PATCH] mouse click simple queue Stefano Stabellini 2008-01-28 11:59 ` Stefano Stabellini 2008-01-28 12:24 ` Ronan Keryell 2008-01-28 12:31 ` Samuel Thibault 2008-01-28 15:08 ` Stefano Stabellini
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).