2 * QEMU VNC display driver
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
6 * Copyright (C) 2009 Red Hat, Inc
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 #include "qemu/osdep.h"
32 #include "sysemu/sysemu.h"
33 #include "qemu/error-report.h"
34 #include "qemu/sockets.h"
35 #include "qemu/timer.h"
37 #include "qemu/config-file.h"
38 #include "qapi/qmp/qerror.h"
39 #include "qapi/qmp/types.h"
40 #include "qmp-commands.h"
42 #include "qapi-event.h"
43 #include "crypto/hash.h"
44 #include "crypto/tlscredsanon.h"
45 #include "crypto/tlscredsx509.h"
46 #include "qom/object_interfaces.h"
47 #include "qemu/cutils.h"
49 #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
50 #define VNC_REFRESH_INTERVAL_INC 50
51 #define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
52 static const struct timeval VNC_REFRESH_STATS
= { 0, 500000 };
53 static const struct timeval VNC_REFRESH_LOSSY
= { 2, 0 };
55 #include "vnc_keysym.h"
56 #include "crypto/cipher.h"
58 static QTAILQ_HEAD(, VncDisplay
) vnc_displays
=
59 QTAILQ_HEAD_INITIALIZER(vnc_displays
);
61 static int vnc_cursor_define(VncState
*vs
);
62 static void vnc_release_modifiers(VncState
*vs
);
64 static void vnc_set_share_mode(VncState
*vs
, VncShareMode mode
)
67 static const char *mn
[] = {
69 [VNC_SHARE_MODE_CONNECTING
] = "connecting",
70 [VNC_SHARE_MODE_SHARED
] = "shared",
71 [VNC_SHARE_MODE_EXCLUSIVE
] = "exclusive",
72 [VNC_SHARE_MODE_DISCONNECTED
] = "disconnected",
74 fprintf(stderr
, "%s/%p: %s -> %s\n", __func__
,
75 vs
->ioc
, mn
[vs
->share_mode
], mn
[mode
]);
78 switch (vs
->share_mode
) {
79 case VNC_SHARE_MODE_CONNECTING
:
80 vs
->vd
->num_connecting
--;
82 case VNC_SHARE_MODE_SHARED
:
85 case VNC_SHARE_MODE_EXCLUSIVE
:
86 vs
->vd
->num_exclusive
--;
92 vs
->share_mode
= mode
;
94 switch (vs
->share_mode
) {
95 case VNC_SHARE_MODE_CONNECTING
:
96 vs
->vd
->num_connecting
++;
98 case VNC_SHARE_MODE_SHARED
:
101 case VNC_SHARE_MODE_EXCLUSIVE
:
102 vs
->vd
->num_exclusive
++;
110 static void vnc_init_basic_info(SocketAddress
*addr
,
114 switch (addr
->type
) {
115 case SOCKET_ADDRESS_KIND_INET
:
116 info
->host
= g_strdup(addr
->u
.inet
.data
->host
);
117 info
->service
= g_strdup(addr
->u
.inet
.data
->port
);
118 if (addr
->u
.inet
.data
->ipv6
) {
119 info
->family
= NETWORK_ADDRESS_FAMILY_IPV6
;
121 info
->family
= NETWORK_ADDRESS_FAMILY_IPV4
;
125 case SOCKET_ADDRESS_KIND_UNIX
:
126 info
->host
= g_strdup("");
127 info
->service
= g_strdup(addr
->u
.q_unix
.data
->path
);
128 info
->family
= NETWORK_ADDRESS_FAMILY_UNIX
;
132 error_setg(errp
, "Unsupported socket kind %d",
140 static void vnc_init_basic_info_from_server_addr(QIOChannelSocket
*ioc
,
144 SocketAddress
*addr
= NULL
;
147 error_setg(errp
, "No listener socket available");
151 addr
= qio_channel_socket_get_local_address(ioc
, errp
);
156 vnc_init_basic_info(addr
, info
, errp
);
157 qapi_free_SocketAddress(addr
);
160 static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket
*ioc
,
164 SocketAddress
*addr
= NULL
;
166 addr
= qio_channel_socket_get_remote_address(ioc
, errp
);
171 vnc_init_basic_info(addr
, info
, errp
);
172 qapi_free_SocketAddress(addr
);
175 static const char *vnc_auth_name(VncDisplay
*vd
) {
177 case VNC_AUTH_INVALID
:
193 case VNC_AUTH_VENCRYPT
:
194 switch (vd
->subauth
) {
195 case VNC_AUTH_VENCRYPT_PLAIN
:
196 return "vencrypt+plain";
197 case VNC_AUTH_VENCRYPT_TLSNONE
:
198 return "vencrypt+tls+none";
199 case VNC_AUTH_VENCRYPT_TLSVNC
:
200 return "vencrypt+tls+vnc";
201 case VNC_AUTH_VENCRYPT_TLSPLAIN
:
202 return "vencrypt+tls+plain";
203 case VNC_AUTH_VENCRYPT_X509NONE
:
204 return "vencrypt+x509+none";
205 case VNC_AUTH_VENCRYPT_X509VNC
:
206 return "vencrypt+x509+vnc";
207 case VNC_AUTH_VENCRYPT_X509PLAIN
:
208 return "vencrypt+x509+plain";
209 case VNC_AUTH_VENCRYPT_TLSSASL
:
210 return "vencrypt+tls+sasl";
211 case VNC_AUTH_VENCRYPT_X509SASL
:
212 return "vencrypt+x509+sasl";
222 static VncServerInfo
*vnc_server_info_get(VncDisplay
*vd
)
227 info
= g_malloc0(sizeof(*info
));
228 vnc_init_basic_info_from_server_addr(vd
->lsock
,
229 qapi_VncServerInfo_base(info
), &err
);
230 info
->has_auth
= true;
231 info
->auth
= g_strdup(vnc_auth_name(vd
));
233 qapi_free_VncServerInfo(info
);
240 static void vnc_client_cache_auth(VncState
*client
)
247 client
->info
->x509_dname
=
248 qcrypto_tls_session_get_peer_name(client
->tls
);
249 client
->info
->has_x509_dname
=
250 client
->info
->x509_dname
!= NULL
;
252 #ifdef CONFIG_VNC_SASL
253 if (client
->sasl
.conn
&&
254 client
->sasl
.username
) {
255 client
->info
->has_sasl_username
= true;
256 client
->info
->sasl_username
= g_strdup(client
->sasl
.username
);
261 static void vnc_client_cache_addr(VncState
*client
)
265 client
->info
= g_malloc0(sizeof(*client
->info
));
266 vnc_init_basic_info_from_remote_addr(client
->sioc
,
267 qapi_VncClientInfo_base(client
->info
),
270 qapi_free_VncClientInfo(client
->info
);
276 static void vnc_qmp_event(VncState
*vs
, QAPIEvent event
)
284 si
= vnc_server_info_get(vs
->vd
);
290 case QAPI_EVENT_VNC_CONNECTED
:
291 qapi_event_send_vnc_connected(si
, qapi_VncClientInfo_base(vs
->info
),
294 case QAPI_EVENT_VNC_INITIALIZED
:
295 qapi_event_send_vnc_initialized(si
, vs
->info
, &error_abort
);
297 case QAPI_EVENT_VNC_DISCONNECTED
:
298 qapi_event_send_vnc_disconnected(si
, vs
->info
, &error_abort
);
304 qapi_free_VncServerInfo(si
);
307 static VncClientInfo
*qmp_query_vnc_client(const VncState
*client
)
312 info
= g_malloc0(sizeof(*info
));
314 vnc_init_basic_info_from_remote_addr(client
->sioc
,
315 qapi_VncClientInfo_base(info
),
319 qapi_free_VncClientInfo(info
);
323 info
->websocket
= client
->websocket
;
326 info
->x509_dname
= qcrypto_tls_session_get_peer_name(client
->tls
);
327 info
->has_x509_dname
= info
->x509_dname
!= NULL
;
329 #ifdef CONFIG_VNC_SASL
330 if (client
->sasl
.conn
&& client
->sasl
.username
) {
331 info
->has_sasl_username
= true;
332 info
->sasl_username
= g_strdup(client
->sasl
.username
);
339 static VncDisplay
*vnc_display_find(const char *id
)
344 return QTAILQ_FIRST(&vnc_displays
);
346 QTAILQ_FOREACH(vd
, &vnc_displays
, next
) {
347 if (strcmp(id
, vd
->id
) == 0) {
354 static VncClientInfoList
*qmp_query_client_list(VncDisplay
*vd
)
356 VncClientInfoList
*cinfo
, *prev
= NULL
;
359 QTAILQ_FOREACH(client
, &vd
->clients
, next
) {
360 cinfo
= g_new0(VncClientInfoList
, 1);
361 cinfo
->value
= qmp_query_vnc_client(client
);
368 VncInfo
*qmp_query_vnc(Error
**errp
)
370 VncInfo
*info
= g_malloc0(sizeof(*info
));
371 VncDisplay
*vd
= vnc_display_find(NULL
);
372 SocketAddress
*addr
= NULL
;
374 if (vd
== NULL
|| !vd
->enabled
) {
375 info
->enabled
= false;
377 info
->enabled
= true;
379 /* for compatibility with the original command */
380 info
->has_clients
= true;
381 info
->clients
= qmp_query_client_list(vd
);
383 if (vd
->lsock
== NULL
) {
387 addr
= qio_channel_socket_get_local_address(vd
->lsock
, errp
);
392 switch (addr
->type
) {
393 case SOCKET_ADDRESS_KIND_INET
:
394 info
->host
= g_strdup(addr
->u
.inet
.data
->host
);
395 info
->service
= g_strdup(addr
->u
.inet
.data
->port
);
396 if (addr
->u
.inet
.data
->ipv6
) {
397 info
->family
= NETWORK_ADDRESS_FAMILY_IPV6
;
399 info
->family
= NETWORK_ADDRESS_FAMILY_IPV4
;
403 case SOCKET_ADDRESS_KIND_UNIX
:
404 info
->host
= g_strdup("");
405 info
->service
= g_strdup(addr
->u
.q_unix
.data
->path
);
406 info
->family
= NETWORK_ADDRESS_FAMILY_UNIX
;
410 error_setg(errp
, "Unsupported socket kind %d",
415 info
->has_host
= true;
416 info
->has_service
= true;
417 info
->has_family
= true;
419 info
->has_auth
= true;
420 info
->auth
= g_strdup(vnc_auth_name(vd
));
423 qapi_free_SocketAddress(addr
);
427 qapi_free_SocketAddress(addr
);
428 qapi_free_VncInfo(info
);
432 static VncBasicInfoList
*qmp_query_server_entry(QIOChannelSocket
*ioc
,
434 VncBasicInfoList
*prev
)
436 VncBasicInfoList
*list
;
441 addr
= qio_channel_socket_get_local_address(ioc
, &err
);
447 info
= g_new0(VncBasicInfo
, 1);
448 vnc_init_basic_info(addr
, info
, &err
);
449 qapi_free_SocketAddress(addr
);
451 qapi_free_VncBasicInfo(info
);
455 info
->websocket
= websocket
;
457 list
= g_new0(VncBasicInfoList
, 1);
463 static void qmp_query_auth(VncDisplay
*vd
, VncInfo2
*info
)
467 info
->auth
= VNC_PRIMARY_AUTH_VNC
;
470 info
->auth
= VNC_PRIMARY_AUTH_RA2
;
473 info
->auth
= VNC_PRIMARY_AUTH_RA2NE
;
476 info
->auth
= VNC_PRIMARY_AUTH_TIGHT
;
479 info
->auth
= VNC_PRIMARY_AUTH_ULTRA
;
482 info
->auth
= VNC_PRIMARY_AUTH_TLS
;
484 case VNC_AUTH_VENCRYPT
:
485 info
->auth
= VNC_PRIMARY_AUTH_VENCRYPT
;
486 info
->has_vencrypt
= true;
487 switch (vd
->subauth
) {
488 case VNC_AUTH_VENCRYPT_PLAIN
:
489 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_PLAIN
;
491 case VNC_AUTH_VENCRYPT_TLSNONE
:
492 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_NONE
;
494 case VNC_AUTH_VENCRYPT_TLSVNC
:
495 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_VNC
;
497 case VNC_AUTH_VENCRYPT_TLSPLAIN
:
498 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN
;
500 case VNC_AUTH_VENCRYPT_X509NONE
:
501 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_NONE
;
503 case VNC_AUTH_VENCRYPT_X509VNC
:
504 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_VNC
;
506 case VNC_AUTH_VENCRYPT_X509PLAIN
:
507 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_PLAIN
;
509 case VNC_AUTH_VENCRYPT_TLSSASL
:
510 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_SASL
;
512 case VNC_AUTH_VENCRYPT_X509SASL
:
513 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_SASL
;
516 info
->has_vencrypt
= false;
521 info
->auth
= VNC_PRIMARY_AUTH_SASL
;
525 info
->auth
= VNC_PRIMARY_AUTH_NONE
;
530 VncInfo2List
*qmp_query_vnc_servers(Error
**errp
)
532 VncInfo2List
*item
, *prev
= NULL
;
537 QTAILQ_FOREACH(vd
, &vnc_displays
, next
) {
538 info
= g_new0(VncInfo2
, 1);
539 info
->id
= g_strdup(vd
->id
);
540 info
->clients
= qmp_query_client_list(vd
);
541 qmp_query_auth(vd
, info
);
543 dev
= DEVICE(object_property_get_link(OBJECT(vd
->dcl
.con
),
545 info
->has_display
= true;
546 info
->display
= g_strdup(dev
->id
);
548 if (vd
->lsock
!= NULL
) {
549 info
->server
= qmp_query_server_entry(
550 vd
->lsock
, false, info
->server
);
552 if (vd
->lwebsock
!= NULL
) {
553 info
->server
= qmp_query_server_entry(
554 vd
->lwebsock
, true, info
->server
);
557 item
= g_new0(VncInfo2List
, 1);
566 1) Get the queue working for IO.
567 2) there is some weirdness when using the -S option (the screen is grey
568 and not totally invalidated
569 3) resolutions > 1024
572 static int vnc_update_client(VncState
*vs
, int has_dirty
, bool sync
);
573 static void vnc_disconnect_start(VncState
*vs
);
575 static void vnc_colordepth(VncState
*vs
);
576 static void framebuffer_update_request(VncState
*vs
, int incremental
,
577 int x_position
, int y_position
,
579 static void vnc_refresh(DisplayChangeListener
*dcl
);
580 static int vnc_refresh_server_surface(VncDisplay
*vd
);
582 static int vnc_width(VncDisplay
*vd
)
584 return MIN(VNC_MAX_WIDTH
, ROUND_UP(surface_width(vd
->ds
),
585 VNC_DIRTY_PIXELS_PER_BIT
));
588 static int vnc_height(VncDisplay
*vd
)
590 return MIN(VNC_MAX_HEIGHT
, surface_height(vd
->ds
));
593 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty
[VNC_MAX_HEIGHT
],
594 VNC_MAX_WIDTH
/ VNC_DIRTY_PIXELS_PER_BIT
),
596 int x
, int y
, int w
, int h
)
598 int width
= vnc_width(vd
);
599 int height
= vnc_height(vd
);
601 /* this is needed this to ensure we updated all affected
602 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
603 w
+= (x
% VNC_DIRTY_PIXELS_PER_BIT
);
604 x
-= (x
% VNC_DIRTY_PIXELS_PER_BIT
);
608 w
= MIN(x
+ w
, width
) - x
;
609 h
= MIN(y
+ h
, height
);
612 bitmap_set(dirty
[y
], x
/ VNC_DIRTY_PIXELS_PER_BIT
,
613 DIV_ROUND_UP(w
, VNC_DIRTY_PIXELS_PER_BIT
));
617 static void vnc_dpy_update(DisplayChangeListener
*dcl
,
618 int x
, int y
, int w
, int h
)
620 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
621 struct VncSurface
*s
= &vd
->guest
;
623 vnc_set_area_dirty(s
->dirty
, vd
, x
, y
, w
, h
);
626 void vnc_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
,
629 vnc_write_u16(vs
, x
);
630 vnc_write_u16(vs
, y
);
631 vnc_write_u16(vs
, w
);
632 vnc_write_u16(vs
, h
);
634 vnc_write_s32(vs
, encoding
);
638 static void vnc_desktop_resize(VncState
*vs
)
640 if (vs
->ioc
== NULL
|| !vnc_has_feature(vs
, VNC_FEATURE_RESIZE
)) {
643 if (vs
->client_width
== pixman_image_get_width(vs
->vd
->server
) &&
644 vs
->client_height
== pixman_image_get_height(vs
->vd
->server
)) {
647 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
648 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
650 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
652 vnc_write_u16(vs
, 1); /* number of rects */
653 vnc_framebuffer_update(vs
, 0, 0, vs
->client_width
, vs
->client_height
,
654 VNC_ENCODING_DESKTOPRESIZE
);
655 vnc_unlock_output(vs
);
659 static void vnc_abort_display_jobs(VncDisplay
*vd
)
663 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
666 vnc_unlock_output(vs
);
668 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
671 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
674 vnc_unlock_output(vs
);
678 int vnc_server_fb_stride(VncDisplay
*vd
)
680 return pixman_image_get_stride(vd
->server
);
683 void *vnc_server_fb_ptr(VncDisplay
*vd
, int x
, int y
)
687 ptr
= (uint8_t *)pixman_image_get_data(vd
->server
);
688 ptr
+= y
* vnc_server_fb_stride(vd
);
689 ptr
+= x
* VNC_SERVER_FB_BYTES
;
693 static void vnc_update_server_surface(VncDisplay
*vd
)
695 qemu_pixman_image_unref(vd
->server
);
698 if (QTAILQ_EMPTY(&vd
->clients
)) {
702 vd
->server
= pixman_image_create_bits(VNC_SERVER_FB_FORMAT
,
708 static void vnc_dpy_switch(DisplayChangeListener
*dcl
,
709 DisplaySurface
*surface
)
711 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
715 vnc_abort_display_jobs(vd
);
719 vnc_update_server_surface(vd
);
722 qemu_pixman_image_unref(vd
->guest
.fb
);
723 vd
->guest
.fb
= pixman_image_ref(surface
->image
);
724 vd
->guest
.format
= surface
->format
;
725 width
= vnc_width(vd
);
726 height
= vnc_height(vd
);
727 memset(vd
->guest
.dirty
, 0x00, sizeof(vd
->guest
.dirty
));
728 vnc_set_area_dirty(vd
->guest
.dirty
, vd
, 0, 0,
731 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
733 vnc_desktop_resize(vs
);
734 if (vs
->vd
->cursor
) {
735 vnc_cursor_define(vs
);
737 memset(vs
->dirty
, 0x00, sizeof(vs
->dirty
));
738 vnc_set_area_dirty(vs
->dirty
, vd
, 0, 0,
744 static void vnc_write_pixels_copy(VncState
*vs
,
745 void *pixels
, int size
)
747 vnc_write(vs
, pixels
, size
);
750 /* slowest but generic code. */
751 void vnc_convert_pixel(VncState
*vs
, uint8_t *buf
, uint32_t v
)
755 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
756 r
= (((v
& 0x00ff0000) >> 16) << vs
->client_pf
.rbits
) >> 8;
757 g
= (((v
& 0x0000ff00) >> 8) << vs
->client_pf
.gbits
) >> 8;
758 b
= (((v
& 0x000000ff) >> 0) << vs
->client_pf
.bbits
) >> 8;
760 # error need some bits here if you change VNC_SERVER_FB_FORMAT
762 v
= (r
<< vs
->client_pf
.rshift
) |
763 (g
<< vs
->client_pf
.gshift
) |
764 (b
<< vs
->client_pf
.bshift
);
765 switch (vs
->client_pf
.bytes_per_pixel
) {
795 static void vnc_write_pixels_generic(VncState
*vs
,
796 void *pixels1
, int size
)
800 if (VNC_SERVER_FB_BYTES
== 4) {
801 uint32_t *pixels
= pixels1
;
804 for (i
= 0; i
< n
; i
++) {
805 vnc_convert_pixel(vs
, buf
, pixels
[i
]);
806 vnc_write(vs
, buf
, vs
->client_pf
.bytes_per_pixel
);
811 int vnc_raw_send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
815 VncDisplay
*vd
= vs
->vd
;
817 row
= vnc_server_fb_ptr(vd
, x
, y
);
818 for (i
= 0; i
< h
; i
++) {
819 vs
->write_pixels(vs
, row
, w
* VNC_SERVER_FB_BYTES
);
820 row
+= vnc_server_fb_stride(vd
);
825 int vnc_send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
828 bool encode_raw
= false;
829 size_t saved_offs
= vs
->output
.offset
;
831 switch(vs
->vnc_encoding
) {
832 case VNC_ENCODING_ZLIB
:
833 n
= vnc_zlib_send_framebuffer_update(vs
, x
, y
, w
, h
);
835 case VNC_ENCODING_HEXTILE
:
836 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_HEXTILE
);
837 n
= vnc_hextile_send_framebuffer_update(vs
, x
, y
, w
, h
);
839 case VNC_ENCODING_TIGHT
:
840 n
= vnc_tight_send_framebuffer_update(vs
, x
, y
, w
, h
);
842 case VNC_ENCODING_TIGHT_PNG
:
843 n
= vnc_tight_png_send_framebuffer_update(vs
, x
, y
, w
, h
);
845 case VNC_ENCODING_ZRLE
:
846 n
= vnc_zrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
848 case VNC_ENCODING_ZYWRLE
:
849 n
= vnc_zywrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
856 /* If the client has the same pixel format as our internal buffer and
857 * a RAW encoding would need less space fall back to RAW encoding to
858 * save bandwidth and processing power in the client. */
859 if (!encode_raw
&& vs
->write_pixels
== vnc_write_pixels_copy
&&
860 12 + h
* w
* VNC_SERVER_FB_BYTES
<= (vs
->output
.offset
- saved_offs
)) {
861 vs
->output
.offset
= saved_offs
;
866 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_RAW
);
867 n
= vnc_raw_send_framebuffer_update(vs
, x
, y
, w
, h
);
873 static void vnc_copy(VncState
*vs
, int src_x
, int src_y
, int dst_x
, int dst_y
, int w
, int h
)
875 /* send bitblit op to the vnc client */
877 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
879 vnc_write_u16(vs
, 1); /* number of rects */
880 vnc_framebuffer_update(vs
, dst_x
, dst_y
, w
, h
, VNC_ENCODING_COPYRECT
);
881 vnc_write_u16(vs
, src_x
);
882 vnc_write_u16(vs
, src_y
);
883 vnc_unlock_output(vs
);
887 static void vnc_dpy_copy(DisplayChangeListener
*dcl
,
888 int src_x
, int src_y
,
889 int dst_x
, int dst_y
, int w
, int h
)
891 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
895 int i
, x
, y
, pitch
, inc
, w_lim
, s
;
899 /* no client connected */
903 vnc_refresh_server_surface(vd
);
904 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
905 if (vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
906 vs
->force_update
= 1;
907 vnc_update_client(vs
, 1, true);
908 /* vs might be free()ed here */
912 /* do bitblit op on the local surface too */
913 pitch
= vnc_server_fb_stride(vd
);
914 src_row
= vnc_server_fb_ptr(vd
, src_x
, src_y
);
915 dst_row
= vnc_server_fb_ptr(vd
, dst_x
, dst_y
);
920 src_row
+= pitch
* (h
-1);
921 dst_row
+= pitch
* (h
-1);
926 w_lim
= w
- (VNC_DIRTY_PIXELS_PER_BIT
- (dst_x
% VNC_DIRTY_PIXELS_PER_BIT
));
930 w_lim
= w
- (w_lim
% VNC_DIRTY_PIXELS_PER_BIT
);
932 for (i
= 0; i
< h
; i
++) {
933 for (x
= 0; x
<= w_lim
;
934 x
+= s
, src_row
+= cmp_bytes
, dst_row
+= cmp_bytes
) {
936 if ((s
= w
- w_lim
) == 0)
939 s
= (VNC_DIRTY_PIXELS_PER_BIT
-
940 (dst_x
% VNC_DIRTY_PIXELS_PER_BIT
));
943 s
= VNC_DIRTY_PIXELS_PER_BIT
;
945 cmp_bytes
= s
* VNC_SERVER_FB_BYTES
;
946 if (memcmp(src_row
, dst_row
, cmp_bytes
) == 0)
948 memmove(dst_row
, src_row
, cmp_bytes
);
949 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
950 if (!vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
951 set_bit(((x
+ dst_x
) / VNC_DIRTY_PIXELS_PER_BIT
),
956 src_row
+= pitch
- w
* VNC_SERVER_FB_BYTES
;
957 dst_row
+= pitch
- w
* VNC_SERVER_FB_BYTES
;
961 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
962 if (vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
963 vnc_copy(vs
, src_x
, src_y
, dst_x
, dst_y
, w
, h
);
968 static void vnc_mouse_set(DisplayChangeListener
*dcl
,
969 int x
, int y
, int visible
)
971 /* can we ask the client(s) to move the pointer ??? */
974 static int vnc_cursor_define(VncState
*vs
)
976 QEMUCursor
*c
= vs
->vd
->cursor
;
979 if (vnc_has_feature(vs
, VNC_FEATURE_RICH_CURSOR
)) {
981 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
982 vnc_write_u8(vs
, 0); /* padding */
983 vnc_write_u16(vs
, 1); /* # of rects */
984 vnc_framebuffer_update(vs
, c
->hot_x
, c
->hot_y
, c
->width
, c
->height
,
985 VNC_ENCODING_RICH_CURSOR
);
986 isize
= c
->width
* c
->height
* vs
->client_pf
.bytes_per_pixel
;
987 vnc_write_pixels_generic(vs
, c
->data
, isize
);
988 vnc_write(vs
, vs
->vd
->cursor_mask
, vs
->vd
->cursor_msize
);
989 vnc_unlock_output(vs
);
995 static void vnc_dpy_cursor_define(DisplayChangeListener
*dcl
,
998 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
1001 cursor_put(vd
->cursor
);
1002 g_free(vd
->cursor_mask
);
1005 cursor_get(vd
->cursor
);
1006 vd
->cursor_msize
= cursor_get_mono_bpl(c
) * c
->height
;
1007 vd
->cursor_mask
= g_malloc0(vd
->cursor_msize
);
1008 cursor_get_mono_mask(c
, 0, vd
->cursor_mask
);
1010 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
1011 vnc_cursor_define(vs
);
1015 static int find_and_clear_dirty_height(VncState
*vs
,
1016 int y
, int last_x
, int x
, int height
)
1020 for (h
= 1; h
< (height
- y
); h
++) {
1021 if (!test_bit(last_x
, vs
->dirty
[y
+ h
])) {
1024 bitmap_clear(vs
->dirty
[y
+ h
], last_x
, x
- last_x
);
1030 static int vnc_update_client(VncState
*vs
, int has_dirty
, bool sync
)
1032 if (vs
->disconnecting
) {
1033 vnc_disconnect_finish(vs
);
1037 vs
->has_dirty
+= has_dirty
;
1038 if (vs
->need_update
&& !vs
->disconnecting
) {
1039 VncDisplay
*vd
= vs
->vd
;
1045 if (vs
->output
.offset
&& !vs
->audio_cap
&& !vs
->force_update
)
1046 /* kernel send buffers are full -> drop frames to throttle */
1049 if (!vs
->has_dirty
&& !vs
->audio_cap
&& !vs
->force_update
)
1053 * Send screen updates to the vnc client using the server
1054 * surface and server dirty map. guest surface updates
1055 * happening in parallel don't disturb us, the next pass will
1056 * send them to the client.
1058 job
= vnc_job_new(vs
);
1060 height
= pixman_image_get_height(vd
->server
);
1061 width
= pixman_image_get_width(vd
->server
);
1067 unsigned long offset
= find_next_bit((unsigned long *) &vs
->dirty
,
1068 height
* VNC_DIRTY_BPL(vs
),
1069 y
* VNC_DIRTY_BPL(vs
));
1070 if (offset
== height
* VNC_DIRTY_BPL(vs
)) {
1071 /* no more dirty bits */
1074 y
= offset
/ VNC_DIRTY_BPL(vs
);
1075 x
= offset
% VNC_DIRTY_BPL(vs
);
1076 x2
= find_next_zero_bit((unsigned long *) &vs
->dirty
[y
],
1077 VNC_DIRTY_BPL(vs
), x
);
1078 bitmap_clear(vs
->dirty
[y
], x
, x2
- x
);
1079 h
= find_and_clear_dirty_height(vs
, y
, x
, x2
, height
);
1080 x2
= MIN(x2
, width
/ VNC_DIRTY_PIXELS_PER_BIT
);
1082 n
+= vnc_job_add_rect(job
, x
* VNC_DIRTY_PIXELS_PER_BIT
, y
,
1083 (x2
- x
) * VNC_DIRTY_PIXELS_PER_BIT
, h
);
1085 if (!x
&& x2
== width
/ VNC_DIRTY_PIXELS_PER_BIT
) {
1097 vs
->force_update
= 0;
1102 if (vs
->disconnecting
) {
1103 vnc_disconnect_finish(vs
);
1112 static void audio_capture_notify(void *opaque
, audcnotification_e cmd
)
1114 VncState
*vs
= opaque
;
1117 case AUD_CNOTIFY_DISABLE
:
1118 vnc_lock_output(vs
);
1119 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1120 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1121 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_END
);
1122 vnc_unlock_output(vs
);
1126 case AUD_CNOTIFY_ENABLE
:
1127 vnc_lock_output(vs
);
1128 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1129 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1130 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN
);
1131 vnc_unlock_output(vs
);
1137 static void audio_capture_destroy(void *opaque
)
1141 static void audio_capture(void *opaque
, void *buf
, int size
)
1143 VncState
*vs
= opaque
;
1145 vnc_lock_output(vs
);
1146 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1147 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1148 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_DATA
);
1149 vnc_write_u32(vs
, size
);
1150 vnc_write(vs
, buf
, size
);
1151 vnc_unlock_output(vs
);
1155 static void audio_add(VncState
*vs
)
1157 struct audio_capture_ops ops
;
1159 if (vs
->audio_cap
) {
1160 error_report("audio already running");
1164 ops
.notify
= audio_capture_notify
;
1165 ops
.destroy
= audio_capture_destroy
;
1166 ops
.capture
= audio_capture
;
1168 vs
->audio_cap
= AUD_add_capture(&vs
->as
, &ops
, vs
);
1169 if (!vs
->audio_cap
) {
1170 error_report("Failed to add audio capture");
1174 static void audio_del(VncState
*vs
)
1176 if (vs
->audio_cap
) {
1177 AUD_del_capture(vs
->audio_cap
, vs
);
1178 vs
->audio_cap
= NULL
;
1182 static void vnc_disconnect_start(VncState
*vs
)
1184 if (vs
->disconnecting
) {
1187 vnc_set_share_mode(vs
, VNC_SHARE_MODE_DISCONNECTED
);
1189 g_source_remove(vs
->ioc_tag
);
1191 qio_channel_close(vs
->ioc
, NULL
);
1192 vs
->disconnecting
= TRUE
;
1195 void vnc_disconnect_finish(VncState
*vs
)
1199 vnc_jobs_join(vs
); /* Wait encoding jobs */
1201 vnc_lock_output(vs
);
1202 vnc_qmp_event(vs
, QAPI_EVENT_VNC_DISCONNECTED
);
1204 buffer_free(&vs
->input
);
1205 buffer_free(&vs
->output
);
1207 qapi_free_VncClientInfo(vs
->info
);
1210 vnc_tight_clear(vs
);
1213 #ifdef CONFIG_VNC_SASL
1214 vnc_sasl_client_cleanup(vs
);
1215 #endif /* CONFIG_VNC_SASL */
1217 vnc_release_modifiers(vs
);
1219 if (vs
->initialized
) {
1220 QTAILQ_REMOVE(&vs
->vd
->clients
, vs
, next
);
1221 qemu_remove_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
1222 if (QTAILQ_EMPTY(&vs
->vd
->clients
)) {
1223 /* last client gone */
1224 vnc_update_server_surface(vs
->vd
);
1228 if (vs
->vd
->lock_key_sync
)
1229 qemu_remove_led_event_handler(vs
->led
);
1230 vnc_unlock_output(vs
);
1232 qemu_mutex_destroy(&vs
->output_mutex
);
1233 if (vs
->bh
!= NULL
) {
1234 qemu_bh_delete(vs
->bh
);
1236 buffer_free(&vs
->jobs_buffer
);
1238 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
1239 g_free(vs
->lossy_rect
[i
]);
1241 g_free(vs
->lossy_rect
);
1243 object_unref(OBJECT(vs
->ioc
));
1245 object_unref(OBJECT(vs
->sioc
));
1250 ssize_t
vnc_client_io_error(VncState
*vs
, ssize_t ret
, Error
**errp
)
1254 VNC_DEBUG("Closing down client sock: EOF\n");
1255 } else if (ret
!= QIO_CHANNEL_ERR_BLOCK
) {
1256 VNC_DEBUG("Closing down client sock: ret %d (%s)\n",
1257 ret
, errp
? error_get_pretty(*errp
) : "Unknown");
1260 vnc_disconnect_start(vs
);
1271 void vnc_client_error(VncState
*vs
)
1273 VNC_DEBUG("Closing down client sock: protocol error\n");
1274 vnc_disconnect_start(vs
);
1279 * Called to write a chunk of data to the client socket. The data may
1280 * be the raw data, or may have already been encoded by SASL.
1281 * The data will be written either straight onto the socket, or
1282 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1284 * NB, it is theoretically possible to have 2 layers of encryption,
1285 * both SASL, and this TLS layer. It is highly unlikely in practice
1286 * though, since SASL encryption will typically be a no-op if TLS
1289 * Returns the number of bytes written, which may be less than
1290 * the requested 'datalen' if the socket would block. Returns
1291 * -1 on error, and disconnects the client socket.
1293 ssize_t
vnc_client_write_buf(VncState
*vs
, const uint8_t *data
, size_t datalen
)
1297 ret
= qio_channel_write(
1298 vs
->ioc
, (const char *)data
, datalen
, &err
);
1299 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data
, datalen
, ret
);
1300 return vnc_client_io_error(vs
, ret
, &err
);
1305 * Called to write buffered data to the client socket, when not
1306 * using any SASL SSF encryption layers. Will write as much data
1307 * as possible without blocking. If all buffered data is written,
1308 * will switch the FD poll() handler back to read monitoring.
1310 * Returns the number of bytes written, which may be less than
1311 * the buffered output data if the socket would block. Returns
1312 * -1 on error, and disconnects the client socket.
1314 static ssize_t
vnc_client_write_plain(VncState
*vs
)
1318 #ifdef CONFIG_VNC_SASL
1319 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1320 vs
->output
.buffer
, vs
->output
.capacity
, vs
->output
.offset
,
1321 vs
->sasl
.waitWriteSSF
);
1323 if (vs
->sasl
.conn
&&
1325 vs
->sasl
.waitWriteSSF
) {
1326 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->sasl
.waitWriteSSF
);
1328 vs
->sasl
.waitWriteSSF
-= ret
;
1330 #endif /* CONFIG_VNC_SASL */
1331 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->output
.offset
);
1335 buffer_advance(&vs
->output
, ret
);
1337 if (vs
->output
.offset
== 0) {
1339 g_source_remove(vs
->ioc_tag
);
1341 vs
->ioc_tag
= qio_channel_add_watch(
1342 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1350 * First function called whenever there is data to be written to
1351 * the client socket. Will delegate actual work according to whether
1352 * SASL SSF layers are enabled (thus requiring encryption calls)
1354 static void vnc_client_write_locked(VncState
*vs
)
1356 #ifdef CONFIG_VNC_SASL
1357 if (vs
->sasl
.conn
&&
1359 !vs
->sasl
.waitWriteSSF
) {
1360 vnc_client_write_sasl(vs
);
1362 #endif /* CONFIG_VNC_SASL */
1364 vnc_client_write_plain(vs
);
1368 static void vnc_client_write(VncState
*vs
)
1371 vnc_lock_output(vs
);
1372 if (vs
->output
.offset
) {
1373 vnc_client_write_locked(vs
);
1374 } else if (vs
->ioc
!= NULL
) {
1376 g_source_remove(vs
->ioc_tag
);
1378 vs
->ioc_tag
= qio_channel_add_watch(
1379 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1381 vnc_unlock_output(vs
);
1384 void vnc_read_when(VncState
*vs
, VncReadEvent
*func
, size_t expecting
)
1386 vs
->read_handler
= func
;
1387 vs
->read_handler_expect
= expecting
;
1392 * Called to read a chunk of data from the client socket. The data may
1393 * be the raw data, or may need to be further decoded by SASL.
1394 * The data will be read either straight from to the socket, or
1395 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1397 * NB, it is theoretically possible to have 2 layers of encryption,
1398 * both SASL, and this TLS layer. It is highly unlikely in practice
1399 * though, since SASL encryption will typically be a no-op if TLS
1402 * Returns the number of bytes read, which may be less than
1403 * the requested 'datalen' if the socket would block. Returns
1404 * -1 on error, and disconnects the client socket.
1406 ssize_t
vnc_client_read_buf(VncState
*vs
, uint8_t *data
, size_t datalen
)
1410 ret
= qio_channel_read(
1411 vs
->ioc
, (char *)data
, datalen
, &err
);
1412 VNC_DEBUG("Read wire %p %zd -> %ld\n", data
, datalen
, ret
);
1413 return vnc_client_io_error(vs
, ret
, &err
);
1418 * Called to read data from the client socket to the input buffer,
1419 * when not using any SASL SSF encryption layers. Will read as much
1420 * data as possible without blocking.
1422 * Returns the number of bytes read. Returns -1 on error, and
1423 * disconnects the client socket.
1425 static ssize_t
vnc_client_read_plain(VncState
*vs
)
1428 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1429 vs
->input
.buffer
, vs
->input
.capacity
, vs
->input
.offset
);
1430 buffer_reserve(&vs
->input
, 4096);
1431 ret
= vnc_client_read_buf(vs
, buffer_end(&vs
->input
), 4096);
1434 vs
->input
.offset
+= ret
;
1438 static void vnc_jobs_bh(void *opaque
)
1440 VncState
*vs
= opaque
;
1442 vnc_jobs_consume_buffer(vs
);
1446 * First function called whenever there is more data to be read from
1447 * the client socket. Will delegate actual work according to whether
1448 * SASL SSF layers are enabled (thus requiring decryption calls)
1449 * Returns 0 on success, -1 if client disconnected
1451 static int vnc_client_read(VncState
*vs
)
1455 #ifdef CONFIG_VNC_SASL
1456 if (vs
->sasl
.conn
&& vs
->sasl
.runSSF
)
1457 ret
= vnc_client_read_sasl(vs
);
1459 #endif /* CONFIG_VNC_SASL */
1460 ret
= vnc_client_read_plain(vs
);
1462 if (vs
->disconnecting
) {
1463 vnc_disconnect_finish(vs
);
1469 while (vs
->read_handler
&& vs
->input
.offset
>= vs
->read_handler_expect
) {
1470 size_t len
= vs
->read_handler_expect
;
1473 ret
= vs
->read_handler(vs
, vs
->input
.buffer
, len
);
1474 if (vs
->disconnecting
) {
1475 vnc_disconnect_finish(vs
);
1480 buffer_advance(&vs
->input
, len
);
1482 vs
->read_handler_expect
= ret
;
1488 gboolean
vnc_client_io(QIOChannel
*ioc G_GNUC_UNUSED
,
1489 GIOCondition condition
, void *opaque
)
1491 VncState
*vs
= opaque
;
1492 if (condition
& G_IO_IN
) {
1493 if (vnc_client_read(vs
) < 0) {
1497 if (condition
& G_IO_OUT
) {
1498 vnc_client_write(vs
);
1504 void vnc_write(VncState
*vs
, const void *data
, size_t len
)
1506 buffer_reserve(&vs
->output
, len
);
1508 if (vs
->ioc
!= NULL
&& buffer_empty(&vs
->output
)) {
1510 g_source_remove(vs
->ioc_tag
);
1512 vs
->ioc_tag
= qio_channel_add_watch(
1513 vs
->ioc
, G_IO_IN
| G_IO_OUT
, vnc_client_io
, vs
, NULL
);
1516 buffer_append(&vs
->output
, data
, len
);
1519 void vnc_write_s32(VncState
*vs
, int32_t value
)
1521 vnc_write_u32(vs
, *(uint32_t *)&value
);
1524 void vnc_write_u32(VncState
*vs
, uint32_t value
)
1528 buf
[0] = (value
>> 24) & 0xFF;
1529 buf
[1] = (value
>> 16) & 0xFF;
1530 buf
[2] = (value
>> 8) & 0xFF;
1531 buf
[3] = value
& 0xFF;
1533 vnc_write(vs
, buf
, 4);
1536 void vnc_write_u16(VncState
*vs
, uint16_t value
)
1540 buf
[0] = (value
>> 8) & 0xFF;
1541 buf
[1] = value
& 0xFF;
1543 vnc_write(vs
, buf
, 2);
1546 void vnc_write_u8(VncState
*vs
, uint8_t value
)
1548 vnc_write(vs
, (char *)&value
, 1);
1551 void vnc_flush(VncState
*vs
)
1553 vnc_lock_output(vs
);
1554 if (vs
->ioc
!= NULL
&& vs
->output
.offset
) {
1555 vnc_client_write_locked(vs
);
1557 vnc_unlock_output(vs
);
1560 static uint8_t read_u8(uint8_t *data
, size_t offset
)
1562 return data
[offset
];
1565 static uint16_t read_u16(uint8_t *data
, size_t offset
)
1567 return ((data
[offset
] & 0xFF) << 8) | (data
[offset
+ 1] & 0xFF);
1570 static int32_t read_s32(uint8_t *data
, size_t offset
)
1572 return (int32_t)((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1573 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1576 uint32_t read_u32(uint8_t *data
, size_t offset
)
1578 return ((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1579 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1582 static void client_cut_text(VncState
*vs
, size_t len
, uint8_t *text
)
1586 static void check_pointer_type_change(Notifier
*notifier
, void *data
)
1588 VncState
*vs
= container_of(notifier
, VncState
, mouse_mode_notifier
);
1589 int absolute
= qemu_input_is_absolute();
1591 if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
) && vs
->absolute
!= absolute
) {
1592 vnc_lock_output(vs
);
1593 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1594 vnc_write_u8(vs
, 0);
1595 vnc_write_u16(vs
, 1);
1596 vnc_framebuffer_update(vs
, absolute
, 0,
1597 pixman_image_get_width(vs
->vd
->server
),
1598 pixman_image_get_height(vs
->vd
->server
),
1599 VNC_ENCODING_POINTER_TYPE_CHANGE
);
1600 vnc_unlock_output(vs
);
1603 vs
->absolute
= absolute
;
1606 static void pointer_event(VncState
*vs
, int button_mask
, int x
, int y
)
1608 static uint32_t bmap
[INPUT_BUTTON__MAX
] = {
1609 [INPUT_BUTTON_LEFT
] = 0x01,
1610 [INPUT_BUTTON_MIDDLE
] = 0x02,
1611 [INPUT_BUTTON_RIGHT
] = 0x04,
1612 [INPUT_BUTTON_WHEEL_UP
] = 0x08,
1613 [INPUT_BUTTON_WHEEL_DOWN
] = 0x10,
1615 QemuConsole
*con
= vs
->vd
->dcl
.con
;
1616 int width
= pixman_image_get_width(vs
->vd
->server
);
1617 int height
= pixman_image_get_height(vs
->vd
->server
);
1619 if (vs
->last_bmask
!= button_mask
) {
1620 qemu_input_update_buttons(con
, bmap
, vs
->last_bmask
, button_mask
);
1621 vs
->last_bmask
= button_mask
;
1625 qemu_input_queue_abs(con
, INPUT_AXIS_X
, x
, width
);
1626 qemu_input_queue_abs(con
, INPUT_AXIS_Y
, y
, height
);
1627 } else if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
)) {
1628 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- 0x7FFF);
1629 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- 0x7FFF);
1631 if (vs
->last_x
!= -1) {
1632 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- vs
->last_x
);
1633 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- vs
->last_y
);
1638 qemu_input_event_sync();
1641 static void reset_keys(VncState
*vs
)
1644 for(i
= 0; i
< 256; i
++) {
1645 if (vs
->modifiers_state
[i
]) {
1646 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, i
, false);
1647 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1648 vs
->modifiers_state
[i
] = 0;
1653 static void press_key(VncState
*vs
, int keysym
)
1655 int keycode
= keysym2scancode(vs
->vd
->kbd_layout
, keysym
) & SCANCODE_KEYMASK
;
1656 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, true);
1657 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1658 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1659 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1662 static int current_led_state(VncState
*vs
)
1666 if (vs
->modifiers_state
[0x46]) {
1667 ledstate
|= QEMU_SCROLL_LOCK_LED
;
1669 if (vs
->modifiers_state
[0x45]) {
1670 ledstate
|= QEMU_NUM_LOCK_LED
;
1672 if (vs
->modifiers_state
[0x3a]) {
1673 ledstate
|= QEMU_CAPS_LOCK_LED
;
1679 static void vnc_led_state_change(VncState
*vs
)
1683 if (!vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
)) {
1687 ledstate
= current_led_state(vs
);
1688 vnc_lock_output(vs
);
1689 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1690 vnc_write_u8(vs
, 0);
1691 vnc_write_u16(vs
, 1);
1692 vnc_framebuffer_update(vs
, 0, 0, 1, 1, VNC_ENCODING_LED_STATE
);
1693 vnc_write_u8(vs
, ledstate
);
1694 vnc_unlock_output(vs
);
1698 static void kbd_leds(void *opaque
, int ledstate
)
1700 VncState
*vs
= opaque
;
1702 bool has_changed
= (ledstate
!= current_led_state(vs
));
1704 trace_vnc_key_guest_leds((ledstate
& QEMU_CAPS_LOCK_LED
),
1705 (ledstate
& QEMU_NUM_LOCK_LED
),
1706 (ledstate
& QEMU_SCROLL_LOCK_LED
));
1708 caps
= ledstate
& QEMU_CAPS_LOCK_LED
? 1 : 0;
1709 num
= ledstate
& QEMU_NUM_LOCK_LED
? 1 : 0;
1710 scr
= ledstate
& QEMU_SCROLL_LOCK_LED
? 1 : 0;
1712 if (vs
->modifiers_state
[0x3a] != caps
) {
1713 vs
->modifiers_state
[0x3a] = caps
;
1715 if (vs
->modifiers_state
[0x45] != num
) {
1716 vs
->modifiers_state
[0x45] = num
;
1718 if (vs
->modifiers_state
[0x46] != scr
) {
1719 vs
->modifiers_state
[0x46] = scr
;
1722 /* Sending the current led state message to the client */
1724 vnc_led_state_change(vs
);
1728 static void do_key_event(VncState
*vs
, int down
, int keycode
, int sym
)
1730 /* QEMU console switch */
1732 case 0x2a: /* Left Shift */
1733 case 0x36: /* Right Shift */
1734 case 0x1d: /* Left CTRL */
1735 case 0x9d: /* Right CTRL */
1736 case 0x38: /* Left ALT */
1737 case 0xb8: /* Right ALT */
1739 vs
->modifiers_state
[keycode
] = 1;
1741 vs
->modifiers_state
[keycode
] = 0;
1743 case 0x02 ... 0x0a: /* '1' to '9' keys */
1744 if (vs
->vd
->dcl
.con
== NULL
&&
1745 down
&& vs
->modifiers_state
[0x1d] && vs
->modifiers_state
[0x38]) {
1746 /* Reset the modifiers sent to the current console */
1748 console_select(keycode
- 0x02);
1752 case 0x3a: /* CapsLock */
1753 case 0x45: /* NumLock */
1755 vs
->modifiers_state
[keycode
] ^= 1;
1759 /* Turn off the lock state sync logic if the client support the led
1762 if (down
&& vs
->vd
->lock_key_sync
&&
1763 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1764 keycode_is_keypad(vs
->vd
->kbd_layout
, keycode
)) {
1765 /* If the numlock state needs to change then simulate an additional
1766 keypress before sending this one. This will happen if the user
1767 toggles numlock away from the VNC window.
1769 if (keysym_is_numlock(vs
->vd
->kbd_layout
, sym
& 0xFFFF)) {
1770 if (!vs
->modifiers_state
[0x45]) {
1771 trace_vnc_key_sync_numlock(true);
1772 vs
->modifiers_state
[0x45] = 1;
1773 press_key(vs
, 0xff7f);
1776 if (vs
->modifiers_state
[0x45]) {
1777 trace_vnc_key_sync_numlock(false);
1778 vs
->modifiers_state
[0x45] = 0;
1779 press_key(vs
, 0xff7f);
1784 if (down
&& vs
->vd
->lock_key_sync
&&
1785 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1786 ((sym
>= 'A' && sym
<= 'Z') || (sym
>= 'a' && sym
<= 'z'))) {
1787 /* If the capslock state needs to change then simulate an additional
1788 keypress before sending this one. This will happen if the user
1789 toggles capslock away from the VNC window.
1791 int uppercase
= !!(sym
>= 'A' && sym
<= 'Z');
1792 int shift
= !!(vs
->modifiers_state
[0x2a] | vs
->modifiers_state
[0x36]);
1793 int capslock
= !!(vs
->modifiers_state
[0x3a]);
1795 if (uppercase
== shift
) {
1796 trace_vnc_key_sync_capslock(false);
1797 vs
->modifiers_state
[0x3a] = 0;
1798 press_key(vs
, 0xffe5);
1801 if (uppercase
!= shift
) {
1802 trace_vnc_key_sync_capslock(true);
1803 vs
->modifiers_state
[0x3a] = 1;
1804 press_key(vs
, 0xffe5);
1809 if (qemu_console_is_graphic(NULL
)) {
1810 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, down
);
1811 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1813 bool numlock
= vs
->modifiers_state
[0x45];
1814 bool control
= (vs
->modifiers_state
[0x1d] ||
1815 vs
->modifiers_state
[0x9d]);
1816 /* QEMU console emulation */
1819 case 0x2a: /* Left Shift */
1820 case 0x36: /* Right Shift */
1821 case 0x1d: /* Left CTRL */
1822 case 0x9d: /* Right CTRL */
1823 case 0x38: /* Left ALT */
1824 case 0xb8: /* Right ALT */
1827 kbd_put_keysym(QEMU_KEY_UP
);
1830 kbd_put_keysym(QEMU_KEY_DOWN
);
1833 kbd_put_keysym(QEMU_KEY_LEFT
);
1836 kbd_put_keysym(QEMU_KEY_RIGHT
);
1839 kbd_put_keysym(QEMU_KEY_DELETE
);
1842 kbd_put_keysym(QEMU_KEY_HOME
);
1845 kbd_put_keysym(QEMU_KEY_END
);
1848 kbd_put_keysym(QEMU_KEY_PAGEUP
);
1851 kbd_put_keysym(QEMU_KEY_PAGEDOWN
);
1855 kbd_put_keysym(numlock
? '7' : QEMU_KEY_HOME
);
1858 kbd_put_keysym(numlock
? '8' : QEMU_KEY_UP
);
1861 kbd_put_keysym(numlock
? '9' : QEMU_KEY_PAGEUP
);
1864 kbd_put_keysym(numlock
? '4' : QEMU_KEY_LEFT
);
1867 kbd_put_keysym('5');
1870 kbd_put_keysym(numlock
? '6' : QEMU_KEY_RIGHT
);
1873 kbd_put_keysym(numlock
? '1' : QEMU_KEY_END
);
1876 kbd_put_keysym(numlock
? '2' : QEMU_KEY_DOWN
);
1879 kbd_put_keysym(numlock
? '3' : QEMU_KEY_PAGEDOWN
);
1882 kbd_put_keysym('0');
1885 kbd_put_keysym(numlock
? '.' : QEMU_KEY_DELETE
);
1889 kbd_put_keysym('/');
1892 kbd_put_keysym('*');
1895 kbd_put_keysym('-');
1898 kbd_put_keysym('+');
1901 kbd_put_keysym('\n');
1906 kbd_put_keysym(sym
& 0x1f);
1908 kbd_put_keysym(sym
);
1916 static void vnc_release_modifiers(VncState
*vs
)
1918 static const int keycodes
[] = {
1919 /* shift, control, alt keys, both left & right */
1920 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1924 if (!qemu_console_is_graphic(NULL
)) {
1927 for (i
= 0; i
< ARRAY_SIZE(keycodes
); i
++) {
1928 keycode
= keycodes
[i
];
1929 if (!vs
->modifiers_state
[keycode
]) {
1932 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1933 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1937 static const char *code2name(int keycode
)
1939 return QKeyCode_lookup
[qemu_input_key_number_to_qcode(keycode
)];
1942 static void key_event(VncState
*vs
, int down
, uint32_t sym
)
1947 if (lsym
>= 'A' && lsym
<= 'Z' && qemu_console_is_graphic(NULL
)) {
1948 lsym
= lsym
- 'A' + 'a';
1951 keycode
= keysym2scancode(vs
->vd
->kbd_layout
, lsym
& 0xFFFF) & SCANCODE_KEYMASK
;
1952 trace_vnc_key_event_map(down
, sym
, keycode
, code2name(keycode
));
1953 do_key_event(vs
, down
, keycode
, sym
);
1956 static void ext_key_event(VncState
*vs
, int down
,
1957 uint32_t sym
, uint16_t keycode
)
1959 /* if the user specifies a keyboard layout, always use it */
1960 if (keyboard_layout
) {
1961 key_event(vs
, down
, sym
);
1963 trace_vnc_key_event_ext(down
, sym
, keycode
, code2name(keycode
));
1964 do_key_event(vs
, down
, keycode
, sym
);
1968 static void framebuffer_update_request(VncState
*vs
, int incremental
,
1969 int x
, int y
, int w
, int h
)
1971 vs
->need_update
= 1;
1977 vs
->force_update
= 1;
1978 vnc_set_area_dirty(vs
->dirty
, vs
->vd
, x
, y
, w
, h
);
1981 static void send_ext_key_event_ack(VncState
*vs
)
1983 vnc_lock_output(vs
);
1984 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1985 vnc_write_u8(vs
, 0);
1986 vnc_write_u16(vs
, 1);
1987 vnc_framebuffer_update(vs
, 0, 0,
1988 pixman_image_get_width(vs
->vd
->server
),
1989 pixman_image_get_height(vs
->vd
->server
),
1990 VNC_ENCODING_EXT_KEY_EVENT
);
1991 vnc_unlock_output(vs
);
1995 static void send_ext_audio_ack(VncState
*vs
)
1997 vnc_lock_output(vs
);
1998 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1999 vnc_write_u8(vs
, 0);
2000 vnc_write_u16(vs
, 1);
2001 vnc_framebuffer_update(vs
, 0, 0,
2002 pixman_image_get_width(vs
->vd
->server
),
2003 pixman_image_get_height(vs
->vd
->server
),
2004 VNC_ENCODING_AUDIO
);
2005 vnc_unlock_output(vs
);
2009 static void set_encodings(VncState
*vs
, int32_t *encodings
, size_t n_encodings
)
2012 unsigned int enc
= 0;
2015 vs
->vnc_encoding
= 0;
2016 vs
->tight
.compression
= 9;
2017 vs
->tight
.quality
= -1; /* Lossless by default */
2021 * Start from the end because the encodings are sent in order of preference.
2022 * This way the preferred encoding (first encoding defined in the array)
2023 * will be set at the end of the loop.
2025 for (i
= n_encodings
- 1; i
>= 0; i
--) {
2028 case VNC_ENCODING_RAW
:
2029 vs
->vnc_encoding
= enc
;
2031 case VNC_ENCODING_COPYRECT
:
2032 vs
->features
|= VNC_FEATURE_COPYRECT_MASK
;
2034 case VNC_ENCODING_HEXTILE
:
2035 vs
->features
|= VNC_FEATURE_HEXTILE_MASK
;
2036 vs
->vnc_encoding
= enc
;
2038 case VNC_ENCODING_TIGHT
:
2039 vs
->features
|= VNC_FEATURE_TIGHT_MASK
;
2040 vs
->vnc_encoding
= enc
;
2042 #ifdef CONFIG_VNC_PNG
2043 case VNC_ENCODING_TIGHT_PNG
:
2044 vs
->features
|= VNC_FEATURE_TIGHT_PNG_MASK
;
2045 vs
->vnc_encoding
= enc
;
2048 case VNC_ENCODING_ZLIB
:
2049 vs
->features
|= VNC_FEATURE_ZLIB_MASK
;
2050 vs
->vnc_encoding
= enc
;
2052 case VNC_ENCODING_ZRLE
:
2053 vs
->features
|= VNC_FEATURE_ZRLE_MASK
;
2054 vs
->vnc_encoding
= enc
;
2056 case VNC_ENCODING_ZYWRLE
:
2057 vs
->features
|= VNC_FEATURE_ZYWRLE_MASK
;
2058 vs
->vnc_encoding
= enc
;
2060 case VNC_ENCODING_DESKTOPRESIZE
:
2061 vs
->features
|= VNC_FEATURE_RESIZE_MASK
;
2063 case VNC_ENCODING_POINTER_TYPE_CHANGE
:
2064 vs
->features
|= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK
;
2066 case VNC_ENCODING_RICH_CURSOR
:
2067 vs
->features
|= VNC_FEATURE_RICH_CURSOR_MASK
;
2068 if (vs
->vd
->cursor
) {
2069 vnc_cursor_define(vs
);
2072 case VNC_ENCODING_EXT_KEY_EVENT
:
2073 send_ext_key_event_ack(vs
);
2075 case VNC_ENCODING_AUDIO
:
2076 send_ext_audio_ack(vs
);
2078 case VNC_ENCODING_WMVi
:
2079 vs
->features
|= VNC_FEATURE_WMVI_MASK
;
2081 case VNC_ENCODING_LED_STATE
:
2082 vs
->features
|= VNC_FEATURE_LED_STATE_MASK
;
2084 case VNC_ENCODING_COMPRESSLEVEL0
... VNC_ENCODING_COMPRESSLEVEL0
+ 9:
2085 vs
->tight
.compression
= (enc
& 0x0F);
2087 case VNC_ENCODING_QUALITYLEVEL0
... VNC_ENCODING_QUALITYLEVEL0
+ 9:
2088 if (vs
->vd
->lossy
) {
2089 vs
->tight
.quality
= (enc
& 0x0F);
2093 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i
, enc
, enc
);
2097 vnc_desktop_resize(vs
);
2098 check_pointer_type_change(&vs
->mouse_mode_notifier
, NULL
);
2099 vnc_led_state_change(vs
);
2102 static void set_pixel_conversion(VncState
*vs
)
2104 pixman_format_code_t fmt
= qemu_pixman_get_format(&vs
->client_pf
);
2106 if (fmt
== VNC_SERVER_FB_FORMAT
) {
2107 vs
->write_pixels
= vnc_write_pixels_copy
;
2108 vnc_hextile_set_pixel_conversion(vs
, 0);
2110 vs
->write_pixels
= vnc_write_pixels_generic
;
2111 vnc_hextile_set_pixel_conversion(vs
, 1);
2115 static void send_color_map(VncState
*vs
)
2119 vnc_write_u8(vs
, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES
);
2120 vnc_write_u8(vs
, 0); /* padding */
2121 vnc_write_u16(vs
, 0); /* first color */
2122 vnc_write_u16(vs
, 256); /* # of colors */
2124 for (i
= 0; i
< 256; i
++) {
2125 PixelFormat
*pf
= &vs
->client_pf
;
2127 vnc_write_u16(vs
, (((i
>> pf
->rshift
) & pf
->rmax
) << (16 - pf
->rbits
)));
2128 vnc_write_u16(vs
, (((i
>> pf
->gshift
) & pf
->gmax
) << (16 - pf
->gbits
)));
2129 vnc_write_u16(vs
, (((i
>> pf
->bshift
) & pf
->bmax
) << (16 - pf
->bbits
)));
2133 static void set_pixel_format(VncState
*vs
, int bits_per_pixel
,
2134 int big_endian_flag
, int true_color_flag
,
2135 int red_max
, int green_max
, int blue_max
,
2136 int red_shift
, int green_shift
, int blue_shift
)
2138 if (!true_color_flag
) {
2139 /* Expose a reasonable default 256 color map */
2149 switch (bits_per_pixel
) {
2155 vnc_client_error(vs
);
2159 vs
->client_pf
.rmax
= red_max
? red_max
: 0xFF;
2160 vs
->client_pf
.rbits
= hweight_long(red_max
);
2161 vs
->client_pf
.rshift
= red_shift
;
2162 vs
->client_pf
.rmask
= red_max
<< red_shift
;
2163 vs
->client_pf
.gmax
= green_max
? green_max
: 0xFF;
2164 vs
->client_pf
.gbits
= hweight_long(green_max
);
2165 vs
->client_pf
.gshift
= green_shift
;
2166 vs
->client_pf
.gmask
= green_max
<< green_shift
;
2167 vs
->client_pf
.bmax
= blue_max
? blue_max
: 0xFF;
2168 vs
->client_pf
.bbits
= hweight_long(blue_max
);
2169 vs
->client_pf
.bshift
= blue_shift
;
2170 vs
->client_pf
.bmask
= blue_max
<< blue_shift
;
2171 vs
->client_pf
.bits_per_pixel
= bits_per_pixel
;
2172 vs
->client_pf
.bytes_per_pixel
= bits_per_pixel
/ 8;
2173 vs
->client_pf
.depth
= bits_per_pixel
== 32 ? 24 : bits_per_pixel
;
2174 vs
->client_be
= big_endian_flag
;
2176 if (!true_color_flag
) {
2180 set_pixel_conversion(vs
);
2182 graphic_hw_invalidate(vs
->vd
->dcl
.con
);
2183 graphic_hw_update(vs
->vd
->dcl
.con
);
2186 static void pixel_format_message (VncState
*vs
) {
2187 char pad
[3] = { 0, 0, 0 };
2189 vs
->client_pf
= qemu_default_pixelformat(32);
2191 vnc_write_u8(vs
, vs
->client_pf
.bits_per_pixel
); /* bits-per-pixel */
2192 vnc_write_u8(vs
, vs
->client_pf
.depth
); /* depth */
2194 #ifdef HOST_WORDS_BIGENDIAN
2195 vnc_write_u8(vs
, 1); /* big-endian-flag */
2197 vnc_write_u8(vs
, 0); /* big-endian-flag */
2199 vnc_write_u8(vs
, 1); /* true-color-flag */
2200 vnc_write_u16(vs
, vs
->client_pf
.rmax
); /* red-max */
2201 vnc_write_u16(vs
, vs
->client_pf
.gmax
); /* green-max */
2202 vnc_write_u16(vs
, vs
->client_pf
.bmax
); /* blue-max */
2203 vnc_write_u8(vs
, vs
->client_pf
.rshift
); /* red-shift */
2204 vnc_write_u8(vs
, vs
->client_pf
.gshift
); /* green-shift */
2205 vnc_write_u8(vs
, vs
->client_pf
.bshift
); /* blue-shift */
2206 vnc_write(vs
, pad
, 3); /* padding */
2208 vnc_hextile_set_pixel_conversion(vs
, 0);
2209 vs
->write_pixels
= vnc_write_pixels_copy
;
2212 static void vnc_colordepth(VncState
*vs
)
2214 if (vnc_has_feature(vs
, VNC_FEATURE_WMVI
)) {
2215 /* Sending a WMVi message to notify the client*/
2216 vnc_lock_output(vs
);
2217 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2218 vnc_write_u8(vs
, 0);
2219 vnc_write_u16(vs
, 1); /* number of rects */
2220 vnc_framebuffer_update(vs
, 0, 0,
2221 pixman_image_get_width(vs
->vd
->server
),
2222 pixman_image_get_height(vs
->vd
->server
),
2224 pixel_format_message(vs
);
2225 vnc_unlock_output(vs
);
2228 set_pixel_conversion(vs
);
2232 static int protocol_client_msg(VncState
*vs
, uint8_t *data
, size_t len
)
2236 VncDisplay
*vd
= vs
->vd
;
2239 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2243 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT
:
2247 set_pixel_format(vs
, read_u8(data
, 4),
2248 read_u8(data
, 6), read_u8(data
, 7),
2249 read_u16(data
, 8), read_u16(data
, 10),
2250 read_u16(data
, 12), read_u8(data
, 14),
2251 read_u8(data
, 15), read_u8(data
, 16));
2253 case VNC_MSG_CLIENT_SET_ENCODINGS
:
2258 limit
= read_u16(data
, 2);
2260 return 4 + (limit
* 4);
2262 limit
= read_u16(data
, 2);
2264 for (i
= 0; i
< limit
; i
++) {
2265 int32_t val
= read_s32(data
, 4 + (i
* 4));
2266 memcpy(data
+ 4 + (i
* 4), &val
, sizeof(val
));
2269 set_encodings(vs
, (int32_t *)(data
+ 4), limit
);
2271 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST
:
2275 framebuffer_update_request(vs
,
2276 read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4),
2277 read_u16(data
, 6), read_u16(data
, 8));
2279 case VNC_MSG_CLIENT_KEY_EVENT
:
2283 key_event(vs
, read_u8(data
, 1), read_u32(data
, 4));
2285 case VNC_MSG_CLIENT_POINTER_EVENT
:
2289 pointer_event(vs
, read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4));
2291 case VNC_MSG_CLIENT_CUT_TEXT
:
2296 uint32_t dlen
= read_u32(data
, 4);
2297 if (dlen
> (1 << 20)) {
2298 error_report("vnc: client_cut_text msg payload has %u bytes"
2299 " which exceeds our limit of 1MB.", dlen
);
2300 vnc_client_error(vs
);
2308 client_cut_text(vs
, read_u32(data
, 4), data
+ 8);
2310 case VNC_MSG_CLIENT_QEMU
:
2314 switch (read_u8(data
, 1)) {
2315 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT
:
2319 ext_key_event(vs
, read_u16(data
, 2),
2320 read_u32(data
, 4), read_u32(data
, 8));
2322 case VNC_MSG_CLIENT_QEMU_AUDIO
:
2326 switch (read_u16 (data
, 2)) {
2327 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE
:
2330 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE
:
2333 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT
:
2336 switch (read_u8(data
, 4)) {
2337 case 0: vs
->as
.fmt
= AUD_FMT_U8
; break;
2338 case 1: vs
->as
.fmt
= AUD_FMT_S8
; break;
2339 case 2: vs
->as
.fmt
= AUD_FMT_U16
; break;
2340 case 3: vs
->as
.fmt
= AUD_FMT_S16
; break;
2341 case 4: vs
->as
.fmt
= AUD_FMT_U32
; break;
2342 case 5: vs
->as
.fmt
= AUD_FMT_S32
; break;
2344 VNC_DEBUG("Invalid audio format %d\n", read_u8(data
, 4));
2345 vnc_client_error(vs
);
2348 vs
->as
.nchannels
= read_u8(data
, 5);
2349 if (vs
->as
.nchannels
!= 1 && vs
->as
.nchannels
!= 2) {
2350 VNC_DEBUG("Invalid audio channel coount %d\n",
2352 vnc_client_error(vs
);
2355 vs
->as
.freq
= read_u32(data
, 6);
2358 VNC_DEBUG("Invalid audio message %d\n", read_u8(data
, 4));
2359 vnc_client_error(vs
);
2365 VNC_DEBUG("Msg: %d\n", read_u16(data
, 0));
2366 vnc_client_error(vs
);
2371 VNC_DEBUG("Msg: %d\n", data
[0]);
2372 vnc_client_error(vs
);
2376 vnc_read_when(vs
, protocol_client_msg
, 1);
2380 static int protocol_client_init(VncState
*vs
, uint8_t *data
, size_t len
)
2386 mode
= data
[0] ? VNC_SHARE_MODE_SHARED
: VNC_SHARE_MODE_EXCLUSIVE
;
2387 switch (vs
->vd
->share_policy
) {
2388 case VNC_SHARE_POLICY_IGNORE
:
2390 * Ignore the shared flag. Nothing to do here.
2392 * Doesn't conform to the rfb spec but is traditional qemu
2393 * behavior, thus left here as option for compatibility
2397 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
:
2399 * Policy: Allow clients ask for exclusive access.
2401 * Implementation: When a client asks for exclusive access,
2402 * disconnect all others. Shared connects are allowed as long
2403 * as no exclusive connection exists.
2405 * This is how the rfb spec suggests to handle the shared flag.
2407 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2409 QTAILQ_FOREACH(client
, &vs
->vd
->clients
, next
) {
2413 if (client
->share_mode
!= VNC_SHARE_MODE_EXCLUSIVE
&&
2414 client
->share_mode
!= VNC_SHARE_MODE_SHARED
) {
2417 vnc_disconnect_start(client
);
2420 if (mode
== VNC_SHARE_MODE_SHARED
) {
2421 if (vs
->vd
->num_exclusive
> 0) {
2422 vnc_disconnect_start(vs
);
2427 case VNC_SHARE_POLICY_FORCE_SHARED
:
2429 * Policy: Shared connects only.
2430 * Implementation: Disallow clients asking for exclusive access.
2432 * Useful for shared desktop sessions where you don't want
2433 * someone forgetting to say -shared when running the vnc
2434 * client disconnect everybody else.
2436 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2437 vnc_disconnect_start(vs
);
2442 vnc_set_share_mode(vs
, mode
);
2444 if (vs
->vd
->num_shared
> vs
->vd
->connections_limit
) {
2445 vnc_disconnect_start(vs
);
2449 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
2450 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
2451 vnc_write_u16(vs
, vs
->client_width
);
2452 vnc_write_u16(vs
, vs
->client_height
);
2454 pixel_format_message(vs
);
2457 size
= snprintf(buf
, sizeof(buf
), "QEMU (%s)", qemu_name
);
2459 size
= snprintf(buf
, sizeof(buf
), "QEMU");
2461 vnc_write_u32(vs
, size
);
2462 vnc_write(vs
, buf
, size
);
2465 vnc_client_cache_auth(vs
);
2466 vnc_qmp_event(vs
, QAPI_EVENT_VNC_INITIALIZED
);
2468 vnc_read_when(vs
, protocol_client_msg
, 1);
2473 void start_client_init(VncState
*vs
)
2475 vnc_read_when(vs
, protocol_client_init
, 1);
2478 static void make_challenge(VncState
*vs
)
2482 srand(time(NULL
)+getpid()+getpid()*987654+rand());
2484 for (i
= 0 ; i
< sizeof(vs
->challenge
) ; i
++)
2485 vs
->challenge
[i
] = (int) (256.0*rand()/(RAND_MAX
+1.0));
2488 static int protocol_client_auth_vnc(VncState
*vs
, uint8_t *data
, size_t len
)
2490 unsigned char response
[VNC_AUTH_CHALLENGE_SIZE
];
2492 unsigned char key
[8];
2493 time_t now
= time(NULL
);
2494 QCryptoCipher
*cipher
= NULL
;
2497 if (!vs
->vd
->password
) {
2498 VNC_DEBUG("No password configured on server");
2501 if (vs
->vd
->expires
< now
) {
2502 VNC_DEBUG("Password is expired");
2506 memcpy(response
, vs
->challenge
, VNC_AUTH_CHALLENGE_SIZE
);
2508 /* Calculate the expected challenge response */
2509 pwlen
= strlen(vs
->vd
->password
);
2510 for (i
=0; i
<sizeof(key
); i
++)
2511 key
[i
] = i
<pwlen
? vs
->vd
->password
[i
] : 0;
2513 cipher
= qcrypto_cipher_new(
2514 QCRYPTO_CIPHER_ALG_DES_RFB
,
2515 QCRYPTO_CIPHER_MODE_ECB
,
2516 key
, G_N_ELEMENTS(key
),
2519 VNC_DEBUG("Cannot initialize cipher %s",
2520 error_get_pretty(err
));
2525 if (qcrypto_cipher_encrypt(cipher
,
2528 VNC_AUTH_CHALLENGE_SIZE
,
2530 VNC_DEBUG("Cannot encrypt challenge %s",
2531 error_get_pretty(err
));
2536 /* Compare expected vs actual challenge response */
2537 if (memcmp(response
, data
, VNC_AUTH_CHALLENGE_SIZE
) != 0) {
2538 VNC_DEBUG("Client challenge response did not match\n");
2541 VNC_DEBUG("Accepting VNC challenge response\n");
2542 vnc_write_u32(vs
, 0); /* Accept auth */
2545 start_client_init(vs
);
2548 qcrypto_cipher_free(cipher
);
2552 vnc_write_u32(vs
, 1); /* Reject auth */
2553 if (vs
->minor
>= 8) {
2554 static const char err
[] = "Authentication failed";
2555 vnc_write_u32(vs
, sizeof(err
));
2556 vnc_write(vs
, err
, sizeof(err
));
2559 vnc_client_error(vs
);
2560 qcrypto_cipher_free(cipher
);
2564 void start_auth_vnc(VncState
*vs
)
2567 /* Send client a 'random' challenge */
2568 vnc_write(vs
, vs
->challenge
, sizeof(vs
->challenge
));
2571 vnc_read_when(vs
, protocol_client_auth_vnc
, sizeof(vs
->challenge
));
2575 static int protocol_client_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2577 /* We only advertise 1 auth scheme at a time, so client
2578 * must pick the one we sent. Verify this */
2579 if (data
[0] != vs
->auth
) { /* Reject auth */
2580 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data
[0]);
2581 vnc_write_u32(vs
, 1);
2582 if (vs
->minor
>= 8) {
2583 static const char err
[] = "Authentication failed";
2584 vnc_write_u32(vs
, sizeof(err
));
2585 vnc_write(vs
, err
, sizeof(err
));
2587 vnc_client_error(vs
);
2588 } else { /* Accept requested auth */
2589 VNC_DEBUG("Client requested auth %d\n", (int)data
[0]);
2592 VNC_DEBUG("Accept auth none\n");
2593 if (vs
->minor
>= 8) {
2594 vnc_write_u32(vs
, 0); /* Accept auth completion */
2597 start_client_init(vs
);
2601 VNC_DEBUG("Start VNC auth\n");
2605 case VNC_AUTH_VENCRYPT
:
2606 VNC_DEBUG("Accept VeNCrypt auth\n");
2607 start_auth_vencrypt(vs
);
2610 #ifdef CONFIG_VNC_SASL
2612 VNC_DEBUG("Accept SASL auth\n");
2613 start_auth_sasl(vs
);
2615 #endif /* CONFIG_VNC_SASL */
2617 default: /* Should not be possible, but just in case */
2618 VNC_DEBUG("Reject auth %d server code bug\n", vs
->auth
);
2619 vnc_write_u8(vs
, 1);
2620 if (vs
->minor
>= 8) {
2621 static const char err
[] = "Authentication failed";
2622 vnc_write_u32(vs
, sizeof(err
));
2623 vnc_write(vs
, err
, sizeof(err
));
2625 vnc_client_error(vs
);
2631 static int protocol_version(VncState
*vs
, uint8_t *version
, size_t len
)
2635 memcpy(local
, version
, 12);
2638 if (sscanf(local
, "RFB %03d.%03d\n", &vs
->major
, &vs
->minor
) != 2) {
2639 VNC_DEBUG("Malformed protocol version %s\n", local
);
2640 vnc_client_error(vs
);
2643 VNC_DEBUG("Client request protocol version %d.%d\n", vs
->major
, vs
->minor
);
2644 if (vs
->major
!= 3 ||
2650 VNC_DEBUG("Unsupported client version\n");
2651 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2653 vnc_client_error(vs
);
2656 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2657 * as equivalent to v3.3 by servers
2659 if (vs
->minor
== 4 || vs
->minor
== 5)
2662 if (vs
->minor
== 3) {
2663 if (vs
->auth
== VNC_AUTH_NONE
) {
2664 VNC_DEBUG("Tell client auth none\n");
2665 vnc_write_u32(vs
, vs
->auth
);
2667 start_client_init(vs
);
2668 } else if (vs
->auth
== VNC_AUTH_VNC
) {
2669 VNC_DEBUG("Tell client VNC auth\n");
2670 vnc_write_u32(vs
, vs
->auth
);
2674 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs
->auth
);
2675 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2677 vnc_client_error(vs
);
2680 VNC_DEBUG("Telling client we support auth %d\n", vs
->auth
);
2681 vnc_write_u8(vs
, 1); /* num auth */
2682 vnc_write_u8(vs
, vs
->auth
);
2683 vnc_read_when(vs
, protocol_client_auth
, 1);
2690 static VncRectStat
*vnc_stat_rect(VncDisplay
*vd
, int x
, int y
)
2692 struct VncSurface
*vs
= &vd
->guest
;
2694 return &vs
->stats
[y
/ VNC_STAT_RECT
][x
/ VNC_STAT_RECT
];
2697 void vnc_sent_lossy_rect(VncState
*vs
, int x
, int y
, int w
, int h
)
2701 w
= (x
+ w
) / VNC_STAT_RECT
;
2702 h
= (y
+ h
) / VNC_STAT_RECT
;
2706 for (j
= y
; j
<= h
; j
++) {
2707 for (i
= x
; i
<= w
; i
++) {
2708 vs
->lossy_rect
[j
][i
] = 1;
2713 static int vnc_refresh_lossy_rect(VncDisplay
*vd
, int x
, int y
)
2716 int sty
= y
/ VNC_STAT_RECT
;
2717 int stx
= x
/ VNC_STAT_RECT
;
2720 y
= y
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2721 x
= x
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2723 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2726 /* kernel send buffers are full -> refresh later */
2727 if (vs
->output
.offset
) {
2731 if (!vs
->lossy_rect
[sty
][stx
]) {
2735 vs
->lossy_rect
[sty
][stx
] = 0;
2736 for (j
= 0; j
< VNC_STAT_RECT
; ++j
) {
2737 bitmap_set(vs
->dirty
[y
+ j
],
2738 x
/ VNC_DIRTY_PIXELS_PER_BIT
,
2739 VNC_STAT_RECT
/ VNC_DIRTY_PIXELS_PER_BIT
);
2747 static int vnc_update_stats(VncDisplay
*vd
, struct timeval
* tv
)
2749 int width
= pixman_image_get_width(vd
->guest
.fb
);
2750 int height
= pixman_image_get_height(vd
->guest
.fb
);
2755 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2756 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2757 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2759 rect
->updated
= false;
2763 qemu_timersub(tv
, &VNC_REFRESH_STATS
, &res
);
2765 if (timercmp(&vd
->guest
.last_freq_check
, &res
, >)) {
2768 vd
->guest
.last_freq_check
= *tv
;
2770 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2771 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2772 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2773 int count
= ARRAY_SIZE(rect
->times
);
2774 struct timeval min
, max
;
2776 if (!timerisset(&rect
->times
[count
- 1])) {
2780 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2781 qemu_timersub(tv
, &max
, &res
);
2783 if (timercmp(&res
, &VNC_REFRESH_LOSSY
, >)) {
2785 has_dirty
+= vnc_refresh_lossy_rect(vd
, x
, y
);
2786 memset(rect
->times
, 0, sizeof (rect
->times
));
2790 min
= rect
->times
[rect
->idx
];
2791 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2792 qemu_timersub(&max
, &min
, &res
);
2794 rect
->freq
= res
.tv_sec
+ res
.tv_usec
/ 1000000.;
2795 rect
->freq
/= count
;
2796 rect
->freq
= 1. / rect
->freq
;
2802 double vnc_update_freq(VncState
*vs
, int x
, int y
, int w
, int h
)
2808 x
= (x
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2809 y
= (y
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2811 for (j
= y
; j
<= y
+ h
; j
+= VNC_STAT_RECT
) {
2812 for (i
= x
; i
<= x
+ w
; i
+= VNC_STAT_RECT
) {
2813 total
+= vnc_stat_rect(vs
->vd
, i
, j
)->freq
;
2825 static void vnc_rect_updated(VncDisplay
*vd
, int x
, int y
, struct timeval
* tv
)
2829 rect
= vnc_stat_rect(vd
, x
, y
);
2830 if (rect
->updated
) {
2833 rect
->times
[rect
->idx
] = *tv
;
2834 rect
->idx
= (rect
->idx
+ 1) % ARRAY_SIZE(rect
->times
);
2835 rect
->updated
= true;
2838 static int vnc_refresh_server_surface(VncDisplay
*vd
)
2840 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2841 pixman_image_get_width(vd
->server
));
2842 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2843 pixman_image_get_height(vd
->server
));
2844 int cmp_bytes
, server_stride
, line_bytes
, guest_ll
, guest_stride
, y
= 0;
2845 uint8_t *guest_row0
= NULL
, *server_row0
;
2848 pixman_image_t
*tmpbuf
= NULL
;
2850 struct timeval tv
= { 0, 0 };
2852 if (!vd
->non_adaptive
) {
2853 gettimeofday(&tv
, NULL
);
2854 has_dirty
= vnc_update_stats(vd
, &tv
);
2858 * Walk through the guest dirty map.
2859 * Check and copy modified bits from guest to server surface.
2860 * Update server dirty map.
2862 server_row0
= (uint8_t *)pixman_image_get_data(vd
->server
);
2863 server_stride
= guest_stride
= guest_ll
=
2864 pixman_image_get_stride(vd
->server
);
2865 cmp_bytes
= MIN(VNC_DIRTY_PIXELS_PER_BIT
* VNC_SERVER_FB_BYTES
,
2867 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2868 int width
= pixman_image_get_width(vd
->server
);
2869 tmpbuf
= qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT
, width
);
2872 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd
->guest
.fb
));
2873 guest_row0
= (uint8_t *)pixman_image_get_data(vd
->guest
.fb
);
2874 guest_stride
= pixman_image_get_stride(vd
->guest
.fb
);
2875 guest_ll
= pixman_image_get_width(vd
->guest
.fb
) * ((guest_bpp
+ 7) / 8);
2877 line_bytes
= MIN(server_stride
, guest_ll
);
2881 uint8_t *guest_ptr
, *server_ptr
;
2882 unsigned long offset
= find_next_bit((unsigned long *) &vd
->guest
.dirty
,
2883 height
* VNC_DIRTY_BPL(&vd
->guest
),
2884 y
* VNC_DIRTY_BPL(&vd
->guest
));
2885 if (offset
== height
* VNC_DIRTY_BPL(&vd
->guest
)) {
2886 /* no more dirty bits */
2889 y
= offset
/ VNC_DIRTY_BPL(&vd
->guest
);
2890 x
= offset
% VNC_DIRTY_BPL(&vd
->guest
);
2892 server_ptr
= server_row0
+ y
* server_stride
+ x
* cmp_bytes
;
2894 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2895 qemu_pixman_linebuf_fill(tmpbuf
, vd
->guest
.fb
, width
, 0, y
);
2896 guest_ptr
= (uint8_t *)pixman_image_get_data(tmpbuf
);
2898 guest_ptr
= guest_row0
+ y
* guest_stride
;
2900 guest_ptr
+= x
* cmp_bytes
;
2902 for (; x
< DIV_ROUND_UP(width
, VNC_DIRTY_PIXELS_PER_BIT
);
2903 x
++, guest_ptr
+= cmp_bytes
, server_ptr
+= cmp_bytes
) {
2904 int _cmp_bytes
= cmp_bytes
;
2905 if (!test_and_clear_bit(x
, vd
->guest
.dirty
[y
])) {
2908 if ((x
+ 1) * cmp_bytes
> line_bytes
) {
2909 _cmp_bytes
= line_bytes
- x
* cmp_bytes
;
2911 assert(_cmp_bytes
>= 0);
2912 if (memcmp(server_ptr
, guest_ptr
, _cmp_bytes
) == 0) {
2915 memcpy(server_ptr
, guest_ptr
, _cmp_bytes
);
2916 if (!vd
->non_adaptive
) {
2917 vnc_rect_updated(vd
, x
* VNC_DIRTY_PIXELS_PER_BIT
,
2920 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2921 set_bit(x
, vs
->dirty
[y
]);
2928 qemu_pixman_image_unref(tmpbuf
);
2932 static void vnc_refresh(DisplayChangeListener
*dcl
)
2934 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
2936 int has_dirty
, rects
= 0;
2938 if (QTAILQ_EMPTY(&vd
->clients
)) {
2939 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_MAX
);
2943 graphic_hw_update(vd
->dcl
.con
);
2945 if (vnc_trylock_display(vd
)) {
2946 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2950 has_dirty
= vnc_refresh_server_surface(vd
);
2951 vnc_unlock_display(vd
);
2953 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
2954 rects
+= vnc_update_client(vs
, has_dirty
, false);
2955 /* vs might be free()ed here */
2958 if (has_dirty
&& rects
) {
2959 vd
->dcl
.update_interval
/= 2;
2960 if (vd
->dcl
.update_interval
< VNC_REFRESH_INTERVAL_BASE
) {
2961 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_BASE
;
2964 vd
->dcl
.update_interval
+= VNC_REFRESH_INTERVAL_INC
;
2965 if (vd
->dcl
.update_interval
> VNC_REFRESH_INTERVAL_MAX
) {
2966 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_MAX
;
2971 static void vnc_connect(VncDisplay
*vd
, QIOChannelSocket
*sioc
,
2972 bool skipauth
, bool websocket
)
2974 VncState
*vs
= g_new0(VncState
, 1);
2978 object_ref(OBJECT(vs
->sioc
));
2979 vs
->ioc
= QIO_CHANNEL(sioc
);
2980 object_ref(OBJECT(vs
->ioc
));
2983 buffer_init(&vs
->input
, "vnc-input/%p", sioc
);
2984 buffer_init(&vs
->output
, "vnc-output/%p", sioc
);
2985 buffer_init(&vs
->jobs_buffer
, "vnc-jobs_buffer/%p", sioc
);
2987 buffer_init(&vs
->tight
.tight
, "vnc-tight/%p", sioc
);
2988 buffer_init(&vs
->tight
.zlib
, "vnc-tight-zlib/%p", sioc
);
2989 buffer_init(&vs
->tight
.gradient
, "vnc-tight-gradient/%p", sioc
);
2990 #ifdef CONFIG_VNC_JPEG
2991 buffer_init(&vs
->tight
.jpeg
, "vnc-tight-jpeg/%p", sioc
);
2993 #ifdef CONFIG_VNC_PNG
2994 buffer_init(&vs
->tight
.png
, "vnc-tight-png/%p", sioc
);
2996 buffer_init(&vs
->zlib
.zlib
, "vnc-zlib/%p", sioc
);
2997 buffer_init(&vs
->zrle
.zrle
, "vnc-zrle/%p", sioc
);
2998 buffer_init(&vs
->zrle
.fb
, "vnc-zrle-fb/%p", sioc
);
2999 buffer_init(&vs
->zrle
.zlib
, "vnc-zrle-zlib/%p", sioc
);
3002 vs
->auth
= VNC_AUTH_NONE
;
3003 vs
->subauth
= VNC_AUTH_INVALID
;
3006 vs
->auth
= vd
->ws_auth
;
3007 vs
->subauth
= VNC_AUTH_INVALID
;
3009 vs
->auth
= vd
->auth
;
3010 vs
->subauth
= vd
->subauth
;
3013 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
3014 sioc
, websocket
, vs
->auth
, vs
->subauth
);
3016 vs
->lossy_rect
= g_malloc0(VNC_STAT_ROWS
* sizeof (*vs
->lossy_rect
));
3017 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
3018 vs
->lossy_rect
[i
] = g_new0(uint8_t, VNC_STAT_COLS
);
3021 VNC_DEBUG("New client on socket %p\n", vs
->sioc
);
3022 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
3023 qio_channel_set_blocking(vs
->ioc
, false, NULL
);
3027 vs
->ioc_tag
= qio_channel_add_watch(
3028 vs
->ioc
, G_IO_IN
, vncws_tls_handshake_io
, vs
, NULL
);
3030 vs
->ioc_tag
= qio_channel_add_watch(
3031 vs
->ioc
, G_IO_IN
, vncws_handshake_io
, vs
, NULL
);
3034 vs
->ioc_tag
= qio_channel_add_watch(
3035 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
3038 vnc_client_cache_addr(vs
);
3039 vnc_qmp_event(vs
, QAPI_EVENT_VNC_CONNECTED
);
3040 vnc_set_share_mode(vs
, VNC_SHARE_MODE_CONNECTING
);
3042 if (!vs
->websocket
) {
3046 if (vd
->num_connecting
> vd
->connections_limit
) {
3047 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
3048 if (vs
->share_mode
== VNC_SHARE_MODE_CONNECTING
) {
3049 vnc_disconnect_start(vs
);
3056 void vnc_init_state(VncState
*vs
)
3058 vs
->initialized
= true;
3059 VncDisplay
*vd
= vs
->vd
;
3060 bool first_client
= QTAILQ_EMPTY(&vd
->clients
);
3065 vs
->as
.freq
= 44100;
3066 vs
->as
.nchannels
= 2;
3067 vs
->as
.fmt
= AUD_FMT_S16
;
3068 vs
->as
.endianness
= 0;
3070 qemu_mutex_init(&vs
->output_mutex
);
3071 vs
->bh
= qemu_bh_new(vnc_jobs_bh
, vs
);
3073 QTAILQ_INSERT_TAIL(&vd
->clients
, vs
, next
);
3075 vnc_update_server_surface(vd
);
3078 graphic_hw_update(vd
->dcl
.con
);
3080 vnc_write(vs
, "RFB 003.008\n", 12);
3082 vnc_read_when(vs
, protocol_version
, 12);
3084 if (vs
->vd
->lock_key_sync
)
3085 vs
->led
= qemu_add_led_event_handler(kbd_leds
, vs
);
3087 vs
->mouse_mode_notifier
.notify
= check_pointer_type_change
;
3088 qemu_add_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
3090 /* vs might be free()ed here */
3093 static gboolean
vnc_listen_io(QIOChannel
*ioc
,
3094 GIOCondition condition
,
3097 VncDisplay
*vs
= opaque
;
3098 QIOChannelSocket
*sioc
= NULL
;
3102 graphic_hw_update(vs
->dcl
.con
);
3103 sioc
= qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc
), &err
);
3105 qio_channel_set_delay(QIO_CHANNEL(sioc
), false);
3106 vnc_connect(vs
, sioc
, false,
3107 ioc
!= QIO_CHANNEL(vs
->lsock
));
3108 object_unref(OBJECT(sioc
));
3110 /* client probably closed connection before we got there */
3117 static const DisplayChangeListenerOps dcl_ops
= {
3119 .dpy_refresh
= vnc_refresh
,
3120 .dpy_gfx_copy
= vnc_dpy_copy
,
3121 .dpy_gfx_update
= vnc_dpy_update
,
3122 .dpy_gfx_switch
= vnc_dpy_switch
,
3123 .dpy_gfx_check_format
= qemu_pixman_check_format
,
3124 .dpy_mouse_set
= vnc_mouse_set
,
3125 .dpy_cursor_define
= vnc_dpy_cursor_define
,
3128 void vnc_display_init(const char *id
)
3132 if (vnc_display_find(id
) != NULL
) {
3135 vs
= g_malloc0(sizeof(*vs
));
3137 vs
->id
= strdup(id
);
3138 QTAILQ_INSERT_TAIL(&vnc_displays
, vs
, next
);
3140 QTAILQ_INIT(&vs
->clients
);
3141 vs
->expires
= TIME_MAX
;
3143 if (keyboard_layout
) {
3144 trace_vnc_key_map_init(keyboard_layout
);
3145 vs
->kbd_layout
= init_keyboard_layout(name2keysym
, keyboard_layout
);
3147 vs
->kbd_layout
= init_keyboard_layout(name2keysym
, "en-us");
3150 if (!vs
->kbd_layout
)
3153 qemu_mutex_init(&vs
->mutex
);
3154 vnc_start_worker_thread();
3156 vs
->dcl
.ops
= &dcl_ops
;
3157 register_displaychangelistener(&vs
->dcl
);
3161 static void vnc_display_close(VncDisplay
*vs
)
3165 vs
->enabled
= false;
3166 vs
->is_unix
= false;
3167 if (vs
->lsock
!= NULL
) {
3168 if (vs
->lsock_tag
) {
3169 g_source_remove(vs
->lsock_tag
);
3171 object_unref(OBJECT(vs
->lsock
));
3174 vs
->ws_enabled
= false;
3175 if (vs
->lwebsock
!= NULL
) {
3176 if (vs
->lwebsock_tag
) {
3177 g_source_remove(vs
->lwebsock_tag
);
3179 object_unref(OBJECT(vs
->lwebsock
));
3180 vs
->lwebsock
= NULL
;
3182 vs
->auth
= VNC_AUTH_INVALID
;
3183 vs
->subauth
= VNC_AUTH_INVALID
;
3185 object_unparent(OBJECT(vs
->tlscreds
));
3186 vs
->tlscreds
= NULL
;
3188 g_free(vs
->tlsaclname
);
3189 vs
->tlsaclname
= NULL
;
3192 int vnc_display_password(const char *id
, const char *password
)
3194 VncDisplay
*vs
= vnc_display_find(id
);
3199 if (vs
->auth
== VNC_AUTH_NONE
) {
3200 error_printf_unless_qmp("If you want use passwords please enable "
3201 "password auth using '-vnc ${dpy},password'.");
3205 g_free(vs
->password
);
3206 vs
->password
= g_strdup(password
);
3211 int vnc_display_pw_expire(const char *id
, time_t expires
)
3213 VncDisplay
*vs
= vnc_display_find(id
);
3219 vs
->expires
= expires
;
3223 static void vnc_display_print_local_addr(VncDisplay
*vs
)
3225 SocketAddress
*addr
;
3228 addr
= qio_channel_socket_get_local_address(vs
->lsock
, &err
);
3233 if (addr
->type
!= SOCKET_ADDRESS_KIND_INET
) {
3234 qapi_free_SocketAddress(addr
);
3237 error_printf_unless_qmp("VNC server running on %s:%s\n",
3238 addr
->u
.inet
.data
->host
,
3239 addr
->u
.inet
.data
->port
);
3240 qapi_free_SocketAddress(addr
);
3243 static QemuOptsList qemu_vnc_opts
= {
3245 .head
= QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts
.head
),
3246 .implied_opt_name
= "vnc",
3250 .type
= QEMU_OPT_STRING
,
3252 .name
= "websocket",
3253 .type
= QEMU_OPT_STRING
,
3255 .name
= "tls-creds",
3256 .type
= QEMU_OPT_STRING
,
3258 /* Deprecated in favour of tls-creds */
3260 .type
= QEMU_OPT_STRING
,
3263 .type
= QEMU_OPT_STRING
,
3266 .type
= QEMU_OPT_STRING
,
3269 .type
= QEMU_OPT_NUMBER
,
3271 .name
= "connections",
3272 .type
= QEMU_OPT_NUMBER
,
3275 .type
= QEMU_OPT_NUMBER
,
3278 .type
= QEMU_OPT_BOOL
,
3281 .type
= QEMU_OPT_BOOL
,
3284 .type
= QEMU_OPT_BOOL
,
3287 .type
= QEMU_OPT_BOOL
,
3289 .name
= "lock-key-sync",
3290 .type
= QEMU_OPT_BOOL
,
3292 .name
= "key-delay-ms",
3293 .type
= QEMU_OPT_NUMBER
,
3296 .type
= QEMU_OPT_BOOL
,
3298 /* Deprecated in favour of tls-creds */
3300 .type
= QEMU_OPT_BOOL
,
3302 /* Deprecated in favour of tls-creds */
3303 .name
= "x509verify",
3304 .type
= QEMU_OPT_STRING
,
3307 .type
= QEMU_OPT_BOOL
,
3310 .type
= QEMU_OPT_BOOL
,
3312 .name
= "non-adaptive",
3313 .type
= QEMU_OPT_BOOL
,
3315 { /* end of list */ }
3321 vnc_display_setup_auth(VncDisplay
*vs
,
3328 * We have a choice of 3 authentication options
3334 * The channel can be run in 2 modes
3339 * And TLS can use 2 types of credentials
3344 * We thus have 9 possible logical combinations
3349 * 4. tls + anon + none
3350 * 5. tls + anon + vnc
3351 * 6. tls + anon + sasl
3352 * 7. tls + x509 + none
3353 * 8. tls + x509 + vnc
3354 * 9. tls + x509 + sasl
3356 * These need to be mapped into the VNC auth schemes
3357 * in an appropriate manner. In regular VNC, all the
3358 * TLS options get mapped into VNC_AUTH_VENCRYPT
3361 * In websockets, the https:// protocol already provides
3362 * TLS support, so there is no need to make use of the
3363 * VeNCrypt extension. Furthermore, websockets browser
3364 * clients could not use VeNCrypt even if they wanted to,
3365 * as they cannot control when the TLS handshake takes
3366 * place. Thus there is no option but to rely on https://,
3367 * meaning combinations 4->6 and 7->9 will be mapped to
3368 * VNC auth schemes in the same way as combos 1->3.
3370 * Regardless of fact that we have a different mapping to
3371 * VNC auth mechs for plain VNC vs websockets VNC, the end
3372 * result has the same security characteristics.
3376 vs
->auth
= VNC_AUTH_VENCRYPT
;
3380 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3381 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3382 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3383 vs
->subauth
= VNC_AUTH_VENCRYPT_X509VNC
;
3384 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3385 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3386 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3387 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSVNC
;
3390 "Unsupported TLS cred type %s",
3391 object_get_typename(OBJECT(vs
->tlscreds
)));
3395 VNC_DEBUG("Initializing VNC server with password auth\n");
3396 vs
->auth
= VNC_AUTH_VNC
;
3397 vs
->subauth
= VNC_AUTH_INVALID
;
3400 vs
->ws_auth
= VNC_AUTH_VNC
;
3402 vs
->ws_auth
= VNC_AUTH_INVALID
;
3406 vs
->auth
= VNC_AUTH_VENCRYPT
;
3410 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3411 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3412 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3413 vs
->subauth
= VNC_AUTH_VENCRYPT_X509SASL
;
3414 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3415 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3416 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3417 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSSASL
;
3420 "Unsupported TLS cred type %s",
3421 object_get_typename(OBJECT(vs
->tlscreds
)));
3425 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3426 vs
->auth
= VNC_AUTH_SASL
;
3427 vs
->subauth
= VNC_AUTH_INVALID
;
3430 vs
->ws_auth
= VNC_AUTH_SASL
;
3432 vs
->ws_auth
= VNC_AUTH_INVALID
;
3436 vs
->auth
= VNC_AUTH_VENCRYPT
;
3440 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3441 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3442 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3443 vs
->subauth
= VNC_AUTH_VENCRYPT_X509NONE
;
3444 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3445 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3446 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3447 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSNONE
;
3450 "Unsupported TLS cred type %s",
3451 object_get_typename(OBJECT(vs
->tlscreds
)));
3455 VNC_DEBUG("Initializing VNC server with no auth\n");
3456 vs
->auth
= VNC_AUTH_NONE
;
3457 vs
->subauth
= VNC_AUTH_INVALID
;
3460 vs
->ws_auth
= VNC_AUTH_NONE
;
3462 vs
->ws_auth
= VNC_AUTH_INVALID
;
3470 * Handle back compat with old CLI syntax by creating some
3471 * suitable QCryptoTLSCreds objects
3473 static QCryptoTLSCreds
*
3474 vnc_display_create_creds(bool x509
,
3480 gchar
*credsid
= g_strdup_printf("tlsvnc%s", id
);
3481 Object
*parent
= object_get_objects_root();
3486 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509
,
3490 "endpoint", "server",
3492 "verify-peer", x509verify
? "yes" : "no",
3495 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON
,
3499 "endpoint", "server",
3506 error_propagate(errp
, err
);
3510 return QCRYPTO_TLS_CREDS(creds
);
3514 void vnc_display_open(const char *id
, Error
**errp
)
3516 VncDisplay
*vs
= vnc_display_find(id
);
3517 QemuOpts
*opts
= qemu_opts_find(&qemu_vnc_opts
, id
);
3518 SocketAddress
*saddr
= NULL
, *wsaddr
= NULL
;
3519 const char *share
, *device_id
;
3521 bool password
= false;
3522 bool reverse
= false;
3526 int show_vnc_port
= 0;
3528 #ifdef CONFIG_VNC_SASL
3532 int lock_key_sync
= 1;
3536 error_setg(errp
, "VNC display not active");
3539 vnc_display_close(vs
);
3544 vnc
= qemu_opt_get(opts
, "vnc");
3545 if (!vnc
|| strcmp(vnc
, "none") == 0) {
3549 h
= strrchr(vnc
, ':');
3551 size_t hlen
= h
- vnc
;
3553 const char *websocket
= qemu_opt_get(opts
, "websocket");
3554 int to
= qemu_opt_get_number(opts
, "to", 0);
3555 bool has_ipv4
= qemu_opt_get(opts
, "ipv4");
3556 bool has_ipv6
= qemu_opt_get(opts
, "ipv6");
3557 bool ipv4
= qemu_opt_get_bool(opts
, "ipv4", false);
3558 bool ipv6
= qemu_opt_get_bool(opts
, "ipv6", false);
3560 saddr
= g_new0(SocketAddress
, 1);
3562 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1
)) {
3564 "SHA1 hash support is required for websockets");
3568 wsaddr
= g_new0(SocketAddress
, 1);
3569 vs
->ws_enabled
= true;
3572 if (strncmp(vnc
, "unix:", 5) == 0) {
3573 saddr
->type
= SOCKET_ADDRESS_KIND_UNIX
;
3574 saddr
->u
.q_unix
.data
= g_new0(UnixSocketAddress
, 1);
3575 saddr
->u
.q_unix
.data
->path
= g_strdup(vnc
+ 5);
3577 if (vs
->ws_enabled
) {
3578 error_setg(errp
, "UNIX sockets not supported with websock");
3582 unsigned long long baseport
;
3583 InetSocketAddress
*inet
;
3584 saddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3585 inet
= saddr
->u
.inet
.data
= g_new0(InetSocketAddress
, 1);
3586 if (vnc
[0] == '[' && vnc
[hlen
- 1] == ']') {
3587 inet
->host
= g_strndup(vnc
+ 1, hlen
- 2);
3589 inet
->host
= g_strndup(vnc
, hlen
);
3591 if (parse_uint_full(h
+ 1, &baseport
, 10) < 0) {
3592 error_setg(errp
, "can't convert to a number: %s", h
+ 1);
3595 if (baseport
> 65535 ||
3596 baseport
+ 5900 > 65535) {
3597 error_setg(errp
, "port %s out of range", h
+ 1);
3600 inet
->port
= g_strdup_printf(
3601 "%d", (int)baseport
+ 5900);
3604 inet
->has_to
= true;
3605 inet
->to
= to
+ 5900;
3609 inet
->has_ipv4
= has_ipv4
;
3611 inet
->has_ipv6
= has_ipv6
;
3613 if (vs
->ws_enabled
) {
3614 wsaddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3615 inet
= wsaddr
->u
.inet
.data
= g_new0(InetSocketAddress
, 1);
3616 inet
->host
= g_strdup(saddr
->u
.inet
.data
->host
);
3617 inet
->port
= g_strdup(websocket
);
3620 inet
->has_to
= true;
3624 inet
->has_ipv4
= has_ipv4
;
3626 inet
->has_ipv6
= has_ipv6
;
3630 error_setg(errp
, "no vnc port specified");
3634 password
= qemu_opt_get_bool(opts
, "password", false);
3636 if (fips_get_state()) {
3638 "VNC password auth disabled due to FIPS mode, "
3639 "consider using the VeNCrypt or SASL authentication "
3640 "methods as an alternative");
3643 if (!qcrypto_cipher_supports(
3644 QCRYPTO_CIPHER_ALG_DES_RFB
)) {
3646 "Cipher backend does not support DES RFB algorithm");
3651 reverse
= qemu_opt_get_bool(opts
, "reverse", false);
3652 lock_key_sync
= qemu_opt_get_bool(opts
, "lock-key-sync", true);
3653 key_delay_ms
= qemu_opt_get_number(opts
, "key-delay-ms", 1);
3654 sasl
= qemu_opt_get_bool(opts
, "sasl", false);
3655 #ifndef CONFIG_VNC_SASL
3657 error_setg(errp
, "VNC SASL auth requires cyrus-sasl support");
3660 #endif /* CONFIG_VNC_SASL */
3661 credid
= qemu_opt_get(opts
, "tls-creds");
3664 if (qemu_opt_get(opts
, "tls") ||
3665 qemu_opt_get(opts
, "x509") ||
3666 qemu_opt_get(opts
, "x509verify")) {
3668 "'tls-creds' parameter is mutually exclusive with "
3669 "'tls', 'x509' and 'x509verify' parameters");
3673 creds
= object_resolve_path_component(
3674 object_get_objects_root(), credid
);
3676 error_setg(errp
, "No TLS credentials with id '%s'",
3680 vs
->tlscreds
= (QCryptoTLSCreds
*)
3681 object_dynamic_cast(creds
,
3682 TYPE_QCRYPTO_TLS_CREDS
);
3683 if (!vs
->tlscreds
) {
3684 error_setg(errp
, "Object with id '%s' is not TLS credentials",
3688 object_ref(OBJECT(vs
->tlscreds
));
3690 if (vs
->tlscreds
->endpoint
!= QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
) {
3692 "Expecting TLS credentials with a server endpoint");
3697 bool tls
= false, x509
= false, x509verify
= false;
3698 tls
= qemu_opt_get_bool(opts
, "tls", false);
3700 path
= qemu_opt_get(opts
, "x509");
3705 path
= qemu_opt_get(opts
, "x509verify");
3711 vs
->tlscreds
= vnc_display_create_creds(x509
,
3716 if (!vs
->tlscreds
) {
3721 acl
= qemu_opt_get_bool(opts
, "acl", false);
3723 share
= qemu_opt_get(opts
, "share");
3725 if (strcmp(share
, "ignore") == 0) {
3726 vs
->share_policy
= VNC_SHARE_POLICY_IGNORE
;
3727 } else if (strcmp(share
, "allow-exclusive") == 0) {
3728 vs
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3729 } else if (strcmp(share
, "force-shared") == 0) {
3730 vs
->share_policy
= VNC_SHARE_POLICY_FORCE_SHARED
;
3732 error_setg(errp
, "unknown vnc share= option");
3736 vs
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3738 vs
->connections_limit
= qemu_opt_get_number(opts
, "connections", 32);
3740 #ifdef CONFIG_VNC_JPEG
3741 vs
->lossy
= qemu_opt_get_bool(opts
, "lossy", false);
3743 vs
->non_adaptive
= qemu_opt_get_bool(opts
, "non-adaptive", false);
3744 /* adaptive updates are only used with tight encoding and
3745 * if lossy updates are enabled so we can disable all the
3746 * calculations otherwise */
3748 vs
->non_adaptive
= true;
3752 if (strcmp(vs
->id
, "default") == 0) {
3753 vs
->tlsaclname
= g_strdup("vnc.x509dname");
3755 vs
->tlsaclname
= g_strdup_printf("vnc.%s.x509dname", vs
->id
);
3757 qemu_acl_init(vs
->tlsaclname
);
3759 #ifdef CONFIG_VNC_SASL
3763 if (strcmp(vs
->id
, "default") == 0) {
3764 aclname
= g_strdup("vnc.username");
3766 aclname
= g_strdup_printf("vnc.%s.username", vs
->id
);
3768 vs
->sasl
.acl
= qemu_acl_init(aclname
);
3773 if (vnc_display_setup_auth(vs
, password
, sasl
, vs
->ws_enabled
, errp
) < 0) {
3777 #ifdef CONFIG_VNC_SASL
3778 if ((saslErr
= sasl_server_init(NULL
, "qemu")) != SASL_OK
) {
3779 error_setg(errp
, "Failed to initialize SASL auth: %s",
3780 sasl_errstring(saslErr
, NULL
, NULL
));
3784 vs
->lock_key_sync
= lock_key_sync
;
3785 vs
->key_delay_ms
= key_delay_ms
;
3787 device_id
= qemu_opt_get(opts
, "display");
3789 int head
= qemu_opt_get_number(opts
, "head", 0);
3792 con
= qemu_console_lookup_by_device_name(device_id
, head
, &err
);
3794 error_propagate(errp
, err
);
3801 if (con
!= vs
->dcl
.con
) {
3802 unregister_displaychangelistener(&vs
->dcl
);
3804 register_displaychangelistener(&vs
->dcl
);
3808 /* connect to viewer */
3809 QIOChannelSocket
*sioc
= NULL
;
3811 vs
->lwebsock
= NULL
;
3812 if (vs
->ws_enabled
) {
3813 error_setg(errp
, "Cannot use websockets in reverse mode");
3816 vs
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3817 sioc
= qio_channel_socket_new();
3818 if (qio_channel_socket_connect_sync(sioc
, saddr
, errp
) < 0) {
3821 vnc_connect(vs
, sioc
, false, false);
3822 object_unref(OBJECT(sioc
));
3824 vs
->lsock
= qio_channel_socket_new();
3825 if (qio_channel_socket_listen_sync(vs
->lsock
, saddr
, errp
) < 0) {
3828 vs
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3831 if (vs
->ws_enabled
) {
3832 vs
->lwebsock
= qio_channel_socket_new();
3833 if (qio_channel_socket_listen_sync(vs
->lwebsock
,
3834 wsaddr
, errp
) < 0) {
3835 object_unref(OBJECT(vs
->lsock
));
3841 vs
->lsock_tag
= qio_channel_add_watch(
3842 QIO_CHANNEL(vs
->lsock
),
3843 G_IO_IN
, vnc_listen_io
, vs
, NULL
);
3844 if (vs
->ws_enabled
) {
3845 vs
->lwebsock_tag
= qio_channel_add_watch(
3846 QIO_CHANNEL(vs
->lwebsock
),
3847 G_IO_IN
, vnc_listen_io
, vs
, NULL
);
3851 if (show_vnc_port
) {
3852 vnc_display_print_local_addr(vs
);
3855 qapi_free_SocketAddress(saddr
);
3856 qapi_free_SocketAddress(wsaddr
);
3860 qapi_free_SocketAddress(saddr
);
3861 qapi_free_SocketAddress(wsaddr
);
3862 vs
->enabled
= false;
3863 vs
->ws_enabled
= false;
3866 void vnc_display_add_client(const char *id
, int csock
, bool skipauth
)
3868 VncDisplay
*vs
= vnc_display_find(id
);
3869 QIOChannelSocket
*sioc
;
3875 sioc
= qio_channel_socket_new_fd(csock
, NULL
);
3877 vnc_connect(vs
, sioc
, skipauth
, false);
3878 object_unref(OBJECT(sioc
));
3882 static void vnc_auto_assign_id(QemuOptsList
*olist
, QemuOpts
*opts
)
3887 id
= g_strdup("default");
3888 while (qemu_opts_find(olist
, id
)) {
3890 id
= g_strdup_printf("vnc%d", i
++);
3892 qemu_opts_set_id(opts
, id
);
3895 QemuOpts
*vnc_parse(const char *str
, Error
**errp
)
3897 QemuOptsList
*olist
= qemu_find_opts("vnc");
3898 QemuOpts
*opts
= qemu_opts_parse(olist
, str
, true, errp
);
3905 id
= qemu_opts_id(opts
);
3907 /* auto-assign id if not present */
3908 vnc_auto_assign_id(olist
, opts
);
3913 int vnc_init_func(void *opaque
, QemuOpts
*opts
, Error
**errp
)
3915 Error
*local_err
= NULL
;
3916 char *id
= (char *)qemu_opts_id(opts
);
3919 vnc_display_init(id
);
3920 vnc_display_open(id
, &local_err
);
3921 if (local_err
!= NULL
) {
3922 error_reportf_err(local_err
, "Failed to start VNC server: ");
3928 static void vnc_register_config(void)
3930 qemu_add_opts(&qemu_vnc_opts
);
3932 opts_init(vnc_register_config
);