Add patch that contain Mali fixes.
[deb_xorg-server.git] / randr / rrdispatch.c
CommitLineData
a09e091a
JB
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 version_compare(pRRClient->major_version, pRRClient->minor_version,
32 1, 1) >= 0;
33}
34
35static int
36ProcRRQueryVersion(ClientPtr client)
37{
38 xRRQueryVersionReply rep = {
39 .type = X_Reply,
40 .sequenceNumber = client->sequence,
41 .length = 0
42 };
43 REQUEST(xRRQueryVersionReq);
44 rrClientPriv(client);
45
46 REQUEST_SIZE_MATCH(xRRQueryVersionReq);
47 pRRClient->major_version = stuff->majorVersion;
48 pRRClient->minor_version = stuff->minorVersion;
49
50 if (version_compare(stuff->majorVersion, stuff->minorVersion,
51 SERVER_RANDR_MAJOR_VERSION,
52 SERVER_RANDR_MINOR_VERSION) < 0) {
53 rep.majorVersion = stuff->majorVersion;
54 rep.minorVersion = stuff->minorVersion;
55 }
56 else {
57 rep.majorVersion = SERVER_RANDR_MAJOR_VERSION;
58 rep.minorVersion = SERVER_RANDR_MINOR_VERSION;
59 }
60
61 if (client->swapped) {
62 swaps(&rep.sequenceNumber);
63 swapl(&rep.length);
64 swapl(&rep.majorVersion);
65 swapl(&rep.minorVersion);
66 }
67 WriteToClient(client, sizeof(xRRQueryVersionReply), &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 RRProviderPropertyNotifyMask)) {
96 ScreenPtr pScreen = pWin->drawable.pScreen;
97
98 rrScrPriv(pScreen);
99
100 pRREvent = NULL;
101 if (pHead) {
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 /* build the entry */
110 pRREvent = (RREventPtr) malloc(sizeof(RREventRec));
111 if (!pRREvent)
112 return BadAlloc;
113 pRREvent->next = 0;
114 pRREvent->client = client;
115 pRREvent->window = pWin;
116 pRREvent->mask = stuff->enable;
117 /*
118 * add a resource that will be deleted when
119 * the client goes away
120 */
121 clientResource = FakeClientID(client->index);
122 pRREvent->clientResource = clientResource;
123 if (!AddResource(clientResource, RRClientType, (pointer) pRREvent))
124 return BadAlloc;
125 /*
126 * create a resource to contain a pointer to the list
127 * of clients selecting input. This must be indirect as
128 * the list may be arbitrarily rearranged which cannot be
129 * done through the resource database.
130 */
131 if (!pHead) {
132 pHead = (RREventPtr *) malloc(sizeof(RREventPtr));
133 if (!pHead ||
134 !AddResource(pWin->drawable.id, RREventType,
135 (pointer) pHead)) {
136 FreeResource(clientResource, RT_NONE);
137 return BadAlloc;
138 }
139 *pHead = 0;
140 }
141 pRREvent->next = *pHead;
142 *pHead = pRREvent;
143 }
144 /*
145 * Now see if the client needs an event
146 */
147 if (pScrPriv) {
148 pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum];
149 if (CompareTimeStamps(pTimes->setTime,
150 pScrPriv->lastSetTime) != 0 ||
151 CompareTimeStamps(pTimes->configTime,
152 pScrPriv->lastConfigTime) != 0) {
153 if (pRREvent->mask & RRScreenChangeNotifyMask) {
154 RRDeliverScreenEvent(client, pWin, pScreen);
155 }
156
157 if (pRREvent->mask & RRCrtcChangeNotifyMask) {
158 int i;
159
160 for (i = 0; i < pScrPriv->numCrtcs; i++) {
161 RRDeliverCrtcEvent(client, pWin, pScrPriv->crtcs[i]);
162 }
163 }
164
165 if (pRREvent->mask & RROutputChangeNotifyMask) {
166 int i;
167
168 for (i = 0; i < pScrPriv->numOutputs; i++) {
169 RRDeliverOutputEvent(client, pWin,
170 pScrPriv->outputs[i]);
171 }
172 }
173
174 /* We don't check for RROutputPropertyNotifyMask, as randrproto.txt doesn't
175 * say if there ought to be notifications of changes to output properties
176 * if those changes occurred before the time RRSelectInput is called.
177 */
178 }
179 }
180 }
181 else if (stuff->enable == 0) {
182 /* delete the interest */
183 if (pHead) {
184 RREventPtr pNewRREvent = 0;
185
186 for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) {
187 if (pRREvent->client == client)
188 break;
189 pNewRREvent = pRREvent;
190 }
191 if (pRREvent) {
192 FreeResource(pRREvent->clientResource, RRClientType);
193 if (pNewRREvent)
194 pNewRREvent->next = pRREvent->next;
195 else
196 *pHead = pRREvent->next;
197 free(pRREvent);
198 }
199 }
200 }
201 else {
202 client->errorValue = stuff->enable;
203 return BadValue;
204 }
205 return Success;
206}
207
208int (*ProcRandrVector[RRNumberRequests]) (ClientPtr) = {
209 ProcRRQueryVersion, /* 0 */
210/* we skip 1 to make old clients fail pretty immediately */
211 NULL, /* 1 ProcRandrOldGetScreenInfo */
212/* V1.0 apps share the same set screen config request id */
213 ProcRRSetScreenConfig, /* 2 */
214 NULL, /* 3 ProcRandrOldScreenChangeSelectInput */
215/* 3 used to be ScreenChangeSelectInput; deprecated */
216 ProcRRSelectInput, /* 4 */
217 ProcRRGetScreenInfo, /* 5 */
218/* V1.2 additions */
219 ProcRRGetScreenSizeRange, /* 6 */
220 ProcRRSetScreenSize, /* 7 */
221 ProcRRGetScreenResources, /* 8 */
222 ProcRRGetOutputInfo, /* 9 */
223 ProcRRListOutputProperties, /* 10 */
224 ProcRRQueryOutputProperty, /* 11 */
225 ProcRRConfigureOutputProperty, /* 12 */
226 ProcRRChangeOutputProperty, /* 13 */
227 ProcRRDeleteOutputProperty, /* 14 */
228 ProcRRGetOutputProperty, /* 15 */
229 ProcRRCreateMode, /* 16 */
230 ProcRRDestroyMode, /* 17 */
231 ProcRRAddOutputMode, /* 18 */
232 ProcRRDeleteOutputMode, /* 19 */
233 ProcRRGetCrtcInfo, /* 20 */
234 ProcRRSetCrtcConfig, /* 21 */
235 ProcRRGetCrtcGammaSize, /* 22 */
236 ProcRRGetCrtcGamma, /* 23 */
237 ProcRRSetCrtcGamma, /* 24 */
238/* V1.3 additions */
239 ProcRRGetScreenResourcesCurrent, /* 25 */
240 ProcRRSetCrtcTransform, /* 26 */
241 ProcRRGetCrtcTransform, /* 27 */
242 ProcRRGetPanning, /* 28 */
243 ProcRRSetPanning, /* 29 */
244 ProcRRSetOutputPrimary, /* 30 */
245 ProcRRGetOutputPrimary, /* 31 */
246/* V1.4 additions */
247 ProcRRGetProviders, /* 32 */
248 ProcRRGetProviderInfo, /* 33 */
249 ProcRRSetProviderOffloadSink, /* 34 */
250 ProcRRSetProviderOutputSource, /* 35 */
251 ProcRRListProviderProperties, /* 36 */
252 ProcRRQueryProviderProperty, /* 37 */
253 ProcRRConfigureProviderProperty, /* 38 */
254 ProcRRChangeProviderProperty, /* 39 */
255 ProcRRDeleteProviderProperty, /* 40 */
256 ProcRRGetProviderProperty, /* 41 */
257};