File: | randr/rrprovider.c |
Location: | line 211, column 18 |
Description: | Array access (from variable 'crtcs') results in a null pointer dereference |
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 | ||||
28 | RESTYPE RRProviderType; | |||
29 | ||||
30 | /* | |||
31 | * Initialize provider type error value | |||
32 | */ | |||
33 | void | |||
34 | RRProviderInitErrorValue(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 | ||||
49 | int | |||
50 | ProcRRGetProviders (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) | |||
67 | return rc; | |||
68 | ||||
69 | pScreen = pWin->drawable.pScreen; | |||
70 | ||||
71 | pScrPriv = rrGetScrPriv(pScreen)((rrScrPrivPtr)dixLookupPrivate(&(pScreen)->devPrivates , (&rrPrivKeyRec))); | |||
72 | ||||
73 | if (pScrPriv->provider) | |||
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) | |||
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) { | |||
111 | extra = malloc(extraLen); | |||
112 | if (!extra) | |||
113 | return BadAlloc11; | |||
114 | } else | |||
115 | extra = NULL((void*)0); | |||
116 | ||||
117 | providers = (RRProvider *)extra; | |||
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); | |||
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 | ||||
145 | int | |||
146 | ProcRRGetProviderInfo (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 | ||||
280 | int | |||
281 | ProcRRSetProviderOutputSource(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 | ||||
315 | int | |||
316 | ProcRRSetProviderOffloadSink(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 | ||||
347 | RRProviderPtr | |||
348 | RRProviderCreate(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 | */ | |||
377 | void | |||
378 | RRProviderDestroy (RRProviderPtr provider) | |||
379 | { | |||
380 | FreeResource (provider->id, 0); | |||
381 | } | |||
382 | ||||
383 | void | |||
384 | RRProviderSetCapabilities(RRProviderPtr provider, uint32_t capabilities) | |||
385 | { | |||
386 | provider->capabilities = capabilities; | |||
387 | } | |||
388 | ||||
389 | static int | |||
390 | RRProviderDestroyResource (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 | ||||
407 | Bool | |||
408 | RRProviderInit(void) | |||
409 | { | |||
410 | RRProviderType = CreateNewResourceType(RRProviderDestroyResource, "Provider"); | |||
411 | if (!RRProviderType) | |||
412 | return FALSE0; | |||
413 | ||||
414 | return TRUE1; | |||
415 | } | |||
416 | ||||
417 | extern _X_EXPORT__attribute__((visibility("default"))) Bool | |||
418 | RRProviderLookup(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 | ||||
427 | void | |||
428 | RRDeliverProviderEvent(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 | } |