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@xxxxxxxxxxxxxx> > --- > 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 :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list