aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-02-11 09:57:38 +0000
committerKeir Fraser <keir.fraser@citrix.com>2008-02-11 09:57:38 +0000
commit0c55a3582f09bea5aa3761012bff7c897d1d3d88 (patch)
tree964e6cb2b132ffc8a66b91c5432b2ed539f643cc /tools
parente1b02119e639a9e13f79c99d145bf8a3c535593a (diff)
downloadxen-0c55a3582f09bea5aa3761012bff7c897d1d3d88.tar.gz
xen-0c55a3582f09bea5aa3761012bff7c897d1d3d88.tar.bz2
xen-0c55a3582f09bea5aa3761012bff7c897d1d3d88.zip
qemu: Queue mouse clicks.
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. This patch implements a simple queue for left mouse click events. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/ioemu/hw/usb-hid.c68
-rw-r--r--tools/ioemu/sdl.c29
2 files changed, 82 insertions, 15 deletions
diff --git a/tools/ioemu/hw/usb-hid.c b/tools/ioemu/hw/usb-hid.c
index e947977313..78b48b8dbb 100644
--- a/tools/ioemu/hw/usb-hid.c
+++ b/tools/ioemu/hw/usb-hid.c
@@ -224,15 +224,37 @@ static const uint8_t qemu_tablet_hid_report_descriptor[] = {
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 *opaque,
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(USBDevice *dev, USBPacket *p)
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 @@ int usb_mouse_load(QEMUFile *f, void *opaque, int version_id)
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_tablet_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 --git a/tools/ioemu/sdl.c b/tools/ioemu/sdl.c
index 4d6d73a6a1..d2af24752b 100644
--- a/tools/ioemu/sdl.c
+++ b/tools/ioemu/sdl.c
@@ -259,11 +259,9 @@ 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))
@@ -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_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()) {
@@ -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;