]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/hw/vnc/rfb.h
ebc70a0649e11c1023df27c0c7db25638a24b979
[rdpsrv] / Xserver / programs / Xserver / hw / vnc / rfb.h
1 /*
2  * rfb.h - header file for RFB DDX implementation.
3  */
4
5 /*
6  *  Copyright (C) 2002-2003 RealVNC Ltd.
7  *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
8  *
9  *  This is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This software is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this software; if not, write to the Free Software
21  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
22  *  USA.
23  */
24
25 #include "scrnintstr.h"
26 #include "colormapst.h"
27 #include "gcstruct.h"
28 #include "osdep.h"
29 #include <rfb/rfbproto.h>
30 #include <rfb/vncauth.h>
31
32 #define MAX_ENCODINGS 20
33
34 extern char *display;
35
36
37 /*
38  * Per-screen (framebuffer) structure.  There is only one of these, since we
39  * don't allow the X server to have multiple screens.
40  */
41
42 typedef struct
43 {
44     int width;
45     int paddedWidthInBytes;
46     int height;
47     int depth;
48     int bitsPerPixel;
49     int sizeInBytes;
50     char *pfbMemory;
51     Pixel blackPixel;
52     Pixel whitePixel;
53
54     /* The following two members are used to minimise the amount of unnecessary
55        drawing caused by cursor movement.  Whenever any drawing affects the
56        part of the screen where the cursor is, the cursor is removed first and
57        then the drawing is done (this is what the sprite routines test for).
58        Afterwards, however, we do not replace the cursor, even when the cursor
59        is logically being moved across the screen.  We only draw the cursor
60        again just as we are about to send the client a framebuffer update.
61
62        We need to be careful when removing and drawing the cursor because of
63        their relationship with the normal drawing routines.  The drawing
64        routines can invoke the cursor routines, but also the cursor routines
65        themselves end up invoking drawing routines.
66
67        Removing the cursor (rfbSpriteRemoveCursor) is eventually achieved by
68        doing a CopyArea from a pixmap to the screen, where the pixmap contains
69        the saved contents of the screen under the cursor.  Before doing this,
70        however, we set cursorIsDrawn to FALSE.  Then, when CopyArea is called,
71        it sees that cursorIsDrawn is FALSE and so doesn't feel the need to
72        (recursively!) remove the cursor before doing it.
73
74        Putting up the cursor (rfbSpriteRestoreCursor) involves a call to
75        PushPixels.  While this is happening, cursorIsDrawn must be FALSE so
76        that PushPixels doesn't think it has to remove the cursor first.
77        Obviously cursorIsDrawn is set to TRUE afterwards.
78
79        Another problem we face is that drawing routines sometimes cause a
80        framebuffer update to be sent to the RFB client.  When the RFB client is
81        already waiting for a framebuffer update and some drawing to the
82        framebuffer then happens, the drawing routine sees that the client is
83        ready, so it calls rfbSendFramebufferUpdate.  If the cursor is not drawn
84        at this stage, it must be put up, and so rfbSpriteRestoreCursor is
85        called.  However, if the original drawing routine was actually called
86        from within rfbSpriteRestoreCursor or rfbSpriteRemoveCursor we don't
87        want this to happen.  So both the cursor routines set
88        dontSendFramebufferUpdate to TRUE, and all the drawing routines check
89        this before calling rfbSendFramebufferUpdate. */
90
91     Bool cursorIsDrawn;             /* TRUE if the cursor is currently drawn */
92     Bool dontSendFramebufferUpdate; /* TRUE while removing or drawing the
93                                        cursor */
94
95     /* wrapped screen functions */
96
97     CloseScreenProcPtr                  CloseScreen;
98     CreateGCProcPtr                     CreateGC;
99     PaintWindowBackgroundProcPtr        PaintWindowBackground;
100     PaintWindowBorderProcPtr            PaintWindowBorder;
101     CopyWindowProcPtr                   CopyWindow;
102     ClearToBackgroundProcPtr            ClearToBackground;
103     RestoreAreasProcPtr                 RestoreAreas;
104
105 } rfbScreenInfo, *rfbScreenInfoPtr;
106
107
108 /*
109  * rfbTranslateFnType is the type of translation functions.
110  */
111
112 struct rfbClientRec;
113 typedef void (*rfbTranslateFnType)(char *table, rfbPixelFormat *in,
114                                    rfbPixelFormat *out,
115                                    char *iptr, char *optr,
116                                    int bytesBetweenInputLines,
117                                    int width, int height);
118
119
120 /*
121  * Per-client structure.
122  */
123
124 typedef struct rfbClientRec {
125
126     int sock;
127     char *host;
128                                 /* Possible client states: */
129     enum {
130         RFB_PROTOCOL_VERSION,   /* establishing protocol version */
131         RFB_AUTHENTICATION,     /* authenticating */
132         RFB_INITIALISATION,     /* sending initialisation messages */
133         RFB_NORMAL              /* normal protocol messages */
134     } state;
135
136     Bool reverseConnection;
137
138     Bool readyForSetColourMapEntries;
139
140     Bool useCopyRect;
141     int preferredEncoding;
142     int correMaxWidth, correMaxHeight;
143     void* zrleData;
144
145     /* The following member is only used during VNC authentication */
146
147     CARD8 authChallenge[CHALLENGESIZE];
148
149     /* The following members represent the update needed to get the client's
150        framebuffer from its present state to the current state of our
151        framebuffer.
152
153        If the client does not accept CopyRect encoding then the update is
154        simply represented as the region of the screen which has been modified
155        (modifiedRegion).
156
157        If the client does accept CopyRect encoding, then the update consists of
158        two parts.  First we have a single copy from one region of the screen to
159        another (the destination of the copy is copyRegion), and second we have
160        the region of the screen which has been modified in some other way
161        (modifiedRegion).
162
163        Although the copy is of a single region, this region may have many
164        rectangles.  When sending an update, the copyRegion is always sent
165        before the modifiedRegion.  This is because the modifiedRegion may
166        overlap parts of the screen which are in the source of the copy.
167
168        In fact during normal processing, the modifiedRegion may even overlap
169        the destination copyRegion.  Just before an update is sent we remove
170        from the copyRegion anything in the modifiedRegion. */
171
172     RegionRec copyRegion;       /* the destination region of the copy */
173     int copyDX, copyDY;         /* the translation by which the copy happens */
174
175     RegionRec modifiedRegion;   /* the region of the screen modified in any
176                                    other way */
177
178     /* As part of the FramebufferUpdateRequest, a client can express interest
179        in a subrectangle of the whole framebuffer.  This is stored in the
180        requestedRegion member.  In the normal case this is the whole
181        framebuffer if the client is ready, empty if it's not. */
182
183     RegionRec requestedRegion;
184
185     /* The following members represent the state of the "deferred update" timer
186        - when the framebuffer is modified and the client is ready, in most
187        cases it is more efficient to defer sending the update by a few
188        milliseconds so that several changes to the framebuffer can be combined
189        into a single update. */
190
191     Bool deferredUpdateScheduled;
192     OsTimerPtr deferredUpdateTimer;
193
194     /* translateFn points to the translation function which is used to copy
195        and translate a rectangle from the framebuffer to an output buffer. */
196
197     rfbTranslateFnType translateFn;
198
199     char *translateLookupTable;
200
201     rfbPixelFormat format;
202
203     /* statistics */
204
205     int rfbBytesSent[MAX_ENCODINGS];
206     int rfbRectanglesSent[MAX_ENCODINGS];
207     int rfbFramebufferUpdateMessagesSent;
208     int rfbRawBytesEquivalent;
209     int rfbKeyEventsRcvd;
210     int rfbPointerEventsRcvd;
211
212     struct rfbClientRec *next;
213
214 } rfbClientRec, *rfbClientPtr;
215
216
217 /*
218  * This macro is used to test whether there is a framebuffer update needing to
219  * be sent to the client.
220  */
221
222 #define FB_UPDATE_PENDING(cl)                           \
223     (!rfbScreen.cursorIsDrawn ||                        \
224      REGION_NOTEMPTY((pScreen),&(cl)->copyRegion) ||    \
225      REGION_NOTEMPTY((pScreen),&(cl)->modifiedRegion))
226
227 /*
228  * This macro creates an empty region (ie. a region with no areas) if it is
229  * given a rectangle with a width or height of zero. It appears that 
230  * REGION_INTERSECT does not quite do the right thing with zero-width
231  * rectangles, but it should with completely empty regions.
232  */
233
234 #define SAFE_REGION_INIT(pscreen, preg, rect, size)          \
235 {                                                            \
236       if ( ( (rect) ) &&                                     \
237            ( ( (rect)->x2 == (rect)->x1 ) ||                 \
238              ( (rect)->y2 == (rect)->y1 ) ) ) {              \
239           REGION_INIT( (pscreen), (preg), NullBox, 0 );      \
240       } else {                                               \
241           REGION_INIT( (pscreen), (preg), (rect), (size) );  \
242       }                                                      \
243 }
244
245 /*
246  * An rfbGCRec is where we store the pointers to the original GC funcs and ops
247  * which we wrap (NULL means not wrapped).
248  */
249
250 typedef struct {
251     GCFuncs *wrapFuncs;
252     GCOps *wrapOps;
253 } rfbGCRec, *rfbGCPtr;
254
255
256
257 /*
258  * Macros for endian swapping.
259  */
260
261 #define Swap16(s) ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff))
262
263 #define Swap32(l) (((l) >> 24) | \
264                    (((l) & 0x00ff0000) >> 8)  | \
265                    (((l) & 0x0000ff00) << 8)  | \
266                    ((l) << 24))
267
268
269 /* init.c */
270
271 static const int rfbEndianTest = 1;
272
273 #define Swap16IfLE(s) (*(const char *)&rfbEndianTest ? Swap16(s) : (s))
274
275 #define Swap32IfLE(l) (*(const char *)&rfbEndianTest ? Swap32(l) : (l))
276
277 extern char *desktopName;
278 extern Bool rfbTrace;
279 extern char rfbThisHost[];
280 extern Atom VNC_LAST_CLIENT_ID;
281
282 extern rfbScreenInfo rfbScreen;
283 extern int rfbGCIndex;
284
285 extern int inetdSock;
286
287 extern int rfbBitsPerPixel(int depth);
288 extern void rfbLog(char *format, ...);
289 extern void rfbLogPerror(char *str);
290
291
292 /* sockets.c */
293
294 extern int rfbMaxClientWait;
295
296 extern int rfbPort;
297 extern int rfbListenSock;
298 extern Bool rfbLocalhostOnly;
299
300 extern void rfbInitSockets();
301 extern void rfbCloseSock();
302 extern void rfbCheckFds();
303 extern void rfbWaitForClient(int sock);
304 extern int rfbConnect(char *host, int port);
305
306 extern int ReadExact(int sock, char *buf, int len);
307 extern int WriteExact(int sock, char *buf, int len);
308 extern int ListenOnTCPPort(int port);
309 extern int ConnectToTcpAddr(char *host, int port);
310
311
312 /* cmap.c */
313
314 extern ColormapPtr rfbInstalledColormap;
315
316 extern int rfbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps);
317 extern void rfbInstallColormap(ColormapPtr pmap);
318 extern void rfbUninstallColormap(ColormapPtr pmap);
319 extern void rfbStoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs);
320
321
322 /* draw.c */
323
324 extern int rfbDeferUpdateTime;
325
326 extern Bool rfbCloseScreen(int,ScreenPtr);
327 extern Bool rfbCreateGC(GCPtr);
328 extern void rfbPaintWindowBackground(WindowPtr, RegionPtr, int what);
329 extern void rfbPaintWindowBorder(WindowPtr, RegionPtr, int what);
330 extern void rfbCopyWindow(WindowPtr, DDXPointRec, RegionPtr);
331 extern void rfbClearToBackground(WindowPtr, int x, int y, int w,
332                                  int h, Bool generateExposures);
333 extern RegionPtr rfbRestoreAreas(WindowPtr, RegionPtr);
334 extern void rfbScheduleDeferredUpdate(rfbClientPtr cl);
335
336
337 /* cutpaste.c */
338
339 extern void rfbSetXCutText(char *str, int len);
340 extern void rfbGotXCutText(char *str, int len);
341
342
343 /* kbdptr.c */
344
345 extern void PtrDeviceInit();
346 extern void PtrDeviceOn();
347 extern void PtrDeviceOff();
348 extern void PtrDeviceControl();
349 extern void PtrAddEvent(int buttonMask, int x, int y, rfbClientPtr cl);
350
351 extern void KbdDeviceInit();
352 extern void KbdDeviceOn();
353 extern void KbdDeviceOff();
354 extern void KbdAddEvent(Bool down, KeySym keySym, rfbClientPtr cl);
355 extern void KbdReleaseAllKeys();
356
357
358 /* rfbserver.c */
359
360 /*
361  * UPDATE_BUF_SIZE must be big enough to send at least one whole line of the
362  * framebuffer.  So for a max screen width of say 2K with 32-bit pixels this
363  * means 8K minimum.
364  */
365
366 #define UPDATE_BUF_SIZE 30000
367 extern char updateBuf[UPDATE_BUF_SIZE];
368 extern int ublen;
369
370 extern rfbClientPtr rfbClientHead;
371 extern rfbClientPtr pointerClient;
372
373 extern Bool rfbAlwaysShared;
374 extern Bool rfbNeverShared;
375 extern Bool rfbDontDisconnect;
376 extern int rfbMaxRects;
377
378 extern void rfbNewClientConnection(int sock);
379 extern rfbClientPtr rfbReverseConnection(char *host, int port);
380 extern void rfbClientConnectionGone(int sock);
381 extern void rfbProcessClientMessage(int sock);
382 extern void rfbClientConnFailed(rfbClientPtr cl, char *reason);
383 extern Bool rfbSendFramebufferUpdate(rfbClientPtr cl);
384 extern Bool rfbSendRectEncodingRaw(rfbClientPtr cl, int x,int y,int w,int h);
385 extern Bool rfbSendUpdateBuf(rfbClientPtr cl);
386 extern Bool rfbSendSetColourMapEntries(rfbClientPtr cl, int firstColour,
387                                        int nColours);
388 extern void rfbSendBell();
389 extern void rfbSendServerCutText(char *str, int len);
390
391
392 /* translate.c */
393
394 extern Bool rfbEconomicTranslate;
395 extern rfbPixelFormat rfbServerFormat;
396
397 extern void rfbTranslateNone(char *table, rfbPixelFormat *in,
398                              rfbPixelFormat *out,
399                              char *iptr, char *optr,
400                              int bytesBetweenInputLines,
401                              int width, int height);
402 extern Bool rfbSetTranslateFunction(rfbClientPtr cl);
403 extern void rfbSetClientColourMaps(int firstColour, int nColours);
404 extern Bool rfbSetClientColourMap(rfbClientPtr cl, int firstColour,
405                                   int nColours);
406
407
408 /* httpd.c */
409
410 extern int httpPort;
411 extern char *httpDir;
412
413 extern void httpInitSockets();
414 extern void httpCheckFds();
415
416
417
418 /* auth.c */
419
420 extern char *rfbAuthPasswdFile;
421 extern Bool rfbAuthenticating;
422
423 extern void rfbAuthNewClient(rfbClientPtr cl);
424 extern void rfbAuthProcessClientMessage(rfbClientPtr cl);
425
426
427 /* rre.c */
428
429 extern Bool rfbSendRectEncodingRRE(rfbClientPtr cl, int x,int y,int w,int h);
430
431
432 /* corre.c */
433
434 extern Bool rfbSendRectEncodingCoRRE(rfbClientPtr cl, int x,int y,int w,int h);
435
436
437 /* hextile.c */
438
439 extern Bool rfbSendRectEncodingHextile(rfbClientPtr cl, int x, int y, int w,
440                                        int h);
441
442 /* zrle.c */
443
444 extern Bool rfbSendRectEncodingZRLE(rfbClientPtr cl, int x, int y, int w,
445                                     int h);
446 extern void FreeZrleData(rfbClientPtr cl);
447
448 /* stats.c */
449
450 extern void rfbResetStats(rfbClientPtr cl);
451 extern void rfbPrintStats(rfbClientPtr cl);