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