The StreamInfo message contains the guest (xrandr) output ID of the monitor that is being streamed. It will later be passed to the client in the MonitorsConfig message. --- server/red-stream-device.c | 43 ++++++++++++++++++++++++++++++++++++-- server/stream-channel.c | 14 +++++++++++-- server/stream-channel.h | 1 + spice-common | 2 +- 4 files changed, 55 insertions(+), 5 deletions(-) diff --git a/server/red-stream-device.c b/server/red-stream-device.c index da6d3094..90ab99d9 100644 --- a/server/red-stream-device.c +++ b/server/red-stream-device.c @@ -34,6 +34,7 @@ struct StreamDevice { uint8_t hdr_pos; union { StreamMsgFormat format; + StreamMsgInfo info; StreamMsgCapabilities capabilities; StreamMsgCursorSet cursor_set; StreamMsgCursorMove cursor_move; @@ -63,8 +64,8 @@ static void char_device_set_state(RedCharDevice *char_dev, int state); typedef bool StreamMsgHandler(StreamDevice *dev, SpiceCharDeviceInstance *sin) SPICE_GNUC_WARN_UNUSED_RESULT; -static StreamMsgHandler handle_msg_format, handle_msg_data, handle_msg_cursor_set, - handle_msg_cursor_move, handle_msg_capabilities; +static StreamMsgHandler handle_msg_format, handle_msg_info, + handle_msg_data, handle_msg_cursor_set, handle_msg_cursor_move, handle_msg_capabilities; static bool handle_msg_invalid(StreamDevice *dev, SpiceCharDeviceInstance *sin, const char *error_msg) SPICE_GNUC_WARN_UNUSED_RESULT; @@ -161,6 +162,13 @@ stream_device_partial_read(StreamDevice *dev, SpiceCharDeviceInstance *sin) case STREAM_TYPE_CAPABILITIES: handled = handle_msg_capabilities(dev, sin); break; + case STREAM_TYPE_INFO: + if (dev->hdr.size != sizeof(StreamMsgInfo)) { + handled = handle_msg_invalid(dev, sin, "Wrong size for StreamMsgInfo"); + } else { + handled = handle_msg_info(dev, sin); + } + break; default: handled = handle_msg_invalid(dev, sin, "Invalid message type"); break; @@ -264,6 +272,37 @@ handle_msg_format(StreamDevice *dev, SpiceCharDeviceInstance *sin) return true; } +static bool +handle_msg_info(StreamDevice *dev, SpiceCharDeviceInstance *sin) +{ + SpiceCharDeviceInterface *sif = spice_char_device_get_interface(sin); + + if (spice_extra_checks) { + spice_assert(dev->hdr_pos >= sizeof(StreamDevHeader)); + spice_assert(dev->hdr.type == STREAM_TYPE_INFO); + } + + int n = sif->read(sin, dev->msg->buf + dev->msg_pos, sizeof(StreamMsgInfo) - dev->msg_pos); + if (n < 0) { + return handle_msg_invalid(dev, sin, NULL); + } + + dev->msg_pos += n; + + if (dev->msg_pos < sizeof(StreamMsgInfo)) { + return false; + } + + dev->msg->info.output_id = GUINT32_FROM_LE(dev->msg->info.output_id); + if (dev->msg->info.output_id < 1) { + return handle_msg_invalid(dev, sin, "StreamMsgInfo.output_id has to be greater than 0."); + } + + stream_channel_handle_stream_info(dev->stream_channel, &dev->msg->info); + + return true; +} + static bool handle_msg_capabilities(StreamDevice *dev, SpiceCharDeviceInstance *sin) { diff --git a/server/stream-channel.c b/server/stream-channel.c index 680fa3d1..138f685d 100644 --- a/server/stream-channel.c +++ b/server/stream-channel.c @@ -71,6 +71,8 @@ struct StreamChannel { int stream_id; /* size of the current video stream */ unsigned width, height; + /* the guest (xrandr) output ID for monitors_config */ + uint32_t output_id; StreamQueueStat queue_stat; @@ -198,9 +200,9 @@ marshall_monitors_config(RedChannelClient *rcc, StreamChannel *channel, SpiceMar } msg = { { 1, 1, }, { - // monitor ID. These IDs are allocated per channel starting from 0 - 0, + 0, // monitor ID. These IDs are allocated per channel starting from 0 PRIMARY_SURFACE_ID, + channel->output_id, // The guest (xrandr) output ID from the streaming agent channel->width, channel->height, 0, 0, 0 // flags @@ -516,6 +518,14 @@ stream_channel_change_format(StreamChannel *channel, const StreamMsgFormat *fmt) red_channel_pipes_add_type(red_channel, RED_PIPE_ITEM_TYPE_STREAM_ACTIVATE_REPORT); } +void +stream_channel_handle_stream_info(StreamChannel *channel, const StreamMsgInfo *info) +{ + channel->output_id = info->output_id; + RedChannel *red_channel = RED_CHANNEL(channel); + red_channel_pipes_add_type(red_channel, RED_PIPE_ITEM_TYPE_MONITORS_CONFIG); +} + static inline void stream_channel_update_queue_stat(StreamChannel *channel, int32_t num_diff, int32_t size_diff) diff --git a/server/stream-channel.h b/server/stream-channel.h index e8bec80b..83c73012 100644 --- a/server/stream-channel.h +++ b/server/stream-channel.h @@ -60,6 +60,7 @@ struct StreamMsgStartStop; void stream_channel_change_format(StreamChannel *channel, const struct StreamMsgFormat *fmt); +void stream_channel_handle_stream_info(StreamChannel *channel, const struct StreamMsgInfo *info); void stream_channel_send_data(StreamChannel *channel, const void *data, size_t size, uint32_t mm_time); diff --git a/spice-common b/spice-common index 4c2d0e97..151fd26c 160000 --- a/spice-common +++ b/spice-common @@ -1 +1 @@ -Subproject commit 4c2d0e977272c5540634d24f485dd64c424f6748 +Subproject commit 151fd26ce7032c062c097deabfd003549ebb3cc8 -- 2.17.1 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel