qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 1/7] Add support for generic notifier lists (v2)
@ 2010-03-15 20:34 Anthony Liguori
  2010-03-15 20:34 ` [Qemu-devel] [PATCH 2/7] Rewrite mouse handlers to use QTAILQ and to have an activation function Anthony Liguori
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Anthony Liguori @ 2010-03-15 20:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Avi Kivity, Anthony Liguori, Gerd Hoffman, Luiz Capitulino

Notifiers are data-less callbacks and a notifier list is a list of registered
notifiers that all are interested in a particular event.

We'll use this in a few patches to implement mouse change notification.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
v1 -> v2
 - Do not do memory allocations by placing list nodes in notifier
---
 Makefile.objs |    1 +
 notify.c      |   39 +++++++++++++++++++++++++++++++++++++++
 notify.h      |   43 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 83 insertions(+), 0 deletions(-)
 create mode 100644 notify.c
 create mode 100644 notify.h

diff --git a/Makefile.objs b/Makefile.objs
index e791dd5..dcb5a92 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -104,6 +104,7 @@ common-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o
 common-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o
 common-obj-$(CONFIG_COCOA) += cocoa.o
 common-obj-$(CONFIG_IOTHREAD) += qemu-thread.o
+common-obj-y += notify.o
 
 slirp-obj-y = cksum.o if.o ip_icmp.o ip_input.o ip_output.o
 slirp-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o
diff --git a/notify.c b/notify.c
new file mode 100644
index 0000000..bcd3fc5
--- /dev/null
+++ b/notify.c
@@ -0,0 +1,39 @@
+/*
+ * Notifier lists
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu-common.h"
+#include "notify.h"
+
+void notifier_list_init(NotifierList *list)
+{
+    QTAILQ_INIT(&list->notifiers);
+}
+
+void notifier_list_add(NotifierList *list, Notifier *notifier)
+{
+    QTAILQ_INSERT_HEAD(&list->notifiers, notifier, node);
+}
+
+void notifier_list_remove(NotifierList *list, Notifier *notifier)
+{
+    QTAILQ_REMOVE(&list->notifiers, notifier, node);
+}
+
+void notifier_list_notify(NotifierList *list)
+{
+    Notifier *notifier, *next;
+
+    QTAILQ_FOREACH_SAFE(notifier, &list->notifiers, node, next) {
+        notifier->notify(notifier);
+    }
+}
diff --git a/notify.h b/notify.h
new file mode 100644
index 0000000..b40522f
--- /dev/null
+++ b/notify.h
@@ -0,0 +1,43 @@
+/*
+ * Notifier lists
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_NOTIFY_H
+#define QEMU_NOTIFY_H
+
+#include "qemu-queue.h"
+
+typedef struct Notifier Notifier;
+
+struct Notifier
+{
+    void (*notify)(Notifier *notifier);
+    QTAILQ_ENTRY(Notifier) node;
+};
+
+typedef struct NotifierList
+{
+    QTAILQ_HEAD(, Notifier) notifiers;
+} NotifierList;
+
+#define NOTIFIER_LIST_INITIALIZER(head) \
+    { QTAILQ_HEAD_INITIALIZER((head).notifiers) }
+
+void notifier_list_init(NotifierList *list);
+
+void notifier_list_add(NotifierList *list, Notifier *notifier);
+
+void notifier_list_remove(NotifierList *list, Notifier *notifier);
+
+void notifier_list_notify(NotifierList *list);
+
+#endif
-- 
1.6.5.2

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 2/7] Rewrite mouse handlers to use QTAILQ and to have an activation function
  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
  2010-03-15 20:34 ` [Qemu-devel] [PATCH 3/7] Add kbd_mouse_has_absolute() Anthony Liguori
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Anthony Liguori @ 2010-03-15 20:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Avi Kivity, Anthony Liguori, Gerd Hoffman, Luiz Capitulino

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

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 3/7] Add kbd_mouse_has_absolute()
  2010-03-15 20:34 [Qemu-devel] [PATCH 1/7] Add support for generic notifier lists (v2) Anthony Liguori
  2010-03-15 20:34 ` [Qemu-devel] [PATCH 2/7] Rewrite mouse handlers to use QTAILQ and to have an activation function Anthony Liguori
@ 2010-03-15 20:34 ` Anthony Liguori
  2010-03-15 20:34 ` [Qemu-devel] [PATCH 4/7] Add notifier for mouse mode changes Anthony Liguori
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Anthony Liguori @ 2010-03-15 20:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Avi Kivity, Anthony Liguori, Gerd Hoffman, Luiz Capitulino

kbd_mouse_is_absolute tells us whether the current mouse handler is an absolute
device.  kbd_mouse_has_absolute tells us whether we have any device that is
capable of absolute input.

This lets us tell a user that they have configured an absolute device but that
the guest is not currently using it.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 console.h |    5 +++++
 input.c   |   13 +++++++++++++
 2 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/console.h b/console.h
index 94d9cae..f3c619f 100644
--- a/console.h
+++ b/console.h
@@ -53,8 +53,13 @@ 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);
+
+/* Does the current mouse generate absolute events */
 int kbd_mouse_is_absolute(void);
 
+/* Of all the mice, is there one that generates absolute events */
+int kbd_mouse_has_absolute(void);
+
 struct MouseTransformInfo {
     /* Touchscreen resolution */
     int x;
diff --git a/input.c b/input.c
index 397bfc5..8d5a14d 100644
--- a/input.c
+++ b/input.c
@@ -153,6 +153,19 @@ int kbd_mouse_is_absolute(void)
     return QTAILQ_FIRST(&mouse_handlers)->qemu_put_mouse_event_absolute;
 }
 
+int kbd_mouse_has_absolute(void)
+{
+    QEMUPutMouseEntry *entry;
+
+    QTAILQ_FOREACH(entry, &mouse_handlers, node) {
+        if (entry->qemu_put_mouse_event_absolute) {
+            return 1;
+        }
+    }
+
+    return 0;
+}
+
 static void info_mice_iter(QObject *data, void *opaque)
 {
     QDict *mouse;
-- 
1.6.5.2

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 4/7] Add notifier for mouse mode changes
  2010-03-15 20:34 [Qemu-devel] [PATCH 1/7] Add support for generic notifier lists (v2) Anthony Liguori
  2010-03-15 20:34 ` [Qemu-devel] [PATCH 2/7] Rewrite mouse handlers to use QTAILQ and to have an activation function Anthony Liguori
  2010-03-15 20:34 ` [Qemu-devel] [PATCH 3/7] Add kbd_mouse_has_absolute() Anthony Liguori
@ 2010-03-15 20:34 ` 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
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Anthony Liguori @ 2010-03-15 20:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Avi Kivity, Anthony Liguori, Gerd Hoffman, Luiz Capitulino

