| File: | randr/rrprovider.c |
| Location: | line 120, 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 | } |