[Spice-devel] [PATCH vd_agent 8/8 v2] Receive the graphics_device_info message
Lukáš Hrázký
lhrazky at redhat.com
Mon Jan 14 16:38:43 UTC 2019
The graphics_device_info message contains the device display ID
information (device address and device display ID). Stores the data in a
hash table in vdagent.
Signed-off-by: Lukáš Hrázký <lhrazky at redhat.com>
---
src/vdagent/vdagent.c | 3 ++
src/vdagent/x11-priv.h | 1 +
src/vdagent/x11-randr.c | 57 ++++++++++++++++++++++++++++++++++++
src/vdagent/x11.c | 13 ++++++++
src/vdagent/x11.h | 1 +
src/vdagentd-proto-strings.h | 1 +
src/vdagentd-proto.h | 1 +
src/vdagentd/vdagentd.c | 16 ++++++++++
8 files changed, 93 insertions(+)
diff --git a/src/vdagent/vdagent.c b/src/vdagent/vdagent.c
index 9642a30..aa52ee9 100644
--- a/src/vdagent/vdagent.c
+++ b/src/vdagent/vdagent.c
@@ -240,6 +240,9 @@ static void daemon_read_complete(struct udscs_connection **connp,
((VDAgentFileXferDataMessage *)data)->id);
}
break;
+ case VDAGENTD_GRAPHICS_DEVICE_INFO:
+ vdagent_x11_handle_graphics_device_info(agent->x11, data, header->size);
+ break;
case VDAGENTD_CLIENT_DISCONNECTED:
vdagent_clipboards_release_all(agent->clipboards);
if (vdagent_finalize_file_xfer(agent)) {
diff --git a/src/vdagent/x11-priv.h b/src/vdagent/x11-priv.h
index b31b0a5..0e954cf 100644
--- a/src/vdagent/x11-priv.h
+++ b/src/vdagent/x11-priv.h
@@ -139,6 +139,7 @@ struct vdagent_x11 {
int xrandr_minor;
int has_xinerama;
int dont_send_guest_xorg_res;
+ GHashTable *graphics_display_infos;
};
extern int (*vdagent_x11_prev_error_handler)(Display *, XErrorEvent *);
diff --git a/src/vdagent/x11-randr.c b/src/vdagent/x11-randr.c
index 192b888..478e78b 100644
--- a/src/vdagent/x11-randr.c
+++ b/src/vdagent/x11-randr.c
@@ -727,6 +727,63 @@ static void dump_monitors_config(struct vdagent_x11 *x11,
}
}
+typedef struct GraphicsDisplayInfo {
+ char device_address[256];
+ uint32_t device_display_id;
+} GraphicsDisplayInfo;
+
+// handle the device info message from the server. This will allow us to
+// maintain a mapping from spice display id to xrandr output
+void vdagent_x11_handle_graphics_device_info(struct vdagent_x11 *x11, uint8_t *data, size_t size)
+{
+ VDAgentGraphicsDeviceInfo *graphics_device_info = (VDAgentGraphicsDeviceInfo *)data;
+ VDAgentDeviceDisplayInfo *device_display_info = graphics_device_info->display_info;
+
+ void *buffer_end = data + size;
+
+ syslog(LOG_INFO, "Received Graphics Device Info:");
+
+ for (size_t i = 0; i < graphics_device_info->count; ++i) {
+ if ((void*) device_display_info > buffer_end ||
+ (void*) (&device_display_info->device_address +
+ device_display_info->device_address_len) > buffer_end) {
+ syslog(LOG_ERR, "Malformed graphics_display_info message, "
+ "extends beyond the end of the buffer");
+ break;
+ }
+
+ GraphicsDisplayInfo *value = g_malloc(sizeof(GraphicsDisplayInfo));
+
+ size_t device_address_len = device_display_info->device_address_len;
+ if (device_address_len > sizeof(value->device_address)) {
+ syslog(LOG_ERR, "Received a device address longer than %lu, "
+ "will be truncated!", device_address_len);
+ device_address_len = sizeof(value->device_address);
+ }
+
+ strncpy(value->device_address,
+ (char*) device_display_info->device_address,
+ device_address_len);
+ value->device_address[device_address_len - 1] = '\0'; // make sure the string is terminated
+ value->device_display_id = device_display_info->device_display_id;
+
+ syslog(LOG_INFO, " channel_id: %u monitor_id: %u device_address: %s, "
+ "device_display_id: %u",
+ device_display_info->channel_id,
+ device_display_info->monitor_id,
+ value->device_address,
+ value->device_display_id);
+
+ g_hash_table_insert(x11->graphics_display_infos,
+ GUINT_TO_POINTER(device_display_info->channel_id + device_display_info->monitor_id),
+ value);
+
+ device_display_info = (VDAgentDeviceDisplayInfo*) ((char*) device_display_info +
+ sizeof(VDAgentDeviceDisplayInfo) + device_display_info->device_address_len);
+ }
+}
+
+
/*
* Set monitor configuration according to client request.
*
diff --git a/src/vdagent/x11.c b/src/vdagent/x11.c
index 53d3c48..2473383 100644
--- a/src/vdagent/x11.c
+++ b/src/vdagent/x11.c
@@ -196,6 +196,12 @@ static gchar *vdagent_x11_get_wm_name(struct vdagent_x11 *x11)
#endif
}
+static void graphics_display_info_destroy(gpointer gdi)
+{
+ g_free(gdi);
+}
+
+
struct vdagent_x11 *vdagent_x11_create(struct udscs_connection *vdagentd,
int debug, int sync)
{
@@ -316,6 +322,12 @@ struct vdagent_x11 *vdagent_x11_create(struct udscs_connection *vdagentd,
__func__, net_wm_name, vdagent_x11_has_icons_on_desktop(x11));
g_free(net_wm_name);
+ x11->graphics_display_infos = g_hash_table_new_full(&g_direct_hash,
+ &g_direct_equal,
+ NULL,
+ &graphics_display_info_destroy);
+
+
/* Flush output buffers and consume any pending events */
vdagent_x11_do_read(x11);
@@ -337,6 +349,7 @@ void vdagent_x11_destroy(struct vdagent_x11 *x11, int vdagentd_disconnected)
}
#endif
+ g_hash_table_destroy(x11->graphics_display_infos);
XCloseDisplay(x11->display);
g_free(x11->randr.failed_conf);
g_free(x11);
diff --git a/src/vdagent/x11.h b/src/vdagent/x11.h
index 2117abf..bb2ac80 100644
--- a/src/vdagent/x11.h
+++ b/src/vdagent/x11.h
@@ -51,5 +51,6 @@ void vdagent_x11_client_disconnected(struct vdagent_x11 *x11);
#endif
int vdagent_x11_has_icons_on_desktop(struct vdagent_x11 *x11);
+void vdagent_x11_handle_graphics_device_info(struct vdagent_x11 *x11, uint8_t *data, size_t size);
#endif
diff --git a/src/vdagentd-proto-strings.h b/src/vdagentd-proto-strings.h
index 6e7bcee..7e03f46 100644
--- a/src/vdagentd-proto-strings.h
+++ b/src/vdagentd-proto-strings.h
@@ -36,6 +36,7 @@ static const char * const vdagentd_messages[] = {
"file xfer data",
"file xfer disable",
"client disconnected",
+ "graphics device info",
};
#endif
diff --git a/src/vdagentd-proto.h b/src/vdagentd-proto.h
index f72a890..243a9c6 100644
--- a/src/vdagentd-proto.h
+++ b/src/vdagentd-proto.h
@@ -44,6 +44,7 @@ enum {
VDAGENTD_FILE_XFER_DATA,
VDAGENTD_FILE_XFER_DISABLE,
VDAGENTD_CLIENT_DISCONNECTED, /* daemon -> client */
+ VDAGENTD_GRAPHICS_DEVICE_INFO, /* daemon -> client */
VDAGENTD_NO_MESSAGES /* Must always be last */
};
diff --git a/src/vdagentd/vdagentd.c b/src/vdagentd/vdagentd.c
index 5ed29cc..4b7e68c 100644
--- a/src/vdagentd/vdagentd.c
+++ b/src/vdagentd/vdagentd.c
@@ -373,6 +373,16 @@ static void do_client_file_xfer(struct vdagent_virtio_port *vport,
udscs_write(conn, msg_type, 0, 0, data, message_header->size);
}
+static void forward_data_to_session_agent(uint32_t type, uint8_t *data, size_t size)
+{
+ if (active_session_conn == NULL) {
+ syslog(LOG_DEBUG, "No active session, can't forward message (type %u)", type);
+ return;
+ }
+
+ udscs_write(active_session_conn, type, 0, 0, data, size);
+}
+
static gsize vdagent_message_min_size[] =
{
-1, /* Does not exist */
@@ -391,6 +401,7 @@ static gsize vdagent_message_min_size[] =
0, /* VD_AGENT_CLIENT_DISCONNECTED */
sizeof(VDAgentMaxClipboard), /* VD_AGENT_MAX_CLIPBOARD */
sizeof(VDAgentAudioVolumeSync), /* VD_AGENT_AUDIO_VOLUME_SYNC */
+ sizeof(VDAgentGraphicsDeviceInfo), /* VD_AGENT_GRAPHICS_DEVICE_INFO */
};
static void vdagent_message_clipboard_from_le(VDAgentMessage *message_header,
@@ -475,6 +486,7 @@ static gboolean vdagent_message_check_size(const VDAgentMessage *message_header)
case VD_AGENT_CLIPBOARD_GRAB:
case VD_AGENT_AUDIO_VOLUME_SYNC:
case VD_AGENT_ANNOUNCE_CAPABILITIES:
+ case VD_AGENT_GRAPHICS_DEVICE_INFO:
if (message_header->size < min_size) {
syslog(LOG_ERR, "read: invalid message size: %u for message type: %u",
message_header->size, message_header->type);
@@ -548,6 +560,10 @@ static int virtio_port_read_complete(
syslog(LOG_DEBUG, "Set max clipboard: %d", max_clipboard);
break;
}
+ case VD_AGENT_GRAPHICS_DEVICE_INFO: {
+ forward_data_to_session_agent(VDAGENTD_GRAPHICS_DEVICE_INFO, data, message_header->size);
+ break;
+ }
case VD_AGENT_AUDIO_VOLUME_SYNC: {
VDAgentAudioVolumeSync *vdata = (VDAgentAudioVolumeSync *)data;
virtio_msg_uint16_from_le((uint8_t *)vdata, message_header->size,
--
2.20.1
More information about the Spice-devel
mailing list