2 * Copyright (c) 2006, Oracle and/or its affiliates. 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>
49 #include "compositeext.h"
51 DevPrivateKeyRec CompScreenPrivateKeyRec
;
52 DevPrivateKeyRec CompWindowPrivateKeyRec
;
53 DevPrivateKeyRec CompSubwindowsPrivateKeyRec
;
56 compCloseScreen(ScreenPtr pScreen
)
58 CompScreenPtr cs
= GetCompScreen(pScreen
);
61 free(cs
->alternateVisuals
);
63 pScreen
->CloseScreen
= cs
->CloseScreen
;
64 pScreen
->InstallColormap
= cs
->InstallColormap
;
65 pScreen
->ChangeWindowAttributes
= cs
->ChangeWindowAttributes
;
66 pScreen
->ReparentWindow
= cs
->ReparentWindow
;
67 pScreen
->ConfigNotify
= cs
->ConfigNotify
;
68 pScreen
->MoveWindow
= cs
->MoveWindow
;
69 pScreen
->ResizeWindow
= cs
->ResizeWindow
;
70 pScreen
->ChangeBorderWidth
= cs
->ChangeBorderWidth
;
72 pScreen
->ClipNotify
= cs
->ClipNotify
;
73 pScreen
->UnrealizeWindow
= cs
->UnrealizeWindow
;
74 pScreen
->RealizeWindow
= cs
->RealizeWindow
;
75 pScreen
->DestroyWindow
= cs
->DestroyWindow
;
76 pScreen
->CreateWindow
= cs
->CreateWindow
;
77 pScreen
->CopyWindow
= cs
->CopyWindow
;
78 pScreen
->PositionWindow
= cs
->PositionWindow
;
80 pScreen
->GetImage
= cs
->GetImage
;
81 pScreen
->SourceValidate
= cs
->SourceValidate
;
84 dixSetPrivate(&pScreen
->devPrivates
, CompScreenPrivateKey
, NULL
);
85 ret
= (*pScreen
->CloseScreen
) (pScreen
);
91 compInstallColormap(ColormapPtr pColormap
)
93 VisualPtr pVisual
= pColormap
->pVisual
;
94 ScreenPtr pScreen
= pColormap
->pScreen
;
95 CompScreenPtr cs
= GetCompScreen(pScreen
);
98 for (a
= 0; a
< cs
->numAlternateVisuals
; a
++)
99 if (pVisual
->vid
== cs
->alternateVisuals
[a
])
101 pScreen
->InstallColormap
= cs
->InstallColormap
;
102 (*pScreen
->InstallColormap
) (pColormap
);
103 cs
->InstallColormap
= pScreen
->InstallColormap
;
104 pScreen
->InstallColormap
= compInstallColormap
;
107 /* Fake backing store via automatic redirection */
109 compChangeWindowAttributes(WindowPtr pWin
, unsigned long mask
)
111 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
112 CompScreenPtr cs
= GetCompScreen(pScreen
);
115 pScreen
->ChangeWindowAttributes
= cs
->ChangeWindowAttributes
;
116 ret
= pScreen
->ChangeWindowAttributes(pWin
, mask
);
118 if (ret
&& (mask
& CWBackingStore
) &&
119 pScreen
->backingStoreSupport
!= NotUseful
) {
120 if (pWin
->backingStore
!= NotUseful
&& !pWin
->backStorage
) {
121 compRedirectWindow(serverClient
, pWin
, CompositeRedirectAutomatic
);
122 pWin
->backStorage
= (pointer
) (intptr_t) 1;
124 else if (pWin
->backingStore
== NotUseful
&& pWin
->backStorage
) {
125 compUnredirectWindow(serverClient
, pWin
,
126 CompositeRedirectAutomatic
);
127 pWin
->backStorage
= NULL
;
131 pScreen
->ChangeWindowAttributes
= compChangeWindowAttributes
;
137 compGetImage(DrawablePtr pDrawable
,
140 unsigned int format
, unsigned long planemask
, char *pdstLine
)
142 ScreenPtr pScreen
= pDrawable
->pScreen
;
143 CompScreenPtr cs
= GetCompScreen(pScreen
);
145 pScreen
->GetImage
= cs
->GetImage
;
146 if (pDrawable
->type
== DRAWABLE_WINDOW
)
147 compPaintChildrenToWindow((WindowPtr
) pDrawable
);
148 (*pScreen
->GetImage
) (pDrawable
, sx
, sy
, w
, h
, format
, planemask
, pdstLine
);
149 cs
->GetImage
= pScreen
->GetImage
;
150 pScreen
->GetImage
= compGetImage
;
154 compSourceValidate(DrawablePtr pDrawable
,
156 int width
, int height
, unsigned int subWindowMode
)
158 ScreenPtr pScreen
= pDrawable
->pScreen
;
159 CompScreenPtr cs
= GetCompScreen(pScreen
);
161 pScreen
->SourceValidate
= cs
->SourceValidate
;
162 if (pDrawable
->type
== DRAWABLE_WINDOW
&& subWindowMode
== IncludeInferiors
)
163 compPaintChildrenToWindow((WindowPtr
) pDrawable
);
164 if (pScreen
->SourceValidate
)
165 (*pScreen
->SourceValidate
) (pDrawable
, x
, y
, width
, height
,
167 cs
->SourceValidate
= pScreen
->SourceValidate
;
168 pScreen
->SourceValidate
= compSourceValidate
;
172 * Add alternate visuals -- always expose an ARGB32 and RGB24 visual
176 compFindVisuallessDepth(ScreenPtr pScreen
, int d
)
180 for (i
= 0; i
< pScreen
->numDepths
; i
++) {
181 DepthPtr depth
= &pScreen
->allowedDepths
[i
];
183 if (depth
->depth
== d
) {
185 * Make sure it doesn't have visuals already
196 * If there isn't one, then it's gonna be hard to have
197 * an associated visual
203 * Add a list of visual IDs to the list of visuals to implicitly redirect.
206 compRegisterAlternateVisuals(CompScreenPtr cs
, VisualID
* vids
, int nVisuals
)
210 p
= realloc(cs
->alternateVisuals
,
211 sizeof(VisualID
) * (cs
->numAlternateVisuals
+ nVisuals
));
215 memcpy(&p
[cs
->numAlternateVisuals
], vids
, sizeof(VisualID
) * nVisuals
);
217 cs
->alternateVisuals
= p
;
218 cs
->numAlternateVisuals
+= nVisuals
;
224 CompositeRegisterAlternateVisuals(ScreenPtr pScreen
, VisualID
* vids
,
227 CompScreenPtr cs
= GetCompScreen(pScreen
);
229 return compRegisterAlternateVisuals(cs
, vids
, nVisuals
);
232 typedef struct _alternateVisual
{
235 } CompAlternateVisual
;
237 static CompAlternateVisual altVisuals
[] = {
238 #if COMP_INCLUDE_RGB24_VISUAL
244 static const int NUM_COMP_ALTERNATE_VISUALS
= sizeof(altVisuals
) /
245 sizeof(CompAlternateVisual
);
248 compAddAlternateVisual(ScreenPtr pScreen
, CompScreenPtr cs
,
249 CompAlternateVisual
* alt
)
253 PictFormatPtr pPictFormat
;
254 unsigned long alphaMask
;
257 * The ARGB32 visual is always available. Other alternate depth visuals
258 * are only provided if their depth is less than the root window depth.
259 * There's no deep reason for this.
261 if (alt
->depth
>= pScreen
->rootDepth
&& alt
->depth
!= 32)
264 depth
= compFindVisuallessDepth(pScreen
, alt
->depth
);
266 /* alt->depth doesn't exist or already has alternate visuals. */
269 pPictFormat
= PictureMatchFormat(pScreen
, alt
->depth
, alt
->format
);
273 if (ResizeVisualArray(pScreen
, 1, depth
) == FALSE
) {
277 visual
= pScreen
->visuals
+ (pScreen
->numVisuals
- 1); /* the new one */
279 /* Initialize the visual */
280 visual
->bitsPerRGBValue
= 8;
281 if (PICT_FORMAT_TYPE(alt
->format
) == PICT_TYPE_COLOR
) {
282 visual
->class = PseudoColor
;
283 visual
->nplanes
= PICT_FORMAT_BPP(alt
->format
);
284 visual
->ColormapEntries
= 1 << visual
->nplanes
;
287 DirectFormatRec
*direct
= &pPictFormat
->direct
;
289 visual
->class = TrueColor
;
290 visual
->redMask
= ((unsigned long) direct
->redMask
) << direct
->red
;
292 ((unsigned long) direct
->greenMask
) << direct
->green
;
293 visual
->blueMask
= ((unsigned long) direct
->blueMask
) << direct
->blue
;
294 alphaMask
= ((unsigned long) direct
->alphaMask
) << direct
->alpha
;
295 visual
->offsetRed
= direct
->red
;
296 visual
->offsetGreen
= direct
->green
;
297 visual
->offsetBlue
= direct
->blue
;
299 * Include A bits in this (unlike GLX which includes only RGB)
300 * This lets DIX compute suitable masks for colormap allocations
302 visual
->nplanes
= Ones(visual
->redMask
|
304 visual
->blueMask
| alphaMask
);
305 /* find widest component */
306 visual
->ColormapEntries
= (1 << max(Ones(visual
->redMask
),
307 max(Ones(visual
->greenMask
),
308 Ones(visual
->blueMask
))));
311 /* remember the visual ID to detect auto-update windows */
312 compRegisterAlternateVisuals(cs
, &visual
->vid
, 1);
318 compAddAlternateVisuals(ScreenPtr pScreen
, CompScreenPtr cs
)
322 for (alt
= 0; alt
< NUM_COMP_ALTERNATE_VISUALS
; alt
++)
323 ret
|= compAddAlternateVisual(pScreen
, cs
, altVisuals
+ alt
);
329 compScreenInit(ScreenPtr pScreen
)
333 if (!dixRegisterPrivateKey(&CompScreenPrivateKeyRec
, PRIVATE_SCREEN
, 0))
335 if (!dixRegisterPrivateKey(&CompWindowPrivateKeyRec
, PRIVATE_WINDOW
, 0))
337 if (!dixRegisterPrivateKey(&CompSubwindowsPrivateKeyRec
, PRIVATE_WINDOW
, 0))
340 if (GetCompScreen(pScreen
))
342 cs
= (CompScreenPtr
) malloc(sizeof(CompScreenRec
));
346 cs
->overlayWid
= FakeClientID(0);
347 cs
->pOverlayWin
= NULL
;
348 cs
->pOverlayClients
= NULL
;
350 cs
->numAlternateVisuals
= 0;
351 cs
->alternateVisuals
= NULL
;
353 if (!compAddAlternateVisuals(pScreen
, cs
)) {
358 if (!disableBackingStore
)
359 pScreen
->backingStoreSupport
= WhenMapped
;
361 cs
->PositionWindow
= pScreen
->PositionWindow
;
362 pScreen
->PositionWindow
= compPositionWindow
;
364 cs
->CopyWindow
= pScreen
->CopyWindow
;
365 pScreen
->CopyWindow
= compCopyWindow
;
367 cs
->CreateWindow
= pScreen
->CreateWindow
;
368 pScreen
->CreateWindow
= compCreateWindow
;
370 cs
->DestroyWindow
= pScreen
->DestroyWindow
;
371 pScreen
->DestroyWindow
= compDestroyWindow
;
373 cs
->RealizeWindow
= pScreen
->RealizeWindow
;
374 pScreen
->RealizeWindow
= compRealizeWindow
;
376 cs
->UnrealizeWindow
= pScreen
->UnrealizeWindow
;
377 pScreen
->UnrealizeWindow
= compUnrealizeWindow
;
379 cs
->ClipNotify
= pScreen
->ClipNotify
;
380 pScreen
->ClipNotify
= compClipNotify
;
382 cs
->ConfigNotify
= pScreen
->ConfigNotify
;
383 pScreen
->ConfigNotify
= compConfigNotify
;
385 cs
->MoveWindow
= pScreen
->MoveWindow
;
386 pScreen
->MoveWindow
= compMoveWindow
;
388 cs
->ResizeWindow
= pScreen
->ResizeWindow
;
389 pScreen
->ResizeWindow
= compResizeWindow
;
391 cs
->ChangeBorderWidth
= pScreen
->ChangeBorderWidth
;
392 pScreen
->ChangeBorderWidth
= compChangeBorderWidth
;
394 cs
->ReparentWindow
= pScreen
->ReparentWindow
;
395 pScreen
->ReparentWindow
= compReparentWindow
;
397 cs
->InstallColormap
= pScreen
->InstallColormap
;
398 pScreen
->InstallColormap
= compInstallColormap
;
400 cs
->ChangeWindowAttributes
= pScreen
->ChangeWindowAttributes
;
401 pScreen
->ChangeWindowAttributes
= compChangeWindowAttributes
;
403 cs
->BlockHandler
= NULL
;
405 cs
->CloseScreen
= pScreen
->CloseScreen
;
406 pScreen
->CloseScreen
= compCloseScreen
;
408 cs
->GetImage
= pScreen
->GetImage
;
409 pScreen
->GetImage
= compGetImage
;
411 cs
->SourceValidate
= pScreen
->SourceValidate
;
412 pScreen
->SourceValidate
= compSourceValidate
;
414 dixSetPrivate(&pScreen
->devPrivates
, CompScreenPrivateKey
, cs
);
416 RegisterRealChildHeadProc(CompositeRealChildHead
);