2 * Copyright © 2000 Keith Packard
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Keith Packard not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Keith Packard makes no
11 * representations about the suitability of this software for any purpose. It
12 * is provided "as is" without express or implied warranty.
14 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
23 #ifdef HAVE_DIX_CONFIG_H
24 #include <dix-config.h>
30 #include "scrnintstr.h"
31 #include "windowstr.h"
32 #include "dixfontstr.h"
34 #include "regionstr.h"
39 static DevPrivateKeyRec shadowScrPrivateKeyRec
;
41 #define shadowScrPrivateKey (&shadowScrPrivateKeyRec)
43 #define wrap(priv, real, mem) {\
44 priv->mem = real->mem; \
45 real->mem = shadow##mem; \
48 #define unwrap(priv, real, mem) {\
49 real->mem = priv->mem; \
53 shadowRedisplay(ScreenPtr pScreen
)
58 if (!pBuf
|| !pBuf
->pDamage
|| !pBuf
->update
)
60 pRegion
= DamageRegion(pBuf
->pDamage
);
61 if (RegionNotEmpty(pRegion
)) {
62 (*pBuf
->update
) (pScreen
, pBuf
);
63 DamageEmpty(pBuf
->pDamage
);
68 shadowBlockHandler(pointer data
, OSTimePtr pTimeout
, pointer pRead
)
70 ScreenPtr pScreen
= (ScreenPtr
) data
;
72 shadowRedisplay(pScreen
);
76 shadowWakeupHandler(pointer data
, int i
, pointer LastSelectMask
)
81 shadowGetImage(DrawablePtr pDrawable
, int sx
, int sy
, int w
, int h
,
82 unsigned int format
, unsigned long planeMask
, char *pdstLine
)
84 ScreenPtr pScreen
= pDrawable
->pScreen
;
88 /* Many apps use GetImage to sync with the visable frame buffer */
89 if (pDrawable
->type
== DRAWABLE_WINDOW
)
90 shadowRedisplay(pScreen
);
91 unwrap(pBuf
, pScreen
, GetImage
);
92 pScreen
->GetImage(pDrawable
, sx
, sy
, w
, h
, format
, planeMask
, pdstLine
);
93 wrap(pBuf
, pScreen
, GetImage
);
96 #define BACKWARDS_COMPATIBILITY
99 shadowCloseScreen(ScreenPtr pScreen
)
103 unwrap(pBuf
, pScreen
, GetImage
);
104 unwrap(pBuf
, pScreen
, CloseScreen
);
105 shadowRemove(pScreen
, pBuf
->pPixmap
);
106 DamageDestroy(pBuf
->pDamage
);
107 #ifdef BACKWARDS_COMPATIBILITY
108 RegionUninit(&pBuf
->damage
); /* bc */
111 pScreen
->DestroyPixmap(pBuf
->pPixmap
);
113 return pScreen
->CloseScreen(pScreen
);
116 #ifdef BACKWARDS_COMPATIBILITY
118 shadowReportFunc(DamagePtr pDamage
, RegionPtr pRegion
, void *closure
)
120 ScreenPtr pScreen
= closure
;
121 shadowBufPtr pBuf
= (shadowBufPtr
)
122 dixLookupPrivate(&pScreen
->devPrivates
, shadowScrPrivateKey
);
124 /* Register the damaged region, use DamageReportNone below when we
125 * want to break BC below... */
126 RegionUnion(&pDamage
->damage
, &pDamage
->damage
, pRegion
);
129 * BC hack. In 7.0 and earlier several drivers would inspect the
130 * 'damage' member directly, so we have to keep it existing.
132 RegionCopy(&pBuf
->damage
, pRegion
);
137 shadowSetup(ScreenPtr pScreen
)
141 if (!dixRegisterPrivateKey(&shadowScrPrivateKeyRec
, PRIVATE_SCREEN
, 0))
144 if (!DamageSetup(pScreen
))
147 pBuf
= malloc(sizeof(shadowBufRec
));
150 #ifdef BACKWARDS_COMPATIBILITY
151 pBuf
->pDamage
= DamageCreate((DamageReportFunc
) shadowReportFunc
,
152 (DamageDestroyFunc
) NULL
,
153 DamageReportRawRegion
, TRUE
, pScreen
, pScreen
);
155 pBuf
->pDamage
= DamageCreate((DamageReportFunc
) NULL
,
156 (DamageDestroyFunc
) NULL
,
157 DamageReportNone
, TRUE
, pScreen
, pScreen
);
159 if (!pBuf
->pDamage
) {
164 wrap(pBuf
, pScreen
, CloseScreen
);
165 wrap(pBuf
, pScreen
, GetImage
);
171 #ifdef BACKWARDS_COMPATIBILITY
172 RegionNull(&pBuf
->damage
); /* bc */
175 dixSetPrivate(&pScreen
->devPrivates
, shadowScrPrivateKey
, pBuf
);
180 shadowAdd(ScreenPtr pScreen
, PixmapPtr pPixmap
, ShadowUpdateProc update
,
181 ShadowWindowProc window
, int randr
, void *closure
)
185 if (!RegisterBlockAndWakeupHandlers(shadowBlockHandler
, shadowWakeupHandler
,
190 * Map simple rotation values to bitmasks; fortunately,
191 * these are all unique
195 randr
= SHADOW_ROTATE_0
;
198 randr
= SHADOW_ROTATE_90
;
201 randr
= SHADOW_ROTATE_180
;
204 randr
= SHADOW_ROTATE_270
;
207 pBuf
->update
= update
;
208 pBuf
->window
= window
;
210 pBuf
->closure
= closure
;
211 pBuf
->pPixmap
= pPixmap
;
212 DamageRegister(&pPixmap
->drawable
, pBuf
->pDamage
);
217 shadowRemove(ScreenPtr pScreen
, PixmapPtr pPixmap
)
222 DamageUnregister(pBuf
->pDamage
);
230 RemoveBlockAndWakeupHandlers(shadowBlockHandler
, shadowWakeupHandler
,
235 shadowInit(ScreenPtr pScreen
, ShadowUpdateProc update
, ShadowWindowProc window
)
239 pPixmap
= pScreen
->CreatePixmap(pScreen
, pScreen
->width
, pScreen
->height
,
240 pScreen
->rootDepth
, 0);
244 if (!shadowSetup(pScreen
)) {
245 pScreen
->DestroyPixmap(pPixmap
);
249 shadowAdd(pScreen
, pPixmap
, update
, window
, SHADOW_ROTATE_0
, 0);