Statistics
| Branch: | Revision:

root / vnc.c @ 925fd0f2

History | View | Annotate | Download (30.9 kB)

1
/*
2
 * QEMU VNC display driver
3
 * 
4
 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5
 * Copyright (C) 2006 Fabrice Bellard
6
 * 
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 * of this software and associated documentation files (the "Software"), to deal
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in
15
 * all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
 * THE SOFTWARE.
24
 */
25

    
26
#include "vl.h"
27
#include "qemu_socket.h"
28

    
29
#define VNC_REFRESH_INTERVAL (1000 / 30)
30

    
31
#include "vnc_keysym.h"
32
#include "keymaps.c"
33

    
34
typedef struct Buffer
35
{
36
    size_t capacity;
37
    size_t offset;
38
    char *buffer;
39
} Buffer;
40

    
41
typedef struct VncState VncState;
42

    
43
typedef int VncReadEvent(VncState *vs, char *data, size_t len);
44

    
45
typedef void VncWritePixels(VncState *vs, void *data, int size);
46

    
47
typedef void VncSendHextileTile(VncState *vs,
48
                                int x, int y, int w, int h,
49
                                uint32_t *last_bg, 
50
                                uint32_t *last_fg,
51
                                int *has_bg, int *has_fg);
52

    
53
#define VNC_MAX_WIDTH 2048
54
#define VNC_MAX_HEIGHT 2048
55
#define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * 32))
56

    
57
struct VncState
58
{
59
    QEMUTimer *timer;
60
    int lsock;
61
    int csock;
62
    DisplayState *ds;
63
    int need_update;
64
    int width;
65
    int height;
66
    uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
67
    char *old_data;
68
    int depth; /* internal VNC frame buffer byte per pixel */
69
    int has_resize;
70
    int has_hextile;
71
    int has_pointer_type_change;
72
    int absolute;
73
    int last_x;
74
    int last_y;
75

    
76
    const char *display;
77

    
78
    Buffer output;
79
    Buffer input;
80
    kbd_layout_t *kbd_layout;
81
    /* current output mode information */
82
    VncWritePixels *write_pixels;
83
    VncSendHextileTile *send_hextile_tile;
84
    int pix_bpp, pix_big_endian;
85
    int red_shift, red_max, red_shift1;
86
    int green_shift, green_max, green_shift1;
87
    int blue_shift, blue_max, blue_shift1;
88

    
89
    VncReadEvent *read_handler;
90
    size_t read_handler_expect;
91
    /* input */
92
    uint8_t modifiers_state[256];
93
};
94

    
95
static VncState *vnc_state; /* needed for info vnc */
96

    
97
void do_info_vnc(void)
98
{
99
    if (vnc_state == NULL)
100
        term_printf("VNC server disabled\n");
101
    else {
102
        term_printf("VNC server active on: ");
103
        term_print_filename(vnc_state->display);
104
        term_printf("\n");
105

    
106
        if (vnc_state->csock == -1)
107
            term_printf("No client connected\n");
108
        else
109
            term_printf("Client connected\n");
110
    }
111
}
112

    
113
/* TODO
114
   1) Get the queue working for IO.
115
   2) there is some weirdness when using the -S option (the screen is grey
116
      and not totally invalidated
117
   3) resolutions > 1024
118
*/
119

    
120
static void vnc_write(VncState *vs, const void *data, size_t len);
121
static void vnc_write_u32(VncState *vs, uint32_t value);
122
static void vnc_write_s32(VncState *vs, int32_t value);
123
static void vnc_write_u16(VncState *vs, uint16_t value);
124
static void vnc_write_u8(VncState *vs, uint8_t value);
125
static void vnc_flush(VncState *vs);
126
static void vnc_update_client(void *opaque);
127
static void vnc_client_read(void *opaque);
128

    
129
static inline void vnc_set_bit(uint32_t *d, int k)
130
{
131
    d[k >> 5] |= 1 << (k & 0x1f);
132
}
133

    
134
static inline void vnc_clear_bit(uint32_t *d, int k)
135
{
136
    d[k >> 5] &= ~(1 << (k & 0x1f));
137
}
138

    
139
static inline void vnc_set_bits(uint32_t *d, int n, int nb_words)
140
{
141
    int j;
142

    
143
    j = 0;
144
    while (n >= 32) {
145
        d[j++] = -1;
146
        n -= 32;
147
    }
148
    if (n > 0) 
149
        d[j++] = (1 << n) - 1;
150
    while (j < nb_words)
151
        d[j++] = 0;
152
}
153

    
154
static inline int vnc_get_bit(const uint32_t *d, int k)
155
{
156
    return (d[k >> 5] >> (k & 0x1f)) & 1;
157
}
158

    
159
static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2, 
160
                               int nb_words)
161
{
162
    int i;
163
    for(i = 0; i < nb_words; i++) {
164
        if ((d1[i] & d2[i]) != 0)
165
            return 1;
166
    }
167
    return 0;
168
}
169

    
170
static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
171
{
172
    VncState *vs = ds->opaque;
173
    int i;
174

    
175
    h += y;
176

    
177
    for (; y < h; y++)
178
        for (i = 0; i < w; i += 16)
179
            vnc_set_bit(vs->dirty_row[y], (x + i) / 16);
180
}
181

    
182
static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
183
                                   int32_t encoding)
