4
* @defgroup libvncserver_api LibVNCServer API Reference
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.
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.
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.
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,
36
#if(defined __cplusplus)
44
#include <rfb/rfbproto.h>
46
#ifdef LIBVNCSERVER_HAVE_SYS_TYPES_H
47
#include <sys/types.h>
55
#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
58
#define LOCK(mutex) (rfbLog("%s:%d LOCK(%s,0x%x)\n",__FILE__,__LINE__,#mutex,&(mutex)), pthread_mutex_lock(&(mutex)))
59
#define UNLOCK(mutex) (rfbLog("%s:%d UNLOCK(%s,0x%x)\n",__FILE__,__LINE__,#mutex,&(mutex)), pthread_mutex_unlock(&(mutex)))
60
#define MUTEX(mutex) pthread_mutex_t (mutex)
61
#define INIT_MUTEX(mutex) (rfbLog("%s:%d INIT_MUTEX(%s,0x%x)\n",__FILE__,__LINE__,#mutex,&(mutex)), pthread_mutex_init(&(mutex),NULL))
62
#define TINI_MUTEX(mutex) (rfbLog("%s:%d TINI_MUTEX(%s)\n",__FILE__,__LINE__,#mutex), pthread_mutex_destroy(&(mutex)))
63
#define TSIGNAL(cond) (rfbLog("%s:%d TSIGNAL(%s)\n",__FILE__,__LINE__,#cond), pthread_cond_signal(&(cond)))
64
#define WAIT(cond,mutex) (rfbLog("%s:%d WAIT(%s,%s)\n",__FILE__,__LINE__,#cond,#mutex), pthread_cond_wait(&(cond),&(mutex)))
65
#define COND(cond) pthread_cond_t (cond)
66
#define INIT_COND(cond) (rfbLog("%s:%d INIT_COND(%s)\n",__FILE__,__LINE__,#cond), pthread_cond_init(&(cond),NULL))
67
#define TINI_COND(cond) (rfbLog("%s:%d TINI_COND(%s)\n",__FILE__,__LINE__,#cond), pthread_cond_destroy(&(cond)))
68
#define IF_PTHREADS(x) x
71
#define LOCK(mutex) pthread_mutex_lock(&(mutex));
72
#define UNLOCK(mutex) pthread_mutex_unlock(&(mutex));
74
#define MUTEX(mutex) pthread_mutex_t (mutex)
75
#define INIT_MUTEX(mutex) pthread_mutex_init(&(mutex),NULL)
76
#define TINI_MUTEX(mutex) pthread_mutex_destroy(&(mutex))
77
#define TSIGNAL(cond) pthread_cond_signal(&(cond))
78
#define WAIT(cond,mutex) pthread_cond_wait(&(cond),&(mutex))
79
#define COND(cond) pthread_cond_t (cond)
80
#define INIT_COND(cond) pthread_cond_init(&(cond),NULL)
81
#define TINI_COND(cond) pthread_cond_destroy(&(cond))
82
#define IF_PTHREADS(x) x
88
#define INIT_MUTEX(mutex)
89
#define TINI_MUTEX(mutex)
91
#define WAIT(cond,mutex) this_is_unsupported
93
#define INIT_COND(cond)
94
#define TINI_COND(cond)
95
#define IF_PTHREADS(x)
98
/* end of stuff for autoconf */
100
/* if you use pthreads, but don't define LIBVNCSERVER_HAVE_LIBPTHREAD, the structs
101
get all mixed up. So this gives a linker error reminding you to compile
102
the library and your application (at least the parts including rfb.h)
103
with the same support for pthreads. */
104
#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
105
#ifdef LIBVNCSERVER_HAVE_LIBZ
106
#define rfbInitServer rfbInitServerWithPthreadsAndZRLE
108
#define rfbInitServer rfbInitServerWithPthreadsButWithoutZRLE
111
#ifdef LIBVNCSERVER_HAVE_LIBZ
112
#define rfbInitServer rfbInitServerWithoutPthreadsButWithZRLE
114
#define rfbInitServer rfbInitServerWithoutPthreadsAndZRLE
118
struct _rfbClientRec;
119
struct _rfbScreenInfo;
122
enum rfbNewClientAction {
128
enum rfbSocketState {
134
typedef void (*rfbKbdAddEventProcPtr) (rfbBool down, rfbKeySym keySym, struct _rfbClientRec* cl);
135
typedef void (*rfbKbdReleaseAllKeysProcPtr) (struct _rfbClientRec* cl);
136
typedef void (*rfbPtrAddEventProcPtr) (int buttonMask, int x, int y, struct _rfbClientRec* cl);
137
typedef void (*rfbSetXCutTextProcPtr) (char* str,int len, struct _rfbClientRec* cl);
138
typedef struct rfbCursor* (*rfbGetCursorProcPtr) (struct _rfbClientRec* pScreen);
139
typedef rfbBool (*rfbSetTranslateFunctionProcPtr)(struct _rfbClientRec* cl);
140
typedef rfbBool (*rfbPasswordCheckProcPtr)(struct _rfbClientRec* cl,const char* encryptedPassWord,int len);
141
typedef enum rfbNewClientAction (*rfbNewClientHookPtr)(struct _rfbClientRec* cl);
142
typedef void (*rfbDisplayHookPtr)(struct _rfbClientRec* cl);
143
typedef void (*rfbDisplayFinishedHookPtr)(struct _rfbClientRec* cl, int result);
144
/** support the capability to view the caps/num/scroll states of the X server */
145
typedef int (*rfbGetKeyboardLedStateHookPtr)(struct _rfbScreenInfo* screen);
146
typedef rfbBool (*rfbXvpHookPtr)(struct _rfbClientRec* cl, uint8_t, uint8_t);
148
* If x==1 and y==1 then set the whole display
149
* else find the window underneath x and y and set the framebuffer to the dimensions
152
typedef void (*rfbSetSingleWindowProcPtr) (struct _rfbClientRec* cl, int x, int y);
154
* Status determines if the X11 server permits input from the local user
157
typedef void (*rfbSetServerInputProcPtr) (struct _rfbClientRec* cl, int status);
159
* Permit the server to allow or deny filetransfers. This is defaulted to deny
160
* It is called when a client initiates a connection to determine if it is permitted.
162
typedef int (*rfbFileTransferPermitted) (struct _rfbClientRec* cl);
163
/** Handle the textchat messages */
164
typedef void (*rfbSetTextChat) (struct _rfbClientRec* cl, int length, char *string);
168
rfbBool is16; /**< is the data format short? */
172
} data; /**< there have to be count*3 entries */
176
* Security handling (RFB protocol version 3.7)
179
typedef struct _rfbSecurity {
181
void (*handler)(struct _rfbClientRec* cl);
182
struct _rfbSecurity* next;
183
} rfbSecurityHandler;
186
* Protocol extension handling.
189
typedef struct _rfbProtocolExtension {
190
/** returns FALSE if extension should be deactivated for client.
191
if newClient == NULL, it is always deactivated. */
192
rfbBool (*newClient)(struct _rfbClientRec* client, void** data);
193
/** returns FALSE if extension should be deactivated for client.
194
if init == NULL, it stays activated. */
195
rfbBool (*init)(struct _rfbClientRec* client, void* data);
196
/** if pseudoEncodings is not NULL, it contains a 0 terminated
197
list of the pseudo encodings handled by this extension. */
198
int *pseudoEncodings;
199
/** returns TRUE if that pseudo encoding is handled by the extension.
200
encodingNumber==0 means "reset encodings". */
201
rfbBool (*enablePseudoEncoding)(struct _rfbClientRec* client,
202
void** data, int encodingNumber);
203
/** returns TRUE if message was handled */
204
rfbBool (*handleMessage)(struct _rfbClientRec* client,
206
const rfbClientToServerMsg* message);
207
void (*close)(struct _rfbClientRec* client, void* data);
209
/** processArguments returns the number of handled arguments */
210
int (*processArgument)(int argc, char *argv[]);
211
struct _rfbProtocolExtension* next;
212
} rfbProtocolExtension;
214
typedef struct _rfbExtensionData {
215
rfbProtocolExtension* extension;
217
struct _rfbExtensionData* next;
221
* Per-screen (framebuffer) structure. There can be as many as you wish,
222
* each serving different clients. However, you have to call
223
* rfbProcessEvents for each of these.
226
typedef struct _rfbScreenInfo
228
/** this structure has children that are scaled versions of this screen */
229
struct _rfbScreenInfo *scaledScreenNext;
230
int scaledScreenRefCount;
233
int paddedWidthInBytes;
243
* some screen specific data can be put into a struct where screenData
244
* points to. You need this if you have more than one screen at the
245
* same time while using the same functions.
249
/* additions by libvncserver */
251
rfbPixelFormat serverFormat;
252
rfbColourMap colourMap; /**< set this if rfbServerFormat.trueColour==FALSE */
253
const char* desktopName;
262
struct fd_set allFds;
267
enum rfbSocketState socketState;
269
rfbBool inetdInitDone;
273
struct _rfbClientRec* udpClient;
274
rfbBool udpSockConnected;
275
struct sockaddr_in udpRemoteAddr;
280
rfbBool httpInitDone;
281
rfbBool httpEnableProxyConnect;
284
SOCKET httpListenSock;
287
rfbPasswordCheckProcPtr passwordCheck;
288
void* authPasswdData;
289
/** If rfbAuthPasswdData is given a list, this is the first
290
view only password. */
291
int authPasswdFirstViewOnly;
293
/** send only this many rectangles in one update */
294
int maxRectsPerUpdate;
295
/** this is the amount of milliseconds to wait at least before sending
301
rfbBool alwaysShared;
303
rfbBool dontDisconnect;
304
struct _rfbClientRec* clientHead;
305
struct _rfbClientRec* pointerClient; /**< "Mutex" for pointer events */
309
int cursorX, cursorY,underCursorBufferLen;
310
char* underCursorBuffer;
311
rfbBool dontConvertRichCursorToXCursor;
312
struct rfbCursor* cursor;
315
* the frameBuffer has to be supplied by the serving process.
316
* The buffer will not be freed by
319
rfbKbdAddEventProcPtr kbdAddEvent;
320
rfbKbdReleaseAllKeysProcPtr kbdReleaseAllKeys;
321
rfbPtrAddEventProcPtr ptrAddEvent;
322
rfbSetXCutTextProcPtr setXCutText;
323
rfbGetCursorProcPtr getCursorPtr;
324
rfbSetTranslateFunctionProcPtr setTranslateFunction;
325
rfbSetSingleWindowProcPtr setSingleWindow;
326
rfbSetServerInputProcPtr setServerInput;
327
rfbFileTransferPermitted getFileTransferPermission;
328
rfbSetTextChat setTextChat;
330
/** newClientHook is called just after a new client is created */
331
rfbNewClientHookPtr newClientHook;
332
/** displayHook is called just before a frame buffer update */
333
rfbDisplayHookPtr displayHook;
335
/** These hooks are called to pass keyboard state back to the client */
336
rfbGetKeyboardLedStateHookPtr getKeyboardLedStateHook;
338
#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
340
rfbBool backgroundLoop;
343
/** if TRUE, an ignoring signal handler is installed for SIGPIPE */
344
rfbBool ignoreSIGPIPE;
346
/** if not zero, only a slice of this height is processed every time
347
* an update should be sent. This should make working on a slow
348
* link more interactive. */
349
int progressiveSliceHeight;
351
in_addr_t listenInterface;
352
int deferPtrUpdateTime;
354
/** handle as many input events as possible (default off) */
355
rfbBool handleEventsEagerly;
357
/** rfbEncodingServerIdentity */
360
/** What does the server tell the new clients which version it supports */
361
int protocolMajorVersion;
362
int protocolMinorVersion;
364
/** command line authorization of file transfers */
365
rfbBool permitFileTransfer;
367
/** displayFinishedHook is called just after a frame buffer update */
368
rfbDisplayFinishedHookPtr displayFinishedHook;
369
/** xvpHook is called to handle an xvp client message */
370
rfbXvpHookPtr xvpHook;
371
} rfbScreenInfo, *rfbScreenInfoPtr;
375
* rfbTranslateFnType is the type of translation functions.
378
typedef void (*rfbTranslateFnType)(char *table, rfbPixelFormat *in,
380
char *iptr, char *optr,
381
int bytesBetweenInputLines,
382
int width, int height);
388
typedef struct sraRegion* sraRegionPtr;
391
* Per-client structure.
394
typedef void (*ClientGoneHookPtr)(struct _rfbClientRec* cl);
396
typedef struct _rfbFileTransferData {
398
int compressionEnabled;
403
} rfbFileTransferData;
406
typedef struct _rfbStatList {
410
uint32_t bytesSentIfRaw;
413
uint32_t bytesRcvdIfRaw;
414
struct _rfbStatList *Next;
417
typedef struct _rfbClientRec {
419
/** back pointer to the screen */
420
rfbScreenInfoPtr screen;
422
/** points to a scaled version of the screen buffer in cl->scaledScreenList */
423
rfbScreenInfoPtr scaledScreen;
424
/** how did the client tell us it wanted the screen changed? Ultra style or palm style? */
428
/** private data. You should put any application client specific data
429
* into a struct and let clientData point to it. Don't forget to
430
* free the struct via clientGoneHook!
432
* This is useful if the IO functions have to behave client specific.
435
ClientGoneHookPtr clientGoneHook;
440
/* RFB protocol minor version number */
441
int protocolMajorVersion;
442
int protocolMinorVersion;
444
#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
445
pthread_t client_thread;
447
/** Possible client states: */
449
RFB_PROTOCOL_VERSION, /**< establishing protocol version */
450
RFB_SECURITY_TYPE, /**< negotiating security (RFB v.3.7) */
451
RFB_AUTHENTICATION, /**< authenticating */
452
RFB_INITIALISATION, /**< sending initialisation messages */
453
RFB_NORMAL /**< normal protocol messages */
456
rfbBool reverseConnection;
458
rfbBool readyForSetColourMapEntries;
460
int preferredEncoding;
461
int correMaxWidth, correMaxHeight;
465
/* The following member is only used during VNC authentication */
466
uint8_t authChallenge[CHALLENGESIZE];
468
/* The following members represent the update needed to get the client's
469
framebuffer from its present state to the current state of our
472
If the client does not accept CopyRect encoding then the update is
473
simply represented as the region of the screen which has been modified
476
If the client does accept CopyRect encoding, then the update consists of
477
two parts. First we have a single copy from one region of the screen to
478
another (the destination of the copy is copyRegion), and second we have
479
the region of the screen which has been modified in some other way
482
Although the copy is of a single region, this region may have many
483
rectangles. When sending an update, the copyRegion is always sent
484
before the modifiedRegion. This is because the modifiedRegion may
485
overlap parts of the screen which are in the source of the copy.
487
In fact during normal processing, the modifiedRegion may even overlap
488
the destination copyRegion. Just before an update is sent we remove
489
from the copyRegion anything in the modifiedRegion. */
491
sraRegionPtr copyRegion; /**< the destination region of the copy */
492
int copyDX, copyDY; /**< the translation by which the copy happens */
494
sraRegionPtr modifiedRegion;
496
/** As part of the FramebufferUpdateRequest, a client can express interest
497
in a subrectangle of the whole framebuffer. This is stored in the
498
requestedRegion member. In the normal case this is the whole
499
framebuffer if the client is ready, empty if it's not. */
501
sraRegionPtr requestedRegion;
503
/** The following member represents the state of the "deferred update" timer
504
- when the framebuffer is modified and the client is ready, in most
505
cases it is more efficient to defer sending the update by a few
506
milliseconds so that several changes to the framebuffer can be combined
507
into a single update. */
509
struct timeval startDeferring;
510
struct timeval startPtrDeferring;
515
/** translateFn points to the translation function which is used to copy
516
and translate a rectangle from the framebuffer to an output buffer. */
518
rfbTranslateFnType translateFn;
519
char *translateLookupTable;
520
rfbPixelFormat format;
523
* UPDATE_BUF_SIZE must be big enough to send at least one whole line of the
524
* framebuffer. So for a max screen width of say 2K with 32-bit pixels this
528
#define UPDATE_BUF_SIZE 30000
530
char updateBuf[UPDATE_BUF_SIZE];
534
struct _rfbStatList *statEncList;
535
struct _rfbStatList *statMsgList;
536
int rawBytesEquivalent;
539
#ifdef LIBVNCSERVER_HAVE_LIBZ
540
/* zlib encoding -- necessary compression state info per client */
542
struct z_stream_s compStream;
543
rfbBool compStreamInited;
544
uint32_t zlibCompressLevel;
545
/** the quality level is also used by ZYWRLE */
546
int tightQualityLevel;
548
#ifdef LIBVNCSERVER_HAVE_LIBJPEG
549
/* tight encoding -- preserve zlib streams' state for each client */
550
z_stream zsStruct[4];
553
int tightCompressLevel;
557
/* Ultra Encoding support */
558
rfbBool compStreamInitedLZO;
561
rfbFileTransferData fileTransfer;
563
int lastKeyboardLedState; /**< keep track of last value so we can send *change* events */
564
rfbBool enableSupportedMessages; /**< client supports SupportedMessages encoding */
565
rfbBool enableSupportedEncodings; /**< client supports SupportedEncodings encoding */
566
rfbBool enableServerIdentity; /**< client supports ServerIdentity encoding */
567
rfbBool enableKeyboardLedState; /**< client supports KeyboardState encoding */
568
rfbBool enableLastRectEncoding; /**< client supports LastRect encoding */
569
rfbBool enableCursorShapeUpdates; /**< client supports cursor shape updates */
570
rfbBool enableCursorPosUpdates; /**< client supports cursor position updates */
571
rfbBool useRichCursorEncoding; /**< rfbEncodingRichCursor is preferred */
572
rfbBool cursorWasChanged; /**< cursor shape update should be sent */
573
rfbBool cursorWasMoved; /**< cursor position update should be sent */
574
int cursorX,cursorY; /**< the coordinates of the cursor,
575
if enableCursorShapeUpdates = FALSE */
577
rfbBool useNewFBSize; /**< client supports NewFBSize encoding */
578
rfbBool newFBSizePending; /**< framebuffer size was changed */
580
struct _rfbClientRec *prev;
581
struct _rfbClientRec *next;
583
#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
584
/** whenever a client is referenced, the refCount has to be incremented
585
and afterwards decremented, so that the client is not cleaned up
586
while being referenced.
587
Use the functions rfbIncrClientRef(cl) and rfbDecrClientRef(cl);
590
MUTEX(refCountMutex);
598
#ifdef LIBVNCSERVER_HAVE_LIBZ
601
int zywrleBuf[rfbZRLETileWidth * rfbZRLETileHeight];
604
/** if progressive updating is on, this variable holds the current
605
* y coordinate of the progressive slice. */
606
int progressiveSliceY;
608
rfbExtensionData* extensions;
610
/** for threaded zrle */
614
/** for thread safety for rfbSendFBUpdate() */
615
#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
616
#define LIBVNCSERVER_SEND_MUTEX
620
/* buffers to hold pixel data before and after encoding.
621
per-client for thread safety */
623
int beforeEncBufSize;
627
} rfbClientRec, *rfbClientPtr;
630
* This macro is used to test whether there is a framebuffer update needing to
631
* be sent to the client.
634
#define FB_UPDATE_PENDING(cl) \
635
(((cl)->enableCursorShapeUpdates && (cl)->cursorWasChanged) || \
636
(((cl)->enableCursorShapeUpdates == FALSE && \
637
((cl)->cursorX != (cl)->screen->cursorX || \
638
(cl)->cursorY != (cl)->screen->cursorY))) || \
639
((cl)->useNewFBSize && (cl)->newFBSizePending) || \
640
((cl)->enableCursorPosUpdates && (cl)->cursorWasMoved) || \
641
!sraRgnEmpty((cl)->copyRegion) || !sraRgnEmpty((cl)->modifiedRegion))
644
* Macros for endian swapping.
647
#define Swap16(s) ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff))
649
#define Swap24(l) ((((l) & 0xff) << 16) | (((l) >> 16) & 0xff) | \
652
#define Swap32(l) (((l) >> 24) | \
653
(((l) & 0x00ff0000) >> 8) | \
654
(((l) & 0x0000ff00) << 8) | \
658
extern char rfbEndianTest;
660
#define Swap16IfLE(s) (rfbEndianTest ? Swap16(s) : (s))
661
#define Swap24IfLE(l) (rfbEndianTest ? Swap24(l) : (l))
662
#define Swap32IfLE(l) (rfbEndianTest ? Swap32(l) : (l))
664
/* UltraVNC uses some windows structures unmodified, so the viewer expects LittleEndian Data */
665
#define Swap16IfBE(s) (rfbEndianTest ? (s) : Swap16(s))
666
#define Swap24IfBE(l) (rfbEndianTest ? (l) : Swap24(l))
667
#define Swap32IfBE(l) (rfbEndianTest ? (l) : Swap32(l))
671
extern int rfbMaxClientWait;
673
extern void rfbInitSockets(rfbScreenInfoPtr rfbScreen);
674
extern void rfbShutdownSockets(rfbScreenInfoPtr rfbScreen);
675
extern void rfbDisconnectUDPSock(rfbScreenInfoPtr rfbScreen);
676
extern void rfbCloseClient(rfbClientPtr cl);
677
extern int rfbReadExact(rfbClientPtr cl, char *buf, int len);
678
extern int rfbReadExactTimeout(rfbClientPtr cl, char *buf, int len,int timeout);
679
extern int rfbWriteExact(rfbClientPtr cl, const char *buf, int len);
680
extern int rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec);
681
extern int rfbConnect(rfbScreenInfoPtr rfbScreen, char* host, int port);
682
extern int rfbConnectToTcpAddr(char* host, int port);
683
extern int rfbListenOnTCPPort(int port, in_addr_t iface);
684
extern int rfbListenOnUDPPort(int port, in_addr_t iface);
685
extern int rfbStringToAddr(char* string,in_addr_t* addr);
686
extern rfbBool rfbSetNonBlocking(int sock);
690
/* Routines to iterate over the client list in a thread-safe way.
691
Only a single iterator can be in use at a time process-wide. */
692
typedef struct rfbClientIterator *rfbClientIteratorPtr;
694
extern void rfbClientListInit(rfbScreenInfoPtr rfbScreen);
695
extern rfbClientIteratorPtr rfbGetClientIterator(rfbScreenInfoPtr rfbScreen);
696
extern rfbClientPtr rfbClientIteratorNext(rfbClientIteratorPtr iterator);
697
extern void rfbReleaseClientIterator(rfbClientIteratorPtr iterator);
698
extern void rfbIncrClientRef(rfbClientPtr cl);
699
extern void rfbDecrClientRef(rfbClientPtr cl);
701
extern void rfbNewClientConnection(rfbScreenInfoPtr rfbScreen,int sock);
702
extern rfbClientPtr rfbNewClient(rfbScreenInfoPtr rfbScreen,int sock);
703
extern rfbClientPtr rfbNewUDPClient(rfbScreenInfoPtr rfbScreen);
704
extern rfbClientPtr rfbReverseConnection(rfbScreenInfoPtr rfbScreen,char *host, int port);
705
extern void rfbClientConnectionGone(rfbClientPtr cl);
706
extern void rfbProcessClientMessage(rfbClientPtr cl);
707
extern void rfbClientConnFailed(rfbClientPtr cl, char *reason);
708
extern void rfbNewUDPConnection(rfbScreenInfoPtr rfbScreen,int sock);
709
extern void rfbProcessUDPInput(rfbScreenInfoPtr rfbScreen);
710
extern rfbBool rfbSendFramebufferUpdate(rfbClientPtr cl, sraRegionPtr updateRegion);
711
extern rfbBool rfbSendRectEncodingRaw(rfbClientPtr cl, int x,int y,int w,int h);
712
extern rfbBool rfbSendUpdateBuf(rfbClientPtr cl);
713
extern void rfbSendServerCutText(rfbScreenInfoPtr rfbScreen,char *str, int len);
714
extern rfbBool rfbSendCopyRegion(rfbClientPtr cl,sraRegionPtr reg,int dx,int dy);
715
extern rfbBool rfbSendLastRectMarker(rfbClientPtr cl);
716
extern rfbBool rfbSendNewFBSize(rfbClientPtr cl, int w, int h);
717
extern rfbBool rfbSendSetColourMapEntries(rfbClientPtr cl, int firstColour, int nColours);
718
extern void rfbSendBell(rfbScreenInfoPtr rfbScreen);
720
extern char *rfbProcessFileTransferReadBuffer(rfbClientPtr cl, uint32_t length);
721
extern rfbBool rfbSendFileTransferChunk(rfbClientPtr cl);
722
extern rfbBool rfbSendDirContent(rfbClientPtr cl, int length, char *buffer);
723
extern rfbBool rfbSendFileTransferMessage(rfbClientPtr cl, uint8_t contentType, uint8_t contentParam, uint32_t size, uint32_t length, char *buffer);
724
extern char *rfbProcessFileTransferReadBuffer(rfbClientPtr cl, uint32_t length);
725
extern rfbBool rfbProcessFileTransfer(rfbClientPtr cl, uint8_t contentType, uint8_t contentParam, uint32_t size, uint32_t length);
727
void rfbGotXCutText(rfbScreenInfoPtr rfbScreen, char *str, int len);
731
extern rfbBool rfbEconomicTranslate;
733
extern void rfbTranslateNone(char *table, rfbPixelFormat *in,
735
char *iptr, char *optr,
736
int bytesBetweenInputLines,
737
int width, int height);
738
extern rfbBool rfbSetTranslateFunction(rfbClientPtr cl);
739
extern rfbBool rfbSetClientColourMap(rfbClientPtr cl, int firstColour, int nColours);
740
extern void rfbSetClientColourMaps(rfbScreenInfoPtr rfbScreen, int firstColour, int nColours);
744
extern void rfbHttpInitSockets(rfbScreenInfoPtr rfbScreen);
745
extern void rfbHttpShutdownSockets(rfbScreenInfoPtr rfbScreen);
746
extern void rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen);
752
extern void rfbAuthNewClient(rfbClientPtr cl);
753
extern void rfbProcessClientSecurityType(rfbClientPtr cl);
754
extern void rfbAuthProcessClientMessage(rfbClientPtr cl);
755
extern void rfbRegisterSecurityHandler(rfbSecurityHandler* handler);
756
extern void rfbUnregisterSecurityHandler(rfbSecurityHandler* handler);
760
extern rfbBool rfbSendRectEncodingRRE(rfbClientPtr cl, int x,int y,int w,int h);
765
extern rfbBool rfbSendRectEncodingCoRRE(rfbClientPtr cl, int x,int y,int w,int h);
770
extern rfbBool rfbSendRectEncodingHextile(rfbClientPtr cl, int x, int y, int w,
775
/* Set maximum ultra rectangle size in pixels. Always allow at least
778
#define ULTRA_MAX_RECT_SIZE (128*256)
779
#define ULTRA_MAX_SIZE(min) ((( min * 2 ) > ULTRA_MAX_RECT_SIZE ) ? \
780
( min * 2 ) : ULTRA_MAX_RECT_SIZE )
782
extern rfbBool rfbSendRectEncodingUltra(rfbClientPtr cl, int x,int y,int w,int h);
785
#ifdef LIBVNCSERVER_HAVE_LIBZ
788
/** Minimum zlib rectangle size in bytes. Anything smaller will
789
* not compress well due to overhead.
791
#define VNC_ENCODE_ZLIB_MIN_COMP_SIZE (17)
793
/* Set maximum zlib rectangle size in pixels. Always allow at least
796
#define ZLIB_MAX_RECT_SIZE (128*256)
797
#define ZLIB_MAX_SIZE(min) ((( min * 2 ) > ZLIB_MAX_RECT_SIZE ) ? \
798
( min * 2 ) : ZLIB_MAX_RECT_SIZE )
800
extern rfbBool rfbSendRectEncodingZlib(rfbClientPtr cl, int x, int y, int w,
803
#ifdef LIBVNCSERVER_HAVE_LIBJPEG
806
#define TIGHT_DEFAULT_COMPRESSION 6
808
extern rfbBool rfbTightDisableGradient;
810
extern int rfbNumCodedRectsTight(rfbClientPtr cl, int x,int y,int w,int h);
811
extern rfbBool rfbSendRectEncodingTight(rfbClientPtr cl, int x,int y,int w,int h);
819
typedef struct rfbCursor {
820
/** set this to true if LibVNCServer has to free this cursor */
821
rfbBool cleanup, cleanupSource, cleanupMask, cleanupRichSource;
822
unsigned char *source; /**< points to bits */
823
unsigned char *mask; /**< points to bits */
824
unsigned short width, height, xhot, yhot; /**< metrics */
825
unsigned short foreRed, foreGreen, foreBlue; /**< device-independent colour */
826
unsigned short backRed, backGreen, backBlue; /**< device-independent colour */
827
unsigned char *richSource; /**< source bytes for a rich cursor */
828
unsigned char *alphaSource; /**< source for alpha blending info */
829
rfbBool alphaPreMultiplied; /**< if richSource already has alpha applied */
830
} rfbCursor, *rfbCursorPtr;
831
extern unsigned char rfbReverseByte[0x100];
833
extern rfbBool rfbSendCursorShape(rfbClientPtr cl/*, rfbScreenInfoPtr pScreen*/);
834
extern rfbBool rfbSendCursorPos(rfbClientPtr cl);
835
extern void rfbConvertLSBCursorBitmapOrMask(int width,int height,unsigned char* bitmap);
836
extern rfbCursorPtr rfbMakeXCursor(int width,int height,char* cursorString,char* maskString);
837
extern char* rfbMakeMaskForXCursor(int width,int height,char* cursorString);
838
extern char* rfbMakeMaskFromAlphaSource(int width,int height,unsigned char* alphaSource);
839
extern void rfbMakeXCursorFromRichCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr cursor);
840
extern void rfbMakeRichCursorFromXCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr cursor);
841
extern void rfbFreeCursor(rfbCursorPtr cursor);
842
extern void rfbSetCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr c);
844
/** cursor handling for the pointer */
845
extern void rfbDefaultPtrAddEvent(int buttonMask,int x,int y,rfbClientPtr cl);
848
#ifdef LIBVNCSERVER_HAVE_LIBZ
849
extern rfbBool rfbSendRectEncodingZRLE(rfbClientPtr cl, int x, int y, int w,int h);
854
extern void rfbResetStats(rfbClientPtr cl);
855
extern void rfbPrintStats(rfbClientPtr cl);
859
typedef struct rfbFontData {
862
metaData is a 256*5 array:
864
(offset,width,height,x,y)
867
} rfbFontData,* rfbFontDataPtr;
869
int rfbDrawChar(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,unsigned char c,rfbPixel colour);
870
void rfbDrawString(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,const char* string,rfbPixel colour);
871
/** if colour==backColour, background is transparent */
872
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);
873
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);
874
int rfbWidthOfString(rfbFontDataPtr font,const char* string);
875
int rfbWidthOfChar(rfbFontDataPtr font,unsigned char c);
876
void rfbFontBBox(rfbFontDataPtr font,unsigned char c,int* x1,int* y1,int* x2,int* y2);
877
/** this returns the smallest box enclosing any character of font. */
878
void rfbWholeFontBBox(rfbFontDataPtr font,int *x1, int *y1, int *x2, int *y2);
880
/** dynamically load a linux console font (4096 bytes, 256 glyphs a 8x16 */
881
rfbFontDataPtr rfbLoadConsoleFont(char *filename);
882
/** free a dynamically loaded font */
883
void rfbFreeFont(rfbFontDataPtr font);
887
void rfbFillRect(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2,rfbPixel col);
888
void rfbDrawPixel(rfbScreenInfoPtr s,int x,int y,rfbPixel col);
889
void rfbDrawLine(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2,rfbPixel col);
893
/** this opens a modal select box. list is an array of strings, the end marked
895
It returns the index in the list or -1 if cancelled or something else
897
typedef void (*SelectionChangedHookPtr)(int _index);
898
extern int rfbSelectBox(rfbScreenInfoPtr rfbScreen,
899
rfbFontDataPtr font, char** list,
900
int x1, int y1, int x2, int y2,
901
rfbPixel foreColour, rfbPixel backColour,
902
int border,SelectionChangedHookPtr selChangedHook);
906
extern void rfbUsage(void);
907
extern void rfbPurgeArguments(int* argc,int* position,int count,char *argv[]);
908
extern rfbBool rfbProcessArguments(rfbScreenInfoPtr rfbScreen,int* argc, char *argv[]);
909
extern rfbBool rfbProcessSizeArguments(int* width,int* height,int* bpp,int* argc, char *argv[]);
913
extern void rfbLogEnable(int enabled);
914
typedef void (*rfbLogProc)(const char *format, ...);
915
extern rfbLogProc rfbLog, rfbErr;
916
extern void rfbLogPerror(const char *str);
918
void rfbScheduleCopyRect(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2,int dx,int dy);
919
void rfbScheduleCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,int dy);
921
void rfbDoCopyRect(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2,int dx,int dy);
922
void rfbDoCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,int dy);
924
void rfbMarkRectAsModified(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2);
925
void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,sraRegionPtr modRegion);
926
void rfbDoNothingWithClient(rfbClientPtr cl);
927
enum rfbNewClientAction defaultNewClientHook(rfbClientPtr cl);
928
void rfbRegisterProtocolExtension(rfbProtocolExtension* extension);
929
void rfbUnregisterProtocolExtension(rfbProtocolExtension* extension);
930
struct _rfbProtocolExtension* rfbGetExtensionIterator();
931
void rfbReleaseExtensionIterator();
932
rfbBool rfbEnableExtension(rfbClientPtr cl, rfbProtocolExtension* extension,
934
rfbBool rfbDisableExtension(rfbClientPtr cl, rfbProtocolExtension* extension);
935
void* rfbGetExtensionClientData(rfbClientPtr cl, rfbProtocolExtension* extension);
937
/** to check against plain passwords */
938
rfbBool rfbCheckPasswordByList(rfbClientPtr cl,const char* response,int len);
940
/* functions to make a vnc server */
941
extern rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
942
int width,int height,int bitsPerSample,int samplesPerPixel,
944
extern void rfbInitServer(rfbScreenInfoPtr rfbScreen);
945
extern void rfbShutdownServer(rfbScreenInfoPtr rfbScreen,rfbBool disconnectClients);
946
extern void rfbNewFramebuffer(rfbScreenInfoPtr rfbScreen,char *framebuffer,
947
int width,int height, int bitsPerSample,int samplesPerPixel,
950
extern void rfbScreenCleanup(rfbScreenInfoPtr screenInfo);
951
extern void rfbSetServerVersionIdentity(rfbScreenInfoPtr screen, char *fmt, ...);
953
/* functions to accept/refuse a client that has been put on hold
954
by a NewClientHookPtr function. Must not be called in other
956
extern void rfbStartOnHoldClient(rfbClientPtr cl);
957
extern void rfbRefuseOnHoldClient(rfbClientPtr cl);
959
/* call one of these two functions to service the vnc clients.
960
usec are the microseconds the select on the fds waits.
961
if you are using the event loop, set this to some value > 0, so the
962
server doesn't get a high load just by listening.
963
rfbProcessEvents() returns TRUE if an update was pending. */
965
extern void rfbRunEventLoop(rfbScreenInfoPtr screenInfo, long usec, rfbBool runInBackground);
966
extern rfbBool rfbProcessEvents(rfbScreenInfoPtr screenInfo,long usec);
967
extern rfbBool rfbIsActive(rfbScreenInfoPtr screenInfo);
969
/* TightVNC file transfer extension */
970
void rfbRegisterTightVNCFileTransferExtension();
971
void rfbUnregisterTightVNCFileTransferExtension();
974
extern char *messageNameServer2Client(uint32_t type, char *buf, int len);
975
extern char *messageNameClient2Server(uint32_t type, char *buf, int len);
976
extern char *encodingName(uint32_t enc, char *buf, int len);
978
extern rfbStatList *rfbStatLookupEncoding(rfbClientPtr cl, uint32_t type);
979
extern rfbStatList *rfbStatLookupMessage(rfbClientPtr cl, uint32_t type);
981
/* Each call to rfbStatRecord* adds one to the rect count for that type */
982
extern void rfbStatRecordEncodingSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
983
extern void rfbStatRecordEncodingSentAdd(rfbClientPtr cl, uint32_t type, int byteCount); /* Specifically for tight encoding */
984
extern void rfbStatRecordEncodingRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
985
extern void rfbStatRecordMessageSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
986
extern void rfbStatRecordMessageRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
987
extern void rfbResetStats(rfbClientPtr cl);
988
extern void rfbPrintStats(rfbClientPtr cl);
990
extern int rfbStatGetSentBytes(rfbClientPtr cl);
991
extern int rfbStatGetSentBytesIfRaw(rfbClientPtr cl);
992
extern int rfbStatGetRcvdBytes(rfbClientPtr cl);
993
extern int rfbStatGetRcvdBytesIfRaw(rfbClientPtr cl);
994
extern int rfbStatGetMessageCountSent(rfbClientPtr cl, uint32_t type);
995
extern int rfbStatGetMessageCountRcvd(rfbClientPtr cl, uint32_t type);
996
extern int rfbStatGetEncodingCountSent(rfbClientPtr cl, uint32_t type);
997
extern int rfbStatGetEncodingCountRcvd(rfbClientPtr cl, uint32_t type);
999
/** Set which version you want to advertise 3.3, 3.6, 3.7 and 3.8 are currently supported*/
1000
extern void rfbSetProtocolVersion(rfbScreenInfoPtr rfbScreen, int major_, int minor_);
1002
/** send a TextChat message to a client */
1003
extern rfbBool rfbSendTextChatMessage(rfbClientPtr cl, uint32_t length, char *buffer);
1008
#if(defined __cplusplus)
1018
@page libvncserver_doc LibVNCServer Documentation
1019
@section create_server Creating a server instance
1020
To make a server, you just have to initialise a server structure using the
1021
function rfbGetScreen(), like
1023
rfbScreenInfoPtr screen =
1024
rfbGetScreen(argc,argv,screenwidth,screenheight,8,3,bpp);
1026
where byte per pixel should be 1, 2 or 4. If performance doesn't matter,
1027
you may try bpp=3 (internally one cannot use native data types in this
1028
case; if you want to use this, look at pnmshow24.c).
1030
You then can set hooks and io functions (see @ref making_it_interactive) or other
1031
options (see @ref server_options).
1033
And you allocate the frame buffer like this:
1035
screen->frameBuffer = (char*)malloc(screenwidth*screenheight*bpp);
1037
After that, you initialize the server, like
1039
rfbInitServer(screen);
1041
You can use a blocking event loop, a background (pthread based) event loop,
1042
or implement your own using the rfbProcessEvents() function.
1044
@subsection server_options Optional Server Features
1046
These options have to be set between rfbGetScreen() and rfbInitServer().
1048
If you already have a socket to talk to, just set rfbScreenInfo::inetdSock
1049
(originally this is for inetd handling, but why not use it for your purpose?).
1051
To also start an HTTP server (running on port 5800+display_number), you have
1052
to set rfbScreenInfo::httpDir to a directory containing vncviewer.jar and
1053
index.vnc (like the included "classes" directory).
1055
@section making_it_interactive Making it interactive
1057
Whenever you draw something, you have to call
1059
rfbMarkRectAsModified(screen,x1,y1,x2,y2).
1061
This tells LibVNCServer to send updates to all connected clients.
1063
There exist the following IO functions as members of rfbScreen:
1064
rfbScreenInfo::kbdAddEvent(), rfbScreenInfo::kbdReleaseAllKeys(), rfbScreenInfo::ptrAddEvent() and rfbScreenInfo::setXCutText()
1066
rfbScreenInfo::kbdAddEvent()
1067
is called when a key is pressed.
1068
rfbScreenInfo::kbdReleaseAllKeys()
1069
is not called at all (maybe in the future).
1070
rfbScreenInfo::ptrAddEvent()
1071
is called when the mouse moves or a button is pressed.
1072
WARNING: if you want to have proper cursor handling, call
1073
rfbDefaultPtrAddEvent()
1074
in your own function. This sets the coordinates of the cursor.
1075
rfbScreenInfo::setXCutText()
1076
is called when the selection changes.
1078
There are only two hooks:
1079
rfbScreenInfo::newClientHook()
1080
is called when a new client has connected.
1081
rfbScreenInfo::displayHook()
1082
is called just before a frame buffer update is sent.
1084
You can also override the following methods:
1085
rfbScreenInfo::getCursorPtr()
1086
This could be used to make an animated cursor (if you really want ...)
1087
rfbScreenInfo::setTranslateFunction()
1088
If you insist on colour maps or something more obscure, you have to
1089
implement this. Default is a trueColour mapping.
1091
@section cursor_handling Cursor handling
1093
The screen holds a pointer
1094
rfbScreenInfo::cursor
1095
to the current cursor. Whenever you set it, remember that any dynamically
1096
created cursor (like return value from rfbMakeXCursor()) is not free'd!
1098
The rfbCursor structure consists mainly of a mask and a source. The rfbCursor::mask
1099
describes, which pixels are drawn for the cursor (a cursor needn't be
1100
rectangular). The rfbCursor::source describes, which colour those pixels should have.
1102
The standard is an XCursor: a cursor with a foreground and a background
1103
colour (stored in backRed,backGreen,backBlue and the same for foreground
1104
in a range from 0-0xffff). Therefore, the arrays "mask" and "source"
1105
contain pixels as single bits stored in bytes in MSB order. The rows are
1106
padded, such that each row begins with a new byte (i.e. a 10x4
1107
cursor's mask has 2x4 bytes, because 2 bytes are needed to hold 10 bits).
1109
It is however very easy to make a cursor like this:
1119
rfbCursorPtr c=rfbMakeXCursor(4,4,cur,mask);
1121
You can even set rfbCursor::mask to NULL in this call and LibVNCServer will calculate
1122
a mask for you (dynamically, so you have to free it yourself).
1124
There is also an array named rfbCursor::richSource for colourful cursors. They have
1125
the same format as the frameBuffer (i.e. if the server is 32 bit,
1126
a 10x4 cursor has 4x10x4 bytes).
1128
@section screen_client_difference What is the difference between rfbScreenInfoPtr and rfbClientPtr?
1130
The rfbScreenInfoPtr is a pointer to a rfbScreenInfo structure, which
1131
holds information about the server, like pixel format, io functions,
1132
frame buffer etc. The rfbClientPtr is a pointer to an rfbClientRec structure, which holds
1133
information about a client, like pixel format, socket of the
1134
connection, etc. A server can have several clients, but needn't have any. So, if you
1135
have a server and three clients are connected, you have one instance
1136
of a rfbScreenInfo and three instances of rfbClientRec's.
1138
The rfbClientRec structure holds a member rfbClientRec::screen which points to the server.
1139
So, to access the server from the client structure, you use client->screen.
1141
To access all clients from a server be sure to use the provided iterator
1142
rfbGetClientIterator()
1144
rfbClientIteratorNext()
1146
rfbReleaseClientIterator()
1147
to prevent thread clashes.
1149
@section example_code Example Code
1151
There are two documented examples included:
1152
- example.c, a shared scribble sheet
1153
- pnmshow.c, a program to show PNMs (pictures) over the net.
1155
The examples are not too well documented, but easy straight forward and a
1156
good starting point.
1158
Try example.c: it outputs on which port it listens (default: 5900), so it is
1159
display 0. To view, call @code vncviewer :0 @endcode
1160
You should see a sheet with a gradient and "Hello World!" written on it. Try
1161
to paint something. Note that everytime you click, there is some bigger blot,
1162
whereas when you drag the mouse while clicked you draw a line. The size of the
1163
blot depends on the mouse button you click. Open a second vncviewer with
1164
the same parameters and watch it as you paint in the other window. This also
1165
works over internet. You just have to know either the name or the IP of your
1166
machine. Then it is @code vncviewer machine.where.example.runs.com:0 @endcode
1167
or similar for the remote client. Now you are ready to type something. Be sure
1168
that your mouse sits still, because everytime the mouse moves, the cursor is
1169
reset to the position of the pointer! If you are done with that demo, press
1170
the down or up arrows. If your viewer supports it, then the dimensions of the
1171
sheet change. Just press Escape in the viewer. Note that the server still
1172
runs, even if you closed both windows. When you reconnect now, everything you
1173
painted and wrote is still there. You can press "Page Up" for a blank page.
1175
The demo pnmshow.c is much simpler: you either provide a filename as argument
1176
or pipe a file through stdin. Note that the file has to be a raw pnm/ppm file,
1177
i.e. a truecolour graphics. Only the Escape key is implemented. This may be
1178
the best starting point if you want to learn how to use LibVNCServer. You
1179
are confronted with the fact that the bytes per pixel can only be 8, 16 or 32.