rfb.h 28.7 KB
Newer Older
dscho's avatar
dscho committed
1 2 3
#ifndef RFB_H
#define RFB_H

dscho's avatar
dscho committed
4 5 6 7 8
/*
 * rfb.h - header file for RFB DDX implementation.
 */

/*
9
 *  Copyright (C) 2002 RealVNC Ltd.
dscho's avatar
dscho committed
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
 *  OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
 *  Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.  
 *  All Rights Reserved.
 *
 *  This is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This software is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this software; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
 *  USA.
 */

30 31 32 33 34
#if(defined __cplusplus)
extern "C"
{
#endif

35
#include <stdio.h>
36 37
#include <stdlib.h>
#include <string.h>
dscho's avatar
dscho committed
38
#include "rfbconfig.h"
39
#include "rfbint.h"
40
#include "keysym.h"
dscho's avatar
dscho committed
41

dscho's avatar
dscho committed
42 43 44 45
#ifdef HAVE_LIBZ
#include <zlib.h>
#endif

46
#include "rfbproto.h"
dscho's avatar
dscho committed
47

48
#ifdef HAVE_SYS_TYPES_H
dscho's avatar
dscho committed
49
#include <sys/types.h>
50 51
#endif

52 53
#if defined(WIN32)
#define WORDS_BIGENDIAN
54 55
#undef Bool
#define Bool int
56
#include <sys/timeb.h>
57 58 59 60
#include <winsock.h>
#undef SOCKET
#define SOCKET int
#else
61
#define max(a,b) (((a)>(b))?(a):(b))
62
#ifdef HAVE_SYS_TIME_H
63
#include <sys/time.h>
64 65
#endif
#ifdef HAVE_NETINET_IN_H
dscho's avatar
dscho committed
66
#include <netinet/in.h>
67
#endif
68
#define SOCKET int
69 70 71 72 73 74
#ifndef Bool
typedef int8_t Bool;
#undef FALSE
#define FALSE 0
#undef TRUE
#define TRUE -1
75
#endif
76 77 78 79
#endif

typedef uint32_t KeySym;
typedef uint32_t Pixel;
dscho's avatar
dscho committed
80

dscho's avatar
dscho committed
81 82 83 84
#ifndef INADDR_NONE
#define                INADDR_NONE     ((in_addr_t) 0xffffffff)
#endif

dscho's avatar
dscho committed
85
#ifdef HAVE_LIBPTHREAD
86
#include <pthread.h>
87
#if 0 /* debugging */
88 89 90 91 92 93 94 95 96 97 98
#define LOCK(mutex) (fprintf(stderr,"%s:%d LOCK(%s,0x%x)\n",__FILE__,__LINE__,#mutex,&(mutex)), pthread_mutex_lock(&(mutex)))
#define UNLOCK(mutex) (fprintf(stderr,"%s:%d UNLOCK(%s,0x%x)\n",__FILE__,__LINE__,#mutex,&(mutex)), pthread_mutex_unlock(&(mutex)))
#define MUTEX(mutex) pthread_mutex_t (mutex)
#define INIT_MUTEX(mutex) (fprintf(stderr,"%s:%d INIT_MUTEX(%s,0x%x)\n",__FILE__,__LINE__,#mutex,&(mutex)), pthread_mutex_init(&(mutex),NULL))
#define TINI_MUTEX(mutex) (fprintf(stderr,"%s:%d TINI_MUTEX(%s)\n",__FILE__,__LINE__,#mutex), pthread_mutex_destroy(&(mutex)))
#define TSIGNAL(cond) (fprintf(stderr,"%s:%d TSIGNAL(%s)\n",__FILE__,__LINE__,#cond), pthread_cond_signal(&(cond)))
#define WAIT(cond,mutex) (fprintf(stderr,"%s:%d WAIT(%s,%s)\n",__FILE__,__LINE__,#cond,#mutex), pthread_cond_wait(&(cond),&(mutex)))
#define COND(cond) pthread_cond_t (cond)
#define INIT_COND(cond) (fprintf(stderr,"%s:%d INIT_COND(%s)\n",__FILE__,__LINE__,#cond), pthread_cond_init(&(cond),NULL))
#define TINI_COND(cond) (fprintf(stderr,"%s:%d TINI_COND(%s)\n",__FILE__,__LINE__,#cond), pthread_cond_destroy(&(cond)))
#define IF_PTHREADS(x) x
99
#else
100 101
#define LOCK(mutex) pthread_mutex_lock(&(mutex));
#define UNLOCK(mutex) pthread_mutex_unlock(&(mutex));
102 103 104
#define MUTEX(mutex) pthread_mutex_t (mutex)
#define INIT_MUTEX(mutex) pthread_mutex_init(&(mutex),NULL)
#define TINI_MUTEX(mutex) pthread_mutex_destroy(&(mutex))
105
#define TSIGNAL(cond) pthread_cond_signal(&(cond))
106 107 108 109 110 111 112 113 114 115 116 117
#define WAIT(cond,mutex) pthread_cond_wait(&(cond),&(mutex))
#define COND(cond) pthread_cond_t (cond)
#define INIT_COND(cond) pthread_cond_init(&(cond),NULL)
#define TINI_COND(cond) pthread_cond_destroy(&(cond))
#define IF_PTHREADS(x) x
#endif
#else
#define LOCK(mutex)
#define UNLOCK(mutex)
#define MUTEX(mutex)
#define INIT_MUTEX(mutex)
#define TINI_MUTEX(mutex)
118
#define TSIGNAL(cond)
119 120 121 122 123 124 125
#define WAIT(cond,mutex) this_is_unsupported
#define COND(cond)
#define INIT_COND(cond)
#define TINI_COND(cond)
#define IF_PTHREADS(x)
#endif

126 127
/* end of stuff for autoconf */

dscho's avatar
dscho committed
128
/* if you use pthreads, but don't define HAVE_LIBPTHREAD, the structs
129 130 131
   get all mixed up. So this gives a linker error reminding you to compile
   the library and your application (at least the parts including rfb.h)
   with the same support for pthreads. */
dscho's avatar
dscho committed
132
#ifdef HAVE_LIBPTHREAD
133 134 135 136 137 138 139 140
#ifdef HAVE_ZRLE
#define rfbInitServer rfbInitServerWithPthreadsAndZRLE
#else
#define rfbInitServer rfbInitServerWithPthreadsButWithoutZRLE
#endif
#else
#ifdef HAVE_ZRLE
#define rfbInitServer rfbInitServerWithoutPthreadsButWithZRLE
141
#else
142 143
#define rfbInitServer rfbInitServerWithoutPthreadsAndZRLE
#endif
144 145
#endif

dscho's avatar
dscho committed
146
#define MAX_ENCODINGS 10
147

148 149
struct _rfbClientRec;
struct _rfbScreenInfo;
150 151
struct rfbCursor;

152 153 154 155 156 157 158 159 160 161 162 163
enum rfbNewClientAction {
	RFB_CLIENT_ACCEPT,
	RFB_CLIENT_ON_HOLD,
	RFB_CLIENT_REFUSE
};

typedef void (*KbdAddEventProcPtr) (Bool down, KeySym keySym, struct _rfbClientRec* cl);
typedef void (*KbdReleaseAllKeysProcPtr) (struct _rfbClientRec* cl);
typedef void (*PtrAddEventProcPtr) (int buttonMask, int x, int y, struct _rfbClientRec* cl);
typedef void (*SetXCutTextProcPtr) (char* str,int len, struct _rfbClientRec* cl);
typedef struct rfbCursor* (*GetCursorProcPtr) (struct _rfbClientRec* pScreen);
typedef Bool (*SetTranslateFunctionProcPtr)(struct _rfbClientRec* cl);
dscho's avatar
dscho committed
164
typedef Bool (*PasswordCheckProcPtr)(struct _rfbClientRec* cl,const char* encryptedPassWord,int len);
165 166
typedef enum rfbNewClientAction (*NewClientHookPtr)(struct _rfbClientRec* cl);
typedef void (*DisplayHookPtr)(struct _rfbClientRec* cl);
dscho's avatar
dscho committed
167

168
typedef struct {
169
  uint32_t count;
170 171
  Bool is16; /* is the data format short? */
  union {
172 173
    uint8_t* bytes;
    uint16_t* shorts;
174 175 176
  } data; /* there have to be count*3 entries */
} rfbColourMap;

dscho's avatar
dscho committed
177
/*
178 179 180
 * Per-screen (framebuffer) structure.  There can be as many as you wish,
 * each serving different clients. However, you have to call
 * rfbProcessEvents for each of these.
dscho's avatar
dscho committed
181 182
 */

183
typedef struct _rfbScreenInfo
dscho's avatar
dscho committed
184 185 186 187 188 189 190 191 192 193 194
{
    int width;
    int paddedWidthInBytes;
    int height;
    int depth;
    int bitsPerPixel;
    int sizeInBytes;

    Pixel blackPixel;
    Pixel whitePixel;

195 196 197 198 199 200
    /* some screen specific data can be put into a struct where screenData
     * points to. You need this if you have more than one screen at the
     * same time while using the same functions.
     */
    void* screenData;
  
dscho's avatar
dscho committed
201 202 203 204 205 206 207 208 209 210 211 212 213
    /* The following two members are used to minimise the amount of unnecessary
       drawing caused by cursor movement.  Whenever any drawing affects the
       part of the screen where the cursor is, the cursor is removed first and
       then the drawing is done (this is what the sprite routines test for).
       Afterwards, however, we do not replace the cursor, even when the cursor
       is logically being moved across the screen.  We only draw the cursor
       again just as we are about to send the client a framebuffer update.

       We need to be careful when removing and drawing the cursor because of
       their relationship with the normal drawing routines.  The drawing
       routines can invoke the cursor routines, but also the cursor routines
       themselves end up invoking drawing routines.

dscho's avatar
dscho committed
214
       Removing the cursor (rfbUndrawCursor) is eventually achieved by
dscho's avatar
dscho committed
215 216 217 218 219 220
       doing a CopyArea from a pixmap to the screen, where the pixmap contains
       the saved contents of the screen under the cursor.  Before doing this,
       however, we set cursorIsDrawn to FALSE.  Then, when CopyArea is called,
       it sees that cursorIsDrawn is FALSE and so doesn't feel the need to
       (recursively!) remove the cursor before doing it.

dscho's avatar
dscho committed
221
       Putting up the cursor (rfbDrawCursor) involves a call to
dscho's avatar
dscho committed
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
       PushPixels.  While this is happening, cursorIsDrawn must be FALSE so
       that PushPixels doesn't think it has to remove the cursor first.
       Obviously cursorIsDrawn is set to TRUE afterwards.

       Another problem we face is that drawing routines sometimes cause a
       framebuffer update to be sent to the RFB client.  When the RFB client is
       already waiting for a framebuffer update and some drawing to the
       framebuffer then happens, the drawing routine sees that the client is
       ready, so it calls rfbSendFramebufferUpdate.  If the cursor is not drawn
       at this stage, it must be put up, and so rfbSpriteRestoreCursor is
       called.  However, if the original drawing routine was actually called
       from within rfbSpriteRestoreCursor or rfbSpriteRemoveCursor we don't
       want this to happen.  So both the cursor routines set
       dontSendFramebufferUpdate to TRUE, and all the drawing routines check
       this before calling rfbSendFramebufferUpdate. */

    Bool cursorIsDrawn;		    /* TRUE if the cursor is currently drawn */
    Bool dontSendFramebufferUpdate; /* TRUE while removing or drawing the
				       cursor */
241
   
dscho's avatar
dscho committed
242
    /* additions by libvncserver */
243

dscho's avatar
dscho committed
244
    rfbPixelFormat rfbServerFormat;
245
    rfbColourMap colourMap; /* set this if rfbServerFormat.trueColour==FALSE */
dscho's avatar
dscho committed
246
    const char* desktopName;
dscho's avatar
dscho committed
247
    char rfbThisHost[255];
248

249
    Bool autoPort;
dscho's avatar
dscho committed
250
    int rfbPort;
251
    SOCKET rfbListenSock;
dscho's avatar
dscho committed
252 253
    int maxSock;
    int maxFd;
254 255 256 257 258 259
    fd_set allFds;

    Bool socketInitDone;
    SOCKET inetdSock;
    Bool inetdInitDone;

dscho's avatar
dscho committed
260
    int udpPort;
261
    SOCKET udpSock;
262
    struct _rfbClientRec* udpClient;
dscho's avatar
dscho committed
263 264
    Bool udpSockConnected;
    struct sockaddr_in udpRemoteAddr;
265

dscho's avatar
dscho committed
266
    int rfbMaxClientWait;
267 268

    /* http stuff */
dscho's avatar
dscho committed
269
    Bool httpInitDone;
270
    Bool httpEnableProxyConnect;
dscho's avatar
dscho committed
271 272
    int httpPort;
    char* httpDir;
273 274
    SOCKET httpListenSock;
    SOCKET httpSock;
dscho's avatar
dscho committed
275

276
    PasswordCheckProcPtr passwordCheck;
277
    void* rfbAuthPasswdData;
278

dscho's avatar
dscho committed
279 280
    /* this is the amount of milliseconds to wait at least before sending
     * an update. */
dscho's avatar
dscho committed
281 282 283 284 285
    int rfbDeferUpdateTime;
    char* rfbScreen;
    Bool rfbAlwaysShared;
    Bool rfbNeverShared;
    Bool rfbDontDisconnect;
286
    struct _rfbClientRec* rfbClientHead;
287 288 289 290 291

    /* cursor */
    int cursorX, cursorY,underCursorBufferLen;
    char* underCursorBuffer;
    Bool dontConvertRichCursorToXCursor;
292
    struct rfbCursor* cursor;
293

dscho's avatar
dscho committed
294 295 296
    /* the frameBufferhas to be supplied by the serving process.
     * The buffer will not be freed by 
     */
dscho's avatar
dscho committed
297 298 299 300 301
    char* frameBuffer;
    KbdAddEventProcPtr kbdAddEvent;
    KbdReleaseAllKeysProcPtr kbdReleaseAllKeys;
    PtrAddEventProcPtr ptrAddEvent;
    SetXCutTextProcPtr setXCutText;
302
    GetCursorProcPtr getCursorPtr;
303 304
    SetTranslateFunctionProcPtr setTranslateFunction;
  
dscho's avatar
dscho committed
305 306
    /* newClientHook is called just after a new client is created */
    NewClientHookPtr newClientHook;
dscho's avatar
dscho committed
307 308
    /* displayHook is called just before a frame buffer update */
    DisplayHookPtr displayHook;
dscho's avatar
dscho committed
309

dscho's avatar
dscho committed
310
#ifdef HAVE_LIBPTHREAD
311
    MUTEX(cursorMutex);
dscho's avatar
dscho committed
312 313 314
    Bool backgroundLoop;
#endif

dscho's avatar
dscho committed
315 316 317 318 319 320 321 322 323 324 325 326 327 328
} rfbScreenInfo, *rfbScreenInfoPtr;


/*
 * rfbTranslateFnType is the type of translation functions.
 */

typedef void (*rfbTranslateFnType)(char *table, rfbPixelFormat *in,
                                   rfbPixelFormat *out,
                                   char *iptr, char *optr,
                                   int bytesBetweenInputLines,
                                   int width, int height);


dscho's avatar
dscho committed
329 330 331 332 333 334 335 336 337 338 339 340
/* 
 * vncauth.h - describes the functions provided by the vncauth library.
 */

#define MAXPWLEN 8
#define CHALLENGESIZE 16

extern int vncEncryptAndStorePasswd(char *passwd, char *fname);
extern char *vncDecryptPasswdFromFile(char *fname);
extern void vncRandomBytes(unsigned char *bytes);
extern void vncEncryptBytes(unsigned char *bytes, char *passwd);

341 342
/* region stuff */

343 344
struct sraRegion;
typedef struct sraRegion* sraRegionPtr;
345

dscho's avatar
dscho committed
346 347 348 349
/*
 * Per-client structure.
 */

350
typedef void (*ClientGoneHookPtr)(struct _rfbClientRec* cl);
dscho's avatar
dscho committed
351

352
typedef struct _rfbClientRec {
353 354
  
    /* back pointer to the screen */
dscho's avatar
dscho committed
355
    rfbScreenInfoPtr screen;
356 357 358 359
  
    /* private data. You should put any application client specific data
     * into a struct and let clientData point to it. Don't forget to
     * free the struct via clientGoneHook!
360 361
     *
     * This is useful if the IO functions have to behave client specific.
362
     */
dscho's avatar
dscho committed
363 364
    void* clientData;
    ClientGoneHookPtr clientGoneHook;
365

366
    SOCKET sock;
dscho's avatar
dscho committed
367
    char *host;
368

dscho's avatar
dscho committed
369
#ifdef HAVE_LIBPTHREAD
370 371
    pthread_t client_thread;
#endif
dscho's avatar
dscho committed
372 373 374 375 376 377 378 379 380
                                /* Possible client states: */
    enum {
        RFB_PROTOCOL_VERSION,   /* establishing protocol version */
        RFB_AUTHENTICATION,     /* authenticating */
        RFB_INITIALISATION,     /* sending initialisation messages */
        RFB_NORMAL              /* normal protocol messages */
    } state;

    Bool reverseConnection;
381
    Bool onHold;
dscho's avatar
dscho committed
382 383 384 385 386 387
    Bool readyForSetColourMapEntries;
    Bool useCopyRect;
    int preferredEncoding;
    int correMaxWidth, correMaxHeight;

    /* The following member is only used during VNC authentication */
388
    uint8_t authChallenge[CHALLENGESIZE];
dscho's avatar
dscho committed
389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412

    /* The following members represent the update needed to get the client's
       framebuffer from its present state to the current state of our
       framebuffer.

       If the client does not accept CopyRect encoding then the update is
       simply represented as the region of the screen which has been modified
       (modifiedRegion).

       If the client does accept CopyRect encoding, then the update consists of
       two parts.  First we have a single copy from one region of the screen to
       another (the destination of the copy is copyRegion), and second we have
       the region of the screen which has been modified in some other way
       (modifiedRegion).

       Although the copy is of a single region, this region may have many
       rectangles.  When sending an update, the copyRegion is always sent
       before the modifiedRegion.  This is because the modifiedRegion may
       overlap parts of the screen which are in the source of the copy.

       In fact during normal processing, the modifiedRegion may even overlap
       the destination copyRegion.  Just before an update is sent we remove
       from the copyRegion anything in the modifiedRegion. */

413
    sraRegionPtr copyRegion;	/* the destination region of the copy */
dscho's avatar
dscho committed
414 415
    int copyDX, copyDY;		/* the translation by which the copy happens */

416
    sraRegionPtr modifiedRegion;
dscho's avatar
dscho committed
417 418 419 420 421 422

    /* As part of the FramebufferUpdateRequest, a client can express interest
       in a subrectangle of the whole framebuffer.  This is stored in the
       requestedRegion member.  In the normal case this is the whole
       framebuffer if the client is ready, empty if it's not. */

423
    sraRegionPtr requestedRegion;
dscho's avatar
dscho committed
424

dscho's avatar
dscho committed
425
    /* The following member represents the state of the "deferred update" timer
dscho's avatar
dscho committed
426 427 428 429 430
       - when the framebuffer is modified and the client is ready, in most
       cases it is more efficient to defer sending the update by a few
       milliseconds so that several changes to the framebuffer can be combined
       into a single update. */

dscho's avatar
dscho committed
431 432
      struct timeval startDeferring;

dscho's avatar
dscho committed
433 434 435 436 437 438 439
    /* translateFn points to the translation function which is used to copy
       and translate a rectangle from the framebuffer to an output buffer. */

    rfbTranslateFnType translateFn;
    char *translateLookupTable;
    rfbPixelFormat format;

440 441 442 443 444
    /*
     * UPDATE_BUF_SIZE must be big enough to send at least one whole line of the
     * framebuffer.  So for a max screen width of say 2K with 32-bit pixels this
     * means 8K minimum.
     */
dscho's avatar
dscho committed
445 446 447 448 449 450 451 452 453 454 455 456

#define UPDATE_BUF_SIZE 30000

    char updateBuf[UPDATE_BUF_SIZE];
    int ublen;

    /* statistics */

    int rfbBytesSent[MAX_ENCODINGS];
    int rfbRectanglesSent[MAX_ENCODINGS];
    int rfbLastRectMarkersSent;
    int rfbLastRectBytesSent;
457 458 459 460
    int rfbCursorShapeBytesSent;
    int rfbCursorShapeUpdatesSent;
    int rfbCursorPosBytesSent;
    int rfbCursorPosUpdatesSent;
dscho's avatar
dscho committed
461 462 463 464 465
    int rfbFramebufferUpdateMessagesSent;
    int rfbRawBytesEquivalent;
    int rfbKeyEventsRcvd;
    int rfbPointerEventsRcvd;

dscho's avatar
dscho committed
466
#ifdef HAVE_LIBZ
dscho's avatar
dscho committed
467 468 469 470
    /* zlib encoding -- necessary compression state info per client */

    struct z_stream_s compStream;
    Bool compStreamInited;
471
    uint32_t zlibCompressLevel;
dscho's avatar
dscho committed
472

dscho's avatar
dscho committed
473
#ifdef HAVE_LIBJPEG
dscho's avatar
dscho committed
474
    /* tight encoding -- preserve zlib streams' state for each client */
dscho's avatar
dscho committed
475
  //#ifdef HAVE_LIBJPEG
dscho's avatar
dscho committed
476 477 478 479 480
    z_stream zsStruct[4];
    Bool zsActive[4];
    int zsLevel[4];
    int tightCompressLevel;
    int tightQualityLevel;
dscho's avatar
dscho committed
481 482
#endif
#endif
dscho's avatar
dscho committed
483 484 485

    Bool enableLastRectEncoding;   /* client supports LastRect encoding */
    Bool enableCursorShapeUpdates; /* client supports cursor shape updates */
486
    Bool enableCursorPosUpdates;   /* client supports cursor position updates */
dscho's avatar
dscho committed
487 488
    Bool useRichCursorEncoding;    /* rfbEncodingRichCursor is preferred */
    Bool cursorWasChanged;         /* cursor shape update should be sent */
489
    Bool cursorWasMoved;           /* cursor position update should be sent */
dscho's avatar
dscho committed
490 491 492 493

    Bool useNewFBSize;             /* client supports NewFBSize encoding */
    Bool newFBSizePending;         /* framebuffer size was changed */

494
#ifdef BACKCHANNEL
dscho's avatar
dscho committed
495
    Bool enableBackChannel;        /* custom channel for special clients */
496
#endif
dscho's avatar
dscho committed
497

498 499
    struct _rfbClientRec *prev;
    struct _rfbClientRec *next;
dscho's avatar
dscho committed
500

dscho's avatar
dscho committed
501
#ifdef HAVE_LIBPTHREAD
dscho's avatar
dscho committed
502
    /* whenever a client is referenced, the refCount has to be incremented
503 504
       and afterwards decremented, so that the client is not cleaned up
       while being referenced.
dscho's avatar
dscho committed
505 506 507 508 509 510 511 512 513 514 515
       Use the functions rfbIncrClientRef(cl) and rfbDecrClientRef(cl);
    */
    int refCount;
    MUTEX(refCountMutex);
    COND(deleteCond);

    MUTEX(outputMutex);
    MUTEX(updateMutex);
    COND(updateCond);
#endif

516 517 518 519
#ifdef HAVE_ZRLE
    void* zrleData;
#endif

dscho's avatar
dscho committed
520 521 522 523 524 525 526
} rfbClientRec, *rfbClientPtr;

/*
 * This macro is used to test whether there is a framebuffer update needing to
 * be sent to the client.
 */

dscho's avatar
dscho committed
527 528 529 530
#define FB_UPDATE_PENDING(cl)                                              \
     ((!(cl)->enableCursorShapeUpdates && !(cl)->screen->cursorIsDrawn) || \
     ((cl)->enableCursorShapeUpdates && (cl)->cursorWasChanged) ||         \
     ((cl)->useNewFBSize && (cl)->newFBSizePending) ||                     \
531
     ((cl)->enableCursorPosUpdates && (cl)->cursorWasMoved) ||             \
532 533
     !sraRgnEmpty((cl)->copyRegion) || !sraRgnEmpty((cl)->modifiedRegion))

dscho's avatar
dscho committed
534 535 536 537 538 539
/*
 * Macros for endian swapping.
 */

#define Swap16(s) ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff))

540 541 542
#define Swap24(l) ((((l) & 0xff) << 16) | (((l) >> 16) & 0xff) | \
                   (((l) & 0x00ff00)))

