Annotation of qemu/vnc.c, revision 1.1.1.5

1.1       root        1: /*
                      2:  * QEMU VNC display driver
1.1.1.4   root        3:  *
1.1       root        4:  * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
                      5:  * Copyright (C) 2006 Fabrice Bellard
1.1.1.4   root        6:  *
1.1       root        7:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                      8:  * of this software and associated documentation files (the "Software"), to deal
                      9:  * in the Software without restriction, including without limitation the rights
                     10:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     11:  * copies of the Software, and to permit persons to whom the Software is
                     12:  * furnished to do so, subject to the following conditions:
                     13:  *
                     14:  * The above copyright notice and this permission notice shall be included in
                     15:  * all copies or substantial portions of the Software.
                     16:  *
                     17:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     18:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     19:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                     20:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     21:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     22:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     23:  * THE SOFTWARE.
                     24:  */
                     25: 
1.1.1.4   root       26: #include "qemu-common.h"
                     27: #include "console.h"
                     28: #include "sysemu.h"
1.1       root       29: #include "qemu_socket.h"
1.1.1.4   root       30: #include "qemu-timer.h"
1.1.1.5 ! root       31: #include "audio/audio.h"
        !            32: #include <zlib.h>
1.1       root       33: 
                     34: #define VNC_REFRESH_INTERVAL (1000 / 30)
                     35: 
1.1.1.5 ! root       36: #include "vnc.h"
1.1       root       37: #include "vnc_keysym.h"
                     38: #include "keymaps.c"
1.1.1.4   root       39: #include "d3des.h"
                     40: 
1.1.1.5 ! root       41: #ifdef CONFIG_VNC_TLS
1.1.1.4   root       42: #include <gnutls/gnutls.h>
                     43: #include <gnutls/x509.h>
                     44: #endif /* CONFIG_VNC_TLS */
                     45: 
                     46: // #define _VNC_DEBUG 1
                     47: 
1.1.1.5 ! root       48: #ifdef _VNC_DEBUG
1.1.1.4   root       49: #define VNC_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
                     50: 
1.1.1.5 ! root       51: #if defined(CONFIG_VNC_TLS) && _VNC_DEBUG >= 2
1.1.1.4   root       52: /* Very verbose, so only enabled for _VNC_DEBUG >= 2 */
                     53: static void vnc_debug_gnutls_log(int level, const char* str) {
                     54:     VNC_DEBUG("%d %s", level, str);
                     55: }
                     56: #endif /* CONFIG_VNC_TLS && _VNC_DEBUG */
                     57: #else
                     58: #define VNC_DEBUG(fmt, ...) do { } while (0)
                     59: #endif
                     60: 
1.1.1.5 ! root       61: #define count_bits(c, v) { \
        !            62:     for (c = 0; v; v >>= 1) \
        !            63:     { \
        !            64:         c += v & 1; \
        !            65:     } \
        !            66: }
1.1       root       67: 
                     68: typedef struct Buffer
                     69: {
                     70:     size_t capacity;
                     71:     size_t offset;
1.1.1.4   root       72:     uint8_t *buffer;
1.1       root       73: } Buffer;
                     74: 
                     75: typedef struct VncState VncState;
                     76: 
1.1.1.4   root       77: typedef int VncReadEvent(VncState *vs, uint8_t *data, size_t len);
1.1       root       78: 
1.1.1.2   root       79: typedef void VncWritePixels(VncState *vs, void *data, int size);
                     80: 
                     81: typedef void VncSendHextileTile(VncState *vs,
                     82:                                 int x, int y, int w, int h,
1.1.1.5 ! root       83:                                 void *last_bg,
        !            84:                                 void *last_fg,
1.1.1.2   root       85:                                 int *has_bg, int *has_fg);
                     86: 
                     87: #define VNC_MAX_WIDTH 2048
                     88: #define VNC_MAX_HEIGHT 2048
                     89: #define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * 32))
                     90: 
1.1.1.4   root       91: #define VNC_AUTH_CHALLENGE_SIZE 16
                     92: 
1.1.1.5 ! root       93: typedef struct VncDisplay VncDisplay;
1.1.1.4   root       94: 
1.1.1.5 ! root       95: struct VncDisplay
        !            96: {
        !            97:     int lsock;
        !            98:     DisplayState *ds;
        !            99:     VncState *clients;
        !           100:     kbd_layout_t *kbd_layout;
1.1.1.4   root      101: 
1.1.1.5 ! root      102:     char *display;
        !           103:     char *password;
        !           104:     int auth;
        !           105: #ifdef CONFIG_VNC_TLS
        !           106:     int subauth;
        !           107:     int x509verify;
1.1.1.4   root      108: 
1.1.1.5 ! root      109:     char *x509cacert;
        !           110:     char *x509cacrl;
        !           111:     char *x509cert;
        !           112:     char *x509key;
1.1.1.4   root      113: #endif
1.1.1.5 ! root      114: };
1.1.1.4   root      115: 
1.1       root      116: struct VncState
                    117: {
                    118:     QEMUTimer *timer;
                    119:     int csock;
                    120:     DisplayState *ds;
1.1.1.5 ! root      121:     VncDisplay *vd;
1.1       root      122:     int need_update;
1.1.1.2   root      123:     uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
1.1       root      124:     char *old_data;
1.1.1.5 ! root      125:     uint32_t features;
1.1.1.3   root      126:     int absolute;
                    127:     int last_x;
                    128:     int last_y;
                    129: 
1.1.1.5 ! root      130:     uint32_t vnc_encoding;
        !           131:     uint8_t tight_quality;
        !           132:     uint8_t tight_compression;
        !           133: 
1.1.1.4   root      134:     int major;
                    135:     int minor;
                    136: 
                    137:     char challenge[VNC_AUTH_CHALLENGE_SIZE];
                    138: 
1.1.1.5 ! root      139: #ifdef CONFIG_VNC_TLS
1.1.1.4   root      140:     int wiremode;
                    141:     gnutls_session_t tls_session;
                    142: #endif
1.1.1.3   root      143: 
1.1       root      144:     Buffer output;
                    145:     Buffer input;
1.1.1.2   root      146:     /* current output mode information */
                    147:     VncWritePixels *write_pixels;
                    148:     VncSendHextileTile *send_hextile_tile;
1.1.1.5 ! root      149:     DisplaySurface clientds, serverds;
        !           150: 
        !           151:     CaptureVoiceOut *audio_cap;
        !           152:     struct audsettings as;
1.1       root      153: 
                    154:     VncReadEvent *read_handler;
                    155:     size_t read_handler_expect;
1.1.1.3   root      156:     /* input */
                    157:     uint8_t modifiers_state[256];
1.1.1.5 ! root      158: 
        !           159:     Buffer zlib;
        !           160:     Buffer zlib_tmp;
        !           161:     z_stream zlib_stream[4];
        !           162: 
        !           163:     VncState *next;
1.1       root      164: };
                    165: 
1.1.1.5 ! root      166: static VncDisplay *vnc_display; /* needed for info vnc */
        !           167: static DisplayChangeListener *dcl;
1.1.1.3   root      168: 
                    169: void do_info_vnc(void)
                    170: {
1.1.1.5 ! root      171:     if (vnc_display == NULL || vnc_display->display == NULL)
1.1.1.3   root      172:        term_printf("VNC server disabled\n");
                    173:     else {
                    174:        term_printf("VNC server active on: ");
1.1.1.5 ! root      175:        term_print_filename(vnc_display->display);
1.1.1.3   root      176:        term_printf("\n");
                    177: 
1.1.1.5 ! root      178:        if (vnc_display->clients == NULL)
1.1.1.3   root      179:            term_printf("No client connected\n");
                    180:        else
                    181:            term_printf("Client connected\n");
                    182:     }
                    183: }
                    184: 
1.1.1.5 ! root      185: static inline uint32_t vnc_has_feature(VncState *vs, int feature) {
        !           186:     return (vs->features & (1 << feature));
        !           187: }
        !           188: 
1.1       root      189: /* TODO
                    190:    1) Get the queue working for IO.
                    191:    2) there is some weirdness when using the -S option (the screen is grey
                    192:       and not totally invalidated
                    193:    3) resolutions > 1024
                    194: */
                    195: 
                    196: static void vnc_write(VncState *vs, const void *data, size_t len);
                    197: static void vnc_write_u32(VncState *vs, uint32_t value);
                    198: static void vnc_write_s32(VncState *vs, int32_t value);
                    199: static void vnc_write_u16(VncState *vs, uint16_t value);
                    200: static void vnc_write_u8(VncState *vs, uint8_t value);
                    201: static void vnc_flush(VncState *vs);
                    202: static void vnc_update_client(void *opaque);
                    203: static void vnc_client_read(void *opaque);
                    204: 
1.1.1.5 ! root      205: static void vnc_colordepth(VncState *vs);
        !           206: 
1.1.1.2   root      207: static inline void vnc_set_bit(uint32_t *d, int k)
                    208: {
                    209:     d[k >> 5] |= 1 << (k & 0x1f);
                    210: }
                    211: 
                    212: static inline void vnc_clear_bit(uint32_t *d, int k)
                    213: {
                    214:     d[k >> 5] &= ~(1 << (k & 0x1f));
                    215: }
                    216: 
                    217: static inline void vnc_set_bits(uint32_t *d, int n, int nb_words)
                    218: {
                    219:     int j;
                    220: 
                    221:     j = 0;
                    222:     while (n >= 32) {
                    223:         d[j++] = -1;
                    224:         n -= 32;
                    225:     }
1.1.1.4   root      226:     if (n > 0)
1.1.1.2   root      227:         d[j++] = (1 << n) - 1;
                    228:     while (j < nb_words)
                    229:         d[j++] = 0;
                    230: }
                    231: 
                    232: static inline int vnc_get_bit(const uint32_t *d, int k)
                    233: {
                    234:     return (d[k >> 5] >> (k & 0x1f)) & 1;
                    235: }
                    236: 
1.1.1.4   root      237: static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2,
1.1.1.2   root      238:                                int nb_words)
                    239: {
                    240:     int i;
                    241:     for(i = 0; i < nb_words; i++) {
                    242:         if ((d1[i] & d2[i]) != 0)
                    243:             return 1;
                    244:     }
                    245:     return 0;
                    246: }
                    247: 
1.1.1.5 ! root      248: static void vnc_update(VncState *vs, int x, int y, int w, int h)
1.1       root      249: {
                    250:     int i;
                    251: 
                    252:     h += y;
                    253: 
1.1.1.4   root      254:     /* round x down to ensure the loop only spans one 16-pixel block per,
                    255:        iteration.  otherwise, if (x % 16) != 0, the last iteration may span
                    256:        two 16-pixel blocks but we only mark the first as dirty
                    257:     */
                    258:     w += (x % 16);
                    259:     x -= (x % 16);
                    260: 
1.1.1.5 ! root      261:     x = MIN(x, vs->serverds.width);
        !           262:     y = MIN(y, vs->serverds.height);
        !           263:     w = MIN(x + w, vs->serverds.width) - x;
        !           264:     h = MIN(h, vs->serverds.height);
        !           265: 
1.1       root      266:     for (; y < h; y++)
                    267:        for (i = 0; i < w; i += 16)
1.1.1.2   root      268:            vnc_set_bit(vs->dirty_row[y], (x + i) / 16);
1.1       root      269: }
                    270: 
1.1.1.5 ! root      271: static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
        !           272: {
        !           273:     VncDisplay *vd = ds->opaque;
        !           274:     VncState *vs = vd->clients;
        !           275:     while (vs != NULL) {
        !           276:         vnc_update(vs, x, y, w, h);
        !           277:         vs = vs->next;
        !           278:     }
        !           279: }
        !           280: 
1.1       root      281: static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
                    282:                                   int32_t encoding)
                    283: {
                    284:     vnc_write_u16(vs, x);
                    285:     vnc_write_u16(vs, y);
                    286:     vnc_write_u16(vs, w);
                    287:     vnc_write_u16(vs, h);
                    288: 
                    289:     vnc_write_s32(vs, encoding);
                    290: }
                    291: 
1.1.1.5 ! root      292: static void buffer_reserve(Buffer *buffer, size_t len)
        !           293: {
        !           294:     if ((buffer->capacity - buffer->offset) < len) {
        !           295:        buffer->capacity += (len + 1024);
        !           296:        buffer->buffer = qemu_realloc(buffer->buffer, buffer->capacity);
        !           297:        if (buffer->buffer == NULL) {
        !           298:            fprintf(stderr, "vnc: out of memory\n");
        !           299:            exit(1);
        !           300:        }
        !           301:     }
        !           302: }
        !           303: 
        !           304: static int buffer_empty(Buffer *buffer)
        !           305: {
        !           306:     return buffer->offset == 0;
        !           307: }
        !           308: 
        !           309: static uint8_t *buffer_end(Buffer *buffer)
        !           310: {
        !           311:     return buffer->buffer + buffer->offset;
        !           312: }
        !           313: 
        !           314: static void buffer_reset(Buffer *buffer)
        !           315: {
        !           316:        buffer->offset = 0;
        !           317: }
        !           318: 
        !           319: static void buffer_append(Buffer *buffer, const void *data, size_t len)
1.1       root      320: {
1.1.1.5 ! root      321:     memcpy(buffer->buffer + buffer->offset, data, len);
        !           322:     buffer->offset += len;
        !           323: }
        !           324: 
        !           325: static void vnc_resize(VncState *vs)
        !           326: {
        !           327:     DisplayState *ds = vs->ds;
        !           328: 
1.1.1.3   root      329:     int size_changed;
1.1       root      330: 
1.1.1.5 ! root      331:     vs->old_data = qemu_realloc(vs->old_data, ds_get_linesize(ds) * ds_get_height(ds));
1.1       root      332: 
1.1.1.5 ! root      333:     if (vs->old_data == NULL) {
1.1       root      334:        fprintf(stderr, "vnc: memory allocation failed\n");
                    335:        exit(1);
                    336:     }
                    337: 
1.1.1.5 ! root      338:     if (ds_get_bytes_per_pixel(ds) != vs->serverds.pf.bytes_per_pixel)
1.1.1.4   root      339:         console_color_init(ds);
1.1.1.5 ! root      340:     vnc_colordepth(vs);
        !           341:     size_changed = ds_get_width(ds) != vs->serverds.width ||
        !           342:                    ds_get_height(ds) != vs->serverds.height;
        !           343:     vs->serverds = *(ds->surface);
        !           344:     if (size_changed) {
        !           345:         if (vs->csock != -1 && vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
        !           346:             vnc_write_u8(vs, 0);  /* msg id */
        !           347:             vnc_write_u8(vs, 0);
        !           348:             vnc_write_u16(vs, 1); /* number of rects */
        !           349:             vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds),
        !           350:                                    VNC_ENCODING_DESKTOPRESIZE);
        !           351:             vnc_flush(vs);
        !           352:         }
