unsigned int *keycodes,
unsigned int nkeycodes)
{
- /*
- * FIXME: qmp sendkey has not been implemented yet,
- * and qmp API of it cannot be anticipated, so we use hmp temporary.
- */
- return qemuMonitorTextSendKey(mon, holdtime, keycodes, nkeycodes);
+ int ret = -1;
+ virJSONValuePtr cmd = NULL;
+ virJSONValuePtr reply = NULL;
+ virJSONValuePtr keys = NULL;
+ virJSONValuePtr key = NULL;
+ unsigned int i;
+
+ /* create the key data array */
+ if (!(keys = virJSONValueNewArray()))
+ goto no_memory;
+
+ for (i = 0; i < nkeycodes; i++) {
+ if (keycodes[i] > 0xffff) {
+ virReportError(VIR_ERR_OPERATION_FAILED,
+ _("keycode %d is invalid: 0x%X"), i, keycodes[i]);
+ goto cleanup;
+ }
+
+ /* create single key object */
+ if (!(key = virJSONValueNewObject()))
+ goto no_memory;
+
+ /* Union KeyValue has two types, use the generic one */
+ if (virJSONValueObjectAppendString(key, "type", "number") < 0)
+ goto no_memory;
+
+ /* with the keycode */
+ if (virJSONValueObjectAppendNumberInt(key, "data", keycodes[i]) < 0)
+ goto no_memory;
+
+ if (virJSONValueArrayAppend(keys, key) < 0)
+ goto no_memory;
+
+ key = NULL;
+
+ }
+
+ cmd = qemuMonitorJSONMakeCommand("send-key",
+ "a:keys", keys,
+ holdtime ? "U:hold-time" : NULL, holdtime,
+ NULL);
+ if (!cmd)
+ goto cleanup;
+
+ if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0)
+ goto cleanup;
+
+ if (qemuMonitorJSONHasError(reply, "CommandNotFound")) {
+ VIR_DEBUG("send-key command not found, trying HMP");
+ ret = qemuMonitorTextSendKey(mon, holdtime, keycodes, nkeycodes);
+ } else {
+ ret = qemuMonitorJSONCheckError(cmd, reply);
+ }
+
+cleanup:
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+ virJSONValueFree(keys);
+ virJSONValueFree(key);
+ return ret;
+
+no_memory:
+ virReportOOMError();
+ goto cleanup;
}
int qemuMonitorJSONScreendump(qemuMonitorPtr mon,