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