From: Anthony Liguori <aliguori@us.ibm.com>
To: qemu-devel@nongnu.org
Cc: Avi Kivity <avi@redhat.com>,
Anthony Liguori <aliguori@us.ibm.com>,
Gerd Hoffman <kraxel@redhat.com>,
Luiz Capitulino <lcapitulino@redhat.com>
Subject: [Qemu-devel] [PATCH 2/7] Rewrite mouse handlers to use QTAILQ and to have an activation function
Date: Mon, 15 Mar 2010 15:34:23 -0500 [thread overview]
Message-ID: <1268685268-16881-2-git-send-email-aliguori@us.ibm.com> (raw)
In-Reply-To: <1268685268-16881-1-git-send-email-aliguori@us.ibm.com>
And convert usb-hid to use it (to avoid regression with bisection)
Right now, when we do info mice and we've added a usb tablet, we don't see it
until the guest starts using the tablet. We implement this behavior in order
to provide a means to delay registration of a mouse handler since we treat
the last registered handler as the current handler.
This is a usability problem though as we would like to give the user feedback
that they've either 1) not added an absolute device 2) there is an absolute
device but the guest isn't using it 3) we have an absolute device and it's
active.
By using QTAILQ and having an explicit activation function that moves the
handler to the front of the queue, we can implement the same semantics as
before with respect to automatically switching to usb tablet while providing
the user with a whole lot more information.
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
console.h | 6 +++-
hw/usb-hid.c | 15 ++++++--
input.c | 109 +++++++++++++++++++++++-----------------------------------
3 files changed, 59 insertions(+), 71 deletions(-)
diff --git a/console.h b/console.h
index 71e8ff2..94d9cae 100644
--- a/console.h
+++ b/console.h
@@ -28,8 +28,10 @@ typedef struct QEMUPutMouseEntry {
int qemu_put_mouse_event_absolute;
char *qemu_put_mouse_event_name;
+ int index;
+
/* used internally by qemu for handling mice */
- struct QEMUPutMouseEntry *next;
+ QTAILQ_ENTRY(QEMUPutMouseEntry) node;
} QEMUPutMouseEntry;
typedef struct QEMUPutLEDEntry {
@@ -43,6 +45,8 @@ QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
void *opaque, int absolute,
const char *name);
void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry);
+void qemu_activate_mouse_event_handler(QEMUPutMouseEntry *entry);
+
QEMUPutLEDEntry *qemu_add_led_event_handler(QEMUPutLEDEvent *func, void *opaque);
void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry);
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index 2e4e647..8e6c6e0 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -511,8 +511,7 @@ static int usb_mouse_poll(USBHIDState *hs, uint8_t *buf, int len)
USBMouseState *s = &hs->ptr;
if (!s->mouse_grabbed) {
- s->eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, hs,
- 0, "QEMU USB Mouse");
+ qemu_activate_mouse_event_handler(s->eh_entry);
s->mouse_grabbed = 1;
}
@@ -553,8 +552,7 @@ static int usb_tablet_poll(USBHIDState *hs, uint8_t *buf, int len)
USBMouseState *s = &hs->ptr;
if (!s->mouse_grabbed) {
- s->eh_entry = qemu_add_mouse_event_handler(usb_tablet_event, hs,
- 1, "QEMU USB Tablet");
+ qemu_activate_mouse_event_handler(s->eh_entry);
s->mouse_grabbed = 1;
}
@@ -866,6 +864,15 @@ static int usb_hid_initfn(USBDevice *dev, int kind)
USBHIDState *s = DO_UPCAST(USBHIDState, dev, dev);
s->dev.speed = USB_SPEED_FULL;
s->kind = kind;
+
+ if (s->kind == USB_MOUSE) {
+ s->ptr.eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, s,
+ 0, "QEMU USB Mouse");
+ } else if (s->kind == USB_TABLET) {
+ s->ptr.eh_entry = qemu_add_mouse_event_handler(usb_tablet_event, s,
+ 1, "QEMU USB Tablet");
+ }
+
/* Force poll routine to be run and grab input the first time. */
s->changed = 1;
return 0;
diff --git a/input.c b/input.c
index baaa4c6..397bfc5 100644
--- a/input.c
+++ b/input.c
@@ -31,9 +31,9 @@
static QEMUPutKBDEvent *qemu_put_kbd_event;
static void *qemu_put_kbd_event_opaque;
-static QEMUPutMouseEntry *qemu_put_mouse_event_head;
-static QEMUPutMouseEntry *qemu_put_mouse_event_current;
static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers = QTAILQ_HEAD_INITIALIZER(led_handlers);
+static QTAILQ_HEAD(, QEMUPutMouseEntry) mouse_handlers =
+ QTAILQ_HEAD_INITIALIZER(mouse_handlers);
void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
{
@@ -45,7 +45,8 @@ QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
void *opaque, int absolute,
const char *name)
{
- QEMUPutMouseEntry *s, *cursor;
+ QEMUPutMouseEntry *s;
+ static int mouse_index = 0;
s = qemu_mallocz(sizeof(QEMUPutMouseEntry));
@@ -53,51 +54,24 @@ QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
s->qemu_put_mouse_event_opaque = opaque;
s->qemu_put_mouse_event_absolute = absolute;
s->qemu_put_mouse_event_name = qemu_strdup(name);
- s->next = NULL;
+ s->index = mouse_index++;
- if (!qemu_put_mouse_event_head) {
- qemu_put_mouse_event_head = qemu_put_mouse_event_current = s;
- return s;
- }
-
- cursor = qemu_put_mouse_event_head;
- while (cursor->next != NULL)
- cursor = cursor->next;
-
- cursor->next = s;
- qemu_put_mouse_event_current = s;
+ QTAILQ_INSERT_TAIL(&mouse_handlers, s, node);
return s;
}
-void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
+void qemu_activate_mouse_event_handler(QEMUPutMouseEntry *entry)
{
- QEMUPutMouseEntry *prev = NULL, *cursor;
-
- if (!qemu_put_mouse_event_head || entry == NULL)
- return;
-
- cursor = qemu_put_mouse_event_head;
- while (cursor != NULL && cursor != entry) {
- prev = cursor;
- cursor = cursor->next;
- }
+ QTAILQ_REMOVE(&mouse_handlers, entry, node);
+ QTAILQ_INSERT_HEAD(&mouse_handlers, entry, node);
- if (cursor == NULL) // does not exist or list empty
- return;
- else if (prev == NULL) { // entry is head
- qemu_put_mouse_event_head = cursor->next;
- if (qemu_put_mouse_event_current == entry)
- qemu_put_mouse_event_current = cursor->next;
- qemu_free(entry->qemu_put_mouse_event_name);
- qemu_free(entry);
- return;
- }
-
- prev->next = entry->next;
+ check_mode_change();
+}
- if (qemu_put_mouse_event_current == entry)
- qemu_put_mouse_event_current = prev;
+void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
+{
+ QTAILQ_REMOVE(&mouse_handlers, entry, node);
qemu_free(entry->qemu_put_mouse_event_name);
qemu_free(entry);
@@ -142,39 +116,41 @@ 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;
- if (!qemu_put_mouse_event_current) {
+ if (QTAILQ_EMPTY(&mouse_handlers)) {
return;
}
- mouse_event =
- qemu_put_mouse_event_current->qemu_put_mouse_event;
- mouse_event_opaque =
- qemu_put_mouse_event_current->qemu_put_mouse_event_opaque;
+ entry = QTAILQ_FIRST(&mouse_handlers);
+
+ mouse_event = entry->qemu_put_mouse_event;
+ mouse_event_opaque = entry->qemu_put_mouse_event_opaque;
if (mouse_event) {
if (graphic_rotate) {
- if (qemu_put_mouse_event_current->qemu_put_mouse_event_absolute)
+ if (entry->qemu_put_mouse_event_absolute)
width = 0x7fff;
else
width = graphic_width - 1;
mouse_event(mouse_event_opaque,
- width - dy, dx, dz, buttons_state);
+ width - dy, dx, dz, buttons_state);
} else
mouse_event(mouse_event_opaque,
- dx, dy, dz, buttons_state);
+ dx, dy, dz, buttons_state);
}
}
int kbd_mouse_is_absolute(void)
{
- if (!qemu_put_mouse_event_current)
+ if (QTAILQ_EMPTY(&mouse_handlers)) {
return 0;
+ }
- return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute;
+ return QTAILQ_FIRST(&mouse_handlers)->qemu_put_mouse_event_absolute;
}
static void info_mice_iter(QObject *data, void *opaque)
@@ -222,23 +198,23 @@ void do_info_mice(Monitor *mon, QObject **ret_data)
{
QEMUPutMouseEntry *cursor;
QList *mice_list;
- int index = 0;
+ int current;
mice_list = qlist_new();
- if (!qemu_put_mouse_event_head) {
+ if (QTAILQ_EMPTY(&mouse_handlers)) {
goto out;
}
- cursor = qemu_put_mouse_event_head;
- while (cursor != NULL) {
+ current = QTAILQ_FIRST(&mouse_handlers)->index;
+
+ QTAILQ_FOREACH(cursor, &mouse_handlers, node) {
QObject *obj;
obj = qobject_from_jsonf("{ 'name': %s, 'index': %d, 'current': %i }",
cursor->qemu_put_mouse_event_name,
- index, cursor == qemu_put_mouse_event_current);
+ cursor->index,
+ cursor->index == current);
qlist_append_obj(mice_list, obj);
- index++;
- cursor = cursor->next;
}
out:
@@ -248,22 +224,23 @@ out:
void do_mouse_set(Monitor *mon, const QDict *qdict)
{
QEMUPutMouseEntry *cursor;
- int i = 0;
int index = qdict_get_int(qdict, "index");
+ int found = 0;
- if (!qemu_put_mouse_event_head) {
+ if (QTAILQ_EMPTY(&mouse_handlers)) {
monitor_printf(mon, "No mouse devices connected\n");
return;
}
- cursor = qemu_put_mouse_event_head;
- while (cursor != NULL && index != i) {
- i++;
- cursor = cursor->next;
+ QTAILQ_FOREACH(cursor, &mouse_handlers, node) {
+ if (cursor->index == index) {
+ found = 1;
+ qemu_activate_mouse_event_handler(cursor);
+ break;
+ }
}
- if (cursor != NULL)
- qemu_put_mouse_event_current = cursor;
- else
+ if (!found) {
monitor_printf(mon, "Mouse at given index not found\n");
+ }
}
--
1.6.5.2
next prev parent reply other threads:[~2010-03-15 20:34 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-03-15 20:34 [Qemu-devel] [PATCH 1/7] Add support for generic notifier lists (v2) Anthony Liguori
2010-03-15 20:34 ` Anthony Liguori [this message]
2010-03-15 20:34 ` [Qemu-devel] [PATCH 3/7] Add kbd_mouse_has_absolute() Anthony Liguori
2010-03-15 20:34 ` [Qemu-devel] [PATCH 4/7] Add notifier for mouse mode changes Anthony Liguori
2010-03-15 20:34 ` [Qemu-devel] [PATCH 5/7] Expose whether a mouse is an absolute device via QMP and the human monitor Anthony Liguori
2010-03-15 20:34 ` [Qemu-devel] [PATCH 6/7] input: make vnc use mouse mode notifiers Anthony Liguori
2010-03-15 20:34 ` [Qemu-devel] [PATCH 7/7] sdl: use mouse mode notifier Anthony Liguori
2010-03-16 9:38 ` [Qemu-devel] Re: [PATCH 1/7] Add support for generic notifier lists (v2) Avi Kivity
2010-03-16 13:20 ` Juan Quintela
-- strict thread matches above, loose matches on Subject: below --
2010-03-10 16:51 [Qemu-devel] [PATCH 1/7] Add support for generic notifier lists Anthony Liguori
2010-03-10 16:51 ` [Qemu-devel] [PATCH 2/7] Rewrite mouse handlers to use QTAILQ and to have an activation function Anthony Liguori
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1268685268-16881-2-git-send-email-aliguori@us.ibm.com \
--to=aliguori@us.ibm.com \
--cc=avi@redhat.com \
--cc=kraxel@redhat.com \
--cc=lcapitulino@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).