From patchwork Mon Sep 3 17:53:52 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?S=C3=B8ren_Sandmann?= X-Patchwork-Id: 181402 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 5CABC2C0093 for ; Tue, 4 Sep 2012 03:51:23 +1000 (EST) Received: from localhost ([::1]:35481 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T8anx-0000kG-DV for incoming@patchwork.ozlabs.org; Mon, 03 Sep 2012 13:51:21 -0400 Received: from eggs.gnu.org ([208.118.235.92]:45901) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T8ani-0000ja-94 for qemu-devel@nongnu.org; Mon, 03 Sep 2012 13:51:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1T8and-0003X0-R9 for qemu-devel@nongnu.org; Mon, 03 Sep 2012 13:51:06 -0400 Received: from mx1.redhat.com ([209.132.183.28]:25816) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T8and-0003Vv-Hw for qemu-devel@nongnu.org; Mon, 03 Sep 2012 13:51:01 -0400 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q83Hp00f030805 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 3 Sep 2012 13:51:00 -0400 Received: from dhcp-100-3-184.bos.redhat.com (dhcp-189-4.bos.redhat.com [10.16.189.4]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q83Howjb024642; Mon, 3 Sep 2012 13:50:59 -0400 From: =?UTF-8?q?S=C3=B8ren=20Sandmann?= To: spice-devel@freedesktop.org, qemu-devel@nongnu.org Date: Mon, 3 Sep 2012 13:53:52 -0400 Message-Id: <1346694835-23590-2-git-send-email-sandmann@cs.au.dk> In-Reply-To: <1346694835-23590-1-git-send-email-sandmann@cs.au.dk> References: <1346694835-23590-1-git-send-email-sandmann@cs.au.dk> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 X-MIME-Autoconverted: from 8bit to quoted-printable by mx1.redhat.com id q83Hp00f030805 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: =?UTF-8?q?S=C3=B8ren=20Sandmann=20Pedersen?= Subject: [Qemu-devel] [PATCH 2/5] Add new set_client_capabilities() interface to QXLInstance X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Søren Sandmann Pedersen 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 133ba94..60b5471 100644 --- a/server/red_worker.c +++ b/server/red_worker.c @@ -10359,6 +10359,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); @@ -11213,9 +11230,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 0dc9d05..9d65efa 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 {