Right now, DisplayState clients rely on polling the mouse mode to determine
when the device is changed to an absolute device.  Use a notification list to
add an explicit notification.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 console.h |    3 +++
 input.c   |   37 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 39 insertions(+), 1 deletions(-)

diff --git a/console.h b/console.h
index f3c619f..6def115 100644
--- a/console.h
+++ b/console.h
@@ -3,6 +3,7 @@
 
 #include "qemu-char.h"
 #include "qdict.h"
+#include "notify.h"
 
 /* keyboard/mouse support */
 
@@ -56,6 +57,8 @@ 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);
+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);
diff --git a/input.c b/input.c
index 8d5a14d..c956e06 100644
--- a/input.c
+++ b/input.c
@@ -28,12 +28,13 @@
 #include "console.h"
 #include "qjson.h"
 
-
 static QEMUPutKBDEvent *qemu_put_kbd_event;
 static void *qemu_put_kbd_event_opaque;
 static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers = QTAILQ_HEAD_INITIALIZER(led_handlers);
 static QTAILQ_HEAD(, QEMUPutMouseEntry) mouse_handlers =
     QTAILQ_HEAD_INITIALIZER(mouse_handlers);
+static NotifierList mouse_mode_notifiers = 
+    NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers);
 
 void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
 {
@@ -41,6 +42,24 @@ void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
     qemu_put_kbd_event = func;
 }
 
+static void check_mode_change(void)
+{
+    static int current_is_absolute, current_has_absolute;
+    int is_absolute;
+    int has_absolute;
+
+    is_absolute = kbd_mouse_is_absolute();
+    has_absolute = kbd_mouse_has_absolute();
+
+    if (is_absolute != current_is_absolute ||
+        has_absolute != current_has_absolute) {
+        notifier_list_notify(&mouse_mode_notifiers);
+    }
+
+    current_is_absolute = is_absolute;
+    current_has_absolute = has_absolute;
+}
+
 QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
                                                 void *opaque, int absolute,
                                                 const char *name)
