File: | randr/rrprovider.c |
Location: | line 123, column 13 |
Description: | Array access (from variable 'providers') 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 | if (!provider->pScreen->isGPU) | |||||
329 | return BadValue2; | |||||
330 | ||||||
331 | if (stuff->sink_provider) { | |||||
332 | 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; } }; | |||||
333 | if (!(sink_provider->capabilities & RR_Capability_SinkOffload8)) | |||||
334 | return BadValue2; | |||||
335 | } | |||||
336 | pScreen = provider->pScreen; | |||||
337 | pScrPriv = rrGetScrPriv(pScreen)((rrScrPrivPtr)dixLookupPrivate(&(pScreen)->devPrivates , (&rrPrivKeyRec))); | |||||
338 | ||||||
339 | pScrPriv->rrProviderSetOffloadSink(pScreen, provider, sink_provider); | |||||
340 | ||||||
341 | provider->changed = TRUE1; | |||||
342 | RRSetChanged(pScreen); | |||||
343 | ||||||
344 | RRTellChanged (pScreen); | |||||
345 | ||||||
346 | return Success0; | |||||
347 | } | |||||
348 | ||||||
349 | RRProviderPtr | |||||
350 | RRProviderCreate(ScreenPtr pScreen, const char *name, | |||||
351 | int nameLength) | |||||
352 | { | |||||
353 | RRProviderPtr provider; | |||||
354 | rrScrPrivPtr pScrPriv; | |||||
355 | ||||||
356 | pScrPriv = rrGetScrPriv(pScreen)((rrScrPrivPtr)dixLookupPrivate(&(pScreen)->devPrivates , (&rrPrivKeyRec))); | |||||
357 | ||||||
358 | provider = calloc(1, sizeof(RRProviderRec) + nameLength + 1); | |||||
359 | if (!provider) | |||||
360 | return NULL((void*)0); | |||||
361 | ||||||
362 | provider->id = FakeClientID(0); | |||||
363 | provider->pScreen = pScreen; | |||||
364 | provider->name = (char *) (provider + 1); | |||||
365 | provider->nameLength = nameLength; | |||||
366 | memcpy(provider->name, name, nameLength)__builtin___memcpy_chk (provider->name, name, nameLength, __builtin_object_size (provider->name, 0)); | |||||
367 | provider->name[nameLength] = '\0'; | |||||
368 | provider->changed = FALSE0; | |||||
369 | ||||||
370 | if (!AddResourceDarwin_X_AddResource (provider->id, RRProviderType, (void *) provider)) | |||||
371 | return NULL((void*)0); | |||||
372 | pScrPriv->provider = provider; | |||||
373 | return provider; | |||||
374 | } | |||||
375 | ||||||
376 | /* | |||||
377 | * Destroy a provider at shutdown | |||||
378 | */ | |||||
379 | void | |||||
380 | RRProviderDestroy (RRProviderPtr provider) | |||||
381 | { | |||||
382 | FreeResource (provider->id, 0); | |||||
383 | } | |||||
384 | ||||||
385 | void | |||||
386 | RRProviderSetCapabilities(RRProviderPtr provider, uint32_t capabilities) | |||||
387 | { | |||||
388 | provider->capabilities = capabilities; | |||||
389 | } | |||||
390 | ||||||
391 | static int | |||||
392 | RRProviderDestroyResource (void *value, XID pid) | |||||
393 | { | |||||
394 | RRProviderPtr provider = (RRProviderPtr)value; | |||||
395 | ScreenPtr pScreen = provider->pScreen; | |||||
396 | ||||||
397 | if (pScreen) | |||||
398 | { | |||||
399 | rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(& (pScreen)->devPrivates, (&rrPrivKeyRec))); | |||||
400 | ||||||
401 | if (pScrPriv->rrProviderDestroy) | |||||
402 | (*pScrPriv->rrProviderDestroy)(pScreen, provider); | |||||
403 | pScrPriv->provider = NULL((void*)0); | |||||
404 | } | |||||
405 | free(provider); | |||||
406 | return 1; | |||||
407 | } | |||||
408 | ||||||
409 | Bool | |||||
410 | RRProviderInit(void) | |||||
411 | { | |||||
412 | RRProviderType = CreateNewResourceType(RRProviderDestroyResource, "Provider"); | |||||
413 | if (!RRProviderType) | |||||
414 | return FALSE0; | |||||
415 | ||||||
416 | return TRUE1; | |||||
417 | } | |||||
418 | ||||||
419 | extern _X_EXPORT__attribute__((visibility("default"))) Bool | |||||
420 | RRProviderLookup(XID id, RRProviderPtr *provider_p) | |||||
421 | { | |||||
422 | int rc = dixLookupResourceByType((void **)provider_p, id, | |||||
423 | RRProviderType, NullClient((ClientPtr) 0), DixReadAccess(1<<0)); | |||||
424 | if (rc == Success0) | |||||
425 | return TRUE1; | |||||
426 | return FALSE0; | |||||
427 | } | |||||
428 | ||||||
429 | void | |||||
430 | RRDeliverProviderEvent(ClientPtr client, WindowPtr pWin, RRProviderPtr provider) | |||||
431 | { | |||||
432 | ScreenPtr pScreen = pWin->drawable.pScreen; | |||||
433 | ||||||
434 | rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(& (pScreen)->devPrivates, (&rrPrivKeyRec))); | |||||
435 | ||||||
436 | xRRProviderChangeNotifyEvent pe = { | |||||
437 | .type = RRNotify1 + RREventBase, | |||||
438 | .subCode = RRNotify_ProviderChange3, | |||||
439 | .timestamp = pScrPriv->lastSetTime.milliseconds, | |||||
440 | .window = pWin->drawable.id, | |||||
441 | .provider = provider->id | |||||
442 | }; | |||||
443 | ||||||
444 | WriteEventsToClient(client, 1, (xEvent *) &pe); | |||||
445 | } |