]> Git Repo - qemu.git/blame - ui/vnc.c
input/curses: add kbd delay between keydown and keyup events
[qemu.git] / ui / vnc.c
CommitLineData
7d510b8c
FB
1/*
2 * QEMU VNC display driver
5fafdf24 3 *
7d510b8c
FB
4 * Copyright (C) 2006 Anthony Liguori <[email protected]>
5 * Copyright (C) 2006 Fabrice Bellard
19a490bf 6 * Copyright (C) 2009 Red Hat, Inc
5fafdf24 7 *
7d510b8c
FB
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26
19a490bf 27#include "vnc.h"
bd023f95 28#include "vnc-jobs.h"
40066175 29#include "trace.h"
9c17d615 30#include "sysemu/sysemu.h"
1de7afc9
PB
31#include "qemu/sockets.h"
32#include "qemu/timer.h"
33#include "qemu/acl.h"
7b1b5d19 34#include "qapi/qmp/types.h"
2b54aa87 35#include "qmp-commands.h"
1de7afc9 36#include "qemu/osdep.h"
8d447d10 37#include "ui/input.h"
24236869 38
0f7b2864 39#define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
2430ffe4 40#define VNC_REFRESH_INTERVAL_INC 50
0f7b2864 41#define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
999342a0
CC
42static const struct timeval VNC_REFRESH_STATS = { 0, 500000 };
43static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
24236869
FB
44
45#include "vnc_keysym.h"
70848515
TS
46#include "d3des.h"
47
753b4053 48static VncDisplay *vnc_display; /* needed for info vnc */
a9ce8590 49
d467b679 50static int vnc_cursor_define(VncState *vs);
7bc9318b 51static void vnc_release_modifiers(VncState *vs);
d467b679 52
8cf36489
GH
53static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
54{
55#ifdef _VNC_DEBUG
56 static const char *mn[] = {
57 [0] = "undefined",
58 [VNC_SHARE_MODE_CONNECTING] = "connecting",
59 [VNC_SHARE_MODE_SHARED] = "shared",
60 [VNC_SHARE_MODE_EXCLUSIVE] = "exclusive",
61 [VNC_SHARE_MODE_DISCONNECTED] = "disconnected",
62 };
63 fprintf(stderr, "%s/%d: %s -> %s\n", __func__,
64 vs->csock, mn[vs->share_mode], mn[mode]);
65#endif
66
67 if (vs->share_mode == VNC_SHARE_MODE_EXCLUSIVE) {
68 vs->vd->num_exclusive--;
69 }
70 vs->share_mode = mode;
71 if (vs->share_mode == VNC_SHARE_MODE_EXCLUSIVE) {
72 vs->vd->num_exclusive++;
73 }
74}
75
1ff7df1a
AL
76static char *addr_to_string(const char *format,
77 struct sockaddr_storage *sa,
78 socklen_t salen) {
79 char *addr;
80 char host[NI_MAXHOST];
81 char serv[NI_MAXSERV];
82 int err;
457772e6 83 size_t addrlen;
1ff7df1a
AL
84
85 if ((err = getnameinfo((struct sockaddr *)sa, salen,
86 host, sizeof(host),
87 serv, sizeof(serv),
88 NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
89 VNC_DEBUG("Cannot resolve address %d: %s\n",
90 err, gai_strerror(err));
91 return NULL;
92 }
93
457772e6 94 /* Enough for the existing format + the 2 vars we're
f425c278 95 * substituting in. */
457772e6 96 addrlen = strlen(format) + strlen(host) + strlen(serv);
7267c094 97 addr = g_malloc(addrlen + 1);
457772e6
AL
98 snprintf(addr, addrlen, format, host, serv);
99 addr[addrlen] = '\0';
1ff7df1a
AL
100
101 return addr;
102}
103
2f9606b3
AL
104
105char *vnc_socket_local_addr(const char *format, int fd) {
1ff7df1a
AL
106 struct sockaddr_storage sa;
107 socklen_t salen;
108
109 salen = sizeof(sa);
110 if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0)
111 return NULL;
112
113 return addr_to_string(format, &sa, salen);
114}
115
2f9606b3 116char *vnc_socket_remote_addr(const char *format, int fd) {
1ff7df1a
AL
117 struct sockaddr_storage sa;
118 socklen_t salen;
119
120 salen = sizeof(sa);
121 if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0)
122 return NULL;
123
124 return addr_to_string(format, &sa, salen);
125}
126
d96fd29c
LC
127static int put_addr_qdict(QDict *qdict, struct sockaddr_storage *sa,
128 socklen_t salen)
129{
130 char host[NI_MAXHOST];
131 char serv[NI_MAXSERV];
132 int err;
133
134 if ((err = getnameinfo((struct sockaddr *)sa, salen,
135 host, sizeof(host),
136 serv, sizeof(serv),
137 NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
138 VNC_DEBUG("Cannot resolve address %d: %s\n",
139 err, gai_strerror(err));
140 return -1;
141 }
142
143 qdict_put(qdict, "host", qstring_from_str(host));
144 qdict_put(qdict, "service", qstring_from_str(serv));
dc0d4efc 145 qdict_put(qdict, "family",qstring_from_str(inet_strfamily(sa->ss_family)));
d96fd29c
LC
146
147 return 0;
148}
149
a7789382 150static int vnc_server_addr_put(QDict *qdict, int fd)
d96fd29c
LC
151{
152 struct sockaddr_storage sa;
153 socklen_t salen;
154
155 salen = sizeof(sa);
156 if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0) {
157 return -1;
158 }
159
160 return put_addr_qdict(qdict, &sa, salen);
161}
162
163static int vnc_qdict_remote_addr(QDict *qdict, int fd)
164{
165 struct sockaddr_storage sa;
166 socklen_t salen;
167
168 salen = sizeof(sa);
169 if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0) {
170 return -1;
171 }
172
173 return put_addr_qdict(qdict, &sa, salen);
174}
175
1ff7df1a
AL
176static const char *vnc_auth_name(VncDisplay *vd) {
177 switch (vd->auth) {
178 case VNC_AUTH_INVALID:
179 return "invalid";
180 case VNC_AUTH_NONE:
181 return "none";
182 case VNC_AUTH_VNC:
183 return "vnc";
184 case VNC_AUTH_RA2:
185 return "ra2";
186 case VNC_AUTH_RA2NE:
187 return "ra2ne";
188 case VNC_AUTH_TIGHT:
189 return "tight";
190 case VNC_AUTH_ULTRA:
191 return "ultra";
192 case VNC_AUTH_TLS:
193 return "tls";
194 case VNC_AUTH_VENCRYPT:
195#ifdef CONFIG_VNC_TLS
196 switch (vd->subauth) {
197 case VNC_AUTH_VENCRYPT_PLAIN:
198 return "vencrypt+plain";
199 case VNC_AUTH_VENCRYPT_TLSNONE:
200 return "vencrypt+tls+none";
201 case VNC_AUTH_VENCRYPT_TLSVNC:
202 return "vencrypt+tls+vnc";
203 case VNC_AUTH_VENCRYPT_TLSPLAIN:
204 return "vencrypt+tls+plain";
205 case VNC_AUTH_VENCRYPT_X509NONE:
206 return "vencrypt+x509+none";
207 case VNC_AUTH_VENCRYPT_X509VNC:
208 return "vencrypt+x509+vnc";
209 case VNC_AUTH_VENCRYPT_X509PLAIN:
210 return "vencrypt+x509+plain";
28a76be8
AL
211 case VNC_AUTH_VENCRYPT_TLSSASL:
212 return "vencrypt+tls+sasl";
213 case VNC_AUTH_VENCRYPT_X509SASL:
214 return "vencrypt+x509+sasl";
1ff7df1a
AL
215 default:
216 return "vencrypt";
217 }
218#else
219 return "vencrypt";
220#endif
2f9606b3 221 case VNC_AUTH_SASL:
28a76be8 222 return "sasl";
1ff7df1a
AL
223 }
224 return "unknown";
225}
226
a7789382
LC
227static int vnc_server_info_put(QDict *qdict)
228{
229 if (vnc_server_addr_put(qdict, vnc_display->lsock) < 0) {
230 return -1;
231 }
232
233 qdict_put(qdict, "auth", qstring_from_str(vnc_auth_name(vnc_display)));
234 return 0;
235}
236
4a80dba3 237static void vnc_client_cache_auth(VncState *client)
1ff7df1a 238{
2ded6ad7 239#if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
d96fd29c 240 QDict *qdict;
2ded6ad7 241#endif
1ff7df1a 242
4a80dba3
LC
243 if (!client->info) {
244 return;
d96fd29c 245 }
1263b7d6 246
2ded6ad7 247#if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
4a80dba3 248 qdict = qobject_to_qdict(client->info);
2ded6ad7 249#endif
4a80dba3 250
1263b7d6
AL
251#ifdef CONFIG_VNC_TLS
252 if (client->tls.session &&
d96fd29c
LC
253 client->tls.dname) {
254 qdict_put(qdict, "x509_dname", qstring_from_str(client->tls.dname));
255 }
1263b7d6
AL
256#endif
257#ifdef CONFIG_VNC_SASL
258 if (client->sasl.conn &&
d96fd29c 259 client->sasl.username) {
76825067
LC
260 qdict_put(qdict, "sasl_username",
261 qstring_from_str(client->sasl.username));
d96fd29c 262 }
1263b7d6 263#endif
4a80dba3 264}
d96fd29c 265
4a80dba3
LC
266static void vnc_client_cache_addr(VncState *client)
267{
268 QDict *qdict;
269
270 qdict = qdict_new();
271 if (vnc_qdict_remote_addr(qdict, client->csock) < 0) {
272 QDECREF(qdict);
273 /* XXX: how to report the error? */
274 return;
275 }
276
277 client->info = QOBJECT(qdict);
1ff7df1a
AL
278}
279
586153d9
LC
280static void vnc_qmp_event(VncState *vs, MonitorEvent event)
281{
282 QDict *server;
283 QObject *data;
284
285 if (!vs->info) {
286 return;
287 }
288
289 server = qdict_new();
290 if (vnc_server_info_put(server) < 0) {
291 QDECREF(server);
292 return;
293 }
294
295 data = qobject_from_jsonf("{ 'client': %p, 'server': %p }",
296 vs->info, QOBJECT(server));
297
298 monitor_protocol_event(event, data);
299
300 qobject_incref(vs->info);
301 qobject_decref(data);
302}
303
2b54aa87 304static VncClientInfo *qmp_query_vnc_client(const VncState *client)
a9ce8590 305{
2b54aa87
LC
306 struct sockaddr_storage sa;
307 socklen_t salen = sizeof(sa);
308 char host[NI_MAXHOST];
309 char serv[NI_MAXSERV];
310 VncClientInfo *info;
311
312 if (getpeername(client->csock, (struct sockaddr *)&sa, &salen) < 0) {
313 return NULL;
314 }
315
316 if (getnameinfo((struct sockaddr *)&sa, salen,
317 host, sizeof(host),
318 serv, sizeof(serv),
319 NI_NUMERICHOST | NI_NUMERICSERV) < 0) {
320 return NULL;
321 }
d96fd29c 322
2b54aa87
LC
323 info = g_malloc0(sizeof(*info));
324 info->host = g_strdup(host);
325 info->service = g_strdup(serv);
326 info->family = g_strdup(inet_strfamily(sa.ss_family));
d96fd29c
LC
327
328#ifdef CONFIG_VNC_TLS
2b54aa87
LC
329 if (client->tls.session && client->tls.dname) {
330 info->has_x509_dname = true;
331 info->x509_dname = g_strdup(client->tls.dname);
332 }
d96fd29c
LC
333#endif
334#ifdef CONFIG_VNC_SASL
2b54aa87
LC
335 if (client->sasl.conn && client->sasl.username) {
336 info->has_sasl_username = true;
337 info->sasl_username = g_strdup(client->sasl.username);
d96fd29c 338 }
2b54aa87 339#endif
1ff7df1a 340
2b54aa87 341 return info;
d96fd29c 342}
1ff7df1a 343
2b54aa87 344VncInfo *qmp_query_vnc(Error **errp)
d96fd29c 345{
2b54aa87
LC
346 VncInfo *info = g_malloc0(sizeof(*info));
347
d96fd29c 348 if (vnc_display == NULL || vnc_display->display == NULL) {
2b54aa87 349 info->enabled = false;
d96fd29c 350 } else {
2b54aa87
LC
351 VncClientInfoList *cur_item = NULL;
352 struct sockaddr_storage sa;
353 socklen_t salen = sizeof(sa);
354 char host[NI_MAXHOST];
355 char serv[NI_MAXSERV];
41b4bef6 356 VncState *client;
1ff7df1a 357
2b54aa87
LC
358 info->enabled = true;
359
360 /* for compatibility with the original command */
361 info->has_clients = true;
362
41b4bef6 363 QTAILQ_FOREACH(client, &vnc_display->clients, next) {
2b54aa87
LC
364 VncClientInfoList *cinfo = g_malloc0(sizeof(*info));
365 cinfo->value = qmp_query_vnc_client(client);
366
367 /* XXX: waiting for the qapi to support GSList */
368 if (!cur_item) {
369 info->clients = cur_item = cinfo;
370 } else {
371 cur_item->next = cinfo;
372 cur_item = cinfo;
1ff7df1a 373 }
d96fd29c
LC
374 }
375
417b0b88
PB
376 if (vnc_display->lsock == -1) {
377 return info;
378 }
379
2b54aa87
LC
380 if (getsockname(vnc_display->lsock, (struct sockaddr *)&sa,
381 &salen) == -1) {
382 error_set(errp, QERR_UNDEFINED_ERROR);
383 goto out_error;
384 }
d96fd29c 385
2b54aa87
LC
386 if (getnameinfo((struct sockaddr *)&sa, salen,
387 host, sizeof(host),
388 serv, sizeof(serv),
389 NI_NUMERICHOST | NI_NUMERICSERV) < 0) {
390 error_set(errp, QERR_UNDEFINED_ERROR);
391 goto out_error;
1ff7df1a 392 }
2b54aa87
LC
393
394 info->has_host = true;
395 info->host = g_strdup(host);
396
397 info->has_service = true;
398 info->service = g_strdup(serv);
399
400 info->has_family = true;
401 info->family = g_strdup(inet_strfamily(sa.ss_family));
402
403 info->has_auth = true;
404 info->auth = g_strdup(vnc_auth_name(vnc_display));
a9ce8590 405 }
2b54aa87
LC
406
407 return info;
408
409out_error:
410 qapi_free_VncInfo(info);
411 return NULL;
a9ce8590
FB
412}
413
24236869
FB
414/* TODO
415 1) Get the queue working for IO.
416 2) there is some weirdness when using the -S option (the screen is grey
417 and not totally invalidated
418 3) resolutions > 1024
419*/
420
38ee14f4 421static int vnc_update_client(VncState *vs, int has_dirty, bool sync);
198a0039 422static void vnc_disconnect_start(VncState *vs);
24236869 423
753b4053 424static void vnc_colordepth(VncState *vs);
1fc62412
SS
425static void framebuffer_update_request(VncState *vs, int incremental,
426 int x_position, int y_position,
427 int w, int h);
0f7b2864 428static void vnc_refresh(DisplayChangeListener *dcl);
1fc62412 429static int vnc_refresh_server_surface(VncDisplay *vd);
7eac3a87 430
7c20b4a3 431static void vnc_dpy_update(DisplayChangeListener *dcl,
7c20b4a3 432 int x, int y, int w, int h)
24236869 433{
21ef45d7 434 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
1fc62412 435 struct VncSurface *s = &vd->guest;
d39fa6d8
GH
436 int width = surface_width(vd->ds);
437 int height = surface_height(vd->ds);
24236869 438
91937225
PL
439 /* this is needed this to ensure we updated all affected
440 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
b4c85ddc
PL
441 w += (x % VNC_DIRTY_PIXELS_PER_BIT);
442 x -= (x % VNC_DIRTY_PIXELS_PER_BIT);
0486e8a7 443
9f64916d
GH
444 x = MIN(x, width);
445 y = MIN(y, height);
446 w = MIN(x + w, width) - x;
91937225 447 h = MIN(y + h, height);
788abf8e 448
b4c85ddc 449 for (; y < h; y++) {
91937225
PL
450 bitmap_set(s->dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT,
451 DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));
b4c85ddc 452 }
24236869
FB
453}
454
70a4568f
CC
455void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
456 int32_t encoding)
24236869
FB
457{
458 vnc_write_u16(vs, x);
459 vnc_write_u16(vs, y);
460 vnc_write_u16(vs, w);
461 vnc_write_u16(vs, h);
462
463 vnc_write_s32(vs, encoding);
464}
465
2f9606b3 466void buffer_reserve(Buffer *buffer, size_t len)
89064286
AL
467{
468 if ((buffer->capacity - buffer->offset) < len) {
28a76be8 469 buffer->capacity += (len + 1024);
7267c094 470 buffer->buffer = g_realloc(buffer->buffer, buffer->capacity);
28a76be8
AL
471 if (buffer->buffer == NULL) {
472 fprintf(stderr, "vnc: out of memory\n");
473 exit(1);
474 }
89064286
AL
475 }
476}
477
71a8cdec 478static int buffer_empty(Buffer *buffer)
89064286
AL
479{
480 return buffer->offset == 0;
481}
482
7536ee4b 483uint8_t *buffer_end(Buffer *buffer)
89064286
AL
484{
485 return buffer->buffer + buffer->offset;
486}
487
2f9606b3 488void buffer_reset(Buffer *buffer)
89064286 489{
28a76be8 490 buffer->offset = 0;
89064286
AL
491}
492
5d418e3b
CC
493void buffer_free(Buffer *buffer)
494{
7267c094 495 g_free(buffer->buffer);
5d418e3b
CC
496 buffer->offset = 0;
497 buffer->capacity = 0;
498 buffer->buffer = NULL;
499}
500
2f9606b3 501void buffer_append(Buffer *buffer, const void *data, size_t len)
89064286
AL
502{
503 memcpy(buffer->buffer + buffer->offset, data, len);
504 buffer->offset += len;
505}
506
32ed2680
TH
507void buffer_advance(Buffer *buf, size_t len)
508{
509 memmove(buf->buffer, buf->buffer + len,
510 (buf->offset - len));
511 buf->offset -= len;
512}
513
621aaeb9
GH
514static void vnc_desktop_resize(VncState *vs)
515{
d39fa6d8 516 DisplaySurface *ds = vs->vd->ds;
621aaeb9
GH
517
518 if (vs->csock == -1 || !vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
519 return;
520 }
d39fa6d8
GH
521 if (vs->client_width == surface_width(ds) &&
522 vs->client_height == surface_height(ds)) {
1d4b638a
GH
523 return;
524 }
d39fa6d8
GH
525 vs->client_width = surface_width(ds);
526 vs->client_height = surface_height(ds);
bd023f95 527 vnc_lock_output(vs);
621aaeb9
GH
528 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
529 vnc_write_u8(vs, 0);
530 vnc_write_u16(vs, 1); /* number of rects */
5862d195 531 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
621aaeb9 532 VNC_ENCODING_DESKTOPRESIZE);
bd023f95 533 vnc_unlock_output(vs);
621aaeb9
GH
534 vnc_flush(vs);
535}
536
bd023f95
CC
537static void vnc_abort_display_jobs(VncDisplay *vd)
538{
539 VncState *vs;
540
541 QTAILQ_FOREACH(vs, &vd->clients, next) {
542 vnc_lock_output(vs);
543 vs->abort = true;
544 vnc_unlock_output(vs);
545 }
546 QTAILQ_FOREACH(vs, &vd->clients, next) {
547 vnc_jobs_join(vs);
548 }
549 QTAILQ_FOREACH(vs, &vd->clients, next) {
550 vnc_lock_output(vs);
551 vs->abort = false;
552 vnc_unlock_output(vs);
553 }
554}
bd023f95 555
9f64916d
GH
556int vnc_server_fb_stride(VncDisplay *vd)
557{
558 return pixman_image_get_stride(vd->server);
559}
560
561void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
562{
563 uint8_t *ptr;
564
565 ptr = (uint8_t *)pixman_image_get_data(vd->server);
566 ptr += y * vnc_server_fb_stride(vd);
567 ptr += x * VNC_SERVER_FB_BYTES;
568 return ptr;
569}
12b316d4
PL
570/* this sets only the visible pixels of a dirty bitmap */
571#define VNC_SET_VISIBLE_PIXELS_DIRTY(bitmap, w, h) {\
572 int y;\
573 memset(bitmap, 0x00, sizeof(bitmap));\
574 for (y = 0; y < h; y++) {\
575 bitmap_set(bitmap[y], 0,\
576 DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));\
577 } \
578 }
9f64916d 579
c12aeb86 580static void vnc_dpy_switch(DisplayChangeListener *dcl,
c12aeb86 581 DisplaySurface *surface)
24236869 582{
21ef45d7 583 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
41b4bef6 584 VncState *vs;
1fc62412 585
bd023f95
CC
586 vnc_abort_display_jobs(vd);
587
1fc62412 588 /* server surface */
9f64916d 589 qemu_pixman_image_unref(vd->server);
d39fa6d8 590 vd->ds = surface;
9f64916d 591 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
d39fa6d8
GH
592 surface_width(vd->ds),
593 surface_height(vd->ds),
9f64916d 594 NULL, 0);
24236869 595
6baebed7 596 /* guest surface */
9f64916d 597#if 0 /* FIXME */
1fc62412 598 if (ds_get_bytes_per_pixel(ds) != vd->guest.ds->pf.bytes_per_pixel)
a528b80c 599 console_color_init(ds);
9f64916d
GH
600#endif
601 qemu_pixman_image_unref(vd->guest.fb);
d39fa6d8
GH
602 vd->guest.fb = pixman_image_ref(surface->image);
603 vd->guest.format = surface->format;
12b316d4
PL
604 VNC_SET_VISIBLE_PIXELS_DIRTY(vd->guest.dirty,
605 surface_width(vd->ds),
606 surface_height(vd->ds));
24236869 607
41b4bef6 608 QTAILQ_FOREACH(vs, &vd->clients, next) {
1fc62412 609 vnc_colordepth(vs);
1d4b638a 610 vnc_desktop_resize(vs);
d467b679
GH
611 if (vs->vd->cursor) {
612 vnc_cursor_define(vs);
613 }
12b316d4
PL
614 VNC_SET_VISIBLE_PIXELS_DIRTY(vs->dirty,
615 surface_width(vd->ds),
616 surface_height(vd->ds));
753b4053
AL
617 }
618}
619
3512779a 620/* fastest code */
9f64916d 621static void vnc_write_pixels_copy(VncState *vs,
d467b679 622 void *pixels, int size)
3512779a
FB
623{
624 vnc_write(vs, pixels, size);
625}
626
627/* slowest but generic code. */
70a4568f 628void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
3512779a 629{
7eac3a87 630 uint8_t r, g, b;
1fc62412 631
9f64916d
GH
632#if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
633 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
634 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
635 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
636#else
637# error need some bits here if you change VNC_SERVER_FB_FORMAT
638#endif
639 v = (r << vs->client_pf.rshift) |
640 (g << vs->client_pf.gshift) |
641 (b << vs->client_pf.bshift);
642 switch (vs->client_pf.bytes_per_pixel) {
3512779a
FB
643 case 1:
644 buf[0] = v;
645 break;
646 case 2:
9f64916d 647 if (vs->client_be) {
3512779a
FB
648 buf[0] = v >> 8;
649 buf[1] = v;
650 } else {
651 buf[1] = v >> 8;
652 buf[0] = v;
653 }
654 break;
655 default:
656 case 4:
9f64916d 657 if (vs->client_be) {
3512779a
FB
658 buf[0] = v >> 24;
659 buf[1] = v >> 16;
660 buf[2] = v >> 8;
661 buf[3] = v;
662 } else {
663 buf[3] = v >> 24;
664 buf[2] = v >> 16;
665 buf[1] = v >> 8;
666 buf[0] = v;
667 }
668 break;
669 }
670}
671
9f64916d 672static void vnc_write_pixels_generic(VncState *vs,
d467b679 673 void *pixels1, int size)
3512779a 674{
3512779a 675 uint8_t buf[4];
3512779a 676
9f64916d 677 if (VNC_SERVER_FB_BYTES == 4) {
7eac3a87
AL
678 uint32_t *pixels = pixels1;
679 int n, i;
680 n = size >> 2;
9f64916d 681 for (i = 0; i < n; i++) {
7eac3a87 682 vnc_convert_pixel(vs, buf, pixels[i]);
9f64916d 683 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
7eac3a87 684 }
3512779a
FB
685 }
686}
687
a885211e 688int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
24236869
FB
689{
690 int i;
60fe76f3 691 uint8_t *row;
1fc62412 692 VncDisplay *vd = vs->vd;
24236869 693
9f64916d 694 row = vnc_server_fb_ptr(vd, x, y);
24236869 695 for (i = 0; i < h; i++) {
9f64916d
GH
696 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
697 row += vnc_server_fb_stride(vd);
24236869 698 }
a885211e 699 return 1;
24236869
FB
700}
701
bd023f95 702int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
24236869 703{
a885211e
CC
704 int n = 0;
705
fb437313 706 switch(vs->vnc_encoding) {
28a76be8 707 case VNC_ENCODING_ZLIB:
a885211e 708 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
28a76be8
AL
709 break;
710 case VNC_ENCODING_HEXTILE:
711 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
a885211e 712 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
28a76be8 713 break;
380282b0
CC
714 case VNC_ENCODING_TIGHT:
715 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
716 break;
efe556ad
CC
717 case VNC_ENCODING_TIGHT_PNG:
718 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
719 break;
148954fa
CC
720 case VNC_ENCODING_ZRLE:
721 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
722 break;
723 case VNC_ENCODING_ZYWRLE:
724 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
725 break;
28a76be8
AL
726 default:
727 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
a885211e 728 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
28a76be8 729 break;
fb437313 730 }
a885211e 731 return n;
24236869
FB
732}
733
753b4053 734static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
24236869 735{
3e28c9ad 736 /* send bitblit op to the vnc client */
bd023f95 737 vnc_lock_output(vs);
46a183da 738 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
24236869
FB
739 vnc_write_u8(vs, 0);
740 vnc_write_u16(vs, 1); /* number of rects */
29fa4ed9 741 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
24236869
FB
742 vnc_write_u16(vs, src_x);
743 vnc_write_u16(vs, src_y);
bd023f95 744 vnc_unlock_output(vs);
24236869
FB
745 vnc_flush(vs);
746}
747
7c20b4a3 748static void vnc_dpy_copy(DisplayChangeListener *dcl,
7c20b4a3
GH
749 int src_x, int src_y,
750 int dst_x, int dst_y, int w, int h)
753b4053 751{
21ef45d7 752 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
198a0039 753 VncState *vs, *vn;
1fc62412
SS
754 uint8_t *src_row;
755 uint8_t *dst_row;
9f64916d 756 int i, x, y, pitch, inc, w_lim, s;
1fc62412 757 int cmp_bytes;
198a0039 758
1fc62412 759 vnc_refresh_server_surface(vd);
41b4bef6 760 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
198a0039
GH
761 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
762 vs->force_update = 1;
38ee14f4 763 vnc_update_client(vs, 1, true);
198a0039
GH
764 /* vs might be free()ed here */
765 }
766 }
767
1fc62412 768 /* do bitblit op on the local surface too */
9f64916d
GH
769 pitch = vnc_server_fb_stride(vd);
770 src_row = vnc_server_fb_ptr(vd, src_x, src_y);
771 dst_row = vnc_server_fb_ptr(vd, dst_x, dst_y);
1fc62412
SS
772 y = dst_y;
773 inc = 1;
774 if (dst_y > src_y) {
775 /* copy backwards */
776 src_row += pitch * (h-1);
777 dst_row += pitch * (h-1);
778 pitch = -pitch;
779 y = dst_y + h - 1;
780 inc = -1;
781 }
b4c85ddc
PL
782 w_lim = w - (VNC_DIRTY_PIXELS_PER_BIT - (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
783 if (w_lim < 0) {
1fc62412 784 w_lim = w;
b4c85ddc
PL
785 } else {
786 w_lim = w - (w_lim % VNC_DIRTY_PIXELS_PER_BIT);
787 }
1fc62412
SS
788 for (i = 0; i < h; i++) {
789 for (x = 0; x <= w_lim;
790 x += s, src_row += cmp_bytes, dst_row += cmp_bytes) {
791 if (x == w_lim) {
792 if ((s = w - w_lim) == 0)
793 break;
794 } else if (!x) {
b4c85ddc
PL
795 s = (VNC_DIRTY_PIXELS_PER_BIT -
796 (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
1fc62412
SS
797 s = MIN(s, w_lim);
798 } else {
b4c85ddc 799 s = VNC_DIRTY_PIXELS_PER_BIT;
1fc62412 800 }
9f64916d 801 cmp_bytes = s * VNC_SERVER_FB_BYTES;
1fc62412
SS
802 if (memcmp(src_row, dst_row, cmp_bytes) == 0)
803 continue;
804 memmove(dst_row, src_row, cmp_bytes);
41b4bef6
AS
805 QTAILQ_FOREACH(vs, &vd->clients, next) {
806 if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
b4c85ddc
PL
807 set_bit(((x + dst_x) / VNC_DIRTY_PIXELS_PER_BIT),
808 vs->dirty[y]);
41b4bef6 809 }
1fc62412
SS
810 }
811 }
9f64916d
GH
812 src_row += pitch - w * VNC_SERVER_FB_BYTES;
813 dst_row += pitch - w * VNC_SERVER_FB_BYTES;
1fc62412
SS
814 y += inc;
815 }
816
41b4bef6
AS
817 QTAILQ_FOREACH(vs, &vd->clients, next) {
818 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
753b4053 819 vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
41b4bef6 820 }
753b4053
AL
821 }
822}
823
7c20b4a3 824static void vnc_mouse_set(DisplayChangeListener *dcl,
7c20b4a3 825 int x, int y, int visible)
d467b679
GH
826{
827 /* can we ask the client(s) to move the pointer ??? */
828}
829
830static int vnc_cursor_define(VncState *vs)
831{
832 QEMUCursor *c = vs->vd->cursor;
d467b679
GH
833 int isize;
834
835 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
d01f9595 836 vnc_lock_output(vs);
d467b679
GH
837 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
838 vnc_write_u8(vs, 0); /* padding */
839 vnc_write_u16(vs, 1); /* # of rects */
840 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
841 VNC_ENCODING_RICH_CURSOR);
9f64916d
GH
842 isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
843 vnc_write_pixels_generic(vs, c->data, isize);
d467b679 844 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
d01f9595 845 vnc_unlock_output(vs);
d467b679
GH
846 return 0;
847 }
848 return -1;
849}
850
7c20b4a3 851static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
7c20b4a3 852 QEMUCursor *c)
d467b679
GH
853{
854 VncDisplay *vd = vnc_display;
855 VncState *vs;
856
857 cursor_put(vd->cursor);
7267c094 858 g_free(vd->cursor_mask);
d467b679
GH
859
860 vd->cursor = c;
861 cursor_get(vd->cursor);
862 vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
7267c094 863 vd->cursor_mask = g_malloc0(vd->cursor_msize);
d467b679
GH
864 cursor_get_mono_mask(c, 0, vd->cursor_mask);
865
866 QTAILQ_FOREACH(vs, &vd->clients, next) {
867 vnc_cursor_define(vs);
868 }
869}
870
1fc62412 871static int find_and_clear_dirty_height(struct VncState *vs,
6c71a539 872 int y, int last_x, int x, int height)
24236869
FB
873{
874 int h;
875
6c71a539 876 for (h = 1; h < (height - y); h++) {
bc2429b9 877 if (!test_bit(last_x, vs->dirty[y + h])) {
28a76be8 878 break;
bc2429b9 879 }
863d7c91 880 bitmap_clear(vs->dirty[y + h], last_x, x - last_x);
24236869
FB
881 }
882
883 return h;
884}
885
38ee14f4 886static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
24236869 887{
24236869 888 if (vs->need_update && vs->csock != -1) {
1fc62412 889 VncDisplay *vd = vs->vd;
bd023f95 890 VncJob *job;
28a76be8 891 int y;
2f487a3d 892 int height, width;
bd023f95
CC
893 int n = 0;
894
703bc68f 895 if (vs->output.offset && !vs->audio_cap && !vs->force_update)
c522d0e2 896 /* kernel send buffers are full -> drop frames to throttle */
2430ffe4 897 return 0;
a0ecfb73 898
703bc68f 899 if (!has_dirty && !vs->audio_cap && !vs->force_update)
2430ffe4 900 return 0;
28a76be8 901
6baebed7
AL
902 /*
903 * Send screen updates to the vnc client using the server
904 * surface and server dirty map. guest surface updates
905 * happening in parallel don't disturb us, the next pass will
906 * send them to the client.
907 */
bd023f95 908 job = vnc_job_new(vs);
28a76be8 909
9f64916d 910 height = MIN(pixman_image_get_height(vd->server), vs->client_height);
2f487a3d 911 width = MIN(pixman_image_get_width(vd->server), vs->client_width);
847ce6a1 912
12b316d4
PL
913 y = 0;
914 for (;;) {
915 int x, h;
916 unsigned long x2;
917 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
918 height * VNC_DIRTY_BPL(vs),
919 y * VNC_DIRTY_BPL(vs));
920 if (offset == height * VNC_DIRTY_BPL(vs)) {
921 /* no more dirty bits */
922 break;
28a76be8 923 }
12b316d4
PL
924 y = offset / VNC_DIRTY_BPL(vs);
925 x = offset % VNC_DIRTY_BPL(vs);
926 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
927 VNC_DIRTY_BPL(vs), x);
928 bitmap_clear(vs->dirty[y], x, x2 - x);
929 h = find_and_clear_dirty_height(vs, y, x, x2, height);
2f487a3d
PL
930 x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
931 if (x2 > x) {
932 n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
933 (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
934 }
28a76be8 935 }
bd023f95
CC
936
937 vnc_job_push(job);
c522d0e2 938 vs->force_update = 0;
bd023f95 939 return n;
24236869 940 }
24236869 941
38ee14f4 942 if (vs->csock == -1) {
198a0039 943 vnc_disconnect_finish(vs);
38ee14f4
GH
944 } else if (sync) {
945 vnc_jobs_join(vs);
946 }
2430ffe4
SS
947
948 return 0;
24236869
FB
949}
950
429a8ed3 951/* audio */
952static void audio_capture_notify(void *opaque, audcnotification_e cmd)
953{
954 VncState *vs = opaque;
955
956 switch (cmd) {
957 case AUD_CNOTIFY_DISABLE:
bd023f95 958 vnc_lock_output(vs);
46a183da
DB
959 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
960 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
961 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
bd023f95 962 vnc_unlock_output(vs);
429a8ed3 963 vnc_flush(vs);
964 break;
965
966 case AUD_CNOTIFY_ENABLE:
bd023f95 967 vnc_lock_output(vs);
46a183da
DB
968 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
969 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
970 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
bd023f95 971 vnc_unlock_output(vs);
429a8ed3 972 vnc_flush(vs);
973 break;
974 }
975}
976
977static void audio_capture_destroy(void *opaque)
978{
979}
980
981static void audio_capture(void *opaque, void *buf, int size)
982{
983 VncState *vs = opaque;
984
bd023f95 985 vnc_lock_output(vs);
46a183da
DB
986 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
987 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
988 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
429a8ed3 989 vnc_write_u32(vs, size);
990 vnc_write(vs, buf, size);
bd023f95 991 vnc_unlock_output(vs);
429a8ed3 992 vnc_flush(vs);
993}
994
995static void audio_add(VncState *vs)
996{
997 struct audio_capture_ops ops;
998
999 if (vs->audio_cap) {
027a79c3 1000 error_report("audio already running");
429a8ed3 1001 return;
1002 }
1003
1004 ops.notify = audio_capture_notify;
1005 ops.destroy = audio_capture_destroy;
1006 ops.capture = audio_capture;
1007
1a7dafce 1008 vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
429a8ed3 1009 if (!vs->audio_cap) {
027a79c3 1010 error_report("Failed to add audio capture");
429a8ed3 1011 }
1012}
1013
1014static void audio_del(VncState *vs)
1015{
1016 if (vs->audio_cap) {
1017 AUD_del_capture(vs->audio_cap, vs);
1018 vs->audio_cap = NULL;
1019 }
1020}
1021
198a0039
GH
1022static void vnc_disconnect_start(VncState *vs)
1023{
1024 if (vs->csock == -1)
1025 return;
8cf36489 1026 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
198a0039
GH
1027 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
1028 closesocket(vs->csock);
1029 vs->csock = -1;
1030}
1031
7536ee4b 1032void vnc_disconnect_finish(VncState *vs)
198a0039 1033{
7d964c9d
CC
1034 int i;
1035
bd023f95
CC
1036 vnc_jobs_join(vs); /* Wait encoding jobs */
1037
1038 vnc_lock_output(vs);
0d72f3d3
LC
1039 vnc_qmp_event(vs, QEVENT_VNC_DISCONNECTED);
1040
5d418e3b
CC
1041 buffer_free(&vs->input);
1042 buffer_free(&vs->output);
7536ee4b
TH
1043#ifdef CONFIG_VNC_WS
1044 buffer_free(&vs->ws_input);
1045 buffer_free(&vs->ws_output);
1046#endif /* CONFIG_VNC_WS */
4a80dba3
LC
1047
1048 qobject_decref(vs->info);
1049
161c4f20 1050 vnc_zlib_clear(vs);
380282b0 1051 vnc_tight_clear(vs);
148954fa 1052 vnc_zrle_clear(vs);
161c4f20 1053
198a0039
GH
1054#ifdef CONFIG_VNC_TLS
1055 vnc_tls_client_cleanup(vs);
1056#endif /* CONFIG_VNC_TLS */
1057#ifdef CONFIG_VNC_SASL
1058 vnc_sasl_client_cleanup(vs);
1059#endif /* CONFIG_VNC_SASL */
1060 audio_del(vs);
7bc9318b 1061 vnc_release_modifiers(vs);
198a0039 1062
6fd8e79a
TH
1063 if (vs->initialized) {
1064 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1065 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1066 }
41b4bef6 1067
3a0558b5
GH
1068 if (vs->vd->lock_key_sync)
1069 qemu_remove_led_event_handler(vs->led);
bd023f95
CC
1070 vnc_unlock_output(vs);
1071
bd023f95 1072 qemu_mutex_destroy(&vs->output_mutex);
6fd8e79a
TH
1073 if (vs->bh != NULL) {
1074 qemu_bh_delete(vs->bh);
1075 }
175b2a6e 1076 buffer_free(&vs->jobs_buffer);
175b2a6e 1077
7d964c9d 1078 for (i = 0; i < VNC_STAT_ROWS; ++i) {
7267c094 1079 g_free(vs->lossy_rect[i]);
7d964c9d 1080 }
7267c094
AL
1081 g_free(vs->lossy_rect);
1082 g_free(vs);
198a0039 1083}
2f9606b3
AL
1084
1085int vnc_client_io_error(VncState *vs, int ret, int last_errno)
24236869
FB
1086{
1087 if (ret == 0 || ret == -1) {
ea01e5fd
AZ
1088 if (ret == -1) {
1089 switch (last_errno) {
1090 case EINTR:
1091 case EAGAIN:
1092#ifdef _WIN32
1093 case WSAEWOULDBLOCK:
1094#endif
1095 return 0;
1096 default:
1097 break;
1098 }
1099 }
24236869 1100
198a0039
GH
1101 VNC_DEBUG("Closing down client sock: ret %d, errno %d\n",
1102 ret, ret < 0 ? last_errno : 0);
1103 vnc_disconnect_start(vs);
6baebed7 1104
28a76be8 1105 return 0;
24236869
FB
1106 }
1107 return ret;
1108}
1109
5fb6c7a8
AL
1110
1111void vnc_client_error(VncState *vs)
24236869 1112{
198a0039
GH
1113 VNC_DEBUG("Closing down client sock: protocol error\n");
1114 vnc_disconnect_start(vs);
24236869
FB
1115}
1116
0057a0d5
TH
1117#ifdef CONFIG_VNC_TLS
1118static long vnc_client_write_tls(gnutls_session_t *session,
1119 const uint8_t *data,
1120 size_t datalen)
1121{
1122 long ret = gnutls_write(*session, data, datalen);
1123 if (ret < 0) {
1124 if (ret == GNUTLS_E_AGAIN) {
1125 errno = EAGAIN;
1126 } else {
1127 errno = EIO;
1128 }
1129 ret = -1;
1130 }
1131 return ret;
1132}
1133#endif /* CONFIG_VNC_TLS */
2f9606b3
AL
1134
1135/*
1136 * Called to write a chunk of data to the client socket. The data may
1137 * be the raw data, or may have already been encoded by SASL.
1138 * The data will be written either straight onto the socket, or
1139 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1140 *
1141 * NB, it is theoretically possible to have 2 layers of encryption,
1142 * both SASL, and this TLS layer. It is highly unlikely in practice
1143 * though, since SASL encryption will typically be a no-op if TLS
1144 * is active
1145 *
1146 * Returns the number of bytes written, which may be less than
1147 * the requested 'datalen' if the socket would block. Returns
1148 * -1 on error, and disconnects the client socket.
1149 */
1150long vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
24236869 1151{
ceb5caaf 1152 long ret;
eb38c52c 1153#ifdef CONFIG_VNC_TLS
5fb6c7a8 1154 if (vs->tls.session) {
0057a0d5
TH
1155 ret = vnc_client_write_tls(&vs->tls.session, data, datalen);
1156 } else {
1157#ifdef CONFIG_VNC_WS
1158 if (vs->ws_tls.session) {
1159 ret = vnc_client_write_tls(&vs->ws_tls.session, data, datalen);
1160 } else
1161#endif /* CONFIG_VNC_WS */
1162#endif /* CONFIG_VNC_TLS */
1163 {
1164 ret = send(vs->csock, (const void *)data, datalen, 0);
28a76be8 1165 }
0057a0d5
TH
1166#ifdef CONFIG_VNC_TLS
1167 }
8d5d2d4c 1168#endif /* CONFIG_VNC_TLS */
23decc87 1169 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
2f9606b3
AL
1170 return vnc_client_io_error(vs, ret, socket_error());
1171}
1172
1173
1174/*
1175 * Called to write buffered data to the client socket, when not
1176 * using any SASL SSF encryption layers. Will write as much data
1177 * as possible without blocking. If all buffered data is written,
1178 * will switch the FD poll() handler back to read monitoring.
1179 *
1180 * Returns the number of bytes written, which may be less than
1181 * the buffered output data if the socket would block. Returns
1182 * -1 on error, and disconnects the client socket.
1183 */
1184static long vnc_client_write_plain(VncState *vs)
1185{
1186 long ret;
1187
1188#ifdef CONFIG_VNC_SASL
23decc87 1189 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
2f9606b3
AL
1190 vs->output.buffer, vs->output.capacity, vs->output.offset,
1191 vs->sasl.waitWriteSSF);
1192
1193 if (vs->sasl.conn &&
1194 vs->sasl.runSSF &&
1195 vs->sasl.waitWriteSSF) {
1196 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1197 if (ret)
1198 vs->sasl.waitWriteSSF -= ret;
1199 } else
1200#endif /* CONFIG_VNC_SASL */
1201 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
24236869 1202 if (!ret)
2f9606b3 1203 return 0;
24236869 1204
32ed2680 1205 buffer_advance(&vs->output, ret);
24236869
FB
1206
1207 if (vs->output.offset == 0) {
28a76be8 1208 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
24236869 1209 }
2f9606b3
AL
1210
1211 return ret;
1212}
1213
1214
1215/*
1216 * First function called whenever there is data to be written to
1217 * the client socket. Will delegate actual work according to whether
1218 * SASL SSF layers are enabled (thus requiring encryption calls)
1219 */
bd023f95 1220static void vnc_client_write_locked(void *opaque)
2f9606b3 1221{
2f9606b3
AL
1222 VncState *vs = opaque;
1223
1224#ifdef CONFIG_VNC_SASL
1225 if (vs->sasl.conn &&
1226 vs->sasl.runSSF &&
9678d950
BS
1227 !vs->sasl.waitWriteSSF) {
1228 vnc_client_write_sasl(vs);
1229 } else
2f9606b3 1230#endif /* CONFIG_VNC_SASL */
7536ee4b
TH
1231 {
1232#ifdef CONFIG_VNC_WS
1233 if (vs->encode_ws) {
1234 vnc_client_write_ws(vs);
1235 } else
1236#endif /* CONFIG_VNC_WS */
1237 {
1238 vnc_client_write_plain(vs);
1239 }
1240 }
24236869
FB
1241}
1242
bd023f95
CC
1243void vnc_client_write(void *opaque)
1244{
1245 VncState *vs = opaque;
1246
1247 vnc_lock_output(vs);
7536ee4b
TH
1248 if (vs->output.offset
1249#ifdef CONFIG_VNC_WS
1250 || vs->ws_output.offset
1251#endif
1252 ) {
bd023f95 1253 vnc_client_write_locked(opaque);
ac71103d 1254 } else if (vs->csock != -1) {
bd023f95
CC
1255 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
1256 }
1257 vnc_unlock_output(vs);
1258}
1259
5fb6c7a8 1260void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
24236869
FB
1261{
1262 vs->read_handler = func;
1263 vs->read_handler_expect = expecting;
1264}
1265
0057a0d5
TH
1266#ifdef CONFIG_VNC_TLS
1267static long vnc_client_read_tls(gnutls_session_t *session, uint8_t *data,
1268 size_t datalen)
1269{
1270 long ret = gnutls_read(*session, data, datalen);
1271 if (ret < 0) {
1272 if (ret == GNUTLS_E_AGAIN) {
1273 errno = EAGAIN;
1274 } else {
1275 errno = EIO;
1276 }
1277 ret = -1;
1278 }
1279 return ret;
1280}
1281#endif /* CONFIG_VNC_TLS */
2f9606b3
AL
1282
1283/*
1284 * Called to read a chunk of data from the client socket. The data may
1285 * be the raw data, or may need to be further decoded by SASL.
1286 * The data will be read either straight from to the socket, or
1287 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1288 *
1289 * NB, it is theoretically possible to have 2 layers of encryption,
1290 * both SASL, and this TLS layer. It is highly unlikely in practice
1291 * though, since SASL encryption will typically be a no-op if TLS
1292 * is active
1293 *
1294 * Returns the number of bytes read, which may be less than
1295 * the requested 'datalen' if the socket would block. Returns
1296 * -1 on error, and disconnects the client socket.
1297 */
1298long vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
24236869 1299{
ceb5caaf 1300 long ret;
eb38c52c 1301#ifdef CONFIG_VNC_TLS
5fb6c7a8 1302 if (vs->tls.session) {
0057a0d5
TH
1303 ret = vnc_client_read_tls(&vs->tls.session, data, datalen);
1304 } else {
1305#ifdef CONFIG_VNC_WS
1306 if (vs->ws_tls.session) {
1307 ret = vnc_client_read_tls(&vs->ws_tls.session, data, datalen);
1308 } else
1309#endif /* CONFIG_VNC_WS */
1310#endif /* CONFIG_VNC_TLS */
1311 {
1312 ret = qemu_recv(vs->csock, data, datalen, 0);
28a76be8 1313 }
0057a0d5
TH
1314#ifdef CONFIG_VNC_TLS
1315 }
8d5d2d4c 1316#endif /* CONFIG_VNC_TLS */
23decc87 1317 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
2f9606b3
AL
1318 return vnc_client_io_error(vs, ret, socket_error());
1319}
24236869 1320
2f9606b3
AL
1321
1322/*
1323 * Called to read data from the client socket to the input buffer,
1324 * when not using any SASL SSF encryption layers. Will read as much
1325 * data as possible without blocking.
1326 *
1327 * Returns the number of bytes read. Returns -1 on error, and
1328 * disconnects the client socket.
1329 */
1330static long vnc_client_read_plain(VncState *vs)
1331{
1332 int ret;
23decc87 1333 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
2f9606b3
AL
1334 vs->input.buffer, vs->input.capacity, vs->input.offset);
1335 buffer_reserve(&vs->input, 4096);
1336 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1337 if (!ret)
1338 return 0;
24236869 1339 vs->input.offset += ret;
2f9606b3
AL
1340 return ret;
1341}
1342
175b2a6e
CC
1343static void vnc_jobs_bh(void *opaque)
1344{
1345 VncState *vs = opaque;
1346
1347 vnc_jobs_consume_buffer(vs);
1348}
2f9606b3
AL
1349
1350/*
1351 * First function called whenever there is more data to be read from
1352 * the client socket. Will delegate actual work according to whether
1353 * SASL SSF layers are enabled (thus requiring decryption calls)
1354 */
1355void vnc_client_read(void *opaque)
1356{
1357 VncState *vs = opaque;
1358 long ret;
1359
1360#ifdef CONFIG_VNC_SASL
1361 if (vs->sasl.conn && vs->sasl.runSSF)
1362 ret = vnc_client_read_sasl(vs);
1363 else
1364#endif /* CONFIG_VNC_SASL */
7536ee4b
TH
1365#ifdef CONFIG_VNC_WS
1366 if (vs->encode_ws) {
1367 ret = vnc_client_read_ws(vs);
1368 if (ret == -1) {
1369 vnc_disconnect_start(vs);
1370 return;
1371 } else if (ret == -2) {
1372 vnc_client_error(vs);
1373 return;
1374 }
1375 } else
1376#endif /* CONFIG_VNC_WS */
1377 {
2f9606b3 1378 ret = vnc_client_read_plain(vs);
7536ee4b 1379 }
198a0039
GH
1380 if (!ret) {
1381 if (vs->csock == -1)
1382 vnc_disconnect_finish(vs);
28a76be8 1383 return;
198a0039 1384 }
24236869
FB
1385
1386 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
28a76be8
AL
1387 size_t len = vs->read_handler_expect;
1388 int ret;
1389
1390 ret = vs->read_handler(vs, vs->input.buffer, len);
198a0039
GH
1391 if (vs->csock == -1) {
1392 vnc_disconnect_finish(vs);
28a76be8 1393 return;
198a0039 1394 }
28a76be8
AL
1395
1396 if (!ret) {
32ed2680 1397 buffer_advance(&vs->input, len);
28a76be8
AL
1398 } else {
1399 vs->read_handler_expect = ret;
1400 }
24236869
FB
1401 }
1402}
1403
5fb6c7a8 1404void vnc_write(VncState *vs, const void *data, size_t len)
24236869
FB
1405{
1406 buffer_reserve(&vs->output, len);
1407
198a0039 1408 if (vs->csock != -1 && buffer_empty(&vs->output)) {
28a76be8 1409 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
24236869
FB
1410 }
1411
1412 buffer_append(&vs->output, data, len);
1413}
1414
5fb6c7a8 1415void vnc_write_s32(VncState *vs, int32_t value)
24236869
FB
1416{
1417 vnc_write_u32(vs, *(uint32_t *)&value);
1418}
1419
5fb6c7a8 1420void vnc_write_u32(VncState *vs, uint32_t value)
24236869
FB
1421{
1422 uint8_t buf[4];
1423
1424 buf[0] = (value >> 24) & 0xFF;
1425 buf[1] = (value >> 16) & 0xFF;
1426 buf[2] = (value >> 8) & 0xFF;
1427 buf[3] = value & 0xFF;
1428
1429 vnc_write(vs, buf, 4);
1430}
1431
5fb6c7a8 1432void vnc_write_u16(VncState *vs, uint16_t value)
24236869 1433{
64f5a135 1434 uint8_t buf[2];
24236869
FB
1435
1436 buf[0] = (value >> 8) & 0xFF;
1437 buf[1] = value & 0xFF;
1438
1439 vnc_write(vs, buf, 2);
1440}
1441
5fb6c7a8 1442void vnc_write_u8(VncState *vs, uint8_t value)
24236869
FB
1443{
1444 vnc_write(vs, (char *)&value, 1);
1445}
1446
5fb6c7a8 1447void vnc_flush(VncState *vs)
24236869 1448{
bd023f95 1449 vnc_lock_output(vs);
7536ee4b
TH
1450 if (vs->csock != -1 && (vs->output.offset
1451#ifdef CONFIG_VNC_WS
1452 || vs->ws_output.offset
1453#endif
1454 )) {
bd023f95
CC
1455 vnc_client_write_locked(vs);
1456 }
1457 vnc_unlock_output(vs);
24236869
FB
1458}
1459
71a8cdec 1460static uint8_t read_u8(uint8_t *data, size_t offset)
24236869
FB
1461{
1462 return data[offset];
1463}
1464
71a8cdec 1465static uint16_t read_u16(uint8_t *data, size_t offset)
24236869
FB
1466{
1467 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1468}
1469
71a8cdec 1470static int32_t read_s32(uint8_t *data, size_t offset)
24236869
FB
1471{
1472 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
28a76be8 1473 (data[offset + 2] << 8) | data[offset + 3]);
24236869
FB
1474}
1475
5fb6c7a8 1476uint32_t read_u32(uint8_t *data, size_t offset)
24236869
FB
1477{
1478 return ((data[offset] << 24) | (data[offset + 1] << 16) |
28a76be8 1479 (data[offset + 2] << 8) | data[offset + 3]);
24236869
FB
1480}
1481
60fe76f3 1482static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
24236869
FB
1483{
1484}
1485
9e8dd451 1486static void check_pointer_type_change(Notifier *notifier, void *data)
564c337e 1487{
37c34d9d 1488 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
14768eba 1489 int absolute = qemu_input_is_absolute();
37c34d9d 1490
29fa4ed9 1491 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
bd023f95 1492 vnc_lock_output(vs);
46a183da 1493 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
28a76be8
AL
1494 vnc_write_u8(vs, 0);
1495 vnc_write_u16(vs, 1);
1496 vnc_framebuffer_update(vs, absolute, 0,
d39fa6d8
GH
1497 surface_width(vs->vd->ds),
1498 surface_height(vs->vd->ds),
29fa4ed9 1499 VNC_ENCODING_POINTER_TYPE_CHANGE);
bd023f95 1500 vnc_unlock_output(vs);
28a76be8 1501 vnc_flush(vs);
564c337e
FB
1502 }
1503 vs->absolute = absolute;
1504}
1505
24236869
FB
1506static void pointer_event(VncState *vs, int button_mask, int x, int y)
1507{
14768eba
GH
1508 static uint32_t bmap[INPUT_BUTTON_MAX] = {
1509 [INPUT_BUTTON_LEFT] = 0x01,
1510 [INPUT_BUTTON_MIDDLE] = 0x02,
1511 [INPUT_BUTTON_RIGHT] = 0x04,
1512 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1513 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
1514 };
1515 QemuConsole *con = vs->vd->dcl.con;
d39fa6d8
GH
1516 int width = surface_width(vs->vd->ds);
1517 int height = surface_height(vs->vd->ds);
24236869 1518
14768eba
GH
1519 if (vs->last_bmask != button_mask) {
1520 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1521 vs->last_bmask = button_mask;
1522 }
564c337e
FB
1523
1524 if (vs->absolute) {
14768eba
GH
1525 qemu_input_queue_abs(con, INPUT_AXIS_X, x, width);
1526 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, height);
29fa4ed9 1527 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
14768eba
GH
1528 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1529 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
564c337e 1530 } else {
14768eba
GH
1531 if (vs->last_x != -1) {
1532 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1533 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1534 }
28a76be8
AL
1535 vs->last_x = x;
1536 vs->last_y = y;
24236869 1537 }
14768eba 1538 qemu_input_event_sync();
24236869
FB
1539}
1540
64f5a135
FB
1541static void reset_keys(VncState *vs)
1542{
1543 int i;
1544 for(i = 0; i < 256; i++) {
1545 if (vs->modifiers_state[i]) {
8d447d10 1546 qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
64f5a135
FB
1547 vs->modifiers_state[i] = 0;
1548 }
1549 }
1550}
1551
a528b80c
AZ
1552static void press_key(VncState *vs, int keysym)
1553{
44bb61c8 1554 int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
8d447d10
GH
1555 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
1556 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
a528b80c
AZ
1557}
1558
ab99e5c1
LL
1559static int current_led_state(VncState *vs)
1560{
1561 int ledstate = 0;
1562
1563 if (vs->modifiers_state[0x46]) {
1564 ledstate |= QEMU_SCROLL_LOCK_LED;
1565 }
1566 if (vs->modifiers_state[0x45]) {
1567 ledstate |= QEMU_NUM_LOCK_LED;
1568 }
1569 if (vs->modifiers_state[0x3a]) {
1570 ledstate |= QEMU_CAPS_LOCK_LED;
1571 }
1572
1573 return ledstate;
1574}
1575
1576static void vnc_led_state_change(VncState *vs)
1577{
1578 int ledstate = 0;
1579
1580 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1581 return;
1582 }
1583
1584 ledstate = current_led_state(vs);
1585 vnc_lock_output(vs);
1586 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1587 vnc_write_u8(vs, 0);
1588 vnc_write_u16(vs, 1);
1589 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1590 vnc_write_u8(vs, ledstate);
1591 vnc_unlock_output(vs);
1592 vnc_flush(vs);
1593}
1594
7ffb82ca
GH
1595static void kbd_leds(void *opaque, int ledstate)
1596{
1597 VncState *vs = opaque;
96f3d174 1598 int caps, num, scr;
1483adcf 1599 bool has_changed = (ledstate != current_led_state(vs));
7ffb82ca 1600
40066175
GH
1601 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1602 (ledstate & QEMU_NUM_LOCK_LED),
1603 (ledstate & QEMU_SCROLL_LOCK_LED));
1604
7ffb82ca
GH
1605 caps = ledstate & QEMU_CAPS_LOCK_LED ? 1 : 0;
1606 num = ledstate & QEMU_NUM_LOCK_LED ? 1 : 0;
96f3d174 1607 scr = ledstate & QEMU_SCROLL_LOCK_LED ? 1 : 0;
7ffb82ca
GH
1608
1609 if (vs->modifiers_state[0x3a] != caps) {
1610 vs->modifiers_state[0x3a] = caps;
1611 }
1612 if (vs->modifiers_state[0x45] != num) {
1613 vs->modifiers_state[0x45] = num;
1614 }
96f3d174
LL
1615 if (vs->modifiers_state[0x46] != scr) {
1616 vs->modifiers_state[0x46] = scr;
1617 }
ab99e5c1
LL
1618
1619 /* Sending the current led state message to the client */
1483adcf 1620 if (has_changed) {
ab99e5c1
LL
1621 vnc_led_state_change(vs);
1622 }
7ffb82ca
GH
1623}
1624
9ca313aa 1625static void do_key_event(VncState *vs, int down, int keycode, int sym)
24236869 1626{
64f5a135
FB
1627 /* QEMU console switch */
1628 switch(keycode) {
1629 case 0x2a: /* Left Shift */
1630 case 0x36: /* Right Shift */
1631 case 0x1d: /* Left CTRL */
1632 case 0x9d: /* Right CTRL */
1633 case 0x38: /* Left ALT */
1634 case 0xb8: /* Right ALT */
1635 if (down)
1636 vs->modifiers_state[keycode] = 1;
1637 else
1638 vs->modifiers_state[keycode] = 0;
1639 break;
5fafdf24 1640 case 0x02 ... 0x0a: /* '1' to '9' keys */
64f5a135
FB
1641 if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1642 /* Reset the modifiers sent to the current console */
1643 reset_keys(vs);
1644 console_select(keycode - 0x02);
1645 return;
1646 }
1647 break;
28a76be8
AL
1648 case 0x3a: /* CapsLock */
1649 case 0x45: /* NumLock */
7ffb82ca 1650 if (down)
a528b80c
AZ
1651 vs->modifiers_state[keycode] ^= 1;
1652 break;
1653 }
1654
e7b2aacc
LL
1655 /* Turn off the lock state sync logic if the client support the led
1656 state extension.
1657 */
9892088b 1658 if (down && vs->vd->lock_key_sync &&
e7b2aacc 1659 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
3a0558b5 1660 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
a528b80c
AZ
1661 /* If the numlock state needs to change then simulate an additional
1662 keypress before sending this one. This will happen if the user
1663 toggles numlock away from the VNC window.
1664 */
753b4053 1665 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
a528b80c 1666 if (!vs->modifiers_state[0x45]) {
40066175 1667 trace_vnc_key_sync_numlock(true);
a528b80c
AZ
1668 vs->modifiers_state[0x45] = 1;
1669 press_key(vs, 0xff7f);
1670 }
1671 } else {
1672 if (vs->modifiers_state[0x45]) {
40066175 1673 trace_vnc_key_sync_numlock(false);
a528b80c
AZ
1674 vs->modifiers_state[0x45] = 0;
1675 press_key(vs, 0xff7f);
1676 }
1677 }
64f5a135 1678 }
24236869 1679
9892088b 1680 if (down && vs->vd->lock_key_sync &&
e7b2aacc 1681 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
3a0558b5 1682 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
6b132502
GH
1683 /* If the capslock state needs to change then simulate an additional
1684 keypress before sending this one. This will happen if the user
1685 toggles capslock away from the VNC window.
1686 */
1687 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1688 int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
1689 int capslock = !!(vs->modifiers_state[0x3a]);
1690 if (capslock) {
1691 if (uppercase == shift) {
40066175 1692 trace_vnc_key_sync_capslock(false);
6b132502
GH
1693 vs->modifiers_state[0x3a] = 0;
1694 press_key(vs, 0xffe5);
1695 }
1696 } else {
1697 if (uppercase != shift) {
40066175 1698 trace_vnc_key_sync_capslock(true);
6b132502
GH
1699 vs->modifiers_state[0x3a] = 1;
1700 press_key(vs, 0xffe5);
1701 }
1702 }
1703 }
1704
81c0d5a6 1705 if (qemu_console_is_graphic(NULL)) {
8d447d10 1706 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
64f5a135 1707 } else {
e26437c2
GH
1708 bool numlock = vs->modifiers_state[0x45];
1709 bool control = (vs->modifiers_state[0x1d] ||
1710 vs->modifiers_state[0x9d]);
64f5a135
FB
1711 /* QEMU console emulation */
1712 if (down) {
1713 switch (keycode) {
1714 case 0x2a: /* Left Shift */
1715 case 0x36: /* Right Shift */
1716 case 0x1d: /* Left CTRL */
1717 case 0x9d: /* Right CTRL */
1718 case 0x38: /* Left ALT */
1719 case 0xb8: /* Right ALT */
1720 break;
1721 case 0xc8:
1722 kbd_put_keysym(QEMU_KEY_UP);
1723 break;
1724 case 0xd0:
1725 kbd_put_keysym(QEMU_KEY_DOWN);
1726 break;
1727 case 0xcb:
1728 kbd_put_keysym(QEMU_KEY_LEFT);
1729 break;
1730 case 0xcd:
1731 kbd_put_keysym(QEMU_KEY_RIGHT);
1732 break;
1733 case 0xd3:
1734 kbd_put_keysym(QEMU_KEY_DELETE);
1735 break;
1736 case 0xc7:
1737 kbd_put_keysym(QEMU_KEY_HOME);
1738 break;
1739 case 0xcf:
1740 kbd_put_keysym(QEMU_KEY_END);
1741 break;
1742 case 0xc9:
1743 kbd_put_keysym(QEMU_KEY_PAGEUP);
1744 break;
1745 case 0xd1:
1746 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1747 break;
bb0a18e1
GH
1748
1749 case 0x47:
1750 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1751 break;
1752 case 0x48:
1753 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1754 break;
1755 case 0x49:
1756 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1757 break;
1758 case 0x4b:
1759 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1760 break;
1761 case 0x4c:
1762 kbd_put_keysym('5');
1763 break;
1764 case 0x4d:
1765 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1766 break;
1767 case 0x4f:
1768 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1769 break;
1770 case 0x50:
1771 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1772 break;
1773 case 0x51:
1774 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1775 break;
1776 case 0x52:
1777 kbd_put_keysym('0');
1778 break;
1779 case 0x53:
1780 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1781 break;
1782
1783 case 0xb5:
1784 kbd_put_keysym('/');
1785 break;
1786 case 0x37:
1787 kbd_put_keysym('*');
1788 break;
1789 case 0x4a:
1790 kbd_put_keysym('-');
1791 break;
1792 case 0x4e:
1793 kbd_put_keysym('+');
1794 break;
1795 case 0x9c:
1796 kbd_put_keysym('\n');
1797 break;
1798
64f5a135 1799 default:
e26437c2
GH
1800 if (control) {
1801 kbd_put_keysym(sym & 0x1f);
1802 } else {
1803 kbd_put_keysym(sym);
1804 }
64f5a135
FB
1805 break;
1806 }
1807 }
1808 }
24236869
FB
1809}
1810
7bc9318b
GH
1811static void vnc_release_modifiers(VncState *vs)
1812{
1813 static const int keycodes[] = {
1814 /* shift, control, alt keys, both left & right */
1815 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1816 };
1817 int i, keycode;
1818
81c0d5a6 1819 if (!qemu_console_is_graphic(NULL)) {
7bc9318b
GH
1820 return;
1821 }
1822 for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
1823 keycode = keycodes[i];
1824 if (!vs->modifiers_state[keycode]) {
1825 continue;
1826 }
8d447d10 1827 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
7bc9318b
GH
1828 }
1829}
1830
40066175
GH
1831static const char *code2name(int keycode)
1832{
1833 return QKeyCode_lookup[qemu_input_key_number_to_qcode(keycode)];
1834}
1835
bdbd7676
FB
1836static void key_event(VncState *vs, int down, uint32_t sym)
1837{
9ca313aa 1838 int keycode;
4a93fe17 1839 int lsym = sym;
9ca313aa 1840
81c0d5a6 1841 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
4a93fe17
GH
1842 lsym = lsym - 'A' + 'a';
1843 }
9ca313aa 1844
44bb61c8 1845 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
40066175 1846 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
9ca313aa
AL
1847 do_key_event(vs, down, keycode, sym);
1848}
1849
1850static void ext_key_event(VncState *vs, int down,
1851 uint32_t sym, uint16_t keycode)
1852{
1853 /* if the user specifies a keyboard layout, always use it */
40066175 1854 if (keyboard_layout) {
9ca313aa 1855 key_event(vs, down, sym);
40066175
GH
1856 } else {
1857 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
9ca313aa 1858 do_key_event(vs, down, keycode, sym);
40066175 1859 }
bdbd7676
FB
1860}
1861
24236869 1862static void framebuffer_update_request(VncState *vs, int incremental,
28a76be8
AL
1863 int x_position, int y_position,
1864 int w, int h)
24236869 1865{
6ed391bf 1866 int i;
b4c85ddc 1867 const size_t width = surface_width(vs->vd->ds) / VNC_DIRTY_PIXELS_PER_BIT;
d39fa6d8 1868 const size_t height = surface_height(vs->vd->ds);
6ed391bf 1869
d39fa6d8
GH
1870 if (y_position > height) {
1871 y_position = height;
1872 }
1873 if (y_position + h >= height) {
1874 h = height - y_position;
1875 }
cf2d385c 1876
24236869
FB
1877 vs->need_update = 1;
1878 if (!incremental) {
24cf0a6e 1879 vs->force_update = 1;
28a76be8 1880 for (i = 0; i < h; i++) {
6ed391bf
WC
1881 bitmap_set(vs->dirty[y_position + i], 0, width);
1882 bitmap_clear(vs->dirty[y_position + i], width,
a0843a68 1883 VNC_DIRTY_BITS - width);
28a76be8 1884 }
24236869
FB
1885 }
1886}
1887
9ca313aa
AL
1888static void send_ext_key_event_ack(VncState *vs)
1889{
bd023f95 1890 vnc_lock_output(vs);
46a183da 1891 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
9ca313aa
AL
1892 vnc_write_u8(vs, 0);
1893 vnc_write_u16(vs, 1);
d39fa6d8
GH
1894 vnc_framebuffer_update(vs, 0, 0,
1895 surface_width(vs->vd->ds),
1896 surface_height(vs->vd->ds),
29fa4ed9 1897 VNC_ENCODING_EXT_KEY_EVENT);
bd023f95 1898 vnc_unlock_output(vs);
9ca313aa
AL
1899 vnc_flush(vs);
1900}
1901
429a8ed3 1902static void send_ext_audio_ack(VncState *vs)
1903{
bd023f95 1904 vnc_lock_output(vs);
46a183da 1905 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
429a8ed3 1906 vnc_write_u8(vs, 0);
1907 vnc_write_u16(vs, 1);
d39fa6d8
GH
1908 vnc_framebuffer_update(vs, 0, 0,
1909 surface_width(vs->vd->ds),
1910 surface_height(vs->vd->ds),
29fa4ed9 1911 VNC_ENCODING_AUDIO);
bd023f95 1912 vnc_unlock_output(vs);
429a8ed3 1913 vnc_flush(vs);
1914}
1915
24236869
FB
1916static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1917{
1918 int i;
29fa4ed9 1919 unsigned int enc = 0;
24236869 1920
29fa4ed9 1921 vs->features = 0;
a9f20d31 1922 vs->vnc_encoding = 0;
d1af0e05
CC
1923 vs->tight.compression = 9;
1924 vs->tight.quality = -1; /* Lossless by default */
564c337e 1925 vs->absolute = -1;
24236869 1926
8a0f0d0c
CC
1927 /*
1928 * Start from the end because the encodings are sent in order of preference.
e5bed759 1929 * This way the preferred encoding (first encoding defined in the array)
8a0f0d0c
CC
1930 * will be set at the end of the loop.
1931 */
24236869 1932 for (i = n_encodings - 1; i >= 0; i--) {
29fa4ed9
AL
1933 enc = encodings[i];
1934 switch (enc) {
1935 case VNC_ENCODING_RAW:
a9f20d31 1936 vs->vnc_encoding = enc;
29fa4ed9
AL
1937 break;
1938 case VNC_ENCODING_COPYRECT:
753b4053 1939 vs->features |= VNC_FEATURE_COPYRECT_MASK;
29fa4ed9
AL
1940 break;
1941 case VNC_ENCODING_HEXTILE:
1942 vs->features |= VNC_FEATURE_HEXTILE_MASK;
a9f20d31 1943 vs->vnc_encoding = enc;
29fa4ed9 1944 break;
380282b0
CC
1945 case VNC_ENCODING_TIGHT:
1946 vs->features |= VNC_FEATURE_TIGHT_MASK;
1947 vs->vnc_encoding = enc;
1948 break;
fe3e7f2d 1949#ifdef CONFIG_VNC_PNG
efe556ad
CC
1950 case VNC_ENCODING_TIGHT_PNG:
1951 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
1952 vs->vnc_encoding = enc;
1953 break;
fe3e7f2d 1954#endif
059cef40
AL
1955 case VNC_ENCODING_ZLIB:
1956 vs->features |= VNC_FEATURE_ZLIB_MASK;
a9f20d31 1957 vs->vnc_encoding = enc;
059cef40 1958 break;
148954fa
CC
1959 case VNC_ENCODING_ZRLE:
1960 vs->features |= VNC_FEATURE_ZRLE_MASK;
1961 vs->vnc_encoding = enc;
1962 break;
1963 case VNC_ENCODING_ZYWRLE:
1964 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
1965 vs->vnc_encoding = enc;
1966 break;
29fa4ed9
AL
1967 case VNC_ENCODING_DESKTOPRESIZE:
1968 vs->features |= VNC_FEATURE_RESIZE_MASK;
1969 break;
1970 case VNC_ENCODING_POINTER_TYPE_CHANGE:
1971 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
1972 break;
d467b679
GH
1973 case VNC_ENCODING_RICH_CURSOR:
1974 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
1975 break;
29fa4ed9 1976 case VNC_ENCODING_EXT_KEY_EVENT:
9ca313aa
AL
1977 send_ext_key_event_ack(vs);
1978 break;
29fa4ed9 1979 case VNC_ENCODING_AUDIO:
429a8ed3 1980 send_ext_audio_ack(vs);
1981 break;
29fa4ed9
AL
1982 case VNC_ENCODING_WMVi:
1983 vs->features |= VNC_FEATURE_WMVI_MASK;
ca4cca4d 1984 break;
ab99e5c1
LL
1985 case VNC_ENCODING_LED_STATE:
1986 vs->features |= VNC_FEATURE_LED_STATE_MASK;
1987 break;
fb437313 1988 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
d1af0e05 1989 vs->tight.compression = (enc & 0x0F);
fb437313
AL
1990 break;
1991 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
b31f519e
CC
1992 if (vs->vd->lossy) {
1993 vs->tight.quality = (enc & 0x0F);
1994 }
fb437313 1995 break;
29fa4ed9
AL
1996 default:
1997 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
1998 break;
1999 }
24236869 2000 }
6356e472 2001 vnc_desktop_resize(vs);
9e8dd451 2002 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
ab99e5c1 2003 vnc_led_state_change(vs);
24236869
FB
2004}
2005
6cec5487
AL
2006static void set_pixel_conversion(VncState *vs)
2007{
9f64916d
GH
2008 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2009
2010 if (fmt == VNC_SERVER_FB_FORMAT) {
6cec5487 2011 vs->write_pixels = vnc_write_pixels_copy;
70a4568f 2012 vnc_hextile_set_pixel_conversion(vs, 0);
6cec5487
AL
2013 } else {
2014 vs->write_pixels = vnc_write_pixels_generic;
70a4568f 2015 vnc_hextile_set_pixel_conversion(vs, 1);
6cec5487
AL
2016 }
2017}
2018
24236869 2019static void set_pixel_format(VncState *vs,
28a76be8
AL
2020 int bits_per_pixel, int depth,
2021 int big_endian_flag, int true_color_flag,
2022 int red_max, int green_max, int blue_max,
2023 int red_shift, int green_shift, int blue_shift)
24236869 2024{
3512779a 2025 if (!true_color_flag) {
28a76be8 2026 vnc_client_error(vs);
3512779a
FB
2027 return;
2028 }
24236869 2029
9f64916d
GH
2030 vs->client_pf.rmax = red_max;
2031 vs->client_pf.rbits = hweight_long(red_max);
2032 vs->client_pf.rshift = red_shift;
2033 vs->client_pf.rmask = red_max << red_shift;
2034 vs->client_pf.gmax = green_max;
2035 vs->client_pf.gbits = hweight_long(green_max);
2036 vs->client_pf.gshift = green_shift;
2037 vs->client_pf.gmask = green_max << green_shift;
2038 vs->client_pf.bmax = blue_max;
2039 vs->client_pf.bbits = hweight_long(blue_max);
2040 vs->client_pf.bshift = blue_shift;
2041 vs->client_pf.bmask = blue_max << blue_shift;
2042 vs->client_pf.bits_per_pixel = bits_per_pixel;
2043 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2044 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2045 vs->client_be = big_endian_flag;
6cec5487
AL
2046
2047 set_pixel_conversion(vs);
24236869 2048
1dbfa005
GH
2049 graphic_hw_invalidate(NULL);
2050 graphic_hw_update(NULL);
24236869
FB
2051}
2052
ca4cca4d
AL
2053static void pixel_format_message (VncState *vs) {
2054 char pad[3] = { 0, 0, 0 };
2055
9f64916d
GH
2056 vs->client_pf = qemu_default_pixelformat(32);
2057
2058 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2059 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
ca4cca4d 2060
e2542fe2 2061#ifdef HOST_WORDS_BIGENDIAN
ca4cca4d
AL
2062 vnc_write_u8(vs, 1); /* big-endian-flag */
2063#else
2064 vnc_write_u8(vs, 0); /* big-endian-flag */
2065#endif
2066 vnc_write_u8(vs, 1); /* true-color-flag */
9f64916d
GH
2067 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2068 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2069 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2070 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2071 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2072 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2073 vnc_write(vs, pad, 3); /* padding */
70a4568f
CC
2074
2075 vnc_hextile_set_pixel_conversion(vs, 0);
ca4cca4d 2076 vs->write_pixels = vnc_write_pixels_copy;
ca4cca4d
AL
2077}
2078
753b4053 2079static void vnc_colordepth(VncState *vs)
7eac3a87 2080{
753b4053 2081 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
ca4cca4d 2082 /* Sending a WMVi message to notify the client*/
bd023f95 2083 vnc_lock_output(vs);
46a183da 2084 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
ca4cca4d
AL
2085 vnc_write_u8(vs, 0);
2086 vnc_write_u16(vs, 1); /* number of rects */
d39fa6d8
GH
2087 vnc_framebuffer_update(vs, 0, 0,
2088 surface_width(vs->vd->ds),
2089 surface_height(vs->vd->ds),
2090 VNC_ENCODING_WMVi);
ca4cca4d 2091 pixel_format_message(vs);
bd023f95 2092 vnc_unlock_output(vs);
ca4cca4d 2093 vnc_flush(vs);
7eac3a87 2094 } else {
6cec5487 2095 set_pixel_conversion(vs);
7eac3a87
AL
2096 }
2097}
2098
60fe76f3 2099static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
24236869
FB
2100{
2101 int i;
2102 uint16_t limit;
2430ffe4
SS
2103 VncDisplay *vd = vs->vd;
2104
2105 if (data[0] > 3) {
0f7b2864 2106 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2430ffe4 2107 }
24236869
FB
2108
2109 switch (data[0]) {
46a183da 2110 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
28a76be8
AL
2111 if (len == 1)
2112 return 20;
2113
2114 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
2115 read_u8(data, 6), read_u8(data, 7),
2116 read_u16(data, 8), read_u16(data, 10),
2117 read_u16(data, 12), read_u8(data, 14),
2118 read_u8(data, 15), read_u8(data, 16));
2119 break;
46a183da 2120 case VNC_MSG_CLIENT_SET_ENCODINGS:
28a76be8
AL
2121 if (len == 1)
2122 return 4;
24236869 2123
28a76be8 2124 if (len == 4) {
69dd5c9f
AL
2125 limit = read_u16(data, 2);
2126 if (limit > 0)
2127 return 4 + (limit * 4);
2128 } else
2129 limit = read_u16(data, 2);
24236869 2130
28a76be8
AL
2131 for (i = 0; i < limit; i++) {
2132 int32_t val = read_s32(data, 4 + (i * 4));
2133 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2134 }
24236869 2135
28a76be8
AL
2136 set_encodings(vs, (int32_t *)(data + 4), limit);
2137 break;
46a183da 2138 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
28a76be8
AL
2139 if (len == 1)
2140 return 10;
24236869 2141
28a76be8
AL
2142 framebuffer_update_request(vs,
2143 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2144 read_u16(data, 6), read_u16(data, 8));
2145 break;
46a183da 2146 case VNC_MSG_CLIENT_KEY_EVENT:
28a76be8
AL
2147 if (len == 1)
2148 return 8;
24236869 2149
28a76be8
AL
2150 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2151 break;
46a183da 2152 case VNC_MSG_CLIENT_POINTER_EVENT:
28a76be8
AL
2153 if (len == 1)
2154 return 6;
24236869 2155
28a76be8
AL
2156 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2157 break;
46a183da 2158 case VNC_MSG_CLIENT_CUT_TEXT:
28a76be8
AL
2159 if (len == 1)
2160 return 8;
24236869 2161
28a76be8 2162 if (len == 8) {
baa7666c
TS
2163 uint32_t dlen = read_u32(data, 4);
2164 if (dlen > 0)
2165 return 8 + dlen;
2166 }
24236869 2167
28a76be8
AL
2168 client_cut_text(vs, read_u32(data, 4), data + 8);
2169 break;
46a183da 2170 case VNC_MSG_CLIENT_QEMU:
9ca313aa
AL
2171 if (len == 1)
2172 return 2;
2173
2174 switch (read_u8(data, 1)) {
46a183da 2175 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
9ca313aa
AL
2176 if (len == 2)
2177 return 12;
2178
2179 ext_key_event(vs, read_u16(data, 2),
2180 read_u32(data, 4), read_u32(data, 8));
2181 break;
46a183da 2182 case VNC_MSG_CLIENT_QEMU_AUDIO:
429a8ed3 2183 if (len == 2)
2184 return 4;
2185
2186 switch (read_u16 (data, 2)) {
46a183da 2187 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
429a8ed3 2188 audio_add(vs);
2189 break;
46a183da 2190 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
429a8ed3 2191 audio_del(vs);
2192 break;
46a183da 2193 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
429a8ed3 2194 if (len == 4)
2195 return 10;
2196 switch (read_u8(data, 4)) {
2197 case 0: vs->as.fmt = AUD_FMT_U8; break;
2198 case 1: vs->as.fmt = AUD_FMT_S8; break;
2199 case 2: vs->as.fmt = AUD_FMT_U16; break;
2200 case 3: vs->as.fmt = AUD_FMT_S16; break;
2201 case 4: vs->as.fmt = AUD_FMT_U32; break;
2202 case 5: vs->as.fmt = AUD_FMT_S32; break;
2203 default:
2204 printf("Invalid audio format %d\n", read_u8(data, 4));
2205 vnc_client_error(vs);
2206 break;
2207 }
2208 vs->as.nchannels = read_u8(data, 5);
2209 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2210 printf("Invalid audio channel coount %d\n",
2211 read_u8(data, 5));
2212 vnc_client_error(vs);
2213 break;
2214 }
2215 vs->as.freq = read_u32(data, 6);
2216 break;
2217 default:
2218 printf ("Invalid audio message %d\n", read_u8(data, 4));
2219 vnc_client_error(vs);
2220 break;
2221 }
2222 break;
2223
9ca313aa
AL
2224 default:
2225 printf("Msg: %d\n", read_u16(data, 0));
2226 vnc_client_error(vs);
2227 break;
2228 }
2229 break;
24236869 2230 default:
28a76be8
AL
2231 printf("Msg: %d\n", data[0]);
2232 vnc_client_error(vs);
2233 break;
24236869 2234 }
5fafdf24 2235
24236869
FB
2236 vnc_read_when(vs, protocol_client_msg, 1);
2237 return 0;
2238}
2239
60fe76f3 2240static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
24236869 2241{
c35734b2 2242 char buf[1024];
8cf36489 2243 VncShareMode mode;
c35734b2 2244 int size;
24236869 2245
8cf36489
GH
2246 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2247 switch (vs->vd->share_policy) {
2248 case VNC_SHARE_POLICY_IGNORE:
2249 /*
2250 * Ignore the shared flag. Nothing to do here.
2251 *
2252 * Doesn't conform to the rfb spec but is traditional qemu
2253 * behavior, thus left here as option for compatibility
2254 * reasons.
2255 */
2256 break;
2257 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2258 /*
2259 * Policy: Allow clients ask for exclusive access.
2260 *
2261 * Implementation: When a client asks for exclusive access,
2262 * disconnect all others. Shared connects are allowed as long
2263 * as no exclusive connection exists.
2264 *
2265 * This is how the rfb spec suggests to handle the shared flag.
2266 */
2267 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2268 VncState *client;
2269 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2270 if (vs == client) {
2271 continue;
2272 }
2273 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2274 client->share_mode != VNC_SHARE_MODE_SHARED) {
2275 continue;
2276 }
2277 vnc_disconnect_start(client);
2278 }
2279 }
2280 if (mode == VNC_SHARE_MODE_SHARED) {
2281 if (vs->vd->num_exclusive > 0) {
2282 vnc_disconnect_start(vs);
2283 return 0;
2284 }
2285 }
2286 break;
2287 case VNC_SHARE_POLICY_FORCE_SHARED:
2288 /*
2289 * Policy: Shared connects only.
2290 * Implementation: Disallow clients asking for exclusive access.
2291 *
2292 * Useful for shared desktop sessions where you don't want
2293 * someone forgetting to say -shared when running the vnc
2294 * client disconnect everybody else.
2295 */
2296 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2297 vnc_disconnect_start(vs);
2298 return 0;
2299 }
2300 break;
2301 }
2302 vnc_set_share_mode(vs, mode);
2303
d39fa6d8
GH
2304 vs->client_width = surface_width(vs->vd->ds);
2305 vs->client_height = surface_height(vs->vd->ds);
5862d195
GH
2306 vnc_write_u16(vs, vs->client_width);
2307 vnc_write_u16(vs, vs->client_height);
24236869 2308
ca4cca4d 2309 pixel_format_message(vs);
24236869 2310
c35734b2
TS
2311 if (qemu_name)
2312 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2313 else
2314 size = snprintf(buf, sizeof(buf), "QEMU");
2315
2316 vnc_write_u32(vs, size);
2317 vnc_write(vs, buf, size);
24236869
FB
2318 vnc_flush(vs);
2319
4a80dba3 2320 vnc_client_cache_auth(vs);
0d2ed46a 2321 vnc_qmp_event(vs, QEVENT_VNC_INITIALIZED);
4a80dba3 2322
24236869
FB
2323 vnc_read_when(vs, protocol_client_msg, 1);
2324
2325 return 0;
2326}
2327
5fb6c7a8
AL
2328void start_client_init(VncState *vs)
2329{
2330 vnc_read_when(vs, protocol_client_init, 1);
2331}
2332
70848515
TS
2333static void make_challenge(VncState *vs)
2334{
2335 int i;
2336
2337 srand(time(NULL)+getpid()+getpid()*987654+rand());
2338
2339 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
2340 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
2341}
2342
60fe76f3 2343static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
70848515 2344{
60fe76f3 2345 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
70848515 2346 int i, j, pwlen;
60fe76f3 2347 unsigned char key[8];
3c9405a0 2348 time_t now = time(NULL);
70848515 2349
1cd20f8b 2350 if (!vs->vd->password) {
28a76be8 2351 VNC_DEBUG("No password configured on server");
6bffdf0f 2352 goto reject;
70848515 2353 }
3c9405a0
GH
2354 if (vs->vd->expires < now) {
2355 VNC_DEBUG("Password is expired");
2356 goto reject;
2357 }
70848515
TS
2358
2359 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2360
2361 /* Calculate the expected challenge response */
753b4053 2362 pwlen = strlen(vs->vd->password);
70848515 2363 for (i=0; i<sizeof(key); i++)
753b4053 2364 key[i] = i<pwlen ? vs->vd->password[i] : 0;
70848515
TS
2365 deskey(key, EN0);
2366 for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
2367 des(response+j, response+j);
2368
2369 /* Compare expected vs actual challenge response */
2370 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
e5bed759 2371 VNC_DEBUG("Client challenge response did not match\n");
6bffdf0f 2372 goto reject;
70848515 2373 } else {
28a76be8
AL
2374 VNC_DEBUG("Accepting VNC challenge response\n");
2375 vnc_write_u32(vs, 0); /* Accept auth */
2376 vnc_flush(vs);
70848515 2377
5fb6c7a8 2378 start_client_init(vs);
70848515
TS
2379 }
2380 return 0;
6bffdf0f
GH
2381
2382reject:
2383 vnc_write_u32(vs, 1); /* Reject auth */
2384 if (vs->minor >= 8) {
2385 static const char err[] = "Authentication failed";
2386 vnc_write_u32(vs, sizeof(err));
2387 vnc_write(vs, err, sizeof(err));
2388 }
2389 vnc_flush(vs);
2390 vnc_client_error(vs);
2391 return 0;
70848515
TS
2392}
2393
5fb6c7a8 2394void start_auth_vnc(VncState *vs)
70848515
TS
2395{
2396 make_challenge(vs);
2397 /* Send client a 'random' challenge */
2398 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2399 vnc_flush(vs);
2400
2401 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
469b15c6
TS
2402}
2403
2404
60fe76f3 2405static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
70848515
TS
2406{
2407 /* We only advertise 1 auth scheme at a time, so client
2408 * must pick the one we sent. Verify this */
7e7e2ebc 2409 if (data[0] != vs->auth) { /* Reject auth */
1263b7d6 2410 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
70848515
TS
2411 vnc_write_u32(vs, 1);
2412 if (vs->minor >= 8) {
2413 static const char err[] = "Authentication failed";
2414 vnc_write_u32(vs, sizeof(err));
2415 vnc_write(vs, err, sizeof(err));
2416 }
2417 vnc_client_error(vs);
2418 } else { /* Accept requested auth */
2419 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
7e7e2ebc 2420 switch (vs->auth) {
70848515
TS
2421 case VNC_AUTH_NONE:
2422 VNC_DEBUG("Accept auth none\n");
a26c97ad
AZ
2423 if (vs->minor >= 8) {
2424 vnc_write_u32(vs, 0); /* Accept auth completion */
2425 vnc_flush(vs);
2426 }
5fb6c7a8 2427 start_client_init(vs);
70848515
TS
2428 break;
2429
2430 case VNC_AUTH_VNC:
2431 VNC_DEBUG("Start VNC auth\n");
5fb6c7a8
AL
2432 start_auth_vnc(vs);
2433 break;
70848515 2434
eb38c52c 2435#ifdef CONFIG_VNC_TLS
8d5d2d4c 2436 case VNC_AUTH_VENCRYPT:
3a93113a 2437 VNC_DEBUG("Accept VeNCrypt auth\n");
5fb6c7a8
AL
2438 start_auth_vencrypt(vs);
2439 break;
8d5d2d4c
TS
2440#endif /* CONFIG_VNC_TLS */
2441
2f9606b3
AL
2442#ifdef CONFIG_VNC_SASL
2443 case VNC_AUTH_SASL:
2444 VNC_DEBUG("Accept SASL auth\n");
2445 start_auth_sasl(vs);
2446 break;
2447#endif /* CONFIG_VNC_SASL */
2448
70848515 2449 default: /* Should not be possible, but just in case */
7e7e2ebc 2450 VNC_DEBUG("Reject auth %d server code bug\n", vs->auth);
70848515
TS
2451 vnc_write_u8(vs, 1);
2452 if (vs->minor >= 8) {
2453 static const char err[] = "Authentication failed";
2454 vnc_write_u32(vs, sizeof(err));
2455 vnc_write(vs, err, sizeof(err));
2456 }
2457 vnc_client_error(vs);
2458 }
2459 }
2460 return 0;
2461}
2462
60fe76f3 2463static int protocol_version(VncState *vs, uint8_t *version, size_t len)
24236869
FB
2464{
2465 char local[13];
24236869
FB
2466
2467 memcpy(local, version, 12);
2468 local[12] = 0;
2469
70848515 2470 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
28a76be8
AL
2471 VNC_DEBUG("Malformed protocol version %s\n", local);
2472 vnc_client_error(vs);
2473 return 0;
24236869 2474 }
70848515
TS
2475 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2476 if (vs->major != 3 ||
28a76be8
AL
2477 (vs->minor != 3 &&
2478 vs->minor != 4 &&
2479 vs->minor != 5 &&
2480 vs->minor != 7 &&
2481 vs->minor != 8)) {
2482 VNC_DEBUG("Unsupported client version\n");
2483 vnc_write_u32(vs, VNC_AUTH_INVALID);
2484 vnc_flush(vs);
2485 vnc_client_error(vs);
2486 return 0;
70848515 2487 }
b0566f4f 2488 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
70848515
TS
2489 * as equivalent to v3.3 by servers
2490 */
b0566f4f 2491 if (vs->minor == 4 || vs->minor == 5)
28a76be8 2492 vs->minor = 3;
70848515
TS
2493
2494 if (vs->minor == 3) {
7e7e2ebc 2495 if (vs->auth == VNC_AUTH_NONE) {
70848515 2496 VNC_DEBUG("Tell client auth none\n");
7e7e2ebc 2497 vnc_write_u32(vs, vs->auth);
70848515 2498 vnc_flush(vs);
28a76be8 2499 start_client_init(vs);
7e7e2ebc 2500 } else if (vs->auth == VNC_AUTH_VNC) {
70848515 2501 VNC_DEBUG("Tell client VNC auth\n");
7e7e2ebc 2502 vnc_write_u32(vs, vs->auth);
70848515
TS
2503 vnc_flush(vs);
2504 start_auth_vnc(vs);
2505 } else {
7e7e2ebc 2506 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
70848515
TS
2507 vnc_write_u32(vs, VNC_AUTH_INVALID);
2508 vnc_flush(vs);
2509 vnc_client_error(vs);
2510 }
2511 } else {
7e7e2ebc 2512 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
28a76be8 2513 vnc_write_u8(vs, 1); /* num auth */
7e7e2ebc 2514 vnc_write_u8(vs, vs->auth);
28a76be8
AL
2515 vnc_read_when(vs, protocol_client_auth, 1);
2516 vnc_flush(vs);
70848515 2517 }
24236869
FB
2518
2519 return 0;
2520}
2521
999342a0
CC
2522static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2523{
2524 struct VncSurface *vs = &vd->guest;
2525
2526 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2527}
2528
7d964c9d
CC
2529void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2530{
2531 int i, j;
2532
2533 w = (x + w) / VNC_STAT_RECT;
2534 h = (y + h) / VNC_STAT_RECT;
2535 x /= VNC_STAT_RECT;
2536 y /= VNC_STAT_RECT;
2537
207f328a
CC
2538 for (j = y; j <= h; j++) {
2539 for (i = x; i <= w; i++) {
7d964c9d
CC
2540 vs->lossy_rect[j][i] = 1;
2541 }
2542 }
2543}
2544
2545static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2546{
2547 VncState *vs;
2548 int sty = y / VNC_STAT_RECT;
2549 int stx = x / VNC_STAT_RECT;
2550 int has_dirty = 0;
2551
2552 y = y / VNC_STAT_RECT * VNC_STAT_RECT;
2553 x = x / VNC_STAT_RECT * VNC_STAT_RECT;
2554
2555 QTAILQ_FOREACH(vs, &vd->clients, next) {
bc2429b9 2556 int j;
7d964c9d
CC
2557
2558 /* kernel send buffers are full -> refresh later */
2559 if (vs->output.offset) {
2560 continue;
2561 }
2562
2563 if (!vs->lossy_rect[sty][stx]) {
2564 continue;
2565 }
207f328a 2566
7d964c9d
CC
2567 vs->lossy_rect[sty][stx] = 0;
2568 for (j = 0; j < VNC_STAT_RECT; ++j) {
b4c85ddc
PL
2569 bitmap_set(vs->dirty[y + j],
2570 x / VNC_DIRTY_PIXELS_PER_BIT,
2571 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
7d964c9d
CC
2572 }
2573 has_dirty++;
2574 }
207f328a 2575
7d964c9d
CC
2576 return has_dirty;
2577}
2578
2579static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
999342a0 2580{
9f64916d
GH
2581 int width = pixman_image_get_width(vd->guest.fb);
2582 int height = pixman_image_get_height(vd->guest.fb);
999342a0
CC
2583 int x, y;
2584 struct timeval res;
7d964c9d 2585 int has_dirty = 0;
999342a0 2586
9f64916d
GH
2587 for (y = 0; y < height; y += VNC_STAT_RECT) {
2588 for (x = 0; x < width; x += VNC_STAT_RECT) {
999342a0
CC
2589 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2590
2591 rect->updated = false;
2592 }
2593 }
2594
ad620c29 2595 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
999342a0
CC
2596
2597 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
7d964c9d 2598 return has_dirty;
999342a0
CC
2599 }
2600 vd->guest.last_freq_check = *tv;
2601
9f64916d
GH
2602 for (y = 0; y < height; y += VNC_STAT_RECT) {
2603 for (x = 0; x < width; x += VNC_STAT_RECT) {
999342a0
CC
2604 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2605 int count = ARRAY_SIZE(rect->times);
2606 struct timeval min, max;
2607
2608 if (!timerisset(&rect->times[count - 1])) {
2609 continue ;
2610 }
2611
2612 max = rect->times[(rect->idx + count - 1) % count];
ad620c29 2613 qemu_timersub(tv, &max, &res);
999342a0
CC
2614
2615 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2616 rect->freq = 0;
7d964c9d 2617 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
999342a0
CC
2618 memset(rect->times, 0, sizeof (rect->times));
2619 continue ;
2620 }
2621
2622 min = rect->times[rect->idx];
2623 max = rect->times[(rect->idx + count - 1) % count];
ad620c29 2624 qemu_timersub(&max, &min, &res);
999342a0
CC
2625
2626 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2627 rect->freq /= count;
2628 rect->freq = 1. / rect->freq;
2629 }
2630 }
7d964c9d 2631 return has_dirty;
999342a0
CC
2632}
2633
2634double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2635{
2636 int i, j;
2637 double total = 0;
2638 int num = 0;
2639
2640 x = (x / VNC_STAT_RECT) * VNC_STAT_RECT;
2641 y = (y / VNC_STAT_RECT) * VNC_STAT_RECT;
2642
2643 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2644 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2645 total += vnc_stat_rect(vs->vd, i, j)->freq;
2646 num++;
2647 }
2648 }
2649
2650 if (num) {
2651 return total / num;
2652 } else {
2653 return 0;
2654 }
2655}
2656
2657static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2658{
2659 VncRectStat *rect;
2660
2661 rect = vnc_stat_rect(vd, x, y);
2662 if (rect->updated) {
2663 return ;
2664 }
2665 rect->times[rect->idx] = *tv;
2666 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
2667 rect->updated = true;
2668}
2669
1fc62412
SS
2670static int vnc_refresh_server_surface(VncDisplay *vd)
2671{
9f64916d
GH
2672 int width = pixman_image_get_width(vd->guest.fb);
2673 int height = pixman_image_get_height(vd->guest.fb);
1fc62412 2674 int y;
12b316d4
PL
2675 uint8_t *guest_row0 = NULL, *server_row0;
2676 int guest_stride = 0, server_stride;
1fc62412 2677 int cmp_bytes;
41b4bef6 2678 VncState *vs;
1fc62412 2679 int has_dirty = 0;
9f64916d 2680 pixman_image_t *tmpbuf = NULL;
1fc62412 2681
80e0c8c3 2682 struct timeval tv = { 0, 0 };
999342a0 2683
80e0c8c3
CC
2684 if (!vd->non_adaptive) {
2685 gettimeofday(&tv, NULL);
2686 has_dirty = vnc_update_stats(vd, &tv);
2687 }
999342a0 2688
1fc62412
SS
2689 /*
2690 * Walk through the guest dirty map.
2691 * Check and copy modified bits from guest to server surface.
2692 * Update server dirty map.
2693 */
6cd859aa 2694 cmp_bytes = VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES;
9f64916d
GH
2695 if (cmp_bytes > vnc_server_fb_stride(vd)) {
2696 cmp_bytes = vnc_server_fb_stride(vd);
2697 }
2698 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2699 int width = pixman_image_get_width(vd->server);
2700 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
12b316d4
PL
2701 } else {
2702 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
2703 guest_stride = pixman_image_get_stride(vd->guest.fb);
2704 }
2705 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
2706 server_stride = pixman_image_get_stride(vd->server);
2707
2708 y = 0;
2709 for (;;) {
2710 int x;
2711 uint8_t *guest_ptr, *server_ptr;
2712 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
2713 height * VNC_DIRTY_BPL(&vd->guest),
2714 y * VNC_DIRTY_BPL(&vd->guest));
2715 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
2716 /* no more dirty bits */
2717 break;
2718 }
2719 y = offset / VNC_DIRTY_BPL(&vd->guest);
2720 x = offset % VNC_DIRTY_BPL(&vd->guest);
1fc62412 2721
12b316d4
PL
2722 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
2723
2724 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2725 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
2726 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
2727 } else {
2728 guest_ptr = guest_row0 + y * guest_stride;
2729 }
2730 guest_ptr += x * cmp_bytes;
2731
2732 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
2733 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
2734 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
2735 continue;
2736 }
2737 if (memcmp(server_ptr, guest_ptr, cmp_bytes) == 0) {
2738 continue;
2739 }
2740 memcpy(server_ptr, guest_ptr, cmp_bytes);
2741 if (!vd->non_adaptive) {
2742 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
2743 y, &tv);
1fc62412 2744 }
12b316d4
PL
2745 QTAILQ_FOREACH(vs, &vd->clients, next) {
2746 set_bit(x, vs->dirty[y]);
2747 }
2748 has_dirty++;
1fc62412 2749 }
12b316d4
PL
2750
2751 y++;
1fc62412 2752 }
9f64916d 2753 qemu_pixman_image_unref(tmpbuf);
1fc62412
SS
2754 return has_dirty;
2755}
2756
0f7b2864 2757static void vnc_refresh(DisplayChangeListener *dcl)
703bc68f 2758{
0f7b2864 2759 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
41b4bef6
AS
2760 VncState *vs, *vn;
2761 int has_dirty, rects = 0;
703bc68f 2762
1dbfa005 2763 graphic_hw_update(NULL);
703bc68f 2764
bd023f95 2765 if (vnc_trylock_display(vd)) {
0f7b2864 2766 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
bd023f95
CC
2767 return;
2768 }
2769
1fc62412 2770 has_dirty = vnc_refresh_server_surface(vd);
bd023f95 2771 vnc_unlock_display(vd);
1fc62412 2772
41b4bef6 2773 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
38ee14f4 2774 rects += vnc_update_client(vs, has_dirty, false);
6185c578 2775 /* vs might be free()ed here */
703bc68f 2776 }
bd023f95 2777
0f7b2864
GH
2778 if (QTAILQ_EMPTY(&vd->clients)) {
2779 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
83755c17 2780 return;
0f7b2864 2781 }
703bc68f 2782
2430ffe4 2783 if (has_dirty && rects) {
0f7b2864
GH
2784 vd->dcl.update_interval /= 2;
2785 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
2786 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
2787 }
2430ffe4 2788 } else {
0f7b2864
GH
2789 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
2790 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
2791 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
2792 }
703bc68f
SS
2793 }
2794}
2795
2c8cf549
MT
2796static void vnc_connect(VncDisplay *vd, int csock,
2797 bool skipauth, bool websocket)
3aa3eea3 2798{
7267c094 2799 VncState *vs = g_malloc0(sizeof(VncState));
7d964c9d
CC
2800 int i;
2801
753b4053 2802 vs->csock = csock;
7e7e2ebc
DB
2803
2804 if (skipauth) {
2805 vs->auth = VNC_AUTH_NONE;
2806#ifdef CONFIG_VNC_TLS
2807 vs->subauth = VNC_AUTH_INVALID;
2808#endif
2809 } else {
2810 vs->auth = vd->auth;
2811#ifdef CONFIG_VNC_TLS
2812 vs->subauth = vd->subauth;
2813#endif
2814 }
2815
7267c094 2816 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
7d964c9d 2817 for (i = 0; i < VNC_STAT_ROWS; ++i) {
7267c094 2818 vs->lossy_rect[i] = g_malloc0(VNC_STAT_COLS * sizeof (uint8_t));
7d964c9d 2819 }
753b4053
AL
2820
2821 VNC_DEBUG("New client on socket %d\n", csock);
0f7b2864 2822 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
f9e8cacc 2823 qemu_set_nonblock(vs->csock);
7536ee4b
TH
2824#ifdef CONFIG_VNC_WS
2825 if (websocket) {
2826 vs->websocket = 1;
0057a0d5
TH
2827#ifdef CONFIG_VNC_TLS
2828 if (vd->tls.x509cert) {
2829 qemu_set_fd_handler2(vs->csock, NULL, vncws_tls_handshake_peek,
2830 NULL, vs);
2831 } else
2832#endif /* CONFIG_VNC_TLS */
2833 {
2834 qemu_set_fd_handler2(vs->csock, NULL, vncws_handshake_read,
2835 NULL, vs);
2836 }
7536ee4b
TH
2837 } else
2838#endif /* CONFIG_VNC_WS */
2839 {
2840 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
2841 }
753b4053 2842
4a80dba3 2843 vnc_client_cache_addr(vs);
586153d9 2844 vnc_qmp_event(vs, QEVENT_VNC_CONNECTED);
8cf36489 2845 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
4a80dba3 2846
753b4053 2847 vs->vd = vd;
7536ee4b
TH
2848
2849#ifdef CONFIG_VNC_WS
2850 if (!vs->websocket)
2851#endif
2852 {
2853 vnc_init_state(vs);
2854 }
2855}
2856
2857void vnc_init_state(VncState *vs)
2858{
6fd8e79a 2859 vs->initialized = true;
7536ee4b
TH
2860 VncDisplay *vd = vs->vd;
2861
753b4053
AL
2862 vs->last_x = -1;
2863 vs->last_y = -1;
2864
2865 vs->as.freq = 44100;
2866 vs->as.nchannels = 2;
2867 vs->as.fmt = AUD_FMT_S16;
2868 vs->as.endianness = 0;
2869
bd023f95 2870 qemu_mutex_init(&vs->output_mutex);
175b2a6e 2871 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
bd023f95 2872
41b4bef6 2873 QTAILQ_INSERT_HEAD(&vd->clients, vs, next);
1fc62412 2874
1dbfa005 2875 graphic_hw_update(NULL);
1fc62412 2876
3aa3eea3
AZ
2877 vnc_write(vs, "RFB 003.008\n", 12);
2878 vnc_flush(vs);
2879 vnc_read_when(vs, protocol_version, 12);
53762ddb 2880 reset_keys(vs);
3a0558b5
GH
2881 if (vs->vd->lock_key_sync)
2882 vs->led = qemu_add_led_event_handler(kbd_leds, vs);
753b4053 2883
37c34d9d
AL
2884 vs->mouse_mode_notifier.notify = check_pointer_type_change;
2885 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
2886
198a0039 2887 /* vs might be free()ed here */
3aa3eea3
AZ
2888}
2889
7536ee4b 2890static void vnc_listen_read(void *opaque, bool websocket)
24236869 2891{
753b4053 2892 VncDisplay *vs = opaque;
24236869
FB
2893 struct sockaddr_in addr;
2894 socklen_t addrlen = sizeof(addr);
7536ee4b 2895 int csock;
24236869 2896
9f60ad50 2897 /* Catch-up */
1dbfa005 2898 graphic_hw_update(NULL);
7536ee4b
TH
2899#ifdef CONFIG_VNC_WS
2900 if (websocket) {
2901 csock = qemu_accept(vs->lwebsock, (struct sockaddr *)&addr, &addrlen);
2902 } else
2903#endif /* CONFIG_VNC_WS */
2904 {
2905 csock = qemu_accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
2906 }
9f60ad50 2907
753b4053 2908 if (csock != -1) {
2c8cf549 2909 vnc_connect(vs, csock, false, websocket);
24236869
FB
2910 }
2911}
2912
7536ee4b
TH
2913static void vnc_listen_regular_read(void *opaque)
2914{
2c8cf549 2915 vnc_listen_read(opaque, false);
7536ee4b
TH
2916}
2917
2918#ifdef CONFIG_VNC_WS
2919static void vnc_listen_websocket_read(void *opaque)
2920{
2c8cf549 2921 vnc_listen_read(opaque, true);
7536ee4b
TH
2922}
2923#endif /* CONFIG_VNC_WS */
2924
7c20b4a3
GH
2925static const DisplayChangeListenerOps dcl_ops = {
2926 .dpy_name = "vnc",
0f7b2864 2927 .dpy_refresh = vnc_refresh,
7c20b4a3
GH
2928 .dpy_gfx_copy = vnc_dpy_copy,
2929 .dpy_gfx_update = vnc_dpy_update,
c12aeb86 2930 .dpy_gfx_switch = vnc_dpy_switch,
7c20b4a3
GH
2931 .dpy_mouse_set = vnc_mouse_set,
2932 .dpy_cursor_define = vnc_dpy_cursor_define,
2933};
2934
71cab5ca 2935void vnc_display_init(DisplayState *ds)
24236869 2936{
7267c094 2937 VncDisplay *vs = g_malloc0(sizeof(*vs));
24236869 2938
753b4053 2939 vnc_display = vs;
24236869
FB
2940
2941 vs->lsock = -1;
7536ee4b
TH
2942#ifdef CONFIG_VNC_WS
2943 vs->lwebsock = -1;
2944#endif
24236869 2945
41b4bef6 2946 QTAILQ_INIT(&vs->clients);
3c9405a0 2947 vs->expires = TIME_MAX;
24236869 2948
40066175
GH
2949 if (keyboard_layout) {
2950 trace_vnc_key_map_init(keyboard_layout);
0483755a 2951 vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
40066175 2952 } else {
0483755a 2953 vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
40066175 2954 }
24236869 2955
24236869 2956 if (!vs->kbd_layout)
28a76be8 2957 exit(1);
24236869 2958
bd023f95
CC
2959 qemu_mutex_init(&vs->mutex);
2960 vnc_start_worker_thread();
bd023f95 2961
21ef45d7 2962 vs->dcl.ops = &dcl_ops;
5209089f 2963 register_displaychangelistener(&vs->dcl);
71cab5ca
TS
2964}
2965
6f43024c 2966
71a8cdec 2967static void vnc_display_close(DisplayState *ds)
71cab5ca 2968{
21ef45d7 2969 VncDisplay *vs = vnc_display;
71cab5ca 2970
452b4d88
AL
2971 if (!vs)
2972 return;
71cab5ca 2973 if (vs->display) {
7267c094 2974 g_free(vs->display);
28a76be8 2975 vs->display = NULL;
71cab5ca
TS
2976 }
2977 if (vs->lsock != -1) {
28a76be8
AL
2978 qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
2979 close(vs->lsock);
2980 vs->lsock = -1;
71cab5ca 2981 }
7536ee4b
TH
2982#ifdef CONFIG_VNC_WS
2983 g_free(vs->ws_display);
2984 vs->ws_display = NULL;
2985 if (vs->lwebsock != -1) {
2986 qemu_set_fd_handler2(vs->lwebsock, NULL, NULL, NULL, NULL);
2987 close(vs->lwebsock);
2988 vs->lwebsock = -1;
2989 }
2990#endif /* CONFIG_VNC_WS */
70848515 2991 vs->auth = VNC_AUTH_INVALID;
eb38c52c 2992#ifdef CONFIG_VNC_TLS
8d5d2d4c 2993 vs->subauth = VNC_AUTH_INVALID;
5fb6c7a8 2994 vs->tls.x509verify = 0;
8d5d2d4c 2995#endif
70848515
TS
2996}
2997
2998int vnc_display_password(DisplayState *ds, const char *password)
2999{
21ef45d7 3000 VncDisplay *vs = vnc_display;
70848515 3001
7ef92331 3002 if (!vs) {
a6aa9d3e 3003 return -EINVAL;
7ef92331 3004 }
cf864569
GH
3005 if (vs->auth == VNC_AUTH_NONE) {
3006 error_printf_unless_qmp("If you want use passwords please enable "
3007 "password auth using '-vnc ${dpy},password'.");
3008 return -EINVAL;
1cd20f8b
AL
3009 }
3010
70848515 3011 if (vs->password) {
7267c094 3012 g_free(vs->password);
28a76be8 3013 vs->password = NULL;
70848515 3014 }
cf864569
GH
3015 if (password) {
3016 vs->password = g_strdup(password);
7dfbfc79 3017 }
a6aa9d3e
LC
3018
3019 return 0;
71cab5ca
TS
3020}
3021
3c9405a0
GH
3022int vnc_display_pw_expire(DisplayState *ds, time_t expires)
3023{
21ef45d7 3024 VncDisplay *vs = vnc_display;
3c9405a0 3025
1643f2b2
GH
3026 if (!vs) {
3027 return -EINVAL;
3028 }
3029
3c9405a0
GH
3030 vs->expires = expires;
3031 return 0;
3032}
3033
f92f8afe
AL
3034char *vnc_display_local_addr(DisplayState *ds)
3035{
21ef45d7 3036 VncDisplay *vs = vnc_display;
f92f8afe
AL
3037
3038 return vnc_socket_local_addr("%s:%s", vs->lsock);
3039}
3040
2d55f0e8 3041void vnc_display_open(DisplayState *ds, const char *display, Error **errp)
71cab5ca 3042{
21ef45d7 3043 VncDisplay *vs = vnc_display;
70848515
TS
3044 const char *options;
3045 int password = 0;
3aa3eea3 3046 int reverse = 0;
eb38c52c 3047#ifdef CONFIG_VNC_TLS
3a702699 3048 int tls = 0, x509 = 0;
8d5d2d4c 3049#endif
2f9606b3
AL
3050#ifdef CONFIG_VNC_SASL
3051 int sasl = 0;
3052 int saslErr;
3053#endif
2ded6ad7 3054#if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
76655d6d 3055 int acl = 0;
2ded6ad7 3056#endif
3a0558b5 3057 int lock_key_sync = 1;
71cab5ca 3058
2d55f0e8
PB
3059 if (!vnc_display) {
3060 error_setg(errp, "VNC display not active");
3061 return;
3062 }
71cab5ca 3063 vnc_display_close(ds);
70848515 3064 if (strcmp(display, "none") == 0)
2d55f0e8 3065 return;
24236869 3066
1ce52c78 3067 vs->display = g_strdup(display);
8cf36489 3068 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
70848515
TS
3069
3070 options = display;
3071 while ((options = strchr(options, ','))) {
28a76be8
AL
3072 options++;
3073 if (strncmp(options, "password", 8) == 0) {
0f66998f 3074 if (fips_get_state()) {
2d55f0e8
PB
3075 error_setg(errp,
3076 "VNC password auth disabled due to FIPS mode, "
3077 "consider using the VeNCrypt or SASL authentication "
3078 "methods as an alternative");
1ce52c78 3079 goto fail;
0f66998f 3080 }
28a76be8
AL
3081 password = 1; /* Require password auth */
3082 } else if (strncmp(options, "reverse", 7) == 0) {
3083 reverse = 1;
cee8e6ad 3084 } else if (strncmp(options, "no-lock-key-sync", 16) == 0) {
3a0558b5 3085 lock_key_sync = 0;
2f9606b3 3086#ifdef CONFIG_VNC_SASL
28a76be8
AL
3087 } else if (strncmp(options, "sasl", 4) == 0) {
3088 sasl = 1; /* Require SASL auth */
2f9606b3 3089#endif
7536ee4b
TH
3090#ifdef CONFIG_VNC_WS
3091 } else if (strncmp(options, "websocket", 9) == 0) {
3092 char *start, *end;
3093 vs->websocket = 1;
3094
3095 /* Check for 'websocket=<port>' */
3096 start = strchr(options, '=');
3097 end = strchr(options, ',');
3098 if (start && (!end || (start < end))) {
3099 int len = end ? end-(start+1) : strlen(start+1);
3100 if (len < 6) {
3101 /* extract the host specification from display */
3102 char *host = NULL, *port = NULL, *host_end = NULL;
3103 port = g_strndup(start + 1, len);
3104
3105 /* ipv6 hosts have colons */
3106 end = strchr(display, ',');
3107 host_end = g_strrstr_len(display, end - display, ":");
3108
3109 if (host_end) {
3110 host = g_strndup(display, host_end - display + 1);
3111 } else {
3112 host = g_strndup(":", 1);
3113 }
3114 vs->ws_display = g_strconcat(host, port, NULL);
3115 g_free(host);
3116 g_free(port);
3117 }
3118 }
3119#endif /* CONFIG_VNC_WS */
eb38c52c 3120#ifdef CONFIG_VNC_TLS
28a76be8
AL
3121 } else if (strncmp(options, "tls", 3) == 0) {
3122 tls = 1; /* Require TLS */
3123 } else if (strncmp(options, "x509", 4) == 0) {
3124 char *start, *end;
3125 x509 = 1; /* Require x509 certificates */
3126 if (strncmp(options, "x509verify", 10) == 0)
3127 vs->tls.x509verify = 1; /* ...and verify client certs */
3128
3129 /* Now check for 'x509=/some/path' postfix
3130 * and use that to setup x509 certificate/key paths */
3131 start = strchr(options, '=');
3132 end = strchr(options, ',');
3133 if (start && (!end || (start < end))) {
3134 int len = end ? end-(start+1) : strlen(start+1);
7267c094 3135 char *path = g_strndup(start + 1, len);
28a76be8
AL
3136
3137 VNC_DEBUG("Trying certificate path '%s'\n", path);
3138 if (vnc_tls_set_x509_creds_dir(vs, path) < 0) {
2d55f0e8 3139 error_setg(errp, "Failed to find x509 certificates/keys in %s", path);
7267c094 3140 g_free(path);
1ce52c78 3141 goto fail;
28a76be8 3142 }
7267c094 3143 g_free(path);
28a76be8 3144 } else {
2d55f0e8 3145 error_setg(errp, "No certificate path provided");
1ce52c78 3146 goto fail;
28a76be8 3147 }
8d5d2d4c 3148#endif
2ded6ad7 3149#if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
28a76be8
AL
3150 } else if (strncmp(options, "acl", 3) == 0) {
3151 acl = 1;
2ded6ad7 3152#endif
6f9c78c1 3153 } else if (strncmp(options, "lossy", 5) == 0) {
e22492d3 3154#ifdef CONFIG_VNC_JPEG
6f9c78c1 3155 vs->lossy = true;
e22492d3 3156#endif
7eff5742 3157 } else if (strncmp(options, "non-adaptive", 12) == 0) {
80e0c8c3 3158 vs->non_adaptive = true;
8cf36489
GH
3159 } else if (strncmp(options, "share=", 6) == 0) {
3160 if (strncmp(options+6, "ignore", 6) == 0) {
3161 vs->share_policy = VNC_SHARE_POLICY_IGNORE;
3162 } else if (strncmp(options+6, "allow-exclusive", 15) == 0) {
3163 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3164 } else if (strncmp(options+6, "force-shared", 12) == 0) {
3165 vs->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
3166 } else {
2d55f0e8 3167 error_setg(errp, "unknown vnc share= option");
1ce52c78 3168 goto fail;
8cf36489 3169 }
28a76be8 3170 }
70848515
TS
3171 }
3172
e22492d3
PL
3173 /* adaptive updates are only used with tight encoding and
3174 * if lossy updates are enabled so we can disable all the
3175 * calculations otherwise */
3176 if (!vs->lossy) {
3177 vs->non_adaptive = true;
3178 }
3179
76655d6d
AL
3180#ifdef CONFIG_VNC_TLS
3181 if (acl && x509 && vs->tls.x509verify) {
28a76be8
AL
3182 if (!(vs->tls.acl = qemu_acl_init("vnc.x509dname"))) {
3183 fprintf(stderr, "Failed to create x509 dname ACL\n");
3184 exit(1);
3185 }
76655d6d
AL
3186 }
3187#endif
3188#ifdef CONFIG_VNC_SASL
3189 if (acl && sasl) {
28a76be8
AL
3190 if (!(vs->sasl.acl = qemu_acl_init("vnc.username"))) {
3191 fprintf(stderr, "Failed to create username ACL\n");
3192 exit(1);
3193 }
76655d6d
AL
3194 }
3195#endif
3196
2f9606b3
AL
3197 /*
3198 * Combinations we support here:
3199 *
3200 * - no-auth (clear text, no auth)
3201 * - password (clear text, weak auth)
3202 * - sasl (encrypt, good auth *IF* using Kerberos via GSSAPI)
3203 * - tls (encrypt, weak anonymous creds, no auth)
3204 * - tls + password (encrypt, weak anonymous creds, weak auth)
3205 * - tls + sasl (encrypt, weak anonymous creds, good auth)
3206 * - tls + x509 (encrypt, good x509 creds, no auth)
3207 * - tls + x509 + password (encrypt, good x509 creds, weak auth)
3208 * - tls + x509 + sasl (encrypt, good x509 creds, good auth)
3209 *
3210 * NB1. TLS is a stackable auth scheme.
3211 * NB2. the x509 schemes have option to validate a client cert dname
3212 */
70848515 3213 if (password) {
eb38c52c 3214#ifdef CONFIG_VNC_TLS
28a76be8
AL
3215 if (tls) {
3216 vs->auth = VNC_AUTH_VENCRYPT;
3217 if (x509) {
3218 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3219 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
3220 } else {
3221 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3222 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3223 }
3224 } else {
2f9606b3 3225#endif /* CONFIG_VNC_TLS */
28a76be8
AL
3226 VNC_DEBUG("Initializing VNC server with password auth\n");
3227 vs->auth = VNC_AUTH_VNC;
eb38c52c 3228#ifdef CONFIG_VNC_TLS
28a76be8
AL
3229 vs->subauth = VNC_AUTH_INVALID;
3230 }
2f9606b3
AL
3231#endif /* CONFIG_VNC_TLS */
3232#ifdef CONFIG_VNC_SASL
3233 } else if (sasl) {
3234#ifdef CONFIG_VNC_TLS
3235 if (tls) {
3236 vs->auth = VNC_AUTH_VENCRYPT;
3237 if (x509) {
28a76be8 3238 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
2f9606b3
AL
3239 vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;
3240 } else {
28a76be8 3241 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
2f9606b3
AL
3242 vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3243 }
3244 } else {
3245#endif /* CONFIG_VNC_TLS */
28a76be8 3246 VNC_DEBUG("Initializing VNC server with SASL auth\n");
2f9606b3
AL
3247 vs->auth = VNC_AUTH_SASL;
3248#ifdef CONFIG_VNC_TLS
3249 vs->subauth = VNC_AUTH_INVALID;
3250 }
3251#endif /* CONFIG_VNC_TLS */
3252#endif /* CONFIG_VNC_SASL */
70848515 3253 } else {
eb38c52c 3254#ifdef CONFIG_VNC_TLS
28a76be8
AL
3255 if (tls) {
3256 vs->auth = VNC_AUTH_VENCRYPT;
3257 if (x509) {
3258 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3259 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
3260 } else {
3261 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3262 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3263 }
3264 } else {
8d5d2d4c 3265#endif
28a76be8
AL
3266 VNC_DEBUG("Initializing VNC server with no auth\n");
3267 vs->auth = VNC_AUTH_NONE;
eb38c52c 3268#ifdef CONFIG_VNC_TLS
28a76be8
AL
3269 vs->subauth = VNC_AUTH_INVALID;
3270 }
8d5d2d4c 3271#endif
70848515 3272 }
24236869 3273
2f9606b3
AL
3274#ifdef CONFIG_VNC_SASL
3275 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
2d55f0e8
PB
3276 error_setg(errp, "Failed to initialize SASL auth: %s",
3277 sasl_errstring(saslErr, NULL, NULL));
1ce52c78 3278 goto fail;
2f9606b3
AL
3279 }
3280#endif
3a0558b5 3281 vs->lock_key_sync = lock_key_sync;
2f9606b3 3282
3aa3eea3 3283 if (reverse) {
9712ecaf 3284 /* connect to viewer */
007fcd3e
PB
3285 int csock;
3286 vs->lsock = -1;
7536ee4b
TH
3287#ifdef CONFIG_VNC_WS
3288 vs->lwebsock = -1;
3289#endif
007fcd3e 3290 if (strncmp(display, "unix:", 5) == 0) {
2d55f0e8 3291 csock = unix_connect(display+5, errp);
3aa3eea3 3292 } else {
2d55f0e8 3293 csock = inet_connect(display, errp);
3aa3eea3 3294 }
007fcd3e
PB
3295 if (csock < 0) {
3296 goto fail;
3297 }
2c8cf549 3298 vnc_connect(vs, csock, false, false);
9712ecaf
AL
3299 } else {
3300 /* listen for connects */
3301 char *dpy;
7267c094 3302 dpy = g_malloc(256);
9712ecaf 3303 if (strncmp(display, "unix:", 5) == 0) {
bc575e95 3304 pstrcpy(dpy, 256, "unix:");
2d55f0e8 3305 vs->lsock = unix_listen(display+5, dpy+5, 256-5, errp);
9712ecaf 3306 } else {
029409e5 3307 vs->lsock = inet_listen(display, dpy, 256,
2d55f0e8 3308 SOCK_STREAM, 5900, errp);
7536ee4b
TH
3309 if (vs->lsock < 0) {
3310 g_free(dpy);
3311 goto fail;
3312 }
3313#ifdef CONFIG_VNC_WS
3314 if (vs->websocket) {
3315 if (vs->ws_display) {
3316 vs->lwebsock = inet_listen(vs->ws_display, NULL, 256,
3317 SOCK_STREAM, 0, errp);
3318 } else {
3319 vs->lwebsock = inet_listen(vs->display, NULL, 256,
3320 SOCK_STREAM, 5700, errp);
3321 }
3322
3323 if (vs->lwebsock < 0) {
3324 if (vs->lsock) {
3325 close(vs->lsock);
3326 vs->lsock = -1;
3327 }
3328 g_free(dpy);
3329 goto fail;
3330 }
3331 }
3332#endif /* CONFIG_VNC_WS */
9712ecaf 3333 }
1ce52c78
PB
3334 g_free(vs->display);
3335 vs->display = dpy;
7536ee4b
TH
3336 qemu_set_fd_handler2(vs->lsock, NULL,
3337 vnc_listen_regular_read, NULL, vs);
3338#ifdef CONFIG_VNC_WS
3339 if (vs->websocket) {
3340 qemu_set_fd_handler2(vs->lwebsock, NULL,
3341 vnc_listen_websocket_read, NULL, vs);
3342 }
3343#endif /* CONFIG_VNC_WS */
24236869 3344 }
2d55f0e8 3345 return;
1ce52c78
PB
3346
3347fail:
3348 g_free(vs->display);
3349 vs->display = NULL;
7536ee4b
TH
3350#ifdef CONFIG_VNC_WS
3351 g_free(vs->ws_display);
3352 vs->ws_display = NULL;
3353#endif /* CONFIG_VNC_WS */
24236869 3354}
13661089 3355
2c8cf549 3356void vnc_display_add_client(DisplayState *ds, int csock, bool skipauth)
13661089 3357{
21ef45d7 3358 VncDisplay *vs = vnc_display;
13661089 3359
2c8cf549 3360 vnc_connect(vs, csock, skipauth, false);
13661089 3361}
This page took 1.418814 seconds and 4 git commands to generate.