Bug Summary

File:randr/rrprovider.c
Location:line 120, column 13
Description:Array access (from variable 'providers') results in a null pointer dereference

Annotated Source Code

1/*
2 * Copyright © 2012 Red Hat Inc.
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 * Authors: Dave Airlie
23 */
24
25#include "randrstr.h"
26#include "swaprep.h"
27
28RESTYPE RRProviderType;
29
30/*
31 * Initialize provider type error value
32 */
33void
34RRProviderInitErrorValue(void)
35{
36 SetResourceTypeErrorValue(RRProviderType, RRErrorBase + BadRRProvider3);
37}
38
39#define ADD_PROVIDER(_pScreen)do { pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&((_pScreen
))->devPrivates, (&rrPrivKeyRec))); if (pScrPriv->provider
) { providers[count_providers] = pScrPriv->provider->id
; if (client->swapped) do { if (sizeof(*(&providers[count_providers
])) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(
&providers[count_providers]) & 3) && ((uintptr_t
)(&providers[count_providers]) & 3) == 0) *(&providers
[count_providers]) = lswapl(*(&providers[count_providers]
)); else swap_uint32((uint32_t *)(&providers[count_providers
])); } while (0); count_providers++; } } while(0)
do { \
40 pScrPriv = rrGetScrPriv((_pScreen))((rrScrPrivPtr)dixLookupPrivate(&((_pScreen))->devPrivates
, (&rrPrivKeyRec)))
; \
41 if (pScrPriv->provider) { \
42 providers[count_providers] = pScrPriv->provider->id; \
43 if (client->swapped) \
44 swapl(&providers[count_providers])do { if (sizeof(*(&providers[count_providers])) != 4) wrong_size
(); if (__builtin_constant_p((uintptr_t)(&providers[count_providers
]) & 3) && ((uintptr_t)(&providers[count_providers
]) & 3) == 0) *(&providers[count_providers]) = lswapl
(*(&providers[count_providers])); else swap_uint32((uint32_t
*)(&providers[count_providers])); } while (0)
; \
45 count_providers++; \
46 } \
47 } while(0)
48
49int
50ProcRRGetProviders (ClientPtr client)
51{
52 REQUEST(xRRGetProvidersReq)xRRGetProvidersReq *stuff = (xRRGetProvidersReq *)client->
requestBuffer
;
53 xRRGetProvidersReply rep;
54 WindowPtr pWin;
55 ScreenPtr pScreen;
56 rrScrPrivPtr pScrPriv;
57 int rc;
58 CARD8 *extra;
59 unsigned int extraLen;
60 RRProvider *providers;
61 int total_providers = 0, count_providers = 0;
62 ScreenPtr iter;
63
64 REQUEST_SIZE_MATCH(xRRGetProvidersReq)if ((sizeof(xRRGetProvidersReq) >> 2) != client->req_len
) return(16)
;
65 rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess(1<<4));
66 if (rc != Success0)
1
Assuming 'rc' is equal to 0
2
Taking false branch
67 return rc;
68
69 pScreen = pWin->drawable.pScreen;
70
71 pScrPriv = rrGetScrPriv(pScreen)((rrScrPrivPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&rrPrivKeyRec)))
;
72
73 if (pScrPriv->provider)
3
Taking false branch
74 total_providers++;
75 xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head)for (iter = ((void*)0), iter = (typeof(*iter) *)((char *)((&
pScreen->output_slave_list)->next) - __builtin_offsetof
(typeof(*iter), output_head)); &iter->output_head != (
&pScreen->output_slave_list); iter = (typeof(*iter) *)
((char *)(iter->output_head.next) - __builtin_offsetof(typeof
(*iter), output_head)))
{
76 pScrPriv = rrGetScrPriv(iter)((rrScrPrivPtr)dixLookupPrivate(&(iter)->devPrivates, (
&rrPrivKeyRec)))
;
77 total_providers += pScrPriv->provider ? 1 : 0;
78 }
79 xorg_list_for_each_entry(iter, &pScreen->offload_slave_list, offload_head)for (iter = ((void*)0), iter = (typeof(*iter) *)((char *)((&
pScreen->offload_slave_list)->next) - __builtin_offsetof
(typeof(*iter), offload_head)); &iter->offload_head !=
(&pScreen->offload_slave_list); iter = (typeof(*iter)
*)((char *)(iter->offload_head.next) - __builtin_offsetof
(typeof(*iter), offload_head)))
{
80 pScrPriv = rrGetScrPriv(iter)((rrScrPrivPtr)dixLookupPrivate(&(iter)->devPrivates, (
&rrPrivKeyRec)))
;
81 total_providers += pScrPriv->provider ? 1 : 0;
82 }
83 xorg_list_for_each_entry(iter, &pScreen->unattached_list, unattached_head)for (iter = ((void*)0), iter = (typeof(*iter) *)((char *)((&
pScreen->unattached_list)->next) - __builtin_offsetof(typeof
(*iter), unattached_head)); &iter->unattached_head != (
&pScreen->unattached_list); iter = (typeof(*iter) *)((
char *)(iter->unattached_head.next) - __builtin_offsetof(typeof
(*iter), unattached_head)))
{
84 pScrPriv = rrGetScrPriv(iter)((rrScrPrivPtr)dixLookupPrivate(&(iter)->devPrivates, (
&rrPrivKeyRec)))
;
85 total_providers += pScrPriv->provider ? 1 : 0;
86 }
87
88 pScrPriv = rrGetScrPriv(pScreen)((rrScrPrivPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&rrPrivKeyRec)))
;
89
90 if (!pScrPriv)
4
Assuming 'pScrPriv' is non-null
5
Taking false branch
91 {
92 rep = (xRRGetProvidersReply) {
93 .type = X_Reply1,
94 .sequenceNumber = client->sequence,
95 .length = 0,
96 .timestamp = currentTime.milliseconds,
97 .nProviders = 0
98 };
99 extra = NULL((void*)0);
100 extraLen = 0;
101 } else {
102 rep = (xRRGetProvidersReply) {
103 .type = X_Reply1,
104 .sequenceNumber = client->sequence,
105 .timestamp = pScrPriv->lastSetTime.milliseconds,
106 .nProviders = total_providers,
107 .length = total_providers
108 };
109 extraLen = rep.length << 2;
110 if (extraLen) {
6
Taking false branch
111 extra = malloc(extraLen);
112 if (!extra)
113 return BadAlloc11;
114 } else
115 extra = NULL((void*)0);
7
Null pointer value stored to 'extra'
116
117 providers = (RRProvider *)extra;
8
Null pointer value stored to 'providers'
118 ADD_PROVIDER(pScreen)do { pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&((pScreen
))->devPrivates, (&rrPrivKeyRec))); if (pScrPriv->provider
) { providers[count_providers] = pScrPriv->provider->id
; if (client->swapped) do { if (sizeof(*(&providers[count_providers
])) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(
&providers[count_providers]) & 3) && ((uintptr_t
)(&providers[count_providers]) & 3) == 0) *(&providers
[count_providers]) = lswapl(*(&providers[count_providers]
)); else swap_uint32((uint32_t *)(&providers[count_providers
])); } while (0); count_providers++; } } while(0)
;
119 xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head)for (iter = ((void*)0), iter = (typeof(*iter) *)((char *)((&
pScreen->output_slave_list)->next) - __builtin_offsetof
(typeof(*iter), output_head)); &iter->output_head != (
&pScreen->output_slave_list); iter = (typeof(*iter) *)
((char *)(iter->output_head.next) - __builtin_offsetof(typeof
(*iter), output_head)))
{
120 ADD_PROVIDER(iter)do { pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&((iter))
->devPrivates, (&rrPrivKeyRec))); if (pScrPriv->provider
) { providers[count_providers] = pScrPriv->provider->id
; if (client->swapped) do { if (sizeof(*(&providers[count_providers
])) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(
&providers[count_providers]) & 3) && ((uintptr_t
)(&providers[count_providers]) & 3) == 0) *(&providers
[count_providers]) = lswapl(*(&providers[count_providers]
)); else swap_uint32((uint32_t *)(&providers[count_providers
])); } while (0); count_providers++; } } while(0)
;
9
Within the expansion of the macro 'ADD_PROVIDER':
a
Array access (from variable 'providers') results in a null pointer dereference
121 }
122 xorg_list_for_each_entry(iter, &pScreen->offload_slave_list, offload_head)for (iter = ((void*)0), iter = (typeof(*iter) *)((char *)((&
pScreen->offload_slave_list)->next) - __builtin_offsetof
(typeof(*iter), offload_head)); &iter->offload_head !=
(&pScreen->offload_slave_list); iter = (typeof(*iter)
*)((char *)(iter->offload_head.next) - __builtin_offsetof
(typeof(*iter), offload_head)))
{
123 ADD_PROVIDER(iter)do { pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&((iter))
->devPrivates, (&rrPrivKeyRec))); if (pScrPriv->provider
) { providers[count_providers] = pScrPriv->provider->id
; if (client->swapped) do { if (sizeof(*(&providers[count_providers
])) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(
&providers[count_providers]) & 3) && ((uintptr_t
)(&providers[count_providers]) & 3) == 0) *(&providers
[count_providers]) = lswapl(*(&providers[count_providers]
)); else swap_uint32((uint32_t *)(&providers[count_providers
])); } while (0); count_providers++; } } while(0)
;
124 }
125 xorg_list_for_each_entry(iter, &pScreen->unattached_list, unattached_head)for (iter = ((void*)0), iter = (typeof(*iter) *)((char *)((&
pScreen->unattached_list)->next) - __builtin_offsetof(typeof
(*iter), unattached_head)); &iter->unattached_head != (
&pScreen->unattached_list); iter = (typeof(*iter) *)((
char *)(iter->unattached_head.next) - __builtin_offsetof(typeof
(*iter), unattached_head)))
{
126 ADD_PROVIDER(iter)do { pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&((iter))
->devPrivates, (&rrPrivKeyRec))); if (pScrPriv->provider
) { providers[count_providers] = pScrPriv->provider->id
; if (client->swapped) do { if (sizeof(*(&providers[count_providers
])) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(
&providers[count_providers]) & 3) && ((uintptr_t
)(&providers[count_providers]) & 3) == 0) *(&providers
[count_providers]) = lswapl(*(&providers[count_providers]
)); else swap_uint32((uint32_t *)(&providers[count_providers
])); } while (0); count_providers++; } } while(0)
;
127 }
128 }
129
130 if (client->swapped) {
131 swaps(&rep.sequenceNumber)do { if (sizeof(*(&rep.sequenceNumber)) != 2) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&rep.sequenceNumber
) & 1) && ((uintptr_t)(&rep.sequenceNumber) &
1) == 0) *(&rep.sequenceNumber) = lswaps(*(&rep.sequenceNumber
)); else swap_uint16((uint16_t *)(&rep.sequenceNumber)); }
while (0)
;
132 swapl(&rep.length)do { if (sizeof(*(&rep.length)) != 4) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&rep.length) & 3) && ((uintptr_t
)(&rep.length) & 3) == 0) *(&rep.length) = lswapl
(*(&rep.length)); else swap_uint32((uint32_t *)(&rep.
length)); } while (0)
;
133 swapl(&rep.timestamp)do { if (sizeof(*(&rep.timestamp)) != 4) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&rep.timestamp) & 3
) && ((uintptr_t)(&rep.timestamp) & 3) == 0) *
(&rep.timestamp) = lswapl(*(&rep.timestamp)); else swap_uint32
((uint32_t *)(&rep.timestamp)); } while (0)
;
134 swaps(&rep.nProviders)do { if (sizeof(*(&rep.nProviders)) != 2) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&rep.nProviders) &
1) && ((uintptr_t)(&rep.nProviders) & 1) == 0
) *(&rep.nProviders) = lswaps(*(&rep.nProviders)); else
swap_uint16((uint16_t *)(&rep.nProviders)); } while (0)
;
135 }
136 WriteToClient(client, sizeof(xRRGetProvidersReply), (char *)&rep);
137 if (extraLen)
138 {
139 WriteToClient (client, extraLen, (char *) extra);
140 free(extra);
141 }
142 return Success0;
143}
144
145int
146ProcRRGetProviderInfo (ClientPtr client)
147{
148 REQUEST(xRRGetProviderInfoReq)xRRGetProviderInfoReq *stuff = (xRRGetProviderInfoReq *)client
->requestBuffer
;
149 xRRGetProviderInfoReply rep;
150 rrScrPrivPtr pScrPriv, pScrProvPriv;
151 RRProviderPtr provider;
152 ScreenPtr pScreen;
153 CARD8 *extra;
154 unsigned int extraLen = 0;
155 RRCrtc *crtcs;
156 RROutput *outputs;
157 int i;
158 char *name;
159 ScreenPtr provscreen;
160 RRProvider *providers;
161 uint32_t *prov_cap;
162
163 REQUEST_SIZE_MATCH(xRRGetProviderInfoReq)if ((sizeof(xRRGetProviderInfoReq) >> 2) != client->
req_len) return(16)
;
164 VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess){ int rc = dixLookupResourceByType((void **)&(provider), stuff
->provider, RRProviderType, client, (1<<0)); if (rc !=
0) { client->errorValue = stuff->provider; return rc; }
}
;
165
166 pScreen = provider->pScreen;
167 pScrPriv = rrGetScrPriv(pScreen)((rrScrPrivPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&rrPrivKeyRec)))
;
168
169 rep = (xRRGetProviderInfoReply) {
170 .type = X_Reply1,
171 .status = RRSetConfigSuccess0,
172 .sequenceNumber = client->sequence,
173 .length = 0,
174 .capabilities = provider->capabilities,
175 .nameLength = provider->nameLength,
176 .timestamp = pScrPriv->lastSetTime.milliseconds,
177 .nCrtcs = pScrPriv->numCrtcs,
178 .nOutputs = pScrPriv->numOutputs,
179 .nAssociatedProviders = 0
180 };
181
182 /* count associated providers */
183 if (provider->offload_sink)
184 rep.nAssociatedProviders++;
185 if (provider->output_source)
186 rep.nAssociatedProviders++;
187 xorg_list_for_each_entry(provscreen, &pScreen->output_slave_list, output_head)for (provscreen = ((void*)0), provscreen = (typeof(*provscreen
) *)((char *)((&pScreen->output_slave_list)->next) -
__builtin_offsetof(typeof(*provscreen), output_head)); &
provscreen->output_head != (&pScreen->output_slave_list
); provscreen = (typeof(*provscreen) *)((char *)(provscreen->
output_head.next) - __builtin_offsetof(typeof(*provscreen), output_head
)))
188 rep.nAssociatedProviders++;
189 xorg_list_for_each_entry(provscreen, &pScreen->offload_slave_list, offload_head)for (provscreen = ((void*)0), provscreen = (typeof(*provscreen
) *)((char *)((&pScreen->offload_slave_list)->next)
- __builtin_offsetof(typeof(*provscreen), offload_head)); &
provscreen->offload_head != (&pScreen->offload_slave_list
); provscreen = (typeof(*provscreen) *)((char *)(provscreen->
offload_head.next) - __builtin_offsetof(typeof(*provscreen), offload_head
)))
190 rep.nAssociatedProviders++;
191
192 rep.length = (pScrPriv->numCrtcs + pScrPriv->numOutputs +
193 (rep.nAssociatedProviders * 2) + bytes_to_int32(rep.nameLength));
194
195 extraLen = rep.length << 2;
196 if (extraLen) {
197 extra = malloc(extraLen);
198 if (!extra)
199 return BadAlloc11;
200 }
201 else
202 extra = NULL((void*)0);
203
204 crtcs = (RRCrtc *)extra;
205 outputs = (RROutput *)(crtcs + rep.nCrtcs);
206 providers = (RRProvider *)(outputs + rep.nOutputs);
207 prov_cap = (unsigned int *)(providers + rep.nAssociatedProviders);
208 name = (char *)(prov_cap + rep.nAssociatedProviders);
209
210 for (i = 0; i < pScrPriv->numCrtcs; i++) {
211 crtcs[i] = pScrPriv->crtcs[i]->id;
212 if (client->swapped)
213 swapl(&crtcs[i])do { if (sizeof(*(&crtcs[i])) != 4) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&crtcs[i]) & 3) && ((uintptr_t)(
&crtcs[i]) & 3) == 0) *(&crtcs[i]) = lswapl(*(&
crtcs[i])); else swap_uint32((uint32_t *)(&crtcs[i])); } while
(0)
;
214 }
215
216 for (i = 0; i < pScrPriv->numOutputs; i++) {
217 outputs[i] = pScrPriv->outputs[i]->id;
218 if (client->swapped)
219 swapl(&outputs[i])do { if (sizeof(*(&outputs[i])) != 4) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&outputs[i]) & 3) && ((uintptr_t
)(&outputs[i]) & 3) == 0) *(&outputs[i]) = lswapl
(*(&outputs[i])); else swap_uint32((uint32_t *)(&outputs
[i])); } while (0)
;
220 }
221
222 i = 0;
223 if (provider->offload_sink) {
224 providers[i] = provider->offload_sink->id;
225 if (client->swapped)
226 swapl(&providers[i])do { if (sizeof(*(&providers[i])) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&providers[i]) & 3) &&
((uintptr_t)(&providers[i]) & 3) == 0) *(&providers
[i]) = lswapl(*(&providers[i])); else swap_uint32((uint32_t
*)(&providers[i])); } while (0)
;
227 prov_cap[i] = RR_Capability_SinkOffload8;
228 if (client->swapped)
229 swapl(&prov_cap[i])do { if (sizeof(*(&prov_cap[i])) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&prov_cap[i]) & 3) &&
((uintptr_t)(&prov_cap[i]) & 3) == 0) *(&prov_cap
[i]) = lswapl(*(&prov_cap[i])); else swap_uint32((uint32_t
*)(&prov_cap[i])); } while (0)
;
230 i++;
231 }
232 if (provider->output_source) {
233 providers[i] = provider->output_source->id;
234 if (client->swapped)
235 swapl(&providers[i])do { if (sizeof(*(&providers[i])) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&providers[i]) & 3) &&
((uintptr_t)(&providers[i]) & 3) == 0) *(&providers
[i]) = lswapl(*(&providers[i])); else swap_uint32((uint32_t
*)(&providers[i])); } while (0)
;
236 prov_cap[i] = RR_Capability_SourceOutput1;
237 swapl(&prov_cap[i])do { if (sizeof(*(&prov_cap[i])) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&prov_cap[i]) & 3) &&
((uintptr_t)(&prov_cap[i]) & 3) == 0) *(&prov_cap
[i]) = lswapl(*(&prov_cap[i])); else swap_uint32((uint32_t
*)(&prov_cap[i])); } while (0)
;
238 i++;
239 }
240 xorg_list_for_each_entry(provscreen, &pScreen->output_slave_list, output_head)for (provscreen = ((void*)0), provscreen = (typeof(*provscreen
) *)((char *)((&pScreen->output_slave_list)->next) -
__builtin_offsetof(typeof(*provscreen), output_head)); &
provscreen->output_head != (&pScreen->output_slave_list
); provscreen = (typeof(*provscreen) *)((char *)(provscreen->
output_head.next) - __builtin_offsetof(typeof(*provscreen), output_head
)))
{
241 pScrProvPriv = rrGetScrPriv(provscreen)((rrScrPrivPtr)dixLookupPrivate(&(provscreen)->devPrivates
, (&rrPrivKeyRec)))
;
242 providers[i] = pScrProvPriv->provider->id;
243 if (client->swapped)
244 swapl(&providers[i])do { if (sizeof(*(&providers[i])) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&providers[i]) & 3) &&
((uintptr_t)(&providers[i]) & 3) == 0) *(&providers
[i]) = lswapl(*(&providers[i])); else swap_uint32((uint32_t
*)(&providers[i])); } while (0)
;
245 prov_cap[i] = RR_Capability_SinkOutput2;
246 if (client->swapped)
247 swapl(&prov_cap[i])do { if (sizeof(*(&prov_cap[i])) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&prov_cap[i]) & 3) &&
((uintptr_t)(&prov_cap[i]) & 3) == 0) *(&prov_cap
[i]) = lswapl(*(&prov_cap[i])); else swap_uint32((uint32_t
*)(&prov_cap[i])); } while (0)
;
248 i++;
249 }
250 xorg_list_for_each_entry(provscreen, &pScreen->offload_slave_list, offload_head)for (provscreen = ((void*)0), provscreen = (typeof(*provscreen
) *)((char *)((&pScreen->offload_slave_list)->next)
- __builtin_offsetof(typeof(*provscreen), offload_head)); &
provscreen->offload_head != (&pScreen->offload_slave_list
); provscreen = (typeof(*provscreen) *)((char *)(provscreen->
offload_head.next) - __builtin_offsetof(typeof(*provscreen), offload_head
)))
{
251 pScrProvPriv = rrGetScrPriv(provscreen)((rrScrPrivPtr)dixLookupPrivate(&(provscreen)->devPrivates
, (&rrPrivKeyRec)))
;
252 providers[i] = pScrProvPriv->provider->id;
253 if (client->swapped)
254 swapl(&providers[i])do { if (sizeof(*(&providers[i])) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&providers[i]) & 3) &&
((uintptr_t)(&providers[i]) & 3) == 0) *(&providers
[i]) = lswapl(*(&providers[i])); else swap_uint32((uint32_t
*)(&providers[i])); } while (0)
;
255 prov_cap[i] = RR_Capability_SourceOffload4;
256 if (client->swapped)
257 swapl(&prov_cap[i])do { if (sizeof(*(&prov_cap[i])) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&prov_cap[i]) & 3) &&
((uintptr_t)(&prov_cap[i]) & 3) == 0) *(&prov_cap
[i]) = lswapl(*(&prov_cap[i])); else swap_uint32((uint32_t
*)(&prov_cap[i])); } while (0)
;
258 i++;
259 }
260
261
262 memcpy(name, provider->name, rep.nameLength)__builtin___memcpy_chk (name, provider->name, rep.nameLength
, __builtin_object_size (name, 0))
;
263 if (client->swapped) {
264 swaps(&rep.sequenceNumber)do { if (sizeof(*(&rep.sequenceNumber)) != 2) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&rep.sequenceNumber
) & 1) && ((uintptr_t)(&rep.sequenceNumber) &
1) == 0) *(&rep.sequenceNumber) = lswaps(*(&rep.sequenceNumber
)); else swap_uint16((uint16_t *)(&rep.sequenceNumber)); }
while (0)
;
265 swapl(&rep.length)do { if (sizeof(*(&rep.length)) != 4) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&rep.length) & 3) && ((uintptr_t
)(&rep.length) & 3) == 0) *(&rep.length) = lswapl
(*(&rep.length)); else swap_uint32((uint32_t *)(&rep.
length)); } while (0)
;
266 swapl(&rep.capabilities)do { if (sizeof(*(&rep.capabilities)) != 4) wrong_size();
if (__builtin_constant_p((uintptr_t)(&rep.capabilities) &
3) && ((uintptr_t)(&rep.capabilities) & 3) ==
0) *(&rep.capabilities) = lswapl(*(&rep.capabilities
)); else swap_uint32((uint32_t *)(&rep.capabilities)); } while
(0)
;
267 swaps(&rep.nCrtcs)do { if (sizeof(*(&rep.nCrtcs)) != 2) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&rep.nCrtcs) & 1) && ((uintptr_t
)(&rep.nCrtcs) & 1) == 0) *(&rep.nCrtcs) = lswaps
(*(&rep.nCrtcs)); else swap_uint16((uint16_t *)(&rep.
nCrtcs)); } while (0)
;
268 swaps(&rep.nOutputs)do { if (sizeof(*(&rep.nOutputs)) != 2) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&rep.nOutputs) & 1) &&
((uintptr_t)(&rep.nOutputs) & 1) == 0) *(&rep.nOutputs
) = lswaps(*(&rep.nOutputs)); else swap_uint16((uint16_t *
)(&rep.nOutputs)); } while (0)
;
269 swaps(&rep.nameLength)do { if (sizeof(*(&rep.nameLength)) != 2) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&rep.nameLength) &
1) && ((uintptr_t)(&rep.nameLength) & 1) == 0
) *(&rep.nameLength) = lswaps(*(&rep.nameLength)); else
swap_uint16((uint16_t *)(&rep.nameLength)); } while (0)
;
270 }
271 WriteToClient(client, sizeof(xRRGetProviderInfoReply), (char *)&rep);
272 if (extraLen)
273 {
274 WriteToClient (client, extraLen, (char *) extra);
275 free(extra);
276 }
277 return Success0;
278}
279
280int
281ProcRRSetProviderOutputSource(ClientPtr client)
282{
283 REQUEST(xRRSetProviderOutputSourceReq)xRRSetProviderOutputSourceReq *stuff = (xRRSetProviderOutputSourceReq
*)client->requestBuffer
;
284 rrScrPrivPtr pScrPriv;
285 RRProviderPtr provider, source_provider = NULL((void*)0);
286 ScreenPtr pScreen;
287
288 REQUEST_SIZE_MATCH(xRRSetProviderOutputSourceReq)if ((sizeof(xRRSetProviderOutputSourceReq) >> 2) != client
->req_len) return(16)
;
289
290 VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess){ int rc = dixLookupResourceByType((void **)&(provider), stuff
->provider, RRProviderType, client, (1<<0)); if (rc !=
0) { client->errorValue = stuff->provider; return rc; }
}
;
291
292 if (!(provider->capabilities & RR_Capability_SinkOutput2))
293 return BadValue2;
294
295 if (stuff->source_provider) {
296 VERIFY_RR_PROVIDER(stuff->source_provider, source_provider, DixReadAccess){ int rc = dixLookupResourceByType((void **)&(source_provider
), stuff->source_provider, RRProviderType, client, (1<<
0)); if (rc != 0) { client->errorValue = stuff->source_provider
; return rc; } }
;
297
298 if (!(source_provider->capabilities & RR_Capability_SourceOutput1))
299 return BadValue2;
300 }
301
302 pScreen = provider->pScreen;
303 pScrPriv = rrGetScrPriv(pScreen)((rrScrPrivPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&rrPrivKeyRec)))
;
304
305 pScrPriv->rrProviderSetOutputSource(pScreen, provider, source_provider);
306
307 provider->changed = TRUE1;
308 RRSetChanged(pScreen);
309
310 RRTellChanged (pScreen);
311
312 return Success0;
313}
314
315int
316ProcRRSetProviderOffloadSink(ClientPtr client)
317{
318 REQUEST(xRRSetProviderOffloadSinkReq)xRRSetProviderOffloadSinkReq *stuff = (xRRSetProviderOffloadSinkReq
*)client->requestBuffer
;
319 rrScrPrivPtr pScrPriv;
320 RRProviderPtr provider, sink_provider = NULL((void*)0);
321 ScreenPtr pScreen;
322
323 REQUEST_SIZE_MATCH(xRRSetProviderOffloadSinkReq)if ((sizeof(xRRSetProviderOffloadSinkReq) >> 2) != client
->req_len) return(16)
;
324
325 VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess){ int rc = dixLookupResourceByType((void **)&(provider), stuff
->provider, RRProviderType, client, (1<<0)); if (rc !=
0) { client->errorValue = stuff->provider; return rc; }
}
;
326 if (!(provider->capabilities & RR_Capability_SourceOffload4))
327 return BadValue2;
328
329 if (stuff->sink_provider) {
330 VERIFY_RR_PROVIDER(stuff->sink_provider, sink_provider, DixReadAccess){ int rc = dixLookupResourceByType((void **)&(sink_provider
), stuff->sink_provider, RRProviderType, client, (1<<
0)); if (rc != 0) { client->errorValue = stuff->sink_provider
; return rc; } }
;
331 if (!(sink_provider->capabilities & RR_Capability_SinkOffload8))
332 return BadValue2;
333 }
334 pScreen = provider->pScreen;
335 pScrPriv = rrGetScrPriv(pScreen)((rrScrPrivPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&rrPrivKeyRec)))
;
336
337 pScrPriv->rrProviderSetOffloadSink(pScreen, provider, sink_provider);
338
339 provider->changed = TRUE1;
340 RRSetChanged(pScreen);
341
342 RRTellChanged (pScreen);
343
344 return Success0;
345}
346
347RRProviderPtr
348RRProviderCreate(ScreenPtr pScreen, const char *name,
349 int nameLength)
350{
351 RRProviderPtr provider;
352 rrScrPrivPtr pScrPriv;
353
354 pScrPriv = rrGetScrPriv(pScreen)((rrScrPrivPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&rrPrivKeyRec)))
;
355
356 provider = calloc(1, sizeof(RRProviderRec) + nameLength + 1);
357 if (!provider)
358 return NULL((void*)0);
359
360 provider->id = FakeClientID(0);
361 provider->pScreen = pScreen;
362 provider->name = (char *) (provider + 1);
363 provider->nameLength = nameLength;
364 memcpy(provider->name, name, nameLength)__builtin___memcpy_chk (provider->name, name, nameLength, __builtin_object_size
(provider->name, 0))
;
365 provider->name[nameLength] = '\0';
366 provider->changed = FALSE0;
367
368 if (!AddResourceDarwin_X_AddResource (provider->id, RRProviderType, (void *) provider))
369 return NULL((void*)0);
370 pScrPriv->provider = provider;
371 return provider;
372}
373
374/*
375 * Destroy a provider at shutdown
376 */
377void
378RRProviderDestroy (RRProviderPtr provider)
379{
380 FreeResource (provider->id, 0);
381}
382
383void
384RRProviderSetCapabilities(RRProviderPtr provider, uint32_t capabilities)
385{
386 provider->capabilities = capabilities;
387}
388
389static int
390RRProviderDestroyResource (void *value, XID pid)
391{
392 RRProviderPtr provider = (RRProviderPtr)value;
393 ScreenPtr pScreen = provider->pScreen;
394
395 if (pScreen)
396 {
397 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
398
399 if (pScrPriv->rrProviderDestroy)
400 (*pScrPriv->rrProviderDestroy)(pScreen, provider);
401 pScrPriv->provider = NULL((void*)0);
402 }
403 free(provider);
404 return 1;
405}
406
407Bool
408RRProviderInit(void)
409{
410 RRProviderType = CreateNewResourceType(RRProviderDestroyResource, "Provider");
411 if (!RRProviderType)
412 return FALSE0;
413
414 return TRUE1;
415}
416
417extern _X_EXPORT__attribute__((visibility("default"))) Bool
418RRProviderLookup(XID id, RRProviderPtr *provider_p)
419{
420 int rc = dixLookupResourceByType((void **)provider_p, id,
421 RRProviderType, NullClient((ClientPtr) 0), DixReadAccess(1<<0));
422 if (rc == Success0)
423 return TRUE1;
424 return FALSE0;
425}
426
427void
428RRDeliverProviderEvent(ClientPtr client, WindowPtr pWin, RRProviderPtr provider)
429{
430 ScreenPtr pScreen = pWin->drawable.pScreen;
431
432 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
433
434 xRRProviderChangeNotifyEvent pe = {
435 .type = RRNotify1 + RREventBase,
436 .subCode = RRNotify_ProviderChange3,
437 .timestamp = pScrPriv->lastSetTime.milliseconds,
438 .window = pWin->drawable.id,
439 .provider = provider->id
440 };
441
442 WriteEventsToClient(client, 1, (xEvent *) &pe);
443}