1.1.1.4   root      353:     }
1.1.1.5 ! root      354: 
        !           355:     memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
        !           356:     memset(vs->old_data, 42, ds_get_linesize(vs->ds) * ds_get_height(vs->ds));
        !           357: }
        !           358: 
        !           359: static void vnc_dpy_resize(DisplayState *ds)
        !           360: {
        !           361:     VncDisplay *vd = ds->opaque;
        !           362:     VncState *vs = vd->clients;
        !           363:     while (vs != NULL) {
        !           364:         vnc_resize(vs);
        !           365:         vs = vs->next;
1.1       root      366:     }
                    367: }
                    368: 
1.1.1.2   root      369: /* fastest code */
                    370: static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size)
                    371: {
                    372:     vnc_write(vs, pixels, size);
                    373: }
                    374: 
                    375: /* slowest but generic code. */
                    376: static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
                    377: {
1.1.1.5 ! root      378:     uint8_t r, g, b;
1.1.1.2   root      379: 
1.1.1.5 ! root      380:     r = ((((v & vs->serverds.pf.rmask) >> vs->serverds.pf.rshift) << vs->clientds.pf.rbits) >>
        !           381:         vs->serverds.pf.rbits);
        !           382:     g = ((((v & vs->serverds.pf.gmask) >> vs->serverds.pf.gshift) << vs->clientds.pf.gbits) >>
        !           383:         vs->serverds.pf.gbits);
        !           384:     b = ((((v & vs->serverds.pf.bmask) >> vs->serverds.pf.bshift) << vs->clientds.pf.bbits) >>
        !           385:         vs->serverds.pf.bbits);
        !           386:     v = (r << vs->clientds.pf.rshift) |
        !           387:         (g << vs->clientds.pf.gshift) |
        !           388:         (b << vs->clientds.pf.bshift);
        !           389:     switch(vs->clientds.pf.bytes_per_pixel) {
1.1.1.2   root      390:     case 1:
                    391:         buf[0] = v;
                    392:         break;
                    393:     case 2:
1.1.1.5 ! root      394:         if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) {
1.1.1.2   root      395:             buf[0] = v >> 8;
                    396:             buf[1] = v;
                    397:         } else {
                    398:             buf[1] = v >> 8;
                    399:             buf[0] = v;
                    400:         }
                    401:         break;
                    402:     default:
                    403:     case 4:
1.1.1.5 ! root      404:         if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) {
1.1.1.2   root      405:             buf[0] = v >> 24;
                    406:             buf[1] = v >> 16;
                    407:             buf[2] = v >> 8;
                    408:             buf[3] = v;
                    409:         } else {
                    410:             buf[3] = v >> 24;
                    411:             buf[2] = v >> 16;
                    412:             buf[1] = v >> 8;
                    413:             buf[0] = v;
                    414:         }
                    415:         break;
                    416:     }
                    417: }
                    418: 
                    419: static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size)
                    420: {
                    421:     uint8_t buf[4];
                    422: 
1.1.1.5 ! root      423:     if (vs->serverds.pf.bytes_per_pixel == 4) {
        !           424:         uint32_t *pixels = pixels1;
        !           425:         int n, i;
        !           426:         n = size >> 2;
        !           427:         for(i = 0; i < n; i++) {
        !           428:             vnc_convert_pixel(vs, buf, pixels[i]);
        !           429:             vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
        !           430:         }
        !           431:     } else if (vs->serverds.pf.bytes_per_pixel == 2) {
        !           432:         uint16_t *pixels = pixels1;
        !           433:         int n, i;
        !           434:         n = size >> 1;
        !           435:         for(i = 0; i < n; i++) {
        !           436:             vnc_convert_pixel(vs, buf, pixels[i]);
        !           437:             vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
        !           438:         }
        !           439:     } else if (vs->serverds.pf.bytes_per_pixel == 1) {
        !           440:         uint8_t *pixels = pixels1;
        !           441:         int n, i;
        !           442:         n = size;
        !           443:         for(i = 0; i < n; i++) {
        !           444:             vnc_convert_pixel(vs, buf, pixels[i]);
        !           445:             vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
        !           446:         }
        !           447:     } else {
        !           448:         fprintf(stderr, "vnc_write_pixels_generic: VncState color depth not supported\n");
1.1.1.2   root      449:     }
                    450: }
                    451: 
1.1       root      452: static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h)
                    453: {
                    454:     int i;
1.1.1.4   root      455:     uint8_t *row;
1.1       root      456: 
1.1.1.5 ! root      457:     row = ds_get_data(vs->ds) + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds);
1.1       root      458:     for (i = 0; i < h; i++) {
1.1.1.5 ! root      459:        vs->write_pixels(vs, row, w * ds_get_bytes_per_pixel(vs->ds));
        !           460:        row += ds_get_linesize(vs->ds);
1.1       root      461:     }
                    462: }
                    463: 
                    464: static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h)
                    465: {
                    466:     ptr[0] = ((x & 0x0F) << 4) | (y & 0x0F);
                    467:     ptr[1] = (((w - 1) & 0x0F) << 4) | ((h - 1) & 0x0F);
                    468: }
                    469: 
                    470: #define BPP 8
                    471: #include "vnchextile.h"
                    472: #undef BPP
                    473: 
                    474: #define BPP 16
                    475: #include "vnchextile.h"
                    476: #undef BPP
                    477: 
                    478: #define BPP 32
                    479: #include "vnchextile.h"
                    480: #undef BPP
                    481: 
1.1.1.2   root      482: #define GENERIC
1.1.1.5 ! root      483: #define BPP 8
        !           484: #include "vnchextile.h"
        !           485: #undef BPP
        !           486: #undef GENERIC
        !           487: 
        !           488: #define GENERIC
        !           489: #define BPP 16
        !           490: #include "vnchextile.h"
        !           491: #undef BPP
        !           492: #undef GENERIC
        !           493: 
        !           494: #define GENERIC
1.1.1.2   root      495: #define BPP 32
                    496: #include "vnchextile.h"
                    497: #undef BPP
                    498: #undef GENERIC
                    499: 
1.1       root      500: static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, int h)
                    501: {
                    502:     int i, j;
                    503:     int has_fg, has_bg;
1.1.1.5 ! root      504:     uint8_t *last_fg, *last_bg;
1.1       root      505: 
1.1.1.5 ! root      506:     last_fg = (uint8_t *) qemu_malloc(vs->serverds.pf.bytes_per_pixel);
        !           507:     last_bg = (uint8_t *) qemu_malloc(vs->serverds.pf.bytes_per_pixel);
1.1       root      508:     has_fg = has_bg = 0;
                    509:     for (j = y; j < (y + h); j += 16) {
                    510:        for (i = x; i < (x + w); i += 16) {
1.1.1.4   root      511:             vs->send_hextile_tile(vs, i, j,
1.1.1.2   root      512:                                   MIN(16, x + w - i), MIN(16, y + h - j),
1.1.1.5 ! root      513:                                   last_bg, last_fg, &has_bg, &has_fg);
1.1       root      514:        }
                    515:     }
1.1.1.5 ! root      516:     free(last_fg);
        !           517:     free(last_bg);
        !           518: 
        !           519: }
        !           520: 
        !           521: static void vnc_zlib_init(VncState *vs)
        !           522: {
        !           523:     int i;
        !           524:     for (i=0; i<(sizeof(vs->zlib_stream) / sizeof(z_stream)); i++)
        !           525:         vs->zlib_stream[i].opaque = NULL;
        !           526: }
        !           527: 
        !           528: static void vnc_zlib_start(VncState *vs)
        !           529: {
        !           530:     buffer_reset(&vs->zlib);
        !           531: 
        !           532:     // make the output buffer be the zlib buffer, so we can compress it later
        !           533:     vs->zlib_tmp = vs->output;
        !           534:     vs->output = vs->zlib;
        !           535: }
        !           536: 
        !           537: static int vnc_zlib_stop(VncState *vs, int stream_id)
        !           538: {
        !           539:     z_streamp zstream = &vs->zlib_stream[stream_id];
        !           540:     int previous_out;
        !           541: 
        !           542:     // switch back to normal output/zlib buffers
        !           543:     vs->zlib = vs->output;
        !           544:     vs->output = vs->zlib_tmp;
        !           545: 
        !           546:     // compress the zlib buffer
        !           547: 
        !           548:     // initialize the stream
        !           549:     // XXX need one stream per session
        !           550:     if (zstream->opaque != vs) {
        !           551:         int err;
        !           552: 
        !           553:         VNC_DEBUG("VNC: initializing zlib stream %d\n", stream_id);
        !           554:         VNC_DEBUG("VNC: opaque = %p | vs = %p\n", zstream->opaque, vs);
        !           555:         zstream->zalloc = Z_NULL;
        !           556:         zstream->zfree = Z_NULL;
        !           557: 
        !           558:         err = deflateInit2(zstream, vs->tight_compression, Z_DEFLATED, MAX_WBITS,
        !           559:                            MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
        !           560: 
        !           561:         if (err != Z_OK) {
        !           562:             fprintf(stderr, "VNC: error initializing zlib\n");
        !           563:             return -1;
        !           564:         }
        !           565: 
        !           566:         zstream->opaque = vs;
        !           567:     }
        !           568: 
        !           569:     // XXX what to do if tight_compression changed in between?
        !           570: 
        !           571:     // reserve memory in output buffer
        !           572:     buffer_reserve(&vs->output, vs->zlib.offset + 64);
        !           573: 
        !           574:     // set pointers
        !           575:     zstream->next_in = vs->zlib.buffer;
        !           576:     zstream->avail_in = vs->zlib.offset;
        !           577:     zstream->next_out = vs->output.buffer + vs->output.offset;
        !           578:     zstream->avail_out = vs->output.capacity - vs->output.offset;
        !           579:     zstream->data_type = Z_BINARY;
        !           580:     previous_out = zstream->total_out;
        !           581: 
        !           582:     // start encoding
        !           583:     if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) {
        !           584:         fprintf(stderr, "VNC: error during zlib compression\n");
        !           585:         return -1;
        !           586:     }
        !           587: 
        !           588:     vs->output.offset = vs->output.capacity - zstream->avail_out;
        !           589:     return zstream->total_out - previous_out;
        !           590: }
        !           591: 
        !           592: static void send_framebuffer_update_zlib(VncState *vs, int x, int y, int w, int h)
        !           593: {
        !           594:     int old_offset, new_offset, bytes_written;
        !           595: 
        !           596:     vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_ZLIB);
        !           597: 
        !           598:     // remember where we put in the follow-up size
        !           599:     old_offset = vs->output.offset;
        !           600:     vnc_write_s32(vs, 0);
        !           601: 
        !           602:     // compress the stream
        !           603:     vnc_zlib_start(vs);
        !           604:     send_framebuffer_update_raw(vs, x, y, w, h);
        !           605:     bytes_written = vnc_zlib_stop(vs, 0);
        !           606: 
        !           607:     if (bytes_written == -1)
        !           608:         return;
        !           609: 
        !           610:     // hack in the size
        !           611:     new_offset = vs->output.offset;
        !           612:     vs->output.offset = old_offset;
        !           613:     vnc_write_u32(vs, bytes_written);
        !           614:     vs->output.offset = new_offset;
1.1       root      615: }
                    616: 
                    617: static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
                    618: {
1.1.1.5 ! root      619:     switch(vs->vnc_encoding) {
        !           620:        case VNC_ENCODING_ZLIB:
        !           621:            send_framebuffer_update_zlib(vs, x, y, w, h);
        !           622:            break;
        !           623:        case VNC_ENCODING_HEXTILE:
        !           624:            vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
1.1       root      625:            send_framebuffer_update_hextile(vs, x, y, w, h);
1.1.1.5 ! root      626:            break;
        !           627:        default:
        !           628:            vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
1.1       root      629:            send_framebuffer_update_raw(vs, x, y, w, h);
1.1.1.5 ! root      630:            break;
        !           631:     }
1.1       root      632: }
                    633: 
1.1.1.5 ! root      634: static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
1.1       root      635: {
                    636:     vnc_update_client(vs);
                    637: 
                    638:     vnc_write_u8(vs, 0);  /* msg id */
                    639:     vnc_write_u8(vs, 0);
                    640:     vnc_write_u16(vs, 1); /* number of rects */
1.1.1.5 ! root      641:     vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
1.1       root      642:     vnc_write_u16(vs, src_x);
                    643:     vnc_write_u16(vs, src_y);
                    644:     vnc_flush(vs);
                    645: }
                    646: 
1.1.1.5 ! root      647: static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
        !           648: {
        !           649:     VncDisplay *vd = ds->opaque;
        !           650:     VncState *vs = vd->clients;
        !           651:     while (vs != NULL) {
        !           652:         if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT))
        !           653:             vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
        !           654:         else /* TODO */
        !           655:             vnc_update(vs, dst_x, dst_y, w, h);
        !           656:         vs = vs->next;
        !           657:     }
        !           658: }
        !           659: 
