Home | History | Annotate | Download | only in rfb
      1 #ifndef RFB_H
      2 #define RFB_H
      3 /**
      4  * @defgroup libvncserver_api LibVNCServer API Reference
      5  * @{
      6  */
      7 
      8 /**
      9  * @file rfb.h
     10  */
     11 
     12 /*
     13  *  Copyright (C) 2005 Rohit Kumar <rokumar (at) novell.com>,
     14  *                     Johannes E. Schindelin <johannes.schindelin (at) gmx.de>
     15  *  Copyright (C) 2002 RealVNC Ltd.
     16  *  OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk (at) incompleteness.net>.
     17  *  Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
     18  *  All Rights Reserved.
     19  *
     20  *  This is free software; you can redistribute it and/or modify
     21  *  it under the terms of the GNU General Public License as published by
     22  *  the Free Software Foundation; either version 2 of the License, or
     23  *  (at your option) any later version.
     24  *
     25  *  This software is distributed in the hope that it will be useful,
     26  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     27  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     28  *  GNU General Public License for more details.
     29  *
     30  *  You should have received a copy of the GNU General Public License
     31  *  along with this software; if not, write to the Free Software
     32  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
     33  *  USA.
     34  */
     35 
     36 #if(defined __cplusplus)
     37 extern "C"
     38 {
     39 #endif
     40 
     41 #include <stdio.h>
     42 #include <stdlib.h>
     43 #include <string.h>
     44 #include <rfb/rfbproto.h>
     45 
     46 #if defined(ANDROID) || defined(LIBVNCSERVER_HAVE_ANDROID)
     47 #include <arpa/inet.h>
     48 #include <sys/select.h>
     49 #endif
     50 
     51 #ifdef LIBVNCSERVER_HAVE_SYS_TYPES_H
     52 #include <sys/types.h>
     53 #endif
     54 
     55 #ifdef WIN32
     56 #undef SOCKET
     57 #include <winsock2.h>
     58 #ifdef LIBVNCSERVER_HAVE_WS2TCPIP_H
     59 #undef socklen_t
     60 #include <ws2tcpip.h>
     61 #endif
     62 #endif
     63 
     64 #ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
     65 #include <pthread.h>
     66 #if 0 /* debugging */
     67 #define LOCK(mutex) (rfbLog("%s:%d LOCK(%s,0x%x)\n",__FILE__,__LINE__,#mutex,&(mutex)), pthread_mutex_lock(&(mutex)))
     68 #define UNLOCK(mutex) (rfbLog("%s:%d UNLOCK(%s,0x%x)\n",__FILE__,__LINE__,#mutex,&(mutex)), pthread_mutex_unlock(&(mutex)))
     69 #define MUTEX(mutex) pthread_mutex_t (mutex)
     70 #define INIT_MUTEX(mutex) (rfbLog("%s:%d INIT_MUTEX(%s,0x%x)\n",__FILE__,__LINE__,#mutex,&(mutex)), pthread_mutex_init(&(mutex),NULL))
     71 #define TINI_MUTEX(mutex) (rfbLog("%s:%d TINI_MUTEX(%s)\n",__FILE__,__LINE__,#mutex), pthread_mutex_destroy(&(mutex)))
     72 #define TSIGNAL(cond) (rfbLog("%s:%d TSIGNAL(%s)\n",__FILE__,__LINE__,#cond), pthread_cond_signal(&(cond)))
     73 #define WAIT(cond,mutex) (rfbLog("%s:%d WAIT(%s,%s)\n",__FILE__,__LINE__,#cond,#mutex), pthread_cond_wait(&(cond),&(mutex)))
     74 #define COND(cond) pthread_cond_t (cond)
     75 #define INIT_COND(cond) (rfbLog("%s:%d INIT_COND(%s)\n",__FILE__,__LINE__,#cond), pthread_cond_init(&(cond),NULL))
     76 #define TINI_COND(cond) (rfbLog("%s:%d TINI_COND(%s)\n",__FILE__,__LINE__,#cond), pthread_cond_destroy(&(cond)))
     77 #define IF_PTHREADS(x) x
     78 #else
     79 #if !NONETWORK
     80 #define LOCK(mutex) pthread_mutex_lock(&(mutex));
     81 #define UNLOCK(mutex) pthread_mutex_unlock(&(mutex));
     82 #endif
     83 #define MUTEX(mutex) pthread_mutex_t (mutex)
     84 #define INIT_MUTEX(mutex) pthread_mutex_init(&(mutex),NULL)
     85 #define TINI_MUTEX(mutex) pthread_mutex_destroy(&(mutex))
     86 #define TSIGNAL(cond) pthread_cond_signal(&(cond))
     87 #define WAIT(cond,mutex) pthread_cond_wait(&(cond),&(mutex))
     88 #define COND(cond) pthread_cond_t (cond)
     89 #define INIT_COND(cond) pthread_cond_init(&(cond),NULL)
     90 #define TINI_COND(cond) pthread_cond_destroy(&(cond))
     91 #define IF_PTHREADS(x) x
     92 #endif
     93 #else
     94 #define LOCK(mutex)
     95 #define UNLOCK(mutex)
     96 #define MUTEX(mutex)
     97 #define INIT_MUTEX(mutex)
     98 #define TINI_MUTEX(mutex)
     99 #define TSIGNAL(cond)
    100 #define WAIT(cond,mutex) this_is_unsupported
    101 #define COND(cond)
    102 #define INIT_COND(cond)
    103 #define TINI_COND(cond)
    104 #define IF_PTHREADS(x)
    105 #endif
    106 
    107 /* end of stuff for autoconf */
    108 
    109 /* if you use pthreads, but don't define LIBVNCSERVER_HAVE_LIBPTHREAD, the structs
    110    get all mixed up. So this gives a linker error reminding you to compile
    111    the library and your application (at least the parts including rfb.h)
    112    with the same support for pthreads. */
    113 #ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
    114 #ifdef LIBVNCSERVER_HAVE_LIBZ
    115 #define rfbInitServer rfbInitServerWithPthreadsAndZRLE
    116 #else
    117 #define rfbInitServer rfbInitServerWithPthreadsButWithoutZRLE
    118 #endif
    119 #else
    120 #ifdef LIBVNCSERVER_HAVE_LIBZ
    121 #define rfbInitServer rfbInitServerWithoutPthreadsButWithZRLE
    122 #else
    123 #define rfbInitServer rfbInitServerWithoutPthreadsAndZRLE
    124 #endif
    125 #endif
    126 
    127 struct _rfbClientRec;
    128 struct _rfbScreenInfo;
    129 struct rfbCursor;
    130 
    131 enum rfbNewClientAction {
    132 	RFB_CLIENT_ACCEPT,
    133 	RFB_CLIENT_ON_HOLD,
    134 	RFB_CLIENT_REFUSE
    135 };
    136 
    137 enum rfbSocketState {
    138 	RFB_SOCKET_INIT,
    139 	RFB_SOCKET_READY,
    140 	RFB_SOCKET_SHUTDOWN
    141 };
    142 
    143 typedef void (*rfbKbdAddEventProcPtr) (rfbBool down, rfbKeySym keySym, struct _rfbClientRec* cl);
    144 typedef void (*rfbKbdReleaseAllKeysProcPtr) (struct _rfbClientRec* cl);
    145 typedef void (*rfbPtrAddEventProcPtr) (int buttonMask, int x, int y, struct _rfbClientRec* cl);
    146 typedef void (*rfbSetXCutTextProcPtr) (char* str,int len, struct _rfbClientRec* cl);
    147 typedef struct rfbCursor* (*rfbGetCursorProcPtr) (struct _rfbClientRec* pScreen);
    148 typedef rfbBool (*rfbSetTranslateFunctionProcPtr)(struct _rfbClientRec* cl);
    149 typedef rfbBool (*rfbPasswordCheckProcPtr)(struct _rfbClientRec* cl,const char* encryptedPassWord,int len);
    150 typedef enum rfbNewClientAction (*rfbNewClientHookPtr)(struct _rfbClientRec* cl);
    151 typedef void (*rfbDisplayHookPtr)(struct _rfbClientRec* cl);
    152 typedef void (*rfbDisplayFinishedHookPtr)(struct _rfbClientRec* cl, int result);
    153 /** support the capability to view the caps/num/scroll states of the X server */
    154 typedef int  (*rfbGetKeyboardLedStateHookPtr)(struct _rfbScreenInfo* screen);
    155 typedef rfbBool (*rfbXvpHookPtr)(struct _rfbClientRec* cl, uint8_t, uint8_t);
    156 /**
    157  * If x==1 and y==1 then set the whole display
    158  * else find the window underneath x and y and set the framebuffer to the dimensions
    159  * of that window
    160  */
    161 typedef void (*rfbSetSingleWindowProcPtr) (struct _rfbClientRec* cl, int x, int y);
    162 /**
    163  * Status determines if the X11 server permits input from the local user
    164  * status==0 or 1
    165  */
    166 typedef void (*rfbSetServerInputProcPtr) (struct _rfbClientRec* cl, int status);
    167 /**
    168  * Permit the server to allow or deny filetransfers.   This is defaulted to deny
    169  * It is called when a client initiates a connection to determine if it is permitted.
    170  */
    171 typedef int  (*rfbFileTransferPermitted) (struct _rfbClientRec* cl);
    172 /** Handle the textchat messages */
    173 typedef void (*rfbSetTextChat) (struct _rfbClientRec* cl, int length, char *string);
    174 
    175 typedef struct {
    176   uint32_t count;
    177   rfbBool is16; /**< is the data format short? */
    178   union {
    179     uint8_t* bytes;
    180     uint16_t* shorts;
    181   } data; /**< there have to be count*3 entries */
    182 } rfbColourMap;
    183 
    184 /**
    185  * Security handling (RFB protocol version 3.7)
    186  */
    187 
    188 typedef struct _rfbSecurity {
    189 	uint8_t type;
    190 	void (*handler)(struct _rfbClientRec* cl);
    191 	struct _rfbSecurity* next;
    192 } rfbSecurityHandler;
    193 
    194 /**
    195  * Protocol extension handling.
    196  */
    197 
    198 typedef struct _rfbProtocolExtension {
    199 	/** returns FALSE if extension should be deactivated for client.
    200 	   if newClient == NULL, it is always deactivated. */
    201 	rfbBool (*newClient)(struct _rfbClientRec* client, void** data);
    202 	/** returns FALSE if extension should be deactivated for client.
    203 	   if init == NULL, it stays activated. */
    204 	rfbBool (*init)(struct _rfbClientRec* client, void* data);
    205 	/** if pseudoEncodings is not NULL, it contains a 0 terminated
    206 	   list of the pseudo encodings handled by this extension. */
    207 	int *pseudoEncodings;
    208 	/** returns TRUE if that pseudo encoding is handled by the extension.
    209 	   encodingNumber==0 means "reset encodings". */
    210 	rfbBool (*enablePseudoEncoding)(struct _rfbClientRec* client,
    211 			void** data, int encodingNumber);
    212 	/** returns TRUE if message was handled */
    213 	rfbBool (*handleMessage)(struct _rfbClientRec* client,
    214 				void* data,
    215 				const rfbClientToServerMsg* message);
    216 	void (*close)(struct _rfbClientRec* client, void* data);
    217 	void (*usage)(void);
    218 	/** processArguments returns the number of handled arguments */
    219 	int (*processArgument)(int argc, char *argv[]);
    220 	struct _rfbProtocolExtension* next;
    221 } rfbProtocolExtension;
    222 
    223 typedef struct _rfbExtensionData {
    224 	rfbProtocolExtension* extension;
    225 	void* data;
    226 	struct _rfbExtensionData* next;
    227 } rfbExtensionData;
    228 
    229 /**
    230  * Per-screen (framebuffer) structure.  There can be as many as you wish,
    231  * each serving different clients. However, you have to call
    232  * rfbProcessEvents for each of these.
    233  */
    234 
    235 typedef struct _rfbScreenInfo
    236 {
    237     /** this structure has children that are scaled versions of this screen */
    238     struct _rfbScreenInfo *scaledScreenNext;
    239     int scaledScreenRefCount;
    240 
    241     int width;
    242     int paddedWidthInBytes;
    243     int height;
    244     int depth;
    245     int bitsPerPixel;
    246     int sizeInBytes;
    247 
    248     rfbPixel blackPixel;
    249     rfbPixel whitePixel;
    250 
    251     /**
    252      * some screen specific data can be put into a struct where screenData
    253      * points to. You need this if you have more than one screen at the
    254      * same time while using the same functions.
    255      */
    256     void* screenData;
    257 
    258     /* additions by libvncserver */
    259 
    260     rfbPixelFormat serverFormat;
    261     rfbColourMap colourMap; /**< set this if rfbServerFormat.trueColour==FALSE */
    262     const char* desktopName;
    263     char thisHost[255];
    264 
    265     rfbBool autoPort;
    266     int port;
    267     SOCKET listenSock;
    268     int maxSock;
    269     int maxFd;
    270 #ifdef WIN32
    271     struct fd_set allFds;
    272 #else
    273     fd_set allFds;
    274 #endif
    275 
    276     enum rfbSocketState socketState;
    277     SOCKET inetdSock;
    278     rfbBool inetdInitDone;
    279 
    280     int udpPort;
    281     SOCKET udpSock;
    282     struct _rfbClientRec* udpClient;
    283     rfbBool udpSockConnected;
    284     struct sockaddr_in udpRemoteAddr;
    285 
    286     int maxClientWait;
    287 
    288     /* http stuff */
    289     rfbBool httpInitDone;
    290     rfbBool httpEnableProxyConnect;
    291     int httpPort;
    292     char* httpDir;
    293     SOCKET httpListenSock;
    294     SOCKET httpSock;
    295 
    296     rfbPasswordCheckProcPtr passwordCheck;
    297     void* authPasswdData;
    298     /** If rfbAuthPasswdData is given a list, this is the first
    299         view only password. */
    300     int authPasswdFirstViewOnly;
    301 
    302     /** send only this many rectangles in one update */
    303     int maxRectsPerUpdate;
    304     /** this is the amount of milliseconds to wait at least before sending
    305      * an update. */
    306     int deferUpdateTime;
    307 #ifdef TODELETE
    308     char* screen;
    309 #endif
    310     rfbBool alwaysShared;
    311     rfbBool neverShared;
    312     rfbBool dontDisconnect;
    313     struct _rfbClientRec* clientHead;
    314     struct _rfbClientRec* pointerClient;  /**< "Mutex" for pointer events */
    315 
    316 
    317     /* cursor */
    318     int cursorX, cursorY,underCursorBufferLen;
    319     char* underCursorBuffer;
    320     rfbBool dontConvertRichCursorToXCursor;
    321     struct rfbCursor* cursor;
    322 
    323     /**
    324      * the frameBuffer has to be supplied by the serving process.
    325      * The buffer will not be freed by
    326      */
    327     char* frameBuffer;
    328     rfbKbdAddEventProcPtr kbdAddEvent;
    329     rfbKbdReleaseAllKeysProcPtr kbdReleaseAllKeys;
    330     rfbPtrAddEventProcPtr ptrAddEvent;
    331     rfbSetXCutTextProcPtr setXCutText;
    332     rfbGetCursorProcPtr getCursorPtr;
    333     rfbSetTranslateFunctionProcPtr setTranslateFunction;
    334     rfbSetSingleWindowProcPtr setSingleWindow;
    335     rfbSetServerInputProcPtr  setServerInput;
    336     rfbFileTransferPermitted  getFileTransferPermission;
    337     rfbSetTextChat            setTextChat;
    338 
    339     /** newClientHook is called just after a new client is created */
    340     rfbNewClientHookPtr newClientHook;
    341     /** displayHook is called just before a frame buffer update */
    342     rfbDisplayHookPtr displayHook;
    343 
    344     /** These hooks are called to pass keyboard state back to the client */
    345     rfbGetKeyboardLedStateHookPtr getKeyboardLedStateHook;
    346 
    347 #ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
    348     MUTEX(cursorMutex);
    349     rfbBool backgroundLoop;
    350 #endif
    351 
    352     /** if TRUE, an ignoring signal handler is installed for SIGPIPE */
    353     rfbBool ignoreSIGPIPE;
    354 
    355     /** if not zero, only a slice of this height is processed every time
    356      * an update should be sent. This should make working on a slow
    357      * link more interactive. */
    358     int progressiveSliceHeight;
    359 
    360     in_addr_t listenInterface;
    361     int deferPtrUpdateTime;
    362 
    363     /** handle as many input events as possible (default off) */
    364     rfbBool handleEventsEagerly;
    365 
    366     /** rfbEncodingServerIdentity */
    367     char *versionString;
    368 
    369     /** What does the server tell the new clients which version it supports */
    370     int protocolMajorVersion;
    371     int protocolMinorVersion;
    372 
    373     /** command line authorization of file transfers */
    374     rfbBool permitFileTransfer;
    375 
    376     /** displayFinishedHook is called just after a frame buffer update */
    377     rfbDisplayFinishedHookPtr displayFinishedHook;
    378     /** xvpHook is called to handle an xvp client message */
    379     rfbXvpHookPtr xvpHook;
    380 #ifdef LIBVNCSERVER_WITH_WEBSOCKETS
    381     char *sslkeyfile;
    382     char *sslcertfile;
    383 #endif
    384     int ipv6port; /**< The port to listen on when using IPv6.  */
    385     char* listen6Interface;
    386     /* We have an additional IPv6 listen socket since there are systems that
    387        don't support dual binding sockets under *any* circumstances, for
    388        instance OpenBSD */
    389     SOCKET listen6Sock;
    390     int http6Port;
    391     SOCKET httpListen6Sock;
    392 } rfbScreenInfo, *rfbScreenInfoPtr;
    393 
    394 
    395 /**
    396  * rfbTranslateFnType is the type of translation functions.
    397  */
    398 
    399 typedef void (*rfbTranslateFnType)(char *table, rfbPixelFormat *in,
    400                                    rfbPixelFormat *out,
    401                                    char *iptr, char *optr,
    402                                    int bytesBetweenInputLines,
    403                                    int width, int height);
    404 
    405 
    406 /* region stuff */
    407 
    408 struct sraRegion;
    409 typedef struct sraRegion* sraRegionPtr;
    410 
    411 /*
    412  * Per-client structure.
    413  */
    414 
    415 typedef void (*ClientGoneHookPtr)(struct _rfbClientRec* cl);
    416 
    417 typedef struct _rfbFileTransferData {
    418   int fd;
    419   int compressionEnabled;
    420   int fileSize;
    421   int numPackets;
    422   int receiving;
    423   int sending;
    424 } rfbFileTransferData;
    425 
    426 
    427 typedef struct _rfbStatList {
    428     uint32_t type;
    429     uint32_t sentCount;
    430     uint32_t bytesSent;
    431     uint32_t bytesSentIfRaw;
    432     uint32_t rcvdCount;
    433     uint32_t bytesRcvd;
    434     uint32_t bytesRcvdIfRaw;
    435     struct _rfbStatList *Next;
    436 } rfbStatList;
    437 
    438 typedef struct _rfbSslCtx rfbSslCtx;
    439 typedef struct _wsCtx wsCtx;
    440 
    441 typedef struct _rfbClientRec {
    442 
    443     /** back pointer to the screen */
    444     rfbScreenInfoPtr screen;
    445 
    446      /** points to a scaled version of the screen buffer in cl->scaledScreenList */
    447      rfbScreenInfoPtr scaledScreen;
    448      /** how did the client tell us it wanted the screen changed?  Ultra style or palm style? */
    449      rfbBool PalmVNC;
    450 
    451 
    452     /** private data. You should put any application client specific data
    453      * into a struct and let clientData point to it. Don't forget to
    454      * free the struct via clientGoneHook!
    455      *
    456      * This is useful if the IO functions have to behave client specific.
    457      */
    458     void* clientData;
    459     ClientGoneHookPtr clientGoneHook;
    460 
    461     SOCKET sock;
    462     char *host;
    463 
    464     /* RFB protocol minor version number */
    465     int protocolMajorVersion;
    466     int protocolMinorVersion;
    467 
    468 #ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
    469     pthread_t client_thread;
    470 #endif
    471 
    472     /* Note that the RFB_INITIALISATION_SHARED state is provided to support
    473        clients that under some circumstances do not send a ClientInit message.
    474        In particular the Mac OS X built-in VNC client (with protocolMinorVersion
    475        == 889) is one of those.  However, it only requires this support under
    476        special circumstances that can only be determined during the initial
    477        authentication.  If the right conditions are met this state will be
    478        set (see the auth.c file) when rfbProcessClientInitMessage is called.
    479 
    480        If the state is RFB_INITIALISATION_SHARED we should not expect to recieve
    481        any ClientInit message, but instead should proceed to the next stage
    482        of initialisation as though an implicit ClientInit message was received
    483        with a shared-flag of true.  (There is currently no corresponding
    484        RFB_INITIALISATION_NOTSHARED state to represent an implicit ClientInit
    485        message with a shared-flag of false because no known existing client
    486        requires such support at this time.)
    487 
    488        Note that software using LibVNCServer to provide a VNC server will only
    489        ever have a chance to see the state field set to
    490        RFB_INITIALISATION_SHARED if the software is multi-threaded and manages
    491        to examine the state field during the extremely brief window after the
    492        'None' authentication type selection has been received from the built-in
    493        OS X VNC client and before the rfbProcessClientInitMessage function is
    494        called -- control cannot return to the caller during this brief window
    495        while the state field is set to RFB_INITIALISATION_SHARED. */
    496 
    497                                 /** Possible client states: */
    498     enum {
    499         RFB_PROTOCOL_VERSION,   /**< establishing protocol version */
    500 	RFB_SECURITY_TYPE,      /**< negotiating security (RFB v.3.7) */
    501         RFB_AUTHENTICATION,     /**< authenticating */
    502         RFB_INITIALISATION,     /**< sending initialisation messages */
    503         RFB_NORMAL,             /**< normal protocol messages */
    504 
    505         /* Ephemeral internal-use states that will never be seen by software
    506          * using LibVNCServer to provide services: */
    507 
    508         RFB_INITIALISATION_SHARED /**< sending initialisation messages with implicit shared-flag already true */
    509     } state;
    510 
    511     rfbBool reverseConnection;
    512     rfbBool onHold;
    513     rfbBool readyForSetColourMapEntries;
    514     rfbBool useCopyRect;
    515     int preferredEncoding;
    516     int correMaxWidth, correMaxHeight;
    517 
    518     rfbBool viewOnly;
    519 
    520     /* The following member is only used during VNC authentication */
    521     uint8_t authChallenge[CHALLENGESIZE];
    522 
    523     /* The following members represent the update needed to get the client's
    524        framebuffer from its present state to the current state of our
    525        framebuffer.
    526 
    527        If the client does not accept CopyRect encoding then the update is
    528        simply represented as the region of the screen which has been modified
    529        (modifiedRegion).
    530 
    531        If the client does accept CopyRect encoding, then the update consists of
    532        two parts.  First we have a single copy from one region of the screen to
    533        another (the destination of the copy is copyRegion), and second we have
    534        the region of the screen which has been modified in some other way
    535        (modifiedRegion).
    536 
    537        Although the copy is of a single region, this region may have many
    538        rectangles.  When sending an update, the copyRegion is always sent
    539        before the modifiedRegion.  This is because the modifiedRegion may
    540        overlap parts of the screen which are in the source of the copy.
    541 
    542        In fact during normal processing, the modifiedRegion may even overlap
    543        the destination copyRegion.  Just before an update is sent we remove
    544        from the copyRegion anything in the modifiedRegion. */
    545 
    546     sraRegionPtr copyRegion;	/**< the destination region of the copy */
    547     int copyDX, copyDY;		/**< the translation by which the copy happens */
    548 
    549     sraRegionPtr modifiedRegion;
    550 
    551     /** As part of the FramebufferUpdateRequest, a client can express interest
    552        in a subrectangle of the whole framebuffer.  This is stored in the
    553        requestedRegion member.  In the normal case this is the whole
    554        framebuffer if the client is ready, empty if it's not. */
    555 
    556     sraRegionPtr requestedRegion;
    557 
    558     /** The following member represents the state of the "deferred update" timer
    559        - when the framebuffer is modified and the client is ready, in most
    560        cases it is more efficient to defer sending the update by a few
    561        milliseconds so that several changes to the framebuffer can be combined
    562        into a single update. */
    563 
    564       struct timeval startDeferring;
    565       struct timeval startPtrDeferring;
    566       int lastPtrX;
    567       int lastPtrY;
    568       int lastPtrButtons;
    569 
    570     /** translateFn points to the translation function which is used to copy
    571        and translate a rectangle from the framebuffer to an output buffer. */
    572 
    573     rfbTranslateFnType translateFn;
    574     char *translateLookupTable;
    575     rfbPixelFormat format;
    576 
    577     /**
    578      * UPDATE_BUF_SIZE must be big enough to send at least one whole line of the
    579      * framebuffer.  So for a max screen width of say 2K with 32-bit pixels this
    580      * means 8K minimum.
    581      */
    582 
    583 #define UPDATE_BUF_SIZE 30000
    584 
    585     char updateBuf[UPDATE_BUF_SIZE];
    586     int ublen;
    587 
    588     /* statistics */
    589     struct _rfbStatList *statEncList;
    590     struct _rfbStatList *statMsgList;
    591     int rawBytesEquivalent;
    592     int bytesSent;
    593 
    594 #ifdef LIBVNCSERVER_HAVE_LIBZ
    595     /* zlib encoding -- necessary compression state info per client */
    596 
    597     struct z_stream_s compStream;
    598     rfbBool compStreamInited;
    599     uint32_t zlibCompressLevel;
    600 #endif
    601 #if defined(LIBVNCSERVER_HAVE_LIBZ) || defined(LIBVNCSERVER_HAVE_LIBPNG)
    602     /** the quality level is also used by ZYWRLE and TightPng */
    603     int tightQualityLevel;
    604 
    605 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
    606     /* tight encoding -- preserve zlib streams' state for each client */
    607     z_stream zsStruct[4];
    608     rfbBool zsActive[4];
    609     int zsLevel[4];
    610     int tightCompressLevel;
    611 #endif
    612 #endif
    613 
    614     /* Ultra Encoding support */
    615     rfbBool compStreamInitedLZO;
    616     char *lzoWrkMem;
    617 
    618     rfbFileTransferData fileTransfer;
    619 
    620     int     lastKeyboardLedState;     /**< keep track of last value so we can send *change* events */
    621     rfbBool enableSupportedMessages;  /**< client supports SupportedMessages encoding */
    622     rfbBool enableSupportedEncodings; /**< client supports SupportedEncodings encoding */
    623     rfbBool enableServerIdentity;     /**< client supports ServerIdentity encoding */
    624     rfbBool enableKeyboardLedState;   /**< client supports KeyboardState encoding */
    625     rfbBool enableLastRectEncoding;   /**< client supports LastRect encoding */
    626     rfbBool enableCursorShapeUpdates; /**< client supports cursor shape updates */
    627     rfbBool enableCursorPosUpdates;   /**< client supports cursor position updates */
    628     rfbBool useRichCursorEncoding;    /**< rfbEncodingRichCursor is preferred */
    629     rfbBool cursorWasChanged;         /**< cursor shape update should be sent */
    630     rfbBool cursorWasMoved;           /**< cursor position update should be sent */
    631     int cursorX,cursorY;	      /**< the coordinates of the cursor,
    632 					 if enableCursorShapeUpdates = FALSE */
    633 
    634     rfbBool useNewFBSize;             /**< client supports NewFBSize encoding */
    635     rfbBool newFBSizePending;         /**< framebuffer size was changed */
    636 
    637     struct _rfbClientRec *prev;
    638     struct _rfbClientRec *next;
    639 
    640 #ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
    641     /** whenever a client is referenced, the refCount has to be incremented
    642        and afterwards decremented, so that the client is not cleaned up
    643        while being referenced.
    644        Use the functions rfbIncrClientRef(cl) and rfbDecrClientRef(cl);
    645     */
    646     int refCount;
    647     MUTEX(refCountMutex);
    648     COND(deleteCond);
    649 
    650     MUTEX(outputMutex);
    651     MUTEX(updateMutex);
    652     COND(updateCond);
    653 #endif
    654 
    655 #ifdef LIBVNCSERVER_HAVE_LIBZ
    656     void* zrleData;
    657     int zywrleLevel;
    658     int zywrleBuf[rfbZRLETileWidth * rfbZRLETileHeight];
    659 #endif
    660 
    661     /** if progressive updating is on, this variable holds the current
    662      * y coordinate of the progressive slice. */
    663     int progressiveSliceY;
    664 
    665     rfbExtensionData* extensions;
    666 
    667     /** for threaded zrle */
    668     char *zrleBeforeBuf;
    669     void *paletteHelper;
    670 
    671     /** for thread safety for rfbSendFBUpdate() */
    672 #ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
    673 #define LIBVNCSERVER_SEND_MUTEX
    674     MUTEX(sendMutex);
    675 #endif
    676 
    677   /* buffers to hold pixel data before and after encoding.
    678      per-client for thread safety */
    679   char *beforeEncBuf;
    680   int beforeEncBufSize;
    681   char *afterEncBuf;
    682   int afterEncBufSize;
    683   int afterEncBufLen;
    684 #if defined(LIBVNCSERVER_HAVE_LIBZ) || defined(LIBVNCSERVER_HAVE_LIBPNG)
    685     uint32_t tightEncoding;  /* rfbEncodingTight or rfbEncodingTightPng */
    686 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
    687     /* TurboVNC Encoding support (extends TightVNC) */
    688     int turboSubsampLevel;
    689     int turboQualityLevel;  /* 1-100 scale */
    690 #endif
    691 #endif
    692 
    693 #ifdef LIBVNCSERVER_WITH_WEBSOCKETS
    694     rfbSslCtx *sslctx;
    695     wsCtx     *wsctx;
    696     char *wspath;                          /* Requests path component */
    697 #endif
    698 } rfbClientRec, *rfbClientPtr;
    699 
    700 /**
    701  * This macro is used to test whether there is a framebuffer update needing to
    702  * be sent to the client.
    703  */
    704 
    705 #define FB_UPDATE_PENDING(cl)                                              \
    706      (((cl)->enableCursorShapeUpdates && (cl)->cursorWasChanged) ||        \
    707      (((cl)->enableCursorShapeUpdates == FALSE &&                          \
    708        ((cl)->cursorX != (cl)->screen->cursorX ||                          \
    709 	(cl)->cursorY != (cl)->screen->cursorY))) ||                       \
    710      ((cl)->useNewFBSize && (cl)->newFBSizePending) ||                     \
    711      ((cl)->enableCursorPosUpdates && (cl)->cursorWasMoved) ||             \
    712      !sraRgnEmpty((cl)->copyRegion) || !sraRgnEmpty((cl)->modifiedRegion))
    713 
    714 /*
    715  * Macros for endian swapping.
    716  */
    717 
    718 #define Swap16(s) ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff))
    719 
    720 #define Swap24(l) ((((l) & 0xff) << 16) | (((l) >> 16) & 0xff) | \
    721                    (((l) & 0x00ff00)))
    722 
    723 #define Swap32(l) (((l) >> 24) | \
    724                    (((l) & 0x00ff0000) >> 8)  | \
    725                    (((l) & 0x0000ff00) << 8)  | \
    726                    ((l) << 24))
    727 
    728 
    729 extern char rfbEndianTest;
    730 
    731 #define Swap16IfLE(s) (rfbEndianTest ? Swap16(s) : (s))
    732 #define Swap24IfLE(l) (rfbEndianTest ? Swap24(l) : (l))
    733 #define Swap32IfLE(l) (rfbEndianTest ? Swap32(l) : (l))
    734 
    735 /* UltraVNC uses some windows structures unmodified, so the viewer expects LittleEndian Data */
    736 #define Swap16IfBE(s) (rfbEndianTest ? (s) : Swap16(s))
    737 #define Swap24IfBE(l) (rfbEndianTest ? (l) : Swap24(l))
    738 #define Swap32IfBE(l) (rfbEndianTest ? (l) : Swap32(l))
    739 
    740 /* sockets.c */
    741 
    742 extern int rfbMaxClientWait;
    743 
    744 extern void rfbInitSockets(rfbScreenInfoPtr rfbScreen);
    745 extern void rfbShutdownSockets(rfbScreenInfoPtr rfbScreen);
    746 extern void rfbDisconnectUDPSock(rfbScreenInfoPtr rfbScreen);
    747 extern void rfbCloseClient(rfbClientPtr cl);
    748 extern int rfbReadExact(rfbClientPtr cl, char *buf, int len);
    749 extern int rfbReadExactTimeout(rfbClientPtr cl, char *buf, int len,int timeout);
    750 extern int rfbPeekExactTimeout(rfbClientPtr cl, char *buf, int len,int timeout);
    751 extern int rfbWriteExact(rfbClientPtr cl, const char *buf, int len);
    752 extern int rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec);
    753 extern int rfbConnect(rfbScreenInfoPtr rfbScreen, char* host, int port);
    754 extern int rfbConnectToTcpAddr(char* host, int port);
    755 extern int rfbListenOnTCPPort(int port, in_addr_t iface);
    756 extern int rfbListenOnTCP6Port(int port, const char* iface);
    757 extern int rfbListenOnUDPPort(int port, in_addr_t iface);
    758 extern int rfbStringToAddr(char* string,in_addr_t* addr);
    759 extern rfbBool rfbSetNonBlocking(int sock);
    760 
    761 #ifdef LIBVNCSERVER_WITH_WEBSOCKETS
    762 /* websockets.c */
    763 
    764 extern rfbBool webSocketsCheck(rfbClientPtr cl);
    765 extern rfbBool webSocketCheckDisconnect(rfbClientPtr cl);
    766 extern int webSocketsEncode(rfbClientPtr cl, const char *src, int len, char **dst);
    767 extern int webSocketsDecode(rfbClientPtr cl, char *dst, int len);
    768 #endif
    769 
    770 /* rfbserver.c */
    771 
    772 /* Routines to iterate over the client list in a thread-safe way.
    773    Only a single iterator can be in use at a time process-wide. */
    774 typedef struct rfbClientIterator *rfbClientIteratorPtr;
    775 
    776 extern void rfbClientListInit(rfbScreenInfoPtr rfbScreen);
    777 extern rfbClientIteratorPtr rfbGetClientIterator(rfbScreenInfoPtr rfbScreen);
    778 extern rfbClientPtr rfbClientIteratorNext(rfbClientIteratorPtr iterator);
    779 extern void rfbReleaseClientIterator(rfbClientIteratorPtr iterator);
    780 extern void rfbIncrClientRef(rfbClientPtr cl);
    781 extern void rfbDecrClientRef(rfbClientPtr cl);
    782 
    783 extern void rfbNewClientConnection(rfbScreenInfoPtr rfbScreen,int sock);
    784 extern rfbClientPtr rfbNewClient(rfbScreenInfoPtr rfbScreen,int sock);
    785 extern rfbClientPtr rfbNewUDPClient(rfbScreenInfoPtr rfbScreen);
    786 extern rfbClientPtr rfbReverseConnection(rfbScreenInfoPtr rfbScreen,char *host, int port);
    787 extern void rfbClientConnectionGone(rfbClientPtr cl);
    788 extern void rfbProcessClientMessage(rfbClientPtr cl);
    789 extern void rfbClientConnFailed(rfbClientPtr cl, const char *reason);
    790 extern void rfbNewUDPConnection(rfbScreenInfoPtr rfbScreen,int sock);
    791 extern void rfbProcessUDPInput(rfbScreenInfoPtr rfbScreen);
    792 extern rfbBool rfbSendFramebufferUpdate(rfbClientPtr cl, sraRegionPtr updateRegion);
    793 extern rfbBool rfbSendRectEncodingRaw(rfbClientPtr cl, int x,int y,int w,int h);
    794 extern rfbBool rfbSendUpdateBuf(rfbClientPtr cl);
    795 extern void rfbSendServerCutText(rfbScreenInfoPtr rfbScreen,char *str, int len);
    796 extern rfbBool rfbSendCopyRegion(rfbClientPtr cl,sraRegionPtr reg,int dx,int dy);
    797 extern rfbBool rfbSendLastRectMarker(rfbClientPtr cl);
    798 extern rfbBool rfbSendNewFBSize(rfbClientPtr cl, int w, int h);
    799 extern rfbBool rfbSendSetColourMapEntries(rfbClientPtr cl, int firstColour, int nColours);
    800 extern void rfbSendBell(rfbScreenInfoPtr rfbScreen);
    801 
    802 extern char *rfbProcessFileTransferReadBuffer(rfbClientPtr cl, uint32_t length);
    803 extern rfbBool rfbSendFileTransferChunk(rfbClientPtr cl);
    804 extern rfbBool rfbSendDirContent(rfbClientPtr cl, int length, char *buffer);
    805 extern rfbBool rfbSendFileTransferMessage(rfbClientPtr cl, uint8_t contentType, uint8_t contentParam, uint32_t size, uint32_t length, const char *buffer);
    806 extern char *rfbProcessFileTransferReadBuffer(rfbClientPtr cl, uint32_t length);
    807 extern rfbBool rfbProcessFileTransfer(rfbClientPtr cl, uint8_t contentType, uint8_t contentParam, uint32_t size, uint32_t length);
    808 
    809 void rfbGotXCutText(rfbScreenInfoPtr rfbScreen, char *str, int len);
    810 
    811 /* translate.c */
    812 
    813 extern rfbBool rfbEconomicTranslate;
    814 
    815 extern void rfbTranslateNone(char *table, rfbPixelFormat *in,
    816                              rfbPixelFormat *out,
    817                              char *iptr, char *optr,
    818                              int bytesBetweenInputLines,
    819                              int width, int height);
    820 extern rfbBool rfbSetTranslateFunction(rfbClientPtr cl);
    821 extern rfbBool rfbSetClientColourMap(rfbClientPtr cl, int firstColour, int nColours);
    822 extern void rfbSetClientColourMaps(rfbScreenInfoPtr rfbScreen, int firstColour, int nColours);
    823 
    824 /* httpd.c */
    825 
    826 extern void rfbHttpInitSockets(rfbScreenInfoPtr rfbScreen);
    827 extern void rfbHttpShutdownSockets(rfbScreenInfoPtr rfbScreen);
    828 extern void rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen);
    829 
    830 
    831 
    832 /* auth.c */
    833 
    834 extern void rfbAuthNewClient(rfbClientPtr cl);
    835 extern void rfbProcessClientSecurityType(rfbClientPtr cl);
    836 extern void rfbAuthProcessClientMessage(rfbClientPtr cl);
    837 extern void rfbRegisterSecurityHandler(rfbSecurityHandler* handler);
    838 extern void rfbUnregisterSecurityHandler(rfbSecurityHandler* handler);
    839 
    840 /* rre.c */
    841 
    842 extern rfbBool rfbSendRectEncodingRRE(rfbClientPtr cl, int x,int y,int w,int h);
    843 
    844 
    845 /* corre.c */
    846 
    847 extern rfbBool rfbSendRectEncodingCoRRE(rfbClientPtr cl, int x,int y,int w,int h);
    848 
    849 
    850 /* hextile.c */
    851 
    852 extern rfbBool rfbSendRectEncodingHextile(rfbClientPtr cl, int x, int y, int w,
    853                                        int h);
    854 
    855 /* ultra.c */
    856 
    857 /* Set maximum ultra rectangle size in pixels.  Always allow at least
    858  * two scan lines.
    859  */
    860 #define ULTRA_MAX_RECT_SIZE (128*256)
    861 #define ULTRA_MAX_SIZE(min) ((( min * 2 ) > ULTRA_MAX_RECT_SIZE ) ? \
    862                             ( min * 2 ) : ULTRA_MAX_RECT_SIZE )
    863 
    864 extern rfbBool rfbSendRectEncodingUltra(rfbClientPtr cl, int x,int y,int w,int h);
    865 
    866 
    867 #ifdef LIBVNCSERVER_HAVE_LIBZ
    868 /* zlib.c */
    869 
    870 /** Minimum zlib rectangle size in bytes.  Anything smaller will
    871  * not compress well due to overhead.
    872  */
    873 #define VNC_ENCODE_ZLIB_MIN_COMP_SIZE (17)
    874 
    875 /* Set maximum zlib rectangle size in pixels.  Always allow at least
    876  * two scan lines.
    877  */
    878 #define ZLIB_MAX_RECT_SIZE (128*256)
    879 #define ZLIB_MAX_SIZE(min) ((( min * 2 ) > ZLIB_MAX_RECT_SIZE ) ? \
    880 			    ( min * 2 ) : ZLIB_MAX_RECT_SIZE )
    881 
    882 extern rfbBool rfbSendRectEncodingZlib(rfbClientPtr cl, int x, int y, int w,
    883 				    int h);
    884 
    885 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
    886 /* tight.c */
    887 
    888 #define TIGHT_DEFAULT_COMPRESSION  6
    889 #define TURBO_DEFAULT_SUBSAMP 0
    890 
    891 extern rfbBool rfbTightDisableGradient;
    892 
    893 extern int rfbNumCodedRectsTight(rfbClientPtr cl, int x,int y,int w,int h);
    894 
    895 extern rfbBool rfbSendRectEncodingTight(rfbClientPtr cl, int x,int y,int w,int h);
    896 
    897 #if defined(LIBVNCSERVER_HAVE_LIBPNG)
    898 extern rfbBool rfbSendRectEncodingTightPng(rfbClientPtr cl, int x,int y,int w,int h);
    899 #endif
    900 
    901 #endif
    902 #endif
    903 
    904 
    905 /* cursor.c */
    906 
    907 typedef struct rfbCursor {
    908     /** set this to true if LibVNCServer has to free this cursor */
    909     rfbBool cleanup, cleanupSource, cleanupMask, cleanupRichSource;
    910     unsigned char *source;			/**< points to bits */
    911     unsigned char *mask;			/**< points to bits */
    912     unsigned short width, height, xhot, yhot;	/**< metrics */
    913     unsigned short foreRed, foreGreen, foreBlue; /**< device-independent colour */
    914     unsigned short backRed, backGreen, backBlue; /**< device-independent colour */
    915     unsigned char *richSource; /**< source bytes for a rich cursor */
    916     unsigned char *alphaSource; /**< source for alpha blending info */
    917     rfbBool alphaPreMultiplied; /**< if richSource already has alpha applied */
    918 } rfbCursor, *rfbCursorPtr;
    919 extern unsigned char rfbReverseByte[0x100];
    920 
    921 extern rfbBool rfbSendCursorShape(rfbClientPtr cl/*, rfbScreenInfoPtr pScreen*/);
    922 extern rfbBool rfbSendCursorPos(rfbClientPtr cl);
    923 extern void rfbConvertLSBCursorBitmapOrMask(int width,int height,unsigned char* bitmap);
    924 extern rfbCursorPtr rfbMakeXCursor(int width,int height,char* cursorString,char* maskString);
    925 extern char* rfbMakeMaskForXCursor(int width,int height,char* cursorString);
    926 extern char* rfbMakeMaskFromAlphaSource(int width,int height,unsigned char* alphaSource);
    927 extern void rfbMakeXCursorFromRichCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr cursor);
    928 extern void rfbMakeRichCursorFromXCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr cursor);
    929 extern void rfbFreeCursor(rfbCursorPtr cursor);
    930 extern void rfbSetCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr c);
    931 
    932 /** cursor handling for the pointer */
    933 extern void rfbDefaultPtrAddEvent(int buttonMask,int x,int y,rfbClientPtr cl);
    934 
    935 /* zrle.c */
    936 #ifdef LIBVNCSERVER_HAVE_LIBZ
    937 extern rfbBool rfbSendRectEncodingZRLE(rfbClientPtr cl, int x, int y, int w,int h);
    938 #endif
    939 
    940 /* stats.c */
    941 
    942 extern void rfbResetStats(rfbClientPtr cl);
    943 extern void rfbPrintStats(rfbClientPtr cl);
    944 
    945 /* font.c */
    946 
    947 typedef struct rfbFontData {
    948   unsigned char* data;
    949   /**
    950     metaData is a 256*5 array:
    951     for each character
    952     (offset,width,height,x,y)
    953   */
    954   int* metaData;
    955 } rfbFontData,* rfbFontDataPtr;
    956 
    957 int rfbDrawChar(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,unsigned char c,rfbPixel colour);
    958 void rfbDrawString(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,const char* string,rfbPixel colour);
    959 /** if colour==backColour, background is transparent */
    960 int rfbDrawCharWithClip(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,unsigned char c,int x1,int y1,int x2,int y2,rfbPixel colour,rfbPixel backColour);
    961 void rfbDrawStringWithClip(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,const char* string,int x1,int y1,int x2,int y2,rfbPixel colour,rfbPixel backColour);
    962 int rfbWidthOfString(rfbFontDataPtr font,const char* string);
    963 int rfbWidthOfChar(rfbFontDataPtr font,unsigned char c);
    964 void rfbFontBBox(rfbFontDataPtr font,unsigned char c,int* x1,int* y1,int* x2,int* y2);
    965 /** this returns the smallest box enclosing any character of font. */
    966 void rfbWholeFontBBox(rfbFontDataPtr font,int *x1, int *y1, int *x2, int *y2);
    967 
    968 /** dynamically load a linux console font (4096 bytes, 256 glyphs a 8x16 */
    969 rfbFontDataPtr rfbLoadConsoleFont(char *filename);
    970 /** free a dynamically loaded font */
    971 void rfbFreeFont(rfbFontDataPtr font);
    972 
    973 /* draw.c */
    974 
    975 void rfbFillRect(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2,rfbPixel col);
    976 void rfbDrawPixel(rfbScreenInfoPtr s,int x,int y,rfbPixel col);
    977 void rfbDrawLine(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2,rfbPixel col);
    978 
    979 /* selbox.c */
    980 
    981 /** this opens a modal select box. list is an array of strings, the end marked
    982    with a NULL.
    983    It returns the index in the list or -1 if cancelled or something else
    984    wasn't kosher. */
    985 typedef void (*SelectionChangedHookPtr)(int _index);
    986 extern int rfbSelectBox(rfbScreenInfoPtr rfbScreen,
    987 			rfbFontDataPtr font, char** list,
    988 			int x1, int y1, int x2, int y2,
    989 			rfbPixel foreColour, rfbPixel backColour,
    990 			int border,SelectionChangedHookPtr selChangedHook);
    991 
    992 /* cargs.c */
    993 
    994 extern void rfbUsage(void);
    995 extern void rfbPurgeArguments(int* argc,int* position,int count,char *argv[]);
    996 extern rfbBool rfbProcessArguments(rfbScreenInfoPtr rfbScreen,int* argc, char *argv[]);
    997 extern rfbBool rfbProcessSizeArguments(int* width,int* height,int* bpp,int* argc, char *argv[]);
    998 
    999 /* main.c */
   1000 
   1001 extern void rfbLogEnable(int enabled);
   1002 typedef void (*rfbLogProc)(const char *format, ...);
   1003 extern rfbLogProc rfbLog, rfbErr;
   1004 extern void rfbLogPerror(const char *str);
   1005 
   1006 void rfbScheduleCopyRect(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2,int dx,int dy);
   1007 void rfbScheduleCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,int dy);
   1008 
   1009 void rfbDoCopyRect(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2,int dx,int dy);
   1010 void rfbDoCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,int dy);
   1011 
   1012 void rfbMarkRectAsModified(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2);
   1013 void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,sraRegionPtr modRegion);
   1014 void rfbDoNothingWithClient(rfbClientPtr cl);
   1015 enum rfbNewClientAction defaultNewClientHook(rfbClientPtr cl);
   1016 void rfbRegisterProtocolExtension(rfbProtocolExtension* extension);
   1017 void rfbUnregisterProtocolExtension(rfbProtocolExtension* extension);
   1018 struct _rfbProtocolExtension* rfbGetExtensionIterator();
   1019 void rfbReleaseExtensionIterator();
   1020 rfbBool rfbEnableExtension(rfbClientPtr cl, rfbProtocolExtension* extension,
   1021 	void* data);
   1022 rfbBool rfbDisableExtension(rfbClientPtr cl, rfbProtocolExtension* extension);
   1023 void* rfbGetExtensionClientData(rfbClientPtr cl, rfbProtocolExtension* extension);
   1024 
   1025 /** to check against plain passwords */
   1026 rfbBool rfbCheckPasswordByList(rfbClientPtr cl,const char* response,int len);
   1027 
   1028 /* functions to make a vnc server */
   1029 extern rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
   1030  int width,int height,int bitsPerSample,int samplesPerPixel,
   1031  int bytesPerPixel);
   1032 extern void rfbInitServer(rfbScreenInfoPtr rfbScreen);
   1033 extern void rfbShutdownServer(rfbScreenInfoPtr rfbScreen,rfbBool disconnectClients);
   1034 extern void rfbNewFramebuffer(rfbScreenInfoPtr rfbScreen,char *framebuffer,
   1035  int width,int height, int bitsPerSample,int samplesPerPixel,
   1036  int bytesPerPixel);
   1037 
   1038 extern void rfbScreenCleanup(rfbScreenInfoPtr screenInfo);
   1039 extern void rfbSetServerVersionIdentity(rfbScreenInfoPtr screen, char *fmt, ...);
   1040 
   1041 /* functions to accept/refuse a client that has been put on hold
   1042    by a NewClientHookPtr function. Must not be called in other
   1043    situations. */
   1044 extern void rfbStartOnHoldClient(rfbClientPtr cl);
   1045 extern void rfbRefuseOnHoldClient(rfbClientPtr cl);
   1046 
   1047 /* call one of these two functions to service the vnc clients.
   1048  usec are the microseconds the select on the fds waits.
   1049  if you are using the event loop, set this to some value > 0, so the
   1050  server doesn't get a high load just by listening.
   1051  rfbProcessEvents() returns TRUE if an update was pending. */
   1052 
   1053 extern void rfbRunEventLoop(rfbScreenInfoPtr screenInfo, long usec, rfbBool runInBackground);
   1054 extern rfbBool rfbProcessEvents(rfbScreenInfoPtr screenInfo,long usec);
   1055 extern rfbBool rfbIsActive(rfbScreenInfoPtr screenInfo);
   1056 
   1057 /* TightVNC file transfer extension */
   1058 void rfbRegisterTightVNCFileTransferExtension();
   1059 void rfbUnregisterTightVNCFileTransferExtension();
   1060 
   1061 /* Statistics */
   1062 extern char *messageNameServer2Client(uint32_t type, char *buf, int len);
   1063 extern char *messageNameClient2Server(uint32_t type, char *buf, int len);
   1064 extern char *encodingName(uint32_t enc, char *buf, int len);
   1065 
   1066 extern rfbStatList *rfbStatLookupEncoding(rfbClientPtr cl, uint32_t type);
   1067 extern rfbStatList *rfbStatLookupMessage(rfbClientPtr cl, uint32_t type);
   1068 
   1069 /* Each call to rfbStatRecord* adds one to the rect count for that type */
   1070 extern void rfbStatRecordEncodingSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
   1071 extern void rfbStatRecordEncodingSentAdd(rfbClientPtr cl, uint32_t type, int byteCount); /* Specifically for tight encoding */
   1072 extern void rfbStatRecordEncodingRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
   1073 extern void rfbStatRecordMessageSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
   1074 extern void rfbStatRecordMessageRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
   1075 extern void rfbResetStats(rfbClientPtr cl);
   1076 extern void rfbPrintStats(rfbClientPtr cl);
   1077 
   1078 extern int rfbStatGetSentBytes(rfbClientPtr cl);
   1079 extern int rfbStatGetSentBytesIfRaw(rfbClientPtr cl);
   1080 extern int rfbStatGetRcvdBytes(rfbClientPtr cl);
   1081 extern int rfbStatGetRcvdBytesIfRaw(rfbClientPtr cl);
   1082 extern int rfbStatGetMessageCountSent(rfbClientPtr cl, uint32_t type);
   1083 extern int rfbStatGetMessageCountRcvd(rfbClientPtr cl, uint32_t type);
   1084 extern int rfbStatGetEncodingCountSent(rfbClientPtr cl, uint32_t type);
   1085 extern int rfbStatGetEncodingCountRcvd(rfbClientPtr cl, uint32_t type);
   1086 
   1087 /** Set which version you want to advertise 3.3, 3.6, 3.7 and 3.8 are currently supported*/
   1088 extern void rfbSetProtocolVersion(rfbScreenInfoPtr rfbScreen, int major_, int minor_);
   1089 
   1090 /** send a TextChat message to a client */
   1091 extern rfbBool rfbSendTextChatMessage(rfbClientPtr cl, uint32_t length, char *buffer);
   1092 
   1093 
   1094 /*
   1095  * Additions for Qt event loop integration
   1096  * Original idea taken from vino.
   1097  */
   1098 rfbBool rfbProcessNewConnection(rfbScreenInfoPtr rfbScreen);
   1099 rfbBool rfbUpdateClient(rfbClientPtr cl);
   1100 
   1101 
   1102 #if(defined __cplusplus)
   1103 }
   1104 #endif
   1105 
   1106 /**
   1107  * @}
   1108  */
   1109 
   1110 
   1111 /**
   1112  @page libvncserver_doc LibVNCServer Documentation
   1113  @section create_server Creating a server instance
   1114  To make a server, you just have to initialise a server structure using the
   1115  function rfbGetScreen(), like
   1116  @code
   1117    rfbScreenInfoPtr screen =
   1118      rfbGetScreen(argc,argv,screenwidth,screenheight,8,3,bpp);
   1119  @endcode
   1120  where byte per pixel should be 1, 2 or 4. If performance doesn't matter,
   1121  you may try bpp=3 (internally one cannot use native data types in this
   1122  case; if you want to use this, look at pnmshow24.c).
   1123 
   1124  You then can set hooks and io functions (see @ref making_it_interactive) or other
   1125  options (see @ref server_options).
   1126 
   1127  And you allocate the frame buffer like this:
   1128  @code
   1129      screen->frameBuffer = (char*)malloc(screenwidth*screenheight*bpp);
   1130  @endcode
   1131  After that, you initialize the server, like
   1132  @code
   1133    rfbInitServer(screen);
   1134  @endcode
   1135  You can use a blocking event loop, a background (pthread based) event loop,
   1136  or implement your own using the rfbProcessEvents() function.
   1137 
   1138  @subsection server_options Optional Server Features
   1139 
   1140  These options have to be set between rfbGetScreen() and rfbInitServer().
   1141 
   1142  If you already have a socket to talk to, just set rfbScreenInfo::inetdSock
   1143  (originally this is for inetd handling, but why not use it for your purpose?).
   1144 
   1145  To also start an HTTP server (running on port 5800+display_number), you have
   1146  to set rfbScreenInfo::httpDir to a directory containing vncviewer.jar and
   1147  index.vnc (like the included "webclients" directory).
   1148 
   1149  @section making_it_interactive Making it interactive
   1150 
   1151  Whenever you draw something, you have to call
   1152  @code
   1153   rfbMarkRectAsModified(screen,x1,y1,x2,y2).
   1154  @endcode
   1155  This tells LibVNCServer to send updates to all connected clients.
   1156 
   1157  There exist the following IO functions as members of rfbScreen:
   1158  rfbScreenInfo::kbdAddEvent(), rfbScreenInfo::kbdReleaseAllKeys(), rfbScreenInfo::ptrAddEvent() and rfbScreenInfo::setXCutText()
   1159 
   1160  rfbScreenInfo::kbdAddEvent()
   1161    is called when a key is pressed.
   1162  rfbScreenInfo::kbdReleaseAllKeys()
   1163    is not called at all (maybe in the future).
   1164  rfbScreenInfo::ptrAddEvent()
   1165    is called when the mouse moves or a button is pressed.
   1166    WARNING: if you want to have proper cursor handling, call
   1167 	rfbDefaultPtrAddEvent()
   1168    in your own function. This sets the coordinates of the cursor.
   1169  rfbScreenInfo::setXCutText()
   1170    is called when the selection changes.
   1171 
   1172  There are only two hooks:
   1173  rfbScreenInfo::newClientHook()
   1174    is called when a new client has connected.
   1175  rfbScreenInfo::displayHook()
   1176    is called just before a frame buffer update is sent.
   1177 
   1178  You can also override the following methods:
   1179  rfbScreenInfo::getCursorPtr()
   1180    This could be used to make an animated cursor (if you really want ...)
   1181  rfbScreenInfo::setTranslateFunction()
   1182    If you insist on colour maps or something more obscure, you have to
   1183    implement this. Default is a trueColour mapping.
   1184 
   1185  @section cursor_handling Cursor handling
   1186 
   1187  The screen holds a pointer
   1188   rfbScreenInfo::cursor
   1189  to the current cursor. Whenever you set it, remember that any dynamically
   1190  created cursor (like return value from rfbMakeXCursor()) is not free'd!
   1191 
   1192  The rfbCursor structure consists mainly of a mask and a source. The rfbCursor::mask
   1193  describes, which pixels are drawn for the cursor (a cursor needn't be
   1194  rectangular). The rfbCursor::source describes, which colour those pixels should have.
   1195 
   1196  The standard is an XCursor: a cursor with a foreground and a background
   1197  colour (stored in backRed,backGreen,backBlue and the same for foreground
   1198  in a range from 0-0xffff). Therefore, the arrays "mask" and "source"
   1199  contain pixels as single bits stored in bytes in MSB order. The rows are
   1200  padded, such that each row begins with a new byte (i.e. a 10x4
   1201  cursor's mask has 2x4 bytes, because 2 bytes are needed to hold 10 bits).
   1202 
   1203  It is however very easy to make a cursor like this:
   1204  @code
   1205  char* cur="    "
   1206            " xx "
   1207 	   " x  "
   1208 	   "    ";
   1209  char* mask="xxxx"
   1210             "xxxx"
   1211             "xxxx"
   1212             "xxx ";
   1213  rfbCursorPtr c=rfbMakeXCursor(4,4,cur,mask);
   1214  @endcode
   1215  You can even set rfbCursor::mask to NULL in this call and LibVNCServer will calculate
   1216  a mask for you (dynamically, so you have to free it yourself).
   1217 
   1218  There is also an array named rfbCursor::richSource for colourful cursors. They have
   1219  the same format as the frameBuffer (i.e. if the server is 32 bit,
   1220  a 10x4 cursor has 4x10x4 bytes).
   1221 
   1222  @section screen_client_difference What is the difference between rfbScreenInfoPtr and rfbClientPtr?
   1223 
   1224  The rfbScreenInfoPtr is a pointer to a rfbScreenInfo structure, which
   1225  holds information about the server, like pixel format, io functions,
   1226  frame buffer etc. The rfbClientPtr is a pointer to an rfbClientRec structure, which holds
   1227  information about a client, like pixel format, socket of the
   1228  connection, etc. A server can have several clients, but needn't have any. So, if you
   1229  have a server and three clients are connected, you have one instance
   1230  of a rfbScreenInfo and three instances of rfbClientRec's.
   1231 
   1232  The rfbClientRec structure holds a member rfbClientRec::screen which points to the server.
   1233  So, to access the server from the client structure, you use client->screen.
   1234 
   1235  To access all clients from a server be sure to use the provided iterator
   1236   rfbGetClientIterator()
   1237  with
   1238   rfbClientIteratorNext()
   1239  and
   1240   rfbReleaseClientIterator()
   1241  to prevent thread clashes.
   1242 
   1243  @section example_code Example Code
   1244 
   1245  There are two documented examples included:
   1246   - example.c, a shared scribble sheet
   1247   - pnmshow.c, a program to show PNMs (pictures) over the net.
   1248 
   1249  The examples are not too well documented, but easy straight forward and a
   1250  good starting point.
   1251 
   1252  Try example.c: it outputs on which port it listens (default: 5900), so it is
   1253  display 0. To view, call @code	vncviewer :0 @endcode
   1254  You should see a sheet with a gradient and "Hello World!" written on it. Try
   1255  to paint something. Note that everytime you click, there is some bigger blot,
   1256  whereas when you drag the mouse while clicked you draw a line. The size of the
   1257  blot depends on the mouse button you click. Open a second vncviewer with
   1258  the same parameters and watch it as you paint in the other window. This also
   1259  works over internet. You just have to know either the name or the IP of your
   1260  machine. Then it is @code vncviewer machine.where.example.runs.com:0 @endcode
   1261  or similar for the remote client. Now you are ready to type something. Be sure
   1262  that your mouse sits still, because everytime the mouse moves, the cursor is
   1263  reset to the position of the pointer! If you are done with that demo, press
   1264  the down or up arrows. If your viewer supports it, then the dimensions of the
   1265  sheet change. Just press Escape in the viewer. Note that the server still
   1266  runs, even if you closed both windows. When you reconnect now, everything you
   1267  painted and wrote is still there. You can press "Page Up" for a blank page.
   1268 
   1269  The demo pnmshow.c is much simpler: you either provide a filename as argument
   1270  or pipe a file through stdin. Note that the file has to be a raw pnm/ppm file,
   1271  i.e. a truecolour graphics. Only the Escape key is implemented. This may be
   1272  the best starting point if you want to learn how to use LibVNCServer. You
   1273  are confronted with the fact that the bytes per pixel can only be 8, 16 or 32.
   1274 */
   1275 
   1276 #endif
   1277