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