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
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
127struct _rfbClientRec;
128struct _rfbScreenInfo;
129struct rfbCursor;
130
131enum rfbNewClientAction {
132	RFB_CLIENT_ACCEPT,
133	RFB_CLIENT_ON_HOLD,
134	RFB_CLIENT_REFUSE
135};
136
137enum rfbSocketState {
138	RFB_SOCKET_INIT,
139	RFB_SOCKET_READY,
140	RFB_SOCKET_SHUTDOWN
141};
142
143typedef void (*rfbKbdAddEventProcPtr) (rfbBool down, rfbKeySym keySym, struct _rfbClientRec* cl);
144typedef void (*rfbKbdReleaseAllKeysProcPtr) (struct _rfbClientRec* cl);
145typedef void (*rfbPtrAddEventProcPtr) (int buttonMask, int x, int y, struct _rfbClientRec* cl);
146typedef void (*rfbSetXCutTextProcPtr) (char* str,int len, struct _rfbClientRec* cl);
147typedef struct rfbCursor* (*rfbGetCursorProcPtr) (struct _rfbClientRec* pScreen);
148typedef rfbBool (*rfbSetTranslateFunctionProcPtr)(struct _rfbClientRec* cl);
149typedef rfbBool (*rfbPasswordCheckProcPtr)(struct _rfbClientRec* cl,const char* encryptedPassWord,int len);
150typedef enum rfbNewClientAction (*rfbNewClientHookPtr)(struct _rfbClientRec* cl);
151typedef void (*rfbDisplayHookPtr)(struct _rfbClientRec* cl);
152typedef void (*rfbDisplayFinishedHookPtr)(struct _rfbClientRec* cl, int result);
153/** support the capability to view the caps/num/scroll states of the X server */
154typedef int  (*rfbGetKeyboardLedStateHookPtr)(struct _rfbScreenInfo* screen);
155typedef 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 */
161typedef 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 */
166typedef 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 */
171typedef int  (*rfbFileTransferPermitted) (struct _rfbClientRec* cl);
172/** Handle the textchat messages */
173typedef void (*rfbSetTextChat) (struct _rfbClientRec* cl, int length, char *string);
174
175typedef 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
188typedef 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
198typedef 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
223typedef 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
235typedef 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
399typedef 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
408struct sraRegion;
409typedef struct sraRegion* sraRegionPtr;
410
411/*
412 * Per-client structure.
413 */
414
415typedef void (*ClientGoneHookPtr)(struct _rfbClientRec* cl);
416
417typedef struct _rfbFileTransferData {
418  int fd;
419  int compressionEnabled;
420  int fileSize;
421  int numPackets;
422  int receiving;
423  int sending;
424} rfbFileTransferData;
425
426
427typedef 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
438typedef struct _rfbSslCtx rfbSslCtx;
439typedef struct _wsCtx wsCtx;
440
441typedef 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
729extern 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
742extern int rfbMaxClientWait;
743
744extern void rfbInitSockets(rfbScreenInfoPtr rfbScreen);
745extern void rfbShutdownSockets(rfbScreenInfoPtr rfbScreen);
746extern void rfbDisconnectUDPSock(rfbScreenInfoPtr rfbScreen);
747extern void rfbCloseClient(rfbClientPtr cl);
748extern int rfbReadExact(rfbClientPtr cl, char *buf, int len);
749extern int rfbReadExactTimeout(rfbClientPtr cl, char *buf, int len,int timeout);
750extern int rfbPeekExactTimeout(rfbClientPtr cl, char *buf, int len,int timeout);
751extern int rfbWriteExact(rfbClientPtr cl, const char *buf, int len);
752extern int rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec);
753extern int rfbConnect(rfbScreenInfoPtr rfbScreen, char* host, int port);
754extern int rfbConnectToTcpAddr(char* host, int port);
755extern int rfbListenOnTCPPort(int port, in_addr_t iface);
756extern int rfbListenOnTCP6Port(int port, const char* iface);
757extern int rfbListenOnUDPPort(int port, in_addr_t iface);
758extern int rfbStringToAddr(char* string,in_addr_t* addr);
759extern rfbBool rfbSetNonBlocking(int sock);
760
761#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
762/* websockets.c */
763
764extern rfbBool webSocketsCheck(rfbClientPtr cl);
765extern rfbBool webSocketCheckDisconnect(rfbClientPtr cl);
766extern int webSocketsEncode(rfbClientPtr cl, const char *src, int len, char **dst);
767extern 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. */
774typedef struct rfbClientIterator *rfbClientIteratorPtr;
775
776extern void rfbClientListInit(rfbScreenInfoPtr rfbScreen);
777extern rfbClientIteratorPtr rfbGetClientIterator(rfbScreenInfoPtr rfbScreen);
778extern rfbClientPtr rfbClientIteratorNext(rfbClientIteratorPtr iterator);
779extern void rfbReleaseClientIterator(rfbClientIteratorPtr iterator);
780extern void rfbIncrClientRef(rfbClientPtr cl);
781extern void rfbDecrClientRef(rfbClientPtr cl);
782
783extern void rfbNewClientConnection(rfbScreenInfoPtr rfbScreen,int sock);
784extern rfbClientPtr rfbNewClient(rfbScreenInfoPtr rfbScreen,int sock);
785extern rfbClientPtr rfbNewUDPClient(rfbScreenInfoPtr rfbScreen);
786extern rfbClientPtr rfbReverseConnection(rfbScreenInfoPtr rfbScreen,char *host, int port);
787extern void rfbClientConnectionGone(rfbClientPtr cl);
788extern void rfbProcessClientMessage(rfbClientPtr cl);
789extern void rfbClientConnFailed(rfbClientPtr cl, const char *reason);
790extern void rfbNewUDPConnection(rfbScreenInfoPtr rfbScreen,int sock);
791extern void rfbProcessUDPInput(rfbScreenInfoPtr rfbScreen);
792extern rfbBool rfbSendFramebufferUpdate(rfbClientPtr cl, sraRegionPtr updateRegion);
793extern rfbBool rfbSendRectEncodingRaw(rfbClientPtr cl, int x,int y,int w,int h);
794extern rfbBool rfbSendUpdateBuf(rfbClientPtr cl);
795extern void rfbSendServerCutText(rfbScreenInfoPtr rfbScreen,char *str, int len);
796extern rfbBool rfbSendCopyRegion(rfbClientPtr cl,sraRegionPtr reg,int dx,int dy);
797extern rfbBool rfbSendLastRectMarker(rfbClientPtr cl);
798extern rfbBool rfbSendNewFBSize(rfbClientPtr cl, int w, int h);
799extern rfbBool rfbSendSetColourMapEntries(rfbClientPtr cl, int firstColour, int nColours);
800extern void rfbSendBell(rfbScreenInfoPtr rfbScreen);
801
802extern char *rfbProcessFileTransferReadBuffer(rfbClientPtr cl, uint32_t length);
803extern rfbBool rfbSendFileTransferChunk(rfbClientPtr cl);
804extern rfbBool rfbSendDirContent(rfbClientPtr cl, int length, char *buffer);
805extern rfbBool rfbSendFileTransferMessage(rfbClientPtr cl, uint8_t contentType, uint8_t contentParam, uint32_t size, uint32_t length, const char *buffer);
806extern char *rfbProcessFileTransferReadBuffer(rfbClientPtr cl, uint32_t length);
807extern rfbBool rfbProcessFileTransfer(rfbClientPtr cl, uint8_t contentType, uint8_t contentParam, uint32_t size, uint32_t length);
808
809void rfbGotXCutText(rfbScreenInfoPtr rfbScreen, char *str, int len);
810
811/* translate.c */
812
813extern rfbBool rfbEconomicTranslate;
814
815extern void rfbTranslateNone(char *table, rfbPixelFormat *in,
816                             rfbPixelFormat *out,
817                             char *iptr, char *optr,
818                             int bytesBetweenInputLines,
819                             int width, int height);
820extern rfbBool rfbSetTranslateFunction(rfbClientPtr cl);
821extern rfbBool rfbSetClientColourMap(rfbClientPtr cl, int firstColour, int nColours);
822extern void rfbSetClientColourMaps(rfbScreenInfoPtr rfbScreen, int firstColour, int nColours);
823
824/* httpd.c */
825
826extern void rfbHttpInitSockets(rfbScreenInfoPtr rfbScreen);
827extern void rfbHttpShutdownSockets(rfbScreenInfoPtr rfbScreen);
828extern void rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen);
829
830
831
832/* auth.c */
833
834extern void rfbAuthNewClient(rfbClientPtr cl);
835extern void rfbProcessClientSecurityType(rfbClientPtr cl);
836extern void rfbAuthProcessClientMessage(rfbClientPtr cl);
837extern void rfbRegisterSecurityHandler(rfbSecurityHandler* handler);
838extern void rfbUnregisterSecurityHandler(rfbSecurityHandler* handler);
839
840/* rre.c */
841
842extern rfbBool rfbSendRectEncodingRRE(rfbClientPtr cl, int x,int y,int w,int h);
843
844
845/* corre.c */
846
847extern rfbBool rfbSendRectEncodingCoRRE(rfbClientPtr cl, int x,int y,int w,int h);
848
849
850/* hextile.c */
851
852extern 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
864extern 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
882extern 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
891extern rfbBool rfbTightDisableGradient;
892
893extern int rfbNumCodedRectsTight(rfbClientPtr cl, int x,int y,int w,int h);
894
895extern rfbBool rfbSendRectEncodingTight(rfbClientPtr cl, int x,int y,int w,int h);
896
897#if defined(LIBVNCSERVER_HAVE_LIBPNG)
898extern 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
907typedef 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;
919extern unsigned char rfbReverseByte[0x100];
920
921extern rfbBool rfbSendCursorShape(rfbClientPtr cl/*, rfbScreenInfoPtr pScreen*/);
922extern rfbBool rfbSendCursorPos(rfbClientPtr cl);
923extern void rfbConvertLSBCursorBitmapOrMask(int width,int height,unsigned char* bitmap);
924extern rfbCursorPtr rfbMakeXCursor(int width,int height,char* cursorString,char* maskString);
925extern char* rfbMakeMaskForXCursor(int width,int height,char* cursorString);
926extern char* rfbMakeMaskFromAlphaSource(int width,int height,unsigned char* alphaSource);
927extern void rfbMakeXCursorFromRichCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr cursor);
928extern void rfbMakeRichCursorFromXCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr cursor);
929extern void rfbFreeCursor(rfbCursorPtr cursor);
930extern void rfbSetCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr c);
931
932/** cursor handling for the pointer */
933extern void rfbDefaultPtrAddEvent(int buttonMask,int x,int y,rfbClientPtr cl);
934
935/* zrle.c */
936#ifdef LIBVNCSERVER_HAVE_LIBZ
937extern rfbBool rfbSendRectEncodingZRLE(rfbClientPtr cl, int x, int y, int w,int h);
938#endif
939
940/* stats.c */
941
942extern void rfbResetStats(rfbClientPtr cl);
943extern void rfbPrintStats(rfbClientPtr cl);
944
945/* font.c */
946
947typedef 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
957int rfbDrawChar(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,unsigned char c,rfbPixel colour);
958void rfbDrawString(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,const char* string,rfbPixel colour);
959/** if colour==backColour, background is transparent */
960int rfbDrawCharWithClip(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,unsigned char c,int x1,int y1,int x2,int y2,rfbPixel colour,rfbPixel backColour);
961void rfbDrawStringWithClip(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,const char* string,int x1,int y1,int x2,int y2,rfbPixel colour,rfbPixel backColour);
962int rfbWidthOfString(rfbFontDataPtr font,const char* string);
963int rfbWidthOfChar(rfbFontDataPtr font,unsigned char c);
964void 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. */
966void 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 */
969rfbFontDataPtr rfbLoadConsoleFont(char *filename);
970/** free a dynamically loaded font */
971void rfbFreeFont(rfbFontDataPtr font);
972
973/* draw.c */
974
975void rfbFillRect(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2,rfbPixel col);
976void rfbDrawPixel(rfbScreenInfoPtr s,int x,int y,rfbPixel col);
977void 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. */
985typedef void (*SelectionChangedHookPtr)(int _index);
986extern 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
994extern void rfbUsage(void);
995extern void rfbPurgeArguments(int* argc,int* position,int count,char *argv[]);
996extern rfbBool rfbProcessArguments(rfbScreenInfoPtr rfbScreen,int* argc, char *argv[]);
997extern rfbBool rfbProcessSizeArguments(int* width,int* height,int* bpp,int* argc, char *argv[]);
998
999/* main.c */
1000
1001extern void rfbLogEnable(int enabled);
1002typedef void (*rfbLogProc)(const char *format, ...);
1003extern rfbLogProc rfbLog, rfbErr;
1004extern void rfbLogPerror(const char *str);
1005
1006void rfbScheduleCopyRect(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2,int dx,int dy);
1007void rfbScheduleCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,int dy);
1008
1009void rfbDoCopyRect(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2,int dx,int dy);
1010void rfbDoCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,int dy);
1011
1012void rfbMarkRectAsModified(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2);
1013void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,sraRegionPtr modRegion);
1014void rfbDoNothingWithClient(rfbClientPtr cl);
1015enum rfbNewClientAction defaultNewClientHook(rfbClientPtr cl);
1016void rfbRegisterProtocolExtension(rfbProtocolExtension* extension);
1017void rfbUnregisterProtocolExtension(rfbProtocolExtension* extension);
1018struct _rfbProtocolExtension* rfbGetExtensionIterator();
1019void rfbReleaseExtensionIterator();
1020rfbBool rfbEnableExtension(rfbClientPtr cl, rfbProtocolExtension* extension,
1021	void* data);
1022rfbBool rfbDisableExtension(rfbClientPtr cl, rfbProtocolExtension* extension);
1023void* rfbGetExtensionClientData(rfbClientPtr cl, rfbProtocolExtension* extension);
1024
1025/** to check against plain passwords */
1026rfbBool rfbCheckPasswordByList(rfbClientPtr cl,const char* response,int len);
1027
1028/* functions to make a vnc server */
1029extern rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
1030 int width,int height,int bitsPerSample,int samplesPerPixel,
1031 int bytesPerPixel);
1032extern void rfbInitServer(rfbScreenInfoPtr rfbScreen);
1033extern void rfbShutdownServer(rfbScreenInfoPtr rfbScreen,rfbBool disconnectClients);
1034extern void rfbNewFramebuffer(rfbScreenInfoPtr rfbScreen,char *framebuffer,
1035 int width,int height, int bitsPerSample,int samplesPerPixel,
1036 int bytesPerPixel);
1037
1038extern void rfbScreenCleanup(rfbScreenInfoPtr screenInfo);
1039extern 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. */
1044extern void rfbStartOnHoldClient(rfbClientPtr cl);
1045extern 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
1053extern void rfbRunEventLoop(rfbScreenInfoPtr screenInfo, long usec, rfbBool runInBackground);
1054extern rfbBool rfbProcessEvents(rfbScreenInfoPtr screenInfo,long usec);
1055extern rfbBool rfbIsActive(rfbScreenInfoPtr screenInfo);
1056
1057/* TightVNC file transfer extension */
1058void rfbRegisterTightVNCFileTransferExtension();
1059void rfbUnregisterTightVNCFileTransferExtension();
1060
1061/* Statistics */
1062extern char *messageNameServer2Client(uint32_t type, char *buf, int len);
1063extern char *messageNameClient2Server(uint32_t type, char *buf, int len);
1064extern char *encodingName(uint32_t enc, char *buf, int len);
1065
1066extern rfbStatList *rfbStatLookupEncoding(rfbClientPtr cl, uint32_t type);
1067extern rfbStatList *rfbStatLookupMessage(rfbClientPtr cl, uint32_t type);
1068
1069/* Each call to rfbStatRecord* adds one to the rect count for that type */
1070extern void rfbStatRecordEncodingSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
1071extern void rfbStatRecordEncodingSentAdd(rfbClientPtr cl, uint32_t type, int byteCount); /* Specifically for tight encoding */
1072extern void rfbStatRecordEncodingRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
1073extern void rfbStatRecordMessageSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
1074extern void rfbStatRecordMessageRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
1075extern void rfbResetStats(rfbClientPtr cl);
1076extern void rfbPrintStats(rfbClientPtr cl);
1077
1078extern int rfbStatGetSentBytes(rfbClientPtr cl);
1079extern int rfbStatGetSentBytesIfRaw(rfbClientPtr cl);
1080extern int rfbStatGetRcvdBytes(rfbClientPtr cl);
1081extern int rfbStatGetRcvdBytesIfRaw(rfbClientPtr cl);
1082extern int rfbStatGetMessageCountSent(rfbClientPtr cl, uint32_t type);
1083extern int rfbStatGetMessageCountRcvd(rfbClientPtr cl, uint32_t type);
1084extern int rfbStatGetEncodingCountSent(rfbClientPtr cl, uint32_t type);
1085extern 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*/
1088extern void rfbSetProtocolVersion(rfbScreenInfoPtr rfbScreen, int major_, int minor_);
1089
1090/** send a TextChat message to a client */
1091extern 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 */
1098rfbBool rfbProcessNewConnection(rfbScreenInfoPtr rfbScreen);
1099rfbBool 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