Bug Summary

File:randr/rroutput.c
Location:line 475, column 18
Description:Array access (from variable 'crtcs') results in a null pointer dereference

Annotated Source Code

1/*
2 * Copyright © 2006 Keith Packard
3 * Copyright © 2008 Red Hat, Inc.
4 *
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that copyright
8 * notice and this permission notice appear in supporting documentation, and
9 * that the name of the copyright holders not be used in advertising or
10 * publicity pertaining to distribution of the software without specific,
11 * written prior permission. The copyright holders make no representations
12 * about the suitability of this software for any purpose. It is provided "as
13 * is" without express or implied warranty.
14 *
15 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21 * OF THIS SOFTWARE.
22 */
23
24#include "randrstr.h"
25
26RESTYPE RROutputType;
27
28/*
29 * Notify the output of some change
30 */
31void
32RROutputChanged(RROutputPtr output, Bool configChanged)
33{
34 /* set changed bits on the master screen only */
35 ScreenPtr pScreen = output->pScreen;
36 rrScrPrivPtr mastersp;
37
38 output->changed = TRUE1;
39 if (!pScreen)
40 return;
41
42 if (pScreen->isGPU) {
43 ScreenPtr master = pScreen->current_master;
44 if (!master)
45 return;
46 mastersp = rrGetScrPriv(master)((rrScrPrivPtr)dixLookupPrivate(&(master)->devPrivates
, (&rrPrivKeyRec)))
;
47 }
48 else {
49 mastersp = rrGetScrPriv(pScreen)((rrScrPrivPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&rrPrivKeyRec)))
;
50 }
51
52 RRSetChanged(pScreen);
53 if (configChanged)
54 mastersp->configChanged = TRUE1;
55}
56
57/*
58 * Create an output
59 */
60
61RROutputPtr
62RROutputCreate(ScreenPtr pScreen,
63 const char *name, int nameLength, void *devPrivate)
64{
65 RROutputPtr output;
66 RROutputPtr *outputs;
67 rrScrPrivPtr pScrPriv;
68
69 if (!RRInit())
70 return NULL((void*)0);
71
72 pScrPriv = rrGetScrPriv(pScreen)((rrScrPrivPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&rrPrivKeyRec)))
;
73
74 if (pScrPriv->numOutputs)
75 outputs = reallocarrayxreallocarray(pScrPriv->outputs,
76 pScrPriv->numOutputs + 1, sizeof(RROutputPtr));
77 else
78 outputs = malloc(sizeof(RROutputPtr));
79 if (!outputs)
80 return FALSE0;
81
82 pScrPriv->outputs = outputs;
83
84 output = malloc(sizeof(RROutputRec) + nameLength + 1);
85 if (!output)
86 return NULL((void*)0);
87 output->id = FakeClientID(0);
88 output->pScreen = pScreen;
89 output->name = (char *) (output + 1);
90 output->nameLength = nameLength;
91 memcpy(output->name, name, nameLength)__builtin___memcpy_chk (output->name, name, nameLength, __builtin_object_size
(output->name, 0))
;
92 output->name[nameLength] = '\0';
93 output->connection = RR_UnknownConnection2;
94 output->subpixelOrder = SubPixelUnknown0;
95 output->mmWidth = 0;
96 output->mmHeight = 0;
97 output->crtc = NULL((void*)0);
98 output->numCrtcs = 0;
99 output->crtcs = NULL((void*)0);
100 output->numClones = 0;
101 output->clones = NULL((void*)0);
102 output->numModes = 0;
103 output->numPreferred = 0;
104 output->modes = NULL((void*)0);
105 output->numUserModes = 0;
106 output->userModes = NULL((void*)0);
107 output->properties = NULL((void*)0);
108 output->pendingProperties = FALSE0;
109 output->changed = FALSE0;
110 output->devPrivate = devPrivate;
111
112 if (!AddResourceDarwin_X_AddResource(output->id, RROutputType, (void *) output))
113 return NULL((void*)0);
114
115 pScrPriv->outputs[pScrPriv->numOutputs++] = output;
116
117 RRResourcesChanged(pScreen);
118
119 return output;
120}
121
122/*
123 * Notify extension that output parameters have been changed
124 */
125Bool
126RROutputSetClones(RROutputPtr output, RROutputPtr * clones, int numClones)
127{
128 RROutputPtr *newClones;
129 int i;
130
131 if (numClones == output->numClones) {
132 for (i = 0; i < numClones; i++)
133 if (output->clones[i] != clones[i])
134 break;
135 if (i == numClones)
136 return TRUE1;
137 }
138 if (numClones) {
139 newClones = xallocarray(numClones, sizeof(RROutputPtr))xreallocarray(((void*)0), (numClones), (sizeof(RROutputPtr)));
140 if (!newClones)
141 return FALSE0;
142 }
143 else
144 newClones = NULL((void*)0);
145 free(output->clones);
146 memcpy(newClones, clones, numClones * sizeof(RROutputPtr))__builtin___memcpy_chk (newClones, clones, numClones * sizeof
(RROutputPtr), __builtin_object_size (newClones, 0))
;
147 output->clones = newClones;
148 output->numClones = numClones;
149 RROutputChanged(output, TRUE1);
150 return TRUE1;
151}
152
153Bool
154RROutputSetModes(RROutputPtr output,
155 RRModePtr * modes, int numModes, int numPreferred)
156{
157 RRModePtr *newModes;
158 int i;
159
160 if (numModes == output->numModes && numPreferred == output->numPreferred) {
161 for (i = 0; i < numModes; i++)
162 if (output->modes[i] != modes[i])
163 break;
164 if (i == numModes) {
165 for (i = 0; i < numModes; i++)
166 RRModeDestroy(modes[i]);
167 return TRUE1;
168 }
169 }
170
171 if (numModes) {
172 newModes = xallocarray(numModes, sizeof(RRModePtr))xreallocarray(((void*)0), (numModes), (sizeof(RRModePtr)));
173 if (!newModes)
174 return FALSE0;
175 }
176 else
177 newModes = NULL((void*)0);
178 if (output->modes) {
179 for (i = 0; i < output->numModes; i++)
180 RRModeDestroy(output->modes[i]);
181 free(output->modes);
182 }
183 memcpy(newModes, modes, numModes * sizeof(RRModePtr))__builtin___memcpy_chk (newModes, modes, numModes * sizeof(RRModePtr
), __builtin_object_size (newModes, 0))
;
184 output->modes = newModes;
185 output->numModes = numModes;
186 output->numPreferred = numPreferred;
187 RROutputChanged(output, TRUE1);
188 return TRUE1;
189}
190
191int
192RROutputAddUserMode(RROutputPtr output, RRModePtr mode)
193{
194 int m;
195 ScreenPtr pScreen = output->pScreen;
196
197 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
198 RRModePtr *newModes;
199
200 /* Check to see if this mode is already listed for this output */
201 for (m = 0; m < output->numModes + output->numUserModes; m++) {
202 RRModePtr e = (m < output->numModes ?
203 output->modes[m] :
204 output->userModes[m - output->numModes]);
205 if (mode == e)
206 return Success0;
207 }
208
209 /* Check with the DDX to see if this mode is OK */
210 if (pScrPriv->rrOutputValidateMode)
211 if (!pScrPriv->rrOutputValidateMode(pScreen, output, mode))
212 return BadMatch8;
213
214 if (output->userModes)
215 newModes = reallocarrayxreallocarray(output->userModes,
216 output->numUserModes + 1, sizeof(RRModePtr));
217 else
218 newModes = malloc(sizeof(RRModePtr));
219 if (!newModes)
220 return BadAlloc11;
221
222 output->userModes = newModes;
223 output->userModes[output->numUserModes++] = mode;
224 ++mode->refcnt;
225 RROutputChanged(output, TRUE1);
226 RRTellChanged(pScreen);
227 return Success0;
228}
229
230int
231RROutputDeleteUserMode(RROutputPtr output, RRModePtr mode)
232{
233 int m;
234
235 /* Find this mode in the user mode list */
236 for (m = 0; m < output->numUserModes; m++) {
237 RRModePtr e = output->userModes[m];
238
239 if (mode == e)
240 break;
241 }
242 /* Not there, access error */
243 if (m == output->numUserModes)
244 return BadAccess10;
245
246 /* make sure the mode isn't active for this output */
247 if (output->crtc && output->crtc->mode == mode)
248 return BadMatch8;
249
250 memmove(output->userModes + m, output->userModes + m + 1,__builtin___memmove_chk (output->userModes + m, output->
userModes + m + 1, (output->numUserModes - m - 1) * sizeof
(RRModePtr), __builtin_object_size (output->userModes + m,
0))
251 (output->numUserModes - m - 1) * sizeof(RRModePtr))__builtin___memmove_chk (output->userModes + m, output->
userModes + m + 1, (output->numUserModes - m - 1) * sizeof
(RRModePtr), __builtin_object_size (output->userModes + m,
0))
;
252 output->numUserModes--;
253 RRModeDestroy(mode);
254 return Success0;
255}
256
257Bool
258RROutputSetCrtcs(RROutputPtr output, RRCrtcPtr * crtcs, int numCrtcs)
259{
260 RRCrtcPtr *newCrtcs;
261 int i;
262
263 if (numCrtcs == output->numCrtcs) {
264 for (i = 0; i < numCrtcs; i++)
265 if (output->crtcs[i] != crtcs[i])
266 break;
267 if (i == numCrtcs)
268 return TRUE1;
269 }
270 if (numCrtcs) {
271 newCrtcs = xallocarray(numCrtcs, sizeof(RRCrtcPtr))xreallocarray(((void*)0), (numCrtcs), (sizeof(RRCrtcPtr)));
272 if (!newCrtcs)
273 return FALSE0;
274 }
275 else
276 newCrtcs = NULL((void*)0);
277 free(output->crtcs);
278 memcpy(newCrtcs, crtcs, numCrtcs * sizeof(RRCrtcPtr))__builtin___memcpy_chk (newCrtcs, crtcs, numCrtcs * sizeof(RRCrtcPtr
), __builtin_object_size (newCrtcs, 0))
;
279 output->crtcs = newCrtcs;
280 output->numCrtcs = numCrtcs;
281 RROutputChanged(output, TRUE1);
282 return TRUE1;
283}
284
285Bool
286RROutputSetConnection(RROutputPtr output, CARD8 connection)
287{
288 if (output->connection == connection)
289 return TRUE1;
290 output->connection = connection;
291 RROutputChanged(output, TRUE1);
292 return TRUE1;
293}
294
295Bool
296RROutputSetSubpixelOrder(RROutputPtr output, int subpixelOrder)
297{
298 if (output->subpixelOrder == subpixelOrder)
299 return TRUE1;
300
301 output->subpixelOrder = subpixelOrder;
302 RROutputChanged(output, FALSE0);
303 return TRUE1;
304}
305
306Bool
307RROutputSetPhysicalSize(RROutputPtr output, int mmWidth, int mmHeight)
308{
309 if (output->mmWidth == mmWidth && output->mmHeight == mmHeight)
310 return TRUE1;
311 output->mmWidth = mmWidth;
312 output->mmHeight = mmHeight;
313 RROutputChanged(output, FALSE0);
314 return TRUE1;
315}
316
317void
318RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output)
319{
320 ScreenPtr pScreen = pWin->drawable.pScreen;
321
322 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
323 RRCrtcPtr crtc = output->crtc;
324 RRModePtr mode = crtc ? crtc->mode : NULL((void*)0);
325
326 xRROutputChangeNotifyEvent oe = {
327 .type = RRNotify1 + RREventBase,
328 .subCode = RRNotify_OutputChange1,
329 .timestamp = pScrPriv->lastSetTime.milliseconds,
330 .configTimestamp = pScrPriv->lastConfigTime.milliseconds,
331 .window = pWin->drawable.id,
332 .output = output->id,
333 .crtc = crtc ? crtc->id : None0L,
334 .mode = mode ? mode->mode.id : None0L,
335 .rotation = crtc ? crtc->rotation : RR_Rotate_01,
336 .connection = output->connection,
337 .subpixelOrder = output->subpixelOrder
338 };
339 WriteEventsToClient(client, 1, (xEvent *) &oe);
340}
341
342/*
343 * Destroy a Output at shutdown
344 */
345void
346RROutputDestroy(RROutputPtr output)
347{
348 FreeResource(output->id, 0);
349}
350
351static int
352RROutputDestroyResource(void *value, XID pid)
353{
354 RROutputPtr output = (RROutputPtr) value;
355 ScreenPtr pScreen = output->pScreen;
356 int m;
357
358 if (pScreen) {
359 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
360 int i;
361
362 if (pScrPriv->primaryOutput == output)
363 pScrPriv->primaryOutput = NULL((void*)0);
364
365 for (i = 0; i < pScrPriv->numOutputs; i++) {
366 if (pScrPriv->outputs[i] == output) {
367 memmove(pScrPriv->outputs + i, pScrPriv->outputs + i + 1,__builtin___memmove_chk (pScrPriv->outputs + i, pScrPriv->
outputs + i + 1, (pScrPriv->numOutputs - (i + 1)) * sizeof
(RROutputPtr), __builtin_object_size (pScrPriv->outputs + i
, 0))
368 (pScrPriv->numOutputs - (i + 1)) * sizeof(RROutputPtr))__builtin___memmove_chk (pScrPriv->outputs + i, pScrPriv->
outputs + i + 1, (pScrPriv->numOutputs - (i + 1)) * sizeof
(RROutputPtr), __builtin_object_size (pScrPriv->outputs + i
, 0))
;
369 --pScrPriv->numOutputs;
370 break;
371 }
372 }
373
374 RRResourcesChanged(pScreen);
375 }
376 if (output->modes) {
377 for (m = 0; m < output->numModes; m++)
378 RRModeDestroy(output->modes[m]);
379 free(output->modes);
380 }
381
382 for (m = 0; m < output->numUserModes; m++)
383 RRModeDestroy(output->userModes[m]);
384 free(output->userModes);
385
386 free(output->crtcs);
387 free(output->clones);
388 RRDeleteAllOutputProperties(output);
389 free(output);
390 return 1;
391}
392
393/*
394 * Initialize output type
395 */
396Bool
397RROutputInit(void)
398{
399 RROutputType = CreateNewResourceType(RROutputDestroyResource, "OUTPUT");
400 if (!RROutputType)
401 return FALSE0;
402
403 return TRUE1;
404}
405
406/*
407 * Initialize output type error value
408 */
409void
410RROutputInitErrorValue(void)
411{
412 SetResourceTypeErrorValue(RROutputType, RRErrorBase + BadRROutput0);
413}
414
415#define OutputInfoExtra(36 - 32) (SIZEOF(xRRGetOutputInfoReply)36 - 32)
416
417int
418ProcRRGetOutputInfo(ClientPtr client)
419{
420 REQUEST(xRRGetOutputInfoReq)xRRGetOutputInfoReq *stuff = (xRRGetOutputInfoReq *)client->
requestBuffer
;
421 xRRGetOutputInfoReply rep;
422 RROutputPtr output;
423 CARD8 *extra;
424 unsigned long extraLen;
425 ScreenPtr pScreen;
426 rrScrPrivPtr pScrPriv;
427 RRCrtc *crtcs;
428 RRMode *modes;
429 RROutput *clones;
430 char *name;
431 int i;
432
433 REQUEST_SIZE_MATCH(xRRGetOutputInfoReq)if ((sizeof(xRRGetOutputInfoReq) >> 2) != client->req_len
) return(16)
;
434 VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess){ int rc = dixLookupResourceByType((void **)&(output), stuff
->output, RROutputType, client, (1<<0)); if (rc != 0
) { client->errorValue = stuff->output; return rc; } }
;
435
436 pScreen = output->pScreen;
437 pScrPriv = rrGetScrPriv(pScreen)((rrScrPrivPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&rrPrivKeyRec)))
;
438
439 rep = (xRRGetOutputInfoReply) {
440 .type = X_Reply1,
441 .status = RRSetConfigSuccess0,
442 .sequenceNumber = client->sequence,
443 .length = bytes_to_int32(OutputInfoExtra(36 - 32)),
444 .timestamp = pScrPriv->lastSetTime.milliseconds,
445 .crtc = output->crtc ? output->crtc->id : None0L,
1
'?' condition is false
446 .mmWidth = output->mmWidth,
447 .mmHeight = output->mmHeight,
448 .connection = output->connection,
449 .subpixelOrder = output->subpixelOrder,
450 .nCrtcs = output->numCrtcs,
451 .nModes = output->numModes + output->numUserModes,
452 .nPreferred = output->numPreferred,
453 .nClones = output->numClones,
454 .nameLength = output->nameLength
455 };
456 extraLen = ((output->numCrtcs +
457 output->numModes + output->numUserModes +
458 output->numClones + bytes_to_int32(rep.nameLength)) << 2);
459
460 if (extraLen) {
2
Assuming 'extraLen' is 0
3
Taking false branch
461 rep.length += bytes_to_int32(extraLen);
462 extra = malloc(extraLen);
463 if (!extra)
464 return BadAlloc11;
465 }
466 else
467 extra = NULL((void*)0);
4
Null pointer value stored to 'extra'
468
469 crtcs = (RRCrtc *) extra;
5
Null pointer value stored to 'crtcs'
470 modes = (RRMode *) (crtcs + output->numCrtcs);
471 clones = (RROutput *) (modes + output->numModes + output->numUserModes);
472 name = (char *) (clones + output->numClones);
473
474 for (i = 0; i < output->numCrtcs; i++) {
6
Loop condition is true. Entering loop body
475 crtcs[i] = output->crtcs[i]->id;
7
Array access (from variable 'crtcs') results in a null pointer dereference
476 if (client->swapped)
477 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)
;
478 }
479 for (i = 0; i < output->numModes + output->numUserModes; i++) {
480 if (i < output->numModes)
481 modes[i] = output->modes[i]->mode.id;
482 else
483 modes[i] = output->userModes[i - output->numModes]->mode.id;
484 if (client->swapped)
485 swapl(&modes[i])do { if (sizeof(*(&modes[i])) != 4) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&modes[i]) & 3) && ((uintptr_t)(
&modes[i]) & 3) == 0) *(&modes[i]) = lswapl(*(&
modes[i])); else swap_uint32((uint32_t *)(&modes[i])); } while
(0)
;
486 }
487 for (i = 0; i < output->numClones; i++) {
488 clones[i] = output->clones[i]->id;
489 if (client->swapped)
490 swapl(&clones[i])do { if (sizeof(*(&clones[i])) != 4) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&clones[i]) & 3) && ((uintptr_t)
(&clones[i]) & 3) == 0) *(&clones[i]) = lswapl(*(
&clones[i])); else swap_uint32((uint32_t *)(&clones[i
])); } while (0)
;
491 }
492 memcpy(name, output->name, output->nameLength)__builtin___memcpy_chk (name, output->name, output->nameLength
, __builtin_object_size (name, 0))
;
493 if (client->swapped) {
494 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)
;
495 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)
;
496 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)
;
497 swapl(&rep.crtc)do { if (sizeof(*(&rep.crtc)) != 4) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&rep.crtc) & 3) && ((uintptr_t)(
&rep.crtc) & 3) == 0) *(&rep.crtc) = lswapl(*(&
rep.crtc)); else swap_uint32((uint32_t *)(&rep.crtc)); } while
(0)
;
498 swapl(&rep.mmWidth)do { if (sizeof(*(&rep.mmWidth)) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&rep.mmWidth) & 3) &&
((uintptr_t)(&rep.mmWidth) & 3) == 0) *(&rep.mmWidth
) = lswapl(*(&rep.mmWidth)); else swap_uint32((uint32_t *
)(&rep.mmWidth)); } while (0)
;
499 swapl(&rep.mmHeight)do { if (sizeof(*(&rep.mmHeight)) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&rep.mmHeight) & 3) &&
((uintptr_t)(&rep.mmHeight) & 3) == 0) *(&rep.mmHeight
) = lswapl(*(&rep.mmHeight)); else swap_uint32((uint32_t *
)(&rep.mmHeight)); } while (0)
;
500 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)
;
501 swaps(&rep.nModes)do { if (sizeof(*(&rep.nModes)) != 2) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&rep.nModes) & 1) && ((uintptr_t
)(&rep.nModes) & 1) == 0) *(&rep.nModes) = lswaps
(*(&rep.nModes)); else swap_uint16((uint16_t *)(&rep.
nModes)); } while (0)
;
502 swaps(&rep.nPreferred)do { if (sizeof(*(&rep.nPreferred)) != 2) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&rep.nPreferred) &
1) && ((uintptr_t)(&rep.nPreferred) & 1) == 0
) *(&rep.nPreferred) = lswaps(*(&rep.nPreferred)); else
swap_uint16((uint16_t *)(&rep.nPreferred)); } while (0)
;
503 swaps(&rep.nClones)do { if (sizeof(*(&rep.nClones)) != 2) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&rep.nClones) & 1) &&
((uintptr_t)(&rep.nClones) & 1) == 0) *(&rep.nClones
) = lswaps(*(&rep.nClones)); else swap_uint16((uint16_t *
)(&rep.nClones)); } while (0)
;
504 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)
;
505 }
506 WriteToClient(client, sizeof(xRRGetOutputInfoReply), &rep);
507 if (extraLen) {
508 WriteToClient(client, extraLen, extra);
509 free(extra);
510 }
511
512 return Success0;
513}
514
515static void
516RRSetPrimaryOutput(ScreenPtr pScreen, rrScrPrivPtr pScrPriv, RROutputPtr output)
517{
518 if (pScrPriv->primaryOutput == output)
519 return;
520
521 /* clear the old primary */
522 if (pScrPriv->primaryOutput) {
523 RROutputChanged(pScrPriv->primaryOutput, 0);
524 pScrPriv->primaryOutput = NULL((void*)0);
525 }
526
527 /* set the new primary */
528 if (output) {
529 pScrPriv->primaryOutput = output;
530 RROutputChanged(output, 0);
531 }
532
533 pScrPriv->layoutChanged = TRUE1;
534
535 RRTellChanged(pScreen);
536}
537
538int
539ProcRRSetOutputPrimary(ClientPtr client)
540{
541 REQUEST(xRRSetOutputPrimaryReq)xRRSetOutputPrimaryReq *stuff = (xRRSetOutputPrimaryReq *)client
->requestBuffer
;
542 RROutputPtr output = NULL((void*)0);
543 WindowPtr pWin;
544 rrScrPrivPtr pScrPriv;
545 int ret;
546 ScreenPtr slave;
547
548 REQUEST_SIZE_MATCH(xRRSetOutputPrimaryReq)if ((sizeof(xRRSetOutputPrimaryReq) >> 2) != client->
req_len) return(16)
;
549
550 ret = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess(1<<4));
551 if (ret != Success0)
552 return ret;
553
554 if (stuff->output) {
555 VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess){ int rc = dixLookupResourceByType((void **)&(output), stuff
->output, RROutputType, client, (1<<0)); if (rc != 0
) { client->errorValue = stuff->output; return rc; } }
;
556
557 if (!output->pScreen->isGPU && output->pScreen != pWin->drawable.pScreen) {
558 client->errorValue = stuff->window;
559 return BadMatch8;
560 }
561 if (output->pScreen->isGPU && output->pScreen->current_master != pWin->drawable.pScreen) {
562 client->errorValue = stuff->window;
563 return BadMatch8;
564 }
565 }
566
567 pScrPriv = rrGetScrPriv(pWin->drawable.pScreen)((rrScrPrivPtr)dixLookupPrivate(&(pWin->drawable.pScreen
)->devPrivates, (&rrPrivKeyRec)))
;
568 if (pScrPriv)
569 {
570 RRSetPrimaryOutput(pWin->drawable.pScreen, pScrPriv, output);
571
572 xorg_list_for_each_entry(slave,for (slave = ((void*)0), slave = (typeof(*slave) *)((char *)(
(&pWin->drawable.pScreen->output_slave_list)->next
) - __builtin_offsetof(typeof(*slave), output_head)); &slave
->output_head != (&pWin->drawable.pScreen->output_slave_list
); slave = (typeof(*slave) *)((char *)(slave->output_head.
next) - __builtin_offsetof(typeof(*slave), output_head)))
573 &pWin->drawable.pScreen->output_slave_list,for (slave = ((void*)0), slave = (typeof(*slave) *)((char *)(
(&pWin->drawable.pScreen->output_slave_list)->next
) - __builtin_offsetof(typeof(*slave), output_head)); &slave
->output_head != (&pWin->drawable.pScreen->output_slave_list
); slave = (typeof(*slave) *)((char *)(slave->output_head.
next) - __builtin_offsetof(typeof(*slave), output_head)))
574 output_head)for (slave = ((void*)0), slave = (typeof(*slave) *)((char *)(
(&pWin->drawable.pScreen->output_slave_list)->next
) - __builtin_offsetof(typeof(*slave), output_head)); &slave
->output_head != (&pWin->drawable.pScreen->output_slave_list
); slave = (typeof(*slave) *)((char *)(slave->output_head.
next) - __builtin_offsetof(typeof(*slave), output_head)))
{
575 rrScrPrivPtr pSlavePriv;
576 pSlavePriv = rrGetScrPriv(slave)((rrScrPrivPtr)dixLookupPrivate(&(slave)->devPrivates,
(&rrPrivKeyRec)))
;
577
578 RRSetPrimaryOutput(slave, pSlavePriv, output);
579 }
580 }
581
582 return Success0;
583}
584
585int
586ProcRRGetOutputPrimary(ClientPtr client)
587{
588 REQUEST(xRRGetOutputPrimaryReq)xRRGetOutputPrimaryReq *stuff = (xRRGetOutputPrimaryReq *)client
->requestBuffer
;
589 WindowPtr pWin;
590 rrScrPrivPtr pScrPriv;
591 xRRGetOutputPrimaryReply rep;
592 RROutputPtr primary = NULL((void*)0);
593 int rc;
594
595 REQUEST_SIZE_MATCH(xRRGetOutputPrimaryReq)if ((sizeof(xRRGetOutputPrimaryReq) >> 2) != client->
req_len) return(16)
;
596
597 rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess(1<<4));
598 if (rc != Success0)
599 return rc;
600
601 pScrPriv = rrGetScrPriv(pWin->drawable.pScreen)((rrScrPrivPtr)dixLookupPrivate(&(pWin->drawable.pScreen
)->devPrivates, (&rrPrivKeyRec)))
;
602 if (pScrPriv)
603 primary = pScrPriv->primaryOutput;
604
605 rep = (xRRGetOutputPrimaryReply) {
606 .type = X_Reply1,
607 .sequenceNumber = client->sequence,
608 .output = primary ? primary->id : None0L
609 };
610
611 if (client->swapped) {
612 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)
;
613 swapl(&rep.output)do { if (sizeof(*(&rep.output)) != 4) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&rep.output) & 3) && ((uintptr_t
)(&rep.output) & 3) == 0) *(&rep.output) = lswapl
(*(&rep.output)); else swap_uint32((uint32_t *)(&rep.
output)); } while (0)
;
614 }
615
616 WriteToClient(client, sizeof(xRRGetOutputPrimaryReply), &rep);
617
618 return Success0;
619}