Commit 753b4053311ff1437d99726970b1e7e6bf38249b

Authored by aliguori
1 parent 880fec5d

Support multiple VNC clients (Brian Kress)

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. 

Signed-off-by: Brian Kress <kressb@moose.net>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6621 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 2 changed files with 172 additions and 135 deletions
@@ -90,12 +90,35 @@ typedef void VncSendHextileTile(VncState *vs, @@ -90,12 +90,35 @@ typedef void VncSendHextileTile(VncState *vs,
90 90
91 #define VNC_AUTH_CHALLENGE_SIZE 16 91 #define VNC_AUTH_CHALLENGE_SIZE 16
92 92
  93 +typedef struct VncDisplay VncDisplay;
  94 +
  95 +struct VncDisplay
  96 +{
  97 + int lsock;
  98 + DisplayState *ds;
  99 + VncState *clients;
  100 + kbd_layout_t *kbd_layout;
  101 +
  102 + char *display;
  103 + char *password;
  104 + int auth;
  105 +#ifdef CONFIG_VNC_TLS
  106 + int subauth;
  107 + int x509verify;
  108 +
  109 + char *x509cacert;
  110 + char *x509cacrl;
  111 + char *x509cert;
  112 + char *x509key;
  113 +#endif
  114 +};
  115 +
93 struct VncState 116 struct VncState
94 { 117 {
95 QEMUTimer *timer; 118 QEMUTimer *timer;
96 - int lsock;  
97 int csock; 119 int csock;
98 DisplayState *ds; 120 DisplayState *ds;
  121 + VncDisplay *vd;
99 int need_update; 122 int need_update;
100 uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS]; 123 uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
101 char *old_data; 124 char *old_data;
@@ -111,18 +134,6 @@ struct VncState @@ -111,18 +134,6 @@ struct VncState
111 int major; 134 int major;
112 int minor; 135 int minor;
113 136
114 - char *display;  
115 - char *password;  
116 - int auth;  
117 -#ifdef CONFIG_VNC_TLS  
118 - int subauth;  
119 - int x509verify;  
120 -  
121 - char *x509cacert;  
122 - char *x509cacrl;  
123 - char *x509cert;  
124 - char *x509key;  
125 -#endif  
126 char challenge[VNC_AUTH_CHALLENGE_SIZE]; 137 char challenge[VNC_AUTH_CHALLENGE_SIZE];
127 138
128 #ifdef CONFIG_VNC_TLS 139 #ifdef CONFIG_VNC_TLS
@@ -132,7 +143,6 @@ struct VncState @@ -132,7 +143,6 @@ struct VncState
132 143
133 Buffer output; 144 Buffer output;
134 Buffer input; 145 Buffer input;
135 - kbd_layout_t *kbd_layout;  
136 /* current output mode information */ 146 /* current output mode information */
137 VncWritePixels *write_pixels; 147 VncWritePixels *write_pixels;
138 VncSendHextileTile *send_hextile_tile; 148 VncSendHextileTile *send_hextile_tile;
@@ -149,21 +159,23 @@ struct VncState @@ -149,21 +159,23 @@ struct VncState
149 Buffer zlib; 159 Buffer zlib;
150 Buffer zlib_tmp; 160 Buffer zlib_tmp;
151 z_stream zlib_stream[4]; 161 z_stream zlib_stream[4];
  162 +
  163 + VncState *next;
152 }; 164 };
153 165
154 -static VncState *vnc_state; /* needed for info vnc */ 166 +static VncDisplay *vnc_display; /* needed for info vnc */
155 static DisplayChangeListener *dcl; 167 static DisplayChangeListener *dcl;
156 168
157 void do_info_vnc(void) 169 void do_info_vnc(void)
158 { 170 {
159 - if (vnc_state == NULL || vnc_state->display == NULL) 171 + if (vnc_display == NULL || vnc_display->display == NULL)
160 term_printf("VNC server disabled\n"); 172 term_printf("VNC server disabled\n");
161 else { 173 else {
162 term_printf("VNC server active on: "); 174 term_printf("VNC server active on: ");
163 - term_print_filename(vnc_state->display); 175 + term_print_filename(vnc_display->display);
164 term_printf("\n"); 176 term_printf("\n");
165 177
166 - if (vnc_state->csock == -1) 178 + if (vnc_display->clients == NULL)
167 term_printf("No client connected\n"); 179 term_printf("No client connected\n");
168 else 180 else
169 term_printf("Client connected\n"); 181 term_printf("Client connected\n");
@@ -190,7 +202,7 @@ static void vnc_flush(VncState *vs); @@ -190,7 +202,7 @@ static void vnc_flush(VncState *vs);
190 static void vnc_update_client(void *opaque); 202 static void vnc_update_client(void *opaque);
191 static void vnc_client_read(void *opaque); 203 static void vnc_client_read(void *opaque);
192 204
193 -static void vnc_colordepth(DisplayState *ds); 205 +static void vnc_colordepth(VncState *vs);
194 206
195 static inline void vnc_set_bit(uint32_t *d, int k) 207 static inline void vnc_set_bit(uint32_t *d, int k)
196 { 208 {
@@ -233,9 +245,8 @@ static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2, @@ -233,9 +245,8 @@ static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2,
233 return 0; 245 return 0;
234 } 246 }
235 247
236 -static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h) 248 +static void vnc_update(VncState *vs, int x, int y, int w, int h)
237 { 249 {
238 - VncState *vs = ds->opaque;  
239 int i; 250 int i;
240 251
241 h += y; 252 h += y;
@@ -257,6 +268,16 @@ static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h) @@ -257,6 +268,16 @@ static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
257 vnc_set_bit(vs->dirty_row[y], (x + i) / 16); 268 vnc_set_bit(vs->dirty_row[y], (x + i) / 16);
258 } 269 }
259 270
  271 +static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
  272 +{
  273 + VncDisplay *vd = ds->opaque;
  274 + VncState *vs = vd->clients;
  275 + while (vs != NULL) {
  276 + vnc_update(vs, x, y, w, h);
  277 + vs = vs->next;
  278 + }
  279 +}
  280 +
260 static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h, 281 static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
261 int32_t encoding) 282 int32_t encoding)
262 { 283 {
@@ -301,10 +322,11 @@ static void buffer_append(Buffer *buffer, const void *data, size_t len) @@ -301,10 +322,11 @@ static void buffer_append(Buffer *buffer, const void *data, size_t len)
301 buffer->offset += len; 322 buffer->offset += len;
302 } 323 }
303 324
304 -static void vnc_dpy_resize(DisplayState *ds) 325 +static void vnc_resize(VncState *vs)
305 { 326 {
  327 + DisplayState *ds = vs->ds;
  328 +
306 int size_changed; 329 int size_changed;
307 - VncState *vs = ds->opaque;  
308 330
309 vs->old_data = qemu_realloc(vs->old_data, ds_get_linesize(ds) * ds_get_height(ds)); 331 vs->old_data = qemu_realloc(vs->old_data, ds_get_linesize(ds) * ds_get_height(ds));
310 332
@@ -315,7 +337,7 @@ static void vnc_dpy_resize(DisplayState *ds) @@ -315,7 +337,7 @@ static void vnc_dpy_resize(DisplayState *ds)
315 337
316 if (ds_get_bytes_per_pixel(ds) != vs->serverds.pf.bytes_per_pixel) 338 if (ds_get_bytes_per_pixel(ds) != vs->serverds.pf.bytes_per_pixel)
317 console_color_init(ds); 339 console_color_init(ds);
318 - vnc_colordepth(ds); 340 + vnc_colordepth(vs);
319 size_changed = ds_get_width(ds) != vs->serverds.width || 341 size_changed = ds_get_width(ds) != vs->serverds.width ||
320 ds_get_height(ds) != vs->serverds.height; 342 ds_get_height(ds) != vs->serverds.height;
321 vs->serverds = *(ds->surface); 343 vs->serverds = *(ds->surface);
@@ -334,6 +356,16 @@ static void vnc_dpy_resize(DisplayState *ds) @@ -334,6 +356,16 @@ static void vnc_dpy_resize(DisplayState *ds)
334 memset(vs->old_data, 42, ds_get_linesize(vs->ds) * ds_get_height(vs->ds)); 356 memset(vs->old_data, 42, ds_get_linesize(vs->ds) * ds_get_height(vs->ds));
335 } 357 }
336 358
  359 +static void vnc_dpy_resize(DisplayState *ds)
  360 +{
  361 + VncDisplay *vd = ds->opaque;
  362 + VncState *vs = vd->clients;
  363 + while (vs != NULL) {
  364 + vnc_resize(vs);
  365 + vs = vs->next;
  366 + }
  367 +}
  368 +
337 /* fastest code */ 369 /* fastest code */
338 static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size) 370 static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size)
339 { 371 {
@@ -599,10 +631,8 @@ static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h) @@ -599,10 +631,8 @@ static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
599 } 631 }
600 } 632 }
601 633
602 -static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h) 634 +static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
603 { 635 {
604 - VncState *vs = ds->opaque;  
605 -  
606 vnc_update_client(vs); 636 vnc_update_client(vs);
607 637
608 vnc_write_u8(vs, 0); /* msg id */ 638 vnc_write_u8(vs, 0); /* msg id */
@@ -614,6 +644,19 @@ static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_ @@ -614,6 +644,19 @@ static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_
614 vnc_flush(vs); 644 vnc_flush(vs);
615 } 645 }
616 646
  647 +static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
  648 +{
  649 + VncDisplay *vd = ds->opaque;
  650 + VncState *vs = vd->clients;
  651 + while (vs != NULL) {
  652 + if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT))
  653 + vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
  654 + else /* TODO */
  655 + vnc_update(vs, dst_x, dst_y, w, h);
  656 + vs = vs->next;
  657 + }
  658 +}
  659 +
