diff options
-rw-r--r-- | gdbstub.c | 12 | ||||
-rw-r--r-- | hw/net/e1000e.c | 4 | ||||
-rw-r--r-- | hw/net/e1000e_core.c | 11 | ||||
-rw-r--r-- | qemu-options.hx | 8 | ||||
-rw-r--r-- | target-alpha/translate.c | 3 | ||||
-rw-r--r-- | target-cris/translate.c | 3 | ||||
-rw-r--r-- | target-i386/translate.c | 3 | ||||
-rw-r--r-- | target-lm32/translate.c | 3 | ||||
-rw-r--r-- | target-m68k/translate.c | 3 | ||||
-rw-r--r-- | target-microblaze/translate.c | 3 | ||||
-rw-r--r-- | target-mips/translate.c | 3 | ||||
-rw-r--r-- | target-openrisc/translate.c | 3 | ||||
-rw-r--r-- | target-ppc/translate.c | 3 | ||||
-rw-r--r-- | target-s390x/translate.c | 3 | ||||
-rw-r--r-- | target-sh4/translate.c | 3 | ||||
-rw-r--r-- | target-sparc/translate.c | 3 | ||||
-rw-r--r-- | target-tricore/translate.c | 3 | ||||
-rw-r--r-- | target-unicore32/translate.c | 3 | ||||
-rw-r--r-- | target-xtensa/translate.c | 3 | ||||
-rw-r--r-- | trace-events | 3 | ||||
-rw-r--r-- | ui/egl-helpers.c | 27 | ||||
-rw-r--r-- | ui/gtk.c | 3 | ||||
-rw-r--r-- | ui/sdl2-2d.c | 3 | ||||
-rw-r--r-- | ui/sdl2.c | 3 | ||||
-rw-r--r-- | ui/spice-core.c | 6 | ||||
-rw-r--r-- | ui/vnc.c | 46 | ||||
-rw-r--r-- | ui/vnc.h | 1 |
27 files changed, 127 insertions, 45 deletions
@@ -333,7 +333,7 @@ static int get_char(GDBState *s) if (ret < 0) { if (errno == ECONNRESET) s->fd = -1; - if (errno != EINTR && errno != EAGAIN) + if (errno != EINTR) return -1; } else if (ret == 0) { close(s->fd); @@ -394,7 +394,7 @@ static void put_buffer(GDBState *s, const uint8_t *buf, int len) while (len > 0) { ret = send(s->fd, buf, len, 0); if (ret < 0) { - if (errno != EINTR && errno != EAGAIN) + if (errno != EINTR) return; } else { buf += ret; @@ -1543,9 +1543,13 @@ gdb_handlesig(CPUState *cpu, int sig) for (i = 0; i < n; i++) { gdb_read_byte(s, buf[i]); } - } else if (n == 0 || errno != EAGAIN) { + } else { /* XXX: Connection closed. Should probably wait for another connection before continuing. */ + if (n == 0) { + close(s->fd); + } + s->fd = -1; return sig; } } @@ -1600,8 +1604,6 @@ static void gdb_accept(void) gdb_has_xml = false; gdbserver_state = s; - - fcntl(fd, F_SETFL, O_NONBLOCK); } static int gdbserver_open(int port) diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c index 61bcbb6083..692283fdd7 100644 --- a/hw/net/e1000e.c +++ b/hw/net/e1000e.c @@ -133,7 +133,7 @@ static uint64_t e1000e_io_read(void *opaque, hwaddr addr, unsigned size) { E1000EState *s = opaque; - uint32_t idx; + uint32_t idx = 0; uint64_t val; switch (addr) { @@ -158,7 +158,7 @@ e1000e_io_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { E1000EState *s = opaque; - uint32_t idx; + uint32_t idx = 0; switch (addr) { case E1000_IOADDR: diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c index 6a44ea1c3f..4549acb120 100644 --- a/hw/net/e1000e_core.c +++ b/hw/net/e1000e_core.c @@ -523,8 +523,15 @@ e1000e_rss_get_hash_type(E1000ECore *core, struct NetRxPkt *pkt) bool ex_dis = core->mac[RFCTL] & E1000_RFCTL_IPV6_EX_DIS; bool new_ex_dis = core->mac[RFCTL] & E1000_RFCTL_NEW_IPV6_EXT_DIS; - trace_e1000e_rx_rss_ip6(core->mac[RFCTL], - ex_dis, new_ex_dis, istcp, + /* + * Following two traces must not be combined because resulting + * event will have 11 arguments totally and some trace backends + * (at least "ust") have limitation of maximum 10 arguments per + * event. Events with more arguments fail to compile for + * backends like these. + */ + trace_e1000e_rx_rss_ip6_rfctl(core->mac[RFCTL]); + trace_e1000e_rx_rss_ip6(ex_dis, new_ex_dis, istcp, ip6info->has_ext_hdrs, ip6info->rss_ex_dst_valid, ip6info->rss_ex_src_valid, 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/target-alpha/translate.c b/target-alpha/translate.c index 76dab154ee..f9b2426636 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -2994,7 +2994,8 @@ void gen_intermediate_code(CPUAlphaState *env, struct TranslationBlock *tb) tb->icount = num_insns; #ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, ctx.pc - pc_start, 1); qemu_log("\n"); diff --git a/target-cris/translate.c b/target-cris/translate.c index 2153ea7af6..cc515690e1 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -3311,7 +3311,8 @@ void gen_intermediate_code(CPUCRISState *env, struct TranslationBlock *tb) #ifdef DEBUG_DISAS #if !DISAS_CRIS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { log_target_disas(cs, pc_start, dc->pc - pc_start, env->pregs[PR_VR]); qemu_log("\nisize=%d osize=%d\n", diff --git a/target-i386/translate.c b/target-i386/translate.c index bf33e6b353..f010022fcd 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -8354,7 +8354,8 @@ done_generating: gen_tb_end(tb, num_insns); #ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { int disas_flags; qemu_log("----------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); diff --git a/target-lm32/translate.c b/target-lm32/translate.c index d09d81447b..526b4374e6 100644 --- a/target-lm32/translate.c +++ b/target-lm32/translate.c @@ -1147,7 +1147,8 @@ void gen_intermediate_code(CPULM32State *env, struct TranslationBlock *tb) tb->icount = num_insns; #ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("\n"); log_target_disas(cs, pc_start, dc->pc - pc_start, 0); qemu_log("\nisize=%d osize=%d\n", diff --git a/target-m68k/translate.c b/target-m68k/translate.c index f90187ff96..83db42a7d3 100644 --- a/target-m68k/translate.c +++ b/target-m68k/translate.c @@ -3067,7 +3067,8 @@ void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb) gen_tb_end(tb, num_insns); #ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("----------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, dc->pc - pc_start, 0); diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c index 513f390807..c54304aca5 100644 --- a/target-microblaze/translate.c +++ b/target-microblaze/translate.c @@ -1818,7 +1818,8 @@ void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb) #ifdef DEBUG_DISAS #if !SIM_COMPAT - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("\n"); #if DISAS_GNU log_target_disas(cs, pc_start, dc->pc - pc_start, 0); diff --git a/target-mips/translate.c b/target-mips/translate.c index 3bd96aae97..f420680d1f 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -19913,7 +19913,8 @@ done_generating: #ifdef DEBUG_DISAS LOG_DISAS("\n"); - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, ctx.pc - pc_start, 0); qemu_log("\n"); diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c index d4f1f260e4..c08876b14a 100644 --- a/target-openrisc/translate.c +++ b/target-openrisc/translate.c @@ -1751,7 +1751,8 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb) tb->icount = num_insns; #ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("\n"); log_target_disas(cs, pc_start, dc->pc - pc_start, 0); qemu_log("\nisize=%d osize=%d\n", diff --git a/target-ppc/translate.c b/target-ppc/translate.c index fe10bf8774..123e42fe6b 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -11642,7 +11642,8 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb) tb->icount = num_insns; #if defined(DEBUG_DISAS) - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { int flags; flags = env->bfd_mach; flags |= ctx.le_mode << 16; diff --git a/target-s390x/translate.c b/target-s390x/translate.c index 2bbd1020c9..ce5db5dd46 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -5429,7 +5429,8 @@ void gen_intermediate_code(CPUS390XState *env, struct TranslationBlock *tb) tb->icount = num_insns; #if defined(S390X_DEBUG_DISAS) - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, dc.pc - pc_start, 1); qemu_log("\n"); diff --git a/target-sh4/translate.c b/target-sh4/translate.c index ff5222b04e..7518eb5508 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -1924,7 +1924,8 @@ void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb) tb->icount = num_insns; #ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("IN:\n"); /* , lookup_symbol(pc_start)); */ log_target_disas(cs, pc_start, ctx.pc - pc_start, 0); qemu_log("\n"); diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 21760b9fea..afd306fbab 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -5330,7 +5330,8 @@ void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb) tb->icount = num_insns; #ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("--------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, last_pc + 4 - pc_start, 0); diff --git a/target-tricore/translate.c b/target-tricore/translate.c index 83fa4fcd54..eb3deac889 100644 --- a/target-tricore/translate.c +++ b/target-tricore/translate.c @@ -8787,7 +8787,8 @@ void gen_intermediate_code(CPUTriCoreState *env, struct TranslationBlock *tb) } #ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, ctx.pc - pc_start, 0); qemu_log("\n"); diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c index b04d22c9fb..c4d45fa0f4 100644 --- a/target-unicore32/translate.c +++ b/target-unicore32/translate.c @@ -2021,7 +2021,8 @@ done_generating: gen_tb_end(tb, num_insns); #ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("----------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, dc->pc - pc_start, 0); diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index 67efb32ef3..2a8e5c5d94 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -3153,7 +3153,8 @@ void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb) gen_tb_end(tb, insn_count); #ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("----------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, dc.pc - pc_start, 0); diff --git a/trace-events b/trace-events index 68ebac9d84..c50b8705c1 100644 --- a/trace-events +++ b/trace-events @@ -2064,7 +2064,8 @@ e1000e_rx_rss_started(void) "Starting RSS processing" e1000e_rx_rss_disabled(void) "RSS is disabled" e1000e_rx_rss_type(uint32_t type) "RSS type is %u" e1000e_rx_rss_ip4(bool isfragment, bool istcp, uint32_t mrqc, bool tcpipv4_enabled, bool ipv4_enabled) "RSS IPv4: fragment %d, tcp %d, mrqc 0x%X, tcpipv4 enabled %d, ipv4 enabled %d" -e1000e_rx_rss_ip6(uint32_t rfctl, bool ex_dis, bool new_ex_dis, bool istcp, bool has_ext_headers, bool ex_dst_valid, bool ex_src_valid, uint32_t mrqc, bool tcpipv6_enabled, bool ipv6ex_enabled, bool ipv6_enabled) "RSS IPv6: rfctl 0x%X, ex_dis: %d, new_ex_dis: %d, tcp %d, has_ext_headers %d, ex_dst_valid %d, ex_src_valid %d, mrqc 0x%X, tcpipv6 enabled %d, ipv6ex enabled %d, ipv6 enabled %d" +e1000e_rx_rss_ip6_rfctl(uint32_t rfctl) "RSS IPv6: rfctl 0x%X" +e1000e_rx_rss_ip6(bool ex_dis, bool new_ex_dis, bool istcp, bool has_ext_headers, bool ex_dst_valid, bool ex_src_valid, uint32_t mrqc, bool tcpipv6_enabled, bool ipv6ex_enabled, bool ipv6_enabled) "RSS IPv6: ex_dis: %d, new_ex_dis: %d, tcp %d, has_ext_headers %d, ex_dst_valid %d, ex_src_valid %d, mrqc 0x%X, tcpipv6 enabled %d, ipv6ex enabled %d, ipv6 enabled %d" e1000e_rx_rss_dispatched_to_queue(int queue_idx) "Packet being dispatched to queue %d" e1000e_rx_metadata_protocols(bool isip4, bool isip6, bool isudp, bool istcp) "protocols: ip4: %d, ip6: %d, udp: %d, tcp: %d" 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 <glob.h> #include <dirent.h> +#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; } @@ -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), 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(); } @@ -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); 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 } @@ -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); } } @@ -2094,6 +2097,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 +2122,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 +2160,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); @@ -3249,6 +3281,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, },{ @@ -3486,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"); @@ -3604,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) { @@ -3735,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) { @@ -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; |