Acked-by: Jonathon Jongsma <jjongsma@xxxxxxxxxx> On Wed, 2019-01-16 at 13:52 +0100, Lukáš Hrázký wrote: > 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 | 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 +++++++++ > 8 files changed, 101 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, > ((VDAgentFileXferDataM > essage *)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 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, _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel