Use the new MousePositionV2 as the mouse position message, which contains the (channel_id, monitor_id) pair as the unique identifier for the monitor to which the position belongs. The ID pair will be translated to a guest_output_id on the server. Since the function sending the position is part of the API, keep the old version of the API function and add a mouse_position_v2() function to the API. For the old version of the API function, we keep sending the old version of the protocol message. Since the function has a single "display_id" as an argument, there is no way to reconstruct the (channel_id, monitor_id) pair from it. Signed-off-by: Lukáš Hrázký <lhrazky@xxxxxxxxxx> --- src/channel-inputs.c | 92 ++++++++++++++++++++++++++++++++++------ src/channel-inputs.h | 10 +++-- src/map-file | 1 + src/spice-glib-sym-file | 1 + src/spice-widget.c | 20 ++------- subprojects/spice-common | 2 +- 6 files changed, 91 insertions(+), 35 deletions(-) diff --git a/src/channel-inputs.c b/src/channel-inputs.c index 1e8f956..e0c2a0c 100644 --- a/src/channel-inputs.c +++ b/src/channel-inputs.c @@ -44,9 +44,12 @@ struct _SpiceInputsChannelPrivate { int bs; int dx, dy; unsigned int x, y, dpy; + uint32_t channel_id, monitor_id; int motion_count; int modifiers; guint32 locks; + bool position_sent; + bool send_v1_position; }; G_DEFINE_TYPE_WITH_PRIVATE(SpiceInputsChannel, spice_inputs_channel, SPICE_TYPE_CHANNEL) @@ -171,23 +174,35 @@ static SpiceMsgOut* mouse_motion(SpiceInputsChannel *channel) static SpiceMsgOut* mouse_position(SpiceInputsChannel *channel) { SpiceInputsChannelPrivate *c = channel->priv; - SpiceMsgcMousePosition position; SpiceMsgOut *msg; - if (c->dpy == -1) + if (c->position_sent) { return NULL; + } - /* CHANNEL_DEBUG(channel, "%s: +%d+%d", __FUNCTION__, c->x, c->y); */ - position.buttons_state = c->bs; - position.x = c->x; - position.y = c->y; - position.display_id = c->dpy; - msg = spice_msg_out_new(SPICE_CHANNEL(channel), - SPICE_MSGC_INPUTS_MOUSE_POSITION); - msg->marshallers->msgc_inputs_mouse_position(msg->marshaller, &position); + if (c->send_v1_position) { + SpiceMsgcMousePosition position; + position.buttons_state = c->bs; + position.x = c->x; + position.y = c->y; + position.display_id = c->dpy; + msg = spice_msg_out_new(SPICE_CHANNEL(channel), + SPICE_MSGC_INPUTS_MOUSE_POSITION); + msg->marshallers->msgc_inputs_mouse_position(msg->marshaller, &position); + } else { + SpiceMsgcMousePositionV2 position; + position.buttons_state = c->bs; + position.x = c->x; + position.y = c->y; + position.channel_id = c->channel_id; + position.monitor_id = c->monitor_id; + msg = spice_msg_out_new(SPICE_CHANNEL(channel), + SPICE_MSGC_INPUTS_MOUSE_POSITION_V2); + msg->marshallers->msgc_inputs_mouse_position_v2(msg->marshaller, &position); + } c->motion_count++; - c->dpy = -1; + c->position_sent = true; return msg; } @@ -323,6 +338,31 @@ void spice_inputs_channel_motion(SpiceInputsChannel *channel, gint dx, gint dy, } } +static void spice_inputs_channel_position_v1(SpiceInputsChannel *channel, gint x, gint y, + gint display, gint button_state) +{ + SpiceInputsChannelPrivate *c; + + g_return_if_fail(channel != NULL); + + if (SPICE_CHANNEL(channel)->priv->state != SPICE_CHANNEL_STATE_READY) + return; + + c = channel->priv; + c->bs = button_state; + c->x = x; + c->y = y; + c->dpy = display; + c->position_sent = false; + c->send_v1_position = true; + + if (c->motion_count < SPICE_INPUT_MOTION_ACK_BUNCH * 2) { + send_position(channel); + } else { + CHANNEL_DEBUG(channel, "over SPICE_INPUT_MOTION_ACK_BUNCH * 2, dropping"); + } +} + /** * spice_inputs_position: * @channel: a #SpiceInputsChannel @@ -333,12 +373,12 @@ void spice_inputs_channel_motion(SpiceInputsChannel *channel, gint dx, gint dy, * * Change mouse position (used in SPICE_MOUSE_MODE_CLIENT). * - * Deprecated: 0.35: use spice_inputs_channel_position() instead. + * Deprecated: 0.35: use spice_inputs_channel_position_v2() instead. **/ void spice_inputs_position(SpiceInputsChannel *channel, gint x, gint y, gint display, gint button_state) { - spice_inputs_channel_position(channel, x, y, display, button_state); + spice_inputs_channel_position_v1(channel, x, y, display, button_state); } /** @@ -352,9 +392,30 @@ void spice_inputs_position(SpiceInputsChannel *channel, gint x, gint y, * Change mouse position (used in SPICE_MOUSE_MODE_CLIENT). * * Since: 0.35 + * Deprecated: 0.36: use spice_inputs_channel_position_v2() instead. **/ void spice_inputs_channel_position(SpiceInputsChannel *channel, gint x, gint y, gint display, gint button_state) +{ + spice_inputs_channel_position_v1(channel, x, y, display, button_state); +} + +/** + * spice_inputs_channel_position_v2: + * @channel: a #SpiceInputsChannel + * @x: X mouse coordinates + * @y: Y mouse coordinates + * @channel_id: the display channel ID + * @monitor_id: the ID of the monitor in the display channel + * @button_state: SPICE_MOUSE_BUTTON_MASK flags + * + * Change mouse position (used in SPICE_MOUSE_MODE_CLIENT). + * + * Since: 0.36 + **/ +void spice_inputs_channel_position_v2(SpiceInputsChannel *channel, + uint32_t channel_id, uint32_t monitor_id, + gint x, gint y, gint button_state) { SpiceInputsChannelPrivate *c; @@ -367,7 +428,10 @@ void spice_inputs_channel_position(SpiceInputsChannel *channel, gint x, gint y, c->bs = button_state; c->x = x; c->y = y; - c->dpy = display; + c->channel_id = channel_id; + c->monitor_id = monitor_id; + c->position_sent = false; + c->send_v1_position = false; if (c->motion_count < SPICE_INPUT_MOTION_ACK_BUNCH * 2) { send_position(channel); diff --git a/src/channel-inputs.h b/src/channel-inputs.h index fa78235..677403d 100644 --- a/src/channel-inputs.h +++ b/src/channel-inputs.h @@ -84,8 +84,9 @@ struct _SpiceInputsChannelClass { GType spice_inputs_channel_get_type(void); void spice_inputs_channel_motion(SpiceInputsChannel *channel, gint dx, gint dy, gint button_state); -void spice_inputs_channel_position(SpiceInputsChannel *channel, gint x, gint y, gint display, - gint button_state); +void spice_inputs_channel_position_v2(SpiceInputsChannel *channel, + uint32_t channel_id, uint32_t monitor_id, + gint x, gint y, gint button_state); void spice_inputs_channel_button_press(SpiceInputsChannel *channel, gint button, gint button_state); void spice_inputs_channel_button_release(SpiceInputsChannel *channel, gint button, gint button_state); @@ -97,7 +98,10 @@ void spice_inputs_channel_key_press_and_release(SpiceInputsChannel *channel, gui #ifndef SPICE_DISABLE_DEPRECATED G_DEPRECATED_FOR(spice_inputs_channel_motion) void spice_inputs_motion(SpiceInputsChannel *channel, gint dx, gint dy, gint button_state); -G_DEPRECATED_FOR(spice_inputs_channel_position) +G_DEPRECATED_FOR(spice_inputs_channel_position_v2) +void spice_inputs_channel_position(SpiceInputsChannel *channel, gint x, gint y, gint display, + gint button_state); +G_DEPRECATED_FOR(spice_inputs_channel_position_v2) void spice_inputs_position(SpiceInputsChannel *channel, gint x, gint y, gint display, gint button_state); G_DEPRECATED_FOR(spice_inputs_channel_button_press) diff --git a/src/map-file b/src/map-file index d0163d4..5c6ee70 100644 --- a/src/map-file +++ b/src/map-file @@ -71,6 +71,7 @@ spice_inputs_channel_key_press_and_release; spice_inputs_channel_key_release; spice_inputs_channel_motion; spice_inputs_channel_position; +spice_inputs_channel_position_v2; spice_inputs_channel_set_key_locks; spice_inputs_key_press; spice_inputs_key_press_and_release; diff --git a/src/spice-glib-sym-file b/src/spice-glib-sym-file index 202588e..6093a6b 100644 --- a/src/spice-glib-sym-file +++ b/src/spice-glib-sym-file @@ -50,6 +50,7 @@ spice_inputs_channel_key_press_and_release spice_inputs_channel_key_release spice_inputs_channel_motion spice_inputs_channel_position +spice_inputs_channel_position_v2 spice_inputs_channel_set_key_locks spice_inputs_key_press spice_inputs_key_press_and_release diff --git a/src/spice-widget.c b/src/spice-widget.c index e361c91..f24e416 100644 --- a/src/spice-widget.c +++ b/src/spice-widget.c @@ -220,19 +220,6 @@ static void update_keyboard_focus(SpiceDisplay *display, gboolean state) spice_gtk_session_request_auto_usbredir(d->gtk_session, state); } -static gint get_display_id(SpiceDisplay *display) -{ - SpiceDisplayPrivate *d = display->priv; - - /* supported monitor_id only with display channel #0 */ - if (d->channel_id == 0 && d->monitor_id >= 0) - return d->monitor_id; - - g_return_val_if_fail(d->monitor_id <= 0, -1); - - return d->channel_id; -} - static bool egl_enabled(SpiceDisplayPrivate *d) { #if HAVE_EGL @@ -1922,10 +1909,9 @@ static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion) switch (d->mouse_mode) { case SPICE_MOUSE_MODE_CLIENT: - if (x >= 0 && x < d->area.width && - y >= 0 && y < d->area.height) { - spice_inputs_channel_position(d->inputs, x, y, get_display_id(display), - button_mask_gdk_to_spice(motion->state)); + if (x >= 0 && x < d->area.width && y >= 0 && y < d->area.height) { + spice_inputs_channel_position_v2(d->inputs, d->channel_id, d->monitor_id, x, y, + button_mask_gdk_to_spice(motion->state)); } break; case SPICE_MOUSE_MODE_SERVER: diff --git a/subprojects/spice-common b/subprojects/spice-common index 0af835f..b72eaca 160000 --- a/subprojects/spice-common +++ b/subprojects/spice-common @@ -1 +1 @@ -Subproject commit 0af835f10e4dd51773dbeeb784fda4364b745874 +Subproject commit b72eaca98e58e18ff2a5b254980e4b6693517e89 -- 2.18.0 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel