Commit 56c2d297 authored by Lukáš Hrázký's avatar Lukáš Hrázký

Receive the graphics_device_info message

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ý's avatarLukáš Hrázký <lhrazky@redhat.com>
Acked-by: default avatarJonathon Jongsma <jjongsma@redhat.com>
parent 97aa39a8
Pipeline #16770 passed with stage
in 11 minutes and 59 seconds
......@@ -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])
......
......@@ -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)) {
......
......@@ -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 *);
......
......@@ -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.
*
......
......@@ -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);
......
......@@ -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
......@@ -36,6 +36,7 @@ static const char * const vdagentd_messages[] = {
"file xfer data",
"file xfer disable",
"client disconnected",
"graphics device info",
};
#endif
......@@ -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 */
};
......
......@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment