qapi: fix input-send-event and promote to stable

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJW1VCoAAoJEEy22O7T6HE4GFUP/3xysMIGF61TzFHsIVuhTvmB
 GL9uqgnUwfGp7NgR1UdWXouMBz+B9bHSedSUIZ8kJ9BC8K2vneyVUT9lOsA8Mett
 U5o7f5+vc26SVhMoDolPmLaoTlBvQv3PZy09FCEBQgGkapgQbsn9ukUcBbsKwgkM
 cHrmrstNLtRc5EqbV86m9DbeTaQnZtmXJv6mqrq/O7S/6JScvEwk7mgoWH1D+UjB
 esUcqWXhmwjm9JB0H2tmPHYUCOCYfXy/pA750kzL2IkhCJBaOq2NTsWI+3I4xTCB
 O/rb42j6JIH3Jb+VS0EUCpwXA7vlr6XwsLphtmsOQRc07S4Mo0FUtWBWafx6/k9r
 n35vQ4tzoNj4kjMeRXFIgKeh1lSbJmTfQaQBuvAeMqtFjzyoRrjnLVN9ri1rZrOC
 nvLAu7mf2/mHY36K+W355HnSNXVqHNFP1fb7nT9samUfdJkwLihTRIHJKXO8XMDi
 p+IRZOng/M7gHV569ctoZjk0Ujl9pE+i4sMniOa3ocANcLF1PeE8WRxb5gQRyEfc
 37WbjnKkY47I2/eiSB/NjG1A5MDz2m+UJp9KX1CKj8t0AczRV+JMKZpr29Ra0mL2
 JGEn1I7w/aFj3cSibw95wXCqhCi9LOF5UPhM89G0r3SIKf6rcSioEHwBWOCACU+/
 thDkrs6/NnllmhJQ+ZBN
 =aPQc
 -----END PGP SIGNATURE-----

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

qapi: fix input-send-event and promote to stable

# gpg: Signature made Tue 01 Mar 2016 08:19:52 GMT 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-20160301-1:
  qapi: promote input-send-event to stable
  qapi: rename InputAxis values.
  qapi: rename input buttons
  qapi: switch x-input-send-event from console to device+head
  console: add & use qemu_console_lookup_by_device_name

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2016-03-01 11:15:00 +00:00
commit 0b85d73583
17 changed files with 104 additions and 99 deletions

View File

