Patchwork Add new set_client_capabilities() interface to QXLInstance

login
register
mail settings
Submitter Søren Sandmann
Date Aug. 27, 2012, 5:20 p.m.
Message ID <1346088041-17062-3-git-send-email-sandmann@cs.au.dk>
Download mbox | patch
Permalink /patch/180274/
State New
Headers show

Comments

Søren Sandmann - Aug. 27, 2012, 5:20 p.m.
From: Søren Sandmann Pedersen <ssp@redhat.com>

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.
---
 server/red_worker.c |   24 ++++++++++++++++++++++++
 server/spice.h      |    3 +++
 2 files changed, 27 insertions(+), 0 deletions(-)

Patch

diff --git a/server/red_worker.c b/server/red_worker.c
index bd6de1c..6f97d6b 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -10289,6 +10289,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);
@@ -11137,9 +11154,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 3d70ec7..c53c044 100644
--- a/server/spice.h
+++ b/server/spice.h
@@ -237,6 +237,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 {