]> git.sesse.net Git - rdpsrv/blobdiff - Xserver/programs/Xserver/hw/vnc/rfb.h
Import X server from vnc-3.3.7.
[rdpsrv] / Xserver / programs / Xserver / hw / vnc / rfb.h
diff --git a/Xserver/programs/Xserver/hw/vnc/rfb.h b/Xserver/programs/Xserver/hw/vnc/rfb.h
new file mode 100644 (file)
index 0000000..ebc70a0
--- /dev/null
@@ -0,0 +1,451 @@
+/*
+ * rfb.h - header file for RFB DDX implementation.
+ */
+
+/*
+ *  Copyright (C) 2002-2003 RealVNC Ltd.
+ *  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.
+ */
+
+#include "scrnintstr.h"
+#include "colormapst.h"
+#include "gcstruct.h"
+#include "osdep.h"
+#include <rfb/rfbproto.h>
+#include <rfb/vncauth.h>
+
+#define MAX_ENCODINGS 20
+
+extern char *display;
+
+
+/*
+ * Per-screen (framebuffer) structure.  There is only one of these, since we
+ * don't allow the X server to have multiple screens.
+ */
+
+typedef struct
+{
+    int width;
+    int paddedWidthInBytes;
+    int height;
+    int depth;
+    int bitsPerPixel;
+    int sizeInBytes;
+    char *pfbMemory;
+    Pixel blackPixel;
+    Pixel whitePixel;
+
+    /* 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.
+
+       Removing the cursor (rfbSpriteRemoveCursor) is eventually achieved by
+       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.
+
+       Putting up the cursor (rfbSpriteRestoreCursor) involves a call to
+       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 */
+
+    /* wrapped screen functions */
+
+    CloseScreenProcPtr                 CloseScreen;
+    CreateGCProcPtr                    CreateGC;
+    PaintWindowBackgroundProcPtr       PaintWindowBackground;
+    PaintWindowBorderProcPtr           PaintWindowBorder;
+    CopyWindowProcPtr                  CopyWindow;
+    ClearToBackgroundProcPtr           ClearToBackground;
+    RestoreAreasProcPtr                        RestoreAreas;
+
+} rfbScreenInfo, *rfbScreenInfoPtr;
+
+
+/*
+ * rfbTranslateFnType is the type of translation functions.
+ */
+
+struct rfbClientRec;
+typedef void (*rfbTranslateFnType)(char *table, rfbPixelFormat *in,
+                                  rfbPixelFormat *out,
+                                  char *iptr, char *optr,
+                                  int bytesBetweenInputLines,
+                                  int width, int height);
+
+
+/*
+ * Per-client structure.
+ */
+
+typedef struct rfbClientRec {
+
+    int sock;
+    char *host;
+                               /* 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;
+
+    Bool readyForSetColourMapEntries;
+
+    Bool useCopyRect;
+    int preferredEncoding;
+    int correMaxWidth, correMaxHeight;
+    void* zrleData;
+
+    /* The following member is only used during VNC authentication */
+
+    CARD8 authChallenge[CHALLENGESIZE];
+
+    /* 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. */
+
+    RegionRec copyRegion;      /* the destination region of the copy */
+    int copyDX, copyDY;                /* the translation by which the copy happens */
+
+    RegionRec modifiedRegion;  /* the region of the screen modified in any
+                                  other way */
+
+    /* 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. */
+
+    RegionRec requestedRegion;
+
+    /* The following members represent the state of the "deferred update" timer
+       - 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. */
+
+    Bool deferredUpdateScheduled;
+    OsTimerPtr deferredUpdateTimer;
+
+    /* 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;
+
+    /* statistics */
+
+    int rfbBytesSent[MAX_ENCODINGS];
+    int rfbRectanglesSent[MAX_ENCODINGS];
+    int rfbFramebufferUpdateMessagesSent;
+    int rfbRawBytesEquivalent;
+    int rfbKeyEventsRcvd;
+    int rfbPointerEventsRcvd;
+
+    struct rfbClientRec *next;
+
+} rfbClientRec, *rfbClientPtr;
+
+
+/*
+ * This macro is used to test whether there is a framebuffer update needing to
+ * be sent to the client.
+ */
+
+#define FB_UPDATE_PENDING(cl)                          \
+    (!rfbScreen.cursorIsDrawn ||                       \
+     REGION_NOTEMPTY((pScreen),&(cl)->copyRegion) ||   \
+     REGION_NOTEMPTY((pScreen),&(cl)->modifiedRegion))
+
+/*
+ * This macro creates an empty region (ie. a region with no areas) if it is
+ * given a rectangle with a width or height of zero. It appears that 
+ * REGION_INTERSECT does not quite do the right thing with zero-width
+ * rectangles, but it should with completely empty regions.
+ */
+
+#define SAFE_REGION_INIT(pscreen, preg, rect, size)          \
+{                                                            \
+      if ( ( (rect) ) &&                                     \
+           ( ( (rect)->x2 == (rect)->x1 ) ||                 \
+            ( (rect)->y2 == (rect)->y1 ) ) ) {              \
+         REGION_INIT( (pscreen), (preg), NullBox, 0 );      \
+      } else {                                               \
+         REGION_INIT( (pscreen), (preg), (rect), (size) );  \
+      }                                                      \
+}
+
+/*
+ * An rfbGCRec is where we store the pointers to the original GC funcs and ops
+ * which we wrap (NULL means not wrapped).
+ */
+
+typedef struct {
+    GCFuncs *wrapFuncs;
+    GCOps *wrapOps;
+} rfbGCRec, *rfbGCPtr;
+
+
+
+/*
+ * Macros for endian swapping.
+ */
+
+#define Swap16(s) ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff))
+
+#define Swap32(l) (((l) >> 24) | \
+                  (((l) & 0x00ff0000) >> 8)  | \
+                  (((l) & 0x0000ff00) << 8)  | \
+                  ((l) << 24))
+
+
+/* init.c */
+
+static const int rfbEndianTest = 1;
+
+#define Swap16IfLE(s) (*(const char *)&rfbEndianTest ? Swap16(s) : (s))
+
+#define Swap32IfLE(l) (*(const char *)&rfbEndianTest ? Swap32(l) : (l))
+
+extern char *desktopName;
+extern Bool rfbTrace;
+extern char rfbThisHost[];
+extern Atom VNC_LAST_CLIENT_ID;
+
+extern rfbScreenInfo rfbScreen;
+extern int rfbGCIndex;
+
+extern int inetdSock;
+
+extern int rfbBitsPerPixel(int depth);
+extern void rfbLog(char *format, ...);
+extern void rfbLogPerror(char *str);
+
+
+/* sockets.c */
+
+extern int rfbMaxClientWait;
+
+extern int rfbPort;
+extern int rfbListenSock;
+extern Bool rfbLocalhostOnly;
+
+extern void rfbInitSockets();
+extern void rfbCloseSock();
+extern void rfbCheckFds();
+extern void rfbWaitForClient(int sock);
+extern int rfbConnect(char *host, int port);
+
+extern int ReadExact(int sock, char *buf, int len);
+extern int WriteExact(int sock, char *buf, int len);
+extern int ListenOnTCPPort(int port);
+extern int ConnectToTcpAddr(char *host, int port);
+
+
+/* cmap.c */
+
+extern ColormapPtr rfbInstalledColormap;
+
+extern int rfbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps);
+extern void rfbInstallColormap(ColormapPtr pmap);
+extern void rfbUninstallColormap(ColormapPtr pmap);
+extern void rfbStoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs);
+
+
+/* draw.c */
+
+extern int rfbDeferUpdateTime;
+
+extern Bool rfbCloseScreen(int,ScreenPtr);
+extern Bool rfbCreateGC(GCPtr);
+extern void rfbPaintWindowBackground(WindowPtr, RegionPtr, int what);
+extern void rfbPaintWindowBorder(WindowPtr, RegionPtr, int what);
+extern void rfbCopyWindow(WindowPtr, DDXPointRec, RegionPtr);
+extern void rfbClearToBackground(WindowPtr, int x, int y, int w,
+                                int h, Bool generateExposures);
+extern RegionPtr rfbRestoreAreas(WindowPtr, RegionPtr);
+extern void rfbScheduleDeferredUpdate(rfbClientPtr cl);
+
+
+/* cutpaste.c */
+
+extern void rfbSetXCutText(char *str, int len);
+extern void rfbGotXCutText(char *str, int len);
+
+
+/* kbdptr.c */
+
+extern void PtrDeviceInit();
+extern void PtrDeviceOn();
+extern void PtrDeviceOff();
+extern void PtrDeviceControl();
+extern void PtrAddEvent(int buttonMask, int x, int y, rfbClientPtr cl);
+
+extern void KbdDeviceInit();
+extern void KbdDeviceOn();
+extern void KbdDeviceOff();
+extern void KbdAddEvent(Bool down, KeySym keySym, rfbClientPtr cl);
+extern void KbdReleaseAllKeys();
+
+
+/* rfbserver.c */
+
+/*
+ * 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.
+ */
+
+#define UPDATE_BUF_SIZE 30000
+extern char updateBuf[UPDATE_BUF_SIZE];
+extern int ublen;
+
+extern rfbClientPtr rfbClientHead;
+extern rfbClientPtr pointerClient;
+
+extern Bool rfbAlwaysShared;
+extern Bool rfbNeverShared;
+extern Bool rfbDontDisconnect;
+extern int rfbMaxRects;
+
+extern void rfbNewClientConnection(int sock);
+extern rfbClientPtr rfbReverseConnection(char *host, int port);
+extern void rfbClientConnectionGone(int sock);
+extern void rfbProcessClientMessage(int sock);
+extern void rfbClientConnFailed(rfbClientPtr cl, char *reason);
+extern Bool rfbSendFramebufferUpdate(rfbClientPtr cl);
+extern Bool rfbSendRectEncodingRaw(rfbClientPtr cl, int x,int y,int w,int h);
+extern Bool rfbSendUpdateBuf(rfbClientPtr cl);
+extern Bool rfbSendSetColourMapEntries(rfbClientPtr cl, int firstColour,
+                                      int nColours);
+extern void rfbSendBell();
+extern void rfbSendServerCutText(char *str, int len);
+
+
+/* translate.c */
+
+extern Bool rfbEconomicTranslate;
+extern rfbPixelFormat rfbServerFormat;
+
+extern void rfbTranslateNone(char *table, rfbPixelFormat *in,
+                            rfbPixelFormat *out,
+                            char *iptr, char *optr,
+                            int bytesBetweenInputLines,
+                            int width, int height);
+extern Bool rfbSetTranslateFunction(rfbClientPtr cl);
+extern void rfbSetClientColourMaps(int firstColour, int nColours);
+extern Bool rfbSetClientColourMap(rfbClientPtr cl, int firstColour,
+                                 int nColours);
+
+
+/* httpd.c */
+
+extern int httpPort;
+extern char *httpDir;
+
+extern void httpInitSockets();
+extern void httpCheckFds();
+
+
+
+/* auth.c */
+
+extern char *rfbAuthPasswdFile;
+extern Bool rfbAuthenticating;
+
+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);
+
+/* zrle.c */
+
+extern Bool rfbSendRectEncodingZRLE(rfbClientPtr cl, int x, int y, int w,
+                                    int h);
+extern void FreeZrleData(rfbClientPtr cl);
+
+/* stats.c */
+
+extern void rfbResetStats(rfbClientPtr cl);
+extern void rfbPrintStats(rfbClientPtr cl);