input monitor patches: fix send-key release ordering
and new input-send-event command -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJULQiEAAoJEEy22O7T6HE4WLQQAKCdMIwxO07onZhv/6UkOJpM Hr04tmMpurGdZfi6nzKzwqKBmvnYV5CN9WmebVkox200o38vbG+QQ0utd/ezdTxS BcbiOnZReEBKHHQCdKsOiYX42F0oVoVMYEdFGzf2oNXf7Jf0n4xFBtjb2umCP0Qy qXNMQtFg+LIgHUO4o/WZvidHdRSobOfuFANGbwNGGx/CXtFWX0GJV+4EM4tzq/qw tAvk3vGIDhP26/BxWnjWqe5B3OZKdO4El4UM+dXUR+o8tEvSzMcL+6LSqP/ZB2Ku xMoKaIpd0wklXjZEJ/DIuaQ42iScwqU6KUaIDIDKKdpJWlDoC16LgpdrhVlH0ATP /NmFsgG1K8iRbHSu2yol4qx7MO0LW2sMSdk2sDMdH0aR5y2ZXMQnJd5D2CIV/Dws nGLNrG/O3OMptmbaceuRpgC+syYU3oEDy5TsGHmDwSE0mQXqH5CKbRgFaMUU1RmN b0MN5t49TS2KRPDkc/OEqUzKQvk+aUo48Bq+Nkwq1YMlXtakfqHM57B9HDmozg+L 1KGnGcSBrpDolRUKe1uYhwRI0asd6kBgGm6C/0WZM64bUvW42VYejPdXpwkB1tri PWcSpVKA49GPdpWuysrvCZMrIYst2+Mx0SK/MLc0MZsUPb1gBk8j0xELxbxe+Bqf KOuTbcFxAOizSAJGI4J8 =KkIF -----END PGP SIGNATURE----- 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: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
b00a0ddb31
@ -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
|
||||
#
|
||||
|
@ -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
|
||||
|
@ -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
ui/input.c
37
ui/input.c
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user