@ -140,9 +140,9 @@ static void hid_pointer_event(DeviceState *dev, QemuConsole *src,
case INPUT_EVENT_KIND_BTN: case INPUT_EVENT_KIND_BTN:
if (evt->u.btn->down) { if (evt->u.btn->down) {
e->buttons_state |= bmap[evt->u.btn->button]; e->buttons_state |= bmap[evt->u.btn->button];
if (evt->u.btn->button == INPUT_BUTTON_WHEELUP) { if (evt->u.btn->button == INPUT_BUTTON_WHEEL_UP) {
e->dz--; e->dz--;
} else if (evt->u.btn->button == INPUT_BUTTON_WHEELDOWN) { } else if (evt->u.btn->button == INPUT_BUTTON_WHEEL_DOWN) {
e->dz++; e->dz++;
} }
} else { } else {

View File

@ -406,9 +406,9 @@ static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
case INPUT_EVENT_KIND_BTN: case INPUT_EVENT_KIND_BTN:
if (evt->u.btn->down) { if (evt->u.btn->down) {
s->mouse_buttons |= bmap[evt->u.btn->button]; s->mouse_buttons |= bmap[evt->u.btn->button];
if (evt->u.btn->button == INPUT_BUTTON_WHEELUP) { if (evt->u.btn->button == INPUT_BUTTON_WHEEL_UP) {
s->mouse_dz--; s->mouse_dz--;
} else if (evt->u.btn->button == INPUT_BUTTON_WHEELDOWN) { } else if (evt->u.btn->button == INPUT_BUTTON_WHEEL_DOWN) {
s->mouse_dz++; s->mouse_dz++;
} }
} else { } else {

View File

@ -143,8 +143,8 @@ static const unsigned int keymap_button[INPUT_BUTTON__MAX] = {
[INPUT_BUTTON_LEFT] = BTN_LEFT, [INPUT_BUTTON_LEFT] = BTN_LEFT,
[INPUT_BUTTON_RIGHT] = BTN_RIGHT, [INPUT_BUTTON_RIGHT] = BTN_RIGHT,
[INPUT_BUTTON_MIDDLE] = BTN_MIDDLE, [INPUT_BUTTON_MIDDLE] = BTN_MIDDLE,
[INPUT_BUTTON_WHEELUP] = BTN_GEAR_UP, [INPUT_BUTTON_WHEEL_UP] = BTN_GEAR_UP,
[INPUT_BUTTON_WHEELDOWN] = BTN_GEAR_DOWN, [INPUT_BUTTON_WHEEL_DOWN] = BTN_GEAR_DOWN,
}; };
static const unsigned int axismap_rel[INPUT_AXIS__MAX] = { static const unsigned int axismap_rel[INPUT_AXIS__MAX] = {

View File

@ -378,6 +378,8 @@ void graphic_hw_gl_block(QemuConsole *con, bool block);
QemuConsole *qemu_console_lookup_by_index(unsigned int index); QemuConsole *qemu_console_lookup_by_index(unsigned int index);
QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head); QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head);
QemuConsole *qemu_console_lookup_by_device_name(const char *device_id,
uint32_t head, Error **errp);
bool qemu_console_is_visible(QemuConsole *con); bool qemu_console_is_visible(QemuConsole *con);
bool qemu_console_is_graphic(QemuConsole *con); bool qemu_console_is_graphic(QemuConsole *con);
bool qemu_console_is_fixedsize(QemuConsole *con); bool qemu_console_is_fixedsize(QemuConsole *con);

View File

@ -1375,7 +1375,7 @@ static void hmp_mouse_move(Monitor *mon, const QDict *qdict)
if (dz_str) { if (dz_str) {
dz = strtol(dz_str, NULL, 0); dz = strtol(dz_str, NULL, 0);
if (dz != 0) { if (dz != 0) {
button = (dz > 0) ? INPUT_BUTTON_WHEELUP : INPUT_BUTTON_WHEELDOWN; button = (dz > 0) ? INPUT_BUTTON_WHEEL_UP : INPUT_BUTTON_WHEEL_DOWN;
qemu_input_queue_btn(NULL, button, true); qemu_input_queue_btn(NULL, button, true);
qemu_input_event_sync(); qemu_input_event_sync();
qemu_input_queue_btn(NULL, button, false); qemu_input_queue_btn(NULL, button, false);

View File

@ -3743,12 +3743,9 @@
# Button of a pointer input device (mouse, tablet). # Button of a pointer input device (mouse, tablet).
# #
# Since: 2.0 # Since: 2.0
#
# Note that the spelling of these values may change when the
# x-input-send-event is promoted out of experimental status.
## ##
{ 'enum' : 'InputButton', { 'enum' : 'InputButton',
'data' : [ 'Left', 'Middle', 'Right', 'WheelUp', 'WheelDown' ] } 'data' : [ 'left', 'middle', 'right', 'wheel-up', 'wheel-down' ] }
## ##
# @InputAxis # @InputAxis
@ -3756,12 +3753,9 @@
# Position axis of a pointer input device (mouse, tablet). # Position axis of a pointer input device (mouse, tablet).
# #
# Since: 2.0 # Since: 2.0
#
# Note that the spelling of these values may change when the
# x-input-send-event is promoted out of experimental status.
## ##
{ 'enum' : 'InputAxis', { 'enum' : 'InputAxis',
'data' : [ 'X', 'Y' ] } 'data' : [ 'x', 'y' ] }
## ##
# @InputKeyEvent # @InputKeyEvent
@ -3825,38 +3819,34 @@
'abs' : 'InputMoveEvent' } } 'abs' : 'InputMoveEvent' } }
## ##
# @x-input-send-event # @input-send-event
# #
# Send input event(s) to guest. # Send input event(s) to guest.
# #
# @console: #optional console to send event(s) to. # @device: #optional display device to send event(s) to.
# This parameter can be used to send the input event to # @head: #optional head to send event(s) to, in case the
# specific input devices in case (a) multiple input devices # display device supports multiple scanouts.
# of the same kind are added to the virtual machine and (b)
# you have configured input routing (see docs/multiseat.txt)
# for those input devices. If input routing is not
# configured this parameter has no effect.
# If @console is missing, only devices that aren't associated
# with a console are admissible.
# If @console is specified, it must exist, and both devices
# associated with that console and devices not associated with a
# console are admissible, but the former take precedence.
#
# @events: List of InputEvent union. # @events: List of InputEvent union.
# #
# Returns: Nothing on success. # Returns: Nothing on success.
# #
# Since: 2.2 # The @display and @head parameters can be used to send the input
# # event to specific input devices in case (a) multiple input devices
# Note: this command is experimental, and not a stable API. Things that # of the same kind are added to the virtual machine and (b) you have
# might change before it becomes stable include the spelling of enum # configured input routing (see docs/multiseat.txt) for those input
# values for InputButton and InputAxis, and the notion of how to designate # devices. The parameters work exactly like the device and head
# which console will receive the event. # properties of input devices. If @device is missing, only devices
# that have no input routing config are admissible. If @device is
# specified, both input devices with and without input routing config
# are admissible, but devices with input routing config take
# precedence.
# #
# Since: 2.6
## ##
{ 'command': 'x-input-send-event', { 'command': 'input-send-event',
'data': { '*console':'int', 'events': [ 'InputEvent' ] } } 'data': { '*device': 'str',
'*head' : 'int',
'events' : [ 'InputEvent' ] } }
## ##
# @NumaOptions # @NumaOptions

View File

@ -4658,21 +4658,22 @@ Example:
EQMP EQMP
{ {
.name = "x-input-send-event", .name = "input-send-event",
.args_type = "console:i?,events:q", .args_type = "console:i?,events:q",
.mhandler.cmd_new = qmp_marshal_x_input_send_event, .mhandler.cmd_new = qmp_marshal_input_send_event,
}, },
SQMP SQMP
@x-input-send-event @input-send-event
----------------- -----------------
Send input event to guest. Send input event to guest.
Arguments: Arguments:
- "console": console index. (json-int, optional) - "device": display device (json-string, optional)
- "events": list of input events. - "head": display head (json-int, optional)
- "events": list of input events
The consoles are visible in the qom tree, under The consoles are visible in the qom tree, under
/backend/console[$index]. They have a device link and head property, so /backend/console[$index]. They have a device link and head property, so
@ -4684,24 +4685,24 @@ Example (1):
Press left mouse button. Press left mouse button.
-> { "execute": "x-input-send-event", -> { "execute": "input-send-event",
"arguments": { "console": 0, "arguments": { "device": "video0",
"events": [ { "type": "btn", "events": [ { "type": "btn",
"data" : { "down": true, "button": "Left" } } ] } } "data" : { "down": true, "button": "left" } } ] } }
<- { "return": {} } <- { "return": {} }
-> { "execute": "x-input-send-event", -> { "execute": "input-send-event",
"arguments": { "console": 0, "arguments": { "device": "video0",
"events": [ { "type": "btn", "events": [ { "type": "btn",
"data" : { "down": false, "button": "Left" } } ] } } "data" : { "down": false, "button": "left" } } ] } }
<- { "return": {} } <- { "return": {} }
Example (2): Example (2):
Press ctrl-alt-del. Press ctrl-alt-del.
-> { "execute": "x-input-send-event", -> { "execute": "input-send-event",
"arguments": { "console": 0, "events": [ "arguments": { "events": [
{ "type": "key", "data" : { "down": true, { "type": "key", "data" : { "down": true,
"key": {"type": "qcode", "data": "ctrl" } } }, "key": {"type": "qcode", "data": "ctrl" } } },
{ "type": "key", "data" : { "down": true, { "type": "key", "data" : { "down": true,
@ -4714,10 +4715,10 @@ Example (3):
Move mouse pointer to absolute coordinates (20000, 400). Move mouse pointer to absolute coordinates (20000, 400).
-> { "execute": "x-input-send-event" , -> { "execute": "input-send-event" ,
"arguments": { "console": 0, "events": [ "arguments": { "events": [
{ "type": "abs", "data" : { "axis": "X", "value" : 20000 } }, { "type": "abs", "data" : { "axis": "x", "value" : 20000 } },
{ "type": "abs", "data" : { "axis": "Y", "value" : 400 } } ] } } { "type": "abs", "data" : { "axis": "y", "value" : 400 } } ] } }
<- { "return": {} } <- { "return": {} }
EQMP EQMP

View File

@ -66,8 +66,6 @@
'CpuInfoBase', # CPU, visible through query-cpu 'CpuInfoBase', # CPU, visible through query-cpu
'CpuInfoMIPS', # PC, visible through query-cpu 'CpuInfoMIPS', # PC, visible through query-cpu
'CpuInfoTricore', # PC, visible through query-cpu 'CpuInfoTricore', # PC, visible through query-cpu
'InputAxis', # TODO: drop when x-input-send-event is fixed
'InputButton', # TODO: drop when x-input-send-event is fixed
'QapiErrorClass', # all members, visible through errors 'QapiErrorClass', # all members, visible through errors
'UuidInfo', # UUID, visible through query-uuid 'UuidInfo', # UUID, visible through query-uuid
'X86CPURegister32', # all members, visible indirectly through qom-get 'X86CPURegister32', # all members, visible indirectly through qom-get

View File

@ -739,8 +739,8 @@ - (void) handleEvent:(NSEvent *)event
[INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON, [INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON,
[INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON, [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
[INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON, [INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON,
[INPUT_BUTTON_WHEELUP] = MOUSE_EVENT_WHEELUP, [INPUT_BUTTON_WHEEL_UP] = MOUSE_EVENT_WHEELUP,
[INPUT_BUTTON_WHEELDOWN] = MOUSE_EVENT_WHEELDN, [INPUT_BUTTON_WHEEL_DOWN] = MOUSE_EVENT_WHEELDN,
}; };
qemu_input_update_buttons(dcl->con, bmap, last_buttons, buttons); qemu_input_update_buttons(dcl->con, bmap, last_buttons, buttons);
last_buttons = buttons; last_buttons = buttons;

View File

@ -1790,6 +1790,29 @@ QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head)
return NULL; return NULL;
} }
QemuConsole *qemu_console_lookup_by_device_name(const char *device_id,
uint32_t head, Error **errp)
{
DeviceState *dev;
QemuConsole *con;
dev = qdev_find_recursive(sysbus_get_default(), device_id);
if (dev == NULL) {
error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
"Device '%s' not found", device_id);
return NULL;
}
con = qemu_console_lookup_by_device(dev, head);
if (con == NULL) {
error_setg(errp, "Device %s (head %d) is not bound to a QemuConsole",
device_id, head);
return NULL;
}
return con;
}
bool qemu_console_is_visible(QemuConsole *con) bool qemu_console_is_visible(QemuConsole *con)
{ {
return (con == active_console) || (con->dcls > 0); return (con == active_console) || (con->dcls > 0);

View File

@ -966,9 +966,9 @@ static gboolean gd_scroll_event(GtkWidget *widget, GdkEventScroll *scroll,
InputButton btn; InputButton btn;
if (scroll->direction == GDK_SCROLL_UP) { if (scroll->direction == GDK_SCROLL_UP) {
btn = INPUT_BUTTON_WHEELUP; btn = INPUT_BUTTON_WHEEL_UP;
} else if (scroll->direction == GDK_SCROLL_DOWN) { } else if (scroll->direction == GDK_SCROLL_DOWN) {
btn = INPUT_BUTTON_WHEELDOWN; btn = INPUT_BUTTON_WHEEL_DOWN;
} else { } else {
return TRUE; return TRUE;
} }

View File

@ -158,7 +158,7 @@ static void legacy_mouse_event(DeviceState *dev, QemuConsole *src,
} else { } else {
s->buttons &= ~bmap[evt->u.btn->button]; s->buttons &= ~bmap[evt->u.btn->button];
} }
if (evt->u.btn->down && evt->u.btn->button == INPUT_BUTTON_WHEELUP) { if (evt->u.btn->down && evt->u.btn->button == INPUT_BUTTON_WHEEL_UP) {
s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque, s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
s->axis[INPUT_AXIS_X], s->axis[INPUT_AXIS_X],
s->axis[INPUT_AXIS_Y], s->axis[INPUT_AXIS_Y],
@ -166,7 +166,7 @@ static void legacy_mouse_event(DeviceState *dev, QemuConsole *src,
s->buttons); s->buttons);
} }
if (evt->u.btn->down && if (evt->u.btn->down &&
evt->u.btn->button == INPUT_BUTTON_WHEELDOWN) { evt->u.btn->button == INPUT_BUTTON_WHEEL_DOWN) {
s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque, s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
s->axis[INPUT_AXIS_X], s->axis[INPUT_AXIS_X],
s->axis[INPUT_AXIS_Y], s->axis[INPUT_AXIS_Y],

View File

@ -82,19 +82,12 @@ void qemu_input_handler_bind(QemuInputHandlerState *s,
const char *device_id, int head, const char *device_id, int head,
Error **errp) Error **errp)
{ {
DeviceState *dev;
QemuConsole *con; QemuConsole *con;
Error *err = NULL;
dev = qdev_find_recursive(sysbus_get_default(), device_id); con = qemu_console_lookup_by_device_name(device_id, head, &err);
if (dev == NULL) { if (err) {
error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, error_propagate(errp, err);
"Device '%s' not found", device_id);
return;
}
con = qemu_console_lookup_by_device(dev, head);
if (con == NULL) {
error_setg(errp, "Device %s is not bound to a QemuConsole", device_id);
return; return;
} }
@ -126,17 +119,22 @@ qemu_input_find_handler(uint32_t mask, QemuConsole *con)
return NULL; return NULL;
} }
void qmp_x_input_send_event(bool has_console, int64_t console, void qmp_input_send_event(bool has_device, const char *device,
InputEventList *events, Error **errp) bool has_head, int64_t head,
InputEventList *events, Error **errp)
{ {
InputEventList *e; InputEventList *e;
QemuConsole *con; QemuConsole *con;
Error *err = NULL;
con = NULL; con = NULL;
if (has_console) { if (has_device) {
con = qemu_console_lookup_by_index(console); if (!has_head) {
if (!con) { head = 0;
error_setg(errp, "console %" PRId64 " not found", console); }
con = qemu_console_lookup_by_device_name(device, head, &err);
if (err) {
error_propagate(errp, err);
return; return;
} }
} }

View File

@ -475,8 +475,8 @@ static void sdl_send_mouse_event(int dx, int dy, int x, int y, int state)
[INPUT_BUTTON_LEFT] = SDL_BUTTON(SDL_BUTTON_LEFT), [INPUT_BUTTON_LEFT] = SDL_BUTTON(SDL_BUTTON_LEFT),
[INPUT_BUTTON_MIDDLE] = SDL_BUTTON(SDL_BUTTON_MIDDLE), [INPUT_BUTTON_MIDDLE] = SDL_BUTTON(SDL_BUTTON_MIDDLE),
[INPUT_BUTTON_RIGHT] = SDL_BUTTON(SDL_BUTTON_RIGHT), [INPUT_BUTTON_RIGHT] = SDL_BUTTON(SDL_BUTTON_RIGHT),
[INPUT_BUTTON_WHEELUP] = SDL_BUTTON(SDL_BUTTON_WHEELUP), [INPUT_BUTTON_WHEEL_UP] = SDL_BUTTON(SDL_BUTTON_WHEELUP),
[INPUT_BUTTON_WHEELDOWN] = SDL_BUTTON(SDL_BUTTON_WHEELDOWN), [INPUT_BUTTON_WHEEL_DOWN] = SDL_BUTTON(SDL_BUTTON_WHEELDOWN),
}; };
static uint32_t prev_state; static uint32_t prev_state;

View File

@ -509,9 +509,9 @@ static void handle_mousewheel(SDL_Event *ev)
InputButton btn; InputButton btn;
if (wev->y > 0) { if (wev->y > 0) {
btn = INPUT_BUTTON_WHEELUP; btn = INPUT_BUTTON_WHEEL_UP;
} else if (wev->y < 0) { } else if (wev->y < 0) {
btn = INPUT_BUTTON_WHEELDOWN; btn = INPUT_BUTTON_WHEEL_DOWN;
} else { } else {
return; return;
} }

View File

@ -108,8 +108,8 @@ static void spice_update_buttons(QemuSpicePointer *pointer,
[INPUT_BUTTON_LEFT] = 0x01, [INPUT_BUTTON_LEFT] = 0x01,
[INPUT_BUTTON_MIDDLE] = 0x04, [INPUT_BUTTON_MIDDLE] = 0x04,
[INPUT_BUTTON_RIGHT] = 0x02, [INPUT_BUTTON_RIGHT] = 0x02,
[INPUT_BUTTON_WHEELUP] = 0x10, [INPUT_BUTTON_WHEEL_UP] = 0x10,
[INPUT_BUTTON_WHEELDOWN] = 0x20, [INPUT_BUTTON_WHEEL_DOWN] = 0x20,
}; };
if (wheel < 0) { if (wheel < 0) {

View File

@ -1593,8 +1593,8 @@ static void pointer_event(VncState *vs, int button_mask, int x, int y)
[INPUT_BUTTON_LEFT] = 0x01, [INPUT_BUTTON_LEFT] = 0x01,
[INPUT_BUTTON_MIDDLE] = 0x02, [INPUT_BUTTON_MIDDLE] = 0x02,
[INPUT_BUTTON_RIGHT] = 0x04, [INPUT_BUTTON_RIGHT] = 0x04,
[INPUT_BUTTON_WHEELUP] = 0x08, [INPUT_BUTTON_WHEEL_UP] = 0x08,
[INPUT_BUTTON_WHEELDOWN] = 0x10, [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
}; };
QemuConsole *con = vs->vd->dcl.con; QemuConsole *con = vs->vd->dcl.con;
int width = pixman_image_get_width(vs->vd->server); int width = pixman_image_get_width(vs->vd->server);
@ -3732,19 +3732,12 @@ void vnc_display_open(const char *id, Error **errp)
device_id = qemu_opt_get(opts, "display"); device_id = qemu_opt_get(opts, "display");
if (device_id) { if (device_id) {
DeviceState *dev;
int head = qemu_opt_get_number(opts, "head", 0); int head = qemu_opt_get_number(opts, "head", 0);
Error *err = NULL;
dev = qdev_find_recursive(sysbus_get_default(), device_id); con = qemu_console_lookup_by_device_name(device_id, head, &err);
if (dev == NULL) { if (err) {
error_setg(errp, "Device '%s' not found", device_id); error_propagate(errp, err);
goto fail;
}
con = qemu_console_lookup_by_device(dev, head);
if (con == NULL) {
error_setg(errp, "Device %s is not bound to a QemuConsole",
device_id);
goto fail; goto fail;
} }
} else { } else {