[Spice-devel] [PATCH vd_agent 8/8 v3] Receive the graphics_device_info message
Jonathon Jongsma
jjongsma at redhat.com
Thu Jan 17 20:36:33 UTC 2019
Acked-by: Jonathon Jongsma <jjongsma at redhat.com>
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 at redhat.com>
> ---
> 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,
More information about the Spice-devel
mailing list