*/
#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;
ssd->worker->wakeup(ssd->worker);
}
-#if SPICE_SERVER_VERSION < 0x000b02 /* before 0.11.2 */
-static void qemu_spice_start(SimpleSpiceDisplay *ssd)
-{
- trace_qemu_spice_start(ssd->qxl.id);
- ssd->worker->start(ssd->worker);
-}
-
-static void qemu_spice_stop(SimpleSpiceDisplay *ssd)
-{
- trace_qemu_spice_stop(ssd->qxl.id);
- ssd->worker->stop(ssd->worker);
-}
-
-#else
-
static int spice_display_is_running;
void qemu_spice_display_start(void)
spice_display_is_running = false;
}
-#endif
-
int qemu_spice_display_is_running(SimpleSpiceDisplay *ssd)
{
-#if SPICE_SERVER_VERSION < 0x000b02 /* before 0.11.2 */
- return ssd->running;
-#else
return spice_display_is_running;
-#endif
}
static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd,
QXLDrawable *drawable;
QXLImage *image;
QXLCommand *cmd;
- uint8_t *src, *mirror, *dst;
- int by, bw, bh, offset, bytes;
+ int bw, bh;
struct timespec time_space;
+ pixman_image_t *dest;
trace_qemu_spice_create_update(
rect->left, rect->right,
image->bitmap.palette = 0;
image->bitmap.format = SPICE_BITMAP_FMT_32BIT;
- offset =
- rect->top * ds_get_linesize(ssd->ds) +
- rect->left * ds_get_bytes_per_pixel(ssd->ds);
- bytes = ds_get_bytes_per_pixel(ssd->ds) * bw;
- src = ds_get_data(ssd->ds) + offset;
- mirror = ssd->ds_mirror + offset;
- dst = update->bitmap;
- for (by = 0; by < bh; by++) {
- memcpy(mirror, src, bytes);
- qemu_pf_conv_run(ssd->conv, dst, mirror, bw);
- src += ds_get_linesize(ssd->ds);
- mirror += ds_get_linesize(ssd->ds);
- dst += image->bitmap.stride;
- }
+ dest = pixman_image_create_bits(PIXMAN_x8r8g8b8, bw, bh,
+ (void *)update->bitmap, bw * 4);
+ pixman_image_composite(PIXMAN_OP_SRC, ssd->surface, NULL, ssd->mirror,
+ rect->left, rect->top, 0, 0,
+ rect->left, rect->top, bw, bh);
+ pixman_image_composite(PIXMAN_OP_SRC, ssd->mirror, NULL, dest,
+ rect->left, rect->top, 0, 0,
+ 0, 0, bw, bh);
+ pixman_image_unref(dest);
cmd->type = QXL_CMD_DRAW;
cmd->data = (uintptr_t)drawable;
return;
};
- if (ssd->conv == NULL) {
- PixelFormat dst = qemu_default_pixelformat(32);
- ssd->conv = qemu_pf_conv_get(&dst, &ssd->ds->surface->pf);
- assert(ssd->conv);
- }
- if (ssd->ds_mirror == NULL) {
- int size = ds_get_height(ssd->ds) * ds_get_linesize(ssd->ds);
- ssd->ds_mirror = g_malloc0(size);
+ 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));
}
for (blk = 0; blk < blocks; blk++) {
}
guest = ds_get_data(ssd->ds);
- mirror = ssd->ds_mirror;
+ 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);
for (x = ssd->dirty.left; x < ssd->dirty.right; x += blksize) {
qemu_spice_destroy_primary_surface(ssd, 0, QXL_SYNC);
}
-void qemu_spice_vm_change_state_handler(void *opaque, int running,
- RunState state)
-{
-#if SPICE_SERVER_VERSION < 0x000b02 /* before 0.11.2 */
- SimpleSpiceDisplay *ssd = opaque;
-
- if (running) {
- ssd->running = true;
- qemu_spice_start(ssd);
- } else {
- qemu_spice_stop(ssd);
- ssd->running = false;
- }
-#endif
-}
-
void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds)
{
ssd->ds = ds;
dprint(1, "%s:\n", __FUNCTION__);
memset(&ssd->dirty, 0, sizeof(ssd->dirty));
- qemu_pf_conv_put(ssd->conv);
- ssd->conv = NULL;
- g_free(ssd->ds_mirror);
- ssd->ds_mirror = NULL;
+ if (ssd->surface) {
+ pixman_image_unref(ssd->surface);
+ ssd->surface = NULL;
+ pixman_image_unref(ssd->mirror);
+ ssd->mirror = NULL;
+ }
qemu_mutex_lock(&ssd->lock);
while ((update = QTAILQ_FIRST(&ssd->updates)) != NULL) {
void qemu_spice_cursor_refresh_unlocked(SimpleSpiceDisplay *ssd)
{
if (ssd->cursor) {
- ssd->ds->cursor_define(ssd->cursor);
+ dpy_cursor_define(ssd->ds, ssd->cursor);
cursor_put(ssd->cursor);
ssd->cursor = NULL;
}
if (ssd->mouse_x != -1 && ssd->mouse_y != -1) {
- ssd->ds->mouse_set(ssd->mouse_x, ssd->mouse_y, 1);
+ dpy_mouse_set(ssd->ds, ssd->mouse_x, ssd->mouse_y, 1);
ssd->mouse_x = -1;
ssd->mouse_y = -1;
}
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 DisplayChangeListener display_listener = {
- .dpy_update = display_update,
- .dpy_resize = display_resize,
+ .dpy_gfx_update = display_update,
+ .dpy_gfx_resize = display_resize,
.dpy_refresh = display_refresh,
};
{
assert(sdpy.ds == NULL);
qemu_spice_display_init_common(&sdpy, ds);
- 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);
+ register_displaychangelistener(ds, &display_listener);
}