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
27 #include "qemu/osdep.h"
32 #include "sysemu/sysemu.h"
33 #include "qemu/error-report.h"
34 #include "qemu/sockets.h"
35 #include "qemu/timer.h"
37 #include "qemu/config-file.h"
38 #include "qapi/qmp/qerror.h"
39 #include "qapi/qmp/types.h"
40 #include "qmp-commands.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"
47 #include "qemu/cutils.h"
49 #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
50 #define VNC_REFRESH_INTERVAL_INC 50
51 #define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
52 static const struct timeval VNC_REFRESH_STATS
= { 0, 500000 };
53 static const struct timeval VNC_REFRESH_LOSSY
= { 2, 0 };
55 #include "vnc_keysym.h"
56 #include "crypto/cipher.h"
58 static QTAILQ_HEAD(, VncDisplay
) vnc_displays
=
59 QTAILQ_HEAD_INITIALIZER(vnc_displays
);
61 static int vnc_cursor_define(VncState
*vs
);
62 static void vnc_release_modifiers(VncState
*vs
);
64 static void vnc_set_share_mode(VncState
*vs
, VncShareMode mode
)
67 static const char *mn
[] = {
69 [VNC_SHARE_MODE_CONNECTING
] = "connecting",
70 [VNC_SHARE_MODE_SHARED
] = "shared",
71 [VNC_SHARE_MODE_EXCLUSIVE
] = "exclusive",
72 [VNC_SHARE_MODE_DISCONNECTED
] = "disconnected",
74 fprintf(stderr
, "%s/%p: %s -> %s\n", __func__
,
75 vs
->ioc
, mn
[vs
->share_mode
], mn
[mode
]);
78 switch (vs
->share_mode
) {
79 case VNC_SHARE_MODE_CONNECTING
:
80 vs
->vd
->num_connecting
--;
82 case VNC_SHARE_MODE_SHARED
:
85 case VNC_SHARE_MODE_EXCLUSIVE
:
86 vs
->vd
->num_exclusive
--;
92 vs
->share_mode
= mode
;
94 switch (vs
->share_mode
) {
95 case VNC_SHARE_MODE_CONNECTING
:
96 vs
->vd
->num_connecting
++;
98 case VNC_SHARE_MODE_SHARED
:
101 case VNC_SHARE_MODE_EXCLUSIVE
:
102 vs
->vd
->num_exclusive
++;
110 static void vnc_init_basic_info(SocketAddress
*addr
,
114 switch (addr
->type
) {
115 case SOCKET_ADDRESS_KIND_INET
:
116 info
->host
= g_strdup(addr
->u
.inet
.data
->host
);
117 info
->service
= g_strdup(addr
->u
.inet
.data
->port
);
118 if (addr
->u
.inet
.data
->ipv6
) {
119 info
->family
= NETWORK_ADDRESS_FAMILY_IPV6
;
121 info
->family
= NETWORK_ADDRESS_FAMILY_IPV4
;
125 case SOCKET_ADDRESS_KIND_UNIX
:
126 info
->host
= g_strdup("");
127 info
->service
= g_strdup(addr
->u
.q_unix
.data
->path
);
128 info
->family
= NETWORK_ADDRESS_FAMILY_UNIX
;
132 error_setg(errp
, "Unsupported socket kind %d",
140 static void vnc_init_basic_info_from_server_addr(QIOChannelSocket
*ioc
,
144 SocketAddress
*addr
= NULL
;
147 error_setg(errp
, "No listener socket available");
151 addr
= qio_channel_socket_get_local_address(ioc
, errp
);
156 vnc_init_basic_info(addr
, info
, errp
);
157 qapi_free_SocketAddress(addr
);
160 static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket
*ioc
,
164 SocketAddress
*addr
= NULL
;
166 addr
= qio_channel_socket_get_remote_address(ioc
, errp
);
171 vnc_init_basic_info(addr
, info
, errp
);
172 qapi_free_SocketAddress(addr
);
175 static const char *vnc_auth_name(VncDisplay
*vd
) {
177 case VNC_AUTH_INVALID
:
193 case VNC_AUTH_VENCRYPT
:
194 switch (vd
->subauth
) {
195 case VNC_AUTH_VENCRYPT_PLAIN
:
196 return "vencrypt+plain";
197 case VNC_AUTH_VENCRYPT_TLSNONE
:
198 return "vencrypt+tls+none";
199 case VNC_AUTH_VENCRYPT_TLSVNC
:
200 return "vencrypt+tls+vnc";
201 case VNC_AUTH_VENCRYPT_TLSPLAIN
:
202 return "vencrypt+tls+plain";
203 case VNC_AUTH_VENCRYPT_X509NONE
:
204 return "vencrypt+x509+none";
205 case VNC_AUTH_VENCRYPT_X509VNC
:
206 return "vencrypt+x509+vnc";
207 case VNC_AUTH_VENCRYPT_X509PLAIN
:
208 return "vencrypt+x509+plain";
209 case VNC_AUTH_VENCRYPT_TLSSASL
:
210 return "vencrypt+tls+sasl";
211 case VNC_AUTH_VENCRYPT_X509SASL
:
212 return "vencrypt+x509+sasl";
222 static VncServerInfo
*vnc_server_info_get(VncDisplay
*vd
)
227 info
= g_malloc0(sizeof(*info
));
228 vnc_init_basic_info_from_server_addr(vd
->lsock
,
229 qapi_VncServerInfo_base(info
), &err
);
230 info
->has_auth
= true;
231 info
->auth
= g_strdup(vnc_auth_name(vd
));
233 qapi_free_VncServerInfo(info
);
240 static void vnc_client_cache_auth(VncState
*client
)
247 client
->info
->x509_dname
=
248 qcrypto_tls_session_get_peer_name(client
->tls
);
249 client
->info
->has_x509_dname
=
250 client
->info
->x509_dname
!= NULL
;
252 #ifdef CONFIG_VNC_SASL
253 if (client
->sasl
.conn
&&
254 client
->sasl
.username
) {
255 client
->info
->has_sasl_username
= true;
256 client
->info
->sasl_username
= g_strdup(client
->sasl
.username
);
261 static void vnc_client_cache_addr(VncState
*client
)
265 client
->info
= g_malloc0(sizeof(*client
->info
));
266 vnc_init_basic_info_from_remote_addr(client
->sioc
,
267 qapi_VncClientInfo_base(client
->info
),
270 qapi_free_VncClientInfo(client
->info
);
276 static void vnc_qmp_event(VncState
*vs
, QAPIEvent event
)
284 si
= vnc_server_info_get(vs
->vd
);
290 case QAPI_EVENT_VNC_CONNECTED
:
291 qapi_event_send_vnc_connected(si
, qapi_VncClientInfo_base(vs
->info
),
294 case QAPI_EVENT_VNC_INITIALIZED
:
295 qapi_event_send_vnc_initialized(si
, vs
->info
, &error_abort
);
297 case QAPI_EVENT_VNC_DISCONNECTED
:
298 qapi_event_send_vnc_disconnected(si
, vs
->info
, &error_abort
);
304 qapi_free_VncServerInfo(si
);
307 static VncClientInfo
*qmp_query_vnc_client(const VncState
*client
)
312 info
= g_malloc0(sizeof(*info
));
314 vnc_init_basic_info_from_remote_addr(client
->sioc
,
315 qapi_VncClientInfo_base(info
),
319 qapi_free_VncClientInfo(info
);
323 info
->websocket
= client
->websocket
;
326 info
->x509_dname
= qcrypto_tls_session_get_peer_name(client
->tls
);
327 info
->has_x509_dname
= info
->x509_dname
!= NULL
;
329 #ifdef CONFIG_VNC_SASL
330 if (client
->sasl
.conn
&& client
->sasl
.username
) {
331 info
->has_sasl_username
= true;
332 info
->sasl_username
= g_strdup(client
->sasl
.username
);
339 static VncDisplay
*vnc_display_find(const char *id
)
344 return QTAILQ_FIRST(&vnc_displays
);
346 QTAILQ_FOREACH(vd
, &vnc_displays
, next
) {
347 if (strcmp(id
, vd
->id
) == 0) {
354 static VncClientInfoList
*qmp_query_client_list(VncDisplay
*vd
)
356 VncClientInfoList
*cinfo
, *prev
= NULL
;
359 QTAILQ_FOREACH(client
, &vd
->clients
, next
) {
360 cinfo
= g_new0(VncClientInfoList
, 1);
361 cinfo
->value
= qmp_query_vnc_client(client
);
368 VncInfo
*qmp_query_vnc(Error
**errp
)
370 VncInfo
*info
= g_malloc0(sizeof(*info
));
371 VncDisplay
*vd
= vnc_display_find(NULL
);
372 SocketAddress
*addr
= NULL
;
374 if (vd
== NULL
|| !vd
->lsock
) {
375 info
->enabled
= false;
377 info
->enabled
= true;
379 /* for compatibility with the original command */
380 info
->has_clients
= true;
381 info
->clients
= qmp_query_client_list(vd
);
383 if (vd
->lsock
== NULL
) {
387 addr
= qio_channel_socket_get_local_address(vd
->lsock
, errp
);
392 switch (addr
->type
) {
393 case SOCKET_ADDRESS_KIND_INET
:
394 info
->host
= g_strdup(addr
->u
.inet
.data
->host
);
395 info
->service
= g_strdup(addr
->u
.inet
.data
->port
);
396 if (addr
->u
.inet
.data
->ipv6
) {
397 info
->family
= NETWORK_ADDRESS_FAMILY_IPV6
;
399 info
->family
= NETWORK_ADDRESS_FAMILY_IPV4
;
403 case SOCKET_ADDRESS_KIND_UNIX
:
404 info
->host
= g_strdup("");
405 info
->service
= g_strdup(addr
->u
.q_unix
.data
->path
);
406 info
->family
= NETWORK_ADDRESS_FAMILY_UNIX
;
410 error_setg(errp
, "Unsupported socket kind %d",
415 info
->has_host
= true;
416 info
->has_service
= true;
417 info
->has_family
= true;
419 info
->has_auth
= true;
420 info
->auth
= g_strdup(vnc_auth_name(vd
));
423 qapi_free_SocketAddress(addr
);
427 qapi_free_SocketAddress(addr
);
428 qapi_free_VncInfo(info
);
433 static void qmp_query_auth(int auth
, int subauth
,
434 VncPrimaryAuth
*qmp_auth
,
435 VncVencryptSubAuth
*qmp_vencrypt
,
436 bool *qmp_has_vencrypt
);
438 static VncServerInfo2List
*qmp_query_server_entry(QIOChannelSocket
*ioc
,
442 VncServerInfo2List
*prev
)
444 VncServerInfo2List
*list
;
445 VncServerInfo2
*info
;
449 addr
= qio_channel_socket_get_local_address(ioc
, &err
);
455 info
= g_new0(VncServerInfo2
, 1);
456 vnc_init_basic_info(addr
, qapi_VncServerInfo2_base(info
), &err
);
457 qapi_free_SocketAddress(addr
);
459 qapi_free_VncServerInfo2(info
);
463 info
->websocket
= websocket
;
465 qmp_query_auth(auth
, subauth
, &info
->auth
,
466 &info
->vencrypt
, &info
->has_vencrypt
);
468 list
= g_new0(VncServerInfo2List
, 1);
474 static void qmp_query_auth(int auth
, int subauth
,
475 VncPrimaryAuth
*qmp_auth
,
476 VncVencryptSubAuth
*qmp_vencrypt
,
477 bool *qmp_has_vencrypt
)
481 *qmp_auth
= VNC_PRIMARY_AUTH_VNC
;
484 *qmp_auth
= VNC_PRIMARY_AUTH_RA2
;
487 *qmp_auth
= VNC_PRIMARY_AUTH_RA2NE
;
490 *qmp_auth
= VNC_PRIMARY_AUTH_TIGHT
;
493 *qmp_auth
= VNC_PRIMARY_AUTH_ULTRA
;
496 *qmp_auth
= VNC_PRIMARY_AUTH_TLS
;
498 case VNC_AUTH_VENCRYPT
:
499 *qmp_auth
= VNC_PRIMARY_AUTH_VENCRYPT
;
500 *qmp_has_vencrypt
= true;
502 case VNC_AUTH_VENCRYPT_PLAIN
:
503 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_PLAIN
;
505 case VNC_AUTH_VENCRYPT_TLSNONE
:
506 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_NONE
;
508 case VNC_AUTH_VENCRYPT_TLSVNC
:
509 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_VNC
;
511 case VNC_AUTH_VENCRYPT_TLSPLAIN
:
512 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN
;
514 case VNC_AUTH_VENCRYPT_X509NONE
:
515 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_NONE
;
517 case VNC_AUTH_VENCRYPT_X509VNC
:
518 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_VNC
;
520 case VNC_AUTH_VENCRYPT_X509PLAIN
:
521 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_PLAIN
;
523 case VNC_AUTH_VENCRYPT_TLSSASL
:
524 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_SASL
;
526 case VNC_AUTH_VENCRYPT_X509SASL
:
527 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_SASL
;
530 *qmp_has_vencrypt
= false;
535 *qmp_auth
= VNC_PRIMARY_AUTH_SASL
;
539 *qmp_auth
= VNC_PRIMARY_AUTH_NONE
;
544 VncInfo2List
*qmp_query_vnc_servers(Error
**errp
)
546 VncInfo2List
*item
, *prev
= NULL
;
551 QTAILQ_FOREACH(vd
, &vnc_displays
, next
) {
552 info
= g_new0(VncInfo2
, 1);
553 info
->id
= g_strdup(vd
->id
);
554 info
->clients
= qmp_query_client_list(vd
);
555 qmp_query_auth(vd
->auth
, vd
->subauth
, &info
->auth
,
556 &info
->vencrypt
, &info
->has_vencrypt
);
558 dev
= DEVICE(object_property_get_link(OBJECT(vd
->dcl
.con
),
560 info
->has_display
= true;
561 info
->display
= g_strdup(dev
->id
);
563 if (vd
->lsock
!= NULL
) {
564 info
->server
= qmp_query_server_entry(
565 vd
->lsock
, false, vd
->auth
, vd
->subauth
, info
->server
);
567 if (vd
->lwebsock
!= NULL
) {
568 info
->server
= qmp_query_server_entry(
569 vd
->lwebsock
, true, vd
->ws_auth
, vd
->ws_subauth
, info
->server
);
572 item
= g_new0(VncInfo2List
, 1);
581 1) Get the queue working for IO.
582 2) there is some weirdness when using the -S option (the screen is grey
583 and not totally invalidated
584 3) resolutions > 1024
587 static int vnc_update_client(VncState
*vs
, int has_dirty
, bool sync
);
588 static void vnc_disconnect_start(VncState
*vs
);
590 static void vnc_colordepth(VncState
*vs
);
591 static void framebuffer_update_request(VncState
*vs
, int incremental
,
592 int x_position
, int y_position
,
594 static void vnc_refresh(DisplayChangeListener
*dcl
);
595 static int vnc_refresh_server_surface(VncDisplay
*vd
);
597 static int vnc_width(VncDisplay
*vd
)
599 return MIN(VNC_MAX_WIDTH
, ROUND_UP(surface_width(vd
->ds
),
600 VNC_DIRTY_PIXELS_PER_BIT
));
603 static int vnc_height(VncDisplay
*vd
)
605 return MIN(VNC_MAX_HEIGHT
, surface_height(vd
->ds
));
608 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty
[VNC_MAX_HEIGHT
],
609 VNC_MAX_WIDTH
/ VNC_DIRTY_PIXELS_PER_BIT
),
611 int x
, int y
, int w
, int h
)
613 int width
= vnc_width(vd
);
614 int height
= vnc_height(vd
);
616 /* this is needed this to ensure we updated all affected
617 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
618 w
+= (x
% VNC_DIRTY_PIXELS_PER_BIT
);
619 x
-= (x
% VNC_DIRTY_PIXELS_PER_BIT
);
623 w
= MIN(x
+ w
, width
) - x
;
624 h
= MIN(y
+ h
, height
);
627 bitmap_set(dirty
[y
], x
/ VNC_DIRTY_PIXELS_PER_BIT
,
628 DIV_ROUND_UP(w
, VNC_DIRTY_PIXELS_PER_BIT
));
632 static void vnc_dpy_update(DisplayChangeListener
*dcl
,
633 int x
, int y
, int w
, int h
)
635 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
636 struct VncSurface
*s
= &vd
->guest
;
638 vnc_set_area_dirty(s
->dirty
, vd
, x
, y
, w
, h
);
641 void vnc_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
,
644 vnc_write_u16(vs
, x
);
645 vnc_write_u16(vs
, y
);
646 vnc_write_u16(vs
, w
);
647 vnc_write_u16(vs
, h
);
649 vnc_write_s32(vs
, encoding
);
653 static void vnc_desktop_resize(VncState
*vs
)
655 if (vs
->ioc
== NULL
|| !vnc_has_feature(vs
, VNC_FEATURE_RESIZE
)) {
658 if (vs
->client_width
== pixman_image_get_width(vs
->vd
->server
) &&
659 vs
->client_height
== pixman_image_get_height(vs
->vd
->server
)) {
662 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
663 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
665 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
667 vnc_write_u16(vs
, 1); /* number of rects */
668 vnc_framebuffer_update(vs
, 0, 0, vs
->client_width
, vs
->client_height
,
669 VNC_ENCODING_DESKTOPRESIZE
);
670 vnc_unlock_output(vs
);
674 static void vnc_abort_display_jobs(VncDisplay
*vd
)
678 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
681 vnc_unlock_output(vs
);
683 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
686 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
689 vnc_unlock_output(vs
);
693 int vnc_server_fb_stride(VncDisplay
*vd
)
695 return pixman_image_get_stride(vd
->server
);
698 void *vnc_server_fb_ptr(VncDisplay
*vd
, int x
, int y
)
702 ptr
= (uint8_t *)pixman_image_get_data(vd
->server
);
703 ptr
+= y
* vnc_server_fb_stride(vd
);
704 ptr
+= x
* VNC_SERVER_FB_BYTES
;
708 static void vnc_update_server_surface(VncDisplay
*vd
)
712 qemu_pixman_image_unref(vd
->server
);
715 if (QTAILQ_EMPTY(&vd
->clients
)) {
719 width
= vnc_width(vd
);
720 height
= vnc_height(vd
);
721 vd
->server
= pixman_image_create_bits(VNC_SERVER_FB_FORMAT
,
725 memset(vd
->guest
.dirty
, 0x00, sizeof(vd
->guest
.dirty
));
726 vnc_set_area_dirty(vd
->guest
.dirty
, vd
, 0, 0,
730 static void vnc_dpy_switch(DisplayChangeListener
*dcl
,
731 DisplaySurface
*surface
)
733 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
736 vnc_abort_display_jobs(vd
);
740 vnc_update_server_surface(vd
);
743 qemu_pixman_image_unref(vd
->guest
.fb
);
744 vd
->guest
.fb
= pixman_image_ref(surface
->image
);
745 vd
->guest
.format
= surface
->format
;
747 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
749 vnc_desktop_resize(vs
);
750 if (vs
->vd
->cursor
) {
751 vnc_cursor_define(vs
);
753 memset(vs
->dirty
, 0x00, sizeof(vs
->dirty
));
754 vnc_set_area_dirty(vs
->dirty
, vd
, 0, 0,
761 static void vnc_write_pixels_copy(VncState
*vs
,
762 void *pixels
, int size
)
764 vnc_write(vs
, pixels
, size
);
767 /* slowest but generic code. */
768 void vnc_convert_pixel(VncState
*vs
, uint8_t *buf
, uint32_t v
)
772 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
773 r
= (((v
& 0x00ff0000) >> 16) << vs
->client_pf
.rbits
) >> 8;
774 g
= (((v
& 0x0000ff00) >> 8) << vs
->client_pf
.gbits
) >> 8;
775 b
= (((v
& 0x000000ff) >> 0) << vs
->client_pf
.bbits
) >> 8;
777 # error need some bits here if you change VNC_SERVER_FB_FORMAT
779 v
= (r
<< vs
->client_pf
.rshift
) |
780 (g
<< vs
->client_pf
.gshift
) |
781 (b
<< vs
->client_pf
.bshift
);
782 switch (vs
->client_pf
.bytes_per_pixel
) {
812 static void vnc_write_pixels_generic(VncState
*vs
,
813 void *pixels1
, int size
)
817 if (VNC_SERVER_FB_BYTES
== 4) {
818 uint32_t *pixels
= pixels1
;
821 for (i
= 0; i
< n
; i
++) {
822 vnc_convert_pixel(vs
, buf
, pixels
[i
]);
823 vnc_write(vs
, buf
, vs
->client_pf
.bytes_per_pixel
);
828 int vnc_raw_send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
832 VncDisplay
*vd
= vs
->vd
;
834 row
= vnc_server_fb_ptr(vd
, x
, y
);
835 for (i
= 0; i
< h
; i
++) {
836 vs
->write_pixels(vs
, row
, w
* VNC_SERVER_FB_BYTES
);
837 row
+= vnc_server_fb_stride(vd
);
842 int vnc_send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
845 bool encode_raw
= false;
846 size_t saved_offs
= vs
->output
.offset
;
848 switch(vs
->vnc_encoding
) {
849 case VNC_ENCODING_ZLIB
:
850 n
= vnc_zlib_send_framebuffer_update(vs
, x
, y
, w
, h
);
852 case VNC_ENCODING_HEXTILE
:
853 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_HEXTILE
);
854 n
= vnc_hextile_send_framebuffer_update(vs
, x
, y
, w
, h
);
856 case VNC_ENCODING_TIGHT
:
857 n
= vnc_tight_send_framebuffer_update(vs
, x
, y
, w
, h
);
859 case VNC_ENCODING_TIGHT_PNG
:
860 n
= vnc_tight_png_send_framebuffer_update(vs
, x
, y
, w
, h
);
862 case VNC_ENCODING_ZRLE
:
863 n
= vnc_zrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
865 case VNC_ENCODING_ZYWRLE
:
866 n
= vnc_zywrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
873 /* If the client has the same pixel format as our internal buffer and
874 * a RAW encoding would need less space fall back to RAW encoding to
875 * save bandwidth and processing power in the client. */
876 if (!encode_raw
&& vs
->write_pixels
== vnc_write_pixels_copy
&&
877 12 + h
* w
* VNC_SERVER_FB_BYTES
<= (vs
->output
.offset
- saved_offs
)) {
878 vs
->output
.offset
= saved_offs
;
883 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_RAW
);
884 n
= vnc_raw_send_framebuffer_update(vs
, x
, y
, w
, h
);
890 static void vnc_copy(VncState
*vs
, int src_x
, int src_y
, int dst_x
, int dst_y
, int w
, int h
)
892 /* send bitblit op to the vnc client */
894 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
896 vnc_write_u16(vs
, 1); /* number of rects */
897 vnc_framebuffer_update(vs
, dst_x
, dst_y
, w
, h
, VNC_ENCODING_COPYRECT
);
898 vnc_write_u16(vs
, src_x
);
899 vnc_write_u16(vs
, src_y
);
900 vnc_unlock_output(vs
);
904 static void vnc_dpy_copy(DisplayChangeListener
*dcl
,
905 int src_x
, int src_y
,
906 int dst_x
, int dst_y
, int w
, int h
)
908 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
912 int i
, x
, y
, pitch
, inc
, w_lim
, s
;
916 /* no client connected */
920 vnc_refresh_server_surface(vd
);
921 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
922 if (vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
923 vs
->force_update
= 1;
924 vnc_update_client(vs
, 1, true);
925 /* vs might be free()ed here */
930 /* no client connected */
933 /* do bitblit op on the local surface too */
934 pitch
= vnc_server_fb_stride(vd
);
935 src_row
= vnc_server_fb_ptr(vd
, src_x
, src_y
);
936 dst_row
= vnc_server_fb_ptr(vd
, dst_x
, dst_y
);
941 src_row
+= pitch
* (h
-1);
942 dst_row
+= pitch
* (h
-1);
947 w_lim
= w
- (VNC_DIRTY_PIXELS_PER_BIT
- (dst_x
% VNC_DIRTY_PIXELS_PER_BIT
));
951 w_lim
= w
- (w_lim
% VNC_DIRTY_PIXELS_PER_BIT
);
953 for (i
= 0; i
< h
; i
++) {
954 for (x
= 0; x
<= w_lim
;
955 x
+= s
, src_row
+= cmp_bytes
, dst_row
+= cmp_bytes
) {
957 if ((s
= w
- w_lim
) == 0)
960 s
= (VNC_DIRTY_PIXELS_PER_BIT
-
961 (dst_x
% VNC_DIRTY_PIXELS_PER_BIT
));
964 s
= VNC_DIRTY_PIXELS_PER_BIT
;
966 cmp_bytes
= s
* VNC_SERVER_FB_BYTES
;
967 if (memcmp(src_row
, dst_row
, cmp_bytes
) == 0)
969 memmove(dst_row
, src_row
, cmp_bytes
);
970 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
971 if (!vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
972 set_bit(((x
+ dst_x
) / VNC_DIRTY_PIXELS_PER_BIT
),
977 src_row
+= pitch
- w
* VNC_SERVER_FB_BYTES
;
978 dst_row
+= pitch
- w
* VNC_SERVER_FB_BYTES
;
982 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
983 if (vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
984 vnc_copy(vs
, src_x
, src_y
, dst_x
, dst_y
, w
, h
);
989 static void vnc_mouse_set(DisplayChangeListener
*dcl
,
990 int x
, int y
, int visible
)
992 /* can we ask the client(s) to move the pointer ??? */
995 static int vnc_cursor_define(VncState
*vs
)
997 QEMUCursor
*c
= vs
->vd
->cursor
;
1000 if (vnc_has_feature(vs
, VNC_FEATURE_RICH_CURSOR
)) {
1001 vnc_lock_output(vs
);
1002 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1003 vnc_write_u8(vs
, 0); /* padding */
1004 vnc_write_u16(vs
, 1); /* # of rects */
1005 vnc_framebuffer_update(vs
, c
->hot_x
, c
->hot_y
, c
->width
, c
->height
,
1006 VNC_ENCODING_RICH_CURSOR
);
1007 isize
= c
->width
* c
->height
* vs
->client_pf
.bytes_per_pixel
;
1008 vnc_write_pixels_generic(vs
, c
->data
, isize
);
1009 vnc_write(vs
, vs
->vd
->cursor_mask
, vs
->vd
->cursor_msize
);
1010 vnc_unlock_output(vs
);
1016 static void vnc_dpy_cursor_define(DisplayChangeListener
*dcl
,
1019 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
1022 cursor_put(vd
->cursor
);
1023 g_free(vd
->cursor_mask
);
1026 cursor_get(vd
->cursor
);
1027 vd
->cursor_msize
= cursor_get_mono_bpl(c
) * c
->height
;
1028 vd
->cursor_mask
= g_malloc0(vd
->cursor_msize
);
1029 cursor_get_mono_mask(c
, 0, vd
->cursor_mask
);
1031 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
1032 vnc_cursor_define(vs
);
1036 static int find_and_clear_dirty_height(VncState
*vs
,
1037 int y
, int last_x
, int x
, int height
)
1041 for (h
= 1; h
< (height
- y
); h
++) {
1042 if (!test_bit(last_x
, vs
->dirty
[y
+ h
])) {
1045 bitmap_clear(vs
->dirty
[y
+ h
], last_x
, x
- last_x
);
1051 static int vnc_update_client(VncState
*vs
, int has_dirty
, bool sync
)
1053 if (vs
->disconnecting
) {
1054 vnc_disconnect_finish(vs
);
1058 vs
->has_dirty
+= has_dirty
;
1059 if (vs
->need_update
&& !vs
->disconnecting
) {
1060 VncDisplay
*vd
= vs
->vd
;
1066 if (vs
->output
.offset
&& !vs
->audio_cap
&& !vs
->force_update
)
1067 /* kernel send buffers are full -> drop frames to throttle */
1070 if (!vs
->has_dirty
&& !vs
->audio_cap
&& !vs
->force_update
)
1074 * Send screen updates to the vnc client using the server
1075 * surface and server dirty map. guest surface updates
1076 * happening in parallel don't disturb us, the next pass will
1077 * send them to the client.
1079 job
= vnc_job_new(vs
);
1081 height
= pixman_image_get_height(vd
->server
);
1082 width
= pixman_image_get_width(vd
->server
);
1088 unsigned long offset
= find_next_bit((unsigned long *) &vs
->dirty
,
1089 height
* VNC_DIRTY_BPL(vs
),
1090 y
* VNC_DIRTY_BPL(vs
));
1091 if (offset
== height
* VNC_DIRTY_BPL(vs
)) {
1092 /* no more dirty bits */
1095 y
= offset
/ VNC_DIRTY_BPL(vs
);
1096 x
= offset
% VNC_DIRTY_BPL(vs
);
1097 x2
= find_next_zero_bit((unsigned long *) &vs
->dirty
[y
],
1098 VNC_DIRTY_BPL(vs
), x
);
1099 bitmap_clear(vs
->dirty
[y
], x
, x2
- x
);
1100 h
= find_and_clear_dirty_height(vs
, y
, x
, x2
, height
);
1101 x2
= MIN(x2
, width
/ VNC_DIRTY_PIXELS_PER_BIT
);
1103 n
+= vnc_job_add_rect(job
, x
* VNC_DIRTY_PIXELS_PER_BIT
, y
,
1104 (x2
- x
) * VNC_DIRTY_PIXELS_PER_BIT
, h
);
1106 if (!x
&& x2
== width
/ VNC_DIRTY_PIXELS_PER_BIT
) {
1118 vs
->force_update
= 0;
1123 if (vs
->disconnecting
) {
1124 vnc_disconnect_finish(vs
);
1133 static void audio_capture_notify(void *opaque
, audcnotification_e cmd
)
1135 VncState
*vs
= opaque
;
1138 case AUD_CNOTIFY_DISABLE
:
1139 vnc_lock_output(vs
);
1140 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1141 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1142 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_END
);
1143 vnc_unlock_output(vs
);
1147 case AUD_CNOTIFY_ENABLE
:
1148 vnc_lock_output(vs
);
1149 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1150 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1151 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN
);
1152 vnc_unlock_output(vs
);
1158 static void audio_capture_destroy(void *opaque
)
1162 static void audio_capture(void *opaque
, void *buf
, int size
)
1164 VncState
*vs
= opaque
;
1166 vnc_lock_output(vs
);
1167 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1168 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1169 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_DATA
);
1170 vnc_write_u32(vs
, size
);
1171 vnc_write(vs
, buf
, size
);
1172 vnc_unlock_output(vs
);
1176 static void audio_add(VncState
*vs
)
1178 struct audio_capture_ops ops
;
1180 if (vs
->audio_cap
) {
1181 error_report("audio already running");
1185 ops
.notify
= audio_capture_notify
;
1186 ops
.destroy
= audio_capture_destroy
;
1187 ops
.capture
= audio_capture
;
1189 vs
->audio_cap
= AUD_add_capture(&vs
->as
, &ops
, vs
);
1190 if (!vs
->audio_cap
) {
1191 error_report("Failed to add audio capture");
1195 static void audio_del(VncState
*vs
)
1197 if (vs
->audio_cap
) {
1198 AUD_del_capture(vs
->audio_cap
, vs
);
1199 vs
->audio_cap
= NULL
;
1203 static void vnc_disconnect_start(VncState
*vs
)
1205 if (vs
->disconnecting
) {
1208 vnc_set_share_mode(vs
, VNC_SHARE_MODE_DISCONNECTED
);
1210 g_source_remove(vs
->ioc_tag
);
1212 qio_channel_close(vs
->ioc
, NULL
);
1213 vs
->disconnecting
= TRUE
;
1216 void vnc_disconnect_finish(VncState
*vs
)
1220 vnc_jobs_join(vs
); /* Wait encoding jobs */
1222 vnc_lock_output(vs
);
1223 vnc_qmp_event(vs
, QAPI_EVENT_VNC_DISCONNECTED
);
1225 buffer_free(&vs
->input
);
1226 buffer_free(&vs
->output
);
1228 qapi_free_VncClientInfo(vs
->info
);
1231 vnc_tight_clear(vs
);
1234 #ifdef CONFIG_VNC_SASL
1235 vnc_sasl_client_cleanup(vs
);
1236 #endif /* CONFIG_VNC_SASL */
1238 vnc_release_modifiers(vs
);
1240 if (vs
->mouse_mode_notifier
.notify
!= NULL
) {
1241 qemu_remove_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
1243 QTAILQ_REMOVE(&vs
->vd
->clients
, vs
, next
);
1244 if (QTAILQ_EMPTY(&vs
->vd
->clients
)) {
1245 /* last client gone */
1246 vnc_update_server_surface(vs
->vd
);
1249 vnc_unlock_output(vs
);
1251 qemu_mutex_destroy(&vs
->output_mutex
);
1252 if (vs
->bh
!= NULL
) {
1253 qemu_bh_delete(vs
->bh
);
1255 buffer_free(&vs
->jobs_buffer
);
1257 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
1258 g_free(vs
->lossy_rect
[i
]);
1260 g_free(vs
->lossy_rect
);
1262 object_unref(OBJECT(vs
->ioc
));
1264 object_unref(OBJECT(vs
->sioc
));
1269 ssize_t
vnc_client_io_error(VncState
*vs
, ssize_t ret
, Error
**errp
)
1273 VNC_DEBUG("Closing down client sock: EOF\n");
1274 vnc_disconnect_start(vs
);
1275 } else if (ret
!= QIO_CHANNEL_ERR_BLOCK
) {
1276 VNC_DEBUG("Closing down client sock: ret %zd (%s)\n",
1277 ret
, errp
? error_get_pretty(*errp
) : "Unknown");
1278 vnc_disconnect_start(vs
);
1291 void vnc_client_error(VncState
*vs
)
1293 VNC_DEBUG("Closing down client sock: protocol error\n");
1294 vnc_disconnect_start(vs
);
1299 * Called to write a chunk of data to the client socket. The data may
1300 * be the raw data, or may have already been encoded by SASL.
1301 * The data will be written either straight onto the socket, or
1302 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1304 * NB, it is theoretically possible to have 2 layers of encryption,
1305 * both SASL, and this TLS layer. It is highly unlikely in practice
1306 * though, since SASL encryption will typically be a no-op if TLS
1309 * Returns the number of bytes written, which may be less than
1310 * the requested 'datalen' if the socket would block. Returns
1311 * -1 on error, and disconnects the client socket.
1313 ssize_t
vnc_client_write_buf(VncState
*vs
, const uint8_t *data
, size_t datalen
)
1317 ret
= qio_channel_write(
1318 vs
->ioc
, (const char *)data
, datalen
, &err
);
1319 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data
, datalen
, ret
);
1320 return vnc_client_io_error(vs
, ret
, &err
);
1325 * Called to write buffered data to the client socket, when not
1326 * using any SASL SSF encryption layers. Will write as much data
1327 * as possible without blocking. If all buffered data is written,
1328 * will switch the FD poll() handler back to read monitoring.
1330 * Returns the number of bytes written, which may be less than
1331 * the buffered output data if the socket would block. Returns
1332 * -1 on error, and disconnects the client socket.
1334 static ssize_t
vnc_client_write_plain(VncState
*vs
)
1338 #ifdef CONFIG_VNC_SASL
1339 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1340 vs
->output
.buffer
, vs
->output
.capacity
, vs
->output
.offset
,
1341 vs
->sasl
.waitWriteSSF
);
1343 if (vs
->sasl
.conn
&&
1345 vs
->sasl
.waitWriteSSF
) {
1346 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->sasl
.waitWriteSSF
);
1348 vs
->sasl
.waitWriteSSF
-= ret
;
1350 #endif /* CONFIG_VNC_SASL */
1351 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->output
.offset
);
1355 buffer_advance(&vs
->output
, ret
);
1357 if (vs
->output
.offset
== 0) {
1359 g_source_remove(vs
->ioc_tag
);
1361 vs
->ioc_tag
= qio_channel_add_watch(
1362 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1370 * First function called whenever there is data to be written to
1371 * the client socket. Will delegate actual work according to whether
1372 * SASL SSF layers are enabled (thus requiring encryption calls)
1374 static void vnc_client_write_locked(VncState
*vs
)
1376 #ifdef CONFIG_VNC_SASL
1377 if (vs
->sasl
.conn
&&
1379 !vs
->sasl
.waitWriteSSF
) {
1380 vnc_client_write_sasl(vs
);
1382 #endif /* CONFIG_VNC_SASL */
1384 vnc_client_write_plain(vs
);
1388 static void vnc_client_write(VncState
*vs
)
1391 vnc_lock_output(vs
);
1392 if (vs
->output
.offset
) {
1393 vnc_client_write_locked(vs
);
1394 } else if (vs
->ioc
!= NULL
) {
1396 g_source_remove(vs
->ioc_tag
);
1398 vs
->ioc_tag
= qio_channel_add_watch(
1399 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1401 vnc_unlock_output(vs
);
1404 void vnc_read_when(VncState
*vs
, VncReadEvent
*func
, size_t expecting
)
1406 vs
->read_handler
= func
;
1407 vs
->read_handler_expect
= expecting
;
1412 * Called to read a chunk of data from the client socket. The data may
1413 * be the raw data, or may need to be further decoded by SASL.
1414 * The data will be read either straight from to the socket, or
1415 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1417 * NB, it is theoretically possible to have 2 layers of encryption,
1418 * both SASL, and this TLS layer. It is highly unlikely in practice
1419 * though, since SASL encryption will typically be a no-op if TLS
1422 * Returns the number of bytes read, which may be less than
1423 * the requested 'datalen' if the socket would block. Returns
1424 * -1 on error, and disconnects the client socket.
1426 ssize_t
vnc_client_read_buf(VncState
*vs
, uint8_t *data
, size_t datalen
)
1430 ret
= qio_channel_read(
1431 vs
->ioc
, (char *)data
, datalen
, &err
);
1432 VNC_DEBUG("Read wire %p %zd -> %ld\n", data
, datalen
, ret
);
1433 return vnc_client_io_error(vs
, ret
, &err
);
1438 * Called to read data from the client socket to the input buffer,
1439 * when not using any SASL SSF encryption layers. Will read as much
1440 * data as possible without blocking.
1442 * Returns the number of bytes read. Returns -1 on error, and
1443 * disconnects the client socket.
1445 static ssize_t
vnc_client_read_plain(VncState
*vs
)
1448 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1449 vs
->input
.buffer
, vs
->input
.capacity
, vs
->input
.offset
);
1450 buffer_reserve(&vs
->input
, 4096);
1451 ret
= vnc_client_read_buf(vs
, buffer_end(&vs
->input
), 4096);
1454 vs
->input
.offset
+= ret
;
1458 static void vnc_jobs_bh(void *opaque
)
1460 VncState
*vs
= opaque
;
1462 vnc_jobs_consume_buffer(vs
);
1466 * First function called whenever there is more data to be read from
1467 * the client socket. Will delegate actual work according to whether
1468 * SASL SSF layers are enabled (thus requiring decryption calls)
1469 * Returns 0 on success, -1 if client disconnected
1471 static int vnc_client_read(VncState
*vs
)
1475 #ifdef CONFIG_VNC_SASL
1476 if (vs
->sasl
.conn
&& vs
->sasl
.runSSF
)
1477 ret
= vnc_client_read_sasl(vs
);
1479 #endif /* CONFIG_VNC_SASL */
1480 ret
= vnc_client_read_plain(vs
);
1482 if (vs
->disconnecting
) {
1483 vnc_disconnect_finish(vs
);
1489 while (vs
->read_handler
&& vs
->input
.offset
>= vs
->read_handler_expect
) {
1490 size_t len
= vs
->read_handler_expect
;
1493 ret
= vs
->read_handler(vs
, vs
->input
.buffer
, len
);
1494 if (vs
->disconnecting
) {
1495 vnc_disconnect_finish(vs
);
1500 buffer_advance(&vs
->input
, len
);
1502 vs
->read_handler_expect
= ret
;
1508 gboolean
vnc_client_io(QIOChannel
*ioc G_GNUC_UNUSED
,
1509 GIOCondition condition
, void *opaque
)
1511 VncState
*vs
= opaque
;
1512 if (condition
& G_IO_IN
) {
1513 if (vnc_client_read(vs
) < 0) {
1517 if (condition
& G_IO_OUT
) {
1518 vnc_client_write(vs
);
1524 void vnc_write(VncState
*vs
, const void *data
, size_t len
)
1526 buffer_reserve(&vs
->output
, len
);
1528 if (vs
->ioc
!= NULL
&& buffer_empty(&vs
->output
)) {
1530 g_source_remove(vs
->ioc_tag
);
1532 vs
->ioc_tag
= qio_channel_add_watch(
1533 vs
->ioc
, G_IO_IN
| G_IO_OUT
, vnc_client_io
, vs
, NULL
);
1536 buffer_append(&vs
->output
, data
, len
);
1539 void vnc_write_s32(VncState
*vs
, int32_t value
)
1541 vnc_write_u32(vs
, *(uint32_t *)&value
);
1544 void vnc_write_u32(VncState
*vs
, uint32_t value
)
1548 buf
[0] = (value
>> 24) & 0xFF;
1549 buf
[1] = (value
>> 16) & 0xFF;
1550 buf
[2] = (value
>> 8) & 0xFF;
1551 buf
[3] = value
& 0xFF;
1553 vnc_write(vs
, buf
, 4);
1556 void vnc_write_u16(VncState
*vs
, uint16_t value
)
1560 buf
[0] = (value
>> 8) & 0xFF;
1561 buf
[1] = value
& 0xFF;
1563 vnc_write(vs
, buf
, 2);
1566 void vnc_write_u8(VncState
*vs
, uint8_t value
)
1568 vnc_write(vs
, (char *)&value
, 1);
1571 void vnc_flush(VncState
*vs
)
1573 vnc_lock_output(vs
);
1574 if (vs
->ioc
!= NULL
&& vs
->output
.offset
) {
1575 vnc_client_write_locked(vs
);
1577 vnc_unlock_output(vs
);
1580 static uint8_t read_u8(uint8_t *data
, size_t offset
)
1582 return data
[offset
];
1585 static uint16_t read_u16(uint8_t *data
, size_t offset
)
1587 return ((data
[offset
] & 0xFF) << 8) | (data
[offset
+ 1] & 0xFF);
1590 static int32_t read_s32(uint8_t *data
, size_t offset
)
1592 return (int32_t)((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1593 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1596 uint32_t read_u32(uint8_t *data
, size_t offset
)
1598 return ((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1599 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1602 static void client_cut_text(VncState
*vs
, size_t len
, uint8_t *text
)
1606 static void check_pointer_type_change(Notifier
*notifier
, void *data
)
1608 VncState
*vs
= container_of(notifier
, VncState
, mouse_mode_notifier
);
1609 int absolute
= qemu_input_is_absolute();
1611 if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
) && vs
->absolute
!= absolute
) {
1612 vnc_lock_output(vs
);
1613 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1614 vnc_write_u8(vs
, 0);
1615 vnc_write_u16(vs
, 1);
1616 vnc_framebuffer_update(vs
, absolute
, 0,
1617 pixman_image_get_width(vs
->vd
->server
),
1618 pixman_image_get_height(vs
->vd
->server
),
1619 VNC_ENCODING_POINTER_TYPE_CHANGE
);
1620 vnc_unlock_output(vs
);
1623 vs
->absolute
= absolute
;
1626 static void pointer_event(VncState
*vs
, int button_mask
, int x
, int y
)
1628 static uint32_t bmap
[INPUT_BUTTON__MAX
] = {
1629 [INPUT_BUTTON_LEFT
] = 0x01,
1630 [INPUT_BUTTON_MIDDLE
] = 0x02,
1631 [INPUT_BUTTON_RIGHT
] = 0x04,
1632 [INPUT_BUTTON_WHEEL_UP
] = 0x08,
1633 [INPUT_BUTTON_WHEEL_DOWN
] = 0x10,
1635 QemuConsole
*con
= vs
->vd
->dcl
.con
;
1636 int width
= pixman_image_get_width(vs
->vd
->server
);
1637 int height
= pixman_image_get_height(vs
->vd
->server
);
1639 if (vs
->last_bmask
!= button_mask
) {
1640 qemu_input_update_buttons(con
, bmap
, vs
->last_bmask
, button_mask
);
1641 vs
->last_bmask
= button_mask
;
1645 qemu_input_queue_abs(con
, INPUT_AXIS_X
, x
, width
);
1646 qemu_input_queue_abs(con
, INPUT_AXIS_Y
, y
, height
);
1647 } else if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
)) {
1648 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- 0x7FFF);
1649 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- 0x7FFF);
1651 if (vs
->last_x
!= -1) {
1652 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- vs
->last_x
);
1653 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- vs
->last_y
);
1658 qemu_input_event_sync();
1661 static void reset_keys(VncState
*vs
)
1664 for(i
= 0; i
< 256; i
++) {
1665 if (vs
->modifiers_state
[i
]) {
1666 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, i
, false);
1667 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1668 vs
->modifiers_state
[i
] = 0;
1673 static void press_key(VncState
*vs
, int keysym
)
1675 int keycode
= keysym2scancode(vs
->vd
->kbd_layout
, keysym
) & SCANCODE_KEYMASK
;
1676 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, true);
1677 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1678 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1679 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1682 static void vnc_led_state_change(VncState
*vs
)
1684 if (!vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
)) {
1688 vnc_lock_output(vs
);
1689 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1690 vnc_write_u8(vs
, 0);
1691 vnc_write_u16(vs
, 1);
1692 vnc_framebuffer_update(vs
, 0, 0, 1, 1, VNC_ENCODING_LED_STATE
);
1693 vnc_write_u8(vs
, vs
->vd
->ledstate
);
1694 vnc_unlock_output(vs
);
1698 static void kbd_leds(void *opaque
, int ledstate
)
1700 VncDisplay
*vd
= opaque
;
1703 trace_vnc_key_guest_leds((ledstate
& QEMU_CAPS_LOCK_LED
),
1704 (ledstate
& QEMU_NUM_LOCK_LED
),
1705 (ledstate
& QEMU_SCROLL_LOCK_LED
));
1707 if (ledstate
== vd
->ledstate
) {
1711 vd
->ledstate
= ledstate
;
1713 QTAILQ_FOREACH(client
, &vd
->clients
, next
) {
1714 vnc_led_state_change(client
);
1718 static void do_key_event(VncState
*vs
, int down
, int keycode
, int sym
)
1720 /* QEMU console switch */
1722 case 0x2a: /* Left Shift */
1723 case 0x36: /* Right Shift */
1724 case 0x1d: /* Left CTRL */
1725 case 0x9d: /* Right CTRL */
1726 case 0x38: /* Left ALT */
1727 case 0xb8: /* Right ALT */
1729 vs
->modifiers_state
[keycode
] = 1;
1731 vs
->modifiers_state
[keycode
] = 0;
1733 case 0x02 ... 0x0a: /* '1' to '9' keys */
1734 if (vs
->vd
->dcl
.con
== NULL
&&
1735 down
&& vs
->modifiers_state
[0x1d] && vs
->modifiers_state
[0x38]) {
1736 /* Reset the modifiers sent to the current console */
1738 console_select(keycode
- 0x02);
1742 case 0x3a: /* CapsLock */
1743 case 0x45: /* NumLock */
1745 vs
->modifiers_state
[keycode
] ^= 1;
1749 /* Turn off the lock state sync logic if the client support the led
1752 if (down
&& vs
->vd
->lock_key_sync
&&
1753 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1754 keycode_is_keypad(vs
->vd
->kbd_layout
, keycode
)) {
1755 /* If the numlock state needs to change then simulate an additional
1756 keypress before sending this one. This will happen if the user
1757 toggles numlock away from the VNC window.
1759 if (keysym_is_numlock(vs
->vd
->kbd_layout
, sym
& 0xFFFF)) {
1760 if (!vs
->modifiers_state
[0x45]) {
1761 trace_vnc_key_sync_numlock(true);
1762 vs
->modifiers_state
[0x45] = 1;
1763 press_key(vs
, 0xff7f);
1766 if (vs
->modifiers_state
[0x45]) {
1767 trace_vnc_key_sync_numlock(false);
1768 vs
->modifiers_state
[0x45] = 0;
1769 press_key(vs
, 0xff7f);
1774 if (down
&& vs
->vd
->lock_key_sync
&&
1775 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1776 ((sym
>= 'A' && sym
<= 'Z') || (sym
>= 'a' && sym
<= 'z'))) {
1777 /* If the capslock state needs to change then simulate an additional
1778 keypress before sending this one. This will happen if the user
1779 toggles capslock away from the VNC window.
1781 int uppercase
= !!(sym
>= 'A' && sym
<= 'Z');
1782 int shift
= !!(vs
->modifiers_state
[0x2a] | vs
->modifiers_state
[0x36]);
1783 int capslock
= !!(vs
->modifiers_state
[0x3a]);
1785 if (uppercase
== shift
) {
1786 trace_vnc_key_sync_capslock(false);
1787 vs
->modifiers_state
[0x3a] = 0;
1788 press_key(vs
, 0xffe5);
1791 if (uppercase
!= shift
) {
1792 trace_vnc_key_sync_capslock(true);
1793 vs
->modifiers_state
[0x3a] = 1;
1794 press_key(vs
, 0xffe5);
1799 if (qemu_console_is_graphic(NULL
)) {
1800 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, down
);
1801 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1803 bool numlock
= vs
->modifiers_state
[0x45];
1804 bool control
= (vs
->modifiers_state
[0x1d] ||
1805 vs
->modifiers_state
[0x9d]);
1806 /* QEMU console emulation */
1809 case 0x2a: /* Left Shift */
1810 case 0x36: /* Right Shift */
1811 case 0x1d: /* Left CTRL */
1812 case 0x9d: /* Right CTRL */
1813 case 0x38: /* Left ALT */
1814 case 0xb8: /* Right ALT */
1817 kbd_put_keysym(QEMU_KEY_UP
);
1820 kbd_put_keysym(QEMU_KEY_DOWN
);
1823 kbd_put_keysym(QEMU_KEY_LEFT
);
1826 kbd_put_keysym(QEMU_KEY_RIGHT
);
1829 kbd_put_keysym(QEMU_KEY_DELETE
);
1832 kbd_put_keysym(QEMU_KEY_HOME
);
1835 kbd_put_keysym(QEMU_KEY_END
);
1838 kbd_put_keysym(QEMU_KEY_PAGEUP
);
1841 kbd_put_keysym(QEMU_KEY_PAGEDOWN
);
1845 kbd_put_keysym(numlock
? '7' : QEMU_KEY_HOME
);
1848 kbd_put_keysym(numlock
? '8' : QEMU_KEY_UP
);
1851 kbd_put_keysym(numlock
? '9' : QEMU_KEY_PAGEUP
);
1854 kbd_put_keysym(numlock
? '4' : QEMU_KEY_LEFT
);
1857 kbd_put_keysym('5');
1860 kbd_put_keysym(numlock
? '6' : QEMU_KEY_RIGHT
);
1863 kbd_put_keysym(numlock
? '1' : QEMU_KEY_END
);
1866 kbd_put_keysym(numlock
? '2' : QEMU_KEY_DOWN
);
1869 kbd_put_keysym(numlock
? '3' : QEMU_KEY_PAGEDOWN
);
1872 kbd_put_keysym('0');
1875 kbd_put_keysym(numlock
? '.' : QEMU_KEY_DELETE
);
1879 kbd_put_keysym('/');
1882 kbd_put_keysym('*');
1885 kbd_put_keysym('-');
1888 kbd_put_keysym('+');
1891 kbd_put_keysym('\n');
1896 kbd_put_keysym(sym
& 0x1f);
1898 kbd_put_keysym(sym
);
1906 static void vnc_release_modifiers(VncState
*vs
)
1908 static const int keycodes
[] = {
1909 /* shift, control, alt keys, both left & right */
1910 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1914 if (!qemu_console_is_graphic(NULL
)) {
1917 for (i
= 0; i
< ARRAY_SIZE(keycodes
); i
++) {
1918 keycode
= keycodes
[i
];
1919 if (!vs
->modifiers_state
[keycode
]) {
1922 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1923 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1927 static const char *code2name(int keycode
)
1929 return QKeyCode_lookup
[qemu_input_key_number_to_qcode(keycode
)];
1932 static void key_event(VncState
*vs
, int down
, uint32_t sym
)
1937 if (lsym
>= 'A' && lsym
<= 'Z' && qemu_console_is_graphic(NULL
)) {
1938 lsym
= lsym
- 'A' + 'a';
1941 keycode
= keysym2scancode(vs
->vd
->kbd_layout
, lsym
& 0xFFFF) & SCANCODE_KEYMASK
;
1942 trace_vnc_key_event_map(down
, sym
, keycode
, code2name(keycode
));
1943 do_key_event(vs
, down
, keycode
, sym
);
1946 static void ext_key_event(VncState
*vs
, int down
,
1947 uint32_t sym
, uint16_t keycode
)
1949 /* if the user specifies a keyboard layout, always use it */
1950 if (keyboard_layout
) {
1951 key_event(vs
, down
, sym
);
1953 trace_vnc_key_event_ext(down
, sym
, keycode
, code2name(keycode
));
1954 do_key_event(vs
, down
, keycode
, sym
);
1958 static void framebuffer_update_request(VncState
*vs
, int incremental
,
1959 int x
, int y
, int w
, int h
)
1961 vs
->need_update
= 1;
1967 vs
->force_update
= 1;
1968 vnc_set_area_dirty(vs
->dirty
, vs
->vd
, x
, y
, w
, h
);
1971 static void send_ext_key_event_ack(VncState
*vs
)
1973 vnc_lock_output(vs
);
1974 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1975 vnc_write_u8(vs
, 0);
1976 vnc_write_u16(vs
, 1);
1977 vnc_framebuffer_update(vs
, 0, 0,
1978 pixman_image_get_width(vs
->vd
->server
),
1979 pixman_image_get_height(vs
->vd
->server
),
1980 VNC_ENCODING_EXT_KEY_EVENT
);
1981 vnc_unlock_output(vs
);
1985 static void send_ext_audio_ack(VncState
*vs
)
1987 vnc_lock_output(vs
);
1988 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1989 vnc_write_u8(vs
, 0);
1990 vnc_write_u16(vs
, 1);
1991 vnc_framebuffer_update(vs
, 0, 0,
1992 pixman_image_get_width(vs
->vd
->server
),
1993 pixman_image_get_height(vs
->vd
->server
),
1994 VNC_ENCODING_AUDIO
);
1995 vnc_unlock_output(vs
);
1999 static void set_encodings(VncState
*vs
, int32_t *encodings
, size_t n_encodings
)
2002 unsigned int enc
= 0;
2005 vs
->vnc_encoding
= 0;
2006 vs
->tight
.compression
= 9;
2007 vs
->tight
.quality
= -1; /* Lossless by default */
2011 * Start from the end because the encodings are sent in order of preference.
2012 * This way the preferred encoding (first encoding defined in the array)
2013 * will be set at the end of the loop.
2015 for (i
= n_encodings
- 1; i
>= 0; i
--) {
2018 case VNC_ENCODING_RAW
:
2019 vs
->vnc_encoding
= enc
;
2021 case VNC_ENCODING_COPYRECT
:
2022 vs
->features
|= VNC_FEATURE_COPYRECT_MASK
;
2024 case VNC_ENCODING_HEXTILE
:
2025 vs
->features
|= VNC_FEATURE_HEXTILE_MASK
;
2026 vs
->vnc_encoding
= enc
;
2028 case VNC_ENCODING_TIGHT
:
2029 vs
->features
|= VNC_FEATURE_TIGHT_MASK
;
2030 vs
->vnc_encoding
= enc
;
2032 #ifdef CONFIG_VNC_PNG
2033 case VNC_ENCODING_TIGHT_PNG
:
2034 vs
->features
|= VNC_FEATURE_TIGHT_PNG_MASK
;
2035 vs
->vnc_encoding
= enc
;
2038 case VNC_ENCODING_ZLIB
:
2039 vs
->features
|= VNC_FEATURE_ZLIB_MASK
;
2040 vs
->vnc_encoding
= enc
;
2042 case VNC_ENCODING_ZRLE
:
2043 vs
->features
|= VNC_FEATURE_ZRLE_MASK
;
2044 vs
->vnc_encoding
= enc
;
2046 case VNC_ENCODING_ZYWRLE
:
2047 vs
->features
|= VNC_FEATURE_ZYWRLE_MASK
;
2048 vs
->vnc_encoding
= enc
;
2050 case VNC_ENCODING_DESKTOPRESIZE
:
2051 vs
->features
|= VNC_FEATURE_RESIZE_MASK
;
2053 case VNC_ENCODING_POINTER_TYPE_CHANGE
:
2054 vs
->features
|= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK
;
2056 case VNC_ENCODING_RICH_CURSOR
:
2057 vs
->features
|= VNC_FEATURE_RICH_CURSOR_MASK
;
2058 if (vs
->vd
->cursor
) {
2059 vnc_cursor_define(vs
);
2062 case VNC_ENCODING_EXT_KEY_EVENT
:
2063 send_ext_key_event_ack(vs
);
2065 case VNC_ENCODING_AUDIO
:
2066 send_ext_audio_ack(vs
);
2068 case VNC_ENCODING_WMVi
:
2069 vs
->features
|= VNC_FEATURE_WMVI_MASK
;
2071 case VNC_ENCODING_LED_STATE
:
2072 vs
->features
|= VNC_FEATURE_LED_STATE_MASK
;
2074 case VNC_ENCODING_COMPRESSLEVEL0
... VNC_ENCODING_COMPRESSLEVEL0
+ 9:
2075 vs
->tight
.compression
= (enc
& 0x0F);
2077 case VNC_ENCODING_QUALITYLEVEL0
... VNC_ENCODING_QUALITYLEVEL0
+ 9:
2078 if (vs
->vd
->lossy
) {
2079 vs
->tight
.quality
= (enc
& 0x0F);
2083 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i
, enc
, enc
);
2087 vnc_desktop_resize(vs
);
2088 check_pointer_type_change(&vs
->mouse_mode_notifier
, NULL
);
2089 vnc_led_state_change(vs
);
2092 static void set_pixel_conversion(VncState
*vs
)
2094 pixman_format_code_t fmt
= qemu_pixman_get_format(&vs
->client_pf
);
2096 if (fmt
== VNC_SERVER_FB_FORMAT
) {
2097 vs
->write_pixels
= vnc_write_pixels_copy
;
2098 vnc_hextile_set_pixel_conversion(vs
, 0);
2100 vs
->write_pixels
= vnc_write_pixels_generic
;
2101 vnc_hextile_set_pixel_conversion(vs
, 1);
2105 static void send_color_map(VncState
*vs
)
2109 vnc_write_u8(vs
, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES
);
2110 vnc_write_u8(vs
, 0); /* padding */
2111 vnc_write_u16(vs
, 0); /* first color */
2112 vnc_write_u16(vs
, 256); /* # of colors */
2114 for (i
= 0; i
< 256; i
++) {
2115 PixelFormat
*pf
= &vs
->client_pf
;
2117 vnc_write_u16(vs
, (((i
>> pf
->rshift
) & pf
->rmax
) << (16 - pf
->rbits
)));
2118 vnc_write_u16(vs
, (((i
>> pf
->gshift
) & pf
->gmax
) << (16 - pf
->gbits
)));
2119 vnc_write_u16(vs
, (((i
>> pf
->bshift
) & pf
->bmax
) << (16 - pf
->bbits
)));
2123 static void set_pixel_format(VncState
*vs
, int bits_per_pixel
,
2124 int big_endian_flag
, int true_color_flag
,
2125 int red_max
, int green_max
, int blue_max
,
2126 int red_shift
, int green_shift
, int blue_shift
)
2128 if (!true_color_flag
) {
2129 /* Expose a reasonable default 256 color map */
2139 switch (bits_per_pixel
) {
2145 vnc_client_error(vs
);
2149 vs
->client_pf
.rmax
= red_max
? red_max
: 0xFF;
2150 vs
->client_pf
.rbits
= hweight_long(red_max
);
2151 vs
->client_pf
.rshift
= red_shift
;
2152 vs
->client_pf
.rmask
= red_max
<< red_shift
;
2153 vs
->client_pf
.gmax
= green_max
? green_max
: 0xFF;
2154 vs
->client_pf
.gbits
= hweight_long(green_max
);
2155 vs
->client_pf
.gshift
= green_shift
;
2156 vs
->client_pf
.gmask
= green_max
<< green_shift
;
2157 vs
->client_pf
.bmax
= blue_max
? blue_max
: 0xFF;
2158 vs
->client_pf
.bbits
= hweight_long(blue_max
);
2159 vs
->client_pf
.bshift
= blue_shift
;
2160 vs
->client_pf
.bmask
= blue_max
<< blue_shift
;
2161 vs
->client_pf
.bits_per_pixel
= bits_per_pixel
;
2162 vs
->client_pf
.bytes_per_pixel
= bits_per_pixel
/ 8;
2163 vs
->client_pf
.depth
= bits_per_pixel
== 32 ? 24 : bits_per_pixel
;
2164 vs
->client_be
= big_endian_flag
;
2166 if (!true_color_flag
) {
2170 set_pixel_conversion(vs
);
2172 graphic_hw_invalidate(vs
->vd
->dcl
.con
);
2173 graphic_hw_update(vs
->vd
->dcl
.con
);
2176 static void pixel_format_message (VncState
*vs
) {
2177 char pad
[3] = { 0, 0, 0 };
2179 vs
->client_pf
= qemu_default_pixelformat(32);
2181 vnc_write_u8(vs
, vs
->client_pf
.bits_per_pixel
); /* bits-per-pixel */
2182 vnc_write_u8(vs
, vs
->client_pf
.depth
); /* depth */
2184 #ifdef HOST_WORDS_BIGENDIAN
2185 vnc_write_u8(vs
, 1); /* big-endian-flag */
2187 vnc_write_u8(vs
, 0); /* big-endian-flag */
2189 vnc_write_u8(vs
, 1); /* true-color-flag */
2190 vnc_write_u16(vs
, vs
->client_pf
.rmax
); /* red-max */
2191 vnc_write_u16(vs
, vs
->client_pf
.gmax
); /* green-max */
2192 vnc_write_u16(vs
, vs
->client_pf
.bmax
); /* blue-max */
2193 vnc_write_u8(vs
, vs
->client_pf
.rshift
); /* red-shift */
2194 vnc_write_u8(vs
, vs
->client_pf
.gshift
); /* green-shift */
2195 vnc_write_u8(vs
, vs
->client_pf
.bshift
); /* blue-shift */
2196 vnc_write(vs
, pad
, 3); /* padding */
2198 vnc_hextile_set_pixel_conversion(vs
, 0);
2199 vs
->write_pixels
= vnc_write_pixels_copy
;
2202 static void vnc_colordepth(VncState
*vs
)
2204 if (vnc_has_feature(vs
, VNC_FEATURE_WMVI
)) {
2205 /* Sending a WMVi message to notify the client*/
2206 vnc_lock_output(vs
);
2207 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2208 vnc_write_u8(vs
, 0);
2209 vnc_write_u16(vs
, 1); /* number of rects */
2210 vnc_framebuffer_update(vs
, 0, 0,
2211 pixman_image_get_width(vs
->vd
->server
),
2212 pixman_image_get_height(vs
->vd
->server
),
2214 pixel_format_message(vs
);
2215 vnc_unlock_output(vs
);
2218 set_pixel_conversion(vs
);
2222 static int protocol_client_msg(VncState
*vs
, uint8_t *data
, size_t len
)
2226 VncDisplay
*vd
= vs
->vd
;
2229 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2233 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT
:
2237 set_pixel_format(vs
, read_u8(data
, 4),
2238 read_u8(data
, 6), read_u8(data
, 7),
2239 read_u16(data
, 8), read_u16(data
, 10),
2240 read_u16(data
, 12), read_u8(data
, 14),
2241 read_u8(data
, 15), read_u8(data
, 16));
2243 case VNC_MSG_CLIENT_SET_ENCODINGS
:
2248 limit
= read_u16(data
, 2);
2250 return 4 + (limit
* 4);
2252 limit
= read_u16(data
, 2);
2254 for (i
= 0; i
< limit
; i
++) {
2255 int32_t val
= read_s32(data
, 4 + (i
* 4));
2256 memcpy(data
+ 4 + (i
* 4), &val
, sizeof(val
));
2259 set_encodings(vs
, (int32_t *)(data
+ 4), limit
);
2261 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST
:
2265 framebuffer_update_request(vs
,
2266 read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4),
2267 read_u16(data
, 6), read_u16(data
, 8));
2269 case VNC_MSG_CLIENT_KEY_EVENT
:
2273 key_event(vs
, read_u8(data
, 1), read_u32(data
, 4));
2275 case VNC_MSG_CLIENT_POINTER_EVENT
:
2279 pointer_event(vs
, read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4));
2281 case VNC_MSG_CLIENT_CUT_TEXT
:
2286 uint32_t dlen
= read_u32(data
, 4);
2287 if (dlen
> (1 << 20)) {
2288 error_report("vnc: client_cut_text msg payload has %u bytes"
2289 " which exceeds our limit of 1MB.", dlen
);
2290 vnc_client_error(vs
);
2298 client_cut_text(vs
, read_u32(data
, 4), data
+ 8);
2300 case VNC_MSG_CLIENT_QEMU
:
2304 switch (read_u8(data
, 1)) {
2305 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT
:
2309 ext_key_event(vs
, read_u16(data
, 2),
2310 read_u32(data
, 4), read_u32(data
, 8));
2312 case VNC_MSG_CLIENT_QEMU_AUDIO
:
2316 switch (read_u16 (data
, 2)) {
2317 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE
:
2320 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE
:
2323 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT
:
2326 switch (read_u8(data
, 4)) {
2327 case 0: vs
->as
.fmt
= AUD_FMT_U8
; break;
2328 case 1: vs
->as
.fmt
= AUD_FMT_S8
; break;
2329 case 2: vs
->as
.fmt
= AUD_FMT_U16
; break;
2330 case 3: vs
->as
.fmt
= AUD_FMT_S16
; break;
2331 case 4: vs
->as
.fmt
= AUD_FMT_U32
; break;
2332 case 5: vs
->as
.fmt
= AUD_FMT_S32
; break;
2334 VNC_DEBUG("Invalid audio format %d\n", read_u8(data
, 4));
2335 vnc_client_error(vs
);
2338 vs
->as
.nchannels
= read_u8(data
, 5);
2339 if (vs
->as
.nchannels
!= 1 && vs
->as
.nchannels
!= 2) {
2340 VNC_DEBUG("Invalid audio channel coount %d\n",
2342 vnc_client_error(vs
);
2345 vs
->as
.freq
= read_u32(data
, 6);
2348 VNC_DEBUG("Invalid audio message %d\n", read_u8(data
, 4));
2349 vnc_client_error(vs
);
2355 VNC_DEBUG("Msg: %d\n", read_u16(data
, 0));
2356 vnc_client_error(vs
);
2361 VNC_DEBUG("Msg: %d\n", data
[0]);
2362 vnc_client_error(vs
);
2366 vnc_read_when(vs
, protocol_client_msg
, 1);
2370 static int protocol_client_init(VncState
*vs
, uint8_t *data
, size_t len
)
2376 mode
= data
[0] ? VNC_SHARE_MODE_SHARED
: VNC_SHARE_MODE_EXCLUSIVE
;
2377 switch (vs
->vd
->share_policy
) {
2378 case VNC_SHARE_POLICY_IGNORE
:
2380 * Ignore the shared flag. Nothing to do here.
2382 * Doesn't conform to the rfb spec but is traditional qemu
2383 * behavior, thus left here as option for compatibility
2387 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
:
2389 * Policy: Allow clients ask for exclusive access.
2391 * Implementation: When a client asks for exclusive access,
2392 * disconnect all others. Shared connects are allowed as long
2393 * as no exclusive connection exists.
2395 * This is how the rfb spec suggests to handle the shared flag.
2397 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2399 QTAILQ_FOREACH(client
, &vs
->vd
->clients
, next
) {
2403 if (client
->share_mode
!= VNC_SHARE_MODE_EXCLUSIVE
&&
2404 client
->share_mode
!= VNC_SHARE_MODE_SHARED
) {
2407 vnc_disconnect_start(client
);
2410 if (mode
== VNC_SHARE_MODE_SHARED
) {
2411 if (vs
->vd
->num_exclusive
> 0) {
2412 vnc_disconnect_start(vs
);
2417 case VNC_SHARE_POLICY_FORCE_SHARED
:
2419 * Policy: Shared connects only.
2420 * Implementation: Disallow clients asking for exclusive access.
2422 * Useful for shared desktop sessions where you don't want
2423 * someone forgetting to say -shared when running the vnc
2424 * client disconnect everybody else.
2426 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2427 vnc_disconnect_start(vs
);
2432 vnc_set_share_mode(vs
, mode
);
2434 if (vs
->vd
->num_shared
> vs
->vd
->connections_limit
) {
2435 vnc_disconnect_start(vs
);
2439 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
2440 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
2441 vnc_write_u16(vs
, vs
->client_width
);
2442 vnc_write_u16(vs
, vs
->client_height
);
2444 pixel_format_message(vs
);
2447 size
= snprintf(buf
, sizeof(buf
), "QEMU (%s)", qemu_name
);
2448 if (size
> sizeof(buf
)) {
2452 size
= snprintf(buf
, sizeof(buf
), "QEMU");
2455 vnc_write_u32(vs
, size
);
2456 vnc_write(vs
, buf
, size
);
2459 vnc_client_cache_auth(vs
);
2460 vnc_qmp_event(vs
, QAPI_EVENT_VNC_INITIALIZED
);
2462 vnc_read_when(vs
, protocol_client_msg
, 1);
2467 void start_client_init(VncState
*vs
)
2469 vnc_read_when(vs
, protocol_client_init
, 1);
2472 static void make_challenge(VncState
*vs
)
2476 srand(time(NULL
)+getpid()+getpid()*987654+rand());
2478 for (i
= 0 ; i
< sizeof(vs
->challenge
) ; i
++)
2479 vs
->challenge
[i
] = (int) (256.0*rand()/(RAND_MAX
+1.0));
2482 static int protocol_client_auth_vnc(VncState
*vs
, uint8_t *data
, size_t len
)
2484 unsigned char response
[VNC_AUTH_CHALLENGE_SIZE
];
2486 unsigned char key
[8];
2487 time_t now
= time(NULL
);
2488 QCryptoCipher
*cipher
= NULL
;
2491 if (!vs
->vd
->password
) {
2492 VNC_DEBUG("No password configured on server");
2495 if (vs
->vd
->expires
< now
) {
2496 VNC_DEBUG("Password is expired");
2500 memcpy(response
, vs
->challenge
, VNC_AUTH_CHALLENGE_SIZE
);
2502 /* Calculate the expected challenge response */
2503 pwlen
= strlen(vs
->vd
->password
);
2504 for (i
=0; i
<sizeof(key
); i
++)
2505 key
[i
] = i
<pwlen
? vs
->vd
->password
[i
] : 0;
2507 cipher
= qcrypto_cipher_new(
2508 QCRYPTO_CIPHER_ALG_DES_RFB
,
2509 QCRYPTO_CIPHER_MODE_ECB
,
2510 key
, G_N_ELEMENTS(key
),
2513 VNC_DEBUG("Cannot initialize cipher %s",
2514 error_get_pretty(err
));
2519 if (qcrypto_cipher_encrypt(cipher
,
2522 VNC_AUTH_CHALLENGE_SIZE
,
2524 VNC_DEBUG("Cannot encrypt challenge %s",
2525 error_get_pretty(err
));
2530 /* Compare expected vs actual challenge response */
2531 if (memcmp(response
, data
, VNC_AUTH_CHALLENGE_SIZE
) != 0) {
2532 VNC_DEBUG("Client challenge response did not match\n");
2535 VNC_DEBUG("Accepting VNC challenge response\n");
2536 vnc_write_u32(vs
, 0); /* Accept auth */
2539 start_client_init(vs
);
2542 qcrypto_cipher_free(cipher
);
2546 vnc_write_u32(vs
, 1); /* Reject auth */
2547 if (vs
->minor
>= 8) {
2548 static const char err
[] = "Authentication failed";
2549 vnc_write_u32(vs
, sizeof(err
));
2550 vnc_write(vs
, err
, sizeof(err
));
2553 vnc_client_error(vs
);
2554 qcrypto_cipher_free(cipher
);
2558 void start_auth_vnc(VncState
*vs
)
2561 /* Send client a 'random' challenge */
2562 vnc_write(vs
, vs
->challenge
, sizeof(vs
->challenge
));
2565 vnc_read_when(vs
, protocol_client_auth_vnc
, sizeof(vs
->challenge
));
2569 static int protocol_client_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2571 /* We only advertise 1 auth scheme at a time, so client
2572 * must pick the one we sent. Verify this */
2573 if (data
[0] != vs
->auth
) { /* Reject auth */
2574 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data
[0]);
2575 vnc_write_u32(vs
, 1);
2576 if (vs
->minor
>= 8) {
2577 static const char err
[] = "Authentication failed";
2578 vnc_write_u32(vs
, sizeof(err
));
2579 vnc_write(vs
, err
, sizeof(err
));
2581 vnc_client_error(vs
);
2582 } else { /* Accept requested auth */
2583 VNC_DEBUG("Client requested auth %d\n", (int)data
[0]);
2586 VNC_DEBUG("Accept auth none\n");
2587 if (vs
->minor
>= 8) {
2588 vnc_write_u32(vs
, 0); /* Accept auth completion */
2591 start_client_init(vs
);
2595 VNC_DEBUG("Start VNC auth\n");
2599 case VNC_AUTH_VENCRYPT
:
2600 VNC_DEBUG("Accept VeNCrypt auth\n");
2601 start_auth_vencrypt(vs
);
2604 #ifdef CONFIG_VNC_SASL
2606 VNC_DEBUG("Accept SASL auth\n");
2607 start_auth_sasl(vs
);
2609 #endif /* CONFIG_VNC_SASL */
2611 default: /* Should not be possible, but just in case */
2612 VNC_DEBUG("Reject auth %d server code bug\n", vs
->auth
);
2613 vnc_write_u8(vs
, 1);
2614 if (vs
->minor
>= 8) {
2615 static const char err
[] = "Authentication failed";
2616 vnc_write_u32(vs
, sizeof(err
));
2617 vnc_write(vs
, err
, sizeof(err
));
2619 vnc_client_error(vs
);
2625 static int protocol_version(VncState
*vs
, uint8_t *version
, size_t len
)
2629 memcpy(local
, version
, 12);
2632 if (sscanf(local
, "RFB %03d.%03d\n", &vs
->major
, &vs
->minor
) != 2) {
2633 VNC_DEBUG("Malformed protocol version %s\n", local
);
2634 vnc_client_error(vs
);
2637 VNC_DEBUG("Client request protocol version %d.%d\n", vs
->major
, vs
->minor
);
2638 if (vs
->major
!= 3 ||
2644 VNC_DEBUG("Unsupported client version\n");
2645 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2647 vnc_client_error(vs
);
2650 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2651 * as equivalent to v3.3 by servers
2653 if (vs
->minor
== 4 || vs
->minor
== 5)
2656 if (vs
->minor
== 3) {
2657 if (vs
->auth
== VNC_AUTH_NONE
) {
2658 VNC_DEBUG("Tell client auth none\n");
2659 vnc_write_u32(vs
, vs
->auth
);
2661 start_client_init(vs
);
2662 } else if (vs
->auth
== VNC_AUTH_VNC
) {
2663 VNC_DEBUG("Tell client VNC auth\n");
2664 vnc_write_u32(vs
, vs
->auth
);
2668 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs
->auth
);
2669 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2671 vnc_client_error(vs
);
2674 VNC_DEBUG("Telling client we support auth %d\n", vs
->auth
);
2675 vnc_write_u8(vs
, 1); /* num auth */
2676 vnc_write_u8(vs
, vs
->auth
);
2677 vnc_read_when(vs
, protocol_client_auth
, 1);
2684 static VncRectStat
*vnc_stat_rect(VncDisplay
*vd
, int x
, int y
)
2686 struct VncSurface
*vs
= &vd
->guest
;
2688 return &vs
->stats
[y
/ VNC_STAT_RECT
][x
/ VNC_STAT_RECT
];
2691 void vnc_sent_lossy_rect(VncState
*vs
, int x
, int y
, int w
, int h
)
2695 w
= (x
+ w
) / VNC_STAT_RECT
;
2696 h
= (y
+ h
) / VNC_STAT_RECT
;
2700 for (j
= y
; j
<= h
; j
++) {
2701 for (i
= x
; i
<= w
; i
++) {
2702 vs
->lossy_rect
[j
][i
] = 1;
2707 static int vnc_refresh_lossy_rect(VncDisplay
*vd
, int x
, int y
)
2710 int sty
= y
/ VNC_STAT_RECT
;
2711 int stx
= x
/ VNC_STAT_RECT
;
2714 y
= y
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2715 x
= x
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2717 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2720 /* kernel send buffers are full -> refresh later */
2721 if (vs
->output
.offset
) {
2725 if (!vs
->lossy_rect
[sty
][stx
]) {
2729 vs
->lossy_rect
[sty
][stx
] = 0;
2730 for (j
= 0; j
< VNC_STAT_RECT
; ++j
) {
2731 bitmap_set(vs
->dirty
[y
+ j
],
2732 x
/ VNC_DIRTY_PIXELS_PER_BIT
,
2733 VNC_STAT_RECT
/ VNC_DIRTY_PIXELS_PER_BIT
);
2741 static int vnc_update_stats(VncDisplay
*vd
, struct timeval
* tv
)
2743 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2744 pixman_image_get_width(vd
->server
));
2745 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2746 pixman_image_get_height(vd
->server
));
2751 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2752 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2753 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2755 rect
->updated
= false;
2759 qemu_timersub(tv
, &VNC_REFRESH_STATS
, &res
);
2761 if (timercmp(&vd
->guest
.last_freq_check
, &res
, >)) {
2764 vd
->guest
.last_freq_check
= *tv
;
2766 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2767 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2768 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2769 int count
= ARRAY_SIZE(rect
->times
);
2770 struct timeval min
, max
;
2772 if (!timerisset(&rect
->times
[count
- 1])) {
2776 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2777 qemu_timersub(tv
, &max
, &res
);
2779 if (timercmp(&res
, &VNC_REFRESH_LOSSY
, >)) {
2781 has_dirty
+= vnc_refresh_lossy_rect(vd
, x
, y
);
2782 memset(rect
->times
, 0, sizeof (rect
->times
));
2786 min
= rect
->times
[rect
->idx
];
2787 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2788 qemu_timersub(&max
, &min
, &res
);
2790 rect
->freq
= res
.tv_sec
+ res
.tv_usec
/ 1000000.;
2791 rect
->freq
/= count
;
2792 rect
->freq
= 1. / rect
->freq
;
2798 double vnc_update_freq(VncState
*vs
, int x
, int y
, int w
, int h
)
2804 x
= (x
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2805 y
= (y
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2807 for (j
= y
; j
<= y
+ h
; j
+= VNC_STAT_RECT
) {
2808 for (i
= x
; i
<= x
+ w
; i
+= VNC_STAT_RECT
) {
2809 total
+= vnc_stat_rect(vs
->vd
, i
, j
)->freq
;
2821 static void vnc_rect_updated(VncDisplay
*vd
, int x
, int y
, struct timeval
* tv
)
2825 rect
= vnc_stat_rect(vd
, x
, y
);
2826 if (rect
->updated
) {
2829 rect
->times
[rect
->idx
] = *tv
;
2830 rect
->idx
= (rect
->idx
+ 1) % ARRAY_SIZE(rect
->times
);
2831 rect
->updated
= true;
2834 static int vnc_refresh_server_surface(VncDisplay
*vd
)
2836 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2837 pixman_image_get_width(vd
->server
));
2838 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2839 pixman_image_get_height(vd
->server
));
2840 int cmp_bytes
, server_stride
, line_bytes
, guest_ll
, guest_stride
, y
= 0;
2841 uint8_t *guest_row0
= NULL
, *server_row0
;
2844 pixman_image_t
*tmpbuf
= NULL
;
2846 struct timeval tv
= { 0, 0 };
2848 if (!vd
->non_adaptive
) {
2849 gettimeofday(&tv
, NULL
);
2850 has_dirty
= vnc_update_stats(vd
, &tv
);
2854 * Walk through the guest dirty map.
2855 * Check and copy modified bits from guest to server surface.
2856 * Update server dirty map.
2858 server_row0
= (uint8_t *)pixman_image_get_data(vd
->server
);
2859 server_stride
= guest_stride
= guest_ll
=
2860 pixman_image_get_stride(vd
->server
);
2861 cmp_bytes
= MIN(VNC_DIRTY_PIXELS_PER_BIT
* VNC_SERVER_FB_BYTES
,
2863 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2864 int width
= pixman_image_get_width(vd
->server
);
2865 tmpbuf
= qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT
, width
);
2868 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd
->guest
.fb
));
2869 guest_row0
= (uint8_t *)pixman_image_get_data(vd
->guest
.fb
);
2870 guest_stride
= pixman_image_get_stride(vd
->guest
.fb
);
2871 guest_ll
= pixman_image_get_width(vd
->guest
.fb
) * ((guest_bpp
+ 7) / 8);
2873 line_bytes
= MIN(server_stride
, guest_ll
);
2877 uint8_t *guest_ptr
, *server_ptr
;
2878 unsigned long offset
= find_next_bit((unsigned long *) &vd
->guest
.dirty
,
2879 height
* VNC_DIRTY_BPL(&vd
->guest
),
2880 y
* VNC_DIRTY_BPL(&vd
->guest
));
2881 if (offset
== height
* VNC_DIRTY_BPL(&vd
->guest
)) {
2882 /* no more dirty bits */
2885 y
= offset
/ VNC_DIRTY_BPL(&vd
->guest
);
2886 x
= offset
% VNC_DIRTY_BPL(&vd
->guest
);
2888 server_ptr
= server_row0
+ y
* server_stride
+ x
* cmp_bytes
;
2890 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2891 qemu_pixman_linebuf_fill(tmpbuf
, vd
->guest
.fb
, width
, 0, y
);
2892 guest_ptr
= (uint8_t *)pixman_image_get_data(tmpbuf
);
2894 guest_ptr
= guest_row0
+ y
* guest_stride
;
2896 guest_ptr
+= x
* cmp_bytes
;
2898 for (; x
< DIV_ROUND_UP(width
, VNC_DIRTY_PIXELS_PER_BIT
);
2899 x
++, guest_ptr
+= cmp_bytes
, server_ptr
+= cmp_bytes
) {
2900 int _cmp_bytes
= cmp_bytes
;
2901 if (!test_and_clear_bit(x
, vd
->guest
.dirty
[y
])) {
2904 if ((x
+ 1) * cmp_bytes
> line_bytes
) {
2905 _cmp_bytes
= line_bytes
- x
* cmp_bytes
;
2907 assert(_cmp_bytes
>= 0);
2908 if (memcmp(server_ptr
, guest_ptr
, _cmp_bytes
) == 0) {
2911 memcpy(server_ptr
, guest_ptr
, _cmp_bytes
);
2912 if (!vd
->non_adaptive
) {
2913 vnc_rect_updated(vd
, x
* VNC_DIRTY_PIXELS_PER_BIT
,
2916 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2917 set_bit(x
, vs
->dirty
[y
]);
2924 qemu_pixman_image_unref(tmpbuf
);
2928 static void vnc_refresh(DisplayChangeListener
*dcl
)
2930 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
2932 int has_dirty
, rects
= 0;
2934 if (QTAILQ_EMPTY(&vd
->clients
)) {
2935 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_MAX
);
2939 graphic_hw_update(vd
->dcl
.con
);
2941 if (vnc_trylock_display(vd
)) {
2942 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2946 has_dirty
= vnc_refresh_server_surface(vd
);
2947 vnc_unlock_display(vd
);
2949 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
2950 rects
+= vnc_update_client(vs
, has_dirty
, false);
2951 /* vs might be free()ed here */
2954 if (has_dirty
&& rects
) {
2955 vd
->dcl
.update_interval
/= 2;
2956 if (vd
->dcl
.update_interval
< VNC_REFRESH_INTERVAL_BASE
) {
2957 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_BASE
;
2960 vd
->dcl
.update_interval
+= VNC_REFRESH_INTERVAL_INC
;
2961 if (vd
->dcl
.update_interval
> VNC_REFRESH_INTERVAL_MAX
) {
2962 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_MAX
;
2967 static void vnc_connect(VncDisplay
*vd
, QIOChannelSocket
*sioc
,
2968 bool skipauth
, bool websocket
)
2970 VncState
*vs
= g_new0(VncState
, 1);
2971 bool first_client
= QTAILQ_EMPTY(&vd
->clients
);
2975 object_ref(OBJECT(vs
->sioc
));
2976 vs
->ioc
= QIO_CHANNEL(sioc
);
2977 object_ref(OBJECT(vs
->ioc
));
2980 buffer_init(&vs
->input
, "vnc-input/%p", sioc
);
2981 buffer_init(&vs
->output
, "vnc-output/%p", sioc
);
2982 buffer_init(&vs
->jobs_buffer
, "vnc-jobs_buffer/%p", sioc
);
2984 buffer_init(&vs
->tight
.tight
, "vnc-tight/%p", sioc
);
2985 buffer_init(&vs
->tight
.zlib
, "vnc-tight-zlib/%p", sioc
);
2986 buffer_init(&vs
->tight
.gradient
, "vnc-tight-gradient/%p", sioc
);
2987 #ifdef CONFIG_VNC_JPEG
2988 buffer_init(&vs
->tight
.jpeg
, "vnc-tight-jpeg/%p", sioc
);
2990 #ifdef CONFIG_VNC_PNG
2991 buffer_init(&vs
->tight
.png
, "vnc-tight-png/%p", sioc
);
2993 buffer_init(&vs
->zlib
.zlib
, "vnc-zlib/%p", sioc
);
2994 buffer_init(&vs
->zrle
.zrle
, "vnc-zrle/%p", sioc
);
2995 buffer_init(&vs
->zrle
.fb
, "vnc-zrle-fb/%p", sioc
);
2996 buffer_init(&vs
->zrle
.zlib
, "vnc-zrle-zlib/%p", sioc
);
2999 vs
->auth
= VNC_AUTH_NONE
;
3000 vs
->subauth
= VNC_AUTH_INVALID
;
3003 vs
->auth
= vd
->ws_auth
;
3004 vs
->subauth
= VNC_AUTH_INVALID
;
3006 vs
->auth
= vd
->auth
;
3007 vs
->subauth
= vd
->subauth
;
3010 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
3011 sioc
, websocket
, vs
->auth
, vs
->subauth
);
3013 vs
->lossy_rect
= g_malloc0(VNC_STAT_ROWS
* sizeof (*vs
->lossy_rect
));
3014 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
3015 vs
->lossy_rect
[i
] = g_new0(uint8_t, VNC_STAT_COLS
);
3018 VNC_DEBUG("New client on socket %p\n", vs
->sioc
);
3019 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
3020 qio_channel_set_blocking(vs
->ioc
, false, NULL
);
3024 vs
->ioc_tag
= qio_channel_add_watch(
3025 vs
->ioc
, G_IO_IN
, vncws_tls_handshake_io
, vs
, NULL
);
3027 vs
->ioc_tag
= qio_channel_add_watch(
3028 vs
->ioc
, G_IO_IN
, vncws_handshake_io
, vs
, NULL
);
3031 vs
->ioc_tag
= qio_channel_add_watch(
3032 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
3035 vnc_client_cache_addr(vs
);
3036 vnc_qmp_event(vs
, QAPI_EVENT_VNC_CONNECTED
);
3037 vnc_set_share_mode(vs
, VNC_SHARE_MODE_CONNECTING
);
3042 vs
->as
.freq
= 44100;
3043 vs
->as
.nchannels
= 2;
3044 vs
->as
.fmt
= AUD_FMT_S16
;
3045 vs
->as
.endianness
= 0;
3047 qemu_mutex_init(&vs
->output_mutex
);
3048 vs
->bh
= qemu_bh_new(vnc_jobs_bh
, vs
);
3050 QTAILQ_INSERT_TAIL(&vd
->clients
, vs
, next
);
3052 vnc_update_server_surface(vd
);
3055 graphic_hw_update(vd
->dcl
.con
);
3057 if (!vs
->websocket
) {
3058 vnc_start_protocol(vs
);
3061 if (vd
->num_connecting
> vd
->connections_limit
) {
3062 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
3063 if (vs
->share_mode
== VNC_SHARE_MODE_CONNECTING
) {
3064 vnc_disconnect_start(vs
);
3071 void vnc_start_protocol(VncState
*vs
)
3073 vnc_write(vs
, "RFB 003.008\n", 12);
3075 vnc_read_when(vs
, protocol_version
, 12);
3077 vs
->mouse_mode_notifier
.notify
= check_pointer_type_change
;
3078 qemu_add_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
3081 static gboolean
vnc_listen_io(QIOChannel
*ioc
,
3082 GIOCondition condition
,
3085 VncDisplay
*vd
= opaque
;
3086 QIOChannelSocket
*sioc
= NULL
;
3089 sioc
= qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc
), &err
);
3091 qio_channel_set_name(QIO_CHANNEL(sioc
),
3092 ioc
!= QIO_CHANNEL(vd
->lsock
) ?
3093 "vnc-ws-server" : "vnc-server");
3094 qio_channel_set_delay(QIO_CHANNEL(sioc
), false);
3095 vnc_connect(vd
, sioc
, false,
3096 ioc
!= QIO_CHANNEL(vd
->lsock
));
3097 object_unref(OBJECT(sioc
));
3099 /* client probably closed connection before we got there */
3106 static const DisplayChangeListenerOps dcl_ops
= {
3108 .dpy_refresh
= vnc_refresh
,
3109 .dpy_gfx_copy
= vnc_dpy_copy
,
3110 .dpy_gfx_update
= vnc_dpy_update
,
3111 .dpy_gfx_switch
= vnc_dpy_switch
,
3112 .dpy_gfx_check_format
= qemu_pixman_check_format
,
3113 .dpy_mouse_set
= vnc_mouse_set
,
3114 .dpy_cursor_define
= vnc_dpy_cursor_define
,
3117 void vnc_display_init(const char *id
)
3121 if (vnc_display_find(id
) != NULL
) {
3124 vd
= g_malloc0(sizeof(*vd
));
3126 vd
->id
= strdup(id
);
3127 QTAILQ_INSERT_TAIL(&vnc_displays
, vd
, next
);
3129 QTAILQ_INIT(&vd
->clients
);
3130 vd
->expires
= TIME_MAX
;
3132 if (keyboard_layout
) {
3133 trace_vnc_key_map_init(keyboard_layout
);
3134 vd
->kbd_layout
= init_keyboard_layout(name2keysym
, keyboard_layout
);
3136 vd
->kbd_layout
= init_keyboard_layout(name2keysym
, "en-us");
3139 if (!vd
->kbd_layout
) {
3143 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3144 vd
->connections_limit
= 32;
3146 qemu_mutex_init(&vd
->mutex
);
3147 vnc_start_worker_thread();
3149 vd
->dcl
.ops
= &dcl_ops
;
3150 register_displaychangelistener(&vd
->dcl
);
3154 static void vnc_display_close(VncDisplay
*vd
)
3159 vd
->is_unix
= false;
3160 if (vd
->lsock
!= NULL
) {
3161 if (vd
->lsock_tag
) {
3162 g_source_remove(vd
->lsock_tag
);
3164 object_unref(OBJECT(vd
->lsock
));
3167 if (vd
->lwebsock
!= NULL
) {
3168 if (vd
->lwebsock_tag
) {
3169 g_source_remove(vd
->lwebsock_tag
);
3171 object_unref(OBJECT(vd
->lwebsock
));
3172 vd
->lwebsock
= NULL
;
3174 vd
->auth
= VNC_AUTH_INVALID
;
3175 vd
->subauth
= VNC_AUTH_INVALID
;
3177 object_unparent(OBJECT(vd
->tlscreds
));
3178 vd
->tlscreds
= NULL
;
3180 g_free(vd
->tlsaclname
);
3181 vd
->tlsaclname
= NULL
;
3182 if (vd
->lock_key_sync
) {
3183 qemu_remove_led_event_handler(vd
->led
);
3187 int vnc_display_password(const char *id
, const char *password
)
3189 VncDisplay
*vd
= vnc_display_find(id
);
3194 if (vd
->auth
== VNC_AUTH_NONE
) {
3195 error_printf_unless_qmp("If you want use passwords please enable "
3196 "password auth using '-vnc ${dpy},password'.\n");
3200 g_free(vd
->password
);
3201 vd
->password
= g_strdup(password
);
3206 int vnc_display_pw_expire(const char *id
, time_t expires
)
3208 VncDisplay
*vd
= vnc_display_find(id
);
3214 vd
->expires
= expires
;
3218 static void vnc_display_print_local_addr(VncDisplay
*vd
)
3220 SocketAddress
*addr
;
3223 addr
= qio_channel_socket_get_local_address(vd
->lsock
, &err
);
3228 if (addr
->type
!= SOCKET_ADDRESS_KIND_INET
) {
3229 qapi_free_SocketAddress(addr
);
3232 error_printf_unless_qmp("VNC server running on %s:%s\n",
3233 addr
->u
.inet
.data
->host
,
3234 addr
->u
.inet
.data
->port
);
3235 qapi_free_SocketAddress(addr
);
3238 static QemuOptsList qemu_vnc_opts
= {
3240 .head
= QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts
.head
),
3241 .implied_opt_name
= "vnc",
3245 .type
= QEMU_OPT_STRING
,
3247 .name
= "websocket",
3248 .type
= QEMU_OPT_STRING
,
3250 .name
= "tls-creds",
3251 .type
= QEMU_OPT_STRING
,
3253 /* Deprecated in favour of tls-creds */
3255 .type
= QEMU_OPT_STRING
,
3258 .type
= QEMU_OPT_STRING
,
3261 .type
= QEMU_OPT_STRING
,
3264 .type
= QEMU_OPT_NUMBER
,
3266 .name
= "connections",
3267 .type
= QEMU_OPT_NUMBER
,
3270 .type
= QEMU_OPT_NUMBER
,
3273 .type
= QEMU_OPT_BOOL
,
3276 .type
= QEMU_OPT_BOOL
,
3279 .type
= QEMU_OPT_BOOL
,
3282 .type
= QEMU_OPT_BOOL
,
3284 .name
= "lock-key-sync",
3285 .type
= QEMU_OPT_BOOL
,
3287 .name
= "key-delay-ms",
3288 .type
= QEMU_OPT_NUMBER
,
3291 .type
= QEMU_OPT_BOOL
,
3293 /* Deprecated in favour of tls-creds */
3295 .type
= QEMU_OPT_BOOL
,
3297 /* Deprecated in favour of tls-creds */
3298 .name
= "x509verify",
3299 .type
= QEMU_OPT_STRING
,
3302 .type
= QEMU_OPT_BOOL
,
3305 .type
= QEMU_OPT_BOOL
,
3307 .name
= "non-adaptive",
3308 .type
= QEMU_OPT_BOOL
,
3310 { /* end of list */ }
3316 vnc_display_setup_auth(int *auth
,
3318 QCryptoTLSCreds
*tlscreds
,
3325 * We have a choice of 3 authentication options
3331 * The channel can be run in 2 modes
3336 * And TLS can use 2 types of credentials
3341 * We thus have 9 possible logical combinations
3346 * 4. tls + anon + none
3347 * 5. tls + anon + vnc
3348 * 6. tls + anon + sasl
3349 * 7. tls + x509 + none
3350 * 8. tls + x509 + vnc
3351 * 9. tls + x509 + sasl
3353 * These need to be mapped into the VNC auth schemes
3354 * in an appropriate manner. In regular VNC, all the
3355 * TLS options get mapped into VNC_AUTH_VENCRYPT
3358 * In websockets, the https:// protocol already provides
3359 * TLS support, so there is no need to make use of the
3360 * VeNCrypt extension. Furthermore, websockets browser
3361 * clients could not use VeNCrypt even if they wanted to,
3362 * as they cannot control when the TLS handshake takes
3363 * place. Thus there is no option but to rely on https://,
3364 * meaning combinations 4->6 and 7->9 will be mapped to
3365 * VNC auth schemes in the same way as combos 1->3.
3367 * Regardless of fact that we have a different mapping to
3368 * VNC auth mechs for plain VNC vs websockets VNC, the end
3369 * result has the same security characteristics.
3371 if (websocket
|| !tlscreds
) {
3373 VNC_DEBUG("Initializing VNC server with password auth\n");
3374 *auth
= VNC_AUTH_VNC
;
3376 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3377 *auth
= VNC_AUTH_SASL
;
3379 VNC_DEBUG("Initializing VNC server with no auth\n");
3380 *auth
= VNC_AUTH_NONE
;
3382 *subauth
= VNC_AUTH_INVALID
;
3384 bool is_x509
= object_dynamic_cast(OBJECT(tlscreds
),
3385 TYPE_QCRYPTO_TLS_CREDS_X509
) != NULL
;
3386 bool is_anon
= object_dynamic_cast(OBJECT(tlscreds
),
3387 TYPE_QCRYPTO_TLS_CREDS_ANON
) != NULL
;
3389 if (!is_x509
&& !is_anon
) {
3391 "Unsupported TLS cred type %s",
3392 object_get_typename(OBJECT(tlscreds
)));
3395 *auth
= VNC_AUTH_VENCRYPT
;
3398 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3399 *subauth
= VNC_AUTH_VENCRYPT_X509VNC
;
3401 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3402 *subauth
= VNC_AUTH_VENCRYPT_TLSVNC
;
3407 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3408 *subauth
= VNC_AUTH_VENCRYPT_X509SASL
;
3410 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3411 *subauth
= VNC_AUTH_VENCRYPT_TLSSASL
;
3415 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3416 *subauth
= VNC_AUTH_VENCRYPT_X509NONE
;
3418 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3419 *subauth
= VNC_AUTH_VENCRYPT_TLSNONE
;
3428 * Handle back compat with old CLI syntax by creating some
3429 * suitable QCryptoTLSCreds objects
3431 static QCryptoTLSCreds
*
3432 vnc_display_create_creds(bool x509
,
3438 gchar
*credsid
= g_strdup_printf("tlsvnc%s", id
);
3439 Object
*parent
= object_get_objects_root();
3444 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509
,
3448 "endpoint", "server",
3450 "verify-peer", x509verify
? "yes" : "no",
3453 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON
,
3457 "endpoint", "server",
3464 error_propagate(errp
, err
);
3468 return QCRYPTO_TLS_CREDS(creds
);
3472 void vnc_display_open(const char *id
, Error
**errp
)
3474 VncDisplay
*vd
= vnc_display_find(id
);
3475 QemuOpts
*opts
= qemu_opts_find(&qemu_vnc_opts
, id
);
3476 SocketAddress
*saddr
= NULL
, *wsaddr
= NULL
;
3477 const char *share
, *device_id
;
3479 bool password
= false;
3480 bool reverse
= false;
3484 int show_vnc_port
= 0;
3486 #ifdef CONFIG_VNC_SASL
3490 int lock_key_sync
= 1;
3492 bool ws_enabled
= false;
3495 error_setg(errp
, "VNC display not active");
3498 vnc_display_close(vd
);
3503 vnc
= qemu_opt_get(opts
, "vnc");
3504 if (!vnc
|| strcmp(vnc
, "none") == 0) {
3508 h
= strrchr(vnc
, ':');
3510 size_t hlen
= h
- vnc
;
3512 const char *websocket
= qemu_opt_get(opts
, "websocket");
3513 int to
= qemu_opt_get_number(opts
, "to", 0);
3514 bool has_ipv4
= qemu_opt_get(opts
, "ipv4");
3515 bool has_ipv6
= qemu_opt_get(opts
, "ipv6");
3516 bool ipv4
= qemu_opt_get_bool(opts
, "ipv4", false);
3517 bool ipv6
= qemu_opt_get_bool(opts
, "ipv6", false);
3519 saddr
= g_new0(SocketAddress
, 1);
3521 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1
)) {
3523 "SHA1 hash support is required for websockets");
3527 wsaddr
= g_new0(SocketAddress
, 1);
3531 if (strncmp(vnc
, "unix:", 5) == 0) {
3532 saddr
->type
= SOCKET_ADDRESS_KIND_UNIX
;
3533 saddr
->u
.q_unix
.data
= g_new0(UnixSocketAddress
, 1);
3534 saddr
->u
.q_unix
.data
->path
= g_strdup(vnc
+ 5);
3537 error_setg(errp
, "UNIX sockets not supported with websock");
3541 unsigned long long baseport
;
3542 InetSocketAddress
*inet
;
3543 saddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3544 inet
= saddr
->u
.inet
.data
= g_new0(InetSocketAddress
, 1);
3545 if (vnc
[0] == '[' && vnc
[hlen
- 1] == ']') {
3546 inet
->host
= g_strndup(vnc
+ 1, hlen
- 2);
3548 inet
->host
= g_strndup(vnc
, hlen
);
3550 if (parse_uint_full(h
+ 1, &baseport
, 10) < 0) {
3551 error_setg(errp
, "can't convert to a number: %s", h
+ 1);
3554 if (baseport
> 65535 ||
3555 baseport
+ 5900 > 65535) {
3556 error_setg(errp
, "port %s out of range", h
+ 1);
3559 inet
->port
= g_strdup_printf(
3560 "%d", (int)baseport
+ 5900);
3563 inet
->has_to
= true;
3564 inet
->to
= to
+ 5900;
3568 inet
->has_ipv4
= has_ipv4
;
3570 inet
->has_ipv6
= has_ipv6
;
3573 wsaddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3574 inet
= wsaddr
->u
.inet
.data
= g_new0(InetSocketAddress
, 1);
3575 inet
->host
= g_strdup(saddr
->u
.inet
.data
->host
);
3576 if (g_str_equal(websocket
, "") ||
3577 g_str_equal(websocket
, "on")) {
3578 inet
->port
= g_strdup_printf(
3579 "%d", (int)baseport
+ 5700);
3581 inet
->port
= g_strdup(websocket
);
3585 inet
->has_to
= true;
3589 inet
->has_ipv4
= has_ipv4
;
3591 inet
->has_ipv6
= has_ipv6
;
3595 error_setg(errp
, "no vnc port specified");
3599 password
= qemu_opt_get_bool(opts
, "password", false);
3601 if (fips_get_state()) {
3603 "VNC password auth disabled due to FIPS mode, "
3604 "consider using the VeNCrypt or SASL authentication "
3605 "methods as an alternative");
3608 if (!qcrypto_cipher_supports(
3609 QCRYPTO_CIPHER_ALG_DES_RFB
, QCRYPTO_CIPHER_MODE_ECB
)) {
3611 "Cipher backend does not support DES RFB algorithm");
3616 reverse
= qemu_opt_get_bool(opts
, "reverse", false);
3617 lock_key_sync
= qemu_opt_get_bool(opts
, "lock-key-sync", true);
3618 key_delay_ms
= qemu_opt_get_number(opts
, "key-delay-ms", 1);
3619 sasl
= qemu_opt_get_bool(opts
, "sasl", false);
3620 #ifndef CONFIG_VNC_SASL
3622 error_setg(errp
, "VNC SASL auth requires cyrus-sasl support");
3625 #endif /* CONFIG_VNC_SASL */
3626 credid
= qemu_opt_get(opts
, "tls-creds");
3629 if (qemu_opt_get(opts
, "tls") ||
3630 qemu_opt_get(opts
, "x509") ||
3631 qemu_opt_get(opts
, "x509verify")) {
3633 "'tls-creds' parameter is mutually exclusive with "
3634 "'tls', 'x509' and 'x509verify' parameters");
3638 creds
= object_resolve_path_component(
3639 object_get_objects_root(), credid
);
3641 error_setg(errp
, "No TLS credentials with id '%s'",
3645 vd
->tlscreds
= (QCryptoTLSCreds
*)
3646 object_dynamic_cast(creds
,
3647 TYPE_QCRYPTO_TLS_CREDS
);
3648 if (!vd
->tlscreds
) {
3649 error_setg(errp
, "Object with id '%s' is not TLS credentials",
3653 object_ref(OBJECT(vd
->tlscreds
));
3655 if (vd
->tlscreds
->endpoint
!= QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
) {
3657 "Expecting TLS credentials with a server endpoint");
3662 bool tls
= false, x509
= false, x509verify
= false;
3663 tls
= qemu_opt_get_bool(opts
, "tls", false);
3665 path
= qemu_opt_get(opts
, "x509");
3670 path
= qemu_opt_get(opts
, "x509verify");
3676 vd
->tlscreds
= vnc_display_create_creds(x509
,
3681 if (!vd
->tlscreds
) {
3686 acl
= qemu_opt_get_bool(opts
, "acl", false);
3688 share
= qemu_opt_get(opts
, "share");
3690 if (strcmp(share
, "ignore") == 0) {
3691 vd
->share_policy
= VNC_SHARE_POLICY_IGNORE
;
3692 } else if (strcmp(share
, "allow-exclusive") == 0) {
3693 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3694 } else if (strcmp(share
, "force-shared") == 0) {
3695 vd
->share_policy
= VNC_SHARE_POLICY_FORCE_SHARED
;
3697 error_setg(errp
, "unknown vnc share= option");
3701 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3703 vd
->connections_limit
= qemu_opt_get_number(opts
, "connections", 32);
3705 #ifdef CONFIG_VNC_JPEG
3706 vd
->lossy
= qemu_opt_get_bool(opts
, "lossy", false);
3708 vd
->non_adaptive
= qemu_opt_get_bool(opts
, "non-adaptive", false);
3709 /* adaptive updates are only used with tight encoding and
3710 * if lossy updates are enabled so we can disable all the
3711 * calculations otherwise */
3713 vd
->non_adaptive
= true;
3717 if (strcmp(vd
->id
, "default") == 0) {
3718 vd
->tlsaclname
= g_strdup("vnc.x509dname");
3720 vd
->tlsaclname
= g_strdup_printf("vnc.%s.x509dname", vd
->id
);
3722 qemu_acl_init(vd
->tlsaclname
);
3724 #ifdef CONFIG_VNC_SASL
3728 if (strcmp(vd
->id
, "default") == 0) {
3729 aclname
= g_strdup("vnc.username");
3731 aclname
= g_strdup_printf("vnc.%s.username", vd
->id
);
3733 vd
->sasl
.acl
= qemu_acl_init(aclname
);
3738 if (vnc_display_setup_auth(&vd
->auth
, &vd
->subauth
,
3739 vd
->tlscreds
, password
,
3740 sasl
, false, errp
) < 0) {
3744 if (vnc_display_setup_auth(&vd
->ws_auth
, &vd
->ws_subauth
,
3745 vd
->tlscreds
, password
,
3746 sasl
, true, errp
) < 0) {
3750 #ifdef CONFIG_VNC_SASL
3751 if ((saslErr
= sasl_server_init(NULL
, "qemu")) != SASL_OK
) {
3752 error_setg(errp
, "Failed to initialize SASL auth: %s",
3753 sasl_errstring(saslErr
, NULL
, NULL
));
3757 vd
->lock_key_sync
= lock_key_sync
;
3758 if (lock_key_sync
) {
3759 vd
->led
= qemu_add_led_event_handler(kbd_leds
, vd
);
3762 vd
->key_delay_ms
= key_delay_ms
;
3764 device_id
= qemu_opt_get(opts
, "display");
3766 int head
= qemu_opt_get_number(opts
, "head", 0);
3769 con
= qemu_console_lookup_by_device_name(device_id
, head
, &err
);
3771 error_propagate(errp
, err
);
3778 if (con
!= vd
->dcl
.con
) {
3779 unregister_displaychangelistener(&vd
->dcl
);
3781 register_displaychangelistener(&vd
->dcl
);
3785 /* connect to viewer */
3786 QIOChannelSocket
*sioc
= NULL
;
3788 vd
->lwebsock
= NULL
;
3790 error_setg(errp
, "Cannot use websockets in reverse mode");
3793 vd
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3794 sioc
= qio_channel_socket_new();
3795 qio_channel_set_name(QIO_CHANNEL(sioc
), "vnc-reverse");
3796 if (qio_channel_socket_connect_sync(sioc
, saddr
, errp
) < 0) {
3799 vnc_connect(vd
, sioc
, false, false);
3800 object_unref(OBJECT(sioc
));
3802 vd
->lsock
= qio_channel_socket_new();
3803 qio_channel_set_name(QIO_CHANNEL(vd
->lsock
), "vnc-listen");
3804 if (qio_channel_socket_listen_sync(vd
->lsock
, saddr
, errp
) < 0) {
3807 vd
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3810 vd
->lwebsock
= qio_channel_socket_new();
3811 qio_channel_set_name(QIO_CHANNEL(vd
->lwebsock
), "vnc-ws-listen");
3812 if (qio_channel_socket_listen_sync(vd
->lwebsock
,
3813 wsaddr
, errp
) < 0) {
3814 object_unref(OBJECT(vd
->lsock
));
3820 vd
->lsock_tag
= qio_channel_add_watch(
3821 QIO_CHANNEL(vd
->lsock
),
3822 G_IO_IN
, vnc_listen_io
, vd
, NULL
);
3824 vd
->lwebsock_tag
= qio_channel_add_watch(
3825 QIO_CHANNEL(vd
->lwebsock
),
3826 G_IO_IN
, vnc_listen_io
, vd
, NULL
);
3830 if (show_vnc_port
) {
3831 vnc_display_print_local_addr(vd
);
3834 qapi_free_SocketAddress(saddr
);
3835 qapi_free_SocketAddress(wsaddr
);
3839 qapi_free_SocketAddress(saddr
);
3840 qapi_free_SocketAddress(wsaddr
);
3844 void vnc_display_add_client(const char *id
, int csock
, bool skipauth
)
3846 VncDisplay
*vd
= vnc_display_find(id
);
3847 QIOChannelSocket
*sioc
;
3853 sioc
= qio_channel_socket_new_fd(csock
, NULL
);
3855 qio_channel_set_name(QIO_CHANNEL(sioc
), "vnc-server");
3856 vnc_connect(vd
, sioc
, skipauth
, false);
3857 object_unref(OBJECT(sioc
));
3861 static void vnc_auto_assign_id(QemuOptsList
*olist
, QemuOpts
*opts
)
3866 id
= g_strdup("default");
3867 while (qemu_opts_find(olist
, id
)) {
3869 id
= g_strdup_printf("vnc%d", i
++);
3871 qemu_opts_set_id(opts
, id
);
3874 QemuOpts
*vnc_parse(const char *str
, Error
**errp
)
3876 QemuOptsList
*olist
= qemu_find_opts("vnc");
3877 QemuOpts
*opts
= qemu_opts_parse(olist
, str
, true, errp
);
3884 id
= qemu_opts_id(opts
);
3886 /* auto-assign id if not present */
3887 vnc_auto_assign_id(olist
, opts
);
3892 int vnc_init_func(void *opaque
, QemuOpts
*opts
, Error
**errp
)
3894 Error
*local_err
= NULL
;
3895 char *id
= (char *)qemu_opts_id(opts
);
3898 vnc_display_init(id
);
3899 vnc_display_open(id
, &local_err
);
3900 if (local_err
!= NULL
) {
3901 error_reportf_err(local_err
, "Failed to start VNC server: ");
3907 static void vnc_register_config(void)
3909 qemu_add_opts(&qemu_vnc_opts
);
3911 opts_init(vnc_register_config
);