184
{
185
    vnc_write_u16(vs, x);
186
    vnc_write_u16(vs, y);
187
    vnc_write_u16(vs, w);
188
    vnc_write_u16(vs, h);
189

    
190
    vnc_write_s32(vs, encoding);
191
}
192

    
193
static void vnc_dpy_resize(DisplayState *ds, int w, int h)
194
{
195
    int size_changed;
196
    VncState *vs = ds->opaque;
197

    
198
    ds->data = realloc(ds->data, w * h * vs->depth);
199
    vs->old_data = realloc(vs->old_data, w * h * vs->depth);
200

    
201
    if (ds->data == NULL || vs->old_data == NULL) {
202
        fprintf(stderr, "vnc: memory allocation failed\n");
203
        exit(1);
204
    }
205

    
206
    ds->depth = vs->depth * 8;
207
    size_changed = ds->width != w || ds->height != h;
208
    ds->width = w;
209
    ds->height = h;
210
    ds->linesize = w * vs->depth;
211
    if (vs->csock != -1 && vs->has_resize && size_changed) {
212
        vnc_write_u8(vs, 0);  /* msg id */
213
        vnc_write_u8(vs, 0);
214
        vnc_write_u16(vs, 1); /* number of rects */
215
        vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223);
216
        vnc_flush(vs);
217
        vs->width = ds->width;
218
        vs->height = ds->height;
219
    }
