Commit b3a4755a authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/kraxel/tags/pull-vnc-20150122-1' into staging



vnc: add support for multiple vnc displays

# gpg: Signature made Thu 22 Jan 2015 11:00:54 GMT using RSA key ID D3E87138
# 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>"

* remotes/kraxel/tags/pull-vnc-20150122-1:
  monitor: add vnc websockets
  monitor: add query-vnc-servers command
  vnc: factor out qmp_query_client_list
  vnc: track & limit connections
  vnc: update docs/multiseat.txt
  vnc: allow binding servers to qemu consoles
  vnc: switch to QemuOpts, allow multiple servers
  vnc: add display id to acl names
  vnc: remove unused DisplayState parameter, add id instead.
  vnc: remove vnc_display global

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents a805ca54 4478aa76
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@ host side

First you must compile qemu with a user interface supporting
multihead/multiseat and input event routing.  Right now this
list includes sdl2 and gtk (both 2+3):
list includes sdl2, gtk (both 2+3) and vnc:

  ./configure --enable-sdl --with-sdlabi=2.0

@@ -16,16 +16,16 @@ or
  ./configure --enable-gtk


Next put together the qemu command line:
Next put together the qemu command line (sdk/gtk):

qemu	-enable-kvm -usb $memory $disk $whatever \
	-display [ sdl | gtk ] \
	-vga std \
	-device usb-tablet

That is it for the first head, which will use the standard vga, the
That is it for the first seat, which will use the standard vga, the
standard ps/2 keyboard (implicitly there) and the usb-tablet.  Now the
additional switches for the second head:
additional switches for the second seat:

	-device pci-bridge,addr=12.0,chassis_nr=2,id=head.2 \
	-device secondary-vga,bus=head.2,addr=02.0,id=video.2 \
@@ -47,6 +47,16 @@ in a separate tab. You can either simply switch tabs to switch heads,
or use the "View / Detach tab" menu item to move one of the displays
to its own window so you can see both display devices side-by-side.

For vnc some additional configuration on the command line is needed.
We'll create two vnc server instances, and bind the second one to the
second seat, simliar to input devices:

	-display vnc=:1,id=primary \
	-display vnc=:2,id=secondary,display=video.2

Connecting to vnc display :1 gives you access to the first seat, and
likewise connecting to vnc display :2 shows the second seat.

Note on spice: Spice handles multihead just fine.  But it can't do
multiseat.  For tablet events the event source is sent to the spice
agent.  But qemu can't figure it, so it can't do input routing.
+10 −8
Original line number Diff line number Diff line
@@ -331,19 +331,21 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame);
void cocoa_display_init(DisplayState *ds, int full_screen);

/* vnc.c */
void vnc_display_init(DisplayState *ds);
void vnc_display_open(DisplayState *ds, const char *display, Error **errp);
void vnc_display_add_client(DisplayState *ds, int csock, bool skipauth);
char *vnc_display_local_addr(DisplayState *ds);
void vnc_display_init(const char *id);
void vnc_display_open(const char *id, Error **errp);
void vnc_display_add_client(const char *id, int csock, bool skipauth);
char *vnc_display_local_addr(const char *id);
#ifdef CONFIG_VNC
int vnc_display_password(DisplayState *ds, const char *password);
int vnc_display_pw_expire(DisplayState *ds, time_t expires);
int vnc_display_password(const char *id, const char *password);
int vnc_display_pw_expire(const char *id, time_t expires);
QemuOpts *vnc_parse_func(const char *str);
int vnc_init_func(QemuOpts *opts, void *opaque);
#else
static inline int vnc_display_password(DisplayState *ds, const char *password)
static inline int vnc_display_password(const char *id, const char *password)
{
    return -ENODEV;
}
static inline int vnc_display_pw_expire(DisplayState *ds, time_t expires)
static inline int vnc_display_pw_expire(const char *id, time_t expires)
{
    return -ENODEV;
};
+72 −1
Original line number Diff line number Diff line
@@ -672,12 +672,15 @@
#
# @family: address family
#
# @websocket: true in case the socket is a websocket (since 2.3).
#
# Since: 2.1
##
{ 'type': 'VncBasicInfo',
  'data': { 'host': 'str',
            'service': 'str',
            'family': 'NetworkAddressFamily' } }
            'family': 'NetworkAddressFamily',
            'websocket': 'bool' } }

