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