ui: use QIONetListener in vnc, bugfixes for sdl1 and vnc.
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJadBCQAAoJEEy22O7T6HE4fhoP/1gDeO2yfC2fPXlH5Ph2/jIG +/jW8bBS6LJPCN6H95GajYv9MoLq5shpQTJBgccxzp5dhs2XyFgQr6LTLKVt/oRH Ymbok0xXcOKILkMqSH+hCmA36R/ptaZUtdsV/0eLy9Ra91RBuPZGz80e1iAK4DPp hGinhYhGNHCF4Gd2ElfmWHVnkCExPXjBqGTSQT8gXRrruGSRxr8BtD9gtTqp532J Bzxqe74ZkW/gRZTRotbLy3DnW7HhkwBi5FWnjWB1Yj24SGe/N8ecZpM0h2f9jRET 1WEji1Qm3Twg4O2M9CJbpFm46QQl6aYGuoNYm19Y748xSi2nDnclNiomfgtGQ5Cd hLjDyeANnlyIFbXHf5GhugYIB3Vp+AJm9yCQwWy1MpfeNmmDtPah0GB1mRNOCxUu 8EFJNUDLeLDGfv1ON3XuVwdcUfhNLtL32uMq0eJbbsxa+iMLtqYx7gLjhN7ze3hp dqe0KuArLqNad94I27RWAAHWz6+Hl8aPX9pztkrt5ASRUHdL60VCyJzeSS0VoZ/4 RLpyiJ2eWVKngCvnNXDmTUifQwJsPupcYJ8h8aFWRP187UkCYd5F4mCfQV1Q/Dyp nhXfqwH6NFXgwWjd+JncWoSxwRl0XY2B3mb1kPmNFeDfnG82ZDBp9zmDem4imya5 IG/r5OH6u1ZlYbcsGQG6 =uRH4 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kraxel/tags/ui-20180202-pull-request' into staging ui: use QIONetListener in vnc, bugfixes for sdl1 and vnc. # gpg: Signature made Fri 02 Feb 2018 07:17:36 GMT # gpg: using RSA key 4CB6D8EED3E87138 # 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/ui-20180202-pull-request: ui: correctly advance output buffer when writing SASL data ui: convert VNC server to QIONetListener ui: fix mixup between qnum and qcode in SDL1 key handling Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
f24ee107a0
9
ui/sdl.c
9
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)
|
static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev)
|
||||||
{
|
{
|
||||||
|
int qcode;
|
||||||
if (!keycode_map) {
|
if (!keycode_map) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -249,7 +250,13 @@ static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev)
|
||||||
return 0;
|
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)
|
static void reset_keys(void)
|
||||||
|
|
|
@ -84,7 +84,7 @@ size_t vnc_client_write_sasl(VncState *vs)
|
||||||
} else {
|
} else {
|
||||||
vs->force_update_offset -= vs->sasl.encodedRawLength;
|
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.encoded = NULL;
|
||||||
vs->sasl.encodedOffset = vs->sasl.encodedLength = 0;
|
vs->sasl.encodedOffset = vs->sasl.encodedLength = 0;
|
||||||
}
|
}
|
||||||
|
|
197
ui/vnc.c
197
ui/vnc.c
|
@ -228,12 +228,12 @@ static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
|
||||||
VncServerInfo *info;
|
VncServerInfo *info;
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
if (!vd->nlsock) {
|
if (!vd->listener || !vd->listener->nsioc) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
info = g_malloc0(sizeof(*info));
|
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);
|
qapi_VncServerInfo_base(info), &err);
|
||||||
info->has_auth = true;
|
info->has_auth = true;
|
||||||
info->auth = g_strdup(vnc_auth_name(vd));
|
info->auth = g_strdup(vnc_auth_name(vd));
|
||||||
|
@ -379,7 +379,7 @@ VncInfo *qmp_query_vnc(Error **errp)
|
||||||
VncDisplay *vd = vnc_display_find(NULL);
|
VncDisplay *vd = vnc_display_find(NULL);
|
||||||
SocketAddress *addr = NULL;
|
SocketAddress *addr = NULL;
|
||||||
|
|
||||||
if (vd == NULL || !vd->nlsock) {
|
if (vd == NULL || !vd->listener || !vd->listener->nsioc) {
|
||||||
info->enabled = false;
|
info->enabled = false;
|
||||||
} else {
|
} else {
|
||||||
info->enabled = true;
|
info->enabled = true;
|
||||||
|
@ -388,11 +388,8 @@ VncInfo *qmp_query_vnc(Error **errp)
|
||||||
info->has_clients = true;
|
info->has_clients = true;
|
||||||
info->clients = qmp_query_client_list(vd);
|
info->clients = qmp_query_client_list(vd);
|
||||||
|
|
||||||
if (vd->lsock == NULL) {
|
addr = qio_channel_socket_get_local_address(vd->listener->sioc[0],
|
||||||
return info;
|
errp);
|
||||||
}
|
|
||||||
|
|
||||||
addr = qio_channel_socket_get_local_address(vd->lsock[0], errp);
|
|
||||||
if (!addr) {
|
if (!addr) {
|
||||||
goto out_error;
|
goto out_error;
|
||||||
}
|
}
|
||||||
|
@ -572,13 +569,14 @@ VncInfo2List *qmp_query_vnc_servers(Error **errp)
|
||||||
info->has_display = true;
|
info->has_display = true;
|
||||||
info->display = g_strdup(dev->id);
|
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(
|
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(
|
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);
|
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);
|
qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean vnc_listen_io(QIOChannel *ioc,
|
static void vnc_listen_io(QIONetListener *listener,
|
||||||
GIOCondition condition,
|
QIOChannelSocket *cioc,
|
||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
VncDisplay *vd = opaque;
|
VncDisplay *vd = opaque;
|
||||||
QIOChannelSocket *sioc = NULL;
|
bool isWebsock = listener == vd->wslistener;
|
||||||
Error *err = NULL;
|
|
||||||
bool isWebsock = false;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < vd->nlwebsock; i++) {
|
qio_channel_set_name(QIO_CHANNEL(cioc),
|
||||||
if (ioc == QIO_CHANNEL(vd->lwebsock[i])) {
|
isWebsock ? "vnc-ws-server" : "vnc-server");
|
||||||
isWebsock = true;
|
qio_channel_set_delay(QIO_CHANNEL(cioc), false);
|
||||||
break;
|
vnc_connect(vd, cioc, false, isWebsock);
|
||||||
}
|
object_unref(OBJECT(cioc));
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const DisplayChangeListenerOps dcl_ops = {
|
static const DisplayChangeListenerOps dcl_ops = {
|
||||||
|
@ -3224,34 +3204,22 @@ void vnc_display_init(const char *id)
|
||||||
|
|
||||||
static void vnc_display_close(VncDisplay *vd)
|
static void vnc_display_close(VncDisplay *vd)
|
||||||
{
|
{
|
||||||
size_t i;
|
|
||||||
if (!vd) {
|
if (!vd) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vd->is_unix = false;
|
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->listener) {
|
||||||
if (vd->lwebsock_tag[i]) {
|
qio_net_listener_disconnect(vd->listener);
|
||||||
g_source_remove(vd->lwebsock_tag[i]);
|
object_unref(OBJECT(vd->listener));
|
||||||
}
|
|
||||||
object_unref(OBJECT(vd->lwebsock[i]));
|
|
||||||
}
|
}
|
||||||
g_free(vd->lwebsock);
|
vd->listener = NULL;
|
||||||
g_free(vd->lwebsock_tag);
|
|
||||||
vd->lwebsock = NULL;
|
if (vd->wslistener) {
|
||||||
vd->lwebsock_tag = NULL;
|
qio_net_listener_disconnect(vd->wslistener);
|
||||||
vd->nlwebsock = 0;
|
object_unref(OBJECT(vd->wslistener));
|
||||||
|
}
|
||||||
|
vd->wslistener = NULL;
|
||||||
|
|
||||||
vd->auth = VNC_AUTH_INVALID;
|
vd->auth = VNC_AUTH_INVALID;
|
||||||
vd->subauth = VNC_AUTH_INVALID;
|
vd->subauth = VNC_AUTH_INVALID;
|
||||||
|
@ -3303,11 +3271,11 @@ static void vnc_display_print_local_addr(VncDisplay *vd)
|
||||||
SocketAddress *addr;
|
SocketAddress *addr;
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
if (!vd->nlsock) {
|
if (!vd->listener || !vd->listener->nsioc) {
|
||||||
return;
|
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) {
|
if (!addr) {
|
||||||
return;
|
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,
|
static int vnc_display_listen(VncDisplay *vd,
|
||||||
SocketAddress **saddr,
|
SocketAddress **saddr,
|
||||||
size_t nsaddr,
|
size_t nsaddr,
|
||||||
|
@ -3886,25 +3792,34 @@ static int vnc_display_listen(VncDisplay *vd,
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < nsaddr; i++) {
|
if (nsaddr) {
|
||||||
if (vnc_display_listen_addr(vd, saddr[i],
|
vd->listener = qio_net_listener_new();
|
||||||
"vnc-listen",
|
qio_net_listener_set_name(vd->listener, "vnc-listen");
|
||||||
&vd->lsock,
|
for (i = 0; i < nsaddr; i++) {
|
||||||
&vd->lsock_tag,
|
if (qio_net_listener_open_sync(vd->listener,
|
||||||
&vd->nlsock,
|
saddr[i],
|
||||||
errp) < 0) {
|
errp) < 0) {
|
||||||
return -1;
|
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],
|
if (nwsaddr) {
|
||||||
"vnc-ws-listen",
|
vd->wslistener = qio_net_listener_new();
|
||||||
&vd->lwebsock,
|
qio_net_listener_set_name(vd->wslistener, "vnc-ws-listen");
|
||||||
&vd->lwebsock_tag,
|
for (i = 0; i < nwsaddr; i++) {
|
||||||
&vd->nlwebsock,
|
if (qio_net_listener_open_sync(vd->wslistener,
|
||||||
errp) < 0) {
|
wsaddr[i],
|
||||||
return -1;
|
errp) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qio_net_listener_set_client_func(vd->wslistener,
|
||||||
|
vnc_listen_io, vd, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
9
ui/vnc.h
9
ui/vnc.h
|
@ -37,6 +37,7 @@
|
||||||
#include "qemu/buffer.h"
|
#include "qemu/buffer.h"
|
||||||
#include "io/channel-socket.h"
|
#include "io/channel-socket.h"
|
||||||
#include "io/channel-tls.h"
|
#include "io/channel-tls.h"
|
||||||
|
#include "io/net-listener.h"
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
#include "keymaps.h"
|
#include "keymaps.h"
|
||||||
|
@ -146,12 +147,8 @@ struct VncDisplay
|
||||||
int num_exclusive;
|
int num_exclusive;
|
||||||
int connections_limit;
|
int connections_limit;
|
||||||
VncSharePolicy share_policy;
|
VncSharePolicy share_policy;
|
||||||
size_t nlsock;
|
QIONetListener *listener;
|
||||||
QIOChannelSocket **lsock;
|
QIONetListener *wslistener;
|
||||||
guint *lsock_tag;
|
|
||||||
size_t nlwebsock;
|
|
||||||
QIOChannelSocket **lwebsock;
|
|
||||||
guint *lwebsock_tag;
|
|
||||||
DisplaySurface *ds;
|
DisplaySurface *ds;
|
||||||
DisplayChangeListener dcl;
|
DisplayChangeListener dcl;
|
||||||
kbd_layout_t *kbd_layout;
|
kbd_layout_t *kbd_layout;
|
||||||
|
|
Loading…
Reference in a new issue