##
# @VncServerInfo
@@ -750,6 +753,63 @@
           '*family': 'NetworkAddressFamily',
           '*service': 'str', '*auth': 'str', '*clients': ['VncClientInfo']} }

##
# @VncPriAuth:
#
# vnc primary authentication method.
#
# Since: 2.3
##
{ 'enum': 'VncPrimaryAuth',
  'data': [ 'none', 'vnc', 'ra2', 'ra2ne', 'tight', 'ultra',
            'tls', 'vencrypt', 'sasl' ] }

##
# @VncVencryptSubAuth:
#
# vnc sub authentication method with vencrypt.
#
# Since: 2.3
##
{ 'enum': 'VncVencryptSubAuth',
  'data': [ 'plain',
            'tls-none',  'x509-none',
            'tls-vnc',   'x509-vnc',
            'tls-plain', 'x509-plain',
            'tls-sasl',  'x509-sasl' ] }

##
# @VncInfo2:
#
# Information about a vnc server
#
# @id: vnc server name.
#
# @server: A list of @VncBasincInfo describing all listening sockets.
#          The list can be empty (in case the vnc server is disabled).
#          It also may have multiple entries: normal + websocket,
#          possibly also ipv4 + ipv6 in the future.
#
# @clients: A list of @VncClientInfo of all currently connected clients.
#           The list can be empty, for obvious reasons.
#
# @auth: The current authentication type used by the server
#
# @vencrypt: #optional The vencrypt sub authentication type used by the server,
#            only specified in case auth == vencrypt.
#
# @display: #optional The display device the vnc server is linked to.
#
# Since: 2.3
##
{ 'type': 'VncInfo2',
  'data': { 'id'        : 'str',
            'server'    : ['VncBasicInfo'],
            'clients'   : ['VncClientInfo'],
            'auth'      : 'VncPrimaryAuth',
            '*vencrypt' : 'VncVencryptSubAuth',
            '*display'  : 'str' } }

##
# @query-vnc:
#
@@ -761,6 +821,17 @@
##
{ 'command': 'query-vnc', 'returns': 'VncInfo' }

##
# @query-vnc-servers:
#
# Returns a list of vnc servers.  The list can be empty.
#
# Returns: a list of @VncInfo2
#
# Since: 2.3
##
{ 'command': 'query-vnc-servers', 'returns': ['VncInfo2'] }

##
# @SpiceBasicInfo
#
+5 −0
Original line number Diff line number Diff line
@@ -2867,6 +2867,11 @@ EQMP
        .args_type  = "",
        .mhandler.cmd_new = qmp_marshal_input_query_vnc,
    },
    {
        .name       = "query-vnc-servers",
        .args_type  = "",
        .mhandler.cmd_new = qmp_marshal_input_query_vnc_servers,
    },

SQMP
query-spice
+14 −1
Original line number Diff line number Diff line
@@ -368,7 +368,20 @@ void qmp_change_vnc_password(const char *password, Error **errp)

static void qmp_change_vnc_listen(const char *target, Error **errp)
{
    vnc_display_open(NULL, target, errp);
    QemuOptsList *olist = qemu_find_opts("vnc");
    QemuOpts *opts;

    if (strstr(target, "id=")) {
        error_setg(errp, "id not supported");
        return;
    }

    opts = qemu_opts_find(olist, "default");
    if (opts) {
        qemu_opts_del(opts);
    }
    opts = vnc_parse_func(target);
    vnc_display_open("default", errp);
}

static void qmp_change_vnc(const char *target, bool has_arg, const char *arg,
Loading