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
->lsock
) {
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 */
915 /* no client connected */
918 /* do bitblit op on the local surface too */
919 pitch
= vnc_server_fb_stride(vd
);
920 src_row
= vnc_server_fb_ptr(vd
, src_x
, src_y
);
921 dst_row
= vnc_server_fb_ptr(vd
, dst_x
, dst_y
);
926 src_row
+= pitch
* (h
-1);
927 dst_row
+= pitch
* (h
-1);
932 w_lim
= w
- (VNC_DIRTY_PIXELS_PER_BIT
- (dst_x
% VNC_DIRTY_PIXELS_PER_BIT
));
936 w_lim
= w
- (w_lim
% VNC_DIRTY_PIXELS_PER_BIT
);
938 for (i
= 0; i
< h
; i
++) {
939 for (x
= 0; x
<= w_lim
;
940 x
+= s
, src_row
+= cmp_bytes
, dst_row
+= cmp_bytes
) {
942 if ((s
= w
- w_lim
) == 0)
945 s
= (VNC_DIRTY_PIXELS_PER_BIT
-
946 (dst_x
% VNC_DIRTY_PIXELS_PER_BIT
));
949 s
= VNC_DIRTY_PIXELS_PER_BIT
;
951 cmp_bytes
= s
* VNC_SERVER_FB_BYTES
;
952 if (memcmp(src_row
, dst_row
, cmp_bytes
) == 0)
954 memmove(dst_row
, src_row
, cmp_bytes
);
955 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
956 if (!vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
957 set_bit(((x
+ dst_x
) / VNC_DIRTY_PIXELS_PER_BIT
),
962 src_row
+= pitch
- w
* VNC_SERVER_FB_BYTES
;
963 dst_row
+= pitch
- w
* VNC_SERVER_FB_BYTES
;
967 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
968 if (vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
969 vnc_copy(vs
, src_x
, src_y
, dst_x
, dst_y
, w
, h
);
974 static void vnc_mouse_set(DisplayChangeListener
*dcl
,
975 int x
, int y
, int visible
)
977 /* can we ask the client(s) to move the pointer ??? */
980 static int vnc_cursor_define(VncState
*vs
)
982 QEMUCursor
*c
= vs
->vd
->cursor
;
985 if (vnc_has_feature(vs
, VNC_FEATURE_RICH_CURSOR
)) {
987 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
988 vnc_write_u8(vs
, 0); /* padding */
989 vnc_write_u16(vs
, 1); /* # of rects */
990 vnc_framebuffer_update(vs
, c
->hot_x
, c
->hot_y
, c
->width
, c
->height
,
991 VNC_ENCODING_RICH_CURSOR
);
992 isize
= c
->width
* c
->height
* vs
->client_pf
.bytes_per_pixel
;
993 vnc_write_pixels_generic(vs
, c
->data
, isize
);
994 vnc_write(vs
, vs
->vd
->cursor_mask
, vs
->vd
->cursor_msize
);
995 vnc_unlock_output(vs
);
1001 static void vnc_dpy_cursor_define(DisplayChangeListener
*dcl
,
1004 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
1007 cursor_put(vd
->cursor
);
1008 g_free(vd
->cursor_mask
);
1011 cursor_get(vd
->cursor
);
1012 vd
->cursor_msize
= cursor_get_mono_bpl(c
) * c
->height
;
1013 vd
->cursor_mask
= g_malloc0(vd
->cursor_msize
);
1014 cursor_get_mono_mask(c
, 0, vd
->cursor_mask
);
1016 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
1017 vnc_cursor_define(vs
);
1021 static int find_and_clear_dirty_height(VncState
*vs
,
1022 int y
, int last_x
, int x
, int height
)
1026 for (h
= 1; h
< (height
- y
); h
++) {
1027 if (!test_bit(last_x
, vs
->dirty
[y
+ h
])) {
1030 bitmap_clear(vs
->dirty
[y
+ h
], last_x
, x
- last_x
);
1036 static int vnc_update_client(VncState
*vs
, int has_dirty
, bool sync
)
1038 if (vs
->disconnecting
) {
1039 vnc_disconnect_finish(vs
);
1043 vs
->has_dirty
+= has_dirty
;
1044 if (vs
->need_update
&& !vs
->disconnecting
) {
1045 VncDisplay
*vd
= vs
->vd
;
1051 if (vs
->output
.offset
&& !vs
->audio_cap
&& !vs
->force_update
)
1052 /* kernel send buffers are full -> drop frames to throttle */
1055 if (!vs
->has_dirty
&& !vs
->audio_cap
&& !vs
->force_update
)
1059 * Send screen updates to the vnc client using the server
1060 * surface and server dirty map. guest surface updates
1061 * happening in parallel don't disturb us, the next pass will
1062 * send them to the client.
1064 job
= vnc_job_new(vs
);
1066 height
= pixman_image_get_height(vd
->server
);
1067 width
= pixman_image_get_width(vd
->server
);
1073 unsigned long offset
= find_next_bit((unsigned long *) &vs
->dirty
,
1074 height
* VNC_DIRTY_BPL(vs
),
1075 y
* VNC_DIRTY_BPL(vs
));
1076 if (offset
== height
* VNC_DIRTY_BPL(vs
)) {
1077 /* no more dirty bits */
1080 y
= offset
/ VNC_DIRTY_BPL(vs
);
1081 x
= offset
% VNC_DIRTY_BPL(vs
);
1082 x2
= find_next_zero_bit((unsigned long *) &vs
->dirty
[y
],
1083 VNC_DIRTY_BPL(vs
), x
);
1084 bitmap_clear(vs
->dirty
[y
], x
, x2
- x
);
1085 h
= find_and_clear_dirty_height(vs
, y
, x
, x2
, height
);
1086 x2
= MIN(x2
, width
/ VNC_DIRTY_PIXELS_PER_BIT
);
1088 n
+= vnc_job_add_rect(job
, x
* VNC_DIRTY_PIXELS_PER_BIT
, y
,
1089 (x2
- x
) * VNC_DIRTY_PIXELS_PER_BIT
, h
);
1091 if (!x
&& x2
== width
/ VNC_DIRTY_PIXELS_PER_BIT
) {
1103 vs
->force_update
= 0;
1108 if (vs
->disconnecting
) {
1109 vnc_disconnect_finish(vs
);
1118 static void audio_capture_notify(void *opaque
, audcnotification_e cmd
)
1120 VncState
*vs
= opaque
;
1123 case AUD_CNOTIFY_DISABLE
:
1124 vnc_lock_output(vs
);
1125 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1126 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1127 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_END
);
1128 vnc_unlock_output(vs
);
1132 case AUD_CNOTIFY_ENABLE
:
1133 vnc_lock_output(vs
);
1134 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1135 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1136 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN
);
1137 vnc_unlock_output(vs
);
1143 static void audio_capture_destroy(void *opaque
)
1147 static void audio_capture(void *opaque
, void *buf
, int size
)
1149 VncState
*vs
= opaque
;
1151 vnc_lock_output(vs
);
1152 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1153 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1154 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_DATA
);
1155 vnc_write_u32(vs
, size
);
1156 vnc_write(vs
, buf
, size
);
1157 vnc_unlock_output(vs
);
1161 static void audio_add(VncState
*vs
)
1163 struct audio_capture_ops ops
;
1165 if (vs
->audio_cap
) {
1166 error_report("audio already running");
1170 ops
.notify
= audio_capture_notify
;
1171 ops
.destroy
= audio_capture_destroy
;
1172 ops
.capture
= audio_capture
;
1174 vs
->audio_cap
= AUD_add_capture(&vs
->as
, &ops
, vs
);
1175 if (!vs
->audio_cap
) {
1176 error_report("Failed to add audio capture");
1180 static void audio_del(VncState
*vs
)
1182 if (vs
->audio_cap
) {
1183 AUD_del_capture(vs
->audio_cap
, vs
);
1184 vs
->audio_cap
= NULL
;
1188 static void vnc_disconnect_start(VncState
*vs
)
1190 if (vs
->disconnecting
) {
1193 vnc_set_share_mode(vs
, VNC_SHARE_MODE_DISCONNECTED
);
1195 g_source_remove(vs
->ioc_tag
);
1197 qio_channel_close(vs
->ioc
, NULL
);
1198 vs
->disconnecting
= TRUE
;
1201 void vnc_disconnect_finish(VncState
*vs
)
1205 vnc_jobs_join(vs
); /* Wait encoding jobs */
1207 vnc_lock_output(vs
);
1208 vnc_qmp_event(vs
, QAPI_EVENT_VNC_DISCONNECTED
);
1210 buffer_free(&vs
->input
);
1211 buffer_free(&vs
->output
);
1213 qapi_free_VncClientInfo(vs
->info
);
1216 vnc_tight_clear(vs
);
1219 #ifdef CONFIG_VNC_SASL
1220 vnc_sasl_client_cleanup(vs
);
1221 #endif /* CONFIG_VNC_SASL */
1223 vnc_release_modifiers(vs
);
1225 if (vs
->mouse_mode_notifier
.notify
!= NULL
) {
1226 qemu_remove_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
1228 QTAILQ_REMOVE(&vs
->vd
->clients
, vs
, next
);
1229 if (QTAILQ_EMPTY(&vs
->vd
->clients
)) {
1230 /* last client gone */
1231 vnc_update_server_surface(vs
->vd
);
1234 vnc_unlock_output(vs
);
1236 qemu_mutex_destroy(&vs
->output_mutex
);
1237 if (vs
->bh
!= NULL
) {
1238 qemu_bh_delete(vs
->bh
);
1240 buffer_free(&vs
->jobs_buffer
);
1242 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
1243 g_free(vs
->lossy_rect
[i
]);
1245 g_free(vs
->lossy_rect
);
1247 object_unref(OBJECT(vs
->ioc
));
1249 object_unref(OBJECT(vs
->sioc
));
1254 ssize_t
vnc_client_io_error(VncState
*vs
, ssize_t ret
, Error
**errp
)
1258 VNC_DEBUG("Closing down client sock: EOF\n");
1259 vnc_disconnect_start(vs
);
1260 } else if (ret
!= QIO_CHANNEL_ERR_BLOCK
) {
1261 VNC_DEBUG("Closing down client sock: ret %zd (%s)\n",
1262 ret
, errp
? error_get_pretty(*errp
) : "Unknown");
1263 vnc_disconnect_start(vs
);
1276 void vnc_client_error(VncState
*vs
)
1278 VNC_DEBUG("Closing down client sock: protocol error\n");
1279 vnc_disconnect_start(vs
);
1284 * Called to write a chunk of data to the client socket. The data may
1285 * be the raw data, or may have already been encoded by SASL.
1286 * The data will be written either straight onto the socket, or
1287 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1289 * NB, it is theoretically possible to have 2 layers of encryption,
1290 * both SASL, and this TLS layer. It is highly unlikely in practice
1291 * though, since SASL encryption will typically be a no-op if TLS
1294 * Returns the number of bytes written, which may be less than
1295 * the requested 'datalen' if the socket would block. Returns
1296 * -1 on error, and disconnects the client socket.
1298 ssize_t
vnc_client_write_buf(VncState
*vs
, const uint8_t *data
, size_t datalen
)
1302 ret
= qio_channel_write(
1303 vs
->ioc
, (const char *)data
, datalen
, &err
);
1304 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data
, datalen
, ret
);
1305 return vnc_client_io_error(vs
, ret
, &err
);
1310 * Called to write buffered data to the client socket, when not
1311 * using any SASL SSF encryption layers. Will write as much data
1312 * as possible without blocking. If all buffered data is written,
1313 * will switch the FD poll() handler back to read monitoring.
1315 * Returns the number of bytes written, which may be less than
1316 * the buffered output data if the socket would block. Returns
1317 * -1 on error, and disconnects the client socket.
1319 static ssize_t
vnc_client_write_plain(VncState
*vs
)
1323 #ifdef CONFIG_VNC_SASL
1324 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1325 vs
->output
.buffer
, vs
->output
.capacity
, vs
->output
.offset
,
1326 vs
->sasl
.waitWriteSSF
);
1328 if (vs
->sasl
.conn
&&
1330 vs
->sasl
.waitWriteSSF
) {
1331 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->sasl
.waitWriteSSF
);
1333 vs
->sasl
.waitWriteSSF
-= ret
;
1335 #endif /* CONFIG_VNC_SASL */
1336 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->output
.offset
);
1340 buffer_advance(&vs
->output
, ret
);
1342 if (vs
->output
.offset
== 0) {
1344 g_source_remove(vs
->ioc_tag
);
1346 vs
->ioc_tag
= qio_channel_add_watch(
1347 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1355 * First function called whenever there is data to be written to
1356 * the client socket. Will delegate actual work according to whether
1357 * SASL SSF layers are enabled (thus requiring encryption calls)
1359 static void vnc_client_write_locked(VncState
*vs
)
1361 #ifdef CONFIG_VNC_SASL
1362 if (vs
->sasl
.conn
&&
1364 !vs
->sasl
.waitWriteSSF
) {
1365 vnc_client_write_sasl(vs
);
1367 #endif /* CONFIG_VNC_SASL */
1369 vnc_client_write_plain(vs
);
1373 static void vnc_client_write(VncState
*vs
)
1376 vnc_lock_output(vs
);
1377 if (vs
->output
.offset
) {
1378 vnc_client_write_locked(vs
);
1379 } else if (vs
->ioc
!= NULL
) {
1381 g_source_remove(vs
->ioc_tag
);
1383 vs
->ioc_tag
= qio_channel_add_watch(
1384 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1386 vnc_unlock_output(vs
);
1389 void vnc_read_when(VncState
*vs
, VncReadEvent
*func
, size_t expecting
)
1391 vs
->read_handler
= func
;
1392 vs
->read_handler_expect
= expecting
;
1397 * Called to read a chunk of data from the client socket. The data may
1398 * be the raw data, or may need to be further decoded by SASL.
1399 * The data will be read either straight from to the socket, or
1400 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1402 * NB, it is theoretically possible to have 2 layers of encryption,
1403 * both SASL, and this TLS layer. It is highly unlikely in practice
1404 * though, since SASL encryption will typically be a no-op if TLS
1407 * Returns the number of bytes read, which may be less than
1408 * the requested 'datalen' if the socket would block. Returns
1409 * -1 on error, and disconnects the client socket.
1411 ssize_t
vnc_client_read_buf(VncState
*vs
, uint8_t *data
, size_t datalen
)
1415 ret
= qio_channel_read(
1416 vs
->ioc
, (char *)data
, datalen
, &err
);
1417 VNC_DEBUG("Read wire %p %zd -> %ld\n", data
, datalen
, ret
);
1418 return vnc_client_io_error(vs
, ret
, &err
);
1423 * Called to read data from the client socket to the input buffer,
1424 * when not using any SASL SSF encryption layers. Will read as much
1425 * data as possible without blocking.
1427 * Returns the number of bytes read. Returns -1 on error, and
1428 * disconnects the client socket.
1430 static ssize_t
vnc_client_read_plain(VncState
*vs
)
1433 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1434 vs
->input
.buffer
, vs
->input
.capacity
, vs
->input
.offset
);
1435 buffer_reserve(&vs
->input
, 4096);
1436 ret
= vnc_client_read_buf(vs
, buffer_end(&vs
->input
), 4096);
1439 vs
->input
.offset
+= ret
;
1443 static void vnc_jobs_bh(void *opaque
)
1445 VncState
*vs
= opaque
;
1447 vnc_jobs_consume_buffer(vs
);
1451 * First function called whenever there is more data to be read from
1452 * the client socket. Will delegate actual work according to whether
1453 * SASL SSF layers are enabled (thus requiring decryption calls)
1454 * Returns 0 on success, -1 if client disconnected
1456 static int vnc_client_read(VncState
*vs
)
1460 #ifdef CONFIG_VNC_SASL
1461 if (vs
->sasl
.conn
&& vs
->sasl
.runSSF
)
1462 ret
= vnc_client_read_sasl(vs
);
1464 #endif /* CONFIG_VNC_SASL */
1465 ret
= vnc_client_read_plain(vs
);
1467 if (vs
->disconnecting
) {
1468 vnc_disconnect_finish(vs
);
1474 while (vs
->read_handler
&& vs
->input
.offset
>= vs
->read_handler_expect
) {
1475 size_t len
= vs
->read_handler_expect
;
1478 ret
= vs
->read_handler(vs
, vs
->input
.buffer
, len
);
1479 if (vs
->disconnecting
) {
1480 vnc_disconnect_finish(vs
);
1485 buffer_advance(&vs
->input
, len
);
1487 vs
->read_handler_expect
= ret
;
1493 gboolean
vnc_client_io(QIOChannel
*ioc G_GNUC_UNUSED
,
1494 GIOCondition condition
, void *opaque
)
1496 VncState
*vs
= opaque
;
1497 if (condition
& G_IO_IN
) {
1498 if (vnc_client_read(vs
) < 0) {
1502 if (condition
& G_IO_OUT
) {
1503 vnc_client_write(vs
);
1509 void vnc_write(VncState
*vs
, const void *data
, size_t len
)
1511 buffer_reserve(&vs
->output
, len
);
1513 if (vs
->ioc
!= NULL
&& buffer_empty(&vs
->output
)) {
1515 g_source_remove(vs
->ioc_tag
);
1517 vs
->ioc_tag
= qio_channel_add_watch(
1518 vs
->ioc
, G_IO_IN
| G_IO_OUT
, vnc_client_io
, vs
, NULL
);
1521 buffer_append(&vs
->output
, data
, len
);
1524 void vnc_write_s32(VncState
*vs
, int32_t value
)
1526 vnc_write_u32(vs
, *(uint32_t *)&value
);
1529 void vnc_write_u32(VncState
*vs
, uint32_t value
)
1533 buf
[0] = (value
>> 24) & 0xFF;
1534 buf
[1] = (value
>> 16) & 0xFF;
1535 buf
[2] = (value
>> 8) & 0xFF;
1536 buf
[3] = value
& 0xFF;
1538 vnc_write(vs
, buf
, 4);
1541 void vnc_write_u16(VncState
*vs
, uint16_t value
)
1545 buf
[0] = (value
>> 8) & 0xFF;
1546 buf
[1] = value
& 0xFF;
1548 vnc_write(vs
, buf
, 2);
1551 void vnc_write_u8(VncState
*vs
, uint8_t value
)
1553 vnc_write(vs
, (char *)&value
, 1);
1556 void vnc_flush(VncState
*vs
)
1558 vnc_lock_output(vs
);
1559 if (vs
->ioc
!= NULL
&& vs
->output
.offset
) {
1560 vnc_client_write_locked(vs
);
1562 vnc_unlock_output(vs
);
1565 static uint8_t read_u8(uint8_t *data
, size_t offset
)
1567 return data
[offset
];
1570 static uint16_t read_u16(uint8_t *data
, size_t offset
)
1572 return ((data
[offset
] & 0xFF) << 8) | (data
[offset
+ 1] & 0xFF);
1575 static int32_t read_s32(uint8_t *data
, size_t offset
)
1577 return (int32_t)((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1578 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1581 uint32_t read_u32(uint8_t *data
, size_t offset
)
1583 return ((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1584 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1587 static void client_cut_text(VncState
*vs
, size_t len
, uint8_t *text
)
1591 static void check_pointer_type_change(Notifier
*notifier
, void *data
)
1593 VncState
*vs
= container_of(notifier
, VncState
, mouse_mode_notifier
);
1594 int absolute
= qemu_input_is_absolute();
1596 if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
) && vs
->absolute
!= absolute
) {
1597 vnc_lock_output(vs
);
1598 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1599 vnc_write_u8(vs
, 0);
1600 vnc_write_u16(vs
, 1);
1601 vnc_framebuffer_update(vs
, absolute
, 0,
1602 pixman_image_get_width(vs
->vd
->server
),
1603 pixman_image_get_height(vs
->vd
->server
),
1604 VNC_ENCODING_POINTER_TYPE_CHANGE
);
1605 vnc_unlock_output(vs
);
1608 vs
->absolute
= absolute
;
1611 static void pointer_event(VncState
*vs
, int button_mask
, int x
, int y
)
1613 static uint32_t bmap
[INPUT_BUTTON__MAX
] = {
1614 [INPUT_BUTTON_LEFT
] = 0x01,
1615 [INPUT_BUTTON_MIDDLE
] = 0x02,
1616 [INPUT_BUTTON_RIGHT
] = 0x04,
1617 [INPUT_BUTTON_WHEEL_UP
] = 0x08,
1618 [INPUT_BUTTON_WHEEL_DOWN
] = 0x10,
1620 QemuConsole
*con
= vs
->vd
->dcl
.con
;
1621 int width
= pixman_image_get_width(vs
->vd
->server
);
1622 int height
= pixman_image_get_height(vs
->vd
->server
);
1624 if (vs
->last_bmask
!= button_mask
) {
1625 qemu_input_update_buttons(con
, bmap
, vs
->last_bmask
, button_mask
);
1626 vs
->last_bmask
= button_mask
;
1630 qemu_input_queue_abs(con
, INPUT_AXIS_X
, x
, width
);
1631 qemu_input_queue_abs(con
, INPUT_AXIS_Y
, y
, height
);
1632 } else if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
)) {
1633 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- 0x7FFF);
1634 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- 0x7FFF);
1636 if (vs
->last_x
!= -1) {
1637 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- vs
->last_x
);
1638 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- vs
->last_y
);
1643 qemu_input_event_sync();
1646 static void reset_keys(VncState
*vs
)
1649 for(i
= 0; i
< 256; i
++) {
1650 if (vs
->modifiers_state
[i
]) {
1651 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, i
, false);
1652 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1653 vs
->modifiers_state
[i
] = 0;
1658 static void press_key(VncState
*vs
, int keysym
)
1660 int keycode
= keysym2scancode(vs
->vd
->kbd_layout
, keysym
) & SCANCODE_KEYMASK
;
1661 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, true);
1662 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1663 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1664 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1667 static void vnc_led_state_change(VncState
*vs
)
1669 if (!vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
)) {
1673 vnc_lock_output(vs
);
1674 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1675 vnc_write_u8(vs
, 0);
1676 vnc_write_u16(vs
, 1);
1677 vnc_framebuffer_update(vs
, 0, 0, 1, 1, VNC_ENCODING_LED_STATE
);
1678 vnc_write_u8(vs
, vs
->vd
->ledstate
);
1679 vnc_unlock_output(vs
);
1683 static void kbd_leds(void *opaque
, int ledstate
)
1685 VncDisplay
*vd
= opaque
;
1688 trace_vnc_key_guest_leds((ledstate
& QEMU_CAPS_LOCK_LED
),
1689 (ledstate
& QEMU_NUM_LOCK_LED
),
1690 (ledstate
& QEMU_SCROLL_LOCK_LED
));
1692 if (ledstate
== vd
->ledstate
) {
1696 vd
->ledstate
= ledstate
;
1698 QTAILQ_FOREACH(client
, &vd
->clients
, next
) {
1699 vnc_led_state_change(client
);
1703 static void do_key_event(VncState
*vs
, int down
, int keycode
, int sym
)
1705 /* QEMU console switch */
1707 case 0x2a: /* Left Shift */
1708 case 0x36: /* Right Shift */
1709 case 0x1d: /* Left CTRL */
1710 case 0x9d: /* Right CTRL */
1711 case 0x38: /* Left ALT */
1712 case 0xb8: /* Right ALT */
1714 vs
->modifiers_state
[keycode
] = 1;
1716 vs
->modifiers_state
[keycode
] = 0;
1718 case 0x02 ... 0x0a: /* '1' to '9' keys */
1719 if (vs
->vd
->dcl
.con
== NULL
&&
1720 down
&& vs
->modifiers_state
[0x1d] && vs
->modifiers_state
[0x38]) {
1721 /* Reset the modifiers sent to the current console */
1723 console_select(keycode
- 0x02);
1727 case 0x3a: /* CapsLock */
1728 case 0x45: /* NumLock */
1730 vs
->modifiers_state
[keycode
] ^= 1;
1734 /* Turn off the lock state sync logic if the client support the led
1737 if (down
&& vs
->vd
->lock_key_sync
&&
1738 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1739 keycode_is_keypad(vs
->vd
->kbd_layout
, keycode
)) {
1740 /* If the numlock state needs to change then simulate an additional
1741 keypress before sending this one. This will happen if the user
1742 toggles numlock away from the VNC window.
1744 if (keysym_is_numlock(vs
->vd
->kbd_layout
, sym
& 0xFFFF)) {
1745 if (!vs
->modifiers_state
[0x45]) {
1746 trace_vnc_key_sync_numlock(true);
1747 vs
->modifiers_state
[0x45] = 1;
1748 press_key(vs
, 0xff7f);
1751 if (vs
->modifiers_state
[0x45]) {
1752 trace_vnc_key_sync_numlock(false);
1753 vs
->modifiers_state
[0x45] = 0;
1754 press_key(vs
, 0xff7f);
1759 if (down
&& vs
->vd
->lock_key_sync
&&
1760 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1761 ((sym
>= 'A' && sym
<= 'Z') || (sym
>= 'a' && sym
<= 'z'))) {
1762 /* If the capslock state needs to change then simulate an additional
1763 keypress before sending this one. This will happen if the user
1764 toggles capslock away from the VNC window.
1766 int uppercase
= !!(sym
>= 'A' && sym
<= 'Z');
1767 int shift
= !!(vs
->modifiers_state
[0x2a] | vs
->modifiers_state
[0x36]);
1768 int capslock
= !!(vs
->modifiers_state
[0x3a]);
1770 if (uppercase
== shift
) {
1771 trace_vnc_key_sync_capslock(false);
1772 vs
->modifiers_state
[0x3a] = 0;
1773 press_key(vs
, 0xffe5);
1776 if (uppercase
!= shift
) {
1777 trace_vnc_key_sync_capslock(true);
1778 vs
->modifiers_state
[0x3a] = 1;
1779 press_key(vs
, 0xffe5);
1784 if (qemu_console_is_graphic(NULL
)) {
1785 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, down
);
1786 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1788 bool numlock
= vs
->modifiers_state
[0x45];
1789 bool control
= (vs
->modifiers_state
[0x1d] ||
1790 vs
->modifiers_state
[0x9d]);
1791 /* QEMU console emulation */
1794 case 0x2a: /* Left Shift */
1795 case 0x36: /* Right Shift */
1796 case 0x1d: /* Left CTRL */
1797 case 0x9d: /* Right CTRL */
1798 case 0x38: /* Left ALT */
1799 case 0xb8: /* Right ALT */
1802 kbd_put_keysym(QEMU_KEY_UP
);
1805 kbd_put_keysym(QEMU_KEY_DOWN
);
1808 kbd_put_keysym(QEMU_KEY_LEFT
);
1811 kbd_put_keysym(QEMU_KEY_RIGHT
);
1814 kbd_put_keysym(QEMU_KEY_DELETE
);
1817 kbd_put_keysym(QEMU_KEY_HOME
);
1820 kbd_put_keysym(QEMU_KEY_END
);
1823 kbd_put_keysym(QEMU_KEY_PAGEUP
);
1826 kbd_put_keysym(QEMU_KEY_PAGEDOWN
);
1830 kbd_put_keysym(numlock
? '7' : QEMU_KEY_HOME
);
1833 kbd_put_keysym(numlock
? '8' : QEMU_KEY_UP
);
1836 kbd_put_keysym(numlock
? '9' : QEMU_KEY_PAGEUP
);
1839 kbd_put_keysym(numlock
? '4' : QEMU_KEY_LEFT
);
1842 kbd_put_keysym('5');
1845 kbd_put_keysym(numlock
? '6' : QEMU_KEY_RIGHT
);
1848 kbd_put_keysym(numlock
? '1' : QEMU_KEY_END
);
1851 kbd_put_keysym(numlock
? '2' : QEMU_KEY_DOWN
);
1854 kbd_put_keysym(numlock
? '3' : QEMU_KEY_PAGEDOWN
);
1857 kbd_put_keysym('0');
1860 kbd_put_keysym(numlock
? '.' : QEMU_KEY_DELETE
);
1864 kbd_put_keysym('/');
1867 kbd_put_keysym('*');
1870 kbd_put_keysym('-');
1873 kbd_put_keysym('+');
1876 kbd_put_keysym('\n');
1881 kbd_put_keysym(sym
& 0x1f);
1883 kbd_put_keysym(sym
);
1891 static void vnc_release_modifiers(VncState
*vs
)
1893 static const int keycodes
[] = {
1894 /* shift, control, alt keys, both left & right */
1895 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1899 if (!qemu_console_is_graphic(NULL
)) {
1902 for (i
= 0; i
< ARRAY_SIZE(keycodes
); i
++) {
1903 keycode
= keycodes
[i
];
1904 if (!vs
->modifiers_state
[keycode
]) {
1907 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1908 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1912 static const char *code2name(int keycode
)
1914 return QKeyCode_lookup
[qemu_input_key_number_to_qcode(keycode
)];
1917 static void key_event(VncState
*vs
, int down
, uint32_t sym
)
1922 if (lsym
>= 'A' && lsym
<= 'Z' && qemu_console_is_graphic(NULL
)) {
1923 lsym
= lsym
- 'A' + 'a';
1926 keycode
= keysym2scancode(vs
->vd
->kbd_layout
, lsym
& 0xFFFF) & SCANCODE_KEYMASK
;
1927 trace_vnc_key_event_map(down
, sym
, keycode
, code2name(keycode
));
1928 do_key_event(vs
, down
, keycode
, sym
);
1931 static void ext_key_event(VncState
*vs
, int down
,
1932 uint32_t sym
, uint16_t keycode
)
1934 /* if the user specifies a keyboard layout, always use it */
1935 if (keyboard_layout
) {
1936 key_event(vs
, down
, sym
);
1938 trace_vnc_key_event_ext(down
, sym
, keycode
, code2name(keycode
));
1939 do_key_event(vs
, down
, keycode
, sym
);
1943 static void framebuffer_update_request(VncState
*vs
, int incremental
,
1944 int x
, int y
, int w
, int h
)
1946 vs
->need_update
= 1;
1952 vs
->force_update
= 1;
1953 vnc_set_area_dirty(vs
->dirty
, vs
->vd
, x
, y
, w
, h
);
1956 static void send_ext_key_event_ack(VncState
*vs
)
1958 vnc_lock_output(vs
);
1959 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1960 vnc_write_u8(vs
, 0);
1961 vnc_write_u16(vs
, 1);
1962 vnc_framebuffer_update(vs
, 0, 0,
1963 pixman_image_get_width(vs
->vd
->server
),
1964 pixman_image_get_height(vs
->vd
->server
),
1965 VNC_ENCODING_EXT_KEY_EVENT
);
1966 vnc_unlock_output(vs
);
1970 static void send_ext_audio_ack(VncState
*vs
)
1972 vnc_lock_output(vs
);
1973 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1974 vnc_write_u8(vs
, 0);
1975 vnc_write_u16(vs
, 1);
1976 vnc_framebuffer_update(vs
, 0, 0,
1977 pixman_image_get_width(vs
->vd
->server
),
1978 pixman_image_get_height(vs
->vd
->server
),
1979 VNC_ENCODING_AUDIO
);
1980 vnc_unlock_output(vs
);
1984 static void set_encodings(VncState
*vs
, int32_t *encodings
, size_t n_encodings
)
1987 unsigned int enc
= 0;
1990 vs
->vnc_encoding
= 0;
1991 vs
->tight
.compression
= 9;
1992 vs
->tight
.quality
= -1; /* Lossless by default */
1996 * Start from the end because the encodings are sent in order of preference.
1997 * This way the preferred encoding (first encoding defined in the array)
1998 * will be set at the end of the loop.
2000 for (i
= n_encodings
- 1; i
>= 0; i
--) {
2003 case VNC_ENCODING_RAW
:
2004 vs
->vnc_encoding
= enc
;
2006 case VNC_ENCODING_COPYRECT
:
2007 vs
->features
|= VNC_FEATURE_COPYRECT_MASK
;
2009 case VNC_ENCODING_HEXTILE
:
2010 vs
->features
|= VNC_FEATURE_HEXTILE_MASK
;
2011 vs
->vnc_encoding
= enc
;
2013 case VNC_ENCODING_TIGHT
:
2014 vs
->features
|= VNC_FEATURE_TIGHT_MASK
;
2015 vs
->vnc_encoding
= enc
;
2017 #ifdef CONFIG_VNC_PNG
2018 case VNC_ENCODING_TIGHT_PNG
:
2019 vs
->features
|= VNC_FEATURE_TIGHT_PNG_MASK
;
2020 vs
->vnc_encoding
= enc
;
2023 case VNC_ENCODING_ZLIB
:
2024 vs
->features
|= VNC_FEATURE_ZLIB_MASK
;
2025 vs
->vnc_encoding
= enc
;
2027 case VNC_ENCODING_ZRLE
:
2028 vs
->features
|= VNC_FEATURE_ZRLE_MASK
;
2029 vs
->vnc_encoding
= enc
;
2031 case VNC_ENCODING_ZYWRLE
:
2032 vs
->features
|= VNC_FEATURE_ZYWRLE_MASK
;
2033 vs
->vnc_encoding
= enc
;
2035 case VNC_ENCODING_DESKTOPRESIZE
:
2036 vs
->features
|= VNC_FEATURE_RESIZE_MASK
;
2038 case VNC_ENCODING_POINTER_TYPE_CHANGE
:
2039 vs
->features
|= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK
;
2041 case VNC_ENCODING_RICH_CURSOR
:
2042 vs
->features
|= VNC_FEATURE_RICH_CURSOR_MASK
;
2043 if (vs
->vd
->cursor
) {
2044 vnc_cursor_define(vs
);
2047 case VNC_ENCODING_EXT_KEY_EVENT
:
2048 send_ext_key_event_ack(vs
);
2050 case VNC_ENCODING_AUDIO
:
2051 send_ext_audio_ack(vs
);
2053 case VNC_ENCODING_WMVi
:
2054 vs
->features
|= VNC_FEATURE_WMVI_MASK
;
2056 case VNC_ENCODING_LED_STATE
:
2057 vs
->features
|= VNC_FEATURE_LED_STATE_MASK
;
2059 case VNC_ENCODING_COMPRESSLEVEL0
... VNC_ENCODING_COMPRESSLEVEL0
+ 9:
2060 vs
->tight
.compression
= (enc
& 0x0F);
2062 case VNC_ENCODING_QUALITYLEVEL0
... VNC_ENCODING_QUALITYLEVEL0
+ 9:
2063 if (vs
->vd
->lossy
) {
2064 vs
->tight
.quality
= (enc
& 0x0F);
2068 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i
, enc
, enc
);
2072 vnc_desktop_resize(vs
);
2073 check_pointer_type_change(&vs
->mouse_mode_notifier
, NULL
);
2074 vnc_led_state_change(vs
);
2077 static void set_pixel_conversion(VncState
*vs
)
2079 pixman_format_code_t fmt
= qemu_pixman_get_format(&vs
->client_pf
);
2081 if (fmt
== VNC_SERVER_FB_FORMAT
) {
2082 vs
->write_pixels
= vnc_write_pixels_copy
;
2083 vnc_hextile_set_pixel_conversion(vs
, 0);
2085 vs
->write_pixels
= vnc_write_pixels_generic
;
2086 vnc_hextile_set_pixel_conversion(vs
, 1);
2090 static void send_color_map(VncState
*vs
)
2094 vnc_write_u8(vs
, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES
);
2095 vnc_write_u8(vs
, 0); /* padding */
2096 vnc_write_u16(vs
, 0); /* first color */
2097 vnc_write_u16(vs
, 256); /* # of colors */
2099 for (i
= 0; i
< 256; i
++) {
2100 PixelFormat
*pf
= &vs
->client_pf
;
2102 vnc_write_u16(vs
, (((i
>> pf
->rshift
) & pf
->rmax
) << (16 - pf
->rbits
)));
2103 vnc_write_u16(vs
, (((i
>> pf
->gshift
) & pf
->gmax
) << (16 - pf
->gbits
)));
2104 vnc_write_u16(vs
, (((i
>> pf
->bshift
) & pf
->bmax
) << (16 - pf
->bbits
)));
2108 static void set_pixel_format(VncState
*vs
, int bits_per_pixel
,
2109 int big_endian_flag
, int true_color_flag
,
2110 int red_max
, int green_max
, int blue_max
,
2111 int red_shift
, int green_shift
, int blue_shift
)
2113 if (!true_color_flag
) {
2114 /* Expose a reasonable default 256 color map */
2124 switch (bits_per_pixel
) {
2130 vnc_client_error(vs
);
2134 vs
->client_pf
.rmax
= red_max
? red_max
: 0xFF;
2135 vs
->client_pf
.rbits
= hweight_long(red_max
);
2136 vs
->client_pf
.rshift
= red_shift
;
2137 vs
->client_pf
.rmask
= red_max
<< red_shift
;
2138 vs
->client_pf
.gmax
= green_max
? green_max
: 0xFF;
2139 vs
->client_pf
.gbits
= hweight_long(green_max
);
2140 vs
->client_pf
.gshift
= green_shift
;
2141 vs
->client_pf
.gmask
= green_max
<< green_shift
;
2142 vs
->client_pf
.bmax
= blue_max
? blue_max
: 0xFF;
2143 vs
->client_pf
.bbits
= hweight_long(blue_max
);
2144 vs
->client_pf
.bshift
= blue_shift
;
2145 vs
->client_pf
.bmask
= blue_max
<< blue_shift
;
2146 vs
->client_pf
.bits_per_pixel
= bits_per_pixel
;
2147 vs
->client_pf
.bytes_per_pixel
= bits_per_pixel
/ 8;
2148 vs
->client_pf
.depth
= bits_per_pixel
== 32 ? 24 : bits_per_pixel
;
2149 vs
->client_be
= big_endian_flag
;
2151 if (!true_color_flag
) {
2155 set_pixel_conversion(vs
);
2157 graphic_hw_invalidate(vs
->vd
->dcl
.con
);
2158 graphic_hw_update(vs
->vd
->dcl
.con
);
2161 static void pixel_format_message (VncState
*vs
) {
2162 char pad
[3] = { 0, 0, 0 };
2164 vs
->client_pf
= qemu_default_pixelformat(32);
2166 vnc_write_u8(vs
, vs
->client_pf
.bits_per_pixel
); /* bits-per-pixel */
2167 vnc_write_u8(vs
, vs
->client_pf
.depth
); /* depth */
2169 #ifdef HOST_WORDS_BIGENDIAN
2170 vnc_write_u8(vs
, 1); /* big-endian-flag */
2172 vnc_write_u8(vs
, 0); /* big-endian-flag */
2174 vnc_write_u8(vs
, 1); /* true-color-flag */
2175 vnc_write_u16(vs
, vs
->client_pf
.rmax
); /* red-max */
2176 vnc_write_u16(vs
, vs
->client_pf
.gmax
); /* green-max */
2177 vnc_write_u16(vs
, vs
->client_pf
.bmax
); /* blue-max */
2178 vnc_write_u8(vs
, vs
->client_pf
.rshift
); /* red-shift */
2179 vnc_write_u8(vs
, vs
->client_pf
.gshift
); /* green-shift */
2180 vnc_write_u8(vs
, vs
->client_pf
.bshift
); /* blue-shift */
2181 vnc_write(vs
, pad
, 3); /* padding */
2183 vnc_hextile_set_pixel_conversion(vs
, 0);
2184 vs
->write_pixels
= vnc_write_pixels_copy
;
2187 static void vnc_colordepth(VncState
*vs
)
2189 if (vnc_has_feature(vs
, VNC_FEATURE_WMVI
)) {
2190 /* Sending a WMVi message to notify the client*/
2191 vnc_lock_output(vs
);
2192 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2193 vnc_write_u8(vs
, 0);
2194 vnc_write_u16(vs
, 1); /* number of rects */
2195 vnc_framebuffer_update(vs
, 0, 0,
2196 pixman_image_get_width(vs
->vd
->server
),
2197 pixman_image_get_height(vs
->vd
->server
),
2199 pixel_format_message(vs
);
2200 vnc_unlock_output(vs
);
2203 set_pixel_conversion(vs
);
2207 static int protocol_client_msg(VncState
*vs
, uint8_t *data
, size_t len
)
2211 VncDisplay
*vd
= vs
->vd
;
2214 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2218 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT
:
2222 set_pixel_format(vs
, read_u8(data
, 4),
2223 read_u8(data
, 6), read_u8(data
, 7),
2224 read_u16(data
, 8), read_u16(data
, 10),
2225 read_u16(data
, 12), read_u8(data
, 14),
2226 read_u8(data
, 15), read_u8(data
, 16));
2228 case VNC_MSG_CLIENT_SET_ENCODINGS
:
2233 limit
= read_u16(data
, 2);
2235 return 4 + (limit
* 4);
2237 limit
= read_u16(data
, 2);
2239 for (i
= 0; i
< limit
; i
++) {
2240 int32_t val
= read_s32(data
, 4 + (i
* 4));
2241 memcpy(data
+ 4 + (i
* 4), &val
, sizeof(val
));
2244 set_encodings(vs
, (int32_t *)(data
+ 4), limit
);
2246 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST
:
2250 framebuffer_update_request(vs
,
2251 read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4),
2252 read_u16(data
, 6), read_u16(data
, 8));
2254 case VNC_MSG_CLIENT_KEY_EVENT
:
2258 key_event(vs
, read_u8(data
, 1), read_u32(data
, 4));
2260 case VNC_MSG_CLIENT_POINTER_EVENT
:
2264 pointer_event(vs
, read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4));
2266 case VNC_MSG_CLIENT_CUT_TEXT
:
2271 uint32_t dlen
= read_u32(data
, 4);
2272 if (dlen
> (1 << 20)) {
2273 error_report("vnc: client_cut_text msg payload has %u bytes"
2274 " which exceeds our limit of 1MB.", dlen
);
2275 vnc_client_error(vs
);
2283 client_cut_text(vs
, read_u32(data
, 4), data
+ 8);
2285 case VNC_MSG_CLIENT_QEMU
:
2289 switch (read_u8(data
, 1)) {
2290 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT
:
2294 ext_key_event(vs
, read_u16(data
, 2),
2295 read_u32(data
, 4), read_u32(data
, 8));
2297 case VNC_MSG_CLIENT_QEMU_AUDIO
:
2301 switch (read_u16 (data
, 2)) {
2302 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE
:
2305 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE
:
2308 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT
:
2311 switch (read_u8(data
, 4)) {
2312 case 0: vs
->as
.fmt
= AUD_FMT_U8
; break;
2313 case 1: vs
->as
.fmt
= AUD_FMT_S8
; break;
2314 case 2: vs
->as
.fmt
= AUD_FMT_U16
; break;
2315 case 3: vs
->as
.fmt
= AUD_FMT_S16
; break;
2316 case 4: vs
->as
.fmt
= AUD_FMT_U32
; break;
2317 case 5: vs
->as
.fmt
= AUD_FMT_S32
; break;
2319 VNC_DEBUG("Invalid audio format %d\n", read_u8(data
, 4));
2320 vnc_client_error(vs
);
2323 vs
->as
.nchannels
= read_u8(data
, 5);
2324 if (vs
->as
.nchannels
!= 1 && vs
->as
.nchannels
!= 2) {
2325 VNC_DEBUG("Invalid audio channel coount %d\n",
2327 vnc_client_error(vs
);
2330 vs
->as
.freq
= read_u32(data
, 6);
2333 VNC_DEBUG("Invalid audio message %d\n", read_u8(data
, 4));
2334 vnc_client_error(vs
);
2340 VNC_DEBUG("Msg: %d\n", read_u16(data
, 0));
2341 vnc_client_error(vs
);
2346 VNC_DEBUG("Msg: %d\n", data
[0]);
2347 vnc_client_error(vs
);
2351 vnc_read_when(vs
, protocol_client_msg
, 1);
2355 static int protocol_client_init(VncState
*vs
, uint8_t *data
, size_t len
)
2361 mode
= data
[0] ? VNC_SHARE_MODE_SHARED
: VNC_SHARE_MODE_EXCLUSIVE
;
2362 switch (vs
->vd
->share_policy
) {
2363 case VNC_SHARE_POLICY_IGNORE
:
2365 * Ignore the shared flag. Nothing to do here.
2367 * Doesn't conform to the rfb spec but is traditional qemu
2368 * behavior, thus left here as option for compatibility
2372 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
:
2374 * Policy: Allow clients ask for exclusive access.
2376 * Implementation: When a client asks for exclusive access,
2377 * disconnect all others. Shared connects are allowed as long
2378 * as no exclusive connection exists.
2380 * This is how the rfb spec suggests to handle the shared flag.
2382 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2384 QTAILQ_FOREACH(client
, &vs
->vd
->clients
, next
) {
2388 if (client
->share_mode
!= VNC_SHARE_MODE_EXCLUSIVE
&&
2389 client
->share_mode
!= VNC_SHARE_MODE_SHARED
) {
2392 vnc_disconnect_start(client
);
2395 if (mode
== VNC_SHARE_MODE_SHARED
) {
2396 if (vs
->vd
->num_exclusive
> 0) {
2397 vnc_disconnect_start(vs
);
2402 case VNC_SHARE_POLICY_FORCE_SHARED
:
2404 * Policy: Shared connects only.
2405 * Implementation: Disallow clients asking for exclusive access.
2407 * Useful for shared desktop sessions where you don't want
2408 * someone forgetting to say -shared when running the vnc
2409 * client disconnect everybody else.
2411 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2412 vnc_disconnect_start(vs
);
2417 vnc_set_share_mode(vs
, mode
);
2419 if (vs
->vd
->num_shared
> vs
->vd
->connections_limit
) {
2420 vnc_disconnect_start(vs
);
2424 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
2425 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
2426 vnc_write_u16(vs
, vs
->client_width
);
2427 vnc_write_u16(vs
, vs
->client_height
);
2429 pixel_format_message(vs
);
2432 size
= snprintf(buf
, sizeof(buf
), "QEMU (%s)", qemu_name
);
2433 if (size
> sizeof(buf
)) {
2437 size
= snprintf(buf
, sizeof(buf
), "QEMU");
2440 vnc_write_u32(vs
, size
);
2441 vnc_write(vs
, buf
, size
);
2444 vnc_client_cache_auth(vs
);
2445 vnc_qmp_event(vs
, QAPI_EVENT_VNC_INITIALIZED
);
2447 vnc_read_when(vs
, protocol_client_msg
, 1);
2452 void start_client_init(VncState
*vs
)
2454 vnc_read_when(vs
, protocol_client_init
, 1);
2457 static void make_challenge(VncState
*vs
)
2461 srand(time(NULL
)+getpid()+getpid()*987654+rand());
2463 for (i
= 0 ; i
< sizeof(vs
->challenge
) ; i
++)
2464 vs
->challenge
[i
] = (int) (256.0*rand()/(RAND_MAX
+1.0));
2467 static int protocol_client_auth_vnc(VncState
*vs
, uint8_t *data
, size_t len
)
2469 unsigned char response
[VNC_AUTH_CHALLENGE_SIZE
];
2471 unsigned char key
[8];
2472 time_t now
= time(NULL
);
2473 QCryptoCipher
*cipher
= NULL
;
2476 if (!vs
->vd
->password
) {
2477 VNC_DEBUG("No password configured on server");
2480 if (vs
->vd
->expires
< now
) {
2481 VNC_DEBUG("Password is expired");
2485 memcpy(response
, vs
->challenge
, VNC_AUTH_CHALLENGE_SIZE
);
2487 /* Calculate the expected challenge response */
2488 pwlen
= strlen(vs
->vd
->password
);
2489 for (i
=0; i
<sizeof(key
); i
++)
2490 key
[i
] = i
<pwlen
? vs
->vd
->password
[i
] : 0;
2492 cipher
= qcrypto_cipher_new(
2493 QCRYPTO_CIPHER_ALG_DES_RFB
,
2494 QCRYPTO_CIPHER_MODE_ECB
,
2495 key
, G_N_ELEMENTS(key
),
2498 VNC_DEBUG("Cannot initialize cipher %s",
2499 error_get_pretty(err
));
2504 if (qcrypto_cipher_encrypt(cipher
,
2507 VNC_AUTH_CHALLENGE_SIZE
,
2509 VNC_DEBUG("Cannot encrypt challenge %s",
2510 error_get_pretty(err
));
2515 /* Compare expected vs actual challenge response */
2516 if (memcmp(response
, data
, VNC_AUTH_CHALLENGE_SIZE
) != 0) {
2517 VNC_DEBUG("Client challenge response did not match\n");
2520 VNC_DEBUG("Accepting VNC challenge response\n");
2521 vnc_write_u32(vs
, 0); /* Accept auth */
2524 start_client_init(vs
);
2527 qcrypto_cipher_free(cipher
);
2531 vnc_write_u32(vs
, 1); /* Reject auth */
2532 if (vs
->minor
>= 8) {
2533 static const char err
[] = "Authentication failed";
2534 vnc_write_u32(vs
, sizeof(err
));
2535 vnc_write(vs
, err
, sizeof(err
));
2538 vnc_client_error(vs
);
2539 qcrypto_cipher_free(cipher
);
2543 void start_auth_vnc(VncState
*vs
)
2546 /* Send client a 'random' challenge */
2547 vnc_write(vs
, vs
->challenge
, sizeof(vs
->challenge
));
2550 vnc_read_when(vs
, protocol_client_auth_vnc
, sizeof(vs
->challenge
));
2554 static int protocol_client_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2556 /* We only advertise 1 auth scheme at a time, so client
2557 * must pick the one we sent. Verify this */
2558 if (data
[0] != vs
->auth
) { /* Reject auth */
2559 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data
[0]);
2560 vnc_write_u32(vs
, 1);
2561 if (vs
->minor
>= 8) {
2562 static const char err
[] = "Authentication failed";
2563 vnc_write_u32(vs
, sizeof(err
));
2564 vnc_write(vs
, err
, sizeof(err
));
2566 vnc_client_error(vs
);
2567 } else { /* Accept requested auth */
2568 VNC_DEBUG("Client requested auth %d\n", (int)data
[0]);
2571 VNC_DEBUG("Accept auth none\n");
2572 if (vs
->minor
>= 8) {
2573 vnc_write_u32(vs
, 0); /* Accept auth completion */
2576 start_client_init(vs
);
2580 VNC_DEBUG("Start VNC auth\n");
2584 case VNC_AUTH_VENCRYPT
:
2585 VNC_DEBUG("Accept VeNCrypt auth\n");
2586 start_auth_vencrypt(vs
);
2589 #ifdef CONFIG_VNC_SASL
2591 VNC_DEBUG("Accept SASL auth\n");
2592 start_auth_sasl(vs
);
2594 #endif /* CONFIG_VNC_SASL */
2596 default: /* Should not be possible, but just in case */
2597 VNC_DEBUG("Reject auth %d server code bug\n", vs
->auth
);
2598 vnc_write_u8(vs
, 1);
2599 if (vs
->minor
>= 8) {
2600 static const char err
[] = "Authentication failed";
2601 vnc_write_u32(vs
, sizeof(err
));
2602 vnc_write(vs
, err
, sizeof(err
));
2604 vnc_client_error(vs
);
2610 static int protocol_version(VncState
*vs
, uint8_t *version
, size_t len
)
2614 memcpy(local
, version
, 12);
2617 if (sscanf(local
, "RFB %03d.%03d\n", &vs
->major
, &vs
->minor
) != 2) {
2618 VNC_DEBUG("Malformed protocol version %s\n", local
);
2619 vnc_client_error(vs
);
2622 VNC_DEBUG("Client request protocol version %d.%d\n", vs
->major
, vs
->minor
);
2623 if (vs
->major
!= 3 ||
2629 VNC_DEBUG("Unsupported client version\n");
2630 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2632 vnc_client_error(vs
);
2635 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2636 * as equivalent to v3.3 by servers
2638 if (vs
->minor
== 4 || vs
->minor
== 5)
2641 if (vs
->minor
== 3) {
2642 if (vs
->auth
== VNC_AUTH_NONE
) {
2643 VNC_DEBUG("Tell client auth none\n");
2644 vnc_write_u32(vs
, vs
->auth
);
2646 start_client_init(vs
);
2647 } else if (vs
->auth
== VNC_AUTH_VNC
) {
2648 VNC_DEBUG("Tell client VNC auth\n");
2649 vnc_write_u32(vs
, vs
->auth
);
2653 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs
->auth
);
2654 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2656 vnc_client_error(vs
);
2659 VNC_DEBUG("Telling client we support auth %d\n", vs
->auth
);
2660 vnc_write_u8(vs
, 1); /* num auth */
2661 vnc_write_u8(vs
, vs
->auth
);
2662 vnc_read_when(vs
, protocol_client_auth
, 1);
2669 static VncRectStat
*vnc_stat_rect(VncDisplay
*vd
, int x
, int y
)
2671 struct VncSurface
*vs
= &vd
->guest
;
2673 return &vs
->stats
[y
/ VNC_STAT_RECT
][x
/ VNC_STAT_RECT
];
2676 void vnc_sent_lossy_rect(VncState
*vs
, int x
, int y
, int w
, int h
)
2680 w
= (x
+ w
) / VNC_STAT_RECT
;
2681 h
= (y
+ h
) / VNC_STAT_RECT
;
2685 for (j
= y
; j
<= h
; j
++) {
2686 for (i
= x
; i
<= w
; i
++) {
2687 vs
->lossy_rect
[j
][i
] = 1;
2692 static int vnc_refresh_lossy_rect(VncDisplay
*vd
, int x
, int y
)
2695 int sty
= y
/ VNC_STAT_RECT
;
2696 int stx
= x
/ VNC_STAT_RECT
;
2699 y
= y
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2700 x
= x
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2702 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2705 /* kernel send buffers are full -> refresh later */
2706 if (vs
->output
.offset
) {
2710 if (!vs
->lossy_rect
[sty
][stx
]) {
2714 vs
->lossy_rect
[sty
][stx
] = 0;
2715 for (j
= 0; j
< VNC_STAT_RECT
; ++j
) {
2716 bitmap_set(vs
->dirty
[y
+ j
],
2717 x
/ VNC_DIRTY_PIXELS_PER_BIT
,
2718 VNC_STAT_RECT
/ VNC_DIRTY_PIXELS_PER_BIT
);
2726 static int vnc_update_stats(VncDisplay
*vd
, struct timeval
* tv
)
2728 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2729 pixman_image_get_width(vd
->server
));
2730 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2731 pixman_image_get_height(vd
->server
));
2736 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2737 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2738 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2740 rect
->updated
= false;
2744 qemu_timersub(tv
, &VNC_REFRESH_STATS
, &res
);
2746 if (timercmp(&vd
->guest
.last_freq_check
, &res
, >)) {
2749 vd
->guest
.last_freq_check
= *tv
;
2751 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2752 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2753 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2754 int count
= ARRAY_SIZE(rect
->times
);
2755 struct timeval min
, max
;
2757 if (!timerisset(&rect
->times
[count
- 1])) {
2761 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2762 qemu_timersub(tv
, &max
, &res
);
2764 if (timercmp(&res
, &VNC_REFRESH_LOSSY
, >)) {
2766 has_dirty
+= vnc_refresh_lossy_rect(vd
, x
, y
);
2767 memset(rect
->times
, 0, sizeof (rect
->times
));
2771 min
= rect
->times
[rect
->idx
];
2772 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2773 qemu_timersub(&max
, &min
, &res
);
2775 rect
->freq
= res
.tv_sec
+ res
.tv_usec
/ 1000000.;
2776 rect
->freq
/= count
;
2777 rect
->freq
= 1. / rect
->freq
;
2783 double vnc_update_freq(VncState
*vs
, int x
, int y
, int w
, int h
)
2789 x
= (x
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2790 y
= (y
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2792 for (j
= y
; j
<= y
+ h
; j
+= VNC_STAT_RECT
) {
2793 for (i
= x
; i
<= x
+ w
; i
+= VNC_STAT_RECT
) {
2794 total
+= vnc_stat_rect(vs
->vd
, i
, j
)->freq
;
2806 static void vnc_rect_updated(VncDisplay
*vd
, int x
, int y
, struct timeval
* tv
)
2810 rect
= vnc_stat_rect(vd
, x
, y
);
2811 if (rect
->updated
) {
2814 rect
->times
[rect
->idx
] = *tv
;
2815 rect
->idx
= (rect
->idx
+ 1) % ARRAY_SIZE(rect
->times
);
2816 rect
->updated
= true;
2819 static int vnc_refresh_server_surface(VncDisplay
*vd
)
2821 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2822 pixman_image_get_width(vd
->server
));
2823 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2824 pixman_image_get_height(vd
->server
));
2825 int cmp_bytes
, server_stride
, line_bytes
, guest_ll
, guest_stride
, y
= 0;
2826 uint8_t *guest_row0
= NULL
, *server_row0
;
2829 pixman_image_t
*tmpbuf
= NULL
;
2831 struct timeval tv
= { 0, 0 };
2833 if (!vd
->non_adaptive
) {
2834 gettimeofday(&tv
, NULL
);
2835 has_dirty
= vnc_update_stats(vd
, &tv
);
2839 * Walk through the guest dirty map.
2840 * Check and copy modified bits from guest to server surface.
2841 * Update server dirty map.
2843 server_row0
= (uint8_t *)pixman_image_get_data(vd
->server
);
2844 server_stride
= guest_stride
= guest_ll
=
2845 pixman_image_get_stride(vd
->server
);
2846 cmp_bytes
= MIN(VNC_DIRTY_PIXELS_PER_BIT
* VNC_SERVER_FB_BYTES
,
2848 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2849 int width
= pixman_image_get_width(vd
->server
);
2850 tmpbuf
= qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT
, width
);
2853 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd
->guest
.fb
));
2854 guest_row0
= (uint8_t *)pixman_image_get_data(vd
->guest
.fb
);
2855 guest_stride
= pixman_image_get_stride(vd
->guest
.fb
);
2856 guest_ll
= pixman_image_get_width(vd
->guest
.fb
) * ((guest_bpp
+ 7) / 8);
2858 line_bytes
= MIN(server_stride
, guest_ll
);
2862 uint8_t *guest_ptr
, *server_ptr
;
2863 unsigned long offset
= find_next_bit((unsigned long *) &vd
->guest
.dirty
,
2864 height
* VNC_DIRTY_BPL(&vd
->guest
),
2865 y
* VNC_DIRTY_BPL(&vd
->guest
));
2866 if (offset
== height
* VNC_DIRTY_BPL(&vd
->guest
)) {
2867 /* no more dirty bits */
2870 y
= offset
/ VNC_DIRTY_BPL(&vd
->guest
);
2871 x
= offset
% VNC_DIRTY_BPL(&vd
->guest
);
2873 server_ptr
= server_row0
+ y
* server_stride
+ x
* cmp_bytes
;
2875 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2876 qemu_pixman_linebuf_fill(tmpbuf
, vd
->guest
.fb
, width
, 0, y
);
2877 guest_ptr
= (uint8_t *)pixman_image_get_data(tmpbuf
);
2879 guest_ptr
= guest_row0
+ y
* guest_stride
;
2881 guest_ptr
+= x
* cmp_bytes
;
2883 for (; x
< DIV_ROUND_UP(width
, VNC_DIRTY_PIXELS_PER_BIT
);
2884 x
++, guest_ptr
+= cmp_bytes
, server_ptr
+= cmp_bytes
) {
2885 int _cmp_bytes
= cmp_bytes
;
2886 if (!test_and_clear_bit(x
, vd
->guest
.dirty
[y
])) {
2889 if ((x
+ 1) * cmp_bytes
> line_bytes
) {
2890 _cmp_bytes
= line_bytes
- x
* cmp_bytes
;
2892 assert(_cmp_bytes
>= 0);
2893 if (memcmp(server_ptr
, guest_ptr
, _cmp_bytes
) == 0) {
2896 memcpy(server_ptr
, guest_ptr
, _cmp_bytes
);
2897 if (!vd
->non_adaptive
) {
2898 vnc_rect_updated(vd
, x
* VNC_DIRTY_PIXELS_PER_BIT
,
2901 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2902 set_bit(x
, vs
->dirty
[y
]);
2909 qemu_pixman_image_unref(tmpbuf
);
2913 static void vnc_refresh(DisplayChangeListener
*dcl
)
2915 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
2917 int has_dirty
, rects
= 0;
2919 if (QTAILQ_EMPTY(&vd
->clients
)) {
2920 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_MAX
);
2924 graphic_hw_update(vd
->dcl
.con
);
2926 if (vnc_trylock_display(vd
)) {
2927 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2931 has_dirty
= vnc_refresh_server_surface(vd
);
2932 vnc_unlock_display(vd
);
2934 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
2935 rects
+= vnc_update_client(vs
, has_dirty
, false);
2936 /* vs might be free()ed here */
2939 if (has_dirty
&& rects
) {
2940 vd
->dcl
.update_interval
/= 2;
2941 if (vd
->dcl
.update_interval
< VNC_REFRESH_INTERVAL_BASE
) {
2942 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_BASE
;
2945 vd
->dcl
.update_interval
+= VNC_REFRESH_INTERVAL_INC
;
2946 if (vd
->dcl
.update_interval
> VNC_REFRESH_INTERVAL_MAX
) {
2947 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_MAX
;
2952 static void vnc_connect(VncDisplay
*vd
, QIOChannelSocket
*sioc
,
2953 bool skipauth
, bool websocket
)
2955 VncState
*vs
= g_new0(VncState
, 1);
2956 bool first_client
= QTAILQ_EMPTY(&vd
->clients
);
2960 object_ref(OBJECT(vs
->sioc
));
2961 vs
->ioc
= QIO_CHANNEL(sioc
);
2962 object_ref(OBJECT(vs
->ioc
));
2965 buffer_init(&vs
->input
, "vnc-input/%p", sioc
);
2966 buffer_init(&vs
->output
, "vnc-output/%p", sioc
);
2967 buffer_init(&vs
->jobs_buffer
, "vnc-jobs_buffer/%p", sioc
);
2969 buffer_init(&vs
->tight
.tight
, "vnc-tight/%p", sioc
);
2970 buffer_init(&vs
->tight
.zlib
, "vnc-tight-zlib/%p", sioc
);
2971 buffer_init(&vs
->tight
.gradient
, "vnc-tight-gradient/%p", sioc
);
2972 #ifdef CONFIG_VNC_JPEG
2973 buffer_init(&vs
->tight
.jpeg
, "vnc-tight-jpeg/%p", sioc
);
2975 #ifdef CONFIG_VNC_PNG
2976 buffer_init(&vs
->tight
.png
, "vnc-tight-png/%p", sioc
);
2978 buffer_init(&vs
->zlib
.zlib
, "vnc-zlib/%p", sioc
);
2979 buffer_init(&vs
->zrle
.zrle
, "vnc-zrle/%p", sioc
);
2980 buffer_init(&vs
->zrle
.fb
, "vnc-zrle-fb/%p", sioc
);
2981 buffer_init(&vs
->zrle
.zlib
, "vnc-zrle-zlib/%p", sioc
);
2984 vs
->auth
= VNC_AUTH_NONE
;
2985 vs
->subauth
= VNC_AUTH_INVALID
;
2988 vs
->auth
= vd
->ws_auth
;
2989 vs
->subauth
= VNC_AUTH_INVALID
;
2991 vs
->auth
= vd
->auth
;
2992 vs
->subauth
= vd
->subauth
;
2995 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
2996 sioc
, websocket
, vs
->auth
, vs
->subauth
);
2998 vs
->lossy_rect
= g_malloc0(VNC_STAT_ROWS
* sizeof (*vs
->lossy_rect
));
2999 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
3000 vs
->lossy_rect
[i
] = g_new0(uint8_t, VNC_STAT_COLS
);
3003 VNC_DEBUG("New client on socket %p\n", vs
->sioc
);
3004 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
3005 qio_channel_set_blocking(vs
->ioc
, false, NULL
);
3009 vs
->ioc_tag
= qio_channel_add_watch(
3010 vs
->ioc
, G_IO_IN
, vncws_tls_handshake_io
, vs
, NULL
);
3012 vs
->ioc_tag
= qio_channel_add_watch(
3013 vs
->ioc
, G_IO_IN
, vncws_handshake_io
, vs
, NULL
);
3016 vs
->ioc_tag
= qio_channel_add_watch(
3017 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
3020 vnc_client_cache_addr(vs
);
3021 vnc_qmp_event(vs
, QAPI_EVENT_VNC_CONNECTED
);
3022 vnc_set_share_mode(vs
, VNC_SHARE_MODE_CONNECTING
);
3027 vs
->as
.freq
= 44100;
3028 vs
->as
.nchannels
= 2;
3029 vs
->as
.fmt
= AUD_FMT_S16
;
3030 vs
->as
.endianness
= 0;
3032 qemu_mutex_init(&vs
->output_mutex
);
3033 vs
->bh
= qemu_bh_new(vnc_jobs_bh
, vs
);
3035 QTAILQ_INSERT_TAIL(&vd
->clients
, vs
, next
);
3037 vnc_update_server_surface(vd
);
3040 graphic_hw_update(vd
->dcl
.con
);
3042 if (!vs
->websocket
) {
3043 vnc_start_protocol(vs
);
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_start_protocol(VncState
*vs
)
3058 vnc_write(vs
, "RFB 003.008\n", 12);
3060 vnc_read_when(vs
, protocol_version
, 12);
3062 vs
->mouse_mode_notifier
.notify
= check_pointer_type_change
;
3063 qemu_add_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
3066 static gboolean
vnc_listen_io(QIOChannel
*ioc
,
3067 GIOCondition condition
,
3070 VncDisplay
*vd
= opaque
;
3071 QIOChannelSocket
*sioc
= NULL
;
3074 sioc
= qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc
), &err
);
3076 qio_channel_set_name(QIO_CHANNEL(sioc
),
3077 ioc
!= QIO_CHANNEL(vd
->lsock
) ?
3078 "vnc-ws-server" : "vnc-server");
3079 qio_channel_set_delay(QIO_CHANNEL(sioc
), false);
3080 vnc_connect(vd
, sioc
, false,
3081 ioc
!= QIO_CHANNEL(vd
->lsock
));
3082 object_unref(OBJECT(sioc
));
3084 /* client probably closed connection before we got there */
3091 static const DisplayChangeListenerOps dcl_ops
= {
3093 .dpy_refresh
= vnc_refresh
,
3094 .dpy_gfx_copy
= vnc_dpy_copy
,
3095 .dpy_gfx_update
= vnc_dpy_update
,
3096 .dpy_gfx_switch
= vnc_dpy_switch
,
3097 .dpy_gfx_check_format
= qemu_pixman_check_format
,
3098 .dpy_mouse_set
= vnc_mouse_set
,
3099 .dpy_cursor_define
= vnc_dpy_cursor_define
,
3102 void vnc_display_init(const char *id
)
3106 if (vnc_display_find(id
) != NULL
) {
3109 vd
= g_malloc0(sizeof(*vd
));
3111 vd
->id
= strdup(id
);
3112 QTAILQ_INSERT_TAIL(&vnc_displays
, vd
, next
);
3114 QTAILQ_INIT(&vd
->clients
);
3115 vd
->expires
= TIME_MAX
;
3117 if (keyboard_layout
) {
3118 trace_vnc_key_map_init(keyboard_layout
);
3119 vd
->kbd_layout
= init_keyboard_layout(name2keysym
, keyboard_layout
);
3121 vd
->kbd_layout
= init_keyboard_layout(name2keysym
, "en-us");
3124 if (!vd
->kbd_layout
) {
3128 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3129 vd
->connections_limit
= 32;
3131 qemu_mutex_init(&vd
->mutex
);
3132 vnc_start_worker_thread();
3134 vd
->dcl
.ops
= &dcl_ops
;
3135 register_displaychangelistener(&vd
->dcl
);
3139 static void vnc_display_close(VncDisplay
*vd
)
3144 vd
->is_unix
= false;
3145 if (vd
->lsock
!= NULL
) {
3146 if (vd
->lsock_tag
) {
3147 g_source_remove(vd
->lsock_tag
);
3149 object_unref(OBJECT(vd
->lsock
));
3152 if (vd
->lwebsock
!= NULL
) {
3153 if (vd
->lwebsock_tag
) {
3154 g_source_remove(vd
->lwebsock_tag
);
3156 object_unref(OBJECT(vd
->lwebsock
));
3157 vd
->lwebsock
= NULL
;
3159 vd
->auth
= VNC_AUTH_INVALID
;
3160 vd
->subauth
= VNC_AUTH_INVALID
;
3162 object_unparent(OBJECT(vd
->tlscreds
));
3163 vd
->tlscreds
= NULL
;
3165 g_free(vd
->tlsaclname
);
3166 vd
->tlsaclname
= NULL
;
3167 if (vd
->lock_key_sync
) {
3168 qemu_remove_led_event_handler(vd
->led
);
3172 int vnc_display_password(const char *id
, const char *password
)
3174 VncDisplay
*vd
= vnc_display_find(id
);
3179 if (vd
->auth
== VNC_AUTH_NONE
) {
3180 error_printf_unless_qmp("If you want use passwords please enable "
3181 "password auth using '-vnc ${dpy},password'.\n");
3185 g_free(vd
->password
);
3186 vd
->password
= g_strdup(password
);
3191 int vnc_display_pw_expire(const char *id
, time_t expires
)
3193 VncDisplay
*vd
= vnc_display_find(id
);
3199 vd
->expires
= expires
;
3203 static void vnc_display_print_local_addr(VncDisplay
*vd
)
3205 SocketAddress
*addr
;
3208 addr
= qio_channel_socket_get_local_address(vd
->lsock
, &err
);
3213 if (addr
->type
!= SOCKET_ADDRESS_KIND_INET
) {
3214 qapi_free_SocketAddress(addr
);
3217 error_printf_unless_qmp("VNC server running on %s:%s\n",
3218 addr
->u
.inet
.data
->host
,
3219 addr
->u
.inet
.data
->port
);
3220 qapi_free_SocketAddress(addr
);
3223 static QemuOptsList qemu_vnc_opts
= {
3225 .head
= QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts
.head
),
3226 .implied_opt_name
= "vnc",
3230 .type
= QEMU_OPT_STRING
,
3232 .name
= "websocket",
3233 .type
= QEMU_OPT_STRING
,
3235 .name
= "tls-creds",
3236 .type
= QEMU_OPT_STRING
,
3238 /* Deprecated in favour of tls-creds */
3240 .type
= QEMU_OPT_STRING
,
3243 .type
= QEMU_OPT_STRING
,
3246 .type
= QEMU_OPT_STRING
,
3249 .type
= QEMU_OPT_NUMBER
,
3251 .name
= "connections",
3252 .type
= QEMU_OPT_NUMBER
,
3255 .type
= QEMU_OPT_NUMBER
,
3258 .type
= QEMU_OPT_BOOL
,
3261 .type
= QEMU_OPT_BOOL
,
3264 .type
= QEMU_OPT_BOOL
,
3267 .type
= QEMU_OPT_BOOL
,
3269 .name
= "lock-key-sync",
3270 .type
= QEMU_OPT_BOOL
,
3272 .name
= "key-delay-ms",
3273 .type
= QEMU_OPT_NUMBER
,
3276 .type
= QEMU_OPT_BOOL
,
3278 /* Deprecated in favour of tls-creds */
3280 .type
= QEMU_OPT_BOOL
,
3282 /* Deprecated in favour of tls-creds */
3283 .name
= "x509verify",
3284 .type
= QEMU_OPT_STRING
,
3287 .type
= QEMU_OPT_BOOL
,
3290 .type
= QEMU_OPT_BOOL
,
3292 .name
= "non-adaptive",
3293 .type
= QEMU_OPT_BOOL
,
3295 { /* end of list */ }
3301 vnc_display_setup_auth(int *auth
,
3303 QCryptoTLSCreds
*tlscreds
,
3310 * We have a choice of 3 authentication options
3316 * The channel can be run in 2 modes
3321 * And TLS can use 2 types of credentials
3326 * We thus have 9 possible logical combinations
3331 * 4. tls + anon + none
3332 * 5. tls + anon + vnc
3333 * 6. tls + anon + sasl
3334 * 7. tls + x509 + none
3335 * 8. tls + x509 + vnc
3336 * 9. tls + x509 + sasl
3338 * These need to be mapped into the VNC auth schemes
3339 * in an appropriate manner. In regular VNC, all the
3340 * TLS options get mapped into VNC_AUTH_VENCRYPT
3343 * In websockets, the https:// protocol already provides
3344 * TLS support, so there is no need to make use of the
3345 * VeNCrypt extension. Furthermore, websockets browser
3346 * clients could not use VeNCrypt even if they wanted to,
3347 * as they cannot control when the TLS handshake takes
3348 * place. Thus there is no option but to rely on https://,
3349 * meaning combinations 4->6 and 7->9 will be mapped to
3350 * VNC auth schemes in the same way as combos 1->3.
3352 * Regardless of fact that we have a different mapping to
3353 * VNC auth mechs for plain VNC vs websockets VNC, the end
3354 * result has the same security characteristics.
3356 if (websocket
|| !tlscreds
) {
3358 VNC_DEBUG("Initializing VNC server with password auth\n");
3359 *auth
= VNC_AUTH_VNC
;
3361 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3362 *auth
= VNC_AUTH_SASL
;
3364 VNC_DEBUG("Initializing VNC server with no auth\n");
3365 *auth
= VNC_AUTH_NONE
;
3367 *subauth
= VNC_AUTH_INVALID
;
3369 bool is_x509
= object_dynamic_cast(OBJECT(tlscreds
),
3370 TYPE_QCRYPTO_TLS_CREDS_X509
) != NULL
;
3371 bool is_anon
= object_dynamic_cast(OBJECT(tlscreds
),
3372 TYPE_QCRYPTO_TLS_CREDS_ANON
) != NULL
;
3374 if (!is_x509
&& !is_anon
) {
3376 "Unsupported TLS cred type %s",
3377 object_get_typename(OBJECT(tlscreds
)));
3380 *auth
= VNC_AUTH_VENCRYPT
;
3383 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3384 *subauth
= VNC_AUTH_VENCRYPT_X509VNC
;
3386 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3387 *subauth
= VNC_AUTH_VENCRYPT_TLSVNC
;
3392 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3393 *subauth
= VNC_AUTH_VENCRYPT_X509SASL
;
3395 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3396 *subauth
= VNC_AUTH_VENCRYPT_TLSSASL
;
3400 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3401 *subauth
= VNC_AUTH_VENCRYPT_X509NONE
;
3403 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3404 *subauth
= VNC_AUTH_VENCRYPT_TLSNONE
;
3413 * Handle back compat with old CLI syntax by creating some
3414 * suitable QCryptoTLSCreds objects
3416 static QCryptoTLSCreds
*
3417 vnc_display_create_creds(bool x509
,
3423 gchar
*credsid
= g_strdup_printf("tlsvnc%s", id
);
3424 Object
*parent
= object_get_objects_root();
3429 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509
,
3433 "endpoint", "server",
3435 "verify-peer", x509verify
? "yes" : "no",
3438 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON
,
3442 "endpoint", "server",
3449 error_propagate(errp
, err
);
3453 return QCRYPTO_TLS_CREDS(creds
);
3457 void vnc_display_open(const char *id
, Error
**errp
)
3459 VncDisplay
*vd
= vnc_display_find(id
);
3460 QemuOpts
*opts
= qemu_opts_find(&qemu_vnc_opts
, id
);
3461 SocketAddress
*saddr
= NULL
, *wsaddr
= NULL
;
3462 const char *share
, *device_id
;
3464 bool password
= false;
3465 bool reverse
= false;
3469 int show_vnc_port
= 0;
3471 #ifdef CONFIG_VNC_SASL
3475 int lock_key_sync
= 1;
3477 bool ws_enabled
= false;
3480 error_setg(errp
, "VNC display not active");
3483 vnc_display_close(vd
);
3488 vnc
= qemu_opt_get(opts
, "vnc");
3489 if (!vnc
|| strcmp(vnc
, "none") == 0) {
3493 h
= strrchr(vnc
, ':');
3495 size_t hlen
= h
- vnc
;
3497 const char *websocket
= qemu_opt_get(opts
, "websocket");
3498 int to
= qemu_opt_get_number(opts
, "to", 0);
3499 bool has_ipv4
= qemu_opt_get(opts
, "ipv4");
3500 bool has_ipv6
= qemu_opt_get(opts
, "ipv6");
3501 bool ipv4
= qemu_opt_get_bool(opts
, "ipv4", false);
3502 bool ipv6
= qemu_opt_get_bool(opts
, "ipv6", false);
3504 saddr
= g_new0(SocketAddress
, 1);
3506 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1
)) {
3508 "SHA1 hash support is required for websockets");
3512 wsaddr
= g_new0(SocketAddress
, 1);
3516 if (strncmp(vnc
, "unix:", 5) == 0) {
3517 saddr
->type
= SOCKET_ADDRESS_KIND_UNIX
;
3518 saddr
->u
.q_unix
.data
= g_new0(UnixSocketAddress
, 1);
3519 saddr
->u
.q_unix
.data
->path
= g_strdup(vnc
+ 5);
3522 error_setg(errp
, "UNIX sockets not supported with websock");
3526 unsigned long long baseport
;
3527 InetSocketAddress
*inet
;
3528 saddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3529 inet
= saddr
->u
.inet
.data
= g_new0(InetSocketAddress
, 1);
3530 if (vnc
[0] == '[' && vnc
[hlen
- 1] == ']') {
3531 inet
->host
= g_strndup(vnc
+ 1, hlen
- 2);
3533 inet
->host
= g_strndup(vnc
, hlen
);
3535 if (parse_uint_full(h
+ 1, &baseport
, 10) < 0) {
3536 error_setg(errp
, "can't convert to a number: %s", h
+ 1);
3539 if (baseport
> 65535 ||
3540 baseport
+ 5900 > 65535) {
3541 error_setg(errp
, "port %s out of range", h
+ 1);
3544 inet
->port
= g_strdup_printf(
3545 "%d", (int)baseport
+ 5900);
3548 inet
->has_to
= true;
3549 inet
->to
= to
+ 5900;
3553 inet
->has_ipv4
= has_ipv4
;
3555 inet
->has_ipv6
= has_ipv6
;
3558 wsaddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3559 inet
= wsaddr
->u
.inet
.data
= g_new0(InetSocketAddress
, 1);
3560 inet
->host
= g_strdup(saddr
->u
.inet
.data
->host
);
3561 inet
->port
= g_strdup(websocket
);
3564 inet
->has_to
= true;
3568 inet
->has_ipv4
= has_ipv4
;
3570 inet
->has_ipv6
= has_ipv6
;
3574 error_setg(errp
, "no vnc port specified");
3578 password
= qemu_opt_get_bool(opts
, "password", false);
3580 if (fips_get_state()) {
3582 "VNC password auth disabled due to FIPS mode, "
3583 "consider using the VeNCrypt or SASL authentication "
3584 "methods as an alternative");
3587 if (!qcrypto_cipher_supports(
3588 QCRYPTO_CIPHER_ALG_DES_RFB
, QCRYPTO_CIPHER_MODE_ECB
)) {
3590 "Cipher backend does not support DES RFB algorithm");
3595 reverse
= qemu_opt_get_bool(opts
, "reverse", false);
3596 lock_key_sync
= qemu_opt_get_bool(opts
, "lock-key-sync", true);
3597 key_delay_ms
= qemu_opt_get_number(opts
, "key-delay-ms", 1);
3598 sasl
= qemu_opt_get_bool(opts
, "sasl", false);
3599 #ifndef CONFIG_VNC_SASL
3601 error_setg(errp
, "VNC SASL auth requires cyrus-sasl support");
3604 #endif /* CONFIG_VNC_SASL */
3605 credid
= qemu_opt_get(opts
, "tls-creds");
3608 if (qemu_opt_get(opts
, "tls") ||
3609 qemu_opt_get(opts
, "x509") ||
3610 qemu_opt_get(opts
, "x509verify")) {
3612 "'tls-creds' parameter is mutually exclusive with "
3613 "'tls', 'x509' and 'x509verify' parameters");
3617 creds
= object_resolve_path_component(
3618 object_get_objects_root(), credid
);
3620 error_setg(errp
, "No TLS credentials with id '%s'",
3624 vd
->tlscreds
= (QCryptoTLSCreds
*)
3625 object_dynamic_cast(creds
,
3626 TYPE_QCRYPTO_TLS_CREDS
);
3627 if (!vd
->tlscreds
) {
3628 error_setg(errp
, "Object with id '%s' is not TLS credentials",
3632 object_ref(OBJECT(vd
->tlscreds
));
3634 if (vd
->tlscreds
->endpoint
!= QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
) {
3636 "Expecting TLS credentials with a server endpoint");
3641 bool tls
= false, x509
= false, x509verify
= false;
3642 tls
= qemu_opt_get_bool(opts
, "tls", false);
3644 path
= qemu_opt_get(opts
, "x509");
3649 path
= qemu_opt_get(opts
, "x509verify");
3655 vd
->tlscreds
= vnc_display_create_creds(x509
,
3660 if (!vd
->tlscreds
) {
3665 acl
= qemu_opt_get_bool(opts
, "acl", false);
3667 share
= qemu_opt_get(opts
, "share");
3669 if (strcmp(share
, "ignore") == 0) {
3670 vd
->share_policy
= VNC_SHARE_POLICY_IGNORE
;
3671 } else if (strcmp(share
, "allow-exclusive") == 0) {
3672 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3673 } else if (strcmp(share
, "force-shared") == 0) {
3674 vd
->share_policy
= VNC_SHARE_POLICY_FORCE_SHARED
;
3676 error_setg(errp
, "unknown vnc share= option");
3680 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3682 vd
->connections_limit
= qemu_opt_get_number(opts
, "connections", 32);
3684 #ifdef CONFIG_VNC_JPEG
3685 vd
->lossy
= qemu_opt_get_bool(opts
, "lossy", false);
3687 vd
->non_adaptive
= qemu_opt_get_bool(opts
, "non-adaptive", false);
3688 /* adaptive updates are only used with tight encoding and
3689 * if lossy updates are enabled so we can disable all the
3690 * calculations otherwise */
3692 vd
->non_adaptive
= true;
3696 if (strcmp(vd
->id
, "default") == 0) {
3697 vd
->tlsaclname
= g_strdup("vnc.x509dname");
3699 vd
->tlsaclname
= g_strdup_printf("vnc.%s.x509dname", vd
->id
);
3701 qemu_acl_init(vd
->tlsaclname
);
3703 #ifdef CONFIG_VNC_SASL
3707 if (strcmp(vd
->id
, "default") == 0) {
3708 aclname
= g_strdup("vnc.username");
3710 aclname
= g_strdup_printf("vnc.%s.username", vd
->id
);
3712 vd
->sasl
.acl
= qemu_acl_init(aclname
);
3717 if (vnc_display_setup_auth(&vd
->auth
, &vd
->subauth
,
3718 vd
->tlscreds
, password
,
3719 sasl
, false, errp
) < 0) {
3723 if (vnc_display_setup_auth(&vd
->ws_auth
, &vd
->ws_subauth
,
3724 vd
->tlscreds
, password
,
3725 sasl
, true, errp
) < 0) {
3729 #ifdef CONFIG_VNC_SASL
3730 if ((saslErr
= sasl_server_init(NULL
, "qemu")) != SASL_OK
) {
3731 error_setg(errp
, "Failed to initialize SASL auth: %s",
3732 sasl_errstring(saslErr
, NULL
, NULL
));
3736 vd
->lock_key_sync
= lock_key_sync
;
3737 if (lock_key_sync
) {
3738 vd
->led
= qemu_add_led_event_handler(kbd_leds
, vd
);
3741 vd
->key_delay_ms
= key_delay_ms
;
3743 device_id
= qemu_opt_get(opts
, "display");
3745 int head
= qemu_opt_get_number(opts
, "head", 0);
3748 con
= qemu_console_lookup_by_device_name(device_id
, head
, &err
);
3750 error_propagate(errp
, err
);
3757 if (con
!= vd
->dcl
.con
) {
3758 unregister_displaychangelistener(&vd
->dcl
);
3760 register_displaychangelistener(&vd
->dcl
);
3764 /* connect to viewer */
3765 QIOChannelSocket
*sioc
= NULL
;
3767 vd
->lwebsock
= NULL
;
3769 error_setg(errp
, "Cannot use websockets in reverse mode");
3772 vd
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3773 sioc
= qio_channel_socket_new();
3774 qio_channel_set_name(QIO_CHANNEL(sioc
), "vnc-reverse");
3775 if (qio_channel_socket_connect_sync(sioc
, saddr
, errp
) < 0) {
3778 vnc_connect(vd
, sioc
, false, false);
3779 object_unref(OBJECT(sioc
));
3781 vd
->lsock
= qio_channel_socket_new();
3782 qio_channel_set_name(QIO_CHANNEL(vd
->lsock
), "vnc-listen");
3783 if (qio_channel_socket_listen_sync(vd
->lsock
, saddr
, errp
) < 0) {
3786 vd
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3789 vd
->lwebsock
= qio_channel_socket_new();
3790 qio_channel_set_name(QIO_CHANNEL(vd
->lwebsock
), "vnc-ws-listen");
3791 if (qio_channel_socket_listen_sync(vd
->lwebsock
,
3792 wsaddr
, errp
) < 0) {
3793 object_unref(OBJECT(vd
->lsock
));
3799 vd
->lsock_tag
= qio_channel_add_watch(
3800 QIO_CHANNEL(vd
->lsock
),
3801 G_IO_IN
, vnc_listen_io
, vd
, NULL
);
3803 vd
->lwebsock_tag
= qio_channel_add_watch(
3804 QIO_CHANNEL(vd
->lwebsock
),
3805 G_IO_IN
, vnc_listen_io
, vd
, NULL
);
3809 if (show_vnc_port
) {
3810 vnc_display_print_local_addr(vd
);
3813 qapi_free_SocketAddress(saddr
);
3814 qapi_free_SocketAddress(wsaddr
);
3818 qapi_free_SocketAddress(saddr
);
3819 qapi_free_SocketAddress(wsaddr
);
3823 void vnc_display_add_client(const char *id
, int csock
, bool skipauth
)
3825 VncDisplay
*vd
= vnc_display_find(id
);
3826 QIOChannelSocket
*sioc
;
3832 sioc
= qio_channel_socket_new_fd(csock
, NULL
);
3834 qio_channel_set_name(QIO_CHANNEL(sioc
), "vnc-server");
3835 vnc_connect(vd
, sioc
, skipauth
, false);
3836 object_unref(OBJECT(sioc
));
3840 static void vnc_auto_assign_id(QemuOptsList
*olist
, QemuOpts
*opts
)
3845 id
= g_strdup("default");
3846 while (qemu_opts_find(olist
, id
)) {
3848 id
= g_strdup_printf("vnc%d", i
++);
3850 qemu_opts_set_id(opts
, id
);
3853 QemuOpts
*vnc_parse(const char *str
, Error
**errp
)
3855 QemuOptsList
*olist
= qemu_find_opts("vnc");
3856 QemuOpts
*opts
= qemu_opts_parse(olist
, str
, true, errp
);
3863 id
= qemu_opts_id(opts
);
3865 /* auto-assign id if not present */
3866 vnc_auto_assign_id(olist
, opts
);
3871 int vnc_init_func(void *opaque
, QemuOpts
*opts
, Error
**errp
)
3873 Error
*local_err
= NULL
;
3874 char *id
= (char *)qemu_opts_id(opts
);
3877 vnc_display_init(id
);
3878 vnc_display_open(id
, &local_err
);
3879 if (local_err
!= NULL
) {
3880 error_reportf_err(local_err
, "Failed to start VNC server: ");
3886 static void vnc_register_config(void)
3888 qemu_add_opts(&qemu_vnc_opts
);
3890 opts_init(vnc_register_config
);