aboutsummaryrefslogtreecommitdiff
path: root/ui
diff options
context:
space:
mode:
Diffstat (limited to 'ui')
-rw-r--r--ui/curses.c1
-rw-r--r--ui/qemu-spice.h12
-rw-r--r--ui/sdl.c16
-rw-r--r--ui/spice-core.c26
-rw-r--r--ui/spice-display.c61
-rw-r--r--ui/spice-display.h24
6 files changed, 98 insertions, 42 deletions
diff --git a/ui/curses.c b/ui/curses.c
index 82bc614..d29b6cf 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -24,7 +24,6 @@
#include <curses.h>
#ifndef _WIN32
-#include <signal.h>
#include <sys/ioctl.h>
#include <termios.h>
#endif
diff --git a/ui/qemu-spice.h b/ui/qemu-spice.h
index 916e5dc..3c6f1fe 100644
--- a/ui/qemu-spice.h
+++ b/ui/qemu-spice.h
@@ -47,8 +47,16 @@ CharDriverState *qemu_chr_open_spice(QemuOpts *opts);
#else /* CONFIG_SPICE */
#define using_spice 0
-#define qemu_spice_set_passwd(_p, _f1, _f2) (-1)
-#define qemu_spice_set_pw_expire(_e) (-1)
+static inline int qemu_spice_set_passwd(const char *passwd,
+ bool fail_if_connected,
+ bool disconnect_if_connected)
+{
+ return -1;
+}
+static inline int qemu_spice_set_pw_expire(time_t expires)
+{
+ return -1;
+}
static inline int qemu_spice_migrate_info(const char *h, int p, int t, const char *s)
{ return -1; }
diff --git a/ui/sdl.c b/ui/sdl.c
index dc5c3a1..f2bd4a0 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -28,10 +28,6 @@
#include <SDL.h>
#include <SDL_syswm.h>
-#ifndef _WIN32
-#include <signal.h>
-#endif
-
#include "qemu-common.h"
#include "console.h"
#include "sysemu.h"
@@ -831,6 +827,18 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
if (!full_screen) {
setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 0);
}
+#ifdef __linux__
+ /* on Linux, SDL may use fbcon|directfb|svgalib when run without
+ * accessible $DISPLAY to open X11 window. This is often the case
+ * when qemu is run using sudo. But in this case, and when actually
+ * run in X11 environment, SDL fights with X11 for the video card,
+ * making current display unavailable, often until reboot.
+ * So make x11 the default SDL video driver if this variable is unset.
+ * This is a bit hackish but saves us from bigger problem.
+ * Maybe it's a good idea to fix this in SDL instead.
+ */
+ setenv("SDL_VIDEODRIVER", "x11", 0);
+#endif
/* Enable normal up/down events for Caps-Lock and Num-Lock keys.
* This requires SDL >= 1.2.14. */
diff --git a/ui/spice-core.c b/ui/spice-core.c
index ef56ed6..dd9905b 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -299,8 +299,6 @@ static int parse_name(const char *string, const char *optname,
exit(1);
}
-#if SPICE_SERVER_VERSION >= 0x000600 /* 0.6.0 */
-
static const char *stream_video_names[] = {
[ SPICE_STREAM_VIDEO_OFF ] = "off",
[ SPICE_STREAM_VIDEO_ALL ] = "all",
@@ -309,8 +307,6 @@ static const char *stream_video_names[] = {
#define parse_stream_video(_name) \
name2enum(_name, stream_video_names, ARRAY_SIZE(stream_video_names))
-#endif /* >= 0.6.0 */
-
static const char *compression_names[] = {
[ SPICE_IMAGE_COMPRESS_OFF ] = "off",
[ SPICE_IMAGE_COMPRESS_AUTO_GLZ ] = "auto_glz",
@@ -549,11 +545,29 @@ void qemu_spice_init(void)
if (password) {
spice_server_set_ticket(spice_server, password, 0, 0, 0);
}
+ if (qemu_opt_get_bool(opts, "sasl", 0)) {
+#if SPICE_SERVER_VERSION >= 0x000900 /* 0.9.0 */
+ if (spice_server_set_sasl_appname(spice_server, "qemu") == -1 ||
+ spice_server_set_sasl(spice_server, 1) == -1) {
+ fprintf(stderr, "spice: failed to enable sasl\n");
+ exit(1);
+ }
+#else
+ fprintf(stderr, "spice: sasl is not available (spice >= 0.9 required)\n");
+ exit(1);
+#endif
+ }
if (qemu_opt_get_bool(opts, "disable-ticketing", 0)) {
auth = "none";
spice_server_set_noauth(spice_server);
}
+#if SPICE_SERVER_VERSION >= 0x000801
+ if (qemu_opt_get_bool(opts, "disable-copy-paste", 0)) {
+ spice_server_set_agent_copypaste(spice_server, false);
+ }
+#endif
+
compression = SPICE_IMAGE_COMPRESS_AUTO_GLZ;
str = qemu_opt_get(opts, "image-compression");
if (str) {
@@ -575,8 +589,6 @@ void qemu_spice_init(void)
}
spice_server_set_zlib_glz_compression(spice_server, wan_compr);
-#if SPICE_SERVER_VERSION >= 0x000600 /* 0.6.0 */
-
str = qemu_opt_get(opts, "streaming-video");
if (str) {
int streaming_video = parse_stream_video(str);
@@ -588,8 +600,6 @@ void qemu_spice_init(void)
spice_server_set_playback_compression
(spice_server, qemu_opt_get_bool(opts, "playback-compression", 1));
-#endif /* >= 0.6.0 */
-
qemu_opt_foreach(opts, add_channel, NULL, 0);
spice_server_init(spice_server, &core_interface);
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 020b423..15f0704 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -62,14 +62,7 @@ void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r)
dest->right = MAX(dest->right, r->right);
}
-/*
- * Called from spice server thread context (via interface_get_command).
- *
- * We must aquire the global qemu mutex here to make sure the
- * DisplayState (+DisplaySurface) we are accessing doesn't change
- * underneath us.
- */
-SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
+static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
{
SimpleSpiceUpdate *update;
QXLDrawable *drawable;
@@ -78,9 +71,7 @@ SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
uint8_t *src, *dst;
int by, bw, bh;
- qemu_mutex_lock_iothread();
if (qemu_spice_rect_is_empty(&ssd->dirty)) {
- qemu_mutex_unlock_iothread();
return NULL;
};
@@ -141,7 +132,6 @@ SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
cmd->data = (intptr_t)drawable;
memset(&ssd->dirty, 0, sizeof(ssd->dirty));
- qemu_mutex_unlock_iothread();
return update;
}
@@ -186,18 +176,14 @@ void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
surface.mem = (intptr_t)ssd->buf;
surface.group_id = MEMSLOT_GROUP_HOST;
- qemu_mutex_unlock_iothread();
ssd->worker->create_primary_surface(ssd->worker, 0, &surface);
- qemu_mutex_lock_iothread();
}
void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd)
{
dprint(1, "%s:\n", __FUNCTION__);
- qemu_mutex_unlock_iothread();
ssd->worker->destroy_primary_surface(ssd->worker, 0);
- qemu_mutex_lock_iothread();
}
void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason)
@@ -207,9 +193,7 @@ void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason)
if (running) {
ssd->worker->start(ssd->worker);
} else {
- qemu_mutex_unlock_iothread();
ssd->worker->stop(ssd->worker);
- qemu_mutex_lock_iothread();
}
ssd->running = running;
}
@@ -241,6 +225,12 @@ void qemu_spice_display_resize(SimpleSpiceDisplay *ssd)
qemu_pf_conv_put(ssd->conv);
ssd->conv = NULL;
+ qemu_mutex_lock(&ssd->lock);
+ if (ssd->update != NULL) {
+ qemu_spice_destroy_update(ssd, ssd->update);
+ ssd->update = NULL;
+ }
+ qemu_mutex_unlock(&ssd->lock);
qemu_spice_destroy_host_primary(ssd);
qemu_spice_create_host_primary(ssd);
@@ -252,6 +242,24 @@ void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd)
{
dprint(3, "%s:\n", __FUNCTION__);
vga_hw_update();
+
+ qemu_mutex_lock(&ssd->lock);
+ if (ssd->update == NULL) {
+ ssd->update = qemu_spice_create_update(ssd);
+ ssd->notify++;
+ }
+ if (ssd->cursor) {
+ ssd->ds->cursor_define(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);
+ ssd->mouse_x = -1;
+ ssd->mouse_y = -1;
+ }
+ qemu_mutex_unlock(&ssd->lock);
+
if (ssd->notify) {
ssd->notify = 0;
ssd->worker->wakeup(ssd->worker);
@@ -298,14 +306,20 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
{
SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
SimpleSpiceUpdate *update;
+ int ret = false;
dprint(3, "%s:\n", __FUNCTION__);
- update = qemu_spice_create_update(ssd);
- if (update == NULL) {
- return false;
+
+ qemu_mutex_lock(&ssd->lock);
+ if (ssd->update != NULL) {
+ update = ssd->update;
+ ssd->update = NULL;
+ *ext = update->ext;
+ ret = true;
}
- *ext = update->ext;
- return true;
+ qemu_mutex_unlock(&ssd->lock);
+
+ return ret;
}
static int interface_req_cmd_notification(QXLInstance *sin)
@@ -398,6 +412,9 @@ void qemu_spice_display_init(DisplayState *ds)
{
assert(sdpy.ds == NULL);
sdpy.ds = ds;
+ qemu_mutex_init(&sdpy.lock);
+ sdpy.mouse_x = -1;
+ sdpy.mouse_y = -1;
sdpy.bufsize = (16 * 1024 * 1024);
sdpy.buf = qemu_malloc(sdpy.bufsize);
register_displaychangelistener(ds, &display_listener);
diff --git a/ui/spice-display.h b/ui/spice-display.h
index aef0464..2f95f68 100644
--- a/ui/spice-display.h
+++ b/ui/spice-display.h
@@ -19,6 +19,8 @@
#include <spice/enums.h>
#include <spice/qxl_dev.h>
+#include "qemu-thread.h"
+#include "console.h"
#include "pflib.h"
#define NUM_MEMSLOTS 8
@@ -31,7 +33,10 @@
#define NUM_SURFACES 1024
-typedef struct SimpleSpiceDisplay {
+typedef struct SimpleSpiceDisplay SimpleSpiceDisplay;
+typedef struct SimpleSpiceUpdate SimpleSpiceUpdate;
+
+struct SimpleSpiceDisplay {
DisplayState *ds;
void *buf;
int bufsize;
@@ -43,19 +48,28 @@ typedef struct SimpleSpiceDisplay {
QXLRect dirty;
int notify;
int running;
-} SimpleSpiceDisplay;
-typedef struct SimpleSpiceUpdate {
+ /*
+ * All struct members below this comment can be accessed from
+ * both spice server and qemu (iothread) context and any access
+ * to them must be protected by the lock.
+ */
+ QemuMutex lock;
+ SimpleSpiceUpdate *update;
+ QEMUCursor *cursor;
+ int mouse_x, mouse_y;
+};
+
+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);