*/
#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;
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)) {
};
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;
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;
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;
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;
}
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);
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;
}
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++;
}
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",
.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);
}