blob: fc1499aeabfb5f5429aea637b09b0fd9285d44d9 [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{
Peter Åstrand60870912005-02-22 21:27:51 +0000111 int scrnum;
112 int width;
113 int paddedBytesWidth;
114 int paddedWidth;
115 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 CloseScreenProcPtr closeScreen;
127
128#ifdef HAS_MMAP
129 int mmap_fd;
130 char mmap_file[MAXPATHLEN];
131#endif
132
133#ifdef HAS_SHM
134 int shmid;
135#endif
136
137 Bool pixelFormatDefined;
138 Bool rgbNotBgr;
139 int redBits, greenBits, blueBits;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000140
141} vfbScreenInfo, *vfbScreenInfoPtr;
142
143static int vfbNumScreens;
144static vfbScreenInfo vfbScreens[MAXSCREENS];
145static Bool vfbPixmapDepths[33];
Peter Åstrand00c759d2005-02-22 20:11:47 +0000146#ifdef HAS_MMAP
147static char *pfbdir = NULL;
148#endif
149typedef enum { NORMAL_MEMORY_FB, SHARED_MEMORY_FB, MMAPPED_FILE_FB } fbMemType;
150static fbMemType fbmemtype = NORMAL_MEMORY_FB;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000151static char needswap = 0;
152static int lastScreen = -1;
Peter Åstrandc5421b22005-02-14 20:25:49 +0000153static Bool Render = TRUE;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000154
155static bool displaySpecified = false;
156static bool wellKnownSocketsCreated = false;
157static char displayNumStr[16];
158
159#define swapcopy16(_dst, _src) \
160 if (needswap) { CARD16 _s = _src; cpswaps(_s, _dst); } \
161 else _dst = _src;
162
163#define swapcopy32(_dst, _src) \
164 if (needswap) { CARD32 _s = _src; cpswapl(_s, _dst); } \
165 else _dst = _src;
166
167
Peter Åstrandf960f042005-02-22 20:07:55 +0000168static void
169vfbInitializePixmapDepths(void)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000170{
Peter Åstrandf960f042005-02-22 20:07:55 +0000171 int i;
172 vfbPixmapDepths[1] = TRUE; /* always need bitmaps */
173 for (i = 2; i <= 32; i++)
174 vfbPixmapDepths[i] = FALSE;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000175}
176
Peter Åstrandf960f042005-02-22 20:07:55 +0000177static void
178vfbInitializeDefaultScreens(void)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000179{
Peter Åstrandf960f042005-02-22 20:07:55 +0000180 int i;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000181
Peter Åstrandf960f042005-02-22 20:07:55 +0000182 for (i = 0; i < MAXSCREENS; i++)
183 {
184 vfbScreens[i].scrnum = i;
185 vfbScreens[i].width = VFB_DEFAULT_WIDTH;
186 vfbScreens[i].height = VFB_DEFAULT_HEIGHT;
187 vfbScreens[i].depth = VFB_DEFAULT_DEPTH;
188 vfbScreens[i].blackPixel = VFB_DEFAULT_BLACKPIXEL;
189 vfbScreens[i].whitePixel = VFB_DEFAULT_WHITEPIXEL;
190 vfbScreens[i].lineBias = VFB_DEFAULT_LINEBIAS;
191 vfbScreens[i].pixelFormatDefined = FALSE;
192 vfbScreens[i].pfbMemory = NULL;
193 }
194 vfbNumScreens = 1;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000195}
196
Peter Åstrand00c759d2005-02-22 20:11:47 +0000197static int
198vfbBitsPerPixel(int depth)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000199{
Peter Åstrand00c759d2005-02-22 20:11:47 +0000200 if (depth == 1) return 1;
201 else if (depth <= 8) return 8;
202 else if (depth <= 16) return 16;
203 else return 32;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000204}
205
206extern "C" {
Peter Åstrand00c759d2005-02-22 20:11:47 +0000207void
208ddxGiveUp()
209{
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000210 int i;
211
212 /* clean up the framebuffers */
213
Peter Åstrand00c759d2005-02-22 20:11:47 +0000214 switch (fbmemtype)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000215 {
Peter Åstrand00c759d2005-02-22 20:11:47 +0000216#ifdef HAS_MMAP
217 case MMAPPED_FILE_FB:
218 for (i = 0; i < vfbNumScreens; i++)
219 {
220 if (-1 == unlink(vfbScreens[i].mmap_file))
221 {
222 perror("unlink");
223 ErrorF("unlink %s failed, errno %d",
224 vfbScreens[i].mmap_file, errno);
225 }
226 }
227 break;
228#else /* HAS_MMAP */
229 case MMAPPED_FILE_FB:
230 break;
231#endif /* HAS_MMAP */
232
233#ifdef HAS_SHM
234 case SHARED_MEMORY_FB:
235 for (i = 0; i < vfbNumScreens; i++)
236 {
237 if (-1 == shmdt((char *)vfbScreens[i].pXWDHeader))
238 {
239 perror("shmdt");
240 ErrorF("shmdt failed, errno %d", errno);
241 }
242 }
243 break;
244#else /* HAS_SHM */
245 case SHARED_MEMORY_FB:
246 break;
247#endif /* HAS_SHM */
248
249 case NORMAL_MEMORY_FB:
250 for (i = 0; i < vfbNumScreens; i++)
251 {
252 Xfree(vfbScreens[i].pXWDHeader);
253 }
254 break;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000255 }
Peter Åstrand00c759d2005-02-22 20:11:47 +0000256}
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000257
Peter Åstrand5b1d7a22005-02-22 20:18:24 +0000258void
259AbortDDX()
260{
261 ddxGiveUp();
262}
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000263
Peter Åstrand5b1d7a22005-02-22 20:18:24 +0000264#ifdef __DARWIN__
265void
266DarwinHandleGUI(int argc, char *argv[])
267{
268}
269
270void GlxExtensionInit();
271void GlxWrapInitVisuals(void *procPtr);
272
273void
274DarwinGlxExtensionInit()
275{
276 GlxExtensionInit();
277}
278
279void
280DarwinGlxWrapInitVisuals(
281 void *procPtr)
282{
283 GlxWrapInitVisuals(procPtr);
284}
285#endif
286
287void
288OsVendorInit()
289{
290}
291
292void
293OsVendorFatalError()
294{
295}
296
297void ddxBeforeReset(void)
298{
299 return;
300}
301
302void
303ddxUseMsg()
304{
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000305 ErrorF("\nXvnc version %s - built %s\n", XVNCVERSION, buildtime);
306 ErrorF("Underlying X server release %d, %s\n\n", VENDOR_RELEASE,
307 VENDOR_STRING);
308 ErrorF("-screen scrn WxHxD set screen's width, height, depth\n");
309 ErrorF("-pixdepths list-of-int support given pixmap depths\n");
Peter Åstrandc5421b22005-02-14 20:25:49 +0000310#ifdef RENDER
311 ErrorF("+/-render turn on/off RENDER extension support"
312 "(default on)\n");
313#endif
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000314 ErrorF("-linebias n adjust thin line pixelization\n");
315 ErrorF("-blackpixel n pixel value for black\n");
316 ErrorF("-whitepixel n pixel value for white\n");
Peter Åstrand5b1d7a22005-02-22 20:18:24 +0000317
318#ifdef HAS_MMAP
319 ErrorF("-fbdir directory put framebuffers in mmap'ed files in directory\n");
320#endif
321
322#ifdef HAS_SHM
323 ErrorF("-shmem put framebuffers in shared memory\n");
324#endif
325
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000326 ErrorF("-geometry WxH set screen 0's width, height\n");
327 ErrorF("-depth D set screen 0's depth\n");
328 ErrorF("-pixelformat fmt set pixel format (rgbNNN or bgrNNN)\n");
329 ErrorF("-inetd has been launched from inetd\n");
330 ErrorF("\nVNC parameters:\n");
331
332 fprintf(stderr,"\n"
333 "Parameters can be turned on with -<param> or off with -<param>=0\n"
334 "Parameters which take a value can be specified as "
335 "-<param> <value>\n"
336 "Other valid forms are <param>=<value> -<param>=<value> "
337 "--<param>=<value>\n"
338 "Parameter names are case-insensitive. The parameters are:\n\n");
339 rfb::Configuration::listParams(79, 14);
340 }
341}
342
Peter Åstrandfc41a212005-02-22 20:29:40 +0000343/* ddxInitGlobals - called by |InitGlobals| from os/util.c */
344void ddxInitGlobals(void)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000345{
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000346}
347
Peter Åstrandfc41a212005-02-22 20:29:40 +0000348static
349bool displayNumFree(int num)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000350{
Peter Åstrandfc41a212005-02-22 20:29:40 +0000351 try {
352 network::TcpListener l(6000+num);
353 } catch (rdr::Exception& e) {
354 return false;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000355 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000356 char file[256];
357 sprintf(file, "/tmp/.X%d-lock", num);
358 if (access(file, F_OK) == 0) return false;
359 sprintf(file, "/tmp/.X11-unix/X%d", num);
360 if (access(file, F_OK) == 0) return false;
361 sprintf(file, "/usr/spool/sockets/X11/%d", num);
362 if (access(file, F_OK) == 0) return false;
363 return true;
364}
365
366int
367ddxProcessArgument(int argc, char *argv[], int i)
368{
369 static Bool firstTime = TRUE;
370
371 if (firstTime)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000372 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000373 vfbInitializeDefaultScreens();
374 vfbInitializePixmapDepths();
375 firstTime = FALSE;
376 rfb::initStdIOLoggers();
377 rfb::LogWriter::setLogParams("*:stderr:30");
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000378 }
379
Peter Åstrandfc41a212005-02-22 20:29:40 +0000380 if (argv[i][0] == ':')
381 displaySpecified = true;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000382
Peter Åstrandfc41a212005-02-22 20:29:40 +0000383 if (strcmp (argv[i], "-screen") == 0) /* -screen n WxHxD */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000384 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000385 int screenNum;
386 if (i + 2 >= argc) UseMsg();
387 screenNum = atoi(argv[i+1]);
388 if (screenNum < 0 || screenNum >= MAXSCREENS)
389 {
390 ErrorF("Invalid screen number %d\n", screenNum);
391 UseMsg();
392 }
393 if (3 != sscanf(argv[i+2], "%dx%dx%d",
394 &vfbScreens[screenNum].width,
395 &vfbScreens[screenNum].height,
396 &vfbScreens[screenNum].depth))
397 {
398 ErrorF("Invalid screen configuration %s\n", argv[i+2]);
399 UseMsg();
400 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000401
Peter Åstrandfc41a212005-02-22 20:29:40 +0000402 if (screenNum >= vfbNumScreens)
403 vfbNumScreens = screenNum + 1;
404 lastScreen = screenNum;
405 return 3;
406 }
407
408 if (strcmp (argv[i], "-pixdepths") == 0) /* -pixdepths list-of-depth */
409 {
410 int depth, ret = 1;
411
412 if (++i >= argc) UseMsg();
413 while ((i < argc) && (depth = atoi(argv[i++])) != 0)
414 {
415 if (depth < 0 || depth > 32)
416 {
417 ErrorF("Invalid pixmap depth %d\n", depth);
418 UseMsg();
419 }
420 vfbPixmapDepths[depth] = TRUE;
421 ret++;
422 }
423 return ret;
424 }
425
426 if (strcmp (argv[i], "+render") == 0) /* +render */
427 {
428 Render = TRUE;
429 return 1;
430 }
Peter Åstrandc5421b22005-02-14 20:25:49 +0000431
Peter Åstrandfc41a212005-02-22 20:29:40 +0000432 if (strcmp (argv[i], "-render") == 0) /* -render */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000433 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000434 Render = FALSE;
435 return 1;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000436 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000437
Peter Åstrandfc41a212005-02-22 20:29:40 +0000438 if (strcmp (argv[i], "-blackpixel") == 0) /* -blackpixel n */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000439 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000440 Pixel pix;
441 if (++i >= argc) UseMsg();
442 pix = atoi(argv[i]);
443 if (-1 == lastScreen)
444 {
445 int i;
446 for (i = 0; i < MAXSCREENS; i++)
447 {
448 vfbScreens[i].blackPixel = pix;
449 }
450 }
451 else
452 {
453 vfbScreens[lastScreen].blackPixel = pix;
454 }
455 return 2;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000456 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000457
458 if (strcmp (argv[i], "-whitepixel") == 0) /* -whitepixel n */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000459 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000460 Pixel pix;
461 if (++i >= argc) UseMsg();
462 pix = atoi(argv[i]);
463 if (-1 == lastScreen)
464 {
465 int i;
466 for (i = 0; i < MAXSCREENS; i++)
467 {
468 vfbScreens[i].whitePixel = pix;
469 }
470 }
471 else
472 {
473 vfbScreens[lastScreen].whitePixel = pix;
474 }
475 return 2;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000476 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000477
478 if (strcmp (argv[i], "-linebias") == 0) /* -linebias n */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000479 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000480 unsigned int linebias;
481 if (++i >= argc) UseMsg();
482 linebias = atoi(argv[i]);
483 if (-1 == lastScreen)
484 {
485 int i;
486 for (i = 0; i < MAXSCREENS; i++)
487 {
488 vfbScreens[i].lineBias = linebias;
489 }
490 }
491 else
492 {
493 vfbScreens[lastScreen].lineBias = linebias;
494 }
495 return 2;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000496 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000497
498#ifdef HAS_MMAP
499 if (strcmp (argv[i], "-fbdir") == 0) /* -fbdir directory */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000500 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000501 if (++i >= argc) UseMsg();
502 pfbdir = argv[i];
503 fbmemtype = MMAPPED_FILE_FB;
504 return 2;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000505 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000506#endif /* HAS_MMAP */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000507
Peter Åstrandfc41a212005-02-22 20:29:40 +0000508#ifdef HAS_SHM
509 if (strcmp (argv[i], "-shmem") == 0) /* -shmem */
510 {
511 fbmemtype = SHARED_MEMORY_FB;
512 return 1;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000513 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000514#endif
515
516 if (strcmp(argv[i], "-geometry") == 0)
517 {
518 if (++i >= argc) UseMsg();
519 if (sscanf(argv[i],"%dx%d",&vfbScreens[0].width,
520 &vfbScreens[0].height) != 2) {
521 ErrorF("Invalid geometry %s\n", argv[i]);
522 UseMsg();
523 }
524 return 2;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000525 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000526
527 if (strcmp(argv[i], "-depth") == 0)
528 {
529 if (++i >= argc) UseMsg();
530 vfbScreens[0].depth = atoi(argv[i]);
531 return 2;
532 }
533
534 if (strcmp(argv[i], "-pixelformat") == 0)
535 {
536 char rgbbgr[4];
537 int bits1, bits2, bits3;
538 if (++i >= argc) UseMsg();
539 if (sscanf(argv[i], "%3s%1d%1d%1d", rgbbgr,&bits1,&bits2,&bits3) < 4) {
540 ErrorF("Invalid pixel format %s\n", argv[i]);
541 UseMsg();
542 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000543
544#define SET_PIXEL_FORMAT(vfbScreen) \
545 (vfbScreen).pixelFormatDefined = TRUE; \
546 (vfbScreen).depth = bits1 + bits2 + bits3; \
547 (vfbScreen).greenBits = bits2; \
548 if (strcasecmp(rgbbgr, "bgr") == 0) { \
549 (vfbScreen).rgbNotBgr = FALSE; \
550 (vfbScreen).redBits = bits3; \
551 (vfbScreen).blueBits = bits1; \
552 } else if (strcasecmp(rgbbgr, "rgb") == 0) { \
553 (vfbScreen).rgbNotBgr = TRUE; \
554 (vfbScreen).redBits = bits1; \
555 (vfbScreen).blueBits = bits3; \
556 } else { \
557 ErrorF("Invalid pixel format %s\n", argv[i]); \
558 UseMsg(); \
559 }
560
Peter Åstrandfc41a212005-02-22 20:29:40 +0000561 if (-1 == lastScreen)
562 {
563 int i;
564 for (i = 0; i < MAXSCREENS; i++)
565 {
566 SET_PIXEL_FORMAT(vfbScreens[i]);
567 }
568 }
569 else
570 {
571 SET_PIXEL_FORMAT(vfbScreens[lastScreen]);
572 }
573
574 return 2;
575 }
576
577 if (strcmp(argv[i], "-inetd") == 0)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000578 {
Peter Åstrandfc41a212005-02-22 20:29:40 +0000579 dup2(0,3);
580 vncInetdSock = 3;
581 close(2);
582
583 if (!displaySpecified) {
584 int port = network::TcpSocket::getSockPort(vncInetdSock);
585 int displayNum = port - 5900;
586 if (displayNum < 0 || displayNum > 99 || !displayNumFree(displayNum)) {
587 for (displayNum = 1; displayNum < 100; displayNum++)
588 if (displayNumFree(displayNum)) break;
589
590 if (displayNum == 100)
591 FatalError("Xvnc error: no free display number for -inetd");
592 }
593
594 display = displayNumStr;
595 sprintf(displayNumStr, "%d", displayNum);
596 }
597
598 return 1;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000599 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000600
601 if (rfb::Configuration::setParam(argv[i]))
602 return 1;
603
604 if (argv[i][0] == '-' && i+1 < argc) {
605 if (rfb::Configuration::setParam(&argv[i][1], argv[i+1]))
606 return 2;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000607 }
Peter Åstrandfc41a212005-02-22 20:29:40 +0000608
609 return 0;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000610}
611
612#ifdef DDXTIME /* from ServerOSDefines */
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000613CARD32
614GetTimeInMillis()
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000615{
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000616 struct timeval tp;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000617
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000618 X_GETTIMEOFDAY(&tp);
619 return(tp.tv_sec * 1000) + (tp.tv_usec / 1000);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000620}
621#endif
622
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000623static ColormapPtr InstalledMaps[MAXSCREENS];
624
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000625static int
626vfbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000627{
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000628 /* By the time we are processing requests, we can guarantee that there
629 * is always a colormap installed */
630 *pmaps = InstalledMaps[pScreen->myNum]->mid;
631 return (1);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000632}
633
634
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000635static void
636vfbInstallColormap(ColormapPtr pmap)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000637{
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000638 int index = pmap->pScreen->myNum;
639 ColormapPtr oldpmap = InstalledMaps[index];
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000640
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000641 if (pmap != oldpmap)
642 {
643 int entries;
644 XWDFileHeader *pXWDHeader;
645 XWDColor *pXWDCmap;
646 VisualPtr pVisual;
647 Pixel * ppix;
648 xrgb * prgb;
649 xColorItem *defs;
650 int i;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000651
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000652 if(oldpmap != (ColormapPtr)None)
653 WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
654 /* Install pmap */
655 InstalledMaps[index] = pmap;
656 WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000657
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000658 entries = pmap->pVisual->ColormapEntries;
659 pXWDHeader = vfbScreens[pmap->pScreen->myNum].pXWDHeader;
660 pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
661 pVisual = pmap->pVisual;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000662
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000663 swapcopy32(pXWDHeader->visual_class, pVisual->c_class);
664 swapcopy32(pXWDHeader->red_mask, pVisual->redMask);
665 swapcopy32(pXWDHeader->green_mask, pVisual->greenMask);
666 swapcopy32(pXWDHeader->blue_mask, pVisual->blueMask);
667 swapcopy32(pXWDHeader->bits_per_rgb, pVisual->bitsPerRGBValue);
668 swapcopy32(pXWDHeader->colormap_entries, pVisual->ColormapEntries);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000669
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000670 ppix = (Pixel *)ALLOCATE_LOCAL(entries * sizeof(Pixel));
671 prgb = (xrgb *)ALLOCATE_LOCAL(entries * sizeof(xrgb));
672 defs = (xColorItem *)ALLOCATE_LOCAL(entries * sizeof(xColorItem));
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000673
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000674 for (i = 0; i < entries; i++) ppix[i] = i;
675 /* XXX truecolor */
676 QueryColors(pmap, entries, ppix, prgb);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000677
Peter Åstrand9d803ef2005-02-22 20:35:43 +0000678 for (i = 0; i < entries; i++) { /* convert xrgbs to xColorItems */
679 defs[i].pixel = ppix[i] & 0xff; /* change pixel to index */
680 defs[i].red = prgb[i].red;
681 defs[i].green = prgb[i].green;
682 defs[i].blue = prgb[i].blue;
683 defs[i].flags = DoRed|DoGreen|DoBlue;
684 }
685 (*pmap->pScreen->StoreColors)(pmap, entries, defs);
686
687 DEALLOCATE_LOCAL(ppix);
688 DEALLOCATE_LOCAL(prgb);
689 DEALLOCATE_LOCAL(defs);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000690 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000691}
692
Peter Åstrand853287d2005-02-22 20:46:58 +0000693static void
694vfbUninstallColormap(ColormapPtr pmap)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000695{
Peter Åstrand853287d2005-02-22 20:46:58 +0000696 ColormapPtr curpmap = InstalledMaps[pmap->pScreen->myNum];
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000697
Peter Åstrand853287d2005-02-22 20:46:58 +0000698 if(pmap == curpmap)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000699 {
Peter Åstrand853287d2005-02-22 20:46:58 +0000700 if (pmap->mid != pmap->pScreen->defColormap)
701 {
702 curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap,
703 RT_COLORMAP);
704 (*pmap->pScreen->InstallColormap)(curpmap);
705 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000706 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000707}
708
Peter Åstrand853287d2005-02-22 20:46:58 +0000709static void
710vfbStoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000711{
Peter Åstrand853287d2005-02-22 20:46:58 +0000712 XWDColor *pXWDCmap;
713 int i;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000714
Peter Åstrand853287d2005-02-22 20:46:58 +0000715 if (pmap != InstalledMaps[pmap->pScreen->myNum])
716 {
717 return;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000718 }
Peter Åstrand853287d2005-02-22 20:46:58 +0000719
720 pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
721
Peter Åstrandbe228572005-02-22 20:48:29 +0000722 if ((pmap->pVisual->c_class | DynamicClass) == DirectColor)
Peter Åstrand853287d2005-02-22 20:46:58 +0000723 {
724 return;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000725 }
Peter Åstrand853287d2005-02-22 20:46:58 +0000726
727 for (i = 0; i < ndef; i++)
728 {
729 if (pdefs[i].flags & DoRed)
730 {
731 swapcopy16(pXWDCmap[pdefs[i].pixel].red, pdefs[i].red);
732 }
733 if (pdefs[i].flags & DoGreen)
734 {
735 swapcopy16(pXWDCmap[pdefs[i].pixel].green, pdefs[i].green);
736 }
737 if (pdefs[i].flags & DoBlue)
738 {
739 swapcopy16(pXWDCmap[pdefs[i].pixel].blue, pdefs[i].blue);
740 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000741 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000742}
743
Peter Åstrand853287d2005-02-22 20:46:58 +0000744static Bool
745vfbSaveScreen(ScreenPtr pScreen, int on)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000746{
Peter Åstrand853287d2005-02-22 20:46:58 +0000747 return TRUE;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000748}
749
Peter Åstrand8de329f2005-02-22 21:05:16 +0000750static char *
751vfbAllocateFramebufferMemory(vfbScreenInfoPtr pvfb)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000752{
Peter Åstrand8de329f2005-02-22 21:05:16 +0000753 if (pvfb->pfbMemory) return pvfb->pfbMemory; /* already done */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000754
Peter Åstrand8de329f2005-02-22 21:05:16 +0000755 pvfb->sizeInBytes = pvfb->paddedBytesWidth * pvfb->height;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000756
Peter Åstrand8de329f2005-02-22 21:05:16 +0000757 /* Calculate how many entries in colormap. This is rather bogus, because
758 * the visuals haven't even been set up yet, but we need to know because we
759 * have to allocate space in the file for the colormap. The number 10
760 * below comes from the MAX_PSEUDO_DEPTH define in cfbcmap.c.
761 */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000762
Peter Åstrand8de329f2005-02-22 21:05:16 +0000763 if (pvfb->depth <= 10)
764 { /* single index colormaps */
765 pvfb->ncolors = 1 << pvfb->depth;
766 }
767 else
768 { /* decomposed colormaps */
769 int nplanes_per_color_component = pvfb->depth / 3;
770 if (pvfb->depth % 3) nplanes_per_color_component++;
771 pvfb->ncolors = 1 << nplanes_per_color_component;
772 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000773
Peter Åstrand8de329f2005-02-22 21:05:16 +0000774 /* add extra bytes for XWDFileHeader, window name, and colormap */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000775
Peter Åstrand8de329f2005-02-22 21:05:16 +0000776 pvfb->sizeInBytes += SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN +
777 pvfb->ncolors * SIZEOF(XWDColor);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000778
Peter Åstrand8de329f2005-02-22 21:05:16 +0000779 pvfb->pXWDHeader = NULL;
780 switch (fbmemtype)
781 {
782#ifdef HAS_MMAP
783 case MMAPPED_FILE_FB: vfbAllocateMmappedFramebuffer(pvfb); break;
784#else
785 case MMAPPED_FILE_FB: break;
786#endif
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000787
Peter Åstrand8de329f2005-02-22 21:05:16 +0000788#ifdef HAS_SHM
789 case SHARED_MEMORY_FB: vfbAllocateSharedMemoryFramebuffer(pvfb); break;
790#else
791 case SHARED_MEMORY_FB: break;
792#endif
793
794 case NORMAL_MEMORY_FB:
795 pvfb->pXWDHeader = (XWDFileHeader *)Xalloc(pvfb->sizeInBytes);
796 break;
797 }
798
799 if (pvfb->pXWDHeader)
800 {
801 pvfb->pXWDCmap = (XWDColor *)((char *)pvfb->pXWDHeader
802 + SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN);
803 pvfb->pfbMemory = (char *)(pvfb->pXWDCmap + pvfb->ncolors);
804
805 return pvfb->pfbMemory;
806 }
807 else
808 return NULL;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000809}
810
Peter Åstrandf9357f52005-02-22 21:08:02 +0000811static void
812vfbWriteXWDFileHeader(ScreenPtr pScreen)
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000813{
Peter Åstrandf9357f52005-02-22 21:08:02 +0000814 vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
815 XWDFileHeader *pXWDHeader = pvfb->pXWDHeader;
816 char hostname[XWD_WINDOW_NAME_LEN];
817 unsigned long swaptest = 1;
818 int i;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000819
Peter Åstrandf9357f52005-02-22 21:08:02 +0000820 needswap = *(char *) &swaptest;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000821
Peter Åstrandf9357f52005-02-22 21:08:02 +0000822 pXWDHeader->header_size = (char *)pvfb->pXWDCmap - (char *)pvfb->pXWDHeader;
823 pXWDHeader->file_version = XWD_FILE_VERSION;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000824
Peter Åstrandf9357f52005-02-22 21:08:02 +0000825 pXWDHeader->pixmap_format = ZPixmap;
826 pXWDHeader->pixmap_depth = pvfb->depth;
827 pXWDHeader->pixmap_height = pXWDHeader->window_height = pvfb->height;
828 pXWDHeader->xoffset = 0;
829 pXWDHeader->byte_order = IMAGE_BYTE_ORDER;
830 pXWDHeader->bitmap_bit_order = BITMAP_BIT_ORDER;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000831#ifndef INTERNAL_VS_EXTERNAL_PADDING
Peter Åstrandf9357f52005-02-22 21:08:02 +0000832 pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->width;
833 pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT;
834 pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000835#else
Peter Åstrandf9357f52005-02-22 21:08:02 +0000836 pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->paddedWidth;
837 pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT_PROTO;
838 pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD_PROTO;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000839#endif
Peter Åstrandf9357f52005-02-22 21:08:02 +0000840 pXWDHeader->bits_per_pixel = pvfb->bitsPerPixel;
841 pXWDHeader->bytes_per_line = pvfb->paddedBytesWidth;
842 pXWDHeader->ncolors = pvfb->ncolors;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000843
Peter Åstrandf9357f52005-02-22 21:08:02 +0000844 /* visual related fields are written when colormap is installed */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000845
Peter Åstrandf9357f52005-02-22 21:08:02 +0000846 pXWDHeader->window_x = pXWDHeader->window_y = 0;
847 pXWDHeader->window_bdrwidth = 0;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000848
Peter Åstrandf9357f52005-02-22 21:08:02 +0000849 /* write xwd "window" name: Xvfb hostname:server.screen */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000850
Peter Åstrandf9357f52005-02-22 21:08:02 +0000851 if (-1 == gethostname(hostname, sizeof(hostname)))
852 hostname[0] = 0;
853 else
854 hostname[XWD_WINDOW_NAME_LEN-1] = 0;
855 sprintf((char *)(pXWDHeader+1), "Xvfb %s:%s.%d", hostname, display,
856 pScreen->myNum);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000857
Peter Åstrandf9357f52005-02-22 21:08:02 +0000858 /* write colormap pixel slot values */
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000859
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000860 for (i = 0; i < pvfb->ncolors; i++)
861 {
Peter Åstrandf9357f52005-02-22 21:08:02 +0000862 pvfb->pXWDCmap[i].pixel = i;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000863 }
Peter Åstrandf9357f52005-02-22 21:08:02 +0000864
865 /* byte swap to most significant byte first */
866
867 if (needswap)
868 {
869 SwapLongs((CARD32 *)pXWDHeader, SIZEOF(XWDheader)/4);
870 for (i = 0; i < pvfb->ncolors; i++)
871 {
872 register char n;
873 swapl(&pvfb->pXWDCmap[i].pixel, n);
874 }
875 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000876}
877
878
Peter Åstrandf9357f52005-02-22 21:08:02 +0000879static Bool
880vfbCursorOffScreen (ScreenPtr *ppScreen, int *x, int *y)
881{
882 return FALSE;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000883}
Peter Åstrandf9357f52005-02-22 21:08:02 +0000884
885static void
886vfbCrossScreen (ScreenPtr pScreen, Bool entering)
887{
888}
889
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000890static Bool vfbRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) {
Peter Åstrand5eef5ee2005-02-22 21:13:14 +0000891 return TRUE;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000892}
Peter Åstrand5eef5ee2005-02-22 21:13:14 +0000893
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000894static Bool vfbUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) {
Peter Åstrand5eef5ee2005-02-22 21:13:14 +0000895 return TRUE;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000896}
Peter Åstrand5eef5ee2005-02-22 21:13:14 +0000897
898static void vfbSetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
899{
900}
901
902static void vfbMoveCursor(ScreenPtr pScreen, int x, int y)
903{
904}
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000905
906static miPointerSpriteFuncRec vfbPointerSpriteFuncs = {
Peter Åstrand5eef5ee2005-02-22 21:13:14 +0000907 vfbRealizeCursor,
908 vfbUnrealizeCursor,
909 vfbSetCursor,
910 vfbMoveCursor
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000911};
912
Peter Åstrand5eef5ee2005-02-22 21:13:14 +0000913static miPointerScreenFuncRec vfbPointerCursorFuncs = {
914 vfbCursorOffScreen,
915 vfbCrossScreen,
916 miPointerWarpCursor
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000917};
918
Peter Åstrand60870912005-02-22 21:27:51 +0000919static Bool
920vfbCloseScreen(int index, ScreenPtr pScreen)
921{
922 vfbScreenInfoPtr pvfb = &vfbScreens[index];
923 int i;
924
925 pScreen->CloseScreen = pvfb->closeScreen;
926
927 /*
928 * XXX probably lots of stuff to clean. For now,
929 * clear InstalledMaps[] so that server reset works correctly.
930 */
931 for (i = 0; i < MAXSCREENS; i++)
932 InstalledMaps[i] = NULL;
933
934 return pScreen->CloseScreen(index, pScreen);
935}
936
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000937static Bool vfbScreenInit(int index, ScreenPtr pScreen, int argc, char** argv)
938{
939 vfbScreenInfoPtr pvfb = &vfbScreens[index];
940 int dpi = 100;
941 int ret;
942 char *pbits;
943
944 if (monitorResolution) dpi = monitorResolution;
945
Peter Åstrand4efcfe02005-02-22 21:00:26 +0000946 pvfb->paddedBytesWidth = PixmapBytePad(pvfb->width, pvfb->depth);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000947 pvfb->bitsPerPixel = vfbBitsPerPixel(pvfb->depth);
Peter Åstrand4efcfe02005-02-22 21:00:26 +0000948 pvfb->paddedWidth = pvfb->paddedBytesWidth * 8 / pvfb->bitsPerPixel;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000949 pbits = vfbAllocateFramebufferMemory(pvfb);
950 if (!pbits) return FALSE;
951 vncFbptr[index] = pbits;
952
953 defaultColorVisualClass
954 = (pvfb->bitsPerPixel > 8) ? TrueColor : PseudoColor;
955
Peter Åstrandc5421b22005-02-14 20:25:49 +0000956 ret = fbScreenInit(pScreen, pbits, pvfb->width, pvfb->height,
957 dpi, dpi, pvfb->paddedWidth, pvfb->bitsPerPixel);
958
959#ifdef RENDER
960 if (ret && Render)
961 fbPictureInit(pScreen, 0, 0);
962#endif
963
964 if (!ret) return FALSE;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000965
966 pScreen->InstallColormap = vfbInstallColormap;
967 pScreen->UninstallColormap = vfbUninstallColormap;
968 pScreen->ListInstalledColormaps = vfbListInstalledColormaps;
969
970 pScreen->SaveScreen = vfbSaveScreen;
971 pScreen->StoreColors = vfbStoreColors;
972
Peter Åstrand5eef5ee2005-02-22 21:13:14 +0000973 miPointerInitialize(pScreen, &vfbPointerSpriteFuncs, &vfbPointerCursorFuncs,
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +0000974 FALSE);
975
976 vfbWriteXWDFileHeader(pScreen);
977
978 pScreen->blackPixel = pvfb->blackPixel;
979 pScreen->whitePixel = pvfb->whitePixel;
980
981 if (!pvfb->pixelFormatDefined && pvfb->depth == 16) {
982 pvfb->pixelFormatDefined = TRUE;
983 pvfb->rgbNotBgr = TRUE;
984 pvfb->blueBits = pvfb->redBits = 5;
985 pvfb->greenBits = 6;
986 }
987
988 if (pvfb->pixelFormatDefined) {
989 VisualPtr vis;
990 for (vis = pScreen->visuals; vis->vid != pScreen->rootVisual; vis++)
991 ;
992
993 if (pvfb->rgbNotBgr) {
994 vis->offsetBlue = 0;
995 vis->blueMask = (1 << pvfb->blueBits) - 1;
996 vis->offsetGreen = pvfb->blueBits;
997 vis->greenMask = ((1 << pvfb->greenBits) - 1) << vis->offsetGreen;
998 vis->offsetRed = vis->offsetGreen + pvfb->greenBits;
999 vis->redMask = ((1 << pvfb->redBits) - 1) << vis->offsetRed;
1000 } else {
1001 vis->offsetRed = 0;
1002 vis->redMask = (1 << pvfb->redBits) - 1;
1003 vis->offsetGreen = pvfb->redBits;
1004 vis->greenMask = ((1 << pvfb->greenBits) - 1) << vis->offsetGreen;
1005 vis->offsetBlue = vis->offsetGreen + pvfb->greenBits;
1006 vis->blueMask = ((1 << pvfb->blueBits) - 1) << vis->offsetBlue;
1007 }
1008 }
1009
Peter Åstrand1bdab802005-02-14 14:03:35 +00001010 ret = fbCreateDefColormap(pScreen);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +00001011
1012 miSetZeroLineBias(pScreen, pvfb->lineBias);
1013
1014 return ret;
1015
1016} /* end vfbScreenInit */
1017
1018
1019static void vfbClientStateChange(CallbackListPtr*, pointer, pointer) {
1020 dispatchException &= ~DE_RESET;
1021}
1022
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +00001023void InitOutput(ScreenInfo *screenInfo, int argc, char **argv)
1024{
1025 ErrorF("\nXvnc version %s - built %s\n", XVNCVERSION, buildtime);
1026 ErrorF("Underlying X server release %d, %s\n\n", VENDOR_RELEASE,
1027 VENDOR_STRING);
1028 wellKnownSocketsCreated = true;
1029
1030 int i;
1031 int NumFormats = 0;
1032
1033 /* initialize pixmap formats */
1034
1035 /* must have a pixmap depth to match every screen depth */
1036 for (i = 0; i < vfbNumScreens; i++)
1037 {
1038 vfbPixmapDepths[vfbScreens[i].depth] = TRUE;
1039 }
1040
Peter Åstrandc5421b22005-02-14 20:25:49 +00001041 /* RENDER needs a good set of pixmaps. */
1042 if (Render) {
1043 vfbPixmapDepths[1] = TRUE;
1044 vfbPixmapDepths[4] = TRUE;
1045 vfbPixmapDepths[8] = TRUE;
1046/* vfbPixmapDepths[15] = TRUE; */
1047 vfbPixmapDepths[16] = TRUE;
1048 vfbPixmapDepths[24] = TRUE;
1049 vfbPixmapDepths[32] = TRUE;
1050 }
1051
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +00001052 for (i = 1; i <= 32; i++)
1053 {
1054 if (vfbPixmapDepths[i])
1055 {
1056 if (NumFormats >= MAXFORMATS)
1057 FatalError ("MAXFORMATS is too small for this server\n");
1058 screenInfo->formats[NumFormats].depth = i;
1059 screenInfo->formats[NumFormats].bitsPerPixel = vfbBitsPerPixel(i);
1060 screenInfo->formats[NumFormats].scanlinePad = BITMAP_SCANLINE_PAD;
1061 NumFormats++;
1062 }
1063 }
1064
1065 screenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
1066 screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
1067 screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
1068 screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
1069 screenInfo->numPixmapFormats = NumFormats;
1070
1071 /* initialize screens */
1072
1073 for (i = 0; i < vfbNumScreens; i++)
1074 {
1075 if (-1 == AddScreen(vfbScreenInit, argc, argv))
1076 {
1077 FatalError("Couldn't add screen %d", i);
1078 }
1079 }
1080
1081 if (!AddCallback(&ClientStateCallback, vfbClientStateChange, 0)) {
1082 FatalError("AddCallback failed\n");
1083 }
1084
1085} /* end InitOutput */
1086
1087#ifdef DPMSExtension
1088extern "C" {
1089#if NeedFunctionPrototypes
1090 void DPMSSet(CARD16 level)
1091#else
1092 void DPMSSet(level)
1093 CARD16 level;
1094#endif
1095 {
1096 return;
1097 }
1098
1099 Bool DPMSSupported()
1100 {
1101 return FALSE;
1102 }
1103}
1104#endif
1105
1106/* this is just to get the server to link on AIX */
1107#ifdef AIXV3
1108int SelectWaitTime = 10000; /* usec */
1109#endif
1110
1111Bool LegalModifier(unsigned int key, DevicePtr pDev)
1112{
1113 return TRUE;
1114}
1115
1116void ProcessInputEvents()
1117{
1118 mieqProcessInputEvents();
1119 miPointerUpdate();
1120}
1121
1122/* Fairly standard US PC Keyboard */
1123
1124#define VFB_MIN_KEY 8
1125#define VFB_MAX_KEY 255
1126#define VFB_MAP_LEN (VFB_MAX_KEY - VFB_MIN_KEY + 1)
1127#define KEYSYMS_PER_KEY 2
1128KeySym keyboardMap[VFB_MAP_LEN * KEYSYMS_PER_KEY] = {
1129 NoSymbol, NoSymbol,
1130 XK_Escape, NoSymbol,
1131 XK_1, XK_exclam,
1132 XK_2, XK_at,
1133 XK_3, XK_numbersign,
1134 XK_4, XK_dollar,
1135 XK_5, XK_percent,
1136 XK_6, XK_asciicircum,
1137 XK_7, XK_ampersand,
1138 XK_8, XK_asterisk,
1139 XK_9, XK_parenleft,
1140 XK_0, XK_parenright,
1141 XK_minus, XK_underscore,
1142 XK_equal, XK_plus,
1143 XK_BackSpace, NoSymbol,
1144 XK_Tab, NoSymbol,
1145 XK_q, XK_Q,
1146 XK_w, XK_W,
1147 XK_e, XK_E,
1148 XK_r, XK_R,
1149 XK_t, XK_T,
1150 XK_y, XK_Y,
1151 XK_u, XK_U,
1152 XK_i, XK_I,
1153 XK_o, XK_O,
1154 XK_p, XK_P,
1155 XK_bracketleft, XK_braceleft,
1156 XK_bracketright, XK_braceright,
1157 XK_Return, NoSymbol,
1158 XK_Control_L, NoSymbol,
1159 XK_a, XK_A,
1160 XK_s, XK_S,
1161 XK_d, XK_D,
1162 XK_f, XK_F,
1163 XK_g, XK_G,
1164 XK_h, XK_H,
1165 XK_j, XK_J,
1166 XK_k, XK_K,
1167 XK_l, XK_L,
1168 XK_semicolon, XK_colon,
1169 XK_apostrophe, XK_quotedbl,
1170 XK_grave, XK_asciitilde,
1171 XK_Shift_L, NoSymbol,
1172 XK_backslash, XK_bar,
1173 XK_z, XK_Z,
1174 XK_x, XK_X,
1175 XK_c, XK_C,
1176 XK_v, XK_V,
1177 XK_b, XK_B,
1178 XK_n, XK_N,
1179 XK_m, XK_M,
1180 XK_comma, XK_less,
1181 XK_period, XK_greater,
1182 XK_slash, XK_question,
1183 XK_Shift_R, NoSymbol,
1184 XK_KP_Multiply, NoSymbol,
1185 XK_Alt_L, XK_Meta_L,
1186 XK_space, NoSymbol,
1187 /*XK_Caps_Lock*/ NoSymbol, NoSymbol,
1188 XK_F1, NoSymbol,
1189 XK_F2, NoSymbol,
1190 XK_F3, NoSymbol,
1191 XK_F4, NoSymbol,
1192 XK_F5, NoSymbol,
1193 XK_F6, NoSymbol,
1194 XK_F7, NoSymbol,
1195 XK_F8, NoSymbol,
1196 XK_F9, NoSymbol,
1197 XK_F10, NoSymbol,
1198 XK_Num_Lock, XK_Pointer_EnableKeys,
1199 XK_Scroll_Lock, NoSymbol,
1200 XK_KP_Home, XK_KP_7,
1201 XK_KP_Up, XK_KP_8,
1202 XK_KP_Prior, XK_KP_9,
1203 XK_KP_Subtract, NoSymbol,
1204 XK_KP_Left, XK_KP_4,
1205 XK_KP_Begin, XK_KP_5,
1206 XK_KP_Right, XK_KP_6,
1207 XK_KP_Add, NoSymbol,
1208 XK_KP_End, XK_KP_1,
1209 XK_KP_Down, XK_KP_2,
1210 XK_KP_Next, XK_KP_3,
1211 XK_KP_Insert, XK_KP_0,
1212 XK_KP_Delete, XK_KP_Decimal,
1213 NoSymbol, NoSymbol,
1214 NoSymbol, NoSymbol,
1215 NoSymbol, NoSymbol,
1216 XK_F11, NoSymbol,
1217 XK_F12, NoSymbol,
1218 XK_Home, NoSymbol,
1219 XK_Up, NoSymbol,
1220 XK_Prior, NoSymbol,
1221 XK_Left, NoSymbol,
1222 NoSymbol, NoSymbol,
1223 XK_Right, NoSymbol,
1224 XK_End, NoSymbol,
1225 XK_Down, NoSymbol,
1226 XK_Next, NoSymbol,
1227 XK_Insert, NoSymbol,
1228 XK_Delete, NoSymbol,
1229 XK_KP_Enter, NoSymbol,
1230 XK_Control_R, NoSymbol,
1231 XK_Pause, XK_Break,
1232 XK_Print, XK_Execute,
1233 XK_KP_Divide, NoSymbol,
1234 XK_Alt_R, XK_Meta_R,
1235};
1236
1237static Bool GetMappings(KeySymsPtr pKeySyms, CARD8 *pModMap)
1238{
1239 int i;
1240
1241 for (i = 0; i < MAP_LENGTH; i++)
1242 pModMap[i] = NoSymbol;
1243
1244 for (i = 0; i < VFB_MAP_LEN; i++) {
1245 if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Caps_Lock)
1246 pModMap[i + VFB_MIN_KEY] = LockMask;
1247 else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Shift_L ||
1248 keyboardMap[i * KEYSYMS_PER_KEY] == XK_Shift_R)
1249 pModMap[i + VFB_MIN_KEY] = ShiftMask;
1250 else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Control_L ||
1251 keyboardMap[i * KEYSYMS_PER_KEY] == XK_Control_R) {
1252 pModMap[i + VFB_MIN_KEY] = ControlMask;
1253 }
1254 else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Alt_L ||
1255 keyboardMap[i * KEYSYMS_PER_KEY] == XK_Alt_R)
1256 pModMap[i + VFB_MIN_KEY] = Mod1Mask;
1257 }
1258
1259 pKeySyms->minKeyCode = VFB_MIN_KEY;
1260 pKeySyms->maxKeyCode = VFB_MAX_KEY;
1261 pKeySyms->mapWidth = KEYSYMS_PER_KEY;
1262 pKeySyms->map = keyboardMap;
1263
1264 return TRUE;
1265}
1266
1267static void vfbBell(int percent, DeviceIntPtr device, pointer ctrl, int class_)
1268{
1269 if (percent > 0)
1270 vncBell();
1271}
1272
1273static int vfbKeybdProc(DeviceIntPtr pDevice, int onoff)
1274{
1275 KeySymsRec keySyms;
1276 CARD8 modMap[MAP_LENGTH];
1277 DevicePtr pDev = (DevicePtr)pDevice;
1278
1279 switch (onoff)
1280 {
1281 case DEVICE_INIT:
1282 GetMappings(&keySyms, modMap);
1283 InitKeyboardDeviceStruct(pDev, &keySyms, modMap,
1284 (BellProcPtr)vfbBell, (KbdCtrlProcPtr)NoopDDA);
1285 break;
1286 case DEVICE_ON:
1287 pDev->on = TRUE;
1288 break;
1289 case DEVICE_OFF:
1290 pDev->on = FALSE;
1291 break;
1292 case DEVICE_CLOSE:
1293 break;
1294 }
1295 return Success;
1296}
1297
1298static int vfbMouseProc(DeviceIntPtr pDevice, int onoff)
1299{
1300 BYTE map[6];
1301 DevicePtr pDev = (DevicePtr)pDevice;
1302
1303 switch (onoff)
1304 {
1305 case DEVICE_INIT:
1306 map[1] = 1;
1307 map[2] = 2;
1308 map[3] = 3;
1309 map[4] = 4;
1310 map[5] = 5;
1311 InitPointerDeviceStruct(pDev, map, 5, miPointerGetMotionEvents,
1312 (PtrCtrlProcPtr)NoopDDA, miPointerGetMotionBufferSize());
1313 break;
1314
1315 case DEVICE_ON:
1316 pDev->on = TRUE;
1317 break;
1318
1319 case DEVICE_OFF:
1320 pDev->on = FALSE;
1321 break;
1322
1323 case DEVICE_CLOSE:
1324 break;
1325 }
1326 return Success;
1327}
1328
1329// InitInput is called after InitExtensions, so we're guaranteed that
1330// vncExtensionInit() has already been called.
1331
1332void InitInput(int argc, char *argv[])
1333{
1334 DeviceIntPtr p, k;
1335 p = AddInputDevice(vfbMouseProc, TRUE);
1336 k = AddInputDevice(vfbKeybdProc, TRUE);
1337 RegisterPointerDevice(p);
1338 RegisterKeyboardDevice(k);
1339 miRegisterPointerDevice(screenInfo.screens[0], p);
1340 (void)mieqInit ((DevicePtr)k, (DevicePtr)p);
1341}