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/%p: %s -> %s\n", __func__
,
74 vs
->ioc
, 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
++;
109 static void vnc_init_basic_info(SocketAddress
*addr
,
113 switch (addr
->type
) {
114 case SOCKET_ADDRESS_KIND_INET
:
115 info
->host
= g_strdup(addr
->u
.inet
->host
);
116 info
->service
= g_strdup(addr
->u
.inet
->port
);
117 if (addr
->u
.inet
->ipv6
) {
118 info
->family
= NETWORK_ADDRESS_FAMILY_IPV6
;
120 info
->family
= NETWORK_ADDRESS_FAMILY_IPV4
;
124 case SOCKET_ADDRESS_KIND_UNIX
:
125 info
->host
= g_strdup("");
126 info
->service
= g_strdup(addr
->u
.q_unix
->path
);
127 info
->family
= NETWORK_ADDRESS_FAMILY_UNIX
;
131 error_setg(errp
, "Unsupported socket kind %d",
139 static void vnc_init_basic_info_from_server_addr(QIOChannelSocket
*ioc
,
143 SocketAddress
*addr
= NULL
;
145 addr
= qio_channel_socket_get_local_address(ioc
, errp
);
150 vnc_init_basic_info(addr
, info
, errp
);
151 qapi_free_SocketAddress(addr
);
154 static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket
*ioc
,
158 SocketAddress
*addr
= NULL
;
160 addr
= qio_channel_socket_get_remote_address(ioc
, errp
);
165 vnc_init_basic_info(addr
, info
, errp
);
166 qapi_free_SocketAddress(addr
);
169 static const char *vnc_auth_name(VncDisplay
*vd
) {
171 case VNC_AUTH_INVALID
:
187 case VNC_AUTH_VENCRYPT
:
188 switch (vd
->subauth
) {
189 case VNC_AUTH_VENCRYPT_PLAIN
:
190 return "vencrypt+plain";
191 case VNC_AUTH_VENCRYPT_TLSNONE
:
192 return "vencrypt+tls+none";
193 case VNC_AUTH_VENCRYPT_TLSVNC
:
194 return "vencrypt+tls+vnc";
195 case VNC_AUTH_VENCRYPT_TLSPLAIN
:
196 return "vencrypt+tls+plain";
197 case VNC_AUTH_VENCRYPT_X509NONE
:
198 return "vencrypt+x509+none";
199 case VNC_AUTH_VENCRYPT_X509VNC
:
200 return "vencrypt+x509+vnc";
201 case VNC_AUTH_VENCRYPT_X509PLAIN
:
202 return "vencrypt+x509+plain";
203 case VNC_AUTH_VENCRYPT_TLSSASL
:
204 return "vencrypt+tls+sasl";
205 case VNC_AUTH_VENCRYPT_X509SASL
:
206 return "vencrypt+x509+sasl";
216 static VncServerInfo
*vnc_server_info_get(VncDisplay
*vd
)
221 info
= g_malloc(sizeof(*info
));
222 vnc_init_basic_info_from_server_addr(vd
->lsock
,
223 qapi_VncServerInfo_base(info
), &err
);
224 info
->has_auth
= true;
225 info
->auth
= g_strdup(vnc_auth_name(vd
));
227 qapi_free_VncServerInfo(info
);
234 static void vnc_client_cache_auth(VncState
*client
)
241 client
->info
->x509_dname
=
242 qcrypto_tls_session_get_peer_name(client
->tls
);
243 client
->info
->has_x509_dname
=
244 client
->info
->x509_dname
!= NULL
;
246 #ifdef CONFIG_VNC_SASL
247 if (client
->sasl
.conn
&&
248 client
->sasl
.username
) {
249 client
->info
->has_sasl_username
= true;
250 client
->info
->sasl_username
= g_strdup(client
->sasl
.username
);
255 static void vnc_client_cache_addr(VncState
*client
)
259 client
->info
= g_malloc0(sizeof(*client
->info
));
260 vnc_init_basic_info_from_remote_addr(client
->sioc
,
261 qapi_VncClientInfo_base(client
->info
),
264 qapi_free_VncClientInfo(client
->info
);
270 static void vnc_qmp_event(VncState
*vs
, QAPIEvent event
)
278 si
= vnc_server_info_get(vs
->vd
);
284 case QAPI_EVENT_VNC_CONNECTED
:
285 qapi_event_send_vnc_connected(si
, qapi_VncClientInfo_base(vs
->info
),
288 case QAPI_EVENT_VNC_INITIALIZED
:
289 qapi_event_send_vnc_initialized(si
, vs
->info
, &error_abort
);
291 case QAPI_EVENT_VNC_DISCONNECTED
:
292 qapi_event_send_vnc_disconnected(si
, vs
->info
, &error_abort
);
298 qapi_free_VncServerInfo(si
);
301 static VncClientInfo
*qmp_query_vnc_client(const VncState
*client
)
306 info
= g_malloc0(sizeof(*info
));
308 vnc_init_basic_info_from_remote_addr(client
->sioc
,
309 qapi_VncClientInfo_base(info
),
313 qapi_free_VncClientInfo(info
);
317 info
->websocket
= client
->websocket
;
320 info
->x509_dname
= qcrypto_tls_session_get_peer_name(client
->tls
);
321 info
->has_x509_dname
= info
->x509_dname
!= NULL
;
323 #ifdef CONFIG_VNC_SASL
324 if (client
->sasl
.conn
&& client
->sasl
.username
) {
325 info
->has_sasl_username
= true;
326 info
->sasl_username
= g_strdup(client
->sasl
.username
);
333 static VncDisplay
*vnc_display_find(const char *id
)
338 return QTAILQ_FIRST(&vnc_displays
);
340 QTAILQ_FOREACH(vd
, &vnc_displays
, next
) {
341 if (strcmp(id
, vd
->id
) == 0) {
348 static VncClientInfoList
*qmp_query_client_list(VncDisplay
*vd
)
350 VncClientInfoList
*cinfo
, *prev
= NULL
;
353 QTAILQ_FOREACH(client
, &vd
->clients
, next
) {
354 cinfo
= g_new0(VncClientInfoList
, 1);
355 cinfo
->value
= qmp_query_vnc_client(client
);
362 VncInfo
*qmp_query_vnc(Error
**errp
)
364 VncInfo
*info
= g_malloc0(sizeof(*info
));
365 VncDisplay
*vd
= vnc_display_find(NULL
);
366 SocketAddress
*addr
= NULL
;
368 if (vd
== NULL
|| !vd
->enabled
) {
369 info
->enabled
= false;
371 info
->enabled
= true;
373 /* for compatibility with the original command */
374 info
->has_clients
= true;
375 info
->clients
= qmp_query_client_list(vd
);
377 if (vd
->lsock
== NULL
) {
381 addr
= qio_channel_socket_get_local_address(vd
->lsock
, errp
);
386 switch (addr
->type
) {
387 case SOCKET_ADDRESS_KIND_INET
:
388 info
->host
= g_strdup(addr
->u
.inet
->host
);
389 info
->service
= g_strdup(addr
->u
.inet
->port
);
390 if (addr
->u
.inet
->ipv6
) {
391 info
->family
= NETWORK_ADDRESS_FAMILY_IPV6
;
393 info
->family
= NETWORK_ADDRESS_FAMILY_IPV4
;
397 case SOCKET_ADDRESS_KIND_UNIX
:
398 info
->host
= g_strdup("");
399 info
->service
= g_strdup(addr
->u
.q_unix
->path
);
400 info
->family
= NETWORK_ADDRESS_FAMILY_UNIX
;
404 error_setg(errp
, "Unsupported socket kind %d",
409 info
->has_host
= true;
410 info
->has_service
= true;
411 info
->has_family
= true;
413 info
->has_auth
= true;
414 info
->auth
= g_strdup(vnc_auth_name(vd
));
417 qapi_free_SocketAddress(addr
);
421 qapi_free_SocketAddress(addr
);
422 qapi_free_VncInfo(info
);
426 static VncBasicInfoList
*qmp_query_server_entry(QIOChannelSocket
*ioc
,
428 VncBasicInfoList
*prev
)
430 VncBasicInfoList
*list
;
435 addr
= qio_channel_socket_get_local_address(ioc
, &err
);
441 info
= g_new0(VncBasicInfo
, 1);
442 vnc_init_basic_info(addr
, info
, &err
);
443 qapi_free_SocketAddress(addr
);
445 qapi_free_VncBasicInfo(info
);
449 info
->websocket
= websocket
;
451 list
= g_new0(VncBasicInfoList
, 1);
457 static void qmp_query_auth(VncDisplay
*vd
, VncInfo2
*info
)
461 info
->auth
= VNC_PRIMARY_AUTH_VNC
;
464 info
->auth
= VNC_PRIMARY_AUTH_RA2
;
467 info
->auth
= VNC_PRIMARY_AUTH_RA2NE
;
470 info
->auth
= VNC_PRIMARY_AUTH_TIGHT
;
473 info
->auth
= VNC_PRIMARY_AUTH_ULTRA
;
476 info
->auth
= VNC_PRIMARY_AUTH_TLS
;
478 case VNC_AUTH_VENCRYPT
:
479 info
->auth
= VNC_PRIMARY_AUTH_VENCRYPT
;
480 info
->has_vencrypt
= true;
481 switch (vd
->subauth
) {
482 case VNC_AUTH_VENCRYPT_PLAIN
:
483 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_PLAIN
;
485 case VNC_AUTH_VENCRYPT_TLSNONE
:
486 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_NONE
;
488 case VNC_AUTH_VENCRYPT_TLSVNC
:
489 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_VNC
;
491 case VNC_AUTH_VENCRYPT_TLSPLAIN
:
492 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN
;
494 case VNC_AUTH_VENCRYPT_X509NONE
:
495 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_NONE
;
497 case VNC_AUTH_VENCRYPT_X509VNC
:
498 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_VNC
;
500 case VNC_AUTH_VENCRYPT_X509PLAIN
:
501 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_PLAIN
;
503 case VNC_AUTH_VENCRYPT_TLSSASL
:
504 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_SASL
;
506 case VNC_AUTH_VENCRYPT_X509SASL
:
507 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_SASL
;
510 info
->has_vencrypt
= false;
515 info
->auth
= VNC_PRIMARY_AUTH_SASL
;
519 info
->auth
= VNC_PRIMARY_AUTH_NONE
;
524 VncInfo2List
*qmp_query_vnc_servers(Error
**errp
)
526 VncInfo2List
*item
, *prev
= NULL
;
531 QTAILQ_FOREACH(vd
, &vnc_displays
, next
) {
532 info
= g_new0(VncInfo2
, 1);
533 info
->id
= g_strdup(vd
->id
);
534 info
->clients
= qmp_query_client_list(vd
);
535 qmp_query_auth(vd
, info
);
537 dev
= DEVICE(object_property_get_link(OBJECT(vd
->dcl
.con
),
539 info
->has_display
= true;
540 info
->display
= g_strdup(dev
->id
);
542 if (vd
->lsock
!= NULL
) {
543 info
->server
= qmp_query_server_entry(
544 vd
->lsock
, false, info
->server
);
546 if (vd
->lwebsock
!= NULL
) {
547 info
->server
= qmp_query_server_entry(
548 vd
->lwebsock
, true, info
->server
);
551 item
= g_new0(VncInfo2List
, 1);
560 1) Get the queue working for IO.
561 2) there is some weirdness when using the -S option (the screen is grey
562 and not totally invalidated
563 3) resolutions > 1024
566 static int vnc_update_client(VncState
*vs
, int has_dirty
, bool sync
);
567 static void vnc_disconnect_start(VncState
*vs
);
569 static void vnc_colordepth(VncState
*vs
);
570 static void framebuffer_update_request(VncState
*vs
, int incremental
,
571 int x_position
, int y_position
,
573 static void vnc_refresh(DisplayChangeListener
*dcl
);
574 static int vnc_refresh_server_surface(VncDisplay
*vd
);
576 static int vnc_width(VncDisplay
*vd
)
578 return MIN(VNC_MAX_WIDTH
, ROUND_UP(surface_width(vd
->ds
),
579 VNC_DIRTY_PIXELS_PER_BIT
));
582 static int vnc_height(VncDisplay
*vd
)
584 return MIN(VNC_MAX_HEIGHT
, surface_height(vd
->ds
));
587 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty
[VNC_MAX_HEIGHT
],
588 VNC_MAX_WIDTH
/ VNC_DIRTY_PIXELS_PER_BIT
),
590 int x
, int y
, int w
, int h
)
592 int width
= vnc_width(vd
);
593 int height
= vnc_height(vd
);
595 /* this is needed this to ensure we updated all affected
596 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
597 w
+= (x
% VNC_DIRTY_PIXELS_PER_BIT
);
598 x
-= (x
% VNC_DIRTY_PIXELS_PER_BIT
);
602 w
= MIN(x
+ w
, width
) - x
;
603 h
= MIN(y
+ h
, height
);
606 bitmap_set(dirty
[y
], x
/ VNC_DIRTY_PIXELS_PER_BIT
,
607 DIV_ROUND_UP(w
, VNC_DIRTY_PIXELS_PER_BIT
));
611 static void vnc_dpy_update(DisplayChangeListener
*dcl
,
612 int x
, int y
, int w
, int h
)
614 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
615 struct VncSurface
*s
= &vd
->guest
;
617 vnc_set_area_dirty(s
->dirty
, vd
, x
, y
, w
, h
);
620 void vnc_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
,
623 vnc_write_u16(vs
, x
);
624 vnc_write_u16(vs
, y
);
625 vnc_write_u16(vs
, w
);
626 vnc_write_u16(vs
, h
);
628 vnc_write_s32(vs
, encoding
);
632 static void vnc_desktop_resize(VncState
*vs
)
634 if (vs
->ioc
== NULL
|| !vnc_has_feature(vs
, VNC_FEATURE_RESIZE
)) {
637 if (vs
->client_width
== pixman_image_get_width(vs
->vd
->server
) &&
638 vs
->client_height
== pixman_image_get_height(vs
->vd
->server
)) {
641 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
642 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
644 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
646 vnc_write_u16(vs
, 1); /* number of rects */
647 vnc_framebuffer_update(vs
, 0, 0, vs
->client_width
, vs
->client_height
,
648 VNC_ENCODING_DESKTOPRESIZE
);
649 vnc_unlock_output(vs
);
653 static void vnc_abort_display_jobs(VncDisplay
*vd
)
657 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
660 vnc_unlock_output(vs
);
662 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
665 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
668 vnc_unlock_output(vs
);
672 int vnc_server_fb_stride(VncDisplay
*vd
)
674 return pixman_image_get_stride(vd
->server
);
677 void *vnc_server_fb_ptr(VncDisplay
*vd
, int x
, int y
)
681 ptr
= (uint8_t *)pixman_image_get_data(vd
->server
);
682 ptr
+= y
* vnc_server_fb_stride(vd
);
683 ptr
+= x
* VNC_SERVER_FB_BYTES
;
687 static void vnc_update_server_surface(VncDisplay
*vd
)
689 qemu_pixman_image_unref(vd
->server
);
692 if (QTAILQ_EMPTY(&vd
->clients
)) {
696 vd
->server
= pixman_image_create_bits(VNC_SERVER_FB_FORMAT
,
702 static void vnc_dpy_switch(DisplayChangeListener
*dcl
,
703 DisplaySurface
*surface
)
705 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
709 vnc_abort_display_jobs(vd
);
713 vnc_update_server_surface(vd
);
716 qemu_pixman_image_unref(vd
->guest
.fb
);
717 vd
->guest
.fb
= pixman_image_ref(surface
->image
);
718 vd
->guest
.format
= surface
->format
;
719 width
= vnc_width(vd
);
720 height
= vnc_height(vd
);
721 memset(vd
->guest
.dirty
, 0x00, sizeof(vd
->guest
.dirty
));
722 vnc_set_area_dirty(vd
->guest
.dirty
, vd
, 0, 0,
725 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
727 vnc_desktop_resize(vs
);
728 if (vs
->vd
->cursor
) {
729 vnc_cursor_define(vs
);
731 memset(vs
->dirty
, 0x00, sizeof(vs
->dirty
));
732 vnc_set_area_dirty(vs
->dirty
, vd
, 0, 0,
738 static void vnc_write_pixels_copy(VncState
*vs
,
739 void *pixels
, int size
)
741 vnc_write(vs
, pixels
, size
);
744 /* slowest but generic code. */
745 void vnc_convert_pixel(VncState
*vs
, uint8_t *buf
, uint32_t v
)
749 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
750 r
= (((v
& 0x00ff0000) >> 16) << vs
->client_pf
.rbits
) >> 8;
751 g
= (((v
& 0x0000ff00) >> 8) << vs
->client_pf
.gbits
) >> 8;
752 b
= (((v
& 0x000000ff) >> 0) << vs
->client_pf
.bbits
) >> 8;
754 # error need some bits here if you change VNC_SERVER_FB_FORMAT
756 v
= (r
<< vs
->client_pf
.rshift
) |
757 (g
<< vs
->client_pf
.gshift
) |
758 (b
<< vs
->client_pf
.bshift
);
759 switch (vs
->client_pf
.bytes_per_pixel
) {
789 static void vnc_write_pixels_generic(VncState
*vs
,
790 void *pixels1
, int size
)
794 if (VNC_SERVER_FB_BYTES
== 4) {
795 uint32_t *pixels
= pixels1
;
798 for (i
= 0; i
< n
; i
++) {
799 vnc_convert_pixel(vs
, buf
, pixels
[i
]);
800 vnc_write(vs
, buf
, vs
->client_pf
.bytes_per_pixel
);
805 int vnc_raw_send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
809 VncDisplay
*vd
= vs
->vd
;
811 row
= vnc_server_fb_ptr(vd
, x
, y
);
812 for (i
= 0; i
< h
; i
++) {
813 vs
->write_pixels(vs
, row
, w
* VNC_SERVER_FB_BYTES
);
814 row
+= vnc_server_fb_stride(vd
);
819 int vnc_send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
822 bool encode_raw
= false;
823 size_t saved_offs
= vs
->output
.offset
;
825 switch(vs
->vnc_encoding
) {
826 case VNC_ENCODING_ZLIB
:
827 n
= vnc_zlib_send_framebuffer_update(vs
, x
, y
, w
, h
);
829 case VNC_ENCODING_HEXTILE
:
830 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_HEXTILE
);
831 n
= vnc_hextile_send_framebuffer_update(vs
, x
, y
, w
, h
);
833 case VNC_ENCODING_TIGHT
:
834 n
= vnc_tight_send_framebuffer_update(vs
, x
, y
, w
, h
);
836 case VNC_ENCODING_TIGHT_PNG
:
837 n
= vnc_tight_png_send_framebuffer_update(vs
, x
, y
, w
, h
);
839 case VNC_ENCODING_ZRLE
:
840 n
= vnc_zrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
842 case VNC_ENCODING_ZYWRLE
:
843 n
= vnc_zywrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
850 /* If the client has the same pixel format as our internal buffer and
851 * a RAW encoding would need less space fall back to RAW encoding to
852 * save bandwidth and processing power in the client. */
853 if (!encode_raw
&& vs
->write_pixels
== vnc_write_pixels_copy
&&
854 12 + h
* w
* VNC_SERVER_FB_BYTES
<= (vs
->output
.offset
- saved_offs
)) {
855 vs
->output
.offset
= saved_offs
;
860 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_RAW
);
861 n
= vnc_raw_send_framebuffer_update(vs
, x
, y
, w
, h
);
867 static void vnc_copy(VncState
*vs
, int src_x
, int src_y
, int dst_x
, int dst_y
, int w
, int h
)
869 /* send bitblit op to the vnc client */
871 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
873 vnc_write_u16(vs
, 1); /* number of rects */
874 vnc_framebuffer_update(vs
, dst_x
, dst_y
, w
, h
, VNC_ENCODING_COPYRECT
);
875 vnc_write_u16(vs
, src_x
);
876 vnc_write_u16(vs
, src_y
);
877 vnc_unlock_output(vs
);
881 static void vnc_dpy_copy(DisplayChangeListener
*dcl
,
882 int src_x
, int src_y
,
883 int dst_x
, int dst_y
, int w
, int h
)
885 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
889 int i
, x
, y
, pitch
, inc
, w_lim
, s
;
893 /* no client connected */
897 vnc_refresh_server_surface(vd
);
898 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
899 if (vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
900 vs
->force_update
= 1;
901 vnc_update_client(vs
, 1, true);
902 /* vs might be free()ed here */
906 /* do bitblit op on the local surface too */
907 pitch
= vnc_server_fb_stride(vd
);
908 src_row
= vnc_server_fb_ptr(vd
, src_x
, src_y
);
909 dst_row
= vnc_server_fb_ptr(vd
, dst_x
, dst_y
);
914 src_row
+= pitch
* (h
-1);
915 dst_row
+= pitch
* (h
-1);
920 w_lim
= w
- (VNC_DIRTY_PIXELS_PER_BIT
- (dst_x
% VNC_DIRTY_PIXELS_PER_BIT
));
924 w_lim
= w
- (w_lim
% VNC_DIRTY_PIXELS_PER_BIT
);
926 for (i
= 0; i
< h
; i
++) {
927 for (x
= 0; x
<= w_lim
;
928 x
+= s
, src_row
+= cmp_bytes
, dst_row
+= cmp_bytes
) {
930 if ((s
= w
- w_lim
) == 0)
933 s
= (VNC_DIRTY_PIXELS_PER_BIT
-
934 (dst_x
% VNC_DIRTY_PIXELS_PER_BIT
));
937 s
= VNC_DIRTY_PIXELS_PER_BIT
;
939 cmp_bytes
= s
* VNC_SERVER_FB_BYTES
;
940 if (memcmp(src_row
, dst_row
, cmp_bytes
) == 0)
942 memmove(dst_row
, src_row
, cmp_bytes
);
943 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
944 if (!vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
945 set_bit(((x
+ dst_x
) / VNC_DIRTY_PIXELS_PER_BIT
),
950 src_row
+= pitch
- w
* VNC_SERVER_FB_BYTES
;
951 dst_row
+= pitch
- w
* VNC_SERVER_FB_BYTES
;
955 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
956 if (vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
957 vnc_copy(vs
, src_x
, src_y
, dst_x
, dst_y
, w
, h
);
962 static void vnc_mouse_set(DisplayChangeListener
*dcl
,
963 int x
, int y
, int visible
)
965 /* can we ask the client(s) to move the pointer ??? */
968 static int vnc_cursor_define(VncState
*vs
)
970 QEMUCursor
*c
= vs
->vd
->cursor
;
973 if (vnc_has_feature(vs
, VNC_FEATURE_RICH_CURSOR
)) {
975 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
976 vnc_write_u8(vs
, 0); /* padding */
977 vnc_write_u16(vs
, 1); /* # of rects */
978 vnc_framebuffer_update(vs
, c
->hot_x
, c
->hot_y
, c
->width
, c
->height
,
979 VNC_ENCODING_RICH_CURSOR
);
980 isize
= c
->width
* c
->height
* vs
->client_pf
.bytes_per_pixel
;
981 vnc_write_pixels_generic(vs
, c
->data
, isize
);
982 vnc_write(vs
, vs
->vd
->cursor_mask
, vs
->vd
->cursor_msize
);
983 vnc_unlock_output(vs
);
989 static void vnc_dpy_cursor_define(DisplayChangeListener
*dcl
,
992 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
995 cursor_put(vd
->cursor
);
996 g_free(vd
->cursor_mask
);
999 cursor_get(vd
->cursor
);
1000 vd
->cursor_msize
= cursor_get_mono_bpl(c
) * c
->height
;
1001 vd
->cursor_mask
= g_malloc0(vd
->cursor_msize
);
1002 cursor_get_mono_mask(c
, 0, vd
->cursor_mask
);
1004 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
1005 vnc_cursor_define(vs
);
1009 static int find_and_clear_dirty_height(VncState
*vs
,
1010 int y
, int last_x
, int x
, int height
)
1014 for (h
= 1; h
< (height
- y
); h
++) {
1015 if (!test_bit(last_x
, vs
->dirty
[y
+ h
])) {
1018 bitmap_clear(vs
->dirty
[y
+ h
], last_x
, x
- last_x
);
1024 static int vnc_update_client(VncState
*vs
, int has_dirty
, bool sync
)
1026 vs
->has_dirty
+= has_dirty
;
1027 if (vs
->need_update
&& vs
->ioc
!= NULL
) {
1028 VncDisplay
*vd
= vs
->vd
;
1034 if (vs
->output
.offset
&& !vs
->audio_cap
&& !vs
->force_update
)
1035 /* kernel send buffers are full -> drop frames to throttle */
1038 if (!vs
->has_dirty
&& !vs
->audio_cap
&& !vs
->force_update
)
1042 * Send screen updates to the vnc client using the server
1043 * surface and server dirty map. guest surface updates
1044 * happening in parallel don't disturb us, the next pass will
1045 * send them to the client.
1047 job
= vnc_job_new(vs
);
1049 height
= pixman_image_get_height(vd
->server
);
1050 width
= pixman_image_get_width(vd
->server
);
1056 unsigned long offset
= find_next_bit((unsigned long *) &vs
->dirty
,
1057 height
* VNC_DIRTY_BPL(vs
),
1058 y
* VNC_DIRTY_BPL(vs
));
1059 if (offset
== height
* VNC_DIRTY_BPL(vs
)) {
1060 /* no more dirty bits */
1063 y
= offset
/ VNC_DIRTY_BPL(vs
);
1064 x
= offset
% VNC_DIRTY_BPL(vs
);
1065 x2
= find_next_zero_bit((unsigned long *) &vs
->dirty
[y
],
1066 VNC_DIRTY_BPL(vs
), x
);
1067 bitmap_clear(vs
->dirty
[y
], x
, x2
- x
);
1068 h
= find_and_clear_dirty_height(vs
, y
, x
, x2
, height
);
1069 x2
= MIN(x2
, width
/ VNC_DIRTY_PIXELS_PER_BIT
);
1071 n
+= vnc_job_add_rect(job
, x
* VNC_DIRTY_PIXELS_PER_BIT
, y
,
1072 (x2
- x
) * VNC_DIRTY_PIXELS_PER_BIT
, h
);
1074 if (!x
&& x2
== width
/ VNC_DIRTY_PIXELS_PER_BIT
) {
1086 vs
->force_update
= 0;
1091 if (vs
->disconnecting
) {
1092 vnc_disconnect_finish(vs
);
1101 static void audio_capture_notify(void *opaque
, audcnotification_e cmd
)
1103 VncState
*vs
= opaque
;
1106 case AUD_CNOTIFY_DISABLE
:
1107 vnc_lock_output(vs
);
1108 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1109 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1110 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_END
);
1111 vnc_unlock_output(vs
);
1115 case AUD_CNOTIFY_ENABLE
:
1116 vnc_lock_output(vs
);
1117 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1118 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1119 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN
);
1120 vnc_unlock_output(vs
);
1126 static void audio_capture_destroy(void *opaque
)
1130 static void audio_capture(void *opaque
, void *buf
, int size
)
1132 VncState
*vs
= opaque
;
1134 vnc_lock_output(vs
);
1135 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1136 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1137 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_DATA
);
1138 vnc_write_u32(vs
, size
);
1139 vnc_write(vs
, buf
, size
);
1140 vnc_unlock_output(vs
);
1144 static void audio_add(VncState
*vs
)
1146 struct audio_capture_ops ops
;
1148 if (vs
->audio_cap
) {
1149 error_report("audio already running");
1153 ops
.notify
= audio_capture_notify
;
1154 ops
.destroy
= audio_capture_destroy
;
1155 ops
.capture
= audio_capture
;
1157 vs
->audio_cap
= AUD_add_capture(&vs
->as
, &ops
, vs
);
1158 if (!vs
->audio_cap
) {
1159 error_report("Failed to add audio capture");
1163 static void audio_del(VncState
*vs
)
1165 if (vs
->audio_cap
) {
1166 AUD_del_capture(vs
->audio_cap
, vs
);
1167 vs
->audio_cap
= NULL
;
1171 static void vnc_disconnect_start(VncState
*vs
)
1173 if (vs
->disconnecting
) {
1176 vnc_set_share_mode(vs
, VNC_SHARE_MODE_DISCONNECTED
);
1178 g_source_remove(vs
->ioc_tag
);
1180 qio_channel_close(vs
->ioc
, NULL
);
1181 vs
->disconnecting
= TRUE
;
1184 void vnc_disconnect_finish(VncState
*vs
)
1188 vnc_jobs_join(vs
); /* Wait encoding jobs */
1190 vnc_lock_output(vs
);
1191 vnc_qmp_event(vs
, QAPI_EVENT_VNC_DISCONNECTED
);
1193 buffer_free(&vs
->input
);
1194 buffer_free(&vs
->output
);
1196 qapi_free_VncClientInfo(vs
->info
);
1199 vnc_tight_clear(vs
);
1202 #ifdef CONFIG_VNC_SASL
1203 vnc_sasl_client_cleanup(vs
);
1204 #endif /* CONFIG_VNC_SASL */
1206 vnc_release_modifiers(vs
);
1208 if (vs
->initialized
) {
1209 QTAILQ_REMOVE(&vs
->vd
->clients
, vs
, next
);
1210 qemu_remove_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
1211 if (QTAILQ_EMPTY(&vs
->vd
->clients
)) {
1212 /* last client gone */
1213 vnc_update_server_surface(vs
->vd
);
1217 if (vs
->vd
->lock_key_sync
)
1218 qemu_remove_led_event_handler(vs
->led
);
1219 vnc_unlock_output(vs
);
1221 qemu_mutex_destroy(&vs
->output_mutex
);
1222 if (vs
->bh
!= NULL
) {
1223 qemu_bh_delete(vs
->bh
);
1225 buffer_free(&vs
->jobs_buffer
);
1227 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
1228 g_free(vs
->lossy_rect
[i
]);
1230 g_free(vs
->lossy_rect
);
1232 object_unref(OBJECT(vs
->ioc
));
1234 object_unref(OBJECT(vs
->sioc
));
1239 ssize_t
vnc_client_io_error(VncState
*vs
, ssize_t ret
, Error
**errp
)
1243 VNC_DEBUG("Closing down client sock: EOF\n");
1244 } else if (ret
!= QIO_CHANNEL_ERR_BLOCK
) {
1245 VNC_DEBUG("Closing down client sock: ret %d (%s)\n",
1246 ret
, errp
? error_get_pretty(*errp
) : "Unknown");
1249 vnc_disconnect_start(vs
);
1260 void vnc_client_error(VncState
*vs
)
1262 VNC_DEBUG("Closing down client sock: protocol error\n");
1263 vnc_disconnect_start(vs
);
1268 * Called to write a chunk of data to the client socket. The data may
1269 * be the raw data, or may have already been encoded by SASL.
1270 * The data will be written either straight onto the socket, or
1271 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1273 * NB, it is theoretically possible to have 2 layers of encryption,
1274 * both SASL, and this TLS layer. It is highly unlikely in practice
1275 * though, since SASL encryption will typically be a no-op if TLS
1278 * Returns the number of bytes written, which may be less than
1279 * the requested 'datalen' if the socket would block. Returns
1280 * -1 on error, and disconnects the client socket.
1282 ssize_t
vnc_client_write_buf(VncState
*vs
, const uint8_t *data
, size_t datalen
)
1286 ret
= qio_channel_write(
1287 vs
->ioc
, (const char *)data
, datalen
, &err
);
1288 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data
, datalen
, ret
);
1289 return vnc_client_io_error(vs
, ret
, &err
);
1294 * Called to write buffered data to the client socket, when not
1295 * using any SASL SSF encryption layers. Will write as much data
1296 * as possible without blocking. If all buffered data is written,
1297 * will switch the FD poll() handler back to read monitoring.
1299 * Returns the number of bytes written, which may be less than
1300 * the buffered output data if the socket would block. Returns
1301 * -1 on error, and disconnects the client socket.
1303 static ssize_t
vnc_client_write_plain(VncState
*vs
)
1307 #ifdef CONFIG_VNC_SASL
1308 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1309 vs
->output
.buffer
, vs
->output
.capacity
, vs
->output
.offset
,
1310 vs
->sasl
.waitWriteSSF
);
1312 if (vs
->sasl
.conn
&&
1314 vs
->sasl
.waitWriteSSF
) {
1315 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->sasl
.waitWriteSSF
);
1317 vs
->sasl
.waitWriteSSF
-= ret
;
1319 #endif /* CONFIG_VNC_SASL */
1320 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->output
.offset
);
1324 buffer_advance(&vs
->output
, ret
);
1326 if (vs
->output
.offset
== 0) {
1328 g_source_remove(vs
->ioc_tag
);
1330 vs
->ioc_tag
= qio_channel_add_watch(
1331 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1339 * First function called whenever there is data to be written to
1340 * the client socket. Will delegate actual work according to whether
1341 * SASL SSF layers are enabled (thus requiring encryption calls)
1343 static void vnc_client_write_locked(VncState
*vs
)
1345 #ifdef CONFIG_VNC_SASL
1346 if (vs
->sasl
.conn
&&
1348 !vs
->sasl
.waitWriteSSF
) {
1349 vnc_client_write_sasl(vs
);
1351 #endif /* CONFIG_VNC_SASL */
1353 vnc_client_write_plain(vs
);
1357 static void vnc_client_write(VncState
*vs
)
1360 vnc_lock_output(vs
);
1361 if (vs
->output
.offset
) {
1362 vnc_client_write_locked(vs
);
1363 } else if (vs
->ioc
!= NULL
) {
1365 g_source_remove(vs
->ioc_tag
);
1367 vs
->ioc_tag
= qio_channel_add_watch(
1368 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1370 vnc_unlock_output(vs
);
1373 void vnc_read_when(VncState
*vs
, VncReadEvent
*func
, size_t expecting
)
1375 vs
->read_handler
= func
;
1376 vs
->read_handler_expect
= expecting
;
1381 * Called to read a chunk of data from the client socket. The data may
1382 * be the raw data, or may need to be further decoded by SASL.
1383 * The data will be read either straight from to the socket, or
1384 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1386 * NB, it is theoretically possible to have 2 layers of encryption,
1387 * both SASL, and this TLS layer. It is highly unlikely in practice
1388 * though, since SASL encryption will typically be a no-op if TLS
1391 * Returns the number of bytes read, which may be less than
1392 * the requested 'datalen' if the socket would block. Returns
1393 * -1 on error, and disconnects the client socket.
1395 ssize_t
vnc_client_read_buf(VncState
*vs
, uint8_t *data
, size_t datalen
)
1399 ret
= qio_channel_read(
1400 vs
->ioc
, (char *)data
, datalen
, &err
);
1401 VNC_DEBUG("Read wire %p %zd -> %ld\n", data
, datalen
, ret
);
1402 return vnc_client_io_error(vs
, ret
, &err
);
1407 * Called to read data from the client socket to the input buffer,
1408 * when not using any SASL SSF encryption layers. Will read as much
1409 * data as possible without blocking.
1411 * Returns the number of bytes read. Returns -1 on error, and
1412 * disconnects the client socket.
1414 static ssize_t
vnc_client_read_plain(VncState
*vs
)
1417 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1418 vs
->input
.buffer
, vs
->input
.capacity
, vs
->input
.offset
);
1419 buffer_reserve(&vs
->input
, 4096);
1420 ret
= vnc_client_read_buf(vs
, buffer_end(&vs
->input
), 4096);
1423 vs
->input
.offset
+= ret
;
1427 static void vnc_jobs_bh(void *opaque
)
1429 VncState
*vs
= opaque
;
1431 vnc_jobs_consume_buffer(vs
);
1435 * First function called whenever there is more data to be read from
1436 * the client socket. Will delegate actual work according to whether
1437 * SASL SSF layers are enabled (thus requiring decryption calls)
1439 static void vnc_client_read(VncState
*vs
)
1443 #ifdef CONFIG_VNC_SASL
1444 if (vs
->sasl
.conn
&& vs
->sasl
.runSSF
)
1445 ret
= vnc_client_read_sasl(vs
);
1447 #endif /* CONFIG_VNC_SASL */
1448 ret
= vnc_client_read_plain(vs
);
1450 if (vs
->disconnecting
) {
1451 vnc_disconnect_finish(vs
);
1456 while (vs
->read_handler
&& vs
->input
.offset
>= vs
->read_handler_expect
) {
1457 size_t len
= vs
->read_handler_expect
;
1460 ret
= vs
->read_handler(vs
, vs
->input
.buffer
, len
);
1461 if (vs
->disconnecting
) {
1462 vnc_disconnect_finish(vs
);
1467 buffer_advance(&vs
->input
, len
);
1469 vs
->read_handler_expect
= ret
;
1474 gboolean
vnc_client_io(QIOChannel
*ioc G_GNUC_UNUSED
,
1475 GIOCondition condition
, void *opaque
)
1477 VncState
*vs
= opaque
;
1478 if (condition
& G_IO_IN
) {
1479 vnc_client_read(vs
);
1481 if (condition
& G_IO_OUT
) {
1482 vnc_client_write(vs
);
1488 void vnc_write(VncState
*vs
, const void *data
, size_t len
)
1490 buffer_reserve(&vs
->output
, len
);
1492 if (vs
->ioc
!= NULL
&& buffer_empty(&vs
->output
)) {
1494 g_source_remove(vs
->ioc_tag
);
1496 vs
->ioc_tag
= qio_channel_add_watch(
1497 vs
->ioc
, G_IO_IN
| G_IO_OUT
, vnc_client_io
, vs
, NULL
);
1500 buffer_append(&vs
->output
, data
, len
);
1503 void vnc_write_s32(VncState
*vs
, int32_t value
)
1505 vnc_write_u32(vs
, *(uint32_t *)&value
);
1508 void vnc_write_u32(VncState
*vs
, uint32_t value
)
1512 buf
[0] = (value
>> 24) & 0xFF;
1513 buf
[1] = (value
>> 16) & 0xFF;
1514 buf
[2] = (value
>> 8) & 0xFF;
1515 buf
[3] = value
& 0xFF;
1517 vnc_write(vs
, buf
, 4);
1520 void vnc_write_u16(VncState
*vs
, uint16_t value
)
1524 buf
[0] = (value
>> 8) & 0xFF;
1525 buf
[1] = value
& 0xFF;
1527 vnc_write(vs
, buf
, 2);
1530 void vnc_write_u8(VncState
*vs
, uint8_t value
)
1532 vnc_write(vs
, (char *)&value
, 1);
1535 void vnc_flush(VncState
*vs
)
1537 vnc_lock_output(vs
);
1538 if (vs
->ioc
!= NULL
&& vs
->output
.offset
) {
1539 vnc_client_write_locked(vs
);
1541 vnc_unlock_output(vs
);
1544 static uint8_t read_u8(uint8_t *data
, size_t offset
)
1546 return data
[offset
];
1549 static uint16_t read_u16(uint8_t *data
, size_t offset
)
1551 return ((data
[offset
] & 0xFF) << 8) | (data
[offset
+ 1] & 0xFF);
1554 static int32_t read_s32(uint8_t *data
, size_t offset
)
1556 return (int32_t)((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1557 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1560 uint32_t read_u32(uint8_t *data
, size_t offset
)
1562 return ((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1563 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1566 static void client_cut_text(VncState
*vs
, size_t len
, uint8_t *text
)
1570 static void check_pointer_type_change(Notifier
*notifier
, void *data
)
1572 VncState
*vs
= container_of(notifier
, VncState
, mouse_mode_notifier
);
1573 int absolute
= qemu_input_is_absolute();
1575 if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
) && vs
->absolute
!= absolute
) {
1576 vnc_lock_output(vs
);
1577 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1578 vnc_write_u8(vs
, 0);
1579 vnc_write_u16(vs
, 1);
1580 vnc_framebuffer_update(vs
, absolute
, 0,
1581 pixman_image_get_width(vs
->vd
->server
),
1582 pixman_image_get_height(vs
->vd
->server
),
1583 VNC_ENCODING_POINTER_TYPE_CHANGE
);
1584 vnc_unlock_output(vs
);
1587 vs
->absolute
= absolute
;
1590 static void pointer_event(VncState
*vs
, int button_mask
, int x
, int y
)
1592 static uint32_t bmap
[INPUT_BUTTON__MAX
] = {
1593 [INPUT_BUTTON_LEFT
] = 0x01,
1594 [INPUT_BUTTON_MIDDLE
] = 0x02,
1595 [INPUT_BUTTON_RIGHT
] = 0x04,
1596 [INPUT_BUTTON_WHEELUP
] = 0x08,
1597 [INPUT_BUTTON_WHEELDOWN
] = 0x10,
1599 QemuConsole
*con
= vs
->vd
->dcl
.con
;
1600 int width
= pixman_image_get_width(vs
->vd
->server
);
1601 int height
= pixman_image_get_height(vs
->vd
->server
);
1603 if (vs
->last_bmask
!= button_mask
) {
1604 qemu_input_update_buttons(con
, bmap
, vs
->last_bmask
, button_mask
);
1605 vs
->last_bmask
= button_mask
;
1609 qemu_input_queue_abs(con
, INPUT_AXIS_X
, x
, width
);
1610 qemu_input_queue_abs(con
, INPUT_AXIS_Y
, y
, height
);
1611 } else if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
)) {
1612 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- 0x7FFF);
1613 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- 0x7FFF);
1615 if (vs
->last_x
!= -1) {
1616 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- vs
->last_x
);
1617 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- vs
->last_y
);
1622 qemu_input_event_sync();
1625 static void reset_keys(VncState
*vs
)
1628 for(i
= 0; i
< 256; i
++) {
1629 if (vs
->modifiers_state
[i
]) {
1630 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, i
, false);
1631 vs
->modifiers_state
[i
] = 0;
1636 static void press_key(VncState
*vs
, int keysym
)
1638 int keycode
= keysym2scancode(vs
->vd
->kbd_layout
, keysym
) & SCANCODE_KEYMASK
;
1639 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, true);
1640 qemu_input_event_send_key_delay(0);
1641 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1642 qemu_input_event_send_key_delay(0);
1645 static int current_led_state(VncState
*vs
)
1649 if (vs
->modifiers_state
[0x46]) {
1650 ledstate
|= QEMU_SCROLL_LOCK_LED
;
1652 if (vs
->modifiers_state
[0x45]) {
1653 ledstate
|= QEMU_NUM_LOCK_LED
;
1655 if (vs
->modifiers_state
[0x3a]) {
1656 ledstate
|= QEMU_CAPS_LOCK_LED
;
1662 static void vnc_led_state_change(VncState
*vs
)
1666 if (!vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
)) {
1670 ledstate
= current_led_state(vs
);
1671 vnc_lock_output(vs
);
1672 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1673 vnc_write_u8(vs
, 0);
1674 vnc_write_u16(vs
, 1);
1675 vnc_framebuffer_update(vs
, 0, 0, 1, 1, VNC_ENCODING_LED_STATE
);
1676 vnc_write_u8(vs
, ledstate
);
1677 vnc_unlock_output(vs
);
1681 static void kbd_leds(void *opaque
, int ledstate
)
1683 VncState
*vs
= opaque
;
1685 bool has_changed
= (ledstate
!= current_led_state(vs
));
1687 trace_vnc_key_guest_leds((ledstate
& QEMU_CAPS_LOCK_LED
),
1688 (ledstate
& QEMU_NUM_LOCK_LED
),
1689 (ledstate
& QEMU_SCROLL_LOCK_LED
));
1691 caps
= ledstate
& QEMU_CAPS_LOCK_LED
? 1 : 0;
1692 num
= ledstate
& QEMU_NUM_LOCK_LED
? 1 : 0;
1693 scr
= ledstate
& QEMU_SCROLL_LOCK_LED
? 1 : 0;
1695 if (vs
->modifiers_state
[0x3a] != caps
) {
1696 vs
->modifiers_state
[0x3a] = caps
;
1698 if (vs
->modifiers_state
[0x45] != num
) {
1699 vs
->modifiers_state
[0x45] = num
;
1701 if (vs
->modifiers_state
[0x46] != scr
) {
1702 vs
->modifiers_state
[0x46] = scr
;
1705 /* Sending the current led state message to the client */
1707 vnc_led_state_change(vs
);
1711 static void do_key_event(VncState
*vs
, int down
, int keycode
, int sym
)
1713 /* QEMU console switch */
1715 case 0x2a: /* Left Shift */
1716 case 0x36: /* Right Shift */
1717 case 0x1d: /* Left CTRL */
1718 case 0x9d: /* Right CTRL */
1719 case 0x38: /* Left ALT */
1720 case 0xb8: /* Right ALT */
1722 vs
->modifiers_state
[keycode
] = 1;
1724 vs
->modifiers_state
[keycode
] = 0;
1726 case 0x02 ... 0x0a: /* '1' to '9' keys */
1727 if (vs
->vd
->dcl
.con
== NULL
&&
1728 down
&& vs
->modifiers_state
[0x1d] && vs
->modifiers_state
[0x38]) {
1729 /* Reset the modifiers sent to the current console */
1731 console_select(keycode
- 0x02);
1735 case 0x3a: /* CapsLock */
1736 case 0x45: /* NumLock */
1738 vs
->modifiers_state
[keycode
] ^= 1;
1742 /* Turn off the lock state sync logic if the client support the led
1745 if (down
&& vs
->vd
->lock_key_sync
&&
1746 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1747 keycode_is_keypad(vs
->vd
->kbd_layout
, keycode
)) {
1748 /* If the numlock state needs to change then simulate an additional
1749 keypress before sending this one. This will happen if the user
1750 toggles numlock away from the VNC window.
1752 if (keysym_is_numlock(vs
->vd
->kbd_layout
, sym
& 0xFFFF)) {
1753 if (!vs
->modifiers_state
[0x45]) {
1754 trace_vnc_key_sync_numlock(true);
1755 vs
->modifiers_state
[0x45] = 1;
1756 press_key(vs
, 0xff7f);
1759 if (vs
->modifiers_state
[0x45]) {
1760 trace_vnc_key_sync_numlock(false);
1761 vs
->modifiers_state
[0x45] = 0;
1762 press_key(vs
, 0xff7f);
1767 if (down
&& vs
->vd
->lock_key_sync
&&
1768 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1769 ((sym
>= 'A' && sym
<= 'Z') || (sym
>= 'a' && sym
<= 'z'))) {
1770 /* If the capslock state needs to change then simulate an additional
1771 keypress before sending this one. This will happen if the user
1772 toggles capslock away from the VNC window.
1774 int uppercase
= !!(sym
>= 'A' && sym
<= 'Z');
1775 int shift
= !!(vs
->modifiers_state
[0x2a] | vs
->modifiers_state
[0x36]);
1776 int capslock
= !!(vs
->modifiers_state
[0x3a]);
1778 if (uppercase
== shift
) {
1779 trace_vnc_key_sync_capslock(false);
1780 vs
->modifiers_state
[0x3a] = 0;
1781 press_key(vs
, 0xffe5);
1784 if (uppercase
!= shift
) {
1785 trace_vnc_key_sync_capslock(true);
1786 vs
->modifiers_state
[0x3a] = 1;
1787 press_key(vs
, 0xffe5);
1792 if (qemu_console_is_graphic(NULL
)) {
1793 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, down
);
1795 bool numlock
= vs
->modifiers_state
[0x45];
1796 bool control
= (vs
->modifiers_state
[0x1d] ||
1797 vs
->modifiers_state
[0x9d]);
1798 /* QEMU console emulation */
1801 case 0x2a: /* Left Shift */
1802 case 0x36: /* Right Shift */
1803 case 0x1d: /* Left CTRL */
1804 case 0x9d: /* Right CTRL */
1805 case 0x38: /* Left ALT */
1806 case 0xb8: /* Right ALT */
1809 kbd_put_keysym(QEMU_KEY_UP
);
1812 kbd_put_keysym(QEMU_KEY_DOWN
);
1815 kbd_put_keysym(QEMU_KEY_LEFT
);
1818 kbd_put_keysym(QEMU_KEY_RIGHT
);
1821 kbd_put_keysym(QEMU_KEY_DELETE
);
1824 kbd_put_keysym(QEMU_KEY_HOME
);
1827 kbd_put_keysym(QEMU_KEY_END
);
1830 kbd_put_keysym(QEMU_KEY_PAGEUP
);
1833 kbd_put_keysym(QEMU_KEY_PAGEDOWN
);
1837 kbd_put_keysym(numlock
? '7' : QEMU_KEY_HOME
);
1840 kbd_put_keysym(numlock
? '8' : QEMU_KEY_UP
);
1843 kbd_put_keysym(numlock
? '9' : QEMU_KEY_PAGEUP
);
1846 kbd_put_keysym(numlock
? '4' : QEMU_KEY_LEFT
);
1849 kbd_put_keysym('5');
1852 kbd_put_keysym(numlock
? '6' : QEMU_KEY_RIGHT
);
1855 kbd_put_keysym(numlock
? '1' : QEMU_KEY_END
);
1858 kbd_put_keysym(numlock
? '2' : QEMU_KEY_DOWN
);
1861 kbd_put_keysym(numlock
? '3' : QEMU_KEY_PAGEDOWN
);
1864 kbd_put_keysym('0');
1867 kbd_put_keysym(numlock
? '.' : QEMU_KEY_DELETE
);
1871 kbd_put_keysym('/');
1874 kbd_put_keysym('*');
1877 kbd_put_keysym('-');
1880 kbd_put_keysym('+');
1883 kbd_put_keysym('\n');
1888 kbd_put_keysym(sym
& 0x1f);
1890 kbd_put_keysym(sym
);
1898 static void vnc_release_modifiers(VncState
*vs
)
1900 static const int keycodes
[] = {
1901 /* shift, control, alt keys, both left & right */
1902 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1906 if (!qemu_console_is_graphic(NULL
)) {
1909 for (i
= 0; i
< ARRAY_SIZE(keycodes
); i
++) {
1910 keycode
= keycodes
[i
];
1911 if (!vs
->modifiers_state
[keycode
]) {
1914 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1918 static const char *code2name(int keycode
)
1920 return QKeyCode_lookup
[qemu_input_key_number_to_qcode(keycode
)];
1923 static void key_event(VncState
*vs
, int down
, uint32_t sym
)
1928 if (lsym
>= 'A' && lsym
<= 'Z' && qemu_console_is_graphic(NULL
)) {
1929 lsym
= lsym
- 'A' + 'a';
1932 keycode
= keysym2scancode(vs
->vd
->kbd_layout
, lsym
& 0xFFFF) & SCANCODE_KEYMASK
;
1933 trace_vnc_key_event_map(down
, sym
, keycode
, code2name(keycode
));
1934 do_key_event(vs
, down
, keycode
, sym
);
1937 static void ext_key_event(VncState
*vs
, int down
,
1938 uint32_t sym
, uint16_t keycode
)
1940 /* if the user specifies a keyboard layout, always use it */
1941 if (keyboard_layout
) {
1942 key_event(vs
, down
, sym
);
1944 trace_vnc_key_event_ext(down
, sym
, keycode
, code2name(keycode
));
1945 do_key_event(vs
, down
, keycode
, sym
);
1949 static void framebuffer_update_request(VncState
*vs
, int incremental
,
1950 int x
, int y
, int w
, int h
)
1952 vs
->need_update
= 1;
1958 vs
->force_update
= 1;
1959 vnc_set_area_dirty(vs
->dirty
, vs
->vd
, x
, y
, w
, h
);
1962 static void send_ext_key_event_ack(VncState
*vs
)
1964 vnc_lock_output(vs
);
1965 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1966 vnc_write_u8(vs
, 0);
1967 vnc_write_u16(vs
, 1);
1968 vnc_framebuffer_update(vs
, 0, 0,
1969 pixman_image_get_width(vs
->vd
->server
),
1970 pixman_image_get_height(vs
->vd
->server
),
1971 VNC_ENCODING_EXT_KEY_EVENT
);
1972 vnc_unlock_output(vs
);
1976 static void send_ext_audio_ack(VncState
*vs
)
1978 vnc_lock_output(vs
);
1979 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1980 vnc_write_u8(vs
, 0);
1981 vnc_write_u16(vs
, 1);
1982 vnc_framebuffer_update(vs
, 0, 0,
1983 pixman_image_get_width(vs
->vd
->server
),
1984 pixman_image_get_height(vs
->vd
->server
),
1985 VNC_ENCODING_AUDIO
);
1986 vnc_unlock_output(vs
);
1990 static void set_encodings(VncState
*vs
, int32_t *encodings
, size_t n_encodings
)
1993 unsigned int enc
= 0;
1996 vs
->vnc_encoding
= 0;
1997 vs
->tight
.compression
= 9;
1998 vs
->tight
.quality
= -1; /* Lossless by default */
2002 * Start from the end because the encodings are sent in order of preference.
2003 * This way the preferred encoding (first encoding defined in the array)
2004 * will be set at the end of the loop.
2006 for (i
= n_encodings
- 1; i
>= 0; i
--) {
2009 case VNC_ENCODING_RAW
:
2010 vs
->vnc_encoding
= enc
;
2012 case VNC_ENCODING_COPYRECT
:
2013 vs
->features
|= VNC_FEATURE_COPYRECT_MASK
;
2015 case VNC_ENCODING_HEXTILE
:
2016 vs
->features
|= VNC_FEATURE_HEXTILE_MASK
;
2017 vs
->vnc_encoding
= enc
;
2019 case VNC_ENCODING_TIGHT
:
2020 vs
->features
|= VNC_FEATURE_TIGHT_MASK
;
2021 vs
->vnc_encoding
= enc
;
2023 #ifdef CONFIG_VNC_PNG
2024 case VNC_ENCODING_TIGHT_PNG
:
2025 vs
->features
|= VNC_FEATURE_TIGHT_PNG_MASK
;
2026 vs
->vnc_encoding
= enc
;
2029 case VNC_ENCODING_ZLIB
:
2030 vs
->features
|= VNC_FEATURE_ZLIB_MASK
;
2031 vs
->vnc_encoding
= enc
;
2033 case VNC_ENCODING_ZRLE
:
2034 vs
->features
|= VNC_FEATURE_ZRLE_MASK
;
2035 vs
->vnc_encoding
= enc
;
2037 case VNC_ENCODING_ZYWRLE
:
2038 vs
->features
|= VNC_FEATURE_ZYWRLE_MASK
;
2039 vs
->vnc_encoding
= enc
;
2041 case VNC_ENCODING_DESKTOPRESIZE
:
2042 vs
->features
|= VNC_FEATURE_RESIZE_MASK
;
2044 case VNC_ENCODING_POINTER_TYPE_CHANGE
:
2045 vs
->features
|= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK
;
2047 case VNC_ENCODING_RICH_CURSOR
:
2048 vs
->features
|= VNC_FEATURE_RICH_CURSOR_MASK
;
2050 case VNC_ENCODING_EXT_KEY_EVENT
:
2051 send_ext_key_event_ack(vs
);
2053 case VNC_ENCODING_AUDIO
:
2054 send_ext_audio_ack(vs
);
2056 case VNC_ENCODING_WMVi
:
2057 vs
->features
|= VNC_FEATURE_WMVI_MASK
;
2059 case VNC_ENCODING_LED_STATE
:
2060 vs
->features
|= VNC_FEATURE_LED_STATE_MASK
;
2062 case VNC_ENCODING_COMPRESSLEVEL0
... VNC_ENCODING_COMPRESSLEVEL0
+ 9:
2063 vs
->tight
.compression
= (enc
& 0x0F);
2065 case VNC_ENCODING_QUALITYLEVEL0
... VNC_ENCODING_QUALITYLEVEL0
+ 9:
2066 if (vs
->vd
->lossy
) {
2067 vs
->tight
.quality
= (enc
& 0x0F);
2071 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i
, enc
, enc
);
2075 vnc_desktop_resize(vs
);
2076 check_pointer_type_change(&vs
->mouse_mode_notifier
, NULL
);
2077 vnc_led_state_change(vs
);
2080 static void set_pixel_conversion(VncState
*vs
)
2082 pixman_format_code_t fmt
= qemu_pixman_get_format(&vs
->client_pf
);
2084 if (fmt
== VNC_SERVER_FB_FORMAT
) {
2085 vs
->write_pixels
= vnc_write_pixels_copy
;
2086 vnc_hextile_set_pixel_conversion(vs
, 0);
2088 vs
->write_pixels
= vnc_write_pixels_generic
;
2089 vnc_hextile_set_pixel_conversion(vs
, 1);
2093 static void set_pixel_format(VncState
*vs
,
2094 int bits_per_pixel
, int depth
,
2095 int big_endian_flag
, int true_color_flag
,
2096 int red_max
, int green_max
, int blue_max
,
2097 int red_shift
, int green_shift
, int blue_shift
)
2099 if (!true_color_flag
) {
2100 vnc_client_error(vs
);
2104 switch (bits_per_pixel
) {
2110 vnc_client_error(vs
);
2114 vs
->client_pf
.rmax
= red_max
? red_max
: 0xFF;
2115 vs
->client_pf
.rbits
= hweight_long(red_max
);
2116 vs
->client_pf
.rshift
= red_shift
;
2117 vs
->client_pf
.rmask
= red_max
<< red_shift
;
2118 vs
->client_pf
.gmax
= green_max
? green_max
: 0xFF;
2119 vs
->client_pf
.gbits
= hweight_long(green_max
);
2120 vs
->client_pf
.gshift
= green_shift
;
2121 vs
->client_pf
.gmask
= green_max
<< green_shift
;
2122 vs
->client_pf
.bmax
= blue_max
? blue_max
: 0xFF;
2123 vs
->client_pf
.bbits
= hweight_long(blue_max
);
2124 vs
->client_pf
.bshift
= blue_shift
;
2125 vs
->client_pf
.bmask
= blue_max
<< blue_shift
;
2126 vs
->client_pf
.bits_per_pixel
= bits_per_pixel
;
2127 vs
->client_pf
.bytes_per_pixel
= bits_per_pixel
/ 8;
2128 vs
->client_pf
.depth
= bits_per_pixel
== 32 ? 24 : bits_per_pixel
;
2129 vs
->client_be
= big_endian_flag
;
2131 set_pixel_conversion(vs
);
2133 graphic_hw_invalidate(vs
->vd
->dcl
.con
);
2134 graphic_hw_update(vs
->vd
->dcl
.con
);
2137 static void pixel_format_message (VncState
*vs
) {
2138 char pad
[3] = { 0, 0, 0 };
2140 vs
->client_pf
= qemu_default_pixelformat(32);
2142 vnc_write_u8(vs
, vs
->client_pf
.bits_per_pixel
); /* bits-per-pixel */
2143 vnc_write_u8(vs
, vs
->client_pf
.depth
); /* depth */
2145 #ifdef HOST_WORDS_BIGENDIAN
2146 vnc_write_u8(vs
, 1); /* big-endian-flag */
2148 vnc_write_u8(vs
, 0); /* big-endian-flag */
2150 vnc_write_u8(vs
, 1); /* true-color-flag */
2151 vnc_write_u16(vs
, vs
->client_pf
.rmax
); /* red-max */
2152 vnc_write_u16(vs
, vs
->client_pf
.gmax
); /* green-max */
2153 vnc_write_u16(vs
, vs
->client_pf
.bmax
); /* blue-max */
2154 vnc_write_u8(vs
, vs
->client_pf
.rshift
); /* red-shift */
2155 vnc_write_u8(vs
, vs
->client_pf
.gshift
); /* green-shift */
2156 vnc_write_u8(vs
, vs
->client_pf
.bshift
); /* blue-shift */
2157 vnc_write(vs
, pad
, 3); /* padding */
2159 vnc_hextile_set_pixel_conversion(vs
, 0);
2160 vs
->write_pixels
= vnc_write_pixels_copy
;
2163 static void vnc_colordepth(VncState
*vs
)
2165 if (vnc_has_feature(vs
, VNC_FEATURE_WMVI
)) {
2166 /* Sending a WMVi message to notify the client*/
2167 vnc_lock_output(vs
);
2168 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2169 vnc_write_u8(vs
, 0);
2170 vnc_write_u16(vs
, 1); /* number of rects */
2171 vnc_framebuffer_update(vs
, 0, 0,
2172 pixman_image_get_width(vs
->vd
->server
),
2173 pixman_image_get_height(vs
->vd
->server
),
2175 pixel_format_message(vs
);
2176 vnc_unlock_output(vs
);
2179 set_pixel_conversion(vs
);
2183 static int protocol_client_msg(VncState
*vs
, uint8_t *data
, size_t len
)
2187 VncDisplay
*vd
= vs
->vd
;
2190 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2194 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT
:
2198 set_pixel_format(vs
, read_u8(data
, 4), read_u8(data
, 5),
2199 read_u8(data
, 6), read_u8(data
, 7),
2200 read_u16(data
, 8), read_u16(data
, 10),
2201 read_u16(data
, 12), read_u8(data
, 14),
2202 read_u8(data
, 15), read_u8(data
, 16));
2204 case VNC_MSG_CLIENT_SET_ENCODINGS
:
2209 limit
= read_u16(data
, 2);
2211 return 4 + (limit
* 4);
2213 limit
= read_u16(data
, 2);
2215 for (i
= 0; i
< limit
; i
++) {
2216 int32_t val
= read_s32(data
, 4 + (i
* 4));
2217 memcpy(data
+ 4 + (i
* 4), &val
, sizeof(val
));
2220 set_encodings(vs
, (int32_t *)(data
+ 4), limit
);
2222 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST
:
2226 framebuffer_update_request(vs
,
2227 read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4),
2228 read_u16(data
, 6), read_u16(data
, 8));
2230 case VNC_MSG_CLIENT_KEY_EVENT
:
2234 key_event(vs
, read_u8(data
, 1), read_u32(data
, 4));
2236 case VNC_MSG_CLIENT_POINTER_EVENT
:
2240 pointer_event(vs
, read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4));
2242 case VNC_MSG_CLIENT_CUT_TEXT
:
2247 uint32_t dlen
= read_u32(data
, 4);
2248 if (dlen
> (1 << 20)) {
2249 error_report("vnc: client_cut_text msg payload has %u bytes"
2250 " which exceeds our limit of 1MB.", dlen
);
2251 vnc_client_error(vs
);
2259 client_cut_text(vs
, read_u32(data
, 4), data
+ 8);
2261 case VNC_MSG_CLIENT_QEMU
:
2265 switch (read_u8(data
, 1)) {
2266 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT
:
2270 ext_key_event(vs
, read_u16(data
, 2),
2271 read_u32(data
, 4), read_u32(data
, 8));
2273 case VNC_MSG_CLIENT_QEMU_AUDIO
:
2277 switch (read_u16 (data
, 2)) {
2278 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE
:
2281 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE
:
2284 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT
:
2287 switch (read_u8(data
, 4)) {
2288 case 0: vs
->as
.fmt
= AUD_FMT_U8
; break;
2289 case 1: vs
->as
.fmt
= AUD_FMT_S8
; break;
2290 case 2: vs
->as
.fmt
= AUD_FMT_U16
; break;
2291 case 3: vs
->as
.fmt
= AUD_FMT_S16
; break;
2292 case 4: vs
->as
.fmt
= AUD_FMT_U32
; break;
2293 case 5: vs
->as
.fmt
= AUD_FMT_S32
; break;
2295 VNC_DEBUG("Invalid audio format %d\n", read_u8(data
, 4));
2296 vnc_client_error(vs
);
2299 vs
->as
.nchannels
= read_u8(data
, 5);
2300 if (vs
->as
.nchannels
!= 1 && vs
->as
.nchannels
!= 2) {
2301 VNC_DEBUG("Invalid audio channel coount %d\n",
2303 vnc_client_error(vs
);
2306 vs
->as
.freq
= read_u32(data
, 6);
2309 VNC_DEBUG("Invalid audio message %d\n", read_u8(data
, 4));
2310 vnc_client_error(vs
);
2316 VNC_DEBUG("Msg: %d\n", read_u16(data
, 0));
2317 vnc_client_error(vs
);
2322 VNC_DEBUG("Msg: %d\n", data
[0]);
2323 vnc_client_error(vs
);
2327 vnc_read_when(vs
, protocol_client_msg
, 1);
2331 static int protocol_client_init(VncState
*vs
, uint8_t *data
, size_t len
)
2337 mode
= data
[0] ? VNC_SHARE_MODE_SHARED
: VNC_SHARE_MODE_EXCLUSIVE
;
2338 switch (vs
->vd
->share_policy
) {
2339 case VNC_SHARE_POLICY_IGNORE
:
2341 * Ignore the shared flag. Nothing to do here.
2343 * Doesn't conform to the rfb spec but is traditional qemu
2344 * behavior, thus left here as option for compatibility
2348 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
:
2350 * Policy: Allow clients ask for exclusive access.
2352 * Implementation: When a client asks for exclusive access,
2353 * disconnect all others. Shared connects are allowed as long
2354 * as no exclusive connection exists.
2356 * This is how the rfb spec suggests to handle the shared flag.
2358 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2360 QTAILQ_FOREACH(client
, &vs
->vd
->clients
, next
) {
2364 if (client
->share_mode
!= VNC_SHARE_MODE_EXCLUSIVE
&&
2365 client
->share_mode
!= VNC_SHARE_MODE_SHARED
) {
2368 vnc_disconnect_start(client
);
2371 if (mode
== VNC_SHARE_MODE_SHARED
) {
2372 if (vs
->vd
->num_exclusive
> 0) {
2373 vnc_disconnect_start(vs
);
2378 case VNC_SHARE_POLICY_FORCE_SHARED
:
2380 * Policy: Shared connects only.
2381 * Implementation: Disallow clients asking for exclusive access.
2383 * Useful for shared desktop sessions where you don't want
2384 * someone forgetting to say -shared when running the vnc
2385 * client disconnect everybody else.
2387 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2388 vnc_disconnect_start(vs
);
2393 vnc_set_share_mode(vs
, mode
);
2395 if (vs
->vd
->num_shared
> vs
->vd
->connections_limit
) {
2396 vnc_disconnect_start(vs
);
2400 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
2401 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
2402 vnc_write_u16(vs
, vs
->client_width
);
2403 vnc_write_u16(vs
, vs
->client_height
);
2405 pixel_format_message(vs
);
2408 size
= snprintf(buf
, sizeof(buf
), "QEMU (%s)", qemu_name
);
2410 size
= snprintf(buf
, sizeof(buf
), "QEMU");
2412 vnc_write_u32(vs
, size
);
2413 vnc_write(vs
, buf
, size
);
2416 vnc_client_cache_auth(vs
);
2417 vnc_qmp_event(vs
, QAPI_EVENT_VNC_INITIALIZED
);
2419 vnc_read_when(vs
, protocol_client_msg
, 1);
2424 void start_client_init(VncState
*vs
)
2426 vnc_read_when(vs
, protocol_client_init
, 1);
2429 static void make_challenge(VncState
*vs
)
2433 srand(time(NULL
)+getpid()+getpid()*987654+rand());
2435 for (i
= 0 ; i
< sizeof(vs
->challenge
) ; i
++)
2436 vs
->challenge
[i
] = (int) (256.0*rand()/(RAND_MAX
+1.0));
2439 static int protocol_client_auth_vnc(VncState
*vs
, uint8_t *data
, size_t len
)
2441 unsigned char response
[VNC_AUTH_CHALLENGE_SIZE
];
2443 unsigned char key
[8];
2444 time_t now
= time(NULL
);
2445 QCryptoCipher
*cipher
= NULL
;
2448 if (!vs
->vd
->password
) {
2449 VNC_DEBUG("No password configured on server");
2452 if (vs
->vd
->expires
< now
) {
2453 VNC_DEBUG("Password is expired");
2457 memcpy(response
, vs
->challenge
, VNC_AUTH_CHALLENGE_SIZE
);
2459 /* Calculate the expected challenge response */
2460 pwlen
= strlen(vs
->vd
->password
);
2461 for (i
=0; i
<sizeof(key
); i
++)
2462 key
[i
] = i
<pwlen
? vs
->vd
->password
[i
] : 0;
2464 cipher
= qcrypto_cipher_new(
2465 QCRYPTO_CIPHER_ALG_DES_RFB
,
2466 QCRYPTO_CIPHER_MODE_ECB
,
2467 key
, G_N_ELEMENTS(key
),
2470 VNC_DEBUG("Cannot initialize cipher %s",
2471 error_get_pretty(err
));
2476 if (qcrypto_cipher_encrypt(cipher
,
2479 VNC_AUTH_CHALLENGE_SIZE
,
2481 VNC_DEBUG("Cannot encrypt challenge %s",
2482 error_get_pretty(err
));
2487 /* Compare expected vs actual challenge response */
2488 if (memcmp(response
, data
, VNC_AUTH_CHALLENGE_SIZE
) != 0) {
2489 VNC_DEBUG("Client challenge response did not match\n");
2492 VNC_DEBUG("Accepting VNC challenge response\n");
2493 vnc_write_u32(vs
, 0); /* Accept auth */
2496 start_client_init(vs
);
2499 qcrypto_cipher_free(cipher
);
2503 vnc_write_u32(vs
, 1); /* Reject auth */
2504 if (vs
->minor
>= 8) {
2505 static const char err
[] = "Authentication failed";
2506 vnc_write_u32(vs
, sizeof(err
));
2507 vnc_write(vs
, err
, sizeof(err
));
2510 vnc_client_error(vs
);
2511 qcrypto_cipher_free(cipher
);
2515 void start_auth_vnc(VncState
*vs
)
2518 /* Send client a 'random' challenge */
2519 vnc_write(vs
, vs
->challenge
, sizeof(vs
->challenge
));
2522 vnc_read_when(vs
, protocol_client_auth_vnc
, sizeof(vs
->challenge
));
2526 static int protocol_client_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2528 /* We only advertise 1 auth scheme at a time, so client
2529 * must pick the one we sent. Verify this */
2530 if (data
[0] != vs
->auth
) { /* Reject auth */
2531 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data
[0]);
2532 vnc_write_u32(vs
, 1);
2533 if (vs
->minor
>= 8) {
2534 static const char err
[] = "Authentication failed";
2535 vnc_write_u32(vs
, sizeof(err
));
2536 vnc_write(vs
, err
, sizeof(err
));
2538 vnc_client_error(vs
);
2539 } else { /* Accept requested auth */
2540 VNC_DEBUG("Client requested auth %d\n", (int)data
[0]);
2543 VNC_DEBUG("Accept auth none\n");
2544 if (vs
->minor
>= 8) {
2545 vnc_write_u32(vs
, 0); /* Accept auth completion */
2548 start_client_init(vs
);
2552 VNC_DEBUG("Start VNC auth\n");
2556 case VNC_AUTH_VENCRYPT
:
2557 VNC_DEBUG("Accept VeNCrypt auth\n");
2558 start_auth_vencrypt(vs
);
2561 #ifdef CONFIG_VNC_SASL
2563 VNC_DEBUG("Accept SASL auth\n");
2564 start_auth_sasl(vs
);
2566 #endif /* CONFIG_VNC_SASL */
2568 default: /* Should not be possible, but just in case */
2569 VNC_DEBUG("Reject auth %d server code bug\n", vs
->auth
);
2570 vnc_write_u8(vs
, 1);
2571 if (vs
->minor
>= 8) {
2572 static const char err
[] = "Authentication failed";
2573 vnc_write_u32(vs
, sizeof(err
));
2574 vnc_write(vs
, err
, sizeof(err
));
2576 vnc_client_error(vs
);
2582 static int protocol_version(VncState
*vs
, uint8_t *version
, size_t len
)
2586 memcpy(local
, version
, 12);
2589 if (sscanf(local
, "RFB %03d.%03d\n", &vs
->major
, &vs
->minor
) != 2) {
2590 VNC_DEBUG("Malformed protocol version %s\n", local
);
2591 vnc_client_error(vs
);
2594 VNC_DEBUG("Client request protocol version %d.%d\n", vs
->major
, vs
->minor
);
2595 if (vs
->major
!= 3 ||
2601 VNC_DEBUG("Unsupported client version\n");
2602 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2604 vnc_client_error(vs
);
2607 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2608 * as equivalent to v3.3 by servers
2610 if (vs
->minor
== 4 || vs
->minor
== 5)
2613 if (vs
->minor
== 3) {
2614 if (vs
->auth
== VNC_AUTH_NONE
) {
2615 VNC_DEBUG("Tell client auth none\n");
2616 vnc_write_u32(vs
, vs
->auth
);
2618 start_client_init(vs
);
2619 } else if (vs
->auth
== VNC_AUTH_VNC
) {
2620 VNC_DEBUG("Tell client VNC auth\n");
2621 vnc_write_u32(vs
, vs
->auth
);
2625 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs
->auth
);
2626 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2628 vnc_client_error(vs
);
2631 VNC_DEBUG("Telling client we support auth %d\n", vs
->auth
);
2632 vnc_write_u8(vs
, 1); /* num auth */
2633 vnc_write_u8(vs
, vs
->auth
);
2634 vnc_read_when(vs
, protocol_client_auth
, 1);
2641 static VncRectStat
*vnc_stat_rect(VncDisplay
*vd
, int x
, int y
)
2643 struct VncSurface
*vs
= &vd
->guest
;
2645 return &vs
->stats
[y
/ VNC_STAT_RECT
][x
/ VNC_STAT_RECT
];
2648 void vnc_sent_lossy_rect(VncState
*vs
, int x
, int y
, int w
, int h
)
2652 w
= (x
+ w
) / VNC_STAT_RECT
;
2653 h
= (y
+ h
) / VNC_STAT_RECT
;
2657 for (j
= y
; j
<= h
; j
++) {
2658 for (i
= x
; i
<= w
; i
++) {
2659 vs
->lossy_rect
[j
][i
] = 1;
2664 static int vnc_refresh_lossy_rect(VncDisplay
*vd
, int x
, int y
)
2667 int sty
= y
/ VNC_STAT_RECT
;
2668 int stx
= x
/ VNC_STAT_RECT
;
2671 y
= y
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2672 x
= x
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2674 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2677 /* kernel send buffers are full -> refresh later */
2678 if (vs
->output
.offset
) {
2682 if (!vs
->lossy_rect
[sty
][stx
]) {
2686 vs
->lossy_rect
[sty
][stx
] = 0;
2687 for (j
= 0; j
< VNC_STAT_RECT
; ++j
) {
2688 bitmap_set(vs
->dirty
[y
+ j
],
2689 x
/ VNC_DIRTY_PIXELS_PER_BIT
,
2690 VNC_STAT_RECT
/ VNC_DIRTY_PIXELS_PER_BIT
);
2698 static int vnc_update_stats(VncDisplay
*vd
, struct timeval
* tv
)
2700 int width
= pixman_image_get_width(vd
->guest
.fb
);
2701 int height
= pixman_image_get_height(vd
->guest
.fb
);
2706 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2707 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2708 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2710 rect
->updated
= false;
2714 qemu_timersub(tv
, &VNC_REFRESH_STATS
, &res
);
2716 if (timercmp(&vd
->guest
.last_freq_check
, &res
, >)) {
2719 vd
->guest
.last_freq_check
= *tv
;
2721 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2722 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2723 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2724 int count
= ARRAY_SIZE(rect
->times
);
2725 struct timeval min
, max
;
2727 if (!timerisset(&rect
->times
[count
- 1])) {
2731 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2732 qemu_timersub(tv
, &max
, &res
);
2734 if (timercmp(&res
, &VNC_REFRESH_LOSSY
, >)) {
2736 has_dirty
+= vnc_refresh_lossy_rect(vd
, x
, y
);
2737 memset(rect
->times
, 0, sizeof (rect
->times
));
2741 min
= rect
->times
[rect
->idx
];
2742 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2743 qemu_timersub(&max
, &min
, &res
);
2745 rect
->freq
= res
.tv_sec
+ res
.tv_usec
/ 1000000.;
2746 rect
->freq
/= count
;
2747 rect
->freq
= 1. / rect
->freq
;
2753 double vnc_update_freq(VncState
*vs
, int x
, int y
, int w
, int h
)
2759 x
= (x
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2760 y
= (y
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2762 for (j
= y
; j
<= y
+ h
; j
+= VNC_STAT_RECT
) {
2763 for (i
= x
; i
<= x
+ w
; i
+= VNC_STAT_RECT
) {
2764 total
+= vnc_stat_rect(vs
->vd
, i
, j
)->freq
;
2776 static void vnc_rect_updated(VncDisplay
*vd
, int x
, int y
, struct timeval
* tv
)
2780 rect
= vnc_stat_rect(vd
, x
, y
);
2781 if (rect
->updated
) {
2784 rect
->times
[rect
->idx
] = *tv
;
2785 rect
->idx
= (rect
->idx
+ 1) % ARRAY_SIZE(rect
->times
);
2786 rect
->updated
= true;
2789 static int vnc_refresh_server_surface(VncDisplay
*vd
)
2791 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2792 pixman_image_get_width(vd
->server
));
2793 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2794 pixman_image_get_height(vd
->server
));
2795 int cmp_bytes
, server_stride
, line_bytes
, guest_ll
, guest_stride
, y
= 0;
2796 uint8_t *guest_row0
= NULL
, *server_row0
;
2799 pixman_image_t
*tmpbuf
= NULL
;
2801 struct timeval tv
= { 0, 0 };
2803 if (!vd
->non_adaptive
) {
2804 gettimeofday(&tv
, NULL
);
2805 has_dirty
= vnc_update_stats(vd
, &tv
);
2809 * Walk through the guest dirty map.
2810 * Check and copy modified bits from guest to server surface.
2811 * Update server dirty map.
2813 server_row0
= (uint8_t *)pixman_image_get_data(vd
->server
);
2814 server_stride
= guest_stride
= guest_ll
=
2815 pixman_image_get_stride(vd
->server
);
2816 cmp_bytes
= MIN(VNC_DIRTY_PIXELS_PER_BIT
* VNC_SERVER_FB_BYTES
,
2818 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2819 int width
= pixman_image_get_width(vd
->server
);
2820 tmpbuf
= qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT
, width
);
2823 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd
->guest
.fb
));
2824 guest_row0
= (uint8_t *)pixman_image_get_data(vd
->guest
.fb
);
2825 guest_stride
= pixman_image_get_stride(vd
->guest
.fb
);
2826 guest_ll
= pixman_image_get_width(vd
->guest
.fb
) * ((guest_bpp
+ 7) / 8);
2828 line_bytes
= MIN(server_stride
, guest_ll
);
2832 uint8_t *guest_ptr
, *server_ptr
;
2833 unsigned long offset
= find_next_bit((unsigned long *) &vd
->guest
.dirty
,
2834 height
* VNC_DIRTY_BPL(&vd
->guest
),
2835 y
* VNC_DIRTY_BPL(&vd
->guest
));
2836 if (offset
== height
* VNC_DIRTY_BPL(&vd
->guest
)) {
2837 /* no more dirty bits */
2840 y
= offset
/ VNC_DIRTY_BPL(&vd
->guest
);
2841 x
= offset
% VNC_DIRTY_BPL(&vd
->guest
);
2843 server_ptr
= server_row0
+ y
* server_stride
+ x
* cmp_bytes
;
2845 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2846 qemu_pixman_linebuf_fill(tmpbuf
, vd
->guest
.fb
, width
, 0, y
);
2847 guest_ptr
= (uint8_t *)pixman_image_get_data(tmpbuf
);
2849 guest_ptr
= guest_row0
+ y
* guest_stride
;
2851 guest_ptr
+= x
* cmp_bytes
;
2853 for (; x
< DIV_ROUND_UP(width
, VNC_DIRTY_PIXELS_PER_BIT
);
2854 x
++, guest_ptr
+= cmp_bytes
, server_ptr
+= cmp_bytes
) {
2855 int _cmp_bytes
= cmp_bytes
;
2856 if (!test_and_clear_bit(x
, vd
->guest
.dirty
[y
])) {
2859 if ((x
+ 1) * cmp_bytes
> line_bytes
) {
2860 _cmp_bytes
= line_bytes
- x
* cmp_bytes
;
2862 assert(_cmp_bytes
>= 0);
2863 if (memcmp(server_ptr
, guest_ptr
, _cmp_bytes
) == 0) {
2866 memcpy(server_ptr
, guest_ptr
, _cmp_bytes
);
2867 if (!vd
->non_adaptive
) {
2868 vnc_rect_updated(vd
, x
* VNC_DIRTY_PIXELS_PER_BIT
,
2871 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2872 set_bit(x
, vs
->dirty
[y
]);
2879 qemu_pixman_image_unref(tmpbuf
);
2883 static void vnc_refresh(DisplayChangeListener
*dcl
)
2885 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
2887 int has_dirty
, rects
= 0;
2889 if (QTAILQ_EMPTY(&vd
->clients
)) {
2890 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_MAX
);
2894 graphic_hw_update(vd
->dcl
.con
);
2896 if (vnc_trylock_display(vd
)) {
2897 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2901 has_dirty
= vnc_refresh_server_surface(vd
);
2902 vnc_unlock_display(vd
);
2904 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
2905 rects
+= vnc_update_client(vs
, has_dirty
, false);
2906 /* vs might be free()ed here */
2909 if (has_dirty
&& rects
) {
2910 vd
->dcl
.update_interval
/= 2;
2911 if (vd
->dcl
.update_interval
< VNC_REFRESH_INTERVAL_BASE
) {
2912 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_BASE
;
2915 vd
->dcl
.update_interval
+= VNC_REFRESH_INTERVAL_INC
;
2916 if (vd
->dcl
.update_interval
> VNC_REFRESH_INTERVAL_MAX
) {
2917 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_MAX
;
2922 static void vnc_connect(VncDisplay
*vd
, QIOChannelSocket
*sioc
,
2923 bool skipauth
, bool websocket
)
2925 VncState
*vs
= g_new0(VncState
, 1);
2929 object_ref(OBJECT(vs
->sioc
));
2930 vs
->ioc
= QIO_CHANNEL(sioc
);
2931 object_ref(OBJECT(vs
->ioc
));
2934 buffer_init(&vs
->input
, "vnc-input/%p", sioc
);
2935 buffer_init(&vs
->output
, "vnc-output/%p", sioc
);
2936 buffer_init(&vs
->jobs_buffer
, "vnc-jobs_buffer/%p", sioc
);
2938 buffer_init(&vs
->tight
.tight
, "vnc-tight/%p", sioc
);
2939 buffer_init(&vs
->tight
.zlib
, "vnc-tight-zlib/%p", sioc
);
2940 buffer_init(&vs
->tight
.gradient
, "vnc-tight-gradient/%p", sioc
);
2941 #ifdef CONFIG_VNC_JPEG
2942 buffer_init(&vs
->tight
.jpeg
, "vnc-tight-jpeg/%p", sioc
);
2944 #ifdef CONFIG_VNC_PNG
2945 buffer_init(&vs
->tight
.png
, "vnc-tight-png/%p", sioc
);
2947 buffer_init(&vs
->zlib
.zlib
, "vnc-zlib/%p", sioc
);
2948 buffer_init(&vs
->zrle
.zrle
, "vnc-zrle/%p", sioc
);
2949 buffer_init(&vs
->zrle
.fb
, "vnc-zrle-fb/%p", sioc
);
2950 buffer_init(&vs
->zrle
.zlib
, "vnc-zrle-zlib/%p", sioc
);
2953 vs
->auth
= VNC_AUTH_NONE
;
2954 vs
->subauth
= VNC_AUTH_INVALID
;
2957 vs
->auth
= vd
->ws_auth
;
2958 vs
->subauth
= VNC_AUTH_INVALID
;
2960 vs
->auth
= vd
->auth
;
2961 vs
->subauth
= vd
->subauth
;
2964 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
2965 sioc
, websocket
, vs
->auth
, vs
->subauth
);
2967 vs
->lossy_rect
= g_malloc0(VNC_STAT_ROWS
* sizeof (*vs
->lossy_rect
));
2968 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
2969 vs
->lossy_rect
[i
] = g_new0(uint8_t, VNC_STAT_COLS
);
2972 VNC_DEBUG("New client on socket %p\n", vs
->sioc
);
2973 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2974 qio_channel_set_blocking(vs
->ioc
, false, NULL
);
2978 vs
->ioc_tag
= qio_channel_add_watch(
2979 vs
->ioc
, G_IO_IN
, vncws_tls_handshake_io
, vs
, NULL
);
2981 vs
->ioc_tag
= qio_channel_add_watch(
2982 vs
->ioc
, G_IO_IN
, vncws_handshake_io
, vs
, NULL
);
2985 vs
->ioc_tag
= qio_channel_add_watch(
2986 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
2989 vnc_client_cache_addr(vs
);
2990 vnc_qmp_event(vs
, QAPI_EVENT_VNC_CONNECTED
);
2991 vnc_set_share_mode(vs
, VNC_SHARE_MODE_CONNECTING
);
2993 if (!vs
->websocket
) {
2997 if (vd
->num_connecting
> vd
->connections_limit
) {
2998 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2999 if (vs
->share_mode
== VNC_SHARE_MODE_CONNECTING
) {
3000 vnc_disconnect_start(vs
);
3007 void vnc_init_state(VncState
*vs
)
3009 vs
->initialized
= true;
3010 VncDisplay
*vd
= vs
->vd
;
3011 bool first_client
= QTAILQ_EMPTY(&vd
->clients
);
3016 vs
->as
.freq
= 44100;
3017 vs
->as
.nchannels
= 2;
3018 vs
->as
.fmt
= AUD_FMT_S16
;
3019 vs
->as
.endianness
= 0;
3021 qemu_mutex_init(&vs
->output_mutex
);
3022 vs
->bh
= qemu_bh_new(vnc_jobs_bh
, vs
);
3024 QTAILQ_INSERT_TAIL(&vd
->clients
, vs
, next
);
3026 vnc_update_server_surface(vd
);
3029 graphic_hw_update(vd
->dcl
.con
);
3031 vnc_write(vs
, "RFB 003.008\n", 12);
3033 vnc_read_when(vs
, protocol_version
, 12);
3035 if (vs
->vd
->lock_key_sync
)
3036 vs
->led
= qemu_add_led_event_handler(kbd_leds
, vs
);
3038 vs
->mouse_mode_notifier
.notify
= check_pointer_type_change
;
3039 qemu_add_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
3041 /* vs might be free()ed here */
3044 static gboolean
vnc_listen_io(QIOChannel
*ioc
,
3045 GIOCondition condition
,
3048 VncDisplay
*vs
= opaque
;
3049 QIOChannelSocket
*sioc
= NULL
;
3053 graphic_hw_update(vs
->dcl
.con
);
3054 sioc
= qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc
), &err
);
3056 qio_channel_set_delay(QIO_CHANNEL(sioc
), false);
3057 vnc_connect(vs
, sioc
, false,
3058 ioc
!= QIO_CHANNEL(vs
->lsock
));
3059 object_unref(OBJECT(sioc
));
3061 /* client probably closed connection before we got there */
3068 static const DisplayChangeListenerOps dcl_ops
= {
3070 .dpy_refresh
= vnc_refresh
,
3071 .dpy_gfx_copy
= vnc_dpy_copy
,
3072 .dpy_gfx_update
= vnc_dpy_update
,
3073 .dpy_gfx_switch
= vnc_dpy_switch
,
3074 .dpy_gfx_check_format
= qemu_pixman_check_format
,
3075 .dpy_mouse_set
= vnc_mouse_set
,
3076 .dpy_cursor_define
= vnc_dpy_cursor_define
,
3079 void vnc_display_init(const char *id
)
3083 if (vnc_display_find(id
) != NULL
) {
3086 vs
= g_malloc0(sizeof(*vs
));
3088 vs
->id
= strdup(id
);
3089 QTAILQ_INSERT_TAIL(&vnc_displays
, vs
, next
);
3091 QTAILQ_INIT(&vs
->clients
);
3092 vs
->expires
= TIME_MAX
;
3094 if (keyboard_layout
) {
3095 trace_vnc_key_map_init(keyboard_layout
);
3096 vs
->kbd_layout
= init_keyboard_layout(name2keysym
, keyboard_layout
);
3098 vs
->kbd_layout
= init_keyboard_layout(name2keysym
, "en-us");
3101 if (!vs
->kbd_layout
)
3104 qemu_mutex_init(&vs
->mutex
);
3105 vnc_start_worker_thread();
3107 vs
->dcl
.ops
= &dcl_ops
;
3108 register_displaychangelistener(&vs
->dcl
);
3112 static void vnc_display_close(VncDisplay
*vs
)
3116 vs
->enabled
= false;
3117 vs
->is_unix
= false;
3118 if (vs
->lsock
!= NULL
) {
3119 if (vs
->lsock_tag
) {
3120 g_source_remove(vs
->lsock_tag
);
3122 object_unref(OBJECT(vs
->lsock
));
3125 vs
->ws_enabled
= false;
3126 if (vs
->lwebsock
!= NULL
) {
3127 if (vs
->lwebsock_tag
) {
3128 g_source_remove(vs
->lwebsock_tag
);
3130 object_unref(OBJECT(vs
->lwebsock
));
3131 vs
->lwebsock
= NULL
;
3133 vs
->auth
= VNC_AUTH_INVALID
;
3134 vs
->subauth
= VNC_AUTH_INVALID
;
3136 object_unparent(OBJECT(vs
->tlscreds
));
3137 vs
->tlscreds
= NULL
;
3139 g_free(vs
->tlsaclname
);
3140 vs
->tlsaclname
= NULL
;
3143 int vnc_display_password(const char *id
, const char *password
)
3145 VncDisplay
*vs
= vnc_display_find(id
);
3150 if (vs
->auth
== VNC_AUTH_NONE
) {
3151 error_printf_unless_qmp("If you want use passwords please enable "
3152 "password auth using '-vnc ${dpy},password'.");
3156 g_free(vs
->password
);
3157 vs
->password
= g_strdup(password
);
3162 int vnc_display_pw_expire(const char *id
, time_t expires
)
3164 VncDisplay
*vs
= vnc_display_find(id
);
3170 vs
->expires
= expires
;
3174 char *vnc_display_local_addr(const char *id
)
3176 VncDisplay
*vs
= vnc_display_find(id
);
3177 SocketAddress
*addr
;
3183 addr
= qio_channel_socket_get_local_address(vs
->lsock
, &err
);
3188 if (addr
->type
!= SOCKET_ADDRESS_KIND_INET
) {
3189 qapi_free_SocketAddress(addr
);
3192 ret
= g_strdup_printf("%s;%s", addr
->u
.inet
->host
, addr
->u
.inet
->port
);
3193 qapi_free_SocketAddress(addr
);
3198 static QemuOptsList qemu_vnc_opts
= {
3200 .head
= QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts
.head
),
3201 .implied_opt_name
= "vnc",
3205 .type
= QEMU_OPT_STRING
,
3207 .name
= "websocket",
3208 .type
= QEMU_OPT_STRING
,
3210 .name
= "tls-creds",
3211 .type
= QEMU_OPT_STRING
,
3213 /* Deprecated in favour of tls-creds */
3215 .type
= QEMU_OPT_STRING
,
3218 .type
= QEMU_OPT_STRING
,
3221 .type
= QEMU_OPT_STRING
,
3224 .type
= QEMU_OPT_NUMBER
,
3226 .name
= "connections",
3227 .type
= QEMU_OPT_NUMBER
,
3230 .type
= QEMU_OPT_NUMBER
,
3233 .type
= QEMU_OPT_BOOL
,
3236 .type
= QEMU_OPT_BOOL
,
3239 .type
= QEMU_OPT_BOOL
,
3242 .type
= QEMU_OPT_BOOL
,
3244 .name
= "lock-key-sync",
3245 .type
= QEMU_OPT_BOOL
,
3248 .type
= QEMU_OPT_BOOL
,
3250 /* Deprecated in favour of tls-creds */
3252 .type
= QEMU_OPT_BOOL
,
3254 /* Deprecated in favour of tls-creds */
3255 .name
= "x509verify",
3256 .type
= QEMU_OPT_STRING
,
3259 .type
= QEMU_OPT_BOOL
,
3262 .type
= QEMU_OPT_BOOL
,
3264 .name
= "non-adaptive",
3265 .type
= QEMU_OPT_BOOL
,
3267 { /* end of list */ }
3273 vnc_display_setup_auth(VncDisplay
*vs
,
3280 * We have a choice of 3 authentication options
3286 * The channel can be run in 2 modes
3291 * And TLS can use 2 types of credentials
3296 * We thus have 9 possible logical combinations
3301 * 4. tls + anon + none
3302 * 5. tls + anon + vnc
3303 * 6. tls + anon + sasl
3304 * 7. tls + x509 + none
3305 * 8. tls + x509 + vnc
3306 * 9. tls + x509 + sasl
3308 * These need to be mapped into the VNC auth schemes
3309 * in an appropriate manner. In regular VNC, all the
3310 * TLS options get mapped into VNC_AUTH_VENCRYPT
3313 * In websockets, the https:// protocol already provides
3314 * TLS support, so there is no need to make use of the
3315 * VeNCrypt extension. Furthermore, websockets browser
3316 * clients could not use VeNCrypt even if they wanted to,
3317 * as they cannot control when the TLS handshake takes
3318 * place. Thus there is no option but to rely on https://,
3319 * meaning combinations 4->6 and 7->9 will be mapped to
3320 * VNC auth schemes in the same way as combos 1->3.
3322 * Regardless of fact that we have a different mapping to
3323 * VNC auth mechs for plain VNC vs websockets VNC, the end
3324 * result has the same security characteristics.
3328 vs
->auth
= VNC_AUTH_VENCRYPT
;
3332 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3333 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3334 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3335 vs
->subauth
= VNC_AUTH_VENCRYPT_X509VNC
;
3336 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3337 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3338 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3339 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSVNC
;
3342 "Unsupported TLS cred type %s",
3343 object_get_typename(OBJECT(vs
->tlscreds
)));
3347 VNC_DEBUG("Initializing VNC server with password auth\n");
3348 vs
->auth
= VNC_AUTH_VNC
;
3349 vs
->subauth
= VNC_AUTH_INVALID
;
3352 vs
->ws_auth
= VNC_AUTH_VNC
;
3354 vs
->ws_auth
= VNC_AUTH_INVALID
;
3358 vs
->auth
= VNC_AUTH_VENCRYPT
;
3362 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3363 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3364 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3365 vs
->subauth
= VNC_AUTH_VENCRYPT_X509SASL
;
3366 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3367 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3368 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3369 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSSASL
;
3372 "Unsupported TLS cred type %s",
3373 object_get_typename(OBJECT(vs
->tlscreds
)));
3377 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3378 vs
->auth
= VNC_AUTH_SASL
;
3379 vs
->subauth
= VNC_AUTH_INVALID
;
3382 vs
->ws_auth
= VNC_AUTH_SASL
;
3384 vs
->ws_auth
= VNC_AUTH_INVALID
;
3388 vs
->auth
= VNC_AUTH_VENCRYPT
;
3392 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3393 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3394 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3395 vs
->subauth
= VNC_AUTH_VENCRYPT_X509NONE
;
3396 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3397 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3398 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3399 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSNONE
;
3402 "Unsupported TLS cred type %s",
3403 object_get_typename(OBJECT(vs
->tlscreds
)));
3407 VNC_DEBUG("Initializing VNC server with no auth\n");
3408 vs
->auth
= VNC_AUTH_NONE
;
3409 vs
->subauth
= VNC_AUTH_INVALID
;
3412 vs
->ws_auth
= VNC_AUTH_NONE
;
3414 vs
->ws_auth
= VNC_AUTH_INVALID
;
3422 * Handle back compat with old CLI syntax by creating some
3423 * suitable QCryptoTLSCreds objects
3425 static QCryptoTLSCreds
*
3426 vnc_display_create_creds(bool x509
,
3432 gchar
*credsid
= g_strdup_printf("tlsvnc%s", id
);
3433 Object
*parent
= object_get_objects_root();
3438 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509
,
3442 "endpoint", "server",
3444 "verify-peer", x509verify
? "yes" : "no",
3447 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON
,
3451 "endpoint", "server",
3458 error_propagate(errp
, err
);
3462 return QCRYPTO_TLS_CREDS(creds
);
3466 void vnc_display_open(const char *id
, Error
**errp
)
3468 VncDisplay
*vs
= vnc_display_find(id
);
3469 QemuOpts
*opts
= qemu_opts_find(&qemu_vnc_opts
, id
);
3470 SocketAddress
*saddr
= NULL
, *wsaddr
= NULL
;
3471 const char *share
, *device_id
;
3473 bool password
= false;
3474 bool reverse
= false;
3479 #ifdef CONFIG_VNC_SASL
3483 int lock_key_sync
= 1;
3486 error_setg(errp
, "VNC display not active");
3489 vnc_display_close(vs
);
3494 vnc
= qemu_opt_get(opts
, "vnc");
3495 if (!vnc
|| strcmp(vnc
, "none") == 0) {
3499 h
= strrchr(vnc
, ':');
3501 size_t hlen
= h
- vnc
;
3503 const char *websocket
= qemu_opt_get(opts
, "websocket");
3504 int to
= qemu_opt_get_number(opts
, "to", 0);
3505 bool has_ipv4
= qemu_opt_get(opts
, "ipv4");
3506 bool has_ipv6
= qemu_opt_get(opts
, "ipv6");
3507 bool ipv4
= qemu_opt_get_bool(opts
, "ipv4", false);
3508 bool ipv6
= qemu_opt_get_bool(opts
, "ipv6", false);
3510 saddr
= g_new0(SocketAddress
, 1);
3512 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1
)) {
3514 "SHA1 hash support is required for websockets");
3518 wsaddr
= g_new0(SocketAddress
, 1);
3519 vs
->ws_enabled
= true;
3522 if (strncmp(vnc
, "unix:", 5) == 0) {
3523 saddr
->type
= SOCKET_ADDRESS_KIND_UNIX
;
3524 saddr
->u
.q_unix
= g_new0(UnixSocketAddress
, 1);
3525 saddr
->u
.q_unix
->path
= g_strdup(vnc
+ 5);
3527 if (vs
->ws_enabled
) {
3528 error_setg(errp
, "UNIX sockets not supported with websock");
3532 unsigned long long baseport
;
3533 saddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3534 saddr
->u
.inet
= g_new0(InetSocketAddress
, 1);
3535 if (vnc
[0] == '[' && vnc
[hlen
- 1] == ']') {
3536 saddr
->u
.inet
->host
= g_strndup(vnc
+ 1, hlen
- 2);
3538 saddr
->u
.inet
->host
= g_strndup(vnc
, hlen
);
3540 if (parse_uint_full(h
+ 1, &baseport
, 10) < 0) {
3541 error_setg(errp
, "can't convert to a number: %s", h
+ 1);
3544 if (baseport
> 65535 ||
3545 baseport
+ 5900 > 65535) {
3546 error_setg(errp
, "port %s out of range", h
+ 1);
3549 saddr
->u
.inet
->port
= g_strdup_printf(
3550 "%d", (int)baseport
+ 5900);
3553 saddr
->u
.inet
->has_to
= true;
3554 saddr
->u
.inet
->to
= to
+ 5900;
3556 saddr
->u
.inet
->ipv4
= ipv4
;
3557 saddr
->u
.inet
->has_ipv4
= has_ipv4
;
3558 saddr
->u
.inet
->ipv6
= ipv6
;
3559 saddr
->u
.inet
->has_ipv6
= has_ipv6
;
3561 if (vs
->ws_enabled
) {
3562 wsaddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3563 wsaddr
->u
.inet
= g_new0(InetSocketAddress
, 1);
3564 wsaddr
->u
.inet
->host
= g_strdup(saddr
->u
.inet
->host
);
3565 wsaddr
->u
.inet
->port
= g_strdup(websocket
);
3568 wsaddr
->u
.inet
->has_to
= true;
3569 wsaddr
->u
.inet
->to
= to
;
3571 wsaddr
->u
.inet
->ipv4
= ipv4
;
3572 wsaddr
->u
.inet
->has_ipv4
= has_ipv4
;
3573 wsaddr
->u
.inet
->ipv6
= ipv6
;
3574 wsaddr
->u
.inet
->has_ipv6
= has_ipv6
;
3578 error_setg(errp
, "no vnc port specified");
3582 password
= qemu_opt_get_bool(opts
, "password", false);
3584 if (fips_get_state()) {
3586 "VNC password auth disabled due to FIPS mode, "
3587 "consider using the VeNCrypt or SASL authentication "
3588 "methods as an alternative");
3591 if (!qcrypto_cipher_supports(
3592 QCRYPTO_CIPHER_ALG_DES_RFB
)) {
3594 "Cipher backend does not support DES RFB algorithm");
3599 reverse
= qemu_opt_get_bool(opts
, "reverse", false);
3600 lock_key_sync
= qemu_opt_get_bool(opts
, "lock-key-sync", true);
3601 sasl
= qemu_opt_get_bool(opts
, "sasl", false);
3602 #ifndef CONFIG_VNC_SASL
3604 error_setg(errp
, "VNC SASL auth requires cyrus-sasl support");
3607 #endif /* CONFIG_VNC_SASL */
3608 credid
= qemu_opt_get(opts
, "tls-creds");
3611 if (qemu_opt_get(opts
, "tls") ||
3612 qemu_opt_get(opts
, "x509") ||
3613 qemu_opt_get(opts
, "x509verify")) {
3615 "'tls-creds' parameter is mutually exclusive with "
3616 "'tls', 'x509' and 'x509verify' parameters");
3620 creds
= object_resolve_path_component(
3621 object_get_objects_root(), credid
);
3623 error_setg(errp
, "No TLS credentials with id '%s'",
3627 vs
->tlscreds
= (QCryptoTLSCreds
*)
3628 object_dynamic_cast(creds
,
3629 TYPE_QCRYPTO_TLS_CREDS
);
3630 if (!vs
->tlscreds
) {
3631 error_setg(errp
, "Object with id '%s' is not TLS credentials",
3635 object_ref(OBJECT(vs
->tlscreds
));
3637 if (vs
->tlscreds
->endpoint
!= QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
) {
3639 "Expecting TLS credentials with a server endpoint");
3644 bool tls
= false, x509
= false, x509verify
= false;
3645 tls
= qemu_opt_get_bool(opts
, "tls", false);
3647 path
= qemu_opt_get(opts
, "x509");
3652 path
= qemu_opt_get(opts
, "x509verify");
3658 vs
->tlscreds
= vnc_display_create_creds(x509
,
3663 if (!vs
->tlscreds
) {
3668 acl
= qemu_opt_get_bool(opts
, "acl", false);
3670 share
= qemu_opt_get(opts
, "share");
3672 if (strcmp(share
, "ignore") == 0) {
3673 vs
->share_policy
= VNC_SHARE_POLICY_IGNORE
;
3674 } else if (strcmp(share
, "allow-exclusive") == 0) {
3675 vs
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3676 } else if (strcmp(share
, "force-shared") == 0) {
3677 vs
->share_policy
= VNC_SHARE_POLICY_FORCE_SHARED
;
3679 error_setg(errp
, "unknown vnc share= option");
3683 vs
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3685 vs
->connections_limit
= qemu_opt_get_number(opts
, "connections", 32);
3687 #ifdef CONFIG_VNC_JPEG
3688 vs
->lossy
= qemu_opt_get_bool(opts
, "lossy", false);
3690 vs
->non_adaptive
= qemu_opt_get_bool(opts
, "non-adaptive", false);
3691 /* adaptive updates are only used with tight encoding and
3692 * if lossy updates are enabled so we can disable all the
3693 * calculations otherwise */
3695 vs
->non_adaptive
= true;
3699 if (strcmp(vs
->id
, "default") == 0) {
3700 vs
->tlsaclname
= g_strdup("vnc.x509dname");
3702 vs
->tlsaclname
= g_strdup_printf("vnc.%s.x509dname", vs
->id
);
3704 qemu_acl_init(vs
->tlsaclname
);
3706 #ifdef CONFIG_VNC_SASL
3710 if (strcmp(vs
->id
, "default") == 0) {
3711 aclname
= g_strdup("vnc.username");
3713 aclname
= g_strdup_printf("vnc.%s.username", vs
->id
);
3715 vs
->sasl
.acl
= qemu_acl_init(aclname
);
3720 if (vnc_display_setup_auth(vs
, password
, sasl
, vs
->ws_enabled
, errp
) < 0) {
3724 #ifdef CONFIG_VNC_SASL
3725 if ((saslErr
= sasl_server_init(NULL
, "qemu")) != SASL_OK
) {
3726 error_setg(errp
, "Failed to initialize SASL auth: %s",
3727 sasl_errstring(saslErr
, NULL
, NULL
));
3731 vs
->lock_key_sync
= lock_key_sync
;
3733 device_id
= qemu_opt_get(opts
, "display");
3736 int head
= qemu_opt_get_number(opts
, "head", 0);
3738 dev
= qdev_find_recursive(sysbus_get_default(), device_id
);
3740 error_setg(errp
, "Device '%s' not found", device_id
);
3744 con
= qemu_console_lookup_by_device(dev
, head
);
3746 error_setg(errp
, "Device %s is not bound to a QemuConsole",
3754 if (con
!= vs
->dcl
.con
) {
3755 unregister_displaychangelistener(&vs
->dcl
);
3757 register_displaychangelistener(&vs
->dcl
);
3761 /* connect to viewer */
3762 QIOChannelSocket
*sioc
= NULL
;
3764 vs
->lwebsock
= NULL
;
3765 if (vs
->ws_enabled
) {
3766 error_setg(errp
, "Cannot use websockets in reverse mode");
3769 vs
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3770 sioc
= qio_channel_socket_new();
3771 if (qio_channel_socket_connect_sync(sioc
, saddr
, errp
) < 0) {
3774 vnc_connect(vs
, sioc
, false, false);
3775 object_unref(OBJECT(sioc
));
3777 vs
->lsock
= qio_channel_socket_new();
3778 if (qio_channel_socket_listen_sync(vs
->lsock
, saddr
, errp
) < 0) {
3781 vs
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3784 if (vs
->ws_enabled
) {
3785 vs
->lwebsock
= qio_channel_socket_new();
3786 if (qio_channel_socket_listen_sync(vs
->lwebsock
,
3787 wsaddr
, errp
) < 0) {
3788 object_unref(OBJECT(vs
->lsock
));
3794 vs
->lsock_tag
= qio_channel_add_watch(
3795 QIO_CHANNEL(vs
->lsock
),
3796 G_IO_IN
, vnc_listen_io
, vs
, NULL
);
3797 if (vs
->ws_enabled
) {
3798 vs
->lwebsock_tag
= qio_channel_add_watch(
3799 QIO_CHANNEL(vs
->lwebsock
),
3800 G_IO_IN
, vnc_listen_io
, vs
, NULL
);
3804 qapi_free_SocketAddress(saddr
);
3805 qapi_free_SocketAddress(wsaddr
);
3809 qapi_free_SocketAddress(saddr
);
3810 qapi_free_SocketAddress(wsaddr
);
3811 vs
->enabled
= false;
3812 vs
->ws_enabled
= false;
3815 void vnc_display_add_client(const char *id
, int csock
, bool skipauth
)
3817 VncDisplay
*vs
= vnc_display_find(id
);
3818 QIOChannelSocket
*sioc
;
3824 sioc
= qio_channel_socket_new_fd(csock
, NULL
);
3826 vnc_connect(vs
, sioc
, skipauth
, false);
3827 object_unref(OBJECT(sioc
));
3831 static void vnc_auto_assign_id(QemuOptsList
*olist
, QemuOpts
*opts
)
3836 id
= g_strdup("default");
3837 while (qemu_opts_find(olist
, id
)) {
3839 id
= g_strdup_printf("vnc%d", i
++);
3841 qemu_opts_set_id(opts
, id
);
3844 QemuOpts
*vnc_parse(const char *str
, Error
**errp
)
3846 QemuOptsList
*olist
= qemu_find_opts("vnc");
3847 QemuOpts
*opts
= qemu_opts_parse(olist
, str
, true, errp
);
3854 id
= qemu_opts_id(opts
);
3856 /* auto-assign id if not present */
3857 vnc_auto_assign_id(olist
, opts
);
3862 int vnc_init_func(void *opaque
, QemuOpts
*opts
, Error
**errp
)
3864 Error
*local_err
= NULL
;
3865 char *id
= (char *)qemu_opts_id(opts
);
3868 vnc_display_init(id
);
3869 vnc_display_open(id
, &local_err
);
3870 if (local_err
!= NULL
) {
3871 error_reportf_err(local_err
, "Failed to start VNC server: ");
3877 static void vnc_register_config(void)
3879 qemu_add_opts(&qemu_vnc_opts
);
3881 machine_init(vnc_register_config
);