2 * QEMU VNC display driver
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
6 * Copyright (C) 2009 Red Hat, Inc
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:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
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
31 #include "sysemu/sysemu.h"
32 #include "qemu/error-report.h"
33 #include "qemu/sockets.h"
34 #include "qemu/timer.h"
36 #include "qemu/config-file.h"
37 #include "qapi/qmp/qerror.h"
38 #include "qapi/qmp/types.h"
39 #include "qmp-commands.h"
40 #include "qemu/osdep.h"
42 #include "qapi-event.h"
43 #include "crypto/hash.h"
44 #include "crypto/tlscredsanon.h"
45 #include "crypto/tlscredsx509.h"
46 #include "qom/object_interfaces.h"
48 #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
49 #define VNC_REFRESH_INTERVAL_INC 50
50 #define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
51 static const struct timeval VNC_REFRESH_STATS
= { 0, 500000 };
52 static const struct timeval VNC_REFRESH_LOSSY
= { 2, 0 };
54 #include "vnc_keysym.h"
55 #include "crypto/cipher.h"
57 static QTAILQ_HEAD(, VncDisplay
) vnc_displays
=
58 QTAILQ_HEAD_INITIALIZER(vnc_displays
);
60 static int vnc_cursor_define(VncState
*vs
);
61 static void vnc_release_modifiers(VncState
*vs
);
63 static void vnc_set_share_mode(VncState
*vs
, VncShareMode mode
)
66 static const char *mn
[] = {
68 [VNC_SHARE_MODE_CONNECTING
] = "connecting",
69 [VNC_SHARE_MODE_SHARED
] = "shared",
70 [VNC_SHARE_MODE_EXCLUSIVE
] = "exclusive",
71 [VNC_SHARE_MODE_DISCONNECTED
] = "disconnected",
73 fprintf(stderr
, "%s/%d: %s -> %s\n", __func__
,
74 vs
->csock
, mn
[vs
->share_mode
], mn
[mode
]);
77 switch (vs
->share_mode
) {
78 case VNC_SHARE_MODE_CONNECTING
:
79 vs
->vd
->num_connecting
--;
81 case VNC_SHARE_MODE_SHARED
:
84 case VNC_SHARE_MODE_EXCLUSIVE
:
85 vs
->vd
->num_exclusive
--;
91 vs
->share_mode
= mode
;
93 switch (vs
->share_mode
) {
94 case VNC_SHARE_MODE_CONNECTING
:
95 vs
->vd
->num_connecting
++;
97 case VNC_SHARE_MODE_SHARED
:
100 case VNC_SHARE_MODE_EXCLUSIVE
:
101 vs
->vd
->num_exclusive
++;
108 static char *addr_to_string(const char *format
,
109 struct sockaddr_storage
*sa
,
112 char host
[NI_MAXHOST
];
113 char serv
[NI_MAXSERV
];
117 if ((err
= getnameinfo((struct sockaddr
*)sa
, salen
,
120 NI_NUMERICHOST
| NI_NUMERICSERV
)) != 0) {
121 VNC_DEBUG("Cannot resolve address %d: %s\n",
122 err
, gai_strerror(err
));
126 /* Enough for the existing format + the 2 vars we're
127 * substituting in. */
128 addrlen
= strlen(format
) + strlen(host
) + strlen(serv
);
129 addr
= g_malloc(addrlen
+ 1);
130 snprintf(addr
, addrlen
, format
, host
, serv
);
131 addr
[addrlen
] = '\0';
137 char *vnc_socket_local_addr(const char *format
, int fd
) {
138 struct sockaddr_storage sa
;
142 if (getsockname(fd
, (struct sockaddr
*)&sa
, &salen
) < 0)
145 return addr_to_string(format
, &sa
, salen
);
148 char *vnc_socket_remote_addr(const char *format
, int fd
) {
149 struct sockaddr_storage sa
;
153 if (getpeername(fd
, (struct sockaddr
*)&sa
, &salen
) < 0)
156 return addr_to_string(format
, &sa
, salen
);
159 static void vnc_init_basic_info(struct sockaddr_storage
*sa
,
164 char host
[NI_MAXHOST
];
165 char serv
[NI_MAXSERV
];
168 if ((err
= getnameinfo((struct sockaddr
*)sa
, salen
,
171 NI_NUMERICHOST
| NI_NUMERICSERV
)) != 0) {
172 error_setg(errp
, "Cannot resolve address: %s",
177 info
->host
= g_strdup(host
);
178 info
->service
= g_strdup(serv
);
179 info
->family
= inet_netfamily(sa
->ss_family
);
182 static void vnc_init_basic_info_from_server_addr(int fd
, VncBasicInfo
*info
,
185 struct sockaddr_storage sa
;
189 if (getsockname(fd
, (struct sockaddr
*)&sa
, &salen
) < 0) {
190 error_setg_errno(errp
, errno
, "getsockname failed");
194 vnc_init_basic_info(&sa
, salen
, info
, errp
);
197 static void vnc_init_basic_info_from_remote_addr(int fd
, VncBasicInfo
*info
,
200 struct sockaddr_storage sa
;
204 if (getpeername(fd
, (struct sockaddr
*)&sa
, &salen
) < 0) {
205 error_setg_errno(errp
, errno
, "getpeername failed");
209 vnc_init_basic_info(&sa
, salen
, info
, errp
);
212 static const char *vnc_auth_name(VncDisplay
*vd
) {
214 case VNC_AUTH_INVALID
:
230 case VNC_AUTH_VENCRYPT
:
231 switch (vd
->subauth
) {
232 case VNC_AUTH_VENCRYPT_PLAIN
:
233 return "vencrypt+plain";
234 case VNC_AUTH_VENCRYPT_TLSNONE
:
235 return "vencrypt+tls+none";
236 case VNC_AUTH_VENCRYPT_TLSVNC
:
237 return "vencrypt+tls+vnc";
238 case VNC_AUTH_VENCRYPT_TLSPLAIN
:
239 return "vencrypt+tls+plain";
240 case VNC_AUTH_VENCRYPT_X509NONE
:
241 return "vencrypt+x509+none";
242 case VNC_AUTH_VENCRYPT_X509VNC
:
243 return "vencrypt+x509+vnc";
244 case VNC_AUTH_VENCRYPT_X509PLAIN
:
245 return "vencrypt+x509+plain";
246 case VNC_AUTH_VENCRYPT_TLSSASL
:
247 return "vencrypt+tls+sasl";
248 case VNC_AUTH_VENCRYPT_X509SASL
:
249 return "vencrypt+x509+sasl";
259 static VncServerInfo
*vnc_server_info_get(VncDisplay
*vd
)
264 info
= g_malloc(sizeof(*info
));
265 vnc_init_basic_info_from_server_addr(vd
->lsock
,
266 qapi_VncServerInfo_base(info
), &err
);
267 info
->has_auth
= true;
268 info
->auth
= g_strdup(vnc_auth_name(vd
));
270 qapi_free_VncServerInfo(info
);
277 static void vnc_client_cache_auth(VncState
*client
)
284 client
->info
->x509_dname
=
285 qcrypto_tls_session_get_peer_name(client
->tls
);
286 client
->info
->has_x509_dname
=
287 client
->info
->x509_dname
!= NULL
;
289 #ifdef CONFIG_VNC_SASL
290 if (client
->sasl
.conn
&&
291 client
->sasl
.username
) {
292 client
->info
->has_sasl_username
= true;
293 client
->info
->sasl_username
= g_strdup(client
->sasl
.username
);
298 static void vnc_client_cache_addr(VncState
*client
)
302 client
->info
= g_malloc0(sizeof(*client
->info
));
303 vnc_init_basic_info_from_remote_addr(client
->csock
,
304 qapi_VncClientInfo_base(client
->info
),
307 qapi_free_VncClientInfo(client
->info
);
313 static void vnc_qmp_event(VncState
*vs
, QAPIEvent event
)
321 si
= vnc_server_info_get(vs
->vd
);
327 case QAPI_EVENT_VNC_CONNECTED
:
328 qapi_event_send_vnc_connected(si
, qapi_VncClientInfo_base(vs
->info
),
331 case QAPI_EVENT_VNC_INITIALIZED
:
332 qapi_event_send_vnc_initialized(si
, vs
->info
, &error_abort
);
334 case QAPI_EVENT_VNC_DISCONNECTED
:
335 qapi_event_send_vnc_disconnected(si
, vs
->info
, &error_abort
);
341 qapi_free_VncServerInfo(si
);
344 static VncClientInfo
*qmp_query_vnc_client(const VncState
*client
)
346 struct sockaddr_storage sa
;
347 socklen_t salen
= sizeof(sa
);
348 char host
[NI_MAXHOST
];
349 char serv
[NI_MAXSERV
];
352 if (getpeername(client
->csock
, (struct sockaddr
*)&sa
, &salen
) < 0) {
356 if (getnameinfo((struct sockaddr
*)&sa
, salen
,
359 NI_NUMERICHOST
| NI_NUMERICSERV
) < 0) {
363 info
= g_malloc0(sizeof(*info
));
364 info
->host
= g_strdup(host
);
365 info
->service
= g_strdup(serv
);
366 info
->family
= inet_netfamily(sa
.ss_family
);
367 info
->websocket
= client
->websocket
;
370 info
->x509_dname
= qcrypto_tls_session_get_peer_name(client
->tls
);
371 info
->has_x509_dname
= info
->x509_dname
!= NULL
;
373 #ifdef CONFIG_VNC_SASL
374 if (client
->sasl
.conn
&& client
->sasl
.username
) {
375 info
->has_sasl_username
= true;
376 info
->sasl_username
= g_strdup(client
->sasl
.username
);
383 static VncDisplay
*vnc_display_find(const char *id
)
388 return QTAILQ_FIRST(&vnc_displays
);
390 QTAILQ_FOREACH(vd
, &vnc_displays
, next
) {
391 if (strcmp(id
, vd
->id
) == 0) {
398 static VncClientInfoList
*qmp_query_client_list(VncDisplay
*vd
)
400 VncClientInfoList
*cinfo
, *prev
= NULL
;
403 QTAILQ_FOREACH(client
, &vd
->clients
, next
) {
404 cinfo
= g_new0(VncClientInfoList
, 1);
405 cinfo
->value
= qmp_query_vnc_client(client
);
412 VncInfo
*qmp_query_vnc(Error
**errp
)
414 VncInfo
*info
= g_malloc0(sizeof(*info
));
415 VncDisplay
*vd
= vnc_display_find(NULL
);
417 if (vd
== NULL
|| !vd
->enabled
) {
418 info
->enabled
= false;
420 struct sockaddr_storage sa
;
421 socklen_t salen
= sizeof(sa
);
422 char host
[NI_MAXHOST
];
423 char serv
[NI_MAXSERV
];
425 info
->enabled
= true;
427 /* for compatibility with the original command */
428 info
->has_clients
= true;
429 info
->clients
= qmp_query_client_list(vd
);
431 if (vd
->lsock
== -1) {
435 if (getsockname(vd
->lsock
, (struct sockaddr
*)&sa
,
437 error_setg(errp
, QERR_UNDEFINED_ERROR
);
441 if (getnameinfo((struct sockaddr
*)&sa
, salen
,
444 NI_NUMERICHOST
| NI_NUMERICSERV
) < 0) {
445 error_setg(errp
, QERR_UNDEFINED_ERROR
);
449 info
->has_host
= true;
450 info
->host
= g_strdup(host
);
452 info
->has_service
= true;
453 info
->service
= g_strdup(serv
);
455 info
->has_family
= true;
456 info
->family
= inet_netfamily(sa
.ss_family
);
458 info
->has_auth
= true;
459 info
->auth
= g_strdup(vnc_auth_name(vd
));
465 qapi_free_VncInfo(info
);
469 static VncBasicInfoList
*qmp_query_server_entry(int socket
,
471 VncBasicInfoList
*prev
)
473 VncBasicInfoList
*list
;
475 struct sockaddr_storage sa
;
476 socklen_t salen
= sizeof(sa
);
477 char host
[NI_MAXHOST
];
478 char serv
[NI_MAXSERV
];
480 if (getsockname(socket
, (struct sockaddr
*)&sa
, &salen
) < 0 ||
481 getnameinfo((struct sockaddr
*)&sa
, salen
,
482 host
, sizeof(host
), serv
, sizeof(serv
),
483 NI_NUMERICHOST
| NI_NUMERICSERV
) < 0) {
487 info
= g_new0(VncBasicInfo
, 1);
488 info
->host
= g_strdup(host
);
489 info
->service
= g_strdup(serv
);
490 info
->family
= inet_netfamily(sa
.ss_family
);
491 info
->websocket
= websocket
;
493 list
= g_new0(VncBasicInfoList
, 1);
499 static void qmp_query_auth(VncDisplay
*vd
, VncInfo2
*info
)
503 info
->auth
= VNC_PRIMARY_AUTH_VNC
;
506 info
->auth
= VNC_PRIMARY_AUTH_RA2
;
509 info
->auth
= VNC_PRIMARY_AUTH_RA2NE
;
512 info
->auth
= VNC_PRIMARY_AUTH_TIGHT
;
515 info
->auth
= VNC_PRIMARY_AUTH_ULTRA
;
518 info
->auth
= VNC_PRIMARY_AUTH_TLS
;
520 case VNC_AUTH_VENCRYPT
:
521 info
->auth
= VNC_PRIMARY_AUTH_VENCRYPT
;
522 info
->has_vencrypt
= true;
523 switch (vd
->subauth
) {
524 case VNC_AUTH_VENCRYPT_PLAIN
:
525 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_PLAIN
;
527 case VNC_AUTH_VENCRYPT_TLSNONE
:
528 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_NONE
;
530 case VNC_AUTH_VENCRYPT_TLSVNC
:
531 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_VNC
;
533 case VNC_AUTH_VENCRYPT_TLSPLAIN
:
534 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN
;
536 case VNC_AUTH_VENCRYPT_X509NONE
:
537 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_NONE
;
539 case VNC_AUTH_VENCRYPT_X509VNC
:
540 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_VNC
;
542 case VNC_AUTH_VENCRYPT_X509PLAIN
:
543 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_PLAIN
;
545 case VNC_AUTH_VENCRYPT_TLSSASL
:
546 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_SASL
;
548 case VNC_AUTH_VENCRYPT_X509SASL
:
549 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_SASL
;
552 info
->has_vencrypt
= false;
557 info
->auth
= VNC_PRIMARY_AUTH_SASL
;
561 info
->auth
= VNC_PRIMARY_AUTH_NONE
;
566 VncInfo2List
*qmp_query_vnc_servers(Error
**errp
)
568 VncInfo2List
*item
, *prev
= NULL
;
573 QTAILQ_FOREACH(vd
, &vnc_displays
, next
) {
574 info
= g_new0(VncInfo2
, 1);
575 info
->id
= g_strdup(vd
->id
);
576 info
->clients
= qmp_query_client_list(vd
);
577 qmp_query_auth(vd
, info
);
579 dev
= DEVICE(object_property_get_link(OBJECT(vd
->dcl
.con
),
581 info
->has_display
= true;
582 info
->display
= g_strdup(dev
->id
);
584 if (vd
->lsock
!= -1) {
585 info
->server
= qmp_query_server_entry(vd
->lsock
, false,
588 if (vd
->lwebsock
!= -1) {
589 info
->server
= qmp_query_server_entry(vd
->lwebsock
, true,
593 item
= g_new0(VncInfo2List
, 1);
602 1) Get the queue working for IO.
603 2) there is some weirdness when using the -S option (the screen is grey
604 and not totally invalidated
605 3) resolutions > 1024
608 static int vnc_update_client(VncState
*vs
, int has_dirty
, bool sync
);
609 static void vnc_disconnect_start(VncState
*vs
);
611 static void vnc_colordepth(VncState
*vs
);
612 static void framebuffer_update_request(VncState
*vs
, int incremental
,
613 int x_position
, int y_position
,
615 static void vnc_refresh(DisplayChangeListener
*dcl
);
616 static int vnc_refresh_server_surface(VncDisplay
*vd
);
618 static int vnc_width(VncDisplay
*vd
)
620 return MIN(VNC_MAX_WIDTH
, ROUND_UP(surface_width(vd
->ds
),
621 VNC_DIRTY_PIXELS_PER_BIT
));
624 static int vnc_height(VncDisplay
*vd
)
626 return MIN(VNC_MAX_HEIGHT
, surface_height(vd
->ds
));
629 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty
[VNC_MAX_HEIGHT
],
630 VNC_MAX_WIDTH
/ VNC_DIRTY_PIXELS_PER_BIT
),
632 int x
, int y
, int w
, int h
)
634 int width
= vnc_width(vd
);
635 int height
= vnc_height(vd
);
637 /* this is needed this to ensure we updated all affected
638 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
639 w
+= (x
% VNC_DIRTY_PIXELS_PER_BIT
);
640 x
-= (x
% VNC_DIRTY_PIXELS_PER_BIT
);
644 w
= MIN(x
+ w
, width
) - x
;
645 h
= MIN(y
+ h
, height
);
648 bitmap_set(dirty
[y
], x
/ VNC_DIRTY_PIXELS_PER_BIT
,
649 DIV_ROUND_UP(w
, VNC_DIRTY_PIXELS_PER_BIT
));
653 static void vnc_dpy_update(DisplayChangeListener
*dcl
,
654 int x
, int y
, int w
, int h
)
656 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
657 struct VncSurface
*s
= &vd
->guest
;
659 vnc_set_area_dirty(s
->dirty
, vd
, x
, y
, w
, h
);
662 void vnc_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
,
665 vnc_write_u16(vs
, x
);
666 vnc_write_u16(vs
, y
);
667 vnc_write_u16(vs
, w
);
668 vnc_write_u16(vs
, h
);
670 vnc_write_s32(vs
, encoding
);
674 static void vnc_desktop_resize(VncState
*vs
)
676 if (vs
->csock
== -1 || !vnc_has_feature(vs
, VNC_FEATURE_RESIZE
)) {
679 if (vs
->client_width
== pixman_image_get_width(vs
->vd
->server
) &&
680 vs
->client_height
== pixman_image_get_height(vs
->vd
->server
)) {
683 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
684 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
686 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
688 vnc_write_u16(vs
, 1); /* number of rects */
689 vnc_framebuffer_update(vs
, 0, 0, vs
->client_width
, vs
->client_height
,
690 VNC_ENCODING_DESKTOPRESIZE
);
691 vnc_unlock_output(vs
);
695 static void vnc_abort_display_jobs(VncDisplay
*vd
)
699 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
702 vnc_unlock_output(vs
);
704 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
707 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
710 vnc_unlock_output(vs
);
714 int vnc_server_fb_stride(VncDisplay
*vd
)
716 return pixman_image_get_stride(vd
->server
);
719 void *vnc_server_fb_ptr(VncDisplay
*vd
, int x
, int y
)
723 ptr
= (uint8_t *)pixman_image_get_data(vd
->server
);
724 ptr
+= y
* vnc_server_fb_stride(vd
);
725 ptr
+= x
* VNC_SERVER_FB_BYTES
;
729 static void vnc_update_server_surface(VncDisplay
*vd
)
731 qemu_pixman_image_unref(vd
->server
);
734 if (QTAILQ_EMPTY(&vd
->clients
)) {
738 vd
->server
= pixman_image_create_bits(VNC_SERVER_FB_FORMAT
,
744 static void vnc_dpy_switch(DisplayChangeListener
*dcl
,
745 DisplaySurface
*surface
)
747 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
751 vnc_abort_display_jobs(vd
);
755 vnc_update_server_surface(vd
);
758 qemu_pixman_image_unref(vd
->guest
.fb
);
759 vd
->guest
.fb
= pixman_image_ref(surface
->image
);
760 vd
->guest
.format
= surface
->format
;
761 width
= vnc_width(vd
);
762 height
= vnc_height(vd
);
763 memset(vd
->guest
.dirty
, 0x00, sizeof(vd
->guest
.dirty
));
764 vnc_set_area_dirty(vd
->guest
.dirty
, vd
, 0, 0,
767 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
769 vnc_desktop_resize(vs
);
770 if (vs
->vd
->cursor
) {
771 vnc_cursor_define(vs
);
773 memset(vs
->dirty
, 0x00, sizeof(vs
->dirty
));
774 vnc_set_area_dirty(vs
->dirty
, vd
, 0, 0,
780 static void vnc_write_pixels_copy(VncState
*vs
,
781 void *pixels
, int size
)
783 vnc_write(vs
, pixels
, size
);
786 /* slowest but generic code. */
787 void vnc_convert_pixel(VncState
*vs
, uint8_t *buf
, uint32_t v
)
791 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
792 r
= (((v
& 0x00ff0000) >> 16) << vs
->client_pf
.rbits
) >> 8;
793 g
= (((v
& 0x0000ff00) >> 8) << vs
->client_pf
.gbits
) >> 8;
794 b
= (((v
& 0x000000ff) >> 0) << vs
->client_pf
.bbits
) >> 8;
796 # error need some bits here if you change VNC_SERVER_FB_FORMAT
798 v
= (r
<< vs
->client_pf
.rshift
) |
799 (g
<< vs
->client_pf
.gshift
) |
800 (b
<< vs
->client_pf
.bshift
);
801 switch (vs
->client_pf
.bytes_per_pixel
) {
831 static void vnc_write_pixels_generic(VncState
*vs
,
832 void *pixels1
, int size
)
836 if (VNC_SERVER_FB_BYTES
== 4) {
837 uint32_t *pixels
= pixels1
;
840 for (i
= 0; i
< n
; i
++) {
841 vnc_convert_pixel(vs
, buf
, pixels
[i
]);
842 vnc_write(vs
, buf
, vs
->client_pf
.bytes_per_pixel
);
847 int vnc_raw_send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
851 VncDisplay
*vd
= vs
->vd
;
853 row
= vnc_server_fb_ptr(vd
, x
, y
);
854 for (i
= 0; i
< h
; i
++) {
855 vs
->write_pixels(vs
, row
, w
* VNC_SERVER_FB_BYTES
);
856 row
+= vnc_server_fb_stride(vd
);
861 int vnc_send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
864 bool encode_raw
= false;
865 size_t saved_offs
= vs
->output
.offset
;
867 switch(vs
->vnc_encoding
) {
868 case VNC_ENCODING_ZLIB
:
869 n
= vnc_zlib_send_framebuffer_update(vs
, x
, y
, w
, h
);
871 case VNC_ENCODING_HEXTILE
:
872 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_HEXTILE
);
873 n
= vnc_hextile_send_framebuffer_update(vs
, x
, y
, w
, h
);
875 case VNC_ENCODING_TIGHT
:
876 n
= vnc_tight_send_framebuffer_update(vs
, x
, y
, w
, h
);
878 case VNC_ENCODING_TIGHT_PNG
:
879 n
= vnc_tight_png_send_framebuffer_update(vs
, x
, y
, w
, h
);
881 case VNC_ENCODING_ZRLE
:
882 n
= vnc_zrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
884 case VNC_ENCODING_ZYWRLE
:
885 n
= vnc_zywrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
892 /* If the client has the same pixel format as our internal buffer and
893 * a RAW encoding would need less space fall back to RAW encoding to
894 * save bandwidth and processing power in the client. */
895 if (!encode_raw
&& vs
->write_pixels
== vnc_write_pixels_copy
&&
896 12 + h
* w
* VNC_SERVER_FB_BYTES
<= (vs
->output
.offset
- saved_offs
)) {
897 vs
->output
.offset
= saved_offs
;
902 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_RAW
);
903 n
= vnc_raw_send_framebuffer_update(vs
, x
, y
, w
, h
);
909 static void vnc_copy(VncState
*vs
, int src_x
, int src_y
, int dst_x
, int dst_y
, int w
, int h
)
911 /* send bitblit op to the vnc client */
913 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
915 vnc_write_u16(vs
, 1); /* number of rects */
916 vnc_framebuffer_update(vs
, dst_x
, dst_y
, w
, h
, VNC_ENCODING_COPYRECT
);
917 vnc_write_u16(vs
, src_x
);
918 vnc_write_u16(vs
, src_y
);
919 vnc_unlock_output(vs
);
923 static void vnc_dpy_copy(DisplayChangeListener
*dcl
,
924 int src_x
, int src_y
,
925 int dst_x
, int dst_y
, int w
, int h
)
927 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
931 int i
, x
, y
, pitch
, inc
, w_lim
, s
;
935 /* no client connected */
939 vnc_refresh_server_surface(vd
);
940 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
941 if (vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
942 vs
->force_update
= 1;
943 vnc_update_client(vs
, 1, true);
944 /* vs might be free()ed here */
948 /* do bitblit op on the local surface too */
949 pitch
= vnc_server_fb_stride(vd
);
950 src_row
= vnc_server_fb_ptr(vd
, src_x
, src_y
);
951 dst_row
= vnc_server_fb_ptr(vd
, dst_x
, dst_y
);
956 src_row
+= pitch
* (h
-1);
957 dst_row
+= pitch
* (h
-1);
962 w_lim
= w
- (VNC_DIRTY_PIXELS_PER_BIT
- (dst_x
% VNC_DIRTY_PIXELS_PER_BIT
));
966 w_lim
= w
- (w_lim
% VNC_DIRTY_PIXELS_PER_BIT
);
968 for (i
= 0; i
< h
; i
++) {
969 for (x
= 0; x
<= w_lim
;
970 x
+= s
, src_row
+= cmp_bytes
, dst_row
+= cmp_bytes
) {
972 if ((s
= w
- w_lim
) == 0)
975 s
= (VNC_DIRTY_PIXELS_PER_BIT
-
976 (dst_x
% VNC_DIRTY_PIXELS_PER_BIT
));
979 s
= VNC_DIRTY_PIXELS_PER_BIT
;
981 cmp_bytes
= s
* VNC_SERVER_FB_BYTES
;
982 if (memcmp(src_row
, dst_row
, cmp_bytes
) == 0)
984 memmove(dst_row
, src_row
, cmp_bytes
);
985 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
986 if (!vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
987 set_bit(((x
+ dst_x
) / VNC_DIRTY_PIXELS_PER_BIT
),
992 src_row
+= pitch
- w
* VNC_SERVER_FB_BYTES
;
993 dst_row
+= pitch
- w
* VNC_SERVER_FB_BYTES
;
997 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
998 if (vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
999 vnc_copy(vs
, src_x
, src_y
, dst_x
, dst_y
, w
, h
);
1004 static void vnc_mouse_set(DisplayChangeListener
*dcl
,
1005 int x
, int y
, int visible
)
1007 /* can we ask the client(s) to move the pointer ??? */
1010 static int vnc_cursor_define(VncState
*vs
)
1012 QEMUCursor
*c
= vs
->vd
->cursor
;
1015 if (vnc_has_feature(vs
, VNC_FEATURE_RICH_CURSOR
)) {
1016 vnc_lock_output(vs
);
1017 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1018 vnc_write_u8(vs
, 0); /* padding */
1019 vnc_write_u16(vs
, 1); /* # of rects */
1020 vnc_framebuffer_update(vs
, c
->hot_x
, c
->hot_y
, c
->width
, c
->height
,
1021 VNC_ENCODING_RICH_CURSOR
);
1022 isize
= c
->width
* c
->height
* vs
->client_pf
.bytes_per_pixel
;
1023 vnc_write_pixels_generic(vs
, c
->data
, isize
);
1024 vnc_write(vs
, vs
->vd
->cursor_mask
, vs
->vd
->cursor_msize
);
1025 vnc_unlock_output(vs
);
1031 static void vnc_dpy_cursor_define(DisplayChangeListener
*dcl
,
1034 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
1037 cursor_put(vd
->cursor
);
1038 g_free(vd
->cursor_mask
);
1041 cursor_get(vd
->cursor
);
1042 vd
->cursor_msize
= cursor_get_mono_bpl(c
) * c
->height
;
1043 vd
->cursor_mask
= g_malloc0(vd
->cursor_msize
);
1044 cursor_get_mono_mask(c
, 0, vd
->cursor_mask
);
1046 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
1047 vnc_cursor_define(vs
);
1051 static int find_and_clear_dirty_height(VncState
*vs
,
1052 int y
, int last_x
, int x
, int height
)
1056 for (h
= 1; h
< (height
- y
); h
++) {
1057 if (!test_bit(last_x
, vs
->dirty
[y
+ h
])) {
1060 bitmap_clear(vs
->dirty
[y
+ h
], last_x
, x
- last_x
);
1066 static int vnc_update_client(VncState
*vs
, int has_dirty
, bool sync
)
1068 vs
->has_dirty
+= has_dirty
;
1069 if (vs
->need_update
&& vs
->csock
!= -1) {
1070 VncDisplay
*vd
= vs
->vd
;
1076 if (vs
->output
.offset
&& !vs
->audio_cap
&& !vs
->force_update
)
1077 /* kernel send buffers are full -> drop frames to throttle */
1080 if (!vs
->has_dirty
&& !vs
->audio_cap
&& !vs
->force_update
)
1084 * Send screen updates to the vnc client using the server
1085 * surface and server dirty map. guest surface updates
1086 * happening in parallel don't disturb us, the next pass will
1087 * send them to the client.
1089 job
= vnc_job_new(vs
);
1091 height
= pixman_image_get_height(vd
->server
);
1092 width
= pixman_image_get_width(vd
->server
);
1098 unsigned long offset
= find_next_bit((unsigned long *) &vs
->dirty
,
1099 height
* VNC_DIRTY_BPL(vs
),
1100 y
* VNC_DIRTY_BPL(vs
));
1101 if (offset
== height
* VNC_DIRTY_BPL(vs
)) {
1102 /* no more dirty bits */
1105 y
= offset
/ VNC_DIRTY_BPL(vs
);
1106 x
= offset
% VNC_DIRTY_BPL(vs
);
1107 x2
= find_next_zero_bit((unsigned long *) &vs
->dirty
[y
],
1108 VNC_DIRTY_BPL(vs
), x
);
1109 bitmap_clear(vs
->dirty
[y
], x
, x2
- x
);
1110 h
= find_and_clear_dirty_height(vs
, y
, x
, x2
, height
);
1111 x2
= MIN(x2
, width
/ VNC_DIRTY_PIXELS_PER_BIT
);
1113 n
+= vnc_job_add_rect(job
, x
* VNC_DIRTY_PIXELS_PER_BIT
, y
,
1114 (x2
- x
) * VNC_DIRTY_PIXELS_PER_BIT
, h
);
1116 if (!x
&& x2
== width
/ VNC_DIRTY_PIXELS_PER_BIT
) {
1128 vs
->force_update
= 0;
1133 if (vs
->csock
== -1) {
1134 vnc_disconnect_finish(vs
);
1143 static void audio_capture_notify(void *opaque
, audcnotification_e cmd
)
1145 VncState
*vs
= opaque
;
1148 case AUD_CNOTIFY_DISABLE
:
1149 vnc_lock_output(vs
);
1150 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1151 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1152 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_END
);
1153 vnc_unlock_output(vs
);
1157 case AUD_CNOTIFY_ENABLE
:
1158 vnc_lock_output(vs
);
1159 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1160 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1161 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN
);
1162 vnc_unlock_output(vs
);
1168 static void audio_capture_destroy(void *opaque
)
1172 static void audio_capture(void *opaque
, void *buf
, int size
)
1174 VncState
*vs
= opaque
;
1176 vnc_lock_output(vs
);
1177 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1178 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1179 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_DATA
);
1180 vnc_write_u32(vs
, size
);
1181 vnc_write(vs
, buf
, size
);
1182 vnc_unlock_output(vs
);
1186 static void audio_add(VncState
*vs
)
1188 struct audio_capture_ops ops
;
1190 if (vs
->audio_cap
) {
1191 error_report("audio already running");
1195 ops
.notify
= audio_capture_notify
;
1196 ops
.destroy
= audio_capture_destroy
;
1197 ops
.capture
= audio_capture
;
1199 vs
->audio_cap
= AUD_add_capture(&vs
->as
, &ops
, vs
);
1200 if (!vs
->audio_cap
) {
1201 error_report("Failed to add audio capture");
1205 static void audio_del(VncState
*vs
)
1207 if (vs
->audio_cap
) {
1208 AUD_del_capture(vs
->audio_cap
, vs
);
1209 vs
->audio_cap
= NULL
;
1213 static void vnc_disconnect_start(VncState
*vs
)
1215 if (vs
->csock
== -1)
1217 vnc_set_share_mode(vs
, VNC_SHARE_MODE_DISCONNECTED
);
1218 qemu_set_fd_handler(vs
->csock
, NULL
, NULL
, NULL
);
1219 closesocket(vs
->csock
);
1223 void vnc_disconnect_finish(VncState
*vs
)
1227 vnc_jobs_join(vs
); /* Wait encoding jobs */
1229 vnc_lock_output(vs
);
1230 vnc_qmp_event(vs
, QAPI_EVENT_VNC_DISCONNECTED
);
1232 buffer_free(&vs
->input
);
1233 buffer_free(&vs
->output
);
1234 buffer_free(&vs
->ws_input
);
1235 buffer_free(&vs
->ws_output
);
1237 qapi_free_VncClientInfo(vs
->info
);
1240 vnc_tight_clear(vs
);
1243 qcrypto_tls_session_free(vs
->tls
);
1244 #ifdef CONFIG_VNC_SASL
1245 vnc_sasl_client_cleanup(vs
);
1246 #endif /* CONFIG_VNC_SASL */
1248 vnc_release_modifiers(vs
);
1250 if (vs
->initialized
) {
1251 QTAILQ_REMOVE(&vs
->vd
->clients
, vs
, next
);
1252 qemu_remove_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
1253 if (QTAILQ_EMPTY(&vs
->vd
->clients
)) {
1254 /* last client gone */
1255 vnc_update_server_surface(vs
->vd
);
1259 if (vs
->vd
->lock_key_sync
)
1260 qemu_remove_led_event_handler(vs
->led
);
1261 vnc_unlock_output(vs
);
1263 qemu_mutex_destroy(&vs
->output_mutex
);
1264 if (vs
->bh
!= NULL
) {
1265 qemu_bh_delete(vs
->bh
);
1267 buffer_free(&vs
->jobs_buffer
);
1269 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
1270 g_free(vs
->lossy_rect
[i
]);
1272 g_free(vs
->lossy_rect
);
1276 ssize_t
vnc_client_io_error(VncState
*vs
, ssize_t ret
, int last_errno
)
1278 if (ret
== 0 || ret
== -1) {
1280 switch (last_errno
) {
1284 case WSAEWOULDBLOCK
:
1292 VNC_DEBUG("Closing down client sock: ret %zd, errno %d\n",
1293 ret
, ret
< 0 ? last_errno
: 0);
1294 vnc_disconnect_start(vs
);
1302 void vnc_client_error(VncState
*vs
)
1304 VNC_DEBUG("Closing down client sock: protocol error\n");
1305 vnc_disconnect_start(vs
);
1309 ssize_t
vnc_tls_pull(char *buf
, size_t len
, void *opaque
)
1311 VncState
*vs
= opaque
;
1315 ret
= qemu_recv(vs
->csock
, buf
, len
, 0);
1317 if (errno
== EINTR
) {
1326 ssize_t
vnc_tls_push(const char *buf
, size_t len
, void *opaque
)
1328 VncState
*vs
= opaque
;
1332 ret
= send(vs
->csock
, buf
, len
, 0);
1334 if (errno
== EINTR
) {
1344 * Called to write a chunk of data to the client socket. The data may
1345 * be the raw data, or may have already been encoded by SASL.
1346 * The data will be written either straight onto the socket, or
1347 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1349 * NB, it is theoretically possible to have 2 layers of encryption,
1350 * both SASL, and this TLS layer. It is highly unlikely in practice
1351 * though, since SASL encryption will typically be a no-op if TLS
1354 * Returns the number of bytes written, which may be less than
1355 * the requested 'datalen' if the socket would block. Returns
1356 * -1 on error, and disconnects the client socket.
1358 ssize_t
vnc_client_write_buf(VncState
*vs
, const uint8_t *data
, size_t datalen
)
1363 ret
= qcrypto_tls_session_write(vs
->tls
, (const char *)data
, datalen
);
1368 ret
= send(vs
->csock
, (const void *)data
, datalen
, 0);
1370 err
= socket_error();
1373 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data
, datalen
, ret
);
1374 return vnc_client_io_error(vs
, ret
, err
);
1379 * Called to write buffered data to the client socket, when not
1380 * using any SASL SSF encryption layers. Will write as much data
1381 * as possible without blocking. If all buffered data is written,
1382 * will switch the FD poll() handler back to read monitoring.
1384 * Returns the number of bytes written, which may be less than
1385 * the buffered output data if the socket would block. Returns
1386 * -1 on error, and disconnects the client socket.
1388 static ssize_t
vnc_client_write_plain(VncState
*vs
)
1392 #ifdef CONFIG_VNC_SASL
1393 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1394 vs
->output
.buffer
, vs
->output
.capacity
, vs
->output
.offset
,
1395 vs
->sasl
.waitWriteSSF
);
1397 if (vs
->sasl
.conn
&&
1399 vs
->sasl
.waitWriteSSF
) {
1400 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->sasl
.waitWriteSSF
);
1402 vs
->sasl
.waitWriteSSF
-= ret
;
1404 #endif /* CONFIG_VNC_SASL */
1405 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->output
.offset
);
1409 buffer_advance(&vs
->output
, ret
);
1411 if (vs
->output
.offset
== 0) {
1412 qemu_set_fd_handler(vs
->csock
, vnc_client_read
, NULL
, vs
);
1420 * First function called whenever there is data to be written to
1421 * the client socket. Will delegate actual work according to whether
1422 * SASL SSF layers are enabled (thus requiring encryption calls)
1424 static void vnc_client_write_locked(void *opaque
)
1426 VncState
*vs
= opaque
;
1428 #ifdef CONFIG_VNC_SASL
1429 if (vs
->sasl
.conn
&&
1431 !vs
->sasl
.waitWriteSSF
) {
1432 vnc_client_write_sasl(vs
);
1434 #endif /* CONFIG_VNC_SASL */
1436 if (vs
->encode_ws
) {
1437 vnc_client_write_ws(vs
);
1439 vnc_client_write_plain(vs
);
1444 void vnc_client_write(void *opaque
)
1446 VncState
*vs
= opaque
;
1448 vnc_lock_output(vs
);
1449 if (vs
->output
.offset
|| vs
->ws_output
.offset
) {
1450 vnc_client_write_locked(opaque
);
1451 } else if (vs
->csock
!= -1) {
1452 qemu_set_fd_handler(vs
->csock
, vnc_client_read
, NULL
, vs
);
1454 vnc_unlock_output(vs
);
1457 void vnc_read_when(VncState
*vs
, VncReadEvent
*func
, size_t expecting
)
1459 vs
->read_handler
= func
;
1460 vs
->read_handler_expect
= expecting
;
1465 * Called to read a chunk of data from the client socket. The data may
1466 * be the raw data, or may need to be further decoded by SASL.
1467 * The data will be read either straight from to the socket, or
1468 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1470 * NB, it is theoretically possible to have 2 layers of encryption,
1471 * both SASL, and this TLS layer. It is highly unlikely in practice
1472 * though, since SASL encryption will typically be a no-op if TLS
1475 * Returns the number of bytes read, which may be less than
1476 * the requested 'datalen' if the socket would block. Returns
1477 * -1 on error, and disconnects the client socket.
1479 ssize_t
vnc_client_read_buf(VncState
*vs
, uint8_t *data
, size_t datalen
)
1484 ret
= qcrypto_tls_session_read(vs
->tls
, (char *)data
, datalen
);
1489 ret
= qemu_recv(vs
->csock
, data
, datalen
, 0);
1491 err
= socket_error();
1494 VNC_DEBUG("Read wire %p %zd -> %ld\n", data
, datalen
, ret
);
1495 return vnc_client_io_error(vs
, ret
, err
);
1500 * Called to read data from the client socket to the input buffer,
1501 * when not using any SASL SSF encryption layers. Will read as much
1502 * data as possible without blocking.
1504 * Returns the number of bytes read. Returns -1 on error, and
1505 * disconnects the client socket.
1507 static ssize_t
vnc_client_read_plain(VncState
*vs
)
1510 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1511 vs
->input
.buffer
, vs
->input
.capacity
, vs
->input
.offset
);
1512 buffer_reserve(&vs
->input
, 4096);
1513 ret
= vnc_client_read_buf(vs
, buffer_end(&vs
->input
), 4096);
1516 vs
->input
.offset
+= ret
;
1520 static void vnc_jobs_bh(void *opaque
)
1522 VncState
*vs
= opaque
;
1524 vnc_jobs_consume_buffer(vs
);
1528 * First function called whenever there is more data to be read from
1529 * the client socket. Will delegate actual work according to whether
1530 * SASL SSF layers are enabled (thus requiring decryption calls)
1532 void vnc_client_read(void *opaque
)
1534 VncState
*vs
= opaque
;
1537 #ifdef CONFIG_VNC_SASL
1538 if (vs
->sasl
.conn
&& vs
->sasl
.runSSF
)
1539 ret
= vnc_client_read_sasl(vs
);
1541 #endif /* CONFIG_VNC_SASL */
1542 if (vs
->encode_ws
) {
1543 ret
= vnc_client_read_ws(vs
);
1545 vnc_disconnect_start(vs
);
1547 } else if (ret
== -2) {
1548 vnc_client_error(vs
);
1552 ret
= vnc_client_read_plain(vs
);
1555 if (vs
->csock
== -1)
1556 vnc_disconnect_finish(vs
);
1560 while (vs
->read_handler
&& vs
->input
.offset
>= vs
->read_handler_expect
) {
1561 size_t len
= vs
->read_handler_expect
;
1564 ret
= vs
->read_handler(vs
, vs
->input
.buffer
, len
);
1565 if (vs
->csock
== -1) {
1566 vnc_disconnect_finish(vs
);
1571 buffer_advance(&vs
->input
, len
);
1573 vs
->read_handler_expect
= ret
;
1578 void vnc_write(VncState
*vs
, const void *data
, size_t len
)
1580 buffer_reserve(&vs
->output
, len
);
1582 if (vs
->csock
!= -1 && buffer_empty(&vs
->output
)) {
1583 qemu_set_fd_handler(vs
->csock
, vnc_client_read
, vnc_client_write
, vs
);
1586 buffer_append(&vs
->output
, data
, len
);
1589 void vnc_write_s32(VncState
*vs
, int32_t value
)
1591 vnc_write_u32(vs
, *(uint32_t *)&value
);
1594 void vnc_write_u32(VncState
*vs
, uint32_t value
)
1598 buf
[0] = (value
>> 24) & 0xFF;
1599 buf
[1] = (value
>> 16) & 0xFF;
1600 buf
[2] = (value
>> 8) & 0xFF;
1601 buf
[3] = value
& 0xFF;
1603 vnc_write(vs
, buf
, 4);
1606 void vnc_write_u16(VncState
*vs
, uint16_t value
)
1610 buf
[0] = (value
>> 8) & 0xFF;
1611 buf
[1] = value
& 0xFF;
1613 vnc_write(vs
, buf
, 2);
1616 void vnc_write_u8(VncState
*vs
, uint8_t value
)
1618 vnc_write(vs
, (char *)&value
, 1);
1621 void vnc_flush(VncState
*vs
)
1623 vnc_lock_output(vs
);
1624 if (vs
->csock
!= -1 && (vs
->output
.offset
||
1625 vs
->ws_output
.offset
)) {
1626 vnc_client_write_locked(vs
);
1628 vnc_unlock_output(vs
);
1631 static uint8_t read_u8(uint8_t *data
, size_t offset
)
1633 return data
[offset
];
1636 static uint16_t read_u16(uint8_t *data
, size_t offset
)
1638 return ((data
[offset
] & 0xFF) << 8) | (data
[offset
+ 1] & 0xFF);
1641 static int32_t read_s32(uint8_t *data
, size_t offset
)
1643 return (int32_t)((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1644 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1647 uint32_t read_u32(uint8_t *data
, size_t offset
)
1649 return ((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1650 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1653 static void client_cut_text(VncState
*vs
, size_t len
, uint8_t *text
)
1657 static void check_pointer_type_change(Notifier
*notifier
, void *data
)
1659 VncState
*vs
= container_of(notifier
, VncState
, mouse_mode_notifier
);
1660 int absolute
= qemu_input_is_absolute();
1662 if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
) && vs
->absolute
!= absolute
) {
1663 vnc_lock_output(vs
);
1664 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1665 vnc_write_u8(vs
, 0);
1666 vnc_write_u16(vs
, 1);
1667 vnc_framebuffer_update(vs
, absolute
, 0,
1668 pixman_image_get_width(vs
->vd
->server
),
1669 pixman_image_get_height(vs
->vd
->server
),
1670 VNC_ENCODING_POINTER_TYPE_CHANGE
);
1671 vnc_unlock_output(vs
);
1674 vs
->absolute
= absolute
;
1677 static void pointer_event(VncState
*vs
, int button_mask
, int x
, int y
)
1679 static uint32_t bmap
[INPUT_BUTTON__MAX
] = {
1680 [INPUT_BUTTON_LEFT
] = 0x01,
1681 [INPUT_BUTTON_MIDDLE
] = 0x02,
1682 [INPUT_BUTTON_RIGHT
] = 0x04,
1683 [INPUT_BUTTON_WHEELUP
] = 0x08,
1684 [INPUT_BUTTON_WHEELDOWN
] = 0x10,
1686 QemuConsole
*con
= vs
->vd
->dcl
.con
;
1687 int width
= pixman_image_get_width(vs
->vd
->server
);
1688 int height
= pixman_image_get_height(vs
->vd
->server
);
1690 if (vs
->last_bmask
!= button_mask
) {
1691 qemu_input_update_buttons(con
, bmap
, vs
->last_bmask
, button_mask
);
1692 vs
->last_bmask
= button_mask
;
1696 qemu_input_queue_abs(con
, INPUT_AXIS_X
, x
, width
);
1697 qemu_input_queue_abs(con
, INPUT_AXIS_Y
, y
, height
);
1698 } else if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
)) {
1699 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- 0x7FFF);
1700 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- 0x7FFF);
1702 if (vs
->last_x
!= -1) {
1703 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- vs
->last_x
);
1704 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- vs
->last_y
);
1709 qemu_input_event_sync();
1712 static void reset_keys(VncState
*vs
)
1715 for(i
= 0; i
< 256; i
++) {
1716 if (vs
->modifiers_state
[i
]) {
1717 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, i
, false);
1718 vs
->modifiers_state
[i
] = 0;
1723 static void press_key(VncState
*vs
, int keysym
)
1725 int keycode
= keysym2scancode(vs
->vd
->kbd_layout
, keysym
) & SCANCODE_KEYMASK
;
1726 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, true);
1727 qemu_input_event_send_key_delay(0);
1728 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1729 qemu_input_event_send_key_delay(0);
1732 static int current_led_state(VncState
*vs
)
1736 if (vs
->modifiers_state
[0x46]) {
1737 ledstate
|= QEMU_SCROLL_LOCK_LED
;
1739 if (vs
->modifiers_state
[0x45]) {
1740 ledstate
|= QEMU_NUM_LOCK_LED
;
1742 if (vs
->modifiers_state
[0x3a]) {
1743 ledstate
|= QEMU_CAPS_LOCK_LED
;
1749 static void vnc_led_state_change(VncState
*vs
)
1753 if (!vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
)) {
1757 ledstate
= current_led_state(vs
);
1758 vnc_lock_output(vs
);
1759 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1760 vnc_write_u8(vs
, 0);
1761 vnc_write_u16(vs
, 1);
1762 vnc_framebuffer_update(vs
, 0, 0, 1, 1, VNC_ENCODING_LED_STATE
);
1763 vnc_write_u8(vs
, ledstate
);
1764 vnc_unlock_output(vs
);
1768 static void kbd_leds(void *opaque
, int ledstate
)
1770 VncState
*vs
= opaque
;
1772 bool has_changed
= (ledstate
!= current_led_state(vs
));
1774 trace_vnc_key_guest_leds((ledstate
& QEMU_CAPS_LOCK_LED
),
1775 (ledstate
& QEMU_NUM_LOCK_LED
),
1776 (ledstate
& QEMU_SCROLL_LOCK_LED
));
1778 caps
= ledstate
& QEMU_CAPS_LOCK_LED
? 1 : 0;
1779 num
= ledstate
& QEMU_NUM_LOCK_LED
? 1 : 0;
1780 scr
= ledstate
& QEMU_SCROLL_LOCK_LED
? 1 : 0;
1782 if (vs
->modifiers_state
[0x3a] != caps
) {
1783 vs
->modifiers_state
[0x3a] = caps
;
1785 if (vs
->modifiers_state
[0x45] != num
) {
1786 vs
->modifiers_state
[0x45] = num
;
1788 if (vs
->modifiers_state
[0x46] != scr
) {
1789 vs
->modifiers_state
[0x46] = scr
;
1792 /* Sending the current led state message to the client */
1794 vnc_led_state_change(vs
);
1798 static void do_key_event(VncState
*vs
, int down
, int keycode
, int sym
)
1800 /* QEMU console switch */
1802 case 0x2a: /* Left Shift */
1803 case 0x36: /* Right Shift */
1804 case 0x1d: /* Left CTRL */
1805 case 0x9d: /* Right CTRL */
1806 case 0x38: /* Left ALT */
1807 case 0xb8: /* Right ALT */
1809 vs
->modifiers_state
[keycode
] = 1;
1811 vs
->modifiers_state
[keycode
] = 0;
1813 case 0x02 ... 0x0a: /* '1' to '9' keys */
1814 if (vs
->vd
->dcl
.con
== NULL
&&
1815 down
&& vs
->modifiers_state
[0x1d] && vs
->modifiers_state
[0x38]) {
1816 /* Reset the modifiers sent to the current console */
1818 console_select(keycode
- 0x02);
1822 case 0x3a: /* CapsLock */
1823 case 0x45: /* NumLock */
1825 vs
->modifiers_state
[keycode
] ^= 1;
1829 /* Turn off the lock state sync logic if the client support the led
1832 if (down
&& vs
->vd
->lock_key_sync
&&
1833 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1834 keycode_is_keypad(vs
->vd
->kbd_layout
, keycode
)) {
1835 /* If the numlock state needs to change then simulate an additional
1836 keypress before sending this one. This will happen if the user
1837 toggles numlock away from the VNC window.
1839 if (keysym_is_numlock(vs
->vd
->kbd_layout
, sym
& 0xFFFF)) {
1840 if (!vs
->modifiers_state
[0x45]) {
1841 trace_vnc_key_sync_numlock(true);
1842 vs
->modifiers_state
[0x45] = 1;
1843 press_key(vs
, 0xff7f);
1846 if (vs
->modifiers_state
[0x45]) {
1847 trace_vnc_key_sync_numlock(false);
1848 vs
->modifiers_state
[0x45] = 0;
1849 press_key(vs
, 0xff7f);
1854 if (down
&& vs
->vd
->lock_key_sync
&&
1855 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1856 ((sym
>= 'A' && sym
<= 'Z') || (sym
>= 'a' && sym
<= 'z'))) {
1857 /* If the capslock state needs to change then simulate an additional
1858 keypress before sending this one. This will happen if the user
1859 toggles capslock away from the VNC window.
1861 int uppercase
= !!(sym
>= 'A' && sym
<= 'Z');
1862 int shift
= !!(vs
->modifiers_state
[0x2a] | vs
->modifiers_state
[0x36]);
1863 int capslock
= !!(vs
->modifiers_state
[0x3a]);
1865 if (uppercase
== shift
) {
1866 trace_vnc_key_sync_capslock(false);
1867 vs
->modifiers_state
[0x3a] = 0;
1868 press_key(vs
, 0xffe5);
1871 if (uppercase
!= shift
) {
1872 trace_vnc_key_sync_capslock(true);
1873 vs
->modifiers_state
[0x3a] = 1;
1874 press_key(vs
, 0xffe5);
1879 if (qemu_console_is_graphic(NULL
)) {
1880 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, down
);
1882 bool numlock
= vs
->modifiers_state
[0x45];
1883 bool control
= (vs
->modifiers_state
[0x1d] ||
1884 vs
->modifiers_state
[0x9d]);
1885 /* QEMU console emulation */
1888 case 0x2a: /* Left Shift */
1889 case 0x36: /* Right Shift */
1890 case 0x1d: /* Left CTRL */
1891 case 0x9d: /* Right CTRL */
1892 case 0x38: /* Left ALT */
1893 case 0xb8: /* Right ALT */
1896 kbd_put_keysym(QEMU_KEY_UP
);
1899 kbd_put_keysym(QEMU_KEY_DOWN
);
1902 kbd_put_keysym(QEMU_KEY_LEFT
);
1905 kbd_put_keysym(QEMU_KEY_RIGHT
);
1908 kbd_put_keysym(QEMU_KEY_DELETE
);
1911 kbd_put_keysym(QEMU_KEY_HOME
);
1914 kbd_put_keysym(QEMU_KEY_END
);
1917 kbd_put_keysym(QEMU_KEY_PAGEUP
);
1920 kbd_put_keysym(QEMU_KEY_PAGEDOWN
);
1924 kbd_put_keysym(numlock
? '7' : QEMU_KEY_HOME
);
1927 kbd_put_keysym(numlock
? '8' : QEMU_KEY_UP
);
1930 kbd_put_keysym(numlock
? '9' : QEMU_KEY_PAGEUP
);
1933 kbd_put_keysym(numlock
? '4' : QEMU_KEY_LEFT
);
1936 kbd_put_keysym('5');
1939 kbd_put_keysym(numlock
? '6' : QEMU_KEY_RIGHT
);
1942 kbd_put_keysym(numlock
? '1' : QEMU_KEY_END
);
1945 kbd_put_keysym(numlock
? '2' : QEMU_KEY_DOWN
);
1948 kbd_put_keysym(numlock
? '3' : QEMU_KEY_PAGEDOWN
);
1951 kbd_put_keysym('0');
1954 kbd_put_keysym(numlock
? '.' : QEMU_KEY_DELETE
);
1958 kbd_put_keysym('/');
1961 kbd_put_keysym('*');
1964 kbd_put_keysym('-');
1967 kbd_put_keysym('+');
1970 kbd_put_keysym('\n');
1975 kbd_put_keysym(sym
& 0x1f);
1977 kbd_put_keysym(sym
);
1985 static void vnc_release_modifiers(VncState
*vs
)
1987 static const int keycodes
[] = {
1988 /* shift, control, alt keys, both left & right */
1989 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1993 if (!qemu_console_is_graphic(NULL
)) {
1996 for (i
= 0; i
< ARRAY_SIZE(keycodes
); i
++) {
1997 keycode
= keycodes
[i
];
1998 if (!vs
->modifiers_state
[keycode
]) {
2001 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
2005 static const char *code2name(int keycode
)
2007 return QKeyCode_lookup
[qemu_input_key_number_to_qcode(keycode
)];
2010 static void key_event(VncState
*vs
, int down
, uint32_t sym
)
2015 if (lsym
>= 'A' && lsym
<= 'Z' && qemu_console_is_graphic(NULL
)) {
2016 lsym
= lsym
- 'A' + 'a';
2019 keycode
= keysym2scancode(vs
->vd
->kbd_layout
, lsym
& 0xFFFF) & SCANCODE_KEYMASK
;
2020 trace_vnc_key_event_map(down
, sym
, keycode
, code2name(keycode
));
2021 do_key_event(vs
, down
, keycode
, sym
);
2024 static void ext_key_event(VncState
*vs
, int down
,
2025 uint32_t sym
, uint16_t keycode
)
2027 /* if the user specifies a keyboard layout, always use it */
2028 if (keyboard_layout
) {
2029 key_event(vs
, down
, sym
);
2031 trace_vnc_key_event_ext(down
, sym
, keycode
, code2name(keycode
));
2032 do_key_event(vs
, down
, keycode
, sym
);
2036 static void framebuffer_update_request(VncState
*vs
, int incremental
,
2037 int x
, int y
, int w
, int h
)
2039 vs
->need_update
= 1;
2045 vs
->force_update
= 1;
2046 vnc_set_area_dirty(vs
->dirty
, vs
->vd
, x
, y
, w
, h
);
2049 static void send_ext_key_event_ack(VncState
*vs
)
2051 vnc_lock_output(vs
);
2052 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2053 vnc_write_u8(vs
, 0);
2054 vnc_write_u16(vs
, 1);
2055 vnc_framebuffer_update(vs
, 0, 0,
2056 pixman_image_get_width(vs
->vd
->server
),
2057 pixman_image_get_height(vs
->vd
->server
),
2058 VNC_ENCODING_EXT_KEY_EVENT
);
2059 vnc_unlock_output(vs
);
2063 static void send_ext_audio_ack(VncState
*vs
)
2065 vnc_lock_output(vs
);
2066 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2067 vnc_write_u8(vs
, 0);
2068 vnc_write_u16(vs
, 1);
2069 vnc_framebuffer_update(vs
, 0, 0,
2070 pixman_image_get_width(vs
->vd
->server
),
2071 pixman_image_get_height(vs
->vd
->server
),
2072 VNC_ENCODING_AUDIO
);
2073 vnc_unlock_output(vs
);
2077 static void set_encodings(VncState
*vs
, int32_t *encodings
, size_t n_encodings
)
2080 unsigned int enc
= 0;
2083 vs
->vnc_encoding
= 0;
2084 vs
->tight
.compression
= 9;
2085 vs
->tight
.quality
= -1; /* Lossless by default */
2089 * Start from the end because the encodings are sent in order of preference.
2090 * This way the preferred encoding (first encoding defined in the array)
2091 * will be set at the end of the loop.
2093 for (i
= n_encodings
- 1; i
>= 0; i
--) {
2096 case VNC_ENCODING_RAW
:
2097 vs
->vnc_encoding
= enc
;
2099 case VNC_ENCODING_COPYRECT
:
2100 vs
->features
|= VNC_FEATURE_COPYRECT_MASK
;
2102 case VNC_ENCODING_HEXTILE
:
2103 vs
->features
|= VNC_FEATURE_HEXTILE_MASK
;
2104 vs
->vnc_encoding
= enc
;
2106 case VNC_ENCODING_TIGHT
:
2107 vs
->features
|= VNC_FEATURE_TIGHT_MASK
;
2108 vs
->vnc_encoding
= enc
;
2110 #ifdef CONFIG_VNC_PNG
2111 case VNC_ENCODING_TIGHT_PNG
:
2112 vs
->features
|= VNC_FEATURE_TIGHT_PNG_MASK
;
2113 vs
->vnc_encoding
= enc
;
2116 case VNC_ENCODING_ZLIB
:
2117 vs
->features
|= VNC_FEATURE_ZLIB_MASK
;
2118 vs
->vnc_encoding
= enc
;
2120 case VNC_ENCODING_ZRLE
:
2121 vs
->features
|= VNC_FEATURE_ZRLE_MASK
;
2122 vs
->vnc_encoding
= enc
;
2124 case VNC_ENCODING_ZYWRLE
:
2125 vs
->features
|= VNC_FEATURE_ZYWRLE_MASK
;
2126 vs
->vnc_encoding
= enc
;
2128 case VNC_ENCODING_DESKTOPRESIZE
:
2129 vs
->features
|= VNC_FEATURE_RESIZE_MASK
;
2131 case VNC_ENCODING_POINTER_TYPE_CHANGE
:
2132 vs
->features
|= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK
;
2134 case VNC_ENCODING_RICH_CURSOR
:
2135 vs
->features
|= VNC_FEATURE_RICH_CURSOR_MASK
;
2137 case VNC_ENCODING_EXT_KEY_EVENT
:
2138 send_ext_key_event_ack(vs
);
2140 case VNC_ENCODING_AUDIO
:
2141 send_ext_audio_ack(vs
);
2143 case VNC_ENCODING_WMVi
:
2144 vs
->features
|= VNC_FEATURE_WMVI_MASK
;
2146 case VNC_ENCODING_LED_STATE
:
2147 vs
->features
|= VNC_FEATURE_LED_STATE_MASK
;
2149 case VNC_ENCODING_COMPRESSLEVEL0
... VNC_ENCODING_COMPRESSLEVEL0
+ 9:
2150 vs
->tight
.compression
= (enc
& 0x0F);
2152 case VNC_ENCODING_QUALITYLEVEL0
... VNC_ENCODING_QUALITYLEVEL0
+ 9:
2153 if (vs
->vd
->lossy
) {
2154 vs
->tight
.quality
= (enc
& 0x0F);
2158 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i
, enc
, enc
);
2162 vnc_desktop_resize(vs
);
2163 check_pointer_type_change(&vs
->mouse_mode_notifier
, NULL
);
2164 vnc_led_state_change(vs
);
2167 static void set_pixel_conversion(VncState
*vs
)
2169 pixman_format_code_t fmt
= qemu_pixman_get_format(&vs
->client_pf
);
2171 if (fmt
== VNC_SERVER_FB_FORMAT
) {
2172 vs
->write_pixels
= vnc_write_pixels_copy
;
2173 vnc_hextile_set_pixel_conversion(vs
, 0);
2175 vs
->write_pixels
= vnc_write_pixels_generic
;
2176 vnc_hextile_set_pixel_conversion(vs
, 1);
2180 static void set_pixel_format(VncState
*vs
,
2181 int bits_per_pixel
, int depth
,
2182 int big_endian_flag
, int true_color_flag
,
2183 int red_max
, int green_max
, int blue_max
,
2184 int red_shift
, int green_shift
, int blue_shift
)
2186 if (!true_color_flag
) {
2187 vnc_client_error(vs
);
2191 switch (bits_per_pixel
) {
2197 vnc_client_error(vs
);
2201 vs
->client_pf
.rmax
= red_max
? red_max
: 0xFF;
2202 vs
->client_pf
.rbits
= hweight_long(red_max
);
2203 vs
->client_pf
.rshift
= red_shift
;
2204 vs
->client_pf
.rmask
= red_max
<< red_shift
;
2205 vs
->client_pf
.gmax
= green_max
? green_max
: 0xFF;
2206 vs
->client_pf
.gbits
= hweight_long(green_max
);
2207 vs
->client_pf
.gshift
= green_shift
;
2208 vs
->client_pf
.gmask
= green_max
<< green_shift
;
2209 vs
->client_pf
.bmax
= blue_max
? blue_max
: 0xFF;
2210 vs
->client_pf
.bbits
= hweight_long(blue_max
);
2211 vs
->client_pf
.bshift
= blue_shift
;
2212 vs
->client_pf
.bmask
= blue_max
<< blue_shift
;
2213 vs
->client_pf
.bits_per_pixel
= bits_per_pixel
;
2214 vs
->client_pf
.bytes_per_pixel
= bits_per_pixel
/ 8;
2215 vs
->client_pf
.depth
= bits_per_pixel
== 32 ? 24 : bits_per_pixel
;
2216 vs
->client_be
= big_endian_flag
;
2218 set_pixel_conversion(vs
);
2220 graphic_hw_invalidate(vs
->vd
->dcl
.con
);
2221 graphic_hw_update(vs
->vd
->dcl
.con
);
2224 static void pixel_format_message (VncState
*vs
) {
2225 char pad
[3] = { 0, 0, 0 };
2227 vs
->client_pf
= qemu_default_pixelformat(32);
2229 vnc_write_u8(vs
, vs
->client_pf
.bits_per_pixel
); /* bits-per-pixel */
2230 vnc_write_u8(vs
, vs
->client_pf
.depth
); /* depth */
2232 #ifdef HOST_WORDS_BIGENDIAN
2233 vnc_write_u8(vs
, 1); /* big-endian-flag */
2235 vnc_write_u8(vs
, 0); /* big-endian-flag */
2237 vnc_write_u8(vs
, 1); /* true-color-flag */
2238 vnc_write_u16(vs
, vs
->client_pf
.rmax
); /* red-max */
2239 vnc_write_u16(vs
, vs
->client_pf
.gmax
); /* green-max */
2240 vnc_write_u16(vs
, vs
->client_pf
.bmax
); /* blue-max */
2241 vnc_write_u8(vs
, vs
->client_pf
.rshift
); /* red-shift */
2242 vnc_write_u8(vs
, vs
->client_pf
.gshift
); /* green-shift */
2243 vnc_write_u8(vs
, vs
->client_pf
.bshift
); /* blue-shift */
2244 vnc_write(vs
, pad
, 3); /* padding */
2246 vnc_hextile_set_pixel_conversion(vs
, 0);
2247 vs
->write_pixels
= vnc_write_pixels_copy
;
2250 static void vnc_colordepth(VncState
*vs
)
2252 if (vnc_has_feature(vs
, VNC_FEATURE_WMVI
)) {
2253 /* Sending a WMVi message to notify the client*/
2254 vnc_lock_output(vs
);
2255 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2256 vnc_write_u8(vs
, 0);
2257 vnc_write_u16(vs
, 1); /* number of rects */
2258 vnc_framebuffer_update(vs
, 0, 0,
2259 pixman_image_get_width(vs
->vd
->server
),
2260 pixman_image_get_height(vs
->vd
->server
),
2262 pixel_format_message(vs
);
2263 vnc_unlock_output(vs
);
2266 set_pixel_conversion(vs
);
2270 static int protocol_client_msg(VncState
*vs
, uint8_t *data
, size_t len
)
2274 VncDisplay
*vd
= vs
->vd
;
2277 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2281 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT
:
2285 set_pixel_format(vs
, read_u8(data
, 4), read_u8(data
, 5),
2286 read_u8(data
, 6), read_u8(data
, 7),
2287 read_u16(data
, 8), read_u16(data
, 10),
2288 read_u16(data
, 12), read_u8(data
, 14),
2289 read_u8(data
, 15), read_u8(data
, 16));
2291 case VNC_MSG_CLIENT_SET_ENCODINGS
:
2296 limit
= read_u16(data
, 2);
2298 return 4 + (limit
* 4);
2300 limit
= read_u16(data
, 2);
2302 for (i
= 0; i
< limit
; i
++) {
2303 int32_t val
= read_s32(data
, 4 + (i
* 4));
2304 memcpy(data
+ 4 + (i
* 4), &val
, sizeof(val
));
2307 set_encodings(vs
, (int32_t *)(data
+ 4), limit
);
2309 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST
:
2313 framebuffer_update_request(vs
,
2314 read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4),
2315 read_u16(data
, 6), read_u16(data
, 8));
2317 case VNC_MSG_CLIENT_KEY_EVENT
:
2321 key_event(vs
, read_u8(data
, 1), read_u32(data
, 4));
2323 case VNC_MSG_CLIENT_POINTER_EVENT
:
2327 pointer_event(vs
, read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4));
2329 case VNC_MSG_CLIENT_CUT_TEXT
:
2334 uint32_t dlen
= read_u32(data
, 4);
2335 if (dlen
> (1 << 20)) {
2336 error_report("vnc: client_cut_text msg payload has %u bytes"
2337 " which exceeds our limit of 1MB.", dlen
);
2338 vnc_client_error(vs
);
2346 client_cut_text(vs
, read_u32(data
, 4), data
+ 8);
2348 case VNC_MSG_CLIENT_QEMU
:
2352 switch (read_u8(data
, 1)) {
2353 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT
:
2357 ext_key_event(vs
, read_u16(data
, 2),
2358 read_u32(data
, 4), read_u32(data
, 8));
2360 case VNC_MSG_CLIENT_QEMU_AUDIO
:
2364 switch (read_u16 (data
, 2)) {
2365 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE
:
2368 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE
:
2371 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT
:
2374 switch (read_u8(data
, 4)) {
2375 case 0: vs
->as
.fmt
= AUD_FMT_U8
; break;
2376 case 1: vs
->as
.fmt
= AUD_FMT_S8
; break;
2377 case 2: vs
->as
.fmt
= AUD_FMT_U16
; break;
2378 case 3: vs
->as
.fmt
= AUD_FMT_S16
; break;
2379 case 4: vs
->as
.fmt
= AUD_FMT_U32
; break;
2380 case 5: vs
->as
.fmt
= AUD_FMT_S32
; break;
2382 VNC_DEBUG("Invalid audio format %d\n", read_u8(data
, 4));
2383 vnc_client_error(vs
);
2386 vs
->as
.nchannels
= read_u8(data
, 5);
2387 if (vs
->as
.nchannels
!= 1 && vs
->as
.nchannels
!= 2) {
2388 VNC_DEBUG("Invalid audio channel coount %d\n",
2390 vnc_client_error(vs
);
2393 vs
->as
.freq
= read_u32(data
, 6);
2396 VNC_DEBUG("Invalid audio message %d\n", read_u8(data
, 4));
2397 vnc_client_error(vs
);
2403 VNC_DEBUG("Msg: %d\n", read_u16(data
, 0));
2404 vnc_client_error(vs
);
2409 VNC_DEBUG("Msg: %d\n", data
[0]);
2410 vnc_client_error(vs
);
2414 vnc_read_when(vs
, protocol_client_msg
, 1);
2418 static int protocol_client_init(VncState
*vs
, uint8_t *data
, size_t len
)
2424 mode
= data
[0] ? VNC_SHARE_MODE_SHARED
: VNC_SHARE_MODE_EXCLUSIVE
;
2425 switch (vs
->vd
->share_policy
) {
2426 case VNC_SHARE_POLICY_IGNORE
:
2428 * Ignore the shared flag. Nothing to do here.
2430 * Doesn't conform to the rfb spec but is traditional qemu
2431 * behavior, thus left here as option for compatibility
2435 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
:
2437 * Policy: Allow clients ask for exclusive access.
2439 * Implementation: When a client asks for exclusive access,
2440 * disconnect all others. Shared connects are allowed as long
2441 * as no exclusive connection exists.
2443 * This is how the rfb spec suggests to handle the shared flag.
2445 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2447 QTAILQ_FOREACH(client
, &vs
->vd
->clients
, next
) {
2451 if (client
->share_mode
!= VNC_SHARE_MODE_EXCLUSIVE
&&
2452 client
->share_mode
!= VNC_SHARE_MODE_SHARED
) {
2455 vnc_disconnect_start(client
);
2458 if (mode
== VNC_SHARE_MODE_SHARED
) {
2459 if (vs
->vd
->num_exclusive
> 0) {
2460 vnc_disconnect_start(vs
);
2465 case VNC_SHARE_POLICY_FORCE_SHARED
:
2467 * Policy: Shared connects only.
2468 * Implementation: Disallow clients asking for exclusive access.
2470 * Useful for shared desktop sessions where you don't want
2471 * someone forgetting to say -shared when running the vnc
2472 * client disconnect everybody else.
2474 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2475 vnc_disconnect_start(vs
);
2480 vnc_set_share_mode(vs
, mode
);
2482 if (vs
->vd
->num_shared
> vs
->vd
->connections_limit
) {
2483 vnc_disconnect_start(vs
);
2487 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
2488 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
2489 vnc_write_u16(vs
, vs
->client_width
);
2490 vnc_write_u16(vs
, vs
->client_height
);
2492 pixel_format_message(vs
);
2495 size
= snprintf(buf
, sizeof(buf
), "QEMU (%s)", qemu_name
);
2497 size
= snprintf(buf
, sizeof(buf
), "QEMU");
2499 vnc_write_u32(vs
, size
);
2500 vnc_write(vs
, buf
, size
);
2503 vnc_client_cache_auth(vs
);
2504 vnc_qmp_event(vs
, QAPI_EVENT_VNC_INITIALIZED
);
2506 vnc_read_when(vs
, protocol_client_msg
, 1);
2511 void start_client_init(VncState
*vs
)
2513 vnc_read_when(vs
, protocol_client_init
, 1);
2516 static void make_challenge(VncState
*vs
)
2520 srand(time(NULL
)+getpid()+getpid()*987654+rand());
2522 for (i
= 0 ; i
< sizeof(vs
->challenge
) ; i
++)
2523 vs
->challenge
[i
] = (int) (256.0*rand()/(RAND_MAX
+1.0));
2526 static int protocol_client_auth_vnc(VncState
*vs
, uint8_t *data
, size_t len
)
2528 unsigned char response
[VNC_AUTH_CHALLENGE_SIZE
];
2530 unsigned char key
[8];
2531 time_t now
= time(NULL
);
2532 QCryptoCipher
*cipher
= NULL
;
2535 if (!vs
->vd
->password
) {
2536 VNC_DEBUG("No password configured on server");
2539 if (vs
->vd
->expires
< now
) {
2540 VNC_DEBUG("Password is expired");
2544 memcpy(response
, vs
->challenge
, VNC_AUTH_CHALLENGE_SIZE
);
2546 /* Calculate the expected challenge response */
2547 pwlen
= strlen(vs
->vd
->password
);
2548 for (i
=0; i
<sizeof(key
); i
++)
2549 key
[i
] = i
<pwlen
? vs
->vd
->password
[i
] : 0;
2551 cipher
= qcrypto_cipher_new(
2552 QCRYPTO_CIPHER_ALG_DES_RFB
,
2553 QCRYPTO_CIPHER_MODE_ECB
,
2554 key
, G_N_ELEMENTS(key
),
2557 VNC_DEBUG("Cannot initialize cipher %s",
2558 error_get_pretty(err
));
2563 if (qcrypto_cipher_encrypt(cipher
,
2566 VNC_AUTH_CHALLENGE_SIZE
,
2568 VNC_DEBUG("Cannot encrypt challenge %s",
2569 error_get_pretty(err
));
2574 /* Compare expected vs actual challenge response */
2575 if (memcmp(response
, data
, VNC_AUTH_CHALLENGE_SIZE
) != 0) {
2576 VNC_DEBUG("Client challenge response did not match\n");
2579 VNC_DEBUG("Accepting VNC challenge response\n");
2580 vnc_write_u32(vs
, 0); /* Accept auth */
2583 start_client_init(vs
);
2586 qcrypto_cipher_free(cipher
);
2590 vnc_write_u32(vs
, 1); /* Reject auth */
2591 if (vs
->minor
>= 8) {
2592 static const char err
[] = "Authentication failed";
2593 vnc_write_u32(vs
, sizeof(err
));
2594 vnc_write(vs
, err
, sizeof(err
));
2597 vnc_client_error(vs
);
2598 qcrypto_cipher_free(cipher
);
2602 void start_auth_vnc(VncState
*vs
)
2605 /* Send client a 'random' challenge */
2606 vnc_write(vs
, vs
->challenge
, sizeof(vs
->challenge
));
2609 vnc_read_when(vs
, protocol_client_auth_vnc
, sizeof(vs
->challenge
));
2613 static int protocol_client_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2615 /* We only advertise 1 auth scheme at a time, so client
2616 * must pick the one we sent. Verify this */
2617 if (data
[0] != vs
->auth
) { /* Reject auth */
2618 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data
[0]);
2619 vnc_write_u32(vs
, 1);
2620 if (vs
->minor
>= 8) {
2621 static const char err
[] = "Authentication failed";
2622 vnc_write_u32(vs
, sizeof(err
));
2623 vnc_write(vs
, err
, sizeof(err
));
2625 vnc_client_error(vs
);
2626 } else { /* Accept requested auth */
2627 VNC_DEBUG("Client requested auth %d\n", (int)data
[0]);
2630 VNC_DEBUG("Accept auth none\n");
2631 if (vs
->minor
>= 8) {
2632 vnc_write_u32(vs
, 0); /* Accept auth completion */
2635 start_client_init(vs
);
2639 VNC_DEBUG("Start VNC auth\n");
2643 case VNC_AUTH_VENCRYPT
:
2644 VNC_DEBUG("Accept VeNCrypt auth\n");
2645 start_auth_vencrypt(vs
);
2648 #ifdef CONFIG_VNC_SASL
2650 VNC_DEBUG("Accept SASL auth\n");
2651 start_auth_sasl(vs
);
2653 #endif /* CONFIG_VNC_SASL */
2655 default: /* Should not be possible, but just in case */
2656 VNC_DEBUG("Reject auth %d server code bug\n", vs
->auth
);
2657 vnc_write_u8(vs
, 1);
2658 if (vs
->minor
>= 8) {
2659 static const char err
[] = "Authentication failed";
2660 vnc_write_u32(vs
, sizeof(err
));
2661 vnc_write(vs
, err
, sizeof(err
));
2663 vnc_client_error(vs
);
2669 static int protocol_version(VncState
*vs
, uint8_t *version
, size_t len
)
2673 memcpy(local
, version
, 12);
2676 if (sscanf(local
, "RFB %03d.%03d\n", &vs
->major
, &vs
->minor
) != 2) {
2677 VNC_DEBUG("Malformed protocol version %s\n", local
);
2678 vnc_client_error(vs
);
2681 VNC_DEBUG("Client request protocol version %d.%d\n", vs
->major
, vs
->minor
);
2682 if (vs
->major
!= 3 ||
2688 VNC_DEBUG("Unsupported client version\n");
2689 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2691 vnc_client_error(vs
);
2694 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2695 * as equivalent to v3.3 by servers
2697 if (vs
->minor
== 4 || vs
->minor
== 5)
2700 if (vs
->minor
== 3) {
2701 if (vs
->auth
== VNC_AUTH_NONE
) {
2702 VNC_DEBUG("Tell client auth none\n");
2703 vnc_write_u32(vs
, vs
->auth
);
2705 start_client_init(vs
);
2706 } else if (vs
->auth
== VNC_AUTH_VNC
) {
2707 VNC_DEBUG("Tell client VNC auth\n");
2708 vnc_write_u32(vs
, vs
->auth
);
2712 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs
->auth
);
2713 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2715 vnc_client_error(vs
);
2718 VNC_DEBUG("Telling client we support auth %d\n", vs
->auth
);
2719 vnc_write_u8(vs
, 1); /* num auth */
2720 vnc_write_u8(vs
, vs
->auth
);
2721 vnc_read_when(vs
, protocol_client_auth
, 1);
2728 static VncRectStat
*vnc_stat_rect(VncDisplay
*vd
, int x
, int y
)
2730 struct VncSurface
*vs
= &vd
->guest
;
2732 return &vs
->stats
[y
/ VNC_STAT_RECT
][x
/ VNC_STAT_RECT
];
2735 void vnc_sent_lossy_rect(VncState
*vs
, int x
, int y
, int w
, int h
)
2739 w
= (x
+ w
) / VNC_STAT_RECT
;
2740 h
= (y
+ h
) / VNC_STAT_RECT
;
2744 for (j
= y
; j
<= h
; j
++) {
2745 for (i
= x
; i
<= w
; i
++) {
2746 vs
->lossy_rect
[j
][i
] = 1;
2751 static int vnc_refresh_lossy_rect(VncDisplay
*vd
, int x
, int y
)
2754 int sty
= y
/ VNC_STAT_RECT
;
2755 int stx
= x
/ VNC_STAT_RECT
;
2758 y
= y
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2759 x
= x
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2761 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2764 /* kernel send buffers are full -> refresh later */
2765 if (vs
->output
.offset
) {
2769 if (!vs
->lossy_rect
[sty
][stx
]) {
2773 vs
->lossy_rect
[sty
][stx
] = 0;
2774 for (j
= 0; j
< VNC_STAT_RECT
; ++j
) {
2775 bitmap_set(vs
->dirty
[y
+ j
],
2776 x
/ VNC_DIRTY_PIXELS_PER_BIT
,
2777 VNC_STAT_RECT
/ VNC_DIRTY_PIXELS_PER_BIT
);
2785 static int vnc_update_stats(VncDisplay
*vd
, struct timeval
* tv
)
2787 int width
= pixman_image_get_width(vd
->guest
.fb
);
2788 int height
= pixman_image_get_height(vd
->guest
.fb
);
2793 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2794 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2795 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2797 rect
->updated
= false;
2801 qemu_timersub(tv
, &VNC_REFRESH_STATS
, &res
);
2803 if (timercmp(&vd
->guest
.last_freq_check
, &res
, >)) {
2806 vd
->guest
.last_freq_check
= *tv
;
2808 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2809 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2810 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2811 int count
= ARRAY_SIZE(rect
->times
);
2812 struct timeval min
, max
;
2814 if (!timerisset(&rect
->times
[count
- 1])) {
2818 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2819 qemu_timersub(tv
, &max
, &res
);
2821 if (timercmp(&res
, &VNC_REFRESH_LOSSY
, >)) {
2823 has_dirty
+= vnc_refresh_lossy_rect(vd
, x
, y
);
2824 memset(rect
->times
, 0, sizeof (rect
->times
));
2828 min
= rect
->times
[rect
->idx
];
2829 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2830 qemu_timersub(&max
, &min
, &res
);
2832 rect
->freq
= res
.tv_sec
+ res
.tv_usec
/ 1000000.;
2833 rect
->freq
/= count
;
2834 rect
->freq
= 1. / rect
->freq
;
2840 double vnc_update_freq(VncState
*vs
, int x
, int y
, int w
, int h
)
2846 x
= (x
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2847 y
= (y
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2849 for (j
= y
; j
<= y
+ h
; j
+= VNC_STAT_RECT
) {
2850 for (i
= x
; i
<= x
+ w
; i
+= VNC_STAT_RECT
) {
2851 total
+= vnc_stat_rect(vs
->vd
, i
, j
)->freq
;
2863 static void vnc_rect_updated(VncDisplay
*vd
, int x
, int y
, struct timeval
* tv
)
2867 rect
= vnc_stat_rect(vd
, x
, y
);
2868 if (rect
->updated
) {
2871 rect
->times
[rect
->idx
] = *tv
;
2872 rect
->idx
= (rect
->idx
+ 1) % ARRAY_SIZE(rect
->times
);
2873 rect
->updated
= true;
2876 static int vnc_refresh_server_surface(VncDisplay
*vd
)
2878 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2879 pixman_image_get_width(vd
->server
));
2880 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2881 pixman_image_get_height(vd
->server
));
2882 int cmp_bytes
, server_stride
, line_bytes
, guest_ll
, guest_stride
, y
= 0;
2883 uint8_t *guest_row0
= NULL
, *server_row0
;
2886 pixman_image_t
*tmpbuf
= NULL
;
2888 struct timeval tv
= { 0, 0 };
2890 if (!vd
->non_adaptive
) {
2891 gettimeofday(&tv
, NULL
);
2892 has_dirty
= vnc_update_stats(vd
, &tv
);
2896 * Walk through the guest dirty map.
2897 * Check and copy modified bits from guest to server surface.
2898 * Update server dirty map.
2900 server_row0
= (uint8_t *)pixman_image_get_data(vd
->server
);
2901 server_stride
= guest_stride
= guest_ll
=
2902 pixman_image_get_stride(vd
->server
);
2903 cmp_bytes
= MIN(VNC_DIRTY_PIXELS_PER_BIT
* VNC_SERVER_FB_BYTES
,
2905 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2906 int width
= pixman_image_get_width(vd
->server
);
2907 tmpbuf
= qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT
, width
);
2910 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd
->guest
.fb
));
2911 guest_row0
= (uint8_t *)pixman_image_get_data(vd
->guest
.fb
);
2912 guest_stride
= pixman_image_get_stride(vd
->guest
.fb
);
2913 guest_ll
= pixman_image_get_width(vd
->guest
.fb
) * ((guest_bpp
+ 7) / 8);
2915 line_bytes
= MIN(server_stride
, guest_ll
);
2919 uint8_t *guest_ptr
, *server_ptr
;
2920 unsigned long offset
= find_next_bit((unsigned long *) &vd
->guest
.dirty
,
2921 height
* VNC_DIRTY_BPL(&vd
->guest
),
2922 y
* VNC_DIRTY_BPL(&vd
->guest
));
2923 if (offset
== height
* VNC_DIRTY_BPL(&vd
->guest
)) {
2924 /* no more dirty bits */
2927 y
= offset
/ VNC_DIRTY_BPL(&vd
->guest
);
2928 x
= offset
% VNC_DIRTY_BPL(&vd
->guest
);
2930 server_ptr
= server_row0
+ y
* server_stride
+ x
* cmp_bytes
;
2932 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2933 qemu_pixman_linebuf_fill(tmpbuf
, vd
->guest
.fb
, width
, 0, y
);
2934 guest_ptr
= (uint8_t *)pixman_image_get_data(tmpbuf
);
2936 guest_ptr
= guest_row0
+ y
* guest_stride
;
2938 guest_ptr
+= x
* cmp_bytes
;
2940 for (; x
< DIV_ROUND_UP(width
, VNC_DIRTY_PIXELS_PER_BIT
);
2941 x
++, guest_ptr
+= cmp_bytes
, server_ptr
+= cmp_bytes
) {
2942 int _cmp_bytes
= cmp_bytes
;
2943 if (!test_and_clear_bit(x
, vd
->guest
.dirty
[y
])) {
2946 if ((x
+ 1) * cmp_bytes
> line_bytes
) {
2947 _cmp_bytes
= line_bytes
- x
* cmp_bytes
;
2949 assert(_cmp_bytes
>= 0);
2950 if (memcmp(server_ptr
, guest_ptr
, _cmp_bytes
) == 0) {
2953 memcpy(server_ptr
, guest_ptr
, _cmp_bytes
);
2954 if (!vd
->non_adaptive
) {
2955 vnc_rect_updated(vd
, x
* VNC_DIRTY_PIXELS_PER_BIT
,
2958 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2959 set_bit(x
, vs
->dirty
[y
]);
2966 qemu_pixman_image_unref(tmpbuf
);
2970 static void vnc_refresh(DisplayChangeListener
*dcl
)
2972 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
2974 int has_dirty
, rects
= 0;
2976 if (QTAILQ_EMPTY(&vd
->clients
)) {
2977 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_MAX
);
2981 graphic_hw_update(vd
->dcl
.con
);
2983 if (vnc_trylock_display(vd
)) {
2984 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2988 has_dirty
= vnc_refresh_server_surface(vd
);
2989 vnc_unlock_display(vd
);
2991 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
2992 rects
+= vnc_update_client(vs
, has_dirty
, false);
2993 /* vs might be free()ed here */
2996 if (has_dirty
&& rects
) {
2997 vd
->dcl
.update_interval
/= 2;
2998 if (vd
->dcl
.update_interval
< VNC_REFRESH_INTERVAL_BASE
) {
2999 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_BASE
;
3002 vd
->dcl
.update_interval
+= VNC_REFRESH_INTERVAL_INC
;
3003 if (vd
->dcl
.update_interval
> VNC_REFRESH_INTERVAL_MAX
) {
3004 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_MAX
;
3009 static void vnc_connect(VncDisplay
*vd
, int csock
,
3010 bool skipauth
, bool websocket
)
3012 VncState
*vs
= g_new0(VncState
, 1);
3018 buffer_init(&vs
->input
, "vnc-input/%d", csock
);
3019 buffer_init(&vs
->output
, "vnc-output/%d", csock
);
3020 buffer_init(&vs
->ws_input
, "vnc-ws_input/%d", csock
);
3021 buffer_init(&vs
->ws_output
, "vnc-ws_output/%d", csock
);
3022 buffer_init(&vs
->jobs_buffer
, "vnc-jobs_buffer/%d", csock
);
3024 buffer_init(&vs
->tight
.tight
, "vnc-tight/%d", csock
);
3025 buffer_init(&vs
->tight
.zlib
, "vnc-tight-zlib/%d", csock
);
3026 buffer_init(&vs
->tight
.gradient
, "vnc-tight-gradient/%d", csock
);
3027 #ifdef CONFIG_VNC_JPEG
3028 buffer_init(&vs
->tight
.jpeg
, "vnc-tight-jpeg/%d", csock
);
3030 #ifdef CONFIG_VNC_PNG
3031 buffer_init(&vs
->tight
.png
, "vnc-tight-png/%d", csock
);
3033 buffer_init(&vs
->zlib
.zlib
, "vnc-zlib/%d", csock
);
3034 buffer_init(&vs
->zrle
.zrle
, "vnc-zrle/%d", csock
);
3035 buffer_init(&vs
->zrle
.fb
, "vnc-zrle-fb/%d", csock
);
3036 buffer_init(&vs
->zrle
.zlib
, "vnc-zrle-zlib/%d", csock
);
3039 vs
->auth
= VNC_AUTH_NONE
;
3040 vs
->subauth
= VNC_AUTH_INVALID
;
3043 vs
->auth
= vd
->ws_auth
;
3044 vs
->subauth
= VNC_AUTH_INVALID
;
3046 vs
->auth
= vd
->auth
;
3047 vs
->subauth
= vd
->subauth
;
3050 VNC_DEBUG("Client sock=%d ws=%d auth=%d subauth=%d\n",
3051 csock
, websocket
, vs
->auth
, vs
->subauth
);
3053 vs
->lossy_rect
= g_malloc0(VNC_STAT_ROWS
* sizeof (*vs
->lossy_rect
));
3054 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
3055 vs
->lossy_rect
[i
] = g_new0(uint8_t, VNC_STAT_COLS
);
3058 VNC_DEBUG("New client on socket %d\n", csock
);
3059 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
3060 qemu_set_nonblock(vs
->csock
);
3064 qemu_set_fd_handler(vs
->csock
, vncws_tls_handshake_io
, NULL
, vs
);
3066 qemu_set_fd_handler(vs
->csock
, vncws_handshake_read
, NULL
, vs
);
3070 qemu_set_fd_handler(vs
->csock
, vnc_client_read
, NULL
, vs
);
3073 vnc_client_cache_addr(vs
);
3074 vnc_qmp_event(vs
, QAPI_EVENT_VNC_CONNECTED
);
3075 vnc_set_share_mode(vs
, VNC_SHARE_MODE_CONNECTING
);
3077 if (!vs
->websocket
) {
3081 if (vd
->num_connecting
> vd
->connections_limit
) {
3082 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
3083 if (vs
->share_mode
== VNC_SHARE_MODE_CONNECTING
) {
3084 vnc_disconnect_start(vs
);
3091 void vnc_init_state(VncState
*vs
)
3093 vs
->initialized
= true;
3094 VncDisplay
*vd
= vs
->vd
;
3095 bool first_client
= QTAILQ_EMPTY(&vd
->clients
);
3100 vs
->as
.freq
= 44100;
3101 vs
->as
.nchannels
= 2;
3102 vs
->as
.fmt
= AUD_FMT_S16
;
3103 vs
->as
.endianness
= 0;
3105 qemu_mutex_init(&vs
->output_mutex
);
3106 vs
->bh
= qemu_bh_new(vnc_jobs_bh
, vs
);
3108 QTAILQ_INSERT_TAIL(&vd
->clients
, vs
, next
);
3110 vnc_update_server_surface(vd
);
3113 graphic_hw_update(vd
->dcl
.con
);
3115 vnc_write(vs
, "RFB 003.008\n", 12);
3117 vnc_read_when(vs
, protocol_version
, 12);
3119 if (vs
->vd
->lock_key_sync
)
3120 vs
->led
= qemu_add_led_event_handler(kbd_leds
, vs
);
3122 vs
->mouse_mode_notifier
.notify
= check_pointer_type_change
;
3123 qemu_add_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
3125 /* vs might be free()ed here */
3128 static void vnc_listen_read(void *opaque
, bool websocket
)
3130 VncDisplay
*vs
= opaque
;
3131 struct sockaddr_in addr
;
3132 socklen_t addrlen
= sizeof(addr
);
3136 graphic_hw_update(vs
->dcl
.con
);
3138 csock
= qemu_accept(vs
->lwebsock
, (struct sockaddr
*)&addr
, &addrlen
);
3140 csock
= qemu_accept(vs
->lsock
, (struct sockaddr
*)&addr
, &addrlen
);
3144 socket_set_nodelay(csock
);
3145 vnc_connect(vs
, csock
, false, websocket
);
3149 static void vnc_listen_regular_read(void *opaque
)
3151 vnc_listen_read(opaque
, false);
3154 static void vnc_listen_websocket_read(void *opaque
)
3156 vnc_listen_read(opaque
, true);
3159 static const DisplayChangeListenerOps dcl_ops
= {
3161 .dpy_refresh
= vnc_refresh
,
3162 .dpy_gfx_copy
= vnc_dpy_copy
,
3163 .dpy_gfx_update
= vnc_dpy_update
,
3164 .dpy_gfx_switch
= vnc_dpy_switch
,
3165 .dpy_gfx_check_format
= qemu_pixman_check_format
,
3166 .dpy_mouse_set
= vnc_mouse_set
,
3167 .dpy_cursor_define
= vnc_dpy_cursor_define
,
3170 void vnc_display_init(const char *id
)
3174 if (vnc_display_find(id
) != NULL
) {
3177 vs
= g_malloc0(sizeof(*vs
));
3179 vs
->id
= strdup(id
);
3180 QTAILQ_INSERT_TAIL(&vnc_displays
, vs
, next
);
3185 QTAILQ_INIT(&vs
->clients
);
3186 vs
->expires
= TIME_MAX
;
3188 if (keyboard_layout
) {
3189 trace_vnc_key_map_init(keyboard_layout
);
3190 vs
->kbd_layout
= init_keyboard_layout(name2keysym
, keyboard_layout
);
3192 vs
->kbd_layout
= init_keyboard_layout(name2keysym
, "en-us");
3195 if (!vs
->kbd_layout
)
3198 qemu_mutex_init(&vs
->mutex
);
3199 vnc_start_worker_thread();
3201 vs
->dcl
.ops
= &dcl_ops
;
3202 register_displaychangelistener(&vs
->dcl
);
3206 static void vnc_display_close(VncDisplay
*vs
)
3210 vs
->enabled
= false;
3211 vs
->is_unix
= false;
3212 if (vs
->lsock
!= -1) {
3213 qemu_set_fd_handler(vs
->lsock
, NULL
, NULL
, NULL
);
3217 vs
->ws_enabled
= false;
3218 if (vs
->lwebsock
!= -1) {
3219 qemu_set_fd_handler(vs
->lwebsock
, NULL
, NULL
, NULL
);
3220 close(vs
->lwebsock
);
3223 vs
->auth
= VNC_AUTH_INVALID
;
3224 vs
->subauth
= VNC_AUTH_INVALID
;
3226 object_unparent(OBJECT(vs
->tlscreds
));
3228 g_free(vs
->tlsaclname
);
3229 vs
->tlsaclname
= NULL
;
3232 int vnc_display_password(const char *id
, const char *password
)
3234 VncDisplay
*vs
= vnc_display_find(id
);
3239 if (vs
->auth
== VNC_AUTH_NONE
) {
3240 error_printf_unless_qmp("If you want use passwords please enable "
3241 "password auth using '-vnc ${dpy},password'.");
3245 g_free(vs
->password
);
3246 vs
->password
= g_strdup(password
);
3251 int vnc_display_pw_expire(const char *id
, time_t expires
)
3253 VncDisplay
*vs
= vnc_display_find(id
);
3259 vs
->expires
= expires
;
3263 char *vnc_display_local_addr(const char *id
)
3265 VncDisplay
*vs
= vnc_display_find(id
);
3268 return vnc_socket_local_addr("%s:%s", vs
->lsock
);
3271 static QemuOptsList qemu_vnc_opts
= {
3273 .head
= QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts
.head
),
3274 .implied_opt_name
= "vnc",
3278 .type
= QEMU_OPT_STRING
,
3280 .name
= "websocket",
3281 .type
= QEMU_OPT_STRING
,
3283 .name
= "tls-creds",
3284 .type
= QEMU_OPT_STRING
,
3286 /* Deprecated in favour of tls-creds */
3288 .type
= QEMU_OPT_STRING
,
3291 .type
= QEMU_OPT_STRING
,
3294 .type
= QEMU_OPT_STRING
,
3297 .type
= QEMU_OPT_NUMBER
,
3299 .name
= "connections",
3300 .type
= QEMU_OPT_NUMBER
,
3303 .type
= QEMU_OPT_NUMBER
,
3306 .type
= QEMU_OPT_BOOL
,
3309 .type
= QEMU_OPT_BOOL
,
3312 .type
= QEMU_OPT_BOOL
,
3315 .type
= QEMU_OPT_BOOL
,
3317 .name
= "lock-key-sync",
3318 .type
= QEMU_OPT_BOOL
,
3321 .type
= QEMU_OPT_BOOL
,
3323 /* Deprecated in favour of tls-creds */
3325 .type
= QEMU_OPT_BOOL
,
3327 /* Deprecated in favour of tls-creds */
3328 .name
= "x509verify",
3329 .type
= QEMU_OPT_STRING
,
3332 .type
= QEMU_OPT_BOOL
,
3335 .type
= QEMU_OPT_BOOL
,
3337 .name
= "non-adaptive",
3338 .type
= QEMU_OPT_BOOL
,
3340 { /* end of list */ }
3346 vnc_display_setup_auth(VncDisplay
*vs
,
3353 * We have a choice of 3 authentication options
3359 * The channel can be run in 2 modes
3364 * And TLS can use 2 types of credentials
3369 * We thus have 9 possible logical combinations
3374 * 4. tls + anon + none
3375 * 5. tls + anon + vnc
3376 * 6. tls + anon + sasl
3377 * 7. tls + x509 + none
3378 * 8. tls + x509 + vnc
3379 * 9. tls + x509 + sasl
3381 * These need to be mapped into the VNC auth schemes
3382 * in an appropriate manner. In regular VNC, all the
3383 * TLS options get mapped into VNC_AUTH_VENCRYPT
3386 * In websockets, the https:// protocol already provides
3387 * TLS support, so there is no need to make use of the
3388 * VeNCrypt extension. Furthermore, websockets browser
3389 * clients could not use VeNCrypt even if they wanted to,
3390 * as they cannot control when the TLS handshake takes
3391 * place. Thus there is no option but to rely on https://,
3392 * meaning combinations 4->6 and 7->9 will be mapped to
3393 * VNC auth schemes in the same way as combos 1->3.
3395 * Regardless of fact that we have a different mapping to
3396 * VNC auth mechs for plain VNC vs websockets VNC, the end
3397 * result has the same security characteristics.
3401 vs
->auth
= VNC_AUTH_VENCRYPT
;
3405 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3406 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3407 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3408 vs
->subauth
= VNC_AUTH_VENCRYPT_X509VNC
;
3409 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3410 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3411 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3412 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSVNC
;
3415 "Unsupported TLS cred type %s",
3416 object_get_typename(OBJECT(vs
->tlscreds
)));
3420 VNC_DEBUG("Initializing VNC server with password auth\n");
3421 vs
->auth
= VNC_AUTH_VNC
;
3422 vs
->subauth
= VNC_AUTH_INVALID
;
3425 vs
->ws_auth
= VNC_AUTH_VNC
;
3427 vs
->ws_auth
= VNC_AUTH_INVALID
;
3431 vs
->auth
= VNC_AUTH_VENCRYPT
;
3435 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3436 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3437 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3438 vs
->subauth
= VNC_AUTH_VENCRYPT_X509SASL
;
3439 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3440 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3441 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3442 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSSASL
;
3445 "Unsupported TLS cred type %s",
3446 object_get_typename(OBJECT(vs
->tlscreds
)));
3450 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3451 vs
->auth
= VNC_AUTH_SASL
;
3452 vs
->subauth
= VNC_AUTH_INVALID
;
3455 vs
->ws_auth
= VNC_AUTH_SASL
;
3457 vs
->ws_auth
= VNC_AUTH_INVALID
;
3461 vs
->auth
= VNC_AUTH_VENCRYPT
;
3465 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3466 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3467 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3468 vs
->subauth
= VNC_AUTH_VENCRYPT_X509NONE
;
3469 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3470 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3471 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3472 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSNONE
;
3475 "Unsupported TLS cred type %s",
3476 object_get_typename(OBJECT(vs
->tlscreds
)));
3480 VNC_DEBUG("Initializing VNC server with no auth\n");
3481 vs
->auth
= VNC_AUTH_NONE
;
3482 vs
->subauth
= VNC_AUTH_INVALID
;
3485 vs
->ws_auth
= VNC_AUTH_NONE
;
3487 vs
->ws_auth
= VNC_AUTH_INVALID
;
3495 * Handle back compat with old CLI syntax by creating some
3496 * suitable QCryptoTLSCreds objects
3498 static QCryptoTLSCreds
*
3499 vnc_display_create_creds(bool x509
,
3505 gchar
*credsid
= g_strdup_printf("tlsvnc%s", id
);
3506 Object
*parent
= object_get_objects_root();
3511 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509
,
3515 "endpoint", "server",
3517 "verify-peer", x509verify
? "yes" : "no",
3520 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON
,
3524 "endpoint", "server",
3531 error_propagate(errp
, err
);
3535 return QCRYPTO_TLS_CREDS(creds
);
3539 void vnc_display_open(const char *id
, Error
**errp
)
3541 VncDisplay
*vs
= vnc_display_find(id
);
3542 QemuOpts
*opts
= qemu_opts_find(&qemu_vnc_opts
, id
);
3543 SocketAddress
*saddr
= NULL
, *wsaddr
= NULL
;
3544 const char *share
, *device_id
;
3546 bool password
= false;
3547 bool reverse
= false;
3552 #ifdef CONFIG_VNC_SASL
3556 int lock_key_sync
= 1;
3559 error_setg(errp
, "VNC display not active");
3562 vnc_display_close(vs
);
3567 vnc
= qemu_opt_get(opts
, "vnc");
3568 if (!vnc
|| strcmp(vnc
, "none") == 0) {
3572 h
= strrchr(vnc
, ':');
3574 size_t hlen
= h
- vnc
;
3576 const char *websocket
= qemu_opt_get(opts
, "websocket");
3577 int to
= qemu_opt_get_number(opts
, "to", 0);
3578 bool has_ipv4
= qemu_opt_get_bool(opts
, "ipv4", false);
3579 bool has_ipv6
= qemu_opt_get_bool(opts
, "ipv6", false);
3581 saddr
= g_new0(SocketAddress
, 1);
3583 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1
)) {
3585 "SHA1 hash support is required for websockets");
3589 wsaddr
= g_new0(SocketAddress
, 1);
3590 vs
->ws_enabled
= true;
3593 if (strncmp(vnc
, "unix:", 5) == 0) {
3594 saddr
->type
= SOCKET_ADDRESS_KIND_UNIX
;
3595 saddr
->u
.q_unix
= g_new0(UnixSocketAddress
, 1);
3596 saddr
->u
.q_unix
->path
= g_strdup(vnc
+ 5);
3598 if (vs
->ws_enabled
) {
3599 error_setg(errp
, "UNIX sockets not supported with websock");
3603 unsigned long long baseport
;
3604 saddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3605 saddr
->u
.inet
= g_new0(InetSocketAddress
, 1);
3606 if (vnc
[0] == '[' && vnc
[hlen
- 1] == ']') {
3607 saddr
->u
.inet
->host
= g_strndup(vnc
+ 1, hlen
- 2);
3609 saddr
->u
.inet
->host
= g_strndup(vnc
, hlen
);
3611 if (parse_uint_full(h
+ 1, &baseport
, 10) < 0) {
3612 error_setg(errp
, "can't convert to a number: %s", h
+ 1);
3615 if (baseport
> 65535 ||
3616 baseport
+ 5900 > 65535) {
3617 error_setg(errp
, "port %s out of range", h
+ 1);
3620 saddr
->u
.inet
->port
= g_strdup_printf(
3621 "%d", (int)baseport
+ 5900);
3624 saddr
->u
.inet
->has_to
= true;
3625 saddr
->u
.inet
->to
= to
+ 5900;
3627 saddr
->u
.inet
->ipv4
= saddr
->u
.inet
->has_ipv4
= has_ipv4
;
3628 saddr
->u
.inet
->ipv6
= saddr
->u
.inet
->has_ipv6
= has_ipv6
;
3630 if (vs
->ws_enabled
) {
3631 wsaddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3632 wsaddr
->u
.inet
= g_new0(InetSocketAddress
, 1);
3633 wsaddr
->u
.inet
->host
= g_strdup(saddr
->u
.inet
->host
);
3634 wsaddr
->u
.inet
->port
= g_strdup(websocket
);
3637 wsaddr
->u
.inet
->has_to
= true;
3638 wsaddr
->u
.inet
->to
= to
;
3640 wsaddr
->u
.inet
->ipv4
= wsaddr
->u
.inet
->has_ipv4
= has_ipv4
;
3641 wsaddr
->u
.inet
->ipv6
= wsaddr
->u
.inet
->has_ipv6
= has_ipv6
;
3645 error_setg(errp
, "no vnc port specified");
3649 password
= qemu_opt_get_bool(opts
, "password", false);
3651 if (fips_get_state()) {
3653 "VNC password auth disabled due to FIPS mode, "
3654 "consider using the VeNCrypt or SASL authentication "
3655 "methods as an alternative");
3658 if (!qcrypto_cipher_supports(
3659 QCRYPTO_CIPHER_ALG_DES_RFB
)) {
3661 "Cipher backend does not support DES RFB algorithm");
3666 reverse
= qemu_opt_get_bool(opts
, "reverse", false);
3667 lock_key_sync
= qemu_opt_get_bool(opts
, "lock-key-sync", true);
3668 sasl
= qemu_opt_get_bool(opts
, "sasl", false);
3669 #ifndef CONFIG_VNC_SASL
3671 error_setg(errp
, "VNC SASL auth requires cyrus-sasl support");
3674 #endif /* CONFIG_VNC_SASL */
3675 credid
= qemu_opt_get(opts
, "tls-creds");
3678 if (qemu_opt_get(opts
, "tls") ||
3679 qemu_opt_get(opts
, "x509") ||
3680 qemu_opt_get(opts
, "x509verify")) {
3682 "'credid' parameter is mutually exclusive with "
3683 "'tls', 'x509' and 'x509verify' parameters");
3687 creds
= object_resolve_path_component(
3688 object_get_objects_root(), credid
);
3690 error_setg(errp
, "No TLS credentials with id '%s'",
3694 vs
->tlscreds
= (QCryptoTLSCreds
*)
3695 object_dynamic_cast(creds
,
3696 TYPE_QCRYPTO_TLS_CREDS
);
3697 if (!vs
->tlscreds
) {
3698 error_setg(errp
, "Object with id '%s' is not TLS credentials",
3702 object_ref(OBJECT(vs
->tlscreds
));
3704 if (vs
->tlscreds
->endpoint
!= QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
) {
3706 "Expecting TLS credentials with a server endpoint");
3711 bool tls
= false, x509
= false, x509verify
= false;
3712 tls
= qemu_opt_get_bool(opts
, "tls", false);
3714 path
= qemu_opt_get(opts
, "x509");
3719 path
= qemu_opt_get(opts
, "x509verify");
3725 vs
->tlscreds
= vnc_display_create_creds(x509
,
3730 if (!vs
->tlscreds
) {
3735 acl
= qemu_opt_get_bool(opts
, "acl", false);
3737 share
= qemu_opt_get(opts
, "share");
3739 if (strcmp(share
, "ignore") == 0) {
3740 vs
->share_policy
= VNC_SHARE_POLICY_IGNORE
;
3741 } else if (strcmp(share
, "allow-exclusive") == 0) {
3742 vs
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3743 } else if (strcmp(share
, "force-shared") == 0) {
3744 vs
->share_policy
= VNC_SHARE_POLICY_FORCE_SHARED
;
3746 error_setg(errp
, "unknown vnc share= option");
3750 vs
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3752 vs
->connections_limit
= qemu_opt_get_number(opts
, "connections", 32);
3754 #ifdef CONFIG_VNC_JPEG
3755 vs
->lossy
= qemu_opt_get_bool(opts
, "lossy", false);
3757 vs
->non_adaptive
= qemu_opt_get_bool(opts
, "non-adaptive", false);
3758 /* adaptive updates are only used with tight encoding and
3759 * if lossy updates are enabled so we can disable all the
3760 * calculations otherwise */
3762 vs
->non_adaptive
= true;
3766 if (strcmp(vs
->id
, "default") == 0) {
3767 vs
->tlsaclname
= g_strdup("vnc.x509dname");
3769 vs
->tlsaclname
= g_strdup_printf("vnc.%s.x509dname", vs
->id
);
3771 qemu_acl_init(vs
->tlsaclname
);
3773 #ifdef CONFIG_VNC_SASL
3777 if (strcmp(vs
->id
, "default") == 0) {
3778 aclname
= g_strdup("vnc.username");
3780 aclname
= g_strdup_printf("vnc.%s.username", vs
->id
);
3782 vs
->sasl
.acl
= qemu_acl_init(aclname
);
3787 if (vnc_display_setup_auth(vs
, password
, sasl
, vs
->ws_enabled
, errp
) < 0) {
3791 #ifdef CONFIG_VNC_SASL
3792 if ((saslErr
= sasl_server_init(NULL
, "qemu")) != SASL_OK
) {
3793 error_setg(errp
, "Failed to initialize SASL auth: %s",
3794 sasl_errstring(saslErr
, NULL
, NULL
));
3798 vs
->lock_key_sync
= lock_key_sync
;
3800 device_id
= qemu_opt_get(opts
, "display");
3803 int head
= qemu_opt_get_number(opts
, "head", 0);
3805 dev
= qdev_find_recursive(sysbus_get_default(), device_id
);
3807 error_setg(errp
, "Device '%s' not found", device_id
);
3811 con
= qemu_console_lookup_by_device(dev
, head
);
3813 error_setg(errp
, "Device %s is not bound to a QemuConsole",
3821 if (con
!= vs
->dcl
.con
) {
3822 unregister_displaychangelistener(&vs
->dcl
);
3824 register_displaychangelistener(&vs
->dcl
);
3828 /* connect to viewer */
3832 if (vs
->ws_enabled
) {
3833 error_setg(errp
, "Cannot use websockets in reverse mode");
3836 csock
= socket_connect(saddr
, errp
, NULL
, NULL
);
3840 vs
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3841 vnc_connect(vs
, csock
, false, false);
3843 /* listen for connects */
3844 vs
->lsock
= socket_listen(saddr
, errp
);
3845 if (vs
->lsock
< 0) {
3848 vs
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3849 if (vs
->ws_enabled
) {
3850 vs
->lwebsock
= socket_listen(wsaddr
, errp
);
3851 if (vs
->lwebsock
< 0) {
3852 if (vs
->lsock
!= -1) {
3860 qemu_set_fd_handler(vs
->lsock
, vnc_listen_regular_read
, NULL
, vs
);
3861 if (vs
->ws_enabled
) {
3862 qemu_set_fd_handler(vs
->lwebsock
, vnc_listen_websocket_read
,
3867 qapi_free_SocketAddress(saddr
);
3868 qapi_free_SocketAddress(wsaddr
);
3872 qapi_free_SocketAddress(saddr
);
3873 qapi_free_SocketAddress(wsaddr
);
3874 vs
->enabled
= false;
3875 vs
->ws_enabled
= false;
3878 void vnc_display_add_client(const char *id
, int csock
, bool skipauth
)
3880 VncDisplay
*vs
= vnc_display_find(id
);
3885 vnc_connect(vs
, csock
, skipauth
, false);
3888 static void vnc_auto_assign_id(QemuOptsList
*olist
, QemuOpts
*opts
)
3893 id
= g_strdup("default");
3894 while (qemu_opts_find(olist
, id
)) {
3896 id
= g_strdup_printf("vnc%d", i
++);
3898 qemu_opts_set_id(opts
, id
);
3901 QemuOpts
*vnc_parse(const char *str
, Error
**errp
)
3903 QemuOptsList
*olist
= qemu_find_opts("vnc");
3904 QemuOpts
*opts
= qemu_opts_parse(olist
, str
, true, errp
);
3911 id
= qemu_opts_id(opts
);
3913 /* auto-assign id if not present */
3914 vnc_auto_assign_id(olist
, opts
);
3919 int vnc_init_func(void *opaque
, QemuOpts
*opts
, Error
**errp
)
3921 Error
*local_err
= NULL
;
3922 char *id
= (char *)qemu_opts_id(opts
);
3925 vnc_display_init(id
);
3926 vnc_display_open(id
, &local_err
);
3927 if (local_err
!= NULL
) {
3928 error_report("Failed to start VNC server: %s",
3929 error_get_pretty(local_err
));
3930 error_free(local_err
);
3936 static void vnc_register_config(void)
3938 qemu_add_opts(&qemu_vnc_opts
);
3940 machine_init(vnc_register_config
);