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.c 43KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801
  1. /* Copyright (c) 1993 X Consortium
  2. Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
  3. Copyright 2009-2015 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 "vncExtInit.h"
  29. #include "RFBGlue.h"
  30. #include "XorgGlue.h"
  31. #include "xorg-version.h"
  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. #if XORG < 114
  45. #include "mibstore.h"
  46. #endif
  47. #include "colormapst.h"
  48. #include "gcstruct.h"
  49. #include "input.h"
  50. #include "mipointer.h"
  51. #include "micmap.h"
  52. #include <sys/types.h>
  53. #include <sys/stat.h>
  54. #include <errno.h>
  55. #ifndef WIN32
  56. #include <sys/param.h>
  57. #endif
  58. #include <X11/XWDFile.h>
  59. #ifdef HAS_SHM
  60. #include <sys/ipc.h>
  61. #include <sys/shm.h>
  62. #endif /* HAS_SHM */
  63. #include "dix.h"
  64. #include "os.h"
  65. #include "miline.h"
  66. #include "inputstr.h"
  67. #ifdef RANDR
  68. #include "randrstr.h"
  69. #endif /* RANDR */
  70. #ifdef DPMSExtension
  71. #include "dpmsproc.h"
  72. #endif
  73. #include <X11/keysym.h>
  74. extern char buildtime[];
  75. #undef VENDOR_RELEASE
  76. #undef VENDOR_STRING
  77. #include "version-config.h"
  78. #include "site.h"
  79. #define XVNCVERSION "TigerVNC 1.8.80"
  80. #define XVNCCOPYRIGHT ("Copyright (C) 1999-2018 TigerVNC Team and many others (see README.rst)\n" \
  81. "See http://www.tigervnc.org for information on TigerVNC.\n")
  82. #define VFB_DEFAULT_WIDTH 1024
  83. #define VFB_DEFAULT_HEIGHT 768
  84. #define VFB_DEFAULT_DEPTH 24
  85. #define VFB_DEFAULT_WHITEPIXEL 0xffffffff
  86. #define VFB_DEFAULT_BLACKPIXEL 0
  87. #define VFB_DEFAULT_LINEBIAS 0
  88. #define XWD_WINDOW_NAME_LEN 60
  89. typedef struct
  90. {
  91. int width;
  92. int height;
  93. int depth;
  94. /* Computed when allocated */
  95. int paddedBytesWidth;
  96. int paddedWidth;
  97. int bitsPerPixel;
  98. /* Private */
  99. int sizeInBytes;
  100. void *pfbMemory;
  101. #ifdef HAS_SHM
  102. int shmid;
  103. #endif
  104. } vfbFramebufferInfo, *vfbFramebufferInfoPtr;
  105. typedef struct
  106. {
  107. int scrnum;
  108. Pixel blackPixel;
  109. Pixel whitePixel;
  110. unsigned int lineBias;
  111. CloseScreenProcPtr closeScreen;
  112. vfbFramebufferInfo fb;
  113. Bool pixelFormatDefined;
  114. Bool rgbNotBgr;
  115. int redBits, greenBits, blueBits;
  116. } vfbScreenInfo, *vfbScreenInfoPtr;
  117. static int vfbNumScreens;
  118. static vfbScreenInfo vfbScreens[MAXSCREENS];
  119. static Bool vfbPixmapDepths[33];
  120. typedef enum { NORMAL_MEMORY_FB, SHARED_MEMORY_FB } fbMemType;
  121. static fbMemType fbmemtype = NORMAL_MEMORY_FB;
  122. static int lastScreen = -1;
  123. static Bool Render = TRUE;
  124. static Bool displaySpecified = FALSE;
  125. static char displayNumStr[16];
  126. static int vncVerbose = DEFAULT_LOG_VERBOSITY;
  127. static void
  128. vncPrintBanner(void)
  129. {
  130. ErrorF("\nXvnc %s - built %s\n%s", XVNCVERSION, buildtime, XVNCCOPYRIGHT);
  131. ErrorF("Underlying X server release %d, %s\n\n", VENDOR_RELEASE,
  132. VENDOR_STRING);
  133. }
  134. static void
  135. vfbInitializePixmapDepths(void)
  136. {
  137. int i;
  138. vfbPixmapDepths[1] = TRUE; /* always need bitmaps */
  139. for (i = 2; i <= 32; i++)
  140. vfbPixmapDepths[i] = FALSE;
  141. }
  142. static void
  143. vfbInitializeDefaultScreens(void)
  144. {
  145. int i;
  146. for (i = 0; i < MAXSCREENS; i++)
  147. {
  148. vfbScreens[i].scrnum = i;
  149. vfbScreens[i].blackPixel = VFB_DEFAULT_BLACKPIXEL;
  150. vfbScreens[i].whitePixel = VFB_DEFAULT_WHITEPIXEL;
  151. vfbScreens[i].lineBias = VFB_DEFAULT_LINEBIAS;
  152. vfbScreens[i].fb.width = VFB_DEFAULT_WIDTH;
  153. vfbScreens[i].fb.height = VFB_DEFAULT_HEIGHT;
  154. vfbScreens[i].fb.pfbMemory = NULL;
  155. vfbScreens[i].fb.depth = VFB_DEFAULT_DEPTH;
  156. vfbScreens[i].pixelFormatDefined = FALSE;
  157. }
  158. vfbNumScreens = 1;
  159. }
  160. static int
  161. vfbBitsPerPixel(int depth)
  162. {
  163. if (depth == 1) return 1;
  164. else if (depth <= 8) return 8;
  165. else if (depth <= 16) return 16;
  166. else return 32;
  167. }
  168. static void vfbFreeFramebufferMemory(vfbFramebufferInfoPtr pfb);
  169. #ifdef DPMSExtension
  170. /* Why support DPMS? Because stupid modern desktop environments
  171. such as Unity 2D on Ubuntu 11.10 crashes if DPMS is not
  172. available. (DPMSSet is called by dpms.c, but the return value
  173. is ignored.) */
  174. int DPMSSet(ClientPtr client, int level)
  175. {
  176. return Success;
  177. }
  178. Bool DPMSSupported(void)
  179. {
  180. /* Causes DPMSCapable to return false, meaning no devices are DPMS
  181. capable */
  182. return FALSE;
  183. }
  184. #endif
  185. #if XORG < 111
  186. void ddxGiveUp()
  187. #else
  188. void ddxGiveUp(enum ExitCode error)
  189. #endif
  190. {
  191. int i;
  192. /* clean up the framebuffers */
  193. for (i = 0; i < vfbNumScreens; i++)
  194. vfbFreeFramebufferMemory(&vfbScreens[i].fb);
  195. }
  196. void
  197. #if XORG < 111
  198. AbortDDX()
  199. #else
  200. AbortDDX(enum ExitCode error)
  201. #endif
  202. {
  203. #if XORG < 111
  204. ddxGiveUp();
  205. #else
  206. ddxGiveUp(error);
  207. #endif
  208. }
  209. #ifdef __DARWIN__
  210. void
  211. DarwinHandleGUI(int argc, char *argv[])
  212. {
  213. }
  214. void GlxExtensionInit();
  215. void GlxWrapInitVisuals(void *procPtr);
  216. void
  217. DarwinGlxExtensionInit()
  218. {
  219. GlxExtensionInit();
  220. }
  221. void
  222. DarwinGlxWrapInitVisuals(
  223. void *procPtr)
  224. {
  225. GlxWrapInitVisuals(procPtr);
  226. }
  227. #endif
  228. void
  229. OsVendorInit(void)
  230. {
  231. }
  232. void
  233. #if XORG < 113
  234. OsVendorFatalError()
  235. #else
  236. OsVendorFatalError(const char *f, va_list args)
  237. #endif
  238. {
  239. }
  240. #ifdef DDXBEFORERESET
  241. void ddxBeforeReset(void)
  242. {
  243. return;
  244. }
  245. #endif
  246. void ddxUseMsg(void)
  247. {
  248. vncPrintBanner();
  249. ErrorF("-screen scrn WxHxD set screen's width, height, depth\n");
  250. ErrorF("-pixdepths list-of-int support given pixmap depths\n");
  251. #ifdef RENDER
  252. ErrorF("+/-render turn on/off RENDER extension support"
  253. "(default on)\n");
  254. #endif
  255. ErrorF("-linebias n adjust thin line pixelization\n");
  256. ErrorF("-blackpixel n pixel value for black\n");
  257. ErrorF("-whitepixel n pixel value for white\n");
  258. #ifdef HAS_SHM
  259. ErrorF("-shmem put framebuffers in shared memory\n");
  260. #endif
  261. ErrorF("-geometry WxH set screen 0's width, height\n");
  262. ErrorF("-depth D set screen 0's depth\n");
  263. ErrorF("-pixelformat fmt set pixel format (rgbNNN or bgrNNN)\n");
  264. ErrorF("-inetd has been launched from inetd\n");
  265. ErrorF("-noclipboard disable clipboard settings modification via vncconfig utility\n");
  266. ErrorF("-verbose [n] verbose startup messages\n");
  267. ErrorF("-quiet minimal startup messages\n");
  268. ErrorF("-version show the server version\n");
  269. ErrorF("\nVNC parameters:\n");
  270. fprintf(stderr,"\n"
  271. "Parameters can be turned on with -<param> or off with -<param>=0\n"
  272. "Parameters which take a value can be specified as "
  273. "-<param> <value>\n"
  274. "Other valid forms are <param>=<value> -<param>=<value> "
  275. "--<param>=<value>\n"
  276. "Parameter names are case-insensitive. The parameters are:\n\n");
  277. vncListParams(79, 14);
  278. }
  279. static
  280. Bool displayNumFree(int num)
  281. {
  282. char file[256];
  283. if (vncIsTCPPortUsed(6000+num))
  284. return FALSE;
  285. sprintf(file, "/tmp/.X%d-lock", num);
  286. if (access(file, F_OK) == 0)
  287. return FALSE;
  288. sprintf(file, "/tmp/.X11-unix/X%d", num);
  289. if (access(file, F_OK) == 0)
  290. return FALSE;
  291. sprintf(file, "/usr/spool/sockets/X11/%d", num);
  292. if (access(file, F_OK) == 0)
  293. return FALSE;
  294. return TRUE;
  295. }
  296. #define fail_unless_args(_argc,_i,_n) \
  297. if (_i + _n >= _argc) \
  298. { \
  299. UseMsg(); \
  300. return 0; \
  301. }
  302. int
  303. ddxProcessArgument(int argc, char *argv[], int i)
  304. {
  305. static Bool firstTime = TRUE;
  306. if (firstTime)
  307. {
  308. /* Force -noreset as default until we properly handle resets */
  309. dispatchExceptionAtReset = 0;
  310. vfbInitializeDefaultScreens();
  311. vfbInitializePixmapDepths();
  312. firstTime = FALSE;
  313. vncInitRFB();
  314. }
  315. if (argv[i][0] == ':')
  316. displaySpecified = TRUE;
  317. if (strcmp (argv[i], "-screen") == 0) /* -screen n WxHxD */
  318. {
  319. int screenNum;
  320. fail_unless_args(argc, i, 2);
  321. screenNum = atoi(argv[i+1]);
  322. if (screenNum < 0 || screenNum >= MAXSCREENS)
  323. {
  324. ErrorF("Invalid screen number %d\n", screenNum);
  325. UseMsg();
  326. return 0;
  327. }
  328. if (3 != sscanf(argv[i+2], "%dx%dx%d",
  329. &vfbScreens[screenNum].fb.width,
  330. &vfbScreens[screenNum].fb.height,
  331. &vfbScreens[screenNum].fb.depth))
  332. {
  333. ErrorF("Invalid screen configuration %s\n", argv[i+2]);
  334. UseMsg();
  335. return 0;
  336. }
  337. if (screenNum >= vfbNumScreens)
  338. vfbNumScreens = screenNum + 1;
  339. lastScreen = screenNum;
  340. return 3;
  341. }
  342. if (strcmp (argv[i], "-pixdepths") == 0) /* -pixdepths list-of-depth */
  343. {
  344. int depth, ret = 1;
  345. fail_unless_args(argc, i, 1);
  346. ++i;
  347. while ((i < argc) && (depth = atoi(argv[i++])) != 0)
  348. {
  349. if (depth < 0 || depth > 32)
  350. {
  351. ErrorF("Invalid pixmap depth %d\n", depth);
  352. UseMsg();
  353. return 0;
  354. }
  355. vfbPixmapDepths[depth] = TRUE;
  356. ret++;
  357. }
  358. return ret;
  359. }
  360. if (strcmp (argv[i], "+render") == 0) /* +render */
  361. {
  362. Render = TRUE;
  363. return 1;
  364. }
  365. if (strcmp (argv[i], "-render") == 0) /* -render */
  366. {
  367. Render = FALSE;
  368. return 1;
  369. }
  370. if (strcmp (argv[i], "-blackpixel") == 0) /* -blackpixel n */
  371. {
  372. Pixel pix;
  373. fail_unless_args(argc, i, 1);
  374. ++i;
  375. pix = atoi(argv[i]);
  376. if (-1 == lastScreen)
  377. {
  378. int j;
  379. for (j = 0; j < MAXSCREENS; j++)
  380. {
  381. vfbScreens[j].blackPixel = pix;
  382. }
  383. }
  384. else
  385. {
  386. vfbScreens[lastScreen].blackPixel = pix;
  387. }
  388. return 2;
  389. }
  390. if (strcmp (argv[i], "-whitepixel") == 0) /* -whitepixel n */
  391. {
  392. Pixel pix;
  393. fail_unless_args(argc, i, 1);
  394. ++i;
  395. pix = atoi(argv[i]);
  396. if (-1 == lastScreen)
  397. {
  398. int j;
  399. for (j = 0; j < MAXSCREENS; j++)
  400. {
  401. vfbScreens[j].whitePixel = pix;
  402. }
  403. }
  404. else
  405. {
  406. vfbScreens[lastScreen].whitePixel = pix;
  407. }
  408. return 2;
  409. }
  410. if (strcmp (argv[i], "-linebias") == 0) /* -linebias n */
  411. {
  412. unsigned int linebias;
  413. fail_unless_args(argc, i, 1);
  414. ++i;
  415. linebias = atoi(argv[i]);
  416. if (-1 == lastScreen)
  417. {
  418. int j;
  419. for (j = 0; j < MAXSCREENS; j++)
  420. {
  421. vfbScreens[j].lineBias = linebias;
  422. }
  423. }
  424. else
  425. {
  426. vfbScreens[lastScreen].lineBias = linebias;
  427. }
  428. return 2;
  429. }
  430. #ifdef HAS_SHM
  431. if (strcmp (argv[i], "-shmem") == 0) /* -shmem */
  432. {
  433. fbmemtype = SHARED_MEMORY_FB;
  434. return 1;
  435. }
  436. #endif
  437. if (strcmp(argv[i], "-geometry") == 0)
  438. {
  439. fail_unless_args(argc, i, 1);
  440. ++i;
  441. if (sscanf(argv[i],"%dx%d",&vfbScreens[0].fb.width,
  442. &vfbScreens[0].fb.height) != 2) {
  443. ErrorF("Invalid geometry %s\n", argv[i]);
  444. UseMsg();
  445. return 0;
  446. }
  447. return 2;
  448. }
  449. if (strcmp(argv[i], "-depth") == 0)
  450. {
  451. fail_unless_args(argc, i, 1);
  452. ++i;
  453. vfbScreens[0].fb.depth = atoi(argv[i]);
  454. return 2;
  455. }
  456. if (strcmp(argv[i], "-pixelformat") == 0)
  457. {
  458. char rgbbgr[4];
  459. int bits1, bits2, bits3;
  460. fail_unless_args(argc, i, 1);
  461. ++i;
  462. if (sscanf(argv[i], "%3s%1d%1d%1d", rgbbgr,&bits1,&bits2,&bits3) < 4) {
  463. ErrorF("Invalid pixel format %s\n", argv[i]);
  464. UseMsg();
  465. return 0;
  466. }
  467. #define SET_PIXEL_FORMAT(vfbScreen) \
  468. (vfbScreen).pixelFormatDefined = TRUE; \
  469. (vfbScreen).fb.depth = bits1 + bits2 + bits3; \
  470. (vfbScreen).greenBits = bits2; \
  471. if (strcasecmp(rgbbgr, "bgr") == 0) { \
  472. (vfbScreen).rgbNotBgr = FALSE; \
  473. (vfbScreen).redBits = bits3; \
  474. (vfbScreen).blueBits = bits1; \
  475. } else if (strcasecmp(rgbbgr, "rgb") == 0) { \
  476. (vfbScreen).rgbNotBgr = TRUE; \
  477. (vfbScreen).redBits = bits1; \
  478. (vfbScreen).blueBits = bits3; \
  479. } else { \
  480. ErrorF("Invalid pixel format %s\n", argv[i]); \
  481. UseMsg(); \
  482. return 0; \
  483. }
  484. if (-1 == lastScreen)
  485. {
  486. int j;
  487. for (j = 0; j < MAXSCREENS; j++)
  488. {
  489. SET_PIXEL_FORMAT(vfbScreens[j]);
  490. }
  491. }
  492. else
  493. {
  494. SET_PIXEL_FORMAT(vfbScreens[lastScreen]);
  495. }
  496. return 2;
  497. }
  498. if (strcmp(argv[i], "-inetd") == 0)
  499. {
  500. int nullfd;
  501. dup2(0,3);
  502. vncInetdSock = 3;
  503. /* Avoid xserver >= 1.19's epoll-fd becoming fd 2 / stderr only to be
  504. replaced by /dev/null by OsInit() because the pollfd is not
  505. writable, breaking ospoll_wait(). */
  506. nullfd = open("/dev/null", O_WRONLY);
  507. dup2(nullfd, 2);
  508. close(nullfd);
  509. if (!displaySpecified) {
  510. int port = vncGetSocketPort(vncInetdSock);
  511. int displayNum = port - 5900;
  512. if (displayNum < 0 || displayNum > 99 || !displayNumFree(displayNum)) {
  513. for (displayNum = 1; displayNum < 100; displayNum++)
  514. if (displayNumFree(displayNum)) break;
  515. if (displayNum == 100)
  516. FatalError("Xvnc error: no free display number for -inetd");
  517. }
  518. display = displayNumStr;
  519. sprintf(displayNumStr, "%d", displayNum);
  520. }
  521. return 1;
  522. }
  523. if (strcmp(argv[i], "-noclipboard") == 0) {
  524. vncNoClipboard = 1;
  525. return 1;
  526. }
  527. if (!strcmp(argv[i], "-verbose")) {
  528. if (++i < argc && argv[i]) {
  529. char *end;
  530. long val;
  531. val = strtol(argv[i], &end, 0);
  532. if (*end == '\0') {
  533. vncVerbose = val;
  534. LogSetParameter(XLOG_VERBOSITY, vncVerbose);
  535. return 2;
  536. }
  537. }
  538. vncVerbose++;
  539. LogSetParameter(XLOG_VERBOSITY, vncVerbose);
  540. return 1;
  541. }
  542. if (!strcmp(argv[i], "-quiet")) {
  543. vncVerbose = -1;
  544. LogSetParameter(XLOG_VERBOSITY, vncVerbose);
  545. return 1;
  546. }
  547. if (!strcmp(argv[i], "-showconfig") || !strcmp(argv[i], "-version")) {
  548. vncPrintBanner();
  549. exit(0);
  550. }
  551. if (vncSetParamSimple(argv[i]))
  552. return 1;
  553. if (argv[i][0] == '-' && i+1 < argc) {
  554. if (vncSetParam(&argv[i][1], argv[i+1]))
  555. return 2;
  556. }
  557. return 0;
  558. }
  559. #ifdef DDXTIME /* from ServerOSDefines */
  560. CARD32
  561. GetTimeInMillis()
  562. {
  563. struct timeval tp;
  564. X_GETTIMEOFDAY(&tp);
  565. return(tp.tv_sec * 1000) + (tp.tv_usec / 1000);
  566. }
  567. #endif
  568. #if XORG < 113
  569. static ColormapPtr InstalledMaps[MAXSCREENS];
  570. #else
  571. static DevPrivateKeyRec cmapScrPrivateKeyRec;
  572. #define cmapScrPrivateKey (&cmapScrPrivateKeyRec)
  573. #define GetInstalledColormap(s) ((ColormapPtr) dixLookupPrivate(&(s)->devPrivates, cmapScrPrivateKey))
  574. #define SetInstalledColormap(s,c) (dixSetPrivate(&(s)->devPrivates, cmapScrPrivateKey, c))
  575. #endif
  576. static int
  577. vfbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
  578. {
  579. /* By the time we are processing requests, we can guarantee that there
  580. * is always a colormap installed */
  581. #if XORG < 113
  582. *pmaps = InstalledMaps[pScreen->myNum]->mid;
  583. #else
  584. *pmaps = GetInstalledColormap(pScreen)->mid;
  585. #endif
  586. return (1);
  587. }
  588. static void
  589. vfbInstallColormap(ColormapPtr pmap)
  590. {
  591. #if XORG < 113
  592. int index = pmap->pScreen->myNum;
  593. #endif
  594. ColormapPtr oldpmap;
  595. #if XORG < 113
  596. oldpmap = InstalledMaps[index];
  597. #else
  598. oldpmap = GetInstalledColormap(pmap->pScreen);
  599. #endif
  600. if (pmap != oldpmap)
  601. {
  602. int entries;
  603. VisualPtr pVisual;
  604. Pixel * ppix;
  605. xrgb * prgb;
  606. xColorItem *defs;
  607. int i;
  608. if(oldpmap != (ColormapPtr)None)
  609. WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
  610. /* Install pmap */
  611. #if XORG < 113
  612. InstalledMaps[index] = pmap;
  613. #else
  614. SetInstalledColormap(pmap->pScreen, pmap);
  615. #endif
  616. WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
  617. entries = pmap->pVisual->ColormapEntries;
  618. pVisual = pmap->pVisual;
  619. ppix = (Pixel *)calloc(entries, sizeof(Pixel));
  620. prgb = (xrgb *)calloc(entries, sizeof(xrgb));
  621. defs = (xColorItem *)calloc(entries, sizeof(xColorItem));
  622. if (!ppix || !prgb || !defs)
  623. FatalError ("Not enough memory for color map\n");
  624. for (i = 0; i < entries; i++) ppix[i] = i;
  625. /* XXX truecolor */
  626. #if XORG < 19
  627. QueryColors(pmap, entries, ppix, prgb);
  628. #else
  629. QueryColors(pmap, entries, ppix, prgb, serverClient);
  630. #endif
  631. for (i = 0; i < entries; i++) { /* convert xrgbs to xColorItems */
  632. defs[i].pixel = ppix[i] & 0xff; /* change pixel to index */
  633. defs[i].red = prgb[i].red;
  634. defs[i].green = prgb[i].green;
  635. defs[i].blue = prgb[i].blue;
  636. defs[i].flags = DoRed|DoGreen|DoBlue;
  637. }
  638. (*pmap->pScreen->StoreColors)(pmap, entries, defs);
  639. free(ppix);
  640. free(prgb);
  641. free(defs);
  642. }
  643. }
  644. static void
  645. vfbUninstallColormap(ColormapPtr pmap)
  646. {
  647. #if XORG < 113
  648. ColormapPtr curpmap = InstalledMaps[pmap->pScreen->myNum];
  649. #else
  650. ColormapPtr curpmap = GetInstalledColormap(pmap->pScreen);
  651. #endif
  652. if(pmap == curpmap)
  653. {
  654. if (pmap->mid != pmap->pScreen->defColormap)
  655. {
  656. #if XORG < 111
  657. curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap,
  658. RT_COLORMAP);
  659. #else
  660. dixLookupResourceByType((void * *) &curpmap, pmap->pScreen->defColormap,
  661. RT_COLORMAP, serverClient, DixUnknownAccess);
  662. #endif
  663. (*pmap->pScreen->InstallColormap)(curpmap);
  664. }
  665. }
  666. }
  667. static Bool
  668. vfbSaveScreen(ScreenPtr pScreen, int on)
  669. {
  670. return TRUE;
  671. }
  672. #ifdef HAS_SHM
  673. static void
  674. vfbAllocateSharedMemoryFramebuffer(vfbFramebufferInfoPtr pfb)
  675. {
  676. /* create the shared memory segment */
  677. pfb->shmid = shmget(IPC_PRIVATE, pfb->sizeInBytes, IPC_CREAT|0777);
  678. if (pfb->shmid < 0) {
  679. perror("shmget");
  680. ErrorF("shmget %d bytes failed, errno %d", pfb->sizeInBytes, errno);
  681. return;
  682. }
  683. /* try to attach it */
  684. pfb->pfbMemory = shmat(pfb->shmid, 0, 0);
  685. if (-1 == (long)pfb->pfbMemory) {
  686. perror("shmat");
  687. ErrorF("shmat failed, errno %d", errno);
  688. pfb->pfbMemory = NULL;
  689. return;
  690. }
  691. }
  692. #endif /* HAS_SHM */
  693. static void *
  694. vfbAllocateFramebufferMemory(vfbFramebufferInfoPtr pfb)
  695. {
  696. if (pfb->pfbMemory != NULL)
  697. return pfb->pfbMemory; /* already done */
  698. /* Compute memory layout */
  699. pfb->paddedBytesWidth = PixmapBytePad(pfb->width, pfb->depth);
  700. pfb->bitsPerPixel = vfbBitsPerPixel(pfb->depth);
  701. pfb->paddedWidth = pfb->paddedBytesWidth * 8 / pfb->bitsPerPixel;
  702. pfb->sizeInBytes = pfb->paddedBytesWidth * pfb->height;
  703. /* And allocate buffer */
  704. switch (fbmemtype) {
  705. #ifdef HAS_SHM
  706. case SHARED_MEMORY_FB:
  707. vfbAllocateSharedMemoryFramebuffer(pfb);
  708. break;
  709. #else
  710. case SHARED_MEMORY_FB:
  711. break;
  712. #endif
  713. case NORMAL_MEMORY_FB:
  714. pfb->pfbMemory = malloc(pfb->sizeInBytes);
  715. break;
  716. }
  717. /* This will be NULL if any of the above failed */
  718. return pfb->pfbMemory;
  719. }
  720. static void
  721. vfbFreeFramebufferMemory(vfbFramebufferInfoPtr pfb)
  722. {
  723. if ((pfb == NULL) || (pfb->pfbMemory == NULL))
  724. return;
  725. switch (fbmemtype) {
  726. #ifdef HAS_SHM
  727. case SHARED_MEMORY_FB:
  728. if (-1 == shmdt(pfb->pfbMemory)) {
  729. perror("shmdt");
  730. ErrorF("shmdt failed, errno %d", errno);
  731. }
  732. break;
  733. #else /* HAS_SHM */
  734. case SHARED_MEMORY_FB:
  735. break;
  736. #endif /* HAS_SHM */
  737. case NORMAL_MEMORY_FB:
  738. free(pfb->pfbMemory);
  739. break;
  740. }
  741. pfb->pfbMemory = NULL;
  742. }
  743. static Bool
  744. vfbCursorOffScreen (ScreenPtr *ppScreen, int *x, int *y)
  745. {
  746. int absX, absY;
  747. int i;
  748. if (screenInfo.numScreens == 1)
  749. return FALSE;
  750. if ((*x >= 0) && (*x < (*ppScreen)->width) &&
  751. (*y >= 0) && (*y < (*ppScreen)->height))
  752. return FALSE;
  753. absX = *x + (*ppScreen)->x;
  754. absY = *y + (*ppScreen)->y;
  755. for (i = 0;i < screenInfo.numScreens;i++) {
  756. ScreenPtr newScreen;
  757. newScreen = screenInfo.screens[i];
  758. if (absX < newScreen->x)
  759. continue;
  760. if (absY < newScreen->y)
  761. continue;
  762. if (absX >= (newScreen->x + newScreen->width))
  763. continue;
  764. if (absY >= (newScreen->y + newScreen->height))
  765. continue;
  766. *ppScreen = newScreen;
  767. *x = absX - newScreen->x;
  768. *y = absY - newScreen->y;
  769. return TRUE;
  770. }
  771. return FALSE;
  772. }
  773. static void
  774. vfbCrossScreen (ScreenPtr pScreen, Bool entering)
  775. {
  776. }
  777. static Bool vfbRealizeCursor(DeviceIntPtr pDev,
  778. ScreenPtr pScreen, CursorPtr pCursor)
  779. {
  780. return TRUE;
  781. }
  782. static Bool vfbUnrealizeCursor(DeviceIntPtr pDev,
  783. ScreenPtr pScreen, CursorPtr pCursor)
  784. {
  785. return TRUE;
  786. }
  787. static void vfbSetCursor(DeviceIntPtr pDev,
  788. ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
  789. {
  790. }
  791. static void vfbMoveCursor(DeviceIntPtr pDev,
  792. ScreenPtr pScreen, int x, int y)
  793. {
  794. }
  795. static Bool
  796. vfbDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
  797. {
  798. return TRUE;
  799. }
  800. static void
  801. vfbDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
  802. {
  803. }
  804. static miPointerSpriteFuncRec vfbPointerSpriteFuncs = {
  805. vfbRealizeCursor,
  806. vfbUnrealizeCursor,
  807. vfbSetCursor,
  808. vfbMoveCursor,
  809. vfbDeviceCursorInitialize,
  810. vfbDeviceCursorCleanup
  811. };
  812. static miPointerScreenFuncRec vfbPointerCursorFuncs = {
  813. vfbCursorOffScreen,
  814. vfbCrossScreen,
  815. miPointerWarpCursor
  816. };
  817. #ifdef RANDR
  818. static Bool vncRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
  819. {
  820. // We update all information right away, so there is nothing to
  821. // do here.
  822. return TRUE;
  823. }
  824. /* from hw/xfree86/common/xf86Helper.c */
  825. #include "mivalidate.h"
  826. static void
  827. xf86SetRootClip (ScreenPtr pScreen, Bool enable)
  828. {
  829. #if XORG < 19
  830. WindowPtr pWin = WindowTable[pScreen->myNum];
  831. #else
  832. WindowPtr pWin = pScreen->root;
  833. #endif
  834. WindowPtr pChild;
  835. Bool WasViewable = (Bool)(pWin->viewable);
  836. Bool anyMarked = FALSE;
  837. #if XORG < 110
  838. RegionPtr pOldClip = NULL, bsExposed;
  839. #ifdef DO_SAVE_UNDERS
  840. Bool dosave = FALSE;
  841. #endif
  842. #endif
  843. WindowPtr pLayerWin;
  844. BoxRec box;
  845. if (WasViewable)
  846. {
  847. for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
  848. {
  849. (void) (*pScreen->MarkOverlappedWindows)(pChild,
  850. pChild,
  851. &pLayerWin);
  852. }
  853. (*pScreen->MarkWindow) (pWin);
  854. anyMarked = TRUE;
  855. if (pWin->valdata)
  856. {
  857. if (HasBorder (pWin))
  858. {
  859. RegionPtr borderVisible;
  860. borderVisible = REGION_CREATE(pScreen, NullBox, 1);
  861. REGION_SUBTRACT(pScreen, borderVisible,
  862. &pWin->borderClip, &pWin->winSize);
  863. pWin->valdata->before.borderVisible = borderVisible;
  864. }
  865. pWin->valdata->before.resized = TRUE;
  866. }
  867. }
  868. /*
  869. * Use REGION_BREAK to avoid optimizations in ValidateTree
  870. * that assume the root borderClip can't change well, normally
  871. * it doesn't...)
  872. */
  873. if (enable)
  874. {
  875. box.x1 = 0;
  876. box.y1 = 0;
  877. box.x2 = pScreen->width;
  878. box.y2 = pScreen->height;
  879. REGION_INIT (pScreen, &pWin->winSize, &box, 1);
  880. REGION_INIT (pScreen, &pWin->borderSize, &box, 1);
  881. if (WasViewable)
  882. REGION_RESET(pScreen, &pWin->borderClip, &box);
  883. pWin->drawable.width = pScreen->width;
  884. pWin->drawable.height = pScreen->height;
  885. REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
  886. }
  887. else
  888. {
  889. REGION_EMPTY(pScreen, &pWin->borderClip);
  890. REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
  891. }
  892. ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
  893. if (WasViewable)
  894. {
  895. #if XORG < 110
  896. if (pWin->backStorage)
  897. {
  898. pOldClip = REGION_CREATE(pScreen, NullBox, 1);
  899. REGION_COPY(pScreen, pOldClip, &pWin->clipList);
  900. }
  901. #endif
  902. if (pWin->firstChild)
  903. {
  904. anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
  905. pWin->firstChild,
  906. (WindowPtr *)NULL);
  907. }
  908. else
  909. {
  910. (*pScreen->MarkWindow) (pWin);
  911. anyMarked = TRUE;
  912. }
  913. #if XORG < 110 && defined(DO_SAVE_UNDERS)
  914. if (DO_SAVE_UNDERS(pWin))
  915. {
  916. dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
  917. }
  918. #endif /* DO_SAVE_UNDERS */
  919. if (anyMarked)
  920. (*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
  921. }
  922. #if XORG < 110
  923. if (pWin->backStorage &&
  924. ((pWin->backingStore == Always) || WasViewable))
  925. {
  926. if (!WasViewable)
  927. pOldClip = &pWin->clipList; /* a convenient empty region */
  928. bsExposed = (*pScreen->TranslateBackingStore)
  929. (pWin, 0, 0, pOldClip,
  930. pWin->drawable.x, pWin->drawable.y);
  931. if (WasViewable)
  932. REGION_DESTROY(pScreen, pOldClip);
  933. if (bsExposed)
  934. {
  935. RegionPtr valExposed = NullRegion;
  936. if (pWin->valdata)
  937. valExposed = &pWin->valdata->after.exposed;
  938. (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
  939. if (valExposed)
  940. REGION_EMPTY(pScreen, valExposed);
  941. REGION_DESTROY(pScreen, bsExposed);
  942. }
  943. }
  944. #endif
  945. if (WasViewable)
  946. {
  947. if (anyMarked)
  948. (*pScreen->HandleExposures)(pWin);
  949. #if XORG < 110 && defined(DO_SAVE_UNDERS)
  950. if (dosave)
  951. (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
  952. #endif /* DO_SAVE_UNDERS */
  953. if (anyMarked && pScreen->PostValidateTree)
  954. (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther);
  955. }
  956. if (pWin->realized)
  957. WindowsRestructured ();
  958. FlushAllOutput ();
  959. }
  960. static Bool vncRandRCrtcSet(ScreenPtr pScreen, RRCrtcPtr crtc, RRModePtr mode,
  961. int x, int y, Rotation rotation, int num_outputs,
  962. RROutputPtr *outputs);
  963. static RRModePtr vncRandRModeGet(int width, int height);
  964. static Bool vncRandRScreenSetSize(ScreenPtr pScreen,
  965. CARD16 width, CARD16 height,
  966. CARD32 mmWidth, CARD32 mmHeight)
  967. {
  968. vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
  969. vfbFramebufferInfo fb;
  970. rrScrPrivPtr rp = rrGetScrPriv(pScreen);
  971. PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
  972. void *pbits;
  973. Bool ret;
  974. int oldwidth, oldheight, oldmmWidth, oldmmHeight;
  975. /* Prevent updates while we fiddle */
  976. xf86SetRootClip(pScreen, FALSE);
  977. /* Store current state in case we fail */
  978. oldwidth = pScreen->width;
  979. oldheight = pScreen->height;
  980. oldmmWidth = pScreen->mmWidth;
  981. oldmmHeight = pScreen->mmHeight;
  982. /* Then set the new dimensions */
  983. pScreen->width = width;
  984. pScreen->height = height;
  985. pScreen->mmWidth = mmWidth;
  986. pScreen->mmHeight = mmHeight;
  987. /* Allocate a new framebuffer */
  988. memset(&fb, 0, sizeof(vfbFramebufferInfo));
  989. fb.width = pScreen->width;
  990. fb.height = pScreen->height;
  991. fb.depth = pvfb->fb.depth;
  992. pbits = vfbAllocateFramebufferMemory(&fb);
  993. if (!pbits) {
  994. /* Allocation failed. Restore old state */
  995. pScreen->width = oldwidth;
  996. pScreen->height = oldheight;
  997. pScreen->mmWidth = oldmmWidth;
  998. pScreen->mmHeight = oldmmHeight;
  999. xf86SetRootClip(pScreen, TRUE);
  1000. return FALSE;
  1001. }
  1002. /* Update root pixmap with the new dimensions and buffer */
  1003. ret = pScreen->ModifyPixmapHeader(rootPixmap, fb.width, fb.height,
  1004. -1, -1, fb.paddedBytesWidth, pbits);
  1005. if (!ret) {
  1006. /* Update failed. Free the new framebuffer and restore old state */
  1007. vfbFreeFramebufferMemory(&fb);
  1008. pScreen->width = oldwidth;
  1009. pScreen->height = oldheight;
  1010. pScreen->mmWidth = oldmmWidth;
  1011. pScreen->mmHeight = oldmmHeight;
  1012. xf86SetRootClip(pScreen, TRUE);
  1013. return FALSE;
  1014. }
  1015. /* Free the old framebuffer and keep the info about the new one */
  1016. vfbFreeFramebufferMemory(&pvfb->fb);
  1017. memcpy(&pvfb->fb, &fb, sizeof(vfbFramebufferInfo));
  1018. /* Let VNC get the new framebuffer (actual update is in vncHooks.cc) */
  1019. vncFbptr[pScreen->myNum] = pbits;
  1020. vncFbstride[pScreen->myNum] = fb.paddedWidth;
  1021. /* Restore ability to update screen, now with new dimensions */
  1022. xf86SetRootClip(pScreen, TRUE);
  1023. /*
  1024. * Let RandR know we changed something (it doesn't assume that
  1025. * TRUE means something changed for some reason...).
  1026. */
  1027. RRScreenSizeNotify(pScreen);
  1028. /* Crop all CRTCs to the new screen */
  1029. for (int i = 0;i < rp->numCrtcs;i++) {
  1030. RRCrtcPtr crtc;
  1031. RRModePtr mode;
  1032. crtc = rp->crtcs[i];
  1033. /* Disabled? */
  1034. if (crtc->mode == NULL)
  1035. continue;
  1036. /* Fully inside? */
  1037. if ((crtc->x + crtc->mode->mode.width <= width) &&
  1038. (crtc->y + crtc->mode->mode.height <= height))
  1039. continue;
  1040. /* Fully outside? */
  1041. if ((crtc->x >= width) || (crtc->y >= height)) {
  1042. /* Disable it */
  1043. ret = vncRandRCrtcSet(pScreen, crtc, NULL,
  1044. crtc->x, crtc->y, crtc->rotation, 0, NULL);
  1045. if (!ret)
  1046. ErrorF("Warning: Unable to disable CRTC that is outside of new screen dimensions");
  1047. continue;
  1048. }
  1049. /* Just needs to be resized to a temporary mode */
  1050. mode = vncRandRModeGet(width - crtc->x, height - crtc->y);
  1051. if (mode == NULL) {
  1052. ErrorF("Warning: Unable to create custom mode for %dx%d",
  1053. width - crtc->x, height - crtc->y);
  1054. continue;
  1055. }
  1056. ret = vncRandRCrtcSet(pScreen, crtc, mode,
  1057. crtc->x, crtc->y, crtc->rotation,
  1058. crtc->numOutputs, crtc->outputs);
  1059. RRModeDestroy(mode);
  1060. if (!ret)
  1061. ErrorF("Warning: Unable to crop CRTC to new screen dimensions");
  1062. }
  1063. return TRUE;
  1064. }
  1065. static Bool vncRandRCrtcSet(ScreenPtr pScreen, RRCrtcPtr crtc, RRModePtr mode,
  1066. int x, int y, Rotation rotation, int num_outputs,
  1067. RROutputPtr *outputs)
  1068. {
  1069. Bool ret;
  1070. int i;
  1071. /*
  1072. * Some applications get confused by a connected output without a
  1073. * mode or CRTC, so we need to fiddle with the connection state as well.
  1074. */
  1075. for (i = 0;i < crtc->numOutputs;i++)
  1076. RROutputSetConnection(crtc->outputs[i], RR_Disconnected);
  1077. for (i = 0;i < num_outputs;i++) {
  1078. if (mode != NULL)
  1079. RROutputSetConnection(outputs[i], RR_Connected);
  1080. else
  1081. RROutputSetConnection(outputs[i], RR_Disconnected);
  1082. }
  1083. /* Let RandR know we approve, and let it update its internal state */
  1084. ret = RRCrtcNotify(crtc, mode, x, y, rotation, NULL, num_outputs, outputs);
  1085. if (!ret)
  1086. return FALSE;
  1087. return TRUE;
  1088. }
  1089. static Bool vncRandROutputValidateMode(ScreenPtr pScreen,
  1090. RROutputPtr output, RRModePtr mode)
  1091. {
  1092. /* We have no hardware so any mode works */
  1093. return TRUE;
  1094. }
  1095. static void vncRandRModeDestroy(ScreenPtr pScreen, RRModePtr mode)
  1096. {
  1097. /* We haven't allocated anything so nothing to destroy */
  1098. }
  1099. static const int vncRandRWidths[] = { 1920, 1920, 1600, 1680, 1400, 1360, 1280, 1280, 1280, 1280, 1024, 800, 640 };
  1100. static const int vncRandRHeights[] = { 1200, 1080, 1200, 1050, 1050, 768, 1024, 960, 800, 720, 768, 600, 480 };
  1101. static int vncRandRIndex = 0;
  1102. static RRModePtr vncRandRModeGet(int width, int height)
  1103. {
  1104. xRRModeInfo modeInfo;
  1105. char name[100];
  1106. RRModePtr mode;
  1107. memset(&modeInfo, 0, sizeof(modeInfo));
  1108. sprintf(name, "%dx%d", width, height);
  1109. modeInfo.width = width;
  1110. modeInfo.height = height;
  1111. modeInfo.hTotal = width;
  1112. modeInfo.vTotal = height;
  1113. modeInfo.dotClock = ((CARD32)width * (CARD32)height * 60);
  1114. modeInfo.nameLength = strlen(name);
  1115. mode = RRModeGet(&modeInfo, name);
  1116. if (mode == NULL)
  1117. return NULL;
  1118. return mode;
  1119. }
  1120. static void vncRandRSetModes(RROutputPtr output, int pref_width, int pref_height)
  1121. {
  1122. RRModePtr mode;
  1123. RRModePtr *modes;
  1124. int i, num_modes, num_pref;
  1125. num_modes = sizeof(vncRandRWidths)/sizeof(*vncRandRWidths) + 1;
  1126. modes = malloc(sizeof(RRModePtr)*num_modes);
  1127. if (modes == NULL)
  1128. return;
  1129. num_modes = 0;
  1130. num_pref = 0;
  1131. if ((pref_width > 0) && (pref_height > 0)) {
  1132. mode = vncRandRModeGet(pref_width, pref_height);
  1133. if (mode != NULL) {
  1134. modes[num_modes] = mode;
  1135. num_modes++;
  1136. num_pref++;
  1137. }
  1138. }
  1139. for (i = 0;i < sizeof(vncRandRWidths)/sizeof(*vncRandRWidths);i++) {
  1140. if ((vncRandRWidths[i] == pref_width) &&
  1141. (vncRandRHeights[i] == pref_height))
  1142. continue;
  1143. mode = vncRandRModeGet(vncRandRWidths[i], vncRandRHeights[i]);
  1144. if (mode != NULL) {
  1145. modes[num_modes] = mode;
  1146. num_modes++;
  1147. }
  1148. }
  1149. RROutputSetModes(output, modes, num_modes, num_pref);
  1150. free(modes);
  1151. }
  1152. static RRCrtcPtr vncRandRCrtcCreate(ScreenPtr pScreen)
  1153. {
  1154. RRCrtcPtr crtc;
  1155. RROutputPtr output;
  1156. char name[100];
  1157. /* First we create the CRTC... */
  1158. crtc = RRCrtcCreate(pScreen, NULL);
  1159. /* We don't actually support gamma, but xrandr complains when it is missing */
  1160. RRCrtcGammaSetSize (crtc, 256);
  1161. /* Then we create a dummy output for it... */
  1162. sprintf(name, "VNC-%d", vncRandRIndex);
  1163. vncRandRIndex++;
  1164. output = RROutputCreate(pScreen, name, strlen(name), NULL);
  1165. RROutputSetCrtcs(output, &crtc, 1);
  1166. RROutputSetConnection(output, RR_Disconnected);
  1167. /* Make sure the CRTC has this output set */
  1168. vncRandRCrtcSet(pScreen, crtc, NULL, 0, 0, RR_Rotate_0, 1, &output);
  1169. /* Populate a list of default modes */
  1170. vncRandRSetModes(output, -1, -1);
  1171. return crtc;
  1172. }
  1173. /* Used from XserverDesktop when it needs more outputs... */
  1174. int vncRandRCreateOutputs(int scrIdx, int extraOutputs)
  1175. {
  1176. RRCrtcPtr crtc;
  1177. while (extraOutputs > 0) {
  1178. crtc = vncRandRCrtcCreate(screenInfo.screens[scrIdx]);
  1179. if (crtc == NULL)
  1180. return -1;
  1181. extraOutputs--;
  1182. }
  1183. return 0;
  1184. }
  1185. /* Used to create a preferred mode from various places */
  1186. void *vncRandRCreatePreferredMode(void *out, int width, int height)
  1187. {
  1188. RROutputPtr output;
  1189. output = out;
  1190. /* Already the preferred mode? */
  1191. if ((output->numModes >= 1) && (output->numPreferred == 1) &&
  1192. (output->modes[0]->mode.width == width) &&
  1193. (output->modes[0]->mode.height == height))
  1194. return output->modes[0];
  1195. /* Recreate the list, with the mode we want as preferred */
  1196. vncRandRSetModes(output, width, height);
  1197. if ((output->numModes >= 1) && (output->numPreferred == 1) &&
  1198. (output->modes[0]->mode.width == width) &&
  1199. (output->modes[0]->mode.height == height))
  1200. return output->modes[0];
  1201. return NULL;
  1202. }
  1203. static Bool vncRandRInit(ScreenPtr pScreen)
  1204. {
  1205. RRCrtcPtr crtc;
  1206. RRModePtr mode;
  1207. Bool ret;
  1208. if (!RRInit())
  1209. return FALSE;
  1210. /* These are completely arbitrary */
  1211. RRScreenSetSizeRange(pScreen, 32, 32, 32768, 32768);
  1212. /*
  1213. * Start with a single CRTC with a single output. More will be
  1214. * allocated as needed...
  1215. */
  1216. crtc = vncRandRCrtcCreate(pScreen);
  1217. /* Make sure the current screen size is the active mode */
  1218. mode = vncRandRCreatePreferredMode(crtc->outputs[0],
  1219. pScreen->width, pScreen->height);
  1220. if (mode == NULL)
  1221. return FALSE;
  1222. ret = vncRandRCrtcSet(pScreen, crtc, mode, 0, 0, RR_Rotate_0,
  1223. crtc->numOutputs, crtc->outputs);
  1224. if (!ret)
  1225. return FALSE;
  1226. return TRUE;
  1227. }
  1228. #endif
  1229. static Bool
  1230. #if XORG < 113
  1231. vfbCloseScreen(int index, ScreenPtr pScreen)
  1232. #else
  1233. vfbCloseScreen(ScreenPtr pScreen)
  1234. #endif
  1235. {
  1236. #if XORG < 113
  1237. vfbScreenInfoPtr pvfb = &vfbScreens[index];
  1238. #else
  1239. vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
  1240. #endif
  1241. int i;
  1242. pScreen->CloseScreen = pvfb->closeScreen;
  1243. /*
  1244. * XXX probably lots of stuff to clean. For now,
  1245. * clear installed colormaps so that server reset works correctly.
  1246. */
  1247. #if XORG < 113
  1248. for (i = 0; i < MAXSCREENS; i++)
  1249. InstalledMaps[i] = NULL;
  1250. return pScreen->CloseScreen(index, pScreen);
  1251. #else
  1252. for (i = 0; i < screenInfo.numScreens; i++)
  1253. SetInstalledColormap(screenInfo.screens[i], NULL);
  1254. /*
  1255. * fb overwrites miCloseScreen, so do this here
  1256. */
  1257. if (pScreen->devPrivate)
  1258. (*pScreen->DestroyPixmap) ((PixmapPtr) pScreen->devPrivate);
  1259. pScreen->devPrivate = NULL;
  1260. return pScreen->CloseScreen(pScreen);
  1261. #endif
  1262. }
  1263. static Bool
  1264. #if XORG < 113
  1265. vfbScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
  1266. #else
  1267. vfbScreenInit(ScreenPtr pScreen, int argc, char **argv)
  1268. #endif
  1269. {
  1270. #if XORG >= 113
  1271. int index = pScreen->myNum;
  1272. #endif
  1273. vfbScreenInfoPtr pvfb = &vfbScreens[index];
  1274. int dpi;
  1275. int ret;
  1276. void *pbits;
  1277. #ifdef RANDR
  1278. rrScrPrivPtr rp;
  1279. #endif
  1280. #if XORG >= 113
  1281. if (!dixRegisterPrivateKey(&cmapScrPrivateKeyRec, PRIVATE_SCREEN, 0))
  1282. return FALSE;
  1283. #endif
  1284. /* 96 is the default used by most other systems */
  1285. dpi = 96;
  1286. if (monitorResolution)
  1287. dpi = monitorResolution;
  1288. pbits = vfbAllocateFramebufferMemory(&pvfb->fb);
  1289. if (!pbits) return FALSE;
  1290. vncFbptr[index] = pbits;
  1291. vncFbstride[index] = pvfb->fb.paddedWidth;
  1292. miSetPixmapDepths();
  1293. switch (pvfb->fb.depth) {
  1294. case 8:
  1295. miSetVisualTypesAndMasks (8,
  1296. ((1 << StaticGray) |
  1297. (1 << GrayScale) |
  1298. (1 << StaticColor) |
  1299. (1 << PseudoColor) |
  1300. (1 << TrueColor) |
  1301. (1 << DirectColor)),
  1302. 8, PseudoColor, 0, 0, 0);
  1303. break;
  1304. case 16:
  1305. miSetVisualTypesAndMasks (16,
  1306. ((1 << TrueColor) |
  1307. (1 << DirectColor)),
  1308. 8, TrueColor, 0xf800, 0x07e0, 0x001f);
  1309. break;
  1310. case 24:
  1311. miSetVisualTypesAndMasks (24,
  1312. ((1 << TrueColor) |
  1313. (1 << DirectColor)),
  1314. 8, TrueColor, 0xff0000, 0x00ff00, 0x0000ff);
  1315. break;
  1316. case 32:
  1317. miSetVisualTypesAndMasks (32,
  1318. ((1 << TrueColor) |
  1319. (1 << DirectColor)),
  1320. 8, TrueColor, 0xff000000, 0x00ff0000, 0x0000ff00);
  1321. break;
  1322. default:
  1323. return FALSE;
  1324. }
  1325. if (index > 0) {
  1326. ScreenPtr prevScreen = screenInfo.screens[index-1];
  1327. pScreen->x = prevScreen->x + prevScreen->width;
  1328. pScreen->y = 0;
  1329. }
  1330. ret = fbScreenInit(pScreen, pbits, pvfb->fb.width, pvfb->fb.height,
  1331. dpi, dpi, pvfb->fb.paddedWidth, pvfb->fb.bitsPerPixel);
  1332. #ifdef RENDER
  1333. if (ret && Render)
  1334. ret = fbPictureInit (pScreen, 0, 0);
  1335. #endif
  1336. if (!ret) return FALSE;
  1337. #if XORG < 110
  1338. miInitializeBackingStore(pScreen);
  1339. #endif
  1340. /*
  1341. * Circumvent the backing store that was just initialised. This amounts
  1342. * to a truely bizarre way of initialising SaveDoomedAreas and friends.
  1343. */
  1344. pScreen->InstallColormap = vfbInstallColormap;
  1345. pScreen->UninstallColormap = vfbUninstallColormap;
  1346. pScreen->ListInstalledColormaps = vfbListInstalledColormaps;
  1347. pScreen->SaveScreen = vfbSaveScreen;
  1348. miPointerInitialize(pScreen, &vfbPointerSpriteFuncs, &vfbPointerCursorFuncs,
  1349. FALSE);
  1350. pScreen->blackPixel = pvfb->blackPixel;
  1351. pScreen->whitePixel = pvfb->whitePixel;
  1352. if (!pvfb->pixelFormatDefined) {
  1353. switch (pvfb->fb.depth) {
  1354. case 16:
  1355. pvfb->pixelFormatDefined = TRUE;
  1356. pvfb->rgbNotBgr = TRUE;
  1357. pvfb->blueBits = pvfb->redBits = 5;
  1358. pvfb->greenBits = 6;
  1359. break;
  1360. case 24:
  1361. case 32:
  1362. pvfb->pixelFormatDefined = TRUE;
  1363. pvfb->rgbNotBgr = TRUE;
  1364. pvfb->blueBits = pvfb->redBits = pvfb->greenBits = 8;
  1365. break;
  1366. }
  1367. }
  1368. if (pvfb->pixelFormatDefined) {
  1369. VisualPtr vis = pScreen->visuals;
  1370. for (int i = 0; i < pScreen->numVisuals; i++) {
  1371. if (pvfb->rgbNotBgr) {
  1372. vis->offsetBlue = 0;
  1373. vis->blueMask = (1 << pvfb->blueBits) - 1;
  1374. vis->offsetGreen = pvfb->blueBits;
  1375. vis->greenMask = ((1 << pvfb->greenBits) - 1) << vis->offsetGreen;
  1376. vis->offsetRed = vis->offsetGreen + pvfb->greenBits;
  1377. vis->redMask = ((1 << pvfb->redBits) - 1) << vis->offsetRed;
  1378. } else {
  1379. vis->offsetRed = 0;
  1380. vis->redMask = (1 << pvfb->redBits) - 1;
  1381. vis->offsetGreen = pvfb->redBits;
  1382. vis->greenMask = ((1 << pvfb->greenBits) - 1) << vis->offsetGreen;
  1383. vis->offsetBlue = vis->offsetGreen + pvfb->greenBits;
  1384. vis->blueMask = ((1 << pvfb->blueBits) - 1) << vis->offsetBlue;
  1385. }
  1386. vis++;
  1387. }
  1388. }
  1389. ret = fbCreateDefColormap(pScreen);
  1390. if (!ret) return FALSE;
  1391. miSetZeroLineBias(pScreen, pvfb->lineBias);
  1392. pvfb->closeScreen = pScreen->CloseScreen;
  1393. pScreen->CloseScreen = vfbCloseScreen;
  1394. #ifdef RANDR
  1395. ret = RRScreenInit(pScreen);
  1396. if (!ret) return FALSE;
  1397. rp = rrGetScrPriv(pScreen);
  1398. rp->rrGetInfo = vncRandRGetInfo;
  1399. rp->rrSetConfig = NULL;
  1400. rp->rrScreenSetSize = vncRandRScreenSetSize;
  1401. rp->rrCrtcSet = vncRandRCrtcSet;
  1402. rp->rrOutputValidateMode = vncRandROutputValidateMode;
  1403. rp->rrModeDestroy = vncRandRModeDestroy;
  1404. ret = vncRandRInit(pScreen);
  1405. if (!ret) return FALSE;
  1406. #endif
  1407. return TRUE;
  1408. } /* end vfbScreenInit */
  1409. static void vfbClientStateChange(CallbackListPtr *a, void *b, void *c) {
  1410. if (dispatchException & DE_RESET) {
  1411. ErrorF("Warning: VNC extension does not support -reset, terminating instead. Use -noreset to prevent termination.\n");
  1412. dispatchException |= DE_TERMINATE;
  1413. dispatchException &= ~DE_RESET;
  1414. }
  1415. }
  1416. #if XORG >= 113
  1417. #ifdef GLXEXT
  1418. extern void GlxExtensionInit(void);
  1419. static ExtensionModule glxExt = {
  1420. GlxExtensionInit,
  1421. "GLX",
  1422. &noGlxExtension
  1423. };
  1424. #endif
  1425. #endif
  1426. void
  1427. InitOutput(ScreenInfo *scrInfo, int argc, char **argv)
  1428. {
  1429. int i;
  1430. int NumFormats = 0;
  1431. vncPrintBanner();
  1432. #if XORG >= 113
  1433. #ifdef GLXEXT
  1434. if (serverGeneration == 1)
  1435. #if XORG >= 116
  1436. LoadExtensionList(&glxExt, 1, TRUE);
  1437. #else
  1438. LoadExtension(&glxExt, TRUE);
  1439. #endif
  1440. #endif
  1441. #endif
  1442. /* initialize pixmap formats */
  1443. /* must have a pixmap depth to match every screen depth */
  1444. for (i = 0; i < vfbNumScreens; i++)
  1445. {
  1446. vfbPixmapDepths[vfbScreens[i].fb.depth] = TRUE;
  1447. }
  1448. /* RENDER needs a good set of pixmaps. */
  1449. if (Render) {
  1450. vfbPixmapDepths[1] = TRUE;
  1451. vfbPixmapDepths[4] = TRUE;
  1452. vfbPixmapDepths[8] = TRUE;
  1453. /* vfbPixmapDepths[15] = TRUE; */
  1454. vfbPixmapDepths[16] = TRUE;
  1455. vfbPixmapDepths[24] = TRUE;
  1456. vfbPixmapDepths[32] = TRUE;
  1457. }
  1458. for (i = 1; i <= 32; i++)
  1459. {
  1460. if (vfbPixmapDepths[i])
  1461. {
  1462. if (NumFormats >= MAXFORMATS)
  1463. FatalError ("MAXFORMATS is too small for this server\n");
  1464. scrInfo->formats[NumFormats].depth = i;
  1465. scrInfo->formats[NumFormats].bitsPerPixel = vfbBitsPerPixel(i);
  1466. scrInfo->formats[NumFormats].scanlinePad = BITMAP_SCANLINE_PAD;
  1467. NumFormats++;
  1468. }
  1469. }
  1470. scrInfo->imageByteOrder = IMAGE_BYTE_ORDER;
  1471. scrInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
  1472. scrInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
  1473. scrInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
  1474. scrInfo->numPixmapFormats = NumFormats;
  1475. /* initialize screens */
  1476. for (i = 0; i < vfbNumScreens; i++)
  1477. {
  1478. if (-1 == AddScreen(vfbScreenInit, argc, argv))
  1479. {
  1480. FatalError("Couldn't add screen %d", i);
  1481. }
  1482. }
  1483. if (!AddCallback(&ClientStateCallback, vfbClientStateChange, 0)) {
  1484. FatalError("AddCallback failed\n");
  1485. }
  1486. } /* end InitOutput */
  1487. /* this is just to get the server to link on AIX */
  1488. #ifdef AIXV3
  1489. int SelectWaitTime = 10000; /* usec */
  1490. #endif
  1491. void DDXRingBell(int percent, int pitch, int duration)
  1492. {
  1493. if (percent > 0)
  1494. vncBell();
  1495. }
  1496. Bool LegalModifier(unsigned int key, DeviceIntPtr pDev)
  1497. {
  1498. return TRUE;
  1499. }
  1500. void ProcessInputEvents(void)
  1501. {
  1502. mieqProcessInputEvents();
  1503. }
  1504. void InitInput(int argc, char *argv[])
  1505. {
  1506. mieqInit ();
  1507. }
  1508. #if XORG > 17
  1509. void CloseInput(void)
  1510. {
  1511. }
  1512. #endif
  1513. void vncClientGone(int fd)
  1514. {
  1515. if (fd == vncInetdSock) {
  1516. ErrorF("inetdSock client gone\n");
  1517. GiveUp(0);
  1518. }
  1519. }