[Spice-devel] [RFC PATCH spice v2 12/20] Handle version 2 of the mouse position message

Lukáš Hrázký lhrazky at redhat.com
Thu Aug 16 16:26:41 UTC 2018


The version 2 of the mouse position message is using the (channel_id,
monitor_id) pair as the unique identifier for the monitor. The pair is
then translated to the guest_output_id (called display_id in the
vd_agent message) either by retrieving it from the
monitors_guest_output_id hash table, if it is in there, or the old way:
channel_id ? channel_id : monitor_id.

Signed-off-by: Lukáš Hrázký <lhrazky at redhat.com>
---
 server/inputs-channel.c  | 64 +++++++++++++++++++++++++++++-----------
 subprojects/spice-common |  2 +-
 2 files changed, 47 insertions(+), 19 deletions(-)

diff --git a/server/inputs-channel.c b/server/inputs-channel.c
index e01bb7d0..3ce0dfb6 100644
--- a/server/inputs-channel.c
+++ b/server/inputs-channel.c
@@ -245,6 +245,34 @@ static void inputs_channel_send_item(RedChannelClient *rcc, RedPipeItem *base)
     red_channel_client_begin_send_message(rcc);
 }
 
+static void inputs_channel_handle_mouse_position(RedChannelClient *rcc, uint32_t x, uint32_t y,
+                                                 uint32_t buttons_state, uint32_t guest_output_id)
+{
+    InputsChannel *inputs_channel = INPUTS_CHANNEL(red_channel_client_get_channel(rcc));
+    InputsChannelClient *icc = INPUTS_CHANNEL_CLIENT(rcc);
+    RedsState *reds = red_channel_get_server(RED_CHANNEL(inputs_channel));
+
+    SpiceTabletInstance *tablet = inputs_channel_get_tablet(inputs_channel);
+
+    inputs_channel_client_on_mouse_motion(icc);
+    if (reds_get_mouse_mode(reds) != SPICE_MOUSE_MODE_CLIENT) {
+        return;
+    }
+    spice_assert((reds_config_get_agent_mouse(reds) && reds_has_vdagent(reds)) || tablet);
+    if (!reds_config_get_agent_mouse(reds) || !reds_has_vdagent(reds)) {
+        SpiceTabletInterface *sif;
+        sif = SPICE_CONTAINEROF(tablet->base.sif, SpiceTabletInterface, base);
+        sif->position(tablet, x, y, RED_MOUSE_STATE_TO_LOCAL(buttons_state));
+        return;
+    }
+    VDAgentMouseState *mouse_state = &inputs_channel->mouse_state;
+    mouse_state->x = x;
+    mouse_state->y = y;
+    mouse_state->buttons = RED_MOUSE_BUTTON_STATE_TO_AGENT(buttons_state);
+    mouse_state->display_id = guest_output_id;
+    reds_handle_agent_mouse_event(reds, mouse_state);
+}
+
 static bool inputs_channel_handle_message(RedChannelClient *rcc, uint16_t type,
                                           uint32_t size, void *message)
 {
@@ -297,25 +325,25 @@ static bool inputs_channel_handle_message(RedChannelClient *rcc, uint16_t type,
     }
     case SPICE_MSGC_INPUTS_MOUSE_POSITION: {
         SpiceMsgcMousePosition *pos = message;
-        SpiceTabletInstance *tablet = inputs_channel_get_tablet(inputs_channel);
-
-        inputs_channel_client_on_mouse_motion(icc);
-        if (reds_get_mouse_mode(reds) != SPICE_MOUSE_MODE_CLIENT) {
-            break;
-        }
-        spice_assert((reds_config_get_agent_mouse(reds) && reds_has_vdagent(reds)) || tablet);
-        if (!reds_config_get_agent_mouse(reds) || !reds_has_vdagent(reds)) {
-            SpiceTabletInterface *sif;
-            sif = SPICE_CONTAINEROF(tablet->base.sif, SpiceTabletInterface, base);
-            sif->position(tablet, pos->x, pos->y, RED_MOUSE_STATE_TO_LOCAL(pos->buttons_state));
-            break;
+        inputs_channel_handle_mouse_position(rcc, pos->x, pos->y, pos->buttons_state, pos->display_id);
+        break;
+    }
+    case SPICE_MSGC_INPUTS_MOUSE_POSITION_V2: {
+        SpiceMsgcMousePositionV2 *pos = message;
+
+        uint32_t guest_output_id;
+
+        if (!reds_get_monitor_guest_output_id(reds,
+                                              pos->channel_id,
+                                              pos->monitor_id,
+                                              &guest_output_id)) {
+            // the original guest_output_id calculation, assuming there is either:
+            // - only one display channel with multiple monitors
+            // - multiple display channels each with only one monitor
+            guest_output_id = pos->channel_id ? pos->channel_id : pos->monitor_id;
         }
-        VDAgentMouseState *mouse_state = &inputs_channel->mouse_state;
-        mouse_state->x = pos->x;
-        mouse_state->y = pos->y;
-        mouse_state->buttons = RED_MOUSE_BUTTON_STATE_TO_AGENT(pos->buttons_state);
-        mouse_state->display_id = pos->display_id;
-        reds_handle_agent_mouse_event(reds, mouse_state);
+
+        inputs_channel_handle_mouse_position(rcc, pos->x, pos->y, pos->buttons_state, guest_output_id);
         break;
     }
     case SPICE_MSGC_INPUTS_MOUSE_PRESS: {
diff --git a/subprojects/spice-common b/subprojects/spice-common
index 0af835f1..b72eaca9 160000
--- a/subprojects/spice-common
+++ b/subprojects/spice-common
@@ -1 +1 @@
-Subproject commit 0af835f10e4dd51773dbeeb784fda4364b745874
+Subproject commit b72eaca98e58e18ff2a5b254980e4b6693517e89
-- 
2.18.0



More information about the Spice-devel mailing list