diff options
-rw-r--r-- | audio/alsaaudio.c | 12 | ||||
-rw-r--r-- | audio/audio_template.h | 15 | ||||
-rw-r--r-- | audio/ossaudio.c | 6 | ||||
-rw-r--r-- | hw/audio/adlib.c | 4 | ||||
-rw-r--r-- | hw/display/qxl-render.c | 6 | ||||
-rw-r--r-- | hw/display/qxl.c | 6 | ||||
-rw-r--r-- | include/ui/spice-display.h | 14 | ||||
-rw-r--r-- | qemu-char.c | 8 | ||||
-rw-r--r-- | ui/spice-display.c | 129 | ||||
-rw-r--r-- | util/qemu-sockets.c | 15 |
10 files changed, 174 insertions, 41 deletions
diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index e4e5442..74ead97 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -815,10 +815,8 @@ static void alsa_fini_out (HWVoiceOut *hw) ldebug ("alsa_fini\n"); alsa_anal_close (&alsa->handle, &alsa->pollhlp); - if (alsa->pcm_buf) { - g_free (alsa->pcm_buf); - alsa->pcm_buf = NULL; - } + g_free(alsa->pcm_buf); + alsa->pcm_buf = NULL; } static int alsa_init_out (HWVoiceOut *hw, struct audsettings *as) @@ -978,10 +976,8 @@ static void alsa_fini_in (HWVoiceIn *hw) alsa_anal_close (&alsa->handle, &alsa->pollhlp); - if (alsa->pcm_buf) { - g_free (alsa->pcm_buf); - alsa->pcm_buf = NULL; - } + g_free(alsa->pcm_buf); + alsa->pcm_buf = NULL; } static int alsa_run_in (HWVoiceIn *hw) diff --git a/audio/audio_template.h b/audio/audio_template.h index 16f7880..8173188 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -71,10 +71,7 @@ static void glue (audio_init_nb_voices_, TYPE) (struct audio_driver *drv) static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw) { - if (HWBUF) { - g_free (HWBUF); - } - + g_free (HWBUF); HWBUF = NULL; } @@ -92,9 +89,7 @@ static int glue (audio_pcm_hw_alloc_resources_, TYPE) (HW *hw) static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw) { - if (sw->buf) { - g_free (sw->buf); - } + g_free (sw->buf); if (sw->rate) { st_rate_stop (sw->rate); @@ -172,10 +167,8 @@ static int glue (audio_pcm_sw_init_, TYPE) ( static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw) { glue (audio_pcm_sw_free_resources_, TYPE) (sw); - if (sw->name) { - g_free (sw->name); - sw->name = NULL; - } + g_free (sw->name); + sw->name = NULL; } static void glue (audio_pcm_hw_add_sw_, TYPE) (HW *hw, SW *sw) diff --git a/audio/ossaudio.c b/audio/ossaudio.c index 5a73716..4db2ca6 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -736,10 +736,8 @@ static void oss_fini_in (HWVoiceIn *hw) oss_anal_close (&oss->fd); - if (oss->pcm_buf) { - g_free (oss->pcm_buf); - oss->pcm_buf = NULL; - } + g_free(oss->pcm_buf); + oss->pcm_buf = NULL; } static int oss_run_in (HWVoiceIn *hw) diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c index 5dd739e..656eb37 100644 --- a/hw/audio/adlib.c +++ b/hw/audio/adlib.c @@ -275,9 +275,7 @@ static void Adlib_fini (AdlibState *s) } #endif - if (s->mixbuf) { - g_free (s->mixbuf); - } + g_free(s->mixbuf); s->active = 0; s->enabled = 0; diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c index 84f1367..cc2c2b1 100644 --- a/hw/display/qxl-render.c +++ b/hw/display/qxl-render.c @@ -138,6 +138,12 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl) if (qemu_spice_rect_is_empty(qxl->dirty+i)) { break; } + if (qxl->dirty[i].left > qxl->dirty[i].right || + qxl->dirty[i].top > qxl->dirty[i].bottom || + qxl->dirty[i].right > qxl->guest_primary.surface.width || + qxl->dirty[i].bottom > qxl->guest_primary.surface.height) { + continue; + } qxl_blit(qxl, qxl->dirty+i); dpy_gfx_update(vga->con, qxl->dirty[i].left, qxl->dirty[i].top, diff --git a/hw/display/qxl.c b/hw/display/qxl.c index 7fb83e4..736fd3c 100644 --- a/hw/display/qxl.c +++ b/hw/display/qxl.c @@ -710,7 +710,11 @@ static void interface_release_resource(QXLInstance *sin, if (ext.group_id == MEMSLOT_GROUP_HOST) { /* host group -> vga mode update request */ - qemu_spice_destroy_update(&qxl->ssd, (void *)(intptr_t)ext.info->id); + QXLCommandExt *cmdext = (void *)(ext.info->id); + SimpleSpiceUpdate *update; + g_assert(cmdext->cmd.type == QXL_CMD_DRAW); + update = container_of(cmdext, SimpleSpiceUpdate, ext); + qemu_spice_destroy_update(&qxl->ssd, update); return; } diff --git a/include/ui/spice-display.h b/include/ui/spice-display.h index a46bc80..4252ab8 100644 --- a/include/ui/spice-display.h +++ b/include/ui/spice-display.h @@ -69,6 +69,7 @@ QXLCookie *qxl_cookie_new(int type, uint64_t io); typedef struct SimpleSpiceDisplay SimpleSpiceDisplay; typedef struct SimpleSpiceUpdate SimpleSpiceUpdate; +typedef struct SimpleSpiceCursor SimpleSpiceCursor; struct SimpleSpiceDisplay { DisplaySurface *ds; @@ -92,6 +93,13 @@ struct SimpleSpiceDisplay { */ QemuMutex lock; QTAILQ_HEAD(, SimpleSpiceUpdate) updates; + + /* cursor (without qxl): displaychangelistener -> spice server */ + SimpleSpiceCursor *ptr_define; + SimpleSpiceCursor *ptr_move; + uint16_t ptr_x, ptr_y; + + /* cursor (with qxl): qxl local renderer -> displaychangelistener */ QEMUCursor *cursor; int mouse_x, mouse_y; }; @@ -104,6 +112,12 @@ struct SimpleSpiceUpdate { QTAILQ_ENTRY(SimpleSpiceUpdate) next; }; +struct SimpleSpiceCursor { + QXLCursorCmd cmd; + QXLCommandExt ext; + QXLCursor cursor; +}; + int qemu_spice_rect_is_empty(const QXLRect* r); void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r); diff --git a/qemu-char.c b/qemu-char.c index 4c04bbc..f918f90 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2493,7 +2493,13 @@ static gboolean tcp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque) #ifndef _WIN32 CharDriverState *qemu_chr_open_eventfd(int eventfd) { - return qemu_chr_open_fd(eventfd, eventfd); + CharDriverState *chr = qemu_chr_open_fd(eventfd, eventfd); + + if (chr) { + chr->avail_connections = 1; + } + + return chr; } #endif diff --git a/ui/spice-display.c b/ui/spice-display.c index ce6b220..03040b1 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c @@ -153,7 +153,7 @@ static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd, drawable->bbox = *rect; drawable->clip.type = SPICE_CLIP_TYPE_NONE; drawable->effect = QXL_EFFECT_OPAQUE; - drawable->release_info.id = (uintptr_t)update; + drawable->release_info.id = (uintptr_t)(&update->ext); drawable->type = QXL_DRAW_COPY; drawable->surfaces_dest[0] = -1; drawable->surfaces_dest[1] = -1; @@ -264,6 +264,49 @@ static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) memset(&ssd->dirty, 0, sizeof(ssd->dirty)); } +static SimpleSpiceCursor* +qemu_spice_create_cursor_update(SimpleSpiceDisplay *ssd, + QEMUCursor *c) +{ + size_t size = c ? c->width * c->height * 4 : 0; + SimpleSpiceCursor *update; + QXLCursorCmd *ccmd; + QXLCursor *cursor; + QXLCommand *cmd; + + update = g_malloc0(sizeof(*update) + size); + ccmd = &update->cmd; + cursor = &update->cursor; + cmd = &update->ext.cmd; + + if (c) { + ccmd->type = QXL_CURSOR_SET; + ccmd->u.set.position.x = ssd->ptr_x; + ccmd->u.set.position.y = ssd->ptr_y; + ccmd->u.set.visible = true; + ccmd->u.set.shape = (uintptr_t)cursor; + cursor->header.unique = ssd->unique++; + cursor->header.type = SPICE_CURSOR_TYPE_ALPHA; + cursor->header.width = c->width; + cursor->header.height = c->height; + cursor->header.hot_spot_x = c->hot_x; + cursor->header.hot_spot_y = c->hot_y; + cursor->data_size = size; + cursor->chunk.data_size = size; + memcpy(cursor->chunk.data, c->data, size); + } else { + ccmd->type = QXL_CURSOR_MOVE; + ccmd->u.position.x = ssd->ptr_x; + ccmd->u.position.y = ssd->ptr_y; + } + ccmd->release_info.id = (uintptr_t)(&update->ext); + + cmd->type = QXL_CMD_CURSOR; + cmd->data = (uintptr_t)ccmd; + + return update; +} + /* * Called from spice server thread context (via interface_release_resource) * We do *not* hold the global qemu mutex here, so extra care is needed @@ -483,20 +526,50 @@ static int interface_req_cmd_notification(QXLInstance *sin) } static void interface_release_resource(QXLInstance *sin, - struct QXLReleaseInfoExt ext) + struct QXLReleaseInfoExt rext) { SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl); - uintptr_t id; + SimpleSpiceUpdate *update; + SimpleSpiceCursor *cursor; + QXLCommandExt *ext; dprint(2, "%s/%d:\n", __func__, ssd->qxl.id); - id = ext.info->id; - qemu_spice_destroy_update(ssd, (void*)id); + ext = (void *)(rext.info->id); + switch (ext->cmd.type) { + case QXL_CMD_DRAW: + update = container_of(ext, SimpleSpiceUpdate, ext); + qemu_spice_destroy_update(ssd, update); + break; + case QXL_CMD_CURSOR: + cursor = container_of(ext, SimpleSpiceCursor, ext); + g_free(cursor); + break; + default: + g_assert_not_reached(); + } } static int interface_get_cursor_command(QXLInstance *sin, struct QXLCommandExt *ext) { - dprint(3, "%s:\n", __FUNCTION__); - return false; + SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl); + int ret; + + dprint(3, "%s/%d:\n", __func__, ssd->qxl.id); + + qemu_mutex_lock(&ssd->lock); + if (ssd->ptr_define) { + *ext = ssd->ptr_define->ext; + ssd->ptr_define = NULL; + ret = true; + } else if (ssd->ptr_move) { + *ext = ssd->ptr_move->ext; + ssd->ptr_move = NULL; + ret = true; + } else { + ret = false; + } + qemu_mutex_unlock(&ssd->lock); + return ret; } static int interface_req_cursor_notification(QXLInstance *sin) @@ -617,11 +690,45 @@ static void display_refresh(DisplayChangeListener *dcl) qemu_spice_display_refresh(ssd); } +static void display_mouse_set(DisplayChangeListener *dcl, + int x, int y, int on) +{ + SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl); + + qemu_mutex_lock(&ssd->lock); + ssd->ptr_x = x; + ssd->ptr_y = x; + if (ssd->ptr_move) { + g_free(ssd->ptr_move); + } + ssd->ptr_move = qemu_spice_create_cursor_update(ssd, NULL); + qemu_mutex_unlock(&ssd->lock); +} + +static void display_mouse_define(DisplayChangeListener *dcl, + QEMUCursor *c) +{ + SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl); + + qemu_mutex_lock(&ssd->lock); + if (ssd->ptr_move) { + g_free(ssd->ptr_move); + ssd->ptr_move = NULL; + } + if (ssd->ptr_define) { + g_free(ssd->ptr_define); + } + ssd->ptr_define = qemu_spice_create_cursor_update(ssd, c); + qemu_mutex_unlock(&ssd->lock); +} + static const DisplayChangeListenerOps display_listener_ops = { - .dpy_name = "spice", - .dpy_gfx_update = display_update, - .dpy_gfx_switch = display_switch, - .dpy_refresh = display_refresh, + .dpy_name = "spice", + .dpy_gfx_update = display_update, + .dpy_gfx_switch = display_switch, + .dpy_refresh = display_refresh, + .dpy_mouse_set = display_mouse_set, + .dpy_cursor_define = display_mouse_define, }; static void qemu_spice_display_init_one(QemuConsole *con) diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index e3d29ee..a4a1e9d 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -131,8 +131,19 @@ int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp) ai.ai_family = PF_INET6; /* lookup */ - if (port_offset) - snprintf(port, sizeof(port), "%d", atoi(port) + port_offset); + if (port_offset) { + unsigned long long baseport; + if (parse_uint_full(port, &baseport, 10) < 0) { + error_setg(errp, "can't convert to a number: %s", port); + return -1; + } + if (baseport > 65535 || + baseport + port_offset > 65535) { + error_setg(errp, "port %s out of range", port); + return -1; + } + snprintf(port, sizeof(port), "%d", (int)baseport + port_offset); + } rc = getaddrinfo(strlen(addr) ? addr : NULL, port, &ai, &res); if (rc != 0) { error_setg(errp, "address resolution failed for %s:%s: %s", addr, port, |