[libvirt] [PATCHv2] qemu: Try to use QMP for send-key if supported

Peter Krempa pkrempa at redhat.com
Thu Apr 11 13:15:18 UTC 2013


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




More information about the libvir-list mailing list