gtk: fix kbd on xwayland

vnc: fix double free issues
 opengl improvements
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJYtE+yAAoJEEy22O7T6HE4MEoQAJkVHsVE6uh8xNJS+CWc/KDp
 mOJp44pdkjxJckHs2HnoecUKhA1zge0oYXbo4Id7NFyu2aKDT102TBd2iI3yKAkZ
 csucfEexgFI6V6eYH7MqIpM6EOnNfXa2pNuIhP7ifn8WtQzpBSJE/mdhVxRMEqnc
 NNAA1T1uLtZ/isbseFsTLtod4V91k67lsWipErSHXyOiV3DLwVUc31eHZZT8Kmsg
 iMbKZPAf+4r8OKHLIBC5a617/musHSBDu5VxBB3ZCl8rXOL46gzeqTUSMq4pjZY0
 YyxHXwcKC0LqT+VuOt6j1Q9vW/dPCIfDMojy+35xAS56aRktSb/5fPk7I+axib6L
 lgRBxd2Bx9AVtVkTQi7VqOv5O1FzDYdMO+7pOLfNu+6LgcONrj2nf0emEz/nJhra
 pFu7RU3MOqS4+UJb3DFnDyiJgqCj4Hjf305DEQWZ5BB8HPrn1OjvMMOMmn6SfQPV
 +6eDw2epU739IQ7R61AqEqILQUkdCEEL/3NwmQrfM+mFDUp+3y4W1MJiGbk5Xcpx
 zoIrvYEkw+gPIZ0FzFGj5xaXtjUBi+7p140h9EwZ+XvDM6YbxIQ28PJY8aNzb9ho
 bsfdexTAKOTcAzSkS98EbObrr719CIehQrRprgpjAFQ+nWgSzvJVs8b5W5OPNtwW
 1k84GVbrJYDlwntZgdss
 =xV24
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/kraxel/tags/pull-ui-20170227-1' into staging

gtk: fix kbd on xwayland
vnc: fix double free issues
opengl improvements

# gpg: Signature made Mon 27 Feb 2017 16:11:30 GMT
# gpg:                using RSA key 0x4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"
# Primary key fingerprint: A032 8CFF B93A 17A7 9901  FE7D 4CB6 D8EE D3E8 7138

* remotes/kraxel/tags/pull-ui-20170227-1:
  vnc: fix double free issues
  spice: add display & head options
  ui: Use XkbGetMap and XkbGetNames instead of XkbGetKeyboard
  gtk-egl: add scanout_disable support
  sdl2: add scanout_disable support
  spice: add scanout_disable support
  virtio-gpu: use dpy_gl_scanout_disable
  console: add dpy_gl_scanout_disable
  console: rename dpy_gl_scanout to dpy_gl_scanout_texture

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2017-02-27 19:19:46 +00:00
commit 9b9fbe8a4e
14 changed files with 178 additions and 97 deletions

View file

@ -177,16 +177,15 @@ static void virgl_cmd_set_scanout(VirtIOGPU *g,
qemu_console_resize(g->scanout[ss.scanout_id].con,
ss.r.width, ss.r.height);
virgl_renderer_force_ctx_0();
dpy_gl_scanout(g->scanout[ss.scanout_id].con, info.tex_id,
info.flags & 1 /* FIXME: Y_0_TOP */,
info.width, info.height,
ss.r.x, ss.r.y, ss.r.width, ss.r.height);
dpy_gl_scanout_texture(g->scanout[ss.scanout_id].con, info.tex_id,
info.flags & 1 /* FIXME: Y_0_TOP */,
info.width, info.height,
ss.r.x, ss.r.y, ss.r.width, ss.r.height);
} else {
if (ss.scanout_id != 0) {
dpy_gfx_replace_surface(g->scanout[ss.scanout_id].con, NULL);
}
dpy_gl_scanout(g->scanout[ss.scanout_id].con, 0, false,
0, 0, 0, 0, 0, 0);
dpy_gl_scanout_disable(g->scanout[ss.scanout_id].con);
}
g->scanout[ss.scanout_id].resource_id = ss.resource_id;
}
@ -597,7 +596,7 @@ void virtio_gpu_virgl_reset(VirtIOGPU *g)
if (i != 0) {
dpy_gfx_replace_surface(g->scanout[i].con, NULL);
}
dpy_gl_scanout(g->scanout[i].con, 0, false, 0, 0, 0, 0, 0, 0);
dpy_gl_scanout_disable(g->scanout[i].con);
}
}

View file