220
}
221

    
222
/* fastest code */
223
static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size)
224
{
225
    vnc_write(vs, pixels, size);
226
}
227

    
228
/* slowest but generic code. */
229
static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
230
{
231
    unsigned int r, g, b;
232

    
233
    r = (v >> vs->red_shift1) & vs->red_max;
234
    g = (v >> vs->green_shift1) & vs->green_max;
235
    b = (v >> vs->blue_shift1) & vs->blue_max;
236
    v = (r << vs->red_shift) | 
237
        (g << vs->green_shift) | 
238
        (b << vs->blue_shift);
239
    switch(vs->pix_bpp) {
240
    case 1:
241
        buf[0] = v;
242
        break;
243
    case 2:
244
        if (vs->pix_big_endian) {
245
            buf[0] = v >> 8;
246
            buf[1] = v;
247
        } else {
248
            buf[1] = v >> 8;
249
            buf[0] = v;
250
        }
251
        break;
252
    default:
253
    case 4:
254
        if (vs->pix_big_endian) {
255
            buf[0] = v >> 24;
256
            buf[1] = v >> 16;
257
            buf[2] = v >> 8;
258
            buf[3] = v;
259
        } else {
260
            buf[3] = v >> 24;
261
            buf[2] = v >> 16;
262
            buf[1] = v >> 8;
263
            buf[0] = v;
264
        }
265
        break;
266
    }
267
}
268

    
269
static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size)
270
{
271
    uint32_t *pixels = pixels1;
272
    uint8_t buf[4];
273
    int n, i;
274

    
275
    n = size >> 2;
276
    for(i = 0; i < n; i++) {
277
        vnc_convert_pixel(vs, buf, pixels[i]);
278
        vnc_write(vs, buf, vs->pix_bpp);
279
    }
280
}
281

    
282
static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h)
283
{
284
    int i;
285
    char *row;
286

    
287
    vnc_framebuffer_update(vs, x, y, w, h, 0);
288

    
289
    row = vs->ds->data + y * vs->ds->linesize + x * vs->depth;
290
    for (i = 0; i < h; i++) {
291
        vs->write_pixels(vs, row, w * vs->depth);
292
        row += vs->ds->linesize;
293
    }
294
}
295

    
296
static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h)
297
{
298
    ptr[0] = ((x & 0x0F) << 4) | (y & 0x0F);
299
    ptr[1] = (((w - 1) & 0x0F) << 4) | ((h - 1) & 0x0F);
300
}
301

    
302
#define BPP 8
303
#include "vnchextile.h"
304
#undef BPP
305

    
306
#define BPP 16
307
#include "vnchextile.h"
308
#undef BPP
309

    
310
#define BPP 32
311
#include "vnchextile.h"
312
#undef BPP
313

    
314
#define GENERIC
315
#define BPP 32
316
#include "vnchextile.h"
317
#undef BPP
318
#undef GENERIC
319

    
320
static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, int h)
321
{
322
    int i, j;
323
    int has_fg, has_bg;
324
    uint32_t last_fg32, last_bg32;
325

    
326
    vnc_framebuffer_update(vs, x, y, w, h, 5);
327

    
328
    has_fg = has_bg = 0;
329
    for (j = y; j < (y + h); j += 16) {
330
        for (i = x; i < (x + w); i += 16) {
331
            vs->send_hextile_tile(vs, i, j, 
332
                                  MIN(16, x + w - i), MIN(16, y + h - j),
333
                                  &last_bg32, &last_fg32, &has_bg, &has_fg);
334
        }
335
    }
336
}
337

    
338
static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
339
{
340
        if (vs->has_hextile)
341
            send_framebuffer_update_hextile(vs, x, y, w, h);
342
        else
343
            send_framebuffer_update_raw(vs, x, y, w, h);
344
}
345

    
346
static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
347
{
348
    int src, dst;
349
    char *src_row;
350
    char *dst_row;
351
    char *old_row;
352
    int y = 0;
353
    int pitch = ds->linesize;
354
    VncState *vs = ds->opaque;
355

    
356
    vnc_update_client(vs);
357

    
358
    if (dst_y > src_y) {
359
        y = h - 1;
360
        pitch = -pitch;
361
    }
362

    
363
    src = (ds->linesize * (src_y + y) + vs->depth * src_x);
364
    dst = (ds->linesize * (dst_y + y) + vs->depth * dst_x);
365

    
366
    src_row = ds->data + src;
367
    dst_row = ds->data + dst;
368
    old_row = vs->old_data + dst;
369

    
370
    for (y = 0; y < h; y++) {
371
        memmove(old_row, src_row, w * vs->depth);
372
        memmove(dst_row, src_row, w * vs->depth);
373
        src_row += pitch;
374
        dst_row += pitch;
375
        old_row += pitch;
376
    }
377

    
378
    vnc_write_u8(vs, 0);  /* msg id */
379
    vnc_write_u8(vs, 0);
380
    vnc_write_u16(vs, 1); /* number of rects */
381
    vnc_framebuffer_update(vs, dst_x, dst_y, w, h, 1);
382
    vnc_write_u16(vs, src_x);
383
    vnc_write_u16(vs, src_y);
384
    vnc_flush(vs);
385
}
386

    
387
static int find_dirty_height(VncState *vs, int y, int last_x, int x)
388
{
389
    int h;
390

    
391
    for (h = 1; h < (vs->height - y); h++) {
392
        int tmp_x;
393
        if (!vnc_get_bit(vs->dirty_row[y + h], last_x))
394
            break;
395
        for (tmp_x = last_x; tmp_x < x; tmp_x++)
396
            vnc_clear_bit(vs->dirty_row[y + h], tmp_x);
397
    }
398

    
399
    return h;
400
}
401

    
402
static void vnc_update_client(void *opaque)
403
{
404
    VncState *vs = opaque;
405

    
406
    if (vs->need_update && vs->csock != -1) {
407
        int y;
408
        char *row;
409
        char *old_row;
410
        uint32_t width_mask[VNC_DIRTY_WORDS];
411
        int n_rectangles;
412
        int saved_offset;
413
        int has_dirty = 0;
414

    
415
        vnc_set_bits(width_mask, (vs->width / 16), VNC_DIRTY_WORDS);
416

    
417
        /* Walk through the dirty map and eliminate tiles that
418
           really aren't dirty */
419
        row = vs->ds->data;
420
        old_row = vs->old_data;
421

    
422
        for (y = 0; y < vs->height; y++) {
423
            if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) {
424
                int x;
425
                char *ptr, *old_ptr;
426

    
427
                ptr = row;
428
                old_ptr = old_row;
429

    
430
                for (x = 0; x < vs->ds->width; x += 16) {
431
                    if (memcmp(old_ptr, ptr, 16 * vs->depth) == 0) {
432
                        vnc_clear_bit(vs->dirty_row[y], (x / 16));
433
                    } else {
434
                        has_dirty = 1;
435
                        memcpy(old_ptr, ptr, 16 * vs->depth);
436
                    }
437

    
438
                    ptr += 16 * vs->depth;
439
                    old_ptr += 16 * vs->depth;
440
                }
441
            }
442

    
443
            row += vs->ds->linesize;
444
            old_row += vs->ds->linesize;
445
        }
446

    
447
        if (!has_dirty) {
448
            qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
449
            return;
450
        }
451

    
452
        /* Count rectangles */
453
        n_rectangles = 0;
454
        vnc_write_u8(vs, 0);  /* msg id */
455
        vnc_write_u8(vs, 0);
456
        saved_offset = vs->output.offset;
457
        vnc_write_u16(vs, 0);
458

    
459
        for (y = 0; y < vs->height; y++) {
460
            int x;
461
            int last_x = -1;
462
            for (x = 0; x < vs->width / 16; x++) {
463
                if (vnc_get_bit(vs->dirty_row[y], x)) {
464
                    if (last_x == -1) {
465
                        last_x = x;
466
                    }
467
                    vnc_clear_bit(vs->dirty_row[y], x);
468
                } else {
469
                    if (last_x != -1) {
470
                        int h = find_dirty_height(vs, y, last_x, x);
471
                        send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
472
                        n_rectangles++;
473
                    }
474
                    last_x = -1;
475
                }
476
            }
477
            if (last_x != -1) {
478
                int h = find_dirty_height(vs, y, last_x, x);
479
                send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
480
                n_rectangles++;
481
            }
482
        }
483
        vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
484
        vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
485
        vnc_flush(vs);
486

    
487
    }
488
    qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
489
}
490

    
491
static void vnc_timer_init(VncState *vs)
492
{
493
    if (vs->timer == NULL) {
494
        vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
495
        qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock));
496
    }
