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> Acked-by: Jonathon Jongsma <jjongsma@xxxxxxxxxx> --- configure.ac | 2 +- src/vdagent/vdagent.c | 3 ++ src/vdagent/x11-priv.h | 1 + src/vdagent/x11-randr.c | 65 ++++++++++++++++++++++++++++++++++++ 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 +++++++++ 9 files changed, 102 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 7cb44db..7faebfd 100644 --- a/configure.ac +++ b/configure.ac @@ -102,7 +102,7 @@ AC_ARG_ENABLE([static-uinput], PKG_CHECK_MODULES([GLIB2], [glib-2.0 >= 2.34]) PKG_CHECK_MODULES(X, [xfixes xrandr >= 1.3 xinerama x11]) -PKG_CHECK_MODULES(SPICE, [spice-protocol >= 0.12.13]) +PKG_CHECK_MODULES(SPICE, [spice-protocol >= 0.12.16]) PKG_CHECK_MODULES(ALSA, [alsa >= 1.0.22]) PKG_CHECK_MODULES([DBUS], [dbus-1]) diff --git a/src/vdagent/vdagent.c b/src/vdagent/vdagent.c index 90247f9..7cc6287 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..405fca9 100644 --- a/src/vdagent/x11-randr.c +++ b/src/vdagent/x11-randr.c @@ -727,6 +727,71 @@ 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)); + value->device_address[0] = '\0'; + + 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); + + if (device_address_len > 0) { + value->device_address[device_address_len - 1] = '\0'; // make sure the string is terminated + } else { + syslog(LOG_WARNING, "Zero length device_address received for channel_id: %u, monitor_id: %u", + device_display_info->channel_id, device_display_info->monitor_id); + } + + 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 02b4858..ab822f8 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 197f325..0bc2689 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 d0f771a..ec8defc 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 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel