xref: /openbmc/qemu/ui/ui-hmp-cmds.c (revision 462ad017ed76889d46696a3581e1b52343f9b683)
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