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 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  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. #ifdef RANDR
  26. #include "randrstr.h"
  27. #endif
  28. #include "RandrGlue.h"
  29. int vncGetScreenWidth(int scrIdx)
  30. {
  31. return screenInfo.screens[scrIdx]->width;
  32. }
  33. int vncGetScreenHeight(int scrIdx)
  34. {
  35. return screenInfo.screens[scrIdx]->height;
  36. }
  37. int vncRandRResizeScreen(int scrIdx, int width, int height)
  38. {
  39. #ifdef RANDR
  40. ScreenPtr pScreen = screenInfo.screens[scrIdx];
  41. /* Try to retain DPI when we resize */
  42. return RRScreenSizeSet(pScreen, width, height,
  43. pScreen->mmWidth * width / pScreen->width,
  44. pScreen->mmHeight * height / pScreen->height);
  45. #else
  46. return -1;
  47. #endif
  48. }
  49. void vncRandRUpdateSetTime(int scrIdx)
  50. {
  51. #ifdef RANDR
  52. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  53. rp->lastSetTime = currentTime;
  54. #endif
  55. }
  56. int vncRandRHasOutputClones(int scrIdx)
  57. {
  58. #ifdef RANDR
  59. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  60. for (int i = 0;i < rp->numCrtcs;i++) {
  61. if (rp->crtcs[i]->numOutputs > 1)
  62. return 1;
  63. }
  64. #endif
  65. return 0;
  66. }
  67. int vncRandRGetOutputCount(int scrIdx)
  68. {
  69. #ifdef RANDR
  70. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  71. return rp->numOutputs;
  72. #else
  73. return 0;
  74. #endif
  75. }
  76. int vncRandRGetAvailableOutputs(int scrIdx)
  77. {
  78. #ifdef RANDR
  79. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  80. int availableOutputs;
  81. RRCrtcPtr *usedCrtcs;
  82. int numUsed;
  83. int i, j, k;
  84. usedCrtcs = malloc(sizeof(RRCrtcPtr) * rp->numCrtcs);
  85. if (usedCrtcs == NULL)
  86. return 0;
  87. /*
  88. * This gets slightly complicated because we might need to hook a CRTC
  89. * up to the output, but also check that we don't try to use the same
  90. * CRTC for multiple outputs.
  91. */
  92. availableOutputs = 0;
  93. numUsed = 0;
  94. for (i = 0;i < rp->numOutputs;i++) {
  95. RROutputPtr output;
  96. output = rp->outputs[i];
  97. if (output->crtc != NULL)
  98. availableOutputs++;
  99. else {
  100. for (j = 0;j < output->numCrtcs;j++) {
  101. if (output->crtcs[j]->numOutputs != 0)
  102. continue;
  103. for (k = 0;k < numUsed;k++) {
  104. if (usedCrtcs[k] == output->crtcs[j])
  105. break;
  106. }
  107. if (k != numUsed)
  108. continue;
  109. availableOutputs++;
  110. usedCrtcs[numUsed] = output->crtcs[j];
  111. numUsed++;
  112. break;
  113. }
  114. }
  115. }
  116. free(usedCrtcs);
  117. return availableOutputs;
  118. #else
  119. return 0;
  120. #endif
  121. }
  122. char *vncRandRGetOutputName(int scrIdx, int outputIdx)
  123. {
  124. #ifdef RANDR
  125. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  126. return strdup(rp->outputs[outputIdx]->name);
  127. #else
  128. return strdup("");
  129. #endif
  130. }
  131. int vncRandRIsOutputEnabled(int scrIdx, int outputIdx)
  132. {
  133. #ifdef RANDR
  134. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  135. if (rp->outputs[outputIdx]->crtc == NULL)
  136. return 0;
  137. if (rp->outputs[outputIdx]->crtc->mode == NULL)
  138. return 0;
  139. return 1;
  140. #else
  141. return 0;
  142. #endif
  143. }
  144. int vncRandRIsOutputUsable(int scrIdx, int outputIdx)
  145. {
  146. #ifdef RANDR
  147. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  148. RROutputPtr output;
  149. int i;
  150. output = rp->outputs[outputIdx];
  151. if (output->crtc != NULL)
  152. return 1;
  153. /* Any unused CRTCs? */
  154. for (i = 0;i < output->numCrtcs;i++) {
  155. if (output->crtcs[i]->numOutputs == 0)
  156. return 1;
  157. }
  158. #endif
  159. return 0;
  160. }
  161. int vncRandRDisableOutput(int scrIdx, int outputIdx)
  162. {
  163. #ifdef RANDR
  164. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  165. RRCrtcPtr crtc;
  166. crtc = rp->outputs[outputIdx]->crtc;
  167. if (crtc == NULL)
  168. return 0;
  169. return RRCrtcSet(crtc, NULL, crtc->x, crtc->y, crtc->rotation, 0, NULL);
  170. #else
  171. return -1;
  172. #endif
  173. }
  174. unsigned int vncRandRGetOutputId(int scrIdx, int outputIdx)
  175. {
  176. #ifdef RANDR
  177. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  178. return rp->outputs[outputIdx]->id;
  179. #else
  180. return 0;
  181. #endif
  182. }
  183. void vncRandRGetOutputDimensions(int scrIdx, int outputIdx,
  184. int *x, int *y, int *width, int *height)
  185. {
  186. #ifdef RANDR
  187. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  188. int swap;
  189. *x = rp->outputs[outputIdx]->crtc->x;
  190. *y = rp->outputs[outputIdx]->crtc->y;
  191. *width = rp->outputs[outputIdx]->crtc->mode->mode.width;
  192. *height = rp->outputs[outputIdx]->crtc->mode->mode.height;
  193. switch (rp->outputs[outputIdx]->crtc->rotation & 0xf) {
  194. case RR_Rotate_90:
  195. case RR_Rotate_270:
  196. swap = *width;
  197. *width = *height;
  198. *height = swap;
  199. break;
  200. }
  201. #endif
  202. }
  203. int vncRandRReconfigureOutput(int scrIdx, int outputIdx, int x, int y,
  204. int width, int height)
  205. {
  206. #ifdef RANDR
  207. rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
  208. RROutputPtr output;
  209. RRCrtcPtr crtc;
  210. RRModePtr mode;
  211. int i;
  212. output = rp->outputs[outputIdx];
  213. crtc = output->crtc;
  214. /* Need a CRTC? */
  215. if (crtc == NULL) {
  216. for (i = 0;i < output->numCrtcs;i++) {
  217. if (output->crtcs[i]->numOutputs != 0)
  218. continue;
  219. crtc = output->crtcs[i];
  220. break;
  221. }
  222. /* Couldn't find one... */
  223. if (crtc == NULL)
  224. return -1;
  225. }
  226. /* Make sure we have the mode we want */
  227. mode = vncRandRCreatePreferredMode(output, width, height);
  228. if (mode == NULL)
  229. return -1;
  230. /* Reconfigure new mode and position */
  231. return RRCrtcSet(crtc, mode, x, y, crtc->rotation, 1, &output);
  232. #else
  233. return -1;
  234. #endif
  235. }