[libvirt] [RFC PATCH 2/2] vbox: Implement virDomainSendKey

Ján Tomko jtomko at redhat.com
Tue Apr 7 10:27:43 UTC 2015


On Thu, Mar 19, 2015 at 05:43:57PM -0400, Dawid Zamirski wrote:
> Since the holdtime is not supported by VBOX SDK, it's being simulated
> by sleeping before sending the key-up codes. The key-up codes are
> auto-generated based on XT codeset rules (adding of 0x80 to key-down)
> which results in the same behavior as for QEMU implementation.
> ---
>  src/vbox/vbox_common.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++
>  src/vbox/vbox_common.h |   1 +
>  2 files changed, 108 insertions(+)
> 

Looks good to me, a few nits inline:

> diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
> index 0fb53aa..88bd226 100644
> --- a/src/vbox/vbox_common.c
> +++ b/src/vbox/vbox_common.c
> @@ -33,6 +33,7 @@
>  #include "virstring.h"
>  #include "virfile.h"
>  #include "virtime.h"
> +#include "virkeycode.h"
>  #include "snapshot_conf.h"
>  #include "vbox_snapshot_conf.h"
>  #include "fdstream.h"
> @@ -7668,6 +7669,111 @@ vboxDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags)
>      return ret;
>  }
>  
> +static int
> +vboxDomainSendKey(virDomainPtr dom,
> +                  unsigned int codeset,
> +                  unsigned int holdtime,
> +                  unsigned int *keycodes,
> +                  int nkeycodes,
> +                  unsigned int flags)
> +{
> +    int ret = -1;
> +    vboxGlobalData *data = dom->conn->privateData;
> +    IConsole *console = NULL;
> +    vboxIIDUnion iid;
> +    IMachine *machine = NULL;
> +    IKeyboard *keyboard = NULL;
> +    PRInt32 *keyDownCodes = NULL;
> +    PRInt32 *keyUpCodes = NULL;
> +    PRUint32 codesStored = 0;
> +    nsresult rc;
> +    size_t i;
> +    int keycode;
> +
> +    if (!data->vboxObj)
> +        return ret;
> +
> +    virCheckFlags(0, -1);
> +
> +    keyDownCodes = (PRInt32 *) keycodes;
> +
> +    if (VIR_ALLOC_N(keyUpCodes, nkeycodes) < 0)
> +        return ret;
> +
> +    /* translate keycodes to xt and generate keyup scancodes */
> +    for (i = 0; i < nkeycodes; i++) {
> +        if (codeset != VIR_KEYCODE_SET_XT) {
> +            keycode = virKeycodeValueTranslate(codeset, VIR_KEYCODE_SET_XT,
> +                                               keyDownCodes[i]);
> +            if (keycode < 0) {
> +                virReportError(VIR_ERR_INTERNAL_ERROR,
> +                               _("cannot translate keycode %u of %s codeset to"
> +                                 " xt keycode"),
> +                                 keyDownCodes[i],
> +                                 virKeycodeSetTypeToString(codeset));
> +                goto cleanup;
> +            }
> +            keyDownCodes[i] = keycode;
> +        }
> +
> +        keyUpCodes[i] = keyDownCodes[i] + 0x80;
> +    }
> +
> +    if (openSessionForMachine(data, dom->uuid, &iid, &machine, false) < 0)
> +        goto cleanup;
> +
> +    rc = gVBoxAPI.UISession.OpenExisting(data, &iid, machine);
> +
> +    if (NS_FAILED(rc))

Missing virReportError here, ...

> +        goto cleanup;
> +
> +    rc = gVBoxAPI.UISession.GetConsole(data->vboxSession, &console);
> +
> +    if (NS_FAILED(rc) || !console)

... here ...

> +        goto cleanup;
> +
> +    rc = gVBoxAPI.UIConsole.GetKeyboard(console, &keyboard);
> +
> +    if (NS_FAILED(rc))

... and here.

> +        goto cleanup;
> +
> +    rc = gVBoxAPI.UIKeyboard.PutScancodes(keyboard, nkeycodes, keyDownCodes,
> +                                          &codesStored);
> +
> +    if (NS_FAILED(rc)) {
> +        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
> +                       _("Unable to send keyboard scancodes"));
> +        goto cleanup;
> +    }
> +
> +    /* since VBOX does not support holdtime, simulate it by sleeping and
> +       then sending the release key scancodes */
> +    if (holdtime > 0) {
> +        usleep(holdtime * 1000);
> +    }

This fails syntax-check for me:
Curly brackets around single-line body:
src/vbox/vbox_common.c:7755-7757:
    if (holdtime > 0) {
        usleep(holdtime * 1000);
    }
maint.mk: incorrect formatting, see HACKING for rules
cfg.mk:1059: recipe for target 'bracket-spacing-check' failed

> +
> +    rc = gVBoxAPI.UIKeyboard.PutScancodes(keyboard, nkeycodes, keyUpCodes,
> +                                          &codesStored);
> +
> +    if (NS_FAILED(rc)) {
> +        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
> +                       _("Unable to send keyboard scan codes"));
> +        goto cleanup;
> +    }
> +
> +    ret = 0;
> +
> + cleanup:
> +    VIR_FREE(keyUpCodes);
> +    VBOX_RELEASE(keyboard);
> +    VBOX_RELEASE(console);
> +    gVBoxAPI.UISession.Close(data->vboxSession);
> +    VBOX_RELEASE(machine);
> +    vboxIIDUnalloc(&iid);
> +
> +    return ret;
> +}
> +
>  
>  /**
>   * Function Tables
> @@ -7742,6 +7848,7 @@ virHypervisorDriver vboxCommonDriver = {
>      .nodeGetFreePages = vboxNodeGetFreePages, /* 1.2.6 */
>      .nodeAllocPages = vboxNodeAllocPages, /* 1.2.9 */
>      .domainHasManagedSaveImage = vboxDomainHasManagedSaveImage, /* 1.2.13 */
> +    .domainSendKey = vboxDomainSendKey, /* 1.2.14 */

1.2.15 now

Jan
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20150407/8ac45f73/attachment-0001.sig>


More information about the libvir-list mailing list