497
}
498

    
499
static void vnc_dpy_refresh(DisplayState *ds)
500
{
501
    VncState *vs = ds->opaque;
502
    vnc_timer_init(vs);
503
    vga_hw_update();
504
}
505

    
506
static int vnc_listen_poll(void *opaque)
507
{
508
    VncState *vs = opaque;
509
    if (vs->csock == -1)
510
        return 1;
511
    return 0;
512
}
513

    
514
static void buffer_reserve(Buffer *buffer, size_t len)
515
{
516
    if ((buffer->capacity - buffer->offset) < len) {
517
        buffer->capacity += (len + 1024);
518
        buffer->buffer = realloc(buffer->buffer, buffer->capacity);
519
        if (buffer->buffer == NULL) {
520
            fprintf(stderr, "vnc: out of memory\n");
521
            exit(1);
522
        }
523
    }
524
}
525

    
526
static int buffer_empty(Buffer *buffer)
527
{
528
    return buffer->offset == 0;
529
}
530

    
531
static char *buffer_end(Buffer *buffer)
532
{
533
    return buffer->buffer + buffer->offset;
534
}
535

    
536
static void buffer_reset(Buffer *buffer)
537
{
538
        buffer->offset = 0;
539
}
540

    
541
static void buffer_append(Buffer *buffer, const void *data, size_t len)
542
{
543
    memcpy(buffer->buffer + buffer->offset, data, len);
544
    buffer->offset += len;
545
}
546

    
547
static int vnc_client_io_error(VncState *vs, int ret, int last_errno)
548
{
549
    if (ret == 0 || ret == -1) {
550
        if (ret == -1 && (last_errno == EINTR || last_errno == EAGAIN))
551
            return 0;
552

    
553
        qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
554
        closesocket(vs->csock);
555
        vs->csock = -1;
556
        buffer_reset(&vs->input);
557
        buffer_reset(&vs->output);
558
        vs->need_update = 0;
559
        return 0;
560
    }
561
    return ret;
562
}
563

    
564
static void vnc_client_error(VncState *vs)
565
{
566
    vnc_client_io_error(vs, -1, EINVAL);
567
}
568

    
569
static void vnc_client_write(void *opaque)
570
{
571
    long ret;
572
    VncState *vs = opaque;
573

    
574
    ret = send(vs->csock, vs->output.buffer, vs->output.offset, 0);
575
    ret = vnc_client_io_error(vs, ret, socket_error());
576
    if (!ret)
577
        return;
578

    
579
    memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));
580
    vs->output.offset -= ret;
581

    
582
    if (vs->output.offset == 0) {
583
        qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
584
    }
585
}
586

    
587
static void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
588
{
589
    vs->read_handler = func;
590
    vs->read_handler_expect = expecting;
591
}
592

    
593
static void vnc_client_read(void *opaque)
594
{
595
    VncState *vs = opaque;
596
    long ret;
597

    
598
    buffer_reserve(&vs->input, 4096);
599

    
600
    ret = recv(vs->csock, buffer_end(&vs->input), 4096, 0);
601
    ret = vnc_client_io_error(vs, ret, socket_error());
602
    if (!ret)
603
        return;
604

    
605
    vs->input.offset += ret;
606

    
607
    while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
608
        size_t len = vs->read_handler_expect;
609
        int ret;
610

    
611
        ret = vs->read_handler(vs, vs->input.buffer, len);
612
        if (vs->csock == -1)
613
            return;
614

    
615
        if (!ret) {
616
            memmove(vs->input.buffer, vs->input.buffer + len, (vs->input.offset - len));
617
            vs->input.offset -= len;
618
        } else {
619
            vs->read_handler_expect = ret;
620
        }
621
    }
622
}
623

    
624
static void vnc_write(VncState *vs, const void *data, size_t len)
625
{
626
    buffer_reserve(&vs->output, len);
627

    
628
    if (buffer_empty(&vs->output)) {
629
        qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
630
    }
631

    
632
    buffer_append(&vs->output, data, len);
633
}
634

    
635
static void vnc_write_s32(VncState *vs, int32_t value)
636
{
637
    vnc_write_u32(vs, *(uint32_t *)&value);
638
}
639

    
640
static void vnc_write_u32(VncState *vs, uint32_t value)
641
{
642
    uint8_t buf[4];
643

    
644
    buf[0] = (value >> 24) & 0xFF;
645
    buf[1] = (value >> 16) & 0xFF;
646
    buf[2] = (value >>  8) & 0xFF;
647
    buf[3] = value & 0xFF;
648

    
649
    vnc_write(vs, buf, 4);
650
}
651

    
652
static void vnc_write_u16(VncState *vs, uint16_t value)
653
{
654
    uint8_t buf[2];
655

    
656
    buf[0] = (value >> 8) & 0xFF;
657
    buf[1] = value & 0xFF;
658

    
659
    vnc_write(vs, buf, 2);
660
}
661

    
662
static void vnc_write_u8(VncState *vs, uint8_t value)
663
{
664
    vnc_write(vs, (char *)&value, 1);
665
}
666

    
667
static void vnc_flush(VncState *vs)
668
{
669
    if (vs->output.offset)
670
        vnc_client_write(vs);
671
}
672

    
673
static uint8_t read_u8(uint8_t *data, size_t offset)
674
{
675
    return data[offset];
676
}
677

    
678
static uint16_t read_u16(uint8_t *data, size_t offset)
679
{
680
    return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
681
}
682

    
683
static int32_t read_s32(uint8_t *data, size_t offset)
684
{
685
    return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
686
                     (data[offset + 2] << 8) | data[offset + 3]);
