2 * Copyright © 2006 Sun Microsystems, Inc. All rights reserved.
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:
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
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.
23 * Copyright © 2003 Keith Packard
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.
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.
44 #ifdef HAVE_DIX_CONFIG_H
45 #include <dix-config.h>
50 #include "protocol-versions.h"
52 static CARD8 CompositeReqCode;
53 static DevPrivateKeyRec CompositeClientPrivateKeyRec;
54 #define CompositeClientPrivateKey (&CompositeClientPrivateKeyRec)
55 RESTYPE CompositeClientWindowType;
56 RESTYPE CompositeClientSubwindowsType;
57 RESTYPE CompositeClientOverlayType;
59 typedef struct _CompositeClient {
62 } CompositeClientRec, *CompositeClientPtr;
64 #define GetCompositeClient(pClient) ((CompositeClientPtr) \
65 dixLookupPrivate(&(pClient)->devPrivates, CompositeClientPrivateKey))
68 CompositeClientCallback (CallbackListPtr *list,
72 NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
73 ClientPtr pClient = clientinfo->client;
74 CompositeClientPtr pCompositeClient = GetCompositeClient (pClient);
76 pCompositeClient->major_version = 0;
77 pCompositeClient->minor_version = 0;
81 FreeCompositeClientWindow (pointer value, XID ccwid)
83 WindowPtr pWin = value;
85 compFreeClientWindow (pWin, ccwid);
90 FreeCompositeClientSubwindows (pointer value, XID ccwid)
92 WindowPtr pWin = value;
94 compFreeClientSubwindows (pWin, ccwid);
99 FreeCompositeClientOverlay (pointer value, XID ccwid)
101 CompOverlayClientPtr pOc = (CompOverlayClientPtr) value;
103 compFreeOverlayClient (pOc);
108 ProcCompositeQueryVersion (ClientPtr client)
110 CompositeClientPtr pCompositeClient = GetCompositeClient (client);
111 xCompositeQueryVersionReply rep;
113 REQUEST(xCompositeQueryVersionReq);
115 REQUEST_SIZE_MATCH(xCompositeQueryVersionReq);
118 rep.sequenceNumber = client->sequence;
119 if (stuff->majorVersion < SERVER_COMPOSITE_MAJOR_VERSION) {
120 rep.majorVersion = stuff->majorVersion;
121 rep.minorVersion = stuff->minorVersion;
123 rep.majorVersion = SERVER_COMPOSITE_MAJOR_VERSION;
124 rep.minorVersion = SERVER_COMPOSITE_MINOR_VERSION;
126 pCompositeClient->major_version = rep.majorVersion;
127 pCompositeClient->minor_version = rep.minorVersion;
128 if (client->swapped) {
129 swaps(&rep.sequenceNumber, n);
130 swapl(&rep.length, n);
131 swapl(&rep.majorVersion, n);
132 swapl(&rep.minorVersion, n);
134 WriteToClient(client, sizeof(xCompositeQueryVersionReply), (char *)&rep);
138 #define VERIFY_WINDOW(pWindow, wid, client, mode) \
141 err = dixLookupResourceByType((pointer *) &pWindow, wid, \
142 RT_WINDOW, client, mode); \
143 if (err != Success) { \
144 client->errorValue = wid; \
150 ProcCompositeRedirectWindow (ClientPtr client)
153 REQUEST(xCompositeRedirectWindowReq);
155 REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
156 VERIFY_WINDOW(pWin, stuff->window, client,
157 DixSetAttrAccess|DixManageAccess|DixBlendAccess);
159 return compRedirectWindow (client, pWin, stuff->update);
163 ProcCompositeRedirectSubwindows (ClientPtr client)
166 REQUEST(xCompositeRedirectSubwindowsReq);
168 REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
169 VERIFY_WINDOW(pWin, stuff->window, client,
170 DixSetAttrAccess|DixManageAccess|DixBlendAccess);
172 return compRedirectSubwindows (client, pWin, stuff->update);
176 ProcCompositeUnredirectWindow (ClientPtr client)
179 REQUEST(xCompositeUnredirectWindowReq);
181 REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
182 VERIFY_WINDOW(pWin, stuff->window, client,
183 DixSetAttrAccess|DixManageAccess|DixBlendAccess);
185 return compUnredirectWindow (client, pWin, stuff->update);
189 ProcCompositeUnredirectSubwindows (ClientPtr client)
192 REQUEST(xCompositeUnredirectSubwindowsReq);
194 REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
195 VERIFY_WINDOW(pWin, stuff->window, client,
196 DixSetAttrAccess|DixManageAccess|DixBlendAccess);
198 return compUnredirectSubwindows (client, pWin, stuff->update);
202 ProcCompositeCreateRegionFromBorderClip (ClientPtr client)
206 RegionPtr pBorderClip, pRegion;
207 REQUEST(xCompositeCreateRegionFromBorderClipReq);
209 REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq);
210 VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
211 LEGAL_NEW_RESOURCE (stuff->region, client);
213 cw = GetCompWindow (pWin);
215 pBorderClip = &cw->borderClip;
217 pBorderClip = &pWin->borderClip;
218 pRegion = XFixesRegionCopy (pBorderClip);
221 RegionTranslate(pRegion, -pWin->drawable.x, -pWin->drawable.y);
223 if (!AddResource (stuff->region, RegionResType, (pointer) pRegion))
230 ProcCompositeNameWindowPixmap (ClientPtr client)
236 REQUEST(xCompositeNameWindowPixmapReq);
238 REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
239 VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
244 LEGAL_NEW_RESOURCE (stuff->pixmap, client);
246 cw = GetCompWindow (pWin);
250 pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
254 /* security creation/labeling check */
255 rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP,
256 pPixmap, RT_WINDOW, pWin, DixCreateAccess);
262 if (!AddResource (stuff->pixmap, RT_PIXMAP, (pointer) pPixmap))
270 ProcCompositeGetOverlayWindow (ClientPtr client)
272 REQUEST(xCompositeGetOverlayWindowReq);
273 xCompositeGetOverlayWindowReply rep;
277 CompOverlayClientPtr pOc;
280 REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
281 VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
282 pScreen = pWin->drawable.pScreen;
285 * Create an OverlayClient structure to mark this client's
286 * interest in the overlay window
288 pOc = compCreateOverlayClient(pScreen, client);
293 * Make sure the overlay window exists
295 cs = GetCompScreen(pScreen);
296 if (cs->pOverlayWin == NULL)
297 if (!compCreateOverlayWindow(pScreen))
299 FreeResource (pOc->resource, RT_NONE);
303 rc = XaceHook(XACE_RESOURCE_ACCESS, client, cs->pOverlayWin->drawable.id,
304 RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL, DixGetAttrAccess);
307 FreeResource (pOc->resource, RT_NONE);
312 rep.sequenceNumber = client->sequence;
314 rep.overlayWin = cs->pOverlayWin->drawable.id;
319 swaps(&rep.sequenceNumber, n);
320 swapl(&rep.length, n);
321 swapl(&rep.overlayWin, n);
323 (void) WriteToClient(client, sz_xCompositeGetOverlayWindowReply, (char *)&rep);
329 ProcCompositeReleaseOverlayWindow (ClientPtr client)
331 REQUEST(xCompositeReleaseOverlayWindowReq);
334 CompOverlayClientPtr pOc;
336 REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
337 VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
338 pScreen = pWin->drawable.pScreen;
341 * Has client queried a reference to the overlay window
342 * on this screen? If not, generate an error.
344 pOc = compFindOverlayClient (pWin->drawable.pScreen, client);
348 /* The delete function will free the client structure */
349 FreeResource (pOc->resource, RT_NONE);
354 static int (*ProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
355 ProcCompositeQueryVersion,
356 ProcCompositeRedirectWindow,
357 ProcCompositeRedirectSubwindows,
358 ProcCompositeUnredirectWindow,
359 ProcCompositeUnredirectSubwindows,
360 ProcCompositeCreateRegionFromBorderClip,
361 ProcCompositeNameWindowPixmap,
362 ProcCompositeGetOverlayWindow,
363 ProcCompositeReleaseOverlayWindow,
367 ProcCompositeDispatch (ClientPtr client)
371 if (stuff->data < CompositeNumberRequests)
372 return (*ProcCompositeVector[stuff->data]) (client);
378 SProcCompositeQueryVersion (ClientPtr client)
381 REQUEST(xCompositeQueryVersionReq);
383 swaps(&stuff->length, n);
384 REQUEST_SIZE_MATCH(xCompositeQueryVersionReq);
385 swapl(&stuff->majorVersion, n);
386 swapl(&stuff->minorVersion, n);
387 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
391 SProcCompositeRedirectWindow (ClientPtr client)
394 REQUEST(xCompositeRedirectWindowReq);
396 swaps(&stuff->length, n);
397 REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
398 swapl (&stuff->window, n);
399 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
403 SProcCompositeRedirectSubwindows (ClientPtr client)
406 REQUEST(xCompositeRedirectSubwindowsReq);
408 swaps(&stuff->length, n);
409 REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
410 swapl (&stuff->window, n);
411 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
415 SProcCompositeUnredirectWindow (ClientPtr client)
418 REQUEST(xCompositeUnredirectWindowReq);
420 swaps(&stuff->length, n);
421 REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
422 swapl (&stuff->window, n);
423 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
427 SProcCompositeUnredirectSubwindows (ClientPtr client)
430 REQUEST(xCompositeUnredirectSubwindowsReq);
432 swaps(&stuff->length, n);
433 REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
434 swapl (&stuff->window, n);
435 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
439 SProcCompositeCreateRegionFromBorderClip (ClientPtr client)
442 REQUEST(xCompositeCreateRegionFromBorderClipReq);
444 swaps(&stuff->length, n);
445 REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq);
446 swapl (&stuff->region, n);
447 swapl (&stuff->window, n);
448 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
452 SProcCompositeNameWindowPixmap (ClientPtr client)
455 REQUEST(xCompositeNameWindowPixmapReq);
457 swaps(&stuff->length, n);
458 REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
459 swapl (&stuff->window, n);
460 swapl (&stuff->pixmap, n);
461 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
465 SProcCompositeGetOverlayWindow (ClientPtr client)
468 REQUEST(xCompositeGetOverlayWindowReq);
470 swaps (&stuff->length, n);
471 REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
472 swapl(&stuff->window, n);
473 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
477 SProcCompositeReleaseOverlayWindow (ClientPtr client)
480 REQUEST(xCompositeReleaseOverlayWindowReq);
482 swaps (&stuff->length, n);
483 REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
484 swapl(&stuff->window, n);
485 return (*ProcCompositeVector[stuff->compositeReqType]) (client);
488 static int (*SProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
489 SProcCompositeQueryVersion,
490 SProcCompositeRedirectWindow,
491 SProcCompositeRedirectSubwindows,
492 SProcCompositeUnredirectWindow,
493 SProcCompositeUnredirectSubwindows,
494 SProcCompositeCreateRegionFromBorderClip,
495 SProcCompositeNameWindowPixmap,
496 SProcCompositeGetOverlayWindow,
497 SProcCompositeReleaseOverlayWindow,
501 SProcCompositeDispatch (ClientPtr client)
505 if (stuff->data < CompositeNumberRequests)
506 return (*SProcCompositeVector[stuff->data]) (client);
512 CompositeExtensionInit (void)
514 ExtensionEntry *extEntry;
517 /* Assume initialization is going to fail */
518 noCompositeExtension = TRUE;
520 for (s = 0; s < screenInfo.numScreens; s++) {
521 ScreenPtr pScreen = screenInfo.screens[s];
524 /* Composite on 8bpp pseudocolor root windows appears to fail, so
525 * just disable it on anything pseudocolor for safety.
527 for (vis = pScreen->visuals; vis->vid != pScreen->rootVisual; vis++)
529 if ((vis->class | DynamicClass) == PseudoColor)
532 /* Ensure that Render is initialized, which is required for automatic
535 if (GetPictureScreenIfSet(pScreen) == NULL)
539 /* Xinerama's rewriting of window drawing before Composite gets to it
542 if (!noPanoramiXExtension)
546 CompositeClientWindowType = CreateNewResourceType
547 (FreeCompositeClientWindow, "CompositeClientWindow");
548 if (!CompositeClientWindowType)
551 CompositeClientSubwindowsType = CreateNewResourceType
552 (FreeCompositeClientSubwindows, "CompositeClientSubwindows");
553 if (!CompositeClientSubwindowsType)
556 CompositeClientOverlayType = CreateNewResourceType
557 (FreeCompositeClientOverlay, "CompositeClientOverlay");
558 if (!CompositeClientOverlayType)
561 if (!dixRegisterPrivateKey(&CompositeClientPrivateKeyRec, PRIVATE_CLIENT,
562 sizeof(CompositeClientRec)))
565 if (!AddCallback (&ClientStateCallback, CompositeClientCallback, 0))
568 for (s = 0; s < screenInfo.numScreens; s++)
569 if (!compScreenInit (screenInfo.screens[s]))
572 extEntry = AddExtension (COMPOSITE_NAME, 0, 0,
573 ProcCompositeDispatch, SProcCompositeDispatch,
574 NULL, StandardMinorOpcode);
577 CompositeReqCode = (CARD8) extEntry->base;
579 miRegisterRedirectBorderClipProc (compSetRedirectBorderClip,
580 compGetRedirectBorderClip);
582 /* Initialization succeeded */
583 noCompositeExtension = FALSE;