]> git.proxmox.com Git - qemu.git/blobdiff - ui/spice-display.c
Merge remote-tracking branch 'mst/tags/for_anthony' into staging
[qemu.git] / ui / spice-display.c
index 0cc0116a5d05a06d9dca2a5f29591bf949511ffd..53c19bea0f93c056e255a45916f0a0aec3fab485 100644 (file)
  */
 
 #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 "ui/qemu-spice.h"
+#include "qemu/timer.h"
+#include "qemu/queue.h"
+#include "monitor/monitor.h"
+#include "ui/console.h"
+#include "sysemu/sysemu.h"
 #include "trace.h"
 
-#include "spice-display.h"
+#include "ui/spice-display.h"
 
 static int debug = 0;
 
@@ -214,10 +214,10 @@ static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd,
 static void qemu_spice_create_update(SimpleSpiceDisplay *ssd)
 {
     static const int blksize = 32;
-    int blocks = (ds_get_width(ssd->ds) + blksize - 1) / blksize;
+    int blocks = (surface_width(ssd->ds) + blksize - 1) / blksize;
     int dirty_top[blocks];
     int y, yoff, x, xoff, blk, bw;
-    int bpp = ds_get_bytes_per_pixel(ssd->ds);
+    int bpp = surface_bytes_per_pixel(ssd->ds);
     uint8_t *guest, *mirror;
 
     if (qemu_spice_rect_is_empty(&ssd->dirty)) {
@@ -225,19 +225,19 @@ static void qemu_spice_create_update(SimpleSpiceDisplay *ssd)
     };
 
     if (ssd->surface == NULL) {
-        ssd->surface = pixman_image_ref(ds_get_image(ssd->ds));
-        ssd->mirror  = qemu_pixman_mirror_create(ds_get_format(ssd->ds),
-                                                 ds_get_image(ssd->ds));
+        ssd->surface = pixman_image_ref(ssd->ds->image);
+        ssd->mirror  = qemu_pixman_mirror_create(ssd->ds->format,
+                                                 ssd->ds->image);
     }
 
     for (blk = 0; blk < blocks; blk++) {
         dirty_top[blk] = -1;
     }
 
-    guest = ds_get_data(ssd->ds);
+    guest = surface_data(ssd->ds);
     mirror = (void *)pixman_image_get_data(ssd->mirror);
     for (y = ssd->dirty.top; y < ssd->dirty.bottom; y++) {
-        yoff = y * ds_get_linesize(ssd->ds);
+        yoff = y * surface_stride(ssd->ds);
         for (x = ssd->dirty.left; x < ssd->dirty.right; x += blksize) {
             xoff = x * bpp;
             blk = x / blksize;
@@ -312,11 +312,11 @@ void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
     memset(&surface, 0, sizeof(surface));
 
     dprint(1, "%s: %dx%d\n", __FUNCTION__,
-           ds_get_width(ssd->ds), ds_get_height(ssd->ds));
+           surface_width(ssd->ds), surface_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.width      = surface_width(ssd->ds);
+    surface.height     = surface_height(ssd->ds);
     surface.stride     = -surface.width * 4;
     surface.mouse_mode = true;
     surface.flags      = 0;
@@ -334,9 +334,8 @@ void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd)
     qemu_spice_destroy_primary_surface(ssd, 0, QXL_SYNC);
 }
 
-void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds)
+void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd)
 {
-    ssd->ds = ds;
     qemu_mutex_init(&ssd->lock);
     QTAILQ_INIT(&ssd->updates);
     ssd->mouse_x = -1;
@@ -367,7 +366,8 @@ void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
     qemu_spice_rect_union(&ssd->dirty, &update_area);
 }
 
-void qemu_spice_display_resize(SimpleSpiceDisplay *ssd)
+void qemu_spice_display_switch(SimpleSpiceDisplay *ssd,
+                               DisplaySurface *surface)
 {
     SimpleSpiceUpdate *update;
 
@@ -382,6 +382,7 @@ void qemu_spice_display_resize(SimpleSpiceDisplay *ssd)
     }
 
     qemu_mutex_lock(&ssd->lock);
