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
)
697 qemu_pixman_image_unref(vd
->server
);
700 if (QTAILQ_EMPTY(&vd
->clients
)) {
704 width
= vnc_width(vd
);
705 height
= vnc_height(vd
);
706 vd
->server
= pixman_image_create_bits(VNC_SERVER_FB_FORMAT
,
710 memset(vd
->guest
.dirty
, 0x00, sizeof(vd
->guest
.dirty
));
711 vnc_set_area_dirty(vd
->guest
.dirty
, vd
, 0, 0,
715 static void vnc_dpy_switch(DisplayChangeListener
*dcl
,
716 DisplaySurface
*surface
)
718 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
721 vnc_abort_display_jobs(vd
);
725 vnc_update_server_surface(vd
);
728 qemu_pixman_image_unref(vd
->guest
.fb
);
729 vd
->guest
.fb
= pixman_image_ref(surface
->image
);
730 vd
->guest
.format
= surface
->format
;
732 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
734 vnc_desktop_resize(vs
);
735 if (vs
->vd
->cursor
) {
736 vnc_cursor_define(vs
);
738 memset(vs
->dirty
, 0x00, sizeof(vs
->dirty
));
739 vnc_set_area_dirty(vs
->dirty
, vd
, 0, 0,
746 static void vnc_write_pixels_copy(VncState
*vs
,
747 void *pixels
, int size
)
749 vnc_write(vs
, pixels
, size
);
752 /* slowest but generic code. */
753 void vnc_convert_pixel(VncState
*vs
, uint8_t *buf
, uint32_t v
)
757 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
758 r
= (((v
& 0x00ff0000) >> 16) << vs
->client_pf
.rbits
) >> 8;
759 g
= (((v
& 0x0000ff00) >> 8) << vs
->client_pf
.gbits
) >> 8;
760 b
= (((v
& 0x000000ff) >> 0) << vs
->client_pf
.bbits
) >> 8;
762 # error need some bits here if you change VNC_SERVER_FB_FORMAT
764 v
= (r
<< vs
->client_pf
.rshift
) |
765 (g
<< vs
->client_pf
.gshift
) |
766 (b
<< vs
->client_pf
.bshift
);
767 switch (vs
->client_pf
.bytes_per_pixel
) {
797 static void vnc_write_pixels_generic(VncState
*vs
,
798 void *pixels1
, int size
)
802 if (VNC_SERVER_FB_BYTES
== 4) {
803 uint32_t *pixels
= pixels1
;
806 for (i
= 0; i
< n
; i
++) {
807 vnc_convert_pixel(vs
, buf
, pixels
[i
]);
808 vnc_write(vs
, buf
, vs
->client_pf
.bytes_per_pixel
);
813 int vnc_raw_send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
817 VncDisplay
*vd
= vs
->vd
;
819 row
= vnc_server_fb_ptr(vd
, x
, y
);
820 for (i
= 0; i
< h
; i
++) {
821 vs
->write_pixels(vs
, row
, w
* VNC_SERVER_FB_BYTES
);
822 row
+= vnc_server_fb_stride(vd
);
827 int vnc_send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
830 bool encode_raw
= false;
831 size_t saved_offs
= vs
->output
.offset
;
833 switch(vs
->vnc_encoding
) {
834 case VNC_ENCODING_ZLIB
:
835 n
= vnc_zlib_send_framebuffer_update(vs
, x
, y
, w
, h
);
837 case VNC_ENCODING_HEXTILE
:
838 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_HEXTILE
);
839 n
= vnc_hextile_send_framebuffer_update(vs
, x
, y
, w
, h
);
841 case VNC_ENCODING_TIGHT
:
842 n
= vnc_tight_send_framebuffer_update(vs
, x
, y
, w
, h
);
844 case VNC_ENCODING_TIGHT_PNG
:
845 n
= vnc_tight_png_send_framebuffer_update(vs
, x
, y
, w
, h
);
847 case VNC_ENCODING_ZRLE
:
848 n
= vnc_zrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
850 case VNC_ENCODING_ZYWRLE
:
851 n
= vnc_zywrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
858 /* If the client has the same pixel format as our internal buffer and
859 * a RAW encoding would need less space fall back to RAW encoding to
860 * save bandwidth and processing power in the client. */
861 if (!encode_raw
&& vs
->write_pixels
== vnc_write_pixels_copy
&&
862 12 + h
* w
* VNC_SERVER_FB_BYTES
<= (vs
->output
.offset
- saved_offs
)) {
863 vs
->output
.offset
= saved_offs
;
868 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_RAW
);
869 n
= vnc_raw_send_framebuffer_update(vs
, x
, y
, w
, h
);
875 static void vnc_copy(VncState
*vs
, int src_x
, int src_y
, int dst_x
, int dst_y
, int w
, int h
)
877 /* send bitblit op to the vnc client */
879 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
881 vnc_write_u16(vs
, 1); /* number of rects */
882 vnc_framebuffer_update(vs
, dst_x
, dst_y
, w
, h
, VNC_ENCODING_COPYRECT
);
883 vnc_write_u16(vs
, src_x
);
884 vnc_write_u16(vs
, src_y
);
885 vnc_unlock_output(vs
);
889 static void vnc_dpy_copy(DisplayChangeListener
*dcl
,
890 int src_x
, int src_y
,
891 int dst_x
, int dst_y
, int w
, int h
)
893 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
897 int i
, x
, y
, pitch
, inc
, w_lim
, s
;
901 /* no client connected */
905 vnc_refresh_server_surface(vd
);
906 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
907 if (vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
908 vs
->force_update
= 1;
909 vnc_update_client(vs
, 1, true);
910 /* vs might be free()ed here */
914 /* do bitblit op on the local surface too */
915 pitch
= vnc_server_fb_stride(vd
);
916 src_row
= vnc_server_fb_ptr(vd
, src_x
, src_y
);
917 dst_row
= vnc_server_fb_ptr(vd
, dst_x
, dst_y
);
922 src_row
+= pitch
* (h
-1);
923 dst_row
+= pitch
* (h
-1);
928 w_lim
= w
- (VNC_DIRTY_PIXELS_PER_BIT
- (dst_x
% VNC_DIRTY_PIXELS_PER_BIT
));
932 w_lim
= w
- (w_lim
% VNC_DIRTY_PIXELS_PER_BIT
);
934 for (i
= 0; i
< h
; i
++) {
935 for (x
= 0; x
<= w_lim
;
936 x
+= s
, src_row
+= cmp_bytes
, dst_row
+= cmp_bytes
) {
938 if ((s
= w
- w_lim
) == 0)
941 s
= (VNC_DIRTY_PIXELS_PER_BIT
-
942 (dst_x
% VNC_DIRTY_PIXELS_PER_BIT
));
945 s
= VNC_DIRTY_PIXELS_PER_BIT
;
947 cmp_bytes
= s
* VNC_SERVER_FB_BYTES
;
948 if (memcmp(src_row
, dst_row
, cmp_bytes
) == 0)
950 memmove(dst_row
, src_row
, cmp_bytes
);
951 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
952 if (!vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
953 set_bit(((x
+ dst_x
) / VNC_DIRTY_PIXELS_PER_BIT
),
958 src_row
+= pitch
- w
* VNC_SERVER_FB_BYTES
;
959 dst_row
+= pitch
- w
* VNC_SERVER_FB_BYTES
;
963 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
964 if (vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
965 vnc_copy(vs
, src_x
, src_y
, dst_x
, dst_y
, w
, h
);
970 static void vnc_mouse_set(DisplayChangeListener
*dcl
,
971 int x
, int y
, int visible
)
973 /* can we ask the client(s) to move the pointer ??? */
976 static int vnc_cursor_define(VncState
*vs
)
978 QEMUCursor
*c
= vs
->vd
->cursor
;
981 if (vnc_has_feature(vs
, VNC_FEATURE_RICH_CURSOR
)) {
983 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
984 vnc_write_u8(vs
, 0); /* padding */
985 vnc_write_u16(vs
, 1); /* # of rects */
986 vnc_framebuffer_update(vs
, c
->hot_x
, c
->hot_y
, c
->width
, c
->height
,
987 VNC_ENCODING_RICH_CURSOR
);
988 isize
= c
->width
* c
->height
* vs
->client_pf
.bytes_per_pixel
;
989 vnc_write_pixels_generic(vs
, c
->data
, isize
);
990 vnc_write(vs
, vs
->vd
->cursor_mask
, vs
->vd
->cursor_msize
);
991 vnc_unlock_output(vs
);
997 static void vnc_dpy_cursor_define(DisplayChangeListener
*dcl
,
1000 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
1003 cursor_put(vd
->cursor
);
1004 g_free(vd
->cursor_mask
);
1007 cursor_get(vd
->cursor
);
1008 vd
->cursor_msize
= cursor_get_mono_bpl(c
) * c
->height
;
1009 vd
->cursor_mask
= g_malloc0(vd
->cursor_msize
);
1010 cursor_get_mono_mask(c
, 0, vd
->cursor_mask
);
1012 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
1013 vnc_cursor_define(vs
);
1017 static int find_and_clear_dirty_height(VncState
*vs
,
1018 int y
, int last_x
, int x
, int height
)
1022 for (h
= 1; h
< (height
- y
); h
++) {
1023 if (!test_bit(last_x
, vs
->dirty
[y
+ h
])) {
1026 bitmap_clear(vs
->dirty
[y
+ h
], last_x
, x
- last_x
);
1032 static int vnc_update_client(VncState
*vs
, int has_dirty
, bool sync
)
1034 if (vs
->disconnecting
) {
1035 vnc_disconnect_finish(vs
);
1039 vs
->has_dirty
+= has_dirty
;
1040 if (vs
->need_update
&& !vs
->disconnecting
) {
1041 VncDisplay
*vd
= vs
->vd
;
1047 if (vs
->output
.offset
&& !vs
->audio_cap
&& !vs
->force_update
)
1048 /* kernel send buffers are full -> drop frames to throttle */
1051 if (!vs
->has_dirty
&& !vs
->audio_cap
&& !vs
->force_update
)
1055 * Send screen updates to the vnc client using the server
1056 * surface and server dirty map. guest surface updates
1057 * happening in parallel don't disturb us, the next pass will
1058 * send them to the client.
1060 job
= vnc_job_new(vs
);
1062 height
= pixman_image_get_height(vd
->server
);
1063 width
= pixman_image_get_width(vd
->server
);
1069 unsigned long offset
= find_next_bit((unsigned long *) &vs
->dirty
,
1070 height
* VNC_DIRTY_BPL(vs
),
1071 y
* VNC_DIRTY_BPL(vs
));
1072 if (offset
== height
* VNC_DIRTY_BPL(vs
)) {
1073 /* no more dirty bits */
1076 y
= offset
/ VNC_DIRTY_BPL(vs
);
1077 x
= offset
% VNC_DIRTY_BPL(vs
);
1078 x2
= find_next_zero_bit((unsigned long *) &vs
->dirty
[y
],
1079 VNC_DIRTY_BPL(vs
), x
);
1080 bitmap_clear(vs
->dirty
[y
], x
, x2
- x
);
1081 h
= find_and_clear_dirty_height(vs
, y
, x
, x2
, height
);
1082 x2
= MIN(x2
, width
/ VNC_DIRTY_PIXELS_PER_BIT
);
1084 n
+= vnc_job_add_rect(job
, x
* VNC_DIRTY_PIXELS_PER_BIT
, y
,
1085 (x2
- x
) * VNC_DIRTY_PIXELS_PER_BIT
, h
);
1087 if (!x
&& x2
== width
/ VNC_DIRTY_PIXELS_PER_BIT
) {
1099 vs
->force_update
= 0;
1104 if (vs
->disconnecting
) {
1105 vnc_disconnect_finish(vs
);
1114 static void audio_capture_notify(void *opaque
, audcnotification_e cmd
)
1116 VncState
*vs
= opaque
;
1119 case AUD_CNOTIFY_DISABLE
:
1120 vnc_lock_output(vs
);
1121 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1122 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1123 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_END
);
1124 vnc_unlock_output(vs
);
1128 case AUD_CNOTIFY_ENABLE
:
1129 vnc_lock_output(vs
);
1130 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1131 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1132 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN
);
1133 vnc_unlock_output(vs
);
1139 static void audio_capture_destroy(void *opaque
)
1143 static void audio_capture(void *opaque
, void *buf
, int size
)
1145 VncState
*vs
= opaque
;
1147 vnc_lock_output(vs
);
1148 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1149 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1150 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_DATA
);
1151 vnc_write_u32(vs
, size
);
1152 vnc_write(vs
, buf
, size
);
1153 vnc_unlock_output(vs
);
1157 static void audio_add(VncState
*vs
)
1159 struct audio_capture_ops ops
;
1161 if (vs
->audio_cap
) {
1162 error_report("audio already running");
1166 ops
.notify
= audio_capture_notify
;
1167 ops
.destroy
= audio_capture_destroy
;
1168 ops
.capture
= audio_capture
;
1170 vs
->audio_cap
= AUD_add_capture(&vs
->as
, &ops
, vs
);
1171 if (!vs
->audio_cap
) {
1172 error_report("Failed to add audio capture");
1176 static void audio_del(VncState
*vs
)
1178 if (vs
->audio_cap
) {
1179 AUD_del_capture(vs
->audio_cap
, vs
);
1180 vs
->audio_cap
= NULL
;
1184 static void vnc_disconnect_start(VncState
*vs
)
1186 if (vs
->disconnecting
) {
1189 vnc_set_share_mode(vs
, VNC_SHARE_MODE_DISCONNECTED
);
1191 g_source_remove(vs
->ioc_tag
);
1193 qio_channel_close(vs
->ioc
, NULL
);
1194 vs
->disconnecting
= TRUE
;
1197 void vnc_disconnect_finish(VncState
*vs
)
1201 vnc_jobs_join(vs
); /* Wait encoding jobs */
1203 vnc_lock_output(vs
);
1204 vnc_qmp_event(vs
, QAPI_EVENT_VNC_DISCONNECTED
);
1206 buffer_free(&vs
->input
);
1207 buffer_free(&vs
->output
);
1209 qapi_free_VncClientInfo(vs
->info
);
1212 vnc_tight_clear(vs
);
1215 #ifdef CONFIG_VNC_SASL
1216 vnc_sasl_client_cleanup(vs
);
1217 #endif /* CONFIG_VNC_SASL */
1219 vnc_release_modifiers(vs
);
1221 if (vs
->initialized
) {
1222 QTAILQ_REMOVE(&vs
->vd
->clients
, vs
, next
);
1223 qemu_remove_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
1224 if (QTAILQ_EMPTY(&vs
->vd
->clients
)) {
1225 /* last client gone */
1226 vnc_update_server_surface(vs
->vd
);
1230 if (vs
->vd
->lock_key_sync
)
1231 qemu_remove_led_event_handler(vs
->led
);
1232 vnc_unlock_output(vs
);
1234 qemu_mutex_destroy(&vs
->output_mutex
);
1235 if (vs
->bh
!= NULL
) {
1236 qemu_bh_delete(vs
->bh
);
1238 buffer_free(&vs
->jobs_buffer
);
1240 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
1241 g_free(vs
->lossy_rect
[i
]);
1243 g_free(vs
->lossy_rect
);
1245 object_unref(OBJECT(vs
->ioc
));
1247 object_unref(OBJECT(vs
->sioc
));
1252 ssize_t
vnc_client_io_error(VncState
*vs
, ssize_t ret
, Error
**errp
)
1256 VNC_DEBUG("Closing down client sock: EOF\n");
1257 } else if (ret
!= QIO_CHANNEL_ERR_BLOCK
) {
1258 VNC_DEBUG("Closing down client sock: ret %d (%s)\n",
1259 ret
, errp
? error_get_pretty(*errp
) : "Unknown");
1262 vnc_disconnect_start(vs
);
1273 void vnc_client_error(VncState
*vs
)
1275 VNC_DEBUG("Closing down client sock: protocol error\n");
1276 vnc_disconnect_start(vs
);
1281 * Called to write a chunk of data to the client socket. The data may
1282 * be the raw data, or may have already been encoded by SASL.
1283 * The data will be written either straight onto the socket, or
1284 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1286 * NB, it is theoretically possible to have 2 layers of encryption,
1287 * both SASL, and this TLS layer. It is highly unlikely in practice
1288 * though, since SASL encryption will typically be a no-op if TLS
1291 * Returns the number of bytes written, which may be less than
1292 * the requested 'datalen' if the socket would block. Returns
1293 * -1 on error, and disconnects the client socket.
1295 ssize_t
vnc_client_write_buf(VncState
*vs
, const uint8_t *data
, size_t datalen
)
1299 ret
= qio_channel_write(
1300 vs
->ioc
, (const char *)data
, datalen
, &err
);
1301 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data
, datalen
, ret
);
1302 return vnc_client_io_error(vs
, ret
, &err
);
1307 * Called to write buffered data to the client socket, when not
1308 * using any SASL SSF encryption layers. Will write as much data
1309 * as possible without blocking. If all buffered data is written,
1310 * will switch the FD poll() handler back to read monitoring.
1312 * Returns the number of bytes written, which may be less than
1313 * the buffered output data if the socket would block. Returns
1314 * -1 on error, and disconnects the client socket.
1316 static ssize_t
vnc_client_write_plain(VncState
*vs
)
1320 #ifdef CONFIG_VNC_SASL
1321 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1322 vs
->output
.buffer
, vs
->output
.capacity
, vs
->output
.offset
,
1323 vs
->sasl
.waitWriteSSF
);
1325 if (vs
->sasl
.conn
&&
1327 vs
->sasl
.waitWriteSSF
) {
1328 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->sasl
.waitWriteSSF
);
1330 vs
->sasl
.waitWriteSSF
-= ret
;
1332 #endif /* CONFIG_VNC_SASL */
1333 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->output
.offset
);
1337 buffer_advance(&vs
->output
, ret
);
1339 if (vs
->output
.offset
== 0) {
1341 g_source_remove(vs
->ioc_tag
);
1343 vs
->ioc_tag
= qio_channel_add_watch(
1344 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1352 * First function called whenever there is data to be written to
1353 * the client socket. Will delegate actual work according to whether
1354 * SASL SSF layers are enabled (thus requiring encryption calls)
1356 static void vnc_client_write_locked(VncState
*vs
)
1358 #ifdef CONFIG_VNC_SASL
1359 if (vs
->sasl
.conn
&&
1361 !vs
->sasl
.waitWriteSSF
) {
1362 vnc_client_write_sasl(vs
);
1364 #endif /* CONFIG_VNC_SASL */
1366 vnc_client_write_plain(vs
);
1370 static void vnc_client_write(VncState
*vs
)
1373 vnc_lock_output(vs
);
1374 if (vs
->output
.offset
) {
1375 vnc_client_write_locked(vs
);
1376 } else if (vs
->ioc
!= NULL
) {
1378 g_source_remove(vs
->ioc_tag
);
1380 vs
->ioc_tag
= qio_channel_add_watch(
1381 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1383 vnc_unlock_output(vs
);
1386 void vnc_read_when(VncState
*vs
, VncReadEvent
*func
, size_t expecting
)
1388 vs
->read_handler
= func
;
1389 vs
->read_handler_expect
= expecting
;
1394 * Called to read a chunk of data from the client socket. The data may
1395 * be the raw data, or may need to be further decoded by SASL.
1396 * The data will be read either straight from to the socket, or
1397 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1399 * NB, it is theoretically possible to have 2 layers of encryption,
1400 * both SASL, and this TLS layer. It is highly unlikely in practice
1401 * though, since SASL encryption will typically be a no-op if TLS
1404 * Returns the number of bytes read, which may be less than
1405 * the requested 'datalen' if the socket would block. Returns
1406 * -1 on error, and disconnects the client socket.
1408 ssize_t
vnc_client_read_buf(VncState
*vs
, uint8_t *data
, size_t datalen
)
1412 ret
= qio_channel_read(
1413 vs
->ioc
, (char *)data
, datalen
, &err
);
1414 VNC_DEBUG("Read wire %p %zd -> %ld\n", data
, datalen
, ret
);
1415 return vnc_client_io_error(vs
, ret
, &err
);
1420 * Called to read data from the client socket to the input buffer,
1421 * when not using any SASL SSF encryption layers. Will read as much
1422 * data as possible without blocking.
1424 * Returns the number of bytes read. Returns -1 on error, and
1425 * disconnects the client socket.
1427 static ssize_t
vnc_client_read_plain(VncState
*vs
)
1430 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1431 vs
->input
.buffer
, vs
->input
.capacity
, vs
->input
.offset
);
1432 buffer_reserve(&vs
->input
, 4096);
1433 ret
= vnc_client_read_buf(vs
, buffer_end(&vs
->input
), 4096);
1436 vs
->input
.offset
+= ret
;
1440 static void vnc_jobs_bh(void *opaque
)
1442 VncState
*vs
= opaque
;
1444 vnc_jobs_consume_buffer(vs
);
1448 * First function called whenever there is more data to be read from
1449 * the client socket. Will delegate actual work according to whether
1450 * SASL SSF layers are enabled (thus requiring decryption calls)
1451 * Returns 0 on success, -1 if client disconnected
1453 static int vnc_client_read(VncState
*vs
)
1457 #ifdef CONFIG_VNC_SASL
1458 if (vs
->sasl
.conn
&& vs
->sasl
.runSSF
)
1459 ret
= vnc_client_read_sasl(vs
);
1461 #endif /* CONFIG_VNC_SASL */
1462 ret
= vnc_client_read_plain(vs
);
1464 if (vs
->disconnecting
) {
1465 vnc_disconnect_finish(vs
);
1471 while (vs
->read_handler
&& vs
->input
.offset
>= vs
->read_handler_expect
) {
1472 size_t len
= vs
->read_handler_expect
;
1475 ret
= vs
->read_handler(vs
, vs
->input
.buffer
, len
);
1476 if (vs
->disconnecting
) {
1477 vnc_disconnect_finish(vs
);
1482 buffer_advance(&vs
->input
, len
);
1484 vs
->read_handler_expect
= ret
;
1490 gboolean
vnc_client_io(QIOChannel
*ioc G_GNUC_UNUSED
,
1491 GIOCondition condition
, void *opaque
)
1493 VncState
*vs
= opaque
;
1494 if (condition
& G_IO_IN
) {
1495 if (vnc_client_read(vs
) < 0) {
1499 if (condition
& G_IO_OUT
) {
1500 vnc_client_write(vs
);
1506 void vnc_write(VncState
*vs
, const void *data
, size_t len
)
1508 buffer_reserve(&vs
->output
, len
);
1510 if (vs
->ioc
!= NULL
&& buffer_empty(&vs
->output
)) {
1512 g_source_remove(vs
->ioc_tag
);
1514 vs
->ioc_tag
= qio_channel_add_watch(
1515 vs
->ioc
, G_IO_IN
| G_IO_OUT
, vnc_client_io
, vs
, NULL
);
1518 buffer_append(&vs
->output
, data
, len
);
1521 void vnc_write_s32(VncState
*vs
, int32_t value
)
1523 vnc_write_u32(vs
, *(uint32_t *)&value
);
1526 void vnc_write_u32(VncState
*vs
, uint32_t value
)
1530 buf
[0] = (value
>> 24) & 0xFF;
1531 buf
[1] = (value
>> 16) & 0xFF;
1532 buf
[2] = (value
>> 8) & 0xFF;
1533 buf
[3] = value
& 0xFF;
1535 vnc_write(vs
, buf
, 4);
1538 void vnc_write_u16(VncState
*vs
, uint16_t value
)
1542 buf
[0] = (value
>> 8) & 0xFF;
1543 buf
[1] = value
& 0xFF;
1545 vnc_write(vs
, buf
, 2);
1548 void vnc_write_u8(VncState
*vs
, uint8_t value
)
1550 vnc_write(vs
, (char *)&value
, 1);
1553 void vnc_flush(VncState
*vs
)
1555 vnc_lock_output(vs
);
1556 if (vs
->ioc
!= NULL
&& vs
->output
.offset
) {
1557 vnc_client_write_locked(vs
);
1559 vnc_unlock_output(vs
);
1562 static uint8_t read_u8(uint8_t *data
, size_t offset
)
1564 return data
[offset
];
1567 static uint16_t read_u16(uint8_t *data
, size_t offset
)
1569 return ((data
[offset
] & 0xFF) << 8) | (data
[offset
+ 1] & 0xFF);
1572 static int32_t read_s32(uint8_t *data
, size_t offset
)
1574 return (int32_t)((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1575 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1578 uint32_t read_u32(uint8_t *data
, size_t offset
)
1580 return ((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1581 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1584 static void client_cut_text(VncState
*vs
, size_t len
, uint8_t *text
)
1588 static void check_pointer_type_change(Notifier
*notifier
, void *data
)
1590 VncState
*vs
= container_of(notifier
, VncState
, mouse_mode_notifier
);
1591 int absolute
= qemu_input_is_absolute();
1593 if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
) && vs
->absolute
!= absolute
) {
1594 vnc_lock_output(vs
);
1595 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1596 vnc_write_u8(vs
, 0);
1597 vnc_write_u16(vs
, 1);
1598 vnc_framebuffer_update(vs
, absolute
, 0,
1599 pixman_image_get_width(vs
->vd
->server
),
1600 pixman_image_get_height(vs
->vd
->server
),
1601 VNC_ENCODING_POINTER_TYPE_CHANGE
);
1602 vnc_unlock_output(vs
);
1605 vs
->absolute
= absolute
;
1608 static void pointer_event(VncState
*vs
, int button_mask
, int x
, int y
)
1610 static uint32_t bmap
[INPUT_BUTTON__MAX
] = {
1611 [INPUT_BUTTON_LEFT
] = 0x01,
1612 [INPUT_BUTTON_MIDDLE
] = 0x02,
1613 [INPUT_BUTTON_RIGHT
] = 0x04,
1614 [INPUT_BUTTON_WHEEL_UP
] = 0x08,
1615 [INPUT_BUTTON_WHEEL_DOWN
] = 0x10,
1617 QemuConsole
*con
= vs
->vd
->dcl
.con
;
1618 int width
= pixman_image_get_width(vs
->vd
->server
);
1619 int height
= pixman_image_get_height(vs
->vd
->server
);
1621 if (vs
->last_bmask
!= button_mask
) {
1622 qemu_input_update_buttons(con
, bmap
, vs
->last_bmask
, button_mask
);
1623 vs
->last_bmask
= button_mask
;
1627 qemu_input_queue_abs(con
, INPUT_AXIS_X
, x
, width
);
1628 qemu_input_queue_abs(con
, INPUT_AXIS_Y
, y
, height
);
1629 } else if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
)) {
1630 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- 0x7FFF);
1631 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- 0x7FFF);
1633 if (vs
->last_x
!= -1) {
1634 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- vs
->last_x
);
1635 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- vs
->last_y
);
1640 qemu_input_event_sync();
1643 static void reset_keys(VncState
*vs
)
1646 for(i
= 0; i
< 256; i
++) {
1647 if (vs
->modifiers_state
[i
]) {
1648 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, i
, false);
1649 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1650 vs
->modifiers_state
[i
] = 0;
1655 static void press_key(VncState
*vs
, int keysym
)
1657 int keycode
= keysym2scancode(vs
->vd
->kbd_layout
, keysym
) & SCANCODE_KEYMASK
;
1658 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, true);
1659 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1660 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1661 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1664 static int current_led_state(VncState
*vs
)
1668 if (vs
->modifiers_state
[0x46]) {
1669 ledstate
|= QEMU_SCROLL_LOCK_LED
;
1671 if (vs
->modifiers_state
[0x45]) {
1672 ledstate
|= QEMU_NUM_LOCK_LED
;
1674 if (vs
->modifiers_state
[0x3a]) {
1675 ledstate
|= QEMU_CAPS_LOCK_LED
;
1681 static void vnc_led_state_change(VncState
*vs
)
1685 if (!vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
)) {
1689 ledstate
= current_led_state(vs
);
1690 vnc_lock_output(vs
);
1691 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1692 vnc_write_u8(vs
, 0);
1693 vnc_write_u16(vs
, 1);
1694 vnc_framebuffer_update(vs
, 0, 0, 1, 1, VNC_ENCODING_LED_STATE
);
1695 vnc_write_u8(vs
, ledstate
);
1696 vnc_unlock_output(vs
);
1700 static void kbd_leds(void *opaque
, int ledstate
)
1702 VncState
*vs
= opaque
;
1704 bool has_changed
= (ledstate
!= current_led_state(vs
));
1706 trace_vnc_key_guest_leds((ledstate
& QEMU_CAPS_LOCK_LED
),
1707 (ledstate
& QEMU_NUM_LOCK_LED
),
1708 (ledstate
& QEMU_SCROLL_LOCK_LED
));
1710 caps
= ledstate
& QEMU_CAPS_LOCK_LED
? 1 : 0;
1711 num
= ledstate
& QEMU_NUM_LOCK_LED
? 1 : 0;
1712 scr
= ledstate
& QEMU_SCROLL_LOCK_LED
? 1 : 0;
1714 if (vs
->modifiers_state
[0x3a] != caps
) {
1715 vs
->modifiers_state
[0x3a] = caps
;
1717 if (vs
->modifiers_state
[0x45] != num
) {
1718 vs
->modifiers_state
[0x45] = num
;
1720 if (vs
->modifiers_state
[0x46] != scr
) {
1721 vs
->modifiers_state
[0x46] = scr
;
1724 /* Sending the current led state message to the client */
1726 vnc_led_state_change(vs
);
1730 static void do_key_event(VncState
*vs
, int down
, int keycode
, int sym
)
1732 /* QEMU console switch */
1734 case 0x2a: /* Left Shift */
1735 case 0x36: /* Right Shift */
1736 case 0x1d: /* Left CTRL */
1737 case 0x9d: /* Right CTRL */
1738 case 0x38: /* Left ALT */
1739 case 0xb8: /* Right ALT */
1741 vs
->modifiers_state
[keycode
] = 1;
1743 vs
->modifiers_state
[keycode
] = 0;
1745 case 0x02 ... 0x0a: /* '1' to '9' keys */
1746 if (vs
->vd
->dcl
.con
== NULL
&&
1747 down
&& vs
->modifiers_state
[0x1d] && vs
->modifiers_state
[0x38]) {
1748 /* Reset the modifiers sent to the current console */
1750 console_select(keycode
- 0x02);
1754 case 0x3a: /* CapsLock */
1755 case 0x45: /* NumLock */
1757 vs
->modifiers_state
[keycode
] ^= 1;
1761 /* Turn off the lock state sync logic if the client support the led
1764 if (down
&& vs
->vd
->lock_key_sync
&&
1765 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1766 keycode_is_keypad(vs
->vd
->kbd_layout
, keycode
)) {
1767 /* If the numlock state needs to change then simulate an additional
1768 keypress before sending this one. This will happen if the user
1769 toggles numlock away from the VNC window.
1771 if (keysym_is_numlock(vs
->vd
->kbd_layout
, sym
& 0xFFFF)) {
1772 if (!vs
->modifiers_state
[0x45]) {
1773 trace_vnc_key_sync_numlock(true);
1774 vs
->modifiers_state
[0x45] = 1;
1775 press_key(vs
, 0xff7f);
1778 if (vs
->modifiers_state
[0x45]) {
1779 trace_vnc_key_sync_numlock(false);
1780 vs
->modifiers_state
[0x45] = 0;
1781 press_key(vs
, 0xff7f);
1786 if (down
&& vs
->vd
->lock_key_sync
&&
1787 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1788 ((sym
>= 'A' && sym
<= 'Z') || (sym
>= 'a' && sym
<= 'z'))) {
1789 /* If the capslock state needs to change then simulate an additional
1790 keypress before sending this one. This will happen if the user
1791 toggles capslock away from the VNC window.
1793 int uppercase
= !!(sym
>= 'A' && sym
<= 'Z');
1794 int shift
= !!(vs
->modifiers_state
[0x2a] | vs
->modifiers_state
[0x36]);
1795 int capslock
= !!(vs
->modifiers_state
[0x3a]);
1797 if (uppercase
== shift
) {
1798 trace_vnc_key_sync_capslock(false);
1799 vs
->modifiers_state
[0x3a] = 0;
1800 press_key(vs
, 0xffe5);
1803 if (uppercase
!= shift
) {
1804 trace_vnc_key_sync_capslock(true);
1805 vs
->modifiers_state
[0x3a] = 1;
1806 press_key(vs
, 0xffe5);
1811 if (qemu_console_is_graphic(NULL
)) {
1812 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, down
);
1813 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1815 bool numlock
= vs
->modifiers_state
[0x45];
1816 bool control
= (vs
->modifiers_state
[0x1d] ||
1817 vs
->modifiers_state
[0x9d]);
1818 /* QEMU console emulation */
1821 case 0x2a: /* Left Shift */
1822 case 0x36: /* Right Shift */
1823 case 0x1d: /* Left CTRL */
1824 case 0x9d: /* Right CTRL */
1825 case 0x38: /* Left ALT */
1826 case 0xb8: /* Right ALT */
1829 kbd_put_keysym(QEMU_KEY_UP
);
1832 kbd_put_keysym(QEMU_KEY_DOWN
);
1835 kbd_put_keysym(QEMU_KEY_LEFT
);
1838 kbd_put_keysym(QEMU_KEY_RIGHT
);
1841 kbd_put_keysym(QEMU_KEY_DELETE
);
1844 kbd_put_keysym(QEMU_KEY_HOME
);
1847 kbd_put_keysym(QEMU_KEY_END
);
1850 kbd_put_keysym(QEMU_KEY_PAGEUP
);
1853 kbd_put_keysym(QEMU_KEY_PAGEDOWN
);
1857 kbd_put_keysym(numlock
? '7' : QEMU_KEY_HOME
);
1860 kbd_put_keysym(numlock
? '8' : QEMU_KEY_UP
);
1863 kbd_put_keysym(numlock
? '9' : QEMU_KEY_PAGEUP
);
1866 kbd_put_keysym(numlock
? '4' : QEMU_KEY_LEFT
);
1869 kbd_put_keysym('5');
1872 kbd_put_keysym(numlock
? '6' : QEMU_KEY_RIGHT
);
1875 kbd_put_keysym(numlock
? '1' : QEMU_KEY_END
);
1878 kbd_put_keysym(numlock
? '2' : QEMU_KEY_DOWN
);
1881 kbd_put_keysym(numlock
? '3' : QEMU_KEY_PAGEDOWN
);
1884 kbd_put_keysym('0');
1887 kbd_put_keysym(numlock
? '.' : QEMU_KEY_DELETE
);
1891 kbd_put_keysym('/');
1894 kbd_put_keysym('*');
1897 kbd_put_keysym('-');
1900 kbd_put_keysym('+');
1903 kbd_put_keysym('\n');
1908 kbd_put_keysym(sym
& 0x1f);
1910 kbd_put_keysym(sym
);
1918 static void vnc_release_modifiers(VncState
*vs
)
1920 static const int keycodes
[] = {
1921 /* shift, control, alt keys, both left & right */
1922 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1926 if (!qemu_console_is_graphic(NULL
)) {
1929 for (i
= 0; i
< ARRAY_SIZE(keycodes
); i
++) {
1930 keycode
= keycodes
[i
];
1931 if (!vs
->modifiers_state
[keycode
]) {
1934 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1935 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1939 static const char *code2name(int keycode
)
1941 return QKeyCode_lookup
[qemu_input_key_number_to_qcode(keycode
)];
1944 static void key_event(VncState
*vs
, int down
, uint32_t sym
)
1949 if (lsym
>= 'A' && lsym
<= 'Z' && qemu_console_is_graphic(NULL
)) {
1950 lsym
= lsym
- 'A' + 'a';
1953 keycode
= keysym2scancode(vs
->vd
->kbd_layout
, lsym
& 0xFFFF) & SCANCODE_KEYMASK
;
1954 trace_vnc_key_event_map(down
, sym
, keycode
, code2name(keycode
));
1955 do_key_event(vs
, down
, keycode
, sym
);
1958 static void ext_key_event(VncState
*vs
, int down
,
1959 uint32_t sym
, uint16_t keycode
)
1961 /* if the user specifies a keyboard layout, always use it */
1962 if (keyboard_layout
) {
1963 key_event(vs
, down
, sym
);
1965 trace_vnc_key_event_ext(down
, sym
, keycode
, code2name(keycode
));
1966 do_key_event(vs
, down
, keycode
, sym
);
1970 static void framebuffer_update_request(VncState
*vs
, int incremental
,
1971 int x
, int y
, int w
, int h
)
1973 vs
->need_update
= 1;
1979 vs
->force_update
= 1;
1980 vnc_set_area_dirty(vs
->dirty
, vs
->vd
, x
, y
, w
, h
);
1983 static void send_ext_key_event_ack(VncState
*vs
)
1985 vnc_lock_output(vs
);
1986 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1987 vnc_write_u8(vs
, 0);
1988 vnc_write_u16(vs
, 1);
1989 vnc_framebuffer_update(vs
, 0, 0,
1990 pixman_image_get_width(vs
->vd
->server
),
1991 pixman_image_get_height(vs
->vd
->server
),
1992 VNC_ENCODING_EXT_KEY_EVENT
);
1993 vnc_unlock_output(vs
);
1997 static void send_ext_audio_ack(VncState
*vs
)
1999 vnc_lock_output(vs
);
2000 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2001 vnc_write_u8(vs
, 0);
2002 vnc_write_u16(vs
, 1);
2003 vnc_framebuffer_update(vs
, 0, 0,
2004 pixman_image_get_width(vs
->vd
->server
),
2005 pixman_image_get_height(vs
->vd
->server
),
2006 VNC_ENCODING_AUDIO
);
2007 vnc_unlock_output(vs
);
2011 static void set_encodings(VncState
*vs
, int32_t *encodings
, size_t n_encodings
)
2014 unsigned int enc
= 0;
2017 vs
->vnc_encoding
= 0;
2018 vs
->tight
.compression
= 9;
2019 vs
->tight
.quality
= -1; /* Lossless by default */
2023 * Start from the end because the encodings are sent in order of preference.
2024 * This way the preferred encoding (first encoding defined in the array)
2025 * will be set at the end of the loop.
2027 for (i
= n_encodings
- 1; i
>= 0; i
--) {
2030 case VNC_ENCODING_RAW
:
2031 vs
->vnc_encoding
= enc
;
2033 case VNC_ENCODING_COPYRECT
:
2034 vs
->features
|= VNC_FEATURE_COPYRECT_MASK
;
2036 case VNC_ENCODING_HEXTILE
:
2037 vs
->features
|= VNC_FEATURE_HEXTILE_MASK
;
2038 vs
->vnc_encoding
= enc
;
2040 case VNC_ENCODING_TIGHT
:
2041 vs
->features
|= VNC_FEATURE_TIGHT_MASK
;
2042 vs
->vnc_encoding
= enc
;
2044 #ifdef CONFIG_VNC_PNG
2045 case VNC_ENCODING_TIGHT_PNG
:
2046 vs
->features
|= VNC_FEATURE_TIGHT_PNG_MASK
;
2047 vs
->vnc_encoding
= enc
;
2050 case VNC_ENCODING_ZLIB
:
2051 vs
->features
|= VNC_FEATURE_ZLIB_MASK
;
2052 vs
->vnc_encoding
= enc
;
2054 case VNC_ENCODING_ZRLE
:
2055 vs
->features
|= VNC_FEATURE_ZRLE_MASK
;
2056 vs
->vnc_encoding
= enc
;
2058 case VNC_ENCODING_ZYWRLE
:
2059 vs
->features
|= VNC_FEATURE_ZYWRLE_MASK
;
2060 vs
->vnc_encoding
= enc
;
2062 case VNC_ENCODING_DESKTOPRESIZE
:
2063 vs
->features
|= VNC_FEATURE_RESIZE_MASK
;
2065 case VNC_ENCODING_POINTER_TYPE_CHANGE
:
2066 vs
->features
|= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK
;
2068 case VNC_ENCODING_RICH_CURSOR
:
2069 vs
->features
|= VNC_FEATURE_RICH_CURSOR_MASK
;
2070 if (vs
->vd
->cursor
) {
2071 vnc_cursor_define(vs
);
2074 case VNC_ENCODING_EXT_KEY_EVENT
:
2075 send_ext_key_event_ack(vs
);
2077 case VNC_ENCODING_AUDIO
:
2078 send_ext_audio_ack(vs
);
2080 case VNC_ENCODING_WMVi
:
2081 vs
->features
|= VNC_FEATURE_WMVI_MASK
;
2083 case VNC_ENCODING_LED_STATE
:
2084 vs
->features
|= VNC_FEATURE_LED_STATE_MASK
;
2086 case VNC_ENCODING_COMPRESSLEVEL0
... VNC_ENCODING_COMPRESSLEVEL0
+ 9:
2087 vs
->tight
.compression
= (enc
& 0x0F);
2089 case VNC_ENCODING_QUALITYLEVEL0
... VNC_ENCODING_QUALITYLEVEL0
+ 9:
2090 if (vs
->vd
->lossy
) {
2091 vs
->tight
.quality
= (enc
& 0x0F);
2095 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i
, enc
, enc
);
2099 vnc_desktop_resize(vs
);
2100 check_pointer_type_change(&vs
->mouse_mode_notifier
, NULL
);
2101 vnc_led_state_change(vs
);
2104 static void set_pixel_conversion(VncState
*vs
)
2106 pixman_format_code_t fmt
= qemu_pixman_get_format(&vs
->client_pf
);
2108 if (fmt
== VNC_SERVER_FB_FORMAT
) {
2109 vs
->write_pixels
= vnc_write_pixels_copy
;
2110 vnc_hextile_set_pixel_conversion(vs
, 0);
2112 vs
->write_pixels
= vnc_write_pixels_generic
;
2113 vnc_hextile_set_pixel_conversion(vs
, 1);
2117 static void send_color_map(VncState
*vs
)
2121 vnc_write_u8(vs
, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES
);
2122 vnc_write_u8(vs
, 0); /* padding */
2123 vnc_write_u16(vs
, 0); /* first color */
2124 vnc_write_u16(vs
, 256); /* # of colors */
2126 for (i
= 0; i
< 256; i
++) {
2127 PixelFormat
*pf
= &vs
->client_pf
;
2129 vnc_write_u16(vs
, (((i
>> pf
->rshift
) & pf
->rmax
) << (16 - pf
->rbits
)));
2130 vnc_write_u16(vs
, (((i
>> pf
->gshift
) & pf
->gmax
) << (16 - pf
->gbits
)));
2131 vnc_write_u16(vs
, (((i
>> pf
->bshift
) & pf
->bmax
) << (16 - pf
->bbits
)));
2135 static void set_pixel_format(VncState
*vs
, int bits_per_pixel
,
2136 int big_endian_flag
, int true_color_flag
,
2137 int red_max
, int green_max
, int blue_max
,
2138 int red_shift
, int green_shift
, int blue_shift
)
2140 if (!true_color_flag
) {
2141 /* Expose a reasonable default 256 color map */
2151 switch (bits_per_pixel
) {
2157 vnc_client_error(vs
);
2161 vs
->client_pf
.rmax
= red_max
? red_max
: 0xFF;
2162 vs
->client_pf
.rbits
= hweight_long(red_max
);
2163 vs
->client_pf
.rshift
= red_shift
;
2164 vs
->client_pf
.rmask
= red_max
<< red_shift
;
2165 vs
->client_pf
.gmax
= green_max
? green_max
: 0xFF;
2166 vs
->client_pf
.gbits
= hweight_long(green_max
);
2167 vs
->client_pf
.gshift
= green_shift
;
2168 vs
->client_pf
.gmask
= green_max
<< green_shift
;
2169 vs
->client_pf
.bmax
= blue_max
? blue_max
: 0xFF;
2170 vs
->client_pf
.bbits
= hweight_long(blue_max
);
2171 vs
->client_pf
.bshift
= blue_shift
;
2172 vs
->client_pf
.bmask
= blue_max
<< blue_shift
;
2173 vs
->client_pf
.bits_per_pixel
= bits_per_pixel
;
2174 vs
->client_pf
.bytes_per_pixel
= bits_per_pixel
/ 8;
2175 vs
->client_pf
.depth
= bits_per_pixel
== 32 ? 24 : bits_per_pixel
;
2176 vs
->client_be
= big_endian_flag
;
2178 if (!true_color_flag
) {
2182 set_pixel_conversion(vs
);
2184 graphic_hw_invalidate(vs
->vd
->dcl
.con
);
2185 graphic_hw_update(vs
->vd
->dcl
.con
);
2188 static void pixel_format_message (VncState
*vs
) {
2189 char pad
[3] = { 0, 0, 0 };
2191 vs
->client_pf
= qemu_default_pixelformat(32);
2193 vnc_write_u8(vs
, vs
->client_pf
.bits_per_pixel
); /* bits-per-pixel */
2194 vnc_write_u8(vs
, vs
->client_pf
.depth
); /* depth */
2196 #ifdef HOST_WORDS_BIGENDIAN
2197 vnc_write_u8(vs
, 1); /* big-endian-flag */
2199 vnc_write_u8(vs
, 0); /* big-endian-flag */
2201 vnc_write_u8(vs
, 1); /* true-color-flag */
2202 vnc_write_u16(vs
, vs
->client_pf
.rmax
); /* red-max */
2203 vnc_write_u16(vs
, vs
->client_pf
.gmax
); /* green-max */
2204 vnc_write_u16(vs
, vs
->client_pf
.bmax
); /* blue-max */
2205 vnc_write_u8(vs
, vs
->client_pf
.rshift
); /* red-shift */
2206 vnc_write_u8(vs
, vs
->client_pf
.gshift
); /* green-shift */
2207 vnc_write_u8(vs
, vs
->client_pf
.bshift
); /* blue-shift */
2208 vnc_write(vs
, pad
, 3); /* padding */
2210 vnc_hextile_set_pixel_conversion(vs
, 0);
2211 vs
->write_pixels
= vnc_write_pixels_copy
;
2214 static void vnc_colordepth(VncState
*vs
)
2216 if (vnc_has_feature(vs
, VNC_FEATURE_WMVI
)) {
2217 /* Sending a WMVi message to notify the client*/
2218 vnc_lock_output(vs
);
2219 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2220 vnc_write_u8(vs
, 0);
2221 vnc_write_u16(vs
, 1); /* number of rects */
2222 vnc_framebuffer_update(vs
, 0, 0,
2223 pixman_image_get_width(vs
->vd
->server
),
2224 pixman_image_get_height(vs
->vd
->server
),
2226 pixel_format_message(vs
);
2227 vnc_unlock_output(vs
);
2230 set_pixel_conversion(vs
);
2234 static int protocol_client_msg(VncState
*vs
, uint8_t *data
, size_t len
)
2238 VncDisplay
*vd
= vs
->vd
;
2241 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2245 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT
:
2249 set_pixel_format(vs
, read_u8(data
, 4),
2250 read_u8(data
, 6), read_u8(data
, 7),
2251 read_u16(data
, 8), read_u16(data
, 10),
2252 read_u16(data
, 12), read_u8(data
, 14),
2253 read_u8(data
, 15), read_u8(data
, 16));
2255 case VNC_MSG_CLIENT_SET_ENCODINGS
:
2260 limit
= read_u16(data
, 2);
2262 return 4 + (limit
* 4);
2264 limit
= read_u16(data
, 2);
2266 for (i
= 0; i
< limit
; i
++) {
2267 int32_t val
= read_s32(data
, 4 + (i
* 4));
2268 memcpy(data
+ 4 + (i
* 4), &val
, sizeof(val
));
2271 set_encodings(vs
, (int32_t *)(data
+ 4), limit
);
2273 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST
:
2277 framebuffer_update_request(vs
,
2278 read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4),
2279 read_u16(data
, 6), read_u16(data
, 8));
2281 case VNC_MSG_CLIENT_KEY_EVENT
:
2285 key_event(vs
, read_u8(data
, 1), read_u32(data
, 4));
2287 case VNC_MSG_CLIENT_POINTER_EVENT
:
2291 pointer_event(vs
, read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4));
2293 case VNC_MSG_CLIENT_CUT_TEXT
:
2298 uint32_t dlen
= read_u32(data
, 4);
2299 if (dlen
> (1 << 20)) {
2300 error_report("vnc: client_cut_text msg payload has %u bytes"
2301 " which exceeds our limit of 1MB.", dlen
);
2302 vnc_client_error(vs
);
2310 client_cut_text(vs
, read_u32(data
, 4), data
+ 8);
2312 case VNC_MSG_CLIENT_QEMU
:
2316 switch (read_u8(data
, 1)) {
2317 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT
:
2321 ext_key_event(vs
, read_u16(data
, 2),
2322 read_u32(data
, 4), read_u32(data
, 8));
2324 case VNC_MSG_CLIENT_QEMU_AUDIO
:
2328 switch (read_u16 (data
, 2)) {
2329 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE
:
2332 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE
:
2335 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT
:
2338 switch (read_u8(data
, 4)) {
2339 case 0: vs
->as
.fmt
= AUD_FMT_U8
; break;
2340 case 1: vs
->as
.fmt
= AUD_FMT_S8
; break;
2341 case 2: vs
->as
.fmt
= AUD_FMT_U16
; break;
2342 case 3: vs
->as
.fmt
= AUD_FMT_S16
; break;
2343 case 4: vs
->as
.fmt
= AUD_FMT_U32
; break;
2344 case 5: vs
->as
.fmt
= AUD_FMT_S32
; break;
2346 VNC_DEBUG("Invalid audio format %d\n", read_u8(data
, 4));
2347 vnc_client_error(vs
);
2350 vs
->as
.nchannels
= read_u8(data
, 5);
2351 if (vs
->as
.nchannels
!= 1 && vs
->as
.nchannels
!= 2) {
2352 VNC_DEBUG("Invalid audio channel coount %d\n",
2354 vnc_client_error(vs
);
2357 vs
->as
.freq
= read_u32(data
, 6);
2360 VNC_DEBUG("Invalid audio message %d\n", read_u8(data
, 4));
2361 vnc_client_error(vs
);
2367 VNC_DEBUG("Msg: %d\n", read_u16(data
, 0));
2368 vnc_client_error(vs
);
2373 VNC_DEBUG("Msg: %d\n", data
[0]);
2374 vnc_client_error(vs
);
2378 vnc_read_when(vs
, protocol_client_msg
, 1);
2382 static int protocol_client_init(VncState
*vs
, uint8_t *data
, size_t len
)
2388 mode
= data
[0] ? VNC_SHARE_MODE_SHARED
: VNC_SHARE_MODE_EXCLUSIVE
;
2389 switch (vs
->vd
->share_policy
) {
2390 case VNC_SHARE_POLICY_IGNORE
:
2392 * Ignore the shared flag. Nothing to do here.
2394 * Doesn't conform to the rfb spec but is traditional qemu
2395 * behavior, thus left here as option for compatibility
2399 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
:
2401 * Policy: Allow clients ask for exclusive access.
2403 * Implementation: When a client asks for exclusive access,
2404 * disconnect all others. Shared connects are allowed as long
2405 * as no exclusive connection exists.
2407 * This is how the rfb spec suggests to handle the shared flag.
2409 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2411 QTAILQ_FOREACH(client
, &vs
->vd
->clients
, next
) {
2415 if (client
->share_mode
!= VNC_SHARE_MODE_EXCLUSIVE
&&
2416 client
->share_mode
!= VNC_SHARE_MODE_SHARED
) {
2419 vnc_disconnect_start(client
);
2422 if (mode
== VNC_SHARE_MODE_SHARED
) {
2423 if (vs
->vd
->num_exclusive
> 0) {
2424 vnc_disconnect_start(vs
);
2429 case VNC_SHARE_POLICY_FORCE_SHARED
:
2431 * Policy: Shared connects only.
2432 * Implementation: Disallow clients asking for exclusive access.
2434 * Useful for shared desktop sessions where you don't want
2435 * someone forgetting to say -shared when running the vnc
2436 * client disconnect everybody else.
2438 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2439 vnc_disconnect_start(vs
);
2444 vnc_set_share_mode(vs
, mode
);
2446 if (vs
->vd
->num_shared
> vs
->vd
->connections_limit
) {
2447 vnc_disconnect_start(vs
);
2451 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
2452 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
2453 vnc_write_u16(vs
, vs
->client_width
);
2454 vnc_write_u16(vs
, vs
->client_height
);
2456 pixel_format_message(vs
);
2459 size
= snprintf(buf
, sizeof(buf
), "QEMU (%s)", qemu_name
);
2461 size
= snprintf(buf
, sizeof(buf
), "QEMU");
2463 vnc_write_u32(vs
, size
);
2464 vnc_write(vs
, buf
, size
);
2467 vnc_client_cache_auth(vs
);
2468 vnc_qmp_event(vs
, QAPI_EVENT_VNC_INITIALIZED
);
2470 vnc_read_when(vs
, protocol_client_msg
, 1);
2475 void start_client_init(VncState
*vs
)
2477 vnc_read_when(vs
, protocol_client_init
, 1);
2480 static void make_challenge(VncState
*vs
)
2484 srand(time(NULL
)+getpid()+getpid()*987654+rand());
2486 for (i
= 0 ; i
< sizeof(vs
->challenge
) ; i
++)
2487 vs
->challenge
[i
] = (int) (256.0*rand()/(RAND_MAX
+1.0));
2490 static int protocol_client_auth_vnc(VncState
*vs
, uint8_t *data
, size_t len
)
2492 unsigned char response
[VNC_AUTH_CHALLENGE_SIZE
];
2494 unsigned char key
[8];
2495 time_t now
= time(NULL
);
2496 QCryptoCipher
*cipher
= NULL
;
2499 if (!vs
->vd
->password
) {
2500 VNC_DEBUG("No password configured on server");
2503 if (vs
->vd
->expires
< now
) {
2504 VNC_DEBUG("Password is expired");
2508 memcpy(response
, vs
->challenge
, VNC_AUTH_CHALLENGE_SIZE
);
2510 /* Calculate the expected challenge response */
2511 pwlen
= strlen(vs
->vd
->password
);
2512 for (i
=0; i
<sizeof(key
); i
++)
2513 key
[i
] = i
<pwlen
? vs
->vd
->password
[i
] : 0;
2515 cipher
= qcrypto_cipher_new(
2516 QCRYPTO_CIPHER_ALG_DES_RFB
,
2517 QCRYPTO_CIPHER_MODE_ECB
,
2518 key
, G_N_ELEMENTS(key
),
2521 VNC_DEBUG("Cannot initialize cipher %s",
2522 error_get_pretty(err
));
2527 if (qcrypto_cipher_encrypt(cipher
,
2530 VNC_AUTH_CHALLENGE_SIZE
,
2532 VNC_DEBUG("Cannot encrypt challenge %s",
2533 error_get_pretty(err
));
2538 /* Compare expected vs actual challenge response */
2539 if (memcmp(response
, data
, VNC_AUTH_CHALLENGE_SIZE
) != 0) {
2540 VNC_DEBUG("Client challenge response did not match\n");
2543 VNC_DEBUG("Accepting VNC challenge response\n");
2544 vnc_write_u32(vs
, 0); /* Accept auth */
2547 start_client_init(vs
);
2550 qcrypto_cipher_free(cipher
);
2554 vnc_write_u32(vs
, 1); /* Reject auth */
2555 if (vs
->minor
>= 8) {
2556 static const char err
[] = "Authentication failed";
2557 vnc_write_u32(vs
, sizeof(err
));
2558 vnc_write(vs
, err
, sizeof(err
));
2561 vnc_client_error(vs
);
2562 qcrypto_cipher_free(cipher
);
2566 void start_auth_vnc(VncState
*vs
)
2569 /* Send client a 'random' challenge */
2570 vnc_write(vs
, vs
->challenge
, sizeof(vs
->challenge
));
2573 vnc_read_when(vs
, protocol_client_auth_vnc
, sizeof(vs
->challenge
));
2577 static int protocol_client_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2579 /* We only advertise 1 auth scheme at a time, so client
2580 * must pick the one we sent. Verify this */
2581 if (data
[0] != vs
->auth
) { /* Reject auth */
2582 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data
[0]);
2583 vnc_write_u32(vs
, 1);
2584 if (vs
->minor
>= 8) {
2585 static const char err
[] = "Authentication failed";
2586 vnc_write_u32(vs
, sizeof(err
));
2587 vnc_write(vs
, err
, sizeof(err
));
2589 vnc_client_error(vs
);
2590 } else { /* Accept requested auth */
2591 VNC_DEBUG("Client requested auth %d\n", (int)data
[0]);
2594 VNC_DEBUG("Accept auth none\n");
2595 if (vs
->minor
>= 8) {
2596 vnc_write_u32(vs
, 0); /* Accept auth completion */
2599 start_client_init(vs
);
2603 VNC_DEBUG("Start VNC auth\n");
2607 case VNC_AUTH_VENCRYPT
:
2608 VNC_DEBUG("Accept VeNCrypt auth\n");
2609 start_auth_vencrypt(vs
);
2612 #ifdef CONFIG_VNC_SASL
2614 VNC_DEBUG("Accept SASL auth\n");
2615 start_auth_sasl(vs
);
2617 #endif /* CONFIG_VNC_SASL */
2619 default: /* Should not be possible, but just in case */
2620 VNC_DEBUG("Reject auth %d server code bug\n", vs
->auth
);
2621 vnc_write_u8(vs
, 1);
2622 if (vs
->minor
>= 8) {
2623 static const char err
[] = "Authentication failed";
2624 vnc_write_u32(vs
, sizeof(err
));
2625 vnc_write(vs
, err
, sizeof(err
));
2627 vnc_client_error(vs
);
2633 static int protocol_version(VncState
*vs
, uint8_t *version
, size_t len
)
2637 memcpy(local
, version
, 12);
2640 if (sscanf(local
, "RFB %03d.%03d\n", &vs
->major
, &vs
->minor
) != 2) {
2641 VNC_DEBUG("Malformed protocol version %s\n", local
);
2642 vnc_client_error(vs
);
2645 VNC_DEBUG("Client request protocol version %d.%d\n", vs
->major
, vs
->minor
);
2646 if (vs
->major
!= 3 ||
2652 VNC_DEBUG("Unsupported client version\n");
2653 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2655 vnc_client_error(vs
);
2658 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2659 * as equivalent to v3.3 by servers
2661 if (vs
->minor
== 4 || vs
->minor
== 5)
2664 if (vs
->minor
== 3) {
2665 if (vs
->auth
== VNC_AUTH_NONE
) {
2666 VNC_DEBUG("Tell client auth none\n");
2667 vnc_write_u32(vs
, vs
->auth
);
2669 start_client_init(vs
);
2670 } else if (vs
->auth
== VNC_AUTH_VNC
) {
2671 VNC_DEBUG("Tell client VNC auth\n");
2672 vnc_write_u32(vs
, vs
->auth
);
2676 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs
->auth
);
2677 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2679 vnc_client_error(vs
);
2682 VNC_DEBUG("Telling client we support auth %d\n", vs
->auth
);
2683 vnc_write_u8(vs
, 1); /* num auth */
2684 vnc_write_u8(vs
, vs
->auth
);
2685 vnc_read_when(vs
, protocol_client_auth
, 1);
2692 static VncRectStat
*vnc_stat_rect(VncDisplay
*vd
, int x
, int y
)
2694 struct VncSurface
*vs
= &vd
->guest
;
2696 return &vs
->stats
[y
/ VNC_STAT_RECT
][x
/ VNC_STAT_RECT
];
2699 void vnc_sent_lossy_rect(VncState
*vs
, int x
, int y
, int w
, int h
)
2703 w
= (x
+ w
) / VNC_STAT_RECT
;
2704 h
= (y
+ h
) / VNC_STAT_RECT
;
2708 for (j
= y
; j
<= h
; j
++) {
2709 for (i
= x
; i
<= w
; i
++) {
2710 vs
->lossy_rect
[j
][i
] = 1;
2715 static int vnc_refresh_lossy_rect(VncDisplay
*vd
, int x
, int y
)
2718 int sty
= y
/ VNC_STAT_RECT
;
2719 int stx
= x
/ VNC_STAT_RECT
;
2722 y
= y
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2723 x
= x
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2725 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2728 /* kernel send buffers are full -> refresh later */
2729 if (vs
->output
.offset
) {
2733 if (!vs
->lossy_rect
[sty
][stx
]) {
2737 vs
->lossy_rect
[sty
][stx
] = 0;
2738 for (j
= 0; j
< VNC_STAT_RECT
; ++j
) {
2739 bitmap_set(vs
->dirty
[y
+ j
],
2740 x
/ VNC_DIRTY_PIXELS_PER_BIT
,
2741 VNC_STAT_RECT
/ VNC_DIRTY_PIXELS_PER_BIT
);
2749 static int vnc_update_stats(VncDisplay
*vd
, struct timeval
* tv
)
2751 int width
= pixman_image_get_width(vd
->guest
.fb
);
2752 int height
= pixman_image_get_height(vd
->guest
.fb
);
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
);
2761 rect
->updated
= false;
2765 qemu_timersub(tv
, &VNC_REFRESH_STATS
, &res
);
2767 if (timercmp(&vd
->guest
.last_freq_check
, &res
, >)) {
2770 vd
->guest
.last_freq_check
= *tv
;
2772 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2773 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2774 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2775 int count
= ARRAY_SIZE(rect
->times
);
2776 struct timeval min
, max
;
2778 if (!timerisset(&rect
->times
[count
- 1])) {
2782 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2783 qemu_timersub(tv
, &max
, &res
);
2785 if (timercmp(&res
, &VNC_REFRESH_LOSSY
, >)) {
2787 has_dirty
+= vnc_refresh_lossy_rect(vd
, x
, y
);
2788 memset(rect
->times
, 0, sizeof (rect
->times
));
2792 min
= rect
->times
[rect
->idx
];
2793 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2794 qemu_timersub(&max
, &min
, &res
);
2796 rect
->freq
= res
.tv_sec
+ res
.tv_usec
/ 1000000.;
2797 rect
->freq
/= count
;
2798 rect
->freq
= 1. / rect
->freq
;
2804 double vnc_update_freq(VncState
*vs
, int x
, int y
, int w
, int h
)
2810 x
= (x
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2811 y
= (y
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2813 for (j
= y
; j
<= y
+ h
; j
+= VNC_STAT_RECT
) {
2814 for (i
= x
; i
<= x
+ w
; i
+= VNC_STAT_RECT
) {
2815 total
+= vnc_stat_rect(vs
->vd
, i
, j
)->freq
;
2827 static void vnc_rect_updated(VncDisplay
*vd
, int x
, int y
, struct timeval
* tv
)
2831 rect
= vnc_stat_rect(vd
, x
, y
);
2832 if (rect
->updated
) {
2835 rect
->times
[rect
->idx
] = *tv
;
2836 rect
->idx
= (rect
->idx
+ 1) % ARRAY_SIZE(rect
->times
);
2837 rect
->updated
= true;
2840 static int vnc_refresh_server_surface(VncDisplay
*vd
)
2842 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2843 pixman_image_get_width(vd
->server
));
2844 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2845 pixman_image_get_height(vd
->server
));
2846 int cmp_bytes
, server_stride
, line_bytes
, guest_ll
, guest_stride
, y
= 0;
2847 uint8_t *guest_row0
= NULL
, *server_row0
;
2850 pixman_image_t
*tmpbuf
= NULL
;
2852 struct timeval tv
= { 0, 0 };
2854 if (!vd
->non_adaptive
) {
2855 gettimeofday(&tv
, NULL
);
2856 has_dirty
= vnc_update_stats(vd
, &tv
);
2860 * Walk through the guest dirty map.
2861 * Check and copy modified bits from guest to server surface.
2862 * Update server dirty map.
2864 server_row0
= (uint8_t *)pixman_image_get_data(vd
->server
);
2865 server_stride
= guest_stride
= guest_ll
=
2866 pixman_image_get_stride(vd
->server
);
2867 cmp_bytes
= MIN(VNC_DIRTY_PIXELS_PER_BIT
* VNC_SERVER_FB_BYTES
,
2869 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2870 int width
= pixman_image_get_width(vd
->server
);
2871 tmpbuf
= qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT
, width
);
2874 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd
->guest
.fb
));
2875 guest_row0
= (uint8_t *)pixman_image_get_data(vd
->guest
.fb
);
2876 guest_stride
= pixman_image_get_stride(vd
->guest
.fb
);
2877 guest_ll
= pixman_image_get_width(vd
->guest
.fb
) * ((guest_bpp
+ 7) / 8);
2879 line_bytes
= MIN(server_stride
, guest_ll
);
2883 uint8_t *guest_ptr
, *server_ptr
;
2884 unsigned long offset
= find_next_bit((unsigned long *) &vd
->guest
.dirty
,
2885 height
* VNC_DIRTY_BPL(&vd
->guest
),
2886 y
* VNC_DIRTY_BPL(&vd
->guest
));
2887 if (offset
== height
* VNC_DIRTY_BPL(&vd
->guest
)) {
2888 /* no more dirty bits */
2891 y
= offset
/ VNC_DIRTY_BPL(&vd
->guest
);
2892 x
= offset
% VNC_DIRTY_BPL(&vd
->guest
);
2894 server_ptr
= server_row0
+ y
* server_stride
+ x
* cmp_bytes
;
2896 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2897 qemu_pixman_linebuf_fill(tmpbuf
, vd
->guest
.fb
, width
, 0, y
);
2898 guest_ptr
= (uint8_t *)pixman_image_get_data(tmpbuf
);
2900 guest_ptr
= guest_row0
+ y
* guest_stride
;
2902 guest_ptr
+= x
* cmp_bytes
;
2904 for (; x
< DIV_ROUND_UP(width
, VNC_DIRTY_PIXELS_PER_BIT
);
2905 x
++, guest_ptr
+= cmp_bytes
, server_ptr
+= cmp_bytes
) {
2906 int _cmp_bytes
= cmp_bytes
;
2907 if (!test_and_clear_bit(x
, vd
->guest
.dirty
[y
])) {
2910 if ((x
+ 1) * cmp_bytes
> line_bytes
) {
2911 _cmp_bytes
= line_bytes
- x
* cmp_bytes
;
2913 assert(_cmp_bytes
>= 0);
2914 if (memcmp(server_ptr
, guest_ptr
, _cmp_bytes
) == 0) {
2917 memcpy(server_ptr
, guest_ptr
, _cmp_bytes
);
2918 if (!vd
->non_adaptive
) {
2919 vnc_rect_updated(vd
, x
* VNC_DIRTY_PIXELS_PER_BIT
,
2922 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2923 set_bit(x
, vs
->dirty
[y
]);
2930 qemu_pixman_image_unref(tmpbuf
);
2934 static void vnc_refresh(DisplayChangeListener
*dcl
)
2936 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
2938 int has_dirty
, rects
= 0;
2940 if (QTAILQ_EMPTY(&vd
->clients
)) {
2941 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_MAX
);
2945 graphic_hw_update(vd
->dcl
.con
);
2947 if (vnc_trylock_display(vd
)) {
2948 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2952 has_dirty
= vnc_refresh_server_surface(vd
);
2953 vnc_unlock_display(vd
);
2955 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
2956 rects
+= vnc_update_client(vs
, has_dirty
, false);
2957 /* vs might be free()ed here */
2960 if (has_dirty
&& rects
) {
2961 vd
->dcl
.update_interval
/= 2;
2962 if (vd
->dcl
.update_interval
< VNC_REFRESH_INTERVAL_BASE
) {
2963 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_BASE
;
2966 vd
->dcl
.update_interval
+= VNC_REFRESH_INTERVAL_INC
;
2967 if (vd
->dcl
.update_interval
> VNC_REFRESH_INTERVAL_MAX
) {
2968 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_MAX
;
2973 static void vnc_connect(VncDisplay
*vd
, QIOChannelSocket
*sioc
,
2974 bool skipauth
, bool websocket
)
2976 VncState
*vs
= g_new0(VncState
, 1);
2980 object_ref(OBJECT(vs
->sioc
));
2981 vs
->ioc
= QIO_CHANNEL(sioc
);
2982 object_ref(OBJECT(vs
->ioc
));
2985 buffer_init(&vs
->input
, "vnc-input/%p", sioc
);
2986 buffer_init(&vs
->output
, "vnc-output/%p", sioc
);
2987 buffer_init(&vs
->jobs_buffer
, "vnc-jobs_buffer/%p", sioc
);
2989 buffer_init(&vs
->tight
.tight
, "vnc-tight/%p", sioc
);
2990 buffer_init(&vs
->tight
.zlib
, "vnc-tight-zlib/%p", sioc
);
2991 buffer_init(&vs
->tight
.gradient
, "vnc-tight-gradient/%p", sioc
);
2992 #ifdef CONFIG_VNC_JPEG
2993 buffer_init(&vs
->tight
.jpeg
, "vnc-tight-jpeg/%p", sioc
);
2995 #ifdef CONFIG_VNC_PNG
2996 buffer_init(&vs
->tight
.png
, "vnc-tight-png/%p", sioc
);
2998 buffer_init(&vs
->zlib
.zlib
, "vnc-zlib/%p", sioc
);
2999 buffer_init(&vs
->zrle
.zrle
, "vnc-zrle/%p", sioc
);
3000 buffer_init(&vs
->zrle
.fb
, "vnc-zrle-fb/%p", sioc
);
3001 buffer_init(&vs
->zrle
.zlib
, "vnc-zrle-zlib/%p", sioc
);
3004 vs
->auth
= VNC_AUTH_NONE
;
3005 vs
->subauth
= VNC_AUTH_INVALID
;
3008 vs
->auth
= vd
->ws_auth
;
3009 vs
->subauth
= VNC_AUTH_INVALID
;
3011 vs
->auth
= vd
->auth
;
3012 vs
->subauth
= vd
->subauth
;
3015 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
3016 sioc
, websocket
, vs
->auth
, vs
->subauth
);
3018 vs
->lossy_rect
= g_malloc0(VNC_STAT_ROWS
* sizeof (*vs
->lossy_rect
));
3019 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
3020 vs
->lossy_rect
[i
] = g_new0(uint8_t, VNC_STAT_COLS
);
3023 VNC_DEBUG("New client on socket %p\n", vs
->sioc
);
3024 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
3025 qio_channel_set_blocking(vs
->ioc
, false, NULL
);
3029 vs
->ioc_tag
= qio_channel_add_watch(
3030 vs
->ioc
, G_IO_IN
, vncws_tls_handshake_io
, vs
, NULL
);
3032 vs
->ioc_tag
= qio_channel_add_watch(
3033 vs
->ioc
, G_IO_IN
, vncws_handshake_io
, vs
, NULL
);
3036 vs
->ioc_tag
= qio_channel_add_watch(
3037 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
3040 vnc_client_cache_addr(vs
);
3041 vnc_qmp_event(vs
, QAPI_EVENT_VNC_CONNECTED
);
3042 vnc_set_share_mode(vs
, VNC_SHARE_MODE_CONNECTING
);
3044 if (!vs
->websocket
) {
3048 if (vd
->num_connecting
> vd
->connections_limit
) {
3049 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
3050 if (vs
->share_mode
== VNC_SHARE_MODE_CONNECTING
) {
3051 vnc_disconnect_start(vs
);
3058 void vnc_init_state(VncState
*vs
)
3060 vs
->initialized
= true;
3061 VncDisplay
*vd
= vs
->vd
;
3062 bool first_client
= QTAILQ_EMPTY(&vd
->clients
);
3067 vs
->as
.freq
= 44100;
3068 vs
->as
.nchannels
= 2;
3069 vs
->as
.fmt
= AUD_FMT_S16
;
3070 vs
->as
.endianness
= 0;
3072 qemu_mutex_init(&vs
->output_mutex
);
3073 vs
->bh
= qemu_bh_new(vnc_jobs_bh
, vs
);
3075 QTAILQ_INSERT_TAIL(&vd
->clients
, vs
, next
);
3077 vnc_update_server_surface(vd
);
3080 graphic_hw_update(vd
->dcl
.con
);
3082 vnc_write(vs
, "RFB 003.008\n", 12);
3084 vnc_read_when(vs
, protocol_version
, 12);
3086 if (vs
->vd
->lock_key_sync
)
3087 vs
->led
= qemu_add_led_event_handler(kbd_leds
, vs
);
3089 vs
->mouse_mode_notifier
.notify
= check_pointer_type_change
;
3090 qemu_add_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
3092 /* vs might be free()ed here */
3095 static gboolean
vnc_listen_io(QIOChannel
*ioc
,
3096 GIOCondition condition
,
3099 VncDisplay
*vs
= opaque
;
3100 QIOChannelSocket
*sioc
= NULL
;
3104 graphic_hw_update(vs
->dcl
.con
);
3105 sioc
= qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc
), &err
);
3107 qio_channel_set_delay(QIO_CHANNEL(sioc
), false);
3108 vnc_connect(vs
, sioc
, false,
3109 ioc
!= QIO_CHANNEL(vs
->lsock
));
3110 object_unref(OBJECT(sioc
));
3112 /* client probably closed connection before we got there */
3119 static const DisplayChangeListenerOps dcl_ops
= {
3121 .dpy_refresh
= vnc_refresh
,
3122 .dpy_gfx_copy
= vnc_dpy_copy
,
3123 .dpy_gfx_update
= vnc_dpy_update
,
3124 .dpy_gfx_switch
= vnc_dpy_switch
,
3125 .dpy_gfx_check_format
= qemu_pixman_check_format
,
3126 .dpy_mouse_set
= vnc_mouse_set
,
3127 .dpy_cursor_define
= vnc_dpy_cursor_define
,
3130 void vnc_display_init(const char *id
)
3134 if (vnc_display_find(id
) != NULL
) {
3137 vs
= g_malloc0(sizeof(*vs
));
3139 vs
->id
= strdup(id
);
3140 QTAILQ_INSERT_TAIL(&vnc_displays
, vs
, next
);
3142 QTAILQ_INIT(&vs
->clients
);
3143 vs
->expires
= TIME_MAX
;
3145 if (keyboard_layout
) {
3146 trace_vnc_key_map_init(keyboard_layout
);
3147 vs
->kbd_layout
= init_keyboard_layout(name2keysym
, keyboard_layout
);
3149 vs
->kbd_layout
= init_keyboard_layout(name2keysym
, "en-us");
3152 if (!vs
->kbd_layout
)
3155 vs
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3156 vs
->connections_limit
= 32;
3158 qemu_mutex_init(&vs
->mutex
);
3159 vnc_start_worker_thread();
3161 vs
->dcl
.ops
= &dcl_ops
;
3162 register_displaychangelistener(&vs
->dcl
);
3166 static void vnc_display_close(VncDisplay
*vs
)
3170 vs
->enabled
= false;
3171 vs
->is_unix
= false;
3172 if (vs
->lsock
!= NULL
) {
3173 if (vs
->lsock_tag
) {
3174 g_source_remove(vs
->lsock_tag
);
3176 object_unref(OBJECT(vs
->lsock
));
3179 vs
->ws_enabled
= false;
3180 if (vs
->lwebsock
!= NULL
) {
3181 if (vs
->lwebsock_tag
) {
3182 g_source_remove(vs
->lwebsock_tag
);
3184 object_unref(OBJECT(vs
->lwebsock
));
3185 vs
->lwebsock
= NULL
;
3187 vs
->auth
= VNC_AUTH_INVALID
;
3188 vs
->subauth
= VNC_AUTH_INVALID
;
3190 object_unparent(OBJECT(vs
->tlscreds
));
3191 vs
->tlscreds
= NULL
;
3193 g_free(vs
->tlsaclname
);
3194 vs
->tlsaclname
= NULL
;
3197 int vnc_display_password(const char *id
, const char *password
)
3199 VncDisplay
*vs
= vnc_display_find(id
);
3204 if (vs
->auth
== VNC_AUTH_NONE
) {
3205 error_printf_unless_qmp("If you want use passwords please enable "
3206 "password auth using '-vnc ${dpy},password'.\n");
3210 g_free(vs
->password
);
3211 vs
->password
= g_strdup(password
);
3216 int vnc_display_pw_expire(const char *id
, time_t expires
)
3218 VncDisplay
*vs
= vnc_display_find(id
);
3224 vs
->expires
= expires
;
3228 static void vnc_display_print_local_addr(VncDisplay
*vs
)
3230 SocketAddress
*addr
;
3233 addr
= qio_channel_socket_get_local_address(vs
->lsock
, &err
);
3238 if (addr
->type
!= SOCKET_ADDRESS_KIND_INET
) {
3239 qapi_free_SocketAddress(addr
);
3242 error_printf_unless_qmp("VNC server running on %s:%s\n",
3243 addr
->u
.inet
.data
->host
,
3244 addr
->u
.inet
.data
->port
);
3245 qapi_free_SocketAddress(addr
);
3248 static QemuOptsList qemu_vnc_opts
= {
3250 .head
= QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts
.head
),
3251 .implied_opt_name
= "vnc",
3255 .type
= QEMU_OPT_STRING
,
3257 .name
= "websocket",
3258 .type
= QEMU_OPT_STRING
,
3260 .name
= "tls-creds",
3261 .type
= QEMU_OPT_STRING
,
3263 /* Deprecated in favour of tls-creds */
3265 .type
= QEMU_OPT_STRING
,
3268 .type
= QEMU_OPT_STRING
,
3271 .type
= QEMU_OPT_STRING
,
3274 .type
= QEMU_OPT_NUMBER
,
3276 .name
= "connections",
3277 .type
= QEMU_OPT_NUMBER
,
3280 .type
= QEMU_OPT_NUMBER
,
3283 .type
= QEMU_OPT_BOOL
,
3286 .type
= QEMU_OPT_BOOL
,
3289 .type
= QEMU_OPT_BOOL
,
3292 .type
= QEMU_OPT_BOOL
,
3294 .name
= "lock-key-sync",
3295 .type
= QEMU_OPT_BOOL
,
3297 .name
= "key-delay-ms",
3298 .type
= QEMU_OPT_NUMBER
,
3301 .type
= QEMU_OPT_BOOL
,
3303 /* Deprecated in favour of tls-creds */
3305 .type
= QEMU_OPT_BOOL
,
3307 /* Deprecated in favour of tls-creds */
3308 .name
= "x509verify",
3309 .type
= QEMU_OPT_STRING
,
3312 .type
= QEMU_OPT_BOOL
,
3315 .type
= QEMU_OPT_BOOL
,
3317 .name
= "non-adaptive",
3318 .type
= QEMU_OPT_BOOL
,
3320 { /* end of list */ }
3326 vnc_display_setup_auth(VncDisplay
*vs
,
3333 * We have a choice of 3 authentication options
3339 * The channel can be run in 2 modes
3344 * And TLS can use 2 types of credentials
3349 * We thus have 9 possible logical combinations
3354 * 4. tls + anon + none
3355 * 5. tls + anon + vnc
3356 * 6. tls + anon + sasl
3357 * 7. tls + x509 + none
3358 * 8. tls + x509 + vnc
3359 * 9. tls + x509 + sasl
3361 * These need to be mapped into the VNC auth schemes
3362 * in an appropriate manner. In regular VNC, all the
3363 * TLS options get mapped into VNC_AUTH_VENCRYPT
3366 * In websockets, the https:// protocol already provides
3367 * TLS support, so there is no need to make use of the
3368 * VeNCrypt extension. Furthermore, websockets browser
3369 * clients could not use VeNCrypt even if they wanted to,
3370 * as they cannot control when the TLS handshake takes
3371 * place. Thus there is no option but to rely on https://,
3372 * meaning combinations 4->6 and 7->9 will be mapped to
3373 * VNC auth schemes in the same way as combos 1->3.
3375 * Regardless of fact that we have a different mapping to
3376 * VNC auth mechs for plain VNC vs websockets VNC, the end
3377 * result has the same security characteristics.
3381 vs
->auth
= VNC_AUTH_VENCRYPT
;
3385 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3386 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3387 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3388 vs
->subauth
= VNC_AUTH_VENCRYPT_X509VNC
;
3389 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3390 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3391 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3392 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSVNC
;
3395 "Unsupported TLS cred type %s",
3396 object_get_typename(OBJECT(vs
->tlscreds
)));
3400 VNC_DEBUG("Initializing VNC server with password auth\n");
3401 vs
->auth
= VNC_AUTH_VNC
;
3402 vs
->subauth
= VNC_AUTH_INVALID
;
3405 vs
->ws_auth
= VNC_AUTH_VNC
;
3407 vs
->ws_auth
= VNC_AUTH_INVALID
;
3411 vs
->auth
= VNC_AUTH_VENCRYPT
;
3415 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3416 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3417 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3418 vs
->subauth
= VNC_AUTH_VENCRYPT_X509SASL
;
3419 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3420 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3421 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3422 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSSASL
;
3425 "Unsupported TLS cred type %s",
3426 object_get_typename(OBJECT(vs
->tlscreds
)));
3430 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3431 vs
->auth
= VNC_AUTH_SASL
;
3432 vs
->subauth
= VNC_AUTH_INVALID
;
3435 vs
->ws_auth
= VNC_AUTH_SASL
;
3437 vs
->ws_auth
= VNC_AUTH_INVALID
;
3441 vs
->auth
= VNC_AUTH_VENCRYPT
;
3445 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3446 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3447 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3448 vs
->subauth
= VNC_AUTH_VENCRYPT_X509NONE
;
3449 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3450 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3451 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3452 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSNONE
;
3455 "Unsupported TLS cred type %s",
3456 object_get_typename(OBJECT(vs
->tlscreds
)));
3460 VNC_DEBUG("Initializing VNC server with no auth\n");
3461 vs
->auth
= VNC_AUTH_NONE
;
3462 vs
->subauth
= VNC_AUTH_INVALID
;
3465 vs
->ws_auth
= VNC_AUTH_NONE
;
3467 vs
->ws_auth
= VNC_AUTH_INVALID
;
3475 * Handle back compat with old CLI syntax by creating some
3476 * suitable QCryptoTLSCreds objects
3478 static QCryptoTLSCreds
*
3479 vnc_display_create_creds(bool x509
,
3485 gchar
*credsid
= g_strdup_printf("tlsvnc%s", id
);
3486 Object
*parent
= object_get_objects_root();
3491 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509
,
3495 "endpoint", "server",
3497 "verify-peer", x509verify
? "yes" : "no",
3500 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON
,
3504 "endpoint", "server",
3511 error_propagate(errp
, err
);
3515 return QCRYPTO_TLS_CREDS(creds
);
3519 void vnc_display_open(const char *id
, Error
**errp
)
3521 VncDisplay
*vs
= vnc_display_find(id
);
3522 QemuOpts
*opts
= qemu_opts_find(&qemu_vnc_opts
, id
);
3523 SocketAddress
*saddr
= NULL
, *wsaddr
= NULL
;
3524 const char *share
, *device_id
;
3526 bool password
= false;
3527 bool reverse
= false;
3531 int show_vnc_port
= 0;
3533 #ifdef CONFIG_VNC_SASL
3537 int lock_key_sync
= 1;
3541 error_setg(errp
, "VNC display not active");
3544 vnc_display_close(vs
);
3549 vnc
= qemu_opt_get(opts
, "vnc");
3550 if (!vnc
|| strcmp(vnc
, "none") == 0) {
3554 h
= strrchr(vnc
, ':');
3556 size_t hlen
= h
- vnc
;
3558 const char *websocket
= qemu_opt_get(opts
, "websocket");
3559 int to
= qemu_opt_get_number(opts
, "to", 0);
3560 bool has_ipv4
= qemu_opt_get(opts
, "ipv4");
3561 bool has_ipv6
= qemu_opt_get(opts
, "ipv6");
3562 bool ipv4
= qemu_opt_get_bool(opts
, "ipv4", false);
3563 bool ipv6
= qemu_opt_get_bool(opts
, "ipv6", false);
3565 saddr
= g_new0(SocketAddress
, 1);
3567 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1
)) {
3569 "SHA1 hash support is required for websockets");
3573 wsaddr
= g_new0(SocketAddress
, 1);
3574 vs
->ws_enabled
= true;
3577 if (strncmp(vnc
, "unix:", 5) == 0) {
3578 saddr
->type
= SOCKET_ADDRESS_KIND_UNIX
;
3579 saddr
->u
.q_unix
.data
= g_new0(UnixSocketAddress
, 1);
3580 saddr
->u
.q_unix
.data
->path
= g_strdup(vnc
+ 5);
3582 if (vs
->ws_enabled
) {
3583 error_setg(errp
, "UNIX sockets not supported with websock");
3587 unsigned long long baseport
;
3588 InetSocketAddress
*inet
;
3589 saddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3590 inet
= saddr
->u
.inet
.data
= g_new0(InetSocketAddress
, 1);
3591 if (vnc
[0] == '[' && vnc
[hlen
- 1] == ']') {
3592 inet
->host
= g_strndup(vnc
+ 1, hlen
- 2);
3594 inet
->host
= g_strndup(vnc
, hlen
);
3596 if (parse_uint_full(h
+ 1, &baseport
, 10) < 0) {
3597 error_setg(errp
, "can't convert to a number: %s", h
+ 1);
3600 if (baseport
> 65535 ||
3601 baseport
+ 5900 > 65535) {
3602 error_setg(errp
, "port %s out of range", h
+ 1);
3605 inet
->port
= g_strdup_printf(
3606 "%d", (int)baseport
+ 5900);
3609 inet
->has_to
= true;
3610 inet
->to
= to
+ 5900;
3614 inet
->has_ipv4
= has_ipv4
;
3616 inet
->has_ipv6
= has_ipv6
;
3618 if (vs
->ws_enabled
) {
3619 wsaddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3620 inet
= wsaddr
->u
.inet
.data
= g_new0(InetSocketAddress
, 1);
3621 inet
->host
= g_strdup(saddr
->u
.inet
.data
->host
);
3622 inet
->port
= g_strdup(websocket
);
3625 inet
->has_to
= true;
3629 inet
->has_ipv4
= has_ipv4
;
3631 inet
->has_ipv6
= has_ipv6
;
3635 error_setg(errp
, "no vnc port specified");
3639 password
= qemu_opt_get_bool(opts
, "password", false);
3641 if (fips_get_state()) {
3643 "VNC password auth disabled due to FIPS mode, "
3644 "consider using the VeNCrypt or SASL authentication "
3645 "methods as an alternative");
3648 if (!qcrypto_cipher_supports(
3649 QCRYPTO_CIPHER_ALG_DES_RFB
)) {
3651 "Cipher backend does not support DES RFB algorithm");
3656 reverse
= qemu_opt_get_bool(opts
, "reverse", false);
3657 lock_key_sync
= qemu_opt_get_bool(opts
, "lock-key-sync", true);
3658 key_delay_ms
= qemu_opt_get_number(opts
, "key-delay-ms", 1);
3659 sasl
= qemu_opt_get_bool(opts
, "sasl", false);
3660 #ifndef CONFIG_VNC_SASL
3662 error_setg(errp
, "VNC SASL auth requires cyrus-sasl support");
3665 #endif /* CONFIG_VNC_SASL */
3666 credid
= qemu_opt_get(opts
, "tls-creds");
3669 if (qemu_opt_get(opts
, "tls") ||
3670 qemu_opt_get(opts
, "x509") ||
3671 qemu_opt_get(opts
, "x509verify")) {
3673 "'tls-creds' parameter is mutually exclusive with "
3674 "'tls', 'x509' and 'x509verify' parameters");
3678 creds
= object_resolve_path_component(
3679 object_get_objects_root(), credid
);
3681 error_setg(errp
, "No TLS credentials with id '%s'",
3685 vs
->tlscreds
= (QCryptoTLSCreds
*)
3686 object_dynamic_cast(creds
,
3687 TYPE_QCRYPTO_TLS_CREDS
);
3688 if (!vs
->tlscreds
) {
3689 error_setg(errp
, "Object with id '%s' is not TLS credentials",
3693 object_ref(OBJECT(vs
->tlscreds
));
3695 if (vs
->tlscreds
->endpoint
!= QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
) {
3697 "Expecting TLS credentials with a server endpoint");
3702 bool tls
= false, x509
= false, x509verify
= false;
3703 tls
= qemu_opt_get_bool(opts
, "tls", false);
3705 path
= qemu_opt_get(opts
, "x509");
3710 path
= qemu_opt_get(opts
, "x509verify");
3716 vs
->tlscreds
= vnc_display_create_creds(x509
,
3721 if (!vs
->tlscreds
) {
3726 acl
= qemu_opt_get_bool(opts
, "acl", false);
3728 share
= qemu_opt_get(opts
, "share");
3730 if (strcmp(share
, "ignore") == 0) {
3731 vs
->share_policy
= VNC_SHARE_POLICY_IGNORE
;
3732 } else if (strcmp(share
, "allow-exclusive") == 0) {
3733 vs
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3734 } else if (strcmp(share
, "force-shared") == 0) {
3735 vs
->share_policy
= VNC_SHARE_POLICY_FORCE_SHARED
;
3737 error_setg(errp
, "unknown vnc share= option");
3741 vs
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3743 vs
->connections_limit
= qemu_opt_get_number(opts
, "connections", 32);
3745 #ifdef CONFIG_VNC_JPEG
3746 vs
->lossy
= qemu_opt_get_bool(opts
, "lossy", false);
3748 vs
->non_adaptive
= qemu_opt_get_bool(opts
, "non-adaptive", false);
3749 /* adaptive updates are only used with tight encoding and
3750 * if lossy updates are enabled so we can disable all the
3751 * calculations otherwise */
3753 vs
->non_adaptive
= true;
3757 if (strcmp(vs
->id
, "default") == 0) {
3758 vs
->tlsaclname
= g_strdup("vnc.x509dname");
3760 vs
->tlsaclname
= g_strdup_printf("vnc.%s.x509dname", vs
->id
);
3762 qemu_acl_init(vs
->tlsaclname
);
3764 #ifdef CONFIG_VNC_SASL
3768 if (strcmp(vs
->id
, "default") == 0) {
3769 aclname
= g_strdup("vnc.username");
3771 aclname
= g_strdup_printf("vnc.%s.username", vs
->id
);
3773 vs
->sasl
.acl
= qemu_acl_init(aclname
);
3778 if (vnc_display_setup_auth(vs
, password
, sasl
, vs
->ws_enabled
, errp
) < 0) {
3782 #ifdef CONFIG_VNC_SASL
3783 if ((saslErr
= sasl_server_init(NULL
, "qemu")) != SASL_OK
) {
3784 error_setg(errp
, "Failed to initialize SASL auth: %s",
3785 sasl_errstring(saslErr
, NULL
, NULL
));
3789 vs
->lock_key_sync
= lock_key_sync
;
3790 vs
->key_delay_ms
= key_delay_ms
;
3792 device_id
= qemu_opt_get(opts
, "display");
3794 int head
= qemu_opt_get_number(opts
, "head", 0);
3797 con
= qemu_console_lookup_by_device_name(device_id
, head
, &err
);
3799 error_propagate(errp
, err
);
3806 if (con
!= vs
->dcl
.con
) {
3807 unregister_displaychangelistener(&vs
->dcl
);
3809 register_displaychangelistener(&vs
->dcl
);
3813 /* connect to viewer */
3814 QIOChannelSocket
*sioc
= NULL
;
3816 vs
->lwebsock
= NULL
;
3817 if (vs
->ws_enabled
) {
3818 error_setg(errp
, "Cannot use websockets in reverse mode");
3821 vs
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3822 sioc
= qio_channel_socket_new();
3823 if (qio_channel_socket_connect_sync(sioc
, saddr
, errp
) < 0) {
3826 vnc_connect(vs
, sioc
, false, false);
3827 object_unref(OBJECT(sioc
));
3829 vs
->lsock
= qio_channel_socket_new();
3830 if (qio_channel_socket_listen_sync(vs
->lsock
, saddr
, errp
) < 0) {
3833 vs
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3836 if (vs
->ws_enabled
) {
3837 vs
->lwebsock
= qio_channel_socket_new();
3838 if (qio_channel_socket_listen_sync(vs
->lwebsock
,
3839 wsaddr
, errp
) < 0) {
3840 object_unref(OBJECT(vs
->lsock
));
3846 vs
->lsock_tag
= qio_channel_add_watch(
3847 QIO_CHANNEL(vs
->lsock
),
3848 G_IO_IN
, vnc_listen_io
, vs
, NULL
);
3849 if (vs
->ws_enabled
) {
3850 vs
->lwebsock_tag
= qio_channel_add_watch(
3851 QIO_CHANNEL(vs
->lwebsock
),
3852 G_IO_IN
, vnc_listen_io
, vs
, NULL
);
3856 if (show_vnc_port
) {
3857 vnc_display_print_local_addr(vs
);
3860 qapi_free_SocketAddress(saddr
);
3861 qapi_free_SocketAddress(wsaddr
);
3865 qapi_free_SocketAddress(saddr
);
3866 qapi_free_SocketAddress(wsaddr
);
3867 vs
->enabled
= false;
3868 vs
->ws_enabled
= false;
3871 void vnc_display_add_client(const char *id
, int csock
, bool skipauth
)
3873 VncDisplay
*vs
= vnc_display_find(id
);
3874 QIOChannelSocket
*sioc
;
3880 sioc
= qio_channel_socket_new_fd(csock
, NULL
);
3882 vnc_connect(vs
, sioc
, skipauth
, false);
3883 object_unref(OBJECT(sioc
));
3887 static void vnc_auto_assign_id(QemuOptsList
*olist
, QemuOpts
*opts
)
3892 id
= g_strdup("default");
3893 while (qemu_opts_find(olist
, id
)) {
3895 id
= g_strdup_printf("vnc%d", i
++);
3897 qemu_opts_set_id(opts
, id
);
3900 QemuOpts
*vnc_parse(const char *str
, Error
**errp
)
3902 QemuOptsList
*olist
= qemu_find_opts("vnc");
3903 QemuOpts
*opts
= qemu_opts_parse(olist
, str
, true, errp
);
3910 id
= qemu_opts_id(opts
);
3912 /* auto-assign id if not present */
3913 vnc_auto_assign_id(olist
, opts
);
3918 int vnc_init_func(void *opaque
, QemuOpts
*opts
, Error
**errp
)
3920 Error
*local_err
= NULL
;
3921 char *id
= (char *)qemu_opts_id(opts
);
3924 vnc_display_init(id
);
3925 vnc_display_open(id
, &local_err
);
3926 if (local_err
!= NULL
) {
3927 error_reportf_err(local_err
, "Failed to start VNC server: ");
3933 static void vnc_register_config(void)
3935 qemu_add_opts(&qemu_vnc_opts
);
3937 opts_init(vnc_register_config
);