@@ -58,6 +77,8 @@ QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
 
     QTAILQ_INSERT_TAIL(&mouse_handlers, s, node);
 
+    check_mode_change();
+
     return s;
 }
 
@@ -75,6 +96,8 @@ void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
 
     qemu_free(entry->qemu_put_mouse_event_name);
     qemu_free(entry);
+
+    check_mode_change();
 }
 
 QEMUPutLEDEntry *qemu_add_led_event_handler(QEMUPutLEDEvent *func,
@@ -256,4 +279,16 @@ void do_mouse_set(Monitor *mon, const QDict *qdict)
     if (!found) {
         monitor_printf(mon, "Mouse at given index not found\n");
     }
+
+    check_mode_change();
+}
+
+void qemu_add_mouse_mode_change_notifier(Notifier *notify)
+{
+    notifier_list_add(&mouse_mode_notifiers, notify);
+}
+
+void qemu_remove_mouse_mode_change_notifier(Notifier *notify)
+{
+    notifier_list_remove(&mouse_mode_notifiers, notify);
 }
-- 
1.6.5.2

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 5/7] Expose whether a mouse is an absolute device via QMP and the human monitor.
  2010-03-15 20:34 [Qemu-devel] [PATCH 1/7] Add support for generic notifier lists (v2) Anthony Liguori
                   ` (2 preceding siblings ...)
  2010-03-15 20:34 ` [Qemu-devel] [PATCH 4/7] Add notifier for mouse mode changes Anthony Liguori
@ 2010-03-15 20:34 ` Anthony Liguori
  2010-03-15 20:34 ` [Qemu-devel] [PATCH 6/7] input: make vnc use mouse mode notifiers Anthony Liguori
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Anthony Liguori @ 2010-03-15 20:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Avi Kivity, Anthony Liguori, Gerd Hoffman, Luiz Capitulino

For QMP, we just add an attribute which is backwards compatible.  For the human
monitor, we add (absolute) to the end of the line.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 input.c |   18 ++++++++++++------
 1 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/input.c b/input.c
index c956e06..8f0941e 100644
--- a/input.c
+++ b/input.c
@@ -195,9 +195,10 @@ static void info_mice_iter(QObject *data, void *opaque)
     Monitor *mon = opaque;
 
     mouse = qobject_to_qdict(data);
-    monitor_printf(mon, "%c Mouse #%" PRId64 ": %s\n",
+    monitor_printf(mon, "%c Mouse #%" PRId64 ": %s%s\n",
                   (qdict_get_bool(mouse, "current") ? '*' : ' '),
-                  qdict_get_int(mouse, "index"), qdict_get_str(mouse, "name"));
+                   qdict_get_int(mouse, "index"), qdict_get_str(mouse, "name"),
+                   qdict_get_bool(mouse, "absolute") ? " (absolute)" : "");
 }
 
 void do_info_mice_print(Monitor *mon, const QObject *data)
@@ -224,11 +225,12 @@ void do_info_mice_print(Monitor *mon, const QObject *data)
  * - "name": mouse's name
  * - "index": mouse's index
  * - "current": true if this mouse is receiving events, false otherwise
+ * - "absolute": true if the mouse generates absolute input events
  *
  * Example:
  *