dscho's avatar
dscho committed
543 544 545 546 547 548
#define Swap32(l) (((l) >> 24) | \
                   (((l) & 0x00ff0000) >> 8)  | \
                   (((l) & 0x0000ff00) << 8)  | \
                   ((l) << 24))


549
extern char rfbEndianTest;
dscho's avatar
dscho committed
550

551
#define Swap16IfLE(s) (rfbEndianTest ? Swap16(s) : (s))
552
#define Swap24IfLE(l) (rfbEndianTest ? Swap24(l) : (l))
553
#define Swap32IfLE(l) (rfbEndianTest ? Swap32(l) : (l))
dscho's avatar
dscho committed
554 555 556 557 558

/* sockets.c */

extern int rfbMaxClientWait;

559 560
extern void rfbInitSockets(rfbScreenInfoPtr rfbScreen);
extern void rfbDisconnectUDPSock(rfbScreenInfoPtr rfbScreen);
dscho's avatar
dscho committed
561 562
extern void rfbCloseClient(rfbClientPtr cl);
extern int ReadExact(rfbClientPtr cl, char *buf, int len);
dscho's avatar
dscho committed
563 564
extern int ReadExactTimeout(rfbClientPtr cl, char *buf, int len,int timeout);
extern int WriteExact(rfbClientPtr cl, const char *buf, int len);
dscho's avatar
dscho committed
565
extern void rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec);
dscho's avatar
dscho committed
566 567
extern int rfbConnect(rfbScreenInfoPtr rfbScreen, char* host, int port);
extern int ConnectToTcpAddr(char* host, int port);
dscho's avatar
dscho committed
568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586
extern int ListenOnTCPPort(int port);
extern int ListenOnUDPPort(int port);