@ -215,10 +215,14 @@ typedef struct DisplayChangeListenerOps {
QEMUGLContext ctx);
QEMUGLContext (*dpy_gl_ctx_get_current)(DisplayChangeListener *dcl);
void (*dpy_gl_scanout)(DisplayChangeListener *dcl,
uint32_t backing_id, bool backing_y_0_top,
uint32_t backing_width, uint32_t backing_height,
uint32_t x, uint32_t y, uint32_t w, uint32_t h);
void (*dpy_gl_scanout_disable)(DisplayChangeListener *dcl);
void (*dpy_gl_scanout_texture)(DisplayChangeListener *dcl,
uint32_t backing_id,
bool backing_y_0_top,
uint32_t backing_width,
uint32_t backing_height,
uint32_t x, uint32_t y,
uint32_t w, uint32_t h);
void (*dpy_gl_update)(DisplayChangeListener *dcl,
uint32_t x, uint32_t y, uint32_t w, uint32_t h);
@ -284,10 +288,11 @@ bool dpy_cursor_define_supported(QemuConsole *con);
bool dpy_gfx_check_format(QemuConsole *con,
pixman_format_code_t format);
void dpy_gl_scanout(QemuConsole *con,
uint32_t backing_id, bool backing_y_0_top,
uint32_t backing_width, uint32_t backing_height,
uint32_t x, uint32_t y, uint32_t w, uint32_t h);
void dpy_gl_scanout_disable(QemuConsole *con);
void dpy_gl_scanout_texture(QemuConsole *con,
uint32_t backing_id, bool backing_y_0_top,
uint32_t backing_width, uint32_t backing_height,
uint32_t x, uint32_t y, uint32_t w, uint32_t h);
void dpy_gl_update(QemuConsole *con,
uint32_t x, uint32_t y, uint32_t w, uint32_t h);

View file

@ -103,11 +103,14 @@ void gd_egl_switch(DisplayChangeListener *dcl,
DisplaySurface *surface);
QEMUGLContext gd_egl_create_context(DisplayChangeListener *dcl,
QEMUGLParams *params);
void gd_egl_scanout(DisplayChangeListener *dcl,
uint32_t backing_id, bool backing_y_0_top,
uint32_t backing_width, uint32_t backing_height,
uint32_t x, uint32_t y,
uint32_t w, uint32_t h);
void gd_egl_scanout_disable(DisplayChangeListener *dcl);
void gd_egl_scanout_texture(DisplayChangeListener *dcl,
uint32_t backing_id,
bool backing_y_0_top,
uint32_t backing_width,
uint32_t backing_height,
uint32_t x, uint32_t y,
uint32_t w, uint32_t h);
void gd_egl_scanout_flush(DisplayChangeListener *dcl,
uint32_t x, uint32_t y, uint32_t w, uint32_t h);
void gtk_egl_init(void);
@ -126,11 +129,13 @@ QEMUGLContext gd_gl_area_create_context(DisplayChangeListener *dcl,
QEMUGLParams *params);
void gd_gl_area_destroy_context(DisplayChangeListener *dcl,
QEMUGLContext ctx);
void gd_gl_area_scanout(DisplayChangeListener *dcl,
uint32_t backing_id, bool backing_y_0_top,
uint32_t backing_width, uint32_t backing_height,
uint32_t x, uint32_t y,
uint32_t w, uint32_t h);
void gd_gl_area_scanout_texture(DisplayChangeListener *dcl,
uint32_t backing_id,
bool backing_y_0_top,
uint32_t backing_width,
uint32_t backing_height,
uint32_t x, uint32_t y,
uint32_t w, uint32_t h);
void gd_gl_area_scanout_flush(DisplayChangeListener *dcl,
uint32_t x, uint32_t y, uint32_t w, uint32_t h);
void gtk_gl_area_init(void);

View file

@ -62,11 +62,14 @@ int sdl2_gl_make_context_current(DisplayChangeListener *dcl,
QEMUGLContext ctx);
QEMUGLContext sdl2_gl_get_current_context(DisplayChangeListener *dcl);
void sdl2_gl_scanout(DisplayChangeListener *dcl,
uint32_t backing_id, bool backing_y_0_top,
uint32_t backing_width, uint32_t backing_height,
uint32_t x, uint32_t y,
uint32_t w, uint32_t h);
void sdl2_gl_scanout_disable(DisplayChangeListener *dcl);
void sdl2_gl_scanout_texture(DisplayChangeListener *dcl,
uint32_t backing_id,
bool backing_y_0_top,
uint32_t backing_width,
uint32_t backing_height,
uint32_t x, uint32_t y,
uint32_t w, uint32_t h);
void sdl2_gl_scanout_flush(DisplayChangeListener *dcl,
uint32_t x, uint32_t y, uint32_t w, uint32_t h);

View file

@ -1735,16 +1735,30 @@ QEMUGLContext dpy_gl_ctx_get_current(QemuConsole *con)
return con->gl->ops->dpy_gl_ctx_get_current(con->gl);
}
void dpy_gl_scanout(QemuConsole *con,
uint32_t backing_id, bool backing_y_0_top,
uint32_t backing_width, uint32_t backing_height,
uint32_t x, uint32_t y, uint32_t width, uint32_t height)
void dpy_gl_scanout_disable(QemuConsole *con)
{
assert(con->gl);
con->gl->ops->dpy_gl_scanout(con->gl, backing_id,
backing_y_0_top,
backing_width, backing_height,
x, y, width, height);
if (con->gl->ops->dpy_gl_scanout_disable) {
con->gl->ops->dpy_gl_scanout_disable(con->gl);
} else {
con->gl->ops->dpy_gl_scanout_texture(con->gl, 0, false, 0, 0,
0, 0, 0, 0);
}
}
void dpy_gl_scanout_texture(QemuConsole *con,
uint32_t backing_id,
bool backing_y_0_top,
uint32_t backing_width,
uint32_t backing_height,
uint32_t x, uint32_t y,
uint32_t width, uint32_t height)
{
assert(con->gl);
con->gl->ops->dpy_gl_scanout_texture(con->gl, backing_id,
backing_y_0_top,
backing_width, backing_height,
x, y, width, height);
}
void dpy_gl_update(QemuConsole *con,

View file

@ -170,11 +170,21 @@ QEMUGLContext gd_egl_create_context(DisplayChangeListener *dcl,
return qemu_egl_create_context(dcl, params);
}
void gd_egl_scanout(DisplayChangeListener *dcl,
uint32_t backing_id, bool backing_y_0_top,
uint32_t backing_width, uint32_t backing_height,
uint32_t x, uint32_t y,
uint32_t w, uint32_t h)
void gd_egl_scanout_disable(DisplayChangeListener *dcl)
{
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
vc->gfx.w = 0;
vc->gfx.h = 0;
vc->gfx.tex_id = 0;
gtk_egl_set_scanout_mode(vc, false);
}
void gd_egl_scanout_texture(DisplayChangeListener *dcl,
uint32_t backing_id, bool backing_y_0_top,
uint32_t backing_width, uint32_t backing_height,
uint32_t x, uint32_t y,
uint32_t w, uint32_t h)
{
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
@ -188,11 +198,6 @@ void gd_egl_scanout(DisplayChangeListener *dcl,
eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
vc->gfx.esurface, vc->gfx.ectx);
if (vc->gfx.tex_id == 0 || vc->gfx.w == 0 || vc->gfx.h == 0) {
gtk_egl_set_scanout_mode(vc, false);
return;
}
gtk_egl_set_scanout_mode(vc, true);
if (!vc->gfx.fbo_id) {
glGenFramebuffers(1, &vc->gfx.fbo_id);

View file

@ -167,11 +167,13 @@ void gd_gl_area_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx)
/* FIXME */
}
void gd_gl_area_scanout(DisplayChangeListener *dcl,
uint32_t backing_id, bool backing_y_0_top,
uint32_t backing_width, uint32_t backing_height,
uint32_t x, uint32_t y,
uint32_t w, uint32_t h)
void gd_gl_area_scanout_texture(DisplayChangeListener *dcl,
uint32_t backing_id,
bool backing_y_0_top,
uint32_t backing_width,
uint32_t backing_height,
uint32_t x, uint32_t y,
uint32_t w, uint32_t h)
{
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);

View file

@ -669,7 +669,7 @@ static const DisplayChangeListenerOps dcl_gl_area_ops = {
.dpy_gl_ctx_destroy = gd_gl_area_destroy_context,
.dpy_gl_ctx_make_current = gd_gl_area_make_current,
.dpy_gl_ctx_get_current = gd_gl_area_get_current_context,
.dpy_gl_scanout = gd_gl_area_scanout,
.dpy_gl_scanout_texture = gd_gl_area_scanout_texture,
.dpy_gl_update = gd_gl_area_scanout_flush,
};
@ -688,7 +688,8 @@ static const DisplayChangeListenerOps dcl_egl_ops = {
.dpy_gl_ctx_destroy = qemu_egl_destroy_context,
.dpy_gl_ctx_make_current = gd_egl_make_current,
.dpy_gl_ctx_get_current = qemu_egl_get_current_context,
.dpy_gl_scanout = gd_egl_scanout,
.dpy_gl_scanout_disable = gd_egl_scanout_disable,
.dpy_gl_scanout_texture = gd_egl_scanout_texture,
.dpy_gl_update = gd_egl_scanout_flush,
};
@ -2200,11 +2201,12 @@ static void gd_set_keycode_type(GtkDisplayState *s)
GdkDisplay *display = gtk_widget_get_display(s->window);
if (GDK_IS_X11_DISPLAY(display)) {
Display *x11_display = gdk_x11_display_get_xdisplay(display);
XkbDescPtr desc = XkbGetKeyboard(x11_display, XkbGBN_AllComponentsMask,
XkbUseCoreKbd);
XkbDescPtr desc = XkbGetMap(x11_display, XkbGBN_AllComponentsMask,
XkbUseCoreKbd);
char *keycodes = NULL;
if (desc && desc->names) {
if (desc &&
(XkbGetNames(x11_display, XkbKeycodesNameMask, desc) == Success)) {
keycodes = XGetAtomName(x11_display, desc->names->keycodes);
}
if (keycodes == NULL) {

View file

@ -233,10 +233,12 @@ static int check_for_evdev(void)
if (!SDL_GetWMInfo(&info)) {
return 0;
}
desc = XkbGetKeyboard(info.info.x11.display,
XkbGBN_AllComponentsMask,
XkbUseCoreKbd);
if (desc && desc->names) {
desc = XkbGetMap(info.info.x11.display,
XkbGBN_AllComponentsMask,
XkbUseCoreKbd);
if (desc &&
(XkbGetNames(info.info.x11.display,
XkbKeycodesNameMask, desc) == Success)) {
keycodes = XGetAtomName(info.info.x11.display, desc->names->keycodes);
if (keycodes == NULL) {
fprintf(stderr, "could not lookup keycode name\n");

View file

@ -184,11 +184,24 @@ QEMUGLContext sdl2_gl_get_current_context(DisplayChangeListener *dcl)
return (QEMUGLContext)sdlctx;
}
void sdl2_gl_scanout(DisplayChangeListener *dcl,
uint32_t backing_id, bool backing_y_0_top,
uint32_t backing_width, uint32_t backing_height,
uint32_t x, uint32_t y,
uint32_t w, uint32_t h)
void sdl2_gl_scanout_disable(DisplayChangeListener *dcl)
{
struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
assert(scon->opengl);
scon->w = 0;
scon->h = 0;
scon->tex_id = 0;
sdl2_set_scanout_mode(scon, false);
}
void sdl2_gl_scanout_texture(DisplayChangeListener *dcl,
uint32_t backing_id,
bool backing_y_0_top,
uint32_t backing_width,
uint32_t backing_height,
uint32_t x, uint32_t y,
uint32_t w, uint32_t h)
{
struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
@ -202,11 +215,6 @@ void sdl2_gl_scanout(DisplayChangeListener *dcl,
SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
if (scon->tex_id == 0 || scon->w == 0 || scon->h == 0) {
sdl2_set_scanout_mode(scon, false);
return;
}
sdl2_set_scanout_mode(scon, true);
if (!scon->fbo_id) {
glGenFramebuffers(1, &scon->fbo_id);

View file

@ -733,7 +733,8 @@ static const DisplayChangeListenerOps dcl_gl_ops = {
.dpy_gl_ctx_destroy = sdl2_gl_destroy_context,
.dpy_gl_ctx_make_current = sdl2_gl_make_context_current,
.dpy_gl_ctx_get_current = sdl2_gl_get_current_context,
.dpy_gl_scanout = sdl2_gl_scanout,
.dpy_gl_scanout_disable = sdl2_gl_scanout_disable,
.dpy_gl_scanout_texture = sdl2_gl_scanout_texture,
.dpy_gl_update = sdl2_gl_scanout_flush,
};
#endif

View file

@ -497,6 +497,12 @@ static QemuOptsList qemu_spice_opts = {
},{
.name = "seamless-migration",
.type = QEMU_OPT_BOOL,
},{
.name = "display",
.type = QEMU_OPT_STRING,
},{
.name = "head",
.type = QEMU_OPT_NUMBER,
#ifdef HAVE_SPICE_GL
},{
.name = "gl",

View file

@ -928,39 +928,44 @@ static QEMUGLContext qemu_spice_gl_create_context(DisplayChangeListener *dcl,
return qemu_egl_create_context(dcl, params);
}
static void qemu_spice_gl_scanout(DisplayChangeListener *dcl,
uint32_t tex_id,
bool y_0_top,
uint32_t backing_width,
uint32_t backing_height,
uint32_t x, uint32_t y,
uint32_t w, uint32_t h)
static void qemu_spice_gl_scanout_disable(DisplayChangeListener *dcl)
{
SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
dprint(1, "%s: no framebuffer\n", __func__);
spice_qxl_gl_scanout(&ssd->qxl, -1, 0, 0, 0, 0, false);
qemu_spice_gl_monitor_config(ssd, 0, 0, 0, 0);
ssd->have_surface = false;
ssd->have_scanout = false;
}
static void qemu_spice_gl_scanout_texture(DisplayChangeListener *dcl,
uint32_t tex_id,
bool y_0_top,
uint32_t backing_width,
uint32_t backing_height,
uint32_t x, uint32_t y,
uint32_t w, uint32_t h)
{
SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
EGLint stride = 0, fourcc = 0;
int fd = -1;
if (tex_id) {
fd = egl_get_fd_for_texture(tex_id, &stride, &fourcc);
if (fd < 0) {
fprintf(stderr, "%s: failed to get fd for texture\n", __func__);
return;
}
dprint(1, "%s: %dx%d (stride %d, fourcc 0x%x)\n", __func__,
w, h, stride, fourcc);
} else {
dprint(1, "%s: no texture (no framebuffer)\n", __func__);
assert(tex_id);
fd = egl_get_fd_for_texture(tex_id, &stride, &fourcc);
if (fd < 0) {
fprintf(stderr, "%s: failed to get fd for texture\n", __func__);
return;
}
assert(!tex_id || fd >= 0);
dprint(1, "%s: %dx%d (stride %d, fourcc 0x%x)\n", __func__,
w, h, stride, fourcc);
/* note: spice server will close the fd */
spice_qxl_gl_scanout(&ssd->qxl, fd, backing_width, backing_height,
stride, fourcc, y_0_top);
ssd->have_surface = false;
ssd->have_scanout = (tex_id != 0);
qemu_spice_gl_monitor_config(ssd, x, y, w, h);
ssd->have_surface = false;
ssd->have_scanout = true;
}
static void qemu_spice_gl_update(DisplayChangeListener *dcl,
@ -993,7 +998,8 @@ static const DisplayChangeListenerOps display_listener_gl_ops = {
.dpy_gl_ctx_make_current = qemu_egl_make_context_current,
.dpy_gl_ctx_get_current = qemu_egl_get_current_context,
.dpy_gl_scanout = qemu_spice_gl_scanout,
.dpy_gl_scanout_disable = qemu_spice_gl_scanout_disable,
.dpy_gl_scanout_texture = qemu_spice_gl_scanout_texture,
.dpy_gl_update = qemu_spice_gl_update,
};
@ -1029,9 +1035,26 @@ static void qemu_spice_display_init_one(QemuConsole *con)
void qemu_spice_display_init(void)
{
QemuConsole *con;
QemuOptsList *olist = qemu_find_opts("spice");
QemuOpts *opts = QTAILQ_FIRST(&olist->head);
QemuConsole *spice_con, *con;
const char *str;
int i;
str = qemu_opt_get(opts, "display");
if (str) {
int head = qemu_opt_get_number(opts, "head", 0);
Error *err = NULL;
spice_con = qemu_console_lookup_by_device_name(str, head, &err);
if (err) {
error_report("Failed to lookup display/head");
exit(1);
}
} else {
spice_con = NULL;
}
for (i = 0;; i++) {
con = qemu_console_lookup_by_index(i);
if (!con || !qemu_console_is_graphic(con)) {
@ -1040,6 +1063,9 @@ void qemu_spice_display_init(void)
if (qemu_spice_have_display_interface(con)) {
continue;
}
if (spice_con != NULL && spice_con != con) {
continue;
}
qemu_spice_display_init_one(con);
}
}

View file

@ -3181,6 +3181,7 @@ static void vnc_display_close(VncDisplay *vd)
g_free(vd->lsock);
g_free(vd->lsock_tag);
vd->lsock = NULL;
vd->lsock_tag = NULL;
vd->nlsock = 0;
for (i = 0; i < vd->nlwebsock; i++) {
@ -3192,6 +3193,7 @@ static void vnc_display_close(VncDisplay *vd)
g_free(vd->lwebsock);
g_free(vd->lwebsock_tag);
vd->lwebsock = NULL;
vd->lwebsock_tag = NULL;
vd->nlwebsock = 0;
vd->auth = VNC_AUTH_INVALID;
@ -3204,6 +3206,7 @@ static void vnc_display_close(VncDisplay *vd)
vd->tlsaclname = NULL;
if (vd->lock_key_sync) {
qemu_remove_led_event_handler(vd->led);
vd->led = NULL;
}
}