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