blob: e1ed9baff6acd8a1746879a6e4d89f45cbf0c45d [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"
Peter Åstrand1d742b42005-02-22 21:33:20 +000077#include "micmap.h"
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +000078#include <sys/types.h>
79#include <sys/stat.h>
80#include <errno.h>
81#ifndef WIN32
82#include <sys/param.h>
83#endif
84#include <X11/XWDFile.h>
85#include "dix.h"
86#include "miline.h"
87#include "inputstr.h"
88#include "keysym.h"
89 extern int defaultColorVisualClass;
90 extern char buildtime[];
91#undef class
92#undef public
93#undef xor
94#undef and
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +000095}
96
97#define XVNCVERSION "4.0"
98
99extern char *display;
100extern int monitorResolution;
101
102#define VFB_DEFAULT_WIDTH 1024
103#define VFB_DEFAULT_HEIGHT 768
104#define VFB_DEFAULT_DEPTH 16
105#define VFB_DEFAULT_WHITEPIXEL 0xffff
106#define VFB_DEFAULT_BLACKPIXEL 0
107#define VFB_DEFAULT_LINEBIAS 0
108#define XWD_WINDOW_NAME_LEN 60
109
110typedef struct
111{
Peter Åstrand60870912005-02-22 21:27:51 +0000112 int scrnum;
113 int width;
114 int paddedBytesWidth;
115 int paddedWidth;
116 int height;
117 int depth;
118 int bitsPerPixel;
119 int sizeInBytes;
120 int ncolors;
121 char *pfbMemory;
122 XWDColor *pXWDCmap;
123 XWDFileHeader *pXWDHeader;
124 Pixel blackPixel;
125 Pixel whitePixel;
126 unsigned int lineBias;
127 CloseScreenProcPtr closeScreen;
128
129#ifdef HAS_MMAP
130 int mmap_fd;
131 char mmap_file[MAXPATHLEN];
132#endif
133
134#ifdef HAS_SHM
135 int shmid;
136#endif
137
138 Bool pixelFormatDefined;
139 Bool rgbNotBgr;
140 int redBits, greenBits, blueBits;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000141
142} vfbScreenInfo, *vfbScreenInfoPtr;
143
144static int vfbNumScreens;
145static vfbScreenInfo vfbScreens[MAXSCREENS];
146static Bool vfbPixmapDepths[33];
Peter Åstrand00c759d2005-02-22 20:11:47 +0000147#ifdef HAS_MMAP
148static char *pfbdir = NULL;
149#endif
150typedef enum { NORMAL_MEMORY_FB, SHARED_MEMORY_FB, MMAPPED_FILE_FB } fbMemType;
151static fbMemType fbmemtype = NORMAL_MEMORY_FB;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000152static char needswap = 0;
153static int lastScreen = -1;
Peter Åstrandc5421b22005-02-14 20:25:49 +0000154static Bool Render = TRUE;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000155
156static bool displaySpecified = false;
157static bool wellKnownSocketsCreated = false;
158static char displayNumStr[16];
159
160#define swapcopy16(_dst, _src) \
161 if (needswap) { CARD16 _s = _src; cpswaps(_s, _dst); } \
162 else _dst = _src;
163
164#define swapcopy32(_dst, _src) \
165 if (needswap) { CARD32 _s = _src; cpswapl(_s, _dst); } \
166 else _dst = _src;
167
168
Peter Åstrandf960f042005-02-22 20:07:55 +0000169static void
170vfbInitializePixmapDepths(void)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000171{
Peter Åstrandf960f042005-02-22 20:07:55 +0000172 int i;
173 vfbPixmapDepths[1] = TRUE; /* always need bitmaps */
174 for (i = 2; i <= 32; i++)
175 vfbPixmapDepths[i] = FALSE;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000176}
177
Peter Åstrandf960f042005-02-22 20:07:55 +0000178static void
179vfbInitializeDefaultScreens(void)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000180{
Peter Åstrandf960f042005-02-22 20:07:55 +0000181 int i;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000182
Peter Åstrandf960f042005-02-22 20:07:55 +0000183 for (i = 0; i < MAXSCREENS; i++)
184 {
185 vfbScreens[i].scrnum = i;
186 vfbScreens[i].width = VFB_DEFAULT_WIDTH;
187 vfbScreens[i].height = VFB_DEFAULT_HEIGHT;
188 vfbScreens[i].depth = VFB_DEFAULT_DEPTH;
189 vfbScreens[i].blackPixel = VFB_DEFAULT_BLACKPIXEL;
190 vfbScreens[i].whitePixel = VFB_DEFAULT_WHITEPIXEL;
191 vfbScreens[i].lineBias = VFB_DEFAULT_LINEBIAS;
192 vfbScreens[i].pixelFormatDefined = FALSE;
193 vfbScreens[i].pfbMemory = NULL;
194 }
195 vfbNumScreens = 1;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000196}
197
Peter Åstrand00c759d2005-02-22 20:11:47 +0000198static int
199vfbBitsPerPixel(int depth)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000200{
Peter Åstrand00c759d2005-02-22 20:11:47 +0000201 if (depth == 1) return 1;
202 else if (depth <= 8) return 8;
203 else if (depth <= 16) return 16;
204 else return 32;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000205}
206
207extern "C" {
Peter Åstrand00c759d2005-02-22 20:11:47 +0000208void
209ddxGiveUp()
210{
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000211 int i;
212
213 /* clean up the framebuffers */
214
Peter Åstrand00c759d2005-02-22 20:11:47 +0000215 switch (fbmemtype)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000216 {
Peter Åstrand00c759d2005-02-22 20:11:47 +0000217#ifdef HAS_MMAP
218 case MMAPPED_FILE_FB:
219 for (i = 0; i < vfbNumScreens; i++)
220 {
221 if (-1 == unlink(vfbScreens[i].mmap_file))
222 {
223 perror("unlink");
224 ErrorF("unlink %s failed, errno %d",
225 vfbScreens[i].mmap_file, errno);
226 }
227 }
228 break;
229#else /* HAS_MMAP */
230 case MMAPPED_FILE_FB:
231 break;
232#endif /* HAS_MMAP */
233
234#ifdef HAS_SHM
235 case SHARED_MEMORY_FB:
236 for (i = 0; i < vfbNumScreens; i++)
237 {
238 if (-1 == shmdt((char *)vfbScreens[i].pXWDHeader))
239 {
240 perror("shmdt");
241 ErrorF("shmdt failed, errno %d", errno);
242 }
243 }
244 break;
245#else /* HAS_SHM */
246 case SHARED_MEMORY_FB:
247 break;
248#endif /* HAS_SHM */
249
250 case NORMAL_MEMORY_FB:
251 for (i = 0; i < vfbNumScreens; i++)
252 {
253 Xfree(vfbScreens[i].pXWDHeader);
254 }
255 break;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000256 }
Peter Åstrand00c759d2005-02-22 20:11:47 +0000257}
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000258
Peter Åstrand5b1d7a22005-02-22 20:18:24 +0000259void
260AbortDDX()
261{
262 ddxGiveUp();
263}
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000264
Peter Åstrand5b1d7a22005-02-22 20:18:24 +0000265#ifdef __DARWIN__
266void
267DarwinHandleGUI(int argc, char *argv[])
268{
269}
270
271void GlxExtensionInit();
272void GlxWrapInitVisuals(void *procPtr);
273
274void
275DarwinGlxExtensionInit()
276{
277 GlxExtensionInit();
278}
279
280void
281DarwinGlxWrapInitVisuals(
282 void *procPtr)
283{
284 GlxWrapInitVisuals(procPtr);
285}
286#endif
287
288void
289OsVendorInit()
290{
291}
292
293void
294OsVendorFatalError()
295{
296}
297
298void ddxBeforeReset(void)
299{
300 return;
301}
302
303void
304ddxUseMsg()
305{
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000306 ErrorF("\nXvnc version %s - built %s\n", XVNCVERSION, buildtime);
307 ErrorF("Underlying X server release %d, %s\n\n", VENDOR_RELEASE,
308 VENDOR_STRING);
309 ErrorF("-screen scrn WxHxD set screen's width, height, depth\n");
310 ErrorF("-pixdepths list-of-int support given pixmap depths\n");
Peter Åstrandc5421b22005-02-14 20:25:49 +0000311#ifdef RENDER
312 ErrorF("+/-render turn on/off RENDER extension support"
313 "(default on)\n");
314#endif
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000315 ErrorF("-linebias n adjust thin line pixelization\n");
316 ErrorF("-blackpixel n pixel value for black\n");
317 ErrorF("-whitepixel n pixel value for white\n");
Peter Åstrand5b1d7a22005-02-22 20:18:24 +0000318
319#ifdef HAS_MMAP
320 ErrorF("-fbdir directory put framebuffers in mmap'ed files in directory\n");
321#endif
322
323#ifdef HAS_SHM
324 ErrorF("-shmem put framebuffers in shared memory\n");
325#endif
326
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000327 ErrorF("-geometry WxH set screen 0's width, height\n");
328 ErrorF("-depth D set screen 0's depth\n");
329 ErrorF("-pixelformat fmt set pixel format (rgbNNN or bgrNNN)\n");
330 ErrorF("-inetd has been launched from inetd\n");
331 ErrorF("\nVNC parameters:\n");
332
333 fprintf(stderr,"\n"
334 "Parameters can be turned on with -<param> or off with -<param>=0\n"
335 "Parameters which take a value can be specified as "
336 "-<param> <value>\n"
337 "Other valid forms are <param>=<value> -<param>=<value> "
338 "--<param>=<value>\n"
339 "Parameter names are case-insensitive. The parameters are:\n\n");
340 rfb::Configuration::listParams(79, 14);
341 }
342}
343
Peter Åstrandfc41a212005-02-22 20:29:40 +0000344/* ddxInitGlobals - called by |InitGlobals| from os/util.c */
345void ddxInitGlobals(void)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000346{
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000347}
348
Peter Åstrandfc41a212005-02-22 20:29:40 +0000349static
350bool displayNumFree(int num)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000351{
Peter Åstrandfc41a212005-02-22 20:29:40 +0000352 try {
353 network::TcpListener l(6000+num);
354 } catch (rdr::Exception& e) {
355 return false;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000356 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000357 char file[256];
358 sprintf(file, "/tmp/.X%d-lock", num);
359 if (access(file, F_OK) == 0) return false;
360 sprintf(file, "/tmp/.X11-unix/X%d", num);
361 if (access(file, F_OK) == 0) return false;
362 sprintf(file, "/usr/spool/sockets/X11/%d", num);
363 if (access(file, F_OK) == 0) return false;
364 return true;
365}
366
367int
368ddxProcessArgument(int argc, char *argv[], int i)
369{
370 static Bool firstTime = TRUE;
371
372 if (firstTime)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000373 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000374 vfbInitializeDefaultScreens();
375 vfbInitializePixmapDepths();
376 firstTime = FALSE;
377 rfb::initStdIOLoggers();
378 rfb::LogWriter::setLogParams("*:stderr:30");
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000379 }
380
Peter Åstrandfc41a212005-02-22 20:29:40 +0000381 if (argv[i][0] == ':')
382 displaySpecified = true;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000383
Peter Åstrandfc41a212005-02-22 20:29:40 +0000384 if (strcmp (argv[i], "-screen") == 0) /* -screen n WxHxD */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000385 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000386 int screenNum;
387 if (i + 2 >= argc) UseMsg();
388 screenNum = atoi(argv[i+1]);
389 if (screenNum < 0 || screenNum >= MAXSCREENS)
390 {
391 ErrorF("Invalid screen number %d\n", screenNum);
392 UseMsg();
393 }
394 if (3 != sscanf(argv[i+2], "%dx%dx%d",
395 &vfbScreens[screenNum].width,
396 &vfbScreens[screenNum].height,
397 &vfbScreens[screenNum].depth))
398 {
399 ErrorF("Invalid screen configuration %s\n", argv[i+2]);
400 UseMsg();
401 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000402
Peter Åstrandfc41a212005-02-22 20:29:40 +0000403 if (screenNum >= vfbNumScreens)
404 vfbNumScreens = screenNum + 1;
405 lastScreen = screenNum;
406 return 3;
407 }
408
409 if (strcmp (argv[i], "-pixdepths") == 0) /* -pixdepths list-of-depth */
410 {
411 int depth, ret = 1;
412
413 if (++i >= argc) UseMsg();
414 while ((i < argc) && (depth = atoi(argv[i++])) != 0)
415 {
416 if (depth < 0 || depth > 32)
417 {
418 ErrorF("Invalid pixmap depth %d\n", depth);
419 UseMsg();
420 }
421 vfbPixmapDepths[depth] = TRUE;
422 ret++;
423 }
424 return ret;
425 }
426
427 if (strcmp (argv[i], "+render") == 0) /* +render */
428 {
429 Render = TRUE;
430 return 1;
431 }
Peter Åstrandc5421b22005-02-14 20:25:49 +0000432
Peter Åstrandfc41a212005-02-22 20:29:40 +0000433 if (strcmp (argv[i], "-render") == 0) /* -render */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000434 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000435 Render = FALSE;
436 return 1;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000437 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000438
Peter Åstrandfc41a212005-02-22 20:29:40 +0000439 if (strcmp (argv[i], "-blackpixel") == 0) /* -blackpixel n */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000440 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000441 Pixel pix;
442 if (++i >= argc) UseMsg();
443 pix = atoi(argv[i]);
444 if (-1 == lastScreen)
445 {
446 int i;
447 for (i = 0; i < MAXSCREENS; i++)
448 {
449 vfbScreens[i].blackPixel = pix;
450 }
451 }
452 else
453 {
454 vfbScreens[lastScreen].blackPixel = pix;
455 }
456 return 2;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000457 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000458
459 if (strcmp (argv[i], "-whitepixel") == 0) /* -whitepixel n */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000460 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000461 Pixel pix;
462 if (++i >= argc) UseMsg();
463 pix = atoi(argv[i]);
464 if (-1 == lastScreen)
465 {
466 int i;
467 for (i = 0; i < MAXSCREENS; i++)
468 {
469 vfbScreens[i].whitePixel = pix;
470 }
471 }
472 else
473 {
474 vfbScreens[lastScreen].whitePixel = pix;
475 }
476 return 2;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000477 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000478
479 if (strcmp (argv[i], "-linebias") == 0) /* -linebias n */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000480 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000481 unsigned int linebias;
482 if (++i >= argc) UseMsg();
483 linebias = atoi(argv[i]);
484 if (-1 == lastScreen)
485 {
486 int i;
487 for (i = 0; i < MAXSCREENS; i++)
488 {
489 vfbScreens[i].lineBias = linebias;
490 }
491 }
492 else
493 {
494 vfbScreens[lastScreen].lineBias = linebias;
495 }
496 return 2;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000497 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000498
499#ifdef HAS_MMAP
500 if (strcmp (argv[i], "-fbdir") == 0) /* -fbdir directory */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000501 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000502 if (++i >= argc) UseMsg();
503 pfbdir = argv[i];
504 fbmemtype = MMAPPED_FILE_FB;
505 return 2;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000506 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000507#endif /* HAS_MMAP */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000508
Peter Åstrandfc41a212005-02-22 20:29:40 +0000509#ifdef HAS_SHM
510 if (strcmp (argv[i], "-shmem") == 0) /* -shmem */
511 {
512 fbmemtype = SHARED_MEMORY_FB;
513 return 1;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000514 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000515#endif
516
517 if (strcmp(argv[i], "-geometry") == 0)
518 {
519 if (++i >= argc) UseMsg();
520 if (sscanf(argv[i],"%dx%d",&vfbScreens[0].width,
521 &vfbScreens[0].height) != 2) {
522 ErrorF("Invalid geometry %s\n", argv[i]);
523 UseMsg();
524 }
525 return 2;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000526 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000527
528 if (strcmp(argv[i], "-depth") == 0)
529 {
530 if (++i >= argc) UseMsg();
531 vfbScreens[0].depth = atoi(argv[i]);
532 return 2;
533 }
534
535 if (strcmp(argv[i], "-pixelformat") == 0)
536 {
537 char rgbbgr[4];
538 int bits1, bits2, bits3;
539 if (++i >= argc) UseMsg();
540 if (sscanf(argv[i], "%3s%1d%1d%1d", rgbbgr,&bits1,&bits2,&bits3) < 4) {
541 ErrorF("Invalid pixel format %s\n", argv[i]);
542 UseMsg();
543 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000544
545#define SET_PIXEL_FORMAT(vfbScreen) \
546 (vfbScreen).pixelFormatDefined = TRUE; \
547 (vfbScreen).depth = bits1 + bits2 + bits3; \
548 (vfbScreen).greenBits = bits2; \
549 if (strcasecmp(rgbbgr, "bgr") == 0) { \
550 (vfbScreen).rgbNotBgr = FALSE; \
551 (vfbScreen).redBits = bits3; \
552 (vfbScreen).blueBits = bits1; \
553 } else if (strcasecmp(rgbbgr, "rgb") == 0) { \
554 (vfbScreen).rgbNotBgr = TRUE; \
555 (vfbScreen).redBits = bits1; \
556 (vfbScreen).blueBits = bits3; \
557 } else { \
558 ErrorF("Invalid pixel format %s\n", argv[i]); \
559 UseMsg(); \
560 }
561
Peter Åstrandfc41a212005-02-22 20:29:40 +0000562 if (-1 == lastScreen)
563 {
564 int i;
565 for (i = 0; i < MAXSCREENS; i++)
566 {
567 SET_PIXEL_FORMAT(vfbScreens[i]);
568 }
569 }
570 else
571 {
572 SET_PIXEL_FORMAT(vfbScreens[lastScreen]);
573 }
574
575 return 2;
576 }
577
578 if (strcmp(argv[i], "-inetd") == 0)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000579 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000580 dup2(0,3);
581 vncInetdSock = 3;
582 close(2);
583
584 if (!displaySpecified) {
585 int port = network::TcpSocket::getSockPort(vncInetdSock);
586 int displayNum = port - 5900;
587 if (displayNum < 0 || displayNum > 99 || !displayNumFree(displayNum)) {
588 for (displayNum = 1; displayNum < 100; displayNum++)
589 if (displayNumFree(displayNum)) break;
590
591 if (displayNum == 100)
592 FatalError("Xvnc error: no free display number for -inetd");
593 }
594
595 display = displayNumStr;
596 sprintf(displayNumStr, "%d", displayNum);
597 }
598
599 return 1;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000600 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000601
602 if (rfb::Configuration::setParam(argv[i]))
603 return 1;
604
605 if (argv[i][0] == '-' && i+1 < argc) {
606 if (rfb::Configuration::setParam(&argv[i][1], argv[i+1]))
607 return 2;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000608 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000609
610 return 0;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000611}
612
613#ifdef DDXTIME /* from ServerOSDefines */
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000614CARD32
615GetTimeInMillis()
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000616{
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000617 struct timeval tp;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000618
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000619 X_GETTIMEOFDAY(&tp);
620 return(tp.tv_sec * 1000) + (tp.tv_usec / 1000);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000621}
622#endif
623
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000624static ColormapPtr InstalledMaps[MAXSCREENS];
625
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000626static int
627vfbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000628{
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000629 /* By the time we are processing requests, we can guarantee that there
630 * is always a colormap installed */
631 *pmaps = InstalledMaps[pScreen->myNum]->mid;
632 return (1);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000633}
634
635
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000636static void
637vfbInstallColormap(ColormapPtr pmap)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000638{
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000639 int index = pmap->pScreen->myNum;
640 ColormapPtr oldpmap = InstalledMaps[index];
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000641
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000642 if (pmap != oldpmap)
643 {
644 int entries;
645 XWDFileHeader *pXWDHeader;
646 XWDColor *pXWDCmap;
647 VisualPtr pVisual;
648 Pixel * ppix;
649 xrgb * prgb;
650 xColorItem *defs;
651 int i;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000652
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000653 if(oldpmap != (ColormapPtr)None)
654 WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
655 /* Install pmap */
656 InstalledMaps[index] = pmap;
657 WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000658
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000659 entries = pmap->pVisual->ColormapEntries;
660 pXWDHeader = vfbScreens[pmap->pScreen->myNum].pXWDHeader;
661 pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
662 pVisual = pmap->pVisual;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000663
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000664 swapcopy32(pXWDHeader->visual_class, pVisual->c_class);
665 swapcopy32(pXWDHeader->red_mask, pVisual->redMask);
666 swapcopy32(pXWDHeader->green_mask, pVisual->greenMask);
667 swapcopy32(pXWDHeader->blue_mask, pVisual->blueMask);
668 swapcopy32(pXWDHeader->bits_per_rgb, pVisual->bitsPerRGBValue);
669 swapcopy32(pXWDHeader->colormap_entries, pVisual->ColormapEntries);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000670
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000671 ppix = (Pixel *)ALLOCATE_LOCAL(entries * sizeof(Pixel));
672 prgb = (xrgb *)ALLOCATE_LOCAL(entries * sizeof(xrgb));
673 defs = (xColorItem *)ALLOCATE_LOCAL(entries * sizeof(xColorItem));
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000674
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000675 for (i = 0; i < entries; i++) ppix[i] = i;
676 /* XXX truecolor */
677 QueryColors(pmap, entries, ppix, prgb);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000678
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000679 for (i = 0; i < entries; i++) { /* convert xrgbs to xColorItems */
680 defs[i].pixel = ppix[i] & 0xff; /* change pixel to index */
681 defs[i].red = prgb[i].red;
682 defs[i].green = prgb[i].green;
683 defs[i].blue = prgb[i].blue;
684 defs[i].flags = DoRed|DoGreen|DoBlue;
685 }
686 (*pmap->pScreen->StoreColors)(pmap, entries, defs);
687
688 DEALLOCATE_LOCAL(ppix);
689 DEALLOCATE_LOCAL(prgb);
690 DEALLOCATE_LOCAL(defs);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000691 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000692}
693
Peter Åstrand853287d2005-02-22 20:46:58 +0000694static void
695vfbUninstallColormap(ColormapPtr pmap)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000696{
Peter Åstrand853287d2005-02-22 20:46:58 +0000697 ColormapPtr curpmap = InstalledMaps[pmap->pScreen->myNum];
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000698
Peter Åstrand853287d2005-02-22 20:46:58 +0000699 if(pmap == curpmap)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000700 {
Peter Åstrand853287d2005-02-22 20:46:58 +0000701 if (pmap->mid != pmap->pScreen->defColormap)
702 {
703 curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap,
704 RT_COLORMAP);
705 (*pmap->pScreen->InstallColormap)(curpmap);
706 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000707 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000708}
709
Peter Åstrand853287d2005-02-22 20:46:58 +0000710static void
711vfbStoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000712{
Peter Åstrand853287d2005-02-22 20:46:58 +0000713 XWDColor *pXWDCmap;
714 int i;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000715
Peter Åstrand853287d2005-02-22 20:46:58 +0000716 if (pmap != InstalledMaps[pmap->pScreen->myNum])
717 {
718 return;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000719 }
Peter Åstrand853287d2005-02-22 20:46:58 +0000720
721 pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
722
Peter Åstrandbe228572005-02-22 20:48:29 +0000723 if ((pmap->pVisual->c_class | DynamicClass) == DirectColor)
Peter Åstrand853287d2005-02-22 20:46:58 +0000724 {
725 return;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000726 }
Peter Åstrand853287d2005-02-22 20:46:58 +0000727
728 for (i = 0; i < ndef; i++)
729 {
730 if (pdefs[i].flags & DoRed)
731 {
732 swapcopy16(pXWDCmap[pdefs[i].pixel].red, pdefs[i].red);
733 }
734 if (pdefs[i].flags & DoGreen)
735 {
736 swapcopy16(pXWDCmap[pdefs[i].pixel].green, pdefs[i].green);
737 }
738 if (pdefs[i].flags & DoBlue)
739 {
740 swapcopy16(pXWDCmap[pdefs[i].pixel].blue, pdefs[i].blue);
741 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000742 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000743}
744
Peter Åstrand853287d2005-02-22 20:46:58 +0000745static Bool
746vfbSaveScreen(ScreenPtr pScreen, int on)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000747{
Peter Åstrand853287d2005-02-22 20:46:58 +0000748 return TRUE;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000749}
750
Peter Åstrand8de329f2005-02-22 21:05:16 +0000751static char *
752vfbAllocateFramebufferMemory(vfbScreenInfoPtr pvfb)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000753{
Peter Åstrand8de329f2005-02-22 21:05:16 +0000754 if (pvfb->pfbMemory) return pvfb->pfbMemory; /* already done */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000755
Peter Åstrand8de329f2005-02-22 21:05:16 +0000756 pvfb->sizeInBytes = pvfb->paddedBytesWidth * pvfb->height;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000757
Peter Åstrand8de329f2005-02-22 21:05:16 +0000758 /* Calculate how many entries in colormap. This is rather bogus, because
759 * the visuals haven't even been set up yet, but we need to know because we
760 * have to allocate space in the file for the colormap. The number 10
761 * below comes from the MAX_PSEUDO_DEPTH define in cfbcmap.c.
762 */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000763
Peter Åstrand8de329f2005-02-22 21:05:16 +0000764 if (pvfb->depth <= 10)
765 { /* single index colormaps */
766 pvfb->ncolors = 1 << pvfb->depth;
767 }
768 else
769 { /* decomposed colormaps */
770 int nplanes_per_color_component = pvfb->depth / 3;
771 if (pvfb->depth % 3) nplanes_per_color_component++;
772 pvfb->ncolors = 1 << nplanes_per_color_component;
773 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000774
Peter Åstrand8de329f2005-02-22 21:05:16 +0000775 /* add extra bytes for XWDFileHeader, window name, and colormap */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000776
Peter Åstrand8de329f2005-02-22 21:05:16 +0000777 pvfb->sizeInBytes += SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN +
778 pvfb->ncolors * SIZEOF(XWDColor);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000779
Peter Åstrand8de329f2005-02-22 21:05:16 +0000780 pvfb->pXWDHeader = NULL;
781 switch (fbmemtype)
782 {
783#ifdef HAS_MMAP
784 case MMAPPED_FILE_FB: vfbAllocateMmappedFramebuffer(pvfb); break;
785#else
786 case MMAPPED_FILE_FB: break;
787#endif
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000788
Peter Åstrand8de329f2005-02-22 21:05:16 +0000789#ifdef HAS_SHM
790 case SHARED_MEMORY_FB: vfbAllocateSharedMemoryFramebuffer(pvfb); break;
791#else
792 case SHARED_MEMORY_FB: break;
793#endif
794
795 case NORMAL_MEMORY_FB:
796 pvfb->pXWDHeader = (XWDFileHeader *)Xalloc(pvfb->sizeInBytes);
797 break;
798 }
799
800 if (pvfb->pXWDHeader)
801 {
802 pvfb->pXWDCmap = (XWDColor *)((char *)pvfb->pXWDHeader
803 + SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN);
804 pvfb->pfbMemory = (char *)(pvfb->pXWDCmap + pvfb->ncolors);
805
806 return pvfb->pfbMemory;
807 }
808 else
809 return NULL;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000810}
811
Peter Åstrandf9357f52005-02-22 21:08:02 +0000812static void
813vfbWriteXWDFileHeader(ScreenPtr pScreen)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000814{
Peter Åstrandf9357f52005-02-22 21:08:02 +0000815 vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
816 XWDFileHeader *pXWDHeader = pvfb->pXWDHeader;
817 char hostname[XWD_WINDOW_NAME_LEN];
818 unsigned long swaptest = 1;
819 int i;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000820
Peter Åstrandf9357f52005-02-22 21:08:02 +0000821 needswap = *(char *) &swaptest;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000822
Peter Åstrandf9357f52005-02-22 21:08:02 +0000823 pXWDHeader->header_size = (char *)pvfb->pXWDCmap - (char *)pvfb->pXWDHeader;
824 pXWDHeader->file_version = XWD_FILE_VERSION;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000825
Peter Åstrandf9357f52005-02-22 21:08:02 +0000826 pXWDHeader->pixmap_format = ZPixmap;
827 pXWDHeader->pixmap_depth = pvfb->depth;
828 pXWDHeader->pixmap_height = pXWDHeader->window_height = pvfb->height;
829 pXWDHeader->xoffset = 0;
830 pXWDHeader->byte_order = IMAGE_BYTE_ORDER;
831 pXWDHeader->bitmap_bit_order = BITMAP_BIT_ORDER;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000832#ifndef INTERNAL_VS_EXTERNAL_PADDING
Peter Åstrandf9357f52005-02-22 21:08:02 +0000833 pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->width;
834 pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT;
835 pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000836#else
Peter Åstrandf9357f52005-02-22 21:08:02 +0000837 pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->paddedWidth;
838 pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT_PROTO;
839 pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD_PROTO;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000840#endif
Peter Åstrandf9357f52005-02-22 21:08:02 +0000841 pXWDHeader->bits_per_pixel = pvfb->bitsPerPixel;
842 pXWDHeader->bytes_per_line = pvfb->paddedBytesWidth;
843 pXWDHeader->ncolors = pvfb->ncolors;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000844
Peter Åstrandf9357f52005-02-22 21:08:02 +0000845 /* visual related fields are written when colormap is installed */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000846
Peter Åstrandf9357f52005-02-22 21:08:02 +0000847 pXWDHeader->window_x = pXWDHeader->window_y = 0;
848 pXWDHeader->window_bdrwidth = 0;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000849
Peter Åstrandf9357f52005-02-22 21:08:02 +0000850 /* write xwd "window" name: Xvfb hostname:server.screen */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000851
Peter Åstrandf9357f52005-02-22 21:08:02 +0000852 if (-1 == gethostname(hostname, sizeof(hostname)))
853 hostname[0] = 0;
854 else
855 hostname[XWD_WINDOW_NAME_LEN-1] = 0;
856 sprintf((char *)(pXWDHeader+1), "Xvfb %s:%s.%d", hostname, display,
857 pScreen->myNum);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000858
Peter Åstrandf9357f52005-02-22 21:08:02 +0000859 /* write colormap pixel slot values */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000860
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000861 for (i = 0; i < pvfb->ncolors; i++)
862 {
Peter Åstrandf9357f52005-02-22 21:08:02 +0000863 pvfb->pXWDCmap[i].pixel = i;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000864 }
Peter Åstrandf9357f52005-02-22 21:08:02 +0000865
866 /* byte swap to most significant byte first */
867
868 if (needswap)
869 {
870 SwapLongs((CARD32 *)pXWDHeader, SIZEOF(XWDheader)/4);
871 for (i = 0; i < pvfb->ncolors; i++)
872 {
873 register char n;
874 swapl(&pvfb->pXWDCmap[i].pixel, n);
875 }
876 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000877}
878
879
Peter Åstrandf9357f52005-02-22 21:08:02 +0000880static Bool
881vfbCursorOffScreen (ScreenPtr *ppScreen, int *x, int *y)
882{
883 return FALSE;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000884}
Peter Åstrandf9357f52005-02-22 21:08:02 +0000885
886static void
887vfbCrossScreen (ScreenPtr pScreen, Bool entering)
888{
889}
890
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000891static Bool vfbRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) {
Peter Åstrand5eef5ee2005-02-22 21:13:14 +0000892 return TRUE;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000893}
Peter Åstrand5eef5ee2005-02-22 21:13:14 +0000894
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000895static Bool vfbUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) {
Peter Åstrand5eef5ee2005-02-22 21:13:14 +0000896 return TRUE;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000897}
Peter Åstrand5eef5ee2005-02-22 21:13:14 +0000898
899static void vfbSetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
900{
901}
902
903static void vfbMoveCursor(ScreenPtr pScreen, int x, int y)
904{
905}
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000906
907static miPointerSpriteFuncRec vfbPointerSpriteFuncs = {
Peter Åstrand5eef5ee2005-02-22 21:13:14 +0000908 vfbRealizeCursor,
909 vfbUnrealizeCursor,
910 vfbSetCursor,
911 vfbMoveCursor
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000912};
913
Peter Åstrand5eef5ee2005-02-22 21:13:14 +0000914static miPointerScreenFuncRec vfbPointerCursorFuncs = {
915 vfbCursorOffScreen,
916 vfbCrossScreen,
917 miPointerWarpCursor
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000918};
919
Peter Åstrand60870912005-02-22 21:27:51 +0000920static Bool
921vfbCloseScreen(int index, ScreenPtr pScreen)
922{
923 vfbScreenInfoPtr pvfb = &vfbScreens[index];
924 int i;
925
926 pScreen->CloseScreen = pvfb->closeScreen;
927
928 /*
929 * XXX probably lots of stuff to clean. For now,
930 * clear InstalledMaps[] so that server reset works correctly.
931 */
932 for (i = 0; i < MAXSCREENS; i++)
933 InstalledMaps[i] = NULL;
934
935 return pScreen->CloseScreen(index, pScreen);
936}
937
Peter Åstrand1d742b42005-02-22 21:33:20 +0000938static Bool
939vfbScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000940{
Peter Åstrand1d742b42005-02-22 21:33:20 +0000941 vfbScreenInfoPtr pvfb = &vfbScreens[index];
942 int dpix = 100, dpiy = 100;
943 int ret;
944 char *pbits;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000945
Peter Åstrand1d742b42005-02-22 21:33:20 +0000946 pvfb->paddedBytesWidth = PixmapBytePad(pvfb->width, pvfb->depth);
947 pvfb->bitsPerPixel = vfbBitsPerPixel(pvfb->depth);
948 if (pvfb->bitsPerPixel >= 8 )
949 pvfb->paddedWidth = pvfb->paddedBytesWidth / (pvfb->bitsPerPixel / 8);
950 else
951 pvfb->paddedWidth = pvfb->paddedBytesWidth * 8;
952 pbits = vfbAllocateFramebufferMemory(pvfb);
953 if (!pbits) return FALSE;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000954
Peter Åstrand1d742b42005-02-22 21:33:20 +0000955 miSetPixmapDepths ();
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000956
Peter Åstrand1d742b42005-02-22 21:33:20 +0000957 switch (pvfb->depth) {
958 case 8:
959 miSetVisualTypesAndMasks (8,
960 ((1 << StaticGray) |
961 (1 << GrayScale) |
962 (1 << StaticColor) |
963 (1 << PseudoColor) |
964 (1 << TrueColor) |
965 (1 << DirectColor)),
966 8, PseudoColor, 0x07, 0x38, 0xc0);
967 break;
968 case 15:
969 miSetVisualTypesAndMasks (15,
970 ((1 << TrueColor) |
971 (1 << DirectColor)),
972 8, TrueColor, 0x7c00, 0x03e0, 0x001f);
973 break;
974 case 16:
975 miSetVisualTypesAndMasks (16,
976 ((1 << TrueColor) |
977 (1 << DirectColor)),
978 8, TrueColor, 0xf800, 0x07e0, 0x001f);
979 break;
980 case 24:
981 miSetVisualTypesAndMasks (24,
982 ((1 << TrueColor) |
983 (1 << DirectColor)),
984 8, TrueColor, 0xff0000, 0x00ff00, 0x0000ff);
985 break;
986 }
987
988 ret = fbScreenInit(pScreen, pbits, pvfb->width, pvfb->height,
989 dpix, dpiy, pvfb->paddedWidth,pvfb->bitsPerPixel);
Peter Åstrandc5421b22005-02-14 20:25:49 +0000990#ifdef RENDER
Peter Åstrand1d742b42005-02-22 21:33:20 +0000991 if (ret && Render)
992 fbPictureInit (pScreen, 0, 0);
Peter Åstrandc5421b22005-02-14 20:25:49 +0000993#endif
994
Peter Åstrand1d742b42005-02-22 21:33:20 +0000995 if (!ret) return FALSE;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000996
Peter Åstrand1d742b42005-02-22 21:33:20 +0000997 /* miInitializeBackingStore(pScreen); */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000998
Peter Åstrand1d742b42005-02-22 21:33:20 +0000999 /*
1000 * Circumvent the backing store that was just initialised. This amounts
1001 * to a truely bizarre way of initialising SaveDoomedAreas and friends.
1002 */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +00001003
Peter Åstrand1d742b42005-02-22 21:33:20 +00001004 pScreen->InstallColormap = vfbInstallColormap;
1005 pScreen->UninstallColormap = vfbUninstallColormap;
1006 pScreen->ListInstalledColormaps = vfbListInstalledColormaps;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +00001007
Peter Åstrand1d742b42005-02-22 21:33:20 +00001008 pScreen->SaveScreen = vfbSaveScreen;
1009 pScreen->StoreColors = vfbStoreColors;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +00001010
Peter Åstrand1d742b42005-02-22 21:33:20 +00001011 miDCInitialize(pScreen, &vfbPointerCursorFuncs);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +00001012
Peter Åstrand1d742b42005-02-22 21:33:20 +00001013 vfbWriteXWDFileHeader(pScreen);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +00001014
Peter Åstrand1d742b42005-02-22 21:33:20 +00001015 pScreen->blackPixel = pvfb->blackPixel;
1016 pScreen->whitePixel = pvfb->whitePixel;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +00001017
Peter Åstrand1d742b42005-02-22 21:33:20 +00001018 ret = fbCreateDefColormap(pScreen);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +00001019
Peter Åstrand1d742b42005-02-22 21:33:20 +00001020 miSetZeroLineBias(pScreen, pvfb->lineBias);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +00001021
Peter Åstrand1d742b42005-02-22 21:33:20 +00001022 pvfb->closeScreen = pScreen->CloseScreen;
1023 pScreen->CloseScreen = vfbCloseScreen;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +00001024
Peter Åstrand1d742b42005-02-22 21:33:20 +00001025 return ret;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +00001026
1027} /* end vfbScreenInit */
1028
1029
1030static void vfbClientStateChange(CallbackListPtr*, pointer, pointer) {
1031 dispatchException &= ~DE_RESET;
1032}
1033
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +00001034void InitOutput(ScreenInfo *screenInfo, int argc, char **argv)
1035{
1036 ErrorF("\nXvnc version %s - built %s\n", XVNCVERSION, buildtime);
1037 ErrorF("Underlying X server release %d, %s\n\n", VENDOR_RELEASE,
1038 VENDOR_STRING);
1039 wellKnownSocketsCreated = true;
1040
1041 int i;
1042 int NumFormats = 0;
1043
1044 /* initialize pixmap formats */
1045
1046 /* must have a pixmap depth to match every screen depth */
1047 for (i = 0; i < vfbNumScreens; i++)
1048 {
1049 vfbPixmapDepths[vfbScreens[i].depth] = TRUE;
1050 }
1051
Peter Åstrandc5421b22005-02-14 20:25:49 +00001052 /* RENDER needs a good set of pixmaps. */
1053 if (Render) {
1054 vfbPixmapDepths[1] = TRUE;
1055 vfbPixmapDepths[4] = TRUE;
1056 vfbPixmapDepths[8] = TRUE;
1057/* vfbPixmapDepths[15] = TRUE; */
1058 vfbPixmapDepths[16] = TRUE;
1059 vfbPixmapDepths[24] = TRUE;
1060 vfbPixmapDepths[32] = TRUE;
1061 }
1062
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +00001063 for (i = 1; i <= 32; i++)
1064 {
1065 if (vfbPixmapDepths[i])
1066 {
1067 if (NumFormats >= MAXFORMATS)
1068 FatalError ("MAXFORMATS is too small for this server\n");
1069 screenInfo->formats[NumFormats].depth = i;
1070 screenInfo->formats[NumFormats].bitsPerPixel = vfbBitsPerPixel(i);
1071 screenInfo->formats[NumFormats].scanlinePad = BITMAP_SCANLINE_PAD;
1072 NumFormats++;
1073 }
1074 }
1075
1076 screenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
1077 screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
1078 screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
1079 screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
1080 screenInfo->numPixmapFormats = NumFormats;
1081
1082 /* initialize screens */
1083
1084 for (i = 0; i < vfbNumScreens; i++)
1085 {
1086 if (-1 == AddScreen(vfbScreenInit, argc, argv))
1087 {
1088 FatalError("Couldn't add screen %d", i);
1089 }
1090 }
1091
1092 if (!AddCallback(&ClientStateCallback, vfbClientStateChange, 0)) {
1093 FatalError("AddCallback failed\n");
1094 }
1095
1096} /* end InitOutput */
1097
1098#ifdef DPMSExtension
1099extern "C" {
1100#if NeedFunctionPrototypes
1101 void DPMSSet(CARD16 level)
1102#else
1103 void DPMSSet(level)
1104 CARD16 level;
1105#endif
1106 {
1107 return;
1108 }
1109
1110 Bool DPMSSupported()
1111 {
1112 return FALSE;
1113 }
1114}
1115#endif
1116
1117/* this is just to get the server to link on AIX */
1118#ifdef AIXV3
1119int SelectWaitTime = 10000; /* usec */
1120#endif
1121
1122Bool LegalModifier(unsigned int key, DevicePtr pDev)
1123{
1124 return TRUE;
1125}
1126
1127void ProcessInputEvents()
1128{
1129 mieqProcessInputEvents();
1130 miPointerUpdate();
1131}
1132
1133/* Fairly standard US PC Keyboard */
1134
1135#define VFB_MIN_KEY 8
1136#define VFB_MAX_KEY 255
1137#define VFB_MAP_LEN (VFB_MAX_KEY - VFB_MIN_KEY + 1)
1138#define KEYSYMS_PER_KEY 2
1139KeySym keyboardMap[VFB_MAP_LEN * KEYSYMS_PER_KEY] = {
1140 NoSymbol, NoSymbol,
1141 XK_Escape, NoSymbol,
1142 XK_1, XK_exclam,
1143 XK_2, XK_at,
1144 XK_3, XK_numbersign,
1145 XK_4, XK_dollar,
1146 XK_5, XK_percent,
1147 XK_6, XK_asciicircum,
1148 XK_7, XK_ampersand,
1149 XK_8, XK_asterisk,
1150 XK_9, XK_parenleft,
1151 XK_0, XK_parenright,
1152 XK_minus, XK_underscore,
1153 XK_equal, XK_plus,
1154 XK_BackSpace, NoSymbol,
1155 XK_Tab, NoSymbol,
1156 XK_q, XK_Q,
1157 XK_w, XK_W,
1158 XK_e, XK_E,
1159 XK_r, XK_R,
1160 XK_t, XK_T,
1161 XK_y, XK_Y,
1162 XK_u, XK_U,
1163 XK_i, XK_I,
1164 XK_o, XK_O,
1165 XK_p, XK_P,
1166 XK_bracketleft, XK_braceleft,
1167 XK_bracketright, XK_braceright,
1168 XK_Return, NoSymbol,
1169 XK_Control_L, NoSymbol,
1170 XK_a, XK_A,
1171 XK_s, XK_S,
1172 XK_d, XK_D,
1173 XK_f, XK_F,
1174 XK_g, XK_G,
1175 XK_h, XK_H,
1176 XK_j, XK_J,
1177 XK_k, XK_K,
1178 XK_l, XK_L,
1179 XK_semicolon, XK_colon,
1180 XK_apostrophe, XK_quotedbl,
1181 XK_grave, XK_asciitilde,
1182 XK_Shift_L, NoSymbol,
1183 XK_backslash, XK_bar,
1184 XK_z, XK_Z,
1185 XK_x, XK_X,
1186 XK_c, XK_C,
1187 XK_v, XK_V,
1188 XK_b, XK_B,
1189 XK_n, XK_N,
1190 XK_m, XK_M,
1191 XK_comma, XK_less,
1192 XK_period, XK_greater,
1193 XK_slash, XK_question,
1194 XK_Shift_R, NoSymbol,
1195 XK_KP_Multiply, NoSymbol,
1196 XK_Alt_L, XK_Meta_L,
1197 XK_space, NoSymbol,
1198 /*XK_Caps_Lock*/ NoSymbol, NoSymbol,
1199 XK_F1, NoSymbol,
1200 XK_F2, NoSymbol,
1201 XK_F3, NoSymbol,
1202 XK_F4, NoSymbol,
1203 XK_F5, NoSymbol,
1204 XK_F6, NoSymbol,
1205 XK_F7, NoSymbol,
1206 XK_F8, NoSymbol,
1207 XK_F9, NoSymbol,
1208 XK_F10, NoSymbol,
1209 XK_Num_Lock, XK_Pointer_EnableKeys,
1210 XK_Scroll_Lock, NoSymbol,
1211 XK_KP_Home, XK_KP_7,
1212 XK_KP_Up, XK_KP_8,
1213 XK_KP_Prior, XK_KP_9,
1214 XK_KP_Subtract, NoSymbol,
1215 XK_KP_Left, XK_KP_4,
1216 XK_KP_Begin, XK_KP_5,
1217 XK_KP_Right, XK_KP_6,
1218 XK_KP_Add, NoSymbol,
1219 XK_KP_End, XK_KP_1,
1220 XK_KP_Down, XK_KP_2,
1221 XK_KP_Next, XK_KP_3,
1222 XK_KP_Insert, XK_KP_0,
1223 XK_KP_Delete, XK_KP_Decimal,
1224 NoSymbol, NoSymbol,
1225 NoSymbol, NoSymbol,
1226 NoSymbol, NoSymbol,
1227 XK_F11, NoSymbol,
1228 XK_F12, NoSymbol,
1229 XK_Home, NoSymbol,
1230 XK_Up, NoSymbol,
1231 XK_Prior, NoSymbol,
1232 XK_Left, NoSymbol,
1233 NoSymbol, NoSymbol,
1234 XK_Right, NoSymbol,
1235 XK_End, NoSymbol,
1236 XK_Down, NoSymbol,
1237 XK_Next, NoSymbol,
1238 XK_Insert, NoSymbol,
1239 XK_Delete, NoSymbol,
1240 XK_KP_Enter, NoSymbol,
1241 XK_Control_R, NoSymbol,
1242 XK_Pause, XK_Break,
1243 XK_Print, XK_Execute,
1244 XK_KP_Divide, NoSymbol,
1245 XK_Alt_R, XK_Meta_R,
1246};
1247
1248static Bool GetMappings(KeySymsPtr pKeySyms, CARD8 *pModMap)
1249{
1250 int i;
1251
1252 for (i = 0; i < MAP_LENGTH; i++)
1253 pModMap[i] = NoSymbol;
1254
1255 for (i = 0; i < VFB_MAP_LEN; i++) {
1256 if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Caps_Lock)
1257 pModMap[i + VFB_MIN_KEY] = LockMask;
1258 else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Shift_L ||
1259 keyboardMap[i * KEYSYMS_PER_KEY] == XK_Shift_R)
1260 pModMap[i + VFB_MIN_KEY] = ShiftMask;
1261 else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Control_L ||
1262 keyboardMap[i * KEYSYMS_PER_KEY] == XK_Control_R) {
1263 pModMap[i + VFB_MIN_KEY] = ControlMask;
1264 }
1265 else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Alt_L ||
1266 keyboardMap[i * KEYSYMS_PER_KEY] == XK_Alt_R)
1267 pModMap[i + VFB_MIN_KEY] = Mod1Mask;
1268 }
1269
1270 pKeySyms->minKeyCode = VFB_MIN_KEY;
1271 pKeySyms->maxKeyCode = VFB_MAX_KEY;
1272 pKeySyms->mapWidth = KEYSYMS_PER_KEY;
1273 pKeySyms->map = keyboardMap;
1274
1275 return TRUE;
1276}
1277
1278static void vfbBell(int percent, DeviceIntPtr device, pointer ctrl, int class_)
1279{
1280 if (percent > 0)
1281 vncBell();
1282}
1283
1284static int vfbKeybdProc(DeviceIntPtr pDevice, int onoff)
1285{
1286 KeySymsRec keySyms;
1287 CARD8 modMap[MAP_LENGTH];
1288 DevicePtr pDev = (DevicePtr)pDevice;
1289
1290 switch (onoff)
1291 {
1292 case DEVICE_INIT:
1293 GetMappings(&keySyms, modMap);
1294 InitKeyboardDeviceStruct(pDev, &keySyms, modMap,
1295 (BellProcPtr)vfbBell, (KbdCtrlProcPtr)NoopDDA);
1296 break;
1297 case DEVICE_ON:
1298 pDev->on = TRUE;
1299 break;
1300 case DEVICE_OFF:
1301 pDev->on = FALSE;
1302 break;
1303 case DEVICE_CLOSE:
1304 break;
1305 }
1306 return Success;
1307}
1308
1309static int vfbMouseProc(DeviceIntPtr pDevice, int onoff)
1310{
1311 BYTE map[6];
1312 DevicePtr pDev = (DevicePtr)pDevice;
1313
1314 switch (onoff)
1315 {
1316 case DEVICE_INIT:
1317 map[1] = 1;
1318 map[2] = 2;
1319 map[3] = 3;
1320 map[4] = 4;
1321 map[5] = 5;
1322 InitPointerDeviceStruct(pDev, map, 5, miPointerGetMotionEvents,
1323 (PtrCtrlProcPtr)NoopDDA, miPointerGetMotionBufferSize());
1324 break;
1325
1326 case DEVICE_ON:
1327 pDev->on = TRUE;
1328 break;
1329
1330 case DEVICE_OFF:
1331 pDev->on = FALSE;
1332 break;
1333
1334 case DEVICE_CLOSE:
1335 break;
1336 }
1337 return Success;
1338}
1339
1340// InitInput is called after InitExtensions, so we're guaranteed that
1341// vncExtensionInit() has already been called.
1342
1343void InitInput(int argc, char *argv[])
1344{
1345 DeviceIntPtr p, k;
1346 p = AddInputDevice(vfbMouseProc, TRUE);
1347 k = AddInputDevice(vfbKeybdProc, TRUE);
1348 RegisterPointerDevice(p);
1349 RegisterKeyboardDevice(k);
1350 miRegisterPointerDevice(screenInfo.screens[0], p);
1351 (void)mieqInit ((DevicePtr)k, (DevicePtr)p);
1352}