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@xxxxxxxxxx> --- src/vdagent/vdagent.c | 69 ++++++++++++++++++++++++++++++++++++ src/vdagentd-proto-strings.h | 1 + src/vdagentd-proto.h | 1 + src/vdagentd/vdagentd.c | 16 +++++++++ 4 files changed, 87 insertions(+) diff --git a/src/vdagent/vdagent.c b/src/vdagent/vdagent.c index f7c8b72..d1af57f 100644 --- a/src/vdagent/vdagent.c +++ b/src/vdagent/vdagent.c @@ -53,6 +53,7 @@ typedef struct VDAgent { struct vdagent_file_xfers *xfers; struct udscs_connection *conn; GIOChannel *x11_channel; + GHashTable *graphics_display_infos; GMainLoop *loop; } VDAgent; @@ -95,6 +96,16 @@ static GOptionEntry entries[] = { { NULL } }; +typedef struct GraphicsDisplayInfo { + char device_address[256]; + uint32_t device_display_id; +} GraphicsDisplayInfo; + +static void graphics_display_info_destroy(gpointer gdi) +{ + g_free(gdi); +} + /** * xfer_get_download_directory * @@ -159,6 +170,55 @@ static gboolean vdagent_finalize_file_xfer(VDAgent *agent) return TRUE; } +static void vdagent_handle_graphics_device_info(VDAgent *agent, uint8_t *data, size_t size) +{ + VDAgentGraphicsDeviceInfos *graphics_device_infos = (VDAgentGraphicsDeviceInfos *)data; + VDAgentGraphicsDeviceInfo *graphics_device_info = graphics_device_infos->graphics_device_infos; + + void *buffer_end = data + size; + + syslog(LOG_INFO, "Received Graphics Device Info:"); + + for (size_t i = 0; i < graphics_device_infos->count; ++i) { + if ((void*) graphics_device_info > buffer_end || + (void*) (&graphics_device_info->device_address + + graphics_device_info->device_address_len) > buffer_end) { + syslog(LOG_ERR, "Malformed graphics_display_info message, " + "extends beyond the end of the buffer"); + break; + } + + syslog(LOG_INFO, " channel_id: %u monitor_id: %u device_address: %s, " + "device_display_id: %u", + graphics_device_info->channel_id, + graphics_device_info->monitor_id, + graphics_device_info->device_address, + graphics_device_info->device_display_id); + + GraphicsDisplayInfo *value = g_malloc(sizeof(GraphicsDisplayInfo)); + + size_t device_address_len = graphics_device_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*) graphics_device_info->device_address, + device_address_len); + value->device_address[device_address_len] = '\0'; // make sure the string is terminated + value->device_display_id = graphics_device_info->device_display_id; + + g_hash_table_insert(agent->graphics_display_infos, + GUINT_TO_POINTER(graphics_device_info->channel_id + graphics_device_info->monitor_id), + value); + + graphics_device_info = (VDAgentGraphicsDeviceInfo*) ((char*) graphics_device_info + + sizeof(VDAgentGraphicsDeviceInfo) + graphics_device_info->device_address_len); + } +} + static void vdagent_quit_loop(VDAgent *agent) { /* other GMainLoop(s) might be running, quit them before agent->loop */ @@ -243,6 +303,9 @@ static void daemon_read_complete(struct udscs_connection **connp, ((VDAgentFileXferDataMessage *)data)->id); } break; + case VDAGENTD_GRAPHICS_DEVICE_INFO: + vdagent_handle_graphics_device_info(agent, data, header->size); + break; case VDAGENTD_CLIENT_DISCONNECTED: vdagent_clipboards_release_all(agent->clipboards); if (vdagent_finalize_file_xfer(agent)) { @@ -345,6 +408,11 @@ static VDAgent *vdagent_new(void) g_unix_signal_add(SIGHUP, vdagent_signal_handler, agent); g_unix_signal_add(SIGTERM, vdagent_signal_handler, agent); + agent->graphics_display_infos = g_hash_table_new_full(&g_direct_hash, + &g_direct_equal, + NULL, + &graphics_display_info_destroy); + return agent; } @@ -359,6 +427,7 @@ static void vdagent_destroy(VDAgent *agent) g_clear_pointer(&agent->x11_channel, g_io_channel_unref); g_clear_pointer(&agent->loop, g_main_loop_unref); + g_hash_table_destroy(agent->graphics_display_infos); g_free(agent); } 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 99683da..7c37358 100644 --- a/src/vdagentd/vdagentd.c +++ b/src/vdagentd/vdagentd.c @@ -375,6 +375,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 */ @@ -393,6 +403,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, @@ -477,6 +488,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); @@ -550,6 +562,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.19.1 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel