[Spice-devel] [PATCH linux vdagent v4 7/9] Send display_id down to the vdagentd daemon

Jonathon Jongsma jjongsma at redhat.com
Thu Jan 17 22:14:26 UTC 2019


Add a display_id field to the structure that we use to send down the
list of guest display resolutions to the vdagentd daemon. This allows us
to map the spice display id to the proper X display for determining
mouse locations, etc.
---
 src/vdagent/x11-randr.c | 35 ++++++++++++++++++++++++++++++++---
 src/vdagentd-proto.h    |  1 +
 src/vdagentd/uinput.c   | 23 ++++++++++++++++++-----
 3 files changed, 51 insertions(+), 8 deletions(-)

diff --git a/src/vdagent/x11-randr.c b/src/vdagent/x11-randr.c
index f3972c8..5749ae7 100644
--- a/src/vdagent/x11-randr.c
+++ b/src/vdagent/x11-randr.c
@@ -688,6 +688,34 @@ static int config_size(int num_of_monitors)
                            num_of_monitors * sizeof(VDAgentMonConfig);
 }
 
+static int get_display_id_for_output_index(struct vdagent_x11 *x11, int output_index)
+{
+    // invalid output index
+    if (output_index >= x11->randr.res->noutput) {
+        syslog(LOG_WARNING, "Invalid output index %d (>%d)", output_index, x11->randr.res->noutput);
+        return -1;
+    }
+
+    if (g_hash_table_size(x11->guest_output_map) == 0) {
+        syslog(LOG_DEBUG, "No guest output map, using output index as display id");
+        return output_index;
+    }
+
+    int display_id = -1;
+    RROutput output_id = x11->randr.res->outputs[output_index];
+    GHashTableIter iter;
+    gpointer key, value;
+    g_hash_table_iter_init(&iter, x11->guest_output_map);
+    while (g_hash_table_iter_next(&iter, &key, &value)) {
+        gint64 *other_id = value;
+        if (*other_id == output_id) {
+            return GPOINTER_TO_INT(key);
+        }
+    }
+
+    syslog(LOG_WARNING, "Unable to find a display id for output index %d)", output_index);
+    return display_id;
+}
 
 // gets monitor information about the specified output index and returns true if there was no error
 static bool get_monitor_info_for_output_index(struct vdagent_x11 *x11, int output_index, int *x, int *y, int *width, int *height)
@@ -1075,11 +1103,12 @@ void vdagent_x11_send_daemon_guest_xorg_res(struct vdagent_x11 *x11, int update)
         for (i = 0; i < screen_count; i++) {
             struct vdagentd_guest_xorg_resolution *curr = &res[i];
             if (!get_monitor_info_for_output_index(x11, i, &curr->x, &curr->y,
-                                                   &curr->width, &curr->height)
+                                                   &curr->width, &curr->height))
             {
                 g_free(res);
                 goto no_info;
             }
+            curr->display_id = get_display_id_for_output_index(x11, i);
         }
         width  = x11->width[0];
         height = x11->height[0];
@@ -1131,8 +1160,8 @@ no_info:
     if (x11->debug) {
         syslog(LOG_DEBUG, "Sending guest screen resolutions to vdagentd:");
         for (i = 0; i < screen_count; i++) {
-            syslog(LOG_DEBUG, "   screen %d %dx%d%+d%+d", i,
-                   res[i].width, res[i].height, res[i].x, res[i].y);
+            syslog(LOG_DEBUG, "   screen %d %dx%d%+d%+d, id=%d", i,
+                   res[i].width, res[i].height, res[i].x, res[i].y, res[i].display_id);
         }
     }
 
diff --git a/src/vdagentd-proto.h b/src/vdagentd-proto.h
index 243a9c6..7eff71d 100644
--- a/src/vdagentd-proto.h
+++ b/src/vdagentd-proto.h
@@ -53,6 +53,7 @@ struct vdagentd_guest_xorg_resolution {
     int height;
     int x;
     int y;
+    int display_id;
 };
 
 #endif
diff --git a/src/vdagentd/uinput.c b/src/vdagentd/uinput.c
index 4f854bf..ff37e1e 100644
--- a/src/vdagentd/uinput.c
+++ b/src/vdagentd/uinput.c
@@ -175,6 +175,18 @@ static void uinput_send_event(struct vdagentd_uinput **uinputp,
     }
 }
 
+static struct vdagentd_guest_xorg_resolution* lookup_screen_info(struct vdagentd_uinput *uinput, int display_id)
+{
+    int i;
+    for (i = 0; i < uinput->screen_count; i++) {
+        if (uinput->screen_info[i].display_id == display_id) {
+            return &uinput->screen_info[i];
+        }
+    }
+    syslog(LOG_WARNING, "Unable to find output index for display id %d", display_id);
+    return NULL;
+}
+
 void vdagentd_uinput_do_mouse(struct vdagentd_uinput **uinputp,
         VDAgentMouseState *mouse)
 {
@@ -196,16 +208,17 @@ void vdagentd_uinput_do_mouse(struct vdagentd_uinput **uinputp,
     int i, down;
 
     if (*uinputp) {
-        if (mouse->display_id >= uinput->screen_count) {
-            syslog(LOG_WARNING, "mouse event for unknown monitor (%d >= %d)",
-                   mouse->display_id, uinput->screen_count);
+        struct vdagentd_guest_xorg_resolution *screen_info = lookup_screen_info(uinput, mouse->display_id);
+        if (screen_info == NULL) {
+            syslog(LOG_WARNING, "mouse event for unknown monitor %d",
+                   mouse->display_id);
             return;
         }
         if (uinput->debug)
             syslog(LOG_DEBUG, "mouse-event: mon %d %dx%d", mouse->display_id,
                    mouse->x, mouse->y);
-        mouse->x += uinput->screen_info[mouse->display_id].x;
-        mouse->y += uinput->screen_info[mouse->display_id].y;
+        mouse->x += screen_info->x;
+        mouse->y += screen_info->y;
 #ifdef WITH_STATIC_UINPUT
         mouse->x = mouse->x * 32767 / (uinput->width - 1);
         mouse->y = mouse->y * 32767 / (uinput->height - 1);
-- 
2.17.2



More information about the Spice-devel mailing list