rrdispatch.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  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. Bool
  24. RRClientKnowsRates(ClientPtr pClient)
  25. {
  26. rrClientPriv(pClient);
  27. return (pRRClient->major_version > 1 ||
  28. (pRRClient->major_version == 1 && pRRClient->minor_version >= 1));
  29. }
  30. static int
  31. ProcRRQueryVersion(ClientPtr client)
  32. {
  33. xRRQueryVersionReply rep;
  34. REQUEST(xRRQueryVersionReq);
  35. rrClientPriv(client);
  36. REQUEST_SIZE_MATCH(xRRQueryVersionReq);
  37. pRRClient->major_version = stuff->majorVersion;
  38. pRRClient->minor_version = stuff->minorVersion;
  39. rep.type = X_Reply;
  40. rep.length = 0;
  41. rep.sequenceNumber = client->sequence;
  42. /*
  43. * Report the current version; the current
  44. * spec says they're all compatible after 1.0
  45. */
  46. rep.majorVersion = 1;
  47. rep.minorVersion = 1;
  48. if (client->swapped) {
  49. swaps(&rep.sequenceNumber);
  50. swapl(&rep.length);
  51. swapl(&rep.majorVersion);
  52. swapl(&rep.minorVersion);
  53. }
  54. WriteToClient(client, sizeof(xRRQueryVersionReply), (char *) &rep);
  55. return (client->noClientException);
  56. }
  57. static int
  58. ProcRRSelectInput(ClientPtr client)
  59. {
  60. REQUEST(xRRSelectInputReq);
  61. rrClientPriv(client);
  62. RRTimesPtr pTimes;
  63. WindowPtr pWin;
  64. RREventPtr pRREvent, *pHead;
  65. XID clientResource;
  66. REQUEST_SIZE_MATCH(xRRSelectInputReq);
  67. pWin = SecurityLookupWindow(stuff->window, client, SecurityWriteAccess);
  68. if (!pWin)
  69. return BadWindow;
  70. pHead = (RREventPtr *) SecurityLookupIDByType(client,
  71. pWin->drawable.id,
  72. RREventType,
  73. SecurityWriteAccess);
  74. if (stuff->enable & (RRScreenChangeNotifyMask |
  75. RRCrtcChangeNotifyMask | RROutputChangeNotifyMask)) {
  76. ScreenPtr pScreen = pWin->drawable.pScreen;
  77. rrScrPriv(pScreen);
  78. pRREvent = NULL;
  79. if (pHead) {
  80. /* check for existing entry. */
  81. for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next)
  82. if (pRREvent->client == client)
  83. break;
  84. }
  85. if (!pRREvent) {
  86. /* build the entry */
  87. pRREvent = malloc(sizeof(RREventRec));
  88. if (!pRREvent)
  89. return BadAlloc;
  90. pRREvent->next = 0;
  91. pRREvent->client = client;
  92. pRREvent->window = pWin;
  93. pRREvent->mask = stuff->enable;
  94. /*
  95. * add a resource that will be deleted when
  96. * the client goes away
  97. */
  98. clientResource = FakeClientID(client->index);
  99. pRREvent->clientResource = clientResource;
  100. if (!AddResource(clientResource, RRClientType, (pointer) pRREvent))
  101. return BadAlloc;
  102. /*
  103. * create a resource to contain a pointer to the list
  104. * of clients selecting input. This must be indirect as
  105. * the list may be arbitrarily rearranged which cannot be
  106. * done through the resource database.
  107. */
  108. if (!pHead) {
  109. pHead = malloc(sizeof(RREventPtr));
  110. if (!pHead ||
  111. !AddResource(pWin->drawable.id, RREventType,
  112. (pointer) pHead)) {
  113. FreeResource(clientResource, RT_NONE);
  114. return BadAlloc;
  115. }
  116. *pHead = 0;
  117. }
  118. pRREvent->next = *pHead;
  119. *pHead = pRREvent;
  120. }
  121. /*
  122. * Now see if the client needs an event
  123. */
  124. if (pScrPriv && (pRREvent->mask & RRScreenChangeNotifyMask)) {
  125. pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum];
  126. if (CompareTimeStamps(pTimes->setTime,
  127. pScrPriv->lastSetTime) != 0 ||
  128. CompareTimeStamps(pTimes->configTime,
  129. pScrPriv->lastConfigTime) != 0) {
  130. RRDeliverScreenEvent(client, pWin, pScreen);
  131. }
  132. }
  133. }
  134. else if (stuff->enable == 0) {
  135. /* delete the interest */
  136. if (pHead) {
  137. RREventPtr pNewRREvent = 0;
  138. for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) {
  139. if (pRREvent->client == client)
  140. break;
  141. pNewRREvent = pRREvent;
  142. }
  143. if (pRREvent) {
  144. FreeResource(pRREvent->clientResource, RRClientType);
  145. if (pNewRREvent)
  146. pNewRREvent->next = pRREvent->next;
  147. else
  148. *pHead = pRREvent->next;
  149. free(pRREvent);
  150. }
  151. }
  152. }
  153. else {
  154. client->errorValue = stuff->enable;
  155. return BadValue;
  156. }
  157. return Success;
  158. }
  159. int (*ProcRandrVector[RRNumberRequests]) (ClientPtr) = {
  160. ProcRRQueryVersion, /* 0 */
  161. /* we skip 1 to make old clients fail pretty immediately */
  162. NULL, /* 1 ProcRandrOldGetScreenInfo */
  163. /* V1.0 apps share the same set screen config request id */
  164. ProcRRSetScreenConfig, /* 2 */
  165. NULL, /* 3 ProcRandrOldScreenChangeSelectInput */
  166. /* 3 used to be ScreenChangeSelectInput; deprecated */
  167. ProcRRSelectInput, /* 4 */
  168. ProcRRGetScreenInfo, /* 5 */
  169. /* V1.2 additions */
  170. ProcRRGetScreenSizeRange, /* 6 */
  171. ProcRRSetScreenSize, /* 7 */
  172. ProcRRGetScreenResources, /* 8 */
  173. ProcRRGetOutputInfo, /* 9 */
  174. ProcRRListOutputProperties, /* 10 */
  175. ProcRRQueryOutputProperty, /* 11 */
  176. ProcRRConfigureOutputProperty, /* 12 */
  177. ProcRRChangeOutputProperty, /* 13 */
  178. ProcRRDeleteOutputProperty, /* 14 */
  179. ProcRRGetOutputProperty, /* 15 */
  180. ProcRRCreateMode, /* 16 */
  181. ProcRRDestroyMode, /* 17 */
  182. ProcRRAddOutputMode, /* 18 */
  183. ProcRRDeleteOutputMode, /* 19 */
  184. ProcRRGetCrtcInfo, /* 20 */
  185. ProcRRSetCrtcConfig, /* 21 */
  186. ProcRRGetCrtcGammaSize, /* 22 */
  187. ProcRRGetCrtcGamma, /* 23 */
  188. ProcRRSetCrtcGamma, /* 24 */
  189. };