1.1       root      660: static int find_dirty_height(VncState *vs, int y, int last_x, int x)
                    661: {
                    662:     int h;
                    663: 
1.1.1.5 ! root      664:     for (h = 1; h < (vs->serverds.height - y); h++) {
1.1       root      665:        int tmp_x;
1.1.1.2   root      666:        if (!vnc_get_bit(vs->dirty_row[y + h], last_x))
1.1       root      667:            break;
                    668:        for (tmp_x = last_x; tmp_x < x; tmp_x++)
1.1.1.2   root      669:            vnc_clear_bit(vs->dirty_row[y + h], tmp_x);
1.1       root      670:     }
                    671: 
                    672:     return h;
                    673: }
                    674: 
                    675: static void vnc_update_client(void *opaque)
                    676: {
                    677:     VncState *vs = opaque;
                    678:     if (vs->need_update && vs->csock != -1) {
                    679:        int y;
1.1.1.4   root      680:        uint8_t *row;
1.1       root      681:        char *old_row;
1.1.1.2   root      682:        uint32_t width_mask[VNC_DIRTY_WORDS];
1.1       root      683:        int n_rectangles;
                    684:        int saved_offset;
                    685:        int has_dirty = 0;
                    686: 
1.1.1.5 ! root      687:         vga_hw_update();
        !           688: 
        !           689:         vnc_set_bits(width_mask, (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
1.1       root      690: 
                    691:        /* Walk through the dirty map and eliminate tiles that
                    692:           really aren't dirty */
1.1.1.5 ! root      693:        row = ds_get_data(vs->ds);
1.1       root      694:        old_row = vs->old_data;
                    695: 
1.1.1.5 ! root      696:        for (y = 0; y < ds_get_height(vs->ds); y++) {
1.1.1.2   root      697:            if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) {
1.1       root      698:                int x;
1.1.1.4   root      699:                uint8_t *ptr;
                    700:                char *old_ptr;
1.1       root      701: 
                    702:                ptr = row;
1.1.1.4   root      703:                old_ptr = (char*)old_row;
1.1       root      704: 
1.1.1.5 ! root      705:                for (x = 0; x < ds_get_width(vs->ds); x += 16) {
        !           706:                    if (memcmp(old_ptr, ptr, 16 * ds_get_bytes_per_pixel(vs->ds)) == 0) {
1.1.1.2   root      707:                        vnc_clear_bit(vs->dirty_row[y], (x / 16));
1.1       root      708:                    } else {
                    709:                        has_dirty = 1;
1.1.1.5 ! root      710:                        memcpy(old_ptr, ptr, 16 * ds_get_bytes_per_pixel(vs->ds));
1.1       root      711:                    }
                    712: 
1.1.1.5 ! root      713:                    ptr += 16 * ds_get_bytes_per_pixel(vs->ds);
        !           714:                    old_ptr += 16 * ds_get_bytes_per_pixel(vs->ds);
1.1       root      715:                }
                    716:            }
                    717: 
1.1.1.5 ! root      718:            row += ds_get_linesize(vs->ds);
        !           719:            old_row += ds_get_linesize(vs->ds);
1.1       root      720:        }
                    721: 
1.1.1.5 ! root      722:        if (!has_dirty && !vs->audio_cap) {
1.1       root      723:            qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
                    724:            return;
                    725:        }
                    726: 
                    727:        /* Count rectangles */
                    728:        n_rectangles = 0;
                    729:        vnc_write_u8(vs, 0);  /* msg id */
                    730:        vnc_write_u8(vs, 0);
                    731:        saved_offset = vs->output.offset;
                    732:        vnc_write_u16(vs, 0);
                    733: 
1.1.1.5 ! root      734:        for (y = 0; y < vs->serverds.height; y++) {
1.1       root      735:            int x;
                    736:            int last_x = -1;
1.1.1.5 ! root      737:            for (x = 0; x < vs->serverds.width / 16; x++) {
1.1.1.2   root      738:                if (vnc_get_bit(vs->dirty_row[y], x)) {
1.1       root      739:                    if (last_x == -1) {
                    740:                        last_x = x;
                    741:                    }
1.1.1.2   root      742:                    vnc_clear_bit(vs->dirty_row[y], x);
1.1       root      743:                } else {
                    744:                    if (last_x != -1) {
                    745:                        int h = find_dirty_height(vs, y, last_x, x);
                    746:                        send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
                    747:                        n_rectangles++;
                    748:                    }
                    749:                    last_x = -1;
                    750:                }
                    751:            }
                    752:            if (last_x != -1) {
                    753:                int h = find_dirty_height(vs, y, last_x, x);
                    754:                send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
                    755:                n_rectangles++;
                    756:            }
                    757:        }
                    758:        vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
                    759:        vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
                    760:        vnc_flush(vs);
                    761: 
                    762:     }
                    763: 
1.1.1.5 ! root      764:     if (vs->csock != -1) {
        !           765:         qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
1.1       root      766:     }
                    767: 
                    768: }
                    769: 
1.1.1.5 ! root      770: /* audio */
        !           771: static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1.1       root      772: {
                    773:     VncState *vs = opaque;
                    774: 
1.1.1.5 ! root      775:     switch (cmd) {
        !           776:     case AUD_CNOTIFY_DISABLE:
        !           777:         vnc_write_u8(vs, 255);
        !           778:         vnc_write_u8(vs, 1);
        !           779:         vnc_write_u16(vs, 0);
        !           780:         vnc_flush(vs);
        !           781:         break;
        !           782: 
        !           783:     case AUD_CNOTIFY_ENABLE:
        !           784:         vnc_write_u8(vs, 255);
        !           785:         vnc_write_u8(vs, 1);
        !           786:         vnc_write_u16(vs, 1);
        !           787:         vnc_flush(vs);
        !           788:         break;
1.1       root      789:     }
                    790: }
                    791: 
1.1.1.5 ! root      792: static void audio_capture_destroy(void *opaque)
1.1       root      793: {
                    794: }
                    795: 
1.1.1.5 ! root      796: static void audio_capture(void *opaque, void *buf, int size)
1.1       root      797: {
1.1.1.5 ! root      798:     VncState *vs = opaque;
        !           799: 
        !           800:     vnc_write_u8(vs, 255);
        !           801:     vnc_write_u8(vs, 1);
        !           802:     vnc_write_u16(vs, 2);
        !           803:     vnc_write_u32(vs, size);
        !           804:     vnc_write(vs, buf, size);
        !           805:     vnc_flush(vs);
1.1       root      806: }
                    807: 
1.1.1.5 ! root      808: static void audio_add(VncState *vs)
1.1       root      809: {
1.1.1.5 ! root      810:     struct audio_capture_ops ops;
        !           811: 
        !           812:     if (vs->audio_cap) {
        !           813:         term_printf ("audio already running\n");
        !           814:         return;
        !           815:     }
        !           816: 
        !           817:     ops.notify = audio_capture_notify;
        !           818:     ops.destroy = audio_capture_destroy;
        !           819:     ops.capture = audio_capture;
        !           820: 
        !           821:     vs->audio_cap = AUD_add_capture(NULL, &vs->as, &ops, vs);
        !           822:     if (!vs->audio_cap) {
        !           823:         term_printf ("Failed to add audio capture\n");
        !           824:     }
1.1       root      825: }
                    826: 
1.1.1.5 ! root      827: static void audio_del(VncState *vs)
1.1       root      828: {
1.1.1.5 ! root      829:     if (vs->audio_cap) {
        !           830:         AUD_del_capture(vs->audio_cap, vs);
        !           831:         vs->audio_cap = NULL;
        !           832:     }
1.1       root      833: }
                    834: 
                    835: static int vnc_client_io_error(VncState *vs, int ret, int last_errno)
                    836: {
                    837:     if (ret == 0 || ret == -1) {
1.1.1.5 ! root      838:         if (ret == -1) {
        !           839:             switch (last_errno) {
        !           840:                 case EINTR:
        !           841:                 case EAGAIN:
        !           842: #ifdef _WIN32
        !           843:                 case WSAEWOULDBLOCK:
        !           844: #endif
        !           845:                     return 0;
        !           846:                 default:
        !           847:                     break;
        !           848:             }
        !           849:         }
1.1       root      850: 
1.1.1.4   root      851:        VNC_DEBUG("Closing down client sock %d %d\n", ret, ret < 0 ? last_errno : 0);
1.1       root      852:        qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
                    853:        closesocket(vs->csock);
1.1.1.5 ! root      854:         qemu_del_timer(vs->timer);
        !           855:         qemu_free_timer(vs->timer);
        !           856:         if (vs->input.buffer) qemu_free(vs->input.buffer);
        !           857:         if (vs->output.buffer) qemu_free(vs->output.buffer);
        !           858: #ifdef CONFIG_VNC_TLS
1.1.1.4   root      859:        if (vs->tls_session) {
                    860:            gnutls_deinit(vs->tls_session);
                    861:            vs->tls_session = NULL;
                    862:        }
                    863: #endif /* CONFIG_VNC_TLS */
1.1.1.5 ! root      864:         audio_del(vs);
        !           865: 
        !           866:         VncState *p, *parent = NULL;
        !           867:         for (p = vs->vd->clients; p != NULL; p = p->next) {
        !           868:             if (p == vs) {
        !           869:                 if (parent)
        !           870:                     parent->next = p->next;
        !           871:                 else
        !           872:                     vs->vd->clients = p->next;
        !           873:                 break;
        !           874:             }
        !           875:             parent = p;
        !           876:         }
        !           877:         if (!vs->vd->clients)
        !           878:             dcl->idle = 1;
        !           879: 
        !           880:         qemu_free(vs->old_data);
        !           881:         qemu_free(vs);
        !           882:   
1.1       root      883:        return 0;
                    884:     }
                    885:     return ret;
                    886: }
                    887: 
                    888: static void vnc_client_error(VncState *vs)
                    889: {
                    890:     vnc_client_io_error(vs, -1, EINVAL);
                    891: }
                    892: 
                    893: static void vnc_client_write(void *opaque)
                    894: {
1.1.1.2   root      895:     long ret;
1.1       root      896:     VncState *vs = opaque;
                    897: 
1.1.1.5 ! root      898: #ifdef CONFIG_VNC_TLS
1.1.1.4   root      899:     if (vs->tls_session) {
                    900:        ret = gnutls_write(vs->tls_session, vs->output.buffer, vs->output.offset);
                    901:        if (ret < 0) {
                    902:            if (ret == GNUTLS_E_AGAIN)
                    903:                errno = EAGAIN;
                    904:            else
                    905:                errno = EIO;
                    906:            ret = -1;
                    907:        }
                    908:     } else
                    909: #endif /* CONFIG_VNC_TLS */
                    910:        ret = send(vs->csock, vs->output.buffer, vs->output.offset, 0);
1.1       root      911:     ret = vnc_client_io_error(vs, ret, socket_error());
                    912:     if (!ret)
                    913:        return;
                    914: 
                    915:     memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));
                    916:     vs->output.offset -= ret;
                    917: 
                    918:     if (vs->output.offset == 0) {
                    919:        qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
                    920:     }
                    921: }
                    922: 
                    923: static void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
                    924: {
                    925:     vs->read_handler = func;
                    926:     vs->read_handler_expect = expecting;
                    927: }
                    928: 
                    929: static void vnc_client_read(void *opaque)
                    930: {
                    931:     VncState *vs = opaque;
1.1.1.2   root      932:     long ret;
1.1       root      933: 
                    934:     buffer_reserve(&vs->input, 4096);
                    935: 
1.1.1.5 ! root      936: #ifdef CONFIG_VNC_TLS
1.1.1.4   root      937:     if (vs->tls_session) {
                    938:        ret = gnutls_read(vs->tls_session, buffer_end(&vs->input), 4096);
                    939:        if (ret < 0) {
                    940:            if (ret == GNUTLS_E_AGAIN)
                    941:                errno = EAGAIN;
                    942:            else
                    943:                errno = EIO;
                    944:            ret = -1;
                    945:        }
                    946:     } else
                    947: #endif /* CONFIG_VNC_TLS */
                    948:        ret = recv(vs->csock, buffer_end(&vs->input), 4096, 0);
1.1       root      949:     ret = vnc_client_io_error(vs, ret, socket_error());
                    950:     if (!ret)
                    951:        return;
                    952: 
                    953:     vs->input.offset += ret;
                    954: 
                    955:     while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
                    956:        size_t len = vs->read_handler_expect;
                    957:        int ret;
                    958: 
                    959:        ret = vs->read_handler(vs, vs->input.buffer, len);
                    960:        if (vs->csock == -1)
                    961:            return;
                    962: 
                    963:        if (!ret) {
                    964:            memmove(vs->input.buffer, vs->input.buffer + len, (vs->input.offset - len));
                    965:            vs->input.offset -= len;
                    966:        } else {
                    967:            vs->read_handler_expect = ret;
                    968:        }
                    969:     }
                    970: }
                    971: 
                    972: static void vnc_write(VncState *vs, const void *data, size_t len)
                    973: {
                    974:     buffer_reserve(&vs->output, len);
                    975: 
                    976:     if (buffer_empty(&vs->output)) {
                    977:        qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
                    978:     }
                    979: 
                    980:     buffer_append(&vs->output, data, len);
                    981: }
                    982: 
                    983: static void vnc_write_s32(VncState *vs, int32_t value)
                    984: {
                    985:     vnc_write_u32(vs, *(uint32_t *)&value);
                    986: }
                    987: 
                    988: static void vnc_write_u32(VncState *vs, uint32_t value)
                    989: {
                    990:     uint8_t buf[4];
                    991: 
                    992:     buf[0] = (value >> 24) & 0xFF;
                    993:     buf[1] = (value >> 16) & 0xFF;
                    994:     buf[2] = (value >>  8) & 0xFF;
                    995:     buf[3] = value & 0xFF;
                    996: 
                    997:     vnc_write(vs, buf, 4);
                    998: }
                    999: 
                   1000: static void vnc_write_u16(VncState *vs, uint16_t value)
                   1001: {
1.1.1.3   root     1002:     uint8_t buf[2];
1.1       root     1003: 
                   1004:     buf[0] = (value >> 8) & 0xFF;
                   1005:     buf[1] = value & 0xFF;
                   1006: 
                   1007:     vnc_write(vs, buf, 2);
                   1008: }
                   1009: 
                   1010: static void vnc_write_u8(VncState *vs, uint8_t value)
                   1011: {
                   1012:     vnc_write(vs, (char *)&value, 1);
                   1013: }
                   1014: 
                   1015: static void vnc_flush(VncState *vs)
                   1016: {
                   1017:     if (vs->output.offset)
                   1018:        vnc_client_write(vs);
                   1019: }
                   1020: 
1.1.1.3   root     1021: static uint8_t read_u8(uint8_t *data, size_t offset)
1.1       root     1022: {
                   1023:     return data[offset];
                   1024: }
                   1025: 