617 static int find_dirty_height(VncState *vs, int y, int last_x, int x) 660 static int find_dirty_height(VncState *vs, int y, int last_x, int x)
618 { 661 {
619 int h; 662 int h;
@@ -632,7 +675,6 @@ static int find_dirty_height(VncState *vs, int y, int last_x, int x) @@ -632,7 +675,6 @@ static int find_dirty_height(VncState *vs, int y, int last_x, int x)
632 static void vnc_update_client(void *opaque) 675 static void vnc_update_client(void *opaque)
633 { 676 {
634 VncState *vs = opaque; 677 VncState *vs = opaque;
635 -  
636 if (vs->need_update && vs->csock != -1) { 678 if (vs->need_update && vs->csock != -1) {
637 int y; 679 int y;
638 uint8_t *row; 680 uint8_t *row;
@@ -725,14 +767,6 @@ static void vnc_update_client(void *opaque) @@ -725,14 +767,6 @@ static void vnc_update_client(void *opaque)
725 767
726 } 768 }
727 769
728 -static int vnc_listen_poll(void *opaque)  
729 -{  
730 - VncState *vs = opaque;  
731 - if (vs->csock == -1)  
732 - return 1;  
733 - return 0;  
734 -}  
735 -  
736 /* audio */ 770 /* audio */
737 static void audio_capture_notify(void *opaque, audcnotification_e cmd) 771 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
738 { 772 {
@@ -817,19 +851,35 @@ static int vnc_client_io_error(VncState *vs, int ret, int last_errno) @@ -817,19 +851,35 @@ static int vnc_client_io_error(VncState *vs, int ret, int last_errno)
817 VNC_DEBUG("Closing down client sock %d %d\n", ret, ret < 0 ? last_errno : 0); 851 VNC_DEBUG("Closing down client sock %d %d\n", ret, ret < 0 ? last_errno : 0);
818 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL); 852 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
819 closesocket(vs->csock); 853 closesocket(vs->csock);
820 - vs->csock = -1;  
821 - dcl->idle = 1;  
822 - buffer_reset(&vs->input);  
823 - buffer_reset(&vs->output);  
824 - vs->need_update = 0; 854 + qemu_del_timer(vs->timer);
  855 + qemu_free_timer(vs->timer);
  856 + if (vs->input.buffer) qemu_free(vs->input.buffer);
  857 + if (vs->output.buffer) qemu_free(vs->output.buffer);
825 #ifdef CONFIG_VNC_TLS 858 #ifdef CONFIG_VNC_TLS
826 if (vs->tls_session) { 859 if (vs->tls_session) {
827 gnutls_deinit(vs->tls_session); 860 gnutls_deinit(vs->tls_session);
828 vs->tls_session = NULL; 861 vs->tls_session = NULL;
829 } 862 }
830 - vs->wiremode = VNC_WIREMODE_CLEAR;  
831 #endif /* CONFIG_VNC_TLS */ 863 #endif /* CONFIG_VNC_TLS */
832 audio_del(vs); 864 audio_del(vs);
  865 +
  866 + VncState *p, *parent = NULL;
  867 + for (p = vs->vd->clients; p != NULL; p = p->next) {
  868 + if (p == vs) {
  869 + if (parent)
  870 + parent->next = p->next;
  871 + else
  872 + vs->vd->clients = p->next;
  873 + break;
  874 + }
  875 + parent = p;
  876 + }
  877 + if (!vs->vd->clients)
  878 + dcl->idle = 1;
  879 +
  880 + qemu_free(vs->old_data);
  881 + qemu_free(vs);
  882 +
833 return 0; 883 return 0;
834 } 884 }
835 return ret; 885 return ret;
@@ -1095,8 +1145,8 @@ static void reset_keys(VncState *vs) @@ -1095,8 +1145,8 @@ static void reset_keys(VncState *vs)
1095 1145
1096 static void press_key(VncState *vs, int keysym) 1146 static void press_key(VncState *vs, int keysym)
1097 { 1147 {
1098 - kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) & 0x7f);  
1099 - kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80); 1148 + kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) & 0x7f);
  1149 + kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) | 0x80);
