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 int shadowScrPrivateIndex
;
42 #define wrap(priv, real, mem) {\
43 priv->mem = real->mem; \
44 real->mem = shadow##mem; \
47 #define unwrap(priv, real, mem) {\
48 real->mem = priv->mem; \
52 shadowRedisplay(ScreenPtr pScreen
)
57 if (!pBuf
|| !pBuf
->pDamage
|| !pBuf
->update
)
59 pRegion
= DamageRegion(pBuf
->pDamage
);
60 if (REGION_NOTEMPTY(pScreen
, pRegion
)) {
61 (*pBuf
->update
)(pScreen
, pBuf
);
62 DamageEmpty(pBuf
->pDamage
);
67 shadowBlockHandler(pointer data
, OSTimePtr pTimeout
, pointer pRead
)
69 ScreenPtr pScreen
= (ScreenPtr
) data
;
71 shadowRedisplay(pScreen
);
75 shadowWakeupHandler(pointer data
, int i
, pointer LastSelectMask
)
80 shadowGetImage(DrawablePtr pDrawable
, int sx
, int sy
, int w
, int h
,
81 unsigned int format
, unsigned long planeMask
, char *pdstLine
)
83 ScreenPtr pScreen
= pDrawable
->pScreen
;
86 /* Many apps use GetImage to sync with the visable frame buffer */
87 if (pDrawable
->type
== DRAWABLE_WINDOW
)
88 shadowRedisplay(pScreen
);
89 unwrap(pBuf
, pScreen
, GetImage
);
90 pScreen
->GetImage(pDrawable
, sx
, sy
, w
, h
, format
, planeMask
, pdstLine
);
91 wrap(pBuf
, pScreen
, GetImage
);
94 #define BACKWARDS_COMPATIBILITY
97 shadowCloseScreen(int i
, ScreenPtr pScreen
)
101 unwrap(pBuf
, pScreen
, GetImage
);
102 unwrap(pBuf
, pScreen
, CloseScreen
);
103 shadowRemove(pScreen
, pBuf
->pPixmap
);
104 DamageDestroy(pBuf
->pDamage
);
105 #ifdef BACKWARDS_COMPATIBILITY
106 REGION_UNINIT(pScreen
, &pBuf
->damage
); /* bc */
109 pScreen
->DestroyPixmap(pBuf
->pPixmap
);
111 return pScreen
->CloseScreen(i
, pScreen
);
114 #ifdef BACKWARDS_COMPATIBILITY
116 shadowReportFunc(DamagePtr pDamage
, RegionPtr pRegion
, void *closure
)
118 ScreenPtr pScreen
= closure
;
119 shadowBufPtr pBuf
= pScreen
->devPrivates
[shadowScrPrivateIndex
].ptr
;
121 /* Register the damaged region, use DamageReportNone below when we
122 * want to break BC below... */
123 REGION_UNION(pScreen
, &pDamage
->damage
, &pDamage
->damage
, pRegion
);
126 * BC hack. In 7.0 and earlier several drivers would inspect the
127 * 'damage' member directly, so we have to keep it existing.
129 REGION_COPY(pScreen
, &pBuf
->damage
, pRegion
);
134 shadowSetup(ScreenPtr pScreen
)
138 if (!DamageSetup(pScreen
))
141 if (shadowGeneration
!= serverGeneration
) {
142 shadowScrPrivateIndex
= AllocateScreenPrivateIndex();
143 if (shadowScrPrivateIndex
== -1)
145 shadowGeneration
= serverGeneration
;
148 pBuf
= (shadowBufPtr
) xalloc(sizeof(shadowBufRec
));
151 #ifdef BACKWARDS_COMPATIBILITY
152 pBuf
->pDamage
= DamageCreate((DamageReportFunc
)shadowReportFunc
,
153 (DamageDestroyFunc
)NULL
,
154 DamageReportRawRegion
,
155 TRUE
, pScreen
, pScreen
);
157 pBuf
->pDamage
= DamageCreate((DamageReportFunc
)NULL
,
158 (DamageDestroyFunc
)NULL
,
160 TRUE
, pScreen
, pScreen
);
162 if (!pBuf
->pDamage
) {
167 wrap(pBuf
, pScreen
, CloseScreen
);
168 wrap(pBuf
, pScreen
, GetImage
);
174 #ifdef BACKWARDS_COMPATIBILITY
175 REGION_NULL(pScreen
, &pBuf
->damage
); /* bc */
178 pScreen
->devPrivates
[shadowScrPrivateIndex
].ptr
= (pointer
) pBuf
;
183 shadowAdd(ScreenPtr pScreen
, PixmapPtr pPixmap
, ShadowUpdateProc update
,
184 ShadowWindowProc window
, int randr
, void *closure
)
188 if (!RegisterBlockAndWakeupHandlers(shadowBlockHandler
, shadowWakeupHandler
,
193 * Map simple rotation values to bitmasks; fortunately,
194 * these are all unique
198 randr
= SHADOW_ROTATE_0
;
201 randr
= SHADOW_ROTATE_90
;
204 randr
= SHADOW_ROTATE_180
;
207 randr
= SHADOW_ROTATE_270
;
210 pBuf
->update
= update
;
211 pBuf
->window
= window
;
214 pBuf
->pPixmap
= pPixmap
;
215 DamageRegister(&pPixmap
->drawable
, pBuf
->pDamage
);
220 shadowRemove(ScreenPtr pScreen
, PixmapPtr pPixmap
)
225 DamageUnregister(&pBuf
->pPixmap
->drawable
, pBuf
->pDamage
);
233 RemoveBlockAndWakeupHandlers(shadowBlockHandler
, shadowWakeupHandler
,
238 shadowInit(ScreenPtr pScreen
, ShadowUpdateProc update
, ShadowWindowProc window
)
242 pPixmap
= pScreen
->CreatePixmap(pScreen
, pScreen
->width
, pScreen
->height
,
247 if (!shadowSetup(pScreen
)) {
248 pScreen
->DestroyPixmap(pPixmap
);
252 shadowAdd(pScreen
, pPixmap
, update
, window
, SHADOW_ROTATE_0
, 0);