15011d262SMarkus Armbruster /*
25011d262SMarkus Armbruster * HMP commands related to UI
35011d262SMarkus Armbruster *
45011d262SMarkus Armbruster * Copyright IBM, Corp. 2011
55011d262SMarkus Armbruster *
65011d262SMarkus Armbruster * Authors:
75011d262SMarkus Armbruster * Anthony Liguori <aliguori@us.ibm.com>
85011d262SMarkus Armbruster *
95011d262SMarkus Armbruster * This work is licensed under the terms of the GNU GPL, version 2. See
105011d262SMarkus Armbruster * the COPYING file in the top-level directory.
115011d262SMarkus Armbruster *
125011d262SMarkus Armbruster * Contributions after 2012-01-13 are licensed under the terms of the
135011d262SMarkus Armbruster * GNU GPL, version 2 or (at your option) any later version.
145011d262SMarkus Armbruster */
155011d262SMarkus Armbruster
165011d262SMarkus Armbruster #include "qemu/osdep.h"
175011d262SMarkus Armbruster #ifdef CONFIG_SPICE
185011d262SMarkus Armbruster #include <spice/enums.h>
195011d262SMarkus Armbruster #endif
205011d262SMarkus Armbruster #include "monitor/hmp.h"
21f916a175SMarkus Armbruster #include "monitor/monitor-internal.h"
22f916a175SMarkus Armbruster #include "qapi/error.h"
235011d262SMarkus Armbruster #include "qapi/qapi-commands-ui.h"
245011d262SMarkus Armbruster #include "qapi/qmp/qdict.h"
255011d262SMarkus Armbruster #include "qemu/cutils.h"
265011d262SMarkus Armbruster #include "ui/console.h"
275011d262SMarkus Armbruster #include "ui/input.h"
285011d262SMarkus Armbruster
295011d262SMarkus Armbruster static int mouse_button_state;
305011d262SMarkus Armbruster
hmp_mouse_move(Monitor * mon,const QDict * qdict)315011d262SMarkus Armbruster void hmp_mouse_move(Monitor *mon, const QDict *qdict)
325011d262SMarkus Armbruster {
335011d262SMarkus Armbruster int dx, dy, dz, button;
345011d262SMarkus Armbruster const char *dx_str = qdict_get_str(qdict, "dx_str");
355011d262SMarkus Armbruster const char *dy_str = qdict_get_str(qdict, "dy_str");
365011d262SMarkus Armbruster const char *dz_str = qdict_get_try_str(qdict, "dz_str");
375011d262SMarkus Armbruster
385011d262SMarkus Armbruster dx = strtol(dx_str, NULL, 0);
395011d262SMarkus Armbruster dy = strtol(dy_str, NULL, 0);
405011d262SMarkus Armbruster qemu_input_queue_rel(NULL, INPUT_AXIS_X, dx);
415011d262SMarkus Armbruster qemu_input_queue_rel(NULL, INPUT_AXIS_Y, dy);
425011d262SMarkus Armbruster
435011d262SMarkus Armbruster if (dz_str) {
445011d262SMarkus Armbruster dz = strtol(dz_str, NULL, 0);
455011d262SMarkus Armbruster if (dz != 0) {
465011d262SMarkus Armbruster button = (dz > 0) ? INPUT_BUTTON_WHEEL_UP : INPUT_BUTTON_WHEEL_DOWN;
475011d262SMarkus Armbruster qemu_input_queue_btn(NULL, button, true);
485011d262SMarkus Armbruster qemu_input_event_sync();
495011d262SMarkus Armbruster qemu_input_queue_btn(NULL, button, false);
505011d262SMarkus Armbruster }
515011d262SMarkus Armbruster }
525011d262SMarkus Armbruster qemu_input_event_sync();
535011d262SMarkus Armbruster }
545011d262SMarkus Armbruster
hmp_mouse_button(Monitor * mon,const QDict * qdict)555011d262SMarkus Armbruster void hmp_mouse_button(Monitor *mon, const QDict *qdict)
565011d262SMarkus Armbruster {
575011d262SMarkus Armbruster static uint32_t bmap[INPUT_BUTTON__MAX] = {
585011d262SMarkus Armbruster [INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON,
595011d262SMarkus Armbruster [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
605011d262SMarkus Armbruster [INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON,
615011d262SMarkus Armbruster };
625011d262SMarkus Armbruster int button_state = qdict_get_int(qdict, "button_state");
635011d262SMarkus Armbruster
645011d262SMarkus Armbruster if (mouse_button_state == button_state) {
655011d262SMarkus Armbruster return;
665011d262SMarkus Armbruster }
675011d262SMarkus Armbruster qemu_input_update_buttons(NULL, bmap, mouse_button_state, button_state);
685011d262SMarkus Armbruster qemu_input_event_sync();
695011d262SMarkus Armbruster mouse_button_state = button_state;
705011d262SMarkus Armbruster }
715011d262SMarkus Armbruster
hmp_mouse_set(Monitor * mon,const QDict * qdict)72ec843b97SMarkus Armbruster void hmp_mouse_set(Monitor *mon, const QDict *qdict)
73ec843b97SMarkus Armbruster {
74ec843b97SMarkus Armbruster Error *err = NULL;
75ec843b97SMarkus Armbruster
76ec843b97SMarkus Armbruster qemu_mouse_set(qdict_get_int(qdict, "index"), &err);
77ec843b97SMarkus Armbruster hmp_handle_error(mon, err);
78ec843b97SMarkus Armbruster }
79ec843b97SMarkus Armbruster
hmp_info_mice(Monitor * mon,const QDict * qdict)805011d262SMarkus Armbruster void hmp_info_mice(Monitor *mon, const QDict *qdict)
815011d262SMarkus Armbruster {
825011d262SMarkus Armbruster MouseInfoList *mice_list, *mouse;
835011d262SMarkus Armbruster
845011d262SMarkus Armbruster mice_list = qmp_query_mice(NULL);
855011d262SMarkus Armbruster if (!mice_list) {
865011d262SMarkus Armbruster monitor_printf(mon, "No mouse devices connected\n");
875011d262SMarkus Armbruster return;
885011d262SMarkus Armbruster }
895011d262SMarkus Armbruster
905011d262SMarkus Armbruster for (mouse = mice_list; mouse; mouse = mouse->next) {
915011d262SMarkus Armbruster monitor_printf(mon, "%c Mouse #%" PRId64 ": %s%s\n",
925011d262SMarkus Armbruster mouse->value->current ? '*' : ' ',
935011d262SMarkus Armbruster mouse->value->index, mouse->value->name,
945011d262SMarkus Armbruster mouse->value->absolute ? " (absolute)" : "");
955011d262SMarkus Armbruster }
965011d262SMarkus Armbruster
975011d262SMarkus Armbruster qapi_free_MouseInfoList(mice_list);
985011d262SMarkus Armbruster }
995011d262SMarkus Armbruster
1005011d262SMarkus Armbruster #ifdef CONFIG_VNC
1015011d262SMarkus Armbruster /* Helper for hmp_info_vnc_clients, _servers */
hmp_info_VncBasicInfo(Monitor * mon,VncBasicInfo * info,const char * name)1025011d262SMarkus Armbruster static void hmp_info_VncBasicInfo(Monitor *mon, VncBasicInfo *info,
1035011d262SMarkus Armbruster const char *name)
1045011d262SMarkus Armbruster {
1055011d262SMarkus Armbruster monitor_printf(mon, " %s: %s:%s (%s%s)\n",
1065011d262SMarkus Armbruster name,
1075011d262SMarkus Armbruster info->host,
1085011d262SMarkus Armbruster info->service,
1095011d262SMarkus Armbruster NetworkAddressFamily_str(info->family),
1105011d262SMarkus Armbruster info->websocket ? " (Websocket)" : "");
1115011d262SMarkus Armbruster }
1125011d262SMarkus Armbruster
1135011d262SMarkus Armbruster /* Helper displaying and auth and crypt info */
hmp_info_vnc_authcrypt(Monitor * mon,const char * indent,VncPrimaryAuth auth,VncVencryptSubAuth * vencrypt)1145011d262SMarkus Armbruster static void hmp_info_vnc_authcrypt(Monitor *mon, const char *indent,
1155011d262SMarkus Armbruster VncPrimaryAuth auth,
1165011d262SMarkus Armbruster VncVencryptSubAuth *vencrypt)
1175011d262SMarkus Armbruster {
1185011d262SMarkus Armbruster monitor_printf(mon, "%sAuth: %s (Sub: %s)\n", indent,
1195011d262SMarkus Armbruster VncPrimaryAuth_str(auth),
1205011d262SMarkus Armbruster vencrypt ? VncVencryptSubAuth_str(*vencrypt) : "none");
1215011d262SMarkus Armbruster }
1225011d262SMarkus Armbruster
hmp_info_vnc_clients(Monitor * mon,VncClientInfoList * client)1235011d262SMarkus Armbruster static void hmp_info_vnc_clients(Monitor *mon, VncClientInfoList *client)
1245011d262SMarkus Armbruster {
1255011d262SMarkus Armbruster while (client) {
1265011d262SMarkus Armbruster VncClientInfo *cinfo = client->value;
1275011d262SMarkus Armbruster
1285011d262SMarkus Armbruster hmp_info_VncBasicInfo(mon, qapi_VncClientInfo_base(cinfo), "Client");
1295011d262SMarkus Armbruster monitor_printf(mon, " x509_dname: %s\n",
1305011d262SMarkus Armbruster cinfo->x509_dname ?: "none");
1315011d262SMarkus Armbruster monitor_printf(mon, " sasl_username: %s\n",
1325011d262SMarkus Armbruster cinfo->sasl_username ?: "none");
1335011d262SMarkus Armbruster
1345011d262SMarkus Armbruster client = client->next;
1355011d262SMarkus Armbruster }
1365011d262SMarkus Armbruster }
1375011d262SMarkus Armbruster
hmp_info_vnc_servers(Monitor * mon,VncServerInfo2List * server)1385011d262SMarkus Armbruster static void hmp_info_vnc_servers(Monitor *mon, VncServerInfo2List *server)
1395011d262SMarkus Armbruster {
1405011d262SMarkus Armbruster while (server) {
1415011d262SMarkus Armbruster VncServerInfo2 *sinfo = server->value;
1425011d262SMarkus Armbruster hmp_info_VncBasicInfo(mon, qapi_VncServerInfo2_base(sinfo), "Server");
1435011d262SMarkus Armbruster hmp_info_vnc_authcrypt(mon, " ", sinfo->auth,
1445011d262SMarkus Armbruster sinfo->has_vencrypt ? &sinfo->vencrypt : NULL);
1455011d262SMarkus Armbruster server = server->next;
1465011d262SMarkus Armbruster }
1475011d262SMarkus Armbruster }
1485011d262SMarkus Armbruster
hmp_info_vnc(Monitor * mon,const QDict * qdict)1495011d262SMarkus Armbruster void hmp_info_vnc(Monitor *mon, const QDict *qdict)
1505011d262SMarkus Armbruster {
1515011d262SMarkus Armbruster VncInfo2List *info2l, *info2l_head;
1525011d262SMarkus Armbruster Error *err = NULL;
1535011d262SMarkus Armbruster
1545011d262SMarkus Armbruster info2l = qmp_query_vnc_servers(&err);
1555011d262SMarkus Armbruster info2l_head = info2l;
1565011d262SMarkus Armbruster if (hmp_handle_error(mon, err)) {
1575011d262SMarkus Armbruster return;
1585011d262SMarkus Armbruster }
1595011d262SMarkus Armbruster if (!info2l) {
1605011d262SMarkus Armbruster monitor_printf(mon, "None\n");
1615011d262SMarkus Armbruster return;
1625011d262SMarkus Armbruster }
1635011d262SMarkus Armbruster
1645011d262SMarkus Armbruster while (info2l) {
1655011d262SMarkus Armbruster VncInfo2 *info = info2l->value;
1665011d262SMarkus Armbruster monitor_printf(mon, "%s:\n", info->id);
1675011d262SMarkus Armbruster hmp_info_vnc_servers(mon, info->server);
1685011d262SMarkus Armbruster hmp_info_vnc_clients(mon, info->clients);
1695011d262SMarkus Armbruster if (!info->server) {
1705011d262SMarkus Armbruster /*
1715011d262SMarkus Armbruster * The server entry displays its auth, we only need to
1725011d262SMarkus Armbruster * display in the case of 'reverse' connections where
1735011d262SMarkus Armbruster * there's no server.
1745011d262SMarkus Armbruster */
1755011d262SMarkus Armbruster hmp_info_vnc_authcrypt(mon, " ", info->auth,
1765011d262SMarkus Armbruster info->has_vencrypt ? &info->vencrypt : NULL);
1775011d262SMarkus Armbruster }
1785011d262SMarkus Armbruster if (info->display) {
1795011d262SMarkus Armbruster monitor_printf(mon, " Display: %s\n", info->display);
1805011d262SMarkus Armbruster }
1815011d262SMarkus Armbruster info2l = info2l->next;
1825011d262SMarkus Armbruster }
1835011d262SMarkus Armbruster
1845011d262SMarkus Armbruster qapi_free_VncInfo2List(info2l_head);
1855011d262SMarkus Armbruster
1865011d262SMarkus Armbruster }
1875011d262SMarkus Armbruster #endif
1885011d262SMarkus Armbruster
1895011d262SMarkus Armbruster #ifdef CONFIG_SPICE
hmp_info_spice(Monitor * mon,const QDict * qdict)1905011d262SMarkus Armbruster void hmp_info_spice(Monitor *mon, const QDict *qdict)
1915011d262SMarkus Armbruster {
1925011d262SMarkus Armbruster SpiceChannelList *chan;
1935011d262SMarkus Armbruster SpiceInfo *info;
1945011d262SMarkus Armbruster const char *channel_name;
1955011d262SMarkus Armbruster static const char *const channel_names[] = {
1965011d262SMarkus Armbruster [SPICE_CHANNEL_MAIN] = "main",
1975011d262SMarkus Armbruster [SPICE_CHANNEL_DISPLAY] = "display",
1985011d262SMarkus Armbruster [SPICE_CHANNEL_INPUTS] = "inputs",
1995011d262SMarkus Armbruster [SPICE_CHANNEL_CURSOR] = "cursor",
2005011d262SMarkus Armbruster [SPICE_CHANNEL_PLAYBACK] = "playback",
2015011d262SMarkus Armbruster [SPICE_CHANNEL_RECORD] = "record",
2025011d262SMarkus Armbruster [SPICE_CHANNEL_TUNNEL] = "tunnel",
2035011d262SMarkus Armbruster [SPICE_CHANNEL_SMARTCARD] = "smartcard",
2045011d262SMarkus Armbruster [SPICE_CHANNEL_USBREDIR] = "usbredir",
2055011d262SMarkus Armbruster [SPICE_CHANNEL_PORT] = "port",
2065011d262SMarkus Armbruster [SPICE_CHANNEL_WEBDAV] = "webdav",
2075011d262SMarkus Armbruster };
2085011d262SMarkus Armbruster
2095011d262SMarkus Armbruster info = qmp_query_spice(NULL);
2105011d262SMarkus Armbruster
2115011d262SMarkus Armbruster if (!info->enabled) {
2125011d262SMarkus Armbruster monitor_printf(mon, "Server: disabled\n");
2135011d262SMarkus Armbruster goto out;
2145011d262SMarkus Armbruster }
2155011d262SMarkus Armbruster
2165011d262SMarkus Armbruster monitor_printf(mon, "Server:\n");
2175011d262SMarkus Armbruster if (info->has_port) {
2185011d262SMarkus Armbruster monitor_printf(mon, " address: %s:%" PRId64 "\n",
2195011d262SMarkus Armbruster info->host, info->port);
2205011d262SMarkus Armbruster }
2215011d262SMarkus Armbruster if (info->has_tls_port) {
2225011d262SMarkus Armbruster monitor_printf(mon, " address: %s:%" PRId64 " [tls]\n",
2235011d262SMarkus Armbruster info->host, info->tls_port);
2245011d262SMarkus Armbruster }
2255011d262SMarkus Armbruster monitor_printf(mon, " migrated: %s\n",
2265011d262SMarkus Armbruster info->migrated ? "true" : "false");
2275011d262SMarkus Armbruster monitor_printf(mon, " auth: %s\n", info->auth);
2285011d262SMarkus Armbruster monitor_printf(mon, " compiled: %s\n", info->compiled_version);
2295011d262SMarkus Armbruster monitor_printf(mon, " mouse-mode: %s\n",
2305011d262SMarkus Armbruster SpiceQueryMouseMode_str(info->mouse_mode));
2315011d262SMarkus Armbruster
2325011d262SMarkus Armbruster if (!info->has_channels || info->channels == NULL) {
2335011d262SMarkus Armbruster monitor_printf(mon, "Channels: none\n");
2345011d262SMarkus Armbruster } else {
2355011d262SMarkus Armbruster for (chan = info->channels; chan; chan = chan->next) {
2365011d262SMarkus Armbruster monitor_printf(mon, "Channel:\n");
2375011d262SMarkus Armbruster monitor_printf(mon, " address: %s:%s%s\n",
2385011d262SMarkus Armbruster chan->value->host, chan->value->port,
2395011d262SMarkus Armbruster chan->value->tls ? " [tls]" : "");
2405011d262SMarkus Armbruster monitor_printf(mon, " session: %" PRId64 "\n",
2415011d262SMarkus Armbruster chan->value->connection_id);
2425011d262SMarkus Armbruster monitor_printf(mon, " channel: %" PRId64 ":%" PRId64 "\n",
2435011d262SMarkus Armbruster chan->value->channel_type, chan->value->channel_id);
2445011d262SMarkus Armbruster
2455011d262SMarkus Armbruster channel_name = "unknown";
2465011d262SMarkus Armbruster if (chan->value->channel_type > 0 &&
2475011d262SMarkus Armbruster chan->value->channel_type < ARRAY_SIZE(channel_names) &&
2485011d262SMarkus Armbruster channel_names[chan->value->channel_type]) {
2495011d262SMarkus Armbruster channel_name = channel_names[chan->value->channel_type];
2505011d262SMarkus Armbruster }
2515011d262SMarkus Armbruster
2525011d262SMarkus Armbruster monitor_printf(mon, " channel name: %s\n", channel_name);
2535011d262SMarkus Armbruster }
2545011d262SMarkus Armbruster }
2555011d262SMarkus Armbruster
2565011d262SMarkus Armbruster out:
2575011d262SMarkus Armbruster qapi_free_SpiceInfo(info);
2585011d262SMarkus Armbruster }
2595011d262SMarkus Armbruster #endif
2605011d262SMarkus Armbruster
hmp_set_password(Monitor * mon,const QDict * qdict)2615011d262SMarkus Armbruster void hmp_set_password(Monitor *mon, const QDict *qdict)
2625011d262SMarkus Armbruster {
2635011d262SMarkus Armbruster const char *protocol = qdict_get_str(qdict, "protocol");
2645011d262SMarkus Armbruster const char *password = qdict_get_str(qdict, "password");
2655011d262SMarkus Armbruster const char *display = qdict_get_try_str(qdict, "display");
2665011d262SMarkus Armbruster const char *connected = qdict_get_try_str(qdict, "connected");
2675011d262SMarkus Armbruster Error *err = NULL;
2685011d262SMarkus Armbruster
2695011d262SMarkus Armbruster SetPasswordOptions opts = {
2705011d262SMarkus Armbruster .password = (char *)password,
2715011d262SMarkus Armbruster .has_connected = !!connected,
2725011d262SMarkus Armbruster };
2735011d262SMarkus Armbruster
2745011d262SMarkus Armbruster opts.connected = qapi_enum_parse(&SetPasswordAction_lookup, connected,
2755011d262SMarkus Armbruster SET_PASSWORD_ACTION_KEEP, &err);
2765011d262SMarkus Armbruster if (err) {
2775011d262SMarkus Armbruster goto out;
2785011d262SMarkus Armbruster }
2795011d262SMarkus Armbruster
2805011d262SMarkus Armbruster opts.protocol = qapi_enum_parse(&DisplayProtocol_lookup, protocol,
2815011d262SMarkus Armbruster DISPLAY_PROTOCOL_VNC, &err);
2825011d262SMarkus Armbruster if (err) {
2835011d262SMarkus Armbruster goto out;
2845011d262SMarkus Armbruster }
2855011d262SMarkus Armbruster
2865011d262SMarkus Armbruster if (opts.protocol == DISPLAY_PROTOCOL_VNC) {
2875011d262SMarkus Armbruster opts.u.vnc.display = (char *)display;
2885011d262SMarkus Armbruster }
2895011d262SMarkus Armbruster
2905011d262SMarkus Armbruster qmp_set_password(&opts, &err);
2915011d262SMarkus Armbruster
2925011d262SMarkus Armbruster out:
2935011d262SMarkus Armbruster hmp_handle_error(mon, err);
2945011d262SMarkus Armbruster }
2955011d262SMarkus Armbruster
hmp_expire_password(Monitor * mon,const QDict * qdict)2965011d262SMarkus Armbruster void hmp_expire_password(Monitor *mon, const QDict *qdict)
2975011d262SMarkus Armbruster {
2985011d262SMarkus Armbruster const char *protocol = qdict_get_str(qdict, "protocol");
2995011d262SMarkus Armbruster const char *whenstr = qdict_get_str(qdict, "time");
3005011d262SMarkus Armbruster const char *display = qdict_get_try_str(qdict, "display");
3015011d262SMarkus Armbruster Error *err = NULL;
3025011d262SMarkus Armbruster
3035011d262SMarkus Armbruster ExpirePasswordOptions opts = {
3045011d262SMarkus Armbruster .time = (char *)whenstr,
3055011d262SMarkus Armbruster };
3065011d262SMarkus Armbruster
3075011d262SMarkus Armbruster opts.protocol = qapi_enum_parse(&DisplayProtocol_lookup, protocol,
3085011d262SMarkus Armbruster DISPLAY_PROTOCOL_VNC, &err);
3095011d262SMarkus Armbruster if (err) {
3105011d262SMarkus Armbruster goto out;
3115011d262SMarkus Armbruster }
3125011d262SMarkus Armbruster
3135011d262SMarkus Armbruster if (opts.protocol == DISPLAY_PROTOCOL_VNC) {
3145011d262SMarkus Armbruster opts.u.vnc.display = (char *)display;
3155011d262SMarkus Armbruster }
3165011d262SMarkus Armbruster
3175011d262SMarkus Armbruster qmp_expire_password(&opts, &err);
3185011d262SMarkus Armbruster
3195011d262SMarkus Armbruster out:
3205011d262SMarkus Armbruster hmp_handle_error(mon, err);
3215011d262SMarkus Armbruster }
3225011d262SMarkus Armbruster
323f916a175SMarkus Armbruster #ifdef CONFIG_VNC
hmp_change_read_arg(void * opaque,const char * password,void * readline_opaque)324f916a175SMarkus Armbruster static void hmp_change_read_arg(void *opaque, const char *password,
325f916a175SMarkus Armbruster void *readline_opaque)
326f916a175SMarkus Armbruster {
327f916a175SMarkus Armbruster qmp_change_vnc_password(password, NULL);
328f916a175SMarkus Armbruster monitor_read_command(opaque, 1);
329f916a175SMarkus Armbruster }
330f916a175SMarkus Armbruster
hmp_change_vnc(Monitor * mon,const char * device,const char * target,const char * arg,const char * read_only,bool force,Error ** errp)331f916a175SMarkus Armbruster void hmp_change_vnc(Monitor *mon, const char *device, const char *target,
332f916a175SMarkus Armbruster const char *arg, const char *read_only, bool force,
333f916a175SMarkus Armbruster Error **errp)
334f916a175SMarkus Armbruster {
335f916a175SMarkus Armbruster if (read_only) {
336f916a175SMarkus Armbruster error_setg(errp, "Parameter 'read-only-mode' is invalid for VNC");
337f916a175SMarkus Armbruster return;
338f916a175SMarkus Armbruster }
339bcaf1fdeSMarkus Armbruster if (strcmp(target, "passwd") && strcmp(target, "password")) {
340bcaf1fdeSMarkus Armbruster error_setg(errp, "Expected 'password' after 'vnc'");
341bcaf1fdeSMarkus Armbruster return;
342bcaf1fdeSMarkus Armbruster }
343f916a175SMarkus Armbruster if (!arg) {
344f916a175SMarkus Armbruster MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common);
345f916a175SMarkus Armbruster monitor_read_password(hmp_mon, hmp_change_read_arg, NULL);
346f916a175SMarkus Armbruster } else {
347f916a175SMarkus Armbruster qmp_change_vnc_password(arg, errp);
348f916a175SMarkus Armbruster }
349f916a175SMarkus Armbruster }
350f916a175SMarkus Armbruster #endif
351f916a175SMarkus Armbruster
hmp_sendkey(Monitor * mon,const QDict * qdict)3525011d262SMarkus Armbruster void hmp_sendkey(Monitor *mon, const QDict *qdict)
3535011d262SMarkus Armbruster {
3545011d262SMarkus Armbruster const char *keys = qdict_get_str(qdict, "keys");
3555011d262SMarkus Armbruster KeyValue *v = NULL;
3565011d262SMarkus Armbruster KeyValueList *head = NULL, **tail = &head;
3575011d262SMarkus Armbruster int has_hold_time = qdict_haskey(qdict, "hold-time");
3585011d262SMarkus Armbruster int hold_time = qdict_get_try_int(qdict, "hold-time", -1);
3595011d262SMarkus Armbruster Error *err = NULL;
3605011d262SMarkus Armbruster const char *separator;
3615011d262SMarkus Armbruster int keyname_len;
3625011d262SMarkus Armbruster
3635011d262SMarkus Armbruster while (1) {
3645011d262SMarkus Armbruster separator = qemu_strchrnul(keys, '-');
3655011d262SMarkus Armbruster keyname_len = separator - keys;
3665011d262SMarkus Armbruster
3675011d262SMarkus Armbruster /* Be compatible with old interface, convert user inputted "<" */
3685011d262SMarkus Armbruster if (keys[0] == '<' && keyname_len == 1) {
3695011d262SMarkus Armbruster keys = "less";
3705011d262SMarkus Armbruster keyname_len = 4;
3715011d262SMarkus Armbruster }
3725011d262SMarkus Armbruster
3735011d262SMarkus Armbruster v = g_malloc0(sizeof(*v));
3745011d262SMarkus Armbruster
3755011d262SMarkus Armbruster if (strstart(keys, "0x", NULL)) {
3765011d262SMarkus Armbruster const char *endp;
3775011d262SMarkus Armbruster int value;
3785011d262SMarkus Armbruster
3795011d262SMarkus Armbruster if (qemu_strtoi(keys, &endp, 0, &value) < 0) {
3805011d262SMarkus Armbruster goto err_out;
3815011d262SMarkus Armbruster }
3825011d262SMarkus Armbruster assert(endp <= keys + keyname_len);
3835011d262SMarkus Armbruster if (endp != keys + keyname_len) {
3845011d262SMarkus Armbruster goto err_out;
3855011d262SMarkus Armbruster }
3865011d262SMarkus Armbruster v->type = KEY_VALUE_KIND_NUMBER;
3875011d262SMarkus Armbruster v->u.number.data = value;
3885011d262SMarkus Armbruster } else {
3895011d262SMarkus Armbruster int idx = index_from_key(keys, keyname_len);
3905011d262SMarkus Armbruster if (idx == Q_KEY_CODE__MAX) {
3915011d262SMarkus Armbruster goto err_out;
3925011d262SMarkus Armbruster }
3935011d262SMarkus Armbruster v->type = KEY_VALUE_KIND_QCODE;
3945011d262SMarkus Armbruster v->u.qcode.data = idx;
3955011d262SMarkus Armbruster }
3965011d262SMarkus Armbruster QAPI_LIST_APPEND(tail, v);
3975011d262SMarkus Armbruster v = NULL;
3985011d262SMarkus Armbruster
3995011d262SMarkus Armbruster if (!*separator) {
4005011d262SMarkus Armbruster break;
4015011d262SMarkus Armbruster }
4025011d262SMarkus Armbruster keys = separator + 1;
4035011d262SMarkus Armbruster }
4045011d262SMarkus Armbruster
4055011d262SMarkus Armbruster qmp_send_key(head, has_hold_time, hold_time, &err);
4065011d262SMarkus Armbruster hmp_handle_error(mon, err);
4075011d262SMarkus Armbruster
4085011d262SMarkus Armbruster out:
4095011d262SMarkus Armbruster qapi_free_KeyValue(v);
4105011d262SMarkus Armbruster qapi_free_KeyValueList(head);
4115011d262SMarkus Armbruster return;
4125011d262SMarkus Armbruster
4135011d262SMarkus Armbruster err_out:
4145011d262SMarkus Armbruster monitor_printf(mon, "invalid parameter: %.*s\n", keyname_len, keys);
4155011d262SMarkus Armbruster goto out;
4165011d262SMarkus Armbruster }
4175011d262SMarkus Armbruster
sendkey_completion(ReadLineState * rs,int nb_args,const char * str)4185011d262SMarkus Armbruster void sendkey_completion(ReadLineState *rs, int nb_args, const char *str)
4195011d262SMarkus Armbruster {
4205011d262SMarkus Armbruster int i;
4215011d262SMarkus Armbruster char *sep;
4225011d262SMarkus Armbruster size_t len;
4235011d262SMarkus Armbruster
4245011d262SMarkus Armbruster if (nb_args != 2) {
4255011d262SMarkus Armbruster return;
4265011d262SMarkus Armbruster }
4275011d262SMarkus Armbruster sep = strrchr(str, '-');
4285011d262SMarkus Armbruster if (sep) {
4295011d262SMarkus Armbruster str = sep + 1;
4305011d262SMarkus Armbruster }
4315011d262SMarkus Armbruster len = strlen(str);
4325011d262SMarkus Armbruster readline_set_completion_index(rs, len);
4335011d262SMarkus Armbruster for (i = 0; i < Q_KEY_CODE__MAX; i++) {
4345011d262SMarkus Armbruster if (!strncmp(str, QKeyCode_str(i), len)) {
4355011d262SMarkus Armbruster readline_add_completion(rs, QKeyCode_str(i));
4365011d262SMarkus Armbruster }
4375011d262SMarkus Armbruster }
4385011d262SMarkus Armbruster }
4395011d262SMarkus Armbruster
440*f38aa2c7SMarc-André Lureau #ifdef CONFIG_PIXMAN
4415011d262SMarkus Armbruster void coroutine_fn
hmp_screendump(Monitor * mon,const QDict * qdict)4425011d262SMarkus Armbruster hmp_screendump(Monitor *mon, const QDict *qdict)
4435011d262SMarkus Armbruster {
4445011d262SMarkus Armbruster const char *filename = qdict_get_str(qdict, "filename");
4455011d262SMarkus Armbruster const char *id = qdict_get_try_str(qdict, "device");
4465011d262SMarkus Armbruster int64_t head = qdict_get_try_int(qdict, "head", 0);
4475011d262SMarkus Armbruster const char *input_format = qdict_get_try_str(qdict, "format");
4485011d262SMarkus Armbruster Error *err = NULL;
4495011d262SMarkus Armbruster ImageFormat format;
4505011d262SMarkus Armbruster
4515011d262SMarkus Armbruster format = qapi_enum_parse(&ImageFormat_lookup, input_format,
4525011d262SMarkus Armbruster IMAGE_FORMAT_PPM, &err);
4535011d262SMarkus Armbruster if (err) {
4545011d262SMarkus Armbruster goto end;
4555011d262SMarkus Armbruster }
4565011d262SMarkus Armbruster
4575011d262SMarkus Armbruster qmp_screendump(filename, id, id != NULL, head,
4585011d262SMarkus Armbruster input_format != NULL, format, &err);
4595011d262SMarkus Armbruster end:
4605011d262SMarkus Armbruster hmp_handle_error(mon, err);
4615011d262SMarkus Armbruster }
462*f38aa2c7SMarc-André Lureau #endif
463f9e1ef74SJuan Quintela
hmp_client_migrate_info(Monitor * mon,const QDict * qdict)464f9e1ef74SJuan Quintela void hmp_client_migrate_info(Monitor *mon, const QDict *qdict)
465f9e1ef74SJuan Quintela {
466f9e1ef74SJuan Quintela Error *err = NULL;
467f9e1ef74SJuan Quintela const char *protocol = qdict_get_str(qdict, "protocol");
468f9e1ef74SJuan Quintela const char *hostname = qdict_get_str(qdict, "hostname");
469f9e1ef74SJuan Quintela bool has_port = qdict_haskey(qdict, "port");
470f9e1ef74SJuan Quintela int port = qdict_get_try_int(qdict, "port", -1);
471f9e1ef74SJuan Quintela bool has_tls_port = qdict_haskey(qdict, "tls-port");
472f9e1ef74SJuan Quintela int tls_port = qdict_get_try_int(qdict, "tls-port", -1);
473f9e1ef74SJuan Quintela const char *cert_subject = qdict_get_try_str(qdict, "cert-subject");
474f9e1ef74SJuan Quintela
475f9e1ef74SJuan Quintela qmp_client_migrate_info(protocol, hostname,
476f9e1ef74SJuan Quintela has_port, port, has_tls_port, tls_port,
477f9e1ef74SJuan Quintela cert_subject, &err);
478f9e1ef74SJuan Quintela hmp_handle_error(mon, err);
479f9e1ef74SJuan Quintela }
480