All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v4 00/10] initial spice support.
@ 2010-08-27  9:59 Gerd Hoffmann
  2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 01/10] Use display types for local display only Gerd Hoffmann
                   ` (10 more replies)
  0 siblings, 11 replies; 20+ messages in thread
From: Gerd Hoffmann @ 2010-08-27  9:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

  Hi,

Here comes v4 of the iniial spice support patch series, hopefully the
final version.  It brings just the very basic bits:

 * Detect spice in configure, Makefile windup.
 * Support for keyboard, mouse and tablet.
 * Support for simple display output (works as DisplayChangeListener,
   plays with any gfx card, sends simple draw commands to update
   dirty regions).

Note that this patch series does *not* yet contain the qxl paravirtual
gfx card.  That will come as part of a additional patch series after
sorting the vgabios support.

The patches are also available in the git repository at:
  git://anongit.freedesktop.org/spice/qemu submit.4

Changes since v3:
  * Drop global spice_server variable, provide a thin wrapper function
    instead so spice interfaces can be registered without needing
    spice_server.
  * Update locking comments.

Changes since v2:
  * Add copyright headers to the files.
  * Add dprint for debug logging.
  * Add mapping for buttons and leds.
  * Add comments for locking+threads.
  * Drop includes which qemu-common.h brings in.
  * Compile -spice switch unconditionally.
  * Hook up spice init using module.h, drop #ifdefs.
  * Misc minor tweaks.

Gerd Hoffmann (10):
  Use display types for local display only.
  Use machine_init() to register virtfs config options.
  add pflib: PixelFormat conversion library.
  configure: add logging
  add spice into the configure file
  spice: core bits
  spice: add keyboard
  spice: add mouse
  spice: simple display
  spice: add tablet support

 Makefile.objs      |    3 +
 configure          |   42 +++++-
 fsdev/qemu-fsdev.c |    9 +
 pflib.c            |  213 +++++++++++++++++++++++++++
 pflib.h            |   20 +++
 qemu-config.c      |   18 +++
 qemu-config.h      |    1 +
 qemu-options.hx    |   21 +++
 sysemu.h           |    1 -
 ui/qemu-spice.h    |   41 +++++
 ui/spice-core.c    |  183 +++++++++++++++++++++++
 ui/spice-display.c |  410 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 ui/spice-display.h |   69 +++++++++
 ui/spice-input.c   |  208 ++++++++++++++++++++++++++
 vl.c               |   49 ++++--
 15 files changed, 1269 insertions(+), 19 deletions(-)
 create mode 100644 pflib.c
 create mode 100644 pflib.h
 create mode 100644 ui/qemu-spice.h
 create mode 100644 ui/spice-core.c
 create mode 100644 ui/spice-display.c
 create mode 100644 ui/spice-display.h
 create mode 100644 ui/spice-input.c

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

* [Qemu-devel] [PATCH v4 01/10] Use display types for local display only.
  2010-08-27  9:59 [Qemu-devel] [PATCH v4 00/10] initial spice support Gerd Hoffmann
@ 2010-08-27  9:59 ` Gerd Hoffmann
  2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 02/10] Use machine_init() to register virtfs config options Gerd Hoffmann
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Gerd Hoffmann @ 2010-08-27  9:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

This patch drops DT_VNC.  The display types are only used to select
select the local display (i.e. curses, sdl, coca, ...).  Remote
displays (for now only vnc, spice will follow) can be enabled
independently.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 sysemu.h |    1 -
 vl.c     |   24 +++++++++++++-----------
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/sysemu.h b/sysemu.h
index a1f6466..b81a70e 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -94,7 +94,6 @@ typedef enum DisplayType
     DT_DEFAULT,
     DT_CURSES,
     DT_SDL,
-    DT_VNC,
     DT_NOGRAPHIC,
 } DisplayType;
 
diff --git a/vl.c b/vl.c
index 91d1684..d90b275 100644
--- a/vl.c
+++ b/vl.c
@@ -172,6 +172,7 @@ static const char *data_dir;
 const char *bios_name = NULL;
 enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
 DisplayType display_type = DT_DEFAULT;
+int display_remote = 0;
 const char* keyboard_layout = NULL;
 ram_addr_t ram_size;
 const char *mem_path = NULL;
@@ -2468,7 +2469,7 @@ int main(int argc, char **argv, char **envp)
                 }
                 break;
 	    case QEMU_OPTION_vnc:
-                display_type = DT_VNC;
+                display_remote++;
 		vnc_display = optarg;
 		break;
             case QEMU_OPTION_no_acpi:
@@ -2898,17 +2899,17 @@ int main(int argc, char **argv, char **envp)
     /* just use the first displaystate for the moment */
     ds = get_displaystate();
 
