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.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324
  1. /* Copyright (c) 1993 X Consortium
  2. Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
  3. Copyright (C) 2009 Pierre Ossman for Cendio AB
  4. Permission is hereby granted, free of charge, to any person obtaining
  5. a copy of this software and associated documentation files (the
  6. "Software"), to deal in the Software without restriction, including
  7. without limitation the rights to use, copy, modify, merge, publish,
  8. distribute, sublicense, and/or sell copies of the Software, and to
  9. permit persons to whom the Software is furnished to do so, subject to
  10. the following conditions:
  11. The above copyright notice and this permission notice shall be included
  12. in all copies or substantial portions of the Software.
  13. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  14. OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  15. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  16. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
  17. OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  18. ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  19. OTHER DEALINGS IN THE SOFTWARE.
  20. Except as contained in this notice, the name of the X Consortium shall
  21. not be used in advertising or otherwise to promote the sale, use or
  22. other dealings in this Software without prior written authorization
  23. from the X Consortium.
  24. */
  25. #ifdef HAVE_DIX_CONFIG_H
  26. #include <dix-config.h>
  27. #endif
  28. #include <rfb/Configuration.h>
  29. #include <rfb/Logger_stdio.h>
  30. #include <rfb/LogWriter.h>
  31. #include <network/TcpSocket.h>
  32. #include "vncExtInit.h"
  33. #include "xorg-version.h"
  34. extern "C" {
  35. #define class c_class
  36. #define public c_public
  37. #ifdef WIN32
  38. #include <X11/Xwinsock.h>
  39. #endif
  40. #include <stdio.h>
  41. #include <X11/X.h>
  42. #define NEED_EVENTS
  43. #include <X11/Xproto.h>
  44. #include <X11/Xos.h>
  45. #include "scrnintstr.h"
  46. #include "servermd.h"
  47. #include "fb.h"
  48. #include "mi.h"
  49. #include "mibstore.h"
  50. #include "colormapst.h"
  51. #include "gcstruct.h"
  52. #include "input.h"
  53. #include "mipointer.h"
  54. #define new New
  55. #include "micmap.h"
  56. #undef new
  57. #include <sys/types.h>
  58. #include <sys/stat.h>
  59. #include <errno.h>
  60. #ifndef WIN32
  61. #include <sys/param.h>
  62. #endif
  63. #include <X11/XWDFile.h>
  64. #ifdef HAS_SHM
  65. #include <sys/ipc.h>
  66. #include <sys/shm.h>
  67. #endif /* HAS_SHM */
  68. #include "dix.h"
  69. #include "miline.h"
  70. #include "inputstr.h"
  71. #ifdef RANDR
  72. #include "randrstr.h"
  73. #endif /* RANDR */
  74. #include <X11/keysym.h>
  75. extern char buildtime[];
  76. #if XORG >= 17
  77. #undef VENDOR_RELEASE
  78. #undef VENDOR_STRING
  79. #include "version-config.h"
  80. #include "site.h"
  81. #endif
  82. #undef class
  83. #undef public
  84. }
  85. #define XVNCVERSION "TigerVNC 1.0.90"
  86. #define XVNCCOPYRIGHT ("Copyright (C) 2002-2005 RealVNC Ltd.\n" \
  87. "Copyright (C) 2000-2006 Constantin Kaplinsky\n" \
  88. "Copyright (C) 2004-2009 Peter Astrand for Cendio AB\n" \
  89. "See http://www.tigervnc.org for information on TigerVNC.\n")
  90. extern char *display;
  91. extern int monitorResolution;
  92. #define VFB_DEFAULT_WIDTH 1024
  93. #define VFB_DEFAULT_HEIGHT 768
  94. #define VFB_DEFAULT_DEPTH 24
  95. #define VFB_DEFAULT_WHITEPIXEL 0xffffffff
  96. #define VFB_DEFAULT_BLACKPIXEL 0
  97. #define VFB_DEFAULT_LINEBIAS 0
  98. #define XWD_WINDOW_NAME_LEN 60
  99. typedef struct
  100. {
  101. int width;
  102. int height;
  103. int depth;
  104. /* Computed when allocated */
  105. int paddedBytesWidth;
  106. int paddedWidth;
  107. int bitsPerPixel;
  108. /* Private */
  109. int sizeInBytes;
  110. void *pfbMemory;
  111. #ifdef HAS_SHM
  112. int shmid;
  113. #endif
  114. } vfbFramebufferInfo, *vfbFramebufferInfoPtr;
  115. typedef struct
  116. {
  117. int scrnum;
  118. Pixel blackPixel;
  119. Pixel whitePixel;
  120. unsigned int lineBias;
  121. CloseScreenProcPtr closeScreen;
  122. vfbFramebufferInfo fb;
  123. Bool pixelFormatDefined;
  124. Bool rgbNotBgr;
  125. int redBits, greenBits, blueBits;
  126. } vfbScreenInfo, *vfbScreenInfoPtr;
  127. static int vfbNumScreens;
  128. static vfbScreenInfo vfbScreens[MAXSCREENS];
  129. static Bool vfbPixmapDepths[33];
  130. typedef enum { NORMAL_MEMORY_FB, SHARED_MEMORY_FB } fbMemType;
  131. static fbMemType fbmemtype = NORMAL_MEMORY_FB;
  132. static int lastScreen = -1;
  133. static Bool Render = TRUE;
  134. static bool displaySpecified = false;
  135. static bool wellKnownSocketsCreated = false;
  136. static char displayNumStr[16];
  137. static void
  138. vfbInitializePixmapDepths(void)
  139. {
  140. int i;
  141. vfbPixmapDepths[1] = TRUE; /* always need bitmaps */
  142. for (i = 2; i <= 32; i++)
  143. vfbPixmapDepths[i] = FALSE;
  144. }
  145. static void
  146. vfbInitializeDefaultScreens(void)
  147. {
  148. int i;
  149. for (i = 0; i < MAXSCREENS; i++)
  150. {
  151. vfbScreens[i].scrnum = i;
  152. vfbScreens[i].blackPixel = VFB_DEFAULT_BLACKPIXEL;
  153. vfbScreens[i].whitePixel = VFB_DEFAULT_WHITEPIXEL;
  154. vfbScreens[i].lineBias = VFB_DEFAULT_LINEBIAS;
  155. vfbScreens[i].fb.width = VFB_DEFAULT_WIDTH;
  156. vfbScreens[i].fb.height = VFB_DEFAULT_HEIGHT;
  157. vfbScreens[i].fb.pfbMemory = NULL;
  158. vfbScreens[i].fb.depth = VFB_DEFAULT_DEPTH;
  159. vfbScreens[i].pixelFormatDefined = FALSE;
  160. }
  161. vfbNumScreens = 1;
  162. }
  163. static int
  164. vfbBitsPerPixel(int depth)
  165. {
  166. if (depth == 1) return 1;
  167. else if (depth <= 8) return 8;
  168. else if (depth <= 16) return 16;
  169. else return 32;
  170. }
  171. static void vfbFreeFramebufferMemory(vfbFramebufferInfoPtr pfb);
  172. extern "C" {
  173. void ddxGiveUp()
  174. {
  175. int i;
  176. /* clean up the framebuffers */
  177. for (i = 0; i < vfbNumScreens; i++)
  178. vfbFreeFramebufferMemory(&vfbScreens[i].fb);
  179. }
  180. void
  181. AbortDDX()
  182. {
  183. ddxGiveUp();
  184. }
  185. #ifdef __DARWIN__
  186. void
  187. DarwinHandleGUI(int argc, char *argv[])
  188. {
  189. }
  190. void GlxExtensionInit();
  191. void GlxWrapInitVisuals(void *procPtr);
  192. void
  193. DarwinGlxExtensionInit()
  194. {
  195. GlxExtensionInit();
  196. }
  197. void
  198. DarwinGlxWrapInitVisuals(
  199. void *procPtr)
  200. {
  201. GlxWrapInitVisuals(procPtr);
  202. }
  203. #endif
  204. void
  205. OsVendorInit()
  206. {
  207. }
  208. void
  209. OsVendorFatalError()
  210. {
  211. }
  212. void ddxBeforeReset(void)
  213. {
  214. return;
  215. }
  216. void
  217. ddxUseMsg()
  218. {
  219. ErrorF("\nXvnc %s - built %s\n%s", XVNCVERSION, buildtime, XVNCCOPYRIGHT);
  220. ErrorF("Underlying X server release %d, %s\n\n", VENDOR_RELEASE,
  221. VENDOR_STRING);
  222. ErrorF("-screen scrn WxHxD set screen's width, height, depth\n");
  223. ErrorF("-pixdepths list-of-int support given pixmap depths\n");
  224. #ifdef RENDER
  225. ErrorF("+/-render turn on/off RENDER extension support"
  226. "(default on)\n");
  227. #endif
  228. ErrorF("-linebias n adjust thin line pixelization\n");
  229. ErrorF("-blackpixel n pixel value for black\n");
  230. ErrorF("-whitepixel n pixel value for white\n");
  231. #ifdef HAS_SHM
  232. ErrorF("-shmem put framebuffers in shared memory\n");
  233. #endif
  234. ErrorF("-geometry WxH set screen 0's width, height\n");
  235. ErrorF("-depth D set screen 0's depth\n");
  236. ErrorF("-pixelformat fmt set pixel format (rgbNNN or bgrNNN)\n");
  237. ErrorF("-inetd has been launched from inetd\n");
  238. ErrorF("\nVNC parameters:\n");
  239. fprintf(stderr,"\n"
  240. "Parameters can be turned on with -<param> or off with -<param>=0\n"
  241. "Parameters which take a value can be specified as "
  242. "-<param> <value>\n"
  243. "Other valid forms are <param>=<value> -<param>=<value> "
  244. "--<param>=<value>\n"
  245. "Parameter names are case-insensitive. The parameters are:\n\n");
  246. rfb::Configuration::listParams(79, 14);
  247. }
  248. }
  249. /* ddxInitGlobals - called by |InitGlobals| from os/util.c */
  250. void ddxInitGlobals(void)
  251. {
  252. }
  253. static
  254. bool displayNumFree(int num)
  255. {
  256. try {
  257. network::TcpListener l(6000+num);
  258. } catch (rdr::Exception& e) {
  259. return false;
  260. }
  261. char file[256];
  262. sprintf(file, "/tmp/.X%d-lock", num);
  263. if (access(file, F_OK) == 0) return false;
  264. sprintf(file, "/tmp/.X11-unix/X%d", num);
  265. if (access(file, F_OK) == 0) return false;
  266. sprintf(file, "/usr/spool/sockets/X11/%d", num);
  267. if (access(file, F_OK) == 0) return false;
  268. return true;
  269. }
  270. int
  271. ddxProcessArgument(int argc, char *argv[], int i)
  272. {
  273. static Bool firstTime = TRUE;
  274. if (firstTime)
  275. {
  276. vfbInitializeDefaultScreens();
  277. vfbInitializePixmapDepths();
  278. firstTime = FALSE;
  279. rfb::initStdIOLoggers();
  280. rfb::LogWriter::setLogParams("*:stderr:30");
  281. }
  282. if (argv[i][0] == ':')
  283. displaySpecified = true;
  284. if (strcmp (argv[i], "-screen") == 0) /* -screen n WxHxD */
  285. {
  286. int screenNum;
  287. if (i + 2 >= argc) UseMsg();
  288. screenNum = atoi(argv[i+1]);
  289. if (screenNum < 0 || screenNum >= MAXSCREENS)
  290. {
  291. ErrorF("Invalid screen number %d\n", screenNum);
  292. UseMsg();
  293. }
  294. if (3 != sscanf(argv[i+2], "%dx%dx%d",
  295. &vfbScreens[screenNum].fb.width,
  296. &vfbScreens[screenNum].fb.height,
  297. &vfbScreens[screenNum].fb.depth))
  298. {
  299. ErrorF("Invalid screen configuration %s\n", argv[i+2]);
  300. UseMsg();
  301. }
  302. if (screenNum >= vfbNumScreens)
  303. vfbNumScreens = screenNum + 1;
  304. lastScreen = screenNum;
  305. return 3;
  306. }
  307. if (strcmp (argv[i], "-pixdepths") == 0) /* -pixdepths list-of-depth */
  308. {
  309. int depth, ret = 1;
  310. if (++i >= argc) UseMsg();
  311. while ((i < argc) && (depth = atoi(argv[i++])) != 0)
  312. {
  313. if (depth < 0 || depth > 32)
  314. {
  315. ErrorF("Invalid pixmap depth %d\n", depth);
  316. UseMsg();
  317. }
  318. vfbPixmapDepths[depth] = TRUE;
  319. ret++;
  320. }
  321. return ret;
  322. }
  323. if (strcmp (argv[i], "+render") == 0) /* +render */
  324. {
  325. Render = TRUE;
  326. return 1;
  327. }
  328. if (strcmp (argv[i], "-render") == 0) /* -render */
  329. {
  330. Render = FALSE;
  331. return 1;
  332. }
  333. if (strcmp (argv[i], "-blackpixel") == 0) /* -blackpixel n */
  334. {
  335. Pixel pix;
  336. if (++i >= argc) UseMsg();
  337. pix = atoi(argv[i]);
  338. if (-1 == lastScreen)
  339. {
  340. int i;
  341. for (i = 0; i < MAXSCREENS; i++)
  342. {
  343. vfbScreens[i].blackPixel = pix;
  344. }
  345. }
  346. else
  347. {
  348. vfbScreens[lastScreen].blackPixel = pix;
  349. }
  350. return 2;
  351. }
  352. if (strcmp (argv[i], "-whitepixel") == 0) /* -whitepixel n */
  353. {
  354. Pixel pix;
  355. if (++i >= argc) UseMsg();
  356. pix = atoi(argv[i]);
  357. if (-1 == lastScreen)
  358. {
  359. int i;
  360. for (i = 0; i < MAXSCREENS; i++)
  361. {
  362. vfbScreens[i].whitePixel = pix;
  363. }
  364. }
  365. else
  366. {
  367. vfbScreens[lastScreen].whitePixel = pix;
  368. }
  369. return 2;
  370. }
  371. if (strcmp (argv[i], "-linebias") == 0) /* -linebias n */
  372. {
  373. unsigned int linebias;
  374. if (++i >= argc) UseMsg();
  375. linebias = atoi(argv[i]);
  376. if (-1 == lastScreen)
  377. {
  378. int i;
  379. for (i = 0; i < MAXSCREENS; i++)
  380. {
  381. vfbScreens[i].lineBias = linebias;
  382. }
  383. }
  384. else
  385. {
  386. vfbScreens[lastScreen].lineBias = linebias;
  387. }
  388. return 2;
  389. }
  390. #ifdef HAS_SHM
  391. if (strcmp (argv[i], "-shmem") == 0) /* -shmem */
  392. {
  393. fbmemtype = SHARED_MEMORY_FB;
  394. return 1;
  395. }
  396. #endif
  397. if (strcmp(argv[i], "-geometry") == 0)
  398. {
  399. if (++i >= argc) UseMsg();
  400. if (sscanf(argv[i],"%dx%d",&vfbScreens[0].fb.width,
  401. &vfbScreens[0].fb.height) != 2) {
  402. ErrorF("Invalid geometry %s\n", argv[i]);
  403. UseMsg();
  404. }
  405. return 2;
  406. }
  407. if (strcmp(argv[i], "-depth") == 0)
  408. {
  409. if (++i >= argc) UseMsg();
  410. vfbScreens[0].fb.depth = atoi(argv[i]);
  411. return 2;
  412. }
  413. if (strcmp(argv[i], "-pixelformat") == 0)
  414. {
  415. char rgbbgr[4];
  416. int bits1, bits2, bits3;
  417. if (++i >= argc) UseMsg();
  418. if (sscanf(argv[i], "%3s%1d%1d%1d", rgbbgr,&bits1,&bits2,&bits3) < 4) {
  419. ErrorF("Invalid pixel format %s\n", argv[i]);
  420. UseMsg();
  421. }
  422. #define SET_PIXEL_FORMAT(vfbScreen) \
  423. (vfbScreen).pixelFormatDefined = TRUE; \
  424. (vfbScreen).fb.depth = bits1 + bits2 + bits3; \
  425. (vfbScreen).greenBits = bits2; \
  426. if (strcasecmp(rgbbgr, "bgr") == 0) { \
  427. (vfbScreen).rgbNotBgr = FALSE; \
  428. (vfbScreen).redBits = bits3; \
  429. (vfbScreen).blueBits = bits1; \
  430. } else if (strcasecmp(rgbbgr, "rgb") == 0) { \
  431. (vfbScreen).rgbNotBgr = TRUE; \
  432. (vfbScreen).redBits = bits1; \
  433. (vfbScreen).blueBits = bits3; \
  434. } else { \
  435. ErrorF("Invalid pixel format %s\n", argv[i]); \
  436. UseMsg(); \
  437. }
  438. if (-1 == lastScreen)
  439. {
  440. int i;
  441. for (i = 0; i < MAXSCREENS; i++)
  442. {
  443. SET_PIXEL_FORMAT(vfbScreens[i]);
  444. }
  445. }
  446. else
  447. {
  448. SET_PIXEL_FORMAT(vfbScreens[lastScreen]);
  449. }
  450. return 2;
  451. }
  452. if (strcmp(argv[i], "-inetd") == 0)
  453. {
  454. dup2(0,3);
  455. vncInetdSock = 3;
  456. close(2);
  457. if (!displaySpecified) {
  458. int port = network::TcpSocket::getSockPort(vncInetdSock);
  459. int displayNum = port - 5900;
  460. if (displayNum < 0 || displayNum > 99 || !displayNumFree(displayNum)) {
  461. for (displayNum = 1; displayNum < 100; displayNum++)
  462. if (displayNumFree(displayNum)) break;
  463. if (displayNum == 100)
  464. FatalError("Xvnc error: no free display number for -inetd");
  465. }
  466. display = displayNumStr;
  467. sprintf(displayNumStr, "%d", displayNum);
  468. }
  469. return 1;
  470. }
  471. if (rfb::Configuration::setParam(argv[i]))
  472. return 1;
  473. if (argv[i][0] == '-' && i+1 < argc) {
  474. if (rfb::Configuration::setParam(&argv[i][1], argv[i+1]))
  475. return 2;
  476. }
  477. return 0;
  478. }
  479. #ifdef DDXTIME /* from ServerOSDefines */
  480. CARD32
  481. GetTimeInMillis()
  482. {
  483. struct timeval tp;
  484. X_GETTIMEOFDAY(&tp);
  485. return(tp.tv_sec * 1000) + (tp.tv_usec / 1000);
  486. }
  487. #endif
  488. static ColormapPtr InstalledMaps[MAXSCREENS];
  489. static int
  490. vfbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
  491. {
  492. /* By the time we are processing requests, we can guarantee that there
  493. * is always a colormap installed */
  494. *pmaps = InstalledMaps[pScreen->myNum]->mid;
  495. return (1);
  496. }
  497. static void
  498. vfbInstallColormap(ColormapPtr pmap)
  499. {
  500. int index = pmap->pScreen->myNum;
  501. ColormapPtr oldpmap = InstalledMaps[index];
  502. if (pmap != oldpmap)
  503. {
  504. int entries;
  505. VisualPtr pVisual;
  506. Pixel * ppix;
  507. xrgb * prgb;
  508. xColorItem *defs;
  509. int i;
  510. if(oldpmap != (ColormapPtr)None)
  511. WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
  512. /* Install pmap */
  513. InstalledMaps[index] = pmap;
  514. WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
  515. entries = pmap->pVisual->ColormapEntries;
  516. pVisual = pmap->pVisual;
  517. ppix = (Pixel *)xalloc(entries * sizeof(Pixel));
  518. prgb = (xrgb *)xalloc(entries * sizeof(xrgb));
  519. defs = (xColorItem *)xalloc(entries * sizeof(xColorItem));
  520. for (i = 0; i < entries; i++) ppix[i] = i;
  521. /* XXX truecolor */
  522. QueryColors(pmap, entries, ppix, prgb);
  523. for (i = 0; i < entries; i++) { /* convert xrgbs to xColorItems */
  524. defs[i].pixel = ppix[i] & 0xff; /* change pixel to index */
  525. defs[i].red = prgb[i].red;
  526. defs[i].green = prgb[i].green;
  527. defs[i].blue = prgb[i].blue;
  528. defs[i].flags = DoRed|DoGreen|DoBlue;
  529. }
  530. (*pmap->pScreen->StoreColors)(pmap, entries, defs);
  531. xfree(ppix);
  532. xfree(prgb);
  533. xfree(defs);
  534. }
  535. }
  536. static void
  537. vfbUninstallColormap(ColormapPtr pmap)
  538. {
  539. ColormapPtr curpmap = InstalledMaps[pmap->pScreen->myNum];
  540. if(pmap == curpmap)
  541. {
  542. if (pmap->mid != pmap->pScreen->defColormap)
  543. {
  544. curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap,
  545. RT_COLORMAP);
  546. (*pmap->pScreen->InstallColormap)(curpmap);
  547. }
  548. }
  549. }
  550. static Bool
  551. vfbSaveScreen(ScreenPtr pScreen, int on)
  552. {
  553. return TRUE;
  554. }
  555. #ifdef HAS_SHM
  556. static void
  557. vfbAllocateSharedMemoryFramebuffer(vfbFramebufferInfoPtr pfb)
  558. {
  559. /* create the shared memory segment */
  560. pfb->shmid = shmget(IPC_PRIVATE, pfb->sizeInBytes, IPC_CREAT|0777);
  561. if (pfb->shmid < 0) {
  562. perror("shmget");
  563. ErrorF("shmget %d bytes failed, errno %d", pfb->sizeInBytes, errno);
  564. return;
  565. }
  566. /* try to attach it */
  567. pfb->pfbMemory = shmat(pfb->shmid, 0, 0);
  568. if (-1 == (long)pfb->pfbMemory) {
  569. perror("shmat");
  570. ErrorF("shmat failed, errno %d", errno);
  571. pfb->pfbMemory = NULL;
  572. return;
  573. }
  574. }
  575. #endif /* HAS_SHM */
  576. static void *
  577. vfbAllocateFramebufferMemory(vfbFramebufferInfoPtr pfb)
  578. {
  579. if (pfb->pfbMemory != NULL)
  580. return pfb->pfbMemory; /* already done */
  581. /* Compute memory layout */
  582. pfb->paddedBytesWidth = PixmapBytePad(pfb->width, pfb->depth);
  583. pfb->bitsPerPixel = vfbBitsPerPixel(pfb->depth);
  584. pfb->paddedWidth = pfb->paddedBytesWidth * 8 / pfb->bitsPerPixel;
  585. pfb->sizeInBytes = pfb->paddedBytesWidth * pfb->height;
  586. /* And allocate buffer */
  587. switch (fbmemtype) {
  588. #ifdef HAS_SHM
  589. case SHARED_MEMORY_FB:
  590. vfbAllocateSharedMemoryFramebuffer(pfb);
  591. break;
  592. #else
  593. case SHARED_MEMORY_FB:
  594. break;
  595. #endif
  596. case NORMAL_MEMORY_FB:
  597. pfb->pfbMemory = Xalloc(pfb->sizeInBytes);
  598. break;
  599. }
  600. /* This will be NULL if any of the above failed */
  601. return pfb->pfbMemory;
  602. }
  603. static void
  604. vfbFreeFramebufferMemory(vfbFramebufferInfoPtr pfb)
  605. {
  606. if ((pfb == NULL) || (pfb->pfbMemory == NULL))
  607. return;
  608. switch (fbmemtype) {
  609. #ifdef HAS_SHM
  610. case SHARED_MEMORY_FB:
  611. if (-1 == shmdt(pfb->pfbMemory)) {
  612. perror("shmdt");
  613. ErrorF("shmdt failed, errno %d", errno);
  614. }
  615. break;
  616. #else /* HAS_SHM */
  617. case SHARED_MEMORY_FB:
  618. break;
  619. #endif /* HAS_SHM */
  620. case NORMAL_MEMORY_FB:
  621. Xfree(pfb->pfbMemory);
  622. break;
  623. }
  624. pfb->pfbMemory = NULL;
  625. }
  626. static Bool
  627. vfbCursorOffScreen (ScreenPtr *ppScreen, int *x, int *y)
  628. {
  629. return FALSE;
  630. }
  631. static void
  632. vfbCrossScreen (ScreenPtr pScreen, Bool entering)
  633. {
  634. }
  635. static Bool vfbRealizeCursor(
  636. #if XORG >= 16
  637. DeviceIntPtr pDev,
  638. #endif
  639. ScreenPtr pScreen, CursorPtr pCursor) {
  640. return TRUE;
  641. }
  642. static Bool vfbUnrealizeCursor(
  643. #if XORG >= 16
  644. DeviceIntPtr pDev,
  645. #endif
  646. ScreenPtr pScreen, CursorPtr pCursor) {
  647. return TRUE;
  648. }
  649. static void vfbSetCursor(
  650. #if XORG >= 16
  651. DeviceIntPtr pDev,
  652. #endif
  653. ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
  654. {
  655. }
  656. static void vfbMoveCursor(
  657. #if XORG >= 16
  658. DeviceIntPtr pDev,
  659. #endif
  660. ScreenPtr pScreen, int x, int y)
  661. {
  662. }
  663. #if XORG >= 16
  664. static Bool
  665. vfbDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
  666. {
  667. return TRUE;
  668. }
  669. static void
  670. vfbDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
  671. {
  672. }
  673. #endif
  674. static miPointerSpriteFuncRec vfbPointerSpriteFuncs = {
  675. vfbRealizeCursor,
  676. vfbUnrealizeCursor,
  677. vfbSetCursor,
  678. vfbMoveCursor
  679. #if XORG >= 16
  680. , vfbDeviceCursorInitialize,
  681. vfbDeviceCursorCleanup
  682. #endif
  683. };
  684. static miPointerScreenFuncRec vfbPointerCursorFuncs = {
  685. vfbCursorOffScreen,
  686. vfbCrossScreen,
  687. miPointerWarpCursor
  688. };
  689. #ifdef RANDR
  690. static Bool vncRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
  691. {
  692. vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
  693. Bool ret, gotCurrent = FALSE;
  694. int i;
  695. const int widths[] = { 1920, 1920, 1600, 1680, 1400, 1360, 1280, 1280, 1280, 1280, 1024, 800, 640 };
  696. const int heights[] = { 1200, 1080, 1200, 1050, 1050, 768, 1024, 960, 800, 720, 768, 600, 480 };
  697. for (i = 0;i < sizeof(widths)/sizeof(*widths);i++) {
  698. RRScreenSizePtr pSize;
  699. pSize = RRRegisterSize(pScreen, widths[i], heights[i],
  700. pScreen->mmWidth, pScreen->mmHeight);
  701. if (!pSize)
  702. return FALSE;
  703. ret = RRRegisterRate(pScreen, pSize, 60);
  704. if (!ret)
  705. return FALSE;
  706. if ((widths[i] == pScreen->width) && (heights[i] == pScreen->height)) {
  707. RRSetCurrentConfig(pScreen, RR_Rotate_0, 60, pSize);
  708. gotCurrent = TRUE;
  709. }
  710. }
  711. if (!gotCurrent) {
  712. RRScreenSizePtr pSize;
  713. pSize = RRRegisterSize(pScreen, pScreen->width, pScreen->height,
  714. pScreen->mmWidth, pScreen->mmHeight);
  715. if (!pSize)
  716. return FALSE;
  717. RRRegisterRate(pScreen, pSize, 60);
  718. RRSetCurrentConfig(pScreen, RR_Rotate_0, 60, pSize);
  719. }
  720. *rotations = RR_Rotate_0;
  721. return TRUE;
  722. }
  723. /* from hw/xfree86/common/xf86Helper.c */
  724. #include "mivalidate.h"
  725. static void
  726. xf86SetRootClip (ScreenPtr pScreen, Bool enable)
  727. {
  728. WindowPtr pWin = WindowTable[pScreen->myNum];
  729. WindowPtr pChild;
  730. Bool WasViewable = (Bool)(pWin->viewable);
  731. Bool anyMarked = FALSE;
  732. RegionPtr pOldClip = NULL, bsExposed;
  733. #ifdef DO_SAVE_UNDERS
  734. Bool dosave = FALSE;
  735. #endif
  736. WindowPtr pLayerWin;
  737. BoxRec box;
  738. if (WasViewable)
  739. {
  740. for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
  741. {
  742. (void) (*pScreen->MarkOverlappedWindows)(pChild,
  743. pChild,
  744. &pLayerWin);
  745. }
  746. (*pScreen->MarkWindow) (pWin);
  747. anyMarked = TRUE;
  748. if (pWin->valdata)
  749. {
  750. if (HasBorder (pWin))
  751. {
  752. RegionPtr borderVisible;
  753. borderVisible = REGION_CREATE(pScreen, NullBox, 1);
  754. REGION_SUBTRACT(pScreen, borderVisible,
  755. &pWin->borderClip, &pWin->winSize);
  756. pWin->valdata->before.borderVisible = borderVisible;
  757. }
  758. pWin->valdata->before.resized = TRUE;
  759. }
  760. }
  761. /*
  762. * Use REGION_BREAK to avoid optimizations in ValidateTree
  763. * that assume the root borderClip can't change well, normally
  764. * it doesn't...)
  765. */
  766. if (enable)
  767. {
  768. box.x1 = 0;
  769. box.y1 = 0;
  770. box.x2 = pScreen->width;
  771. box.y2 = pScreen->height;
  772. REGION_INIT (pScreen, &pWin->winSize, &box, 1);
  773. REGION_INIT (pScreen, &pWin->borderSize, &box, 1);
  774. if (WasViewable)
  775. REGION_RESET(pScreen, &pWin->borderClip, &box);
  776. pWin->drawable.width = pScreen->width;
  777. pWin->drawable.height = pScreen->height;
  778. REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
  779. }
  780. else
  781. {
  782. REGION_EMPTY(pScreen, &pWin->borderClip);
  783. REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
  784. }
  785. ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
  786. if (WasViewable)
  787. {
  788. if (pWin->backStorage)
  789. {
  790. pOldClip = REGION_CREATE(pScreen, NullBox, 1);
  791. REGION_COPY(pScreen, pOldClip, &pWin->clipList);
  792. }
  793. if (pWin->firstChild)
  794. {
  795. anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
  796. pWin->firstChild,
  797. (WindowPtr *)NULL);
  798. }
  799. else
  800. {
  801. (*pScreen->MarkWindow) (pWin);
  802. anyMarked = TRUE;
  803. }
  804. #ifdef DO_SAVE_UNDERS
  805. if (DO_SAVE_UNDERS(pWin))
  806. {
  807. dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
  808. }
  809. #endif /* DO_SAVE_UNDERS */
  810. if (anyMarked)
  811. (*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
  812. }
  813. if (pWin->backStorage &&
  814. ((pWin->backingStore == Always) || WasViewable))
  815. {
  816. if (!WasViewable)
  817. pOldClip = &pWin->clipList; /* a convenient empty region */
  818. bsExposed = (*pScreen->TranslateBackingStore)
  819. (pWin, 0, 0, pOldClip,
  820. pWin->drawable.x, pWin->drawable.y);
  821. if (WasViewable)
  822. REGION_DESTROY(pScreen, pOldClip);
  823. if (bsExposed)
  824. {
  825. RegionPtr valExposed = NullRegion;
  826. if (pWin->valdata)
  827. valExposed = &pWin->valdata->after.exposed;
  828. (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
  829. if (valExposed)
  830. REGION_EMPTY(pScreen, valExposed);
  831. REGION_DESTROY(pScreen, bsExposed);
  832. }
  833. }
  834. if (WasViewable)
  835. {
  836. if (anyMarked)
  837. (*pScreen->HandleExposures)(pWin);
  838. #ifdef DO_SAVE_UNDERS
  839. if (dosave)
  840. (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
  841. #endif /* DO_SAVE_UNDERS */
  842. if (anyMarked && pScreen->PostValidateTree)
  843. (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther);
  844. }
  845. if (pWin->realized)
  846. WindowsRestructured ();
  847. FlushAllOutput ();
  848. }
  849. static Bool vncRandRSetConfig (ScreenPtr pScreen, Rotation rotation,
  850. int rate, RRScreenSizePtr pSize)
  851. {
  852. vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
  853. vfbFramebufferInfo fb;
  854. PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
  855. void *pbits;
  856. Bool ret;
  857. int oldwidth, oldheight, oldmmWidth, oldmmHeight;
  858. int dpix, dpiy;
  859. /* Prevent updates while we fiddle */
  860. xf86SetRootClip(pScreen, FALSE);
  861. /* Store current state in case we fail */
  862. oldwidth = pScreen->width;
  863. oldheight = pScreen->height;
  864. oldmmWidth = pScreen->mmWidth;
  865. oldmmHeight = pScreen->mmHeight;
  866. /* Compute the current DPI (for use later) */
  867. dpix = (pScreen->width * 254 + pScreen->mmWidth * 5) / (pScreen->mmWidth * 10);
  868. dpiy = (pScreen->height * 254 + pScreen->mmHeight * 5) / (pScreen->mmHeight * 10);
  869. /* Then set the new dimensions */
  870. pScreen->width = pSize->width;
  871. pScreen->height = pSize->height;
  872. /* Try to keep the same DPI as we do not have a physical screen */
  873. pScreen->mmWidth = (pScreen->width * 254 + dpix * 5) / (dpix * 10);
  874. pScreen->mmHeight = (pScreen->height * 254 + dpiy * 5) / (dpiy * 10);
  875. /* Allocate a new framebuffer */
  876. memset(&fb, 0, sizeof(vfbFramebufferInfo));
  877. fb.width = pScreen->width;
  878. fb.height = pScreen->height;
  879. fb.depth = pvfb->fb.depth;
  880. pbits = vfbAllocateFramebufferMemory(&fb);
  881. if (!pbits) {
  882. /* Allocation failed. Restore old state */
  883. pScreen->width = oldwidth;
  884. pScreen->height = oldheight;
  885. pScreen->mmWidth = oldmmWidth;
  886. pScreen->mmHeight = oldmmHeight;
  887. xf86SetRootClip(pScreen, TRUE);
  888. return FALSE;
  889. }
  890. /* Update root pixmap with the new dimensions and buffer */
  891. ret = pScreen->ModifyPixmapHeader(rootPixmap, fb.width, fb.height,
  892. -1, -1, fb.paddedBytesWidth, pbits);
  893. if (!ret) {
  894. /* Update failed. Free the new framebuffer and restore old state */
  895. vfbFreeFramebufferMemory(&fb);
  896. pScreen->width = oldwidth;
  897. pScreen->height = oldheight;
  898. pScreen->mmWidth = oldmmWidth;
  899. pScreen->mmHeight = oldmmHeight;
  900. xf86SetRootClip(pScreen, TRUE);
  901. return FALSE;
  902. }
  903. /* Free the old framebuffer and keep the info about the new one */
  904. vfbFreeFramebufferMemory(&pvfb->fb);
  905. memcpy(&pvfb->fb, &fb, sizeof(vfbFramebufferInfo));
  906. /* Let VNC get the new framebuffer (actual update is in vncHooks.cc) */
  907. vncFbptr[pScreen->myNum] = pbits;
  908. vncFbstride[pScreen->myNum] = fb.paddedWidth;
  909. /* Restore ability to update screen, now with new dimensions */
  910. xf86SetRootClip(pScreen, TRUE);
  911. return TRUE;
  912. }
  913. #endif
  914. static Bool
  915. vfbCloseScreen(int index, ScreenPtr pScreen)
  916. {
  917. vfbScreenInfoPtr pvfb = &vfbScreens[index];
  918. int i;
  919. pScreen->CloseScreen = pvfb->closeScreen;
  920. /*
  921. * XXX probably lots of stuff to clean. For now,
  922. * clear InstalledMaps[] so that server reset works correctly.
  923. */
  924. for (i = 0; i < MAXSCREENS; i++)
  925. InstalledMaps[i] = NULL;
  926. return pScreen->CloseScreen(index, pScreen);
  927. }
  928. static Bool
  929. vfbScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
  930. {
  931. vfbScreenInfoPtr pvfb = &vfbScreens[index];
  932. int dpi = 100;
  933. int ret;
  934. void *pbits;
  935. if (monitorResolution) dpi = monitorResolution;
  936. pbits = vfbAllocateFramebufferMemory(&pvfb->fb);
  937. if (!pbits) return FALSE;
  938. vncFbptr[index] = pbits;
  939. vncFbstride[index] = pvfb->fb.paddedWidth;
  940. miSetPixmapDepths();
  941. switch (pvfb->fb.depth) {
  942. case 8:
  943. miSetVisualTypesAndMasks (8,
  944. ((1 << StaticGray) |
  945. (1 << GrayScale) |
  946. (1 << StaticColor) |
  947. (1 << PseudoColor) |
  948. (1 << TrueColor) |
  949. (1 << DirectColor)),
  950. 8, PseudoColor, 0, 0, 0);
  951. break;
  952. case 16:
  953. miSetVisualTypesAndMasks (16,
  954. ((1 << TrueColor) |
  955. (1 << DirectColor)),
  956. 8, TrueColor, 0xf800, 0x07e0, 0x001f);
  957. break;
  958. case 24:
  959. miSetVisualTypesAndMasks (24,
  960. ((1 << TrueColor) |
  961. (1 << DirectColor)),
  962. 8, TrueColor, 0xff0000, 0x00ff00, 0x0000ff);
  963. break;
  964. case 32:
  965. miSetVisualTypesAndMasks (32,
  966. ((1 << TrueColor) |
  967. (1 << DirectColor)),
  968. 8, TrueColor, 0xff000000, 0x00ff0000, 0x0000ff00);
  969. break;
  970. default:
  971. return FALSE;
  972. }
  973. ret = fbScreenInit(pScreen, pbits, pvfb->fb.width, pvfb->fb.height,
  974. dpi, dpi, pvfb->fb.paddedWidth, pvfb->fb.bitsPerPixel);
  975. #ifdef RENDER
  976. if (ret && Render)
  977. ret = fbPictureInit (pScreen, 0, 0);
  978. #endif
  979. if (!ret) return FALSE;
  980. miInitializeBackingStore(pScreen);
  981. /*
  982. * Circumvent the backing store that was just initialised. This amounts
  983. * to a truely bizarre way of initialising SaveDoomedAreas and friends.
  984. */
  985. pScreen->InstallColormap = vfbInstallColormap;
  986. pScreen->UninstallColormap = vfbUninstallColormap;
  987. pScreen->ListInstalledColormaps = vfbListInstalledColormaps;
  988. pScreen->SaveScreen = vfbSaveScreen;
  989. miPointerInitialize(pScreen, &vfbPointerSpriteFuncs, &vfbPointerCursorFuncs,
  990. FALSE);
  991. pScreen->blackPixel = pvfb->blackPixel;
  992. pScreen->whitePixel = pvfb->whitePixel;
  993. if (!pvfb->pixelFormatDefined && pvfb->fb.depth == 16) {
  994. pvfb->pixelFormatDefined = TRUE;
  995. pvfb->rgbNotBgr = TRUE;
  996. pvfb->blueBits = pvfb->redBits = 5;
  997. pvfb->greenBits = 6;
  998. }
  999. if (pvfb->pixelFormatDefined) {
  1000. VisualPtr vis = pScreen->visuals;
  1001. for (int i = 0; i < pScreen->numVisuals; i++) {
  1002. if (pvfb->rgbNotBgr) {
  1003. vis->offsetBlue = 0;
  1004. vis->blueMask = (1 << pvfb->blueBits) - 1;
  1005. vis->offsetGreen = pvfb->blueBits;
  1006. vis->greenMask = ((1 << pvfb->greenBits) - 1) << vis->offsetGreen;
  1007. vis->offsetRed = vis->offsetGreen + pvfb->greenBits;
  1008. vis->redMask = ((1 << pvfb->redBits) - 1) << vis->offsetRed;
  1009. } else {
  1010. vis->offsetRed = 0;
  1011. vis->redMask = (1 << pvfb->redBits) - 1;
  1012. vis->offsetGreen = pvfb->redBits;
  1013. vis->greenMask = ((1 << pvfb->greenBits) - 1) << vis->offsetGreen;
  1014. vis->offsetBlue = vis->offsetGreen + pvfb->greenBits;
  1015. vis->blueMask = ((1 << pvfb->blueBits) - 1) << vis->offsetBlue;
  1016. }
  1017. vis++;
  1018. }
  1019. }
  1020. ret = fbCreateDefColormap(pScreen);
  1021. if (!ret) return FALSE;
  1022. miSetZeroLineBias(pScreen, pvfb->lineBias);
  1023. pvfb->closeScreen = pScreen->CloseScreen;
  1024. pScreen->CloseScreen = vfbCloseScreen;
  1025. #ifdef RANDR
  1026. rrScrPrivPtr rp;
  1027. ret = RRScreenInit(pScreen);
  1028. if (!ret) return FALSE;
  1029. rp = rrGetScrPriv(pScreen);
  1030. rp->rrGetInfo = vncRandRGetInfo;
  1031. rp->rrSetConfig = vncRandRSetConfig;
  1032. #endif
  1033. return TRUE;
  1034. } /* end vfbScreenInit */
  1035. static void vfbClientStateChange(CallbackListPtr*, pointer, pointer) {
  1036. dispatchException &= ~DE_RESET;
  1037. }
  1038. void
  1039. InitOutput(ScreenInfo *screenInfo, int argc, char **argv)
  1040. {
  1041. ErrorF("\nXvnc %s - built %s\n%s", XVNCVERSION, buildtime, XVNCCOPYRIGHT);
  1042. ErrorF("Underlying X server release %d, %s\n\n", VENDOR_RELEASE,
  1043. VENDOR_STRING);
  1044. int i;
  1045. int NumFormats = 0;
  1046. /* initialize pixmap formats */
  1047. /* must have a pixmap depth to match every screen depth */
  1048. for (i = 0; i < vfbNumScreens; i++)
  1049. {
  1050. vfbPixmapDepths[vfbScreens[i].fb.depth] = TRUE;
  1051. }
  1052. /* RENDER needs a good set of pixmaps. */
  1053. if (Render) {
  1054. vfbPixmapDepths[1] = TRUE;
  1055. vfbPixmapDepths[4] = TRUE;
  1056. vfbPixmapDepths[8] = TRUE;
  1057. /* vfbPixmapDepths[15] = TRUE; */
  1058. vfbPixmapDepths[16] = TRUE;
  1059. vfbPixmapDepths[24] = TRUE;
  1060. vfbPixmapDepths[32] = TRUE;
  1061. }
  1062. for (i = 1; i <= 32; i++)
  1063. {
  1064. if (vfbPixmapDepths[i])
  1065. {
  1066. if (NumFormats >= MAXFORMATS)
  1067. FatalError ("MAXFORMATS is too small for this server\n");
  1068. screenInfo->formats[NumFormats].depth = i;
  1069. screenInfo->formats[NumFormats].bitsPerPixel = vfbBitsPerPixel(i);
  1070. screenInfo->formats[NumFormats].scanlinePad = BITMAP_SCANLINE_PAD;
  1071. NumFormats++;
  1072. }
  1073. }
  1074. screenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
  1075. screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
  1076. screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
  1077. screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
  1078. screenInfo->numPixmapFormats = NumFormats;
  1079. /* initialize screens */
  1080. for (i = 0; i < vfbNumScreens; i++)
  1081. {
  1082. if (-1 == AddScreen(vfbScreenInit, argc, argv))
  1083. {
  1084. FatalError("Couldn't add screen %d", i);
  1085. }
  1086. }
  1087. if (!AddCallback(&ClientStateCallback, vfbClientStateChange, 0)) {
  1088. FatalError("AddCallback failed\n");
  1089. }
  1090. } /* end InitOutput */
  1091. /* this is just to get the server to link on AIX */
  1092. #ifdef AIXV3
  1093. int SelectWaitTime = 10000; /* usec */
  1094. #endif
  1095. void DDXRingBell(int percent, int pitch, int duration)
  1096. {
  1097. if (percent > 0)
  1098. vncBell();
  1099. }
  1100. Bool LegalModifier(unsigned int key, DeviceIntPtr pDev)
  1101. {
  1102. return TRUE;
  1103. }
  1104. void ProcessInputEvents()
  1105. {
  1106. mieqProcessInputEvents();
  1107. #if XORG == 15
  1108. miPointerUpdate();
  1109. #endif
  1110. }
  1111. // InitInput is called after InitExtensions, so we're guaranteed that
  1112. // vncExtensionInit() has already been called.
  1113. void InitInput(int argc, char *argv[])
  1114. {
  1115. mieqInit ();
  1116. }