rrmode.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /*
  2. * Copyright © 2006 Keith Packard
  3. *
  4. * Permission to use, copy, modify, distribute, and sell this software and its
  5. * documentation for any purpose is hereby granted without fee, provided that
  6. * the above copyright notice appear in all copies and that both that copyright
  7. * notice and this permission notice appear in supporting documentation, and
  8. * that the name of the copyright holders not be used in advertising or
  9. * publicity pertaining to distribution of the software without specific,
  10. * written prior permission. The copyright holders make no representations
  11. * about the suitability of this software for any purpose. It is provided "as
  12. * is" without express or implied warranty.
  13. *
  14. * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  15. * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  16. * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  17. * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  18. * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  19. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  20. * OF THIS SOFTWARE.
  21. */
  22. #include "randrstr.h"
  23. RESTYPE RRModeType;
  24. static Bool
  25. RRModeEqual(xRRModeInfo * a, xRRModeInfo * b)
  26. {
  27. if (a->width != b->width)
  28. return FALSE;
  29. if (a->height != b->height)
  30. return FALSE;
  31. if (a->dotClock != b->dotClock)
  32. return FALSE;
  33. if (a->hSyncStart != b->hSyncStart)
  34. return FALSE;
  35. if (a->hSyncEnd != b->hSyncEnd)
  36. return FALSE;
  37. if (a->hTotal != b->hTotal)
  38. return FALSE;
  39. if (a->hSkew != b->hSkew)
  40. return FALSE;
  41. if (a->vSyncStart != b->vSyncStart)
  42. return FALSE;
  43. if (a->vSyncEnd != b->vSyncEnd)
  44. return FALSE;
  45. if (a->vTotal != b->vTotal)
  46. return FALSE;
  47. if (a->nameLength != b->nameLength)
  48. return FALSE;
  49. if (a->modeFlags != b->modeFlags)
  50. return FALSE;
  51. return TRUE;
  52. }
  53. /*
  54. * Keep a list so it's easy to find modes in the resource database.
  55. */
  56. static int num_modes;
  57. static RRModePtr *modes;
  58. RRModePtr
  59. RRModeGet(xRRModeInfo * modeInfo, const char *name)
  60. {
  61. int i;
  62. RRModePtr mode;
  63. RRModePtr *newModes;
  64. for (i = 0; i < num_modes; i++) {
  65. mode = modes[i];
  66. if (RRModeEqual(&mode->mode, modeInfo) &&
  67. !memcmp(name, mode->name, modeInfo->nameLength)) {
  68. ++mode->refcnt;
  69. return mode;
  70. }
  71. }
  72. if (!RRInit())
  73. return NULL;
  74. mode = malloc(sizeof(RRModeRec) + modeInfo->nameLength + 1);
  75. if (!mode)
  76. return NULL;
  77. mode->refcnt = 1;
  78. mode->mode = *modeInfo;
  79. mode->name = (char *) (mode + 1);
  80. memcpy(mode->name, name, modeInfo->nameLength);
  81. mode->name[modeInfo->nameLength] = '\0';
  82. mode->userDefined = FALSE;
  83. if (num_modes)
  84. newModes = realloc(modes, (num_modes + 1) * sizeof(RRModePtr));
  85. else
  86. newModes = malloc(sizeof(RRModePtr));
  87. if (!newModes) {
  88. free(mode);
  89. return NULL;
  90. }
  91. mode->mode.id = FakeClientID(0);
  92. if (!AddResource(mode->mode.id, RRModeType, (pointer) mode))
  93. return NULL;
  94. modes = newModes;
  95. modes[num_modes++] = mode;
  96. /*
  97. * give the caller a reference to this mode
  98. */
  99. ++mode->refcnt;
  100. return mode;
  101. }
  102. RRModePtr *
  103. RRModesForScreen(ScreenPtr pScreen, int *num_ret)
  104. {
  105. rrScrPriv(pScreen);
  106. int o, c;
  107. RRModePtr *screen_modes;
  108. int num_screen_modes = 0;
  109. screen_modes = malloc((num_modes ? num_modes : 1) * sizeof(RRModePtr));
  110. /*
  111. * Add modes from all outputs
  112. */
  113. for (o = 0; o < pScrPriv->numOutputs; o++) {
  114. RROutputPtr output = pScrPriv->outputs[o];
  115. int m, n;
  116. for (m = 0; m < output->numModes; m++) {
  117. RRModePtr mode = output->modes[m];
  118. for (n = 0; n < num_screen_modes; n++)
  119. if (screen_modes[n] == mode)
  120. break;
  121. if (n == num_screen_modes)
  122. screen_modes[num_screen_modes++] = mode;
  123. }
  124. }
  125. /*
  126. * Add modes from all crtcs. The goal is to
  127. * make sure all available and active modes
  128. * are visible to the client
  129. */
  130. for (c = 0; c < pScrPriv->numCrtcs; c++) {
  131. RRCrtcPtr crtc = pScrPriv->crtcs[c];
  132. RRModePtr mode = crtc->mode;
  133. int n;
  134. if (!mode)
  135. continue;
  136. for (n = 0; n < num_screen_modes; n++)
  137. if (screen_modes[n] == mode)
  138. break;
  139. if (n == num_screen_modes)
  140. screen_modes[num_screen_modes++] = mode;
  141. }
  142. *num_ret = num_screen_modes;
  143. return screen_modes;
  144. }
  145. void
  146. RRModeDestroy(RRModePtr mode)
  147. {
  148. int m;
  149. if (--mode->refcnt > 0)
  150. return;
  151. for (m = 0; m < num_modes; m++) {
  152. if (modes[m] == mode) {
  153. memmove(modes + m, modes + m + 1,
  154. (num_modes - m - 1) * sizeof(RRModePtr));
  155. num_modes--;
  156. if (!num_modes) {
  157. free(modes);
  158. modes = NULL;
  159. }
  160. break;
  161. }
  162. }
  163. free(mode);
  164. }
  165. static int
  166. RRModeDestroyResource(pointer value, XID pid)
  167. {
  168. RRModeDestroy((RRModePtr) value);
  169. return 1;
  170. }
  171. Bool
  172. RRModeInit(void)
  173. {
  174. assert(num_modes == 0);
  175. assert(modes == NULL);
  176. RRModeType = CreateNewResourceType(RRModeDestroyResource);
  177. if (!RRModeType)
  178. return FALSE;
  179. #ifdef XResExtension
  180. RegisterResourceName(RRModeType, "MODE");
  181. #endif
  182. return TRUE;
  183. }
  184. int
  185. ProcRRCreateMode(ClientPtr client)
  186. {
  187. REQUEST(xRRCreateModeReq);
  188. REQUEST_SIZE_MATCH(xRRCreateModeReq);
  189. (void) stuff;
  190. return BadImplementation;
  191. }
  192. int
  193. ProcRRDestroyMode(ClientPtr client)
  194. {
  195. REQUEST(xRRDestroyModeReq);
  196. REQUEST_SIZE_MATCH(xRRDestroyModeReq);
  197. (void) stuff;
  198. return BadImplementation;
  199. }
  200. int
  201. ProcRRAddOutputMode(ClientPtr client)
  202. {
  203. REQUEST(xRRAddOutputModeReq);
  204. REQUEST_SIZE_MATCH(xRRAddOutputModeReq);
  205. (void) stuff;
  206. return BadImplementation;
  207. }
  208. int
  209. ProcRRDeleteOutputMode(ClientPtr client)
  210. {
  211. REQUEST(xRRDeleteOutputModeReq);
  212. REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq);
  213. (void) stuff;
  214. return BadImplementation;
  215. }