1100 } 1150 }
1101 1151
1102 static void do_key_event(VncState *vs, int down, int keycode, int sym) 1152 static void do_key_event(VncState *vs, int down, int keycode, int sym)
@@ -1129,12 +1179,12 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym) @@ -1129,12 +1179,12 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym)
1129 break; 1179 break;
1130 } 1180 }
1131 1181
1132 - if (keycode_is_keypad(vs->kbd_layout, keycode)) { 1182 + if (keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1133 /* If the numlock state needs to change then simulate an additional 1183 /* If the numlock state needs to change then simulate an additional
1134 keypress before sending this one. This will happen if the user 1184 keypress before sending this one. This will happen if the user
1135 toggles numlock away from the VNC window. 1185 toggles numlock away from the VNC window.
1136 */ 1186 */
1137 - if (keysym_is_numlock(vs->kbd_layout, sym & 0xFFFF)) { 1187 + if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1138 if (!vs->modifiers_state[0x45]) { 1188 if (!vs->modifiers_state[0x45]) {
1139 vs->modifiers_state[0x45] = 1; 1189 vs->modifiers_state[0x45] = 1;
1140 press_key(vs, 0xff7f); 1190 press_key(vs, 0xff7f);
@@ -1207,7 +1257,7 @@ static void key_event(VncState *vs, int down, uint32_t sym) @@ -1207,7 +1257,7 @@ static void key_event(VncState *vs, int down, uint32_t sym)
1207 if (sym >= 'A' && sym <= 'Z' && is_graphic_console()) 1257 if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
1208 sym = sym - 'A' + 'a'; 1258 sym = sym - 'A' + 'a';
1209 1259
1210 - keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF); 1260 + keycode = keysym2scancode(vs->vd->kbd_layout, sym & 0xFFFF);
1211 do_key_event(vs, down, keycode, sym); 1261 do_key_event(vs, down, keycode, sym);
1212 } 1262 }
1213 1263
@@ -1279,7 +1329,6 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) @@ -1279,7 +1329,6 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1279 vs->tight_compression = 9; 1329 vs->tight_compression = 9;
1280 vs->tight_quality = 9; 1330 vs->tight_quality = 9;
1281 vs->absolute = -1; 1331 vs->absolute = -1;
1282 - dcl->dpy_copy = NULL;  
1283 1332
1284 for (i = n_encodings - 1; i >= 0; i--) { 1333 for (i = n_encodings - 1; i >= 0; i--) {
1285 enc = encodings[i]; 1334 enc = encodings[i];
@@ -1288,7 +1337,7 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) @@ -1288,7 +1337,7 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1288 vs->vnc_encoding = enc; 1337 vs->vnc_encoding = enc;
1289 break; 1338 break;
1290 case VNC_ENCODING_COPYRECT: 1339 case VNC_ENCODING_COPYRECT:
1291 - dcl->dpy_copy = vnc_copy; 1340 + vs->features |= VNC_FEATURE_COPYRECT_MASK;
1292 break; 1341 break;
1293 case VNC_ENCODING_HEXTILE: 1342 case VNC_ENCODING_HEXTILE:
1294 vs->features |= VNC_FEATURE_HEXTILE_MASK; 1343 vs->features |= VNC_FEATURE_HEXTILE_MASK;
@@ -1432,17 +1481,15 @@ static void vnc_dpy_setdata(DisplayState *ds) @@ -1432,17 +1481,15 @@ static void vnc_dpy_setdata(DisplayState *ds)
1432 /* We don't have to do anything */ 1481 /* We don't have to do anything */
1433 } 1482 }
1434 1483
1435 -static void vnc_colordepth(DisplayState *ds) 1484 +static void vnc_colordepth(VncState *vs)
1436 { 1485 {
1437 - struct VncState *vs = ds->opaque;  
1438 -  
1439 - if (vs->csock != -1 && vnc_has_feature(vs, VNC_FEATURE_WMVI)) { 1486 + if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
1440 /* Sending a WMVi message to notify the client*/ 1487 /* Sending a WMVi message to notify the client*/
1441 vnc_write_u8(vs, 0); /* msg id */ 1488 vnc_write_u8(vs, 0); /* msg id */
1442 vnc_write_u8(vs, 0); 1489 vnc_write_u8(vs, 0);
1443 vnc_write_u16(vs, 1); /* number of rects */ 1490 vnc_write_u16(vs, 1); /* number of rects */
1444 - vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds),  
1445 - VNC_ENCODING_WMVi); 1491 + vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds),
  1492 + ds_get_height(vs->ds), VNC_ENCODING_WMVi);
