
#ifndef __VNCSERV_H__
#define __VNCSERV_H__

#include "areas.h"

#define RAW_ENCODING                    0
#define COPY_ENCODING                   1
#define HEXTILE_ENCODING                5
#define HEXTILEDITHER8_ENCODING         0x00221000

typedef unsigned char  CARD8;
typedef unsigned short CARD16;
typedef unsigned int   CARD32;

typedef struct vncserv_s vncserv;


// status codes to be returned by io functions
#define VNCSERV_OK                      0
#define VNCSERV_CLIENT_HAS_GONE         -1
#define VNCSERV_FAILED_TO_READ          -2
#define VNCSERV_FAILED_TO_WRITE         -3
#define VNCSERV_FATAL_ERROR             -4

typedef struct vncservio_t {
  // read() should return no. of bytes read or VNCSERV_???
  int (* read      )(const vncserv *serv, void *buffer, int bytes, void *meta);
  int (* write     )(const vncserv *serv, void *buffer, int bytes, void *meta);
  int (* setmark  )(const vncserv *serv, void *meta);
  int (* getmark )(const vncserv *serv, void *meta);
  int (* keypress  )(const vncserv *serv, int key, int down, void *meta);
  int (* pointer   )(const vncserv *serv, int x, int y, int buttons, void *meta);
  int (* cuttext   )(const vncserv *serv, const char *text, int len, void *meta);
  // error() may be called with serv=NULL during vncserver_create()
  int (* error     )(const vncserv *serv, const char *msg, void *meta);
  int (* poll      )(const vncserv *serv, void *meta);
} vncservio;


// create a new server
vncserv *vncserver_create(void *framebuffer, int sizex, int sizey, int bpp, int bpl, char *name, vncservio *io, void *meta, const char *password);

// set buffer size - should be set to a little bit larger than the
// largest amount of text the client will ever pass in a 'cut text' message
int vncserver_set_buffer_size(vncserv *serv, int size);

// inform the server that the connection to the client is open
void vncserv_started(vncserv *serv);

// set 8bpp palette (if not RGB332)
void vncserv_set_8bpp_palette(vncserv *cl, const unsigned int *palette);

// poll the server, should be called as often as possible
// returns VNCSERV_OK or VNCSERV_FATAL_ERROR
int vncserv_poll(vncserv *serv, int timeout_in_milliseconds);

// inform the server that part of the framebuffer has changed
// coords are in pixels, with 0,0 being the top left corner
void vncserv_framebuffer_changed(vncserv *serv, area *ar);
void vncserv_framebuffer_area_moved(vncserv *serv, area *from, area *to);

// shutdown the server
void vncserv_closedown(vncserv *serv);

// paste text to the client
void vncserv_cut_text(vncserv *serv, char *text);

// ring the bell on the client
void vncserv_bell(vncserv *serv);

// if no io.read() function is specified, use vncserv_give_data() to
// give data to the server - returns no. of bytes free in the
// internal buffer (if < 0, no. of bytes not buffered)
int vncserv_give_data(vncserv *serv, char *buffer, int bytes);

// if no io.keypress() function is specified, use vncserv_read_key()
// to read key events, returns no. of buffered keypressed
int vncserv_read_key(vncserv *serv, int *key, int *down, int *time);

// if no io.pointer() function is specified, use vncserv_read_pointer()
// to read pointer events, returns no. of buffered events
int vncserv_read_pointer(vncserv *serv, int *x, int *y, int *buttons, int *time);


#define Swap16IfLE(s)  ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff))
#define Swap32IfLE(l)  ((((l) & 0xff000000) >> 24) |         \
		        (((l) & 0x00ff0000) >> 8)  |         \
		        (((l) & 0x0000ff00) << 8)  |         \
		        (((l) & 0x000000ff) << 24))

#endif
