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
;
146 addr
= qio_channel_socket_get_local_address(ioc
, errp
);
151 vnc_init_basic_info(addr
, info
, errp
);
152 qapi_free_SocketAddress(addr
);
155 static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket
*ioc
,
159 SocketAddress
*addr
= NULL
;
161 addr
= qio_channel_socket_get_remote_address(ioc
, errp
);
166 vnc_init_basic_info(addr
, info
, errp
);
167 qapi_free_SocketAddress(addr
);
170 static const char *vnc_auth_name(VncDisplay
*vd
) {
172 case VNC_AUTH_INVALID
:
188 case VNC_AUTH_VENCRYPT
:
189 switch (vd
->subauth
) {
190 case VNC_AUTH_VENCRYPT_PLAIN
:
191 return "vencrypt+plain";
192 case VNC_AUTH_VENCRYPT_TLSNONE
:
193 return "vencrypt+tls+none";
194 case VNC_AUTH_VENCRYPT_TLSVNC
:
195 return "vencrypt+tls+vnc";
196 case VNC_AUTH_VENCRYPT_TLSPLAIN
:
197 return "vencrypt+tls+plain";
198 case VNC_AUTH_VENCRYPT_X509NONE
:
199 return "vencrypt+x509+none";
200 case VNC_AUTH_VENCRYPT_X509VNC
:
201 return "vencrypt+x509+vnc";
202 case VNC_AUTH_VENCRYPT_X509PLAIN
:
203 return "vencrypt+x509+plain";
204 case VNC_AUTH_VENCRYPT_TLSSASL
:
205 return "vencrypt+tls+sasl";
206 case VNC_AUTH_VENCRYPT_X509SASL
:
207 return "vencrypt+x509+sasl";
217 static VncServerInfo
*vnc_server_info_get(VncDisplay
*vd
)
222 info
= g_malloc(sizeof(*info
));
223 vnc_init_basic_info_from_server_addr(vd
->lsock
,
224 qapi_VncServerInfo_base(info
), &err
);
225 info
->has_auth
= true;
226 info
->auth
= g_strdup(vnc_auth_name(vd
));
228 qapi_free_VncServerInfo(info
);
235 static void vnc_client_cache_auth(VncState
*client
)
242 client
->info
->x509_dname
=
243 qcrypto_tls_session_get_peer_name(client
->tls
);
244 client
->info
->has_x509_dname
=
245 client
->info
->x509_dname
!= NULL
;
247 #ifdef CONFIG_VNC_SASL
248 if (client
->sasl
.conn
&&
249 client
->sasl
.username
) {
250 client
->info
->has_sasl_username
= true;
251 client
->info
->sasl_username
= g_strdup(client
->sasl
.username
);
256 static void vnc_client_cache_addr(VncState
*client
)
260 client
->info
= g_malloc0(sizeof(*client
->info
));
261 vnc_init_basic_info_from_remote_addr(client
->sioc
,
262 qapi_VncClientInfo_base(client
->info
),
265 qapi_free_VncClientInfo(client
->info
);
271 static void vnc_qmp_event(VncState
*vs
, QAPIEvent event
)
279 si
= vnc_server_info_get(vs
->vd
);
285 case QAPI_EVENT_VNC_CONNECTED
:
286 qapi_event_send_vnc_connected(si
, qapi_VncClientInfo_base(vs
->info
),
289 case QAPI_EVENT_VNC_INITIALIZED
:
290 qapi_event_send_vnc_initialized(si
, vs
->info
, &error_abort
);
292 case QAPI_EVENT_VNC_DISCONNECTED
:
293 qapi_event_send_vnc_disconnected(si
, vs
->info
, &error_abort
);
299 qapi_free_VncServerInfo(si
);
302 static VncClientInfo
*qmp_query_vnc_client(const VncState
*client
)
307 info
= g_malloc0(sizeof(*info
));
309 vnc_init_basic_info_from_remote_addr(client
->sioc
,
310 qapi_VncClientInfo_base(info
),
314 qapi_free_VncClientInfo(info
);
318 info
->websocket
= client
->websocket
;
321 info
->x509_dname
= qcrypto_tls_session_get_peer_name(client
->tls
);
322 info
->has_x509_dname
= info
->x509_dname
!= NULL
;
324 #ifdef CONFIG_VNC_SASL
325 if (client
->sasl
.conn
&& client
->sasl
.username
) {
326 info
->has_sasl_username
= true;
327 info
->sasl_username
= g_strdup(client
->sasl
.username
);
334 static VncDisplay
*vnc_display_find(const char *id
)
339 return QTAILQ_FIRST(&vnc_displays
);
341 QTAILQ_FOREACH(vd
, &vnc_displays
, next
) {
342 if (strcmp(id
, vd
->id
) == 0) {
349 static VncClientInfoList
*qmp_query_client_list(VncDisplay
*vd
)
351 VncClientInfoList
*cinfo
, *prev
= NULL
;
354 QTAILQ_FOREACH(client
, &vd
->clients
, next
) {
355 cinfo
= g_new0(VncClientInfoList
, 1);
356 cinfo
->value
= qmp_query_vnc_client(client
);
363 VncInfo
*qmp_query_vnc(Error
**errp
)
365 VncInfo
*info
= g_malloc0(sizeof(*info
));
366 VncDisplay
*vd
= vnc_display_find(NULL
);
367 SocketAddress
*addr
= NULL
;
369 if (vd
== NULL
|| !vd
->enabled
) {
370 info
->enabled
= false;
372 info
->enabled
= true;
374 /* for compatibility with the original command */
375 info
->has_clients
= true;
376 info
->clients
= qmp_query_client_list(vd
);
378 if (vd
->lsock
== NULL
) {
382 addr
= qio_channel_socket_get_local_address(vd
->lsock
, errp
);
387 switch (addr
->type
) {
388 case SOCKET_ADDRESS_KIND_INET
:
389 info
->host
= g_strdup(addr
->u
.inet
.data
->host
);
390 info
->service
= g_strdup(addr
->u
.inet
.data
->port
);
391 if (addr
->u
.inet
.data
->ipv6
) {
392 info
->family
= NETWORK_ADDRESS_FAMILY_IPV6
;
394 info
->family
= NETWORK_ADDRESS_FAMILY_IPV4
;
398 case SOCKET_ADDRESS_KIND_UNIX
:
399 info
->host
= g_strdup("");
400 info
->service
= g_strdup(addr
->u
.q_unix
.data
->path
);
401 info
->family
= NETWORK_ADDRESS_FAMILY_UNIX
;
405 error_setg(errp
, "Unsupported socket kind %d",
410 info
->has_host
= true;
411 info
->has_service
= true;
412 info
->has_family
= true;
414 info
->has_auth
= true;
415 info
->auth
= g_strdup(vnc_auth_name(vd
));
418 qapi_free_SocketAddress(addr
);
422 qapi_free_SocketAddress(addr
);
423 qapi_free_VncInfo(info
);
427 static VncBasicInfoList
*qmp_query_server_entry(QIOChannelSocket
*ioc
,
429 VncBasicInfoList
*prev
)
431 VncBasicInfoList
*list
;
436 addr
= qio_channel_socket_get_local_address(ioc
, &err
);
442 info
= g_new0(VncBasicInfo
, 1);
443 vnc_init_basic_info(addr
, info
, &err
);
444 qapi_free_SocketAddress(addr
);
446 qapi_free_VncBasicInfo(info
);
450 info
->websocket
= websocket
;
452 list
= g_new0(VncBasicInfoList
, 1);
458 static void qmp_query_auth(VncDisplay
*vd
, VncInfo2
*info
)
462 info
->auth
= VNC_PRIMARY_AUTH_VNC
;
465 info
->auth
= VNC_PRIMARY_AUTH_RA2
;
468 info
->auth
= VNC_PRIMARY_AUTH_RA2NE
;
471 info
->auth
= VNC_PRIMARY_AUTH_TIGHT
;
474 info
->auth
= VNC_PRIMARY_AUTH_ULTRA
;
477 info
->auth
= VNC_PRIMARY_AUTH_TLS
;
479 case VNC_AUTH_VENCRYPT
:
480 info
->auth
= VNC_PRIMARY_AUTH_VENCRYPT
;
481 info
->has_vencrypt
= true;
482 switch (vd
->subauth
) {
483 case VNC_AUTH_VENCRYPT_PLAIN
:
484 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_PLAIN
;
486 case VNC_AUTH_VENCRYPT_TLSNONE
:
487 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_NONE
;
489 case VNC_AUTH_VENCRYPT_TLSVNC
:
490 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_VNC
;
492 case VNC_AUTH_VENCRYPT_TLSPLAIN
:
493 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN
;
495 case VNC_AUTH_VENCRYPT_X509NONE
:
496 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_NONE
;
498 case VNC_AUTH_VENCRYPT_X509VNC
:
499 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_VNC
;
501 case VNC_AUTH_VENCRYPT_X509PLAIN
:
502 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_PLAIN
;
504 case VNC_AUTH_VENCRYPT_TLSSASL
:
505 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_SASL
;
507 case VNC_AUTH_VENCRYPT_X509SASL
:
508 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_SASL
;
511 info
->has_vencrypt
= false;
516 info
->auth
= VNC_PRIMARY_AUTH_SASL
;
520 info
->auth
= VNC_PRIMARY_AUTH_NONE
;
525 VncInfo2List
*qmp_query_vnc_servers(Error
**errp
)
527 VncInfo2List
*item
, *prev
= NULL
;
532 QTAILQ_FOREACH(vd
, &vnc_displays
, next
) {
533 info
= g_new0(VncInfo2
, 1);
534 info
->id
= g_strdup(vd
->id
);
535 info
->clients
= qmp_query_client_list(vd
);
536 qmp_query_auth(vd
, info
);
538 dev
= DEVICE(object_property_get_link(OBJECT(vd
->dcl
.con
),
540 info
->has_display
= true;
541 info
->display
= g_strdup(dev
->id
);
543 if (vd
->lsock
!= NULL
) {
544 info
->server
= qmp_query_server_entry(
545 vd
->lsock
, false, info
->server
);
547 if (vd
->lwebsock
!= NULL
) {
548 info
->server
= qmp_query_server_entry(
549 vd
->lwebsock
, true, info
->server
);
552 item
= g_new0(VncInfo2List
, 1);
561 1) Get the queue working for IO.
562 2) there is some weirdness when using the -S option (the screen is grey
563 and not totally invalidated
564 3) resolutions > 1024
567 static int vnc_update_client(VncState
*vs
, int has_dirty
, bool sync
);
568 static void vnc_disconnect_start(VncState
*vs
);
570 static void vnc_colordepth(VncState
*vs
);
571 static void framebuffer_update_request(VncState
*vs
, int incremental
,
572 int x_position
, int y_position
,
574 static void vnc_refresh(DisplayChangeListener
*dcl
);
575 static int vnc_refresh_server_surface(VncDisplay
*vd
);
577 static int vnc_width(VncDisplay
*vd
)
579 return MIN(VNC_MAX_WIDTH
, ROUND_UP(surface_width(vd
->ds
),
580 VNC_DIRTY_PIXELS_PER_BIT
));
583 static int vnc_height(VncDisplay
*vd
)
585 return MIN(VNC_MAX_HEIGHT
, surface_height(vd
->ds
));
588 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty
[VNC_MAX_HEIGHT
],
589 VNC_MAX_WIDTH
/ VNC_DIRTY_PIXELS_PER_BIT
),
591 int x
, int y
, int w
, int h
)
593 int width
= vnc_width(vd
);
594 int height
= vnc_height(vd
);
596 /* this is needed this to ensure we updated all affected
597 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
598 w
+= (x
% VNC_DIRTY_PIXELS_PER_BIT
);
599 x
-= (x
% VNC_DIRTY_PIXELS_PER_BIT
);
603 w
= MIN(x
+ w
, width
) - x
;
604 h
= MIN(y
+ h
, height
);
607 bitmap_set(dirty
[y
], x
/ VNC_DIRTY_PIXELS_PER_BIT
,
608 DIV_ROUND_UP(w
, VNC_DIRTY_PIXELS_PER_BIT
));
612 static void vnc_dpy_update(DisplayChangeListener
*dcl
,
613 int x
, int y
, int w
, int h
)
615 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
616 struct VncSurface
*s
= &vd
->guest
;
618 vnc_set_area_dirty(s
->dirty
, vd
, x
, y
, w
, h
);
621 void vnc_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
,
624 vnc_write_u16(vs
, x
);
625 vnc_write_u16(vs
, y
);
626 vnc_write_u16(vs
, w
);
627 vnc_write_u16(vs
, h
);
629 vnc_write_s32(vs
, encoding
);
633 static void vnc_desktop_resize(VncState
*vs
)
635 if (vs
->ioc
== NULL
|| !vnc_has_feature(vs
, VNC_FEATURE_RESIZE
)) {
638 if (vs
->client_width
== pixman_image_get_width(vs
->vd
->server
) &&
639 vs
->client_height
== pixman_image_get_height(vs
->vd
->server
)) {
642 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
643 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
645 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
647 vnc_write_u16(vs
, 1); /* number of rects */
648 vnc_framebuffer_update(vs
, 0, 0, vs
->client_width
, vs
->client_height
,
649 VNC_ENCODING_DESKTOPRESIZE
);
650 vnc_unlock_output(vs
);
654 static void vnc_abort_display_jobs(VncDisplay
*vd
)
658 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
661 vnc_unlock_output(vs
);
663 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
666 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
669 vnc_unlock_output(vs
);
673 int vnc_server_fb_stride(VncDisplay
*vd
)
675 return pixman_image_get_stride(vd
->server
);
678 void *vnc_server_fb_ptr(VncDisplay
*vd
, int x
, int y
)
682 ptr
= (uint8_t *)pixman_image_get_data(vd
->server
);
683 ptr
+= y
* vnc_server_fb_stride(vd
);
684 ptr
+= x
* VNC_SERVER_FB_BYTES
;
688 static void vnc_update_server_surface(VncDisplay
*vd
)
690 qemu_pixman_image_unref(vd
->server
);
693 if (QTAILQ_EMPTY(&vd
->clients
)) {
697 vd
->server
= pixman_image_create_bits(VNC_SERVER_FB_FORMAT
,
703 static void vnc_dpy_switch(DisplayChangeListener
*dcl
,
704 DisplaySurface
*surface
)
706 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
710 vnc_abort_display_jobs(vd
);
714 vnc_update_server_surface(vd
);
717 qemu_pixman_image_unref(vd
->guest
.fb
);
718 vd
->guest
.fb
= pixman_image_ref(surface
->image
);
719 vd
->guest
.format
= surface
->format
;
720 width
= vnc_width(vd
);
721 height
= vnc_height(vd
);
722 memset(vd
->guest
.dirty
, 0x00, sizeof(vd
->guest
.dirty
));
723 vnc_set_area_dirty(vd
->guest
.dirty
, vd
, 0, 0,
726 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
728 vnc_desktop_resize(vs
);
729 if (vs
->vd
->cursor
) {
730 vnc_cursor_define(vs
);
732 memset(vs
->dirty
, 0x00, sizeof(vs
->dirty
));
733 vnc_set_area_dirty(vs
->dirty
, vd
, 0, 0,
739 static void vnc_write_pixels_copy(VncState
*vs
,
740 void *pixels
, int size
)
742 vnc_write(vs
, pixels
, size
);
745 /* slowest but generic code. */
746 void vnc_convert_pixel(VncState
*vs
, uint8_t *buf
, uint32_t v
)
750 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
751 r
= (((v
& 0x00ff0000) >> 16) << vs
->client_pf
.rbits
) >> 8;
752 g
= (((v
& 0x0000ff00) >> 8) << vs
->client_pf
.gbits
) >> 8;
753 b
= (((v
& 0x000000ff) >> 0) << vs
->client_pf
.bbits
) >> 8;
755 # error need some bits here if you change VNC_SERVER_FB_FORMAT
757 v
= (r
<< vs
->client_pf
.rshift
) |
758 (g
<< vs
->client_pf
.gshift
) |
759 (b
<< vs
->client_pf
.bshift
);
760 switch (vs
->client_pf
.bytes_per_pixel
) {
790 static void vnc_write_pixels_generic(VncState
*vs
,
791 void *pixels1
, int size
)
795 if (VNC_SERVER_FB_BYTES
== 4) {
796 uint32_t *pixels
= pixels1
;
799 for (i
= 0; i
< n
; i
++) {
800 vnc_convert_pixel(vs
, buf
, pixels
[i
]);
801 vnc_write(vs
, buf
, vs
->client_pf
.bytes_per_pixel
);
806 int vnc_raw_send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
810 VncDisplay
*vd
= vs
->vd
;
812 row
= vnc_server_fb_ptr(vd
, x
, y
);
813 for (i
= 0; i
< h
; i
++) {
814 vs
->write_pixels(vs
, row
, w
* VNC_SERVER_FB_BYTES
);
815 row
+= vnc_server_fb_stride(vd
);
820 int vnc_send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
823 bool encode_raw
= false;
824 size_t saved_offs
= vs
->output
.offset
;
826 switch(vs
->vnc_encoding
) {
827 case VNC_ENCODING_ZLIB
:
828 n
= vnc_zlib_send_framebuffer_update(vs
, x
, y
, w
, h
);
830 case VNC_ENCODING_HEXTILE
:
831 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_HEXTILE
);
832 n
= vnc_hextile_send_framebuffer_update(vs
, x
, y
, w
, h
);
834 case VNC_ENCODING_TIGHT
:
835 n
= vnc_tight_send_framebuffer_update(vs
, x
, y
, w
, h
);
837 case VNC_ENCODING_TIGHT_PNG
:
838 n
= vnc_tight_png_send_framebuffer_update(vs
, x
, y
, w
, h
);
840 case VNC_ENCODING_ZRLE
:
841 n
= vnc_zrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
843 case VNC_ENCODING_ZYWRLE
:
844 n
= vnc_zywrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
851 /* If the client has the same pixel format as our internal buffer and
852 * a RAW encoding would need less space fall back to RAW encoding to
853 * save bandwidth and processing power in the client. */
854 if (!encode_raw
&& vs
->write_pixels
== vnc_write_pixels_copy
&&
855 12 + h
* w
* VNC_SERVER_FB_BYTES
<= (vs
->output
.offset
- saved_offs
)) {
856 vs
->output
.offset
= saved_offs
;
861 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_RAW
);
862 n
= vnc_raw_send_framebuffer_update(vs
, x
, y
, w
, h
);
868 static void vnc_copy(VncState
*vs
, int src_x
, int src_y
, int dst_x
, int dst_y
, int w
, int h
)
870 /* send bitblit op to the vnc client */
872 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
874 vnc_write_u16(vs
, 1); /* number of rects */
875 vnc_framebuffer_update(vs
, dst_x
, dst_y
, w
, h
, VNC_ENCODING_COPYRECT
);
876 vnc_write_u16(vs
, src_x
);
877 vnc_write_u16(vs
, src_y
);
878 vnc_unlock_output(vs
);
882 static void vnc_dpy_copy(DisplayChangeListener
*dcl
,
883 int src_x
, int src_y
,
884 int dst_x
, int dst_y
, int w
, int h
)
886 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
890 int i
, x
, y
, pitch
, inc
, w_lim
, s
;
894 /* no client connected */
898 vnc_refresh_server_surface(vd
);
899 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
900 if (vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
901 vs
->force_update
= 1;
902 vnc_update_client(vs
, 1, true);
903 /* vs might be free()ed here */
907 /* do bitblit op on the local surface too */
908 pitch
= vnc_server_fb_stride(vd
);
909 src_row
= vnc_server_fb_ptr(vd
, src_x
, src_y
);
910 dst_row
= vnc_server_fb_ptr(vd
, dst_x
, dst_y
);
915 src_row
+= pitch
* (h
-1);
916 dst_row
+= pitch
* (h
-1);
921 w_lim
= w
- (VNC_DIRTY_PIXELS_PER_BIT
- (dst_x
% VNC_DIRTY_PIXELS_PER_BIT
));
925 w_lim
= w
- (w_lim
% VNC_DIRTY_PIXELS_PER_BIT
);
927 for (i
= 0; i
< h
; i
++) {
928 for (x
= 0; x
<= w_lim
;
929 x
+= s
, src_row
+= cmp_bytes
, dst_row
+= cmp_bytes
) {
931 if ((s
= w
- w_lim
) == 0)
934 s
= (VNC_DIRTY_PIXELS_PER_BIT
-
935 (dst_x
% VNC_DIRTY_PIXELS_PER_BIT
));
938 s
= VNC_DIRTY_PIXELS_PER_BIT
;
940 cmp_bytes
= s
* VNC_SERVER_FB_BYTES
;
941 if (memcmp(src_row
, dst_row
, cmp_bytes
) == 0)
943 memmove(dst_row
, src_row
, cmp_bytes
);
944 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
945 if (!vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
946 set_bit(((x
+ dst_x
) / VNC_DIRTY_PIXELS_PER_BIT
),
951 src_row
+= pitch
- w
* VNC_SERVER_FB_BYTES
;
952 dst_row
+= pitch
- w
* VNC_SERVER_FB_BYTES
;
956 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
957 if (vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
958 vnc_copy(vs
, src_x
, src_y
, dst_x
, dst_y
, w
, h
);
963 static void vnc_mouse_set(DisplayChangeListener
*dcl
,
964 int x
, int y
, int visible
)
966 /* can we ask the client(s) to move the pointer ??? */
969 static int vnc_cursor_define(VncState
*vs
)
971 QEMUCursor
*c
= vs
->vd
->cursor
;
974 if (vnc_has_feature(vs
, VNC_FEATURE_RICH_CURSOR
)) {
976 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
977 vnc_write_u8(vs
, 0); /* padding */
978 vnc_write_u16(vs
, 1); /* # of rects */
979 vnc_framebuffer_update(vs
, c
->hot_x
, c
->hot_y
, c
->width
, c
->height
,
980 VNC_ENCODING_RICH_CURSOR
);
981 isize
= c
->width
* c
->height
* vs
->client_pf
.bytes_per_pixel
;
982 vnc_write_pixels_generic(vs
, c
->data
, isize
);
983 vnc_write(vs
, vs
->vd
->cursor_mask
, vs
->vd
->cursor_msize
);
984 vnc_unlock_output(vs
);
990 static void vnc_dpy_cursor_define(DisplayChangeListener
*dcl
,
993 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
996 cursor_put(vd
->cursor
);
997 g_free(vd
->cursor_mask
);
1000 cursor_get(vd
->cursor
);
1001 vd
->cursor_msize
= cursor_get_mono_bpl(c
) * c
->height
;
1002 vd
->cursor_mask
= g_malloc0(vd
->cursor_msize
);
1003 cursor_get_mono_mask(c
, 0, vd
->cursor_mask
);
1005 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
1006 vnc_cursor_define(vs
);
1010 static int find_and_clear_dirty_height(VncState
*vs
,
1011 int y
, int last_x
, int x
, int height
)
1015 for (h
= 1; h
< (height
- y
); h
++) {
1016 if (!test_bit(last_x
, vs
->dirty
[y
+ h
])) {
1019 bitmap_clear(vs
->dirty
[y
+ h
], last_x
, x
- last_x
);
1025 static int vnc_update_client(VncState
*vs
, int has_dirty
, bool sync
)
1027 if (vs
->disconnecting
) {
1028 vnc_disconnect_finish(vs
);
1032 vs
->has_dirty
+= has_dirty
;
1033 if (vs
->need_update
&& !vs
->disconnecting
) {
1034 VncDisplay
*vd
= vs
->vd
;
1040 if (vs
->output
.offset
&& !vs
->audio_cap
&& !vs
->force_update
)
1041 /* kernel send buffers are full -> drop frames to throttle */
1044 if (!vs
->has_dirty
&& !vs
->audio_cap
&& !vs
->force_update
)
1048 * Send screen updates to the vnc client using the server
1049 * surface and server dirty map. guest surface updates
1050 * happening in parallel don't disturb us, the next pass will
1051 * send them to the client.
1053 job
= vnc_job_new(vs
);
1055 height
= pixman_image_get_height(vd
->server
);
1056 width
= pixman_image_get_width(vd
->server
);
1062 unsigned long offset
= find_next_bit((unsigned long *) &vs
->dirty
,
1063 height
* VNC_DIRTY_BPL(vs
),
1064 y
* VNC_DIRTY_BPL(vs
));
1065 if (offset
== height
* VNC_DIRTY_BPL(vs
)) {
1066 /* no more dirty bits */
1069 y
= offset
/ VNC_DIRTY_BPL(vs
);
1070 x
= offset
% VNC_DIRTY_BPL(vs
);
1071 x2
= find_next_zero_bit((unsigned long *) &vs
->dirty
[y
],
1072 VNC_DIRTY_BPL(vs
), x
);
1073 bitmap_clear(vs
->dirty
[y
], x
, x2
- x
);
1074 h
= find_and_clear_dirty_height(vs
, y
, x
, x2
, height
);
1075 x2
= MIN(x2
, width
/ VNC_DIRTY_PIXELS_PER_BIT
);
1077 n
+= vnc_job_add_rect(job
, x
* VNC_DIRTY_PIXELS_PER_BIT
, y
,
1078 (x2
- x
) * VNC_DIRTY_PIXELS_PER_BIT
, h
);
1080 if (!x
&& x2
== width
/ VNC_DIRTY_PIXELS_PER_BIT
) {
1092 vs
->force_update
= 0;
1097 if (vs
->disconnecting
) {
1098 vnc_disconnect_finish(vs
);
1107 static void audio_capture_notify(void *opaque
, audcnotification_e cmd
)
1109 VncState
*vs
= opaque
;
1112 case AUD_CNOTIFY_DISABLE
:
1113 vnc_lock_output(vs
);
1114 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1115 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1116 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_END
);
1117 vnc_unlock_output(vs
);
1121 case AUD_CNOTIFY_ENABLE
:
1122 vnc_lock_output(vs
);
1123 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1124 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1125 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN
);
1126 vnc_unlock_output(vs
);
1132 static void audio_capture_destroy(void *opaque
)
1136 static void audio_capture(void *opaque
, void *buf
, int size
)
1138 VncState
*vs
= opaque
;
1140 vnc_lock_output(vs
);
1141 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1142 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1143 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_DATA
);
1144 vnc_write_u32(vs
, size
);
1145 vnc_write(vs
, buf
, size
);
1146 vnc_unlock_output(vs
);
1150 static void audio_add(VncState
*vs
)
1152 struct audio_capture_ops ops
;
1154 if (vs
->audio_cap
) {
1155 error_report("audio already running");
1159 ops
.notify
= audio_capture_notify
;
1160 ops
.destroy
= audio_capture_destroy
;
1161 ops
.capture
= audio_capture
;
1163 vs
->audio_cap
= AUD_add_capture(&vs
->as
, &ops
, vs
);
1164 if (!vs
->audio_cap
) {
1165 error_report("Failed to add audio capture");
1169 static void audio_del(VncState
*vs
)
1171 if (vs
->audio_cap
) {
1172 AUD_del_capture(vs
->audio_cap
, vs
);
1173 vs
->audio_cap
= NULL
;
1177 static void vnc_disconnect_start(VncState
*vs
)
1179 if (vs
->disconnecting
) {
1182 vnc_set_share_mode(vs
, VNC_SHARE_MODE_DISCONNECTED
);
1184 g_source_remove(vs
->ioc_tag
);
1186 qio_channel_close(vs
->ioc
, NULL
);
1187 vs
->disconnecting
= TRUE
;
1190 void vnc_disconnect_finish(VncState
*vs
)
1194 vnc_jobs_join(vs
); /* Wait encoding jobs */
1196 vnc_lock_output(vs
);
1197 vnc_qmp_event(vs
, QAPI_EVENT_VNC_DISCONNECTED
);
1199 buffer_free(&vs
->input
);
1200 buffer_free(&vs
->output
);
1202 qapi_free_VncClientInfo(vs
->info
);
1205 vnc_tight_clear(vs
);
1208 #ifdef CONFIG_VNC_SASL
1209 vnc_sasl_client_cleanup(vs
);
1210 #endif /* CONFIG_VNC_SASL */
1212 vnc_release_modifiers(vs
);
1214 if (vs
->initialized
) {
1215 QTAILQ_REMOVE(&vs
->vd
->clients
, vs
, next
);
1216 qemu_remove_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
1217 if (QTAILQ_EMPTY(&vs
->vd
->clients
)) {
1218 /* last client gone */
1219 vnc_update_server_surface(vs
->vd
);
1223 if (vs
->vd
->lock_key_sync
)
1224 qemu_remove_led_event_handler(vs
->led
);
1225 vnc_unlock_output(vs
);
1227 qemu_mutex_destroy(&vs
->output_mutex
);
1228 if (vs
->bh
!= NULL
) {
1229 qemu_bh_delete(vs
->bh
);
1231 buffer_free(&vs
->jobs_buffer
);
1233 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
1234 g_free(vs
->lossy_rect
[i
]);
1236 g_free(vs
->lossy_rect
);
1238 object_unref(OBJECT(vs
->ioc
));
1240 object_unref(OBJECT(vs
->sioc
));
1245 ssize_t
vnc_client_io_error(VncState
*vs
, ssize_t ret
, Error
**errp
)
1249 VNC_DEBUG("Closing down client sock: EOF\n");
1250 } else if (ret
!= QIO_CHANNEL_ERR_BLOCK
) {
1251 VNC_DEBUG("Closing down client sock: ret %d (%s)\n",
1252 ret
, errp
? error_get_pretty(*errp
) : "Unknown");
1255 vnc_disconnect_start(vs
);
1266 void vnc_client_error(VncState
*vs
)
1268 VNC_DEBUG("Closing down client sock: protocol error\n");
1269 vnc_disconnect_start(vs
);
1274 * Called to write a chunk of data to the client socket. The data may
1275 * be the raw data, or may have already been encoded by SASL.
1276 * The data will be written either straight onto the socket, or
1277 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1279 * NB, it is theoretically possible to have 2 layers of encryption,
1280 * both SASL, and this TLS layer. It is highly unlikely in practice
1281 * though, since SASL encryption will typically be a no-op if TLS
1284 * Returns the number of bytes written, which may be less than
1285 * the requested 'datalen' if the socket would block. Returns
1286 * -1 on error, and disconnects the client socket.
1288 ssize_t
vnc_client_write_buf(VncState
*vs
, const uint8_t *data
, size_t datalen
)
1292 ret
= qio_channel_write(
1293 vs
->ioc
, (const char *)data
, datalen
, &err
);
1294 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data
, datalen
, ret
);
1295 return vnc_client_io_error(vs
, ret
, &err
);
1300 * Called to write buffered data to the client socket, when not
1301 * using any SASL SSF encryption layers. Will write as much data
1302 * as possible without blocking. If all buffered data is written,
1303 * will switch the FD poll() handler back to read monitoring.
1305 * Returns the number of bytes written, which may be less than
1306 * the buffered output data if the socket would block. Returns
1307 * -1 on error, and disconnects the client socket.
1309 static ssize_t
vnc_client_write_plain(VncState
*vs
)
1313 #ifdef CONFIG_VNC_SASL
1314 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1315 vs
->output
.buffer
, vs
->output
.capacity
, vs
->output
.offset
,
1316 vs
->sasl
.waitWriteSSF
);
1318 if (vs
->sasl
.conn
&&
1320 vs
->sasl
.waitWriteSSF
) {
1321 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->sasl
.waitWriteSSF
);
1323 vs
->sasl
.waitWriteSSF
-= ret
;
1325 #endif /* CONFIG_VNC_SASL */
1326 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->output
.offset
);
1330 buffer_advance(&vs
->output
, ret
);
1332 if (vs
->output
.offset
== 0) {
1334 g_source_remove(vs
->ioc_tag
);
1336 vs
->ioc_tag
= qio_channel_add_watch(
1337 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1345 * First function called whenever there is data to be written to
1346 * the client socket. Will delegate actual work according to whether
1347 * SASL SSF layers are enabled (thus requiring encryption calls)
1349 static void vnc_client_write_locked(VncState
*vs
)
1351 #ifdef CONFIG_VNC_SASL
1352 if (vs
->sasl
.conn
&&
1354 !vs
->sasl
.waitWriteSSF
) {
1355 vnc_client_write_sasl(vs
);
1357 #endif /* CONFIG_VNC_SASL */
1359 vnc_client_write_plain(vs
);
1363 static void vnc_client_write(VncState
*vs
)
1366 vnc_lock_output(vs
);
1367 if (vs
->output
.offset
) {
1368 vnc_client_write_locked(vs
);
1369 } else if (vs
->ioc
!= NULL
) {
1371 g_source_remove(vs
->ioc_tag
);
1373 vs
->ioc_tag
= qio_channel_add_watch(
1374 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1376 vnc_unlock_output(vs
);
1379 void vnc_read_when(VncState
*vs
, VncReadEvent
*func
, size_t expecting
)
1381 vs
->read_handler
= func
;
1382 vs
->read_handler_expect
= expecting
;
1387 * Called to read a chunk of data from the client socket. The data may
1388 * be the raw data, or may need to be further decoded by SASL.
1389 * The data will be read either straight from to the socket, or
1390 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1392 * NB, it is theoretically possible to have 2 layers of encryption,
1393 * both SASL, and this TLS layer. It is highly unlikely in practice
1394 * though, since SASL encryption will typically be a no-op if TLS
1397 * Returns the number of bytes read, which may be less than
1398 * the requested 'datalen' if the socket would block. Returns
1399 * -1 on error, and disconnects the client socket.
1401 ssize_t
vnc_client_read_buf(VncState
*vs
, uint8_t *data
, size_t datalen
)
1405 ret
= qio_channel_read(
1406 vs
->ioc
, (char *)data
, datalen
, &err
);
1407 VNC_DEBUG("Read wire %p %zd -> %ld\n", data
, datalen
, ret
);
1408 return vnc_client_io_error(vs
, ret
, &err
);
1413 * Called to read data from the client socket to the input buffer,
1414 * when not using any SASL SSF encryption layers. Will read as much
1415 * data as possible without blocking.
1417 * Returns the number of bytes read. Returns -1 on error, and
1418 * disconnects the client socket.
1420 static ssize_t
vnc_client_read_plain(VncState
*vs
)
1423 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1424 vs
->input
.buffer
, vs
->input
.capacity
, vs
->input
.offset
);
1425 buffer_reserve(&vs
->input
, 4096);
1426 ret
= vnc_client_read_buf(vs
, buffer_end(&vs
->input
), 4096);
1429 vs
->input
.offset
+= ret
;
1433 static void vnc_jobs_bh(void *opaque
)
1435 VncState
*vs
= opaque
;
1437 vnc_jobs_consume_buffer(vs
);
1441 * First function called whenever there is more data to be read from
1442 * the client socket. Will delegate actual work according to whether
1443 * SASL SSF layers are enabled (thus requiring decryption calls)
1444 * Returns 0 on success, -1 if client disconnected
1446 static int vnc_client_read(VncState
*vs
)
1450 #ifdef CONFIG_VNC_SASL
1451 if (vs
->sasl
.conn
&& vs
->sasl
.runSSF
)
1452 ret
= vnc_client_read_sasl(vs
);
1454 #endif /* CONFIG_VNC_SASL */
1455 ret
= vnc_client_read_plain(vs
);
1457 if (vs
->disconnecting
) {
1458 vnc_disconnect_finish(vs
);
1464 while (vs
->read_handler
&& vs
->input
.offset
>= vs
->read_handler_expect
) {
1465 size_t len
= vs
->read_handler_expect
;
1468 ret
= vs
->read_handler(vs
, vs
->input
.buffer
, len
);
1469 if (vs
->disconnecting
) {
1470 vnc_disconnect_finish(vs
);
1475 buffer_advance(&vs
->input
, len
);
1477 vs
->read_handler_expect
= ret
;
1483 gboolean
vnc_client_io(QIOChannel
*ioc G_GNUC_UNUSED
,
1484 GIOCondition condition
, void *opaque
)
1486 VncState
*vs
= opaque
;
1487 if (condition
& G_IO_IN
) {
1488 if (vnc_client_read(vs
) < 0) {
1492 if (condition
& G_IO_OUT
) {
1493 vnc_client_write(vs
);
1499 void vnc_write(VncState
*vs
, const void *data
, size_t len
)
1501 buffer_reserve(&vs
->output
, len
);
1503 if (vs
->ioc
!= NULL
&& buffer_empty(&vs
->output
)) {
1505 g_source_remove(vs
->ioc_tag
);
1507 vs
->ioc_tag
= qio_channel_add_watch(
1508 vs
->ioc
, G_IO_IN
| G_IO_OUT
, vnc_client_io
, vs
, NULL
);
1511 buffer_append(&vs
->output
, data
, len
);
1514 void vnc_write_s32(VncState
*vs
, int32_t value
)
1516 vnc_write_u32(vs
, *(uint32_t *)&value
);
1519 void vnc_write_u32(VncState
*vs
, uint32_t value
)
1523 buf
[0] = (value
>> 24) & 0xFF;
1524 buf
[1] = (value
>> 16) & 0xFF;
1525 buf
[2] = (value
>> 8) & 0xFF;
1526 buf
[3] = value
& 0xFF;
1528 vnc_write(vs
, buf
, 4);
1531 void vnc_write_u16(VncState
*vs
, uint16_t value
)
1535 buf
[0] = (value
>> 8) & 0xFF;
1536 buf
[1] = value
& 0xFF;
1538 vnc_write(vs
, buf
, 2);
1541 void vnc_write_u8(VncState
*vs
, uint8_t value
)
1543 vnc_write(vs
, (char *)&value
, 1);
1546 void vnc_flush(VncState
*vs
)
1548 vnc_lock_output(vs
);
1549 if (vs
->ioc
!= NULL
&& vs
->output
.offset
) {
1550 vnc_client_write_locked(vs
);
1552 vnc_unlock_output(vs
);
1555 static uint8_t read_u8(uint8_t *data
, size_t offset
)
1557 return data
[offset
];
1560 static uint16_t read_u16(uint8_t *data
, size_t offset
)
1562 return ((data
[offset
] & 0xFF) << 8) | (data
[offset
+ 1] & 0xFF);
1565 static int32_t read_s32(uint8_t *data
, size_t offset
)
1567 return (int32_t)((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1568 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1571 uint32_t read_u32(uint8_t *data
, size_t offset
)
1573 return ((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1574 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1577 static void client_cut_text(VncState
*vs
, size_t len
, uint8_t *text
)
1581 static void check_pointer_type_change(Notifier
*notifier
, void *data
)
1583 VncState
*vs
= container_of(notifier
, VncState
, mouse_mode_notifier
);
1584 int absolute
= qemu_input_is_absolute();
1586 if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
) && vs
->absolute
!= absolute
) {
1587 vnc_lock_output(vs
);
1588 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1589 vnc_write_u8(vs
, 0);
1590 vnc_write_u16(vs
, 1);
1591 vnc_framebuffer_update(vs
, absolute
, 0,
1592 pixman_image_get_width(vs
->vd
->server
),
1593 pixman_image_get_height(vs
->vd
->server
),
1594 VNC_ENCODING_POINTER_TYPE_CHANGE
);
1595 vnc_unlock_output(vs
);
1598 vs
->absolute
= absolute
;
1601 static void pointer_event(VncState
*vs
, int button_mask
, int x
, int y
)
1603 static uint32_t bmap
[INPUT_BUTTON__MAX
] = {
1604 [INPUT_BUTTON_LEFT
] = 0x01,
1605 [INPUT_BUTTON_MIDDLE
] = 0x02,
1606 [INPUT_BUTTON_RIGHT
] = 0x04,
1607 [INPUT_BUTTON_WHEEL_UP
] = 0x08,
1608 [INPUT_BUTTON_WHEEL_DOWN
] = 0x10,
1610 QemuConsole
*con
= vs
->vd
->dcl
.con
;
1611 int width
= pixman_image_get_width(vs
->vd
->server
);
1612 int height
= pixman_image_get_height(vs
->vd
->server
);
1614 if (vs
->last_bmask
!= button_mask
) {
1615 qemu_input_update_buttons(con
, bmap
, vs
->last_bmask
, button_mask
);
1616 vs
->last_bmask
= button_mask
;
1620 qemu_input_queue_abs(con
, INPUT_AXIS_X
, x
, width
);
1621 qemu_input_queue_abs(con
, INPUT_AXIS_Y
, y
, height
);
1622 } else if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
)) {
1623 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- 0x7FFF);
1624 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- 0x7FFF);
1626 if (vs
->last_x
!= -1) {
1627 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- vs
->last_x
);
1628 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- vs
->last_y
);
1633 qemu_input_event_sync();
1636 static void reset_keys(VncState
*vs
)
1639 for(i
= 0; i
< 256; i
++) {
1640 if (vs
->modifiers_state
[i
]) {
1641 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, i
, false);
1642 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1643 vs
->modifiers_state
[i
] = 0;
1648 static void press_key(VncState
*vs
, int keysym
)
1650 int keycode
= keysym2scancode(vs
->vd
->kbd_layout
, keysym
) & SCANCODE_KEYMASK
;
1651 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, true);
1652 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1653 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1654 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1657 static int current_led_state(VncState
*vs
)
1661 if (vs
->modifiers_state
[0x46]) {
1662 ledstate
|= QEMU_SCROLL_LOCK_LED
;
1664 if (vs
->modifiers_state
[0x45]) {
1665 ledstate
|= QEMU_NUM_LOCK_LED
;
1667 if (vs
->modifiers_state
[0x3a]) {
1668 ledstate
|= QEMU_CAPS_LOCK_LED
;
1674 static void vnc_led_state_change(VncState
*vs
)
1678 if (!vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
)) {
1682 ledstate
= current_led_state(vs
);
1683 vnc_lock_output(vs
);
1684 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1685 vnc_write_u8(vs
, 0);
1686 vnc_write_u16(vs
, 1);
1687 vnc_framebuffer_update(vs
, 0, 0, 1, 1, VNC_ENCODING_LED_STATE
);
1688 vnc_write_u8(vs
, ledstate
);
1689 vnc_unlock_output(vs
);
1693 static void kbd_leds(void *opaque
, int ledstate
)
1695 VncState
*vs
= opaque
;
1697 bool has_changed
= (ledstate
!= current_led_state(vs
));
1699 trace_vnc_key_guest_leds((ledstate
& QEMU_CAPS_LOCK_LED
),
1700 (ledstate
& QEMU_NUM_LOCK_LED
),
1701 (ledstate
& QEMU_SCROLL_LOCK_LED
));
1703 caps
= ledstate
& QEMU_CAPS_LOCK_LED
? 1 : 0;
1704 num
= ledstate
& QEMU_NUM_LOCK_LED
? 1 : 0;
1705 scr
= ledstate
& QEMU_SCROLL_LOCK_LED
? 1 : 0;
1707 if (vs
->modifiers_state
[0x3a] != caps
) {
1708 vs
->modifiers_state
[0x3a] = caps
;
1710 if (vs
->modifiers_state
[0x45] != num
) {
1711 vs
->modifiers_state
[0x45] = num
;
1713 if (vs
->modifiers_state
[0x46] != scr
) {
1714 vs
->modifiers_state
[0x46] = scr
;
1717 /* Sending the current led state message to the client */
1719 vnc_led_state_change(vs
);
1723 static void do_key_event(VncState
*vs
, int down
, int keycode
, int sym
)
1725 /* QEMU console switch */
1727 case 0x2a: /* Left Shift */
1728 case 0x36: /* Right Shift */
1729 case 0x1d: /* Left CTRL */
1730 case 0x9d: /* Right CTRL */
1731 case 0x38: /* Left ALT */
1732 case 0xb8: /* Right ALT */
1734 vs
->modifiers_state
[keycode
] = 1;
1736 vs
->modifiers_state
[keycode
] = 0;
1738 case 0x02 ... 0x0a: /* '1' to '9' keys */
1739 if (vs
->vd
->dcl
.con
== NULL
&&
1740 down
&& vs
->modifiers_state
[0x1d] && vs
->modifiers_state
[0x38]) {
1741 /* Reset the modifiers sent to the current console */
1743 console_select(keycode
- 0x02);
1747 case 0x3a: /* CapsLock */
1748 case 0x45: /* NumLock */
1750 vs
->modifiers_state
[keycode
] ^= 1;
1754 /* Turn off the lock state sync logic if the client support the led
1757 if (down
&& vs
->vd
->lock_key_sync
&&
1758 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1759 keycode_is_keypad(vs
->vd
->kbd_layout
, keycode
)) {
1760 /* If the numlock state needs to change then simulate an additional
1761 keypress before sending this one. This will happen if the user
1762 toggles numlock away from the VNC window.
1764 if (keysym_is_numlock(vs
->vd
->kbd_layout
, sym
& 0xFFFF)) {
1765 if (!vs
->modifiers_state
[0x45]) {
1766 trace_vnc_key_sync_numlock(true);
1767 vs
->modifiers_state
[0x45] = 1;
1768 press_key(vs
, 0xff7f);
1771 if (vs
->modifiers_state
[0x45]) {
1772 trace_vnc_key_sync_numlock(false);
1773 vs
->modifiers_state
[0x45] = 0;
1774 press_key(vs
, 0xff7f);
1779 if (down
&& vs
->vd
->lock_key_sync
&&
1780 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1781 ((sym
>= 'A' && sym
<= 'Z') || (sym
>= 'a' && sym
<= 'z'))) {
1782 /* If the capslock state needs to change then simulate an additional
1783 keypress before sending this one. This will happen if the user
1784 toggles capslock away from the VNC window.
1786 int uppercase
= !!(sym
>= 'A' && sym
<= 'Z');
1787 int shift
= !!(vs
->modifiers_state
[0x2a] | vs
->modifiers_state
[0x36]);
1788 int capslock
= !!(vs
->modifiers_state
[0x3a]);
1790 if (uppercase
== shift
) {
1791 trace_vnc_key_sync_capslock(false);
1792 vs
->modifiers_state
[0x3a] = 0;
1793 press_key(vs
, 0xffe5);
1796 if (uppercase
!= shift
) {
1797 trace_vnc_key_sync_capslock(true);
1798 vs
->modifiers_state
[0x3a] = 1;
1799 press_key(vs
, 0xffe5);
1804 if (qemu_console_is_graphic(NULL
)) {
1805 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, down
);
1806 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1808 bool numlock
= vs
->modifiers_state
[0x45];
1809 bool control
= (vs
->modifiers_state
[0x1d] ||
1810 vs
->modifiers_state
[0x9d]);
1811 /* QEMU console emulation */
1814 case 0x2a: /* Left Shift */
1815 case 0x36: /* Right Shift */
1816 case 0x1d: /* Left CTRL */
1817 case 0x9d: /* Right CTRL */
1818 case 0x38: /* Left ALT */
1819 case 0xb8: /* Right ALT */
1822 kbd_put_keysym(QEMU_KEY_UP
);
1825 kbd_put_keysym(QEMU_KEY_DOWN
);
1828 kbd_put_keysym(QEMU_KEY_LEFT
);
1831 kbd_put_keysym(QEMU_KEY_RIGHT
);
1834 kbd_put_keysym(QEMU_KEY_DELETE
);
1837 kbd_put_keysym(QEMU_KEY_HOME
);
1840 kbd_put_keysym(QEMU_KEY_END
);
1843 kbd_put_keysym(QEMU_KEY_PAGEUP
);
1846 kbd_put_keysym(QEMU_KEY_PAGEDOWN
);
1850 kbd_put_keysym(numlock
? '7' : QEMU_KEY_HOME
);
1853 kbd_put_keysym(numlock
? '8' : QEMU_KEY_UP
);
1856 kbd_put_keysym(numlock
? '9' : QEMU_KEY_PAGEUP
);
1859 kbd_put_keysym(numlock
? '4' : QEMU_KEY_LEFT
);
1862 kbd_put_keysym('5');
1865 kbd_put_keysym(numlock
? '6' : QEMU_KEY_RIGHT
);
1868 kbd_put_keysym(numlock
? '1' : QEMU_KEY_END
);
1871 kbd_put_keysym(numlock
? '2' : QEMU_KEY_DOWN
);
1874 kbd_put_keysym(numlock
? '3' : QEMU_KEY_PAGEDOWN
);
1877 kbd_put_keysym('0');
1880 kbd_put_keysym(numlock
? '.' : QEMU_KEY_DELETE
);
1884 kbd_put_keysym('/');
1887 kbd_put_keysym('*');
1890 kbd_put_keysym('-');
1893 kbd_put_keysym('+');
1896 kbd_put_keysym('\n');
1901 kbd_put_keysym(sym
& 0x1f);
1903 kbd_put_keysym(sym
);
1911 static void vnc_release_modifiers(VncState
*vs
)
1913 static const int keycodes
[] = {
1914 /* shift, control, alt keys, both left & right */
1915 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1919 if (!qemu_console_is_graphic(NULL
)) {
1922 for (i
= 0; i
< ARRAY_SIZE(keycodes
); i
++) {
1923 keycode
= keycodes
[i
];
1924 if (!vs
->modifiers_state
[keycode
]) {
1927 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1928 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1932 static const char *code2name(int keycode
)
1934 return QKeyCode_lookup
[qemu_input_key_number_to_qcode(keycode
)];
1937 static void key_event(VncState
*vs
, int down
, uint32_t sym
)
1942 if (lsym
>= 'A' && lsym
<= 'Z' && qemu_console_is_graphic(NULL
)) {
1943 lsym
= lsym
- 'A' + 'a';
1946 keycode
= keysym2scancode(vs
->vd
->kbd_layout
, lsym
& 0xFFFF) & SCANCODE_KEYMASK
;
1947 trace_vnc_key_event_map(down
, sym
, keycode
, code2name(keycode
));
1948 do_key_event(vs
, down
, keycode
, sym
);
1951 static void ext_key_event(VncState
*vs
, int down
,
1952 uint32_t sym
, uint16_t keycode
)
1954 /* if the user specifies a keyboard layout, always use it */
1955 if (keyboard_layout
) {
1956 key_event(vs
, down
, sym
);
1958 trace_vnc_key_event_ext(down
, sym
, keycode
, code2name(keycode
));
1959 do_key_event(vs
, down
, keycode
, sym
);
1963 static void framebuffer_update_request(VncState
*vs
, int incremental
,
1964 int x
, int y
, int w
, int h
)
1966 vs
->need_update
= 1;
1972 vs
->force_update
= 1;
1973 vnc_set_area_dirty(vs
->dirty
, vs
->vd
, x
, y
, w
, h
);
1976 static void send_ext_key_event_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_EXT_KEY_EVENT
);
1986 vnc_unlock_output(vs
);
1990 static void send_ext_audio_ack(VncState
*vs
)
1992 vnc_lock_output(vs
);
1993 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1994 vnc_write_u8(vs
, 0);
1995 vnc_write_u16(vs
, 1);
1996 vnc_framebuffer_update(vs
, 0, 0,
1997 pixman_image_get_width(vs
->vd
->server
),
1998 pixman_image_get_height(vs
->vd
->server
),
1999 VNC_ENCODING_AUDIO
);
2000 vnc_unlock_output(vs
);
2004 static void set_encodings(VncState
*vs
, int32_t *encodings
, size_t n_encodings
)
2007 unsigned int enc
= 0;
2010 vs
->vnc_encoding
= 0;
2011 vs
->tight
.compression
= 9;
2012 vs
->tight
.quality
= -1; /* Lossless by default */
2016 * Start from the end because the encodings are sent in order of preference.
2017 * This way the preferred encoding (first encoding defined in the array)
2018 * will be set at the end of the loop.
2020 for (i
= n_encodings
- 1; i
>= 0; i
--) {
2023 case VNC_ENCODING_RAW
:
2024 vs
->vnc_encoding
= enc
;
2026 case VNC_ENCODING_COPYRECT
:
2027 vs
->features
|= VNC_FEATURE_COPYRECT_MASK
;
2029 case VNC_ENCODING_HEXTILE
:
2030 vs
->features
|= VNC_FEATURE_HEXTILE_MASK
;
2031 vs
->vnc_encoding
= enc
;
2033 case VNC_ENCODING_TIGHT
:
2034 vs
->features
|= VNC_FEATURE_TIGHT_MASK
;
2035 vs
->vnc_encoding
= enc
;
2037 #ifdef CONFIG_VNC_PNG
2038 case VNC_ENCODING_TIGHT_PNG
:
2039 vs
->features
|= VNC_FEATURE_TIGHT_PNG_MASK
;
2040 vs
->vnc_encoding
= enc
;
2043 case VNC_ENCODING_ZLIB
:
2044 vs
->features
|= VNC_FEATURE_ZLIB_MASK
;
2045 vs
->vnc_encoding
= enc
;
2047 case VNC_ENCODING_ZRLE
:
2048 vs
->features
|= VNC_FEATURE_ZRLE_MASK
;
2049 vs
->vnc_encoding
= enc
;
2051 case VNC_ENCODING_ZYWRLE
:
2052 vs
->features
|= VNC_FEATURE_ZYWRLE_MASK
;
2053 vs
->vnc_encoding
= enc
;
2055 case VNC_ENCODING_DESKTOPRESIZE
:
2056 vs
->features
|= VNC_FEATURE_RESIZE_MASK
;
2058 case VNC_ENCODING_POINTER_TYPE_CHANGE
:
2059 vs
->features
|= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK
;
2061 case VNC_ENCODING_RICH_CURSOR
:
2062 vs
->features
|= VNC_FEATURE_RICH_CURSOR_MASK
;
2063 if (vs
->vd
->cursor
) {
2064 vnc_cursor_define(vs
);
2067 case VNC_ENCODING_EXT_KEY_EVENT
:
2068 send_ext_key_event_ack(vs
);
2070 case VNC_ENCODING_AUDIO
:
2071 send_ext_audio_ack(vs
);
2073 case VNC_ENCODING_WMVi
:
2074 vs
->features
|= VNC_FEATURE_WMVI_MASK
;
2076 case VNC_ENCODING_LED_STATE
:
2077 vs
->features
|= VNC_FEATURE_LED_STATE_MASK
;
2079 case VNC_ENCODING_COMPRESSLEVEL0
... VNC_ENCODING_COMPRESSLEVEL0
+ 9:
2080 vs
->tight
.compression
= (enc
& 0x0F);
2082 case VNC_ENCODING_QUALITYLEVEL0
... VNC_ENCODING_QUALITYLEVEL0
+ 9:
2083 if (vs
->vd
->lossy
) {
2084 vs
->tight
.quality
= (enc
& 0x0F);
2088 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i
, enc
, enc
);
2092 vnc_desktop_resize(vs
);
2093 check_pointer_type_change(&vs
->mouse_mode_notifier
, NULL
);
2094 vnc_led_state_change(vs
);
2097 static void set_pixel_conversion(VncState
*vs
)
2099 pixman_format_code_t fmt
= qemu_pixman_get_format(&vs
->client_pf
);
2101 if (fmt
== VNC_SERVER_FB_FORMAT
) {
2102 vs
->write_pixels
= vnc_write_pixels_copy
;
2103 vnc_hextile_set_pixel_conversion(vs
, 0);
2105 vs
->write_pixels
= vnc_write_pixels_generic
;
2106 vnc_hextile_set_pixel_conversion(vs
, 1);
2110 static void send_color_map(VncState
*vs
)
2114 vnc_write_u8(vs
, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES
);
2115 vnc_write_u8(vs
, 0); /* padding */
2116 vnc_write_u16(vs
, 0); /* first color */
2117 vnc_write_u16(vs
, 256); /* # of colors */
2119 for (i
= 0; i
< 256; i
++) {
2120 PixelFormat
*pf
= &vs
->client_pf
;
2122 vnc_write_u16(vs
, (((i
>> pf
->rshift
) & pf
->rmax
) << (16 - pf
->rbits
)));
2123 vnc_write_u16(vs
, (((i
>> pf
->gshift
) & pf
->gmax
) << (16 - pf
->gbits
)));
2124 vnc_write_u16(vs
, (((i
>> pf
->bshift
) & pf
->bmax
) << (16 - pf
->bbits
)));
2128 static void set_pixel_format(VncState
*vs
, int bits_per_pixel
,
2129 int big_endian_flag
, int true_color_flag
,
2130 int red_max
, int green_max
, int blue_max
,
2131 int red_shift
, int green_shift
, int blue_shift
)
2133 if (!true_color_flag
) {
2134 /* Expose a reasonable default 256 color map */
2144 switch (bits_per_pixel
) {
2150 vnc_client_error(vs
);
2154 vs
->client_pf
.rmax
= red_max
? red_max
: 0xFF;
2155 vs
->client_pf
.rbits
= hweight_long(red_max
);
2156 vs
->client_pf
.rshift
= red_shift
;
2157 vs
->client_pf
.rmask
= red_max
<< red_shift
;
2158 vs
->client_pf
.gmax
= green_max
? green_max
: 0xFF;
2159 vs
->client_pf
.gbits
= hweight_long(green_max
);
2160 vs
->client_pf
.gshift
= green_shift
;
2161 vs
->client_pf
.gmask
= green_max
<< green_shift
;
2162 vs
->client_pf
.bmax
= blue_max
? blue_max
: 0xFF;
2163 vs
->client_pf
.bbits
= hweight_long(blue_max
);
2164 vs
->client_pf
.bshift
= blue_shift
;
2165 vs
->client_pf
.bmask
= blue_max
<< blue_shift
;
2166 vs
->client_pf
.bits_per_pixel
= bits_per_pixel
;
2167 vs
->client_pf
.bytes_per_pixel
= bits_per_pixel
/ 8;
2168 vs
->client_pf
.depth
= bits_per_pixel
== 32 ? 24 : bits_per_pixel
;
2169 vs
->client_be
= big_endian_flag
;
2171 if (!true_color_flag
) {
2175 set_pixel_conversion(vs
);
2177 graphic_hw_invalidate(vs
->vd
->dcl
.con
);
2178 graphic_hw_update(vs
->vd
->dcl
.con
);
2181 static void pixel_format_message (VncState
*vs
) {
2182 char pad
[3] = { 0, 0, 0 };
2184 vs
->client_pf
= qemu_default_pixelformat(32);
2186 vnc_write_u8(vs
, vs
->client_pf
.bits_per_pixel
); /* bits-per-pixel */
2187 vnc_write_u8(vs
, vs
->client_pf
.depth
); /* depth */
2189 #ifdef HOST_WORDS_BIGENDIAN
2190 vnc_write_u8(vs
, 1); /* big-endian-flag */
2192 vnc_write_u8(vs
, 0); /* big-endian-flag */
2194 vnc_write_u8(vs
, 1); /* true-color-flag */
2195 vnc_write_u16(vs
, vs
->client_pf
.rmax
); /* red-max */
2196 vnc_write_u16(vs
, vs
->client_pf
.gmax
); /* green-max */
2197 vnc_write_u16(vs
, vs
->client_pf
.bmax
); /* blue-max */
2198 vnc_write_u8(vs
, vs
->client_pf
.rshift
); /* red-shift */
2199 vnc_write_u8(vs
, vs
->client_pf
.gshift
); /* green-shift */
2200 vnc_write_u8(vs
, vs
->client_pf
.bshift
); /* blue-shift */
2201 vnc_write(vs
, pad
, 3); /* padding */
2203 vnc_hextile_set_pixel_conversion(vs
, 0);
2204 vs
->write_pixels
= vnc_write_pixels_copy
;
2207 static void vnc_colordepth(VncState
*vs
)
2209 if (vnc_has_feature(vs
, VNC_FEATURE_WMVI
)) {
2210 /* Sending a WMVi message to notify the client*/
2211 vnc_lock_output(vs
);
2212 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2213 vnc_write_u8(vs
, 0);
2214 vnc_write_u16(vs
, 1); /* number of rects */
2215 vnc_framebuffer_update(vs
, 0, 0,
2216 pixman_image_get_width(vs
->vd
->server
),
2217 pixman_image_get_height(vs
->vd
->server
),
2219 pixel_format_message(vs
);
2220 vnc_unlock_output(vs
);
2223 set_pixel_conversion(vs
);
2227 static int protocol_client_msg(VncState
*vs
, uint8_t *data
, size_t len
)
2231 VncDisplay
*vd
= vs
->vd
;
2234 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2238 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT
:
2242 set_pixel_format(vs
, read_u8(data
, 4),
2243 read_u8(data
, 6), read_u8(data
, 7),
2244 read_u16(data
, 8), read_u16(data
, 10),
2245 read_u16(data
, 12), read_u8(data
, 14),
2246 read_u8(data
, 15), read_u8(data
, 16));
2248 case VNC_MSG_CLIENT_SET_ENCODINGS
:
2253 limit
= read_u16(data
, 2);
2255 return 4 + (limit
* 4);
2257 limit
= read_u16(data
, 2);
2259 for (i
= 0; i
< limit
; i
++) {
2260 int32_t val
= read_s32(data
, 4 + (i
* 4));
2261 memcpy(data
+ 4 + (i
* 4), &val
, sizeof(val
));
2264 set_encodings(vs
, (int32_t *)(data
+ 4), limit
);
2266 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST
:
2270 framebuffer_update_request(vs
,
2271 read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4),
2272 read_u16(data
, 6), read_u16(data
, 8));
2274 case VNC_MSG_CLIENT_KEY_EVENT
:
2278 key_event(vs
, read_u8(data
, 1), read_u32(data
, 4));
2280 case VNC_MSG_CLIENT_POINTER_EVENT
:
2284 pointer_event(vs
, read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4));
2286 case VNC_MSG_CLIENT_CUT_TEXT
:
2291 uint32_t dlen
= read_u32(data
, 4);
2292 if (dlen
> (1 << 20)) {
2293 error_report("vnc: client_cut_text msg payload has %u bytes"
2294 " which exceeds our limit of 1MB.", dlen
);
2295 vnc_client_error(vs
);
2303 client_cut_text(vs
, read_u32(data
, 4), data
+ 8);
2305 case VNC_MSG_CLIENT_QEMU
:
2309 switch (read_u8(data
, 1)) {
2310 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT
:
2314 ext_key_event(vs
, read_u16(data
, 2),
2315 read_u32(data
, 4), read_u32(data
, 8));
2317 case VNC_MSG_CLIENT_QEMU_AUDIO
:
2321 switch (read_u16 (data
, 2)) {
2322 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE
:
2325 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE
:
2328 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT
:
2331 switch (read_u8(data
, 4)) {
2332 case 0: vs
->as
.fmt
= AUD_FMT_U8
; break;
2333 case 1: vs
->as
.fmt
= AUD_FMT_S8
; break;
2334 case 2: vs
->as
.fmt
= AUD_FMT_U16
; break;
2335 case 3: vs
->as
.fmt
= AUD_FMT_S16
; break;
2336 case 4: vs
->as
.fmt
= AUD_FMT_U32
; break;
2337 case 5: vs
->as
.fmt
= AUD_FMT_S32
; break;
2339 VNC_DEBUG("Invalid audio format %d\n", read_u8(data
, 4));
2340 vnc_client_error(vs
);
2343 vs
->as
.nchannels
= read_u8(data
, 5);
2344 if (vs
->as
.nchannels
!= 1 && vs
->as
.nchannels
!= 2) {
2345 VNC_DEBUG("Invalid audio channel coount %d\n",
2347 vnc_client_error(vs
);
2350 vs
->as
.freq
= read_u32(data
, 6);
2353 VNC_DEBUG("Invalid audio message %d\n", read_u8(data
, 4));
2354 vnc_client_error(vs
);
2360 VNC_DEBUG("Msg: %d\n", read_u16(data
, 0));
2361 vnc_client_error(vs
);
2366 VNC_DEBUG("Msg: %d\n", data
[0]);
2367 vnc_client_error(vs
);
2371 vnc_read_when(vs
, protocol_client_msg
, 1);
2375 static int protocol_client_init(VncState
*vs
, uint8_t *data
, size_t len
)
2381 mode
= data
[0] ? VNC_SHARE_MODE_SHARED
: VNC_SHARE_MODE_EXCLUSIVE
;
2382 switch (vs
->vd
->share_policy
) {
2383 case VNC_SHARE_POLICY_IGNORE
:
2385 * Ignore the shared flag. Nothing to do here.
2387 * Doesn't conform to the rfb spec but is traditional qemu
2388 * behavior, thus left here as option for compatibility
2392 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
:
2394 * Policy: Allow clients ask for exclusive access.
2396 * Implementation: When a client asks for exclusive access,
2397 * disconnect all others. Shared connects are allowed as long
2398 * as no exclusive connection exists.
2400 * This is how the rfb spec suggests to handle the shared flag.
2402 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2404 QTAILQ_FOREACH(client
, &vs
->vd
->clients
, next
) {
2408 if (client
->share_mode
!= VNC_SHARE_MODE_EXCLUSIVE
&&
2409 client
->share_mode
!= VNC_SHARE_MODE_SHARED
) {
2412 vnc_disconnect_start(client
);
2415 if (mode
== VNC_SHARE_MODE_SHARED
) {
2416 if (vs
->vd
->num_exclusive
> 0) {
2417 vnc_disconnect_start(vs
);
2422 case VNC_SHARE_POLICY_FORCE_SHARED
:
2424 * Policy: Shared connects only.
2425 * Implementation: Disallow clients asking for exclusive access.
2427 * Useful for shared desktop sessions where you don't want
2428 * someone forgetting to say -shared when running the vnc
2429 * client disconnect everybody else.
2431 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2432 vnc_disconnect_start(vs
);
2437 vnc_set_share_mode(vs
, mode
);
2439 if (vs
->vd
->num_shared
> vs
->vd
->connections_limit
) {
2440 vnc_disconnect_start(vs
);
2444 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
2445 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
2446 vnc_write_u16(vs
, vs
->client_width
);
2447 vnc_write_u16(vs
, vs
->client_height
);
2449 pixel_format_message(vs
);
2452 size
= snprintf(buf
, sizeof(buf
), "QEMU (%s)", qemu_name
);
2454 size
= snprintf(buf
, sizeof(buf
), "QEMU");
2456 vnc_write_u32(vs
, size
);
2457 vnc_write(vs
, buf
, size
);
2460 vnc_client_cache_auth(vs
);
2461 vnc_qmp_event(vs
, QAPI_EVENT_VNC_INITIALIZED
);
2463 vnc_read_when(vs
, protocol_client_msg
, 1);
2468 void start_client_init(VncState
*vs
)
2470 vnc_read_when(vs
, protocol_client_init
, 1);
2473 static void make_challenge(VncState
*vs
)
2477 srand(time(NULL
)+getpid()+getpid()*987654+rand());
2479 for (i
= 0 ; i
< sizeof(vs
->challenge
) ; i
++)
2480 vs
->challenge
[i
] = (int) (256.0*rand()/(RAND_MAX
+1.0));
2483 static int protocol_client_auth_vnc(VncState
*vs
, uint8_t *data
, size_t len
)
2485 unsigned char response
[VNC_AUTH_CHALLENGE_SIZE
];
2487 unsigned char key
[8];
2488 time_t now
= time(NULL
);
2489 QCryptoCipher
*cipher
= NULL
;
2492 if (!vs
->vd
->password
) {
2493 VNC_DEBUG("No password configured on server");
2496 if (vs
->vd
->expires
< now
) {
2497 VNC_DEBUG("Password is expired");
2501 memcpy(response
, vs
->challenge
, VNC_AUTH_CHALLENGE_SIZE
);
2503 /* Calculate the expected challenge response */
2504 pwlen
= strlen(vs
->vd
->password
);
2505 for (i
=0; i
<sizeof(key
); i
++)
2506 key
[i
] = i
<pwlen
? vs
->vd
->password
[i
] : 0;
2508 cipher
= qcrypto_cipher_new(
2509 QCRYPTO_CIPHER_ALG_DES_RFB
,
2510 QCRYPTO_CIPHER_MODE_ECB
,
2511 key
, G_N_ELEMENTS(key
),
2514 VNC_DEBUG("Cannot initialize cipher %s",
2515 error_get_pretty(err
));
2520 if (qcrypto_cipher_encrypt(cipher
,
2523 VNC_AUTH_CHALLENGE_SIZE
,
2525 VNC_DEBUG("Cannot encrypt challenge %s",
2526 error_get_pretty(err
));
2531 /* Compare expected vs actual challenge response */
2532 if (memcmp(response
, data
, VNC_AUTH_CHALLENGE_SIZE
) != 0) {
2533 VNC_DEBUG("Client challenge response did not match\n");
2536 VNC_DEBUG("Accepting VNC challenge response\n");
2537 vnc_write_u32(vs
, 0); /* Accept auth */
2540 start_client_init(vs
);
2543 qcrypto_cipher_free(cipher
);
2547 vnc_write_u32(vs
, 1); /* Reject auth */
2548 if (vs
->minor
>= 8) {
2549 static const char err
[] = "Authentication failed";
2550 vnc_write_u32(vs
, sizeof(err
));
2551 vnc_write(vs
, err
, sizeof(err
));
2554 vnc_client_error(vs
);
2555 qcrypto_cipher_free(cipher
);
2559 void start_auth_vnc(VncState
*vs
)
2562 /* Send client a 'random' challenge */
2563 vnc_write(vs
, vs
->challenge
, sizeof(vs
->challenge
));
2566 vnc_read_when(vs
, protocol_client_auth_vnc
, sizeof(vs
->challenge
));
2570 static int protocol_client_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2572 /* We only advertise 1 auth scheme at a time, so client
2573 * must pick the one we sent. Verify this */
2574 if (data
[0] != vs
->auth
) { /* Reject auth */
2575 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data
[0]);
2576 vnc_write_u32(vs
, 1);
2577 if (vs
->minor
>= 8) {
2578 static const char err
[] = "Authentication failed";
2579 vnc_write_u32(vs
, sizeof(err
));
2580 vnc_write(vs
, err
, sizeof(err
));
2582 vnc_client_error(vs
);
2583 } else { /* Accept requested auth */
2584 VNC_DEBUG("Client requested auth %d\n", (int)data
[0]);
2587 VNC_DEBUG("Accept auth none\n");
2588 if (vs
->minor
>= 8) {
2589 vnc_write_u32(vs
, 0); /* Accept auth completion */
2592 start_client_init(vs
);
2596 VNC_DEBUG("Start VNC auth\n");
2600 case VNC_AUTH_VENCRYPT
:
2601 VNC_DEBUG("Accept VeNCrypt auth\n");
2602 start_auth_vencrypt(vs
);
2605 #ifdef CONFIG_VNC_SASL
2607 VNC_DEBUG("Accept SASL auth\n");
2608 start_auth_sasl(vs
);
2610 #endif /* CONFIG_VNC_SASL */
2612 default: /* Should not be possible, but just in case */
2613 VNC_DEBUG("Reject auth %d server code bug\n", vs
->auth
);
2614 vnc_write_u8(vs
, 1);
2615 if (vs
->minor
>= 8) {
2616 static const char err
[] = "Authentication failed";
2617 vnc_write_u32(vs
, sizeof(err
));
2618 vnc_write(vs
, err
, sizeof(err
));
2620 vnc_client_error(vs
);
2626 static int protocol_version(VncState
*vs
, uint8_t *version
, size_t len
)
2630 memcpy(local
, version
, 12);
2633 if (sscanf(local
, "RFB %03d.%03d\n", &vs
->major
, &vs
->minor
) != 2) {
2634 VNC_DEBUG("Malformed protocol version %s\n", local
);
2635 vnc_client_error(vs
);
2638 VNC_DEBUG("Client request protocol version %d.%d\n", vs
->major
, vs
->minor
);
2639 if (vs
->major
!= 3 ||
2645 VNC_DEBUG("Unsupported client version\n");
2646 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2648 vnc_client_error(vs
);
2651 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2652 * as equivalent to v3.3 by servers
2654 if (vs
->minor
== 4 || vs
->minor
== 5)
2657 if (vs
->minor
== 3) {
2658 if (vs
->auth
== VNC_AUTH_NONE
) {
2659 VNC_DEBUG("Tell client auth none\n");
2660 vnc_write_u32(vs
, vs
->auth
);
2662 start_client_init(vs
);
2663 } else if (vs
->auth
== VNC_AUTH_VNC
) {
2664 VNC_DEBUG("Tell client VNC auth\n");
2665 vnc_write_u32(vs
, vs
->auth
);
2669 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs
->auth
);
2670 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2672 vnc_client_error(vs
);
2675 VNC_DEBUG("Telling client we support auth %d\n", vs
->auth
);
2676 vnc_write_u8(vs
, 1); /* num auth */
2677 vnc_write_u8(vs
, vs
->auth
);
2678 vnc_read_when(vs
, protocol_client_auth
, 1);
2685 static VncRectStat
*vnc_stat_rect(VncDisplay
*vd
, int x
, int y
)
2687 struct VncSurface
*vs
= &vd
->guest
;
2689 return &vs
->stats
[y
/ VNC_STAT_RECT
][x
/ VNC_STAT_RECT
];
2692 void vnc_sent_lossy_rect(VncState
*vs
, int x
, int y
, int w
, int h
)
2696 w
= (x
+ w
) / VNC_STAT_RECT
;
2697 h
= (y
+ h
) / VNC_STAT_RECT
;
2701 for (j
= y
; j
<= h
; j
++) {
2702 for (i
= x
; i
<= w
; i
++) {
2703 vs
->lossy_rect
[j
][i
] = 1;
2708 static int vnc_refresh_lossy_rect(VncDisplay
*vd
, int x
, int y
)
2711 int sty
= y
/ VNC_STAT_RECT
;
2712 int stx
= x
/ VNC_STAT_RECT
;
2715 y
= y
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2716 x
= x
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2718 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2721 /* kernel send buffers are full -> refresh later */
2722 if (vs
->output
.offset
) {
2726 if (!vs
->lossy_rect
[sty
][stx
]) {
2730 vs
->lossy_rect
[sty
][stx
] = 0;
2731 for (j
= 0; j
< VNC_STAT_RECT
; ++j
) {
2732 bitmap_set(vs
->dirty
[y
+ j
],
2733 x
/ VNC_DIRTY_PIXELS_PER_BIT
,
2734 VNC_STAT_RECT
/ VNC_DIRTY_PIXELS_PER_BIT
);
2742 static int vnc_update_stats(VncDisplay
*vd
, struct timeval
* tv
)
2744 int width
= pixman_image_get_width(vd
->guest
.fb
);
2745 int height
= pixman_image_get_height(vd
->guest
.fb
);
2750 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2751 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2752 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2754 rect
->updated
= false;
2758 qemu_timersub(tv
, &VNC_REFRESH_STATS
, &res
);
2760 if (timercmp(&vd
->guest
.last_freq_check
, &res
, >)) {
2763 vd
->guest
.last_freq_check
= *tv
;
2765 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2766 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2767 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2768 int count
= ARRAY_SIZE(rect
->times
);
2769 struct timeval min
, max
;
2771 if (!timerisset(&rect
->times
[count
- 1])) {
2775 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2776 qemu_timersub(tv
, &max
, &res
);
2778 if (timercmp(&res
, &VNC_REFRESH_LOSSY
, >)) {
2780 has_dirty
+= vnc_refresh_lossy_rect(vd
, x
, y
);
2781 memset(rect
->times
, 0, sizeof (rect
->times
));
2785 min
= rect
->times
[rect
->idx
];
2786 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2787 qemu_timersub(&max
, &min
, &res
);
2789 rect
->freq
= res
.tv_sec
+ res
.tv_usec
/ 1000000.;
2790 rect
->freq
/= count
;
2791 rect
->freq
= 1. / rect
->freq
;
2797 double vnc_update_freq(VncState
*vs
, int x
, int y
, int w
, int h
)
2803 x
= (x
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2804 y
= (y
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2806 for (j
= y
; j
<= y
+ h
; j
+= VNC_STAT_RECT
) {
2807 for (i
= x
; i
<= x
+ w
; i
+= VNC_STAT_RECT
) {
2808 total
+= vnc_stat_rect(vs
->vd
, i
, j
)->freq
;
2820 static void vnc_rect_updated(VncDisplay
*vd
, int x
, int y
, struct timeval
* tv
)
2824 rect
= vnc_stat_rect(vd
, x
, y
);
2825 if (rect
->updated
) {
2828 rect
->times
[rect
->idx
] = *tv
;
2829 rect
->idx
= (rect
->idx
+ 1) % ARRAY_SIZE(rect
->times
);
2830 rect
->updated
= true;
2833 static int vnc_refresh_server_surface(VncDisplay
*vd
)
2835 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2836 pixman_image_get_width(vd
->server
));
2837 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2838 pixman_image_get_height(vd
->server
));
2839 int cmp_bytes
, server_stride
, line_bytes
, guest_ll
, guest_stride
, y
= 0;
2840 uint8_t *guest_row0
= NULL
, *server_row0
;
2843 pixman_image_t
*tmpbuf
= NULL
;
2845 struct timeval tv
= { 0, 0 };
2847 if (!vd
->non_adaptive
) {
2848 gettimeofday(&tv
, NULL
);
2849 has_dirty
= vnc_update_stats(vd
, &tv
);
2853 * Walk through the guest dirty map.
2854 * Check and copy modified bits from guest to server surface.
2855 * Update server dirty map.
2857 server_row0
= (uint8_t *)pixman_image_get_data(vd
->server
);
2858 server_stride
= guest_stride
= guest_ll
=
2859 pixman_image_get_stride(vd
->server
);
2860 cmp_bytes
= MIN(VNC_DIRTY_PIXELS_PER_BIT
* VNC_SERVER_FB_BYTES
,
2862 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2863 int width
= pixman_image_get_width(vd
->server
);
2864 tmpbuf
= qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT
, width
);
2867 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd
->guest
.fb
));
2868 guest_row0
= (uint8_t *)pixman_image_get_data(vd
->guest
.fb
);
2869 guest_stride
= pixman_image_get_stride(vd
->guest
.fb
);
2870 guest_ll
= pixman_image_get_width(vd
->guest
.fb
) * ((guest_bpp
+ 7) / 8);
2872 line_bytes
= MIN(server_stride
, guest_ll
);
2876 uint8_t *guest_ptr
, *server_ptr
;
2877 unsigned long offset
= find_next_bit((unsigned long *) &vd
->guest
.dirty
,
2878 height
* VNC_DIRTY_BPL(&vd
->guest
),
2879 y
* VNC_DIRTY_BPL(&vd
->guest
));
2880 if (offset
== height
* VNC_DIRTY_BPL(&vd
->guest
)) {
2881 /* no more dirty bits */
2884 y
= offset
/ VNC_DIRTY_BPL(&vd
->guest
);
2885 x
= offset
% VNC_DIRTY_BPL(&vd
->guest
);
2887 server_ptr
= server_row0
+ y
* server_stride
+ x
* cmp_bytes
;
2889 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2890 qemu_pixman_linebuf_fill(tmpbuf
, vd
->guest
.fb
, width
, 0, y
);
2891 guest_ptr
= (uint8_t *)pixman_image_get_data(tmpbuf
);
2893 guest_ptr
= guest_row0
+ y
* guest_stride
;
2895 guest_ptr
+= x
* cmp_bytes
;
2897 for (; x
< DIV_ROUND_UP(width
, VNC_DIRTY_PIXELS_PER_BIT
);
2898 x
++, guest_ptr
+= cmp_bytes
, server_ptr
+= cmp_bytes
) {
2899 int _cmp_bytes
= cmp_bytes
;
2900 if (!test_and_clear_bit(x
, vd
->guest
.dirty
[y
])) {
2903 if ((x
+ 1) * cmp_bytes
> line_bytes
) {
2904 _cmp_bytes
= line_bytes
- x
* cmp_bytes
;
2906 assert(_cmp_bytes
>= 0);
2907 if (memcmp(server_ptr
, guest_ptr
, _cmp_bytes
) == 0) {
2910 memcpy(server_ptr
, guest_ptr
, _cmp_bytes
);
2911 if (!vd
->non_adaptive
) {
2912 vnc_rect_updated(vd
, x
* VNC_DIRTY_PIXELS_PER_BIT
,
2915 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2916 set_bit(x
, vs
->dirty
[y
]);
2923 qemu_pixman_image_unref(tmpbuf
);
2927 static void vnc_refresh(DisplayChangeListener
*dcl
)
2929 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
2931 int has_dirty
, rects
= 0;
2933 if (QTAILQ_EMPTY(&vd
->clients
)) {
2934 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_MAX
);
2938 graphic_hw_update(vd
->dcl
.con
);
2940 if (vnc_trylock_display(vd
)) {
2941 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2945 has_dirty
= vnc_refresh_server_surface(vd
);
2946 vnc_unlock_display(vd
);
2948 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
2949 rects
+= vnc_update_client(vs
, has_dirty
, false);
2950 /* vs might be free()ed here */
2953 if (has_dirty
&& rects
) {
2954 vd
->dcl
.update_interval
/= 2;
2955 if (vd
->dcl
.update_interval
< VNC_REFRESH_INTERVAL_BASE
) {
2956 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_BASE
;
2959 vd
->dcl
.update_interval
+= VNC_REFRESH_INTERVAL_INC
;
2960 if (vd
->dcl
.update_interval
> VNC_REFRESH_INTERVAL_MAX
) {
2961 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_MAX
;
2966 static void vnc_connect(VncDisplay
*vd
, QIOChannelSocket
*sioc
,
2967 bool skipauth
, bool websocket
)
2969 VncState
*vs
= g_new0(VncState
, 1);
2973 object_ref(OBJECT(vs
->sioc
));
2974 vs
->ioc
= QIO_CHANNEL(sioc
);
2975 object_ref(OBJECT(vs
->ioc
));
2978 buffer_init(&vs
->input
, "vnc-input/%p", sioc
);
2979 buffer_init(&vs
->output
, "vnc-output/%p", sioc
);
2980 buffer_init(&vs
->jobs_buffer
, "vnc-jobs_buffer/%p", sioc
);
2982 buffer_init(&vs
->tight
.tight
, "vnc-tight/%p", sioc
);
2983 buffer_init(&vs
->tight
.zlib
, "vnc-tight-zlib/%p", sioc
);
2984 buffer_init(&vs
->tight
.gradient
, "vnc-tight-gradient/%p", sioc
);
2985 #ifdef CONFIG_VNC_JPEG
2986 buffer_init(&vs
->tight
.jpeg
, "vnc-tight-jpeg/%p", sioc
);
2988 #ifdef CONFIG_VNC_PNG
2989 buffer_init(&vs
->tight
.png
, "vnc-tight-png/%p", sioc
);
2991 buffer_init(&vs
->zlib
.zlib
, "vnc-zlib/%p", sioc
);
2992 buffer_init(&vs
->zrle
.zrle
, "vnc-zrle/%p", sioc
);
2993 buffer_init(&vs
->zrle
.fb
, "vnc-zrle-fb/%p", sioc
);
2994 buffer_init(&vs
->zrle
.zlib
, "vnc-zrle-zlib/%p", sioc
);
2997 vs
->auth
= VNC_AUTH_NONE
;
2998 vs
->subauth
= VNC_AUTH_INVALID
;
3001 vs
->auth
= vd
->ws_auth
;
3002 vs
->subauth
= VNC_AUTH_INVALID
;
3004 vs
->auth
= vd
->auth
;
3005 vs
->subauth
= vd
->subauth
;
3008 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
3009 sioc
, websocket
, vs
->auth
, vs
->subauth
);
3011 vs
->lossy_rect
= g_malloc0(VNC_STAT_ROWS
* sizeof (*vs
->lossy_rect
));
3012 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
3013 vs
->lossy_rect
[i
] = g_new0(uint8_t, VNC_STAT_COLS
);
3016 VNC_DEBUG("New client on socket %p\n", vs
->sioc
);
3017 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
3018 qio_channel_set_blocking(vs
->ioc
, false, NULL
);
3022 vs
->ioc_tag
= qio_channel_add_watch(
3023 vs
->ioc
, G_IO_IN
, vncws_tls_handshake_io
, vs
, NULL
);
3025 vs
->ioc_tag
= qio_channel_add_watch(
3026 vs
->ioc
, G_IO_IN
, vncws_handshake_io
, vs
, NULL
);
3029 vs
->ioc_tag
= qio_channel_add_watch(
3030 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
3033 vnc_client_cache_addr(vs
);
3034 vnc_qmp_event(vs
, QAPI_EVENT_VNC_CONNECTED
);
3035 vnc_set_share_mode(vs
, VNC_SHARE_MODE_CONNECTING
);
3037 if (!vs
->websocket
) {
3041 if (vd
->num_connecting
> vd
->connections_limit
) {
3042 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
3043 if (vs
->share_mode
== VNC_SHARE_MODE_CONNECTING
) {
3044 vnc_disconnect_start(vs
);
3051 void vnc_init_state(VncState
*vs
)
3053 vs
->initialized
= true;
3054 VncDisplay
*vd
= vs
->vd
;
3055 bool first_client
= QTAILQ_EMPTY(&vd
->clients
);
3060 vs
->as
.freq
= 44100;
3061 vs
->as
.nchannels
= 2;
3062 vs
->as
.fmt
= AUD_FMT_S16
;
3063 vs
->as
.endianness
= 0;
3065 qemu_mutex_init(&vs
->output_mutex
);
3066 vs
->bh
= qemu_bh_new(vnc_jobs_bh
, vs
);
3068 QTAILQ_INSERT_TAIL(&vd
->clients
, vs
, next
);
3070 vnc_update_server_surface(vd
);
3073 graphic_hw_update(vd
->dcl
.con
);
3075 vnc_write(vs
, "RFB 003.008\n", 12);
3077 vnc_read_when(vs
, protocol_version
, 12);
3079 if (vs
->vd
->lock_key_sync
)
3080 vs
->led
= qemu_add_led_event_handler(kbd_leds
, vs
);
3082 vs
->mouse_mode_notifier
.notify
= check_pointer_type_change
;
3083 qemu_add_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
3085 /* vs might be free()ed here */
3088 static gboolean
vnc_listen_io(QIOChannel
*ioc
,
3089 GIOCondition condition
,
3092 VncDisplay
*vs
= opaque
;
3093 QIOChannelSocket
*sioc
= NULL
;
3097 graphic_hw_update(vs
->dcl
.con
);
3098 sioc
= qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc
), &err
);
3100 qio_channel_set_delay(QIO_CHANNEL(sioc
), false);
3101 vnc_connect(vs
, sioc
, false,
3102 ioc
!= QIO_CHANNEL(vs
->lsock
));
3103 object_unref(OBJECT(sioc
));
3105 /* client probably closed connection before we got there */
3112 static const DisplayChangeListenerOps dcl_ops
= {
3114 .dpy_refresh
= vnc_refresh
,
3115 .dpy_gfx_copy
= vnc_dpy_copy
,
3116 .dpy_gfx_update
= vnc_dpy_update
,
3117 .dpy_gfx_switch
= vnc_dpy_switch
,
3118 .dpy_gfx_check_format
= qemu_pixman_check_format
,
3119 .dpy_mouse_set
= vnc_mouse_set
,
3120 .dpy_cursor_define
= vnc_dpy_cursor_define
,
3123 void vnc_display_init(const char *id
)
3127 if (vnc_display_find(id
) != NULL
) {
3130 vs
= g_malloc0(sizeof(*vs
));
3132 vs
->id
= strdup(id
);
3133 QTAILQ_INSERT_TAIL(&vnc_displays
, vs
, next
);
3135 QTAILQ_INIT(&vs
->clients
);
3136 vs
->expires
= TIME_MAX
;
3138 if (keyboard_layout
) {
3139 trace_vnc_key_map_init(keyboard_layout
);
3140 vs
->kbd_layout
= init_keyboard_layout(name2keysym
, keyboard_layout
);
3142 vs
->kbd_layout
= init_keyboard_layout(name2keysym
, "en-us");
3145 if (!vs
->kbd_layout
)
3148 qemu_mutex_init(&vs
->mutex
);
3149 vnc_start_worker_thread();
3151 vs
->dcl
.ops
= &dcl_ops
;
3152 register_displaychangelistener(&vs
->dcl
);
3156 static void vnc_display_close(VncDisplay
*vs
)
3160 vs
->enabled
= false;
3161 vs
->is_unix
= false;
3162 if (vs
->lsock
!= NULL
) {
3163 if (vs
->lsock_tag
) {
3164 g_source_remove(vs
->lsock_tag
);
3166 object_unref(OBJECT(vs
->lsock
));
3169 vs
->ws_enabled
= false;
3170 if (vs
->lwebsock
!= NULL
) {
3171 if (vs
->lwebsock_tag
) {
3172 g_source_remove(vs
->lwebsock_tag
);
3174 object_unref(OBJECT(vs
->lwebsock
));
3175 vs
->lwebsock
= NULL
;
3177 vs
->auth
= VNC_AUTH_INVALID
;
3178 vs
->subauth
= VNC_AUTH_INVALID
;
3180 object_unparent(OBJECT(vs
->tlscreds
));
3181 vs
->tlscreds
= NULL
;
3183 g_free(vs
->tlsaclname
);
3184 vs
->tlsaclname
= NULL
;
3187 int vnc_display_password(const char *id
, const char *password
)
3189 VncDisplay
*vs
= vnc_display_find(id
);
3194 if (vs
->auth
== VNC_AUTH_NONE
) {
3195 error_printf_unless_qmp("If you want use passwords please enable "
3196 "password auth using '-vnc ${dpy},password'.");
3200 g_free(vs
->password
);
3201 vs
->password
= g_strdup(password
);
3206 int vnc_display_pw_expire(const char *id
, time_t expires
)
3208 VncDisplay
*vs
= vnc_display_find(id
);
3214 vs
->expires
= expires
;
3218 static void vnc_display_print_local_addr(VncDisplay
*vs
)
3220 SocketAddress
*addr
;
3223 addr
= qio_channel_socket_get_local_address(vs
->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(VncDisplay
*vs
,
3323 * We have a choice of 3 authentication options
3329 * The channel can be run in 2 modes
3334 * And TLS can use 2 types of credentials
3339 * We thus have 9 possible logical combinations
3344 * 4. tls + anon + none
3345 * 5. tls + anon + vnc
3346 * 6. tls + anon + sasl
3347 * 7. tls + x509 + none
3348 * 8. tls + x509 + vnc
3349 * 9. tls + x509 + sasl
3351 * These need to be mapped into the VNC auth schemes
3352 * in an appropriate manner. In regular VNC, all the
3353 * TLS options get mapped into VNC_AUTH_VENCRYPT
3356 * In websockets, the https:// protocol already provides
3357 * TLS support, so there is no need to make use of the
3358 * VeNCrypt extension. Furthermore, websockets browser
3359 * clients could not use VeNCrypt even if they wanted to,
3360 * as they cannot control when the TLS handshake takes
3361 * place. Thus there is no option but to rely on https://,
3362 * meaning combinations 4->6 and 7->9 will be mapped to
3363 * VNC auth schemes in the same way as combos 1->3.
3365 * Regardless of fact that we have a different mapping to
3366 * VNC auth mechs for plain VNC vs websockets VNC, the end
3367 * result has the same security characteristics.
3371 vs
->auth
= VNC_AUTH_VENCRYPT
;
3375 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3376 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3377 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3378 vs
->subauth
= VNC_AUTH_VENCRYPT_X509VNC
;
3379 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3380 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3381 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3382 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSVNC
;
3385 "Unsupported TLS cred type %s",
3386 object_get_typename(OBJECT(vs
->tlscreds
)));
3390 VNC_DEBUG("Initializing VNC server with password auth\n");
3391 vs
->auth
= VNC_AUTH_VNC
;
3392 vs
->subauth
= VNC_AUTH_INVALID
;
3395 vs
->ws_auth
= VNC_AUTH_VNC
;
3397 vs
->ws_auth
= VNC_AUTH_INVALID
;
3401 vs
->auth
= VNC_AUTH_VENCRYPT
;
3405 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3406 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3407 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3408 vs
->subauth
= VNC_AUTH_VENCRYPT_X509SASL
;
3409 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3410 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3411 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3412 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSSASL
;
3415 "Unsupported TLS cred type %s",
3416 object_get_typename(OBJECT(vs
->tlscreds
)));
3420 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3421 vs
->auth
= VNC_AUTH_SASL
;
3422 vs
->subauth
= VNC_AUTH_INVALID
;
3425 vs
->ws_auth
= VNC_AUTH_SASL
;
3427 vs
->ws_auth
= VNC_AUTH_INVALID
;
3431 vs
->auth
= VNC_AUTH_VENCRYPT
;
3435 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3436 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3437 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3438 vs
->subauth
= VNC_AUTH_VENCRYPT_X509NONE
;
3439 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3440 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3441 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3442 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSNONE
;
3445 "Unsupported TLS cred type %s",
3446 object_get_typename(OBJECT(vs
->tlscreds
)));
3450 VNC_DEBUG("Initializing VNC server with no auth\n");
3451 vs
->auth
= VNC_AUTH_NONE
;
3452 vs
->subauth
= VNC_AUTH_INVALID
;
3455 vs
->ws_auth
= VNC_AUTH_NONE
;
3457 vs
->ws_auth
= VNC_AUTH_INVALID
;
3465 * Handle back compat with old CLI syntax by creating some
3466 * suitable QCryptoTLSCreds objects
3468 static QCryptoTLSCreds
*
3469 vnc_display_create_creds(bool x509
,
3475 gchar
*credsid
= g_strdup_printf("tlsvnc%s", id
);
3476 Object
*parent
= object_get_objects_root();
3481 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509
,
3485 "endpoint", "server",
3487 "verify-peer", x509verify
? "yes" : "no",
3490 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON
,
3494 "endpoint", "server",
3501 error_propagate(errp
, err
);
3505 return QCRYPTO_TLS_CREDS(creds
);
3509 void vnc_display_open(const char *id
, Error
**errp
)
3511 VncDisplay
*vs
= vnc_display_find(id
);
3512 QemuOpts
*opts
= qemu_opts_find(&qemu_vnc_opts
, id
);
3513 SocketAddress
*saddr
= NULL
, *wsaddr
= NULL
;
3514 const char *share
, *device_id
;
3516 bool password
= false;
3517 bool reverse
= false;
3521 int show_vnc_port
= 0;
3523 #ifdef CONFIG_VNC_SASL
3527 int lock_key_sync
= 1;
3531 error_setg(errp
, "VNC display not active");
3534 vnc_display_close(vs
);
3539 vnc
= qemu_opt_get(opts
, "vnc");
3540 if (!vnc
|| strcmp(vnc
, "none") == 0) {
3544 h
= strrchr(vnc
, ':');
3546 size_t hlen
= h
- vnc
;
3548 const char *websocket
= qemu_opt_get(opts
, "websocket");
3549 int to
= qemu_opt_get_number(opts
, "to", 0);
3550 bool has_ipv4
= qemu_opt_get(opts
, "ipv4");
3551 bool has_ipv6
= qemu_opt_get(opts
, "ipv6");
3552 bool ipv4
= qemu_opt_get_bool(opts
, "ipv4", false);
3553 bool ipv6
= qemu_opt_get_bool(opts
, "ipv6", false);
3555 saddr
= g_new0(SocketAddress
, 1);
3557 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1
)) {
3559 "SHA1 hash support is required for websockets");
3563 wsaddr
= g_new0(SocketAddress
, 1);
3564 vs
->ws_enabled
= true;
3567 if (strncmp(vnc
, "unix:", 5) == 0) {
3568 saddr
->type
= SOCKET_ADDRESS_KIND_UNIX
;
3569 saddr
->u
.q_unix
.data
= g_new0(UnixSocketAddress
, 1);
3570 saddr
->u
.q_unix
.data
->path
= g_strdup(vnc
+ 5);
3572 if (vs
->ws_enabled
) {
3573 error_setg(errp
, "UNIX sockets not supported with websock");
3577 unsigned long long baseport
;
3578 InetSocketAddress
*inet
;
3579 saddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3580 inet
= saddr
->u
.inet
.data
= g_new0(InetSocketAddress
, 1);
3581 if (vnc
[0] == '[' && vnc
[hlen
- 1] == ']') {
3582 inet
->host
= g_strndup(vnc
+ 1, hlen
- 2);
3584 inet
->host
= g_strndup(vnc
, hlen
);
3586 if (parse_uint_full(h
+ 1, &baseport
, 10) < 0) {
3587 error_setg(errp
, "can't convert to a number: %s", h
+ 1);
3590 if (baseport
> 65535 ||
3591 baseport
+ 5900 > 65535) {
3592 error_setg(errp
, "port %s out of range", h
+ 1);
3595 inet
->port
= g_strdup_printf(
3596 "%d", (int)baseport
+ 5900);
3599 inet
->has_to
= true;
3600 inet
->to
= to
+ 5900;
3604 inet
->has_ipv4
= has_ipv4
;
3606 inet
->has_ipv6
= has_ipv6
;
3608 if (vs
->ws_enabled
) {
3609 wsaddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3610 inet
= wsaddr
->u
.inet
.data
= g_new0(InetSocketAddress
, 1);
3611 inet
->host
= g_strdup(saddr
->u
.inet
.data
->host
);
3612 inet
->port
= g_strdup(websocket
);
3615 inet
->has_to
= true;
3619 inet
->has_ipv4
= has_ipv4
;
3621 inet
->has_ipv6
= has_ipv6
;
3625 error_setg(errp
, "no vnc port specified");
3629 password
= qemu_opt_get_bool(opts
, "password", false);
3631 if (fips_get_state()) {
3633 "VNC password auth disabled due to FIPS mode, "
3634 "consider using the VeNCrypt or SASL authentication "
3635 "methods as an alternative");
3638 if (!qcrypto_cipher_supports(
3639 QCRYPTO_CIPHER_ALG_DES_RFB
)) {
3641 "Cipher backend does not support DES RFB algorithm");
3646 reverse
= qemu_opt_get_bool(opts
, "reverse", false);
3647 lock_key_sync
= qemu_opt_get_bool(opts
, "lock-key-sync", true);
3648 key_delay_ms
= qemu_opt_get_number(opts
, "key-delay-ms", 1);
3649 sasl
= qemu_opt_get_bool(opts
, "sasl", false);
3650 #ifndef CONFIG_VNC_SASL
3652 error_setg(errp
, "VNC SASL auth requires cyrus-sasl support");
3655 #endif /* CONFIG_VNC_SASL */
3656 credid
= qemu_opt_get(opts
, "tls-creds");
3659 if (qemu_opt_get(opts
, "tls") ||
3660 qemu_opt_get(opts
, "x509") ||
3661 qemu_opt_get(opts
, "x509verify")) {
3663 "'tls-creds' parameter is mutually exclusive with "
3664 "'tls', 'x509' and 'x509verify' parameters");
3668 creds
= object_resolve_path_component(
3669 object_get_objects_root(), credid
);
3671 error_setg(errp
, "No TLS credentials with id '%s'",
3675 vs
->tlscreds
= (QCryptoTLSCreds
*)
3676 object_dynamic_cast(creds
,
3677 TYPE_QCRYPTO_TLS_CREDS
);
3678 if (!vs
->tlscreds
) {
3679 error_setg(errp
, "Object with id '%s' is not TLS credentials",
3683 object_ref(OBJECT(vs
->tlscreds
));
3685 if (vs
->tlscreds
->endpoint
!= QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
) {
3687 "Expecting TLS credentials with a server endpoint");
3692 bool tls
= false, x509
= false, x509verify
= false;
3693 tls
= qemu_opt_get_bool(opts
, "tls", false);
3695 path
= qemu_opt_get(opts
, "x509");
3700 path
= qemu_opt_get(opts
, "x509verify");
3706 vs
->tlscreds
= vnc_display_create_creds(x509
,
3711 if (!vs
->tlscreds
) {
3716 acl
= qemu_opt_get_bool(opts
, "acl", false);
3718 share
= qemu_opt_get(opts
, "share");
3720 if (strcmp(share
, "ignore") == 0) {
3721 vs
->share_policy
= VNC_SHARE_POLICY_IGNORE
;
3722 } else if (strcmp(share
, "allow-exclusive") == 0) {
3723 vs
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3724 } else if (strcmp(share
, "force-shared") == 0) {
3725 vs
->share_policy
= VNC_SHARE_POLICY_FORCE_SHARED
;
3727 error_setg(errp
, "unknown vnc share= option");
3731 vs
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3733 vs
->connections_limit
= qemu_opt_get_number(opts
, "connections", 32);
3735 #ifdef CONFIG_VNC_JPEG
3736 vs
->lossy
= qemu_opt_get_bool(opts
, "lossy", false);
3738 vs
->non_adaptive
= qemu_opt_get_bool(opts
, "non-adaptive", false);
3739 /* adaptive updates are only used with tight encoding and
3740 * if lossy updates are enabled so we can disable all the
3741 * calculations otherwise */
3743 vs
->non_adaptive
= true;
3747 if (strcmp(vs
->id
, "default") == 0) {
3748 vs
->tlsaclname
= g_strdup("vnc.x509dname");
3750 vs
->tlsaclname
= g_strdup_printf("vnc.%s.x509dname", vs
->id
);
3752 qemu_acl_init(vs
->tlsaclname
);
3754 #ifdef CONFIG_VNC_SASL
3758 if (strcmp(vs
->id
, "default") == 0) {
3759 aclname
= g_strdup("vnc.username");
3761 aclname
= g_strdup_printf("vnc.%s.username", vs
->id
);
3763 vs
->sasl
.acl
= qemu_acl_init(aclname
);
3768 if (vnc_display_setup_auth(vs
, password
, sasl
, vs
->ws_enabled
, errp
) < 0) {
3772 #ifdef CONFIG_VNC_SASL
3773 if ((saslErr
= sasl_server_init(NULL
, "qemu")) != SASL_OK
) {
3774 error_setg(errp
, "Failed to initialize SASL auth: %s",
3775 sasl_errstring(saslErr
, NULL
, NULL
));
3779 vs
->lock_key_sync
= lock_key_sync
;
3780 vs
->key_delay_ms
= key_delay_ms
;
3782 device_id
= qemu_opt_get(opts
, "display");
3784 int head
= qemu_opt_get_number(opts
, "head", 0);
3787 con
= qemu_console_lookup_by_device_name(device_id
, head
, &err
);
3789 error_propagate(errp
, err
);
3796 if (con
!= vs
->dcl
.con
) {
3797 unregister_displaychangelistener(&vs
->dcl
);
3799 register_displaychangelistener(&vs
->dcl
);
3803 /* connect to viewer */
3804 QIOChannelSocket
*sioc
= NULL
;
3806 vs
->lwebsock
= NULL
;
3807 if (vs
->ws_enabled
) {
3808 error_setg(errp
, "Cannot use websockets in reverse mode");
3811 vs
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3812 sioc
= qio_channel_socket_new();
3813 if (qio_channel_socket_connect_sync(sioc
, saddr
, errp
) < 0) {
3816 vnc_connect(vs
, sioc
, false, false);
3817 object_unref(OBJECT(sioc
));
3819 vs
->lsock
= qio_channel_socket_new();
3820 if (qio_channel_socket_listen_sync(vs
->lsock
, saddr
, errp
) < 0) {
3823 vs
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3826 if (vs
->ws_enabled
) {
3827 vs
->lwebsock
= qio_channel_socket_new();
3828 if (qio_channel_socket_listen_sync(vs
->lwebsock
,
3829 wsaddr
, errp
) < 0) {
3830 object_unref(OBJECT(vs
->lsock
));
3836 vs
->lsock_tag
= qio_channel_add_watch(
3837 QIO_CHANNEL(vs
->lsock
),
3838 G_IO_IN
, vnc_listen_io
, vs
, NULL
);
3839 if (vs
->ws_enabled
) {
3840 vs
->lwebsock_tag
= qio_channel_add_watch(
3841 QIO_CHANNEL(vs
->lwebsock
),
3842 G_IO_IN
, vnc_listen_io
, vs
, NULL
);
3846 if (show_vnc_port
) {
3847 vnc_display_print_local_addr(vs
);
3850 qapi_free_SocketAddress(saddr
);
3851 qapi_free_SocketAddress(wsaddr
);
3855 qapi_free_SocketAddress(saddr
);
3856 qapi_free_SocketAddress(wsaddr
);
3857 vs
->enabled
= false;
3858 vs
->ws_enabled
= false;
3861 void vnc_display_add_client(const char *id
, int csock
, bool skipauth
)
3863 VncDisplay
*vs
= vnc_display_find(id
);
3864 QIOChannelSocket
*sioc
;
3870 sioc
= qio_channel_socket_new_fd(csock
, NULL
);
3872 vnc_connect(vs
, sioc
, skipauth
, false);
3873 object_unref(OBJECT(sioc
));
3877 static void vnc_auto_assign_id(QemuOptsList
*olist
, QemuOpts
*opts
)
3882 id
= g_strdup("default");
3883 while (qemu_opts_find(olist
, id
)) {
3885 id
= g_strdup_printf("vnc%d", i
++);
3887 qemu_opts_set_id(opts
, id
);
3890 QemuOpts
*vnc_parse(const char *str
, Error
**errp
)
3892 QemuOptsList
*olist
= qemu_find_opts("vnc");
3893 QemuOpts
*opts
= qemu_opts_parse(olist
, str
, true, errp
);
3900 id
= qemu_opts_id(opts
);
3902 /* auto-assign id if not present */
3903 vnc_auto_assign_id(olist
, opts
);
3908 int vnc_init_func(void *opaque
, QemuOpts
*opts
, Error
**errp
)
3910 Error
*local_err
= NULL
;
3911 char *id
= (char *)qemu_opts_id(opts
);
3914 vnc_display_init(id
);
3915 vnc_display_open(id
, &local_err
);
3916 if (local_err
!= NULL
) {
3917 error_reportf_err(local_err
, "Failed to start VNC server: ");
3923 static void vnc_register_config(void)
3925 qemu_add_opts(&qemu_vnc_opts
);
3927 opts_init(vnc_register_config
);