Statistics
| Branch: | Revision:

root / vnc.c @ 70240ca6

History | View | Annotate | Download (65.5 kB)

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