]> git.proxmox.com Git - mirror_qemu.git/blame - ui/vnc.c
vnc: add a way to get the update frequency for a given region
[mirror_qemu.git] / ui / vnc.c
CommitLineData
7d510b8c
FB
1/*
2 * QEMU VNC display driver
5fafdf24 3 *
7d510b8c
FB
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
19a490bf 6 * Copyright (C) 2009 Red Hat, Inc
5fafdf24 7 *
7d510b8c
FB
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:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
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
24 * THE SOFTWARE.
25 */
26
19a490bf 27#include "vnc.h"
bd023f95 28#include "vnc-jobs.h"
87ecb68b 29#include "sysemu.h"
6ca957f0 30#include "qemu_socket.h"
87ecb68b 31#include "qemu-timer.h"
76655d6d 32#include "acl.h"
d96fd29c 33#include "qemu-objects.h"
24236869 34
2430ffe4
SS
35#define VNC_REFRESH_INTERVAL_BASE 30
36#define VNC_REFRESH_INTERVAL_INC 50
37#define VNC_REFRESH_INTERVAL_MAX 2000
999342a0
CC
38static const struct timeval VNC_REFRESH_STATS = { 0, 500000 };
39static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
24236869
FB
40
41#include "vnc_keysym.h"
70848515
TS
42#include "d3des.h"
43
90a1e3c0
AL
44#define count_bits(c, v) { \
45 for (c = 0; v; v >>= 1) \
46 { \
47 c += v & 1; \
48 } \
49}
8d5d2d4c 50
753b4053 51static VncDisplay *vnc_display; /* needed for info vnc */
7d957bd8 52static DisplayChangeListener *dcl;
a9ce8590 53
d467b679
GH
54static int vnc_cursor_define(VncState *vs);
55
1ff7df1a
AL
56static char *addr_to_string(const char *format,
57 struct sockaddr_storage *sa,
58 socklen_t salen) {
59 char *addr;
60 char host[NI_MAXHOST];
61 char serv[NI_MAXSERV];
62 int err;
457772e6 63 size_t addrlen;
1ff7df1a
AL
64
65 if ((err = getnameinfo((struct sockaddr *)sa, salen,
66 host, sizeof(host),
67 serv, sizeof(serv),
68 NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
69 VNC_DEBUG("Cannot resolve address %d: %s\n",
70 err, gai_strerror(err));
71 return NULL;
72 }
73
457772e6 74 /* Enough for the existing format + the 2 vars we're
f425c278 75 * substituting in. */
457772e6
AL
76 addrlen = strlen(format) + strlen(host) + strlen(serv);
77 addr = qemu_malloc(addrlen + 1);
78 snprintf(addr, addrlen, format, host, serv);
79 addr[addrlen] = '\0';
1ff7df1a
AL
80
81 return addr;
82}
83
2f9606b3
AL
84
85char *vnc_socket_local_addr(const char *format, int fd) {
1ff7df1a
AL
86 struct sockaddr_storage sa;
87 socklen_t salen;
88
89 salen = sizeof(sa);
90 if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0)
91 return NULL;
92
93 return addr_to_string(format, &sa, salen);
94}
95
2f9606b3 96char *vnc_socket_remote_addr(const char *format, int fd) {
1ff7df1a
AL
97 struct sockaddr_storage sa;
98 socklen_t salen;
99
100 salen = sizeof(sa);
101 if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0)
102 return NULL;
103
104 return addr_to_string(format, &sa, salen);
105}
106
d96fd29c
LC
107static int put_addr_qdict(QDict *qdict, struct sockaddr_storage *sa,
108 socklen_t salen)
109{
110 char host[NI_MAXHOST];
111 char serv[NI_MAXSERV];
112 int err;
113
114 if ((err = getnameinfo((struct sockaddr *)sa, salen,
115 host, sizeof(host),
116 serv, sizeof(serv),
117 NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
118 VNC_DEBUG("Cannot resolve address %d: %s\n",
119 err, gai_strerror(err));
120 return -1;
121 }
122
123 qdict_put(qdict, "host", qstring_from_str(host));
124 qdict_put(qdict, "service", qstring_from_str(serv));
dc0d4efc 125 qdict_put(qdict, "family",qstring_from_str(inet_strfamily(sa->ss_family)));
d96fd29c
LC
126
127 return 0;
128}
129
a7789382 130static int vnc_server_addr_put(QDict *qdict, int fd)
d96fd29c
LC
131{
132 struct sockaddr_storage sa;
133 socklen_t salen;
134
135 salen = sizeof(sa);
136 if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0) {
137 return -1;
138 }
139
140 return put_addr_qdict(qdict, &sa, salen);
141}
142
143static int vnc_qdict_remote_addr(QDict *qdict, int fd)
144{
145 struct sockaddr_storage sa;
146 socklen_t salen;
147
148 salen = sizeof(sa);
149 if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0) {
150 return -1;
151 }
152
153 return put_addr_qdict(qdict, &sa, salen);
154}
155
1ff7df1a
AL
156static const char *vnc_auth_name(VncDisplay *vd) {
157 switch (vd->auth) {
158 case VNC_AUTH_INVALID:
159 return "invalid";
160 case VNC_AUTH_NONE:
161 return "none";
162 case VNC_AUTH_VNC:
163 return "vnc";
164 case VNC_AUTH_RA2:
165 return "ra2";
166 case VNC_AUTH_RA2NE:
167 return "ra2ne";
168 case VNC_AUTH_TIGHT:
169 return "tight";
170 case VNC_AUTH_ULTRA:
171 return "ultra";
172 case VNC_AUTH_TLS:
173 return "tls";
174 case VNC_AUTH_VENCRYPT:
175#ifdef CONFIG_VNC_TLS
176 switch (vd->subauth) {
177 case VNC_AUTH_VENCRYPT_PLAIN:
178 return "vencrypt+plain";
179 case VNC_AUTH_VENCRYPT_TLSNONE:
180 return "vencrypt+tls+none";
181 case VNC_AUTH_VENCRYPT_TLSVNC:
182 return "vencrypt+tls+vnc";
183 case VNC_AUTH_VENCRYPT_TLSPLAIN:
184 return "vencrypt+tls+plain";
185 case VNC_AUTH_VENCRYPT_X509NONE:
186 return "vencrypt+x509+none";
187 case VNC_AUTH_VENCRYPT_X509VNC:
188 return "vencrypt+x509+vnc";
189 case VNC_AUTH_VENCRYPT_X509PLAIN:
190 return "vencrypt+x509+plain";
28a76be8
AL
191 case VNC_AUTH_VENCRYPT_TLSSASL:
192 return "vencrypt+tls+sasl";
193 case VNC_AUTH_VENCRYPT_X509SASL:
194 return "vencrypt+x509+sasl";
1ff7df1a
AL
195 default:
196 return "vencrypt";
197 }
198#else
199 return "vencrypt";
200#endif
2f9606b3 201 case VNC_AUTH_SASL:
28a76be8 202 return "sasl";
1ff7df1a
AL
203 }
204 return "unknown";
205}
206
a7789382
LC
207static int vnc_server_info_put(QDict *qdict)
208{
209 if (vnc_server_addr_put(qdict, vnc_display->lsock) < 0) {
210 return -1;
211 }
212
213 qdict_put(qdict, "auth", qstring_from_str(vnc_auth_name(vnc_display)));
214 return 0;
215}
216
4a80dba3 217static void vnc_client_cache_auth(VncState *client)
1ff7df1a 218{
2ded6ad7 219#if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
d96fd29c 220 QDict *qdict;
2ded6ad7 221#endif
1ff7df1a 222
4a80dba3
LC
223 if (!client->info) {
224 return;
d96fd29c 225 }
1263b7d6 226
2ded6ad7 227#if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
4a80dba3 228 qdict = qobject_to_qdict(client->info);
2ded6ad7 229#endif
4a80dba3 230
1263b7d6
AL
231#ifdef CONFIG_VNC_TLS
232 if (client->tls.session &&
d96fd29c
LC
233 client->tls.dname) {
234 qdict_put(qdict, "x509_dname", qstring_from_str(client->tls.dname));
235 }
1263b7d6
AL
236#endif
237#ifdef CONFIG_VNC_SASL
238 if (client->sasl.conn &&
d96fd29c 239 client->sasl.username) {
76825067
LC
240 qdict_put(qdict, "sasl_username",
241 qstring_from_str(client->sasl.username));
d96fd29c 242 }
1263b7d6 243#endif
4a80dba3 244}
d96fd29c 245
4a80dba3
LC
246static void vnc_client_cache_addr(VncState *client)
247{
248 QDict *qdict;
249
250 qdict = qdict_new();
251 if (vnc_qdict_remote_addr(qdict, client->csock) < 0) {
252 QDECREF(qdict);
253 /* XXX: how to report the error? */
254 return;
255 }
256
257 client->info = QOBJECT(qdict);
1ff7df1a
AL
258}
259
586153d9
LC
260static void vnc_qmp_event(VncState *vs, MonitorEvent event)
261{
262 QDict *server;
263 QObject *data;
264
265 if (!vs->info) {
266 return;
267 }
268
269 server = qdict_new();
270 if (vnc_server_info_put(server) < 0) {
271 QDECREF(server);
272 return;
273 }
274
275 data = qobject_from_jsonf("{ 'client': %p, 'server': %p }",
276 vs->info, QOBJECT(server));
277
278 monitor_protocol_event(event, data);
279
280 qobject_incref(vs->info);
281 qobject_decref(data);
282}
283
d96fd29c 284static void info_vnc_iter(QObject *obj, void *opaque)
a9ce8590 285{
d96fd29c
LC
286 QDict *client;
287 Monitor *mon = opaque;
288
289 client = qobject_to_qdict(obj);
290 monitor_printf(mon, "Client:\n");
291 monitor_printf(mon, " address: %s:%s\n",
292 qdict_get_str(client, "host"),
293 qdict_get_str(client, "service"));
294
295#ifdef CONFIG_VNC_TLS
296 monitor_printf(mon, " x509_dname: %s\n",
297 qdict_haskey(client, "x509_dname") ?
298 qdict_get_str(client, "x509_dname") : "none");
299#endif
300#ifdef CONFIG_VNC_SASL
301 monitor_printf(mon, " username: %s\n",
76825067
LC
302 qdict_haskey(client, "sasl_username") ?
303 qdict_get_str(client, "sasl_username") : "none");
d96fd29c
LC
304#endif
305}
306
307void do_info_vnc_print(Monitor *mon, const QObject *data)
308{
309 QDict *server;
310 QList *clients;
311
312 server = qobject_to_qdict(data);
8950a950 313 if (qdict_get_bool(server, "enabled") == 0) {
1ff7df1a 314 monitor_printf(mon, "Server: disabled\n");
d96fd29c
LC
315 return;
316 }
1ff7df1a 317
d96fd29c
LC
318 monitor_printf(mon, "Server:\n");
319 monitor_printf(mon, " address: %s:%s\n",
320 qdict_get_str(server, "host"),
321 qdict_get_str(server, "service"));
a7789382 322 monitor_printf(mon, " auth: %s\n", qdict_get_str(server, "auth"));
d96fd29c
LC
323
324 clients = qdict_get_qlist(server, "clients");
325 if (qlist_empty(clients)) {
326 monitor_printf(mon, "Client: none\n");
327 } else {
328 qlist_iter(clients, info_vnc_iter, mon);
329 }
330}
1ff7df1a 331
d96fd29c
LC
332void do_info_vnc(Monitor *mon, QObject **ret_data)
333{
334 if (vnc_display == NULL || vnc_display->display == NULL) {
8950a950 335 *ret_data = qobject_from_jsonf("{ 'enabled': false }");
d96fd29c 336 } else {
d96fd29c 337 QList *clist;
41b4bef6 338 VncState *client;
1ff7df1a 339
d96fd29c 340 clist = qlist_new();
41b4bef6
AS
341 QTAILQ_FOREACH(client, &vnc_display->clients, next) {
342 if (client->info) {
343 /* incref so that it's not freed by upper layers */
344 qobject_incref(client->info);
345 qlist_append_obj(clist, client->info);
1ff7df1a 346 }
d96fd29c
LC
347 }
348
8950a950 349 *ret_data = qobject_from_jsonf("{ 'enabled': true, 'clients': %p }",
d96fd29c
LC
350 QOBJECT(clist));
351 assert(*ret_data != NULL);
352
a7789382 353 if (vnc_server_info_put(qobject_to_qdict(*ret_data)) < 0) {
d96fd29c
LC
354 qobject_decref(*ret_data);
355 *ret_data = NULL;
1ff7df1a 356 }
a9ce8590
FB
357 }
358}
359
24236869
FB
360/* TODO
361 1) Get the queue working for IO.
362 2) there is some weirdness when using the -S option (the screen is grey
363 and not totally invalidated
364 3) resolutions > 1024
365*/
366
2430ffe4 367static int vnc_update_client(VncState *vs, int has_dirty);
bd023f95 368static int vnc_update_client_sync(VncState *vs, int has_dirty);
198a0039
GH
369static void vnc_disconnect_start(VncState *vs);
370static void vnc_disconnect_finish(VncState *vs);
703bc68f
SS
371static void vnc_init_timer(VncDisplay *vd);
372static void vnc_remove_timer(VncDisplay *vd);
24236869 373
753b4053 374static void vnc_colordepth(VncState *vs);
1fc62412
SS
375static void framebuffer_update_request(VncState *vs, int incremental,
376 int x_position, int y_position,
377 int w, int h);
378static void vnc_refresh(void *opaque);
379static int vnc_refresh_server_surface(VncDisplay *vd);
7eac3a87 380
99589bdc
FB
381static inline void vnc_set_bit(uint32_t *d, int k)
382{
383 d[k >> 5] |= 1 << (k & 0x1f);
384}
385
386static inline void vnc_clear_bit(uint32_t *d, int k)
387{
388 d[k >> 5] &= ~(1 << (k & 0x1f));
389}
390
391static inline void vnc_set_bits(uint32_t *d, int n, int nb_words)
392{
393 int j;
394
395 j = 0;
396 while (n >= 32) {
397 d[j++] = -1;
398 n -= 32;
399 }
5fafdf24 400 if (n > 0)
99589bdc
FB
401 d[j++] = (1 << n) - 1;
402 while (j < nb_words)
403 d[j++] = 0;
404}
405
406static inline int vnc_get_bit(const uint32_t *d, int k)
407{
408 return (d[k >> 5] >> (k & 0x1f)) & 1;
409}
410
5fafdf24 411static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2,
99589bdc
FB
412 int nb_words)
413{
414 int i;
415 for(i = 0; i < nb_words; i++) {
416 if ((d1[i] & d2[i]) != 0)
417 return 1;
418 }
419 return 0;
420}
421
1fc62412 422static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
24236869 423{
24236869 424 int i;
1fc62412
SS
425 VncDisplay *vd = ds->opaque;
426 struct VncSurface *s = &vd->guest;
24236869
FB
427
428 h += y;
429
0486e8a7
AZ
430 /* round x down to ensure the loop only spans one 16-pixel block per,
431 iteration. otherwise, if (x % 16) != 0, the last iteration may span
432 two 16-pixel blocks but we only mark the first as dirty
433 */
434 w += (x % 16);
435 x -= (x % 16);
436
6baebed7
AL
437 x = MIN(x, s->ds->width);
438 y = MIN(y, s->ds->height);
439 w = MIN(x + w, s->ds->width) - x;
440 h = MIN(h, s->ds->height);
788abf8e 441
24236869 442 for (; y < h; y++)
28a76be8 443 for (i = 0; i < w; i += 16)
6baebed7 444 vnc_set_bit(s->dirty[y], (x + i) / 16);
24236869
FB
445}
446
70a4568f
CC
447void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
448 int32_t encoding)
24236869
FB
449{
450 vnc_write_u16(vs, x);
451 vnc_write_u16(vs, y);
452 vnc_write_u16(vs, w);
453 vnc_write_u16(vs, h);
454
455 vnc_write_s32(vs, encoding);
456}
457
2f9606b3 458void buffer_reserve(Buffer *buffer, size_t len)
89064286
AL
459{
460 if ((buffer->capacity - buffer->offset) < len) {
28a76be8
AL
461 buffer->capacity += (len + 1024);
462 buffer->buffer = qemu_realloc(buffer->buffer, buffer->capacity);
463 if (buffer->buffer == NULL) {
464 fprintf(stderr, "vnc: out of memory\n");
465 exit(1);
466 }
89064286
AL
467 }
468}
469
2f9606b3 470int buffer_empty(Buffer *buffer)
89064286
AL
471{
472 return buffer->offset == 0;
473}
474
2f9606b3 475uint8_t *buffer_end(Buffer *buffer)
89064286
AL
476{
477 return buffer->buffer + buffer->offset;
478}
479
2f9606b3 480void buffer_reset(Buffer *buffer)
89064286 481{
28a76be8 482 buffer->offset = 0;
89064286
AL
483}
484
5d418e3b
CC
485void buffer_free(Buffer *buffer)
486{
487 qemu_free(buffer->buffer);
488 buffer->offset = 0;
489 buffer->capacity = 0;
490 buffer->buffer = NULL;
491}
492
2f9606b3 493void buffer_append(Buffer *buffer, const void *data, size_t len)
89064286
AL
494{
495 memcpy(buffer->buffer + buffer->offset, data, len);
496 buffer->offset += len;
497}
498
621aaeb9
GH
499static void vnc_desktop_resize(VncState *vs)
500{
501 DisplayState *ds = vs->ds;
502
503 if (vs->csock == -1 || !vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
504 return;
505 }
1d4b638a
GH
506 if (vs->client_width == ds_get_width(ds) &&
507 vs->client_height == ds_get_height(ds)) {
508 return;
509 }
5862d195
GH
510 vs->client_width = ds_get_width(ds);
511 vs->client_height = ds_get_height(ds);
bd023f95 512 vnc_lock_output(vs);
621aaeb9
GH
513 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
514 vnc_write_u8(vs, 0);
515 vnc_write_u16(vs, 1); /* number of rects */
5862d195 516 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
621aaeb9 517 VNC_ENCODING_DESKTOPRESIZE);
bd023f95 518 vnc_unlock_output(vs);
621aaeb9
GH
519 vnc_flush(vs);
520}
521
bd023f95
CC
522#ifdef CONFIG_VNC_THREAD
523static void vnc_abort_display_jobs(VncDisplay *vd)
524{
525 VncState *vs;
526
527 QTAILQ_FOREACH(vs, &vd->clients, next) {
528 vnc_lock_output(vs);
529 vs->abort = true;
530 vnc_unlock_output(vs);
531 }
532 QTAILQ_FOREACH(vs, &vd->clients, next) {
533 vnc_jobs_join(vs);
534 }
535 QTAILQ_FOREACH(vs, &vd->clients, next) {
536 vnc_lock_output(vs);
537 vs->abort = false;
538 vnc_unlock_output(vs);
539 }
540}
541#else
542static void vnc_abort_display_jobs(VncDisplay *vd)
543{
544}
545#endif
546
1fc62412 547static void vnc_dpy_resize(DisplayState *ds)
24236869 548{
1fc62412 549 VncDisplay *vd = ds->opaque;
41b4bef6 550 VncState *vs;
1fc62412 551
bd023f95
CC
552 vnc_abort_display_jobs(vd);
553
1fc62412
SS
554 /* server surface */
555 if (!vd->server)
556 vd->server = qemu_mallocz(sizeof(*vd->server));
557 if (vd->server->data)
558 qemu_free(vd->server->data);
559 *(vd->server) = *(ds->surface);
560 vd->server->data = qemu_mallocz(vd->server->linesize *
561 vd->server->height);
24236869 562
6baebed7 563 /* guest surface */
1fc62412
SS
564 if (!vd->guest.ds)
565 vd->guest.ds = qemu_mallocz(sizeof(*vd->guest.ds));
566 if (ds_get_bytes_per_pixel(ds) != vd->guest.ds->pf.bytes_per_pixel)
a528b80c 567 console_color_init(ds);
1fc62412
SS
568 *(vd->guest.ds) = *(ds->surface);
569 memset(vd->guest.dirty, 0xFF, sizeof(vd->guest.dirty));
24236869 570
41b4bef6 571 QTAILQ_FOREACH(vs, &vd->clients, next) {
1fc62412 572 vnc_colordepth(vs);
1d4b638a 573 vnc_desktop_resize(vs);
d467b679
GH
574 if (vs->vd->cursor) {
575 vnc_cursor_define(vs);
576 }
1fc62412 577 memset(vs->dirty, 0xFF, sizeof(vs->dirty));
753b4053
AL
578 }
579}
580
3512779a 581/* fastest code */
d467b679
GH
582static void vnc_write_pixels_copy(VncState *vs, struct PixelFormat *pf,
583 void *pixels, int size)
3512779a
FB
584{
585 vnc_write(vs, pixels, size);
586}
587
588/* slowest but generic code. */
70a4568f 589void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
3512779a 590{
7eac3a87 591 uint8_t r, g, b;
1fc62412
SS
592 VncDisplay *vd = vs->vd;
593
594 r = ((((v & vd->server->pf.rmask) >> vd->server->pf.rshift) << vs->clientds.pf.rbits) >>
595 vd->server->pf.rbits);
596 g = ((((v & vd->server->pf.gmask) >> vd->server->pf.gshift) << vs->clientds.pf.gbits) >>
597 vd->server->pf.gbits);
598 b = ((((v & vd->server->pf.bmask) >> vd->server->pf.bshift) << vs->clientds.pf.bbits) >>
599 vd->server->pf.bbits);
6cec5487
AL
600 v = (r << vs->clientds.pf.rshift) |
601 (g << vs->clientds.pf.gshift) |
602 (b << vs->clientds.pf.bshift);
603 switch(vs->clientds.pf.bytes_per_pixel) {
3512779a
FB
604 case 1:
605 buf[0] = v;
606 break;
607 case 2:
6cec5487 608 if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) {
3512779a
FB
609 buf[0] = v >> 8;
610 buf[1] = v;
611 } else {
612 buf[1] = v >> 8;
613 buf[0] = v;
614 }
615 break;
616 default:
617 case 4:
6cec5487 618 if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) {
3512779a
FB
619 buf[0] = v >> 24;
620 buf[1] = v >> 16;
621 buf[2] = v >> 8;
622 buf[3] = v;
623 } else {
624 buf[3] = v >> 24;
625 buf[2] = v >> 16;
626 buf[1] = v >> 8;
627 buf[0] = v;
628 }
629 break;
630 }
631}
632
d467b679
GH
633static void vnc_write_pixels_generic(VncState *vs, struct PixelFormat *pf,
634 void *pixels1, int size)
3512779a 635{
3512779a 636 uint8_t buf[4];
3512779a 637
d467b679 638 if (pf->bytes_per_pixel == 4) {
7eac3a87
AL
639 uint32_t *pixels = pixels1;
640 int n, i;
641 n = size >> 2;
642 for(i = 0; i < n; i++) {
643 vnc_convert_pixel(vs, buf, pixels[i]);
6cec5487 644 vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
7eac3a87 645 }
d467b679 646 } else if (pf->bytes_per_pixel == 2) {
7eac3a87
AL
647 uint16_t *pixels = pixels1;
648 int n, i;
649 n = size >> 1;
650 for(i = 0; i < n; i++) {
651 vnc_convert_pixel(vs, buf, pixels[i]);
6cec5487 652 vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
7eac3a87 653 }
d467b679 654 } else if (pf->bytes_per_pixel == 1) {
7eac3a87
AL
655 uint8_t *pixels = pixels1;
656 int n, i;
657 n = size;
658 for(i = 0; i < n; i++) {
659 vnc_convert_pixel(vs, buf, pixels[i]);
6cec5487 660 vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
7eac3a87
AL
661 }
662 } else {
663 fprintf(stderr, "vnc_write_pixels_generic: VncState color depth not supported\n");
3512779a
FB
664 }
665}
666
a885211e 667int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
24236869
FB
668{
669 int i;
60fe76f3 670 uint8_t *row;
1fc62412 671 VncDisplay *vd = vs->vd;
24236869 672
1fc62412 673 row = vd->server->data + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds);
24236869 674 for (i = 0; i < h; i++) {
d467b679 675 vs->write_pixels(vs, &vd->server->pf, row, w * ds_get_bytes_per_pixel(vs->ds));
28a76be8 676 row += ds_get_linesize(vs->ds);
24236869 677 }
a885211e 678 return 1;
24236869
FB
679}
680
bd023f95 681int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
24236869 682{
a885211e
CC
683 int n = 0;
684
fb437313 685 switch(vs->vnc_encoding) {
28a76be8 686 case VNC_ENCODING_ZLIB:
a885211e 687 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
28a76be8
AL
688 break;
689 case VNC_ENCODING_HEXTILE:
690 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
a885211e 691 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
28a76be8 692 break;
380282b0
CC
693 case VNC_ENCODING_TIGHT:
694 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
695 break;
efe556ad
CC
696 case VNC_ENCODING_TIGHT_PNG:
697 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
698 break;
28a76be8
AL
699 default:
700 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
a885211e 701 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
28a76be8 702 break;
fb437313 703 }
a885211e 704 return n;
24236869
FB
705}
706
753b4053 707static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
24236869 708{
3e28c9ad 709 /* send bitblit op to the vnc client */
bd023f95 710 vnc_lock_output(vs);
46a183da 711 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
24236869
FB
712 vnc_write_u8(vs, 0);
713 vnc_write_u16(vs, 1); /* number of rects */
29fa4ed9 714 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
24236869
FB
715 vnc_write_u16(vs, src_x);
716 vnc_write_u16(vs, src_y);
bd023f95 717 vnc_unlock_output(vs);
24236869
FB
718 vnc_flush(vs);
719}
720
753b4053
AL
721static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
722{
723 VncDisplay *vd = ds->opaque;
198a0039 724 VncState *vs, *vn;
1fc62412
SS
725 uint8_t *src_row;
726 uint8_t *dst_row;
727 int i,x,y,pitch,depth,inc,w_lim,s;
728 int cmp_bytes;
198a0039 729
1fc62412 730 vnc_refresh_server_surface(vd);
41b4bef6 731 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
198a0039
GH
732 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
733 vs->force_update = 1;
bd023f95 734 vnc_update_client_sync(vs, 1);
198a0039
GH
735 /* vs might be free()ed here */
736 }
737 }
738
1fc62412
SS
739 /* do bitblit op on the local surface too */
740 pitch = ds_get_linesize(vd->ds);
741 depth = ds_get_bytes_per_pixel(vd->ds);
742 src_row = vd->server->data + pitch * src_y + depth * src_x;
743 dst_row = vd->server->data + pitch * dst_y + depth * dst_x;
744 y = dst_y;
745 inc = 1;
746 if (dst_y > src_y) {
747 /* copy backwards */
748 src_row += pitch * (h-1);
749 dst_row += pitch * (h-1);
750 pitch = -pitch;
751 y = dst_y + h - 1;
752 inc = -1;
753 }
754 w_lim = w - (16 - (dst_x % 16));
755 if (w_lim < 0)
756 w_lim = w;
757 else
758 w_lim = w - (w_lim % 16);
759 for (i = 0; i < h; i++) {
760 for (x = 0; x <= w_lim;
761 x += s, src_row += cmp_bytes, dst_row += cmp_bytes) {
762 if (x == w_lim) {
763 if ((s = w - w_lim) == 0)
764 break;
765 } else if (!x) {
766 s = (16 - (dst_x % 16));
767 s = MIN(s, w_lim);
768 } else {
769 s = 16;
770 }
771 cmp_bytes = s * depth;
772 if (memcmp(src_row, dst_row, cmp_bytes) == 0)
773 continue;
774 memmove(dst_row, src_row, cmp_bytes);
41b4bef6
AS
775 QTAILQ_FOREACH(vs, &vd->clients, next) {
776 if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
1fc62412 777 vnc_set_bit(vs->dirty[y], ((x + dst_x) / 16));
41b4bef6 778 }
1fc62412
SS
779 }
780 }
781 src_row += pitch - w * depth;
782 dst_row += pitch - w * depth;
783 y += inc;
784 }
785
41b4bef6
AS
786 QTAILQ_FOREACH(vs, &vd->clients, next) {
787 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
753b4053 788 vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
41b4bef6 789 }
753b4053
AL
790 }
791}
792
d467b679
GH
793static void vnc_mouse_set(int x, int y, int visible)
794{
795 /* can we ask the client(s) to move the pointer ??? */
796}
797
798static int vnc_cursor_define(VncState *vs)
799{
800 QEMUCursor *c = vs->vd->cursor;
801 PixelFormat pf = qemu_default_pixelformat(32);
802 int isize;
803
804 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
d01f9595 805 vnc_lock_output(vs);
d467b679
GH
806 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
807 vnc_write_u8(vs, 0); /* padding */
808 vnc_write_u16(vs, 1); /* # of rects */
809 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
810 VNC_ENCODING_RICH_CURSOR);
811 isize = c->width * c->height * vs->clientds.pf.bytes_per_pixel;
812 vnc_write_pixels_generic(vs, &pf, c->data, isize);
813 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
d01f9595 814 vnc_unlock_output(vs);
d467b679
GH
815 return 0;
816 }
817 return -1;
818}
819
820static void vnc_dpy_cursor_define(QEMUCursor *c)
821{
822 VncDisplay *vd = vnc_display;
823 VncState *vs;
824
825 cursor_put(vd->cursor);
826 qemu_free(vd->cursor_mask);
827
828 vd->cursor = c;
829 cursor_get(vd->cursor);
830 vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
831 vd->cursor_mask = qemu_mallocz(vd->cursor_msize);
832 cursor_get_mono_mask(c, 0, vd->cursor_mask);
833
834 QTAILQ_FOREACH(vs, &vd->clients, next) {
835 vnc_cursor_define(vs);
836 }
837}
838
1fc62412 839static int find_and_clear_dirty_height(struct VncState *vs,
6baebed7 840 int y, int last_x, int x)
24236869
FB
841{
842 int h;
1fc62412 843 VncDisplay *vd = vs->vd;
24236869 844
1fc62412 845 for (h = 1; h < (vd->server->height - y); h++) {
28a76be8 846 int tmp_x;
1fc62412 847 if (!vnc_get_bit(vs->dirty[y + h], last_x))
28a76be8
AL
848 break;
849 for (tmp_x = last_x; tmp_x < x; tmp_x++)
1fc62412 850 vnc_clear_bit(vs->dirty[y + h], tmp_x);
24236869
FB
851 }
852
853 return h;
854}
855
bd023f95
CC
856#ifdef CONFIG_VNC_THREAD
857static int vnc_update_client_sync(VncState *vs, int has_dirty)
858{
859 int ret = vnc_update_client(vs, has_dirty);
860 vnc_jobs_join(vs);
861 return ret;
862}
863#else
864static int vnc_update_client_sync(VncState *vs, int has_dirty)
865{
866 return vnc_update_client(vs, has_dirty);
867}
868#endif
869
2430ffe4 870static int vnc_update_client(VncState *vs, int has_dirty)
24236869 871{
24236869 872 if (vs->need_update && vs->csock != -1) {
1fc62412 873 VncDisplay *vd = vs->vd;
bd023f95 874 VncJob *job;
28a76be8 875 int y;
847ce6a1 876 int width, height;
bd023f95
CC
877 int n = 0;
878
24236869 879
703bc68f 880 if (vs->output.offset && !vs->audio_cap && !vs->force_update)
c522d0e2 881 /* kernel send buffers are full -> drop frames to throttle */
2430ffe4 882 return 0;
a0ecfb73 883
703bc68f 884 if (!has_dirty && !vs->audio_cap && !vs->force_update)
2430ffe4 885 return 0;
28a76be8 886
6baebed7
AL
887 /*
888 * Send screen updates to the vnc client using the server
889 * surface and server dirty map. guest surface updates
890 * happening in parallel don't disturb us, the next pass will
891 * send them to the client.
892 */
bd023f95 893 job = vnc_job_new(vs);
28a76be8 894
847ce6a1
GH
895 width = MIN(vd->server->width, vs->client_width);
896 height = MIN(vd->server->height, vs->client_height);
897
898 for (y = 0; y < height; y++) {
28a76be8
AL
899 int x;
900 int last_x = -1;
847ce6a1 901 for (x = 0; x < width / 16; x++) {
1fc62412 902 if (vnc_get_bit(vs->dirty[y], x)) {
28a76be8
AL
903 if (last_x == -1) {
904 last_x = x;
905 }
1fc62412 906 vnc_clear_bit(vs->dirty[y], x);
28a76be8
AL
907 } else {
908 if (last_x != -1) {
1fc62412 909 int h = find_and_clear_dirty_height(vs, y, last_x, x);
bd023f95
CC
910
911 n += vnc_job_add_rect(job, last_x * 16, y,
912 (x - last_x) * 16, h);
28a76be8
AL
913 }
914 last_x = -1;
915 }
916 }
917 if (last_x != -1) {
1fc62412 918 int h = find_and_clear_dirty_height(vs, y, last_x, x);
bd023f95
CC
919 n += vnc_job_add_rect(job, last_x * 16, y,
920 (x - last_x) * 16, h);
28a76be8
AL
921 }
922 }
bd023f95
CC
923
924 vnc_job_push(job);
c522d0e2 925 vs->force_update = 0;
bd023f95 926 return n;
24236869 927 }
24236869 928
703bc68f 929 if (vs->csock == -1)
198a0039 930 vnc_disconnect_finish(vs);
2430ffe4
SS
931
932 return 0;
24236869
FB
933}
934
429a8ed3 935/* audio */
936static void audio_capture_notify(void *opaque, audcnotification_e cmd)
937{
938 VncState *vs = opaque;
939
940 switch (cmd) {
941 case AUD_CNOTIFY_DISABLE:
bd023f95 942 vnc_lock_output(vs);
46a183da
DB
943 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
944 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
945 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
bd023f95 946 vnc_unlock_output(vs);
429a8ed3 947 vnc_flush(vs);
948 break;
949
950 case AUD_CNOTIFY_ENABLE:
bd023f95 951 vnc_lock_output(vs);
46a183da
DB
952 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
953 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
954 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
bd023f95 955 vnc_unlock_output(vs);
429a8ed3 956 vnc_flush(vs);
957 break;
958 }
959}
960
961static void audio_capture_destroy(void *opaque)
962{
963}
964
965static void audio_capture(void *opaque, void *buf, int size)
966{
967 VncState *vs = opaque;
968
bd023f95 969 vnc_lock_output(vs);
46a183da
DB
970 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
971 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
972 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
429a8ed3 973 vnc_write_u32(vs, size);
974 vnc_write(vs, buf, size);
bd023f95 975 vnc_unlock_output(vs);
429a8ed3 976 vnc_flush(vs);
977}
978
979static void audio_add(VncState *vs)
980{
981 struct audio_capture_ops ops;
982
983 if (vs->audio_cap) {
8631b608 984 monitor_printf(default_mon, "audio already running\n");
429a8ed3 985 return;
986 }
987
988 ops.notify = audio_capture_notify;
989 ops.destroy = audio_capture_destroy;
990 ops.capture = audio_capture;
991
1a7dafce 992 vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
429a8ed3 993 if (!vs->audio_cap) {
8631b608 994 monitor_printf(default_mon, "Failed to add audio capture\n");
429a8ed3 995 }
996}
997
998static void audio_del(VncState *vs)
999{
1000 if (vs->audio_cap) {
1001 AUD_del_capture(vs->audio_cap, vs);
1002 vs->audio_cap = NULL;
1003 }
1004}
1005
198a0039
GH
1006static void vnc_disconnect_start(VncState *vs)
1007{
1008 if (vs->csock == -1)
1009 return;
1010 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
1011 closesocket(vs->csock);
1012 vs->csock = -1;
1013}
1014
1015static void vnc_disconnect_finish(VncState *vs)
1016{
bd023f95
CC
1017 vnc_jobs_join(vs); /* Wait encoding jobs */
1018
1019 vnc_lock_output(vs);
0d72f3d3
LC
1020 vnc_qmp_event(vs, QEVENT_VNC_DISCONNECTED);
1021
5d418e3b
CC
1022 buffer_free(&vs->input);
1023 buffer_free(&vs->output);
4a80dba3
LC
1024
1025 qobject_decref(vs->info);
1026
161c4f20 1027 vnc_zlib_clear(vs);
380282b0 1028 vnc_tight_clear(vs);
161c4f20 1029
198a0039
GH
1030#ifdef CONFIG_VNC_TLS
1031 vnc_tls_client_cleanup(vs);
1032#endif /* CONFIG_VNC_TLS */
1033#ifdef CONFIG_VNC_SASL
1034 vnc_sasl_client_cleanup(vs);
1035#endif /* CONFIG_VNC_SASL */
1036 audio_del(vs);
1037
41b4bef6
AS
1038 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1039
1040 if (QTAILQ_EMPTY(&vs->vd->clients)) {
198a0039 1041 dcl->idle = 1;
41b4bef6 1042 }
198a0039 1043
37c34d9d 1044 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
703bc68f 1045 vnc_remove_timer(vs->vd);
3a0558b5
GH
1046 if (vs->vd->lock_key_sync)
1047 qemu_remove_led_event_handler(vs->led);
bd023f95
CC
1048 vnc_unlock_output(vs);
1049
1050#ifdef CONFIG_VNC_THREAD
1051 qemu_mutex_destroy(&vs->output_mutex);
1052#endif
5d95ac5b 1053 qemu_free(vs);
198a0039 1054}
2f9606b3
AL
1055
1056int vnc_client_io_error(VncState *vs, int ret, int last_errno)
24236869
FB
1057{
1058 if (ret == 0 || ret == -1) {
ea01e5fd
AZ
1059 if (ret == -1) {
1060 switch (last_errno) {
1061 case EINTR:
1062 case EAGAIN:
1063#ifdef _WIN32
1064 case WSAEWOULDBLOCK:
1065#endif
1066 return 0;
1067 default:
1068 break;
1069 }
1070 }
24236869 1071
198a0039
GH
1072 VNC_DEBUG("Closing down client sock: ret %d, errno %d\n",
1073 ret, ret < 0 ? last_errno : 0);
1074 vnc_disconnect_start(vs);
6baebed7 1075
28a76be8 1076 return 0;
24236869
FB
1077 }
1078 return ret;
1079}
1080
5fb6c7a8
AL
1081
1082void vnc_client_error(VncState *vs)
24236869 1083{
198a0039
GH
1084 VNC_DEBUG("Closing down client sock: protocol error\n");
1085 vnc_disconnect_start(vs);
24236869
FB
1086}
1087
2f9606b3
AL
1088
1089/*
1090 * Called to write a chunk of data to the client socket. The data may
1091 * be the raw data, or may have already been encoded by SASL.
1092 * The data will be written either straight onto the socket, or
1093 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1094 *
1095 * NB, it is theoretically possible to have 2 layers of encryption,
1096 * both SASL, and this TLS layer. It is highly unlikely in practice
1097 * though, since SASL encryption will typically be a no-op if TLS
1098 * is active
1099 *
1100 * Returns the number of bytes written, which may be less than
1101 * the requested 'datalen' if the socket would block. Returns
1102 * -1 on error, and disconnects the client socket.
1103 */
1104long vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
24236869 1105{
ceb5caaf 1106 long ret;
eb38c52c 1107#ifdef CONFIG_VNC_TLS
5fb6c7a8 1108 if (vs->tls.session) {
28a76be8
AL
1109 ret = gnutls_write(vs->tls.session, data, datalen);
1110 if (ret < 0) {
1111 if (ret == GNUTLS_E_AGAIN)
1112 errno = EAGAIN;
1113 else
1114 errno = EIO;
1115 ret = -1;
1116 }
8d5d2d4c
TS
1117 } else
1118#endif /* CONFIG_VNC_TLS */
70503264 1119 ret = send(vs->csock, (const void *)data, datalen, 0);
23decc87 1120 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
2f9606b3
AL
1121 return vnc_client_io_error(vs, ret, socket_error());
1122}
1123
1124
1125/*
1126 * Called to write buffered data to the client socket, when not
1127 * using any SASL SSF encryption layers. Will write as much data
1128 * as possible without blocking. If all buffered data is written,
1129 * will switch the FD poll() handler back to read monitoring.
1130 *
1131 * Returns the number of bytes written, which may be less than
1132 * the buffered output data if the socket would block. Returns
1133 * -1 on error, and disconnects the client socket.
1134 */
1135static long vnc_client_write_plain(VncState *vs)
1136{
1137 long ret;
1138
1139#ifdef CONFIG_VNC_SASL
23decc87 1140 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
2f9606b3
AL
1141 vs->output.buffer, vs->output.capacity, vs->output.offset,
1142 vs->sasl.waitWriteSSF);
1143
1144 if (vs->sasl.conn &&
1145 vs->sasl.runSSF &&
1146 vs->sasl.waitWriteSSF) {
1147 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1148 if (ret)
1149 vs->sasl.waitWriteSSF -= ret;
1150 } else
1151#endif /* CONFIG_VNC_SASL */
1152 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
24236869 1153 if (!ret)
2f9606b3 1154 return 0;
24236869
FB
1155
1156 memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));
1157 vs->output.offset -= ret;
1158
1159 if (vs->output.offset == 0) {
28a76be8 1160 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
24236869 1161 }
2f9606b3
AL
1162
1163 return ret;
1164}
1165
1166
1167/*
1168 * First function called whenever there is data to be written to
1169 * the client socket. Will delegate actual work according to whether
1170 * SASL SSF layers are enabled (thus requiring encryption calls)
1171 */
bd023f95 1172static void vnc_client_write_locked(void *opaque)
2f9606b3 1173{
2f9606b3
AL
1174 VncState *vs = opaque;
1175
1176#ifdef CONFIG_VNC_SASL
1177 if (vs->sasl.conn &&
1178 vs->sasl.runSSF &&
9678d950
BS
1179 !vs->sasl.waitWriteSSF) {
1180 vnc_client_write_sasl(vs);
1181 } else
2f9606b3 1182#endif /* CONFIG_VNC_SASL */
9678d950 1183 vnc_client_write_plain(vs);
24236869
FB
1184}
1185
bd023f95
CC
1186void vnc_client_write(void *opaque)
1187{
1188 VncState *vs = opaque;
1189
1190 vnc_lock_output(vs);
1191 if (vs->output.offset) {
1192 vnc_client_write_locked(opaque);
ac71103d 1193 } else if (vs->csock != -1) {
bd023f95
CC
1194 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
1195 }
1196 vnc_unlock_output(vs);
1197}
1198
5fb6c7a8 1199void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
24236869
FB
1200{
1201 vs->read_handler = func;
1202 vs->read_handler_expect = expecting;
1203}
1204
2f9606b3
AL
1205
1206/*
1207 * Called to read a chunk of data from the client socket. The data may
1208 * be the raw data, or may need to be further decoded by SASL.
1209 * The data will be read either straight from to the socket, or
1210 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1211 *
1212 * NB, it is theoretically possible to have 2 layers of encryption,
1213 * both SASL, and this TLS layer. It is highly unlikely in practice
1214 * though, since SASL encryption will typically be a no-op if TLS
1215 * is active
1216 *
1217 * Returns the number of bytes read, which may be less than
1218 * the requested 'datalen' if the socket would block. Returns
1219 * -1 on error, and disconnects the client socket.
1220 */
1221long vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
24236869 1222{
ceb5caaf 1223 long ret;
eb38c52c 1224#ifdef CONFIG_VNC_TLS
5fb6c7a8 1225 if (vs->tls.session) {
28a76be8
AL
1226 ret = gnutls_read(vs->tls.session, data, datalen);
1227 if (ret < 0) {
1228 if (ret == GNUTLS_E_AGAIN)
1229 errno = EAGAIN;
1230 else
1231 errno = EIO;
1232 ret = -1;
1233 }
8d5d2d4c
TS
1234 } else
1235#endif /* CONFIG_VNC_TLS */
c5b76b38 1236 ret = recv(vs->csock, (void *)data, datalen, 0);
23decc87 1237 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
2f9606b3
AL
1238 return vnc_client_io_error(vs, ret, socket_error());
1239}
24236869 1240
2f9606b3
AL
1241
1242/*
1243 * Called to read data from the client socket to the input buffer,
1244 * when not using any SASL SSF encryption layers. Will read as much
1245 * data as possible without blocking.
1246 *
1247 * Returns the number of bytes read. Returns -1 on error, and
1248 * disconnects the client socket.
1249 */
1250static long vnc_client_read_plain(VncState *vs)
1251{
1252 int ret;
23decc87 1253 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
2f9606b3
AL
1254 vs->input.buffer, vs->input.capacity, vs->input.offset);
1255 buffer_reserve(&vs->input, 4096);
1256 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1257 if (!ret)
1258 return 0;
24236869 1259 vs->input.offset += ret;
2f9606b3
AL
1260 return ret;
1261}
1262
1263
1264/*
1265 * First function called whenever there is more data to be read from
1266 * the client socket. Will delegate actual work according to whether
1267 * SASL SSF layers are enabled (thus requiring decryption calls)
1268 */
1269void vnc_client_read(void *opaque)
1270{
1271 VncState *vs = opaque;
1272 long ret;
1273
1274#ifdef CONFIG_VNC_SASL
1275 if (vs->sasl.conn && vs->sasl.runSSF)
1276 ret = vnc_client_read_sasl(vs);
1277 else
1278#endif /* CONFIG_VNC_SASL */
1279 ret = vnc_client_read_plain(vs);
198a0039
GH
1280 if (!ret) {
1281 if (vs->csock == -1)
1282 vnc_disconnect_finish(vs);
28a76be8 1283 return;
198a0039 1284 }
24236869
FB
1285
1286 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
28a76be8
AL
1287 size_t len = vs->read_handler_expect;
1288 int ret;
1289
1290 ret = vs->read_handler(vs, vs->input.buffer, len);
198a0039
GH
1291 if (vs->csock == -1) {
1292 vnc_disconnect_finish(vs);
28a76be8 1293 return;
198a0039 1294 }
28a76be8
AL
1295
1296 if (!ret) {
1297 memmove(vs->input.buffer, vs->input.buffer + len, (vs->input.offset - len));
1298 vs->input.offset -= len;
1299 } else {
1300 vs->read_handler_expect = ret;
1301 }
24236869
FB
1302 }
1303}
1304
5fb6c7a8 1305void vnc_write(VncState *vs, const void *data, size_t len)
24236869
FB
1306{
1307 buffer_reserve(&vs->output, len);
1308
198a0039 1309 if (vs->csock != -1 && buffer_empty(&vs->output)) {
28a76be8 1310 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
24236869
FB
1311 }
1312
1313 buffer_append(&vs->output, data, len);
1314}
1315
5fb6c7a8 1316void vnc_write_s32(VncState *vs, int32_t value)
24236869
FB
1317{
1318 vnc_write_u32(vs, *(uint32_t *)&value);
1319}
1320
5fb6c7a8 1321void vnc_write_u32(VncState *vs, uint32_t value)
24236869
FB
1322{
1323 uint8_t buf[4];
1324
1325 buf[0] = (value >> 24) & 0xFF;
1326 buf[1] = (value >> 16) & 0xFF;
1327 buf[2] = (value >> 8) & 0xFF;
1328 buf[3] = value & 0xFF;
1329
1330 vnc_write(vs, buf, 4);
1331}
1332
5fb6c7a8 1333void vnc_write_u16(VncState *vs, uint16_t value)
24236869 1334{
64f5a135 1335 uint8_t buf[2];
24236869
FB
1336
1337 buf[0] = (value >> 8) & 0xFF;
1338 buf[1] = value & 0xFF;
1339
1340 vnc_write(vs, buf, 2);
1341}
1342
5fb6c7a8 1343void vnc_write_u8(VncState *vs, uint8_t value)
24236869
FB
1344{
1345 vnc_write(vs, (char *)&value, 1);
1346}
1347
5fb6c7a8 1348void vnc_flush(VncState *vs)
24236869 1349{
bd023f95
CC
1350 vnc_lock_output(vs);
1351 if (vs->csock != -1 && vs->output.offset) {
1352 vnc_client_write_locked(vs);
1353 }
1354 vnc_unlock_output(vs);
24236869
FB
1355}
1356
5fb6c7a8 1357uint8_t read_u8(uint8_t *data, size_t offset)
24236869
FB
1358{
1359 return data[offset];
1360}
1361
5fb6c7a8 1362uint16_t read_u16(uint8_t *data, size_t offset)
24236869
FB
1363{
1364 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1365}
1366
5fb6c7a8 1367int32_t read_s32(uint8_t *data, size_t offset)
24236869
FB
1368{
1369 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
28a76be8 1370 (data[offset + 2] << 8) | data[offset + 3]);
24236869
FB
1371}
1372
5fb6c7a8 1373uint32_t read_u32(uint8_t *data, size_t offset)
24236869
FB
1374{
1375 return ((data[offset] << 24) | (data[offset + 1] << 16) |
28a76be8 1376 (data[offset + 2] << 8) | data[offset + 3]);
24236869
FB
1377}
1378
60fe76f3 1379static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
24236869
FB
1380{
1381}
1382
37c34d9d 1383static void check_pointer_type_change(Notifier *notifier)
564c337e 1384{
37c34d9d
AL
1385 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
1386 int absolute = kbd_mouse_is_absolute();
1387
29fa4ed9 1388 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
bd023f95 1389 vnc_lock_output(vs);
46a183da 1390 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
28a76be8
AL
1391 vnc_write_u8(vs, 0);
1392 vnc_write_u16(vs, 1);
1393 vnc_framebuffer_update(vs, absolute, 0,
1394 ds_get_width(vs->ds), ds_get_height(vs->ds),
29fa4ed9 1395 VNC_ENCODING_POINTER_TYPE_CHANGE);
bd023f95 1396 vnc_unlock_output(vs);
28a76be8 1397 vnc_flush(vs);
564c337e
FB
1398 }
1399 vs->absolute = absolute;
1400}
1401
24236869
FB
1402static void pointer_event(VncState *vs, int button_mask, int x, int y)
1403{
1404 int buttons = 0;
1405 int dz = 0;
1406
1407 if (button_mask & 0x01)
28a76be8 1408 buttons |= MOUSE_EVENT_LBUTTON;
24236869 1409 if (button_mask & 0x02)
28a76be8 1410 buttons |= MOUSE_EVENT_MBUTTON;
24236869 1411 if (button_mask & 0x04)
28a76be8 1412 buttons |= MOUSE_EVENT_RBUTTON;
24236869 1413 if (button_mask & 0x08)
28a76be8 1414 dz = -1;
24236869 1415 if (button_mask & 0x10)
28a76be8 1416 dz = 1;
564c337e
FB
1417
1418 if (vs->absolute) {
cc39a92c
CW
1419 kbd_mouse_event(ds_get_width(vs->ds) > 1 ?
1420 x * 0x7FFF / (ds_get_width(vs->ds) - 1) : 0x4000,
1421 ds_get_height(vs->ds) > 1 ?
1422 y * 0x7FFF / (ds_get_height(vs->ds) - 1) : 0x4000,
28a76be8 1423 dz, buttons);
29fa4ed9 1424 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
28a76be8
AL
1425 x -= 0x7FFF;
1426 y -= 0x7FFF;
24236869 1427
28a76be8 1428 kbd_mouse_event(x, y, dz, buttons);
564c337e 1429 } else {
28a76be8
AL
1430 if (vs->last_x != -1)
1431 kbd_mouse_event(x - vs->last_x,
1432 y - vs->last_y,
1433 dz, buttons);
1434 vs->last_x = x;
1435 vs->last_y = y;
24236869
FB
1436 }
1437}
1438
64f5a135
FB
1439static void reset_keys(VncState *vs)
1440{
1441 int i;
1442 for(i = 0; i < 256; i++) {
1443 if (vs->modifiers_state[i]) {
44bb61c8
ST
1444 if (i & SCANCODE_GREY)
1445 kbd_put_keycode(SCANCODE_EMUL0);
1446 kbd_put_keycode(i | SCANCODE_UP);
64f5a135
FB
1447 vs->modifiers_state[i] = 0;
1448 }
1449 }
1450}
1451
a528b80c
AZ
1452static void press_key(VncState *vs, int keysym)
1453{
44bb61c8
ST
1454 int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
1455 if (keycode & SCANCODE_GREY)
1456 kbd_put_keycode(SCANCODE_EMUL0);
1457 kbd_put_keycode(keycode & SCANCODE_KEYCODEMASK);
1458 if (keycode & SCANCODE_GREY)
1459 kbd_put_keycode(SCANCODE_EMUL0);
1460 kbd_put_keycode(keycode | SCANCODE_UP);
a528b80c
AZ
1461}
1462
7ffb82ca
GH
1463static void kbd_leds(void *opaque, int ledstate)
1464{
1465 VncState *vs = opaque;
1466 int caps, num;
1467
1468 caps = ledstate & QEMU_CAPS_LOCK_LED ? 1 : 0;
1469 num = ledstate & QEMU_NUM_LOCK_LED ? 1 : 0;
1470
1471 if (vs->modifiers_state[0x3a] != caps) {
1472 vs->modifiers_state[0x3a] = caps;
1473 }
1474 if (vs->modifiers_state[0x45] != num) {
1475 vs->modifiers_state[0x45] = num;
1476 }
1477}
1478
9ca313aa 1479static void do_key_event(VncState *vs, int down, int keycode, int sym)
24236869 1480{
64f5a135
FB
1481 /* QEMU console switch */
1482 switch(keycode) {
1483 case 0x2a: /* Left Shift */
1484 case 0x36: /* Right Shift */
1485 case 0x1d: /* Left CTRL */
1486 case 0x9d: /* Right CTRL */
1487 case 0x38: /* Left ALT */
1488 case 0xb8: /* Right ALT */
1489 if (down)
1490 vs->modifiers_state[keycode] = 1;
1491 else
1492 vs->modifiers_state[keycode] = 0;
1493 break;
5fafdf24 1494 case 0x02 ... 0x0a: /* '1' to '9' keys */
64f5a135
FB
1495 if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1496 /* Reset the modifiers sent to the current console */
1497 reset_keys(vs);
1498 console_select(keycode - 0x02);
1499 return;
1500 }
1501 break;
28a76be8
AL
1502 case 0x3a: /* CapsLock */
1503 case 0x45: /* NumLock */
7ffb82ca 1504 if (down)
a528b80c
AZ
1505 vs->modifiers_state[keycode] ^= 1;
1506 break;
1507 }
1508
9892088b 1509 if (down && vs->vd->lock_key_sync &&
3a0558b5 1510 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
a528b80c
AZ
1511 /* If the numlock state needs to change then simulate an additional
1512 keypress before sending this one. This will happen if the user
1513 toggles numlock away from the VNC window.
1514 */
753b4053 1515 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
a528b80c
AZ
1516 if (!vs->modifiers_state[0x45]) {
1517 vs->modifiers_state[0x45] = 1;
1518 press_key(vs, 0xff7f);
1519 }
1520 } else {
1521 if (vs->modifiers_state[0x45]) {
1522 vs->modifiers_state[0x45] = 0;
1523 press_key(vs, 0xff7f);
1524 }
1525 }
64f5a135 1526 }
24236869 1527
9892088b 1528 if (down && vs->vd->lock_key_sync &&
3a0558b5 1529 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
6b132502
GH
1530 /* If the capslock state needs to change then simulate an additional
1531 keypress before sending this one. This will happen if the user
1532 toggles capslock away from the VNC window.
1533 */
1534 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1535 int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
1536 int capslock = !!(vs->modifiers_state[0x3a]);
1537 if (capslock) {
1538 if (uppercase == shift) {
1539 vs->modifiers_state[0x3a] = 0;
1540 press_key(vs, 0xffe5);
1541 }
1542 } else {
1543 if (uppercase != shift) {
1544 vs->modifiers_state[0x3a] = 1;
1545 press_key(vs, 0xffe5);
1546 }
1547 }
1548 }
1549
64f5a135 1550 if (is_graphic_console()) {
44bb61c8
ST
1551 if (keycode & SCANCODE_GREY)
1552 kbd_put_keycode(SCANCODE_EMUL0);
64f5a135 1553 if (down)
44bb61c8 1554 kbd_put_keycode(keycode & SCANCODE_KEYCODEMASK);
64f5a135 1555 else
44bb61c8 1556 kbd_put_keycode(keycode | SCANCODE_UP);
64f5a135
FB
1557 } else {
1558 /* QEMU console emulation */
1559 if (down) {
bb0a18e1 1560 int numlock = vs->modifiers_state[0x45];
64f5a135
FB
1561 switch (keycode) {
1562 case 0x2a: /* Left Shift */
1563 case 0x36: /* Right Shift */
1564 case 0x1d: /* Left CTRL */
1565 case 0x9d: /* Right CTRL */
1566 case 0x38: /* Left ALT */
1567 case 0xb8: /* Right ALT */
1568 break;
1569 case 0xc8:
1570 kbd_put_keysym(QEMU_KEY_UP);
1571 break;
1572 case 0xd0:
1573 kbd_put_keysym(QEMU_KEY_DOWN);
1574 break;
1575 case 0xcb:
1576 kbd_put_keysym(QEMU_KEY_LEFT);
1577 break;
1578 case 0xcd:
1579 kbd_put_keysym(QEMU_KEY_RIGHT);
1580 break;
1581 case 0xd3:
1582 kbd_put_keysym(QEMU_KEY_DELETE);
1583 break;
1584 case 0xc7:
1585 kbd_put_keysym(QEMU_KEY_HOME);
1586 break;
1587 case 0xcf:
1588 kbd_put_keysym(QEMU_KEY_END);
1589 break;
1590 case 0xc9:
1591 kbd_put_keysym(QEMU_KEY_PAGEUP);
1592 break;
1593 case 0xd1:
1594 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1595 break;
bb0a18e1
GH
1596
1597 case 0x47:
1598 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1599 break;
1600 case 0x48:
1601 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1602 break;
1603 case 0x49:
1604 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1605 break;
1606 case 0x4b:
1607 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1608 break;
1609 case 0x4c:
1610 kbd_put_keysym('5');
1611 break;
1612 case 0x4d:
1613 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1614 break;
1615 case 0x4f:
1616 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1617 break;
1618 case 0x50:
1619 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1620 break;
1621 case 0x51:
1622 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1623 break;
1624 case 0x52:
1625 kbd_put_keysym('0');
1626 break;
1627 case 0x53:
1628 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1629 break;
1630
1631 case 0xb5:
1632 kbd_put_keysym('/');
1633 break;
1634 case 0x37:
1635 kbd_put_keysym('*');
1636 break;
1637 case 0x4a:
1638 kbd_put_keysym('-');
1639 break;
1640 case 0x4e:
1641 kbd_put_keysym('+');
1642 break;
1643 case 0x9c:
1644 kbd_put_keysym('\n');
1645 break;
1646
64f5a135
FB
1647 default:
1648 kbd_put_keysym(sym);
1649 break;
1650 }
1651 }
1652 }
24236869
FB
1653}
1654
bdbd7676
FB
1655static void key_event(VncState *vs, int down, uint32_t sym)
1656{
9ca313aa 1657 int keycode;
4a93fe17 1658 int lsym = sym;
9ca313aa 1659
4a93fe17
GH
1660 if (lsym >= 'A' && lsym <= 'Z' && is_graphic_console()) {
1661 lsym = lsym - 'A' + 'a';
1662 }
9ca313aa 1663
44bb61c8 1664 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
9ca313aa
AL
1665 do_key_event(vs, down, keycode, sym);
1666}
1667
1668static void ext_key_event(VncState *vs, int down,
1669 uint32_t sym, uint16_t keycode)
1670{
1671 /* if the user specifies a keyboard layout, always use it */
1672 if (keyboard_layout)
1673 key_event(vs, down, sym);
1674 else
1675 do_key_event(vs, down, keycode, sym);
bdbd7676
FB
1676}
1677
24236869 1678static void framebuffer_update_request(VncState *vs, int incremental,
28a76be8
AL
1679 int x_position, int y_position,
1680 int w, int h)
24236869 1681{
0e1f5a0c
AL
1682 if (y_position > ds_get_height(vs->ds))
1683 y_position = ds_get_height(vs->ds);
0e1f5a0c
AL
1684 if (y_position + h >= ds_get_height(vs->ds))
1685 h = ds_get_height(vs->ds) - y_position;
cf2d385c 1686
24236869
FB
1687 int i;
1688 vs->need_update = 1;
1689 if (!incremental) {
24cf0a6e 1690 vs->force_update = 1;
28a76be8 1691 for (i = 0; i < h; i++) {
1fc62412 1692 vnc_set_bits(vs->dirty[y_position + i],
0e1f5a0c 1693 (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
28a76be8 1694 }
24236869
FB
1695 }
1696}
1697
9ca313aa
AL
1698static void send_ext_key_event_ack(VncState *vs)
1699{
bd023f95 1700 vnc_lock_output(vs);
46a183da 1701 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
9ca313aa
AL
1702 vnc_write_u8(vs, 0);
1703 vnc_write_u16(vs, 1);
29fa4ed9
AL
1704 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
1705 VNC_ENCODING_EXT_KEY_EVENT);
bd023f95 1706 vnc_unlock_output(vs);
9ca313aa
AL
1707 vnc_flush(vs);
1708}
1709
429a8ed3 1710static void send_ext_audio_ack(VncState *vs)
1711{
bd023f95 1712 vnc_lock_output(vs);
46a183da 1713 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
429a8ed3 1714 vnc_write_u8(vs, 0);
1715 vnc_write_u16(vs, 1);
29fa4ed9
AL
1716 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
1717 VNC_ENCODING_AUDIO);
bd023f95 1718 vnc_unlock_output(vs);
429a8ed3 1719 vnc_flush(vs);
1720}
1721
24236869
FB
1722static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1723{
1724 int i;
29fa4ed9 1725 unsigned int enc = 0;
24236869 1726
29fa4ed9 1727 vs->features = 0;
a9f20d31 1728 vs->vnc_encoding = 0;
d1af0e05
CC
1729 vs->tight.compression = 9;
1730 vs->tight.quality = -1; /* Lossless by default */
564c337e 1731 vs->absolute = -1;
24236869 1732
8a0f0d0c
CC
1733 /*
1734 * Start from the end because the encodings are sent in order of preference.
1735 * This way the prefered encoding (first encoding defined in the array)
1736 * will be set at the end of the loop.
1737 */
24236869 1738 for (i = n_encodings - 1; i >= 0; i--) {
29fa4ed9
AL
1739 enc = encodings[i];
1740 switch (enc) {
1741 case VNC_ENCODING_RAW:
a9f20d31 1742 vs->vnc_encoding = enc;
29fa4ed9
AL
1743 break;
1744 case VNC_ENCODING_COPYRECT:
753b4053 1745 vs->features |= VNC_FEATURE_COPYRECT_MASK;
29fa4ed9
AL
1746 break;
1747 case VNC_ENCODING_HEXTILE:
1748 vs->features |= VNC_FEATURE_HEXTILE_MASK;
a9f20d31 1749 vs->vnc_encoding = enc;
29fa4ed9 1750 break;
380282b0
CC
1751 case VNC_ENCODING_TIGHT:
1752 vs->features |= VNC_FEATURE_TIGHT_MASK;
1753 vs->vnc_encoding = enc;
1754 break;
efe556ad
CC
1755 case VNC_ENCODING_TIGHT_PNG:
1756 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
1757 vs->vnc_encoding = enc;
1758 break;
059cef40
AL
1759 case VNC_ENCODING_ZLIB:
1760 vs->features |= VNC_FEATURE_ZLIB_MASK;
a9f20d31 1761 vs->vnc_encoding = enc;
059cef40 1762 break;
29fa4ed9
AL
1763 case VNC_ENCODING_DESKTOPRESIZE:
1764 vs->features |= VNC_FEATURE_RESIZE_MASK;
1765 break;
1766 case VNC_ENCODING_POINTER_TYPE_CHANGE:
1767 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
1768 break;
d467b679
GH
1769 case VNC_ENCODING_RICH_CURSOR:
1770 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
1771 break;
29fa4ed9 1772 case VNC_ENCODING_EXT_KEY_EVENT:
9ca313aa
AL
1773 send_ext_key_event_ack(vs);
1774 break;
29fa4ed9 1775 case VNC_ENCODING_AUDIO:
429a8ed3 1776 send_ext_audio_ack(vs);
1777 break;
29fa4ed9
AL
1778 case VNC_ENCODING_WMVi:
1779 vs->features |= VNC_FEATURE_WMVI_MASK;
ca4cca4d 1780 break;
fb437313 1781 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
d1af0e05 1782 vs->tight.compression = (enc & 0x0F);
fb437313
AL
1783 break;
1784 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
b31f519e
CC
1785 if (vs->vd->lossy) {
1786 vs->tight.quality = (enc & 0x0F);
1787 }
fb437313 1788 break;
29fa4ed9
AL
1789 default:
1790 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
1791 break;
1792 }
24236869 1793 }
6356e472 1794 vnc_desktop_resize(vs);
0684bf1b 1795 check_pointer_type_change(&vs->mouse_mode_notifier);
24236869
FB
1796}
1797
6cec5487
AL
1798static void set_pixel_conversion(VncState *vs)
1799{
1800 if ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) ==
1801 (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) &&
1802 !memcmp(&(vs->clientds.pf), &(vs->ds->surface->pf), sizeof(PixelFormat))) {
1803 vs->write_pixels = vnc_write_pixels_copy;
70a4568f 1804 vnc_hextile_set_pixel_conversion(vs, 0);
6cec5487
AL
1805 } else {
1806 vs->write_pixels = vnc_write_pixels_generic;
70a4568f 1807 vnc_hextile_set_pixel_conversion(vs, 1);
6cec5487
AL
1808 }
1809}
1810
24236869 1811static void set_pixel_format(VncState *vs,
28a76be8
AL
1812 int bits_per_pixel, int depth,
1813 int big_endian_flag, int true_color_flag,
1814 int red_max, int green_max, int blue_max,
1815 int red_shift, int green_shift, int blue_shift)
24236869 1816{
3512779a 1817 if (!true_color_flag) {
28a76be8 1818 vnc_client_error(vs);
3512779a
FB
1819 return;
1820 }
24236869 1821
1fc62412 1822 vs->clientds = *(vs->vd->guest.ds);
6cec5487 1823 vs->clientds.pf.rmax = red_max;
90a1e3c0 1824 count_bits(vs->clientds.pf.rbits, red_max);
6cec5487
AL
1825 vs->clientds.pf.rshift = red_shift;
1826 vs->clientds.pf.rmask = red_max << red_shift;
1827 vs->clientds.pf.gmax = green_max;
90a1e3c0 1828 count_bits(vs->clientds.pf.gbits, green_max);
6cec5487
AL
1829 vs->clientds.pf.gshift = green_shift;
1830 vs->clientds.pf.gmask = green_max << green_shift;
1831 vs->clientds.pf.bmax = blue_max;
90a1e3c0 1832 count_bits(vs->clientds.pf.bbits, blue_max);
6cec5487
AL
1833 vs->clientds.pf.bshift = blue_shift;
1834 vs->clientds.pf.bmask = blue_max << blue_shift;
1835 vs->clientds.pf.bits_per_pixel = bits_per_pixel;
1836 vs->clientds.pf.bytes_per_pixel = bits_per_pixel / 8;
1837 vs->clientds.pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
1838 vs->clientds.flags = big_endian_flag ? QEMU_BIG_ENDIAN_FLAG : 0x00;
1839
1840 set_pixel_conversion(vs);
24236869
FB
1841
1842 vga_hw_invalidate();
1843 vga_hw_update();
1844}
1845
ca4cca4d
AL
1846static void pixel_format_message (VncState *vs) {
1847 char pad[3] = { 0, 0, 0 };
1848
6cec5487
AL
1849 vnc_write_u8(vs, vs->ds->surface->pf.bits_per_pixel); /* bits-per-pixel */
1850 vnc_write_u8(vs, vs->ds->surface->pf.depth); /* depth */
ca4cca4d 1851
e2542fe2 1852#ifdef HOST_WORDS_BIGENDIAN
ca4cca4d
AL
1853 vnc_write_u8(vs, 1); /* big-endian-flag */
1854#else
1855 vnc_write_u8(vs, 0); /* big-endian-flag */
1856#endif
1857 vnc_write_u8(vs, 1); /* true-color-flag */
6cec5487
AL
1858 vnc_write_u16(vs, vs->ds->surface->pf.rmax); /* red-max */
1859 vnc_write_u16(vs, vs->ds->surface->pf.gmax); /* green-max */
1860 vnc_write_u16(vs, vs->ds->surface->pf.bmax); /* blue-max */
1861 vnc_write_u8(vs, vs->ds->surface->pf.rshift); /* red-shift */
1862 vnc_write_u8(vs, vs->ds->surface->pf.gshift); /* green-shift */
1863 vnc_write_u8(vs, vs->ds->surface->pf.bshift); /* blue-shift */
70a4568f
CC
1864
1865 vnc_hextile_set_pixel_conversion(vs, 0);
1866
6cec5487 1867 vs->clientds = *(vs->ds->surface);
3cded540 1868 vs->clientds.flags &= ~QEMU_ALLOCATED_FLAG;
ca4cca4d
AL
1869 vs->write_pixels = vnc_write_pixels_copy;
1870
1871 vnc_write(vs, pad, 3); /* padding */
1872}
1873
7d957bd8
AL
1874static void vnc_dpy_setdata(DisplayState *ds)
1875{
1876 /* We don't have to do anything */
1877}
1878
753b4053 1879static void vnc_colordepth(VncState *vs)
7eac3a87 1880{
753b4053 1881 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
ca4cca4d 1882 /* Sending a WMVi message to notify the client*/
bd023f95 1883 vnc_lock_output(vs);
46a183da 1884 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
ca4cca4d
AL
1885 vnc_write_u8(vs, 0);
1886 vnc_write_u16(vs, 1); /* number of rects */
753b4053
AL
1887 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds),
1888 ds_get_height(vs->ds), VNC_ENCODING_WMVi);
ca4cca4d 1889 pixel_format_message(vs);
bd023f95 1890 vnc_unlock_output(vs);
ca4cca4d 1891 vnc_flush(vs);
7eac3a87 1892 } else {
6cec5487 1893 set_pixel_conversion(vs);
7eac3a87
AL
1894 }
1895}
1896
60fe76f3 1897static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
24236869
FB
1898{
1899 int i;
1900 uint16_t limit;
2430ffe4
SS
1901 VncDisplay *vd = vs->vd;
1902
1903 if (data[0] > 3) {
1904 vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
1905 if (!qemu_timer_expired(vd->timer, qemu_get_clock(rt_clock) + vd->timer_interval))
1906 qemu_mod_timer(vd->timer, qemu_get_clock(rt_clock) + vd->timer_interval);
1907 }
24236869
FB
1908
1909 switch (data[0]) {
46a183da 1910 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
28a76be8
AL
1911 if (len == 1)
1912 return 20;
1913
1914 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
1915 read_u8(data, 6), read_u8(data, 7),
1916 read_u16(data, 8), read_u16(data, 10),
1917 read_u16(data, 12), read_u8(data, 14),
1918 read_u8(data, 15), read_u8(data, 16));
1919 break;
46a183da 1920 case VNC_MSG_CLIENT_SET_ENCODINGS:
28a76be8
AL
1921 if (len == 1)
1922 return 4;
24236869 1923
28a76be8 1924 if (len == 4) {
69dd5c9f
AL
1925 limit = read_u16(data, 2);
1926 if (limit > 0)
1927 return 4 + (limit * 4);
1928 } else
1929 limit = read_u16(data, 2);
24236869 1930
28a76be8
AL
1931 for (i = 0; i < limit; i++) {
1932 int32_t val = read_s32(data, 4 + (i * 4));
1933 memcpy(data + 4 + (i * 4), &val, sizeof(val));
1934 }
24236869 1935
28a76be8
AL
1936 set_encodings(vs, (int32_t *)(data + 4), limit);
1937 break;
46a183da 1938 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
28a76be8
AL
1939 if (len == 1)
1940 return 10;
24236869 1941
28a76be8
AL
1942 framebuffer_update_request(vs,
1943 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
1944 read_u16(data, 6), read_u16(data, 8));
1945 break;
46a183da 1946 case VNC_MSG_CLIENT_KEY_EVENT:
28a76be8
AL
1947 if (len == 1)
1948 return 8;
24236869 1949
28a76be8
AL
1950 key_event(vs, read_u8(data, 1), read_u32(data, 4));
1951 break;
46a183da 1952 case VNC_MSG_CLIENT_POINTER_EVENT:
28a76be8
AL
1953 if (len == 1)
1954 return 6;
24236869 1955
28a76be8
AL
1956 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
1957 break;
46a183da 1958 case VNC_MSG_CLIENT_CUT_TEXT:
28a76be8
AL
1959 if (len == 1)
1960 return 8;
24236869 1961
28a76be8 1962 if (len == 8) {
baa7666c
TS
1963 uint32_t dlen = read_u32(data, 4);
1964 if (dlen > 0)
1965 return 8 + dlen;
1966 }
24236869 1967
28a76be8
AL
1968 client_cut_text(vs, read_u32(data, 4), data + 8);
1969 break;
46a183da 1970 case VNC_MSG_CLIENT_QEMU:
9ca313aa
AL
1971 if (len == 1)
1972 return 2;
1973
1974 switch (read_u8(data, 1)) {
46a183da 1975 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
9ca313aa
AL
1976 if (len == 2)
1977 return 12;
1978
1979 ext_key_event(vs, read_u16(data, 2),
1980 read_u32(data, 4), read_u32(data, 8));
1981 break;
46a183da 1982 case VNC_MSG_CLIENT_QEMU_AUDIO:
429a8ed3 1983 if (len == 2)
1984 return 4;
1985
1986 switch (read_u16 (data, 2)) {
46a183da 1987 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
429a8ed3 1988 audio_add(vs);
1989 break;
46a183da 1990 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
429a8ed3 1991 audio_del(vs);
1992 break;
46a183da 1993 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
429a8ed3 1994 if (len == 4)
1995 return 10;
1996 switch (read_u8(data, 4)) {
1997 case 0: vs->as.fmt = AUD_FMT_U8; break;
1998 case 1: vs->as.fmt = AUD_FMT_S8; break;
1999 case 2: vs->as.fmt = AUD_FMT_U16; break;
2000 case 3: vs->as.fmt = AUD_FMT_S16; break;
2001 case 4: vs->as.fmt = AUD_FMT_U32; break;
2002 case 5: vs->as.fmt = AUD_FMT_S32; break;
2003 default:
2004 printf("Invalid audio format %d\n", read_u8(data, 4));
2005 vnc_client_error(vs);
2006 break;
2007 }
2008 vs->as.nchannels = read_u8(data, 5);
2009 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2010 printf("Invalid audio channel coount %d\n",
2011 read_u8(data, 5));
2012 vnc_client_error(vs);
2013 break;
2014 }
2015 vs->as.freq = read_u32(data, 6);
2016 break;
2017 default:
2018 printf ("Invalid audio message %d\n", read_u8(data, 4));
2019 vnc_client_error(vs);
2020 break;
2021 }
2022 break;
2023
9ca313aa
AL
2024 default:
2025 printf("Msg: %d\n", read_u16(data, 0));
2026 vnc_client_error(vs);
2027 break;
2028 }
2029 break;
24236869 2030 default:
28a76be8
AL
2031 printf("Msg: %d\n", data[0]);
2032 vnc_client_error(vs);
2033 break;
24236869 2034 }
5fafdf24 2035
24236869
FB
2036 vnc_read_when(vs, protocol_client_msg, 1);
2037 return 0;
2038}
2039
60fe76f3 2040static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
24236869 2041{
c35734b2
TS
2042 char buf[1024];
2043 int size;
24236869 2044
5862d195
GH
2045 vs->client_width = ds_get_width(vs->ds);
2046 vs->client_height = ds_get_height(vs->ds);
2047 vnc_write_u16(vs, vs->client_width);
2048 vnc_write_u16(vs, vs->client_height);
24236869 2049
ca4cca4d 2050 pixel_format_message(vs);
24236869 2051
c35734b2
TS
2052 if (qemu_name)
2053 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2054 else
2055 size = snprintf(buf, sizeof(buf), "QEMU");
2056
2057 vnc_write_u32(vs, size);
2058 vnc_write(vs, buf, size);
24236869
FB
2059 vnc_flush(vs);
2060
4a80dba3 2061 vnc_client_cache_auth(vs);
0d2ed46a 2062 vnc_qmp_event(vs, QEVENT_VNC_INITIALIZED);
4a80dba3 2063
24236869
FB
2064 vnc_read_when(vs, protocol_client_msg, 1);
2065
2066 return 0;
2067}
2068
5fb6c7a8
AL
2069void start_client_init(VncState *vs)
2070{
2071 vnc_read_when(vs, protocol_client_init, 1);
2072}
2073
70848515
TS
2074static void make_challenge(VncState *vs)
2075{
2076 int i;
2077
2078 srand(time(NULL)+getpid()+getpid()*987654+rand());
2079
2080 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
2081 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
2082}
2083
60fe76f3 2084static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
70848515 2085{
60fe76f3 2086 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
70848515 2087 int i, j, pwlen;
60fe76f3 2088 unsigned char key[8];
3c9405a0 2089 time_t now = time(NULL);
70848515 2090
1cd20f8b 2091 if (!vs->vd->password) {
28a76be8 2092 VNC_DEBUG("No password configured on server");
6bffdf0f 2093 goto reject;
70848515 2094 }
3c9405a0
GH
2095 if (vs->vd->expires < now) {
2096 VNC_DEBUG("Password is expired");
2097 goto reject;
2098 }
70848515
TS
2099
2100 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2101
2102 /* Calculate the expected challenge response */
753b4053 2103 pwlen = strlen(vs->vd->password);
70848515 2104 for (i=0; i<sizeof(key); i++)
753b4053 2105 key[i] = i<pwlen ? vs->vd->password[i] : 0;
70848515
TS
2106 deskey(key, EN0);
2107 for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
2108 des(response+j, response+j);
2109
2110 /* Compare expected vs actual challenge response */
2111 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
28a76be8 2112 VNC_DEBUG("Client challenge reponse did not match\n");
6bffdf0f 2113 goto reject;
70848515 2114 } else {
28a76be8
AL
2115 VNC_DEBUG("Accepting VNC challenge response\n");
2116 vnc_write_u32(vs, 0); /* Accept auth */
2117 vnc_flush(vs);
70848515 2118
5fb6c7a8 2119 start_client_init(vs);
70848515
TS
2120 }
2121 return 0;
6bffdf0f
GH
2122
2123reject:
2124 vnc_write_u32(vs, 1); /* Reject auth */
2125 if (vs->minor >= 8) {
2126 static const char err[] = "Authentication failed";
2127 vnc_write_u32(vs, sizeof(err));
2128 vnc_write(vs, err, sizeof(err));
2129 }
2130 vnc_flush(vs);
2131 vnc_client_error(vs);
2132 return 0;
70848515
TS
2133}
2134
5fb6c7a8 2135void start_auth_vnc(VncState *vs)
70848515
TS
2136{
2137 make_challenge(vs);
2138 /* Send client a 'random' challenge */
2139 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2140 vnc_flush(vs);
2141
2142 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
469b15c6
TS
2143}
2144
2145
60fe76f3 2146static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
70848515
TS
2147{
2148 /* We only advertise 1 auth scheme at a time, so client
2149 * must pick the one we sent. Verify this */
753b4053 2150 if (data[0] != vs->vd->auth) { /* Reject auth */
1263b7d6 2151 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
70848515
TS
2152 vnc_write_u32(vs, 1);
2153 if (vs->minor >= 8) {
2154 static const char err[] = "Authentication failed";
2155 vnc_write_u32(vs, sizeof(err));
2156 vnc_write(vs, err, sizeof(err));
2157 }
2158 vnc_client_error(vs);
2159 } else { /* Accept requested auth */
2160 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
753b4053 2161 switch (vs->vd->auth) {
70848515
TS
2162 case VNC_AUTH_NONE:
2163 VNC_DEBUG("Accept auth none\n");
a26c97ad
AZ
2164 if (vs->minor >= 8) {
2165 vnc_write_u32(vs, 0); /* Accept auth completion */
2166 vnc_flush(vs);
2167 }
5fb6c7a8 2168 start_client_init(vs);
70848515
TS
2169 break;
2170
2171 case VNC_AUTH_VNC:
2172 VNC_DEBUG("Start VNC auth\n");
5fb6c7a8
AL
2173 start_auth_vnc(vs);
2174 break;
70848515 2175
eb38c52c 2176#ifdef CONFIG_VNC_TLS
8d5d2d4c
TS
2177 case VNC_AUTH_VENCRYPT:
2178 VNC_DEBUG("Accept VeNCrypt auth\n");;
5fb6c7a8
AL
2179 start_auth_vencrypt(vs);
2180 break;
8d5d2d4c
TS
2181#endif /* CONFIG_VNC_TLS */
2182
2f9606b3
AL
2183#ifdef CONFIG_VNC_SASL
2184 case VNC_AUTH_SASL:
2185 VNC_DEBUG("Accept SASL auth\n");
2186 start_auth_sasl(vs);
2187 break;
2188#endif /* CONFIG_VNC_SASL */
2189
70848515 2190 default: /* Should not be possible, but just in case */
1263b7d6 2191 VNC_DEBUG("Reject auth %d server code bug\n", vs->vd->auth);
70848515
TS
2192 vnc_write_u8(vs, 1);
2193 if (vs->minor >= 8) {
2194 static const char err[] = "Authentication failed";
2195 vnc_write_u32(vs, sizeof(err));
2196 vnc_write(vs, err, sizeof(err));
2197 }
2198 vnc_client_error(vs);
2199 }
2200 }
2201 return 0;
2202}
2203
60fe76f3 2204static int protocol_version(VncState *vs, uint8_t *version, size_t len)
24236869
FB
2205{
2206 char local[13];
24236869
FB
2207
2208 memcpy(local, version, 12);
2209 local[12] = 0;
2210
70848515 2211 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
28a76be8
AL
2212 VNC_DEBUG("Malformed protocol version %s\n", local);
2213 vnc_client_error(vs);
2214 return 0;
24236869 2215 }
70848515
TS
2216 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2217 if (vs->major != 3 ||
28a76be8
AL
2218 (vs->minor != 3 &&
2219 vs->minor != 4 &&
2220 vs->minor != 5 &&
2221 vs->minor != 7 &&
2222 vs->minor != 8)) {
2223 VNC_DEBUG("Unsupported client version\n");
2224 vnc_write_u32(vs, VNC_AUTH_INVALID);
2225 vnc_flush(vs);
2226 vnc_client_error(vs);
2227 return 0;
70848515 2228 }
b0566f4f 2229 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
70848515
TS
2230 * as equivalent to v3.3 by servers
2231 */
b0566f4f 2232 if (vs->minor == 4 || vs->minor == 5)
28a76be8 2233 vs->minor = 3;
70848515
TS
2234
2235 if (vs->minor == 3) {
28a76be8 2236 if (vs->vd->auth == VNC_AUTH_NONE) {
70848515 2237 VNC_DEBUG("Tell client auth none\n");
753b4053 2238 vnc_write_u32(vs, vs->vd->auth);
70848515 2239 vnc_flush(vs);
28a76be8 2240 start_client_init(vs);
753b4053 2241 } else if (vs->vd->auth == VNC_AUTH_VNC) {
70848515 2242 VNC_DEBUG("Tell client VNC auth\n");
753b4053 2243 vnc_write_u32(vs, vs->vd->auth);
70848515
TS
2244 vnc_flush(vs);
2245 start_auth_vnc(vs);
2246 } else {
753b4053 2247 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->vd->auth);
70848515
TS
2248 vnc_write_u32(vs, VNC_AUTH_INVALID);
2249 vnc_flush(vs);
2250 vnc_client_error(vs);
2251 }
2252 } else {
28a76be8
AL
2253 VNC_DEBUG("Telling client we support auth %d\n", vs->vd->auth);
2254 vnc_write_u8(vs, 1); /* num auth */
2255 vnc_write_u8(vs, vs->vd->auth);
2256 vnc_read_when(vs, protocol_client_auth, 1);
2257 vnc_flush(vs);
70848515 2258 }
24236869
FB
2259
2260 return 0;
2261}
2262
999342a0
CC
2263static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2264{
2265 struct VncSurface *vs = &vd->guest;
2266
2267 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2268}
2269
2270static void vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2271{
2272 int x, y;
2273 struct timeval res;
2274
2275 for (y = 0; y < vd->guest.ds->height; y += VNC_STAT_RECT) {
2276 for (x = 0; x < vd->guest.ds->width; x += VNC_STAT_RECT) {
2277 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2278
2279 rect->updated = false;
2280 }
2281 }
2282
2283 timersub(tv, &VNC_REFRESH_STATS, &res);
2284
2285 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
2286 return ;
2287 }
2288 vd->guest.last_freq_check = *tv;
2289
2290 for (y = 0; y < vd->guest.ds->height; y += VNC_STAT_RECT) {
2291 for (x = 0; x < vd->guest.ds->width; x += VNC_STAT_RECT) {
2292 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2293 int count = ARRAY_SIZE(rect->times);
2294 struct timeval min, max;
2295
2296 if (!timerisset(&rect->times[count - 1])) {
2297 continue ;
2298 }
2299
2300 max = rect->times[(rect->idx + count - 1) % count];
2301 timersub(tv, &max, &res);
2302
2303 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2304 rect->freq = 0;
2305 memset(rect->times, 0, sizeof (rect->times));
2306 continue ;
2307 }
2308
2309 min = rect->times[rect->idx];
2310 max = rect->times[(rect->idx + count - 1) % count];
2311 timersub(&max, &min, &res);
2312
2313 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2314 rect->freq /= count;
2315 rect->freq = 1. / rect->freq;
2316 }
2317 }
2318}
2319
2320double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2321{
2322 int i, j;
2323 double total = 0;
2324 int num = 0;
2325
2326 x = (x / VNC_STAT_RECT) * VNC_STAT_RECT;
2327 y = (y / VNC_STAT_RECT) * VNC_STAT_RECT;
2328
2329 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2330 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2331 total += vnc_stat_rect(vs->vd, i, j)->freq;
2332 num++;
2333 }
2334 }
2335
2336 if (num) {
2337 return total / num;
2338 } else {
2339 return 0;
2340 }
2341}
2342
2343static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2344{
2345 VncRectStat *rect;
2346
2347 rect = vnc_stat_rect(vd, x, y);
2348 if (rect->updated) {
2349 return ;
2350 }
2351 rect->times[rect->idx] = *tv;
2352 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
2353 rect->updated = true;
2354}
2355
1fc62412
SS
2356static int vnc_refresh_server_surface(VncDisplay *vd)
2357{
2358 int y;
2359 uint8_t *guest_row;
2360 uint8_t *server_row;
2361 int cmp_bytes;
2362 uint32_t width_mask[VNC_DIRTY_WORDS];
41b4bef6 2363 VncState *vs;
1fc62412
SS
2364 int has_dirty = 0;
2365
999342a0
CC
2366 struct timeval tv;
2367
2368 gettimeofday(&tv, NULL);
2369 vnc_update_stats(vd, &tv);
2370
1fc62412
SS
2371 /*
2372 * Walk through the guest dirty map.
2373 * Check and copy modified bits from guest to server surface.
2374 * Update server dirty map.
2375 */
2376 vnc_set_bits(width_mask, (ds_get_width(vd->ds) / 16), VNC_DIRTY_WORDS);
2377 cmp_bytes = 16 * ds_get_bytes_per_pixel(vd->ds);
2378 guest_row = vd->guest.ds->data;
2379 server_row = vd->server->data;
2380 for (y = 0; y < vd->guest.ds->height; y++) {
2381 if (vnc_and_bits(vd->guest.dirty[y], width_mask, VNC_DIRTY_WORDS)) {
2382 int x;
2383 uint8_t *guest_ptr;
2384 uint8_t *server_ptr;
2385
2386 guest_ptr = guest_row;
2387 server_ptr = server_row;
2388
2389 for (x = 0; x < vd->guest.ds->width;
2390 x += 16, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
2391 if (!vnc_get_bit(vd->guest.dirty[y], (x / 16)))
2392 continue;
2393 vnc_clear_bit(vd->guest.dirty[y], (x / 16));
2394 if (memcmp(server_ptr, guest_ptr, cmp_bytes) == 0)
2395 continue;
2396 memcpy(server_ptr, guest_ptr, cmp_bytes);
999342a0 2397 vnc_rect_updated(vd, x, y, &tv);
41b4bef6 2398 QTAILQ_FOREACH(vs, &vd->clients, next) {
1fc62412 2399 vnc_set_bit(vs->dirty[y], (x / 16));
1fc62412
SS
2400 }
2401 has_dirty++;
2402 }
2403 }
2404 guest_row += ds_get_linesize(vd->ds);
2405 server_row += ds_get_linesize(vd->ds);
2406 }
2407 return has_dirty;
2408}
2409
703bc68f
SS
2410static void vnc_refresh(void *opaque)
2411{
2412 VncDisplay *vd = opaque;
41b4bef6
AS
2413 VncState *vs, *vn;
2414 int has_dirty, rects = 0;
703bc68f
SS
2415
2416 vga_hw_update();
2417
bd023f95
CC
2418 if (vnc_trylock_display(vd)) {
2419 vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
2420 qemu_mod_timer(vd->timer, qemu_get_clock(rt_clock) +
2421 vd->timer_interval);
2422 return;
2423 }
2424
1fc62412 2425 has_dirty = vnc_refresh_server_surface(vd);
bd023f95 2426 vnc_unlock_display(vd);
1fc62412 2427
41b4bef6 2428 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
2430ffe4 2429 rects += vnc_update_client(vs, has_dirty);
6185c578 2430 /* vs might be free()ed here */
703bc68f 2431 }
bd023f95 2432
83755c17
SS
2433 /* vd->timer could be NULL now if the last client disconnected,
2434 * in this case don't update the timer */
2435 if (vd->timer == NULL)
2436 return;
703bc68f 2437
2430ffe4
SS
2438 if (has_dirty && rects) {
2439 vd->timer_interval /= 2;
2440 if (vd->timer_interval < VNC_REFRESH_INTERVAL_BASE)
2441 vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
2442 } else {
2443 vd->timer_interval += VNC_REFRESH_INTERVAL_INC;
2444 if (vd->timer_interval > VNC_REFRESH_INTERVAL_MAX)
2445 vd->timer_interval = VNC_REFRESH_INTERVAL_MAX;
2446 }
2447 qemu_mod_timer(vd->timer, qemu_get_clock(rt_clock) + vd->timer_interval);
703bc68f
SS
2448}
2449
2450static void vnc_init_timer(VncDisplay *vd)
2451{
2430ffe4 2452 vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
41b4bef6 2453 if (vd->timer == NULL && !QTAILQ_EMPTY(&vd->clients)) {
703bc68f 2454 vd->timer = qemu_new_timer(rt_clock, vnc_refresh, vd);
1fc62412 2455 vnc_refresh(vd);
703bc68f
SS
2456 }
2457}
2458
2459static void vnc_remove_timer(VncDisplay *vd)
2460{
41b4bef6 2461 if (vd->timer != NULL && QTAILQ_EMPTY(&vd->clients)) {
703bc68f
SS
2462 qemu_del_timer(vd->timer);
2463 qemu_free_timer(vd->timer);
2464 vd->timer = NULL;
2465 }
2466}
2467
753b4053 2468static void vnc_connect(VncDisplay *vd, int csock)
3aa3eea3 2469{
753b4053
AL
2470 VncState *vs = qemu_mallocz(sizeof(VncState));
2471 vs->csock = csock;
2472
2473 VNC_DEBUG("New client on socket %d\n", csock);
7d957bd8 2474 dcl->idle = 0;
3aa3eea3
AZ
2475 socket_set_nonblock(vs->csock);
2476 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
753b4053 2477
4a80dba3 2478 vnc_client_cache_addr(vs);
586153d9 2479 vnc_qmp_event(vs, QEVENT_VNC_CONNECTED);
4a80dba3 2480
753b4053
AL
2481 vs->vd = vd;
2482 vs->ds = vd->ds;
753b4053
AL
2483 vs->last_x = -1;
2484 vs->last_y = -1;
2485
2486 vs->as.freq = 44100;
2487 vs->as.nchannels = 2;
2488 vs->as.fmt = AUD_FMT_S16;
2489 vs->as.endianness = 0;
2490
bd023f95
CC
2491#ifdef CONFIG_VNC_THREAD
2492 qemu_mutex_init(&vs->output_mutex);
2493#endif
2494
41b4bef6 2495 QTAILQ_INSERT_HEAD(&vd->clients, vs, next);
1fc62412
SS
2496
2497 vga_hw_update();
2498
3aa3eea3
AZ
2499 vnc_write(vs, "RFB 003.008\n", 12);
2500 vnc_flush(vs);
2501 vnc_read_when(vs, protocol_version, 12);
53762ddb 2502 reset_keys(vs);
3a0558b5
GH
2503 if (vs->vd->lock_key_sync)
2504 vs->led = qemu_add_led_event_handler(kbd_leds, vs);
753b4053 2505
37c34d9d
AL
2506 vs->mouse_mode_notifier.notify = check_pointer_type_change;
2507 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
2508
703bc68f 2509 vnc_init_timer(vd);
1fc62412 2510
198a0039 2511 /* vs might be free()ed here */
3aa3eea3
AZ
2512}
2513
24236869
FB
2514static void vnc_listen_read(void *opaque)
2515{
753b4053 2516 VncDisplay *vs = opaque;
24236869
FB
2517 struct sockaddr_in addr;
2518 socklen_t addrlen = sizeof(addr);
2519
9f60ad50
AZ
2520 /* Catch-up */
2521 vga_hw_update();
2522
40ff6d7e 2523 int csock = qemu_accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
753b4053
AL
2524 if (csock != -1) {
2525 vnc_connect(vs, csock);
24236869
FB
2526 }
2527}
2528
71cab5ca 2529void vnc_display_init(DisplayState *ds)
24236869 2530{
afd32160 2531 VncDisplay *vs = qemu_mallocz(sizeof(*vs));
24236869 2532
7d957bd8 2533 dcl = qemu_mallocz(sizeof(DisplayChangeListener));
24236869
FB
2534
2535 ds->opaque = vs;
7d957bd8 2536 dcl->idle = 1;
753b4053 2537 vnc_display = vs;
24236869
FB
2538
2539 vs->lsock = -1;
24236869
FB
2540
2541 vs->ds = ds;
41b4bef6 2542 QTAILQ_INIT(&vs->clients);
3c9405a0 2543 vs->expires = TIME_MAX;
24236869 2544
9ca313aa 2545 if (keyboard_layout)
0483755a 2546 vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
9ca313aa 2547 else
0483755a 2548 vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
24236869 2549
24236869 2550 if (!vs->kbd_layout)
28a76be8 2551 exit(1);
24236869 2552
bd023f95
CC
2553#ifdef CONFIG_VNC_THREAD
2554 qemu_mutex_init(&vs->mutex);
2555 vnc_start_worker_thread();
2556#endif
2557
753b4053 2558 dcl->dpy_copy = vnc_dpy_copy;
7d957bd8
AL
2559 dcl->dpy_update = vnc_dpy_update;
2560 dcl->dpy_resize = vnc_dpy_resize;
2561 dcl->dpy_setdata = vnc_dpy_setdata;
7d957bd8 2562 register_displaychangelistener(ds, dcl);
d467b679
GH
2563 ds->mouse_set = vnc_mouse_set;
2564 ds->cursor_define = vnc_dpy_cursor_define;
71cab5ca
TS
2565}
2566
6f43024c 2567
71cab5ca
TS
2568void vnc_display_close(DisplayState *ds)
2569{
753b4053 2570 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
71cab5ca 2571
452b4d88
AL
2572 if (!vs)
2573 return;
71cab5ca 2574 if (vs->display) {
28a76be8
AL
2575 qemu_free(vs->display);
2576 vs->display = NULL;
71cab5ca
TS
2577 }
2578 if (vs->lsock != -1) {
28a76be8
AL
2579 qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
2580 close(vs->lsock);
2581 vs->lsock = -1;
71cab5ca 2582 }
70848515 2583 vs->auth = VNC_AUTH_INVALID;
eb38c52c 2584#ifdef CONFIG_VNC_TLS
8d5d2d4c 2585 vs->subauth = VNC_AUTH_INVALID;
5fb6c7a8 2586 vs->tls.x509verify = 0;
8d5d2d4c 2587#endif
70848515
TS
2588}
2589
1cd20f8b
AL
2590int vnc_display_disable_login(DisplayState *ds)
2591{
2592 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
2593
2594 if (!vs) {
2595 return -1;
2596 }
2597
2598 if (vs->password) {
2599 qemu_free(vs->password);
2600 }
2601
2602 vs->password = NULL;
2603 vs->auth = VNC_AUTH_VNC;
2604
2605 return 0;
2606}
2607
70848515
TS
2608int vnc_display_password(DisplayState *ds, const char *password)
2609{
753b4053 2610 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
70848515 2611
7ef92331
ZA
2612 if (!vs) {
2613 return -1;
2614 }
2615
1cd20f8b
AL
2616 if (!password) {
2617 /* This is not the intention of this interface but err on the side
2618 of being safe */
2619 return vnc_display_disable_login(ds);
2620 }
2621
70848515 2622 if (vs->password) {
28a76be8
AL
2623 qemu_free(vs->password);
2624 vs->password = NULL;
70848515 2625 }
1cd20f8b
AL
2626 vs->password = qemu_strdup(password);
2627 vs->auth = VNC_AUTH_VNC;
70848515
TS
2628
2629 return 0;
71cab5ca
TS
2630}
2631
3c9405a0
GH
2632int vnc_display_pw_expire(DisplayState *ds, time_t expires)
2633{
2634 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
2635
2636 vs->expires = expires;
2637 return 0;
2638}
2639
f92f8afe
AL
2640char *vnc_display_local_addr(DisplayState *ds)
2641{
2642 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
2643
2644 return vnc_socket_local_addr("%s:%s", vs->lsock);
2645}
2646
70848515 2647int vnc_display_open(DisplayState *ds, const char *display)
71cab5ca 2648{
753b4053 2649 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
70848515
TS
2650 const char *options;
2651 int password = 0;
3aa3eea3 2652 int reverse = 0;
eb38c52c 2653#ifdef CONFIG_VNC_TLS
3a702699 2654 int tls = 0, x509 = 0;
8d5d2d4c 2655#endif
2f9606b3
AL
2656#ifdef CONFIG_VNC_SASL
2657 int sasl = 0;
2658 int saslErr;
2659#endif
2ded6ad7 2660#if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
76655d6d 2661 int acl = 0;
2ded6ad7 2662#endif
3a0558b5 2663 int lock_key_sync = 1;
71cab5ca 2664
753b4053 2665 if (!vnc_display)
452b4d88 2666 return -1;
71cab5ca 2667 vnc_display_close(ds);
70848515 2668 if (strcmp(display, "none") == 0)
28a76be8 2669 return 0;
24236869 2670
70848515 2671 if (!(vs->display = strdup(display)))
28a76be8 2672 return -1;
70848515
TS
2673
2674 options = display;
2675 while ((options = strchr(options, ','))) {
28a76be8
AL
2676 options++;
2677 if (strncmp(options, "password", 8) == 0) {
2678 password = 1; /* Require password auth */
2679 } else if (strncmp(options, "reverse", 7) == 0) {
2680 reverse = 1;
3a0558b5
GH
2681 } else if (strncmp(options, "no-lock-key-sync", 9) == 0) {
2682 lock_key_sync = 0;
2f9606b3 2683#ifdef CONFIG_VNC_SASL
28a76be8
AL
2684 } else if (strncmp(options, "sasl", 4) == 0) {
2685 sasl = 1; /* Require SASL auth */
2f9606b3 2686#endif
eb38c52c 2687#ifdef CONFIG_VNC_TLS
28a76be8
AL
2688 } else if (strncmp(options, "tls", 3) == 0) {
2689 tls = 1; /* Require TLS */
2690 } else if (strncmp(options, "x509", 4) == 0) {
2691 char *start, *end;
2692 x509 = 1; /* Require x509 certificates */
2693 if (strncmp(options, "x509verify", 10) == 0)
2694 vs->tls.x509verify = 1; /* ...and verify client certs */
2695
2696 /* Now check for 'x509=/some/path' postfix
2697 * and use that to setup x509 certificate/key paths */
2698 start = strchr(options, '=');
2699 end = strchr(options, ',');
2700 if (start && (!end || (start < end))) {
2701 int len = end ? end-(start+1) : strlen(start+1);
2702 char *path = qemu_strndup(start + 1, len);
2703
2704 VNC_DEBUG("Trying certificate path '%s'\n", path);
2705 if (vnc_tls_set_x509_creds_dir(vs, path) < 0) {
2706 fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
2707 qemu_free(path);
2708 qemu_free(vs->display);
2709 vs->display = NULL;
2710 return -1;
2711 }
2712 qemu_free(path);
2713 } else {
2714 fprintf(stderr, "No certificate path provided\n");
2715 qemu_free(vs->display);
2716 vs->display = NULL;
2717 return -1;
2718 }
8d5d2d4c 2719#endif
2ded6ad7 2720#if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
28a76be8
AL
2721 } else if (strncmp(options, "acl", 3) == 0) {
2722 acl = 1;
2ded6ad7 2723#endif
6f9c78c1
CC
2724 } else if (strncmp(options, "lossy", 5) == 0) {
2725 vs->lossy = true;
28a76be8 2726 }
70848515
TS
2727 }
2728
76655d6d
AL
2729#ifdef CONFIG_VNC_TLS
2730 if (acl && x509 && vs->tls.x509verify) {
28a76be8
AL
2731 if (!(vs->tls.acl = qemu_acl_init("vnc.x509dname"))) {
2732 fprintf(stderr, "Failed to create x509 dname ACL\n");
2733 exit(1);
2734 }
76655d6d
AL
2735 }
2736#endif
2737#ifdef CONFIG_VNC_SASL
2738 if (acl && sasl) {
28a76be8
AL
2739 if (!(vs->sasl.acl = qemu_acl_init("vnc.username"))) {
2740 fprintf(stderr, "Failed to create username ACL\n");
2741 exit(1);
2742 }
76655d6d
AL
2743 }
2744#endif
2745
2f9606b3
AL
2746 /*
2747 * Combinations we support here:
2748 *
2749 * - no-auth (clear text, no auth)
2750 * - password (clear text, weak auth)
2751 * - sasl (encrypt, good auth *IF* using Kerberos via GSSAPI)
2752 * - tls (encrypt, weak anonymous creds, no auth)
2753 * - tls + password (encrypt, weak anonymous creds, weak auth)
2754 * - tls + sasl (encrypt, weak anonymous creds, good auth)
2755 * - tls + x509 (encrypt, good x509 creds, no auth)
2756 * - tls + x509 + password (encrypt, good x509 creds, weak auth)
2757 * - tls + x509 + sasl (encrypt, good x509 creds, good auth)
2758 *
2759 * NB1. TLS is a stackable auth scheme.
2760 * NB2. the x509 schemes have option to validate a client cert dname
2761 */
70848515 2762 if (password) {
eb38c52c 2763#ifdef CONFIG_VNC_TLS
28a76be8
AL
2764 if (tls) {
2765 vs->auth = VNC_AUTH_VENCRYPT;
2766 if (x509) {
2767 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
2768 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
2769 } else {
2770 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
2771 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
2772 }
2773 } else {
2f9606b3 2774#endif /* CONFIG_VNC_TLS */
28a76be8
AL
2775 VNC_DEBUG("Initializing VNC server with password auth\n");
2776 vs->auth = VNC_AUTH_VNC;
eb38c52c 2777#ifdef CONFIG_VNC_TLS
28a76be8
AL
2778 vs->subauth = VNC_AUTH_INVALID;
2779 }
2f9606b3
AL
2780#endif /* CONFIG_VNC_TLS */
2781#ifdef CONFIG_VNC_SASL
2782 } else if (sasl) {
2783#ifdef CONFIG_VNC_TLS
2784 if (tls) {
2785 vs->auth = VNC_AUTH_VENCRYPT;
2786 if (x509) {
28a76be8 2787 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
2f9606b3
AL
2788 vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;
2789 } else {
28a76be8 2790 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
2f9606b3
AL
2791 vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;
2792 }
2793 } else {
2794#endif /* CONFIG_VNC_TLS */
28a76be8 2795 VNC_DEBUG("Initializing VNC server with SASL auth\n");
2f9606b3
AL
2796 vs->auth = VNC_AUTH_SASL;
2797#ifdef CONFIG_VNC_TLS
2798 vs->subauth = VNC_AUTH_INVALID;
2799 }
2800#endif /* CONFIG_VNC_TLS */
2801#endif /* CONFIG_VNC_SASL */
70848515 2802 } else {
eb38c52c 2803#ifdef CONFIG_VNC_TLS
28a76be8
AL
2804 if (tls) {
2805 vs->auth = VNC_AUTH_VENCRYPT;
2806 if (x509) {
2807 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
2808 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
2809 } else {
2810 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
2811 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
2812 }
2813 } else {
8d5d2d4c 2814#endif
28a76be8
AL
2815 VNC_DEBUG("Initializing VNC server with no auth\n");
2816 vs->auth = VNC_AUTH_NONE;
eb38c52c 2817#ifdef CONFIG_VNC_TLS
28a76be8
AL
2818 vs->subauth = VNC_AUTH_INVALID;
2819 }
8d5d2d4c 2820#endif
70848515 2821 }
24236869 2822
2f9606b3
AL
2823#ifdef CONFIG_VNC_SASL
2824 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
2825 fprintf(stderr, "Failed to initialize SASL auth %s",
2826 sasl_errstring(saslErr, NULL, NULL));
2827 free(vs->display);
2828 vs->display = NULL;
2829 return -1;
2830 }
2831#endif
3a0558b5 2832 vs->lock_key_sync = lock_key_sync;
2f9606b3 2833
3aa3eea3 2834 if (reverse) {
9712ecaf
AL
2835 /* connect to viewer */
2836 if (strncmp(display, "unix:", 5) == 0)
2837 vs->lsock = unix_connect(display+5);
2838 else
2839 vs->lsock = inet_connect(display, SOCK_STREAM);
2840 if (-1 == vs->lsock) {
3aa3eea3
AZ
2841 free(vs->display);
2842 vs->display = NULL;
2843 return -1;
2844 } else {
753b4053 2845 int csock = vs->lsock;
3aa3eea3 2846 vs->lsock = -1;
753b4053 2847 vnc_connect(vs, csock);
3aa3eea3 2848 }
9712ecaf 2849 return 0;
24236869 2850
9712ecaf
AL
2851 } else {
2852 /* listen for connects */
2853 char *dpy;
2854 dpy = qemu_malloc(256);
2855 if (strncmp(display, "unix:", 5) == 0) {
bc575e95 2856 pstrcpy(dpy, 256, "unix:");
4a55bfdf 2857 vs->lsock = unix_listen(display+5, dpy+5, 256-5);
9712ecaf
AL
2858 } else {
2859 vs->lsock = inet_listen(display, dpy, 256, SOCK_STREAM, 5900);
2860 }
2861 if (-1 == vs->lsock) {
2862 free(dpy);
d0513623 2863 return -1;
9712ecaf
AL
2864 } else {
2865 free(vs->display);
2866 vs->display = dpy;
2867 }
24236869 2868 }
753b4053 2869 return qemu_set_fd_handler2(vs->lsock, NULL, vnc_listen_read, NULL, vs);
24236869 2870}