From 38a55bddccd4edc393a2e7a30c3f1b79c177b8c4 Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Wed, 18 May 2016 12:40:49 -0400 Subject: ui: egl: Replace fprintf with error_report MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Cole Robinson Reviewed-by: Eric Blake Reviewed-by: Marc-André Lureau Message-id: c880920f6e40a506394d89dbbe1f67c63d359c17.1463588606.git.crobinso@redhat.com Signed-off-by: Gerd Hoffmann --- ui/egl-helpers.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c index 22835c0626..79cee0503a 100644 --- a/ui/egl-helpers.c +++ b/ui/egl-helpers.c @@ -2,6 +2,7 @@ #include #include +#include "qemu/error-report.h" #include "ui/egl-helpers.h" EGLDisplay *qemu_egl_display; @@ -74,13 +75,13 @@ int egl_rendernode_init(void) qemu_egl_rn_fd = qemu_egl_rendernode_open(); if (qemu_egl_rn_fd == -1) { - fprintf(stderr, "egl: no drm render node available\n"); + error_report("egl: no drm render node available"); goto err; } qemu_egl_rn_gbm_dev = gbm_create_device(qemu_egl_rn_fd); if (!qemu_egl_rn_gbm_dev) { - fprintf(stderr, "egl: gbm_create_device failed\n"); + error_report("egl: gbm_create_device failed"); goto err; } @@ -88,18 +89,18 @@ int egl_rendernode_init(void) if (!epoxy_has_egl_extension(qemu_egl_display, "EGL_KHR_surfaceless_context")) { - fprintf(stderr, "egl: EGL_KHR_surfaceless_context not supported\n"); + error_report("egl: EGL_KHR_surfaceless_context not supported"); goto err; } if (!epoxy_has_egl_extension(qemu_egl_display, "EGL_MESA_image_dma_buf_export")) { - fprintf(stderr, "egl: EGL_MESA_image_dma_buf_export not supported\n"); + error_report("egl: EGL_MESA_image_dma_buf_export not supported"); goto err; } qemu_egl_rn_ctx = qemu_egl_init_ctx(); if (!qemu_egl_rn_ctx) { - fprintf(stderr, "egl: egl_init_ctx failed\n"); + error_report("egl: egl_init_ctx failed"); goto err; } @@ -156,13 +157,13 @@ EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win) qemu_egl_config, (EGLNativeWindowType)win, NULL); if (esurface == EGL_NO_SURFACE) { - fprintf(stderr, "egl: eglCreateWindowSurface failed\n"); + error_report("egl: eglCreateWindowSurface failed"); return NULL; } b = eglMakeCurrent(qemu_egl_display, esurface, esurface, ectx); if (b == EGL_FALSE) { - fprintf(stderr, "egl: eglMakeCurrent failed\n"); + error_report("egl: eglMakeCurrent failed"); return NULL; } @@ -204,21 +205,21 @@ int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug) egl_dbg("eglGetDisplay (dpy %p) ...\n", dpy); qemu_egl_display = eglGetDisplay(dpy); if (qemu_egl_display == EGL_NO_DISPLAY) { - fprintf(stderr, "egl: eglGetDisplay failed\n"); + error_report("egl: eglGetDisplay failed"); return -1; } egl_dbg("eglInitialize ...\n"); b = eglInitialize(qemu_egl_display, &major, &minor); if (b == EGL_FALSE) { - fprintf(stderr, "egl: eglInitialize failed\n"); + error_report("egl: eglInitialize failed"); return -1; } egl_dbg("eglBindAPI ...\n"); b = eglBindAPI(gles ? EGL_OPENGL_ES_API : EGL_OPENGL_API); if (b == EGL_FALSE) { - fprintf(stderr, "egl: eglBindAPI failed\n"); + error_report("egl: eglBindAPI failed"); return -1; } @@ -227,7 +228,7 @@ int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug) gles ? conf_att_gles : conf_att_gl, &qemu_egl_config, 1, &n); if (b == EGL_FALSE || n != 1) { - fprintf(stderr, "egl: eglChooseConfig failed\n"); + error_report("egl: eglChooseConfig failed"); return -1; } @@ -252,13 +253,13 @@ EGLContext qemu_egl_init_ctx(void) ectx = eglCreateContext(qemu_egl_display, qemu_egl_config, EGL_NO_CONTEXT, egl_gles ? ctx_att_gles : ctx_att_gl); if (ectx == EGL_NO_CONTEXT) { - fprintf(stderr, "egl: eglCreateContext failed\n"); + error_report("egl: eglCreateContext failed"); return NULL; } b = eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, ectx); if (b == EGL_FALSE) { - fprintf(stderr, "egl: eglMakeCurrent failed\n"); + error_report("egl: eglMakeCurrent failed"); return NULL; } -- cgit v1.2.3 From daafc661cc1a1de5a2e8ea0a7c0f396b827ebc3b Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Wed, 18 May 2016 12:40:50 -0400 Subject: ui: spice: Exit if gl=on EGL init fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The user explicitly requested spice GL, so if we know it isn't going to work we should exit Signed-off-by: Cole Robinson Reviewed-by: Marc-André Lureau Message-id: e3789e35b16f9e3cc6f2652f91c52d88ba6d6936.1463588606.git.crobinso@redhat.com Signed-off-by: Gerd Hoffmann --- ui/spice-core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ui/spice-core.c b/ui/spice-core.c index 61db3c18b3..da0505434a 100644 --- a/ui/spice-core.c +++ b/ui/spice-core.c @@ -833,9 +833,11 @@ void qemu_spice_init(void) "incompatible with -spice port/tls-port"); exit(1); } - if (egl_rendernode_init() == 0) { - display_opengl = 1; + if (egl_rendernode_init() != 0) { + error_report("Failed to initialize EGL render node for SPICE GL"); + exit(1); } + display_opengl = 1; } #endif } -- cgit v1.2.3 From 41cc5239f3fdb992f9dc76e22161179fdb50026c Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 20 May 2016 11:49:08 +0200 Subject: gtk: fix unchecked vc dereference Spotted by Coverity. Cc: Paolo Bonzini Signed-off-by: Gerd Hoffmann Message-id: 1463737748-1062-1-git-send-email-kraxel@redhat.com --- ui/gtk.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/gtk.c b/ui/gtk.c index 7572cec8c5..01b821616e 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -1477,13 +1477,14 @@ static void gd_grab_pointer(VirtualConsole *vc, const char *reason) static void gd_ungrab_pointer(GtkDisplayState *s) { VirtualConsole *vc = s->ptr_owner; - GdkDisplay *display = gtk_widget_get_display(vc->gfx.drawing_area); + GdkDisplay *display; if (vc == NULL) { return; } s->ptr_owner = NULL; + display = gtk_widget_get_display(vc->gfx.drawing_area); #if GTK_CHECK_VERSION(3, 20, 0) gd_grab_update(vc, vc->s->kbd_owner == vc, false); gdk_device_warp(gd_get_pointer(display), -- cgit v1.2.3 From 435deffefbb07d9a0cafef445e4bfa14cd87b2c0 Mon Sep 17 00:00:00 2001 From: Pavel Dovgalyuk Date: Tue, 17 May 2016 10:28:48 +0300 Subject: SDL2: add bgrx pixel format This patch adds support of b8g8r8x8 pixel format for SDL2. Signed-off-by: Pavel Dovgalyuk Message-id: 20160517072848.4540.34695.stgit@PASHA-ISP Signed-off-by: Gerd Hoffmann --- ui/sdl2-2d.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ui/sdl2-2d.c b/ui/sdl2-2d.c index 95930061ea..8ab68d67b9 100644 --- a/ui/sdl2-2d.c +++ b/ui/sdl2-2d.c @@ -116,6 +116,9 @@ void sdl2_2d_switch(DisplayChangeListener *dcl, case PIXMAN_r8g8b8x8: format = SDL_PIXELFORMAT_RGBA8888; break; + case PIXMAN_b8g8r8x8: + format = SDL_PIXELFORMAT_BGRX8888; + break; default: g_assert_not_reached(); } -- cgit v1.2.3 From 0c426e4534b4945f7377380b7bb4e64b098bb638 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Tue, 24 May 2016 17:19:19 +0300 Subject: vnc: Add support for color map Our current VNC code does not handle color maps (aka non-true-color) at all and aborts if a client requests them. There are 2 major issues with this: 1) A VNC viewer on an 8-bit X11 system may request color maps 2) RealVNC _always_ starts requesting color maps, then moves on to full color In order to support these 2 use cases, let's just create a fake color map that covers exactly our normal true color 8 bit color space. That way we don't lose anything over a client that wants true color. Reported-by: Sascha Wehnert Signed-off-by: Alexander Graf Signed-off-by: Pavel Butsykin Signed-off-by: Denis V. Lunev Message-id: 1464099559-20789-1-git-send-email-den@openvz.org Actually this is a very old patch originally submitted in 2013 by Alexander. The situation is still the same with RealVNC, it does not connect by default to QEMU VNC. The problem is that this client is really popular. This is better to be kludged. Signed-off-by: Pavel Butsykin Signed-off-by: Denis V. Lunev CC: Gerd Hoffmann CC: Paolo Bonzini Signed-off-by: Gerd Hoffmann --- ui/vnc.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index d2ebf1fb71..ddd01fdce6 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -2094,6 +2094,24 @@ static void set_pixel_conversion(VncState *vs) } } +static void send_color_map(VncState *vs) +{ + int i; + + vnc_write_u8(vs, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES); + vnc_write_u8(vs, 0); /* padding */ + vnc_write_u16(vs, 0); /* first color */ + vnc_write_u16(vs, 256); /* # of colors */ + + for (i = 0; i < 256; i++) { + PixelFormat *pf = &vs->client_pf; + + vnc_write_u16(vs, (((i >> pf->rshift) & pf->rmax) << (16 - pf->rbits))); + vnc_write_u16(vs, (((i >> pf->gshift) & pf->gmax) << (16 - pf->gbits))); + vnc_write_u16(vs, (((i >> pf->bshift) & pf->bmax) << (16 - pf->bbits))); + } +} + static void set_pixel_format(VncState *vs, int bits_per_pixel, int depth, int big_endian_flag, int true_color_flag, @@ -2101,8 +2119,15 @@ static void set_pixel_format(VncState *vs, int red_shift, int green_shift, int blue_shift) { if (!true_color_flag) { - vnc_client_error(vs); - return; + /* Expose a reasonable default 256 color map */ + bits_per_pixel = 8; + depth = 8; + red_max = 7; + green_max = 7; + blue_max = 3; + red_shift = 0; + green_shift = 3; + blue_shift = 6; } switch (bits_per_pixel) { @@ -2132,6 +2157,10 @@ static void set_pixel_format(VncState *vs, vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel; vs->client_be = big_endian_flag; + if (!true_color_flag) { + send_color_map(vs); + } + set_pixel_conversion(vs); graphic_hw_invalidate(vs->vd->dcl.con); -- cgit v1.2.3 From 8efa5f29f83816ae34f428143de49acbaacccb24 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 1 Jun 2016 16:08:36 +0200 Subject: sdl2: skip init without outputs Signed-off-by: Gerd Hoffmann Tested-by: Cole Robinson Message-id: 1464790116-32405-1-git-send-email-kraxel@redhat.com --- ui/sdl2.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ui/sdl2.c b/ui/sdl2.c index 909038f81d..30d2a3c35d 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -794,6 +794,9 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame) } } sdl2_num_outputs = i; + if (sdl2_num_outputs == 0) { + return; + } sdl2_console = g_new0(struct sdl2_console, sdl2_num_outputs); for (i = 0; i < sdl2_num_outputs; i++) { QemuConsole *con = qemu_console_lookup_by_index(i); -- cgit v1.2.3 From c5ce83334465ee5acb6789a2f22d125273761c9e Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 1 Jun 2016 08:22:30 +0200 Subject: vnc: add configurable keyboard delay Limits the rate kbd events from the vnc server are forwarded to the guest, so input devices which are typically low-bandwidth can keep up even on bulky input. v2: update documentation too. v3: spell fixes. Signed-off-by: Gerd Hoffmann Tested-by: Yang Hongyang Message-id: 1464762150-25817-1-git-send-email-kraxel@redhat.com --- qemu-options.hx | 8 ++++++++ ui/vnc.c | 13 +++++++++++-- ui/vnc.h | 1 + 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index 6106520c56..9f33361876 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1410,6 +1410,14 @@ everybody else. 'ignore' completely ignores the shared flag and allows everybody connect unconditionally. Doesn't conform to the rfb spec but is traditional QEMU behavior. +@item key-delay-ms + +Set keyboard delay, for key down and key up events, in milliseconds. +Default is 1. Keyboards are low-bandwidth devices, so this slowdown +can help the device and guest to keep up and not lose events in case +events are arriving in bulk. Possible causes for the latter are flaky +network connections, or scripts for automated testing. + @end table ETEXI diff --git a/ui/vnc.c b/ui/vnc.c index ddd01fdce6..c862fdcc9d 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1629,6 +1629,7 @@ static void reset_keys(VncState *vs) for(i = 0; i < 256; i++) { if (vs->modifiers_state[i]) { qemu_input_event_send_key_number(vs->vd->dcl.con, i, false); + qemu_input_event_send_key_delay(vs->vd->key_delay_ms); vs->modifiers_state[i] = 0; } } @@ -1638,9 +1639,9 @@ static void press_key(VncState *vs, int keysym) { int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK; qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true); - qemu_input_event_send_key_delay(0); + qemu_input_event_send_key_delay(vs->vd->key_delay_ms); qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false); - qemu_input_event_send_key_delay(0); + qemu_input_event_send_key_delay(vs->vd->key_delay_ms); } static int current_led_state(VncState *vs) @@ -1792,6 +1793,7 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym) if (qemu_console_is_graphic(NULL)) { qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down); + qemu_input_event_send_key_delay(vs->vd->key_delay_ms); } else { bool numlock = vs->modifiers_state[0x45]; bool control = (vs->modifiers_state[0x1d] || @@ -1913,6 +1915,7 @@ static void vnc_release_modifiers(VncState *vs) continue; } qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false); + qemu_input_event_send_key_delay(vs->vd->key_delay_ms); } } @@ -3277,6 +3280,9 @@ static QemuOptsList qemu_vnc_opts = { },{ .name = "lock-key-sync", .type = QEMU_OPT_BOOL, + },{ + .name = "key-delay-ms", + .type = QEMU_OPT_NUMBER, },{ .name = "sasl", .type = QEMU_OPT_BOOL, @@ -3515,6 +3521,7 @@ void vnc_display_open(const char *id, Error **errp) #endif int acl = 0; int lock_key_sync = 1; + int key_delay_ms; if (!vs) { error_setg(errp, "VNC display not active"); @@ -3633,6 +3640,7 @@ void vnc_display_open(const char *id, Error **errp) reverse = qemu_opt_get_bool(opts, "reverse", false); lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true); + key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 1); sasl = qemu_opt_get_bool(opts, "sasl", false); #ifndef CONFIG_VNC_SASL if (sasl) { @@ -3764,6 +3772,7 @@ void vnc_display_open(const char *id, Error **errp) } #endif vs->lock_key_sync = lock_key_sync; + vs->key_delay_ms = key_delay_ms; device_id = qemu_opt_get(opts, "display"); if (device_id) { diff --git a/ui/vnc.h b/ui/vnc.h index 81a326116b..6568bca520 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -155,6 +155,7 @@ struct VncDisplay DisplayChangeListener dcl; kbd_layout_t *kbd_layout; int lock_key_sync; + int key_delay_ms; QemuMutex mutex; QEMUCursor *cursor; -- cgit v1.2.3