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 vs
->has_dirty
+= has_dirty
;
1028 if (vs
->need_update
&& vs
->ioc
!= NULL
) {
1029 VncDisplay
*vd
= vs
->vd
;
1035 if (vs
->output
.offset
&& !vs
->audio_cap
&& !vs
->force_update
)
1036 /* kernel send buffers are full -> drop frames to throttle */
1039 if (!vs
->has_dirty
&& !vs
->audio_cap
&& !vs
->force_update
)
1043 * Send screen updates to the vnc client using the server
1044 * surface and server dirty map. guest surface updates
1045 * happening in parallel don't disturb us, the next pass will
1046 * send them to the client.
1048 job
= vnc_job_new(vs
);
1050 height
= pixman_image_get_height(vd
->server
);
1051 width
= pixman_image_get_width(vd
->server
);
1057 unsigned long offset
= find_next_bit((unsigned long *) &vs
->dirty
,
1058 height
* VNC_DIRTY_BPL(vs
),
1059 y
* VNC_DIRTY_BPL(vs
));
1060 if (offset
== height
* VNC_DIRTY_BPL(vs
)) {
1061 /* no more dirty bits */
1064 y
= offset
/ VNC_DIRTY_BPL(vs
);
1065 x
= offset
% VNC_DIRTY_BPL(vs
);
1066 x2
= find_next_zero_bit((unsigned long *) &vs
->dirty
[y
],
1067 VNC_DIRTY_BPL(vs
), x
);
1068 bitmap_clear(vs
->dirty
[y
], x
, x2
- x
);
1069 h
= find_and_clear_dirty_height(vs
, y
, x
, x2
, height
);
1070 x2
= MIN(x2
, width
/ VNC_DIRTY_PIXELS_PER_BIT
);
1072 n
+= vnc_job_add_rect(job
, x
* VNC_DIRTY_PIXELS_PER_BIT
, y
,
1073 (x2
- x
) * VNC_DIRTY_PIXELS_PER_BIT
, h
);
1075 if (!x
&& x2
== width
/ VNC_DIRTY_PIXELS_PER_BIT
) {
1087 vs
->force_update
= 0;
1092 if (vs
->disconnecting
) {
1093 vnc_disconnect_finish(vs
);
1102 static void audio_capture_notify(void *opaque
, audcnotification_e cmd
)
1104 VncState
*vs
= opaque
;
1107 case AUD_CNOTIFY_DISABLE
:
1108 vnc_lock_output(vs
);
1109 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1110 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1111 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_END
);
1112 vnc_unlock_output(vs
);
1116 case AUD_CNOTIFY_ENABLE
:
1117 vnc_lock_output(vs
);
1118 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1119 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1120 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN
);
1121 vnc_unlock_output(vs
);
1127 static void audio_capture_destroy(void *opaque
)
1131 static void audio_capture(void *opaque
, void *buf
, int size
)
1133 VncState
*vs
= opaque
;
1135 vnc_lock_output(vs
);
1136 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1137 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1138 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_DATA
);
1139 vnc_write_u32(vs
, size
);
1140 vnc_write(vs
, buf
, size
);
1141 vnc_unlock_output(vs
);
1145 static void audio_add(VncState
*vs
)
1147 struct audio_capture_ops ops
;
1149 if (vs
->audio_cap
) {
1150 error_report("audio already running");
1154 ops
.notify
= audio_capture_notify
;
1155 ops
.destroy
= audio_capture_destroy
;
1156 ops
.capture
= audio_capture
;
1158 vs
->audio_cap
= AUD_add_capture(&vs
->as
, &ops
, vs
);
1159 if (!vs
->audio_cap
) {
1160 error_report("Failed to add audio capture");
1164 static void audio_del(VncState
*vs
)
1166 if (vs
->audio_cap
) {
1167 AUD_del_capture(vs
->audio_cap
, vs
);
1168 vs
->audio_cap
= NULL
;
1172 static void vnc_disconnect_start(VncState
*vs
)
1174 if (vs
->disconnecting
) {
1177 vnc_set_share_mode(vs
, VNC_SHARE_MODE_DISCONNECTED
);
1179 g_source_remove(vs
->ioc_tag
);
1181 qio_channel_close(vs
->ioc
, NULL
);
1182 vs
->disconnecting
= TRUE
;
1185 void vnc_disconnect_finish(VncState
*vs
)
1189 vnc_jobs_join(vs
); /* Wait encoding jobs */
1191 vnc_lock_output(vs
);
1192 vnc_qmp_event(vs
, QAPI_EVENT_VNC_DISCONNECTED
);
1194 buffer_free(&vs
->input
);
1195 buffer_free(&vs
->output
);
1197 qapi_free_VncClientInfo(vs
->info
);
1200 vnc_tight_clear(vs
);
1203 #ifdef CONFIG_VNC_SASL
1204 vnc_sasl_client_cleanup(vs
);
1205 #endif /* CONFIG_VNC_SASL */
1207 vnc_release_modifiers(vs
);
1209 if (vs
->initialized
) {
1210 QTAILQ_REMOVE(&vs
->vd
->clients
, vs
, next
);
1211 qemu_remove_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
1212 if (QTAILQ_EMPTY(&vs
->vd
->clients
)) {
1213 /* last client gone */
1214 vnc_update_server_surface(vs
->vd
);
1218 if (vs
->vd
->lock_key_sync
)
1219 qemu_remove_led_event_handler(vs
->led
);
1220 vnc_unlock_output(vs
);
1222 qemu_mutex_destroy(&vs
->output_mutex
);
1223 if (vs
->bh
!= NULL
) {
1224 qemu_bh_delete(vs
->bh
);
1226 buffer_free(&vs
->jobs_buffer
);
1228 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
1229 g_free(vs
->lossy_rect
[i
]);
1231 g_free(vs
->lossy_rect
);
1233 object_unref(OBJECT(vs
->ioc
));
1235 object_unref(OBJECT(vs
->sioc
));
1240 ssize_t
vnc_client_io_error(VncState
*vs
, ssize_t ret
, Error
**errp
)
1244 VNC_DEBUG("Closing down client sock: EOF\n");
1245 } else if (ret
!= QIO_CHANNEL_ERR_BLOCK
) {
1246 VNC_DEBUG("Closing down client sock: ret %d (%s)\n",
1247 ret
, errp
? error_get_pretty(*errp
) : "Unknown");
1250 vnc_disconnect_start(vs
);
1261 void vnc_client_error(VncState
*vs
)
1263 VNC_DEBUG("Closing down client sock: protocol error\n");
1264 vnc_disconnect_start(vs
);
1269 * Called to write a chunk of data to the client socket. The data may
1270 * be the raw data, or may have already been encoded by SASL.
1271 * The data will be written either straight onto the socket, or
1272 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1274 * NB, it is theoretically possible to have 2 layers of encryption,
1275 * both SASL, and this TLS layer. It is highly unlikely in practice
1276 * though, since SASL encryption will typically be a no-op if TLS
1279 * Returns the number of bytes written, which may be less than
1280 * the requested 'datalen' if the socket would block. Returns
1281 * -1 on error, and disconnects the client socket.
1283 ssize_t
vnc_client_write_buf(VncState
*vs
, const uint8_t *data
, size_t datalen
)
1287 ret
= qio_channel_write(
1288 vs
->ioc
, (const char *)data
, datalen
, &err
);
1289 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data
, datalen
, ret
);
1290 return vnc_client_io_error(vs
, ret
, &err
);
1295 * Called to write buffered data to the client socket, when not
1296 * using any SASL SSF encryption layers. Will write as much data
1297 * as possible without blocking. If all buffered data is written,
1298 * will switch the FD poll() handler back to read monitoring.
1300 * Returns the number of bytes written, which may be less than
1301 * the buffered output data if the socket would block. Returns
1302 * -1 on error, and disconnects the client socket.
1304 static ssize_t
vnc_client_write_plain(VncState
*vs
)
1308 #ifdef CONFIG_VNC_SASL
1309 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1310 vs
->output
.buffer
, vs
->output
.capacity
, vs
->output
.offset
,
1311 vs
->sasl
.waitWriteSSF
);
1313 if (vs
->sasl
.conn
&&
1315 vs
->sasl
.waitWriteSSF
) {
1316 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->sasl
.waitWriteSSF
);
1318 vs
->sasl
.waitWriteSSF
-= ret
;
1320 #endif /* CONFIG_VNC_SASL */
1321 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->output
.offset
);
1325 buffer_advance(&vs
->output
, ret
);
1327 if (vs
->output
.offset
== 0) {
1329 g_source_remove(vs
->ioc_tag
);
1331 vs
->ioc_tag
= qio_channel_add_watch(
1332 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1340 * First function called whenever there is data to be written to
1341 * the client socket. Will delegate actual work according to whether
1342 * SASL SSF layers are enabled (thus requiring encryption calls)
1344 static void vnc_client_write_locked(VncState
*vs
)
1346 #ifdef CONFIG_VNC_SASL
1347 if (vs
->sasl
.conn
&&
1349 !vs
->sasl
.waitWriteSSF
) {
1350 vnc_client_write_sasl(vs
);
1352 #endif /* CONFIG_VNC_SASL */
1354 vnc_client_write_plain(vs
);
1358 static void vnc_client_write(VncState
*vs
)
1361 vnc_lock_output(vs
);
1362 if (vs
->output
.offset
) {
1363 vnc_client_write_locked(vs
);
1364 } else if (vs
->ioc
!= NULL
) {
1366 g_source_remove(vs
->ioc_tag
);
1368 vs
->ioc_tag
= qio_channel_add_watch(
1369 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1371 vnc_unlock_output(vs
);
1374 void vnc_read_when(VncState
*vs
, VncReadEvent
*func
, size_t expecting
)
1376 vs
->read_handler
= func
;
1377 vs
->read_handler_expect
= expecting
;
1382 * Called to read a chunk of data from the client socket. The data may
1383 * be the raw data, or may need to be further decoded by SASL.
1384 * The data will be read either straight from to the socket, or
1385 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1387 * NB, it is theoretically possible to have 2 layers of encryption,
1388 * both SASL, and this TLS layer. It is highly unlikely in practice
1389 * though, since SASL encryption will typically be a no-op if TLS
1392 * Returns the number of bytes read, which may be less than
1393 * the requested 'datalen' if the socket would block. Returns
1394 * -1 on error, and disconnects the client socket.
1396 ssize_t
vnc_client_read_buf(VncState
*vs
, uint8_t *data
, size_t datalen
)
1400 ret
= qio_channel_read(
1401 vs
->ioc
, (char *)data
, datalen
, &err
);
1402 VNC_DEBUG("Read wire %p %zd -> %ld\n", data
, datalen
, ret
);
1403 return vnc_client_io_error(vs
, ret
, &err
);
1408 * Called to read data from the client socket to the input buffer,
1409 * when not using any SASL SSF encryption layers. Will read as much
1410 * data as possible without blocking.
1412 * Returns the number of bytes read. Returns -1 on error, and
1413 * disconnects the client socket.
1415 static ssize_t
vnc_client_read_plain(VncState
*vs
)
1418 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1419 vs
->input
.buffer
, vs
->input
.capacity
, vs
->input
.offset
);
1420 buffer_reserve(&vs
->input
, 4096);
1421 ret
= vnc_client_read_buf(vs
, buffer_end(&vs
->input
), 4096);
1424 vs
->input
.offset
+= ret
;
1428 static void vnc_jobs_bh(void *opaque
)
1430 VncState
*vs
= opaque
;
1432 vnc_jobs_consume_buffer(vs
);
1436 * First function called whenever there is more data to be read from
1437 * the client socket. Will delegate actual work according to whether
1438 * SASL SSF layers are enabled (thus requiring decryption calls)
1440 static void vnc_client_read(VncState
*vs
)
1444 #ifdef CONFIG_VNC_SASL
1445 if (vs
->sasl
.conn
&& vs
->sasl
.runSSF
)
1446 ret
= vnc_client_read_sasl(vs
);
1448 #endif /* CONFIG_VNC_SASL */
1449 ret
= vnc_client_read_plain(vs
);
1451 if (vs
->disconnecting
) {
1452 vnc_disconnect_finish(vs
);
1457 while (vs
->read_handler
&& vs
->input
.offset
>= vs
->read_handler_expect
) {
1458 size_t len
= vs
->read_handler_expect
;
1461 ret
= vs
->read_handler(vs
, vs
->input
.buffer
, len
);
1462 if (vs
->disconnecting
) {
1463 vnc_disconnect_finish(vs
);
1468 buffer_advance(&vs
->input
, len
);
1470 vs
->read_handler_expect
= ret
;
1475 gboolean
vnc_client_io(QIOChannel
*ioc G_GNUC_UNUSED
,
1476 GIOCondition condition
, void *opaque
)
1478 VncState
*vs
= opaque
;
1479 if (condition
& G_IO_IN
) {
1480 vnc_client_read(vs
);
1482 if (condition
& G_IO_OUT
) {
1483 vnc_client_write(vs
);
1489 void vnc_write(VncState
*vs
, const void *data
, size_t len
)
1491 buffer_reserve(&vs
->output
, len
);
1493 if (vs
->ioc
!= NULL
&& buffer_empty(&vs
->output
)) {
1495 g_source_remove(vs
->ioc_tag
);
1497 vs
->ioc_tag
= qio_channel_add_watch(
1498 vs
->ioc
, G_IO_IN
| G_IO_OUT
, vnc_client_io
, vs
, NULL
);
1501 buffer_append(&vs
->output
, data
, len
);
1504 void vnc_write_s32(VncState
*vs
, int32_t value
)
1506 vnc_write_u32(vs
, *(uint32_t *)&value
);
1509 void vnc_write_u32(VncState
*vs
, uint32_t value
)
1513 buf
[0] = (value
>> 24) & 0xFF;
1514 buf
[1] = (value
>> 16) & 0xFF;
1515 buf
[2] = (value
>> 8) & 0xFF;
1516 buf
[3] = value
& 0xFF;
1518 vnc_write(vs
, buf
, 4);
1521 void vnc_write_u16(VncState
*vs
, uint16_t value
)
1525 buf
[0] = (value
>> 8) & 0xFF;
1526 buf
[1] = value
& 0xFF;
1528 vnc_write(vs
, buf
, 2);
1531 void vnc_write_u8(VncState
*vs
, uint8_t value
)
1533 vnc_write(vs
, (char *)&value
, 1);
1536 void vnc_flush(VncState
*vs
)
1538 vnc_lock_output(vs
);
1539 if (vs
->ioc
!= NULL
&& vs
->output
.offset
) {
1540 vnc_client_write_locked(vs
);
1542 vnc_unlock_output(vs
);
1545 static uint8_t read_u8(uint8_t *data
, size_t offset
)
1547 return data
[offset
];
1550 static uint16_t read_u16(uint8_t *data
, size_t offset
)
1552 return ((data
[offset
] & 0xFF) << 8) | (data
[offset
+ 1] & 0xFF);
1555 static int32_t read_s32(uint8_t *data
, size_t offset
)
1557 return (int32_t)((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1558 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1561 uint32_t read_u32(uint8_t *data
, size_t offset
)
1563 return ((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1564 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1567 static void client_cut_text(VncState
*vs
, size_t len
, uint8_t *text
)
1571 static void check_pointer_type_change(Notifier
*notifier
, void *data
)
1573 VncState
*vs
= container_of(notifier
, VncState
, mouse_mode_notifier
);
1574 int absolute
= qemu_input_is_absolute();
1576 if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
) && vs
->absolute
!= absolute
) {
1577 vnc_lock_output(vs
);
1578 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1579 vnc_write_u8(vs
, 0);
1580 vnc_write_u16(vs
, 1);
1581 vnc_framebuffer_update(vs
, absolute
, 0,
1582 pixman_image_get_width(vs
->vd
->server
),
1583 pixman_image_get_height(vs
->vd
->server
),
1584 VNC_ENCODING_POINTER_TYPE_CHANGE
);
1585 vnc_unlock_output(vs
);
1588 vs
->absolute
= absolute
;
1591 static void pointer_event(VncState
*vs
, int button_mask
, int x
, int y
)
1593 static uint32_t bmap
[INPUT_BUTTON__MAX
] = {
1594 [INPUT_BUTTON_LEFT
] = 0x01,
1595 [INPUT_BUTTON_MIDDLE
] = 0x02,
1596 [INPUT_BUTTON_RIGHT
] = 0x04,
1597 [INPUT_BUTTON_WHEEL_UP
] = 0x08,
1598 [INPUT_BUTTON_WHEEL_DOWN
] = 0x10,
1600 QemuConsole
*con
= vs
->vd
->dcl
.con
;
1601 int width
= pixman_image_get_width(vs
->vd
->server
);
1602 int height
= pixman_image_get_height(vs
->vd
->server
);
1604 if (vs
->last_bmask
!= button_mask
) {
1605 qemu_input_update_buttons(con
, bmap
, vs
->last_bmask
, button_mask
);
1606 vs
->last_bmask
= button_mask
;
1610 qemu_input_queue_abs(con
, INPUT_AXIS_X
, x
, width
);
1611 qemu_input_queue_abs(con
, INPUT_AXIS_Y
, y
, height
);
1612 } else if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
)) {
1613 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- 0x7FFF);
1614 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- 0x7FFF);
1616 if (vs
->last_x
!= -1) {
1617 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- vs
->last_x
);
1618 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- vs
->last_y
);
1623 qemu_input_event_sync();
1626 static void reset_keys(VncState
*vs
)
1629 for(i
= 0; i
< 256; i
++) {
1630 if (vs
->modifiers_state
[i
]) {
1631 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, i
, false);
1632 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1633 vs
->modifiers_state
[i
] = 0;
1638 static void press_key(VncState
*vs
, int keysym
)
1640 int keycode
= keysym2scancode(vs
->vd
->kbd_layout
, keysym
) & SCANCODE_KEYMASK
;
1641 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, true);
1642 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1643 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1644 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1647 static int current_led_state(VncState
*vs
)
1651 if (vs
->modifiers_state
[0x46]) {
1652 ledstate
|= QEMU_SCROLL_LOCK_LED
;
1654 if (vs
->modifiers_state
[0x45]) {
1655 ledstate
|= QEMU_NUM_LOCK_LED
;
1657 if (vs
->modifiers_state
[0x3a]) {
1658 ledstate
|= QEMU_CAPS_LOCK_LED
;
1664 static void vnc_led_state_change(VncState
*vs
)
1668 if (!vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
)) {
1672 ledstate
= current_led_state(vs
);
1673 vnc_lock_output(vs
);
1674 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1675 vnc_write_u8(vs
, 0);
1676 vnc_write_u16(vs
, 1);
1677 vnc_framebuffer_update(vs
, 0, 0, 1, 1, VNC_ENCODING_LED_STATE
);
1678 vnc_write_u8(vs
, ledstate
);
1679 vnc_unlock_output(vs
);
1683 static void kbd_leds(void *opaque
, int ledstate
)
1685 VncState
*vs
= opaque
;
1687 bool has_changed
= (ledstate
!= current_led_state(vs
));
1689 trace_vnc_key_guest_leds((ledstate
& QEMU_CAPS_LOCK_LED
),
1690 (ledstate
& QEMU_NUM_LOCK_LED
),
1691 (ledstate
& QEMU_SCROLL_LOCK_LED
));
1693 caps
= ledstate
& QEMU_CAPS_LOCK_LED
? 1 : 0;
1694 num
= ledstate
& QEMU_NUM_LOCK_LED
? 1 : 0;
1695 scr
= ledstate
& QEMU_SCROLL_LOCK_LED
? 1 : 0;
1697 if (vs
->modifiers_state
[0x3a] != caps
) {
1698 vs
->modifiers_state
[0x3a] = caps
;
1700 if (vs
->modifiers_state
[0x45] != num
) {
1701 vs
->modifiers_state
[0x45] = num
;
1703 if (vs
->modifiers_state
[0x46] != scr
) {
1704 vs
->modifiers_state
[0x46] = scr
;
1707 /* Sending the current led state message to the client */
1709 vnc_led_state_change(vs
);
1713 static void do_key_event(VncState
*vs
, int down
, int keycode
, int sym
)
1715 /* QEMU console switch */
1717 case 0x2a: /* Left Shift */
1718 case 0x36: /* Right Shift */
1719 case 0x1d: /* Left CTRL */
1720 case 0x9d: /* Right CTRL */
1721 case 0x38: /* Left ALT */
1722 case 0xb8: /* Right ALT */
1724 vs
->modifiers_state
[keycode
] = 1;
1726 vs
->modifiers_state
[keycode
] = 0;
1728 case 0x02 ... 0x0a: /* '1' to '9' keys */
1729 if (vs
->vd
->dcl
.con
== NULL
&&
1730 down
&& vs
->modifiers_state
[0x1d] && vs
->modifiers_state
[0x38]) {
1731 /* Reset the modifiers sent to the current console */
1733 console_select(keycode
- 0x02);
1737 case 0x3a: /* CapsLock */
1738 case 0x45: /* NumLock */
1740 vs
->modifiers_state
[keycode
] ^= 1;
1744 /* Turn off the lock state sync logic if the client support the led
1747 if (down
&& vs
->vd
->lock_key_sync
&&
1748 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1749 keycode_is_keypad(vs
->vd
->kbd_layout
, keycode
)) {
1750 /* If the numlock state needs to change then simulate an additional
1751 keypress before sending this one. This will happen if the user
1752 toggles numlock away from the VNC window.
1754 if (keysym_is_numlock(vs
->vd
->kbd_layout
, sym
& 0xFFFF)) {
1755 if (!vs
->modifiers_state
[0x45]) {
1756 trace_vnc_key_sync_numlock(true);
1757 vs
->modifiers_state
[0x45] = 1;
1758 press_key(vs
, 0xff7f);
1761 if (vs
->modifiers_state
[0x45]) {
1762 trace_vnc_key_sync_numlock(false);
1763 vs
->modifiers_state
[0x45] = 0;
1764 press_key(vs
, 0xff7f);
1769 if (down
&& vs
->vd
->lock_key_sync
&&
1770 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1771 ((sym
>= 'A' && sym
<= 'Z') || (sym
>= 'a' && sym
<= 'z'))) {
1772 /* If the capslock state needs to change then simulate an additional
1773 keypress before sending this one. This will happen if the user
1774 toggles capslock away from the VNC window.
1776 int uppercase
= !!(sym
>= 'A' && sym
<= 'Z');
1777 int shift
= !!(vs
->modifiers_state
[0x2a] | vs
->modifiers_state
[0x36]);
1778 int capslock
= !!(vs
->modifiers_state
[0x3a]);
1780 if (uppercase
== shift
) {
1781 trace_vnc_key_sync_capslock(false);
1782 vs
->modifiers_state
[0x3a] = 0;
1783 press_key(vs
, 0xffe5);
1786 if (uppercase
!= shift
) {
1787 trace_vnc_key_sync_capslock(true);
1788 vs
->modifiers_state
[0x3a] = 1;
1789 press_key(vs
, 0xffe5);
1794 if (qemu_console_is_graphic(NULL
)) {
1795 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, down
);
1796 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1798 bool numlock
= vs
->modifiers_state
[0x45];
1799 bool control
= (vs
->modifiers_state
[0x1d] ||
1800 vs
->modifiers_state
[0x9d]);
1801 /* QEMU console emulation */
1804 case 0x2a: /* Left Shift */
1805 case 0x36: /* Right Shift */
1806 case 0x1d: /* Left CTRL */
1807 case 0x9d: /* Right CTRL */
1808 case 0x38: /* Left ALT */
1809 case 0xb8: /* Right ALT */
1812 kbd_put_keysym(QEMU_KEY_UP
);
1815 kbd_put_keysym(QEMU_KEY_DOWN
);
1818 kbd_put_keysym(QEMU_KEY_LEFT
);
1821 kbd_put_keysym(QEMU_KEY_RIGHT
);
1824 kbd_put_keysym(QEMU_KEY_DELETE
);
1827 kbd_put_keysym(QEMU_KEY_HOME
);
1830 kbd_put_keysym(QEMU_KEY_END
);
1833 kbd_put_keysym(QEMU_KEY_PAGEUP
);
1836 kbd_put_keysym(QEMU_KEY_PAGEDOWN
);
1840 kbd_put_keysym(numlock
? '7' : QEMU_KEY_HOME
);
1843 kbd_put_keysym(numlock
? '8' : QEMU_KEY_UP
);
1846 kbd_put_keysym(numlock
? '9' : QEMU_KEY_PAGEUP
);
1849 kbd_put_keysym(numlock
? '4' : QEMU_KEY_LEFT
);
1852 kbd_put_keysym('5');
1855 kbd_put_keysym(numlock
? '6' : QEMU_KEY_RIGHT
);
1858 kbd_put_keysym(numlock
? '1' : QEMU_KEY_END
);
1861 kbd_put_keysym(numlock
? '2' : QEMU_KEY_DOWN
);
1864 kbd_put_keysym(numlock
? '3' : QEMU_KEY_PAGEDOWN
);
1867 kbd_put_keysym('0');
1870 kbd_put_keysym(numlock
? '.' : QEMU_KEY_DELETE
);
1874 kbd_put_keysym('/');
1877 kbd_put_keysym('*');
1880 kbd_put_keysym('-');
1883 kbd_put_keysym('+');
1886 kbd_put_keysym('\n');
1891 kbd_put_keysym(sym
& 0x1f);
1893 kbd_put_keysym(sym
);
1901 static void vnc_release_modifiers(VncState
*vs
)
1903 static const int keycodes
[] = {
1904 /* shift, control, alt keys, both left & right */
1905 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1909 if (!qemu_console_is_graphic(NULL
)) {
1912 for (i
= 0; i
< ARRAY_SIZE(keycodes
); i
++) {
1913 keycode
= keycodes
[i
];
1914 if (!vs
->modifiers_state
[keycode
]) {
1917 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1918 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1922 static const char *code2name(int keycode
)
1924 return QKeyCode_lookup
[qemu_input_key_number_to_qcode(keycode
)];
1927 static void key_event(VncState
*vs
, int down
, uint32_t sym
)
1932 if (lsym
>= 'A' && lsym
<= 'Z' && qemu_console_is_graphic(NULL
)) {
1933 lsym
= lsym
- 'A' + 'a';
1936 keycode
= keysym2scancode(vs
->vd
->kbd_layout
, lsym
& 0xFFFF) & SCANCODE_KEYMASK
;
1937 trace_vnc_key_event_map(down
, sym
, keycode
, code2name(keycode
));
1938 do_key_event(vs
, down
, keycode
, sym
);
1941 static void ext_key_event(VncState
*vs
, int down
,
1942 uint32_t sym
, uint16_t keycode
)
1944 /* if the user specifies a keyboard layout, always use it */
1945 if (keyboard_layout
) {
1946 key_event(vs
, down
, sym
);
1948 trace_vnc_key_event_ext(down
, sym
, keycode
, code2name(keycode
));
1949 do_key_event(vs
, down
, keycode
, sym
);
1953 static void framebuffer_update_request(VncState
*vs
, int incremental
,
1954 int x
, int y
, int w
, int h
)
1956 vs
->need_update
= 1;
1962 vs
->force_update
= 1;
1963 vnc_set_area_dirty(vs
->dirty
, vs
->vd
, x
, y
, w
, h
);
1966 static void send_ext_key_event_ack(VncState
*vs
)
1968 vnc_lock_output(vs
);
1969 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1970 vnc_write_u8(vs
, 0);
1971 vnc_write_u16(vs
, 1);
1972 vnc_framebuffer_update(vs
, 0, 0,
1973 pixman_image_get_width(vs
->vd
->server
),
1974 pixman_image_get_height(vs
->vd
->server
),
1975 VNC_ENCODING_EXT_KEY_EVENT
);
1976 vnc_unlock_output(vs
);
1980 static void send_ext_audio_ack(VncState
*vs
)
1982 vnc_lock_output(vs
);
1983 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1984 vnc_write_u8(vs
, 0);
1985 vnc_write_u16(vs
, 1);
1986 vnc_framebuffer_update(vs
, 0, 0,
1987 pixman_image_get_width(vs
->vd
->server
),
1988 pixman_image_get_height(vs
->vd
->server
),
1989 VNC_ENCODING_AUDIO
);
1990 vnc_unlock_output(vs
);
1994 static void set_encodings(VncState
*vs
, int32_t *encodings
, size_t n_encodings
)
1997 unsigned int enc
= 0;
2000 vs
->vnc_encoding
= 0;
2001 vs
->tight
.compression
= 9;
2002 vs
->tight
.quality
= -1; /* Lossless by default */
2006 * Start from the end because the encodings are sent in order of preference.
2007 * This way the preferred encoding (first encoding defined in the array)
2008 * will be set at the end of the loop.
2010 for (i
= n_encodings
- 1; i
>= 0; i
--) {
2013 case VNC_ENCODING_RAW
:
2014 vs
->vnc_encoding
= enc
;
2016 case VNC_ENCODING_COPYRECT
:
2017 vs
->features
|= VNC_FEATURE_COPYRECT_MASK
;
2019 case VNC_ENCODING_HEXTILE
:
2020 vs
->features
|= VNC_FEATURE_HEXTILE_MASK
;
2021 vs
->vnc_encoding
= enc
;
2023 case VNC_ENCODING_TIGHT
:
2024 vs
->features
|= VNC_FEATURE_TIGHT_MASK
;
2025 vs
->vnc_encoding
= enc
;
2027 #ifdef CONFIG_VNC_PNG
2028 case VNC_ENCODING_TIGHT_PNG
:
2029 vs
->features
|= VNC_FEATURE_TIGHT_PNG_MASK
;
2030 vs
->vnc_encoding
= enc
;
2033 case VNC_ENCODING_ZLIB
:
2034 vs
->features
|= VNC_FEATURE_ZLIB_MASK
;
2035 vs
->vnc_encoding
= enc
;
2037 case VNC_ENCODING_ZRLE
:
2038 vs
->features
|= VNC_FEATURE_ZRLE_MASK
;
2039 vs
->vnc_encoding
= enc
;
2041 case VNC_ENCODING_ZYWRLE
:
2042 vs
->features
|= VNC_FEATURE_ZYWRLE_MASK
;
2043 vs
->vnc_encoding
= enc
;
2045 case VNC_ENCODING_DESKTOPRESIZE
:
2046 vs
->features
|= VNC_FEATURE_RESIZE_MASK
;
2048 case VNC_ENCODING_POINTER_TYPE_CHANGE
:
2049 vs
->features
|= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK
;
2051 case VNC_ENCODING_RICH_CURSOR
:
2052 vs
->features
|= VNC_FEATURE_RICH_CURSOR_MASK
;
2053 if (vs
->vd
->cursor
) {
2054 vnc_cursor_define(vs
);
2057 case VNC_ENCODING_EXT_KEY_EVENT
:
2058 send_ext_key_event_ack(vs
);
2060 case VNC_ENCODING_AUDIO
:
2061 send_ext_audio_ack(vs
);
2063 case VNC_ENCODING_WMVi
:
2064 vs
->features
|= VNC_FEATURE_WMVI_MASK
;
2066 case VNC_ENCODING_LED_STATE
:
2067 vs
->features
|= VNC_FEATURE_LED_STATE_MASK
;
2069 case VNC_ENCODING_COMPRESSLEVEL0
... VNC_ENCODING_COMPRESSLEVEL0
+ 9:
2070 vs
->tight
.compression
= (enc
& 0x0F);
2072 case VNC_ENCODING_QUALITYLEVEL0
... VNC_ENCODING_QUALITYLEVEL0
+ 9:
2073 if (vs
->vd
->lossy
) {
2074 vs
->tight
.quality
= (enc
& 0x0F);
2078 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i
, enc
, enc
);
2082 vnc_desktop_resize(vs
);
2083 check_pointer_type_change(&vs
->mouse_mode_notifier
, NULL
);
2084 vnc_led_state_change(vs
);
2087 static void set_pixel_conversion(VncState
*vs
)
2089 pixman_format_code_t fmt
= qemu_pixman_get_format(&vs
->client_pf
);
2091 if (fmt
== VNC_SERVER_FB_FORMAT
) {
2092 vs
->write_pixels
= vnc_write_pixels_copy
;
2093 vnc_hextile_set_pixel_conversion(vs
, 0);
2095 vs
->write_pixels
= vnc_write_pixels_generic
;
2096 vnc_hextile_set_pixel_conversion(vs
, 1);
2100 static void send_color_map(VncState
*vs
)
2104 vnc_write_u8(vs
, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES
);
2105 vnc_write_u8(vs
, 0); /* padding */
2106 vnc_write_u16(vs
, 0); /* first color */
2107 vnc_write_u16(vs
, 256); /* # of colors */
2109 for (i
= 0; i
< 256; i
++) {
2110 PixelFormat
*pf
= &vs
->client_pf
;
2112 vnc_write_u16(vs
, (((i
>> pf
->rshift
) & pf
->rmax
) << (16 - pf
->rbits
)));
2113 vnc_write_u16(vs
, (((i
>> pf
->gshift
) & pf
->gmax
) << (16 - pf
->gbits
)));
2114 vnc_write_u16(vs
, (((i
>> pf
->bshift
) & pf
->bmax
) << (16 - pf
->bbits
)));
2118 static void set_pixel_format(VncState
*vs
,
2119 int bits_per_pixel
, int depth
,
2120 int big_endian_flag
, int true_color_flag
,
2121 int red_max
, int green_max
, int blue_max
,
2122 int red_shift
, int green_shift
, int blue_shift
)
2124 if (!true_color_flag
) {
2125 /* Expose a reasonable default 256 color map */
2136 switch (bits_per_pixel
) {
2142 vnc_client_error(vs
);
2146 vs
->client_pf
.rmax
= red_max
? red_max
: 0xFF;
2147 vs
->client_pf
.rbits
= hweight_long(red_max
);
2148 vs
->client_pf
.rshift
= red_shift
;
2149 vs
->client_pf
.rmask
= red_max
<< red_shift
;
2150 vs
->client_pf
.gmax
= green_max
? green_max
: 0xFF;
2151 vs
->client_pf
.gbits
= hweight_long(green_max
);
2152 vs
->client_pf
.gshift
= green_shift
;
2153 vs
->client_pf
.gmask
= green_max
<< green_shift
;
2154 vs
->client_pf
.bmax
= blue_max
? blue_max
: 0xFF;
2155 vs
->client_pf
.bbits
= hweight_long(blue_max
);
2156 vs
->client_pf
.bshift
= blue_shift
;
2157 vs
->client_pf
.bmask
= blue_max
<< blue_shift
;
2158 vs
->client_pf
.bits_per_pixel
= bits_per_pixel
;
2159 vs
->client_pf
.bytes_per_pixel
= bits_per_pixel
/ 8;
2160 vs
->client_pf
.depth
= bits_per_pixel
== 32 ? 24 : bits_per_pixel
;
2161 vs
->client_be
= big_endian_flag
;
2163 if (!true_color_flag
) {
2167 set_pixel_conversion(vs
);
2169 graphic_hw_invalidate(vs
->vd
->dcl
.con
);
2170 graphic_hw_update(vs
->vd
->dcl
.con
);
2173 static void pixel_format_message (VncState
*vs
) {
2174 char pad
[3] = { 0, 0, 0 };
2176 vs
->client_pf
= qemu_default_pixelformat(32);
2178 vnc_write_u8(vs
, vs
->client_pf
.bits_per_pixel
); /* bits-per-pixel */
2179 vnc_write_u8(vs
, vs
->client_pf
.depth
); /* depth */
2181 #ifdef HOST_WORDS_BIGENDIAN
2182 vnc_write_u8(vs
, 1); /* big-endian-flag */
2184 vnc_write_u8(vs
, 0); /* big-endian-flag */
2186 vnc_write_u8(vs
, 1); /* true-color-flag */
2187 vnc_write_u16(vs
, vs
->client_pf
.rmax
); /* red-max */
2188 vnc_write_u16(vs
, vs
->client_pf
.gmax
); /* green-max */
2189 vnc_write_u16(vs
, vs
->client_pf
.bmax
); /* blue-max */
2190 vnc_write_u8(vs
, vs
->client_pf
.rshift
); /* red-shift */
2191 vnc_write_u8(vs
, vs
->client_pf
.gshift
); /* green-shift */
2192 vnc_write_u8(vs
, vs
->client_pf
.bshift
); /* blue-shift */
2193 vnc_write(vs
, pad
, 3); /* padding */
2195 vnc_hextile_set_pixel_conversion(vs
, 0);
2196 vs
->write_pixels
= vnc_write_pixels_copy
;
2199 static void vnc_colordepth(VncState
*vs
)
2201 if (vnc_has_feature(vs
, VNC_FEATURE_WMVI
)) {
2202 /* Sending a WMVi message to notify the client*/
2203 vnc_lock_output(vs
);
2204 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2205 vnc_write_u8(vs
, 0);
2206 vnc_write_u16(vs
, 1); /* number of rects */
2207 vnc_framebuffer_update(vs
, 0, 0,
2208 pixman_image_get_width(vs
->vd
->server
),
2209 pixman_image_get_height(vs
->vd
->server
),
2211 pixel_format_message(vs
);
2212 vnc_unlock_output(vs
);
2215 set_pixel_conversion(vs
);
2219 static int protocol_client_msg(VncState
*vs
, uint8_t *data
, size_t len
)
2223 VncDisplay
*vd
= vs
->vd
;
2226 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2230 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT
:
2234 set_pixel_format(vs
, read_u8(data
, 4), read_u8(data
, 5),
2235 read_u8(data
, 6), read_u8(data
, 7),
2236 read_u16(data
, 8), read_u16(data
, 10),
2237 read_u16(data
, 12), read_u8(data
, 14),
2238 read_u8(data
, 15), read_u8(data
, 16));
2240 case VNC_MSG_CLIENT_SET_ENCODINGS
:
2245 limit
= read_u16(data
, 2);
2247 return 4 + (limit
* 4);
2249 limit
= read_u16(data
, 2);
2251 for (i
= 0; i
< limit
; i
++) {
2252 int32_t val
= read_s32(data
, 4 + (i
* 4));
2253 memcpy(data
+ 4 + (i
* 4), &val
, sizeof(val
));
2256 set_encodings(vs
, (int32_t *)(data
+ 4), limit
);
2258 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST
:
2262 framebuffer_update_request(vs
,
2263 read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4),
2264 read_u16(data
, 6), read_u16(data
, 8));
2266 case VNC_MSG_CLIENT_KEY_EVENT
:
2270 key_event(vs
, read_u8(data
, 1), read_u32(data
, 4));
2272 case VNC_MSG_CLIENT_POINTER_EVENT
:
2276 pointer_event(vs
, read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4));
2278 case VNC_MSG_CLIENT_CUT_TEXT
:
2283 uint32_t dlen
= read_u32(data
, 4);
2284 if (dlen
> (1 << 20)) {
2285 error_report("vnc: client_cut_text msg payload has %u bytes"
2286 " which exceeds our limit of 1MB.", dlen
);
2287 vnc_client_error(vs
);
2295 client_cut_text(vs
, read_u32(data
, 4), data
+ 8);
2297 case VNC_MSG_CLIENT_QEMU
:
2301 switch (read_u8(data
, 1)) {
2302 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT
:
2306 ext_key_event(vs
, read_u16(data
, 2),
2307 read_u32(data
, 4), read_u32(data
, 8));
2309 case VNC_MSG_CLIENT_QEMU_AUDIO
:
2313 switch (read_u16 (data
, 2)) {
2314 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE
:
2317 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE
:
2320 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT
:
2323 switch (read_u8(data
, 4)) {
2324 case 0: vs
->as
.fmt
= AUD_FMT_U8
; break;
2325 case 1: vs
->as
.fmt
= AUD_FMT_S8
; break;
2326 case 2: vs
->as
.fmt
= AUD_FMT_U16
; break;
2327 case 3: vs
->as
.fmt
= AUD_FMT_S16
; break;
2328 case 4: vs
->as
.fmt
= AUD_FMT_U32
; break;
2329 case 5: vs
->as
.fmt
= AUD_FMT_S32
; break;
2331 VNC_DEBUG("Invalid audio format %d\n", read_u8(data
, 4));
2332 vnc_client_error(vs
);
2335 vs
->as
.nchannels
= read_u8(data
, 5);
2336 if (vs
->as
.nchannels
!= 1 && vs
->as
.nchannels
!= 2) {
2337 VNC_DEBUG("Invalid audio channel coount %d\n",
2339 vnc_client_error(vs
);
2342 vs
->as
.freq
= read_u32(data
, 6);
2345 VNC_DEBUG("Invalid audio message %d\n", read_u8(data
, 4));
2346 vnc_client_error(vs
);
2352 VNC_DEBUG("Msg: %d\n", read_u16(data
, 0));
2353 vnc_client_error(vs
);
2358 VNC_DEBUG("Msg: %d\n", data
[0]);
2359 vnc_client_error(vs
);
2363 vnc_read_when(vs
, protocol_client_msg
, 1);
2367 static int protocol_client_init(VncState
*vs
, uint8_t *data
, size_t len
)
2373 mode
= data
[0] ? VNC_SHARE_MODE_SHARED
: VNC_SHARE_MODE_EXCLUSIVE
;
2374 switch (vs
->vd
->share_policy
) {
2375 case VNC_SHARE_POLICY_IGNORE
:
2377 * Ignore the shared flag. Nothing to do here.
2379 * Doesn't conform to the rfb spec but is traditional qemu
2380 * behavior, thus left here as option for compatibility
2384 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
:
2386 * Policy: Allow clients ask for exclusive access.
2388 * Implementation: When a client asks for exclusive access,
2389 * disconnect all others. Shared connects are allowed as long
2390 * as no exclusive connection exists.
2392 * This is how the rfb spec suggests to handle the shared flag.
2394 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2396 QTAILQ_FOREACH(client
, &vs
->vd
->clients
, next
) {
2400 if (client
->share_mode
!= VNC_SHARE_MODE_EXCLUSIVE
&&
2401 client
->share_mode
!= VNC_SHARE_MODE_SHARED
) {
2404 vnc_disconnect_start(client
);
2407 if (mode
== VNC_SHARE_MODE_SHARED
) {
2408 if (vs
->vd
->num_exclusive
> 0) {
2409 vnc_disconnect_start(vs
);
2414 case VNC_SHARE_POLICY_FORCE_SHARED
:
2416 * Policy: Shared connects only.
2417 * Implementation: Disallow clients asking for exclusive access.
2419 * Useful for shared desktop sessions where you don't want
2420 * someone forgetting to say -shared when running the vnc
2421 * client disconnect everybody else.
2423 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2424 vnc_disconnect_start(vs
);
2429 vnc_set_share_mode(vs
, mode
);
2431 if (vs
->vd
->num_shared
> vs
->vd
->connections_limit
) {
2432 vnc_disconnect_start(vs
);
2436 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
2437 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
2438 vnc_write_u16(vs
, vs
->client_width
);
2439 vnc_write_u16(vs
, vs
->client_height
);
2441 pixel_format_message(vs
);
2444 size
= snprintf(buf
, sizeof(buf
), "QEMU (%s)", qemu_name
);
2446 size
= snprintf(buf
, sizeof(buf
), "QEMU");
2448 vnc_write_u32(vs
, size
);
2449 vnc_write(vs
, buf
, size
);
2452 vnc_client_cache_auth(vs
);
2453 vnc_qmp_event(vs
, QAPI_EVENT_VNC_INITIALIZED
);
2455 vnc_read_when(vs
, protocol_client_msg
, 1);
2460 void start_client_init(VncState
*vs
)
2462 vnc_read_when(vs
, protocol_client_init
, 1);
2465 static void make_challenge(VncState
*vs
)
2469 srand(time(NULL
)+getpid()+getpid()*987654+rand());
2471 for (i
= 0 ; i
< sizeof(vs
->challenge
) ; i
++)
2472 vs
->challenge
[i
] = (int) (256.0*rand()/(RAND_MAX
+1.0));
2475 static int protocol_client_auth_vnc(VncState
*vs
, uint8_t *data
, size_t len
)
2477 unsigned char response
[VNC_AUTH_CHALLENGE_SIZE
];
2479 unsigned char key
[8];
2480 time_t now
= time(NULL
);
2481 QCryptoCipher
*cipher
= NULL
;
2484 if (!vs
->vd
->password
) {
2485 VNC_DEBUG("No password configured on server");
2488 if (vs
->vd
->expires
< now
) {
2489 VNC_DEBUG("Password is expired");
2493 memcpy(response
, vs
->challenge
, VNC_AUTH_CHALLENGE_SIZE
);
2495 /* Calculate the expected challenge response */
2496 pwlen
= strlen(vs
->vd
->password
);
2497 for (i
=0; i
<sizeof(key
); i
++)
2498 key
[i
] = i
<pwlen
? vs
->vd
->password
[i
] : 0;
2500 cipher
= qcrypto_cipher_new(
2501 QCRYPTO_CIPHER_ALG_DES_RFB
,
2502 QCRYPTO_CIPHER_MODE_ECB
,
2503 key
, G_N_ELEMENTS(key
),
2506 VNC_DEBUG("Cannot initialize cipher %s",
2507 error_get_pretty(err
));
2512 if (qcrypto_cipher_encrypt(cipher
,
2515 VNC_AUTH_CHALLENGE_SIZE
,
2517 VNC_DEBUG("Cannot encrypt challenge %s",
2518 error_get_pretty(err
));
2523 /* Compare expected vs actual challenge response */
2524 if (memcmp(response
, data
, VNC_AUTH_CHALLENGE_SIZE
) != 0) {
2525 VNC_DEBUG("Client challenge response did not match\n");
2528 VNC_DEBUG("Accepting VNC challenge response\n");
2529 vnc_write_u32(vs
, 0); /* Accept auth */
2532 start_client_init(vs
);
2535 qcrypto_cipher_free(cipher
);
2539 vnc_write_u32(vs
, 1); /* Reject auth */
2540 if (vs
->minor
>= 8) {
2541 static const char err
[] = "Authentication failed";
2542 vnc_write_u32(vs
, sizeof(err
));
2543 vnc_write(vs
, err
, sizeof(err
));
2546 vnc_client_error(vs
);
2547 qcrypto_cipher_free(cipher
);
2551 void start_auth_vnc(VncState
*vs
)
2554 /* Send client a 'random' challenge */
2555 vnc_write(vs
, vs
->challenge
, sizeof(vs
->challenge
));
2558 vnc_read_when(vs
, protocol_client_auth_vnc
, sizeof(vs
->challenge
));
2562 static int protocol_client_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2564 /* We only advertise 1 auth scheme at a time, so client
2565 * must pick the one we sent. Verify this */
2566 if (data
[0] != vs
->auth
) { /* Reject auth */
2567 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data
[0]);
2568 vnc_write_u32(vs
, 1);
2569 if (vs
->minor
>= 8) {
2570 static const char err
[] = "Authentication failed";
2571 vnc_write_u32(vs
, sizeof(err
));
2572 vnc_write(vs
, err
, sizeof(err
));
2574 vnc_client_error(vs
);
2575 } else { /* Accept requested auth */
2576 VNC_DEBUG("Client requested auth %d\n", (int)data
[0]);
2579 VNC_DEBUG("Accept auth none\n");
2580 if (vs
->minor
>= 8) {
2581 vnc_write_u32(vs
, 0); /* Accept auth completion */
2584 start_client_init(vs
);
2588 VNC_DEBUG("Start VNC auth\n");
2592 case VNC_AUTH_VENCRYPT
:
2593 VNC_DEBUG("Accept VeNCrypt auth\n");
2594 start_auth_vencrypt(vs
);
2597 #ifdef CONFIG_VNC_SASL
2599 VNC_DEBUG("Accept SASL auth\n");
2600 start_auth_sasl(vs
);
2602 #endif /* CONFIG_VNC_SASL */
2604 default: /* Should not be possible, but just in case */
2605 VNC_DEBUG("Reject auth %d server code bug\n", vs
->auth
);
2606 vnc_write_u8(vs
, 1);
2607 if (vs
->minor
>= 8) {
2608 static const char err
[] = "Authentication failed";
2609 vnc_write_u32(vs
, sizeof(err
));
2610 vnc_write(vs
, err
, sizeof(err
));
2612 vnc_client_error(vs
);
2618 static int protocol_version(VncState
*vs
, uint8_t *version
, size_t len
)
2622 memcpy(local
, version
, 12);
2625 if (sscanf(local
, "RFB %03d.%03d\n", &vs
->major
, &vs
->minor
) != 2) {
2626 VNC_DEBUG("Malformed protocol version %s\n", local
);
2627 vnc_client_error(vs
);
2630 VNC_DEBUG("Client request protocol version %d.%d\n", vs
->major
, vs
->minor
);
2631 if (vs
->major
!= 3 ||
2637 VNC_DEBUG("Unsupported client version\n");
2638 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2640 vnc_client_error(vs
);
2643 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2644 * as equivalent to v3.3 by servers
2646 if (vs
->minor
== 4 || vs
->minor
== 5)
2649 if (vs
->minor
== 3) {
2650 if (vs
->auth
== VNC_AUTH_NONE
) {
2651 VNC_DEBUG("Tell client auth none\n");
2652 vnc_write_u32(vs
, vs
->auth
);
2654 start_client_init(vs
);
2655 } else if (vs
->auth
== VNC_AUTH_VNC
) {
2656 VNC_DEBUG("Tell client VNC auth\n");
2657 vnc_write_u32(vs
, vs
->auth
);
2661 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs
->auth
);
2662 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2664 vnc_client_error(vs
);
2667 VNC_DEBUG("Telling client we support auth %d\n", vs
->auth
);
2668 vnc_write_u8(vs
, 1); /* num auth */
2669 vnc_write_u8(vs
, vs
->auth
);
2670 vnc_read_when(vs
, protocol_client_auth
, 1);
2677 static VncRectStat
*vnc_stat_rect(VncDisplay
*vd
, int x
, int y
)
2679 struct VncSurface
*vs
= &vd
->guest
;
2681 return &vs
->stats
[y
/ VNC_STAT_RECT
][x
/ VNC_STAT_RECT
];
2684 void vnc_sent_lossy_rect(VncState
*vs
, int x
, int y
, int w
, int h
)
2688 w
= (x
+ w
) / VNC_STAT_RECT
;
2689 h
= (y
+ h
) / VNC_STAT_RECT
;
2693 for (j
= y
; j
<= h
; j
++) {
2694 for (i
= x
; i
<= w
; i
++) {
2695 vs
->lossy_rect
[j
][i
] = 1;
2700 static int vnc_refresh_lossy_rect(VncDisplay
*vd
, int x
, int y
)
2703 int sty
= y
/ VNC_STAT_RECT
;
2704 int stx
= x
/ VNC_STAT_RECT
;
2707 y
= y
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2708 x
= x
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2710 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2713 /* kernel send buffers are full -> refresh later */
2714 if (vs
->output
.offset
) {
2718 if (!vs
->lossy_rect
[sty
][stx
]) {
2722 vs
->lossy_rect
[sty
][stx
] = 0;
2723 for (j
= 0; j
< VNC_STAT_RECT
; ++j
) {
2724 bitmap_set(vs
->dirty
[y
+ j
],
2725 x
/ VNC_DIRTY_PIXELS_PER_BIT
,
2726 VNC_STAT_RECT
/ VNC_DIRTY_PIXELS_PER_BIT
);
2734 static int vnc_update_stats(VncDisplay
*vd
, struct timeval
* tv
)
2736 int width
= pixman_image_get_width(vd
->guest
.fb
);
2737 int height
= pixman_image_get_height(vd
->guest
.fb
);
2742 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2743 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2744 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2746 rect
->updated
= false;
2750 qemu_timersub(tv
, &VNC_REFRESH_STATS
, &res
);
2752 if (timercmp(&vd
->guest
.last_freq_check
, &res
, >)) {
2755 vd
->guest
.last_freq_check
= *tv
;
2757 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2758 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2759 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2760 int count
= ARRAY_SIZE(rect
->times
);
2761 struct timeval min
, max
;
2763 if (!timerisset(&rect
->times
[count
- 1])) {
2767 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2768 qemu_timersub(tv
, &max
, &res
);
2770 if (timercmp(&res
, &VNC_REFRESH_LOSSY
, >)) {
2772 has_dirty
+= vnc_refresh_lossy_rect(vd
, x
, y
);
2773 memset(rect
->times
, 0, sizeof (rect
->times
));
2777 min
= rect
->times
[rect
->idx
];
2778 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2779 qemu_timersub(&max
, &min
, &res
);
2781 rect
->freq
= res
.tv_sec
+ res
.tv_usec
/ 1000000.;
2782 rect
->freq
/= count
;
2783 rect
->freq
= 1. / rect
->freq
;
2789 double vnc_update_freq(VncState
*vs
, int x
, int y
, int w
, int h
)
2795 x
= (x
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2796 y
= (y
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2798 for (j
= y
; j
<= y
+ h
; j
+= VNC_STAT_RECT
) {
2799 for (i
= x
; i
<= x
+ w
; i
+= VNC_STAT_RECT
) {
2800 total
+= vnc_stat_rect(vs
->vd
, i
, j
)->freq
;
2812 static void vnc_rect_updated(VncDisplay
*vd
, int x
, int y
, struct timeval
* tv
)
2816 rect
= vnc_stat_rect(vd
, x
, y
);
2817 if (rect
->updated
) {
2820 rect
->times
[rect
->idx
] = *tv
;
2821 rect
->idx
= (rect
->idx
+ 1) % ARRAY_SIZE(rect
->times
);
2822 rect
->updated
= true;
2825 static int vnc_refresh_server_surface(VncDisplay
*vd
)
2827 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2828 pixman_image_get_width(vd
->server
));
2829 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2830 pixman_image_get_height(vd
->server
));
2831 int cmp_bytes
, server_stride
, line_bytes
, guest_ll
, guest_stride
, y
= 0;
2832 uint8_t *guest_row0
= NULL
, *server_row0
;
2835 pixman_image_t
*tmpbuf
= NULL
;
2837 struct timeval tv
= { 0, 0 };
2839 if (!vd
->non_adaptive
) {
2840 gettimeofday(&tv
, NULL
);
2841 has_dirty
= vnc_update_stats(vd
, &tv
);
2845 * Walk through the guest dirty map.
2846 * Check and copy modified bits from guest to server surface.
2847 * Update server dirty map.
2849 server_row0
= (uint8_t *)pixman_image_get_data(vd
->server
);
2850 server_stride
= guest_stride
= guest_ll
=
2851 pixman_image_get_stride(vd
->server
);
2852 cmp_bytes
= MIN(VNC_DIRTY_PIXELS_PER_BIT
* VNC_SERVER_FB_BYTES
,
2854 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2855 int width
= pixman_image_get_width(vd
->server
);
2856 tmpbuf
= qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT
, width
);
2859 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd
->guest
.fb
));
2860 guest_row0
= (uint8_t *)pixman_image_get_data(vd
->guest
.fb
);
2861 guest_stride
= pixman_image_get_stride(vd
->guest
.fb
);
2862 guest_ll
= pixman_image_get_width(vd
->guest
.fb
) * ((guest_bpp
+ 7) / 8);
2864 line_bytes
= MIN(server_stride
, guest_ll
);
2868 uint8_t *guest_ptr
, *server_ptr
;
2869 unsigned long offset
= find_next_bit((unsigned long *) &vd
->guest
.dirty
,
2870 height
* VNC_DIRTY_BPL(&vd
->guest
),
2871 y
* VNC_DIRTY_BPL(&vd
->guest
));
2872 if (offset
== height
* VNC_DIRTY_BPL(&vd
->guest
)) {
2873 /* no more dirty bits */
2876 y
= offset
/ VNC_DIRTY_BPL(&vd
->guest
);
2877 x
= offset
% VNC_DIRTY_BPL(&vd
->guest
);
2879 server_ptr
= server_row0
+ y
* server_stride
+ x
* cmp_bytes
;
2881 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2882 qemu_pixman_linebuf_fill(tmpbuf
, vd
->guest
.fb
, width
, 0, y
);
2883 guest_ptr
= (uint8_t *)pixman_image_get_data(tmpbuf
);
2885 guest_ptr
= guest_row0
+ y
* guest_stride
;
2887 guest_ptr
+= x
* cmp_bytes
;
2889 for (; x
< DIV_ROUND_UP(width
, VNC_DIRTY_PIXELS_PER_BIT
);
2890 x
++, guest_ptr
+= cmp_bytes
, server_ptr
+= cmp_bytes
) {
2891 int _cmp_bytes
= cmp_bytes
;
2892 if (!test_and_clear_bit(x
, vd
->guest
.dirty
[y
])) {
2895 if ((x
+ 1) * cmp_bytes
> line_bytes
) {
2896 _cmp_bytes
= line_bytes
- x
* cmp_bytes
;
2898 assert(_cmp_bytes
>= 0);
2899 if (memcmp(server_ptr
, guest_ptr
, _cmp_bytes
) == 0) {
2902 memcpy(server_ptr
, guest_ptr
, _cmp_bytes
);
2903 if (!vd
->non_adaptive
) {
2904 vnc_rect_updated(vd
, x
* VNC_DIRTY_PIXELS_PER_BIT
,
2907 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2908 set_bit(x
, vs
->dirty
[y
]);
2915 qemu_pixman_image_unref(tmpbuf
);
2919 static void vnc_refresh(DisplayChangeListener
*dcl
)
2921 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
2923 int has_dirty
, rects
= 0;
2925 if (QTAILQ_EMPTY(&vd
->clients
)) {
2926 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_MAX
);
2930 graphic_hw_update(vd
->dcl
.con
);
2932 if (vnc_trylock_display(vd
)) {
2933 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2937 has_dirty
= vnc_refresh_server_surface(vd
);
2938 vnc_unlock_display(vd
);
2940 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
2941 rects
+= vnc_update_client(vs
, has_dirty
, false);
2942 /* vs might be free()ed here */
2945 if (has_dirty
&& rects
) {
2946 vd
->dcl
.update_interval
/= 2;
2947 if (vd
->dcl
.update_interval
< VNC_REFRESH_INTERVAL_BASE
) {
2948 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_BASE
;
2951 vd
->dcl
.update_interval
+= VNC_REFRESH_INTERVAL_INC
;
2952 if (vd
->dcl
.update_interval
> VNC_REFRESH_INTERVAL_MAX
) {
2953 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_MAX
;
2958 static void vnc_connect(VncDisplay
*vd
, QIOChannelSocket
*sioc
,
2959 bool skipauth
, bool websocket
)
2961 VncState
*vs
= g_new0(VncState
, 1);
2965 object_ref(OBJECT(vs
->sioc
));
2966 vs
->ioc
= QIO_CHANNEL(sioc
);
2967 object_ref(OBJECT(vs
->ioc
));
2970 buffer_init(&vs
->input
, "vnc-input/%p", sioc
);
2971 buffer_init(&vs
->output
, "vnc-output/%p", sioc
);
2972 buffer_init(&vs
->jobs_buffer
, "vnc-jobs_buffer/%p", sioc
);
2974 buffer_init(&vs
->tight
.tight
, "vnc-tight/%p", sioc
);
2975 buffer_init(&vs
->tight
.zlib
, "vnc-tight-zlib/%p", sioc
);
2976 buffer_init(&vs
->tight
.gradient
, "vnc-tight-gradient/%p", sioc
);
2977 #ifdef CONFIG_VNC_JPEG
2978 buffer_init(&vs
->tight
.jpeg
, "vnc-tight-jpeg/%p", sioc
);
2980 #ifdef CONFIG_VNC_PNG
2981 buffer_init(&vs
->tight
.png
, "vnc-tight-png/%p", sioc
);
2983 buffer_init(&vs
->zlib
.zlib
, "vnc-zlib/%p", sioc
);
2984 buffer_init(&vs
->zrle
.zrle
, "vnc-zrle/%p", sioc
);
2985 buffer_init(&vs
->zrle
.fb
, "vnc-zrle-fb/%p", sioc
);
2986 buffer_init(&vs
->zrle
.zlib
, "vnc-zrle-zlib/%p", sioc
);
2989 vs
->auth
= VNC_AUTH_NONE
;
2990 vs
->subauth
= VNC_AUTH_INVALID
;
2993 vs
->auth
= vd
->ws_auth
;
2994 vs
->subauth
= VNC_AUTH_INVALID
;
2996 vs
->auth
= vd
->auth
;
2997 vs
->subauth
= vd
->subauth
;
3000 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
3001 sioc
, websocket
, vs
->auth
, vs
->subauth
);
3003 vs
->lossy_rect
= g_malloc0(VNC_STAT_ROWS
* sizeof (*vs
->lossy_rect
));
3004 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
3005 vs
->lossy_rect
[i
] = g_new0(uint8_t, VNC_STAT_COLS
);
3008 VNC_DEBUG("New client on socket %p\n", vs
->sioc
);
3009 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
3010 qio_channel_set_blocking(vs
->ioc
, false, NULL
);
3014 vs
->ioc_tag
= qio_channel_add_watch(
3015 vs
->ioc
, G_IO_IN
, vncws_tls_handshake_io
, vs
, NULL
);
3017 vs
->ioc_tag
= qio_channel_add_watch(
3018 vs
->ioc
, G_IO_IN
, vncws_handshake_io
, vs
, NULL
);
3021 vs
->ioc_tag
= qio_channel_add_watch(
3022 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
3025 vnc_client_cache_addr(vs
);
3026 vnc_qmp_event(vs
, QAPI_EVENT_VNC_CONNECTED
);
3027 vnc_set_share_mode(vs
, VNC_SHARE_MODE_CONNECTING
);
3029 if (!vs
->websocket
) {
3033 if (vd
->num_connecting
> vd
->connections_limit
) {
3034 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
3035 if (vs
->share_mode
== VNC_SHARE_MODE_CONNECTING
) {
3036 vnc_disconnect_start(vs
);
3043 void vnc_init_state(VncState
*vs
)
3045 vs
->initialized
= true;
3046 VncDisplay
*vd
= vs
->vd
;
3047 bool first_client
= QTAILQ_EMPTY(&vd
->clients
);
3052 vs
->as
.freq
= 44100;
3053 vs
->as
.nchannels
= 2;
3054 vs
->as
.fmt
= AUD_FMT_S16
;
3055 vs
->as
.endianness
= 0;
3057 qemu_mutex_init(&vs
->output_mutex
);
3058 vs
->bh
= qemu_bh_new(vnc_jobs_bh
, vs
);
3060 QTAILQ_INSERT_TAIL(&vd
->clients
, vs
, next
);
3062 vnc_update_server_surface(vd
);
3065 graphic_hw_update(vd
->dcl
.con
);
3067 vnc_write(vs
, "RFB 003.008\n", 12);
3069 vnc_read_when(vs
, protocol_version
, 12);
3071 if (vs
->vd
->lock_key_sync
)
3072 vs
->led
= qemu_add_led_event_handler(kbd_leds
, vs
);
3074 vs
->mouse_mode_notifier
.notify
= check_pointer_type_change
;
3075 qemu_add_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
3077 /* vs might be free()ed here */
3080 static gboolean
vnc_listen_io(QIOChannel
*ioc
,
3081 GIOCondition condition
,
3084 VncDisplay
*vs
= opaque
;
3085 QIOChannelSocket
*sioc
= NULL
;
3089 graphic_hw_update(vs
->dcl
.con
);
3090 sioc
= qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc
), &err
);
3092 qio_channel_set_delay(QIO_CHANNEL(sioc
), false);
3093 vnc_connect(vs
, sioc
, false,
3094 ioc
!= QIO_CHANNEL(vs
->lsock
));
3095 object_unref(OBJECT(sioc
));
3097 /* client probably closed connection before we got there */
3104 static const DisplayChangeListenerOps dcl_ops
= {
3106 .dpy_refresh
= vnc_refresh
,
3107 .dpy_gfx_copy
= vnc_dpy_copy
,
3108 .dpy_gfx_update
= vnc_dpy_update
,
3109 .dpy_gfx_switch
= vnc_dpy_switch
,
3110 .dpy_gfx_check_format
= qemu_pixman_check_format
,
3111 .dpy_mouse_set
= vnc_mouse_set
,
3112 .dpy_cursor_define
= vnc_dpy_cursor_define
,
3115 void vnc_display_init(const char *id
)
3119 if (vnc_display_find(id
) != NULL
) {
3122 vs
= g_malloc0(sizeof(*vs
));
3124 vs
->id
= strdup(id
);
3125 QTAILQ_INSERT_TAIL(&vnc_displays
, vs
, next
);
3127 QTAILQ_INIT(&vs
->clients
);
3128 vs
->expires
= TIME_MAX
;
3130 if (keyboard_layout
) {
3131 trace_vnc_key_map_init(keyboard_layout
);
3132 vs
->kbd_layout
= init_keyboard_layout(name2keysym
, keyboard_layout
);
3134 vs
->kbd_layout
= init_keyboard_layout(name2keysym
, "en-us");
3137 if (!vs
->kbd_layout
)
3140 qemu_mutex_init(&vs
->mutex
);
3141 vnc_start_worker_thread();
3143 vs
->dcl
.ops
= &dcl_ops
;
3144 register_displaychangelistener(&vs
->dcl
);
3148 static void vnc_display_close(VncDisplay
*vs
)
3152 vs
->enabled
= false;
3153 vs
->is_unix
= false;
3154 if (vs
->lsock
!= NULL
) {
3155 if (vs
->lsock_tag
) {
3156 g_source_remove(vs
->lsock_tag
);
3158 object_unref(OBJECT(vs
->lsock
));
3161 vs
->ws_enabled
= false;
3162 if (vs
->lwebsock
!= NULL
) {
3163 if (vs
->lwebsock_tag
) {
3164 g_source_remove(vs
->lwebsock_tag
);
3166 object_unref(OBJECT(vs
->lwebsock
));
3167 vs
->lwebsock
= NULL
;
3169 vs
->auth
= VNC_AUTH_INVALID
;
3170 vs
->subauth
= VNC_AUTH_INVALID
;
3172 object_unparent(OBJECT(vs
->tlscreds
));
3173 vs
->tlscreds
= NULL
;
3175 g_free(vs
->tlsaclname
);
3176 vs
->tlsaclname
= NULL
;
3179 int vnc_display_password(const char *id
, const char *password
)
3181 VncDisplay
*vs
= vnc_display_find(id
);
3186 if (vs
->auth
== VNC_AUTH_NONE
) {
3187 error_printf_unless_qmp("If you want use passwords please enable "
3188 "password auth using '-vnc ${dpy},password'.");
3192 g_free(vs
->password
);
3193 vs
->password
= g_strdup(password
);
3198 int vnc_display_pw_expire(const char *id
, time_t expires
)
3200 VncDisplay
*vs
= vnc_display_find(id
);
3206 vs
->expires
= expires
;
3210 char *vnc_display_local_addr(const char *id
)
3212 VncDisplay
*vs
= vnc_display_find(id
);
3213 SocketAddress
*addr
;
3219 addr
= qio_channel_socket_get_local_address(vs
->lsock
, &err
);
3224 if (addr
->type
!= SOCKET_ADDRESS_KIND_INET
) {
3225 qapi_free_SocketAddress(addr
);
3228 ret
= g_strdup_printf("%s;%s", addr
->u
.inet
.data
->host
,
3229 addr
->u
.inet
.data
->port
);
3230 qapi_free_SocketAddress(addr
);
3235 static QemuOptsList qemu_vnc_opts
= {
3237 .head
= QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts
.head
),
3238 .implied_opt_name
= "vnc",
3242 .type
= QEMU_OPT_STRING
,
3244 .name
= "websocket",
3245 .type
= QEMU_OPT_STRING
,
3247 .name
= "tls-creds",
3248 .type
= QEMU_OPT_STRING
,
3250 /* Deprecated in favour of tls-creds */
3252 .type
= QEMU_OPT_STRING
,
3255 .type
= QEMU_OPT_STRING
,
3258 .type
= QEMU_OPT_STRING
,
3261 .type
= QEMU_OPT_NUMBER
,
3263 .name
= "connections",
3264 .type
= QEMU_OPT_NUMBER
,
3267 .type
= QEMU_OPT_NUMBER
,
3270 .type
= QEMU_OPT_BOOL
,
3273 .type
= QEMU_OPT_BOOL
,
3276 .type
= QEMU_OPT_BOOL
,
3279 .type
= QEMU_OPT_BOOL
,
3281 .name
= "lock-key-sync",
3282 .type
= QEMU_OPT_BOOL
,
3284 .name
= "key-delay-ms",
3285 .type
= QEMU_OPT_NUMBER
,
3288 .type
= QEMU_OPT_BOOL
,
3290 /* Deprecated in favour of tls-creds */
3292 .type
= QEMU_OPT_BOOL
,
3294 /* Deprecated in favour of tls-creds */
3295 .name
= "x509verify",
3296 .type
= QEMU_OPT_STRING
,
3299 .type
= QEMU_OPT_BOOL
,
3302 .type
= QEMU_OPT_BOOL
,
3304 .name
= "non-adaptive",
3305 .type
= QEMU_OPT_BOOL
,
3307 { /* end of list */ }
3313 vnc_display_setup_auth(VncDisplay
*vs
,
3320 * We have a choice of 3 authentication options
3326 * The channel can be run in 2 modes
3331 * And TLS can use 2 types of credentials
3336 * We thus have 9 possible logical combinations
3341 * 4. tls + anon + none
3342 * 5. tls + anon + vnc
3343 * 6. tls + anon + sasl
3344 * 7. tls + x509 + none
3345 * 8. tls + x509 + vnc
3346 * 9. tls + x509 + sasl
3348 * These need to be mapped into the VNC auth schemes
3349 * in an appropriate manner. In regular VNC, all the
3350 * TLS options get mapped into VNC_AUTH_VENCRYPT
3353 * In websockets, the https:// protocol already provides
3354 * TLS support, so there is no need to make use of the
3355 * VeNCrypt extension. Furthermore, websockets browser
3356 * clients could not use VeNCrypt even if they wanted to,
3357 * as they cannot control when the TLS handshake takes
3358 * place. Thus there is no option but to rely on https://,
3359 * meaning combinations 4->6 and 7->9 will be mapped to
3360 * VNC auth schemes in the same way as combos 1->3.
3362 * Regardless of fact that we have a different mapping to
3363 * VNC auth mechs for plain VNC vs websockets VNC, the end
3364 * result has the same security characteristics.
3368 vs
->auth
= VNC_AUTH_VENCRYPT
;
3372 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3373 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3374 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3375 vs
->subauth
= VNC_AUTH_VENCRYPT_X509VNC
;
3376 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3377 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3378 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3379 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSVNC
;
3382 "Unsupported TLS cred type %s",
3383 object_get_typename(OBJECT(vs
->tlscreds
)));
3387 VNC_DEBUG("Initializing VNC server with password auth\n");
3388 vs
->auth
= VNC_AUTH_VNC
;
3389 vs
->subauth
= VNC_AUTH_INVALID
;
3392 vs
->ws_auth
= VNC_AUTH_VNC
;
3394 vs
->ws_auth
= VNC_AUTH_INVALID
;
3398 vs
->auth
= VNC_AUTH_VENCRYPT
;
3402 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3403 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3404 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3405 vs
->subauth
= VNC_AUTH_VENCRYPT_X509SASL
;
3406 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3407 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3408 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3409 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSSASL
;
3412 "Unsupported TLS cred type %s",
3413 object_get_typename(OBJECT(vs
->tlscreds
)));
3417 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3418 vs
->auth
= VNC_AUTH_SASL
;
3419 vs
->subauth
= VNC_AUTH_INVALID
;
3422 vs
->ws_auth
= VNC_AUTH_SASL
;
3424 vs
->ws_auth
= VNC_AUTH_INVALID
;
3428 vs
->auth
= VNC_AUTH_VENCRYPT
;
3432 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3433 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3434 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3435 vs
->subauth
= VNC_AUTH_VENCRYPT_X509NONE
;
3436 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3437 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3438 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3439 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSNONE
;
3442 "Unsupported TLS cred type %s",
3443 object_get_typename(OBJECT(vs
->tlscreds
)));
3447 VNC_DEBUG("Initializing VNC server with no auth\n");
3448 vs
->auth
= VNC_AUTH_NONE
;
3449 vs
->subauth
= VNC_AUTH_INVALID
;
3452 vs
->ws_auth
= VNC_AUTH_NONE
;
3454 vs
->ws_auth
= VNC_AUTH_INVALID
;
3462 * Handle back compat with old CLI syntax by creating some
3463 * suitable QCryptoTLSCreds objects
3465 static QCryptoTLSCreds
*
3466 vnc_display_create_creds(bool x509
,
3472 gchar
*credsid
= g_strdup_printf("tlsvnc%s", id
);
3473 Object
*parent
= object_get_objects_root();
3478 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509
,
3482 "endpoint", "server",
3484 "verify-peer", x509verify
? "yes" : "no",
3487 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON
,
3491 "endpoint", "server",
3498 error_propagate(errp
, err
);
3502 return QCRYPTO_TLS_CREDS(creds
);
3506 void vnc_display_open(const char *id
, Error
**errp
)
3508 VncDisplay
*vs
= vnc_display_find(id
);
3509 QemuOpts
*opts
= qemu_opts_find(&qemu_vnc_opts
, id
);
3510 SocketAddress
*saddr
= NULL
, *wsaddr
= NULL
;
3511 const char *share
, *device_id
;
3513 bool password
= false;
3514 bool reverse
= false;
3519 #ifdef CONFIG_VNC_SASL
3523 int lock_key_sync
= 1;
3527 error_setg(errp
, "VNC display not active");
3530 vnc_display_close(vs
);
3535 vnc
= qemu_opt_get(opts
, "vnc");
3536 if (!vnc
|| strcmp(vnc
, "none") == 0) {
3540 h
= strrchr(vnc
, ':');
3542 size_t hlen
= h
- vnc
;
3544 const char *websocket
= qemu_opt_get(opts
, "websocket");
3545 int to
= qemu_opt_get_number(opts
, "to", 0);
3546 bool has_ipv4
= qemu_opt_get(opts
, "ipv4");
3547 bool has_ipv6
= qemu_opt_get(opts
, "ipv6");
3548 bool ipv4
= qemu_opt_get_bool(opts
, "ipv4", false);
3549 bool ipv6
= qemu_opt_get_bool(opts
, "ipv6", false);
3551 saddr
= g_new0(SocketAddress
, 1);
3553 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1
)) {
3555 "SHA1 hash support is required for websockets");
3559 wsaddr
= g_new0(SocketAddress
, 1);
3560 vs
->ws_enabled
= true;
3563 if (strncmp(vnc
, "unix:", 5) == 0) {
3564 saddr
->type
= SOCKET_ADDRESS_KIND_UNIX
;
3565 saddr
->u
.q_unix
.data
= g_new0(UnixSocketAddress
, 1);
3566 saddr
->u
.q_unix
.data
->path
= g_strdup(vnc
+ 5);
3568 if (vs
->ws_enabled
) {
3569 error_setg(errp
, "UNIX sockets not supported with websock");
3573 unsigned long long baseport
;
3574 InetSocketAddress
*inet
;
3575 saddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3576 inet
= saddr
->u
.inet
.data
= g_new0(InetSocketAddress
, 1);
3577 if (vnc
[0] == '[' && vnc
[hlen
- 1] == ']') {
3578 inet
->host
= g_strndup(vnc
+ 1, hlen
- 2);
3580 inet
->host
= g_strndup(vnc
, hlen
);
3582 if (parse_uint_full(h
+ 1, &baseport
, 10) < 0) {
3583 error_setg(errp
, "can't convert to a number: %s", h
+ 1);
3586 if (baseport
> 65535 ||
3587 baseport
+ 5900 > 65535) {
3588 error_setg(errp
, "port %s out of range", h
+ 1);
3591 inet
->port
= g_strdup_printf(
3592 "%d", (int)baseport
+ 5900);
3595 inet
->has_to
= true;
3596 inet
->to
= to
+ 5900;
3599 inet
->has_ipv4
= has_ipv4
;
3601 inet
->has_ipv6
= has_ipv6
;
3603 if (vs
->ws_enabled
) {
3604 wsaddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3605 inet
= wsaddr
->u
.inet
.data
= g_new0(InetSocketAddress
, 1);
3606 inet
->host
= g_strdup(saddr
->u
.inet
.data
->host
);
3607 inet
->port
= g_strdup(websocket
);
3610 inet
->has_to
= true;
3614 inet
->has_ipv4
= has_ipv4
;
3616 inet
->has_ipv6
= has_ipv6
;
3620 error_setg(errp
, "no vnc port specified");
3624 password
= qemu_opt_get_bool(opts
, "password", false);
3626 if (fips_get_state()) {
3628 "VNC password auth disabled due to FIPS mode, "
3629 "consider using the VeNCrypt or SASL authentication "
3630 "methods as an alternative");
3633 if (!qcrypto_cipher_supports(
3634 QCRYPTO_CIPHER_ALG_DES_RFB
)) {
3636 "Cipher backend does not support DES RFB algorithm");
3641 reverse
= qemu_opt_get_bool(opts
, "reverse", false);
3642 lock_key_sync
= qemu_opt_get_bool(opts
, "lock-key-sync", true);
3643 key_delay_ms
= qemu_opt_get_number(opts
, "key-delay-ms", 1);
3644 sasl
= qemu_opt_get_bool(opts
, "sasl", false);
3645 #ifndef CONFIG_VNC_SASL
3647 error_setg(errp
, "VNC SASL auth requires cyrus-sasl support");
3650 #endif /* CONFIG_VNC_SASL */
3651 credid
= qemu_opt_get(opts
, "tls-creds");
3654 if (qemu_opt_get(opts
, "tls") ||
3655 qemu_opt_get(opts
, "x509") ||
3656 qemu_opt_get(opts
, "x509verify")) {
3658 "'tls-creds' parameter is mutually exclusive with "
3659 "'tls', 'x509' and 'x509verify' parameters");
3663 creds
= object_resolve_path_component(
3664 object_get_objects_root(), credid
);
3666 error_setg(errp
, "No TLS credentials with id '%s'",
3670 vs
->tlscreds
= (QCryptoTLSCreds
*)
3671 object_dynamic_cast(creds
,
3672 TYPE_QCRYPTO_TLS_CREDS
);
3673 if (!vs
->tlscreds
) {
3674 error_setg(errp
, "Object with id '%s' is not TLS credentials",
3678 object_ref(OBJECT(vs
->tlscreds
));
3680 if (vs
->tlscreds
->endpoint
!= QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
) {
3682 "Expecting TLS credentials with a server endpoint");
3687 bool tls
= false, x509
= false, x509verify
= false;
3688 tls
= qemu_opt_get_bool(opts
, "tls", false);
3690 path
= qemu_opt_get(opts
, "x509");
3695 path
= qemu_opt_get(opts
, "x509verify");
3701 vs
->tlscreds
= vnc_display_create_creds(x509
,
3706 if (!vs
->tlscreds
) {
3711 acl
= qemu_opt_get_bool(opts
, "acl", false);
3713 share
= qemu_opt_get(opts
, "share");
3715 if (strcmp(share
, "ignore") == 0) {
3716 vs
->share_policy
= VNC_SHARE_POLICY_IGNORE
;
3717 } else if (strcmp(share
, "allow-exclusive") == 0) {
3718 vs
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3719 } else if (strcmp(share
, "force-shared") == 0) {
3720 vs
->share_policy
= VNC_SHARE_POLICY_FORCE_SHARED
;
3722 error_setg(errp
, "unknown vnc share= option");
3726 vs
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3728 vs
->connections_limit
= qemu_opt_get_number(opts
, "connections", 32);
3730 #ifdef CONFIG_VNC_JPEG
3731 vs
->lossy
= qemu_opt_get_bool(opts
, "lossy", false);
3733 vs
->non_adaptive
= qemu_opt_get_bool(opts
, "non-adaptive", false);
3734 /* adaptive updates are only used with tight encoding and
3735 * if lossy updates are enabled so we can disable all the
3736 * calculations otherwise */
3738 vs
->non_adaptive
= true;
3742 if (strcmp(vs
->id
, "default") == 0) {
3743 vs
->tlsaclname
= g_strdup("vnc.x509dname");
3745 vs
->tlsaclname
= g_strdup_printf("vnc.%s.x509dname", vs
->id
);
3747 qemu_acl_init(vs
->tlsaclname
);
3749 #ifdef CONFIG_VNC_SASL
3753 if (strcmp(vs
->id
, "default") == 0) {
3754 aclname
= g_strdup("vnc.username");
3756 aclname
= g_strdup_printf("vnc.%s.username", vs
->id
);
3758 vs
->sasl
.acl
= qemu_acl_init(aclname
);
3763 if (vnc_display_setup_auth(vs
, password
, sasl
, vs
->ws_enabled
, errp
) < 0) {
3767 #ifdef CONFIG_VNC_SASL
3768 if ((saslErr
= sasl_server_init(NULL
, "qemu")) != SASL_OK
) {
3769 error_setg(errp
, "Failed to initialize SASL auth: %s",
3770 sasl_errstring(saslErr
, NULL
, NULL
));
3774 vs
->lock_key_sync
= lock_key_sync
;
3775 vs
->key_delay_ms
= key_delay_ms
;
3777 device_id
= qemu_opt_get(opts
, "display");
3779 int head
= qemu_opt_get_number(opts
, "head", 0);
3782 con
= qemu_console_lookup_by_device_name(device_id
, head
, &err
);
3784 error_propagate(errp
, err
);
3791 if (con
!= vs
->dcl
.con
) {
3792 unregister_displaychangelistener(&vs
->dcl
);
3794 register_displaychangelistener(&vs
->dcl
);
3798 /* connect to viewer */
3799 QIOChannelSocket
*sioc
= NULL
;
3801 vs
->lwebsock
= NULL
;
3802 if (vs
->ws_enabled
) {
3803 error_setg(errp
, "Cannot use websockets in reverse mode");
3806 vs
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3807 sioc
= qio_channel_socket_new();
3808 if (qio_channel_socket_connect_sync(sioc
, saddr
, errp
) < 0) {
3811 vnc_connect(vs
, sioc
, false, false);
3812 object_unref(OBJECT(sioc
));
3814 vs
->lsock
= qio_channel_socket_new();
3815 if (qio_channel_socket_listen_sync(vs
->lsock
, saddr
, errp
) < 0) {
3818 vs
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3821 if (vs
->ws_enabled
) {
3822 vs
->lwebsock
= qio_channel_socket_new();
3823 if (qio_channel_socket_listen_sync(vs
->lwebsock
,
3824 wsaddr
, errp
) < 0) {
3825 object_unref(OBJECT(vs
->lsock
));
3831 vs
->lsock_tag
= qio_channel_add_watch(
3832 QIO_CHANNEL(vs
->lsock
),
3833 G_IO_IN
, vnc_listen_io
, vs
, NULL
);
3834 if (vs
->ws_enabled
) {
3835 vs
->lwebsock_tag
= qio_channel_add_watch(
3836 QIO_CHANNEL(vs
->lwebsock
),
3837 G_IO_IN
, vnc_listen_io
, vs
, NULL
);
3841 qapi_free_SocketAddress(saddr
);
3842 qapi_free_SocketAddress(wsaddr
);
3846 qapi_free_SocketAddress(saddr
);
3847 qapi_free_SocketAddress(wsaddr
);
3848 vs
->enabled
= false;
3849 vs
->ws_enabled
= false;
3852 void vnc_display_add_client(const char *id
, int csock
, bool skipauth
)
3854 VncDisplay
*vs
= vnc_display_find(id
);
3855 QIOChannelSocket
*sioc
;
3861 sioc
= qio_channel_socket_new_fd(csock
, NULL
);
3863 vnc_connect(vs
, sioc
, skipauth
, false);
3864 object_unref(OBJECT(sioc
));
3868 static void vnc_auto_assign_id(QemuOptsList
*olist
, QemuOpts
*opts
)
3873 id
= g_strdup("default");
3874 while (qemu_opts_find(olist
, id
)) {
3876 id
= g_strdup_printf("vnc%d", i
++);
3878 qemu_opts_set_id(opts
, id
);
3881 QemuOpts
*vnc_parse(const char *str
, Error
**errp
)
3883 QemuOptsList
*olist
= qemu_find_opts("vnc");
3884 QemuOpts
*opts
= qemu_opts_parse(olist
, str
, true, errp
);
3891 id
= qemu_opts_id(opts
);
3893 /* auto-assign id if not present */
3894 vnc_auto_assign_id(olist
, opts
);
3899 int vnc_init_func(void *opaque
, QemuOpts
*opts
, Error
**errp
)
3901 Error
*local_err
= NULL
;
3902 char *id
= (char *)qemu_opts_id(opts
);
3905 vnc_display_init(id
);
3906 vnc_display_open(id
, &local_err
);
3907 if (local_err
!= NULL
) {
3908 error_reportf_err(local_err
, "Failed to start VNC server: ");
3914 static void vnc_register_config(void)
3916 qemu_add_opts(&qemu_vnc_opts
);
3918 opts_init(vnc_register_config
);