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