/* rfbserver.c */

extern rfbClientPtr pointerClient;


/* Routines to iterate over the client list in a thread-safe way.
   Only a single iterator can be in use at a time process-wide. */
typedef struct rfbClientIterator *rfbClientIteratorPtr;

extern void rfbClientListInit(rfbScreenInfoPtr rfbScreen);
extern rfbClientIteratorPtr rfbGetClientIterator(rfbScreenInfoPtr rfbScreen);
extern rfbClientPtr rfbClientIteratorNext(rfbClientIteratorPtr iterator);
extern void rfbReleaseClientIterator(rfbClientIteratorPtr iterator);

extern void rfbNewClientConnection(rfbScreenInfoPtr rfbScreen,int sock);
extern rfbClientPtr rfbNewClient(rfbScreenInfoPtr rfbScreen,int sock);
587
extern rfbClientPtr rfbNewUDPClient(rfbScreenInfoPtr rfbScreen);
dscho's avatar
dscho committed
588
extern rfbClientPtr rfbReverseConnection(rfbScreenInfoPtr rfbScreen,char *host, int port);
dscho's avatar
dscho committed
589 590 591 592
extern void rfbClientConnectionGone(rfbClientPtr cl);
extern void rfbProcessClientMessage(rfbClientPtr cl);
extern void rfbClientConnFailed(rfbClientPtr cl, char *reason);
extern void rfbNewUDPConnection(rfbScreenInfoPtr rfbScreen,int sock);
593
extern void rfbProcessUDPInput(rfbScreenInfoPtr rfbScreen);
594
extern Bool rfbSendFramebufferUpdate(rfbClientPtr cl, sraRegionPtr updateRegion);
dscho's avatar
dscho committed
595 596 597
extern Bool rfbSendRectEncodingRaw(rfbClientPtr cl, int x,int y,int w,int h);
extern Bool rfbSendUpdateBuf(rfbClientPtr cl);
extern void rfbSendServerCutText(rfbScreenInfoPtr rfbScreen,char *str, int len);
598
extern Bool rfbSendCopyRegion(rfbClientPtr cl,sraRegionPtr reg,int dx,int dy);
dscho's avatar
dscho committed
599
extern Bool rfbSendLastRectMarker(rfbClientPtr cl);
dscho's avatar
dscho committed
600
extern Bool rfbSendNewFBSize(rfbClientPtr cl, int w, int h);
601
extern Bool rfbSendSetColourMapEntries(rfbClientPtr cl, int firstColour, int nColours);
dscho's avatar
dscho committed
602
extern void rfbSendBell(rfbScreenInfoPtr rfbScreen);
dscho's avatar
dscho committed
603 604 605

void rfbGotXCutText(rfbScreenInfoPtr rfbScreen, char *str, int len);

606 607 608 609
#ifdef BACKCHANNEL
extern void rfbSendBackChannel(rfbScreenInfoPtr s,char* message,int len);
#endif

dscho's avatar
dscho committed
610 611 612 613 614 615 616 617 618 619
/* translate.c */

extern Bool rfbEconomicTranslate;

extern void rfbTranslateNone(char *table, rfbPixelFormat *in,
                             rfbPixelFormat *out,
                             char *iptr, char *optr,
                             int bytesBetweenInputLines,
                             int width, int height);
extern Bool rfbSetTranslateFunction(rfbClientPtr cl);
620 621
extern Bool rfbSetClientColourMap(rfbClientPtr cl, int firstColour, int nColours);
extern void rfbSetClientColourMaps(rfbScreenInfoPtr rfbScreen, int firstColour, int nColours);
dscho's avatar
dscho committed
622 623 624

/* httpd.c */

dscho's avatar
dscho committed
625 626
extern void httpInitSockets(rfbScreenInfoPtr rfbScreen);
extern void httpCheckFds(rfbScreenInfoPtr rfbScreen);
dscho's avatar
dscho committed
627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651



/* auth.c */

extern void rfbAuthNewClient(rfbClientPtr cl);
extern void rfbAuthProcessClientMessage(rfbClientPtr cl);


/* rre.c */

extern Bool rfbSendRectEncodingRRE(rfbClientPtr cl, int x,int y,int w,int h);


/* corre.c */

extern Bool rfbSendRectEncodingCoRRE(rfbClientPtr cl, int x,int y,int w,int h);


/* hextile.c */

extern Bool rfbSendRectEncodingHextile(rfbClientPtr cl, int x, int y, int w,
                                       int h);


dscho's avatar
dscho committed
652
#ifdef HAVE_LIBZ
dscho's avatar
dscho committed
653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669
/* zlib.c */

/* Minimum zlib rectangle size in bytes.  Anything smaller will
 * not compress well due to overhead.
 */
#define VNC_ENCODE_ZLIB_MIN_COMP_SIZE (17)

/* Set maximum zlib rectangle size in pixels.  Always allow at least
 * two scan lines.
 */
#define ZLIB_MAX_RECT_SIZE (128*256)
#define ZLIB_MAX_SIZE(min) ((( min * 2 ) > ZLIB_MAX_RECT_SIZE ) ? \
			    ( min * 2 ) : ZLIB_MAX_RECT_SIZE )

extern Bool rfbSendRectEncodingZlib(rfbClientPtr cl, int x, int y, int w,
				    int h);

dscho's avatar
dscho committed
670
#ifdef HAVE_LIBJPEG
dscho's avatar
dscho committed
671 672 673 674 675 676 677 678
/* tight.c */