687
}
688

    
689
static uint32_t read_u32(uint8_t *data, size_t offset)
690
{
691
    return ((data[offset] << 24) | (data[offset + 1] << 16) |
692
            (data[offset + 2] << 8) | data[offset + 3]);
693
}
694

    
695
static void client_cut_text(VncState *vs, size_t len, char *text)
696
{
697
}
698

    
699
static void check_pointer_type_change(VncState *vs, int absolute)
700
{
701
    if (vs->has_pointer_type_change && vs->absolute != absolute) {
702
        vnc_write_u8(vs, 0);
703
        vnc_write_u8(vs, 0);
704
        vnc_write_u16(vs, 1);
705
        vnc_framebuffer_update(vs, absolute, 0,
706
                               vs->ds->width, vs->ds->height, -257);
707
        vnc_flush(vs);
708
    }
709
    vs->absolute = absolute;
710
}
711

    
712
static void pointer_event(VncState *vs, int button_mask, int x, int y)
713
{
714
    int buttons = 0;
715
    int dz = 0;
716

    
717
    if (button_mask & 0x01)
718
        buttons |= MOUSE_EVENT_LBUTTON;
719
    if (button_mask & 0x02)
720
        buttons |= MOUSE_EVENT_MBUTTON;
721
    if (button_mask & 0x04)
722
        buttons |= MOUSE_EVENT_RBUTTON;
723
    if (button_mask & 0x08)
724
        dz = -1;
725
    if (button_mask & 0x10)
726
        dz = 1;
727

    
728
    if (vs->absolute) {
729
        kbd_mouse_event(x * 0x7FFF / vs->ds->width,
730
                        y * 0x7FFF / vs->ds->height,
731
                        dz, buttons);
732
    } else if (vs->has_pointer_type_change) {
733
        x -= 0x7FFF;
734
        y -= 0x7FFF;
735

    
736
        kbd_mouse_event(x, y, dz, buttons);
737
    } else {
738
        if (vs->last_x != -1)
739
            kbd_mouse_event(x - vs->last_x,
740
                            y - vs->last_y,
741
                            dz, buttons);
742
        vs->last_x = x;
743
        vs->last_y = y;
744
    }
745

    
746
    check_pointer_type_change(vs, kbd_mouse_is_absolute());
747
}
748

    
749
static void reset_keys(VncState *vs)
750
{
751
    int i;
752
    for(i = 0; i < 256; i++) {
753
        if (vs->modifiers_state[i]) {
754
            if (i & 0x80)
755
                kbd_put_keycode(0xe0);
756
            kbd_put_keycode(i | 0x80);
757
            vs->modifiers_state[i] = 0;
758
        }
759
    }
760
}
761

    
762
static void do_key_event(VncState *vs, int down, uint32_t sym)
763
{
764
    int keycode;
765

    
766
    keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
767
    
768
    /* QEMU console switch */
769
    switch(keycode) {
770
    case 0x2a:                          /* Left Shift */
771
    case 0x36:                          /* Right Shift */
772
    case 0x1d:                          /* Left CTRL */
773
    case 0x9d:                          /* Right CTRL */
774
    case 0x38:                          /* Left ALT */
775
    case 0xb8:                          /* Right ALT */
776
        if (down)
777
            vs->modifiers_state[keycode] = 1;
778
        else
779
            vs->modifiers_state[keycode] = 0;
780
        break;
781
    case 0x02 ... 0x0a: /* '1' to '9' keys */ 
782
        if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
783
            /* Reset the modifiers sent to the current console */
784
            reset_keys(vs);
785
            console_select(keycode - 0x02);
786
            return;
787
        }
788
        break;
789
    }
790

    
791
    if (is_graphic_console()) {
792
        if (keycode & 0x80)
793
            kbd_put_keycode(0xe0);
794
        if (down)
795
            kbd_put_keycode(keycode & 0x7f);
796
        else
797
            kbd_put_keycode(keycode | 0x80);
798
    } else {
799
        /* QEMU console emulation */
800
        if (down) {
801
            switch (keycode) {
802
            case 0x2a:                          /* Left Shift */
803
            case 0x36:                          /* Right Shift */
804
            case 0x1d:                          /* Left CTRL */
805
            case 0x9d:                          /* Right CTRL */
806
            case 0x38:                          /* Left ALT */
807
            case 0xb8:                          /* Right ALT */
808
                break;
809
            case 0xc8:
810
                kbd_put_keysym(QEMU_KEY_UP);
811
                break;
812
            case 0xd0:
813
                kbd_put_keysym(QEMU_KEY_DOWN);
814
                break;
815
            case 0xcb:
816
                kbd_put_keysym(QEMU_KEY_LEFT);
817
                break;
818
            case 0xcd:
819
                kbd_put_keysym(QEMU_KEY_RIGHT);
820
                break;
821
            case 0xd3:
822
                kbd_put_keysym(QEMU_KEY_DELETE);
823
                break;
824
            case 0xc7:
825
                kbd_put_keysym(QEMU_KEY_HOME);
826
                break;
827
            case 0xcf:
828
                kbd_put_keysym(QEMU_KEY_END);
829
                break;
830
            case 0xc9:
831
                kbd_put_keysym(QEMU_KEY_PAGEUP);
832
                break;
833
            case 0xd1:
834
                kbd_put_keysym(QEMU_KEY_PAGEDOWN);
835
                break;
836
            default:
837
                kbd_put_keysym(sym);
838
                break;
839
            }
840
        }
841
    }
