Commit b00a0ddb authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/kraxel/tags/pull-input-20141002-1' into staging



input monitor patches: fix send-key release ordering
and new input-send-event command

# gpg: Signature made Thu 02 Oct 2014 09:10:44 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/kraxel/tags/pull-input-20141002-1:
  add input-send-event command
  input: fix send-key monitor command release event ordering

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 53b98718 50c6617f
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -3232,6 +3232,23 @@
              'rel'     : 'InputMoveEvent',
              'abs'     : 'InputMoveEvent' } }

##
# @input-send-event
#
# Send input event(s) to guest.
#
# @console: Which console to send event(s) to.
#
# @events: List of InputEvent union.
#
# Returns: Nothing on success.
#
# Since: 2.2
#
##
{ 'command': 'input-send-event',
  'data': { 'console':'int', 'events': [ 'InputEvent' ] } }

##
# @NumaOptions
#
+63 −0
Original line number Diff line number Diff line
@@ -3788,4 +3788,67 @@ Example:

-> { "execute": "trace-event-set-state", "arguments": { "name": "qemu_memalign", "enable": "true" } }
<- { "return": {} }
EQMP

    {
        .name       = "input-send-event",
        .args_type  = "console:i,events:q",
        .mhandler.cmd_new = qmp_marshal_input_input_send_event,
    },

SQMP
@input-send-event
-----------------

Send input event to guest.

Arguments:

- "console": console index.
- "events": list of input events.

The consoles are visible in the qom tree, under
/backend/console[$index]. They have a device link and head property, so
it is possible to map which console belongs to which device and display.

Example (1):

Press left mouse button.

-> { "execute": "input-send-event",
    "arguments": { "console": 0,
                   "events": [ { "type": "btn",
                    "data" : { "down": true, "button": "Left" } } } }
<- { "return": {} }

-> { "execute": "input-send-event",
    "arguments": { "console": 0,
                   "events": [ { "type": "btn",
                    "data" : { "down": false, "button": "Left" } } } }
<- { "return": {} }

Example (2):

Press ctrl-alt-del.

-> { "execute": "input-send-event",
     "arguments": { "console": 0, "events": [
        { "type": "key", "data" : { "down": true,
          "key": {"type": "qcode", "data": "ctrl" } } },
        { "type": "key", "data" : { "down": true,
          "key": {"type": "qcode", "data": "alt" } } },
        { "type": "key", "data" : { "down": true,
          "key": {"type": "qcode", "data": "delete" } } } ] } }
<- { "return": {} }

Example (3):

Move mouse pointer to absolute coordinates (20000, 400).

-> { "execute": "input-send-event" ,
  "arguments": { "console": 0, "events": [
               { "type": "abs", "data" : { "axis": "X", "value" : 20000 } },
               { "type": "abs", "data" : { "axis": "Y", "value" : 400 } } ] } }
<- { "return": {} }

EQMP
+9 −2
Original line number Diff line number Diff line
@@ -85,6 +85,8 @@ void qmp_send_key(KeyValueList *keys, bool has_hold_time, int64_t hold_time,
                  Error **errp)
{
    KeyValueList *p;
    KeyValue **up = NULL;
    int count = 0;

    if (!has_hold_time) {
        hold_time = 0; /* use default */
@@ -93,11 +95,16 @@ void qmp_send_key(KeyValueList *keys, bool has_hold_time, int64_t hold_time,
    for (p = keys; p != NULL; p = p->next) {
        qemu_input_event_send_key(NULL, copy_key_value(p->value), true);
        qemu_input_event_send_key_delay(hold_time);
        up = g_realloc(up, sizeof(*up) * (count+1));
        up[count] = copy_key_value(p->value);
        count++;
    }
    for (p = keys; p != NULL; p = p->next) {
        qemu_input_event_send_key(NULL, copy_key_value(p->value), false);
    while (count) {
        count--;
        qemu_input_event_send_key(NULL, up[count], false);
        qemu_input_event_send_key_delay(hold_time);
    }
    g_free(up);
}

static void legacy_kbd_event(DeviceState *dev, QemuConsole *src,
+37 −0
Original line number Diff line number Diff line
@@ -122,6 +122,43 @@ qemu_input_find_handler(uint32_t mask, QemuConsole *con)
    return NULL;
}

void qmp_input_send_event(int64_t console, InputEventList *events,
                          Error **errp)
{
    InputEventList *e;
    QemuConsole *con;

    con = qemu_console_lookup_by_index(console);
    if (!con) {
        error_setg(errp, "console %" PRId64 " not found", console);
        return;
    }

    if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
        error_setg(errp, "VM not running");
        return;
    }

    for (e = events; e != NULL; e = e->next) {
        InputEvent *event = e->value;

        if (!qemu_input_find_handler(1 << event->kind, con)) {
            error_setg(errp, "Input handler not found for "
                             "event type %s",
                            InputEventKind_lookup[event->kind]);
            return;
        }
    }

    for (e = events; e != NULL; e = e->next) {
        InputEvent *event = e->value;

        qemu_input_event_send(con, event);
    }

    qemu_input_event_sync();
}

static void qemu_input_transform_abs_rotate(InputEvent *evt)
{
    switch (graphic_rotate) {