#define TIGHT_DEFAULT_COMPRESSION  6

extern Bool rfbTightDisableGradient;

extern int rfbNumCodedRectsTight(rfbClientPtr cl, int x,int y,int w,int h);
extern Bool rfbSendRectEncodingTight(rfbClientPtr cl, int x,int y,int w,int h);
dscho's avatar
dscho committed
679 680
#endif
#endif
dscho's avatar
dscho committed
681 682 683 684


/* cursor.c */

685 686 687 688
typedef struct rfbCursor {
    unsigned char *source;			/* points to bits */
    unsigned char *mask;			/* points to bits */
    unsigned short width, height, xhot, yhot;	/* metrics */
689 690
    unsigned short foreRed, foreGreen, foreBlue; /* device-independent colour */
    unsigned short backRed, backGreen, backBlue; /* device-independent colour */
691 692 693 694
    unsigned char *richSource; /* source bytes for a rich cursor */
} rfbCursor, *rfbCursorPtr;

extern Bool rfbSendCursorShape(rfbClientPtr cl/*, rfbScreenInfoPtr pScreen*/);
695
extern Bool rfbSendCursorPos(rfbClientPtr cl);
696 697 698 699 700 701
extern void rfbConvertLSBCursorBitmapOrMask(int width,int height,unsigned char* bitmap);
extern rfbCursorPtr rfbMakeXCursor(int width,int height,char* cursorString,char* maskString);
extern char* rfbMakeMaskForXCursor(int width,int height,char* cursorString);
extern void MakeXCursorFromRichCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr cursor);
extern void MakeRichCursorFromXCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr cursor);
extern void rfbFreeCursor(rfbCursorPtr cursor);
702 703
extern void rfbDrawCursor(rfbScreenInfoPtr rfbScreen);
extern void rfbUndrawCursor(rfbScreenInfoPtr rfbScreen);
dscho's avatar
dscho committed
704
extern void rfbSetCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr c,Bool freeOld);
dscho's avatar
dscho committed
705

