* [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).