123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- /*
- *
- * Copyright © 2000 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
- #ifdef HAVE_DIX_CONFIG_H
- #include <dix-config.h>
- #endif
- #include <stdlib.h>
- #include <X11/X.h>
- #include "scrnintstr.h"
- #include "windowstr.h"
- #include "dixfontstr.h"
- #include "mi.h"
- #include "regionstr.h"
- #include "globals.h"
- #include "gcstruct.h"
- #include "shadow.h"
- int shadowScrPrivateIndex;
- int shadowGeneration;
- #define wrap(priv, real, mem) {\
- priv->mem = real->mem; \
- real->mem = shadow##mem; \
- }
- #define unwrap(priv, real, mem) {\
- real->mem = priv->mem; \
- }
- static void
- shadowRedisplay(ScreenPtr pScreen)
- {
- shadowBuf(pScreen);
- RegionPtr pRegion;
- if (!pBuf || !pBuf->pDamage || !pBuf->update)
- return;
- pRegion = DamageRegion(pBuf->pDamage);
- if (REGION_NOTEMPTY(pRegion)) {
- (*pBuf->update) (pScreen, pBuf);
- DamageEmpty(pBuf->pDamage);
- }
- }
- static void
- shadowBlockHandler(pointer data, OSTimePtr pTimeout, pointer pRead)
- {
- ScreenPtr pScreen = (ScreenPtr) data;
- shadowRedisplay(pScreen);
- }
- static void
- shadowWakeupHandler(pointer data, int i, pointer LastSelectMask)
- {
- }
- static void
- shadowGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
- unsigned int format, unsigned long planeMask, char *pdstLine)
- {
- ScreenPtr pScreen = pDrawable->pScreen;
- shadowBuf(pScreen);
- /* Many apps use GetImage to sync with the visable frame buffer */
- if (pDrawable->type == DRAWABLE_WINDOW)
- shadowRedisplay(pScreen);
- unwrap(pBuf, pScreen, GetImage);
- pScreen->GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
- wrap(pBuf, pScreen, GetImage);
- }
- #define BACKWARDS_COMPATIBILITY
- static Bool
- shadowCloseScreen(int i, ScreenPtr pScreen)
- {
- shadowBuf(pScreen);
- unwrap(pBuf, pScreen, GetImage);
- unwrap(pBuf, pScreen, CloseScreen);
- shadowRemove(pScreen, pBuf->pPixmap);
- DamageDestroy(pBuf->pDamage);
- #ifdef BACKWARDS_COMPATIBILITY
- REGION_UNINIT(&pBuf->damage); /* bc */
- #endif
- if (pBuf->pPixmap)
- pScreen->DestroyPixmap(pBuf->pPixmap);
- free(pBuf);
- return pScreen->CloseScreen(i, pScreen);
- }
- #ifdef BACKWARDS_COMPATIBILITY
- static void
- shadowReportFunc(DamagePtr pDamage, RegionPtr pRegion, void *closure)
- {
- ScreenPtr pScreen = closure;
- shadowBufPtr pBuf = pScreen->devPrivates[shadowScrPrivateIndex].ptr;
- /* Register the damaged region, use DamageReportNone below when we
- * want to break BC below... */
- REGION_UNION(&pDamage->damage, &pDamage->damage, pRegion);
- /*
- * BC hack. In 7.0 and earlier several drivers would inspect the
- * 'damage' member directly, so we have to keep it existing.
- */
- REGION_COPY(&pBuf->damage, pRegion);
- }
- #endif
- Bool
- shadowSetup(ScreenPtr pScreen)
- {
- shadowBufPtr pBuf;
- if (!DamageSetup(pScreen))
- return FALSE;
- if (shadowGeneration != serverGeneration) {
- shadowScrPrivateIndex = AllocateScreenPrivateIndex();
- if (shadowScrPrivateIndex == -1)
- return FALSE;
- shadowGeneration = serverGeneration;
- }
- pBuf = malloc(sizeof(shadowBufRec));
- if (!pBuf)
- return FALSE;
- #ifdef BACKWARDS_COMPATIBILITY
- pBuf->pDamage = DamageCreate((DamageReportFunc) shadowReportFunc,
- (DamageDestroyFunc) NULL,
- DamageReportRawRegion, TRUE, pScreen, pScreen);
- #else
- pBuf->pDamage = DamageCreate((DamageReportFunc) NULL,
- (DamageDestroyFunc) NULL,
- DamageReportNone, TRUE, pScreen, pScreen);
- #endif
- if (!pBuf->pDamage) {
- free(pBuf);
- return FALSE;
- }
- wrap(pBuf, pScreen, CloseScreen);
- wrap(pBuf, pScreen, GetImage);
- pBuf->update = 0;
- pBuf->window = 0;
- pBuf->pPixmap = 0;
- pBuf->closure = 0;
- pBuf->randr = 0;
- #ifdef BACKWARDS_COMPATIBILITY
- REGION_NULL(&pBuf->damage); /* bc */
- #endif
- pScreen->devPrivates[shadowScrPrivateIndex].ptr = (pointer) pBuf;
- return TRUE;
- }
- Bool
- shadowAdd(ScreenPtr pScreen, PixmapPtr pPixmap, ShadowUpdateProc update,
- ShadowWindowProc window, int randr, void *closure)
- {
- shadowBuf(pScreen);
- if (!RegisterBlockAndWakeupHandlers(shadowBlockHandler, shadowWakeupHandler,
- (pointer) pScreen))
- return FALSE;
- /*
- * Map simple rotation values to bitmasks; fortunately,
- * these are all unique
- */
- switch (randr) {
- case 0:
- randr = SHADOW_ROTATE_0;
- break;
- case 90:
- randr = SHADOW_ROTATE_90;
- break;
- case 180:
- randr = SHADOW_ROTATE_180;
- break;
- case 270:
- randr = SHADOW_ROTATE_270;
- break;
- }
- pBuf->update = update;
- pBuf->window = window;
- pBuf->randr = randr;
- pBuf->closure = 0;
- pBuf->pPixmap = pPixmap;
- DamageRegister(&pPixmap->drawable, pBuf->pDamage);
- return TRUE;
- }
- void
- shadowRemove(ScreenPtr pScreen, PixmapPtr pPixmap)
- {
- shadowBuf(pScreen);
- if (pBuf->pPixmap) {
- DamageUnregister(&pBuf->pPixmap->drawable, pBuf->pDamage);
- pBuf->update = 0;
- pBuf->window = 0;
- pBuf->randr = 0;
- pBuf->closure = 0;
- pBuf->pPixmap = 0;
- }
- RemoveBlockAndWakeupHandlers(shadowBlockHandler, shadowWakeupHandler,
- (pointer) pScreen);
- }
- Bool
- shadowInit(ScreenPtr pScreen, ShadowUpdateProc update, ShadowWindowProc window)
- {
- PixmapPtr pPixmap;
- pPixmap = pScreen->CreatePixmap(pScreen, pScreen->width, pScreen->height,
- pScreen->rootDepth);
- if (!pPixmap)
- return FALSE;
- if (!shadowSetup(pScreen)) {
- pScreen->DestroyPixmap(pPixmap);
- return FALSE;
- }
- shadowAdd(pScreen, pPixmap, update, window, SHADOW_ROTATE_0, 0);
- return TRUE;
- }
|