|
|
1.1 root 1: /*
2: * QEMU VNC display driver
3: *
4: * Copyright (C) 2006 Anthony Liguori <[email protected]>
5: * Copyright (C) 2006 Fabrice Bellard
6: * Copyright (C) 2009 Red Hat, Inc
7: *
8: * Permission is hereby granted, free of charge, to any person obtaining a copy
9: * of this software and associated documentation files (the "Software"), to deal
10: * in the Software without restriction, including without limitation the rights
11: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12: * copies of the Software, and to permit persons to whom the Software is
13: * furnished to do so, subject to the following conditions:
14: *
15: * The above copyright notice and this permission notice shall be included in
16: * all copies or substantial portions of the Software.
17: *
18: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24: * THE SOFTWARE.
25: */
26:
27: #ifndef __QEMU_VNC_H
28: #define __QEMU_VNC_H
29:
30: #include "qemu-common.h"
31: #include "qemu-queue.h"
32: #ifdef CONFIG_VNC_THREAD
33: #include "qemu-thread.h"
34: #endif
35: #include "console.h"
36: #include "monitor.h"
37: #include "audio/audio.h"
1.1.1.3 root 38: #include "bitmap.h"
1.1 root 39: #include <zlib.h>
40: #include <stdbool.h>
41:
42: #include "keymaps.h"
1.1.1.3 root 43: #include "vnc-palette.h"
44: #include "vnc-enc-zrle.h"
1.1 root 45:
46: // #define _VNC_DEBUG 1
47:
48: #ifdef _VNC_DEBUG
49: #define VNC_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
50: #else
51: #define VNC_DEBUG(fmt, ...) do { } while (0)
52: #endif
53:
54: /*****************************************************************************
55: *
56: * Core data structures
57: *
58: *****************************************************************************/
59:
60: typedef struct Buffer
61: {
62: size_t capacity;
63: size_t offset;
64: uint8_t *buffer;
65: } Buffer;
66:
67: typedef struct VncState VncState;
68: typedef struct VncJob VncJob;
69: typedef struct VncRect VncRect;
70: typedef struct VncRectEntry VncRectEntry;
71:
72: typedef int VncReadEvent(VncState *vs, uint8_t *data, size_t len);
73:
74: typedef void VncWritePixels(VncState *vs, struct PixelFormat *pf, void *data, int size);
75:
76: typedef void VncSendHextileTile(VncState *vs,
77: int x, int y, int w, int h,
78: void *last_bg,
79: void *last_fg,
80: int *has_bg, int *has_fg);
81:
1.1.1.3 root 82: /* VNC_MAX_WIDTH must be a multiple of 16. */
1.1 root 83: #define VNC_MAX_WIDTH 2560
84: #define VNC_MAX_HEIGHT 2048
1.1.1.3 root 85:
86: /* VNC_DIRTY_BITS is the number of bits in the dirty bitmap. */
87: #define VNC_DIRTY_BITS (VNC_MAX_WIDTH / 16)
88:
89: #define VNC_STAT_RECT 64
90: #define VNC_STAT_COLS (VNC_MAX_WIDTH / VNC_STAT_RECT)
91: #define VNC_STAT_ROWS (VNC_MAX_HEIGHT / VNC_STAT_RECT)
1.1 root 92:
93: #define VNC_AUTH_CHALLENGE_SIZE 16
94:
95: typedef struct VncDisplay VncDisplay;
96:
97: #ifdef CONFIG_VNC_TLS
98: #include "vnc-tls.h"
99: #include "vnc-auth-vencrypt.h"
100: #endif
101: #ifdef CONFIG_VNC_SASL
102: #include "vnc-auth-sasl.h"
103: #endif
104:
1.1.1.3 root 105: struct VncRectStat
106: {
107: /* time of last 10 updates, to find update frequency */
108: struct timeval times[10];
109: int idx;
110:
111: double freq; /* Update frequency (in Hz) */
112: bool updated; /* Already updated during this refresh */
113: };
114:
115: typedef struct VncRectStat VncRectStat;
116:
1.1 root 117: struct VncSurface
118: {
1.1.1.3 root 119: struct timeval last_freq_check;
120: DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT], VNC_MAX_WIDTH / 16);
121: VncRectStat stats[VNC_STAT_ROWS][VNC_STAT_COLS];
1.1 root 122: DisplaySurface *ds;
123: };
124:
1.1.1.4 ! root 125: typedef enum VncShareMode {
! 126: VNC_SHARE_MODE_CONNECTING = 1,
! 127: VNC_SHARE_MODE_SHARED,
! 128: VNC_SHARE_MODE_EXCLUSIVE,
! 129: VNC_SHARE_MODE_DISCONNECTED,
! 130: } VncShareMode;
! 131:
! 132: typedef enum VncSharePolicy {
! 133: VNC_SHARE_POLICY_IGNORE = 1,
! 134: VNC_SHARE_POLICY_ALLOW_EXCLUSIVE,
! 135: VNC_SHARE_POLICY_FORCE_SHARED,
! 136: } VncSharePolicy;
! 137:
1.1 root 138: struct VncDisplay
139: {
140: QTAILQ_HEAD(, VncState) clients;
1.1.1.4 ! root 141: int num_exclusive;
! 142: VncSharePolicy share_policy;
1.1 root 143: QEMUTimer *timer;
144: int timer_interval;
145: int lsock;
146: DisplayState *ds;
147: kbd_layout_t *kbd_layout;
148: int lock_key_sync;
149: #ifdef CONFIG_VNC_THREAD
150: QemuMutex mutex;
151: #endif
152:
153: QEMUCursor *cursor;
154: int cursor_msize;
155: uint8_t *cursor_mask;
156:
157: struct VncSurface guest; /* guest visible surface (aka ds->surface) */
158: DisplaySurface *server; /* vnc server surface */
159:
160: char *display;
161: char *password;
1.1.1.2 root 162: time_t expires;
1.1 root 163: int auth;
164: bool lossy;
1.1.1.3 root 165: bool non_adaptive;
1.1 root 166: #ifdef CONFIG_VNC_TLS
167: int subauth; /* Used by VeNCrypt */
168: VncDisplayTLS tls;
169: #endif
170: #ifdef CONFIG_VNC_SASL
171: VncDisplaySASL sasl;
172: #endif
173: };
174:
175: typedef struct VncTight {
176: int type;
177: uint8_t quality;
178: uint8_t compression;
179: uint8_t pixel24;
180: Buffer tight;
181: Buffer tmp;
182: Buffer zlib;
183: Buffer gradient;
184: #ifdef CONFIG_VNC_JPEG
185: Buffer jpeg;
186: #endif
187: #ifdef CONFIG_VNC_PNG
188: Buffer png;
189: #endif
190: int levels[4];
191: z_stream stream[4];
192: } VncTight;
193:
194: typedef struct VncHextile {
195: VncSendHextileTile *send_tile;
196: } VncHextile;
197:
198: typedef struct VncZlib {
199: Buffer zlib;
200: Buffer tmp;
201: z_stream stream;
202: int level;
203: } VncZlib;
204:
1.1.1.3 root 205: typedef struct VncZrle {
206: int type;
207: Buffer fb;
208: Buffer zrle;
209: Buffer tmp;
210: Buffer zlib;
211: z_stream stream;
212: VncPalette palette;
213: } VncZrle;
214:
215: typedef struct VncZywrle {
216: int buf[VNC_ZRLE_TILE_WIDTH * VNC_ZRLE_TILE_HEIGHT];
217: } VncZywrle;
218:
1.1 root 219: #ifdef CONFIG_VNC_THREAD
220: struct VncRect
221: {
222: int x;
223: int y;
224: int w;
225: int h;
226: };
227:
228: struct VncRectEntry
229: {
230: struct VncRect rect;
231: QLIST_ENTRY(VncRectEntry) next;
232: };
233:
234: struct VncJob
235: {
236: VncState *vs;
237:
238: QLIST_HEAD(, VncRectEntry) rectangles;
239: QTAILQ_ENTRY(VncJob) next;
240: };
241: #else
242: struct VncJob
243: {
244: VncState *vs;
245: int rectangles;
246: size_t saved_offset;
247: };
248: #endif
249:
250: struct VncState
251: {
252: int csock;
253:
254: DisplayState *ds;
1.1.1.3 root 255: DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT], VNC_DIRTY_BITS);
256: uint8_t **lossy_rect; /* Not an Array to avoid costly memcpy in
257: * vnc-jobs-async.c */
1.1 root 258:
259: VncDisplay *vd;
260: int need_update;
261: int force_update;
262: uint32_t features;
263: int absolute;
264: int last_x;
265: int last_y;
266: int client_width;
267: int client_height;
1.1.1.4 ! root 268: VncShareMode share_mode;
1.1 root 269:
270: uint32_t vnc_encoding;
271:
272: int major;
273: int minor;
274:
1.1.1.3 root 275: int auth;
1.1 root 276: char challenge[VNC_AUTH_CHALLENGE_SIZE];
277: #ifdef CONFIG_VNC_TLS
1.1.1.3 root 278: int subauth; /* Used by VeNCrypt */
1.1 root 279: VncStateTLS tls;
280: #endif
281: #ifdef CONFIG_VNC_SASL
282: VncStateSASL sasl;
283: #endif
284:
285: QObject *info;
286:
287: Buffer output;
288: Buffer input;
289: /* current output mode information */
290: VncWritePixels *write_pixels;
291: DisplaySurface clientds;
292:
293: CaptureVoiceOut *audio_cap;
294: struct audsettings as;
295:
296: VncReadEvent *read_handler;
297: size_t read_handler_expect;
298: /* input */
299: uint8_t modifiers_state[256];
300: QEMUPutLEDEntry *led;
301:
302: bool abort;
303: #ifndef CONFIG_VNC_THREAD
304: VncJob job;
305: #else
306: QemuMutex output_mutex;
1.1.1.4 ! root 307: QEMUBH *bh;
! 308: Buffer jobs_buffer;
1.1 root 309: #endif
310:
311: /* Encoding specific, if you add something here, don't forget to
312: * update vnc_async_encoding_start()
313: */
314: VncTight tight;
315: VncZlib zlib;
316: VncHextile hextile;
1.1.1.3 root 317: VncZrle zrle;
318: VncZywrle zywrle;
1.1 root 319:
320: Notifier mouse_mode_notifier;
321:
322: QTAILQ_ENTRY(VncState) next;
323: };
324:
325:
326: /*****************************************************************************
327: *
328: * Authentication modes
329: *
330: *****************************************************************************/
331:
332: enum {
333: VNC_AUTH_INVALID = 0,
334: VNC_AUTH_NONE = 1,
335: VNC_AUTH_VNC = 2,
336: VNC_AUTH_RA2 = 5,
337: VNC_AUTH_RA2NE = 6,
338: VNC_AUTH_TIGHT = 16,
339: VNC_AUTH_ULTRA = 17,
340: VNC_AUTH_TLS = 18, /* Supported in GTK-VNC & VINO */
341: VNC_AUTH_VENCRYPT = 19, /* Supported in GTK-VNC & VeNCrypt */
342: VNC_AUTH_SASL = 20, /* Supported in GTK-VNC & VINO */
343: };
344:
345: enum {
346: VNC_AUTH_VENCRYPT_PLAIN = 256,
347: VNC_AUTH_VENCRYPT_TLSNONE = 257,
348: VNC_AUTH_VENCRYPT_TLSVNC = 258,
349: VNC_AUTH_VENCRYPT_TLSPLAIN = 259,
350: VNC_AUTH_VENCRYPT_X509NONE = 260,
351: VNC_AUTH_VENCRYPT_X509VNC = 261,
352: VNC_AUTH_VENCRYPT_X509PLAIN = 262,
353: VNC_AUTH_VENCRYPT_X509SASL = 263,
354: VNC_AUTH_VENCRYPT_TLSSASL = 264,
355: };
356:
357:
358: /*****************************************************************************
359: *
360: * Encoding types
361: *
362: *****************************************************************************/
363:
364: #define VNC_ENCODING_RAW 0x00000000
365: #define VNC_ENCODING_COPYRECT 0x00000001
366: #define VNC_ENCODING_RRE 0x00000002
367: #define VNC_ENCODING_CORRE 0x00000004
368: #define VNC_ENCODING_HEXTILE 0x00000005
369: #define VNC_ENCODING_ZLIB 0x00000006
370: #define VNC_ENCODING_TIGHT 0x00000007
371: #define VNC_ENCODING_ZLIBHEX 0x00000008
372: #define VNC_ENCODING_TRLE 0x0000000f
373: #define VNC_ENCODING_ZRLE 0x00000010
374: #define VNC_ENCODING_ZYWRLE 0x00000011
375: #define VNC_ENCODING_COMPRESSLEVEL0 0xFFFFFF00 /* -256 */
376: #define VNC_ENCODING_QUALITYLEVEL0 0xFFFFFFE0 /* -32 */
377: #define VNC_ENCODING_XCURSOR 0xFFFFFF10 /* -240 */
378: #define VNC_ENCODING_RICH_CURSOR 0xFFFFFF11 /* -239 */
379: #define VNC_ENCODING_POINTER_POS 0xFFFFFF18 /* -232 */
380: #define VNC_ENCODING_LASTRECT 0xFFFFFF20 /* -224 */
381: #define VNC_ENCODING_DESKTOPRESIZE 0xFFFFFF21 /* -223 */
382: #define VNC_ENCODING_POINTER_TYPE_CHANGE 0XFFFFFEFF /* -257 */
383: #define VNC_ENCODING_EXT_KEY_EVENT 0XFFFFFEFE /* -258 */
384: #define VNC_ENCODING_AUDIO 0XFFFFFEFD /* -259 */
385: #define VNC_ENCODING_TIGHT_PNG 0xFFFFFEFC /* -260 */
386: #define VNC_ENCODING_WMVi 0x574D5669
387:
388: /*****************************************************************************
389: *
390: * Other tight constants
391: *
392: *****************************************************************************/
393:
394: /*
395: * Vendors known by TightVNC: standard VNC/RealVNC, TridiaVNC, and TightVNC.
396: */
397:
398: #define VNC_TIGHT_CCB_RESET_MASK (0x0f)
399: #define VNC_TIGHT_CCB_TYPE_MASK (0x0f << 4)
400: #define VNC_TIGHT_CCB_TYPE_FILL (0x08 << 4)
401: #define VNC_TIGHT_CCB_TYPE_JPEG (0x09 << 4)
402: #define VNC_TIGHT_CCB_TYPE_PNG (0x0A << 4)
403: #define VNC_TIGHT_CCB_BASIC_MAX (0x07 << 4)
404: #define VNC_TIGHT_CCB_BASIC_ZLIB (0x03 << 4)
405: #define VNC_TIGHT_CCB_BASIC_FILTER (0x04 << 4)
406:
407: /*****************************************************************************
408: *
409: * Features
410: *
411: *****************************************************************************/
412:
413: #define VNC_FEATURE_RESIZE 0
414: #define VNC_FEATURE_HEXTILE 1
415: #define VNC_FEATURE_POINTER_TYPE_CHANGE 2
416: #define VNC_FEATURE_WMVI 3
417: #define VNC_FEATURE_TIGHT 4
418: #define VNC_FEATURE_ZLIB 5
419: #define VNC_FEATURE_COPYRECT 6
420: #define VNC_FEATURE_RICH_CURSOR 7
421: #define VNC_FEATURE_TIGHT_PNG 8
1.1.1.3 root 422: #define VNC_FEATURE_ZRLE 9
423: #define VNC_FEATURE_ZYWRLE 10
1.1 root 424:
425: #define VNC_FEATURE_RESIZE_MASK (1 << VNC_FEATURE_RESIZE)
426: #define VNC_FEATURE_HEXTILE_MASK (1 << VNC_FEATURE_HEXTILE)
427: #define VNC_FEATURE_POINTER_TYPE_CHANGE_MASK (1 << VNC_FEATURE_POINTER_TYPE_CHANGE)
428: #define VNC_FEATURE_WMVI_MASK (1 << VNC_FEATURE_WMVI)
429: #define VNC_FEATURE_TIGHT_MASK (1 << VNC_FEATURE_TIGHT)
430: #define VNC_FEATURE_ZLIB_MASK (1 << VNC_FEATURE_ZLIB)
431: #define VNC_FEATURE_COPYRECT_MASK (1 << VNC_FEATURE_COPYRECT)
432: #define VNC_FEATURE_RICH_CURSOR_MASK (1 << VNC_FEATURE_RICH_CURSOR)
433: #define VNC_FEATURE_TIGHT_PNG_MASK (1 << VNC_FEATURE_TIGHT_PNG)
1.1.1.3 root 434: #define VNC_FEATURE_ZRLE_MASK (1 << VNC_FEATURE_ZRLE)
435: #define VNC_FEATURE_ZYWRLE_MASK (1 << VNC_FEATURE_ZYWRLE)
1.1 root 436:
437:
438: /* Client -> Server message IDs */
439: #define VNC_MSG_CLIENT_SET_PIXEL_FORMAT 0
440: #define VNC_MSG_CLIENT_SET_ENCODINGS 2
441: #define VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST 3
442: #define VNC_MSG_CLIENT_KEY_EVENT 4
443: #define VNC_MSG_CLIENT_POINTER_EVENT 5
444: #define VNC_MSG_CLIENT_CUT_TEXT 6
445: #define VNC_MSG_CLIENT_VMWARE_0 127
446: #define VNC_MSG_CLIENT_CALL_CONTROL 249
447: #define VNC_MSG_CLIENT_XVP 250
448: #define VNC_MSG_CLIENT_SET_DESKTOP_SIZE 251
449: #define VNC_MSG_CLIENT_TIGHT 252
450: #define VNC_MSG_CLIENT_GII 253
451: #define VNC_MSG_CLIENT_VMWARE_1 254
452: #define VNC_MSG_CLIENT_QEMU 255
453:
454: /* Server -> Client message IDs */
455: #define VNC_MSG_SERVER_FRAMEBUFFER_UPDATE 0
456: #define VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES 1
457: #define VNC_MSG_SERVER_BELL 2
458: #define VNC_MSG_SERVER_CUT_TEXT 3
459: #define VNC_MSG_SERVER_VMWARE_0 127
460: #define VNC_MSG_SERVER_CALL_CONTROL 249
461: #define VNC_MSG_SERVER_XVP 250
462: #define VNC_MSG_SERVER_TIGHT 252
463: #define VNC_MSG_SERVER_GII 253
464: #define VNC_MSG_SERVER_VMWARE_1 254
465: #define VNC_MSG_SERVER_QEMU 255
466:
467:
468:
469: /* QEMU client -> server message IDs */
470: #define VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT 0
471: #define VNC_MSG_CLIENT_QEMU_AUDIO 1
472:
473: /* QEMU server -> client message IDs */
474: #define VNC_MSG_SERVER_QEMU_AUDIO 1
475:
476:
477:
478: /* QEMU client -> server audio message IDs */
479: #define VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE 0
480: #define VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE 1
481: #define VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT 2
482:
483: /* QEMU server -> client audio message IDs */
484: #define VNC_MSG_SERVER_QEMU_AUDIO_END 0
485: #define VNC_MSG_SERVER_QEMU_AUDIO_BEGIN 1
486: #define VNC_MSG_SERVER_QEMU_AUDIO_DATA 2
487:
488:
489: /*****************************************************************************
490: *
491: * Internal APIs
492: *
493: *****************************************************************************/
494:
495: /* Event loop functions */
496: void vnc_client_read(void *opaque);
497: void vnc_client_write(void *opaque);
498:
499: long vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen);
500: long vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen);
501:
502: /* Protocol I/O functions */
503: void vnc_write(VncState *vs, const void *data, size_t len);
504: void vnc_write_u32(VncState *vs, uint32_t value);
505: void vnc_write_s32(VncState *vs, int32_t value);
506: void vnc_write_u16(VncState *vs, uint16_t value);
507: void vnc_write_u8(VncState *vs, uint8_t value);
508: void vnc_flush(VncState *vs);
509: void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting);
510:
511:
512: /* Buffer I/O functions */
513: uint8_t read_u8(uint8_t *data, size_t offset);
514: uint16_t read_u16(uint8_t *data, size_t offset);
515: int32_t read_s32(uint8_t *data, size_t offset);
516: uint32_t read_u32(uint8_t *data, size_t offset);
517:
518: /* Protocol stage functions */
519: void vnc_client_error(VncState *vs);
520: int vnc_client_io_error(VncState *vs, int ret, int last_errno);
521:
522: void start_client_init(VncState *vs);
523: void start_auth_vnc(VncState *vs);
524:
525: /* Buffer management */
526: void buffer_reserve(Buffer *buffer, size_t len);
527: int buffer_empty(Buffer *buffer);
528: uint8_t *buffer_end(Buffer *buffer);
529: void buffer_reset(Buffer *buffer);
530: void buffer_free(Buffer *buffer);
531: void buffer_append(Buffer *buffer, const void *data, size_t len);
532:
533:
534: /* Misc helpers */
535:
536: char *vnc_socket_local_addr(const char *format, int fd);
537: char *vnc_socket_remote_addr(const char *format, int fd);
538:
539: static inline uint32_t vnc_has_feature(VncState *vs, int feature) {
540: return (vs->features & (1 << feature));
541: }
542:
543: /* Framebuffer */
544: void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
545: int32_t encoding);
546:
547: void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v);
1.1.1.3 root 548: double vnc_update_freq(VncState *vs, int x, int y, int w, int h);
549: void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h);
1.1 root 550:
551: /* Encodings */
552: int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h);
553:
554: int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h);
555:
556: int vnc_hextile_send_framebuffer_update(VncState *vs, int x,
557: int y, int w, int h);
558: void vnc_hextile_set_pixel_conversion(VncState *vs, int generic);
559:
560: void *vnc_zlib_zalloc(void *x, unsigned items, unsigned size);
561: void vnc_zlib_zfree(void *x, void *addr);
562: int vnc_zlib_send_framebuffer_update(VncState *vs, int x, int y, int w, int h);
563: void vnc_zlib_clear(VncState *vs);
564:
565: int vnc_tight_send_framebuffer_update(VncState *vs, int x, int y, int w, int h);
566: int vnc_tight_png_send_framebuffer_update(VncState *vs, int x, int y,
567: int w, int h);
568: void vnc_tight_clear(VncState *vs);
569:
1.1.1.3 root 570: int vnc_zrle_send_framebuffer_update(VncState *vs, int x, int y, int w, int h);
571: int vnc_zywrle_send_framebuffer_update(VncState *vs, int x, int y, int w, int h);
572: void vnc_zrle_clear(VncState *vs);
573:
1.1 root 574: #endif /* __QEMU_VNC_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.