cscg24-guacamole

CSCG 2024 Challenge 'Guacamole Mashup'
git clone https://git.sinitax.com/sinitax/cscg24-guacamole
Log | Files | Refs | sfeed.txt

rfb.h (50605B)


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