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/%d: %s -> %s\n", __func__
,
74 vs
->csock
, 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
++;
108 static char *addr_to_string(const char *format
,
109 struct sockaddr_storage
*sa
,
112 char host
[NI_MAXHOST
];
113 char serv
[NI_MAXSERV
];
117 if ((err
= getnameinfo((struct sockaddr
*)sa
, salen
,
120 NI_NUMERICHOST
| NI_NUMERICSERV
)) != 0) {
121 VNC_DEBUG("Cannot resolve address %d: %s\n",
122 err
, gai_strerror(err
));
126 /* Enough for the existing format + the 2 vars we're
127 * substituting in. */
128 addrlen
= strlen(format
) + strlen(host
) + strlen(serv
);
129 addr
= g_malloc(addrlen
+ 1);
130 snprintf(addr
, addrlen
, format
, host
, serv
);
131 addr
[addrlen
] = '\0';
137 char *vnc_socket_local_addr(const char *format
, int fd
) {
138 struct sockaddr_storage sa
;
142 if (getsockname(fd
, (struct sockaddr
*)&sa
, &salen
) < 0)
145 return addr_to_string(format
, &sa
, salen
);
148 char *vnc_socket_remote_addr(const char *format
, int fd
) {
149 struct sockaddr_storage sa
;
153 if (getpeername(fd
, (struct sockaddr
*)&sa
, &salen
) < 0)
156 return addr_to_string(format
, &sa
, salen
);
159 static void vnc_init_basic_info(struct sockaddr_storage
*sa
,
164 char host
[NI_MAXHOST
];
165 char serv
[NI_MAXSERV
];
168 if ((err
= getnameinfo((struct sockaddr
*)sa
, salen
,
171 NI_NUMERICHOST
| NI_NUMERICSERV
)) != 0) {
172 error_setg(errp
, "Cannot resolve address: %s",
177 info
->host
= g_strdup(host
);
178 info
->service
= g_strdup(serv
);
179 info
->family
= inet_netfamily(sa
->ss_family
);
182 static void vnc_init_basic_info_from_server_addr(int fd
, VncBasicInfo
*info
,
185 struct sockaddr_storage sa
;
189 if (getsockname(fd
, (struct sockaddr
*)&sa
, &salen
) < 0) {
190 error_setg_errno(errp
, errno
, "getsockname failed");
194 vnc_init_basic_info(&sa
, salen
, info
, errp
);
197 static void vnc_init_basic_info_from_remote_addr(int fd
, VncBasicInfo
*info
,
200 struct sockaddr_storage sa
;
204 if (getpeername(fd
, (struct sockaddr
*)&sa
, &salen
) < 0) {
205 error_setg_errno(errp
, errno
, "getpeername failed");
209 vnc_init_basic_info(&sa
, salen
, info
, errp
);
212 static const char *vnc_auth_name(VncDisplay
*vd
) {
214 case VNC_AUTH_INVALID
:
230 case VNC_AUTH_VENCRYPT
:
231 switch (vd
->subauth
) {
232 case VNC_AUTH_VENCRYPT_PLAIN
:
233 return "vencrypt+plain";
234 case VNC_AUTH_VENCRYPT_TLSNONE
:
235 return "vencrypt+tls+none";
236 case VNC_AUTH_VENCRYPT_TLSVNC
:
237 return "vencrypt+tls+vnc";
238 case VNC_AUTH_VENCRYPT_TLSPLAIN
:
239 return "vencrypt+tls+plain";
240 case VNC_AUTH_VENCRYPT_X509NONE
:
241 return "vencrypt+x509+none";
242 case VNC_AUTH_VENCRYPT_X509VNC
:
243 return "vencrypt+x509+vnc";
244 case VNC_AUTH_VENCRYPT_X509PLAIN
:
245 return "vencrypt+x509+plain";
246 case VNC_AUTH_VENCRYPT_TLSSASL
:
247 return "vencrypt+tls+sasl";
248 case VNC_AUTH_VENCRYPT_X509SASL
:
249 return "vencrypt+x509+sasl";
259 static VncServerInfo
*vnc_server_info_get(VncDisplay
*vd
)
264 info
= g_malloc(sizeof(*info
));
265 vnc_init_basic_info_from_server_addr(vd
->lsock
,
266 qapi_VncServerInfo_base(info
), &err
);
267 info
->has_auth
= true;
268 info
->auth
= g_strdup(vnc_auth_name(vd
));
270 qapi_free_VncServerInfo(info
);
277 static void vnc_client_cache_auth(VncState
*client
)
284 client
->info
->x509_dname
=
285 qcrypto_tls_session_get_peer_name(client
->tls
);
286 client
->info
->has_x509_dname
=
287 client
->info
->x509_dname
!= NULL
;
289 #ifdef CONFIG_VNC_SASL
290 if (client
->sasl
.conn
&&
291 client
->sasl
.username
) {
292 client
->info
->has_sasl_username
= true;
293 client
->info
->sasl_username
= g_strdup(client
->sasl
.username
);
298 static void vnc_client_cache_addr(VncState
*client
)
302 client
->info
= g_malloc0(sizeof(*client
->info
));
303 vnc_init_basic_info_from_remote_addr(client
->csock
,
304 qapi_VncClientInfo_base(client
->info
),
307 qapi_free_VncClientInfo(client
->info
);
313 static void vnc_qmp_event(VncState
*vs
, QAPIEvent event
)
321 si
= vnc_server_info_get(vs
->vd
);
327 case QAPI_EVENT_VNC_CONNECTED
:
328 qapi_event_send_vnc_connected(si
, qapi_VncClientInfo_base(vs
->info
),
331 case QAPI_EVENT_VNC_INITIALIZED
:
332 qapi_event_send_vnc_initialized(si
, vs
->info
, &error_abort
);
334 case QAPI_EVENT_VNC_DISCONNECTED
:
335 qapi_event_send_vnc_disconnected(si
, vs
->info
, &error_abort
);
341 qapi_free_VncServerInfo(si
);
344 static VncClientInfo
*qmp_query_vnc_client(const VncState
*client
)
346 struct sockaddr_storage sa
;
347 socklen_t salen
= sizeof(sa
);
348 char host
[NI_MAXHOST
];
349 char serv
[NI_MAXSERV
];
352 if (getpeername(client
->csock
, (struct sockaddr
*)&sa
, &salen
) < 0) {
356 if (getnameinfo((struct sockaddr
*)&sa
, salen
,
359 NI_NUMERICHOST
| NI_NUMERICSERV
) < 0) {
363 info
= g_malloc0(sizeof(*info
));
364 info
->host
= g_strdup(host
);
365 info
->service
= g_strdup(serv
);
366 info
->family
= inet_netfamily(sa
.ss_family
);
367 info
->websocket
= client
->websocket
;
370 info
->x509_dname
= qcrypto_tls_session_get_peer_name(client
->tls
);
371 info
->has_x509_dname
= info
->x509_dname
!= NULL
;
373 #ifdef CONFIG_VNC_SASL
374 if (client
->sasl
.conn
&& client
->sasl
.username
) {
375 info
->has_sasl_username
= true;
376 info
->sasl_username
= g_strdup(client
->sasl
.username
);
383 static VncDisplay
*vnc_display_find(const char *id
)
388 return QTAILQ_FIRST(&vnc_displays
);
390 QTAILQ_FOREACH(vd
, &vnc_displays
, next
) {
391 if (strcmp(id
, vd
->id
) == 0) {
398 static VncClientInfoList
*qmp_query_client_list(VncDisplay
*vd
)
400 VncClientInfoList
*cinfo
, *prev
= NULL
;
403 QTAILQ_FOREACH(client
, &vd
->clients
, next
) {
404 cinfo
= g_new0(VncClientInfoList
, 1);
405 cinfo
->value
= qmp_query_vnc_client(client
);
412 VncInfo
*qmp_query_vnc(Error
**errp
)
414 VncInfo
*info
= g_malloc0(sizeof(*info
));
415 VncDisplay
*vd
= vnc_display_find(NULL
);
417 if (vd
== NULL
|| !vd
->enabled
) {
418 info
->enabled
= false;
420 struct sockaddr_storage sa
;
421 socklen_t salen
= sizeof(sa
);
422 char host
[NI_MAXHOST
];
423 char serv
[NI_MAXSERV
];
425 info
->enabled
= true;
427 /* for compatibility with the original command */
428 info
->has_clients
= true;
429 info
->clients
= qmp_query_client_list(vd
);
431 if (vd
->lsock
== -1) {
435 if (getsockname(vd
->lsock
, (struct sockaddr
*)&sa
,
437 error_setg(errp
, QERR_UNDEFINED_ERROR
);
441 if (getnameinfo((struct sockaddr
*)&sa
, salen
,
444 NI_NUMERICHOST
| NI_NUMERICSERV
) < 0) {
445 error_setg(errp
, QERR_UNDEFINED_ERROR
);
449 info
->has_host
= true;
450 info
->host
= g_strdup(host
);
452 info
->has_service
= true;
453 info
->service
= g_strdup(serv
);
455 info
->has_family
= true;
456 info
->family
= inet_netfamily(sa
.ss_family
);
458 info
->has_auth
= true;
459 info
->auth
= g_strdup(vnc_auth_name(vd
));
465 qapi_free_VncInfo(info
);
469 static VncBasicInfoList
*qmp_query_server_entry(int socket
,
471 VncBasicInfoList
*prev
)
473 VncBasicInfoList
*list
;
475 struct sockaddr_storage sa
;
476 socklen_t salen
= sizeof(sa
);
477 char host
[NI_MAXHOST
];
478 char serv
[NI_MAXSERV
];
480 if (getsockname(socket
, (struct sockaddr
*)&sa
, &salen
) < 0 ||
481 getnameinfo((struct sockaddr
*)&sa
, salen
,
482 host
, sizeof(host
), serv
, sizeof(serv
),
483 NI_NUMERICHOST
| NI_NUMERICSERV
) < 0) {
487 info
= g_new0(VncBasicInfo
, 1);
488 info
->host
= g_strdup(host
);
489 info
->service
= g_strdup(serv
);
490 info
->family
= inet_netfamily(sa
.ss_family
);
491 info
->websocket
= websocket
;
493 list
= g_new0(VncBasicInfoList
, 1);
499 static void qmp_query_auth(VncDisplay
*vd
, VncInfo2
*info
)
503 info
->auth
= VNC_PRIMARY_AUTH_VNC
;
506 info
->auth
= VNC_PRIMARY_AUTH_RA2
;
509 info
->auth
= VNC_PRIMARY_AUTH_RA2NE
;
512 info
->auth
= VNC_PRIMARY_AUTH_TIGHT
;
515 info
->auth
= VNC_PRIMARY_AUTH_ULTRA
;
518 info
->auth
= VNC_PRIMARY_AUTH_TLS
;
520 case VNC_AUTH_VENCRYPT
:
521 info
->auth
= VNC_PRIMARY_AUTH_VENCRYPT
;
522 info
->has_vencrypt
= true;
523 switch (vd
->subauth
) {
524 case VNC_AUTH_VENCRYPT_PLAIN
:
525 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_PLAIN
;
527 case VNC_AUTH_VENCRYPT_TLSNONE
:
528 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_NONE
;
530 case VNC_AUTH_VENCRYPT_TLSVNC
:
531 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_VNC
;
533 case VNC_AUTH_VENCRYPT_TLSPLAIN
:
534 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN
;
536 case VNC_AUTH_VENCRYPT_X509NONE
:
537 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_NONE
;
539 case VNC_AUTH_VENCRYPT_X509VNC
:
540 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_VNC
;
542 case VNC_AUTH_VENCRYPT_X509PLAIN
:
543 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_PLAIN
;
545 case VNC_AUTH_VENCRYPT_TLSSASL
:
546 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_SASL
;
548 case VNC_AUTH_VENCRYPT_X509SASL
:
549 info
->vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_SASL
;
552 info
->has_vencrypt
= false;
557 info
->auth
= VNC_PRIMARY_AUTH_SASL
;
561 info
->auth
= VNC_PRIMARY_AUTH_NONE
;
566 VncInfo2List
*qmp_query_vnc_servers(Error
**errp
)
568 VncInfo2List
*item
, *prev
= NULL
;
573 QTAILQ_FOREACH(vd
, &vnc_displays
, next
) {
574 info
= g_new0(VncInfo2
, 1);
575 info
->id
= g_strdup(vd
->id
);
576 info
->clients
= qmp_query_client_list(vd
);
577 qmp_query_auth(vd
, info
);
579 dev
= DEVICE(object_property_get_link(OBJECT(vd
->dcl
.con
),
581 info
->has_display
= true;
582 info
->display
= g_strdup(dev
->id
);
584 if (vd
->lsock
!= -1) {
585 info
->server
= qmp_query_server_entry(vd
->lsock
, false,
588 if (vd
->lwebsock
!= -1) {
589 info
->server
= qmp_query_server_entry(vd
->lwebsock
, true,
593 item
= g_new0(VncInfo2List
, 1);
602 1) Get the queue working for IO.
603 2) there is some weirdness when using the -S option (the screen is grey
604 and not totally invalidated
605 3) resolutions > 1024
608 static int vnc_update_client(VncState
*vs
, int has_dirty
, bool sync
);
609 static void vnc_disconnect_start(VncState
*vs
);
611 static void vnc_colordepth(VncState
*vs
);
612 static void framebuffer_update_request(VncState
*vs
, int incremental
,
613 int x_position
, int y_position
,
615 static void vnc_refresh(DisplayChangeListener
*dcl
);
616 static int vnc_refresh_server_surface(VncDisplay
*vd
);
618 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty
[VNC_MAX_HEIGHT
],
619 VNC_MAX_WIDTH
/ VNC_DIRTY_PIXELS_PER_BIT
),
620 int width
, int height
,
621 int x
, int y
, int w
, int h
) {
622 /* this is needed this to ensure we updated all affected
623 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
624 w
+= (x
% VNC_DIRTY_PIXELS_PER_BIT
);
625 x
-= (x
% VNC_DIRTY_PIXELS_PER_BIT
);
629 w
= MIN(x
+ w
, width
) - x
;
630 h
= MIN(y
+ h
, height
);
633 bitmap_set(dirty
[y
], x
/ VNC_DIRTY_PIXELS_PER_BIT
,
634 DIV_ROUND_UP(w
, VNC_DIRTY_PIXELS_PER_BIT
));
638 static void vnc_dpy_update(DisplayChangeListener
*dcl
,
639 int x
, int y
, int w
, int h
)
641 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
642 struct VncSurface
*s
= &vd
->guest
;
643 int width
= pixman_image_get_width(vd
->server
);
644 int height
= pixman_image_get_height(vd
->server
);
646 vnc_set_area_dirty(s
->dirty
, width
, height
, x
, y
, w
, h
);
649 void vnc_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
,
652 vnc_write_u16(vs
, x
);
653 vnc_write_u16(vs
, y
);
654 vnc_write_u16(vs
, w
);
655 vnc_write_u16(vs
, h
);
657 vnc_write_s32(vs
, encoding
);
661 static void vnc_desktop_resize(VncState
*vs
)
663 if (vs
->csock
== -1 || !vnc_has_feature(vs
, VNC_FEATURE_RESIZE
)) {
666 if (vs
->client_width
== pixman_image_get_width(vs
->vd
->server
) &&
667 vs
->client_height
== pixman_image_get_height(vs
->vd
->server
)) {
670 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
671 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
673 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
675 vnc_write_u16(vs
, 1); /* number of rects */
676 vnc_framebuffer_update(vs
, 0, 0, vs
->client_width
, vs
->client_height
,
677 VNC_ENCODING_DESKTOPRESIZE
);
678 vnc_unlock_output(vs
);
682 static void vnc_abort_display_jobs(VncDisplay
*vd
)
686 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
689 vnc_unlock_output(vs
);
691 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
694 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
697 vnc_unlock_output(vs
);
701 int vnc_server_fb_stride(VncDisplay
*vd
)
703 return pixman_image_get_stride(vd
->server
);
706 void *vnc_server_fb_ptr(VncDisplay
*vd
, int x
, int y
)
710 ptr
= (uint8_t *)pixman_image_get_data(vd
->server
);
711 ptr
+= y
* vnc_server_fb_stride(vd
);
712 ptr
+= x
* VNC_SERVER_FB_BYTES
;
716 static void vnc_dpy_switch(DisplayChangeListener
*dcl
,
717 DisplaySurface
*surface
)
719 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
723 vnc_abort_display_jobs(vd
);
726 qemu_pixman_image_unref(vd
->server
);
728 width
= MIN(VNC_MAX_WIDTH
, ROUND_UP(surface_width(vd
->ds
),
729 VNC_DIRTY_PIXELS_PER_BIT
));
730 height
= MIN(VNC_MAX_HEIGHT
, surface_height(vd
->ds
));
731 vd
->server
= pixman_image_create_bits(VNC_SERVER_FB_FORMAT
,
732 width
, height
, NULL
, 0);
736 if (ds_get_bytes_per_pixel(ds
) != vd
->guest
.ds
->pf
.bytes_per_pixel
)
737 console_color_init(ds
);
739 qemu_pixman_image_unref(vd
->guest
.fb
);
740 vd
->guest
.fb
= pixman_image_ref(surface
->image
);
741 vd
->guest
.format
= surface
->format
;
742 memset(vd
->guest
.dirty
, 0x00, sizeof(vd
->guest
.dirty
));
743 vnc_set_area_dirty(vd
->guest
.dirty
, width
, height
, 0, 0,
746 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
748 vnc_desktop_resize(vs
);
749 if (vs
->vd
->cursor
) {
750 vnc_cursor_define(vs
);
752 memset(vs
->dirty
, 0x00, sizeof(vs
->dirty
));
753 vnc_set_area_dirty(vs
->dirty
, width
, height
, 0, 0,
759 static void vnc_write_pixels_copy(VncState
*vs
,
760 void *pixels
, int size
)
762 vnc_write(vs
, pixels
, size
);
765 /* slowest but generic code. */
766 void vnc_convert_pixel(VncState
*vs
, uint8_t *buf
, uint32_t v
)
770 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
771 r
= (((v
& 0x00ff0000) >> 16) << vs
->client_pf
.rbits
) >> 8;
772 g
= (((v
& 0x0000ff00) >> 8) << vs
->client_pf
.gbits
) >> 8;
773 b
= (((v
& 0x000000ff) >> 0) << vs
->client_pf
.bbits
) >> 8;
775 # error need some bits here if you change VNC_SERVER_FB_FORMAT
777 v
= (r
<< vs
->client_pf
.rshift
) |
778 (g
<< vs
->client_pf
.gshift
) |
779 (b
<< vs
->client_pf
.bshift
);
780 switch (vs
->client_pf
.bytes_per_pixel
) {
810 static void vnc_write_pixels_generic(VncState
*vs
,
811 void *pixels1
, int size
)
815 if (VNC_SERVER_FB_BYTES
== 4) {
816 uint32_t *pixels
= pixels1
;
819 for (i
= 0; i
< n
; i
++) {
820 vnc_convert_pixel(vs
, buf
, pixels
[i
]);
821 vnc_write(vs
, buf
, vs
->client_pf
.bytes_per_pixel
);
826 int vnc_raw_send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
830 VncDisplay
*vd
= vs
->vd
;
832 row
= vnc_server_fb_ptr(vd
, x
, y
);
833 for (i
= 0; i
< h
; i
++) {
834 vs
->write_pixels(vs
, row
, w
* VNC_SERVER_FB_BYTES
);
835 row
+= vnc_server_fb_stride(vd
);
840 int vnc_send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
843 bool encode_raw
= false;
844 size_t saved_offs
= vs
->output
.offset
;
846 switch(vs
->vnc_encoding
) {
847 case VNC_ENCODING_ZLIB
:
848 n
= vnc_zlib_send_framebuffer_update(vs
, x
, y
, w
, h
);
850 case VNC_ENCODING_HEXTILE
:
851 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_HEXTILE
);
852 n
= vnc_hextile_send_framebuffer_update(vs
, x
, y
, w
, h
);
854 case VNC_ENCODING_TIGHT
:
855 n
= vnc_tight_send_framebuffer_update(vs
, x
, y
, w
, h
);
857 case VNC_ENCODING_TIGHT_PNG
:
858 n
= vnc_tight_png_send_framebuffer_update(vs
, x
, y
, w
, h
);
860 case VNC_ENCODING_ZRLE
:
861 n
= vnc_zrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
863 case VNC_ENCODING_ZYWRLE
:
864 n
= vnc_zywrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
871 /* If the client has the same pixel format as our internal buffer and
872 * a RAW encoding would need less space fall back to RAW encoding to
873 * save bandwidth and processing power in the client. */
874 if (!encode_raw
&& vs
->write_pixels
== vnc_write_pixels_copy
&&
875 12 + h
* w
* VNC_SERVER_FB_BYTES
<= (vs
->output
.offset
- saved_offs
)) {
876 vs
->output
.offset
= saved_offs
;
881 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_RAW
);
882 n
= vnc_raw_send_framebuffer_update(vs
, x
, y
, w
, h
);
888 static void vnc_copy(VncState
*vs
, int src_x
, int src_y
, int dst_x
, int dst_y
, int w
, int h
)
890 /* send bitblit op to the vnc client */
892 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
894 vnc_write_u16(vs
, 1); /* number of rects */
895 vnc_framebuffer_update(vs
, dst_x
, dst_y
, w
, h
, VNC_ENCODING_COPYRECT
);
896 vnc_write_u16(vs
, src_x
);
897 vnc_write_u16(vs
, src_y
);
898 vnc_unlock_output(vs
);
902 static void vnc_dpy_copy(DisplayChangeListener
*dcl
,
903 int src_x
, int src_y
,
904 int dst_x
, int dst_y
, int w
, int h
)
906 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
910 int i
, x
, y
, pitch
, inc
, w_lim
, s
;
913 vnc_refresh_server_surface(vd
);
914 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
915 if (vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
916 vs
->force_update
= 1;
917 vnc_update_client(vs
, 1, true);
918 /* vs might be free()ed here */
922 /* do bitblit op on the local surface too */
923 pitch
= vnc_server_fb_stride(vd
);
924 src_row
= vnc_server_fb_ptr(vd
, src_x
, src_y
);
925 dst_row
= vnc_server_fb_ptr(vd
, dst_x
, dst_y
);
930 src_row
+= pitch
* (h
-1);
931 dst_row
+= pitch
* (h
-1);
936 w_lim
= w
- (VNC_DIRTY_PIXELS_PER_BIT
- (dst_x
% VNC_DIRTY_PIXELS_PER_BIT
));
940 w_lim
= w
- (w_lim
% VNC_DIRTY_PIXELS_PER_BIT
);
942 for (i
= 0; i
< h
; i
++) {
943 for (x
= 0; x
<= w_lim
;
944 x
+= s
, src_row
+= cmp_bytes
, dst_row
+= cmp_bytes
) {
946 if ((s
= w
- w_lim
) == 0)
949 s
= (VNC_DIRTY_PIXELS_PER_BIT
-
950 (dst_x
% VNC_DIRTY_PIXELS_PER_BIT
));
953 s
= VNC_DIRTY_PIXELS_PER_BIT
;
955 cmp_bytes
= s
* VNC_SERVER_FB_BYTES
;
956 if (memcmp(src_row
, dst_row
, cmp_bytes
) == 0)
958 memmove(dst_row
, src_row
, cmp_bytes
);
959 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
960 if (!vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
961 set_bit(((x
+ dst_x
) / VNC_DIRTY_PIXELS_PER_BIT
),
966 src_row
+= pitch
- w
* VNC_SERVER_FB_BYTES
;
967 dst_row
+= pitch
- w
* VNC_SERVER_FB_BYTES
;
971 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
972 if (vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
)) {
973 vnc_copy(vs
, src_x
, src_y
, dst_x
, dst_y
, w
, h
);
978 static void vnc_mouse_set(DisplayChangeListener
*dcl
,
979 int x
, int y
, int visible
)
981 /* can we ask the client(s) to move the pointer ??? */
984 static int vnc_cursor_define(VncState
*vs
)
986 QEMUCursor
*c
= vs
->vd
->cursor
;
989 if (vnc_has_feature(vs
, VNC_FEATURE_RICH_CURSOR
)) {
991 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
992 vnc_write_u8(vs
, 0); /* padding */
993 vnc_write_u16(vs
, 1); /* # of rects */
994 vnc_framebuffer_update(vs
, c
->hot_x
, c
->hot_y
, c
->width
, c
->height
,
995 VNC_ENCODING_RICH_CURSOR
);
996 isize
= c
->width
* c
->height
* vs
->client_pf
.bytes_per_pixel
;
997 vnc_write_pixels_generic(vs
, c
->data
, isize
);
998 vnc_write(vs
, vs
->vd
->cursor_mask
, vs
->vd
->cursor_msize
);
999 vnc_unlock_output(vs
);
1005 static void vnc_dpy_cursor_define(DisplayChangeListener
*dcl
,
1008 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
1011 cursor_put(vd
->cursor
);
1012 g_free(vd
->cursor_mask
);
1015 cursor_get(vd
->cursor
);
1016 vd
->cursor_msize
= cursor_get_mono_bpl(c
) * c
->height
;
1017 vd
->cursor_mask
= g_malloc0(vd
->cursor_msize
);
1018 cursor_get_mono_mask(c
, 0, vd
->cursor_mask
);
1020 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
1021 vnc_cursor_define(vs
);
1025 static int find_and_clear_dirty_height(VncState
*vs
,
1026 int y
, int last_x
, int x
, int height
)
1030 for (h
= 1; h
< (height
- y
); h
++) {
1031 if (!test_bit(last_x
, vs
->dirty
[y
+ h
])) {
1034 bitmap_clear(vs
->dirty
[y
+ h
], last_x
, x
- last_x
);
1040 static int vnc_update_client(VncState
*vs
, int has_dirty
, bool sync
)
1042 vs
->has_dirty
+= has_dirty
;
1043 if (vs
->need_update
&& vs
->csock
!= -1) {
1044 VncDisplay
*vd
= vs
->vd
;
1050 if (vs
->output
.offset
&& !vs
->audio_cap
&& !vs
->force_update
)
1051 /* kernel send buffers are full -> drop frames to throttle */
1054 if (!vs
->has_dirty
&& !vs
->audio_cap
&& !vs
->force_update
)
1058 * Send screen updates to the vnc client using the server
1059 * surface and server dirty map. guest surface updates
1060 * happening in parallel don't disturb us, the next pass will
1061 * send them to the client.
1063 job
= vnc_job_new(vs
);
1065 height
= pixman_image_get_height(vd
->server
);
1066 width
= pixman_image_get_width(vd
->server
);
1072 unsigned long offset
= find_next_bit((unsigned long *) &vs
->dirty
,
1073 height
* VNC_DIRTY_BPL(vs
),
1074 y
* VNC_DIRTY_BPL(vs
));
1075 if (offset
== height
* VNC_DIRTY_BPL(vs
)) {
1076 /* no more dirty bits */
1079 y
= offset
/ VNC_DIRTY_BPL(vs
);
1080 x
= offset
% VNC_DIRTY_BPL(vs
);
1081 x2
= find_next_zero_bit((unsigned long *) &vs
->dirty
[y
],
1082 VNC_DIRTY_BPL(vs
), x
);
1083 bitmap_clear(vs
->dirty
[y
], x
, x2
- x
);
1084 h
= find_and_clear_dirty_height(vs
, y
, x
, x2
, height
);
1085 x2
= MIN(x2
, width
/ VNC_DIRTY_PIXELS_PER_BIT
);
1087 n
+= vnc_job_add_rect(job
, x
* VNC_DIRTY_PIXELS_PER_BIT
, y
,
1088 (x2
- x
) * VNC_DIRTY_PIXELS_PER_BIT
, h
);
1090 if (!x
&& x2
== width
/ VNC_DIRTY_PIXELS_PER_BIT
) {
1102 vs
->force_update
= 0;
1107 if (vs
->csock
== -1) {
1108 vnc_disconnect_finish(vs
);
1117 static void audio_capture_notify(void *opaque
, audcnotification_e cmd
)
1119 VncState
*vs
= opaque
;
1122 case AUD_CNOTIFY_DISABLE
:
1123 vnc_lock_output(vs
);
1124 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1125 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1126 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_END
);
1127 vnc_unlock_output(vs
);
1131 case AUD_CNOTIFY_ENABLE
:
1132 vnc_lock_output(vs
);
1133 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1134 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1135 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN
);
1136 vnc_unlock_output(vs
);
1142 static void audio_capture_destroy(void *opaque
)
1146 static void audio_capture(void *opaque
, void *buf
, int size
)
1148 VncState
*vs
= opaque
;
1150 vnc_lock_output(vs
);
1151 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1152 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1153 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_DATA
);
1154 vnc_write_u32(vs
, size
);
1155 vnc_write(vs
, buf
, size
);
1156 vnc_unlock_output(vs
);
1160 static void audio_add(VncState
*vs
)
1162 struct audio_capture_ops ops
;
1164 if (vs
->audio_cap
) {
1165 error_report("audio already running");
1169 ops
.notify
= audio_capture_notify
;
1170 ops
.destroy
= audio_capture_destroy
;
1171 ops
.capture
= audio_capture
;
1173 vs
->audio_cap
= AUD_add_capture(&vs
->as
, &ops
, vs
);
1174 if (!vs
->audio_cap
) {
1175 error_report("Failed to add audio capture");
1179 static void audio_del(VncState
*vs
)
1181 if (vs
->audio_cap
) {
1182 AUD_del_capture(vs
->audio_cap
, vs
);
1183 vs
->audio_cap
= NULL
;
1187 static void vnc_disconnect_start(VncState
*vs
)
1189 if (vs
->csock
== -1)
1191 vnc_set_share_mode(vs
, VNC_SHARE_MODE_DISCONNECTED
);
1192 qemu_set_fd_handler(vs
->csock
, NULL
, NULL
, NULL
);
1193 closesocket(vs
->csock
);
1197 void vnc_disconnect_finish(VncState
*vs
)
1201 vnc_jobs_join(vs
); /* Wait encoding jobs */
1203 vnc_lock_output(vs
);
1204 vnc_qmp_event(vs
, QAPI_EVENT_VNC_DISCONNECTED
);
1206 buffer_free(&vs
->input
);
1207 buffer_free(&vs
->output
);
1208 buffer_free(&vs
->ws_input
);
1209 buffer_free(&vs
->ws_output
);
1211 qapi_free_VncClientInfo(vs
->info
);
1214 vnc_tight_clear(vs
);
1217 qcrypto_tls_session_free(vs
->tls
);
1218 #ifdef CONFIG_VNC_SASL
1219 vnc_sasl_client_cleanup(vs
);
1220 #endif /* CONFIG_VNC_SASL */
1222 vnc_release_modifiers(vs
);
1224 if (vs
->initialized
) {
1225 QTAILQ_REMOVE(&vs
->vd
->clients
, vs
, next
);
1226 qemu_remove_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
1229 if (vs
->vd
->lock_key_sync
)
1230 qemu_remove_led_event_handler(vs
->led
);
1231 vnc_unlock_output(vs
);
1233 qemu_mutex_destroy(&vs
->output_mutex
);
1234 if (vs
->bh
!= NULL
) {
1235 qemu_bh_delete(vs
->bh
);
1237 buffer_free(&vs
->jobs_buffer
);
1239 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
1240 g_free(vs
->lossy_rect
[i
]);
1242 g_free(vs
->lossy_rect
);
1246 ssize_t
vnc_client_io_error(VncState
*vs
, ssize_t ret
, int last_errno
)
1248 if (ret
== 0 || ret
== -1) {
1250 switch (last_errno
) {
1254 case WSAEWOULDBLOCK
:
1262 VNC_DEBUG("Closing down client sock: ret %zd, errno %d\n",
1263 ret
, ret
< 0 ? last_errno
: 0);
1264 vnc_disconnect_start(vs
);
1272 void vnc_client_error(VncState
*vs
)
1274 VNC_DEBUG("Closing down client sock: protocol error\n");
1275 vnc_disconnect_start(vs
);
1279 ssize_t
vnc_tls_pull(char *buf
, size_t len
, void *opaque
)
1281 VncState
*vs
= opaque
;
1285 ret
= qemu_recv(vs
->csock
, buf
, len
, 0);
1287 if (errno
== EINTR
) {
1296 ssize_t
vnc_tls_push(const char *buf
, size_t len
, void *opaque
)
1298 VncState
*vs
= opaque
;
1302 ret
= send(vs
->csock
, buf
, len
, 0);
1304 if (errno
== EINTR
) {
1314 * Called to write a chunk of data to the client socket. The data may
1315 * be the raw data, or may have already been encoded by SASL.
1316 * The data will be written either straight onto the socket, or
1317 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1319 * NB, it is theoretically possible to have 2 layers of encryption,
1320 * both SASL, and this TLS layer. It is highly unlikely in practice
1321 * though, since SASL encryption will typically be a no-op if TLS
1324 * Returns the number of bytes written, which may be less than
1325 * the requested 'datalen' if the socket would block. Returns
1326 * -1 on error, and disconnects the client socket.
1328 ssize_t
vnc_client_write_buf(VncState
*vs
, const void *data
, size_t datalen
)
1333 ret
= qcrypto_tls_session_write(vs
->tls
, data
, datalen
);
1338 ret
= send(vs
->csock
, data
, datalen
, 0);
1340 err
= socket_error();
1343 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data
, datalen
, ret
);
1344 return vnc_client_io_error(vs
, ret
, err
);
1349 * Called to write buffered data to the client socket, when not
1350 * using any SASL SSF encryption layers. Will write as much data
1351 * as possible without blocking. If all buffered data is written,
1352 * will switch the FD poll() handler back to read monitoring.
1354 * Returns the number of bytes written, which may be less than
1355 * the buffered output data if the socket would block. Returns
1356 * -1 on error, and disconnects the client socket.
1358 static ssize_t
vnc_client_write_plain(VncState
*vs
)
1362 #ifdef CONFIG_VNC_SASL
1363 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1364 vs
->output
.buffer
, vs
->output
.capacity
, vs
->output
.offset
,
1365 vs
->sasl
.waitWriteSSF
);
1367 if (vs
->sasl
.conn
&&
1369 vs
->sasl
.waitWriteSSF
) {
1370 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->sasl
.waitWriteSSF
);
1372 vs
->sasl
.waitWriteSSF
-= ret
;
1374 #endif /* CONFIG_VNC_SASL */
1375 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->output
.offset
);
1379 buffer_advance(&vs
->output
, ret
);
1381 if (vs
->output
.offset
== 0) {
1382 qemu_set_fd_handler(vs
->csock
, vnc_client_read
, NULL
, vs
);
1390 * First function called whenever there is data to be written to
1391 * the client socket. Will delegate actual work according to whether
1392 * SASL SSF layers are enabled (thus requiring encryption calls)
1394 static void vnc_client_write_locked(void *opaque
)
1396 VncState
*vs
= opaque
;
1398 #ifdef CONFIG_VNC_SASL
1399 if (vs
->sasl
.conn
&&
1401 !vs
->sasl
.waitWriteSSF
) {
1402 vnc_client_write_sasl(vs
);
1404 #endif /* CONFIG_VNC_SASL */
1406 if (vs
->encode_ws
) {
1407 vnc_client_write_ws(vs
);
1409 vnc_client_write_plain(vs
);
1414 void vnc_client_write(void *opaque
)
1416 VncState
*vs
= opaque
;
1418 vnc_lock_output(vs
);
1419 if (vs
->output
.offset
|| vs
->ws_output
.offset
) {
1420 vnc_client_write_locked(opaque
);
1421 } else if (vs
->csock
!= -1) {
1422 qemu_set_fd_handler(vs
->csock
, vnc_client_read
, NULL
, vs
);
1424 vnc_unlock_output(vs
);
1427 void vnc_read_when(VncState
*vs
, VncReadEvent
*func
, size_t expecting
)
1429 vs
->read_handler
= func
;
1430 vs
->read_handler_expect
= expecting
;
1435 * Called to read a chunk of data from the client socket. The data may
1436 * be the raw data, or may need to be further decoded by SASL.
1437 * The data will be read either straight from to the socket, or
1438 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1440 * NB, it is theoretically possible to have 2 layers of encryption,
1441 * both SASL, and this TLS layer. It is highly unlikely in practice
1442 * though, since SASL encryption will typically be a no-op if TLS
1445 * Returns the number of bytes read, which may be less than
1446 * the requested 'datalen' if the socket would block. Returns
1447 * -1 on error, and disconnects the client socket.
1449 ssize_t
vnc_client_read_buf(VncState
*vs
, void *data
, size_t datalen
)
1454 ret
= qcrypto_tls_session_read(vs
->tls
, data
, datalen
);
1459 ret
= qemu_recv(vs
->csock
, data
, datalen
, 0);
1461 err
= socket_error();
1464 VNC_DEBUG("Read wire %p %zd -> %ld\n", data
, datalen
, ret
);
1465 return vnc_client_io_error(vs
, ret
, err
);
1470 * Called to read data from the client socket to the input buffer,
1471 * when not using any SASL SSF encryption layers. Will read as much
1472 * data as possible without blocking.
1474 * Returns the number of bytes read. Returns -1 on error, and
1475 * disconnects the client socket.
1477 static ssize_t
vnc_client_read_plain(VncState
*vs
)
1480 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1481 vs
->input
.buffer
, vs
->input
.capacity
, vs
->input
.offset
);
1482 buffer_reserve(&vs
->input
, 4096);
1483 ret
= vnc_client_read_buf(vs
, buffer_end(&vs
->input
), 4096);
1486 vs
->input
.offset
+= ret
;
1490 static void vnc_jobs_bh(void *opaque
)
1492 VncState
*vs
= opaque
;
1494 vnc_jobs_consume_buffer(vs
);
1498 * First function called whenever there is more data to be read from
1499 * the client socket. Will delegate actual work according to whether
1500 * SASL SSF layers are enabled (thus requiring decryption calls)
1502 void vnc_client_read(void *opaque
)
1504 VncState
*vs
= opaque
;
1507 #ifdef CONFIG_VNC_SASL
1508 if (vs
->sasl
.conn
&& vs
->sasl
.runSSF
)
1509 ret
= vnc_client_read_sasl(vs
);
1511 #endif /* CONFIG_VNC_SASL */
1512 if (vs
->encode_ws
) {
1513 ret
= vnc_client_read_ws(vs
);
1515 vnc_disconnect_start(vs
);
1517 } else if (ret
== -2) {
1518 vnc_client_error(vs
);
1522 ret
= vnc_client_read_plain(vs
);
1525 if (vs
->csock
== -1)
1526 vnc_disconnect_finish(vs
);
1530 while (vs
->read_handler
&& vs
->input
.offset
>= vs
->read_handler_expect
) {
1531 size_t len
= vs
->read_handler_expect
;
1534 ret
= vs
->read_handler(vs
, vs
->input
.buffer
, len
);
1535 if (vs
->csock
== -1) {
1536 vnc_disconnect_finish(vs
);
1541 buffer_advance(&vs
->input
, len
);
1543 vs
->read_handler_expect
= ret
;
1548 void vnc_write(VncState
*vs
, const void *data
, size_t len
)
1550 buffer_reserve(&vs
->output
, len
);
1552 if (vs
->csock
!= -1 && buffer_empty(&vs
->output
)) {
1553 qemu_set_fd_handler(vs
->csock
, vnc_client_read
, vnc_client_write
, vs
);
1556 buffer_append(&vs
->output
, data
, len
);
1559 void vnc_write_s32(VncState
*vs
, int32_t value
)
1561 vnc_write_u32(vs
, *(uint32_t *)&value
);
1564 void vnc_write_u32(VncState
*vs
, uint32_t value
)
1568 buf
[0] = (value
>> 24) & 0xFF;
1569 buf
[1] = (value
>> 16) & 0xFF;
1570 buf
[2] = (value
>> 8) & 0xFF;
1571 buf
[3] = value
& 0xFF;
1573 vnc_write(vs
, buf
, 4);
1576 void vnc_write_u16(VncState
*vs
, uint16_t value
)
1580 buf
[0] = (value
>> 8) & 0xFF;
1581 buf
[1] = value
& 0xFF;
1583 vnc_write(vs
, buf
, 2);
1586 void vnc_write_u8(VncState
*vs
, uint8_t value
)
1588 vnc_write(vs
, (char *)&value
, 1);
1591 void vnc_flush(VncState
*vs
)
1593 vnc_lock_output(vs
);
1594 if (vs
->csock
!= -1 && (vs
->output
.offset
||
1595 vs
->ws_output
.offset
)) {
1596 vnc_client_write_locked(vs
);
1598 vnc_unlock_output(vs
);
1601 static uint8_t read_u8(uint8_t *data
, size_t offset
)
1603 return data
[offset
];
1606 static uint16_t read_u16(uint8_t *data
, size_t offset
)
1608 return ((data
[offset
] & 0xFF) << 8) | (data
[offset
+ 1] & 0xFF);
1611 static int32_t read_s32(uint8_t *data
, size_t offset
)
1613 return (int32_t)((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1614 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1617 uint32_t read_u32(uint8_t *data
, size_t offset
)
1619 return ((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1620 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1623 static void client_cut_text(VncState
*vs
, size_t len
, uint8_t *text
)
1627 static void check_pointer_type_change(Notifier
*notifier
, void *data
)
1629 VncState
*vs
= container_of(notifier
, VncState
, mouse_mode_notifier
);
1630 int absolute
= qemu_input_is_absolute();
1632 if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
) && vs
->absolute
!= absolute
) {
1633 vnc_lock_output(vs
);
1634 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1635 vnc_write_u8(vs
, 0);
1636 vnc_write_u16(vs
, 1);
1637 vnc_framebuffer_update(vs
, absolute
, 0,
1638 pixman_image_get_width(vs
->vd
->server
),
1639 pixman_image_get_height(vs
->vd
->server
),
1640 VNC_ENCODING_POINTER_TYPE_CHANGE
);
1641 vnc_unlock_output(vs
);
1644 vs
->absolute
= absolute
;
1647 static void pointer_event(VncState
*vs
, int button_mask
, int x
, int y
)
1649 static uint32_t bmap
[INPUT_BUTTON_MAX
] = {
1650 [INPUT_BUTTON_LEFT
] = 0x01,
1651 [INPUT_BUTTON_MIDDLE
] = 0x02,
1652 [INPUT_BUTTON_RIGHT
] = 0x04,
1653 [INPUT_BUTTON_WHEEL_UP
] = 0x08,
1654 [INPUT_BUTTON_WHEEL_DOWN
] = 0x10,
1656 QemuConsole
*con
= vs
->vd
->dcl
.con
;
1657 int width
= pixman_image_get_width(vs
->vd
->server
);
1658 int height
= pixman_image_get_height(vs
->vd
->server
);
1660 if (vs
->last_bmask
!= button_mask
) {
1661 qemu_input_update_buttons(con
, bmap
, vs
->last_bmask
, button_mask
);
1662 vs
->last_bmask
= button_mask
;
1666 qemu_input_queue_abs(con
, INPUT_AXIS_X
, x
, width
);
1667 qemu_input_queue_abs(con
, INPUT_AXIS_Y
, y
, height
);
1668 } else if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
)) {
1669 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- 0x7FFF);
1670 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- 0x7FFF);
1672 if (vs
->last_x
!= -1) {
1673 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- vs
->last_x
);
1674 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- vs
->last_y
);
1679 qemu_input_event_sync();
1682 static void reset_keys(VncState
*vs
)
1685 for(i
= 0; i
< 256; i
++) {
1686 if (vs
->modifiers_state
[i
]) {
1687 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, i
, false);
1688 vs
->modifiers_state
[i
] = 0;
1693 static void press_key(VncState
*vs
, int keysym
)
1695 int keycode
= keysym2scancode(vs
->vd
->kbd_layout
, keysym
) & SCANCODE_KEYMASK
;
1696 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, true);
1697 qemu_input_event_send_key_delay(0);
1698 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1699 qemu_input_event_send_key_delay(0);
1702 static int current_led_state(VncState
*vs
)
1706 if (vs
->modifiers_state
[0x46]) {
1707 ledstate
|= QEMU_SCROLL_LOCK_LED
;
1709 if (vs
->modifiers_state
[0x45]) {
1710 ledstate
|= QEMU_NUM_LOCK_LED
;
1712 if (vs
->modifiers_state
[0x3a]) {
1713 ledstate
|= QEMU_CAPS_LOCK_LED
;
1719 static void vnc_led_state_change(VncState
*vs
)
1723 if (!vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
)) {
1727 ledstate
= current_led_state(vs
);
1728 vnc_lock_output(vs
);
1729 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1730 vnc_write_u8(vs
, 0);
1731 vnc_write_u16(vs
, 1);
1732 vnc_framebuffer_update(vs
, 0, 0, 1, 1, VNC_ENCODING_LED_STATE
);
1733 vnc_write_u8(vs
, ledstate
);
1734 vnc_unlock_output(vs
);
1738 static void kbd_leds(void *opaque
, int ledstate
)
1740 VncState
*vs
= opaque
;
1742 bool has_changed
= (ledstate
!= current_led_state(vs
));
1744 trace_vnc_key_guest_leds((ledstate
& QEMU_CAPS_LOCK_LED
),
1745 (ledstate
& QEMU_NUM_LOCK_LED
),
1746 (ledstate
& QEMU_SCROLL_LOCK_LED
));
1748 caps
= ledstate
& QEMU_CAPS_LOCK_LED
? 1 : 0;
1749 num
= ledstate
& QEMU_NUM_LOCK_LED
? 1 : 0;
1750 scr
= ledstate
& QEMU_SCROLL_LOCK_LED
? 1 : 0;
1752 if (vs
->modifiers_state
[0x3a] != caps
) {
1753 vs
->modifiers_state
[0x3a] = caps
;
1755 if (vs
->modifiers_state
[0x45] != num
) {
1756 vs
->modifiers_state
[0x45] = num
;
1758 if (vs
->modifiers_state
[0x46] != scr
) {
1759 vs
->modifiers_state
[0x46] = scr
;
1762 /* Sending the current led state message to the client */
1764 vnc_led_state_change(vs
);
1768 static void do_key_event(VncState
*vs
, int down
, int keycode
, int sym
)
1770 /* QEMU console switch */
1772 case 0x2a: /* Left Shift */
1773 case 0x36: /* Right Shift */
1774 case 0x1d: /* Left CTRL */
1775 case 0x9d: /* Right CTRL */
1776 case 0x38: /* Left ALT */
1777 case 0xb8: /* Right ALT */
1779 vs
->modifiers_state
[keycode
] = 1;
1781 vs
->modifiers_state
[keycode
] = 0;
1783 case 0x02 ... 0x0a: /* '1' to '9' keys */
1784 if (vs
->vd
->dcl
.con
== NULL
&&
1785 down
&& vs
->modifiers_state
[0x1d] && vs
->modifiers_state
[0x38]) {
1786 /* Reset the modifiers sent to the current console */
1788 console_select(keycode
- 0x02);
1792 case 0x3a: /* CapsLock */
1793 case 0x45: /* NumLock */
1795 vs
->modifiers_state
[keycode
] ^= 1;
1799 /* Turn off the lock state sync logic if the client support the led
1802 if (down
&& vs
->vd
->lock_key_sync
&&
1803 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1804 keycode_is_keypad(vs
->vd
->kbd_layout
, keycode
)) {
1805 /* If the numlock state needs to change then simulate an additional
1806 keypress before sending this one. This will happen if the user
1807 toggles numlock away from the VNC window.
1809 if (keysym_is_numlock(vs
->vd
->kbd_layout
, sym
& 0xFFFF)) {
1810 if (!vs
->modifiers_state
[0x45]) {
1811 trace_vnc_key_sync_numlock(true);
1812 vs
->modifiers_state
[0x45] = 1;
1813 press_key(vs
, 0xff7f);
1816 if (vs
->modifiers_state
[0x45]) {
1817 trace_vnc_key_sync_numlock(false);
1818 vs
->modifiers_state
[0x45] = 0;
1819 press_key(vs
, 0xff7f);
1824 if (down
&& vs
->vd
->lock_key_sync
&&
1825 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1826 ((sym
>= 'A' && sym
<= 'Z') || (sym
>= 'a' && sym
<= 'z'))) {
1827 /* If the capslock state needs to change then simulate an additional
1828 keypress before sending this one. This will happen if the user
1829 toggles capslock away from the VNC window.
1831 int uppercase
= !!(sym
>= 'A' && sym
<= 'Z');
1832 int shift
= !!(vs
->modifiers_state
[0x2a] | vs
->modifiers_state
[0x36]);
1833 int capslock
= !!(vs
->modifiers_state
[0x3a]);
1835 if (uppercase
== shift
) {
1836 trace_vnc_key_sync_capslock(false);
1837 vs
->modifiers_state
[0x3a] = 0;
1838 press_key(vs
, 0xffe5);
1841 if (uppercase
!= shift
) {
1842 trace_vnc_key_sync_capslock(true);
1843 vs
->modifiers_state
[0x3a] = 1;
1844 press_key(vs
, 0xffe5);
1849 if (qemu_console_is_graphic(NULL
)) {
1850 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, down
);
1852 bool numlock
= vs
->modifiers_state
[0x45];
1853 bool control
= (vs
->modifiers_state
[0x1d] ||
1854 vs
->modifiers_state
[0x9d]);
1855 /* QEMU console emulation */
1858 case 0x2a: /* Left Shift */
1859 case 0x36: /* Right Shift */
1860 case 0x1d: /* Left CTRL */
1861 case 0x9d: /* Right CTRL */
1862 case 0x38: /* Left ALT */
1863 case 0xb8: /* Right ALT */
1866 kbd_put_keysym(QEMU_KEY_UP
);
1869 kbd_put_keysym(QEMU_KEY_DOWN
);
1872 kbd_put_keysym(QEMU_KEY_LEFT
);
1875 kbd_put_keysym(QEMU_KEY_RIGHT
);
1878 kbd_put_keysym(QEMU_KEY_DELETE
);
1881 kbd_put_keysym(QEMU_KEY_HOME
);
1884 kbd_put_keysym(QEMU_KEY_END
);
1887 kbd_put_keysym(QEMU_KEY_PAGEUP
);
1890 kbd_put_keysym(QEMU_KEY_PAGEDOWN
);
1894 kbd_put_keysym(numlock
? '7' : QEMU_KEY_HOME
);
1897 kbd_put_keysym(numlock
? '8' : QEMU_KEY_UP
);
1900 kbd_put_keysym(numlock
? '9' : QEMU_KEY_PAGEUP
);
1903 kbd_put_keysym(numlock
? '4' : QEMU_KEY_LEFT
);
1906 kbd_put_keysym('5');
1909 kbd_put_keysym(numlock
? '6' : QEMU_KEY_RIGHT
);
1912 kbd_put_keysym(numlock
? '1' : QEMU_KEY_END
);
1915 kbd_put_keysym(numlock
? '2' : QEMU_KEY_DOWN
);
1918 kbd_put_keysym(numlock
? '3' : QEMU_KEY_PAGEDOWN
);
1921 kbd_put_keysym('0');
1924 kbd_put_keysym(numlock
? '.' : QEMU_KEY_DELETE
);
1928 kbd_put_keysym('/');
1931 kbd_put_keysym('*');
1934 kbd_put_keysym('-');
1937 kbd_put_keysym('+');
1940 kbd_put_keysym('\n');
1945 kbd_put_keysym(sym
& 0x1f);
1947 kbd_put_keysym(sym
);
1955 static void vnc_release_modifiers(VncState
*vs
)
1957 static const int keycodes
[] = {
1958 /* shift, control, alt keys, both left & right */
1959 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1963 if (!qemu_console_is_graphic(NULL
)) {
1966 for (i
= 0; i
< ARRAY_SIZE(keycodes
); i
++) {
1967 keycode
= keycodes
[i
];
1968 if (!vs
->modifiers_state
[keycode
]) {
1971 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1975 static const char *code2name(int keycode
)
1977 return QKeyCode_lookup
[qemu_input_key_number_to_qcode(keycode
)];
1980 static void key_event(VncState
*vs
, int down
, uint32_t sym
)
1985 if (lsym
>= 'A' && lsym
<= 'Z' && qemu_console_is_graphic(NULL
)) {
1986 lsym
= lsym
- 'A' + 'a';
1989 keycode
= keysym2scancode(vs
->vd
->kbd_layout
, lsym
& 0xFFFF) & SCANCODE_KEYMASK
;
1990 trace_vnc_key_event_map(down
, sym
, keycode
, code2name(keycode
));
1991 do_key_event(vs
, down
, keycode
, sym
);
1994 static void ext_key_event(VncState
*vs
, int down
,
1995 uint32_t sym
, uint16_t keycode
)
1997 /* if the user specifies a keyboard layout, always use it */
1998 if (keyboard_layout
) {
1999 key_event(vs
, down
, sym
);
2001 trace_vnc_key_event_ext(down
, sym
, keycode
, code2name(keycode
));
2002 do_key_event(vs
, down
, keycode
, sym
);
2006 static void framebuffer_update_request(VncState
*vs
, int incremental
,
2007 int x
, int y
, int w
, int h
)
2009 int width
= pixman_image_get_width(vs
->vd
->server
);
2010 int height
= pixman_image_get_height(vs
->vd
->server
);
2012 vs
->need_update
= 1;
2018 vs
->force_update
= 1;
2019 vnc_set_area_dirty(vs
->dirty
, width
, height
, x
, y
, w
, h
);
2022 static void send_ext_key_event_ack(VncState
*vs
)
2024 vnc_lock_output(vs
);
2025 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2026 vnc_write_u8(vs
, 0);
2027 vnc_write_u16(vs
, 1);
2028 vnc_framebuffer_update(vs
, 0, 0,
2029 pixman_image_get_width(vs
->vd
->server
),
2030 pixman_image_get_height(vs
->vd
->server
),
2031 VNC_ENCODING_EXT_KEY_EVENT
);
2032 vnc_unlock_output(vs
);
2036 static void send_ext_audio_ack(VncState
*vs
)
2038 vnc_lock_output(vs
);
2039 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2040 vnc_write_u8(vs
, 0);
2041 vnc_write_u16(vs
, 1);
2042 vnc_framebuffer_update(vs
, 0, 0,
2043 pixman_image_get_width(vs
->vd
->server
),
2044 pixman_image_get_height(vs
->vd
->server
),
2045 VNC_ENCODING_AUDIO
);
2046 vnc_unlock_output(vs
);
2050 static void set_encodings(VncState
*vs
, int32_t *encodings
, size_t n_encodings
)
2053 unsigned int enc
= 0;
2056 vs
->vnc_encoding
= 0;
2057 vs
->tight
.compression
= 9;
2058 vs
->tight
.quality
= -1; /* Lossless by default */
2062 * Start from the end because the encodings are sent in order of preference.
2063 * This way the preferred encoding (first encoding defined in the array)
2064 * will be set at the end of the loop.
2066 for (i
= n_encodings
- 1; i
>= 0; i
--) {
2069 case VNC_ENCODING_RAW
:
2070 vs
->vnc_encoding
= enc
;
2072 case VNC_ENCODING_COPYRECT
:
2073 vs
->features
|= VNC_FEATURE_COPYRECT_MASK
;
2075 case VNC_ENCODING_HEXTILE
:
2076 vs
->features
|= VNC_FEATURE_HEXTILE_MASK
;
2077 vs
->vnc_encoding
= enc
;
2079 case VNC_ENCODING_TIGHT
:
2080 vs
->features
|= VNC_FEATURE_TIGHT_MASK
;
2081 vs
->vnc_encoding
= enc
;
2083 #ifdef CONFIG_VNC_PNG
2084 case VNC_ENCODING_TIGHT_PNG
:
2085 vs
->features
|= VNC_FEATURE_TIGHT_PNG_MASK
;
2086 vs
->vnc_encoding
= enc
;
2089 case VNC_ENCODING_ZLIB
:
2090 vs
->features
|= VNC_FEATURE_ZLIB_MASK
;
2091 vs
->vnc_encoding
= enc
;
2093 case VNC_ENCODING_ZRLE
:
2094 vs
->features
|= VNC_FEATURE_ZRLE_MASK
;
2095 vs
->vnc_encoding
= enc
;
2097 case VNC_ENCODING_ZYWRLE
:
2098 vs
->features
|= VNC_FEATURE_ZYWRLE_MASK
;
2099 vs
->vnc_encoding
= enc
;
2101 case VNC_ENCODING_DESKTOPRESIZE
:
2102 vs
->features
|= VNC_FEATURE_RESIZE_MASK
;
2104 case VNC_ENCODING_POINTER_TYPE_CHANGE
:
2105 vs
->features
|= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK
;
2107 case VNC_ENCODING_RICH_CURSOR
:
2108 vs
->features
|= VNC_FEATURE_RICH_CURSOR_MASK
;
2110 case VNC_ENCODING_EXT_KEY_EVENT
:
2111 send_ext_key_event_ack(vs
);
2113 case VNC_ENCODING_AUDIO
:
2114 send_ext_audio_ack(vs
);
2116 case VNC_ENCODING_WMVi
:
2117 vs
->features
|= VNC_FEATURE_WMVI_MASK
;
2119 case VNC_ENCODING_LED_STATE
:
2120 vs
->features
|= VNC_FEATURE_LED_STATE_MASK
;
2122 case VNC_ENCODING_COMPRESSLEVEL0
... VNC_ENCODING_COMPRESSLEVEL0
+ 9:
2123 vs
->tight
.compression
= (enc
& 0x0F);
2125 case VNC_ENCODING_QUALITYLEVEL0
... VNC_ENCODING_QUALITYLEVEL0
+ 9:
2126 if (vs
->vd
->lossy
) {
2127 vs
->tight
.quality
= (enc
& 0x0F);
2131 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i
, enc
, enc
);
2135 vnc_desktop_resize(vs
);
2136 check_pointer_type_change(&vs
->mouse_mode_notifier
, NULL
);
2137 vnc_led_state_change(vs
);
2140 static void set_pixel_conversion(VncState
*vs
)
2142 pixman_format_code_t fmt
= qemu_pixman_get_format(&vs
->client_pf
);
2144 if (fmt
== VNC_SERVER_FB_FORMAT
) {
2145 vs
->write_pixels
= vnc_write_pixels_copy
;
2146 vnc_hextile_set_pixel_conversion(vs
, 0);
2148 vs
->write_pixels
= vnc_write_pixels_generic
;
2149 vnc_hextile_set_pixel_conversion(vs
, 1);
2153 static void set_pixel_format(VncState
*vs
,
2154 int bits_per_pixel
, int depth
,
2155 int big_endian_flag
, int true_color_flag
,
2156 int red_max
, int green_max
, int blue_max
,
2157 int red_shift
, int green_shift
, int blue_shift
)
2159 if (!true_color_flag
) {
2160 vnc_client_error(vs
);
2164 switch (bits_per_pixel
) {
2170 vnc_client_error(vs
);
2174 vs
->client_pf
.rmax
= red_max
;
2175 vs
->client_pf
.rbits
= hweight_long(red_max
);
2176 vs
->client_pf
.rshift
= red_shift
;
2177 vs
->client_pf
.rmask
= red_max
<< red_shift
;
2178 vs
->client_pf
.gmax
= green_max
;
2179 vs
->client_pf
.gbits
= hweight_long(green_max
);
2180 vs
->client_pf
.gshift
= green_shift
;
2181 vs
->client_pf
.gmask
= green_max
<< green_shift
;
2182 vs
->client_pf
.bmax
= blue_max
;
2183 vs
->client_pf
.bbits
= hweight_long(blue_max
);
2184 vs
->client_pf
.bshift
= blue_shift
;
2185 vs
->client_pf
.bmask
= blue_max
<< blue_shift
;
2186 vs
->client_pf
.bits_per_pixel
= bits_per_pixel
;
2187 vs
->client_pf
.bytes_per_pixel
= bits_per_pixel
/ 8;
2188 vs
->client_pf
.depth
= bits_per_pixel
== 32 ? 24 : bits_per_pixel
;
2189 vs
->client_be
= big_endian_flag
;
2191 set_pixel_conversion(vs
);
2193 graphic_hw_invalidate(vs
->vd
->dcl
.con
);
2194 graphic_hw_update(vs
->vd
->dcl
.con
);
2197 static void pixel_format_message (VncState
*vs
) {
2198 char pad
[3] = { 0, 0, 0 };
2200 vs
->client_pf
= qemu_default_pixelformat(32);
2202 vnc_write_u8(vs
, vs
->client_pf
.bits_per_pixel
); /* bits-per-pixel */
2203 vnc_write_u8(vs
, vs
->client_pf
.depth
); /* depth */
2205 #ifdef HOST_WORDS_BIGENDIAN
2206 vnc_write_u8(vs
, 1); /* big-endian-flag */
2208 vnc_write_u8(vs
, 0); /* big-endian-flag */
2210 vnc_write_u8(vs
, 1); /* true-color-flag */
2211 vnc_write_u16(vs
, vs
->client_pf
.rmax
); /* red-max */
2212 vnc_write_u16(vs
, vs
->client_pf
.gmax
); /* green-max */
2213 vnc_write_u16(vs
, vs
->client_pf
.bmax
); /* blue-max */
2214 vnc_write_u8(vs
, vs
->client_pf
.rshift
); /* red-shift */
2215 vnc_write_u8(vs
, vs
->client_pf
.gshift
); /* green-shift */
2216 vnc_write_u8(vs
, vs
->client_pf
.bshift
); /* blue-shift */
2217 vnc_write(vs
, pad
, 3); /* padding */
2219 vnc_hextile_set_pixel_conversion(vs
, 0);
2220 vs
->write_pixels
= vnc_write_pixels_copy
;
2223 static void vnc_colordepth(VncState
*vs
)
2225 if (vnc_has_feature(vs
, VNC_FEATURE_WMVI
)) {
2226 /* Sending a WMVi message to notify the client*/
2227 vnc_lock_output(vs
);
2228 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2229 vnc_write_u8(vs
, 0);
2230 vnc_write_u16(vs
, 1); /* number of rects */
2231 vnc_framebuffer_update(vs
, 0, 0,
2232 pixman_image_get_width(vs
->vd
->server
),
2233 pixman_image_get_height(vs
->vd
->server
),
2235 pixel_format_message(vs
);
2236 vnc_unlock_output(vs
);
2239 set_pixel_conversion(vs
);
2243 static int protocol_client_msg(VncState
*vs
, uint8_t *data
, size_t len
)
2247 VncDisplay
*vd
= vs
->vd
;
2250 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2254 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT
:
2258 set_pixel_format(vs
, read_u8(data
, 4), read_u8(data
, 5),
2259 read_u8(data
, 6), read_u8(data
, 7),
2260 read_u16(data
, 8), read_u16(data
, 10),
2261 read_u16(data
, 12), read_u8(data
, 14),
2262 read_u8(data
, 15), read_u8(data
, 16));
2264 case VNC_MSG_CLIENT_SET_ENCODINGS
:
2269 limit
= read_u16(data
, 2);
2271 return 4 + (limit
* 4);
2273 limit
= read_u16(data
, 2);
2275 for (i
= 0; i
< limit
; i
++) {
2276 int32_t val
= read_s32(data
, 4 + (i
* 4));
2277 memcpy(data
+ 4 + (i
* 4), &val
, sizeof(val
));
2280 set_encodings(vs
, (int32_t *)(data
+ 4), limit
);
2282 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST
:
2286 framebuffer_update_request(vs
,
2287 read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4),
2288 read_u16(data
, 6), read_u16(data
, 8));
2290 case VNC_MSG_CLIENT_KEY_EVENT
:
2294 key_event(vs
, read_u8(data
, 1), read_u32(data
, 4));
2296 case VNC_MSG_CLIENT_POINTER_EVENT
:
2300 pointer_event(vs
, read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4));
2302 case VNC_MSG_CLIENT_CUT_TEXT
:
2307 uint32_t dlen
= read_u32(data
, 4);
2308 if (dlen
> (1 << 20)) {
2309 error_report("vnc: client_cut_text msg payload has %u bytes"
2310 " which exceeds our limit of 1MB.", dlen
);
2311 vnc_client_error(vs
);
2319 client_cut_text(vs
, read_u32(data
, 4), data
+ 8);
2321 case VNC_MSG_CLIENT_QEMU
:
2325 switch (read_u8(data
, 1)) {
2326 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT
:
2330 ext_key_event(vs
, read_u16(data
, 2),
2331 read_u32(data
, 4), read_u32(data
, 8));
2333 case VNC_MSG_CLIENT_QEMU_AUDIO
:
2337 switch (read_u16 (data
, 2)) {
2338 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE
:
2341 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE
:
2344 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT
:
2347 switch (read_u8(data
, 4)) {
2348 case 0: vs
->as
.fmt
= AUD_FMT_U8
; break;
2349 case 1: vs
->as
.fmt
= AUD_FMT_S8
; break;
2350 case 2: vs
->as
.fmt
= AUD_FMT_U16
; break;
2351 case 3: vs
->as
.fmt
= AUD_FMT_S16
; break;
2352 case 4: vs
->as
.fmt
= AUD_FMT_U32
; break;
2353 case 5: vs
->as
.fmt
= AUD_FMT_S32
; break;
2355 VNC_DEBUG("Invalid audio format %d\n", read_u8(data
, 4));
2356 vnc_client_error(vs
);
2359 vs
->as
.nchannels
= read_u8(data
, 5);
2360 if (vs
->as
.nchannels
!= 1 && vs
->as
.nchannels
!= 2) {
2361 VNC_DEBUG("Invalid audio channel coount %d\n",
2363 vnc_client_error(vs
);
2366 vs
->as
.freq
= read_u32(data
, 6);
2369 VNC_DEBUG("Invalid audio message %d\n", read_u8(data
, 4));
2370 vnc_client_error(vs
);
2376 VNC_DEBUG("Msg: %d\n", read_u16(data
, 0));
2377 vnc_client_error(vs
);
2382 VNC_DEBUG("Msg: %d\n", data
[0]);
2383 vnc_client_error(vs
);
2387 vnc_read_when(vs
, protocol_client_msg
, 1);
2391 static int protocol_client_init(VncState
*vs
, uint8_t *data
, size_t len
)
2397 mode
= data
[0] ? VNC_SHARE_MODE_SHARED
: VNC_SHARE_MODE_EXCLUSIVE
;
2398 switch (vs
->vd
->share_policy
) {
2399 case VNC_SHARE_POLICY_IGNORE
:
2401 * Ignore the shared flag. Nothing to do here.
2403 * Doesn't conform to the rfb spec but is traditional qemu
2404 * behavior, thus left here as option for compatibility
2408 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
:
2410 * Policy: Allow clients ask for exclusive access.
2412 * Implementation: When a client asks for exclusive access,
2413 * disconnect all others. Shared connects are allowed as long
2414 * as no exclusive connection exists.
2416 * This is how the rfb spec suggests to handle the shared flag.
2418 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2420 QTAILQ_FOREACH(client
, &vs
->vd
->clients
, next
) {
2424 if (client
->share_mode
!= VNC_SHARE_MODE_EXCLUSIVE
&&
2425 client
->share_mode
!= VNC_SHARE_MODE_SHARED
) {
2428 vnc_disconnect_start(client
);
2431 if (mode
== VNC_SHARE_MODE_SHARED
) {
2432 if (vs
->vd
->num_exclusive
> 0) {
2433 vnc_disconnect_start(vs
);
2438 case VNC_SHARE_POLICY_FORCE_SHARED
:
2440 * Policy: Shared connects only.
2441 * Implementation: Disallow clients asking for exclusive access.
2443 * Useful for shared desktop sessions where you don't want
2444 * someone forgetting to say -shared when running the vnc
2445 * client disconnect everybody else.
2447 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2448 vnc_disconnect_start(vs
);
2453 vnc_set_share_mode(vs
, mode
);
2455 if (vs
->vd
->num_shared
> vs
->vd
->connections_limit
) {
2456 vnc_disconnect_start(vs
);
2460 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
2461 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
2462 vnc_write_u16(vs
, vs
->client_width
);
2463 vnc_write_u16(vs
, vs
->client_height
);
2465 pixel_format_message(vs
);
2468 size
= snprintf(buf
, sizeof(buf
), "QEMU (%s)", qemu_name
);
2470 size
= snprintf(buf
, sizeof(buf
), "QEMU");
2472 vnc_write_u32(vs
, size
);
2473 vnc_write(vs
, buf
, size
);
2476 vnc_client_cache_auth(vs
);
2477 vnc_qmp_event(vs
, QAPI_EVENT_VNC_INITIALIZED
);
2479 vnc_read_when(vs
, protocol_client_msg
, 1);
2484 void start_client_init(VncState
*vs
)
2486 vnc_read_when(vs
, protocol_client_init
, 1);
2489 static void make_challenge(VncState
*vs
)
2493 srand(time(NULL
)+getpid()+getpid()*987654+rand());
2495 for (i
= 0 ; i
< sizeof(vs
->challenge
) ; i
++)
2496 vs
->challenge
[i
] = (int) (256.0*rand()/(RAND_MAX
+1.0));
2499 static int protocol_client_auth_vnc(VncState
*vs
, uint8_t *data
, size_t len
)
2501 unsigned char response
[VNC_AUTH_CHALLENGE_SIZE
];
2503 unsigned char key
[8];
2504 time_t now
= time(NULL
);
2505 QCryptoCipher
*cipher
= NULL
;
2508 if (!vs
->vd
->password
) {
2509 VNC_DEBUG("No password configured on server");
2512 if (vs
->vd
->expires
< now
) {
2513 VNC_DEBUG("Password is expired");
2517 memcpy(response
, vs
->challenge
, VNC_AUTH_CHALLENGE_SIZE
);
2519 /* Calculate the expected challenge response */
2520 pwlen
= strlen(vs
->vd
->password
);
2521 for (i
=0; i
<sizeof(key
); i
++)
2522 key
[i
] = i
<pwlen
? vs
->vd
->password
[i
] : 0;
2524 cipher
= qcrypto_cipher_new(
2525 QCRYPTO_CIPHER_ALG_DES_RFB
,
2526 QCRYPTO_CIPHER_MODE_ECB
,
2527 key
, G_N_ELEMENTS(key
),
2530 VNC_DEBUG("Cannot initialize cipher %s",
2531 error_get_pretty(err
));
2536 if (qcrypto_cipher_encrypt(cipher
,
2539 VNC_AUTH_CHALLENGE_SIZE
,
2541 VNC_DEBUG("Cannot encrypt challenge %s",
2542 error_get_pretty(err
));
2547 /* Compare expected vs actual challenge response */
2548 if (memcmp(response
, data
, VNC_AUTH_CHALLENGE_SIZE
) != 0) {
2549 VNC_DEBUG("Client challenge response did not match\n");
2552 VNC_DEBUG("Accepting VNC challenge response\n");
2553 vnc_write_u32(vs
, 0); /* Accept auth */
2556 start_client_init(vs
);
2559 qcrypto_cipher_free(cipher
);
2563 vnc_write_u32(vs
, 1); /* Reject auth */
2564 if (vs
->minor
>= 8) {
2565 static const char err
[] = "Authentication failed";
2566 vnc_write_u32(vs
, sizeof(err
));
2567 vnc_write(vs
, err
, sizeof(err
));
2570 vnc_client_error(vs
);
2571 qcrypto_cipher_free(cipher
);
2575 void start_auth_vnc(VncState
*vs
)
2578 /* Send client a 'random' challenge */
2579 vnc_write(vs
, vs
->challenge
, sizeof(vs
->challenge
));
2582 vnc_read_when(vs
, protocol_client_auth_vnc
, sizeof(vs
->challenge
));
2586 static int protocol_client_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2588 /* We only advertise 1 auth scheme at a time, so client
2589 * must pick the one we sent. Verify this */
2590 if (data
[0] != vs
->auth
) { /* Reject auth */
2591 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data
[0]);
2592 vnc_write_u32(vs
, 1);
2593 if (vs
->minor
>= 8) {
2594 static const char err
[] = "Authentication failed";
2595 vnc_write_u32(vs
, sizeof(err
));
2596 vnc_write(vs
, err
, sizeof(err
));
2598 vnc_client_error(vs
);
2599 } else { /* Accept requested auth */
2600 VNC_DEBUG("Client requested auth %d\n", (int)data
[0]);
2603 VNC_DEBUG("Accept auth none\n");
2604 if (vs
->minor
>= 8) {
2605 vnc_write_u32(vs
, 0); /* Accept auth completion */
2608 start_client_init(vs
);
2612 VNC_DEBUG("Start VNC auth\n");
2616 case VNC_AUTH_VENCRYPT
:
2617 VNC_DEBUG("Accept VeNCrypt auth\n");
2618 start_auth_vencrypt(vs
);
2621 #ifdef CONFIG_VNC_SASL
2623 VNC_DEBUG("Accept SASL auth\n");
2624 start_auth_sasl(vs
);
2626 #endif /* CONFIG_VNC_SASL */
2628 default: /* Should not be possible, but just in case */
2629 VNC_DEBUG("Reject auth %d server code bug\n", vs
->auth
);
2630 vnc_write_u8(vs
, 1);
2631 if (vs
->minor
>= 8) {
2632 static const char err
[] = "Authentication failed";
2633 vnc_write_u32(vs
, sizeof(err
));
2634 vnc_write(vs
, err
, sizeof(err
));
2636 vnc_client_error(vs
);
2642 static int protocol_version(VncState
*vs
, uint8_t *version
, size_t len
)
2646 memcpy(local
, version
, 12);
2649 if (sscanf(local
, "RFB %03d.%03d\n", &vs
->major
, &vs
->minor
) != 2) {
2650 VNC_DEBUG("Malformed protocol version %s\n", local
);
2651 vnc_client_error(vs
);
2654 VNC_DEBUG("Client request protocol version %d.%d\n", vs
->major
, vs
->minor
);
2655 if (vs
->major
!= 3 ||
2661 VNC_DEBUG("Unsupported client version\n");
2662 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2664 vnc_client_error(vs
);
2667 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2668 * as equivalent to v3.3 by servers
2670 if (vs
->minor
== 4 || vs
->minor
== 5)
2673 if (vs
->minor
== 3) {
2674 if (vs
->auth
== VNC_AUTH_NONE
) {
2675 VNC_DEBUG("Tell client auth none\n");
2676 vnc_write_u32(vs
, vs
->auth
);
2678 start_client_init(vs
);
2679 } else if (vs
->auth
== VNC_AUTH_VNC
) {
2680 VNC_DEBUG("Tell client VNC auth\n");
2681 vnc_write_u32(vs
, vs
->auth
);
2685 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs
->auth
);
2686 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2688 vnc_client_error(vs
);
2691 VNC_DEBUG("Telling client we support auth %d\n", vs
->auth
);
2692 vnc_write_u8(vs
, 1); /* num auth */
2693 vnc_write_u8(vs
, vs
->auth
);
2694 vnc_read_when(vs
, protocol_client_auth
, 1);
2701 static VncRectStat
*vnc_stat_rect(VncDisplay
*vd
, int x
, int y
)
2703 struct VncSurface
*vs
= &vd
->guest
;
2705 return &vs
->stats
[y
/ VNC_STAT_RECT
][x
/ VNC_STAT_RECT
];
2708 void vnc_sent_lossy_rect(VncState
*vs
, int x
, int y
, int w
, int h
)
2712 w
= (x
+ w
) / VNC_STAT_RECT
;
2713 h
= (y
+ h
) / VNC_STAT_RECT
;
2717 for (j
= y
; j
<= h
; j
++) {
2718 for (i
= x
; i
<= w
; i
++) {
2719 vs
->lossy_rect
[j
][i
] = 1;
2724 static int vnc_refresh_lossy_rect(VncDisplay
*vd
, int x
, int y
)
2727 int sty
= y
/ VNC_STAT_RECT
;
2728 int stx
= x
/ VNC_STAT_RECT
;
2731 y
= y
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2732 x
= x
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2734 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2737 /* kernel send buffers are full -> refresh later */
2738 if (vs
->output
.offset
) {
2742 if (!vs
->lossy_rect
[sty
][stx
]) {
2746 vs
->lossy_rect
[sty
][stx
] = 0;
2747 for (j
= 0; j
< VNC_STAT_RECT
; ++j
) {
2748 bitmap_set(vs
->dirty
[y
+ j
],
2749 x
/ VNC_DIRTY_PIXELS_PER_BIT
,
2750 VNC_STAT_RECT
/ VNC_DIRTY_PIXELS_PER_BIT
);
2758 static int vnc_update_stats(VncDisplay
*vd
, struct timeval
* tv
)
2760 int width
= pixman_image_get_width(vd
->guest
.fb
);
2761 int height
= pixman_image_get_height(vd
->guest
.fb
);
2766 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2767 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2768 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2770 rect
->updated
= false;
2774 qemu_timersub(tv
, &VNC_REFRESH_STATS
, &res
);
2776 if (timercmp(&vd
->guest
.last_freq_check
, &res
, >)) {
2779 vd
->guest
.last_freq_check
= *tv
;
2781 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2782 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2783 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2784 int count
= ARRAY_SIZE(rect
->times
);
2785 struct timeval min
, max
;
2787 if (!timerisset(&rect
->times
[count
- 1])) {
2791 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2792 qemu_timersub(tv
, &max
, &res
);
2794 if (timercmp(&res
, &VNC_REFRESH_LOSSY
, >)) {
2796 has_dirty
+= vnc_refresh_lossy_rect(vd
, x
, y
);
2797 memset(rect
->times
, 0, sizeof (rect
->times
));
2801 min
= rect
->times
[rect
->idx
];
2802 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2803 qemu_timersub(&max
, &min
, &res
);
2805 rect
->freq
= res
.tv_sec
+ res
.tv_usec
/ 1000000.;
2806 rect
->freq
/= count
;
2807 rect
->freq
= 1. / rect
->freq
;
2813 double vnc_update_freq(VncState
*vs
, int x
, int y
, int w
, int h
)
2819 x
= (x
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2820 y
= (y
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2822 for (j
= y
; j
<= y
+ h
; j
+= VNC_STAT_RECT
) {
2823 for (i
= x
; i
<= x
+ w
; i
+= VNC_STAT_RECT
) {
2824 total
+= vnc_stat_rect(vs
->vd
, i
, j
)->freq
;
2836 static void vnc_rect_updated(VncDisplay
*vd
, int x
, int y
, struct timeval
* tv
)
2840 rect
= vnc_stat_rect(vd
, x
, y
);
2841 if (rect
->updated
) {
2844 rect
->times
[rect
->idx
] = *tv
;
2845 rect
->idx
= (rect
->idx
+ 1) % ARRAY_SIZE(rect
->times
);
2846 rect
->updated
= true;
2849 static int vnc_refresh_server_surface(VncDisplay
*vd
)
2851 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2852 pixman_image_get_width(vd
->server
));
2853 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2854 pixman_image_get_height(vd
->server
));
2855 int cmp_bytes
, server_stride
, line_bytes
, guest_ll
, guest_stride
, y
= 0;
2856 uint8_t *guest_row0
= NULL
, *server_row0
;
2859 pixman_image_t
*tmpbuf
= NULL
;
2861 struct timeval tv
= { 0, 0 };
2863 if (!vd
->non_adaptive
) {
2864 gettimeofday(&tv
, NULL
);
2865 has_dirty
= vnc_update_stats(vd
, &tv
);
2869 * Walk through the guest dirty map.
2870 * Check and copy modified bits from guest to server surface.
2871 * Update server dirty map.
2873 server_row0
= (uint8_t *)pixman_image_get_data(vd
->server
);
2874 server_stride
= guest_stride
= guest_ll
=
2875 pixman_image_get_stride(vd
->server
);
2876 cmp_bytes
= MIN(VNC_DIRTY_PIXELS_PER_BIT
* VNC_SERVER_FB_BYTES
,
2878 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2879 int width
= pixman_image_get_width(vd
->server
);
2880 tmpbuf
= qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT
, width
);
2883 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd
->guest
.fb
));
2884 guest_row0
= (uint8_t *)pixman_image_get_data(vd
->guest
.fb
);
2885 guest_stride
= pixman_image_get_stride(vd
->guest
.fb
);
2886 guest_ll
= pixman_image_get_width(vd
->guest
.fb
) * ((guest_bpp
+ 7) / 8);
2888 line_bytes
= MIN(server_stride
, guest_ll
);
2892 uint8_t *guest_ptr
, *server_ptr
;
2893 unsigned long offset
= find_next_bit((unsigned long *) &vd
->guest
.dirty
,
2894 height
* VNC_DIRTY_BPL(&vd
->guest
),
2895 y
* VNC_DIRTY_BPL(&vd
->guest
));
2896 if (offset
== height
* VNC_DIRTY_BPL(&vd
->guest
)) {
2897 /* no more dirty bits */
2900 y
= offset
/ VNC_DIRTY_BPL(&vd
->guest
);
2901 x
= offset
% VNC_DIRTY_BPL(&vd
->guest
);
2903 server_ptr
= server_row0
+ y
* server_stride
+ x
* cmp_bytes
;
2905 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2906 qemu_pixman_linebuf_fill(tmpbuf
, vd
->guest
.fb
, width
, 0, y
);
2907 guest_ptr
= (uint8_t *)pixman_image_get_data(tmpbuf
);
2909 guest_ptr
= guest_row0
+ y
* guest_stride
;
2911 guest_ptr
+= x
* cmp_bytes
;
2913 for (; x
< DIV_ROUND_UP(width
, VNC_DIRTY_PIXELS_PER_BIT
);
2914 x
++, guest_ptr
+= cmp_bytes
, server_ptr
+= cmp_bytes
) {
2915 int _cmp_bytes
= cmp_bytes
;
2916 if (!test_and_clear_bit(x
, vd
->guest
.dirty
[y
])) {
2919 if ((x
+ 1) * cmp_bytes
> line_bytes
) {
2920 _cmp_bytes
= line_bytes
- x
* cmp_bytes
;
2922 assert(_cmp_bytes
>= 0);
2923 if (memcmp(server_ptr
, guest_ptr
, _cmp_bytes
) == 0) {
2926 memcpy(server_ptr
, guest_ptr
, _cmp_bytes
);
2927 if (!vd
->non_adaptive
) {
2928 vnc_rect_updated(vd
, x
* VNC_DIRTY_PIXELS_PER_BIT
,
2931 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2932 set_bit(x
, vs
->dirty
[y
]);
2939 qemu_pixman_image_unref(tmpbuf
);
2943 static void vnc_refresh(DisplayChangeListener
*dcl
)
2945 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
2947 int has_dirty
, rects
= 0;
2949 if (QTAILQ_EMPTY(&vd
->clients
)) {
2950 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_MAX
);
2954 graphic_hw_update(vd
->dcl
.con
);
2956 if (vnc_trylock_display(vd
)) {
2957 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2961 has_dirty
= vnc_refresh_server_surface(vd
);
2962 vnc_unlock_display(vd
);
2964 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
2965 rects
+= vnc_update_client(vs
, has_dirty
, false);
2966 /* vs might be free()ed here */
2969 if (has_dirty
&& rects
) {
2970 vd
->dcl
.update_interval
/= 2;
2971 if (vd
->dcl
.update_interval
< VNC_REFRESH_INTERVAL_BASE
) {
2972 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_BASE
;
2975 vd
->dcl
.update_interval
+= VNC_REFRESH_INTERVAL_INC
;
2976 if (vd
->dcl
.update_interval
> VNC_REFRESH_INTERVAL_MAX
) {
2977 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_MAX
;
2982 static void vnc_connect(VncDisplay
*vd
, int csock
,
2983 bool skipauth
, bool websocket
)
2985 VncState
*vs
= g_new0(VncState
, 1);
2992 vs
->auth
= VNC_AUTH_NONE
;
2993 vs
->subauth
= VNC_AUTH_INVALID
;
2996 vs
->auth
= vd
->ws_auth
;
2997 vs
->subauth
= VNC_AUTH_INVALID
;
2999 vs
->auth
= vd
->auth
;
3000 vs
->subauth
= vd
->subauth
;
3003 VNC_DEBUG("Client sock=%d ws=%d auth=%d subauth=%d\n",
3004 csock
, websocket
, vs
->auth
, vs
->subauth
);
3006 vs
->lossy_rect
= g_malloc0(VNC_STAT_ROWS
* sizeof (*vs
->lossy_rect
));
3007 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
3008 vs
->lossy_rect
[i
] = g_new0(uint8_t, VNC_STAT_COLS
);
3011 VNC_DEBUG("New client on socket %d\n", csock
);
3012 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
3013 qemu_set_nonblock(vs
->csock
);
3017 qemu_set_fd_handler(vs
->csock
, vncws_tls_handshake_io
, NULL
, vs
);
3019 qemu_set_fd_handler(vs
->csock
, vncws_handshake_read
, NULL
, vs
);
3023 qemu_set_fd_handler(vs
->csock
, vnc_client_read
, NULL
, vs
);
3026 vnc_client_cache_addr(vs
);
3027 vnc_qmp_event(vs
, QAPI_EVENT_VNC_CONNECTED
);
3028 vnc_set_share_mode(vs
, VNC_SHARE_MODE_CONNECTING
);
3030 if (!vs
->websocket
) {
3034 if (vd
->num_connecting
> vd
->connections_limit
) {
3035 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
3036 if (vs
->share_mode
== VNC_SHARE_MODE_CONNECTING
) {
3037 vnc_disconnect_start(vs
);
3044 void vnc_init_state(VncState
*vs
)
3046 vs
->initialized
= true;
3047 VncDisplay
*vd
= vs
->vd
;
3052 vs
->as
.freq
= 44100;
3053 vs
->as
.nchannels
= 2;
3054 vs
->as
.fmt
= AUD_FMT_S16
;
3055 vs
->as
.endianness
= 0;
3057 qemu_mutex_init(&vs
->output_mutex
);
3058 vs
->bh
= qemu_bh_new(vnc_jobs_bh
, vs
);
3060 QTAILQ_INSERT_TAIL(&vd
->clients
, vs
, next
);
3062 graphic_hw_update(vd
->dcl
.con
);
3064 vnc_write(vs
, "RFB 003.008\n", 12);
3066 vnc_read_when(vs
, protocol_version
, 12);
3068 if (vs
->vd
->lock_key_sync
)
3069 vs
->led
= qemu_add_led_event_handler(kbd_leds
, vs
);
3071 vs
->mouse_mode_notifier
.notify
= check_pointer_type_change
;
3072 qemu_add_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
3074 /* vs might be free()ed here */
3077 static void vnc_listen_read(void *opaque
, bool websocket
)
3079 VncDisplay
*vs
= opaque
;
3080 struct sockaddr_in addr
;
3081 socklen_t addrlen
= sizeof(addr
);
3085 graphic_hw_update(vs
->dcl
.con
);
3087 csock
= qemu_accept(vs
->lwebsock
, (struct sockaddr
*)&addr
, &addrlen
);
3089 csock
= qemu_accept(vs
->lsock
, (struct sockaddr
*)&addr
, &addrlen
);
3093 socket_set_nodelay(csock
);
3094 vnc_connect(vs
, csock
, false, websocket
);
3098 static void vnc_listen_regular_read(void *opaque
)
3100 vnc_listen_read(opaque
, false);
3103 static void vnc_listen_websocket_read(void *opaque
)
3105 vnc_listen_read(opaque
, true);
3108 static const DisplayChangeListenerOps dcl_ops
= {
3110 .dpy_refresh
= vnc_refresh
,
3111 .dpy_gfx_copy
= vnc_dpy_copy
,
3112 .dpy_gfx_update
= vnc_dpy_update
,
3113 .dpy_gfx_switch
= vnc_dpy_switch
,
3114 .dpy_gfx_check_format
= qemu_pixman_check_format
,
3115 .dpy_mouse_set
= vnc_mouse_set
,
3116 .dpy_cursor_define
= vnc_dpy_cursor_define
,
3119 void vnc_display_init(const char *id
)
3123 if (vnc_display_find(id
) != NULL
) {
3126 vs
= g_malloc0(sizeof(*vs
));
3128 vs
->id
= strdup(id
);
3129 QTAILQ_INSERT_TAIL(&vnc_displays
, vs
, next
);
3134 QTAILQ_INIT(&vs
->clients
);
3135 vs
->expires
= TIME_MAX
;
3137 if (keyboard_layout
) {
3138 trace_vnc_key_map_init(keyboard_layout
);
3139 vs
->kbd_layout
= init_keyboard_layout(name2keysym
, keyboard_layout
);
3141 vs
->kbd_layout
= init_keyboard_layout(name2keysym
, "en-us");
3144 if (!vs
->kbd_layout
)
3147 qemu_mutex_init(&vs
->mutex
);
3148 vnc_start_worker_thread();
3150 vs
->dcl
.ops
= &dcl_ops
;
3151 register_displaychangelistener(&vs
->dcl
);
3155 static void vnc_display_close(VncDisplay
*vs
)
3159 vs
->enabled
= false;
3160 vs
->is_unix
= false;
3161 if (vs
->lsock
!= -1) {
3162 qemu_set_fd_handler(vs
->lsock
, NULL
, NULL
, NULL
);
3166 vs
->ws_enabled
= false;
3167 if (vs
->lwebsock
!= -1) {
3168 qemu_set_fd_handler(vs
->lwebsock
, NULL
, NULL
, NULL
);
3169 close(vs
->lwebsock
);
3172 vs
->auth
= VNC_AUTH_INVALID
;
3173 vs
->subauth
= VNC_AUTH_INVALID
;
3175 object_unparent(OBJECT(vs
->tlscreds
));
3177 g_free(vs
->tlsaclname
);
3178 vs
->tlsaclname
= NULL
;
3181 int vnc_display_password(const char *id
, const char *password
)
3183 VncDisplay
*vs
= vnc_display_find(id
);
3188 if (vs
->auth
== VNC_AUTH_NONE
) {
3189 error_printf_unless_qmp("If you want use passwords please enable "
3190 "password auth using '-vnc ${dpy},password'.");
3194 g_free(vs
->password
);
3195 vs
->password
= g_strdup(password
);
3200 int vnc_display_pw_expire(const char *id
, time_t expires
)
3202 VncDisplay
*vs
= vnc_display_find(id
);
3208 vs
->expires
= expires
;
3212 char *vnc_display_local_addr(const char *id
)
3214 VncDisplay
*vs
= vnc_display_find(id
);
3217 return vnc_socket_local_addr("%s:%s", vs
->lsock
);
3220 static QemuOptsList qemu_vnc_opts
= {
3222 .head
= QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts
.head
),
3223 .implied_opt_name
= "vnc",
3227 .type
= QEMU_OPT_STRING
,
3229 .name
= "websocket",
3230 .type
= QEMU_OPT_STRING
,
3232 .name
= "tls-creds",
3233 .type
= QEMU_OPT_STRING
,
3235 /* Deprecated in favour of tls-creds */
3237 .type
= QEMU_OPT_STRING
,
3240 .type
= QEMU_OPT_STRING
,
3243 .type
= QEMU_OPT_STRING
,
3246 .type
= QEMU_OPT_NUMBER
,
3248 .name
= "connections",
3249 .type
= QEMU_OPT_NUMBER
,
3252 .type
= QEMU_OPT_NUMBER
,
3255 .type
= QEMU_OPT_BOOL
,
3258 .type
= QEMU_OPT_BOOL
,
3261 .type
= QEMU_OPT_BOOL
,
3264 .type
= QEMU_OPT_BOOL
,
3266 .name
= "lock-key-sync",
3267 .type
= QEMU_OPT_BOOL
,
3270 .type
= QEMU_OPT_BOOL
,
3272 /* Deprecated in favour of tls-creds */
3274 .type
= QEMU_OPT_BOOL
,
3276 /* Deprecated in favour of tls-creds */
3277 .name
= "x509verify",
3278 .type
= QEMU_OPT_STRING
,
3281 .type
= QEMU_OPT_BOOL
,
3284 .type
= QEMU_OPT_BOOL
,
3286 .name
= "non-adaptive",
3287 .type
= QEMU_OPT_BOOL
,
3289 { /* end of list */ }
3295 vnc_display_setup_auth(VncDisplay
*vs
,
3302 * We have a choice of 3 authentication options
3308 * The channel can be run in 2 modes
3313 * And TLS can use 2 types of credentials
3318 * We thus have 9 possible logical combinations
3323 * 4. tls + anon + none
3324 * 5. tls + anon + vnc
3325 * 6. tls + anon + sasl
3326 * 7. tls + x509 + none
3327 * 8. tls + x509 + vnc
3328 * 9. tls + x509 + sasl
3330 * These need to be mapped into the VNC auth schemes
3331 * in an appropriate manner. In regular VNC, all the
3332 * TLS options get mapped into VNC_AUTH_VENCRYPT
3335 * In websockets, the https:// protocol already provides
3336 * TLS support, so there is no need to make use of the
3337 * VeNCrypt extension. Furthermore, websockets browser
3338 * clients could not use VeNCrypt even if they wanted to,
3339 * as they cannot control when the TLS handshake takes
3340 * place. Thus there is no option but to rely on https://,
3341 * meaning combinations 4->6 and 7->9 will be mapped to
3342 * VNC auth schemes in the same way as combos 1->3.
3344 * Regardless of fact that we have a different mapping to
3345 * VNC auth mechs for plain VNC vs websockets VNC, the end
3346 * result has the same security characteristics.
3350 vs
->auth
= VNC_AUTH_VENCRYPT
;
3354 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3355 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3356 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3357 vs
->subauth
= VNC_AUTH_VENCRYPT_X509VNC
;
3358 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3359 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3360 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3361 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSVNC
;
3364 "Unsupported TLS cred type %s",
3365 object_get_typename(OBJECT(vs
->tlscreds
)));
3369 VNC_DEBUG("Initializing VNC server with password auth\n");
3370 vs
->auth
= VNC_AUTH_VNC
;
3371 vs
->subauth
= VNC_AUTH_INVALID
;
3374 vs
->ws_auth
= VNC_AUTH_VNC
;
3376 vs
->ws_auth
= VNC_AUTH_INVALID
;
3380 vs
->auth
= VNC_AUTH_VENCRYPT
;
3384 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3385 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3386 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3387 vs
->subauth
= VNC_AUTH_VENCRYPT_X509SASL
;
3388 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3389 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3390 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3391 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSSASL
;
3394 "Unsupported TLS cred type %s",
3395 object_get_typename(OBJECT(vs
->tlscreds
)));
3399 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3400 vs
->auth
= VNC_AUTH_SASL
;
3401 vs
->subauth
= VNC_AUTH_INVALID
;
3404 vs
->ws_auth
= VNC_AUTH_SASL
;
3406 vs
->ws_auth
= VNC_AUTH_INVALID
;
3410 vs
->auth
= VNC_AUTH_VENCRYPT
;
3414 if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3415 TYPE_QCRYPTO_TLS_CREDS_X509
)) {
3416 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3417 vs
->subauth
= VNC_AUTH_VENCRYPT_X509NONE
;
3418 } else if (object_dynamic_cast(OBJECT(vs
->tlscreds
),
3419 TYPE_QCRYPTO_TLS_CREDS_ANON
)) {
3420 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3421 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSNONE
;
3424 "Unsupported TLS cred type %s",
3425 object_get_typename(OBJECT(vs
->tlscreds
)));
3429 VNC_DEBUG("Initializing VNC server with no auth\n");
3430 vs
->auth
= VNC_AUTH_NONE
;
3431 vs
->subauth
= VNC_AUTH_INVALID
;
3434 vs
->ws_auth
= VNC_AUTH_NONE
;
3436 vs
->ws_auth
= VNC_AUTH_INVALID
;
3444 * Handle back compat with old CLI syntax by creating some
3445 * suitable QCryptoTLSCreds objects
3447 static QCryptoTLSCreds
*
3448 vnc_display_create_creds(bool x509
,
3454 gchar
*credsid
= g_strdup_printf("tlsvnc%s", id
);
3455 Object
*parent
= object_get_objects_root();
3460 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509
,
3464 "endpoint", "server",
3466 "verify-peer", x509verify
? "yes" : "no",
3469 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON
,
3473 "endpoint", "server",
3480 error_propagate(errp
, err
);
3484 return QCRYPTO_TLS_CREDS(creds
);
3488 void vnc_display_open(const char *id
, Error
**errp
)
3490 VncDisplay
*vs
= vnc_display_find(id
);
3491 QemuOpts
*opts
= qemu_opts_find(&qemu_vnc_opts
, id
);
3492 SocketAddress
*saddr
= NULL
, *wsaddr
= NULL
;
3493 const char *share
, *device_id
;
3495 bool password
= false;
3496 bool reverse
= false;
3501 #ifdef CONFIG_VNC_SASL
3505 int lock_key_sync
= 1;
3508 error_setg(errp
, "VNC display not active");
3511 vnc_display_close(vs
);
3516 vnc
= qemu_opt_get(opts
, "vnc");
3517 if (!vnc
|| strcmp(vnc
, "none") == 0) {
3521 h
= strrchr(vnc
, ':');
3523 size_t hlen
= h
- vnc
;
3525 const char *websocket
= qemu_opt_get(opts
, "websocket");
3526 int to
= qemu_opt_get_number(opts
, "to", 0);
3527 bool has_ipv4
= qemu_opt_get_bool(opts
, "ipv4", false);
3528 bool has_ipv6
= qemu_opt_get_bool(opts
, "ipv6", false);
3530 saddr
= g_new0(SocketAddress
, 1);
3532 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1
)) {
3534 "SHA1 hash support is required for websockets");
3538 wsaddr
= g_new0(SocketAddress
, 1);
3539 vs
->ws_enabled
= true;
3542 if (strncmp(vnc
, "unix:", 5) == 0) {
3543 saddr
->type
= SOCKET_ADDRESS_KIND_UNIX
;
3544 saddr
->u
.q_unix
= g_new0(UnixSocketAddress
, 1);
3545 saddr
->u
.q_unix
->path
= g_strdup(vnc
+ 5);
3547 if (vs
->ws_enabled
) {
3548 error_setg(errp
, "UNIX sockets not supported with websock");
3552 unsigned long long baseport
;
3553 saddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3554 saddr
->u
.inet
= g_new0(InetSocketAddress
, 1);
3555 if (vnc
[0] == '[' && vnc
[hlen
- 1] == ']') {
3556 saddr
->u
.inet
->host
= g_strndup(vnc
+ 1, hlen
- 2);
3558 saddr
->u
.inet
->host
= g_strndup(vnc
, hlen
);
3560 if (parse_uint_full(h
+ 1, &baseport
, 10) < 0) {
3561 error_setg(errp
, "can't convert to a number: %s", h
+ 1);
3564 if (baseport
> 65535 ||
3565 baseport
+ 5900 > 65535) {
3566 error_setg(errp
, "port %s out of range", h
+ 1);
3569 saddr
->u
.inet
->port
= g_strdup_printf(
3570 "%d", (int)baseport
+ 5900);
3573 saddr
->u
.inet
->has_to
= true;
3574 saddr
->u
.inet
->to
= to
;
3575 saddr
->u
.inet
->has_to
= true;
3576 saddr
->u
.inet
->to
= to
+ 5900;
3578 saddr
->u
.inet
->ipv4
= saddr
->u
.inet
->has_ipv4
= has_ipv4
;
3579 saddr
->u
.inet
->ipv6
= saddr
->u
.inet
->has_ipv6
= has_ipv6
;
3581 if (vs
->ws_enabled
) {
3582 wsaddr
->type
= SOCKET_ADDRESS_KIND_INET
;
3583 wsaddr
->u
.inet
= g_new0(InetSocketAddress
, 1);
3584 wsaddr
->u
.inet
->host
= g_strdup(saddr
->u
.inet
->host
);
3585 wsaddr
->u
.inet
->port
= g_strdup(websocket
);
3588 wsaddr
->u
.inet
->has_to
= true;
3589 wsaddr
->u
.inet
->to
= to
;
3591 wsaddr
->u
.inet
->ipv4
= wsaddr
->u
.inet
->has_ipv4
= has_ipv4
;
3592 wsaddr
->u
.inet
->ipv6
= wsaddr
->u
.inet
->has_ipv6
= has_ipv6
;
3596 error_setg(errp
, "no vnc port specified");
3600 password
= qemu_opt_get_bool(opts
, "password", false);
3602 if (fips_get_state()) {
3604 "VNC password auth disabled due to FIPS mode, "
3605 "consider using the VeNCrypt or SASL authentication "
3606 "methods as an alternative");
3609 if (!qcrypto_cipher_supports(
3610 QCRYPTO_CIPHER_ALG_DES_RFB
)) {
3612 "Cipher backend does not support DES RFB algorithm");
3617 reverse
= qemu_opt_get_bool(opts
, "reverse", false);
3618 lock_key_sync
= qemu_opt_get_bool(opts
, "lock-key-sync", true);
3619 sasl
= qemu_opt_get_bool(opts
, "sasl", false);
3620 #ifndef CONFIG_VNC_SASL
3622 error_setg(errp
, "VNC SASL auth requires cyrus-sasl support");
3625 #endif /* CONFIG_VNC_SASL */
3626 credid
= qemu_opt_get(opts
, "tls-creds");
3629 if (qemu_opt_get(opts
, "tls") ||
3630 qemu_opt_get(opts
, "x509") ||
3631 qemu_opt_get(opts
, "x509verify")) {
3633 "'credid' parameter is mutually exclusive with "
3634 "'tls', 'x509' and 'x509verify' parameters");
3638 creds
= object_resolve_path_component(
3639 object_get_objects_root(), credid
);
3641 error_setg(errp
, "No TLS credentials with id '%s'",
3645 vs
->tlscreds
= (QCryptoTLSCreds
*)
3646 object_dynamic_cast(creds
,
3647 TYPE_QCRYPTO_TLS_CREDS
);
3648 if (!vs
->tlscreds
) {
3649 error_setg(errp
, "Object with id '%s' is not TLS credentials",
3653 object_ref(OBJECT(vs
->tlscreds
));
3655 if (vs
->tlscreds
->endpoint
!= QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
) {
3657 "Expecting TLS credentials with a server endpoint");
3662 bool tls
= false, x509
= false, x509verify
= false;
3663 tls
= qemu_opt_get_bool(opts
, "tls", false);
3665 path
= qemu_opt_get(opts
, "x509");
3670 path
= qemu_opt_get(opts
, "x509verify");
3676 vs
->tlscreds
= vnc_display_create_creds(x509
,
3681 if (!vs
->tlscreds
) {
3686 acl
= qemu_opt_get_bool(opts
, "acl", false);
3688 share
= qemu_opt_get(opts
, "share");
3690 if (strcmp(share
, "ignore") == 0) {
3691 vs
->share_policy
= VNC_SHARE_POLICY_IGNORE
;
3692 } else if (strcmp(share
, "allow-exclusive") == 0) {
3693 vs
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3694 } else if (strcmp(share
, "force-shared") == 0) {
3695 vs
->share_policy
= VNC_SHARE_POLICY_FORCE_SHARED
;
3697 error_setg(errp
, "unknown vnc share= option");
3701 vs
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3703 vs
->connections_limit
= qemu_opt_get_number(opts
, "connections", 32);
3705 #ifdef CONFIG_VNC_JPEG
3706 vs
->lossy
= qemu_opt_get_bool(opts
, "lossy", false);
3708 vs
->non_adaptive
= qemu_opt_get_bool(opts
, "non-adaptive", false);
3709 /* adaptive updates are only used with tight encoding and
3710 * if lossy updates are enabled so we can disable all the
3711 * calculations otherwise */
3713 vs
->non_adaptive
= true;
3717 if (strcmp(vs
->id
, "default") == 0) {
3718 vs
->tlsaclname
= g_strdup("vnc.x509dname");
3720 vs
->tlsaclname
= g_strdup_printf("vnc.%s.x509dname", vs
->id
);
3722 qemu_acl_init(vs
->tlsaclname
);
3724 #ifdef CONFIG_VNC_SASL
3728 if (strcmp(vs
->id
, "default") == 0) {
3729 aclname
= g_strdup("vnc.username");
3731 aclname
= g_strdup_printf("vnc.%s.username", vs
->id
);
3733 vs
->sasl
.acl
= qemu_acl_init(aclname
);
3738 if (vnc_display_setup_auth(vs
, password
, sasl
, vs
->ws_enabled
, errp
) < 0) {
3742 #ifdef CONFIG_VNC_SASL
3743 if ((saslErr
= sasl_server_init(NULL
, "qemu")) != SASL_OK
) {
3744 error_setg(errp
, "Failed to initialize SASL auth: %s",
3745 sasl_errstring(saslErr
, NULL
, NULL
));
3749 vs
->lock_key_sync
= lock_key_sync
;
3751 device_id
= qemu_opt_get(opts
, "display");
3754 int head
= qemu_opt_get_number(opts
, "head", 0);
3756 dev
= qdev_find_recursive(sysbus_get_default(), device_id
);
3758 error_setg(errp
, "Device '%s' not found", device_id
);
3762 con
= qemu_console_lookup_by_device(dev
, head
);
3764 error_setg(errp
, "Device %s is not bound to a QemuConsole",
3772 if (con
!= vs
->dcl
.con
) {
3773 unregister_displaychangelistener(&vs
->dcl
);
3775 register_displaychangelistener(&vs
->dcl
);
3779 /* connect to viewer */
3783 if (vs
->ws_enabled
) {
3784 error_setg(errp
, "Cannot use websockets in reverse mode");
3787 csock
= socket_connect(saddr
, errp
, NULL
, NULL
);
3791 vs
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3792 vnc_connect(vs
, csock
, false, false);
3794 /* listen for connects */
3795 vs
->lsock
= socket_listen(saddr
, errp
);
3796 if (vs
->lsock
< 0) {
3799 vs
->is_unix
= saddr
->type
== SOCKET_ADDRESS_KIND_UNIX
;
3800 if (vs
->ws_enabled
) {
3801 vs
->lwebsock
= socket_listen(wsaddr
, errp
);
3802 if (vs
->lwebsock
< 0) {
3803 if (vs
->lsock
!= -1) {
3811 qemu_set_fd_handler(vs
->lsock
, vnc_listen_regular_read
, NULL
, vs
);
3812 if (vs
->ws_enabled
) {
3813 qemu_set_fd_handler(vs
->lwebsock
, vnc_listen_websocket_read
,
3818 qapi_free_SocketAddress(saddr
);
3819 qapi_free_SocketAddress(wsaddr
);
3823 qapi_free_SocketAddress(saddr
);
3824 qapi_free_SocketAddress(wsaddr
);
3825 vs
->enabled
= false;
3826 vs
->ws_enabled
= false;
3829 void vnc_display_add_client(const char *id
, int csock
, bool skipauth
)
3831 VncDisplay
*vs
= vnc_display_find(id
);
3836 vnc_connect(vs
, csock
, skipauth
, false);
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_report("Failed to start VNC server: %s",
3880 error_get_pretty(local_err
));
3881 error_free(local_err
);
3887 static void vnc_register_config(void)
3889 qemu_add_opts(&qemu_vnc_opts
);
3891 machine_init(vnc_register_config
);