-    if (display_type == DT_DEFAULT) {
+    if (display_type == DT_DEFAULT && !display_remote) {
 #if defined(CONFIG_SDL) || defined(CONFIG_COCOA)
         display_type = DT_SDL;
 #else
-        display_type = DT_VNC;
         vnc_display = "localhost:0,to=99";
         show_vnc_port = 1;
 #endif
     }
         
 
+    /* init local displays */
     switch (display_type) {
     case DT_NOGRAPHIC:
         break;
@@ -2926,7 +2927,12 @@ int main(int argc, char **argv, char **envp)
         cocoa_display_init(ds, full_screen);
         break;
 #endif
-    case DT_VNC:
+    default:
+        break;
+    }
+
+    /* init remote displays */
+    if (vnc_display) {
         vnc_display_init(ds);
         if (vnc_display_open(ds, vnc_display) < 0)
             exit(1);
@@ -2934,12 +2940,10 @@ int main(int argc, char **argv, char **envp)
         if (show_vnc_port) {
             printf("VNC server running on `%s'\n", vnc_display_local_addr(ds));
         }
-        break;
-    default:
-        break;
     }
-    dpy_resize(ds);
 
+    /* display setup */
+    dpy_resize(ds);
     dcl = ds->listeners;
     while (dcl != NULL) {
         if (dcl->dpy_refresh != NULL) {
@@ -2949,12 +2953,10 @@ int main(int argc, char **argv, char **envp)
         }
         dcl = dcl->next;
     }
-
-    if (display_type == DT_NOGRAPHIC || display_type == DT_VNC) {
+    if (ds->gui_timer == NULL) {
         nographic_timer = qemu_new_timer(rt_clock, nographic_update, NULL);
         qemu_mod_timer(nographic_timer, qemu_get_clock(rt_clock));
     }
-
     text_consoles_set_display(ds);
 
     if (gdbstub_dev && gdbserver_start(gdbstub_dev) < 0) {
-- 
1.7.1

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

* [Qemu-devel] [PATCH v4 02/10] Use machine_init() to register virtfs config options.
  2010-08-27  9:59 [Qemu-devel] [PATCH v4 00/10] initial spice support Gerd Hoffmann
  2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 01/10] Use display types for local display only Gerd Hoffmann
@ 2010-08-27  9:59 ` Gerd Hoffmann
  2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 03/10] add pflib: PixelFormat conversion library Gerd Hoffmann
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Gerd Hoffmann @ 2010-08-27  9:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann


Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 fsdev/qemu-fsdev.c |    9 +++++++++
 vl.c               |    5 -----
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/fsdev/qemu-fsdev.c b/fsdev/qemu-fsdev.c
index ad69b0e..280b8f5 100644
--- a/fsdev/qemu-fsdev.c
+++ b/fsdev/qemu-fsdev.c
@@ -16,6 +16,7 @@
 #include "qemu-queue.h"
 #include "osdep.h"
 #include "qemu-common.h"
+#include "qemu-config.h"
 
 static QTAILQ_HEAD(FsTypeEntry_head, FsTypeListEntry) fstype_entries =
     QTAILQ_HEAD_INITIALIZER(fstype_entries);
@@ -75,3 +76,11 @@ FsTypeEntry *get_fsdev_fsentry(char *id)
     }
     return NULL;
 }
+
+static void fsdev_register_config(void)
+{
+    qemu_add_opts(&qemu_fsdev_opts);
+    qemu_add_opts(&qemu_virtfs_opts);
+}
+machine_init(fsdev_register_config);
+
diff --git a/vl.c b/vl.c
index d90b275..40bf30b 100644
--- a/vl.c
+++ b/vl.c
@@ -1856,11 +1856,6 @@ int main(int argc, char **argv, char **envp)
     tb_size = 0;
     autostart= 1;
 
-#ifdef CONFIG_VIRTFS
-    qemu_add_opts(&qemu_fsdev_opts);
-    qemu_add_opts(&qemu_virtfs_opts);
-#endif
-
     /* first pass of option parsing */
     optind = 1;
     while (optind < argc) {
-- 
1.7.1

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

* [Qemu-devel] [PATCH v4 03/10] add pflib: PixelFormat conversion library.
  2010-08-27  9:59 [Qemu-devel] [PATCH v4 00/10] initial spice support Gerd Hoffmann
  2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 01/10] Use display types for local display only Gerd Hoffmann
  2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 02/10] Use machine_init() to register virtfs config options Gerd Hoffmann
@ 2010-08-27  9:59 ` Gerd Hoffmann
  2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 04/10] configure: add logging Gerd Hoffmann
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Gerd Hoffmann @ 2010-08-27  9:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann


Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 Makefile.objs |    1 +
 pflib.c       |  213 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 pflib.h       |   20 ++++++
 3 files changed, 234 insertions(+), 0 deletions(-)
 create mode 100644 pflib.c
 create mode 100644 pflib.h

diff --git a/Makefile.objs b/Makefile.objs
index 4a1eaa1..edfca87 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -83,6 +83,7 @@ common-obj-y += qemu-char.o savevm.o #aio.o
 common-obj-y += msmouse.o ps2.o
 common-obj-y += qdev.o qdev-properties.o
 common-obj-y += block-migration.o
+common-obj-y += pflib.o
 
 common-obj-$(CONFIG_BRLAPI) += baum.o
 common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
diff --git a/pflib.c b/pflib.c
new file mode 100644
index 0000000..1154d0c
--- /dev/null
+++ b/pflib.c
@@ -0,0 +1,213 @@
+/*
+ * PixelFormat conversion library.
+ *
+ * Author: Gerd Hoffmann <kraxel@redhat.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 "console.h"
+#include "pflib.h"
+
+typedef struct QemuPixel QemuPixel;
+
+typedef void (*pf_convert)(QemuPfConv *conv,
+                           void *dst, void *src, uint32_t cnt);
+typedef void (*pf_convert_from)(PixelFormat *pf,
+                                QemuPixel *dst, void *src, uint32_t cnt);
+typedef void (*pf_convert_to)(PixelFormat *pf,
+                              void *dst, QemuPixel *src, uint32_t cnt);
+
+struct QemuPfConv {
+    pf_convert        convert;
+    PixelFormat       src;
+    PixelFormat       dst;
+
+    /* for copy_generic() */
+    pf_convert_from   conv_from;
+    pf_convert_to     conv_to;
+    QemuPixel         *conv_buf;
+    uint32_t          conv_cnt;
+};
+
+struct QemuPixel {
+    uint8_t red;
+    uint8_t green;
+    uint8_t blue;
+    uint8_t alpha;
+};
+
+/* ----------------------------------------------------------------------- */
+/* PixelFormat -> QemuPixel conversions                                    */
+
+static void conv_16_to_pixel(PixelFormat *pf,
+                             QemuPixel *dst, void *src, uint32_t cnt)
+{
+    uint16_t *src16 = src;
+
+    while (cnt > 0) {
+        dst->red   = ((*src16 & pf->rmask) >> pf->rshift) << (8 - pf->rbits);
+        dst->green = ((*src16 & pf->gmask) >> pf->gshift) << (8 - pf->gbits);
+        dst->blue  = ((*src16 & pf->bmask) >> pf->bshift) << (8 - pf->bbits);
+        dst->alpha = ((*src16 & pf->amask) >> pf->ashift) << (8 - pf->abits);
+        dst++, src16++, cnt--;
+    }
+}
+
+/* assumes pf->{r,g,b,a}bits == 8 */
+static void conv_32_to_pixel_fast(PixelFormat *pf,
+                                  QemuPixel *dst, void *src, uint32_t cnt)
+{
+    uint32_t *src32 = src;
+
+    while (cnt > 0) {
+        dst->red   = (*src32 & pf->rmask) >> pf->rshift;
+        dst->green = (*src32 & pf->gmask) >> pf->gshift;
+        dst->blue  = (*src32 & pf->bmask) >> pf->bshift;
+        dst->alpha = (*src32 & pf->amask) >> pf->ashift;
+        dst++, src32++, cnt--;
+    }
+}
+
+static void conv_32_to_pixel_generic(PixelFormat *pf,
+                                     QemuPixel *dst, void *src, uint32_t cnt)
+{
+    uint32_t *src32 = src;
+
+    while (cnt > 0) {
+        if (pf->rbits < 8) {
+            dst->red   = ((*src32 & pf->rmask) >> pf->rshift) << (8 - pf->rbits);
+        } else {
+            dst->red   = ((*src32 & pf->rmask) >> pf->rshift) >> (pf->rbits - 8);
+        }
+        if (pf->gbits < 8) {
+            dst->green = ((*src32 & pf->gmask) >> pf->gshift) << (8 - pf->gbits);
+        } else {
+            dst->green = ((*src32 & pf->gmask) >> pf->gshift) >> (pf->gbits - 8);
+        }
+        if (pf->bbits < 8) {
+            dst->blue  = ((*src32 & pf->bmask) >> pf->bshift) << (8 - pf->bbits);
+        } else {
+            dst->blue  = ((*src32 & pf->bmask) >> pf->bshift) >> (pf->bbits - 8);
+        }
+        if (pf->abits < 8) {
+            dst->alpha = ((*src32 & pf->amask) >> pf->ashift) << (8 - pf->abits);
+        } else {
+            dst->alpha = ((*src32 & pf->amask) >> pf->ashift) >> (pf->abits - 8);
+        }
+        dst++, src32++, cnt--;
+    }
+}
+
+/* ----------------------------------------------------------------------- */
+/* QemuPixel -> PixelFormat conversions                                    */
+
+static void conv_pixel_to_16(PixelFormat *pf,
+                             void *dst, QemuPixel *src, uint32_t cnt)
+{
+    uint16_t *dst16 = dst;
+
+    while (cnt > 0) {
+        *dst16  = ((uint16_t)src->red   >> (8 - pf->rbits)) << pf->rshift;
+        *dst16 |= ((uint16_t)src->green >> (8 - pf->gbits)) << pf->gshift;
+        *dst16 |= ((uint16_t)src->blue  >> (8 - pf->bbits)) << pf->bshift;
+        *dst16 |= ((uint16_t)src->alpha >> (8 - pf->abits)) << pf->ashift;
+        dst16++, src++, cnt--;
+    }
+}
+
+static void conv_pixel_to_32(PixelFormat *pf,
+                             void *dst, QemuPixel *src, uint32_t cnt)
+{
+    uint32_t *dst32 = dst;
+
+    while (cnt > 0) {
+        *dst32  = ((uint32_t)src->red   >> (8 - pf->rbits)) << pf->rshift;
+        *dst32 |= ((uint32_t)src->green >> (8 - pf->gbits)) << pf->gshift;
+        *dst32 |= ((uint32_t)src->blue  >> (8 - pf->bbits)) << pf->bshift;
+        *dst32 |= ((uint32_t)src->alpha >> (8 - pf->abits)) << pf->ashift;
+        dst32++, src++, cnt--;
+    }
+}
+
+/* ----------------------------------------------------------------------- */
+/* PixelFormat -> PixelFormat conversions                                  */
+
+static void convert_copy(QemuPfConv *conv, void *dst, void *src, uint32_t cnt)
+{
+    uint32_t bytes = cnt * conv->src.bytes_per_pixel;
+    memcpy(dst, src, bytes);
+}
+
+static void convert_generic(QemuPfConv *conv, void *dst, void *src, uint32_t cnt)
+{
+    if (conv->conv_cnt < cnt) {
+        conv->conv_cnt = cnt;
+        conv->conv_buf = qemu_realloc(conv->conv_buf, sizeof(QemuPixel) * conv->conv_cnt);
+    }
+    conv->conv_from(&conv->src, conv->conv_buf, src, cnt);
+    conv->conv_to(&conv->dst, dst, conv->conv_buf, cnt);
+}
+
+/* ----------------------------------------------------------------------- */
+/* public interface                                                        */
+
+QemuPfConv *qemu_pf_conv_get(PixelFormat *dst, PixelFormat *src)
+{
+    QemuPfConv *conv = qemu_mallocz(sizeof(QemuPfConv));
+
+    conv->src = *src;
+    conv->dst = *dst;
+
+    if (memcmp(&conv->src, &conv->dst, sizeof(PixelFormat)) == 0) {
+        /* formats identical, can simply copy */
+        conv->convert = convert_copy;
+    } else {
+        /* generic two-step conversion: src -> QemuPixel -> dst  */
+        switch (conv->src.bytes_per_pixel) {
+        case 2:
+            conv->conv_from = conv_16_to_pixel;
+            break;
+        case 4:
+            if (conv->src.rbits == 8 && conv->src.gbits == 8 && conv->src.bbits == 8) {
+                conv->conv_from = conv_32_to_pixel_fast;
+            } else {
+                conv->conv_from = conv_32_to_pixel_generic;
+            }
+            break;
+        default:
+            goto err;
+        }
+        switch (conv->dst.bytes_per_pixel) {
+        case 2:
+            conv->conv_to = conv_pixel_to_16;
+            break;
+        case 4:
+            conv->conv_to = conv_pixel_to_32;
+            break;
+        default:
+            goto err;
+        }
+        conv->convert = convert_generic;
+    }
+    return conv;
+
+err:
+    qemu_free(conv);
+    return NULL;
+}
+
+void qemu_pf_conv_run(QemuPfConv *conv, void *dst, void *src, uint32_t cnt)
+{
+    conv->convert(conv, dst, src, cnt);
+}
+
+void qemu_pf_conv_put(QemuPfConv *conv)
+{
+    if (conv) {
+        qemu_free(conv->conv_buf);
+        qemu_free(conv);
+    }
+}
diff --git a/pflib.h b/pflib.h
new file mode 100644
index 0000000..b70c313
--- /dev/null
+++ b/pflib.h
@@ -0,0 +1,20 @@
+#ifndef __QEMU_PFLIB_H
+#define __QEMU_PFLIB_H
+
+/*
+ * PixelFormat conversion library.
+ *
+ * Author: Gerd Hoffmann <kraxel@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+typedef struct QemuPfConv QemuPfConv;
+
+QemuPfConv *qemu_pf_conv_get(PixelFormat *dst, PixelFormat *src);
+void qemu_pf_conv_run(QemuPfConv *conv, void *dst, void *src, uint32_t cnt);
+void qemu_pf_conv_put(QemuPfConv *conv);
+
+#endif
-- 
1.7.1

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

* [Qemu-devel] [PATCH v4 04/10] configure: add logging
  2010-08-27  9:59 [Qemu-devel] [PATCH v4 00/10] initial spice support Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 03/10] add pflib: PixelFormat conversion library Gerd Hoffmann
@ 2010-08-27  9:59 ` Gerd Hoffmann
  2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 05/10] add spice into the configure file Gerd Hoffmann
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Gerd Hoffmann @ 2010-08-27  9:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Write compile commands and messages to config.log.
Useful for debugging configure.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 configure |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index 146dac0..0639b33 100755
--- a/configure
+++ b/configure
@@ -16,15 +16,18 @@ TMPO="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.o"
 TMPE="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.exe"
 
 trap "rm -f $TMPC $TMPO $TMPE ; exit" EXIT INT QUIT TERM
+rm -f config.log
 
 compile_object() {
-  $cc $QEMU_CFLAGS -c -o $TMPO $TMPC > /dev/null 2> /dev/null
+  echo $cc $QEMU_CFLAGS -c -o $TMPO $TMPC >> config.log
+  $cc $QEMU_CFLAGS -c -o $TMPO $TMPC >> config.log 2>&1
 }
 
 compile_prog() {
   local_cflags="$1"
   local_ldflags="$2"
-  $cc $QEMU_CFLAGS $local_cflags -o $TMPE $TMPC $LDFLAGS $local_ldflags > /dev/null 2> /dev/null
+  echo $cc $QEMU_CFLAGS $local_cflags -o $TMPE $TMPC $LDFLAGS $local_ldflags >> config.log
+  $cc $QEMU_CFLAGS $local_cflags -o $TMPE $TMPC $LDFLAGS $local_ldflags >> config.log 2>&1
 }
 
 # check whether a command is available to this shell (may be either an
-- 
1.7.1

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

* [Qemu-devel] [PATCH v4 05/10] add spice into the configure file
  2010-08-27  9:59 [Qemu-devel] [PATCH v4 00/10] initial spice support Gerd Hoffmann
                   ` (3 preceding siblings ...)
  2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 04/10] configure: add logging Gerd Hoffmann
@ 2010-08-27  9:59 ` Gerd Hoffmann
  2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 06/10] spice: core bits Gerd Hoffmann
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Gerd Hoffmann @ 2010-08-27  9:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann


Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 configure |   35 +++++++++++++++++++++++++++++++++++
 1 files changed, 35 insertions(+), 0 deletions(-)

diff --git a/configure b/configure
index 0639b33..b391165 100755
--- a/configure
+++ b/configure
@@ -320,6 +320,7 @@ pkgversion=""
 check_utests="no"
 user_pie="no"
 zero_malloc=""
+spice=""
 
 # OS specific
 if check_define __linux__ ; then
@@ -621,6 +622,10 @@ for opt do
   ;;
   --enable-kvm) kvm="yes"
   ;;
+  --disable-spice) spice="no"
+  ;;
+  --enable-spice) spice="yes"
+  ;;
   --enable-profiler) profiler="yes"
   ;;
   --enable-cocoa)
@@ -900,6 +905,8 @@ echo "  --enable-docs            enable documentation build"
 echo "  --disable-docs           disable documentation build"
 echo "  --disable-vhost-net      disable vhost-net acceleration support"
 echo "  --enable-vhost-net       enable vhost-net acceleration support"
+echo "  --disable-spice          disable spice"
+echo "  --enable-spice           enable spice"
 echo ""
 echo "NOTE: The object files are built at the place where configure is launched"
 exit 1
@@ -2050,6 +2057,29 @@ if compile_prog "" ""; then
     gcc_attribute_warn_unused_result=yes
 fi
 
+# spice probe
+if test "$spice" != "no" ; then
+  cat > $TMPC << EOF
+#include <spice.h>
+int main(void) { spice_server_new(); return 0; }
+EOF
+  spice_cflags=$($pkgconfig --cflags spice-protocol spice-server 2>/dev/null)
+  spice_libs=$($pkgconfig --libs spice-protocol spice-server 2>/dev/null)
+  if $pkgconfig --atleast-version=0.5.3 spice-server &&\
+     compile_prog "$spice_cflags" "$spice_libs" ; then
+    spice="yes"
+    libs_softmmu="$libs_softmmu $spice_libs"
+    QEMU_CFLAGS="$QEMU_CFLAGS $spice_cflags"
+  else
+    if test "$spice" = "yes" ; then
+      feature_not_found "spice"
+    fi
+    spice="no"
+  fi
+fi
+
+##########################################
+
 ##########################################
 # check if we have fdatasync
 
@@ -2192,6 +2222,7 @@ echo "preadv support    $preadv"
 echo "fdatasync         $fdatasync"
 echo "uuid support      $uuid"
 echo "vhost-net support $vhost_net"
+echo "spice support     $spice"
 
 if test $sdl_too_old = "yes"; then
 echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -2429,6 +2460,10 @@ if test "$fdatasync" = "yes" ; then
   echo "CONFIG_FDATASYNC=y" >> $config_host_mak
 fi
 
+if test "$spice" = "yes" ; then
+  echo "CONFIG_SPICE=y" >> $config_host_mak
+fi
+
 # XXX: suppress that
 if [ "$bsd" = "yes" ] ; then
   echo "CONFIG_BSD=y" >> $config_host_mak
-- 
1.7.1

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

* [Qemu-devel] [PATCH v4 06/10] spice: core bits
  2010-08-27  9:59 [Qemu-devel] [PATCH v4 00/10] initial spice support Gerd Hoffmann
                   ` (4 preceding siblings ...)
  2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 05/10] add spice into the configure file Gerd Hoffmann
@ 2010-08-27  9:59 ` Gerd Hoffmann
  2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 07/10] spice: add keyboard Gerd Hoffmann
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Gerd Hoffmann @ 2010-08-27  9:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Add -spice command line switch.  Has support setting passwd and port for
now.  With this patch applied the spice client can successfully connect
to qemu.  You can't do anything useful yet though.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 Makefile.objs   |    2 +
 qemu-config.c   |   18 ++++++
 qemu-config.h   |    1 +
 qemu-options.hx |   21 +++++++
 ui/qemu-spice.h |   39 ++++++++++++
 ui/spice-core.c |  181 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 vl.c            |   15 +++++
 7 files changed, 277 insertions(+), 0 deletions(-)
 create mode 100644 ui/qemu-spice.h
 create mode 100644 ui/spice-core.c

diff --git a/Makefile.objs b/Makefile.objs
index edfca87..1a53027 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -88,6 +88,8 @@ common-obj-y += pflib.o
 common-obj-$(CONFIG_BRLAPI) += baum.o
 common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
 
+common-obj-$(CONFIG_SPICE) += ui/spice-core.o
+
 audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
 audio-obj-$(CONFIG_SDL) += sdlaudio.o
 audio-obj-$(CONFIG_OSS) += ossaudio.o
diff --git a/qemu-config.c b/qemu-config.c
index 3abe655..4c47cd0 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -336,6 +336,24 @@ static QemuOptsList qemu_cpudef_opts = {
     },
 };
 
+QemuOptsList qemu_spice_opts = {
+    .name = "spice",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_spice_opts.head),
+    .desc = {
+        {
+            .name = "port",
+            .type = QEMU_OPT_NUMBER,
+        },{
+            .name = "password",
+            .type = QEMU_OPT_STRING,
+        },{
+            .name = "disable-ticketing",
+            .type = QEMU_OPT_BOOL,
+        },
+        { /* end if list */ }
+    },
+};
+
 static QemuOptsList *vm_config_groups[32] = {
     &qemu_drive_opts,
     &qemu_chardev_opts,
diff --git a/qemu-config.h b/qemu-config.h
index 533a049..20d707f 100644
--- a/qemu-config.h
+++ b/qemu-config.h
@@ -3,6 +3,7 @@
 
 extern QemuOptsList qemu_fsdev_opts;
 extern QemuOptsList qemu_virtfs_opts;
+extern QemuOptsList qemu_spice_opts;
 
 QemuOptsList *qemu_find_opts(const char *group);
 void qemu_add_opts(QemuOptsList *list);
diff --git a/qemu-options.hx b/qemu-options.hx
index 453f129..87bd451 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -670,6 +670,27 @@ STEXI
 Enable SDL.
 ETEXI
 
+DEF("spice", HAS_ARG, QEMU_OPTION_spice,
+    "-spice <args>   enable spice\n", QEMU_ARCH_ALL)
+STEXI
+@item -spice @var{option}[,@var{option}[,...]]
+@findex -spice
+Enable the spice remote desktop protocol. Valid options are
+
+@table @option
+
+@item port=<nr>
+Set the TCP port spice is listening on.
+
+@item password=<secret>
+Set the password you need to authenticate.
+
+@item disable-ticketing
+Allow client connects without authentication.
+
+@end table
+ETEXI
+
 DEF("portrait", 0, QEMU_OPTION_portrait,
     "-portrait       rotate graphical output 90 deg left (only PXA LCD)\n",
     QEMU_ARCH_ALL)
diff --git a/ui/qemu-spice.h b/ui/qemu-spice.h
new file mode 100644
index 0000000..50faefb
--- /dev/null
+++ b/ui/qemu-spice.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 or
+ * (at your option) version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef QEMU_SPICE_H
+#define QEMU_SPICE_H
+
+#ifdef CONFIG_SPICE
+
+#include <spice.h>
+
+#include "qemu-option.h"
+#include "qemu-config.h"
+
+extern int using_spice;
+
+void qemu_spice_init(void);
+int qemu_spice_add_interface(SpiceBaseInstance *sin);
+
+#else  /* CONFIG_SPICE */
+
+#define using_spice 0
+
+#endif /* CONFIG_SPICE */
+
+#endif /* QEMU_SPICE_H */
diff --git a/ui/spice-core.c b/ui/spice-core.c
new file mode 100644
index 0000000..178d740
--- /dev/null
+++ b/ui/spice-core.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 or
+ * (at your option) version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <spice.h>
+#include <spice-experimental.h>
+
+#include "qemu-common.h"
+#include "qemu-spice.h"
+#include "qemu-timer.h"
+#include "qemu-queue.h"
+#include "monitor.h"
+
+/* core bits */
+
+static SpiceServer *spice_server;
+int using_spice = 0;
+
+struct SpiceTimer {
+    QEMUTimer *timer;
+    QTAILQ_ENTRY(SpiceTimer) next;
+};
+static QTAILQ_HEAD(, SpiceTimer) timers = QTAILQ_HEAD_INITIALIZER(timers);
+
+static SpiceTimer *timer_add(SpiceTimerFunc func, void *opaque)
+{
+    SpiceTimer *timer;
+
+    timer = qemu_mallocz(sizeof(*timer));
+    timer->timer = qemu_new_timer(rt_clock, func, opaque);
+    QTAILQ_INSERT_TAIL(&timers, timer, next);
+    return timer;
+}
+
+static void timer_start(SpiceTimer *timer, uint32_t ms)
+{
+    qemu_mod_timer(timer->timer, qemu_get_clock(rt_clock) + ms);
+}
+
+static void timer_cancel(SpiceTimer *timer)
+{
+    qemu_del_timer(timer->timer);
+}
+
+static void timer_remove(SpiceTimer *timer)
+{
+    qemu_del_timer(timer->timer);
+    qemu_free_timer(timer->timer);
+    QTAILQ_REMOVE(&timers, timer, next);
+    qemu_free(timer);
+}
+
+struct SpiceWatch {
+    int fd;
+    int event_mask;
+    SpiceWatchFunc func;
+    void *opaque;
+    QTAILQ_ENTRY(SpiceWatch) next;
+};
+static QTAILQ_HEAD(, SpiceWatch) watches = QTAILQ_HEAD_INITIALIZER(watches);
+
+static void watch_read(void *opaque)
+{
+    SpiceWatch *watch = opaque;
+    watch->func(watch->fd, SPICE_WATCH_EVENT_READ, watch->opaque);
+}
+
+static void watch_write(void *opaque)
+{
+    SpiceWatch *watch = opaque;
+    watch->func(watch->fd, SPICE_WATCH_EVENT_WRITE, watch->opaque);
+}
+
+static void watch_update_mask(SpiceWatch *watch, int event_mask)
+{
+    IOHandler *on_read = NULL;
+    IOHandler *on_write = NULL;
+
+    watch->event_mask = event_mask;
+    if (watch->event_mask & SPICE_WATCH_EVENT_READ)
+        on_read = watch_read;
+    if (watch->event_mask & SPICE_WATCH_EVENT_WRITE)
+        on_read = watch_write;
+    qemu_set_fd_handler(watch->fd, on_read, on_write, watch);
+}
+
+static SpiceWatch *watch_add(int fd, int event_mask, SpiceWatchFunc func, void *opaque)
+{
+    SpiceWatch *watch;
+
+    watch = qemu_mallocz(sizeof(*watch));
+    watch->fd     = fd;
+    watch->func   = func;
+    watch->opaque = opaque;
+    QTAILQ_INSERT_TAIL(&watches, watch, next);
+
+    watch_update_mask(watch, event_mask);
+    return watch;
+}
+
+static void watch_remove(SpiceWatch *watch)
+{
+    watch_update_mask(watch, 0);
+    QTAILQ_REMOVE(&watches, watch, next);
+    qemu_free(watch);
+}
+
+static SpiceCoreInterface core_interface = {
+    .base.type          = SPICE_INTERFACE_CORE,
+    .base.description   = "qemu core services",
+    .base.major_version = SPICE_INTERFACE_CORE_MAJOR,
+    .base.minor_version = SPICE_INTERFACE_CORE_MINOR,
+
+    .timer_add          = timer_add,
+    .timer_start        = timer_start,
+    .timer_cancel       = timer_cancel,
+    .timer_remove       = timer_remove,
+
+    .watch_add          = watch_add,
+    .watch_update_mask  = watch_update_mask,
+    .watch_remove       = watch_remove,
+};
+
+/* functions for the rest of qemu */
+
+void qemu_spice_init(void)
+{
+    QemuOpts *opts = QTAILQ_FIRST(&qemu_spice_opts.head);
+    const char *password;
+    int port;
+
+    if (!opts)
+        return;
+    port = qemu_opt_get_number(opts, "port", 0);
+    if (!port)
+        return;
+    password = qemu_opt_get(opts, "password");
+
+    spice_server = spice_server_new();
+    spice_server_set_port(spice_server, port);
+    if (password)
+        spice_server_set_ticket(spice_server, password, 0, 0, 0);
+    if (qemu_opt_get_bool(opts, "disable-ticketing", 0))
+        spice_server_set_noauth(spice_server);
+
+    /* TODO: make configurable via cmdline */
+    spice_server_set_image_compression(spice_server, SPICE_IMAGE_COMPRESS_AUTO_GLZ);
+
+    spice_server_init(spice_server, &core_interface);
+    using_spice = 1;
+}
+
+int qemu_spice_add_interface(SpiceBaseInstance *sin)
+{
+    return spice_server_add_interface(spice_server, sin);
+}
+
+static void spice_register_config(void)
+{
+    qemu_add_opts(&qemu_spice_opts);
+}
+machine_init(spice_register_config);
+
+static void spice_initialize(void)
+{
+    qemu_spice_init();
+}
+device_init(spice_initialize);
diff --git a/vl.c b/vl.c
index 40bf30b..a8c2a33 100644
--- a/vl.c
+++ b/vl.c
@@ -161,6 +161,8 @@ int main(int argc, char **argv)
 #include "cpus.h"
 #include "arch_init.h"
 
+#include "ui/qemu-spice.h"
+
 //#define DEBUG_NET
 //#define DEBUG_SLIRP
 
@@ -2599,6 +2601,19 @@ int main(int argc, char **argv, char **envp)
                     }
                     break;
                 }
