F: ui/
F: include/ui/
F: qapi/ui.json
+F: util/drm.c
Cocoa graphics
--- /dev/null
+#ifndef QEMU_DRM_H_
+#define QEMU_DRM_H_
+
+int qemu_drm_rendernode_open(const char *rendernode);
+
+#endif
uint32_t stride;
uint32_t fourcc;
uint32_t texture;
+ bool y0_top;
};
typedef struct DisplayChangeListenerOps {
The ``-no-kvm'' argument is now a synonym for setting
``-machine accel=tcg''.
-@subsection -vnc tls (since 2.5.0)
-
-The ``-vnc tls'' argument is now a synonym for setting
-``-object tls-creds-anon,id=tls0'' combined with
-``-vnc tls-creds=tls0'
-
-@subsection -vnc x509 (since 2.5.0)
-
-The ``-vnc x509=/path/to/certs'' argument is now a
-synonym for setting
-``-object tls-creds-x509,dir=/path/to/certs,id=tls0,verify-peer=no''
-combined with ``-vnc tls-creds=tls0'
-
-@subsection -vnc x509verify (since 2.5.0)
-
-The ``-vnc x509verify=/path/to/certs'' argument is now a
-synonym for setting
-``-object tls-creds-x509,dir=/path/to/certs,id=tls0,verify-peer=yes''
-combined with ``-vnc tls-creds=tls0'
-
@subsection -tftp (since 2.6.0)
The ``-tftp /some/dir'' argument is replaced by either
client to connect, and provides an encrypted session.
@example
-qemu-system-i386 [...OPTIONS...] -vnc :1,tls,x509=/etc/pki/qemu -monitor stdio
+qemu-system-i386 [...OPTIONS...] \
+ -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=server,verify-peer=no \
+ -vnc :1,tls-creds=tls0 -monitor stdio
@end example
In the above example @code{/etc/pki/qemu} should contain at least three files,
Certificates can also provide a means to authenticate the client connecting.
The server will request that the client provide a certificate, which it will
then validate against the CA certificate. This is a good choice if deploying
-in an environment with a private internal certificate authority.
+in an environment with a private internal certificate authority. It uses the
+same syntax as previously, but with @code{verify-peer} set to @code{yes}
+instead.
@example
-qemu-system-i386 [...OPTIONS...] -vnc :1,tls,x509verify=/etc/pki/qemu -monitor stdio
+qemu-system-i386 [...OPTIONS...] \
+ -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=server,verify-peer=yes \
+ -vnc :1,tls-creds=tls0 -monitor stdio
@end example
to provide two layers of authentication for clients.
@example
-qemu-system-i386 [...OPTIONS...] -vnc :1,password,tls,x509verify=/etc/pki/qemu -monitor stdio
+qemu-system-i386 [...OPTIONS...] \
+ -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=server,verify-peer=yes \
+ -vnc :1,tls-creds=tls0,password -monitor stdio
(qemu) change vnc password
Password: ********
(qemu)
with the aforementioned TLS + x509 options:
@example
-qemu-system-i386 [...OPTIONS...] -vnc :1,tls,x509,sasl -monitor stdio
+qemu-system-i386 [...OPTIONS...] \
+ -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=server,verify-peer=yes \
+ -vnc :1,tls-creds=tls0,sasl -monitor stdio
@end example
@node vnc_setup_sasl
}
fprintf(outfile, "# evdev %d (0x%x), QKeyCode \"%s\", number 0x%x\n",
evdev, evdev,
- QKeyCode_lookup.array[qcode],
+ QKeyCode_str(qcode),
qcode_to_number(qcode));
/*
mechanism. The credentials should have been previously created
using the @option{-object tls-creds} argument.
-The @option{tls-creds} parameter obsoletes the @option{tls},
-@option{x509}, and @option{x509verify} options, and as such
-it is not permitted to set both new and old type options at
-the same time.
-
-@item tls
-
-Require that client use TLS when communicating with the VNC server. This
-uses anonymous TLS credentials so is susceptible to a man-in-the-middle
-attack. It is recommended that this option be combined with either the
-@option{x509} or @option{x509verify} options.
-
-This option is now deprecated in favor of using the @option{tls-creds}
-argument.
-
-@item x509=@var{/path/to/certificate/dir}
-
-Valid if @option{tls} is specified. Require that x509 credentials are used
-for negotiating the TLS session. The server will send its x509 certificate
-to the client. It is recommended that a password be set on the VNC server
-to provide authentication of the client when this is used. The path following
-this option specifies where the x509 certificates are to be loaded from.
-See the @ref{vnc_security} section for details on generating certificates.
-
-This option is now deprecated in favour of using the @option{tls-creds}
-argument.
-
-@item x509verify=@var{/path/to/certificate/dir}
-
-Valid if @option{tls} is specified. Require that x509 credentials are used
-for negotiating the TLS session. The server will send its x509 certificate
-to the client, and request that the client send its own x509 certificate.
-The server will validate the client's certificate against the CA certificate,
-and reject clients when validation fails. If the certificate authority is
-trusted, this is a sufficient authentication mechanism. You may still wish
-to set a password on the VNC server as a second authentication layer. The
-path following this option specifies where the x509 certificates are to
-be loaded from. See the @ref{vnc_security} section for details on generating
-certificates.
-
-This option is now deprecated in favour of using the @option{tls-creds}
-argument.
-
@item sasl
Require that the client use SASL to authenticate with the VNC server.
for (i = 0; i < ARRAY_SIZE(prio); i++) {
if (dpys[prio[i]] == NULL) {
- ui_module_load_one(DisplayType_lookup.array[prio[i]]);
+ ui_module_load_one(DisplayType_str(prio[i]));
}
if (dpys[prio[i]] == NULL) {
continue;
return;
}
if (dpys[opts->type] == NULL) {
- ui_module_load_one(DisplayType_lookup.array[opts->type]);
+ ui_module_load_one(DisplayType_str(opts->type));
}
if (dpys[opts->type] == NULL) {
error_report("Display '%s' is not available.",
- DisplayType_lookup.array[opts->type]);
+ DisplayType_str(opts->type));
exit(1);
}
if (dpys[opts->type]->early_init) {
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
-#include <glob.h>
-#include <dirent.h>
-
+#include "qemu/drm.h"
#include "qemu/error-report.h"
#include "ui/console.h"
#include "ui/egl-helpers.h"
struct gbm_device *qemu_egl_rn_gbm_dev;
EGLContext qemu_egl_rn_ctx;
-static int qemu_egl_rendernode_open(const char *rendernode)
-{
- DIR *dir;
- struct dirent *e;
- int r, fd;
- char *p;
-
- if (rendernode) {
- return open(rendernode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
- }
-
- dir = opendir("/dev/dri");
- if (!dir) {
- return -1;
- }
-
- fd = -1;
- while ((e = readdir(dir))) {
- if (e->d_type != DT_CHR) {
- continue;
- }
-
- if (strncmp(e->d_name, "renderD", 7)) {
- continue;
- }
-
- p = g_strdup_printf("/dev/dri/%s", e->d_name);
-
- r = open(p, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
- if (r < 0) {
- g_free(p);
- continue;
- }
- fd = r;
- g_free(p);
- break;
- }
-
- closedir(dir);
- if (fd < 0) {
- return -1;
- }
- return fd;
-}
-
int egl_rendernode_init(const char *rendernode, DisplayGLMode mode)
{
qemu_egl_rn_fd = -1;
int rc;
- qemu_egl_rn_fd = qemu_egl_rendernode_open(rendernode);
+ qemu_egl_rn_fd = qemu_drm_rendernode_open(rendernode);
if (qemu_egl_rn_fd == -1) {
error_report("egl: no drm render node available");
goto err;
{
assert(scon->opengl);
+ if (scon->scanout_mode) {
+ /* sdl2_gl_scanout_flush actually only care about
+ * the first argument. */
+ return sdl2_gl_scanout_flush(&scon->dcl, 0, 0, 0, 0);
+ }
if (scon->surface) {
sdl2_gl_render_surface(scon);
}
static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)
{
- int flags;
uint8_t data = 0;
char *filename;
int i;
setenv("SDL_VIDEODRIVER", "x11", 0);
#endif
- flags = SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE;
- if (SDL_Init(flags)) {
+ if (SDL_Init(SDL_INIT_VIDEO)) {
fprintf(stderr, "Could not initialize SDL(%s) - exiting\n",
SDL_GetError());
exit(1);
memset(&info, 0, sizeof(info));
SDL_VERSION(&info.version);
+ gui_fullscreen = o->has_full_screen && o->full_screen;
+
for (i = 0;; i++) {
QemuConsole *con = qemu_console_lookup_by_index(i);
if (!con) {
g_free(filename);
}
- if (sdl2_console->opts->has_full_screen &&
- sdl2_console->opts->full_screen) {
- gui_fullscreen = 1;
+ gui_grab = 0;
+ if (gui_fullscreen) {
sdl_grab_start(0);
}
mouse_mode_notifier.notify = sdl_mouse_mode_change;
qemu_add_mouse_mode_change_notifier(&mouse_mode_notifier);
- gui_grab = 0;
-
sdl_cursor_hidden = SDL_CreateCursor(&data, &data, 8, 1, 0, 0);
sdl_cursor_normal = SDL_GetCursor();
qemu_mutex_unlock(&ssd->lock);
}
-static void qemu_spice_cursor_refresh_unlocked(SimpleSpiceDisplay *ssd)
+void qemu_spice_cursor_refresh_bh(void *opaque)
{
+ SimpleSpiceDisplay *ssd = opaque;
+
+ qemu_mutex_lock(&ssd->lock);
if (ssd->cursor) {
+ QEMUCursor *c = ssd->cursor;
assert(ssd->dcl.con);
- dpy_cursor_define(ssd->dcl.con, ssd->cursor);
+ cursor_get(c);
+ qemu_mutex_unlock(&ssd->lock);
+ dpy_cursor_define(ssd->dcl.con, c);
+ qemu_mutex_lock(&ssd->lock);
+ cursor_put(c);
}
+
if (ssd->mouse_x != -1 && ssd->mouse_y != -1) {
+ int x, y;
assert(ssd->dcl.con);
- dpy_mouse_set(ssd->dcl.con, ssd->mouse_x, ssd->mouse_y, 1);
+ x = ssd->mouse_x;
+ y = ssd->mouse_y;
ssd->mouse_x = -1;
ssd->mouse_y = -1;
+ qemu_mutex_unlock(&ssd->lock);
+ dpy_mouse_set(ssd->dcl.con, x, y, 1);
+ } else {
+ qemu_mutex_unlock(&ssd->lock);
}
}
-void qemu_spice_cursor_refresh_bh(void *opaque)
-{
- SimpleSpiceDisplay *ssd = opaque;
-
- qemu_mutex_lock(&ssd->lock);
- qemu_spice_cursor_refresh_unlocked(ssd);
- qemu_mutex_unlock(&ssd->lock);
-}
-
void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd)
{
graphic_hw_update(ssd->dcl.con);
{
SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
+ qemu_mutex_lock(&ssd->lock);
ssd->ptr_x = pos_x;
ssd->ptr_y = pos_y;
+ qemu_mutex_unlock(&ssd->lock);
}
static void qemu_spice_gl_release_dmabuf(DisplayChangeListener *dcl,
/* note: spice server will close the fd, so hand over a dup */
spice_qxl_gl_scanout(&ssd->qxl, dup(dmabuf->fd),
dmabuf->width, dmabuf->height,
- dmabuf->stride, dmabuf->fourcc, false);
+ dmabuf->stride, dmabuf->fourcc,
+ dmabuf->y0_top);
}
qemu_spice_gl_monitor_config(ssd, 0, 0, dmabuf->width, dmabuf->height);
ssd->guest_dmabuf_refresh = false;
}
if (render_cursor) {
+ int x, y;
+ qemu_mutex_lock(&ssd->lock);
+ x = ssd->ptr_x;
+ y = ssd->ptr_y;
+ qemu_mutex_unlock(&ssd->lock);
egl_texture_blit(ssd->gls, &ssd->blit_fb, &ssd->guest_fb,
!y_0_top);
egl_texture_blend(ssd->gls, &ssd->blit_fb, &ssd->cursor_fb,
- !y_0_top, ssd->ptr_x, ssd->ptr_y);
+ !y_0_top, x, y);
glFlush();
}
}
#endif
- bytes = (DIV_ROUND_UP(w, 8)) * h;
+ bytes = DIV_ROUND_UP(w, 8) * h;
vnc_write_u8(vs, (stream | VNC_TIGHT_EXPLICIT_FILTER) << 4);
vnc_write_u8(vs, VNC_TIGHT_FILTER_PALETTE);
static void vnc_async_encoding_end(VncState *orig, VncState *local)
{
+ buffer_free(&local->output);
orig->tight = local->tight;
orig->zlib = local->zlib;
orig->hextile = local->hextile;
/* Copy persistent encoding data */
vnc_async_encoding_end(job->vs, &vs);
- qemu_bh_schedule(job->vs->bh);
+ qemu_bh_schedule(job->vs->bh);
} else {
buffer_reset(&vs.output);
/* Copy persistent encoding data */
PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
guest_stride = pixman_image_get_stride(vd->guest.fb);
- guest_ll = pixman_image_get_width(vd->guest.fb) * (DIV_ROUND_UP(guest_bpp, 8));
+ guest_ll = pixman_image_get_width(vd->guest.fb)
+ * DIV_ROUND_UP(guest_bpp, 8);
}
line_bytes = MIN(server_stride, guest_ll);
},{
.name = "tls-creds",
.type = QEMU_OPT_STRING,
- },{
- /* Deprecated in favour of tls-creds */
- .name = "x509",
- .type = QEMU_OPT_STRING,
},{
.name = "share",
.type = QEMU_OPT_STRING,
},{
.name = "sasl",
.type = QEMU_OPT_BOOL,
- },{
- /* Deprecated in favour of tls-creds */
- .name = "tls",
- .type = QEMU_OPT_BOOL,
- },{
- /* Deprecated in favour of tls-creds */
- .name = "x509verify",
- .type = QEMU_OPT_STRING,
},{
.name = "acl",
.type = QEMU_OPT_BOOL,
}
-/*
- * Handle back compat with old CLI syntax by creating some
- * suitable QCryptoTLSCreds objects
- */
-static QCryptoTLSCreds *
-vnc_display_create_creds(bool x509,
- bool x509verify,
- const char *dir,
- const char *id,
- Error **errp)
-{
- gchar *credsid = g_strdup_printf("tlsvnc%s", id);
- Object *parent = object_get_objects_root();
- Object *creds;
- Error *err = NULL;
-
- if (x509) {
- creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509,
- parent,
- credsid,
- &err,
- "endpoint", "server",
- "dir", dir,
- "verify-peer", x509verify ? "yes" : "no",
- NULL);
- } else {
- creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON,
- parent,
- credsid,
- &err,
- "endpoint", "server",
- NULL);
- }
-
- g_free(credsid);
-
- if (err) {
- error_propagate(errp, err);
- return NULL;
- }
-
- return QCRYPTO_TLS_CREDS(creds);
-}
-
-
static int vnc_display_get_address(const char *addrstr,
bool websocket,
bool reverse,
credid = qemu_opt_get(opts, "tls-creds");
if (credid) {
Object *creds;
- if (qemu_opt_get(opts, "tls") ||
- qemu_opt_get(opts, "x509") ||
- qemu_opt_get(opts, "x509verify")) {
- error_setg(errp,
- "'tls-creds' parameter is mutually exclusive with "
- "'tls', 'x509' and 'x509verify' parameters");
- goto fail;
- }
-
creds = object_resolve_path_component(
object_get_objects_root(), credid);
if (!creds) {
"Expecting TLS credentials with a server endpoint");
goto fail;
}
- } else {
- const char *path;
- bool tls = false, x509 = false, x509verify = false;
- tls = qemu_opt_get_bool(opts, "tls", false);
- if (tls) {
- path = qemu_opt_get(opts, "x509");
-
- if (path) {
- x509 = true;
- } else {
- path = qemu_opt_get(opts, "x509verify");
- if (path) {
- x509 = true;
- x509verify = true;
- }
- }
- vd->tlscreds = vnc_display_create_creds(x509,
- x509verify,
- path,
- vd->id,
- errp);
- if (!vd->tlscreds) {
- goto fail;
- }
- }
}
acl = qemu_opt_get_bool(opts, "acl", false);
util-obj-y += systemd.o
util-obj-y += iova-tree.o
util-obj-$(CONFIG_LINUX) += vfio-helpers.o
+util-obj-$(CONFIG_OPENGL) += drm.o
--- /dev/null
+/*
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include "qemu/osdep.h"
+#include "qemu/drm.h"
+
+#include <glob.h>
+#include <dirent.h>
+
+int qemu_drm_rendernode_open(const char *rendernode)
+{
+ DIR *dir;
+ struct dirent *e;
+ int r, fd;
+ char *p;
+
+ if (rendernode) {
+ return open(rendernode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
+ }
+
+ dir = opendir("/dev/dri");
+ if (!dir) {
+ return -1;
+ }
+
+ fd = -1;
+ while ((e = readdir(dir))) {
+ if (e->d_type != DT_CHR) {
+ continue;
+ }
+
+ if (strncmp(e->d_name, "renderD", 7)) {
+ continue;
+ }
+
+ p = g_strdup_printf("/dev/dri/%s", e->d_name);
+
+ r = open(p, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
+ if (r < 0) {
+ g_free(p);
+ continue;
+ }
+ fd = r;
+ g_free(p);
+ break;
+ }
+
+ closedir(dir);
+ if (fd < 0) {
+ return -1;
+ }
+ return fd;
+}