842
}
843

    
844
static void key_event(VncState *vs, int down, uint32_t sym)
845
{
846
    if (sym >= 'A' && sym <= 'Z')
847
        sym = sym - 'A' + 'a';
848
    do_key_event(vs, down, sym);
849
}
850

    
851
static void framebuffer_update_request(VncState *vs, int incremental,
852
                                       int x_position, int y_position,
853
                                       int w, int h)
854
{
855
    int i;
856
    vs->need_update = 1;
857
    if (!incremental) {
858
        char *old_row = vs->old_data + y_position * vs->ds->linesize;
859

    
860
        for (i = 0; i < h; i++) {
861
            vnc_set_bits(vs->dirty_row[y_position + i], 
862
                         (vs->ds->width / 16), VNC_DIRTY_WORDS);
863
            memset(old_row, 42, vs->ds->width * vs->depth);
864
            old_row += vs->ds->linesize;
865
        }
866
    }
867
}
868

    
869
static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
870
{
871
    int i;
872

    
873
    vs->has_hextile = 0;
874
    vs->has_resize = 0;
875
    vs->has_pointer_type_change = 0;
876
    vs->absolute = -1;
877
    vs->ds->dpy_copy = NULL;
878

    
879
    for (i = n_encodings - 1; i >= 0; i--) {
880
        switch (encodings[i]) {
881
        case 0: /* Raw */
882
            vs->has_hextile = 0;
883
            break;
884
        case 1: /* CopyRect */
885
            vs->ds->dpy_copy = vnc_copy;
886
            break;
887
        case 5: /* Hextile */
888
            vs->has_hextile = 1;
889
            break;
890
        case -223: /* DesktopResize */
891
            vs->has_resize = 1;
892
            break;
893
        case -257:
894
            vs->has_pointer_type_change = 1;
895
            break;
896
        default:
897
            break;
898
        }
899
    }
900

    
901
    check_pointer_type_change(vs, kbd_mouse_is_absolute());
902
}
903

    
904
static int compute_nbits(unsigned int val)
905
{
906
    int n;
907
    n = 0;
908
    while (val != 0) {
909
        n++;
910
        val >>= 1;
911
    }
912
    return n;
913
}
914

    
915
static void set_pixel_format(VncState *vs,
916
                             int bits_per_pixel, int depth,
917
                             int big_endian_flag, int true_color_flag,
918
                             int red_max, int green_max, int blue_max,
919
                             int red_shift, int green_shift, int blue_shift)
920
{
921
    int host_big_endian_flag;
922

    
923
#ifdef WORDS_BIGENDIAN
924
    host_big_endian_flag = 1;
925
#else
926
    host_big_endian_flag = 0;
927
#endif
928
    if (!true_color_flag) {
929
    fail:
930
        vnc_client_error(vs);
931
        return;
932
    }
933
    if (bits_per_pixel == 32 && 
934
        host_big_endian_flag == big_endian_flag &&
935
        red_max == 0xff && green_max == 0xff && blue_max == 0xff &&
936
        red_shift == 16 && green_shift == 8 && blue_shift == 0) {
937
        vs->depth = 4;
938
        vs->write_pixels = vnc_write_pixels_copy;
939
        vs->send_hextile_tile = send_hextile_tile_32;
940
    } else 
941
    if (bits_per_pixel == 16 && 
942
        host_big_endian_flag == big_endian_flag &&
943
        red_max == 31 && green_max == 63 && blue_max == 31 &&
944
        red_shift == 11 && green_shift == 5 && blue_shift == 0) {
945
        vs->depth = 2;
946
        vs->write_pixels = vnc_write_pixels_copy;
947
        vs->send_hextile_tile = send_hextile_tile_16;
948
    } else 
949
    if (bits_per_pixel == 8 && 
950
        red_max == 7 && green_max == 7 && blue_max == 3 &&
951
        red_shift == 5 && green_shift == 2 && blue_shift == 0) {
952
        vs->depth = 1;
953
        vs->write_pixels = vnc_write_pixels_copy;
954
        vs->send_hextile_tile = send_hextile_tile_8;
955
    } else 
956
    {
957
        /* generic and slower case */
958
        if (bits_per_pixel != 8 &&
959
            bits_per_pixel != 16 &&
960
            bits_per_pixel != 32)
961
            goto fail;
962
        vs->depth = 4;
963
        vs->red_shift = red_shift;
964
        vs->red_max = red_max;
965
        vs->red_shift1 = 24 - compute_nbits(red_max);
966
        vs->green_shift = green_shift;
967
        vs->green_max = green_max;
968
        vs->green_shift1 = 16 - compute_nbits(green_max);
969
        vs->blue_shift = blue_shift;
970
        vs->blue_max = blue_max;
971
        vs->blue_shift1 = 8 - compute_nbits(blue_max);
972
        vs->pix_bpp = bits_per_pixel / 8;
973
        vs->pix_big_endian = big_endian_flag;
974
        vs->write_pixels = vnc_write_pixels_generic;
975
        vs->send_hextile_tile = send_hextile_tile_generic;
976
    }
977

    
978
    vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height);
