All of lore.kernel.org
 help / color / mirror / Atom feed
From: Brian Kress <kressb@moose.net>
To: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH] Support multiple VNC clients
Date: Sat, 14 Feb 2009 20:13:29 -0500	[thread overview]
Message-ID: <49976C39.10301@moose.net> (raw)
In-Reply-To: <499740A8.3090502@codemonkey.ws>

[-- Attachment #1: Type: text/plain, Size: 762 bytes --]

Anthony Liguori wrote:
> Brian Kress wrote:
>> Attached is a patch that allows qemu to support multiple vnc 
>> clients.  Each client can have their own
>> VNC encodings and VNC state.
>>
>> General idea:
>>
>> Change structure associated with a display from VncState to a new 
>> structure VncDisplay. Remove client specific fields from VncDisplay.
>> Remove display specific fields from VncState.
>> Maintain a linked list of VncStates per VncDisplay structure, update 
>> as necessary.
>> When updates/resizes/copies come in from the hardware, dispatch to 
>> all clients.
>>
>>
>> Patch is against current SVN (6618)
>> Any ideas/suggestions/comments/flames appreciated.
>
> Can you add a Signed-off-by line?
>
> The patch looks good to me.

    Attached.



[-- Attachment #2: patch.vnc --]
[-- Type: text/plain, Size: 22298 bytes --]

Signed-off-by: Brian Kress <kressb@moose.net>

Index: vnc.c
===================================================================
--- vnc.c	(revision 6618)
+++ vnc.c	(working copy)
@@ -90,12 +90,35 @@
 
 #define VNC_AUTH_CHALLENGE_SIZE 16
 
+typedef struct VncDisplay VncDisplay;
+
+struct VncDisplay
+{
+    int lsock;
+    DisplayState *ds;
+    VncState *clients;
+    kbd_layout_t *kbd_layout;
+
+    char *display;
+    char *password;
+    int auth;
+#ifdef CONFIG_VNC_TLS
+    int subauth;
+    int x509verify;
+
+    char *x509cacert;
+    char *x509cacrl;
+    char *x509cert;
+    char *x509key;
+#endif
+};
+
 struct VncState
 {
     QEMUTimer *timer;
-    int lsock;
     int csock;
     DisplayState *ds;
+    VncDisplay *vd;
     int need_update;
     uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
     char *old_data;
@@ -111,18 +134,6 @@
     int major;
     int minor;
 
-    char *display;
-    char *password;
-    int auth;
-#ifdef CONFIG_VNC_TLS
-    int subauth;
-    int x509verify;
-
-    char *x509cacert;
-    char *x509cacrl;
-    char *x509cert;
-    char *x509key;
-#endif
     char challenge[VNC_AUTH_CHALLENGE_SIZE];
 
 #ifdef CONFIG_VNC_TLS
@@ -132,7 +143,6 @@
 
     Buffer output;
     Buffer input;
-    kbd_layout_t *kbd_layout;
     /* current output mode information */
     VncWritePixels *write_pixels;
     VncSendHextileTile *send_hextile_tile;
@@ -149,21 +159,23 @@
     Buffer zlib;
     Buffer zlib_tmp;
     z_stream zlib_stream[4];
+
+    VncState *next;
 };
 
-static VncState *vnc_state; /* needed for info vnc */
+static VncDisplay *vnc_display; /* needed for info vnc */
 static DisplayChangeListener *dcl;
 
 void do_info_vnc(void)
 {
-    if (vnc_state == NULL || vnc_state->display == NULL)
+    if (vnc_display == NULL || vnc_display->display == NULL)
 	term_printf("VNC server disabled\n");
     else {
 	term_printf("VNC server active on: ");
-	term_print_filename(vnc_state->display);
+	term_print_filename(vnc_display->display);
 	term_printf("\n");
 
-	if (vnc_state->csock == -1)
+	if (vnc_display->clients == NULL)
 	    term_printf("No client connected\n");
 	else
 	    term_printf("Client connected\n");
@@ -190,7 +202,7 @@
 static void vnc_update_client(void *opaque);
 static void vnc_client_read(void *opaque);
 
-static void vnc_colordepth(DisplayState *ds);
+static void vnc_colordepth(VncState *vs);
 
 static inline void vnc_set_bit(uint32_t *d, int k)
 {
@@ -233,9 +245,8 @@
     return 0;
 }
 
-static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
+static void vnc_update(VncState *vs, int x, int y, int w, int h)
 {
-    VncState *vs = ds->opaque;
     int i;
 
     h += y;
@@ -257,6 +268,16 @@
 	    vnc_set_bit(vs->dirty_row[y], (x + i) / 16);
 }
 
+static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
+{
+    VncDisplay *vd = ds->opaque;
+    VncState *vs = vd->clients;
+    while (vs != NULL) {
+        vnc_update(vs, x, y, w, h);
+        vs = vs->next;
+    }
+}
+
 static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
 				   int32_t encoding)
 {
@@ -301,10 +322,11 @@
     buffer->offset += len;
 }
 
-static void vnc_dpy_resize(DisplayState *ds)
+static void vnc_resize(VncState *vs)
 {
+    DisplayState *ds = vs->ds;
+
     int size_changed;
-    VncState *vs = ds->opaque;
 
     vs->old_data = qemu_realloc(vs->old_data, ds_get_linesize(ds) * ds_get_height(ds));
 
@@ -315,7 +337,7 @@
 
     if (ds_get_bytes_per_pixel(ds) != vs->serverds.pf.bytes_per_pixel)
         console_color_init(ds);
-    vnc_colordepth(ds);
+    vnc_colordepth(vs);
     size_changed = ds_get_width(ds) != vs->serverds.width ||
                    ds_get_height(ds) != vs->serverds.height;
     vs->serverds = *(ds->surface);
@@ -334,6 +356,16 @@
     memset(vs->old_data, 42, ds_get_linesize(vs->ds) * ds_get_height(vs->ds));
 }
 
+static void vnc_dpy_resize(DisplayState *ds)
+{
+    VncDisplay *vd = ds->opaque;
+    VncState *vs = vd->clients;
+    while (vs != NULL) {
+        vnc_resize(vs);
+        vs = vs->next;
+    }
+}
+
 /* fastest code */
 static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size)
 {
@@ -599,10 +631,8 @@
     }
 }
 
-static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
+static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
 {
-    VncState *vs = ds->opaque;
-
     vnc_update_client(vs);
 
     vnc_write_u8(vs, 0);  /* msg id */
@@ -614,6 +644,19 @@
     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;
+    VncState *vs = vd->clients;
+    while (vs != NULL) {
+        if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT))
+            vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
+        else /* TODO */
+            vnc_update(vs, dst_x, dst_y, w, h);
+        vs = vs->next;
+    }
+}
+
 static int find_dirty_height(VncState *vs, int y, int last_x, int x)
 {
     int h;
@@ -632,7 +675,6 @@
 static void vnc_update_client(void *opaque)
 {
     VncState *vs = opaque;
-
     if (vs->need_update && vs->csock != -1) {
 	int y;
 	uint8_t *row;
@@ -725,14 +767,6 @@
 
 }
 
-static int vnc_listen_poll(void *opaque)
-{
-    VncState *vs = opaque;
-    if (vs->csock == -1)
-	return 1;
-    return 0;
-}
-
 /* audio */
 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
 {
@@ -817,19 +851,35 @@
 	VNC_DEBUG("Closing down client sock %d %d\n", ret, ret < 0 ? last_errno : 0);
 	qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
 	closesocket(vs->csock);
-	vs->csock = -1;
-	dcl->idle = 1;
-	buffer_reset(&vs->input);
-	buffer_reset(&vs->output);
-	vs->need_update = 0;
+        qemu_del_timer(vs->timer);
+        qemu_free_timer(vs->timer);
+        if (vs->input.buffer) qemu_free(vs->input.buffer);
+        if (vs->output.buffer) qemu_free(vs->output.buffer);
 #ifdef CONFIG_VNC_TLS
 	if (vs->tls_session) {
 	    gnutls_deinit(vs->tls_session);
 	    vs->tls_session = NULL;
 	}
-	vs->wiremode = VNC_WIREMODE_CLEAR;
 #endif /* CONFIG_VNC_TLS */
         audio_del(vs);
+
+        VncState *p, *parent = NULL;
+        for (p = vs->vd->clients; p != NULL; p = p->next) {
+            if (p == vs) {
+                if (parent)
+                    parent->next = p->next;
+                else
+                    vs->vd->clients = p->next;
+                break;
+            }
+            parent = p;
+        }
+        if (!vs->vd->clients)
+	    dcl->idle = 1;
+
+        qemu_free(vs->old_data);
+        qemu_free(vs);
+  
 	return 0;
     }
     return ret;
@@ -1095,8 +1145,8 @@
 
 static void press_key(VncState *vs, int keysym)
 {
-    kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) & 0x7f);
-    kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80);
+    kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) & 0x7f);
+    kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) | 0x80);
 }
 
 static void do_key_event(VncState *vs, int down, int keycode, int sym)