1.1.1.3   root     1026: static uint16_t read_u16(uint8_t *data, size_t offset)
1.1       root     1027: {
                   1028:     return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
                   1029: }
                   1030: 
1.1.1.3   root     1031: static int32_t read_s32(uint8_t *data, size_t offset)
1.1       root     1032: {
                   1033:     return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
                   1034:                     (data[offset + 2] << 8) | data[offset + 3]);
                   1035: }
                   1036: 
1.1.1.3   root     1037: static uint32_t read_u32(uint8_t *data, size_t offset)
1.1       root     1038: {
                   1039:     return ((data[offset] << 24) | (data[offset + 1] << 16) |
                   1040:            (data[offset + 2] << 8) | data[offset + 3]);
                   1041: }
                   1042: 
1.1.1.5 ! root     1043: #ifdef CONFIG_VNC_TLS
1.1.1.4   root     1044: static ssize_t vnc_tls_push(gnutls_transport_ptr_t transport,
                   1045:                             const void *data,
                   1046:                             size_t len) {
                   1047:     struct VncState *vs = (struct VncState *)transport;
                   1048:     int ret;
                   1049: 
                   1050:  retry:
                   1051:     ret = send(vs->csock, data, len, 0);
                   1052:     if (ret < 0) {
                   1053:        if (errno == EINTR)
                   1054:            goto retry;
                   1055:        return -1;
                   1056:     }
                   1057:     return ret;
                   1058: }
                   1059: 
                   1060: 
                   1061: static ssize_t vnc_tls_pull(gnutls_transport_ptr_t transport,
                   1062:                             void *data,
                   1063:                             size_t len) {
                   1064:     struct VncState *vs = (struct VncState *)transport;
                   1065:     int ret;
                   1066: 
                   1067:  retry:
                   1068:     ret = recv(vs->csock, data, len, 0);
                   1069:     if (ret < 0) {
                   1070:        if (errno == EINTR)
                   1071:            goto retry;
                   1072:        return -1;
                   1073:     }
                   1074:     return ret;
                   1075: }
                   1076: #endif /* CONFIG_VNC_TLS */
                   1077: 
                   1078: static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1.1       root     1079: {
                   1080: }
                   1081: 
1.1.1.3   root     1082: static void check_pointer_type_change(VncState *vs, int absolute)
                   1083: {
1.1.1.5 ! root     1084:     if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1.1.1.3   root     1085:        vnc_write_u8(vs, 0);
                   1086:        vnc_write_u8(vs, 0);
                   1087:        vnc_write_u16(vs, 1);
                   1088:        vnc_framebuffer_update(vs, absolute, 0,
1.1.1.5 ! root     1089:                               ds_get_width(vs->ds), ds_get_height(vs->ds),
        !          1090:                                VNC_ENCODING_POINTER_TYPE_CHANGE);
1.1.1.3   root     1091:        vnc_flush(vs);
                   1092:     }
                   1093:     vs->absolute = absolute;
                   1094: }
                   1095: 
1.1       root     1096: static void pointer_event(VncState *vs, int button_mask, int x, int y)
                   1097: {
                   1098:     int buttons = 0;
                   1099:     int dz = 0;
                   1100: 
                   1101:     if (button_mask & 0x01)
                   1102:        buttons |= MOUSE_EVENT_LBUTTON;
                   1103:     if (button_mask & 0x02)
                   1104:        buttons |= MOUSE_EVENT_MBUTTON;
                   1105:     if (button_mask & 0x04)
                   1106:        buttons |= MOUSE_EVENT_RBUTTON;
                   1107:     if (button_mask & 0x08)
                   1108:        dz = -1;
                   1109:     if (button_mask & 0x10)
                   1110:        dz = 1;
1.1.1.3   root     1111: 
                   1112:     if (vs->absolute) {
1.1.1.5 ! root     1113:        kbd_mouse_event(x * 0x7FFF / (ds_get_width(vs->ds) - 1),
        !          1114:                        y * 0x7FFF / (ds_get_height(vs->ds) - 1),
1.1       root     1115:                        dz, buttons);
1.1.1.5 ! root     1116:     } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1.1.1.3   root     1117:        x -= 0x7FFF;
                   1118:        y -= 0x7FFF;
                   1119: 
                   1120:        kbd_mouse_event(x, y, dz, buttons);
1.1       root     1121:     } else {
1.1.1.3   root     1122:        if (vs->last_x != -1)
                   1123:            kbd_mouse_event(x - vs->last_x,
                   1124:                            y - vs->last_y,
                   1125:                            dz, buttons);
                   1126:        vs->last_x = x;
                   1127:        vs->last_y = y;
                   1128:     }
1.1       root     1129: 
1.1.1.3   root     1130:     check_pointer_type_change(vs, kbd_mouse_is_absolute());
                   1131: }
1.1       root     1132: 
1.1.1.3   root     1133: static void reset_keys(VncState *vs)
                   1134: {
                   1135:     int i;
                   1136:     for(i = 0; i < 256; i++) {
                   1137:         if (vs->modifiers_state[i]) {
                   1138:             if (i & 0x80)
                   1139:                 kbd_put_keycode(0xe0);
                   1140:             kbd_put_keycode(i | 0x80);
                   1141:             vs->modifiers_state[i] = 0;
                   1142:         }
1.1       root     1143:     }
                   1144: }
                   1145: 
1.1.1.4   root     1146: static void press_key(VncState *vs, int keysym)
                   1147: {
1.1.1.5 ! root     1148:     kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) & 0x7f);
        !          1149:     kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) | 0x80);
1.1.1.4   root     1150: }
                   1151: 
1.1.1.5 ! root     1152: static void do_key_event(VncState *vs, int down, int keycode, int sym)
1.1       root     1153: {
1.1.1.3   root     1154:     /* QEMU console switch */
                   1155:     switch(keycode) {
                   1156:     case 0x2a:                          /* Left Shift */
                   1157:     case 0x36:                          /* Right Shift */
                   1158:     case 0x1d:                          /* Left CTRL */
                   1159:     case 0x9d:                          /* Right CTRL */
                   1160:     case 0x38:                          /* Left ALT */
                   1161:     case 0xb8:                          /* Right ALT */
                   1162:         if (down)
                   1163:             vs->modifiers_state[keycode] = 1;
                   1164:         else
                   1165:             vs->modifiers_state[keycode] = 0;
                   1166:         break;
1.1.1.4   root     1167:     case 0x02 ... 0x0a: /* '1' to '9' keys */
1.1.1.3   root     1168:         if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
                   1169:             /* Reset the modifiers sent to the current console */
                   1170:             reset_keys(vs);
                   1171:             console_select(keycode - 0x02);
                   1172:             return;
                   1173:         }
                   1174:         break;
1.1.1.5 ! root     1175:     case 0x3a:                 /* CapsLock */
1.1.1.4   root     1176:     case 0x45:                 /* NumLock */
                   1177:         if (!down)
                   1178:             vs->modifiers_state[keycode] ^= 1;
                   1179:         break;
                   1180:     }
                   1181: 
1.1.1.5 ! root     1182:     if (keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1.1.1.4   root     1183:         /* If the numlock state needs to change then simulate an additional
                   1184:            keypress before sending this one.  This will happen if the user
                   1185:            toggles numlock away from the VNC window.
                   1186:         */
1.1.1.5 ! root     1187:         if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1.1.1.4   root     1188:             if (!vs->modifiers_state[0x45]) {
                   1189:                 vs->modifiers_state[0x45] = 1;
                   1190:                 press_key(vs, 0xff7f);
                   1191:             }
                   1192:         } else {
                   1193:             if (vs->modifiers_state[0x45]) {
                   1194:                 vs->modifiers_state[0x45] = 0;
                   1195:                 press_key(vs, 0xff7f);
                   1196:             }
                   1197:         }
1.1.1.3   root     1198:     }
1.1       root     1199: 
1.1.1.3   root     1200:     if (is_graphic_console()) {
                   1201:         if (keycode & 0x80)
                   1202:             kbd_put_keycode(0xe0);
                   1203:         if (down)
                   1204:             kbd_put_keycode(keycode & 0x7f);
                   1205:         else
                   1206:             kbd_put_keycode(keycode | 0x80);
                   1207:     } else {
                   1208:         /* QEMU console emulation */
                   1209:         if (down) {
                   1210:             switch (keycode) {
                   1211:             case 0x2a:                          /* Left Shift */
                   1212:             case 0x36:                          /* Right Shift */
                   1213:             case 0x1d:                          /* Left CTRL */
                   1214:             case 0x9d:                          /* Right CTRL */
                   1215:             case 0x38:                          /* Left ALT */
                   1216:             case 0xb8:                          /* Right ALT */
                   1217:                 break;
                   1218:             case 0xc8:
                   1219:                 kbd_put_keysym(QEMU_KEY_UP);
                   1220:                 break;
                   1221:             case 0xd0:
                   1222:                 kbd_put_keysym(QEMU_KEY_DOWN);
                   1223:                 break;
                   1224:             case 0xcb:
                   1225:                 kbd_put_keysym(QEMU_KEY_LEFT);
                   1226:                 break;
                   1227:             case 0xcd:
                   1228:                 kbd_put_keysym(QEMU_KEY_RIGHT);
                   1229:                 break;
                   1230:             case 0xd3:
                   1231:                 kbd_put_keysym(QEMU_KEY_DELETE);
                   1232:                 break;
                   1233:             case 0xc7:
                   1234:                 kbd_put_keysym(QEMU_KEY_HOME);
                   1235:                 break;
                   1236:             case 0xcf:
                   1237:                 kbd_put_keysym(QEMU_KEY_END);
                   1238:                 break;
                   1239:             case 0xc9:
                   1240:                 kbd_put_keysym(QEMU_KEY_PAGEUP);
                   1241:                 break;
                   1242:             case 0xd1:
                   1243:                 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
                   1244:                 break;
                   1245:             default:
                   1246:                 kbd_put_keysym(sym);
                   1247:                 break;
                   1248:             }
                   1249:         }
                   1250:     }
1.1       root     1251: }
                   1252: 
                   1253: static void key_event(VncState *vs, int down, uint32_t sym)
                   1254: {
1.1.1.5 ! root     1255:     int keycode;
        !          1256: 
1.1.1.4   root     1257:     if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
1.1       root     1258:        sym = sym - 'A' + 'a';
1.1.1.5 ! root     1259: 
        !          1260:     keycode = keysym2scancode(vs->vd->kbd_layout, sym & 0xFFFF);
        !          1261:     do_key_event(vs, down, keycode, sym);
        !          1262: }
        !          1263: 
        !          1264: static void ext_key_event(VncState *vs, int down,
        !          1265:                           uint32_t sym, uint16_t keycode)
        !          1266: {
        !          1267:     /* if the user specifies a keyboard layout, always use it */
        !          1268:     if (keyboard_layout)
        !          1269:         key_event(vs, down, sym);
        !          1270:     else
        !          1271:         do_key_event(vs, down, keycode, sym);
1.1       root     1272: }
                   1273: 
                   1274: static void framebuffer_update_request(VncState *vs, int incremental,
                   1275:                                       int x_position, int y_position,
                   1276:                                       int w, int h)
                   1277: {
1.1.1.5 ! root     1278:     if (x_position > ds_get_width(vs->ds))
        !          1279:         x_position = ds_get_width(vs->ds);
        !          1280:     if (y_position > ds_get_height(vs->ds))
        !          1281:         y_position = ds_get_height(vs->ds);
        !          1282:     if (x_position + w >= ds_get_width(vs->ds))
        !          1283:         w = ds_get_width(vs->ds)  - x_position;
        !          1284:     if (y_position + h >= ds_get_height(vs->ds))
        !          1285:         h = ds_get_height(vs->ds) - y_position;
1.1.1.4   root     1286: 
1.1       root     1287:     int i;
                   1288:     vs->need_update = 1;
                   1289:     if (!incremental) {
1.1.1.5 ! root     1290:        char *old_row = vs->old_data + y_position * ds_get_linesize(vs->ds);
1.1       root     1291: 
                   1292:        for (i = 0; i < h; i++) {
1.1.1.4   root     1293:             vnc_set_bits(vs->dirty_row[y_position + i],
1.1.1.5 ! root     1294:                          (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
        !          1295:            memset(old_row, 42, ds_get_width(vs->ds) * ds_get_bytes_per_pixel(vs->ds));
        !          1296:            old_row += ds_get_linesize(vs->ds);
1.1       root     1297:        }
                   1298:     }
                   1299: }
                   1300: 
1.1.1.5 ! root     1301: static void send_ext_key_event_ack(VncState *vs)
        !          1302: {
        !          1303:     vnc_write_u8(vs, 0);
        !          1304:     vnc_write_u8(vs, 0);
        !          1305:     vnc_write_u16(vs, 1);
        !          1306:     vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
        !          1307:                            VNC_ENCODING_EXT_KEY_EVENT);
        !          1308:     vnc_flush(vs);
        !          1309: }
        !          1310: 
        !          1311: static void send_ext_audio_ack(VncState *vs)
        !          1312: {
        !          1313:     vnc_write_u8(vs, 0);
        !          1314:     vnc_write_u8(vs, 0);
        !          1315:     vnc_write_u16(vs, 1);
        !          1316:     vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
        !          1317:                            VNC_ENCODING_AUDIO);
        !          1318:     vnc_flush(vs);
        !          1319: }
        !          1320: 
