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 int
FreeCompositeClientWindow(void * value,XID ccwid)70 FreeCompositeClientWindow(void *value, XID ccwid)
71 {
72 WindowPtr pWin = value;
73
74 compFreeClientWindow(pWin, ccwid);
75 return Success;
76 }
77
78 static int
FreeCompositeClientSubwindows(void * value,XID ccwid)79 FreeCompositeClientSubwindows(void *value, XID ccwid)
80 {
81 WindowPtr pWin = value;
82
83 compFreeClientSubwindows(pWin, ccwid);
84 return Success;
85 }
86
87 static int
FreeCompositeClientOverlay(void * value,XID ccwid)88 FreeCompositeClientOverlay(void *value, XID ccwid)
89 {
90 CompOverlayClientPtr pOc = (CompOverlayClientPtr) value;
91
92 compFreeOverlayClient(pOc);
93 return Success;
94 }
95
96 static int
ProcCompositeQueryVersion(ClientPtr client)97 ProcCompositeQueryVersion(ClientPtr client)
98 {
99 CompositeClientPtr pCompositeClient = GetCompositeClient(client);
100 xCompositeQueryVersionReply rep = {
101 .type = X_Reply,
102 .sequenceNumber = client->sequence,
103 .length = 0
104 };
105
106 REQUEST(xCompositeQueryVersionReq);
107
108 REQUEST_SIZE_MATCH(xCompositeQueryVersionReq);
109 if (stuff->majorVersion < SERVER_COMPOSITE_MAJOR_VERSION) {
110 rep.majorVersion = stuff->majorVersion;
111 rep.minorVersion = stuff->minorVersion;
112 }
113 else {
114 rep.majorVersion = SERVER_COMPOSITE_MAJOR_VERSION;
115 rep.minorVersion = SERVER_COMPOSITE_MINOR_VERSION;
116 }
117 pCompositeClient->major_version = rep.majorVersion;
118 pCompositeClient->minor_version = rep.minorVersion;
119 if (client->swapped) {
120 swaps(&rep.sequenceNumber);
121 swapl(&rep.length);
122 swapl(&rep.majorVersion);
123 swapl(&rep.minorVersion);
124 }
125 WriteToClient(client, sizeof(xCompositeQueryVersionReply), &rep);
126 return Success;
127 }
128
129 #define VERIFY_WINDOW(pWindow, wid, client, mode) \
130 do { \
131 int err; \
132 err = dixLookupResourceByType((void **) &pWindow, wid, \
133 RT_WINDOW, client, mode); \
134 if (err != Success) { \
135 client->errorValue = wid; \
136 return err; \
137 } \
138 } while (0)
139
140 static int
ProcCompositeRedirectWindow(ClientPtr client)141 ProcCompositeRedirectWindow(ClientPtr client)
142 {
143 WindowPtr pWin;
144
145 REQUEST(xCompositeRedirectWindowReq);
146
147 REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
148 VERIFY_WINDOW(pWin, stuff->window, client,
149 DixSetAttrAccess | DixManageAccess | DixBlendAccess);
150
151 return compRedirectWindow(client, pWin, stuff->update);
152 }
153
154 static int
ProcCompositeRedirectSubwindows(ClientPtr client)155 ProcCompositeRedirectSubwindows(ClientPtr client)
156 {
157 WindowPtr pWin;
158
159 REQUEST(xCompositeRedirectSubwindowsReq);
160
161 REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
162 VERIFY_WINDOW(pWin, stuff->window, client,
163 DixSetAttrAccess | DixManageAccess | DixBlendAccess);
164
165 return compRedirectSubwindows(client, pWin, stuff->update);
166 }
167
168 static int
ProcCompositeUnredirectWindow(ClientPtr client)169 ProcCompositeUnredirectWindow(ClientPtr client)
170 {
171 WindowPtr pWin;
172
173 REQUEST(xCompositeUnredirectWindowReq);
174
175 REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
176 VERIFY_WINDOW(pWin, stuff->window, client,
177 DixSetAttrAccess | DixManageAccess | DixBlendAccess);
178
179 return compUnredirectWindow(client, pWin, stuff->update);
180 }
181
182 static int
ProcCompositeUnredirectSubwindows(ClientPtr client)183 ProcCompositeUnredirectSubwindows(ClientPtr client)
184 {
185 WindowPtr pWin;
186
187 REQUEST(xCompositeUnredirectSubwindowsReq);
188
189 REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
190 VERIFY_WINDOW(pWin, stuff->window, client,
191 DixSetAttrAccess | DixManageAccess | DixBlendAccess);
192
193 return compUnredirectSubwindows(client, pWin, stuff->update);
194 }
195
196 static int
ProcCompositeCreateRegionFromBorderClip(ClientPtr client)197 ProcCompositeCreateRegionFromBorderClip(ClientPtr client)
198 {
199 WindowPtr pWin;
200 CompWindowPtr cw;
201 RegionPtr pBorderClip, pRegion;
202
203 REQUEST(xCompositeCreateRegionFromBorderClipReq);
204
205 REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq);
206 VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
207 LEGAL_NEW_RESOURCE(stuff->region, client);
208
209 cw = GetCompWindow(pWin);
210 if (cw)
211 pBorderClip = &cw->borderClip;
212 else
213 pBorderClip = &pWin->borderClip;
214 pRegion = XFixesRegionCopy(pBorderClip);
215 if (!pRegion)
216 return BadAlloc;
217 RegionTranslate(pRegion, -pWin->drawable.x, -pWin->drawable.y);
218
219 if (!AddResource(stuff->region, RegionResType, (void *) pRegion))
220 return BadAlloc;
221
222 return Success;
223 }
224
225 static int
ProcCompositeNameWindowPixmap(ClientPtr client)226 ProcCompositeNameWindowPixmap(ClientPtr client)
227 {
228 WindowPtr pWin;
229 CompWindowPtr cw;
230 PixmapPtr pPixmap;
231 ScreenPtr pScreen;
232 int rc;
233
234 REQUEST(xCompositeNameWindowPixmapReq);
235
236 REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
237 VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
238
239 pScreen = pWin->drawable.pScreen;
240
241 if (!pWin->viewable)
242 return BadMatch;
243
244 LEGAL_NEW_RESOURCE(stuff->pixmap, client);
245
246 cw = GetCompWindow(pWin);
247 if (!cw)
248 return BadMatch;
249
250 pPixmap = (*pScreen->GetWindowPixmap) (pWin);
251 if (!pPixmap)
252 return BadMatch;
253
254 /* security creation/labeling check */
255 rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP,
256 pPixmap, RT_WINDOW, pWin, DixCreateAccess);
257 if (rc != Success)
258 return rc;
259
260 ++pPixmap->refcnt;
261
262 if (!AddResource(stuff->pixmap, RT_PIXMAP, (void *) pPixmap))
263 return BadAlloc;
264
265 if (pScreen->NameWindowPixmap) {
266 rc = pScreen->NameWindowPixmap(pWin, pPixmap, stuff->pixmap);
267 if (rc != Success) {
268 FreeResource(stuff->pixmap, RT_NONE);
269 return rc;
270 }
271 }
272
273 return Success;
274 }
275
276 static int
ProcCompositeGetOverlayWindow(ClientPtr client)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
ProcCompositeReleaseOverlayWindow(ClientPtr client)334 ProcCompositeReleaseOverlayWindow(ClientPtr client)
335 {
336 REQUEST(xCompositeReleaseOverlayWindowReq);
337 WindowPtr pWin;
338 CompOverlayClientPtr pOc;
339
340 REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
341 VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
342
343 /*
344 * Has client queried a reference to the overlay window
345 * on this screen? If not, generate an error.
346 */
347 pOc = compFindOverlayClient(pWin->drawable.pScreen, client);
348 if (pOc == NULL)
349 return BadMatch;
350
351 /* The delete function will free the client structure */
352 FreeResource(pOc->resource, RT_NONE);
353
354 return Success;
355 }
356
357 static int (*ProcCompositeVector[CompositeNumberRequests]) (ClientPtr) = {
358 ProcCompositeQueryVersion,
359 ProcCompositeRedirectWindow,
360 ProcCompositeRedirectSubwindows,
361 ProcCompositeUnredirectWindow,
362 ProcCompositeUnredirectSubwindows,
363 ProcCompositeCreateRegionFromBorderClip,
364 ProcCompositeNameWindowPixmap,
365 ProcCompositeGetOverlayWindow, ProcCompositeReleaseOverlayWindow,};
366
367 static int
ProcCompositeDispatch(ClientPtr client)368 ProcCompositeDispatch(ClientPtr client)
369 {
370 REQUEST(xReq);
371
372 if (stuff->data < CompositeNumberRequests)
373 return (*ProcCompositeVector[stuff->data]) (client);
374 else
375 return BadRequest;
376 }
377
378 static int _X_COLD
SProcCompositeQueryVersion(ClientPtr client)379 SProcCompositeQueryVersion(ClientPtr client)
380 {
381 REQUEST(xCompositeQueryVersionReq);
382
383 swaps(&stuff->length);
384 REQUEST_SIZE_MATCH(xCompositeQueryVersionReq);
385 swapl(&stuff->majorVersion);
386 swapl(&stuff->minorVersion);
387 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
388 }
389
390 static int _X_COLD
SProcCompositeRedirectWindow(ClientPtr client)391 SProcCompositeRedirectWindow(ClientPtr client)
392 {
393 REQUEST(xCompositeRedirectWindowReq);
394
395 swaps(&stuff->length);
396 REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
397 swapl(&stuff->window);
398 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
399 }
400
401 static int _X_COLD
SProcCompositeRedirectSubwindows(ClientPtr client)402 SProcCompositeRedirectSubwindows(ClientPtr client)
403 {
404 REQUEST(xCompositeRedirectSubwindowsReq);
405
406 swaps(&stuff->length);
407 REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
408 swapl(&stuff->window);
409 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
410 }
411
412 static int _X_COLD
SProcCompositeUnredirectWindow(ClientPtr client)413 SProcCompositeUnredirectWindow(ClientPtr client)
414 {
415 REQUEST(xCompositeUnredirectWindowReq);
416
417 swaps(&stuff->length);
418 REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
419 swapl(&stuff->window);
420 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
421 }
422
423 static int _X_COLD
SProcCompositeUnredirectSubwindows(ClientPtr client)424 SProcCompositeUnredirectSubwindows(ClientPtr client)
425 {
426 REQUEST(xCompositeUnredirectSubwindowsReq);
427
428 swaps(&stuff->length);
429 REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
430 swapl(&stuff->window);
431 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
432 }
433
434 static int _X_COLD
SProcCompositeCreateRegionFromBorderClip(ClientPtr client)435 SProcCompositeCreateRegionFromBorderClip(ClientPtr client)
436 {
437 REQUEST(xCompositeCreateRegionFromBorderClipReq);
438
439 swaps(&stuff->length);
440 REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq);
441 swapl(&stuff->region);
442 swapl(&stuff->window);
443 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
444 }
445
446 static int _X_COLD
SProcCompositeNameWindowPixmap(ClientPtr client)447 SProcCompositeNameWindowPixmap(ClientPtr client)
448 {
449 REQUEST(xCompositeNameWindowPixmapReq);
450
451 swaps(&stuff->length);
452 REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
453 swapl(&stuff->window);
454 swapl(&stuff->pixmap);
455 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
456 }
457
458 static int _X_COLD
SProcCompositeGetOverlayWindow(ClientPtr client)459 SProcCompositeGetOverlayWindow(ClientPtr client)
460 {
461 REQUEST(xCompositeGetOverlayWindowReq);
462
463 swaps(&stuff->length);
464 REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
465 swapl(&stuff->window);
466 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
467 }
468
469 static int _X_COLD
SProcCompositeReleaseOverlayWindow(ClientPtr client)470 SProcCompositeReleaseOverlayWindow(ClientPtr client)
471 {
472 REQUEST(xCompositeReleaseOverlayWindowReq);
473
474 swaps(&stuff->length);
475 REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
476 swapl(&stuff->window);
477 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
478 }
479
480 static int
481 (*SProcCompositeVector[CompositeNumberRequests]) (ClientPtr) = {
482 SProcCompositeQueryVersion,
483 SProcCompositeRedirectWindow,
484 SProcCompositeRedirectSubwindows,
485 SProcCompositeUnredirectWindow,
486 SProcCompositeUnredirectSubwindows,
487 SProcCompositeCreateRegionFromBorderClip,
488 SProcCompositeNameWindowPixmap,
489 SProcCompositeGetOverlayWindow,
490 SProcCompositeReleaseOverlayWindow,
491 };
492
493 static int _X_COLD
SProcCompositeDispatch(ClientPtr client)494 SProcCompositeDispatch(ClientPtr client)
495 {
496 REQUEST(xReq);
497
498 if (stuff->data < CompositeNumberRequests)
499 return (*SProcCompositeVector[stuff->data]) (client);
500 else
501 return BadRequest;
502 }
503
504 /** @see GetDefaultBytes */
505 static SizeType coreGetWindowBytes;
506
507 static void
GetCompositeWindowBytes(void * value,XID id,ResourceSizePtr size)508 GetCompositeWindowBytes(void *value, XID id, ResourceSizePtr size)
509 {
510 WindowPtr window = value;
511
512 /* call down */
513 coreGetWindowBytes(value, id, size);
514
515 /* account for redirection */
516 if (window->redirectDraw != RedirectDrawNone)
517 {
518 SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP);
519 ResourceSizeRec pixmapSize = { 0, 0 };
520 ScreenPtr screen = window->drawable.pScreen;
521 PixmapPtr pixmap = screen->GetWindowPixmap(window);
522 pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize);
523 size->pixmapRefSize += pixmapSize.pixmapRefSize;
524 }
525 }
526
527 void
CompositeExtensionInit(void)528 CompositeExtensionInit(void)
529 {
530 ExtensionEntry *extEntry;
531 int s;
532
533 /* Assume initialization is going to fail */
534 noCompositeExtension = TRUE;
535
536 for (s = 0; s < screenInfo.numScreens; s++) {
537 ScreenPtr pScreen = screenInfo.screens[s];
538 VisualPtr vis;
539
540 /* Composite on 8bpp pseudocolor root windows appears to fail, so
541 * just disable it on anything pseudocolor for safety.
542 */
543 for (vis = pScreen->visuals; vis->vid != pScreen->rootVisual; vis++);
544 if ((vis->class | DynamicClass) == PseudoColor)
545 return;
546
547 /* Ensure that Render is initialized, which is required for automatic
548 * compositing.
549 */
550 if (GetPictureScreenIfSet(pScreen) == NULL)
551 return;
552 }
553
554 CompositeClientWindowType = CreateNewResourceType
555 (FreeCompositeClientWindow, "CompositeClientWindow");
556 if (!CompositeClientWindowType)
557 return;
558
559 coreGetWindowBytes = GetResourceTypeSizeFunc(RT_WINDOW);
560 SetResourceTypeSizeFunc(RT_WINDOW, GetCompositeWindowBytes);
561
562 CompositeClientSubwindowsType = CreateNewResourceType
563 (FreeCompositeClientSubwindows, "CompositeClientSubwindows");
564 if (!CompositeClientSubwindowsType)
565 return;
566
567 CompositeClientOverlayType = CreateNewResourceType
568 (FreeCompositeClientOverlay, "CompositeClientOverlay");
569 if (!CompositeClientOverlayType)
570 return;
571
572 if (!dixRegisterPrivateKey(&CompositeClientPrivateKeyRec, PRIVATE_CLIENT,
573 sizeof(CompositeClientRec)))
574 return;
575
576 for (s = 0; s < screenInfo.numScreens; s++)
577 if (!compScreenInit(screenInfo.screens[s]))
578 return;
579
580 extEntry = AddExtension(COMPOSITE_NAME, 0, 0,
581 ProcCompositeDispatch, SProcCompositeDispatch,
582 NULL, StandardMinorOpcode);
583 if (!extEntry)
584 return;
585 CompositeReqCode = (CARD8) extEntry->base;
586
587 /* Initialization succeeded */
588 noCompositeExtension = FALSE;
589 }
590
591 #ifdef PANORAMIX
592 #include "panoramiXsrv.h"
593
594 int (*PanoramiXSaveCompositeVector[CompositeNumberRequests]) (ClientPtr);
595
596 static int
PanoramiXCompositeRedirectWindow(ClientPtr client)597 PanoramiXCompositeRedirectWindow(ClientPtr client)
598 {
599 PanoramiXRes *win;
600 int rc = 0, j;
601
602 REQUEST(xCompositeRedirectWindowReq);
603
604 REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
605
606 if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
607 client, DixUnknownAccess))) {
608 client->errorValue = stuff->window;
609 return rc;
610 }
611
612 FOR_NSCREENS_FORWARD(j) {
613 stuff->window = win->info[j].id;
614 rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
615 if (rc != Success)
616 break;
617 }
618
619 return rc;
620 }
621
622 static int
PanoramiXCompositeRedirectSubwindows(ClientPtr client)623 PanoramiXCompositeRedirectSubwindows(ClientPtr client)
624 {
625 PanoramiXRes *win;
626 int rc = 0, j;
627
628 REQUEST(xCompositeRedirectSubwindowsReq);
629
630 REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
631
632 if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
633 client, DixUnknownAccess))) {
634 client->errorValue = stuff->window;
635 return rc;
636 }
637
638 FOR_NSCREENS_FORWARD(j) {
639 stuff->window = win->info[j].id;
640 rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
641 if (rc != Success)
642 break;
643 }
644
645 return rc;
646 }
647
648 static int
PanoramiXCompositeUnredirectWindow(ClientPtr client)649 PanoramiXCompositeUnredirectWindow(ClientPtr client)
650 {
651 PanoramiXRes *win;
652 int rc = 0, j;
653
654 REQUEST(xCompositeUnredirectWindowReq);
655
656 REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
657
658 if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
659 client, DixUnknownAccess))) {
660 client->errorValue = stuff->window;
661 return rc;
662 }
663
664 FOR_NSCREENS_FORWARD(j) {
665 stuff->window = win->info[j].id;
666 rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
667 if (rc != Success)
668 break;
669 }
670
671 return rc;
672 }
673
674 static int
PanoramiXCompositeUnredirectSubwindows(ClientPtr client)675 PanoramiXCompositeUnredirectSubwindows(ClientPtr client)
676 {
677 PanoramiXRes *win;
678 int rc = 0, j;
679
680 REQUEST(xCompositeUnredirectSubwindowsReq);
681
682 REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
683
684 if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
685 client, DixUnknownAccess))) {
686 client->errorValue = stuff->window;
687 return rc;
688 }
689
690 FOR_NSCREENS_FORWARD(j) {
691 stuff->window = win->info[j].id;
692 rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
693 if (rc != Success)
694 break;
695 }
696
697 return rc;
698 }
699
700 static int
PanoramiXCompositeNameWindowPixmap(ClientPtr client)701 PanoramiXCompositeNameWindowPixmap(ClientPtr client)
702 {
703 WindowPtr pWin;
704 CompWindowPtr cw;
705 PixmapPtr pPixmap;
706 int rc;
707 PanoramiXRes *win, *newPix;
708 int i;
709
710 REQUEST(xCompositeNameWindowPixmapReq);
711
712 REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
713
714 if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
715 client, DixUnknownAccess))) {
716 client->errorValue = stuff->window;
717 return rc;
718 }
719
720 LEGAL_NEW_RESOURCE(stuff->pixmap, client);
721
722 if (!(newPix = malloc(sizeof(PanoramiXRes))))
723 return BadAlloc;
724
725 newPix->type = XRT_PIXMAP;
726 newPix->u.pix.shared = FALSE;
727 panoramix_setup_ids(newPix, client, stuff->pixmap);
728
729 FOR_NSCREENS(i) {
730 rc = dixLookupResourceByType((void **) &pWin, win->info[i].id,
731 RT_WINDOW, client, DixGetAttrAccess);
732 if (rc != Success) {
733 client->errorValue = stuff->window;
734 free(newPix);
735 return rc;
736 }
737
738 if (!pWin->viewable) {
739 free(newPix);
740 return BadMatch;
741 }
742
743 cw = GetCompWindow(pWin);
744 if (!cw) {
745 free(newPix);
746 return BadMatch;
747 }
748
749 pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
750 if (!pPixmap) {
751 free(newPix);
752 return BadMatch;
753 }
754
755 if (!AddResource(newPix->info[i].id, RT_PIXMAP, (void *) pPixmap))
756 return BadAlloc;
757
758 ++pPixmap->refcnt;
759 }
760
761 if (!AddResource(stuff->pixmap, XRT_PIXMAP, (void *) newPix))
762 return BadAlloc;
763
764 return Success;
765 }
766
767 static int
PanoramiXCompositeGetOverlayWindow(ClientPtr client)768 PanoramiXCompositeGetOverlayWindow(ClientPtr client)
769 {
770 REQUEST(xCompositeGetOverlayWindowReq);
771 xCompositeGetOverlayWindowReply rep;
772 WindowPtr pWin;
773 ScreenPtr pScreen;
774 CompScreenPtr cs;
775 CompOverlayClientPtr pOc;
776 int rc;
777 PanoramiXRes *win, *overlayWin = NULL;
778 int i;
779
780 REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
781
782 if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
783 client, DixUnknownAccess))) {
784 client->errorValue = stuff->window;
785 return rc;
786 }
787
788 cs = GetCompScreen(screenInfo.screens[0]);
789 if (!cs->pOverlayWin) {
790 if (!(overlayWin = malloc(sizeof(PanoramiXRes))))
791 return BadAlloc;
792
793 overlayWin->type = XRT_WINDOW;
794 overlayWin->u.win.root = FALSE;
795 }
796
797 FOR_NSCREENS_BACKWARD(i) {
798 rc = dixLookupResourceByType((void **) &pWin, win->info[i].id,
799 RT_WINDOW, client, DixGetAttrAccess);
800 if (rc != Success) {
801 client->errorValue = stuff->window;
802 free(overlayWin);
803 return rc;
804 }
805 pScreen = pWin->drawable.pScreen;
806
807 /*
808 * Create an OverlayClient structure to mark this client's
809 * interest in the overlay window
810 */
811 pOc = compCreateOverlayClient(pScreen, client);
812 if (pOc == NULL) {
813 free(overlayWin);
814 return BadAlloc;
815 }
816
817 /*
818 * Make sure the overlay window exists
819 */
820 cs = GetCompScreen(pScreen);
821 if (cs->pOverlayWin == NULL)
822 if (!compCreateOverlayWindow(pScreen)) {
823 FreeResource(pOc->resource, RT_NONE);
824 free(overlayWin);
825 return BadAlloc;
826 }
827
828 rc = XaceHook(XACE_RESOURCE_ACCESS, client,
829 cs->pOverlayWin->drawable.id,
830 RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL,
831 DixGetAttrAccess);
832 if (rc != Success) {
833 FreeResource(pOc->resource, RT_NONE);
834 free(overlayWin);
835 return rc;
836 }
837 }
838
839 if (overlayWin) {
840 FOR_NSCREENS(i) {
841 cs = GetCompScreen(screenInfo.screens[i]);
842 overlayWin->info[i].id = cs->pOverlayWin->drawable.id;
843 }
844
845 AddResource(overlayWin->info[0].id, XRT_WINDOW, overlayWin);
846 }
847
848 cs = GetCompScreen(screenInfo.screens[0]);
849
850 rep = (xCompositeGetOverlayWindowReply) {
851 .type = X_Reply,
852 .sequenceNumber = client->sequence,
853 .length = 0,
854 .overlayWin = cs->pOverlayWin->drawable.id
855 };
856
857 if (client->swapped) {
858 swaps(&rep.sequenceNumber);
859 swapl(&rep.length);
860 swapl(&rep.overlayWin);
861 }
862 WriteToClient(client, sz_xCompositeGetOverlayWindowReply, &rep);
863
864 return Success;
865 }
866
867 static int
PanoramiXCompositeReleaseOverlayWindow(ClientPtr client)868 PanoramiXCompositeReleaseOverlayWindow(ClientPtr client)
869 {
870 REQUEST(xCompositeReleaseOverlayWindowReq);
871 WindowPtr pWin;
872 CompOverlayClientPtr pOc;
873 PanoramiXRes *win;
874 int i, rc;
875
876 REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
877
878 if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
879 client, DixUnknownAccess))) {
880 client->errorValue = stuff->window;
881 return rc;
882 }
883
884 FOR_NSCREENS_BACKWARD(i) {
885 if ((rc = dixLookupResourceByType((void **) &pWin, win->info[i].id,
886 XRT_WINDOW, client,
887 DixUnknownAccess))) {
888 client->errorValue = stuff->window;
889 return rc;
890 }
891
892 /*
893 * Has client queried a reference to the overlay window
894 * on this screen? If not, generate an error.
895 */
896 pOc = compFindOverlayClient(pWin->drawable.pScreen, client);
897 if (pOc == NULL)
898 return BadMatch;
899
900 /* The delete function will free the client structure */
901 FreeResource(pOc->resource, RT_NONE);
902 }
903
904 return Success;
905 }
906
907 void
PanoramiXCompositeInit(void)908 PanoramiXCompositeInit(void)
909 {
910 int i;
911
912 for (i = 0; i < CompositeNumberRequests; i++)
913 PanoramiXSaveCompositeVector[i] = ProcCompositeVector[i];
914 /*
915 * Stuff in Xinerama aware request processing hooks
916 */
917 ProcCompositeVector[X_CompositeRedirectWindow] =
918 PanoramiXCompositeRedirectWindow;
919 ProcCompositeVector[X_CompositeRedirectSubwindows] =
920 PanoramiXCompositeRedirectSubwindows;
921 ProcCompositeVector[X_CompositeUnredirectWindow] =
922 PanoramiXCompositeUnredirectWindow;
923 ProcCompositeVector[X_CompositeUnredirectSubwindows] =
924 PanoramiXCompositeUnredirectSubwindows;
925 ProcCompositeVector[X_CompositeNameWindowPixmap] =
926 PanoramiXCompositeNameWindowPixmap;
927 ProcCompositeVector[X_CompositeGetOverlayWindow] =
928 PanoramiXCompositeGetOverlayWindow;
929 ProcCompositeVector[X_CompositeReleaseOverlayWindow] =
930 PanoramiXCompositeReleaseOverlayWindow;
931 }
932
933 void
PanoramiXCompositeReset(void)934 PanoramiXCompositeReset(void)
935 {
936 int i;
937
938 for (i = 0; i < CompositeNumberRequests; i++)
939 ProcCompositeVector[i] = PanoramiXSaveCompositeVector[i];
940 }
941
942 #endif
943