Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

xvnc.cc 34KB

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