dscho's avatar
dscho committed
706 707 708
/* cursor handling for the pointer */
extern void defaultPtrAddEvent(int buttonMask,int x,int y,rfbClientPtr cl);

709
/* zrle.c */
710
#ifdef HAVE_ZRLE
711 712
extern Bool rfbSendRectEncodingZRLE(rfbClientPtr cl, int x, int y, int w,int h);
extern void FreeZrleData(rfbClientPtr cl);
713
#endif
714

dscho's avatar
dscho committed
715 716 717 718 719
/* stats.c */

extern void rfbResetStats(rfbClientPtr cl);
extern void rfbPrintStats(rfbClientPtr cl);

720 721 722
/* font.c */

typedef struct rfbFontData {
dscho's avatar
dscho committed
723
  unsigned char* data;
724 725 726 727 728 729 730 731
  /*
    metaData is a 256*5 array:
    for each character
    (offset,width,height,x,y)
  */
  int* metaData;
} rfbFontData,* rfbFontDataPtr;

732
int rfbDrawChar(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,unsigned char c,Pixel colour);
dscho's avatar
dscho committed
733
void rfbDrawString(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,const char* string,Pixel colour);
734 735
/* if colour==backColour, background is transparent */
int rfbDrawCharWithClip(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,unsigned char c,int x1,int y1,int x2,int y2,Pixel colour,Pixel backColour);
dscho's avatar
dscho committed
736 737
void rfbDrawStringWithClip(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,const char* string,int x1,int y1,int x2,int y2,Pixel colour,Pixel backColour);
int rfbWidthOfString(rfbFontDataPtr font,const char* string);
dscho's avatar
dscho committed
738 739
int rfbWidthOfChar(rfbFontDataPtr font,unsigned char c);
void rfbFontBBox(rfbFontDataPtr font,unsigned char c,int* x1,int* y1,int* x2,int* y2);
740 741 742 743 744 745 746 747 748 749
/* this returns the smallest box enclosing any character of font. */
void rfbWholeFontBBox(rfbFontDataPtr font,int *x1, int *y1, int *x2, int *y2);