+    ssd->ds = surface;
     while ((update = QTAILQ_FIRST(&ssd->updates)) != NULL) {
         QTAILQ_REMOVE(&ssd->updates, update, next);
         qemu_spice_destroy_update(ssd, update);
@@ -397,12 +398,14 @@ void qemu_spice_display_resize(SimpleSpiceDisplay *ssd)
 void qemu_spice_cursor_refresh_unlocked(SimpleSpiceDisplay *ssd)
 {
     if (ssd->cursor) {
-        dpy_cursor_define(ssd->ds, ssd->cursor);
+        assert(ssd->dcl.con);
+        dpy_cursor_define(ssd->dcl.con, ssd->cursor);
         cursor_put(ssd->cursor);
         ssd->cursor = NULL;
     }
     if (ssd->mouse_x != -1 && ssd->mouse_y != -1) {
-        dpy_mouse_set(ssd->ds, ssd->mouse_x, ssd->mouse_y, 1);
+        assert(ssd->dcl.con);
+        dpy_mouse_set(ssd->dcl.con, ssd->mouse_x, ssd->mouse_y, 1);
         ssd->mouse_x = -1;
         ssd->mouse_y = -1;
     }
@@ -411,10 +414,10 @@ void qemu_spice_cursor_refresh_unlocked(SimpleSpiceDisplay *ssd)
 void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd)
 {
     dprint(3, "%s:\n", __func__);
-    vga_hw_update();
+    graphic_hw_update(ssd->dcl.con);
 
     qemu_mutex_lock(&ssd->lock);
-    if (QTAILQ_EMPTY(&ssd->updates)) {
+    if (QTAILQ_EMPTY(&ssd->updates) && ssd->ds) {
         qemu_spice_create_update(ssd);
         ssd->notify++;
     }
@@ -525,6 +528,37 @@ static int interface_flush_resources(QXLInstance *sin)
     return 0;
 }
 
+static void interface_update_area_complete(QXLInstance *sin,
+        uint32_t surface_id,
+        QXLRect *dirty, uint32_t num_updated_rects)
+{
+    /* should never be called, used in qxl native mode only */
+    fprintf(stderr, "%s: abort()\n", __func__);
+    abort();
+}
+
+/* called from spice server thread context only */
+static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token)
+{
+    /* should never be called, used in qxl native mode only */
+    fprintf(stderr, "%s: abort()\n", __func__);
+    abort();
+}
+
+static void interface_set_client_capabilities(QXLInstance *sin,
+                                              uint8_t client_present,
+                                              uint8_t caps[58])
+{
+    dprint(3, "%s:\n", __func__);
+}
+
+static int interface_client_monitors_config(QXLInstance *sin,
+                                        VDAgentMonitorsConfig *monitors_config)
+{
+    dprint(3, "%s:\n", __func__);
+    return 0; /* == not supported by guest */
+}
+
 static const QXLInterface dpy_interface = {
     .base.type               = SPICE_INTERFACE_QXL,
     .base.description        = "qemu simple display",
@@ -544,41 +578,54 @@ static const QXLInterface dpy_interface = {
     .req_cursor_notification = interface_req_cursor_notification,
     .notify_update           = interface_notify_update,
     .flush_resources         = interface_flush_resources,
+    .async_complete          = interface_async_complete,
+    .update_area_complete    = interface_update_area_complete,
+    .set_client_capabilities = interface_set_client_capabilities,
+    .client_monitors_config  = interface_client_monitors_config,
 };
 
-static SimpleSpiceDisplay sdpy;
-
-static void display_update(struct DisplayState *ds, int x, int y, int w, int h)
+static void display_update(DisplayChangeListener *dcl,
+                           int x, int y, int w, int h)
 {
-    qemu_spice_display_update(&sdpy, x, y, w, h);
+    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
+    qemu_spice_display_update(ssd, x, y, w, h);
 }
 
-static void display_resize(struct DisplayState *ds)
+static void display_switch(DisplayChangeListener *dcl,
+                           struct DisplaySurface *surface)
 {
-    qemu_spice_display_resize(&sdpy);
+    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
+    qemu_spice_display_switch(ssd, surface);
 }
 
-static void display_refresh(struct DisplayState *ds)
+static void display_refresh(DisplayChangeListener *dcl)
 {
-    qemu_spice_display_refresh(&sdpy);
+    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
+    qemu_spice_display_refresh(ssd);
 }
 
-static DisplayChangeListener display_listener = {
+static const DisplayChangeListenerOps display_listener_ops = {
+    .dpy_name        = "spice",
     .dpy_gfx_update  = display_update,
-    .dpy_gfx_resize  = display_resize,
-    .dpy_refresh = display_refresh,
+    .dpy_gfx_switch  = display_switch,
+    .dpy_refresh     = display_refresh,
 };
 
 void qemu_spice_display_init(DisplayState *ds)
 {
-    assert(sdpy.ds == NULL);
-    qemu_spice_display_init_common(&sdpy, ds);
+    SimpleSpiceDisplay *ssd = g_new0(SimpleSpiceDisplay, 1);
+
+    qemu_spice_display_init_common(ssd);
+
+    ssd->qxl.base.sif = &dpy_interface.base;
+    qemu_spice_add_interface(&ssd->qxl.base);
+    assert(ssd->worker);
 
-    sdpy.qxl.base.sif = &dpy_interface.base;
-    qemu_spice_add_interface(&sdpy.qxl.base);
-    assert(sdpy.worker);
+    qemu_spice_create_host_memslot(ssd);
 
-    qemu_spice_create_host_memslot(&sdpy);
-    qemu_spice_create_host_primary(&sdpy);
-    register_displaychangelistener(ds, &display_listener);
+    ssd->dcl.ops = &display_listener_ops;
+    ssd->dcl.con = qemu_console_lookup_by_index(0);
+    register_displaychangelistener(ds, &ssd->dcl);
+
+    qemu_spice_create_host_primary(ssd);
 }