1.1       root     1321: static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
                   1322: {
                   1323:     int i;
1.1.1.5 ! root     1324:     unsigned int enc = 0;
1.1       root     1325: 
1.1.1.5 ! root     1326:     vnc_zlib_init(vs);
        !          1327:     vs->features = 0;
        !          1328:     vs->vnc_encoding = 0;
        !          1329:     vs->tight_compression = 9;
        !          1330:     vs->tight_quality = 9;
1.1.1.3   root     1331:     vs->absolute = -1;
1.1       root     1332: 
                   1333:     for (i = n_encodings - 1; i >= 0; i--) {
1.1.1.5 ! root     1334:         enc = encodings[i];
        !          1335:         switch (enc) {
        !          1336:         case VNC_ENCODING_RAW:
        !          1337:             vs->vnc_encoding = enc;
        !          1338:             break;
        !          1339:         case VNC_ENCODING_COPYRECT:
        !          1340:             vs->features |= VNC_FEATURE_COPYRECT_MASK;
        !          1341:             break;
        !          1342:         case VNC_ENCODING_HEXTILE:
        !          1343:             vs->features |= VNC_FEATURE_HEXTILE_MASK;
        !          1344:             vs->vnc_encoding = enc;
        !          1345:             break;
        !          1346:         case VNC_ENCODING_ZLIB:
        !          1347:             vs->features |= VNC_FEATURE_ZLIB_MASK;
        !          1348:             vs->vnc_encoding = enc;
        !          1349:             break;
        !          1350:         case VNC_ENCODING_DESKTOPRESIZE:
        !          1351:             vs->features |= VNC_FEATURE_RESIZE_MASK;
        !          1352:             break;
        !          1353:         case VNC_ENCODING_POINTER_TYPE_CHANGE:
        !          1354:             vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
        !          1355:             break;
        !          1356:         case VNC_ENCODING_EXT_KEY_EVENT:
        !          1357:             send_ext_key_event_ack(vs);
        !          1358:             break;
        !          1359:         case VNC_ENCODING_AUDIO:
        !          1360:             send_ext_audio_ack(vs);
        !          1361:             break;
        !          1362:         case VNC_ENCODING_WMVi:
        !          1363:             vs->features |= VNC_FEATURE_WMVI_MASK;
        !          1364:             break;
        !          1365:         case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
        !          1366:             vs->tight_compression = (enc & 0x0F);
        !          1367:             break;
        !          1368:         case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
        !          1369:             vs->tight_quality = (enc & 0x0F);
        !          1370:             break;
        !          1371:         default:
        !          1372:             VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
        !          1373:             break;
        !          1374:         }
1.1       root     1375:     }
1.1.1.3   root     1376: 
                   1377:     check_pointer_type_change(vs, kbd_mouse_is_absolute());
1.1       root     1378: }
                   1379: 
1.1.1.5 ! root     1380: static void set_pixel_conversion(VncState *vs)
1.1.1.2   root     1381: {
1.1.1.5 ! root     1382:     if ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) ==
        !          1383:         (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) && 
        !          1384:         !memcmp(&(vs->clientds.pf), &(vs->ds->surface->pf), sizeof(PixelFormat))) {
        !          1385:         vs->write_pixels = vnc_write_pixels_copy;
        !          1386:         switch (vs->ds->surface->pf.bits_per_pixel) {
        !          1387:             case 8:
        !          1388:                 vs->send_hextile_tile = send_hextile_tile_8;
        !          1389:                 break;
        !          1390:             case 16:
        !          1391:                 vs->send_hextile_tile = send_hextile_tile_16;
        !          1392:                 break;
        !          1393:             case 32:
        !          1394:                 vs->send_hextile_tile = send_hextile_tile_32;
        !          1395:                 break;
        !          1396:         }
        !          1397:     } else {
        !          1398:         vs->write_pixels = vnc_write_pixels_generic;
        !          1399:         switch (vs->ds->surface->pf.bits_per_pixel) {
        !          1400:             case 8:
        !          1401:                 vs->send_hextile_tile = send_hextile_tile_generic_8;
        !          1402:                 break;
        !          1403:             case 16:
        !          1404:                 vs->send_hextile_tile = send_hextile_tile_generic_16;
        !          1405:                 break;
        !          1406:             case 32:
        !          1407:                 vs->send_hextile_tile = send_hextile_tile_generic_32;
        !          1408:                 break;
        !          1409:         }
1.1.1.2   root     1410:     }
                   1411: }
                   1412: 
1.1       root     1413: static void set_pixel_format(VncState *vs,
                   1414:                             int bits_per_pixel, int depth,
                   1415:                             int big_endian_flag, int true_color_flag,
                   1416:                             int red_max, int green_max, int blue_max,
                   1417:                             int red_shift, int green_shift, int blue_shift)
                   1418: {
1.1.1.2   root     1419:     if (!true_color_flag) {
1.1       root     1420:        vnc_client_error(vs);
1.1.1.2   root     1421:         return;
                   1422:     }
1.1.1.5 ! root     1423: 
        !          1424:     vs->clientds = vs->serverds;
        !          1425:     vs->clientds.pf.rmax = red_max;
        !          1426:     count_bits(vs->clientds.pf.rbits, red_max);
        !          1427:     vs->clientds.pf.rshift = red_shift;
        !          1428:     vs->clientds.pf.rmask = red_max << red_shift;
        !          1429:     vs->clientds.pf.gmax = green_max;
        !          1430:     count_bits(vs->clientds.pf.gbits, green_max);
        !          1431:     vs->clientds.pf.gshift = green_shift;
        !          1432:     vs->clientds.pf.gmask = green_max << green_shift;
        !          1433:     vs->clientds.pf.bmax = blue_max;
        !          1434:     count_bits(vs->clientds.pf.bbits, blue_max);
        !          1435:     vs->clientds.pf.bshift = blue_shift;
        !          1436:     vs->clientds.pf.bmask = blue_max << blue_shift;
        !          1437:     vs->clientds.pf.bits_per_pixel = bits_per_pixel;
        !          1438:     vs->clientds.pf.bytes_per_pixel = bits_per_pixel / 8;
        !          1439:     vs->clientds.pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
        !          1440:     vs->clientds.flags = big_endian_flag ? QEMU_BIG_ENDIAN_FLAG : 0x00;
        !          1441: 
        !          1442:     set_pixel_conversion(vs);
        !          1443: 
        !          1444:     vga_hw_invalidate();
        !          1445:     vga_hw_update();
        !          1446: }
        !          1447: 
        !          1448: static void pixel_format_message (VncState *vs) {
        !          1449:     char pad[3] = { 0, 0, 0 };
        !          1450: 
        !          1451:     vnc_write_u8(vs, vs->ds->surface->pf.bits_per_pixel); /* bits-per-pixel */
        !          1452:     vnc_write_u8(vs, vs->ds->surface->pf.depth); /* depth */
        !          1453: 
        !          1454: #ifdef WORDS_BIGENDIAN
        !          1455:     vnc_write_u8(vs, 1);             /* big-endian-flag */
        !          1456: #else
        !          1457:     vnc_write_u8(vs, 0);             /* big-endian-flag */
        !          1458: #endif
        !          1459:     vnc_write_u8(vs, 1);             /* true-color-flag */
        !          1460:     vnc_write_u16(vs, vs->ds->surface->pf.rmax);     /* red-max */
        !          1461:     vnc_write_u16(vs, vs->ds->surface->pf.gmax);     /* green-max */
        !          1462:     vnc_write_u16(vs, vs->ds->surface->pf.bmax);     /* blue-max */
        !          1463:     vnc_write_u8(vs, vs->ds->surface->pf.rshift);    /* red-shift */
        !          1464:     vnc_write_u8(vs, vs->ds->surface->pf.gshift);    /* green-shift */
        !          1465:     vnc_write_u8(vs, vs->ds->surface->pf.bshift);    /* blue-shift */
        !          1466:     if (vs->ds->surface->pf.bits_per_pixel == 32)
1.1.1.2   root     1467:         vs->send_hextile_tile = send_hextile_tile_32;
1.1.1.5 ! root     1468:     else if (vs->ds->surface->pf.bits_per_pixel == 16)
1.1.1.2   root     1469:         vs->send_hextile_tile = send_hextile_tile_16;
1.1.1.5 ! root     1470:     else if (vs->ds->surface->pf.bits_per_pixel == 8)
1.1.1.2   root     1471:         vs->send_hextile_tile = send_hextile_tile_8;
1.1.1.5 ! root     1472:     vs->clientds = *(vs->ds->surface);
        !          1473:     vs->clientds.flags |= ~QEMU_ALLOCATED_FLAG;
        !          1474:     vs->write_pixels = vnc_write_pixels_copy;
1.1       root     1475: 
1.1.1.5 ! root     1476:     vnc_write(vs, pad, 3);           /* padding */
        !          1477: }
1.1       root     1478: 
1.1.1.5 ! root     1479: static void vnc_dpy_setdata(DisplayState *ds)
        !          1480: {
        !          1481:     /* We don't have to do anything */
        !          1482: }
        !          1483: 
        !          1484: static void vnc_colordepth(VncState *vs)
        !          1485: {
        !          1486:     if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
        !          1487:         /* Sending a WMVi message to notify the client*/
        !          1488:         vnc_write_u8(vs, 0);  /* msg id */
        !          1489:         vnc_write_u8(vs, 0);
        !          1490:         vnc_write_u16(vs, 1); /* number of rects */
        !          1491:         vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), 
        !          1492:                                ds_get_height(vs->ds), VNC_ENCODING_WMVi);
        !          1493:         pixel_format_message(vs);
        !          1494:         vnc_flush(vs);
        !          1495:     } else {
        !          1496:         set_pixel_conversion(vs);
        !          1497:     }
1.1       root     1498: }
                   1499: 
1.1.1.4   root     1500: static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
1.1       root     1501: {
                   1502:     int i;
                   1503:     uint16_t limit;
                   1504: 
                   1505:     switch (data[0]) {
                   1506:     case 0:
                   1507:        if (len == 1)
                   1508:            return 20;
                   1509: 
                   1510:        set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
                   1511:                         read_u8(data, 6), read_u8(data, 7),
                   1512:                         read_u16(data, 8), read_u16(data, 10),
                   1513:                         read_u16(data, 12), read_u8(data, 14),
                   1514:                         read_u8(data, 15), read_u8(data, 16));
                   1515:        break;
                   1516:     case 2:
                   1517:        if (len == 1)
                   1518:            return 4;
                   1519: 
1.1.1.5 ! root     1520:        if (len == 4) {
        !          1521:             limit = read_u16(data, 2);
        !          1522:             if (limit > 0)
        !          1523:                 return 4 + (limit * 4);
        !          1524:         } else
        !          1525:             limit = read_u16(data, 2);
1.1       root     1526: 
                   1527:        for (i = 0; i < limit; i++) {
                   1528:            int32_t val = read_s32(data, 4 + (i * 4));
                   1529:            memcpy(data + 4 + (i * 4), &val, sizeof(val));
                   1530:        }
                   1531: 
                   1532:        set_encodings(vs, (int32_t *)(data + 4), limit);
                   1533:        break;
                   1534:     case 3:
                   1535:        if (len == 1)
                   1536:            return 10;
                   1537: 
                   1538:        framebuffer_update_request(vs,
                   1539:                                   read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
                   1540:                                   read_u16(data, 6), read_u16(data, 8));
                   1541:        break;
                   1542:     case 4:
                   1543:        if (len == 1)
                   1544:            return 8;
                   1545: 
                   1546:        key_event(vs, read_u8(data, 1), read_u32(data, 4));
                   1547:        break;
                   1548:     case 5:
                   1549:        if (len == 1)
                   1550:            return 6;
                   1551: 
                   1552:        pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
                   1553:        break;
                   1554:     case 6:
                   1555:        if (len == 1)
                   1556:            return 8;
                   1557: 
1.1.1.4   root     1558:        if (len == 8) {
                   1559:             uint32_t dlen = read_u32(data, 4);
                   1560:             if (dlen > 0)
                   1561:                 return 8 + dlen;
                   1562:         }
1.1       root     1563: 
                   1564:        client_cut_text(vs, read_u32(data, 4), data + 8);
                   1565:        break;
1.1.1.5 ! root     1566:     case 255:
        !          1567:         if (len == 1)
        !          1568:             return 2;
        !          1569: 
        !          1570:         switch (read_u8(data, 1)) {
        !          1571:         case 0:
        !          1572:             if (len == 2)
        !          1573:                 return 12;
        !          1574: 
        !          1575:             ext_key_event(vs, read_u16(data, 2),
        !          1576:                           read_u32(data, 4), read_u32(data, 8));
        !          1577:             break;
        !          1578:         case 1:
        !          1579:             if (len == 2)
        !          1580:                 return 4;
        !          1581: 
        !          1582:             switch (read_u16 (data, 2)) {
        !          1583:             case 0:
        !          1584:                 audio_add(vs);
        !          1585:                 break;
        !          1586:             case 1:
        !          1587:                 audio_del(vs);
        !          1588:                 break;
        !          1589:             case 2:
        !          1590:                 if (len == 4)
        !          1591:                     return 10;
        !          1592:                 switch (read_u8(data, 4)) {
        !          1593:                 case 0: vs->as.fmt = AUD_FMT_U8; break;
        !          1594:                 case 1: vs->as.fmt = AUD_FMT_S8; break;
        !          1595:                 case 2: vs->as.fmt = AUD_FMT_U16; break;
        !          1596:                 case 3: vs->as.fmt = AUD_FMT_S16; break;
        !          1597:                 case 4: vs->as.fmt = AUD_FMT_U32; break;
        !          1598:                 case 5: vs->as.fmt = AUD_FMT_S32; break;
        !          1599:                 default:
        !          1600:                     printf("Invalid audio format %d\n", read_u8(data, 4));
        !          1601:                     vnc_client_error(vs);
        !          1602:                     break;
        !          1603:                 }
        !          1604:                 vs->as.nchannels = read_u8(data, 5);
        !          1605:                 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
        !          1606:                     printf("Invalid audio channel coount %d\n",
        !          1607:                            read_u8(data, 5));
        !          1608:                     vnc_client_error(vs);
        !          1609:                     break;
        !          1610:                 }
        !          1611:                 vs->as.freq = read_u32(data, 6);
        !          1612:                 break;
        !          1613:             default:
        !          1614:                 printf ("Invalid audio message %d\n", read_u8(data, 4));
        !          1615:                 vnc_client_error(vs);
        !          1616:                 break;
        !          1617:             }
        !          1618:             break;
        !          1619: 
        !          1620:         default:
        !          1621:             printf("Msg: %d\n", read_u16(data, 0));
        !          1622:             vnc_client_error(vs);
        !          1623:             break;
        !          1624:         }
        !          1625:         break;
1.1       root     1626:     default:
                   1627:        printf("Msg: %d\n", data[0]);
                   1628:        vnc_client_error(vs);
                   1629:        break;
                   1630:     }
1.1.1.4   root     1631: 
1.1       root     1632:     vnc_read_when(vs, protocol_client_msg, 1);
                   1633:     return 0;
                   1634: }
                   1635: 
