Bug Summary

File:randr/rrcrtc.c
Location:line 1141, column 9
Description:Value stored to 'time' 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
364static void
365rrDestroySharedPixmap(RRCrtcPtr crtc, PixmapPtr pPixmap) {
366 ScreenPtr master = crtc->pScreen->current_master;
367
368 if (master && pPixmap->master_pixmap) {
369 PixmapPtr mscreenpix = master->GetScreenPixmap(master);
370
371 master->StopPixmapTracking(mscreenpix, pPixmap);
372 /*
373 * Unref the pixmap twice: once for the original reference, and once
374 * for the reference implicitly added by PixmapShareToSlave.
375 */
376 master->DestroyPixmap(pPixmap->master_pixmap);
377 master->DestroyPixmap(pPixmap->master_pixmap);
378 }
379
380 crtc->pScreen->DestroyPixmap(pPixmap);
381}
382
383void
384RRCrtcDetachScanoutPixmap(RRCrtcPtr crtc)
385{
386 rrScrPriv(crtc->pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(crtc->pScreen)->devPrivates, (&rrPrivKeyRec)))
;
387
388 pScrPriv->rrCrtcSetScanoutPixmap(crtc, NULL((void*)0));
389 if (crtc->scanout_pixmap) {
390 rrDestroySharedPixmap(crtc, crtc->scanout_pixmap);
391 }
392 crtc->scanout_pixmap = NULL((void*)0);
393 RRCrtcChanged(crtc, TRUE1);
394}
395
396static PixmapPtr
397rrCreateSharedPixmap(RRCrtcPtr crtc, ScreenPtr master,
398 int width, int height, int depth,
399 int x, int y, Rotation rotation)
400{
401 Bool ret;
402 PixmapPtr mpix, spix;
403 rrScrPriv(crtc->pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(crtc->pScreen)->devPrivates, (&rrPrivKeyRec)))
;
404
405 mpix = master->CreatePixmap(master, width, height, depth,
406 CREATE_PIXMAP_USAGE_SHARED4);
407 if (!mpix)
408 return NULL((void*)0);
409
410 spix = PixmapShareToSlave(mpix, crtc->pScreen);
411 if (spix == NULL((void*)0)) {
412 master->DestroyPixmap(mpix);
413 return NULL((void*)0);
414 }
415
416 ret = pScrPriv->rrCrtcSetScanoutPixmap(crtc, spix);
417 if (ret == FALSE0) {
418 rrDestroySharedPixmap(crtc, spix);
419 ErrorF("randr: failed to set shadow slave pixmap\n");
420 return NULL((void*)0);
421 }
422
423 return spix;
424}
425
426static Bool
427rrSetupPixmapSharing(RRCrtcPtr crtc, int width, int height,
428 int x, int y, Rotation rotation)
429{
430 ScreenPtr master = crtc->pScreen->current_master;
431 int depth;
432 PixmapPtr mscreenpix;
433 PixmapPtr spix;
434
435 /* create a pixmap on the master screen,
436 then get a shared handle for it
437 create a shared pixmap on the slave screen using the handle
438 set the master screen to do dirty updates to the shared pixmap
439 from the screen pixmap.
440 set slave screen to scanout shared linear pixmap
441 */
442
443 mscreenpix = master->GetScreenPixmap(master);
444 depth = mscreenpix->drawable.depth;
445
446 if (crtc->scanout_pixmap)
447 RRCrtcDetachScanoutPixmap(crtc);
448
449 if (width == 0 && height == 0) {
450 return TRUE1;
451 }
452
453 spix = rrCreateSharedPixmap(crtc, master,
454 width, height, depth,
455 x, y, rotation);
456 if (spix == NULL((void*)0)) {
457 return FALSE0;
458 }
459
460 crtc->scanout_pixmap = spix;
461
462 master->StartPixmapTracking(mscreenpix, spix, x, y, 0, 0, rotation);
463 return TRUE1;
464}
465
466static void crtc_to_box(BoxPtr box, RRCrtcPtr crtc)
467{
468 box->x1 = crtc->x;
469 box->y1 = crtc->y;
470 switch (crtc->rotation) {
471 case RR_Rotate_01:
472 case RR_Rotate_1804:
473 default:
474 box->x2 = crtc->x + crtc->mode->mode.width;
475 box->y2 = crtc->y + crtc->mode->mode.height;
476 break;
477 case RR_Rotate_902:
478 case RR_Rotate_2708:
479 box->x2 = crtc->x + crtc->mode->mode.height;
480 box->y2 = crtc->y + crtc->mode->mode.width;
481 break;
482 }
483}
484
485static Bool
486rrCheckPixmapBounding(ScreenPtr pScreen,
487 RRCrtcPtr rr_crtc, Rotation rotation,
488 int x, int y, int w, int h)
489{
490 RegionRec root_pixmap_region, total_region, new_crtc_region;
491 int c;
492 BoxRec newbox;
493 BoxPtr newsize;
494 ScreenPtr slave;
495 int new_width, new_height;
496 PixmapPtr screen_pixmap = pScreen->GetScreenPixmap(pScreen);
497 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
498
499 PixmapRegionInit(&root_pixmap_region, screen_pixmap);
500 RegionInit(&total_region, NULL((void*)0), 0);
501
502 /* have to iterate all the crtcs of the attached gpu masters
503 and all their output slaves */
504 for (c = 0; c < pScrPriv->numCrtcs; c++) {
505 RRCrtcPtr crtc = pScrPriv->crtcs[c];
506
507 if (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 } else {
519 if (!crtc->mode)
520 continue;
521 crtc_to_box(&newbox, crtc);
522 }
523 RegionInit(&new_crtc_region, &newbox, 1);
524 RegionUnion(&total_region, &total_region, &new_crtc_region);
525 }
526
527 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)))
{
528 rrScrPrivPtr slave_priv = rrGetScrPriv(slave)((rrScrPrivPtr)dixLookupPrivate(&(slave)->devPrivates,
(&rrPrivKeyRec)))
;
529 for (c = 0; c < slave_priv->numCrtcs; c++) {
530 RRCrtcPtr slave_crtc = slave_priv->crtcs[c];
531
532 if (slave_crtc == rr_crtc) {
533 newbox.x1 = x;
534 newbox.y1 = y;
535 if (rotation == RR_Rotate_902 ||
536 rotation == RR_Rotate_2708) {
537 newbox.x2 = x + h;
538 newbox.y2 = y + w;
539 } else {
540 newbox.x2 = x + w;
541 newbox.y2 = y + h;
542 }
543 }
544 else {
545 if (!slave_crtc->mode)
546 continue;
547 crtc_to_box(&newbox, slave_crtc);
548 }
549 RegionInit(&new_crtc_region, &newbox, 1);
550 RegionUnion(&total_region, &total_region, &new_crtc_region);
551 }
552 }
553
554 newsize = RegionExtents(&total_region);
555 new_width = newsize->x2 - newsize->x1;
556 new_height = newsize->y2 - newsize->y1;
557
558 if (new_width == screen_pixmap->drawable.width &&
559 new_height == screen_pixmap->drawable.height) {
560 } else {
561 pScrPriv->rrScreenSetSize(pScreen, new_width, new_height, 0, 0);
562 }
563
564 /* set shatters TODO */
565 return TRUE1;
566}
567
568/*
569 * Request that the Crtc be reconfigured
570 */
571Bool
572RRCrtcSet(RRCrtcPtr crtc,
573 RRModePtr mode,
574 int x,
575 int y, Rotation rotation, int numOutputs, RROutputPtr * outputs)
576{
577 ScreenPtr pScreen = crtc->pScreen;
578 Bool ret = FALSE0;
579 Bool recompute = TRUE1;
580 Bool crtcChanged;
581 int o;
582
583 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
584
585 crtcChanged = FALSE0;
586 for (o = 0; o < numOutputs; o++) {
587 if (outputs[o] && outputs[o]->crtc != crtc) {
588 crtcChanged = TRUE1;
589 break;
590 }
591 }
592
593 /* See if nothing changed */
594 if (crtc->mode == mode &&
595 crtc->x == x &&
596 crtc->y == y &&
597 crtc->rotation == rotation &&
598 crtc->numOutputs == numOutputs &&
599 !memcmp(crtc->outputs, outputs, numOutputs * sizeof(RROutputPtr)) &&
600 !RRCrtcPendingProperties(crtc) && !RRCrtcPendingTransform(crtc) &&
601 !crtcChanged) {
602 recompute = FALSE0;
603 ret = TRUE1;
604 }
605 else {
606 if (pScreen->isGPU) {
607 ScreenPtr master = pScreen->current_master;
608 int width = 0, height = 0;
609
610 if (mode) {
611 width = mode->mode.width;
612 height = mode->mode.height;
613 }
614 ret = rrCheckPixmapBounding(master, crtc,
615 rotation, x, y, width, height);
616 if (!ret)
617 return FALSE0;
618
619 if (pScreen->current_master) {
620 ret = rrSetupPixmapSharing(crtc, width, height, x, y, rotation);
621 }
622 }
623#if RANDR_12_INTERFACE1
624 if (pScrPriv->rrCrtcSet) {
625 ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y,
626 rotation, numOutputs, outputs);
627 }
628 else
629#endif
630 {
631#if RANDR_10_INTERFACE1
632 if (pScrPriv->rrSetConfig) {
633 RRScreenSize size;
634 RRScreenRate rate;
635
636 if (!mode) {
637 RRCrtcNotify(crtc, NULL((void*)0), x, y, rotation, NULL((void*)0), 0, NULL((void*)0));
638 ret = TRUE1;
639 }
640 else {
641 size.width = mode->mode.width;
642 size.height = mode->mode.height;
643 if (outputs[0]->mmWidth && outputs[0]->mmHeight) {
644 size.mmWidth = outputs[0]->mmWidth;
645 size.mmHeight = outputs[0]->mmHeight;
646 }
647 else {
648 size.mmWidth = pScreen->mmWidth;
649 size.mmHeight = pScreen->mmHeight;
650 }
651 size.nRates = 1;
652 rate.rate = RRVerticalRefresh(&mode->mode);
653 size.pRates = &rate;
654 ret =
655 (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate,
656 &size);
657 /*
658 * Old 1.0 interface tied screen size to mode size
659 */
660 if (ret) {
661 RRCrtcNotify(crtc, mode, x, y, rotation, NULL((void*)0), 1,
662 outputs);
663 RRScreenSizeNotify(pScreen);
664 }
665 }
666 }
667#endif
668 }
669 if (ret) {
670
671 RRTellChanged(pScreen);
672
673 for (o = 0; o < numOutputs; o++)
674 RRPostPendingProperties(outputs[o]);
675 }
676 }
677
678 if (recompute)
679 RRComputeContiguity(pScreen);
680
681 return ret;
682}
683
684/*
685 * Return crtc transform
686 */
687RRTransformPtr
688RRCrtcGetTransform(RRCrtcPtr crtc)
689{
690 RRTransformPtr transform = &crtc->client_pending_transform;
691
692 if (pixman_transform_is_identity(&transform->transform))
693 return NULL((void*)0);
694 return transform;
695}
696
697/*
698 * Check whether the pending and current transforms are the same
699 */
700Bool
701RRCrtcPendingTransform(RRCrtcPtr crtc)
702{
703 return memcmp(&crtc->client_current_transform.transform,
704 &crtc->client_pending_transform.transform,
705 sizeof(PictTransform)) != 0;
706}
707
708/*
709 * Destroy a Crtc at shutdown
710 */
711void
712RRCrtcDestroy(RRCrtcPtr crtc)
713{
714 FreeResource(crtc->id, 0);
715}
716
717static int
718RRCrtcDestroyResource(void *value, XID pid)
719{
720 RRCrtcPtr crtc = (RRCrtcPtr) value;
721 ScreenPtr pScreen = crtc->pScreen;
722
723 if (pScreen) {
724 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
725 int i;
726
727 for (i = 0; i < pScrPriv->numCrtcs; i++) {
728 if (pScrPriv->crtcs[i] == crtc) {
729 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))
730 (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))
;
731 --pScrPriv->numCrtcs;
732 break;
733 }
734 }
735
736 RRResourcesChanged(pScreen);
737 }
738
739 if (crtc->scanout_pixmap)
740 RRCrtcDetachScanoutPixmap(crtc);
741 free(crtc->gammaRed);
742 if (crtc->mode)
743 RRModeDestroy(crtc->mode);
744 free(crtc);
745 return 1;
746}
747
748/*
749 * Request that the Crtc gamma be changed
750 */
751
752Bool
753RRCrtcGammaSet(RRCrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue)
754{
755 Bool ret = TRUE1;
756
757#if RANDR_12_INTERFACE1
758 ScreenPtr pScreen = crtc->pScreen;
759#endif
760
761 memcpy(crtc->gammaRed, red, crtc->gammaSize * sizeof(CARD16))__builtin___memcpy_chk (crtc->gammaRed, red, crtc->gammaSize
* sizeof(CARD16), __builtin_object_size (crtc->gammaRed, 0
))
;
762 memcpy(crtc->gammaGreen, green, crtc->gammaSize * sizeof(CARD16))__builtin___memcpy_chk (crtc->gammaGreen, green, crtc->
gammaSize * sizeof(CARD16), __builtin_object_size (crtc->gammaGreen
, 0))
;
763 memcpy(crtc->gammaBlue, blue, crtc->gammaSize * sizeof(CARD16))__builtin___memcpy_chk (crtc->gammaBlue, blue, crtc->gammaSize
* sizeof(CARD16), __builtin_object_size (crtc->gammaBlue,
0))
;
764#if RANDR_12_INTERFACE1
765 if (pScreen) {
766 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
767 if (pScrPriv->rrCrtcSetGamma)
768 ret = (*pScrPriv->rrCrtcSetGamma) (pScreen, crtc);
769 }
770#endif
771 return ret;
772}
773
774/*
775 * Request current gamma back from the DDX (if possible).
776 * This includes gamma size.
777 */
778Bool
779RRCrtcGammaGet(RRCrtcPtr crtc)
780{
781 Bool ret = TRUE1;
782
783#if RANDR_12_INTERFACE1
784 ScreenPtr pScreen = crtc->pScreen;
785#endif
786
787#if RANDR_12_INTERFACE1
788 if (pScreen) {
789 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
790 if (pScrPriv->rrCrtcGetGamma)
791 ret = (*pScrPriv->rrCrtcGetGamma) (pScreen, crtc);
792 }
793#endif
794 return ret;
795}
796
797/*
798 * Notify the extension that the Crtc gamma has been changed
799 * The driver calls this whenever it has changed the gamma values
800 * in the RRCrtcRec
801 */
802
803Bool
804RRCrtcGammaNotify(RRCrtcPtr crtc)
805{
806 return TRUE1; /* not much going on here */
807}
808
809static void
810RRModeGetScanoutSize(RRModePtr mode, PictTransformPtr transform,
811 int *width, int *height)
812{
813 BoxRec box;
814
815 if (mode == NULL((void*)0)) {
816 *width = 0;
817 *height = 0;
818 return;
819 }
820
821 box.x1 = 0;
822 box.y1 = 0;
823 box.x2 = mode->mode.width;
824 box.y2 = mode->mode.height;
825
826 pixman_transform_bounds(transform, &box);
827 *width = box.x2 - box.x1;
828 *height = box.y2 - box.y1;
829}
830
831/**
832 * Returns the width/height that the crtc scans out from the framebuffer
833 */
834void
835RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height)
836{
837 RRModeGetScanoutSize(crtc->mode, &crtc->transform, width, height);
838}
839
840/*
841 * Set the size of the gamma table at server startup time
842 */
843
844Bool
845RRCrtcGammaSetSize(RRCrtcPtr crtc, int size)
846{
847 CARD16 *gamma;
848
849 if (size == crtc->gammaSize)
850 return TRUE1;
851 if (size) {
852 gamma = xallocarray(size, 3 * sizeof(CARD16))xreallocarray(((void*)0), (size), (3 * sizeof(CARD16)));
853 if (!gamma)
854 return FALSE0;
855 }
856 else
857 gamma = NULL((void*)0);
858 free(crtc->gammaRed);
859 crtc->gammaRed = gamma;
860 crtc->gammaGreen = gamma + size;
861 crtc->gammaBlue = gamma + size * 2;
862 crtc->gammaSize = size;
863 return TRUE1;
864}
865
866/*
867 * Set the pending CRTC transformation
868 */
869
870int
871RRCrtcTransformSet(RRCrtcPtr crtc,
872 PictTransformPtr transform,
873 struct pixman_f_transform *f_transform,
874 struct pixman_f_transform *f_inverse,
875 char *filter_name,
876 int filter_len, xFixed * params, int nparams)
877{
878 PictFilterPtr filter = NULL((void*)0);
879 int width = 0, height = 0;
880
881 if (!crtc->transforms)
882 return BadValue2;
883
884 if (filter_len) {
885 filter = PictureFindFilter(crtc->pScreen, filter_name, filter_len);
886 if (!filter)
887 return BadName15;
888 if (filter->ValidateParams) {
889 if (!filter->ValidateParams(crtc->pScreen, filter->id,
890 params, nparams, &width, &height))
891 return BadMatch8;
892 }
893 else {
894 width = filter->width;
895 height = filter->height;
896 }
897 }
898 else {
899 if (nparams)
900 return BadMatch8;
901 }
902 if (!RRTransformSetFilter(&crtc->client_pending_transform,
903 filter, params, nparams, width, height))
904 return BadAlloc11;
905
906 crtc->client_pending_transform.transform = *transform;
907 crtc->client_pending_transform.f_transform = *f_transform;
908 crtc->client_pending_transform.f_inverse = *f_inverse;
909 return Success0;
910}
911
912/*
913 * Initialize crtc type
914 */
915Bool
916RRCrtcInit(void)
917{
918 RRCrtcType = CreateNewResourceType(RRCrtcDestroyResource, "CRTC");
919 if (!RRCrtcType)
920 return FALSE0;
921
922 return TRUE1;
923}
924
925/*
926 * Initialize crtc type error value
927 */
928void
929RRCrtcInitErrorValue(void)
930{
931 SetResourceTypeErrorValue(RRCrtcType, RRErrorBase + BadRRCrtc1);
932}
933
934int
935ProcRRGetCrtcInfo(ClientPtr client)
936{
937 REQUEST(xRRGetCrtcInfoReq)xRRGetCrtcInfoReq *stuff = (xRRGetCrtcInfoReq *)client->requestBuffer;
938 xRRGetCrtcInfoReply rep;
939 RRCrtcPtr crtc;
940 CARD8 *extra;
941 unsigned long extraLen;
942 ScreenPtr pScreen;
943 rrScrPrivPtr pScrPriv;
944 RRModePtr mode;
945 RROutput *outputs;
946 RROutput *possible;
947 int i, j, k;
948 int width, height;
949 BoxRec panned_area;
950
951 REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq)if ((sizeof(xRRGetCrtcInfoReq) >> 2) != client->req_len
) return(16)
;
952 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; } }
;
953
954 /* All crtcs must be associated with screens before client
955 * requests are processed
956 */
957 pScreen = crtc->pScreen;
958 pScrPriv = rrGetScrPriv(pScreen)((rrScrPrivPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&rrPrivKeyRec)))
;
959
960 mode = crtc->mode;
961
962 rep = (xRRGetCrtcInfoReply) {
963 .type = X_Reply1,
964 .status = RRSetConfigSuccess0,
965 .sequenceNumber = client->sequence,
966 .length = 0,
967 .timestamp = pScrPriv->lastSetTime.milliseconds
968 };
969 if (pScrPriv->rrGetPanning &&
970 pScrPriv->rrGetPanning(pScreen, crtc, &panned_area, NULL((void*)0), NULL((void*)0)) &&
971 (panned_area.x2 > panned_area.x1) && (panned_area.y2 > panned_area.y1))
972 {
973 rep.x = panned_area.x1;
974 rep.y = panned_area.y1;
975 rep.width = panned_area.x2 - panned_area.x1;
976 rep.height = panned_area.y2 - panned_area.y1;
977 }
978 else {
979 RRCrtcGetScanoutSize(crtc, &width, &height);
980 rep.x = crtc->x;
981 rep.y = crtc->y;
982 rep.width = width;
983 rep.height = height;
984 }
985 rep.mode = mode ? mode->mode.id : 0;
986 rep.rotation = crtc->rotation;
987 rep.rotations = crtc->rotations;
988 rep.nOutput = crtc->numOutputs;
989 k = 0;
990 for (i = 0; i < pScrPriv->numOutputs; i++)
991 for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++)
992 if (pScrPriv->outputs[i]->crtcs[j] == crtc)
993 k++;
994 rep.nPossibleOutput = k;
995
996 rep.length = rep.nOutput + rep.nPossibleOutput;
997
998 extraLen = rep.length << 2;
999 if (extraLen) {
1000 extra = malloc(extraLen);
1001 if (!extra)
1002 return BadAlloc11;
1003 }
1004 else
1005 extra = NULL((void*)0);
1006
1007 outputs = (RROutput *) extra;
1008 possible = (RROutput *) (outputs + rep.nOutput);
1009
1010 for (i = 0; i < crtc->numOutputs; i++) {
1011 outputs[i] = crtc->outputs[i]->id;
1012 if (client->swapped)
1013 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)
;
1014 }
1015 k = 0;
1016 for (i = 0; i < pScrPriv->numOutputs; i++)
1017 for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++)
1018 if (pScrPriv->outputs[i]->crtcs[j] == crtc) {
1019 possible[k] = pScrPriv->outputs[i]->id;
1020 if (client->swapped)
1021 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)
;
1022 k++;
1023 }
1024
1025 if (client->swapped) {
1026 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)
;
1027 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)
;
1028 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)
;
1029 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)
;
1030 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)
;
1031 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)
;
1032 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)
;
1033 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)
;
1034 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)
;
1035 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)
;
1036 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)
;
1037 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)
;
1038 }
1039 WriteToClient(client, sizeof(xRRGetCrtcInfoReply), &rep);
1040 if (extraLen) {
1041 WriteToClient(client, extraLen, extra);
1042 free(extra);
1043 }
1044
1045 return Success0;
1046}
1047
1048int
1049ProcRRSetCrtcConfig(ClientPtr client)
1050{
1051 REQUEST(xRRSetCrtcConfigReq)xRRSetCrtcConfigReq *stuff = (xRRSetCrtcConfigReq *)client->
requestBuffer
;
1052 xRRSetCrtcConfigReply rep;
1053 ScreenPtr pScreen;
1054 rrScrPrivPtr pScrPriv;
1055 RRCrtcPtr crtc;
1056 RRModePtr mode;
1057 int numOutputs;
1058 RROutputPtr *outputs = NULL((void*)0);
1059 RROutput *outputIds;
1060 TimeStamp time;
1061 Rotation rotation;
1062 int ret, i, j;
1063 CARD8 status;
1064
1065 REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq)if ((sizeof(xRRSetCrtcConfigReq) >> 2) > client->
req_len ) return(16)
;
1066 numOutputs = (stuff->length - bytes_to_int32(SIZEOF(xRRSetCrtcConfigReq)28));
1067
1068 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; } }
;
1069
1070 if (stuff->mode == None0L) {
1071 mode = NULL((void*)0);
1072 if (numOutputs > 0)
1073 return BadMatch8;
1074 }
1075 else {
1076 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; } }
;
1077 if (numOutputs == 0)
1078 return BadMatch8;
1079 }
1080 if (numOutputs) {
1081 outputs = xallocarray(numOutputs, sizeof(RROutputPtr))xreallocarray(((void*)0), (numOutputs), (sizeof(RROutputPtr))
)
;
1082 if (!outputs)
1083 return BadAlloc11;
1084 }
1085 else
1086 outputs = NULL((void*)0);
1087
1088 outputIds = (RROutput *) (stuff + 1);
1089 for (i = 0; i < numOutputs; i++) {
1090 ret = dixLookupResourceByType((void **) (outputs + i), outputIds[i],
1091 RROutputType, client, DixSetAttrAccess(1<<5));
1092 if (ret != Success0) {
1093 free(outputs);
1094 return ret;
1095 }
1096 /* validate crtc for this output */
1097 for (j = 0; j < outputs[i]->numCrtcs; j++)
1098 if (outputs[i]->crtcs[j] == crtc)
1099 break;
1100 if (j == outputs[i]->numCrtcs) {
1101 free(outputs);
1102 return BadMatch8;
1103 }
1104 /* validate mode for this output */
1105 for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++) {
1106 RRModePtr m = (j < outputs[i]->numModes ?
1107 outputs[i]->modes[j] :
1108 outputs[i]->userModes[j - outputs[i]->numModes]);
1109 if (m == mode)
1110 break;
1111 }
1112 if (j == outputs[i]->numModes + outputs[i]->numUserModes) {
1113 free(outputs);
1114 return BadMatch8;
1115 }
1116 }
1117 /* validate clones */
1118 for (i = 0; i < numOutputs; i++) {
1119 for (j = 0; j < numOutputs; j++) {
1120 int k;
1121
1122 if (i == j)
1123 continue;
1124 for (k = 0; k < outputs[i]->numClones; k++) {
1125 if (outputs[i]->clones[k] == outputs[j])
1126 break;
1127 }
1128 if (k == outputs[i]->numClones) {
1129 free(outputs);
1130 return BadMatch8;
1131 }
1132 }
1133 }
1134
1135 pScreen = crtc->pScreen;
1136 pScrPriv = rrGetScrPriv(pScreen)((rrScrPrivPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&rrPrivKeyRec)))
;
1137
1138 time = ClientTimeToServerTime(stuff->timestamp);
1139
1140 if (!pScrPriv) {
1141 time = currentTime;
Value stored to 'time' is never read
1142 status = RRSetConfigFailed3;
1143 goto sendReply;
1144 }
1145
1146 /*
1147 * Validate requested rotation
1148 */
1149 rotation = (Rotation) stuff->rotation;
1150
1151 /* test the rotation bits only! */
1152 switch (rotation & 0xf) {
1153 case RR_Rotate_01:
1154 case RR_Rotate_902:
1155 case RR_Rotate_1804:
1156 case RR_Rotate_2708:
1157 break;
1158 default:
1159 /*
1160 * Invalid rotation
1161 */
1162 client->errorValue = stuff->rotation;
1163 free(outputs);
1164 return BadValue2;
1165 }
1166
1167 if (mode) {
1168 if ((~crtc->rotations) & rotation) {
1169 /*
1170 * requested rotation or reflection not supported by screen
1171 */
1172 client->errorValue = stuff->rotation;
1173 free(outputs);
1174 return BadMatch8;
1175 }
1176
1177#ifdef RANDR_12_INTERFACE1
1178 /*
1179 * Check screen size bounds if the DDX provides a 1.2 interface
1180 * for setting screen size. Else, assume the CrtcSet sets
1181 * the size along with the mode. If the driver supports transforms,
1182 * then it must allow crtcs to display a subset of the screen, so
1183 * only do this check for drivers without transform support.
1184 */
1185 if (pScrPriv->rrScreenSetSize && !crtc->transforms) {
1186 int source_width;
1187 int source_height;
1188 PictTransform transform;
1189 struct pixman_f_transform f_transform, f_inverse;
1190 int width, height;
1191
1192 if (pScreen->isGPU) {
1193 width = pScreen->current_master->width;
1194 height = pScreen->current_master->height;
1195 }
1196 else {
1197 width = pScreen->width;
1198 height = pScreen->height;
1199 }
1200
1201 RRTransformCompute(stuff->x, stuff->y,
1202 mode->mode.width, mode->mode.height,
1203 rotation,
1204 &crtc->client_pending_transform,
1205 &transform, &f_transform, &f_inverse);
1206
1207 RRModeGetScanoutSize(mode, &transform, &source_width,
1208 &source_height);
1209 if (stuff->x + source_width > width) {
1210 client->errorValue = stuff->x;
1211 free(outputs);
1212 return BadValue2;
1213 }
1214
1215 if (stuff->y + source_height > height) {
1216 client->errorValue = stuff->y;
1217 free(outputs);
1218 return BadValue2;
1219 }
1220 }
1221#endif
1222 }
1223
1224 if (!RRCrtcSet(crtc, mode, stuff->x, stuff->y,
1225 rotation, numOutputs, outputs)) {
1226 status = RRSetConfigFailed3;
1227 goto sendReply;
1228 }
1229 status = RRSetConfigSuccess0;
1230 pScrPriv->lastSetTime = time;
1231
1232 sendReply:
1233 free(outputs);
1234
1235 rep = (xRRSetCrtcConfigReply) {
1236 .type = X_Reply1,
1237 .status = status,
1238 .sequenceNumber = client->sequence,
1239 .length = 0,
1240 .newTimestamp = pScrPriv->lastSetTime.milliseconds
1241 };
1242
1243 if (client->swapped) {
1244 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)
;
1245 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)
;
1246 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)
;
1247 }
1248 WriteToClient(client, sizeof(xRRSetCrtcConfigReply), &rep);
1249
1250 return Success0;
1251}
1252
1253int
1254ProcRRGetPanning(ClientPtr client)
1255{
1256 REQUEST(xRRGetPanningReq)xRRGetPanningReq *stuff = (xRRGetPanningReq *)client->requestBuffer;
1257 xRRGetPanningReply rep;
1258 RRCrtcPtr crtc;
1259 ScreenPtr pScreen;
1260 rrScrPrivPtr pScrPriv;
1261 BoxRec total;
1262 BoxRec tracking;
1263 INT16 border[4];
1264
1265 REQUEST_SIZE_MATCH(xRRGetPanningReq)if ((sizeof(xRRGetPanningReq) >> 2) != client->req_len
) return(16)
;
1266 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; } }
;
1267
1268 /* All crtcs must be associated with screens before client
1269 * requests are processed
1270 */
1271 pScreen = crtc->pScreen;
1272 pScrPriv = rrGetScrPriv(pScreen)((rrScrPrivPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&rrPrivKeyRec)))
;
1273
1274 if (!pScrPriv)
1275 return RRErrorBase + BadRRCrtc1;
1276
1277 rep = (xRRGetPanningReply) {
1278 .type = X_Reply1,
1279 .status = RRSetConfigSuccess0,
1280 .sequenceNumber = client->sequence,
1281 .length = 1,
1282 .timestamp = pScrPriv->lastSetTime.milliseconds
1283 };
1284
1285 if (pScrPriv->rrGetPanning &&
1286 pScrPriv->rrGetPanning(pScreen, crtc, &total, &tracking, border)) {
1287 rep.left = total.x1;
1288 rep.top = total.y1;
1289 rep.width = total.x2 - total.x1;
1290 rep.height = total.y2 - total.y1;
1291 rep.track_left = tracking.x1;
1292 rep.track_top = tracking.y1;
1293 rep.track_width = tracking.x2 - tracking.x1;
1294 rep.track_height = tracking.y2 - tracking.y1;
1295 rep.border_left = border[0];
1296 rep.border_top = border[1];
1297 rep.border_right = border[2];
1298 rep.border_bottom = border[3];
1299 }
1300
1301 if (client->swapped) {
1302 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)
;
1303 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)
;
1304 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)
;
1305 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)
;
1306 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)
;
1307 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)
;
1308 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)
;
1309 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)
;
1310 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)
;
1311 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)
;
1312 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)
;
1313 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)
;
1314 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)
;
1315 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)
;
1316 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)
;
1317 }
1318 WriteToClient(client, sizeof(xRRGetPanningReply), &rep);
1319 return Success0;
1320}
1321
1322int
1323ProcRRSetPanning(ClientPtr client)
1324{
1325 REQUEST(xRRSetPanningReq)xRRSetPanningReq *stuff = (xRRSetPanningReq *)client->requestBuffer;
1326 xRRSetPanningReply rep;
1327 RRCrtcPtr crtc;
1328 ScreenPtr pScreen;
1329 rrScrPrivPtr pScrPriv;
1330 TimeStamp time;
1331 BoxRec total;
1332 BoxRec tracking;
1333 INT16 border[4];
1334 CARD8 status;
1335
1336 REQUEST_SIZE_MATCH(xRRSetPanningReq)if ((sizeof(xRRSetPanningReq) >> 2) != client->req_len
) return(16)
;
1337 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; } }
;
1338
1339 /* All crtcs must be associated with screens before client
1340 * requests are processed
1341 */
1342 pScreen = crtc->pScreen;
1343 pScrPriv = rrGetScrPriv(pScreen)((rrScrPrivPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&rrPrivKeyRec)))
;
1344
1345 if (!pScrPriv) {
1346 time = currentTime;
1347 status = RRSetConfigFailed3;
1348 goto sendReply;
1349 }
1350
1351 time = ClientTimeToServerTime(stuff->timestamp);
1352
1353 if (!pScrPriv->rrGetPanning)
1354 return RRErrorBase + BadRRCrtc1;
1355
1356 total.x1 = stuff->left;
1357 total.y1 = stuff->top;
1358 total.x2 = total.x1 + stuff->width;
1359 total.y2 = total.y1 + stuff->height;
1360 tracking.x1 = stuff->track_left;
1361 tracking.y1 = stuff->track_top;
1362 tracking.x2 = tracking.x1 + stuff->track_width;
1363 tracking.y2 = tracking.y1 + stuff->track_height;
1364 border[0] = stuff->border_left;
1365 border[1] = stuff->border_top;
1366 border[2] = stuff->border_right;
1367 border[3] = stuff->border_bottom;
1368
1369 if (!pScrPriv->rrSetPanning(pScreen, crtc, &total, &tracking, border))
1370 return BadMatch8;
1371
1372 pScrPriv->lastSetTime = time;
1373
1374 status = RRSetConfigSuccess0;
1375
1376 sendReply:
1377 rep = (xRRSetPanningReply) {
1378 .type = X_Reply1,
1379 .status = status,
1380 .sequenceNumber = client->sequence,
1381 .length = 0,
1382 .newTimestamp = pScrPriv->lastSetTime.milliseconds
1383 };
1384
1385 if (client->swapped) {
1386 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)
;
1387 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)
;
1388 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)
;
1389 }
1390 WriteToClient(client, sizeof(xRRSetPanningReply), &rep);
1391 return Success0;
1392}
1393
1394int
1395ProcRRGetCrtcGammaSize(ClientPtr client)
1396{
1397 REQUEST(xRRGetCrtcGammaSizeReq)xRRGetCrtcGammaSizeReq *stuff = (xRRGetCrtcGammaSizeReq *)client
->requestBuffer
;
1398 xRRGetCrtcGammaSizeReply reply;
1399 RRCrtcPtr crtc;
1400
1401 REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq)if ((sizeof(xRRGetCrtcGammaSizeReq) >> 2) != client->
req_len) return(16)
;
1402 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; } }
;
1403
1404 /* Gamma retrieval failed, any better error? */
1405 if (!RRCrtcGammaGet(crtc))
1406 return RRErrorBase + BadRRCrtc1;
1407
1408 reply = (xRRGetCrtcGammaSizeReply) {
1409 .type = X_Reply1,
1410 .sequenceNumber = client->sequence,
1411 .length = 0,
1412 .size = crtc->gammaSize
1413 };
1414 if (client->swapped) {
1415 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)
;
1416 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)
;
1417 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)
;
1418 }
1419 WriteToClient(client, sizeof(xRRGetCrtcGammaSizeReply), &reply);
1420 return Success0;
1421}
1422
1423int
1424ProcRRGetCrtcGamma(ClientPtr client)
1425{
1426 REQUEST(xRRGetCrtcGammaReq)xRRGetCrtcGammaReq *stuff = (xRRGetCrtcGammaReq *)client->
requestBuffer
;
1427 xRRGetCrtcGammaReply reply;
1428 RRCrtcPtr crtc;
1429 unsigned long len;
1430 char *extra = NULL((void*)0);
1431
1432 REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq)if ((sizeof(xRRGetCrtcGammaReq) >> 2) != client->req_len
) return(16)
;
1433 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; } }
;
1434
1435 /* Gamma retrieval failed, any better error? */
1436 if (!RRCrtcGammaGet(crtc))
1437 return RRErrorBase + BadRRCrtc1;
1438
1439 len = crtc->gammaSize * 3 * 2;
1440
1441 if (crtc->gammaSize) {
1442 extra = malloc(len);
1443 if (!extra)
1444 return BadAlloc11;
1445 }
1446
1447 reply = (xRRGetCrtcGammaReply) {
1448 .type = X_Reply1,
1449 .sequenceNumber = client->sequence,
1450 .length = bytes_to_int32(len),
1451 .size = crtc->gammaSize
1452 };
1453 if (client->swapped) {
1454 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)
;
1455 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)
;
1456 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)
;
1457 }
1458 WriteToClient(client, sizeof(xRRGetCrtcGammaReply), &reply);
1459 if (crtc->gammaSize) {
1460 memcpy(extra, crtc->gammaRed, len)__builtin___memcpy_chk (extra, crtc->gammaRed, len, __builtin_object_size
(extra, 0))
;
1461 client->pSwapReplyFunc = (ReplySwapPtr) CopySwap16Write;
1462 WriteSwappedDataToClient(client, len, extra)if ((client)->swapped) (*(client)->pSwapReplyFunc)(client
, (int)(len), extra); else WriteToClient(client, (int)(len), (
extra));
;
1463 free(extra);
1464 }
1465 return Success0;
1466}
1467
1468int
1469ProcRRSetCrtcGamma(ClientPtr client)
1470{
1471 REQUEST(xRRSetCrtcGammaReq)xRRSetCrtcGammaReq *stuff = (xRRSetCrtcGammaReq *)client->
requestBuffer
;
1472 RRCrtcPtr crtc;
1473 unsigned long len;
1474 CARD16 *red, *green, *blue;
1475
1476 REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq)if ((sizeof(xRRSetCrtcGammaReq) >> 2) > client->req_len
) return(16)
;
1477 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; } }
;
1478
1479 len = client->req_len - bytes_to_int32(sizeof(xRRSetCrtcGammaReq));
1480 if (len < (stuff->size * 3 + 1) >> 1)
1481 return BadLength16;
1482
1483 if (stuff->size != crtc->gammaSize)
1484 return BadMatch8;
1485
1486 red = (CARD16 *) (stuff + 1);
1487 green = red + crtc->gammaSize;
1488 blue = green + crtc->gammaSize;
1489
1490 RRCrtcGammaSet(crtc, red, green, blue);
1491
1492 return Success0;
1493}
1494
1495/* Version 1.3 additions */
1496
1497int
1498ProcRRSetCrtcTransform(ClientPtr client)
1499{
1500 REQUEST(xRRSetCrtcTransformReq)xRRSetCrtcTransformReq *stuff = (xRRSetCrtcTransformReq *)client
->requestBuffer
;
1501 RRCrtcPtr crtc;
1502 PictTransform transform;
1503 struct pixman_f_transform f_transform, f_inverse;
1504 char *filter;
1505 int nbytes;
1506 xFixed *params;
1507 int nparams;
1508
1509 REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq)if ((sizeof(xRRSetCrtcTransformReq) >> 2) > client->
req_len ) return(16)
;
1510 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; } }
;
1511
1512 PictTransform_from_xRenderTransform(&transform, &stuff->transform);
1513 pixman_f_transform_from_pixman_transform(&f_transform, &transform);
1514 if (!pixman_f_transform_invert(&f_inverse, &f_transform))
1515 return BadMatch8;
1516
1517 filter = (char *) (stuff + 1);
1518 nbytes = stuff->nbytesFilter;
1519 params = (xFixed *) (filter + pad_to_int32(nbytes));
1520 nparams = ((xFixed *) stuff + client->req_len) - params;
1521 if (nparams < 0)
1522 return BadLength16;
1523
1524 return RRCrtcTransformSet(crtc, &transform, &f_transform, &f_inverse,
1525 filter, nbytes, params, nparams);
1526}
1527
1528#define CrtcTransformExtra(96 - 32) (SIZEOF(xRRGetCrtcTransformReply)96 - 32)
1529
1530static int
1531transform_filter_length(RRTransformPtr transform)
1532{
1533 int nbytes, nparams;
1534
1535 if (transform->filter == NULL((void*)0))
1536 return 0;
1537 nbytes = strlen(transform->filter->name);
1538 nparams = transform->nparams;
1539 return pad_to_int32(nbytes) + (nparams * sizeof(xFixed));
1540}
1541
1542static int
1543transform_filter_encode(ClientPtr client, char *output,
1544 CARD16 *nbytesFilter,
1545 CARD16 *nparamsFilter, RRTransformPtr transform)
1546{
1547 int nbytes, nparams;
1548
1549 if (transform->filter == NULL((void*)0)) {
1550 *nbytesFilter = 0;
1551 *nparamsFilter = 0;
1552 return 0;
1553 }
1554 nbytes = strlen(transform->filter->name);
1555 nparams = transform->nparams;
1556 *nbytesFilter = nbytes;
1557 *nparamsFilter = nparams;
1558 memcpy(output, transform->filter->name, nbytes)__builtin___memcpy_chk (output, transform->filter->name
, nbytes, __builtin_object_size (output, 0))
;
1559 while ((nbytes & 3) != 0)
1560 output[nbytes++] = 0;
1561 memcpy(output + nbytes, transform->params, nparams * sizeof(xFixed))__builtin___memcpy_chk (output + nbytes, transform->params
, nparams * sizeof(xFixed), __builtin_object_size (output + nbytes
, 0))
;
1562 if (client->swapped) {
1563 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)
;
1564 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
)
;
1565 SwapLongs((CARD32 *) (output + nbytes), nparams);
1566 }
1567 nbytes += nparams * sizeof(xFixed);
1568 return nbytes;
1569}
1570
1571static void
1572transform_encode(ClientPtr client, xRenderTransform * wire,
1573 PictTransform * pict)
1574{
1575 xRenderTransform_from_PictTransform(wire, pict);
1576 if (client->swapped)
1577 SwapLongs((CARD32 *) wire, bytes_to_int32(sizeof(xRenderTransform)));
1578}
1579
1580int
1581ProcRRGetCrtcTransform(ClientPtr client)
1582{
1583 REQUEST(xRRGetCrtcTransformReq)xRRGetCrtcTransformReq *stuff = (xRRGetCrtcTransformReq *)client
->requestBuffer
;
1584 xRRGetCrtcTransformReply *reply;
1585 RRCrtcPtr crtc;
1586 int nextra;
1587 RRTransformPtr current, pending;
1588 char *extra;
1589
1590 REQUEST_SIZE_MATCH(xRRGetCrtcTransformReq)if ((sizeof(xRRGetCrtcTransformReq) >> 2) != client->
req_len) return(16)
;
1591 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; } }
;
1592
1593 pending = &crtc->client_pending_transform;
1594 current = &crtc->client_current_transform;
1595
1596 nextra = (transform_filter_length(pending) +
1597 transform_filter_length(current));
1598
1599 reply = calloc(1, sizeof(xRRGetCrtcTransformReply) + nextra);
1600 if (!reply)
1601 return BadAlloc11;
1602
1603 extra = (char *) (reply + 1);
1604 reply->type = X_Reply1;
1605 reply->sequenceNumber = client->sequence;
1606 reply->length = bytes_to_int32(CrtcTransformExtra(96 - 32) + nextra);
1607
1608 reply->hasTransforms = crtc->transforms;
1609
1610 transform_encode(client, &reply->pendingTransform, &pending->transform);
1611 extra += transform_filter_encode(client, extra,
1612 &reply->pendingNbytesFilter,
1613 &reply->pendingNparamsFilter, pending);
1614
1615 transform_encode(client, &reply->currentTransform, &current->transform);
1616 extra += transform_filter_encode(client, extra,
1617 &reply->currentNbytesFilter,
1618 &reply->currentNparamsFilter, current);
1619
1620 if (client->swapped) {
1621 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)
;
1622 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)
;
1623 }
1624 WriteToClient(client, sizeof(xRRGetCrtcTransformReply) + nextra, reply);
1625 free(reply);
1626 return Success0;
1627}
1628
1629static Bool
1630check_all_screen_crtcs(ScreenPtr pScreen, int *x, int *y)
1631{
1632 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
1633 int i;
1634 for (i = 0; i < pScrPriv->numCrtcs; i++) {
1635 RRCrtcPtr crtc = pScrPriv->crtcs[i];
1636
1637 int left, right, top, bottom;
1638
1639 if (!crtc->mode)
1640 continue;
1641
1642 crtc_bounds(crtc, &left, &right, &top, &bottom);
1643
1644 if ((*x >= left) && (*x < right) && (*y >= top) && (*y < bottom))
1645 return TRUE1;
1646 }
1647 return FALSE0;
1648}
1649
1650static Bool
1651constrain_all_screen_crtcs(DeviceIntPtr pDev, ScreenPtr pScreen, int *x, int *y)
1652{
1653 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
1654 int i;
1655
1656 /* if we're trying to escape, clamp to the CRTC we're coming from */
1657 for (i = 0; i < pScrPriv->numCrtcs; i++) {
1658 RRCrtcPtr crtc = pScrPriv->crtcs[i];
1659 int nx, ny;
1660 int left, right, top, bottom;
1661
1662 if (!crtc->mode)
1663 continue;
1664
1665 crtc_bounds(crtc, &left, &right, &top, &bottom);
1666 miPointerGetPosition(pDev, &nx, &ny);
1667
1668 if ((nx >= left) && (nx < right) && (ny >= top) && (ny < bottom)) {
1669 if (*x < left)
1670 *x = left;
1671 if (*x >= right)
1672 *x = right - 1;
1673 if (*y < top)
1674 *y = top;
1675 if (*y >= bottom)
1676 *y = bottom - 1;
1677
1678 return TRUE1;
1679 }
1680 }
1681 return FALSE0;
1682}
1683
1684void
1685RRConstrainCursorHarder(DeviceIntPtr pDev, ScreenPtr pScreen, int mode, int *x,
1686 int *y)
1687{
1688 rrScrPriv(pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pScreen)->devPrivates, (&rrPrivKeyRec)))
;
1689 Bool ret;
1690 ScreenPtr slave;
1691
1692 /* intentional dead space -> let it float */
1693 if (pScrPriv->discontiguous)
1694 return;
1695
1696 /* if we're moving inside a crtc, we're fine */
1697 ret = check_all_screen_crtcs(pScreen, x, y);
1698 if (ret == TRUE1)
1699 return;
1700
1701 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)))
{
1702 ret = check_all_screen_crtcs(slave, x, y);
1703 if (ret == TRUE1)
1704 return;
1705 }
1706
1707 /* if we're trying to escape, clamp to the CRTC we're coming from */
1708 ret = constrain_all_screen_crtcs(pDev, pScreen, x, y);
1709 if (ret == TRUE1)
1710 return;
1711
1712 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)))
{
1713 ret = constrain_all_screen_crtcs(pDev, slave, x, y);
1714 if (ret == TRUE1)
1715 return;
1716 }
1717}
1718
1719Bool
1720RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable)
1721{
1722 rrScrPriv(pDrawable->pScreen)rrScrPrivPtr pScrPriv = ((rrScrPrivPtr)dixLookupPrivate(&
(pDrawable->pScreen)->devPrivates, (&rrPrivKeyRec))
)
;
1723 Bool ret = TRUE1;
1724 PixmapPtr *saved_scanout_pixmap;
1725 int i;
1726
1727 saved_scanout_pixmap = malloc(sizeof(PixmapPtr)*pScrPriv->numCrtcs);
1728 if (saved_scanout_pixmap == NULL((void*)0))
1729 return FALSE0;
1730
1731 for (i = 0; i < pScrPriv->numCrtcs; i++) {
1732 RRCrtcPtr crtc = pScrPriv->crtcs[i];
1733 Bool size_fits;
1734
1735 saved_scanout_pixmap[i] = crtc->scanout_pixmap;
1736
1737 if (!crtc->mode && enable)
1738 continue;
1739 if (!crtc->scanout_pixmap && !enable)
1740 continue;
1741
1742 size_fits = (crtc->mode &&
1743 crtc->x == pDrawable->x &&
1744 crtc->y == pDrawable->y &&
1745 crtc->mode->mode.width == pDrawable->width &&
1746 crtc->mode->mode.height == pDrawable->height);
1747
1748 /* is the pixmap already set? */
1749 if (crtc->scanout_pixmap == pPixmap) {
1750 /* if its a disable then don't care about size */
1751 if (enable == FALSE0) {
1752 /* set scanout to NULL */
1753 crtc->scanout_pixmap = NULL((void*)0);
1754 }
1755 else if (!size_fits) {
1756 /* if the size no longer fits then drop off */
1757 crtc->scanout_pixmap = NULL((void*)0);
1758 pScrPriv->rrCrtcSetScanoutPixmap(crtc, crtc->scanout_pixmap);
1759
1760 (*pScrPriv->rrCrtcSet) (pDrawable->pScreen, crtc, crtc->mode, crtc->x, crtc->y,
1761 crtc->rotation, crtc->numOutputs, crtc->outputs);
1762 saved_scanout_pixmap[i] = crtc->scanout_pixmap;
1763 ret = FALSE0;
1764 }
1765 else {
1766 /* if the size fits then we are already setup */
1767 }
1768 }
1769 else {
1770 if (!size_fits)
1771 ret = FALSE0;
1772 else if (enable)
1773 crtc->scanout_pixmap = pPixmap;
1774 else
1775 /* reject an attempt to disable someone else's scanout_pixmap */
1776 ret = FALSE0;
1777 }
1778 }
1779
1780 for (i = 0; i < pScrPriv->numCrtcs; i++) {
1781 RRCrtcPtr crtc = pScrPriv->crtcs[i];
1782
1783 if (crtc->scanout_pixmap == saved_scanout_pixmap[i])
1784 continue;
1785
1786 if (ret) {
1787 pScrPriv->rrCrtcSetScanoutPixmap(crtc, crtc->scanout_pixmap);
1788
1789 (*pScrPriv->rrCrtcSet) (pDrawable->pScreen, crtc, crtc->mode, crtc->x, crtc->y,
1790 crtc->rotation, crtc->numOutputs, crtc->outputs);
1791 }
1792 else
1793 crtc->scanout_pixmap = saved_scanout_pixmap[i];
1794 }
1795 free(saved_scanout_pixmap);
1796
1797 return ret;
1798}