| 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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 | } |