]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/hw/vnc/init.c
Remove RFB dependencies from X server (crashes, though).
[rdpsrv] / Xserver / programs / Xserver / hw / vnc / init.c
1 /*
2  * init.c
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 /*
26
27 Copyright (c) 1993  X Consortium
28
29 Permission is hereby granted, free of charge, to any person obtaining
30 a copy of this software and associated documentation files (the
31 "Software"), to deal in the Software without restriction, including
32 without limitation the rights to use, copy, modify, merge, publish,
33 distribute, sublicense, and/or sell copies of the Software, and to
34 permit persons to whom the Software is furnished to do so, subject to
35 the following conditions:
36
37 The above copyright notice and this permission notice shall be included
38 in all copies or substantial portions of the Software.
39
40 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
41 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
42 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
43 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
44 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
45 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
46 OTHER DEALINGS IN THE SOFTWARE.
47
48 Except as contained in this notice, the name of the X Consortium shall
49 not be used in advertising or otherwise to promote the sale, use or
50 other dealings in this Software without prior written authorization
51 from the X Consortium.
52
53 */
54
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <stdarg.h>
58 #include <sys/types.h>
59 #include <sys/socket.h>
60 #include <netinet/in.h>
61 #include <netdb.h>
62 #include "X11/X.h"
63 #define NEED_EVENTS
64 #include "X11/Xproto.h"
65 #include "X11/Xos.h"
66 #include "scrnintstr.h"
67 #include "servermd.h"
68 #define PSZ 8
69 #include "cfb.h"
70 #include "mi.h"
71 #include "mibstore.h"
72 #include "colormapst.h"
73 #include "gcstruct.h"
74 #include "input.h"
75 #include "mipointer.h"
76 #include "dixstruct.h"
77 #include "propertyst.h"
78 #include <Xatom.h>
79 #include <errno.h>
80 #include <sys/param.h>
81 #include "dix.h"
82 #include "rfb.h"
83 #include "dispcur.h"
84
85 int rfbMaxClientWait;
86
87 int rfbPort;
88 int rfbListenSock;
89 Bool rfbLocalhostOnly;
90
91 extern Bool cfb16ScreenInit(ScreenPtr, pointer, int, int, int, int, int);
92 extern Bool cfb32ScreenInit(ScreenPtr, pointer, int, int, int, int, int);
93
94 #define RFB_DEFAULT_WIDTH  640
95 #define RFB_DEFAULT_HEIGHT 480
96 #define RFB_DEFAULT_DEPTH  8
97 #define RFB_DEFAULT_WHITEPIXEL 0
98 #define RFB_DEFAULT_BLACKPIXEL 1
99
100 rfbScreenInfo rfbScreen;
101 int rfbGCIndex;
102
103 static Bool initOutputCalled = FALSE;
104 static Bool noCursor = FALSE;
105 char *desktopName = "x11";
106 Bool rfbTrace = FALSE;
107
108 char rfbThisHost[256];
109
110 Atom VNC_LAST_CLIENT_ID;
111 Atom VNC_CONNECT;
112 Atom VNC_DEFER_UPDATE;
113
114 static HWEventQueueType alwaysCheckForInput[2] = { 0, 1 };
115 static HWEventQueueType *mieqCheckForInput[2];
116
117 static char primaryOrder[4] = "";
118 static int redBits, greenBits, blueBits;
119
120
121 static Bool rfbScreenInit(int index, ScreenPtr pScreen, int argc,
122                           char **argv);
123 static int rfbKeybdProc(DeviceIntPtr pDevice, int onoff);
124 static int rfbMouseProc(DeviceIntPtr pDevice, int onoff);
125 static Bool CheckDisplayNumber(int n);
126
127 static Bool rfbAlwaysTrue();
128 static char *rfbAllocateFramebufferMemory(rfbScreenInfoPtr prfb);
129 static Bool rfbCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y);
130 static void rfbCrossScreen(ScreenPtr pScreen, Bool entering);
131 static void rfbClientStateChange(CallbackListPtr *, pointer myData,
132                                  pointer client);
133
134 static miPointerScreenFuncRec rfbPointerCursorFuncs = {
135     rfbCursorOffScreen,
136     rfbCrossScreen,
137     miPointerWarpCursor
138 };
139
140
141 int inetdSock = -1;
142 static char inetdDisplayNumStr[10];
143
144 extern char buildtime[];
145
146
147 /*
148  * ddxProcessArgument is our first entry point and will be called at the
149  * very start for each argument.  It is not called again on server reset.
150  */
151
152 int
153 ddxProcessArgument (argc, argv, i)
154     int argc;
155     char *argv[];
156     int i;
157 {
158     static Bool firstTime = TRUE;
159
160     if (firstTime)
161     {
162         rfbScreen.width  = RFB_DEFAULT_WIDTH;
163         rfbScreen.height = RFB_DEFAULT_HEIGHT;
164         rfbScreen.depth  = RFB_DEFAULT_DEPTH;
165         rfbScreen.blackPixel = RFB_DEFAULT_BLACKPIXEL;
166         rfbScreen.whitePixel = RFB_DEFAULT_WHITEPIXEL;
167         rfbScreen.pfbMemory = NULL;
168         gethostname(rfbThisHost, 255);
169         firstTime = FALSE;
170     }
171
172     if (strcasecmp (argv[i], "-geometry") == 0) /* -geometry WxH */
173     {
174         if (i + 1 >= argc) UseMsg();
175         if (sscanf(argv[i+1],"%dx%d",
176                    &rfbScreen.width,&rfbScreen.height) != 2) {
177             ErrorF("Invalid geometry %s\n", argv[i+1]);
178             UseMsg();
179         }
180         return 2;
181     }
182
183     if (strcasecmp (argv[i], "-depth") == 0)    /* -depth D */
184     {
185         if (i + 1 >= argc) UseMsg();
186         rfbScreen.depth = atoi(argv[i+1]);
187         return 2;
188     }
189
190     if (strcasecmp (argv[i], "-pixelformat") == 0) {
191         if (i + 1 >= argc) UseMsg();
192         if (sscanf(argv[i+1], "%3s%1d%1d%1d", primaryOrder,
193                    &redBits, &greenBits, &blueBits) < 4) {
194             ErrorF("Invalid pixel format %s\n", argv[i+1]);
195             UseMsg();
196         }
197
198         if (strcasecmp(primaryOrder, "bgr") == 0) {
199             int tmp = redBits;
200             redBits = blueBits;
201             blueBits = tmp;
202         } else if (strcasecmp(primaryOrder, "rgb") != 0) {
203             ErrorF("Invalid pixel format %s\n", argv[i+1]);
204             UseMsg();
205         }
206
207         return 2;
208     }
209
210     if (strcasecmp (argv[i], "-blackpixel") == 0) {     /* -blackpixel n */
211         if (i + 1 >= argc) UseMsg();
212         rfbScreen.blackPixel = atoi(argv[i+1]);
213         return 2;
214     }
215
216     if (strcasecmp (argv[i], "-whitepixel") == 0) {     /* -whitepixel n */
217         if (i + 1 >= argc) UseMsg();
218         rfbScreen.whitePixel = atoi(argv[i+1]);
219         return 2;
220     }
221
222     if (strcasecmp(argv[i], "-nocursor") == 0) {
223         noCursor = TRUE;
224         return 1;
225     }
226
227     if (strcasecmp(argv[i], "-desktop") == 0) { /* -desktop desktop-name */
228         if (i + 1 >= argc) UseMsg();
229         desktopName = argv[i+1];
230         return 2;
231     }
232
233     if (strcasecmp(argv[i], "-inetd") == 0) {   /* -inetd */ 
234         int n;
235         for (n = 1; n < 100; n++) {
236             if (CheckDisplayNumber(n))
237                 break;
238         }
239
240         if (n >= 100)
241             FatalError("-inetd: couldn't find free display number");
242
243         sprintf(inetdDisplayNumStr, "%d", n);
244         display = inetdDisplayNumStr;
245
246         /* fds 0, 1 and 2 (stdin, out and err) are all the same socket to the
247            RFB client.  OsInit() closes stdout and stdin, and we don't want
248            stderr to go to the RFB client, so make the client socket 3 and
249            close stderr.  OsInit() will redirect stderr logging to an
250            appropriate log file or /dev/null if that doesn't work. */
251
252         dup2(0,3);
253         inetdSock = 3;
254         close(2);
255
256         return 1;
257     }
258
259     if (inetdSock != -1 && argv[i][0] == ':') {
260         FatalError("can't specify both -inetd and :displaynumber");
261     }
262
263     return 0;
264 }
265
266
267 /*
268  * InitOutput is called every time the server resets.  It should call
269  * AddScreen for each screen (but we only ever have one), and in turn this
270  * will call rfbScreenInit.
271  */
272
273 void
274 InitOutput(screenInfo, argc, argv)
275     ScreenInfo *screenInfo;
276     int argc;
277     char **argv;
278 {
279     initOutputCalled = TRUE;
280
281     rfbLog("rdpsrv version 0.1 - built %s\n", buildtime);
282     rfbLog("Copyright (C) 2005 Steinar H. Gunderson\n");
283     rfbLog("Copyright (C) 2002-2003 RealVNC Ltd.\n");
284     rfbLog("Copyright (C) 1994-2000 AT&T Laboratories Cambridge.\n");
285     rfbLog("All Rights Reserved.\n");
286     rfbLog("See http://www.realvnc.com for information on VNC\n");
287     rfbLog("Desktop name '%s' (%s:%s)\n",desktopName,rfbThisHost,display);
288
289     VNC_LAST_CLIENT_ID = MakeAtom("VNC_LAST_CLIENT_ID",
290                                   strlen("VNC_LAST_CLIENT_ID"), TRUE);
291     VNC_CONNECT = MakeAtom("VNC_CONNECT", strlen("VNC_CONNECT"), TRUE);
292     VNC_DEFER_UPDATE = MakeAtom("VNC_DEFER_UPDATE",
293                                 strlen("VNC_DEFER_UPDATE"), TRUE);
294 /*    rfbInitSockets();
295     if (inetdSock == -1)
296         httpInitSockets(); */
297    
298
299     /* initialize pixmap formats */
300
301     screenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
302     screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
303     screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
304     screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
305     screenInfo->numPixmapFormats = 2;
306
307     screenInfo->formats[0].depth = 1;
308     screenInfo->formats[0].bitsPerPixel = 1;
309     screenInfo->formats[0].scanlinePad = BITMAP_SCANLINE_PAD;
310
311     screenInfo->formats[1].depth = rfbScreen.depth;
312     screenInfo->formats[1].bitsPerPixel = rfbBitsPerPixel(rfbScreen.depth);
313     screenInfo->formats[1].scanlinePad = BITMAP_SCANLINE_PAD;
314
315     rfbGCIndex = AllocateGCPrivateIndex();
316     if (rfbGCIndex < 0) {
317         FatalError("InitOutput: AllocateGCPrivateIndex failed\n");
318     }
319
320     if (!AddCallback(&ClientStateCallback, rfbClientStateChange, NULL)) {
321         rfbLog("InitOutput: AddCallback failed\n");
322         return;
323     }
324
325     /* initialize screen */
326
327     if (AddScreen(rfbScreenInit, argc, argv) == -1) {
328         FatalError("Couldn't add screen");
329     }
330 }
331
332
333 static Bool
334 rfbScreenInit(index, pScreen, argc, argv)
335     int index;
336     ScreenPtr pScreen;
337     int argc;
338     char ** argv;
339 {
340     rfbScreenInfoPtr prfb = &rfbScreen;
341     int dpix = 75, dpiy = 75;
342     int ret;
343     char *pbits;
344     VisualPtr vis;
345     extern int monitorResolution;
346
347     if (monitorResolution != 0) {
348         dpix = monitorResolution;
349         dpiy = monitorResolution;
350     }
351
352     prfb->paddedWidthInBytes = PixmapBytePad(prfb->width, prfb->depth);
353     prfb->bitsPerPixel = rfbBitsPerPixel(prfb->depth);
354     pbits = rfbAllocateFramebufferMemory(prfb);
355     if (!pbits) return FALSE;
356
357     if (prfb->bitsPerPixel > 1) {
358         extern int defaultColorVisualClass;
359         if (defaultColorVisualClass != -1) {
360             cfbSetVisualTypes(prfb->depth, (1 << defaultColorVisualClass), 8);
361         } else {
362             cfbSetVisualTypes(prfb->depth, (1 << TrueColor), 8);
363         }
364     }
365
366     switch (prfb->bitsPerPixel)
367     {
368     case 1:
369         ret = mfbScreenInit(pScreen, pbits, prfb->width, prfb->height,
370                             dpix, dpiy, prfb->paddedWidthInBytes * 8);
371         break;
372     case 8:
373         ret = cfbScreenInit(pScreen, pbits, prfb->width, prfb->height,
374                             dpix, dpiy, prfb->paddedWidthInBytes);
375         break;
376     case 16:
377         ret = cfb16ScreenInit(pScreen, pbits, prfb->width, prfb->height,
378                               dpix, dpiy, prfb->paddedWidthInBytes / 2);
379         break;
380     case 32:
381         ret = cfb32ScreenInit(pScreen, pbits, prfb->width, prfb->height,
382                               dpix, dpiy, prfb->paddedWidthInBytes / 4);
383         break;
384     default:
385         return FALSE;
386     }
387
388     if (!ret) return FALSE;
389
390     if (!AllocateGCPrivate(pScreen, rfbGCIndex, sizeof(rfbGCRec))) {
391         FatalError("rfbScreenInit: AllocateGCPrivate failed\n");
392     }
393
394     prfb->cursorIsDrawn = FALSE;
395     prfb->dontSendFramebufferUpdate = FALSE;
396
397     prfb->CloseScreen = pScreen->CloseScreen;
398     prfb->CreateGC = pScreen->CreateGC;
399     prfb->PaintWindowBackground = pScreen->PaintWindowBackground;
400     prfb->PaintWindowBorder = pScreen->PaintWindowBorder;
401     prfb->CopyWindow = pScreen->CopyWindow;
402     prfb->ClearToBackground = pScreen->ClearToBackground;
403     prfb->RestoreAreas = pScreen->RestoreAreas;
404
405 /*    pScreen->CloseScreen = rfbCloseScreen;
406     pScreen->CreateGC = rfbCreateGC;
407     pScreen->PaintWindowBackground = rfbPaintWindowBackground;
408     pScreen->PaintWindowBorder = rfbPaintWindowBorder;
409     pScreen->CopyWindow = rfbCopyWindow;
410     pScreen->ClearToBackground = rfbClearToBackground;
411     pScreen->RestoreAreas = rfbRestoreAreas; 
412
413     pScreen->InstallColormap = rfbInstallColormap;
414     pScreen->UninstallColormap = rfbUninstallColormap;
415     pScreen->ListInstalledColormaps = rfbListInstalledColormaps;
416     pScreen->StoreColors = rfbStoreColors; */
417
418     pScreen->SaveScreen = rfbAlwaysTrue;
419
420     //rfbDCInitialize(pScreen, &rfbPointerCursorFuncs);
421
422     if (noCursor) {
423         pScreen->DisplayCursor = rfbAlwaysTrue;
424         prfb->cursorIsDrawn = TRUE;
425     }
426
427     pScreen->blackPixel = prfb->blackPixel;
428     pScreen->whitePixel = prfb->whitePixel;
429
430     for (vis = pScreen->visuals; vis->vid != pScreen->rootVisual; vis++)
431         ;
432
433     if (!vis) {
434         rfbLog("rfbScreenInit: couldn't find root visual\n");
435         exit(1);
436     }
437
438     if (strcmp(primaryOrder, "") == 0) {
439       if (prfb->depth == 16) { /* use rgb565 for depth 16 */
440         strcpy(primaryOrder, "rgb");
441         redBits = 5;
442         greenBits = 6;
443         blueBits = 5;
444       } else if (prfb->depth == 24) { /* use rgb888 for depth 24 */
445         strcpy(primaryOrder, "rgb");
446         redBits = 8;
447         greenBits = 8;
448         blueBits = 8;
449       }
450     }
451
452     if (strcasecmp(primaryOrder, "rgb") == 0) {
453         vis->offsetBlue = 0;
454         vis->blueMask = (1 << blueBits) - 1;
455         vis->offsetGreen = blueBits;
456         vis->greenMask = ((1 << greenBits) - 1) << vis->offsetGreen;
457         vis->offsetRed = vis->offsetGreen + greenBits;
458         vis->redMask = ((1 << redBits) - 1) << vis->offsetRed;
459     } else if (strcasecmp(primaryOrder, "bgr") == 0) {
460         rfbLog("BGR format %d %d %d\n", blueBits, greenBits, redBits);
461         vis->offsetRed = 0;
462         vis->redMask = (1 << redBits) - 1;
463         vis->offsetGreen = redBits;
464         vis->greenMask = ((1 << greenBits) - 1) << vis->offsetGreen;
465         vis->offsetBlue = vis->offsetGreen + greenBits;
466         vis->blueMask = ((1 << blueBits) - 1) << vis->offsetBlue;
467     }
468
469 #if 0
470     rfbServerFormat.bitsPerPixel = prfb->bitsPerPixel;
471     rfbServerFormat.depth = prfb->depth;
472     rfbServerFormat.bigEndian = !(*(char *)&rfbEndianTest);
473     rfbServerFormat.trueColour = (vis->class == TrueColor);
474     if (rfbServerFormat.trueColour) {
475         rfbServerFormat.redMax = vis->redMask >> vis->offsetRed;
476         rfbServerFormat.greenMax = vis->greenMask >> vis->offsetGreen;
477         rfbServerFormat.blueMax = vis->blueMask >> vis->offsetBlue;
478         rfbServerFormat.redShift = vis->offsetRed;
479         rfbServerFormat.greenShift = vis->offsetGreen;
480         rfbServerFormat.blueShift = vis->offsetBlue;
481     } else {
482         rfbServerFormat.redMax
483             = rfbServerFormat.greenMax = rfbServerFormat.blueMax = 0;
484         rfbServerFormat.redShift
485             = rfbServerFormat.greenShift = rfbServerFormat.blueShift = 0;
486     }
487 #endif
488
489     if (prfb->bitsPerPixel == 1)
490     {
491         ret = mfbCreateDefColormap(pScreen);
492     }
493     else
494     {
495         ret = cfbCreateDefColormap(pScreen);
496     }
497
498     return ret;
499
500 } /* end rfbScreenInit */
501
502
503
504 /*
505  * InitInput is also called every time the server resets.  It is called after
506  * InitOutput so we can assume that rfbInitSockets has already been called.
507  */
508
509 void
510 InitInput(argc, argv)
511     int argc;
512     char *argv[];
513 {
514     DeviceIntPtr p, k;
515     k = AddInputDevice(rfbKeybdProc, TRUE);
516     p = AddInputDevice(rfbMouseProc, TRUE);
517     RegisterKeyboardDevice(k);
518     RegisterPointerDevice(p);
519     miRegisterPointerDevice(screenInfo.screens[0], p);
520     mieqInit((DevicePtr)k, (DevicePtr)p);
521     mieqCheckForInput[0] = checkForInput[0];
522     mieqCheckForInput[1] = checkForInput[1];
523     SetInputCheck(&alwaysCheckForInput[0], &alwaysCheckForInput[1]);
524 }
525
526
527 static int
528 rfbKeybdProc(pDevice, onoff)
529     DeviceIntPtr pDevice;
530     int onoff;
531 {
532     KeySymsRec          keySyms;
533     CARD8               modMap[MAP_LENGTH];
534     DevicePtr pDev = (DevicePtr)pDevice;
535
536     switch (onoff)
537     {
538     case DEVICE_INIT: 
539         //KbdDeviceInit(pDevice, &keySyms, modMap);
540 /*      InitKeyboardDeviceStruct(pDev, &keySyms, modMap,
541                                  (BellProcPtr)rfbSendBell,
542                                  (KbdCtrlProcPtr)NoopDDA); */
543             break;
544     case DEVICE_ON: 
545         pDev->on = TRUE;
546         //KbdDeviceOn();
547         break;
548     case DEVICE_OFF: 
549         pDev->on = FALSE;
550         //KbdDeviceOff();
551         break;
552     case DEVICE_CLOSE:
553 /*      if (pDev->on)
554             KbdDeviceOff(); */
555         break;
556     }
557     return Success;
558 }
559
560 static int
561 rfbMouseProc(pDevice, onoff)
562     DeviceIntPtr pDevice;
563     int onoff;
564 {
565     BYTE map[6];
566     DevicePtr pDev = (DevicePtr)pDevice;
567
568     switch (onoff)
569     {
570     case DEVICE_INIT:
571         //PtrDeviceInit();
572         map[1] = 1;
573         map[2] = 2;
574         map[3] = 3;
575         map[4] = 4;
576         map[5] = 5;
577 /*      InitPointerDeviceStruct(pDev, map, 5, miPointerGetMotionEvents,
578                                 PtrDeviceControl,
579                                 miPointerGetMotionBufferSize()); */
580         break;
581
582     case DEVICE_ON:
583         pDev->on = TRUE;
584 //      PtrDeviceOn(pDevice);
585         break;
586
587     case DEVICE_OFF:
588         pDev->on = FALSE;
589 //      PtrDeviceOff();
590         break;
591
592     case DEVICE_CLOSE:
593 /*      if (pDev->on)
594             PtrDeviceOff(); */
595         break;
596     }
597     return Success;
598 }
599
600
601 Bool
602 LegalModifier(key, pDev)
603     unsigned int key;
604     DevicePtr   pDev;
605 {
606     return TRUE;
607 }
608
609
610 void
611 ProcessInputEvents()
612 {
613     /*rfbCheckFds();
614     httpCheckFds(); */
615     if (*mieqCheckForInput[0] != *mieqCheckForInput[1]) {
616         mieqProcessInputEvents();
617         miPointerUpdate();
618     }
619 }
620
621
622 static Bool CheckDisplayNumber(int n)
623 {
624     char fname[32];
625     int sock;
626     struct sockaddr_in addr;
627
628     sock = socket(AF_INET, SOCK_STREAM, 0);
629     addr.sin_family = AF_INET;
630     addr.sin_addr.s_addr = htonl(INADDR_ANY);
631     addr.sin_port = htons(6000+n);
632     if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
633         close(sock);
634         return FALSE;
635     }
636     close(sock);
637
638     sprintf(fname, "/tmp/.X%d-lock", n);
639     if (access(fname, F_OK) == 0)
640         return FALSE;
641
642     sprintf(fname, "/tmp/.X11-unix/X%d", n);
643     if (access(fname, F_OK) == 0)
644         return FALSE;
645
646     sprintf(fname, "/usr/spool/sockets/X11/%d", n);
647     if (access(fname, F_OK) == 0)
648         return FALSE;
649
650     return TRUE;
651 }
652
653
654 void
655 rfbRootPropertyChange(PropertyPtr pProp)
656 {
657 /*    if ((pProp->propertyName == XA_CUT_BUFFER0) && (pProp->type == XA_STRING)
658         && (pProp->format == 8))
659     {
660         rfbGotXCutText(pProp->data, pProp->size);
661  }
662     else */ if ((pProp->propertyName == VNC_CONNECT) && (pProp->type == XA_STRING)
663              && (pProp->format == 8))
664     {
665         if (pProp->size == 0) {
666           rfbClientPtr cl, nextCl;
667           rfbLog("VNC_CONNECT message: disconnecting all clients\n");
668 /*          for (cl = rfbClientHead; cl; cl = nextCl) {
669             nextCl = cl->next;
670             rfbCloseSock(cl->sock);
671           } */
672         } else {
673           int i;
674           rfbClientPtr cl;
675           int port = 5500;
676           char *host = (char *)Xalloc(pProp->size+1);
677           memcpy(host, pProp->data, pProp->size);
678           host[pProp->size] = 0;
679           for (i = 0; i < pProp->size; i++) {
680             if (host[i] == ':') {
681               port = atoi(&host[i+1]);
682               host[i] = 0;
683             }
684           }
685
686 //          cl = rfbReverseConnection(host, port);
687
688           free(host);
689         }
690         return;
691     }
692     else if ((pProp->propertyName == VNC_DEFER_UPDATE) &&
693              (pProp->type == XA_STRING) && (pProp->format == 8))
694     {
695       char *str = (char *)Xalloc(pProp->size+1);
696       memcpy(str, pProp->data, pProp->size);
697       str[pProp->size] = 0;
698       //rfbDeferUpdateTime = atoi(str);
699       free(str);
700     }
701 }
702
703
704 int
705 rfbBitsPerPixel(depth)
706     int depth;
707 {
708     if (depth == 1) return 1;
709     else if (depth <= 8) return 8;
710     else if (depth <= 16) return 16;
711     else return 32;
712 }
713
714
715 static Bool
716 rfbAlwaysTrue()
717 {
718     return TRUE;
719 }
720
721
722 static char *
723 rfbAllocateFramebufferMemory(prfb)
724     rfbScreenInfoPtr prfb;
725 {
726     if (prfb->pfbMemory) return prfb->pfbMemory; /* already done */
727
728     prfb->sizeInBytes = (prfb->paddedWidthInBytes * prfb->height);
729
730     prfb->pfbMemory = (char *)Xalloc(prfb->sizeInBytes);
731
732     return prfb->pfbMemory;
733 }
734
735
736 static Bool
737 rfbCursorOffScreen (ppScreen, x, y)
738     ScreenPtr   *ppScreen;
739     int         *x, *y;
740 {
741     return FALSE;
742 }
743
744 static void
745 rfbCrossScreen (pScreen, entering)
746     ScreenPtr   pScreen;
747     Bool        entering;
748 {
749 }
750
751 static void
752 rfbClientStateChange(cbl, myData, clt)
753     CallbackListPtr *cbl;
754     pointer myData;
755     pointer clt;
756 {
757     dispatchException &= ~DE_RESET;     /* hack - force server not to reset */
758 }
759
760 void
761 ddxGiveUp()
762 {
763     Xfree(rfbScreen.pfbMemory);
764     if (initOutputCalled) {
765         char unixSocketName[256];
766         sprintf(unixSocketName,"/tmp/.X11-unix/X%s",display);
767         unlink(unixSocketName);
768         sprintf(unixSocketName,"/usr/spool/sockets/X11/%s",display);
769         unlink(unixSocketName);
770     }
771 }
772
773 void
774 AbortDDX()
775 {
776     ddxGiveUp();
777 }
778
779 void
780 OsVendorInit()
781 {
782 }
783
784 void
785 OsVendorFatalError()
786 {
787 }
788
789 #ifdef DDXTIME /* from ServerOSDefines */
790 CARD32
791 GetTimeInMillis()
792 {
793     struct timeval  tp;
794
795     X_GETTIMEOFDAY(&tp);
796     return(tp.tv_sec * 1000) + (tp.tv_usec / 1000);
797 }
798 #endif
799
800 void
801 ddxUseMsg()
802 {
803     ErrorF("\nXvnc version %s - built %s\n\n", XVNCRELEASE, buildtime);
804     ErrorF("-geometry WxH          set framebuffer width & height\n");
805     ErrorF("-depth D               set framebuffer depth\n");
806     ErrorF("-pixelformat format    set pixel format (BGRnnn or RGBnnn)\n");
807     ErrorF("-rfbport port          TCP port for RFB protocol\n");
808     ErrorF("-rfbwait time          max time in ms to wait for RFB client\n");
809     ErrorF("-nocursor              don't put up a cursor\n");
810     ErrorF("-rfbauth passwd-file   use authentication on RFB protocol\n");
811     ErrorF("-httpd dir             serve files via HTTP from here\n");
812     ErrorF("-httpport port         port for HTTP\n");
813     ErrorF("-deferupdate time      time in ms to defer updates "
814                                                              "(default 40)\n");
815     ErrorF("-economictranslate     less memory-hungry translation\n");
816     ErrorF("-maxrects num          max number of rectangles in an update "
817                                                              "(default 50)\n");
818     ErrorF("-desktop name          VNC desktop name (default x11)\n");
819     ErrorF("-alwaysshared          always treat new clients as shared\n");
820     ErrorF("-nevershared           never treat new clients as shared\n");
821     ErrorF("-dontdisconnect        don't disconnect existing clients when a "
822                                                              "new non-shared\n"
823            "                       connection comes in (refuse new connection "
824                                                                  "instead)\n");
825     ErrorF("-localhost             only allow connections from localhost\n");
826     ErrorF("-inetd                 Xvnc is launched by inetd\n");
827     exit(1);
828 }
829
830 /*
831  * rfbLog prints a time-stamped message to the log file (stderr).
832  */
833
834 void rfbLog(char *format, ...)
835 {
836     va_list args;
837     char buf[256];
838     time_t clock;
839
840     va_start(args, format);
841
842     time(&clock);
843     strftime(buf, 255, "%d/%m/%y %T ", localtime(&clock));
844     fprintf(stderr, buf);
845
846     vfprintf(stderr, format, args);
847     fflush(stderr);
848
849     va_end(args);
850 }
851
852 void rfbLogPerror(char *str)
853 {
854     rfbLog("");
855     perror(str);
856 }