Add patch that contain Mali fixes.
[deb_xorg-server.git] / composite / compext.c
1 /*
2 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 * Copyright © 2003 Keith Packard
24 *
25 * Permission to use, copy, modify, distribute, and sell this software and its
26 * documentation for any purpose is hereby granted without fee, provided that
27 * the above copyright notice appear in all copies and that both that
28 * copyright notice and this permission notice appear in supporting
29 * documentation, and that the name of Keith Packard not be used in
30 * advertising or publicity pertaining to distribution of the software without
31 * specific, written prior permission. Keith Packard makes no
32 * representations about the suitability of this software for any purpose. It
33 * is provided "as is" without express or implied warranty.
34 *
35 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
36 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
37 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
38 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
39 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
40 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
41 * PERFORMANCE OF THIS SOFTWARE.
42 */
43
44 #ifdef HAVE_DIX_CONFIG_H
45 #include <dix-config.h>
46 #endif
47
48 #include "compint.h"
49 #include "xace.h"
50 #include "protocol-versions.h"
51 #include "extinit.h"
52
53 static CARD8 CompositeReqCode;
54 static DevPrivateKeyRec CompositeClientPrivateKeyRec;
55
56 #define CompositeClientPrivateKey (&CompositeClientPrivateKeyRec)
57 RESTYPE CompositeClientWindowType;
58 RESTYPE CompositeClientSubwindowsType;
59 RESTYPE CompositeClientOverlayType;
60
61 typedef struct _CompositeClient {
62 int major_version;
63 int minor_version;
64 } CompositeClientRec, *CompositeClientPtr;
65
66 #define GetCompositeClient(pClient) ((CompositeClientPtr) \
67 dixLookupPrivate(&(pClient)->devPrivates, CompositeClientPrivateKey))
68
69 static void
70 CompositeClientCallback(CallbackListPtr *list, pointer closure, pointer data)
71 {
72 NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
73 ClientPtr pClient = clientinfo->client;
74 CompositeClientPtr pCompositeClient = GetCompositeClient(pClient);
75
76 pCompositeClient->major_version = 0;
77 pCompositeClient->minor_version = 0;
78 }
79
80 static int
81 FreeCompositeClientWindow(pointer value, XID ccwid)
82 {
83 WindowPtr pWin = value;
84
85 compFreeClientWindow(pWin, ccwid);
86 return Success;
87 }
88
89 static int
90 FreeCompositeClientSubwindows(pointer value, XID ccwid)
91 {
92 WindowPtr pWin = value;
93
94 compFreeClientSubwindows(pWin, ccwid);
95 return Success;
96 }
97
98 static int
99 FreeCompositeClientOverlay(pointer value, XID ccwid)
100 {
101 CompOverlayClientPtr pOc = (CompOverlayClientPtr) value;
102
103 compFreeOverlayClient(pOc);
104 return Success;
105 }
106
107 static int
108 ProcCompositeQueryVersion(ClientPtr client)
109 {
110 CompositeClientPtr pCompositeClient = GetCompositeClient(client);
111 xCompositeQueryVersionReply rep = {
112 .type = X_Reply,
113 .sequenceNumber = client->sequence,
114 .length = 0
115 };
116
117 REQUEST(xCompositeQueryVersionReq);
118
119 REQUEST_SIZE_MATCH(xCompositeQueryVersionReq);
120 if (stuff->majorVersion < SERVER_COMPOSITE_MAJOR_VERSION) {
121 rep.majorVersion = stuff->majorVersion;
122 rep.minorVersion = stuff->minorVersion;
123 }
124 else {
125 rep.majorVersion = SERVER_COMPOSITE_MAJOR_VERSION;
126 rep.minorVersion = SERVER_COMPOSITE_MINOR_VERSION;
127 }
128 pCompositeClient->major_version = rep.majorVersion;
129 pCompositeClient->minor_version = rep.minorVersion;
130 if (client->swapped) {
131 swaps(&rep.sequenceNumber);
132 swapl(&rep.length);
133 swapl(&rep.majorVersion);
134 swapl(&rep.minorVersion);
135 }
136 WriteToClient(client, sizeof(xCompositeQueryVersionReply), &rep);
137 return Success;
138 }
139
140 #define VERIFY_WINDOW(pWindow, wid, client, mode) \
141 do { \
142 int err; \
143 err = dixLookupResourceByType((pointer *) &pWindow, wid, \
144 RT_WINDOW, client, mode); \
145 if (err != Success) { \
146 client->errorValue = wid; \
147 return err; \
148 } \
149 } while (0)
150
151 static int
152 ProcCompositeRedirectWindow(ClientPtr client)
153 {
154 WindowPtr pWin;
155
156 REQUEST(xCompositeRedirectWindowReq);
157
158 REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
159 VERIFY_WINDOW(pWin, stuff->window, client,
160 DixSetAttrAccess | DixManageAccess | DixBlendAccess);
161
162 return compRedirectWindow(client, pWin, stuff->update);
163 }
164
165 static int
166 ProcCompositeRedirectSubwindows(ClientPtr client)
167 {
168 WindowPtr pWin;
169
170 REQUEST(xCompositeRedirectSubwindowsReq);
171
172 REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
173 VERIFY_WINDOW(pWin, stuff->window, client,
174 DixSetAttrAccess | DixManageAccess | DixBlendAccess);
175
176 return compRedirectSubwindows(client, pWin, stuff->update);
177 }
178
179 static int
180 ProcCompositeUnredirectWindow(ClientPtr client)
181 {
182 WindowPtr pWin;
183
184 REQUEST(xCompositeUnredirectWindowReq);
185
186 REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
187 VERIFY_WINDOW(pWin, stuff->window, client,
188 DixSetAttrAccess | DixManageAccess | DixBlendAccess);
189
190 return compUnredirectWindow(client, pWin, stuff->update);
191 }
192
193 static int
194 ProcCompositeUnredirectSubwindows(ClientPtr client)
195 {
196 WindowPtr pWin;
197
198 REQUEST(xCompositeUnredirectSubwindowsReq);
199
200 REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
201 VERIFY_WINDOW(pWin, stuff->window, client,
202 DixSetAttrAccess | DixManageAccess | DixBlendAccess);
203
204 return compUnredirectSubwindows(client, pWin, stuff->update);
205 }
206
207 static int
208 ProcCompositeCreateRegionFromBorderClip(ClientPtr client)
209 {
210 WindowPtr pWin;
211 CompWindowPtr cw;
212 RegionPtr pBorderClip, pRegion;
213
214 REQUEST(xCompositeCreateRegionFromBorderClipReq);
215
216 REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq);
217 VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
218 LEGAL_NEW_RESOURCE(stuff->region, client);
219
220 cw = GetCompWindow(pWin);
221 if (cw)
222 pBorderClip = &cw->borderClip;
223 else
224 pBorderClip = &pWin->borderClip;
225 pRegion = XFixesRegionCopy(pBorderClip);
226 if (!pRegion)
227 return BadAlloc;
228 RegionTranslate(pRegion, -pWin->drawable.x, -pWin->drawable.y);
229
230 if (!AddResource(stuff->region, RegionResType, (pointer) pRegion))
231 return BadAlloc;
232
233 return Success;
234 }
235
236 static int
237 ProcCompositeNameWindowPixmap(ClientPtr client)
238 {
239 WindowPtr pWin;
240 CompWindowPtr cw;
241 PixmapPtr pPixmap;
242 int rc;
243
244 REQUEST(xCompositeNameWindowPixmapReq);
245
246 REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
247 VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
248
249 if (!pWin->viewable)
250 return BadMatch;
251
252 LEGAL_NEW_RESOURCE(stuff->pixmap, client);
253
254 cw = GetCompWindow(pWin);
255 if (!cw)
256 return BadMatch;
257
258 pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
259 if (!pPixmap)
260 return BadMatch;
261
262 /* security creation/labeling check */
263 rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP,
264 pPixmap, RT_WINDOW, pWin, DixCreateAccess);
265 if (rc != Success)
266 return rc;
267
268 ++pPixmap->refcnt;
269
270 if (!AddResource(stuff->pixmap, RT_PIXMAP, (pointer) pPixmap))
271 return BadAlloc;
272
273 return Success;
274 }
275
276 static int
277 ProcCompositeGetOverlayWindow(ClientPtr client)
278 {
279 REQUEST(xCompositeGetOverlayWindowReq);
280 xCompositeGetOverlayWindowReply rep;
281 WindowPtr pWin;
282 ScreenPtr pScreen;
283 CompScreenPtr cs;
284 CompOverlayClientPtr pOc;
285 int rc;
286
287 REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
288 VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
289 pScreen = pWin->drawable.pScreen;
290
291 /*
292 * Create an OverlayClient structure to mark this client's
293 * interest in the overlay window
294 */
295 pOc = compCreateOverlayClient(pScreen, client);
296 if (pOc == NULL)
297 return BadAlloc;
298
299 /*
300 * Make sure the overlay window exists
301 */
302 cs = GetCompScreen(pScreen);
303 if (cs->pOverlayWin == NULL)
304 if (!compCreateOverlayWindow(pScreen)) {
305 FreeResource(pOc->resource, RT_NONE);
306 return BadAlloc;
307 }
308
309 rc = XaceHook(XACE_RESOURCE_ACCESS, client, cs->pOverlayWin->drawable.id,
310 RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL, DixGetAttrAccess);
311 if (rc != Success) {
312 FreeResource(pOc->resource, RT_NONE);
313 return rc;
314 }
315
316 rep = (xCompositeGetOverlayWindowReply) {
317 .type = X_Reply,
318 .sequenceNumber = client->sequence,
319 .length = 0,
320 .overlayWin = cs->pOverlayWin->drawable.id
321 };
322
323 if (client->swapped) {
324 swaps(&rep.sequenceNumber);
325 swapl(&rep.length);
326 swapl(&rep.overlayWin);
327 }
328 WriteToClient(client, sz_xCompositeGetOverlayWindowReply, &rep);
329
330 return Success;
331 }
332
333 static int
334 ProcCompositeReleaseOverlayWindow(ClientPtr client)
335 {
336 REQUEST(xCompositeReleaseOverlayWindowReq);
337 WindowPtr pWin;
338 ScreenPtr pScreen;
339 CompOverlayClientPtr pOc;
340
341 REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
342 VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
343 pScreen = pWin->drawable.pScreen;
344
345 /*
346 * Has client queried a reference to the overlay window
347 * on this screen? If not, generate an error.
348 */
349 pOc = compFindOverlayClient(pWin->drawable.pScreen, client);
350 if (pOc == NULL)
351 return BadMatch;
352
353 /* The delete function will free the client structure */
354 FreeResource(pOc->resource, RT_NONE);
355
356 return Success;
357 }
358
359 static int (*ProcCompositeVector[CompositeNumberRequests]) (ClientPtr) = {
360 ProcCompositeQueryVersion,
361 ProcCompositeRedirectWindow,
362 ProcCompositeRedirectSubwindows,
363 ProcCompositeUnredirectWindow,
364 ProcCompositeUnredirectSubwindows,
365 ProcCompositeCreateRegionFromBorderClip,
366 ProcCompositeNameWindowPixmap,
367 ProcCompositeGetOverlayWindow, ProcCompositeReleaseOverlayWindow,};
368
369 static int
370 ProcCompositeDispatch(ClientPtr client)
371 {
372 REQUEST(xReq);
373
374 if (stuff->data < CompositeNumberRequests)
375 return (*ProcCompositeVector[stuff->data]) (client);
376 else
377 return BadRequest;
378 }
379
380 static int
381 SProcCompositeQueryVersion(ClientPtr client)
382 {
383 REQUEST(xCompositeQueryVersionReq);
384
385 swaps(&stuff->length);
386 REQUEST_SIZE_MATCH(xCompositeQueryVersionReq);
387 swapl(&stuff->majorVersion);
388 swapl(&stuff->minorVersion);
389 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
390 }
391
392 static int
393 SProcCompositeRedirectWindow(ClientPtr client)
394 {
395 REQUEST(xCompositeRedirectWindowReq);
396
397 swaps(&stuff->length);
398 REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
399 swapl(&stuff->window);
400 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
401 }
402
403 static int
404 SProcCompositeRedirectSubwindows(ClientPtr client)
405 {
406 REQUEST(xCompositeRedirectSubwindowsReq);
407
408 swaps(&stuff->length);
409 REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
410 swapl(&stuff->window);
411 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
412 }
413
414 static int
415 SProcCompositeUnredirectWindow(ClientPtr client)
416 {
417 REQUEST(xCompositeUnredirectWindowReq);
418
419 swaps(&stuff->length);
420 REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
421 swapl(&stuff->window);
422 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
423 }
424
425 static int
426 SProcCompositeUnredirectSubwindows(ClientPtr client)
427 {
428 REQUEST(xCompositeUnredirectSubwindowsReq);
429
430 swaps(&stuff->length);
431 REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
432 swapl(&stuff->window);
433 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
434 }
435
436 static int
437 SProcCompositeCreateRegionFromBorderClip(ClientPtr client)
438 {
439 REQUEST(xCompositeCreateRegionFromBorderClipReq);
440
441 swaps(&stuff->length);
442 REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq);
443 swapl(&stuff->region);
444 swapl(&stuff->window);
445 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
446 }
447
448 static int
449 SProcCompositeNameWindowPixmap(ClientPtr client)
450 {
451 REQUEST(xCompositeNameWindowPixmapReq);
452
453 swaps(&stuff->length);
454 REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
455 swapl(&stuff->window);
456 swapl(&stuff->pixmap);
457 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
458 }
459
460 static int
461 SProcCompositeGetOverlayWindow(ClientPtr client)
462 {
463 REQUEST(xCompositeGetOverlayWindowReq);
464
465 swaps(&stuff->length);
466 REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
467 swapl(&stuff->window);
468 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
469 }
470
471 static int
472 SProcCompositeReleaseOverlayWindow(ClientPtr client)
473 {
474 REQUEST(xCompositeReleaseOverlayWindowReq);
475
476 swaps(&stuff->length);
477 REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
478 swapl(&stuff->window);
479 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
480 }
481
482 static int (*SProcCompositeVector[CompositeNumberRequests]) (ClientPtr) = {
483 SProcCompositeQueryVersion,
484 SProcCompositeRedirectWindow,
485 SProcCompositeRedirectSubwindows,
486 SProcCompositeUnredirectWindow,
487 SProcCompositeUnredirectSubwindows,
488 SProcCompositeCreateRegionFromBorderClip,
489 SProcCompositeNameWindowPixmap,
490 SProcCompositeGetOverlayWindow, SProcCompositeReleaseOverlayWindow,};
491
492 static int
493 SProcCompositeDispatch(ClientPtr client)
494 {
495 REQUEST(xReq);
496
497 if (stuff->data < CompositeNumberRequests)
498 return (*SProcCompositeVector[stuff->data]) (client);
499 else
500 return BadRequest;
501 }
502
503 /** @see GetDefaultBytes */
504 static void
505 GetCompositeClientWindowBytes(pointer value, XID id, ResourceSizePtr size)
506 {
507 WindowPtr window = value;
508
509 /* Currently only pixmap bytes are reported to clients. */
510 size->resourceSize = 0;
511
512 /* Calculate pixmap reference sizes. */
513 size->pixmapRefSize = 0;
514 if (window->redirectDraw != RedirectDrawNone)
515 {
516 SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP);
517 ResourceSizeRec pixmapSize = { 0, 0 };
518 ScreenPtr screen = window->drawable.pScreen;
519 PixmapPtr pixmap = screen->GetWindowPixmap(window);
520 pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize);
521 size->pixmapRefSize += pixmapSize.pixmapRefSize;
522 }
523 }
524
525 void
526 CompositeExtensionInit(void)
527 {
528 ExtensionEntry *extEntry;
529 int s;
530
531 /* Assume initialization is going to fail */
532 noCompositeExtension = TRUE;
533
534 for (s = 0; s < screenInfo.numScreens; s++) {
535 ScreenPtr pScreen = screenInfo.screens[s];
536 VisualPtr vis;
537
538 /* Composite on 8bpp pseudocolor root windows appears to fail, so
539 * just disable it on anything pseudocolor for safety.
540 */
541 for (vis = pScreen->visuals; vis->vid != pScreen->rootVisual; vis++);
542 if ((vis->class | DynamicClass) == PseudoColor)
543 return;
544
545 /* Ensure that Render is initialized, which is required for automatic
546 * compositing.
547 */
548 if (GetPictureScreenIfSet(pScreen) == NULL)
549 return;
550 }
551
552 CompositeClientWindowType = CreateNewResourceType
553 (FreeCompositeClientWindow, "CompositeClientWindow");
554 if (!CompositeClientWindowType)
555 return;
556
557 SetResourceTypeSizeFunc(CompositeClientWindowType,
558 GetCompositeClientWindowBytes);
559
560 CompositeClientSubwindowsType = CreateNewResourceType
561 (FreeCompositeClientSubwindows, "CompositeClientSubwindows");
562 if (!CompositeClientSubwindowsType)
563 return;
564
565 CompositeClientOverlayType = CreateNewResourceType
566 (FreeCompositeClientOverlay, "CompositeClientOverlay");
567 if (!CompositeClientOverlayType)
568 return;
569
570 if (!dixRegisterPrivateKey(&CompositeClientPrivateKeyRec, PRIVATE_CLIENT,
571 sizeof(CompositeClientRec)))
572 return;
573
574 if (!AddCallback(&ClientStateCallback, CompositeClientCallback, 0))
575 return;
576
577 for (s = 0; s < screenInfo.numScreens; s++)
578 if (!compScreenInit(screenInfo.screens[s]))
579 return;
580
581 extEntry = AddExtension(COMPOSITE_NAME, 0, 0,
582 ProcCompositeDispatch, SProcCompositeDispatch,
583 NULL, StandardMinorOpcode);
584 if (!extEntry)
585 return;
586 CompositeReqCode = (CARD8) extEntry->base;
587
588 miRegisterRedirectBorderClipProc(compSetRedirectBorderClip,
589 compGetRedirectBorderClip);
590
591 /* Initialization succeeded */
592 noCompositeExtension = FALSE;
593 }
594
595 #ifdef PANORAMIX
596 #include "panoramiXsrv.h"
597
598 int (*PanoramiXSaveCompositeVector[CompositeNumberRequests]) (ClientPtr);
599
600 static int
601 PanoramiXCompositeRedirectWindow(ClientPtr client)
602 {
603 PanoramiXRes *win;
604 int rc = 0, j;
605
606 REQUEST(xCompositeRedirectWindowReq);
607
608 REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
609
610 if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
611 client, DixUnknownAccess))) {
612 client->errorValue = stuff->window;
613 return rc;
614 }
615
616 FOR_NSCREENS_FORWARD(j) {
617 stuff->window = win->info[j].id;
618 rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
619 if (rc != Success)
620 break;
621 }
622
623 return rc;
624 }
625
626 static int
627 PanoramiXCompositeRedirectSubwindows(ClientPtr client)
628 {
629 PanoramiXRes *win;
630 int rc = 0, j;
631
632 REQUEST(xCompositeRedirectSubwindowsReq);
633
634 REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
635
636 if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
637 client, DixUnknownAccess))) {
638 client->errorValue = stuff->window;
639 return rc;
640 }
641
642 FOR_NSCREENS_FORWARD(j) {
643 stuff->window = win->info[j].id;
644 rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
645 if (rc != Success)
646 break;
647 }
648
649 return rc;
650 }
651
652 static int
653 PanoramiXCompositeUnredirectWindow(ClientPtr client)
654 {
655 PanoramiXRes *win;
656 int rc = 0, j;
657
658 REQUEST(xCompositeUnredirectWindowReq);
659
660 REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
661
662 if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
663 client, DixUnknownAccess))) {
664 client->errorValue = stuff->window;
665 return rc;
666 }
667
668 FOR_NSCREENS_FORWARD(j) {
669 stuff->window = win->info[j].id;
670 rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
671 if (rc != Success)
672 break;
673 }
674
675 return rc;
676 }
677
678 static int
679 PanoramiXCompositeUnredirectSubwindows(ClientPtr client)
680 {
681 PanoramiXRes *win;
682 int rc = 0, j;
683
684 REQUEST(xCompositeUnredirectSubwindowsReq);
685
686 REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
687
688 if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
689 client, DixUnknownAccess))) {
690 client->errorValue = stuff->window;
691 return rc;
692 }
693
694 FOR_NSCREENS_FORWARD(j) {
695 stuff->window = win->info[j].id;
696 rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
697 if (rc != Success)
698 break;
699 }
700
701 return rc;
702 }
703
704 static int
705 PanoramiXCompositeNameWindowPixmap(ClientPtr client)
706 {
707 WindowPtr pWin;
708 CompWindowPtr cw;
709 PixmapPtr pPixmap;
710 int rc;
711 PanoramiXRes *win, *newPix;
712 int i;
713
714 REQUEST(xCompositeNameWindowPixmapReq);
715
716 REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
717
718 if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
719 client, DixUnknownAccess))) {
720 client->errorValue = stuff->window;
721 return rc;
722 }
723
724 LEGAL_NEW_RESOURCE(stuff->pixmap, client);
725
726 if (!(newPix = malloc(sizeof(PanoramiXRes))))
727 return BadAlloc;
728
729 newPix->type = XRT_PIXMAP;
730 newPix->u.pix.shared = FALSE;
731 panoramix_setup_ids(newPix, client, stuff->pixmap);
732
733 FOR_NSCREENS(i) {
734 rc = dixLookupResourceByType((void **) &pWin, win->info[i].id,
735 RT_WINDOW, client, DixGetAttrAccess);
736 if (rc != Success) {
737 client->errorValue = stuff->window;
738 free(newPix);
739 return rc;
740 }
741
742 if (!pWin->viewable) {
743 free(newPix);
744 return BadMatch;
745 }
746
747 cw = GetCompWindow(pWin);
748 if (!cw) {
749 free(newPix);
750 return BadMatch;
751 }
752
753 pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
754 if (!pPixmap) {
755 free(newPix);
756 return BadMatch;
757 }
758
759 if (!AddResource(newPix->info[i].id, RT_PIXMAP, (pointer) pPixmap))
760 return BadAlloc;
761
762 ++pPixmap->refcnt;
763 }
764
765 if (!AddResource(stuff->pixmap, XRT_PIXMAP, (pointer) newPix))
766 return BadAlloc;
767
768 return Success;
769 }
770
771 static int
772 PanoramiXCompositeGetOverlayWindow(ClientPtr client)
773 {
774 REQUEST(xCompositeGetOverlayWindowReq);
775 xCompositeGetOverlayWindowReply rep;
776 WindowPtr pWin;
777 ScreenPtr pScreen;
778 CompScreenPtr cs;
779 CompOverlayClientPtr pOc;
780 int rc;
781 PanoramiXRes *win, *overlayWin = NULL;
782 int i;
783
784 REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
785
786 if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
787 client, DixUnknownAccess))) {
788 client->errorValue = stuff->window;
789 return rc;
790 }
791
792 cs = GetCompScreen(screenInfo.screens[0]);
793 if (!cs->pOverlayWin) {
794 if (!(overlayWin = malloc(sizeof(PanoramiXRes))))
795 return BadAlloc;
796
797 overlayWin->type = XRT_WINDOW;
798 overlayWin->u.win.root = FALSE;
799 }
800
801 FOR_NSCREENS_BACKWARD(i) {
802 rc = dixLookupResourceByType((pointer *) &pWin, win->info[i].id,
803 RT_WINDOW, client, DixGetAttrAccess);
804 if (rc != Success) {
805 client->errorValue = stuff->window;
806 free(overlayWin);
807 return rc;
808 }
809 pScreen = pWin->drawable.pScreen;
810
811 /*
812 * Create an OverlayClient structure to mark this client's
813 * interest in the overlay window
814 */
815 pOc = compCreateOverlayClient(pScreen, client);
816 if (pOc == NULL) {
817 free(overlayWin);
818 return BadAlloc;
819 }
820
821 /*
822 * Make sure the overlay window exists
823 */
824 cs = GetCompScreen(pScreen);
825 if (cs->pOverlayWin == NULL)
826 if (!compCreateOverlayWindow(pScreen)) {
827 FreeResource(pOc->resource, RT_NONE);
828 free(overlayWin);
829 return BadAlloc;
830 }
831
832 rc = XaceHook(XACE_RESOURCE_ACCESS, client,
833 cs->pOverlayWin->drawable.id,
834 RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL,
835 DixGetAttrAccess);
836 if (rc != Success) {
837 FreeResource(pOc->resource, RT_NONE);
838 free(overlayWin);
839 return rc;
840 }
841 }
842
843 if (overlayWin) {
844 FOR_NSCREENS(i) {
845 cs = GetCompScreen(screenInfo.screens[i]);
846 overlayWin->info[i].id = cs->pOverlayWin->drawable.id;
847 }
848
849 AddResource(overlayWin->info[0].id, XRT_WINDOW, overlayWin);
850 }
851
852 cs = GetCompScreen(screenInfo.screens[0]);
853
854 rep = (xCompositeGetOverlayWindowReply) {
855 .type = X_Reply,
856 .sequenceNumber = client->sequence,
857 .length = 0,
858 .overlayWin = cs->pOverlayWin->drawable.id
859 };
860
861 if (client->swapped) {
862 swaps(&rep.sequenceNumber);
863 swapl(&rep.length);
864 swapl(&rep.overlayWin);
865 }
866 WriteToClient(client, sz_xCompositeGetOverlayWindowReply, &rep);
867
868 return Success;
869 }
870
871 static int
872 PanoramiXCompositeReleaseOverlayWindow(ClientPtr client)
873 {
874 REQUEST(xCompositeReleaseOverlayWindowReq);
875 WindowPtr pWin;
876 ScreenPtr pScreen;
877 CompOverlayClientPtr pOc;
878 PanoramiXRes *win;
879 int i, rc;
880
881 REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
882
883 if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
884 client, DixUnknownAccess))) {
885 client->errorValue = stuff->window;
886 return rc;
887 }
888
889 FOR_NSCREENS_BACKWARD(i) {
890 if ((rc = dixLookupResourceByType((void **) &pWin, win->info[i].id,
891 XRT_WINDOW, client,
892 DixUnknownAccess))) {
893 client->errorValue = stuff->window;
894 return rc;
895 }
896 pScreen = pWin->drawable.pScreen;
897
898 /*
899 * Has client queried a reference to the overlay window
900 * on this screen? If not, generate an error.
901 */
902 pOc = compFindOverlayClient(pWin->drawable.pScreen, client);
903 if (pOc == NULL)
904 return BadMatch;
905
906 /* The delete function will free the client structure */
907 FreeResource(pOc->resource, RT_NONE);
908 }
909
910 return Success;
911 }
912
913 void
914 PanoramiXCompositeInit(void)
915 {
916 int i;
917
918 for (i = 0; i < CompositeNumberRequests; i++)
919 PanoramiXSaveCompositeVector[i] = ProcCompositeVector[i];
920 /*
921 * Stuff in Xinerama aware request processing hooks
922 */
923 ProcCompositeVector[X_CompositeRedirectWindow] =
924 PanoramiXCompositeRedirectWindow;
925 ProcCompositeVector[X_CompositeRedirectSubwindows] =
926 PanoramiXCompositeRedirectSubwindows;
927 ProcCompositeVector[X_CompositeUnredirectWindow] =
928 PanoramiXCompositeUnredirectWindow;
929 ProcCompositeVector[X_CompositeUnredirectSubwindows] =
930 PanoramiXCompositeUnredirectSubwindows;
931 ProcCompositeVector[X_CompositeNameWindowPixmap] =
932 PanoramiXCompositeNameWindowPixmap;
933 ProcCompositeVector[X_CompositeGetOverlayWindow] =
934 PanoramiXCompositeGetOverlayWindow;
935 ProcCompositeVector[X_CompositeReleaseOverlayWindow] =
936 PanoramiXCompositeReleaseOverlayWindow;
937 }
938
939 void
940 PanoramiXCompositeReset(void)
941 {
942 int i;
943
944 for (i = 0; i < CompositeNumberRequests; i++)
945 ProcCompositeVector[i] = PanoramiXSaveCompositeVector[i];
946 }
947
948 #endif