- * [ { "name": "QEMU Microsoft Mouse", "index": 0, "current": false },
- *   { "name": "QEMU PS/2 Mouse", "index": 1, "current": true } ]
+ * [ { "name": "QEMU Microsoft Mouse", "index": 0, "current": false, "absolute": false },
+ *   { "name": "QEMU PS/2 Mouse", "index": 1, "current": true, "absolute": true } ]
  */
 void do_info_mice(Monitor *mon, QObject **ret_data)
 {
@@ -246,10 +248,14 @@ void do_info_mice(Monitor *mon, QObject **ret_data)
 
     QTAILQ_FOREACH(cursor, &mouse_handlers, node) {
         QObject *obj;
-        obj = qobject_from_jsonf("{ 'name': %s, 'index': %d, 'current': %i }",
+        obj = qobject_from_jsonf("{ 'name': %s,"
+                                 "  'index': %d,"
+                                 "  'current': %i,"
+                                 "  'absolute': %i }",
                                  cursor->qemu_put_mouse_event_name,
                                  cursor->index,
-                                 cursor->index == current);
+                                 cursor->index == current,
+                                 !!cursor->qemu_put_mouse_event_absolute);
         qlist_append_obj(mice_list, obj);
     }
 
-- 
1.6.5.2

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 6/7] input: make vnc use mouse mode notifiers
  2010-03-15 20:34 [Qemu-devel] [PATCH 1/7] Add support for generic notifier lists (v2) Anthony Liguori
                   ` (3 preceding siblings ...)
  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 ` Anthony Liguori
  2010-03-15 20:34 ` [Qemu-devel] [PATCH 7/7] sdl: use mouse mode notifier Anthony Liguori
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Anthony Liguori @ 2010-03-15 20:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Avi Kivity, Anthony Liguori, Gerd Hoffman, Luiz Capitulino

When we switch to absolute mode, we send out a notification (if the client
supports it).  Today, we only send this notification when the client sends us
a mouse event and we're in the wrong mode.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 vnc.c |   13 ++++++++-----
 vnc.h |    2 ++
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/vnc.c b/vnc.c
index 7ce73dc..14ded6c 100644
--- a/vnc.c
+++ b/vnc.c
@@ -1110,6 +1110,7 @@ static void vnc_disconnect_finish(VncState *vs)
         dcl->idle = 1;
     }
 
+    qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
     vnc_remove_timer(vs->vd);
     qemu_remove_led_event_handler(vs->led);
     qemu_free(vs);
@@ -1427,8 +1428,11 @@ static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
 {
 }
 
-static void check_pointer_type_change(VncState *vs, int absolute)
+static void check_pointer_type_change(Notifier *notifier)
 {
+    VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
+    int absolute = kbd_mouse_is_absolute();
+
     if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
         vnc_write_u8(vs, 0);
         vnc_write_u8(vs, 0);
@@ -1474,8 +1478,6 @@ static void pointer_event(VncState *vs, int button_mask, int x, int y)
         vs->last_x = x;
         vs->last_y = y;
     }
-
-    check_pointer_type_change(vs, kbd_mouse_is_absolute());
 }
 
 static void reset_keys(VncState *vs)
@@ -1814,8 +1816,6 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
             break;
         }
     }
-
-    check_pointer_type_change(vs, kbd_mouse_is_absolute());
 }
 
 static void set_pixel_conversion(VncState *vs)
@@ -2431,6 +2431,9 @@ static void vnc_connect(VncDisplay *vd, int csock)
     reset_keys(vs);
     vs->led = qemu_add_led_event_handler(kbd_leds, vs);
 
+    vs->mouse_mode_notifier.notify = check_pointer_type_change;
+    qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
+
     vnc_init_timer(vd);
 
     /* vs might be free()ed here */
diff --git a/vnc.h b/vnc.h
index 0fc89bd..8052000 100644
--- a/vnc.h
+++ b/vnc.h
@@ -167,6 +167,8 @@ struct VncState
     Buffer zlib_tmp;
     z_stream zlib_stream[4];
 
+    Notifier mouse_mode_notifier;
+
     QTAILQ_ENTRY(VncState) next;
 };
 
-- 
1.6.5.2

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 7/7] sdl: use mouse mode notifier
  2010-03-15 20:34 [Qemu-devel] [PATCH 1/7] Add support for generic notifier lists (v2) Anthony Liguori
                   ` (4 preceding siblings ...)
  2010-03-15 20:34 ` [Qemu-devel] [PATCH 6/7] input: make vnc use mouse mode notifiers Anthony Liguori
@ 2010-03-15 20:34 ` 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
  7 siblings, 0 replies; 9+ messages in thread
From: Anthony Liguori @ 2010-03-15 20:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Avi Kivity, Anthony Liguori, Gerd Hoffman, Luiz Capitulino

Today we poll the mouse mode whenever there is a mouse movement.  There is a
subtle usability problem with this though.

If we're in relative mode and grab is enabled, when we change to absolute mode,
we break grab.  This gives a user a seamless transition when the new pointer
is enabled.

But because we poll for mouse change, this grab break won't occur until the user
attempts to move the mouse.  By using notifiers, the grab break happens as soon
as possible.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 sdl.c |   31 ++++++++++++++++++++-----------
 1 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/sdl.c b/sdl.c
