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