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 vd
->server
= pixman_image_create_bits(VNC_SERVER_FB_FORMAT
,
740 static void vnc_dpy_switch(DisplayChangeListener
*dcl
,
741 DisplaySurface
*surface
)
743 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
747 vnc_abort_display_jobs(vd
);
751 vnc_update_server_surface(vd
);
754 qemu_pixman_image_unref(vd
->guest
.fb
);
755 vd
->guest
.fb
= pixman_image_ref(surface
->image
);
756 vd
->guest
.format
= surface
->format
;
757 width
= vnc_width(vd
);
758 height
= vnc_height(vd
);
759 memset(vd
->guest
.dirty
, 0x00, sizeof(vd
->guest
.dirty
));
760 vnc_set_area_dirty(vd
->guest
.dirty
, vd
, 0, 0,
763 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
765 vnc_desktop_resize(vs
);
766 if (vs
->vd
->cursor
) {
767 vnc_cursor_define(vs
);
769 memset(vs
->dirty
, 0x00, sizeof(vs
->dirty
));
770 vnc_set_area_dirty(vs
->dirty
, vd
, 0, 0,
776 static void vnc_write_pixels_copy(VncState
*vs
,
777 void *pixels
, int size
)
779 vnc_write(vs
, pixels
, size
);
782 /* slowest but generic code. */
783 void vnc_convert_pixel(VncState
*vs
, uint8_t *buf
, uint32_t v
)
787 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
788 r
= (((v
& 0x00ff0000) >> 16) << vs
->client_pf
.rbits
) >> 8;
789 g
= (((v
& 0x0000ff00) >> 8) << vs
->client_pf
.gbits
) >> 8;
790 b
= (((v
& 0x000000ff) >> 0) << vs
->client_pf
.bbits
) >> 8;
792 # error need some bits here if you change VNC_SERVER_FB_FORMAT
794 v
= (r
<< vs
->client_pf
.rshift
) |
795 (g
<< vs
->client_pf
.gshift
) |
796 (b
<< vs
->client_pf
.bshift
);
797 switch (vs
->client_pf
.bytes_per_pixel
) {
827 static void vnc_write_pixels_generic(VncState
*vs
,
828 void *pixels1
, int size
)
832 if (VNC_SERVER_FB_BYTES
== 4) {
833 uint32_t *pixels
= pixels1
;
836 for (i
= 0; i
< n
; i
++) {
837 vnc_convert_pixel(vs
, buf
, pixels
[i
]);
838 vnc_write(vs
, buf
, vs
->client_pf
.bytes_per_pixel
);
843 int vnc_raw_send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
847 VncDisplay
*vd
= vs
->vd
;
849 row
= vnc_server_fb_ptr(vd
, x
, y
);
850 for (i
= 0; i
< h
; i
++) {
851 vs
->write_pixels(vs
, row
, w
* VNC_SERVER_FB_BYTES
);
852 row
+= vnc_server_fb_stride(vd
);
857 int vnc_send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
860 bool encode_raw
= false;
861 size_t saved_offs
= vs
->output
.offset
;
863 switch(vs
->vnc_encoding
) {
864 case VNC_ENCODING_ZLIB
:
865 n
= vnc_zlib_send_framebuffer_update(vs
, x
, y
, w
, h
);
867 case VNC_ENCODING_HEXTILE
:
868 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_HEXTILE
);
869 n
= vnc_hextile_send_framebuffer_update(vs
, x
, y
, w
, h
);
871 case VNC_ENCODING_TIGHT
:
872 n
= vnc_tight_send_framebuffer_update(vs
, x
, y
, w
, h
);
874 case VNC_ENCODING_TIGHT_PNG
:
875 n
= vnc_tight_png_send_framebuffer_update(vs
, x
, y
, w
, h
);
877 case VNC_ENCODING_ZRLE
:
878 n
= vnc_zrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
880 case VNC_ENCODING_ZYWRLE
:
881 n
= vnc_zywrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
888 /* If the client has the same pixel format as our internal buffer and
889 * a RAW encoding would need less space fall back to RAW encoding to
890 * save bandwidth and processing power in the client. */
891 if (!encode_raw
&& vs
->write_pixels
== vnc_write_pixels_copy
&&
892 12 + h
* w
* VNC_SERVER_FB_BYTES
<= (vs
->output
.offset
- saved_offs
)) {
893 vs
->output
.offset
= saved_offs
;
898 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_RAW
);
899 n
= vnc_raw_send_framebuffer_update(vs
, x
, y
, w
, h
);
905 static void vnc_copy(VncState
*vs
, int src_x
, int src_y
, int dst_x
, int dst_y
, int w
, int h
)
907 /* send bitblit op to the vnc client */
909 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
911 vnc_write_u16(vs
, 1); /* number of rects */
912 vnc_framebuffer_update(vs
, dst_x
, dst_y
, w
, h
, VNC_ENCODING_COPYRECT
);
913 vnc_write_u16(vs
, src_x
);
914 vnc_write_u16(vs
, src_y
);
915 vnc_unlock_output(vs
);
919 static void vnc_dpy_copy(DisplayChangeListener
*dcl
,
920 int src_x
, int src_y
,
921 int dst_x
, int dst_y
, int w
, int h
)
923 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
927 int i
, x
, y
, pitch
, inc
, w_lim
, s
;
930 vnc_refresh_server_surface(vd
);
931 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
932 if (vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
933 vs
->force_update
= 1;
934 vnc_update_client(vs
, 1, true);
935 /* vs might be free()ed here */
939 /* do bitblit op on the local surface too */
940 pitch
= vnc_server_fb_stride(vd
);
941 src_row
= vnc_server_fb_ptr(vd
, src_x
, src_y
);
942 dst_row
= vnc_server_fb_ptr(vd
, dst_x
, dst_y
);
947 src_row
+= pitch
* (h
-1);
948 dst_row
+= pitch
* (h
-1);
953 w_lim
= w
- (VNC_DIRTY_PIXELS_PER_BIT
- (dst_x
% VNC_DIRTY_PIXELS_PER_BIT
));
957 w_lim
= w
- (w_lim
% VNC_DIRTY_PIXELS_PER_BIT
);
959 for (i
= 0; i
< h
; i
++) {
960 for (x
= 0; x
<= w_lim
;
961 x
+= s
, src_row
+= cmp_bytes
, dst_row
+= cmp_bytes
) {
963 if ((s
= w
- w_lim
) == 0)
966 s
= (VNC_DIRTY_PIXELS_PER_BIT
-
967 (dst_x
% VNC_DIRTY_PIXELS_PER_BIT
));
970 s
= VNC_DIRTY_PIXELS_PER_BIT
;
972 cmp_bytes
= s
* VNC_SERVER_FB_BYTES
;
973 if (memcmp(src_row
, dst_row
, cmp_bytes
) == 0)
975 memmove(dst_row
, src_row
, cmp_bytes
);
976 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
977 if (!vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
978 set_bit(((x
+ dst_x
) / VNC_DIRTY_PIXELS_PER_BIT
),
983 src_row
+= pitch
- w
* VNC_SERVER_FB_BYTES
;
984 dst_row
+= pitch
- w
* VNC_SERVER_FB_BYTES
;
988 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
989 if (vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
990 vnc_copy(vs
, src_x
, src_y
, dst_x
, dst_y
, w
, h
);
995 static void vnc_mouse_set(DisplayChangeListener
*dcl
,
996 int x
, int y
, int visible
)
998 /* can we ask the client(s) to move the pointer ??? */
1001 static int vnc_cursor_define(VncState
*vs
)
1003 QEMUCursor
*c
= vs
->vd
->cursor
;
1006 if (vnc_has_feature(vs
, VNC_FEATURE_RICH_CURSOR
)) {
1007 vnc_lock_output(vs
);
1008 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1009 vnc_write_u8(vs
, 0); /* padding */
1010 vnc_write_u16(vs
, 1); /* # of rects */
1011 vnc_framebuffer_update(vs
, c
->hot_x
, c
->hot_y
, c
->width
, c
->height
,
1012 VNC_ENCODING_RICH_CURSOR
);
1013 isize
= c
->width
* c
->height
* vs
->client_pf
.bytes_per_pixel
;
1014 vnc_write_pixels_generic(vs
, c
->data
, isize
);
1015 vnc_write(vs
, vs
->vd
->cursor_mask
, vs
->vd
->cursor_msize
);
1016 vnc_unlock_output(vs
);
1022 static void vnc_dpy_cursor_define(DisplayChangeListener
*dcl
,
1025 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
1028 cursor_put(vd
->cursor
);
1029 g_free(vd
->cursor_mask
);
1032 cursor_get(vd
->cursor
);
1033 vd
->cursor_msize
= cursor_get_mono_bpl(c
) * c
->height
;
1034 vd
->cursor_mask
= g_malloc0(vd
->cursor_msize
);
1035 cursor_get_mono_mask(c
, 0, vd
->cursor_mask
);
1037 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
1038 vnc_cursor_define(vs
);
1042 static int find_and_clear_dirty_height(VncState
*vs
,
1043 int y
, int last_x
, int x
, int height
)
1047 for (h
= 1; h
< (height
- y
); h
++) {
1048 if (!test_bit(last_x
, vs
->dirty
[y
+ h
])) {
1051 bitmap_clear(vs
->dirty
[y
+ h
], last_x
, x
- last_x
);
1057 static int vnc_update_client(VncState
*vs
, int has_dirty
, bool sync
)
1059 vs
->has_dirty
+= has_dirty
;
1060 if (vs
->need_update
&& vs
->csock
!= -1) {
1061 VncDisplay
*vd
= vs
->vd
;
1067 if (vs
->output
.offset
&& !vs
->audio_cap
&& !vs
->force_update
)
1068 /* kernel send buffers are full -> drop frames to throttle */
1071 if (!vs
->has_dirty
&& !vs
->audio_cap
&& !vs
->force_update
)
1075 * Send screen updates to the vnc client using the server
1076 * surface and server dirty map. guest surface updates
1077 * happening in parallel don't disturb us, the next pass will
1078 * send them to the client.
1080 job
= vnc_job_new(vs
);
1082 height
= pixman_image_get_height(vd
->server
);
1083 width
= pixman_image_get_width(vd
->server
);
1089 unsigned long offset
= find_next_bit((unsigned long *) &vs
->dirty
,
1090 height
* VNC_DIRTY_BPL(vs
),
1091 y
* VNC_DIRTY_BPL(vs
));
1092 if (offset
== height
* VNC_DIRTY_BPL(vs
)) {
1093 /* no more dirty bits */
1096 y
= offset
/ VNC_DIRTY_BPL(vs
);
1097 x
= offset
% VNC_DIRTY_BPL(vs
);
1098 x2
= find_next_zero_bit((unsigned long *) &vs
->dirty
[y
],
1099 VNC_DIRTY_BPL(vs
), x
);
1100 bitmap_clear(vs
->dirty
[y
], x
, x2
- x
);
1101 h
= find_and_clear_dirty_height(vs
, y
, x
, x2
, height
);
1102 x2
= MIN(x2
, width
/ VNC_DIRTY_PIXELS_PER_BIT
);
1104 n
+= vnc_job_add_rect(job
, x
* VNC_DIRTY_PIXELS_PER_BIT
, y
,
1105 (x2
- x
) * VNC_DIRTY_PIXELS_PER_BIT
, h
);
1107 if (!x
&& x2
== width
/ VNC_DIRTY_PIXELS_PER_BIT
) {
1119 vs
->force_update
= 0;
1124 if (vs
->csock
== -1) {
1125 vnc_disconnect_finish(vs
);
1134 static void audio_capture_notify(void *opaque
, audcnotification_e cmd
)
1136 VncState
*vs
= opaque
;
1139 case AUD_CNOTIFY_DISABLE
:
1140 vnc_lock_output(vs
);
1141 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1142 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1143 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_END
);
1144 vnc_unlock_output(vs
);
1148 case AUD_CNOTIFY_ENABLE
:
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_BEGIN
);
1153 vnc_unlock_output(vs
);
1159 static void audio_capture_destroy(void *opaque
)
1163 static void audio_capture(void *opaque
, void *buf
, int size
)
1165 VncState
*vs
= opaque
;
1167 vnc_lock_output(vs
);
1168 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1169 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1170 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_DATA
);
1171 vnc_write_u32(vs
, size
);
1172 vnc_write(vs
, buf
, size
);
1173 vnc_unlock_output(vs
);
1177 static void audio_add(VncState
*vs
)
1179 struct audio_capture_ops ops
;
1181 if (vs
->audio_cap
) {
1182 error_report("audio already running");
1186 ops
.notify
= audio_capture_notify
;
1187 ops
.destroy
= audio_capture_destroy
;
1188 ops
.capture
= audio_capture
;
1190 vs
->audio_cap
= AUD_add_capture(&vs
->as
, &ops
, vs
);
1191 if (!vs
->audio_cap
) {
1192 error_report("Failed to add audio capture");
1196 static void audio_del(VncState
*vs
)
1198 if (vs
->audio_cap
) {
1199 AUD_del_capture(vs
->audio_cap
, vs
);
1200 vs
->audio_cap
= NULL
;
1204 static void vnc_disconnect_start(VncState
*vs
)
1206 if (vs
->csock
== -1)
1208 vnc_set_share_mode(vs
, VNC_SHARE_MODE_DISCONNECTED
);
1209 qemu_set_fd_handler(vs
->csock
, NULL
, NULL
, NULL
);
1210 closesocket(vs
->csock
);
1214 void vnc_disconnect_finish(VncState
*vs
)
1218 vnc_jobs_join(vs
); /* Wait encoding jobs */
1220 vnc_lock_output(vs
);
1221 vnc_qmp_event(vs
, QAPI_EVENT_VNC_DISCONNECTED
);
1223 buffer_free(&vs
->input
);
1224 buffer_free(&vs
->output
);
1225 buffer_free(&vs
->ws_input
);
1226 buffer_free(&vs
->ws_output
);
1228 qapi_free_VncClientInfo(vs
->info
);
1231 vnc_tight_clear(vs
);
1234 qcrypto_tls_session_free(vs
->tls
);
1235 #ifdef CONFIG_VNC_SASL
1236 vnc_sasl_client_cleanup(vs
);
1237 #endif /* CONFIG_VNC_SASL */
1239 vnc_release_modifiers(vs
);
1241 if (vs
->initialized
) {
1242 QTAILQ_REMOVE(&vs
->vd
->clients
, vs
, next
);
1243 qemu_remove_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
1246 if (vs
->vd
->lock_key_sync
)
1247 qemu_remove_led_event_handler(vs
->led
);
1248 vnc_unlock_output(vs
);
1250 qemu_mutex_destroy(&vs
->output_mutex
);
1251 if (vs
->bh
!= NULL
) {
1252 qemu_bh_delete(vs
->bh
);
1254 buffer_free(&vs
->jobs_buffer
);
1256 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
1257 g_free(vs
->lossy_rect
[i
]);
1259 g_free(vs
->lossy_rect
);
1263 ssize_t
vnc_client_io_error(VncState
*vs
, ssize_t ret
, int last_errno
)
1265 if (ret
== 0 || ret
== -1) {
1267 switch (last_errno
) {
1271 case WSAEWOULDBLOCK
:
1279 VNC_DEBUG("Closing down client sock: ret %zd, errno %d\n",
1280 ret
, ret
< 0 ? last_errno
: 0);
1281 vnc_disconnect_start(vs
);
1289 void vnc_client_error(VncState
*vs
)
1291 VNC_DEBUG("Closing down client sock: protocol error\n");
1292 vnc_disconnect_start(vs
);
1296 ssize_t
vnc_tls_pull(char *buf
, size_t len
, void *opaque
)
1298 VncState
*vs
= opaque
;
1302 ret
= qemu_recv(vs
->csock
, buf
, len
, 0);
1304 if (errno
== EINTR
) {
1313 ssize_t
vnc_tls_push(const char *buf
, size_t len
, void *opaque
)
1315 VncState
*vs
= opaque
;
1319 ret
= send(vs
->csock
, buf
, len
, 0);
1321 if (errno
== EINTR
) {
1331 * Called to write a chunk of data to the client socket. The data may
1332 * be the raw data, or may have already been encoded by SASL.
1333 * The data will be written either straight onto the socket, or
1334 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1336 * NB, it is theoretically possible to have 2 layers of encryption,
1337 * both SASL, and this TLS layer. It is highly unlikely in practice
1338 * though, since SASL encryption will typically be a no-op if TLS
1341 * Returns the number of bytes written, which may be less than
1342 * the requested 'datalen' if the socket would block. Returns
1343 * -1 on error, and disconnects the client socket.
1345 ssize_t
vnc_client_write_buf(VncState
*vs
, const uint8_t *data
, size_t datalen
)
1350 ret
= qcrypto_tls_session_write(vs
->tls
, (const char *)data
, datalen
);
1355 ret
= send(vs
->csock
, (const void *)data
, datalen
, 0);
1357 err
= socket_error();
1360 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data
, datalen
, ret
);
1361 return vnc_client_io_error(vs
, ret
, err
);
1366 * Called to write buffered data to the client socket, when not
1367 * using any SASL SSF encryption layers. Will write as much data
1368 * as possible without blocking. If all buffered data is written,
1369 * will switch the FD poll() handler back to read monitoring.
1371 * Returns the number of bytes written, which may be less than
1372 * the buffered output data if the socket would block. Returns
1373 * -1 on error, and disconnects the client socket.
1375 static ssize_t
vnc_client_write_plain(VncState
*vs
)
1379 #ifdef CONFIG_VNC_SASL
1380 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1381 vs
->output
.buffer
, vs
->output
.capacity
, vs
->output
.offset
,
1382 vs
->sasl
.waitWriteSSF
);
1384 if (vs
->sasl
.conn
&&
1386 vs
->sasl
.waitWriteSSF
) {
1387 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->sasl
.waitWriteSSF
);
1389 vs
->sasl
.waitWriteSSF
-= ret
;
1391 #endif /* CONFIG_VNC_SASL */
1392 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->output
.offset
);
1396 buffer_advance(&vs
->output
, ret
);
1398 if (vs
->output
.offset
== 0) {
1399 qemu_set_fd_handler(vs
->csock
, vnc_client_read
, NULL
, vs
);
1407 * First function called whenever there is data to be written to
1408 * the client socket. Will delegate actual work according to whether
1409 * SASL SSF layers are enabled (thus requiring encryption calls)
1411 static void vnc_client_write_locked(void *opaque
)
1413 VncState
*vs
= opaque
;
1415 #ifdef CONFIG_VNC_SASL
1416 if (vs
->sasl
.conn
&&
1418 !vs
->sasl
.waitWriteSSF
) {
1419 vnc_client_write_sasl(vs
);
1421 #endif /* CONFIG_VNC_SASL */
1423 if (vs
->encode_ws
) {
1424 vnc_client_write_ws(vs
);
1426 vnc_client_write_plain(vs
);
1431 void vnc_client_write(void *opaque
)
1433 VncState
*vs
= opaque
;
1435 vnc_lock_output(vs
);
1436 if (vs
->output
.offset
|| vs
->ws_output
.offset
) {
1437 vnc_client_write_locked(opaque
);
1438 } else if (vs
->csock
!= -1) {
1439 qemu_set_fd_handler(vs
->csock
, vnc_client_read
, NULL
, vs
);
1441 vnc_unlock_output(vs
);
1444 void vnc_read_when(VncState
*vs
, VncReadEvent
*func
, size_t expecting
)
1446 vs
->read_handler
= func
;
1447 vs
->read_handler_expect
= expecting
;
1452 * Called to read a chunk of data from the client socket. The data may
1453 * be the raw data, or may need to be further decoded by SASL.
1454 * The data will be read either straight from to the socket, or
1455 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1457 * NB, it is theoretically possible to have 2 layers of encryption,
1458 * both SASL, and this TLS layer. It is highly unlikely in practice
1459 * though, since SASL encryption will typically be a no-op if TLS
1462 * Returns the number of bytes read, which may be less than
1463 * the requested 'datalen' if the socket would block. Returns
1464 * -1 on error, and disconnects the client socket.
1466 ssize_t
vnc_client_read_buf(VncState
*vs
, uint8_t *data
, size_t datalen
)
1471 ret
= qcrypto_tls_session_read(vs
->tls
, (char *)data
, datalen
);
1476 ret
= qemu_recv(vs
->csock
, data
, datalen
, 0);
1478 err
= socket_error();
1481 VNC_DEBUG("Read wire %p %zd -> %ld\n", data
, datalen
, ret
);
1482 return vnc_client_io_error(vs
, ret
, err
);
1487 * Called to read data from the client socket to the input buffer,
1488 * when not using any SASL SSF encryption layers. Will read as much
1489 * data as possible without blocking.
1491 * Returns the number of bytes read. Returns -1 on error, and
1492 * disconnects the client socket.
1494 static ssize_t
vnc_client_read_plain(VncState
*vs
)
1497 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1498 vs
->input
.buffer
, vs
->input
.capacity
, vs
->input
.offset
);
1499 buffer_reserve(&vs
->input
, 4096);
1500 ret
= vnc_client_read_buf(vs
, buffer_end(&vs
->input
), 4096);
1503 vs
->input
.offset
+= ret
;
1507 static void vnc_jobs_bh(void *opaque
)
1509 VncState
*vs
= opaque
;
1511 vnc_jobs_consume_buffer(vs
);
1515 * First function called whenever there is more data to be read from
1516 * the client socket. Will delegate actual work according to whether
1517 * SASL SSF layers are enabled (thus requiring decryption calls)
1519 void vnc_client_read(void *opaque
)
1521 VncState
*vs
= opaque
;
1524 #ifdef CONFIG_VNC_SASL
1525 if (vs
->sasl
.conn
&& vs
->sasl
.runSSF
)
1526 ret
= vnc_client_read_sasl(vs
);
1528 #endif /* CONFIG_VNC_SASL */
1529 if (vs
->encode_ws
) {
1530 ret
= vnc_client_read_ws(vs
);
1532 vnc_disconnect_start(vs
);
1534 } else if (ret
== -2) {
1535 vnc_client_error(vs
);
1539 ret
= vnc_client_read_plain(vs
);
1542 if (vs
->csock
== -1)
1543 vnc_disconnect_finish(vs
);
1547 while (vs
->read_handler
&& vs
->input
.offset
>= vs
->read_handler_expect
) {
1548 size_t len
= vs
->read_handler_expect
;
1551 ret
= vs
->read_handler(vs
, vs
->input
.buffer
, len
);
1552 if (vs
->csock
== -1) {
1553 vnc_disconnect_finish(vs
);
1558 buffer_advance(&vs
->input
, len
);
1560 vs
->read_handler_expect
= ret
;
1565 void vnc_write(VncState
*vs
, const void *data
, size_t len
)
1567 buffer_reserve(&vs
->output
, len
);
1569 if (vs
->csock
!= -1 && buffer_empty(&vs
->output
)) {
1570 qemu_set_fd_handler(vs
->csock
, vnc_client_read
, vnc_client_write
, vs
);
1573 buffer_append(&vs
->output
, data
, len
);
1576 void vnc_write_s32(VncState
*vs
, int32_t value
)
1578 vnc_write_u32(vs
, *(uint32_t *)&value
);
1581 void vnc_write_u32(VncState
*vs
, uint32_t value
)
1585 buf
[0] = (value
>> 24) & 0xFF;
1586 buf
[1] = (value
>> 16) & 0xFF;
1587 buf
[2] = (value
>> 8) & 0xFF;
1588 buf
[3] = value
& 0xFF;
1590 vnc_write(vs
, buf
, 4);
1593 void vnc_write_u16(VncState
*vs
, uint16_t value
)
1597 buf
[0] = (value
>> 8) & 0xFF;
1598 buf
[1] = value
& 0xFF;
1600 vnc_write(vs
, buf
, 2);
1603 void vnc_write_u8(VncState
*vs
, uint8_t value
)
1605 vnc_write(vs
, (char *)&value
, 1);
1608 void vnc_flush(VncState
*vs
)
1610 vnc_lock_output(vs
);
1611 if (vs
->csock
!= -1 && (vs
->output
.offset
||
1612 vs
->ws_output
.offset
)) {
1613 vnc_client_write_locked(vs
);
1615 vnc_unlock_output(vs
);
1618 static uint8_t read_u8(uint8_t *data
, size_t offset
)
1620 return data
[offset
];
1623 static uint16_t read_u16(uint8_t *data
, size_t offset
)
1625 return ((data
[offset
] & 0xFF) << 8) | (data
[offset
+ 1] & 0xFF);
1628 static int32_t read_s32(uint8_t *data
, size_t offset
)
1630 return (int32_t)((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1631 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1634 uint32_t read_u32(uint8_t *data
, size_t offset
)
1636 return ((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1637 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1640 static void client_cut_text(VncState
*vs
, size_t len
, uint8_t *text
)
1644 static void check_pointer_type_change(Notifier
*notifier
, void *data
)
1646 VncState
*vs
= container_of(notifier
, VncState
, mouse_mode_notifier
);
1647 int absolute
= qemu_input_is_absolute();
1649 if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
) && vs
->absolute
!= absolute
) {
1650 vnc_lock_output(vs
);
1651 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1652 vnc_write_u8(vs
, 0);
1653 vnc_write_u16(vs
, 1);
1654 vnc_framebuffer_update(vs
, absolute
, 0,
1655 pixman_image_get_width(vs
->vd
->server
),
1656 pixman_image_get_height(vs
->vd
->server
),
1657 VNC_ENCODING_POINTER_TYPE_CHANGE
);
1658 vnc_unlock_output(vs
);
1661 vs
->absolute
= absolute
;
1664 static void pointer_event(VncState
*vs
, int button_mask
, int x
, int y
)
1666 static uint32_t bmap
[INPUT_BUTTON_MAX
] = {
1667 [INPUT_BUTTON_LEFT
] = 0x01,
1668 [INPUT_BUTTON_MIDDLE
] = 0x02,
1669 [INPUT_BUTTON_RIGHT
] = 0x04,
1670 [INPUT_BUTTON_WHEEL_UP
] = 0x08,
1671 [INPUT_BUTTON_WHEEL_DOWN
] = 0x10,
1673 QemuConsole
*con
= vs
->vd
->dcl
.con
;
1674 int width
= pixman_image_get_width(vs
->vd
->server
);
1675 int height
= pixman_image_get_height(vs
->vd
->server
);
1677 if (vs
->last_bmask
!= button_mask
) {
1678 qemu_input_update_buttons(con
, bmap
, vs
->last_bmask
, button_mask
);
1679 vs
->last_bmask
= button_mask
;
1683 qemu_input_queue_abs(con
, INPUT_AXIS_X
, x
, width
);
1684 qemu_input_queue_abs(con
, INPUT_AXIS_Y
, y
, height
);
1685 } else if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
)) {
1686 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- 0x7FFF);
1687 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- 0x7FFF);
1689 if (vs
->last_x
!= -1) {
1690 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- vs
->last_x
);
1691 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- vs
->last_y
);
1696 qemu_input_event_sync();
1699 static void reset_keys(VncState
*vs
)
1702 for(i
= 0; i
< 256; i
++) {
1703 if (vs
->modifiers_state
[i
]) {
1704 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, i
, false);
1705 vs
->modifiers_state
[i
] = 0;
1710 static void press_key(VncState
*vs
, int keysym
)
1712 int keycode
= keysym2scancode(vs
->vd
->kbd_layout
, keysym
) & SCANCODE_KEYMASK
;
1713 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, true);
1714 qemu_input_event_send_key_delay(0);
1715 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1716 qemu_input_event_send_key_delay(0);
1719 static int current_led_state(VncState
*vs
)
1723 if (vs
->modifiers_state
[0x46]) {
1724 ledstate
|= QEMU_SCROLL_LOCK_LED
;
1726 if (vs
->modifiers_state
[0x45]) {
1727 ledstate
|= QEMU_NUM_LOCK_LED
;
1729 if (vs
->modifiers_state
[0x3a]) {
1730 ledstate
|= QEMU_CAPS_LOCK_LED
;
1736 static void vnc_led_state_change(VncState
*vs
)
1740 if (!vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
)) {
1744 ledstate
= current_led_state(vs
);
1745 vnc_lock_output(vs
);
1746 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1747 vnc_write_u8(vs
, 0);
1748 vnc_write_u16(vs
, 1);
1749 vnc_framebuffer_update(vs
, 0, 0, 1, 1, VNC_ENCODING_LED_STATE
);
1750 vnc_write_u8(vs
, ledstate
);
1751 vnc_unlock_output(vs
);
1755 static void kbd_leds(void *opaque
, int ledstate
)
1757 VncState
*vs
= opaque
;
1759 bool has_changed
= (ledstate
!= current_led_state(vs
));
1761 trace_vnc_key_guest_leds((ledstate
& QEMU_CAPS_LOCK_LED
),
1762 (ledstate
& QEMU_NUM_LOCK_LED
),
1763 (ledstate
& QEMU_SCROLL_LOCK_LED
));
1765 caps
= ledstate
& QEMU_CAPS_LOCK_LED
? 1 : 0;
1766 num
= ledstate
& QEMU_NUM_LOCK_LED
? 1 : 0;
1767 scr
= ledstate
& QEMU_SCROLL_LOCK_LED
? 1 : 0;
1769 if (vs
->modifiers_state
[0x3a] != caps
) {
1770 vs
->modifiers_state
[0x3a] = caps
;
1772 if (vs
->modifiers_state
[0x45] != num
) {
1773 vs
->modifiers_state
[0x45] = num
;
1775 if (vs
->modifiers_state
[0x46] != scr
) {
1776 vs
->modifiers_state
[0x46] = scr
;
1779 /* Sending the current led state message to the client */
1781 vnc_led_state_change(vs
);
1785 static void do_key_event(VncState
*vs
, int down
, int keycode
, int sym
)
1787 /* QEMU console switch */
1789 case 0x2a: /* Left Shift */
1790 case 0x36: /* Right Shift */
1791 case 0x1d: /* Left CTRL */
1792 case 0x9d: /* Right CTRL */
1793 case 0x38: /* Left ALT */
1794 case 0xb8: /* Right ALT */
1796 vs
->modifiers_state
[keycode
] = 1;
1798 vs
->modifiers_state
[keycode
] = 0;
1800 case 0x02 ... 0x0a: /* '1' to '9' keys */
1801 if (vs
->vd
->dcl
.con
== NULL
&&
1802 down
&& vs
->modifiers_state
[0x1d] && vs
->modifiers_state
[0x38]) {
1803 /* Reset the modifiers sent to the current console */
1805 console_select(keycode
- 0x02);
1809 case 0x3a: /* CapsLock */
1810 case 0x45: /* NumLock */
1812 vs
->modifiers_state
[keycode
] ^= 1;
1816 /* Turn off the lock state sync logic if the client support the led
1819 if (down
&& vs
->vd
->lock_key_sync
&&
1820 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1821 keycode_is_keypad(vs
->vd
->kbd_layout
, keycode
)) {
1822 /* If the numlock state needs to change then simulate an additional
1823 keypress before sending this one. This will happen if the user
1824 toggles numlock away from the VNC window.
1826 if (keysym_is_numlock(vs
->vd
->kbd_layout
, sym
& 0xFFFF)) {
1827 if (!vs
->modifiers_state
[0x45]) {
1828 trace_vnc_key_sync_numlock(true);
1829 vs
->modifiers_state
[0x45] = 1;
1830 press_key(vs
, 0xff7f);
1833 if (vs
->modifiers_state
[0x45]) {
1834 trace_vnc_key_sync_numlock(false);
1835 vs
->modifiers_state
[0x45] = 0;
1836 press_key(vs
, 0xff7f);
1841 if (down
&& vs
->vd
->lock_key_sync
&&
1842 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1843 ((sym
>= 'A' && sym
<= 'Z') || (sym
>= 'a' && sym
<= 'z'))) {
1844 /* If the capslock state needs to change then simulate an additional
1845 keypress before sending this one. This will happen if the user
1846 toggles capslock away from the VNC window.
1848 int uppercase
= !!(sym
>= 'A' && sym
<= 'Z');
1849 int shift
= !!(vs
->modifiers_state
[0x2a] | vs
->modifiers_state
[0x36]);
1850 int capslock
= !!(vs
->modifiers_state
[0x3a]);
1852 if (uppercase
== shift
) {
1853 trace_vnc_key_sync_capslock(false);
1854 vs
->modifiers_state
[0x3a] = 0;
1855 press_key(vs
, 0xffe5);
1858 if (uppercase
!= shift
) {
1859 trace_vnc_key_sync_capslock(true);
1860 vs
->modifiers_state
[0x3a] = 1;
1861 press_key(vs
, 0xffe5);
1866 if (qemu_console_is_graphic(NULL
)) {
1867 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, down
);
1869 bool numlock
= vs
->modifiers_state
[0x45];
1870 bool control
= (vs
->modifiers_state
[0x1d] ||
1871 vs
->modifiers_state
[0x9d]);
1872 /* QEMU console emulation */
1875 case 0x2a: /* Left Shift */
1876 case 0x36: /* Right Shift */
1877 case 0x1d: /* Left CTRL */
1878 case 0x9d: /* Right CTRL */
1879 case 0x38: /* Left ALT */
1880 case 0xb8: /* Right ALT */
1883 kbd_put_keysym(QEMU_KEY_UP
);
1886 kbd_put_keysym(QEMU_KEY_DOWN
);
1889 kbd_put_keysym(QEMU_KEY_LEFT
);
1892 kbd_put_keysym(QEMU_KEY_RIGHT
);
1895 kbd_put_keysym(QEMU_KEY_DELETE
);
1898 kbd_put_keysym(QEMU_KEY_HOME
);
1901 kbd_put_keysym(QEMU_KEY_END
);
1904 kbd_put_keysym(QEMU_KEY_PAGEUP
);
1907 kbd_put_keysym(QEMU_KEY_PAGEDOWN
);
1911 kbd_put_keysym(numlock
? '7' : QEMU_KEY_HOME
);
1914 kbd_put_keysym(numlock
? '8' : QEMU_KEY_UP
);
1917 kbd_put_keysym(numlock
? '9' : QEMU_KEY_PAGEUP
);
1920 kbd_put_keysym(numlock
? '4' : QEMU_KEY_LEFT
);
1923 kbd_put_keysym('5');
1926 kbd_put_keysym(numlock
? '6' : QEMU_KEY_RIGHT
);
1929 kbd_put_keysym(numlock
? '1' : QEMU_KEY_END
);
1932 kbd_put_keysym(numlock
? '2' : QEMU_KEY_DOWN
);
1935 kbd_put_keysym(numlock
? '3' : QEMU_KEY_PAGEDOWN
);
1938 kbd_put_keysym('0');
1941 kbd_put_keysym(numlock
? '.' : QEMU_KEY_DELETE
);
1945 kbd_put_keysym('/');
1948 kbd_put_keysym('*');
1951 kbd_put_keysym('-');
1954 kbd_put_keysym('+');
1957 kbd_put_keysym('\n');
1962 kbd_put_keysym(sym
& 0x1f);
1964 kbd_put_keysym(sym
);
1972 static void vnc_release_modifiers(VncState
*vs
)
1974 static const int keycodes
[] = {
1975 /* shift, control, alt keys, both left & right */
1976 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1980 if (!qemu_console_is_graphic(NULL
)) {
1983 for (i
= 0; i
< ARRAY_SIZE(keycodes
); i
++) {
1984 keycode
= keycodes
[i
];
1985 if (!vs
->modifiers_state
[keycode
]) {
1988 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1992 static const char *code2name(int keycode
)
1994 return QKeyCode_lookup
[qemu_input_key_number_to_qcode(keycode
)];
1997 static void key_event(VncState
*vs
, int down
, uint32_t sym
)
2002 if (lsym
>= 'A' && lsym
<= 'Z' && qemu_console_is_graphic(NULL
)) {
2003 lsym
= lsym
- 'A' + 'a';
2006 keycode
= keysym2scancode(vs
->vd
->kbd_layout
, lsym
& 0xFFFF) & SCANCODE_KEYMASK
;
2007 trace_vnc_key_event_map(down
, sym
, keycode
, code2name(keycode
));
2008 do_key_event(vs
, down
, keycode
, sym
);
2011 static void ext_key_event(VncState
*vs
, int down
,
2012 uint32_t sym
, uint16_t keycode
)
2014 /* if the user specifies a keyboard layout, always use it */
2015 if (keyboard_layout
) {
2016 key_event(vs
, down
, sym
);
2018 trace_vnc_key_event_ext(down
, sym
, keycode
, code2name(keycode
));
2019 do_key_event(vs
, down
, keycode
, sym
);
2023 static void framebuffer_update_request(VncState
*vs
, int incremental
,
2024 int x
, int y
, int w
, int h
)
2026 vs
->need_update
= 1;
2032 vs
->force_update
= 1;
2033 vnc_set_area_dirty(vs
->dirty
, vs
->vd
, x
, y
, w
, h
);
2036 static void send_ext_key_event_ack(VncState
*vs
)
2038 vnc_lock_output(vs
);
2039 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2040 vnc_write_u8(vs
, 0);
2041 vnc_write_u16(vs
, 1);
2042 vnc_framebuffer_update(vs
, 0, 0,
2043 pixman_image_get_width(vs
->vd
->server
),
2044 pixman_image_get_height(vs
->vd
->server
),
2045 VNC_ENCODING_EXT_KEY_EVENT
);
2046 vnc_unlock_output(vs
);
2050 static void send_ext_audio_ack(VncState
*vs
)
2052 vnc_lock_output(vs
);
2053 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2054 vnc_write_u8(vs
, 0);
2055 vnc_write_u16(vs
, 1);
2056 vnc_framebuffer_update(vs
, 0, 0,
2057 pixman_image_get_width(vs
->vd
->server
),
2058 pixman_image_get_height(vs
->vd
->server
),
2059 VNC_ENCODING_AUDIO
);
2060 vnc_unlock_output(vs
);
2064 static void set_encodings(VncState
*vs
, int32_t *encodings
, size_t n_encodings
)
2067 unsigned int enc
= 0;
2070 vs
->vnc_encoding
= 0;
2071 vs
->tight
.compression
= 9;
2072 vs
->tight
.quality
= -1; /* Lossless by default */
2076 * Start from the end because the encodings are sent in order of preference.
2077 * This way the preferred encoding (first encoding defined in the array)
2078 * will be set at the end of the loop.
2080 for (i
= n_encodings
- 1; i
>= 0; i
--) {
2083 case VNC_ENCODING_RAW
:
2084 vs
->vnc_encoding
= enc
;
2086 case VNC_ENCODING_COPYRECT
:
2087 vs
->features
|= VNC_FEATURE_COPYRECT_MASK
;
2089 case VNC_ENCODING_HEXTILE
:
2090 vs
->features
|= VNC_FEATURE_HEXTILE_MASK
;
2091 vs
->vnc_encoding
= enc
;
2093 case VNC_ENCODING_TIGHT
:
2094 vs
->features
|= VNC_FEATURE_TIGHT_MASK
;
2095 vs
->vnc_encoding
= enc
;
2097 #ifdef CONFIG_VNC_PNG
2098 case VNC_ENCODING_TIGHT_PNG
:
2099 vs
->features
|= VNC_FEATURE_TIGHT_PNG_MASK
;
2100 vs
->vnc_encoding
= enc
;
2103 case VNC_ENCODING_ZLIB
:
2104 vs
->features
|= VNC_FEATURE_ZLIB_MASK
;
2105 vs
->vnc_encoding
= enc
;
2107 case VNC_ENCODING_ZRLE
:
2108 vs
->features
|= VNC_FEATURE_ZRLE_MASK
;
2109 vs
->vnc_encoding
= enc
;
2111 case VNC_ENCODING_ZYWRLE
:
2112 vs
->features
|= VNC_FEATURE_ZYWRLE_MASK
;
2113 vs
->vnc_encoding
= enc
;
2115 case VNC_ENCODING_DESKTOPRESIZE
:
2116 vs
->features
|= VNC_FEATURE_RESIZE_MASK
;
2118 case VNC_ENCODING_POINTER_TYPE_CHANGE
:
2119 vs
->features
|= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK
;
2121 case VNC_ENCODING_RICH_CURSOR
:
2122 vs
->features
|= VNC_FEATURE_RICH_CURSOR_MASK
;
2124 case VNC_ENCODING_EXT_KEY_EVENT
:
2125 send_ext_key_event_ack(vs
);
2127 case VNC_ENCODING_AUDIO
:
2128 send_ext_audio_ack(vs
);
2130 case VNC_ENCODING_WMVi
:
2131 vs
->features
|= VNC_FEATURE_WMVI_MASK
;
2133 case VNC_ENCODING_LED_STATE
:
2134 vs
->features
|= VNC_FEATURE_LED_STATE_MASK
;
2136 case VNC_ENCODING_COMPRESSLEVEL0
... VNC_ENCODING_COMPRESSLEVEL0
+ 9:
2137 vs
->tight
.compression
= (enc
& 0x0F);
2139 case VNC_ENCODING_QUALITYLEVEL0
... VNC_ENCODING_QUALITYLEVEL0
+ 9:
2140 if (vs
->vd
->lossy
) {
2141 vs
->tight
.quality
= (enc
& 0x0F);
2145 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i
, enc
, enc
);
2149 vnc_desktop_resize(vs
);
2150 check_pointer_type_change(&vs
->mouse_mode_notifier
, NULL
);
2151 vnc_led_state_change(vs
);
2154 static void set_pixel_conversion(VncState
*vs
)
2156 pixman_format_code_t fmt
= qemu_pixman_get_format(&vs
->client_pf
);
2158 if (fmt
== VNC_SERVER_FB_FORMAT
) {
2159 vs
->write_pixels
= vnc_write_pixels_copy
;
2160 vnc_hextile_set_pixel_conversion(vs
, 0);
2162 vs
->write_pixels
= vnc_write_pixels_generic
;
2163 vnc_hextile_set_pixel_conversion(vs
, 1);
2167 static void set_pixel_format(VncState
*vs
,
2168 int bits_per_pixel
, int depth
,
2169 int big_endian_flag
, int true_color_flag
,
2170 int red_max
, int green_max
, int blue_max
,
2171 int red_shift
, int green_shift
, int blue_shift
)
2173 if (!true_color_flag
) {
2174 vnc_client_error(vs
);
2178 switch (bits_per_pixel
) {
2184 vnc_client_error(vs
);
2188 vs
->client_pf
.rmax
= red_max
;
2189 vs
->client_pf
.rbits
= hweight_long(red_max
);
2190 vs
->client_pf
.rshift
= red_shift
;
2191 vs
->client_pf
.rmask
= red_max
<< red_shift
;
2192 vs
->client_pf
.gmax
= green_max
;
2193 vs
->client_pf
.gbits
= hweight_long(green_max
);
2194 vs
->client_pf
.gshift
= green_shift
;
2195 vs
->client_pf
.gmask
= green_max
<< green_shift
;
2196 vs
->client_pf
.bmax
= blue_max
;
2197 vs
->client_pf
.bbits
= hweight_long(blue_max
);
2198 vs
->client_pf
.bshift
= blue_shift
;
2199 vs
->client_pf
.bmask
= blue_max
<< blue_shift
;
2200 vs
->client_pf
.bits_per_pixel
= bits_per_pixel
;
2201 vs
->client_pf
.bytes_per_pixel
= bits_per_pixel
/ 8;
2202 vs
->client_pf
.depth
= bits_per_pixel
== 32 ? 24 : bits_per_pixel
;
2203 vs
->client_be
= big_endian_flag
;
2205 set_pixel_conversion(vs
);
2207 graphic_hw_invalidate(vs
->vd
->dcl
.con
);
2208 graphic_hw_update(vs
->vd
->dcl
.con
);
2211 static void pixel_format_message (VncState
*vs
) {
2212 char pad
[3] = { 0, 0, 0 };
2214 vs
->client_pf
= qemu_default_pixelformat(32);
2216 vnc_write_u8(vs
, vs
->client_pf
.bits_per_pixel
); /* bits-per-pixel */
2217 vnc_write_u8(vs
, vs
->client_pf
.depth
); /* depth */
2219 #ifdef HOST_WORDS_BIGENDIAN
2220 vnc_write_u8(vs
, 1); /* big-endian-flag */
2222 vnc_write_u8(vs
, 0); /* big-endian-flag */
2224 vnc_write_u8(vs
, 1); /* true-color-flag */
2225 vnc_write_u16(vs
, vs
->client_pf
.rmax
); /* red-max */
2226 vnc_write_u16(vs
, vs
->client_pf
.gmax
); /* green-max */
2227 vnc_write_u16(vs
, vs
->client_pf
.bmax
); /* blue-max */
2228 vnc_write_u8(vs
, vs
->client_pf
.rshift
); /* red-shift */
2229 vnc_write_u8(vs
, vs
->client_pf
.gshift
); /* green-shift */
2230 vnc_write_u8(vs
, vs
->client_pf
.bshift
); /* blue-shift */
2231 vnc_write(vs
, pad
, 3); /* padding */
2233 vnc_hextile_set_pixel_conversion(vs
, 0);
2234 vs
->write_pixels
= vnc_write_pixels_copy
;
2237 static void vnc_colordepth(VncState
*vs
)
2239 if (vnc_has_feature(vs
, VNC_FEATURE_WMVI
)) {
2240 /* Sending a WMVi message to notify the client*/
2241 vnc_lock_output(vs
);
2242 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2243 vnc_write_u8(vs
, 0);
2244 vnc_write_u16(vs
, 1); /* number of rects */
2245 vnc_framebuffer_update(vs
, 0, 0,
2246 pixman_image_get_width(vs
->vd
->server
),
2247 pixman_image_get_height(vs
->vd
->server
),
2249 pixel_format_message(vs
);
2250 vnc_unlock_output(vs
);
2253 set_pixel_conversion(vs
);
2257 static int protocol_client_msg(VncState
*vs
, uint8_t *data
, size_t len
)
2261 VncDisplay
*vd
= vs
->vd
;
2264 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2268 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT
:
2272 set_pixel_format(vs
, read_u8(data
, 4), read_u8(data
, 5),
2273 read_u8(data
, 6), read_u8(data
, 7),
2274 read_u16(data
, 8), read_u16(data
, 10),
2275 read_u16(data
, 12), read_u8(data
, 14),
2276 read_u8(data
, 15), read_u8(data
, 16));
2278 case VNC_MSG_CLIENT_SET_ENCODINGS
:
2283 limit
= read_u16(data
, 2);
2285 return 4 + (limit
* 4);
2287 limit
= read_u16(data
, 2);
2289 for (i
= 0; i
< limit
; i
++) {
2290 int32_t val
= read_s32(data
, 4 + (i
* 4));
2291 memcpy(data
+ 4 + (i
* 4), &val
, sizeof(val
));
2294 set_encodings(vs
, (int32_t *)(data
+ 4), limit
);
2296 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST
:
2300 framebuffer_update_request(vs
,
2301 read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4),
2302 read_u16(data
, 6), read_u16(data
, 8));
2304 case VNC_MSG_CLIENT_KEY_EVENT
:
2308 key_event(vs
, read_u8(data
, 1), read_u32(data
, 4));
2310 case VNC_MSG_CLIENT_POINTER_EVENT
:
2314 pointer_event(vs
, read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4));
2316 case VNC_MSG_CLIENT_CUT_TEXT
:
2321 uint32_t dlen
= read_u32(data
, 4);
2322 if (dlen
> (1 << 20)) {
2323 error_report("vnc: client_cut_text msg payload has %u bytes"
2324 " which exceeds our limit of 1MB.", dlen
);
2325 vnc_client_error(vs
);
2333 client_cut_text(vs
, read_u32(data
, 4), data
+ 8);
2335 case VNC_MSG_CLIENT_QEMU
:
2339 switch (read_u8(data
, 1)) {
2340 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT
:
2344 ext_key_event(vs
, read_u16(data
, 2),
2345 read_u32(data
, 4), read_u32(data
, 8));
2347 case VNC_MSG_CLIENT_QEMU_AUDIO
:
2351 switch (read_u16 (data
, 2)) {
2352 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE
:
2355 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE
:
2358 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT
:
2361 switch (read_u8(data
, 4)) {
2362 case 0: vs
->as
.fmt
= AUD_FMT_U8
; break;
2363 case 1: vs
->as
.fmt
= AUD_FMT_S8
; break;
2364 case 2: vs
->as
.fmt
= AUD_FMT_U16
; break;
2365 case 3: vs
->as
.fmt
= AUD_FMT_S16
; break;
2366 case 4: vs
->as
.fmt
= AUD_FMT_U32
; break;
2367 case 5: vs
->as
.fmt
= AUD_FMT_S32
; break;
2369 VNC_DEBUG("Invalid audio format %d\n", read_u8(data
, 4));
2370 vnc_client_error(vs
);
2373 vs
->as
.nchannels
= read_u8(data
, 5);
2374 if (vs
->as
.nchannels
!= 1 && vs
->as
.nchannels
!= 2) {
2375 VNC_DEBUG("Invalid audio channel coount %d\n",
2377 vnc_client_error(vs
);
2380 vs
->as
.freq
= read_u32(data
, 6);
2383 VNC_DEBUG("Invalid audio message %d\n", read_u8(data
, 4));
2384 vnc_client_error(vs
);
2390 VNC_DEBUG("Msg: %d\n", read_u16(data
, 0));
2391 vnc_client_error(vs
);
2396 VNC_DEBUG("Msg: %d\n", data
[0]);
2397 vnc_client_error(vs
);
2401 vnc_read_when(vs
, protocol_client_msg
, 1);
2405 static int protocol_client_init(VncState
*vs
, uint8_t *data
, size_t len
)
2411 mode
= data
[0] ? VNC_SHARE_MODE_SHARED
: VNC_SHARE_MODE_EXCLUSIVE
;
2412 switch (vs
->vd
->share_policy
) {
2413 case VNC_SHARE_POLICY_IGNORE
:
2415 * Ignore the shared flag. Nothing to do here.
2417 * Doesn't conform to the rfb spec but is traditional qemu
2418 * behavior, thus left here as option for compatibility
2422 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
:
2424 * Policy: Allow clients ask for exclusive access.
2426 * Implementation: When a client asks for exclusive access,
2427 * disconnect all others. Shared connects are allowed as long
2428 * as no exclusive connection exists.
2430 * This is how the rfb spec suggests to handle the shared flag.
2432 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2434 QTAILQ_FOREACH(client
, &vs
->vd
->clients
, next
) {
2438 if (client
->share_mode
!= VNC_SHARE_MODE_EXCLUSIVE
&&
2439 client
->share_mode
!= VNC_SHARE_MODE_SHARED
) {
2442 vnc_disconnect_start(client
);
2445 if (mode
== VNC_SHARE_MODE_SHARED
) {
2446 if (vs
->vd
->num_exclusive
> 0) {
2447 vnc_disconnect_start(vs
);
2452 case VNC_SHARE_POLICY_FORCE_SHARED
:
2454 * Policy: Shared connects only.
2455 * Implementation: Disallow clients asking for exclusive access.
2457 * Useful for shared desktop sessions where you don't want
2458 * someone forgetting to say -shared when running the vnc
2459 * client disconnect everybody else.
2461 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2462 vnc_disconnect_start(vs
);
2467 vnc_set_share_mode(vs
, mode
);
2469 if (vs
->vd
->num_shared
> vs
->vd
->connections_limit
) {
2470 vnc_disconnect_start(vs
);
2474 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
2475 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
2476 vnc_write_u16(vs
, vs
->client_width
);
2477 vnc_write_u16(vs
, vs
->client_height
);
2479 pixel_format_message(vs
);
2482 size
= snprintf(buf
, sizeof(buf
), "QEMU (%s)", qemu_name
);
2484 size
= snprintf(buf
, sizeof(buf
), "QEMU");
2486 vnc_write_u32(vs
, size
);
2487 vnc_write(vs
, buf
, size
);
2490 vnc_client_cache_auth(vs
);
2491 vnc_qmp_event(vs
, QAPI_EVENT_VNC_INITIALIZED
);
2493 vnc_read_when(vs
, protocol_client_msg
, 1);
2498 void start_client_init(VncState
*vs
)
2500 vnc_read_when(vs
, protocol_client_init
, 1);
2503 static void make_challenge(VncState
*vs
)
2507 srand(time(NULL
)+getpid()+getpid()*987654+rand());
2509 for (i
= 0 ; i
< sizeof(vs
->challenge
) ; i
++)
2510 vs
->challenge
[i
] = (int) (256.0*rand()/(RAND_MAX
+1.0));
2513 static int protocol_client_auth_vnc(VncState
*vs
, uint8_t *data
, size_t len
)
2515 unsigned char response
[VNC_AUTH_CHALLENGE_SIZE
];
2517 unsigned char key
[8];
2518 time_t now
= time(NULL
);
2519 QCryptoCipher
*cipher
= NULL
;
2522 if (!vs
->vd
->password
) {
2523 VNC_DEBUG("No password configured on server");
2526 if (vs
->vd
->expires
< now
) {
2527 VNC_DEBUG("Password is expired");
2531 memcpy(response
, vs
->challenge
, VNC_AUTH_CHALLENGE_SIZE
);
2533 /* Calculate the expected challenge response */
2534 pwlen
= strlen(vs
->vd
->password
);
2535 for (i
=0; i
<sizeof(key
); i
++)
2536 key
[i
] = i
<pwlen
? vs
->vd
->password
[i
] : 0;
2538 cipher
= qcrypto_cipher_new(
2539 QCRYPTO_CIPHER_ALG_DES_RFB
,
2540 QCRYPTO_CIPHER_MODE_ECB
,
2541 key
, G_N_ELEMENTS(key
),
2544 VNC_DEBUG("Cannot initialize cipher %s",
2545 error_get_pretty(err
));
2550 if (qcrypto_cipher_encrypt(cipher
,
2553 VNC_AUTH_CHALLENGE_SIZE
,
2555 VNC_DEBUG("Cannot encrypt challenge %s",
2556 error_get_pretty(err
));
2561 /* Compare expected vs actual challenge response */
2562 if (memcmp(response
, data
, VNC_AUTH_CHALLENGE_SIZE
) != 0) {
2563 VNC_DEBUG("Client challenge response did not match\n");
2566 VNC_DEBUG("Accepting VNC challenge response\n");
2567 vnc_write_u32(vs
, 0); /* Accept auth */
2570 start_client_init(vs
);
2573 qcrypto_cipher_free(cipher
);
2577 vnc_write_u32(vs
, 1); /* Reject auth */
2578 if (vs
->minor
>= 8) {
2579 static const char err
[] = "Authentication failed";
2580 vnc_write_u32(vs
, sizeof(err
));
2581 vnc_write(vs
, err
, sizeof(err
));
2584 vnc_client_error(vs
);
2585 qcrypto_cipher_free(cipher
);
2589 void start_auth_vnc(VncState
*vs
)
2592 /* Send client a 'random' challenge */
2593 vnc_write(vs
, vs
->challenge
, sizeof(vs
->challenge
));
2596 vnc_read_when(vs
, protocol_client_auth_vnc
, sizeof(vs
->challenge
));
2600 static int protocol_client_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2602 /* We only advertise 1 auth scheme at a time, so client
2603 * must pick the one we sent. Verify this */
2604 if (data
[0] != vs
->auth
) { /* Reject auth */
2605 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data
[0]);
2606 vnc_write_u32(vs
, 1);
2607 if (vs
->minor
>= 8) {
2608 static const char err
[] = "Authentication failed";
2609 vnc_write_u32(vs
, sizeof(err
));
2610 vnc_write(vs
, err
, sizeof(err
));
2612 vnc_client_error(vs
);
2613 } else { /* Accept requested auth */
2614 VNC_DEBUG("Client requested auth %d\n", (int)data
[0]);
2617 VNC_DEBUG("Accept auth none\n");
2618 if (vs
->minor
>= 8) {
2619 vnc_write_u32(vs
, 0); /* Accept auth completion */
2622 start_client_init(vs
);
2626 VNC_DEBUG("Start VNC auth\n");
2630 case VNC_AUTH_VENCRYPT
:
2631 VNC_DEBUG("Accept VeNCrypt auth\n");
2632 start_auth_vencrypt(vs
);
2635 #ifdef CONFIG_VNC_SASL
2637 VNC_DEBUG("Accept SASL auth\n");
2638 start_auth_sasl(vs
);
2640 #endif /* CONFIG_VNC_SASL */
2642 default: /* Should not be possible, but just in case */
2643 VNC_DEBUG("Reject auth %d server code bug\n", vs
->auth
);
2644 vnc_write_u8(vs
, 1);
2645 if (vs
->minor
>= 8) {
2646 static const char err
[] = "Authentication failed";
2647 vnc_write_u32(vs
, sizeof(err
));
2648 vnc_write(vs
, err
, sizeof(err
));
2650 vnc_client_error(vs
);
2656 static int protocol_version(VncState
*vs
, uint8_t *version
, size_t len
)
2660 memcpy(local
, version
, 12);
2663 if (sscanf(local
, "RFB %03d.%03d\n", &vs
->major
, &vs
->minor
) != 2) {
2664 VNC_DEBUG("Malformed protocol version %s\n", local
);
2665 vnc_client_error(vs
);
2668 VNC_DEBUG("Client request protocol version %d.%d\n", vs
->major
, vs
->minor
);
2669 if (vs
->major
!= 3 ||
2675 VNC_DEBUG("Unsupported client version\n");
2676 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2678 vnc_client_error(vs
);
2681 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2682 * as equivalent to v3.3 by servers
2684 if (vs
->minor
== 4 || vs
->minor
== 5)
2687 if (vs
->minor
== 3) {
2688 if (vs
->auth
== VNC_AUTH_NONE
) {
2689 VNC_DEBUG("Tell client auth none\n");
2690 vnc_write_u32(vs
, vs
->auth
);
2692 start_client_init(vs
);
2693 } else if (vs
->auth
== VNC_AUTH_VNC
) {
2694 VNC_DEBUG("Tell client VNC auth\n");
2695 vnc_write_u32(vs
, vs
->auth
);
2699 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs
->auth
);
2700 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2702 vnc_client_error(vs
);
2705 VNC_DEBUG("Telling client we support auth %d\n", vs
->auth
);
2706 vnc_write_u8(vs
, 1); /* num auth */
2707 vnc_write_u8(vs
, vs
->auth
);
2708 vnc_read_when(vs
, protocol_client_auth
, 1);
2715 static VncRectStat
*vnc_stat_rect(VncDisplay
*vd
, int x
, int y
)
2717 struct VncSurface
*vs
= &vd
->guest
;
2719 return &vs
->stats
[y
/ VNC_STAT_RECT
][x
/ VNC_STAT_RECT
];
2722 void vnc_sent_lossy_rect(VncState
*vs
, int x
, int y
, int w
, int h
)
2726 w
= (x
+ w
) / VNC_STAT_RECT
;
2727 h
= (y
+ h
) / VNC_STAT_RECT
;
2731 for (j
= y
; j
<= h
; j
++) {
2732 for (i
= x
; i
<= w
; i
++) {
2733 vs
->lossy_rect
[j
][i
] = 1;
2738 static int vnc_refresh_lossy_rect(VncDisplay
*vd
, int x
, int y
)
2741 int sty
= y
/ VNC_STAT_RECT
;
2742 int stx
= x
/ VNC_STAT_RECT
;
2745 y
= y
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2746 x
= x
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2748 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2751 /* kernel send buffers are full -> refresh later */
2752 if (vs
->output
.offset
) {
2756 if (!vs
->lossy_rect
[sty
][stx
]) {
2760 vs
->lossy_rect
[sty
][stx
] = 0;
2761 for (j
= 0; j
< VNC_STAT_RECT
; ++j
) {
2762 bitmap_set(vs
->dirty
[y
+ j
],
2763 x
/ VNC_DIRTY_PIXELS_PER_BIT
,
2764 VNC_STAT_RECT
/ VNC_DIRTY_PIXELS_PER_BIT
);
2772 static int vnc_update_stats(VncDisplay
*vd
, struct timeval
* tv
)
2774 int width
= pixman_image_get_width(vd
->guest
.fb
);
2775 int height
= pixman_image_get_height(vd
->guest
.fb
);
2780 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2781 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2782 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2784 rect
->updated
= false;
2788 qemu_timersub(tv
, &VNC_REFRESH_STATS
, &res
);
2790 if (timercmp(&vd
->guest
.last_freq_check
, &res
, >)) {
2793 vd
->guest
.last_freq_check
= *tv
;
2795 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2796 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2797 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2798 int count
= ARRAY_SIZE(rect
->times
);
2799 struct timeval min
, max
;
2801 if (!timerisset(&rect
->times
[count
- 1])) {
2805 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2806 qemu_timersub(tv
, &max
, &res
);
2808 if (timercmp(&res
, &VNC_REFRESH_LOSSY
, >)) {
2810 has_dirty
+= vnc_refresh_lossy_rect(vd
, x
, y
);
2811 memset(rect
->times
, 0, sizeof (rect
->times
));
2815 min
= rect
->times
[rect
->idx
];
2816 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2817 qemu_timersub(&max
, &min
, &res
);
2819 rect
->freq
= res
.tv_sec
+ res
.tv_usec
/ 1000000.;
2820 rect
->freq
/= count
;
2821 rect
->freq
= 1. / rect
->freq
;
2827 double vnc_update_freq(VncState
*vs
, int x
, int y
, int w
, int h
)
2833 x
= (x
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2834 y
= (y
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2836 for (j
= y
; j
<= y
+ h
; j
+= VNC_STAT_RECT
) {
2837 for (i
= x
; i
<= x
+ w
; i
+= VNC_STAT_RECT
) {
2838 total
+= vnc_stat_rect(vs
->vd
, i
, j
)->freq
;
2850 static void vnc_rect_updated(VncDisplay
*vd
, int x
, int y
, struct timeval
* tv
)
2854 rect
= vnc_stat_rect(vd
, x
, y
);
2855 if (rect
->updated
) {
2858 rect
->times
[rect
->idx
] = *tv
;
2859 rect
->idx
= (rect
->idx
+ 1) % ARRAY_SIZE(rect
->times
);
2860 rect
->updated
= true;
2863 static int vnc_refresh_server_surface(VncDisplay
*vd
)
2865 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2866 pixman_image_get_width(vd
->server
));
2867 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2868 pixman_image_get_height(vd
->server
));
2869 int cmp_bytes
, server_stride
, line_bytes
, guest_ll
, guest_stride
, y
= 0;
2870 uint8_t *guest_row0
= NULL
, *server_row0
;
2873 pixman_image_t
*tmpbuf
= NULL
;
2875 struct timeval tv
= { 0, 0 };
2877 if (!vd
->non_adaptive
) {
2878 gettimeofday(&tv
, NULL
);
2879 has_dirty
= vnc_update_stats(vd
, &tv
);
2883 * Walk through the guest dirty map.
2884 * Check and copy modified bits from guest to server surface.
2885 * Update server dirty map.
2887 server_row0
= (uint8_t *)pixman_image_get_data(vd
->server
);
2888 server_stride
= guest_stride
= guest_ll
=
2889 pixman_image_get_stride(vd
->server
);
2890 cmp_bytes
= MIN(VNC_DIRTY_PIXELS_PER_BIT
* VNC_SERVER_FB_BYTES
,
2892 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2893 int width
= pixman_image_get_width(vd
->server
);
2894 tmpbuf
= qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT
, width
);
2897 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd
->guest
.fb
));
2898 guest_row0
= (uint8_t *)pixman_image_get_data(vd
->guest
.fb
);
2899 guest_stride
= pixman_image_get_stride(vd
->guest
.fb
);
2900 guest_ll
= pixman_image_get_width(vd
->guest
.fb
) * ((guest_bpp
+ 7) / 8);
2902 line_bytes
= MIN(server_stride
, guest_ll
);
2906 uint8_t *guest_ptr
, *server_ptr
;
2907 unsigned long offset
= find_next_bit((unsigned long *) &vd
->guest
.dirty
,
2908 height
* VNC_DIRTY_BPL(&vd
->guest
),
2909 y
* VNC_DIRTY_BPL(&vd
->guest
));
2910 if (offset
== height
* VNC_DIRTY_BPL(&vd
->guest
)) {
2911 /* no more dirty bits */
2914 y
= offset
/ VNC_DIRTY_BPL(&vd
->guest
);
2915 x
= offset
% VNC_DIRTY_BPL(&vd
->guest
);
2917 server_ptr
= server_row0
+ y
* server_stride
+ x
* cmp_bytes
;
2919 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2920 qemu_pixman_linebuf_fill(tmpbuf
, vd
->guest
.fb
, width
, 0, y
);
2921 guest_ptr
= (uint8_t *)pixman_image_get_data(tmpbuf
);
2923 guest_ptr
= guest_row0
+ y
* guest_stride
;
2925 guest_ptr
+= x
* cmp_bytes
;
2927 for (; x
< DIV_ROUND_UP(width
, VNC_DIRTY_PIXELS_PER_BIT
);
2928 x
++, guest_ptr
+= cmp_bytes
, server_ptr
+= cmp_bytes
) {
2929 int _cmp_bytes
= cmp_bytes
;
2930 if (!test_and_clear_bit(x
, vd
->guest
.dirty
[y
])) {
2933 if ((x
+ 1) * cmp_bytes
> line_bytes
) {
2934 _cmp_bytes
= line_bytes
- x
* cmp_bytes
;
2936 assert(_cmp_bytes
>= 0);
2937 if (memcmp(server_ptr
, guest_ptr
, _cmp_bytes
) == 0) {
2940 memcpy(server_ptr
, guest_ptr
, _cmp_bytes
);
2941 if (!vd
->non_adaptive
) {
2942 vnc_rect_updated(vd
, x
* VNC_DIRTY_PIXELS_PER_BIT
,
2945 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2946 set_bit(x
, vs
->dirty
[y
]);
2953 qemu_pixman_image_unref(tmpbuf
);
2957 static void vnc_refresh(DisplayChangeListener
*dcl
)
2959 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
2961 int has_dirty
, rects
= 0;
2963 if (QTAILQ_EMPTY(&vd
->clients
)) {
2964 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_MAX
);
2968 graphic_hw_update(vd
->dcl
.con
);
2970 if (vnc_trylock_display(vd
)) {
2971 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2975 has_dirty
= vnc_refresh_server_surface(vd
);
2976 vnc_unlock_display(vd
);
2978 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
2979 rects
+= vnc_update_client(vs
, has_dirty
, false);
2980 /* vs might be free()ed here */
2983 if (has_dirty
&& rects
) {
2984 vd
->dcl
.update_interval
/= 2;
2985 if (vd
->dcl
.update_interval
< VNC_REFRESH_INTERVAL_BASE
) {
2986 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_BASE
;
2989 vd
->dcl
.update_interval
+= VNC_REFRESH_INTERVAL_INC
;
2990 if (vd
->dcl
.update_interval
> VNC_REFRESH_INTERVAL_MAX
) {
2991 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_MAX
;
2996 static void vnc_connect(VncDisplay
*vd
, int csock
,
2997 bool skipauth
, bool websocket
)
2999 VncState
*vs
= g_malloc0(sizeof(VncState
));
3005 buffer_init(&vs
->input
, "vnc-input/%d", csock
);
3006 buffer_init(&vs
->output
, "vnc-output/%d", csock
);
3007 buffer_init(&vs
->ws_input
, "vnc-ws_input/%d", csock
);
3008 buffer_init(&vs
->ws_output
, "vnc-ws_output/%d", csock
);
3009 buffer_init(&vs
->jobs_buffer
, "vnc-jobs_buffer/%d", csock
);
3011 buffer_init(&vs
->tight
.tight
, "vnc-tight/%d", csock
);
3012 buffer_init(&vs
->tight
.zlib
, "vnc-tight-zlib/%d", csock
);
3013 buffer_init(&vs
->tight
.gradient
, "vnc-tight-gradient/%d", csock
);
3014 #ifdef CONFIG_VNC_JPEG
3015 buffer_init(&vs
->tight
.jpeg
, "vnc-tight-jpeg/%d", csock
);
3017 #ifdef CONFIG_VNC_PNG
3018 buffer_init(&vs
->tight
.png
, "vnc-tight-png/%d", csock
);
3020 buffer_init(&vs
->zlib
.zlib
, "vnc-zlib/%d", csock
);
3021 buffer_init(&vs
->zrle
.zrle
, "vnc-zrle/%d", csock
);
3022 buffer_init(&vs
->zrle
.fb
, "vnc-zrle-fb/%d", csock
);
3023 buffer_init(&vs
->zrle
.zlib
, "vnc-zrle-zlib/%d", csock
);
3026 vs
->auth
= VNC_AUTH_NONE
;
3027 vs
->subauth
= VNC_AUTH_INVALID
;
3030 vs
->auth
= vd
->ws_auth
;
3031 vs
->subauth
= VNC_AUTH_INVALID
;
3033 vs
->auth
= vd
->auth
;
3034 vs
->subauth
= vd
->subauth
;
3037 VNC_DEBUG("Client sock=%d ws=%d auth=%d subauth=%d\n",
3038 csock
, websocket
, vs
->auth
, vs
->subauth
);
3040 vs
->lossy_rect
= g_malloc0(VNC_STAT_ROWS
* sizeof (*vs
->lossy_rect
));
3041 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
3042 vs
->lossy_rect
[i
] = g_malloc0(VNC_STAT_COLS
* sizeof (uint8_t));
3045 VNC_DEBUG("New client on socket %d\n", csock
);
3046 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
3047 qemu_set_nonblock(vs
->csock
);
3051 qemu_set_fd_handler(vs
->csock
, vncws_tls_handshake_io
, NULL
, vs
);
3053 qemu_set_fd_handler(vs
->csock
, vncws_handshake_read
, NULL
, vs
);
3057 qemu_set_fd_handler(vs
->csock
, vnc_client_read
, NULL
, vs
);
3060 vnc_client_cache_addr(vs
);
3061 vnc_qmp_event(vs
, QAPI_EVENT_VNC_CONNECTED
);
3062 vnc_set_share_mode(vs
, VNC_SHARE_MODE_CONNECTING
);
3064 if (!vs
->websocket
) {
3068 if (vd
->num_connecting
> vd
->connections_limit
) {
3069 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
3070 if (vs
->share_mode
== VNC_SHARE_MODE_CONNECTING
) {
3071 vnc_disconnect_start(vs
);
3078 void vnc_init_state(VncState
*vs
)
3080 vs
->initialized
= true;
3081 VncDisplay
*vd
= vs
->vd
;
3086 vs
->as
.freq
= 44100;
3087 vs
->as
.nchannels
= 2;
3088 vs
->as
.fmt
= AUD_FMT_S16
;
3089 vs
->as
.endianness
= 0;
3091 qemu_mutex_init(&vs
->output_mutex
);
3092 vs
->bh
= qemu_bh_new(vnc_jobs_bh
, vs
);
3094 QTAILQ_INSERT_TAIL(&vd
->clients
, vs
, next
);
3096 graphic_hw_update(vd
->dcl
.con
);
3098 vnc_write(vs
, "RFB 003.008\n", 12);
3100 vnc_read_when(vs
, protocol_version
, 12);
3102 if (vs
->vd
->lock_key_sync
)
3103 vs
->led
= qemu_add_led_event_handler(kbd_leds
, vs
);
3105 vs
->mouse_mode_notifier
.notify
= check_pointer_type_change
;
3106 qemu_add_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
3108 /* vs might be free()ed here */
3111 static void vnc_listen_read(void *opaque
, bool websocket
)
3113 VncDisplay
*vs
= opaque
;
3114 struct sockaddr_in addr
;
3115 socklen_t addrlen
= sizeof(addr
);
3119 graphic_hw_update(vs
->dcl
.con
);
3121 csock
= qemu_accept(vs
->lwebsock
, (struct sockaddr
*)&addr
, &addrlen
);
3123 csock
= qemu_accept(vs
->lsock
, (struct sockaddr
*)&addr
, &addrlen
);
3127 socket_set_nodelay(csock
);
3128 vnc_connect(vs
, csock
, false, websocket
);
3132 static void vnc_listen_regular_read(void *opaque
)
3134 vnc_listen_read(opaque
, false);
3137 static void vnc_listen_websocket_read(void *opaque
)
3139 vnc_listen_read(opaque
, true);
3142 static const DisplayChangeListenerOps dcl_ops
= {
3144 .dpy_refresh
= vnc_refresh
,
3145 .dpy_gfx_copy
= vnc_dpy_copy
,
3146 .dpy_gfx_update
= vnc_dpy_update
,
3147 .dpy_gfx_switch
= vnc_dpy_switch
,
3148 .dpy_gfx_check_format
= qemu_pixman_check_format
,
3149 .dpy_mouse_set
= vnc_mouse_set
,
3150 .dpy_cursor_define
= vnc_dpy_cursor_define
,
3153 void vnc_display_init(const char *id
)
3157 if (vnc_display_find(id
) != NULL
) {
3160 vs
= g_malloc0(sizeof(*vs
));
3162 vs
->id
= strdup(id
);
3163 QTAILQ_INSERT_TAIL(&vnc_displays
, vs
, next
);
3168 QTAILQ_INIT(&vs
->clients
);
3169 vs
->expires
= TIME_MAX
;
3171 if (keyboard_layout
) {
3172 trace_vnc_key_map_init(keyboard_layout
);
3173 vs
->kbd_layout
= init_keyboard_layout(name2keysym
, keyboard_layout
);
3175 vs
->kbd_layout
= init_keyboard_layout(name2keysym
, "en-us");
3178 if (!vs
->kbd_layout
)
3181 qemu_mutex_init(&vs
->mutex
);
3182 vnc_start_worker_thread();
3184 vs
->dcl
.ops
= &dcl_ops
;
3185 register_displaychangelistener(&vs
->dcl
);
3189 static void vnc_display_close(VncDisplay
*vs
)
3193 vs
->enabled
= false;
3194 vs
->is_unix
= false;
3195 if (vs
->lsock
!= -1) {
3196 qemu_set_fd_handler(vs
->lsock
, NULL
, NULL
, NULL
);
3200 vs
->ws_enabled
= false;
3201 if (vs
->lwebsock
!= -1) {
3202 qemu_set_fd_handler(vs
->lwebsock
, NULL
, NULL
, NULL
);
3203 close(vs
->lwebsock
);
3206 vs
->auth
= VNC_AUTH_INVALID
;
3207 vs
->subauth
= VNC_AUTH_INVALID
;
3209 object_unparent(OBJECT(vs
->tlscreds
));
3211 g_free(vs
->tlsaclname
);
3212 vs
->tlsaclname
= NULL
;
3215 int vnc_display_password(const char *id
, const char *password
)
3217 VncDisplay
*vs
= vnc_display_find(id
);
3222 if (vs
->auth
== VNC_AUTH_NONE
) {
3223 error_printf_unless_qmp("If you want use passwords please enable "
3224 "password auth using '-vnc ${dpy},password'.");
3228 g_free(vs
->password
);
3229 vs
->password
= g_strdup(password
);
3234 int vnc_display_pw_expire(const char *id
, time_t expires
)
3236 VncDisplay
*vs
= vnc_display_find(id
);
3242 vs
->expires
= expires
;
3246 char *vnc_display_local_addr(const char *id
)
3248 VncDisplay
*vs
= vnc_display_find(id
);
3251 return vnc_socket_local_addr("%s:%s", vs
->lsock
);
3254 static QemuOptsList qemu_vnc_opts
= {
3256 .head
= QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts
.head
),
3257 .implied_opt_name
= "vnc",
3261 .type
= QEMU_OPT_STRING
,
3263 .name
= "websocket",
3264 .type
= QEMU_OPT_STRING
,
3266 .name
= "tls-creds",
3267 .type
= QEMU_OPT_STRING
,
3269 /* Deprecated in favour of tls-creds */
3271 .type
= QEMU_OPT_STRING
,
3274 .type
= QEMU_OPT_STRING
,
3277 .type
= QEMU_OPT_STRING
,
3280 .type
= QEMU_OPT_NUMBER
,
3282 .name
= "connections",
3283 .type
= QEMU_OPT_NUMBER
,
3286 .type
= QEMU_OPT_NUMBER
,
3289 .type
= QEMU_OPT_BOOL
,
3292 .type
= QEMU_OPT_BOOL
,
3295 .type
= QEMU_OPT_BOOL
,
3298 .type
= QEMU_OPT_BOOL
,
3300 .name
= "lock-key-sync",
3301 .type
= QEMU_OPT_BOOL
,
3304 .type
= QEMU_OPT_BOOL
,
3306 /* Deprecated in favour of tls-creds */
3308 .type
= QEMU_OPT_BOOL
,
3310 /* Deprecated in favour of tls-creds */
3311 .name
= "x509verify",
3312 .type
= QEMU_OPT_STRING
,
3315 .type
= QEMU_OPT_BOOL
,
3318 .type
= QEMU_OPT_BOOL
,
3320 .name
= "non-adaptive",
3321 .type
= QEMU_OPT_BOOL
,
3323 { /* end of list */ }
3329 vnc_display_setup_auth(VncDisplay
*vs
,
3336 * We have a choice of 3 authentication options
3342 * The channel can be run in 2 modes
3347 * And TLS can use 2 types of credentials
3352 * We thus have 9 possible logical combinations
3357 * 4. tls + anon + none
3358 * 5. tls + anon + vnc
3359 * 6. tls + anon + sasl
3360 * 7. tls + x509 + none
3361 * 8. tls + x509 + vnc
3362 * 9. tls + x509 + sasl
3364 * These need to be mapped into the VNC auth schemes
3365 * in an appropriate manner. In regular VNC, all the
3366 * TLS options get mapped into VNC_AUTH_VENCRYPT
3369 * In websockets, the https:// protocol already provides
3370 * TLS support, so there is no need to make use of the
3371 * VeNCrypt extension. Furthermore, websockets browser
3372 * clients could not use VeNCrypt even if they wanted to,
3373 * as they cannot control when the TLS handshake takes
3374 * place. Thus there is no option but to rely on https://,
3375 * meaning combinations 4->6 and 7->9 will be mapped to
3376 * VNC auth schemes in the same way as combos 1->3.
3378 * Regardless of fact that we have a different mapping to
3379 * VNC auth mechs for plain VNC vs websockets VNC, the end
3380 * result has the same security characteristics.
3384 vs
->auth
= VNC_AUTH_VENCRYPT
;
3388 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3389 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3390 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3391 vs
->subauth
= VNC_AUTH_VENCRYPT_X509VNC
;
3392 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3393 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3394 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3395 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSVNC
;
3398 "Unsupported TLS cred type %s",
3399 object_get_typename(OBJECT(vs
->tlscreds
)));
3403 VNC_DEBUG("Initializing VNC server with password auth\n");
3404 vs
->auth
= VNC_AUTH_VNC
;
3405 vs
->subauth
= VNC_AUTH_INVALID
;
3408 vs
->ws_auth
= VNC_AUTH_VNC
;
3410 vs
->ws_auth
= VNC_AUTH_INVALID
;
3414 vs
->auth
= VNC_AUTH_VENCRYPT
;
3418 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3419 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3420 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3421 vs
->subauth
= VNC_AUTH_VENCRYPT_X509SASL
;
3422 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3423 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3424 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3425 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSSASL
;
3428 "Unsupported TLS cred type %s",
3429 object_get_typename(OBJECT(vs
->tlscreds
)));
3433 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3434 vs
->auth
= VNC_AUTH_SASL
;
3435 vs
->subauth
= VNC_AUTH_INVALID
;
3438 vs
->ws_auth
= VNC_AUTH_SASL
;
3440 vs
->ws_auth
= VNC_AUTH_INVALID
;
3444 vs
->auth
= VNC_AUTH_VENCRYPT
;
3448 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3449 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3450 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3451 vs
->subauth
= VNC_AUTH_VENCRYPT_X509NONE
;
3452 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3453 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3454 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3455 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSNONE
;
3458 "Unsupported TLS cred type %s",
3459 object_get_typename(OBJECT(vs
->tlscreds
)));
3463 VNC_DEBUG("Initializing VNC server with no auth\n");
3464 vs
->auth
= VNC_AUTH_NONE
;
3465 vs
->subauth
= VNC_AUTH_INVALID
;
3468 vs
->ws_auth
= VNC_AUTH_NONE
;
3470 vs
->ws_auth
= VNC_AUTH_INVALID
;
3478 * Handle back compat with old CLI syntax by creating some
3479 * suitable QCryptoTLSCreds objects
3481 static QCryptoTLSCreds
*
3482 vnc_display_create_creds(bool x509
,
3488 gchar
*credsid
= g_strdup_printf("tlsvnc%s", id
);
3489 Object
*parent
= object_get_objects_root();
3494 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509
,
3498 "endpoint", "server",
3500 "verify-peer", x509verify
? "yes" : "no",
3503 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON
,
3507 "endpoint", "server",
3514 error_propagate(errp
, err
);
3518 return QCRYPTO_TLS_CREDS(creds
);
3522 void vnc_display_open(const char *id
, Error
**errp
)
3524 VncDisplay
*vs
= vnc_display_find(id
);
3525 QemuOpts
*opts
= qemu_opts_find(&qemu_vnc_opts
, id
);
3526 SocketAddress
*saddr
= NULL
, *wsaddr
= NULL
;
3527 const char *share
, *device_id
;
3529 bool password
= false;
3530 bool reverse
= false;
3535 #ifdef CONFIG_VNC_SASL
3539 int lock_key_sync
= 1;
3542 error_setg(errp
, "VNC display not active");
3545 vnc_display_close(vs
);
3550 vnc
= qemu_opt_get(opts
, "vnc");
3551 if (!vnc
|| strcmp(vnc
, "none") == 0) {
3555 h
= strrchr(vnc
, ':');
3557 size_t hlen
= h
- vnc
;
3559 const char *websocket
= qemu_opt_get(opts
, "websocket");
3560 int to
= qemu_opt_get_number(opts
, "to", 0);
3561 bool has_ipv4
= qemu_opt_get_bool(opts
, "ipv4", false);
3562 bool has_ipv6
= qemu_opt_get_bool(opts
, "ipv6", false);
3564 saddr
= g_new0(SocketAddress
, 1);
3566 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1
)) {
3568 "SHA1 hash support is required for websockets");
3572 wsaddr
= g_new0(SocketAddress
, 1);
3573 vs
->ws_enabled
= true;
3576 if (strncmp(vnc
, "unix:", 5) == 0) {
3577 saddr
->type
= SOCKET_ADDRESS_KIND_UNIX
;
3578 saddr
->u
.q_unix
= g_new0(UnixSocketAddress
, 1);
3579 saddr
->u
.q_unix
->path
= g_strdup(vnc
+ 5);
3581 if (vs
->ws_enabled
) {
3582 error_setg(errp
, "UNIX sockets not supported with websock");
3586 unsigned long long baseport
;
3587 saddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3588 saddr
->u
.inet
= g_new0(InetSocketAddress
, 1);
3589 if (vnc
[0] == '[' && vnc
[hlen
- 1] == ']') {
3590 saddr
->u
.inet
->host
= g_strndup(vnc
+ 1, hlen
- 2);
3592 saddr
->u
.inet
->host
= g_strndup(vnc
, hlen
);
3594 if (parse_uint_full(h
+ 1, &baseport
, 10) < 0) {
3595 error_setg(errp
, "can't convert to a number: %s", h
+ 1);
3598 if (baseport
> 65535 ||
3599 baseport
+ 5900 > 65535) {
3600 error_setg(errp
, "port %s out of range", h
+ 1);
3603 saddr
->u
.inet
->port
= g_strdup_printf(
3604 "%d", (int)baseport
+ 5900);
3607 saddr
->u
.inet
->has_to
= true;
3608 saddr
->u
.inet
->to
= to
;
3609 saddr
->u
.inet
->has_to
= true;
3610 saddr
->u
.inet
->to
= to
+ 5900;
3612 saddr
->u
.inet
->ipv4
= saddr
->u
.inet
->has_ipv4
= has_ipv4
;
3613 saddr
->u
.inet
->ipv6
= saddr
->u
.inet
->has_ipv6
= has_ipv6
;
3615 if (vs
->ws_enabled
) {
3616 wsaddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3617 wsaddr
->u
.inet
= g_new0(InetSocketAddress
, 1);
3618 wsaddr
->u
.inet
->host
= g_strdup(saddr
->u
.inet
->host
);
3619 wsaddr
->u
.inet
->port
= g_strdup(websocket
);
3622 wsaddr
->u
.inet
->has_to
= true;
3623 wsaddr
->u
.inet
->to
= to
;
3625 wsaddr
->u
.inet
->ipv4
= wsaddr
->u
.inet
->has_ipv4
= has_ipv4
;
3626 wsaddr
->u
.inet
->ipv6
= wsaddr
->u
.inet
->has_ipv6
= has_ipv6
;
3630 error_setg(errp
, "no vnc port specified");
3634 password
= qemu_opt_get_bool(opts
, "password", false);
3636 if (fips_get_state()) {
3638 "VNC password auth disabled due to FIPS mode, "
3639 "consider using the VeNCrypt or SASL authentication "
3640 "methods as an alternative");
3643 if (!qcrypto_cipher_supports(
3644 QCRYPTO_CIPHER_ALG_DES_RFB
)) {
3646 "Cipher backend does not support DES RFB algorithm");
3651 reverse
= qemu_opt_get_bool(opts
, "reverse", false);
3652 lock_key_sync
= qemu_opt_get_bool(opts
, "lock-key-sync", true);
3653 sasl
= qemu_opt_get_bool(opts
, "sasl", false);
3654 #ifndef CONFIG_VNC_SASL
3656 error_setg(errp
, "VNC SASL auth requires cyrus-sasl support");
3659 #endif /* CONFIG_VNC_SASL */
3660 credid
= qemu_opt_get(opts
, "tls-creds");
3663 if (qemu_opt_get(opts
, "tls") ||
3664 qemu_opt_get(opts
, "x509") ||
3665 qemu_opt_get(opts
, "x509verify")) {
3667 "'credid' parameter is mutually exclusive with "
3668 "'tls', 'x509' and 'x509verify' parameters");
3672 creds
= object_resolve_path_component(
3673 object_get_objects_root(), credid
);
3675 error_setg(errp
, "No TLS credentials with id '%s'",
3679 vs
->tlscreds
= (QCryptoTLSCreds
*)
3680 object_dynamic_cast(creds
,
3681 TYPE_QCRYPTO_TLS_CREDS
);
3682 if (!vs
->tlscreds
) {
3683 error_setg(errp
, "Object with id '%s' is not TLS credentials",
3687 object_ref(OBJECT(vs
->tlscreds
));
3689 if (vs
->tlscreds
->endpoint
!= QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
) {
3691 "Expecting TLS credentials with a server endpoint");
3696 bool tls
= false, x509
= false, x509verify
= false;
3697 tls
= qemu_opt_get_bool(opts
, "tls", false);
3699 path
= qemu_opt_get(opts
, "x509");
3704 path
= qemu_opt_get(opts
, "x509verify");
3710 vs
->tlscreds
= vnc_display_create_creds(x509
,
3715 if (!vs
->tlscreds
) {
3720 acl
= qemu_opt_get_bool(opts
, "acl", false);
3722 share
= qemu_opt_get(opts
, "share");
3724 if (strcmp(share
, "ignore") == 0) {
3725 vs
->share_policy
= VNC_SHARE_POLICY_IGNORE
;
3726 } else if (strcmp(share
, "allow-exclusive") == 0) {
3727 vs
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3728 } else if (strcmp(share
, "force-shared") == 0) {
3729 vs
->share_policy
= VNC_SHARE_POLICY_FORCE_SHARED
;
3731 error_setg(errp
, "unknown vnc share= option");
3735 vs
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3737 vs
->connections_limit
= qemu_opt_get_number(opts
, "connections", 32);
3739 #ifdef CONFIG_VNC_JPEG
3740 vs
->lossy
= qemu_opt_get_bool(opts
, "lossy", false);
3742 vs
->non_adaptive
= qemu_opt_get_bool(opts
, "non-adaptive", false);
3743 /* adaptive updates are only used with tight encoding and
3744 * if lossy updates are enabled so we can disable all the
3745 * calculations otherwise */
3747 vs
->non_adaptive
= true;
3751 if (strcmp(vs
->id
, "default") == 0) {
3752 vs
->tlsaclname
= g_strdup("vnc.x509dname");
3754 vs
->tlsaclname
= g_strdup_printf("vnc.%s.x509dname", vs
->id
);
3756 qemu_acl_init(vs
->tlsaclname
);
3758 #ifdef CONFIG_VNC_SASL
3762 if (strcmp(vs
->id
, "default") == 0) {
3763 aclname
= g_strdup("vnc.username");
3765 aclname
= g_strdup_printf("vnc.%s.username", vs
->id
);
3767 vs
->sasl
.acl
= qemu_acl_init(aclname
);
3772 if (vnc_display_setup_auth(vs
, password
, sasl
, vs
->ws_enabled
, errp
) < 0) {
3776 #ifdef CONFIG_VNC_SASL
3777 if ((saslErr
= sasl_server_init(NULL
, "qemu")) != SASL_OK
) {
3778 error_setg(errp
, "Failed to initialize SASL auth: %s",
3779 sasl_errstring(saslErr
, NULL
, NULL
));
3783 vs
->lock_key_sync
= lock_key_sync
;
3785 device_id
= qemu_opt_get(opts
, "display");
3788 int head
= qemu_opt_get_number(opts
, "head", 0);
3790 dev
= qdev_find_recursive(sysbus_get_default(), device_id
);
3792 error_setg(errp
, "Device '%s' not found", device_id
);
3796 con
= qemu_console_lookup_by_device(dev
, head
);
3798 error_setg(errp
, "Device %s is not bound to a QemuConsole",
3806 if (con
!= vs
->dcl
.con
) {
3807 unregister_displaychangelistener(&vs
->dcl
);
3809 register_displaychangelistener(&vs
->dcl
);
3813 /* connect to viewer */
3817 if (vs
->ws_enabled
) {
3818 error_setg(errp
, "Cannot use websockets in reverse mode");
3821 csock
= socket_connect(saddr
, errp
, NULL
, NULL
);
3825 vs
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3826 vnc_connect(vs
, csock
, false, false);
3828 /* listen for connects */
3829 vs
->lsock
= socket_listen(saddr
, errp
);
3830 if (vs
->lsock
< 0) {
3833 vs
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3834 if (vs
->ws_enabled
) {
3835 vs
->lwebsock
= socket_listen(wsaddr
, errp
);
3836 if (vs
->lwebsock
< 0) {
3837 if (vs
->lsock
!= -1) {
3845 qemu_set_fd_handler(vs
->lsock
, vnc_listen_regular_read
, NULL
, vs
);
3846 if (vs
->ws_enabled
) {
3847 qemu_set_fd_handler(vs
->lwebsock
, vnc_listen_websocket_read
,
3852 qapi_free_SocketAddress(saddr
);
3853 qapi_free_SocketAddress(wsaddr
);
3857 qapi_free_SocketAddress(saddr
);
3858 qapi_free_SocketAddress(wsaddr
);
3859 vs
->enabled
= false;
3860 vs
->ws_enabled
= false;
3863 void vnc_display_add_client(const char *id
, int csock
, bool skipauth
)
3865 VncDisplay
*vs
= vnc_display_find(id
);
3870 vnc_connect(vs
, csock
, skipauth
, false);
3873 static void vnc_auto_assign_id(QemuOptsList
*olist
, QemuOpts
*opts
)
3878 id
= g_strdup("default");
3879 while (qemu_opts_find(olist
, id
)) {
3881 id
= g_strdup_printf("vnc%d", i
++);
3883 qemu_opts_set_id(opts
, id
);
3886 QemuOpts
*vnc_parse(const char *str
, Error
**errp
)
3888 QemuOptsList
*olist
= qemu_find_opts("vnc");
3889 QemuOpts
*opts
= qemu_opts_parse(olist
, str
, true, errp
);
3896 id
= qemu_opts_id(opts
);
3898 /* auto-assign id if not present */
3899 vnc_auto_assign_id(olist
, opts
);
3904 int vnc_init_func(void *opaque
, QemuOpts
*opts
, Error
**errp
)
3906 Error
*local_err
= NULL
;
3907 char *id
= (char *)qemu_opts_id(opts
);
3910 vnc_display_init(id
);
3911 vnc_display_open(id
, &local_err
);
3912 if (local_err
!= NULL
) {
3913 error_report("Failed to start VNC server: %s",
3914 error_get_pretty(local_err
));
3915 error_free(local_err
);
3921 static void vnc_register_config(void)
3923 qemu_add_opts(&qemu_vnc_opts
);
3925 machine_init(vnc_register_config
);