Which allows specification of absolute/relative, up/down and console parameters.
Suggested by Gerd Hoffman. --- qapi-schema.json | 18 ++++++++++++++++ qmp-commands.hx | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ ui/input.c | 31 ++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+) Index: qemu/qapi-schema.json =================================================================== --- qemu.orig/qapi-schema.json 2014-06-16 20:12:51.049064621 -0300 +++ qemu/qapi-schema.json 2014-06-16 20:13:42.886920723 -0300 @@ -4722,3 +4722,21 @@ 'btn' : 'InputBtnEvent', '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.1 +# +## +{ 'command': 'input-send-event', + 'data': { 'console':'int', 'events': [ 'InputEvent' ] } } + Index: qemu/qmp-commands.hx =================================================================== --- qemu.orig/qmp-commands.hx 2014-06-16 20:12:51.050064619 -0300 +++ qemu/qmp-commands.hx 2014-06-16 20:13:42.888920718 -0300 @@ -3572,3 +3572,62 @@ } } ] } 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 +its 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" } }, + { "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 Index: qemu/ui/input.c =================================================================== --- qemu.orig/ui/input.c 2014-06-16 20:12:51.051064616 -0300 +++ qemu/ui/input.c 2014-06-16 20:13:42.888920718 -0300 @@ -102,6 +102,37 @@ 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; + } + qemu_input_event_send(con, event); + } + qemu_input_event_sync(); +} + static void qemu_input_transform_abs_rotate(InputEvent *evt) { switch (graphic_rotate) {