/* dynamically load a linux console font (4096 bytes, 256 glyphs a 8x16 */
rfbFontDataPtr rfbLoadConsoleFont(char *filename);
/* free a dynamically loaded font */
void rfbFreeFont(rfbFontDataPtr font);

/* draw.c */

750
/* You have to call rfbUndrawCursor before using these functions */
751
void rfbFillRect(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2,Pixel col);
752 753
void rfbDrawPixel(rfbScreenInfoPtr s,int x,int y,Pixel col);
void rfbDrawLine(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2,Pixel col);
754 755 756 757 758 759 760 761 762 763 764 765 766

/* selbox.c */

/* this opens a modal select box. list is an array of strings, the end marked
   with a NULL.
   It returns the index in the list or -1 if cancelled or something else
   wasn't kosher. */
typedef void (*SelectionChangedHookPtr)(int index);
extern int rfbSelectBox(rfbScreenInfoPtr rfbScreen,
			rfbFontDataPtr font, char** list,
			int x1, int y1, int x2, int y2,
			Pixel foreColour, Pixel backColour,
			int border,SelectionChangedHookPtr selChangedHook);
767

dscho's avatar
dscho committed
768 769
/* cargs.c */

dscho's avatar
dscho committed
770
extern void rfbUsage(void);
dscho's avatar
dscho committed
771
extern void rfbPurgeArguments(int* argc,int* position,int count,char *argv[]);
dscho's avatar
dscho committed
772 773 774
extern void rfbProcessArguments(rfbScreenInfoPtr rfbScreen,int* argc, char *argv[]);
extern void rfbProcessSizeArguments(int* width,int* height,int* bpp,int* argc, char *argv[]);

775 776
/* main.c */

dscho's avatar
dscho committed
777
extern void rfbLogEnable(int enabled);
778 779
extern void rfbLog(const char *format, ...);
extern void rfbLogPerror(const char *str);
780 781 782 783 784 785 786

void rfbScheduleCopyRect(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2,int dx,int dy);
void rfbScheduleCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,int dy);

void rfbDoCopyRect(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2,int dx,int dy);
void rfbDoCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,int dy);

dscho's avatar
dscho committed
787
void rfbMarkRectAsModified(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2);
788
void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,sraRegionPtr modRegion);
dscho's avatar
dscho committed
789
void doNothingWithClient(rfbClientPtr cl);
790
enum rfbNewClientAction defaultNewClientHook(rfbClientPtr cl);
dscho's avatar
dscho committed
791

dscho's avatar
dscho committed
792
/* to check against plain passwords */
dscho's avatar
dscho committed
793
Bool rfbCheckPasswordByList(rfbClientPtr cl,const char* response,int len);
dscho's avatar
dscho committed
794

795
/* functions to make a vnc server */
dscho's avatar
dscho committed
796
extern rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
797 798
 int width,int height,int bitsPerSample,int samplesPerPixel,
 int bytesPerPixel);
dscho's avatar
dscho committed
799
extern void rfbInitServer(rfbScreenInfoPtr rfbScreen);
dscho's avatar
dscho committed
800 801 802 803
extern void rfbNewFramebuffer(rfbScreenInfoPtr rfbScreen,char *framebuffer,
 int width,int height, int bitsPerSample,int samplesPerPixel,
 int bytesPerPixel);

dscho's avatar
dscho committed
804 805
extern void rfbScreenCleanup(rfbScreenInfoPtr screenInfo);

806 807 808 809 810 811
/* functions to accept/refuse a client that has been put on hold
   by a NewClientHookPtr function. Must not be called in other
   situations. */
extern void rfbStartOnHoldClient(rfbClientPtr cl);
extern void rfbRefuseOnHoldClient(rfbClientPtr cl);

dscho's avatar
dscho committed
812 813
/* call one of these two functions to service the vnc clients.
 usec are the microseconds the select on the fds waits.
dscho's avatar
dscho committed
814 815
 if you are using the event loop, set this to some value > 0, so the
 server doesn't get a high load just by listening. */
dscho's avatar
dscho committed
816

dscho's avatar
dscho committed
817 818
extern void rfbRunEventLoop(rfbScreenInfoPtr screenInfo, long usec, Bool runInBackground);
extern void rfbProcessEvents(rfbScreenInfoPtr screenInfo,long usec);
dscho's avatar
dscho committed
819 820

#endif
821 822 823 824

#if(defined __cplusplus)
}
#endif