Statistics
| Branch: | Revision:

root / vnc.c @ 7e1543c2

History | View | Annotate | Download (31.4 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
    if (x_position > vs->ds->width)
856
        x_position = vs->ds->width;
857
    if (y_position > vs->ds->height)
858
        y_position = vs->ds->height;
859
    if (x_position + w >= vs->ds->width)
860
        w = vs->ds->width  - x_position;
861
    if (y_position + h >= vs->ds->height)
862
        h = vs->ds->height - y_position;
863

    
864
    int i;
865
    vs->need_update = 1;
866
    if (!incremental) {
867
        char *old_row = vs->old_data + y_position * vs->ds->linesize;
868

    
869
        for (i = 0; i < h; i++) {
870
            vnc_set_bits(vs->dirty_row[y_position + i], 
871
                         (vs->ds->width / 16), VNC_DIRTY_WORDS);
872
            memset(old_row, 42, vs->ds->width * vs->depth);
873
            old_row += vs->ds->linesize;
874
        }
875
    }
876
}
877

    
878
static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
879
{
880
    int i;
881

    
882
    vs->has_hextile = 0;
883
    vs->has_resize = 0;
884
    vs->has_pointer_type_change = 0;
885
    vs->absolute = -1;
886
    vs->ds->dpy_copy = NULL;
887

    
888
    for (i = n_encodings - 1; i >= 0; i--) {
889
        switch (encodings[i]) {
890
        case 0: /* Raw */
891
            vs->has_hextile = 0;
892
            break;
893
        case 1: /* CopyRect */
894
            vs->ds->dpy_copy = vnc_copy;
895
            break;
896
        case 5: /* Hextile */
897
            vs->has_hextile = 1;
898
            break;
899
        case -223: /* DesktopResize */
900
            vs->has_resize = 1;
901
            break;
902
        case -257:
903
            vs->has_pointer_type_change = 1;
904
            break;
905
        default:
906
            break;
907
        }
908
    }
909

    
910
    check_pointer_type_change(vs, kbd_mouse_is_absolute());
911
}
912

    
913
static int compute_nbits(unsigned int val)
914
{
915
    int n;
916
    n = 0;
917
    while (val != 0) {
918
        n++;
919
        val >>= 1;
920
    }
921
    return n;
922
}
923

    
924
static void set_pixel_format(VncState *vs,
925
                             int bits_per_pixel, int depth,
926
                             int big_endian_flag, int true_color_flag,
927
                             int red_max, int green_max, int blue_max,
928
                             int red_shift, int green_shift, int blue_shift)
929
{
930
    int host_big_endian_flag;
931

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

    
987
    vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height);
988
    memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
989
    memset(vs->old_data, 42, vs->ds->linesize * vs->ds->height);
990

    
991
    vga_hw_invalidate();
992
    vga_hw_update();
993
}
994

    
995
static int protocol_client_msg(VncState *vs, char *data, size_t len)
996
{
997
    int i;
998
    uint16_t limit;
999

    
1000
    switch (data[0]) {
1001
    case 0:
1002
        if (len == 1)
1003
            return 20;
1004

    
1005
        set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
1006
                         read_u8(data, 6), read_u8(data, 7),
1007
                         read_u16(data, 8), read_u16(data, 10),
1008
                         read_u16(data, 12), read_u8(data, 14),
1009
                         read_u8(data, 15), read_u8(data, 16));
1010
        break;
1011
    case 2:
1012
        if (len == 1)
1013
            return 4;
1014

    
1015
        if (len == 4)
1016
            return 4 + (read_u16(data, 2) * 4);
1017

    
1018
        limit = read_u16(data, 2);
1019
        for (i = 0; i < limit; i++) {
1020
            int32_t val = read_s32(data, 4 + (i * 4));
1021
            memcpy(data + 4 + (i * 4), &val, sizeof(val));
1022
        }
1023

    
1024
        set_encodings(vs, (int32_t *)(data + 4), limit);
1025
        break;
1026
    case 3:
1027
        if (len == 1)
1028
            return 10;
1029

    
1030
        framebuffer_update_request(vs,
1031
                                   read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
1032
                                   read_u16(data, 6), read_u16(data, 8));
1033
        break;
1034
    case 4:
1035
        if (len == 1)
1036
            return 8;
1037

    
1038
        key_event(vs, read_u8(data, 1), read_u32(data, 4));
1039
        break;
1040
    case 5:
1041
        if (len == 1)
1042
            return 6;
1043

    
1044
        pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
1045
        break;
1046
    case 6:
1047
        if (len == 1)
1048
            return 8;
1049

    
1050
        if (len == 8)
1051
            return 8 + read_u32(data, 4);
1052

    
1053
        client_cut_text(vs, read_u32(data, 4), data + 8);
1054
        break;
1055
    default:
1056
        printf("Msg: %d\n", data[0]);
1057
        vnc_client_error(vs);
1058
        break;
1059
    }
1060
        
1061
    vnc_read_when(vs, protocol_client_msg, 1);
1062
    return 0;
