diff --git a/ui/sdl.c b/ui/sdl.c index c8f102bb9f..a6bff301eb 100644 --- a/ui/sdl.c +++ b/ui/sdl.c @@ -242,6 +242,7 @@ static const guint16 *sdl_get_keymap(size_t *maplen) static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev) { + int qcode; if (!keycode_map) { return 0; } @@ -249,7 +250,13 @@ static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev) return 0; } - return keycode_map[ev->keysym.scancode]; + qcode = keycode_map[ev->keysym.scancode]; + + if (qcode > qemu_input_map_qcode_to_qnum_len) { + return 0; + } + + return qemu_input_map_qcode_to_qnum[qcode]; } static void reset_keys(void) diff --git a/ui/vnc-auth-sasl.c b/ui/vnc-auth-sasl.c index 74a5f513f2..fbccca8c8a 100644 --- a/ui/vnc-auth-sasl.c +++ b/ui/vnc-auth-sasl.c @@ -84,7 +84,7 @@ size_t vnc_client_write_sasl(VncState *vs) } else { vs->force_update_offset -= vs->sasl.encodedRawLength; } - vs->output.offset -= vs->sasl.encodedRawLength; + buffer_advance(&vs->output, vs->sasl.encodedRawLength); vs->sasl.encoded = NULL; vs->sasl.encodedOffset = vs->sasl.encodedLength = 0; } diff --git a/ui/vnc.c b/ui/vnc.c index 33b087221f..93731accb6 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -228,12 +228,12 @@ static VncServerInfo *vnc_server_info_get(VncDisplay *vd) VncServerInfo *info; Error *err = NULL; - if (!vd->nlsock) { + if (!vd->listener || !vd->listener->nsioc) { return NULL; } info = g_malloc0(sizeof(*info)); - vnc_init_basic_info_from_server_addr(vd->lsock[0], + vnc_init_basic_info_from_server_addr(vd->listener->sioc[0], qapi_VncServerInfo_base(info), &err); info->has_auth = true; info->auth = g_strdup(vnc_auth_name(vd)); @@ -379,7 +379,7 @@ VncInfo *qmp_query_vnc(Error **errp) VncDisplay *vd = vnc_display_find(NULL); SocketAddress *addr = NULL; - if (vd == NULL || !vd->nlsock) { + if (vd == NULL || !vd->listener || !vd->listener->nsioc) { info->enabled = false; } else { info->enabled = true; @@ -388,11 +388,8 @@ VncInfo *qmp_query_vnc(Error **errp) info->has_clients = true; info->clients = qmp_query_client_list(vd); - if (vd->lsock == NULL) { - return info; - } - - addr = qio_channel_socket_get_local_address(vd->lsock[0], errp); + addr = qio_channel_socket_get_local_address(vd->listener->sioc[0], + errp); if (!addr) { goto out_error; } @@ -572,13 +569,14 @@ VncInfo2List *qmp_query_vnc_servers(Error **errp) info->has_display = true; info->display = g_strdup(dev->id); } - for (i = 0; i < vd->nlsock; i++) { + for (i = 0; vd->listener != NULL && i < vd->listener->nsioc; i++) { info->server = qmp_query_server_entry( - vd->lsock[i], false, vd->auth, vd->subauth, info->server); + vd->listener->sioc[i], false, vd->auth, vd->subauth, + info->server); } - for (i = 0; i < vd->nlwebsock; i++) { + for (i = 0; vd->wslistener != NULL && i < vd->wslistener->nsioc; i++) { info->server = qmp_query_server_entry( - vd->lwebsock[i], true, vd->ws_auth, + vd->wslistener->sioc[i], true, vd->ws_auth, vd->ws_subauth, info->server); } @@ -3143,36 +3141,18 @@ void vnc_start_protocol(VncState *vs) qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier); } -static gboolean vnc_listen_io(QIOChannel *ioc, - GIOCondition condition, - void *opaque) +static void vnc_listen_io(QIONetListener *listener, + QIOChannelSocket *cioc, + void *opaque) { VncDisplay *vd = opaque; - QIOChannelSocket *sioc = NULL; - Error *err = NULL; - bool isWebsock = false; - size_t i; + bool isWebsock = listener == vd->wslistener; - for (i = 0; i < vd->nlwebsock; i++) { - if (ioc == QIO_CHANNEL(vd->lwebsock[i])) { - isWebsock = true; - break; - } - } - - sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc), &err); - if (sioc != NULL) { - qio_channel_set_name(QIO_CHANNEL(sioc), - isWebsock ? "vnc-ws-server" : "vnc-server"); - qio_channel_set_delay(QIO_CHANNEL(sioc), false); - vnc_connect(vd, sioc, false, isWebsock); - object_unref(OBJECT(sioc)); - } else { - /* client probably closed connection before we got there */ - error_free(err); - } - - return TRUE; + qio_channel_set_name(QIO_CHANNEL(cioc), + isWebsock ? "vnc-ws-server" : "vnc-server"); + qio_channel_set_delay(QIO_CHANNEL(cioc), false); + vnc_connect(vd, cioc, false, isWebsock); + object_unref(OBJECT(cioc)); } static const DisplayChangeListenerOps dcl_ops = { @@ -3224,34 +3204,22 @@ void vnc_display_init(const char *id) static void vnc_display_close(VncDisplay *vd) { - size_t i; if (!vd) { return; } vd->is_unix = false; - for (i = 0; i < vd->nlsock; i++) { - if (vd->lsock_tag[i]) { - g_source_remove(vd->lsock_tag[i]); - } - object_unref(OBJECT(vd->lsock[i])); - } - 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++) { - if (vd->lwebsock_tag[i]) { - g_source_remove(vd->lwebsock_tag[i]); - } - object_unref(OBJECT(vd->lwebsock[i])); + if (vd->listener) { + qio_net_listener_disconnect(vd->listener); + object_unref(OBJECT(vd->listener)); } - g_free(vd->lwebsock); - g_free(vd->lwebsock_tag); - vd->lwebsock = NULL; - vd->lwebsock_tag = NULL; - vd->nlwebsock = 0; + vd->listener = NULL; + + if (vd->wslistener) { + qio_net_listener_disconnect(vd->wslistener); + object_unref(OBJECT(vd->wslistener)); + } + vd->wslistener = NULL; vd->auth = VNC_AUTH_INVALID; vd->subauth = VNC_AUTH_INVALID; @@ -3303,11 +3271,11 @@ static void vnc_display_print_local_addr(VncDisplay *vd) SocketAddress *addr; Error *err = NULL; - if (!vd->nlsock) { + if (!vd->listener || !vd->listener->nsioc) { return; } - addr = qio_channel_socket_get_local_address(vd->lsock[0], &err); + addr = qio_channel_socket_get_local_address(vd->listener->sioc[0], &err); if (!addr) { return; } @@ -3815,68 +3783,6 @@ static int vnc_display_connect(VncDisplay *vd, } -static int vnc_display_listen_addr(VncDisplay *vd, - SocketAddress *addr, - const char *name, - QIOChannelSocket ***lsock, - guint **lsock_tag, - size_t *nlsock, - Error **errp) -{ - QIODNSResolver *resolver = qio_dns_resolver_get_instance(); - SocketAddress **rawaddrs = NULL; - size_t nrawaddrs = 0; - Error *listenerr = NULL; - bool listening = false; - size_t i; - - if (qio_dns_resolver_lookup_sync(resolver, addr, &nrawaddrs, - &rawaddrs, errp) < 0) { - return -1; - } - - for (i = 0; i < nrawaddrs; i++) { - QIOChannelSocket *sioc = qio_channel_socket_new(); - - qio_channel_set_name(QIO_CHANNEL(sioc), name); - if (qio_channel_socket_listen_sync( - sioc, rawaddrs[i], listenerr == NULL ? &listenerr : NULL) < 0) { - object_unref(OBJECT(sioc)); - continue; - } - listening = true; - (*nlsock)++; - *lsock = g_renew(QIOChannelSocket *, *lsock, *nlsock); - *lsock_tag = g_renew(guint, *lsock_tag, *nlsock); - - (*lsock)[*nlsock - 1] = sioc; - (*lsock_tag)[*nlsock - 1] = 0; - } - - for (i = 0; i < nrawaddrs; i++) { - qapi_free_SocketAddress(rawaddrs[i]); - } - g_free(rawaddrs); - - if (listenerr) { - if (!listening) { - error_propagate(errp, listenerr); - return -1; - } else { - error_free(listenerr); - } - } - - for (i = 0; i < *nlsock; i++) { - (*lsock_tag)[i] = qio_channel_add_watch( - QIO_CHANNEL((*lsock)[i]), - G_IO_IN, vnc_listen_io, vd, NULL); - } - - return 0; -} - - static int vnc_display_listen(VncDisplay *vd, SocketAddress **saddr, size_t nsaddr, @@ -3886,25 +3792,34 @@ static int vnc_display_listen(VncDisplay *vd, { size_t i; - for (i = 0; i < nsaddr; i++) { - if (vnc_display_listen_addr(vd, saddr[i], - "vnc-listen", - &vd->lsock, - &vd->lsock_tag, - &vd->nlsock, - errp) < 0) { - return -1; + if (nsaddr) { + vd->listener = qio_net_listener_new(); + qio_net_listener_set_name(vd->listener, "vnc-listen"); + for (i = 0; i < nsaddr; i++) { + if (qio_net_listener_open_sync(vd->listener, + saddr[i], + errp) < 0) { + return -1; + } } + + qio_net_listener_set_client_func(vd->listener, + vnc_listen_io, vd, NULL); } - for (i = 0; i < nwsaddr; i++) { - if (vnc_display_listen_addr(vd, wsaddr[i], - "vnc-ws-listen", - &vd->lwebsock, - &vd->lwebsock_tag, - &vd->nlwebsock, - errp) < 0) { - return -1; + + if (nwsaddr) { + vd->wslistener = qio_net_listener_new(); + qio_net_listener_set_name(vd->wslistener, "vnc-ws-listen"); + for (i = 0; i < nwsaddr; i++) { + if (qio_net_listener_open_sync(vd->wslistener, + wsaddr[i], + errp) < 0) { + return -1; + } } + + qio_net_listener_set_client_func(vd->wslistener, + vnc_listen_io, vd, NULL); } return 0; diff --git a/ui/vnc.h b/ui/vnc.h index bbda0540a7..23b4dbbe72 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -37,6 +37,7 @@ #include "qemu/buffer.h" #include "io/channel-socket.h" #include "io/channel-tls.h" +#include "io/net-listener.h" #include #include "keymaps.h" @@ -146,12 +147,8 @@ struct VncDisplay int num_exclusive; int connections_limit; VncSharePolicy share_policy; - size_t nlsock; - QIOChannelSocket **lsock; - guint *lsock_tag; - size_t nlwebsock; - QIOChannelSocket **lwebsock; - guint *lwebsock_tag; + QIONetListener *listener; + QIONetListener *wslistener; DisplaySurface *ds; DisplayChangeListener dcl; kbd_layout_t *kbd_layout;