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