1.1.1.4   root     1636: static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
1.1       root     1637: {
1.1.1.4   root     1638:     char buf[1024];
                   1639:     int size;
1.1       root     1640: 
1.1.1.5 ! root     1641:     vnc_write_u16(vs, ds_get_width(vs->ds));
        !          1642:     vnc_write_u16(vs, ds_get_height(vs->ds));
1.1       root     1643: 
1.1.1.5 ! root     1644:     pixel_format_message(vs);
1.1       root     1645: 
1.1.1.4   root     1646:     if (qemu_name)
                   1647:         size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
                   1648:     else
                   1649:         size = snprintf(buf, sizeof(buf), "QEMU");
                   1650: 
                   1651:     vnc_write_u32(vs, size);
                   1652:     vnc_write(vs, buf, size);
1.1       root     1653:     vnc_flush(vs);
                   1654: 
                   1655:     vnc_read_when(vs, protocol_client_msg, 1);
                   1656: 
                   1657:     return 0;
                   1658: }
                   1659: 
1.1.1.4   root     1660: static void make_challenge(VncState *vs)
1.1       root     1661: {
1.1.1.4   root     1662:     int i;
1.1       root     1663: 
1.1.1.4   root     1664:     srand(time(NULL)+getpid()+getpid()*987654+rand());
                   1665: 
                   1666:     for (i = 0 ; i < sizeof(vs->challenge) ; i++)
                   1667:         vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
                   1668: }
1.1       root     1669: 
1.1.1.4   root     1670: static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
                   1671: {
                   1672:     unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
                   1673:     int i, j, pwlen;
                   1674:     unsigned char key[8];
                   1675: 
1.1.1.5 ! root     1676:     if (!vs->vd->password || !vs->vd->password[0]) {
1.1.1.4   root     1677:        VNC_DEBUG("No password configured on server");
                   1678:        vnc_write_u32(vs, 1); /* Reject auth */
                   1679:        if (vs->minor >= 8) {
                   1680:            static const char err[] = "Authentication failed";
                   1681:            vnc_write_u32(vs, sizeof(err));
                   1682:            vnc_write(vs, err, sizeof(err));
                   1683:        }
                   1684:        vnc_flush(vs);
1.1       root     1685:        vnc_client_error(vs);
                   1686:        return 0;
                   1687:     }
                   1688: 
1.1.1.4   root     1689:     memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
                   1690: 
                   1691:     /* Calculate the expected challenge response */
1.1.1.5 ! root     1692:     pwlen = strlen(vs->vd->password);
1.1.1.4   root     1693:     for (i=0; i<sizeof(key); i++)
1.1.1.5 ! root     1694:         key[i] = i<pwlen ? vs->vd->password[i] : 0;
1.1.1.4   root     1695:     deskey(key, EN0);
                   1696:     for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
                   1697:         des(response+j, response+j);
                   1698: 
                   1699:     /* Compare expected vs actual challenge response */
                   1700:     if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
                   1701:        VNC_DEBUG("Client challenge reponse did not match\n");
                   1702:        vnc_write_u32(vs, 1); /* Reject auth */
                   1703:        if (vs->minor >= 8) {
                   1704:            static const char err[] = "Authentication failed";
                   1705:            vnc_write_u32(vs, sizeof(err));
                   1706:            vnc_write(vs, err, sizeof(err));
                   1707:        }
                   1708:        vnc_flush(vs);
                   1709:        vnc_client_error(vs);
                   1710:     } else {
                   1711:        VNC_DEBUG("Accepting VNC challenge response\n");
                   1712:        vnc_write_u32(vs, 0); /* Accept auth */
                   1713:        vnc_flush(vs);
                   1714: 
                   1715:        vnc_read_when(vs, protocol_client_init, 1);
                   1716:     }
                   1717:     return 0;
                   1718: }
                   1719: 
                   1720: static int start_auth_vnc(VncState *vs)
                   1721: {
                   1722:     make_challenge(vs);
                   1723:     /* Send client a 'random' challenge */
                   1724:     vnc_write(vs, vs->challenge, sizeof(vs->challenge));
1.1       root     1725:     vnc_flush(vs);
                   1726: 
1.1.1.4   root     1727:     vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
                   1728:     return 0;
                   1729: }
                   1730: 
                   1731: 
1.1.1.5 ! root     1732: #ifdef CONFIG_VNC_TLS
1.1.1.4   root     1733: #define DH_BITS 1024
                   1734: static gnutls_dh_params_t dh_params;
                   1735: 
                   1736: static int vnc_tls_initialize(void)
                   1737: {
                   1738:     static int tlsinitialized = 0;
                   1739: 
                   1740:     if (tlsinitialized)
                   1741:        return 1;
                   1742: 
                   1743:     if (gnutls_global_init () < 0)
                   1744:        return 0;
                   1745: 
                   1746:     /* XXX ought to re-generate diffie-hellmen params periodically */
                   1747:     if (gnutls_dh_params_init (&dh_params) < 0)
                   1748:        return 0;
                   1749:     if (gnutls_dh_params_generate2 (dh_params, DH_BITS) < 0)
                   1750:        return 0;
                   1751: 
1.1.1.5 ! root     1752: #if defined(_VNC_DEBUG) && _VNC_DEBUG >= 2
1.1.1.4   root     1753:     gnutls_global_set_log_level(10);
                   1754:     gnutls_global_set_log_function(vnc_debug_gnutls_log);
                   1755: #endif
                   1756: 
                   1757:     tlsinitialized = 1;
                   1758: 
                   1759:     return 1;
                   1760: }
                   1761: 
                   1762: static gnutls_anon_server_credentials vnc_tls_initialize_anon_cred(void)
                   1763: {
                   1764:     gnutls_anon_server_credentials anon_cred;
                   1765:     int ret;
                   1766: 
                   1767:     if ((ret = gnutls_anon_allocate_server_credentials(&anon_cred)) < 0) {
                   1768:        VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
                   1769:        return NULL;
                   1770:     }
                   1771: 
                   1772:     gnutls_anon_set_server_dh_params(anon_cred, dh_params);
                   1773: 
                   1774:     return anon_cred;
                   1775: }
                   1776: 
                   1777: 
                   1778: static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *vs)
                   1779: {
                   1780:     gnutls_certificate_credentials_t x509_cred;
                   1781:     int ret;
                   1782: 
1.1.1.5 ! root     1783:     if (!vs->vd->x509cacert) {
1.1.1.4   root     1784:        VNC_DEBUG("No CA x509 certificate specified\n");
                   1785:        return NULL;
                   1786:     }
1.1.1.5 ! root     1787:     if (!vs->vd->x509cert) {
1.1.1.4   root     1788:        VNC_DEBUG("No server x509 certificate specified\n");
                   1789:        return NULL;
                   1790:     }
1.1.1.5 ! root     1791:     if (!vs->vd->x509key) {
1.1.1.4   root     1792:        VNC_DEBUG("No server private key specified\n");
                   1793:        return NULL;
                   1794:     }
                   1795: 
                   1796:     if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) {
                   1797:        VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
                   1798:        return NULL;
                   1799:     }
                   1800:     if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred,
1.1.1.5 ! root     1801:                                                      vs->vd->x509cacert,
1.1.1.4   root     1802:                                                      GNUTLS_X509_FMT_PEM)) < 0) {
                   1803:        VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret));
                   1804:        gnutls_certificate_free_credentials(x509_cred);
                   1805:        return NULL;
                   1806:     }
                   1807: 
                   1808:     if ((ret = gnutls_certificate_set_x509_key_file (x509_cred,
1.1.1.5 ! root     1809:                                                     vs->vd->x509cert,
        !          1810:                                                     vs->vd->x509key,
1.1.1.4   root     1811:                                                     GNUTLS_X509_FMT_PEM)) < 0) {
                   1812:        VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret));
                   1813:        gnutls_certificate_free_credentials(x509_cred);
                   1814:        return NULL;
                   1815:     }
                   1816: 
1.1.1.5 ! root     1817:     if (vs->vd->x509cacrl) {
1.1.1.4   root     1818:        if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred,
1.1.1.5 ! root     1819:                                                        vs->vd->x509cacrl,
1.1.1.4   root     1820:                                                        GNUTLS_X509_FMT_PEM)) < 0) {
                   1821:            VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret));
                   1822:            gnutls_certificate_free_credentials(x509_cred);
                   1823:            return NULL;
                   1824:        }
                   1825:     }
                   1826: 
                   1827:     gnutls_certificate_set_dh_params (x509_cred, dh_params);
                   1828: 
                   1829:     return x509_cred;
                   1830: }
                   1831: 
                   1832: static int vnc_validate_certificate(struct VncState *vs)
                   1833: {
                   1834:     int ret;
                   1835:     unsigned int status;
                   1836:     const gnutls_datum_t *certs;
                   1837:     unsigned int nCerts, i;
                   1838:     time_t now;
                   1839: 
                   1840:     VNC_DEBUG("Validating client certificate\n");
                   1841:     if ((ret = gnutls_certificate_verify_peers2 (vs->tls_session, &status)) < 0) {
                   1842:        VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret));
                   1843:        return -1;
                   1844:     }
                   1845: 
                   1846:     if ((now = time(NULL)) == ((time_t)-1)) {
                   1847:        return -1;
                   1848:     }
                   1849: 
                   1850:     if (status != 0) {
                   1851:        if (status & GNUTLS_CERT_INVALID)
                   1852:            VNC_DEBUG("The certificate is not trusted.\n");
                   1853: 
                   1854:        if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
                   1855:            VNC_DEBUG("The certificate hasn't got a known issuer.\n");
                   1856: 
                   1857:        if (status & GNUTLS_CERT_REVOKED)
                   1858:            VNC_DEBUG("The certificate has been revoked.\n");
                   1859: 
                   1860:        if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
                   1861:            VNC_DEBUG("The certificate uses an insecure algorithm\n");
                   1862: 
                   1863:        return -1;
                   1864:     } else {
                   1865:        VNC_DEBUG("Certificate is valid!\n");
                   1866:     }
                   1867: 
                   1868:     /* Only support x509 for now */
                   1869:     if (gnutls_certificate_type_get(vs->tls_session) != GNUTLS_CRT_X509)
                   1870:        return -1;
                   1871: 
                   1872:     if (!(certs = gnutls_certificate_get_peers(vs->tls_session, &nCerts)))
                   1873:        return -1;
                   1874: 
                   1875:     for (i = 0 ; i < nCerts ; i++) {
                   1876:        gnutls_x509_crt_t cert;
                   1877:        VNC_DEBUG ("Checking certificate chain %d\n", i);
                   1878:        if (gnutls_x509_crt_init (&cert) < 0)
                   1879:            return -1;
                   1880: 
                   1881:        if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) {
                   1882:            gnutls_x509_crt_deinit (cert);
                   1883:            return -1;
                   1884:        }
                   1885: 
                   1886:        if (gnutls_x509_crt_get_expiration_time (cert) < now) {
                   1887:            VNC_DEBUG("The certificate has expired\n");
                   1888:            gnutls_x509_crt_deinit (cert);
                   1889:            return -1;
                   1890:        }
                   1891: 
                   1892:        if (gnutls_x509_crt_get_activation_time (cert) > now) {
                   1893:            VNC_DEBUG("The certificate is not yet activated\n");
                   1894:            gnutls_x509_crt_deinit (cert);
                   1895:            return -1;
                   1896:        }
                   1897: 
                   1898:        if (gnutls_x509_crt_get_activation_time (cert) > now) {
                   1899:            VNC_DEBUG("The certificate is not yet activated\n");
                   1900:            gnutls_x509_crt_deinit (cert);
                   1901:            return -1;
                   1902:        }
                   1903: 
                   1904:        gnutls_x509_crt_deinit (cert);
                   1905:     }
                   1906: 
                   1907:     return 0;
                   1908: }
                   1909: 
                   1910: 
                   1911: static int start_auth_vencrypt_subauth(VncState *vs)
                   1912: {
1.1.1.5 ! root     1913:     switch (vs->vd->subauth) {
1.1.1.4   root     1914:     case VNC_AUTH_VENCRYPT_TLSNONE:
                   1915:     case VNC_AUTH_VENCRYPT_X509NONE:
                   1916:        VNC_DEBUG("Accept TLS auth none\n");
                   1917:        vnc_write_u32(vs, 0); /* Accept auth completion */
                   1918:        vnc_read_when(vs, protocol_client_init, 1);
                   1919:        break;
                   1920: 
                   1921:     case VNC_AUTH_VENCRYPT_TLSVNC:
                   1922:     case VNC_AUTH_VENCRYPT_X509VNC:
                   1923:        VNC_DEBUG("Start TLS auth VNC\n");
                   1924:        return start_auth_vnc(vs);
                   1925: 
                   1926:     default: /* Should not be possible, but just in case */
1.1.1.5 ! root     1927:        VNC_DEBUG("Reject auth %d\n", vs->vd->auth);
1.1.1.4   root     1928:        vnc_write_u8(vs, 1);
                   1929:        if (vs->minor >= 8) {
                   1930:            static const char err[] = "Unsupported authentication type";
                   1931:            vnc_write_u32(vs, sizeof(err));
                   1932:            vnc_write(vs, err, sizeof(err));
                   1933:        }
                   1934:        vnc_client_error(vs);
                   1935:     }
                   1936: 
                   1937:     return 0;
                   1938: }
                   1939: 
                   1940: static void vnc_handshake_io(void *opaque);
                   1941: 
                   1942: static int vnc_continue_handshake(struct VncState *vs) {
                   1943:     int ret;
                   1944: 
                   1945:     if ((ret = gnutls_handshake(vs->tls_session)) < 0) {
                   1946:        if (!gnutls_error_is_fatal(ret)) {
                   1947:            VNC_DEBUG("Handshake interrupted (blocking)\n");
                   1948:            if (!gnutls_record_get_direction(vs->tls_session))
                   1949:                qemu_set_fd_handler(vs->csock, vnc_handshake_io, NULL, vs);
                   1950:            else
                   1951:                qemu_set_fd_handler(vs->csock, NULL, vnc_handshake_io, vs);
                   1952:            return 0;
                   1953:        }
                   1954:        VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
                   1955:        vnc_client_error(vs);
                   1956:        return -1;
                   1957:     }
                   1958: 
1.1.1.5 ! root     1959:     if (vs->vd->x509verify) {
1.1.1.4   root     1960:        if (vnc_validate_certificate(vs) < 0) {
                   1961:            VNC_DEBUG("Client verification failed\n");
                   1962:            vnc_client_error(vs);
                   1963:            return -1;
                   1964:        } else {
                   1965:            VNC_DEBUG("Client verification passed\n");
                   1966:        }
                   1967:     }
                   1968: 
                   1969:     VNC_DEBUG("Handshake done, switching to TLS data mode\n");
                   1970:     vs->wiremode = VNC_WIREMODE_TLS;
                   1971:     qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
                   1972: 
                   1973:     return start_auth_vencrypt_subauth(vs);
                   1974: }
                   1975: 
                   1976: static void vnc_handshake_io(void *opaque) {
                   1977:     struct VncState *vs = (struct VncState *)opaque;
                   1978: 
                   1979:     VNC_DEBUG("Handshake IO continue\n");
                   1980:     vnc_continue_handshake(vs);
                   1981: }
                   1982: 
                   1983: #define NEED_X509_AUTH(vs)                           \