+            case QEMU_OPTION_spice:
+                olist = qemu_find_opts("spice");
+                if (!olist) {
+                    fprintf(stderr, "spice is not supported by this qemu build.\n");
+                    exit(1);
+                }
+                opts = qemu_opts_parse(olist, optarg, 0);
+                if (!opts) {
+                    fprintf(stderr, "parse error: %s\n", optarg);
+                    exit(1);
+                }
+                display_remote++;
+                break;
             case QEMU_OPTION_writeconfig:
                 {
                     FILE *fp;
-- 
1.7.1

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

* [Qemu-devel] [PATCH v4 07/10] spice: add keyboard
  2010-08-27  9:59 [Qemu-devel] [PATCH v4 00/10] initial spice support Gerd Hoffmann
                   ` (5 preceding siblings ...)
  2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 06/10] spice: core bits Gerd Hoffmann
@ 2010-08-27  9:59 ` Gerd Hoffmann
  2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 08/10] spice: add mouse Gerd Hoffmann
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Gerd Hoffmann @ 2010-08-27  9:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Open keyboard channel.  Now you can type into the spice client and the
keyboard events are sent to your guest.  You'll need some other display
like vnc to actually see the guest responding to them though.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 Makefile.objs    |    2 +-
 ui/qemu-spice.h  |    1 +
 ui/spice-core.c  |    2 +
 ui/spice-input.c |   82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 86 insertions(+), 1 deletions(-)
 create mode 100644 ui/spice-input.c

