blob: 91a654f43f53af2fc6d046cbd45470678b4b57ac [file] [log] [blame]
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +00001/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
2 *
3 * This is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This software is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 * USA.
17 */
18
19/*
20
21Copyright (c) 1993 X Consortium
22
23Permission is hereby granted, free of charge, to any person obtaining
24a copy of this software and associated documentation files (the
25"Software"), to deal in the Software without restriction, including
26without limitation the rights to use, copy, modify, merge, publish,
27distribute, sublicense, and/or sell copies of the Software, and to
28permit persons to whom the Software is furnished to do so, subject to
29the following conditions:
30
31The above copyright notice and this permission notice shall be included
32in all copies or substantial portions of the Software.
33
34THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
35OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
36MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
37IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
38OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
39ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
40OTHER DEALINGS IN THE SOFTWARE.
41
42Except as contained in this notice, the name of the X Consortium shall
43not be used in advertising or otherwise to promote the sale, use or
44other dealings in this Software without prior written authorization
45from the X Consortium.
46
47*/
48
49#include <rfb/Configuration.h>
50#include <rfb/Logger_stdio.h>
51#include <rfb/LogWriter.h>
52#include <network/TcpSocket.h>
53#include "vncExtInit.h"
54
55extern "C" {
56#define class c_class
57#define public c_public
58#define xor c_xor
59#define and c_and
60#ifdef WIN32
61#include <X11/Xwinsock.h>
62#endif
63#include <stdio.h>
64#include "X11/X.h"
65#define NEED_EVENTS
66#include "X11/Xproto.h"
67#include "X11/Xos.h"
68#include "scrnintstr.h"
69#include "servermd.h"
Peter Åstrand1bdab802005-02-14 14:03:35 +000070#include "fb.h"
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +000071#include "mi.h"
72#include "mibstore.h"
73#include "colormapst.h"
74#include "gcstruct.h"
75#include "input.h"
76#include "mipointer.h"
77#include <sys/types.h>
78#include <sys/stat.h>
79#include <errno.h>
80#ifndef WIN32
81#include <sys/param.h>
82#endif
83#include <X11/XWDFile.h>
84#include "dix.h"
85#include "miline.h"
86#include "inputstr.h"
87#include "keysym.h"
88 extern int defaultColorVisualClass;
89 extern char buildtime[];
90#undef class
91#undef public
92#undef xor
93#undef and
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +000094}
95
96#define XVNCVERSION "4.0"
97
98extern char *display;
99extern int monitorResolution;
100
101#define VFB_DEFAULT_WIDTH 1024
102#define VFB_DEFAULT_HEIGHT 768
103#define VFB_DEFAULT_DEPTH 16
104#define VFB_DEFAULT_WHITEPIXEL 0xffff
105#define VFB_DEFAULT_BLACKPIXEL 0
106#define VFB_DEFAULT_LINEBIAS 0
107#define XWD_WINDOW_NAME_LEN 60
108
109typedef struct
110{
111 int scrnum;
112 int width;
Peter Åstrand4efcfe02005-02-22 21:00:26 +0000113 int paddedBytesWidth;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000114 int paddedWidth;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000115 int height;
116 int depth;
117 int bitsPerPixel;
118 int sizeInBytes;
119 int ncolors;
120 char *pfbMemory;
121 XWDColor *pXWDCmap;
122 XWDFileHeader *pXWDHeader;
123 Pixel blackPixel;
124 Pixel whitePixel;
125 unsigned int lineBias;
126 Bool pixelFormatDefined;
127 Bool rgbNotBgr;
128 int redBits, greenBits, blueBits;
129
130} vfbScreenInfo, *vfbScreenInfoPtr;
131
132static int vfbNumScreens;
133static vfbScreenInfo vfbScreens[MAXSCREENS];
134static Bool vfbPixmapDepths[33];
Peter Åstrand00c759d2005-02-22 20:11:47 +0000135#ifdef HAS_MMAP
136static char *pfbdir = NULL;
137#endif
138typedef enum { NORMAL_MEMORY_FB, SHARED_MEMORY_FB, MMAPPED_FILE_FB } fbMemType;
139static fbMemType fbmemtype = NORMAL_MEMORY_FB;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000140static char needswap = 0;
141static int lastScreen = -1;
Peter Åstrandc5421b22005-02-14 20:25:49 +0000142static Bool Render = TRUE;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000143
144static bool displaySpecified = false;
145static bool wellKnownSocketsCreated = false;
146static char displayNumStr[16];
147
148#define swapcopy16(_dst, _src) \
149 if (needswap) { CARD16 _s = _src; cpswaps(_s, _dst); } \
150 else _dst = _src;
151
152#define swapcopy32(_dst, _src) \
153 if (needswap) { CARD32 _s = _src; cpswapl(_s, _dst); } \
154 else _dst = _src;
155
156
Peter Åstrandf960f042005-02-22 20:07:55 +0000157static void
158vfbInitializePixmapDepths(void)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000159{
Peter Åstrandf960f042005-02-22 20:07:55 +0000160 int i;
161 vfbPixmapDepths[1] = TRUE; /* always need bitmaps */
162 for (i = 2; i <= 32; i++)
163 vfbPixmapDepths[i] = FALSE;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000164}
165
Peter Åstrandf960f042005-02-22 20:07:55 +0000166static void
167vfbInitializeDefaultScreens(void)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000168{
Peter Åstrandf960f042005-02-22 20:07:55 +0000169 int i;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000170
Peter Åstrandf960f042005-02-22 20:07:55 +0000171 for (i = 0; i < MAXSCREENS; i++)
172 {
173 vfbScreens[i].scrnum = i;
174 vfbScreens[i].width = VFB_DEFAULT_WIDTH;
175 vfbScreens[i].height = VFB_DEFAULT_HEIGHT;
176 vfbScreens[i].depth = VFB_DEFAULT_DEPTH;
177 vfbScreens[i].blackPixel = VFB_DEFAULT_BLACKPIXEL;
178 vfbScreens[i].whitePixel = VFB_DEFAULT_WHITEPIXEL;
179 vfbScreens[i].lineBias = VFB_DEFAULT_LINEBIAS;
180 vfbScreens[i].pixelFormatDefined = FALSE;
181 vfbScreens[i].pfbMemory = NULL;
182 }
183 vfbNumScreens = 1;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000184}
185
Peter Åstrand00c759d2005-02-22 20:11:47 +0000186static int
187vfbBitsPerPixel(int depth)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000188{
Peter Åstrand00c759d2005-02-22 20:11:47 +0000189 if (depth == 1) return 1;
190 else if (depth <= 8) return 8;
191 else if (depth <= 16) return 16;
192 else return 32;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000193}
194
195extern "C" {
Peter Åstrand00c759d2005-02-22 20:11:47 +0000196void
197ddxGiveUp()
198{
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000199 int i;
200
201 /* clean up the framebuffers */
202
Peter Åstrand00c759d2005-02-22 20:11:47 +0000203 switch (fbmemtype)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000204 {
Peter Åstrand00c759d2005-02-22 20:11:47 +0000205#ifdef HAS_MMAP
206 case MMAPPED_FILE_FB:
207 for (i = 0; i < vfbNumScreens; i++)
208 {
209 if (-1 == unlink(vfbScreens[i].mmap_file))
210 {
211 perror("unlink");
212 ErrorF("unlink %s failed, errno %d",
213 vfbScreens[i].mmap_file, errno);
214 }
215 }
216 break;
217#else /* HAS_MMAP */
218 case MMAPPED_FILE_FB:
219 break;
220#endif /* HAS_MMAP */
221
222#ifdef HAS_SHM
223 case SHARED_MEMORY_FB:
224 for (i = 0; i < vfbNumScreens; i++)
225 {
226 if (-1 == shmdt((char *)vfbScreens[i].pXWDHeader))
227 {
228 perror("shmdt");
229 ErrorF("shmdt failed, errno %d", errno);
230 }
231 }
232 break;
233#else /* HAS_SHM */
234 case SHARED_MEMORY_FB:
235 break;
236#endif /* HAS_SHM */
237
238 case NORMAL_MEMORY_FB:
239 for (i = 0; i < vfbNumScreens; i++)
240 {
241 Xfree(vfbScreens[i].pXWDHeader);
242 }
243 break;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000244 }
Peter Åstrand00c759d2005-02-22 20:11:47 +0000245}
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000246
Peter Åstrand5b1d7a22005-02-22 20:18:24 +0000247void
248AbortDDX()
249{
250 ddxGiveUp();
251}
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000252
Peter Åstrand5b1d7a22005-02-22 20:18:24 +0000253#ifdef __DARWIN__
254void
255DarwinHandleGUI(int argc, char *argv[])
256{
257}
258
259void GlxExtensionInit();
260void GlxWrapInitVisuals(void *procPtr);
261
262void
263DarwinGlxExtensionInit()
264{
265 GlxExtensionInit();
266}
267
268void
269DarwinGlxWrapInitVisuals(
270 void *procPtr)
271{
272 GlxWrapInitVisuals(procPtr);
273}
274#endif
275
276void
277OsVendorInit()
278{
279}
280
281void
282OsVendorFatalError()
283{
284}
285
286void ddxBeforeReset(void)
287{
288 return;
289}
290
291void
292ddxUseMsg()
293{
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000294 ErrorF("\nXvnc version %s - built %s\n", XVNCVERSION, buildtime);
295 ErrorF("Underlying X server release %d, %s\n\n", VENDOR_RELEASE,
296 VENDOR_STRING);
297 ErrorF("-screen scrn WxHxD set screen's width, height, depth\n");
298 ErrorF("-pixdepths list-of-int support given pixmap depths\n");
Peter Åstrandc5421b22005-02-14 20:25:49 +0000299#ifdef RENDER
300 ErrorF("+/-render turn on/off RENDER extension support"
301 "(default on)\n");
302#endif
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000303 ErrorF("-linebias n adjust thin line pixelization\n");
304 ErrorF("-blackpixel n pixel value for black\n");
305 ErrorF("-whitepixel n pixel value for white\n");
Peter Åstrand5b1d7a22005-02-22 20:18:24 +0000306
307#ifdef HAS_MMAP
308 ErrorF("-fbdir directory put framebuffers in mmap'ed files in directory\n");
309#endif
310
311#ifdef HAS_SHM
312 ErrorF("-shmem put framebuffers in shared memory\n");
313#endif
314
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000315 ErrorF("-geometry WxH set screen 0's width, height\n");
316 ErrorF("-depth D set screen 0's depth\n");
317 ErrorF("-pixelformat fmt set pixel format (rgbNNN or bgrNNN)\n");
318 ErrorF("-inetd has been launched from inetd\n");
319 ErrorF("\nVNC parameters:\n");
320
321 fprintf(stderr,"\n"
322 "Parameters can be turned on with -<param> or off with -<param>=0\n"
323 "Parameters which take a value can be specified as "
324 "-<param> <value>\n"
325 "Other valid forms are <param>=<value> -<param>=<value> "
326 "--<param>=<value>\n"
327 "Parameter names are case-insensitive. The parameters are:\n\n");
328 rfb::Configuration::listParams(79, 14);
329 }
330}
331
Peter Åstrandfc41a212005-02-22 20:29:40 +0000332/* ddxInitGlobals - called by |InitGlobals| from os/util.c */
333void ddxInitGlobals(void)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000334{
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000335}
336
Peter Åstrandfc41a212005-02-22 20:29:40 +0000337static
338bool displayNumFree(int num)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000339{
Peter Åstrandfc41a212005-02-22 20:29:40 +0000340 try {
341 network::TcpListener l(6000+num);
342 } catch (rdr::Exception& e) {
343 return false;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000344 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000345 char file[256];
346 sprintf(file, "/tmp/.X%d-lock", num);
347 if (access(file, F_OK) == 0) return false;
348 sprintf(file, "/tmp/.X11-unix/X%d", num);
349 if (access(file, F_OK) == 0) return false;
350 sprintf(file, "/usr/spool/sockets/X11/%d", num);
351 if (access(file, F_OK) == 0) return false;
352 return true;
353}
354
355int
356ddxProcessArgument(int argc, char *argv[], int i)
357{
358 static Bool firstTime = TRUE;
359
360 if (firstTime)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000361 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000362 vfbInitializeDefaultScreens();
363 vfbInitializePixmapDepths();
364 firstTime = FALSE;
365 rfb::initStdIOLoggers();
366 rfb::LogWriter::setLogParams("*:stderr:30");
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000367 }
368
Peter Åstrandfc41a212005-02-22 20:29:40 +0000369 if (argv[i][0] == ':')
370 displaySpecified = true;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000371
Peter Åstrandfc41a212005-02-22 20:29:40 +0000372 if (strcmp (argv[i], "-screen") == 0) /* -screen n WxHxD */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000373 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000374 int screenNum;
375 if (i + 2 >= argc) UseMsg();
376 screenNum = atoi(argv[i+1]);
377 if (screenNum < 0 || screenNum >= MAXSCREENS)
378 {
379 ErrorF("Invalid screen number %d\n", screenNum);
380 UseMsg();
381 }
382 if (3 != sscanf(argv[i+2], "%dx%dx%d",
383 &vfbScreens[screenNum].width,
384 &vfbScreens[screenNum].height,
385 &vfbScreens[screenNum].depth))
386 {
387 ErrorF("Invalid screen configuration %s\n", argv[i+2]);
388 UseMsg();
389 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000390
Peter Åstrandfc41a212005-02-22 20:29:40 +0000391 if (screenNum >= vfbNumScreens)
392 vfbNumScreens = screenNum + 1;
393 lastScreen = screenNum;
394 return 3;
395 }
396
397 if (strcmp (argv[i], "-pixdepths") == 0) /* -pixdepths list-of-depth */
398 {
399 int depth, ret = 1;
400
401 if (++i >= argc) UseMsg();
402 while ((i < argc) && (depth = atoi(argv[i++])) != 0)
403 {
404 if (depth < 0 || depth > 32)
405 {
406 ErrorF("Invalid pixmap depth %d\n", depth);
407 UseMsg();
408 }
409 vfbPixmapDepths[depth] = TRUE;
410 ret++;
411 }
412 return ret;
413 }
414
415 if (strcmp (argv[i], "+render") == 0) /* +render */
416 {
417 Render = TRUE;
418 return 1;
419 }
Peter Åstrandc5421b22005-02-14 20:25:49 +0000420
Peter Åstrandfc41a212005-02-22 20:29:40 +0000421 if (strcmp (argv[i], "-render") == 0) /* -render */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000422 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000423 Render = FALSE;
424 return 1;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000425 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000426
Peter Åstrandfc41a212005-02-22 20:29:40 +0000427 if (strcmp (argv[i], "-blackpixel") == 0) /* -blackpixel n */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000428 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000429 Pixel pix;
430 if (++i >= argc) UseMsg();
431 pix = atoi(argv[i]);
432 if (-1 == lastScreen)
433 {
434 int i;
435 for (i = 0; i < MAXSCREENS; i++)
436 {
437 vfbScreens[i].blackPixel = pix;
438 }
439 }
440 else
441 {
442 vfbScreens[lastScreen].blackPixel = pix;
443 }
444 return 2;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000445 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000446
447 if (strcmp (argv[i], "-whitepixel") == 0) /* -whitepixel n */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000448 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000449 Pixel pix;
450 if (++i >= argc) UseMsg();
451 pix = atoi(argv[i]);
452 if (-1 == lastScreen)
453 {
454 int i;
455 for (i = 0; i < MAXSCREENS; i++)
456 {
457 vfbScreens[i].whitePixel = pix;
458 }
459 }
460 else
461 {
462 vfbScreens[lastScreen].whitePixel = pix;
463 }
464 return 2;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000465 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000466
467 if (strcmp (argv[i], "-linebias") == 0) /* -linebias n */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000468 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000469 unsigned int linebias;
470 if (++i >= argc) UseMsg();
471 linebias = atoi(argv[i]);
472 if (-1 == lastScreen)
473 {
474 int i;
475 for (i = 0; i < MAXSCREENS; i++)
476 {
477 vfbScreens[i].lineBias = linebias;
478 }
479 }
480 else
481 {
482 vfbScreens[lastScreen].lineBias = linebias;
483 }
484 return 2;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000485 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000486
487#ifdef HAS_MMAP
488 if (strcmp (argv[i], "-fbdir") == 0) /* -fbdir directory */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000489 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000490 if (++i >= argc) UseMsg();
491 pfbdir = argv[i];
492 fbmemtype = MMAPPED_FILE_FB;
493 return 2;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000494 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000495#endif /* HAS_MMAP */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000496
Peter Åstrandfc41a212005-02-22 20:29:40 +0000497#ifdef HAS_SHM
498 if (strcmp (argv[i], "-shmem") == 0) /* -shmem */
499 {
500 fbmemtype = SHARED_MEMORY_FB;
501 return 1;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000502 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000503#endif
504
505 if (strcmp(argv[i], "-geometry") == 0)
506 {
507 if (++i >= argc) UseMsg();
508 if (sscanf(argv[i],"%dx%d",&vfbScreens[0].width,
509 &vfbScreens[0].height) != 2) {
510 ErrorF("Invalid geometry %s\n", argv[i]);
511 UseMsg();
512 }
513 return 2;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000514 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000515
516 if (strcmp(argv[i], "-depth") == 0)
517 {
518 if (++i >= argc) UseMsg();
519 vfbScreens[0].depth = atoi(argv[i]);
520 return 2;
521 }
522
523 if (strcmp(argv[i], "-pixelformat") == 0)
524 {
525 char rgbbgr[4];
526 int bits1, bits2, bits3;
527 if (++i >= argc) UseMsg();
528 if (sscanf(argv[i], "%3s%1d%1d%1d", rgbbgr,&bits1,&bits2,&bits3) < 4) {
529 ErrorF("Invalid pixel format %s\n", argv[i]);
530 UseMsg();
531 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000532
533#define SET_PIXEL_FORMAT(vfbScreen) \
534 (vfbScreen).pixelFormatDefined = TRUE; \
535 (vfbScreen).depth = bits1 + bits2 + bits3; \
536 (vfbScreen).greenBits = bits2; \
537 if (strcasecmp(rgbbgr, "bgr") == 0) { \
538 (vfbScreen).rgbNotBgr = FALSE; \
539 (vfbScreen).redBits = bits3; \
540 (vfbScreen).blueBits = bits1; \
541 } else if (strcasecmp(rgbbgr, "rgb") == 0) { \
542 (vfbScreen).rgbNotBgr = TRUE; \
543 (vfbScreen).redBits = bits1; \
544 (vfbScreen).blueBits = bits3; \
545 } else { \
546 ErrorF("Invalid pixel format %s\n", argv[i]); \
547 UseMsg(); \
548 }
549
Peter Åstrandfc41a212005-02-22 20:29:40 +0000550 if (-1 == lastScreen)
551 {
552 int i;
553 for (i = 0; i < MAXSCREENS; i++)
554 {
555 SET_PIXEL_FORMAT(vfbScreens[i]);
556 }
557 }
558 else
559 {
560 SET_PIXEL_FORMAT(vfbScreens[lastScreen]);
561 }
562
563 return 2;
564 }
565
566 if (strcmp(argv[i], "-inetd") == 0)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000567 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000568 dup2(0,3);
569 vncInetdSock = 3;
570 close(2);
571
572 if (!displaySpecified) {
573 int port = network::TcpSocket::getSockPort(vncInetdSock);
574 int displayNum = port - 5900;
575 if (displayNum < 0 || displayNum > 99 || !displayNumFree(displayNum)) {
576 for (displayNum = 1; displayNum < 100; displayNum++)
577 if (displayNumFree(displayNum)) break;
578
579 if (displayNum == 100)
580 FatalError("Xvnc error: no free display number for -inetd");
581 }
582
583 display = displayNumStr;
584 sprintf(displayNumStr, "%d", displayNum);
585 }
586
587 return 1;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000588 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000589
590 if (rfb::Configuration::setParam(argv[i]))
591 return 1;
592
593 if (argv[i][0] == '-' && i+1 < argc) {
594 if (rfb::Configuration::setParam(&argv[i][1], argv[i+1]))
595 return 2;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000596 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000597
598 return 0;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000599}
600
601#ifdef DDXTIME /* from ServerOSDefines */
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000602CARD32
603GetTimeInMillis()
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000604{
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000605 struct timeval tp;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000606
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000607 X_GETTIMEOFDAY(&tp);
608 return(tp.tv_sec * 1000) + (tp.tv_usec / 1000);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000609}
610#endif
611
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000612static ColormapPtr InstalledMaps[MAXSCREENS];
613
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000614static int
615vfbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000616{
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000617 /* By the time we are processing requests, we can guarantee that there
618 * is always a colormap installed */
619 *pmaps = InstalledMaps[pScreen->myNum]->mid;
620 return (1);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000621}
622
623
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000624static void
625vfbInstallColormap(ColormapPtr pmap)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000626{
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000627 int index = pmap->pScreen->myNum;
628 ColormapPtr oldpmap = InstalledMaps[index];
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000629
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000630 if (pmap != oldpmap)
631 {
632 int entries;
633 XWDFileHeader *pXWDHeader;
634 XWDColor *pXWDCmap;
635 VisualPtr pVisual;
636 Pixel * ppix;
637 xrgb * prgb;
638 xColorItem *defs;
639 int i;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000640
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000641 if(oldpmap != (ColormapPtr)None)
642 WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
643 /* Install pmap */
644 InstalledMaps[index] = pmap;
645 WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000646
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000647 entries = pmap->pVisual->ColormapEntries;
648 pXWDHeader = vfbScreens[pmap->pScreen->myNum].pXWDHeader;
649 pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
650 pVisual = pmap->pVisual;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000651
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000652 swapcopy32(pXWDHeader->visual_class, pVisual->c_class);
653 swapcopy32(pXWDHeader->red_mask, pVisual->redMask);
654 swapcopy32(pXWDHeader->green_mask, pVisual->greenMask);
655 swapcopy32(pXWDHeader->blue_mask, pVisual->blueMask);
656 swapcopy32(pXWDHeader->bits_per_rgb, pVisual->bitsPerRGBValue);
657 swapcopy32(pXWDHeader->colormap_entries, pVisual->ColormapEntries);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000658
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000659 ppix = (Pixel *)ALLOCATE_LOCAL(entries * sizeof(Pixel));
660 prgb = (xrgb *)ALLOCATE_LOCAL(entries * sizeof(xrgb));
661 defs = (xColorItem *)ALLOCATE_LOCAL(entries * sizeof(xColorItem));
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000662
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000663 for (i = 0; i < entries; i++) ppix[i] = i;
664 /* XXX truecolor */
665 QueryColors(pmap, entries, ppix, prgb);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000666
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000667 for (i = 0; i < entries; i++) { /* convert xrgbs to xColorItems */
668 defs[i].pixel = ppix[i] & 0xff; /* change pixel to index */
669 defs[i].red = prgb[i].red;
670 defs[i].green = prgb[i].green;
671 defs[i].blue = prgb[i].blue;
672 defs[i].flags = DoRed|DoGreen|DoBlue;
673 }
674 (*pmap->pScreen->StoreColors)(pmap, entries, defs);
675
676 DEALLOCATE_LOCAL(ppix);
677 DEALLOCATE_LOCAL(prgb);
678 DEALLOCATE_LOCAL(defs);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000679 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000680}
681
Peter Åstrand853287d2005-02-22 20:46:58 +0000682static void
683vfbUninstallColormap(ColormapPtr pmap)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000684{
Peter Åstrand853287d2005-02-22 20:46:58 +0000685 ColormapPtr curpmap = InstalledMaps[pmap->pScreen->myNum];
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000686
Peter Åstrand853287d2005-02-22 20:46:58 +0000687 if(pmap == curpmap)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000688 {
Peter Åstrand853287d2005-02-22 20:46:58 +0000689 if (pmap->mid != pmap->pScreen->defColormap)
690 {
691 curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap,
692 RT_COLORMAP);
693 (*pmap->pScreen->InstallColormap)(curpmap);
694 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000695 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000696}
697
Peter Åstrand853287d2005-02-22 20:46:58 +0000698static void
699vfbStoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000700{
Peter Åstrand853287d2005-02-22 20:46:58 +0000701 XWDColor *pXWDCmap;
702 int i;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000703
Peter Åstrand853287d2005-02-22 20:46:58 +0000704 if (pmap != InstalledMaps[pmap->pScreen->myNum])
705 {
706 return;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000707 }
Peter Åstrand853287d2005-02-22 20:46:58 +0000708
709 pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
710
Peter Åstrandbe228572005-02-22 20:48:29 +0000711 if ((pmap->pVisual->c_class | DynamicClass) == DirectColor)
Peter Åstrand853287d2005-02-22 20:46:58 +0000712 {
713 return;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000714 }
Peter Åstrand853287d2005-02-22 20:46:58 +0000715
716 for (i = 0; i < ndef; i++)
717 {
718 if (pdefs[i].flags & DoRed)
719 {
720 swapcopy16(pXWDCmap[pdefs[i].pixel].red, pdefs[i].red);
721 }
722 if (pdefs[i].flags & DoGreen)
723 {
724 swapcopy16(pXWDCmap[pdefs[i].pixel].green, pdefs[i].green);
725 }
726 if (pdefs[i].flags & DoBlue)
727 {
728 swapcopy16(pXWDCmap[pdefs[i].pixel].blue, pdefs[i].blue);
729 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000730 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000731}
732
Peter Åstrand853287d2005-02-22 20:46:58 +0000733static Bool
734vfbSaveScreen(ScreenPtr pScreen, int on)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000735{
Peter Åstrand853287d2005-02-22 20:46:58 +0000736 return TRUE;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000737}
738
Peter Åstrand8de329f2005-02-22 21:05:16 +0000739static char *
740vfbAllocateFramebufferMemory(vfbScreenInfoPtr pvfb)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000741{
Peter Åstrand8de329f2005-02-22 21:05:16 +0000742 if (pvfb->pfbMemory) return pvfb->pfbMemory; /* already done */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000743
Peter Åstrand8de329f2005-02-22 21:05:16 +0000744 pvfb->sizeInBytes = pvfb->paddedBytesWidth * pvfb->height;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000745
Peter Åstrand8de329f2005-02-22 21:05:16 +0000746 /* Calculate how many entries in colormap. This is rather bogus, because
747 * the visuals haven't even been set up yet, but we need to know because we
748 * have to allocate space in the file for the colormap. The number 10
749 * below comes from the MAX_PSEUDO_DEPTH define in cfbcmap.c.
750 */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000751
Peter Åstrand8de329f2005-02-22 21:05:16 +0000752 if (pvfb->depth <= 10)
753 { /* single index colormaps */
754 pvfb->ncolors = 1 << pvfb->depth;
755 }
756 else
757 { /* decomposed colormaps */
758 int nplanes_per_color_component = pvfb->depth / 3;
759 if (pvfb->depth % 3) nplanes_per_color_component++;
760 pvfb->ncolors = 1 << nplanes_per_color_component;
761 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000762
Peter Åstrand8de329f2005-02-22 21:05:16 +0000763 /* add extra bytes for XWDFileHeader, window name, and colormap */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000764
Peter Åstrand8de329f2005-02-22 21:05:16 +0000765 pvfb->sizeInBytes += SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN +
766 pvfb->ncolors * SIZEOF(XWDColor);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000767
Peter Åstrand8de329f2005-02-22 21:05:16 +0000768 pvfb->pXWDHeader = NULL;
769 switch (fbmemtype)
770 {
771#ifdef HAS_MMAP
772 case MMAPPED_FILE_FB: vfbAllocateMmappedFramebuffer(pvfb); break;
773#else
774 case MMAPPED_FILE_FB: break;
775#endif
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000776
Peter Åstrand8de329f2005-02-22 21:05:16 +0000777#ifdef HAS_SHM
778 case SHARED_MEMORY_FB: vfbAllocateSharedMemoryFramebuffer(pvfb); break;
779#else
780 case SHARED_MEMORY_FB: break;
781#endif
782
783 case NORMAL_MEMORY_FB:
784 pvfb->pXWDHeader = (XWDFileHeader *)Xalloc(pvfb->sizeInBytes);
785 break;
786 }
787
788 if (pvfb->pXWDHeader)
789 {
790 pvfb->pXWDCmap = (XWDColor *)((char *)pvfb->pXWDHeader
791 + SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN);
792 pvfb->pfbMemory = (char *)(pvfb->pXWDCmap + pvfb->ncolors);
793
794 return pvfb->pfbMemory;
795 }
796 else
797 return NULL;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000798}
799
Peter Åstrandf9357f52005-02-22 21:08:02 +0000800static void
801vfbWriteXWDFileHeader(ScreenPtr pScreen)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000802{
Peter Åstrandf9357f52005-02-22 21:08:02 +0000803 vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
804 XWDFileHeader *pXWDHeader = pvfb->pXWDHeader;
805 char hostname[XWD_WINDOW_NAME_LEN];
806 unsigned long swaptest = 1;
807 int i;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000808
Peter Åstrandf9357f52005-02-22 21:08:02 +0000809 needswap = *(char *) &swaptest;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000810
Peter Åstrandf9357f52005-02-22 21:08:02 +0000811 pXWDHeader->header_size = (char *)pvfb->pXWDCmap - (char *)pvfb->pXWDHeader;
812 pXWDHeader->file_version = XWD_FILE_VERSION;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000813
Peter Åstrandf9357f52005-02-22 21:08:02 +0000814 pXWDHeader->pixmap_format = ZPixmap;
815 pXWDHeader->pixmap_depth = pvfb->depth;
816 pXWDHeader->pixmap_height = pXWDHeader->window_height = pvfb->height;
817 pXWDHeader->xoffset = 0;
818 pXWDHeader->byte_order = IMAGE_BYTE_ORDER;
819 pXWDHeader->bitmap_bit_order = BITMAP_BIT_ORDER;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000820#ifndef INTERNAL_VS_EXTERNAL_PADDING
Peter Åstrandf9357f52005-02-22 21:08:02 +0000821 pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->width;
822 pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT;
823 pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000824#else
Peter Åstrandf9357f52005-02-22 21:08:02 +0000825 pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->paddedWidth;
826 pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT_PROTO;
827 pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD_PROTO;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000828#endif
Peter Åstrandf9357f52005-02-22 21:08:02 +0000829 pXWDHeader->bits_per_pixel = pvfb->bitsPerPixel;
830 pXWDHeader->bytes_per_line = pvfb->paddedBytesWidth;
831 pXWDHeader->ncolors = pvfb->ncolors;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000832
Peter Åstrandf9357f52005-02-22 21:08:02 +0000833 /* visual related fields are written when colormap is installed */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000834
Peter Åstrandf9357f52005-02-22 21:08:02 +0000835 pXWDHeader->window_x = pXWDHeader->window_y = 0;
836 pXWDHeader->window_bdrwidth = 0;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000837
Peter Åstrandf9357f52005-02-22 21:08:02 +0000838 /* write xwd "window" name: Xvfb hostname:server.screen */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000839
Peter Åstrandf9357f52005-02-22 21:08:02 +0000840 if (-1 == gethostname(hostname, sizeof(hostname)))
841 hostname[0] = 0;
842 else
843 hostname[XWD_WINDOW_NAME_LEN-1] = 0;
844 sprintf((char *)(pXWDHeader+1), "Xvfb %s:%s.%d", hostname, display,
845 pScreen->myNum);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000846
Peter Åstrandf9357f52005-02-22 21:08:02 +0000847 /* write colormap pixel slot values */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000848
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000849 for (i = 0; i < pvfb->ncolors; i++)
850 {
Peter Åstrandf9357f52005-02-22 21:08:02 +0000851 pvfb->pXWDCmap[i].pixel = i;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000852 }
Peter Åstrandf9357f52005-02-22 21:08:02 +0000853
854 /* byte swap to most significant byte first */
855
856 if (needswap)
857 {
858 SwapLongs((CARD32 *)pXWDHeader, SIZEOF(XWDheader)/4);
859 for (i = 0; i < pvfb->ncolors; i++)
860 {
861 register char n;
862 swapl(&pvfb->pXWDCmap[i].pixel, n);
863 }
864 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000865}
866
867
Peter Åstrandf9357f52005-02-22 21:08:02 +0000868static Bool
869vfbCursorOffScreen (ScreenPtr *ppScreen, int *x, int *y)
870{
871 return FALSE;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000872}
Peter Åstrandf9357f52005-02-22 21:08:02 +0000873
874static void
875vfbCrossScreen (ScreenPtr pScreen, Bool entering)
876{
877}
878
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000879static Bool vfbRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) {
Peter Åstrand5eef5ee2005-02-22 21:13:14 +0000880 return TRUE;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000881}
Peter Åstrand5eef5ee2005-02-22 21:13:14 +0000882
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000883static Bool vfbUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) {
Peter Åstrand5eef5ee2005-02-22 21:13:14 +0000884 return TRUE;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000885}
Peter Åstrand5eef5ee2005-02-22 21:13:14 +0000886
887static void vfbSetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
888{
889}
890
891static void vfbMoveCursor(ScreenPtr pScreen, int x, int y)
892{
893}
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000894
895static miPointerSpriteFuncRec vfbPointerSpriteFuncs = {
Peter Åstrand5eef5ee2005-02-22 21:13:14 +0000896 vfbRealizeCursor,
897 vfbUnrealizeCursor,
898 vfbSetCursor,
899 vfbMoveCursor
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000900};
901
Peter Åstrand5eef5ee2005-02-22 21:13:14 +0000902static miPointerScreenFuncRec vfbPointerCursorFuncs = {
903 vfbCursorOffScreen,
904 vfbCrossScreen,
905 miPointerWarpCursor
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000906};
907
908static Bool vfbScreenInit(int index, ScreenPtr pScreen, int argc, char** argv)
909{
910 vfbScreenInfoPtr pvfb = &vfbScreens[index];
911 int dpi = 100;
912 int ret;
913 char *pbits;
914
915 if (monitorResolution) dpi = monitorResolution;
916
Peter Åstrand4efcfe02005-02-22 21:00:26 +0000917 pvfb->paddedBytesWidth = PixmapBytePad(pvfb->width, pvfb->depth);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000918 pvfb->bitsPerPixel = vfbBitsPerPixel(pvfb->depth);
Peter Åstrand4efcfe02005-02-22 21:00:26 +0000919 pvfb->paddedWidth = pvfb->paddedBytesWidth * 8 / pvfb->bitsPerPixel;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000920 pbits = vfbAllocateFramebufferMemory(pvfb);
921 if (!pbits) return FALSE;
922 vncFbptr[index] = pbits;
923
924 defaultColorVisualClass
925 = (pvfb->bitsPerPixel > 8) ? TrueColor : PseudoColor;
926
Peter Åstrandc5421b22005-02-14 20:25:49 +0000927 ret = fbScreenInit(pScreen, pbits, pvfb->width, pvfb->height,
928 dpi, dpi, pvfb->paddedWidth, pvfb->bitsPerPixel);
929
930#ifdef RENDER
931 if (ret && Render)
932 fbPictureInit(pScreen, 0, 0);
933#endif
934
935 if (!ret) return FALSE;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000936
937 pScreen->InstallColormap = vfbInstallColormap;
938 pScreen->UninstallColormap = vfbUninstallColormap;
939 pScreen->ListInstalledColormaps = vfbListInstalledColormaps;
940
941 pScreen->SaveScreen = vfbSaveScreen;
942 pScreen->StoreColors = vfbStoreColors;
943
Peter Åstrand5eef5ee2005-02-22 21:13:14 +0000944 miPointerInitialize(pScreen, &vfbPointerSpriteFuncs, &vfbPointerCursorFuncs,
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000945 FALSE);
946
947 vfbWriteXWDFileHeader(pScreen);
948
949 pScreen->blackPixel = pvfb->blackPixel;
950 pScreen->whitePixel = pvfb->whitePixel;
951
952 if (!pvfb->pixelFormatDefined && pvfb->depth == 16) {
953 pvfb->pixelFormatDefined = TRUE;
954 pvfb->rgbNotBgr = TRUE;
955 pvfb->blueBits = pvfb->redBits = 5;
956 pvfb->greenBits = 6;
957 }
958
959 if (pvfb->pixelFormatDefined) {
960 VisualPtr vis;
961 for (vis = pScreen->visuals; vis->vid != pScreen->rootVisual; vis++)
962 ;
963
964 if (pvfb->rgbNotBgr) {
965 vis->offsetBlue = 0;
966 vis->blueMask = (1 << pvfb->blueBits) - 1;
967 vis->offsetGreen = pvfb->blueBits;
968 vis->greenMask = ((1 << pvfb->greenBits) - 1) << vis->offsetGreen;
969 vis->offsetRed = vis->offsetGreen + pvfb->greenBits;
970 vis->redMask = ((1 << pvfb->redBits) - 1) << vis->offsetRed;
971 } else {
972 vis->offsetRed = 0;
973 vis->redMask = (1 << pvfb->redBits) - 1;
974 vis->offsetGreen = pvfb->redBits;
975 vis->greenMask = ((1 << pvfb->greenBits) - 1) << vis->offsetGreen;
976 vis->offsetBlue = vis->offsetGreen + pvfb->greenBits;
977 vis->blueMask = ((1 << pvfb->blueBits) - 1) << vis->offsetBlue;
978 }
979 }
980
Peter Åstrand1bdab802005-02-14 14:03:35 +0000981 ret = fbCreateDefColormap(pScreen);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000982
983 miSetZeroLineBias(pScreen, pvfb->lineBias);
984
985 return ret;
986
987} /* end vfbScreenInit */
988
989
990static void vfbClientStateChange(CallbackListPtr*, pointer, pointer) {
991 dispatchException &= ~DE_RESET;
992}
993
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000994void InitOutput(ScreenInfo *screenInfo, int argc, char **argv)
995{
996 ErrorF("\nXvnc version %s - built %s\n", XVNCVERSION, buildtime);
997 ErrorF("Underlying X server release %d, %s\n\n", VENDOR_RELEASE,
998 VENDOR_STRING);
999 wellKnownSocketsCreated = true;
1000
1001 int i;
1002 int NumFormats = 0;
1003
1004 /* initialize pixmap formats */
1005
1006 /* must have a pixmap depth to match every screen depth */
1007 for (i = 0; i < vfbNumScreens; i++)
1008 {
1009 vfbPixmapDepths[vfbScreens[i].depth] = TRUE;
1010 }
1011
Peter Åstrandc5421b22005-02-14 20:25:49 +00001012 /* RENDER needs a good set of pixmaps. */
1013 if (Render) {
1014 vfbPixmapDepths[1] = TRUE;
1015 vfbPixmapDepths[4] = TRUE;
1016 vfbPixmapDepths[8] = TRUE;
1017/* vfbPixmapDepths[15] = TRUE; */
1018 vfbPixmapDepths[16] = TRUE;
1019 vfbPixmapDepths[24] = TRUE;
1020 vfbPixmapDepths[32] = TRUE;
1021 }
1022
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +00001023 for (i = 1; i <= 32; i++)
1024 {
1025 if (vfbPixmapDepths[i])
1026 {
1027 if (NumFormats >= MAXFORMATS)
1028 FatalError ("MAXFORMATS is too small for this server\n");
1029 screenInfo->formats[NumFormats].depth = i;
1030 screenInfo->formats[NumFormats].bitsPerPixel = vfbBitsPerPixel(i);
1031 screenInfo->formats[NumFormats].scanlinePad = BITMAP_SCANLINE_PAD;
1032 NumFormats++;
1033 }
1034 }
1035
1036 screenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
1037 screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
1038 screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
1039 screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
1040 screenInfo->numPixmapFormats = NumFormats;
1041
1042 /* initialize screens */
1043
1044 for (i = 0; i < vfbNumScreens; i++)
1045 {
1046 if (-1 == AddScreen(vfbScreenInit, argc, argv))
1047 {
1048 FatalError("Couldn't add screen %d", i);
1049 }
1050 }
1051
1052 if (!AddCallback(&ClientStateCallback, vfbClientStateChange, 0)) {
1053 FatalError("AddCallback failed\n");
1054 }
1055
1056} /* end InitOutput */
1057
1058#ifdef DPMSExtension
1059extern "C" {
1060#if NeedFunctionPrototypes
1061 void DPMSSet(CARD16 level)
1062#else
1063 void DPMSSet(level)
1064 CARD16 level;
1065#endif
1066 {
1067 return;
1068 }
1069
1070 Bool DPMSSupported()
1071 {
1072 return FALSE;
1073 }
1074}
1075#endif
1076
1077/* this is just to get the server to link on AIX */
1078#ifdef AIXV3
1079int SelectWaitTime = 10000; /* usec */
1080#endif
1081
1082Bool LegalModifier(unsigned int key, DevicePtr pDev)
1083{
1084 return TRUE;
1085}
1086
1087void ProcessInputEvents()
1088{
1089 mieqProcessInputEvents();
1090 miPointerUpdate();
1091}
1092
1093/* Fairly standard US PC Keyboard */
1094
1095#define VFB_MIN_KEY 8
1096#define VFB_MAX_KEY 255
1097#define VFB_MAP_LEN (VFB_MAX_KEY - VFB_MIN_KEY + 1)
1098#define KEYSYMS_PER_KEY 2
1099KeySym keyboardMap[VFB_MAP_LEN * KEYSYMS_PER_KEY] = {
1100 NoSymbol, NoSymbol,
1101 XK_Escape, NoSymbol,
1102 XK_1, XK_exclam,
1103 XK_2, XK_at,
1104 XK_3, XK_numbersign,
1105 XK_4, XK_dollar,
1106 XK_5, XK_percent,
1107 XK_6, XK_asciicircum,
1108 XK_7, XK_ampersand,
1109 XK_8, XK_asterisk,
1110 XK_9, XK_parenleft,
1111 XK_0, XK_parenright,
1112 XK_minus, XK_underscore,
1113 XK_equal, XK_plus,
1114 XK_BackSpace, NoSymbol,
1115 XK_Tab, NoSymbol,
1116 XK_q, XK_Q,
1117 XK_w, XK_W,
1118 XK_e, XK_E,
1119 XK_r, XK_R,
1120 XK_t, XK_T,
1121 XK_y, XK_Y,
1122 XK_u, XK_U,
1123 XK_i, XK_I,
1124 XK_o, XK_O,
1125 XK_p, XK_P,
1126 XK_bracketleft, XK_braceleft,
1127 XK_bracketright, XK_braceright,
1128 XK_Return, NoSymbol,
1129 XK_Control_L, NoSymbol,
1130 XK_a, XK_A,
1131 XK_s, XK_S,
1132 XK_d, XK_D,
1133 XK_f, XK_F,
1134 XK_g, XK_G,
1135 XK_h, XK_H,
1136 XK_j, XK_J,
1137 XK_k, XK_K,
1138 XK_l, XK_L,
1139 XK_semicolon, XK_colon,
1140 XK_apostrophe, XK_quotedbl,
1141 XK_grave, XK_asciitilde,
1142 XK_Shift_L, NoSymbol,
1143 XK_backslash, XK_bar,
1144 XK_z, XK_Z,
1145 XK_x, XK_X,
1146 XK_c, XK_C,
1147 XK_v, XK_V,
1148 XK_b, XK_B,
1149 XK_n, XK_N,
1150 XK_m, XK_M,
1151 XK_comma, XK_less,
1152 XK_period, XK_greater,
1153 XK_slash, XK_question,
1154 XK_Shift_R, NoSymbol,
1155 XK_KP_Multiply, NoSymbol,
1156 XK_Alt_L, XK_Meta_L,
1157 XK_space, NoSymbol,
1158 /*XK_Caps_Lock*/ NoSymbol, NoSymbol,
1159 XK_F1, NoSymbol,
1160 XK_F2, NoSymbol,
1161 XK_F3, NoSymbol,
1162 XK_F4, NoSymbol,
1163 XK_F5, NoSymbol,
1164 XK_F6, NoSymbol,
1165 XK_F7, NoSymbol,
1166 XK_F8, NoSymbol,
1167 XK_F9, NoSymbol,
1168 XK_F10, NoSymbol,
1169 XK_Num_Lock, XK_Pointer_EnableKeys,
1170 XK_Scroll_Lock, NoSymbol,
1171 XK_KP_Home, XK_KP_7,
1172 XK_KP_Up, XK_KP_8,
1173 XK_KP_Prior, XK_KP_9,
1174 XK_KP_Subtract, NoSymbol,
1175 XK_KP_Left, XK_KP_4,
1176 XK_KP_Begin, XK_KP_5,
1177 XK_KP_Right, XK_KP_6,
1178 XK_KP_Add, NoSymbol,
1179 XK_KP_End, XK_KP_1,
1180 XK_KP_Down, XK_KP_2,
1181 XK_KP_Next, XK_KP_3,
1182 XK_KP_Insert, XK_KP_0,
1183 XK_KP_Delete, XK_KP_Decimal,
1184 NoSymbol, NoSymbol,
1185 NoSymbol, NoSymbol,
1186 NoSymbol, NoSymbol,
1187 XK_F11, NoSymbol,
1188 XK_F12, NoSymbol,
1189 XK_Home, NoSymbol,
1190 XK_Up, NoSymbol,
1191 XK_Prior, NoSymbol,
1192 XK_Left, NoSymbol,
1193 NoSymbol, NoSymbol,
1194 XK_Right, NoSymbol,
1195 XK_End, NoSymbol,
1196 XK_Down, NoSymbol,
1197 XK_Next, NoSymbol,
1198 XK_Insert, NoSymbol,
1199 XK_Delete, NoSymbol,
1200 XK_KP_Enter, NoSymbol,
1201 XK_Control_R, NoSymbol,
1202 XK_Pause, XK_Break,
1203 XK_Print, XK_Execute,
1204 XK_KP_Divide, NoSymbol,
1205 XK_Alt_R, XK_Meta_R,
1206};
1207
1208static Bool GetMappings(KeySymsPtr pKeySyms, CARD8 *pModMap)
1209{
1210 int i;
1211
1212 for (i = 0; i < MAP_LENGTH; i++)
1213 pModMap[i] = NoSymbol;
1214
1215 for (i = 0; i < VFB_MAP_LEN; i++) {
1216 if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Caps_Lock)
1217 pModMap[i + VFB_MIN_KEY] = LockMask;
1218 else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Shift_L ||
1219 keyboardMap[i * KEYSYMS_PER_KEY] == XK_Shift_R)
1220 pModMap[i + VFB_MIN_KEY] = ShiftMask;
1221 else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Control_L ||
1222 keyboardMap[i * KEYSYMS_PER_KEY] == XK_Control_R) {
1223 pModMap[i + VFB_MIN_KEY] = ControlMask;
1224 }
1225 else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Alt_L ||
1226 keyboardMap[i * KEYSYMS_PER_KEY] == XK_Alt_R)
1227 pModMap[i + VFB_MIN_KEY] = Mod1Mask;
1228 }
1229
1230 pKeySyms->minKeyCode = VFB_MIN_KEY;
1231 pKeySyms->maxKeyCode = VFB_MAX_KEY;
1232 pKeySyms->mapWidth = KEYSYMS_PER_KEY;
1233 pKeySyms->map = keyboardMap;
1234
1235 return TRUE;
1236}
1237
1238static void vfbBell(int percent, DeviceIntPtr device, pointer ctrl, int class_)
1239{
1240 if (percent > 0)
1241 vncBell();
1242}
1243
1244static int vfbKeybdProc(DeviceIntPtr pDevice, int onoff)
1245{
1246 KeySymsRec keySyms;
1247 CARD8 modMap[MAP_LENGTH];
1248 DevicePtr pDev = (DevicePtr)pDevice;
1249
1250 switch (onoff)
1251 {
1252 case DEVICE_INIT:
1253 GetMappings(&keySyms, modMap);
1254 InitKeyboardDeviceStruct(pDev, &keySyms, modMap,
1255 (BellProcPtr)vfbBell, (KbdCtrlProcPtr)NoopDDA);
1256 break;
1257 case DEVICE_ON:
1258 pDev->on = TRUE;
1259 break;
1260 case DEVICE_OFF:
1261 pDev->on = FALSE;
1262 break;
1263 case DEVICE_CLOSE:
1264 break;
1265 }
1266 return Success;
1267}
1268
1269static int vfbMouseProc(DeviceIntPtr pDevice, int onoff)
1270{
1271 BYTE map[6];
1272 DevicePtr pDev = (DevicePtr)pDevice;
1273
1274 switch (onoff)
1275 {
1276 case DEVICE_INIT:
1277 map[1] = 1;
1278 map[2] = 2;
1279 map[3] = 3;
1280 map[4] = 4;
1281 map[5] = 5;
1282 InitPointerDeviceStruct(pDev, map, 5, miPointerGetMotionEvents,
1283 (PtrCtrlProcPtr)NoopDDA, miPointerGetMotionBufferSize());
1284 break;
1285
1286 case DEVICE_ON:
1287 pDev->on = TRUE;
1288 break;
1289
1290 case DEVICE_OFF:
1291 pDev->on = FALSE;
1292 break;
1293
1294 case DEVICE_CLOSE:
1295 break;
1296 }
1297 return Success;
1298}
1299
1300// InitInput is called after InitExtensions, so we're guaranteed that
1301// vncExtensionInit() has already been called.
1302
1303void InitInput(int argc, char *argv[])
1304{
1305 DeviceIntPtr p, k;
1306 p = AddInputDevice(vfbMouseProc, TRUE);
1307 k = AddInputDevice(vfbKeybdProc, TRUE);
1308 RegisterPointerDevice(p);
1309 RegisterKeyboardDevice(k);
1310 miRegisterPointerDevice(screenInfo.screens[0], p);
1311 (void)mieqInit ((DevicePtr)k, (DevicePtr)p);
1312}