1446 pixel_format_message(vs); 1493 pixel_format_message(vs);
1447 vnc_flush(vs); 1494 vnc_flush(vs);
1448 } else { 1495 } else {
@@ -1626,7 +1673,7 @@ static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len) @@ -1626,7 +1673,7 @@ static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
1626 int i, j, pwlen; 1673 int i, j, pwlen;
1627 unsigned char key[8]; 1674 unsigned char key[8];
1628 1675
1629 - if (!vs->password || !vs->password[0]) { 1676 + if (!vs->vd->password || !vs->vd->password[0]) {
1630 VNC_DEBUG("No password configured on server"); 1677 VNC_DEBUG("No password configured on server");
1631 vnc_write_u32(vs, 1); /* Reject auth */ 1678 vnc_write_u32(vs, 1); /* Reject auth */
1632 if (vs->minor >= 8) { 1679 if (vs->minor >= 8) {
@@ -1642,9 +1689,9 @@ static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len) @@ -1642,9 +1689,9 @@ static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
1642 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE); 1689 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
1643 1690
1644 /* Calculate the expected challenge response */ 1691 /* Calculate the expected challenge response */
1645 - pwlen = strlen(vs->password); 1692 + pwlen = strlen(vs->vd->password);
1646 for (i=0; i<sizeof(key); i++) 1693 for (i=0; i<sizeof(key); i++)
1647 - key[i] = i<pwlen ? vs->password[i] : 0; 1694 + key[i] = i<pwlen ? vs->vd->password[i] : 0;
1648 deskey(key, EN0); 1695 deskey(key, EN0);
1649 for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8) 1696 for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
1650 des(response+j, response+j); 1697 des(response+j, response+j);
@@ -1733,15 +1780,15 @@ static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *v @@ -1733,15 +1780,15 @@ static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *v
1733 gnutls_certificate_credentials_t x509_cred; 1780 gnutls_certificate_credentials_t x509_cred;
1734 int ret; 1781 int ret;
1735 1782
1736 - if (!vs->x509cacert) { 1783 + if (!vs->vd->x509cacert) {
1737 VNC_DEBUG("No CA x509 certificate specified\n"); 1784 VNC_DEBUG("No CA x509 certificate specified\n");
1738 return NULL; 1785 return NULL;
1739 } 1786 }
1740 - if (!vs->x509cert) { 1787 + if (!vs->vd->x509cert) {
1741 VNC_DEBUG("No server x509 certificate specified\n"); 1788 VNC_DEBUG("No server x509 certificate specified\n");
1742 return NULL; 1789 return NULL;
1743 } 1790 }
1744 - if (!vs->x509key) { 1791 + if (!vs->vd->x509key) {
1745 VNC_DEBUG("No server private key specified\n"); 1792 VNC_DEBUG("No server private key specified\n");
1746 return NULL; 1793 return NULL;
1747 } 1794 }
@@ -1751,7 +1798,7 @@ static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *v @@ -1751,7 +1798,7 @@ static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *v
1751 return NULL; 1798 return NULL;
1752 } 1799 }
1753 if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred, 1800 if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred,
1754 - vs->x509cacert, 1801 + vs->vd->x509cacert,
1755 GNUTLS_X509_FMT_PEM)) < 0) { 1802 GNUTLS_X509_FMT_PEM)) < 0) {
1756 VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret)); 1803 VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret));
1757 gnutls_certificate_free_credentials(x509_cred); 1804 gnutls_certificate_free_credentials(x509_cred);
@@ -1759,17 +1806,17 @@ static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *v @@ -1759,17 +1806,17 @@ static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *v
1759 } 1806 }
1760 1807
1761 if ((ret = gnutls_certificate_set_x509_key_file (x509_cred, 1808 if ((ret = gnutls_certificate_set_x509_key_file (x509_cred,
1762 - vs->x509cert,  
1763 - vs->x509key, 1809 + vs->vd->x509cert,
  1810 + vs->vd->x509key,
1764 GNUTLS_X509_FMT_PEM)) < 0) { 1811 GNUTLS_X509_FMT_PEM)) < 0) {
1765 VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret)); 1812 VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret));
1766 gnutls_certificate_free_credentials(x509_cred); 1813 gnutls_certificate_free_credentials(x509_cred);
1767 return NULL; 1814 return NULL;
1768 } 1815 }
1769 1816
1770 - if (vs->x509cacrl) { 1817 + if (vs->vd->x509cacrl) {
1771 if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred, 1818 if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred,
1772 - vs->x509cacrl, 1819 + vs->vd->x509cacrl,
1773 GNUTLS_X509_FMT_PEM)) < 0) { 1820 GNUTLS_X509_FMT_PEM)) < 0) {
1774 VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret)); 1821 VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret));
1775 gnutls_certificate_free_credentials(x509_cred); 1822 gnutls_certificate_free_credentials(x509_cred);
@@ -1863,7 +1910,7 @@ static int vnc_validate_certificate(struct VncState *vs) @@ -1863,7 +1910,7 @@ static int vnc_validate_certificate(struct VncState *vs)
1863 1910
1864 static int start_auth_vencrypt_subauth(VncState *vs) 1911 static int start_auth_vencrypt_subauth(VncState *vs)
1865 { 1912 {
1866 - switch (vs->subauth) { 1913 + switch (vs->vd->subauth) {
1867 case VNC_AUTH_VENCRYPT_TLSNONE: 1914 case VNC_AUTH_VENCRYPT_TLSNONE:
1868 case VNC_AUTH_VENCRYPT_X509NONE: 1915 case VNC_AUTH_VENCRYPT_X509NONE:
1869 VNC_DEBUG("Accept TLS auth none\n"); 1916 VNC_DEBUG("Accept TLS auth none\n");
@@ -1877,7 +1924,7 @@ static int start_auth_vencrypt_subauth(VncState *vs) @@ -1877,7 +1924,7 @@ static int start_auth_vencrypt_subauth(VncState *vs)
1877 return start_auth_vnc(vs); 1924 return start_auth_vnc(vs);
1878 1925
1879 default: /* Should not be possible, but just in case */ 1926 default: /* Should not be possible, but just in case */
1880 - VNC_DEBUG("Reject auth %d\n", vs->auth); 1927 + VNC_DEBUG("Reject auth %d\n", vs->vd->auth);
1881 vnc_write_u8(vs, 1); 1928 vnc_write_u8(vs, 1);
1882 if (vs->minor >= 8) { 1929 if (vs->minor >= 8) {
1883 static const char err[] = "Unsupported authentication type"; 1930 static const char err[] = "Unsupported authentication type";
@@ -1909,7 +1956,7 @@ static int vnc_continue_handshake(struct VncState *vs) { @@ -1909,7 +1956,7 @@ static int vnc_continue_handshake(struct VncState *vs) {
1909 return -1; 1956 return -1;
1910 } 1957 }
1911 1958
1912 - if (vs->x509verify) { 1959 + if (vs->vd->x509verify) {
1913 if (vnc_validate_certificate(vs) < 0) { 1960 if (vnc_validate_certificate(vs) < 0) {
1914 VNC_DEBUG("Client verification failed\n"); 1961 VNC_DEBUG("Client verification failed\n");
1915 vnc_client_error(vs); 1962 vnc_client_error(vs);
@@ -1934,9 +1981,9 @@ static void vnc_handshake_io(void *opaque) { @@ -1934,9 +1981,9 @@ static void vnc_handshake_io(void *opaque) {
1934 } 1981 }
1935 1982
1936 #define NEED_X509_AUTH(vs) \ 1983 #define NEED_X509_AUTH(vs) \
1937 - ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE || \  
1938 - (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC || \  
1939 - (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN) 1984 + ((vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509NONE || \
  1985 + (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509VNC || \
  1986 + (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
1940 1987
1941 1988
1942 static int vnc_start_tls(struct VncState *vs) { 1989 static int vnc_start_tls(struct VncState *vs) {
@@ -2000,7 +2047,7 @@ static int vnc_start_tls(struct VncState *vs) { @@ -2000,7 +2047,7 @@ static int vnc_start_tls(struct VncState *vs) {
2000 vnc_client_error(vs); 2047 vnc_client_error(vs);
2001 return -1; 2048 return -1;
2002 } 2049 }
2003 - if (vs->x509verify) { 2050 + if (vs->vd->x509verify) {
2004 VNC_DEBUG("Requesting a client certificate\n"); 2051 VNC_DEBUG("Requesting a client certificate\n");
2005 gnutls_certificate_server_set_request (vs->tls_session, GNUTLS_CERT_REQUEST); 2052 gnutls_certificate_server_set_request (vs->tls_session, GNUTLS_CERT_REQUEST);
2006 } 2053 }
@@ -2035,7 +2082,7 @@ static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len @@ -2035,7 +2082,7 @@ static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len
2035 { 2082 {
2036 int auth = read_u32(data, 0); 2083 int auth = read_u32(data, 0);
2037 2084
2038 - if (auth != vs->subauth) { 2085 + if (auth != vs->vd->subauth) {
2039 VNC_DEBUG("Rejecting auth %d\n", auth); 2086 VNC_DEBUG("Rejecting auth %d\n", auth);
2040 vnc_write_u8(vs, 0); /* Reject auth */ 2087 vnc_write_u8(vs, 0); /* Reject auth */
2041 vnc_flush(vs); 2088 vnc_flush(vs);
@@ -2070,10 +2117,10 @@ static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len @@ -2070,10 +2117,10 @@ static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len
2070 vnc_flush(vs); 2117 vnc_flush(vs);
2071 vnc_client_error(vs); 2118 vnc_client_error(vs);
2072 } else { 2119 } else {
2073 - VNC_DEBUG("Sending allowed auth %d\n", vs->subauth); 2120 + VNC_DEBUG("Sending allowed auth %d\n", vs->vd->subauth);
2074 vnc_write_u8(vs, 0); /* Accept version */ 2121 vnc_write_u8(vs, 0); /* Accept version */
2075 vnc_write_u8(vs, 1); /* Number of sub-auths */ 2122 vnc_write_u8(vs, 1); /* Number of sub-auths */
2076 - vnc_write_u32(vs, vs->subauth); /* The supported auth */ 2123 + vnc_write_u32(vs, vs->vd->subauth); /* The supported auth */
2077 vnc_flush(vs); 2124 vnc_flush(vs);
2078 vnc_read_when(vs, protocol_client_vencrypt_auth, 4); 2125 vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
2079 } 2126 }
@@ -2095,7 +2142,7 @@ static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len) @@ -2095,7 +2142,7 @@ static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2095 { 2142 {
2096 /* We only advertise 1 auth scheme at a time, so client 2143 /* We only advertise 1 auth scheme at a time, so client
2097 * must pick the one we sent. Verify this */ 2144 * must pick the one we sent. Verify this */
2098 - if (data[0] != vs->auth) { /* Reject auth */ 2145 + if (data[0] != vs->vd->auth) { /* Reject auth */
2099 VNC_DEBUG("Reject auth %d\n", (int)data[0]); 2146 VNC_DEBUG("Reject auth %d\n", (int)data[0]);
2100 vnc_write_u32(vs, 1); 2147 vnc_write_u32(vs, 1);
2101 if (vs->minor >= 8) { 2148 if (vs->minor >= 8) {
@@ -2106,7 +2153,7 @@ static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len) @@ -2106,7 +2153,7 @@ static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2106 vnc_client_error(vs); 2153 vnc_client_error(vs);
2107 } else { /* Accept requested auth */ 2154 } else { /* Accept requested auth */
2108 VNC_DEBUG("Client requested auth %d\n", (int)data[0]); 2155 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
2109 - switch (vs->auth) { 2156 + switch (vs->vd->auth) {
2110 case VNC_AUTH_NONE: 2157 case VNC_AUTH_NONE:
2111 VNC_DEBUG("Accept auth none\n"); 2158 VNC_DEBUG("Accept auth none\n");
2112 if (vs->minor >= 8) { 2159 if (vs->minor >= 8) {
@@ -2127,7 +2174,7 @@ static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len) @@ -2127,7 +2174,7 @@ static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2127 #endif /* CONFIG_VNC_TLS */ 2174 #endif /* CONFIG_VNC_TLS */
2128 2175
2129 default: /* Should not be possible, but just in case */ 2176 default: /* Should not be possible, but just in case */
2130 - VNC_DEBUG("Reject auth %d\n", vs->auth); 2177 + VNC_DEBUG("Reject auth %d\n", vs->vd->auth);
2131 vnc_write_u8(vs, 1); 2178 vnc_write_u8(vs, 1);
2132 if (vs->minor >= 8) { 2179 if (vs->minor >= 8) {
2133 static const char err[] = "Authentication failed"; 2180 static const char err[] = "Authentication failed";
@@ -2172,26 +2219,26 @@ static int protocol_version(VncState *vs, uint8_t *version, size_t len) @@ -2172,26 +2219,26 @@ static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2172 vs->minor = 3; 2219 vs->minor = 3;
2173 2220
2174 if (vs->minor == 3) { 2221 if (vs->minor == 3) {
2175 - if (vs->auth == VNC_AUTH_NONE) { 2222 + if (vs->vd->auth == VNC_AUTH_NONE) {
2176 VNC_DEBUG("Tell client auth none\n"); 2223 VNC_DEBUG("Tell client auth none\n");
2177 - vnc_write_u32(vs, vs->auth); 2224 + vnc_write_u32(vs, vs->vd->auth);
2178 vnc_flush(vs); 2225 vnc_flush(vs);
2179 vnc_read_when(vs, protocol_client_init, 1); 2226 vnc_read_when(vs, protocol_client_init, 1);
2180 - } else if (vs->auth == VNC_AUTH_VNC) { 2227 + } else if (vs->vd->auth == VNC_AUTH_VNC) {
2181 VNC_DEBUG("Tell client VNC auth\n"); 2228 VNC_DEBUG("Tell client VNC auth\n");
2182 - vnc_write_u32(vs, vs->auth); 2229 + vnc_write_u32(vs, vs->vd->auth);
2183 vnc_flush(vs); 2230 vnc_flush(vs);
2184 start_auth_vnc(vs); 2231 start_auth_vnc(vs);
2185 } else { 2232 } else {
2186 - VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth); 2233 + VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->vd->auth);
2187 vnc_write_u32(vs, VNC_AUTH_INVALID); 2234 vnc_write_u32(vs, VNC_AUTH_INVALID);
2188 vnc_flush(vs); 2235 vnc_flush(vs);
2189 vnc_client_error(vs); 2236 vnc_client_error(vs);
2190 } 2237 }
2191 } else { 2238 } else {
2192 - VNC_DEBUG("Telling client we support auth %d\n", vs->auth); 2239 + VNC_DEBUG("Telling client we support auth %d\n", vs->vd->auth);
2193 vnc_write_u8(vs, 1); /* num auth */ 2240 vnc_write_u8(vs, 1); /* num auth */
2194 - vnc_write_u8(vs, vs->auth); 2241 + vnc_write_u8(vs, vs->vd->auth);
2195 vnc_read_when(vs, protocol_client_auth, 1); 2242 vnc_read_when(vs, protocol_client_auth, 1);
2196 vnc_flush(vs); 2243 vnc_flush(vs);
2197 } 2244 }
@@ -2199,55 +2246,67 @@ static int protocol_version(VncState *vs, uint8_t *version, size_t len) @@ -2199,55 +2246,67 @@ static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2199 return 0; 2246 return 0;
2200 } 2247 }
2201 2248
2202 -static void vnc_connect(VncState *vs) 2249 +static void vnc_connect(VncDisplay *vd, int csock)
2203 { 2250 {
2204 - VNC_DEBUG("New client on socket %d\n", vs->csock); 2251 + VncState *vs = qemu_mallocz(sizeof(VncState));
  2252 + vs->csock = csock;
  2253 +
  2254 + VNC_DEBUG("New client on socket %d\n", csock);
2205 dcl->idle = 0; 2255 dcl->idle = 0;
2206 socket_set_nonblock(vs->csock); 2256 socket_set_nonblock(vs->csock);
2207 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs); 2257 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
  2258 +
  2259 + vs->vd = vd;
  2260 + vs->ds = vd->ds;
  2261 + vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
  2262 + vs->last_x = -1;
  2263 + vs->last_y = -1;
  2264 +
  2265 + vs->as.freq = 44100;
  2266 + vs->as.nchannels = 2;
  2267 + vs->as.fmt = AUD_FMT_S16;
  2268 + vs->as.endianness = 0;
  2269 +
  2270 + vnc_resize(vs);
2208 vnc_write(vs, "RFB 003.008\n", 12); 2271 vnc_write(vs, "RFB 003.008\n", 12);
2209 vnc_flush(vs); 2272 vnc_flush(vs);
2210 vnc_read_when(vs, protocol_version, 12); 2273 vnc_read_when(vs, protocol_version, 12);
2211 memset(vs->old_data, 0, ds_get_linesize(vs->ds) * ds_get_height(vs->ds)); 2274 memset(vs->old_data, 0, ds_get_linesize(vs->ds) * ds_get_height(vs->ds));
2212 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row)); 2275 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
2213 - vs->features = 0;  
2214 - dcl->dpy_copy = NULL;  
2215 vnc_update_client(vs); 2276 vnc_update_client(vs);
2216 reset_keys(vs); 2277 reset_keys(vs);
  2278 +
  2279 + vs->next = vd->clients;
  2280 + vd->clients = vs;
2217 } 2281 }
2218 2282
2219 static void vnc_listen_read(void *opaque) 2283 static void vnc_listen_read(void *opaque)
2220 { 2284 {
2221 - VncState *vs = opaque; 2285 + VncDisplay *vs = opaque;
2222 struct sockaddr_in addr; 2286 struct sockaddr_in addr;
2223 socklen_t addrlen = sizeof(addr); 2287 socklen_t addrlen = sizeof(addr);
2224 2288
2225 /* Catch-up */ 2289 /* Catch-up */
2226 vga_hw_update(); 2290 vga_hw_update();
2227 2291
2228 - vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);  
2229 - if (vs->csock != -1) {  
2230 - vnc_connect(vs); 2292 + int csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
  2293 + if (csock != -1) {
  2294 + vnc_connect(vs, csock);
2231 } 2295 }
2232 } 2296 }
2233 2297
2234 void vnc_display_init(DisplayState *ds) 2298 void vnc_display_init(DisplayState *ds)
2235 { 2299 {
2236 - VncState *vs; 2300 + VncDisplay *vs;
2237 2301
2238 vs = qemu_mallocz(sizeof(VncState)); 2302 vs = qemu_mallocz(sizeof(VncState));
2239 dcl = qemu_mallocz(sizeof(DisplayChangeListener)); 2303 dcl = qemu_mallocz(sizeof(DisplayChangeListener));
2240 2304
2241 ds->opaque = vs; 2305 ds->opaque = vs;
2242 dcl->idle = 1; 2306 dcl->idle = 1;
2243 - vnc_state = vs;  
2244 - vs->display = NULL;  
2245 - vs->password = NULL; 2307 + vnc_display = vs;
2246 2308
2247 vs->lsock = -1; 2309 vs->lsock = -1;
2248 - vs->csock = -1;  
2249 - vs->last_x = -1;  
2250 - vs->last_y = -1;  
2251 2310
2252 vs->ds = ds; 2311 vs->ds = ds;
2253 2312
@@ -2259,22 +2318,15 @@ void vnc_display_init(DisplayState *ds) @@ -2259,22 +2318,15 @@ void vnc_display_init(DisplayState *ds)
2259 if (!vs->kbd_layout) 2318 if (!vs->kbd_layout)
2260 exit(1); 2319 exit(1);
2261 2320
2262 - vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);  
2263 - 2321 + dcl->dpy_copy = vnc_dpy_copy;
2264 dcl->dpy_update = vnc_dpy_update; 2322 dcl->dpy_update = vnc_dpy_update;
2265 dcl->dpy_resize = vnc_dpy_resize; 2323 dcl->dpy_resize = vnc_dpy_resize;
2266 dcl->dpy_setdata = vnc_dpy_setdata; 2324 dcl->dpy_setdata = vnc_dpy_setdata;
2267 - dcl->dpy_refresh = NULL;  
2268 register_displaychangelistener(ds, dcl); 2325 register_displaychangelistener(ds, dcl);
2269 -  
2270 - vs->as.freq = 44100;  
2271 - vs->as.nchannels = 2;  
2272 - vs->as.fmt = AUD_FMT_S16;  
2273 - vs->as.endianness = 0;  
2274 } 2326 }
2275 2327
2276 #ifdef CONFIG_VNC_TLS 2328 #ifdef CONFIG_VNC_TLS
2277 -static int vnc_set_x509_credential(VncState *vs, 2329 +static int vnc_set_x509_credential(VncDisplay *vs,
2278 const char *certdir, 2330 const char *certdir,
2279 const char *filename, 2331 const char *filename,
2280 char **cred, 2332 char **cred,
@@ -2305,7 +2357,7 @@ static int vnc_set_x509_credential(VncState *vs, @@ -2305,7 +2357,7 @@ static int vnc_set_x509_credential(VncState *vs,
2305 return 0; 2357 return 0;
2306 } 2358 }
2307 2359
2308 -static int vnc_set_x509_credential_dir(VncState *vs, 2360 +static int vnc_set_x509_credential_dir(VncDisplay *vs,
2309 const char *certdir) 2361 const char *certdir)
2310 { 2362 {
2311 if (vnc_set_x509_credential(vs, certdir, X509_CA_CERT_FILE, &vs->x509cacert, 0) < 0) 2363 if (vnc_set_x509_credential(vs, certdir, X509_CA_CERT_FILE, &vs->x509cacert, 0) < 0)
@@ -2331,7 +2383,7 @@ static int vnc_set_x509_credential_dir(VncState *vs, @@ -2331,7 +2383,7 @@ static int vnc_set_x509_credential_dir(VncState *vs,
2331 2383
2332 void vnc_display_close(DisplayState *ds) 2384 void vnc_display_close(DisplayState *ds)
2333 { 2385 {
2334 - VncState *vs = ds ? (VncState *)ds->opaque : vnc_state; 2386 + VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
2335 2387
2336 if (!vs) 2388 if (!vs)
2337 return; 2389 return;
@@ -2344,32 +2396,16 @@ void vnc_display_close(DisplayState *ds) @@ -2344,32 +2396,16 @@ void vnc_display_close(DisplayState *ds)
2344 close(vs->lsock); 2396 close(vs->lsock);
2345 vs->lsock = -1; 2397 vs->lsock = -1;
2346 } 2398 }
2347 - if (vs->csock != -1) {  
2348 - qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);  
2349 - closesocket(vs->csock);  
2350 - vs->csock = -1;  
2351 - buffer_reset(&vs->input);  
2352 - buffer_reset(&vs->output);  
2353 - vs->need_update = 0;  
2354 -#ifdef CONFIG_VNC_TLS  
2355 - if (vs->tls_session) {  
2356 - gnutls_deinit(vs->tls_session);  
2357 - vs->tls_session = NULL;  
2358 - }  
2359 - vs->wiremode = VNC_WIREMODE_CLEAR;  
2360 -#endif /* CONFIG_VNC_TLS */  
2361 - }  
2362 vs->auth = VNC_AUTH_INVALID; 2399 vs->auth = VNC_AUTH_INVALID;
2363 #ifdef CONFIG_VNC_TLS 2400 #ifdef CONFIG_VNC_TLS
2364 vs->subauth = VNC_AUTH_INVALID; 2401 vs->subauth = VNC_AUTH_INVALID;
2365 vs->x509verify = 0; 2402 vs->x509verify = 0;
2366 #endif 2403 #endif
2367 - audio_del(vs);  
2368 } 2404 }
2369 2405
2370 int vnc_display_password(DisplayState *ds, const char *password) 2406 int vnc_display_password(DisplayState *ds, const char *password)
2371 { 2407 {
2372 - VncState *vs = ds ? (VncState *)ds->opaque : vnc_state; 2408 + VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
2373 2409
2374 if (vs->password) { 2410 if (vs->password) {
2375 qemu_free(vs->password); 2411 qemu_free(vs->password);
@@ -2385,7 +2421,7 @@ int vnc_display_password(DisplayState *ds, const char *password) @@ -2385,7 +2421,7 @@ int vnc_display_password(DisplayState *ds, const char *password)
2385 2421
2386 int vnc_display_open(DisplayState *ds, const char *display) 2422 int vnc_display_open(DisplayState *ds, const char *display)
2387 { 2423 {
2388 - VncState *vs = ds ? (VncState *)ds->opaque : vnc_state; 2424 + VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
2389 const char *options; 2425 const char *options;
2390 int password = 0; 2426 int password = 0;
2391 int reverse = 0; 2427 int reverse = 0;
@@ -2394,7 +2430,7 @@ int vnc_display_open(DisplayState *ds, const char *display) @@ -2394,7 +2430,7 @@ int vnc_display_open(DisplayState *ds, const char *display)
2394 int tls = 0, x509 = 0; 2430 int tls = 0, x509 = 0;
2395 #endif 2431 #endif
2396 2432
2397 - if (!vnc_state) 2433 + if (!vnc_display)
2398 return -1; 2434 return -1;
2399 vnc_display_close(ds); 2435 vnc_display_close(ds);
2400 if (strcmp(display, "none") == 0) 2436 if (strcmp(display, "none") == 0)
@@ -2499,9 +2535,9 @@ int vnc_display_open(DisplayState *ds, const char *display) @@ -2499,9 +2535,9 @@ int vnc_display_open(DisplayState *ds, const char *display)
2499 vs->display = NULL; 2535 vs->display = NULL;
2500 return -1; 2536 return -1;
2501 } else { 2537 } else {
2502 - vs->csock = vs->lsock; 2538 + int csock = vs->lsock;
2503 vs->lsock = -1; 2539 vs->lsock = -1;
2504 - vnc_connect(vs); 2540 + vnc_connect(vs, csock);
2505 } 2541 }
2506 return 0; 2542 return 0;
2507 2543
@@ -2523,6 +2559,5 @@ int vnc_display_open(DisplayState *ds, const char *display) @@ -2523,6 +2559,5 @@ int vnc_display_open(DisplayState *ds, const char *display)
2523 vs->display = dpy; 2559 vs->display = dpy;
2524 } 2560 }
2525 } 2561 }
2526 -  
2527 - return qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs); 2562 + return qemu_set_fd_handler2(vs->lsock, NULL, vnc_listen_read, NULL, vs);
2528 } 2563 }
@@ -101,6 +101,7 @@ enum { @@ -101,6 +101,7 @@ enum {
101 #define VNC_FEATURE_WMVI 3 101 #define VNC_FEATURE_WMVI 3
102 #define VNC_FEATURE_TIGHT 4 102 #define VNC_FEATURE_TIGHT 4
103 #define VNC_FEATURE_ZLIB 5 103 #define VNC_FEATURE_ZLIB 5
  104 +#define VNC_FEATURE_COPYRECT 6
104 105
105 #define VNC_FEATURE_RESIZE_MASK (1 << VNC_FEATURE_RESIZE) 106 #define VNC_FEATURE_RESIZE_MASK (1 << VNC_FEATURE_RESIZE)
106 #define VNC_FEATURE_HEXTILE_MASK (1 << VNC_FEATURE_HEXTILE) 107 #define VNC_FEATURE_HEXTILE_MASK (1 << VNC_FEATURE_HEXTILE)
@@ -108,5 +109,6 @@ enum { @@ -108,5 +109,6 @@ enum {
108 #define VNC_FEATURE_WMVI_MASK (1 << VNC_FEATURE_WMVI) 109 #define VNC_FEATURE_WMVI_MASK (1 << VNC_FEATURE_WMVI)
109 #define VNC_FEATURE_TIGHT_MASK (1 << VNC_FEATURE_TIGHT) 110 #define VNC_FEATURE_TIGHT_MASK (1 << VNC_FEATURE_TIGHT)
110 #define VNC_FEATURE_ZLIB_MASK (1 << VNC_FEATURE_ZLIB) 111 #define VNC_FEATURE_ZLIB_MASK (1 << VNC_FEATURE_ZLIB)
  112 +#define VNC_FEATURE_COPYRECT_MASK (1 << VNC_FEATURE_COPYRECT)
111 113
112 #endif /* __VNCTIGHT_H */ 114 #endif /* __VNCTIGHT_H */