1.1.1.5 ! root     1984:     ((vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509NONE ||   \
        !          1985:      (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509VNC ||    \
        !          1986:      (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
1.1.1.4   root     1987: 
                   1988: 
                   1989: static int vnc_start_tls(struct VncState *vs) {
                   1990:     static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
                   1991:     static const int protocol_priority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };
                   1992:     static const int kx_anon[] = {GNUTLS_KX_ANON_DH, 0};
                   1993:     static const int kx_x509[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0};
                   1994: 
                   1995:     VNC_DEBUG("Do TLS setup\n");
                   1996:     if (vnc_tls_initialize() < 0) {
                   1997:        VNC_DEBUG("Failed to init TLS\n");
                   1998:        vnc_client_error(vs);
                   1999:        return -1;
                   2000:     }
                   2001:     if (vs->tls_session == NULL) {
                   2002:        if (gnutls_init(&vs->tls_session, GNUTLS_SERVER) < 0) {
                   2003:            vnc_client_error(vs);
                   2004:            return -1;
                   2005:        }
                   2006: 
                   2007:        if (gnutls_set_default_priority(vs->tls_session) < 0) {
                   2008:            gnutls_deinit(vs->tls_session);
                   2009:            vs->tls_session = NULL;
                   2010:            vnc_client_error(vs);
                   2011:            return -1;
                   2012:        }
                   2013: 
                   2014:        if (gnutls_kx_set_priority(vs->tls_session, NEED_X509_AUTH(vs) ? kx_x509 : kx_anon) < 0) {
                   2015:            gnutls_deinit(vs->tls_session);
                   2016:            vs->tls_session = NULL;
                   2017:            vnc_client_error(vs);
                   2018:            return -1;
                   2019:        }
                   2020: 
                   2021:        if (gnutls_certificate_type_set_priority(vs->tls_session, cert_type_priority) < 0) {
                   2022:            gnutls_deinit(vs->tls_session);
                   2023:            vs->tls_session = NULL;
                   2024:            vnc_client_error(vs);
                   2025:            return -1;
                   2026:        }
                   2027: 
                   2028:        if (gnutls_protocol_set_priority(vs->tls_session, protocol_priority) < 0) {
                   2029:            gnutls_deinit(vs->tls_session);
                   2030:            vs->tls_session = NULL;
                   2031:            vnc_client_error(vs);
                   2032:            return -1;
                   2033:        }
                   2034: 
                   2035:        if (NEED_X509_AUTH(vs)) {
                   2036:            gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs);
                   2037:            if (!x509_cred) {
                   2038:                gnutls_deinit(vs->tls_session);
                   2039:                vs->tls_session = NULL;
                   2040:                vnc_client_error(vs);
                   2041:                return -1;
                   2042:            }
                   2043:            if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) {
                   2044:                gnutls_deinit(vs->tls_session);
                   2045:                vs->tls_session = NULL;
                   2046:                gnutls_certificate_free_credentials(x509_cred);
                   2047:                vnc_client_error(vs);
                   2048:                return -1;
                   2049:            }
1.1.1.5 ! root     2050:            if (vs->vd->x509verify) {
1.1.1.4   root     2051:                VNC_DEBUG("Requesting a client certificate\n");
                   2052:                gnutls_certificate_server_set_request (vs->tls_session, GNUTLS_CERT_REQUEST);
                   2053:            }
                   2054: 
                   2055:        } else {
                   2056:            gnutls_anon_server_credentials anon_cred = vnc_tls_initialize_anon_cred();
                   2057:            if (!anon_cred) {
                   2058:                gnutls_deinit(vs->tls_session);
                   2059:                vs->tls_session = NULL;
                   2060:                vnc_client_error(vs);
                   2061:                return -1;
                   2062:            }
                   2063:            if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_ANON, anon_cred) < 0) {
                   2064:                gnutls_deinit(vs->tls_session);
                   2065:                vs->tls_session = NULL;
                   2066:                gnutls_anon_free_server_credentials(anon_cred);
                   2067:                vnc_client_error(vs);
                   2068:                return -1;
                   2069:            }
                   2070:        }
                   2071: 
                   2072:        gnutls_transport_set_ptr(vs->tls_session, (gnutls_transport_ptr_t)vs);
                   2073:        gnutls_transport_set_push_function(vs->tls_session, vnc_tls_push);
                   2074:        gnutls_transport_set_pull_function(vs->tls_session, vnc_tls_pull);
                   2075:     }
                   2076: 
                   2077:     VNC_DEBUG("Start TLS handshake process\n");
                   2078:     return vnc_continue_handshake(vs);
                   2079: }
                   2080: 
                   2081: static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len)
                   2082: {
                   2083:     int auth = read_u32(data, 0);
                   2084: 
1.1.1.5 ! root     2085:     if (auth != vs->vd->subauth) {
1.1.1.4   root     2086:        VNC_DEBUG("Rejecting auth %d\n", auth);
                   2087:        vnc_write_u8(vs, 0); /* Reject auth */
                   2088:        vnc_flush(vs);
                   2089:        vnc_client_error(vs);
                   2090:     } else {
                   2091:        VNC_DEBUG("Accepting auth %d, starting handshake\n", auth);
                   2092:        vnc_write_u8(vs, 1); /* Accept auth */
                   2093:        vnc_flush(vs);
                   2094: 
                   2095:        if (vnc_start_tls(vs) < 0) {
                   2096:            VNC_DEBUG("Failed to complete TLS\n");
                   2097:            return 0;
                   2098:        }
                   2099: 
                   2100:        if (vs->wiremode == VNC_WIREMODE_TLS) {
                   2101:            VNC_DEBUG("Starting VeNCrypt subauth\n");
                   2102:            return start_auth_vencrypt_subauth(vs);
                   2103:        } else {
                   2104:            VNC_DEBUG("TLS handshake blocked\n");
                   2105:            return 0;
                   2106:        }
                   2107:     }
                   2108:     return 0;
                   2109: }
                   2110: 
                   2111: static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len)
                   2112: {
                   2113:     if (data[0] != 0 ||
                   2114:        data[1] != 2) {
                   2115:        VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);
                   2116:        vnc_write_u8(vs, 1); /* Reject version */
                   2117:        vnc_flush(vs);
                   2118:        vnc_client_error(vs);
                   2119:     } else {
1.1.1.5 ! root     2120:        VNC_DEBUG("Sending allowed auth %d\n", vs->vd->subauth);
1.1.1.4   root     2121:        vnc_write_u8(vs, 0); /* Accept version */
                   2122:        vnc_write_u8(vs, 1); /* Number of sub-auths */
1.1.1.5 ! root     2123:        vnc_write_u32(vs, vs->vd->subauth); /* The supported auth */
1.1.1.4   root     2124:        vnc_flush(vs);
                   2125:        vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
                   2126:     }
                   2127:     return 0;
                   2128: }
                   2129: 
                   2130: static int start_auth_vencrypt(VncState *vs)
                   2131: {
                   2132:     /* Send VeNCrypt version 0.2 */
                   2133:     vnc_write_u8(vs, 0);
                   2134:     vnc_write_u8(vs, 2);
                   2135: 
                   2136:     vnc_read_when(vs, protocol_client_vencrypt_init, 2);
                   2137:     return 0;
                   2138: }
                   2139: #endif /* CONFIG_VNC_TLS */
                   2140: 
                   2141: static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
                   2142: {
                   2143:     /* We only advertise 1 auth scheme at a time, so client
                   2144:      * must pick the one we sent. Verify this */
1.1.1.5 ! root     2145:     if (data[0] != vs->vd->auth) { /* Reject auth */
1.1.1.4   root     2146:        VNC_DEBUG("Reject auth %d\n", (int)data[0]);
                   2147:        vnc_write_u32(vs, 1);
                   2148:        if (vs->minor >= 8) {
                   2149:            static const char err[] = "Authentication failed";
                   2150:            vnc_write_u32(vs, sizeof(err));
                   2151:            vnc_write(vs, err, sizeof(err));
                   2152:        }
                   2153:        vnc_client_error(vs);
                   2154:     } else { /* Accept requested auth */
                   2155:        VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
1.1.1.5 ! root     2156:        switch (vs->vd->auth) {
1.1.1.4   root     2157:        case VNC_AUTH_NONE:
                   2158:            VNC_DEBUG("Accept auth none\n");
                   2159:            if (vs->minor >= 8) {
                   2160:                vnc_write_u32(vs, 0); /* Accept auth completion */
                   2161:                vnc_flush(vs);
                   2162:            }
                   2163:            vnc_read_when(vs, protocol_client_init, 1);
                   2164:            break;
                   2165: 
                   2166:        case VNC_AUTH_VNC:
                   2167:            VNC_DEBUG("Start VNC auth\n");
                   2168:            return start_auth_vnc(vs);
                   2169: 
1.1.1.5 ! root     2170: #ifdef CONFIG_VNC_TLS
1.1.1.4   root     2171:        case VNC_AUTH_VENCRYPT:
                   2172:            VNC_DEBUG("Accept VeNCrypt auth\n");;
                   2173:            return start_auth_vencrypt(vs);
                   2174: #endif /* CONFIG_VNC_TLS */
                   2175: 
                   2176:        default: /* Should not be possible, but just in case */
1.1.1.5 ! root     2177:            VNC_DEBUG("Reject auth %d\n", vs->vd->auth);
1.1.1.4   root     2178:            vnc_write_u8(vs, 1);
                   2179:            if (vs->minor >= 8) {
                   2180:                static const char err[] = "Authentication failed";
                   2181:                vnc_write_u32(vs, sizeof(err));
                   2182:                vnc_write(vs, err, sizeof(err));
                   2183:            }
                   2184:            vnc_client_error(vs);
                   2185:        }
                   2186:     }
                   2187:     return 0;
                   2188: }
                   2189: 
                   2190: static int protocol_version(VncState *vs, uint8_t *version, size_t len)
                   2191: {
                   2192:     char local[13];
                   2193: 
                   2194:     memcpy(local, version, 12);
                   2195:     local[12] = 0;
                   2196: 
                   2197:     if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
                   2198:        VNC_DEBUG("Malformed protocol version %s\n", local);
                   2199:        vnc_client_error(vs);
                   2200:        return 0;
                   2201:     }
                   2202:     VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
                   2203:     if (vs->major != 3 ||
                   2204:        (vs->minor != 3 &&
                   2205:         vs->minor != 4 &&
                   2206:         vs->minor != 5 &&
                   2207:         vs->minor != 7 &&
                   2208:         vs->minor != 8)) {
                   2209:        VNC_DEBUG("Unsupported client version\n");
                   2210:        vnc_write_u32(vs, VNC_AUTH_INVALID);
                   2211:        vnc_flush(vs);
                   2212:        vnc_client_error(vs);
                   2213:        return 0;
                   2214:     }
                   2215:     /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
                   2216:      * as equivalent to v3.3 by servers
                   2217:      */
                   2218:     if (vs->minor == 4 || vs->minor == 5)
                   2219:        vs->minor = 3;
                   2220: 
                   2221:     if (vs->minor == 3) {
1.1.1.5 ! root     2222:        if (vs->vd->auth == VNC_AUTH_NONE) {
1.1.1.4   root     2223:             VNC_DEBUG("Tell client auth none\n");
1.1.1.5 ! root     2224:             vnc_write_u32(vs, vs->vd->auth);
1.1.1.4   root     2225:             vnc_flush(vs);
                   2226:             vnc_read_when(vs, protocol_client_init, 1);
1.1.1.5 ! root     2227:        } else if (vs->vd->auth == VNC_AUTH_VNC) {
1.1.1.4   root     2228:             VNC_DEBUG("Tell client VNC auth\n");
1.1.1.5 ! root     2229:             vnc_write_u32(vs, vs->vd->auth);
1.1.1.4   root     2230:             vnc_flush(vs);
                   2231:             start_auth_vnc(vs);
                   2232:        } else {
1.1.1.5 ! root     2233:             VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->vd->auth);
1.1.1.4   root     2234:             vnc_write_u32(vs, VNC_AUTH_INVALID);
                   2235:             vnc_flush(vs);
                   2236:             vnc_client_error(vs);
                   2237:        }
                   2238:     } else {
1.1.1.5 ! root     2239:        VNC_DEBUG("Telling client we support auth %d\n", vs->vd->auth);
1.1.1.4   root     2240:        vnc_write_u8(vs, 1); /* num auth */
1.1.1.5 ! root     2241:        vnc_write_u8(vs, vs->vd->auth);
1.1.1.4   root     2242:        vnc_read_when(vs, protocol_client_auth, 1);
                   2243:        vnc_flush(vs);
                   2244:     }
1.1       root     2245: 
                   2246:     return 0;
                   2247: }
                   2248: 