@@ -1129,12 +1179,12 @@
         break;
     }
 
-    if (keycode_is_keypad(vs->kbd_layout, keycode)) {
+    if (keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
         /* If the numlock state needs to change then simulate an additional
            keypress before sending this one.  This will happen if the user
            toggles numlock away from the VNC window.
         */
-        if (keysym_is_numlock(vs->kbd_layout, sym & 0xFFFF)) {
+        if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
             if (!vs->modifiers_state[0x45]) {
                 vs->modifiers_state[0x45] = 1;
                 press_key(vs, 0xff7f);
@@ -1207,7 +1257,7 @@
     if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
 	sym = sym - 'A' + 'a';
 
-    keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
+    keycode = keysym2scancode(vs->vd->kbd_layout, sym & 0xFFFF);
     do_key_event(vs, down, keycode, sym);
 }
 
@@ -1279,7 +1329,6 @@
     vs->tight_compression = 9;
     vs->tight_quality = 9;
     vs->absolute = -1;
-    dcl->dpy_copy = NULL;
 
     for (i = n_encodings - 1; i >= 0; i--) {
         enc = encodings[i];
@@ -1288,7 +1337,7 @@
             vs->vnc_encoding = enc;
             break;
         case VNC_ENCODING_COPYRECT:
-            dcl->dpy_copy = vnc_copy;
+            vs->features |= VNC_FEATURE_COPYRECT_MASK;
             break;
         case VNC_ENCODING_HEXTILE:
             vs->features |= VNC_FEATURE_HEXTILE_MASK;
@@ -1432,17 +1481,15 @@
     /* We don't have to do anything */
 }
 
-static void vnc_colordepth(DisplayState *ds)
+static void vnc_colordepth(VncState *vs)
 {
-    struct VncState *vs = ds->opaque;
-
-    if (vs->csock != -1 && vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
+    if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
         /* Sending a WMVi message to notify the client*/
         vnc_write_u8(vs, 0);  /* msg id */
         vnc_write_u8(vs, 0);
         vnc_write_u16(vs, 1); /* number of rects */
-        vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds),
-                               VNC_ENCODING_WMVi);
+        vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), 
+                               ds_get_height(vs->ds), VNC_ENCODING_WMVi);
         pixel_format_message(vs);
         vnc_flush(vs);
     } else {
@@ -1626,7 +1673,7 @@
     int i, j, pwlen;
     unsigned char key[8];
 
-    if (!vs->password || !vs->password[0]) {
+    if (!vs->vd->password || !vs->vd->password[0]) {
 	VNC_DEBUG("No password configured on server");
 	vnc_write_u32(vs, 1); /* Reject auth */
 	if (vs->minor >= 8) {
@@ -1642,9 +1689,9 @@
     memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
 
     /* Calculate the expected challenge response */
-    pwlen = strlen(vs->password);
+    pwlen = strlen(vs->vd->password);
     for (i=0; i<sizeof(key); i++)
-        key[i] = i<pwlen ? vs->password[i] : 0;
+        key[i] = i<pwlen ? vs->vd->password[i] : 0;
     deskey(key, EN0);
     for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
         des(response+j, response+j);
@@ -1733,15 +1780,15 @@
     gnutls_certificate_credentials_t x509_cred;
     int ret;
 
-    if (!vs->x509cacert) {
+    if (!vs->vd->x509cacert) {
 	VNC_DEBUG("No CA x509 certificate specified\n");
 	return NULL;
     }
-    if (!vs->x509cert) {
+    if (!vs->vd->x509cert) {
 	VNC_DEBUG("No server x509 certificate specified\n");
 	return NULL;
     }
-    if (!vs->x509key) {
+    if (!vs->vd->x509key) {
 	VNC_DEBUG("No server private key specified\n");
 	return NULL;
     }
@@ -1751,7 +1798,7 @@
 	return NULL;
     }
     if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred,
-						      vs->x509cacert,
+						      vs->vd->x509cacert,
 						      GNUTLS_X509_FMT_PEM)) < 0) {
 	VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret));
 	gnutls_certificate_free_credentials(x509_cred);
@@ -1759,17 +1806,17 @@
     }
 
     if ((ret = gnutls_certificate_set_x509_key_file (x509_cred,
-						     vs->x509cert,
-						     vs->x509key,
+						     vs->vd->x509cert,
+						     vs->vd->x509key,
 						     GNUTLS_X509_FMT_PEM)) < 0) {
 	VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret));
 	gnutls_certificate_free_credentials(x509_cred);
 	return NULL;
     }
 
