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