1.1.1.5 ! root     2249: static void vnc_connect(VncDisplay *vd, int csock)
        !          2250: {
        !          2251:     VncState *vs = qemu_mallocz(sizeof(VncState));
        !          2252:     vs->csock = csock;
        !          2253: 
        !          2254:     VNC_DEBUG("New client on socket %d\n", csock);
        !          2255:     dcl->idle = 0;
        !          2256:     socket_set_nonblock(vs->csock);
        !          2257:     qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
        !          2258: 
        !          2259:     vs->vd = vd;
        !          2260:     vs->ds = vd->ds;
        !          2261:     vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
        !          2262:     vs->last_x = -1;
        !          2263:     vs->last_y = -1;
        !          2264: 
        !          2265:     vs->as.freq = 44100;
        !          2266:     vs->as.nchannels = 2;
        !          2267:     vs->as.fmt = AUD_FMT_S16;
        !          2268:     vs->as.endianness = 0;
        !          2269: 
        !          2270:     vnc_resize(vs);
        !          2271:     vnc_write(vs, "RFB 003.008\n", 12);
        !          2272:     vnc_flush(vs);
        !          2273:     vnc_read_when(vs, protocol_version, 12);
        !          2274:     memset(vs->old_data, 0, ds_get_linesize(vs->ds) * ds_get_height(vs->ds));
        !          2275:     memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
        !          2276:     vnc_update_client(vs);
        !          2277:     reset_keys(vs);
        !          2278: 
        !          2279:     vs->next = vd->clients;
        !          2280:     vd->clients = vs;
        !          2281: }
        !          2282: 
1.1       root     2283: static void vnc_listen_read(void *opaque)
                   2284: {
1.1.1.5 ! root     2285:     VncDisplay *vs = opaque;
1.1       root     2286:     struct sockaddr_in addr;
                   2287:     socklen_t addrlen = sizeof(addr);
                   2288: 
1.1.1.5 ! root     2289:     /* Catch-up */
        !          2290:     vga_hw_update();
        !          2291: 
        !          2292:     int csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
        !          2293:     if (csock != -1) {
        !          2294:         vnc_connect(vs, csock);
1.1       root     2295:     }
                   2296: }
                   2297: 
1.1.1.4   root     2298: void vnc_display_init(DisplayState *ds)
1.1       root     2299: {
1.1.1.5 ! root     2300:     VncDisplay *vs;
1.1       root     2301: 
                   2302:     vs = qemu_mallocz(sizeof(VncState));
1.1.1.5 ! root     2303:     dcl = qemu_mallocz(sizeof(DisplayChangeListener));
1.1       root     2304: 
                   2305:     ds->opaque = vs;
1.1.1.5 ! root     2306:     dcl->idle = 1;
        !          2307:     vnc_display = vs;
1.1       root     2308: 
                   2309:     vs->lsock = -1;
                   2310: 
                   2311:     vs->ds = ds;
                   2312: 
1.1.1.5 ! root     2313:     if (keyboard_layout)
        !          2314:         vs->kbd_layout = init_keyboard_layout(keyboard_layout);
        !          2315:     else
        !          2316:         vs->kbd_layout = init_keyboard_layout("en-us");
1.1       root     2317: 
                   2318:     if (!vs->kbd_layout)
                   2319:        exit(1);
                   2320: 
1.1.1.5 ! root     2321:     dcl->dpy_copy = vnc_dpy_copy;
        !          2322:     dcl->dpy_update = vnc_dpy_update;
        !          2323:     dcl->dpy_resize = vnc_dpy_resize;
        !          2324:     dcl->dpy_setdata = vnc_dpy_setdata;
        !          2325:     register_displaychangelistener(ds, dcl);
1.1.1.4   root     2326: }
                   2327: 
1.1.1.5 ! root     2328: #ifdef CONFIG_VNC_TLS
        !          2329: static int vnc_set_x509_credential(VncDisplay *vs,
1.1.1.4   root     2330:                                   const char *certdir,
                   2331:                                   const char *filename,
                   2332:                                   char **cred,
                   2333:                                   int ignoreMissing)
                   2334: {
                   2335:     struct stat sb;
                   2336: 
                   2337:     if (*cred) {
                   2338:        qemu_free(*cred);
                   2339:        *cred = NULL;
                   2340:     }
                   2341: 
1.1.1.5 ! root     2342:     *cred = qemu_malloc(strlen(certdir) + strlen(filename) + 2);
1.1.1.4   root     2343: 
                   2344:     strcpy(*cred, certdir);
                   2345:     strcat(*cred, "/");
                   2346:     strcat(*cred, filename);
                   2347: 
                   2348:     VNC_DEBUG("Check %s\n", *cred);
                   2349:     if (stat(*cred, &sb) < 0) {
                   2350:        qemu_free(*cred);
                   2351:        *cred = NULL;
                   2352:        if (ignoreMissing && errno == ENOENT)
                   2353:            return 0;
                   2354:        return -1;
                   2355:     }
                   2356: 
                   2357:     return 0;
                   2358: }
1.1.1.3   root     2359: 
1.1.1.5 ! root     2360: static int vnc_set_x509_credential_dir(VncDisplay *vs,
1.1.1.4   root     2361:                                       const char *certdir)
                   2362: {
                   2363:     if (vnc_set_x509_credential(vs, certdir, X509_CA_CERT_FILE, &vs->x509cacert, 0) < 0)
                   2364:        goto cleanup;
                   2365:     if (vnc_set_x509_credential(vs, certdir, X509_CA_CRL_FILE, &vs->x509cacrl, 1) < 0)
                   2366:        goto cleanup;
                   2367:     if (vnc_set_x509_credential(vs, certdir, X509_SERVER_CERT_FILE, &vs->x509cert, 0) < 0)
                   2368:        goto cleanup;
                   2369:     if (vnc_set_x509_credential(vs, certdir, X509_SERVER_KEY_FILE, &vs->x509key, 0) < 0)
                   2370:        goto cleanup;
                   2371: 
                   2372:     return 0;
                   2373: 
                   2374:  cleanup:
                   2375:     qemu_free(vs->x509cacert);
                   2376:     qemu_free(vs->x509cacrl);
                   2377:     qemu_free(vs->x509cert);
                   2378:     qemu_free(vs->x509key);
                   2379:     vs->x509cacert = vs->x509cacrl = vs->x509cert = vs->x509key = NULL;
                   2380:     return -1;
                   2381: }
                   2382: #endif /* CONFIG_VNC_TLS */
                   2383: 
                   2384: void vnc_display_close(DisplayState *ds)
                   2385: {
1.1.1.5 ! root     2386:     VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
1.1.1.4   root     2387: 
1.1.1.5 ! root     2388:     if (!vs)
        !          2389:         return;
1.1.1.4   root     2390:     if (vs->display) {
                   2391:        qemu_free(vs->display);
                   2392:        vs->display = NULL;
                   2393:     }
                   2394:     if (vs->lsock != -1) {
                   2395:        qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
                   2396:        close(vs->lsock);
                   2397:        vs->lsock = -1;
                   2398:     }
                   2399:     vs->auth = VNC_AUTH_INVALID;
1.1.1.5 ! root     2400: #ifdef CONFIG_VNC_TLS
1.1.1.4   root     2401:     vs->subauth = VNC_AUTH_INVALID;
                   2402:     vs->x509verify = 0;
                   2403: #endif
                   2404: }
                   2405: 
                   2406: int vnc_display_password(DisplayState *ds, const char *password)
                   2407: {
1.1.1.5 ! root     2408:     VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
1.1.1.4   root     2409: 
                   2410:     if (vs->password) {
                   2411:        qemu_free(vs->password);
                   2412:        vs->password = NULL;
                   2413:     }
                   2414:     if (password && password[0]) {
                   2415:        if (!(vs->password = qemu_strdup(password)))
                   2416:            return -1;
                   2417:     }
                   2418: 
                   2419:     return 0;
                   2420: }
                   2421: 
                   2422: int vnc_display_open(DisplayState *ds, const char *display)
                   2423: {
1.1.1.5 ! root     2424:     VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
1.1.1.4   root     2425:     const char *options;
                   2426:     int password = 0;
1.1.1.5 ! root     2427:     int reverse = 0;
        !          2428:     int to_port = 0;
        !          2429: #ifdef CONFIG_VNC_TLS
1.1.1.4   root     2430:     int tls = 0, x509 = 0;
                   2431: #endif
                   2432: 
1.1.1.5 ! root     2433:     if (!vnc_display)
        !          2434:         return -1;
1.1.1.4   root     2435:     vnc_display_close(ds);
                   2436:     if (strcmp(display, "none") == 0)
                   2437:        return 0;
                   2438: 
                   2439:     if (!(vs->display = strdup(display)))
                   2440:        return -1;
                   2441: 
                   2442:     options = display;
                   2443:     while ((options = strchr(options, ','))) {
                   2444:        options++;
                   2445:        if (strncmp(options, "password", 8) == 0) {
                   2446:            password = 1; /* Require password auth */
1.1.1.5 ! root     2447:        } else if (strncmp(options, "reverse", 7) == 0) {
        !          2448:            reverse = 1;
        !          2449:        } else if (strncmp(options, "to=", 3) == 0) {
        !          2450:             to_port = atoi(options+3) + 5900;
        !          2451: #ifdef CONFIG_VNC_TLS
1.1.1.4   root     2452:        } else if (strncmp(options, "tls", 3) == 0) {
                   2453:            tls = 1; /* Require TLS */
                   2454:        } else if (strncmp(options, "x509", 4) == 0) {
                   2455:            char *start, *end;
                   2456:            x509 = 1; /* Require x509 certificates */
                   2457:            if (strncmp(options, "x509verify", 10) == 0)
                   2458:                vs->x509verify = 1; /* ...and verify client certs */
                   2459: 
                   2460:            /* Now check for 'x509=/some/path' postfix
                   2461:             * and use that to setup x509 certificate/key paths */
                   2462:            start = strchr(options, '=');
                   2463:            end = strchr(options, ',');
                   2464:            if (start && (!end || (start < end))) {
                   2465:                int len = end ? end-(start+1) : strlen(start+1);
1.1.1.5 ! root     2466:                char *path = qemu_strndup(start + 1, len);
        !          2467: 
1.1.1.4   root     2468:                VNC_DEBUG("Trying certificate path '%s'\n", path);
                   2469:                if (vnc_set_x509_credential_dir(vs, path) < 0) {
                   2470:                    fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
                   2471:                    qemu_free(path);
                   2472:                    qemu_free(vs->display);
                   2473:                    vs->display = NULL;
                   2474:                    return -1;
                   2475:                }
                   2476:                qemu_free(path);
                   2477:            } else {
                   2478:                fprintf(stderr, "No certificate path provided\n");
                   2479:                qemu_free(vs->display);
                   2480:                vs->display = NULL;
                   2481:                return -1;
                   2482:            }
                   2483: #endif
                   2484:        }
                   2485:     }
                   2486: 
                   2487:     if (password) {
1.1.1.5 ! root     2488: #ifdef CONFIG_VNC_TLS
1.1.1.4   root     2489:        if (tls) {
                   2490:            vs->auth = VNC_AUTH_VENCRYPT;
                   2491:            if (x509) {
                   2492:                VNC_DEBUG("Initializing VNC server with x509 password auth\n");
                   2493:                vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
                   2494:            } else {
                   2495:                VNC_DEBUG("Initializing VNC server with TLS password auth\n");
                   2496:                vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
                   2497:            }
                   2498:        } else {
                   2499: #endif
                   2500:            VNC_DEBUG("Initializing VNC server with password auth\n");
                   2501:            vs->auth = VNC_AUTH_VNC;
1.1.1.5 ! root     2502: #ifdef CONFIG_VNC_TLS
1.1.1.4   root     2503:            vs->subauth = VNC_AUTH_INVALID;
                   2504:        }
                   2505: #endif
                   2506:     } else {
1.1.1.5 ! root     2507: #ifdef CONFIG_VNC_TLS
1.1.1.4   root     2508:        if (tls) {
                   2509:            vs->auth = VNC_AUTH_VENCRYPT;
                   2510:            if (x509) {
                   2511:                VNC_DEBUG("Initializing VNC server with x509 no auth\n");
                   2512:                vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
                   2513:            } else {
                   2514:                VNC_DEBUG("Initializing VNC server with TLS no auth\n");
                   2515:                vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
                   2516:            }
                   2517:        } else {
                   2518: #endif
                   2519:            VNC_DEBUG("Initializing VNC server with no auth\n");
                   2520:            vs->auth = VNC_AUTH_NONE;
1.1.1.5 ! root     2521: #ifdef CONFIG_VNC_TLS
1.1.1.4   root     2522:            vs->subauth = VNC_AUTH_INVALID;
                   2523:        }
                   2524: #endif
                   2525:     }
1.1       root     2526: 
1.1.1.5 ! root     2527:     if (reverse) {
        !          2528:         /* connect to viewer */
        !          2529:         if (strncmp(display, "unix:", 5) == 0)
        !          2530:             vs->lsock = unix_connect(display+5);
        !          2531:         else
        !          2532:             vs->lsock = inet_connect(display, SOCK_STREAM);
        !          2533:         if (-1 == vs->lsock) {
        !          2534:             free(vs->display);
        !          2535:             vs->display = NULL;
        !          2536:             return -1;
        !          2537:         } else {
        !          2538:             int csock = vs->lsock;
        !          2539:             vs->lsock = -1;
        !          2540:             vnc_connect(vs, csock);
        !          2541:         }
        !          2542:         return 0;
1.1       root     2543: 
1.1.1.5 ! root     2544:     } else {
        !          2545:         /* listen for connects */
        !          2546:         char *dpy;
        !          2547:         dpy = qemu_malloc(256);
        !          2548:         if (strncmp(display, "unix:", 5) == 0) {
        !          2549:             pstrcpy(dpy, 256, "unix:");
        !          2550:             vs->lsock = unix_listen(display+5, dpy+5, 256-5);
        !          2551:         } else {
        !          2552:             vs->lsock = inet_listen(display, dpy, 256, SOCK_STREAM, 5900);
        !          2553:         }
        !          2554:         if (-1 == vs->lsock) {
        !          2555:             free(dpy);
        !          2556:             return -1;
        !          2557:         } else {
        !          2558:             free(vs->display);
        !          2559:             vs->display = dpy;
        !          2560:         }
1.1       root     2561:     }
1.1.1.5 ! root     2562:     return qemu_set_fd_handler2(vs->lsock, NULL, vnc_listen_read, NULL, vs);
1.1       root     2563: }

unix.superglobalmegacorp.com