-    if (vs->x509cacrl) {
+    if (vs->vd->x509cacrl) {
 	if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred,
-							vs->x509cacrl,
+							vs->vd->x509cacrl,
 							GNUTLS_X509_FMT_PEM)) < 0) {
 	    VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret));
 	    gnutls_certificate_free_credentials(x509_cred);
@@ -1863,7 +1910,7 @@
 
 static int start_auth_vencrypt_subauth(VncState *vs)
 {
-    switch (vs->subauth) {
+    switch (vs->vd->subauth) {
     case VNC_AUTH_VENCRYPT_TLSNONE:
     case VNC_AUTH_VENCRYPT_X509NONE:
        VNC_DEBUG("Accept TLS auth none\n");
@@ -1877,7 +1924,7 @@
        return start_auth_vnc(vs);
 
     default: /* Should not be possible, but just in case */
-       VNC_DEBUG("Reject auth %d\n", vs->auth);
+       VNC_DEBUG("Reject auth %d\n", vs->vd->auth);
        vnc_write_u8(vs, 1);
        if (vs->minor >= 8) {
            static const char err[] = "Unsupported authentication type";
@@ -1909,7 +1956,7 @@
        return -1;
     }
 
-    if (vs->x509verify) {
+    if (vs->vd->x509verify) {
 	if (vnc_validate_certificate(vs) < 0) {
 	    VNC_DEBUG("Client verification failed\n");
 	    vnc_client_error(vs);
@@ -1934,9 +1981,9 @@
 }
 
 #define NEED_X509_AUTH(vs)			      \
-    ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE ||   \
-     (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC ||    \
-     (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
+    ((vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509NONE ||   \
+     (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509VNC ||    \
+     (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
 
 
 static int vnc_start_tls(struct VncState *vs) {
@@ -2000,7 +2047,7 @@
 		vnc_client_error(vs);
 		return -1;
 	    }
-	    if (vs->x509verify) {
+	    if (vs->vd->x509verify) {
 		VNC_DEBUG("Requesting a client certificate\n");
 		gnutls_certificate_server_set_request (vs->tls_session, GNUTLS_CERT_REQUEST);
 	    }
@@ -2035,7 +2082,7 @@
 {
     int auth = read_u32(data, 0);
 
-    if (auth != vs->subauth) {
+    if (auth != vs->vd->subauth) {
 	VNC_DEBUG("Rejecting auth %d\n", auth);
 	vnc_write_u8(vs, 0); /* Reject auth */
 	vnc_flush(vs);
@@ -2070,10 +2117,10 @@
 	vnc_flush(vs);
 	vnc_client_error(vs);
     } else {
-	VNC_DEBUG("Sending allowed auth %d\n", vs->subauth);
+	VNC_DEBUG("Sending allowed auth %d\n", vs->vd->subauth);
 	vnc_write_u8(vs, 0); /* Accept version */
 	vnc_write_u8(vs, 1); /* Number of sub-auths */
-	vnc_write_u32(vs, vs->subauth); /* The supported auth */
+	vnc_write_u32(vs, vs->vd->subauth); /* The supported auth */
 	vnc_flush(vs);
 	vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
     }
@@ -2095,7 +2142,7 @@
 {
     /* We only advertise 1 auth scheme at a time, so client
      * must pick the one we sent. Verify this */
-    if (data[0] != vs->auth) { /* Reject auth */
+    if (data[0] != vs->vd->auth) { /* Reject auth */
        VNC_DEBUG("Reject auth %d\n", (int)data[0]);
        vnc_write_u32(vs, 1);
        if (vs->minor >= 8) {
@@ -2106,7 +2153,7 @@
        vnc_client_error(vs);
     } else { /* Accept requested auth */
        VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
-       switch (vs->auth) {
+       switch (vs->vd->auth) {
        case VNC_AUTH_NONE:
            VNC_DEBUG("Accept auth none\n");
            if (vs->minor >= 8) {
@@ -2127,7 +2174,7 @@
 #endif /* CONFIG_VNC_TLS */
 
        default: /* Should not be possible, but just in case */
-           VNC_DEBUG("Reject auth %d\n", vs->auth);
+           VNC_DEBUG("Reject auth %d\n", vs->vd->auth);
            vnc_write_u8(vs, 1);
            if (vs->minor >= 8) {
                static const char err[] = "Authentication failed";
@@ -2172,26 +2219,26 @@
 	vs->minor = 3;
 
     if (vs->minor == 3) {
-	if (vs->auth == VNC_AUTH_NONE) {
+	if (vs->vd->auth == VNC_AUTH_NONE) {
             VNC_DEBUG("Tell client auth none\n");
-            vnc_write_u32(vs, vs->auth);
+            vnc_write_u32(vs, vs->vd->auth);
             vnc_flush(vs);
             vnc_read_when(vs, protocol_client_init, 1);
-       } else if (vs->auth == VNC_AUTH_VNC) {
+       } else if (vs->vd->auth == VNC_AUTH_VNC) {
             VNC_DEBUG("Tell client VNC auth\n");
-            vnc_write_u32(vs, vs->auth);
+            vnc_write_u32(vs, vs->vd->auth);
             vnc_flush(vs);
             start_auth_vnc(vs);
        } else {
-            VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
+            VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->vd->auth);
             vnc_write_u32(vs, VNC_AUTH_INVALID);
             vnc_flush(vs);
             vnc_client_error(vs);
        }
     } else {
-	VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
+	VNC_DEBUG("Telling client we support auth %d\n", vs->vd->auth);
 	vnc_write_u8(vs, 1); /* num auth */
-	vnc_write_u8(vs, vs->auth);
+	vnc_write_u8(vs, vs->vd->auth);
 	vnc_read_when(vs, protocol_client_auth, 1);
 	vnc_flush(vs);
     }
@@ -2199,55 +2246,67 @@
     return 0;
 }
 
-static void vnc_connect(VncState *vs)
+static void vnc_connect(VncDisplay *vd, int csock)
 {
-    VNC_DEBUG("New client on socket %d\n", vs->csock);
+    VncState *vs = qemu_mallocz(sizeof(VncState));
+    vs->csock = csock;
+
+    VNC_DEBUG("New client on socket %d\n", csock);
     dcl->idle = 0;
     socket_set_nonblock(vs->csock);
     qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
+
+    vs->vd = vd;
+    vs->ds = vd->ds;
+    vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
+    vs->last_x = -1;
+    vs->last_y = -1;
+
+    vs->as.freq = 44100;
+    vs->as.nchannels = 2;
+    vs->as.fmt = AUD_FMT_S16;
+    vs->as.endianness = 0;
+
+    vnc_resize(vs);
     vnc_write(vs, "RFB 003.008\n", 12);
     vnc_flush(vs);
     vnc_read_when(vs, protocol_version, 12);
     memset(vs->old_data, 0, ds_get_linesize(vs->ds) * ds_get_height(vs->ds));
     memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
-    vs->features = 0;
-    dcl->dpy_copy = NULL;
     vnc_update_client(vs);
     reset_keys(vs);
+
+    vs->next = vd->clients;
+    vd->clients = vs;
 }
 
 static void vnc_listen_read(void *opaque)
 {
-    VncState *vs = opaque;
+    VncDisplay *vs = opaque;
     struct sockaddr_in addr;
     socklen_t addrlen = sizeof(addr);
 
     /* Catch-up */
     vga_hw_update();
 
-    vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
-    if (vs->csock != -1) {
-        vnc_connect(vs);
+    int csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
+    if (csock != -1) {
+        vnc_connect(vs, csock);
     }
 }
 
 void vnc_display_init(DisplayState *ds)
 {
-    VncState *vs;
+    VncDisplay *vs;
 
     vs = qemu_mallocz(sizeof(VncState));
     dcl = qemu_mallocz(sizeof(DisplayChangeListener));
 
     ds->opaque = vs;
     dcl->idle = 1;
-    vnc_state = vs;
-    vs->display = NULL;
-    vs->password = NULL;
+    vnc_display = vs;
 
     vs->lsock = -1;
-    vs->csock = -1;
-    vs->last_x = -1;
-    vs->last_y = -1;
 
     vs->ds = ds;
 
@@ -2259,22 +2318,15 @@
     if (!vs->kbd_layout)
 	exit(1);
 
-    vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
-
+    dcl->dpy_copy = vnc_dpy_copy;
     dcl->dpy_update = vnc_dpy_update;
     dcl->dpy_resize = vnc_dpy_resize;
     dcl->dpy_setdata = vnc_dpy_setdata;
-    dcl->dpy_refresh = NULL;
     register_displaychangelistener(ds, dcl);
-
-    vs->as.freq = 44100;
-    vs->as.nchannels = 2;
-    vs->as.fmt = AUD_FMT_S16;
-    vs->as.endianness = 0;
 }
 
 #ifdef CONFIG_VNC_TLS
-static int vnc_set_x509_credential(VncState *vs,
+static int vnc_set_x509_credential(VncDisplay *vs,
 				   const char *certdir,
 				   const char *filename,
 				   char **cred,
@@ -2305,7 +2357,7 @@
     return 0;
 }
 
-static int vnc_set_x509_credential_dir(VncState *vs,
+static int vnc_set_x509_credential_dir(VncDisplay *vs,
 				       const char *certdir)
 {
     if (vnc_set_x509_credential(vs, certdir, X509_CA_CERT_FILE, &vs->x509cacert, 0) < 0)
@@ -2331,7 +2383,7 @@
 
 void vnc_display_close(DisplayState *ds)
 {
-    VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
+    VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
 
     if (!vs)
         return;
@@ -2344,32 +2396,16 @@
 	close(vs->lsock);
 	vs->lsock = -1;
     }
-    if (vs->csock != -1) {
-	qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
-	closesocket(vs->csock);
-	vs->csock = -1;
-	buffer_reset(&vs->input);
-	buffer_reset(&vs->output);
-	vs->need_update = 0;
-#ifdef CONFIG_VNC_TLS
-	if (vs->tls_session) {
-	    gnutls_deinit(vs->tls_session);
-	    vs->tls_session = NULL;
-	}
-	vs->wiremode = VNC_WIREMODE_CLEAR;
-#endif /* CONFIG_VNC_TLS */
-    }
     vs->auth = VNC_AUTH_INVALID;
 #ifdef CONFIG_VNC_TLS
     vs->subauth = VNC_AUTH_INVALID;
     vs->x509verify = 0;
 #endif
-    audio_del(vs);
 }
 
 int vnc_display_password(DisplayState *ds, const char *password)
 {
-    VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
+    VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
 
     if (vs->password) {
 	qemu_free(vs->password);
@@ -2385,7 +2421,7 @@
 
 int vnc_display_open(DisplayState *ds, const char *display)
 {
-    VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
+    VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
     const char *options;
     int password = 0;
     int reverse = 0;
@@ -2394,7 +2430,7 @@
     int tls = 0, x509 = 0;
 #endif
 
-    if (!vnc_state)
+    if (!vnc_display)
         return -1;
     vnc_display_close(ds);
     if (strcmp(display, "none") == 0)
@@ -2499,9 +2535,9 @@
             vs->display = NULL;
             return -1;
         } else {
-            vs->csock = vs->lsock;
+            int csock = vs->lsock;
             vs->lsock = -1;
-            vnc_connect(vs);
+            vnc_connect(vs, csock);
         }
         return 0;
 
@@ -2523,6 +2559,5 @@
             vs->display = dpy;
         }
     }
-
-    return qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);
+    return qemu_set_fd_handler2(vs->lsock, NULL, vnc_listen_read, NULL, vs);
 }
Index: vnc.h
===================================================================
--- vnc.h	(revision 6618)
+++ vnc.h	(working copy)
@@ -101,6 +101,7 @@
 #define VNC_FEATURE_WMVI                     3
 #define VNC_FEATURE_TIGHT                    4
 #define VNC_FEATURE_ZLIB                     5
+#define VNC_FEATURE_COPYRECT                 6
 
 #define VNC_FEATURE_RESIZE_MASK              (1 << VNC_FEATURE_RESIZE)
 #define VNC_FEATURE_HEXTILE_MASK             (1 << VNC_FEATURE_HEXTILE)
@@ -108,5 +109,6 @@
 #define VNC_FEATURE_WMVI_MASK                (1 << VNC_FEATURE_WMVI)
 #define VNC_FEATURE_TIGHT_MASK               (1 << VNC_FEATURE_TIGHT)
 #define VNC_FEATURE_ZLIB_MASK                (1 << VNC_FEATURE_ZLIB)
+#define VNC_FEATURE_COPYRECT_MASK            (1 << VNC_FEATURE_COPYRECT)
 
 #endif /* __VNCTIGHT_H */

  reply	other threads:[~2009-02-15  1:13 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-02-13 19:49 [Qemu-devel] [PATCH] Support multiple VNC clients Brian Kress
2009-02-14 10:07 ` malc
2009-02-14 22:07 ` Anthony Liguori
2009-02-15  1:13   ` Brian Kress [this message]
2009-02-16 14:59     ` Anthony Liguori
2009-02-15 11:35 ` Daniel P. Berrange
2009-02-15 21:47   ` Itamar Heim
2009-02-15 22:21     ` Brian Kress
2009-02-16  0:59       ` Anthony Liguori
2009-02-16 11:32         ` Stefano Stabellini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=49976C39.10301@moose.net \
    --to=kressb@moose.net \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.