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