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
31 #include "sysemu/sysemu.h"
32 #include "qemu/error-report.h"
33 #include "qemu/sockets.h"
34 #include "qemu/timer.h"
36 #include "qemu/config-file.h"
37 #include "qapi/qmp/qerror.h"
38 #include "qapi/qmp/types.h"
39 #include "qmp-commands.h"
40 #include "qemu/osdep.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"
48 #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
49 #define VNC_REFRESH_INTERVAL_INC 50
50 #define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
51 static const struct timeval VNC_REFRESH_STATS
= { 0, 500000 };
52 static const struct timeval VNC_REFRESH_LOSSY
= { 2, 0 };
54 #include "vnc_keysym.h"
55 #include "crypto/cipher.h"
57 static QTAILQ_HEAD(, VncDisplay
) vnc_displays
=
58 QTAILQ_HEAD_INITIALIZER(vnc_displays
);
60 static int vnc_cursor_define(VncState
*vs
);
61 static void vnc_release_modifiers(VncState
*vs
);
63 static void vnc_set_share_mode(VncState
*vs
, VncShareMode mode
)
66 static const char *mn
[] = {
68 [VNC_SHARE_MODE_CONNECTING
] = "connecting",
69 [VNC_SHARE_MODE_SHARED
] = "shared",
70 [VNC_SHARE_MODE_EXCLUSIVE
] = "exclusive",
71 [VNC_SHARE_MODE_DISCONNECTED
] = "disconnected",
73 fprintf(stderr
, "%s/%p: %s -> %s\n", __func__
,
74 vs
->ioc
, mn
[vs
->share_mode
], mn
[mode
]);
77 switch (vs
->share_mode
) {
78 case VNC_SHARE_MODE_CONNECTING
:
79 vs
->vd
->num_connecting
--;
81 case VNC_SHARE_MODE_SHARED
:
84 case VNC_SHARE_MODE_EXCLUSIVE
:
85 vs
->vd
->num_exclusive
--;
91 vs
->share_mode
= mode
;
93 switch (vs
->share_mode
) {
94 case VNC_SHARE_MODE_CONNECTING
:
95 vs
->vd
->num_connecting
++;
97 case VNC_SHARE_MODE_SHARED
:
100 case VNC_SHARE_MODE_EXCLUSIVE
:
101 vs
->vd
->num_exclusive
++;
109 static void vnc_init_basic_info(SocketAddress
*addr
,
113 switch (addr
->type
) {
114 case SOCKET_ADDRESS_KIND_INET
:
115 info
->host
= g_strdup(addr
->u
.inet
->host
);
116 info
->service
= g_strdup(addr
->u
.inet
->port
);
117 if (addr
->u
.inet
->ipv6
) {
118 info
->family
= NETWORK_ADDRESS_FAMILY_IPV6
;
120 info
->family
= NETWORK_ADDRESS_FAMILY_IPV4
;
124 case SOCKET_ADDRESS_KIND_UNIX
:
125 info
->host
= g_strdup("");
126 info
->service
= g_strdup(addr
->u
.q_unix
->path
);
127 info
->family
= NETWORK_ADDRESS_FAMILY_UNIX
;
131 error_setg(errp
, "Unsupported socket kind %d",
139 static void vnc_init_basic_info_from_server_addr(QIOChannelSocket
*ioc
,
143 SocketAddress
*addr
= NULL
;
145 addr
= qio_channel_socket_get_local_address(ioc
, errp
);
150 vnc_init_basic_info(addr
, info
, errp
);
151 qapi_free_SocketAddress(addr
);
154 static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket
*ioc
,
158 SocketAddress
*addr
= NULL
;
160 addr
= qio_channel_socket_get_remote_address(ioc
, errp
);
165 vnc_init_basic_info(addr
, info
, errp
);
166 qapi_free_SocketAddress(addr
);
169 static const char *vnc_auth_name(VncDisplay
*vd
) {
171 case VNC_AUTH_INVALID
:
187 case VNC_AUTH_VENCRYPT
:
188 switch (vd
->subauth
) {
189 case VNC_AUTH_VENCRYPT_PLAIN
:
190 return "vencrypt+plain";
191 case VNC_AUTH_VENCRYPT_TLSNONE
:
192 return "vencrypt+tls+none";
193 case VNC_AUTH_VENCRYPT_TLSVNC
:
194 return "vencrypt+tls+vnc";
195 case VNC_AUTH_VENCRYPT_TLSPLAIN
:
196 return "vencrypt+tls+plain";
197 case VNC_AUTH_VENCRYPT_X509NONE
:
198 return "vencrypt+x509+none";
199 case VNC_AUTH_VENCRYPT_X509VNC
:
200 return "vencrypt+x509+vnc";
201 case VNC_AUTH_VENCRYPT_X509PLAIN
:
202 return "vencrypt+x509+plain";
203 case VNC_AUTH_VENCRYPT_TLSSASL
:
204 return "vencrypt+tls+sasl";
205 case VNC_AUTH_VENCRYPT_X509SASL
:
206 return "vencrypt+x509+sasl";
216 static VncServerInfo
*vnc_server_info_get(VncDisplay
*vd
)
221 info
= g_malloc(sizeof(*info
));
222 vnc_init_basic_info_from_server_addr(vd
->lsock
,
223 qapi_VncServerInfo_base(info
), &err
);
224 info
->has_auth
= true;
225 info
->auth
= g_strdup(vnc_auth_name(vd
));
227 qapi_free_VncServerInfo(info
);
234 static void vnc_client_cache_auth(VncState
*client
)
241 client
->info
->x509_dname
=
242 qcrypto_tls_session_get_peer_name(client
->tls
);
243 client
->info
->has_x509_dname
=
244 client
->info
->x509_dname
!= NULL
;
246 #ifdef CONFIG_VNC_SASL
247 if (client
->sasl
.conn
&&
248 client
->sasl
.username
) {
249 client
->info
->has_sasl_username
= true;
250 client
->info
->sasl_username
= g_strdup(client
->sasl
.username
);
255 static void vnc_client_cache_addr(VncState
*client
)
259 client
->info
= g_malloc0(sizeof(*client
->info
));
260 vnc_init_basic_info_from_remote_addr(client
->sioc
,
261 qapi_VncClientInfo_base(client
->info
),
264 qapi_free_VncClientInfo(client
->info
);
270 static void vnc_qmp_event(VncState
*vs
, QAPIEvent event
)
278 si
= vnc_server_info_get(vs
->vd
);
284 case QAPI_EVENT_VNC_CONNECTED
:
285 qapi_event_send_vnc_connected(si
, qapi_VncClientInfo_base(vs
->info
),
288 case QAPI_EVENT_VNC_INITIALIZED
:
289 qapi_event_send_vnc_initialized(si
, vs
->info
, &error_abort
);
291 case QAPI_EVENT_VNC_DISCONNECTED
:
292 qapi_event_send_vnc_disconnected(si
, vs
->info
, &error_abort
);
298 qapi_free_VncServerInfo(si
);
301 static VncClientInfo
*qmp_query_vnc_client(const VncState
*client
)
306 info
= g_malloc0(sizeof(*info
));
308 vnc_init_basic_info_from_remote_addr(client
->sioc
,
309 qapi_VncClientInfo_base(info
),
313 qapi_free_VncClientInfo(info
);
317 info
->websocket
= client
->websocket
;
320 info
->x509_dname
= qcrypto_tls_session_get_peer_name(client
->tls
);
321 info
->has_x509_dname
= info
->x509_dname
!= NULL
;
323 #ifdef CONFIG_VNC_SASL
324 if (client
->sasl
.conn
&& client
->sasl
.username
) {
325 info
->has_sasl_username
= true;
326 info
->sasl_username
= g_strdup(client
->sasl
.username
);
333 static VncDisplay
*vnc_display_find(const char *id
)
338 return QTAILQ_FIRST(&vnc_displays
);
340 QTAILQ_FOREACH(vd
, &vnc_displays
, next
) {
341 if (strcmp(id
, vd
->id
) == 0) {
348 static VncClientInfoList
*qmp_query_client_list(VncDisplay
*vd
)
350 VncClientInfoList
*cinfo
, *prev
= NULL
;
353 QTAILQ_FOREACH(client
, &vd
->clients
, next
) {
354 cinfo
= g_new0(VncClientInfoList
, 1);
355 cinfo
->value
= qmp_query_vnc_client(client
);
362 VncInfo
*qmp_query_vnc(Error
**errp
)
364 VncInfo
*info
= g_malloc0(sizeof(*info
));
365 VncDisplay
*vd
= vnc_display_find(NULL
);
366 SocketAddress
*addr
= NULL
;
368 if (vd
== NULL
|| !vd
->enabled
) {
369 info
->enabled
= false;
371 info
->enabled
= true;
373 /* for compatibility with the original command */
374 info
->has_clients
= true;
375 info
->clients
= qmp_query_client_list(vd
);
377 if (vd
->lsock
== NULL
) {
381 addr
= qio_channel_socket_get_local_address(vd
->lsock
, errp
);
386 switch (addr
->type
) {
387 case SOCKET_ADDRESS_KIND_INET
:
388 info
->host
= g_strdup(addr
->u
.inet
->host
);
389 info
->service
= g_strdup(addr
->u
.inet
->port
);
390 if (addr
->u
.inet
->ipv6
) {
391 info
->family
= NETWORK_ADDRESS_FAMILY_IPV6
;
393 info
->family
= NETWORK_ADDRESS_FAMILY_IPV4
;
397 case SOCKET_ADDRESS_KIND_UNIX
:
398 info
->host
= g_strdup("");
399 info
->service
= g_strdup(addr
->u
.q_unix
->path
);
400 info
->family
= NETWORK_ADDRESS_FAMILY_UNIX
;
404 error_setg(errp
, "Unsupported socket kind %d",
409 info
->has_host
= true;
410 info
->has_service
= true;
411 info
->has_family
= true;
413 info
->has_auth
= true;
414 info
->auth
= g_strdup(vnc_auth_name(vd
));
417 qapi_free_SocketAddress(addr
);
421 qapi_free_SocketAddress(addr
);
422 qapi_free_VncInfo(info
);
426 static VncBasicInfoList
*qmp_query_server_entry(QIOChannelSocket
*ioc
,
428 VncBasicInfoList
*prev
)
430 VncBasicInfoList
*list
;
435 addr
= qio_channel_socket_get_local_address(ioc
, &err
);
441 info
= g_new0(VncBasicInfo
, 1);
442 vnc_init_basic_info(addr
, info
, &err
);
443 qapi_free_SocketAddress(addr
);
445 qapi_free_VncBasicInfo(info
);
449 info
->websocket
= websocket
;
451 list
= g_new0(VncBasicInfoList
, 1);
457 static void qmp_query_auth(VncDisplay
*vd
, VncInfo2
*info
)
461 info
->auth
= VNC_PRIMARY_AUTH_VNC
;
464 info
->auth
= VNC_PRIMARY_AUTH_RA2
;
467 info
->auth
= VNC_PRIMARY_AUTH_RA2NE
;
470 info
->auth
= VNC_PRIMARY_AUTH_TIGHT
;
473 info
->auth
= VNC_PRIMARY_AUTH_ULTRA
;
476 info
->auth
= VNC_PRIMARY_AUTH_TLS
;
478 case VNC_AUTH_VENCRYPT
:
479 info
->auth
= VNC_PRIMARY_AUTH_VENCRYPT
;
480 info
->has_vencrypt
= true;
481 switch (vd
->subauth
) {
482 case VNC_AUTH_VENCRYPT_PLAIN
:
483 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_PLAIN
;
485 case VNC_AUTH_VENCRYPT_TLSNONE
:
486 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_NONE
;
488 case VNC_AUTH_VENCRYPT_TLSVNC
:
489 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_VNC
;
491 case VNC_AUTH_VENCRYPT_TLSPLAIN
:
492 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN
;
494 case VNC_AUTH_VENCRYPT_X509NONE
:
495 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_NONE
;
497 case VNC_AUTH_VENCRYPT_X509VNC
:
498 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_VNC
;
500 case VNC_AUTH_VENCRYPT_X509PLAIN
:
501 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_PLAIN
;
503 case VNC_AUTH_VENCRYPT_TLSSASL
:
504 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_SASL
;
506 case VNC_AUTH_VENCRYPT_X509SASL
:
507 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_SASL
;
510 info
->has_vencrypt
= false;
515 info
->auth
= VNC_PRIMARY_AUTH_SASL
;
519 info
->auth
= VNC_PRIMARY_AUTH_NONE
;
524 VncInfo2List
*qmp_query_vnc_servers(Error
**errp
)
526 VncInfo2List
*item
, *prev
= NULL
;
531 QTAILQ_FOREACH(vd
, &vnc_displays
, next
) {
532 info
= g_new0(VncInfo2
, 1);
533 info
->id
= g_strdup(vd
->id
);
534 info
->clients
= qmp_query_client_list(vd
);
535 qmp_query_auth(vd
, info
);
537 dev
= DEVICE(object_property_get_link(OBJECT(vd
->dcl
.con
),
539 info
->has_display
= true;
540 info
->display
= g_strdup(dev
->id
);
542 if (vd
->lsock
!= NULL
) {
543 info
->server
= qmp_query_server_entry(
544 vd
->lsock
, false, info
->server
);
546 if (vd
->lwebsock
!= NULL
) {
547 info
->server
= qmp_query_server_entry(
548 vd
->lwebsock
, true, info
->server
);
551 item
= g_new0(VncInfo2List
, 1);
560 1) Get the queue working for IO.
561 2) there is some weirdness when using the -S option (the screen is grey
562 and not totally invalidated
563 3) resolutions > 1024
566 static int vnc_update_client(VncState
*vs
, int has_dirty
, bool sync
);
567 static void vnc_disconnect_start(VncState
*vs
);
569 static void vnc_colordepth(VncState
*vs
);
570 static void framebuffer_update_request(VncState
*vs
, int incremental
,
571 int x_position
, int y_position
,
573 static void vnc_refresh(DisplayChangeListener
*dcl
);
574 static int vnc_refresh_server_surface(VncDisplay
*vd
);
576 static int vnc_width(VncDisplay
*vd
)
578 return MIN(VNC_MAX_WIDTH
, ROUND_UP(surface_width(vd
->ds
),
579 VNC_DIRTY_PIXELS_PER_BIT
));
582 static int vnc_height(VncDisplay
*vd
)
584 return MIN(VNC_MAX_HEIGHT
, surface_height(vd
->ds
));
587 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty
[VNC_MAX_HEIGHT
],
588 VNC_MAX_WIDTH
/ VNC_DIRTY_PIXELS_PER_BIT
),
590 int x
, int y
, int w
, int h
)
592 int width
= vnc_width(vd
);
593 int height
= vnc_height(vd
);
595 /* this is needed this to ensure we updated all affected
596 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
597 w
+= (x
% VNC_DIRTY_PIXELS_PER_BIT
);
598 x
-= (x
% VNC_DIRTY_PIXELS_PER_BIT
);
602 w
= MIN(x
+ w
, width
) - x
;
603 h
= MIN(y
+ h
, height
);
606 bitmap_set(dirty
[y
], x
/ VNC_DIRTY_PIXELS_PER_BIT
,
607 DIV_ROUND_UP(w
, VNC_DIRTY_PIXELS_PER_BIT
));
611 static void vnc_dpy_update(DisplayChangeListener
*dcl
,
612 int x
, int y
, int w
, int h
)
614 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
615 struct VncSurface
*s
= &vd
->guest
;
617 vnc_set_area_dirty(s
->dirty
, vd
, x
, y
, w
, h
);
620 void vnc_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
,
623 vnc_write_u16(vs
, x
);
624 vnc_write_u16(vs
, y
);
625 vnc_write_u16(vs
, w
);
626 vnc_write_u16(vs
, h
);
628 vnc_write_s32(vs
, encoding
);
632 static void vnc_desktop_resize(VncState
*vs
)
634 if (vs
->ioc
== NULL
|| !vnc_has_feature(vs
, VNC_FEATURE_RESIZE
)) {
637 if (vs
->client_width
== pixman_image_get_width(vs
->vd
->server
) &&
638 vs
->client_height
== pixman_image_get_height(vs
->vd
->server
)) {
641 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
642 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
644 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
646 vnc_write_u16(vs
, 1); /* number of rects */
647 vnc_framebuffer_update(vs
, 0, 0, vs
->client_width
, vs
->client_height
,
648 VNC_ENCODING_DESKTOPRESIZE
);
649 vnc_unlock_output(vs
);
653 static void vnc_abort_display_jobs(VncDisplay
*vd
)
657 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
660 vnc_unlock_output(vs
);
662 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
665 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
668 vnc_unlock_output(vs
);
672 int vnc_server_fb_stride(VncDisplay
*vd
)
674 return pixman_image_get_stride(vd
->server
);
677 void *vnc_server_fb_ptr(VncDisplay
*vd
, int x
, int y
)
681 ptr
= (uint8_t *)pixman_image_get_data(vd
->server
);
682 ptr
+= y
* vnc_server_fb_stride(vd
);
683 ptr
+= x
* VNC_SERVER_FB_BYTES
;
687 static void vnc_update_server_surface(VncDisplay
*vd
)
689 qemu_pixman_image_unref(vd
->server
);
692 if (QTAILQ_EMPTY(&vd
->clients
)) {
696 vd
->server
= pixman_image_create_bits(VNC_SERVER_FB_FORMAT
,
702 static void vnc_dpy_switch(DisplayChangeListener
*dcl
,
703 DisplaySurface
*surface
)
705 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
709 vnc_abort_display_jobs(vd
);
713 vnc_update_server_surface(vd
);
716 qemu_pixman_image_unref(vd
->guest
.fb
);
717 vd
->guest
.fb
= pixman_image_ref(surface
->image
);
718 vd
->guest
.format
= surface
->format
;
719 width
= vnc_width(vd
);
720 height
= vnc_height(vd
);
721 memset(vd
->guest
.dirty
, 0x00, sizeof(vd
->guest
.dirty
));
722 vnc_set_area_dirty(vd
->guest
.dirty
, vd
, 0, 0,
725 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
727 vnc_desktop_resize(vs
);
728 if (vs
->vd
->cursor
) {
729 vnc_cursor_define(vs
);
731 memset(vs
->dirty
, 0x00, sizeof(vs
->dirty
));
732 vnc_set_area_dirty(vs
->dirty
, vd
, 0, 0,
738 static void vnc_write_pixels_copy(VncState
*vs
,
739 void *pixels
, int size
)
741 vnc_write(vs
, pixels
, size
);
744 /* slowest but generic code. */
745 void vnc_convert_pixel(VncState
*vs
, uint8_t *buf
, uint32_t v
)
749 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
750 r
= (((v
& 0x00ff0000) >> 16) << vs
->client_pf
.rbits
) >> 8;
751 g
= (((v
& 0x0000ff00) >> 8) << vs
->client_pf
.gbits
) >> 8;
752 b
= (((v
& 0x000000ff) >> 0) << vs
->client_pf
.bbits
) >> 8;
754 # error need some bits here if you change VNC_SERVER_FB_FORMAT
756 v
= (r
<< vs
->client_pf
.rshift
) |
757 (g
<< vs
->client_pf
.gshift
) |
758 (b
<< vs
->client_pf
.bshift
);
759 switch (vs
->client_pf
.bytes_per_pixel
) {
789 static void vnc_write_pixels_generic(VncState
*vs
,
790 void *pixels1
, int size
)
794 if (VNC_SERVER_FB_BYTES
== 4) {
795 uint32_t *pixels
= pixels1
;
798 for (i
= 0; i
< n
; i
++) {
799 vnc_convert_pixel(vs
, buf
, pixels
[i
]);
800 vnc_write(vs
, buf
, vs
->client_pf
.bytes_per_pixel
);
805 int vnc_raw_send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
809 VncDisplay
*vd
= vs
->vd
;
811 row
= vnc_server_fb_ptr(vd
, x
, y
);
812 for (i
= 0; i
< h
; i
++) {
813 vs
->write_pixels(vs
, row
, w
* VNC_SERVER_FB_BYTES
);
814 row
+= vnc_server_fb_stride(vd
);
819 int vnc_send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
822 bool encode_raw
= false;
823 size_t saved_offs
= vs
->output
.offset
;
825 switch(vs
->vnc_encoding
) {
826 case VNC_ENCODING_ZLIB
:
827 n
= vnc_zlib_send_framebuffer_update(vs
, x
, y
, w
, h
);
829 case VNC_ENCODING_HEXTILE
:
830 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_HEXTILE
);
831 n
= vnc_hextile_send_framebuffer_update(vs
, x
, y
, w
, h
);
833 case VNC_ENCODING_TIGHT
:
834 n
= vnc_tight_send_framebuffer_update(vs
, x
, y
, w
, h
);
836 case VNC_ENCODING_TIGHT_PNG
:
837 n
= vnc_tight_png_send_framebuffer_update(vs
, x
, y
, w
, h
);
839 case VNC_ENCODING_ZRLE
:
840 n
= vnc_zrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
842 case VNC_ENCODING_ZYWRLE
:
843 n
= vnc_zywrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
850 /* If the client has the same pixel format as our internal buffer and
851 * a RAW encoding would need less space fall back to RAW encoding to
852 * save bandwidth and processing power in the client. */
853 if (!encode_raw
&& vs
->write_pixels
== vnc_write_pixels_copy
&&
854 12 + h
* w
* VNC_SERVER_FB_BYTES
<= (vs
->output
.offset
- saved_offs
)) {
855 vs
->output
.offset
= saved_offs
;
860 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_RAW
);
861 n
= vnc_raw_send_framebuffer_update(vs
, x
, y
, w
, h
);
867 static void vnc_copy(VncState
*vs
, int src_x
, int src_y
, int dst_x
, int dst_y
, int w
, int h
)
869 /* send bitblit op to the vnc client */
871 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
873 vnc_write_u16(vs
, 1); /* number of rects */
874 vnc_framebuffer_update(vs
, dst_x
, dst_y
, w
, h
, VNC_ENCODING_COPYRECT
);
875 vnc_write_u16(vs
, src_x
);
876 vnc_write_u16(vs
, src_y
);
877 vnc_unlock_output(vs
);
881 static void vnc_dpy_copy(DisplayChangeListener
*dcl
,
882 int src_x
, int src_y
,
883 int dst_x
, int dst_y
, int w
, int h
)
885 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
889 int i
, x
, y
, pitch
, inc
, w_lim
, s
;
893 /* no client connected */
897 vnc_refresh_server_surface(vd
);
898 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
899 if (vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
900 vs
->force_update
= 1;
901 vnc_update_client(vs
, 1, true);
902 /* vs might be free()ed here */
906 /* do bitblit op on the local surface too */
907 pitch
= vnc_server_fb_stride(vd
);
908 src_row
= vnc_server_fb_ptr(vd
, src_x
, src_y
);
909 dst_row
= vnc_server_fb_ptr(vd
, dst_x
, dst_y
);
914 src_row
+= pitch
* (h
-1);
915 dst_row
+= pitch
* (h
-1);
920 w_lim
= w
- (VNC_DIRTY_PIXELS_PER_BIT
- (dst_x
% VNC_DIRTY_PIXELS_PER_BIT
));
924 w_lim
= w
- (w_lim
% VNC_DIRTY_PIXELS_PER_BIT
);
926 for (i
= 0; i
< h
; i
++) {
927 for (x
= 0; x
<= w_lim
;
928 x
+= s
, src_row
+= cmp_bytes
, dst_row
+= cmp_bytes
) {
930 if ((s
= w
- w_lim
) == 0)
933 s
= (VNC_DIRTY_PIXELS_PER_BIT
-
934 (dst_x
% VNC_DIRTY_PIXELS_PER_BIT
));
937 s
= VNC_DIRTY_PIXELS_PER_BIT
;
939 cmp_bytes
= s
* VNC_SERVER_FB_BYTES
;
940 if (memcmp(src_row
, dst_row
, cmp_bytes
) == 0)
942 memmove(dst_row
, src_row
, cmp_bytes
);
943 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
944 if (!vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
945 set_bit(((x
+ dst_x
) / VNC_DIRTY_PIXELS_PER_BIT
),
950 src_row
+= pitch
- w
* VNC_SERVER_FB_BYTES
;
951 dst_row
+= pitch
- w
* VNC_SERVER_FB_BYTES
;
955 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
956 if (vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
957 vnc_copy(vs
, src_x
, src_y
, dst_x
, dst_y
, w
, h
);
962 static void vnc_mouse_set(DisplayChangeListener
*dcl
,
963 int x
, int y
, int visible
)
965 /* can we ask the client(s) to move the pointer ??? */
968 static int vnc_cursor_define(VncState
*vs
)
970 QEMUCursor
*c
= vs
->vd
->cursor
;
973 if (vnc_has_feature(vs
, VNC_FEATURE_RICH_CURSOR
)) {
975 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
976 vnc_write_u8(vs
, 0); /* padding */
977 vnc_write_u16(vs
, 1); /* # of rects */
978 vnc_framebuffer_update(vs
, c
->hot_x
, c
->hot_y
, c
->width
, c
->height
,
979 VNC_ENCODING_RICH_CURSOR
);
980 isize
= c
->width
* c
->height
* vs
->client_pf
.bytes_per_pixel
;
981 vnc_write_pixels_generic(vs
, c
->data
, isize
);
982 vnc_write(vs
, vs
->vd
->cursor_mask
, vs
->vd
->cursor_msize
);
983 vnc_unlock_output(vs
);
989 static void vnc_dpy_cursor_define(DisplayChangeListener
*dcl
,
992 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
995 cursor_put(vd
->cursor
);
996 g_free(vd
->cursor_mask
);
999 cursor_get(vd
->cursor
);
1000 vd
->cursor_msize
= cursor_get_mono_bpl(c
) * c
->height
;
1001 vd
->cursor_mask
= g_malloc0(vd
->cursor_msize
);
1002 cursor_get_mono_mask(c
, 0, vd
->cursor_mask
);
1004 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
1005 vnc_cursor_define(vs
);
1009 static int find_and_clear_dirty_height(VncState
*vs
,
1010 int y
, int last_x
, int x
, int height
)
1014 for (h
= 1; h
< (height
- y
); h
++) {
1015 if (!test_bit(last_x
, vs
->dirty
[y
+ h
])) {
1018 bitmap_clear(vs
->dirty
[y
+ h
], last_x
, x
- last_x
);
1024 static int vnc_update_client(VncState
*vs
, int has_dirty
, bool sync
)
1026 vs
->has_dirty
+= has_dirty
;
1027 if (vs
->need_update
&& vs
->ioc
!= NULL
) {
1028 VncDisplay
*vd
= vs
->vd
;
1034 if (vs
->output
.offset
&& !vs
->audio_cap
&& !vs
->force_update
)
1035 /* kernel send buffers are full -> drop frames to throttle */
1038 if (!vs
->has_dirty
&& !vs
->audio_cap
&& !vs
->force_update
)
1042 * Send screen updates to the vnc client using the server
1043 * surface and server dirty map. guest surface updates
1044 * happening in parallel don't disturb us, the next pass will
1045 * send them to the client.
1047 job
= vnc_job_new(vs
);
1049 height
= pixman_image_get_height(vd
->server
);
1050 width
= pixman_image_get_width(vd
->server
);
1056 unsigned long offset
= find_next_bit((unsigned long *) &vs
->dirty
,
1057 height
* VNC_DIRTY_BPL(vs
),
1058 y
* VNC_DIRTY_BPL(vs
));
1059 if (offset
== height
* VNC_DIRTY_BPL(vs
)) {
1060 /* no more dirty bits */
1063 y
= offset
/ VNC_DIRTY_BPL(vs
);
1064 x
= offset
% VNC_DIRTY_BPL(vs
);
1065 x2
= find_next_zero_bit((unsigned long *) &vs
->dirty
[y
],
1066 VNC_DIRTY_BPL(vs
), x
);
1067 bitmap_clear(vs
->dirty
[y
], x
, x2
- x
);
1068 h
= find_and_clear_dirty_height(vs
, y
, x
, x2
, height
);
1069 x2
= MIN(x2
, width
/ VNC_DIRTY_PIXELS_PER_BIT
);
1071 n
+= vnc_job_add_rect(job
, x
* VNC_DIRTY_PIXELS_PER_BIT
, y
,
1072 (x2
- x
) * VNC_DIRTY_PIXELS_PER_BIT
, h
);
1074 if (!x
&& x2
== width
/ VNC_DIRTY_PIXELS_PER_BIT
) {
1086 vs
->force_update
= 0;
1091 if (vs
->disconnecting
) {
1092 vnc_disconnect_finish(vs
);
1101 static void audio_capture_notify(void *opaque
, audcnotification_e cmd
)
1103 VncState
*vs
= opaque
;
1106 case AUD_CNOTIFY_DISABLE
:
1107 vnc_lock_output(vs
);
1108 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1109 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1110 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_END
);
1111 vnc_unlock_output(vs
);
1115 case AUD_CNOTIFY_ENABLE
:
1116 vnc_lock_output(vs
);
1117 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1118 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1119 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN
);
1120 vnc_unlock_output(vs
);
1126 static void audio_capture_destroy(void *opaque
)
1130 static void audio_capture(void *opaque
, void *buf
, int size
)
1132 VncState
*vs
= opaque
;
1134 vnc_lock_output(vs
);
1135 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1136 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1137 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_DATA
);
1138 vnc_write_u32(vs
, size
);
1139 vnc_write(vs
, buf
, size
);
1140 vnc_unlock_output(vs
);
1144 static void audio_add(VncState
*vs
)
1146 struct audio_capture_ops ops
;
1148 if (vs
->audio_cap
) {
1149 error_report("audio already running");
1153 ops
.notify
= audio_capture_notify
;
1154 ops
.destroy
= audio_capture_destroy
;
1155 ops
.capture
= audio_capture
;
1157 vs
->audio_cap
= AUD_add_capture(&vs
->as
, &ops
, vs
);
1158 if (!vs
->audio_cap
) {
1159 error_report("Failed to add audio capture");
1163 static void audio_del(VncState
*vs
)
1165 if (vs
->audio_cap
) {
1166 AUD_del_capture(vs
->audio_cap
, vs
);
1167 vs
->audio_cap
= NULL
;
1171 static void vnc_disconnect_start(VncState
*vs
)
1173 if (vs
->disconnecting
) {
1176 vnc_set_share_mode(vs
, VNC_SHARE_MODE_DISCONNECTED
);
1178 g_source_remove(vs
->ioc_tag
);
1180 qio_channel_close(vs
->ioc
, NULL
);
1181 vs
->disconnecting
= TRUE
;
1184 void vnc_disconnect_finish(VncState
*vs
)
1188 vnc_jobs_join(vs
); /* Wait encoding jobs */
1190 vnc_lock_output(vs
);
1191 vnc_qmp_event(vs
, QAPI_EVENT_VNC_DISCONNECTED
);
1193 buffer_free(&vs
->input
);
1194 buffer_free(&vs
->output
);
1195 buffer_free(&vs
->ws_input
);
1196 buffer_free(&vs
->ws_output
);
1198 qapi_free_VncClientInfo(vs
->info
);
1201 vnc_tight_clear(vs
);
1204 qcrypto_tls_session_free(vs
->tls
);
1205 #ifdef CONFIG_VNC_SASL
1206 vnc_sasl_client_cleanup(vs
);
1207 #endif /* CONFIG_VNC_SASL */
1209 vnc_release_modifiers(vs
);
1211 if (vs
->initialized
) {
1212 QTAILQ_REMOVE(&vs
->vd
->clients
, vs
, next
);
1213 qemu_remove_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
1214 if (QTAILQ_EMPTY(&vs
->vd
->clients
)) {
1215 /* last client gone */
1216 vnc_update_server_surface(vs
->vd
);
1220 if (vs
->vd
->lock_key_sync
)
1221 qemu_remove_led_event_handler(vs
->led
);
1222 vnc_unlock_output(vs
);
1224 qemu_mutex_destroy(&vs
->output_mutex
);
1225 if (vs
->bh
!= NULL
) {
1226 qemu_bh_delete(vs
->bh
);
1228 buffer_free(&vs
->jobs_buffer
);
1230 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
1231 g_free(vs
->lossy_rect
[i
]);
1233 g_free(vs
->lossy_rect
);
1235 object_unref(OBJECT(vs
->ioc
));
1237 object_unref(OBJECT(vs
->sioc
));
1242 ssize_t
vnc_client_io_error(VncState
*vs
, ssize_t ret
, Error
**errp
)
1246 VNC_DEBUG("Closing down client sock: EOF\n");
1247 } else if (ret
!= QIO_CHANNEL_ERR_BLOCK
) {
1248 VNC_DEBUG("Closing down client sock: ret %d (%s)\n",
1249 ret
, errp
? error_get_pretty(*errp
) : "Unknown");
1252 vnc_disconnect_start(vs
);
1263 void vnc_client_error(VncState
*vs
)
1265 VNC_DEBUG("Closing down client sock: protocol error\n");
1266 vnc_disconnect_start(vs
);
1270 ssize_t
vnc_tls_pull(char *buf
, size_t len
, void *opaque
)
1272 VncState
*vs
= opaque
;
1273 ssize_t ret
= qio_channel_read(vs
->ioc
, buf
, len
, NULL
);
1275 if (ret
== QIO_CHANNEL_ERR_BLOCK
) {
1286 ssize_t
vnc_tls_push(const char *buf
, size_t len
, void *opaque
)
1288 VncState
*vs
= opaque
;
1289 ssize_t ret
= qio_channel_write(vs
->ioc
, buf
, len
, NULL
);
1291 if (ret
== QIO_CHANNEL_ERR_BLOCK
) {
1303 * Called to write a chunk of data to the client socket. The data may
1304 * be the raw data, or may have already been encoded by SASL.
1305 * The data will be written either straight onto the socket, or
1306 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1308 * NB, it is theoretically possible to have 2 layers of encryption,
1309 * both SASL, and this TLS layer. It is highly unlikely in practice
1310 * though, since SASL encryption will typically be a no-op if TLS
1313 * Returns the number of bytes written, which may be less than
1314 * the requested 'datalen' if the socket would block. Returns
1315 * -1 on error, and disconnects the client socket.
1317 ssize_t
vnc_client_write_buf(VncState
*vs
, const uint8_t *data
, size_t datalen
)
1322 ret
= qcrypto_tls_session_write(vs
->tls
, (const char *)data
, datalen
);
1324 if (errno
== EAGAIN
) {
1325 ret
= QIO_CHANNEL_ERR_BLOCK
;
1328 error_setg_errno(&err
, errno
, "%s",
1329 "Cannot write to TLS socket");
1333 ret
= qio_channel_write(
1334 vs
->ioc
, (const char *)data
, datalen
, &err
);
1336 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data
, datalen
, ret
);
1337 return vnc_client_io_error(vs
, ret
, &err
);
1342 * Called to write buffered data to the client socket, when not
1343 * using any SASL SSF encryption layers. Will write as much data
1344 * as possible without blocking. If all buffered data is written,
1345 * will switch the FD poll() handler back to read monitoring.
1347 * Returns the number of bytes written, which may be less than
1348 * the buffered output data if the socket would block. Returns
1349 * -1 on error, and disconnects the client socket.
1351 static ssize_t
vnc_client_write_plain(VncState
*vs
)
1355 #ifdef CONFIG_VNC_SASL
1356 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1357 vs
->output
.buffer
, vs
->output
.capacity
, vs
->output
.offset
,
1358 vs
->sasl
.waitWriteSSF
);
1360 if (vs
->sasl
.conn
&&
1362 vs
->sasl
.waitWriteSSF
) {
1363 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->sasl
.waitWriteSSF
);
1365 vs
->sasl
.waitWriteSSF
-= ret
;
1367 #endif /* CONFIG_VNC_SASL */
1368 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->output
.offset
);
1372 buffer_advance(&vs
->output
, ret
);
1374 if (vs
->output
.offset
== 0) {
1376 g_source_remove(vs
->ioc_tag
);
1378 vs
->ioc_tag
= qio_channel_add_watch(
1379 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1387 * First function called whenever there is data to be written to
1388 * the client socket. Will delegate actual work according to whether
1389 * SASL SSF layers are enabled (thus requiring encryption calls)
1391 static void vnc_client_write_locked(VncState
*vs
)
1393 #ifdef CONFIG_VNC_SASL
1394 if (vs
->sasl
.conn
&&
1396 !vs
->sasl
.waitWriteSSF
) {
1397 vnc_client_write_sasl(vs
);
1399 #endif /* CONFIG_VNC_SASL */
1401 if (vs
->encode_ws
) {
1402 vnc_client_write_ws(vs
);
1404 vnc_client_write_plain(vs
);
1409 static void vnc_client_write(VncState
*vs
)
1412 vnc_lock_output(vs
);
1413 if (vs
->output
.offset
|| vs
->ws_output
.offset
) {
1414 vnc_client_write_locked(vs
);
1415 } else if (vs
->ioc
!= NULL
) {
1417 g_source_remove(vs
->ioc_tag
);
1419 vs
->ioc_tag
= qio_channel_add_watch(
1420 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1422 vnc_unlock_output(vs
);
1425 void vnc_read_when(VncState
*vs
, VncReadEvent
*func
, size_t expecting
)
1427 vs
->read_handler
= func
;
1428 vs
->read_handler_expect
= expecting
;
1433 * Called to read a chunk of data from the client socket. The data may
1434 * be the raw data, or may need to be further decoded by SASL.
1435 * The data will be read either straight from to the socket, or
1436 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1438 * NB, it is theoretically possible to have 2 layers of encryption,
1439 * both SASL, and this TLS layer. It is highly unlikely in practice
1440 * though, since SASL encryption will typically be a no-op if TLS
1443 * Returns the number of bytes read, which may be less than
1444 * the requested 'datalen' if the socket would block. Returns
1445 * -1 on error, and disconnects the client socket.
1447 ssize_t
vnc_client_read_buf(VncState
*vs
, uint8_t *data
, size_t datalen
)
1452 ret
= qcrypto_tls_session_read(vs
->tls
, (char *)data
, datalen
);
1454 if (errno
== EAGAIN
) {
1455 ret
= QIO_CHANNEL_ERR_BLOCK
;
1458 error_setg_errno(&err
, errno
, "%s",
1459 "Cannot read from TLS socket");
1463 ret
= qio_channel_read(
1464 vs
->ioc
, (char *)data
, datalen
, &err
);
1466 VNC_DEBUG("Read wire %p %zd -> %ld\n", data
, datalen
, ret
);
1467 return vnc_client_io_error(vs
, ret
, &err
);
1472 * Called to read data from the client socket to the input buffer,
1473 * when not using any SASL SSF encryption layers. Will read as much
1474 * data as possible without blocking.
1476 * Returns the number of bytes read. Returns -1 on error, and
1477 * disconnects the client socket.
1479 static ssize_t
vnc_client_read_plain(VncState
*vs
)
1482 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1483 vs
->input
.buffer
, vs
->input
.capacity
, vs
->input
.offset
);
1484 buffer_reserve(&vs
->input
, 4096);
1485 ret
= vnc_client_read_buf(vs
, buffer_end(&vs
->input
), 4096);
1488 vs
->input
.offset
+= ret
;
1492 static void vnc_jobs_bh(void *opaque
)
1494 VncState
*vs
= opaque
;
1496 vnc_jobs_consume_buffer(vs
);
1500 * First function called whenever there is more data to be read from
1501 * the client socket. Will delegate actual work according to whether
1502 * SASL SSF layers are enabled (thus requiring decryption calls)
1504 static void vnc_client_read(VncState
*vs
)
1508 #ifdef CONFIG_VNC_SASL
1509 if (vs
->sasl
.conn
&& vs
->sasl
.runSSF
)
1510 ret
= vnc_client_read_sasl(vs
);
1512 #endif /* CONFIG_VNC_SASL */
1513 if (vs
->encode_ws
) {
1514 ret
= vnc_client_read_ws(vs
);
1516 vnc_disconnect_start(vs
);
1518 } else if (ret
== -2) {
1519 vnc_client_error(vs
);
1523 ret
= vnc_client_read_plain(vs
);
1526 if (vs
->disconnecting
) {
1527 vnc_disconnect_finish(vs
);
1532 while (vs
->read_handler
&& vs
->input
.offset
>= vs
->read_handler_expect
) {
1533 size_t len
= vs
->read_handler_expect
;
1536 ret
= vs
->read_handler(vs
, vs
->input
.buffer
, len
);
1537 if (vs
->disconnecting
) {
1538 vnc_disconnect_finish(vs
);
1543 buffer_advance(&vs
->input
, len
);
1545 vs
->read_handler_expect
= ret
;
1550 gboolean
vnc_client_io(QIOChannel
*ioc G_GNUC_UNUSED
,
1551 GIOCondition condition
, void *opaque
)
1553 VncState
*vs
= opaque
;
1554 if (condition
& G_IO_IN
) {
1555 vnc_client_read(vs
);
1557 if (condition
& G_IO_OUT
) {
1558 vnc_client_write(vs
);
1564 void vnc_write(VncState
*vs
, const void *data
, size_t len
)
1566 buffer_reserve(&vs
->output
, len
);
1568 if (vs
->ioc
!= NULL
&& buffer_empty(&vs
->output
)) {
1570 g_source_remove(vs
->ioc_tag
);
1572 vs
->ioc_tag
= qio_channel_add_watch(
1573 vs
->ioc
, G_IO_IN
| G_IO_OUT
, vnc_client_io
, vs
, NULL
);
1576 buffer_append(&vs
->output
, data
, len
);
1579 void vnc_write_s32(VncState
*vs
, int32_t value
)
1581 vnc_write_u32(vs
, *(uint32_t *)&value
);
1584 void vnc_write_u32(VncState
*vs
, uint32_t value
)
1588 buf
[0] = (value
>> 24) & 0xFF;
1589 buf
[1] = (value
>> 16) & 0xFF;
1590 buf
[2] = (value
>> 8) & 0xFF;
1591 buf
[3] = value
& 0xFF;
1593 vnc_write(vs
, buf
, 4);
1596 void vnc_write_u16(VncState
*vs
, uint16_t value
)
1600 buf
[0] = (value
>> 8) & 0xFF;
1601 buf
[1] = value
& 0xFF;
1603 vnc_write(vs
, buf
, 2);
1606 void vnc_write_u8(VncState
*vs
, uint8_t value
)
1608 vnc_write(vs
, (char *)&value
, 1);
1611 void vnc_flush(VncState
*vs
)
1613 vnc_lock_output(vs
);
1614 if (vs
->ioc
!= NULL
&& (vs
->output
.offset
|| vs
->ws_output
.offset
)) {
1615 vnc_client_write_locked(vs
);
1617 vnc_unlock_output(vs
);
1620 static uint8_t read_u8(uint8_t *data
, size_t offset
)
1622 return data
[offset
];
1625 static uint16_t read_u16(uint8_t *data
, size_t offset
)
1627 return ((data
[offset
] & 0xFF) << 8) | (data
[offset
+ 1] & 0xFF);
1630 static int32_t read_s32(uint8_t *data
, size_t offset
)
1632 return (int32_t)((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1633 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1636 uint32_t read_u32(uint8_t *data
, size_t offset
)
1638 return ((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1639 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1642 static void client_cut_text(VncState
*vs
, size_t len
, uint8_t *text
)
1646 static void check_pointer_type_change(Notifier
*notifier
, void *data
)
1648 VncState
*vs
= container_of(notifier
, VncState
, mouse_mode_notifier
);
1649 int absolute
= qemu_input_is_absolute();
1651 if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
) && vs
->absolute
!= absolute
) {
1652 vnc_lock_output(vs
);
1653 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1654 vnc_write_u8(vs
, 0);
1655 vnc_write_u16(vs
, 1);
1656 vnc_framebuffer_update(vs
, absolute
, 0,
1657 pixman_image_get_width(vs
->vd
->server
),
1658 pixman_image_get_height(vs
->vd
->server
),
1659 VNC_ENCODING_POINTER_TYPE_CHANGE
);
1660 vnc_unlock_output(vs
);
1663 vs
->absolute
= absolute
;
1666 static void pointer_event(VncState
*vs
, int button_mask
, int x
, int y
)
1668 static uint32_t bmap
[INPUT_BUTTON__MAX
] = {
1669 [INPUT_BUTTON_LEFT
] = 0x01,
1670 [INPUT_BUTTON_MIDDLE
] = 0x02,
1671 [INPUT_BUTTON_RIGHT
] = 0x04,
1672 [INPUT_BUTTON_WHEELUP
] = 0x08,
1673 [INPUT_BUTTON_WHEELDOWN
] = 0x10,
1675 QemuConsole
*con
= vs
->vd
->dcl
.con
;
1676 int width
= pixman_image_get_width(vs
->vd
->server
);
1677 int height
= pixman_image_get_height(vs
->vd
->server
);
1679 if (vs
->last_bmask
!= button_mask
) {
1680 qemu_input_update_buttons(con
, bmap
, vs
->last_bmask
, button_mask
);
1681 vs
->last_bmask
= button_mask
;
1685 qemu_input_queue_abs(con
, INPUT_AXIS_X
, x
, width
);
1686 qemu_input_queue_abs(con
, INPUT_AXIS_Y
, y
, height
);
1687 } else if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
)) {
1688 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- 0x7FFF);
1689 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- 0x7FFF);
1691 if (vs
->last_x
!= -1) {
1692 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- vs
->last_x
);
1693 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- vs
->last_y
);
1698 qemu_input_event_sync();
1701 static void reset_keys(VncState
*vs
)
1704 for(i
= 0; i
< 256; i
++) {
1705 if (vs
->modifiers_state
[i
]) {
1706 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, i
, false);
1707 vs
->modifiers_state
[i
] = 0;
1712 static void press_key(VncState
*vs
, int keysym
)
1714 int keycode
= keysym2scancode(vs
->vd
->kbd_layout
, keysym
) & SCANCODE_KEYMASK
;
1715 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, true);
1716 qemu_input_event_send_key_delay(0);
1717 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1718 qemu_input_event_send_key_delay(0);
1721 static int current_led_state(VncState
*vs
)
1725 if (vs
->modifiers_state
[0x46]) {
1726 ledstate
|= QEMU_SCROLL_LOCK_LED
;
1728 if (vs
->modifiers_state
[0x45]) {
1729 ledstate
|= QEMU_NUM_LOCK_LED
;
1731 if (vs
->modifiers_state
[0x3a]) {
1732 ledstate
|= QEMU_CAPS_LOCK_LED
;
1738 static void vnc_led_state_change(VncState
*vs
)
1742 if (!vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
)) {
1746 ledstate
= current_led_state(vs
);
1747 vnc_lock_output(vs
);
1748 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1749 vnc_write_u8(vs
, 0);
1750 vnc_write_u16(vs
, 1);
1751 vnc_framebuffer_update(vs
, 0, 0, 1, 1, VNC_ENCODING_LED_STATE
);
1752 vnc_write_u8(vs
, ledstate
);
1753 vnc_unlock_output(vs
);
1757 static void kbd_leds(void *opaque
, int ledstate
)
1759 VncState
*vs
= opaque
;
1761 bool has_changed
= (ledstate
!= current_led_state(vs
));
1763 trace_vnc_key_guest_leds((ledstate
& QEMU_CAPS_LOCK_LED
),
1764 (ledstate
& QEMU_NUM_LOCK_LED
),
1765 (ledstate
& QEMU_SCROLL_LOCK_LED
));
1767 caps
= ledstate
& QEMU_CAPS_LOCK_LED
? 1 : 0;
1768 num
= ledstate
& QEMU_NUM_LOCK_LED
? 1 : 0;
1769 scr
= ledstate
& QEMU_SCROLL_LOCK_LED
? 1 : 0;
1771 if (vs
->modifiers_state
[0x3a] != caps
) {
1772 vs
->modifiers_state
[0x3a] = caps
;
1774 if (vs
->modifiers_state
[0x45] != num
) {
1775 vs
->modifiers_state
[0x45] = num
;
1777 if (vs
->modifiers_state
[0x46] != scr
) {
1778 vs
->modifiers_state
[0x46] = scr
;
1781 /* Sending the current led state message to the client */
1783 vnc_led_state_change(vs
);
1787 static void do_key_event(VncState
*vs
, int down
, int keycode
, int sym
)
1789 /* QEMU console switch */
1791 case 0x2a: /* Left Shift */
1792 case 0x36: /* Right Shift */
1793 case 0x1d: /* Left CTRL */
1794 case 0x9d: /* Right CTRL */
1795 case 0x38: /* Left ALT */
1796 case 0xb8: /* Right ALT */
1798 vs
->modifiers_state
[keycode
] = 1;
1800 vs
->modifiers_state
[keycode
] = 0;
1802 case 0x02 ... 0x0a: /* '1' to '9' keys */
1803 if (vs
->vd
->dcl
.con
== NULL
&&
1804 down
&& vs
->modifiers_state
[0x1d] && vs
->modifiers_state
[0x38]) {
1805 /* Reset the modifiers sent to the current console */
1807 console_select(keycode
- 0x02);
1811 case 0x3a: /* CapsLock */
1812 case 0x45: /* NumLock */
1814 vs
->modifiers_state
[keycode
] ^= 1;
1818 /* Turn off the lock state sync logic if the client support the led
1821 if (down
&& vs
->vd
->lock_key_sync
&&
1822 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1823 keycode_is_keypad(vs
->vd
->kbd_layout
, keycode
)) {
1824 /* If the numlock state needs to change then simulate an additional
1825 keypress before sending this one. This will happen if the user
1826 toggles numlock away from the VNC window.
1828 if (keysym_is_numlock(vs
->vd
->kbd_layout
, sym
& 0xFFFF)) {
1829 if (!vs
->modifiers_state
[0x45]) {
1830 trace_vnc_key_sync_numlock(true);
1831 vs
->modifiers_state
[0x45] = 1;
1832 press_key(vs
, 0xff7f);
1835 if (vs
->modifiers_state
[0x45]) {
1836 trace_vnc_key_sync_numlock(false);
1837 vs
->modifiers_state
[0x45] = 0;
1838 press_key(vs
, 0xff7f);
1843 if (down
&& vs
->vd
->lock_key_sync
&&
1844 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1845 ((sym
>= 'A' && sym
<= 'Z') || (sym
>= 'a' && sym
<= 'z'))) {
1846 /* If the capslock state needs to change then simulate an additional
1847 keypress before sending this one. This will happen if the user
1848 toggles capslock away from the VNC window.
1850 int uppercase
= !!(sym
>= 'A' && sym
<= 'Z');
1851 int shift
= !!(vs
->modifiers_state
[0x2a] | vs
->modifiers_state
[0x36]);
1852 int capslock
= !!(vs
->modifiers_state
[0x3a]);
1854 if (uppercase
== shift
) {
1855 trace_vnc_key_sync_capslock(false);
1856 vs
->modifiers_state
[0x3a] = 0;
1857 press_key(vs
, 0xffe5);
1860 if (uppercase
!= shift
) {
1861 trace_vnc_key_sync_capslock(true);
1862 vs
->modifiers_state
[0x3a] = 1;
1863 press_key(vs
, 0xffe5);
1868 if (qemu_console_is_graphic(NULL
)) {
1869 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, down
);
1871 bool numlock
= vs
->modifiers_state
[0x45];
1872 bool control
= (vs
->modifiers_state
[0x1d] ||
1873 vs
->modifiers_state
[0x9d]);
1874 /* QEMU console emulation */
1877 case 0x2a: /* Left Shift */
1878 case 0x36: /* Right Shift */
1879 case 0x1d: /* Left CTRL */
1880 case 0x9d: /* Right CTRL */
1881 case 0x38: /* Left ALT */
1882 case 0xb8: /* Right ALT */
1885 kbd_put_keysym(QEMU_KEY_UP
);
1888 kbd_put_keysym(QEMU_KEY_DOWN
);
1891 kbd_put_keysym(QEMU_KEY_LEFT
);
1894 kbd_put_keysym(QEMU_KEY_RIGHT
);
1897 kbd_put_keysym(QEMU_KEY_DELETE
);
1900 kbd_put_keysym(QEMU_KEY_HOME
);
1903 kbd_put_keysym(QEMU_KEY_END
);
1906 kbd_put_keysym(QEMU_KEY_PAGEUP
);
1909 kbd_put_keysym(QEMU_KEY_PAGEDOWN
);
1913 kbd_put_keysym(numlock
? '7' : QEMU_KEY_HOME
);
1916 kbd_put_keysym(numlock
? '8' : QEMU_KEY_UP
);
1919 kbd_put_keysym(numlock
? '9' : QEMU_KEY_PAGEUP
);
1922 kbd_put_keysym(numlock
? '4' : QEMU_KEY_LEFT
);
1925 kbd_put_keysym('5');
1928 kbd_put_keysym(numlock
? '6' : QEMU_KEY_RIGHT
);
1931 kbd_put_keysym(numlock
? '1' : QEMU_KEY_END
);
1934 kbd_put_keysym(numlock
? '2' : QEMU_KEY_DOWN
);
1937 kbd_put_keysym(numlock
? '3' : QEMU_KEY_PAGEDOWN
);
1940 kbd_put_keysym('0');
1943 kbd_put_keysym(numlock
? '.' : QEMU_KEY_DELETE
);
1947 kbd_put_keysym('/');
1950 kbd_put_keysym('*');
1953 kbd_put_keysym('-');
1956 kbd_put_keysym('+');
1959 kbd_put_keysym('\n');
1964 kbd_put_keysym(sym
& 0x1f);
1966 kbd_put_keysym(sym
);
1974 static void vnc_release_modifiers(VncState
*vs
)
1976 static const int keycodes
[] = {
1977 /* shift, control, alt keys, both left & right */
1978 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1982 if (!qemu_console_is_graphic(NULL
)) {
1985 for (i
= 0; i
< ARRAY_SIZE(keycodes
); i
++) {
1986 keycode
= keycodes
[i
];
1987 if (!vs
->modifiers_state
[keycode
]) {
1990 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1994 static const char *code2name(int keycode
)
1996 return QKeyCode_lookup
[qemu_input_key_number_to_qcode(keycode
)];
1999 static void key_event(VncState
*vs
, int down
, uint32_t sym
)
2004 if (lsym
>= 'A' && lsym
<= 'Z' && qemu_console_is_graphic(NULL
)) {
2005 lsym
= lsym
- 'A' + 'a';
2008 keycode
= keysym2scancode(vs
->vd
->kbd_layout
, lsym
& 0xFFFF) & SCANCODE_KEYMASK
;
2009 trace_vnc_key_event_map(down
, sym
, keycode
, code2name(keycode
));
2010 do_key_event(vs
, down
, keycode
, sym
);
2013 static void ext_key_event(VncState
*vs
, int down
,
2014 uint32_t sym
, uint16_t keycode
)
2016 /* if the user specifies a keyboard layout, always use it */
2017 if (keyboard_layout
) {
2018 key_event(vs
, down
, sym
);
2020 trace_vnc_key_event_ext(down
, sym
, keycode
, code2name(keycode
));
2021 do_key_event(vs
, down
, keycode
, sym
);
2025 static void framebuffer_update_request(VncState
*vs
, int incremental
,
2026 int x
, int y
, int w
, int h
)
2028 vs
->need_update
= 1;
2034 vs
->force_update
= 1;
2035 vnc_set_area_dirty(vs
->dirty
, vs
->vd
, x
, y
, w
, h
);
2038 static void send_ext_key_event_ack(VncState
*vs
)
2040 vnc_lock_output(vs
);
2041 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2042 vnc_write_u8(vs
, 0);
2043 vnc_write_u16(vs
, 1);
2044 vnc_framebuffer_update(vs
, 0, 0,
2045 pixman_image_get_width(vs
->vd
->server
),
2046 pixman_image_get_height(vs
->vd
->server
),
2047 VNC_ENCODING_EXT_KEY_EVENT
);
2048 vnc_unlock_output(vs
);
2052 static void send_ext_audio_ack(VncState
*vs
)
2054 vnc_lock_output(vs
);
2055 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2056 vnc_write_u8(vs
, 0);
2057 vnc_write_u16(vs
, 1);
2058 vnc_framebuffer_update(vs
, 0, 0,
2059 pixman_image_get_width(vs
->vd
->server
),
2060 pixman_image_get_height(vs
->vd
->server
),
2061 VNC_ENCODING_AUDIO
);
2062 vnc_unlock_output(vs
);
2066 static void set_encodings(VncState
*vs
, int32_t *encodings
, size_t n_encodings
)
2069 unsigned int enc
= 0;
2072 vs
->vnc_encoding
= 0;
2073 vs
->tight
.compression
= 9;
2074 vs
->tight
.quality
= -1; /* Lossless by default */
2078 * Start from the end because the encodings are sent in order of preference.
2079 * This way the preferred encoding (first encoding defined in the array)
2080 * will be set at the end of the loop.
2082 for (i
= n_encodings
- 1; i
>= 0; i
--) {
2085 case VNC_ENCODING_RAW
:
2086 vs
->vnc_encoding
= enc
;
2088 case VNC_ENCODING_COPYRECT
:
2089 vs
->features
|= VNC_FEATURE_COPYRECT_MASK
;
2091 case VNC_ENCODING_HEXTILE
:
2092 vs
->features
|= VNC_FEATURE_HEXTILE_MASK
;
2093 vs
->vnc_encoding
= enc
;
2095 case VNC_ENCODING_TIGHT
:
2096 vs
->features
|= VNC_FEATURE_TIGHT_MASK
;
2097 vs
->vnc_encoding
= enc
;
2099 #ifdef CONFIG_VNC_PNG
2100 case VNC_ENCODING_TIGHT_PNG
:
2101 vs
->features
|= VNC_FEATURE_TIGHT_PNG_MASK
;
2102 vs
->vnc_encoding
= enc
;
2105 case VNC_ENCODING_ZLIB
:
2106 vs
->features
|= VNC_FEATURE_ZLIB_MASK
;
2107 vs
->vnc_encoding
= enc
;
2109 case VNC_ENCODING_ZRLE
:
2110 vs
->features
|= VNC_FEATURE_ZRLE_MASK
;
2111 vs
->vnc_encoding
= enc
;
2113 case VNC_ENCODING_ZYWRLE
:
2114 vs
->features
|= VNC_FEATURE_ZYWRLE_MASK
;
2115 vs
->vnc_encoding
= enc
;
2117 case VNC_ENCODING_DESKTOPRESIZE
:
2118 vs
->features
|= VNC_FEATURE_RESIZE_MASK
;
2120 case VNC_ENCODING_POINTER_TYPE_CHANGE
:
2121 vs
->features
|= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK
;
2123 case VNC_ENCODING_RICH_CURSOR
:
2124 vs
->features
|= VNC_FEATURE_RICH_CURSOR_MASK
;
2126 case VNC_ENCODING_EXT_KEY_EVENT
:
2127 send_ext_key_event_ack(vs
);
2129 case VNC_ENCODING_AUDIO
:
2130 send_ext_audio_ack(vs
);
2132 case VNC_ENCODING_WMVi
:
2133 vs
->features
|= VNC_FEATURE_WMVI_MASK
;
2135 case VNC_ENCODING_LED_STATE
:
2136 vs
->features
|= VNC_FEATURE_LED_STATE_MASK
;
2138 case VNC_ENCODING_COMPRESSLEVEL0
... VNC_ENCODING_COMPRESSLEVEL0
+ 9:
2139 vs
->tight
.compression
= (enc
& 0x0F);
2141 case VNC_ENCODING_QUALITYLEVEL0
... VNC_ENCODING_QUALITYLEVEL0
+ 9:
2142 if (vs
->vd
->lossy
) {
2143 vs
->tight
.quality
= (enc
& 0x0F);
2147 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i
, enc
, enc
);
2151 vnc_desktop_resize(vs
);
2152 check_pointer_type_change(&vs
->mouse_mode_notifier
, NULL
);
2153 vnc_led_state_change(vs
);
2156 static void set_pixel_conversion(VncState
*vs
)
2158 pixman_format_code_t fmt
= qemu_pixman_get_format(&vs
->client_pf
);
2160 if (fmt
== VNC_SERVER_FB_FORMAT
) {
2161 vs
->write_pixels
= vnc_write_pixels_copy
;
2162 vnc_hextile_set_pixel_conversion(vs
, 0);
2164 vs
->write_pixels
= vnc_write_pixels_generic
;
2165 vnc_hextile_set_pixel_conversion(vs
, 1);
2169 static void set_pixel_format(VncState
*vs
,
2170 int bits_per_pixel
, int depth
,
2171 int big_endian_flag
, int true_color_flag
,
2172 int red_max
, int green_max
, int blue_max
,
2173 int red_shift
, int green_shift
, int blue_shift
)
2175 if (!true_color_flag
) {
2176 vnc_client_error(vs
);
2180 switch (bits_per_pixel
) {
2186 vnc_client_error(vs
);
2190 vs
->client_pf
.rmax
= red_max
? red_max
: 0xFF;
2191 vs
->client_pf
.rbits
= hweight_long(red_max
);
2192 vs
->client_pf
.rshift
= red_shift
;
2193 vs
->client_pf
.rmask
= red_max
<< red_shift
;
2194 vs
->client_pf
.gmax
= green_max
? green_max
: 0xFF;
2195 vs
->client_pf
.gbits
= hweight_long(green_max
);
2196 vs
->client_pf
.gshift
= green_shift
;
2197 vs
->client_pf
.gmask
= green_max
<< green_shift
;
2198 vs
->client_pf
.bmax
= blue_max
? blue_max
: 0xFF;
2199 vs
->client_pf
.bbits
= hweight_long(blue_max
);
2200 vs
->client_pf
.bshift
= blue_shift
;
2201 vs
->client_pf
.bmask
= blue_max
<< blue_shift
;
2202 vs
->client_pf
.bits_per_pixel
= bits_per_pixel
;
2203 vs
->client_pf
.bytes_per_pixel
= bits_per_pixel
/ 8;
2204 vs
->client_pf
.depth
= bits_per_pixel
== 32 ? 24 : bits_per_pixel
;
2205 vs
->client_be
= big_endian_flag
;
2207 set_pixel_conversion(vs
);
2209 graphic_hw_invalidate(vs
->vd
->dcl
.con
);
2210 graphic_hw_update(vs
->vd
->dcl
.con
);
2213 static void pixel_format_message (VncState
*vs
) {
2214 char pad
[3] = { 0, 0, 0 };
2216 vs
->client_pf
= qemu_default_pixelformat(32);
2218 vnc_write_u8(vs
, vs
->client_pf
.bits_per_pixel
); /* bits-per-pixel */
2219 vnc_write_u8(vs
, vs
->client_pf
.depth
); /* depth */
2221 #ifdef HOST_WORDS_BIGENDIAN
2222 vnc_write_u8(vs
, 1); /* big-endian-flag */
2224 vnc_write_u8(vs
, 0); /* big-endian-flag */
2226 vnc_write_u8(vs
, 1); /* true-color-flag */
2227 vnc_write_u16(vs
, vs
->client_pf
.rmax
); /* red-max */
2228 vnc_write_u16(vs
, vs
->client_pf
.gmax
); /* green-max */
2229 vnc_write_u16(vs
, vs
->client_pf
.bmax
); /* blue-max */
2230 vnc_write_u8(vs
, vs
->client_pf
.rshift
); /* red-shift */
2231 vnc_write_u8(vs
, vs
->client_pf
.gshift
); /* green-shift */
2232 vnc_write_u8(vs
, vs
->client_pf
.bshift
); /* blue-shift */
2233 vnc_write(vs
, pad
, 3); /* padding */
2235 vnc_hextile_set_pixel_conversion(vs
, 0);
2236 vs
->write_pixels
= vnc_write_pixels_copy
;
2239 static void vnc_colordepth(VncState
*vs
)
2241 if (vnc_has_feature(vs
, VNC_FEATURE_WMVI
)) {
2242 /* Sending a WMVi message to notify the client*/
2243 vnc_lock_output(vs
);
2244 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2245 vnc_write_u8(vs
, 0);
2246 vnc_write_u16(vs
, 1); /* number of rects */
2247 vnc_framebuffer_update(vs
, 0, 0,
2248 pixman_image_get_width(vs
->vd
->server
),
2249 pixman_image_get_height(vs
->vd
->server
),
2251 pixel_format_message(vs
);
2252 vnc_unlock_output(vs
);
2255 set_pixel_conversion(vs
);
2259 static int protocol_client_msg(VncState
*vs
, uint8_t *data
, size_t len
)
2263 VncDisplay
*vd
= vs
->vd
;
2266 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2270 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT
:
2274 set_pixel_format(vs
, read_u8(data
, 4), read_u8(data
, 5),
2275 read_u8(data
, 6), read_u8(data
, 7),
2276 read_u16(data
, 8), read_u16(data
, 10),
2277 read_u16(data
, 12), read_u8(data
, 14),
2278 read_u8(data
, 15), read_u8(data
, 16));
2280 case VNC_MSG_CLIENT_SET_ENCODINGS
:
2285 limit
= read_u16(data
, 2);
2287 return 4 + (limit
* 4);
2289 limit
= read_u16(data
, 2);
2291 for (i
= 0; i
< limit
; i
++) {
2292 int32_t val
= read_s32(data
, 4 + (i
* 4));
2293 memcpy(data
+ 4 + (i
* 4), &val
, sizeof(val
));
2296 set_encodings(vs
, (int32_t *)(data
+ 4), limit
);
2298 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST
:
2302 framebuffer_update_request(vs
,
2303 read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4),
2304 read_u16(data
, 6), read_u16(data
, 8));
2306 case VNC_MSG_CLIENT_KEY_EVENT
:
2310 key_event(vs
, read_u8(data
, 1), read_u32(data
, 4));
2312 case VNC_MSG_CLIENT_POINTER_EVENT
:
2316 pointer_event(vs
, read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4));
2318 case VNC_MSG_CLIENT_CUT_TEXT
:
2323 uint32_t dlen
= read_u32(data
, 4);
2324 if (dlen
> (1 << 20)) {
2325 error_report("vnc: client_cut_text msg payload has %u bytes"
2326 " which exceeds our limit of 1MB.", dlen
);
2327 vnc_client_error(vs
);
2335 client_cut_text(vs
, read_u32(data
, 4), data
+ 8);
2337 case VNC_MSG_CLIENT_QEMU
:
2341 switch (read_u8(data
, 1)) {
2342 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT
:
2346 ext_key_event(vs
, read_u16(data
, 2),
2347 read_u32(data
, 4), read_u32(data
, 8));
2349 case VNC_MSG_CLIENT_QEMU_AUDIO
:
2353 switch (read_u16 (data
, 2)) {
2354 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE
:
2357 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE
:
2360 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT
:
2363 switch (read_u8(data
, 4)) {
2364 case 0: vs
->as
.fmt
= AUD_FMT_U8
; break;
2365 case 1: vs
->as
.fmt
= AUD_FMT_S8
; break;
2366 case 2: vs
->as
.fmt
= AUD_FMT_U16
; break;
2367 case 3: vs
->as
.fmt
= AUD_FMT_S16
; break;
2368 case 4: vs
->as
.fmt
= AUD_FMT_U32
; break;
2369 case 5: vs
->as
.fmt
= AUD_FMT_S32
; break;
2371 VNC_DEBUG("Invalid audio format %d\n", read_u8(data
, 4));
2372 vnc_client_error(vs
);
2375 vs
->as
.nchannels
= read_u8(data
, 5);
2376 if (vs
->as
.nchannels
!= 1 && vs
->as
.nchannels
!= 2) {
2377 VNC_DEBUG("Invalid audio channel coount %d\n",
2379 vnc_client_error(vs
);
2382 vs
->as
.freq
= read_u32(data
, 6);
2385 VNC_DEBUG("Invalid audio message %d\n", read_u8(data
, 4));
2386 vnc_client_error(vs
);
2392 VNC_DEBUG("Msg: %d\n", read_u16(data
, 0));
2393 vnc_client_error(vs
);
2398 VNC_DEBUG("Msg: %d\n", data
[0]);
2399 vnc_client_error(vs
);
2403 vnc_read_when(vs
, protocol_client_msg
, 1);
2407 static int protocol_client_init(VncState
*vs
, uint8_t *data
, size_t len
)
2413 mode
= data
[0] ? VNC_SHARE_MODE_SHARED
: VNC_SHARE_MODE_EXCLUSIVE
;
2414 switch (vs
->vd
->share_policy
) {
2415 case VNC_SHARE_POLICY_IGNORE
:
2417 * Ignore the shared flag. Nothing to do here.
2419 * Doesn't conform to the rfb spec but is traditional qemu
2420 * behavior, thus left here as option for compatibility
2424 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
:
2426 * Policy: Allow clients ask for exclusive access.
2428 * Implementation: When a client asks for exclusive access,
2429 * disconnect all others. Shared connects are allowed as long
2430 * as no exclusive connection exists.
2432 * This is how the rfb spec suggests to handle the shared flag.
2434 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2436 QTAILQ_FOREACH(client
, &vs
->vd
->clients
, next
) {
2440 if (client
->share_mode
!= VNC_SHARE_MODE_EXCLUSIVE
&&
2441 client
->share_mode
!= VNC_SHARE_MODE_SHARED
) {
2444 vnc_disconnect_start(client
);
2447 if (mode
== VNC_SHARE_MODE_SHARED
) {
2448 if (vs
->vd
->num_exclusive
> 0) {
2449 vnc_disconnect_start(vs
);
2454 case VNC_SHARE_POLICY_FORCE_SHARED
:
2456 * Policy: Shared connects only.
2457 * Implementation: Disallow clients asking for exclusive access.
2459 * Useful for shared desktop sessions where you don't want
2460 * someone forgetting to say -shared when running the vnc
2461 * client disconnect everybody else.
2463 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2464 vnc_disconnect_start(vs
);
2469 vnc_set_share_mode(vs
, mode
);
2471 if (vs
->vd
->num_shared
> vs
->vd
->connections_limit
) {
2472 vnc_disconnect_start(vs
);
2476 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
2477 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
2478 vnc_write_u16(vs
, vs
->client_width
);
2479 vnc_write_u16(vs
, vs
->client_height
);
2481 pixel_format_message(vs
);
2484 size
= snprintf(buf
, sizeof(buf
), "QEMU (%s)", qemu_name
);
2486 size
= snprintf(buf
, sizeof(buf
), "QEMU");
2488 vnc_write_u32(vs
, size
);
2489 vnc_write(vs
, buf
, size
);
2492 vnc_client_cache_auth(vs
);
2493 vnc_qmp_event(vs
, QAPI_EVENT_VNC_INITIALIZED
);
2495 vnc_read_when(vs
, protocol_client_msg
, 1);
2500 void start_client_init(VncState
*vs
)
2502 vnc_read_when(vs
, protocol_client_init
, 1);
2505 static void make_challenge(VncState
*vs
)
2509 srand(time(NULL
)+getpid()+getpid()*987654+rand());
2511 for (i
= 0 ; i
< sizeof(vs
->challenge
) ; i
++)
2512 vs
->challenge
[i
] = (int) (256.0*rand()/(RAND_MAX
+1.0));
2515 static int protocol_client_auth_vnc(VncState
*vs
, uint8_t *data
, size_t len
)
2517 unsigned char response
[VNC_AUTH_CHALLENGE_SIZE
];
2519 unsigned char key
[8];
2520 time_t now
= time(NULL
);
2521 QCryptoCipher
*cipher
= NULL
;
2524 if (!vs
->vd
->password
) {
2525 VNC_DEBUG("No password configured on server");
2528 if (vs
->vd
->expires
< now
) {
2529 VNC_DEBUG("Password is expired");
2533 memcpy(response
, vs
->challenge
, VNC_AUTH_CHALLENGE_SIZE
);
2535 /* Calculate the expected challenge response */
2536 pwlen
= strlen(vs
->vd
->password
);
2537 for (i
=0; i
<sizeof(key
); i
++)
2538 key
[i
] = i
<pwlen
? vs
->vd
->password
[i
] : 0;
2540 cipher
= qcrypto_cipher_new(
2541 QCRYPTO_CIPHER_ALG_DES_RFB
,
2542 QCRYPTO_CIPHER_MODE_ECB
,
2543 key
, G_N_ELEMENTS(key
),
2546 VNC_DEBUG("Cannot initialize cipher %s",
2547 error_get_pretty(err
));
2552 if (qcrypto_cipher_encrypt(cipher
,
2555 VNC_AUTH_CHALLENGE_SIZE
,
2557 VNC_DEBUG("Cannot encrypt challenge %s",
2558 error_get_pretty(err
));
2563 /* Compare expected vs actual challenge response */
2564 if (memcmp(response
, data
, VNC_AUTH_CHALLENGE_SIZE
) != 0) {
2565 VNC_DEBUG("Client challenge response did not match\n");
2568 VNC_DEBUG("Accepting VNC challenge response\n");
2569 vnc_write_u32(vs
, 0); /* Accept auth */
2572 start_client_init(vs
);
2575 qcrypto_cipher_free(cipher
);
2579 vnc_write_u32(vs
, 1); /* Reject auth */
2580 if (vs
->minor
>= 8) {
2581 static const char err
[] = "Authentication failed";
2582 vnc_write_u32(vs
, sizeof(err
));
2583 vnc_write(vs
, err
, sizeof(err
));
2586 vnc_client_error(vs
);
2587 qcrypto_cipher_free(cipher
);
2591 void start_auth_vnc(VncState
*vs
)
2594 /* Send client a 'random' challenge */
2595 vnc_write(vs
, vs
->challenge
, sizeof(vs
->challenge
));
2598 vnc_read_when(vs
, protocol_client_auth_vnc
, sizeof(vs
->challenge
));
2602 static int protocol_client_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2604 /* We only advertise 1 auth scheme at a time, so client
2605 * must pick the one we sent. Verify this */
2606 if (data
[0] != vs
->auth
) { /* Reject auth */
2607 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data
[0]);
2608 vnc_write_u32(vs
, 1);
2609 if (vs
->minor
>= 8) {
2610 static const char err
[] = "Authentication failed";
2611 vnc_write_u32(vs
, sizeof(err
));
2612 vnc_write(vs
, err
, sizeof(err
));
2614 vnc_client_error(vs
);
2615 } else { /* Accept requested auth */
2616 VNC_DEBUG("Client requested auth %d\n", (int)data
[0]);
2619 VNC_DEBUG("Accept auth none\n");
2620 if (vs
->minor
>= 8) {
2621 vnc_write_u32(vs
, 0); /* Accept auth completion */
2624 start_client_init(vs
);
2628 VNC_DEBUG("Start VNC auth\n");
2632 case VNC_AUTH_VENCRYPT
:
2633 VNC_DEBUG("Accept VeNCrypt auth\n");
2634 start_auth_vencrypt(vs
);
2637 #ifdef CONFIG_VNC_SASL
2639 VNC_DEBUG("Accept SASL auth\n");
2640 start_auth_sasl(vs
);
2642 #endif /* CONFIG_VNC_SASL */
2644 default: /* Should not be possible, but just in case */
2645 VNC_DEBUG("Reject auth %d server code bug\n", vs
->auth
);
2646 vnc_write_u8(vs
, 1);
2647 if (vs
->minor
>= 8) {
2648 static const char err
[] = "Authentication failed";
2649 vnc_write_u32(vs
, sizeof(err
));
2650 vnc_write(vs
, err
, sizeof(err
));
2652 vnc_client_error(vs
);
2658 static int protocol_version(VncState
*vs
, uint8_t *version
, size_t len
)
2662 memcpy(local
, version
, 12);
2665 if (sscanf(local
, "RFB %03d.%03d\n", &vs
->major
, &vs
->minor
) != 2) {
2666 VNC_DEBUG("Malformed protocol version %s\n", local
);
2667 vnc_client_error(vs
);
2670 VNC_DEBUG("Client request protocol version %d.%d\n", vs
->major
, vs
->minor
);
2671 if (vs
->major
!= 3 ||
2677 VNC_DEBUG("Unsupported client version\n");
2678 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2680 vnc_client_error(vs
);
2683 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2684 * as equivalent to v3.3 by servers
2686 if (vs
->minor
== 4 || vs
->minor
== 5)
2689 if (vs
->minor
== 3) {
2690 if (vs
->auth
== VNC_AUTH_NONE
) {
2691 VNC_DEBUG("Tell client auth none\n");
2692 vnc_write_u32(vs
, vs
->auth
);
2694 start_client_init(vs
);
2695 } else if (vs
->auth
== VNC_AUTH_VNC
) {
2696 VNC_DEBUG("Tell client VNC auth\n");
2697 vnc_write_u32(vs
, vs
->auth
);
2701 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs
->auth
);
2702 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2704 vnc_client_error(vs
);
2707 VNC_DEBUG("Telling client we support auth %d\n", vs
->auth
);
2708 vnc_write_u8(vs
, 1); /* num auth */
2709 vnc_write_u8(vs
, vs
->auth
);
2710 vnc_read_when(vs
, protocol_client_auth
, 1);
2717 static VncRectStat
*vnc_stat_rect(VncDisplay
*vd
, int x
, int y
)
2719 struct VncSurface
*vs
= &vd
->guest
;
2721 return &vs
->stats
[y
/ VNC_STAT_RECT
][x
/ VNC_STAT_RECT
];
2724 void vnc_sent_lossy_rect(VncState
*vs
, int x
, int y
, int w
, int h
)
2728 w
= (x
+ w
) / VNC_STAT_RECT
;
2729 h
= (y
+ h
) / VNC_STAT_RECT
;
2733 for (j
= y
; j
<= h
; j
++) {
2734 for (i
= x
; i
<= w
; i
++) {
2735 vs
->lossy_rect
[j
][i
] = 1;
2740 static int vnc_refresh_lossy_rect(VncDisplay
*vd
, int x
, int y
)
2743 int sty
= y
/ VNC_STAT_RECT
;
2744 int stx
= x
/ VNC_STAT_RECT
;
2747 y
= y
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2748 x
= x
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2750 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2753 /* kernel send buffers are full -> refresh later */
2754 if (vs
->output
.offset
) {
2758 if (!vs
->lossy_rect
[sty
][stx
]) {
2762 vs
->lossy_rect
[sty
][stx
] = 0;
2763 for (j
= 0; j
< VNC_STAT_RECT
; ++j
) {
2764 bitmap_set(vs
->dirty
[y
+ j
],
2765 x
/ VNC_DIRTY_PIXELS_PER_BIT
,
2766 VNC_STAT_RECT
/ VNC_DIRTY_PIXELS_PER_BIT
);
2774 static int vnc_update_stats(VncDisplay
*vd
, struct timeval
* tv
)
2776 int width
= pixman_image_get_width(vd
->guest
.fb
);
2777 int height
= pixman_image_get_height(vd
->guest
.fb
);
2782 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2783 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2784 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2786 rect
->updated
= false;
2790 qemu_timersub(tv
, &VNC_REFRESH_STATS
, &res
);
2792 if (timercmp(&vd
->guest
.last_freq_check
, &res
, >)) {
2795 vd
->guest
.last_freq_check
= *tv
;
2797 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2798 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2799 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2800 int count
= ARRAY_SIZE(rect
->times
);
2801 struct timeval min
, max
;
2803 if (!timerisset(&rect
->times
[count
- 1])) {
2807 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2808 qemu_timersub(tv
, &max
, &res
);
2810 if (timercmp(&res
, &VNC_REFRESH_LOSSY
, >)) {
2812 has_dirty
+= vnc_refresh_lossy_rect(vd
, x
, y
);
2813 memset(rect
->times
, 0, sizeof (rect
->times
));
2817 min
= rect
->times
[rect
->idx
];
2818 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2819 qemu_timersub(&max
, &min
, &res
);
2821 rect
->freq
= res
.tv_sec
+ res
.tv_usec
/ 1000000.;
2822 rect
->freq
/= count
;
2823 rect
->freq
= 1. / rect
->freq
;
2829 double vnc_update_freq(VncState
*vs
, int x
, int y
, int w
, int h
)
2835 x
= (x
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2836 y
= (y
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2838 for (j
= y
; j
<= y
+ h
; j
+= VNC_STAT_RECT
) {
2839 for (i
= x
; i
<= x
+ w
; i
+= VNC_STAT_RECT
) {
2840 total
+= vnc_stat_rect(vs
->vd
, i
, j
)->freq
;
2852 static void vnc_rect_updated(VncDisplay
*vd
, int x
, int y
, struct timeval
* tv
)
2856 rect
= vnc_stat_rect(vd
, x
, y
);
2857 if (rect
->updated
) {
2860 rect
->times
[rect
->idx
] = *tv
;
2861 rect
->idx
= (rect
->idx
+ 1) % ARRAY_SIZE(rect
->times
);
2862 rect
->updated
= true;
2865 static int vnc_refresh_server_surface(VncDisplay
*vd
)
2867 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2868 pixman_image_get_width(vd
->server
));
2869 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2870 pixman_image_get_height(vd
->server
));
2871 int cmp_bytes
, server_stride
, line_bytes
, guest_ll
, guest_stride
, y
= 0;
2872 uint8_t *guest_row0
= NULL
, *server_row0
;
2875 pixman_image_t
*tmpbuf
= NULL
;
2877 struct timeval tv
= { 0, 0 };
2879 if (!vd
->non_adaptive
) {
2880 gettimeofday(&tv
, NULL
);
2881 has_dirty
= vnc_update_stats(vd
, &tv
);
2885 * Walk through the guest dirty map.
2886 * Check and copy modified bits from guest to server surface.
2887 * Update server dirty map.
2889 server_row0
= (uint8_t *)pixman_image_get_data(vd
->server
);
2890 server_stride
= guest_stride
= guest_ll
=
2891 pixman_image_get_stride(vd
->server
);
2892 cmp_bytes
= MIN(VNC_DIRTY_PIXELS_PER_BIT
* VNC_SERVER_FB_BYTES
,
2894 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2895 int width
= pixman_image_get_width(vd
->server
);
2896 tmpbuf
= qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT
, width
);
2899 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd
->guest
.fb
));
2900 guest_row0
= (uint8_t *)pixman_image_get_data(vd
->guest
.fb
);
2901 guest_stride
= pixman_image_get_stride(vd
->guest
.fb
);
2902 guest_ll
= pixman_image_get_width(vd
->guest
.fb
) * ((guest_bpp
+ 7) / 8);
2904 line_bytes
= MIN(server_stride
, guest_ll
);
2908 uint8_t *guest_ptr
, *server_ptr
;
2909 unsigned long offset
= find_next_bit((unsigned long *) &vd
->guest
.dirty
,
2910 height
* VNC_DIRTY_BPL(&vd
->guest
),
2911 y
* VNC_DIRTY_BPL(&vd
->guest
));
2912 if (offset
== height
* VNC_DIRTY_BPL(&vd
->guest
)) {
2913 /* no more dirty bits */
2916 y
= offset
/ VNC_DIRTY_BPL(&vd
->guest
);
2917 x
= offset
% VNC_DIRTY_BPL(&vd
->guest
);
2919 server_ptr
= server_row0
+ y
* server_stride
+ x
* cmp_bytes
;
2921 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2922 qemu_pixman_linebuf_fill(tmpbuf
, vd
->guest
.fb
, width
, 0, y
);
2923 guest_ptr
= (uint8_t *)pixman_image_get_data(tmpbuf
);
2925 guest_ptr
= guest_row0
+ y
* guest_stride
;
2927 guest_ptr
+= x
* cmp_bytes
;
2929 for (; x
< DIV_ROUND_UP(width
, VNC_DIRTY_PIXELS_PER_BIT
);
2930 x
++, guest_ptr
+= cmp_bytes
, server_ptr
+= cmp_bytes
) {
2931 int _cmp_bytes
= cmp_bytes
;
2932 if (!test_and_clear_bit(x
, vd
->guest
.dirty
[y
])) {
2935 if ((x
+ 1) * cmp_bytes
> line_bytes
) {
2936 _cmp_bytes
= line_bytes
- x
* cmp_bytes
;
2938 assert(_cmp_bytes
>= 0);
2939 if (memcmp(server_ptr
, guest_ptr
, _cmp_bytes
) == 0) {
2942 memcpy(server_ptr
, guest_ptr
, _cmp_bytes
);
2943 if (!vd
->non_adaptive
) {
2944 vnc_rect_updated(vd
, x
* VNC_DIRTY_PIXELS_PER_BIT
,
2947 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2948 set_bit(x
, vs
->dirty
[y
]);
2955 qemu_pixman_image_unref(tmpbuf
);
2959 static void vnc_refresh(DisplayChangeListener
*dcl
)
2961 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
2963 int has_dirty
, rects
= 0;
2965 if (QTAILQ_EMPTY(&vd
->clients
)) {
2966 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_MAX
);
2970 graphic_hw_update(vd
->dcl
.con
);
2972 if (vnc_trylock_display(vd
)) {
2973 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2977 has_dirty
= vnc_refresh_server_surface(vd
);
2978 vnc_unlock_display(vd
);
2980 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
2981 rects
+= vnc_update_client(vs
, has_dirty
, false);
2982 /* vs might be free()ed here */
2985 if (has_dirty
&& rects
) {
2986 vd
->dcl
.update_interval
/= 2;
2987 if (vd
->dcl
.update_interval
< VNC_REFRESH_INTERVAL_BASE
) {
2988 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_BASE
;
2991 vd
->dcl
.update_interval
+= VNC_REFRESH_INTERVAL_INC
;
2992 if (vd
->dcl
.update_interval
> VNC_REFRESH_INTERVAL_MAX
) {
2993 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_MAX
;
2998 static void vnc_connect(VncDisplay
*vd
, QIOChannelSocket
*sioc
,
2999 bool skipauth
, bool websocket
)
3001 VncState
*vs
= g_new0(VncState
, 1);
3005 object_ref(OBJECT(vs
->sioc
));
3006 vs
->ioc
= QIO_CHANNEL(sioc
);
3007 object_ref(OBJECT(vs
->ioc
));
3010 buffer_init(&vs
->input
, "vnc-input/%p", sioc
);
3011 buffer_init(&vs
->output
, "vnc-output/%p", sioc
);
3012 buffer_init(&vs
->ws_input
, "vnc-ws_input/%p", sioc
);
3013 buffer_init(&vs
->ws_output
, "vnc-ws_output/%p", sioc
);
3014 buffer_init(&vs
->jobs_buffer
, "vnc-jobs_buffer/%p", sioc
);
3016 buffer_init(&vs
->tight
.tight
, "vnc-tight/%p", sioc
);
3017 buffer_init(&vs
->tight
.zlib
, "vnc-tight-zlib/%p", sioc
);
3018 buffer_init(&vs
->tight
.gradient
, "vnc-tight-gradient/%p", sioc
);
3019 #ifdef CONFIG_VNC_JPEG
3020 buffer_init(&vs
->tight
.jpeg
, "vnc-tight-jpeg/%p", sioc
);
3022 #ifdef CONFIG_VNC_PNG
3023 buffer_init(&vs
->tight
.png
, "vnc-tight-png/%p", sioc
);
3025 buffer_init(&vs
->zlib
.zlib
, "vnc-zlib/%p", sioc
);
3026 buffer_init(&vs
->zrle
.zrle
, "vnc-zrle/%p", sioc
);
3027 buffer_init(&vs
->zrle
.fb
, "vnc-zrle-fb/%p", sioc
);
3028 buffer_init(&vs
->zrle
.zlib
, "vnc-zrle-zlib/%p", sioc
);
3031 vs
->auth
= VNC_AUTH_NONE
;
3032 vs
->subauth
= VNC_AUTH_INVALID
;
3035 vs
->auth
= vd
->ws_auth
;
3036 vs
->subauth
= VNC_AUTH_INVALID
;
3038 vs
->auth
= vd
->auth
;
3039 vs
->subauth
= vd
->subauth
;
3042 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
3043 sioc
, websocket
, vs
->auth
, vs
->subauth
);
3045 vs
->lossy_rect
= g_malloc0(VNC_STAT_ROWS
* sizeof (*vs
->lossy_rect
));
3046 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
3047 vs
->lossy_rect
[i
] = g_new0(uint8_t, VNC_STAT_COLS
);
3050 VNC_DEBUG("New client on socket %p\n", vs
->sioc
);
3051 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
3052 qio_channel_set_blocking(vs
->ioc
, false, NULL
);
3056 vs
->ioc_tag
= qio_channel_add_watch(
3057 vs
->ioc
, G_IO_IN
, vncws_tls_handshake_io
, vs
, NULL
);
3059 vs
->ioc_tag
= qio_channel_add_watch(
3060 vs
->ioc
, G_IO_IN
, vncws_handshake_io
, vs
, NULL
);
3063 vs
->ioc_tag
= qio_channel_add_watch(
3064 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
3067 vnc_client_cache_addr(vs
);
3068 vnc_qmp_event(vs
, QAPI_EVENT_VNC_CONNECTED
);
3069 vnc_set_share_mode(vs
, VNC_SHARE_MODE_CONNECTING
);
3071 if (!vs
->websocket
) {
3075 if (vd
->num_connecting
> vd
->connections_limit
) {
3076 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
3077 if (vs
->share_mode
== VNC_SHARE_MODE_CONNECTING
) {
3078 vnc_disconnect_start(vs
);
3085 void vnc_init_state(VncState
*vs
)
3087 vs
->initialized
= true;
3088 VncDisplay
*vd
= vs
->vd
;
3089 bool first_client
= QTAILQ_EMPTY(&vd
->clients
);
3094 vs
->as
.freq
= 44100;
3095 vs
->as
.nchannels
= 2;
3096 vs
->as
.fmt
= AUD_FMT_S16
;
3097 vs
->as
.endianness
= 0;
3099 qemu_mutex_init(&vs
->output_mutex
);
3100 vs
->bh
= qemu_bh_new(vnc_jobs_bh
, vs
);
3102 QTAILQ_INSERT_TAIL(&vd
->clients
, vs
, next
);
3104 vnc_update_server_surface(vd
);
3107 graphic_hw_update(vd
->dcl
.con
);
3109 vnc_write(vs
, "RFB 003.008\n", 12);
3111 vnc_read_when(vs
, protocol_version
, 12);
3113 if (vs
->vd
->lock_key_sync
)
3114 vs
->led
= qemu_add_led_event_handler(kbd_leds
, vs
);
3116 vs
->mouse_mode_notifier
.notify
= check_pointer_type_change
;
3117 qemu_add_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
3119 /* vs might be free()ed here */
3122 static gboolean
vnc_listen_io(QIOChannel
*ioc
,
3123 GIOCondition condition
,
3126 VncDisplay
*vs
= opaque
;
3127 QIOChannelSocket
*sioc
= NULL
;
3131 graphic_hw_update(vs
->dcl
.con
);
3132 sioc
= qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc
), &err
);
3134 qio_channel_set_delay(QIO_CHANNEL(sioc
), false);
3135 vnc_connect(vs
, sioc
, false,
3136 ioc
!= QIO_CHANNEL(vs
->lsock
));
3137 object_unref(OBJECT(sioc
));
3139 /* client probably closed connection before we got there */
3146 static const DisplayChangeListenerOps dcl_ops
= {
3148 .dpy_refresh
= vnc_refresh
,
3149 .dpy_gfx_copy
= vnc_dpy_copy
,
3150 .dpy_gfx_update
= vnc_dpy_update
,
3151 .dpy_gfx_switch
= vnc_dpy_switch
,
3152 .dpy_gfx_check_format
= qemu_pixman_check_format
,
3153 .dpy_mouse_set
= vnc_mouse_set
,
3154 .dpy_cursor_define
= vnc_dpy_cursor_define
,
3157 void vnc_display_init(const char *id
)
3161 if (vnc_display_find(id
) != NULL
) {
3164 vs
= g_malloc0(sizeof(*vs
));
3166 vs
->id
= strdup(id
);
3167 QTAILQ_INSERT_TAIL(&vnc_displays
, vs
, next
);
3169 QTAILQ_INIT(&vs
->clients
);
3170 vs
->expires
= TIME_MAX
;
3172 if (keyboard_layout
) {
3173 trace_vnc_key_map_init(keyboard_layout
);
3174 vs
->kbd_layout
= init_keyboard_layout(name2keysym
, keyboard_layout
);
3176 vs
->kbd_layout
= init_keyboard_layout(name2keysym
, "en-us");
3179 if (!vs
->kbd_layout
)
3182 qemu_mutex_init(&vs
->mutex
);
3183 vnc_start_worker_thread();
3185 vs
->dcl
.ops
= &dcl_ops
;
3186 register_displaychangelistener(&vs
->dcl
);
3190 static void vnc_display_close(VncDisplay
*vs
)
3194 vs
->enabled
= false;
3195 vs
->is_unix
= false;
3196 if (vs
->lsock
!= NULL
) {
3197 if (vs
->lsock_tag
) {
3198 g_source_remove(vs
->lsock_tag
);
3200 object_unref(OBJECT(vs
->lsock
));
3203 vs
->ws_enabled
= false;
3204 if (vs
->lwebsock
!= NULL
) {
3205 if (vs
->lwebsock_tag
) {
3206 g_source_remove(vs
->lwebsock_tag
);
3208 object_unref(OBJECT(vs
->lwebsock
));
3209 vs
->lwebsock
= NULL
;
3211 vs
->auth
= VNC_AUTH_INVALID
;
3212 vs
->subauth
= VNC_AUTH_INVALID
;
3214 object_unparent(OBJECT(vs
->tlscreds
));
3216 g_free(vs
->tlsaclname
);
3217 vs
->tlsaclname
= NULL
;
3220 int vnc_display_password(const char *id
, const char *password
)
3222 VncDisplay
*vs
= vnc_display_find(id
);
3227 if (vs
->auth
== VNC_AUTH_NONE
) {
3228 error_printf_unless_qmp("If you want use passwords please enable "
3229 "password auth using '-vnc ${dpy},password'.");
3233 g_free(vs
->password
);
3234 vs
->password
= g_strdup(password
);
3239 int vnc_display_pw_expire(const char *id
, time_t expires
)
3241 VncDisplay
*vs
= vnc_display_find(id
);
3247 vs
->expires
= expires
;
3251 char *vnc_display_local_addr(const char *id
)
3253 VncDisplay
*vs
= vnc_display_find(id
);
3254 SocketAddress
*addr
;
3260 addr
= qio_channel_socket_get_local_address(vs
->lsock
, &err
);
3265 if (addr
->type
!= SOCKET_ADDRESS_KIND_INET
) {
3266 qapi_free_SocketAddress(addr
);
3269 ret
= g_strdup_printf("%s;%s", addr
->u
.inet
->host
, addr
->u
.inet
->port
);
3270 qapi_free_SocketAddress(addr
);
3275 static QemuOptsList qemu_vnc_opts
= {
3277 .head
= QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts
.head
),
3278 .implied_opt_name
= "vnc",
3282 .type
= QEMU_OPT_STRING
,
3284 .name
= "websocket",
3285 .type
= QEMU_OPT_STRING
,
3287 .name
= "tls-creds",
3288 .type
= QEMU_OPT_STRING
,
3290 /* Deprecated in favour of tls-creds */
3292 .type
= QEMU_OPT_STRING
,
3295 .type
= QEMU_OPT_STRING
,
3298 .type
= QEMU_OPT_STRING
,
3301 .type
= QEMU_OPT_NUMBER
,
3303 .name
= "connections",
3304 .type
= QEMU_OPT_NUMBER
,
3307 .type
= QEMU_OPT_NUMBER
,
3310 .type
= QEMU_OPT_BOOL
,
3313 .type
= QEMU_OPT_BOOL
,
3316 .type
= QEMU_OPT_BOOL
,
3319 .type
= QEMU_OPT_BOOL
,
3321 .name
= "lock-key-sync",
3322 .type
= QEMU_OPT_BOOL
,
3325 .type
= QEMU_OPT_BOOL
,
3327 /* Deprecated in favour of tls-creds */
3329 .type
= QEMU_OPT_BOOL
,
3331 /* Deprecated in favour of tls-creds */
3332 .name
= "x509verify",
3333 .type
= QEMU_OPT_STRING
,
3336 .type
= QEMU_OPT_BOOL
,
3339 .type
= QEMU_OPT_BOOL
,
3341 .name
= "non-adaptive",
3342 .type
= QEMU_OPT_BOOL
,
3344 { /* end of list */ }
3350 vnc_display_setup_auth(VncDisplay
*vs
,
3357 * We have a choice of 3 authentication options
3363 * The channel can be run in 2 modes
3368 * And TLS can use 2 types of credentials
3373 * We thus have 9 possible logical combinations
3378 * 4. tls + anon + none
3379 * 5. tls + anon + vnc
3380 * 6. tls + anon + sasl
3381 * 7. tls + x509 + none
3382 * 8. tls + x509 + vnc
3383 * 9. tls + x509 + sasl
3385 * These need to be mapped into the VNC auth schemes
3386 * in an appropriate manner. In regular VNC, all the
3387 * TLS options get mapped into VNC_AUTH_VENCRYPT
3390 * In websockets, the https:// protocol already provides
3391 * TLS support, so there is no need to make use of the
3392 * VeNCrypt extension. Furthermore, websockets browser
3393 * clients could not use VeNCrypt even if they wanted to,
3394 * as they cannot control when the TLS handshake takes
3395 * place. Thus there is no option but to rely on https://,
3396 * meaning combinations 4->6 and 7->9 will be mapped to
3397 * VNC auth schemes in the same way as combos 1->3.
3399 * Regardless of fact that we have a different mapping to
3400 * VNC auth mechs for plain VNC vs websockets VNC, the end
3401 * result has the same security characteristics.
3405 vs
->auth
= VNC_AUTH_VENCRYPT
;
3409 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3410 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3411 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3412 vs
->subauth
= VNC_AUTH_VENCRYPT_X509VNC
;
3413 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3414 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3415 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3416 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSVNC
;
3419 "Unsupported TLS cred type %s",
3420 object_get_typename(OBJECT(vs
->tlscreds
)));
3424 VNC_DEBUG("Initializing VNC server with password auth\n");
3425 vs
->auth
= VNC_AUTH_VNC
;
3426 vs
->subauth
= VNC_AUTH_INVALID
;
3429 vs
->ws_auth
= VNC_AUTH_VNC
;
3431 vs
->ws_auth
= VNC_AUTH_INVALID
;
3435 vs
->auth
= VNC_AUTH_VENCRYPT
;
3439 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3440 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3441 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3442 vs
->subauth
= VNC_AUTH_VENCRYPT_X509SASL
;
3443 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3444 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3445 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3446 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSSASL
;
3449 "Unsupported TLS cred type %s",
3450 object_get_typename(OBJECT(vs
->tlscreds
)));
3454 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3455 vs
->auth
= VNC_AUTH_SASL
;
3456 vs
->subauth
= VNC_AUTH_INVALID
;
3459 vs
->ws_auth
= VNC_AUTH_SASL
;
3461 vs
->ws_auth
= VNC_AUTH_INVALID
;
3465 vs
->auth
= VNC_AUTH_VENCRYPT
;
3469 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3470 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3471 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3472 vs
->subauth
= VNC_AUTH_VENCRYPT_X509NONE
;
3473 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3474 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3475 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3476 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSNONE
;
3479 "Unsupported TLS cred type %s",
3480 object_get_typename(OBJECT(vs
->tlscreds
)));
3484 VNC_DEBUG("Initializing VNC server with no auth\n");
3485 vs
->auth
= VNC_AUTH_NONE
;
3486 vs
->subauth
= VNC_AUTH_INVALID
;
3489 vs
->ws_auth
= VNC_AUTH_NONE
;
3491 vs
->ws_auth
= VNC_AUTH_INVALID
;
3499 * Handle back compat with old CLI syntax by creating some
3500 * suitable QCryptoTLSCreds objects
3502 static QCryptoTLSCreds
*
3503 vnc_display_create_creds(bool x509
,
3509 gchar
*credsid
= g_strdup_printf("tlsvnc%s", id
);
3510 Object
*parent
= object_get_objects_root();
3515 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509
,
3519 "endpoint", "server",
3521 "verify-peer", x509verify
? "yes" : "no",
3524 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON
,
3528 "endpoint", "server",
3535 error_propagate(errp
, err
);
3539 return QCRYPTO_TLS_CREDS(creds
);
3543 void vnc_display_open(const char *id
, Error
**errp
)
3545 VncDisplay
*vs
= vnc_display_find(id
);
3546 QemuOpts
*opts
= qemu_opts_find(&qemu_vnc_opts
, id
);
3547 SocketAddress
*saddr
= NULL
, *wsaddr
= NULL
;
3548 const char *share
, *device_id
;
3550 bool password
= false;
3551 bool reverse
= false;
3556 #ifdef CONFIG_VNC_SASL
3560 int lock_key_sync
= 1;
3563 error_setg(errp
, "VNC display not active");
3566 vnc_display_close(vs
);
3571 vnc
= qemu_opt_get(opts
, "vnc");
3572 if (!vnc
|| strcmp(vnc
, "none") == 0) {
3576 h
= strrchr(vnc
, ':');
3578 size_t hlen
= h
- vnc
;
3580 const char *websocket
= qemu_opt_get(opts
, "websocket");
3581 int to
= qemu_opt_get_number(opts
, "to", 0);
3582 bool has_ipv4
= qemu_opt_get_bool(opts
, "ipv4", false);
3583 bool has_ipv6
= qemu_opt_get_bool(opts
, "ipv6", false);
3585 saddr
= g_new0(SocketAddress
, 1);
3587 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1
)) {
3589 "SHA1 hash support is required for websockets");
3593 wsaddr
= g_new0(SocketAddress
, 1);
3594 vs
->ws_enabled
= true;
3597 if (strncmp(vnc
, "unix:", 5) == 0) {
3598 saddr
->type
= SOCKET_ADDRESS_KIND_UNIX
;
3599 saddr
->u
.q_unix
= g_new0(UnixSocketAddress
, 1);
3600 saddr
->u
.q_unix
->path
= g_strdup(vnc
+ 5);
3602 if (vs
->ws_enabled
) {
3603 error_setg(errp
, "UNIX sockets not supported with websock");
3607 unsigned long long baseport
;
3608 saddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3609 saddr
->u
.inet
= g_new0(InetSocketAddress
, 1);
3610 if (vnc
[0] == '[' && vnc
[hlen
- 1] == ']') {
3611 saddr
->u
.inet
->host
= g_strndup(vnc
+ 1, hlen
- 2);
3613 saddr
->u
.inet
->host
= g_strndup(vnc
, hlen
);
3615 if (parse_uint_full(h
+ 1, &baseport
, 10) < 0) {
3616 error_setg(errp
, "can't convert to a number: %s", h
+ 1);
3619 if (baseport
> 65535 ||
3620 baseport
+ 5900 > 65535) {
3621 error_setg(errp
, "port %s out of range", h
+ 1);
3624 saddr
->u
.inet
->port
= g_strdup_printf(
3625 "%d", (int)baseport
+ 5900);
3628 saddr
->u
.inet
->has_to
= true;
3629 saddr
->u
.inet
->to
= to
+ 5900;
3631 saddr
->u
.inet
->ipv4
= saddr
->u
.inet
->has_ipv4
= has_ipv4
;
3632 saddr
->u
.inet
->ipv6
= saddr
->u
.inet
->has_ipv6
= has_ipv6
;
3634 if (vs
->ws_enabled
) {
3635 wsaddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3636 wsaddr
->u
.inet
= g_new0(InetSocketAddress
, 1);
3637 wsaddr
->u
.inet
->host
= g_strdup(saddr
->u
.inet
->host
);
3638 wsaddr
->u
.inet
->port
= g_strdup(websocket
);
3641 wsaddr
->u
.inet
->has_to
= true;
3642 wsaddr
->u
.inet
->to
= to
;
3644 wsaddr
->u
.inet
->ipv4
= wsaddr
->u
.inet
->has_ipv4
= has_ipv4
;
3645 wsaddr
->u
.inet
->ipv6
= wsaddr
->u
.inet
->has_ipv6
= has_ipv6
;
3649 error_setg(errp
, "no vnc port specified");
3653 password
= qemu_opt_get_bool(opts
, "password", false);
3655 if (fips_get_state()) {
3657 "VNC password auth disabled due to FIPS mode, "
3658 "consider using the VeNCrypt or SASL authentication "
3659 "methods as an alternative");
3662 if (!qcrypto_cipher_supports(
3663 QCRYPTO_CIPHER_ALG_DES_RFB
)) {
3665 "Cipher backend does not support DES RFB algorithm");
3670 reverse
= qemu_opt_get_bool(opts
, "reverse", false);
3671 lock_key_sync
= qemu_opt_get_bool(opts
, "lock-key-sync", true);
3672 sasl
= qemu_opt_get_bool(opts
, "sasl", false);
3673 #ifndef CONFIG_VNC_SASL
3675 error_setg(errp
, "VNC SASL auth requires cyrus-sasl support");
3678 #endif /* CONFIG_VNC_SASL */
3679 credid
= qemu_opt_get(opts
, "tls-creds");
3682 if (qemu_opt_get(opts
, "tls") ||
3683 qemu_opt_get(opts
, "x509") ||
3684 qemu_opt_get(opts
, "x509verify")) {
3686 "'credid' parameter is mutually exclusive with "
3687 "'tls', 'x509' and 'x509verify' parameters");
3691 creds
= object_resolve_path_component(
3692 object_get_objects_root(), credid
);
3694 error_setg(errp
, "No TLS credentials with id '%s'",
3698 vs
->tlscreds
= (QCryptoTLSCreds
*)
3699 object_dynamic_cast(creds
,
3700 TYPE_QCRYPTO_TLS_CREDS
);
3701 if (!vs
->tlscreds
) {
3702 error_setg(errp
, "Object with id '%s' is not TLS credentials",
3706 object_ref(OBJECT(vs
->tlscreds
));
3708 if (vs
->tlscreds
->endpoint
!= QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
) {
3710 "Expecting TLS credentials with a server endpoint");
3715 bool tls
= false, x509
= false, x509verify
= false;
3716 tls
= qemu_opt_get_bool(opts
, "tls", false);
3718 path
= qemu_opt_get(opts
, "x509");
3723 path
= qemu_opt_get(opts
, "x509verify");
3729 vs
->tlscreds
= vnc_display_create_creds(x509
,
3734 if (!vs
->tlscreds
) {
3739 acl
= qemu_opt_get_bool(opts
, "acl", false);
3741 share
= qemu_opt_get(opts
, "share");
3743 if (strcmp(share
, "ignore") == 0) {
3744 vs
->share_policy
= VNC_SHARE_POLICY_IGNORE
;
3745 } else if (strcmp(share
, "allow-exclusive") == 0) {
3746 vs
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3747 } else if (strcmp(share
, "force-shared") == 0) {
3748 vs
->share_policy
= VNC_SHARE_POLICY_FORCE_SHARED
;
3750 error_setg(errp
, "unknown vnc share= option");
3754 vs
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3756 vs
->connections_limit
= qemu_opt_get_number(opts
, "connections", 32);
3758 #ifdef CONFIG_VNC_JPEG
3759 vs
->lossy
= qemu_opt_get_bool(opts
, "lossy", false);
3761 vs
->non_adaptive
= qemu_opt_get_bool(opts
, "non-adaptive", false);
3762 /* adaptive updates are only used with tight encoding and
3763 * if lossy updates are enabled so we can disable all the
3764 * calculations otherwise */
3766 vs
->non_adaptive
= true;
3770 if (strcmp(vs
->id
, "default") == 0) {
3771 vs
->tlsaclname
= g_strdup("vnc.x509dname");
3773 vs
->tlsaclname
= g_strdup_printf("vnc.%s.x509dname", vs
->id
);
3775 qemu_acl_init(vs
->tlsaclname
);
3777 #ifdef CONFIG_VNC_SASL
3781 if (strcmp(vs
->id
, "default") == 0) {
3782 aclname
= g_strdup("vnc.username");
3784 aclname
= g_strdup_printf("vnc.%s.username", vs
->id
);
3786 vs
->sasl
.acl
= qemu_acl_init(aclname
);
3791 if (vnc_display_setup_auth(vs
, password
, sasl
, vs
->ws_enabled
, errp
) < 0) {
3795 #ifdef CONFIG_VNC_SASL
3796 if ((saslErr
= sasl_server_init(NULL
, "qemu")) != SASL_OK
) {
3797 error_setg(errp
, "Failed to initialize SASL auth: %s",
3798 sasl_errstring(saslErr
, NULL
, NULL
));
3802 vs
->lock_key_sync
= lock_key_sync
;
3804 device_id
= qemu_opt_get(opts
, "display");
3807 int head
= qemu_opt_get_number(opts
, "head", 0);
3809 dev
= qdev_find_recursive(sysbus_get_default(), device_id
);
3811 error_setg(errp
, "Device '%s' not found", device_id
);
3815 con
= qemu_console_lookup_by_device(dev
, head
);
3817 error_setg(errp
, "Device %s is not bound to a QemuConsole",
3825 if (con
!= vs
->dcl
.con
) {
3826 unregister_displaychangelistener(&vs
->dcl
);
3828 register_displaychangelistener(&vs
->dcl
);
3832 /* connect to viewer */
3833 QIOChannelSocket
*sioc
= NULL
;
3835 vs
->lwebsock
= NULL
;
3836 if (vs
->ws_enabled
) {
3837 error_setg(errp
, "Cannot use websockets in reverse mode");
3840 vs
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3841 sioc
= qio_channel_socket_new();
3842 if (qio_channel_socket_connect_sync(sioc
, saddr
, errp
) < 0) {
3845 vnc_connect(vs
, sioc
, false, false);
3846 object_unref(OBJECT(sioc
));
3848 vs
->lsock
= qio_channel_socket_new();
3849 if (qio_channel_socket_listen_sync(vs
->lsock
, saddr
, errp
) < 0) {
3852 vs
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3855 if (vs
->ws_enabled
) {
3856 vs
->lwebsock
= qio_channel_socket_new();
3857 if (qio_channel_socket_listen_sync(vs
->lwebsock
,
3858 wsaddr
, errp
) < 0) {
3859 object_unref(OBJECT(vs
->lsock
));
3865 vs
->lsock_tag
= qio_channel_add_watch(
3866 QIO_CHANNEL(vs
->lsock
),
3867 G_IO_IN
, vnc_listen_io
, vs
, NULL
);
3868 if (vs
->ws_enabled
) {
3869 vs
->lwebsock_tag
= qio_channel_add_watch(
3870 QIO_CHANNEL(vs
->lwebsock
),
3871 G_IO_IN
, vnc_listen_io
, vs
, NULL
);
3875 qapi_free_SocketAddress(saddr
);
3876 qapi_free_SocketAddress(wsaddr
);
3880 qapi_free_SocketAddress(saddr
);
3881 qapi_free_SocketAddress(wsaddr
);
3882 vs
->enabled
= false;
3883 vs
->ws_enabled
= false;
3886 void vnc_display_add_client(const char *id
, int csock
, bool skipauth
)
3888 VncDisplay
*vs
= vnc_display_find(id
);
3889 QIOChannelSocket
*sioc
;
3895 sioc
= qio_channel_socket_new_fd(csock
, NULL
);
3897 vnc_connect(vs
, sioc
, skipauth
, false);
3898 object_unref(OBJECT(sioc
));
3902 static void vnc_auto_assign_id(QemuOptsList
*olist
, QemuOpts
*opts
)
3907 id
= g_strdup("default");
3908 while (qemu_opts_find(olist
, id
)) {
3910 id
= g_strdup_printf("vnc%d", i
++);
3912 qemu_opts_set_id(opts
, id
);
3915 QemuOpts
*vnc_parse(const char *str
, Error
**errp
)
3917 QemuOptsList
*olist
= qemu_find_opts("vnc");
3918 QemuOpts
*opts
= qemu_opts_parse(olist
, str
, true, errp
);
3925 id
= qemu_opts_id(opts
);
3927 /* auto-assign id if not present */
3928 vnc_auto_assign_id(olist
, opts
);
3933 int vnc_init_func(void *opaque
, QemuOpts
*opts
, Error
**errp
)
3935 Error
*local_err
= NULL
;
3936 char *id
= (char *)qemu_opts_id(opts
);
3939 vnc_display_init(id
);
3940 vnc_display_open(id
, &local_err
);
3941 if (local_err
!= NULL
) {
3942 error_report("Failed to start VNC server: %s",
3943 error_get_pretty(local_err
));
3944 error_free(local_err
);
3950 static void vnc_register_config(void)
3952 qemu_add_opts(&qemu_vnc_opts
);
3954 machine_init(vnc_register_config
);