get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/808804/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 808804,
    "url": "http://patchwork.ozlabs.org/api/patches/808804/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20170901153758.8628-24-armbru@redhat.com/",
    "project": {
        "id": 14,
        "url": "http://patchwork.ozlabs.org/api/projects/14/?format=api",
        "name": "QEMU Development",
        "link_name": "qemu-devel",
        "list_id": "qemu-devel.nongnu.org",
        "list_email": "qemu-devel@nongnu.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20170901153758.8628-24-armbru@redhat.com>",
    "list_archive_url": null,
    "date": "2017-09-01T15:37:34",
    "name": "[PULL,v2,23/47] qapi-schema: Collect UI stuff in qapi/ui.json",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "0ab67fb837a53496b962dd5ccb4feaf5d797afae",
    "submitter": {
        "id": 2645,
        "url": "http://patchwork.ozlabs.org/api/people/2645/?format=api",
        "name": "Markus Armbruster",
        "email": "armbru@redhat.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20170901153758.8628-24-armbru@redhat.com/mbox/",
    "series": [
        {
            "id": 1049,
            "url": "http://patchwork.ozlabs.org/api/series/1049/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=1049",
            "date": "2017-09-01T15:37:14",
            "name": "[PULL,v2,01/47] qapi: Fix error handling code on alternate conflict",
            "version": 2,
            "mbox": "http://patchwork.ozlabs.org/series/1049/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/808804/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/808804/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org",
        "Authentication-Results": [
            "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=nongnu.org\n\t(client-ip=2001:4830:134:3::11; helo=lists.gnu.org;\n\tenvelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n\treceiver=<UNKNOWN>)",
            "ext-mx04.extmail.prod.ext.phx2.redhat.com;\n\tdmarc=none (p=none dis=none) header.from=redhat.com",
            "ext-mx04.extmail.prod.ext.phx2.redhat.com;\n\tspf=fail smtp.mailfrom=armbru@redhat.com"
        ],
        "Received": [
            "from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11])\n\t(using TLSv1 with cipher AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xkPjR58Bnz9t2x\n\tfor <incoming@patchwork.ozlabs.org>;\n\tSat,  2 Sep 2017 02:25:15 +1000 (AEST)",
            "from localhost ([::1]:47698 helo=lists.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.71) (envelope-from\n\t<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>)\n\tid 1dnokr-0002xL-OT\n\tfor incoming@patchwork.ozlabs.org; Fri, 01 Sep 2017 12:25:13 -0400",
            "from eggs.gnu.org ([2001:4830:134:3::10]:51882)\n\tby lists.gnu.org with esmtp (Exim 4.71)\n\t(envelope-from <armbru@redhat.com>) id 1dno1c-0006wV-U2\n\tfor qemu-devel@nongnu.org; Fri, 01 Sep 2017 11:38:33 -0400",
            "from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)\n\t(envelope-from <armbru@redhat.com>) id 1dno1U-0001qc-Dj\n\tfor qemu-devel@nongnu.org; Fri, 01 Sep 2017 11:38:28 -0400",
            "from mx1.redhat.com ([209.132.183.28]:35350)\n\tby eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32)\n\t(Exim 4.71) (envelope-from <armbru@redhat.com>) id 1dno1T-0001pj-UB\n\tfor qemu-devel@nongnu.org; Fri, 01 Sep 2017 11:38:20 -0400",
            "from smtp.corp.redhat.com\n\t(int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby mx1.redhat.com (Postfix) with ESMTPS id DFDDE8B125\n\tfor <qemu-devel@nongnu.org>; Fri,  1 Sep 2017 15:38:18 +0000 (UTC)",
            "from blackfin.pond.sub.org (ovpn-116-75.ams2.redhat.com\n\t[10.36.116.75])\n\tby smtp.corp.redhat.com (Postfix) with ESMTPS id 88A1C7843F;\n\tFri,  1 Sep 2017 15:38:09 +0000 (UTC)",
            "by blackfin.pond.sub.org (Postfix, from userid 1000)\n\tid 8657C11384D6; Fri,  1 Sep 2017 17:37:58 +0200 (CEST)"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.3.2 mx1.redhat.com DFDDE8B125",
        "From": "Markus Armbruster <armbru@redhat.com>",
        "To": "qemu-devel@nongnu.org",
        "Date": "Fri,  1 Sep 2017 17:37:34 +0200",
        "Message-Id": "<20170901153758.8628-24-armbru@redhat.com>",
        "In-Reply-To": "<20170901153758.8628-1-armbru@redhat.com>",
        "References": "<20170901153758.8628-1-armbru@redhat.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=UTF-8",
        "X-Scanned-By": "MIMEDefang 2.79 on 10.5.11.13",
        "X-Greylist": "Sender IP whitelisted, not delayed by milter-greylist-4.5.16\n\t(mx1.redhat.com [10.5.110.28]);\n\tFri, 01 Sep 2017 15:38:19 +0000 (UTC)",
        "Content-Transfer-Encoding": "quoted-printable",
        "X-detected-operating-system": "by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic]\n\t[fuzzy]",
        "X-Received-From": "209.132.183.28",
        "Subject": "[Qemu-devel] [PULL v2 23/47] qapi-schema: Collect UI stuff in\n\tqapi/ui.json",
        "X-BeenThere": "qemu-devel@nongnu.org",
        "X-Mailman-Version": "2.1.21",
        "Precedence": "list",
        "List-Id": "<qemu-devel.nongnu.org>",
        "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n\t<mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.nongnu.org/archive/html/qemu-devel/>",
        "List-Post": "<mailto:qemu-devel@nongnu.org>",
        "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>",
        "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n\t<mailto:qemu-devel-request@nongnu.org?subject=subscribe>",
        "Cc": "Gerd Hoffmann <kraxel@redhat.com>",
        "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org",
        "Sender": "\"Qemu-devel\"\n\t<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>"
    },
    "content": "UI stuff is remote desktop stuff (Spice, VNC) and input stuff (mouse,\nkeyboard).\n\nCc: Gerd Hoffmann <kraxel@redhat.com>\nSigned-off-by: Markus Armbruster <armbru@redhat.com>\nMessage-Id: <1503602048-12268-9-git-send-email-armbru@redhat.com>\nReviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>\nReviewed-by: Gerd Hoffmann <kraxel@redhat.com>\n---\n MAINTAINERS      |   2 +\n Makefile         |   3 +-\n qapi-schema.json | 784 +-------------------------------------------\n qapi/event.json  | 175 ----------\n qapi/ui.json     | 977 +++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 5 files changed, 982 insertions(+), 959 deletions(-)\n create mode 100644 qapi/ui.json",
    "diff": "diff --git a/MAINTAINERS b/MAINTAINERS\nindex aecde6585e..24c5105b12 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -1320,12 +1320,14 @@ F: include/ui/spice-display.h\n F: ui/spice-*.c\n F: audio/spiceaudio.c\n F: hw/display/qxl*\n+F: qapi/ui.json\n \n Graphics\n M: Gerd Hoffmann <kraxel@redhat.com>\n S: Odd Fixes\n F: ui/\n F: include/ui/\n+F: qapi/ui.json\n \n Cocoa graphics\n M: Peter Maydell <peter.maydell@linaro.org>\ndiff --git a/Makefile b/Makefile\nindex 75f3ffedd7..c7b6fd1a1c 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -417,7 +417,8 @@ qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json \\\n                $(SRC_PATH)/qapi/rocker.json \\\n                $(SRC_PATH)/qapi/run-state.json \\\n                $(SRC_PATH)/qapi/sockets.json \\\n-               $(SRC_PATH)/qapi/trace.json\n+               $(SRC_PATH)/qapi/trace.json \\\n+               $(SRC_PATH)/qapi/ui.json\n \n qapi-types.c qapi-types.h :\\\n $(qapi-modules) $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)\ndiff --git a/qapi-schema.json b/qapi-schema.json\nindex e9b61ebf12..6a23f5991c 100644\n--- a/qapi-schema.json\n+++ b/qapi-schema.json\n@@ -86,6 +86,7 @@\n { 'include': 'qapi/char.json' }\n { 'include': 'qapi/net.json' }\n { 'include': 'qapi/rocker.json' }\n+{ 'include': 'qapi/ui.json' }\n { 'include': 'qapi/event.json' }\n { 'include': 'qapi/trace.json' }\n { 'include': 'qapi/introspect.json' }\n@@ -1087,56 +1088,6 @@\n { 'command': 'x-colo-lost-heartbeat' }\n \n ##\n-# @MouseInfo:\n-#\n-# Information about a mouse device.\n-#\n-# @name: the name of the mouse device\n-#\n-# @index: the index of the mouse device\n-#\n-# @current: true if this device is currently receiving mouse events\n-#\n-# @absolute: true if this device supports absolute coordinates as input\n-#\n-# Since: 0.14.0\n-##\n-{ 'struct': 'MouseInfo',\n-  'data': {'name': 'str', 'index': 'int', 'current': 'bool',\n-           'absolute': 'bool'} }\n-\n-##\n-# @query-mice:\n-#\n-# Returns information about each active mouse device\n-#\n-# Returns: a list of @MouseInfo for each device\n-#\n-# Since: 0.14.0\n-#\n-# Example:\n-#\n-# -> { \"execute\": \"query-mice\" }\n-# <- { \"return\": [\n-#          {\n-#             \"name\":\"QEMU Microsoft Mouse\",\n-#             \"index\":0,\n-#             \"current\":false,\n-#             \"absolute\":false\n-#          },\n-#          {\n-#             \"name\":\"QEMU PS/2 Mouse\",\n-#             \"index\":1,\n-#             \"current\":true,\n-#             \"absolute\":true\n-#          }\n-#       ]\n-#    }\n-#\n-##\n-{ 'command': 'query-mice', 'returns': ['MouseInfo'] }\n-\n-##\n # @CpuInfoArch:\n #\n # An enumeration of cpu types that enable additional information during\n@@ -1349,376 +1300,6 @@\n { 'command': 'query-iothreads', 'returns': ['IOThreadInfo'] }\n \n ##\n-# @VncBasicInfo:\n-#\n-# The basic information for vnc network connection\n-#\n-# @host: IP address\n-#\n-# @service: The service name of the vnc port. This may depend on the host\n-#           system's service database so symbolic names should not be relied\n-#           on.\n-#\n-# @family: address family\n-#\n-# @websocket: true in case the socket is a websocket (since 2.3).\n-#\n-# Since: 2.1\n-##\n-{ 'struct': 'VncBasicInfo',\n-  'data': { 'host': 'str',\n-            'service': 'str',\n-            'family': 'NetworkAddressFamily',\n-            'websocket': 'bool' } }\n-\n-##\n-# @VncServerInfo:\n-#\n-# The network connection information for server\n-#\n-# @auth: authentication method used for\n-#        the plain (non-websocket) VNC server\n-#\n-# Since: 2.1\n-##\n-{ 'struct': 'VncServerInfo',\n-  'base': 'VncBasicInfo',\n-  'data': { '*auth': 'str' } }\n-\n-##\n-# @VncClientInfo:\n-#\n-# Information about a connected VNC client.\n-#\n-# @x509_dname: If x509 authentication is in use, the Distinguished\n-#              Name of the client.\n-#\n-# @sasl_username: If SASL authentication is in use, the SASL username\n-#                 used for authentication.\n-#\n-# Since: 0.14.0\n-##\n-{ 'struct': 'VncClientInfo',\n-  'base': 'VncBasicInfo',\n-  'data': { '*x509_dname': 'str', '*sasl_username': 'str' } }\n-\n-##\n-# @VncInfo:\n-#\n-# Information about the VNC session.\n-#\n-# @enabled: true if the VNC server is enabled, false otherwise\n-#\n-# @host: The hostname the VNC server is bound to.  This depends on\n-#        the name resolution on the host and may be an IP address.\n-#\n-# @family: 'ipv6' if the host is listening for IPv6 connections\n-#                    'ipv4' if the host is listening for IPv4 connections\n-#                    'unix' if the host is listening on a unix domain socket\n-#                    'unknown' otherwise\n-#\n-# @service: The service name of the server's port.  This may depends\n-#           on the host system's service database so symbolic names should not\n-#           be relied on.\n-#\n-# @auth: the current authentication type used by the server\n-#        'none' if no authentication is being used\n-#        'vnc' if VNC authentication is being used\n-#        'vencrypt+plain' if VEncrypt is used with plain text authentication\n-#        'vencrypt+tls+none' if VEncrypt is used with TLS and no authentication\n-#        'vencrypt+tls+vnc' if VEncrypt is used with TLS and VNC authentication\n-#        'vencrypt+tls+plain' if VEncrypt is used with TLS and plain text auth\n-#        'vencrypt+x509+none' if VEncrypt is used with x509 and no auth\n-#        'vencrypt+x509+vnc' if VEncrypt is used with x509 and VNC auth\n-#        'vencrypt+x509+plain' if VEncrypt is used with x509 and plain text auth\n-#        'vencrypt+tls+sasl' if VEncrypt is used with TLS and SASL auth\n-#        'vencrypt+x509+sasl' if VEncrypt is used with x509 and SASL auth\n-#\n-# @clients: a list of @VncClientInfo of all currently connected clients\n-#\n-# Since: 0.14.0\n-##\n-{ 'struct': 'VncInfo',\n-  'data': {'enabled': 'bool', '*host': 'str',\n-           '*family': 'NetworkAddressFamily',\n-           '*service': 'str', '*auth': 'str', '*clients': ['VncClientInfo']} }\n-\n-##\n-# @VncPrimaryAuth:\n-#\n-# vnc primary authentication method.\n-#\n-# Since: 2.3\n-##\n-{ 'enum': 'VncPrimaryAuth',\n-  'data': [ 'none', 'vnc', 'ra2', 'ra2ne', 'tight', 'ultra',\n-            'tls', 'vencrypt', 'sasl' ] }\n-\n-##\n-# @VncVencryptSubAuth:\n-#\n-# vnc sub authentication method with vencrypt.\n-#\n-# Since: 2.3\n-##\n-{ 'enum': 'VncVencryptSubAuth',\n-  'data': [ 'plain',\n-            'tls-none',  'x509-none',\n-            'tls-vnc',   'x509-vnc',\n-            'tls-plain', 'x509-plain',\n-            'tls-sasl',  'x509-sasl' ] }\n-\n-\n-##\n-# @VncServerInfo2:\n-#\n-# The network connection information for server\n-#\n-# @auth: The current authentication type used by the servers\n-#\n-# @vencrypt: The vencrypt sub authentication type used by the\n-#            servers, only specified in case auth == vencrypt.\n-#\n-# Since: 2.9\n-##\n-{ 'struct': 'VncServerInfo2',\n-  'base': 'VncBasicInfo',\n-  'data': { 'auth'      : 'VncPrimaryAuth',\n-            '*vencrypt' : 'VncVencryptSubAuth' } }\n-\n-\n-##\n-# @VncInfo2:\n-#\n-# Information about a vnc server\n-#\n-# @id: vnc server name.\n-#\n-# @server: A list of @VncBasincInfo describing all listening sockets.\n-#          The list can be empty (in case the vnc server is disabled).\n-#          It also may have multiple entries: normal + websocket,\n-#          possibly also ipv4 + ipv6 in the future.\n-#\n-# @clients: A list of @VncClientInfo of all currently connected clients.\n-#           The list can be empty, for obvious reasons.\n-#\n-# @auth: The current authentication type used by the non-websockets servers\n-#\n-# @vencrypt: The vencrypt authentication type used by the servers,\n-#            only specified in case auth == vencrypt.\n-#\n-# @display: The display device the vnc server is linked to.\n-#\n-# Since: 2.3\n-##\n-{ 'struct': 'VncInfo2',\n-  'data': { 'id'        : 'str',\n-            'server'    : ['VncServerInfo2'],\n-            'clients'   : ['VncClientInfo'],\n-            'auth'      : 'VncPrimaryAuth',\n-            '*vencrypt' : 'VncVencryptSubAuth',\n-            '*display'  : 'str' } }\n-\n-##\n-# @query-vnc:\n-#\n-# Returns information about the current VNC server\n-#\n-# Returns: @VncInfo\n-#\n-# Since: 0.14.0\n-#\n-# Example:\n-#\n-# -> { \"execute\": \"query-vnc\" }\n-# <- { \"return\": {\n-#          \"enabled\":true,\n-#          \"host\":\"0.0.0.0\",\n-#          \"service\":\"50402\",\n-#          \"auth\":\"vnc\",\n-#          \"family\":\"ipv4\",\n-#          \"clients\":[\n-#             {\n-#                \"host\":\"127.0.0.1\",\n-#                \"service\":\"50401\",\n-#                \"family\":\"ipv4\"\n-#             }\n-#          ]\n-#       }\n-#    }\n-#\n-##\n-{ 'command': 'query-vnc', 'returns': 'VncInfo' }\n-\n-##\n-# @query-vnc-servers:\n-#\n-# Returns a list of vnc servers.  The list can be empty.\n-#\n-# Returns: a list of @VncInfo2\n-#\n-# Since: 2.3\n-##\n-{ 'command': 'query-vnc-servers', 'returns': ['VncInfo2'] }\n-\n-##\n-# @SpiceBasicInfo:\n-#\n-# The basic information for SPICE network connection\n-#\n-# @host: IP address\n-#\n-# @port: port number\n-#\n-# @family: address family\n-#\n-# Since: 2.1\n-##\n-{ 'struct': 'SpiceBasicInfo',\n-  'data': { 'host': 'str',\n-            'port': 'str',\n-            'family': 'NetworkAddressFamily' } }\n-\n-##\n-# @SpiceServerInfo:\n-#\n-# Information about a SPICE server\n-#\n-# @auth: authentication method\n-#\n-# Since: 2.1\n-##\n-{ 'struct': 'SpiceServerInfo',\n-  'base': 'SpiceBasicInfo',\n-  'data': { '*auth': 'str' } }\n-\n-##\n-# @SpiceChannel:\n-#\n-# Information about a SPICE client channel.\n-#\n-# @connection-id: SPICE connection id number.  All channels with the same id\n-#                 belong to the same SPICE session.\n-#\n-# @channel-type: SPICE channel type number.  \"1\" is the main control\n-#                channel, filter for this one if you want to track spice\n-#                sessions only\n-#\n-# @channel-id: SPICE channel ID number.  Usually \"0\", might be different when\n-#              multiple channels of the same type exist, such as multiple\n-#              display channels in a multihead setup\n-#\n-# @tls: true if the channel is encrypted, false otherwise.\n-#\n-# Since: 0.14.0\n-##\n-{ 'struct': 'SpiceChannel',\n-  'base': 'SpiceBasicInfo',\n-  'data': {'connection-id': 'int', 'channel-type': 'int', 'channel-id': 'int',\n-           'tls': 'bool'} }\n-\n-##\n-# @SpiceQueryMouseMode:\n-#\n-# An enumeration of Spice mouse states.\n-#\n-# @client: Mouse cursor position is determined by the client.\n-#\n-# @server: Mouse cursor position is determined by the server.\n-#\n-# @unknown: No information is available about mouse mode used by\n-#           the spice server.\n-#\n-# Note: spice/enums.h has a SpiceMouseMode already, hence the name.\n-#\n-# Since: 1.1\n-##\n-{ 'enum': 'SpiceQueryMouseMode',\n-  'data': [ 'client', 'server', 'unknown' ] }\n-\n-##\n-# @SpiceInfo:\n-#\n-# Information about the SPICE session.\n-#\n-# @enabled: true if the SPICE server is enabled, false otherwise\n-#\n-# @migrated: true if the last guest migration completed and spice\n-#            migration had completed as well. false otherwise. (since 1.4)\n-#\n-# @host: The hostname the SPICE server is bound to.  This depends on\n-#        the name resolution on the host and may be an IP address.\n-#\n-# @port: The SPICE server's port number.\n-#\n-# @compiled-version: SPICE server version.\n-#\n-# @tls-port: The SPICE server's TLS port number.\n-#\n-# @auth: the current authentication type used by the server\n-#        'none'  if no authentication is being used\n-#        'spice' uses SASL or direct TLS authentication, depending on command\n-#                line options\n-#\n-# @mouse-mode: The mode in which the mouse cursor is displayed currently. Can\n-#              be determined by the client or the server, or unknown if spice\n-#              server doesn't provide this information. (since: 1.1)\n-#\n-# @channels: a list of @SpiceChannel for each active spice channel\n-#\n-# Since: 0.14.0\n-##\n-{ 'struct': 'SpiceInfo',\n-  'data': {'enabled': 'bool', 'migrated': 'bool', '*host': 'str', '*port': 'int',\n-           '*tls-port': 'int', '*auth': 'str', '*compiled-version': 'str',\n-           'mouse-mode': 'SpiceQueryMouseMode', '*channels': ['SpiceChannel']} }\n-\n-##\n-# @query-spice:\n-#\n-# Returns information about the current SPICE server\n-#\n-# Returns: @SpiceInfo\n-#\n-# Since: 0.14.0\n-#\n-# Example:\n-#\n-# -> { \"execute\": \"query-spice\" }\n-# <- { \"return\": {\n-#          \"enabled\": true,\n-#          \"auth\": \"spice\",\n-#          \"port\": 5920,\n-#          \"tls-port\": 5921,\n-#          \"host\": \"0.0.0.0\",\n-#          \"channels\": [\n-#             {\n-#                \"port\": \"54924\",\n-#                \"family\": \"ipv4\",\n-#                \"channel-type\": 1,\n-#                \"connection-id\": 1804289383,\n-#                \"host\": \"127.0.0.1\",\n-#                \"channel-id\": 0,\n-#                \"tls\": true\n-#             },\n-#             {\n-#                \"port\": \"36710\",\n-#                \"family\": \"ipv4\",\n-#                \"channel-type\": 4,\n-#                \"connection-id\": 1804289383,\n-#                \"host\": \"127.0.0.1\",\n-#                \"channel-id\": 0,\n-#                \"tls\": false\n-#             },\n-#             [ ... more channels follow ... ]\n-#          ]\n-#       }\n-#    }\n-#\n-##\n-{ 'command': 'query-spice', 'returns': 'SpiceInfo' }\n-\n-##\n # @BalloonInfo:\n #\n # Information about the guest balloon device.\n@@ -2685,83 +2266,6 @@\n   'data': { 'path': 'str', 'property': 'str', 'value': 'any' } }\n \n ##\n-# @set_password:\n-#\n-# Sets the password of a remote display session.\n-#\n-# @protocol: `vnc' to modify the VNC server password\n-#            `spice' to modify the Spice server password\n-#\n-# @password: the new password\n-#\n-# @connected: how to handle existing clients when changing the\n-#                       password.  If nothing is specified, defaults to `keep'\n-#                       `fail' to fail the command if clients are connected\n-#                       `disconnect' to disconnect existing clients\n-#                       `keep' to maintain existing clients\n-#\n-# Returns: Nothing on success\n-#          If Spice is not enabled, DeviceNotFound\n-#\n-# Since: 0.14.0\n-#\n-# Example:\n-#\n-# -> { \"execute\": \"set_password\", \"arguments\": { \"protocol\": \"vnc\",\n-#                                                \"password\": \"secret\" } }\n-# <- { \"return\": {} }\n-#\n-##\n-{ 'command': 'set_password',\n-  'data': {'protocol': 'str', 'password': 'str', '*connected': 'str'} }\n-\n-##\n-# @expire_password:\n-#\n-# Expire the password of a remote display server.\n-#\n-# @protocol: the name of the remote display protocol `vnc' or `spice'\n-#\n-# @time: when to expire the password.\n-#        `now' to expire the password immediately\n-#        `never' to cancel password expiration\n-#        `+INT' where INT is the number of seconds from now (integer)\n-#        `INT' where INT is the absolute time in seconds\n-#\n-# Returns: Nothing on success\n-#          If @protocol is `spice' and Spice is not active, DeviceNotFound\n-#\n-# Since: 0.14.0\n-#\n-# Notes: Time is relative to the server and currently there is no way to\n-#        coordinate server time with client time.  It is not recommended to\n-#        use the absolute time version of the @time parameter unless you're\n-#        sure you are on the same machine as the QEMU instance.\n-#\n-# Example:\n-#\n-# -> { \"execute\": \"expire_password\", \"arguments\": { \"protocol\": \"vnc\",\n-#                                                   \"time\": \"+60\" } }\n-# <- { \"return\": {} }\n-#\n-##\n-{ 'command': 'expire_password', 'data': {'protocol': 'str', 'time': 'str'} }\n-\n-##\n-# @change-vnc-password:\n-#\n-# Change the VNC server password.\n-#\n-# @password:  the new password to use with VNC authentication\n-#\n-# Since: 1.1\n-#\n-# Notes:  An empty password in this command will set the password to the empty\n-#         string.  Existing clients are unaffected by executing this command.\n-##\n-{ 'command': 'change-vnc-password', 'data': {'password': 'str'} }\n-\n-##\n # @change:\n #\n # This command is multiple commands multiplexed together.\n@@ -3839,133 +3343,6 @@\n { 'command': 'query-target', 'returns': 'TargetInfo' }\n \n ##\n-# @QKeyCode:\n-#\n-# An enumeration of key name.\n-#\n-# This is used by the @send-key command.\n-#\n-# @unmapped: since 2.0\n-# @pause: since 2.0\n-# @ro: since 2.4\n-# @kp_comma: since 2.4\n-# @kp_equals: since 2.6\n-# @power: since 2.6\n-# @hiragana: since 2.9\n-# @henkan: since 2.9\n-# @yen: since 2.9\n-#\n-# @sleep: since 2.10\n-# @wake: since 2.10\n-# @audionext: since 2.10\n-# @audioprev: since 2.10\n-# @audiostop: since 2.10\n-# @audioplay: since 2.10\n-# @audiomute: since 2.10\n-# @volumeup: since 2.10\n-# @volumedown: since 2.10\n-# @mediaselect: since 2.10\n-# @mail: since 2.10\n-# @calculator: since 2.10\n-# @computer: since 2.10\n-# @ac_home: since 2.10\n-# @ac_back: since 2.10\n-# @ac_forward: since 2.10\n-# @ac_refresh: since 2.10\n-# @ac_bookmarks: since 2.10\n-# altgr, altgr_r: dropped in 2.10\n-#\n-# Since: 1.3.0\n-#\n-##\n-{ 'enum': 'QKeyCode',\n-  'data': [ 'unmapped',\n-            'shift', 'shift_r', 'alt', 'alt_r', 'ctrl',\n-            'ctrl_r', 'menu', 'esc', '1', '2', '3', '4', '5', '6', '7', '8',\n-            '9', '0', 'minus', 'equal', 'backspace', 'tab', 'q', 'w', 'e',\n-            'r', 't', 'y', 'u', 'i', 'o', 'p', 'bracket_left', 'bracket_right',\n-            'ret', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'semicolon',\n-            'apostrophe', 'grave_accent', 'backslash', 'z', 'x', 'c', 'v', 'b',\n-            'n', 'm', 'comma', 'dot', 'slash', 'asterisk', 'spc', 'caps_lock',\n-            'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10',\n-            'num_lock', 'scroll_lock', 'kp_divide', 'kp_multiply',\n-            'kp_subtract', 'kp_add', 'kp_enter', 'kp_decimal', 'sysrq', 'kp_0',\n-            'kp_1', 'kp_2', 'kp_3', 'kp_4', 'kp_5', 'kp_6', 'kp_7', 'kp_8',\n-            'kp_9', 'less', 'f11', 'f12', 'print', 'home', 'pgup', 'pgdn', 'end',\n-            'left', 'up', 'down', 'right', 'insert', 'delete', 'stop', 'again',\n-            'props', 'undo', 'front', 'copy', 'open', 'paste', 'find', 'cut',\n-            'lf', 'help', 'meta_l', 'meta_r', 'compose', 'pause',\n-            'ro', 'hiragana', 'henkan', 'yen',\n-            'kp_comma', 'kp_equals', 'power', 'sleep', 'wake',\n-            'audionext', 'audioprev', 'audiostop', 'audioplay', 'audiomute',\n-            'volumeup', 'volumedown', 'mediaselect',\n-            'mail', 'calculator', 'computer',\n-            'ac_home', 'ac_back', 'ac_forward', 'ac_refresh', 'ac_bookmarks' ] }\n-\n-##\n-# @KeyValue:\n-#\n-# Represents a keyboard key.\n-#\n-# Since: 1.3.0\n-##\n-{ 'union': 'KeyValue',\n-  'data': {\n-    'number': 'int',\n-    'qcode': 'QKeyCode' } }\n-\n-##\n-# @send-key:\n-#\n-# Send keys to guest.\n-#\n-# @keys: An array of @KeyValue elements. All @KeyValues in this array are\n-#        simultaneously sent to the guest. A @KeyValue.number value is sent\n-#        directly to the guest, while @KeyValue.qcode must be a valid\n-#        @QKeyCode value\n-#\n-# @hold-time: time to delay key up events, milliseconds. Defaults\n-#             to 100\n-#\n-# Returns: Nothing on success\n-#          If key is unknown or redundant, InvalidParameter\n-#\n-# Since: 1.3.0\n-#\n-# Example:\n-#\n-# -> { \"execute\": \"send-key\",\n-#      \"arguments\": { \"keys\": [ { \"type\": \"qcode\", \"data\": \"ctrl\" },\n-#                               { \"type\": \"qcode\", \"data\": \"alt\" },\n-#                               { \"type\": \"qcode\", \"data\": \"delete\" } ] } }\n-# <- { \"return\": {} }\n-#\n-##\n-{ 'command': 'send-key',\n-  'data': { 'keys': ['KeyValue'], '*hold-time': 'int' } }\n-\n-##\n-# @screendump:\n-#\n-# Write a PPM of the VGA screen to a file.\n-#\n-# @filename: the path of a new PPM file to store the image\n-#\n-# Returns: Nothing on success\n-#\n-# Since: 0.14.0\n-#\n-# Example:\n-#\n-# -> { \"execute\": \"screendump\",\n-#      \"arguments\": { \"filename\": \"/tmp/image\" } }\n-# <- { \"return\": {} }\n-#\n-##\n-{ 'command': 'screendump', 'data': {'filename': 'str'} }\n-\n-\n-##\n # @TpmModel:\n #\n # An enumeration of TPM models\n@@ -4289,165 +3666,6 @@\n \n \n ##\n-# @InputButton:\n-#\n-# Button of a pointer input device (mouse, tablet).\n-#\n-# @side: front side button of a 5-button mouse (since 2.9)\n-#\n-# @extra: rear side button of a 5-button mouse (since 2.9)\n-#\n-# Since: 2.0\n-##\n-{ 'enum'  : 'InputButton',\n-  'data'  : [ 'left', 'middle', 'right', 'wheel-up', 'wheel-down', 'side',\n-  'extra' ] }\n-\n-##\n-# @InputAxis:\n-#\n-# Position axis of a pointer input device (mouse, tablet).\n-#\n-# Since: 2.0\n-##\n-{ 'enum'  : 'InputAxis',\n-  'data'  : [ 'x', 'y' ] }\n-\n-##\n-# @InputKeyEvent:\n-#\n-# Keyboard input event.\n-#\n-# @key:    Which key this event is for.\n-# @down:   True for key-down and false for key-up events.\n-#\n-# Since: 2.0\n-##\n-{ 'struct'  : 'InputKeyEvent',\n-  'data'  : { 'key'     : 'KeyValue',\n-              'down'    : 'bool' } }\n-\n-##\n-# @InputBtnEvent:\n-#\n-# Pointer button input event.\n-#\n-# @button: Which button this event is for.\n-# @down:   True for key-down and false for key-up events.\n-#\n-# Since: 2.0\n-##\n-{ 'struct'  : 'InputBtnEvent',\n-  'data'  : { 'button'  : 'InputButton',\n-              'down'    : 'bool' } }\n-\n-##\n-# @InputMoveEvent:\n-#\n-# Pointer motion input event.\n-#\n-# @axis:   Which axis is referenced by @value.\n-# @value:  Pointer position.  For absolute coordinates the\n-#          valid range is 0 -> 0x7ffff\n-#\n-# Since: 2.0\n-##\n-{ 'struct'  : 'InputMoveEvent',\n-  'data'  : { 'axis'    : 'InputAxis',\n-              'value'   : 'int' } }\n-\n-##\n-# @InputEvent:\n-#\n-# Input event union.\n-#\n-# @type: the input type, one of:\n-#  - 'key': Input event of Keyboard\n-#  - 'btn': Input event of pointer buttons\n-#  - 'rel': Input event of relative pointer motion\n-#  - 'abs': Input event of absolute pointer motion\n-#\n-# Since: 2.0\n-##\n-{ 'union' : 'InputEvent',\n-  'data'  : { 'key'     : 'InputKeyEvent',\n-              'btn'     : 'InputBtnEvent',\n-              'rel'     : 'InputMoveEvent',\n-              'abs'     : 'InputMoveEvent' } }\n-\n-##\n-# @input-send-event:\n-#\n-# Send input event(s) to guest.\n-#\n-# @device: display device to send event(s) to.\n-# @head: head to send event(s) to, in case the\n-#        display device supports multiple scanouts.\n-# @events: List of InputEvent union.\n-#\n-# Returns: Nothing on success.\n-#\n-# The @device and @head parameters can be used to send the input event\n-# to specific input devices in case (a) multiple input devices of the\n-# same kind are added to the virtual machine and (b) you have\n-# configured input routing (see docs/multiseat.txt) for those input\n-# devices.  The parameters work exactly like the device and head\n-# properties of input devices.  If @device is missing, only devices\n-# that have no input routing config are admissible.  If @device is\n-# specified, both input devices with and without input routing config\n-# are admissible, but devices with input routing config take\n-# precedence.\n-#\n-# Since: 2.6\n-#\n-# Note: The consoles are visible in the qom tree, under\n-# /backend/console[$index]. They have a device link and head property,\n-# so it is possible to map which console belongs to which device and\n-# display.\n-#\n-# Example:\n-#\n-# 1. Press left mouse button.\n-#\n-# -> { \"execute\": \"input-send-event\",\n-#     \"arguments\": { \"device\": \"video0\",\n-#                    \"events\": [ { \"type\": \"btn\",\n-#                    \"data\" : { \"down\": true, \"button\": \"left\" } } ] } }\n-# <- { \"return\": {} }\n-#\n-# -> { \"execute\": \"input-send-event\",\n-#     \"arguments\": { \"device\": \"video0\",\n-#                    \"events\": [ { \"type\": \"btn\",\n-#                    \"data\" : { \"down\": false, \"button\": \"left\" } } ] } }\n-# <- { \"return\": {} }\n-#\n-# 2. Press ctrl-alt-del.\n-#\n-# -> { \"execute\": \"input-send-event\",\n-#      \"arguments\": { \"events\": [\n-#         { \"type\": \"key\", \"data\" : { \"down\": true,\n-#           \"key\": {\"type\": \"qcode\", \"data\": \"ctrl\" } } },\n-#         { \"type\": \"key\", \"data\" : { \"down\": true,\n-#           \"key\": {\"type\": \"qcode\", \"data\": \"alt\" } } },\n-#         { \"type\": \"key\", \"data\" : { \"down\": true,\n-#           \"key\": {\"type\": \"qcode\", \"data\": \"delete\" } } } ] } }\n-# <- { \"return\": {} }\n-#\n-# 3. Move mouse pointer to absolute coordinates (20000, 400).\n-#\n-# -> { \"execute\": \"input-send-event\" ,\n-#   \"arguments\": { \"events\": [\n-#                { \"type\": \"abs\", \"data\" : { \"axis\": \"x\", \"value\" : 20000 } },\n-#                { \"type\": \"abs\", \"data\" : { \"axis\": \"y\", \"value\" : 400 } } ] } }\n-# <- { \"return\": {} }\n-#\n-##\n-{ 'command': 'input-send-event',\n-  'data': { '*device': 'str',\n-            '*head'  : 'int',\n-            'events' : [ 'InputEvent' ] } }\n-\n-##\n # @NumaOptionsType:\n #\n # @node: NUMA nodes configuration\ndiff --git a/qapi/event.json b/qapi/event.json\nindex 4b327739d7..f49bd3d564 100644\n--- a/qapi/event.json\n+++ b/qapi/event.json\n@@ -51,181 +51,6 @@\n   'data': { '*device': 'str', 'path': 'str' } }\n \n ##\n-# @VNC_CONNECTED:\n-#\n-# Emitted when a VNC client establishes a connection\n-#\n-# @server: server information\n-#\n-# @client: client information\n-#\n-# Note: This event is emitted before any authentication takes place, thus\n-# the authentication ID is not provided\n-#\n-# Since: 0.13.0\n-#\n-# Example:\n-#\n-# <- { \"event\": \"VNC_CONNECTED\",\n-#      \"data\": {\n-#            \"server\": { \"auth\": \"sasl\", \"family\": \"ipv4\",\n-#                        \"service\": \"5901\", \"host\": \"0.0.0.0\" },\n-#            \"client\": { \"family\": \"ipv4\", \"service\": \"58425\",\n-#                        \"host\": \"127.0.0.1\" } },\n-#      \"timestamp\": { \"seconds\": 1262976601, \"microseconds\": 975795 } }\n-#\n-##\n-{ 'event': 'VNC_CONNECTED',\n-  'data': { 'server': 'VncServerInfo',\n-            'client': 'VncBasicInfo' } }\n-\n-##\n-# @VNC_INITIALIZED:\n-#\n-# Emitted after authentication takes place (if any) and the VNC session is\n-# made active\n-#\n-# @server: server information\n-#\n-# @client: client information\n-#\n-# Since: 0.13.0\n-#\n-# Example:\n-#\n-# <-  { \"event\": \"VNC_INITIALIZED\",\n-#       \"data\": {\n-#            \"server\": { \"auth\": \"sasl\", \"family\": \"ipv4\",\n-#                        \"service\": \"5901\", \"host\": \"0.0.0.0\"},\n-#            \"client\": { \"family\": \"ipv4\", \"service\": \"46089\",\n-#                        \"host\": \"127.0.0.1\", \"sasl_username\": \"luiz\" } },\n-#       \"timestamp\": { \"seconds\": 1263475302, \"microseconds\": 150772 } }\n-#\n-##\n-{ 'event': 'VNC_INITIALIZED',\n-  'data': { 'server': 'VncServerInfo',\n-            'client': 'VncClientInfo' } }\n-\n-##\n-# @VNC_DISCONNECTED:\n-#\n-# Emitted when the connection is closed\n-#\n-# @server: server information\n-#\n-# @client: client information\n-#\n-# Since: 0.13.0\n-#\n-# Example:\n-#\n-# <- { \"event\": \"VNC_DISCONNECTED\",\n-#      \"data\": {\n-#            \"server\": { \"auth\": \"sasl\", \"family\": \"ipv4\",\n-#                        \"service\": \"5901\", \"host\": \"0.0.0.0\" },\n-#            \"client\": { \"family\": \"ipv4\", \"service\": \"58425\",\n-#                        \"host\": \"127.0.0.1\", \"sasl_username\": \"luiz\" } },\n-#      \"timestamp\": { \"seconds\": 1262976601, \"microseconds\": 975795 } }\n-#\n-##\n-{ 'event': 'VNC_DISCONNECTED',\n-  'data': { 'server': 'VncServerInfo',\n-            'client': 'VncClientInfo' } }\n-\n-##\n-# @SPICE_CONNECTED:\n-#\n-# Emitted when a SPICE client establishes a connection\n-#\n-# @server: server information\n-#\n-# @client: client information\n-#\n-# Since: 0.14.0\n-#\n-# Example:\n-#\n-# <- { \"timestamp\": {\"seconds\": 1290688046, \"microseconds\": 388707},\n-#      \"event\": \"SPICE_CONNECTED\",\n-#      \"data\": {\n-#        \"server\": { \"port\": \"5920\", \"family\": \"ipv4\", \"host\": \"127.0.0.1\"},\n-#        \"client\": {\"port\": \"52873\", \"family\": \"ipv4\", \"host\": \"127.0.0.1\"}\n-#    }}\n-#\n-##\n-{ 'event': 'SPICE_CONNECTED',\n-  'data': { 'server': 'SpiceBasicInfo',\n-            'client': 'SpiceBasicInfo' } }\n-\n-##\n-# @SPICE_INITIALIZED:\n-#\n-# Emitted after initial handshake and authentication takes place (if any)\n-# and the SPICE channel is up and running\n-#\n-# @server: server information\n-#\n-# @client: client information\n-#\n-# Since: 0.14.0\n-#\n-# Example:\n-#\n-# <- { \"timestamp\": {\"seconds\": 1290688046, \"microseconds\": 417172},\n-#      \"event\": \"SPICE_INITIALIZED\",\n-#      \"data\": {\"server\": {\"auth\": \"spice\", \"port\": \"5921\",\n-#                          \"family\": \"ipv4\", \"host\": \"127.0.0.1\"},\n-#               \"client\": {\"port\": \"49004\", \"family\": \"ipv4\", \"channel-type\": 3,\n-#                          \"connection-id\": 1804289383, \"host\": \"127.0.0.1\",\n-#                          \"channel-id\": 0, \"tls\": true}\n-#    }}\n-#\n-##\n-{ 'event': 'SPICE_INITIALIZED',\n-  'data': { 'server': 'SpiceServerInfo',\n-            'client': 'SpiceChannel' } }\n-\n-##\n-# @SPICE_DISCONNECTED:\n-#\n-# Emitted when the SPICE connection is closed\n-#\n-# @server: server information\n-#\n-# @client: client information\n-#\n-# Since: 0.14.0\n-#\n-# Example:\n-#\n-# <- { \"timestamp\": {\"seconds\": 1290688046, \"microseconds\": 388707},\n-#      \"event\": \"SPICE_DISCONNECTED\",\n-#      \"data\": {\n-#        \"server\": { \"port\": \"5920\", \"family\": \"ipv4\", \"host\": \"127.0.0.1\"},\n-#        \"client\": {\"port\": \"52873\", \"family\": \"ipv4\", \"host\": \"127.0.0.1\"}\n-#    }}\n-#\n-##\n-{ 'event': 'SPICE_DISCONNECTED',\n-  'data': { 'server': 'SpiceBasicInfo',\n-            'client': 'SpiceBasicInfo' } }\n-\n-##\n-# @SPICE_MIGRATE_COMPLETED:\n-#\n-# Emitted when SPICE migration has completed\n-#\n-# Since: 1.3\n-#\n-# Example:\n-#\n-# <- { \"timestamp\": {\"seconds\": 1290688046, \"microseconds\": 417172},\n-#      \"event\": \"SPICE_MIGRATE_COMPLETED\" }\n-#\n-##\n-{ 'event': 'SPICE_MIGRATE_COMPLETED' }\n-\n-##\n # @MIGRATION:\n #\n # Emitted when a migration event happens\ndiff --git a/qapi/ui.json b/qapi/ui.json\nnew file mode 100644\nindex 0000000000..e5d6610b4a\n--- /dev/null\n+++ b/qapi/ui.json\n@@ -0,0 +1,977 @@\n+# -*- Mode: Python -*-\n+#\n+\n+##\n+# = Remote desktop\n+##\n+\n+{ 'include': 'sockets.json' }\n+\n+##\n+# @set_password:\n+#\n+# Sets the password of a remote display session.\n+#\n+# @protocol: `vnc' to modify the VNC server password\n+#            `spice' to modify the Spice server password\n+#\n+# @password: the new password\n+#\n+# @connected: how to handle existing clients when changing the\n+#                       password.  If nothing is specified, defaults to `keep'\n+#                       `fail' to fail the command if clients are connected\n+#                       `disconnect' to disconnect existing clients\n+#                       `keep' to maintain existing clients\n+#\n+# Returns: Nothing on success\n+#          If Spice is not enabled, DeviceNotFound\n+#\n+# Since: 0.14.0\n+#\n+# Example:\n+#\n+# -> { \"execute\": \"set_password\", \"arguments\": { \"protocol\": \"vnc\",\n+#                                                \"password\": \"secret\" } }\n+# <- { \"return\": {} }\n+#\n+##\n+{ 'command': 'set_password',\n+  'data': {'protocol': 'str', 'password': 'str', '*connected': 'str'} }\n+\n+##\n+# @expire_password:\n+#\n+# Expire the password of a remote display server.\n+#\n+# @protocol: the name of the remote display protocol `vnc' or `spice'\n+#\n+# @time: when to expire the password.\n+#        `now' to expire the password immediately\n+#        `never' to cancel password expiration\n+#        `+INT' where INT is the number of seconds from now (integer)\n+#        `INT' where INT is the absolute time in seconds\n+#\n+# Returns: Nothing on success\n+#          If @protocol is `spice' and Spice is not active, DeviceNotFound\n+#\n+# Since: 0.14.0\n+#\n+# Notes: Time is relative to the server and currently there is no way to\n+#        coordinate server time with client time.  It is not recommended to\n+#        use the absolute time version of the @time parameter unless you're\n+#        sure you are on the same machine as the QEMU instance.\n+#\n+# Example:\n+#\n+# -> { \"execute\": \"expire_password\", \"arguments\": { \"protocol\": \"vnc\",\n+#                                                   \"time\": \"+60\" } }\n+# <- { \"return\": {} }\n+#\n+##\n+{ 'command': 'expire_password', 'data': {'protocol': 'str', 'time': 'str'} }\n+\n+##\n+# @screendump:\n+#\n+# Write a PPM of the VGA screen to a file.\n+#\n+# @filename: the path of a new PPM file to store the image\n+#\n+# Returns: Nothing on success\n+#\n+# Since: 0.14.0\n+#\n+# Example:\n+#\n+# -> { \"execute\": \"screendump\",\n+#      \"arguments\": { \"filename\": \"/tmp/image\" } }\n+# <- { \"return\": {} }\n+#\n+##\n+{ 'command': 'screendump', 'data': {'filename': 'str'} }\n+\n+##\n+# == Spice\n+##\n+\n+##\n+# @SpiceBasicInfo:\n+#\n+# The basic information for SPICE network connection\n+#\n+# @host: IP address\n+#\n+# @port: port number\n+#\n+# @family: address family\n+#\n+# Since: 2.1\n+##\n+{ 'struct': 'SpiceBasicInfo',\n+  'data': { 'host': 'str',\n+            'port': 'str',\n+            'family': 'NetworkAddressFamily' } }\n+\n+##\n+# @SpiceServerInfo:\n+#\n+# Information about a SPICE server\n+#\n+# @auth: authentication method\n+#\n+# Since: 2.1\n+##\n+{ 'struct': 'SpiceServerInfo',\n+  'base': 'SpiceBasicInfo',\n+  'data': { '*auth': 'str' } }\n+\n+##\n+# @SpiceChannel:\n+#\n+# Information about a SPICE client channel.\n+#\n+# @connection-id: SPICE connection id number.  All channels with the same id\n+#                 belong to the same SPICE session.\n+#\n+# @channel-type: SPICE channel type number.  \"1\" is the main control\n+#                channel, filter for this one if you want to track spice\n+#                sessions only\n+#\n+# @channel-id: SPICE channel ID number.  Usually \"0\", might be different when\n+#              multiple channels of the same type exist, such as multiple\n+#              display channels in a multihead setup\n+#\n+# @tls: true if the channel is encrypted, false otherwise.\n+#\n+# Since: 0.14.0\n+##\n+{ 'struct': 'SpiceChannel',\n+  'base': 'SpiceBasicInfo',\n+  'data': {'connection-id': 'int', 'channel-type': 'int', 'channel-id': 'int',\n+           'tls': 'bool'} }\n+\n+##\n+# @SpiceQueryMouseMode:\n+#\n+# An enumeration of Spice mouse states.\n+#\n+# @client: Mouse cursor position is determined by the client.\n+#\n+# @server: Mouse cursor position is determined by the server.\n+#\n+# @unknown: No information is available about mouse mode used by\n+#           the spice server.\n+#\n+# Note: spice/enums.h has a SpiceMouseMode already, hence the name.\n+#\n+# Since: 1.1\n+##\n+{ 'enum': 'SpiceQueryMouseMode',\n+  'data': [ 'client', 'server', 'unknown' ] }\n+\n+##\n+# @SpiceInfo:\n+#\n+# Information about the SPICE session.\n+#\n+# @enabled: true if the SPICE server is enabled, false otherwise\n+#\n+# @migrated: true if the last guest migration completed and spice\n+#            migration had completed as well. false otherwise. (since 1.4)\n+#\n+# @host: The hostname the SPICE server is bound to.  This depends on\n+#        the name resolution on the host and may be an IP address.\n+#\n+# @port: The SPICE server's port number.\n+#\n+# @compiled-version: SPICE server version.\n+#\n+# @tls-port: The SPICE server's TLS port number.\n+#\n+# @auth: the current authentication type used by the server\n+#        'none'  if no authentication is being used\n+#        'spice' uses SASL or direct TLS authentication, depending on command\n+#                line options\n+#\n+# @mouse-mode: The mode in which the mouse cursor is displayed currently. Can\n+#              be determined by the client or the server, or unknown if spice\n+#              server doesn't provide this information. (since: 1.1)\n+#\n+# @channels: a list of @SpiceChannel for each active spice channel\n+#\n+# Since: 0.14.0\n+##\n+{ 'struct': 'SpiceInfo',\n+  'data': {'enabled': 'bool', 'migrated': 'bool', '*host': 'str', '*port': 'int',\n+           '*tls-port': 'int', '*auth': 'str', '*compiled-version': 'str',\n+           'mouse-mode': 'SpiceQueryMouseMode', '*channels': ['SpiceChannel']} }\n+\n+##\n+# @query-spice:\n+#\n+# Returns information about the current SPICE server\n+#\n+# Returns: @SpiceInfo\n+#\n+# Since: 0.14.0\n+#\n+# Example:\n+#\n+# -> { \"execute\": \"query-spice\" }\n+# <- { \"return\": {\n+#          \"enabled\": true,\n+#          \"auth\": \"spice\",\n+#          \"port\": 5920,\n+#          \"tls-port\": 5921,\n+#          \"host\": \"0.0.0.0\",\n+#          \"channels\": [\n+#             {\n+#                \"port\": \"54924\",\n+#                \"family\": \"ipv4\",\n+#                \"channel-type\": 1,\n+#                \"connection-id\": 1804289383,\n+#                \"host\": \"127.0.0.1\",\n+#                \"channel-id\": 0,\n+#                \"tls\": true\n+#             },\n+#             {\n+#                \"port\": \"36710\",\n+#                \"family\": \"ipv4\",\n+#                \"channel-type\": 4,\n+#                \"connection-id\": 1804289383,\n+#                \"host\": \"127.0.0.1\",\n+#                \"channel-id\": 0,\n+#                \"tls\": false\n+#             },\n+#             [ ... more channels follow ... ]\n+#          ]\n+#       }\n+#    }\n+#\n+##\n+{ 'command': 'query-spice', 'returns': 'SpiceInfo' }\n+\n+##\n+# @SPICE_CONNECTED:\n+#\n+# Emitted when a SPICE client establishes a connection\n+#\n+# @server: server information\n+#\n+# @client: client information\n+#\n+# Since: 0.14.0\n+#\n+# Example:\n+#\n+# <- { \"timestamp\": {\"seconds\": 1290688046, \"microseconds\": 388707},\n+#      \"event\": \"SPICE_CONNECTED\",\n+#      \"data\": {\n+#        \"server\": { \"port\": \"5920\", \"family\": \"ipv4\", \"host\": \"127.0.0.1\"},\n+#        \"client\": {\"port\": \"52873\", \"family\": \"ipv4\", \"host\": \"127.0.0.1\"}\n+#    }}\n+#\n+##\n+{ 'event': 'SPICE_CONNECTED',\n+  'data': { 'server': 'SpiceBasicInfo',\n+            'client': 'SpiceBasicInfo' } }\n+\n+##\n+# @SPICE_INITIALIZED:\n+#\n+# Emitted after initial handshake and authentication takes place (if any)\n+# and the SPICE channel is up and running\n+#\n+# @server: server information\n+#\n+# @client: client information\n+#\n+# Since: 0.14.0\n+#\n+# Example:\n+#\n+# <- { \"timestamp\": {\"seconds\": 1290688046, \"microseconds\": 417172},\n+#      \"event\": \"SPICE_INITIALIZED\",\n+#      \"data\": {\"server\": {\"auth\": \"spice\", \"port\": \"5921\",\n+#                          \"family\": \"ipv4\", \"host\": \"127.0.0.1\"},\n+#               \"client\": {\"port\": \"49004\", \"family\": \"ipv4\", \"channel-type\": 3,\n+#                          \"connection-id\": 1804289383, \"host\": \"127.0.0.1\",\n+#                          \"channel-id\": 0, \"tls\": true}\n+#    }}\n+#\n+##\n+{ 'event': 'SPICE_INITIALIZED',\n+  'data': { 'server': 'SpiceServerInfo',\n+            'client': 'SpiceChannel' } }\n+\n+##\n+# @SPICE_DISCONNECTED:\n+#\n+# Emitted when the SPICE connection is closed\n+#\n+# @server: server information\n+#\n+# @client: client information\n+#\n+# Since: 0.14.0\n+#\n+# Example:\n+#\n+# <- { \"timestamp\": {\"seconds\": 1290688046, \"microseconds\": 388707},\n+#      \"event\": \"SPICE_DISCONNECTED\",\n+#      \"data\": {\n+#        \"server\": { \"port\": \"5920\", \"family\": \"ipv4\", \"host\": \"127.0.0.1\"},\n+#        \"client\": {\"port\": \"52873\", \"family\": \"ipv4\", \"host\": \"127.0.0.1\"}\n+#    }}\n+#\n+##\n+{ 'event': 'SPICE_DISCONNECTED',\n+  'data': { 'server': 'SpiceBasicInfo',\n+            'client': 'SpiceBasicInfo' } }\n+\n+##\n+# @SPICE_MIGRATE_COMPLETED:\n+#\n+# Emitted when SPICE migration has completed\n+#\n+# Since: 1.3\n+#\n+# Example:\n+#\n+# <- { \"timestamp\": {\"seconds\": 1290688046, \"microseconds\": 417172},\n+#      \"event\": \"SPICE_MIGRATE_COMPLETED\" }\n+#\n+##\n+{ 'event': 'SPICE_MIGRATE_COMPLETED' }\n+\n+##\n+# == VNC\n+##\n+\n+##\n+# @VncBasicInfo:\n+#\n+# The basic information for vnc network connection\n+#\n+# @host: IP address\n+#\n+# @service: The service name of the vnc port. This may depend on the host\n+#           system's service database so symbolic names should not be relied\n+#           on.\n+#\n+# @family: address family\n+#\n+# @websocket: true in case the socket is a websocket (since 2.3).\n+#\n+# Since: 2.1\n+##\n+{ 'struct': 'VncBasicInfo',\n+  'data': { 'host': 'str',\n+            'service': 'str',\n+            'family': 'NetworkAddressFamily',\n+            'websocket': 'bool' } }\n+\n+##\n+# @VncServerInfo:\n+#\n+# The network connection information for server\n+#\n+# @auth: authentication method used for\n+#        the plain (non-websocket) VNC server\n+#\n+# Since: 2.1\n+##\n+{ 'struct': 'VncServerInfo',\n+  'base': 'VncBasicInfo',\n+  'data': { '*auth': 'str' } }\n+\n+##\n+# @VncClientInfo:\n+#\n+# Information about a connected VNC client.\n+#\n+# @x509_dname: If x509 authentication is in use, the Distinguished\n+#              Name of the client.\n+#\n+# @sasl_username: If SASL authentication is in use, the SASL username\n+#                 used for authentication.\n+#\n+# Since: 0.14.0\n+##\n+{ 'struct': 'VncClientInfo',\n+  'base': 'VncBasicInfo',\n+  'data': { '*x509_dname': 'str', '*sasl_username': 'str' } }\n+\n+##\n+# @VncInfo:\n+#\n+# Information about the VNC session.\n+#\n+# @enabled: true if the VNC server is enabled, false otherwise\n+#\n+# @host: The hostname the VNC server is bound to.  This depends on\n+#        the name resolution on the host and may be an IP address.\n+#\n+# @family: 'ipv6' if the host is listening for IPv6 connections\n+#                    'ipv4' if the host is listening for IPv4 connections\n+#                    'unix' if the host is listening on a unix domain socket\n+#                    'unknown' otherwise\n+#\n+# @service: The service name of the server's port.  This may depends\n+#           on the host system's service database so symbolic names should not\n+#           be relied on.\n+#\n+# @auth: the current authentication type used by the server\n+#        'none' if no authentication is being used\n+#        'vnc' if VNC authentication is being used\n+#        'vencrypt+plain' if VEncrypt is used with plain text authentication\n+#        'vencrypt+tls+none' if VEncrypt is used with TLS and no authentication\n+#        'vencrypt+tls+vnc' if VEncrypt is used with TLS and VNC authentication\n+#        'vencrypt+tls+plain' if VEncrypt is used with TLS and plain text auth\n+#        'vencrypt+x509+none' if VEncrypt is used with x509 and no auth\n+#        'vencrypt+x509+vnc' if VEncrypt is used with x509 and VNC auth\n+#        'vencrypt+x509+plain' if VEncrypt is used with x509 and plain text auth\n+#        'vencrypt+tls+sasl' if VEncrypt is used with TLS and SASL auth\n+#        'vencrypt+x509+sasl' if VEncrypt is used with x509 and SASL auth\n+#\n+# @clients: a list of @VncClientInfo of all currently connected clients\n+#\n+# Since: 0.14.0\n+##\n+{ 'struct': 'VncInfo',\n+  'data': {'enabled': 'bool', '*host': 'str',\n+           '*family': 'NetworkAddressFamily',\n+           '*service': 'str', '*auth': 'str', '*clients': ['VncClientInfo']} }\n+\n+##\n+# @VncPrimaryAuth:\n+#\n+# vnc primary authentication method.\n+#\n+# Since: 2.3\n+##\n+{ 'enum': 'VncPrimaryAuth',\n+  'data': [ 'none', 'vnc', 'ra2', 'ra2ne', 'tight', 'ultra',\n+            'tls', 'vencrypt', 'sasl' ] }\n+\n+##\n+# @VncVencryptSubAuth:\n+#\n+# vnc sub authentication method with vencrypt.\n+#\n+# Since: 2.3\n+##\n+{ 'enum': 'VncVencryptSubAuth',\n+  'data': [ 'plain',\n+            'tls-none',  'x509-none',\n+            'tls-vnc',   'x509-vnc',\n+            'tls-plain', 'x509-plain',\n+            'tls-sasl',  'x509-sasl' ] }\n+\n+\n+##\n+# @VncServerInfo2:\n+#\n+# The network connection information for server\n+#\n+# @auth: The current authentication type used by the servers\n+#\n+# @vencrypt: The vencrypt sub authentication type used by the\n+#            servers, only specified in case auth == vencrypt.\n+#\n+# Since: 2.9\n+##\n+{ 'struct': 'VncServerInfo2',\n+  'base': 'VncBasicInfo',\n+  'data': { 'auth'      : 'VncPrimaryAuth',\n+            '*vencrypt' : 'VncVencryptSubAuth' } }\n+\n+\n+##\n+# @VncInfo2:\n+#\n+# Information about a vnc server\n+#\n+# @id: vnc server name.\n+#\n+# @server: A list of @VncBasincInfo describing all listening sockets.\n+#          The list can be empty (in case the vnc server is disabled).\n+#          It also may have multiple entries: normal + websocket,\n+#          possibly also ipv4 + ipv6 in the future.\n+#\n+# @clients: A list of @VncClientInfo of all currently connected clients.\n+#           The list can be empty, for obvious reasons.\n+#\n+# @auth: The current authentication type used by the non-websockets servers\n+#\n+# @vencrypt: The vencrypt authentication type used by the servers,\n+#            only specified in case auth == vencrypt.\n+#\n+# @display: The display device the vnc server is linked to.\n+#\n+# Since: 2.3\n+##\n+{ 'struct': 'VncInfo2',\n+  'data': { 'id'        : 'str',\n+            'server'    : ['VncServerInfo2'],\n+            'clients'   : ['VncClientInfo'],\n+            'auth'      : 'VncPrimaryAuth',\n+            '*vencrypt' : 'VncVencryptSubAuth',\n+            '*display'  : 'str' } }\n+\n+##\n+# @query-vnc:\n+#\n+# Returns information about the current VNC server\n+#\n+# Returns: @VncInfo\n+#\n+# Since: 0.14.0\n+#\n+# Example:\n+#\n+# -> { \"execute\": \"query-vnc\" }\n+# <- { \"return\": {\n+#          \"enabled\":true,\n+#          \"host\":\"0.0.0.0\",\n+#          \"service\":\"50402\",\n+#          \"auth\":\"vnc\",\n+#          \"family\":\"ipv4\",\n+#          \"clients\":[\n+#             {\n+#                \"host\":\"127.0.0.1\",\n+#                \"service\":\"50401\",\n+#                \"family\":\"ipv4\"\n+#             }\n+#          ]\n+#       }\n+#    }\n+#\n+##\n+{ 'command': 'query-vnc', 'returns': 'VncInfo' }\n+\n+##\n+# @query-vnc-servers:\n+#\n+# Returns a list of vnc servers.  The list can be empty.\n+#\n+# Returns: a list of @VncInfo2\n+#\n+# Since: 2.3\n+##\n+{ 'command': 'query-vnc-servers', 'returns': ['VncInfo2'] }\n+\n+##\n+# @change-vnc-password:\n+#\n+# Change the VNC server password.\n+#\n+# @password:  the new password to use with VNC authentication\n+#\n+# Since: 1.1\n+#\n+# Notes:  An empty password in this command will set the password to the empty\n+#         string.  Existing clients are unaffected by executing this command.\n+##\n+{ 'command': 'change-vnc-password', 'data': {'password': 'str'} }\n+\n+##\n+# @VNC_CONNECTED:\n+#\n+# Emitted when a VNC client establishes a connection\n+#\n+# @server: server information\n+#\n+# @client: client information\n+#\n+# Note: This event is emitted before any authentication takes place, thus\n+# the authentication ID is not provided\n+#\n+# Since: 0.13.0\n+#\n+# Example:\n+#\n+# <- { \"event\": \"VNC_CONNECTED\",\n+#      \"data\": {\n+#            \"server\": { \"auth\": \"sasl\", \"family\": \"ipv4\",\n+#                        \"service\": \"5901\", \"host\": \"0.0.0.0\" },\n+#            \"client\": { \"family\": \"ipv4\", \"service\": \"58425\",\n+#                        \"host\": \"127.0.0.1\" } },\n+#      \"timestamp\": { \"seconds\": 1262976601, \"microseconds\": 975795 } }\n+#\n+##\n+{ 'event': 'VNC_CONNECTED',\n+  'data': { 'server': 'VncServerInfo',\n+            'client': 'VncBasicInfo' } }\n+\n+##\n+# @VNC_INITIALIZED:\n+#\n+# Emitted after authentication takes place (if any) and the VNC session is\n+# made active\n+#\n+# @server: server information\n+#\n+# @client: client information\n+#\n+# Since: 0.13.0\n+#\n+# Example:\n+#\n+# <-  { \"event\": \"VNC_INITIALIZED\",\n+#       \"data\": {\n+#            \"server\": { \"auth\": \"sasl\", \"family\": \"ipv4\",\n+#                        \"service\": \"5901\", \"host\": \"0.0.0.0\"},\n+#            \"client\": { \"family\": \"ipv4\", \"service\": \"46089\",\n+#                        \"host\": \"127.0.0.1\", \"sasl_username\": \"luiz\" } },\n+#       \"timestamp\": { \"seconds\": 1263475302, \"microseconds\": 150772 } }\n+#\n+##\n+{ 'event': 'VNC_INITIALIZED',\n+  'data': { 'server': 'VncServerInfo',\n+            'client': 'VncClientInfo' } }\n+\n+##\n+# @VNC_DISCONNECTED:\n+#\n+# Emitted when the connection is closed\n+#\n+# @server: server information\n+#\n+# @client: client information\n+#\n+# Since: 0.13.0\n+#\n+# Example:\n+#\n+# <- { \"event\": \"VNC_DISCONNECTED\",\n+#      \"data\": {\n+#            \"server\": { \"auth\": \"sasl\", \"family\": \"ipv4\",\n+#                        \"service\": \"5901\", \"host\": \"0.0.0.0\" },\n+#            \"client\": { \"family\": \"ipv4\", \"service\": \"58425\",\n+#                        \"host\": \"127.0.0.1\", \"sasl_username\": \"luiz\" } },\n+#      \"timestamp\": { \"seconds\": 1262976601, \"microseconds\": 975795 } }\n+#\n+##\n+{ 'event': 'VNC_DISCONNECTED',\n+  'data': { 'server': 'VncServerInfo',\n+            'client': 'VncClientInfo' } }\n+\n+##\n+# = Input\n+##\n+\n+##\n+# @MouseInfo:\n+#\n+# Information about a mouse device.\n+#\n+# @name: the name of the mouse device\n+#\n+# @index: the index of the mouse device\n+#\n+# @current: true if this device is currently receiving mouse events\n+#\n+# @absolute: true if this device supports absolute coordinates as input\n+#\n+# Since: 0.14.0\n+##\n+{ 'struct': 'MouseInfo',\n+  'data': {'name': 'str', 'index': 'int', 'current': 'bool',\n+           'absolute': 'bool'} }\n+\n+##\n+# @query-mice:\n+#\n+# Returns information about each active mouse device\n+#\n+# Returns: a list of @MouseInfo for each device\n+#\n+# Since: 0.14.0\n+#\n+# Example:\n+#\n+# -> { \"execute\": \"query-mice\" }\n+# <- { \"return\": [\n+#          {\n+#             \"name\":\"QEMU Microsoft Mouse\",\n+#             \"index\":0,\n+#             \"current\":false,\n+#             \"absolute\":false\n+#          },\n+#          {\n+#             \"name\":\"QEMU PS/2 Mouse\",\n+#             \"index\":1,\n+#             \"current\":true,\n+#             \"absolute\":true\n+#          }\n+#       ]\n+#    }\n+#\n+##\n+{ 'command': 'query-mice', 'returns': ['MouseInfo'] }\n+\n+##\n+# @QKeyCode:\n+#\n+# An enumeration of key name.\n+#\n+# This is used by the @send-key command.\n+#\n+# @unmapped: since 2.0\n+# @pause: since 2.0\n+# @ro: since 2.4\n+# @kp_comma: since 2.4\n+# @kp_equals: since 2.6\n+# @power: since 2.6\n+# @hiragana: since 2.9\n+# @henkan: since 2.9\n+# @yen: since 2.9\n+#\n+# @sleep: since 2.10\n+# @wake: since 2.10\n+# @audionext: since 2.10\n+# @audioprev: since 2.10\n+# @audiostop: since 2.10\n+# @audioplay: since 2.10\n+# @audiomute: since 2.10\n+# @volumeup: since 2.10\n+# @volumedown: since 2.10\n+# @mediaselect: since 2.10\n+# @mail: since 2.10\n+# @calculator: since 2.10\n+# @computer: since 2.10\n+# @ac_home: since 2.10\n+# @ac_back: since 2.10\n+# @ac_forward: since 2.10\n+# @ac_refresh: since 2.10\n+# @ac_bookmarks: since 2.10\n+# altgr, altgr_r: dropped in 2.10\n+#\n+# Since: 1.3.0\n+#\n+##\n+{ 'enum': 'QKeyCode',\n+  'data': [ 'unmapped',\n+            'shift', 'shift_r', 'alt', 'alt_r', 'ctrl',\n+            'ctrl_r', 'menu', 'esc', '1', '2', '3', '4', '5', '6', '7', '8',\n+            '9', '0', 'minus', 'equal', 'backspace', 'tab', 'q', 'w', 'e',\n+            'r', 't', 'y', 'u', 'i', 'o', 'p', 'bracket_left', 'bracket_right',\n+            'ret', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'semicolon',\n+            'apostrophe', 'grave_accent', 'backslash', 'z', 'x', 'c', 'v', 'b',\n+            'n', 'm', 'comma', 'dot', 'slash', 'asterisk', 'spc', 'caps_lock',\n+            'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10',\n+            'num_lock', 'scroll_lock', 'kp_divide', 'kp_multiply',\n+            'kp_subtract', 'kp_add', 'kp_enter', 'kp_decimal', 'sysrq', 'kp_0',\n+            'kp_1', 'kp_2', 'kp_3', 'kp_4', 'kp_5', 'kp_6', 'kp_7', 'kp_8',\n+            'kp_9', 'less', 'f11', 'f12', 'print', 'home', 'pgup', 'pgdn', 'end',\n+            'left', 'up', 'down', 'right', 'insert', 'delete', 'stop', 'again',\n+            'props', 'undo', 'front', 'copy', 'open', 'paste', 'find', 'cut',\n+            'lf', 'help', 'meta_l', 'meta_r', 'compose', 'pause',\n+            'ro', 'hiragana', 'henkan', 'yen',\n+            'kp_comma', 'kp_equals', 'power', 'sleep', 'wake',\n+            'audionext', 'audioprev', 'audiostop', 'audioplay', 'audiomute',\n+            'volumeup', 'volumedown', 'mediaselect',\n+            'mail', 'calculator', 'computer',\n+            'ac_home', 'ac_back', 'ac_forward', 'ac_refresh', 'ac_bookmarks' ] }\n+\n+##\n+# @KeyValue:\n+#\n+# Represents a keyboard key.\n+#\n+# Since: 1.3.0\n+##\n+{ 'union': 'KeyValue',\n+  'data': {\n+    'number': 'int',\n+    'qcode': 'QKeyCode' } }\n+\n+##\n+# @send-key:\n+#\n+# Send keys to guest.\n+#\n+# @keys: An array of @KeyValue elements. All @KeyValues in this array are\n+#        simultaneously sent to the guest. A @KeyValue.number value is sent\n+#        directly to the guest, while @KeyValue.qcode must be a valid\n+#        @QKeyCode value\n+#\n+# @hold-time: time to delay key up events, milliseconds. Defaults\n+#             to 100\n+#\n+# Returns: Nothing on success\n+#          If key is unknown or redundant, InvalidParameter\n+#\n+# Since: 1.3.0\n+#\n+# Example:\n+#\n+# -> { \"execute\": \"send-key\",\n+#      \"arguments\": { \"keys\": [ { \"type\": \"qcode\", \"data\": \"ctrl\" },\n+#                               { \"type\": \"qcode\", \"data\": \"alt\" },\n+#                               { \"type\": \"qcode\", \"data\": \"delete\" } ] } }\n+# <- { \"return\": {} }\n+#\n+##\n+{ 'command': 'send-key',\n+  'data': { 'keys': ['KeyValue'], '*hold-time': 'int' } }\n+\n+##\n+# @InputButton:\n+#\n+# Button of a pointer input device (mouse, tablet).\n+#\n+# @side: front side button of a 5-button mouse (since 2.9)\n+#\n+# @extra: rear side button of a 5-button mouse (since 2.9)\n+#\n+# Since: 2.0\n+##\n+{ 'enum'  : 'InputButton',\n+  'data'  : [ 'left', 'middle', 'right', 'wheel-up', 'wheel-down', 'side',\n+  'extra' ] }\n+\n+##\n+# @InputAxis:\n+#\n+# Position axis of a pointer input device (mouse, tablet).\n+#\n+# Since: 2.0\n+##\n+{ 'enum'  : 'InputAxis',\n+  'data'  : [ 'x', 'y' ] }\n+\n+##\n+# @InputKeyEvent:\n+#\n+# Keyboard input event.\n+#\n+# @key:    Which key this event is for.\n+# @down:   True for key-down and false for key-up events.\n+#\n+# Since: 2.0\n+##\n+{ 'struct'  : 'InputKeyEvent',\n+  'data'  : { 'key'     : 'KeyValue',\n+              'down'    : 'bool' } }\n+\n+##\n+# @InputBtnEvent:\n+#\n+# Pointer button input event.\n+#\n+# @button: Which button this event is for.\n+# @down:   True for key-down and false for key-up events.\n+#\n+# Since: 2.0\n+##\n+{ 'struct'  : 'InputBtnEvent',\n+  'data'  : { 'button'  : 'InputButton',\n+              'down'    : 'bool' } }\n+\n+##\n+# @InputMoveEvent:\n+#\n+# Pointer motion input event.\n+#\n+# @axis:   Which axis is referenced by @value.\n+# @value:  Pointer position.  For absolute coordinates the\n+#          valid range is 0 -> 0x7ffff\n+#\n+# Since: 2.0\n+##\n+{ 'struct'  : 'InputMoveEvent',\n+  'data'  : { 'axis'    : 'InputAxis',\n+              'value'   : 'int' } }\n+\n+##\n+# @InputEvent:\n+#\n+# Input event union.\n+#\n+# @type: the input type, one of:\n+#  - 'key': Input event of Keyboard\n+#  - 'btn': Input event of pointer buttons\n+#  - 'rel': Input event of relative pointer motion\n+#  - 'abs': Input event of absolute pointer motion\n+#\n+# Since: 2.0\n+##\n+{ 'union' : 'InputEvent',\n+  'data'  : { 'key'     : 'InputKeyEvent',\n+              'btn'     : 'InputBtnEvent',\n+              'rel'     : 'InputMoveEvent',\n+              'abs'     : 'InputMoveEvent' } }\n+\n+##\n+# @input-send-event:\n+#\n+# Send input event(s) to guest.\n+#\n+# @device: display device to send event(s) to.\n+# @head: head to send event(s) to, in case the\n+#        display device supports multiple scanouts.\n+# @events: List of InputEvent union.\n+#\n+# Returns: Nothing on success.\n+#\n+# The @device and @head parameters can be used to send the input event\n+# to specific input devices in case (a) multiple input devices of the\n+# same kind are added to the virtual machine and (b) you have\n+# configured input routing (see docs/multiseat.txt) for those input\n+# devices.  The parameters work exactly like the device and head\n+# properties of input devices.  If @device is missing, only devices\n+# that have no input routing config are admissible.  If @device is\n+# specified, both input devices with and without input routing config\n+# are admissible, but devices with input routing config take\n+# precedence.\n+#\n+# Since: 2.6\n+#\n+# Note: The consoles are visible in the qom tree, under\n+# /backend/console[$index]. They have a device link and head property,\n+# so it is possible to map which console belongs to which device and\n+# display.\n+#\n+# Example:\n+#\n+# 1. Press left mouse button.\n+#\n+# -> { \"execute\": \"input-send-event\",\n+#     \"arguments\": { \"device\": \"video0\",\n+#                    \"events\": [ { \"type\": \"btn\",\n+#                    \"data\" : { \"down\": true, \"button\": \"left\" } } ] } }\n+# <- { \"return\": {} }\n+#\n+# -> { \"execute\": \"input-send-event\",\n+#     \"arguments\": { \"device\": \"video0\",\n+#                    \"events\": [ { \"type\": \"btn\",\n+#                    \"data\" : { \"down\": false, \"button\": \"left\" } } ] } }\n+# <- { \"return\": {} }\n+#\n+# 2. Press ctrl-alt-del.\n+#\n+# -> { \"execute\": \"input-send-event\",\n+#      \"arguments\": { \"events\": [\n+#         { \"type\": \"key\", \"data\" : { \"down\": true,\n+#           \"key\": {\"type\": \"qcode\", \"data\": \"ctrl\" } } },\n+#         { \"type\": \"key\", \"data\" : { \"down\": true,\n+#           \"key\": {\"type\": \"qcode\", \"data\": \"alt\" } } },\n+#         { \"type\": \"key\", \"data\" : { \"down\": true,\n+#           \"key\": {\"type\": \"qcode\", \"data\": \"delete\" } } } ] } }\n+# <- { \"return\": {} }\n+#\n+# 3. Move mouse pointer to absolute coordinates (20000, 400).\n+#\n+# -> { \"execute\": \"input-send-event\" ,\n+#   \"arguments\": { \"events\": [\n+#                { \"type\": \"abs\", \"data\" : { \"axis\": \"x\", \"value\" : 20000 } },\n+#                { \"type\": \"abs\", \"data\" : { \"axis\": \"y\", \"value\" : 400 } } ] } }\n+# <- { \"return\": {} }\n+#\n+##\n+{ 'command': 'input-send-event',\n+  'data': { '*device': 'str',\n+            '*head'  : 'int',\n+            'events' : [ 'InputEvent' ] } }\n",
    "prefixes": [
        "PULL",
        "v2",
        "23/47"
    ]
}