File: | randr/rroutput.c |
Location: | line 463, column 18 |
Description: | Array access (from variable 'crtcs') results in a null pointer dereference |
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 | ||||
26 | RESTYPE RROutputType; | |||
27 | ||||
28 | /* | |||
29 | * Notify the output of some change | |||
30 | */ | |||
31 | void | |||
32 | RROutputChanged(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 | ||||
49 | RROutputPtr | |||
50 | RROutputCreate(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 | */ | |||
113 | Bool | |||
114 | RROutputSetClones(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 | ||||
141 | Bool | |||
142 | RROutputSetModes(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 | ||||
179 | int | |||
180 | RROutputAddUserMode(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 | ||||
218 | int | |||
219 | RROutputDeleteUserMode(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 | ||||
245 | Bool | |||
246 | RROutputSetCrtcs(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 | ||||
273 | Bool | |||
274 | RROutputSetConnection(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 | ||||
283 | Bool | |||
284 | RROutputSetSubpixelOrder(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 | ||||
294 | Bool | |||
295 | RROutputSetPhysicalSize(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 | ||||
305 | void | |||
306 | RRDeliverOutputEvent(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 | */ | |||
333 | void | |||
334 | RROutputDestroy(RROutputPtr output) | |||
335 | { | |||
336 | FreeResource(output->id, 0); | |||
337 | } | |||
338 | ||||
339 | static int | |||
340 | RROutputDestroyResource(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 | */ | |||
384 | Bool | |||
385 | RROutputInit(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 | */ | |||
397 | void | |||
398 | RROutputInitErrorValue(void) | |||
399 | { | |||
400 | SetResourceTypeErrorValue(RROutputType, RRErrorBase + BadRROutput0); | |||
401 | } | |||
402 | ||||
403 | #define OutputInfoExtra(36 - 32) (SIZEOF(xRRGetOutputInfoReply)36 - 32) | |||
404 | ||||
405 | int | |||
406 | ProcRRGetOutputInfo(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, | |||
| ||||
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) { | |||
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); | |||
456 | ||||
457 | crtcs = (RRCrtc *) extra; | |||
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++) { | |||
463 | crtcs[i] = output->crtcs[i]->id; | |||
| ||||
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 | ||||
503 | static void | |||
504 | RRSetPrimaryOutput(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 | ||||
526 | int | |||
527 | ProcRRSetOutputPrimary(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 | ||||
561 | int | |||
562 | ProcRRGetOutputPrimary(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 | } |