Monitor patches for 2023-01-19
-----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEENUvIs9frKmtoZ05fOHC0AOuRhlMFAmPJO+8SHGFybWJydUBy ZWRoYXQuY29tAAoJEDhwtADrkYZTbBwP/RsZLLDCz6moSet4Hly+vPTWibyYYDkS uk6a70Ja7fsAcONumBaXdpoinPtbED662eYxidbLFr//tAjnKu57jnwAIFTTOKJc sCVtdgOlbNSZFrqyIr8ctY6yKJLLBaa02in/BczFIQphPatpUwvxrvrdgxc58NNK qaeKDnWKXvZ6EUaYPpruxqE5J/NV0ykyab9Rc8rNJqdUMnqbd662zHcA0l31misH gAfKBhReo53XUbfvoFS9kaoBQaTJPk4CcKHaT7NJXR8ezlIEQVLtFzdfAf04kSdG 8VRwwx5NDpmafATEaMXJhJ74Fyc8biDWXoQ6aA1jdUCu39B2EPl1H1qlCG9ZYp7w CkbJU6UwtOYsG11NU8Mr1u9rMlAgAVkkLsMYiiI4cpLBkI0vkoV66ms3oZgYUtbq /TgCpfjKpE87ZBLIwJjGsg+TMN2AH5lpt/49HV8QEFA8mI7h29oo2HvheXE7PPzH b9iIe9ADrKwB5DpJW2vigPj+fSHqoSGd3R/hUcMVOubKnJme97mys2hD+sfxga/H qfKLzgTqQI2dGhfow/8wzfYdfYmkii+ggDyzcxLAxx2ITO/fLWJygmTgXJmA3dl6 pnpZvhOu4dEgK4VstugXcvgCVHUVXd9wqI9wxJAc+mKanTmZIJBnxCm/QVG2/w/d 5IgmP9Se7vb0 =7OEC -----END PGP SIGNATURE----- Merge tag 'pull-monitor-2023-01-19' of https://repo.or.cz/qemu/armbru into staging Monitor patches for 2023-01-19 # -----BEGIN PGP SIGNATURE----- # # iQJGBAABCAAwFiEENUvIs9frKmtoZ05fOHC0AOuRhlMFAmPJO+8SHGFybWJydUBy # ZWRoYXQuY29tAAoJEDhwtADrkYZTbBwP/RsZLLDCz6moSet4Hly+vPTWibyYYDkS # uk6a70Ja7fsAcONumBaXdpoinPtbED662eYxidbLFr//tAjnKu57jnwAIFTTOKJc # sCVtdgOlbNSZFrqyIr8ctY6yKJLLBaa02in/BczFIQphPatpUwvxrvrdgxc58NNK # qaeKDnWKXvZ6EUaYPpruxqE5J/NV0ykyab9Rc8rNJqdUMnqbd662zHcA0l31misH # gAfKBhReo53XUbfvoFS9kaoBQaTJPk4CcKHaT7NJXR8ezlIEQVLtFzdfAf04kSdG # 8VRwwx5NDpmafATEaMXJhJ74Fyc8biDWXoQ6aA1jdUCu39B2EPl1H1qlCG9ZYp7w # CkbJU6UwtOYsG11NU8Mr1u9rMlAgAVkkLsMYiiI4cpLBkI0vkoV66ms3oZgYUtbq # /TgCpfjKpE87ZBLIwJjGsg+TMN2AH5lpt/49HV8QEFA8mI7h29oo2HvheXE7PPzH # b9iIe9ADrKwB5DpJW2vigPj+fSHqoSGd3R/hUcMVOubKnJme97mys2hD+sfxga/H # qfKLzgTqQI2dGhfow/8wzfYdfYmkii+ggDyzcxLAxx2ITO/fLWJygmTgXJmA3dl6 # pnpZvhOu4dEgK4VstugXcvgCVHUVXd9wqI9wxJAc+mKanTmZIJBnxCm/QVG2/w/d # 5IgmP9Se7vb0 # =7OEC # -----END PGP SIGNATURE----- # gpg: Signature made Thu 19 Jan 2023 12:47:43 GMT # gpg: using RSA key 354BC8B3D7EB2A6B68674E5F3870B400EB918653 # gpg: issuer "armbru@redhat.com" # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" [full] # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" [full] # Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653 * tag 'pull-monitor-2023-01-19' of https://repo.or.cz/qemu/armbru: ui: Simplify control flow in qemu_mouse_set() ui: Split hmp_mouse_set() and move the HMP part to ui/ ui: Don't check for mode change after mouse_set error ui: Reduce nesting in hmp_change_vnc() slightly ui: Factor out hmp_change_vnc(), and move to ui/ui-hmp-cmds.c ui: Improve "change vnc" error reporting ui: Move HMP commands from monitor to new ui/ui-hmp-cmds.c ui: Factor out qmp_add_client() parts and move to ui/ui-qmp-cmds.c ui: Move QMP commands from monitor to new ui/ui-qmp-cmds.c ui: Clean up a few things checkpatch.pl would flag later on ui/spice: Give hmp_info_spice()'s channel_names[] static linkage ui/spice: QXLInterface method set_mm_time() is now dead, drop ui/spice: Require spice-server >= 0.14.0 Revert "hmp: info spice: take out webdav" ui/spice: Require spice-protocol >= 0.14.0 ui: Fix silent truncation of numeric keys in HMP sendkey ui: Check numeric part of expire_password argument @time properly Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
70d17c3eed
@ -98,9 +98,7 @@ static SpiceCharDeviceInterface vmc_interface = {
|
|||||||
.write = vmc_write,
|
.write = vmc_write,
|
||||||
.read = vmc_read,
|
.read = vmc_read,
|
||||||
.event = vmc_event,
|
.event = vmc_event,
|
||||||
#if SPICE_SERVER_VERSION >= 0x000c06
|
|
||||||
.flags = SPICE_CHAR_DEVICE_NOTIFY_WRITABLE,
|
.flags = SPICE_CHAR_DEVICE_NOTIFY_WRITABLE,
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -260,8 +260,7 @@ static void qxl_spice_monitors_config_async(PCIQXLDevice *qxl, int replay)
|
|||||||
QXL_COOKIE_TYPE_POST_LOAD_MONITORS_CONFIG,
|
QXL_COOKIE_TYPE_POST_LOAD_MONITORS_CONFIG,
|
||||||
0));
|
0));
|
||||||
} else {
|
} else {
|
||||||
/* >= release 0.12.6, < release 0.14.2 */
|
#if SPICE_SERVER_VERSION < 0x000e02 /* release 0.14.2 */
|
||||||
#if SPICE_SERVER_VERSION >= 0x000c06 && SPICE_SERVER_VERSION < 0x000e02
|
|
||||||
if (qxl->max_outputs) {
|
if (qxl->max_outputs) {
|
||||||
spice_qxl_set_max_monitors(&qxl->ssd.qxl, qxl->max_outputs);
|
spice_qxl_set_max_monitors(&qxl->ssd.qxl, qxl->max_outputs);
|
||||||
}
|
}
|
||||||
@ -544,22 +543,6 @@ static void interface_set_compression_level(QXLInstance *sin, int level)
|
|||||||
qxl_rom_set_dirty(qxl);
|
qxl_rom_set_dirty(qxl);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SPICE_NEEDS_SET_MM_TIME
|
|
||||||
static void interface_set_mm_time(QXLInstance *sin, uint32_t mm_time)
|
|
||||||
{
|
|
||||||
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
|
|
||||||
|
|
||||||
if (!qemu_spice_display_is_running(&qxl->ssd)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
trace_qxl_interface_set_mm_time(qxl->id, mm_time);
|
|
||||||
qxl->shadow_rom.mm_clock = cpu_to_le32(mm_time);
|
|
||||||
qxl->rom->mm_clock = cpu_to_le32(mm_time);
|
|
||||||
qxl_rom_set_dirty(qxl);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
|
static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
|
||||||
{
|
{
|
||||||
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
|
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
|
||||||
@ -1089,12 +1072,10 @@ static int interface_client_monitors_config(QXLInstance *sin,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SPICE_SERVER_VERSION >= 0x000c06 /* release 0.12.6 */
|
|
||||||
/* limit number of outputs based on setting limit */
|
/* limit number of outputs based on setting limit */
|
||||||
if (qxl->max_outputs && qxl->max_outputs <= max_outputs) {
|
if (qxl->max_outputs && qxl->max_outputs <= max_outputs) {
|
||||||
max_outputs = qxl->max_outputs;
|
max_outputs = qxl->max_outputs;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
config_changed = qxl_rom_monitors_config_changed(rom,
|
config_changed = qxl_rom_monitors_config_changed(rom,
|
||||||
monitors_config,
|
monitors_config,
|
||||||
@ -1148,9 +1129,6 @@ static const QXLInterface qxl_interface = {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
.set_compression_level = interface_set_compression_level,
|
.set_compression_level = interface_set_compression_level,
|
||||||
#if SPICE_NEEDS_SET_MM_TIME
|
|
||||||
.set_mm_time = interface_set_mm_time,
|
|
||||||
#endif
|
|
||||||
.get_init_info = interface_get_init_info,
|
.get_init_info = interface_get_init_info,
|
||||||
|
|
||||||
/* the callbacks below are called from spice server thread context */
|
/* the callbacks below are called from spice server thread context */
|
||||||
@ -2487,9 +2465,7 @@ static Property qxl_properties[] = {
|
|||||||
DEFINE_PROP_UINT32("vram64_size_mb", PCIQXLDevice, vram_size_mb, -1),
|
DEFINE_PROP_UINT32("vram64_size_mb", PCIQXLDevice, vram_size_mb, -1),
|
||||||
DEFINE_PROP_UINT32("vgamem_mb", PCIQXLDevice, vgamem_size_mb, 16),
|
DEFINE_PROP_UINT32("vgamem_mb", PCIQXLDevice, vgamem_size_mb, 16),
|
||||||
DEFINE_PROP_INT32("surfaces", PCIQXLDevice, ssd.num_surfaces, 1024),
|
DEFINE_PROP_INT32("surfaces", PCIQXLDevice, ssd.num_surfaces, 1024),
|
||||||
#if SPICE_SERVER_VERSION >= 0x000c06 /* release 0.12.6 */
|
|
||||||
DEFINE_PROP_UINT16("max_outputs", PCIQXLDevice, max_outputs, 0),
|
DEFINE_PROP_UINT16("max_outputs", PCIQXLDevice, max_outputs, 0),
|
||||||
#endif
|
|
||||||
DEFINE_PROP_UINT32("xres", PCIQXLDevice, xres, 0),
|
DEFINE_PROP_UINT32("xres", PCIQXLDevice, xres, 0),
|
||||||
DEFINE_PROP_UINT32("yres", PCIQXLDevice, yres, 0),
|
DEFINE_PROP_UINT32("yres", PCIQXLDevice, yres, 0),
|
||||||
DEFINE_PROP_BOOL("global-vmstate", PCIQXLDevice, vga.global_vmstate, false),
|
DEFINE_PROP_BOOL("global-vmstate", PCIQXLDevice, vga.global_vmstate, false),
|
||||||
|
@ -99,9 +99,7 @@ struct PCIQXLDevice {
|
|||||||
QXLModes *modes;
|
QXLModes *modes;
|
||||||
uint32_t rom_size;
|
uint32_t rom_size;
|
||||||
MemoryRegion rom_bar;
|
MemoryRegion rom_bar;
|
||||||
#if SPICE_SERVER_VERSION >= 0x000c06 /* release 0.12.6 */
|
|
||||||
uint16_t max_outputs;
|
uint16_t max_outputs;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* vram pci bar */
|
/* vram pci bar */
|
||||||
uint64_t vram_size;
|
uint64_t vram_size;
|
||||||
|
@ -55,7 +55,6 @@ virtio_gpu_fence_ctrl(uint64_t fence, uint32_t type) "fence 0x%" PRIx64 ", type
|
|||||||
virtio_gpu_fence_resp(uint64_t fence) "fence 0x%" PRIx64
|
virtio_gpu_fence_resp(uint64_t fence) "fence 0x%" PRIx64
|
||||||
|
|
||||||
# qxl.c
|
# qxl.c
|
||||||
disable qxl_interface_set_mm_time(int qid, uint32_t mm_time) "%d %d"
|
|
||||||
disable qxl_io_write_vga(int qid, const char *mode, uint32_t addr, uint32_t val) "%d %s addr=%u val=%u"
|
disable qxl_io_write_vga(int qid, const char *mode, uint32_t addr, uint32_t val) "%d %s addr=%u val=%u"
|
||||||
qxl_create_guest_primary(int qid, uint32_t width, uint32_t height, uint64_t mem, uint32_t format, uint32_t position) "%d %ux%u mem=0x%" PRIx64 " %u,%u"
|
qxl_create_guest_primary(int qid, uint32_t width, uint32_t height, uint64_t mem, uint32_t format, uint32_t position) "%d %ux%u mem=0x%" PRIx64 " %u,%u"
|
||||||
qxl_create_guest_primary_rest(int qid, int32_t stride, uint32_t type, uint32_t flags) "%d %d,%d,%d"
|
qxl_create_guest_primary_rest(int qid, int32_t stride, uint32_t type, uint32_t flags) "%d %d,%d,%d"
|
||||||
|
@ -73,6 +73,11 @@ void hmp_x_colo_lost_heartbeat(Monitor *mon, const QDict *qdict);
|
|||||||
void hmp_set_password(Monitor *mon, const QDict *qdict);
|
void hmp_set_password(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_expire_password(Monitor *mon, const QDict *qdict);
|
void hmp_expire_password(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_change(Monitor *mon, const QDict *qdict);
|
void hmp_change(Monitor *mon, const QDict *qdict);
|
||||||
|
#ifdef CONFIG_VNC
|
||||||
|
void hmp_change_vnc(Monitor *mon, const char *device, const char *target,
|
||||||
|
const char *arg, const char *read_only, bool force,
|
||||||
|
Error **errp);
|
||||||
|
#endif
|
||||||
void hmp_migrate(Monitor *mon, const QDict *qdict);
|
void hmp_migrate(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_device_add(Monitor *mon, const QDict *qdict);
|
void hmp_device_add(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_device_del(Monitor *mon, const QDict *qdict);
|
void hmp_device_del(Monitor *mon, const QDict *qdict);
|
||||||
@ -81,6 +86,9 @@ void hmp_netdev_add(Monitor *mon, const QDict *qdict);
|
|||||||
void hmp_netdev_del(Monitor *mon, const QDict *qdict);
|
void hmp_netdev_del(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_getfd(Monitor *mon, const QDict *qdict);
|
void hmp_getfd(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_closefd(Monitor *mon, const QDict *qdict);
|
void hmp_closefd(Monitor *mon, const QDict *qdict);
|
||||||
|
void hmp_mouse_move(Monitor *mon, const QDict *qdict);
|
||||||
|
void hmp_mouse_button(Monitor *mon, const QDict *qdict);
|
||||||
|
void hmp_mouse_set(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_sendkey(Monitor *mon, const QDict *qdict);
|
void hmp_sendkey(Monitor *mon, const QDict *qdict);
|
||||||
void coroutine_fn hmp_screendump(Monitor *mon, const QDict *qdict);
|
void coroutine_fn hmp_screendump(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_chardev_add(Monitor *mon, const QDict *qdict);
|
void hmp_chardev_add(Monitor *mon, const QDict *qdict);
|
||||||
|
26
include/monitor/qmp-helpers.h
Normal file
26
include/monitor/qmp-helpers.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* QMP command helpers
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Markus Armbruster <armbru@redhat.com>
|
||||||
|
*
|
||||||
|
* This work is licensed under the terms of the GNU GPL, version 2. See
|
||||||
|
* the COPYING file in the top-level directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MONITOR_QMP_HELPERS_H
|
||||||
|
|
||||||
|
bool qmp_add_client_spice(int fd, bool has_skipauth, bool skipauth,
|
||||||
|
bool has_tls, bool tls, Error **errp);
|
||||||
|
#ifdef CONFIG_VNC
|
||||||
|
bool qmp_add_client_vnc(int fd, bool has_skipauth, bool skipauth,
|
||||||
|
bool has_tls, bool tls, Error **errp);
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_DBUS_DISPLAY
|
||||||
|
bool qmp_add_client_dbus_display(int fd, bool has_skipauth, bool skipauth,
|
||||||
|
bool has_tls, bool tls, Error **errp);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -65,7 +65,7 @@ void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry);
|
|||||||
|
|
||||||
void kbd_put_ledstate(int ledstate);
|
void kbd_put_ledstate(int ledstate);
|
||||||
|
|
||||||
void hmp_mouse_set(Monitor *mon, const QDict *qdict);
|
bool qemu_mouse_set(int index, Error **errp);
|
||||||
|
|
||||||
/* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
|
/* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
|
||||||
constants) */
|
constants) */
|
||||||
|
@ -34,13 +34,7 @@ int qemu_spice_add_display_interface(QXLInstance *qxlin, QemuConsole *con);
|
|||||||
int qemu_spice_migrate_info(const char *hostname, int port, int tls_port,
|
int qemu_spice_migrate_info(const char *hostname, int port, int tls_port,
|
||||||
const char *subject);
|
const char *subject);
|
||||||
|
|
||||||
#if !defined(SPICE_SERVER_VERSION) || (SPICE_SERVER_VERSION < 0xc06)
|
#if SPICE_SERVER_VERSION >= 0x000f00 /* release 0.15.0 */
|
||||||
#define SPICE_NEEDS_SET_MM_TIME 1
|
|
||||||
#else
|
|
||||||
#define SPICE_NEEDS_SET_MM_TIME 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(SPICE_SERVER_VERSION) && (SPICE_SERVER_VERSION >= 0x000f00)
|
|
||||||
#define SPICE_HAS_ATTACHED_WORKER 1
|
#define SPICE_HAS_ATTACHED_WORKER 1
|
||||||
#else
|
#else
|
||||||
#define SPICE_HAS_ATTACHED_WORKER 0
|
#define SPICE_HAS_ATTACHED_WORKER 0
|
||||||
|
@ -28,11 +28,9 @@
|
|||||||
#include "ui/console.h"
|
#include "ui/console.h"
|
||||||
|
|
||||||
#if defined(CONFIG_OPENGL) && defined(CONFIG_GBM)
|
#if defined(CONFIG_OPENGL) && defined(CONFIG_GBM)
|
||||||
# if SPICE_SERVER_VERSION >= 0x000d01 /* release 0.13.1 */
|
|
||||||
# define HAVE_SPICE_GL 1
|
# define HAVE_SPICE_GL 1
|
||||||
# include "ui/egl-helpers.h"
|
# include "ui/egl-helpers.h"
|
||||||
# include "ui/egl-context.h"
|
# include "ui/egl-context.h"
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define NUM_MEMSLOTS 8
|
#define NUM_MEMSLOTS 8
|
||||||
|
@ -742,13 +742,13 @@ endif
|
|||||||
|
|
||||||
spice_protocol = not_found
|
spice_protocol = not_found
|
||||||
if not get_option('spice_protocol').auto() or have_system
|
if not get_option('spice_protocol').auto() or have_system
|
||||||
spice_protocol = dependency('spice-protocol', version: '>=0.12.3',
|
spice_protocol = dependency('spice-protocol', version: '>=0.14.0',
|
||||||
required: get_option('spice_protocol'),
|
required: get_option('spice_protocol'),
|
||||||
method: 'pkg-config', kwargs: static_kwargs)
|
method: 'pkg-config', kwargs: static_kwargs)
|
||||||
endif
|
endif
|
||||||
spice = not_found
|
spice = not_found
|
||||||
if not get_option('spice').auto() or have_system
|
if not get_option('spice').auto() or have_system
|
||||||
spice = dependency('spice-server', version: '>=0.12.5',
|
spice = dependency('spice-server', version: '>=0.14.0',
|
||||||
required: get_option('spice'),
|
required: get_option('spice'),
|
||||||
method: 'pkg-config', kwargs: static_kwargs)
|
method: 'pkg-config', kwargs: static_kwargs)
|
||||||
endif
|
endif
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include "qemu/timer.h"
|
#include "qemu/timer.h"
|
||||||
#include "qemu/sockets.h"
|
#include "qemu/sockets.h"
|
||||||
#include "qemu/help_option.h"
|
#include "qemu/help_option.h"
|
||||||
#include "monitor/monitor-internal.h"
|
#include "monitor/monitor.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qapi/clone-visitor.h"
|
#include "qapi/clone-visitor.h"
|
||||||
#include "qapi/opts-visitor.h"
|
#include "qapi/opts-visitor.h"
|
||||||
@ -41,7 +41,6 @@
|
|||||||
#include "qapi/qapi-commands-run-state.h"
|
#include "qapi/qapi-commands-run-state.h"
|
||||||
#include "qapi/qapi-commands-stats.h"
|
#include "qapi/qapi-commands-stats.h"
|
||||||
#include "qapi/qapi-commands-tpm.h"
|
#include "qapi/qapi-commands-tpm.h"
|
||||||
#include "qapi/qapi-commands-ui.h"
|
|
||||||
#include "qapi/qapi-commands-virtio.h"
|
#include "qapi/qapi-commands-virtio.h"
|
||||||
#include "qapi/qapi-visit-virtio.h"
|
#include "qapi/qapi-visit-virtio.h"
|
||||||
#include "qapi/qapi-visit-net.h"
|
#include "qapi/qapi-visit-net.h"
|
||||||
@ -51,7 +50,6 @@
|
|||||||
#include "qapi/string-input-visitor.h"
|
#include "qapi/string-input-visitor.h"
|
||||||
#include "qapi/string-output-visitor.h"
|
#include "qapi/string-output-visitor.h"
|
||||||
#include "qom/object_interfaces.h"
|
#include "qom/object_interfaces.h"
|
||||||
#include "ui/console.h"
|
|
||||||
#include "qemu/cutils.h"
|
#include "qemu/cutils.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "hw/core/cpu.h"
|
#include "hw/core/cpu.h"
|
||||||
@ -59,10 +57,6 @@
|
|||||||
#include "migration/snapshot.h"
|
#include "migration/snapshot.h"
|
||||||
#include "migration/misc.h"
|
#include "migration/misc.h"
|
||||||
|
|
||||||
#ifdef CONFIG_SPICE
|
|
||||||
#include <spice/enums.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool hmp_handle_error(Monitor *mon, Error *err)
|
bool hmp_handle_error(Monitor *mon, Error *err)
|
||||||
{
|
{
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -178,26 +172,6 @@ void hmp_info_chardev(Monitor *mon, const QDict *qdict)
|
|||||||
qapi_free_ChardevInfoList(char_info);
|
qapi_free_ChardevInfoList(char_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_info_mice(Monitor *mon, const QDict *qdict)
|
|
||||||
{
|
|
||||||
MouseInfoList *mice_list, *mouse;
|
|
||||||
|
|
||||||
mice_list = qmp_query_mice(NULL);
|
|
||||||
if (!mice_list) {
|
|
||||||
monitor_printf(mon, "No mouse devices connected\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (mouse = mice_list; mouse; mouse = mouse->next) {
|
|
||||||
monitor_printf(mon, "%c Mouse #%" PRId64 ": %s%s\n",
|
|
||||||
mouse->value->current ? '*' : ' ',
|
|
||||||
mouse->value->index, mouse->value->name,
|
|
||||||
mouse->value->absolute ? " (absolute)" : "");
|
|
||||||
}
|
|
||||||
|
|
||||||
qapi_free_MouseInfoList(mice_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hmp_info_migrate(Monitor *mon, const QDict *qdict)
|
void hmp_info_migrate(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
MigrationInfo *info;
|
MigrationInfo *info;
|
||||||
@ -516,172 +490,6 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
|
|||||||
qapi_free_MigrationParameters(params);
|
qapi_free_MigrationParameters(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_VNC
|
|
||||||
/* Helper for hmp_info_vnc_clients, _servers */
|
|
||||||
static void hmp_info_VncBasicInfo(Monitor *mon, VncBasicInfo *info,
|
|
||||||
const char *name)
|
|
||||||
{
|
|
||||||
monitor_printf(mon, " %s: %s:%s (%s%s)\n",
|
|
||||||
name,
|
|
||||||
info->host,
|
|
||||||
info->service,
|
|
||||||
NetworkAddressFamily_str(info->family),
|
|
||||||
info->websocket ? " (Websocket)" : "");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Helper displaying and auth and crypt info */
|
|
||||||
static void hmp_info_vnc_authcrypt(Monitor *mon, const char *indent,
|
|
||||||
VncPrimaryAuth auth,
|
|
||||||
VncVencryptSubAuth *vencrypt)
|
|
||||||
{
|
|
||||||
monitor_printf(mon, "%sAuth: %s (Sub: %s)\n", indent,
|
|
||||||
VncPrimaryAuth_str(auth),
|
|
||||||
vencrypt ? VncVencryptSubAuth_str(*vencrypt) : "none");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hmp_info_vnc_clients(Monitor *mon, VncClientInfoList *client)
|
|
||||||
{
|
|
||||||
while (client) {
|
|
||||||
VncClientInfo *cinfo = client->value;
|
|
||||||
|
|
||||||
hmp_info_VncBasicInfo(mon, qapi_VncClientInfo_base(cinfo), "Client");
|
|
||||||
monitor_printf(mon, " x509_dname: %s\n",
|
|
||||||
cinfo->x509_dname ?: "none");
|
|
||||||
monitor_printf(mon, " sasl_username: %s\n",
|
|
||||||
cinfo->sasl_username ?: "none");
|
|
||||||
|
|
||||||
client = client->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hmp_info_vnc_servers(Monitor *mon, VncServerInfo2List *server)
|
|
||||||
{
|
|
||||||
while (server) {
|
|
||||||
VncServerInfo2 *sinfo = server->value;
|
|
||||||
hmp_info_VncBasicInfo(mon, qapi_VncServerInfo2_base(sinfo), "Server");
|
|
||||||
hmp_info_vnc_authcrypt(mon, " ", sinfo->auth,
|
|
||||||
sinfo->has_vencrypt ? &sinfo->vencrypt : NULL);
|
|
||||||
server = server->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void hmp_info_vnc(Monitor *mon, const QDict *qdict)
|
|
||||||
{
|
|
||||||
VncInfo2List *info2l, *info2l_head;
|
|
||||||
Error *err = NULL;
|
|
||||||
|
|
||||||
info2l = qmp_query_vnc_servers(&err);
|
|
||||||
info2l_head = info2l;
|
|
||||||
if (hmp_handle_error(mon, err)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!info2l) {
|
|
||||||
monitor_printf(mon, "None\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (info2l) {
|
|
||||||
VncInfo2 *info = info2l->value;
|
|
||||||
monitor_printf(mon, "%s:\n", info->id);
|
|
||||||
hmp_info_vnc_servers(mon, info->server);
|
|
||||||
hmp_info_vnc_clients(mon, info->clients);
|
|
||||||
if (!info->server) {
|
|
||||||
/* The server entry displays its auth, we only
|
|
||||||
* need to display in the case of 'reverse' connections
|
|
||||||
* where there's no server.
|
|
||||||
*/
|
|
||||||
hmp_info_vnc_authcrypt(mon, " ", info->auth,
|
|
||||||
info->has_vencrypt ? &info->vencrypt : NULL);
|
|
||||||
}
|
|
||||||
if (info->display) {
|
|
||||||
monitor_printf(mon, " Display: %s\n", info->display);
|
|
||||||
}
|
|
||||||
info2l = info2l->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
qapi_free_VncInfo2List(info2l_head);
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_SPICE
|
|
||||||
void hmp_info_spice(Monitor *mon, const QDict *qdict)
|
|
||||||
{
|
|
||||||
SpiceChannelList *chan;
|
|
||||||
SpiceInfo *info;
|
|
||||||
const char *channel_name;
|
|
||||||
const char * const channel_names[] = {
|
|
||||||
[SPICE_CHANNEL_MAIN] = "main",
|
|
||||||
[SPICE_CHANNEL_DISPLAY] = "display",
|
|
||||||
[SPICE_CHANNEL_INPUTS] = "inputs",
|
|
||||||
[SPICE_CHANNEL_CURSOR] = "cursor",
|
|
||||||
[SPICE_CHANNEL_PLAYBACK] = "playback",
|
|
||||||
[SPICE_CHANNEL_RECORD] = "record",
|
|
||||||
[SPICE_CHANNEL_TUNNEL] = "tunnel",
|
|
||||||
[SPICE_CHANNEL_SMARTCARD] = "smartcard",
|
|
||||||
[SPICE_CHANNEL_USBREDIR] = "usbredir",
|
|
||||||
[SPICE_CHANNEL_PORT] = "port",
|
|
||||||
#if 0
|
|
||||||
/* minimum spice-protocol is 0.12.3, webdav was added in 0.12.7,
|
|
||||||
* no easy way to #ifdef (SPICE_CHANNEL_* is a enum). Disable
|
|
||||||
* as quick fix for build failures with older versions. */
|
|
||||||
[SPICE_CHANNEL_WEBDAV] = "webdav",
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
info = qmp_query_spice(NULL);
|
|
||||||
|
|
||||||
if (!info->enabled) {
|
|
||||||
monitor_printf(mon, "Server: disabled\n");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
monitor_printf(mon, "Server:\n");
|
|
||||||
if (info->has_port) {
|
|
||||||
monitor_printf(mon, " address: %s:%" PRId64 "\n",
|
|
||||||
info->host, info->port);
|
|
||||||
}
|
|
||||||
if (info->has_tls_port) {
|
|
||||||
monitor_printf(mon, " address: %s:%" PRId64 " [tls]\n",
|
|
||||||
info->host, info->tls_port);
|
|
||||||
}
|
|
||||||
monitor_printf(mon, " migrated: %s\n",
|
|
||||||
info->migrated ? "true" : "false");
|
|
||||||
monitor_printf(mon, " auth: %s\n", info->auth);
|
|
||||||
monitor_printf(mon, " compiled: %s\n", info->compiled_version);
|
|
||||||
monitor_printf(mon, " mouse-mode: %s\n",
|
|
||||||
SpiceQueryMouseMode_str(info->mouse_mode));
|
|
||||||
|
|
||||||
if (!info->has_channels || info->channels == NULL) {
|
|
||||||
monitor_printf(mon, "Channels: none\n");
|
|
||||||
} else {
|
|
||||||
for (chan = info->channels; chan; chan = chan->next) {
|
|
||||||
monitor_printf(mon, "Channel:\n");
|
|
||||||
monitor_printf(mon, " address: %s:%s%s\n",
|
|
||||||
chan->value->host, chan->value->port,
|
|
||||||
chan->value->tls ? " [tls]" : "");
|
|
||||||
monitor_printf(mon, " session: %" PRId64 "\n",
|
|
||||||
chan->value->connection_id);
|
|
||||||
monitor_printf(mon, " channel: %" PRId64 ":%" PRId64 "\n",
|
|
||||||
chan->value->channel_type, chan->value->channel_id);
|
|
||||||
|
|
||||||
channel_name = "unknown";
|
|
||||||
if (chan->value->channel_type > 0 &&
|
|
||||||
chan->value->channel_type < ARRAY_SIZE(channel_names) &&
|
|
||||||
channel_names[chan->value->channel_type]) {
|
|
||||||
channel_name = channel_names[chan->value->channel_type];
|
|
||||||
}
|
|
||||||
|
|
||||||
monitor_printf(mon, " channel name: %s\n", channel_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
qapi_free_SpiceInfo(info);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void hmp_info_balloon(Monitor *mon, const QDict *qdict)
|
void hmp_info_balloon(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
BalloonInfo *info;
|
BalloonInfo *info;
|
||||||
@ -1266,78 +1074,6 @@ void hmp_x_colo_lost_heartbeat(Monitor *mon, const QDict *qdict)
|
|||||||
hmp_handle_error(mon, err);
|
hmp_handle_error(mon, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_set_password(Monitor *mon, const QDict *qdict)
|
|
||||||
{
|
|
||||||
const char *protocol = qdict_get_str(qdict, "protocol");
|
|
||||||
const char *password = qdict_get_str(qdict, "password");
|
|
||||||
const char *display = qdict_get_try_str(qdict, "display");
|
|
||||||
const char *connected = qdict_get_try_str(qdict, "connected");
|
|
||||||
Error *err = NULL;
|
|
||||||
|
|
||||||
SetPasswordOptions opts = {
|
|
||||||
.password = (char *)password,
|
|
||||||
.has_connected = !!connected,
|
|
||||||
};
|
|
||||||
|
|
||||||
opts.connected = qapi_enum_parse(&SetPasswordAction_lookup, connected,
|
|
||||||
SET_PASSWORD_ACTION_KEEP, &err);
|
|
||||||
if (err) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
opts.protocol = qapi_enum_parse(&DisplayProtocol_lookup, protocol,
|
|
||||||
DISPLAY_PROTOCOL_VNC, &err);
|
|
||||||
if (err) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opts.protocol == DISPLAY_PROTOCOL_VNC) {
|
|
||||||
opts.u.vnc.display = (char *)display;
|
|
||||||
}
|
|
||||||
|
|
||||||
qmp_set_password(&opts, &err);
|
|
||||||
|
|
||||||
out:
|
|
||||||
hmp_handle_error(mon, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hmp_expire_password(Monitor *mon, const QDict *qdict)
|
|
||||||
{
|
|
||||||
const char *protocol = qdict_get_str(qdict, "protocol");
|
|
||||||
const char *whenstr = qdict_get_str(qdict, "time");
|
|
||||||
const char *display = qdict_get_try_str(qdict, "display");
|
|
||||||
Error *err = NULL;
|
|
||||||
|
|
||||||
ExpirePasswordOptions opts = {
|
|
||||||
.time = (char *)whenstr,
|
|
||||||
};
|
|
||||||
|
|
||||||
opts.protocol = qapi_enum_parse(&DisplayProtocol_lookup, protocol,
|
|
||||||
DISPLAY_PROTOCOL_VNC, &err);
|
|
||||||
if (err) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opts.protocol == DISPLAY_PROTOCOL_VNC) {
|
|
||||||
opts.u.vnc.display = (char *)display;
|
|
||||||
}
|
|
||||||
|
|
||||||
qmp_expire_password(&opts, &err);
|
|
||||||
|
|
||||||
out:
|
|
||||||
hmp_handle_error(mon, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_VNC
|
|
||||||
static void hmp_change_read_arg(void *opaque, const char *password,
|
|
||||||
void *readline_opaque)
|
|
||||||
{
|
|
||||||
qmp_change_vnc_password(password, NULL);
|
|
||||||
monitor_read_command(opaque, 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void hmp_change(Monitor *mon, const QDict *qdict)
|
void hmp_change(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
const char *device = qdict_get_str(qdict, "device");
|
const char *device = qdict_get_str(qdict, "device");
|
||||||
@ -1350,23 +1086,7 @@ void hmp_change(Monitor *mon, const QDict *qdict)
|
|||||||
|
|
||||||
#ifdef CONFIG_VNC
|
#ifdef CONFIG_VNC
|
||||||
if (strcmp(device, "vnc") == 0) {
|
if (strcmp(device, "vnc") == 0) {
|
||||||
if (read_only) {
|
hmp_change_vnc(mon, device, target, arg, read_only, force, &err);
|
||||||
monitor_printf(mon,
|
|
||||||
"Parameter 'read-only-mode' is invalid for VNC\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (strcmp(target, "passwd") == 0 ||
|
|
||||||
strcmp(target, "password") == 0) {
|
|
||||||
if (!arg) {
|
|
||||||
MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common);
|
|
||||||
monitor_read_password(hmp_mon, hmp_change_read_arg, NULL);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
qmp_change_vnc_password(arg, &err);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
monitor_printf(mon, "Expected 'password' after 'vnc'\n");
|
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
@ -1525,90 +1245,6 @@ void hmp_closefd(Monitor *mon, const QDict *qdict)
|
|||||||
hmp_handle_error(mon, err);
|
hmp_handle_error(mon, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_sendkey(Monitor *mon, const QDict *qdict)
|
|
||||||
{
|
|
||||||
const char *keys = qdict_get_str(qdict, "keys");
|
|
||||||
KeyValue *v = NULL;
|
|
||||||
KeyValueList *head = NULL, **tail = &head;
|
|
||||||
int has_hold_time = qdict_haskey(qdict, "hold-time");
|
|
||||||
int hold_time = qdict_get_try_int(qdict, "hold-time", -1);
|
|
||||||
Error *err = NULL;
|
|
||||||
const char *separator;
|
|
||||||
int keyname_len;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
separator = qemu_strchrnul(keys, '-');
|
|
||||||
keyname_len = separator - keys;
|
|
||||||
|
|
||||||
/* Be compatible with old interface, convert user inputted "<" */
|
|
||||||
if (keys[0] == '<' && keyname_len == 1) {
|
|
||||||
keys = "less";
|
|
||||||
keyname_len = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
v = g_malloc0(sizeof(*v));
|
|
||||||
|
|
||||||
if (strstart(keys, "0x", NULL)) {
|
|
||||||
char *endp;
|
|
||||||
int value = strtoul(keys, &endp, 0);
|
|
||||||
assert(endp <= keys + keyname_len);
|
|
||||||
if (endp != keys + keyname_len) {
|
|
||||||
goto err_out;
|
|
||||||
}
|
|
||||||
v->type = KEY_VALUE_KIND_NUMBER;
|
|
||||||
v->u.number.data = value;
|
|
||||||
} else {
|
|
||||||
int idx = index_from_key(keys, keyname_len);
|
|
||||||
if (idx == Q_KEY_CODE__MAX) {
|
|
||||||
goto err_out;
|
|
||||||
}
|
|
||||||
v->type = KEY_VALUE_KIND_QCODE;
|
|
||||||
v->u.qcode.data = idx;
|
|
||||||
}
|
|
||||||
QAPI_LIST_APPEND(tail, v);
|
|
||||||
v = NULL;
|
|
||||||
|
|
||||||
if (!*separator) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
keys = separator + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
qmp_send_key(head, has_hold_time, hold_time, &err);
|
|
||||||
hmp_handle_error(mon, err);
|
|
||||||
|
|
||||||
out:
|
|
||||||
qapi_free_KeyValue(v);
|
|
||||||
qapi_free_KeyValueList(head);
|
|
||||||
return;
|
|
||||||
|
|
||||||
err_out:
|
|
||||||
monitor_printf(mon, "invalid parameter: %.*s\n", keyname_len, keys);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
void coroutine_fn
|
|
||||||
hmp_screendump(Monitor *mon, const QDict *qdict)
|
|
||||||
{
|
|
||||||
const char *filename = qdict_get_str(qdict, "filename");
|
|
||||||
const char *id = qdict_get_try_str(qdict, "device");
|
|
||||||
int64_t head = qdict_get_try_int(qdict, "head", 0);
|
|
||||||
const char *input_format = qdict_get_try_str(qdict, "format");
|
|
||||||
Error *err = NULL;
|
|
||||||
ImageFormat format;
|
|
||||||
|
|
||||||
format = qapi_enum_parse(&ImageFormat_lookup, input_format,
|
|
||||||
IMAGE_FORMAT_PPM, &err);
|
|
||||||
if (err) {
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
qmp_screendump(filename, id, id != NULL, head,
|
|
||||||
input_format != NULL, format, &err);
|
|
||||||
end:
|
|
||||||
hmp_handle_error(mon, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hmp_chardev_add(Monitor *mon, const QDict *qdict)
|
void hmp_chardev_add(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
const char *args = qdict_get_str(qdict, "args");
|
const char *args = qdict_get_str(qdict, "args");
|
||||||
|
@ -33,8 +33,6 @@
|
|||||||
#include "ui/qemu-spice.h"
|
#include "ui/qemu-spice.h"
|
||||||
#include "qemu/config-file.h"
|
#include "qemu/config-file.h"
|
||||||
#include "qemu/ctype.h"
|
#include "qemu/ctype.h"
|
||||||
#include "ui/console.h"
|
|
||||||
#include "ui/input.h"
|
|
||||||
#include "audio/audio.h"
|
#include "audio/audio.h"
|
||||||
#include "disas/disas.h"
|
#include "disas/disas.h"
|
||||||
#include "qemu/timer.h"
|
#include "qemu/timer.h"
|
||||||
@ -825,49 +823,6 @@ static void hmp_sum(Monitor *mon, const QDict *qdict)
|
|||||||
monitor_printf(mon, "%05d\n", sum);
|
monitor_printf(mon, "%05d\n", sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mouse_button_state;
|
|
||||||
|
|
||||||
static void hmp_mouse_move(Monitor *mon, const QDict *qdict)
|
|
||||||
{
|
|
||||||
int dx, dy, dz, button;
|
|
||||||
const char *dx_str = qdict_get_str(qdict, "dx_str");
|
|
||||||
const char *dy_str = qdict_get_str(qdict, "dy_str");
|
|
||||||
const char *dz_str = qdict_get_try_str(qdict, "dz_str");
|
|
||||||
|
|
||||||
dx = strtol(dx_str, NULL, 0);
|
|
||||||
dy = strtol(dy_str, NULL, 0);
|
|
||||||
qemu_input_queue_rel(NULL, INPUT_AXIS_X, dx);
|
|
||||||
qemu_input_queue_rel(NULL, INPUT_AXIS_Y, dy);
|
|
||||||
|
|
||||||
if (dz_str) {
|
|
||||||
dz = strtol(dz_str, NULL, 0);
|
|
||||||
if (dz != 0) {
|
|
||||||
button = (dz > 0) ? INPUT_BUTTON_WHEEL_UP : INPUT_BUTTON_WHEEL_DOWN;
|
|
||||||
qemu_input_queue_btn(NULL, button, true);
|
|
||||||
qemu_input_event_sync();
|
|
||||||
qemu_input_queue_btn(NULL, button, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
qemu_input_event_sync();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hmp_mouse_button(Monitor *mon, const QDict *qdict)
|
|
||||||
{
|
|
||||||
static uint32_t bmap[INPUT_BUTTON__MAX] = {
|
|
||||||
[INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON,
|
|
||||||
[INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
|
|
||||||
[INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON,
|
|
||||||
};
|
|
||||||
int button_state = qdict_get_int(qdict, "button_state");
|
|
||||||
|
|
||||||
if (mouse_button_state == button_state) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
qemu_input_update_buttons(NULL, bmap, mouse_button_state, button_state);
|
|
||||||
qemu_input_event_sync();
|
|
||||||
mouse_button_state = button_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hmp_ioport_read(Monitor *mon, const QDict *qdict)
|
static void hmp_ioport_read(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
int size = qdict_get_int(qdict, "size");
|
int size = qdict_get_int(qdict, "size");
|
||||||
@ -1700,28 +1655,6 @@ void object_del_completion(ReadLineState *rs, int nb_args, const char *str)
|
|||||||
qapi_free_ObjectPropertyInfoList(start);
|
qapi_free_ObjectPropertyInfoList(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendkey_completion(ReadLineState *rs, int nb_args, const char *str)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
char *sep;
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
if (nb_args != 2) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sep = strrchr(str, '-');
|
|
||||||
if (sep) {
|
|
||||||
str = sep + 1;
|
|
||||||
}
|
|
||||||
len = strlen(str);
|
|
||||||
readline_set_completion_index(rs, len);
|
|
||||||
for (i = 0; i < Q_KEY_CODE__MAX; i++) {
|
|
||||||
if (!strncmp(str, QKeyCode_str(i), len)) {
|
|
||||||
readline_add_completion(rs, QKeyCode_str(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_link_completion(ReadLineState *rs, int nb_args, const char *str)
|
void set_link_completion(ReadLineState *rs, int nb_args, const char *str)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
|
@ -17,13 +17,11 @@
|
|||||||
#include "qemu/cutils.h"
|
#include "qemu/cutils.h"
|
||||||
#include "qemu/option.h"
|
#include "qemu/option.h"
|
||||||
#include "monitor/monitor.h"
|
#include "monitor/monitor.h"
|
||||||
|
#include "monitor/qmp-helpers.h"
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
#include "qemu/config-file.h"
|
#include "qemu/config-file.h"
|
||||||
#include "qemu/uuid.h"
|
#include "qemu/uuid.h"
|
||||||
#include "chardev/char.h"
|
#include "chardev/char.h"
|
||||||
#include "ui/qemu-spice.h"
|
|
||||||
#include "ui/console.h"
|
|
||||||
#include "ui/dbus-display.h"
|
|
||||||
#include "sysemu/kvm.h"
|
#include "sysemu/kvm.h"
|
||||||
#include "sysemu/runstate.h"
|
#include "sysemu/runstate.h"
|
||||||
#include "sysemu/runstate-action.h"
|
#include "sysemu/runstate-action.h"
|
||||||
@ -36,9 +34,7 @@
|
|||||||
#include "qapi/qapi-commands-machine.h"
|
#include "qapi/qapi-commands-machine.h"
|
||||||
#include "qapi/qapi-commands-misc.h"
|
#include "qapi/qapi-commands-misc.h"
|
||||||
#include "qapi/qapi-commands-stats.h"
|
#include "qapi/qapi-commands-stats.h"
|
||||||
#include "qapi/qapi-commands-ui.h"
|
|
||||||
#include "qapi/type-helpers.h"
|
#include "qapi/type-helpers.h"
|
||||||
#include "qapi/qmp/qerror.h"
|
|
||||||
#include "exec/ramlist.h"
|
#include "exec/ramlist.h"
|
||||||
#include "hw/mem/memory-device.h"
|
#include "hw/mem/memory-device.h"
|
||||||
#include "hw/acpi/acpi_dev_interface.h"
|
#include "hw/acpi/acpi_dev_interface.h"
|
||||||
@ -168,130 +164,54 @@ void qmp_system_wakeup(Error **errp)
|
|||||||
qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, errp);
|
qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void qmp_set_password(SetPasswordOptions *opts, Error **errp)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (opts->protocol == DISPLAY_PROTOCOL_SPICE) {
|
|
||||||
if (!qemu_using_spice(errp)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
rc = qemu_spice.set_passwd(opts->password,
|
|
||||||
opts->connected == SET_PASSWORD_ACTION_FAIL,
|
|
||||||
opts->connected == SET_PASSWORD_ACTION_DISCONNECT);
|
|
||||||
} else {
|
|
||||||
assert(opts->protocol == DISPLAY_PROTOCOL_VNC);
|
|
||||||
if (opts->connected != SET_PASSWORD_ACTION_KEEP) {
|
|
||||||
/* vnc supports "connected=keep" only */
|
|
||||||
error_setg(errp, QERR_INVALID_PARAMETER, "connected");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* Note that setting an empty password will not disable login through
|
|
||||||
* this interface. */
|
|
||||||
rc = vnc_display_password(opts->u.vnc.display, opts->password);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rc != 0) {
|
|
||||||
error_setg(errp, "Could not set password");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void qmp_expire_password(ExpirePasswordOptions *opts, Error **errp)
|
|
||||||
{
|
|
||||||
time_t when;
|
|
||||||
int rc;
|
|
||||||
const char *whenstr = opts->time;
|
|
||||||
|
|
||||||
if (strcmp(whenstr, "now") == 0) {
|
|
||||||
when = 0;
|
|
||||||
} else if (strcmp(whenstr, "never") == 0) {
|
|
||||||
when = TIME_MAX;
|
|
||||||
} else if (whenstr[0] == '+') {
|
|
||||||
when = time(NULL) + strtoull(whenstr+1, NULL, 10);
|
|
||||||
} else {
|
|
||||||
when = strtoull(whenstr, NULL, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opts->protocol == DISPLAY_PROTOCOL_SPICE) {
|
|
||||||
if (!qemu_using_spice(errp)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
rc = qemu_spice.set_pw_expire(when);
|
|
||||||
} else {
|
|
||||||
assert(opts->protocol == DISPLAY_PROTOCOL_VNC);
|
|
||||||
rc = vnc_display_pw_expire(opts->u.vnc.display, when);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rc != 0) {
|
|
||||||
error_setg(errp, "Could not set password expire time");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_VNC
|
|
||||||
void qmp_change_vnc_password(const char *password, Error **errp)
|
|
||||||
{
|
|
||||||
if (vnc_display_password(NULL, password) < 0) {
|
|
||||||
error_setg(errp, "Could not set password");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void qmp_add_client(const char *protocol, const char *fdname,
|
void qmp_add_client(const char *protocol, const char *fdname,
|
||||||
bool has_skipauth, bool skipauth, bool has_tls, bool tls,
|
bool has_skipauth, bool skipauth, bool has_tls, bool tls,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
|
static const struct {
|
||||||
|
const char *name;
|
||||||
|
bool (*add_client)(int fd, bool has_skipauth, bool skipauth,
|
||||||
|
bool has_tls, bool tls, Error **errp);
|
||||||
|
} protocol_table[] = {
|
||||||
|
{ "spice", qmp_add_client_spice },
|
||||||
|
#ifdef CONFIG_VNC
|
||||||
|
{ "vnc", qmp_add_client_vnc },
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_DBUS_DISPLAY
|
||||||
|
{ "@dbus-display", qmp_add_client_dbus_display },
|
||||||
|
#endif
|
||||||
|
};
|
||||||
Chardev *s;
|
Chardev *s;
|
||||||
int fd;
|
int fd, i;
|
||||||
|
|
||||||
fd = monitor_get_fd(monitor_cur(), fdname, errp);
|
fd = monitor_get_fd(monitor_cur(), fdname, errp);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(protocol, "spice") == 0) {
|
for (i = 0; i < ARRAY_SIZE(protocol_table); i++) {
|
||||||
if (!qemu_using_spice(errp)) {
|
if (!strcmp(protocol, protocol_table[i].name)) {
|
||||||
close(fd);
|
if (!protocol_table[i].add_client(fd, has_skipauth, skipauth,
|
||||||
|
has_tls, tls, errp)) {
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
skipauth = has_skipauth ? skipauth : false;
|
|
||||||
tls = has_tls ? tls : false;
|
|
||||||
if (qemu_spice.display_add_client(fd, skipauth, tls) < 0) {
|
|
||||||
error_setg(errp, "spice failed to add client");
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
#ifdef CONFIG_VNC
|
|
||||||
} else if (strcmp(protocol, "vnc") == 0) {
|
|
||||||
skipauth = has_skipauth ? skipauth : false;
|
|
||||||
vnc_display_add_client(NULL, fd, skipauth);
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_DBUS_DISPLAY
|
|
||||||
} else if (strcmp(protocol, "@dbus-display") == 0) {
|
|
||||||
if (!qemu_using_dbus_display(errp)) {
|
|
||||||
close(fd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!qemu_dbus_display.add_client(fd, errp)) {
|
|
||||||
close(fd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
} else if ((s = qemu_chr_find(protocol)) != NULL) {
|
|
||||||
if (qemu_chr_add_client(s, fd) < 0) {
|
|
||||||
error_setg(errp, "failed to add client");
|
|
||||||
close(fd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
error_setg(errp, "protocol '%s' is invalid", protocol);
|
s = qemu_chr_find(protocol);
|
||||||
close(fd);
|
if (!s) {
|
||||||
|
error_setg(errp, "protocol '%s' is invalid", protocol);
|
||||||
|
close(fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (qemu_chr_add_client(s, fd) < 0) {
|
||||||
|
error_setg(errp, "failed to add client");
|
||||||
|
close(fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MemoryDeviceInfoList *qmp_query_memory_devices(Error **errp)
|
MemoryDeviceInfoList *qmp_query_memory_devices(Error **errp)
|
||||||
{
|
{
|
||||||
return qmp_memory_device_list();
|
return qmp_memory_device_list();
|
||||||
@ -330,38 +250,6 @@ MemoryInfo *qmp_query_memory_size_summary(Error **errp)
|
|||||||
return mem_info;
|
return mem_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
void qmp_display_reload(DisplayReloadOptions *arg, Error **errp)
|
|
||||||
{
|
|
||||||
switch (arg->type) {
|
|
||||||
case DISPLAY_RELOAD_TYPE_VNC:
|
|
||||||
#ifdef CONFIG_VNC
|
|
||||||
if (arg->u.vnc.has_tls_certs && arg->u.vnc.tls_certs) {
|
|
||||||
vnc_display_reload_certs(NULL, errp);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
error_setg(errp, "vnc is invalid, missing 'CONFIG_VNC'");
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void qmp_display_update(DisplayUpdateOptions *arg, Error **errp)
|
|
||||||
{
|
|
||||||
switch (arg->type) {
|
|
||||||
case DISPLAY_UPDATE_TYPE_VNC:
|
|
||||||
#ifdef CONFIG_VNC
|
|
||||||
vnc_display_update(&arg->u.vnc, errp);
|
|
||||||
#else
|
|
||||||
error_setg(errp, "vnc is invalid, missing 'CONFIG_VNC'");
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int qmp_x_query_rdma_foreach(Object *obj, void *opaque)
|
static int qmp_x_query_rdma_foreach(Object *obj, void *opaque)
|
||||||
{
|
{
|
||||||
RdmaProvider *rdma;
|
RdmaProvider *rdma;
|
||||||
|
32
ui/input.c
32
ui/input.c
@ -2,8 +2,6 @@
|
|||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qapi/qapi-commands-ui.h"
|
#include "qapi/qapi-commands-ui.h"
|
||||||
#include "qapi/qmp/qdict.h"
|
|
||||||
#include "qemu/error-report.h"
|
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "ui/input.h"
|
#include "ui/input.h"
|
||||||
#include "ui/console.h"
|
#include "ui/console.h"
|
||||||
@ -594,29 +592,29 @@ MouseInfoList *qmp_query_mice(Error **errp)
|
|||||||
return mice_list;
|
return mice_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_mouse_set(Monitor *mon, const QDict *qdict)
|
bool qemu_mouse_set(int index, Error **errp)
|
||||||
{
|
{
|
||||||
QemuInputHandlerState *s;
|
QemuInputHandlerState *s;
|
||||||
int index = qdict_get_int(qdict, "index");
|
|
||||||
int found = 0;
|
|
||||||
|
|
||||||
QTAILQ_FOREACH(s, &handlers, node) {
|
QTAILQ_FOREACH(s, &handlers, node) {
|
||||||
if (s->id != index) {
|
if (s->id == index) {
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
if (!(s->handler->mask & (INPUT_EVENT_MASK_REL |
|
|
||||||
INPUT_EVENT_MASK_ABS))) {
|
|
||||||
error_report("Input device '%s' is not a mouse", s->handler->name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
found = 1;
|
|
||||||
qemu_input_handler_activate(s);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) {
|
if (!s) {
|
||||||
error_report("Mouse at index '%d' not found", index);
|
error_setg(errp, "Mouse at index '%d' not found", index);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(s->handler->mask & (INPUT_EVENT_MASK_REL |
|
||||||
|
INPUT_EVENT_MASK_ABS))) {
|
||||||
|
error_setg(errp, "Input device '%s' is not a mouse",
|
||||||
|
s->handler->name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
qemu_input_handler_activate(s);
|
||||||
qemu_input_check_mode_change();
|
qemu_input_check_mode_change();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,8 @@ softmmu_ss.add(files(
|
|||||||
'kbd-state.c',
|
'kbd-state.c',
|
||||||
'keymaps.c',
|
'keymaps.c',
|
||||||
'qemu-pixman.c',
|
'qemu-pixman.c',
|
||||||
|
'ui-hmp-cmds.c',
|
||||||
|
'ui-qmp-cmds.c',
|
||||||
'util.c',
|
'util.c',
|
||||||
))
|
))
|
||||||
if dbus_display
|
if dbus_display
|
||||||
|
@ -517,13 +517,6 @@ static void interface_set_compression_level(QXLInstance *sin, int level)
|
|||||||
/* nothing to do */
|
/* nothing to do */
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SPICE_NEEDS_SET_MM_TIME
|
|
||||||
static void interface_set_mm_time(QXLInstance *sin, uint32_t mm_time)
|
|
||||||
{
|
|
||||||
/* nothing to do */
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
|
static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
|
||||||
{
|
{
|
||||||
SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
|
SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
|
||||||
@ -715,9 +708,6 @@ static const QXLInterface dpy_interface = {
|
|||||||
.attache_worker = interface_attach_worker,
|
.attache_worker = interface_attach_worker,
|
||||||
#endif
|
#endif
|
||||||
.set_compression_level = interface_set_compression_level,
|
.set_compression_level = interface_set_compression_level,
|
||||||
#if SPICE_NEEDS_SET_MM_TIME
|
|
||||||
.set_mm_time = interface_set_mm_time,
|
|
||||||
#endif
|
|
||||||
.get_init_info = interface_get_init_info,
|
.get_init_info = interface_get_init_info,
|
||||||
|
|
||||||
/* the callbacks below are called from spice server thread context */
|
/* the callbacks below are called from spice server thread context */
|
||||||
|
460
ui/ui-hmp-cmds.c
Normal file
460
ui/ui-hmp-cmds.c
Normal file
@ -0,0 +1,460 @@
|
|||||||
|
/*
|
||||||
|
* HMP commands related to UI
|
||||||
|
*
|
||||||
|
* Copyright IBM, Corp. 2011
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Anthony Liguori <aliguori@us.ibm.com>
|
||||||
|
*
|
||||||
|
* This work is licensed under the terms of the GNU GPL, version 2. See
|
||||||
|
* the COPYING file in the top-level directory.
|
||||||
|
*
|
||||||
|
* Contributions after 2012-01-13 are licensed under the terms of the
|
||||||
|
* GNU GPL, version 2 or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qemu/osdep.h"
|
||||||
|
#ifdef CONFIG_SPICE
|
||||||
|
#include <spice/enums.h>
|
||||||
|
#endif
|
||||||
|
#include "monitor/hmp.h"
|
||||||
|
#include "monitor/monitor-internal.h"
|
||||||
|
#include "qapi/error.h"
|
||||||
|
#include "qapi/qapi-commands-ui.h"
|
||||||
|
#include "qapi/qmp/qdict.h"
|
||||||
|
#include "qemu/cutils.h"
|
||||||
|
#include "ui/console.h"
|
||||||
|
#include "ui/input.h"
|
||||||
|
|
||||||
|
static int mouse_button_state;
|
||||||
|
|
||||||
|
void hmp_mouse_move(Monitor *mon, const QDict *qdict)
|
||||||
|
{
|
||||||
|
int dx, dy, dz, button;
|
||||||
|
const char *dx_str = qdict_get_str(qdict, "dx_str");
|
||||||
|
const char *dy_str = qdict_get_str(qdict, "dy_str");
|
||||||
|
const char *dz_str = qdict_get_try_str(qdict, "dz_str");
|
||||||
|
|
||||||
|
dx = strtol(dx_str, NULL, 0);
|
||||||
|
dy = strtol(dy_str, NULL, 0);
|
||||||
|
qemu_input_queue_rel(NULL, INPUT_AXIS_X, dx);
|
||||||
|
qemu_input_queue_rel(NULL, INPUT_AXIS_Y, dy);
|
||||||
|
|
||||||
|
if (dz_str) {
|
||||||
|
dz = strtol(dz_str, NULL, 0);
|
||||||
|
if (dz != 0) {
|
||||||
|
button = (dz > 0) ? INPUT_BUTTON_WHEEL_UP : INPUT_BUTTON_WHEEL_DOWN;
|
||||||
|
qemu_input_queue_btn(NULL, button, true);
|
||||||
|
qemu_input_event_sync();
|
||||||
|
qemu_input_queue_btn(NULL, button, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qemu_input_event_sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void hmp_mouse_button(Monitor *mon, const QDict *qdict)
|
||||||
|
{
|
||||||
|
static uint32_t bmap[INPUT_BUTTON__MAX] = {
|
||||||
|
[INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON,
|
||||||
|
[INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
|
||||||
|
[INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON,
|
||||||
|
};
|
||||||
|
int button_state = qdict_get_int(qdict, "button_state");
|
||||||
|
|
||||||
|
if (mouse_button_state == button_state) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qemu_input_update_buttons(NULL, bmap, mouse_button_state, button_state);
|
||||||
|
qemu_input_event_sync();
|
||||||
|
mouse_button_state = button_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hmp_mouse_set(Monitor *mon, const QDict *qdict)
|
||||||
|
{
|
||||||
|
Error *err = NULL;
|
||||||
|
|
||||||
|
qemu_mouse_set(qdict_get_int(qdict, "index"), &err);
|
||||||
|
hmp_handle_error(mon, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hmp_info_mice(Monitor *mon, const QDict *qdict)
|
||||||
|
{
|
||||||
|
MouseInfoList *mice_list, *mouse;
|
||||||
|
|
||||||
|
mice_list = qmp_query_mice(NULL);
|
||||||
|
if (!mice_list) {
|
||||||
|
monitor_printf(mon, "No mouse devices connected\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (mouse = mice_list; mouse; mouse = mouse->next) {
|
||||||
|
monitor_printf(mon, "%c Mouse #%" PRId64 ": %s%s\n",
|
||||||
|
mouse->value->current ? '*' : ' ',
|
||||||
|
mouse->value->index, mouse->value->name,
|
||||||
|
mouse->value->absolute ? " (absolute)" : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
qapi_free_MouseInfoList(mice_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_VNC
|
||||||
|
/* Helper for hmp_info_vnc_clients, _servers */
|
||||||
|
static void hmp_info_VncBasicInfo(Monitor *mon, VncBasicInfo *info,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
monitor_printf(mon, " %s: %s:%s (%s%s)\n",
|
||||||
|
name,
|
||||||
|
info->host,
|
||||||
|
info->service,
|
||||||
|
NetworkAddressFamily_str(info->family),
|
||||||
|
info->websocket ? " (Websocket)" : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Helper displaying and auth and crypt info */
|
||||||
|
static void hmp_info_vnc_authcrypt(Monitor *mon, const char *indent,
|
||||||
|
VncPrimaryAuth auth,
|
||||||
|
VncVencryptSubAuth *vencrypt)
|
||||||
|
{
|
||||||
|
monitor_printf(mon, "%sAuth: %s (Sub: %s)\n", indent,
|
||||||
|
VncPrimaryAuth_str(auth),
|
||||||
|
vencrypt ? VncVencryptSubAuth_str(*vencrypt) : "none");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hmp_info_vnc_clients(Monitor *mon, VncClientInfoList *client)
|
||||||
|
{
|
||||||
|
while (client) {
|
||||||
|
VncClientInfo *cinfo = client->value;
|
||||||
|
|
||||||
|
hmp_info_VncBasicInfo(mon, qapi_VncClientInfo_base(cinfo), "Client");
|
||||||
|
monitor_printf(mon, " x509_dname: %s\n",
|
||||||
|
cinfo->x509_dname ?: "none");
|
||||||
|
monitor_printf(mon, " sasl_username: %s\n",
|
||||||
|
cinfo->sasl_username ?: "none");
|
||||||
|
|
||||||
|
client = client->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hmp_info_vnc_servers(Monitor *mon, VncServerInfo2List *server)
|
||||||
|
{
|
||||||
|
while (server) {
|
||||||
|
VncServerInfo2 *sinfo = server->value;
|
||||||
|
hmp_info_VncBasicInfo(mon, qapi_VncServerInfo2_base(sinfo), "Server");
|
||||||
|
hmp_info_vnc_authcrypt(mon, " ", sinfo->auth,
|
||||||
|
sinfo->has_vencrypt ? &sinfo->vencrypt : NULL);
|
||||||
|
server = server->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void hmp_info_vnc(Monitor *mon, const QDict *qdict)
|
||||||
|
{
|
||||||
|
VncInfo2List *info2l, *info2l_head;
|
||||||
|
Error *err = NULL;
|
||||||
|
|
||||||
|
info2l = qmp_query_vnc_servers(&err);
|
||||||
|
info2l_head = info2l;
|
||||||
|
if (hmp_handle_error(mon, err)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!info2l) {
|
||||||
|
monitor_printf(mon, "None\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (info2l) {
|
||||||
|
VncInfo2 *info = info2l->value;
|
||||||
|
monitor_printf(mon, "%s:\n", info->id);
|
||||||
|
hmp_info_vnc_servers(mon, info->server);
|
||||||
|
hmp_info_vnc_clients(mon, info->clients);
|
||||||
|
if (!info->server) {
|
||||||
|
/*
|
||||||
|
* The server entry displays its auth, we only need to
|
||||||
|
* display in the case of 'reverse' connections where
|
||||||
|
* there's no server.
|
||||||
|
*/
|
||||||
|
hmp_info_vnc_authcrypt(mon, " ", info->auth,
|
||||||
|
info->has_vencrypt ? &info->vencrypt : NULL);
|
||||||
|
}
|
||||||
|
if (info->display) {
|
||||||
|
monitor_printf(mon, " Display: %s\n", info->display);
|
||||||
|
}
|
||||||
|
info2l = info2l->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
qapi_free_VncInfo2List(info2l_head);
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_SPICE
|
||||||
|
void hmp_info_spice(Monitor *mon, const QDict *qdict)
|
||||||
|
{
|
||||||
|
SpiceChannelList *chan;
|
||||||
|
SpiceInfo *info;
|
||||||
|
const char *channel_name;
|
||||||
|
static const char *const channel_names[] = {
|
||||||
|
[SPICE_CHANNEL_MAIN] = "main",
|
||||||
|
[SPICE_CHANNEL_DISPLAY] = "display",
|
||||||
|
[SPICE_CHANNEL_INPUTS] = "inputs",
|
||||||
|
[SPICE_CHANNEL_CURSOR] = "cursor",
|
||||||
|
[SPICE_CHANNEL_PLAYBACK] = "playback",
|
||||||
|
[SPICE_CHANNEL_RECORD] = "record",
|
||||||
|
[SPICE_CHANNEL_TUNNEL] = "tunnel",
|
||||||
|
[SPICE_CHANNEL_SMARTCARD] = "smartcard",
|
||||||
|
[SPICE_CHANNEL_USBREDIR] = "usbredir",
|
||||||
|
[SPICE_CHANNEL_PORT] = "port",
|
||||||
|
[SPICE_CHANNEL_WEBDAV] = "webdav",
|
||||||
|
};
|
||||||
|
|
||||||
|
info = qmp_query_spice(NULL);
|
||||||
|
|
||||||
|
if (!info->enabled) {
|
||||||
|
monitor_printf(mon, "Server: disabled\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
monitor_printf(mon, "Server:\n");
|
||||||
|
if (info->has_port) {
|
||||||
|
monitor_printf(mon, " address: %s:%" PRId64 "\n",
|
||||||
|
info->host, info->port);
|
||||||
|
}
|
||||||
|
if (info->has_tls_port) {
|
||||||
|
monitor_printf(mon, " address: %s:%" PRId64 " [tls]\n",
|
||||||
|
info->host, info->tls_port);
|
||||||
|
}
|
||||||
|
monitor_printf(mon, " migrated: %s\n",
|
||||||
|
info->migrated ? "true" : "false");
|
||||||
|
monitor_printf(mon, " auth: %s\n", info->auth);
|
||||||
|
monitor_printf(mon, " compiled: %s\n", info->compiled_version);
|
||||||
|
monitor_printf(mon, " mouse-mode: %s\n",
|
||||||
|
SpiceQueryMouseMode_str(info->mouse_mode));
|
||||||
|
|
||||||
|
if (!info->has_channels || info->channels == NULL) {
|
||||||
|
monitor_printf(mon, "Channels: none\n");
|
||||||
|
} else {
|
||||||
|
for (chan = info->channels; chan; chan = chan->next) {
|
||||||
|
monitor_printf(mon, "Channel:\n");
|
||||||
|
monitor_printf(mon, " address: %s:%s%s\n",
|
||||||
|
chan->value->host, chan->value->port,
|
||||||
|
chan->value->tls ? " [tls]" : "");
|
||||||
|
monitor_printf(mon, " session: %" PRId64 "\n",
|
||||||
|
chan->value->connection_id);
|
||||||
|
monitor_printf(mon, " channel: %" PRId64 ":%" PRId64 "\n",
|
||||||
|
chan->value->channel_type, chan->value->channel_id);
|
||||||
|
|
||||||
|
channel_name = "unknown";
|
||||||
|
if (chan->value->channel_type > 0 &&
|
||||||
|
chan->value->channel_type < ARRAY_SIZE(channel_names) &&
|
||||||
|
channel_names[chan->value->channel_type]) {
|
||||||
|
channel_name = channel_names[chan->value->channel_type];
|
||||||
|
}
|
||||||
|
|
||||||
|
monitor_printf(mon, " channel name: %s\n", channel_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
qapi_free_SpiceInfo(info);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void hmp_set_password(Monitor *mon, const QDict *qdict)
|
||||||
|
{
|
||||||
|
const char *protocol = qdict_get_str(qdict, "protocol");
|
||||||
|
const char *password = qdict_get_str(qdict, "password");
|
||||||
|
const char *display = qdict_get_try_str(qdict, "display");
|
||||||
|
const char *connected = qdict_get_try_str(qdict, "connected");
|
||||||
|
Error *err = NULL;
|
||||||
|
|
||||||
|
SetPasswordOptions opts = {
|
||||||
|
.password = (char *)password,
|
||||||
|
.has_connected = !!connected,
|
||||||
|
};
|
||||||
|
|
||||||
|
opts.connected = qapi_enum_parse(&SetPasswordAction_lookup, connected,
|
||||||
|
SET_PASSWORD_ACTION_KEEP, &err);
|
||||||
|
if (err) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.protocol = qapi_enum_parse(&DisplayProtocol_lookup, protocol,
|
||||||
|
DISPLAY_PROTOCOL_VNC, &err);
|
||||||
|
if (err) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts.protocol == DISPLAY_PROTOCOL_VNC) {
|
||||||
|
opts.u.vnc.display = (char *)display;
|
||||||
|
}
|
||||||
|
|
||||||
|
qmp_set_password(&opts, &err);
|
||||||
|
|
||||||
|
out:
|
||||||
|
hmp_handle_error(mon, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hmp_expire_password(Monitor *mon, const QDict *qdict)
|
||||||
|
{
|
||||||
|
const char *protocol = qdict_get_str(qdict, "protocol");
|
||||||
|
const char *whenstr = qdict_get_str(qdict, "time");
|
||||||
|
const char *display = qdict_get_try_str(qdict, "display");
|
||||||
|
Error *err = NULL;
|
||||||
|
|
||||||
|
ExpirePasswordOptions opts = {
|
||||||
|
.time = (char *)whenstr,
|
||||||
|
};
|
||||||
|
|
||||||
|
opts.protocol = qapi_enum_parse(&DisplayProtocol_lookup, protocol,
|
||||||
|
DISPLAY_PROTOCOL_VNC, &err);
|
||||||
|
if (err) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts.protocol == DISPLAY_PROTOCOL_VNC) {
|
||||||
|
opts.u.vnc.display = (char *)display;
|
||||||
|
}
|
||||||
|
|
||||||
|
qmp_expire_password(&opts, &err);
|
||||||
|
|
||||||
|
out:
|
||||||
|
hmp_handle_error(mon, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_VNC
|
||||||
|
static void hmp_change_read_arg(void *opaque, const char *password,
|
||||||
|
void *readline_opaque)
|
||||||
|
{
|
||||||
|
qmp_change_vnc_password(password, NULL);
|
||||||
|
monitor_read_command(opaque, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hmp_change_vnc(Monitor *mon, const char *device, const char *target,
|
||||||
|
const char *arg, const char *read_only, bool force,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
if (read_only) {
|
||||||
|
error_setg(errp, "Parameter 'read-only-mode' is invalid for VNC");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (strcmp(target, "passwd") && strcmp(target, "password")) {
|
||||||
|
error_setg(errp, "Expected 'password' after 'vnc'");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!arg) {
|
||||||
|
MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common);
|
||||||
|
monitor_read_password(hmp_mon, hmp_change_read_arg, NULL);
|
||||||
|
} else {
|
||||||
|
qmp_change_vnc_password(arg, errp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void hmp_sendkey(Monitor *mon, const QDict *qdict)
|
||||||
|
{
|
||||||
|
const char *keys = qdict_get_str(qdict, "keys");
|
||||||
|
KeyValue *v = NULL;
|
||||||
|
KeyValueList *head = NULL, **tail = &head;
|
||||||
|
int has_hold_time = qdict_haskey(qdict, "hold-time");
|
||||||
|
int hold_time = qdict_get_try_int(qdict, "hold-time", -1);
|
||||||
|
Error *err = NULL;
|
||||||
|
const char *separator;
|
||||||
|
int keyname_len;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
separator = qemu_strchrnul(keys, '-');
|
||||||
|
keyname_len = separator - keys;
|
||||||
|
|
||||||
|
/* Be compatible with old interface, convert user inputted "<" */
|
||||||
|
if (keys[0] == '<' && keyname_len == 1) {
|
||||||
|
keys = "less";
|
||||||
|
keyname_len = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
v = g_malloc0(sizeof(*v));
|
||||||
|
|
||||||
|
if (strstart(keys, "0x", NULL)) {
|
||||||
|
const char *endp;
|
||||||
|
int value;
|
||||||
|
|
||||||
|
if (qemu_strtoi(keys, &endp, 0, &value) < 0) {
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
assert(endp <= keys + keyname_len);
|
||||||
|
if (endp != keys + keyname_len) {
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
v->type = KEY_VALUE_KIND_NUMBER;
|
||||||
|
v->u.number.data = value;
|
||||||
|
} else {
|
||||||
|
int idx = index_from_key(keys, keyname_len);
|
||||||
|
if (idx == Q_KEY_CODE__MAX) {
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
v->type = KEY_VALUE_KIND_QCODE;
|
||||||
|
v->u.qcode.data = idx;
|
||||||
|
}
|
||||||
|
QAPI_LIST_APPEND(tail, v);
|
||||||
|
v = NULL;
|
||||||
|
|
||||||
|
if (!*separator) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
keys = separator + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
qmp_send_key(head, has_hold_time, hold_time, &err);
|
||||||
|
hmp_handle_error(mon, err);
|
||||||
|
|
||||||
|
out:
|
||||||
|
qapi_free_KeyValue(v);
|
||||||
|
qapi_free_KeyValueList(head);
|
||||||
|
return;
|
||||||
|
|
||||||
|
err_out:
|
||||||
|
monitor_printf(mon, "invalid parameter: %.*s\n", keyname_len, keys);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendkey_completion(ReadLineState *rs, int nb_args, const char *str)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *sep;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (nb_args != 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sep = strrchr(str, '-');
|
||||||
|
if (sep) {
|
||||||
|
str = sep + 1;
|
||||||
|
}
|
||||||
|
len = strlen(str);
|
||||||
|
readline_set_completion_index(rs, len);
|
||||||
|
for (i = 0; i < Q_KEY_CODE__MAX; i++) {
|
||||||
|
if (!strncmp(str, QKeyCode_str(i), len)) {
|
||||||
|
readline_add_completion(rs, QKeyCode_str(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void coroutine_fn
|
||||||
|
hmp_screendump(Monitor *mon, const QDict *qdict)
|
||||||
|
{
|
||||||
|
const char *filename = qdict_get_str(qdict, "filename");
|
||||||
|
const char *id = qdict_get_try_str(qdict, "device");
|
||||||
|
int64_t head = qdict_get_try_int(qdict, "head", 0);
|
||||||
|
const char *input_format = qdict_get_try_str(qdict, "format");
|
||||||
|
Error *err = NULL;
|
||||||
|
ImageFormat format;
|
||||||
|
|
||||||
|
format = qapi_enum_parse(&ImageFormat_lookup, input_format,
|
||||||
|
IMAGE_FORMAT_PPM, &err);
|
||||||
|
if (err) {
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
qmp_screendump(filename, id, id != NULL, head,
|
||||||
|
input_format != NULL, format, &err);
|
||||||
|
end:
|
||||||
|
hmp_handle_error(mon, err);
|
||||||
|
}
|
177
ui/ui-qmp-cmds.c
Normal file
177
ui/ui-qmp-cmds.c
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
/*
|
||||||
|
* QMP commands related to UI
|
||||||
|
*
|
||||||
|
* Copyright IBM, Corp. 2011
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Anthony Liguori <aliguori@us.ibm.com>
|
||||||
|
*
|
||||||
|
* This work is licensed under the terms of the GNU GPL, version 2. See
|
||||||
|
* the COPYING file in the top-level directory.
|
||||||
|
*
|
||||||
|
* Contributions after 2012-01-13 are licensed under the terms of the
|
||||||
|
* GNU GPL, version 2 or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qemu/osdep.h"
|
||||||
|
#include "monitor/qmp-helpers.h"
|
||||||
|
#include "qapi/qapi-commands-ui.h"
|
||||||
|
#include "qapi/qmp/qerror.h"
|
||||||
|
#include "qemu/cutils.h"
|
||||||
|
#include "ui/console.h"
|
||||||
|
#include "ui/dbus-display.h"
|
||||||
|
#include "ui/qemu-spice.h"
|
||||||
|
|
||||||
|
void qmp_set_password(SetPasswordOptions *opts, Error **errp)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (opts->protocol == DISPLAY_PROTOCOL_SPICE) {
|
||||||
|
if (!qemu_using_spice(errp)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rc = qemu_spice.set_passwd(opts->password,
|
||||||
|
opts->connected == SET_PASSWORD_ACTION_FAIL,
|
||||||
|
opts->connected == SET_PASSWORD_ACTION_DISCONNECT);
|
||||||
|
} else {
|
||||||
|
assert(opts->protocol == DISPLAY_PROTOCOL_VNC);
|
||||||
|
if (opts->connected != SET_PASSWORD_ACTION_KEEP) {
|
||||||
|
/* vnc supports "connected=keep" only */
|
||||||
|
error_setg(errp, QERR_INVALID_PARAMETER, "connected");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Note that setting an empty password will not disable login
|
||||||
|
* through this interface.
|
||||||
|
*/
|
||||||
|
rc = vnc_display_password(opts->u.vnc.display, opts->password);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc != 0) {
|
||||||
|
error_setg(errp, "Could not set password");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void qmp_expire_password(ExpirePasswordOptions *opts, Error **errp)
|
||||||
|
{
|
||||||
|
time_t when;
|
||||||
|
int rc;
|
||||||
|
const char *whenstr = opts->time;
|
||||||
|
const char *numstr = NULL;
|
||||||
|
uint64_t num;
|
||||||
|
|
||||||
|
if (strcmp(whenstr, "now") == 0) {
|
||||||
|
when = 0;
|
||||||
|
} else if (strcmp(whenstr, "never") == 0) {
|
||||||
|
when = TIME_MAX;
|
||||||
|
} else if (whenstr[0] == '+') {
|
||||||
|
when = time(NULL);
|
||||||
|
numstr = whenstr + 1;
|
||||||
|
} else {
|
||||||
|
when = 0;
|
||||||
|
numstr = whenstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numstr) {
|
||||||
|
if (qemu_strtou64(numstr, NULL, 10, &num) < 0) {
|
||||||
|
error_setg(errp, "Parameter 'time' doesn't take value '%s'",
|
||||||
|
whenstr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
when += num;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts->protocol == DISPLAY_PROTOCOL_SPICE) {
|
||||||
|
if (!qemu_using_spice(errp)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rc = qemu_spice.set_pw_expire(when);
|
||||||
|
} else {
|
||||||
|
assert(opts->protocol == DISPLAY_PROTOCOL_VNC);
|
||||||
|
rc = vnc_display_pw_expire(opts->u.vnc.display, when);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc != 0) {
|
||||||
|
error_setg(errp, "Could not set password expire time");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_VNC
|
||||||
|
void qmp_change_vnc_password(const char *password, Error **errp)
|
||||||
|
{
|
||||||
|
if (vnc_display_password(NULL, password) < 0) {
|
||||||
|
error_setg(errp, "Could not set password");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool qmp_add_client_spice(int fd, bool has_skipauth, bool skipauth,
|
||||||
|
bool has_tls, bool tls, Error **errp)
|
||||||
|
{
|
||||||
|
if (!qemu_using_spice(errp)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
skipauth = has_skipauth ? skipauth : false;
|
||||||
|
tls = has_tls ? tls : false;
|
||||||
|
if (qemu_spice.display_add_client(fd, skipauth, tls) < 0) {
|
||||||
|
error_setg(errp, "spice failed to add client");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_VNC
|
||||||
|
bool qmp_add_client_vnc(int fd, bool has_skipauth, bool skipauth,
|
||||||
|
bool has_tls, bool tls, Error **errp)
|
||||||
|
{
|
||||||
|
skipauth = has_skipauth ? skipauth : false;
|
||||||
|
vnc_display_add_client(NULL, fd, skipauth);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_DBUS_DISPLAY
|
||||||
|
bool qmp_add_client_dbus_display(int fd, bool has_skipauth, bool skipauth,
|
||||||
|
bool has_tls, bool tls, Error **errp)
|
||||||
|
{
|
||||||
|
if (!qemu_using_dbus_display(errp)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!qemu_dbus_display.add_client(fd, errp)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void qmp_display_reload(DisplayReloadOptions *arg, Error **errp)
|
||||||
|
{
|
||||||
|
switch (arg->type) {
|
||||||
|
case DISPLAY_RELOAD_TYPE_VNC:
|
||||||
|
#ifdef CONFIG_VNC
|
||||||
|
if (arg->u.vnc.has_tls_certs && arg->u.vnc.tls_certs) {
|
||||||
|
vnc_display_reload_certs(NULL, errp);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
error_setg(errp, "vnc is invalid, missing 'CONFIG_VNC'");
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void qmp_display_update(DisplayUpdateOptions *arg, Error **errp)
|
||||||
|
{
|
||||||
|
switch (arg->type) {
|
||||||
|
case DISPLAY_UPDATE_TYPE_VNC:
|
||||||
|
#ifdef CONFIG_VNC
|
||||||
|
vnc_display_update(&arg->u.vnc, errp);
|
||||||
|
#else
|
||||||
|
error_setg(errp, "vnc is invalid, missing 'CONFIG_VNC'");
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
@ -87,9 +87,7 @@ static const char *cap_name[] = {
|
|||||||
[VD_AGENT_CAP_MONITORS_CONFIG_POSITION] = "monitors-config-position",
|
[VD_AGENT_CAP_MONITORS_CONFIG_POSITION] = "monitors-config-position",
|
||||||
[VD_AGENT_CAP_FILE_XFER_DISABLED] = "file-xfer-disabled",
|
[VD_AGENT_CAP_FILE_XFER_DISABLED] = "file-xfer-disabled",
|
||||||
[VD_AGENT_CAP_FILE_XFER_DETAILED_ERRORS] = "file-xfer-detailed-errors",
|
[VD_AGENT_CAP_FILE_XFER_DETAILED_ERRORS] = "file-xfer-detailed-errors",
|
||||||
#if CHECK_SPICE_PROTOCOL_VERSION(0, 14, 0)
|
|
||||||
[VD_AGENT_CAP_GRAPHICS_DEVICE_INFO] = "graphics-device-info",
|
[VD_AGENT_CAP_GRAPHICS_DEVICE_INFO] = "graphics-device-info",
|
||||||
#endif
|
|
||||||
#if CHECK_SPICE_PROTOCOL_VERSION(0, 14, 1)
|
#if CHECK_SPICE_PROTOCOL_VERSION(0, 14, 1)
|
||||||
[VD_AGENT_CAP_CLIPBOARD_NO_RELEASE_ON_REGRAB] = "clipboard-no-release-on-regrab",
|
[VD_AGENT_CAP_CLIPBOARD_NO_RELEASE_ON_REGRAB] = "clipboard-no-release-on-regrab",
|
||||||
[VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL] = "clipboard-grab-serial",
|
[VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL] = "clipboard-grab-serial",
|
||||||
@ -112,9 +110,7 @@ static const char *msg_name[] = {
|
|||||||
[VD_AGENT_CLIENT_DISCONNECTED] = "client-disconnected",
|
[VD_AGENT_CLIENT_DISCONNECTED] = "client-disconnected",
|
||||||
[VD_AGENT_MAX_CLIPBOARD] = "max-clipboard",
|
[VD_AGENT_MAX_CLIPBOARD] = "max-clipboard",
|
||||||
[VD_AGENT_AUDIO_VOLUME_SYNC] = "audio-volume-sync",
|
[VD_AGENT_AUDIO_VOLUME_SYNC] = "audio-volume-sync",
|
||||||
#if CHECK_SPICE_PROTOCOL_VERSION(0, 14, 0)
|
|
||||||
[VD_AGENT_GRAPHICS_DEVICE_INFO] = "graphics-device-info",
|
[VD_AGENT_GRAPHICS_DEVICE_INFO] = "graphics-device-info",
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *sel_name[] = {
|
static const char *sel_name[] = {
|
||||||
|
Loading…
Reference in New Issue
Block a user