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