From patchwork Mon Jul 27 18:04:36 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amit Shah X-Patchwork-Id: 37593 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n6RI54K3004530 for ; Mon, 27 Jul 2009 18:05:04 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752638AbZG0SFA (ORCPT ); Mon, 27 Jul 2009 14:05:00 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1751882AbZG0SFA (ORCPT ); Mon, 27 Jul 2009 14:05:00 -0400 Received: from mx2.redhat.com ([66.187.237.31]:60490 "EHLO mx2.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751426AbZG0SFA (ORCPT ); Mon, 27 Jul 2009 14:05:00 -0400 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n6RI4vKn031403; Mon, 27 Jul 2009 14:04:57 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n6RI4uRk017742; Mon, 27 Jul 2009 14:04:57 -0400 Received: from localhost (vpn-13-206.rdu.redhat.com [10.11.13.206]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id n6RI4s2Q028007; Mon, 27 Jul 2009 14:04:55 -0400 From: Amit Shah To: virtualization@lists.linux-foundation.org Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org, Amit Shah Subject: [PATCH 3/3] virtio-serial: vnc: support for sending / receiving guest clipboard Date: Mon, 27 Jul 2009 23:34:36 +0530 Message-Id: <1248717876-17630-5-git-send-email-amit.shah@redhat.com> In-Reply-To: <1248717876-17630-4-git-send-email-amit.shah@redhat.com> References: <1248717876-17630-1-git-send-email-amit.shah@redhat.com> <1248717876-17630-2-git-send-email-amit.shah@redhat.com> <1248717876-17630-3-git-send-email-amit.shah@redhat.com> <1248717876-17630-4-git-send-email-amit.shah@redhat.com> X-Scanned-By: MIMEDefang 2.58 on 172.16.27.26 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org - Send ServerCutText message over to the vnc client from qemu on every write to the clipboard port via virtio-serial - On receiving ClientCutText message send over the data to the guest via virtio-serial. Signed-off-by: Amit Shah --- hw/virtio-serial.c | 15 +++++++++++++++ hw/virtio-serial.h | 4 ++++ vnc.c | 24 ++++++++++++++++++++++++ vnc.h | 2 ++ 4 files changed, 45 insertions(+), 0 deletions(-) diff --git a/hw/virtio-serial.c b/hw/virtio-serial.c index d77af9b..95c715f 100644 --- a/hw/virtio-serial.c +++ b/hw/virtio-serial.c @@ -20,6 +20,7 @@ #include "pci.h" #include "monitor.h" #include "qemu-char.h" +#include "vnc.h" #include "virtio.h" #include "virtio-serial.h" @@ -118,6 +119,10 @@ static size_t flush_buf(uint32_t id, const uint8_t *buf, size_t len) VirtIOSerialPort *port; size_t write_len = 0; + if (id == VIRTIO_SERIAL_CLIPBOARD_PORT && is_vnc_active()) { + vnc_clipboard_data_from_guest(buf, len); + return len; + } port = get_port_from_id(id); if (port && port->hd) { write_len = qemu_chr_write(port->hd, buf, len); @@ -211,6 +216,16 @@ static void write_to_port(VirtIOSerialPort *port, virtio_notify(port->virtserial->vdev, vq); } +void virtio_serial_send_clipboard_to_guest(const uint8_t *buf, size_t len) +{ + VirtIOSerialPort *port = get_port_from_id(VIRTIO_SERIAL_CLIPBOARD_PORT); + + if (!port) { + return; + } + write_to_port(port, buf, len); +} + /* Readiness of the guest to accept data on a port */ static int cons_can_read(void *opaque) { diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h index 08c4b51..44238f6 100644 --- a/hw/virtio-serial.h +++ b/hw/virtio-serial.h @@ -18,6 +18,9 @@ #define VIRTIO_ID_SERIAL 7 #define VIRTIO_SERIAL_BAD_ID (~(uint32_t)0) +/* Port number to function mapping */ +#define VIRTIO_SERIAL_CLIPBOARD_PORT 3 + struct virtio_serial_config { uint32_t max_nr_ports; @@ -32,5 +35,6 @@ struct virtio_serial_config void *virtio_serial_new_port(PCIDevice *dev, int idx); void virtio_serial_monitor_command(Monitor *mon, const char *command, const char *param); +void virtio_serial_send_clipboard_to_guest(const uint8_t *buf, size_t len); #endif diff --git a/vnc.c b/vnc.c index e4e78dc..271b64e 100644 --- a/vnc.c +++ b/vnc.c @@ -29,6 +29,7 @@ #include "qemu_socket.h" #include "qemu-timer.h" #include "acl.h" +#include "hw/virtio-serial.h" #define VNC_REFRESH_INTERVAL (1000 / 30) @@ -671,6 +672,28 @@ static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, i vnc_flush(vs); } +void vnc_clipboard_data_from_guest(const uint8_t *buf, size_t len) +{ + VncState *vs; + VncDisplay *vd; + DisplayState *ds; + + ds = vnc_display->ds; + vd = ds->opaque; + + for (vs = vd->clients; vs; vs = vs->next) { + vnc_write_u8(vs, 3); /* ServerCutText */ + vnc_write_u8(vs, 0); /* Padding */ + vnc_write_u8(vs, 0); /* Padding */ + vnc_write_u8(vs, 0); /* Padding */ + vnc_write_u32(vs, len); + while (len--) { + vnc_write_u8(vs, *(buf++)); + } + vnc_flush(vs); + } +} + static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h) { VncDisplay *vd = ds->opaque; @@ -1239,6 +1262,7 @@ uint32_t read_u32(uint8_t *data, size_t offset) static void client_cut_text(VncState *vs, size_t len, uint8_t *text) { + virtio_serial_send_clipboard_to_guest(text, len); } static void check_pointer_type_change(VncState *vs, int absolute) diff --git a/vnc.h b/vnc.h index 9739c35..00afdbb 100644 --- a/vnc.h +++ b/vnc.h @@ -303,6 +303,8 @@ int vnc_client_io_error(VncState *vs, int ret, int last_errno); void start_client_init(VncState *vs); void start_auth_vnc(VncState *vs); +void vnc_clipboard_data_from_guest(const uint8_t *buf, size_t len); + /* Buffer management */ void buffer_reserve(Buffer *buffer, size_t len); int buffer_empty(Buffer *buffer);