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