67b8b9fd9d
Also add patches for the included copy of spice-protocol.
91 lines
3.6 KiB
Diff
91 lines
3.6 KiB
Diff
From 83b3e3f20dbd7c87e2d7cace68d99138c09ed6ab Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?S=C3=B8ren=20Sandmann=20Pedersen?= <ssp@redhat.com>
|
|
Date: Thu, 23 Aug 2012 22:04:24 -0400
|
|
Subject: [PATCH 2/5] Add new set_client_capabilities() interface to QXLInstance
|
|
|
|
A new interface
|
|
|
|
set_client_capabilities (QXLInstance *qin,
|
|
uint8_t client_present,
|
|
uint8_t caps[58]);
|
|
|
|
is added to QXLInstance, and spice server is changed to call it
|
|
whenever a client connects or disconnects. The QXL device in response
|
|
is expected to update the client capability bits in the ROM of the
|
|
device and raise the QXL_INTERRUPT_CLIENT interrupt.
|
|
|
|
There is a potential race condition in the case where a client
|
|
disconnects and a new client with fewer capabilities connects. There
|
|
may be commands in the ring that the new client can't handle. This
|
|
case is handled by first changing the capability bits, then processing
|
|
all commands in the ring, and then start forwarding commands to the
|
|
new client. As long as the guest obeys the capability bits, the new
|
|
client will never see anything it doesn't understand.
|
|
---
|
|
server/red_worker.c | 24 ++++++++++++++++++++++++
|
|
server/spice.h | 3 +++
|
|
2 files changed, 27 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/server/red_worker.c b/server/red_worker.c
|
|
index eee9915..1e301c4 100644
|
|
--- a/server/red_worker.c
|
|
+++ b/server/red_worker.c
|
|
@@ -10344,6 +10344,23 @@ static void handle_new_display_channel(RedWorker *worker, RedClient *client, Red
|
|
spice_info("jpeg %s", display_channel->enable_jpeg ? "enabled" : "disabled");
|
|
spice_info("zlib-over-glz %s", display_channel->enable_zlib_glz_wrap ? "enabled" : "disabled");
|
|
|
|
+ if (worker->qxl->st->qif->set_client_capabilities) {
|
|
+ RedChannelClient *rcc = (RedChannelClient *)dcc;
|
|
+ uint8_t caps[58] = { 0 };
|
|
+
|
|
+#define SET_CAP(a,c) \
|
|
+ ((a)[(c) / 8] |= (1 << ((c) % 8)))
|
|
+
|
|
+ if (red_channel_client_test_remote_cap(rcc, SPICE_DISPLAY_CAP_SIZED_STREAM))
|
|
+ SET_CAP(caps, SPICE_DISPLAY_CAP_SIZED_STREAM);
|
|
+ if (red_channel_client_test_remote_cap(rcc, SPICE_DISPLAY_CAP_MONITORS_CONFIG))
|
|
+ SET_CAP(caps, SPICE_DISPLAY_CAP_MONITORS_CONFIG);
|
|
+ if (red_channel_client_test_remote_cap(rcc, SPICE_DISPLAY_CAP_COMPOSITE))
|
|
+ SET_CAP(caps, SPICE_DISPLAY_CAP_COMPOSITE);
|
|
+
|
|
+ worker->qxl->st->qif->set_client_capabilities(worker->qxl, TRUE, caps);
|
|
+ }
|
|
+
|
|
// todo: tune level according to bandwidth
|
|
display_channel->zlib_level = ZLIB_DEFAULT_COMPRESSION_LEVEL;
|
|
red_display_client_init_streams(dcc);
|
|
@@ -11198,9 +11215,16 @@ void handle_dev_display_disconnect(void *opaque, void *payload)
|
|
{
|
|
RedWorkerMessageDisplayDisconnect *msg = payload;
|
|
RedChannelClient *rcc = msg->rcc;
|
|
+ RedWorker *worker = opaque;
|
|
|
|
spice_info("disconnect display client");
|
|
spice_assert(rcc);
|
|
+
|
|
+ if (worker->qxl->st->qif->set_client_capabilities) {
|
|
+ uint8_t caps[58] = { 0 };
|
|
+ worker->qxl->st->qif->set_client_capabilities(worker->qxl, FALSE, caps);
|
|
+ }
|
|
+
|
|
red_channel_client_disconnect(rcc);
|
|
}
|
|
|
|
diff --git a/server/spice.h b/server/spice.h
|
|
index fdcfbb7..6114407 100644
|
|
--- a/server/spice.h
|
|
+++ b/server/spice.h
|
|
@@ -239,6 +239,9 @@ struct QXLInterface {
|
|
void (*update_area_complete)(QXLInstance *qin, uint32_t surface_id,
|
|
struct QXLRect *updated_rects,
|
|
uint32_t num_updated_rects);
|
|
+ void (*set_client_capabilities)(QXLInstance *qin,
|
|
+ uint8_t client_present,
|
|
+ uint8_t caps[58]);
|
|
};
|
|
|
|
struct QXLInstance {
|
|
--
|
|
1.7.4
|
|
|