diff --git a/Makefile.objs b/Makefile.objs
index 1a53027..20e6ad7 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -88,7 +88,7 @@ common-obj-y += pflib.o
 common-obj-$(CONFIG_BRLAPI) += baum.o
 common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
 
-common-obj-$(CONFIG_SPICE) += ui/spice-core.o
+common-obj-$(CONFIG_SPICE) += ui/spice-core.o ui/spice-input.o
 
 audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
 audio-obj-$(CONFIG_SDL) += sdlaudio.o
diff --git a/ui/qemu-spice.h b/ui/qemu-spice.h
index 50faefb..175c961 100644
--- a/ui/qemu-spice.h
+++ b/ui/qemu-spice.h
@@ -28,6 +28,7 @@
 extern int using_spice;
 
 void qemu_spice_init(void);
+void qemu_spice_input_init(void);
 int qemu_spice_add_interface(SpiceBaseInstance *sin);
 
 #else  /* CONFIG_SPICE */
diff --git a/ui/spice-core.c b/ui/spice-core.c
index 178d740..07d6a0c 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -161,6 +161,8 @@ void qemu_spice_init(void)
 
     spice_server_init(spice_server, &core_interface);
     using_spice = 1;
+
+    qemu_spice_input_init();
 }
 
 int qemu_spice_add_interface(SpiceBaseInstance *sin)
diff --git a/ui/spice-input.c b/ui/spice-input.c
new file mode 100644
index 0000000..efecc22
--- /dev/null
+++ b/ui/spice-input.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 or
+ * (at your option) version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <spice.h>
+#include <spice/enums.h>
+
+#include "qemu-common.h"
+#include "qemu-spice.h"
+#include "console.h"
+
+/* keyboard bits */
+
+typedef struct QemuSpiceKbd {
+    SpiceKbdInstance sin;
+    int ledstate;
+} QemuSpiceKbd;
+
+static void kbd_push_key(SpiceKbdInstance *sin, uint8_t frag);
+static uint8_t kbd_get_leds(SpiceKbdInstance *sin);
+static void kbd_leds(void *opaque, int l);
+
+static const SpiceKbdInterface kbd_interface = {
+    .base.type          = SPICE_INTERFACE_KEYBOARD,
+    .base.description   = "qemu keyboard",
+    .base.major_version = SPICE_INTERFACE_KEYBOARD_MAJOR,
+    .base.minor_version = SPICE_INTERFACE_KEYBOARD_MINOR,
+    .push_scan_freg     = kbd_push_key,
+    .get_leds           = kbd_get_leds,
+};
+
+static void kbd_push_key(SpiceKbdInstance *sin, uint8_t frag)
+{
+    kbd_put_keycode(frag);
+}
+
+static uint8_t kbd_get_leds(SpiceKbdInstance *sin)
+{
+    QemuSpiceKbd *kbd = container_of(sin, QemuSpiceKbd, sin);
+    return kbd->ledstate;
+}
+
+static void kbd_leds(void *opaque, int ledstate)
+{
+    QemuSpiceKbd *kbd = opaque;
+
+    kbd->ledstate = 0;
+    if (ledstate & QEMU_SCROLL_LOCK_LED)
+        kbd->ledstate |= SPICE_KEYBOARD_MODIFIER_FLAGS_SCROLL_LOCK;
+    if (ledstate & QEMU_NUM_LOCK_LED)
+        kbd->ledstate |= SPICE_KEYBOARD_MODIFIER_FLAGS_NUM_LOCK;
+    if (ledstate & QEMU_CAPS_LOCK_LED)
+        kbd->ledstate |= SPICE_KEYBOARD_MODIFIER_FLAGS_CAPS_LOCK;
+    spice_server_kbd_leds(&kbd->sin, ledstate);
+}
+
+void qemu_spice_input_init(void)
+{
+    QemuSpiceKbd *kbd;
+
+    kbd = qemu_mallocz(sizeof(*kbd));
+    kbd->sin.base.sif = &kbd_interface.base;
+    qemu_spice_add_interface(&kbd->sin.base);
+    qemu_add_led_event_handler(kbd_leds, kbd);
+}
-- 
1.7.1

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

* [Qemu-devel] [PATCH v4 08/10] spice: add mouse
  2010-08-27  9:59 [Qemu-devel] [PATCH v4 00/10] initial spice support Gerd Hoffmann
                   ` (6 preceding siblings ...)
  2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 07/10] spice: add keyboard Gerd Hoffmann
@ 2010-08-27  9:59 ` Gerd Hoffmann
  2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 09/10] spice: simple display Gerd Hoffmann
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Gerd Hoffmann @ 2010-08-27  9:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Open mouse channel.  Now you can move the guests mouse pointer.
No tablet / absolute positioning (yet) though.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/spice-input.c |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/ui/spice-input.c b/ui/spice-input.c
index efecc22..afb4d61 100644
--- a/ui/spice-input.c
+++ b/ui/spice-input.c
@@ -71,12 +71,61 @@ static void kbd_leds(void *opaque, int ledstate)
     spice_server_kbd_leds(&kbd->sin, ledstate);
 }
 
+/* mouse bits */
+
+typedef struct QemuSpiceMouse {
+    SpiceMouseInstance sin;
+} QemuSpiceMouse;
+
+static int map_buttons(int spice_buttons)
+{
+    int qemu_buttons = 0;
+
+    /*
+     * Note: SPICE_MOUSE_BUTTON_* specifies the wire protocol but this
+     * isn't what we get passed in via interface callbacks for the
+     * middle and right button ...
+     */
+    if (spice_buttons & SPICE_MOUSE_BUTTON_MASK_LEFT)
+        qemu_buttons |= MOUSE_EVENT_LBUTTON;
+    if (spice_buttons & 0x04 /* SPICE_MOUSE_BUTTON_MASK_MIDDLE */)
+        qemu_buttons |= MOUSE_EVENT_MBUTTON;
+    if (spice_buttons & 0x02 /* SPICE_MOUSE_BUTTON_MASK_RIGHT */)
+        qemu_buttons |= MOUSE_EVENT_RBUTTON;
+    return qemu_buttons;
+}
+
+static void mouse_motion(SpiceMouseInstance *sin, int dx, int dy, int dz,
+                         uint32_t buttons_state)
+{
+    kbd_mouse_event(dx, dy, dz, map_buttons(buttons_state));
+}
+
+static void mouse_buttons(SpiceMouseInstance *sin, uint32_t buttons_state)
+{
+    kbd_mouse_event(0, 0, 0, map_buttons(buttons_state));
+}
+
+static const SpiceMouseInterface mouse_interface = {
+    .base.type          = SPICE_INTERFACE_MOUSE,
+    .base.description   = "mouse",
+    .base.major_version = SPICE_INTERFACE_MOUSE_MAJOR,
+    .base.minor_version = SPICE_INTERFACE_MOUSE_MINOR,
+    .motion             = mouse_motion,
+    .buttons            = mouse_buttons,
+};
+
 void qemu_spice_input_init(void)
 {
     QemuSpiceKbd *kbd;
+    QemuSpiceMouse *mouse;
 
     kbd = qemu_mallocz(sizeof(*kbd));
     kbd->sin.base.sif = &kbd_interface.base;
     qemu_spice_add_interface(&kbd->sin.base);
     qemu_add_led_event_handler(kbd_leds, kbd);
+
+    mouse = qemu_mallocz(sizeof(*mouse));
+    mouse->sin.base.sif = &mouse_interface.base;
+    qemu_spice_add_interface(&mouse->sin.base);
 }
-- 
1.7.1

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

* [Qemu-devel] [PATCH v4 09/10] spice: simple display
  2010-08-27  9:59 [Qemu-devel] [PATCH v4 00/10] initial spice support Gerd Hoffmann
                   ` (7 preceding siblings ...)
  2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 08/10] spice: add mouse Gerd Hoffmann
@ 2010-08-27  9:59 ` Gerd Hoffmann
  2010-08-27 12:42   ` Anthony Liguori
  2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 10/10] spice: add tablet support Gerd Hoffmann
  2010-08-28  6:42 ` [Qemu-devel] [PATCH v4 00/10] initial spice support Blue Swirl
  10 siblings, 1 reply; 20+ messages in thread
From: Gerd Hoffmann @ 2010-08-27  9:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

With that patch applied you'll actually see the guests screen in the
spice client.  This does *not* bring qxl and full spice support though.
This is basically the qxl vga mode made more generic, so it plays
together with any qemu-emulated gfx card.  You can display stdvga or
cirrus via spice client.  You can have both vnc and spice enabled and
clients connected at the same time.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 Makefile.objs      |    2 +-
 ui/qemu-spice.h    |    1 +
 ui/spice-display.c |  410 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 ui/spice-display.h |   69 +++++++++
 vl.c               |    5 +
 5 files changed, 486 insertions(+), 1 deletions(-)
 create mode 100644 ui/spice-display.c
 create mode 100644 ui/spice-display.h

diff --git a/Makefile.objs b/Makefile.objs
index 20e6ad7..d09a1e4 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -88,7 +88,7 @@ common-obj-y += pflib.o
 common-obj-$(CONFIG_BRLAPI) += baum.o
 common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
 
-common-obj-$(CONFIG_SPICE) += ui/spice-core.o ui/spice-input.o
+common-obj-$(CONFIG_SPICE) += ui/spice-core.o ui/spice-input.o ui/spice-display.o
 
 audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
 audio-obj-$(CONFIG_SDL) += sdlaudio.o
diff --git a/ui/qemu-spice.h b/ui/qemu-spice.h
index 175c961..063c7dc 100644
--- a/ui/qemu-spice.h
+++ b/ui/qemu-spice.h
@@ -29,6 +29,7 @@ extern int using_spice;
 
 void qemu_spice_init(void);
 void qemu_spice_input_init(void);
+void qemu_spice_display_init(DisplayState *ds);
 int qemu_spice_add_interface(SpiceBaseInstance *sin);
 
 #else  /* CONFIG_SPICE */
diff --git a/ui/spice-display.c b/ui/spice-display.c
new file mode 100644
index 0000000..9e11fb3
--- /dev/null
+++ b/ui/spice-display.c
@@ -0,0 +1,410 @@
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 or
+ * (at your option) version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <pthread.h>
+
+#include "qemu-common.h"
+#include "qemu-spice.h"
+#include "qemu-timer.h"
+#include "qemu-queue.h"
+#include "monitor.h"
+#include "console.h"
+#include "sysemu.h"
+
+#include "spice-display.h"
+
+static int debug = 0;
+
+static void __attribute__((format(printf,2,3)))
+dprint(int level, const char *fmt, ...)
+{
+    va_list args;
+
+    if (level <= debug) {
+        va_start(args, fmt);
+        vfprintf(stderr, fmt, args);
+        va_end(args);
+    }
+}
+
+int qemu_spice_rect_is_empty(const QXLRect* r)
+{
+    return r->top == r->bottom || r->left == r->right;
+}
+
+void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r)
+{
+    if (qemu_spice_rect_is_empty(r)) {
+        return;
+    }
+
+    if (qemu_spice_rect_is_empty(dest)) {
+        *dest = *r;
+        return;
+    }
+
+    dest->top = MIN(dest->top, r->top);
+    dest->left = MIN(dest->left, r->left);
+    dest->bottom = MAX(dest->bottom, r->bottom);
+    dest->right = MAX(dest->right, r->right);
+}
+
+/*
+ * Called from spice server thread context (via interface_get_command).
+ * We do *not* hold the global qemu mutex here, so extra care is needed
+ * when calling qemu functions.  Qemu interfaces used:
+ *    - pflib (is re-entrant).
+ *    - qemu_malloc (underlying glibc malloc is re-entrant).
+ */
+SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
+{
+    SimpleSpiceUpdate *update;
+    QXLDrawable *drawable;
+    QXLImage *image;
+    QXLCommand *cmd;
+    uint8_t *src, *dst;
+    int by, bw, bh;
+
+    if (qemu_spice_rect_is_empty(&ssd->dirty)) {
+        return NULL;
+    };
+
+    pthread_mutex_lock(&ssd->lock);
+    dprint(2, "%s: lr %d -> %d,  tb -> %d -> %d\n", __FUNCTION__,
+           ssd->dirty.left, ssd->dirty.right,
+           ssd->dirty.top, ssd->dirty.bottom);
+
+    update   = qemu_mallocz(sizeof(*update));
+    drawable = &update->drawable;
+    image    = &update->image;
+    cmd      = &update->ext.cmd;
+
+    bw       = ssd->dirty.right - ssd->dirty.left;
+    bh       = ssd->dirty.bottom - ssd->dirty.top;
+    update->bitmap = qemu_malloc(bw * bh * 4);
+
+    drawable->bbox            = ssd->dirty;
+    drawable->clip.type       = SPICE_CLIP_TYPE_NONE;
+    drawable->effect          = QXL_EFFECT_OPAQUE;
+    drawable->release_info.id = (intptr_t)update;
+    drawable->type            = QXL_DRAW_COPY;
+
+    drawable->u.copy.rop_descriptor  = SPICE_ROPD_OP_PUT;
+    drawable->u.copy.src_bitmap      = (intptr_t)image;
+    drawable->u.copy.src_area.right  = bw;
+    drawable->u.copy.src_area.bottom = bh;
+
+    QXL_SET_IMAGE_ID(image, QXL_IMAGE_GROUP_DEVICE, ssd->unique++);
+    image->descriptor.type   = SPICE_IMAGE_TYPE_BITMAP;
+    image->bitmap.flags      = QXL_BITMAP_DIRECT | QXL_BITMAP_TOP_DOWN;
+    image->bitmap.stride     = bw * 4;
+    image->descriptor.width  = image->bitmap.x = bw;
+    image->descriptor.height = image->bitmap.y = bh;
+    image->bitmap.data = (intptr_t)(update->bitmap);
+    image->bitmap.palette = 0;
+    image->bitmap.format = SPICE_BITMAP_FMT_32BIT;
+
+    if (ssd->conv == NULL) {
+        PixelFormat dst = qemu_default_pixelformat(32);
+        ssd->conv = qemu_pf_conv_get(&dst, &ssd->ds->surface->pf);
+        assert(ssd->conv);
+    }
+
+    src = ds_get_data(ssd->ds) +
+        ssd->dirty.top * ds_get_linesize(ssd->ds) +
+        ssd->dirty.left * ds_get_bytes_per_pixel(ssd->ds);
+    dst = update->bitmap;
+    for (by = 0; by < bh; by++) {
+        qemu_pf_conv_run(ssd->conv, dst, src, bw);
+        src += ds_get_linesize(ssd->ds);
+        dst += image->bitmap.stride;
+    }
+
+    cmd->type = QXL_CMD_DRAW;
+    cmd->data = (intptr_t)drawable;
+
+    memset(&ssd->dirty, 0, sizeof(ssd->dirty));
+    pthread_mutex_unlock(&ssd->lock);
+    return update;
+}
+
+/*
+ * Called from spice server thread context (via interface_release_ressource)
+ * We do *not* hold the global qemu mutex here, so extra care is needed
+ * when calling qemu functions.  Qemu interfaces used:
+ *    - qemu_free (underlying glibc free is re-entrant).
+ */
+void qemu_spice_destroy_update(SimpleSpiceDisplay *sdpy, SimpleSpiceUpdate *update)
+{
+    qemu_free(update->bitmap);
+    qemu_free(update);
+}
+
+void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd)
+{
+    QXLDevMemSlot memslot;
+
+    dprint(1, "%s:\n", __FUNCTION__);
+
+    memset(&memslot, 0, sizeof(memslot));
+    memslot.slot_group_id = MEMSLOT_GROUP_HOST;
+    memslot.virt_end = ~0;
+    ssd->worker->add_memslot(ssd->worker, &memslot);
+}
+
+void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
+{
+    QXLDevSurfaceCreate surface;
+
+    dprint(1, "%s: %dx%d\n", __FUNCTION__,
+           ds_get_width(ssd->ds), ds_get_height(ssd->ds));
+
+    surface.format     = SPICE_SURFACE_FMT_32_xRGB;
+    surface.width      = ds_get_width(ssd->ds);
+    surface.height     = ds_get_height(ssd->ds);
+    surface.stride     = -surface.width * 4;
+    surface.mouse_mode = 0;
+    surface.flags      = 0;
+    surface.type       = 0;
+    surface.mem        = (intptr_t)ssd->buf;
+    surface.group_id   = MEMSLOT_GROUP_HOST;
+    ssd->worker->create_primary_surface(ssd->worker, 0, &surface);
+}
+
+void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd)
+{
+    dprint(1, "%s:\n", __FUNCTION__);
+
+    ssd->worker->destroy_primary_surface(ssd->worker, 0);
+}
+
+void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason)
+{
+    SimpleSpiceDisplay *ssd = opaque;
+
+    if (running) {
+        ssd->worker->start(ssd->worker);
+    } else {
+        ssd->worker->stop(ssd->worker);
+    }
+    ssd->running = running;
+}
+
+/* display listener callbacks */
+
+void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
+                               int x, int y, int w, int h)
+{
+    QXLRect update_area;
+
+    dprint(2, "%s: x %d y %d w %d h %d\n", __FUNCTION__, x, y, w, h);
+    update_area.left = x,
+    update_area.right = x + w;
+    update_area.top = y;
+    update_area.bottom = y + h;
+
+    pthread_mutex_lock(&ssd->lock);
+    if (qemu_spice_rect_is_empty(&ssd->dirty)) {
+        ssd->notify++;
+    }
+    qemu_spice_rect_union(&ssd->dirty, &update_area);
+    pthread_mutex_unlock(&ssd->lock);
+}
+
+void qemu_spice_display_resize(SimpleSpiceDisplay *ssd)
+{
+    dprint(1, "%s:\n", __FUNCTION__);
+
+    pthread_mutex_lock(&ssd->lock);
+    memset(&ssd->dirty, 0, sizeof(ssd->dirty));
+    qemu_pf_conv_put(ssd->conv);
+    ssd->conv = NULL;
+    pthread_mutex_unlock(&ssd->lock);
+
+    qemu_spice_destroy_host_primary(ssd);
+    qemu_spice_create_host_primary(ssd);
+
+    pthread_mutex_lock(&ssd->lock);
+    memset(&ssd->dirty, 0, sizeof(ssd->dirty));
+    ssd->notify++;
+    pthread_mutex_unlock(&ssd->lock);
+}
+
+void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd)
+{
+    dprint(3, "%s:\n", __FUNCTION__);
+    vga_hw_update();
+    if (ssd->notify) {
+        ssd->notify = 0;
+        ssd->worker->wakeup(ssd->worker);
+        if (debug > 1)
+            fprintf(stderr, "%s: notify\n", __FUNCTION__);
+    }
+}
+
+/* spice display interface callbacks */
+
+static void interface_attach_worker(QXLInstance *sin, QXLWorker *qxl_worker)
+{
+    SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
+
+    dprint(1, "%s:\n", __FUNCTION__);
+    ssd->worker = qxl_worker;
+}
+
+static void interface_set_compression_level(QXLInstance *sin, int level)
+{
+    dprint(1, "%s:\n", __FUNCTION__);
+    /* nothing to do */
+}
+
+static void interface_set_mm_time(QXLInstance *sin, uint32_t mm_time)
+{
+    dprint(3, "%s:\n", __FUNCTION__);
+    /* nothing to do */
+}
+
+static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
+{
+    SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
+
+    info->memslot_gen_bits = MEMSLOT_GENERATION_BITS;
+    info->memslot_id_bits  = MEMSLOT_SLOT_BITS;
+    info->num_memslots = NUM_MEMSLOTS;
+    info->num_memslots_groups = NUM_MEMSLOTS_GROUPS;
+    info->internal_groupslot_id = 0;
+    info->qxl_ram_size = ssd->bufsize;
+    info->n_surfaces = NUM_SURFACES;
+}
+
+static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
+{
+    SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
+    SimpleSpiceUpdate *update;
+
+    dprint(3, "%s:\n", __FUNCTION__);
+    update = qemu_spice_create_update(ssd);
+    if (update == NULL) {
+        return false;
+    }
+    *ext = update->ext;
+    return true;
+}
+
+static int interface_req_cmd_notification(QXLInstance *sin)
+{
+    dprint(1, "%s:\n", __FUNCTION__);
+    return 1;
+}
+
+static void interface_release_resource(QXLInstance *sin,
+                                       struct QXLReleaseInfoExt ext)
+{
+    SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
+    uintptr_t id;
+
+    dprint(2, "%s:\n", __FUNCTION__);
+    id = ext.info->id;
+    qemu_spice_destroy_update(ssd, (void*)id);
+}
+
+static int interface_get_cursor_command(QXLInstance *sin, struct QXLCommandExt *ext)
+{
+    dprint(3, "%s:\n", __FUNCTION__);
+    return false;
+}
+
+static int interface_req_cursor_notification(QXLInstance *sin)
+{
+    dprint(1, "%s:\n", __FUNCTION__);
+    return 1;
+}
+
+static void interface_notify_update(QXLInstance *sin, uint32_t update_id)
+{
+    fprintf(stderr, "%s: abort()\n", __FUNCTION__);
+    abort();
+}
+
+static int interface_flush_resources(QXLInstance *sin)
+{
+    fprintf(stderr, "%s: abort()\n", __FUNCTION__);
+    abort();
+    return 0;
+}
+
+static const QXLInterface dpy_interface = {
+    .base.type               = SPICE_INTERFACE_QXL,
+    .base.description        = "qemu simple display",
+    .base.major_version      = SPICE_INTERFACE_QXL_MAJOR,
+    .base.minor_version      = SPICE_INTERFACE_QXL_MINOR,
+
+    .attache_worker          = interface_attach_worker,
+    .set_compression_level   = interface_set_compression_level,
+    .set_mm_time             = interface_set_mm_time,
+    .get_init_info           = interface_get_init_info,
+
+    /* the callbacks below are called from spice server thread context */
+    .get_command             = interface_get_command,
+    .req_cmd_notification    = interface_req_cmd_notification,
+    .release_resource        = interface_release_resource,
+    .get_cursor_command      = interface_get_cursor_command,
+    .req_cursor_notification = interface_req_cursor_notification,
+    .notify_update           = interface_notify_update,
+    .flush_resources         = interface_flush_resources,
+};
+
+static SimpleSpiceDisplay sdpy;
+
+static void display_update(struct DisplayState *ds, int x, int y, int w, int h)
+{
+    qemu_spice_display_update(&sdpy, x, y, w, h);
+}
+
+static void display_resize(struct DisplayState *ds)
+{
+    qemu_spice_display_resize(&sdpy);
+}
+
+static void display_refresh(struct DisplayState *ds)
+{
+    qemu_spice_display_refresh(&sdpy);
+}
+
+static DisplayChangeListener display_listener = {
+    .dpy_update  = display_update,
+    .dpy_resize  = display_resize,
+    .dpy_refresh = display_refresh,
+};
+
+void qemu_spice_display_init(DisplayState *ds)
+{
+    assert(sdpy.ds == NULL);
+    sdpy.ds = ds;
+    sdpy.bufsize = (16 * 1024 * 1024);
+    sdpy.buf = qemu_malloc(sdpy.bufsize);
+    pthread_mutex_init(&sdpy.lock, NULL);
+    register_displaychangelistener(ds, &display_listener);
+
+    sdpy.qxl.base.sif = &dpy_interface.base;
+    qemu_spice_add_interface(&sdpy.qxl.base);
+    assert(sdpy.worker);
+
+    qemu_add_vm_change_state_handler(qemu_spice_vm_change_state_handler, &sdpy);
+    qemu_spice_create_host_memslot(&sdpy);
+    qemu_spice_create_host_primary(&sdpy);
+}
diff --git a/ui/spice-display.h b/ui/spice-display.h
new file mode 100644
index 0000000..e17671c
--- /dev/null
+++ b/ui/spice-display.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 or
+ * (at your option) version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <spice/ipc_ring.h>
+#include <spice/enums.h>
+#include <spice/qxl_dev.h>
+
+#include "pflib.h"
+
+#define NUM_MEMSLOTS 8
+#define MEMSLOT_GENERATION_BITS 8
+#define MEMSLOT_SLOT_BITS 8
+
+#define MEMSLOT_GROUP_HOST  0
+#define MEMSLOT_GROUP_GUEST 1
+#define NUM_MEMSLOTS_GROUPS 2
+
+#define NUM_SURFACES 1024
+
+typedef struct SimpleSpiceDisplay {
+    DisplayState *ds;
+    void *buf;
+    int bufsize;
+    QXLWorker *worker;
+    QXLInstance qxl;
+    uint32_t unique;
+    QemuPfConv *conv;
+
+    pthread_mutex_t lock;
+    QXLRect dirty;
+    int notify;
+    int running;
+} SimpleSpiceDisplay;
+
+typedef struct SimpleSpiceUpdate {
+    QXLDrawable drawable;
+    QXLImage image;
+    QXLCommandExt ext;
+    uint8_t *bitmap;
+} SimpleSpiceUpdate;
+
+int qemu_spice_rect_is_empty(const QXLRect* r);
+void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r);
+
+SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *sdpy);
+void qemu_spice_destroy_update(SimpleSpiceDisplay *sdpy, SimpleSpiceUpdate *update);
+void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd);
+void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd);
+void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd);
+void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason);
+
+void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
+                               int x, int y, int w, int h);
+void qemu_spice_display_resize(SimpleSpiceDisplay *ssd);
+void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd);
diff --git a/vl.c b/vl.c
index a8c2a33..a5229ad 100644
--- a/vl.c
+++ b/vl.c
@@ -2951,6 +2951,11 @@ int main(int argc, char **argv, char **envp)
             printf("VNC server running on `%s'\n", vnc_display_local_addr(ds));
         }
     }
+#ifdef CONFIG_SPICE
+    if (using_spice) {
+        qemu_spice_display_init(ds);
+    }
+#endif
 
     /* display setup */
     dpy_resize(ds);
-- 
1.7.1

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

* [Qemu-devel] [PATCH v4 10/10] spice: add tablet support
  2010-08-27  9:59 [Qemu-devel] [PATCH v4 00/10] initial spice support Gerd Hoffmann
                   ` (8 preceding siblings ...)
  2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 09/10] spice: simple display Gerd Hoffmann
@ 2010-08-27  9:59 ` Gerd Hoffmann
  2010-08-28  6:42 ` [Qemu-devel] [PATCH v4 00/10] initial spice support Blue Swirl
  10 siblings, 0 replies; 20+ messages in thread
From: Gerd Hoffmann @ 2010-08-27  9:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Add support for the spice tablet interface.  The tablet interface will
be registered (and then used by the spice client) as soon as a absolute
pointing device is available and used by the guest, i.e. you'll have to
configure your guest with '-usbdevice tablet'.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/spice-display.c |    2 +-
 ui/spice-input.c   |   91 ++++++++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 85 insertions(+), 8 deletions(-)

diff --git a/ui/spice-display.c b/ui/spice-display.c
index 9e11fb3..30dfb9f 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -177,7 +177,7 @@ void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
     surface.width      = ds_get_width(ssd->ds);
     surface.height     = ds_get_height(ssd->ds);
     surface.stride     = -surface.width * 4;
-    surface.mouse_mode = 0;
+    surface.mouse_mode = true;
     surface.flags      = 0;
     surface.type       = 0;
     surface.mem        = (intptr_t)ssd->buf;
diff --git a/ui/spice-input.c b/ui/spice-input.c
index afb4d61..c6ac632 100644
--- a/ui/spice-input.c
+++ b/ui/spice-input.c
@@ -17,6 +17,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <stdbool.h>
 #include <string.h>
 
 #include <spice.h>
@@ -73,9 +74,13 @@ static void kbd_leds(void *opaque, int ledstate)
 
 /* mouse bits */
 
-typedef struct QemuSpiceMouse {
-    SpiceMouseInstance sin;
-} QemuSpiceMouse;
+typedef struct QemuSpicePointer {
+    SpiceMouseInstance  mouse;
+    SpiceTabletInstance tablet;
+    int width, height, x, y;
+    Notifier mouse_mode;
+    bool absolute;
+} QemuSpicePointer;
 
 static int map_buttons(int spice_buttons)
 {
@@ -115,17 +120,89 @@ static const SpiceMouseInterface mouse_interface = {
     .buttons            = mouse_buttons,
 };
 
+static void tablet_set_logical_size(SpiceTabletInstance* sin, int width, int height)
+{
+    QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, tablet);
+
+    if (height < 16)
+        height = 16;
+    if (width < 16)
+        width = 16;
+    pointer->width  = width;
+    pointer->height = height;
+}
+
+static void tablet_position(SpiceTabletInstance* sin, int x, int y,
+                            uint32_t buttons_state)
+{
+    QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, tablet);
+
+    pointer->x = x * 0x7FFF / (pointer->width - 1);
+    pointer->y = y * 0x7FFF / (pointer->height - 1);
+    kbd_mouse_event(pointer->x, pointer->y, 0, map_buttons(buttons_state));
+}
+
+
+static void tablet_wheel(SpiceTabletInstance* sin, int wheel,
+                         uint32_t buttons_state)
+{
+    QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, tablet);
+
+    kbd_mouse_event(pointer->x, pointer->y, wheel, map_buttons(buttons_state));
+}
+
+static void tablet_buttons(SpiceTabletInstance *sin,
+                           uint32_t buttons_state)
+{
+    QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, tablet);
+
+    kbd_mouse_event(pointer->x, pointer->y, 0, map_buttons(buttons_state));
+}
+
+static const SpiceTabletInterface tablet_interface = {
+    .base.type          = SPICE_INTERFACE_TABLET,
+    .base.description   = "tablet",
+    .base.major_version = SPICE_INTERFACE_TABLET_MAJOR,
+    .base.minor_version = SPICE_INTERFACE_TABLET_MINOR,
+    .set_logical_size   = tablet_set_logical_size,
+    .position           = tablet_position,
+    .wheel              = tablet_wheel,
+    .buttons            = tablet_buttons,
+};
+
+static void mouse_mode_notifier(Notifier *notifier)
+{
+    QemuSpicePointer *pointer = container_of(notifier, QemuSpicePointer, mouse_mode);
+    bool is_absolute  = kbd_mouse_is_absolute();
+
+    if (pointer->absolute == is_absolute)
+        return;
+
+    if (is_absolute) {
+        qemu_spice_add_interface(&pointer->tablet.base);
+    } else {
+        spice_server_remove_interface(&pointer->tablet.base);
+    }
+    pointer->absolute = is_absolute;
+}
+
 void qemu_spice_input_init(void)
 {
     QemuSpiceKbd *kbd;
-    QemuSpiceMouse *mouse;
+    QemuSpicePointer *pointer;
 
     kbd = qemu_mallocz(sizeof(*kbd));
     kbd->sin.base.sif = &kbd_interface.base;
     qemu_spice_add_interface(&kbd->sin.base);
     qemu_add_led_event_handler(kbd_leds, kbd);
 
-    mouse = qemu_mallocz(sizeof(*mouse));
-    mouse->sin.base.sif = &mouse_interface.base;
-    qemu_spice_add_interface(&mouse->sin.base);
+    pointer = qemu_mallocz(sizeof(*pointer));
+    pointer->mouse.base.sif  = &mouse_interface.base;
+    pointer->tablet.base.sif = &tablet_interface.base;
+    qemu_spice_add_interface(&pointer->mouse.base);
+
+    pointer->absolute = false;
+    pointer->mouse_mode.notify = mouse_mode_notifier;
+    qemu_add_mouse_mode_change_notifier(&pointer->mouse_mode);
+    mouse_mode_notifier(&pointer->mouse_mode);
 }
-- 
1.7.1

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

* Re: [Qemu-devel] [PATCH v4 09/10] spice: simple display
  2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 09/10] spice: simple display Gerd Hoffmann
@ 2010-08-27 12:42   ` Anthony Liguori
  0 siblings, 0 replies; 20+ messages in thread
From: Anthony Liguori @ 2010-08-27 12:42 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

On 08/27/2010 04:59 AM, Gerd Hoffmann wrote:
> With that patch applied you'll actually see the guests screen in the
> spice client.  This does *not* bring qxl and full spice support though.
> This is basically the qxl vga mode made more generic, so it plays
> together with any qemu-emulated gfx card.  You can display stdvga or
> cirrus via spice client.  You can have both vnc and spice enabled and
> clients connected at the same time.
>
> Signed-off-by: Gerd Hoffmann<kraxel@redhat.com>
>    
[snip]
> +/*
> + * Called from spice server thread context (via interface_get_command).
> + * We do *not* hold the global qemu mutex here, so extra care is needed
> + * when calling qemu functions.  Qemu interfaces used:
> + *    - pflib (is re-entrant).
> + *    - qemu_malloc (underlying glibc malloc is re-entrant).
> + */
>    

Thanks, that's exactly what I was looking for.

Regards,

Anthony Liguori

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

* Re: [Qemu-devel] [PATCH v4 00/10] initial spice support.
  2010-08-27  9:59 [Qemu-devel] [PATCH v4 00/10] initial spice support Gerd Hoffmann
                   ` (9 preceding siblings ...)
  2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 10/10] spice: add tablet support Gerd Hoffmann
@ 2010-08-28  6:42 ` Blue Swirl
  2010-08-30  8:48   ` Gerd Hoffmann
  10 siblings, 1 reply; 20+ messages in thread
From: Blue Swirl @ 2010-08-28  6:42 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

On Fri, Aug 27, 2010 at 9:59 AM, Gerd Hoffmann <kraxel@redhat.com> wrote:
>  Hi,
>
> Here comes v4 of the iniial spice support patch series, hopefully the
> final version.  It brings just the very basic bits:
>
>  * Detect spice in configure, Makefile windup.
>  * Support for keyboard, mouse and tablet.
>  * Support for simple display output (works as DisplayChangeListener,
>   plays with any gfx card, sends simple draw commands to update
>   dirty regions).
>
> Note that this patch series does *not* yet contain the qxl paravirtual
> gfx card.  That will come as part of a additional patch series after
> sorting the vgabios support.
>
> The patches are also available in the git repository at:
>  git://anongit.freedesktop.org/spice/qemu submit.4

Please read CODING_STYLE, especially the braces rule.

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

* Re: [Qemu-devel] [PATCH v4 00/10] initial spice support.
  2010-08-28  6:42 ` [Qemu-devel] [PATCH v4 00/10] initial spice support Blue Swirl
@ 2010-08-30  8:48   ` Gerd Hoffmann
  2010-08-30 18:58     ` Blue Swirl
  0 siblings, 1 reply; 20+ messages in thread