1063
}
1064

    
1065
static int protocol_client_init(VncState *vs, char *data, size_t len)
1066
{
1067
    char pad[3] = { 0, 0, 0 };
1068
    char buf[1024];
1069
    int size;
1070

    
1071
    vs->width = vs->ds->width;
1072
    vs->height = vs->ds->height;
1073
    vnc_write_u16(vs, vs->ds->width);
1074
    vnc_write_u16(vs, vs->ds->height);
1075

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

    
1114
    if (qemu_name)
1115
        size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
1116
    else
1117
        size = snprintf(buf, sizeof(buf), "QEMU");
1118

    
1119
    vnc_write_u32(vs, size);
1120
    vnc_write(vs, buf, size);
1121
    vnc_flush(vs);
1122

    
1123
    vnc_read_when(vs, protocol_client_msg, 1);
1124

    
1125
    return 0;
1126
}
1127

    
1128
static int protocol_version(VncState *vs, char *version, size_t len)
1129
{
1130
    char local[13];
1131
    int maj, min;
1132

    
1133
    memcpy(local, version, 12);
1134
    local[12] = 0;
1135

    
1136
    if (sscanf(local, "RFB %03d.%03d\n", &maj, &min) != 2) {
1137
        vnc_client_error(vs);
1138
        return 0;
1139
    }
1140

    
1141
    vnc_write_u32(vs, 1); /* None */
1142
    vnc_flush(vs);
1143

    
1144
    vnc_read_when(vs, protocol_client_init, 1);
1145

    
1146
    return 0;
1147
}
1148

    
1149
static void vnc_listen_read(void *opaque)
1150
{
1151
    VncState *vs = opaque;
1152
    struct sockaddr_in addr;
1153
    socklen_t addrlen = sizeof(addr);
1154

    
1155
    vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
1156
    if (vs->csock != -1) {
1157
        socket_set_nonblock(vs->csock);
1158
        qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, opaque);
1159
        vnc_write(vs, "RFB 003.003\n", 12);
1160
        vnc_flush(vs);
1161
        vnc_read_when(vs, protocol_version, 12);
1162
        memset(vs->old_data, 0, vs->ds->linesize * vs->ds->height);
1163
        memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1164
        vs->has_resize = 0;
1165
        vs->has_hextile = 0;
1166
        vs->ds->dpy_copy = NULL;
1167
    }
1168
}
1169

    
1170
extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
1171

    
1172
void vnc_display_init(DisplayState *ds, const char *arg)
1173
{
1174
    struct sockaddr *addr;
1175
    struct sockaddr_in iaddr;
1176
#ifndef _WIN32
1177
    struct sockaddr_un uaddr;
1178
#endif
1179
    int reuse_addr, ret;
1180
    socklen_t addrlen;
1181
    const char *p;
1182
    VncState *vs;
1183

    
1184
    vs = qemu_mallocz(sizeof(VncState));
1185
    if (!vs)
1186
        exit(1);
1187

    
1188
    ds->opaque = vs;
1189
    vnc_state = vs;
1190
    vs->display = arg;
1191

    
1192
    vs->lsock = -1;
1193
    vs->csock = -1;
1194
    vs->depth = 4;
1195
    vs->last_x = -1;
1196
    vs->last_y = -1;
1197

    
1198
    vs->ds = ds;
1199

    
1200
    if (!keyboard_layout)
1201
        keyboard_layout = "en-us";
1202

    
1203
    vs->kbd_layout = init_keyboard_layout(keyboard_layout);
1204
    if (!vs->kbd_layout)
1205
        exit(1);
1206

    
1207
    vs->ds->data = NULL;
1208
    vs->ds->dpy_update = vnc_dpy_update;
1209
    vs->ds->dpy_resize = vnc_dpy_resize;
1210
    vs->ds->dpy_refresh = vnc_dpy_refresh;
1211

    
1212
    memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1213

    
1214
    vnc_dpy_resize(vs->ds, 640, 400);
1215

    
1216
#ifndef _WIN32
1217
    if (strstart(arg, "unix:", &p)) {
1218
        addr = (struct sockaddr *)&uaddr;
1219
        addrlen = sizeof(uaddr);
1220

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

    
1227
        uaddr.sun_family = AF_UNIX;
1228
        memset(uaddr.sun_path, 0, 108);
1229
        snprintf(uaddr.sun_path, 108, "%s", p);
1230

    
1231
        unlink(uaddr.sun_path);
1232
    } else
1233
#endif
1234
    {
1235
        addr = (struct sockaddr *)&iaddr;
1236
        addrlen = sizeof(iaddr);
1237

    
1238
        vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
1239
        if (vs->lsock == -1) {
1240
            fprintf(stderr, "Could not create socket\n");
1241
            exit(1);
1242
        }
1243

    
1244
        if (parse_host_port(&iaddr, arg) < 0) {
1245
            fprintf(stderr, "Could not parse VNC address\n");
1246
            exit(1);
1247
        }
1248
            
1249
        iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900);
1250

    
1251
        reuse_addr = 1;
1252
        ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
1253
                         (const char *)&reuse_addr, sizeof(reuse_addr));
1254
        if (ret == -1) {
1255
            fprintf(stderr, "setsockopt() failed\n");
1256
            exit(1);
1257
        }
1258
    }
1259

    
1260
    if (bind(vs->lsock, addr, addrlen) == -1) {
1261
        fprintf(stderr, "bind() failed\n");
1262
        exit(1);
1263
    }
1264

    
1265
    if (listen(vs->lsock, 1) == -1) {
1266
        fprintf(stderr, "listen() failed\n");
1267
        exit(1);
1268
    }
1269

    
1270
    ret = qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);
1271
    if (ret == -1) {
1272
        exit(1);
1273
    }
1274
}