Bug Summary

File:randr/rrcrtc.c
Location:line 1591, column 5
Description:Value stored to 'extra' is never read

Annotated Source Code

1/*
2 * Copyright © 2006 Keith Packard
3 * Copyright 2010 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#include "swaprep.h"
26#include "mipointer.h"
27
28RESTYPE RRCrtcType;
29
30/*
31 * Notify the CRTC of some change
32 */
33void
34RRCrtcChanged(RRCrtcPtr crtc, Bool layoutChanged)
35{
36 ScreenPtr pScreen = crtc->pScreen;
37
38 crtc->changed = TRUE1;
39 if (pScreen) {
40 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
41
42 RRSetChanged(pScreen);
43 /*
44 * Send ConfigureNotify on any layout change
45 */
46 if (layoutChanged)
47 pScrPriv->layoutChanged = TRUE1;
48 }
49}
50
51/*
52 * Create a CRTC
53 */
54RRCrtcPtr
55RRCrtcCreate(ScreenPtr pScreen, void *devPrivate)
56{
57 RRCrtcPtr crtc;
58 RRCrtcPtr *crtcs;
59 rrScrPrivPtr pScrPriv;
60
61 if (!RRInit())
62 return NULL((void*)0);
63
64 pScrPriv = rrGetScrPriv(pScreen)((rrScrPrivPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&rrPrivKeyRec)))
;
65
66 /* make space for the crtc pointer */
67 if (pScrPriv->numCrtcs)
68 crtcs = reallocarrayxreallocarray(pScrPriv->crtcs,
69 pScrPriv->numCrtcs + 1, sizeof(RRCrtcPtr));
70 else
71 crtcs = malloc(sizeof(RRCrtcPtr));
72 if (!crtcs)
73 return FALSE0;
74 pScrPriv->crtcs = crtcs;
75
76 crtc = calloc(1, sizeof(RRCrtcRec));
77 if (!crtc)
78 return NULL((void*)0);
79 crtc->id = FakeClientID(0);
80 crtc->pScreen = pScreen;
81 crtc->mode = NULL((void*)0);
82 crtc->x = 0;
83 crtc->y = 0;
84 crtc->rotation = RR_Rotate_01;
85 crtc->rotations = RR_Rotate_01;
86 crtc->outputs = NULL((void*)0);
87 crtc->numOutputs = 0;
88 crtc->gammaSize = 0;
89 crtc->gammaRed = crtc->gammaBlue = crtc->gammaGreen = NULL((void*)0);
90 crtc->changed = FALSE0;
91 crtc->devPrivate = devPrivate;
92 RRTransformInit(&crtc->client_pending_transform);
93 RRTransformInit(&crtc->client_current_transform);
94 pixman_transform_init_identity(&crtc->transform);
95 pixman_f_transform_init_identity(&crtc->f_transform);
96 pixman_f_transform_init_identity(&crtc->f_inverse);
97
98 if (!AddResourceDarwin_X_AddResource(crtc->id, RRCrtcType, (void *) crtc))
99 return NULL((void*)0);
100
101 /* attach the screen and crtc together */
102 crtc->pScreen = pScreen;
103 pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc;
104
105 RRResourcesChanged(pScreen);
106
107 return crtc;
108}
109
110/*
111 * Set the allowed rotations on a CRTC
112 */
113void
114RRCrtcSetRotations(RRCrtcPtr crtc, Rotation rotations)
115{
116 crtc->rotations = rotations;
117}
118
119/*
120 * Set whether transforms are allowed on a CRTC
121 */
122void
123RRCrtcSetTransformSupport(RRCrtcPtr crtc, Bool transforms)
124{
125 crtc->transforms = transforms;
126}
127
128/*
129 * Notify the extension that the Crtc has been reconfigured,
130 * the driver calls this whenever it has updated the mode
131 */
132Bool
133RRCrtcNotify(RRCrtcPtr crtc,
134 RRModePtr mode,
135 int x,
136 int y,
137 Rotation rotation,
138 RRTransformPtr transform, int numOutputs, RROutputPtr * outputs)
139{
140 int i, j;
141
142 /*
143 * Check to see if any of the new outputs were
144 * not in the old list and mark them as changed
145 */
146 for (i = 0; i < numOutputs; i++) {
147 for (j = 0; j < crtc->numOutputs; j++)
148 if (outputs[i] == crtc->outputs[j])
149 break;
150 if (j == crtc->numOutputs) {
151 outputs[i]->crtc = crtc;
152 RROutputChanged(outputs[i], FALSE0);
153 RRCrtcChanged(crtc, FALSE0);
154 }
155 }
156 /*
157 * Check to see if any of the old outputs are
158 * not in the new list and mark them as changed
159 */
160 for (j = 0; j < crtc->numOutputs; j++) {
161 for (i = 0; i < numOutputs; i++)
162 if (outputs[i] == crtc->outputs[j])
163 break;
164 if (i == numOutputs) {
165 if (crtc->outputs[j]->crtc == crtc)
166 crtc->outputs[j]->crtc = NULL((void*)0);
167 RROutputChanged(crtc->outputs[j], FALSE0);
168 RRCrtcChanged(crtc, FALSE0);
169 }
170 }
171 /*
172 * Reallocate the crtc output array if necessary
173 */
174 if (numOutputs != crtc->numOutputs) {
175 RROutputPtr *newoutputs;
176
177 if (numOutputs) {
178 if (crtc->numOutputs)
179 newoutputs = reallocarrayxreallocarray(crtc->outputs,
180 numOutputs, sizeof(RROutputPtr));
181 else
182 newoutputs = xallocarray(numOutputs, sizeof(RROutputPtr))xreallocarray(((void*)0), (numOutputs), (sizeof(RROutputPtr))
)
;
183 if (!newoutputs)
184 return FALSE0;
185 }
186 else {
187 free(crtc->outputs);
188 newoutputs = NULL((void*)0);
189 }
190 crtc->outputs = newoutputs;
191 crtc->numOutputs = numOutputs;
192 }
193 /*
194 * Copy the new list of outputs into the crtc
195 */
196 memcpy(crtc->outputs, outputs, numOutputs * sizeof(RROutputPtr))__builtin___memcpy_chk (crtc->outputs, outputs, numOutputs
* sizeof(RROutputPtr), __builtin_object_size (crtc->outputs
, 0))
;
197 /*
198 * Update remaining crtc fields
199 */
200 if (mode != crtc->mode) {
201 if (crtc->mode)
202 RRModeDestroy(crtc->mode);
203 crtc->mode = mode;
204 if (mode != NULL((void*)0))
205 mode->refcnt++;
206 RRCrtcChanged(crtc, TRUE1);
207 }
208 if (x != crtc->x) {
209 crtc->x = x;
210 RRCrtcChanged(crtc, TRUE1);
211 }
212 if (y != crtc->y) {
213 crtc->y = y;
214 RRCrtcChanged(crtc, TRUE1);
215 }
216 if (rotation != crtc->rotation) {
217 crtc->rotation = rotation;
218 RRCrtcChanged(crtc, TRUE1);
219 }
220 if (!RRTransformEqual(transform, &crtc->client_current_transform)) {
221 RRTransformCopy(&crtc->client_current_transform, transform);
222 RRCrtcChanged(crtc, TRUE1);
223 }
224 if (crtc->changed && mode) {
225 RRTransformCompute(x, y,
226 mode->mode.width, mode->mode.height,
227 rotation,
228 &crtc->client_current_transform,
229 &crtc->transform, &crtc->f_transform,
230 &crtc->f_inverse);
231 }
232 return TRUE1;
233}
234
235void
236RRDeliverCrtcEvent(ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc)
237{
238 ScreenPtr pScreen = pWin->drawable.pScreen;
239
240 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
241 RRModePtr mode = crtc->mode;
242
243 xRRCrtcChangeNotifyEvent ce = {
244 .type = RRNotify1 + RREventBase,
245 .subCode = RRNotify_CrtcChange0,
246 .timestamp = pScrPriv->lastSetTime.milliseconds,
247 .window = pWin->drawable.id,
248 .crtc = crtc->id,
249 .mode = mode ? mode->mode.id : None0L,
250 .rotation = crtc->rotation,
251 .x = mode ? crtc->x : 0,
252 .y = mode ? crtc->y : 0,
253 .width = mode ? mode->mode.width : 0,
254 .height = mode ? mode->mode.height : 0
255 };
256 WriteEventsToClient(client, 1, (xEvent *) &ce);
257}
258
259static Bool
260RRCrtcPendingProperties(RRCrtcPtr crtc)
261{
262 ScreenPtr pScreen = crtc->pScreen;
263
264 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
265 int o;
266
267 for (o = 0; o < pScrPriv->numOutputs; o++) {
268 RROutputPtr output = pScrPriv->outputs[o];
269
270 if (output->crtc == crtc && output->pendingProperties)
271 return TRUE1;
272 }
273 return FALSE0;
274}
275
276static void
277crtc_bounds(RRCrtcPtr crtc, int *left, int *right, int *top, int *bottom)
278{
279 *left = crtc->x;
280 *top = crtc->y;
281
282 switch (crtc->rotation) {
283 case RR_Rotate_01:
284 case RR_Rotate_1804:
285 default:
286 *right = crtc->x + crtc->mode->mode.width;
287 *bottom = crtc->y + crtc->mode->mode.height;
288 return;
289 case RR_Rotate_902:
290 case RR_Rotate_2708:
291 *right = crtc->x + crtc->mode->mode.height;
292 *bottom = crtc->y + crtc->mode->mode.width;
293 return;
294 }
295}
296
297/* overlapping counts as adjacent */
298static Bool
299crtcs_adjacent(const RRCrtcPtr a, const RRCrtcPtr b)
300{
301 /* left, right, top, bottom... */
302 int al, ar, at, ab;
303 int bl, br, bt, bb;
304 int cl, cr, ct, cb; /* the overlap, if any */
305
306 crtc_bounds(a, &al, &ar, &at, &ab);
307 crtc_bounds(b, &bl, &br, &bt, &bb);
308
309 cl = max(al, bl)(((al) > (bl)) ? (al) : (bl));
310 cr = min(ar, br)(((ar) < (br)) ? (ar) : (br));
311 ct = max(at, bt)(((at) > (bt)) ? (at) : (bt));
312 cb = min(ab, bb)(((ab) < (bb)) ? (ab) : (bb));
313
314 return (cl <= cr) && (ct <= cb);
315}
316
317/* Depth-first search and mark all CRTCs reachable from cur */
318static void
319mark_crtcs(rrScrPrivPtr pScrPriv, int *reachable, int cur)
320{
321 int i;
322
323 reachable[cur] = TRUE1;
324 for (i = 0; i < pScrPriv->numCrtcs; ++i) {
325 if (reachable[i] || !pScrPriv->crtcs[i]->mode)
326 continue;
327 if (crtcs_adjacent(pScrPriv->crtcs[cur], pScrPriv->crtcs[i]))
328 mark_crtcs(pScrPriv, reachable, i);
329 }
330}
331
332static void
333RRComputeContiguity(ScreenPtr pScreen)
334{
335 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
336 Bool discontiguous = TRUE1;
337 int i, n = pScrPriv->numCrtcs;
338
339 int *reachable = calloc(n, sizeof(int));
340
341 if (!reachable)
342 goto out;
343
344 /* Find first enabled CRTC and start search for reachable CRTCs from it */
345 for (i = 0; i < n; ++i) {
346 if (pScrPriv->crtcs[i]->mode) {
347 mark_crtcs(pScrPriv, reachable, i);
348 break;
349 }
350 }
351
352 /* Check that all enabled CRTCs were marked as reachable */
353 for (i = 0; i < n; ++i)
354 if (pScrPriv->crtcs[i]->mode && !reachable[i])
355 goto out;
356
357 discontiguous = FALSE0;
358
359 out:
360 free(reachable);
361 pScrPriv->discontiguous = discontiguous;
362}
363
364void
365RRCrtcDetachScanoutPixmap(RRCrtcPtr crtc)
366{
367 ScreenPtr master = crtc->pScreen->current_master;
368 PixmapPtr mscreenpix;
369 rrScrPriv(crtc->pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(crtc->pScreen)->devPrivates, (&rrPrivKeyRec)))
;
370
371 mscreenpix = master->GetScreenPixmap(master);
372
373 pScrPriv->rrCrtcSetScanoutPixmap(crtc, NULL((void*)0));
374 if (crtc->scanout_pixmap) {
375 master->StopPixmapTracking(mscreenpix, crtc->scanout_pixmap);
376 /*
377 * Unref the pixmap twice: once for the original reference, and once
378 * for the reference implicitly added by PixmapShareToSlave.
379 */
380 master->DestroyPixmap(crtc->scanout_pixmap->master_pixmap);
381 master->DestroyPixmap(crtc->scanout_pixmap->master_pixmap);
382 crtc->pScreen->DestroyPixmap(crtc->scanout_pixmap);
383 }
384 crtc->scanout_pixmap = NULL((void*)0);
385 RRCrtcChanged(crtc, TRUE1);
386}
387
388static Bool
389rrCreateSharedPixmap(RRCrtcPtr crtc, int width, int height,
390 int x, int y, Rotation rotation)
391{
392 PixmapPtr mpix, spix;
393 ScreenPtr master = crtc->pScreen->current_master;
394 Bool ret;
395 int depth;
396 PixmapPtr mscreenpix;
397 PixmapPtr protopix = master->GetScreenPixmap(master);
398 rrScrPriv(crtc->pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(crtc->pScreen)->devPrivates, (&rrPrivKeyRec)))
;
399
400 /* create a pixmap on the master screen,
401 then get a shared handle for it
402 create a shared pixmap on the slave screen using the handle
403 set the master screen to do dirty updates to the shared pixmap
404 from the screen pixmap.
405 set slave screen to scanout shared linear pixmap
406 */
407
408 mscreenpix = master->GetScreenPixmap(master);
409 depth = protopix->drawable.depth;
410
411 if (crtc->scanout_pixmap)
412 RRCrtcDetachScanoutPixmap(crtc);
413
414 if (width == 0 && height == 0) {
415 return TRUE1;
416 }
417
418 mpix = master->CreatePixmap(master, width, height, depth,
419 CREATE_PIXMAP_USAGE_SHARED4);
420 if (!mpix)
421 return FALSE0;
422
423 spix = PixmapShareToSlave(mpix, crtc->pScreen);
424 if (spix == NULL((void*)0)) {
425 master->DestroyPixmap(mpix);
426 return FALSE0;
427 }
428
429 ret = pScrPriv->rrCrtcSetScanoutPixmap(crtc, spix);
430 if (ret == FALSE0) {
431 ErrorF("randr: failed to set shadow slave pixmap\n");
432 return FALSE0;
433 }
434
435 crtc->scanout_pixmap = spix;
436
437 master->StartPixmapTracking(mscreenpix, spix, x, y, 0, 0, rotation);
438 return TRUE1;
439}
440
441static void crtc_to_box(BoxPtr box, RRCrtcPtr crtc)
442{
443 box->x1 = crtc->x;
444 box->y1 = crtc->y;
445 switch (crtc->rotation) {
446 case RR_Rotate_01:
447 case RR_Rotate_1804:
448 default:
449 box->x2 = crtc->x + crtc->mode->mode.width;
450 box->y2 = crtc->y + crtc->mode->mode.height;
451 break;
452 case RR_Rotate_902:
453 case RR_Rotate_2708:
454 box->x2 = crtc->x + crtc->mode->mode.height;
455 box->y2 = crtc->y + crtc->mode->mode.width;
456 break;
457 }
458}
459
460static Bool
461rrCheckPixmapBounding(ScreenPtr pScreen,
462 RRCrtcPtr rr_crtc, Rotation rotation,
463 int x, int y, int w, int h)
464{
465 RegionRec root_pixmap_region, total_region, new_crtc_region;
466 int c;
467 BoxRec newbox;
468 BoxPtr newsize;
469 ScreenPtr slave;
470 int new_width, new_height;
471 PixmapPtr screen_pixmap = pScreen->GetScreenPixmap(pScreen);
472 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
473
474 PixmapRegionInit(&root_pixmap_region, screen_pixmap);
475 RegionInit(&total_region, NULL((void*)0), 0);
476
477 /* have to iterate all the crtcs of the attached gpu masters
478 and all their output slaves */
479 for (c = 0; c < pScrPriv->numCrtcs; c++) {
480 RRCrtcPtr crtc = pScrPriv->crtcs[c];
481
482 if (crtc == rr_crtc) {
483 newbox.x1 = x;
484 newbox.y1 = y;
485 if (rotation == RR_Rotate_902 ||
486 rotation == RR_Rotate_2708) {
487 newbox.x2 = x + h;
488 newbox.y2 = y + w;
489 } else {
490 newbox.x2 = x + w;
491 newbox.y2 = y + h;
492 }
493 } else {
494 if (!crtc->mode)
495 continue;
496 crtc_to_box(&newbox, crtc);
497 }
498 RegionInit(&new_crtc_region, &newbox, 1);
499 RegionUnion(&total_region, &total_region, &new_crtc_region);
500 }
501
502 xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head)for (slave = ((void*)0), slave = (typeof(*slave) *)((char *)(
(&pScreen->output_slave_list)->next) - __builtin_offsetof
(typeof(*slave), output_head)); &slave->output_head !=
(&pScreen->output_slave_list); slave = (typeof(*slave
) *)((char *)(slave->output_head.next) - __builtin_offsetof
(typeof(*slave), output_head)))
{
503 rrScrPrivPtr slave_priv = rrGetScrPriv(slave)((rrScrPrivPtr)dixLookupPrivate(&(slave)->devPrivates,
(&rrPrivKeyRec)))
;
504 for (c = 0; c < slave_priv->numCrtcs; c++) {
505 RRCrtcPtr slave_crtc = slave_priv->crtcs[c];
506
507 if (slave_crtc == rr_crtc) {
508 newbox.x1 = x;
509 newbox.y1 = y;
510 if (rotation == RR_Rotate_902 ||
511 rotation == RR_Rotate_2708) {
512 newbox.x2 = x + h;
513 newbox.y2 = y + w;
514 } else {
515 newbox.x2 = x + w;
516 newbox.y2 = y + h;
517 }
518 }
519 else {
520 if (!slave_crtc->mode)
521 continue;
522 crtc_to_box(&newbox, slave_crtc);
523 }
524 RegionInit(&new_crtc_region, &newbox, 1);
525 RegionUnion(&total_region, &total_region, &new_crtc_region);
526 }
527 }
528
529 newsize = RegionExtents(&total_region);
530 new_width = newsize->x2 - newsize->x1;
531 new_height = newsize->y2 - newsize->y1;
532
533 if (new_width == screen_pixmap->drawable.width &&
534 new_height == screen_pixmap->drawable.height) {
535 } else {
536 pScrPriv->rrScreenSetSize(pScreen, new_width, new_height, 0, 0);
537 }
538
539 /* set shatters TODO */
540 return TRUE1;
541}
542
543/*
544 * Request that the Crtc be reconfigured
545 */
546Bool
547RRCrtcSet(RRCrtcPtr crtc,
548 RRModePtr mode,
549 int x,
550 int y, Rotation rotation, int numOutputs, RROutputPtr * outputs)
551{
552 ScreenPtr pScreen = crtc->pScreen;
553 Bool ret = FALSE0;
554 Bool recompute = TRUE1;
555 Bool crtcChanged;
556 int o;
557
558 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
559
560 crtcChanged = FALSE0;
561 for (o = 0; o < numOutputs; o++) {
562 if (outputs[o] && outputs[o]->crtc != crtc) {
563 crtcChanged = TRUE1;
564 break;
565 }
566 }
567
568 /* See if nothing changed */
569 if (crtc->mode == mode &&
570 crtc->x == x &&
571 crtc->y == y &&
572 crtc->rotation == rotation &&
573 crtc->numOutputs == numOutputs &&
574 !memcmp(crtc->outputs, outputs, numOutputs * sizeof(RROutputPtr)) &&
575 !RRCrtcPendingProperties(crtc) && !RRCrtcPendingTransform(crtc) &&
576 !crtcChanged) {
577 recompute = FALSE0;
578 ret = TRUE1;
579 }
580 else {
581 if (pScreen->isGPU) {
582 ScreenPtr master = pScreen->current_master;
583 int width = 0, height = 0;
584
585 if (mode) {
586 width = mode->mode.width;
587 height = mode->mode.height;
588 }
589 ret = rrCheckPixmapBounding(master, crtc,
590 rotation, x, y, width, height);
591 if (!ret)
592 return FALSE0;
593
594 if (pScreen->current_master) {
595 ret = rrCreateSharedPixmap(crtc, width, height, x, y, rotation);
596 }
597 }
598#if RANDR_12_INTERFACE1
599 if (pScrPriv->rrCrtcSet) {
600 ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y,
601 rotation, numOutputs, outputs);
602 }
603 else
604#endif
605 {
606#if RANDR_10_INTERFACE1
607 if (pScrPriv->rrSetConfig) {
608 RRScreenSize size;
609 RRScreenRate rate;
610
611 if (!mode) {
612 RRCrtcNotify(crtc, NULL((void*)0), x, y, rotation, NULL((void*)0), 0, NULL((void*)0));
613 ret = TRUE1;
614 }
615 else {
616 size.width = mode->mode.width;
617 size.height = mode->mode.height;
618 if (outputs[0]->mmWidth && outputs[0]->mmHeight) {
619 size.mmWidth = outputs[0]->mmWidth;
620 size.mmHeight = outputs[0]->mmHeight;
621 }
622 else {
623 size.mmWidth = pScreen->mmWidth;
624 size.mmHeight = pScreen->mmHeight;
625 }
626 size.nRates = 1;
627 rate.rate = RRVerticalRefresh(&mode->mode);
628 size.pRates = &rate;
629 ret =
630 (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate,
631 &size);
632 /*
633 * Old 1.0 interface tied screen size to mode size
634 */
635 if (ret) {
636 RRCrtcNotify(crtc, mode, x, y, rotation, NULL((void*)0), 1,
637 outputs);
638 RRScreenSizeNotify(pScreen);
639 }
640 }
641 }
642#endif
643 }
644 if (ret) {
645
646 RRTellChanged(pScreen);
647
648 for (o = 0; o < numOutputs; o++)
649 RRPostPendingProperties(outputs[o]);
650 }
651 }
652
653 if (recompute)
654 RRComputeContiguity(pScreen);
655
656 return ret;
657}
658
659/*
660 * Return crtc transform
661 */
662RRTransformPtr
663RRCrtcGetTransform(RRCrtcPtr crtc)
664{
665 RRTransformPtr transform = &crtc->client_pending_transform;
666
667 if (pixman_transform_is_identity(&transform->transform))
668 return NULL((void*)0);
669 return transform;
670}
671
672/*
673 * Check whether the pending and current transforms are the same
674 */
675Bool
676RRCrtcPendingTransform(RRCrtcPtr crtc)
677{
678 return memcmp(&crtc->client_current_transform.transform,
679 &crtc->client_pending_transform.transform,
680 sizeof(PictTransform)) != 0;
681}
682
683/*
684 * Destroy a Crtc at shutdown
685 */
686void
687RRCrtcDestroy(RRCrtcPtr crtc)
688{
689 FreeResource(crtc->id, 0);
690}
691
692static int
693RRCrtcDestroyResource(void *value, XID pid)
694{
695 RRCrtcPtr crtc = (RRCrtcPtr) value;
696 ScreenPtr pScreen = crtc->pScreen;
697
698 if (pScreen) {
699 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
700 int i;
701
702 for (i = 0; i < pScrPriv->numCrtcs; i++) {
703 if (pScrPriv->crtcs[i] == crtc) {
704 memmove(pScrPriv->crtcs + i, pScrPriv->crtcs + i + 1,__builtin___memmove_chk (pScrPriv->crtcs + i, pScrPriv->
crtcs + i + 1, (pScrPriv->numCrtcs - (i + 1)) * sizeof(RRCrtcPtr
), __builtin_object_size (pScrPriv->crtcs + i, 0))
705 (pScrPriv->numCrtcs - (i + 1)) * sizeof(RRCrtcPtr))__builtin___memmove_chk (pScrPriv->crtcs + i, pScrPriv->
crtcs + i + 1, (pScrPriv->numCrtcs - (i + 1)) * sizeof(RRCrtcPtr
), __builtin_object_size (pScrPriv->crtcs + i, 0))
;
706 --pScrPriv->numCrtcs;
707 break;
708 }
709 }
710
711 RRResourcesChanged(pScreen);
712 }
713
714 if (crtc->scanout_pixmap)
715 RRCrtcDetachScanoutPixmap(crtc);
716 free(crtc->gammaRed);
717 if (crtc->mode)
718 RRModeDestroy(crtc->mode);
719 free(crtc);
720 return 1;
721}
722
723/*
724 * Request that the Crtc gamma be changed
725 */
726
727Bool
728RRCrtcGammaSet(RRCrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue)
729{
730 Bool ret = TRUE1;
731
732#if RANDR_12_INTERFACE1
733 ScreenPtr pScreen = crtc->pScreen;
734#endif
735
736 memcpy(crtc->gammaRed, red, crtc->gammaSize * sizeof(CARD16))__builtin___memcpy_chk (crtc->gammaRed, red, crtc->gammaSize
* sizeof(CARD16), __builtin_object_size (crtc->gammaRed, 0
))
;
737 memcpy(crtc->gammaGreen, green, crtc->gammaSize * sizeof(CARD16))__builtin___memcpy_chk (crtc->gammaGreen, green, crtc->
gammaSize * sizeof(CARD16), __builtin_object_size (crtc->gammaGreen
, 0))
;
738 memcpy(crtc->gammaBlue, blue, crtc->gammaSize * sizeof(CARD16))__builtin___memcpy_chk (crtc->gammaBlue, blue, crtc->gammaSize
* sizeof(CARD16), __builtin_object_size (crtc->gammaBlue,
0))
;
739#if RANDR_12_INTERFACE1
740 if (pScreen) {
741 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
742 if (pScrPriv->rrCrtcSetGamma)
743 ret = (*pScrPriv->rrCrtcSetGamma) (pScreen, crtc);
744 }
745#endif
746 return ret;
747}
748
749/*
750 * Request current gamma back from the DDX (if possible).
751 * This includes gamma size.
752 */
753Bool
754RRCrtcGammaGet(RRCrtcPtr crtc)
755{
756 Bool ret = TRUE1;
757
758#if RANDR_12_INTERFACE1
759 ScreenPtr pScreen = crtc->pScreen;
760#endif
761
762#if RANDR_12_INTERFACE1
763 if (pScreen) {
764 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
765 if (pScrPriv->rrCrtcGetGamma)
766 ret = (*pScrPriv->rrCrtcGetGamma) (pScreen, crtc);
767 }
768#endif
769 return ret;
770}
771
772/*
773 * Notify the extension that the Crtc gamma has been changed
774 * The driver calls this whenever it has changed the gamma values
775 * in the RRCrtcRec
776 */
777
778Bool
779RRCrtcGammaNotify(RRCrtcPtr crtc)
780{
781 return TRUE1; /* not much going on here */
782}
783
784static void
785RRModeGetScanoutSize(RRModePtr mode, PictTransformPtr transform,
786 int *width, int *height)
787{
788 BoxRec box;
789
790 if (mode == NULL((void*)0)) {
791 *width = 0;
792 *height = 0;
793 return;
794 }
795
796 box.x1 = 0;
797 box.y1 = 0;
798 box.x2 = mode->mode.width;
799 box.y2 = mode->mode.height;
800
801 pixman_transform_bounds(transform, &box);
802 *width = box.x2 - box.x1;
803 *height = box.y2 - box.y1;
804}
805
806/**
807 * Returns the width/height that the crtc scans out from the framebuffer
808 */
809void
810RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height)
811{
812 RRModeGetScanoutSize(crtc->mode, &crtc->transform, width, height);
813}
814
815/*
816 * Set the size of the gamma table at server startup time
817 */
818
819Bool
820RRCrtcGammaSetSize(RRCrtcPtr crtc, int size)
821{
822 CARD16 *gamma;
823
824 if (size == crtc->gammaSize)
825 return TRUE1;
826 if (size) {
827 gamma = xallocarray(size, 3 * sizeof(CARD16))xreallocarray(((void*)0), (size), (3 * sizeof(CARD16)));
828 if (!gamma)
829 return FALSE0;
830 }
831 else
832 gamma = NULL((void*)0);
833 free(crtc->gammaRed);
834 crtc->gammaRed = gamma;
835 crtc->gammaGreen = gamma + size;
836 crtc->gammaBlue = gamma + size * 2;
837 crtc->gammaSize = size;
838 return TRUE1;
839}
840
841/*
842 * Set the pending CRTC transformation
843 */
844
845int
846RRCrtcTransformSet(RRCrtcPtr crtc,
847 PictTransformPtr transform,
848 struct pixman_f_transform *f_transform,
849 struct pixman_f_transform *f_inverse,
850 char *filter_name,
851 int filter_len, xFixed * params, int nparams)
852{
853 PictFilterPtr filter = NULL((void*)0);
854 int width = 0, height = 0;
855
856 if (!crtc->transforms)
857 return BadValue2;
858
859 if (filter_len) {
860 filter = PictureFindFilter(crtc->pScreen, filter_name, filter_len);
861 if (!filter)
862 return BadName15;
863 if (filter->ValidateParams) {
864 if (!filter->ValidateParams(crtc->pScreen, filter->id,
865 params, nparams, &width, &height))
866 return BadMatch8;
867 }
868 else {
869 width = filter->width;
870 height = filter->height;
871 }
872 }
873 else {
874 if (nparams)
875 return BadMatch8;
876 }
877 if (!RRTransformSetFilter(&crtc->client_pending_transform,
878 filter, params, nparams, width, height))
879 return BadAlloc11;
880
881 crtc->client_pending_transform.transform = *transform;
882 crtc->client_pending_transform.f_transform = *f_transform;
883 crtc->client_pending_transform.f_inverse = *f_inverse;
884 return Success0;
885}
886
887/*
888 * Initialize crtc type
889 */
890Bool
891RRCrtcInit(void)
892{
893 RRCrtcType = CreateNewResourceType(RRCrtcDestroyResource, "CRTC");
894 if (!RRCrtcType)
895 return FALSE0;
896
897 return TRUE1;
898}
899
900/*
901 * Initialize crtc type error value
902 */
903void
904RRCrtcInitErrorValue(void)
905{
906 SetResourceTypeErrorValue(RRCrtcType, RRErrorBase + BadRRCrtc1);
907}
908
909int
910ProcRRGetCrtcInfo(ClientPtr client)
911{
912 REQUEST(xRRGetCrtcInfoReq)xRRGetCrtcInfoReq *stuff = (xRRGetCrtcInfoReq *)client->requestBuffer;
913 xRRGetCrtcInfoReply rep;
914 RRCrtcPtr crtc;
915 CARD8 *extra;
916 unsigned long extraLen;
917 ScreenPtr pScreen;
918 rrScrPrivPtr pScrPriv;
919 RRModePtr mode;
920 RROutput *outputs;
921 RROutput *possible;
922 int i, j, k;
923 int width, height;
924 BoxRec panned_area;
925
926 REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq)if ((sizeof(xRRGetCrtcInfoReq) >> 2) != client->req_len
) return(16)
;
927 VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess){ int rc = dixLookupResourceByType((void **)&(crtc), stuff
->crtc, RRCrtcType, client, (1<<0)); if (rc != 0) { client
->errorValue = stuff->crtc; return rc; } }
;
928
929 /* All crtcs must be associated with screens before client
930 * requests are processed
931 */
932 pScreen = crtc->pScreen;
933 pScrPriv = rrGetScrPriv(pScreen)((rrScrPrivPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&rrPrivKeyRec)))
;
934
935 mode = crtc->mode;
936
937 rep = (xRRGetCrtcInfoReply) {
938 .type = X_Reply1,
939 .status = RRSetConfigSuccess0,
940 .sequenceNumber = client->sequence,
941 .length = 0,
942 .timestamp = pScrPriv->lastSetTime.milliseconds
943 };
944 if (pScrPriv->rrGetPanning &&
945 pScrPriv->rrGetPanning(pScreen, crtc, &panned_area, NULL((void*)0), NULL((void*)0)) &&
946 (panned_area.x2 > panned_area.x1) && (panned_area.y2 > panned_area.y1))
947 {
948 rep.x = panned_area.x1;
949 rep.y = panned_area.y1;
950 rep.width = panned_area.x2 - panned_area.x1;
951 rep.height = panned_area.y2 - panned_area.y1;
952 }
953 else {
954 RRCrtcGetScanoutSize(crtc, &width, &height);
955 rep.x = crtc->x;
956 rep.y = crtc->y;
957 rep.width = width;
958 rep.height = height;
959 }
960 rep.mode = mode ? mode->mode.id : 0;
961 rep.rotation = crtc->rotation;
962 rep.rotations = crtc->rotations;
963 rep.nOutput = crtc->numOutputs;
964 k = 0;
965 for (i = 0; i < pScrPriv->numOutputs; i++)
966 for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++)
967 if (pScrPriv->outputs[i]->crtcs[j] == crtc)
968 k++;
969 rep.nPossibleOutput = k;
970
971 rep.length = rep.nOutput + rep.nPossibleOutput;
972
973 extraLen = rep.length << 2;
974 if (extraLen) {
975 extra = malloc(extraLen);
976 if (!extra)
977 return BadAlloc11;
978 }
979 else
980 extra = NULL((void*)0);
981
982 outputs = (RROutput *) extra;
983 possible = (RROutput *) (outputs + rep.nOutput);
984
985 for (i = 0; i < crtc->numOutputs; i++) {
986 outputs[i] = crtc->outputs[i]->id;
987 if (client->swapped)
988 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)
;
989 }
990 k = 0;
991 for (i = 0; i < pScrPriv->numOutputs; i++)
992 for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++)
993 if (pScrPriv->outputs[i]->crtcs[j] == crtc) {
994 possible[k] = pScrPriv->outputs[i]->id;
995 if (client->swapped)
996 swapl(&possible[k])do { if (sizeof(*(&possible[k])) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&possible[k]) & 3) &&
((uintptr_t)(&possible[k]) & 3) == 0) *(&possible
[k]) = lswapl(*(&possible[k])); else swap_uint32((uint32_t
*)(&possible[k])); } while (0)
;
997 k++;
998 }
999
1000 if (client->swapped) {
1001 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)
;
1002 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)
;
1003 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)
;
1004 swaps(&rep.x)do { if (sizeof(*(&rep.x)) != 2) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&rep.x) & 1) && ((uintptr_t)(&
rep.x) & 1) == 0) *(&rep.x) = lswaps(*(&rep.x)); else
swap_uint16((uint16_t *)(&rep.x)); } while (0)
;
1005 swaps(&rep.y)do { if (sizeof(*(&rep.y)) != 2) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&rep.y) & 1) && ((uintptr_t)(&
rep.y) & 1) == 0) *(&rep.y) = lswaps(*(&rep.y)); else
swap_uint16((uint16_t *)(&rep.y)); } while (0)
;
1006 swaps(&rep.width)do { if (sizeof(*(&rep.width)) != 2) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&rep.width) & 1) && ((uintptr_t)
(&rep.width) & 1) == 0) *(&rep.width) = lswaps(*(
&rep.width)); else swap_uint16((uint16_t *)(&rep.width
)); } while (0)
;
1007 swaps(&rep.height)do { if (sizeof(*(&rep.height)) != 2) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&rep.height) & 1) && ((uintptr_t
)(&rep.height) & 1) == 0) *(&rep.height) = lswaps
(*(&rep.height)); else swap_uint16((uint16_t *)(&rep.
height)); } while (0)
;
1008 swapl(&rep.mode)do { if (sizeof(*(&rep.mode)) != 4) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&rep.mode) & 3) && ((uintptr_t)(
&rep.mode) & 3) == 0) *(&rep.mode) = lswapl(*(&
rep.mode)); else swap_uint32((uint32_t *)(&rep.mode)); } while
(0)
;
1009 swaps(&rep.rotation)do { if (sizeof(*(&rep.rotation)) != 2) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&rep.rotation) & 1) &&
((uintptr_t)(&rep.rotation) & 1) == 0) *(&rep.rotation
) = lswaps(*(&rep.rotation)); else swap_uint16((uint16_t *
)(&rep.rotation)); } while (0)
;
1010 swaps(&rep.rotations)do { if (sizeof(*(&rep.rotations)) != 2) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&rep.rotations) & 1
) && ((uintptr_t)(&rep.rotations) & 1) == 0) *
(&rep.rotations) = lswaps(*(&rep.rotations)); else swap_uint16
((uint16_t *)(&rep.rotations)); } while (0)
;
1011 swaps(&rep.nOutput)do { if (sizeof(*(&rep.nOutput)) != 2) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&rep.nOutput) & 1) &&
((uintptr_t)(&rep.nOutput) & 1) == 0) *(&rep.nOutput
) = lswaps(*(&rep.nOutput)); else swap_uint16((uint16_t *
)(&rep.nOutput)); } while (0)
;
1012 swaps(&rep.nPossibleOutput)do { if (sizeof(*(&rep.nPossibleOutput)) != 2) wrong_size
(); if (__builtin_constant_p((uintptr_t)(&rep.nPossibleOutput
) & 1) && ((uintptr_t)(&rep.nPossibleOutput) &
1) == 0) *(&rep.nPossibleOutput) = lswaps(*(&rep.nPossibleOutput
)); else swap_uint16((uint16_t *)(&rep.nPossibleOutput));
} while (0)
;
1013 }
1014 WriteToClient(client, sizeof(xRRGetCrtcInfoReply), &rep);
1015 if (extraLen) {
1016 WriteToClient(client, extraLen, extra);
1017 free(extra);
1018 }
1019
1020 return Success0;
1021}
1022
1023int
1024ProcRRSetCrtcConfig(ClientPtr client)
1025{
1026 REQUEST(xRRSetCrtcConfigReq)xRRSetCrtcConfigReq *stuff = (xRRSetCrtcConfigReq *)client->
requestBuffer
;
1027 xRRSetCrtcConfigReply rep;
1028 ScreenPtr pScreen;
1029 rrScrPrivPtr pScrPriv;
1030 RRCrtcPtr crtc;
1031 RRModePtr mode;
1032 int numOutputs;
1033 RROutputPtr *outputs = NULL((void*)0);
1034 RROutput *outputIds;
1035 TimeStamp time;
1036 Rotation rotation;
1037 int ret, i, j;
1038 CARD8 status;
1039
1040 REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq)if ((sizeof(xRRSetCrtcConfigReq) >> 2) > client->
req_len ) return(16)
;
1041 numOutputs = (stuff->length - bytes_to_int32(SIZEOF(xRRSetCrtcConfigReq)28));
1042
1043 VERIFY_RR_CRTC(stuff->crtc, crtc, DixSetAttrAccess){ int rc = dixLookupResourceByType((void **)&(crtc), stuff
->crtc, RRCrtcType, client, (1<<5)); if (rc != 0) { client
->errorValue = stuff->crtc; return rc; } }
;
1044
1045 if (stuff->mode == None0L) {
1046 mode = NULL((void*)0);
1047 if (numOutputs > 0)
1048 return BadMatch8;
1049 }
1050 else {
1051 VERIFY_RR_MODE(stuff->mode, mode, DixSetAttrAccess){ int rc = dixLookupResourceByType((void **)&(mode), stuff
->mode, RRModeType, client, (1<<5)); if (rc != 0) { client
->errorValue = stuff->mode; return rc; } }
;
1052 if (numOutputs == 0)
1053 return BadMatch8;
1054 }
1055 if (numOutputs) {
1056 outputs = xallocarray(numOutputs, sizeof(RROutputPtr))xreallocarray(((void*)0), (numOutputs), (sizeof(RROutputPtr))
)
;
1057 if (!outputs)
1058 return BadAlloc11;
1059 }
1060 else
1061 outputs = NULL((void*)0);
1062
1063 outputIds = (RROutput *) (stuff + 1);
1064 for (i = 0; i < numOutputs; i++) {
1065 ret = dixLookupResourceByType((void **) (outputs + i), outputIds[i],
1066 RROutputType, client, DixSetAttrAccess(1<<5));
1067 if (ret != Success0) {
1068 free(outputs);
1069 return ret;
1070 }
1071 /* validate crtc for this output */
1072 for (j = 0; j < outputs[i]->numCrtcs; j++)
1073 if (outputs[i]->crtcs[j] == crtc)
1074 break;
1075 if (j == outputs[i]->numCrtcs) {
1076 free(outputs);
1077 return BadMatch8;
1078 }
1079 /* validate mode for this output */
1080 for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++) {
1081 RRModePtr m = (j < outputs[i]->numModes ?
1082 outputs[i]->modes[j] :
1083 outputs[i]->userModes[j - outputs[i]->numModes]);
1084 if (m == mode)
1085 break;
1086 }
1087 if (j == outputs[i]->numModes + outputs[i]->numUserModes) {
1088 free(outputs);
1089 return BadMatch8;
1090 }
1091 }
1092 /* validate clones */
1093 for (i = 0; i < numOutputs; i++) {
1094 for (j = 0; j < numOutputs; j++) {
1095 int k;
1096
1097 if (i == j)
1098 continue;
1099 for (k = 0; k < outputs[i]->numClones; k++) {
1100 if (outputs[i]->clones[k] == outputs[j])
1101 break;
1102 }
1103 if (k == outputs[i]->numClones) {
1104 free(outputs);
1105 return BadMatch8;
1106 }
1107 }
1108 }
1109
1110 pScreen = crtc->pScreen;
1111 pScrPriv = rrGetScrPriv(pScreen)((rrScrPrivPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&rrPrivKeyRec)))
;
1112
1113 time = ClientTimeToServerTime(stuff->timestamp);
1114
1115 if (!pScrPriv) {
1116 time = currentTime;
1117 status = RRSetConfigFailed3;
1118 goto sendReply;
1119 }
1120
1121 /*
1122 * Validate requested rotation
1123 */
1124 rotation = (Rotation) stuff->rotation;
1125
1126 /* test the rotation bits only! */
1127 switch (rotation & 0xf) {
1128 case RR_Rotate_01:
1129 case RR_Rotate_902:
1130 case RR_Rotate_1804:
1131 case RR_Rotate_2708:
1132 break;
1133 default:
1134 /*
1135 * Invalid rotation
1136 */
1137 client->errorValue = stuff->rotation;
1138 free(outputs);
1139 return BadValue2;
1140 }
1141
1142 if (mode) {
1143 if ((~crtc->rotations) & rotation) {
1144 /*
1145 * requested rotation or reflection not supported by screen
1146 */
1147 client->errorValue = stuff->rotation;
1148 free(outputs);
1149 return BadMatch8;
1150 }
1151
1152#ifdef RANDR_12_INTERFACE1
1153 /*
1154 * Check screen size bounds if the DDX provides a 1.2 interface
1155 * for setting screen size. Else, assume the CrtcSet sets
1156 * the size along with the mode. If the driver supports transforms,
1157 * then it must allow crtcs to display a subset of the screen, so
1158 * only do this check for drivers without transform support.
1159 */
1160 if (pScrPriv->rrScreenSetSize && !crtc->transforms) {
1161 int source_width;
1162 int source_height;
1163 PictTransform transform;
1164 struct pixman_f_transform f_transform, f_inverse;
1165 int width, height;
1166
1167 if (pScreen->isGPU) {
1168 width = pScreen->current_master->width;
1169 height = pScreen->current_master->height;
1170 }
1171 else {
1172 width = pScreen->width;
1173 height = pScreen->height;
1174 }
1175
1176 RRTransformCompute(stuff->x, stuff->y,
1177 mode->mode.width, mode->mode.height,
1178 rotation,
1179 &crtc->client_pending_transform,
1180 &transform, &f_transform, &f_inverse);
1181
1182 RRModeGetScanoutSize(mode, &transform, &source_width,
1183 &source_height);
1184 if (stuff->x + source_width > width) {
1185 client->errorValue = stuff->x;
1186 free(outputs);
1187 return BadValue2;
1188 }
1189
1190 if (stuff->y + source_height > height) {
1191 client->errorValue = stuff->y;
1192 free(outputs);
1193 return BadValue2;
1194 }
1195 }
1196#endif
1197 }
1198
1199 if (!RRCrtcSet(crtc, mode, stuff->x, stuff->y,
1200 rotation, numOutputs, outputs)) {
1201 status = RRSetConfigFailed3;
1202 goto sendReply;
1203 }
1204 status = RRSetConfigSuccess0;
1205 pScrPriv->lastSetTime = time;
1206
1207 sendReply:
1208 free(outputs);
1209
1210 rep = (xRRSetCrtcConfigReply) {
1211 .type = X_Reply1,
1212 .status = status,
1213 .sequenceNumber = client->sequence,
1214 .length = 0,
1215 .newTimestamp = pScrPriv->lastSetTime.milliseconds
1216 };
1217
1218 if (client->swapped) {
1219 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)
;
1220 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)
;
1221 swapl(&rep.newTimestamp)do { if (sizeof(*(&rep.newTimestamp)) != 4) wrong_size();
if (__builtin_constant_p((uintptr_t)(&rep.newTimestamp) &
3) && ((uintptr_t)(&rep.newTimestamp) & 3) ==
0) *(&rep.newTimestamp) = lswapl(*(&rep.newTimestamp
)); else swap_uint32((uint32_t *)(&rep.newTimestamp)); } while
(0)
;
1222 }
1223 WriteToClient(client, sizeof(xRRSetCrtcConfigReply), &rep);
1224
1225 return Success0;
1226}
1227
1228int
1229ProcRRGetPanning(ClientPtr client)
1230{
1231 REQUEST(xRRGetPanningReq)xRRGetPanningReq *stuff = (xRRGetPanningReq *)client->requestBuffer;
1232 xRRGetPanningReply rep;
1233 RRCrtcPtr crtc;
1234 ScreenPtr pScreen;
1235 rrScrPrivPtr pScrPriv;
1236 BoxRec total;
1237 BoxRec tracking;
1238 INT16 border[4];
1239
1240 REQUEST_SIZE_MATCH(xRRGetPanningReq)if ((sizeof(xRRGetPanningReq) >> 2) != client->req_len
) return(16)
;
1241 VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess){ int rc = dixLookupResourceByType((void **)&(crtc), stuff
->crtc, RRCrtcType, client, (1<<0)); if (rc != 0) { client
->errorValue = stuff->crtc; return rc; } }
;
1242
1243 /* All crtcs must be associated with screens before client
1244 * requests are processed
1245 */
1246 pScreen = crtc->pScreen;
1247 pScrPriv = rrGetScrPriv(pScreen)((rrScrPrivPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&rrPrivKeyRec)))
;
1248
1249 if (!pScrPriv)
1250 return RRErrorBase + BadRRCrtc1;
1251
1252 rep = (xRRGetPanningReply) {
1253 .type = X_Reply1,
1254 .status = RRSetConfigSuccess0,
1255 .sequenceNumber = client->sequence,
1256 .length = 1,
1257 .timestamp = pScrPriv->lastSetTime.milliseconds
1258 };
1259
1260 if (pScrPriv->rrGetPanning &&
1261 pScrPriv->rrGetPanning(pScreen, crtc, &total, &tracking, border)) {
1262 rep.left = total.x1;
1263 rep.top = total.y1;
1264 rep.width = total.x2 - total.x1;
1265 rep.height = total.y2 - total.y1;
1266 rep.track_left = tracking.x1;
1267 rep.track_top = tracking.y1;
1268 rep.track_width = tracking.x2 - tracking.x1;
1269 rep.track_height = tracking.y2 - tracking.y1;
1270 rep.border_left = border[0];
1271 rep.border_top = border[1];
1272 rep.border_right = border[2];
1273 rep.border_bottom = border[3];
1274 }
1275
1276 if (client->swapped) {
1277 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)
;
1278 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)
;
1279 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)
;
1280 swaps(&rep.left)do { if (sizeof(*(&rep.left)) != 2) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&rep.left) & 1) && ((uintptr_t)(
&rep.left) & 1) == 0) *(&rep.left) = lswaps(*(&
rep.left)); else swap_uint16((uint16_t *)(&rep.left)); } while
(0)
;
1281 swaps(&rep.top)do { if (sizeof(*(&rep.top)) != 2) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&rep.top) & 1) && ((uintptr_t)(&
rep.top) & 1) == 0) *(&rep.top) = lswaps(*(&rep.top
)); else swap_uint16((uint16_t *)(&rep.top)); } while (0)
;
1282 swaps(&rep.width)do { if (sizeof(*(&rep.width)) != 2) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&rep.width) & 1) && ((uintptr_t)
(&rep.width) & 1) == 0) *(&rep.width) = lswaps(*(
&rep.width)); else swap_uint16((uint16_t *)(&rep.width
)); } while (0)
;
1283 swaps(&rep.height)do { if (sizeof(*(&rep.height)) != 2) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&rep.height) & 1) && ((uintptr_t
)(&rep.height) & 1) == 0) *(&rep.height) = lswaps
(*(&rep.height)); else swap_uint16((uint16_t *)(&rep.
height)); } while (0)
;
1284 swaps(&rep.track_left)do { if (sizeof(*(&rep.track_left)) != 2) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&rep.track_left) &
1) && ((uintptr_t)(&rep.track_left) & 1) == 0
) *(&rep.track_left) = lswaps(*(&rep.track_left)); else
swap_uint16((uint16_t *)(&rep.track_left)); } while (0)
;
1285 swaps(&rep.track_top)do { if (sizeof(*(&rep.track_top)) != 2) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&rep.track_top) & 1
) && ((uintptr_t)(&rep.track_top) & 1) == 0) *
(&rep.track_top) = lswaps(*(&rep.track_top)); else swap_uint16
((uint16_t *)(&rep.track_top)); } while (0)
;
1286 swaps(&rep.track_width)do { if (sizeof(*(&rep.track_width)) != 2) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&rep.track_width) &
1) && ((uintptr_t)(&rep.track_width) & 1) ==
0) *(&rep.track_width) = lswaps(*(&rep.track_width))
; else swap_uint16((uint16_t *)(&rep.track_width)); } while
(0)
;
1287 swaps(&rep.track_height)do { if (sizeof(*(&rep.track_height)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&rep.track_height) &
1) && ((uintptr_t)(&rep.track_height) & 1) ==
0) *(&rep.track_height) = lswaps(*(&rep.track_height
)); else swap_uint16((uint16_t *)(&rep.track_height)); } while
(0)
;
1288 swaps(&rep.border_left)do { if (sizeof(*(&rep.border_left)) != 2) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&rep.border_left) &
1) && ((uintptr_t)(&rep.border_left) & 1) ==
0) *(&rep.border_left) = lswaps(*(&rep.border_left))
; else swap_uint16((uint16_t *)(&rep.border_left)); } while
(0)
;
1289 swaps(&rep.border_top)do { if (sizeof(*(&rep.border_top)) != 2) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&rep.border_top) &
1) && ((uintptr_t)(&rep.border_top) & 1) == 0
) *(&rep.border_top) = lswaps(*(&rep.border_top)); else
swap_uint16((uint16_t *)(&rep.border_top)); } while (0)
;
1290 swaps(&rep.border_right)do { if (sizeof(*(&rep.border_right)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&rep.border_right) &
1) && ((uintptr_t)(&rep.border_right) & 1) ==
0) *(&rep.border_right) = lswaps(*(&rep.border_right
)); else swap_uint16((uint16_t *)(&rep.border_right)); } while
(0)
;
1291 swaps(&rep.border_bottom)do { if (sizeof(*(&rep.border_bottom)) != 2) wrong_size()
; if (__builtin_constant_p((uintptr_t)(&rep.border_bottom
) & 1) && ((uintptr_t)(&rep.border_bottom) &
1) == 0) *(&rep.border_bottom) = lswaps(*(&rep.border_bottom
)); else swap_uint16((uint16_t *)(&rep.border_bottom)); }
while (0)
;
1292 }
1293 WriteToClient(client, sizeof(xRRGetPanningReply), &rep);
1294 return Success0;
1295}
1296
1297int
1298ProcRRSetPanning(ClientPtr client)
1299{
1300 REQUEST(xRRSetPanningReq)xRRSetPanningReq *stuff = (xRRSetPanningReq *)client->requestBuffer;
1301 xRRSetPanningReply rep;
1302 RRCrtcPtr crtc;
1303 ScreenPtr pScreen;
1304 rrScrPrivPtr pScrPriv;
1305 TimeStamp time;
1306 BoxRec total;
1307 BoxRec tracking;
1308 INT16 border[4];
1309 CARD8 status;
1310
1311 REQUEST_SIZE_MATCH(xRRSetPanningReq)if ((sizeof(xRRSetPanningReq) >> 2) != client->req_len
) return(16)
;
1312 VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess){ int rc = dixLookupResourceByType((void **)&(crtc), stuff
->crtc, RRCrtcType, client, (1<<0)); if (rc != 0) { client
->errorValue = stuff->crtc; return rc; } }
;
1313
1314 /* All crtcs must be associated with screens before client
1315 * requests are processed
1316 */
1317 pScreen = crtc->pScreen;
1318 pScrPriv = rrGetScrPriv(pScreen)((rrScrPrivPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&rrPrivKeyRec)))
;
1319
1320 if (!pScrPriv) {
1321 time = currentTime;
1322 status = RRSetConfigFailed3;
1323 goto sendReply;
1324 }
1325
1326 time = ClientTimeToServerTime(stuff->timestamp);
1327
1328 if (!pScrPriv->rrGetPanning)
1329 return RRErrorBase + BadRRCrtc1;
1330
1331 total.x1 = stuff->left;
1332 total.y1 = stuff->top;
1333 total.x2 = total.x1 + stuff->width;
1334 total.y2 = total.y1 + stuff->height;
1335 tracking.x1 = stuff->track_left;
1336 tracking.y1 = stuff->track_top;
1337 tracking.x2 = tracking.x1 + stuff->track_width;
1338 tracking.y2 = tracking.y1 + stuff->track_height;
1339 border[0] = stuff->border_left;
1340 border[1] = stuff->border_top;
1341 border[2] = stuff->border_right;
1342 border[3] = stuff->border_bottom;
1343
1344 if (!pScrPriv->rrSetPanning(pScreen, crtc, &total, &tracking, border))
1345 return BadMatch8;
1346
1347 pScrPriv->lastSetTime = time;
1348
1349 status = RRSetConfigSuccess0;
1350
1351 sendReply:
1352 rep = (xRRSetPanningReply) {
1353 .type = X_Reply1,
1354 .status = status,
1355 .sequenceNumber = client->sequence,
1356 .length = 0,
1357 .newTimestamp = pScrPriv->lastSetTime.milliseconds
1358 };
1359
1360 if (client->swapped) {
1361 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)
;
1362 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)
;
1363 swapl(&rep.newTimestamp)do { if (sizeof(*(&rep.newTimestamp)) != 4) wrong_size();
if (__builtin_constant_p((uintptr_t)(&rep.newTimestamp) &
3) && ((uintptr_t)(&rep.newTimestamp) & 3) ==
0) *(&rep.newTimestamp) = lswapl(*(&rep.newTimestamp
)); else swap_uint32((uint32_t *)(&rep.newTimestamp)); } while
(0)
;
1364 }
1365 WriteToClient(client, sizeof(xRRSetPanningReply), &rep);
1366 return Success0;
1367}
1368
1369int
1370ProcRRGetCrtcGammaSize(ClientPtr client)
1371{
1372 REQUEST(xRRGetCrtcGammaSizeReq)xRRGetCrtcGammaSizeReq *stuff = (xRRGetCrtcGammaSizeReq *)client
->requestBuffer
;
1373 xRRGetCrtcGammaSizeReply reply;
1374 RRCrtcPtr crtc;
1375
1376 REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq)if ((sizeof(xRRGetCrtcGammaSizeReq) >> 2) != client->
req_len) return(16)
;
1377 VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess){ int rc = dixLookupResourceByType((void **)&(crtc), stuff
->crtc, RRCrtcType, client, (1<<0)); if (rc != 0) { client
->errorValue = stuff->crtc; return rc; } }
;
1378
1379 /* Gamma retrieval failed, any better error? */
1380 if (!RRCrtcGammaGet(crtc))
1381 return RRErrorBase + BadRRCrtc1;
1382
1383 reply = (xRRGetCrtcGammaSizeReply) {
1384 .type = X_Reply1,
1385 .sequenceNumber = client->sequence,
1386 .length = 0,
1387 .size = crtc->gammaSize
1388 };
1389 if (client->swapped) {
1390 swaps(&reply.sequenceNumber)do { if (sizeof(*(&reply.sequenceNumber)) != 2) wrong_size
(); if (__builtin_constant_p((uintptr_t)(&reply.sequenceNumber
) & 1) && ((uintptr_t)(&reply.sequenceNumber)
& 1) == 0) *(&reply.sequenceNumber) = lswaps(*(&
reply.sequenceNumber)); else swap_uint16((uint16_t *)(&reply
.sequenceNumber)); } while (0)
;
1391 swapl(&reply.length)do { if (sizeof(*(&reply.length)) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&reply.length) & 3) &&
((uintptr_t)(&reply.length) & 3) == 0) *(&reply.
length) = lswapl(*(&reply.length)); else swap_uint32((uint32_t
*)(&reply.length)); } while (0)
;
1392 swaps(&reply.size)do { if (sizeof(*(&reply.size)) != 2) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&reply.size) & 1) && ((uintptr_t
)(&reply.size) & 1) == 0) *(&reply.size) = lswaps
(*(&reply.size)); else swap_uint16((uint16_t *)(&reply
.size)); } while (0)
;
1393 }
1394 WriteToClient(client, sizeof(xRRGetCrtcGammaSizeReply), &reply);
1395 return Success0;
1396}
1397
1398int
1399ProcRRGetCrtcGamma(ClientPtr client)
1400{
1401 REQUEST(xRRGetCrtcGammaReq)xRRGetCrtcGammaReq *stuff = (xRRGetCrtcGammaReq *)client->
requestBuffer
;
1402 xRRGetCrtcGammaReply reply;
1403 RRCrtcPtr crtc;
1404 unsigned long len;
1405 char *extra = NULL((void*)0);
1406
1407 REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq)if ((sizeof(xRRGetCrtcGammaReq) >> 2) != client->req_len
) return(16)
;
1408 VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess){ int rc = dixLookupResourceByType((void **)&(crtc), stuff
->crtc, RRCrtcType, client, (1<<0)); if (rc != 0) { client
->errorValue = stuff->crtc; return rc; } }
;
1409
1410 /* Gamma retrieval failed, any better error? */
1411 if (!RRCrtcGammaGet(crtc))
1412 return RRErrorBase + BadRRCrtc1;
1413
1414 len = crtc->gammaSize * 3 * 2;
1415
1416 if (crtc->gammaSize) {
1417 extra = malloc(len);
1418 if (!extra)
1419 return BadAlloc11;
1420 }
1421
1422 reply = (xRRGetCrtcGammaReply) {
1423 .type = X_Reply1,
1424 .sequenceNumber = client->sequence,
1425 .length = bytes_to_int32(len),
1426 .size = crtc->gammaSize
1427 };
1428 if (client->swapped) {
1429 swaps(&reply.sequenceNumber)do { if (sizeof(*(&reply.sequenceNumber)) != 2) wrong_size
(); if (__builtin_constant_p((uintptr_t)(&reply.sequenceNumber
) & 1) && ((uintptr_t)(&reply.sequenceNumber)
& 1) == 0) *(&reply.sequenceNumber) = lswaps(*(&
reply.sequenceNumber)); else swap_uint16((uint16_t *)(&reply
.sequenceNumber)); } while (0)
;
1430 swapl(&reply.length)do { if (sizeof(*(&reply.length)) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&reply.length) & 3) &&
((uintptr_t)(&reply.length) & 3) == 0) *(&reply.
length) = lswapl(*(&reply.length)); else swap_uint32((uint32_t
*)(&reply.length)); } while (0)
;
1431 swaps(&reply.size)do { if (sizeof(*(&reply.size)) != 2) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&reply.size) & 1) && ((uintptr_t
)(&reply.size) & 1) == 0) *(&reply.size) = lswaps
(*(&reply.size)); else swap_uint16((uint16_t *)(&reply
.size)); } while (0)
;
1432 }
1433 WriteToClient(client, sizeof(xRRGetCrtcGammaReply), &reply);
1434 if (crtc->gammaSize) {
1435 memcpy(extra, crtc->gammaRed, len)__builtin___memcpy_chk (extra, crtc->gammaRed, len, __builtin_object_size
(extra, 0))
;
1436 client->pSwapReplyFunc = (ReplySwapPtr) CopySwap16Write;
1437 WriteSwappedDataToClient(client, len, extra)if ((client)->swapped) (*(client)->pSwapReplyFunc)(client
, (int)(len), extra); else WriteToClient(client, (int)(len), (
extra));
;
1438 free(extra);
1439 }
1440 return Success0;
1441}
1442
1443int
1444ProcRRSetCrtcGamma(ClientPtr client)
1445{
1446 REQUEST(xRRSetCrtcGammaReq)xRRSetCrtcGammaReq *stuff = (xRRSetCrtcGammaReq *)client->
requestBuffer
;
1447 RRCrtcPtr crtc;
1448 unsigned long len;
1449 CARD16 *red, *green, *blue;
1450
1451 REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq)if ((sizeof(xRRSetCrtcGammaReq) >> 2) > client->req_len
) return(16)
;
1452 VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess){ int rc = dixLookupResourceByType((void **)&(crtc), stuff
->crtc, RRCrtcType, client, (1<<0)); if (rc != 0) { client
->errorValue = stuff->crtc; return rc; } }
;
1453
1454 len = client->req_len - bytes_to_int32(sizeof(xRRSetCrtcGammaReq));
1455 if (len < (stuff->size * 3 + 1) >> 1)
1456 return BadLength16;
1457
1458 if (stuff->size != crtc->gammaSize)
1459 return BadMatch8;
1460
1461 red = (CARD16 *) (stuff + 1);
1462 green = red + crtc->gammaSize;
1463 blue = green + crtc->gammaSize;
1464
1465 RRCrtcGammaSet(crtc, red, green, blue);
1466
1467 return Success0;
1468}
1469
1470/* Version 1.3 additions */
1471
1472int
1473ProcRRSetCrtcTransform(ClientPtr client)
1474{
1475 REQUEST(xRRSetCrtcTransformReq)xRRSetCrtcTransformReq *stuff = (xRRSetCrtcTransformReq *)client
->requestBuffer
;
1476 RRCrtcPtr crtc;
1477 PictTransform transform;
1478 struct pixman_f_transform f_transform, f_inverse;
1479 char *filter;
1480 int nbytes;
1481 xFixed *params;
1482 int nparams;
1483
1484 REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq)if ((sizeof(xRRSetCrtcTransformReq) >> 2) > client->
req_len ) return(16)
;
1485 VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess){ int rc = dixLookupResourceByType((void **)&(crtc), stuff
->crtc, RRCrtcType, client, (1<<0)); if (rc != 0) { client
->errorValue = stuff->crtc; return rc; } }
;
1486
1487 PictTransform_from_xRenderTransform(&transform, &stuff->transform);
1488 pixman_f_transform_from_pixman_transform(&f_transform, &transform);
1489 if (!pixman_f_transform_invert(&f_inverse, &f_transform))
1490 return BadMatch8;
1491
1492 filter = (char *) (stuff + 1);
1493 nbytes = stuff->nbytesFilter;
1494 params = (xFixed *) (filter + pad_to_int32(nbytes));
1495 nparams = ((xFixed *) stuff + client->req_len) - params;
1496 if (nparams < 0)
1497 return BadLength16;
1498
1499 return RRCrtcTransformSet(crtc, &transform, &f_transform, &f_inverse,
1500 filter, nbytes, params, nparams);
1501}
1502
1503#define CrtcTransformExtra(96 - 32) (SIZEOF(xRRGetCrtcTransformReply)96 - 32)
1504
1505static int
1506transform_filter_length(RRTransformPtr transform)
1507{
1508 int nbytes, nparams;
1509
1510 if (transform->filter == NULL((void*)0))
1511 return 0;
1512 nbytes = strlen(transform->filter->name);
1513 nparams = transform->nparams;
1514 return pad_to_int32(nbytes) + (nparams * sizeof(xFixed));
1515}
1516
1517static int
1518transform_filter_encode(ClientPtr client, char *output,
1519 CARD16 *nbytesFilter,
1520 CARD16 *nparamsFilter, RRTransformPtr transform)
1521{
1522 int nbytes, nparams;
1523
1524 if (transform->filter == NULL((void*)0)) {
1525 *nbytesFilter = 0;
1526 *nparamsFilter = 0;
1527 return 0;
1528 }
1529 nbytes = strlen(transform->filter->name);
1530 nparams = transform->nparams;
1531 *nbytesFilter = nbytes;
1532 *nparamsFilter = nparams;
1533 memcpy(output, transform->filter->name, nbytes)__builtin___memcpy_chk (output, transform->filter->name
, nbytes, __builtin_object_size (output, 0))
;
1534 while ((nbytes & 3) != 0)
1535 output[nbytes++] = 0;
1536 memcpy(output + nbytes, transform->params, nparams * sizeof(xFixed))__builtin___memcpy_chk (output + nbytes, transform->params
, nparams * sizeof(xFixed), __builtin_object_size (output + nbytes
, 0))
;
1537 if (client->swapped) {
1538 swaps(nbytesFilter)do { if (sizeof(*(nbytesFilter)) != 2) wrong_size(); if (__builtin_constant_p
((uintptr_t)(nbytesFilter) & 1) && ((uintptr_t)(nbytesFilter
) & 1) == 0) *(nbytesFilter) = lswaps(*(nbytesFilter)); else
swap_uint16((uint16_t *)(nbytesFilter)); } while (0)
;
1539 swaps(nparamsFilter)do { if (sizeof(*(nparamsFilter)) != 2) wrong_size(); if (__builtin_constant_p
((uintptr_t)(nparamsFilter) & 1) && ((uintptr_t)(
nparamsFilter) & 1) == 0) *(nparamsFilter) = lswaps(*(nparamsFilter
)); else swap_uint16((uint16_t *)(nparamsFilter)); } while (0
)
;
1540 SwapLongs((CARD32 *) (output + nbytes), nparams);
1541 }
1542 nbytes += nparams * sizeof(xFixed);
1543 return nbytes;
1544}
1545
1546static void
1547transform_encode(ClientPtr client, xRenderTransform * wire,
1548 PictTransform * pict)
1549{
1550 xRenderTransform_from_PictTransform(wire, pict);
1551 if (client->swapped)
1552 SwapLongs((CARD32 *) wire, bytes_to_int32(sizeof(xRenderTransform)));
1553}
1554
1555int
1556ProcRRGetCrtcTransform(ClientPtr client)
1557{
1558 REQUEST(xRRGetCrtcTransformReq)xRRGetCrtcTransformReq *stuff = (xRRGetCrtcTransformReq *)client
->requestBuffer
;
1559 xRRGetCrtcTransformReply *reply;
1560 RRCrtcPtr crtc;
1561 int nextra;
1562 RRTransformPtr current, pending;
1563 char *extra;
1564
1565 REQUEST_SIZE_MATCH(xRRGetCrtcTransformReq)if ((sizeof(xRRGetCrtcTransformReq) >> 2) != client->
req_len) return(16)
;
1566 VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess){ int rc = dixLookupResourceByType((void **)&(crtc), stuff
->crtc, RRCrtcType, client, (1<<0)); if (rc != 0) { client
->errorValue = stuff->crtc; return rc; } }
;
1567
1568 pending = &crtc->client_pending_transform;
1569 current = &crtc->client_current_transform;
1570
1571 nextra = (transform_filter_length(pending) +
1572 transform_filter_length(current));
1573
1574 reply = calloc(1, sizeof(xRRGetCrtcTransformReply) + nextra);
1575 if (!reply)
1576 return BadAlloc11;
1577
1578 extra = (char *) (reply + 1);
1579 reply->type = X_Reply1;
1580 reply->sequenceNumber = client->sequence;
1581 reply->length = bytes_to_int32(CrtcTransformExtra(96 - 32) + nextra);
1582
1583 reply->hasTransforms = crtc->transforms;
1584
1585 transform_encode(client, &reply->pendingTransform, &pending->transform);
1586 extra += transform_filter_encode(client, extra,
1587 &reply->pendingNbytesFilter,
1588 &reply->pendingNparamsFilter, pending);
1589
1590 transform_encode(client, &reply->currentTransform, &current->transform);
1591 extra += transform_filter_encode(client, extra,
Value stored to 'extra' is never read
1592 &reply->currentNbytesFilter,
1593 &reply->currentNparamsFilter, current);
1594
1595 if (client->swapped) {
1596 swaps(&reply->sequenceNumber)do { if (sizeof(*(&reply->sequenceNumber)) != 2) wrong_size
(); if (__builtin_constant_p((uintptr_t)(&reply->sequenceNumber
) & 1) && ((uintptr_t)(&reply->sequenceNumber
) & 1) == 0) *(&reply->sequenceNumber) = lswaps(*(
&reply->sequenceNumber)); else swap_uint16((uint16_t *
)(&reply->sequenceNumber)); } while (0)
;
1597 swapl(&reply->length)do { if (sizeof(*(&reply->length)) != 4) wrong_size();
if (__builtin_constant_p((uintptr_t)(&reply->length) &
3) && ((uintptr_t)(&reply->length) & 3) ==
0) *(&reply->length) = lswapl(*(&reply->length
)); else swap_uint32((uint32_t *)(&reply->length)); } while
(0)
;
1598 }
1599 WriteToClient(client, sizeof(xRRGetCrtcTransformReply) + nextra, reply);
1600 free(reply);
1601 return Success0;
1602}
1603
1604static Bool
1605check_all_screen_crtcs(ScreenPtr pScreen, int *x, int *y)
1606{
1607 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
1608 int i;
1609 for (i = 0; i < pScrPriv->numCrtcs; i++) {
1610 RRCrtcPtr crtc = pScrPriv->crtcs[i];
1611
1612 int left, right, top, bottom;
1613
1614 if (!crtc->mode)
1615 continue;
1616
1617 crtc_bounds(crtc, &left, &right, &top, &bottom);
1618
1619 if ((*x >= left) && (*x < right) && (*y >= top) && (*y < bottom))
1620 return TRUE1;
1621 }
1622 return FALSE0;
1623}
1624
1625static Bool
1626constrain_all_screen_crtcs(DeviceIntPtr pDev, ScreenPtr pScreen, int *x, int *y)
1627{
1628 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
1629 int i;
1630
1631 /* if we're trying to escape, clamp to the CRTC we're coming from */
1632 for (i = 0; i < pScrPriv->numCrtcs; i++) {
1633 RRCrtcPtr crtc = pScrPriv->crtcs[i];
1634 int nx, ny;
1635 int left, right, top, bottom;
1636
1637 if (!crtc->mode)
1638 continue;
1639
1640 crtc_bounds(crtc, &left, &right, &top, &bottom);
1641 miPointerGetPosition(pDev, &nx, &ny);
1642
1643 if ((nx >= left) && (nx < right) && (ny >= top) && (ny < bottom)) {
1644 if (*x < left)
1645 *x = left;
1646 if (*x >= right)
1647 *x = right - 1;
1648 if (*y < top)
1649 *y = top;
1650 if (*y >= bottom)
1651 *y = bottom - 1;
1652
1653 return TRUE1;
1654 }
1655 }
1656 return FALSE0;
1657}
1658
1659void
1660RRConstrainCursorHarder(DeviceIntPtr pDev, ScreenPtr pScreen, int mode, int *x,
1661 int *y)
1662{
1663 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
1664 Bool ret;
1665 ScreenPtr slave;
1666
1667 /* intentional dead space -> let it float */
1668 if (pScrPriv->discontiguous)
1669 return;
1670
1671 /* if we're moving inside a crtc, we're fine */
1672 ret = check_all_screen_crtcs(pScreen, x, y);
1673 if (ret == TRUE1)
1674 return;
1675
1676 xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head)for (slave = ((void*)0), slave = (typeof(*slave) *)((char *)(
(&pScreen->output_slave_list)->next) - __builtin_offsetof
(typeof(*slave), output_head)); &slave->output_head !=
(&pScreen->output_slave_list); slave = (typeof(*slave
) *)((char *)(slave->output_head.next) - __builtin_offsetof
(typeof(*slave), output_head)))
{
1677 ret = check_all_screen_crtcs(slave, x, y);
1678 if (ret == TRUE1)
1679 return;
1680 }
1681
1682 /* if we're trying to escape, clamp to the CRTC we're coming from */
1683 ret = constrain_all_screen_crtcs(pDev, pScreen, x, y);
1684 if (ret == TRUE1)
1685 return;
1686
1687 xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head)for (slave = ((void*)0), slave = (typeof(*slave) *)((char *)(
(&pScreen->output_slave_list)->next) - __builtin_offsetof
(typeof(*slave), output_head)); &slave->output_head !=
(&pScreen->output_slave_list); slave = (typeof(*slave
) *)((char *)(slave->output_head.next) - __builtin_offsetof
(typeof(*slave), output_head)))
{
1688 ret = constrain_all_screen_crtcs(pDev, slave, x, y);
1689 if (ret == TRUE1)
1690 return;
1691 }
1692}
1693
1694Bool
1695RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable)
1696{
1697 rrScrPriv(pDrawable->pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pDrawable->pScreen)->devPrivates, (&rrPrivKeyRec))
)
;
1698 Bool ret = TRUE1;
1699 PixmapPtr *saved_scanout_pixmap;
1700 int i;
1701
1702 saved_scanout_pixmap = malloc(sizeof(PixmapPtr)*pScrPriv->numCrtcs);
1703 if (saved_scanout_pixmap == NULL((void*)0))
1704 return FALSE0;
1705
1706 for (i = 0; i < pScrPriv->numCrtcs; i++) {
1707 RRCrtcPtr crtc = pScrPriv->crtcs[i];
1708 Bool size_fits;
1709
1710 saved_scanout_pixmap[i] = crtc->scanout_pixmap;
1711
1712 if (!crtc->mode && enable)
1713 continue;
1714 if (!crtc->scanout_pixmap && !enable)
1715 continue;
1716
1717 size_fits = (crtc->mode &&
1718 crtc->x == pDrawable->x &&
1719 crtc->y == pDrawable->y &&
1720 crtc->mode->mode.width == pDrawable->width &&
1721 crtc->mode->mode.height == pDrawable->height);
1722
1723 /* is the pixmap already set? */
1724 if (crtc->scanout_pixmap == pPixmap) {
1725 /* if its a disable then don't care about size */
1726 if (enable == FALSE0) {
1727 /* set scanout to NULL */
1728 crtc->scanout_pixmap = NULL((void*)0);
1729 }
1730 else if (!size_fits) {
1731 /* if the size no longer fits then drop off */
1732 crtc->scanout_pixmap = NULL((void*)0);
1733 pScrPriv->rrCrtcSetScanoutPixmap(crtc, crtc->scanout_pixmap);
1734
1735 (*pScrPriv->rrCrtcSet) (pDrawable->pScreen, crtc, crtc->mode, crtc->x, crtc->y,
1736 crtc->rotation, crtc->numOutputs, crtc->outputs);
1737 saved_scanout_pixmap[i] = crtc->scanout_pixmap;
1738 ret = FALSE0;
1739 }
1740 else {
1741 /* if the size fits then we are already setup */
1742 }
1743 }
1744 else {
1745 if (!size_fits)
1746 ret = FALSE0;
1747 else if (enable)
1748 crtc->scanout_pixmap = pPixmap;
1749 else
1750 /* reject an attempt to disable someone else's scanout_pixmap */
1751 ret = FALSE0;
1752 }
1753 }
1754
1755 for (i = 0; i < pScrPriv->numCrtcs; i++) {
1756 RRCrtcPtr crtc = pScrPriv->crtcs[i];
1757
1758 if (crtc->scanout_pixmap == saved_scanout_pixmap[i])
1759 continue;
1760
1761 if (ret) {
1762 pScrPriv->rrCrtcSetScanoutPixmap(crtc, crtc->scanout_pixmap);
1763
1764 (*pScrPriv->rrCrtcSet) (pDrawable->pScreen, crtc, crtc->mode, crtc->x, crtc->y,
1765 crtc->rotation, crtc->numOutputs, crtc->outputs);
1766 }
1767 else
1768 crtc->scanout_pixmap = saved_scanout_pixmap[i];
1769 }
1770 free(saved_scanout_pixmap);
1771
1772 return ret;
1773}