From: Gerd Hoffmann @ 2010-08-30  8:48 UTC (permalink / raw)
  To: Blue Swirl; +Cc: qemu-devel

On 08/28/10 08:42, Blue Swirl wrote:
> On Fri, Aug 27, 2010 at 9:59 AM, Gerd Hoffmann<kraxel@redhat.com>  wrote:
>>   Hi,
>>
>> Here comes v4 of the iniial spice support patch series, hopefully the
>> final version.  It brings just the very basic bits:
>>
>>   * Detect spice in configure, Makefile windup.
>>   * Support for keyboard, mouse and tablet.
>>   * Support for simple display output (works as DisplayChangeListener,
>>    plays with any gfx card, sends simple draw commands to update
>>    dirty regions).
>>
>> Note that this patch series does *not* yet contain the qxl paravirtual
>> gfx card.  That will come as part of a additional patch series after
>> sorting the vgabios support.
>>
>> The patches are also available in the git repository at:
>>   git://anongit.freedesktop.org/spice/qemu submit.4
>
> Please read CODING_STYLE, especially the braces rule.

I'm aware of the coding style.  I'm also aware of the recent 
flam^Wdiscussions on that topic, especially the braces rule.  I didn't 
read the whole thread though.  Is there some result?  If so, can someone 
summarize please?

thanks,
   Gerd

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

* Re: [Qemu-devel] [PATCH v4 00/10] initial spice support.
  2010-08-30  8:48   ` Gerd Hoffmann
@ 2010-08-30 18:58     ` Blue Swirl
  2010-08-30 19:02       ` Anthony Liguori
  0 siblings, 1 reply; 20+ messages in thread
From: Blue Swirl @ 2010-08-30 18:58 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

On Mon, Aug 30, 2010 at 8:48 AM, Gerd Hoffmann <kraxel@redhat.com> wrote:
> On 08/28/10 08:42, Blue Swirl wrote:
>>
>> On Fri, Aug 27, 2010 at 9:59 AM, Gerd Hoffmann<kraxel@redhat.com>  wrote:
>>>
>>>  Hi,
>>>
>>> Here comes v4 of the iniial spice support patch series, hopefully the
>>> final version.  It brings just the very basic bits:
>>>
>>>  * Detect spice in configure, Makefile windup.
>>>  * Support for keyboard, mouse and tablet.
>>>  * Support for simple display output (works as DisplayChangeListener,
>>>   plays with any gfx card, sends simple draw commands to update
>>>   dirty regions).
>>>
>>> Note that this patch series does *not* yet contain the qxl paravirtual
>>> gfx card.  That will come as part of a additional patch series after
>>> sorting the vgabios support.
>>>
>>> The patches are also available in the git repository at:
>>>  git://anongit.freedesktop.org/spice/qemu submit.4
>>
>> Please read CODING_STYLE, especially the braces rule.
>
> I'm aware of the coding style.

Wilful misconduct? May I ask if there are other things that you don't
agree with and you are covertly working against?

>  I'm also aware of the recent
> flam^Wdiscussions on that topic, especially the braces rule.  I didn't read
> the whole thread though.  Is there some result?  If so, can someone
> summarize please?

There was no conclusion. One point that was raised is that
reformatting of existing code was seen problematic. That would mean
that if offending code is let in, it will never be fixed.

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

* Re: [Qemu-devel] [PATCH v4 00/10] initial spice support.
  2010-08-30 18:58     ` Blue Swirl
@ 2010-08-30 19:02       ` Anthony Liguori
  2010-08-30 19:32         ` Gerd Hoffmann
  2010-08-31  9:54         ` Gerd Hoffmann
  0 siblings, 2 replies; 20+ messages in thread
From: Anthony Liguori @ 2010-08-30 19:02 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Gerd Hoffmann, qemu-devel

On 08/30/2010 01:58 PM, Blue Swirl wrote:
>
> Wilful misconduct? May I ask if there are other things that you don't
> agree with and you are covertly working against?
>    

:-)

Braces should be used.  The discussion was about enforcing coding style 
at commit time and reformatting code.

But for the most part, people agree that we want braces to be used on 
single line ifs.

Regards,

Anthony Liguori

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

* Re: [Qemu-devel] [PATCH v4 00/10] initial spice support.
  2010-08-30 19:02       ` Anthony Liguori
@ 2010-08-30 19:32         ` Gerd Hoffmann
  2010-08-30 19:45           ` Blue Swirl
  2010-08-31  9:54         ` Gerd Hoffmann
  1 sibling, 1 reply; 20+ messages in thread
From: Gerd Hoffmann @ 2010-08-30 19:32 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel

On 08/30/10 21:02, Anthony Liguori wrote:
> On 08/30/2010 01:58 PM, Blue Swirl wrote:
>>
>> Wilful misconduct? May I ask if there are other things that you don't
>> agree with and you are covertly working against?

I'm just not used to it.  Changing habits takes time.

I think I became better meanwhile on avoiding "if (NULL == ptr)" ;)

> Braces should be used. The discussion was about enforcing coding style
> at commit time and reformatting code.

The discussion started with unhappiness about the current situation 
(code not matching code style being committed).  I've seen messages 
discussing whenever we should change code style or commit policy.  I 
qickly stopped following the huge thread though, thats why I ask.

> But for the most part, people agree that we want braces to be used on
> single line ifs.

Ok, so code style stays as-is.  Anyone has a code style git commit hook 
ready for me?  So I can let git do the style review and I don't waste 
everybody's time with that boring stuff?

thanks,
   Gerd

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

* Re: [Qemu-devel] [PATCH v4 00/10] initial spice support.
  2010-08-30 19:32         ` Gerd Hoffmann
@ 2010-08-30 19:45           ` Blue Swirl
  0 siblings, 0 replies; 20+ messages in thread
From: Blue Swirl @ 2010-08-30 19:45 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

On Mon, Aug 30, 2010 at 7:32 PM, Gerd Hoffmann <kraxel@redhat.com> wrote:
> On 08/30/10 21:02, Anthony Liguori wrote:
>>
>> On 08/30/2010 01:58 PM, Blue Swirl wrote:
>>>
>>> Wilful misconduct? May I ask if there are other things that you don't
>>> agree with and you are covertly working against?
>
> I'm just not used to it.  Changing habits takes time.
>
> I think I became better meanwhile on avoiding "if (NULL == ptr)" ;)

Thank you! I'm also just not used to that ;-)

>> Braces should be used. The discussion was about enforcing coding style
>> at commit time and reformatting code.
>
> The discussion started with unhappiness about the current situation (code
> not matching code style being committed).  I've seen messages discussing
> whenever we should change code style or commit policy.  I qickly stopped
> following the huge thread though, thats why I ask.
>
>> But for the most part, people agree that we want braces to be used on
>> single line ifs.
>
> Ok, so code style stays as-is.  Anyone has a code style git commit hook
> ready for me?  So I can let git do the style review and I don't waste
> everybody's time with that boring stuff?

That's the plan. I tried Coccinelle but there were other problems with
that approach.

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

* Re: [Qemu-devel] [PATCH v4 00/10] initial spice support.
  2010-08-30 19:02       ` Anthony Liguori
  2010-08-30 19:32         ` Gerd Hoffmann
@ 2010-08-31  9:54         ` Gerd Hoffmann
  2010-08-31 13:09           ` Anthony Liguori
  1 sibling, 1 reply; 20+ messages in thread
From: Gerd Hoffmann @ 2010-08-31  9:54 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel

   Hi,

> But for the most part, people agree that we want braces to be used on
> single line ifs.

Ok.  Got a bunch of incremental fixes committed locally.  How to go 
forward now?  Want me to respin or can I send those codestyle fixups as 
part of the next spice patch series?

BTW: what is the plan for the vgabios patches?

cheers,
   Gerd

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

* Re: [Qemu-devel] [PATCH v4 00/10] initial spice support.
  2010-08-31  9:54         ` Gerd Hoffmann
@ 2010-08-31 13:09           ` Anthony Liguori
  0 siblings, 0 replies; 20+ messages in thread
From: Anthony Liguori @ 2010-08-31 13:09 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: Blue Swirl, qemu-devel

On 08/31/2010 04:54 AM, Gerd Hoffmann wrote:
>   Hi,
>
>> But for the most part, people agree that we want braces to be used on
>> single line ifs.
>
> Ok.  Got a bunch of incremental fixes committed locally.  How to go 
> forward now?  Want me to respin or can I send those codestyle fixups 
> as part of the next spice patch series?

Send another series.  I'm ready to merge it though.

> BTW: what is the plan for the vgabios patches?

In my queue to merge.  Will do along side Spice.  Updating vgabios is 
painful so I've been delaying it but it needs to be done.

Regards,

Anthony Liguori

> cheers,
>   Gerd

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

end of thread, other threads:[~2010-08-31 13:09 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-27  9:59 [Qemu-devel] [PATCH v4 00/10] initial spice support Gerd Hoffmann
2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 01/10] Use display types for local display only Gerd Hoffmann
2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 02/10] Use machine_init() to register virtfs config options Gerd Hoffmann
2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 03/10] add pflib: PixelFormat conversion library Gerd Hoffmann
2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 04/10] configure: add logging Gerd Hoffmann
2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 05/10] add spice into the configure file Gerd Hoffmann
2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 06/10] spice: core bits Gerd Hoffmann
2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 07/10] spice: add keyboard Gerd Hoffmann
2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 08/10] spice: add mouse Gerd Hoffmann
2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 09/10] spice: simple display Gerd Hoffmann
2010-08-27 12:42   ` Anthony Liguori
2010-08-27  9:59 ` [Qemu-devel] [PATCH v4 10/10] spice: add tablet support Gerd Hoffmann
2010-08-28  6:42 ` [Qemu-devel] [PATCH v4 00/10] initial spice support Blue Swirl
2010-08-30  8:48   ` Gerd Hoffmann
2010-08-30 18:58     ` Blue Swirl
2010-08-30 19:02       ` Anthony Liguori
2010-08-30 19:32         ` Gerd Hoffmann
2010-08-30 19:45           ` Blue Swirl
2010-08-31  9:54         ` Gerd Hoffmann
2010-08-31 13:09           ` Anthony Liguori

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.