Instead of always using HMP use the QMP send-key command introduced in qemu 1.3.
---
Notes:
Version 2:
- always try QMP instead of adding capability bit
src/qemu/qemu_monitor_json.c | 69 ++++++++++++++++++++++++++++++++++++++++----
1 file changed, 64 insertions(+), 5 deletions(-)
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 1bf8baf..759198b 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -3372,11 +3372,70 @@ int qemuMonitorJSONSendKey(qemuMonitorPtr mon,
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,
--
1.8.1.5