979
    memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
980
    memset(vs->old_data, 42, vs->ds->linesize * vs->ds->height);
981

    
982
    vga_hw_invalidate();
983
    vga_hw_update();
984
}
985

    
986
static int protocol_client_msg(VncState *vs, char *data, size_t len)
987
{
988
    int i;
989
    uint16_t limit;
990

    
991
    switch (data[0]) {
992
    case 0:
993
        if (len == 1)
994
            return 20;
995

    
996
        set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
997
                         read_u8(data, 6), read_u8(data, 7),
998
                         read_u16(data, 8), read_u16(data, 10),
999
                         read_u16(data, 12), read_u8(data, 14),
1000
                         read_u8(data, 15), read_u8(data, 16));
1001
        break;
1002
    case 2:
1003
        if (len == 1)
1004
            return 4;
1005

    
1006
        if (len == 4)
1007
            return 4 + (read_u16(data, 2) * 4);
1008

    
1009
        limit = read_u16(data, 2);
1010
        for (i = 0; i < limit; i++) {
1011
            int32_t val = read_s32(data, 4 + (i * 4));
1012
            memcpy(data + 4 + (i * 4), &val, sizeof(val));
1013
        }
1014

    
1015
        set_encodings(vs, (int32_t *)(data + 4), limit);
1016
        break;
1017
    case 3:
1018
        if (len == 1)
1019
            return 10;
1020

    
1021
        framebuffer_update_request(vs,
1022
                                   read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
1023
                                   read_u16(data, 6), read_u16(data, 8));
1024
        break;
1025
    case 4:
1026
        if (len == 1)
1027
            return 8;
1028

    
1029
        key_event(vs, read_u8(data, 1), read_u32(data, 4));
1030
        break;
1031
    case 5:
1032
        if (len == 1)
1033
            return 6;
1034

    
1035
        pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
1036
        break;
1037
    case 6:
1038
        if (len == 1)
1039
            return 8;
1040

    
1041
        if (len == 8)
1042
            return 8 + read_u32(data, 4);
1043

    
1044
        client_cut_text(vs, read_u32(data, 4), data + 8);
1045
        break;
1046
    default:
1047
        printf("Msg: %d\n", data[0]);
1048
        vnc_client_error(vs);
1049
        break;
1050
    }
1051
        
1052
    vnc_read_when(vs, protocol_client_msg, 1);
1053
    return 0;
1054
}
1055

    
1056
static int protocol_client_init(VncState *vs, char *data, size_t len)
1057
{
1058
    char pad[3] = { 0, 0, 0 };
1059

    
1060
    vs->width = vs->ds->width;
1061
    vs->height = vs->ds->height;
1062
    vnc_write_u16(vs, vs->ds->width);
1063
    vnc_write_u16(vs, vs->ds->height);
1064

    
1065
    vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */
1066
    vnc_write_u8(vs, vs->depth * 8); /* depth */
1067
#ifdef WORDS_BIGENDIAN
1068
    vnc_write_u8(vs, 1);             /* big-endian-flag */
1069
#else
1070
    vnc_write_u8(vs, 0);             /* big-endian-flag */
1071
#endif
1072
    vnc_write_u8(vs, 1);             /* true-color-flag */
1073
    if (vs->depth == 4) {
1074
        vnc_write_u16(vs, 0xFF);     /* red-max */
1075
        vnc_write_u16(vs, 0xFF);     /* green-max */
1076
        vnc_write_u16(vs, 0xFF);     /* blue-max */
1077
        vnc_write_u8(vs, 16);        /* red-shift */
1078
        vnc_write_u8(vs, 8);         /* green-shift */
1079
        vnc_write_u8(vs, 0);         /* blue-shift */
1080
        vs->send_hextile_tile = send_hextile_tile_32;
1081
    } else if (vs->depth == 2) {
1082
        vnc_write_u16(vs, 31);       /* red-max */
1083
        vnc_write_u16(vs, 63);       /* green-max */
1084
        vnc_write_u16(vs, 31);       /* blue-max */
1085
        vnc_write_u8(vs, 11);        /* red-shift */
1086
        vnc_write_u8(vs, 5);         /* green-shift */
1087
        vnc_write_u8(vs, 0);         /* blue-shift */
1088
        vs->send_hextile_tile = send_hextile_tile_16;
1089
    } else if (vs->depth == 1) {
1090
        /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */
1091
        vnc_write_u16(vs, 7);        /* red-max */
1092
        vnc_write_u16(vs, 7);        /* green-max */
1093
        vnc_write_u16(vs, 3);        /* blue-max */
1094
        vnc_write_u8(vs, 5);         /* red-shift */
1095
        vnc_write_u8(vs, 2);         /* green-shift */
1096
        vnc_write_u8(vs, 0);         /* blue-shift */
1097
        vs->send_hextile_tile = send_hextile_tile_8;
1098
    }
1099
    vs->write_pixels = vnc_write_pixels_copy;
1100
        
1101
    vnc_write(vs, pad, 3);           /* padding */
1102

    
1103
    vnc_write_u32(vs, 4);        
1104
    vnc_write(vs, "QEMU", 4);
1105
    vnc_flush(vs);
1106

    
1107
    vnc_read_when(vs, protocol_client_msg, 1);
1108

    
1109
    return 0;
1110
}
1111

    
1112
static int protocol_version(VncState *vs, char *version, size_t len)
1113
{
1114
    char local[13];
1115
    int maj, min;
1116

    
1117
    memcpy(local, version, 12);
1118
    local[12] = 0;
1119

    
1120
    if (sscanf(local, "RFB %03d.%03d\n", &maj, &min) != 2) {
1121
        vnc_client_error(vs);
1122
        return 0;
1123
    }
1124

    
1125
    vnc_write_u32(vs, 1); /* None */
1126
    vnc_flush(vs);
1127

    
1128
    vnc_read_when(vs, protocol_client_init, 1);
1129

    
1130
    return 0;
1131
}
1132

    
1133
static void vnc_listen_read(void *opaque)
1134
{
1135
    VncState *vs = opaque;
1136
    struct sockaddr_in addr;
1137
    socklen_t addrlen = sizeof(addr);
1138

    
1139
    vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
1140
    if (vs->csock != -1) {
1141
        socket_set_nonblock(vs->csock);
1142
        qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, opaque);
1143
        vnc_write(vs, "RFB 003.003\n", 12);
1144
        vnc_flush(vs);
1145
        vnc_read_when(vs, protocol_version, 12);
1146
        memset(vs->old_data, 0, vs->ds->linesize * vs->ds->height);
1147
        memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1148
        vs->has_resize = 0;
1149
        vs->has_hextile = 0;
1150
        vs->ds->dpy_copy = NULL;
1151
    }
