Bug Summary

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