On Fri, Jun 24, 2011 at 02:33:31PM +0800, Lai Jiangshan wrote:
qemu driver just accept xt_kbd codeset's keycode, so the lib
virtkey
is used for translating keycodes from other codesets.
Signed-off-by: Lai Jiangshan <laijs(a)cn.fujitsu.com>
---
src/qemu/qemu_driver.c | 51 ++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor.c | 37 ++++++++++++++++++++++++++++++
src/qemu/qemu_monitor.h | 6 +++++
src/qemu/qemu_monitor_json.c | 15 ++++++++++++
src/qemu/qemu_monitor_json.h | 5 ++++
src/qemu/qemu_monitor_text.c | 49 ++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor_text.h | 5 ++++
7 files changed, 168 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 01587e8..994d7bd 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1761,6 +1761,56 @@ cleanup:
return ret;
}
+static int qemuDomainSendKey(virDomainPtr domain,
+ unsigned int codeset,
+ unsigned int holdtime,
+ unsigned int *keycodes,
+ int nkeycodes,
+ unsigned int flags)
+{
+ struct qemud_driver *driver = domain->conn->privateData;
+ virDomainObjPtr vm = NULL;
+ int ret = -1;
+ qemuDomainObjPrivatePtr priv;
+
+ virCheckFlags(0, -1);
+
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, domain->uuid);
+ if (!vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(domain->uuid, uuidstr);
+ qemuReportError(VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"),
uuidstr);
+ goto cleanup;
+ }
+
+ priv = vm->privateData;
+
+ if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0)
+ goto cleanup;
+
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto cleanup;
+ }
+
+ qemuDomainObjEnterMonitorWithDriver(driver, vm);
+ ret = qemuMonitorSendKey(priv->mon, codeset, holdtime, keycodes, nkeycodes);
+ qemuDomainObjExitMonitorWithDriver(driver, vm);
+ if (qemuDomainObjEndJob(vm) == 0) {
+ vm = NULL;
+ goto cleanup;
+ }
+
+cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
+ qemuDriverUnlock(driver);
+ return ret;
+}
+
static int qemudDomainGetInfo(virDomainPtr dom,
virDomainInfoPtr info)
{
@@ -8436,6 +8486,7 @@ static virDriver qemuDriver = {
.domainMigratePerform3 = qemuDomainMigratePerform3, /* 0.9.2 */
.domainMigrateFinish3 = qemuDomainMigrateFinish3, /* 0.9.2 */
.domainMigrateConfirm3 = qemuDomainMigrateConfirm3, /* 0.9.2 */
+ .domainSendKey = qemuDomainSendKey, /* 0.9.3 */
.domainBlockPull = qemuDomainBlockPull, /* 0.9.3 */
.domainBlockPullAll = qemuDomainBlockPullAll, /* 0.9.3 */
.domainBlockPullAbort = qemuDomainBlockPullAbort, /* 0.9.3 */
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 89a3f64..e14703b 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -36,6 +36,7 @@
#include "memory.h"
#include "logging.h"
#include "files.h"
+#include "virtkey.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
@@ -2369,6 +2370,42 @@ int qemuMonitorInjectNMI(qemuMonitorPtr mon)
return ret;
}
+int qemuMonitorSendKey(qemuMonitorPtr mon,
+ unsigned int codeset,
+ unsigned int holdtime,
+ unsigned int *keycodes,
+ unsigned int nkeycodes)
Remove the 'codeset' here and require the caller to
always pass in XT keycodes, and have the caller do
the translation
+{
+ int ret;
+
+ VIR_DEBUG("mon=%p, codeset=%s(%u), holdtime=%u, nkeycodes=%u",
+ mon, virKeycodeSetName(codeset), codeset, holdtime, nkeycodes);
+
+ if (codeset != VIR_KEYCODE_SET_XT_KBD) {
+ int i;
+ int keycode;
+
+ for (i = 0; i < nkeycodes; i++) {
+ keycode = virTranslateKeyCode(codeset, VIR_KEYCODE_SET_XT_KBD,
+ keycodes[i]);
+ if (keycode < 0) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "can not translate "
+ "keycode %u of %s codeset to xt_kbd codeset "
+ "keycode", keycodes[i],
+ virKeycodeSetName(codeset));
+ return -1;
+ }
+ keycodes[i] = keycode;
+ }
+ }
I think this code should be in the qemuDomainSendKey(). We
like to keep the qemuMonitorXXX() methods to only contain
code that is directly related to using the QEMU monitor.
+
+ if (mon->json)
+ ret = qemuMonitorJSONSendKey(mon, holdtime, keycodes, nkeycodes);
+ else
+ ret = qemuMonitorTextSendKey(mon, holdtime, keycodes, nkeycodes);
+ return ret;
+}
+
int qemuMonitorScreendump(qemuMonitorPtr mon,
const char *file)
{
Regards,
Daniel
--
|:
http://berrange.com -o-
http://www.flickr.com/photos/dberrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|:
http://entangle-photo.org -o-
http://live.gnome.org/gtk-vnc :|