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