* THE SOFTWARE.
*/
-#ifndef __QEMU_VNC_H
-#define __QEMU_VNC_H
+#ifndef QEMU_VNC_H
+#define QEMU_VNC_H
#include "qemu-common.h"
#include "qemu/queue.h"
#include "qemu/thread.h"
#include "ui/console.h"
-#include "monitor/monitor.h"
#include "audio/audio.h"
#include "qemu/bitmap.h"
+#include "crypto/tlssession.h"
+#include "qemu/buffer.h"
+#include "io/channel-socket.h"
+#include "io/channel-tls.h"
#include <zlib.h>
-#include <stdbool.h>
#include "keymaps.h"
#include "vnc-palette.h"
#include "vnc-enc-zrle.h"
+#include "qapi-types.h"
// #define _VNC_DEBUG 1
*
*****************************************************************************/
-typedef struct Buffer
-{
- size_t capacity;
- size_t offset;
- uint8_t *buffer;
-} Buffer;
-
typedef struct VncState VncState;
typedef struct VncJob VncJob;
typedef struct VncRect VncRect;
void *last_fg,
int *has_bg, int *has_fg);
-/* VNC_MAX_WIDTH must be a multiple of 16. */
-#define VNC_MAX_WIDTH 2560
+/* VNC_DIRTY_PIXELS_PER_BIT is the number of dirty pixels represented
+ * by one bit in the dirty bitmap, should be a power of 2 */
+#define VNC_DIRTY_PIXELS_PER_BIT 16
+
+/* VNC_MAX_WIDTH must be a multiple of VNC_DIRTY_PIXELS_PER_BIT. */
+
+#define VNC_MAX_WIDTH ROUND_UP(2560, VNC_DIRTY_PIXELS_PER_BIT)
#define VNC_MAX_HEIGHT 2048
/* VNC_DIRTY_BITS is the number of bits in the dirty bitmap. */
-#define VNC_DIRTY_BITS (VNC_MAX_WIDTH / 16)
+#define VNC_DIRTY_BITS (VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT)
+
+/* VNC_DIRTY_BPL (BPL = bits per line) might be greater than
+ * VNC_DIRTY_BITS due to alignment */
+#define VNC_DIRTY_BPL(x) (sizeof((x)->dirty) / VNC_MAX_HEIGHT * BITS_PER_BYTE)
#define VNC_STAT_RECT 64
#define VNC_STAT_COLS (VNC_MAX_WIDTH / VNC_STAT_RECT)
typedef struct VncDisplay VncDisplay;
-#ifdef CONFIG_VNC_TLS
-#include "vnc-tls.h"
#include "vnc-auth-vencrypt.h"
-#endif
#ifdef CONFIG_VNC_SASL
#include "vnc-auth-sasl.h"
#endif
-#ifdef CONFIG_VNC_WS
#include "vnc-ws.h"
-#endif
struct VncRectStat
{
struct VncSurface
{
struct timeval last_freq_check;
- DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT], VNC_MAX_WIDTH / 16);
+ DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT],
+ VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT);
VncRectStat stats[VNC_STAT_ROWS][VNC_STAT_COLS];
pixman_image_t *fb;
pixman_format_code_t format;
struct VncDisplay
{
QTAILQ_HEAD(, VncState) clients;
+ int num_connecting;
+ int num_shared;
int num_exclusive;
+ int connections_limit;
VncSharePolicy share_policy;
- int lsock;
-#ifdef CONFIG_VNC_WS
- int lwebsock;
- bool websocket;
- char *ws_display;
-#endif
+ QIOChannelSocket *lsock;
+ guint lsock_tag;
+ QIOChannelSocket *lwebsock;
+ guint lwebsock_tag;
+ bool ws_enabled;
DisplaySurface *ds;
DisplayChangeListener dcl;
kbd_layout_t *kbd_layout;
int lock_key_sync;
+ int key_delay_ms;
QemuMutex mutex;
QEMUCursor *cursor;
struct VncSurface guest; /* guest visible surface (aka ds->surface) */
pixman_image_t *server; /* vnc server surface */
- char *display;
+ const char *id;
+ QTAILQ_ENTRY(VncDisplay) next;
+ bool enabled;
+ bool is_unix;
char *password;
time_t expires;
int auth;
+ int subauth; /* Used by VeNCrypt */
+ int ws_auth; /* Used by websockets */
+ bool ws_tls; /* Used by websockets */
bool lossy;
bool non_adaptive;
-#ifdef CONFIG_VNC_TLS
- int subauth; /* Used by VeNCrypt */
- VncDisplayTLS tls;
-#endif
+ QCryptoTLSCreds *tlscreds;
+ char *tlsaclname;
#ifdef CONFIG_VNC_SASL
VncDisplaySASL sasl;
#endif
struct VncState
{
- int csock;
+ QIOChannelSocket *sioc; /* The underlying socket */
+ QIOChannel *ioc; /* The channel currently used for I/O */
+ guint ioc_tag;
+ gboolean disconnecting;
DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT], VNC_DIRTY_BITS);
uint8_t **lossy_rect; /* Not an Array to avoid costly memcpy in
VncDisplay *vd;
int need_update;
int force_update;
+ int has_dirty;
uint32_t features;
int absolute;
int last_x;
int last_y;
+ uint32_t last_bmask;
int client_width;
int client_height;
VncShareMode share_mode;
int minor;
int auth;
- char challenge[VNC_AUTH_CHALLENGE_SIZE];
-#ifdef CONFIG_VNC_TLS
int subauth; /* Used by VeNCrypt */
- VncStateTLS tls;
-#endif
+ char challenge[VNC_AUTH_CHALLENGE_SIZE];
+ QCryptoTLSSession *tls; /* Borrowed pointer from channel, don't free */
#ifdef CONFIG_VNC_SASL
VncStateSASL sasl;
#endif
-#ifdef CONFIG_VNC_WS
bool encode_ws;
bool websocket;
-#endif
- QObject *info;
+ VncClientInfo *info;
Buffer output;
Buffer input;
-#ifdef CONFIG_VNC_WS
- Buffer ws_input;
- Buffer ws_output;
-#endif
/* current output mode information */
VncWritePixels *write_pixels;
PixelFormat client_pf;
#define VNC_ENCODING_EXT_KEY_EVENT 0XFFFFFEFE /* -258 */
#define VNC_ENCODING_AUDIO 0XFFFFFEFD /* -259 */
#define VNC_ENCODING_TIGHT_PNG 0xFFFFFEFC /* -260 */
+#define VNC_ENCODING_LED_STATE 0XFFFFFEFB /* -261 */
#define VNC_ENCODING_WMVi 0x574D5669
/*****************************************************************************
#define VNC_FEATURE_TIGHT_PNG 8
#define VNC_FEATURE_ZRLE 9
#define VNC_FEATURE_ZYWRLE 10
+#define VNC_FEATURE_LED_STATE 11
#define VNC_FEATURE_RESIZE_MASK (1 << VNC_FEATURE_RESIZE)
#define VNC_FEATURE_HEXTILE_MASK (1 << VNC_FEATURE_HEXTILE)
#define VNC_FEATURE_TIGHT_PNG_MASK (1 << VNC_FEATURE_TIGHT_PNG)
#define VNC_FEATURE_ZRLE_MASK (1 << VNC_FEATURE_ZRLE)
#define VNC_FEATURE_ZYWRLE_MASK (1 << VNC_FEATURE_ZYWRLE)
+#define VNC_FEATURE_LED_STATE_MASK (1 << VNC_FEATURE_LED_STATE)
/* Client -> Server message IDs */
*****************************************************************************/
/* Event loop functions */
-void vnc_client_read(void *opaque);
-void vnc_client_write(void *opaque);
+gboolean vnc_client_io(QIOChannel *ioc,
+ GIOCondition condition,
+ void *opaque);
-long vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen);
-long vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen);
+ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen);
+ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen);
/* Protocol I/O functions */
void vnc_write(VncState *vs, const void *data, size_t len);
/* Protocol stage functions */
void vnc_client_error(VncState *vs);
-int vnc_client_io_error(VncState *vs, int ret, int last_errno);
+ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp);
void start_client_init(VncState *vs);
void start_auth_vnc(VncState *vs);
-/* Buffer management */
-void buffer_reserve(Buffer *buffer, size_t len);
-void buffer_reset(Buffer *buffer);
-void buffer_free(Buffer *buffer);
-void buffer_append(Buffer *buffer, const void *data, size_t len);
-void buffer_advance(Buffer *buf, size_t len);
-uint8_t *buffer_end(Buffer *buffer);
-
/* Misc helpers */
-char *vnc_socket_local_addr(const char *format, int fd);
-char *vnc_socket_remote_addr(const char *format, int fd);
-
static inline uint32_t vnc_has_feature(VncState *vs, int feature) {
return (vs->features & (1 << feature));
}
int vnc_zywrle_send_framebuffer_update(VncState *vs, int x, int y, int w, int h);
void vnc_zrle_clear(VncState *vs);
-#endif /* __QEMU_VNC_H */
+#endif /* QEMU_VNC_H */