X-Git-Url: https://git.sesse.net/?p=rdpsrv;a=blobdiff_plain;f=Xserver%2Fprograms%2FXserver%2Fhw%2Fvnc%2Frfb.h;fp=Xserver%2Fprograms%2FXserver%2Fhw%2Fvnc%2Frfb.h;h=ebc70a0649e11c1023df27c0c7db25638a24b979;hp=0000000000000000000000000000000000000000;hb=b6e6afccf37f4ad0515ef2a698f714fdf1bf23b3;hpb=e3340a110a3b01756b8e67531395a33b40a17d37 diff --git a/Xserver/programs/Xserver/hw/vnc/rfb.h b/Xserver/programs/Xserver/hw/vnc/rfb.h new file mode 100644 index 0000000..ebc70a0 --- /dev/null +++ b/Xserver/programs/Xserver/hw/vnc/rfb.h @@ -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 +#include + +#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);