[libvirt] [PATCH 3/3 V3] qemu:send-key: Implement the driver methods

Daniel P. Berrange berrange at redhat.com
Fri Jun 24 13:21:43 UTC 2011


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 at 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 :|




More information about the libvir-list mailing list