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.

RandrGlue.c 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
  2. * Copyright 2011-2015 Pierre Ossman for Cendio AB
  3. *
  4. * This is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This software is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this software; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  17. * USA.
  18. */
  19. #ifdef HAVE_DIX_CONFIG_H
  20. #include <dix-config.h>
  21. #endif
  22. #include <assert.h>
  23. #include <string.h>
  24. #include "scrnintstr.h"
  25. #include "randrstr.h"
  26. #include "RandrGlue.h"
  27. #include "XorgGlue.h"
  28. static int scrIdx;
  29. void vncSetGlueContext(int screenIndex);
  30. void vncSetGlueContext(int screenIndex)
  31. {
  32. scrIdx = screenIndex;
  33. }
  34. int vncGetScreenWidth(void)
  35. {
  36. return screenInfo.screens[scrIdx]->width;
  37. }
  38. int vncGetScreenHeight(void)
  39. {
  40. return screenInfo.screens[scrIdx]->height;
  41. }
  42. int vncRandRIsValidScreenSize(int width, int height)
  43. {
  44. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  45. if (width < rp->minWidth || rp->maxWidth < width)
  46. return 0;
  47. if (height < rp->minHeight || rp->maxHeight < height)
  48. return 0;
  49. return 1;
  50. }
  51. int vncRandRResizeScreen(int width, int height)
  52. {
  53. ScreenPtr pScreen = screenInfo.screens[scrIdx];
  54. int dpi, mwidth, mheight;
  55. /* Keep the DPI specified at start */
  56. dpi = monitorResolution ? monitorResolution : 96;
  57. mwidth = width * 254 / dpi / 10;
  58. mheight = height * 254 / dpi / 10;
  59. return RRScreenSizeSet(pScreen, width, height, mwidth, mheight);
  60. }
  61. void vncRandRUpdateSetTime(void)
  62. {
  63. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  64. rp->lastSetTime = currentTime;
  65. }
  66. int vncRandRHasOutputClones(void)
  67. {
  68. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  69. for (int i = 0;i < rp->numCrtcs;i++) {
  70. if (rp->crtcs[i]->numOutputs > 1)
  71. return 1;
  72. }
  73. return 0;
  74. }
  75. int vncRandRGetOutputCount(void)
  76. {
  77. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  78. return rp->numOutputs;
  79. }
  80. int vncRandRGetAvailableOutputs(void)
  81. {
  82. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  83. int availableOutputs;
  84. RRCrtcPtr *usedCrtcs;
  85. int numUsed;
  86. int i, j, k;
  87. usedCrtcs = malloc(sizeof(RRCrtcPtr) * rp->numCrtcs);
  88. if (usedCrtcs == NULL)
  89. return 0;
  90. /*
  91. * This gets slightly complicated because we might need to hook a CRTC
  92. * up to the output, but also check that we don't try to use the same
  93. * CRTC for multiple outputs.
  94. */
  95. availableOutputs = 0;
  96. numUsed = 0;
  97. for (i = 0;i < rp->numOutputs;i++) {
  98. RROutputPtr output;
  99. output = rp->outputs[i];
  100. if (output->crtc != NULL)
  101. availableOutputs++;
  102. else {
  103. for (j = 0;j < output->numCrtcs;j++) {
  104. if (output->crtcs[j]->numOutputs != 0)
  105. continue;
  106. for (k = 0;k < numUsed;k++) {
  107. if (usedCrtcs[k] == output->crtcs[j])
  108. break;
  109. }
  110. if (k != numUsed)
  111. continue;
  112. availableOutputs++;
  113. usedCrtcs[numUsed] = output->crtcs[j];
  114. numUsed++;
  115. break;
  116. }
  117. }
  118. }
  119. free(usedCrtcs);
  120. return availableOutputs;
  121. }
  122. char *vncRandRGetOutputName(int outputIdx)
  123. {
  124. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  125. return strdup(rp->outputs[outputIdx]->name);
  126. }
  127. int vncRandRIsOutputEnabled(int outputIdx)
  128. {
  129. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  130. if (rp->outputs[outputIdx]->crtc == NULL)
  131. return 0;
  132. if (rp->outputs[outputIdx]->crtc->mode == NULL)
  133. return 0;
  134. return 1;
  135. }
  136. int vncRandRIsOutputUsable(int outputIdx)
  137. {
  138. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  139. RROutputPtr output;
  140. int i;
  141. output = rp->outputs[outputIdx];
  142. if (output->crtc != NULL)
  143. return 1;
  144. /* Any unused CRTCs? */
  145. for (i = 0;i < output->numCrtcs;i++) {
  146. if (output->crtcs[i]->numOutputs == 0)
  147. return 1;
  148. }
  149. return 0;
  150. }
  151. int vncRandRIsOutputConnected(int outputIdx)
  152. {
  153. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  154. RROutputPtr output;
  155. output = rp->outputs[outputIdx];
  156. return (output->connection == RR_Connected);
  157. }
  158. static RRModePtr vncRandRGetMatchingMode(int outputIdx, int width, int height)
  159. {
  160. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  161. RROutputPtr output;
  162. output = rp->outputs[outputIdx];
  163. if (output->crtc != NULL) {
  164. unsigned int swap;
  165. switch (output->crtc->rotation) {
  166. case RR_Rotate_90:
  167. case RR_Rotate_270:
  168. swap = width;
  169. width = height;
  170. height = swap;
  171. break;
  172. }
  173. }
  174. for (int i = 0; i < output->numModes; i++) {
  175. if ((output->modes[i]->mode.width == width) &&
  176. (output->modes[i]->mode.height == height))
  177. return output->modes[i];
  178. }
  179. return NULL;
  180. }
  181. int vncRandRCheckOutputMode(int outputIdx, int width, int height)
  182. {
  183. if (vncRandRGetMatchingMode(outputIdx, width, height) != NULL)
  184. return 1;
  185. if (vncRandRCanCreateModes())
  186. return 1;
  187. return 0;
  188. }
  189. int vncRandRDisableOutput(int outputIdx)
  190. {
  191. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  192. RRCrtcPtr crtc;
  193. int i;
  194. RROutputPtr *outputs;
  195. int numOutputs = 0;
  196. RRModePtr mode;
  197. int ret;
  198. crtc = rp->outputs[outputIdx]->crtc;
  199. if (crtc == NULL)
  200. return 1;
  201. /* Remove this output from the CRTC configuration */
  202. outputs = malloc(crtc->numOutputs * sizeof(RROutputPtr));
  203. if (!outputs) {
  204. return 0;
  205. }
  206. for (i = 0; i < crtc->numOutputs; i++) {
  207. if (rp->outputs[outputIdx] != crtc->outputs[i]) {
  208. outputs[numOutputs++] = crtc->outputs[i];
  209. }
  210. }
  211. if (numOutputs == 0) {
  212. mode = NULL;
  213. } else {
  214. mode = crtc->mode;
  215. }
  216. ret = RRCrtcSet(crtc, mode, crtc->x, crtc->y, crtc->rotation, numOutputs, outputs);
  217. free(outputs);
  218. return ret;
  219. }
  220. unsigned int vncRandRGetOutputId(int outputIdx)
  221. {
  222. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  223. return rp->outputs[outputIdx]->id;
  224. }
  225. int vncRandRGetOutputDimensions(int outputIdx,
  226. int *x, int *y, int *width, int *height)
  227. {
  228. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  229. RRCrtcPtr crtc;
  230. int swap;
  231. *x = *y = *width = *height = 0;
  232. crtc = rp->outputs[outputIdx]->crtc;
  233. if (crtc == NULL || !crtc->mode)
  234. return 1;
  235. *x = crtc->x;
  236. *y = crtc->y;
  237. *width = crtc->mode->mode.width;
  238. *height = crtc->mode->mode.height;
  239. switch (crtc->rotation & 0xf) {
  240. case RR_Rotate_90:
  241. case RR_Rotate_270:
  242. swap = *width;
  243. *width = *height;
  244. *height = swap;
  245. break;
  246. }
  247. return 0;
  248. }
  249. int vncRandRReconfigureOutput(int outputIdx, int x, int y,
  250. int width, int height)
  251. {
  252. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  253. RROutputPtr output;
  254. RRCrtcPtr crtc;
  255. RRModePtr mode;
  256. int i;
  257. output = rp->outputs[outputIdx];
  258. crtc = output->crtc;
  259. /* Need a CRTC? */
  260. if (crtc == NULL) {
  261. for (i = 0;i < output->numCrtcs;i++) {
  262. if (output->crtcs[i]->numOutputs != 0)
  263. continue;
  264. crtc = output->crtcs[i];
  265. break;
  266. }
  267. /* Couldn't find one... */
  268. if (crtc == NULL)
  269. return 0;
  270. }
  271. /* Make sure we have the mode we want */
  272. mode = vncRandRGetMatchingMode(outputIdx, width, height);
  273. if (mode == NULL) {
  274. mode = vncRandRCreateMode(output, width, height);
  275. if (mode == NULL)
  276. return 0;
  277. }
  278. mode = vncRandRSetPreferredMode(output, mode);
  279. if (mode == NULL)
  280. return 0;
  281. /* Reconfigure new mode and position */
  282. return RRCrtcSet(crtc, mode, x, y, crtc->rotation, 1, &output);
  283. }
  284. int vncRandRCanCreateOutputs(int extraOutputs)
  285. {
  286. return vncRandRCanCreateScreenOutputs(scrIdx, extraOutputs);
  287. }
  288. int vncRandRCreateOutputs(int extraOutputs)
  289. {
  290. return vncRandRCreateScreenOutputs(scrIdx, extraOutputs);
  291. }