* [Qemu-devel] [PATCH RFC 0/8] monitor: Fix mouse_button and improve mouse_move commands
@ 2013-06-16 3:39 Andreas Färber
2013-06-16 3:39 ` [Qemu-devel] [PATCH RFC 1/8] ui/input: Clean up QEMUPutMouseEntry struct Andreas Färber
` (8 more replies)
0 siblings, 9 replies; 13+ messages in thread
From: Andreas Färber @ 2013-06-16 3:39 UTC (permalink / raw)
To: qemu-devel
Cc: Bernhard M. Wiedemann, xen-devel, Stephan Kulow, Brad Hards,
Peter Maydell, Stefano Stabellini, Mark Cave-Ayland,
Alexander Graf, Luiz Capitulino, Blue Swirl, qemu-ppc,
Gerd Hoffmann, Paolo Bonzini, Ludwig Nussel, Andreas Färber
Hi everyone,
Here's a new stab at fixing mouse_button HMP command with absolute coordinates,
as seen with the following devices: usb-tablet, usb-wacom-tablet, ads7846 and
depending on settings vmmouse and xenfb, as well as pre-qdev tsc2005, tsc2102,
tsc2301 touchscreens.
openQA [3] is a framework for recording input sequences and expected graphical
guest output. An absolute coordinate system is handy there. :)
When sending mouse_button command though, QEMU generates the event at
coordinates (0,0), i.e. top left corner for absolute coordinates, so that a
sequence of
(qemu) mouse_move 42 42
(qemu) mouse_button 1
may lead the guest to recognize a mouse drag from (42,42) to (0,0) rather
than a click at (42,42).
Since there can be more than one mouse (and there is for -device usb-tablet
without -no-defaults) and since there are multiple ways to interact with the
mouse beyond the monitor, using a single global state in the monitor is ugly.
We therefore need to push the event handling to ui/input.c, where the
mouse_handlers list (QEMUPutMouseEntry) is accessible.
My first attempt was to add coordinates state to QEMUPutMouseEntry, so that
we can safely switch via mouse_set between absolute and non-absolute mice.
The downside of that approach was that state at that level is not migratable,
i.e. we would still warp to (0,0) on mouse_button after migration, and it is
not being reset either.
My solution is to obtain position and buttons state from where the VMState is:
I clean up the mouse event handler registration code a bit and extend it:
* one mandatory callback to obtain mouse button state and
* one optional callback to obtain absolute position state from backends.
Since I didn't know most mice implementations, these could use some review.
* For the msmouse chardev backend I needed to persist buttons state alongside
the CharDriverState (no device) because it just wrote it to serial.
Should we turn this backend into a device to reset this state?
* It seemed that escc is not fully migration-ready (e.g., SerIOQueue and
keyboard state missing) so I did not bother to add VMSD fields or a subsection
for the fields added. Similarly it just wrote it to said SerIOQueue and
get_queue() would've destructively read from it.
* xenfb stored buttons state but not coordinates, so added them to XenInput state.
No VMStateDescription at all here.
* hid and vmmouse read the position from some queue (vmmouse also button state),
not sure how safe that is and whether we may need to add it to state directly?
Ludwig, can you test these with the openQA qemu package please? Thanks!
Regards,
Andreas
>From Brad Hards' mouse_button patch:
* Instead of adding more global monitor-only state, delegate to ui/input.c
(suggested by Gerd [1] and Paolo [2]).
But instead of keeping state just in ui/input.c:QEMUPutMouseEntry,
delegate it to the individual mouse event handlers.
* Prepend some code cleanups.
* Introduce MouseOps for callbacks (inspired by MemoryRegionOps).
* Implement MouseOps::get_position() for all absolute mice.
* Implement MouseOps::get_buttons_state() for all mice.
* Improve mouse_move while at it (suggested by Gerd to Brad [1]).
[1] http://lists.gnu.org/archive/html/qemu-devel/2011-04/msg02408.html
[2] https://bugs.launchpad.net/qemu/+bug/752476
[3] http://openqa.opensuse.org/
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Luiz Capitulino <lcapitulino@redhat.com>
Cc: Bernhard M. Wiedemann <bwiedemann@suse.de>
Cc: Ludwig Nussel <lnussel@suse.de>
Cc: Stephan Kulow <coolo@suse.de>
Cc: Brad Hards <bradh@frogmouth.net>
Cc: Blue Swirl <blauwirbel@gmail.com> (escc)
Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> (escc)
Cc: Alexander Graf <agraf@suse.de> (adb)
Cc: qemu-ppc <qemu-ppc@nongnu.org> (adb)
Cc: Andrzej Zaborowski <balrogg@gmail.com> (tsc2005, tsc210x, ads7846)
Cc: Peter Maydell <peter.maydell@linaro.org> (tsc2005, tsc210x, ads7846)
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com> (xenfb)
Cc: xen-devel <xen-devel@lists.xensource.com> (xenfb)
Andreas Färber (8):
ui/input: Clean up QEMUPutMouseEntry struct
ui/input: Simplify kbd_mouse_event()
ui/input: Use bool for qemu_add_mouse_event_handler()
ui/input: Introduce MouseOps for qemu_add_mouse_event_handler()
ui/input: Introduce MouseOps::get_buttons_state()
monitor: Eliminate global mouse buttons state for mouse_move
ui/input: Introduce MouseOps::get_position()
monitor: Fix mouse_button command for absolute coordinates
backends/msmouse.c | 29 ++++++++++++---
hw/char/escc.c | 17 ++++++++-
hw/display/ads7846.c | 25 +++++++++++--
hw/display/xenfb.c | 49 +++++++++++++++++++++++---
hw/input/adb.c | 13 ++++++-
hw/input/hid.c | 51 ++++++++++++++++++++++++---
hw/input/ps2.c | 14 +++++++-
hw/input/tsc2005.c | 25 +++++++++++--
hw/input/tsc210x.c | 29 ++++++++++++---
hw/input/vmmouse.c | 33 ++++++++++++++++--
hw/usb/dev-wacom.c | 34 +++++++++++++++---
include/ui/console.h | 27 +++++++++++---
monitor.c | 10 +++---
ui/input.c | 99 ++++++++++++++++++++++++++++++++++------------------
14 files changed, 380 insertions(+), 75 deletions(-)
--
1.8.1.4
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH RFC 1/8] ui/input: Clean up QEMUPutMouseEntry struct
2013-06-16 3:39 [Qemu-devel] [PATCH RFC 0/8] monitor: Fix mouse_button and improve mouse_move commands Andreas Färber
@ 2013-06-16 3:39 ` Andreas Färber
2013-06-17 7:17 ` Gerd Hoffmann
2013-06-16 3:39 ` [Qemu-devel] [PATCH RFC 2/8] ui/input: Simplify kbd_mouse_event() Andreas Färber
` (7 subsequent siblings)
8 siblings, 1 reply; 13+ messages in thread
From: Andreas Färber @ 2013-06-16 3:39 UTC (permalink / raw)
To: qemu-devel
Cc: Anthony Liguori, Brad Hards, Luiz Capitulino, Gerd Hoffmann,
Paolo Bonzini, Ludwig Nussel, Andreas Färber
Shorten field names to not duplicate struct name.
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
ui/input.c | 32 ++++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/ui/input.c b/ui/input.c
index 92c44ca..badf6c3 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -31,10 +31,10 @@
#include "ui/keymaps.h"
struct QEMUPutMouseEntry {
- QEMUPutMouseEvent *qemu_put_mouse_event;
- void *qemu_put_mouse_event_opaque;
- int qemu_put_mouse_event_absolute;
- char *qemu_put_mouse_event_name;
+ QEMUPutMouseEvent *put_event;
+ void *opaque;
+ int absolute;
+ char *name;
int index;
@@ -355,10 +355,10 @@ QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
s = g_malloc0(sizeof(QEMUPutMouseEntry));
- s->qemu_put_mouse_event = func;
- s->qemu_put_mouse_event_opaque = opaque;
- s->qemu_put_mouse_event_absolute = absolute;
- s->qemu_put_mouse_event_name = g_strdup(name);
+ s->put_event = func;
+ s->opaque = opaque;
+ s->absolute = absolute;
+ s->name = g_strdup(name);
s->index = mouse_index++;
QTAILQ_INSERT_TAIL(&mouse_handlers, s, node);
@@ -380,7 +380,7 @@ void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
{
QTAILQ_REMOVE(&mouse_handlers, entry, node);
- g_free(entry->qemu_put_mouse_event_name);
+ g_free(entry->name);
g_free(entry);
check_mode_change();
@@ -444,11 +444,11 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
entry = QTAILQ_FIRST(&mouse_handlers);
- mouse_event = entry->qemu_put_mouse_event;
- mouse_event_opaque = entry->qemu_put_mouse_event_opaque;
+ mouse_event = entry->put_event;
+ mouse_event_opaque = entry->opaque;
if (mouse_event) {
- if (entry->qemu_put_mouse_event_absolute) {
+ if (entry->absolute) {
width = 0x7fff;
height = 0x7fff;
} else {
@@ -483,7 +483,7 @@ int kbd_mouse_is_absolute(void)
return 0;
}
- return QTAILQ_FIRST(&mouse_handlers)->qemu_put_mouse_event_absolute;
+ return QTAILQ_FIRST(&mouse_handlers)->absolute;
}
int kbd_mouse_has_absolute(void)
@@ -491,7 +491,7 @@ int kbd_mouse_has_absolute(void)
QEMUPutMouseEntry *entry;
QTAILQ_FOREACH(entry, &mouse_handlers, node) {
- if (entry->qemu_put_mouse_event_absolute) {
+ if (entry->absolute) {
return 1;
}
}
@@ -508,9 +508,9 @@ MouseInfoList *qmp_query_mice(Error **errp)
QTAILQ_FOREACH(cursor, &mouse_handlers, node) {
MouseInfoList *info = g_malloc0(sizeof(*info));
info->value = g_malloc0(sizeof(*info->value));
- info->value->name = g_strdup(cursor->qemu_put_mouse_event_name);
+ info->value->name = g_strdup(cursor->name);
info->value->index = cursor->index;
- info->value->absolute = !!cursor->qemu_put_mouse_event_absolute;
+ info->value->absolute = !!cursor->absolute;
info->value->current = current;
current = false;
--
1.8.1.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH RFC 2/8] ui/input: Simplify kbd_mouse_event()
2013-06-16 3:39 [Qemu-devel] [PATCH RFC 0/8] monitor: Fix mouse_button and improve mouse_move commands Andreas Färber
2013-06-16 3:39 ` [Qemu-devel] [PATCH RFC 1/8] ui/input: Clean up QEMUPutMouseEntry struct Andreas Färber
@ 2013-06-16 3:39 ` Andreas Färber
2013-06-17 7:17 ` Gerd Hoffmann
2013-06-16 3:40 ` [Qemu-devel] [PATCH RFC 3/8] ui/input: Use bool for qemu_add_mouse_event_handler() Andreas Färber
` (6 subsequent siblings)
8 siblings, 1 reply; 13+ messages in thread
From: Andreas Färber @ 2013-06-16 3:39 UTC (permalink / raw)
To: qemu-devel
Cc: Anthony Liguori, Brad Hards, Luiz Capitulino, Gerd Hoffmann,
Paolo Bonzini, Ludwig Nussel, Andreas Färber
Now that the field names are bearable, there's no compelling reason to
use local variables for the fields.
Unify the four callback invokations through variables for the rotated
coordinates instead.
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
ui/input.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/ui/input.c b/ui/input.c
index badf6c3..28353b4 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -431,9 +431,8 @@ void kbd_put_ledstate(int ledstate)
void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
{
QEMUPutMouseEntry *entry;
- QEMUPutMouseEvent *mouse_event;
- void *mouse_event_opaque;
int width, height;
+ int rotated_dx, rotated_dy;
if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
return;
@@ -444,10 +443,7 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
entry = QTAILQ_FIRST(&mouse_handlers);
- mouse_event = entry->put_event;
- mouse_event_opaque = entry->opaque;
-
- if (mouse_event) {
+ if (entry->put_event) {
if (entry->absolute) {
width = 0x7fff;
height = 0x7fff;
@@ -458,22 +454,26 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
switch (graphic_rotate) {
case 0:
- mouse_event(mouse_event_opaque,
- dx, dy, dz, buttons_state);
+ rotated_dx = dx;
+ rotated_dy = dy;
break;
case 90:
- mouse_event(mouse_event_opaque,
- width - dy, dx, dz, buttons_state);
+ rotated_dx = width - dy;
+ rotated_dy = dx;
break;
case 180:
- mouse_event(mouse_event_opaque,
- width - dx, height - dy, dz, buttons_state);
+ rotated_dx = width - dx;
+ rotated_dy = height - dy;
break;
case 270:
- mouse_event(mouse_event_opaque,
- dy, height - dx, dz, buttons_state);
+ rotated_dx = dy;
+ rotated_dy = height - dx;
break;
+ default:
+ return;
}
+ entry->put_event(entry->opaque,
+ rotated_dx, rotated_dy, dz, buttons_state);
}
}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH RFC 3/8] ui/input: Use bool for qemu_add_mouse_event_handler()
2013-06-16 3:39 [Qemu-devel] [PATCH RFC 0/8] monitor: Fix mouse_button and improve mouse_move commands Andreas Färber
2013-06-16 3:39 ` [Qemu-devel] [PATCH RFC 1/8] ui/input: Clean up QEMUPutMouseEntry struct Andreas Färber
2013-06-16 3:39 ` [Qemu-devel] [PATCH RFC 2/8] ui/input: Simplify kbd_mouse_event() Andreas Färber
@ 2013-06-16 3:40 ` Andreas Färber
2013-06-16 3:40 ` [Qemu-devel] [PATCH RFC 4/8] ui/input: Introduce MouseOps " Andreas Färber
` (5 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Andreas Färber @ 2013-06-16 3:40 UTC (permalink / raw)
To: qemu-devel
Cc: Anthony Liguori, Brad Hards, Luiz Capitulino, Gerd Hoffmann,
Paolo Bonzini, Ludwig Nussel, Andreas Färber
Change kbd_mouse_{is,has}_absolute() alongside.
vmmouse uses uint8_t in its VMStateDescription, and Xen uses int in xend
communication, so they cannot easily be changed.
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
backends/msmouse.c | 3 ++-
hw/char/escc.c | 2 +-
hw/display/ads7846.c | 4 ++--
hw/input/adb.c | 2 +-
hw/input/hid.c | 10 ++++++----
hw/input/ps2.c | 2 +-
hw/input/tsc2005.c | 4 ++--
hw/input/tsc210x.c | 8 ++++----
hw/input/vmmouse.c | 2 +-
hw/usb/dev-wacom.c | 8 ++++----
include/ui/console.h | 6 +++---
ui/input.c | 14 +++++++-------
12 files changed, 34 insertions(+), 31 deletions(-)
diff --git a/backends/msmouse.c b/backends/msmouse.c
index c0dbfcd..1d24ac6 100644
--- a/backends/msmouse.c
+++ b/backends/msmouse.c
@@ -72,7 +72,8 @@ CharDriverState *qemu_chr_open_msmouse(void)
chr->chr_close = msmouse_chr_close;
chr->explicit_be_open = true;
- qemu_add_mouse_event_handler(msmouse_event, chr, 0, "QEMU Microsoft Mouse");
+ qemu_add_mouse_event_handler(msmouse_event, chr, false,
+ "QEMU Microsoft Mouse");
return chr;
}
diff --git a/hw/char/escc.c b/hw/char/escc.c
index c2cb07f..68a49cd 100644
--- a/hw/char/escc.c
+++ b/hw/char/escc.c
@@ -891,7 +891,7 @@ static int escc_init1(SysBusDevice *dev)
sysbus_init_mmio(dev, &s->mmio);
if (s->chn[0].type == mouse) {
- qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
+ qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], false,
"QEMU Sun Mouse");
}
if (s->chn[1].type == kbd) {
diff --git a/hw/display/ads7846.c b/hw/display/ads7846.c
index 5da3dc5..4a02744 100644
--- a/hw/display/ads7846.c
+++ b/hw/display/ads7846.c
@@ -145,8 +145,8 @@ static int ads7846_init(SSISlave *dev)
s->input[7] = ADS_TEMP1; /* TEMP1 */
/* We want absolute coordinates */
- qemu_add_mouse_event_handler(ads7846_ts_event, s, 1,
- "QEMU ADS7846-driven Touchscreen");
+ qemu_add_mouse_event_handler(ads7846_ts_event, s, true,
+ "QEMU ADS7846-driven Touchscreen");
ads7846_int_update(s);
diff --git a/hw/input/adb.c b/hw/input/adb.c
index a75d3fd..104bfc8 100644
--- a/hw/input/adb.c
+++ b/hw/input/adb.c
@@ -536,7 +536,7 @@ static void adb_mouse_realizefn(DeviceState *dev, Error **errp)
amc->parent_realize(dev, errp);
- qemu_add_mouse_event_handler(adb_mouse_event, s, 0, "QEMU ADB Mouse");
+ qemu_add_mouse_event_handler(adb_mouse_event, s, false, "QEMU ADB Mouse");
}
static void adb_mouse_initfn(Object *obj)
diff --git a/hw/input/hid.c b/hw/input/hid.c
index 14b3125..7a3a7a4 100644
--- a/hw/input/hid.c
+++ b/hw/input/hid.c
@@ -433,11 +433,13 @@ void hid_init(HIDState *hs, int kind, HIDEventFunc event)
if (hs->kind == HID_KEYBOARD) {
hs->kbd.eh_entry = qemu_add_kbd_event_handler(hid_keyboard_event, hs);
} else if (hs->kind == HID_MOUSE) {
- hs->ptr.eh_entry = qemu_add_mouse_event_handler(hid_pointer_event, hs,
- 0, "QEMU HID Mouse");
+ hs->ptr.eh_entry = qemu_add_mouse_event_handler(hid_pointer_event,
+ hs, false,
+ "QEMU HID Mouse");
} else if (hs->kind == HID_TABLET) {
- hs->ptr.eh_entry = qemu_add_mouse_event_handler(hid_pointer_event, hs,
- 1, "QEMU HID Tablet");
+ hs->ptr.eh_entry = qemu_add_mouse_event_handler(hid_pointer_event,
+ hs, true,
+ "QEMU HID Tablet");
}
}
diff --git a/hw/input/ps2.c b/hw/input/ps2.c
index 3412079..e555f74 100644
--- a/hw/input/ps2.c
+++ b/hw/input/ps2.c
@@ -670,7 +670,7 @@ void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
s->common.update_irq = update_irq;
s->common.update_arg = update_arg;
vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
- qemu_add_mouse_event_handler(ps2_mouse_event, s, 0, "QEMU PS/2 Mouse");
+ qemu_add_mouse_event_handler(ps2_mouse_event, s, false, "QEMU PS/2 Mouse");
qemu_register_reset(ps2_mouse_reset, s);
return s;
}
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
index a771cd5..b0d9263 100644
--- a/hw/input/tsc2005.c
+++ b/hw/input/tsc2005.c
@@ -544,8 +544,8 @@ void *tsc2005_init(qemu_irq pintdav)
tsc2005_reset(s);
- qemu_add_mouse_event_handler(tsc2005_touchscreen_event, s, 1,
- "QEMU TSC2005-driven Touchscreen");
+ qemu_add_mouse_event_handler(tsc2005_touchscreen_event, s, true,
+ "QEMU TSC2005-driven Touchscreen");
qemu_register_reset((void *) tsc2005_reset, s);
register_savevm(NULL, "tsc2005", -1, 0, tsc2005_save, tsc2005_load, s);
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
index 9b854e7..02d3440 100644
--- a/hw/input/tsc210x.c
+++ b/hw/input/tsc210x.c
@@ -1137,8 +1137,8 @@ uWireSlave *tsc2102_init(qemu_irq pint)
tsc210x_reset(s);
- qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1,
- "QEMU TSC2102-driven Touchscreen");
+ qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, true,
+ "QEMU TSC2102-driven Touchscreen");
AUD_register_card(s->name, &s->card);
@@ -1188,8 +1188,8 @@ uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav)
tsc210x_reset(s);
- qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1,
- "QEMU TSC2301-driven Touchscreen");
+ qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, true,
+ "QEMU TSC2301-driven Touchscreen");
AUD_register_card(s->name, &s->card);
diff --git a/hw/input/vmmouse.c b/hw/input/vmmouse.c
index a610738..2b2ea88 100644
--- a/hw/input/vmmouse.c
+++ b/hw/input/vmmouse.c
@@ -114,7 +114,7 @@ static void vmmouse_remove_handler(VMMouseState *s)
}
}
-static void vmmouse_update_handler(VMMouseState *s, int absolute)
+static void vmmouse_update_handler(VMMouseState *s, uint8_t absolute)
{
if (s->status != 0) {
return;
diff --git a/hw/usb/dev-wacom.c b/hw/usb/dev-wacom.c
index 3be5cde..78563ff 100644
--- a/hw/usb/dev-wacom.c
+++ b/hw/usb/dev-wacom.c
@@ -170,8 +170,8 @@ static int usb_mouse_poll(USBWacomState *s, uint8_t *buf, int len)
int dx, dy, dz, b, l;
if (!s->mouse_grabbed) {
- s->eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, s, 0,
- "QEMU PenPartner tablet");
+ s->eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, s, false,
+ "QEMU PenPartner tablet");
qemu_activate_mouse_event_handler(s->eh_entry);
s->mouse_grabbed = 1;
}
@@ -208,8 +208,8 @@ static int usb_wacom_poll(USBWacomState *s, uint8_t *buf, int len)
int b;
if (!s->mouse_grabbed) {
- s->eh_entry = qemu_add_mouse_event_handler(usb_wacom_event, s, 1,
- "QEMU PenPartner tablet");
+ s->eh_entry = qemu_add_mouse_event_handler(usb_wacom_event, s, true,
+ "QEMU PenPartner tablet");
qemu_activate_mouse_event_handler(s->eh_entry);
s->mouse_grabbed = 1;
}
diff --git a/include/ui/console.h b/include/ui/console.h
index f1d79f9..e25879f 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -37,7 +37,7 @@ QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
void *opaque);
void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry);
QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
- void *opaque, int absolute,
+ void *opaque, bool absolute,
const char *name);
void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry);
void qemu_activate_mouse_event_handler(QEMUPutMouseEntry *entry);
@@ -50,12 +50,12 @@ void kbd_put_ledstate(int ledstate);
void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
/* Does the current mouse generate absolute events */
-int kbd_mouse_is_absolute(void);
+bool kbd_mouse_is_absolute(void);
void qemu_add_mouse_mode_change_notifier(Notifier *notify);
void qemu_remove_mouse_mode_change_notifier(Notifier *notify);
/* Of all the mice, is there one that generates absolute events */
-int kbd_mouse_has_absolute(void);
+bool kbd_mouse_has_absolute(void);
struct MouseTransformInfo {
/* Touchscreen resolution */
diff --git a/ui/input.c b/ui/input.c
index 28353b4..76ded94 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -33,7 +33,7 @@
struct QEMUPutMouseEntry {
QEMUPutMouseEvent *put_event;
void *opaque;
- int absolute;
+ bool absolute;
char *name;
int index;
@@ -347,7 +347,7 @@ static void check_mode_change(void)
}
QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
- void *opaque, int absolute,
+ void *opaque, bool absolute,
const char *name)
{
QEMUPutMouseEntry *s;
@@ -477,7 +477,7 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
}
}
-int kbd_mouse_is_absolute(void)
+bool kbd_mouse_is_absolute(void)
{
if (QTAILQ_EMPTY(&mouse_handlers)) {
return 0;
@@ -486,17 +486,17 @@ int kbd_mouse_is_absolute(void)
return QTAILQ_FIRST(&mouse_handlers)->absolute;
}
-int kbd_mouse_has_absolute(void)
+bool kbd_mouse_has_absolute(void)
{
QEMUPutMouseEntry *entry;
QTAILQ_FOREACH(entry, &mouse_handlers, node) {
if (entry->absolute) {
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
MouseInfoList *qmp_query_mice(Error **errp)
@@ -510,7 +510,7 @@ MouseInfoList *qmp_query_mice(Error **errp)
info->value = g_malloc0(sizeof(*info->value));
info->value->name = g_strdup(cursor->name);
info->value->index = cursor->index;
- info->value->absolute = !!cursor->absolute;
+ info->value->absolute = cursor->absolute;
info->value->current = current;
current = false;
--
1.8.1.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH RFC 4/8] ui/input: Introduce MouseOps for qemu_add_mouse_event_handler()
2013-06-16 3:39 [Qemu-devel] [PATCH RFC 0/8] monitor: Fix mouse_button and improve mouse_move commands Andreas Färber
` (2 preceding siblings ...)
2013-06-16 3:40 ` [Qemu-devel] [PATCH RFC 3/8] ui/input: Use bool for qemu_add_mouse_event_handler() Andreas Färber
@ 2013-06-16 3:40 ` Andreas Färber
2013-06-17 7:20 ` Gerd Hoffmann
2013-06-16 3:40 ` [Qemu-devel] [PATCH RFC 5/8] ui/input: Introduce MouseOps::get_buttons_state() Andreas Färber
` (4 subsequent siblings)
8 siblings, 1 reply; 13+ messages in thread
From: Andreas Färber @ 2013-06-16 3:40 UTC (permalink / raw)
To: qemu-devel
Cc: Anthony Liguori, Brad Hards, Luiz Capitulino, Gerd Hoffmann,
Paolo Bonzini, Ludwig Nussel, Andreas Färber
This allows to add callbacks to mouse event handlers without constantly
touching all callers of qemu_add_mouse_event_handler() or
qemu_add_mouse_event_handler() itself.
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
backends/msmouse.c | 6 +++++-
hw/char/escc.c | 6 +++++-
hw/display/ads7846.c | 6 +++++-
hw/display/xenfb.c | 6 +++++-
hw/input/adb.c | 6 +++++-
hw/input/hid.c | 8 ++++++--
hw/input/ps2.c | 6 +++++-
hw/input/tsc2005.c | 6 +++++-
hw/input/tsc210x.c | 8 ++++++--
hw/input/vmmouse.c | 6 +++++-
hw/usb/dev-wacom.c | 12 ++++++++++--
include/ui/console.h | 13 +++++++++++--
ui/input.c | 12 ++++++------
13 files changed, 79 insertions(+), 22 deletions(-)
diff --git a/backends/msmouse.c b/backends/msmouse.c
index 1d24ac6..035b7b4 100644
--- a/backends/msmouse.c
+++ b/backends/msmouse.c
@@ -63,6 +63,10 @@ static void msmouse_chr_close (struct CharDriverState *chr)
g_free (chr);
}
+static const MouseOps msmouse_mouse_ops = {
+ .put_event = msmouse_event,
+};
+
CharDriverState *qemu_chr_open_msmouse(void)
{
CharDriverState *chr;
@@ -72,7 +76,7 @@ CharDriverState *qemu_chr_open_msmouse(void)
chr->chr_close = msmouse_chr_close;
chr->explicit_be_open = true;
- qemu_add_mouse_event_handler(msmouse_event, chr, false,
+ qemu_add_mouse_event_handler(&msmouse_mouse_ops, chr, false,
"QEMU Microsoft Mouse");
return chr;
diff --git a/hw/char/escc.c b/hw/char/escc.c
index 68a49cd..f6592cb 100644
--- a/hw/char/escc.c
+++ b/hw/char/escc.c
@@ -867,6 +867,10 @@ void slavio_serial_ms_kbd_init(hwaddr base, qemu_irq irq,
sysbus_mmio_map(s, 0, base);
}
+static const MouseOps sunmouse_mouse_ops = {
+ .put_event = sunmouse_event,
+};
+
static int escc_init1(SysBusDevice *dev)
{
SerialState *s = FROM_SYSBUS(SerialState, dev);
@@ -891,7 +895,7 @@ static int escc_init1(SysBusDevice *dev)
sysbus_init_mmio(dev, &s->mmio);
if (s->chn[0].type == mouse) {
- qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], false,
+ qemu_add_mouse_event_handler(&sunmouse_mouse_ops, &s->chn[0], false,
"QEMU Sun Mouse");
}
if (s->chn[1].type == kbd) {
diff --git a/hw/display/ads7846.c b/hw/display/ads7846.c
index 4a02744..9026d97 100644
--- a/hw/display/ads7846.c
+++ b/hw/display/ads7846.c
@@ -133,6 +133,10 @@ static const VMStateDescription vmstate_ads7846 = {
}
};
+static const MouseOps ads7846_ts_ops = {
+ .put_event = ads7846_ts_event,
+};
+
static int ads7846_init(SSISlave *dev)
{
ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, dev);
@@ -145,7 +149,7 @@ static int ads7846_init(SSISlave *dev)
s->input[7] = ADS_TEMP1; /* TEMP1 */
/* We want absolute coordinates */
- qemu_add_mouse_event_handler(ads7846_ts_event, s, true,
+ qemu_add_mouse_event_handler(&ads7846_ts_ops, s, true,
"QEMU ADS7846-driven Touchscreen");
ads7846_int_update(s);
diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c
index f0333a0..14dac45 100644
--- a/hw/display/xenfb.c
+++ b/hw/display/xenfb.c
@@ -366,6 +366,10 @@ static int input_initialise(struct XenDevice *xendev)
return 0;
}
+static const MouseOps xenfb_mouse_ops = {
+ .put_event = xenfb_mouse_event,
+};
+
static void input_connected(struct XenDevice *xendev)
{
struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);
@@ -378,7 +382,7 @@ static void input_connected(struct XenDevice *xendev)
if (in->qmouse) {
qemu_remove_mouse_event_handler(in->qmouse);
}
- in->qmouse = qemu_add_mouse_event_handler(xenfb_mouse_event, in,
+ in->qmouse = qemu_add_mouse_event_handler(&xenfb_mouse_ops, in,
in->abs_pointer_wanted,
"Xen PVFB Mouse");
}
diff --git a/hw/input/adb.c b/hw/input/adb.c
index 104bfc8..88edf57 100644
--- a/hw/input/adb.c
+++ b/hw/input/adb.c
@@ -529,6 +529,10 @@ static const VMStateDescription vmstate_adb_mouse = {
}
};
+static const MouseOps adb_mouse_ops = {
+ .put_event = adb_mouse_event,
+};
+
static void adb_mouse_realizefn(DeviceState *dev, Error **errp)
{
MouseState *s = ADB_MOUSE(dev);
@@ -536,7 +540,7 @@ static void adb_mouse_realizefn(DeviceState *dev, Error **errp)
amc->parent_realize(dev, errp);
- qemu_add_mouse_event_handler(adb_mouse_event, s, false, "QEMU ADB Mouse");
+ qemu_add_mouse_event_handler(&adb_mouse_ops, s, false, "QEMU ADB Mouse");
}
static void adb_mouse_initfn(Object *obj)
diff --git a/hw/input/hid.c b/hw/input/hid.c
index 7a3a7a4..4cdc8a9 100644
--- a/hw/input/hid.c
+++ b/hw/input/hid.c
@@ -425,6 +425,10 @@ void hid_free(HIDState *hs)
hid_del_idle_timer(hs);
}
+static const MouseOps hid_mouse_ops = {
+ .put_event = hid_pointer_event,
+};
+
void hid_init(HIDState *hs, int kind, HIDEventFunc event)
{
hs->kind = kind;
@@ -433,11 +437,11 @@ void hid_init(HIDState *hs, int kind, HIDEventFunc event)
if (hs->kind == HID_KEYBOARD) {
hs->kbd.eh_entry = qemu_add_kbd_event_handler(hid_keyboard_event, hs);
} else if (hs->kind == HID_MOUSE) {
- hs->ptr.eh_entry = qemu_add_mouse_event_handler(hid_pointer_event,
+ hs->ptr.eh_entry = qemu_add_mouse_event_handler(&hid_mouse_ops,
hs, false,
"QEMU HID Mouse");
} else if (hs->kind == HID_TABLET) {
- hs->ptr.eh_entry = qemu_add_mouse_event_handler(hid_pointer_event,
+ hs->ptr.eh_entry = qemu_add_mouse_event_handler(&hid_mouse_ops,
hs, true,
"QEMU HID Tablet");
}
diff --git a/hw/input/ps2.c b/hw/input/ps2.c
index e555f74..743e380 100644
--- a/hw/input/ps2.c
+++ b/hw/input/ps2.c
@@ -663,6 +663,10 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
return s;
}
+static const MouseOps ps2_mouse_ops = {
+ .put_event = ps2_mouse_event,
+};
+
void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
{
PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState));
@@ -670,7 +674,7 @@ void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
s->common.update_irq = update_irq;
s->common.update_arg = update_arg;
vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
- qemu_add_mouse_event_handler(ps2_mouse_event, s, false, "QEMU PS/2 Mouse");
+ qemu_add_mouse_event_handler(&ps2_mouse_ops, s, false, "QEMU PS/2 Mouse");
qemu_register_reset(ps2_mouse_reset, s);
return s;
}
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
index b0d9263..69b543c 100644
--- a/hw/input/tsc2005.c
+++ b/hw/input/tsc2005.c
@@ -519,6 +519,10 @@ static int tsc2005_load(QEMUFile *f, void *opaque, int version_id)
return 0;
}
+static const MouseOps tsc2005_touchscreen_ops = {
+ .put_event = tsc2005_touchscreen_event,
+};
+
void *tsc2005_init(qemu_irq pintdav)
{
TSC2005State *s;
@@ -544,7 +548,7 @@ void *tsc2005_init(qemu_irq pintdav)
tsc2005_reset(s);
- qemu_add_mouse_event_handler(tsc2005_touchscreen_event, s, true,
+ qemu_add_mouse_event_handler(&tsc2005_touchscreen_ops, s, true,
"QEMU TSC2005-driven Touchscreen");
qemu_register_reset((void *) tsc2005_reset, s);
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
index 02d3440..66e18fb 100644
--- a/hw/input/tsc210x.c
+++ b/hw/input/tsc210x.c
@@ -1100,6 +1100,10 @@ static int tsc210x_load(QEMUFile *f, void *opaque, int version_id)
return 0;
}
+static const MouseOps tsc210x_touchscreen_ops = {
+ .put_event = tsc210x_touchscreen_event,
+};
+
uWireSlave *tsc2102_init(qemu_irq pint)
{
TSC210xState *s;
@@ -1137,7 +1141,7 @@ uWireSlave *tsc2102_init(qemu_irq pint)
tsc210x_reset(s);
- qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, true,
+ qemu_add_mouse_event_handler(&tsc210x_touchscreen_ops, s, true,
"QEMU TSC2102-driven Touchscreen");
AUD_register_card(s->name, &s->card);
@@ -1188,7 +1192,7 @@ uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav)
tsc210x_reset(s);
- qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, true,
+ qemu_add_mouse_event_handler(&tsc210x_touchscreen_ops, s, true,
"QEMU TSC2301-driven Touchscreen");
AUD_register_card(s->name, &s->card);
diff --git a/hw/input/vmmouse.c b/hw/input/vmmouse.c
index 2b2ea88..ec13a8b 100644
--- a/hw/input/vmmouse.c
+++ b/hw/input/vmmouse.c
@@ -114,6 +114,10 @@ static void vmmouse_remove_handler(VMMouseState *s)
}
}
+static const MouseOps vmmouse_mouse_ops = {
+ .put_event = vmmouse_mouse_event,
+};
+
static void vmmouse_update_handler(VMMouseState *s, uint8_t absolute)
{
if (s->status != 0) {
@@ -124,7 +128,7 @@ static void vmmouse_update_handler(VMMouseState *s, uint8_t absolute)
vmmouse_remove_handler(s);
}
if (s->entry == NULL) {
- s->entry = qemu_add_mouse_event_handler(vmmouse_mouse_event,
+ s->entry = qemu_add_mouse_event_handler(&vmmouse_mouse_ops,
s, s->absolute,
"vmmouse");
qemu_activate_mouse_event_handler(s->entry);
diff --git a/hw/usb/dev-wacom.c b/hw/usb/dev-wacom.c
index 78563ff..90b7fee 100644
--- a/hw/usb/dev-wacom.c
+++ b/hw/usb/dev-wacom.c
@@ -165,12 +165,16 @@ static inline int int_clamp(int val, int vmin, int vmax)
return val;
}
+static const MouseOps usb_mouse_ops = {
+ .put_event = usb_mouse_event,
+};
+
static int usb_mouse_poll(USBWacomState *s, uint8_t *buf, int len)
{
int dx, dy, dz, b, l;
if (!s->mouse_grabbed) {
- s->eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, s, false,
+ s->eh_entry = qemu_add_mouse_event_handler(&usb_mouse_ops, s, false,
"QEMU PenPartner tablet");
qemu_activate_mouse_event_handler(s->eh_entry);
s->mouse_grabbed = 1;
@@ -203,12 +207,16 @@ static int usb_mouse_poll(USBWacomState *s, uint8_t *buf, int len)
return l;
}
+static const MouseOps usb_wacom_ops = {
+ .put_event = usb_wacom_event,
+};
+
static int usb_wacom_poll(USBWacomState *s, uint8_t *buf, int len)
{
int b;
if (!s->mouse_grabbed) {
- s->eh_entry = qemu_add_mouse_event_handler(usb_wacom_event, s, true,
+ s->eh_entry = qemu_add_mouse_event_handler(&usb_wacom_ops, s, true,
"QEMU PenPartner tablet");
qemu_activate_mouse_event_handler(s->eh_entry);
s->mouse_grabbed = 1;
diff --git a/include/ui/console.h b/include/ui/console.h
index e25879f..30b0451 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -27,7 +27,16 @@
typedef void QEMUPutKBDEvent(void *opaque, int keycode);
typedef void QEMUPutLEDEvent(void *opaque, int ledstate);
-typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state);
+typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz,
+ int buttons_state);
+
+/**
+ * MouseOps:
+ * @put_event: Signals a mouse event to a backend.
+ */
+typedef struct MouseOps {
+ QEMUPutMouseEvent *put_event;
+} MouseOps;
typedef struct QEMUPutMouseEntry QEMUPutMouseEntry;
typedef struct QEMUPutKbdEntry QEMUPutKbdEntry;
@@ -36,7 +45,7 @@ typedef struct QEMUPutLEDEntry QEMUPutLEDEntry;
QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
void *opaque);
void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry);
-QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
+QEMUPutMouseEntry *qemu_add_mouse_event_handler(const MouseOps *ops,
void *opaque, bool absolute,
const char *name);
void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry);
diff --git a/ui/input.c b/ui/input.c
index 76ded94..7f1248b 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -31,7 +31,7 @@
#include "ui/keymaps.h"
struct QEMUPutMouseEntry {
- QEMUPutMouseEvent *put_event;
+ const MouseOps *ops;
void *opaque;
bool absolute;
char *name;
@@ -346,7 +346,7 @@ static void check_mode_change(void)
current_has_absolute = has_absolute;
}
-QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
+QEMUPutMouseEntry *qemu_add_mouse_event_handler(const MouseOps *ops,
void *opaque, bool absolute,
const char *name)
{
@@ -355,7 +355,7 @@ QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
s = g_malloc0(sizeof(QEMUPutMouseEntry));
- s->put_event = func;
+ s->ops = ops;
s->opaque = opaque;
s->absolute = absolute;
s->name = g_strdup(name);
@@ -443,7 +443,7 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
entry = QTAILQ_FIRST(&mouse_handlers);
- if (entry->put_event) {
+ if (entry->ops->put_event) {
if (entry->absolute) {
width = 0x7fff;
height = 0x7fff;
@@ -472,8 +472,8 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
default:
return;
}
- entry->put_event(entry->opaque,
- rotated_dx, rotated_dy, dz, buttons_state);
+ entry->ops->put_event(entry->opaque,
+ rotated_dx, rotated_dy, dz, buttons_state);
}
}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH RFC 5/8] ui/input: Introduce MouseOps::get_buttons_state()
2013-06-16 3:39 [Qemu-devel] [PATCH RFC 0/8] monitor: Fix mouse_button and improve mouse_move commands Andreas Färber
` (3 preceding siblings ...)
2013-06-16 3:40 ` [Qemu-devel] [PATCH RFC 4/8] ui/input: Introduce MouseOps " Andreas Färber
@ 2013-06-16 3:40 ` Andreas Färber
2013-06-16 3:40 ` [Qemu-devel] [PATCH RFC 6/8] monitor: Eliminate global mouse buttons state for mouse_move Andreas Färber
` (3 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Andreas Färber @ 2013-06-16 3:40 UTC (permalink / raw)
To: qemu-devel
Cc: Brad Hards, Luiz Capitulino, Gerd Hoffmann, Paolo Bonzini,
Ludwig Nussel, Andreas Färber
Extend msmouse CharDriverState and escc ChannelState to store it.
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
backends/msmouse.c | 22 +++++++++++++++++++---
hw/char/escc.c | 11 +++++++++++
hw/display/ads7846.c | 8 ++++++++
hw/display/xenfb.c | 9 +++++++++
hw/input/adb.c | 7 +++++++
hw/input/hid.c | 13 +++++++++++++
hw/input/ps2.c | 8 ++++++++
hw/input/tsc2005.c | 8 ++++++++
hw/input/tsc210x.c | 8 ++++++++
hw/input/vmmouse.c | 11 +++++++++++
hw/usb/dev-wacom.c | 9 +++++++++
include/ui/console.h | 3 +++
12 files changed, 114 insertions(+), 3 deletions(-)
diff --git a/backends/msmouse.c b/backends/msmouse.c
index 035b7b4..3f35e7e 100644
--- a/backends/msmouse.c
+++ b/backends/msmouse.c
@@ -29,10 +29,16 @@
#define MSMOUSE_LO6(n) ((n) & 0x3f)
#define MSMOUSE_HI2(n) (((n) & 0xc0) >> 6)
+typedef struct MSMouseState {
+ CharDriverState chr;
+
+ int buttons_state;
+} MSMouseState;
+
static void msmouse_event(void *opaque,
int dx, int dy, int dz, int buttons_state)
{
- CharDriverState *chr = (CharDriverState *)opaque;
+ MSMouseState *s = opaque;
unsigned char bytes[4] = { 0x40, 0x00, 0x00, 0x00 };
@@ -49,7 +55,16 @@ static void msmouse_event(void *opaque,
/* We always send the packet of, so that we do not have to keep track
of previous state of the middle button. This can potentially confuse
some very old drivers for two button mice though. */
- qemu_chr_be_write(chr, bytes, 4);
+ qemu_chr_be_write(&s->chr, bytes, 4);
+
+ s->buttons_state = buttons_state;
+}
+
+static int msmouse_get_buttons_state(void *opaque)
+{
+ MSMouseState *s = opaque;
+
+ return s->buttons_state;
}
static int msmouse_chr_write (struct CharDriverState *s, const uint8_t *buf, int len)
@@ -65,13 +80,14 @@ static void msmouse_chr_close (struct CharDriverState *chr)
static const MouseOps msmouse_mouse_ops = {
.put_event = msmouse_event,
+ .get_buttons_state = msmouse_get_buttons_state,
};
CharDriverState *qemu_chr_open_msmouse(void)
{
CharDriverState *chr;
- chr = g_malloc0(sizeof(CharDriverState));
+ chr = g_malloc0(sizeof(MSMouseState));
chr->chr_write = msmouse_chr_write;
chr->chr_close = msmouse_chr_close;
chr->explicit_be_open = true;
diff --git a/hw/char/escc.c b/hw/char/escc.c
index f6592cb..1ac4d9e 100644
--- a/hw/char/escc.c
+++ b/hw/char/escc.c
@@ -88,6 +88,7 @@ typedef struct ChannelState {
SERIOQueue queue;
CharDriverState *chr;
int e0_mode, led_mode, caps_lock_mode, num_lock_mode;
+ int buttons_state;
int disabled;
int clock;
uint32_t vmstate_dummy;
@@ -304,6 +305,7 @@ static void escc_reset_chn(ChannelState *s)
s->rxint = s->txint = 0;
s->rxint_under_svc = s->txint_under_svc = 0;
s->e0_mode = s->led_mode = s->caps_lock_mode = s->num_lock_mode = 0;
+ s->buttons_state = 0;
clear_queue(s);
}
@@ -813,6 +815,7 @@ static void sunmouse_event(void *opaque,
trace_escc_sunmouse_event(dx, dy, buttons_state);
ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */
+ s->buttons_state = buttons_state;
if (buttons_state & MOUSE_EVENT_LBUTTON)
ch ^= 0x4;
if (buttons_state & MOUSE_EVENT_MBUTTON)
@@ -846,6 +849,13 @@ static void sunmouse_event(void *opaque,
put_queue(s, 0);
}
+static int sunmouse_get_buttons_state(void *opaque)
+{
+ ChannelState *s = opaque;
+
+ return s->buttons_state;
+}
+
void slavio_serial_ms_kbd_init(hwaddr base, qemu_irq irq,
int disabled, int clock, int it_shift)
{
@@ -869,6 +879,7 @@ void slavio_serial_ms_kbd_init(hwaddr base, qemu_irq irq,
static const MouseOps sunmouse_mouse_ops = {
.put_event = sunmouse_event,
+ .get_buttons_state = sunmouse_get_buttons_state,
};
static int escc_init1(SysBusDevice *dev)
diff --git a/hw/display/ads7846.c b/hw/display/ads7846.c
index 9026d97..d8d05e6 100644
--- a/hw/display/ads7846.c
+++ b/hw/display/ads7846.c
@@ -108,6 +108,13 @@ static void ads7846_ts_event(void *opaque,
}
}
+static int ads7846_ts_get_buttons_state(void *opaque)
+{
+ ADS7846State *s = opaque;
+
+ return s->pressure;
+}
+
static int ads7856_post_load(void *opaque, int version_id)
{
ADS7846State *s = opaque;
@@ -135,6 +142,7 @@ static const VMStateDescription vmstate_ads7846 = {
static const MouseOps ads7846_ts_ops = {
.put_event = ads7846_ts_event,
+ .get_buttons_state = ads7846_ts_get_buttons_state,
};
static int ads7846_init(SSISlave *dev)
diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c
index 14dac45..0d27377 100644
--- a/hw/display/xenfb.c
+++ b/hw/display/xenfb.c
@@ -64,6 +64,7 @@ struct XenInput {
int extended;
QEMUPutMouseEntry *qmouse;
};
+typedef struct XenInput XenInput;
#define UP_QUEUE 8
@@ -342,6 +343,13 @@ static void xenfb_mouse_event(void *opaque,
xenfb->button_state = button_state;
}
+static int xenfb_mouse_get_buttons_state(void *opaque)
+{
+ XenInput *in = opaque;
+
+ return in->button_state;
+}
+
static int input_init(struct XenDevice *xendev)
{
xenstore_write_be_int(xendev, "feature-abs-pointer", 1);
@@ -368,6 +376,7 @@ static int input_initialise(struct XenDevice *xendev)
static const MouseOps xenfb_mouse_ops = {
.put_event = xenfb_mouse_event,
+ .get_buttons_state = xenfb_mouse_get_buttons_state,
};
static void input_connected(struct XenDevice *xendev)
diff --git a/hw/input/adb.c b/hw/input/adb.c
index 88edf57..e12d978 100644
--- a/hw/input/adb.c
+++ b/hw/input/adb.c
@@ -404,6 +404,12 @@ static void adb_mouse_event(void *opaque,
s->buttons_state = buttons_state;
}
+static int adb_mouse_get_buttons_state(void *opaque)
+{
+ MouseState *s = opaque;
+
+ return s->buttons_state;
+}
static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
{
@@ -531,6 +537,7 @@ static const VMStateDescription vmstate_adb_mouse = {
static const MouseOps adb_mouse_ops = {
.put_event = adb_mouse_event,
+ .get_buttons_state = adb_mouse_get_buttons_state,
};
static void adb_mouse_realizefn(DeviceState *dev, Error **errp)
diff --git a/hw/input/hid.c b/hw/input/hid.c
index 4cdc8a9..ebe6276 100644
--- a/hw/input/hid.c
+++ b/hw/input/hid.c
@@ -158,6 +158,18 @@ static void hid_pointer_event(void *opaque,
hs->event(hs);
}
+static int hid_pointer_get_buttons_state(void *opaque)
+{
+ HIDState *hs = opaque;
+ int index;
+ HIDPointerEvent *e;
+
+ index = (hs->n ? hs->head : hs->head - 1);
+ e = &hs->ptr.queue[index & QUEUE_MASK];
+
+ return e->buttons_state;
+}
+
static void hid_keyboard_event(void *opaque, int keycode)
{
HIDState *hs = opaque;
@@ -427,6 +439,7 @@ void hid_free(HIDState *hs)
static const MouseOps hid_mouse_ops = {
.put_event = hid_pointer_event,
+ .get_buttons_state = hid_pointer_get_buttons_state,
};
void hid_init(HIDState *hs, int kind, HIDEventFunc event)
diff --git a/hw/input/ps2.c b/hw/input/ps2.c
index 743e380..a4de407 100644
--- a/hw/input/ps2.c
+++ b/hw/input/ps2.c
@@ -391,6 +391,13 @@ void ps2_mouse_fake_event(void *opaque)
ps2_mouse_event(opaque, 1, 0, 0, 0);
}
+static int ps2_mouse_get_buttons_state(void *opaque)
+{
+ PS2MouseState *s = opaque;
+
+ return s->mouse_buttons;
+}
+
void ps2_write_mouse(void *opaque, int val)
{
PS2MouseState *s = (PS2MouseState *)opaque;
@@ -665,6 +672,7 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
static const MouseOps ps2_mouse_ops = {
.put_event = ps2_mouse_event,
+ .get_buttons_state = ps2_mouse_get_buttons_state,
};
void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
index 69b543c..ed9f405 100644
--- a/hw/input/tsc2005.c
+++ b/hw/input/tsc2005.c
@@ -432,6 +432,13 @@ static void tsc2005_touchscreen_event(void *opaque,
tsc2005_pin_update(s);
}
+static int tsc2005_touchscreen_get_buttons_state(void *opaque)
+{
+ TSC2005State *s = opaque;
+
+ return s->pressure;
+}
+
static void tsc2005_save(QEMUFile *f, void *opaque)
{
TSC2005State *s = (TSC2005State *) opaque;
@@ -521,6 +528,7 @@ static int tsc2005_load(QEMUFile *f, void *opaque, int version_id)
static const MouseOps tsc2005_touchscreen_ops = {
.put_event = tsc2005_touchscreen_event,
+ .get_buttons_state = tsc2005_touchscreen_get_buttons_state,
};
void *tsc2005_init(qemu_irq pintdav)
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
index 66e18fb..593b90d 100644
--- a/hw/input/tsc210x.c
+++ b/hw/input/tsc210x.c
@@ -988,6 +988,13 @@ static void tsc210x_touchscreen_event(void *opaque,
tsc210x_pin_update(s);
}
+static int tsc210x_touchscreen_get_buttons_state(void *opaque)
+{
+ TSC210xState *s = opaque;
+
+ return s->pressure;
+}
+
static void tsc210x_i2s_swallow(TSC210xState *s)
{
if (s->dac_voice[0])
@@ -1102,6 +1109,7 @@ static int tsc210x_load(QEMUFile *f, void *opaque, int version_id)
static const MouseOps tsc210x_touchscreen_ops = {
.put_event = tsc210x_touchscreen_event,
+ .get_buttons_state = tsc210x_touchscreen_get_buttons_state,
};
uWireSlave *tsc2102_init(qemu_irq pint)
diff --git a/hw/input/vmmouse.c b/hw/input/vmmouse.c
index ec13a8b..dd20f1d 100644
--- a/hw/input/vmmouse.c
+++ b/hw/input/vmmouse.c
@@ -106,6 +106,16 @@ static void vmmouse_mouse_event(void *opaque, int x, int y, int dz, int buttons_
i8042_isa_mouse_fake_event(s->ps2_mouse);
}
+static int vmmouse_get_buttons_state(void *opaque)
+{
+ VMMouseState *s = opaque;
+
+ if (s->nb_queue < 4) {
+ return 0;
+ }
+ return s->queue[s->nb_queue - 4];
+}
+
static void vmmouse_remove_handler(VMMouseState *s)
{
if (s->entry) {
@@ -116,6 +126,7 @@ static void vmmouse_remove_handler(VMMouseState *s)
static const MouseOps vmmouse_mouse_ops = {
.put_event = vmmouse_mouse_event,
+ .get_buttons_state = vmmouse_get_buttons_state,
};
static void vmmouse_update_handler(VMMouseState *s, uint8_t absolute)
diff --git a/hw/usb/dev-wacom.c b/hw/usb/dev-wacom.c
index 90b7fee..76f75bb 100644
--- a/hw/usb/dev-wacom.c
+++ b/hw/usb/dev-wacom.c
@@ -155,6 +155,13 @@ static void usb_wacom_event(void *opaque,
usb_wakeup(s->intr, 0);
}
+static int usb_mouse_get_buttons_state(void *opaque)
+{
+ USBWacomState *s = opaque;
+
+ return s->buttons_state;
+}
+
static inline int int_clamp(int val, int vmin, int vmax)
{
if (val < vmin)
@@ -167,6 +174,7 @@ static inline int int_clamp(int val, int vmin, int vmax)
static const MouseOps usb_mouse_ops = {
.put_event = usb_mouse_event,
+ .get_buttons_state = usb_mouse_get_buttons_state,
};
static int usb_mouse_poll(USBWacomState *s, uint8_t *buf, int len)
@@ -209,6 +217,7 @@ static int usb_mouse_poll(USBWacomState *s, uint8_t *buf, int len)
static const MouseOps usb_wacom_ops = {
.put_event = usb_wacom_event,
+ .get_buttons_state = usb_mouse_get_buttons_state,
};
static int usb_wacom_poll(USBWacomState *s, uint8_t *buf, int len)
diff --git a/include/ui/console.h b/include/ui/console.h
index 30b0451..2ac6403 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -29,13 +29,16 @@ typedef void QEMUPutKBDEvent(void *opaque, int keycode);
typedef void QEMUPutLEDEvent(void *opaque, int ledstate);
typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz,
int buttons_state);
+typedef int QEMUGetMouseButtonsState(void *opaque);
/**
* MouseOps:
* @put_event: Signals a mouse event to a backend.
+ * @get_buttons_state: Retrieves mouse buttons state from a backend.
*/
typedef struct MouseOps {
QEMUPutMouseEvent *put_event;
+ QEMUGetMouseButtonsState *get_buttons_state;
} MouseOps;
typedef struct QEMUPutMouseEntry QEMUPutMouseEntry;
--
1.8.1.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH RFC 6/8] monitor: Eliminate global mouse buttons state for mouse_move
2013-06-16 3:39 [Qemu-devel] [PATCH RFC 0/8] monitor: Fix mouse_button and improve mouse_move commands Andreas Färber
` (4 preceding siblings ...)
2013-06-16 3:40 ` [Qemu-devel] [PATCH RFC 5/8] ui/input: Introduce MouseOps::get_buttons_state() Andreas Färber
@ 2013-06-16 3:40 ` Andreas Färber
2013-06-16 3:40 ` [Qemu-devel] [PATCH RFC 7/8] ui/input: Introduce MouseOps::get_position() Andreas Färber
` (2 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Andreas Färber @ 2013-06-16 3:40 UTC (permalink / raw)
To: qemu-devel
Cc: Anthony Liguori, Brad Hards, Luiz Capitulino, Gerd Hoffmann,
Paolo Bonzini, Ludwig Nussel, Andreas Färber
mouse_button command would save buttons state globally so that
move_move command could reuse it for kbd_mouse_event().
Introduce kbd_mouse_move_event() to allow to use new
MouseOps::get_buttons_state() to obtain buttons state from the
respective mouse.
This means that mouse_set will now affect which buttons state is used on
mouse_move.
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
include/ui/console.h | 1 +
monitor.c | 10 ++++------
ui/input.c | 14 ++++++++++++++
3 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/include/ui/console.h b/include/ui/console.h
index 2ac6403..132591a 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -60,6 +60,7 @@ void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry);
void kbd_put_keycode(int keycode);
void kbd_put_ledstate(int ledstate);
void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
+void kbd_mouse_move_event(int dx, int dy, int dz);
/* Does the current mouse generate absolute events */
bool kbd_mouse_is_absolute(void);
diff --git a/monitor.c b/monitor.c
index 70ae8f5..6816e82 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1266,8 +1266,6 @@ static void do_sum(Monitor *mon, const QDict *qdict)
monitor_printf(mon, "%05d\n", sum);
}
-static int mouse_button_state;
-
static void do_mouse_move(Monitor *mon, const QDict *qdict)
{
int dx, dy, dz;
@@ -1277,16 +1275,16 @@ static void do_mouse_move(Monitor *mon, const QDict *qdict)
dx = strtol(dx_str, NULL, 0);
dy = strtol(dy_str, NULL, 0);
dz = 0;
- if (dz_str)
+ if (dz_str) {
dz = strtol(dz_str, NULL, 0);
- kbd_mouse_event(dx, dy, dz, mouse_button_state);
+ }
+ kbd_mouse_move_event(dx, dy, dz);
}
static void do_mouse_button(Monitor *mon, const QDict *qdict)
{
int button_state = qdict_get_int(qdict, "button_state");
- mouse_button_state = button_state;
- kbd_mouse_event(0, 0, 0, mouse_button_state);
+ kbd_mouse_event(0, 0, 0, button_state);
}
static void do_ioport_read(Monitor *mon, const QDict *qdict)
diff --git a/ui/input.c b/ui/input.c
index 7f1248b..366f3c0 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -477,6 +477,20 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
}
}
+void kbd_mouse_move_event(int dx, int dy, int dz)
+{
+ QEMUPutMouseEntry *mouse;
+ int buttons_state;
+
+ if (QTAILQ_EMPTY(&mouse_handlers)) {
+ return;
+ }
+ mouse = QTAILQ_FIRST(&mouse_handlers);
+
+ buttons_state = mouse->ops->get_buttons_state(mouse->opaque);
+ kbd_mouse_event(dx, dy, dz, buttons_state);
+}
+
bool kbd_mouse_is_absolute(void)
{
if (QTAILQ_EMPTY(&mouse_handlers)) {
--
1.8.1.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH RFC 7/8] ui/input: Introduce MouseOps::get_position()
2013-06-16 3:39 [Qemu-devel] [PATCH RFC 0/8] monitor: Fix mouse_button and improve mouse_move commands Andreas Färber
` (5 preceding siblings ...)
2013-06-16 3:40 ` [Qemu-devel] [PATCH RFC 6/8] monitor: Eliminate global mouse buttons state for mouse_move Andreas Färber
@ 2013-06-16 3:40 ` Andreas Färber
2013-06-16 3:40 ` [Qemu-devel] [PATCH RFC 8/8] monitor: Fix mouse_button command for absolute coordinates Andreas Färber
2013-06-17 7:16 ` [Qemu-devel] [PATCH RFC 0/8] monitor: Fix mouse_button and improve mouse_move commands Gerd Hoffmann
8 siblings, 0 replies; 13+ messages in thread
From: Andreas Färber @ 2013-06-16 3:40 UTC (permalink / raw)
To: qemu-devel
Cc: Brad Hards, Luiz Capitulino, Gerd Hoffmann, Paolo Bonzini,
Ludwig Nussel, Andreas Färber
Traditionally mice have used relative coordinates, so that a mouse event
at (0,0,0) would mean no change of position. However, with absolute
coordinates those coordinates signify the top left corner.
Since the VMState of mice is kept at device level, introduce a callback
to retrieve the current position in a migration-safe way.
For xenfb add state fields for (x,y) coordinates.
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
hw/display/ads7846.c | 9 +++++++++
hw/display/xenfb.c | 34 ++++++++++++++++++++++++++++++----
hw/input/hid.c | 26 +++++++++++++++++++++++++-
hw/input/tsc2005.c | 9 +++++++++
hw/input/tsc210x.c | 9 +++++++++
hw/input/vmmouse.c | 14 ++++++++++++++
hw/usb/dev-wacom.c | 9 +++++++++
include/ui/console.h | 3 +++
8 files changed, 108 insertions(+), 5 deletions(-)
diff --git a/hw/display/ads7846.c b/hw/display/ads7846.c
index d8d05e6..a7ee56f 100644
--- a/hw/display/ads7846.c
+++ b/hw/display/ads7846.c
@@ -88,6 +88,14 @@ static uint32_t ads7846_transfer(SSISlave *dev, uint32_t value)
return s->output;
}
+static void ads7846_ts_get_position(void *opaque, int *x, int *y)
+{
+ ADS7846State *s = opaque;
+
+ *x = 0x7fff - (((s->input[1] - X_AXIS_MIN) << 15) / X_AXIS_DMAX);
+ *y = ((s->input[5] - Y_AXIS_MIN) << 15) / Y_AXIS_DMAX;
+}
+
static void ads7846_ts_event(void *opaque,
int x, int y, int z, int buttons_state)
{
@@ -143,6 +151,7 @@ static const VMStateDescription vmstate_ads7846 = {
static const MouseOps ads7846_ts_ops = {
.put_event = ads7846_ts_event,
.get_buttons_state = ads7846_ts_get_buttons_state,
+ .get_position = ads7846_ts_get_position,
};
static int ads7846_init(SSISlave *dev)
diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c
index 0d27377..46a2881 100644
--- a/hw/display/xenfb.c
+++ b/hw/display/xenfb.c
@@ -57,10 +57,19 @@ struct common {
QemuConsole *con;
};
+/**
+ * XenInput:
+ * @abs_pointer_wanted: Whether guest supports absolute pointer.
+ * @x: Last pointer X position in QEMU coordinates.
+ * @y: Last pointer Y position in QEMU coordinates.
+ * @button_state: Last seen pointer button state.
+ */
struct XenInput {
struct common c;
- int abs_pointer_wanted; /* Whether guest supports absolute pointer */
- int button_state; /* Last seen pointer button state */
+ int abs_pointer_wanted;
+ int x;
+ int y;
+ int button_state;
int extended;
QEMUPutMouseEntry *qmouse;
};
@@ -323,13 +332,16 @@ static void xenfb_mouse_event(void *opaque,
int dh = surface_height(surface);
int i;
- if (xenfb->abs_pointer_wanted)
+ if (xenfb->abs_pointer_wanted) {
xenfb_send_position(xenfb,
dx * (dw - 1) / 0x7fff,
dy * (dh - 1) / 0x7fff,
dz);
- else
+ xenfb->x = dx;
+ xenfb->y = dy;
+ } else {
xenfb_send_motion(xenfb, dx, dy, dz);
+ }
for (i = 0 ; i < 8 ; i++) {
int lastDown = xenfb->button_state & (1 << i);
@@ -350,6 +362,19 @@ static int xenfb_mouse_get_buttons_state(void *opaque)
return in->button_state;
}
+static void xenfb_mouse_get_position(void *opaque, int *x, int *y)
+{
+ XenInput *in = opaque;
+
+ if (in->abs_pointer_wanted) {
+ *x = in->x;
+ *y = in->y;
+ } else {
+ *x = 0;
+ *y = 0;
+ }
+}
+
static int input_init(struct XenDevice *xendev)
{
xenstore_write_be_int(xendev, "feature-abs-pointer", 1);
@@ -377,6 +402,7 @@ static int input_initialise(struct XenDevice *xendev)
static const MouseOps xenfb_mouse_ops = {
.put_event = xenfb_mouse_event,
.get_buttons_state = xenfb_mouse_get_buttons_state,
+ .get_position = xenfb_mouse_get_position,
};
static void input_connected(struct XenDevice *xendev)
diff --git a/hw/input/hid.c b/hw/input/hid.c
index ebe6276..37239e5 100644
--- a/hw/input/hid.c
+++ b/hw/input/hid.c
@@ -264,6 +264,24 @@ void hid_pointer_activate(HIDState *hs)
}
}
+static void hid_pointer_get_position(void *opaque, int *x, int *y)
+{
+ HIDState *hs = opaque;
+ int index;
+ HIDPointerEvent *e;
+
+ index = (hs->n ? hs->head : hs->head - 1);
+ e = &hs->ptr.queue[index & QUEUE_MASK];
+
+ if (hs->kind == HID_MOUSE) {
+ *x = 0;
+ *y = 0;
+ } else {
+ *x = e->xdx;
+ *y = e->ydy;
+ }
+}
+
int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len)
{
int dx, dy, dz, b, l;
@@ -442,6 +460,12 @@ static const MouseOps hid_mouse_ops = {
.get_buttons_state = hid_pointer_get_buttons_state,
};
+static const MouseOps hid_tablet_ops = {
+ .put_event = hid_pointer_event,
+ .get_buttons_state = hid_pointer_get_buttons_state,
+ .get_position = hid_pointer_get_position,
+};
+
void hid_init(HIDState *hs, int kind, HIDEventFunc event)
{
hs->kind = kind;
@@ -454,7 +478,7 @@ void hid_init(HIDState *hs, int kind, HIDEventFunc event)
hs, false,
"QEMU HID Mouse");
} else if (hs->kind == HID_TABLET) {
- hs->ptr.eh_entry = qemu_add_mouse_event_handler(&hid_mouse_ops,
+ hs->ptr.eh_entry = qemu_add_mouse_event_handler(&hid_tablet_ops,
hs, true,
"QEMU HID Tablet");
}
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
index ed9f405..c0dbc02 100644
--- a/hw/input/tsc2005.c
+++ b/hw/input/tsc2005.c
@@ -411,6 +411,14 @@ static void tsc2005_timer_tick(void *opaque)
tsc2005_pin_update(s);
}
+static void tsc2005_touchscreen_get_position(void *opaque, int *x, int *y)
+{
+ TSC2005State *s = opaque;
+
+ *x = s->x;
+ *y = s->y;
+}
+
static void tsc2005_touchscreen_event(void *opaque,
int x, int y, int z, int buttons_state)
{
@@ -529,6 +537,7 @@ static int tsc2005_load(QEMUFile *f, void *opaque, int version_id)
static const MouseOps tsc2005_touchscreen_ops = {
.put_event = tsc2005_touchscreen_event,
.get_buttons_state = tsc2005_touchscreen_get_buttons_state,
+ .get_position = tsc2005_touchscreen_get_position,
};
void *tsc2005_init(qemu_irq pintdav)
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
index 593b90d..5faaaf6 100644
--- a/hw/input/tsc210x.c
+++ b/hw/input/tsc210x.c
@@ -967,6 +967,14 @@ static void tsc210x_timer_tick(void *opaque)
qemu_irq_lower(s->davint);
}
+static void tsc210x_touchscreen_get_position(void *opaque, int *x, int *y)
+{
+ TSC210xState *s = opaque;
+
+ *x = s->x;
+ *y = s->y;
+}
+
static void tsc210x_touchscreen_event(void *opaque,
int x, int y, int z, int buttons_state)
{
@@ -1110,6 +1118,7 @@ static int tsc210x_load(QEMUFile *f, void *opaque, int version_id)
static const MouseOps tsc210x_touchscreen_ops = {
.put_event = tsc210x_touchscreen_event,
.get_buttons_state = tsc210x_touchscreen_get_buttons_state,
+ .get_position = tsc210x_touchscreen_get_position,
};
uWireSlave *tsc2102_init(qemu_irq pint)
diff --git a/hw/input/vmmouse.c b/hw/input/vmmouse.c
index dd20f1d..461091a 100644
--- a/hw/input/vmmouse.c
+++ b/hw/input/vmmouse.c
@@ -73,6 +73,19 @@ static uint32_t vmmouse_get_status(VMMouseState *s)
return (s->status << 16) | s->nb_queue;
}
+static void vmmouse_get_position(void *opaque, int *x, int *y)
+{
+ VMMouseState *s = opaque;
+
+ if (s->absolute && s->nb_queue >= 4) {
+ *x = s->queue[s->nb_queue - 3] >> 1;
+ *y = s->queue[s->nb_queue - 2] >> 1;
+ } else {
+ *x = 0;
+ *y = 0;
+ }
+}
+
static void vmmouse_mouse_event(void *opaque, int x, int y, int dz, int buttons_state)
{
VMMouseState *s = opaque;
@@ -127,6 +140,7 @@ static void vmmouse_remove_handler(VMMouseState *s)
static const MouseOps vmmouse_mouse_ops = {
.put_event = vmmouse_mouse_event,
.get_buttons_state = vmmouse_get_buttons_state,
+ .get_position = vmmouse_get_position,
};
static void vmmouse_update_handler(VMMouseState *s, uint8_t absolute)
diff --git a/hw/usb/dev-wacom.c b/hw/usb/dev-wacom.c
index 76f75bb..d4ebd9c 100644
--- a/hw/usb/dev-wacom.c
+++ b/hw/usb/dev-wacom.c
@@ -141,6 +141,14 @@ static void usb_mouse_event(void *opaque,
usb_wakeup(s->intr, 0);
}
+static void usb_wacom_get_position(void *opaque, int *x, int *y)
+{
+ USBWacomState *s = opaque;
+
+ *x = s->x * 0x7FFF / 5040;
+ *y = s->y * 0x7FFF / 3780;
+}
+
static void usb_wacom_event(void *opaque,
int x, int y, int dz, int buttons_state)
{
@@ -218,6 +226,7 @@ static int usb_mouse_poll(USBWacomState *s, uint8_t *buf, int len)
static const MouseOps usb_wacom_ops = {
.put_event = usb_wacom_event,
.get_buttons_state = usb_mouse_get_buttons_state,
+ .get_position = usb_wacom_get_position,
};
static int usb_wacom_poll(USBWacomState *s, uint8_t *buf, int len)
diff --git a/include/ui/console.h b/include/ui/console.h
index 132591a..d41dd1d 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -30,15 +30,18 @@ typedef void QEMUPutLEDEvent(void *opaque, int ledstate);
typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz,
int buttons_state);
typedef int QEMUGetMouseButtonsState(void *opaque);
+typedef void QEMUGetMousePosition(void *opaque, int *x, int *y);
/**
* MouseOps:
* @put_event: Signals a mouse event to a backend.
* @get_buttons_state: Retrieves mouse buttons state from a backend.
+ * @get_position: Retrieves mouse cursor position from a backend.
*/
typedef struct MouseOps {
QEMUPutMouseEvent *put_event;
QEMUGetMouseButtonsState *get_buttons_state;
+ QEMUGetMousePosition *get_position;
} MouseOps;
typedef struct QEMUPutMouseEntry QEMUPutMouseEntry;
--
1.8.1.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH RFC 8/8] monitor: Fix mouse_button command for absolute coordinates
2013-06-16 3:39 [Qemu-devel] [PATCH RFC 0/8] monitor: Fix mouse_button and improve mouse_move commands Andreas Färber
` (6 preceding siblings ...)
2013-06-16 3:40 ` [Qemu-devel] [PATCH RFC 7/8] ui/input: Introduce MouseOps::get_position() Andreas Färber
@ 2013-06-16 3:40 ` Andreas Färber
2013-06-17 7:16 ` [Qemu-devel] [PATCH RFC 0/8] monitor: Fix mouse_button and improve mouse_move commands Gerd Hoffmann
8 siblings, 0 replies; 13+ messages in thread
From: Andreas Färber @ 2013-06-16 3:40 UTC (permalink / raw)
To: qemu-devel
Cc: Anthony Liguori, Brad Hards, Luiz Capitulino, Gerd Hoffmann,
Paolo Bonzini, Ludwig Nussel, Andreas Färber
When using a virtual mouse device with absolute coordinates (tablet) the
mouse_button command would raise a mouse event at coordinates (0,0,0),
breaking openQA among others.
Use a new kbd_mouse_button_event() to obtain the current position with
the new MouseOps::get_position() callback when in absolute mode.
This allows both switching mice via mouse_set and mixing mouse_move with
interactive GUI/VNC mouse movements.
Addresses LP#752476 / BNC#813642.
Reported-by: Brad Hards <bradh@frogmouth.net>
Reported-by: Ludwig Nussel <lnussel@suse.de>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
include/ui/console.h | 1 +
monitor.c | 2 +-
ui/input.c | 17 +++++++++++++++++
3 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/include/ui/console.h b/include/ui/console.h
index d41dd1d..f912ad6 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -64,6 +64,7 @@ void kbd_put_keycode(int keycode);
void kbd_put_ledstate(int ledstate);
void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
void kbd_mouse_move_event(int dx, int dy, int dz);
+void kbd_mouse_button_event(int buttons_state);
/* Does the current mouse generate absolute events */
bool kbd_mouse_is_absolute(void);
diff --git a/monitor.c b/monitor.c
index 6816e82..97ca8a8 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1284,7 +1284,7 @@ static void do_mouse_move(Monitor *mon, const QDict *qdict)
static void do_mouse_button(Monitor *mon, const QDict *qdict)
{
int button_state = qdict_get_int(qdict, "button_state");
- kbd_mouse_event(0, 0, 0, button_state);
+ kbd_mouse_button_event(button_state);
}
static void do_ioport_read(Monitor *mon, const QDict *qdict)
diff --git a/ui/input.c b/ui/input.c
index 366f3c0..a02160d 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -491,6 +491,23 @@ void kbd_mouse_move_event(int dx, int dy, int dz)
kbd_mouse_event(dx, dy, dz, buttons_state);
}
+void kbd_mouse_button_event(int buttons_state)
+{
+ QEMUPutMouseEntry *mouse;
+ int dx = 0, dy = 0;
+
+ if (QTAILQ_EMPTY(&mouse_handlers)) {
+ return;
+ }
+
+ mouse = QTAILQ_FIRST(&mouse_handlers);
+ if (mouse->absolute && mouse->ops->get_position != NULL) {
+ mouse->ops->get_position(mouse->opaque, &dx, &dy);
+ }
+
+ kbd_mouse_event(dx, dy, 0, buttons_state);
+}
+
bool kbd_mouse_is_absolute(void)
{
if (QTAILQ_EMPTY(&mouse_handlers)) {
--
1.8.1.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH RFC 0/8] monitor: Fix mouse_button and improve mouse_move commands
2013-06-16 3:39 [Qemu-devel] [PATCH RFC 0/8] monitor: Fix mouse_button and improve mouse_move commands Andreas Färber
` (7 preceding siblings ...)
2013-06-16 3:40 ` [Qemu-devel] [PATCH RFC 8/8] monitor: Fix mouse_button command for absolute coordinates Andreas Färber
@ 2013-06-17 7:16 ` Gerd Hoffmann
8 siblings, 0 replies; 13+ messages in thread
From: Gerd Hoffmann @ 2013-06-17 7:16 UTC (permalink / raw)
To: Andreas Färber
Cc: Bernhard M. Wiedemann, xen-devel, Stephan Kulow, Brad Hards,
Peter Maydell, Stefano Stabellini, Mark Cave-Ayland, qemu-devel,
Luiz Capitulino, Blue Swirl, Alexander Graf, qemu-ppc,
Paolo Bonzini, Ludwig Nussel
Hi,
> My solution is to obtain position and buttons state from where the VMState is:
> I clean up the mouse event handler registration code a bit and extend it:
> * one mandatory callback to obtain mouse button state and
> * one optional callback to obtain absolute position state from backends.
Hmm, querying state from the mouse drivers just to be able to pass it
back in is a bit backwards.
I'd rather go fix the event reporting interface. Instead of having
*one* callback with *all* parameters I think we should have a callback
per parameter, or maybe better a parameter type enum. i.e. instead of:
mouse_event(x, y, z, button_state)
We'll have
mouse_event(type, value)
Then we'll report moves this way:
mouse_event(REL_X, 23); // or ABS_X for the tablet.
mouse_event(REL_Y, 42);
mouse_event(SYNC, 0); // <<= means "done, flush events to guest"
And klicks this way:
mouse_event(DOWN, BTN_LEFT);
mouse_event(SYNC);
mouse_event(UP, BTN_LEFT);
mouse_event(SYNC);
The linux input layer works in a simliar way.
cheers,
Gerd
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH RFC 1/8] ui/input: Clean up QEMUPutMouseEntry struct
2013-06-16 3:39 ` [Qemu-devel] [PATCH RFC 1/8] ui/input: Clean up QEMUPutMouseEntry struct Andreas Färber
@ 2013-06-17 7:17 ` Gerd Hoffmann
0 siblings, 0 replies; 13+ messages in thread
From: Gerd Hoffmann @ 2013-06-17 7:17 UTC (permalink / raw)
To: Andreas Färber
Cc: Anthony Liguori, Brad Hards, qemu-devel, Luiz Capitulino,
Paolo Bonzini, Ludwig Nussel
On 06/16/13 05:39, Andreas Färber wrote:
> Shorten field names to not duplicate struct name.
Nice.
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
cheers,
Gerd
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH RFC 2/8] ui/input: Simplify kbd_mouse_event()
2013-06-16 3:39 ` [Qemu-devel] [PATCH RFC 2/8] ui/input: Simplify kbd_mouse_event() Andreas Färber
@ 2013-06-17 7:17 ` Gerd Hoffmann
0 siblings, 0 replies; 13+ messages in thread
From: Gerd Hoffmann @ 2013-06-17 7:17 UTC (permalink / raw)
To: Andreas Färber
Cc: Anthony Liguori, Brad Hards, qemu-devel, Luiz Capitulino,
Paolo Bonzini, Ludwig Nussel
On 06/16/13 05:39, Andreas Färber wrote:
> Now that the field names are bearable, there's no compelling reason to
> use local variables for the fields.
>
> Unify the four callback invokations through variables for the rotated
> coordinates instead.
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
cheers,
Gerd
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH RFC 4/8] ui/input: Introduce MouseOps for qemu_add_mouse_event_handler()
2013-06-16 3:40 ` [Qemu-devel] [PATCH RFC 4/8] ui/input: Introduce MouseOps " Andreas Färber
@ 2013-06-17 7:20 ` Gerd Hoffmann
0 siblings, 0 replies; 13+ messages in thread
From: Gerd Hoffmann @ 2013-06-17 7:20 UTC (permalink / raw)
To: Andreas Färber
Cc: Anthony Liguori, Brad Hards, qemu-devel, Luiz Capitulino,
Paolo Bonzini, Ludwig Nussel
On 06/16/13 05:40, Andreas Färber wrote:
> This allows to add callbacks to mouse event handlers without constantly
> touching all callers of qemu_add_mouse_event_handler() or
> qemu_add_mouse_event_handler() itself.
I think you can stick other static information into the Ops too: name +
absolute.
cheers,
Gerd
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2013-06-17 7:20 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-16 3:39 [Qemu-devel] [PATCH RFC 0/8] monitor: Fix mouse_button and improve mouse_move commands Andreas Färber
2013-06-16 3:39 ` [Qemu-devel] [PATCH RFC 1/8] ui/input: Clean up QEMUPutMouseEntry struct Andreas Färber
2013-06-17 7:17 ` Gerd Hoffmann
2013-06-16 3:39 ` [Qemu-devel] [PATCH RFC 2/8] ui/input: Simplify kbd_mouse_event() Andreas Färber
2013-06-17 7:17 ` Gerd Hoffmann
2013-06-16 3:40 ` [Qemu-devel] [PATCH RFC 3/8] ui/input: Use bool for qemu_add_mouse_event_handler() Andreas Färber
2013-06-16 3:40 ` [Qemu-devel] [PATCH RFC 4/8] ui/input: Introduce MouseOps " Andreas Färber
2013-06-17 7:20 ` Gerd Hoffmann
2013-06-16 3:40 ` [Qemu-devel] [PATCH RFC 5/8] ui/input: Introduce MouseOps::get_buttons_state() Andreas Färber
2013-06-16 3:40 ` [Qemu-devel] [PATCH RFC 6/8] monitor: Eliminate global mouse buttons state for mouse_move Andreas Färber
2013-06-16 3:40 ` [Qemu-devel] [PATCH RFC 7/8] ui/input: Introduce MouseOps::get_position() Andreas Färber
2013-06-16 3:40 ` [Qemu-devel] [PATCH RFC 8/8] monitor: Fix mouse_button command for absolute coordinates Andreas Färber
2013-06-17 7:16 ` [Qemu-devel] [PATCH RFC 0/8] monitor: Fix mouse_button and improve mouse_move commands Gerd Hoffmann
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).