1152
}
1153

    
1154
extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
1155

    
1156
void vnc_display_init(DisplayState *ds, const char *arg)
1157
{
1158
    struct sockaddr *addr;
1159
    struct sockaddr_in iaddr;
1160
#ifndef _WIN32
1161
    struct sockaddr_un uaddr;
1162
#endif
1163
    int reuse_addr, ret;
1164
    socklen_t addrlen;
1165
    const char *p;
1166
    VncState *vs;
1167

    
1168
    vs = qemu_mallocz(sizeof(VncState));
1169
    if (!vs)
1170
        exit(1);
1171

    
1172
    ds->opaque = vs;
1173
    vnc_state = vs;
1174
    vs->display = arg;
1175

    
1176
    vs->lsock = -1;
1177
    vs->csock = -1;
1178
    vs->depth = 4;
1179
    vs->last_x = -1;
1180
    vs->last_y = -1;
1181

    
1182
    vs->ds = ds;
1183

    
1184
    if (!keyboard_layout)
1185
        keyboard_layout = "en-us";
1186

    
1187
    vs->kbd_layout = init_keyboard_layout(keyboard_layout);
1188
    if (!vs->kbd_layout)
1189
        exit(1);
1190

    
1191
    vs->ds->data = NULL;
1192
    vs->ds->dpy_update = vnc_dpy_update;
1193
    vs->ds->dpy_resize = vnc_dpy_resize;
1194
    vs->ds->dpy_refresh = vnc_dpy_refresh;
1195

    
1196
    memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1197

    
1198
    vnc_dpy_resize(vs->ds, 640, 400);
1199

    
1200
#ifndef _WIN32
1201
    if (strstart(arg, "unix:", &p)) {
1202
        addr = (struct sockaddr *)&uaddr;
1203
        addrlen = sizeof(uaddr);
1204

    
1205
        vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);
1206
        if (vs->lsock == -1) {
1207
            fprintf(stderr, "Could not create socket\n");
1208
            exit(1);
1209
        }
1210

    
1211
        uaddr.sun_family = AF_UNIX;
1212
        memset(uaddr.sun_path, 0, 108);
1213
        snprintf(uaddr.sun_path, 108, "%s", p);
1214

    
1215
        unlink(uaddr.sun_path);
1216
    } else
1217
#endif
1218
    {
1219
        addr = (struct sockaddr *)&iaddr;
1220
        addrlen = sizeof(iaddr);
1221

    
1222
        vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
1223
        if (vs->lsock == -1) {
1224
            fprintf(stderr, "Could not create socket\n");
1225
            exit(1);
1226
        }
1227

    
1228
        if (parse_host_port(&iaddr, arg) < 0) {
1229
            fprintf(stderr, "Could not parse VNC address\n");
1230
            exit(1);
1231
        }
1232
            
1233
        iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900);
1234

    
1235
        reuse_addr = 1;
1236
        ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
1237
                         (const char *)&reuse_addr, sizeof(reuse_addr));
1238
        if (ret == -1) {
1239
            fprintf(stderr, "setsockopt() failed\n");
1240
            exit(1);
1241
        }
1242
    }
1243

    
1244
    if (bind(vs->lsock, addr, addrlen) == -1) {
1245
        fprintf(stderr, "bind() failed\n");
1246
        exit(1);
1247
    }
1248

    
1249
    if (listen(vs->lsock, 1) == -1) {
1250
        fprintf(stderr, "listen() failed\n");
1251
        exit(1);
1252
    }
1253

    
1254
    ret = qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);
1255
    if (ret == -1) {
1256
        exit(1);
1257
    }
1258
}