]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
qemu: Try to use QMP for send-key if supported
authorPeter Krempa <pkrempa@redhat.com>
Thu, 11 Apr 2013 12:33:43 +0000 (14:33 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Thu, 11 Apr 2013 14:42:30 +0000 (16:42 +0200)
Instead of always using HMP use the QMP send-key command introduced in qemu 1.3.

src/qemu/qemu_monitor_json.c

index 1bf8bafe633f66c83a6244b49a95ce59ffc777b1..0f548774dddd2a08d55665f23ddb4e29ba7b901c 100644 (file)
@@ -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,