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

xvnc.cc 39KB

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