You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

xvnc.cc 35KB

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