#ifndef RFBCLIENT_H
#define RFBCLIENT_H
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#ifdef _MSC_VER
#pragma warning(disable:4996)
#endif
#endif
#if defined(ANDROID) || defined(LIBVNCSERVER_HAVE_ANDROID)
#include <arpa/inet.h>
#include <sys/select.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if LIBVNCSERVER_HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#if LIBVNCSERVER_HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <rfb/rfbproto.h>
#include <rfb/keysym.h>
#include <rfb/threading.h>
#ifdef LIBVNCSERVER_HAVE_SASL
#include <sasl/sasl.h>
#endif
#define rfbClientSwap16IfLE(s) \
(*(char *)&client->endianTest ? ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) : (s))
#define rfbClientSwap32IfLE(l) \
(*(char *)&client->endianTest ? ((((l) >> 24) & 0x000000ff) | \
(((l) & 0x00ff0000) >> 8) | \
(((l) & 0x0000ff00) << 8) | \
(((l) & 0x000000ff) << 24)) : (l))
#define rfbClientSwap64IfLE(l) \
(*(char *)&client->endianTest ? ((((l) >> 56 ) & 0x00000000000000ffULL) | \
(((l) & 0x00ff000000000000ULL) >> 40) | \
(((l) & 0x0000ff0000000000ULL) >> 24) | \
(((l) & 0x000000ff00000000ULL) >> 8) | \
(((l) & 0x00000000ff000000ULL) << 8) | \
(((l) & 0x0000000000ff0000ULL) << 24) | \
(((l) & 0x000000000000ff00ULL) << 40) | \
(((l) & 0x00000000000000ffULL) << 56)) : (l))
#define FLASH_PORT_OFFSET 5400
#define LISTEN_PORT_OFFSET 5500
#define TUNNEL_PORT_OFFSET 5500
#define SERVER_PORT_OFFSET 5900
#define DEFAULT_CONNECT_TIMEOUT 60
#define DEFAULT_READ_TIMEOUT 0
#define DEFAULT_SSH_CMD "/usr/bin/ssh"
#define DEFAULT_TUNNEL_CMD \
(DEFAULT_SSH_CMD " -f -L %L:localhost:%R %H sleep 20")
#define DEFAULT_VIA_CMD \
(DEFAULT_SSH_CMD " -f -L %L:%H:%R %G sleep 20")
#if(defined __cplusplus)
extern "C"
{
#endif
typedef struct {
FILE* file;
struct timeval tv;
rfbBool readTimestamp;
rfbBool doNotSleep;
} rfbVNCRec;
typedef struct rfbClientData {
void* tag;
void* data;
struct rfbClientData* next;
} rfbClientData;
typedef struct {
rfbBool shareDesktop;
rfbBool viewOnly;
const char* encodingsString;
rfbBool useBGR233;
int nColours;
rfbBool forceOwnCmap;
rfbBool forceTrueColour;
int requestedDepth;
int compressLevel;
int qualityLevel;
rfbBool enableJPEG;
rfbBool useRemoteCursor;
rfbBool palmVNC;
int scaleSetting;
} AppData;
typedef union _rfbCredential
{
struct
{
char *x509CACertFile;
char *x509CACrlFile;
char *x509ClientCertFile;
char *x509ClientKeyFile;
uint8_t x509CrlVerifyMode;
} x509Credential;
struct
{
char *username;
char *password;
} userCredential;
} rfbCredential;
#define rfbCredentialTypeX509 1
#define rfbCredentialTypeUser 2
#define rfbX509CrlVerifyNone 0
#define rfbX509CrlVerifyClient 1
#define rfbX509CrlVerifyAll 2
struct _rfbClient;
typedef void (*HandleTextChatProc)(struct _rfbClient* client, int value, char *text);
typedef void (*HandleXvpMsgProc)(struct _rfbClient* client, uint8_t version, uint8_t opcode);
typedef void (*HandleKeyboardLedStateProc)(struct _rfbClient* client, int value, int pad);
typedef rfbBool (*HandleCursorPosProc)(struct _rfbClient* client, int x, int y);
typedef void (*SoftCursorLockAreaProc)(struct _rfbClient* client, int x, int y, int w, int h);
typedef void (*SoftCursorUnlockScreenProc)(struct _rfbClient* client);
typedef void (*GotFrameBufferUpdateProc)(struct _rfbClient* client, int x, int y, int w, int h);
typedef void (*FinishedFrameBufferUpdateProc)(struct _rfbClient* client);
typedef char* (*GetPasswordProc)(struct _rfbClient* client);
typedef rfbCredential* (*GetCredentialProc)(struct _rfbClient* client, int credentialType);
typedef rfbBool (*MallocFrameBufferProc)(struct _rfbClient* client);
typedef void (*GotXCutTextProc)(struct _rfbClient* client, const char *text, int textlen);
typedef void (*GotXCutTextUTF8Proc)(struct _rfbClient* client, const char* buffer, int buffer_len);
typedef void (*BellProc)(struct _rfbClient* client);
typedef void (*GotCursorShapeProc)(struct _rfbClient* client, int xhot, int yhot, int width, int height, int bytesPerPixel);
typedef void (*GotCopyRectProc)(struct _rfbClient* client, int src_x, int src_y, int w, int h, int dest_x, int dest_y);
typedef void (*GotFillRectProc)(struct _rfbClient* client, int x, int y, int w, int h, uint32_t colour);
typedef void (*GotBitmapProc)(struct _rfbClient* client, const uint8_t* buffer, int x, int y, int w, int h);
typedef rfbBool (*GotJpegProc)(struct _rfbClient* client, const uint8_t* buffer, int length, int x, int y, int w, int h);
typedef rfbBool (*LockWriteToTLSProc)(struct _rfbClient* client);
typedef rfbBool (*UnlockWriteToTLSProc)(struct _rfbClient* client);
#ifdef LIBVNCSERVER_HAVE_SASL
typedef char* (*GetUserProc)(struct _rfbClient* client);
typedef char* (*GetSASLMechanismProc)(struct _rfbClient* client, char* mechlist);
#endif
typedef struct _rfbClient {
uint8_t* frameBuffer;
int width, height;
int endianTest;
AppData appData;
const char* programName;
char* serverHost;
int serverPort;
rfbBool listenSpecified;
int listenPort, flashPort;
struct {
int x, y, w, h;
} updateRect;
#define RFB_BUFFER_SIZE (640*480)
char buffer[RFB_BUFFER_SIZE];
rfbSocket sock;
rfbBool canUseCoRRE;
rfbBool canUseHextile;
char *desktopName;
rfbPixelFormat format;
rfbServerInitMsg si;
#define RFB_BUF_SIZE 8192
char buf[RFB_BUF_SIZE];
char *bufoutptr;
unsigned int buffered;
int ultra_buffer_size;
char *ultra_buffer;
int raw_buffer_size;
char *raw_buffer;
#ifdef LIBVNCSERVER_HAVE_LIBZ
z_stream decompStream;
rfbBool decompStreamInited;
#endif
#ifdef LIBVNCSERVER_HAVE_LIBZ
#define ZLIB_BUFFER_SIZE 30000
char zlib_buffer[ZLIB_BUFFER_SIZE];
z_stream zlibStream[4];
rfbBool zlibStreamActive[4];
rfbBool cutZeros;
int rectWidth, rectColors;
char tightPalette[256*4];
uint8_t tightPrevRow[2048*3*sizeof(uint16_t)];
#ifdef LIBVNCSERVER_HAVE_LIBJPEG
rfbBool jpegError;
struct jpeg_source_mgr* jpegSrcManager;
void* jpegBufferPtr;
size_t jpegBufferLen;
#endif
#endif
uint8_t *rcSource, *rcMask;
rfbClientData* clientData;
rfbVNCRec* vncRec;
int KeyboardLedStateEnabled;
int CurrentKeyboardLedState;
int canHandleNewFBSize;
HandleTextChatProc HandleTextChat;
HandleKeyboardLedStateProc HandleKeyboardLedState;
HandleCursorPosProc HandleCursorPos;
SoftCursorLockAreaProc SoftCursorLockArea;
SoftCursorUnlockScreenProc SoftCursorUnlockScreen;
GotFrameBufferUpdateProc GotFrameBufferUpdate;
GetPasswordProc GetPassword;
MallocFrameBufferProc MallocFrameBuffer;
GotXCutTextProc GotXCutText;
BellProc Bell;
GotCursorShapeProc GotCursorShape;
GotCopyRectProc GotCopyRect;
rfbSupportedMessages supportedMessages;
int major, minor;
uint32_t authScheme, subAuthScheme;
void* tlsSession;
GetCredentialProc GetCredential;
uint32_t *clientAuthSchemes;
char *destHost;
int destPort;
int QoS_DSCP;
HandleXvpMsgProc HandleXvpMsg;
rfbSocket listenSock;
FinishedFrameBufferUpdateProc FinishedFrameBufferUpdate;
char *listenAddress;
rfbSocket listen6Sock;
char* listen6Address;
int listen6Port;
unsigned long outputWindow;
LockWriteToTLSProc LockWriteToTLS;
UnlockWriteToTLSProc UnlockWriteToTLS;
GotFillRectProc GotFillRect;
GotBitmapProc GotBitmap;
GotJpegProc GotJpeg;
#ifdef LIBVNCSERVER_HAVE_SASL
sasl_conn_t *saslconn;
const char *saslDecoded;
unsigned int saslDecodedLength;
unsigned int saslDecodedOffset;
sasl_secret_t *saslSecret;
GetSASLMechanismProc GetSASLMechanism;
GetUserProc GetUser;
#endif
#ifdef LIBVNCSERVER_HAVE_LIBZ
#ifdef LIBVNCSERVER_HAVE_LIBJPEG
void *tjhnd;
#endif
#endif
unsigned int connectTimeout;
unsigned int readTimeout;
MUTEX(tlsRwMutex);
rfbBool requestedResize;
rfbExtDesktopScreen screen;
#ifdef LIBVNCSERVER_HAVE_LIBZ
uint32_t extendedClipboardServerCapabilities;
#endif
GotXCutTextUTF8Proc GotXCutTextUTF8;
rfbBool isUpdateRectManagedByLib;
} rfbClient;
extern rfbBool HandleCursorShape(rfbClient* client,int xhot, int yhot, int width, int height, uint32_t enc);
extern void listenForIncomingConnections(rfbClient* viewer);
extern int listenForIncomingConnectionsNoFork(rfbClient* viewer, int usec_timeout);
extern rfbBool rfbEnableClientLogging;
typedef void (*rfbClientLogProc)(const char *format, ...);
extern rfbClientLogProc rfbClientLog,rfbClientErr;
extern rfbBool ConnectToRFBServer(rfbClient* client,const char *hostname, int port);
extern rfbBool ConnectToRFBRepeater(rfbClient* client,const char *repeaterHost, int repeaterPort, const char *destHost, int destPort);
extern void SetClientAuthSchemes(rfbClient* client,const uint32_t *authSchemes, int size);
extern rfbBool InitialiseRFBConnection(rfbClient* client);
extern rfbBool SetFormatAndEncodings(rfbClient* client);
extern rfbBool SendIncrementalFramebufferUpdateRequest(rfbClient* client);
extern rfbBool SendFramebufferUpdateRequest(rfbClient* client,
int x, int y, int w, int h,
rfbBool incremental);
extern rfbBool SendScaleSetting(rfbClient* client,int scaleSetting);
extern rfbBool SendPointerEvent(rfbClient* client,int x, int y, int buttonMask);
extern rfbBool SendExtDesktopSize(rfbClient* client, uint16_t width, uint16_t height);
extern rfbBool SendKeyEvent(rfbClient* client,uint32_t key, rfbBool down);
extern rfbBool SendExtendedKeyEvent(rfbClient* client, uint32_t keysym, uint32_t keycode, rfbBool down);
extern rfbBool SendClientCutText(rfbClient* client,char *str, int len);
extern rfbBool SendClientCutTextUTF8(rfbClient* client, char *str, int len);
extern rfbBool HandleRFBServerMessage(rfbClient* client);
extern rfbBool TextChatSend(rfbClient* client, char *text);
extern rfbBool TextChatOpen(rfbClient* client);
extern rfbBool TextChatClose(rfbClient* client);
extern rfbBool TextChatFinish(rfbClient* client);
extern rfbBool PermitServerInput(rfbClient* client, int enabled);
extern rfbBool SendXvpMsg(rfbClient* client, uint8_t version, uint8_t code);
extern void PrintPixelFormat(rfbPixelFormat *format);
extern rfbBool SupportsClient2Server(rfbClient* client, int messageType);
extern rfbBool SupportsServer2Client(rfbClient* client, int messageType);
extern void rfbClientSetUpdateRect(rfbClient *client, rfbRectangle *rect);
extern void rfbClientGetUpdateRect(rfbClient *client, rfbRectangle *rect, rfbBool *isManagedByLib);
void rfbClientSetClientData(rfbClient* client, void* tag, void* data);
void* rfbClientGetClientData(rfbClient* client, void* tag);
typedef struct _rfbClientProtocolExtension {
int* encodings;
rfbBool (*handleEncoding)(rfbClient* cl,
rfbFramebufferUpdateRectHeader* rect);
rfbBool (*handleMessage)(rfbClient* cl,
rfbServerToClientMsg* message);
struct _rfbClientProtocolExtension* next;
uint32_t const* securityTypes;
rfbBool (*handleAuthentication)(rfbClient* cl, uint32_t authScheme);
} rfbClientProtocolExtension;
void rfbClientRegisterExtension(rfbClientProtocolExtension* e);
extern rfbBool errorMessageOnReadFailure;
extern rfbBool ReadFromRFBServer(rfbClient* client, char *out, unsigned int n);
extern rfbBool WriteToRFBServer(rfbClient* client, const char *buf, unsigned int n);
extern int FindFreeTcpPort(void);
extern rfbSocket ListenAtTcpPort(int port);
extern rfbSocket ListenAtTcpPortAndAddress(int port, const char *address);
extern rfbSocket ConnectClientToTcpAddr(unsigned int host, int port);
extern rfbSocket ConnectClientToTcpAddr6(const char *hostname, int port);
extern rfbSocket ConnectClientToUnixSock(const char *sockFile);
extern rfbSocket ConnectClientToTcpAddrWithTimeout(unsigned int host, int port, unsigned int timeout);
extern rfbSocket ConnectClientToTcpAddr6WithTimeout(const char *hostname, int port, unsigned int timeout);
extern rfbSocket ConnectClientToUnixSockWithTimeout(const char *sockFile, unsigned int timeout);
extern rfbSocket AcceptTcpConnection(rfbSocket listenSock);
extern rfbBool SetNonBlocking(rfbSocket sock);
extern rfbBool SetBlocking(rfbSocket sock);
extern rfbBool SetDSCP(rfbSocket sock, int dscp);
extern rfbBool StringToIPAddr(const char *str, unsigned int *addr);
extern rfbBool SameMachine(rfbSocket sock);
extern int WaitForMessage(rfbClient* client,unsigned int usecs);
rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel,int bytesPerPixel);
rfbBool rfbInitClient(rfbClient* client,int* argc,char** argv);
rfbBool rfbClientConnect(rfbClient* client);
rfbBool rfbClientInitialise(rfbClient* client);
void rfbClientCleanup(rfbClient* client);
#if(defined __cplusplus)
}
#endif
#endif