index 1d1e100..e9edbcc 100644
--- a/sdl.c
+++ b/sdl.c
@@ -57,6 +57,7 @@ static SDL_Cursor *guest_sprite = NULL;
 static uint8_t allocator;
 static SDL_PixelFormat host_format;
 static int scaling_active = 0;
+static Notifier mouse_mode_notifier;
 
 static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
 {
@@ -485,6 +486,22 @@ static void sdl_grab_end(void)
     sdl_update_caption();
 }
 
+static void sdl_mouse_mode_change(Notifier *notify)
+{
+    if (kbd_mouse_is_absolute()) {
+        if (!absolute_enabled) {
+            sdl_hide_cursor();
+            if (gui_grab) {
+                sdl_grab_end();
+            }
+            absolute_enabled = 1;
+        }
+    } else if (absolute_enabled) {
+	sdl_show_cursor();
+	absolute_enabled = 0;
+    }
+}
+
 static void sdl_send_mouse_event(int dx, int dy, int dz, int x, int y, int state)
 {
     int buttons;
@@ -497,19 +514,8 @@ static void sdl_send_mouse_event(int dx, int dy, int dz, int x, int y, int state
         buttons |= MOUSE_EVENT_MBUTTON;
 
     if (kbd_mouse_is_absolute()) {
-	if (!absolute_enabled) {
-	    sdl_hide_cursor();
-	    if (gui_grab) {
-		sdl_grab_end();
-	    }
-	    absolute_enabled = 1;
-	}
-
        dx = x * 0x7FFF / (width - 1);
        dy = y * 0x7FFF / (height - 1);
-    } else if (absolute_enabled) {
-	sdl_show_cursor();
-	absolute_enabled = 0;
     } else if (guest_cursor) {
         x -= guest_x;
         y -= guest_y;
@@ -875,6 +881,9 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
         dpy_resize(ds);
     }
 
+    mouse_mode_notifier.notify = sdl_mouse_mode_change;
+    qemu_add_mouse_mode_change_notifier(&mouse_mode_notifier);
+
     sdl_update_caption();
     SDL_EnableKeyRepeat(250, 50);
     gui_grab = 0;
-- 
1.6.5.2

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] Re: [PATCH 1/7] Add support for generic notifier lists (v2)
  2010-03-15 20:34 [Qemu-devel] [PATCH 1/7] Add support for generic notifier lists (v2) Anthony Liguori
                   ` (5 preceding siblings ...)
  2010-03-15 20:34 ` [Qemu-devel] [PATCH 7/7] sdl: use mouse mode notifier Anthony Liguori
@ 2010-03-16  9:38 ` Avi Kivity
  2010-03-16 13:20 ` Juan Quintela
  7 siblings, 0 replies; 9+ messages in thread
From: Avi Kivity @ 2010-03-16  9:38 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Gerd Hoffman, qemu-devel, Luiz Capitulino

On 03/15/2010 10:34 PM, Anthony Liguori wrote:
> Notifiers are data-less callbacks and a notifier list is a list of registered
> notifiers that all are interested in a particular event.
>
> We'll use this in a few patches to implement mouse change notification.
>    

Looks nicer & lighter!

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Qemu-devel] Re: [PATCH 1/7] Add support for generic notifier lists (v2)
  2010-03-15 20:34 [Qemu-devel] [PATCH 1/7] Add support for generic notifier lists (v2) Anthony Liguori
                   ` (6 preceding siblings ...)
  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
  7 siblings, 0 replies; 9+ messages in thread
From: Juan Quintela @ 2010-03-16 13:20 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Luiz Capitulino, Gerd Hoffman, qemu-devel, Avi Kivity

Anthony Liguori <aliguori@us.ibm.com> wrote:
> Notifiers are data-less callbacks and a notifier list is a list of registered
> notifiers that all are interested in a particular event.
>
> We'll use this in a few patches to implement mouse change notification.

We could use that for migration also.

spice just needs to have start/end migration happening.  And block
migration added a new callback that is basically call this on start.

Later, Juan.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2010-03-16 13:20 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-03-15 20:34 [Qemu-devel] [PATCH 1/7] Add support for generic notifier lists (v2) Anthony Liguori
2010-03-15 20:34 ` [Qemu-devel] [PATCH 2/7] Rewrite mouse handlers to use QTAILQ and to have an activation function Anthony Liguori
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

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