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 } else if (ret
!= QIO_CHANNEL_ERR_BLOCK
) {
1260 VNC_DEBUG("Closing down client sock: ret %zd (%s)\n",
1261 ret
, errp
? error_get_pretty(*errp
) : "Unknown");
1264 vnc_disconnect_start(vs
);
1275 void vnc_client_error(VncState
*vs
)
1277 VNC_DEBUG("Closing down client sock: protocol error\n");
1278 vnc_disconnect_start(vs
);
1283 * Called to write a chunk of data to the client socket. The data may
1284 * be the raw data, or may have already been encoded by SASL.
1285 * The data will be written either straight onto the socket, or
1286 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1288 * NB, it is theoretically possible to have 2 layers of encryption,
1289 * both SASL, and this TLS layer. It is highly unlikely in practice
1290 * though, since SASL encryption will typically be a no-op if TLS
1293 * Returns the number of bytes written, which may be less than
1294 * the requested 'datalen' if the socket would block. Returns
1295 * -1 on error, and disconnects the client socket.
1297 ssize_t
vnc_client_write_buf(VncState
*vs
, const uint8_t *data
, size_t datalen
)
1301 ret
= qio_channel_write(
1302 vs
->ioc
, (const char *)data
, datalen
, &err
);
1303 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data
, datalen
, ret
);
1304 return vnc_client_io_error(vs
, ret
, &err
);
1309 * Called to write buffered data to the client socket, when not
1310 * using any SASL SSF encryption layers. Will write as much data
1311 * as possible without blocking. If all buffered data is written,
1312 * will switch the FD poll() handler back to read monitoring.
1314 * Returns the number of bytes written, which may be less than
1315 * the buffered output data if the socket would block. Returns
1316 * -1 on error, and disconnects the client socket.
1318 static ssize_t
vnc_client_write_plain(VncState
*vs
)
1322 #ifdef CONFIG_VNC_SASL
1323 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1324 vs
->output
.buffer
, vs
->output
.capacity
, vs
->output
.offset
,
1325 vs
->sasl
.waitWriteSSF
);
1327 if (vs
->sasl
.conn
&&
1329 vs
->sasl
.waitWriteSSF
) {
1330 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->sasl
.waitWriteSSF
);
1332 vs
->sasl
.waitWriteSSF
-= ret
;
1334 #endif /* CONFIG_VNC_SASL */
1335 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->output
.offset
);
1339 buffer_advance(&vs
->output
, ret
);
1341 if (vs
->output
.offset
== 0) {
1343 g_source_remove(vs
->ioc_tag
);
1345 vs
->ioc_tag
= qio_channel_add_watch(
1346 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1354 * First function called whenever there is data to be written to
1355 * the client socket. Will delegate actual work according to whether
1356 * SASL SSF layers are enabled (thus requiring encryption calls)
1358 static void vnc_client_write_locked(VncState
*vs
)
1360 #ifdef CONFIG_VNC_SASL
1361 if (vs
->sasl
.conn
&&
1363 !vs
->sasl
.waitWriteSSF
) {
1364 vnc_client_write_sasl(vs
);
1366 #endif /* CONFIG_VNC_SASL */
1368 vnc_client_write_plain(vs
);
1372 static void vnc_client_write(VncState
*vs
)
1375 vnc_lock_output(vs
);
1376 if (vs
->output
.offset
) {
1377 vnc_client_write_locked(vs
);
1378 } else if (vs
->ioc
!= NULL
) {
1380 g_source_remove(vs
->ioc_tag
);
1382 vs
->ioc_tag
= qio_channel_add_watch(
1383 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1385 vnc_unlock_output(vs
);
1388 void vnc_read_when(VncState
*vs
, VncReadEvent
*func
, size_t expecting
)
1390 vs
->read_handler
= func
;
1391 vs
->read_handler_expect
= expecting
;
1396 * Called to read a chunk of data from the client socket. The data may
1397 * be the raw data, or may need to be further decoded by SASL.
1398 * The data will be read either straight from to the socket, or
1399 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1401 * NB, it is theoretically possible to have 2 layers of encryption,
1402 * both SASL, and this TLS layer. It is highly unlikely in practice
1403 * though, since SASL encryption will typically be a no-op if TLS
1406 * Returns the number of bytes read, which may be less than
1407 * the requested 'datalen' if the socket would block. Returns
1408 * -1 on error, and disconnects the client socket.
1410 ssize_t
vnc_client_read_buf(VncState
*vs
, uint8_t *data
, size_t datalen
)
1414 ret
= qio_channel_read(
1415 vs
->ioc
, (char *)data
, datalen
, &err
);
1416 VNC_DEBUG("Read wire %p %zd -> %ld\n", data
, datalen
, ret
);
1417 return vnc_client_io_error(vs
, ret
, &err
);
1422 * Called to read data from the client socket to the input buffer,
1423 * when not using any SASL SSF encryption layers. Will read as much
1424 * data as possible without blocking.
1426 * Returns the number of bytes read. Returns -1 on error, and
1427 * disconnects the client socket.
1429 static ssize_t
vnc_client_read_plain(VncState
*vs
)
1432 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1433 vs
->input
.buffer
, vs
->input
.capacity
, vs
->input
.offset
);
1434 buffer_reserve(&vs
->input
, 4096);
1435 ret
= vnc_client_read_buf(vs
, buffer_end(&vs
->input
), 4096);
1438 vs
->input
.offset
+= ret
;
1442 static void vnc_jobs_bh(void *opaque
)
1444 VncState
*vs
= opaque
;
1446 vnc_jobs_consume_buffer(vs
);
1450 * First function called whenever there is more data to be read from
1451 * the client socket. Will delegate actual work according to whether
1452 * SASL SSF layers are enabled (thus requiring decryption calls)
1453 * Returns 0 on success, -1 if client disconnected
1455 static int vnc_client_read(VncState
*vs
)
1459 #ifdef CONFIG_VNC_SASL
1460 if (vs
->sasl
.conn
&& vs
->sasl
.runSSF
)
1461 ret
= vnc_client_read_sasl(vs
);
1463 #endif /* CONFIG_VNC_SASL */
1464 ret
= vnc_client_read_plain(vs
);
1466 if (vs
->disconnecting
) {
1467 vnc_disconnect_finish(vs
);
1473 while (vs
->read_handler
&& vs
->input
.offset
>= vs
->read_handler_expect
) {
1474 size_t len
= vs
->read_handler_expect
;
1477 ret
= vs
->read_handler(vs
, vs
->input
.buffer
, len
);
1478 if (vs
->disconnecting
) {
1479 vnc_disconnect_finish(vs
);
1484 buffer_advance(&vs
->input
, len
);
1486 vs
->read_handler_expect
= ret
;
1492 gboolean
vnc_client_io(QIOChannel
*ioc G_GNUC_UNUSED
,
1493 GIOCondition condition
, void *opaque
)
1495 VncState
*vs
= opaque
;
1496 if (condition
& G_IO_IN
) {
1497 if (vnc_client_read(vs
) < 0) {
1501 if (condition
& G_IO_OUT
) {
1502 vnc_client_write(vs
);
1508 void vnc_write(VncState
*vs
, const void *data
, size_t len
)
1510 buffer_reserve(&vs
->output
, len
);
1512 if (vs
->ioc
!= NULL
&& buffer_empty(&vs
->output
)) {
1514 g_source_remove(vs
->ioc_tag
);
1516 vs
->ioc_tag
= qio_channel_add_watch(
1517 vs
->ioc
, G_IO_IN
| G_IO_OUT
, vnc_client_io
, vs
, NULL
);
1520 buffer_append(&vs
->output
, data
, len
);
1523 void vnc_write_s32(VncState
*vs
, int32_t value
)
1525 vnc_write_u32(vs
, *(uint32_t *)&value
);
1528 void vnc_write_u32(VncState
*vs
, uint32_t value
)
1532 buf
[0] = (value
>> 24) & 0xFF;
1533 buf
[1] = (value
>> 16) & 0xFF;
1534 buf
[2] = (value
>> 8) & 0xFF;
1535 buf
[3] = value
& 0xFF;
1537 vnc_write(vs
, buf
, 4);
1540 void vnc_write_u16(VncState
*vs
, uint16_t value
)
1544 buf
[0] = (value
>> 8) & 0xFF;
1545 buf
[1] = value
& 0xFF;
1547 vnc_write(vs
, buf
, 2);
1550 void vnc_write_u8(VncState
*vs
, uint8_t value
)
1552 vnc_write(vs
, (char *)&value
, 1);
1555 void vnc_flush(VncState
*vs
)
1557 vnc_lock_output(vs
);
1558 if (vs
->ioc
!= NULL
&& vs
->output
.offset
) {
1559 vnc_client_write_locked(vs
);
1561 vnc_unlock_output(vs
);
1564 static uint8_t read_u8(uint8_t *data
, size_t offset
)
1566 return data
[offset
];
1569 static uint16_t read_u16(uint8_t *data
, size_t offset
)
1571 return ((data
[offset
] & 0xFF) << 8) | (data
[offset
+ 1] & 0xFF);
1574 static int32_t read_s32(uint8_t *data
, size_t offset
)
1576 return (int32_t)((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1577 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1580 uint32_t read_u32(uint8_t *data
, size_t offset
)
1582 return ((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1583 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1586 static void client_cut_text(VncState
*vs
, size_t len
, uint8_t *text
)
1590 static void check_pointer_type_change(Notifier
*notifier
, void *data
)
1592 VncState
*vs
= container_of(notifier
, VncState
, mouse_mode_notifier
);
1593 int absolute
= qemu_input_is_absolute();
1595 if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
) && vs
->absolute
!= absolute
) {
1596 vnc_lock_output(vs
);
1597 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1598 vnc_write_u8(vs
, 0);
1599 vnc_write_u16(vs
, 1);
1600 vnc_framebuffer_update(vs
, absolute
, 0,
1601 pixman_image_get_width(vs
->vd
->server
),
1602 pixman_image_get_height(vs
->vd
->server
),
1603 VNC_ENCODING_POINTER_TYPE_CHANGE
);
1604 vnc_unlock_output(vs
);
1607 vs
->absolute
= absolute
;
1610 static void pointer_event(VncState
*vs
, int button_mask
, int x
, int y
)
1612 static uint32_t bmap
[INPUT_BUTTON__MAX
] = {
1613 [INPUT_BUTTON_LEFT
] = 0x01,
1614 [INPUT_BUTTON_MIDDLE
] = 0x02,
1615 [INPUT_BUTTON_RIGHT
] = 0x04,
1616 [INPUT_BUTTON_WHEEL_UP
] = 0x08,
1617 [INPUT_BUTTON_WHEEL_DOWN
] = 0x10,
1619 QemuConsole
*con
= vs
->vd
->dcl
.con
;
1620 int width
= pixman_image_get_width(vs
->vd
->server
);
1621 int height
= pixman_image_get_height(vs
->vd
->server
);
1623 if (vs
->last_bmask
!= button_mask
) {
1624 qemu_input_update_buttons(con
, bmap
, vs
->last_bmask
, button_mask
);
1625 vs
->last_bmask
= button_mask
;
1629 qemu_input_queue_abs(con
, INPUT_AXIS_X
, x
, width
);
1630 qemu_input_queue_abs(con
, INPUT_AXIS_Y
, y
, height
);
1631 } else if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
)) {
1632 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- 0x7FFF);
1633 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- 0x7FFF);
1635 if (vs
->last_x
!= -1) {
1636 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- vs
->last_x
);
1637 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- vs
->last_y
);
1642 qemu_input_event_sync();
1645 static void reset_keys(VncState
*vs
)
1648 for(i
= 0; i
< 256; i
++) {
1649 if (vs
->modifiers_state
[i
]) {
1650 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, i
, false);
1651 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1652 vs
->modifiers_state
[i
] = 0;
1657 static void press_key(VncState
*vs
, int keysym
)
1659 int keycode
= keysym2scancode(vs
->vd
->kbd_layout
, keysym
) & SCANCODE_KEYMASK
;
1660 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, true);
1661 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1662 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1663 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1666 static void vnc_led_state_change(VncState
*vs
)
1668 if (!vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
)) {
1672 vnc_lock_output(vs
);
1673 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1674 vnc_write_u8(vs
, 0);
1675 vnc_write_u16(vs
, 1);
1676 vnc_framebuffer_update(vs
, 0, 0, 1, 1, VNC_ENCODING_LED_STATE
);
1677 vnc_write_u8(vs
, vs
->vd
->ledstate
);
1678 vnc_unlock_output(vs
);
1682 static void kbd_leds(void *opaque
, int ledstate
)
1684 VncDisplay
*vd
= opaque
;
1687 trace_vnc_key_guest_leds((ledstate
& QEMU_CAPS_LOCK_LED
),
1688 (ledstate
& QEMU_NUM_LOCK_LED
),
1689 (ledstate
& QEMU_SCROLL_LOCK_LED
));
1691 if (ledstate
== vd
->ledstate
) {
1695 vd
->ledstate
= ledstate
;
1697 QTAILQ_FOREACH(client
, &vd
->clients
, next
) {
1698 vnc_led_state_change(client
);
1702 static void do_key_event(VncState
*vs
, int down
, int keycode
, int sym
)
1704 /* QEMU console switch */
1706 case 0x2a: /* Left Shift */
1707 case 0x36: /* Right Shift */
1708 case 0x1d: /* Left CTRL */
1709 case 0x9d: /* Right CTRL */
1710 case 0x38: /* Left ALT */
1711 case 0xb8: /* Right ALT */
1713 vs
->modifiers_state
[keycode
] = 1;
1715 vs
->modifiers_state
[keycode
] = 0;
1717 case 0x02 ... 0x0a: /* '1' to '9' keys */
1718 if (vs
->vd
->dcl
.con
== NULL
&&
1719 down
&& vs
->modifiers_state
[0x1d] && vs
->modifiers_state
[0x38]) {
1720 /* Reset the modifiers sent to the current console */
1722 console_select(keycode
- 0x02);
1726 case 0x3a: /* CapsLock */
1727 case 0x45: /* NumLock */
1729 vs
->modifiers_state
[keycode
] ^= 1;
1733 /* Turn off the lock state sync logic if the client support the led
1736 if (down
&& vs
->vd
->lock_key_sync
&&
1737 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1738 keycode_is_keypad(vs
->vd
->kbd_layout
, keycode
)) {
1739 /* If the numlock state needs to change then simulate an additional
1740 keypress before sending this one. This will happen if the user
1741 toggles numlock away from the VNC window.
1743 if (keysym_is_numlock(vs
->vd
->kbd_layout
, sym
& 0xFFFF)) {
1744 if (!vs
->modifiers_state
[0x45]) {
1745 trace_vnc_key_sync_numlock(true);
1746 vs
->modifiers_state
[0x45] = 1;
1747 press_key(vs
, 0xff7f);
1750 if (vs
->modifiers_state
[0x45]) {
1751 trace_vnc_key_sync_numlock(false);
1752 vs
->modifiers_state
[0x45] = 0;
1753 press_key(vs
, 0xff7f);
1758 if (down
&& vs
->vd
->lock_key_sync
&&
1759 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1760 ((sym
>= 'A' && sym
<= 'Z') || (sym
>= 'a' && sym
<= 'z'))) {
1761 /* If the capslock state needs to change then simulate an additional
1762 keypress before sending this one. This will happen if the user
1763 toggles capslock away from the VNC window.
1765 int uppercase
= !!(sym
>= 'A' && sym
<= 'Z');
1766 int shift
= !!(vs
->modifiers_state
[0x2a] | vs
->modifiers_state
[0x36]);
1767 int capslock
= !!(vs
->modifiers_state
[0x3a]);
1769 if (uppercase
== shift
) {
1770 trace_vnc_key_sync_capslock(false);
1771 vs
->modifiers_state
[0x3a] = 0;
1772 press_key(vs
, 0xffe5);
1775 if (uppercase
!= shift
) {
1776 trace_vnc_key_sync_capslock(true);
1777 vs
->modifiers_state
[0x3a] = 1;
1778 press_key(vs
, 0xffe5);
1783 if (qemu_console_is_graphic(NULL
)) {
1784 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, down
);
1785 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1787 bool numlock
= vs
->modifiers_state
[0x45];
1788 bool control
= (vs
->modifiers_state
[0x1d] ||
1789 vs
->modifiers_state
[0x9d]);
1790 /* QEMU console emulation */
1793 case 0x2a: /* Left Shift */
1794 case 0x36: /* Right Shift */
1795 case 0x1d: /* Left CTRL */
1796 case 0x9d: /* Right CTRL */
1797 case 0x38: /* Left ALT */
1798 case 0xb8: /* Right ALT */
1801 kbd_put_keysym(QEMU_KEY_UP
);
1804 kbd_put_keysym(QEMU_KEY_DOWN
);
1807 kbd_put_keysym(QEMU_KEY_LEFT
);
1810 kbd_put_keysym(QEMU_KEY_RIGHT
);
1813 kbd_put_keysym(QEMU_KEY_DELETE
);
1816 kbd_put_keysym(QEMU_KEY_HOME
);
1819 kbd_put_keysym(QEMU_KEY_END
);
1822 kbd_put_keysym(QEMU_KEY_PAGEUP
);
1825 kbd_put_keysym(QEMU_KEY_PAGEDOWN
);
1829 kbd_put_keysym(numlock
? '7' : QEMU_KEY_HOME
);
1832 kbd_put_keysym(numlock
? '8' : QEMU_KEY_UP
);
1835 kbd_put_keysym(numlock
? '9' : QEMU_KEY_PAGEUP
);
1838 kbd_put_keysym(numlock
? '4' : QEMU_KEY_LEFT
);
1841 kbd_put_keysym('5');
1844 kbd_put_keysym(numlock
? '6' : QEMU_KEY_RIGHT
);
1847 kbd_put_keysym(numlock
? '1' : QEMU_KEY_END
);
1850 kbd_put_keysym(numlock
? '2' : QEMU_KEY_DOWN
);
1853 kbd_put_keysym(numlock
? '3' : QEMU_KEY_PAGEDOWN
);
1856 kbd_put_keysym('0');
1859 kbd_put_keysym(numlock
? '.' : QEMU_KEY_DELETE
);
1863 kbd_put_keysym('/');
1866 kbd_put_keysym('*');
1869 kbd_put_keysym('-');
1872 kbd_put_keysym('+');
1875 kbd_put_keysym('\n');
1880 kbd_put_keysym(sym
& 0x1f);
1882 kbd_put_keysym(sym
);
1890 static void vnc_release_modifiers(VncState
*vs
)
1892 static const int keycodes
[] = {
1893 /* shift, control, alt keys, both left & right */
1894 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1898 if (!qemu_console_is_graphic(NULL
)) {
1901 for (i
= 0; i
< ARRAY_SIZE(keycodes
); i
++) {
1902 keycode
= keycodes
[i
];
1903 if (!vs
->modifiers_state
[keycode
]) {
1906 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1907 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1911 static const char *code2name(int keycode
)
1913 return QKeyCode_lookup
[qemu_input_key_number_to_qcode(keycode
)];
1916 static void key_event(VncState
*vs
, int down
, uint32_t sym
)
1921 if (lsym
>= 'A' && lsym
<= 'Z' && qemu_console_is_graphic(NULL
)) {
1922 lsym
= lsym
- 'A' + 'a';
1925 keycode
= keysym2scancode(vs
->vd
->kbd_layout
, lsym
& 0xFFFF) & SCANCODE_KEYMASK
;
1926 trace_vnc_key_event_map(down
, sym
, keycode
, code2name(keycode
));
1927 do_key_event(vs
, down
, keycode
, sym
);
1930 static void ext_key_event(VncState
*vs
, int down
,
1931 uint32_t sym
, uint16_t keycode
)
1933 /* if the user specifies a keyboard layout, always use it */
1934 if (keyboard_layout
) {
1935 key_event(vs
, down
, sym
);
1937 trace_vnc_key_event_ext(down
, sym
, keycode
, code2name(keycode
));
1938 do_key_event(vs
, down
, keycode
, sym
);
1942 static void framebuffer_update_request(VncState
*vs
, int incremental
,
1943 int x
, int y
, int w
, int h
)
1945 vs
->need_update
= 1;
1951 vs
->force_update
= 1;
1952 vnc_set_area_dirty(vs
->dirty
, vs
->vd
, x
, y
, w
, h
);
1955 static void send_ext_key_event_ack(VncState
*vs
)
1957 vnc_lock_output(vs
);
1958 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1959 vnc_write_u8(vs
, 0);
1960 vnc_write_u16(vs
, 1);
1961 vnc_framebuffer_update(vs
, 0, 0,
1962 pixman_image_get_width(vs
->vd
->server
),
1963 pixman_image_get_height(vs
->vd
->server
),
1964 VNC_ENCODING_EXT_KEY_EVENT
);
1965 vnc_unlock_output(vs
);
1969 static void send_ext_audio_ack(VncState
*vs
)
1971 vnc_lock_output(vs
);
1972 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1973 vnc_write_u8(vs
, 0);
1974 vnc_write_u16(vs
, 1);
1975 vnc_framebuffer_update(vs
, 0, 0,
1976 pixman_image_get_width(vs
->vd
->server
),
1977 pixman_image_get_height(vs
->vd
->server
),
1978 VNC_ENCODING_AUDIO
);
1979 vnc_unlock_output(vs
);
1983 static void set_encodings(VncState
*vs
, int32_t *encodings
, size_t n_encodings
)
1986 unsigned int enc
= 0;
1989 vs
->vnc_encoding
= 0;
1990 vs
->tight
.compression
= 9;
1991 vs
->tight
.quality
= -1; /* Lossless by default */
1995 * Start from the end because the encodings are sent in order of preference.
1996 * This way the preferred encoding (first encoding defined in the array)
1997 * will be set at the end of the loop.
1999 for (i
= n_encodings
- 1; i
>= 0; i
--) {
2002 case VNC_ENCODING_RAW
:
2003 vs
->vnc_encoding
= enc
;
2005 case VNC_ENCODING_COPYRECT
:
2006 vs
->features
|= VNC_FEATURE_COPYRECT_MASK
;
2008 case VNC_ENCODING_HEXTILE
:
2009 vs
->features
|= VNC_FEATURE_HEXTILE_MASK
;
2010 vs
->vnc_encoding
= enc
;
2012 case VNC_ENCODING_TIGHT
:
2013 vs
->features
|= VNC_FEATURE_TIGHT_MASK
;
2014 vs
->vnc_encoding
= enc
;
2016 #ifdef CONFIG_VNC_PNG
2017 case VNC_ENCODING_TIGHT_PNG
:
2018 vs
->features
|= VNC_FEATURE_TIGHT_PNG_MASK
;
2019 vs
->vnc_encoding
= enc
;
2022 case VNC_ENCODING_ZLIB
:
2023 vs
->features
|= VNC_FEATURE_ZLIB_MASK
;
2024 vs
->vnc_encoding
= enc
;
2026 case VNC_ENCODING_ZRLE
:
2027 vs
->features
|= VNC_FEATURE_ZRLE_MASK
;
2028 vs
->vnc_encoding
= enc
;
2030 case VNC_ENCODING_ZYWRLE
:
2031 vs
->features
|= VNC_FEATURE_ZYWRLE_MASK
;
2032 vs
->vnc_encoding
= enc
;
2034 case VNC_ENCODING_DESKTOPRESIZE
:
2035 vs
->features
|= VNC_FEATURE_RESIZE_MASK
;
2037 case VNC_ENCODING_POINTER_TYPE_CHANGE
:
2038 vs
->features
|= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK
;
2040 case VNC_ENCODING_RICH_CURSOR
:
2041 vs
->features
|= VNC_FEATURE_RICH_CURSOR_MASK
;
2042 if (vs
->vd
->cursor
) {
2043 vnc_cursor_define(vs
);
2046 case VNC_ENCODING_EXT_KEY_EVENT
:
2047 send_ext_key_event_ack(vs
);
2049 case VNC_ENCODING_AUDIO
:
2050 send_ext_audio_ack(vs
);
2052 case VNC_ENCODING_WMVi
:
2053 vs
->features
|= VNC_FEATURE_WMVI_MASK
;
2055 case VNC_ENCODING_LED_STATE
:
2056 vs
->features
|= VNC_FEATURE_LED_STATE_MASK
;
2058 case VNC_ENCODING_COMPRESSLEVEL0
... VNC_ENCODING_COMPRESSLEVEL0
+ 9:
2059 vs
->tight
.compression
= (enc
& 0x0F);
2061 case VNC_ENCODING_QUALITYLEVEL0
... VNC_ENCODING_QUALITYLEVEL0
+ 9:
2062 if (vs
->vd
->lossy
) {
2063 vs
->tight
.quality
= (enc
& 0x0F);
2067 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i
, enc
, enc
);
2071 vnc_desktop_resize(vs
);
2072 check_pointer_type_change(&vs
->mouse_mode_notifier
, NULL
);
2073 vnc_led_state_change(vs
);
2076 static void set_pixel_conversion(VncState
*vs
)
2078 pixman_format_code_t fmt
= qemu_pixman_get_format(&vs
->client_pf
);
2080 if (fmt
== VNC_SERVER_FB_FORMAT
) {
2081 vs
->write_pixels
= vnc_write_pixels_copy
;
2082 vnc_hextile_set_pixel_conversion(vs
, 0);
2084 vs
->write_pixels
= vnc_write_pixels_generic
;
2085 vnc_hextile_set_pixel_conversion(vs
, 1);
2089 static void send_color_map(VncState
*vs
)
2093 vnc_write_u8(vs
, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES
);
2094 vnc_write_u8(vs
, 0); /* padding */
2095 vnc_write_u16(vs
, 0); /* first color */
2096 vnc_write_u16(vs
, 256); /* # of colors */
2098 for (i
= 0; i
< 256; i
++) {
2099 PixelFormat
*pf
= &vs
->client_pf
;
2101 vnc_write_u16(vs
, (((i
>> pf
->rshift
) & pf
->rmax
) << (16 - pf
->rbits
)));
2102 vnc_write_u16(vs
, (((i
>> pf
->gshift
) & pf
->gmax
) << (16 - pf
->gbits
)));
2103 vnc_write_u16(vs
, (((i
>> pf
->bshift
) & pf
->bmax
) << (16 - pf
->bbits
)));
2107 static void set_pixel_format(VncState
*vs
, int bits_per_pixel
,
2108 int big_endian_flag
, int true_color_flag
,
2109 int red_max
, int green_max
, int blue_max
,
2110 int red_shift
, int green_shift
, int blue_shift
)
2112 if (!true_color_flag
) {
2113 /* Expose a reasonable default 256 color map */
2123 switch (bits_per_pixel
) {
2129 vnc_client_error(vs
);
2133 vs
->client_pf
.rmax
= red_max
? red_max
: 0xFF;
2134 vs
->client_pf
.rbits
= hweight_long(red_max
);
2135 vs
->client_pf
.rshift
= red_shift
;
2136 vs
->client_pf
.rmask
= red_max
<< red_shift
;
2137 vs
->client_pf
.gmax
= green_max
? green_max
: 0xFF;
2138 vs
->client_pf
.gbits
= hweight_long(green_max
);
2139 vs
->client_pf
.gshift
= green_shift
;
2140 vs
->client_pf
.gmask
= green_max
<< green_shift
;
2141 vs
->client_pf
.bmax
= blue_max
? blue_max
: 0xFF;
2142 vs
->client_pf
.bbits
= hweight_long(blue_max
);
2143 vs
->client_pf
.bshift
= blue_shift
;
2144 vs
->client_pf
.bmask
= blue_max
<< blue_shift
;
2145 vs
->client_pf
.bits_per_pixel
= bits_per_pixel
;
2146 vs
->client_pf
.bytes_per_pixel
= bits_per_pixel
/ 8;
2147 vs
->client_pf
.depth
= bits_per_pixel
== 32 ? 24 : bits_per_pixel
;
2148 vs
->client_be
= big_endian_flag
;
2150 if (!true_color_flag
) {
2154 set_pixel_conversion(vs
);
2156 graphic_hw_invalidate(vs
->vd
->dcl
.con
);
2157 graphic_hw_update(vs
->vd
->dcl
.con
);
2160 static void pixel_format_message (VncState
*vs
) {
2161 char pad
[3] = { 0, 0, 0 };
2163 vs
->client_pf
= qemu_default_pixelformat(32);
2165 vnc_write_u8(vs
, vs
->client_pf
.bits_per_pixel
); /* bits-per-pixel */
2166 vnc_write_u8(vs
, vs
->client_pf
.depth
); /* depth */
2168 #ifdef HOST_WORDS_BIGENDIAN
2169 vnc_write_u8(vs
, 1); /* big-endian-flag */
2171 vnc_write_u8(vs
, 0); /* big-endian-flag */
2173 vnc_write_u8(vs
, 1); /* true-color-flag */
2174 vnc_write_u16(vs
, vs
->client_pf
.rmax
); /* red-max */
2175 vnc_write_u16(vs
, vs
->client_pf
.gmax
); /* green-max */
2176 vnc_write_u16(vs
, vs
->client_pf
.bmax
); /* blue-max */
2177 vnc_write_u8(vs
, vs
->client_pf
.rshift
); /* red-shift */
2178 vnc_write_u8(vs
, vs
->client_pf
.gshift
); /* green-shift */
2179 vnc_write_u8(vs
, vs
->client_pf
.bshift
); /* blue-shift */
2180 vnc_write(vs
, pad
, 3); /* padding */
2182 vnc_hextile_set_pixel_conversion(vs
, 0);
2183 vs
->write_pixels
= vnc_write_pixels_copy
;
2186 static void vnc_colordepth(VncState
*vs
)
2188 if (vnc_has_feature(vs
, VNC_FEATURE_WMVI
)) {
2189 /* Sending a WMVi message to notify the client*/
2190 vnc_lock_output(vs
);
2191 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2192 vnc_write_u8(vs
, 0);
2193 vnc_write_u16(vs
, 1); /* number of rects */
2194 vnc_framebuffer_update(vs
, 0, 0,
2195 pixman_image_get_width(vs
->vd
->server
),
2196 pixman_image_get_height(vs
->vd
->server
),
2198 pixel_format_message(vs
);
2199 vnc_unlock_output(vs
);
2202 set_pixel_conversion(vs
);
2206 static int protocol_client_msg(VncState
*vs
, uint8_t *data
, size_t len
)
2210 VncDisplay
*vd
= vs
->vd
;
2213 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2217 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT
:
2221 set_pixel_format(vs
, read_u8(data
, 4),
2222 read_u8(data
, 6), read_u8(data
, 7),
2223 read_u16(data
, 8), read_u16(data
, 10),
2224 read_u16(data
, 12), read_u8(data
, 14),
2225 read_u8(data
, 15), read_u8(data
, 16));
2227 case VNC_MSG_CLIENT_SET_ENCODINGS
:
2232 limit
= read_u16(data
, 2);
2234 return 4 + (limit
* 4);
2236 limit
= read_u16(data
, 2);
2238 for (i
= 0; i
< limit
; i
++) {
2239 int32_t val
= read_s32(data
, 4 + (i
* 4));
2240 memcpy(data
+ 4 + (i
* 4), &val
, sizeof(val
));
2243 set_encodings(vs
, (int32_t *)(data
+ 4), limit
);
2245 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST
:
2249 framebuffer_update_request(vs
,
2250 read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4),
2251 read_u16(data
, 6), read_u16(data
, 8));
2253 case VNC_MSG_CLIENT_KEY_EVENT
:
2257 key_event(vs
, read_u8(data
, 1), read_u32(data
, 4));
2259 case VNC_MSG_CLIENT_POINTER_EVENT
:
2263 pointer_event(vs
, read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4));
2265 case VNC_MSG_CLIENT_CUT_TEXT
:
2270 uint32_t dlen
= read_u32(data
, 4);
2271 if (dlen
> (1 << 20)) {
2272 error_report("vnc: client_cut_text msg payload has %u bytes"
2273 " which exceeds our limit of 1MB.", dlen
);
2274 vnc_client_error(vs
);
2282 client_cut_text(vs
, read_u32(data
, 4), data
+ 8);
2284 case VNC_MSG_CLIENT_QEMU
:
2288 switch (read_u8(data
, 1)) {
2289 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT
:
2293 ext_key_event(vs
, read_u16(data
, 2),
2294 read_u32(data
, 4), read_u32(data
, 8));
2296 case VNC_MSG_CLIENT_QEMU_AUDIO
:
2300 switch (read_u16 (data
, 2)) {
2301 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE
:
2304 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE
:
2307 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT
:
2310 switch (read_u8(data
, 4)) {
2311 case 0: vs
->as
.fmt
= AUD_FMT_U8
; break;
2312 case 1: vs
->as
.fmt
= AUD_FMT_S8
; break;
2313 case 2: vs
->as
.fmt
= AUD_FMT_U16
; break;
2314 case 3: vs
->as
.fmt
= AUD_FMT_S16
; break;
2315 case 4: vs
->as
.fmt
= AUD_FMT_U32
; break;
2316 case 5: vs
->as
.fmt
= AUD_FMT_S32
; break;
2318 VNC_DEBUG("Invalid audio format %d\n", read_u8(data
, 4));
2319 vnc_client_error(vs
);
2322 vs
->as
.nchannels
= read_u8(data
, 5);
2323 if (vs
->as
.nchannels
!= 1 && vs
->as
.nchannels
!= 2) {
2324 VNC_DEBUG("Invalid audio channel coount %d\n",
2326 vnc_client_error(vs
);
2329 vs
->as
.freq
= read_u32(data
, 6);
2332 VNC_DEBUG("Invalid audio message %d\n", read_u8(data
, 4));
2333 vnc_client_error(vs
);
2339 VNC_DEBUG("Msg: %d\n", read_u16(data
, 0));
2340 vnc_client_error(vs
);
2345 VNC_DEBUG("Msg: %d\n", data
[0]);
2346 vnc_client_error(vs
);
2350 vnc_read_when(vs
, protocol_client_msg
, 1);
2354 static int protocol_client_init(VncState
*vs
, uint8_t *data
, size_t len
)
2360 mode
= data
[0] ? VNC_SHARE_MODE_SHARED
: VNC_SHARE_MODE_EXCLUSIVE
;
2361 switch (vs
->vd
->share_policy
) {
2362 case VNC_SHARE_POLICY_IGNORE
:
2364 * Ignore the shared flag. Nothing to do here.
2366 * Doesn't conform to the rfb spec but is traditional qemu
2367 * behavior, thus left here as option for compatibility
2371 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
:
2373 * Policy: Allow clients ask for exclusive access.
2375 * Implementation: When a client asks for exclusive access,
2376 * disconnect all others. Shared connects are allowed as long
2377 * as no exclusive connection exists.
2379 * This is how the rfb spec suggests to handle the shared flag.
2381 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2383 QTAILQ_FOREACH(client
, &vs
->vd
->clients
, next
) {
2387 if (client
->share_mode
!= VNC_SHARE_MODE_EXCLUSIVE
&&
2388 client
->share_mode
!= VNC_SHARE_MODE_SHARED
) {
2391 vnc_disconnect_start(client
);
2394 if (mode
== VNC_SHARE_MODE_SHARED
) {
2395 if (vs
->vd
->num_exclusive
> 0) {
2396 vnc_disconnect_start(vs
);
2401 case VNC_SHARE_POLICY_FORCE_SHARED
:
2403 * Policy: Shared connects only.
2404 * Implementation: Disallow clients asking for exclusive access.
2406 * Useful for shared desktop sessions where you don't want
2407 * someone forgetting to say -shared when running the vnc
2408 * client disconnect everybody else.
2410 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2411 vnc_disconnect_start(vs
);
2416 vnc_set_share_mode(vs
, mode
);
2418 if (vs
->vd
->num_shared
> vs
->vd
->connections_limit
) {
2419 vnc_disconnect_start(vs
);
2423 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
2424 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
2425 vnc_write_u16(vs
, vs
->client_width
);
2426 vnc_write_u16(vs
, vs
->client_height
);
2428 pixel_format_message(vs
);
2431 size
= snprintf(buf
, sizeof(buf
), "QEMU (%s)", qemu_name
);
2432 if (size
> sizeof(buf
)) {
2436 size
= snprintf(buf
, sizeof(buf
), "QEMU");
2439 vnc_write_u32(vs
, size
);
2440 vnc_write(vs
, buf
, size
);
2443 vnc_client_cache_auth(vs
);
2444 vnc_qmp_event(vs
, QAPI_EVENT_VNC_INITIALIZED
);
2446 vnc_read_when(vs
, protocol_client_msg
, 1);
2451 void start_client_init(VncState
*vs
)
2453 vnc_read_when(vs
, protocol_client_init
, 1);
2456 static void make_challenge(VncState
*vs
)
2460 srand(time(NULL
)+getpid()+getpid()*987654+rand());
2462 for (i
= 0 ; i
< sizeof(vs
->challenge
) ; i
++)
2463 vs
->challenge
[i
] = (int) (256.0*rand()/(RAND_MAX
+1.0));
2466 static int protocol_client_auth_vnc(VncState
*vs
, uint8_t *data
, size_t len
)
2468 unsigned char response
[VNC_AUTH_CHALLENGE_SIZE
];
2470 unsigned char key
[8];
2471 time_t now
= time(NULL
);
2472 QCryptoCipher
*cipher
= NULL
;
2475 if (!vs
->vd
->password
) {
2476 VNC_DEBUG("No password configured on server");
2479 if (vs
->vd
->expires
< now
) {
2480 VNC_DEBUG("Password is expired");
2484 memcpy(response
, vs
->challenge
, VNC_AUTH_CHALLENGE_SIZE
);
2486 /* Calculate the expected challenge response */
2487 pwlen
= strlen(vs
->vd
->password
);
2488 for (i
=0; i
<sizeof(key
); i
++)
2489 key
[i
] = i
<pwlen
? vs
->vd
->password
[i
] : 0;
2491 cipher
= qcrypto_cipher_new(
2492 QCRYPTO_CIPHER_ALG_DES_RFB
,
2493 QCRYPTO_CIPHER_MODE_ECB
,
2494 key
, G_N_ELEMENTS(key
),
2497 VNC_DEBUG("Cannot initialize cipher %s",
2498 error_get_pretty(err
));
2503 if (qcrypto_cipher_encrypt(cipher
,
2506 VNC_AUTH_CHALLENGE_SIZE
,
2508 VNC_DEBUG("Cannot encrypt challenge %s",
2509 error_get_pretty(err
));
2514 /* Compare expected vs actual challenge response */
2515 if (memcmp(response
, data
, VNC_AUTH_CHALLENGE_SIZE
) != 0) {
2516 VNC_DEBUG("Client challenge response did not match\n");
2519 VNC_DEBUG("Accepting VNC challenge response\n");
2520 vnc_write_u32(vs
, 0); /* Accept auth */
2523 start_client_init(vs
);
2526 qcrypto_cipher_free(cipher
);
2530 vnc_write_u32(vs
, 1); /* Reject auth */
2531 if (vs
->minor
>= 8) {
2532 static const char err
[] = "Authentication failed";
2533 vnc_write_u32(vs
, sizeof(err
));
2534 vnc_write(vs
, err
, sizeof(err
));
2537 vnc_client_error(vs
);
2538 qcrypto_cipher_free(cipher
);
2542 void start_auth_vnc(VncState
*vs
)
2545 /* Send client a 'random' challenge */
2546 vnc_write(vs
, vs
->challenge
, sizeof(vs
->challenge
));
2549 vnc_read_when(vs
, protocol_client_auth_vnc
, sizeof(vs
->challenge
));
2553 static int protocol_client_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2555 /* We only advertise 1 auth scheme at a time, so client
2556 * must pick the one we sent. Verify this */
2557 if (data
[0] != vs
->auth
) { /* Reject auth */
2558 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data
[0]);
2559 vnc_write_u32(vs
, 1);
2560 if (vs
->minor
>= 8) {
2561 static const char err
[] = "Authentication failed";
2562 vnc_write_u32(vs
, sizeof(err
));
2563 vnc_write(vs
, err
, sizeof(err
));
2565 vnc_client_error(vs
);
2566 } else { /* Accept requested auth */
2567 VNC_DEBUG("Client requested auth %d\n", (int)data
[0]);
2570 VNC_DEBUG("Accept auth none\n");
2571 if (vs
->minor
>= 8) {
2572 vnc_write_u32(vs
, 0); /* Accept auth completion */
2575 start_client_init(vs
);
2579 VNC_DEBUG("Start VNC auth\n");
2583 case VNC_AUTH_VENCRYPT
:
2584 VNC_DEBUG("Accept VeNCrypt auth\n");
2585 start_auth_vencrypt(vs
);
2588 #ifdef CONFIG_VNC_SASL
2590 VNC_DEBUG("Accept SASL auth\n");
2591 start_auth_sasl(vs
);
2593 #endif /* CONFIG_VNC_SASL */
2595 default: /* Should not be possible, but just in case */
2596 VNC_DEBUG("Reject auth %d server code bug\n", vs
->auth
);
2597 vnc_write_u8(vs
, 1);
2598 if (vs
->minor
>= 8) {
2599 static const char err
[] = "Authentication failed";
2600 vnc_write_u32(vs
, sizeof(err
));
2601 vnc_write(vs
, err
, sizeof(err
));
2603 vnc_client_error(vs
);
2609 static int protocol_version(VncState
*vs
, uint8_t *version
, size_t len
)
2613 memcpy(local
, version
, 12);
2616 if (sscanf(local
, "RFB %03d.%03d\n", &vs
->major
, &vs
->minor
) != 2) {
2617 VNC_DEBUG("Malformed protocol version %s\n", local
);
2618 vnc_client_error(vs
);
2621 VNC_DEBUG("Client request protocol version %d.%d\n", vs
->major
, vs
->minor
);
2622 if (vs
->major
!= 3 ||
2628 VNC_DEBUG("Unsupported client version\n");
2629 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2631 vnc_client_error(vs
);
2634 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2635 * as equivalent to v3.3 by servers
2637 if (vs
->minor
== 4 || vs
->minor
== 5)
2640 if (vs
->minor
== 3) {
2641 if (vs
->auth
== VNC_AUTH_NONE
) {
2642 VNC_DEBUG("Tell client auth none\n");
2643 vnc_write_u32(vs
, vs
->auth
);
2645 start_client_init(vs
);
2646 } else if (vs
->auth
== VNC_AUTH_VNC
) {
2647 VNC_DEBUG("Tell client VNC auth\n");
2648 vnc_write_u32(vs
, vs
->auth
);
2652 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs
->auth
);
2653 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2655 vnc_client_error(vs
);
2658 VNC_DEBUG("Telling client we support auth %d\n", vs
->auth
);
2659 vnc_write_u8(vs
, 1); /* num auth */
2660 vnc_write_u8(vs
, vs
->auth
);
2661 vnc_read_when(vs
, protocol_client_auth
, 1);
2668 static VncRectStat
*vnc_stat_rect(VncDisplay
*vd
, int x
, int y
)
2670 struct VncSurface
*vs
= &vd
->guest
;
2672 return &vs
->stats
[y
/ VNC_STAT_RECT
][x
/ VNC_STAT_RECT
];
2675 void vnc_sent_lossy_rect(VncState
*vs
, int x
, int y
, int w
, int h
)
2679 w
= (x
+ w
) / VNC_STAT_RECT
;
2680 h
= (y
+ h
) / VNC_STAT_RECT
;
2684 for (j
= y
; j
<= h
; j
++) {
2685 for (i
= x
; i
<= w
; i
++) {
2686 vs
->lossy_rect
[j
][i
] = 1;
2691 static int vnc_refresh_lossy_rect(VncDisplay
*vd
, int x
, int y
)
2694 int sty
= y
/ VNC_STAT_RECT
;
2695 int stx
= x
/ VNC_STAT_RECT
;
2698 y
= y
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2699 x
= x
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2701 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2704 /* kernel send buffers are full -> refresh later */
2705 if (vs
->output
.offset
) {
2709 if (!vs
->lossy_rect
[sty
][stx
]) {
2713 vs
->lossy_rect
[sty
][stx
] = 0;
2714 for (j
= 0; j
< VNC_STAT_RECT
; ++j
) {
2715 bitmap_set(vs
->dirty
[y
+ j
],
2716 x
/ VNC_DIRTY_PIXELS_PER_BIT
,
2717 VNC_STAT_RECT
/ VNC_DIRTY_PIXELS_PER_BIT
);
2725 static int vnc_update_stats(VncDisplay
*vd
, struct timeval
* tv
)
2727 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2728 pixman_image_get_width(vd
->server
));
2729 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2730 pixman_image_get_height(vd
->server
));
2735 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2736 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2737 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2739 rect
->updated
= false;
2743 qemu_timersub(tv
, &VNC_REFRESH_STATS
, &res
);
2745 if (timercmp(&vd
->guest
.last_freq_check
, &res
, >)) {
2748 vd
->guest
.last_freq_check
= *tv
;
2750 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2751 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2752 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2753 int count
= ARRAY_SIZE(rect
->times
);
2754 struct timeval min
, max
;
2756 if (!timerisset(&rect
->times
[count
- 1])) {
2760 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2761 qemu_timersub(tv
, &max
, &res
);
2763 if (timercmp(&res
, &VNC_REFRESH_LOSSY
, >)) {
2765 has_dirty
+= vnc_refresh_lossy_rect(vd
, x
, y
);
2766 memset(rect
->times
, 0, sizeof (rect
->times
));
2770 min
= rect
->times
[rect
->idx
];
2771 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2772 qemu_timersub(&max
, &min
, &res
);
2774 rect
->freq
= res
.tv_sec
+ res
.tv_usec
/ 1000000.;
2775 rect
->freq
/= count
;
2776 rect
->freq
= 1. / rect
->freq
;
2782 double vnc_update_freq(VncState
*vs
, int x
, int y
, int w
, int h
)
2788 x
= (x
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2789 y
= (y
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2791 for (j
= y
; j
<= y
+ h
; j
+= VNC_STAT_RECT
) {
2792 for (i
= x
; i
<= x
+ w
; i
+= VNC_STAT_RECT
) {
2793 total
+= vnc_stat_rect(vs
->vd
, i
, j
)->freq
;
2805 static void vnc_rect_updated(VncDisplay
*vd
, int x
, int y
, struct timeval
* tv
)
2809 rect
= vnc_stat_rect(vd
, x
, y
);
2810 if (rect
->updated
) {
2813 rect
->times
[rect
->idx
] = *tv
;
2814 rect
->idx
= (rect
->idx
+ 1) % ARRAY_SIZE(rect
->times
);
2815 rect
->updated
= true;
2818 static int vnc_refresh_server_surface(VncDisplay
*vd
)
2820 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2821 pixman_image_get_width(vd
->server
));
2822 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2823 pixman_image_get_height(vd
->server
));
2824 int cmp_bytes
, server_stride
, line_bytes
, guest_ll
, guest_stride
, y
= 0;
2825 uint8_t *guest_row0
= NULL
, *server_row0
;
2828 pixman_image_t
*tmpbuf
= NULL
;
2830 struct timeval tv
= { 0, 0 };
2832 if (!vd
->non_adaptive
) {
2833 gettimeofday(&tv
, NULL
);
2834 has_dirty
= vnc_update_stats(vd
, &tv
);
2838 * Walk through the guest dirty map.
2839 * Check and copy modified bits from guest to server surface.
2840 * Update server dirty map.
2842 server_row0
= (uint8_t *)pixman_image_get_data(vd
->server
);
2843 server_stride
= guest_stride
= guest_ll
=
2844 pixman_image_get_stride(vd
->server
);
2845 cmp_bytes
= MIN(VNC_DIRTY_PIXELS_PER_BIT
* VNC_SERVER_FB_BYTES
,
2847 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2848 int width
= pixman_image_get_width(vd
->server
);
2849 tmpbuf
= qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT
, width
);
2852 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd
->guest
.fb
));
2853 guest_row0
= (uint8_t *)pixman_image_get_data(vd
->guest
.fb
);
2854 guest_stride
= pixman_image_get_stride(vd
->guest
.fb
);
2855 guest_ll
= pixman_image_get_width(vd
->guest
.fb
) * ((guest_bpp
+ 7) / 8);
2857 line_bytes
= MIN(server_stride
, guest_ll
);
2861 uint8_t *guest_ptr
, *server_ptr
;
2862 unsigned long offset
= find_next_bit((unsigned long *) &vd
->guest
.dirty
,
2863 height
* VNC_DIRTY_BPL(&vd
->guest
),
2864 y
* VNC_DIRTY_BPL(&vd
->guest
));
2865 if (offset
== height
* VNC_DIRTY_BPL(&vd
->guest
)) {
2866 /* no more dirty bits */
2869 y
= offset
/ VNC_DIRTY_BPL(&vd
->guest
);
2870 x
= offset
% VNC_DIRTY_BPL(&vd
->guest
);
2872 server_ptr
= server_row0
+ y
* server_stride
+ x
* cmp_bytes
;
2874 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2875 qemu_pixman_linebuf_fill(tmpbuf
, vd
->guest
.fb
, width
, 0, y
);
2876 guest_ptr
= (uint8_t *)pixman_image_get_data(tmpbuf
);
2878 guest_ptr
= guest_row0
+ y
* guest_stride
;
2880 guest_ptr
+= x
* cmp_bytes
;
2882 for (; x
< DIV_ROUND_UP(width
, VNC_DIRTY_PIXELS_PER_BIT
);
2883 x
++, guest_ptr
+= cmp_bytes
, server_ptr
+= cmp_bytes
) {
2884 int _cmp_bytes
= cmp_bytes
;
2885 if (!test_and_clear_bit(x
, vd
->guest
.dirty
[y
])) {
2888 if ((x
+ 1) * cmp_bytes
> line_bytes
) {
2889 _cmp_bytes
= line_bytes
- x
* cmp_bytes
;
2891 assert(_cmp_bytes
>= 0);
2892 if (memcmp(server_ptr
, guest_ptr
, _cmp_bytes
) == 0) {
2895 memcpy(server_ptr
, guest_ptr
, _cmp_bytes
);
2896 if (!vd
->non_adaptive
) {
2897 vnc_rect_updated(vd
, x
* VNC_DIRTY_PIXELS_PER_BIT
,
2900 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2901 set_bit(x
, vs
->dirty
[y
]);
2908 qemu_pixman_image_unref(tmpbuf
);
2912 static void vnc_refresh(DisplayChangeListener
*dcl
)
2914 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
2916 int has_dirty
, rects
= 0;
2918 if (QTAILQ_EMPTY(&vd
->clients
)) {
2919 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_MAX
);
2923 graphic_hw_update(vd
->dcl
.con
);
2925 if (vnc_trylock_display(vd
)) {
2926 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2930 has_dirty
= vnc_refresh_server_surface(vd
);
2931 vnc_unlock_display(vd
);
2933 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
2934 rects
+= vnc_update_client(vs
, has_dirty
, false);
2935 /* vs might be free()ed here */
2938 if (has_dirty
&& rects
) {
2939 vd
->dcl
.update_interval
/= 2;
2940 if (vd
->dcl
.update_interval
< VNC_REFRESH_INTERVAL_BASE
) {
2941 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_BASE
;
2944 vd
->dcl
.update_interval
+= VNC_REFRESH_INTERVAL_INC
;
2945 if (vd
->dcl
.update_interval
> VNC_REFRESH_INTERVAL_MAX
) {
2946 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_MAX
;
2951 static void vnc_connect(VncDisplay
*vd
, QIOChannelSocket
*sioc
,
2952 bool skipauth
, bool websocket
)
2954 VncState
*vs
= g_new0(VncState
, 1);
2955 bool first_client
= QTAILQ_EMPTY(&vd
->clients
);
2959 object_ref(OBJECT(vs
->sioc
));
2960 vs
->ioc
= QIO_CHANNEL(sioc
);
2961 object_ref(OBJECT(vs
->ioc
));
2964 buffer_init(&vs
->input
, "vnc-input/%p", sioc
);
2965 buffer_init(&vs
->output
, "vnc-output/%p", sioc
);
2966 buffer_init(&vs
->jobs_buffer
, "vnc-jobs_buffer/%p", sioc
);
2968 buffer_init(&vs
->tight
.tight
, "vnc-tight/%p", sioc
);
2969 buffer_init(&vs
->tight
.zlib
, "vnc-tight-zlib/%p", sioc
);
2970 buffer_init(&vs
->tight
.gradient
, "vnc-tight-gradient/%p", sioc
);
2971 #ifdef CONFIG_VNC_JPEG
2972 buffer_init(&vs
->tight
.jpeg
, "vnc-tight-jpeg/%p", sioc
);
2974 #ifdef CONFIG_VNC_PNG
2975 buffer_init(&vs
->tight
.png
, "vnc-tight-png/%p", sioc
);
2977 buffer_init(&vs
->zlib
.zlib
, "vnc-zlib/%p", sioc
);
2978 buffer_init(&vs
->zrle
.zrle
, "vnc-zrle/%p", sioc
);
2979 buffer_init(&vs
->zrle
.fb
, "vnc-zrle-fb/%p", sioc
);
2980 buffer_init(&vs
->zrle
.zlib
, "vnc-zrle-zlib/%p", sioc
);
2983 vs
->auth
= VNC_AUTH_NONE
;
2984 vs
->subauth
= VNC_AUTH_INVALID
;
2987 vs
->auth
= vd
->ws_auth
;
2988 vs
->subauth
= VNC_AUTH_INVALID
;
2990 vs
->auth
= vd
->auth
;
2991 vs
->subauth
= vd
->subauth
;
2994 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
2995 sioc
, websocket
, vs
->auth
, vs
->subauth
);
2997 vs
->lossy_rect
= g_malloc0(VNC_STAT_ROWS
* sizeof (*vs
->lossy_rect
));
2998 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
2999 vs
->lossy_rect
[i
] = g_new0(uint8_t, VNC_STAT_COLS
);
3002 VNC_DEBUG("New client on socket %p\n", vs
->sioc
);
3003 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
3004 qio_channel_set_blocking(vs
->ioc
, false, NULL
);
3008 vs
->ioc_tag
= qio_channel_add_watch(
3009 vs
->ioc
, G_IO_IN
, vncws_tls_handshake_io
, vs
, NULL
);
3011 vs
->ioc_tag
= qio_channel_add_watch(
3012 vs
->ioc
, G_IO_IN
, vncws_handshake_io
, vs
, NULL
);
3015 vs
->ioc_tag
= qio_channel_add_watch(
3016 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
3019 vnc_client_cache_addr(vs
);
3020 vnc_qmp_event(vs
, QAPI_EVENT_VNC_CONNECTED
);
3021 vnc_set_share_mode(vs
, VNC_SHARE_MODE_CONNECTING
);
3026 vs
->as
.freq
= 44100;
3027 vs
->as
.nchannels
= 2;
3028 vs
->as
.fmt
= AUD_FMT_S16
;
3029 vs
->as
.endianness
= 0;
3031 qemu_mutex_init(&vs
->output_mutex
);
3032 vs
->bh
= qemu_bh_new(vnc_jobs_bh
, vs
);
3034 QTAILQ_INSERT_TAIL(&vd
->clients
, vs
, next
);
3036 vnc_update_server_surface(vd
);
3039 graphic_hw_update(vd
->dcl
.con
);
3041 if (!vs
->websocket
) {
3042 vnc_start_protocol(vs
);
3045 if (vd
->num_connecting
> vd
->connections_limit
) {
3046 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
3047 if (vs
->share_mode
== VNC_SHARE_MODE_CONNECTING
) {
3048 vnc_disconnect_start(vs
);
3055 void vnc_start_protocol(VncState
*vs
)
3057 vnc_write(vs
, "RFB 003.008\n", 12);
3059 vnc_read_when(vs
, protocol_version
, 12);
3061 vs
->mouse_mode_notifier
.notify
= check_pointer_type_change
;
3062 qemu_add_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
3065 static gboolean
vnc_listen_io(QIOChannel
*ioc
,
3066 GIOCondition condition
,
3069 VncDisplay
*vd
= opaque
;
3070 QIOChannelSocket
*sioc
= NULL
;
3073 sioc
= qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc
), &err
);
3075 qio_channel_set_name(QIO_CHANNEL(sioc
),
3076 ioc
!= QIO_CHANNEL(vd
->lsock
) ?
3077 "vnc-ws-server" : "vnc-server");
3078 qio_channel_set_delay(QIO_CHANNEL(sioc
), false);
3079 vnc_connect(vd
, sioc
, false,
3080 ioc
!= QIO_CHANNEL(vd
->lsock
));
3081 object_unref(OBJECT(sioc
));
3083 /* client probably closed connection before we got there */
3090 static const DisplayChangeListenerOps dcl_ops
= {
3092 .dpy_refresh
= vnc_refresh
,
3093 .dpy_gfx_copy
= vnc_dpy_copy
,
3094 .dpy_gfx_update
= vnc_dpy_update
,
3095 .dpy_gfx_switch
= vnc_dpy_switch
,
3096 .dpy_gfx_check_format
= qemu_pixman_check_format
,
3097 .dpy_mouse_set
= vnc_mouse_set
,
3098 .dpy_cursor_define
= vnc_dpy_cursor_define
,
3101 void vnc_display_init(const char *id
)
3105 if (vnc_display_find(id
) != NULL
) {
3108 vd
= g_malloc0(sizeof(*vd
));
3110 vd
->id
= strdup(id
);
3111 QTAILQ_INSERT_TAIL(&vnc_displays
, vd
, next
);
3113 QTAILQ_INIT(&vd
->clients
);
3114 vd
->expires
= TIME_MAX
;
3116 if (keyboard_layout
) {
3117 trace_vnc_key_map_init(keyboard_layout
);
3118 vd
->kbd_layout
= init_keyboard_layout(name2keysym
, keyboard_layout
);
3120 vd
->kbd_layout
= init_keyboard_layout(name2keysym
, "en-us");
3123 if (!vd
->kbd_layout
) {
3127 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3128 vd
->connections_limit
= 32;
3130 qemu_mutex_init(&vd
->mutex
);
3131 vnc_start_worker_thread();
3133 vd
->dcl
.ops
= &dcl_ops
;
3134 register_displaychangelistener(&vd
->dcl
);
3138 static void vnc_display_close(VncDisplay
*vd
)
3143 vd
->is_unix
= false;
3144 if (vd
->lsock
!= NULL
) {
3145 if (vd
->lsock_tag
) {
3146 g_source_remove(vd
->lsock_tag
);
3148 object_unref(OBJECT(vd
->lsock
));
3151 if (vd
->lwebsock
!= NULL
) {
3152 if (vd
->lwebsock_tag
) {
3153 g_source_remove(vd
->lwebsock_tag
);
3155 object_unref(OBJECT(vd
->lwebsock
));
3156 vd
->lwebsock
= NULL
;
3158 vd
->auth
= VNC_AUTH_INVALID
;
3159 vd
->subauth
= VNC_AUTH_INVALID
;
3161 object_unparent(OBJECT(vd
->tlscreds
));
3162 vd
->tlscreds
= NULL
;
3164 g_free(vd
->tlsaclname
);
3165 vd
->tlsaclname
= NULL
;
3166 if (vd
->lock_key_sync
) {
3167 qemu_remove_led_event_handler(vd
->led
);
3171 int vnc_display_password(const char *id
, const char *password
)
3173 VncDisplay
*vd
= vnc_display_find(id
);
3178 if (vd
->auth
== VNC_AUTH_NONE
) {
3179 error_printf_unless_qmp("If you want use passwords please enable "
3180 "password auth using '-vnc ${dpy},password'.\n");
3184 g_free(vd
->password
);
3185 vd
->password
= g_strdup(password
);
3190 int vnc_display_pw_expire(const char *id
, time_t expires
)
3192 VncDisplay
*vd
= vnc_display_find(id
);
3198 vd
->expires
= expires
;
3202 static void vnc_display_print_local_addr(VncDisplay
*vd
)
3204 SocketAddress
*addr
;
3207 addr
= qio_channel_socket_get_local_address(vd
->lsock
, &err
);
3212 if (addr
->type
!= SOCKET_ADDRESS_KIND_INET
) {
3213 qapi_free_SocketAddress(addr
);
3216 error_printf_unless_qmp("VNC server running on %s:%s\n",
3217 addr
->u
.inet
.data
->host
,
3218 addr
->u
.inet
.data
->port
);
3219 qapi_free_SocketAddress(addr
);
3222 static QemuOptsList qemu_vnc_opts
= {
3224 .head
= QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts
.head
),
3225 .implied_opt_name
= "vnc",
3229 .type
= QEMU_OPT_STRING
,
3231 .name
= "websocket",
3232 .type
= QEMU_OPT_STRING
,
3234 .name
= "tls-creds",
3235 .type
= QEMU_OPT_STRING
,
3237 /* Deprecated in favour of tls-creds */
3239 .type
= QEMU_OPT_STRING
,
3242 .type
= QEMU_OPT_STRING
,
3245 .type
= QEMU_OPT_STRING
,
3248 .type
= QEMU_OPT_NUMBER
,
3250 .name
= "connections",
3251 .type
= QEMU_OPT_NUMBER
,
3254 .type
= QEMU_OPT_NUMBER
,
3257 .type
= QEMU_OPT_BOOL
,
3260 .type
= QEMU_OPT_BOOL
,
3263 .type
= QEMU_OPT_BOOL
,
3266 .type
= QEMU_OPT_BOOL
,
3268 .name
= "lock-key-sync",
3269 .type
= QEMU_OPT_BOOL
,
3271 .name
= "key-delay-ms",
3272 .type
= QEMU_OPT_NUMBER
,
3275 .type
= QEMU_OPT_BOOL
,
3277 /* Deprecated in favour of tls-creds */
3279 .type
= QEMU_OPT_BOOL
,
3281 /* Deprecated in favour of tls-creds */
3282 .name
= "x509verify",
3283 .type
= QEMU_OPT_STRING
,
3286 .type
= QEMU_OPT_BOOL
,
3289 .type
= QEMU_OPT_BOOL
,
3291 .name
= "non-adaptive",
3292 .type
= QEMU_OPT_BOOL
,
3294 { /* end of list */ }
3300 vnc_display_setup_auth(int *auth
,
3302 QCryptoTLSCreds
*tlscreds
,
3309 * We have a choice of 3 authentication options
3315 * The channel can be run in 2 modes
3320 * And TLS can use 2 types of credentials
3325 * We thus have 9 possible logical combinations
3330 * 4. tls + anon + none
3331 * 5. tls + anon + vnc
3332 * 6. tls + anon + sasl
3333 * 7. tls + x509 + none
3334 * 8. tls + x509 + vnc
3335 * 9. tls + x509 + sasl
3337 * These need to be mapped into the VNC auth schemes
3338 * in an appropriate manner. In regular VNC, all the
3339 * TLS options get mapped into VNC_AUTH_VENCRYPT
3342 * In websockets, the https:// protocol already provides
3343 * TLS support, so there is no need to make use of the
3344 * VeNCrypt extension. Furthermore, websockets browser
3345 * clients could not use VeNCrypt even if they wanted to,
3346 * as they cannot control when the TLS handshake takes
3347 * place. Thus there is no option but to rely on https://,
3348 * meaning combinations 4->6 and 7->9 will be mapped to
3349 * VNC auth schemes in the same way as combos 1->3.
3351 * Regardless of fact that we have a different mapping to
3352 * VNC auth mechs for plain VNC vs websockets VNC, the end
3353 * result has the same security characteristics.
3355 if (websocket
|| !tlscreds
) {
3357 VNC_DEBUG("Initializing VNC server with password auth\n");
3358 *auth
= VNC_AUTH_VNC
;
3360 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3361 *auth
= VNC_AUTH_SASL
;
3363 VNC_DEBUG("Initializing VNC server with no auth\n");
3364 *auth
= VNC_AUTH_NONE
;
3366 *subauth
= VNC_AUTH_INVALID
;
3368 bool is_x509
= object_dynamic_cast(OBJECT(tlscreds
),
3369 TYPE_QCRYPTO_TLS_CREDS_X509
) != NULL
;
3370 bool is_anon
= object_dynamic_cast(OBJECT(tlscreds
),
3371 TYPE_QCRYPTO_TLS_CREDS_ANON
) != NULL
;
3373 if (!is_x509
&& !is_anon
) {
3375 "Unsupported TLS cred type %s",
3376 object_get_typename(OBJECT(tlscreds
)));
3379 *auth
= VNC_AUTH_VENCRYPT
;
3382 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3383 *subauth
= VNC_AUTH_VENCRYPT_X509VNC
;
3385 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3386 *subauth
= VNC_AUTH_VENCRYPT_TLSVNC
;
3391 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3392 *subauth
= VNC_AUTH_VENCRYPT_X509SASL
;
3394 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3395 *subauth
= VNC_AUTH_VENCRYPT_TLSSASL
;
3399 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3400 *subauth
= VNC_AUTH_VENCRYPT_X509NONE
;
3402 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3403 *subauth
= VNC_AUTH_VENCRYPT_TLSNONE
;
3412 * Handle back compat with old CLI syntax by creating some
3413 * suitable QCryptoTLSCreds objects
3415 static QCryptoTLSCreds
*
3416 vnc_display_create_creds(bool x509
,
3422 gchar
*credsid
= g_strdup_printf("tlsvnc%s", id
);
3423 Object
*parent
= object_get_objects_root();
3428 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509
,
3432 "endpoint", "server",
3434 "verify-peer", x509verify
? "yes" : "no",
3437 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON
,
3441 "endpoint", "server",
3448 error_propagate(errp
, err
);
3452 return QCRYPTO_TLS_CREDS(creds
);
3456 void vnc_display_open(const char *id
, Error
**errp
)
3458 VncDisplay
*vd
= vnc_display_find(id
);
3459 QemuOpts
*opts
= qemu_opts_find(&qemu_vnc_opts
, id
);
3460 SocketAddress
*saddr
= NULL
, *wsaddr
= NULL
;
3461 const char *share
, *device_id
;
3463 bool password
= false;
3464 bool reverse
= false;
3468 int show_vnc_port
= 0;
3470 #ifdef CONFIG_VNC_SASL
3474 int lock_key_sync
= 1;
3476 bool ws_enabled
= false;
3479 error_setg(errp
, "VNC display not active");
3482 vnc_display_close(vd
);
3487 vnc
= qemu_opt_get(opts
, "vnc");
3488 if (!vnc
|| strcmp(vnc
, "none") == 0) {
3492 h
= strrchr(vnc
, ':');
3494 size_t hlen
= h
- vnc
;
3496 const char *websocket
= qemu_opt_get(opts
, "websocket");
3497 int to
= qemu_opt_get_number(opts
, "to", 0);
3498 bool has_ipv4
= qemu_opt_get(opts
, "ipv4");
3499 bool has_ipv6
= qemu_opt_get(opts
, "ipv6");
3500 bool ipv4
= qemu_opt_get_bool(opts
, "ipv4", false);
3501 bool ipv6
= qemu_opt_get_bool(opts
, "ipv6", false);
3503 saddr
= g_new0(SocketAddress
, 1);
3505 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1
)) {
3507 "SHA1 hash support is required for websockets");
3511 wsaddr
= g_new0(SocketAddress
, 1);
3515 if (strncmp(vnc
, "unix:", 5) == 0) {
3516 saddr
->type
= SOCKET_ADDRESS_KIND_UNIX
;
3517 saddr
->u
.q_unix
.data
= g_new0(UnixSocketAddress
, 1);
3518 saddr
->u
.q_unix
.data
->path
= g_strdup(vnc
+ 5);
3521 error_setg(errp
, "UNIX sockets not supported with websock");
3525 unsigned long long baseport
;
3526 InetSocketAddress
*inet
;
3527 saddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3528 inet
= saddr
->u
.inet
.data
= g_new0(InetSocketAddress
, 1);
3529 if (vnc
[0] == '[' && vnc
[hlen
- 1] == ']') {
3530 inet
->host
= g_strndup(vnc
+ 1, hlen
- 2);
3532 inet
->host
= g_strndup(vnc
, hlen
);
3534 if (parse_uint_full(h
+ 1, &baseport
, 10) < 0) {
3535 error_setg(errp
, "can't convert to a number: %s", h
+ 1);
3538 if (baseport
> 65535 ||
3539 baseport
+ 5900 > 65535) {
3540 error_setg(errp
, "port %s out of range", h
+ 1);
3543 inet
->port
= g_strdup_printf(
3544 "%d", (int)baseport
+ 5900);
3547 inet
->has_to
= true;
3548 inet
->to
= to
+ 5900;
3552 inet
->has_ipv4
= has_ipv4
;
3554 inet
->has_ipv6
= has_ipv6
;
3557 wsaddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3558 inet
= wsaddr
->u
.inet
.data
= g_new0(InetSocketAddress
, 1);
3559 inet
->host
= g_strdup(saddr
->u
.inet
.data
->host
);
3560 inet
->port
= g_strdup(websocket
);
3563 inet
->has_to
= true;
3567 inet
->has_ipv4
= has_ipv4
;
3569 inet
->has_ipv6
= has_ipv6
;
3573 error_setg(errp
, "no vnc port specified");
3577 password
= qemu_opt_get_bool(opts
, "password", false);
3579 if (fips_get_state()) {
3581 "VNC password auth disabled due to FIPS mode, "
3582 "consider using the VeNCrypt or SASL authentication "
3583 "methods as an alternative");
3586 if (!qcrypto_cipher_supports(
3587 QCRYPTO_CIPHER_ALG_DES_RFB
, QCRYPTO_CIPHER_MODE_ECB
)) {
3589 "Cipher backend does not support DES RFB algorithm");
3594 reverse
= qemu_opt_get_bool(opts
, "reverse", false);
3595 lock_key_sync
= qemu_opt_get_bool(opts
, "lock-key-sync", true);
3596 key_delay_ms
= qemu_opt_get_number(opts
, "key-delay-ms", 1);
3597 sasl
= qemu_opt_get_bool(opts
, "sasl", false);
3598 #ifndef CONFIG_VNC_SASL
3600 error_setg(errp
, "VNC SASL auth requires cyrus-sasl support");
3603 #endif /* CONFIG_VNC_SASL */
3604 credid
= qemu_opt_get(opts
, "tls-creds");
3607 if (qemu_opt_get(opts
, "tls") ||
3608 qemu_opt_get(opts
, "x509") ||
3609 qemu_opt_get(opts
, "x509verify")) {
3611 "'tls-creds' parameter is mutually exclusive with "
3612 "'tls', 'x509' and 'x509verify' parameters");
3616 creds
= object_resolve_path_component(
3617 object_get_objects_root(), credid
);
3619 error_setg(errp
, "No TLS credentials with id '%s'",
3623 vd
->tlscreds
= (QCryptoTLSCreds
*)
3624 object_dynamic_cast(creds
,
3625 TYPE_QCRYPTO_TLS_CREDS
);
3626 if (!vd
->tlscreds
) {
3627 error_setg(errp
, "Object with id '%s' is not TLS credentials",
3631 object_ref(OBJECT(vd
->tlscreds
));
3633 if (vd
->tlscreds
->endpoint
!= QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
) {
3635 "Expecting TLS credentials with a server endpoint");
3640 bool tls
= false, x509
= false, x509verify
= false;
3641 tls
= qemu_opt_get_bool(opts
, "tls", false);
3643 path
= qemu_opt_get(opts
, "x509");
3648 path
= qemu_opt_get(opts
, "x509verify");
3654 vd
->tlscreds
= vnc_display_create_creds(x509
,
3659 if (!vd
->tlscreds
) {
3664 acl
= qemu_opt_get_bool(opts
, "acl", false);
3666 share
= qemu_opt_get(opts
, "share");
3668 if (strcmp(share
, "ignore") == 0) {
3669 vd
->share_policy
= VNC_SHARE_POLICY_IGNORE
;
3670 } else if (strcmp(share
, "allow-exclusive") == 0) {
3671 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3672 } else if (strcmp(share
, "force-shared") == 0) {
3673 vd
->share_policy
= VNC_SHARE_POLICY_FORCE_SHARED
;
3675 error_setg(errp
, "unknown vnc share= option");
3679 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3681 vd
->connections_limit
= qemu_opt_get_number(opts
, "connections", 32);
3683 #ifdef CONFIG_VNC_JPEG
3684 vd
->lossy
= qemu_opt_get_bool(opts
, "lossy", false);
3686 vd
->non_adaptive
= qemu_opt_get_bool(opts
, "non-adaptive", false);
3687 /* adaptive updates are only used with tight encoding and
3688 * if lossy updates are enabled so we can disable all the
3689 * calculations otherwise */
3691 vd
->non_adaptive
= true;
3695 if (strcmp(vd
->id
, "default") == 0) {
3696 vd
->tlsaclname
= g_strdup("vnc.x509dname");
3698 vd
->tlsaclname
= g_strdup_printf("vnc.%s.x509dname", vd
->id
);
3700 qemu_acl_init(vd
->tlsaclname
);
3702 #ifdef CONFIG_VNC_SASL
3706 if (strcmp(vd
->id
, "default") == 0) {
3707 aclname
= g_strdup("vnc.username");
3709 aclname
= g_strdup_printf("vnc.%s.username", vd
->id
);
3711 vd
->sasl
.acl
= qemu_acl_init(aclname
);
3716 if (vnc_display_setup_auth(&vd
->auth
, &vd
->subauth
,
3717 vd
->tlscreds
, password
,
3718 sasl
, false, errp
) < 0) {
3722 if (vnc_display_setup_auth(&vd
->ws_auth
, &vd
->ws_subauth
,
3723 vd
->tlscreds
, password
,
3724 sasl
, true, errp
) < 0) {
3728 #ifdef CONFIG_VNC_SASL
3729 if ((saslErr
= sasl_server_init(NULL
, "qemu")) != SASL_OK
) {
3730 error_setg(errp
, "Failed to initialize SASL auth: %s",
3731 sasl_errstring(saslErr
, NULL
, NULL
));
3735 vd
->lock_key_sync
= lock_key_sync
;
3736 if (lock_key_sync
) {
3737 vd
->led
= qemu_add_led_event_handler(kbd_leds
, vd
);
3740 vd
->key_delay_ms
= key_delay_ms
;
3742 device_id
= qemu_opt_get(opts
, "display");
3744 int head
= qemu_opt_get_number(opts
, "head", 0);
3747 con
= qemu_console_lookup_by_device_name(device_id
, head
, &err
);
3749 error_propagate(errp
, err
);
3756 if (con
!= vd
->dcl
.con
) {
3757 unregister_displaychangelistener(&vd
->dcl
);
3759 register_displaychangelistener(&vd
->dcl
);
3763 /* connect to viewer */
3764 QIOChannelSocket
*sioc
= NULL
;
3766 vd
->lwebsock
= NULL
;
3768 error_setg(errp
, "Cannot use websockets in reverse mode");
3771 vd
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3772 sioc
= qio_channel_socket_new();
3773 qio_channel_set_name(QIO_CHANNEL(sioc
), "vnc-reverse");
3774 if (qio_channel_socket_connect_sync(sioc
, saddr
, errp
) < 0) {
3777 vnc_connect(vd
, sioc
, false, false);
3778 object_unref(OBJECT(sioc
));
3780 vd
->lsock
= qio_channel_socket_new();
3781 qio_channel_set_name(QIO_CHANNEL(vd
->lsock
), "vnc-listen");
3782 if (qio_channel_socket_listen_sync(vd
->lsock
, saddr
, errp
) < 0) {
3785 vd
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3788 vd
->lwebsock
= qio_channel_socket_new();
3789 qio_channel_set_name(QIO_CHANNEL(vd
->lwebsock
), "vnc-ws-listen");
3790 if (qio_channel_socket_listen_sync(vd
->lwebsock
,
3791 wsaddr
, errp
) < 0) {
3792 object_unref(OBJECT(vd
->lsock
));
3798 vd
->lsock_tag
= qio_channel_add_watch(
3799 QIO_CHANNEL(vd
->lsock
),
3800 G_IO_IN
, vnc_listen_io
, vd
, NULL
);
3802 vd
->lwebsock_tag
= qio_channel_add_watch(
3803 QIO_CHANNEL(vd
->lwebsock
),
3804 G_IO_IN
, vnc_listen_io
, vd
, NULL
);
3808 if (show_vnc_port
) {
3809 vnc_display_print_local_addr(vd
);
3812 qapi_free_SocketAddress(saddr
);
3813 qapi_free_SocketAddress(wsaddr
);
3817 qapi_free_SocketAddress(saddr
);
3818 qapi_free_SocketAddress(wsaddr
);
3822 void vnc_display_add_client(const char *id
, int csock
, bool skipauth
)
3824 VncDisplay
*vd
= vnc_display_find(id
);
3825 QIOChannelSocket
*sioc
;
3831 sioc
= qio_channel_socket_new_fd(csock
, NULL
);
3833 qio_channel_set_name(QIO_CHANNEL(sioc
), "vnc-server");
3834 vnc_connect(vd
, sioc
, skipauth
, false);
3835 object_unref(OBJECT(sioc
));
3839 static void vnc_auto_assign_id(QemuOptsList
*olist
, QemuOpts
*opts
)
3844 id
= g_strdup("default");
3845 while (qemu_opts_find(olist
, id
)) {
3847 id
= g_strdup_printf("vnc%d", i
++);
3849 qemu_opts_set_id(opts
, id
);
3852 QemuOpts
*vnc_parse(const char *str
, Error
**errp
)
3854 QemuOptsList
*olist
= qemu_find_opts("vnc");
3855 QemuOpts
*opts
= qemu_opts_parse(olist
, str
, true, errp
);
3862 id
= qemu_opts_id(opts
);
3864 /* auto-assign id if not present */
3865 vnc_auto_assign_id(olist
, opts
);
3870 int vnc_init_func(void *opaque
, QemuOpts
*opts
, Error
**errp
)
3872 Error
*local_err
= NULL
;
3873 char *id
= (char *)qemu_opts_id(opts
);
3876 vnc_display_init(id
);
3877 vnc_display_open(id
, &local_err
);
3878 if (local_err
!= NULL
) {
3879 error_reportf_err(local_err
, "Failed to start VNC server: ");
3885 static void vnc_register_config(void)
3887 qemu_add_opts(&qemu_vnc_opts
);
3889 opts_init(vnc_register_config
);