mirror of https://github.com/xemu-project/xemu.git
vnc: remove vnc_display global
Replace with a vnc_displays list, so we can have multiple vnc server instances. Add vnc_server_find function to lookup a display by id. With no id supplied return the first vnc server, for backward compatibility reasons. It is not possible (yet) to actually create multiple vnc server instances. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Gonglei <arei.gonglei@huawei.com>
This commit is contained in:
parent
699eae17b8
commit
d616ccc5dd
63
ui/vnc.c
63
ui/vnc.c
|
@ -46,7 +46,8 @@ static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
|
||||||
#include "vnc_keysym.h"
|
#include "vnc_keysym.h"
|
||||||
#include "d3des.h"
|
#include "d3des.h"
|
||||||
|
|
||||||
static VncDisplay *vnc_display; /* needed for info vnc */
|
static QTAILQ_HEAD(, VncDisplay) vnc_displays =
|
||||||
|
QTAILQ_HEAD_INITIALIZER(vnc_displays);
|
||||||
|
|
||||||
static int vnc_cursor_define(VncState *vs);
|
static int vnc_cursor_define(VncState *vs);
|
||||||
static void vnc_release_modifiers(VncState *vs);
|
static void vnc_release_modifiers(VncState *vs);
|
||||||
|
@ -226,10 +227,10 @@ static const char *vnc_auth_name(VncDisplay *vd) {
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
static VncServerInfo *vnc_server_info_get(void)
|
static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
|
||||||
{
|
{
|
||||||
VncServerInfo *info;
|
VncServerInfo *info;
|
||||||
VncBasicInfo *bi = vnc_basic_info_get_from_server_addr(vnc_display->lsock);
|
VncBasicInfo *bi = vnc_basic_info_get_from_server_addr(vd->lsock);
|
||||||
if (!bi) {
|
if (!bi) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -237,7 +238,7 @@ static VncServerInfo *vnc_server_info_get(void)
|
||||||
info = g_malloc(sizeof(*info));
|
info = g_malloc(sizeof(*info));
|
||||||
info->base = bi;
|
info->base = bi;
|
||||||
info->has_auth = true;
|
info->has_auth = true;
|
||||||
info->auth = g_strdup(vnc_auth_name(vnc_display));
|
info->auth = g_strdup(vnc_auth_name(vd));
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,7 +283,7 @@ static void vnc_qmp_event(VncState *vs, QAPIEvent event)
|
||||||
}
|
}
|
||||||
g_assert(vs->info->base);
|
g_assert(vs->info->base);
|
||||||
|
|
||||||
si = vnc_server_info_get();
|
si = vnc_server_info_get(vs->vd);
|
||||||
if (!si) {
|
if (!si) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -345,11 +346,27 @@ static VncClientInfo *qmp_query_vnc_client(const VncState *client)
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VncDisplay *vnc_display_find(const char *id)
|
||||||
|
{
|
||||||
|
VncDisplay *vd;
|
||||||
|
|
||||||
|
if (id == NULL) {
|
||||||
|
return QTAILQ_FIRST(&vnc_displays);
|
||||||
|
}
|
||||||
|
QTAILQ_FOREACH(vd, &vnc_displays, next) {
|
||||||
|
if (strcmp(id, vd->id) == 0) {
|
||||||
|
return vd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
VncInfo *qmp_query_vnc(Error **errp)
|
VncInfo *qmp_query_vnc(Error **errp)
|
||||||
{
|
{
|
||||||
VncInfo *info = g_malloc0(sizeof(*info));
|
VncInfo *info = g_malloc0(sizeof(*info));
|
||||||
|
VncDisplay *vd = vnc_display_find(NULL);
|
||||||
|
|
||||||
if (vnc_display == NULL || vnc_display->display == NULL) {
|
if (vd == NULL || vd->display == NULL) {
|
||||||
info->enabled = false;
|
info->enabled = false;
|
||||||
} else {
|
} else {
|
||||||
VncClientInfoList *cur_item = NULL;
|
VncClientInfoList *cur_item = NULL;
|
||||||
|
@ -364,7 +381,7 @@ VncInfo *qmp_query_vnc(Error **errp)
|
||||||
/* for compatibility with the original command */
|
/* for compatibility with the original command */
|
||||||
info->has_clients = true;
|
info->has_clients = true;
|
||||||
|
|
||||||
QTAILQ_FOREACH(client, &vnc_display->clients, next) {
|
QTAILQ_FOREACH(client, &vd->clients, next) {
|
||||||
VncClientInfoList *cinfo = g_malloc0(sizeof(*info));
|
VncClientInfoList *cinfo = g_malloc0(sizeof(*info));
|
||||||
cinfo->value = qmp_query_vnc_client(client);
|
cinfo->value = qmp_query_vnc_client(client);
|
||||||
|
|
||||||
|
@ -377,11 +394,11 @@ VncInfo *qmp_query_vnc(Error **errp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vnc_display->lsock == -1) {
|
if (vd->lsock == -1) {
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getsockname(vnc_display->lsock, (struct sockaddr *)&sa,
|
if (getsockname(vd->lsock, (struct sockaddr *)&sa,
|
||||||
&salen) == -1) {
|
&salen) == -1) {
|
||||||
error_set(errp, QERR_UNDEFINED_ERROR);
|
error_set(errp, QERR_UNDEFINED_ERROR);
|
||||||
goto out_error;
|
goto out_error;
|
||||||
|
@ -405,7 +422,7 @@ VncInfo *qmp_query_vnc(Error **errp)
|
||||||
info->family = inet_netfamily(sa.ss_family);
|
info->family = inet_netfamily(sa.ss_family);
|
||||||
|
|
||||||
info->has_auth = true;
|
info->has_auth = true;
|
||||||
info->auth = g_strdup(vnc_auth_name(vnc_display));
|
info->auth = g_strdup(vnc_auth_name(vd));
|
||||||
}
|
}
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
|
@ -853,7 +870,7 @@ static int vnc_cursor_define(VncState *vs)
|
||||||
static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
|
static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
|
||||||
QEMUCursor *c)
|
QEMUCursor *c)
|
||||||
{
|
{
|
||||||
VncDisplay *vd = vnc_display;
|
VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
|
||||||
VncState *vs;
|
VncState *vs;
|
||||||
|
|
||||||
cursor_put(vd->cursor);
|
cursor_put(vd->cursor);
|
||||||
|
@ -2818,6 +2835,7 @@ static void vnc_connect(VncDisplay *vd, int csock,
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
vs->csock = csock;
|
vs->csock = csock;
|
||||||
|
vs->vd = vd;
|
||||||
|
|
||||||
if (skipauth) {
|
if (skipauth) {
|
||||||
vs->auth = VNC_AUTH_NONE;
|
vs->auth = VNC_AUTH_NONE;
|
||||||
|
@ -2862,8 +2880,6 @@ static void vnc_connect(VncDisplay *vd, int csock,
|
||||||
vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
|
vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
|
||||||
vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
|
vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
|
||||||
|
|
||||||
vs->vd = vd;
|
|
||||||
|
|
||||||
#ifdef CONFIG_VNC_WS
|
#ifdef CONFIG_VNC_WS
|
||||||
if (!vs->websocket)
|
if (!vs->websocket)
|
||||||
#endif
|
#endif
|
||||||
|
@ -2956,7 +2972,7 @@ void vnc_display_init(DisplayState *ds)
|
||||||
{
|
{
|
||||||
VncDisplay *vs = g_malloc0(sizeof(*vs));
|
VncDisplay *vs = g_malloc0(sizeof(*vs));
|
||||||
|
|
||||||
vnc_display = vs;
|
QTAILQ_INSERT_TAIL(&vnc_displays, vs, next);
|
||||||
|
|
||||||
vs->lsock = -1;
|
vs->lsock = -1;
|
||||||
#ifdef CONFIG_VNC_WS
|
#ifdef CONFIG_VNC_WS
|
||||||
|
@ -2986,7 +3002,7 @@ void vnc_display_init(DisplayState *ds)
|
||||||
|
|
||||||
static void vnc_display_close(DisplayState *ds)
|
static void vnc_display_close(DisplayState *ds)
|
||||||
{
|
{
|
||||||
VncDisplay *vs = vnc_display;
|
VncDisplay *vs = vnc_display_find(NULL);
|
||||||
|
|
||||||
if (!vs)
|
if (!vs)
|
||||||
return;
|
return;
|
||||||
|
@ -3015,7 +3031,7 @@ static void vnc_display_close(DisplayState *ds)
|
||||||
|
|
||||||
int vnc_display_password(DisplayState *ds, const char *password)
|
int vnc_display_password(DisplayState *ds, const char *password)
|
||||||
{
|
{
|
||||||
VncDisplay *vs = vnc_display;
|
VncDisplay *vs = vnc_display_find(NULL);
|
||||||
|
|
||||||
if (!vs) {
|
if (!vs) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -3034,7 +3050,7 @@ int vnc_display_password(DisplayState *ds, const char *password)
|
||||||
|
|
||||||
int vnc_display_pw_expire(DisplayState *ds, time_t expires)
|
int vnc_display_pw_expire(DisplayState *ds, time_t expires)
|
||||||
{
|
{
|
||||||
VncDisplay *vs = vnc_display;
|
VncDisplay *vs = vnc_display_find(NULL);
|
||||||
|
|
||||||
if (!vs) {
|
if (!vs) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -3046,14 +3062,14 @@ int vnc_display_pw_expire(DisplayState *ds, time_t expires)
|
||||||
|
|
||||||
char *vnc_display_local_addr(DisplayState *ds)
|
char *vnc_display_local_addr(DisplayState *ds)
|
||||||
{
|
{
|
||||||
VncDisplay *vs = vnc_display;
|
VncDisplay *vs = vnc_display_find(NULL);
|
||||||
|
|
||||||
return vnc_socket_local_addr("%s:%s", vs->lsock);
|
return vnc_socket_local_addr("%s:%s", vs->lsock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vnc_display_open(DisplayState *ds, const char *display, Error **errp)
|
void vnc_display_open(DisplayState *ds, const char *display, Error **errp)
|
||||||
{
|
{
|
||||||
VncDisplay *vs = vnc_display;
|
VncDisplay *vs = vnc_display_find(NULL);
|
||||||
const char *options;
|
const char *options;
|
||||||
int password = 0;
|
int password = 0;
|
||||||
int reverse = 0;
|
int reverse = 0;
|
||||||
|
@ -3069,7 +3085,7 @@ void vnc_display_open(DisplayState *ds, const char *display, Error **errp)
|
||||||
#endif
|
#endif
|
||||||
int lock_key_sync = 1;
|
int lock_key_sync = 1;
|
||||||
|
|
||||||
if (!vnc_display) {
|
if (!vs) {
|
||||||
error_setg(errp, "VNC display not active");
|
error_setg(errp, "VNC display not active");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3368,7 +3384,10 @@ fail:
|
||||||
|
|
||||||
void vnc_display_add_client(DisplayState *ds, int csock, bool skipauth)
|
void vnc_display_add_client(DisplayState *ds, int csock, bool skipauth)
|
||||||
{
|
{
|
||||||
VncDisplay *vs = vnc_display;
|
VncDisplay *vs = vnc_display_find(NULL);
|
||||||
|
|
||||||
|
if (!vs) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
vnc_connect(vs, csock, skipauth, false);
|
vnc_connect(vs, csock, skipauth, false);
|
||||||
}
|
}
|
||||||
|
|
2
ui/vnc.h
2
ui/vnc.h
|
@ -171,6 +171,8 @@ struct VncDisplay
|
||||||
struct VncSurface guest; /* guest visible surface (aka ds->surface) */
|
struct VncSurface guest; /* guest visible surface (aka ds->surface) */
|
||||||
pixman_image_t *server; /* vnc server surface */
|
pixman_image_t *server; /* vnc server surface */
|
||||||
|
|
||||||
|
const char *id;
|
||||||
|
QTAILQ_ENTRY(VncDisplay) next;
|
||||||
char *display;
|
char *display;
|
||||||
char *password;
|
char *password;
|
||||||
time_t expires;
|
time_t expires;
|
||||||
|
|
Loading…
Reference in New Issue