diff options
author | marha <marha@users.sourceforge.net> | 2012-03-23 10:05:55 +0100 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2012-03-23 10:05:55 +0100 |
commit | 0f834b91a4768673833ab4917e87d86c237bb1a6 (patch) | |
tree | 363489504ed4b2d360259b8de4c9e392918e5d02 /xorg-server/miext | |
parent | fc72edebf875378459368c5383d9023730cbca54 (diff) | |
download | vcxsrv-0f834b91a4768673833ab4917e87d86c237bb1a6.tar.gz vcxsrv-0f834b91a4768673833ab4917e87d86c237bb1a6.tar.bz2 vcxsrv-0f834b91a4768673833ab4917e87d86c237bb1a6.zip |
libX11 xserver fontconfig mesa pixman xkbcomp xkeyboard-config git update
23 Mar 2012
Diffstat (limited to 'xorg-server/miext')
23 files changed, 7662 insertions, 7829 deletions
diff --git a/xorg-server/miext/cw/cw.c b/xorg-server/miext/cw/cw.c index db06209d9..87ced2f6a 100644 --- a/xorg-server/miext/cw/cw.c +++ b/xorg-server/miext/cw/cw.c @@ -1,527 +1,524 @@ -/*
- * Copyright © 2004 Eric Anholt
- *
- * 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 Eric Anholt not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Eric Anholt makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL ERIC ANHOLT 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 <string.h>
-
-#include "gcstruct.h"
-#include "windowstr.h"
-#include "cw.h"
-
-#define CW_DEBUG 1
-
-#if CW_DEBUG
-#define CW_ASSERT(x) do { \
- if (!(x)) { \
- ErrorF("composite wrapper: assertion failed at %s:%d\n", __FUNC__, \
- __LINE__); \
- } \
-} while (0)
-#else
-#define CW_ASSERT(x) do {} while (0)
-#endif
-
-DevPrivateKeyRec cwGCKeyRec;
-DevPrivateKeyRec cwScreenKeyRec;
-DevPrivateKeyRec cwWindowKeyRec;
-DevPrivateKeyRec cwPictureKeyRec;
-
-extern GCOps cwGCOps;
-
-static Bool
-cwCloseScreen (int i, ScreenPtr pScreen);
-
-static void
-cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable);
-static void
-cwChangeGC(GCPtr pGC, unsigned long mask);
-static void
-cwCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
-static void
-cwDestroyGC(GCPtr pGC);
-static void
-cwChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects);
-static void
-cwCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
-static void
-cwDestroyClip(GCPtr pGC);
-
-GCFuncs cwGCFuncs = {
- cwValidateGC,
- cwChangeGC,
- cwCopyGC,
- cwDestroyGC,
- cwChangeClip,
- cwDestroyClip,
- cwCopyClip,
-};
-
-/* Find the real drawable to draw to, and provide offsets that will translate
- * window coordinates to backing pixmap coordinates.
- */
-DrawablePtr
-cwGetBackingDrawable(DrawablePtr pDrawable, int *x_off, int *y_off)
-{
- PixmapPtr pPixmap;
-
- if (pDrawable->type == DRAWABLE_WINDOW &&
- (pPixmap = getCwPixmap ((WindowPtr) pDrawable)))
- {
- *x_off = pDrawable->x - pPixmap->screen_x;
- *y_off = pDrawable->y - pPixmap->screen_y;
- return &pPixmap->drawable;
- } else {
- *x_off = *y_off = 0;
- return pDrawable;
- }
-}
-
-#define FUNC_PROLOGUE(pGC, pPriv) do { \
- (pGC)->funcs = (pPriv)->wrapFuncs; \
- (pGC)->ops = (pPriv)->wrapOps; \
-} while (0)
-
-#define FUNC_EPILOGUE(pGC, pPriv) do { \
- (pPriv)->wrapFuncs = (pGC)->funcs; \
- (pPriv)->wrapOps = (pGC)->ops; \
- (pGC)->funcs = &cwGCFuncs; \
- (pGC)->ops = &cwGCOps; \
-} while (0)
-
-
-static Bool
-cwCreateBackingGC(GCPtr pGC, DrawablePtr pDrawable)
-{
- cwGCRec *pPriv = getCwGC(pGC);
- int status, x_off, y_off;
- XID noexpose = xFalse;
- DrawablePtr pBackingDrawable;
-
- pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off);
- pPriv->pBackingGC = CreateGC(pBackingDrawable, GCGraphicsExposures,
- &noexpose, &status, (XID)0, serverClient);
- if (status != Success)
- return FALSE;
-
- pPriv->serialNumber = 0;
- pPriv->stateChanges = GCAllBits;
-
- return TRUE;
-}
-
-static void
-cwDestroyBackingGC(GCPtr pGC)
-{
- cwGCPtr pPriv;
-
- pPriv = (cwGCPtr) getCwGC (pGC);
-
- if (pPriv->pBackingGC) {
- FreeGC(pPriv->pBackingGC, (XID)0);
- pPriv->pBackingGC = NULL;
- }
-}
-
-static void
-cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable)
-{
- GCPtr pBackingGC;
- cwGCPtr pPriv;
- DrawablePtr pBackingDrawable;
- int x_off, y_off;
-
- pPriv = (cwGCPtr) getCwGC (pGC);
-
- FUNC_PROLOGUE(pGC, pPriv);
-
- /*
- * Must call ValidateGC to ensure pGC->pCompositeClip is valid
- */
- (*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable);
-
- if (!cwDrawableIsRedirWindow(pDrawable)) {
- cwDestroyBackingGC(pGC);
- FUNC_EPILOGUE(pGC, pPriv);
- return;
- } else {
- if (!pPriv->pBackingGC && !cwCreateBackingGC(pGC, pDrawable)) {
- FUNC_EPILOGUE(pGC, pPriv);
- return;
- }
- }
-
- pBackingGC = pPriv->pBackingGC;
- pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off);
-
- pPriv->stateChanges |= stateChanges;
-
- /*
- * Copy the composite clip into the backing GC if either
- * the drawable clip list has changed or the client has changed
- * the client clip data
- */
- if (pDrawable->serialNumber != pPriv->serialNumber ||
- (pPriv->stateChanges & (GCClipXOrigin|GCClipYOrigin|GCClipMask)))
- {
- ChangeGCVal vals[2];
- RegionPtr pCompositeClip;
-
- pCompositeClip = RegionCreate(NULL, 0);
- RegionCopy(pCompositeClip, pGC->pCompositeClip);
-
- /* Either the drawable has changed, or the clip list in the drawable has
- * changed. Copy the new clip list over and set the new translated
- * offset for it.
- */
-
- (*pBackingGC->funcs->ChangeClip) (pBackingGC, CT_REGION,
- (pointer) pCompositeClip, 0);
-
- vals[0].val = x_off - pDrawable->x;
- vals[1].val = y_off - pDrawable->y;
- ChangeGC(NullClient, pBackingGC,
- (GCClipXOrigin | GCClipYOrigin), vals);
-
- pPriv->serialNumber = pDrawable->serialNumber;
- /*
- * Mask off any client clip changes to make sure
- * the clip list set above remains in effect
- */
- pPriv->stateChanges &= ~(GCClipXOrigin|GCClipYOrigin|GCClipMask);
- }
-
- if (pPriv->stateChanges) {
- CopyGC(pGC, pBackingGC, pPriv->stateChanges);
- pPriv->stateChanges = 0;
- }
-
- if ((pGC->patOrg.x + x_off) != pBackingGC->patOrg.x ||
- (pGC->patOrg.y + y_off) != pBackingGC->patOrg.y)
- {
- ChangeGCVal vals[2];
- vals[0].val = pGC->patOrg.x + x_off;
- vals[1].val = pGC->patOrg.y + y_off;
- ChangeGC(NullClient, pBackingGC,
- (GCTileStipXOrigin | GCTileStipYOrigin), vals);
- }
-
- ValidateGC(pBackingDrawable, pBackingGC);
-
- FUNC_EPILOGUE(pGC, pPriv);
-}
-
-static void
-cwChangeGC(GCPtr pGC, unsigned long mask)
-{
- cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pGC->devPrivates, cwGCKey);
-
- FUNC_PROLOGUE(pGC, pPriv);
-
- (*pGC->funcs->ChangeGC) (pGC, mask);
-
- FUNC_EPILOGUE(pGC, pPriv);
-}
-
-static void
-cwCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
-{
- cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pGCDst->devPrivates, cwGCKey);
-
- FUNC_PROLOGUE(pGCDst, pPriv);
-
- (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
-
- FUNC_EPILOGUE(pGCDst, pPriv);
-}
-
-static void
-cwDestroyGC(GCPtr pGC)
-{
- cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pGC->devPrivates, cwGCKey);
-
- FUNC_PROLOGUE(pGC, pPriv);
-
- cwDestroyBackingGC(pGC);
-
- (*pGC->funcs->DestroyGC) (pGC);
-
- /* leave it unwrapped */
-}
-
-static void
-cwChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
-{
- cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pGC->devPrivates, cwGCKey);
-
- FUNC_PROLOGUE(pGC, pPriv);
-
- (*pGC->funcs->ChangeClip)(pGC, type, pvalue, nrects);
-
- FUNC_EPILOGUE(pGC, pPriv);
-}
-
-static void
-cwCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
-{
- cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pgcDst->devPrivates, cwGCKey);
-
- FUNC_PROLOGUE(pgcDst, pPriv);
-
- (*pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
-
- FUNC_EPILOGUE(pgcDst, pPriv);
-}
-
-static void
-cwDestroyClip(GCPtr pGC)
-{
- cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pGC->devPrivates, cwGCKey);
-
- FUNC_PROLOGUE(pGC, pPriv);
-
- (*pGC->funcs->DestroyClip)(pGC);
-
- FUNC_EPILOGUE(pGC, pPriv);
-}
-
-/*
- * Screen wrappers.
- */
-
-#define SCREEN_PROLOGUE(pScreen, field) \
- ((pScreen)->field = getCwScreen(pScreen)->field)
-
-#define SCREEN_EPILOGUE(pScreen, field, wrapper) do { \
- getCwScreen(pScreen)->field = (pScreen)->field; \
- (pScreen)->field = (wrapper); \
-} while (0)
-
-static Bool
-cwCreateGC(GCPtr pGC)
-{
- cwGCPtr pPriv = getCwGC(pGC);
- ScreenPtr pScreen = pGC->pScreen;
- Bool ret;
-
- SCREEN_PROLOGUE(pScreen, CreateGC);
-
- if ( (ret = (*pScreen->CreateGC)(pGC)) )
- FUNC_EPILOGUE(pGC, pPriv);
-
- SCREEN_EPILOGUE(pScreen, CreateGC, cwCreateGC);
-
- return ret;
-}
-
-static void
-cwGetImage(DrawablePtr pSrc, int x, int y, int w, int h, unsigned int format,
- unsigned long planemask, char *pdstLine)
-{
- ScreenPtr pScreen = pSrc->pScreen;
- DrawablePtr pBackingDrawable;
- int src_off_x, src_off_y;
-
- SCREEN_PROLOGUE(pScreen, GetImage);
-
- pBackingDrawable = cwGetBackingDrawable(pSrc, &src_off_x, &src_off_y);
-
- CW_OFFSET_XY_SRC(x, y);
-
- (*pScreen->GetImage)(pBackingDrawable, x, y, w, h, format, planemask,
- pdstLine);
-
- SCREEN_EPILOGUE(pScreen, GetImage, cwGetImage);
-}
-
-static void
-cwGetSpans(DrawablePtr pSrc, int wMax, DDXPointPtr ppt, int *pwidth,
- int nspans, char *pdstStart)
-{
- ScreenPtr pScreen = pSrc->pScreen;
- DrawablePtr pBackingDrawable;
- int i;
- int src_off_x, src_off_y;
-
- SCREEN_PROLOGUE(pScreen, GetSpans);
-
- pBackingDrawable = cwGetBackingDrawable(pSrc, &src_off_x, &src_off_y);
-
- for (i = 0; i < nspans; i++)
- CW_OFFSET_XY_SRC(ppt[i].x, ppt[i].y);
-
- (*pScreen->GetSpans)(pBackingDrawable, wMax, ppt, pwidth, nspans,
- pdstStart);
-
- SCREEN_EPILOGUE(pScreen, GetSpans, cwGetSpans);
-}
-
-
-static void
-cwCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
-
- SCREEN_PROLOGUE(pScreen, CopyWindow);
-
- if (!cwDrawableIsRedirWindow((DrawablePtr)pWin)) {
- (*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc);
- } else {
- GCPtr pGC;
- BoxPtr pExtents;
- int x_off, y_off;
- int dx, dy;
- PixmapPtr pBackingPixmap;
- RegionPtr pClip;
- int src_x, src_y, dst_x, dst_y, w, h;
-
- dx = ptOldOrg.x - pWin->drawable.x;
- dy = ptOldOrg.y - pWin->drawable.y;
-
- pExtents = RegionExtents(prgnSrc);
-
- pBackingPixmap = (PixmapPtr) cwGetBackingDrawable((DrawablePtr)pWin,
- &x_off, &y_off);
-
- src_x = pExtents->x1 - pBackingPixmap->screen_x;
- src_y = pExtents->y1 - pBackingPixmap->screen_y;
- w = pExtents->x2 - pExtents->x1;
- h = pExtents->y2 - pExtents->y1;
- dst_x = src_x - dx;
- dst_y = src_y - dy;
-
- /* Translate region (as required by API) */
- RegionTranslate(prgnSrc, -dx, -dy);
-
- pGC = GetScratchGC(pBackingPixmap->drawable.depth, pScreen);
- /*
- * Copy region to GC as clip, aligning as dest clip
- */
- pClip = RegionCreate(NULL, 0);
- RegionIntersect(pClip, &pWin->borderClip, prgnSrc);
- RegionTranslate(pClip,
- -pBackingPixmap->screen_x,
- -pBackingPixmap->screen_y);
-
- (*pGC->funcs->ChangeClip) (pGC, CT_REGION, pClip, 0);
-
- ValidateGC(&pBackingPixmap->drawable, pGC);
-
- (*pGC->ops->CopyArea) (&pBackingPixmap->drawable,
- &pBackingPixmap->drawable, pGC,
- src_x, src_y, w, h, dst_x, dst_y);
-
- (*pGC->funcs->DestroyClip) (pGC);
-
- FreeScratchGC(pGC);
- }
-
- SCREEN_EPILOGUE(pScreen, CopyWindow, cwCopyWindow);
-}
-
-static PixmapPtr
-cwGetWindowPixmap (WindowPtr pWin)
-{
- PixmapPtr pPixmap = getCwPixmap (pWin);
-
- if (!pPixmap)
- {
- ScreenPtr pScreen = pWin->drawable.pScreen;
- SCREEN_PROLOGUE(pScreen, GetWindowPixmap);
- if (pScreen->GetWindowPixmap)
- pPixmap = (*pScreen->GetWindowPixmap) (pWin);
- SCREEN_EPILOGUE(pScreen, GetWindowPixmap, cwGetWindowPixmap);
- }
- return pPixmap;
-}
-
-static void
-cwSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
-
- if (pPixmap == (*pScreen->GetScreenPixmap) (pScreen))
- pPixmap = NULL;
- setCwPixmap (pWindow, pPixmap);
-}
-
-/* Screen initialization/teardown */
-void
-miInitializeCompositeWrapper(ScreenPtr pScreen)
-{
- cwScreenPtr pScreenPriv;
- Bool has_render = GetPictureScreenIfSet(pScreen) != NULL;
-
- if (!dixRegisterPrivateKey(&cwScreenKeyRec, PRIVATE_SCREEN, 0))
- return;
-
- if (!dixRegisterPrivateKey(&cwGCKeyRec, PRIVATE_GC, sizeof(cwGCRec)))
- return;
-
- if (!dixRegisterPrivateKey(&cwWindowKeyRec, PRIVATE_WINDOW, 0))
- return;
-
- if (!dixRegisterPrivateKey(&cwPictureKeyRec, PRIVATE_PICTURE, 0))
- return;
-
- pScreenPriv = malloc(sizeof(cwScreenRec));
- if (!pScreenPriv)
- return;
-
- dixSetPrivate(&pScreen->devPrivates, cwScreenKey, pScreenPriv);
-
- SCREEN_EPILOGUE(pScreen, CloseScreen, cwCloseScreen);
- SCREEN_EPILOGUE(pScreen, GetImage, cwGetImage);
- SCREEN_EPILOGUE(pScreen, GetSpans, cwGetSpans);
- SCREEN_EPILOGUE(pScreen, CreateGC, cwCreateGC);
- SCREEN_EPILOGUE(pScreen, CopyWindow, cwCopyWindow);
-
- SCREEN_EPILOGUE(pScreen, SetWindowPixmap, cwSetWindowPixmap);
- SCREEN_EPILOGUE(pScreen, GetWindowPixmap, cwGetWindowPixmap);
-
- if (has_render)
- cwInitializeRender(pScreen);
-}
-
-static Bool
-cwCloseScreen (int i, ScreenPtr pScreen)
-{
- cwScreenPtr pScreenPriv;
- PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
-
- pScreenPriv = (cwScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
- cwScreenKey);
- pScreen->CloseScreen = pScreenPriv->CloseScreen;
- pScreen->GetImage = pScreenPriv->GetImage;
- pScreen->GetSpans = pScreenPriv->GetSpans;
- pScreen->CreateGC = pScreenPriv->CreateGC;
- pScreen->CopyWindow = pScreenPriv->CopyWindow;
-
- if (ps)
- cwFiniRender(pScreen);
-
- free((pointer)pScreenPriv);
-
- return (*pScreen->CloseScreen)(i, pScreen);
-}
+/* + * Copyright © 2004 Eric Anholt + * + * 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 Eric Anholt not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Eric Anholt makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ERIC ANHOLT 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 <string.h> + +#include "gcstruct.h" +#include "windowstr.h" +#include "cw.h" + +#define CW_DEBUG 1 + +#if CW_DEBUG +#define CW_ASSERT(x) do { \ + if (!(x)) { \ + ErrorF("composite wrapper: assertion failed at %s:%d\n", __FUNC__, \ + __LINE__); \ + } \ +} while (0) +#else +#define CW_ASSERT(x) do {} while (0) +#endif + +DevPrivateKeyRec cwGCKeyRec; +DevPrivateKeyRec cwScreenKeyRec; +DevPrivateKeyRec cwWindowKeyRec; +DevPrivateKeyRec cwPictureKeyRec; + +extern GCOps cwGCOps; + +static Bool + cwCloseScreen(int i, ScreenPtr pScreen); + +static void + cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable); +static void + cwChangeGC(GCPtr pGC, unsigned long mask); +static void + cwCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst); +static void + cwDestroyGC(GCPtr pGC); +static void + cwChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects); +static void + cwCopyClip(GCPtr pgcDst, GCPtr pgcSrc); +static void + cwDestroyClip(GCPtr pGC); + +GCFuncs cwGCFuncs = { + cwValidateGC, + cwChangeGC, + cwCopyGC, + cwDestroyGC, + cwChangeClip, + cwDestroyClip, + cwCopyClip, +}; + +/* Find the real drawable to draw to, and provide offsets that will translate + * window coordinates to backing pixmap coordinates. + */ +DrawablePtr +cwGetBackingDrawable(DrawablePtr pDrawable, int *x_off, int *y_off) +{ + PixmapPtr pPixmap; + + if (pDrawable->type == DRAWABLE_WINDOW && + (pPixmap = getCwPixmap((WindowPtr) pDrawable))) { + *x_off = pDrawable->x - pPixmap->screen_x; + *y_off = pDrawable->y - pPixmap->screen_y; + return &pPixmap->drawable; + } + else { + *x_off = *y_off = 0; + return pDrawable; + } +} + +#define FUNC_PROLOGUE(pGC, pPriv) do { \ + (pGC)->funcs = (pPriv)->wrapFuncs; \ + (pGC)->ops = (pPriv)->wrapOps; \ +} while (0) + +#define FUNC_EPILOGUE(pGC, pPriv) do { \ + (pPriv)->wrapFuncs = (pGC)->funcs; \ + (pPriv)->wrapOps = (pGC)->ops; \ + (pGC)->funcs = &cwGCFuncs; \ + (pGC)->ops = &cwGCOps; \ +} while (0) + +static Bool +cwCreateBackingGC(GCPtr pGC, DrawablePtr pDrawable) +{ + cwGCRec *pPriv = getCwGC(pGC); + int status, x_off, y_off; + XID noexpose = xFalse; + DrawablePtr pBackingDrawable; + + pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off); + pPriv->pBackingGC = CreateGC(pBackingDrawable, GCGraphicsExposures, + &noexpose, &status, (XID) 0, serverClient); + if (status != Success) + return FALSE; + + pPriv->serialNumber = 0; + pPriv->stateChanges = GCAllBits; + + return TRUE; +} + +static void +cwDestroyBackingGC(GCPtr pGC) +{ + cwGCPtr pPriv; + + pPriv = (cwGCPtr) getCwGC(pGC); + + if (pPriv->pBackingGC) { + FreeGC(pPriv->pBackingGC, (XID) 0); + pPriv->pBackingGC = NULL; + } +} + +static void +cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable) +{ + GCPtr pBackingGC; + cwGCPtr pPriv; + DrawablePtr pBackingDrawable; + int x_off, y_off; + + pPriv = (cwGCPtr) getCwGC(pGC); + + FUNC_PROLOGUE(pGC, pPriv); + + /* + * Must call ValidateGC to ensure pGC->pCompositeClip is valid + */ + (*pGC->funcs->ValidateGC) (pGC, stateChanges, pDrawable); + + if (!cwDrawableIsRedirWindow(pDrawable)) { + cwDestroyBackingGC(pGC); + FUNC_EPILOGUE(pGC, pPriv); + return; + } + else { + if (!pPriv->pBackingGC && !cwCreateBackingGC(pGC, pDrawable)) { + FUNC_EPILOGUE(pGC, pPriv); + return; + } + } + + pBackingGC = pPriv->pBackingGC; + pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off); + + pPriv->stateChanges |= stateChanges; + + /* + * Copy the composite clip into the backing GC if either + * the drawable clip list has changed or the client has changed + * the client clip data + */ + if (pDrawable->serialNumber != pPriv->serialNumber || + (pPriv->stateChanges & (GCClipXOrigin | GCClipYOrigin | GCClipMask))) { + ChangeGCVal vals[2]; + RegionPtr pCompositeClip; + + pCompositeClip = RegionCreate(NULL, 0); + RegionCopy(pCompositeClip, pGC->pCompositeClip); + + /* Either the drawable has changed, or the clip list in the drawable has + * changed. Copy the new clip list over and set the new translated + * offset for it. + */ + + (*pBackingGC->funcs->ChangeClip) (pBackingGC, CT_REGION, + (pointer) pCompositeClip, 0); + + vals[0].val = x_off - pDrawable->x; + vals[1].val = y_off - pDrawable->y; + ChangeGC(NullClient, pBackingGC, (GCClipXOrigin | GCClipYOrigin), vals); + + pPriv->serialNumber = pDrawable->serialNumber; + /* + * Mask off any client clip changes to make sure + * the clip list set above remains in effect + */ + pPriv->stateChanges &= ~(GCClipXOrigin | GCClipYOrigin | GCClipMask); + } + + if (pPriv->stateChanges) { + CopyGC(pGC, pBackingGC, pPriv->stateChanges); + pPriv->stateChanges = 0; + } + + if ((pGC->patOrg.x + x_off) != pBackingGC->patOrg.x || + (pGC->patOrg.y + y_off) != pBackingGC->patOrg.y) { + ChangeGCVal vals[2]; + + vals[0].val = pGC->patOrg.x + x_off; + vals[1].val = pGC->patOrg.y + y_off; + ChangeGC(NullClient, pBackingGC, + (GCTileStipXOrigin | GCTileStipYOrigin), vals); + } + + ValidateGC(pBackingDrawable, pBackingGC); + + FUNC_EPILOGUE(pGC, pPriv); +} + +static void +cwChangeGC(GCPtr pGC, unsigned long mask) +{ + cwGCPtr pPriv = (cwGCPtr) dixLookupPrivate(&pGC->devPrivates, cwGCKey); + + FUNC_PROLOGUE(pGC, pPriv); + + (*pGC->funcs->ChangeGC) (pGC, mask); + + FUNC_EPILOGUE(pGC, pPriv); +} + +static void +cwCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst) +{ + cwGCPtr pPriv = (cwGCPtr) dixLookupPrivate(&pGCDst->devPrivates, cwGCKey); + + FUNC_PROLOGUE(pGCDst, pPriv); + + (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst); + + FUNC_EPILOGUE(pGCDst, pPriv); +} + +static void +cwDestroyGC(GCPtr pGC) +{ + cwGCPtr pPriv = (cwGCPtr) dixLookupPrivate(&pGC->devPrivates, cwGCKey); + + FUNC_PROLOGUE(pGC, pPriv); + + cwDestroyBackingGC(pGC); + + (*pGC->funcs->DestroyGC) (pGC); + + /* leave it unwrapped */ +} + +static void +cwChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects) +{ + cwGCPtr pPriv = (cwGCPtr) dixLookupPrivate(&pGC->devPrivates, cwGCKey); + + FUNC_PROLOGUE(pGC, pPriv); + + (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects); + + FUNC_EPILOGUE(pGC, pPriv); +} + +static void +cwCopyClip(GCPtr pgcDst, GCPtr pgcSrc) +{ + cwGCPtr pPriv = (cwGCPtr) dixLookupPrivate(&pgcDst->devPrivates, cwGCKey); + + FUNC_PROLOGUE(pgcDst, pPriv); + + (*pgcDst->funcs->CopyClip) (pgcDst, pgcSrc); + + FUNC_EPILOGUE(pgcDst, pPriv); +} + +static void +cwDestroyClip(GCPtr pGC) +{ + cwGCPtr pPriv = (cwGCPtr) dixLookupPrivate(&pGC->devPrivates, cwGCKey); + + FUNC_PROLOGUE(pGC, pPriv); + + (*pGC->funcs->DestroyClip) (pGC); + + FUNC_EPILOGUE(pGC, pPriv); +} + +/* + * Screen wrappers. + */ + +#define SCREEN_PROLOGUE(pScreen, field) \ + ((pScreen)->field = getCwScreen(pScreen)->field) + +#define SCREEN_EPILOGUE(pScreen, field, wrapper) do { \ + getCwScreen(pScreen)->field = (pScreen)->field; \ + (pScreen)->field = (wrapper); \ +} while (0) + +static Bool +cwCreateGC(GCPtr pGC) +{ + cwGCPtr pPriv = getCwGC(pGC); + ScreenPtr pScreen = pGC->pScreen; + Bool ret; + + SCREEN_PROLOGUE(pScreen, CreateGC); + + if ((ret = (*pScreen->CreateGC) (pGC))) + FUNC_EPILOGUE(pGC, pPriv); + + SCREEN_EPILOGUE(pScreen, CreateGC, cwCreateGC); + + return ret; +} + +static void +cwGetImage(DrawablePtr pSrc, int x, int y, int w, int h, unsigned int format, + unsigned long planemask, char *pdstLine) +{ + ScreenPtr pScreen = pSrc->pScreen; + DrawablePtr pBackingDrawable; + int src_off_x, src_off_y; + + SCREEN_PROLOGUE(pScreen, GetImage); + + pBackingDrawable = cwGetBackingDrawable(pSrc, &src_off_x, &src_off_y); + + CW_OFFSET_XY_SRC(x, y); + + (*pScreen->GetImage) (pBackingDrawable, x, y, w, h, format, planemask, + pdstLine); + + SCREEN_EPILOGUE(pScreen, GetImage, cwGetImage); +} + +static void +cwGetSpans(DrawablePtr pSrc, int wMax, DDXPointPtr ppt, int *pwidth, + int nspans, char *pdstStart) +{ + ScreenPtr pScreen = pSrc->pScreen; + DrawablePtr pBackingDrawable; + int i; + int src_off_x, src_off_y; + + SCREEN_PROLOGUE(pScreen, GetSpans); + + pBackingDrawable = cwGetBackingDrawable(pSrc, &src_off_x, &src_off_y); + + for (i = 0; i < nspans; i++) + CW_OFFSET_XY_SRC(ppt[i].x, ppt[i].y); + + (*pScreen->GetSpans) (pBackingDrawable, wMax, ppt, pwidth, nspans, + pdstStart); + + SCREEN_EPILOGUE(pScreen, GetSpans, cwGetSpans); +} + +static void +cwCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + + SCREEN_PROLOGUE(pScreen, CopyWindow); + + if (!cwDrawableIsRedirWindow((DrawablePtr) pWin)) { + (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc); + } + else { + GCPtr pGC; + BoxPtr pExtents; + int x_off, y_off; + int dx, dy; + PixmapPtr pBackingPixmap; + RegionPtr pClip; + int src_x, src_y, dst_x, dst_y, w, h; + + dx = ptOldOrg.x - pWin->drawable.x; + dy = ptOldOrg.y - pWin->drawable.y; + + pExtents = RegionExtents(prgnSrc); + + pBackingPixmap = (PixmapPtr) cwGetBackingDrawable((DrawablePtr) pWin, + &x_off, &y_off); + + src_x = pExtents->x1 - pBackingPixmap->screen_x; + src_y = pExtents->y1 - pBackingPixmap->screen_y; + w = pExtents->x2 - pExtents->x1; + h = pExtents->y2 - pExtents->y1; + dst_x = src_x - dx; + dst_y = src_y - dy; + + /* Translate region (as required by API) */ + RegionTranslate(prgnSrc, -dx, -dy); + + pGC = GetScratchGC(pBackingPixmap->drawable.depth, pScreen); + /* + * Copy region to GC as clip, aligning as dest clip + */ + pClip = RegionCreate(NULL, 0); + RegionIntersect(pClip, &pWin->borderClip, prgnSrc); + RegionTranslate(pClip, + -pBackingPixmap->screen_x, -pBackingPixmap->screen_y); + + (*pGC->funcs->ChangeClip) (pGC, CT_REGION, pClip, 0); + + ValidateGC(&pBackingPixmap->drawable, pGC); + + (*pGC->ops->CopyArea) (&pBackingPixmap->drawable, + &pBackingPixmap->drawable, pGC, + src_x, src_y, w, h, dst_x, dst_y); + + (*pGC->funcs->DestroyClip) (pGC); + + FreeScratchGC(pGC); + } + + SCREEN_EPILOGUE(pScreen, CopyWindow, cwCopyWindow); +} + +static PixmapPtr +cwGetWindowPixmap(WindowPtr pWin) +{ + PixmapPtr pPixmap = getCwPixmap(pWin); + + if (!pPixmap) { + ScreenPtr pScreen = pWin->drawable.pScreen; + + SCREEN_PROLOGUE(pScreen, GetWindowPixmap); + if (pScreen->GetWindowPixmap) + pPixmap = (*pScreen->GetWindowPixmap) (pWin); + SCREEN_EPILOGUE(pScreen, GetWindowPixmap, cwGetWindowPixmap); + } + return pPixmap; +} + +static void +cwSetWindowPixmap(WindowPtr pWindow, PixmapPtr pPixmap) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + + if (pPixmap == (*pScreen->GetScreenPixmap) (pScreen)) + pPixmap = NULL; + setCwPixmap(pWindow, pPixmap); +} + +/* Screen initialization/teardown */ +void +miInitializeCompositeWrapper(ScreenPtr pScreen) +{ + cwScreenPtr pScreenPriv; + Bool has_render = GetPictureScreenIfSet(pScreen) != NULL; + + if (!dixRegisterPrivateKey(&cwScreenKeyRec, PRIVATE_SCREEN, 0)) + return; + + if (!dixRegisterPrivateKey(&cwGCKeyRec, PRIVATE_GC, sizeof(cwGCRec))) + return; + + if (!dixRegisterPrivateKey(&cwWindowKeyRec, PRIVATE_WINDOW, 0)) + return; + + if (!dixRegisterPrivateKey(&cwPictureKeyRec, PRIVATE_PICTURE, 0)) + return; + + pScreenPriv = malloc(sizeof(cwScreenRec)); + if (!pScreenPriv) + return; + + dixSetPrivate(&pScreen->devPrivates, cwScreenKey, pScreenPriv); + + SCREEN_EPILOGUE(pScreen, CloseScreen, cwCloseScreen); + SCREEN_EPILOGUE(pScreen, GetImage, cwGetImage); + SCREEN_EPILOGUE(pScreen, GetSpans, cwGetSpans); + SCREEN_EPILOGUE(pScreen, CreateGC, cwCreateGC); + SCREEN_EPILOGUE(pScreen, CopyWindow, cwCopyWindow); + + SCREEN_EPILOGUE(pScreen, SetWindowPixmap, cwSetWindowPixmap); + SCREEN_EPILOGUE(pScreen, GetWindowPixmap, cwGetWindowPixmap); + + if (has_render) + cwInitializeRender(pScreen); +} + +static Bool +cwCloseScreen(int i, ScreenPtr pScreen) +{ + cwScreenPtr pScreenPriv; + PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); + + pScreenPriv = (cwScreenPtr) dixLookupPrivate(&pScreen->devPrivates, + cwScreenKey); + pScreen->CloseScreen = pScreenPriv->CloseScreen; + pScreen->GetImage = pScreenPriv->GetImage; + pScreen->GetSpans = pScreenPriv->GetSpans; + pScreen->CreateGC = pScreenPriv->CreateGC; + pScreen->CopyWindow = pScreenPriv->CopyWindow; + + if (ps) + cwFiniRender(pScreen); + + free((pointer) pScreenPriv); + + return (*pScreen->CloseScreen) (i, pScreen); +} diff --git a/xorg-server/miext/cw/cw_ops.c b/xorg-server/miext/cw/cw_ops.c index 9ae56cb6c..ccc558074 100644 --- a/xorg-server/miext/cw/cw_ops.c +++ b/xorg-server/miext/cw/cw_ops.c @@ -65,76 +65,75 @@ extern GCFuncs cwGCFuncs; */ static void cwFillSpans(DrawablePtr pDst, GCPtr pGC, int nInit, - DDXPointPtr pptInit, int *pwidthInit, int fSorted); + DDXPointPtr pptInit, int *pwidthInit, int fSorted); static void cwSetSpans(DrawablePtr pDst, GCPtr pGC, char *psrc, - DDXPointPtr ppt, int *pwidth, int nspans, int fSorted); + DDXPointPtr ppt, int *pwidth, int nspans, int fSorted); static void cwPutImage(DrawablePtr pDst, GCPtr pGC, int depth, - int x, int y, int w, int h, int leftPad, int format, - char *pBits); + int x, int y, int w, int h, int leftPad, int format, + char *pBits); static RegionPtr cwCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - int srcx, int srcy, int w, int h, - int dstx, int dsty); + int srcx, int srcy, int w, int h, + int dstx, int dsty); static RegionPtr cwCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - int srcx, int srcy, int w, int h, - int dstx, int dsty, unsigned long plane); + int srcx, int srcy, int w, int h, + int dstx, int dsty, unsigned long plane); static void cwPolyPoint(DrawablePtr pDst, GCPtr pGC, int mode, int npt, - xPoint *pptInit); + xPoint * pptInit); static void cwPolylines(DrawablePtr pDst, GCPtr pGC, int mode, int npt, - DDXPointPtr pptInit); + DDXPointPtr pptInit); static void cwPolySegment(DrawablePtr pDst, GCPtr pGC, int nseg, - xSegment *pSegs); + xSegment * pSegs); static void cwPolyRectangle(DrawablePtr pDst, GCPtr pGC, - int nrects, xRectangle *pRects); -static void cwPolyArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *parcs); + int nrects, xRectangle *pRects); +static void cwPolyArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc * parcs); static void cwFillPolygon(DrawablePtr pDst, GCPtr pGC, int shape, int mode, - int count, DDXPointPtr pPts); + int count, DDXPointPtr pPts); static void cwPolyFillRect(DrawablePtr pDst, GCPtr pGC, - int nrectFill, xRectangle *prectInit); -static void cwPolyFillArc(DrawablePtr pDst, GCPtr pGC, - int narcs, xArc *parcs); + int nrectFill, xRectangle *prectInit); +static void cwPolyFillArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc * parcs); static int cwPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, - int count, char *chars); + int count, char *chars); static int cwPolyText16(DrawablePtr pDst, GCPtr pGC, int x, int y, - int count, unsigned short *chars); + int count, unsigned short *chars); static void cwImageText8(DrawablePtr pDst, GCPtr pGC, int x, int y, - int count, char *chars); + int count, char *chars); static void cwImageText16(DrawablePtr pDst, GCPtr pGC, int x, int y, - int count, unsigned short *chars); + int count, unsigned short *chars); static void cwImageGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y, - unsigned int nglyph, CharInfoPtr *ppci, - pointer pglyphBase); + unsigned int nglyph, CharInfoPtr * ppci, + pointer pglyphBase); static void cwPolyGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y, - unsigned int nglyph, CharInfoPtr *ppci, - pointer pglyphBase); + unsigned int nglyph, CharInfoPtr * ppci, + pointer pglyphBase); static void cwPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, - int w, int h, int x, int y); + int w, int h, int x, int y); GCOps cwGCOps = { - cwFillSpans, - cwSetSpans, - cwPutImage, - cwCopyArea, - cwCopyPlane, - cwPolyPoint, - cwPolylines, - cwPolySegment, - cwPolyRectangle, - cwPolyArc, - cwFillPolygon, - cwPolyFillRect, - cwPolyFillArc, - cwPolyText8, - cwPolyText16, - cwImageText8, - cwImageText16, - cwImageGlyphBlt, - cwPolyGlyphBlt, - cwPushPixels + cwFillSpans, + cwSetSpans, + cwPutImage, + cwCopyArea, + cwCopyPlane, + cwPolyPoint, + cwPolylines, + cwPolySegment, + cwPolyRectangle, + cwPolyArc, + cwFillPolygon, + cwPolyFillRect, + cwPolyFillArc, + cwPolyText8, + cwPolyText16, + cwImageText8, + cwImageText16, + cwImageGlyphBlt, + cwPolyGlyphBlt, + cwPushPixels }; static void cwFillSpans(DrawablePtr pDst, GCPtr pGC, int nspans, DDXPointPtr ppt, - int *pwidth, int fSorted) + int *pwidth, int fSorted) { SETUP_BACKING_DST(pDst, pGC); @@ -142,15 +141,15 @@ cwFillSpans(DrawablePtr pDst, GCPtr pGC, int nspans, DDXPointPtr ppt, CW_OFFSET_XYPOINTS(ppt, nspans); - (*pBackingGC->ops->FillSpans)(pBackingDst, pBackingGC, nspans, ppt, - pwidth, fSorted); + (*pBackingGC->ops->FillSpans) (pBackingDst, pBackingGC, nspans, ppt, + pwidth, fSorted); EPILOGUE(pGC); } static void cwSetSpans(DrawablePtr pDst, GCPtr pGC, char *psrc, DDXPointPtr ppt, - int *pwidth, int nspans, int fSorted) + int *pwidth, int nspans, int fSorted) { SETUP_BACKING_DST(pDst, pGC); @@ -158,15 +157,15 @@ cwSetSpans(DrawablePtr pDst, GCPtr pGC, char *psrc, DDXPointPtr ppt, CW_OFFSET_XYPOINTS(ppt, nspans); - (*pBackingGC->ops->SetSpans)(pBackingDst, pBackingGC, psrc, ppt, pwidth, - nspans, fSorted); + (*pBackingGC->ops->SetSpans) (pBackingDst, pBackingGC, psrc, ppt, pwidth, + nspans, fSorted); EPILOGUE(pGC); } static void cwPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y, int w, int h, - int leftPad, int format, char *pBits) + int leftPad, int format, char *pBits) { SETUP_BACKING_DST(pDst, pGC); @@ -174,18 +173,19 @@ cwPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y, int w, int h, CW_OFFSET_XY_DST(x, y); - (*pBackingGC->ops->PutImage)(pBackingDst, pBackingGC, depth, x, y, w, h, - leftPad, format, pBits); + (*pBackingGC->ops->PutImage) (pBackingDst, pBackingGC, depth, x, y, w, h, + leftPad, format, pBits); EPILOGUE(pGC); } static RegionPtr cwCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, - int w, int h, int dstx, int dsty) + int w, int h, int dstx, int dsty) { - int odstx, odsty; - int osrcx, osrcy; + int odstx, odsty; + int osrcx, osrcy; + SETUP_BACKING_DST(pDst, pGC); SETUP_BACKING_SRC(pSrc, pGC); @@ -198,23 +198,22 @@ cwCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, CW_OFFSET_XY_DST(dstx, dsty); CW_OFFSET_XY_SRC(srcx, srcy); - (*pBackingGC->ops->CopyArea)(pBackingSrc, pBackingDst, - pBackingGC, srcx, srcy, w, h, - dstx, dsty); - + (*pBackingGC->ops->CopyArea) (pBackingSrc, pBackingDst, + pBackingGC, srcx, srcy, w, h, dstx, dsty); + EPILOGUE(pGC); return miHandleExposures(pSrc, pDst, pGC, - osrcx, osrcy, w, h, - odstx, odsty, 0); + osrcx, osrcy, w, h, odstx, odsty, 0); } static RegionPtr cwCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, - int w, int h, int dstx, int dsty, unsigned long plane) + int w, int h, int dstx, int dsty, unsigned long plane) { - int odstx, odsty; - int osrcx, osrcy; + int odstx, odsty; + int osrcx, osrcy; + SETUP_BACKING_DST(pDst, pGC); SETUP_BACKING_SRC(pSrc, pGC); @@ -227,30 +226,29 @@ cwCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, CW_OFFSET_XY_DST(dstx, dsty); CW_OFFSET_XY_SRC(srcx, srcy); - (*pBackingGC->ops->CopyPlane)(pBackingSrc, pBackingDst, - pBackingGC, srcx, srcy, w, h, - dstx, dsty, plane); + (*pBackingGC->ops->CopyPlane) (pBackingSrc, pBackingDst, + pBackingGC, srcx, srcy, w, h, + dstx, dsty, plane); EPILOGUE(pGC); return miHandleExposures(pSrc, pDst, pGC, - osrcx, osrcy, w, h, - odstx, odsty, plane); + osrcx, osrcy, w, h, odstx, odsty, plane); } static void -cwPolyPoint(DrawablePtr pDst, GCPtr pGC, int mode, int npt, xPoint *ppt) +cwPolyPoint(DrawablePtr pDst, GCPtr pGC, int mode, int npt, xPoint * ppt) { SETUP_BACKING_DST(pDst, pGC); PROLOGUE(pGC); if (mode == CoordModeOrigin) - CW_OFFSET_XYPOINTS(ppt, npt); + CW_OFFSET_XYPOINTS(ppt, npt); else - CW_OFFSET_XYPOINTS(ppt, 1); + CW_OFFSET_XYPOINTS(ppt, 1); - (*pBackingGC->ops->PolyPoint)(pBackingDst, pBackingGC, mode, npt, ppt); + (*pBackingGC->ops->PolyPoint) (pBackingDst, pBackingGC, mode, npt, ppt); EPILOGUE(pGC); } @@ -263,17 +261,17 @@ cwPolylines(DrawablePtr pDst, GCPtr pGC, int mode, int npt, DDXPointPtr ppt) PROLOGUE(pGC); if (mode == CoordModeOrigin) - CW_OFFSET_XYPOINTS(ppt, npt); + CW_OFFSET_XYPOINTS(ppt, npt); else - CW_OFFSET_XYPOINTS(ppt, 1); + CW_OFFSET_XYPOINTS(ppt, 1); - (*pBackingGC->ops->Polylines)(pBackingDst, pBackingGC, mode, npt, ppt); + (*pBackingGC->ops->Polylines) (pBackingDst, pBackingGC, mode, npt, ppt); EPILOGUE(pGC); } static void -cwPolySegment(DrawablePtr pDst, GCPtr pGC, int nseg, xSegment *pSegs) +cwPolySegment(DrawablePtr pDst, GCPtr pGC, int nseg, xSegment * pSegs) { SETUP_BACKING_DST(pDst, pGC); @@ -281,7 +279,7 @@ cwPolySegment(DrawablePtr pDst, GCPtr pGC, int nseg, xSegment *pSegs) CW_OFFSET_XYPOINTS(pSegs, nseg * 2); - (*pBackingGC->ops->PolySegment)(pBackingDst, pBackingGC, nseg, pSegs); + (*pBackingGC->ops->PolySegment) (pBackingDst, pBackingGC, nseg, pSegs); EPILOGUE(pGC); } @@ -295,13 +293,13 @@ cwPolyRectangle(DrawablePtr pDst, GCPtr pGC, int nrects, xRectangle *pRects) CW_OFFSET_RECTS(pRects, nrects); - (*pBackingGC->ops->PolyRectangle)(pBackingDst, pBackingGC, nrects, pRects); + (*pBackingGC->ops->PolyRectangle) (pBackingDst, pBackingGC, nrects, pRects); EPILOGUE(pGC); } static void -cwPolyArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *pArcs) +cwPolyArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc * pArcs) { SETUP_BACKING_DST(pDst, pGC); @@ -309,26 +307,26 @@ cwPolyArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *pArcs) CW_OFFSET_RECTS(pArcs, narcs); - (*pBackingGC->ops->PolyArc)(pBackingDst, pBackingGC, narcs, pArcs); + (*pBackingGC->ops->PolyArc) (pBackingDst, pBackingGC, narcs, pArcs); EPILOGUE(pGC); } static void cwFillPolygon(DrawablePtr pDst, GCPtr pGC, int shape, int mode, int npt, - DDXPointPtr ppt) + DDXPointPtr ppt) { SETUP_BACKING_DST(pDst, pGC); PROLOGUE(pGC); if (mode == CoordModeOrigin) - CW_OFFSET_XYPOINTS(ppt, npt); + CW_OFFSET_XYPOINTS(ppt, npt); else - CW_OFFSET_XYPOINTS(ppt, 1); + CW_OFFSET_XYPOINTS(ppt, 1); - (*pBackingGC->ops->FillPolygon)(pBackingDst, pBackingGC, shape, mode, npt, - ppt); + (*pBackingGC->ops->FillPolygon) (pBackingDst, pBackingGC, shape, mode, npt, + ppt); EPILOGUE(pGC); } @@ -342,13 +340,13 @@ cwPolyFillRect(DrawablePtr pDst, GCPtr pGC, int nrects, xRectangle *pRects) CW_OFFSET_RECTS(pRects, nrects); - (*pBackingGC->ops->PolyFillRect)(pBackingDst, pBackingGC, nrects, pRects); + (*pBackingGC->ops->PolyFillRect) (pBackingDst, pBackingGC, nrects, pRects); EPILOGUE(pGC); } static void -cwPolyFillArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *parcs) +cwPolyFillArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc * parcs) { SETUP_BACKING_DST(pDst, pGC); @@ -356,7 +354,7 @@ cwPolyFillArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *parcs) CW_OFFSET_RECTS(parcs, narcs); - (*pBackingGC->ops->PolyFillArc)(pBackingDst, pBackingGC, narcs, parcs); + (*pBackingGC->ops->PolyFillArc) (pBackingDst, pBackingGC, narcs, parcs); EPILOGUE(pGC); } @@ -365,14 +363,15 @@ static int cwPolyText8(DrawablePtr pDst, GCPtr pGC, int x, int y, int count, char *chars) { int result; + SETUP_BACKING_DST(pDst, pGC); PROLOGUE(pGC); CW_OFFSET_XY_DST(x, y); - result = (*pBackingGC->ops->PolyText8)(pBackingDst, pBackingGC, x, y, - count, chars); + result = (*pBackingGC->ops->PolyText8) (pBackingDst, pBackingGC, x, y, + count, chars); EPILOGUE(pGC); @@ -381,17 +380,18 @@ cwPolyText8(DrawablePtr pDst, GCPtr pGC, int x, int y, int count, char *chars) static int cwPolyText16(DrawablePtr pDst, GCPtr pGC, int x, int y, int count, - unsigned short *chars) + unsigned short *chars) { int result; + SETUP_BACKING_DST(pDst, pGC); PROLOGUE(pGC); CW_OFFSET_XY_DST(x, y); - result = (*pBackingGC->ops->PolyText16)(pBackingDst, pBackingGC, x, y, - count, chars); + result = (*pBackingGC->ops->PolyText16) (pBackingDst, pBackingGC, x, y, + count, chars); EPILOGUE(pGC); return result; @@ -406,15 +406,15 @@ cwImageText8(DrawablePtr pDst, GCPtr pGC, int x, int y, int count, char *chars) CW_OFFSET_XY_DST(x, y); - (*pBackingGC->ops->ImageText8)(pBackingDst, pBackingGC, x, y, count, - chars); + (*pBackingGC->ops->ImageText8) (pBackingDst, pBackingGC, x, y, count, + chars); EPILOGUE(pGC); } static void cwImageText16(DrawablePtr pDst, GCPtr pGC, int x, int y, int count, - unsigned short *chars) + unsigned short *chars) { SETUP_BACKING_DST(pDst, pGC); @@ -422,15 +422,15 @@ cwImageText16(DrawablePtr pDst, GCPtr pGC, int x, int y, int count, CW_OFFSET_XY_DST(x, y); - (*pBackingGC->ops->ImageText16)(pBackingDst, pBackingGC, x, y, count, - chars); + (*pBackingGC->ops->ImageText16) (pBackingDst, pBackingGC, x, y, count, + chars); EPILOGUE(pGC); } static void cwImageGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y, unsigned int nglyph, - CharInfoPtr *ppci, pointer pglyphBase) + CharInfoPtr * ppci, pointer pglyphBase) { SETUP_BACKING_DST(pDst, pGC); @@ -438,15 +438,15 @@ cwImageGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y, unsigned int nglyph, CW_OFFSET_XY_DST(x, y); - (*pBackingGC->ops->ImageGlyphBlt)(pBackingDst, pBackingGC, x, y, nglyph, - ppci, pglyphBase); + (*pBackingGC->ops->ImageGlyphBlt) (pBackingDst, pBackingGC, x, y, nglyph, + ppci, pglyphBase); EPILOGUE(pGC); } static void cwPolyGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y, unsigned int nglyph, - CharInfoPtr *ppci, pointer pglyphBase) + CharInfoPtr * ppci, pointer pglyphBase) { SETUP_BACKING_DST(pDst, pGC); @@ -454,15 +454,15 @@ cwPolyGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y, unsigned int nglyph, CW_OFFSET_XY_DST(x, y); - (*pBackingGC->ops->PolyGlyphBlt)(pBackingDst, pBackingGC, x, y, nglyph, - ppci, pglyphBase); + (*pBackingGC->ops->PolyGlyphBlt) (pBackingDst, pBackingGC, x, y, nglyph, + ppci, pglyphBase); EPILOGUE(pGC); } static void cwPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, int w, int h, - int x, int y) + int x, int y) { SETUP_BACKING_DST(pDst, pGC); @@ -470,9 +470,8 @@ cwPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, int w, int h, CW_OFFSET_XY_DST(x, y); - (*pBackingGC->ops->PushPixels)(pBackingGC, pBitMap, pBackingDst, w, h, - x, y); + (*pBackingGC->ops->PushPixels) (pBackingGC, pBitMap, pBackingDst, w, h, + x, y); EPILOGUE(pGC); } - diff --git a/xorg-server/miext/cw/cw_render.c b/xorg-server/miext/cw/cw_render.c index 25601f3e2..059d686fb 100644 --- a/xorg-server/miext/cw/cw_render.c +++ b/xorg-server/miext/cw/cw_render.c @@ -1,405 +1,383 @@ -/*
- * Copyright © 2004 Eric Anholt
- *
- * 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 Eric Anholt not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Eric Anholt makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL ERIC ANHOLT 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 <string.h>
-
-#include "gcstruct.h"
-#include "windowstr.h"
-#include "cw.h"
-
-#define cwPsDecl(pScreen) \
- PictureScreenPtr ps = GetPictureScreen (pScreen); \
- cwScreenPtr pCwScreen = getCwScreen (pScreen)
-
-#define cwPicturePrivate \
- cwPicturePtr pPicturePrivate = getCwPicture(pPicture)
-
-#define cwSrcPictureDecl \
- int src_picture_x_off, src_picture_y_off; \
- PicturePtr pBackingSrcPicture = cwGetBackingPicture(pSrcPicture, \
- &src_picture_x_off,\
- &src_picture_y_off)
-
-#define cwDstPictureDecl \
- int dst_picture_x_off, dst_picture_y_off; \
- PicturePtr pBackingDstPicture = cwGetBackingPicture(pDstPicture, \
- &dst_picture_x_off,\
- &dst_picture_y_off)
-
-#define cwMskPictureDecl \
- int msk_picture_x_off = 0, msk_picture_y_off = 0; \
- PicturePtr pBackingMskPicture = (!pMskPicture ? 0 : \
- cwGetBackingPicture(pMskPicture, \
- &msk_picture_x_off,\
- &msk_picture_y_off))
-
-#define cwPsUnwrap(elt) { \
- ps->elt = pCwScreen->elt; \
-}
-
-#define cwPsWrap(elt,func) { \
- pCwScreen->elt = ps->elt; \
- ps->elt = func; \
-}
-
-static cwPicturePtr
-cwCreatePicturePrivate (PicturePtr pPicture)
-{
- WindowPtr pWindow = (WindowPtr) pPicture->pDrawable;
- PixmapPtr pPixmap = getCwPixmap (pWindow);
- int error;
- cwPicturePtr pPicturePrivate;
-
- pPicturePrivate = malloc(sizeof (cwPictureRec));
- if (!pPicturePrivate)
- return NULL;
-
- pPicturePrivate->pBackingPicture = CreatePicture (0, &pPixmap->drawable,
- pPicture->pFormat,
- 0, 0, serverClient,
- &error);
- if (!pPicturePrivate->pBackingPicture)
- {
- free(pPicturePrivate);
- return NULL;
- }
-
- /*
- * Ensure that this serial number does not match the window's
- */
- pPicturePrivate->serialNumber = pPixmap->drawable.serialNumber;
- pPicturePrivate->stateChanges = (1 << (CPLastBit + 1)) - 1;
-
- setCwPicture(pPicture, pPicturePrivate);
-
- return pPicturePrivate;
-}
-
-static void
-cwDestroyPicturePrivate (PicturePtr pPicture)
-{
- cwPicturePrivate;
-
- if (pPicturePrivate)
- {
- if (pPicturePrivate->pBackingPicture)
- FreePicture (pPicturePrivate->pBackingPicture, 0);
- free(pPicturePrivate);
- setCwPicture(pPicture, NULL);
- }
-}
-
-static PicturePtr
-cwGetBackingPicture (PicturePtr pPicture, int *x_off, int *y_off)
-{
- cwPicturePrivate;
-
- if (pPicturePrivate)
- {
- DrawablePtr pDrawable = pPicture->pDrawable;
- WindowPtr pWindow = (WindowPtr) pDrawable;
- PixmapPtr pPixmap = getCwPixmap (pWindow);
-
- *x_off = pDrawable->x - pPixmap->screen_x;
- *y_off = pDrawable->y - pPixmap->screen_y;
-
- return pPicturePrivate->pBackingPicture;
- }
- else
- {
- *x_off = *y_off = 0;
- return pPicture;
- }
-}
-
-static void
-cwDestroyPicture (PicturePtr pPicture)
-{
- ScreenPtr pScreen = pPicture->pDrawable->pScreen;
- cwPsDecl(pScreen);
-
- cwPsUnwrap(DestroyPicture);
- cwDestroyPicturePrivate (pPicture);
- (*ps->DestroyPicture) (pPicture);
- cwPsWrap(DestroyPicture, cwDestroyPicture);
-}
-
-static void
-cwChangePicture (PicturePtr pPicture, Mask mask)
-{
- ScreenPtr pScreen = pPicture->pDrawable->pScreen;
- cwPsDecl(pScreen);
- cwPicturePtr pPicturePrivate = getCwPicture(pPicture);
-
- cwPsUnwrap(ChangePicture);
- (*ps->ChangePicture) (pPicture, mask);
- if (pPicturePrivate)
- pPicturePrivate->stateChanges |= mask;
- cwPsWrap(ChangePicture, cwChangePicture);
-}
-
-
-static void
-cwValidatePicture (PicturePtr pPicture,
- Mask mask)
-{
- DrawablePtr pDrawable = pPicture->pDrawable;
- ScreenPtr pScreen = pDrawable->pScreen;
- cwPsDecl(pScreen);
- cwPicturePrivate;
-
- cwPsUnwrap(ValidatePicture);
-
- /*
- * Must call ValidatePicture to ensure pPicture->pCompositeClip is valid
- */
- (*ps->ValidatePicture) (pPicture, mask);
-
- if (!cwDrawableIsRedirWindow (pDrawable))
- {
- if (pPicturePrivate)
- cwDestroyPicturePrivate (pPicture);
- }
- else
- {
- PicturePtr pBackingPicture;
- DrawablePtr pBackingDrawable;
- int x_off, y_off;
-
- pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off);
-
- if (pPicturePrivate &&
- pPicturePrivate->pBackingPicture->pDrawable != pBackingDrawable)
- {
- cwDestroyPicturePrivate (pPicture);
- pPicturePrivate = 0;
- }
-
- if (!pPicturePrivate)
- {
- pPicturePrivate = cwCreatePicturePrivate (pPicture);
- if (!pPicturePrivate)
- {
- cwPsWrap(ValidatePicture, cwValidatePicture);
- return;
- }
- }
-
- pBackingPicture = pPicturePrivate->pBackingPicture;
-
- /*
- * Always copy transform and filters because there's no
- * indication of when they've changed
- */
- SetPictureTransform(pBackingPicture, pPicture->transform);
-
- if (pBackingPicture->filter != pPicture->filter ||
- pPicture->filter_nparams > 0)
- {
- char *filter = PictureGetFilterName (pPicture->filter);
-
- SetPictureFilter(pBackingPicture,
- filter, strlen (filter),
- pPicture->filter_params,
- pPicture->filter_nparams);
- }
-
- pPicturePrivate->stateChanges |= mask;
-
- if (pPicturePrivate->serialNumber != pDrawable->serialNumber ||
- (pPicturePrivate->stateChanges & (CPClipXOrigin|CPClipYOrigin|CPClipMask)))
- {
- SetPictureClipRegion (pBackingPicture,
- x_off - pDrawable->x,
- y_off - pDrawable->y,
- pPicture->pCompositeClip);
-
- pPicturePrivate->serialNumber = pDrawable->serialNumber;
- pPicturePrivate->stateChanges &= ~(CPClipXOrigin | CPClipYOrigin | CPClipMask);
- }
-
- CopyPicture(pPicture, pPicturePrivate->stateChanges, pBackingPicture);
-
- ValidatePicture (pBackingPicture);
- }
- cwPsWrap(ValidatePicture, cwValidatePicture);
-}
-
-static void
-cwComposite (CARD8 op,
- PicturePtr pSrcPicture,
- PicturePtr pMskPicture,
- PicturePtr pDstPicture,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMsk,
- INT16 yMsk,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height)
-{
- ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
- cwPsDecl(pScreen);
- cwSrcPictureDecl;
- cwMskPictureDecl;
- cwDstPictureDecl;
-
- cwPsUnwrap(Composite);
- (*ps->Composite) (op, pBackingSrcPicture, pBackingMskPicture, pBackingDstPicture,
- xSrc + src_picture_x_off, ySrc + src_picture_y_off,
- xMsk + msk_picture_x_off, yMsk + msk_picture_y_off,
- xDst + dst_picture_x_off, yDst + dst_picture_y_off,
- width, height);
- cwPsWrap(Composite, cwComposite);
-}
-
-static void
-cwCompositeRects (CARD8 op,
- PicturePtr pDstPicture,
- xRenderColor *color,
- int nRect,
- xRectangle *rects)
-{
- ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
- cwPsDecl(pScreen);
- cwDstPictureDecl;
- int i;
-
- cwPsUnwrap(CompositeRects);
- for (i = 0; i < nRect; i++)
- {
- rects[i].x += dst_picture_x_off;
- rects[i].y += dst_picture_y_off;
- }
- (*ps->CompositeRects) (op, pBackingDstPicture, color, nRect, rects);
- cwPsWrap(CompositeRects, cwCompositeRects);
-}
-
-static void
-cwTrapezoids (CARD8 op,
- PicturePtr pSrcPicture,
- PicturePtr pDstPicture,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int ntrap,
- xTrapezoid *traps)
-{
- ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
- cwPsDecl(pScreen);
- cwSrcPictureDecl;
- cwDstPictureDecl;
- int i;
-
- cwPsUnwrap(Trapezoids);
- if (dst_picture_x_off || dst_picture_y_off) {
- for (i = 0; i < ntrap; i++)
- {
- traps[i].top += dst_picture_y_off << 16;
- traps[i].bottom += dst_picture_y_off << 16;
- traps[i].left.p1.x += dst_picture_x_off << 16;
- traps[i].left.p1.y += dst_picture_y_off << 16;
- traps[i].left.p2.x += dst_picture_x_off << 16;
- traps[i].left.p2.y += dst_picture_y_off << 16;
- traps[i].right.p1.x += dst_picture_x_off << 16;
- traps[i].right.p1.y += dst_picture_y_off << 16;
- traps[i].right.p2.x += dst_picture_x_off << 16;
- traps[i].right.p2.y += dst_picture_y_off << 16;
- }
- }
- (*ps->Trapezoids) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
- xSrc + src_picture_x_off, ySrc + src_picture_y_off,
- ntrap, traps);
- cwPsWrap(Trapezoids, cwTrapezoids);
-}
-
-static void
-cwTriangles (CARD8 op,
- PicturePtr pSrcPicture,
- PicturePtr pDstPicture,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int ntri,
- xTriangle *tris)
-{
- ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
- cwPsDecl(pScreen);
- cwSrcPictureDecl;
- cwDstPictureDecl;
- int i;
-
- cwPsUnwrap(Triangles);
- if (dst_picture_x_off || dst_picture_y_off) {
- for (i = 0; i < ntri; i++)
- {
- tris[i].p1.x += dst_picture_x_off << 16;
- tris[i].p1.y += dst_picture_y_off << 16;
- tris[i].p2.x += dst_picture_x_off << 16;
- tris[i].p2.y += dst_picture_y_off << 16;
- tris[i].p3.x += dst_picture_x_off << 16;
- tris[i].p3.y += dst_picture_y_off << 16;
- }
- }
- (*ps->Triangles) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
- xSrc + src_picture_x_off, ySrc + src_picture_y_off,
- ntri, tris);
- cwPsWrap(Triangles, cwTriangles);
-}
-
-void
-cwInitializeRender (ScreenPtr pScreen)
-{
- cwPsDecl (pScreen);
-
- cwPsWrap(DestroyPicture, cwDestroyPicture);
- cwPsWrap(ChangePicture, cwChangePicture);
- cwPsWrap(ValidatePicture, cwValidatePicture);
- cwPsWrap(Composite, cwComposite);
- cwPsWrap(CompositeRects, cwCompositeRects);
- cwPsWrap(Trapezoids, cwTrapezoids);
- cwPsWrap(Triangles, cwTriangles);
- /* There is no need to wrap AddTraps as far as we can tell. AddTraps can
- * only be done on alpha-only pictures, and we won't be getting
- * alpha-only window pictures, so there's no need to translate.
- */
-}
-
-void
-cwFiniRender (ScreenPtr pScreen)
-{
- cwPsDecl (pScreen);
-
- cwPsUnwrap(DestroyPicture);
- cwPsUnwrap(ChangePicture);
- cwPsUnwrap(ValidatePicture);
- cwPsUnwrap(Composite);
- cwPsUnwrap(CompositeRects);
- cwPsUnwrap(Trapezoids);
- cwPsUnwrap(Triangles);
-}
-
+/* + * Copyright © 2004 Eric Anholt + * + * 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 Eric Anholt not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Eric Anholt makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ERIC ANHOLT 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 <string.h> + +#include "gcstruct.h" +#include "windowstr.h" +#include "cw.h" + +#define cwPsDecl(pScreen) \ + PictureScreenPtr ps = GetPictureScreen (pScreen); \ + cwScreenPtr pCwScreen = getCwScreen (pScreen) + +#define cwPicturePrivate \ + cwPicturePtr pPicturePrivate = getCwPicture(pPicture) + +#define cwSrcPictureDecl \ + int src_picture_x_off, src_picture_y_off; \ + PicturePtr pBackingSrcPicture = cwGetBackingPicture(pSrcPicture, \ + &src_picture_x_off,\ + &src_picture_y_off) + +#define cwDstPictureDecl \ + int dst_picture_x_off, dst_picture_y_off; \ + PicturePtr pBackingDstPicture = cwGetBackingPicture(pDstPicture, \ + &dst_picture_x_off,\ + &dst_picture_y_off) + +#define cwMskPictureDecl \ + int msk_picture_x_off = 0, msk_picture_y_off = 0; \ + PicturePtr pBackingMskPicture = (!pMskPicture ? 0 : \ + cwGetBackingPicture(pMskPicture, \ + &msk_picture_x_off,\ + &msk_picture_y_off)) + +#define cwPsUnwrap(elt) { \ + ps->elt = pCwScreen->elt; \ +} + +#define cwPsWrap(elt,func) { \ + pCwScreen->elt = ps->elt; \ + ps->elt = func; \ +} + +static cwPicturePtr +cwCreatePicturePrivate(PicturePtr pPicture) +{ + WindowPtr pWindow = (WindowPtr) pPicture->pDrawable; + PixmapPtr pPixmap = getCwPixmap(pWindow); + int error; + cwPicturePtr pPicturePrivate; + + pPicturePrivate = malloc(sizeof(cwPictureRec)); + if (!pPicturePrivate) + return NULL; + + pPicturePrivate->pBackingPicture = CreatePicture(0, &pPixmap->drawable, + pPicture->pFormat, + 0, 0, serverClient, + &error); + if (!pPicturePrivate->pBackingPicture) { + free(pPicturePrivate); + return NULL; + } + + /* + * Ensure that this serial number does not match the window's + */ + pPicturePrivate->serialNumber = pPixmap->drawable.serialNumber; + pPicturePrivate->stateChanges = (1 << (CPLastBit + 1)) - 1; + + setCwPicture(pPicture, pPicturePrivate); + + return pPicturePrivate; +} + +static void +cwDestroyPicturePrivate(PicturePtr pPicture) +{ + cwPicturePrivate; + + if (pPicturePrivate) { + if (pPicturePrivate->pBackingPicture) + FreePicture(pPicturePrivate->pBackingPicture, 0); + free(pPicturePrivate); + setCwPicture(pPicture, NULL); + } +} + +static PicturePtr +cwGetBackingPicture(PicturePtr pPicture, int *x_off, int *y_off) +{ + cwPicturePrivate; + + if (pPicturePrivate) { + DrawablePtr pDrawable = pPicture->pDrawable; + WindowPtr pWindow = (WindowPtr) pDrawable; + PixmapPtr pPixmap = getCwPixmap(pWindow); + + *x_off = pDrawable->x - pPixmap->screen_x; + *y_off = pDrawable->y - pPixmap->screen_y; + + return pPicturePrivate->pBackingPicture; + } + else { + *x_off = *y_off = 0; + return pPicture; + } +} + +static void +cwDestroyPicture(PicturePtr pPicture) +{ + ScreenPtr pScreen = pPicture->pDrawable->pScreen; + + cwPsDecl(pScreen); + + cwPsUnwrap(DestroyPicture); + cwDestroyPicturePrivate(pPicture); + (*ps->DestroyPicture) (pPicture); + cwPsWrap(DestroyPicture, cwDestroyPicture); +} + +static void +cwChangePicture(PicturePtr pPicture, Mask mask) +{ + ScreenPtr pScreen = pPicture->pDrawable->pScreen; + + cwPsDecl(pScreen); + cwPicturePtr pPicturePrivate = getCwPicture(pPicture); + + cwPsUnwrap(ChangePicture); + (*ps->ChangePicture) (pPicture, mask); + if (pPicturePrivate) + pPicturePrivate->stateChanges |= mask; + cwPsWrap(ChangePicture, cwChangePicture); +} + +static void +cwValidatePicture(PicturePtr pPicture, Mask mask) +{ + DrawablePtr pDrawable = pPicture->pDrawable; + ScreenPtr pScreen = pDrawable->pScreen; + + cwPsDecl(pScreen); + cwPicturePrivate; + + cwPsUnwrap(ValidatePicture); + + /* + * Must call ValidatePicture to ensure pPicture->pCompositeClip is valid + */ + (*ps->ValidatePicture) (pPicture, mask); + + if (!cwDrawableIsRedirWindow(pDrawable)) { + if (pPicturePrivate) + cwDestroyPicturePrivate(pPicture); + } + else { + PicturePtr pBackingPicture; + DrawablePtr pBackingDrawable; + int x_off, y_off; + + pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off); + + if (pPicturePrivate && + pPicturePrivate->pBackingPicture->pDrawable != pBackingDrawable) { + cwDestroyPicturePrivate(pPicture); + pPicturePrivate = 0; + } + + if (!pPicturePrivate) { + pPicturePrivate = cwCreatePicturePrivate(pPicture); + if (!pPicturePrivate) { + cwPsWrap(ValidatePicture, cwValidatePicture); + return; + } + } + + pBackingPicture = pPicturePrivate->pBackingPicture; + + /* + * Always copy transform and filters because there's no + * indication of when they've changed + */ + SetPictureTransform(pBackingPicture, pPicture->transform); + + if (pBackingPicture->filter != pPicture->filter || + pPicture->filter_nparams > 0) { + char *filter = PictureGetFilterName(pPicture->filter); + + SetPictureFilter(pBackingPicture, + filter, strlen(filter), + pPicture->filter_params, pPicture->filter_nparams); + } + + pPicturePrivate->stateChanges |= mask; + + if (pPicturePrivate->serialNumber != pDrawable->serialNumber || + (pPicturePrivate-> + stateChanges & (CPClipXOrigin | CPClipYOrigin | CPClipMask))) { + SetPictureClipRegion(pBackingPicture, x_off - pDrawable->x, + y_off - pDrawable->y, + pPicture->pCompositeClip); + + pPicturePrivate->serialNumber = pDrawable->serialNumber; + pPicturePrivate->stateChanges &= + ~(CPClipXOrigin | CPClipYOrigin | CPClipMask); + } + + CopyPicture(pPicture, pPicturePrivate->stateChanges, pBackingPicture); + + ValidatePicture(pBackingPicture); + } + cwPsWrap(ValidatePicture, cwValidatePicture); +} + +static void +cwComposite(CARD8 op, + PicturePtr pSrcPicture, + PicturePtr pMskPicture, + PicturePtr pDstPicture, + INT16 xSrc, + INT16 ySrc, + INT16 xMsk, + INT16 yMsk, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) +{ + ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; + + cwPsDecl(pScreen); + cwSrcPictureDecl; + cwMskPictureDecl; + cwDstPictureDecl; + + cwPsUnwrap(Composite); + (*ps->Composite) (op, pBackingSrcPicture, pBackingMskPicture, + pBackingDstPicture, xSrc + src_picture_x_off, + ySrc + src_picture_y_off, xMsk + msk_picture_x_off, + yMsk + msk_picture_y_off, xDst + dst_picture_x_off, + yDst + dst_picture_y_off, width, height); + cwPsWrap(Composite, cwComposite); +} + +static void +cwCompositeRects(CARD8 op, + PicturePtr pDstPicture, + xRenderColor * color, int nRect, xRectangle *rects) +{ + ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; + + cwPsDecl(pScreen); + cwDstPictureDecl; + int i; + + cwPsUnwrap(CompositeRects); + for (i = 0; i < nRect; i++) { + rects[i].x += dst_picture_x_off; + rects[i].y += dst_picture_y_off; + } + (*ps->CompositeRects) (op, pBackingDstPicture, color, nRect, rects); + cwPsWrap(CompositeRects, cwCompositeRects); +} + +static void +cwTrapezoids(CARD8 op, + PicturePtr pSrcPicture, + PicturePtr pDstPicture, + PictFormatPtr maskFormat, + INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid * traps) +{ + ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; + + cwPsDecl(pScreen); + cwSrcPictureDecl; + cwDstPictureDecl; + int i; + + cwPsUnwrap(Trapezoids); + if (dst_picture_x_off || dst_picture_y_off) { + for (i = 0; i < ntrap; i++) { + traps[i].top += dst_picture_y_off << 16; + traps[i].bottom += dst_picture_y_off << 16; + traps[i].left.p1.x += dst_picture_x_off << 16; + traps[i].left.p1.y += dst_picture_y_off << 16; + traps[i].left.p2.x += dst_picture_x_off << 16; + traps[i].left.p2.y += dst_picture_y_off << 16; + traps[i].right.p1.x += dst_picture_x_off << 16; + traps[i].right.p1.y += dst_picture_y_off << 16; + traps[i].right.p2.x += dst_picture_x_off << 16; + traps[i].right.p2.y += dst_picture_y_off << 16; + } + } + (*ps->Trapezoids) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat, + xSrc + src_picture_x_off, ySrc + src_picture_y_off, + ntrap, traps); + cwPsWrap(Trapezoids, cwTrapezoids); +} + +static void +cwTriangles(CARD8 op, + PicturePtr pSrcPicture, + PicturePtr pDstPicture, + PictFormatPtr maskFormat, + INT16 xSrc, INT16 ySrc, int ntri, xTriangle * tris) +{ + ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; + + cwPsDecl(pScreen); + cwSrcPictureDecl; + cwDstPictureDecl; + int i; + + cwPsUnwrap(Triangles); + if (dst_picture_x_off || dst_picture_y_off) { + for (i = 0; i < ntri; i++) { + tris[i].p1.x += dst_picture_x_off << 16; + tris[i].p1.y += dst_picture_y_off << 16; + tris[i].p2.x += dst_picture_x_off << 16; + tris[i].p2.y += dst_picture_y_off << 16; + tris[i].p3.x += dst_picture_x_off << 16; + tris[i].p3.y += dst_picture_y_off << 16; + } + } + (*ps->Triangles) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat, + xSrc + src_picture_x_off, ySrc + src_picture_y_off, + ntri, tris); + cwPsWrap(Triangles, cwTriangles); +} + +void +cwInitializeRender(ScreenPtr pScreen) +{ + cwPsDecl(pScreen); + + cwPsWrap(DestroyPicture, cwDestroyPicture); + cwPsWrap(ChangePicture, cwChangePicture); + cwPsWrap(ValidatePicture, cwValidatePicture); + cwPsWrap(Composite, cwComposite); + cwPsWrap(CompositeRects, cwCompositeRects); + cwPsWrap(Trapezoids, cwTrapezoids); + cwPsWrap(Triangles, cwTriangles); + /* There is no need to wrap AddTraps as far as we can tell. AddTraps can + * only be done on alpha-only pictures, and we won't be getting + * alpha-only window pictures, so there's no need to translate. + */ +} + +void +cwFiniRender(ScreenPtr pScreen) +{ + cwPsDecl(pScreen); + + cwPsUnwrap(DestroyPicture); + cwPsUnwrap(ChangePicture); + cwPsUnwrap(ValidatePicture); + cwPsUnwrap(Composite); + cwPsUnwrap(CompositeRects); + cwPsUnwrap(Trapezoids); + cwPsUnwrap(Triangles); +} diff --git a/xorg-server/miext/damage/damage.c b/xorg-server/miext/damage/damage.c index d79121165..72ed65997 100644 --- a/xorg-server/miext/damage/damage.c +++ b/xorg-server/miext/damage/damage.c @@ -71,41 +71,43 @@ #define pixmapDamage(pPixmap) damagePixPriv(pPixmap) static DevPrivateKeyRec damageScrPrivateKeyRec; + #define damageScrPrivateKey (&damageScrPrivateKeyRec) static DevPrivateKeyRec damagePixPrivateKeyRec; + #define damagePixPrivateKey (&damagePixPrivateKeyRec) static DevPrivateKeyRec damageGCPrivateKeyRec; + #define damageGCPrivateKey (&damageGCPrivateKeyRec) static DevPrivateKeyRec damageWinPrivateKeyRec; + #define damageWinPrivateKey (&damageWinPrivateKeyRec) static DamagePtr * -getDrawableDamageRef (DrawablePtr pDrawable) +getDrawableDamageRef(DrawablePtr pDrawable) { - PixmapPtr pPixmap; - - if (WindowDrawable(pDrawable->type)) - { - ScreenPtr pScreen = pDrawable->pScreen; + PixmapPtr pPixmap; - pPixmap = 0; - if (pScreen->GetWindowPixmap + if (WindowDrawable(pDrawable->type)) { + ScreenPtr pScreen = pDrawable->pScreen; + + pPixmap = 0; + if (pScreen->GetWindowPixmap #ifdef ROOTLESS_WORKAROUND - && ((WindowPtr)pDrawable)->viewable + && ((WindowPtr) pDrawable)->viewable #endif - ) - pPixmap = (*pScreen->GetWindowPixmap) ((WindowPtr)pDrawable); + ) + pPixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) pDrawable); - if (!pPixmap) - { - damageScrPriv(pScreen); + if (!pPixmap) { + damageScrPriv(pScreen); - return &pScrPriv->pScreenDamage; - } + return &pScrPriv->pScreenDamage; + } } else - pPixmap = (PixmapPtr) pDrawable; - return getPixmapDamageRef (pPixmap); + pPixmap = (PixmapPtr) pDrawable; + return getPixmapDamageRef(pPixmap); } #define getDrawableDamage(pDrawable) (*getDrawableDamageRef (pDrawable)) @@ -121,7 +123,8 @@ getDrawableDamageRef (DrawablePtr pDrawable) dixLookupPrivateAddr(&(pWindow)->devPrivates, damageWinPrivateKey) static void -damageReportDamagePostRendering (DamagePtr pDamage, RegionPtr pOldDamage, RegionPtr pDamageRegion) +damageReportDamagePostRendering(DamagePtr pDamage, RegionPtr pOldDamage, + RegionPtr pDamageRegion) { BoxRec tmpBox; RegionRec tmpRegion, newDamage; @@ -131,32 +134,34 @@ damageReportDamagePostRendering (DamagePtr pDamage, RegionPtr pOldDamage, Region switch (pDamage->damageLevel) { case DamageReportRawRegion: - (*pDamage->damageReportPostRendering) (pDamage, pDamageRegion, pDamage->closure); - break; + (*pDamage->damageReportPostRendering) (pDamage, pDamageRegion, + pDamage->closure); + break; case DamageReportDeltaRegion: - RegionNull(&tmpRegion); - RegionSubtract(&tmpRegion, pDamageRegion, pOldDamage); - if (RegionNotEmpty(&tmpRegion)) { - (*pDamage->damageReportPostRendering) (pDamage, &tmpRegion, pDamage->closure); - } - RegionUninit(&tmpRegion); - break; + RegionNull(&tmpRegion); + RegionSubtract(&tmpRegion, pDamageRegion, pOldDamage); + if (RegionNotEmpty(&tmpRegion)) { + (*pDamage->damageReportPostRendering) (pDamage, &tmpRegion, + pDamage->closure); + } + RegionUninit(&tmpRegion); + break; case DamageReportBoundingBox: - tmpBox = *RegionExtents(pOldDamage); - if (!BOX_SAME (&tmpBox, RegionExtents(&newDamage))) { - (*pDamage->damageReportPostRendering) (pDamage, &newDamage, - pDamage->closure); - } - break; + tmpBox = *RegionExtents(pOldDamage); + if (!BOX_SAME(&tmpBox, RegionExtents(&newDamage))) { + (*pDamage->damageReportPostRendering) (pDamage, &newDamage, + pDamage->closure); + } + break; case DamageReportNonEmpty: - was_empty = !RegionNotEmpty(pOldDamage); - if (was_empty && RegionNotEmpty(&newDamage)) { - (*pDamage->damageReportPostRendering) (pDamage, &newDamage, - pDamage->closure); - } - break; + was_empty = !RegionNotEmpty(pOldDamage); + if (was_empty && RegionNotEmpty(&newDamage)) { + (*pDamage->damageReportPostRendering) (pDamage, &newDamage, + pDamage->closure); + } + break; case DamageReportNone: - break; + break; } RegionUninit(&newDamage); @@ -164,217 +169,215 @@ damageReportDamagePostRendering (DamagePtr pDamage, RegionPtr pOldDamage, Region #if DAMAGE_DEBUG_ENABLE static void -_damageRegionAppend (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip, int subWindowMode, const char *where) +_damageRegionAppend(DrawablePtr pDrawable, RegionPtr pRegion, Bool clip, + int subWindowMode, const char *where) #define damageRegionAppend(d,r,c,m) _damageRegionAppend(d,r,c,m,__FUNCTION__) #else static void -damageRegionAppend (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip, - int subWindowMode) +damageRegionAppend(DrawablePtr pDrawable, RegionPtr pRegion, Bool clip, + int subWindowMode) #endif { - ScreenPtr pScreen = pDrawable->pScreen; + ScreenPtr pScreen = pDrawable->pScreen; + damageScrPriv(pScreen); drawableDamage(pDrawable); - DamagePtr pNext; - RegionRec clippedRec; - RegionPtr pDamageRegion; - RegionRec pixClip; - int draw_x, draw_y; + DamagePtr pNext; + RegionRec clippedRec; + RegionPtr pDamageRegion; + RegionRec pixClip; + int draw_x, draw_y; + #ifdef COMPOSITE - int screen_x = 0, screen_y = 0; + int screen_x = 0, screen_y = 0; #endif /* short circuit for empty regions */ if (!RegionNotEmpty(pRegion)) - return; - + return; + #ifdef COMPOSITE /* * When drawing to a pixmap which is storing window contents, * the region presented is in pixmap relative coordinates which * need to be converted to screen relative coordinates */ - if (pDrawable->type != DRAWABLE_WINDOW) - { - screen_x = ((PixmapPtr) pDrawable)->screen_x - pDrawable->x; - screen_y = ((PixmapPtr) pDrawable)->screen_y - pDrawable->y; + if (pDrawable->type != DRAWABLE_WINDOW) { + screen_x = ((PixmapPtr) pDrawable)->screen_x - pDrawable->x; + screen_y = ((PixmapPtr) pDrawable)->screen_y - pDrawable->y; } if (screen_x || screen_y) RegionTranslate(pRegion, screen_x, screen_y); #endif - + if (pDrawable->type == DRAWABLE_WINDOW && - ((WindowPtr)(pDrawable))->backingStore == NotUseful) - { - if (subWindowMode == ClipByChildren) - { - RegionIntersect(pRegion, pRegion, - &((WindowPtr)(pDrawable))->clipList); - } - else if (subWindowMode == IncludeInferiors) - { - RegionPtr pTempRegion = - NotClippedByChildren((WindowPtr)(pDrawable)); - RegionIntersect(pRegion, pRegion, pTempRegion); - RegionDestroy(pTempRegion); - } - /* If subWindowMode is set to an invalid value, don't perform - * any drawable-based clipping. */ + ((WindowPtr) (pDrawable))->backingStore == NotUseful) { + if (subWindowMode == ClipByChildren) { + RegionIntersect(pRegion, pRegion, + &((WindowPtr) (pDrawable))->clipList); + } + else if (subWindowMode == IncludeInferiors) { + RegionPtr pTempRegion = + NotClippedByChildren((WindowPtr) (pDrawable)); + RegionIntersect(pRegion, pRegion, pTempRegion); + RegionDestroy(pTempRegion); + } + /* If subWindowMode is set to an invalid value, don't perform + * any drawable-based clipping. */ } - RegionNull(&clippedRec); - for (; pDamage; pDamage = pNext) - { - pNext = pDamage->pNext; - /* - * Check for internal damage and don't send events - */ - if (pScrPriv->internalLevel > 0 && !pDamage->isInternal) - { - DAMAGE_DEBUG (("non internal damage, skipping at %d\n", - pScrPriv->internalLevel)); - continue; - } - /* - * Check for unrealized windows - */ - if (pDamage->pDrawable->type == DRAWABLE_WINDOW && - !((WindowPtr) (pDamage->pDrawable))->realized) - { - continue; - } - - draw_x = pDamage->pDrawable->x; - draw_y = pDamage->pDrawable->y; + for (; pDamage; pDamage = pNext) { + pNext = pDamage->pNext; + /* + * Check for internal damage and don't send events + */ + if (pScrPriv->internalLevel > 0 && !pDamage->isInternal) { + DAMAGE_DEBUG(("non internal damage, skipping at %d\n", + pScrPriv->internalLevel)); + continue; + } + /* + * Check for unrealized windows + */ + if (pDamage->pDrawable->type == DRAWABLE_WINDOW && + !((WindowPtr) (pDamage->pDrawable))->realized) { + continue; + } + + draw_x = pDamage->pDrawable->x; + draw_y = pDamage->pDrawable->y; #ifdef COMPOSITE - /* - * Need to move everyone to screen coordinates - * XXX what about off-screen pixmaps with non-zero x/y? - */ - if (!WindowDrawable(pDamage->pDrawable->type)) - { - draw_x += ((PixmapPtr) pDamage->pDrawable)->screen_x; - draw_y += ((PixmapPtr) pDamage->pDrawable)->screen_y; - } + /* + * Need to move everyone to screen coordinates + * XXX what about off-screen pixmaps with non-zero x/y? + */ + if (!WindowDrawable(pDamage->pDrawable->type)) { + draw_x += ((PixmapPtr) pDamage->pDrawable)->screen_x; + draw_y += ((PixmapPtr) pDamage->pDrawable)->screen_y; + } #endif - - /* - * Clip against border or pixmap bounds - */ - - pDamageRegion = pRegion; - if (clip || pDamage->pDrawable != pDrawable) - { - pDamageRegion = &clippedRec; - if (pDamage->pDrawable->type == DRAWABLE_WINDOW) { - RegionIntersect(pDamageRegion, pRegion, - &((WindowPtr)(pDamage->pDrawable))->borderClip); - } else { - BoxRec box; - box.x1 = draw_x; - box.y1 = draw_y; - box.x2 = draw_x + pDamage->pDrawable->width; - box.y2 = draw_y + pDamage->pDrawable->height; - RegionInit(&pixClip, &box, 1); - RegionIntersect(pDamageRegion, pRegion, &pixClip); - RegionUninit(&pixClip); - } - /* - * Short circuit empty results - */ - if (!RegionNotEmpty(pDamageRegion)) - continue; - } - - DAMAGE_DEBUG (("%s %d x %d +%d +%d (target 0x%lx monitor 0x%lx)\n", - where, - pDamageRegion->extents.x2 - pDamageRegion->extents.x1, - pDamageRegion->extents.y2 - pDamageRegion->extents.y1, - pDamageRegion->extents.x1, pDamageRegion->extents.y1, - pDrawable->id, pDamage->pDrawable->id)); - - /* - * Move region to target coordinate space - */ - if (draw_x || draw_y) - RegionTranslate(pDamageRegion, -draw_x, -draw_y); - - /* Store damage region if needed after submission. */ - if (pDamage->reportAfter || pDamage->damageMarker) - RegionUnion(&pDamage->pendingDamage, - &pDamage->pendingDamage, pDamageRegion); - - /* Duplicate current damage if needed. */ - if (pDamage->damageMarker) - RegionCopy(&pDamage->backupDamage, &pDamage->damage); - - /* Report damage now, if desired. */ - if (!pDamage->reportAfter) { - if (pDamage->damageReport) - DamageReportDamage (pDamage, pDamageRegion); - else - RegionUnion(&pDamage->damage, - &pDamage->damage, pDamageRegion); - } - - /* - * translate original region back - */ - if (pDamageRegion == pRegion && (draw_x || draw_y)) - RegionTranslate(pDamageRegion, draw_x, draw_y); + + /* + * Clip against border or pixmap bounds + */ + + pDamageRegion = pRegion; + if (clip || pDamage->pDrawable != pDrawable) { + pDamageRegion = &clippedRec; + if (pDamage->pDrawable->type == DRAWABLE_WINDOW) { + RegionIntersect(pDamageRegion, pRegion, + &((WindowPtr) (pDamage->pDrawable))-> + borderClip); + } + else { + BoxRec box; + + box.x1 = draw_x; + box.y1 = draw_y; + box.x2 = draw_x + pDamage->pDrawable->width; + box.y2 = draw_y + pDamage->pDrawable->height; + RegionInit(&pixClip, &box, 1); + RegionIntersect(pDamageRegion, pRegion, &pixClip); + RegionUninit(&pixClip); + } + /* + * Short circuit empty results + */ + if (!RegionNotEmpty(pDamageRegion)) + continue; + } + + DAMAGE_DEBUG(("%s %d x %d +%d +%d (target 0x%lx monitor 0x%lx)\n", + where, + pDamageRegion->extents.x2 - pDamageRegion->extents.x1, + pDamageRegion->extents.y2 - pDamageRegion->extents.y1, + pDamageRegion->extents.x1, pDamageRegion->extents.y1, + pDrawable->id, pDamage->pDrawable->id)); + + /* + * Move region to target coordinate space + */ + if (draw_x || draw_y) + RegionTranslate(pDamageRegion, -draw_x, -draw_y); + + /* Store damage region if needed after submission. */ + if (pDamage->reportAfter || pDamage->damageMarker) + RegionUnion(&pDamage->pendingDamage, + &pDamage->pendingDamage, pDamageRegion); + + /* Duplicate current damage if needed. */ + if (pDamage->damageMarker) + RegionCopy(&pDamage->backupDamage, &pDamage->damage); + + /* Report damage now, if desired. */ + if (!pDamage->reportAfter) { + if (pDamage->damageReport) + DamageReportDamage(pDamage, pDamageRegion); + else + RegionUnion(&pDamage->damage, &pDamage->damage, pDamageRegion); + } + + /* + * translate original region back + */ + if (pDamageRegion == pRegion && (draw_x || draw_y)) + RegionTranslate(pDamageRegion, draw_x, draw_y); } #ifdef COMPOSITE if (screen_x || screen_y) - RegionTranslate(pRegion, -screen_x, -screen_y); + RegionTranslate(pRegion, -screen_x, -screen_y); #endif - + RegionUninit(&clippedRec); } static void -damageRegionProcessPending (DrawablePtr pDrawable) +damageRegionProcessPending(DrawablePtr pDrawable) { drawableDamage(pDrawable); - for (; pDamage != NULL; pDamage = pDamage->pNext) - { - /* submit damage marker whenever possible. */ - if (pDamage->damageMarker) - (*pDamage->damageMarker) (pDrawable, pDamage, &pDamage->backupDamage, &pDamage->pendingDamage, pDamage->closure); - if (pDamage->reportAfter) { - /* It's possible that there is only interest in postRendering reporting. */ - if (pDamage->damageReport) - DamageReportDamage (pDamage, &pDamage->pendingDamage); - else - RegionUnion(&pDamage->damage, &pDamage->damage, - &pDamage->pendingDamage); - } - - if (pDamage->reportAfter || pDamage->damageMarker) - RegionEmpty(&pDamage->pendingDamage); - if (pDamage->damageMarker) - RegionEmpty(&pDamage->backupDamage); + for (; pDamage != NULL; pDamage = pDamage->pNext) { + /* submit damage marker whenever possible. */ + if (pDamage->damageMarker) + (*pDamage->damageMarker) (pDrawable, pDamage, + &pDamage->backupDamage, + &pDamage->pendingDamage, + pDamage->closure); + if (pDamage->reportAfter) { + /* It's possible that there is only interest in postRendering reporting. */ + if (pDamage->damageReport) + DamageReportDamage(pDamage, &pDamage->pendingDamage); + else + RegionUnion(&pDamage->damage, &pDamage->damage, + &pDamage->pendingDamage); + } + + if (pDamage->reportAfter || pDamage->damageMarker) + RegionEmpty(&pDamage->pendingDamage); + if (pDamage->damageMarker) + RegionEmpty(&pDamage->backupDamage); } - + } #if DAMAGE_DEBUG_ENABLE #define damageDamageBox(d,b,m) _damageDamageBox(d,b,m,__FUNCTION__) static void -_damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode, const char *where) +_damageDamageBox(DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode, + const char *where) #else static void -damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode) +damageDamageBox(DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode) #endif { - RegionRec region; + RegionRec region; RegionInit(®ion, pBox, 1); #if DAMAGE_DEBUG_ENABLE - _damageRegionAppend (pDrawable, ®ion, TRUE, subWindowMode, where); + _damageRegionAppend(pDrawable, ®ion, TRUE, subWindowMode, where); #else - damageRegionAppend (pDrawable, ®ion, TRUE, subWindowMode); + damageRegionAppend(pDrawable, ®ion, TRUE, subWindowMode); #endif RegionUninit(®ion); } @@ -398,17 +401,18 @@ static Bool damageCreateGC(GCPtr pGC) { ScreenPtr pScreen = pGC->pScreen; + damageScrPriv(pScreen); damageGCPriv(pGC); Bool ret; - unwrap (pScrPriv, pScreen, CreateGC); - if((ret = (*pScreen->CreateGC) (pGC))) { - pGCPriv->ops = NULL; - pGCPriv->funcs = pGC->funcs; - pGC->funcs = &damageGCFuncs; + unwrap(pScrPriv, pScreen, CreateGC); + if ((ret = (*pScreen->CreateGC) (pGC))) { + pGCPriv->ops = NULL; + pGCPriv->funcs = pGC->funcs; + pGC->funcs = &damageGCFuncs; } - wrap (pScrPriv, pScreen, CreateGC, damageCreateGC); + wrap(pScrPriv, pScreen, CreateGC, damageCreateGC); return ret; } @@ -433,68 +437,60 @@ damageCreateGC(GCPtr pGC) if (pGCPriv->ops) wrap(pGCPriv, pGC, ops, &damageGCOps) static void -damageValidateGC(GCPtr pGC, - unsigned long changes, - DrawablePtr pDrawable) +damageValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) { - DAMAGE_GC_FUNC_PROLOGUE (pGC); - (*pGC->funcs->ValidateGC)(pGC, changes, pDrawable); - pGCPriv->ops = pGC->ops; /* just so it's not NULL */ - DAMAGE_GC_FUNC_EPILOGUE (pGC); + DAMAGE_GC_FUNC_PROLOGUE(pGC); + (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable); + pGCPriv->ops = pGC->ops; /* just so it's not NULL */ + DAMAGE_GC_FUNC_EPILOGUE(pGC); } static void damageDestroyGC(GCPtr pGC) { - DAMAGE_GC_FUNC_PROLOGUE (pGC); - (*pGC->funcs->DestroyGC)(pGC); - DAMAGE_GC_FUNC_EPILOGUE (pGC); + DAMAGE_GC_FUNC_PROLOGUE(pGC); + (*pGC->funcs->DestroyGC) (pGC); + DAMAGE_GC_FUNC_EPILOGUE(pGC); } static void -damageChangeGC (GCPtr pGC, - unsigned long mask) +damageChangeGC(GCPtr pGC, unsigned long mask) { - DAMAGE_GC_FUNC_PROLOGUE (pGC); + DAMAGE_GC_FUNC_PROLOGUE(pGC); (*pGC->funcs->ChangeGC) (pGC, mask); - DAMAGE_GC_FUNC_EPILOGUE (pGC); + DAMAGE_GC_FUNC_EPILOGUE(pGC); } static void -damageCopyGC (GCPtr pGCSrc, - unsigned long mask, - GCPtr pGCDst) +damageCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst) { - DAMAGE_GC_FUNC_PROLOGUE (pGCDst); + DAMAGE_GC_FUNC_PROLOGUE(pGCDst); (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst); - DAMAGE_GC_FUNC_EPILOGUE (pGCDst); + DAMAGE_GC_FUNC_EPILOGUE(pGCDst); } static void -damageChangeClip (GCPtr pGC, - int type, - pointer pvalue, - int nrects) +damageChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects) { - DAMAGE_GC_FUNC_PROLOGUE (pGC); + DAMAGE_GC_FUNC_PROLOGUE(pGC); (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects); - DAMAGE_GC_FUNC_EPILOGUE (pGC); + DAMAGE_GC_FUNC_EPILOGUE(pGC); } static void damageCopyClip(GCPtr pgcDst, GCPtr pgcSrc) { - DAMAGE_GC_FUNC_PROLOGUE (pgcDst); - (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc); - DAMAGE_GC_FUNC_EPILOGUE (pgcDst); + DAMAGE_GC_FUNC_PROLOGUE(pgcDst); + (*pgcDst->funcs->CopyClip) (pgcDst, pgcSrc); + DAMAGE_GC_FUNC_EPILOGUE(pgcDst); } static void damageDestroyClip(GCPtr pGC) { - DAMAGE_GC_FUNC_PROLOGUE (pGC); - (* pGC->funcs->DestroyClip)(pGC); - DAMAGE_GC_FUNC_EPILOGUE (pGC); + DAMAGE_GC_FUNC_PROLOGUE(pGC); + (*pGC->funcs->DestroyClip) (pGC); + DAMAGE_GC_FUNC_EPILOGUE(pGC); } #define TRIM_BOX(box, pGC) if (pGC->pCompositeClip) { \ @@ -531,825 +527,767 @@ damageDestroyClip(GCPtr pGC) if(box.y1 < extents->y1) box.y1 = extents->y1; \ if(box.y2 > extents->y2) box.y2 = extents->y2; \ } - + #define checkPictureDamage(p) (getDrawableDamage(p->pDrawable) && \ RegionNotEmpty(p->pCompositeClip)) static void -damageComposite (CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, - PicturePtr pDst, - INT16 xSrc, - INT16 ySrc, - INT16 xMask, - INT16 yMask, - INT16 xDst, - INT16 yDst, - CARD16 width, - CARD16 height) -{ - ScreenPtr pScreen = pDst->pDrawable->pScreen; - PictureScreenPtr ps = GetPictureScreen(pScreen); +damageComposite(CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) +{ + ScreenPtr pScreen = pDst->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + damageScrPriv(pScreen); - if (checkPictureDamage (pDst)) - { - BoxRec box; - - box.x1 = xDst + pDst->pDrawable->x; - box.y1 = yDst + pDst->pDrawable->y; - box.x2 = box.x1 + width; - box.y2 = box.y1 + height; - TRIM_PICTURE_BOX(box, pDst); - if (BOX_NOT_EMPTY(box)) - damageDamageBox (pDst->pDrawable, &box, pDst->subWindowMode); + if (checkPictureDamage(pDst)) { + BoxRec box; + + box.x1 = xDst + pDst->pDrawable->x; + box.y1 = yDst + pDst->pDrawable->y; + box.x2 = box.x1 + width; + box.y2 = box.y1 + height; + TRIM_PICTURE_BOX(box, pDst); + if (BOX_NOT_EMPTY(box)) + damageDamageBox(pDst->pDrawable, &box, pDst->subWindowMode); } - unwrap (pScrPriv, ps, Composite); + unwrap(pScrPriv, ps, Composite); (*ps->Composite) (op, - pSrc, - pMask, - pDst, - xSrc, - ySrc, - xMask, - yMask, - xDst, - yDst, - width, - height); - damageRegionProcessPending (pDst->pDrawable); - wrap (pScrPriv, ps, Composite, damageComposite); + pSrc, + pMask, + pDst, + xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); + damageRegionProcessPending(pDst->pDrawable); + wrap(pScrPriv, ps, Composite, damageComposite); } static void -damageGlyphs (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int nlist, - GlyphListPtr list, - GlyphPtr *glyphs) -{ - ScreenPtr pScreen = pDst->pDrawable->pScreen; - PictureScreenPtr ps = GetPictureScreen(pScreen); +damageGlyphs(CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs) +{ + ScreenPtr pScreen = pDst->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + damageScrPriv(pScreen); - if (checkPictureDamage (pDst)) - { - int nlistTmp = nlist; - GlyphListPtr listTmp = list; - GlyphPtr *glyphsTmp = glyphs; - int x, y; - int n; - GlyphPtr glyph; - BoxRec box; - int x1, y1, x2, y2; - - box.x1 = 32767; - box.y1 = 32767; - box.x2 = -32767; - box.y2 = -32767; - x = pDst->pDrawable->x; - y = pDst->pDrawable->y; - while (nlistTmp--) - { - x += listTmp->xOff; - y += listTmp->yOff; - n = listTmp->len; - while (n--) - { - glyph = *glyphsTmp++; - x1 = x - glyph->info.x; - y1 = y - glyph->info.y; - x2 = x1 + glyph->info.width; - y2 = y1 + glyph->info.height; - if (x1 < box.x1) - box.x1 = x1; - if (y1 < box.y1) - box.y1 = y1; - if (x2 > box.x2) - box.x2 = x2; - if (y2 > box.y2) - box.y2 = y2; - x += glyph->info.xOff; - y += glyph->info.yOff; - } - listTmp++; - } - TRIM_PICTURE_BOX (box, pDst); - if (BOX_NOT_EMPTY(box)) - damageDamageBox (pDst->pDrawable, &box, pDst->subWindowMode); + if (checkPictureDamage(pDst)) { + int nlistTmp = nlist; + GlyphListPtr listTmp = list; + GlyphPtr *glyphsTmp = glyphs; + int x, y; + int n; + GlyphPtr glyph; + BoxRec box; + int x1, y1, x2, y2; + + box.x1 = 32767; + box.y1 = 32767; + box.x2 = -32767; + box.y2 = -32767; + x = pDst->pDrawable->x; + y = pDst->pDrawable->y; + while (nlistTmp--) { + x += listTmp->xOff; + y += listTmp->yOff; + n = listTmp->len; + while (n--) { + glyph = *glyphsTmp++; + x1 = x - glyph->info.x; + y1 = y - glyph->info.y; + x2 = x1 + glyph->info.width; + y2 = y1 + glyph->info.height; + if (x1 < box.x1) + box.x1 = x1; + if (y1 < box.y1) + box.y1 = y1; + if (x2 > box.x2) + box.x2 = x2; + if (y2 > box.y2) + box.y2 = y2; + x += glyph->info.xOff; + y += glyph->info.yOff; + } + listTmp++; + } + TRIM_PICTURE_BOX(box, pDst); + if (BOX_NOT_EMPTY(box)) + damageDamageBox(pDst->pDrawable, &box, pDst->subWindowMode); } - unwrap (pScrPriv, ps, Glyphs); + unwrap(pScrPriv, ps, Glyphs); (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs); - damageRegionProcessPending (pDst->pDrawable); - wrap (pScrPriv, ps, Glyphs, damageGlyphs); + damageRegionProcessPending(pDst->pDrawable); + wrap(pScrPriv, ps, Glyphs, damageGlyphs); } static void -damageAddTraps (PicturePtr pPicture, - INT16 x_off, - INT16 y_off, - int ntrap, - xTrap *traps) -{ - ScreenPtr pScreen = pPicture->pDrawable->pScreen; - PictureScreenPtr ps = GetPictureScreen(pScreen); +damageAddTraps(PicturePtr pPicture, + INT16 x_off, INT16 y_off, int ntrap, xTrap * traps) +{ + ScreenPtr pScreen = pPicture->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + damageScrPriv(pScreen); - if (checkPictureDamage (pPicture)) - { - BoxRec box; - int i; - int x, y; - xTrap *t = traps; - - box.x1 = 32767; - box.y1 = 32767; - box.x2 = -32767; - box.y2 = -32767; - x = pPicture->pDrawable->x + x_off; - y = pPicture->pDrawable->y + y_off; - for (i = 0; i < ntrap; i++) - { - pixman_fixed_t l = min (t->top.l, t->bot.l); - pixman_fixed_t r = max (t->top.r, t->bot.r); - int x1 = x + pixman_fixed_to_int (l); - int x2 = x + pixman_fixed_to_int (pixman_fixed_ceil (r)); - int y1 = y + pixman_fixed_to_int (t->top.y); - int y2 = y + pixman_fixed_to_int (pixman_fixed_ceil (t->bot.y)); - - if (x1 < box.x1) - box.x1 = x1; - if (x2 > box.x2) - box.x2 = x2; - if (y1 < box.y1) - box.y1 = y1; - if (y2 > box.y2) - box.y2 = y2; - } - TRIM_PICTURE_BOX (box, pPicture); - if (BOX_NOT_EMPTY(box)) - damageDamageBox (pPicture->pDrawable, &box, pPicture->subWindowMode); + if (checkPictureDamage(pPicture)) { + BoxRec box; + int i; + int x, y; + xTrap *t = traps; + + box.x1 = 32767; + box.y1 = 32767; + box.x2 = -32767; + box.y2 = -32767; + x = pPicture->pDrawable->x + x_off; + y = pPicture->pDrawable->y + y_off; + for (i = 0; i < ntrap; i++) { + pixman_fixed_t l = min(t->top.l, t->bot.l); + pixman_fixed_t r = max(t->top.r, t->bot.r); + int x1 = x + pixman_fixed_to_int(l); + int x2 = x + pixman_fixed_to_int(pixman_fixed_ceil(r)); + int y1 = y + pixman_fixed_to_int(t->top.y); + int y2 = y + pixman_fixed_to_int(pixman_fixed_ceil(t->bot.y)); + + if (x1 < box.x1) + box.x1 = x1; + if (x2 > box.x2) + box.x2 = x2; + if (y1 < box.y1) + box.y1 = y1; + if (y2 > box.y2) + box.y2 = y2; + } + TRIM_PICTURE_BOX(box, pPicture); + if (BOX_NOT_EMPTY(box)) + damageDamageBox(pPicture->pDrawable, &box, pPicture->subWindowMode); } - unwrap (pScrPriv, ps, AddTraps); + unwrap(pScrPriv, ps, AddTraps); (*ps->AddTraps) (pPicture, x_off, y_off, ntrap, traps); - damageRegionProcessPending (pPicture->pDrawable); - wrap (pScrPriv, ps, AddTraps, damageAddTraps); + damageRegionProcessPending(pPicture->pDrawable); + wrap(pScrPriv, ps, AddTraps, damageAddTraps); } /**********************************************************/ - static void damageFillSpans(DrawablePtr pDrawable, - GC *pGC, - int npt, - DDXPointPtr ppt, - int *pwidth, - int fSorted) + GC * pGC, int npt, DDXPointPtr ppt, int *pwidth, int fSorted) { DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - if (npt && checkGCDamage (pDrawable, pGC)) - { - int nptTmp = npt; - DDXPointPtr pptTmp = ppt; - int *pwidthTmp = pwidth; - BoxRec box; - - box.x1 = pptTmp->x; - box.x2 = box.x1 + *pwidthTmp; - box.y2 = box.y1 = pptTmp->y; - - while(--nptTmp) - { - pptTmp++; - pwidthTmp++; - if(box.x1 > pptTmp->x) box.x1 = pptTmp->x; - if(box.x2 < (pptTmp->x + *pwidthTmp)) - box.x2 = pptTmp->x + *pwidthTmp; - if(box.y1 > pptTmp->y) box.y1 = pptTmp->y; - else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y; - } - - box.y2++; - - if(!pGC->miTranslate) { - TRANSLATE_BOX(box, pDrawable); + if (npt && checkGCDamage(pDrawable, pGC)) { + int nptTmp = npt; + DDXPointPtr pptTmp = ppt; + int *pwidthTmp = pwidth; + BoxRec box; + + box.x1 = pptTmp->x; + box.x2 = box.x1 + *pwidthTmp; + box.y2 = box.y1 = pptTmp->y; + + while (--nptTmp) { + pptTmp++; + pwidthTmp++; + if (box.x1 > pptTmp->x) + box.x1 = pptTmp->x; + if (box.x2 < (pptTmp->x + *pwidthTmp)) + box.x2 = pptTmp->x + *pwidthTmp; + if (box.y1 > pptTmp->y) + box.y1 = pptTmp->y; + else if (box.y2 < pptTmp->y) + box.y2 = pptTmp->y; } - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); + box.y2++; + + if (!pGC->miTranslate) { + TRANSLATE_BOX(box, pDrawable); + } + TRIM_BOX(box, pGC); + + if (BOX_NOT_EMPTY(box)) + damageDamageBox(pDrawable, &box, pGC->subWindowMode); } - - (*pGC->ops->FillSpans)(pDrawable, pGC, npt, ppt, pwidth, fSorted); - damageRegionProcessPending (pDrawable); + (*pGC->ops->FillSpans) (pDrawable, pGC, npt, ppt, pwidth, fSorted); + + damageRegionProcessPending(pDrawable); DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); } static void -damageSetSpans(DrawablePtr pDrawable, - GCPtr pGC, - char *pcharsrc, - DDXPointPtr ppt, - int *pwidth, - int npt, - int fSorted) +damageSetSpans(DrawablePtr pDrawable, + GCPtr pGC, + char *pcharsrc, + DDXPointPtr ppt, int *pwidth, int npt, int fSorted) { DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - if (npt && checkGCDamage (pDrawable, pGC)) - { - DDXPointPtr pptTmp = ppt; - int *pwidthTmp = pwidth; - int nptTmp = npt; - BoxRec box; - - box.x1 = pptTmp->x; - box.x2 = box.x1 + *pwidthTmp; - box.y2 = box.y1 = pptTmp->y; - - while(--nptTmp) - { - pptTmp++; - pwidthTmp++; - if(box.x1 > pptTmp->x) box.x1 = pptTmp->x; - if(box.x2 < (pptTmp->x + *pwidthTmp)) - box.x2 = pptTmp->x + *pwidthTmp; - if(box.y1 > pptTmp->y) box.y1 = pptTmp->y; - else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y; - } - - box.y2++; - - if(!pGC->miTranslate) { - TRANSLATE_BOX(box, pDrawable); + if (npt && checkGCDamage(pDrawable, pGC)) { + DDXPointPtr pptTmp = ppt; + int *pwidthTmp = pwidth; + int nptTmp = npt; + BoxRec box; + + box.x1 = pptTmp->x; + box.x2 = box.x1 + *pwidthTmp; + box.y2 = box.y1 = pptTmp->y; + + while (--nptTmp) { + pptTmp++; + pwidthTmp++; + if (box.x1 > pptTmp->x) + box.x1 = pptTmp->x; + if (box.x2 < (pptTmp->x + *pwidthTmp)) + box.x2 = pptTmp->x + *pwidthTmp; + if (box.y1 > pptTmp->y) + box.y1 = pptTmp->y; + else if (box.y2 < pptTmp->y) + box.y2 = pptTmp->y; } - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); + box.y2++; + + if (!pGC->miTranslate) { + TRANSLATE_BOX(box, pDrawable); + } + TRIM_BOX(box, pGC); + + if (BOX_NOT_EMPTY(box)) + damageDamageBox(pDrawable, &box, pGC->subWindowMode); } - (*pGC->ops->SetSpans)(pDrawable, pGC, pcharsrc, ppt, pwidth, npt, fSorted); - damageRegionProcessPending (pDrawable); + (*pGC->ops->SetSpans) (pDrawable, pGC, pcharsrc, ppt, pwidth, npt, fSorted); + damageRegionProcessPending(pDrawable); DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); } static void -damagePutImage(DrawablePtr pDrawable, - GCPtr pGC, - int depth, - int x, - int y, - int w, - int h, - int leftPad, - int format, - char *pImage) +damagePutImage(DrawablePtr pDrawable, + GCPtr pGC, + int depth, + int x, + int y, int w, int h, int leftPad, int format, char *pImage) { DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - if (checkGCDamage (pDrawable, pGC)) - { - BoxRec box; - - box.x1 = x + pDrawable->x; - box.x2 = box.x1 + w; - box.y1 = y + pDrawable->y; - box.y2 = box.y1 + h; - - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); + if (checkGCDamage(pDrawable, pGC)) { + BoxRec box; + + box.x1 = x + pDrawable->x; + box.x2 = box.x1 + w; + box.y1 = y + pDrawable->y; + box.y2 = box.y1 + h; + + TRIM_BOX(box, pGC); + if (BOX_NOT_EMPTY(box)) + damageDamageBox(pDrawable, &box, pGC->subWindowMode); } - (*pGC->ops->PutImage)(pDrawable, pGC, depth, x, y, w, h, - leftPad, format, pImage); - damageRegionProcessPending (pDrawable); + (*pGC->ops->PutImage) (pDrawable, pGC, depth, x, y, w, h, + leftPad, format, pImage); + damageRegionProcessPending(pDrawable); DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); } static RegionPtr -damageCopyArea(DrawablePtr pSrc, - DrawablePtr pDst, - GC *pGC, - int srcx, - int srcy, - int width, - int height, - int dstx, - int dsty) +damageCopyArea(DrawablePtr pSrc, + DrawablePtr pDst, + GC * pGC, + int srcx, int srcy, int width, int height, int dstx, int dsty) { RegionPtr ret; + DAMAGE_GC_OP_PROLOGUE(pGC, pDst); - - if (checkGCDamage (pDst, pGC)) - { - BoxRec box; - - box.x1 = dstx + pDst->x; - box.x2 = box.x1 + width; - box.y1 = dsty + pDst->y; - box.y2 = box.y1 + height; - - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDst, &box, pGC->subWindowMode); + + if (checkGCDamage(pDst, pGC)) { + BoxRec box; + + box.x1 = dstx + pDst->x; + box.x2 = box.x1 + width; + box.y1 = dsty + pDst->y; + box.y2 = box.y1 + height; + + TRIM_BOX(box, pGC); + if (BOX_NOT_EMPTY(box)) + damageDamageBox(pDst, &box, pGC->subWindowMode); } - ret = (*pGC->ops->CopyArea)(pSrc, pDst, - pGC, srcx, srcy, width, height, dstx, dsty); - damageRegionProcessPending (pDst); + ret = (*pGC->ops->CopyArea) (pSrc, pDst, + pGC, srcx, srcy, width, height, dstx, dsty); + damageRegionProcessPending(pDst); DAMAGE_GC_OP_EPILOGUE(pGC, pDst); return ret; } static RegionPtr -damageCopyPlane(DrawablePtr pSrc, - DrawablePtr pDst, - GCPtr pGC, - int srcx, - int srcy, - int width, - int height, - int dstx, - int dsty, - unsigned long bitPlane) +damageCopyPlane(DrawablePtr pSrc, + DrawablePtr pDst, + GCPtr pGC, + int srcx, + int srcy, + int width, + int height, int dstx, int dsty, unsigned long bitPlane) { RegionPtr ret; + DAMAGE_GC_OP_PROLOGUE(pGC, pDst); - if (checkGCDamage (pDst, pGC)) - { - BoxRec box; + if (checkGCDamage(pDst, pGC)) { + BoxRec box; - box.x1 = dstx + pDst->x; - box.x2 = box.x1 + width; - box.y1 = dsty + pDst->y; - box.y2 = box.y1 + height; + box.x1 = dstx + pDst->x; + box.x2 = box.x1 + width; + box.y1 = dsty + pDst->y; + box.y2 = box.y1 + height; - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDst, &box, pGC->subWindowMode); + TRIM_BOX(box, pGC); + if (BOX_NOT_EMPTY(box)) + damageDamageBox(pDst, &box, pGC->subWindowMode); } - ret = (*pGC->ops->CopyPlane)(pSrc, pDst, - pGC, srcx, srcy, width, height, dstx, dsty, bitPlane); - damageRegionProcessPending (pDst); + ret = (*pGC->ops->CopyPlane) (pSrc, pDst, + pGC, srcx, srcy, width, height, dstx, dsty, + bitPlane); + damageRegionProcessPending(pDst); DAMAGE_GC_OP_EPILOGUE(pGC, pDst); return ret; } static void damagePolyPoint(DrawablePtr pDrawable, - GCPtr pGC, - int mode, - int npt, - xPoint *ppt) + GCPtr pGC, int mode, int npt, xPoint * ppt) { DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - if (npt && checkGCDamage (pDrawable, pGC)) - { - BoxRec box; - int nptTmp = npt; - xPoint *pptTmp = ppt; - - box.x2 = box.x1 = pptTmp->x; - box.y2 = box.y1 = pptTmp->y; - - /* this could be slow if the points were spread out */ - - while(--nptTmp) - { - pptTmp++; - if(box.x1 > pptTmp->x) box.x1 = pptTmp->x; - else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x; - if(box.y1 > pptTmp->y) box.y1 = pptTmp->y; - else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y; - } + if (npt && checkGCDamage(pDrawable, pGC)) { + BoxRec box; + int nptTmp = npt; + xPoint *pptTmp = ppt; + + box.x2 = box.x1 = pptTmp->x; + box.y2 = box.y1 = pptTmp->y; + + /* this could be slow if the points were spread out */ + + while (--nptTmp) { + pptTmp++; + if (box.x1 > pptTmp->x) + box.x1 = pptTmp->x; + else if (box.x2 < pptTmp->x) + box.x2 = pptTmp->x; + if (box.y1 > pptTmp->y) + box.y1 = pptTmp->y; + else if (box.y2 < pptTmp->y) + box.y2 = pptTmp->y; + } - box.x2++; - box.y2++; + box.x2++; + box.y2++; - TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); + TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); + if (BOX_NOT_EMPTY(box)) + damageDamageBox(pDrawable, &box, pGC->subWindowMode); } - (*pGC->ops->PolyPoint)(pDrawable, pGC, mode, npt, ppt); - damageRegionProcessPending (pDrawable); + (*pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, ppt); + damageRegionProcessPending(pDrawable); DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); } static void damagePolylines(DrawablePtr pDrawable, - GCPtr pGC, - int mode, - int npt, - DDXPointPtr ppt) + GCPtr pGC, int mode, int npt, DDXPointPtr ppt) { DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - if (npt && checkGCDamage (pDrawable, pGC)) - { - int nptTmp = npt; - DDXPointPtr pptTmp = ppt; - BoxRec box; - int extra = pGC->lineWidth >> 1; - - box.x2 = box.x1 = pptTmp->x; - box.y2 = box.y1 = pptTmp->y; - - if(nptTmp > 1) - { - if(pGC->joinStyle == JoinMiter) - extra = 6 * pGC->lineWidth; - else if(pGC->capStyle == CapProjecting) - extra = pGC->lineWidth; + if (npt && checkGCDamage(pDrawable, pGC)) { + int nptTmp = npt; + DDXPointPtr pptTmp = ppt; + BoxRec box; + int extra = pGC->lineWidth >> 1; + + box.x2 = box.x1 = pptTmp->x; + box.y2 = box.y1 = pptTmp->y; + + if (nptTmp > 1) { + if (pGC->joinStyle == JoinMiter) + extra = 6 * pGC->lineWidth; + else if (pGC->capStyle == CapProjecting) + extra = pGC->lineWidth; } - if(mode == CoordModePrevious) - { - int x = box.x1; - int y = box.y1; - while(--nptTmp) - { - pptTmp++; - x += pptTmp->x; - y += pptTmp->y; - if(box.x1 > x) box.x1 = x; - else if(box.x2 < x) box.x2 = x; - if(box.y1 > y) box.y1 = y; - else if(box.y2 < y) box.y2 = y; - } - } - else - { - while(--nptTmp) - { - pptTmp++; - if(box.x1 > pptTmp->x) box.x1 = pptTmp->x; - else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x; - if(box.y1 > pptTmp->y) box.y1 = pptTmp->y; - else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y; - } - } - - box.x2++; - box.y2++; - - if(extra) - { - box.x1 -= extra; - box.x2 += extra; - box.y1 -= extra; - box.y2 += extra; + if (mode == CoordModePrevious) { + int x = box.x1; + int y = box.y1; + + while (--nptTmp) { + pptTmp++; + x += pptTmp->x; + y += pptTmp->y; + if (box.x1 > x) + box.x1 = x; + else if (box.x2 < x) + box.x2 = x; + if (box.y1 > y) + box.y1 = y; + else if (box.y2 < y) + box.y2 = y; + } } + else { + while (--nptTmp) { + pptTmp++; + if (box.x1 > pptTmp->x) + box.x1 = pptTmp->x; + else if (box.x2 < pptTmp->x) + box.x2 = pptTmp->x; + if (box.y1 > pptTmp->y) + box.y1 = pptTmp->y; + else if (box.y2 < pptTmp->y) + box.y2 = pptTmp->y; + } + } + + box.x2++; + box.y2++; - TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); + if (extra) { + box.x1 -= extra; + box.x2 += extra; + box.y1 -= extra; + box.y2 += extra; + } + + TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); + if (BOX_NOT_EMPTY(box)) + damageDamageBox(pDrawable, &box, pGC->subWindowMode); } - (*pGC->ops->Polylines)(pDrawable, pGC, mode, npt, ppt); - damageRegionProcessPending (pDrawable); + (*pGC->ops->Polylines) (pDrawable, pGC, mode, npt, ppt); + damageRegionProcessPending(pDrawable); DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); } static void -damagePolySegment(DrawablePtr pDrawable, - GCPtr pGC, - int nSeg, - xSegment *pSeg) +damagePolySegment(DrawablePtr pDrawable, GCPtr pGC, int nSeg, xSegment * pSeg) { DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - if (nSeg && checkGCDamage (pDrawable, pGC)) - { - BoxRec box; - int extra = pGC->lineWidth; - int nsegTmp = nSeg; - xSegment *pSegTmp = pSeg; - - if(pGC->capStyle != CapProjecting) - extra >>= 1; - - if(pSegTmp->x2 > pSegTmp->x1) { - box.x1 = pSegTmp->x1; - box.x2 = pSegTmp->x2; - } else { - box.x2 = pSegTmp->x1; - box.x1 = pSegTmp->x2; - } - - if(pSegTmp->y2 > pSegTmp->y1) { - box.y1 = pSegTmp->y1; - box.y2 = pSegTmp->y2; - } else { - box.y2 = pSegTmp->y1; - box.y1 = pSegTmp->y2; - } - - while(--nsegTmp) - { - pSegTmp++; - if(pSegTmp->x2 > pSegTmp->x1) - { - if(pSegTmp->x1 < box.x1) box.x1 = pSegTmp->x1; - if(pSegTmp->x2 > box.x2) box.x2 = pSegTmp->x2; - } - else - { - if(pSegTmp->x2 < box.x1) box.x1 = pSegTmp->x2; - if(pSegTmp->x1 > box.x2) box.x2 = pSegTmp->x1; - } - if(pSegTmp->y2 > pSegTmp->y1) - { - if(pSegTmp->y1 < box.y1) box.y1 = pSegTmp->y1; - if(pSegTmp->y2 > box.y2) box.y2 = pSegTmp->y2; - } - else - { - if(pSegTmp->y2 < box.y1) box.y1 = pSegTmp->y2; - if(pSegTmp->y1 > box.y2) box.y2 = pSegTmp->y1; - } - } - - box.x2++; - box.y2++; - - if(extra) - { - box.x1 -= extra; - box.x2 += extra; - box.y1 -= extra; - box.y2 += extra; + if (nSeg && checkGCDamage(pDrawable, pGC)) { + BoxRec box; + int extra = pGC->lineWidth; + int nsegTmp = nSeg; + xSegment *pSegTmp = pSeg; + + if (pGC->capStyle != CapProjecting) + extra >>= 1; + + if (pSegTmp->x2 > pSegTmp->x1) { + box.x1 = pSegTmp->x1; + box.x2 = pSegTmp->x2; + } + else { + box.x2 = pSegTmp->x1; + box.x1 = pSegTmp->x2; + } + + if (pSegTmp->y2 > pSegTmp->y1) { + box.y1 = pSegTmp->y1; + box.y2 = pSegTmp->y2; + } + else { + box.y2 = pSegTmp->y1; + box.y1 = pSegTmp->y2; + } + + while (--nsegTmp) { + pSegTmp++; + if (pSegTmp->x2 > pSegTmp->x1) { + if (pSegTmp->x1 < box.x1) + box.x1 = pSegTmp->x1; + if (pSegTmp->x2 > box.x2) + box.x2 = pSegTmp->x2; + } + else { + if (pSegTmp->x2 < box.x1) + box.x1 = pSegTmp->x2; + if (pSegTmp->x1 > box.x2) + box.x2 = pSegTmp->x1; + } + if (pSegTmp->y2 > pSegTmp->y1) { + if (pSegTmp->y1 < box.y1) + box.y1 = pSegTmp->y1; + if (pSegTmp->y2 > box.y2) + box.y2 = pSegTmp->y2; + } + else { + if (pSegTmp->y2 < box.y1) + box.y1 = pSegTmp->y2; + if (pSegTmp->y1 > box.y2) + box.y2 = pSegTmp->y1; + } + } + + box.x2++; + box.y2++; + + if (extra) { + box.x1 -= extra; + box.x2 += extra; + box.y1 -= extra; + box.y2 += extra; } - TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); + TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); + if (BOX_NOT_EMPTY(box)) + damageDamageBox(pDrawable, &box, pGC->subWindowMode); } - (*pGC->ops->PolySegment)(pDrawable, pGC, nSeg, pSeg); - damageRegionProcessPending (pDrawable); + (*pGC->ops->PolySegment) (pDrawable, pGC, nSeg, pSeg); + damageRegionProcessPending(pDrawable); DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); } static void -damagePolyRectangle(DrawablePtr pDrawable, - GCPtr pGC, - int nRects, - xRectangle *pRects) +damagePolyRectangle(DrawablePtr pDrawable, + GCPtr pGC, int nRects, xRectangle *pRects) { DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - if (nRects && checkGCDamage (pDrawable, pGC)) - { - BoxRec box; - int offset1, offset2, offset3; - int nRectsTmp = nRects; - xRectangle *pRectsTmp = pRects; - - offset2 = pGC->lineWidth; - if(!offset2) offset2 = 1; - offset1 = offset2 >> 1; - offset3 = offset2 - offset1; - - while(nRectsTmp--) - { - box.x1 = pRectsTmp->x - offset1; - box.y1 = pRectsTmp->y - offset1; - box.x2 = box.x1 + pRectsTmp->width + offset2; - box.y2 = box.y1 + offset2; - TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); - - box.x1 = pRectsTmp->x - offset1; - box.y1 = pRectsTmp->y + offset3; - box.x2 = box.x1 + offset2; - box.y2 = box.y1 + pRectsTmp->height - offset2; - TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); - - box.x1 = pRectsTmp->x + pRectsTmp->width - offset1; - box.y1 = pRectsTmp->y + offset3; - box.x2 = box.x1 + offset2; - box.y2 = box.y1 + pRectsTmp->height - offset2; - TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); - - box.x1 = pRectsTmp->x - offset1; - box.y1 = pRectsTmp->y + pRectsTmp->height - offset1; - box.x2 = box.x1 + pRectsTmp->width + offset2; - box.y2 = box.y1 + offset2; - TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); - - pRectsTmp++; - } + if (nRects && checkGCDamage(pDrawable, pGC)) { + BoxRec box; + int offset1, offset2, offset3; + int nRectsTmp = nRects; + xRectangle *pRectsTmp = pRects; + + offset2 = pGC->lineWidth; + if (!offset2) + offset2 = 1; + offset1 = offset2 >> 1; + offset3 = offset2 - offset1; + + while (nRectsTmp--) { + box.x1 = pRectsTmp->x - offset1; + box.y1 = pRectsTmp->y - offset1; + box.x2 = box.x1 + pRectsTmp->width + offset2; + box.y2 = box.y1 + offset2; + TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); + if (BOX_NOT_EMPTY(box)) + damageDamageBox(pDrawable, &box, pGC->subWindowMode); + + box.x1 = pRectsTmp->x - offset1; + box.y1 = pRectsTmp->y + offset3; + box.x2 = box.x1 + offset2; + box.y2 = box.y1 + pRectsTmp->height - offset2; + TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); + if (BOX_NOT_EMPTY(box)) + damageDamageBox(pDrawable, &box, pGC->subWindowMode); + + box.x1 = pRectsTmp->x + pRectsTmp->width - offset1; + box.y1 = pRectsTmp->y + offset3; + box.x2 = box.x1 + offset2; + box.y2 = box.y1 + pRectsTmp->height - offset2; + TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); + if (BOX_NOT_EMPTY(box)) + damageDamageBox(pDrawable, &box, pGC->subWindowMode); + + box.x1 = pRectsTmp->x - offset1; + box.y1 = pRectsTmp->y + pRectsTmp->height - offset1; + box.x2 = box.x1 + pRectsTmp->width + offset2; + box.y2 = box.y1 + offset2; + TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); + if (BOX_NOT_EMPTY(box)) + damageDamageBox(pDrawable, &box, pGC->subWindowMode); + + pRectsTmp++; + } } - (*pGC->ops->PolyRectangle)(pDrawable, pGC, nRects, pRects); - damageRegionProcessPending (pDrawable); + (*pGC->ops->PolyRectangle) (pDrawable, pGC, nRects, pRects); + damageRegionProcessPending(pDrawable); DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); } static void -damagePolyArc(DrawablePtr pDrawable, - GCPtr pGC, - int nArcs, - xArc *pArcs) +damagePolyArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, xArc * pArcs) { DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - if (nArcs && checkGCDamage (pDrawable, pGC)) - { - int extra = pGC->lineWidth >> 1; - BoxRec box; - int nArcsTmp = nArcs; - xArc *pArcsTmp = pArcs; - - box.x1 = pArcsTmp->x; - box.x2 = box.x1 + pArcsTmp->width; - box.y1 = pArcsTmp->y; - box.y2 = box.y1 + pArcsTmp->height; - - while(--nArcsTmp) - { - pArcsTmp++; - if(box.x1 > pArcsTmp->x) - box.x1 = pArcsTmp->x; - if(box.x2 < (pArcsTmp->x + pArcsTmp->width)) - box.x2 = pArcsTmp->x + pArcsTmp->width; - if(box.y1 > pArcsTmp->y) - box.y1 = pArcsTmp->y; - if(box.y2 < (pArcsTmp->y + pArcsTmp->height)) - box.y2 = pArcsTmp->y + pArcsTmp->height; + if (nArcs && checkGCDamage(pDrawable, pGC)) { + int extra = pGC->lineWidth >> 1; + BoxRec box; + int nArcsTmp = nArcs; + xArc *pArcsTmp = pArcs; + + box.x1 = pArcsTmp->x; + box.x2 = box.x1 + pArcsTmp->width; + box.y1 = pArcsTmp->y; + box.y2 = box.y1 + pArcsTmp->height; + + while (--nArcsTmp) { + pArcsTmp++; + if (box.x1 > pArcsTmp->x) + box.x1 = pArcsTmp->x; + if (box.x2 < (pArcsTmp->x + pArcsTmp->width)) + box.x2 = pArcsTmp->x + pArcsTmp->width; + if (box.y1 > pArcsTmp->y) + box.y1 = pArcsTmp->y; + if (box.y2 < (pArcsTmp->y + pArcsTmp->height)) + box.y2 = pArcsTmp->y + pArcsTmp->height; } - if(extra) - { - box.x1 -= extra; - box.x2 += extra; - box.y1 -= extra; - box.y2 += extra; + if (extra) { + box.x1 -= extra; + box.x2 += extra; + box.y1 -= extra; + box.y2 += extra; } - box.x2++; - box.y2++; + box.x2++; + box.y2++; - TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); + TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); + if (BOX_NOT_EMPTY(box)) + damageDamageBox(pDrawable, &box, pGC->subWindowMode); } - (*pGC->ops->PolyArc)(pDrawable, pGC, nArcs, pArcs); - damageRegionProcessPending (pDrawable); + (*pGC->ops->PolyArc) (pDrawable, pGC, nArcs, pArcs); + damageRegionProcessPending(pDrawable); DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); } static void -damageFillPolygon(DrawablePtr pDrawable, - GCPtr pGC, - int shape, - int mode, - int npt, - DDXPointPtr ppt) +damageFillPolygon(DrawablePtr pDrawable, + GCPtr pGC, int shape, int mode, int npt, DDXPointPtr ppt) { DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - if (npt > 2 && checkGCDamage (pDrawable, pGC)) - { - DDXPointPtr pptTmp = ppt; - int nptTmp = npt; - BoxRec box; - - box.x2 = box.x1 = pptTmp->x; - box.y2 = box.y1 = pptTmp->y; - - if(mode != CoordModeOrigin) - { - int x = box.x1; - int y = box.y1; - while(--nptTmp) - { - pptTmp++; - x += pptTmp->x; - y += pptTmp->y; - if(box.x1 > x) box.x1 = x; - else if(box.x2 < x) box.x2 = x; - if(box.y1 > y) box.y1 = y; - else if(box.y2 < y) box.y2 = y; - } - } - else - { - while(--nptTmp) - { - pptTmp++; - if(box.x1 > pptTmp->x) box.x1 = pptTmp->x; - else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x; - if(box.y1 > pptTmp->y) box.y1 = pptTmp->y; - else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y; - } - } - - box.x2++; - box.y2++; - - TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); + if (npt > 2 && checkGCDamage(pDrawable, pGC)) { + DDXPointPtr pptTmp = ppt; + int nptTmp = npt; + BoxRec box; + + box.x2 = box.x1 = pptTmp->x; + box.y2 = box.y1 = pptTmp->y; + + if (mode != CoordModeOrigin) { + int x = box.x1; + int y = box.y1; + + while (--nptTmp) { + pptTmp++; + x += pptTmp->x; + y += pptTmp->y; + if (box.x1 > x) + box.x1 = x; + else if (box.x2 < x) + box.x2 = x; + if (box.y1 > y) + box.y1 = y; + else if (box.y2 < y) + box.y2 = y; + } + } + else { + while (--nptTmp) { + pptTmp++; + if (box.x1 > pptTmp->x) + box.x1 = pptTmp->x; + else if (box.x2 < pptTmp->x) + box.x2 = pptTmp->x; + if (box.y1 > pptTmp->y) + box.y1 = pptTmp->y; + else if (box.y2 < pptTmp->y) + box.y2 = pptTmp->y; + } + } + + box.x2++; + box.y2++; + + TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); + if (BOX_NOT_EMPTY(box)) + damageDamageBox(pDrawable, &box, pGC->subWindowMode); } - - (*pGC->ops->FillPolygon)(pDrawable, pGC, shape, mode, npt, ppt); - damageRegionProcessPending (pDrawable); + + (*pGC->ops->FillPolygon) (pDrawable, pGC, shape, mode, npt, ppt); + damageRegionProcessPending(pDrawable); DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); } - static void -damagePolyFillRect(DrawablePtr pDrawable, - GCPtr pGC, - int nRects, - xRectangle *pRects) +damagePolyFillRect(DrawablePtr pDrawable, + GCPtr pGC, int nRects, xRectangle *pRects) { DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - if (nRects && checkGCDamage (pDrawable, pGC)) - { - BoxRec box; - xRectangle *pRectsTmp = pRects; - int nRectsTmp = nRects; - - box.x1 = pRectsTmp->x; - box.x2 = box.x1 + pRectsTmp->width; - box.y1 = pRectsTmp->y; - box.y2 = box.y1 + pRectsTmp->height; - - while(--nRectsTmp) - { - pRectsTmp++; - if(box.x1 > pRectsTmp->x) box.x1 = pRectsTmp->x; - if(box.x2 < (pRectsTmp->x + pRectsTmp->width)) - box.x2 = pRectsTmp->x + pRectsTmp->width; - if(box.y1 > pRectsTmp->y) box.y1 = pRectsTmp->y; - if(box.y2 < (pRectsTmp->y + pRectsTmp->height)) - box.y2 = pRectsTmp->y + pRectsTmp->height; - } - - TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); + if (nRects && checkGCDamage(pDrawable, pGC)) { + BoxRec box; + xRectangle *pRectsTmp = pRects; + int nRectsTmp = nRects; + + box.x1 = pRectsTmp->x; + box.x2 = box.x1 + pRectsTmp->width; + box.y1 = pRectsTmp->y; + box.y2 = box.y1 + pRectsTmp->height; + + while (--nRectsTmp) { + pRectsTmp++; + if (box.x1 > pRectsTmp->x) + box.x1 = pRectsTmp->x; + if (box.x2 < (pRectsTmp->x + pRectsTmp->width)) + box.x2 = pRectsTmp->x + pRectsTmp->width; + if (box.y1 > pRectsTmp->y) + box.y1 = pRectsTmp->y; + if (box.y2 < (pRectsTmp->y + pRectsTmp->height)) + box.y2 = pRectsTmp->y + pRectsTmp->height; + } + + TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); + if (BOX_NOT_EMPTY(box)) + damageDamageBox(pDrawable, &box, pGC->subWindowMode); } - (*pGC->ops->PolyFillRect)(pDrawable, pGC, nRects, pRects); - damageRegionProcessPending (pDrawable); + (*pGC->ops->PolyFillRect) (pDrawable, pGC, nRects, pRects); + damageRegionProcessPending(pDrawable); DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); } - static void -damagePolyFillArc(DrawablePtr pDrawable, - GCPtr pGC, - int nArcs, - xArc *pArcs) +damagePolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, xArc * pArcs) { DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - if (nArcs && checkGCDamage (pDrawable, pGC)) - { - BoxRec box; - int nArcsTmp = nArcs; - xArc *pArcsTmp = pArcs; - - box.x1 = pArcsTmp->x; - box.x2 = box.x1 + pArcsTmp->width; - box.y1 = pArcsTmp->y; - box.y2 = box.y1 + pArcsTmp->height; - - while(--nArcsTmp) - { - pArcsTmp++; - if(box.x1 > pArcsTmp->x) - box.x1 = pArcsTmp->x; - if(box.x2 < (pArcsTmp->x + pArcsTmp->width)) - box.x2 = pArcsTmp->x + pArcsTmp->width; - if(box.y1 > pArcsTmp->y) - box.y1 = pArcsTmp->y; - if(box.y2 < (pArcsTmp->y + pArcsTmp->height)) - box.y2 = pArcsTmp->y + pArcsTmp->height; + if (nArcs && checkGCDamage(pDrawable, pGC)) { + BoxRec box; + int nArcsTmp = nArcs; + xArc *pArcsTmp = pArcs; + + box.x1 = pArcsTmp->x; + box.x2 = box.x1 + pArcsTmp->width; + box.y1 = pArcsTmp->y; + box.y2 = box.y1 + pArcsTmp->height; + + while (--nArcsTmp) { + pArcsTmp++; + if (box.x1 > pArcsTmp->x) + box.x1 = pArcsTmp->x; + if (box.x2 < (pArcsTmp->x + pArcsTmp->width)) + box.x2 = pArcsTmp->x + pArcsTmp->width; + if (box.y1 > pArcsTmp->y) + box.y1 = pArcsTmp->y; + if (box.y2 < (pArcsTmp->y + pArcsTmp->height)) + box.y2 = pArcsTmp->y + pArcsTmp->height; } - TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); + TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); + if (BOX_NOT_EMPTY(box)) + damageDamageBox(pDrawable, &box, pGC->subWindowMode); } - (*pGC->ops->PolyFillArc)(pDrawable, pGC, nArcs, pArcs); - damageRegionProcessPending (pDrawable); + (*pGC->ops->PolyFillArc) (pDrawable, pGC, nArcs, pArcs); + damageRegionProcessPending(pDrawable); DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); } @@ -1359,37 +1297,34 @@ damagePolyFillArc(DrawablePtr pDrawable, */ static void -damageDamageChars (DrawablePtr pDrawable, - FontPtr font, - int x, - int y, - unsigned int n, - CharInfoPtr *charinfo, - Bool imageblt, - int subWindowMode) -{ - ExtentInfoRec extents; - BoxRec box; +damageDamageChars(DrawablePtr pDrawable, + FontPtr font, + int x, + int y, + unsigned int n, + CharInfoPtr * charinfo, Bool imageblt, int subWindowMode) +{ + ExtentInfoRec extents; + BoxRec box; QueryGlyphExtents(font, charinfo, n, &extents); - if (imageblt) - { - if (extents.overallWidth > extents.overallRight) - extents.overallRight = extents.overallWidth; - if (extents.overallWidth < extents.overallLeft) - extents.overallLeft = extents.overallWidth; - if (extents.overallLeft > 0) - extents.overallLeft = 0; - if (extents.fontAscent > extents.overallAscent) - extents.overallAscent = extents.fontAscent; - if (extents.fontDescent > extents.overallDescent) - extents.overallDescent = extents.fontDescent; + if (imageblt) { + if (extents.overallWidth > extents.overallRight) + extents.overallRight = extents.overallWidth; + if (extents.overallWidth < extents.overallLeft) + extents.overallLeft = extents.overallWidth; + if (extents.overallLeft > 0) + extents.overallLeft = 0; + if (extents.fontAscent > extents.overallAscent) + extents.overallAscent = extents.fontAscent; + if (extents.fontDescent > extents.overallDescent) + extents.overallDescent = extents.fontDescent; } box.x1 = x + extents.overallLeft; box.y1 = y - extents.overallAscent; box.x2 = x + extents.overallRight; box.y2 = y + extents.overallDescent; - damageDamageBox (pDrawable, &box, subWindowMode); + damageDamageBox(pDrawable, &box, subWindowMode); } /* @@ -1400,46 +1335,45 @@ damageDamageChars (DrawablePtr pDrawable, #define TT_POLY16 2 #define TT_IMAGE16 3 -static int -damageText (DrawablePtr pDrawable, - GCPtr pGC, - int x, - int y, - unsigned long count, - char *chars, - FontEncoding fontEncoding, - Bool textType) -{ - CharInfoPtr *charinfo; - CharInfoPtr *info; - unsigned long i; - unsigned int n; - int w; - Bool imageblt; +static int +damageText(DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + unsigned long count, + char *chars, FontEncoding fontEncoding, Bool textType) +{ + CharInfoPtr *charinfo; + CharInfoPtr *info; + unsigned long i; + unsigned int n; + int w; + Bool imageblt; imageblt = (textType == TT_IMAGE8) || (textType == TT_IMAGE16); charinfo = malloc(count * sizeof(CharInfoPtr)); if (!charinfo) - return x; + return x; - GetGlyphs(pGC->font, count, (unsigned char *)chars, - fontEncoding, &i, charinfo); - n = (unsigned int)i; + GetGlyphs(pGC->font, count, (unsigned char *) chars, + fontEncoding, &i, charinfo); + n = (unsigned int) i; w = 0; if (!imageblt) - for (info = charinfo; i--; info++) - w += (*info)->metrics.characterWidth; + for (info = charinfo; i--; info++) + w += (*info)->metrics.characterWidth; if (n != 0) { - damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y, n, - charinfo, imageblt, pGC->subWindowMode); - if (imageblt) - (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, n, charinfo, - FONTGLYPHS(pGC->font)); - else - (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, n, charinfo, - FONTGLYPHS(pGC->font)); + damageDamageChars(pDrawable, pGC->font, x + pDrawable->x, + y + pDrawable->y, n, charinfo, imageblt, + pGC->subWindowMode); + if (imageblt) + (*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, n, charinfo, + FONTGLYPHS(pGC->font)); + else + (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, n, charinfo, + FONTGLYPHS(pGC->font)); } free(charinfo); return x + w; @@ -1447,238 +1381,206 @@ damageText (DrawablePtr pDrawable, static int damagePolyText8(DrawablePtr pDrawable, - GCPtr pGC, - int x, - int y, - int count, - char *chars) + GCPtr pGC, int x, int y, int count, char *chars) { DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - if (checkGCDamage (pDrawable, pGC)) - x = damageText (pDrawable, pGC, x, y, (unsigned long) count, chars, - Linear8Bit, TT_POLY8); + if (checkGCDamage(pDrawable, pGC)) + x = damageText(pDrawable, pGC, x, y, (unsigned long) count, chars, + Linear8Bit, TT_POLY8); else - x = (*pGC->ops->PolyText8)(pDrawable, pGC, x, y, count, chars); - damageRegionProcessPending (pDrawable); + x = (*pGC->ops->PolyText8) (pDrawable, pGC, x, y, count, chars); + damageRegionProcessPending(pDrawable); DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); return x; } static int -damagePolyText16(DrawablePtr pDrawable, - GCPtr pGC, - int x, - int y, - int count, - unsigned short *chars) +damagePolyText16(DrawablePtr pDrawable, + GCPtr pGC, int x, int y, int count, unsigned short *chars) { DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - if (checkGCDamage (pDrawable, pGC)) - x = damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars, - FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit, - TT_POLY16); + if (checkGCDamage(pDrawable, pGC)) + x = damageText(pDrawable, pGC, x, y, (unsigned long) count, + (char *) chars, + FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit, + TT_POLY16); else - x = (*pGC->ops->PolyText16)(pDrawable, pGC, x, y, count, chars); - damageRegionProcessPending (pDrawable); + x = (*pGC->ops->PolyText16) (pDrawable, pGC, x, y, count, chars); + damageRegionProcessPending(pDrawable); DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); return x; } static void -damageImageText8(DrawablePtr pDrawable, - GCPtr pGC, - int x, - int y, - int count, - char *chars) +damageImageText8(DrawablePtr pDrawable, + GCPtr pGC, int x, int y, int count, char *chars) { DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - if (checkGCDamage (pDrawable, pGC)) - damageText (pDrawable, pGC, x, y, (unsigned long) count, chars, - Linear8Bit, TT_IMAGE8); + if (checkGCDamage(pDrawable, pGC)) + damageText(pDrawable, pGC, x, y, (unsigned long) count, chars, + Linear8Bit, TT_IMAGE8); else - (*pGC->ops->ImageText8)(pDrawable, pGC, x, y, count, chars); - damageRegionProcessPending (pDrawable); + (*pGC->ops->ImageText8) (pDrawable, pGC, x, y, count, chars); + damageRegionProcessPending(pDrawable); DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); } static void -damageImageText16(DrawablePtr pDrawable, - GCPtr pGC, - int x, - int y, - int count, - unsigned short *chars) +damageImageText16(DrawablePtr pDrawable, + GCPtr pGC, int x, int y, int count, unsigned short *chars) { DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - if (checkGCDamage (pDrawable, pGC)) - damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars, - FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit, - TT_IMAGE16); + if (checkGCDamage(pDrawable, pGC)) + damageText(pDrawable, pGC, x, y, (unsigned long) count, (char *) chars, + FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit, + TT_IMAGE16); else - (*pGC->ops->ImageText16)(pDrawable, pGC, x, y, count, chars); - damageRegionProcessPending (pDrawable); + (*pGC->ops->ImageText16) (pDrawable, pGC, x, y, count, chars); + damageRegionProcessPending(pDrawable); DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); } - static void -damageImageGlyphBlt(DrawablePtr pDrawable, - GCPtr pGC, - int x, - int y, - unsigned int nglyph, - CharInfoPtr *ppci, - pointer pglyphBase) +damageImageGlyphBlt(DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + unsigned int nglyph, CharInfoPtr * ppci, pointer pglyphBase) { DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y, - nglyph, ppci, TRUE, pGC->subWindowMode); - (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, nglyph, - ppci, pglyphBase); - damageRegionProcessPending (pDrawable); + damageDamageChars(pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y, + nglyph, ppci, TRUE, pGC->subWindowMode); + (*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); + damageRegionProcessPending(pDrawable); DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); } static void -damagePolyGlyphBlt(DrawablePtr pDrawable, - GCPtr pGC, - int x, - int y, - unsigned int nglyph, - CharInfoPtr *ppci, - pointer pglyphBase) +damagePolyGlyphBlt(DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + unsigned int nglyph, CharInfoPtr * ppci, pointer pglyphBase) { DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y, - nglyph, ppci, FALSE, pGC->subWindowMode); - (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph, - ppci, pglyphBase); - damageRegionProcessPending (pDrawable); + damageDamageChars(pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y, + nglyph, ppci, FALSE, pGC->subWindowMode); + (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); + damageRegionProcessPending(pDrawable); DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); } static void -damagePushPixels(GCPtr pGC, - PixmapPtr pBitMap, - DrawablePtr pDrawable, - int dx, - int dy, - int xOrg, - int yOrg) +damagePushPixels(GCPtr pGC, + PixmapPtr pBitMap, + DrawablePtr pDrawable, int dx, int dy, int xOrg, int yOrg) { DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - if(checkGCDamage (pDrawable, pGC)) - { - BoxRec box; + if (checkGCDamage(pDrawable, pGC)) { + BoxRec box; box.x1 = xOrg; box.y1 = yOrg; - if(!pGC->miTranslate) { - box.x1 += pDrawable->x; - box.y1 += pDrawable->y; + if (!pGC->miTranslate) { + box.x1 += pDrawable->x; + box.y1 += pDrawable->y; } - box.x2 = box.x1 + dx; - box.y2 = box.y1 + dy; + box.x2 = box.x1 + dx; + box.y2 = box.y1 + dy; - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); + TRIM_BOX(box, pGC); + if (BOX_NOT_EMPTY(box)) + damageDamageBox(pDrawable, &box, pGC->subWindowMode); } - (*pGC->ops->PushPixels)(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg); - damageRegionProcessPending (pDrawable); + (*pGC->ops->PushPixels) (pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg); + damageRegionProcessPending(pDrawable); DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); } static void -damageRemoveDamage (DamagePtr *pPrev, DamagePtr pDamage) -{ - while (*pPrev) - { - if (*pPrev == pDamage) - { - *pPrev = pDamage->pNext; - return; - } - pPrev = &(*pPrev)->pNext; +damageRemoveDamage(DamagePtr * pPrev, DamagePtr pDamage) +{ + while (*pPrev) { + if (*pPrev == pDamage) { + *pPrev = pDamage->pNext; + return; + } + pPrev = &(*pPrev)->pNext; } #if DAMAGE_VALIDATE_ENABLE - ErrorF ("Damage not on list\n"); - OsAbort (); + ErrorF("Damage not on list\n"); + OsAbort(); #endif } static void -damageInsertDamage (DamagePtr *pPrev, DamagePtr pDamage) +damageInsertDamage(DamagePtr * pPrev, DamagePtr pDamage) { #if DAMAGE_VALIDATE_ENABLE - DamagePtr pOld; + DamagePtr pOld; for (pOld = *pPrev; pOld; pOld = pOld->pNext) - if (pOld == pDamage) { - ErrorF ("Damage already on list\n"); - OsAbort (); - } + if (pOld == pDamage) { + ErrorF("Damage already on list\n"); + OsAbort(); + } #endif pDamage->pNext = *pPrev; *pPrev = pDamage; } static Bool -damageDestroyPixmap (PixmapPtr pPixmap) +damageDestroyPixmap(PixmapPtr pPixmap) { - ScreenPtr pScreen = pPixmap->drawable.pScreen; + ScreenPtr pScreen = pPixmap->drawable.pScreen; + damageScrPriv(pScreen); - if (pPixmap->refcnt == 1) - { - DamagePtr *pPrev = getPixmapDamageRef (pPixmap); - DamagePtr pDamage; - - while ((pDamage = *pPrev)) - { - damageRemoveDamage (pPrev, pDamage); - if (!pDamage->isWindow) - DamageDestroy (pDamage); - } + if (pPixmap->refcnt == 1) { + DamagePtr *pPrev = getPixmapDamageRef(pPixmap); + DamagePtr pDamage; + + while ((pDamage = *pPrev)) { + damageRemoveDamage(pPrev, pDamage); + if (!pDamage->isWindow) + DamageDestroy(pDamage); + } } - unwrap (pScrPriv, pScreen, DestroyPixmap); + unwrap(pScrPriv, pScreen, DestroyPixmap); (*pScreen->DestroyPixmap) (pPixmap); - wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap); + wrap(pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap); return TRUE; } static void -damageCopyWindow(WindowPtr pWindow, - DDXPointRec ptOldOrg, - RegionPtr prgnSrc) +damageCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc) { ScreenPtr pScreen = pWindow->drawable.pScreen; + damageScrPriv(pScreen); - if (getWindowDamage (pWindow)) - { - int dx = pWindow->drawable.x - ptOldOrg.x; - int dy = pWindow->drawable.y - ptOldOrg.y; - - /* - * The region comes in source relative, but the damage occurs - * at the destination location. Translate back and forth. - */ - RegionTranslate(prgnSrc, dx, dy); - damageRegionAppend (&pWindow->drawable, prgnSrc, FALSE, -1); - RegionTranslate(prgnSrc, -dx, -dy); + if (getWindowDamage(pWindow)) { + int dx = pWindow->drawable.x - ptOldOrg.x; + int dy = pWindow->drawable.y - ptOldOrg.y; + + /* + * The region comes in source relative, but the damage occurs + * at the destination location. Translate back and forth. + */ + RegionTranslate(prgnSrc, dx, dy); + damageRegionAppend(&pWindow->drawable, prgnSrc, FALSE, -1); + RegionTranslate(prgnSrc, -dx, -dy); } - unwrap (pScrPriv, pScreen, CopyWindow); + unwrap(pScrPriv, pScreen, CopyWindow); (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc); - damageRegionProcessPending (&pWindow->drawable); - wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow); + damageRegionProcessPending(&pWindow->drawable); + wrap(pScrPriv, pScreen, CopyWindow, damageCopyWindow); } static GCOps damageGCOps = { @@ -1695,66 +1597,63 @@ static GCOps damageGCOps = { }; static void -damageSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap) +damageSetWindowPixmap(WindowPtr pWindow, PixmapPtr pPixmap) { - DamagePtr pDamage; - ScreenPtr pScreen = pWindow->drawable.pScreen; + DamagePtr pDamage; + ScreenPtr pScreen = pWindow->drawable.pScreen; + damageScrPriv(pScreen); - if ((pDamage = damageGetWinPriv(pWindow))) - { - PixmapPtr pOldPixmap = (*pScreen->GetWindowPixmap) (pWindow); - DamagePtr *pPrev = getPixmapDamageRef(pOldPixmap); - - while (pDamage) - { - damageRemoveDamage (pPrev, pDamage); - pDamage = pDamage->pNextWin; - } + if ((pDamage = damageGetWinPriv(pWindow))) { + PixmapPtr pOldPixmap = (*pScreen->GetWindowPixmap) (pWindow); + DamagePtr *pPrev = getPixmapDamageRef(pOldPixmap); + + while (pDamage) { + damageRemoveDamage(pPrev, pDamage); + pDamage = pDamage->pNextWin; + } } - unwrap (pScrPriv, pScreen, SetWindowPixmap); + unwrap(pScrPriv, pScreen, SetWindowPixmap); (*pScreen->SetWindowPixmap) (pWindow, pPixmap); - wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap); - if ((pDamage = damageGetWinPriv(pWindow))) - { - DamagePtr *pPrev = getPixmapDamageRef(pPixmap); - - while (pDamage) - { - damageInsertDamage (pPrev, pDamage); - pDamage = pDamage->pNextWin; - } + wrap(pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap); + if ((pDamage = damageGetWinPriv(pWindow))) { + DamagePtr *pPrev = getPixmapDamageRef(pPixmap); + + while (pDamage) { + damageInsertDamage(pPrev, pDamage); + pDamage = pDamage->pNextWin; + } } } static Bool -damageDestroyWindow (WindowPtr pWindow) +damageDestroyWindow(WindowPtr pWindow) { - DamagePtr pDamage; - ScreenPtr pScreen = pWindow->drawable.pScreen; - Bool ret; + DamagePtr pDamage; + ScreenPtr pScreen = pWindow->drawable.pScreen; + Bool ret; + damageScrPriv(pScreen); - while ((pDamage = damageGetWinPriv(pWindow))) - { - DamageUnregister (&pWindow->drawable, pDamage); - DamageDestroy (pDamage); + while ((pDamage = damageGetWinPriv(pWindow))) { + DamageUnregister(&pWindow->drawable, pDamage); + DamageDestroy(pDamage); } - unwrap (pScrPriv, pScreen, DestroyWindow); + unwrap(pScrPriv, pScreen, DestroyWindow); ret = (*pScreen->DestroyWindow) (pWindow); - wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow); + wrap(pScrPriv, pScreen, DestroyWindow, damageDestroyWindow); return ret; } static Bool -damageCloseScreen (int i, ScreenPtr pScreen) +damageCloseScreen(int i, ScreenPtr pScreen) { damageScrPriv(pScreen); - unwrap (pScrPriv, pScreen, DestroyPixmap); - unwrap (pScrPriv, pScreen, CreateGC); - unwrap (pScrPriv, pScreen, CopyWindow); - unwrap (pScrPriv, pScreen, CloseScreen); + unwrap(pScrPriv, pScreen, DestroyPixmap); + unwrap(pScrPriv, pScreen, CreateGC); + unwrap(pScrPriv, pScreen, CopyWindow); + unwrap(pScrPriv, pScreen, CloseScreen); free(pScrPriv); return (*pScreen->CloseScreen) (i, pScreen); } @@ -1762,19 +1661,23 @@ damageCloseScreen (int i, ScreenPtr pScreen) /** * Default implementations of the damage management functions. */ -void miDamageCreate (DamagePtr pDamage) +void +miDamageCreate(DamagePtr pDamage) { } -void miDamageRegister (DrawablePtr pDrawable, DamagePtr pDamage) +void +miDamageRegister(DrawablePtr pDrawable, DamagePtr pDamage) { } -void miDamageUnregister (DrawablePtr pDrawable, DamagePtr pDamage) +void +miDamageUnregister(DrawablePtr pDrawable, DamagePtr pDamage) { } -void miDamageDestroy (DamagePtr pDamage) +void +miDamageDestroy(DamagePtr pDamage) { } @@ -1783,46 +1686,48 @@ void miDamageDestroy (DamagePtr pDamage) */ Bool -DamageSetup (ScreenPtr pScreen) +DamageSetup(ScreenPtr pScreen) { - DamageScrPrivPtr pScrPriv; - PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); + DamageScrPrivPtr pScrPriv; + PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); + const DamageScreenFuncsRec miFuncs = { - miDamageCreate, miDamageRegister, miDamageUnregister, miDamageDestroy + miDamageCreate, miDamageRegister, miDamageUnregister, miDamageDestroy }; if (!dixRegisterPrivateKey(&damageScrPrivateKeyRec, PRIVATE_SCREEN, 0)) - return FALSE; + return FALSE; if (dixLookupPrivate(&pScreen->devPrivates, damageScrPrivateKey)) - return TRUE; + return TRUE; - if (!dixRegisterPrivateKey(&damageGCPrivateKeyRec, PRIVATE_GC, sizeof(DamageGCPrivRec))) - return FALSE; + if (!dixRegisterPrivateKey + (&damageGCPrivateKeyRec, PRIVATE_GC, sizeof(DamageGCPrivRec))) + return FALSE; if (!dixRegisterPrivateKey(&damagePixPrivateKeyRec, PRIVATE_PIXMAP, 0)) - return FALSE; + return FALSE; if (!dixRegisterPrivateKey(&damageWinPrivateKeyRec, PRIVATE_WINDOW, 0)) - return FALSE; + return FALSE; - pScrPriv = malloc(sizeof (DamageScrPrivRec)); + pScrPriv = malloc(sizeof(DamageScrPrivRec)); if (!pScrPriv) - return FALSE; + return FALSE; pScrPriv->internalLevel = 0; pScrPriv->pScreenDamage = 0; - wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap); - wrap (pScrPriv, pScreen, CreateGC, damageCreateGC); - wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow); - wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap); - wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow); - wrap (pScrPriv, pScreen, CloseScreen, damageCloseScreen); + wrap(pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap); + wrap(pScrPriv, pScreen, CreateGC, damageCreateGC); + wrap(pScrPriv, pScreen, DestroyWindow, damageDestroyWindow); + wrap(pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap); + wrap(pScrPriv, pScreen, CopyWindow, damageCopyWindow); + wrap(pScrPriv, pScreen, CloseScreen, damageCloseScreen); if (ps) { - wrap (pScrPriv, ps, Glyphs, damageGlyphs); - wrap (pScrPriv, ps, Composite, damageComposite); - wrap (pScrPriv, ps, AddTraps, damageAddTraps); + wrap(pScrPriv, ps, Glyphs, damageGlyphs); + wrap(pScrPriv, ps, Composite, damageComposite); + wrap(pScrPriv, ps, AddTraps, damageAddTraps); } pScrPriv->funcs = miFuncs; @@ -1832,24 +1737,22 @@ DamageSetup (ScreenPtr pScreen) } DamagePtr -DamageCreate (DamageReportFunc damageReport, - DamageDestroyFunc damageDestroy, - DamageReportLevel damageLevel, - Bool isInternal, - ScreenPtr pScreen, - void *closure) +DamageCreate(DamageReportFunc damageReport, + DamageDestroyFunc damageDestroy, + DamageReportLevel damageLevel, + Bool isInternal, ScreenPtr pScreen, void *closure) { damageScrPriv(pScreen); - DamagePtr pDamage; + DamagePtr pDamage; pDamage = dixAllocateObjectWithPrivates(DamageRec, PRIVATE_DAMAGE); if (!pDamage) - return 0; + return 0; pDamage->pNext = 0; pDamage->pNextWin = 0; RegionNull(&pDamage->damage); RegionNull(&pDamage->pendingDamage); - + pDamage->damageLevel = damageLevel; pDamage->isInternal = isInternal; pDamage->closure = closure; @@ -1869,101 +1772,99 @@ DamageCreate (DamageReportFunc damageReport, } void -DamageRegister (DrawablePtr pDrawable, - DamagePtr pDamage) +DamageRegister(DrawablePtr pDrawable, DamagePtr pDamage) { ScreenPtr pScreen = pDrawable->pScreen; + damageScrPriv(pScreen); #if DAMAGE_VALIDATE_ENABLE - if (pDrawable->pScreen != pDamage->pScreen) - { - ErrorF ("DamageRegister called with mismatched screens\n"); - OsAbort (); + if (pDrawable->pScreen != pDamage->pScreen) { + ErrorF("DamageRegister called with mismatched screens\n"); + OsAbort(); } #endif - if (pDrawable->type == DRAWABLE_WINDOW) - { - WindowPtr pWindow = (WindowPtr) pDrawable; - winDamageRef(pWindow); + if (pDrawable->type == DRAWABLE_WINDOW) { + WindowPtr pWindow = (WindowPtr) pDrawable; + + winDamageRef(pWindow); #if DAMAGE_VALIDATE_ENABLE - DamagePtr pOld; - - for (pOld = *pPrev; pOld; pOld = pOld->pNextWin) - if (pOld == pDamage) { - ErrorF ("Damage already on window list\n"); - OsAbort (); - } + DamagePtr pOld; + + for (pOld = *pPrev; pOld; pOld = pOld->pNextWin) + if (pOld == pDamage) { + ErrorF("Damage already on window list\n"); + OsAbort(); + } #endif - pDamage->pNextWin = *pPrev; - *pPrev = pDamage; - pDamage->isWindow = TRUE; + pDamage->pNextWin = *pPrev; + *pPrev = pDamage; + pDamage->isWindow = TRUE; } else - pDamage->isWindow = FALSE; + pDamage->isWindow = FALSE; pDamage->pDrawable = pDrawable; - damageInsertDamage (getDrawableDamageRef (pDrawable), pDamage); + damageInsertDamage(getDrawableDamageRef(pDrawable), pDamage); (*pScrPriv->funcs.Register) (pDrawable, pDamage); } void -DamageDrawInternal (ScreenPtr pScreen, Bool enable) +DamageDrawInternal(ScreenPtr pScreen, Bool enable) { - damageScrPriv (pScreen); + damageScrPriv(pScreen); pScrPriv->internalLevel += enable ? 1 : -1; } void -DamageUnregister (DrawablePtr pDrawable, - DamagePtr pDamage) +DamageUnregister(DrawablePtr pDrawable, DamagePtr pDamage) { ScreenPtr pScreen = pDrawable->pScreen; + damageScrPriv(pScreen); (*pScrPriv->funcs.Unregister) (pDrawable, pDamage); - if (pDrawable->type == DRAWABLE_WINDOW) - { - WindowPtr pWindow = (WindowPtr) pDrawable; - winDamageRef (pWindow); + if (pDrawable->type == DRAWABLE_WINDOW) { + WindowPtr pWindow = (WindowPtr) pDrawable; + + winDamageRef(pWindow); #if DAMAGE_VALIDATE_ENABLE - int found = 0; + int found = 0; #endif - while (*pPrev) - { - if (*pPrev == pDamage) - { - *pPrev = pDamage->pNextWin; + while (*pPrev) { + if (*pPrev == pDamage) { + *pPrev = pDamage->pNextWin; #if DAMAGE_VALIDATE_ENABLE - found = 1; + found = 1; #endif - break; - } - pPrev = &(*pPrev)->pNextWin; - } + break; + } + pPrev = &(*pPrev)->pNextWin; + } #if DAMAGE_VALIDATE_ENABLE - if (!found) { - ErrorF ("Damage not on window list\n"); - OsAbort (); - } + if (!found) { + ErrorF("Damage not on window list\n"); + OsAbort(); + } #endif } pDamage->pDrawable = 0; - damageRemoveDamage (getDrawableDamageRef (pDrawable), pDamage); + damageRemoveDamage(getDrawableDamageRef(pDrawable), pDamage); } void -DamageDestroy (DamagePtr pDamage) +DamageDestroy(DamagePtr pDamage) { ScreenPtr pScreen = pDamage->pScreen; + damageScrPriv(pScreen); if (pDamage->damageDestroy) - (*pDamage->damageDestroy) (pDamage, pDamage->closure); + (*pDamage->damageDestroy) (pDamage, pDamage->closure); (*pScrPriv->funcs.Destroy) (pDamage); RegionUninit(&pDamage->damage); RegionUninit(&pDamage->pendingDamage); @@ -1971,115 +1872,113 @@ DamageDestroy (DamagePtr pDamage) } Bool -DamageSubtract (DamagePtr pDamage, - const RegionPtr pRegion) +DamageSubtract(DamagePtr pDamage, const RegionPtr pRegion) { - RegionPtr pClip; - RegionRec pixmapClip; - DrawablePtr pDrawable = pDamage->pDrawable; - + RegionPtr pClip; + RegionRec pixmapClip; + DrawablePtr pDrawable = pDamage->pDrawable; + RegionSubtract(&pDamage->damage, &pDamage->damage, pRegion); - if (pDrawable) - { - if (pDrawable->type == DRAWABLE_WINDOW) - pClip = &((WindowPtr) pDrawable)->borderClip; - else - { - BoxRec box; - - box.x1 = pDrawable->x; - box.y1 = pDrawable->y; - box.x2 = pDrawable->x + pDrawable->width; - box.y2 = pDrawable->y + pDrawable->height; - RegionInit(&pixmapClip, &box, 1); - pClip = &pixmapClip; - } - RegionTranslate(&pDamage->damage, pDrawable->x, pDrawable->y); - RegionIntersect(&pDamage->damage, &pDamage->damage, pClip); - RegionTranslate(&pDamage->damage, -pDrawable->x, -pDrawable->y); - if (pDrawable->type != DRAWABLE_WINDOW) - RegionUninit(&pixmapClip); + if (pDrawable) { + if (pDrawable->type == DRAWABLE_WINDOW) + pClip = &((WindowPtr) pDrawable)->borderClip; + else { + BoxRec box; + + box.x1 = pDrawable->x; + box.y1 = pDrawable->y; + box.x2 = pDrawable->x + pDrawable->width; + box.y2 = pDrawable->y + pDrawable->height; + RegionInit(&pixmapClip, &box, 1); + pClip = &pixmapClip; + } + RegionTranslate(&pDamage->damage, pDrawable->x, pDrawable->y); + RegionIntersect(&pDamage->damage, &pDamage->damage, pClip); + RegionTranslate(&pDamage->damage, -pDrawable->x, -pDrawable->y); + if (pDrawable->type != DRAWABLE_WINDOW) + RegionUninit(&pixmapClip); } return RegionNotEmpty(&pDamage->damage); } void -DamageEmpty (DamagePtr pDamage) +DamageEmpty(DamagePtr pDamage) { RegionEmpty(&pDamage->damage); } RegionPtr -DamageRegion (DamagePtr pDamage) +DamageRegion(DamagePtr pDamage) { return &pDamage->damage; } RegionPtr -DamagePendingRegion (DamagePtr pDamage) +DamagePendingRegion(DamagePtr pDamage) { return &pDamage->pendingDamage; } void -DamageRegionAppend (DrawablePtr pDrawable, RegionPtr pRegion) +DamageRegionAppend(DrawablePtr pDrawable, RegionPtr pRegion) { - damageRegionAppend (pDrawable, pRegion, FALSE, -1); + damageRegionAppend(pDrawable, pRegion, FALSE, -1); } void -DamageRegionProcessPending (DrawablePtr pDrawable) +DamageRegionProcessPending(DrawablePtr pDrawable) { - damageRegionProcessPending (pDrawable); + damageRegionProcessPending(pDrawable); } /* If a damage marker is provided, then this function must be called after rendering is done. */ /* Please do call back so any future enhancements can assume this function is called. */ /* There are no strict timing requirements for calling this function, just as soon as (is cheaply) possible. */ void -DamageRegionRendered (DrawablePtr pDrawable, DamagePtr pDamage, RegionPtr pOldDamage, RegionPtr pRegion) +DamageRegionRendered(DrawablePtr pDrawable, DamagePtr pDamage, + RegionPtr pOldDamage, RegionPtr pRegion) { if (pDamage->damageReportPostRendering) - damageReportDamagePostRendering (pDamage, pOldDamage, pRegion); + damageReportDamagePostRendering(pDamage, pOldDamage, pRegion); } /* This call is very odd, i'm leaving it intact for API sake, but please don't use it. */ void -DamageDamageRegion (DrawablePtr pDrawable, - RegionPtr pRegion) +DamageDamageRegion(DrawablePtr pDrawable, RegionPtr pRegion) { - damageRegionAppend (pDrawable, pRegion, FALSE, -1); + damageRegionAppend(pDrawable, pRegion, FALSE, -1); /* Go back and report this damage for DamagePtrs with reportAfter set, since * this call isn't part of an in-progress drawing op in the call chain and * the DDX probably just wants to know about it right away. */ - damageRegionProcessPending (pDrawable); + damageRegionProcessPending(pDrawable); } void -DamageSetReportAfterOp (DamagePtr pDamage, Bool reportAfter) +DamageSetReportAfterOp(DamagePtr pDamage, Bool reportAfter) { pDamage->reportAfter = reportAfter; } void -DamageSetPostRenderingFunctions(DamagePtr pDamage, DamageReportFunc damageReportPostRendering, - DamageMarkerFunc damageMarker) +DamageSetPostRenderingFunctions(DamagePtr pDamage, + DamageReportFunc damageReportPostRendering, + DamageMarkerFunc damageMarker) { pDamage->damageReportPostRendering = damageReportPostRendering; pDamage->damageMarker = damageMarker; } DamageScreenFuncsPtr -DamageGetScreenFuncs (ScreenPtr pScreen) +DamageGetScreenFuncs(ScreenPtr pScreen) { damageScrPriv(pScreen); return &pScrPriv->funcs; } void -DamageReportDamage (DamagePtr pDamage, RegionPtr pDamageRegion) +DamageReportDamage(DamagePtr pDamage, RegionPtr pDamageRegion) { BoxRec tmpBox; RegionRec tmpRegion; @@ -2087,42 +1986,36 @@ DamageReportDamage (DamagePtr pDamage, RegionPtr pDamageRegion) switch (pDamage->damageLevel) { case DamageReportRawRegion: - RegionUnion(&pDamage->damage, &pDamage->damage, - pDamageRegion); - (*pDamage->damageReport) (pDamage, pDamageRegion, pDamage->closure); - break; + RegionUnion(&pDamage->damage, &pDamage->damage, pDamageRegion); + (*pDamage->damageReport) (pDamage, pDamageRegion, pDamage->closure); + break; case DamageReportDeltaRegion: - RegionNull(&tmpRegion); - RegionSubtract(&tmpRegion, pDamageRegion, &pDamage->damage); - if (RegionNotEmpty(&tmpRegion)) { - RegionUnion(&pDamage->damage, &pDamage->damage, - pDamageRegion); - (*pDamage->damageReport) (pDamage, &tmpRegion, pDamage->closure); - } - RegionUninit(&tmpRegion); - break; + RegionNull(&tmpRegion); + RegionSubtract(&tmpRegion, pDamageRegion, &pDamage->damage); + if (RegionNotEmpty(&tmpRegion)) { + RegionUnion(&pDamage->damage, &pDamage->damage, pDamageRegion); + (*pDamage->damageReport) (pDamage, &tmpRegion, pDamage->closure); + } + RegionUninit(&tmpRegion); + break; case DamageReportBoundingBox: - tmpBox = *RegionExtents(&pDamage->damage); - RegionUnion(&pDamage->damage, &pDamage->damage, - pDamageRegion); - if (!BOX_SAME (&tmpBox, RegionExtents(&pDamage->damage))) { - (*pDamage->damageReport) (pDamage, &pDamage->damage, - pDamage->closure); - } - break; + tmpBox = *RegionExtents(&pDamage->damage); + RegionUnion(&pDamage->damage, &pDamage->damage, pDamageRegion); + if (!BOX_SAME(&tmpBox, RegionExtents(&pDamage->damage))) { + (*pDamage->damageReport) (pDamage, &pDamage->damage, + pDamage->closure); + } + break; case DamageReportNonEmpty: - was_empty = !RegionNotEmpty(&pDamage->damage); - RegionUnion(&pDamage->damage, &pDamage->damage, - pDamageRegion); - if (was_empty && RegionNotEmpty(&pDamage->damage)) { - (*pDamage->damageReport) (pDamage, &pDamage->damage, - pDamage->closure); - } - break; + was_empty = !RegionNotEmpty(&pDamage->damage); + RegionUnion(&pDamage->damage, &pDamage->damage, pDamageRegion); + if (was_empty && RegionNotEmpty(&pDamage->damage)) { + (*pDamage->damageReport) (pDamage, &pDamage->damage, + pDamage->closure); + } + break; case DamageReportNone: - RegionUnion(&pDamage->damage, &pDamage->damage, - pDamageRegion); - break; + RegionUnion(&pDamage->damage, &pDamage->damage, pDamageRegion); + break; } } - diff --git a/xorg-server/miext/damage/damage.h b/xorg-server/miext/damage/damage.h index 0c7fc316c..c2c313a15 100644 --- a/xorg-server/miext/damage/damage.h +++ b/xorg-server/miext/damage/damage.h @@ -27,7 +27,7 @@ #ifndef _DAMAGE_H_ #define _DAMAGE_H_ -typedef struct _damage *DamagePtr; +typedef struct _damage *DamagePtr; typedef enum _damageReportLevel { DamageReportRawRegion, @@ -37,11 +37,15 @@ typedef enum _damageReportLevel { DamageReportNone } DamageReportLevel; -typedef void (*DamageReportFunc) (DamagePtr pDamage, RegionPtr pRegion, void *closure); +typedef void (*DamageReportFunc) (DamagePtr pDamage, RegionPtr pRegion, + void *closure); typedef void (*DamageDestroyFunc) (DamagePtr pDamage, void *closure); + /* It's the responsibility of the driver to duplicate both regions. */ /* At some point DamageRegionRendered() must be called. */ -typedef void (*DamageMarkerFunc) (DrawablePtr pDrawable, DamagePtr pDamage, RegionPtr pOldDamage, RegionPtr pRegion, void *closure); +typedef void (*DamageMarkerFunc) (DrawablePtr pDrawable, DamagePtr pDamage, + RegionPtr pOldDamage, RegionPtr pRegion, + void *closure); typedef void (*DamageScreenCreateFunc) (DamagePtr); typedef void (*DamageScreenRegisterFunc) (DrawablePtr, DamagePtr); @@ -49,84 +53,81 @@ typedef void (*DamageScreenUnregisterFunc) (DrawablePtr, DamagePtr); typedef void (*DamageScreenDestroyFunc) (DamagePtr); typedef struct _damageScreenFuncs { - DamageScreenCreateFunc Create; - DamageScreenRegisterFunc Register; - DamageScreenUnregisterFunc Unregister; - DamageScreenDestroyFunc Destroy; + DamageScreenCreateFunc Create; + DamageScreenRegisterFunc Register; + DamageScreenUnregisterFunc Unregister; + DamageScreenDestroyFunc Destroy; } DamageScreenFuncsRec, *DamageScreenFuncsPtr; -extern _X_EXPORT void miDamageCreate (DamagePtr); -extern _X_EXPORT void miDamageRegister (DrawablePtr, DamagePtr); -extern _X_EXPORT void miDamageUnregister (DrawablePtr, DamagePtr); -extern _X_EXPORT void miDamageDestroy (DamagePtr); +extern _X_EXPORT void miDamageCreate(DamagePtr); +extern _X_EXPORT void miDamageRegister(DrawablePtr, DamagePtr); +extern _X_EXPORT void miDamageUnregister(DrawablePtr, DamagePtr); +extern _X_EXPORT void miDamageDestroy(DamagePtr); extern _X_EXPORT Bool -DamageSetup (ScreenPtr pScreen); - + DamageSetup(ScreenPtr pScreen); + extern _X_EXPORT DamagePtr -DamageCreate (DamageReportFunc damageReport, - DamageDestroyFunc damageDestroy, - DamageReportLevel damageLevel, - Bool isInternal, - ScreenPtr pScreen, - void * closure); +DamageCreate(DamageReportFunc damageReport, + DamageDestroyFunc damageDestroy, + DamageReportLevel damageLevel, + Bool isInternal, ScreenPtr pScreen, void *closure); extern _X_EXPORT void -DamageDrawInternal (ScreenPtr pScreen, Bool enable); + DamageDrawInternal(ScreenPtr pScreen, Bool enable); extern _X_EXPORT void -DamageRegister (DrawablePtr pDrawable, - DamagePtr pDamage); + DamageRegister(DrawablePtr pDrawable, DamagePtr pDamage); extern _X_EXPORT void -DamageUnregister (DrawablePtr pDrawable, - DamagePtr pDamage); + DamageUnregister(DrawablePtr pDrawable, DamagePtr pDamage); extern _X_EXPORT void -DamageDestroy (DamagePtr pDamage); + DamageDestroy(DamagePtr pDamage); extern _X_EXPORT Bool -DamageSubtract (DamagePtr pDamage, - const RegionPtr pRegion); + DamageSubtract(DamagePtr pDamage, const RegionPtr pRegion); extern _X_EXPORT void -DamageEmpty (DamagePtr pDamage); + DamageEmpty(DamagePtr pDamage); extern _X_EXPORT RegionPtr -DamageRegion (DamagePtr pDamage); + DamageRegion(DamagePtr pDamage); extern _X_EXPORT RegionPtr -DamagePendingRegion (DamagePtr pDamage); + DamagePendingRegion(DamagePtr pDamage); /* In case of rendering, call this before the submitting the commands. */ extern _X_EXPORT void -DamageRegionAppend (DrawablePtr pDrawable, RegionPtr pRegion); + DamageRegionAppend(DrawablePtr pDrawable, RegionPtr pRegion); /* Call this directly after the rendering operation has been submitted. */ extern _X_EXPORT void -DamageRegionProcessPending (DrawablePtr pDrawable); + DamageRegionProcessPending(DrawablePtr pDrawable); /* Call this some time after rendering is done, only relevant when a damageMarker is provided. */ extern _X_EXPORT void -DamageRegionRendered (DrawablePtr pDrawable, DamagePtr pDamage, RegionPtr pOldDamage, RegionPtr pRegion); + +DamageRegionRendered(DrawablePtr pDrawable, DamagePtr pDamage, + RegionPtr pOldDamage, RegionPtr pRegion); /* Call this when you create a new Damage and you wish to send an initial damage message (to it). */ extern _X_EXPORT void -DamageReportDamage (DamagePtr pDamage, RegionPtr pDamageRegion); + DamageReportDamage(DamagePtr pDamage, RegionPtr pDamageRegion); /* Avoid using this call, it only exists for API compatibility. */ extern _X_EXPORT void -DamageDamageRegion (DrawablePtr pDrawable, - const RegionPtr pRegion); + DamageDamageRegion(DrawablePtr pDrawable, const RegionPtr pRegion); extern _X_EXPORT void -DamageSetReportAfterOp (DamagePtr pDamage, Bool reportAfter); + DamageSetReportAfterOp(DamagePtr pDamage, Bool reportAfter); extern _X_EXPORT void -DamageSetPostRenderingFunctions(DamagePtr pDamage, DamageReportFunc damageReportPostRendering, - DamageMarkerFunc damageMarker); -extern _X_EXPORT DamageScreenFuncsPtr -DamageGetScreenFuncs (ScreenPtr); +DamageSetPostRenderingFunctions(DamagePtr pDamage, + DamageReportFunc damageReportPostRendering, + DamageMarkerFunc damageMarker); + +extern _X_EXPORT DamageScreenFuncsPtr DamageGetScreenFuncs(ScreenPtr); -#endif /* _DAMAGE_H_ */ +#endif /* _DAMAGE_H_ */ diff --git a/xorg-server/miext/rootless/rootless.h b/xorg-server/miext/rootless/rootless.h index 757e4d372..a3f38b633 100644 --- a/xorg-server/miext/rootless/rootless.h +++ b/xorg-server/miext/rootless/rootless.h @@ -1,368 +1,363 @@ -/*
- * External interface to generic rootless mode
- */
-/*
- * Copyright (c) 2001 Greg Parker. All Rights Reserved.
- * Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name(s) of the above copyright
- * holders shall not be used in advertising or otherwise to promote the sale,
- * use or other dealings in this Software without prior written authorization.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#ifndef _ROOTLESS_H
-#define _ROOTLESS_H
-
-#include "rootlessConfig.h"
-#include "mi.h"
-#include "gcstruct.h"
-
-/*
- Each top-level rootless window has a one-to-one correspondence to a physical
- on-screen window. The physical window is refered to as a "frame".
- */
-
-typedef void * RootlessFrameID;
-
-/*
- * RootlessWindowRec
- * This structure stores the per-frame data used by the rootless code.
- * Each top-level X window has one RootlessWindowRec associated with it.
- */
-typedef struct _RootlessWindowRec {
- // Position and size includes the window border
- // Position is in per-screen coordinates
- int x, y;
- unsigned int width, height;
- unsigned int borderWidth;
- int level;
-
- RootlessFrameID wid; // implementation specific frame id
- WindowPtr win; // underlying X window
-
- // Valid only when drawing (ie. is_drawing is set)
- char *pixelData;
- int bytesPerRow;
-
- PixmapPtr pixmap;
-
- unsigned int is_drawing :1; // Currently drawing?
- unsigned int is_reorder_pending :1;
- unsigned int is_offscreen :1;
- unsigned int is_obscured :1;
-} RootlessWindowRec, *RootlessWindowPtr;
-
-
-/* Offset for screen-local to global coordinate transforms */
-extern int rootlessGlobalOffsetX;
-extern int rootlessGlobalOffsetY;
-
-/* The minimum number of bytes or pixels for which to use the
- implementation's accelerated functions. */
-extern unsigned int rootless_CopyBytes_threshold;
-extern unsigned int rootless_CopyWindow_threshold;
-
-/* Gravity for window contents during resizing */
-enum rl_gravity_enum {
- RL_GRAVITY_NONE = 0, /* no gravity, fill everything */
- RL_GRAVITY_NORTH_WEST = 1, /* anchor to top-left corner */
- RL_GRAVITY_NORTH_EAST = 2, /* anchor to top-right corner */
- RL_GRAVITY_SOUTH_EAST = 3, /* anchor to bottom-right corner */
- RL_GRAVITY_SOUTH_WEST = 4, /* anchor to bottom-left corner */
-};
-
-
-/*------------------------------------------
- Rootless Implementation Functions
- ------------------------------------------*/
-
-/*
- * Create a new frame.
- * The frame is created unmapped.
- *
- * pFrame RootlessWindowPtr for this frame should be completely
- * initialized before calling except for pFrame->wid, which
- * is set by this function.
- * pScreen Screen on which to place the new frame
- * newX, newY Position of the frame.
- * pNewShape Shape for the frame (in frame-local coordinates). NULL for
- * unshaped frames.
- */
-typedef Bool (*RootlessCreateFrameProc)
- (RootlessWindowPtr pFrame, ScreenPtr pScreen, int newX, int newY,
- RegionPtr pNewShape);
-
-/*
- * Destroy a frame.
- * Drawing is stopped and all updates are flushed before this is called.
- *
- * wid Frame id
- */
-typedef void (*RootlessDestroyFrameProc)
- (RootlessFrameID wid);
-
-/*
- * Move a frame on screen.
- * Drawing is stopped and all updates are flushed before this is called.
- *
- * wid Frame id
- * pScreen Screen to move the new frame to
- * newX, newY New position of the frame
- */
-typedef void (*RootlessMoveFrameProc)
- (RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY);
-
-/*
- * Resize and move a frame.
- * Drawing is stopped and all updates are flushed before this is called.
- *
- * wid Frame id
- * pScreen Screen to move the new frame to
- * newX, newY New position of the frame
- * newW, newH New size of the frame
- * gravity Gravity for window contents (rl_gravity_enum). This is always
- * RL_GRAVITY_NONE unless ROOTLESS_RESIZE_GRAVITY is set.
- */
-typedef void (*RootlessResizeFrameProc)
- (RootlessFrameID wid, ScreenPtr pScreen,
- int newX, int newY, unsigned int newW, unsigned int newH,
- unsigned int gravity);
-
-/*
- * Change frame ordering (AKA stacking, layering).
- * Drawing is stopped before this is called. Unmapped frames are mapped by
- * setting their ordering.
- *
- * wid Frame id
- * nextWid Frame id of frame that is now above this one or NULL if this
- * frame is at the top.
- */
-typedef void (*RootlessRestackFrameProc)
- (RootlessFrameID wid, RootlessFrameID nextWid);
-
-/*
- * Change frame's shape.
- * Drawing is stopped before this is called.
- *
- * wid Frame id
- * pNewShape New shape for the frame (in frame-local coordinates)
- * or NULL if now unshaped.
- */
-typedef void (*RootlessReshapeFrameProc)
- (RootlessFrameID wid, RegionPtr pNewShape);
-
-/*
- * Unmap a frame.
- *
- * wid Frame id
- */
-typedef void (*RootlessUnmapFrameProc)
- (RootlessFrameID wid);
-
-/*
- * Start drawing to a frame.
- * Prepare a frame for direct access to its backing buffer.
- *
- * wid Frame id
- * pixelData Address of the backing buffer (returned)
- * bytesPerRow Width in bytes of the backing buffer (returned)
- */
-typedef void (*RootlessStartDrawingProc)
- (RootlessFrameID wid, char **pixelData, int *bytesPerRow);
-
-/*
- * Stop drawing to a frame.
- * No drawing to the frame's backing buffer will occur until drawing
- * is started again.
- *
- * wid Frame id
- * flush Flush drawing updates for this frame to the screen.
- */
-typedef void (*RootlessStopDrawingProc)
- (RootlessFrameID wid, Bool flush);
-
-/*
- * Flush drawing updates to the screen.
- * Drawing is stopped before this is called.
- *
- * wid Frame id
- * pDamage Region containing all the changed pixels in frame-lcoal
- * coordinates. This is clipped to the window's clip.
- */
-typedef void (*RootlessUpdateRegionProc)
- (RootlessFrameID wid, RegionPtr pDamage);
-
-/*
- * Mark damaged rectangles as requiring redisplay to screen.
- *
- * wid Frame id
- * nrects Number of damaged rectangles
- * rects Array of damaged rectangles in frame-local coordinates
- * shift_x, Vector to shift rectangles by
- * shift_y
- */
-typedef void (*RootlessDamageRectsProc)
- (RootlessFrameID wid, int nrects, const BoxRec *rects,
- int shift_x, int shift_y);
-
-/*
- * Switch the window associated with a frame. (Optional)
- * When a framed window is reparented, the frame is resized and set to
- * use the new top-level parent. If defined this function will be called
- * afterwards for implementation specific bookkeeping.
- *
- * pFrame Frame whose window has switched
- * oldWin Previous window wrapped by this frame
- */
-typedef void (*RootlessSwitchWindowProc)
- (RootlessWindowPtr pFrame, WindowPtr oldWin);
-
-/*
- * Check if window should be reordered. (Optional)
- * The underlying window system may animate windows being ordered in.
- * We want them to be mapped but remain ordered out until the animation
- * completes. If defined this function will be called to check if a
- * framed window should be reordered now. If this function returns
- * FALSE, the window will still be mapped from the X11 perspective, but
- * the RestackFrame function will not be called for its frame.
- *
- * pFrame Frame to reorder
- */
-typedef Bool (*RootlessDoReorderWindowProc)
- (RootlessWindowPtr pFrame);
-
-/*
- * Copy bytes. (Optional)
- * Source and destinate may overlap and the right thing should happen.
- *
- * width Bytes to copy per row
- * height Number of rows
- * src Source data
- * srcRowBytes Width of source in bytes
- * dst Destination data
- * dstRowBytes Width of destination in bytes
- */
-typedef void (*RootlessCopyBytesProc)
- (unsigned int width, unsigned int height,
- const void *src, unsigned int srcRowBytes,
- void *dst, unsigned int dstRowBytes);
-
-/*
- * Copy area in frame to another part of frame. (Optional)
- *
- * wid Frame id
- * dstNrects Number of rectangles to copy
- * dstRects Array of rectangles to copy
- * dx, dy Number of pixels away to copy area
- */
-typedef void (*RootlessCopyWindowProc)
- (RootlessFrameID wid, int dstNrects, const BoxRec *dstRects,
- int dx, int dy);
-
-
-typedef void (*RootlessHideWindowProc)
- (RootlessFrameID wid);
-
-typedef void (*RootlessUpdateColormapProc)
- (RootlessFrameID wid, ScreenPtr pScreen);
-
-/*
- * Rootless implementation function list
- */
-typedef struct _RootlessFrameProcs {
- RootlessCreateFrameProc CreateFrame;
- RootlessDestroyFrameProc DestroyFrame;
-
- RootlessMoveFrameProc MoveFrame;
- RootlessResizeFrameProc ResizeFrame;
- RootlessRestackFrameProc RestackFrame;
- RootlessReshapeFrameProc ReshapeFrame;
- RootlessUnmapFrameProc UnmapFrame;
-
- RootlessStartDrawingProc StartDrawing;
- RootlessStopDrawingProc StopDrawing;
- RootlessUpdateRegionProc UpdateRegion;
- RootlessDamageRectsProc DamageRects;
-
- /* Optional frame functions */
- RootlessSwitchWindowProc SwitchWindow;
- RootlessDoReorderWindowProc DoReorderWindow;
- RootlessHideWindowProc HideWindow;
- RootlessUpdateColormapProc UpdateColormap;
-
- /* Optional acceleration functions */
- RootlessCopyBytesProc CopyBytes;
- RootlessCopyWindowProc CopyWindow;
-} RootlessFrameProcsRec, *RootlessFrameProcsPtr;
-
-
-/*
- * Initialize rootless mode on the given screen.
- */
-Bool RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs);
-
-/*
- * Return the frame ID for the physical window displaying the given window.
- *
- * create If true and the window has no frame, attempt to create one
- */
-RootlessFrameID RootlessFrameForWindow(WindowPtr pWin, Bool create);
-
-/*
- * Return the top-level parent of a window.
- * The root is the top-level parent of itself, even though the root is
- * not otherwise considered to be a top-level window.
- */
-WindowPtr TopLevelParent(WindowPtr pWindow);
-
-/*
- * Prepare a window for direct access to its backing buffer.
- */
-void RootlessStartDrawing(WindowPtr pWindow);
-
-/*
- * Finish drawing to a window's backing buffer.
- *
- * flush If true, damaged areas are flushed to the screen.
- */
-void RootlessStopDrawing(WindowPtr pWindow, Bool flush);
-
-/*
- * Alocate a new screen pixmap.
- * miCreateScreenResources does not do this properly with a null
- * framebuffer pointer.
- */
-void RootlessUpdateScreenPixmap(ScreenPtr pScreen);
-
-/*
- * Reposition all windows on a screen to their correct positions.
- */
-void RootlessRepositionWindows(ScreenPtr pScreen);
-
-/*
- * Bring all windows to the front of the native stack
- */
-void RootlessOrderAllWindows (Bool include_unhitable);
-#endif /* _ROOTLESS_H */
+/* + * External interface to generic rootless mode + */ +/* + * Copyright (c) 2001 Greg Parker. All Rights Reserved. + * Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name(s) of the above copyright + * holders shall not be used in advertising or otherwise to promote the sale, + * use or other dealings in this Software without prior written authorization. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef _ROOTLESS_H +#define _ROOTLESS_H + +#include "rootlessConfig.h" +#include "mi.h" +#include "gcstruct.h" + +/* + Each top-level rootless window has a one-to-one correspondence to a physical + on-screen window. The physical window is refered to as a "frame". + */ + +typedef void *RootlessFrameID; + +/* + * RootlessWindowRec + * This structure stores the per-frame data used by the rootless code. + * Each top-level X window has one RootlessWindowRec associated with it. + */ +typedef struct _RootlessWindowRec { + // Position and size includes the window border + // Position is in per-screen coordinates + int x, y; + unsigned int width, height; + unsigned int borderWidth; + int level; + + RootlessFrameID wid; // implementation specific frame id + WindowPtr win; // underlying X window + + // Valid only when drawing (ie. is_drawing is set) + char *pixelData; + int bytesPerRow; + + PixmapPtr pixmap; + + unsigned int is_drawing:1; // Currently drawing? + unsigned int is_reorder_pending:1; + unsigned int is_offscreen:1; + unsigned int is_obscured:1; +} RootlessWindowRec, *RootlessWindowPtr; + +/* Offset for screen-local to global coordinate transforms */ +extern int rootlessGlobalOffsetX; +extern int rootlessGlobalOffsetY; + +/* The minimum number of bytes or pixels for which to use the + implementation's accelerated functions. */ +extern unsigned int rootless_CopyBytes_threshold; +extern unsigned int rootless_CopyWindow_threshold; + +/* Gravity for window contents during resizing */ +enum rl_gravity_enum { + RL_GRAVITY_NONE = 0, /* no gravity, fill everything */ + RL_GRAVITY_NORTH_WEST = 1, /* anchor to top-left corner */ + RL_GRAVITY_NORTH_EAST = 2, /* anchor to top-right corner */ + RL_GRAVITY_SOUTH_EAST = 3, /* anchor to bottom-right corner */ + RL_GRAVITY_SOUTH_WEST = 4, /* anchor to bottom-left corner */ +}; + +/*------------------------------------------ + Rootless Implementation Functions + ------------------------------------------*/ + +/* + * Create a new frame. + * The frame is created unmapped. + * + * pFrame RootlessWindowPtr for this frame should be completely + * initialized before calling except for pFrame->wid, which + * is set by this function. + * pScreen Screen on which to place the new frame + * newX, newY Position of the frame. + * pNewShape Shape for the frame (in frame-local coordinates). NULL for + * unshaped frames. + */ +typedef Bool (*RootlessCreateFrameProc) + (RootlessWindowPtr pFrame, ScreenPtr pScreen, int newX, int newY, + RegionPtr pNewShape); + +/* + * Destroy a frame. + * Drawing is stopped and all updates are flushed before this is called. + * + * wid Frame id + */ +typedef void (*RootlessDestroyFrameProc) + (RootlessFrameID wid); + +/* + * Move a frame on screen. + * Drawing is stopped and all updates are flushed before this is called. + * + * wid Frame id + * pScreen Screen to move the new frame to + * newX, newY New position of the frame + */ +typedef void (*RootlessMoveFrameProc) + (RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY); + +/* + * Resize and move a frame. + * Drawing is stopped and all updates are flushed before this is called. + * + * wid Frame id + * pScreen Screen to move the new frame to + * newX, newY New position of the frame + * newW, newH New size of the frame + * gravity Gravity for window contents (rl_gravity_enum). This is always + * RL_GRAVITY_NONE unless ROOTLESS_RESIZE_GRAVITY is set. + */ +typedef void (*RootlessResizeFrameProc) + (RootlessFrameID wid, ScreenPtr pScreen, + int newX, int newY, unsigned int newW, unsigned int newH, + unsigned int gravity); + +/* + * Change frame ordering (AKA stacking, layering). + * Drawing is stopped before this is called. Unmapped frames are mapped by + * setting their ordering. + * + * wid Frame id + * nextWid Frame id of frame that is now above this one or NULL if this + * frame is at the top. + */ +typedef void (*RootlessRestackFrameProc) + (RootlessFrameID wid, RootlessFrameID nextWid); + +/* + * Change frame's shape. + * Drawing is stopped before this is called. + * + * wid Frame id + * pNewShape New shape for the frame (in frame-local coordinates) + * or NULL if now unshaped. + */ +typedef void (*RootlessReshapeFrameProc) + (RootlessFrameID wid, RegionPtr pNewShape); + +/* + * Unmap a frame. + * + * wid Frame id + */ +typedef void (*RootlessUnmapFrameProc) + (RootlessFrameID wid); + +/* + * Start drawing to a frame. + * Prepare a frame for direct access to its backing buffer. + * + * wid Frame id + * pixelData Address of the backing buffer (returned) + * bytesPerRow Width in bytes of the backing buffer (returned) + */ +typedef void (*RootlessStartDrawingProc) + (RootlessFrameID wid, char **pixelData, int *bytesPerRow); + +/* + * Stop drawing to a frame. + * No drawing to the frame's backing buffer will occur until drawing + * is started again. + * + * wid Frame id + * flush Flush drawing updates for this frame to the screen. + */ +typedef void (*RootlessStopDrawingProc) + (RootlessFrameID wid, Bool flush); + +/* + * Flush drawing updates to the screen. + * Drawing is stopped before this is called. + * + * wid Frame id + * pDamage Region containing all the changed pixels in frame-lcoal + * coordinates. This is clipped to the window's clip. + */ +typedef void (*RootlessUpdateRegionProc) + (RootlessFrameID wid, RegionPtr pDamage); + +/* + * Mark damaged rectangles as requiring redisplay to screen. + * + * wid Frame id + * nrects Number of damaged rectangles + * rects Array of damaged rectangles in frame-local coordinates + * shift_x, Vector to shift rectangles by + * shift_y + */ +typedef void (*RootlessDamageRectsProc) + (RootlessFrameID wid, int nrects, const BoxRec * rects, + int shift_x, int shift_y); + +/* + * Switch the window associated with a frame. (Optional) + * When a framed window is reparented, the frame is resized and set to + * use the new top-level parent. If defined this function will be called + * afterwards for implementation specific bookkeeping. + * + * pFrame Frame whose window has switched + * oldWin Previous window wrapped by this frame + */ +typedef void (*RootlessSwitchWindowProc) + (RootlessWindowPtr pFrame, WindowPtr oldWin); + +/* + * Check if window should be reordered. (Optional) + * The underlying window system may animate windows being ordered in. + * We want them to be mapped but remain ordered out until the animation + * completes. If defined this function will be called to check if a + * framed window should be reordered now. If this function returns + * FALSE, the window will still be mapped from the X11 perspective, but + * the RestackFrame function will not be called for its frame. + * + * pFrame Frame to reorder + */ +typedef Bool (*RootlessDoReorderWindowProc) + (RootlessWindowPtr pFrame); + +/* + * Copy bytes. (Optional) + * Source and destinate may overlap and the right thing should happen. + * + * width Bytes to copy per row + * height Number of rows + * src Source data + * srcRowBytes Width of source in bytes + * dst Destination data + * dstRowBytes Width of destination in bytes + */ +typedef void (*RootlessCopyBytesProc) + (unsigned int width, unsigned int height, + const void *src, unsigned int srcRowBytes, + void *dst, unsigned int dstRowBytes); + +/* + * Copy area in frame to another part of frame. (Optional) + * + * wid Frame id + * dstNrects Number of rectangles to copy + * dstRects Array of rectangles to copy + * dx, dy Number of pixels away to copy area + */ +typedef void (*RootlessCopyWindowProc) + (RootlessFrameID wid, int dstNrects, const BoxRec * dstRects, int dx, int dy); + +typedef void (*RootlessHideWindowProc) + (RootlessFrameID wid); + +typedef void (*RootlessUpdateColormapProc) + (RootlessFrameID wid, ScreenPtr pScreen); + +/* + * Rootless implementation function list + */ +typedef struct _RootlessFrameProcs { + RootlessCreateFrameProc CreateFrame; + RootlessDestroyFrameProc DestroyFrame; + + RootlessMoveFrameProc MoveFrame; + RootlessResizeFrameProc ResizeFrame; + RootlessRestackFrameProc RestackFrame; + RootlessReshapeFrameProc ReshapeFrame; + RootlessUnmapFrameProc UnmapFrame; + + RootlessStartDrawingProc StartDrawing; + RootlessStopDrawingProc StopDrawing; + RootlessUpdateRegionProc UpdateRegion; + RootlessDamageRectsProc DamageRects; + + /* Optional frame functions */ + RootlessSwitchWindowProc SwitchWindow; + RootlessDoReorderWindowProc DoReorderWindow; + RootlessHideWindowProc HideWindow; + RootlessUpdateColormapProc UpdateColormap; + + /* Optional acceleration functions */ + RootlessCopyBytesProc CopyBytes; + RootlessCopyWindowProc CopyWindow; +} RootlessFrameProcsRec, *RootlessFrameProcsPtr; + +/* + * Initialize rootless mode on the given screen. + */ +Bool RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs); + +/* + * Return the frame ID for the physical window displaying the given window. + * + * create If true and the window has no frame, attempt to create one + */ +RootlessFrameID RootlessFrameForWindow(WindowPtr pWin, Bool create); + +/* + * Return the top-level parent of a window. + * The root is the top-level parent of itself, even though the root is + * not otherwise considered to be a top-level window. + */ +WindowPtr TopLevelParent(WindowPtr pWindow); + +/* + * Prepare a window for direct access to its backing buffer. + */ +void RootlessStartDrawing(WindowPtr pWindow); + +/* + * Finish drawing to a window's backing buffer. + * + * flush If true, damaged areas are flushed to the screen. + */ +void RootlessStopDrawing(WindowPtr pWindow, Bool flush); + +/* + * Alocate a new screen pixmap. + * miCreateScreenResources does not do this properly with a null + * framebuffer pointer. + */ +void RootlessUpdateScreenPixmap(ScreenPtr pScreen); + +/* + * Reposition all windows on a screen to their correct positions. + */ +void RootlessRepositionWindows(ScreenPtr pScreen); + +/* + * Bring all windows to the front of the native stack + */ +void RootlessOrderAllWindows(Bool include_unhitable); +#endif /* _ROOTLESS_H */ diff --git a/xorg-server/miext/rootless/rootlessCommon.c b/xorg-server/miext/rootless/rootlessCommon.c index 3ea3e5970..d8f43bd1b 100644 --- a/xorg-server/miext/rootless/rootlessCommon.c +++ b/xorg-server/miext/rootless/rootlessCommon.c @@ -1,448 +1,460 @@ -/*
- * Common rootless definitions and code
- */
-/*
- * Copyright (c) 2001 Greg Parker. All Rights Reserved.
- * Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved.
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name(s) of the above copyright
- * holders shall not be used in advertising or otherwise to promote the sale,
- * use or other dealings in this Software without prior written authorization.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stddef.h> /* For NULL */
-#include <limits.h> /* For CHAR_BIT */
-
-#include "rootlessCommon.h"
-#include "colormapst.h"
-
-unsigned int rootless_CopyBytes_threshold = 0;
-unsigned int rootless_CopyWindow_threshold = 0;
-int rootlessGlobalOffsetX = 0;
-int rootlessGlobalOffsetY = 0;
-
-RegionRec rootlessHugeRoot = {{-32767, -32767, 32767, 32767}, NULL};
-
-/* Following macro from miregion.c */
-
-/* true iff two Boxes overlap */
-#define EXTENTCHECK(r1,r2) \
- (!( ((r1)->x2 <= (r2)->x1) || \
- ((r1)->x1 >= (r2)->x2) || \
- ((r1)->y2 <= (r2)->y1) || \
- ((r1)->y1 >= (r2)->y2) ) )
-
-
-/*
- * TopLevelParent
- * Returns the top-level parent of pWindow.
- * The root is the top-level parent of itself, even though the root is
- * not otherwise considered to be a top-level window.
- */
-WindowPtr
-TopLevelParent(WindowPtr pWindow)
-{
- WindowPtr top;
-
- if (IsRoot(pWindow))
- return pWindow;
-
- top = pWindow;
- while (top && ! IsTopLevel(top))
- top = top->parent;
-
- return top;
-}
-
-
-/*
- * IsFramedWindow
- * Returns TRUE if this window is visible inside a frame
- * (e.g. it is visible and has a top-level or root parent)
- */
-Bool
-IsFramedWindow(WindowPtr pWin)
-{
- WindowPtr top;
-
- if (!dixPrivateKeyRegistered(&rootlessWindowPrivateKeyRec))
- return FALSE;
-
- if (!pWin->realized)
- return FALSE;
- top = TopLevelParent(pWin);
-
- return (top && WINREC(top));
-}
-
-Bool
-RootlessResolveColormap (ScreenPtr pScreen, int first_color,
- int n_colors, uint32_t *colors)
-{
- int last, i;
- ColormapPtr map;
-
- map = RootlessGetColormap (pScreen);
- if (map == NULL || map->class != PseudoColor) return FALSE;
-
- last = min (map->pVisual->ColormapEntries, first_color + n_colors);
- for (i = max (0, first_color); i < last; i++) {
- Entry *ent = map->red + i;
- uint16_t red, green, blue;
-
- if (!ent->refcnt) continue;
- if (ent->fShared) {
- red = ent->co.shco.red->color;
- green = ent->co.shco.green->color;
- blue = ent->co.shco.blue->color;
- } else {
- red = ent->co.local.red;
- green = ent->co.local.green;
- blue = ent->co.local.blue;
- }
-
- colors[i - first_color] = (0xFF000000UL
- | ((uint32_t) red & 0xff00) << 8
- | (green & 0xff00)
- | (blue >> 8));
- }
-
- return TRUE;
-}
-
-
-/*
- * RootlessStartDrawing
- * Prepare a window for direct access to its backing buffer.
- * Each top-level parent has a Pixmap representing its backing buffer,
- * which all of its children inherit.
- */
-void RootlessStartDrawing(WindowPtr pWindow)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- WindowPtr top = TopLevelParent(pWindow);
- RootlessWindowRec *winRec;
- PixmapPtr curPixmap;
-
- if (top == NULL)
- return;
- winRec = WINREC(top);
- if (winRec == NULL)
- return;
-
- // Make sure the window's top-level parent is prepared for drawing.
- if (!winRec->is_drawing) {
- int bw = wBorderWidth(top);
-
- SCREENREC(pScreen)->imp->StartDrawing(winRec->wid, &winRec->pixelData,
- &winRec->bytesPerRow);
-
- winRec->pixmap =
- GetScratchPixmapHeader(pScreen, winRec->width, winRec->height,
- top->drawable.depth,
- top->drawable.bitsPerPixel,
- winRec->bytesPerRow,
- winRec->pixelData);
- SetPixmapBaseToScreen(winRec->pixmap,
- top->drawable.x - bw, top->drawable.y - bw);
-
- winRec->is_drawing = TRUE;
- }
-
- curPixmap = pScreen->GetWindowPixmap(pWindow);
- if (curPixmap == winRec->pixmap)
- {
- RL_DEBUG_MSG("Window %p already has winRec->pixmap %p; not pushing\n", pWindow, winRec->pixmap);
- }
- else
- {
- PixmapPtr oldPixmap = dixLookupPrivate(&pWindow->devPrivates, rootlessWindowOldPixmapPrivateKey);
- if (oldPixmap != NULL)
- {
- if (oldPixmap == curPixmap)
- RL_DEBUG_MSG("Window %p's curPixmap %p is the same as its oldPixmap; strange\n", pWindow, curPixmap);
- else
- RL_DEBUG_MSG("Window %p's existing oldPixmap %p being lost!\n", pWindow, oldPixmap);
- }
- dixSetPrivate(&pWindow->devPrivates, rootlessWindowOldPixmapPrivateKey, curPixmap);
- pScreen->SetWindowPixmap(pWindow, winRec->pixmap);
- }
-}
-
-
-/*
- * RootlessStopDrawing
- * Stop drawing to a window's backing buffer. If flush is true,
- * damaged regions are flushed to the screen.
- */
-static int RestorePreDrawingPixmapVisitor(WindowPtr pWindow, pointer data)
-{
- RootlessWindowRec *winRec = (RootlessWindowRec*)data;
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- PixmapPtr exPixmap = pScreen->GetWindowPixmap(pWindow);
- PixmapPtr oldPixmap = dixLookupPrivate(&pWindow->devPrivates, rootlessWindowOldPixmapPrivateKey);
- if (oldPixmap == NULL)
- {
- if (exPixmap == winRec->pixmap)
- RL_DEBUG_MSG("Window %p appears to be in drawing mode (ex-pixmap %p equals winRec->pixmap, which is being freed) but has no oldPixmap!\n", pWindow, exPixmap);
- }
- else
- {
- if (exPixmap != winRec->pixmap)
- RL_DEBUG_MSG("Window %p appears to be in drawing mode (oldPixmap %p) but ex-pixmap %p not winRec->pixmap %p!\n", pWindow, oldPixmap, exPixmap, winRec->pixmap);
- if (oldPixmap == winRec->pixmap)
- RL_DEBUG_MSG("Window %p's oldPixmap %p is winRec->pixmap, which has just been freed!\n", pWindow, oldPixmap);
- pScreen->SetWindowPixmap(pWindow, oldPixmap);
- dixSetPrivate(&pWindow->devPrivates, rootlessWindowOldPixmapPrivateKey, NULL);
- }
- return WT_WALKCHILDREN;
-}
-
-void RootlessStopDrawing(WindowPtr pWindow, Bool flush)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- WindowPtr top = TopLevelParent(pWindow);
- RootlessWindowRec *winRec;
-
- if (top == NULL)
- return;
- winRec = WINREC(top);
- if (winRec == NULL)
- return;
-
- if (winRec->is_drawing) {
- SCREENREC(pScreen)->imp->StopDrawing(winRec->wid, flush);
-
- FreeScratchPixmapHeader(winRec->pixmap);
- TraverseTree(top, RestorePreDrawingPixmapVisitor, (pointer)winRec);
- winRec->pixmap = NULL;
-
- winRec->is_drawing = FALSE;
- }
- else if (flush) {
- SCREENREC(pScreen)->imp->UpdateRegion(winRec->wid, NULL);
- }
-
- if (flush && winRec->is_reorder_pending) {
- winRec->is_reorder_pending = FALSE;
- RootlessReorderWindow(pWindow);
- }
-}
-
-
-/*
- * RootlessDamageRegion
- * Mark a damaged region as requiring redisplay to screen.
- * pRegion is in GLOBAL coordinates.
- */
-void
-RootlessDamageRegion(WindowPtr pWindow, RegionPtr pRegion)
-{
- RootlessWindowRec *winRec;
- RegionRec clipped;
- WindowPtr pTop;
- BoxPtr b1, b2;
-
- RL_DEBUG_MSG("Damaged win 0x%x ", pWindow);
-
- pTop = TopLevelParent(pWindow);
- if (pTop == NULL)
- return;
-
- winRec = WINREC(pTop);
- if (winRec == NULL)
- return;
-
- /* We need to intersect the drawn region with the clip of the window
- to avoid marking places we didn't actually draw (which can cause
- problems when the window has an extra client-side backing store)
-
- But this is a costly operation and since we'll normally just be
- drawing inside the clip, go to some lengths to avoid the general
- case intersection. */
-
- b1 = RegionExtents(&pWindow->borderClip);
- b2 = RegionExtents(pRegion);
-
- if (EXTENTCHECK(b1, b2)) {
- /* Regions may overlap. */
-
- if (RegionNumRects(pRegion) == 1) {
- int in;
-
- /* Damaged region only has a single rect, so we can
- just compare that against the region */
-
- in = RegionContainsRect(&pWindow->borderClip,
- RegionRects (pRegion));
- if (in == rgnIN) {
- /* clip totally contains pRegion */
-
- SCREENREC(pWindow->drawable.pScreen)->imp->
- DamageRects(winRec->wid,
- RegionNumRects(pRegion),
- RegionRects(pRegion),
- -winRec->x, -winRec->y);
-
- RootlessQueueRedisplay(pTop->drawable.pScreen);
- goto out;
- }
- else if (in == rgnOUT) {
- /* clip doesn't contain pRegion */
-
- goto out;
- }
- }
-
- /* clip overlaps pRegion, need to intersect */
-
- RegionNull(&clipped);
- RegionIntersect(&clipped, &pWindow->borderClip, pRegion);
-
- SCREENREC(pWindow->drawable.pScreen)->imp->
- DamageRects(winRec->wid,
- RegionNumRects(&clipped),
- RegionRects(&clipped),
- -winRec->x, -winRec->y);
-
- RegionUninit(&clipped);
-
- RootlessQueueRedisplay(pTop->drawable.pScreen);
- }
-
-out:
-#ifdef ROOTLESSDEBUG
- {
- BoxRec *box = RegionRects(pRegion), *end;
- int numBox = RegionNumRects(pRegion);
-
- for (end = box+numBox; box < end; box++) {
- RL_DEBUG_MSG("Damage rect: %i, %i, %i, %i\n",
- box->x1, box->x2, box->y1, box->y2);
- }
- }
-#endif
- return;
-}
-
-
-/*
- * RootlessDamageBox
- * Mark a damaged box as requiring redisplay to screen.
- * pRegion is in GLOBAL coordinates.
- */
-void
-RootlessDamageBox(WindowPtr pWindow, BoxPtr pBox)
-{
- RegionRec region;
-
- RegionInit(®ion, pBox, 1);
-
- RootlessDamageRegion(pWindow, ®ion);
-
- RegionUninit(®ion); /* no-op */
-}
-
-
-/*
- * RootlessDamageRect
- * Mark a damaged rectangle as requiring redisplay to screen.
- * (x, y, w, h) is in window-local coordinates.
- */
-void
-RootlessDamageRect(WindowPtr pWindow, int x, int y, int w, int h)
-{
- BoxRec box;
- RegionRec region;
-
- x += pWindow->drawable.x;
- y += pWindow->drawable.y;
-
- box.x1 = x;
- box.x2 = x + w;
- box.y1 = y;
- box.y2 = y + h;
-
- RegionInit(®ion, &box, 1);
-
- RootlessDamageRegion(pWindow, ®ion);
-
- RegionUninit(®ion); /* no-op */
-}
-
-
-/*
- * RootlessRedisplay
- * Stop drawing and redisplay the damaged region of a window.
- */
-void
-RootlessRedisplay(WindowPtr pWindow)
-{
- RootlessStopDrawing(pWindow, TRUE);
-}
-
-
-/*
- * RootlessRepositionWindows
- * Reposition all windows on a screen to their correct positions.
- */
-void
-RootlessRepositionWindows(ScreenPtr pScreen)
-{
- WindowPtr root = pScreen->root;
- WindowPtr win;
-
- if (root != NULL) {
- RootlessRepositionWindow(root);
-
- for (win = root->firstChild; win; win = win->nextSib) {
- if (WINREC(win) != NULL)
- RootlessRepositionWindow(win);
- }
- }
-}
-
-
-/*
- * RootlessRedisplayScreen
- * Walk every window on a screen and redisplay the damaged regions.
- */
-void
-RootlessRedisplayScreen(ScreenPtr pScreen)
-{
- WindowPtr root = pScreen->root;
-
- if (root != NULL) {
- WindowPtr win;
-
- RootlessRedisplay(root);
- for (win = root->firstChild; win; win = win->nextSib) {
- if (WINREC(win) != NULL) {
- RootlessRedisplay(win);
- }
- }
- }
-}
+/* + * Common rootless definitions and code + */ +/* + * Copyright (c) 2001 Greg Parker. All Rights Reserved. + * Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved. + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name(s) of the above copyright + * holders shall not be used in advertising or otherwise to promote the sale, + * use or other dealings in this Software without prior written authorization. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stddef.h> /* For NULL */ +#include <limits.h> /* For CHAR_BIT */ + +#include "rootlessCommon.h" +#include "colormapst.h" + +unsigned int rootless_CopyBytes_threshold = 0; +unsigned int rootless_CopyWindow_threshold = 0; +int rootlessGlobalOffsetX = 0; +int rootlessGlobalOffsetY = 0; + +RegionRec rootlessHugeRoot = { {-32767, -32767, 32767, 32767}, NULL }; + +/* Following macro from miregion.c */ + +/* true iff two Boxes overlap */ +#define EXTENTCHECK(r1,r2) \ + (!( ((r1)->x2 <= (r2)->x1) || \ + ((r1)->x1 >= (r2)->x2) || \ + ((r1)->y2 <= (r2)->y1) || \ + ((r1)->y1 >= (r2)->y2) ) ) + +/* + * TopLevelParent + * Returns the top-level parent of pWindow. + * The root is the top-level parent of itself, even though the root is + * not otherwise considered to be a top-level window. + */ +WindowPtr +TopLevelParent(WindowPtr pWindow) +{ + WindowPtr top; + + if (IsRoot(pWindow)) + return pWindow; + + top = pWindow; + while (top && !IsTopLevel(top)) + top = top->parent; + + return top; +} + +/* + * IsFramedWindow + * Returns TRUE if this window is visible inside a frame + * (e.g. it is visible and has a top-level or root parent) + */ +Bool +IsFramedWindow(WindowPtr pWin) +{ + WindowPtr top; + + if (!dixPrivateKeyRegistered(&rootlessWindowPrivateKeyRec)) + return FALSE; + + if (!pWin->realized) + return FALSE; + top = TopLevelParent(pWin); + + return (top && WINREC(top)); +} + +Bool +RootlessResolveColormap(ScreenPtr pScreen, int first_color, + int n_colors, uint32_t * colors) +{ + int last, i; + ColormapPtr map; + + map = RootlessGetColormap(pScreen); + if (map == NULL || map->class != PseudoColor) + return FALSE; + + last = min(map->pVisual->ColormapEntries, first_color + n_colors); + for (i = max(0, first_color); i < last; i++) { + Entry *ent = map->red + i; + uint16_t red, green, blue; + + if (!ent->refcnt) + continue; + if (ent->fShared) { + red = ent->co.shco.red->color; + green = ent->co.shco.green->color; + blue = ent->co.shco.blue->color; + } + else { + red = ent->co.local.red; + green = ent->co.local.green; + blue = ent->co.local.blue; + } + + colors[i - first_color] = (0xFF000000UL + | ((uint32_t) red & 0xff00) << 8 + | (green & 0xff00) + | (blue >> 8)); + } + + return TRUE; +} + +/* + * RootlessStartDrawing + * Prepare a window for direct access to its backing buffer. + * Each top-level parent has a Pixmap representing its backing buffer, + * which all of its children inherit. + */ +void +RootlessStartDrawing(WindowPtr pWindow) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + WindowPtr top = TopLevelParent(pWindow); + RootlessWindowRec *winRec; + PixmapPtr curPixmap; + + if (top == NULL) + return; + winRec = WINREC(top); + if (winRec == NULL) + return; + + // Make sure the window's top-level parent is prepared for drawing. + if (!winRec->is_drawing) { + int bw = wBorderWidth(top); + + SCREENREC(pScreen)->imp->StartDrawing(winRec->wid, &winRec->pixelData, + &winRec->bytesPerRow); + + winRec->pixmap = + GetScratchPixmapHeader(pScreen, winRec->width, winRec->height, + top->drawable.depth, + top->drawable.bitsPerPixel, + winRec->bytesPerRow, winRec->pixelData); + SetPixmapBaseToScreen(winRec->pixmap, + top->drawable.x - bw, top->drawable.y - bw); + + winRec->is_drawing = TRUE; + } + + curPixmap = pScreen->GetWindowPixmap(pWindow); + if (curPixmap == winRec->pixmap) { + RL_DEBUG_MSG("Window %p already has winRec->pixmap %p; not pushing\n", + pWindow, winRec->pixmap); + } + else { + PixmapPtr oldPixmap = + dixLookupPrivate(&pWindow->devPrivates, + rootlessWindowOldPixmapPrivateKey); + if (oldPixmap != NULL) { + if (oldPixmap == curPixmap) + RL_DEBUG_MSG + ("Window %p's curPixmap %p is the same as its oldPixmap; strange\n", + pWindow, curPixmap); + else + RL_DEBUG_MSG("Window %p's existing oldPixmap %p being lost!\n", + pWindow, oldPixmap); + } + dixSetPrivate(&pWindow->devPrivates, rootlessWindowOldPixmapPrivateKey, + curPixmap); + pScreen->SetWindowPixmap(pWindow, winRec->pixmap); + } +} + +/* + * RootlessStopDrawing + * Stop drawing to a window's backing buffer. If flush is true, + * damaged regions are flushed to the screen. + */ +static int +RestorePreDrawingPixmapVisitor(WindowPtr pWindow, pointer data) +{ + RootlessWindowRec *winRec = (RootlessWindowRec *) data; + ScreenPtr pScreen = pWindow->drawable.pScreen; + PixmapPtr exPixmap = pScreen->GetWindowPixmap(pWindow); + PixmapPtr oldPixmap = + dixLookupPrivate(&pWindow->devPrivates, + rootlessWindowOldPixmapPrivateKey); + if (oldPixmap == NULL) { + if (exPixmap == winRec->pixmap) + RL_DEBUG_MSG + ("Window %p appears to be in drawing mode (ex-pixmap %p equals winRec->pixmap, which is being freed) but has no oldPixmap!\n", + pWindow, exPixmap); + } + else { + if (exPixmap != winRec->pixmap) + RL_DEBUG_MSG + ("Window %p appears to be in drawing mode (oldPixmap %p) but ex-pixmap %p not winRec->pixmap %p!\n", + pWindow, oldPixmap, exPixmap, winRec->pixmap); + if (oldPixmap == winRec->pixmap) + RL_DEBUG_MSG + ("Window %p's oldPixmap %p is winRec->pixmap, which has just been freed!\n", + pWindow, oldPixmap); + pScreen->SetWindowPixmap(pWindow, oldPixmap); + dixSetPrivate(&pWindow->devPrivates, rootlessWindowOldPixmapPrivateKey, + NULL); + } + return WT_WALKCHILDREN; +} + +void +RootlessStopDrawing(WindowPtr pWindow, Bool flush) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + WindowPtr top = TopLevelParent(pWindow); + RootlessWindowRec *winRec; + + if (top == NULL) + return; + winRec = WINREC(top); + if (winRec == NULL) + return; + + if (winRec->is_drawing) { + SCREENREC(pScreen)->imp->StopDrawing(winRec->wid, flush); + + FreeScratchPixmapHeader(winRec->pixmap); + TraverseTree(top, RestorePreDrawingPixmapVisitor, (pointer) winRec); + winRec->pixmap = NULL; + + winRec->is_drawing = FALSE; + } + else if (flush) { + SCREENREC(pScreen)->imp->UpdateRegion(winRec->wid, NULL); + } + + if (flush && winRec->is_reorder_pending) { + winRec->is_reorder_pending = FALSE; + RootlessReorderWindow(pWindow); + } +} + +/* + * RootlessDamageRegion + * Mark a damaged region as requiring redisplay to screen. + * pRegion is in GLOBAL coordinates. + */ +void +RootlessDamageRegion(WindowPtr pWindow, RegionPtr pRegion) +{ + RootlessWindowRec *winRec; + RegionRec clipped; + WindowPtr pTop; + BoxPtr b1, b2; + + RL_DEBUG_MSG("Damaged win 0x%x ", pWindow); + + pTop = TopLevelParent(pWindow); + if (pTop == NULL) + return; + + winRec = WINREC(pTop); + if (winRec == NULL) + return; + + /* We need to intersect the drawn region with the clip of the window + to avoid marking places we didn't actually draw (which can cause + problems when the window has an extra client-side backing store) + + But this is a costly operation and since we'll normally just be + drawing inside the clip, go to some lengths to avoid the general + case intersection. */ + + b1 = RegionExtents(&pWindow->borderClip); + b2 = RegionExtents(pRegion); + + if (EXTENTCHECK(b1, b2)) { + /* Regions may overlap. */ + + if (RegionNumRects(pRegion) == 1) { + int in; + + /* Damaged region only has a single rect, so we can + just compare that against the region */ + + in = RegionContainsRect(&pWindow->borderClip, RegionRects(pRegion)); + if (in == rgnIN) { + /* clip totally contains pRegion */ + + SCREENREC(pWindow->drawable.pScreen)->imp->DamageRects(winRec-> + wid, + RegionNumRects + (pRegion), + RegionRects + (pRegion), + -winRec-> + x, + -winRec-> + y); + + RootlessQueueRedisplay(pTop->drawable.pScreen); + goto out; + } + else if (in == rgnOUT) { + /* clip doesn't contain pRegion */ + + goto out; + } + } + + /* clip overlaps pRegion, need to intersect */ + + RegionNull(&clipped); + RegionIntersect(&clipped, &pWindow->borderClip, pRegion); + + SCREENREC(pWindow->drawable.pScreen)->imp->DamageRects(winRec->wid, + RegionNumRects + (&clipped), + RegionRects + (&clipped), + -winRec->x, + -winRec->y); + + RegionUninit(&clipped); + + RootlessQueueRedisplay(pTop->drawable.pScreen); + } + + out: +#ifdef ROOTLESSDEBUG + { + BoxRec *box = RegionRects(pRegion), *end; + int numBox = RegionNumRects(pRegion); + + for (end = box + numBox; box < end; box++) { + RL_DEBUG_MSG("Damage rect: %i, %i, %i, %i\n", + box->x1, box->x2, box->y1, box->y2); + } + } +#endif + return; +} + +/* + * RootlessDamageBox + * Mark a damaged box as requiring redisplay to screen. + * pRegion is in GLOBAL coordinates. + */ +void +RootlessDamageBox(WindowPtr pWindow, BoxPtr pBox) +{ + RegionRec region; + + RegionInit(®ion, pBox, 1); + + RootlessDamageRegion(pWindow, ®ion); + + RegionUninit(®ion); /* no-op */ +} + +/* + * RootlessDamageRect + * Mark a damaged rectangle as requiring redisplay to screen. + * (x, y, w, h) is in window-local coordinates. + */ +void +RootlessDamageRect(WindowPtr pWindow, int x, int y, int w, int h) +{ + BoxRec box; + RegionRec region; + + x += pWindow->drawable.x; + y += pWindow->drawable.y; + + box.x1 = x; + box.x2 = x + w; + box.y1 = y; + box.y2 = y + h; + + RegionInit(®ion, &box, 1); + + RootlessDamageRegion(pWindow, ®ion); + + RegionUninit(®ion); /* no-op */ +} + +/* + * RootlessRedisplay + * Stop drawing and redisplay the damaged region of a window. + */ +void +RootlessRedisplay(WindowPtr pWindow) +{ + RootlessStopDrawing(pWindow, TRUE); +} + +/* + * RootlessRepositionWindows + * Reposition all windows on a screen to their correct positions. + */ +void +RootlessRepositionWindows(ScreenPtr pScreen) +{ + WindowPtr root = pScreen->root; + WindowPtr win; + + if (root != NULL) { + RootlessRepositionWindow(root); + + for (win = root->firstChild; win; win = win->nextSib) { + if (WINREC(win) != NULL) + RootlessRepositionWindow(win); + } + } +} + +/* + * RootlessRedisplayScreen + * Walk every window on a screen and redisplay the damaged regions. + */ +void +RootlessRedisplayScreen(ScreenPtr pScreen) +{ + WindowPtr root = pScreen->root; + + if (root != NULL) { + WindowPtr win; + + RootlessRedisplay(root); + for (win = root->firstChild; win; win = win->nextSib) { + if (WINREC(win) != NULL) { + RootlessRedisplay(win); + } + } + } +} diff --git a/xorg-server/miext/rootless/rootlessGC.c b/xorg-server/miext/rootless/rootlessGC.c index 21a3bd806..932899591 100644 --- a/xorg-server/miext/rootless/rootlessGC.c +++ b/xorg-server/miext/rootless/rootlessGC.c @@ -1,1460 +1,1487 @@ -/*
- * Graphics Context support for generic rootless X server
- */
-/*
- * Copyright (c) 2001 Greg Parker. All Rights Reserved.
- * Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved.
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name(s) of the above copyright
- * holders shall not be used in advertising or otherwise to promote the sale,
- * use or other dealings in this Software without prior written authorization.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stddef.h> /* For NULL */
-#include "mi.h"
-#include "scrnintstr.h"
-#include "gcstruct.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "dixfontstr.h"
-#include "mivalidate.h"
-#include "fb.h"
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "rootlessCommon.h"
-
-
-// GC functions
-static void RootlessValidateGC(GCPtr pGC, unsigned long changes,
- DrawablePtr pDrawable);
-static void RootlessChangeGC(GCPtr pGC, unsigned long mask);
-static void RootlessCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
-static void RootlessDestroyGC(GCPtr pGC);
-static void RootlessChangeClip(GCPtr pGC, int type, pointer pvalue,
- int nrects);
-static void RootlessDestroyClip(GCPtr pGC);
-static void RootlessCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
-
-Bool RootlessCreateGC(GCPtr pGC);
-
-GCFuncs rootlessGCFuncs = {
- RootlessValidateGC,
- RootlessChangeGC,
- RootlessCopyGC,
- RootlessDestroyGC,
- RootlessChangeClip,
- RootlessDestroyClip,
- RootlessCopyClip,
-};
-
-// GC operations
-static void RootlessFillSpans(DrawablePtr dst, GCPtr pGC, int nInit,
- DDXPointPtr pptInit, int *pwidthInit,
- int sorted);
-static void RootlessSetSpans(DrawablePtr dst, GCPtr pGC, char *pSrc,
- DDXPointPtr pptInit, int *pwidthInit,
- int nspans, int sorted);
-static void RootlessPutImage(DrawablePtr dst, GCPtr pGC,
- int depth, int x, int y, int w, int h,
- int leftPad, int format, char *pBits);
-static RegionPtr RootlessCopyArea(DrawablePtr pSrc, DrawablePtr dst, GCPtr pGC,
- int srcx, int srcy, int w, int h,
- int dstx, int dsty);
-static RegionPtr RootlessCopyPlane(DrawablePtr pSrc, DrawablePtr dst,
- GCPtr pGC, int srcx, int srcy,
- int w, int h, int dstx, int dsty,
- unsigned long plane);
-static void RootlessPolyPoint(DrawablePtr dst, GCPtr pGC,
- int mode, int npt, DDXPointPtr pptInit);
-static void RootlessPolylines(DrawablePtr dst, GCPtr pGC,
- int mode, int npt, DDXPointPtr pptInit);
-static void RootlessPolySegment(DrawablePtr dst, GCPtr pGC,
- int nseg, xSegment *pSeg);
-static void RootlessPolyRectangle(DrawablePtr dst, GCPtr pGC,
- int nRects, xRectangle *pRects);
-static void RootlessPolyArc(DrawablePtr dst, GCPtr pGC, int narcs, xArc *parcs);
-static void RootlessFillPolygon(DrawablePtr dst, GCPtr pGC,
- int shape, int mode, int count,
- DDXPointPtr pptInit);
-static void RootlessPolyFillRect(DrawablePtr dst, GCPtr pGC,
- int nRectsInit, xRectangle *pRectsInit);
-static void RootlessPolyFillArc(DrawablePtr dst, GCPtr pGC,
- int narcsInit, xArc *parcsInit);
-static int RootlessPolyText8(DrawablePtr dst, GCPtr pGC,
- int x, int y, int count, char *chars);
-static int RootlessPolyText16(DrawablePtr dst, GCPtr pGC,
- int x, int y, int count, unsigned short *chars);
-static void RootlessImageText8(DrawablePtr dst, GCPtr pGC,
- int x, int y, int count, char *chars);
-static void RootlessImageText16(DrawablePtr dst, GCPtr pGC,
- int x, int y, int count, unsigned short *chars);
-static void RootlessImageGlyphBlt(DrawablePtr dst, GCPtr pGC,
- int x, int y, unsigned int nglyphInit,
- CharInfoPtr *ppciInit, pointer unused);
-static void RootlessPolyGlyphBlt(DrawablePtr dst, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, pointer pglyphBase);
-static void RootlessPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr dst,
- int dx, int dy, int xOrg, int yOrg);
-
-
-static GCOps rootlessGCOps = {
- RootlessFillSpans,
- RootlessSetSpans,
- RootlessPutImage,
- RootlessCopyArea,
- RootlessCopyPlane,
- RootlessPolyPoint,
- RootlessPolylines,
- RootlessPolySegment,
- RootlessPolyRectangle,
- RootlessPolyArc,
- RootlessFillPolygon,
- RootlessPolyFillRect,
- RootlessPolyFillArc,
- RootlessPolyText8,
- RootlessPolyText16,
- RootlessImageText8,
- RootlessImageText16,
- RootlessImageGlyphBlt,
- RootlessPolyGlyphBlt,
- RootlessPushPixels
-};
-
-/*
- If ROOTLESS_PROTECT_ALPHA is set, we have to make sure that the alpha
- channel of the on screen windows is always opaque. fb makes this harder
- than it would otherwise be by noticing that a planemask of 0x00ffffff
- includes all bits when depth==24, and so it "optimizes" the planemask to
- 0xffffffff. We work around this by temporarily setting depth=bpp while
- changing the GC.
-
- So the normal situation (in 32 bit mode) is that the planemask is
- 0x00ffffff and thus fb leaves the alpha channel alone. The rootless
- implementation is responsible for setting the alpha channel opaque
- initially.
-
- Unfortunately drawing with a planemask that doesn't have all bits set
- normally causes fb to fall off its fastest paths when blitting and
- filling. So we try to recognize when we can relax the planemask back to
- 0xffffffff, and do that for the duration of the drawing operation,
- setting the alpha channel in fg/bg pixels to opaque at the same time. We
- can do this when drawing op is GXcopy. We can also do this when copying
- from another window since its alpha channel must also be opaque.
-
- The three macros below are used to implement this. Drawing ops that can
- potentially have their planemask relaxed look like:
-
- OP {
- GC_SAVE(gc);
- GCOP_UNWRAP(gc);
-
- ...
-
- if (canAccelxxx(..) && otherwise-suitable)
- GC_UNSET_PM(gc, dst);
-
- gc->funcs->OP(gc, ...);
-
- GC_RESTORE(gc, dst);
- GCOP_WRAP(gc);
- }
-
- */
-
-#define GC_SAVE(pGC) \
- unsigned long _save_fg = (pGC)->fgPixel; \
- unsigned long _save_bg = (pGC)->bgPixel; \
- unsigned long _save_pm = (pGC)->planemask; \
- Bool _changed = FALSE
-
-#define GC_RESTORE(pGC, pDraw) \
- do { \
- if (_changed) { \
- unsigned int depth = (pDraw)->depth; \
- (pGC)->fgPixel = _save_fg; \
- (pGC)->bgPixel = _save_bg; \
- (pGC)->planemask = _save_pm; \
- (pDraw)->depth = (pDraw)->bitsPerPixel; \
- VALIDATE_GC(pGC, GCForeground | GCBackground | \
- GCPlaneMask, pDraw); \
- (pDraw)->depth = depth; \
- } \
- } while (0)
-
-#define GC_UNSET_PM(pGC, pDraw) \
- do { \
- unsigned int mask = RootlessAlphaMask ((pDraw)->bitsPerPixel); \
- if (((pGC)->planemask & mask) != mask) { \
- unsigned int depth = (pDraw)->depth; \
- (pGC)->fgPixel |= mask; \
- (pGC)->bgPixel |= mask; \
- (pGC)->planemask |= mask; \
- (pDraw)->depth = (pDraw)->bitsPerPixel; \
- VALIDATE_GC(pGC, GCForeground | \
- GCBackground | GCPlaneMask, pDraw); \
- (pDraw)->depth = depth; \
- _changed = TRUE; \
- } \
- } while (0)
-
-#define VALIDATE_GC(pGC, changes, pDrawable) \
- do { \
- pGC->funcs->ValidateGC(pGC, changes, pDrawable); \
- if (((WindowPtr) pDrawable)->viewable) { \
- gcrec->originalOps = pGC->ops; \
- } \
- } while(0)
-
-static RootlessWindowRec *
-canAccelBlit (DrawablePtr pDraw, GCPtr pGC)
-{
- WindowPtr pTop;
- RootlessWindowRec *winRec;
- unsigned int pm;
-
- if (pGC->alu != GXcopy)
- return NULL;
-
- if (pDraw->type != DRAWABLE_WINDOW)
- return NULL;
-
- pm = ~RootlessAlphaMask(pDraw->bitsPerPixel);
- if ((pGC->planemask & pm) != pm)
- return NULL;
-
- pTop = TopLevelParent((WindowPtr) pDraw);
- if (pTop == NULL)
- return NULL;
-
- winRec = WINREC(pTop);
- if (winRec == NULL)
- return NULL;
-
- return winRec;
-}
-
-static inline RootlessWindowRec *
-canAccelFill(DrawablePtr pDraw, GCPtr pGC)
-{
- if (pGC->fillStyle != FillSolid)
- return NULL;
-
- return canAccelBlit(pDraw, pGC);
-}
-
-
-/*
- * Screen function to create a graphics context
- */
-Bool
-RootlessCreateGC(GCPtr pGC)
-{
- RootlessGCRec *gcrec;
- RootlessScreenRec *s;
- Bool result;
-
- SCREEN_UNWRAP(pGC->pScreen, CreateGC);
- s = SCREENREC(pGC->pScreen);
- result = s->CreateGC(pGC);
-
- gcrec = (RootlessGCRec *)
- dixLookupPrivate(&pGC->devPrivates, rootlessGCPrivateKey);
- gcrec->originalOps = NULL; // don't wrap ops yet
- gcrec->originalFuncs = pGC->funcs;
- pGC->funcs = &rootlessGCFuncs;
-
- SCREEN_WRAP(pGC->pScreen, CreateGC);
- return result;
-}
-
-
-/*
- * GC funcs
- *
- * These wrap lower level GC funcs.
- * ValidateGC wraps the GC ops iff dest is viewable.
- * All the others just unwrap and call.
- */
-
-// GCFUNC_UNRAP assumes funcs have been wrapped and
-// does not assume ops have been wrapped
-#define GCFUNC_UNWRAP(pGC) \
- RootlessGCRec *gcrec = (RootlessGCRec *) \
- dixLookupPrivate(&(pGC)->devPrivates, rootlessGCPrivateKey); \
- (pGC)->funcs = gcrec->originalFuncs; \
- if (gcrec->originalOps) { \
- (pGC)->ops = gcrec->originalOps; \
-}
-
-#define GCFUNC_WRAP(pGC) \
- gcrec->originalFuncs = (pGC)->funcs; \
- (pGC)->funcs = &rootlessGCFuncs; \
- if (gcrec->originalOps) { \
- gcrec->originalOps = (pGC)->ops; \
- (pGC)->ops = &rootlessGCOps; \
-}
-
-
-static void
-RootlessValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
-{
- GCFUNC_UNWRAP(pGC);
-
- gcrec->originalOps = NULL;
-
- if (pDrawable->type == DRAWABLE_WINDOW)
- {
-#ifdef ROOTLESS_PROTECT_ALPHA
- unsigned int depth = pDrawable->depth;
-
- // We force a planemask so fb doesn't overwrite the alpha channel.
- // Left to its own devices, fb will optimize away the planemask.
- pDrawable->depth = pDrawable->bitsPerPixel;
- pGC->planemask &= ~RootlessAlphaMask(pDrawable->bitsPerPixel);
- VALIDATE_GC(pGC, changes | GCPlaneMask, pDrawable);
- pDrawable->depth = depth;
-#else
- VALIDATE_GC(pGC, changes, pDrawable);
-#endif
- } else {
- pGC->funcs->ValidateGC(pGC, changes, pDrawable);
- }
-
- GCFUNC_WRAP(pGC);
-}
-
-static void RootlessChangeGC(GCPtr pGC, unsigned long mask)
-{
- GCFUNC_UNWRAP(pGC);
- pGC->funcs->ChangeGC(pGC, mask);
- GCFUNC_WRAP(pGC);
-}
-
-static void RootlessCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
-{
- GCFUNC_UNWRAP(pGCDst);
- pGCDst->funcs->CopyGC(pGCSrc, mask, pGCDst);
- GCFUNC_WRAP(pGCDst);
-}
-
-static void RootlessDestroyGC(GCPtr pGC)
-{
- GCFUNC_UNWRAP(pGC);
- pGC->funcs->DestroyGC(pGC);
- GCFUNC_WRAP(pGC);
-}
-
-static void RootlessChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
-{
- GCFUNC_UNWRAP(pGC);
- pGC->funcs->ChangeClip(pGC, type, pvalue, nrects);
- GCFUNC_WRAP(pGC);
-}
-
-static void RootlessDestroyClip(GCPtr pGC)
-{
- GCFUNC_UNWRAP(pGC);
- pGC->funcs->DestroyClip(pGC);
- GCFUNC_WRAP(pGC);
-}
-
-static void RootlessCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
-{
- GCFUNC_UNWRAP(pgcDst);
- pgcDst->funcs->CopyClip(pgcDst, pgcSrc);
- GCFUNC_WRAP(pgcDst);
-}
-
-
-/*
- * GC ops
- *
- * We can't use shadowfb because shadowfb assumes one pixmap
- * and our root window is a special case.
- * However, much of this code is copied from shadowfb.
- */
-
-// assumes both funcs and ops are wrapped
-#define GCOP_UNWRAP(pGC) \
- RootlessGCRec *gcrec = (RootlessGCRec *) \
- dixLookupPrivate(&(pGC)->devPrivates, rootlessGCPrivateKey); \
- GCFuncs *saveFuncs = pGC->funcs; \
- (pGC)->funcs = gcrec->originalFuncs; \
- (pGC)->ops = gcrec->originalOps;
-
-#define GCOP_WRAP(pGC) \
- gcrec->originalOps = (pGC)->ops; \
- (pGC)->funcs = saveFuncs; \
- (pGC)->ops = &rootlessGCOps;
-
-static void
-RootlessFillSpans(DrawablePtr dst, GCPtr pGC, int nInit,
- DDXPointPtr pptInit, int *pwidthInit, int sorted)
-{
- GC_SAVE(pGC);
- GCOP_UNWRAP(pGC);
- RL_DEBUG_MSG("fill spans start ");
-
- if (nInit <= 0) {
- pGC->ops->FillSpans(dst, pGC, nInit, pptInit, pwidthInit, sorted);
- } else {
- DDXPointPtr ppt = pptInit;
- int *pwidth = pwidthInit;
- int i = nInit;
- BoxRec box;
-
- box.x1 = ppt->x;
- box.x2 = box.x1 + *pwidth;
- box.y2 = box.y1 = ppt->y;
-
- while (--i) {
- ppt++;
- pwidth++;
- if (box.x1 > ppt->x)
- box.x1 = ppt->x;
- if (box.x2 < (ppt->x + *pwidth))
- box.x2 = ppt->x + *pwidth;
- if (box.y1 > ppt->y)
- box.y1 = ppt->y;
- else if (box.y2 < ppt->y)
- box.y2 = ppt->y;
- }
-
- box.y2++;
-
- RootlessStartDrawing((WindowPtr) dst);
-
- if (canAccelFill(dst, pGC))
- {
- GC_UNSET_PM(pGC, dst);
- }
-
- pGC->ops->FillSpans(dst, pGC, nInit, pptInit, pwidthInit, sorted);
-
- TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
- }
-
- GC_RESTORE(pGC, dst);
- GCOP_WRAP(pGC);
- RL_DEBUG_MSG("fill spans end\n");
-}
-
-static void
-RootlessSetSpans(DrawablePtr dst, GCPtr pGC, char *pSrc,
- DDXPointPtr pptInit, int *pwidthInit,
- int nspans, int sorted)
-{
- GCOP_UNWRAP(pGC);
- RL_DEBUG_MSG("set spans start ");
-
- if (nspans <= 0) {
- pGC->ops->SetSpans(dst, pGC, pSrc, pptInit, pwidthInit,
- nspans, sorted);
- } else {
- DDXPointPtr ppt = pptInit;
- int *pwidth = pwidthInit;
- int i = nspans;
- BoxRec box;
-
- box.x1 = ppt->x;
- box.x2 = box.x1 + *pwidth;
- box.y2 = box.y1 = ppt->y;
-
- while (--i) {
- ppt++;
- pwidth++;
- if (box.x1 > ppt->x)
- box.x1 = ppt->x;
- if (box.x2 < (ppt->x + *pwidth))
- box.x2 = ppt->x + *pwidth;
- if (box.y1 > ppt->y)
- box.y1 = ppt->y;
- else if (box.y2 < ppt->y)
- box.y2 = ppt->y;
- }
-
- box.y2++;
-
- RootlessStartDrawing((WindowPtr) dst);
- pGC->ops->SetSpans(dst, pGC, pSrc, pptInit, pwidthInit,
- nspans, sorted);
-
- TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
- }
- GCOP_WRAP(pGC);
- RL_DEBUG_MSG("set spans end\n");
-}
-
-static void
-RootlessPutImage(DrawablePtr dst, GCPtr pGC,
- int depth, int x, int y, int w, int h,
- int leftPad, int format, char *pBits)
-{
- BoxRec box;
-
- GCOP_UNWRAP(pGC);
- RL_DEBUG_MSG("put image start ");
-
- RootlessStartDrawing((WindowPtr) dst);
- pGC->ops->PutImage(dst, pGC, depth, x,y,w,h, leftPad, format, pBits);
-
- box.x1 = x + dst->x;
- box.x2 = box.x1 + w;
- box.y1 = y + dst->y;
- box.y2 = box.y1 + h;
-
- TRIM_BOX(box, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
-
- GCOP_WRAP(pGC);
- RL_DEBUG_MSG("put image end\n");
-}
-
-/* changed area is *dest* rect */
-static RegionPtr
-RootlessCopyArea(DrawablePtr pSrc, DrawablePtr dst, GCPtr pGC,
- int srcx, int srcy, int w, int h,
- int dstx, int dsty)
-{
- RegionPtr result;
- BoxRec box;
-
- GC_SAVE(pGC);
- GCOP_UNWRAP(pGC);
-
- RL_DEBUG_MSG("copy area start (src 0x%x, dst 0x%x)", pSrc, dst);
-
- if (pSrc->type == DRAWABLE_WINDOW && IsFramedWindow((WindowPtr)pSrc)) {
- /* If both source and dest are windows, and we're doing
- a simple copy operation, we can remove the alpha-protecting
- planemask (since source has opaque alpha as well) */
-
- if (canAccelBlit(pSrc, pGC))
- {
- GC_UNSET_PM(pGC, dst);
- }
-
- RootlessStartDrawing((WindowPtr) pSrc);
- }
- RootlessStartDrawing((WindowPtr) dst);
- result = pGC->ops->CopyArea(pSrc, dst, pGC, srcx, srcy, w, h, dstx, dsty);
-
- box.x1 = dstx + dst->x;
- box.x2 = box.x1 + w;
- box.y1 = dsty + dst->y;
- box.y2 = box.y1 + h;
-
- TRIM_BOX(box, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
-
- GC_RESTORE(pGC, dst);
- GCOP_WRAP(pGC);
- RL_DEBUG_MSG("copy area end\n");
- return result;
-}
-
-/* changed area is *dest* rect */
-static RegionPtr RootlessCopyPlane(DrawablePtr pSrc, DrawablePtr dst,
- GCPtr pGC, int srcx, int srcy,
- int w, int h, int dstx, int dsty,
- unsigned long plane)
-{
- RegionPtr result;
- BoxRec box;
-
- GCOP_UNWRAP(pGC);
-
- RL_DEBUG_MSG("copy plane start ");
-
- if (pSrc->type == DRAWABLE_WINDOW && IsFramedWindow((WindowPtr)pSrc)) {
- RootlessStartDrawing((WindowPtr) pSrc);
- }
- RootlessStartDrawing((WindowPtr) dst);
- result = pGC->ops->CopyPlane(pSrc, dst, pGC, srcx, srcy, w, h,
- dstx, dsty, plane);
-
- box.x1 = dstx + dst->x;
- box.x2 = box.x1 + w;
- box.y1 = dsty + dst->y;
- box.y2 = box.y1 + h;
-
- TRIM_BOX(box, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
-
- GCOP_WRAP(pGC);
- RL_DEBUG_MSG("copy plane end\n");
- return result;
-}
-
-// Options for size of changed area:
-// 0 = box per point
-// 1 = big box around all points
-// 2 = accumulate point in 20 pixel radius
-#define ROOTLESS_CHANGED_AREA 1
-#define abs(a) ((a) > 0 ? (a) : -(a))
-
-/* changed area is box around all points */
-static void RootlessPolyPoint(DrawablePtr dst, GCPtr pGC,
- int mode, int npt, DDXPointPtr pptInit)
-{
- GCOP_UNWRAP(pGC);
- RL_DEBUG_MSG("polypoint start ");
-
- RootlessStartDrawing((WindowPtr) dst);
- pGC->ops->PolyPoint(dst, pGC, mode, npt, pptInit);
-
- if (npt > 0) {
-#if ROOTLESS_CHANGED_AREA==0
- // box per point
- BoxRec box;
-
- while (npt) {
- box.x1 = pptInit->x;
- box.y1 = pptInit->y;
- box.x2 = box.x1 + 1;
- box.y2 = box.y1 + 1;
-
- TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
-
- npt--;
- pptInit++;
- }
-
-#elif ROOTLESS_CHANGED_AREA==1
- // one big box
- BoxRec box;
-
- box.x2 = box.x1 = pptInit->x;
- box.y2 = box.y1 = pptInit->y;
- while (--npt) {
- pptInit++;
- if (box.x1 > pptInit->x)
- box.x1 = pptInit->x;
- else if (box.x2 < pptInit->x)
- box.x2 = pptInit->x;
- if (box.y1 > pptInit->y)
- box.y1 = pptInit->y;
- else if (box.y2 < pptInit->y)
- box.y2 = pptInit->y;
- }
-
- box.x2++;
- box.y2++;
-
- TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
-
-#elif ROOTLESS_CHANGED_AREA==2
- // clever(?) method: accumulate point in 20-pixel radius
- BoxRec box;
- int firstx, firsty;
-
- box.x2 = box.x1 = firstx = pptInit->x;
- box.y2 = box.y1 = firsty = pptInit->y;
- while (--npt) {
- pptInit++;
- if (abs(pptInit->x - firstx) > 20 ||
- abs(pptInit->y - firsty) > 20) {
- box.x2++;
- box.y2++;
- TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
- box.x2 = box.x1 = firstx = pptInit->x;
- box.y2 = box.y1 = firsty = pptInit->y;
- } else {
- if (box.x1 > pptInit->x) box.x1 = pptInit->x;
- else if (box.x2 < pptInit->x) box.x2 = pptInit->x;
- if (box.y1 > pptInit->y) box.y1 = pptInit->y;
- else if (box.y2 < pptInit->y) box.y2 = pptInit->y;
- }
- }
- box.x2++;
- box.y2++;
- TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox((WindowPtr) dst, &box);
-#endif /* ROOTLESS_CHANGED_AREA */
- }
-
- GCOP_WRAP(pGC);
- RL_DEBUG_MSG("polypoint end\n");
-}
-
-#undef ROOTLESS_CHANGED_AREA
-
-/* changed area is box around each line */
-static void RootlessPolylines(DrawablePtr dst, GCPtr pGC,
- int mode, int npt, DDXPointPtr pptInit)
-{
- GCOP_UNWRAP(pGC);
- RL_DEBUG_MSG("poly lines start ");
-
- RootlessStartDrawing((WindowPtr) dst);
- pGC->ops->Polylines(dst, pGC, mode, npt, pptInit);
-
- if (npt > 0) {
- BoxRec box;
- int extra = pGC->lineWidth >> 1;
-
- box.x2 = box.x1 = pptInit->x;
- box.y2 = box.y1 = pptInit->y;
-
- if (npt > 1) {
- if (pGC->joinStyle == JoinMiter)
- extra = 6 * pGC->lineWidth;
- else if (pGC->capStyle == CapProjecting)
- extra = pGC->lineWidth;
- }
-
- if (mode == CoordModePrevious) {
- int x = box.x1;
- int y = box.y1;
-
- while (--npt) {
- pptInit++;
- x += pptInit->x;
- y += pptInit->y;
- if (box.x1 > x)
- box.x1 = x;
- else if (box.x2 < x)
- box.x2 = x;
- if (box.y1 > y)
- box.y1 = y;
- else if (box.y2 < y)
- box.y2 = y;
- }
- } else {
- while (--npt) {
- pptInit++;
- if (box.x1 > pptInit->x)
- box.x1 = pptInit->x;
- else if (box.x2 < pptInit->x)
- box.x2 = pptInit->x;
- if (box.y1 > pptInit->y)
- box.y1 = pptInit->y;
- else if (box.y2 < pptInit->y)
- box.y2 = pptInit->y;
- }
- }
-
- box.x2++;
- box.y2++;
-
- if (extra) {
- box.x1 -= extra;
- box.x2 += extra;
- box.y1 -= extra;
- box.y2 += extra;
- }
-
- TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
- }
-
- GCOP_WRAP(pGC);
- RL_DEBUG_MSG("poly lines end\n");
-}
-
-/* changed area is box around each line segment */
-static void RootlessPolySegment(DrawablePtr dst, GCPtr pGC,
- int nseg, xSegment *pSeg)
-{
- GCOP_UNWRAP(pGC);
- RL_DEBUG_MSG("poly segment start (win 0x%x)", dst);
-
- RootlessStartDrawing((WindowPtr) dst);
- pGC->ops->PolySegment(dst, pGC, nseg, pSeg);
-
- if (nseg > 0) {
- BoxRec box;
- int extra = pGC->lineWidth;
-
- if (pGC->capStyle != CapProjecting)
- extra >>= 1;
-
- if (pSeg->x2 > pSeg->x1) {
- box.x1 = pSeg->x1;
- box.x2 = pSeg->x2;
- } else {
- box.x2 = pSeg->x1;
- box.x1 = pSeg->x2;
- }
-
- if (pSeg->y2 > pSeg->y1) {
- box.y1 = pSeg->y1;
- box.y2 = pSeg->y2;
- } else {
- box.y2 = pSeg->y1;
- box.y1 = pSeg->y2;
- }
-
- while (--nseg) {
- pSeg++;
- if (pSeg->x2 > pSeg->x1) {
- if (pSeg->x1 < box.x1) box.x1 = pSeg->x1;
- if (pSeg->x2 > box.x2) box.x2 = pSeg->x2;
- } else {
- if (pSeg->x2 < box.x1) box.x1 = pSeg->x2;
- if (pSeg->x1 > box.x2) box.x2 = pSeg->x1;
- }
- if (pSeg->y2 > pSeg->y1) {
- if (pSeg->y1 < box.y1) box.y1 = pSeg->y1;
- if (pSeg->y2 > box.y2) box.y2 = pSeg->y2;
- } else {
- if (pSeg->y2 < box.y1) box.y1 = pSeg->y2;
- if (pSeg->y1 > box.y2) box.y2 = pSeg->y1;
- }
- }
-
- box.x2++;
- box.y2++;
-
- if (extra) {
- box.x1 -= extra;
- box.x2 += extra;
- box.y1 -= extra;
- box.y2 += extra;
- }
-
- TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
- }
-
- GCOP_WRAP(pGC);
- RL_DEBUG_MSG("poly segment end\n");
-}
-
-/* changed area is box around each line (not entire rects) */
-static void RootlessPolyRectangle(DrawablePtr dst, GCPtr pGC,
- int nRects, xRectangle *pRects)
-{
- GCOP_UNWRAP(pGC);
- RL_DEBUG_MSG("poly rectangle start ");
-
- RootlessStartDrawing((WindowPtr) dst);
- pGC->ops->PolyRectangle(dst, pGC, nRects, pRects);
-
- if (nRects > 0) {
- BoxRec box;
- int offset1, offset2, offset3;
-
- offset2 = pGC->lineWidth;
- if (!offset2) offset2 = 1;
- offset1 = offset2 >> 1;
- offset3 = offset2 - offset1;
-
- while (nRects--) {
- box.x1 = pRects->x - offset1;
- box.y1 = pRects->y - offset1;
- box.x2 = box.x1 + pRects->width + offset2;
- box.y2 = box.y1 + offset2;
- TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
-
- box.x1 = pRects->x - offset1;
- box.y1 = pRects->y + offset3;
- box.x2 = box.x1 + offset2;
- box.y2 = box.y1 + pRects->height - offset2;
- TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
-
- box.x1 = pRects->x + pRects->width - offset1;
- box.y1 = pRects->y + offset3;
- box.x2 = box.x1 + offset2;
- box.y2 = box.y1 + pRects->height - offset2;
- TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
-
- box.x1 = pRects->x - offset1;
- box.y1 = pRects->y + pRects->height - offset1;
- box.x2 = box.x1 + pRects->width + offset2;
- box.y2 = box.y1 + offset2;
- TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
-
- pRects++;
- }
- }
-
- GCOP_WRAP(pGC);
- RL_DEBUG_MSG("poly rectangle end\n");
-}
-
-
-/* changed area is box around each arc (assumes all arcs are 360 degrees) */
-static void RootlessPolyArc(DrawablePtr dst, GCPtr pGC, int narcs, xArc *parcs)
-{
- GCOP_UNWRAP(pGC);
- RL_DEBUG_MSG("poly arc start ");
-
- RootlessStartDrawing((WindowPtr) dst);
- pGC->ops->PolyArc(dst, pGC, narcs, parcs);
-
- if (narcs > 0) {
- int extra = pGC->lineWidth >> 1;
- BoxRec box;
-
- box.x1 = parcs->x;
- box.x2 = box.x1 + parcs->width;
- box.y1 = parcs->y;
- box.y2 = box.y1 + parcs->height;
-
- /* should I break these up instead ? */
-
- while (--narcs) {
- parcs++;
- if (box.x1 > parcs->x)
- box.x1 = parcs->x;
- if (box.x2 < (parcs->x + parcs->width))
- box.x2 = parcs->x + parcs->width;
- if (box.y1 > parcs->y)
- box.y1 = parcs->y;
- if (box.y2 < (parcs->y + parcs->height))
- box.y2 = parcs->y + parcs->height;
- }
-
- if (extra) {
- box.x1 -= extra;
- box.x2 += extra;
- box.y1 -= extra;
- box.y2 += extra;
- }
-
- box.x2++;
- box.y2++;
-
- TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
- }
-
- GCOP_WRAP(pGC);
- RL_DEBUG_MSG("poly arc end\n");
-}
-
-
-/* changed area is box around each poly */
-static void RootlessFillPolygon(DrawablePtr dst, GCPtr pGC,
- int shape, int mode, int count,
- DDXPointPtr pptInit)
-{
- GC_SAVE(pGC);
- GCOP_UNWRAP(pGC);
- RL_DEBUG_MSG("fill poly start (win 0x%x, fillStyle 0x%x)", dst,
- pGC->fillStyle);
-
- if (count <= 2) {
- pGC->ops->FillPolygon(dst, pGC, shape, mode, count, pptInit);
- } else {
- DDXPointPtr ppt = pptInit;
- int i = count;
- BoxRec box;
-
- box.x2 = box.x1 = ppt->x;
- box.y2 = box.y1 = ppt->y;
-
- if (mode != CoordModeOrigin) {
- int x = box.x1;
- int y = box.y1;
-
- while (--i) {
- ppt++;
- x += ppt->x;
- y += ppt->y;
- if (box.x1 > x)
- box.x1 = x;
- else if (box.x2 < x)
- box.x2 = x;
- if (box.y1 > y)
- box.y1 = y;
- else if (box.y2 < y)
- box.y2 = y;
- }
- } else {
- while (--i) {
- ppt++;
- if (box.x1 > ppt->x)
- box.x1 = ppt->x;
- else if (box.x2 < ppt->x)
- box.x2 = ppt->x;
- if (box.y1 > ppt->y)
- box.y1 = ppt->y;
- else if (box.y2 < ppt->y)
- box.y2 = ppt->y;
- }
- }
-
- box.x2++;
- box.y2++;
-
- RootlessStartDrawing((WindowPtr) dst);
-
- if (canAccelFill(dst, pGC))
- {
- GC_UNSET_PM(pGC, dst);
- }
-
- pGC->ops->FillPolygon(dst, pGC, shape, mode, count, pptInit);
-
- TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
- }
-
- GC_RESTORE(pGC, dst);
- GCOP_WRAP(pGC);
- RL_DEBUG_MSG("fill poly end\n");
-}
-
-/* changed area is the rects */
-static void RootlessPolyFillRect(DrawablePtr dst, GCPtr pGC,
- int nRectsInit, xRectangle *pRectsInit)
-{
- GC_SAVE(pGC);
- GCOP_UNWRAP(pGC);
- RL_DEBUG_MSG("fill rect start (win 0x%x, fillStyle 0x%x)", dst,
- pGC->fillStyle);
-
- if (nRectsInit <= 0) {
- pGC->ops->PolyFillRect(dst, pGC, nRectsInit, pRectsInit);
- } else {
- BoxRec box;
- xRectangle *pRects = pRectsInit;
- int nRects = nRectsInit;
-
- box.x1 = pRects->x;
- box.x2 = box.x1 + pRects->width;
- box.y1 = pRects->y;
- box.y2 = box.y1 + pRects->height;
-
- while (--nRects) {
- pRects++;
- if (box.x1 > pRects->x)
- box.x1 = pRects->x;
- if (box.x2 < (pRects->x + pRects->width))
- box.x2 = pRects->x + pRects->width;
- if (box.y1 > pRects->y)
- box.y1 = pRects->y;
- if (box.y2 < (pRects->y + pRects->height))
- box.y2 = pRects->y + pRects->height;
- }
-
- RootlessStartDrawing((WindowPtr) dst);
-
- if (canAccelFill(dst, pGC))
- {
- GC_UNSET_PM(pGC, dst);
- }
-
- pGC->ops->PolyFillRect(dst, pGC, nRectsInit, pRectsInit);
-
- TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
- }
-
- GC_RESTORE(pGC, dst);
- GCOP_WRAP(pGC);
- RL_DEBUG_MSG("fill rect end\n");
-}
-
-
-/* changed area is box around each arc (assuming arcs are all 360 degrees) */
-static void RootlessPolyFillArc(DrawablePtr dst, GCPtr pGC,
- int narcsInit, xArc *parcsInit)
-{
- GC_SAVE(pGC);
- GCOP_UNWRAP(pGC);
- RL_DEBUG_MSG("fill arc start ");
-
- if (narcsInit > 0) {
- BoxRec box;
- int narcs = narcsInit;
- xArc *parcs = parcsInit;
-
- box.x1 = parcs->x;
- box.x2 = box.x1 + parcs->width;
- box.y1 = parcs->y;
- box.y2 = box.y1 + parcs->height;
-
- /* should I break these up instead ? */
-
- while (--narcs) {
- parcs++;
- if (box.x1 > parcs->x)
- box.x1 = parcs->x;
- if (box.x2 < (parcs->x + parcs->width))
- box.x2 = parcs->x + parcs->width;
- if (box.y1 > parcs->y)
- box.y1 = parcs->y;
- if (box.y2 < (parcs->y + parcs->height))
- box.y2 = parcs->y + parcs->height;
- }
-
- RootlessStartDrawing((WindowPtr) dst);
-
- if (canAccelFill(dst, pGC))
- {
- GC_UNSET_PM(pGC, dst);
- }
-
- pGC->ops->PolyFillArc(dst, pGC, narcsInit, parcsInit);
-
- TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
- } else {
- pGC->ops->PolyFillArc(dst, pGC, narcsInit, parcsInit);
- }
-
- GC_RESTORE(pGC, dst);
- GCOP_WRAP(pGC);
- RL_DEBUG_MSG("fill arc end\n");
-}
-
-
-static void RootlessImageText8(DrawablePtr dst, GCPtr pGC,
- int x, int y, int count, char *chars)
-{
- GC_SAVE(pGC);
- GCOP_UNWRAP(pGC);
- RL_DEBUG_MSG("imagetext8 start ");
-
- if (count > 0) {
- int top, bot, Min, Max;
- BoxRec box;
-
- top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
- bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
-
- Min = count * FONTMINBOUNDS(pGC->font, characterWidth);
- if (Min > 0) Min = 0;
- Max = count * FONTMAXBOUNDS(pGC->font, characterWidth);
- if (Max < 0) Max = 0;
-
- /* ugh */
- box.x1 = dst->x + x + Min +
- FONTMINBOUNDS(pGC->font, leftSideBearing);
- box.x2 = dst->x + x + Max +
- FONTMAXBOUNDS(pGC->font, rightSideBearing);
-
- box.y1 = dst->y + y - top;
- box.y2 = dst->y + y + bot;
-
- RootlessStartDrawing((WindowPtr) dst);
-
- if (canAccelFill(dst, pGC))
- {
- GC_UNSET_PM(pGC, dst);
- }
-
- pGC->ops->ImageText8(dst, pGC, x, y, count, chars);
-
- TRIM_BOX(box, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
- } else {
- pGC->ops->ImageText8(dst, pGC, x, y, count, chars);
- }
-
- GC_RESTORE(pGC, dst);
- GCOP_WRAP(pGC);
- RL_DEBUG_MSG("imagetext8 end\n");
-}
-
-static int RootlessPolyText8(DrawablePtr dst, GCPtr pGC,
- int x, int y, int count, char *chars)
-{
- int width; // the result, sorta
-
- GCOP_UNWRAP(pGC);
-
- RL_DEBUG_MSG("polytext8 start ");
-
- RootlessStartDrawing((WindowPtr) dst);
- width = pGC->ops->PolyText8(dst, pGC, x, y, count, chars);
- width -= x;
-
- if (width > 0) {
- BoxRec box;
-
- /* ugh */
- box.x1 = dst->x + x + FONTMINBOUNDS(pGC->font, leftSideBearing);
- box.x2 = dst->x + x + FONTMAXBOUNDS(pGC->font, rightSideBearing);
-
- if (count > 1) {
- if (width > 0) box.x2 += width;
- else box.x1 += width;
- }
-
- box.y1 = dst->y + y - FONTMAXBOUNDS(pGC->font, ascent);
- box.y2 = dst->y + y + FONTMAXBOUNDS(pGC->font, descent);
-
- TRIM_BOX(box, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
- }
-
- GCOP_WRAP(pGC);
- RL_DEBUG_MSG("polytext8 end\n");
- return width + x;
-}
-
-static void RootlessImageText16(DrawablePtr dst, GCPtr pGC,
- int x, int y, int count, unsigned short *chars)
-{
- GC_SAVE(pGC);
- GCOP_UNWRAP(pGC);
- RL_DEBUG_MSG("imagetext16 start ");
-
- if (count > 0) {
- int top, bot, Min, Max;
- BoxRec box;
-
- top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
- bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
-
- Min = count * FONTMINBOUNDS(pGC->font, characterWidth);
- if (Min > 0) Min = 0;
- Max = count * FONTMAXBOUNDS(pGC->font, characterWidth);
- if (Max < 0) Max = 0;
-
- /* ugh */
- box.x1 = dst->x + x + Min +
- FONTMINBOUNDS(pGC->font, leftSideBearing);
- box.x2 = dst->x + x + Max +
- FONTMAXBOUNDS(pGC->font, rightSideBearing);
-
- box.y1 = dst->y + y - top;
- box.y2 = dst->y + y + bot;
-
- RootlessStartDrawing((WindowPtr) dst);
-
- if (canAccelFill(dst, pGC))
- {
- GC_UNSET_PM(pGC, dst);
- }
-
- pGC->ops->ImageText16(dst, pGC, x, y, count, chars);
-
- TRIM_BOX(box, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
- } else {
- pGC->ops->ImageText16(dst, pGC, x, y, count, chars);
- }
-
- GC_RESTORE(pGC, dst);
- GCOP_WRAP(pGC);
- RL_DEBUG_MSG("imagetext16 end\n");
-}
-
-static int RootlessPolyText16(DrawablePtr dst, GCPtr pGC,
- int x, int y, int count, unsigned short *chars)
-{
- int width; // the result, sorta
-
- GCOP_UNWRAP(pGC);
-
- RL_DEBUG_MSG("polytext16 start ");
-
- RootlessStartDrawing((WindowPtr) dst);
- width = pGC->ops->PolyText16(dst, pGC, x, y, count, chars);
- width -= x;
-
- if (width > 0) {
- BoxRec box;
-
- /* ugh */
- box.x1 = dst->x + x + FONTMINBOUNDS(pGC->font, leftSideBearing);
- box.x2 = dst->x + x + FONTMAXBOUNDS(pGC->font, rightSideBearing);
-
- if (count > 1) {
- if (width > 0) box.x2 += width;
- else box.x1 += width;
- }
-
- box.y1 = dst->y + y - FONTMAXBOUNDS(pGC->font, ascent);
- box.y2 = dst->y + y + FONTMAXBOUNDS(pGC->font, descent);
-
- TRIM_BOX(box, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
- }
-
- GCOP_WRAP(pGC);
- RL_DEBUG_MSG("polytext16 end\n");
- return width + x;
-}
-
-static void RootlessImageGlyphBlt(DrawablePtr dst, GCPtr pGC,
- int x, int y, unsigned int nglyphInit,
- CharInfoPtr *ppciInit, pointer unused)
-{
- GC_SAVE(pGC);
- GCOP_UNWRAP(pGC);
- RL_DEBUG_MSG("imageglyph start ");
-
- if (nglyphInit > 0) {
- int top, bot, width = 0;
- BoxRec box;
- unsigned int nglyph = nglyphInit;
- CharInfoPtr *ppci = ppciInit;
-
- top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
- bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
-
- box.x1 = ppci[0]->metrics.leftSideBearing;
- if (box.x1 > 0) box.x1 = 0;
- box.x2 = ppci[nglyph - 1]->metrics.rightSideBearing -
- ppci[nglyph - 1]->metrics.characterWidth;
- if (box.x2 < 0) box.x2 = 0;
-
- box.x2 += dst->x + x;
- box.x1 += dst->x + x;
-
- while (nglyph--) {
- width += (*ppci)->metrics.characterWidth;
- ppci++;
- }
-
- if (width > 0)
- box.x2 += width;
- else
- box.x1 += width;
-
- box.y1 = dst->y + y - top;
- box.y2 = dst->y + y + bot;
-
- RootlessStartDrawing((WindowPtr) dst);
-
- if (canAccelFill(dst, pGC))
- {
- GC_UNSET_PM(pGC, dst);
- }
-
- pGC->ops->ImageGlyphBlt(dst, pGC, x, y, nglyphInit, ppciInit, unused);
-
- TRIM_BOX(box, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
- } else {
- pGC->ops->ImageGlyphBlt(dst, pGC, x, y, nglyphInit, ppciInit, unused);
- }
-
- GC_RESTORE(pGC, dst);
- GCOP_WRAP(pGC);
- RL_DEBUG_MSG("imageglyph end\n");
-}
-
-static void RootlessPolyGlyphBlt(DrawablePtr dst, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, pointer pglyphBase)
-{
- GCOP_UNWRAP(pGC);
- RL_DEBUG_MSG("polyglyph start ");
-
- RootlessStartDrawing((WindowPtr) dst);
- pGC->ops->PolyGlyphBlt(dst, pGC, x, y, nglyph, ppci, pglyphBase);
-
- if (nglyph > 0) {
- BoxRec box;
-
- /* ugh */
- box.x1 = dst->x + x + ppci[0]->metrics.leftSideBearing;
- box.x2 = dst->x + x + ppci[nglyph - 1]->metrics.rightSideBearing;
-
- if (nglyph > 1) {
- int width = 0;
-
- while (--nglyph) {
- width += (*ppci)->metrics.characterWidth;
- ppci++;
- }
-
- if (width > 0) box.x2 += width;
- else box.x1 += width;
- }
-
- box.y1 = dst->y + y - FONTMAXBOUNDS(pGC->font, ascent);
- box.y2 = dst->y + y + FONTMAXBOUNDS(pGC->font, descent);
-
- TRIM_BOX(box, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
- }
-
- GCOP_WRAP(pGC);
- RL_DEBUG_MSG("polyglyph end\n");
-}
-
-
-/* changed area is in dest */
-static void
-RootlessPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr dst,
- int dx, int dy, int xOrg, int yOrg)
-{
- BoxRec box;
-
- GCOP_UNWRAP(pGC);
- RL_DEBUG_MSG("push pixels start ");
-
- RootlessStartDrawing((WindowPtr) dst);
- pGC->ops->PushPixels(pGC, pBitMap, dst, dx, dy, xOrg, yOrg);
-
- box.x1 = xOrg + dst->x;
- box.x2 = box.x1 + dx;
- box.y1 = yOrg + dst->y;
- box.y2 = box.y1 + dy;
-
- TRIM_BOX(box, pGC);
- if (BOX_NOT_EMPTY(box))
- RootlessDamageBox ((WindowPtr) dst, &box);
-
- GCOP_WRAP(pGC);
- RL_DEBUG_MSG("push pixels end\n");
-}
+/* + * Graphics Context support for generic rootless X server + */ +/* + * Copyright (c) 2001 Greg Parker. All Rights Reserved. + * Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved. + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name(s) of the above copyright + * holders shall not be used in advertising or otherwise to promote the sale, + * use or other dealings in this Software without prior written authorization. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stddef.h> /* For NULL */ +#include "mi.h" +#include "scrnintstr.h" +#include "gcstruct.h" +#include "pixmapstr.h" +#include "windowstr.h" +#include "dixfontstr.h" +#include "mivalidate.h" +#include "fb.h" + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include "rootlessCommon.h" + +// GC functions +static void RootlessValidateGC(GCPtr pGC, unsigned long changes, + DrawablePtr pDrawable); +static void RootlessChangeGC(GCPtr pGC, unsigned long mask); +static void RootlessCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst); +static void RootlessDestroyGC(GCPtr pGC); +static void RootlessChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects); +static void RootlessDestroyClip(GCPtr pGC); +static void RootlessCopyClip(GCPtr pgcDst, GCPtr pgcSrc); + +Bool RootlessCreateGC(GCPtr pGC); + +GCFuncs rootlessGCFuncs = { + RootlessValidateGC, + RootlessChangeGC, + RootlessCopyGC, + RootlessDestroyGC, + RootlessChangeClip, + RootlessDestroyClip, + RootlessCopyClip, +}; + +// GC operations +static void RootlessFillSpans(DrawablePtr dst, GCPtr pGC, int nInit, + DDXPointPtr pptInit, int *pwidthInit, int sorted); +static void RootlessSetSpans(DrawablePtr dst, GCPtr pGC, char *pSrc, + DDXPointPtr pptInit, int *pwidthInit, + int nspans, int sorted); +static void RootlessPutImage(DrawablePtr dst, GCPtr pGC, + int depth, int x, int y, int w, int h, + int leftPad, int format, char *pBits); +static RegionPtr RootlessCopyArea(DrawablePtr pSrc, DrawablePtr dst, GCPtr pGC, + int srcx, int srcy, int w, int h, + int dstx, int dsty); +static RegionPtr RootlessCopyPlane(DrawablePtr pSrc, DrawablePtr dst, + GCPtr pGC, int srcx, int srcy, + int w, int h, int dstx, int dsty, + unsigned long plane); +static void RootlessPolyPoint(DrawablePtr dst, GCPtr pGC, + int mode, int npt, DDXPointPtr pptInit); +static void RootlessPolylines(DrawablePtr dst, GCPtr pGC, + int mode, int npt, DDXPointPtr pptInit); +static void RootlessPolySegment(DrawablePtr dst, GCPtr pGC, + int nseg, xSegment * pSeg); +static void RootlessPolyRectangle(DrawablePtr dst, GCPtr pGC, + int nRects, xRectangle *pRects); +static void RootlessPolyArc(DrawablePtr dst, GCPtr pGC, int narcs, + xArc * parcs); +static void RootlessFillPolygon(DrawablePtr dst, GCPtr pGC, int shape, int mode, + int count, DDXPointPtr pptInit); +static void RootlessPolyFillRect(DrawablePtr dst, GCPtr pGC, int nRectsInit, + xRectangle *pRectsInit); +static void RootlessPolyFillArc(DrawablePtr dst, GCPtr pGC, int narcsInit, + xArc * parcsInit); +static int RootlessPolyText8(DrawablePtr dst, GCPtr pGC, int x, int y, + int count, char *chars); +static int RootlessPolyText16(DrawablePtr dst, GCPtr pGC, int x, int y, + int count, unsigned short *chars); +static void RootlessImageText8(DrawablePtr dst, GCPtr pGC, int x, int y, + int count, char *chars); +static void RootlessImageText16(DrawablePtr dst, GCPtr pGC, int x, int y, + int count, unsigned short *chars); +static void RootlessImageGlyphBlt(DrawablePtr dst, GCPtr pGC, int x, int y, + unsigned int nglyphInit, + CharInfoPtr * ppciInit, pointer unused); +static void RootlessPolyGlyphBlt(DrawablePtr dst, GCPtr pGC, int x, int y, + unsigned int nglyph, CharInfoPtr * ppci, + pointer pglyphBase); +static void RootlessPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr dst, + int dx, int dy, int xOrg, int yOrg); + +static GCOps rootlessGCOps = { + RootlessFillSpans, + RootlessSetSpans, + RootlessPutImage, + RootlessCopyArea, + RootlessCopyPlane, + RootlessPolyPoint, + RootlessPolylines, + RootlessPolySegment, + RootlessPolyRectangle, + RootlessPolyArc, + RootlessFillPolygon, + RootlessPolyFillRect, + RootlessPolyFillArc, + RootlessPolyText8, + RootlessPolyText16, + RootlessImageText8, + RootlessImageText16, + RootlessImageGlyphBlt, + RootlessPolyGlyphBlt, + RootlessPushPixels +}; + +/* + If ROOTLESS_PROTECT_ALPHA is set, we have to make sure that the alpha + channel of the on screen windows is always opaque. fb makes this harder + than it would otherwise be by noticing that a planemask of 0x00ffffff + includes all bits when depth==24, and so it "optimizes" the planemask to + 0xffffffff. We work around this by temporarily setting depth=bpp while + changing the GC. + + So the normal situation (in 32 bit mode) is that the planemask is + 0x00ffffff and thus fb leaves the alpha channel alone. The rootless + implementation is responsible for setting the alpha channel opaque + initially. + + Unfortunately drawing with a planemask that doesn't have all bits set + normally causes fb to fall off its fastest paths when blitting and + filling. So we try to recognize when we can relax the planemask back to + 0xffffffff, and do that for the duration of the drawing operation, + setting the alpha channel in fg/bg pixels to opaque at the same time. We + can do this when drawing op is GXcopy. We can also do this when copying + from another window since its alpha channel must also be opaque. + + The three macros below are used to implement this. Drawing ops that can + potentially have their planemask relaxed look like: + + OP { + GC_SAVE(gc); + GCOP_UNWRAP(gc); + + ... + + if (canAccelxxx(..) && otherwise-suitable) + GC_UNSET_PM(gc, dst); + + gc->funcs->OP(gc, ...); + + GC_RESTORE(gc, dst); + GCOP_WRAP(gc); + } + + */ + +#define GC_SAVE(pGC) \ + unsigned long _save_fg = (pGC)->fgPixel; \ + unsigned long _save_bg = (pGC)->bgPixel; \ + unsigned long _save_pm = (pGC)->planemask; \ + Bool _changed = FALSE + +#define GC_RESTORE(pGC, pDraw) \ + do { \ + if (_changed) { \ + unsigned int depth = (pDraw)->depth; \ + (pGC)->fgPixel = _save_fg; \ + (pGC)->bgPixel = _save_bg; \ + (pGC)->planemask = _save_pm; \ + (pDraw)->depth = (pDraw)->bitsPerPixel; \ + VALIDATE_GC(pGC, GCForeground | GCBackground | \ + GCPlaneMask, pDraw); \ + (pDraw)->depth = depth; \ + } \ + } while (0) + +#define GC_UNSET_PM(pGC, pDraw) \ + do { \ + unsigned int mask = RootlessAlphaMask ((pDraw)->bitsPerPixel); \ + if (((pGC)->planemask & mask) != mask) { \ + unsigned int depth = (pDraw)->depth; \ + (pGC)->fgPixel |= mask; \ + (pGC)->bgPixel |= mask; \ + (pGC)->planemask |= mask; \ + (pDraw)->depth = (pDraw)->bitsPerPixel; \ + VALIDATE_GC(pGC, GCForeground | \ + GCBackground | GCPlaneMask, pDraw); \ + (pDraw)->depth = depth; \ + _changed = TRUE; \ + } \ + } while (0) + +#define VALIDATE_GC(pGC, changes, pDrawable) \ + do { \ + pGC->funcs->ValidateGC(pGC, changes, pDrawable); \ + if (((WindowPtr) pDrawable)->viewable) { \ + gcrec->originalOps = pGC->ops; \ + } \ + } while(0) + +static RootlessWindowRec * +canAccelBlit(DrawablePtr pDraw, GCPtr pGC) +{ + WindowPtr pTop; + RootlessWindowRec *winRec; + unsigned int pm; + + if (pGC->alu != GXcopy) + return NULL; + + if (pDraw->type != DRAWABLE_WINDOW) + return NULL; + + pm = ~RootlessAlphaMask(pDraw->bitsPerPixel); + if ((pGC->planemask & pm) != pm) + return NULL; + + pTop = TopLevelParent((WindowPtr) pDraw); + if (pTop == NULL) + return NULL; + + winRec = WINREC(pTop); + if (winRec == NULL) + return NULL; + + return winRec; +} + +static inline RootlessWindowRec * +canAccelFill(DrawablePtr pDraw, GCPtr pGC) +{ + if (pGC->fillStyle != FillSolid) + return NULL; + + return canAccelBlit(pDraw, pGC); +} + +/* + * Screen function to create a graphics context + */ +Bool +RootlessCreateGC(GCPtr pGC) +{ + RootlessGCRec *gcrec; + RootlessScreenRec *s; + Bool result; + + SCREEN_UNWRAP(pGC->pScreen, CreateGC); + s = SCREENREC(pGC->pScreen); + result = s->CreateGC(pGC); + + gcrec = (RootlessGCRec *) + dixLookupPrivate(&pGC->devPrivates, rootlessGCPrivateKey); + gcrec->originalOps = NULL; // don't wrap ops yet + gcrec->originalFuncs = pGC->funcs; + pGC->funcs = &rootlessGCFuncs; + + SCREEN_WRAP(pGC->pScreen, CreateGC); + return result; +} + +/* + * GC funcs + * + * These wrap lower level GC funcs. + * ValidateGC wraps the GC ops iff dest is viewable. + * All the others just unwrap and call. + */ + +// GCFUNC_UNRAP assumes funcs have been wrapped and +// does not assume ops have been wrapped +#define GCFUNC_UNWRAP(pGC) \ + RootlessGCRec *gcrec = (RootlessGCRec *) \ + dixLookupPrivate(&(pGC)->devPrivates, rootlessGCPrivateKey); \ + (pGC)->funcs = gcrec->originalFuncs; \ + if (gcrec->originalOps) { \ + (pGC)->ops = gcrec->originalOps; \ +} + +#define GCFUNC_WRAP(pGC) \ + gcrec->originalFuncs = (pGC)->funcs; \ + (pGC)->funcs = &rootlessGCFuncs; \ + if (gcrec->originalOps) { \ + gcrec->originalOps = (pGC)->ops; \ + (pGC)->ops = &rootlessGCOps; \ +} + +static void +RootlessValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) +{ + GCFUNC_UNWRAP(pGC); + + gcrec->originalOps = NULL; + + if (pDrawable->type == DRAWABLE_WINDOW) { +#ifdef ROOTLESS_PROTECT_ALPHA + unsigned int depth = pDrawable->depth; + + // We force a planemask so fb doesn't overwrite the alpha channel. + // Left to its own devices, fb will optimize away the planemask. + pDrawable->depth = pDrawable->bitsPerPixel; + pGC->planemask &= ~RootlessAlphaMask(pDrawable->bitsPerPixel); + VALIDATE_GC(pGC, changes | GCPlaneMask, pDrawable); + pDrawable->depth = depth; +#else + VALIDATE_GC(pGC, changes, pDrawable); +#endif + } + else { + pGC->funcs->ValidateGC(pGC, changes, pDrawable); + } + + GCFUNC_WRAP(pGC); +} + +static void +RootlessChangeGC(GCPtr pGC, unsigned long mask) +{ + GCFUNC_UNWRAP(pGC); + pGC->funcs->ChangeGC(pGC, mask); + GCFUNC_WRAP(pGC); +} + +static void +RootlessCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst) +{ + GCFUNC_UNWRAP(pGCDst); + pGCDst->funcs->CopyGC(pGCSrc, mask, pGCDst); + GCFUNC_WRAP(pGCDst); +} + +static void +RootlessDestroyGC(GCPtr pGC) +{ + GCFUNC_UNWRAP(pGC); + pGC->funcs->DestroyGC(pGC); + GCFUNC_WRAP(pGC); +} + +static void +RootlessChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects) +{ + GCFUNC_UNWRAP(pGC); + pGC->funcs->ChangeClip(pGC, type, pvalue, nrects); + GCFUNC_WRAP(pGC); +} + +static void +RootlessDestroyClip(GCPtr pGC) +{ + GCFUNC_UNWRAP(pGC); + pGC->funcs->DestroyClip(pGC); + GCFUNC_WRAP(pGC); +} + +static void +RootlessCopyClip(GCPtr pgcDst, GCPtr pgcSrc) +{ + GCFUNC_UNWRAP(pgcDst); + pgcDst->funcs->CopyClip(pgcDst, pgcSrc); + GCFUNC_WRAP(pgcDst); +} + +/* + * GC ops + * + * We can't use shadowfb because shadowfb assumes one pixmap + * and our root window is a special case. + * However, much of this code is copied from shadowfb. + */ + +// assumes both funcs and ops are wrapped +#define GCOP_UNWRAP(pGC) \ + RootlessGCRec *gcrec = (RootlessGCRec *) \ + dixLookupPrivate(&(pGC)->devPrivates, rootlessGCPrivateKey); \ + GCFuncs *saveFuncs = pGC->funcs; \ + (pGC)->funcs = gcrec->originalFuncs; \ + (pGC)->ops = gcrec->originalOps; + +#define GCOP_WRAP(pGC) \ + gcrec->originalOps = (pGC)->ops; \ + (pGC)->funcs = saveFuncs; \ + (pGC)->ops = &rootlessGCOps; + +static void +RootlessFillSpans(DrawablePtr dst, GCPtr pGC, int nInit, + DDXPointPtr pptInit, int *pwidthInit, int sorted) +{ + GC_SAVE(pGC); + GCOP_UNWRAP(pGC); + RL_DEBUG_MSG("fill spans start "); + + if (nInit <= 0) { + pGC->ops->FillSpans(dst, pGC, nInit, pptInit, pwidthInit, sorted); + } + else { + DDXPointPtr ppt = pptInit; + int *pwidth = pwidthInit; + int i = nInit; + BoxRec box; + + box.x1 = ppt->x; + box.x2 = box.x1 + *pwidth; + box.y2 = box.y1 = ppt->y; + + while (--i) { + ppt++; + pwidth++; + if (box.x1 > ppt->x) + box.x1 = ppt->x; + if (box.x2 < (ppt->x + *pwidth)) + box.x2 = ppt->x + *pwidth; + if (box.y1 > ppt->y) + box.y1 = ppt->y; + else if (box.y2 < ppt->y) + box.y2 = ppt->y; + } + + box.y2++; + + RootlessStartDrawing((WindowPtr) dst); + + if (canAccelFill(dst, pGC)) { + GC_UNSET_PM(pGC, dst); + } + + pGC->ops->FillSpans(dst, pGC, nInit, pptInit, pwidthInit, sorted); + + TRIM_AND_TRANSLATE_BOX(box, dst, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + } + + GC_RESTORE(pGC, dst); + GCOP_WRAP(pGC); + RL_DEBUG_MSG("fill spans end\n"); +} + +static void +RootlessSetSpans(DrawablePtr dst, GCPtr pGC, char *pSrc, + DDXPointPtr pptInit, int *pwidthInit, int nspans, int sorted) +{ + GCOP_UNWRAP(pGC); + RL_DEBUG_MSG("set spans start "); + + if (nspans <= 0) { + pGC->ops->SetSpans(dst, pGC, pSrc, pptInit, pwidthInit, nspans, sorted); + } + else { + DDXPointPtr ppt = pptInit; + int *pwidth = pwidthInit; + int i = nspans; + BoxRec box; + + box.x1 = ppt->x; + box.x2 = box.x1 + *pwidth; + box.y2 = box.y1 = ppt->y; + + while (--i) { + ppt++; + pwidth++; + if (box.x1 > ppt->x) + box.x1 = ppt->x; + if (box.x2 < (ppt->x + *pwidth)) + box.x2 = ppt->x + *pwidth; + if (box.y1 > ppt->y) + box.y1 = ppt->y; + else if (box.y2 < ppt->y) + box.y2 = ppt->y; + } + + box.y2++; + + RootlessStartDrawing((WindowPtr) dst); + pGC->ops->SetSpans(dst, pGC, pSrc, pptInit, pwidthInit, nspans, sorted); + + TRIM_AND_TRANSLATE_BOX(box, dst, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + } + GCOP_WRAP(pGC); + RL_DEBUG_MSG("set spans end\n"); +} + +static void +RootlessPutImage(DrawablePtr dst, GCPtr pGC, + int depth, int x, int y, int w, int h, + int leftPad, int format, char *pBits) +{ + BoxRec box; + + GCOP_UNWRAP(pGC); + RL_DEBUG_MSG("put image start "); + + RootlessStartDrawing((WindowPtr) dst); + pGC->ops->PutImage(dst, pGC, depth, x, y, w, h, leftPad, format, pBits); + + box.x1 = x + dst->x; + box.x2 = box.x1 + w; + box.y1 = y + dst->y; + box.y2 = box.y1 + h; + + TRIM_BOX(box, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + + GCOP_WRAP(pGC); + RL_DEBUG_MSG("put image end\n"); +} + +/* changed area is *dest* rect */ +static RegionPtr +RootlessCopyArea(DrawablePtr pSrc, DrawablePtr dst, GCPtr pGC, + int srcx, int srcy, int w, int h, int dstx, int dsty) +{ + RegionPtr result; + BoxRec box; + + GC_SAVE(pGC); + GCOP_UNWRAP(pGC); + + RL_DEBUG_MSG("copy area start (src 0x%x, dst 0x%x)", pSrc, dst); + + if (pSrc->type == DRAWABLE_WINDOW && IsFramedWindow((WindowPtr) pSrc)) { + /* If both source and dest are windows, and we're doing + a simple copy operation, we can remove the alpha-protecting + planemask (since source has opaque alpha as well) */ + + if (canAccelBlit(pSrc, pGC)) { + GC_UNSET_PM(pGC, dst); + } + + RootlessStartDrawing((WindowPtr) pSrc); + } + RootlessStartDrawing((WindowPtr) dst); + result = pGC->ops->CopyArea(pSrc, dst, pGC, srcx, srcy, w, h, dstx, dsty); + + box.x1 = dstx + dst->x; + box.x2 = box.x1 + w; + box.y1 = dsty + dst->y; + box.y2 = box.y1 + h; + + TRIM_BOX(box, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + + GC_RESTORE(pGC, dst); + GCOP_WRAP(pGC); + RL_DEBUG_MSG("copy area end\n"); + return result; +} + +/* changed area is *dest* rect */ +static RegionPtr +RootlessCopyPlane(DrawablePtr pSrc, DrawablePtr dst, + GCPtr pGC, int srcx, int srcy, + int w, int h, int dstx, int dsty, unsigned long plane) +{ + RegionPtr result; + BoxRec box; + + GCOP_UNWRAP(pGC); + + RL_DEBUG_MSG("copy plane start "); + + if (pSrc->type == DRAWABLE_WINDOW && IsFramedWindow((WindowPtr) pSrc)) { + RootlessStartDrawing((WindowPtr) pSrc); + } + RootlessStartDrawing((WindowPtr) dst); + result = pGC->ops->CopyPlane(pSrc, dst, pGC, srcx, srcy, w, h, + dstx, dsty, plane); + + box.x1 = dstx + dst->x; + box.x2 = box.x1 + w; + box.y1 = dsty + dst->y; + box.y2 = box.y1 + h; + + TRIM_BOX(box, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + + GCOP_WRAP(pGC); + RL_DEBUG_MSG("copy plane end\n"); + return result; +} + +// Options for size of changed area: +// 0 = box per point +// 1 = big box around all points +// 2 = accumulate point in 20 pixel radius +#define ROOTLESS_CHANGED_AREA 1 +#define abs(a) ((a) > 0 ? (a) : -(a)) + +/* changed area is box around all points */ +static void +RootlessPolyPoint(DrawablePtr dst, GCPtr pGC, + int mode, int npt, DDXPointPtr pptInit) +{ + GCOP_UNWRAP(pGC); + RL_DEBUG_MSG("polypoint start "); + + RootlessStartDrawing((WindowPtr) dst); + pGC->ops->PolyPoint(dst, pGC, mode, npt, pptInit); + + if (npt > 0) { +#if ROOTLESS_CHANGED_AREA==0 + // box per point + BoxRec box; + + while (npt) { + box.x1 = pptInit->x; + box.y1 = pptInit->y; + box.x2 = box.x1 + 1; + box.y2 = box.y1 + 1; + + TRIM_AND_TRANSLATE_BOX(box, dst, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + + npt--; + pptInit++; + } + +#elif ROOTLESS_CHANGED_AREA==1 + // one big box + BoxRec box; + + box.x2 = box.x1 = pptInit->x; + box.y2 = box.y1 = pptInit->y; + while (--npt) { + pptInit++; + if (box.x1 > pptInit->x) + box.x1 = pptInit->x; + else if (box.x2 < pptInit->x) + box.x2 = pptInit->x; + if (box.y1 > pptInit->y) + box.y1 = pptInit->y; + else if (box.y2 < pptInit->y) + box.y2 = pptInit->y; + } + + box.x2++; + box.y2++; + + TRIM_AND_TRANSLATE_BOX(box, dst, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + +#elif ROOTLESS_CHANGED_AREA==2 + // clever(?) method: accumulate point in 20-pixel radius + BoxRec box; + int firstx, firsty; + + box.x2 = box.x1 = firstx = pptInit->x; + box.y2 = box.y1 = firsty = pptInit->y; + while (--npt) { + pptInit++; + if (abs(pptInit->x - firstx) > 20 || abs(pptInit->y - firsty) > 20) { + box.x2++; + box.y2++; + TRIM_AND_TRANSLATE_BOX(box, dst, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + box.x2 = box.x1 = firstx = pptInit->x; + box.y2 = box.y1 = firsty = pptInit->y; + } + else { + if (box.x1 > pptInit->x) + box.x1 = pptInit->x; + else if (box.x2 < pptInit->x) + box.x2 = pptInit->x; + if (box.y1 > pptInit->y) + box.y1 = pptInit->y; + else if (box.y2 < pptInit->y) + box.y2 = pptInit->y; + } + } + box.x2++; + box.y2++; + TRIM_AND_TRANSLATE_BOX(box, dst, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); +#endif /* ROOTLESS_CHANGED_AREA */ + } + + GCOP_WRAP(pGC); + RL_DEBUG_MSG("polypoint end\n"); +} + +#undef ROOTLESS_CHANGED_AREA + +/* changed area is box around each line */ +static void +RootlessPolylines(DrawablePtr dst, GCPtr pGC, + int mode, int npt, DDXPointPtr pptInit) +{ + GCOP_UNWRAP(pGC); + RL_DEBUG_MSG("poly lines start "); + + RootlessStartDrawing((WindowPtr) dst); + pGC->ops->Polylines(dst, pGC, mode, npt, pptInit); + + if (npt > 0) { + BoxRec box; + int extra = pGC->lineWidth >> 1; + + box.x2 = box.x1 = pptInit->x; + box.y2 = box.y1 = pptInit->y; + + if (npt > 1) { + if (pGC->joinStyle == JoinMiter) + extra = 6 * pGC->lineWidth; + else if (pGC->capStyle == CapProjecting) + extra = pGC->lineWidth; + } + + if (mode == CoordModePrevious) { + int x = box.x1; + int y = box.y1; + + while (--npt) { + pptInit++; + x += pptInit->x; + y += pptInit->y; + if (box.x1 > x) + box.x1 = x; + else if (box.x2 < x) + box.x2 = x; + if (box.y1 > y) + box.y1 = y; + else if (box.y2 < y) + box.y2 = y; + } + } + else { + while (--npt) { + pptInit++; + if (box.x1 > pptInit->x) + box.x1 = pptInit->x; + else if (box.x2 < pptInit->x) + box.x2 = pptInit->x; + if (box.y1 > pptInit->y) + box.y1 = pptInit->y; + else if (box.y2 < pptInit->y) + box.y2 = pptInit->y; + } + } + + box.x2++; + box.y2++; + + if (extra) { + box.x1 -= extra; + box.x2 += extra; + box.y1 -= extra; + box.y2 += extra; + } + + TRIM_AND_TRANSLATE_BOX(box, dst, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + } + + GCOP_WRAP(pGC); + RL_DEBUG_MSG("poly lines end\n"); +} + +/* changed area is box around each line segment */ +static void +RootlessPolySegment(DrawablePtr dst, GCPtr pGC, int nseg, xSegment * pSeg) +{ + GCOP_UNWRAP(pGC); + RL_DEBUG_MSG("poly segment start (win 0x%x)", dst); + + RootlessStartDrawing((WindowPtr) dst); + pGC->ops->PolySegment(dst, pGC, nseg, pSeg); + + if (nseg > 0) { + BoxRec box; + int extra = pGC->lineWidth; + + if (pGC->capStyle != CapProjecting) + extra >>= 1; + + if (pSeg->x2 > pSeg->x1) { + box.x1 = pSeg->x1; + box.x2 = pSeg->x2; + } + else { + box.x2 = pSeg->x1; + box.x1 = pSeg->x2; + } + + if (pSeg->y2 > pSeg->y1) { + box.y1 = pSeg->y1; + box.y2 = pSeg->y2; + } + else { + box.y2 = pSeg->y1; + box.y1 = pSeg->y2; + } + + while (--nseg) { + pSeg++; + if (pSeg->x2 > pSeg->x1) { + if (pSeg->x1 < box.x1) + box.x1 = pSeg->x1; + if (pSeg->x2 > box.x2) + box.x2 = pSeg->x2; + } + else { + if (pSeg->x2 < box.x1) + box.x1 = pSeg->x2; + if (pSeg->x1 > box.x2) + box.x2 = pSeg->x1; + } + if (pSeg->y2 > pSeg->y1) { + if (pSeg->y1 < box.y1) + box.y1 = pSeg->y1; + if (pSeg->y2 > box.y2) + box.y2 = pSeg->y2; + } + else { + if (pSeg->y2 < box.y1) + box.y1 = pSeg->y2; + if (pSeg->y1 > box.y2) + box.y2 = pSeg->y1; + } + } + + box.x2++; + box.y2++; + + if (extra) { + box.x1 -= extra; + box.x2 += extra; + box.y1 -= extra; + box.y2 += extra; + } + + TRIM_AND_TRANSLATE_BOX(box, dst, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + } + + GCOP_WRAP(pGC); + RL_DEBUG_MSG("poly segment end\n"); +} + +/* changed area is box around each line (not entire rects) */ +static void +RootlessPolyRectangle(DrawablePtr dst, GCPtr pGC, + int nRects, xRectangle *pRects) +{ + GCOP_UNWRAP(pGC); + RL_DEBUG_MSG("poly rectangle start "); + + RootlessStartDrawing((WindowPtr) dst); + pGC->ops->PolyRectangle(dst, pGC, nRects, pRects); + + if (nRects > 0) { + BoxRec box; + int offset1, offset2, offset3; + + offset2 = pGC->lineWidth; + if (!offset2) + offset2 = 1; + offset1 = offset2 >> 1; + offset3 = offset2 - offset1; + + while (nRects--) { + box.x1 = pRects->x - offset1; + box.y1 = pRects->y - offset1; + box.x2 = box.x1 + pRects->width + offset2; + box.y2 = box.y1 + offset2; + TRIM_AND_TRANSLATE_BOX(box, dst, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + + box.x1 = pRects->x - offset1; + box.y1 = pRects->y + offset3; + box.x2 = box.x1 + offset2; + box.y2 = box.y1 + pRects->height - offset2; + TRIM_AND_TRANSLATE_BOX(box, dst, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + + box.x1 = pRects->x + pRects->width - offset1; + box.y1 = pRects->y + offset3; + box.x2 = box.x1 + offset2; + box.y2 = box.y1 + pRects->height - offset2; + TRIM_AND_TRANSLATE_BOX(box, dst, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + + box.x1 = pRects->x - offset1; + box.y1 = pRects->y + pRects->height - offset1; + box.x2 = box.x1 + pRects->width + offset2; + box.y2 = box.y1 + offset2; + TRIM_AND_TRANSLATE_BOX(box, dst, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + + pRects++; + } + } + + GCOP_WRAP(pGC); + RL_DEBUG_MSG("poly rectangle end\n"); +} + +/* changed area is box around each arc (assumes all arcs are 360 degrees) */ +static void +RootlessPolyArc(DrawablePtr dst, GCPtr pGC, int narcs, xArc * parcs) +{ + GCOP_UNWRAP(pGC); + RL_DEBUG_MSG("poly arc start "); + + RootlessStartDrawing((WindowPtr) dst); + pGC->ops->PolyArc(dst, pGC, narcs, parcs); + + if (narcs > 0) { + int extra = pGC->lineWidth >> 1; + BoxRec box; + + box.x1 = parcs->x; + box.x2 = box.x1 + parcs->width; + box.y1 = parcs->y; + box.y2 = box.y1 + parcs->height; + + /* should I break these up instead ? */ + + while (--narcs) { + parcs++; + if (box.x1 > parcs->x) + box.x1 = parcs->x; + if (box.x2 < (parcs->x + parcs->width)) + box.x2 = parcs->x + parcs->width; + if (box.y1 > parcs->y) + box.y1 = parcs->y; + if (box.y2 < (parcs->y + parcs->height)) + box.y2 = parcs->y + parcs->height; + } + + if (extra) { + box.x1 -= extra; + box.x2 += extra; + box.y1 -= extra; + box.y2 += extra; + } + + box.x2++; + box.y2++; + + TRIM_AND_TRANSLATE_BOX(box, dst, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + } + + GCOP_WRAP(pGC); + RL_DEBUG_MSG("poly arc end\n"); +} + +/* changed area is box around each poly */ +static void +RootlessFillPolygon(DrawablePtr dst, GCPtr pGC, + int shape, int mode, int count, DDXPointPtr pptInit) +{ + GC_SAVE(pGC); + GCOP_UNWRAP(pGC); + RL_DEBUG_MSG("fill poly start (win 0x%x, fillStyle 0x%x)", dst, + pGC->fillStyle); + + if (count <= 2) { + pGC->ops->FillPolygon(dst, pGC, shape, mode, count, pptInit); + } + else { + DDXPointPtr ppt = pptInit; + int i = count; + BoxRec box; + + box.x2 = box.x1 = ppt->x; + box.y2 = box.y1 = ppt->y; + + if (mode != CoordModeOrigin) { + int x = box.x1; + int y = box.y1; + + while (--i) { + ppt++; + x += ppt->x; + y += ppt->y; + if (box.x1 > x) + box.x1 = x; + else if (box.x2 < x) + box.x2 = x; + if (box.y1 > y) + box.y1 = y; + else if (box.y2 < y) + box.y2 = y; + } + } + else { + while (--i) { + ppt++; + if (box.x1 > ppt->x) + box.x1 = ppt->x; + else if (box.x2 < ppt->x) + box.x2 = ppt->x; + if (box.y1 > ppt->y) + box.y1 = ppt->y; + else if (box.y2 < ppt->y) + box.y2 = ppt->y; + } + } + + box.x2++; + box.y2++; + + RootlessStartDrawing((WindowPtr) dst); + + if (canAccelFill(dst, pGC)) { + GC_UNSET_PM(pGC, dst); + } + + pGC->ops->FillPolygon(dst, pGC, shape, mode, count, pptInit); + + TRIM_AND_TRANSLATE_BOX(box, dst, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + } + + GC_RESTORE(pGC, dst); + GCOP_WRAP(pGC); + RL_DEBUG_MSG("fill poly end\n"); +} + +/* changed area is the rects */ +static void +RootlessPolyFillRect(DrawablePtr dst, GCPtr pGC, + int nRectsInit, xRectangle *pRectsInit) +{ + GC_SAVE(pGC); + GCOP_UNWRAP(pGC); + RL_DEBUG_MSG("fill rect start (win 0x%x, fillStyle 0x%x)", dst, + pGC->fillStyle); + + if (nRectsInit <= 0) { + pGC->ops->PolyFillRect(dst, pGC, nRectsInit, pRectsInit); + } + else { + BoxRec box; + xRectangle *pRects = pRectsInit; + int nRects = nRectsInit; + + box.x1 = pRects->x; + box.x2 = box.x1 + pRects->width; + box.y1 = pRects->y; + box.y2 = box.y1 + pRects->height; + + while (--nRects) { + pRects++; + if (box.x1 > pRects->x) + box.x1 = pRects->x; + if (box.x2 < (pRects->x + pRects->width)) + box.x2 = pRects->x + pRects->width; + if (box.y1 > pRects->y) + box.y1 = pRects->y; + if (box.y2 < (pRects->y + pRects->height)) + box.y2 = pRects->y + pRects->height; + } + + RootlessStartDrawing((WindowPtr) dst); + + if (canAccelFill(dst, pGC)) { + GC_UNSET_PM(pGC, dst); + } + + pGC->ops->PolyFillRect(dst, pGC, nRectsInit, pRectsInit); + + TRIM_AND_TRANSLATE_BOX(box, dst, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + } + + GC_RESTORE(pGC, dst); + GCOP_WRAP(pGC); + RL_DEBUG_MSG("fill rect end\n"); +} + +/* changed area is box around each arc (assuming arcs are all 360 degrees) */ +static void +RootlessPolyFillArc(DrawablePtr dst, GCPtr pGC, int narcsInit, xArc * parcsInit) +{ + GC_SAVE(pGC); + GCOP_UNWRAP(pGC); + RL_DEBUG_MSG("fill arc start "); + + if (narcsInit > 0) { + BoxRec box; + int narcs = narcsInit; + xArc *parcs = parcsInit; + + box.x1 = parcs->x; + box.x2 = box.x1 + parcs->width; + box.y1 = parcs->y; + box.y2 = box.y1 + parcs->height; + + /* should I break these up instead ? */ + + while (--narcs) { + parcs++; + if (box.x1 > parcs->x) + box.x1 = parcs->x; + if (box.x2 < (parcs->x + parcs->width)) + box.x2 = parcs->x + parcs->width; + if (box.y1 > parcs->y) + box.y1 = parcs->y; + if (box.y2 < (parcs->y + parcs->height)) + box.y2 = parcs->y + parcs->height; + } + + RootlessStartDrawing((WindowPtr) dst); + + if (canAccelFill(dst, pGC)) { + GC_UNSET_PM(pGC, dst); + } + + pGC->ops->PolyFillArc(dst, pGC, narcsInit, parcsInit); + + TRIM_AND_TRANSLATE_BOX(box, dst, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + } + else { + pGC->ops->PolyFillArc(dst, pGC, narcsInit, parcsInit); + } + + GC_RESTORE(pGC, dst); + GCOP_WRAP(pGC); + RL_DEBUG_MSG("fill arc end\n"); +} + +static void +RootlessImageText8(DrawablePtr dst, GCPtr pGC, + int x, int y, int count, char *chars) +{ + GC_SAVE(pGC); + GCOP_UNWRAP(pGC); + RL_DEBUG_MSG("imagetext8 start "); + + if (count > 0) { + int top, bot, Min, Max; + BoxRec box; + + top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font)); + bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font)); + + Min = count * FONTMINBOUNDS(pGC->font, characterWidth); + if (Min > 0) + Min = 0; + Max = count * FONTMAXBOUNDS(pGC->font, characterWidth); + if (Max < 0) + Max = 0; + + /* ugh */ + box.x1 = dst->x + x + Min + FONTMINBOUNDS(pGC->font, leftSideBearing); + box.x2 = dst->x + x + Max + FONTMAXBOUNDS(pGC->font, rightSideBearing); + + box.y1 = dst->y + y - top; + box.y2 = dst->y + y + bot; + + RootlessStartDrawing((WindowPtr) dst); + + if (canAccelFill(dst, pGC)) { + GC_UNSET_PM(pGC, dst); + } + + pGC->ops->ImageText8(dst, pGC, x, y, count, chars); + + TRIM_BOX(box, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + } + else { + pGC->ops->ImageText8(dst, pGC, x, y, count, chars); + } + + GC_RESTORE(pGC, dst); + GCOP_WRAP(pGC); + RL_DEBUG_MSG("imagetext8 end\n"); +} + +static int +RootlessPolyText8(DrawablePtr dst, GCPtr pGC, + int x, int y, int count, char *chars) +{ + int width; // the result, sorta + + GCOP_UNWRAP(pGC); + + RL_DEBUG_MSG("polytext8 start "); + + RootlessStartDrawing((WindowPtr) dst); + width = pGC->ops->PolyText8(dst, pGC, x, y, count, chars); + width -= x; + + if (width > 0) { + BoxRec box; + + /* ugh */ + box.x1 = dst->x + x + FONTMINBOUNDS(pGC->font, leftSideBearing); + box.x2 = dst->x + x + FONTMAXBOUNDS(pGC->font, rightSideBearing); + + if (count > 1) { + if (width > 0) + box.x2 += width; + else + box.x1 += width; + } + + box.y1 = dst->y + y - FONTMAXBOUNDS(pGC->font, ascent); + box.y2 = dst->y + y + FONTMAXBOUNDS(pGC->font, descent); + + TRIM_BOX(box, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + } + + GCOP_WRAP(pGC); + RL_DEBUG_MSG("polytext8 end\n"); + return width + x; +} + +static void +RootlessImageText16(DrawablePtr dst, GCPtr pGC, + int x, int y, int count, unsigned short *chars) +{ + GC_SAVE(pGC); + GCOP_UNWRAP(pGC); + RL_DEBUG_MSG("imagetext16 start "); + + if (count > 0) { + int top, bot, Min, Max; + BoxRec box; + + top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font)); + bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font)); + + Min = count * FONTMINBOUNDS(pGC->font, characterWidth); + if (Min > 0) + Min = 0; + Max = count * FONTMAXBOUNDS(pGC->font, characterWidth); + if (Max < 0) + Max = 0; + + /* ugh */ + box.x1 = dst->x + x + Min + FONTMINBOUNDS(pGC->font, leftSideBearing); + box.x2 = dst->x + x + Max + FONTMAXBOUNDS(pGC->font, rightSideBearing); + + box.y1 = dst->y + y - top; + box.y2 = dst->y + y + bot; + + RootlessStartDrawing((WindowPtr) dst); + + if (canAccelFill(dst, pGC)) { + GC_UNSET_PM(pGC, dst); + } + + pGC->ops->ImageText16(dst, pGC, x, y, count, chars); + + TRIM_BOX(box, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + } + else { + pGC->ops->ImageText16(dst, pGC, x, y, count, chars); + } + + GC_RESTORE(pGC, dst); + GCOP_WRAP(pGC); + RL_DEBUG_MSG("imagetext16 end\n"); +} + +static int +RootlessPolyText16(DrawablePtr dst, GCPtr pGC, + int x, int y, int count, unsigned short *chars) +{ + int width; // the result, sorta + + GCOP_UNWRAP(pGC); + + RL_DEBUG_MSG("polytext16 start "); + + RootlessStartDrawing((WindowPtr) dst); + width = pGC->ops->PolyText16(dst, pGC, x, y, count, chars); + width -= x; + + if (width > 0) { + BoxRec box; + + /* ugh */ + box.x1 = dst->x + x + FONTMINBOUNDS(pGC->font, leftSideBearing); + box.x2 = dst->x + x + FONTMAXBOUNDS(pGC->font, rightSideBearing); + + if (count > 1) { + if (width > 0) + box.x2 += width; + else + box.x1 += width; + } + + box.y1 = dst->y + y - FONTMAXBOUNDS(pGC->font, ascent); + box.y2 = dst->y + y + FONTMAXBOUNDS(pGC->font, descent); + + TRIM_BOX(box, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + } + + GCOP_WRAP(pGC); + RL_DEBUG_MSG("polytext16 end\n"); + return width + x; +} + +static void +RootlessImageGlyphBlt(DrawablePtr dst, GCPtr pGC, + int x, int y, unsigned int nglyphInit, + CharInfoPtr * ppciInit, pointer unused) +{ + GC_SAVE(pGC); + GCOP_UNWRAP(pGC); + RL_DEBUG_MSG("imageglyph start "); + + if (nglyphInit > 0) { + int top, bot, width = 0; + BoxRec box; + unsigned int nglyph = nglyphInit; + CharInfoPtr *ppci = ppciInit; + + top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font)); + bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font)); + + box.x1 = ppci[0]->metrics.leftSideBearing; + if (box.x1 > 0) + box.x1 = 0; + box.x2 = ppci[nglyph - 1]->metrics.rightSideBearing - + ppci[nglyph - 1]->metrics.characterWidth; + if (box.x2 < 0) + box.x2 = 0; + + box.x2 += dst->x + x; + box.x1 += dst->x + x; + + while (nglyph--) { + width += (*ppci)->metrics.characterWidth; + ppci++; + } + + if (width > 0) + box.x2 += width; + else + box.x1 += width; + + box.y1 = dst->y + y - top; + box.y2 = dst->y + y + bot; + + RootlessStartDrawing((WindowPtr) dst); + + if (canAccelFill(dst, pGC)) { + GC_UNSET_PM(pGC, dst); + } + + pGC->ops->ImageGlyphBlt(dst, pGC, x, y, nglyphInit, ppciInit, unused); + + TRIM_BOX(box, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + } + else { + pGC->ops->ImageGlyphBlt(dst, pGC, x, y, nglyphInit, ppciInit, unused); + } + + GC_RESTORE(pGC, dst); + GCOP_WRAP(pGC); + RL_DEBUG_MSG("imageglyph end\n"); +} + +static void +RootlessPolyGlyphBlt(DrawablePtr dst, GCPtr pGC, + int x, int y, unsigned int nglyph, + CharInfoPtr * ppci, pointer pglyphBase) +{ + GCOP_UNWRAP(pGC); + RL_DEBUG_MSG("polyglyph start "); + + RootlessStartDrawing((WindowPtr) dst); + pGC->ops->PolyGlyphBlt(dst, pGC, x, y, nglyph, ppci, pglyphBase); + + if (nglyph > 0) { + BoxRec box; + + /* ugh */ + box.x1 = dst->x + x + ppci[0]->metrics.leftSideBearing; + box.x2 = dst->x + x + ppci[nglyph - 1]->metrics.rightSideBearing; + + if (nglyph > 1) { + int width = 0; + + while (--nglyph) { + width += (*ppci)->metrics.characterWidth; + ppci++; + } + + if (width > 0) + box.x2 += width; + else + box.x1 += width; + } + + box.y1 = dst->y + y - FONTMAXBOUNDS(pGC->font, ascent); + box.y2 = dst->y + y + FONTMAXBOUNDS(pGC->font, descent); + + TRIM_BOX(box, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + } + + GCOP_WRAP(pGC); + RL_DEBUG_MSG("polyglyph end\n"); +} + +/* changed area is in dest */ +static void +RootlessPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr dst, + int dx, int dy, int xOrg, int yOrg) +{ + BoxRec box; + + GCOP_UNWRAP(pGC); + RL_DEBUG_MSG("push pixels start "); + + RootlessStartDrawing((WindowPtr) dst); + pGC->ops->PushPixels(pGC, pBitMap, dst, dx, dy, xOrg, yOrg); + + box.x1 = xOrg + dst->x; + box.x2 = box.x1 + dx; + box.y1 = yOrg + dst->y; + box.y2 = box.y1 + dy; + + TRIM_BOX(box, pGC); + if (BOX_NOT_EMPTY(box)) + RootlessDamageBox((WindowPtr) dst, &box); + + GCOP_WRAP(pGC); + RL_DEBUG_MSG("push pixels end\n"); +} diff --git a/xorg-server/miext/rootless/rootlessScreen.c b/xorg-server/miext/rootless/rootlessScreen.c index c8557066e..ecc72ea92 100644 --- a/xorg-server/miext/rootless/rootlessScreen.c +++ b/xorg-server/miext/rootless/rootlessScreen.c @@ -29,7 +29,6 @@ * use or other dealings in this Software without prior written authorization. */ - #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> #endif @@ -83,10 +82,10 @@ RootlessUpdateScreenPixmap(ScreenPtr pScreen) PixmapPtr pPix; unsigned int rowbytes; - pPix = (*pScreen->GetScreenPixmap)(pScreen); + pPix = (*pScreen->GetScreenPixmap) (pScreen); if (pPix == NULL) { - pPix = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0); - (*pScreen->SetScreenPixmap)(pPix); + pPix = (*pScreen->CreatePixmap) (pScreen, 0, 0, pScreen->rootDepth, 0); + (*pScreen->SetScreenPixmap) (pPix); } rowbytes = PixmapBytePad(pScreen->width, pScreen->rootDepth); @@ -111,7 +110,6 @@ RootlessUpdateScreenPixmap(ScreenPtr pScreen) } } - /* * RootlessCreateScreenResources * Rootless implementations typically set a null framebuffer pointer, which @@ -125,7 +123,7 @@ RootlessCreateScreenResources(ScreenPtr pScreen) SCREEN_UNWRAP(pScreen, CreateScreenResources); if (pScreen->CreateScreenResources != NULL) - ret = (*pScreen->CreateScreenResources)(pScreen); + ret = (*pScreen->CreateScreenResources) (pScreen); SCREEN_WRAP(pScreen, CreateScreenResources); @@ -139,7 +137,6 @@ RootlessCreateScreenResources(ScreenPtr pScreen) return ret; } - static Bool RootlessCloseScreen(int i, ScreenPtr pScreen) { @@ -160,12 +157,12 @@ RootlessCloseScreen(int i, ScreenPtr pScreen) return pScreen->CloseScreen(i, pScreen); } - static void RootlessGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, unsigned int format, unsigned long planeMask, char *pdstLine) { ScreenPtr pScreen = pDrawable->pScreen; + SCREEN_UNWRAP(pScreen, GetImage); if (pDrawable->type == DRAWABLE_WINDOW) { @@ -177,7 +174,7 @@ RootlessGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, RootlessRedisplayScreen(pScreen); // RedisplayScreen stops drawing, so we need to start it again - RootlessStartDrawing((WindowPtr)pDrawable); + RootlessStartDrawing((WindowPtr) pDrawable); /* Check that we have some place to read from. */ winRec = WINREC(TopLevelParent((WindowPtr) pDrawable)); @@ -194,10 +191,10 @@ RootlessGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, x1 = x0 + w; y1 = y0 + h; - x0 = max (x0, winRec->x); - y0 = max (y0, winRec->y); - x1 = min (x1, winRec->x + winRec->width); - y1 = min (y1, winRec->y + winRec->height); + x0 = max(x0, winRec->x); + y0 = max(y0, winRec->y); + x1 = min(x1, winRec->x + winRec->width); + y1 = min(y1, winRec->y + winRec->height); sx = x0 - pDrawable->x; sy = y0 - pDrawable->y; @@ -210,11 +207,10 @@ RootlessGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, pScreen->GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine); -out: + out: SCREEN_WRAP(pScreen, GetImage); } - /* * RootlessSourceValidate * CopyArea and CopyPlane use a GC tied to the destination drawable. @@ -228,48 +224,50 @@ RootlessSourceValidate(DrawablePtr pDrawable, int x, int y, int w, int h, { SCREEN_UNWRAP(pDrawable->pScreen, SourceValidate); if (pDrawable->type == DRAWABLE_WINDOW) { - WindowPtr pWin = (WindowPtr)pDrawable; + WindowPtr pWin = (WindowPtr) pDrawable; + RootlessStartDrawing(pWin); } if (pDrawable->pScreen->SourceValidate) { - pDrawable->pScreen->SourceValidate(pDrawable, x, y, w, h, subWindowMode); + pDrawable->pScreen->SourceValidate(pDrawable, x, y, w, h, + subWindowMode); } SCREEN_WRAP(pDrawable->pScreen, SourceValidate); } static void RootlessComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, - INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, + INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { ScreenPtr pScreen = pDst->pDrawable->pScreen; PictureScreenPtr ps = GetPictureScreen(pScreen); WindowPtr srcWin, dstWin, maskWin = NULL; - if (pMask) { // pMask can be NULL - maskWin = (pMask->pDrawable && pMask->pDrawable->type == DRAWABLE_WINDOW) ? - (WindowPtr)pMask->pDrawable : NULL; + if (pMask) { // pMask can be NULL + maskWin = (pMask->pDrawable && + pMask->pDrawable->type == + DRAWABLE_WINDOW) ? (WindowPtr) pMask->pDrawable : NULL; } - srcWin = (pSrc->pDrawable && pSrc->pDrawable->type == DRAWABLE_WINDOW) ? - (WindowPtr)pSrc->pDrawable : NULL; - dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ? - (WindowPtr)pDst->pDrawable : NULL; + srcWin = (pSrc->pDrawable && pSrc->pDrawable->type == DRAWABLE_WINDOW) ? + (WindowPtr) pSrc->pDrawable : NULL; + dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ? + (WindowPtr) pDst->pDrawable : NULL; // SCREEN_UNWRAP(ps, Composite); ps->Composite = SCREENREC(pScreen)->Composite; - if (srcWin && IsFramedWindow(srcWin)) + if (srcWin && IsFramedWindow(srcWin)) RootlessStartDrawing(srcWin); if (maskWin && IsFramedWindow(maskWin)) RootlessStartDrawing(maskWin); - if (dstWin && IsFramedWindow(dstWin)) + if (dstWin && IsFramedWindow(dstWin)) RootlessStartDrawing(dstWin); ps->Composite(op, pSrc, pMask, pDst, - xSrc, ySrc, xMask, yMask, - xDst, yDst, width, height); + xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); - if (dstWin && IsFramedWindow(dstWin)) { + if (dstWin && IsFramedWindow(dstWin)) { RootlessDamageRect(dstWin, xDst, yDst, width, height); } @@ -277,11 +275,10 @@ RootlessComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, // SCREEN_WRAP(ps, Composite); } - static void RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, - int nlist, GlyphListPtr list, GlyphPtr *glyphs) + int nlist, GlyphListPtr list, GlyphPtr * glyphs) { ScreenPtr pScreen = pDst->pDrawable->pScreen; PictureScreenPtr ps = GetPictureScreen(pScreen); @@ -291,12 +288,14 @@ RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, WindowPtr srcWin, dstWin; srcWin = (pSrc->pDrawable && pSrc->pDrawable->type == DRAWABLE_WINDOW) ? - (WindowPtr)pSrc->pDrawable : NULL; + (WindowPtr) pSrc->pDrawable : NULL; dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ? - (WindowPtr)pDst->pDrawable : NULL; + (WindowPtr) pDst->pDrawable : NULL; - if (srcWin && IsFramedWindow(srcWin)) RootlessStartDrawing(srcWin); - if (dstWin && IsFramedWindow(dstWin)) RootlessStartDrawing(dstWin); + if (srcWin && IsFramedWindow(srcWin)) + RootlessStartDrawing(srcWin); + if (dstWin && IsFramedWindow(dstWin)) + RootlessStartDrawing(dstWin); //SCREEN_UNWRAP(ps, Glyphs); ps->Glyphs = SCREENREC(pScreen)->Glyphs; @@ -340,10 +339,10 @@ RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, x2 = x1 + glyph->info.width; y2 = y1 + glyph->info.height; - box.x1 = max (box.x1, x1); - box.y1 = max (box.y1, y1); - box.x2 = max (box.x2, x2); - box.y2 = max (box.y2, y2); + box.x1 = max(box.x1, x1); + box.y1 = max(box.y1, y1); + box.x2 = max(box.x2, x2); + box.y2 = max(box.y2, y2); x += glyph->info.xOff; y += glyph->info.yOff; @@ -356,7 +355,6 @@ RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, } } - /* * RootlessValidateTree * ValidateTree is modified in two ways: @@ -378,7 +376,8 @@ RootlessValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind) if (IsRoot(pParent)) { RL_DEBUG_MSG("custom "); result = RootlessMiValidateTree(pParent, pChild, kind); - } else { + } + else { HUGE_ROOT(pParent); result = pScreen->ValidateTree(pParent, pChild, kind); NORMAL_ROOT(pParent); @@ -390,7 +389,6 @@ RootlessValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind) return result; } - /* * RootlessMarkOverlappedWindows * MarkOverlappedWindows is modified to ignore overlapping @@ -403,6 +401,7 @@ RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst, RegionRec saveRoot; Bool result; ScreenPtr pScreen = pWin->drawable.pScreen; + SCREEN_UNWRAP(pScreen, MarkOverlappedWindows); RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS start "); @@ -412,7 +411,7 @@ RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst, RL_DEBUG_MSG("is root not marking "); result = FALSE; } - else if (! IsTopLevel(pWin)) { + else if (!IsTopLevel(pWin)) { // not top-level window - mark normally result = pScreen->MarkOverlappedWindows(pWin, pFirst, ppLayerWin); } @@ -426,7 +425,8 @@ RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst, RL_DEBUG_MSG("is top level! "); /* single layered systems are easy */ - if (ppLayerWin) *ppLayerWin = pWin; + if (ppLayerWin) + *ppLayerWin = pWin; if (pWin == pFirst) { /* Blindly mark pWin and all of its inferiors. This is a slight @@ -437,10 +437,10 @@ RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst, while (1) { if (pChild->viewable) { if (RegionBroken(&pChild->winSize)) - SetWinSize (pChild); + SetWinSize(pChild); if (RegionBroken(&pChild->borderSize)) - SetBorderSize (pChild); - (* MarkWindow)(pChild); + SetBorderSize(pChild); + (*MarkWindow) (pChild); if (pChild->firstChild) { pChild = pChild->firstChild; continue; @@ -455,7 +455,7 @@ RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst, anyMarked = TRUE; } if (anyMarked) - (* MarkWindow)(pWin->parent); + (*MarkWindow) (pWin->parent); result = anyMarked; } NORMAL_ROOT(pWin); @@ -465,94 +465,94 @@ RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst, return result; } -static void expose_1 (WindowPtr pWin) { +static void +expose_1(WindowPtr pWin) +{ WindowPtr pChild; - + if (!pWin->realized) return; - + miPaintWindow(pWin, &pWin->borderClip, PW_BACKGROUND); - + /* FIXME: comments in windowstr.h indicate that borderClip doesn't - include subwindow visibility. But I'm not so sure.. so we may - be exposing too much.. */ - - miSendExposures (pWin, &pWin->borderClip, - pWin->drawable.x, pWin->drawable.y); - + include subwindow visibility. But I'm not so sure.. so we may + be exposing too much.. */ + + miSendExposures(pWin, &pWin->borderClip, + pWin->drawable.x, pWin->drawable.y); + for (pChild = pWin->firstChild; pChild != NULL; pChild = pChild->nextSib) - expose_1 (pChild); + expose_1(pChild); } void -RootlessScreenExpose (ScreenPtr pScreen) +RootlessScreenExpose(ScreenPtr pScreen) { - expose_1 (pScreen->root); + expose_1(pScreen->root); } - ColormapPtr -RootlessGetColormap (ScreenPtr pScreen) +RootlessGetColormap(ScreenPtr pScreen) { - RootlessScreenRec *s = SCREENREC (pScreen); + RootlessScreenRec *s = SCREENREC(pScreen); - return s->colormap; + return s->colormap; } static void -RootlessInstallColormap (ColormapPtr pMap) +RootlessInstallColormap(ColormapPtr pMap) { - ScreenPtr pScreen = pMap->pScreen; - RootlessScreenRec *s = SCREENREC (pScreen); + ScreenPtr pScreen = pMap->pScreen; + RootlessScreenRec *s = SCREENREC(pScreen); - SCREEN_UNWRAP(pScreen, InstallColormap); + SCREEN_UNWRAP(pScreen, InstallColormap); - if (s->colormap != pMap) { - s->colormap = pMap; - s->colormap_changed = TRUE; - RootlessQueueRedisplay (pScreen); - } + if (s->colormap != pMap) { + s->colormap = pMap; + s->colormap_changed = TRUE; + RootlessQueueRedisplay(pScreen); + } - pScreen->InstallColormap (pMap); + pScreen->InstallColormap(pMap); - SCREEN_WRAP (pScreen, InstallColormap); + SCREEN_WRAP(pScreen, InstallColormap); } static void -RootlessUninstallColormap (ColormapPtr pMap) +RootlessUninstallColormap(ColormapPtr pMap) { - ScreenPtr pScreen = pMap->pScreen; - RootlessScreenRec *s = SCREENREC (pScreen); + ScreenPtr pScreen = pMap->pScreen; + RootlessScreenRec *s = SCREENREC(pScreen); - SCREEN_UNWRAP(pScreen, UninstallColormap); + SCREEN_UNWRAP(pScreen, UninstallColormap); - if (s->colormap == pMap) - s->colormap = NULL; + if (s->colormap == pMap) + s->colormap = NULL; - pScreen->UninstallColormap (pMap); + pScreen->UninstallColormap(pMap); - SCREEN_WRAP(pScreen, UninstallColormap); + SCREEN_WRAP(pScreen, UninstallColormap); } static void -RootlessStoreColors (ColormapPtr pMap, int ndef, xColorItem *pdef) +RootlessStoreColors(ColormapPtr pMap, int ndef, xColorItem * pdef) { - ScreenPtr pScreen = pMap->pScreen; - RootlessScreenRec *s = SCREENREC (pScreen); + ScreenPtr pScreen = pMap->pScreen; + RootlessScreenRec *s = SCREENREC(pScreen); - SCREEN_UNWRAP(pScreen, StoreColors); + SCREEN_UNWRAP(pScreen, StoreColors); - if (s->colormap == pMap && ndef > 0) { - s->colormap_changed = TRUE; - RootlessQueueRedisplay (pScreen); - } + if (s->colormap == pMap && ndef > 0) { + s->colormap_changed = TRUE; + RootlessQueueRedisplay(pScreen); + } - pScreen->StoreColors (pMap, ndef, pdef); + pScreen->StoreColors(pMap, ndef, pdef); - SCREEN_WRAP(pScreen, StoreColors); + SCREEN_WRAP(pScreen, StoreColors); } - static CARD32 RootlessRedisplayCallback(OsTimerPtr timer, CARD32 time, void *arg) { @@ -576,7 +576,6 @@ RootlessRedisplayCallback(OsTimerPtr timer, CARD32 time, void *arg) return ROOTLESS_REDISPLAY_DELAY; } - /* * RootlessQueueRedisplay * Queue a redisplay after a timer delay to ensure we do not redisplay @@ -594,12 +593,10 @@ RootlessQueueRedisplay(ScreenPtr pScreen) screenRec->redisplay_timer = TimerSet(screenRec->redisplay_timer, 0, ROOTLESS_REDISPLAY_DELAY, - RootlessRedisplayCallback, - screenRec); + RootlessRedisplayCallback, screenRec); screenRec->redisplay_timer_set = TRUE; } - /* * RootlessBlockHandler * If the redisplay timer has expired, flush drawing before blocking @@ -618,30 +615,31 @@ RootlessBlockHandler(pointer pbdata, OSTimePtr pTimeout, pointer pReadmask) } } - static void RootlessWakeupHandler(pointer data, int i, pointer LastSelectMask) { // nothing here } - static Bool RootlessAllocatePrivates(ScreenPtr pScreen) { RootlessScreenRec *s; - if (!dixRegisterPrivateKey(&rootlessGCPrivateKeyRec, PRIVATE_GC, sizeof(RootlessGCRec))) + if (!dixRegisterPrivateKey + (&rootlessGCPrivateKeyRec, PRIVATE_GC, sizeof(RootlessGCRec))) return FALSE; if (!dixRegisterPrivateKey(&rootlessScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) return FALSE; if (!dixRegisterPrivateKey(&rootlessWindowPrivateKeyRec, PRIVATE_WINDOW, 0)) return FALSE; - if (!dixRegisterPrivateKey(&rootlessWindowOldPixmapPrivateKeyRec, PRIVATE_WINDOW, 0)) + if (!dixRegisterPrivateKey + (&rootlessWindowOldPixmapPrivateKeyRec, PRIVATE_WINDOW, 0)) return FALSE; s = malloc(sizeof(RootlessScreenRec)); - if (! s) return FALSE; + if (!s) + return FALSE; SETSCREENREC(pScreen, s); s->pixmap_data = NULL; @@ -653,7 +651,6 @@ RootlessAllocatePrivates(ScreenPtr pScreen) return TRUE; } - static void RootlessWrap(ScreenPtr pScreen) { @@ -696,6 +693,7 @@ RootlessWrap(ScreenPtr pScreen) { // Composite and Glyphs don't use normal screen wrapping PictureScreenPtr ps = GetPictureScreen(pScreen); + s->Composite = ps->Composite; ps->Composite = RootlessComposite; s->Glyphs = ps->Glyphs; @@ -707,13 +705,13 @@ RootlessWrap(ScreenPtr pScreen) #undef WRAP } - /* * RootlessInit * Called by the rootless implementation to initialize the rootless layer. * Rootless wraps lots of stuff and needs a bunch of devPrivates. */ -Bool RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs) +Bool +RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs) { RootlessScreenRec *s; @@ -730,25 +728,24 @@ Bool RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs) if (!RegisterBlockAndWakeupHandlers(RootlessBlockHandler, RootlessWakeupHandler, - (pointer) pScreen)) - { + (pointer) pScreen)) { return FALSE; } return TRUE; } -void RootlessUpdateRooted (Bool state) { +void +RootlessUpdateRooted(Bool state) +{ int i; - - if (!state) - { + + if (!state) { for (i = 0; i < screenInfo.numScreens; i++) - RootlessDisableRoot (screenInfo.screens[i]); + RootlessDisableRoot(screenInfo.screens[i]); } - else - { + else { for (i = 0; i < screenInfo.numScreens; i++) - RootlessEnableRoot (screenInfo.screens[i]); + RootlessEnableRoot(screenInfo.screens[i]); } } diff --git a/xorg-server/miext/rootless/rootlessValTree.c b/xorg-server/miext/rootless/rootlessValTree.c index 9aa881423..730d2917e 100644 --- a/xorg-server/miext/rootless/rootlessValTree.c +++ b/xorg-server/miext/rootless/rootlessValTree.c @@ -86,14 +86,14 @@ Equipment Corporation. * Summer '89: Joel McCormack -- so fast you wouldn't believe it possible. * In particular, much improved code for window mapping and * circulating. - * Bob Scheifler -- avoid miComputeClips for unmapped windows, - * valdata changes + * Bob Scheifler -- avoid miComputeClips for unmapped windows, + * valdata changes */ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> #endif -#include <stddef.h> /* For NULL */ +#include <stddef.h> /* For NULL */ #include <X11/X.h> #include "scrnintstr.h" #include "validate.h" @@ -104,65 +104,63 @@ Equipment Corporation. #include "globals.h" -int RootlessMiValidateTree (WindowPtr pRoot, WindowPtr pChild, VTKind kind); +int RootlessMiValidateTree(WindowPtr pRoot, WindowPtr pChild, VTKind kind); /* * Compute the visibility of a shaped window */ static int -RootlessShapedWindowIn (RegionPtr universe, - RegionPtr bounding, BoxPtr rect, int x, int y) +RootlessShapedWindowIn(RegionPtr universe, + RegionPtr bounding, BoxPtr rect, int x, int y) { - BoxRec box; - register BoxPtr boundBox; - int nbox; - Bool someIn, someOut; + BoxRec box; + register BoxPtr boundBox; + int nbox; + Bool someIn, someOut; register int t, x1, y1, x2, y2; - nbox = RegionNumRects (bounding); - boundBox = RegionRects (bounding); + nbox = RegionNumRects(bounding); + boundBox = RegionRects(bounding); someIn = someOut = FALSE; x1 = rect->x1; y1 = rect->y1; x2 = rect->x2; y2 = rect->y2; - while (nbox--) - { - if ((t = boundBox->x1 + x) < x1) - t = x1; - box.x1 = t; - if ((t = boundBox->y1 + y) < y1) - t = y1; - box.y1 = t; - if ((t = boundBox->x2 + x) > x2) - t = x2; - box.x2 = t; - if ((t = boundBox->y2 + y) > y2) - t = y2; - box.y2 = t; - if (box.x1 > box.x2) - box.x2 = box.x1; - if (box.y1 > box.y2) - box.y2 = box.y1; - switch (RegionContainsRect(universe, &box)) - { - case rgnIN: - if (someOut) - return rgnPART; - someIn = TRUE; - break; - case rgnOUT: - if (someIn) - return rgnPART; - someOut = TRUE; - break; - default: - return rgnPART; - } - boundBox++; + while (nbox--) { + if ((t = boundBox->x1 + x) < x1) + t = x1; + box.x1 = t; + if ((t = boundBox->y1 + y) < y1) + t = y1; + box.y1 = t; + if ((t = boundBox->x2 + x) > x2) + t = x2; + box.x2 = t; + if ((t = boundBox->y2 + y) > y2) + t = y2; + box.y2 = t; + if (box.x1 > box.x2) + box.x2 = box.x1; + if (box.y1 > box.y2) + box.y2 = box.y1; + switch (RegionContainsRect(universe, &box)) { + case rgnIN: + if (someOut) + return rgnPART; + someIn = TRUE; + break; + case rgnOUT: + if (someIn) + return rgnPART; + someOut = TRUE; + break; + default: + return rgnPART; + } + boundBox++; } if (someIn) - return rgnIN; + return rgnIN; return rgnOUT; } @@ -170,7 +168,6 @@ RootlessShapedWindowIn (RegionPtr universe, HasBorder(w) && \ (w)->backgroundState == ParentRelative) - /* *----------------------------------------------------------------------- * RootlessComputeClips -- @@ -188,18 +185,18 @@ RootlessShapedWindowIn (RegionPtr universe, *----------------------------------------------------------------------- */ static void -RootlessComputeClips (WindowPtr pParent, ScreenPtr pScreen, - RegionPtr universe, VTKind kind, RegionPtr exposed) +RootlessComputeClips(WindowPtr pParent, ScreenPtr pScreen, + RegionPtr universe, VTKind kind, RegionPtr exposed) { - int dx, - dy; - RegionRec childUniverse; - register WindowPtr pChild; - int oldVis, newVis; - BoxRec borderSize; - RegionRec childUnion; - Bool overlap; - RegionPtr borderVisible; + int dx, dy; + RegionRec childUniverse; + register WindowPtr pChild; + int oldVis, newVis; + BoxRec borderSize; + RegionRec childUnion; + Bool overlap; + RegionPtr borderVisible; + /* * Figure out the new visibility of this window. * The extent of the universe should be the same as the extent of @@ -210,52 +207,52 @@ RootlessComputeClips (WindowPtr pParent, ScreenPtr pScreen, */ borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent); borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent); - dx = (int) pParent->drawable.x + (int) pParent->drawable.width + wBorderWidth(pParent); + dx = (int) pParent->drawable.x + (int) pParent->drawable.width + + wBorderWidth(pParent); if (dx > 32767) - dx = 32767; + dx = 32767; borderSize.x2 = dx; - dy = (int) pParent->drawable.y + (int) pParent->drawable.height + wBorderWidth(pParent); + dy = (int) pParent->drawable.y + (int) pParent->drawable.height + + wBorderWidth(pParent); if (dy > 32767) - dy = 32767; + dy = 32767; borderSize.y2 = dy; oldVis = pParent->visibility; - switch (RegionContainsRect(universe, &borderSize)) - { + switch (RegionContainsRect(universe, &borderSize)) { case rgnIN: - newVis = VisibilityUnobscured; - break; - case rgnPART: - newVis = VisibilityPartiallyObscured; - { - RegionPtr pBounding; - - if ((pBounding = wBoundingShape (pParent))) - { - switch (RootlessShapedWindowIn (universe, - pBounding, &borderSize, - pParent->drawable.x, - pParent->drawable.y)) - { - case rgnIN: - newVis = VisibilityUnobscured; - break; - case rgnOUT: - newVis = VisibilityFullyObscured; - break; - } - } - } - break; - default: - newVis = VisibilityFullyObscured; - break; + newVis = VisibilityUnobscured; + break; + case rgnPART: + newVis = VisibilityPartiallyObscured; + { + RegionPtr pBounding; + + if ((pBounding = wBoundingShape(pParent))) { + switch (RootlessShapedWindowIn(universe, + pBounding, &borderSize, + pParent->drawable.x, + pParent->drawable.y)) { + case rgnIN: + newVis = VisibilityUnobscured; + break; + case rgnOUT: + newVis = VisibilityFullyObscured; + break; + } + } + } + break; + default: + newVis = VisibilityFullyObscured; + break; } pParent->visibility = newVis; if (oldVis != newVis && - ((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask)) - SendVisibilityNotify(pParent); + ((pParent-> + eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask)) + SendVisibilityNotify(pParent); dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x; dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y; @@ -268,74 +265,64 @@ RootlessComputeClips (WindowPtr pParent, ScreenPtr pScreen, case VTMap: case VTStack: case VTUnmap: - break; + break; case VTMove: - if ((oldVis == newVis) && - ((oldVis == VisibilityFullyObscured) || - (oldVis == VisibilityUnobscured))) - { - pChild = pParent; - while (1) - { - if (pChild->viewable) - { - if (pChild->visibility != VisibilityFullyObscured) - { - RegionTranslate(&pChild->borderClip, - dx, dy); - RegionTranslate(&pChild->clipList, - dx, dy); - pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER; - if (pScreen->ClipNotify) - (* pScreen->ClipNotify) (pChild, dx, dy); - - } - if (pChild->valdata) - { - RegionNull(&pChild->valdata->after.borderExposed); - if (HasParentRelativeBorder(pChild)) - { - RegionSubtract(&pChild->valdata->after.borderExposed, - &pChild->borderClip, - &pChild->winSize); - } - RegionNull(&pChild->valdata->after.exposed); - } - if (pChild->firstChild) - { - pChild = pChild->firstChild; - continue; - } - } - while (!pChild->nextSib && (pChild != pParent)) - pChild = pChild->parent; - if (pChild == pParent) - break; - pChild = pChild->nextSib; - } - return; - } - /* fall through */ + if ((oldVis == newVis) && + ((oldVis == VisibilityFullyObscured) || + (oldVis == VisibilityUnobscured))) { + pChild = pParent; + while (1) { + if (pChild->viewable) { + if (pChild->visibility != VisibilityFullyObscured) { + RegionTranslate(&pChild->borderClip, dx, dy); + RegionTranslate(&pChild->clipList, dx, dy); + pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER; + if (pScreen->ClipNotify) + (*pScreen->ClipNotify) (pChild, dx, dy); + + } + if (pChild->valdata) { + RegionNull(&pChild->valdata->after.borderExposed); + if (HasParentRelativeBorder(pChild)) { + RegionSubtract(&pChild->valdata->after. + borderExposed, &pChild->borderClip, + &pChild->winSize); + } + RegionNull(&pChild->valdata->after.exposed); + } + if (pChild->firstChild) { + pChild = pChild->firstChild; + continue; + } + } + while (!pChild->nextSib && (pChild != pParent)) + pChild = pChild->parent; + if (pChild == pParent) + break; + pChild = pChild->nextSib; + } + return; + } + /* fall through */ default: - /* - * To calculate exposures correctly, we have to translate the old - * borderClip and clipList regions to the window's new location so there - * is a correspondence between pieces of the new and old clipping regions. - */ - if (dx || dy) - { - /* - * We translate the old clipList because that will be exposed or copied - * if gravity is right. - */ - RegionTranslate(&pParent->borderClip, dx, dy); - RegionTranslate(&pParent->clipList, dx, dy); - } - break; + /* + * To calculate exposures correctly, we have to translate the old + * borderClip and clipList regions to the window's new location so there + * is a correspondence between pieces of the new and old clipping regions. + */ + if (dx || dy) { + /* + * We translate the old clipList because that will be exposed or copied + * if gravity is right. + */ + RegionTranslate(&pParent->borderClip, dx, dy); + RegionTranslate(&pParent->clipList, dx, dy); + } + break; case VTBroken: - RegionEmpty(&pParent->borderClip); - RegionEmpty(&pParent->clipList); - break; + RegionEmpty(&pParent->borderClip); + RegionEmpty(&pParent->clipList); + break; } borderVisible = pParent->valdata->before.borderVisible; @@ -351,104 +338,91 @@ RootlessComputeClips (WindowPtr pParent, ScreenPtr pScreen, * This leaves a region of pieces that weren't exposed before. */ - if (HasBorder (pParent)) - { - if (borderVisible) - { - /* - * when the border changes shape, the old visible portions - * of the border will be saved by DIX in borderVisible -- - * use that region and destroy it - */ - RegionSubtract(exposed, universe, borderVisible); - RegionDestroy(borderVisible); - } - else - { - RegionSubtract(exposed, universe, &pParent->borderClip); - } - if (HasParentRelativeBorder(pParent) && (dx || dy)) { - RegionSubtract(&pParent->valdata->after.borderExposed, - universe, - &pParent->winSize); - } else { - RegionSubtract(&pParent->valdata->after.borderExposed, - exposed, &pParent->winSize); - } - - RegionCopy(&pParent->borderClip, universe); - - /* - * To get the right clipList for the parent, and to make doubly sure - * that no child overlaps the parent's border, we remove the parent's - * border from the universe before proceeding. - */ - - RegionIntersect(universe, universe, &pParent->winSize); + if (HasBorder(pParent)) { + if (borderVisible) { + /* + * when the border changes shape, the old visible portions + * of the border will be saved by DIX in borderVisible -- + * use that region and destroy it + */ + RegionSubtract(exposed, universe, borderVisible); + RegionDestroy(borderVisible); + } + else { + RegionSubtract(exposed, universe, &pParent->borderClip); + } + if (HasParentRelativeBorder(pParent) && (dx || dy)) { + RegionSubtract(&pParent->valdata->after.borderExposed, + universe, &pParent->winSize); + } + else { + RegionSubtract(&pParent->valdata->after.borderExposed, + exposed, &pParent->winSize); + } + + RegionCopy(&pParent->borderClip, universe); + + /* + * To get the right clipList for the parent, and to make doubly sure + * that no child overlaps the parent's border, we remove the parent's + * border from the universe before proceeding. + */ + + RegionIntersect(universe, universe, &pParent->winSize); } else - RegionCopy(&pParent->borderClip, universe); - - if ((pChild = pParent->firstChild) && pParent->mapped) - { - RegionNull(&childUniverse); - RegionNull(&childUnion); - if ((pChild->drawable.y < pParent->lastChild->drawable.y) || - ((pChild->drawable.y == pParent->lastChild->drawable.y) && - (pChild->drawable.x < pParent->lastChild->drawable.x))) - { - for (; pChild; pChild = pChild->nextSib) - { - if (pChild->viewable) - RegionAppend(&childUnion, &pChild->borderSize); - } - } - else - { - for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib) - { - if (pChild->viewable) - RegionAppend(&childUnion, &pChild->borderSize); - } - } - RegionValidate(&childUnion, &overlap); - - for (pChild = pParent->firstChild; - pChild; - pChild = pChild->nextSib) - { - if (pChild->viewable) { - /* - * If the child is viewable, we want to remove its extents - * from the current universe, but we only re-clip it if - * it's been marked. - */ - if (pChild->valdata) { - /* - * Figure out the new universe from the child's - * perspective and recurse. - */ - RegionIntersect(&childUniverse, - universe, - &pChild->borderSize); - RootlessComputeClips (pChild, pScreen, &childUniverse, - kind, exposed); - } - /* - * Once the child has been processed, we remove its extents - * from the current universe, thus denying its space to any - * other sibling. - */ - if (overlap) - RegionSubtract(universe, universe, - &pChild->borderSize); - } - } - if (!overlap) - RegionSubtract(universe, universe, &childUnion); - RegionUninit(&childUnion); - RegionUninit(&childUniverse); - } /* if any children */ + RegionCopy(&pParent->borderClip, universe); + + if ((pChild = pParent->firstChild) && pParent->mapped) { + RegionNull(&childUniverse); + RegionNull(&childUnion); + if ((pChild->drawable.y < pParent->lastChild->drawable.y) || + ((pChild->drawable.y == pParent->lastChild->drawable.y) && + (pChild->drawable.x < pParent->lastChild->drawable.x))) { + for (; pChild; pChild = pChild->nextSib) { + if (pChild->viewable) + RegionAppend(&childUnion, &pChild->borderSize); + } + } + else { + for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib) { + if (pChild->viewable) + RegionAppend(&childUnion, &pChild->borderSize); + } + } + RegionValidate(&childUnion, &overlap); + + for (pChild = pParent->firstChild; pChild; pChild = pChild->nextSib) { + if (pChild->viewable) { + /* + * If the child is viewable, we want to remove its extents + * from the current universe, but we only re-clip it if + * it's been marked. + */ + if (pChild->valdata) { + /* + * Figure out the new universe from the child's + * perspective and recurse. + */ + RegionIntersect(&childUniverse, + universe, &pChild->borderSize); + RootlessComputeClips(pChild, pScreen, &childUniverse, + kind, exposed); + } + /* + * Once the child has been processed, we remove its extents + * from the current universe, thus denying its space to any + * other sibling. + */ + if (overlap) + RegionSubtract(universe, universe, &pChild->borderSize); + } + } + if (!overlap) + RegionSubtract(universe, universe, &childUnion); + RegionUninit(&childUnion); + RegionUninit(&childUniverse); + } /* if any children */ /* * 'universe' now contains the new clipList for the parent window. @@ -457,25 +431,22 @@ RootlessComputeClips (WindowPtr pParent, ScreenPtr pScreen, * new, just as for the border. */ - if (oldVis == VisibilityFullyObscured || - oldVis == VisibilityNotViewable) - { - RegionCopy(&pParent->valdata->after.exposed, universe); + if (oldVis == VisibilityFullyObscured || oldVis == VisibilityNotViewable) { + RegionCopy(&pParent->valdata->after.exposed, universe); } else if (newVis != VisibilityFullyObscured && - newVis != VisibilityNotViewable) - { - RegionSubtract(&pParent->valdata->after.exposed, - universe, &pParent->clipList); + newVis != VisibilityNotViewable) { + RegionSubtract(&pParent->valdata->after.exposed, + universe, &pParent->clipList); } /* HACK ALERT - copying contents of regions, instead of regions */ { - RegionRec tmp; + RegionRec tmp; - tmp = pParent->clipList; - pParent->clipList = *universe; - *universe = tmp; + tmp = pParent->clipList; + pParent->clipList = *universe; + *universe = tmp; } #ifdef NOTDEF @@ -485,35 +456,33 @@ RootlessComputeClips (WindowPtr pParent, ScreenPtr pScreen, pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER; if (pScreen->ClipNotify) - (* pScreen->ClipNotify) (pParent, dx, dy); + (*pScreen->ClipNotify) (pParent, dx, dy); } static void RootlessTreeObscured(WindowPtr pParent) { register WindowPtr pChild; - register int oldVis; + register int oldVis; pChild = pParent; - while (1) - { - if (pChild->viewable) - { - oldVis = pChild->visibility; - if (oldVis != (pChild->visibility = VisibilityFullyObscured) && - ((pChild->eventMask | wOtherEventMasks(pChild)) & VisibilityChangeMask)) - SendVisibilityNotify(pChild); - if (pChild->firstChild) - { - pChild = pChild->firstChild; - continue; - } - } - while (!pChild->nextSib && (pChild != pParent)) - pChild = pChild->parent; - if (pChild == pParent) - break; - pChild = pChild->nextSib; + while (1) { + if (pChild->viewable) { + oldVis = pChild->visibility; + if (oldVis != (pChild->visibility = VisibilityFullyObscured) && + ((pChild-> + eventMask | wOtherEventMasks(pChild)) & VisibilityChangeMask)) + SendVisibilityNotify(pChild); + if (pChild->firstChild) { + pChild = pChild->firstChild; + continue; + } + } + while (!pChild->nextSib && (pChild != pParent)) + pChild = pChild->parent; + if (pChild == pParent) + break; + pChild = pChild->nextSib; } } @@ -551,31 +520,30 @@ RootlessTreeObscured(WindowPtr pParent) We need to make sure top-level windows don't clip each other, and that top-level windows aren't clipped to the root window. */ -/*ARGSUSED*/ + /*ARGSUSED*/ // fixme this is ugly // Xprint/ValTree.c doesn't work, but maybe that method can? -int -RootlessMiValidateTree (WindowPtr pRoot, /* Parent to validate */ - WindowPtr pChild, /* First child of pRoot that was - * affected */ - VTKind kind /* What kind of configuration caused call */) + int +RootlessMiValidateTree(WindowPtr pRoot, /* Parent to validate */ + WindowPtr pChild, /* First child of pRoot that was + * affected */ + VTKind kind /* What kind of configuration caused call */ + ) { - RegionRec childClip; /* The new borderClip for the current - * child */ - RegionRec exposed; /* For intermediate calculations */ - register ScreenPtr pScreen; - register WindowPtr pWin; + RegionRec childClip; /* The new borderClip for the current + * child */ + RegionRec exposed; /* For intermediate calculations */ + register ScreenPtr pScreen; + register WindowPtr pWin; pScreen = pRoot->drawable.pScreen; if (pChild == NullWindow) - pChild = pRoot->firstChild; + pChild = pRoot->firstChild; RegionNull(&childClip); RegionNull(&exposed); - if (RegionBroken(&pRoot->clipList) && - !RegionBroken(&pRoot->borderClip)) - { + if (RegionBroken(&pRoot->clipList) && !RegionBroken(&pRoot->borderClip)) { // fixme this might not work, but hopefully doesn't happen anyway. kind = VTBroken; RegionEmpty(&pRoot->clipList); @@ -588,22 +556,21 @@ RootlessMiValidateTree (WindowPtr pRoot, /* Parent to validate */ * childClip is always reset to that child's size. */ - for (pWin = pChild; - pWin != NullWindow; - pWin = pWin->nextSib) - { + for (pWin = pChild; pWin != NullWindow; pWin = pWin->nextSib) { if (pWin->viewable) { if (pWin->valdata) { RegionCopy(&childClip, &pWin->borderSize); - RootlessComputeClips (pWin, pScreen, &childClip, kind, &exposed); - } else if (pWin->visibility == VisibilityNotViewable) { + RootlessComputeClips(pWin, pScreen, &childClip, kind, &exposed); + } + else if (pWin->visibility == VisibilityNotViewable) { RootlessTreeObscured(pWin); } - } else { + } + else { if (pWin->valdata) { RegionEmpty(&pWin->clipList); if (pScreen->ClipNotify) - (* pScreen->ClipNotify) (pWin, 0, 0); + (*pScreen->ClipNotify) (pWin, 0, 0); RegionEmpty(&pWin->borderClip); pWin->valdata = NULL; } diff --git a/xorg-server/miext/rootless/rootlessWindow.c b/xorg-server/miext/rootless/rootlessWindow.c index 20fdaba8d..cfcb6e558 100644 --- a/xorg-server/miext/rootless/rootlessWindow.c +++ b/xorg-server/miext/rootless/rootlessWindow.c @@ -1,1637 +1,1638 @@ -/*
- * Rootless window management
- */
-/*
- * Copyright (c) 2001 Greg Parker. All Rights Reserved.
- * Copyright (c) 2002-2004 Torrey T. Lyons. All Rights Reserved.
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name(s) of the above copyright
- * holders shall not be used in advertising or otherwise to promote the sale,
- * use or other dealings in this Software without prior written authorization.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stddef.h> /* For NULL */
-#include <limits.h> /* For CHAR_BIT */
-#include <assert.h>
-#include <X11/Xatom.h>
-#ifdef __APPLE__
-#include <Xplugin.h>
-#include "mi.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-//#include <X11/extensions/applewm.h>
-extern int darwinMainScreenX, darwinMainScreenY;
-extern Bool no_configure_window;
-#endif
-#include "fb.h"
-
-#include "rootlessCommon.h"
-#include "rootlessWindow.h"
-
-#define SCREEN_TO_GLOBAL_X \
- (pScreen->x + rootlessGlobalOffsetX)
-#define SCREEN_TO_GLOBAL_Y \
- (pScreen->y + rootlessGlobalOffsetY)
-
-#define DEFINE_ATOM_HELPER(func,atom_name) \
- static Atom func (void) { \
- static unsigned int generation = 0; \
- static Atom atom; \
- if (generation != serverGeneration) { \
- generation = serverGeneration; \
- atom = MakeAtom (atom_name, strlen (atom_name), TRUE); \
- } \
- return atom; \
- }
-
-DEFINE_ATOM_HELPER (xa_native_window_id, "_NATIVE_WINDOW_ID")
-
-static Bool windows_hidden;
-// TODO - abstract xp functions
-
-#ifdef __APPLE__
-
-// XXX: identical to x_cvt_vptr_to_uint ?
-#define MAKE_WINDOW_ID(x) ((xp_window_id)((size_t)(x)))
-
-void
-RootlessNativeWindowStateChanged (WindowPtr pWin, unsigned int state)
-{
- RootlessWindowRec *winRec;
-
- if (pWin == NULL) return;
-
- winRec = WINREC (pWin);
- if (winRec == NULL) return;
-
- winRec->is_offscreen = ((state & XP_WINDOW_STATE_OFFSCREEN) != 0);
- winRec->is_obscured = ((state & XP_WINDOW_STATE_OBSCURED) != 0);
- pWin->rootlessUnhittable = winRec->is_offscreen;
-}
-
-void RootlessNativeWindowMoved (WindowPtr pWin) {
- xp_box bounds;
- int sx, sy, err;
- XID vlist[2];
- Mask mask;
- ClientPtr pClient;
- RootlessWindowRec *winRec;
-
- winRec = WINREC(pWin);
-
- if (xp_get_window_bounds (MAKE_WINDOW_ID(winRec->wid), &bounds) != Success) return;
-
- sx = pWin->drawable.pScreen->x + darwinMainScreenX;
- sy = pWin->drawable.pScreen->y + darwinMainScreenY;
-
- /* Fake up a ConfigureWindow packet to resize the window to the current bounds. */
- vlist[0] = (INT16) bounds.x1 - sx;
- vlist[1] = (INT16) bounds.y1 - sy;
- mask = CWX | CWY;
-
- /* pretend we're the owner of the window! */
- err = dixLookupClient(&pClient, pWin->drawable.id, serverClient, DixUnknownAccess);
- if(err != Success) {
- ErrorF("RootlessNativeWindowMoved(): Failed to lookup window: 0x%x\n", (unsigned int)pWin->drawable.id);
- return;
- }
-
- /* Don't want to do anything to the physical window (avoids
- notification-response feedback loops) */
-
- no_configure_window = TRUE;
- ConfigureWindow (pWin, mask, vlist, pClient);
- no_configure_window = FALSE;
-}
-
-#endif /* __APPLE__ */
-
-/*
- * RootlessCreateWindow
- * For now, don't create a physical window until either the window is
- * realized, or we really need it (e.g. to attach VRAM surfaces to).
- * Do reset the window size so it's not clipped by the root window.
- */
-Bool
-RootlessCreateWindow(WindowPtr pWin)
-{
- Bool result;
- RegionRec saveRoot;
-
- SETWINREC(pWin, NULL);
- dixSetPrivate(&pWin->devPrivates, rootlessWindowOldPixmapPrivateKey, NULL);
-
- SCREEN_UNWRAP(pWin->drawable.pScreen, CreateWindow);
-
- if (!IsRoot(pWin)) {
- /* win/border size set by DIX, not by wrapped CreateWindow, so
- correct it here. Don't HUGE_ROOT when pWin is the root! */
-
- HUGE_ROOT(pWin);
- SetWinSize(pWin);
- SetBorderSize(pWin);
- }
-
- result = pWin->drawable.pScreen->CreateWindow(pWin);
-
- if (pWin->parent) {
- NORMAL_ROOT(pWin);
- }
-
- SCREEN_WRAP(pWin->drawable.pScreen, CreateWindow);
-
- return result;
-}
-
-
-/*
- * RootlessDestroyFrame
- * Destroy the physical window associated with the given window.
- */
-static void
-RootlessDestroyFrame(WindowPtr pWin, RootlessWindowPtr winRec)
-{
- SCREENREC(pWin->drawable.pScreen)->imp->DestroyFrame(winRec->wid);
- free(winRec);
- SETWINREC(pWin, NULL);
-}
-
-
-/*
- * RootlessDestroyWindow
- * Destroy the physical window associated with the given window.
- */
-Bool
-RootlessDestroyWindow(WindowPtr pWin)
-{
- RootlessWindowRec *winRec = WINREC(pWin);
- Bool result;
-
- if (winRec != NULL) {
- RootlessDestroyFrame(pWin, winRec);
- }
-
- SCREEN_UNWRAP(pWin->drawable.pScreen, DestroyWindow);
- result = pWin->drawable.pScreen->DestroyWindow(pWin);
- SCREEN_WRAP(pWin->drawable.pScreen, DestroyWindow);
-
- return result;
-}
-
-
-
-static Bool
-RootlessGetShape(WindowPtr pWin, RegionPtr pShape)
-{
- if (wBoundingShape(pWin) == NULL)
- return FALSE;
-
- /* wBoundingShape is relative to *inner* origin of window.
- Translate by borderWidth to get the outside-relative position. */
-
- RegionNull(pShape);
- RegionCopy(pShape, wBoundingShape(pWin));
- RegionTranslate(pShape, pWin->borderWidth, pWin->borderWidth);
-
- return TRUE;
-}
-
-
-/*
- * RootlessReshapeFrame
- * Set the frame shape.
- */
-static void RootlessReshapeFrame(WindowPtr pWin)
-{
- RootlessWindowRec *winRec = WINREC(pWin);
- RegionRec newShape;
- RegionPtr pShape;
-
- // If the window is not yet framed, do nothing
- if (winRec == NULL)
- return;
-
- if (IsRoot(pWin))
- return;
-
- RootlessStopDrawing(pWin, FALSE);
-
- pShape = RootlessGetShape(pWin, &newShape) ? &newShape : NULL;
-
-#ifdef ROOTLESSDEBUG
- RL_DEBUG_MSG("reshaping...");
- if (pShape != NULL) {
- RL_DEBUG_MSG("numrects %d, extents %d %d %d %d ",
- RegionNumRects(&newShape),
- newShape.extents.x1, newShape.extents.y1,
- newShape.extents.x2, newShape.extents.y2);
- } else {
- RL_DEBUG_MSG("no shape ");
- }
-#endif
-
- SCREENREC(pWin->drawable.pScreen)->imp->ReshapeFrame(winRec->wid, pShape);
-
- if (pShape != NULL)
- RegionUninit(&newShape);
-}
-
-
-/*
- * RootlessSetShape
- * Shape is usually set before a window is mapped and the window will
- * not have a frame associated with it. In this case, the frame will be
- * shaped when the window is framed.
- */
-void
-RootlessSetShape(WindowPtr pWin, int kind)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
-
- SCREEN_UNWRAP(pScreen, SetShape);
- pScreen->SetShape(pWin, kind);
- SCREEN_WRAP(pScreen, SetShape);
-
- RootlessReshapeFrame(pWin);
-}
-
-
-
-/* Disallow ParentRelative background on top-level windows
- because the root window doesn't really have the right background.
- */
-Bool
-RootlessChangeWindowAttributes(WindowPtr pWin, unsigned long vmask)
-{
- Bool result;
- ScreenPtr pScreen = pWin->drawable.pScreen;
-
- RL_DEBUG_MSG("change window attributes start ");
-
- SCREEN_UNWRAP(pScreen, ChangeWindowAttributes);
- result = pScreen->ChangeWindowAttributes(pWin, vmask);
- SCREEN_WRAP(pScreen, ChangeWindowAttributes);
-
- if (WINREC(pWin)) {
- // disallow ParentRelative background state
- if (pWin->backgroundState == ParentRelative) {
- XID pixel = 0;
- ChangeWindowAttributes(pWin, CWBackPixel, &pixel, serverClient);
- }
- }
-
- RL_DEBUG_MSG("change window attributes end\n");
- return result;
-}
-
-
-/*
- * RootlessPositionWindow
- * This is a hook for when DIX moves or resizes a window.
- * Update the frame position now although the physical window is moved
- * in RootlessMoveWindow. (x, y) are *inside* position. After this,
- * mi and fb are expecting the pixmap to be at the new location.
- */
-Bool
-RootlessPositionWindow(WindowPtr pWin, int x, int y)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- RootlessWindowRec *winRec = WINREC(pWin);
- Bool result;
-
- RL_DEBUG_MSG("positionwindow start (win 0x%x @ %i, %i)\n", pWin, x, y);
-
- if (winRec) {
- if (winRec->is_drawing) {
- // Reset frame's pixmap and move it to the new position.
- int bw = wBorderWidth(pWin);
-
- winRec->pixmap->devPrivate.ptr = winRec->pixelData;
- SetPixmapBaseToScreen(winRec->pixmap, x - bw, y - bw);
- }
- }
-
- SCREEN_UNWRAP(pScreen, PositionWindow);
- result = pScreen->PositionWindow(pWin, x, y);
- SCREEN_WRAP(pScreen, PositionWindow);
-
- RL_DEBUG_MSG("positionwindow end\n");
- return result;
-}
-
-
-/*
- * RootlessInitializeFrame
- * Initialize some basic attributes of the frame. Note that winRec
- * may already have valid data in it, so don't overwrite anything
- * valuable.
- */
-static void
-RootlessInitializeFrame(WindowPtr pWin, RootlessWindowRec *winRec)
-{
- DrawablePtr d = &pWin->drawable;
- int bw = wBorderWidth(pWin);
-
- winRec->win = pWin;
-
- winRec->x = d->x - bw;
- winRec->y = d->y - bw;
- winRec->width = d->width + 2*bw;
- winRec->height = d->height + 2*bw;
- winRec->borderWidth = bw;
-}
-
-/*
- * RootlessEnsureFrame
- * Make sure the given window is framed. If the window doesn't have a
- * physical window associated with it, attempt to create one. If that
- * is unsuccessful, return NULL.
- */
-static RootlessWindowRec *
-RootlessEnsureFrame(WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- RootlessWindowRec *winRec;
- RegionRec shape;
- RegionPtr pShape = NULL;
-
- if (WINREC(pWin) != NULL)
- return WINREC(pWin);
-
- if (!IsTopLevel(pWin) && !IsRoot(pWin))
- return NULL;
-
- if (pWin->drawable.class != InputOutput)
- return NULL;
-
- winRec = malloc(sizeof(RootlessWindowRec));
-
- if (!winRec)
- return NULL;
-
- RootlessInitializeFrame(pWin, winRec);
-
- winRec->is_drawing = FALSE;
- winRec->is_reorder_pending = FALSE;
- winRec->pixmap = NULL;
- winRec->wid = NULL;
- winRec->level = 0;
-
- SETWINREC(pWin, winRec);
-
- // Set the frame's shape if the window is shaped
- if (RootlessGetShape(pWin, &shape))
- pShape = &shape;
-
- RL_DEBUG_MSG("creating frame ");
-
- if (!SCREENREC(pScreen)->imp->CreateFrame(winRec, pScreen,
- winRec->x + SCREEN_TO_GLOBAL_X,
- winRec->y + SCREEN_TO_GLOBAL_Y,
- pShape))
- {
- RL_DEBUG_MSG("implementation failed to create frame!\n");
- free(winRec);
- SETWINREC(pWin, NULL);
- return NULL;
- }
-
- if (pWin->drawable.depth == 8)
- RootlessFlushWindowColormap(pWin);
-
- if (pShape != NULL)
- RegionUninit(&shape);
-
- return winRec;
-}
-
-
-/*
- * RootlessRealizeWindow
- * The frame is usually created here and not in CreateWindow so that
- * windows do not eat memory until they are realized.
- */
-Bool
-RootlessRealizeWindow(WindowPtr pWin)
-{
- Bool result;
- RegionRec saveRoot;
- ScreenPtr pScreen = pWin->drawable.pScreen;
-
- RL_DEBUG_MSG("realizewindow start (win 0x%x) ", pWin);
-
- if ((IsTopLevel(pWin) && pWin->drawable.class == InputOutput)) {
- RootlessWindowRec *winRec;
-
- winRec = RootlessEnsureFrame(pWin);
- if (winRec == NULL)
- return FALSE;
-
- winRec->is_reorder_pending = TRUE;
-
- RL_DEBUG_MSG("Top level window ");
-
- // Disallow ParentRelative background state on top-level windows.
- // This might have been set before the window was mapped.
- if (pWin->backgroundState == ParentRelative) {
- XID pixel = 0;
- ChangeWindowAttributes(pWin, CWBackPixel, &pixel, serverClient);
- }
- }
-
- if (!IsRoot(pWin)) HUGE_ROOT(pWin);
- SCREEN_UNWRAP(pScreen, RealizeWindow);
- result = pScreen->RealizeWindow(pWin);
- SCREEN_WRAP(pScreen, RealizeWindow);
- if (!IsRoot(pWin)) NORMAL_ROOT(pWin);
-
- RL_DEBUG_MSG("realizewindow end\n");
- return result;
-}
-
-
-/*
- * RootlessFrameForWindow
- * Returns the frame ID for the physical window displaying the given window.
- * If CREATE is true and the window has no frame, attempt to create one.
- */
-RootlessFrameID
-RootlessFrameForWindow(WindowPtr pWin, Bool create)
-{
- WindowPtr pTopWin;
- RootlessWindowRec *winRec;
-
- pTopWin = TopLevelParent(pWin);
- if (pTopWin == NULL)
- return NULL;
-
- winRec = WINREC(pTopWin);
-
- if (winRec == NULL && create && pWin->drawable.class == InputOutput) {
- winRec = RootlessEnsureFrame(pTopWin);
- }
-
- if (winRec == NULL)
- return NULL;
-
- return winRec->wid;
-}
-
-
-/*
- * RootlessUnrealizeWindow
- * Unmap the physical window.
- */
-Bool
-RootlessUnrealizeWindow(WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- RootlessWindowRec *winRec = WINREC(pWin);
- Bool result;
-
- RL_DEBUG_MSG("unrealizewindow start ");
-
- if (winRec) {
- RootlessStopDrawing(pWin, FALSE);
-
- SCREENREC(pScreen)->imp->UnmapFrame(winRec->wid);
-
- winRec->is_reorder_pending = FALSE;
- }
-
- SCREEN_UNWRAP(pScreen, UnrealizeWindow);
- result = pScreen->UnrealizeWindow(pWin);
- SCREEN_WRAP(pScreen, UnrealizeWindow);
-
- RL_DEBUG_MSG("unrealizewindow end\n");
- return result;
-}
-
-
-/*
- * RootlessReorderWindow
- * Reorder the frame associated with the given window so that it's
- * physically above the window below it in the X stacking order.
- */
-void
-RootlessReorderWindow(WindowPtr pWin)
-{
- RootlessWindowRec *winRec = WINREC(pWin);
-
- if (pWin->realized && winRec != NULL && !winRec->is_reorder_pending && !windows_hidden) {
- WindowPtr newPrevW;
- RootlessWindowRec *newPrev;
- RootlessFrameID newPrevID;
- ScreenPtr pScreen = pWin->drawable.pScreen;
-
- /* Check if the implementation wants the frame to not be reordered
- even though the X11 window is restacked. This can be useful if
- frames are ordered-in with animation so that the reordering is not
- done until the animation is complete. */
- if (SCREENREC(pScreen)->imp->DoReorderWindow) {
- if (!SCREENREC(pScreen)->imp->DoReorderWindow(winRec))
- return;
- }
-
- RootlessStopDrawing(pWin, FALSE);
-
- /* Find the next window above this one that has a mapped frame.
- * Only include cases where the windows are in the same category of
- * hittability to ensure offscreen windows dont get restacked
- * relative to onscreen ones (but that the offscreen ones maintain
- * their stacking order if they are explicitly asked to Reorder
- */
-
- newPrevW = pWin->prevSib;
- while (newPrevW && (WINREC(newPrevW) == NULL || !newPrevW->realized || newPrevW->rootlessUnhittable != pWin->rootlessUnhittable))
- newPrevW = newPrevW->prevSib;
-
- newPrev = newPrevW != NULL ? WINREC(newPrevW) : NULL;
- newPrevID = newPrev != NULL ? newPrev->wid : 0;
-
- /* If it exists, reorder the frame above us first. */
-
- if (newPrev && newPrev->is_reorder_pending) {
- newPrev->is_reorder_pending = FALSE;
- RootlessReorderWindow(newPrevW);
- }
-
- SCREENREC(pScreen)->imp->RestackFrame(winRec->wid, newPrevID);
- }
-}
-
-
-/*
- * RootlessRestackWindow
- * This is a hook for when DIX changes the window stacking order.
- * The window has already been inserted into its new position in the
- * DIX window stack. We need to change the order of the physical
- * window to match.
- */
-void
-RootlessRestackWindow(WindowPtr pWin, WindowPtr pOldNextSib)
-{
- RegionRec saveRoot;
- RootlessWindowRec *winRec = WINREC(pWin);
- ScreenPtr pScreen = pWin->drawable.pScreen;
-
- RL_DEBUG_MSG("restackwindow start ");
- if (winRec)
- RL_DEBUG_MSG("restack top level \n");
-
- HUGE_ROOT(pWin);
- SCREEN_UNWRAP(pScreen, RestackWindow);
-
- if (pScreen->RestackWindow)
- pScreen->RestackWindow(pWin, pOldNextSib);
-
- SCREEN_WRAP(pScreen, RestackWindow);
- NORMAL_ROOT(pWin);
-
- if (winRec && pWin->viewable) {
- RootlessReorderWindow(pWin);
- }
-
- RL_DEBUG_MSG("restackwindow end\n");
-}
-
-/*
- * Specialized window copy procedures
- */
-
-// Globals needed during window resize and move.
-static pointer gResizeDeathBits = NULL;
-static int gResizeDeathCount = 0;
-static PixmapPtr gResizeDeathPix[2] = {NULL, NULL};
-static BoxRec gResizeDeathBounds[2];
-static CopyWindowProcPtr gResizeOldCopyWindowProc = NULL;
-
-/*
- * RootlessNoCopyWindow
- * CopyWindow() that doesn't do anything. For MoveWindow() of
- * top-level windows.
- */
-static void
-RootlessNoCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg,
- RegionPtr prgnSrc)
-{
- // some code expects the region to be translated
- int dx = ptOldOrg.x - pWin->drawable.x;
- int dy = ptOldOrg.y - pWin->drawable.y;
-
- RL_DEBUG_MSG("ROOTLESSNOCOPYWINDOW ");
-
- RegionTranslate(prgnSrc, -dx, -dy);
-}
-
-
-/*
- * RootlessResizeCopyWindow
- * CopyWindow used during ResizeWindow for gravity moves. Based on
- * fbCopyWindow. The original always draws on the root pixmap, which
- * we don't have. Instead, draw on the parent window's pixmap.
- * Resize version: the old location's pixels are in gResizeCopyWindowSource.
- */
-static void
-RootlessResizeCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg,
- RegionPtr prgnSrc)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- RegionRec rgnDst;
- int dx, dy;
-
- RL_DEBUG_MSG("resizecopywindowFB start (win 0x%x) ", pWin);
-
- /* Don't unwrap pScreen->CopyWindow.
- The bogus rewrap with RootlessCopyWindow causes a crash if
- CopyWindow is called again during the same resize. */
-
- if (gResizeDeathCount == 0)
- return;
-
- RootlessStartDrawing(pWin);
-
- dx = ptOldOrg.x - pWin->drawable.x;
- dy = ptOldOrg.y - pWin->drawable.y;
- RegionTranslate(prgnSrc, -dx, -dy);
- RegionNull(&rgnDst);
- RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc);
-
- if (gResizeDeathCount == 1) {
- /* Simple case, we only have a single source pixmap. */
-
- fbCopyRegion(&gResizeDeathPix[0]->drawable,
- &pScreen->GetWindowPixmap(pWin)->drawable, 0,
- &rgnDst, dx, dy, fbCopyWindowProc, 0, 0);
- }
- else {
- int i;
- RegionRec clip, clipped;
-
- /* More complex case, N source pixmaps (usually two). So we
- intersect the destination with each source and copy those bits. */
-
- for (i = 0; i < gResizeDeathCount; i++) {
- RegionInit(&clip, gResizeDeathBounds + 0, 1);
- RegionNull(&clipped);
- RegionIntersect(&rgnDst, &clip, &clipped);
-
- fbCopyRegion(&gResizeDeathPix[i]->drawable,
- &pScreen->GetWindowPixmap(pWin)->drawable, 0,
- &clipped, dx, dy, fbCopyWindowProc, 0, 0);
-
- RegionUninit(&clipped);
- RegionUninit(&clip);
- }
- }
-
- /* Don't update - resize will update everything */
- RegionUninit(&rgnDst);
-
- fbValidateDrawable(&pWin->drawable);
-
- RL_DEBUG_MSG("resizecopywindowFB end\n");
-}
-
-
-/*
- * RootlessCopyWindow
- * Update *new* location of window. Old location is redrawn with
- * miPaintWindow. Cloned from fbCopyWindow.
- * The original always draws on the root pixmap, which we don't have.
- * Instead, draw on the parent window's pixmap.
- */
-void
-RootlessCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- RegionRec rgnDst;
- int dx, dy;
- BoxPtr extents;
- int area;
-
- RL_DEBUG_MSG("copywindowFB start (win 0x%x) ", pWin);
-
- SCREEN_UNWRAP(pScreen, CopyWindow);
-
- dx = ptOldOrg.x - pWin->drawable.x;
- dy = ptOldOrg.y - pWin->drawable.y;
- RegionTranslate(prgnSrc, -dx, -dy);
-
- RegionNull(&rgnDst);
- RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc);
-
- extents = RegionExtents(&rgnDst);
- area = (extents->x2 - extents->x1) * (extents->y2 - extents->y1);
-
- /* If the area exceeds threshold, use the implementation's
- accelerated version. */
- if (area > rootless_CopyWindow_threshold &&
- SCREENREC(pScreen)->imp->CopyWindow)
- {
- RootlessWindowRec *winRec;
- WindowPtr top;
-
- top = TopLevelParent(pWin);
- if (top == NULL) {
- RL_DEBUG_MSG("no parent\n");
- goto out;
- }
-
- winRec = WINREC(top);
- if (winRec == NULL) {
- RL_DEBUG_MSG("not framed\n");
- goto out;
- }
-
- /* Move region to window local coords */
- RegionTranslate(&rgnDst, -winRec->x, -winRec->y);
-
- RootlessStopDrawing(pWin, FALSE);
-
- SCREENREC(pScreen)->imp->CopyWindow(winRec->wid,
- RegionNumRects(&rgnDst),
- RegionRects(&rgnDst),
- dx, dy);
- }
- else {
- RootlessStartDrawing(pWin);
-
- fbCopyRegion((DrawablePtr) pWin, (DrawablePtr) pWin,
- 0, &rgnDst, dx, dy, fbCopyWindowProc, 0, 0);
-
- /* prgnSrc has been translated to dst position */
- RootlessDamageRegion(pWin, prgnSrc);
- }
-
-out:
- RegionUninit(&rgnDst);
- fbValidateDrawable(&pWin->drawable);
-
- SCREEN_WRAP(pScreen, CopyWindow);
-
- RL_DEBUG_MSG("copywindowFB end\n");
-}
-
-
-/*
- * Window resize procedures
- */
-
-enum {
- WIDTH_SMALLER = 1,
- HEIGHT_SMALLER = 2,
-};
-
-
-/*
- * ResizeWeighting
- * Choose gravity to avoid local copies. Do that by looking for
- * a corner that doesn't move _relative to the screen_.
- */
-static inline unsigned int
-ResizeWeighting(int oldX1, int oldY1, int oldX2, int oldY2, int oldBW,
- int newX1, int newY1, int newX2, int newY2, int newBW)
-{
-#ifdef ROOTLESS_RESIZE_GRAVITY
- if (newBW != oldBW)
- return RL_GRAVITY_NONE;
-
- if (newX1 == oldX1 && newY1 == oldY1)
- return RL_GRAVITY_NORTH_WEST;
- else if (newX1 == oldX1 && newY2 == oldY2)
- return RL_GRAVITY_SOUTH_WEST;
- else if (newX2 == oldX2 && newY2 == oldY2)
- return RL_GRAVITY_SOUTH_EAST;
- else if (newX2 == oldX2 && newY1 == oldY1)
- return RL_GRAVITY_NORTH_EAST;
- else
- return RL_GRAVITY_NONE;
-#else
- return RL_GRAVITY_NONE;
-#endif
-}
-
-
-/*
- * StartFrameResize
- * Prepare to resize a top-level window. The old window's pixels are
- * saved and the implementation is told to change the window size.
- * (x,y,w,h) is outer frame of window (outside border)
- */
-static Bool
-StartFrameResize(WindowPtr pWin, Bool gravity,
- int oldX, int oldY, int oldW, int oldH, int oldBW,
- int newX, int newY, int newW, int newH, int newBW)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- RootlessWindowRec *winRec = WINREC(pWin);
- Bool need_window_source = FALSE, resize_after = FALSE;
-
- BoxRec rect;
- int oldX2, newX2;
- int oldY2, newY2;
- unsigned int weight;
-
- oldX2 = oldX + oldW, newX2 = newX + newW;
- oldY2 = oldY + oldH, newY2 = newY + newH;
-
- /* Decide which resize weighting to use */
- weight = ResizeWeighting(oldX, oldY, oldW, oldH, oldBW,
- newX, newY, newW, newH, newBW);
-
- /* Compute intersection between old and new rects */
- rect.x1 = max(oldX, newX);
- rect.y1 = max(oldY, newY);
- rect.x2 = min(oldX2, newX2);
- rect.y2 = min(oldY2, newY2);
-
- RL_DEBUG_MSG("RESIZE TOPLEVEL WINDOW with gravity %i ", gravity);
- RL_DEBUG_MSG("%d %d %d %d %d %d %d %d %d %d\n",
- oldX, oldY, oldW, oldH, oldBW,
- newX, newY, newW, newH, newBW);
-
- RootlessRedisplay(pWin);
-
- /* If gravity is true, then we need to have a way of recovering all
- the original bits in the window for when X rearranges the contents
- based on the various gravity settings. The obvious way is to just
- snapshot the entire backing store before resizing it, but that
- it slow on large windows.
-
- So the optimization here is to use the implementation's resize
- weighting options (if available) to allow us to reason about what
- is left in the backing store after the resize. We can then only
- copy what won't be there after the resize, and do a two-stage copy
- operation.
-
- Most of these optimizations are only applied when the top-left
- corner of the window is fixed, since that's the common case. They
- could probably be extended with some thought. */
-
- gResizeDeathCount = 0;
-
- if (gravity && weight == RL_GRAVITY_NORTH_WEST) {
- unsigned int code = 0;
-
- /* Top left corner is anchored. We never need to copy the
- entire window. */
-
- need_window_source = TRUE;
-
- /* These comparisons were chosen to avoid setting bits when the sizes
- are the same. (So the fastest case automatically gets taken when
- dimensions are unchanging.) */
-
- if (newW < oldW)
- code |= WIDTH_SMALLER;
- if (newH < oldH)
- code |= HEIGHT_SMALLER;
-
- if (((code ^ (code >> 1)) & 1) == 0) {
- /* Both dimensions are either getting larger, or both
- are getting smaller. No need to copy anything. */
-
- if (code == (WIDTH_SMALLER | HEIGHT_SMALLER)) {
- /* Since the window is getting smaller, we can do gravity
- repair on it with it's current size, then resize it
- afterwards. */
-
- resize_after = TRUE;
- }
-
- gResizeDeathCount = 1;
- }
- else {
- unsigned int copy_rowbytes, Bpp;
- unsigned int copy_rect_width, copy_rect_height;
- BoxRec copy_rect;
-
- /* We can get away with a partial copy. 'rect' is the
- intersection between old and new bounds, so copy
- everything to the right of or below the intersection. */
-
- RootlessStartDrawing(pWin);
-
- if (code == WIDTH_SMALLER) {
- copy_rect.x1 = rect.x2;
- copy_rect.y1 = rect.y1;
- copy_rect.x2 = oldX2;
- copy_rect.y2 = oldY2;
- }
- else if (code == HEIGHT_SMALLER) {
- copy_rect.x1 = rect.x1;
- copy_rect.y1 = rect.y2;
- copy_rect.x2 = oldX2;
- copy_rect.y2 = oldY2;
- }
- else
- OsAbort();
-
- Bpp = winRec->win->drawable.bitsPerPixel / 8;
- copy_rect_width = copy_rect.x2 - copy_rect.x1;
- copy_rect_height = copy_rect.y2 - copy_rect.y1;
- copy_rowbytes = ((copy_rect_width * Bpp) + 31) & ~31;
- gResizeDeathBits = malloc(copy_rowbytes
- * copy_rect_height);
-
- if (copy_rect_width * copy_rect_height >
- rootless_CopyBytes_threshold &&
- SCREENREC(pScreen)->imp->CopyBytes)
- {
- SCREENREC(pScreen)->imp->CopyBytes(
- copy_rect_width * Bpp, copy_rect_height,
- ((char *) winRec->pixelData)
- + ((copy_rect.y1 - oldY) * winRec->bytesPerRow)
- + (copy_rect.x1 - oldX) * Bpp, winRec->bytesPerRow,
- gResizeDeathBits, copy_rowbytes);
- } else {
- fbBlt((FbBits *) (winRec->pixelData
- + ((copy_rect.y1 - oldY) * winRec->bytesPerRow)
- + (copy_rect.x1 - oldX) * Bpp),
- winRec->bytesPerRow / sizeof(FbBits), 0,
- (FbBits *) gResizeDeathBits,
- copy_rowbytes / sizeof(FbBits), 0,
- copy_rect_width * Bpp, copy_rect_height,
- GXcopy, FB_ALLONES, Bpp, 0, 0);
- }
-
- gResizeDeathBounds[1] = copy_rect;
- gResizeDeathPix[1]
- = GetScratchPixmapHeader(pScreen, copy_rect_width,
- copy_rect_height,
- winRec->win->drawable.depth,
- winRec->win->drawable.bitsPerPixel,
- winRec->bytesPerRow,
- (void *) gResizeDeathBits);
-
- SetPixmapBaseToScreen(gResizeDeathPix[1],
- copy_rect.x1, copy_rect.y1);
-
- gResizeDeathCount = 2;
- }
- }
- else if (gravity) {
- /* The general case. Just copy everything. */
-
- RootlessStartDrawing(pWin);
-
- gResizeDeathBits = malloc(winRec->bytesPerRow * winRec->height);
-
- memcpy(gResizeDeathBits, winRec->pixelData,
- winRec->bytesPerRow * winRec->height);
-
- gResizeDeathBounds[0] = (BoxRec) {oldX, oldY, oldX2, oldY2};
- gResizeDeathPix[0]
- = GetScratchPixmapHeader(pScreen, winRec->width,
- winRec->height,
- winRec->win->drawable.depth,
- winRec->win->drawable.bitsPerPixel,
- winRec->bytesPerRow,
- (void *) gResizeDeathBits);
-
- SetPixmapBaseToScreen(gResizeDeathPix[0], oldX, oldY);
- gResizeDeathCount = 1;
- }
-
- RootlessStopDrawing(pWin, FALSE);
-
- winRec->x = newX;
- winRec->y = newY;
- winRec->width = newW;
- winRec->height = newH;
- winRec->borderWidth = newBW;
-
- /* Unless both dimensions are getting smaller, Resize the frame
- before doing gravity repair */
-
- if (!resize_after) {
- SCREENREC(pScreen)->imp->ResizeFrame(winRec->wid, pScreen,
- newX + SCREEN_TO_GLOBAL_X,
- newY + SCREEN_TO_GLOBAL_Y,
- newW, newH, weight);
- }
-
- RootlessStartDrawing(pWin);
-
- /* If necessary, create a source pixmap pointing at the current
- window bits. */
-
- if (need_window_source) {
- gResizeDeathBounds[0] = (BoxRec) {oldX, oldY, oldX2, oldY2};
- gResizeDeathPix[0]
- = GetScratchPixmapHeader(pScreen, oldW, oldH,
- winRec->win->drawable.depth,
- winRec->win->drawable.bitsPerPixel,
- winRec->bytesPerRow, winRec->pixelData);
-
- SetPixmapBaseToScreen(gResizeDeathPix[0], oldX, oldY);
- }
-
- /* Use custom CopyWindow when moving gravity bits around
- ResizeWindow assumes the old window contents are in the same
- pixmap, but here they're in deathPix instead. */
-
- if (gravity) {
- gResizeOldCopyWindowProc = pScreen->CopyWindow;
- pScreen->CopyWindow = RootlessResizeCopyWindow;
- }
-
- /* If we can't rely on the window server preserving the bits we
- need in the position we need, copy the pixels in the
- intersection from src to dst. ResizeWindow assumes these pixels
- are already present when making gravity adjustments. pWin
- currently has new-sized pixmap but is in old position.
-
- FIXME: border width change! (?) */
-
- if (gravity && weight == RL_GRAVITY_NONE) {
- PixmapPtr src, dst;
-
- assert(gResizeDeathCount == 1);
-
- src = gResizeDeathPix[0];
- dst = pScreen->GetWindowPixmap(pWin);
-
- RL_DEBUG_MSG("Resize copy rect %d %d %d %d\n",
- rect.x1, rect.y1, rect.x2, rect.y2);
-
- /* rect is the intersection of the old location and new location */
- if (BOX_NOT_EMPTY(rect) && src != NULL && dst != NULL) {
- /* The window drawable still has the old frame position, which
- means that DST doesn't actually point at the origin of our
- physical backing store when adjusted by the drawable.x,y
- position. So sneakily adjust it temporarily while copying.. */
-
- ((PixmapPtr) dst)->devPrivate.ptr = winRec->pixelData;
- SetPixmapBaseToScreen(dst, newX, newY);
-
- fbCopyWindowProc(&src->drawable, &dst->drawable, NULL,
- &rect, 1, 0, 0, FALSE, FALSE, 0, 0);
-
- ((PixmapPtr) dst)->devPrivate.ptr = winRec->pixelData;
- SetPixmapBaseToScreen(dst, oldX, oldY);
- }
- }
-
- return resize_after;
-}
-
-
-static void
-FinishFrameResize(WindowPtr pWin, Bool gravity, int oldX, int oldY,
- unsigned int oldW, unsigned int oldH, unsigned int oldBW,
- int newX, int newY, unsigned int newW, unsigned int newH,
- unsigned int newBW, Bool resize_now)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- RootlessWindowRec *winRec = WINREC(pWin);
- int i;
-
- RootlessStopDrawing(pWin, FALSE);
-
- if (resize_now) {
- unsigned int weight;
-
- /* We didn't resize anything earlier, so do it now, now that
- we've finished gravitating the bits. */
-
- weight = ResizeWeighting(oldX, oldY, oldW, oldH, oldBW,
- newX, newY, newW, newH, newBW);
-
- SCREENREC(pScreen)->imp->ResizeFrame(winRec->wid, pScreen,
- newX + SCREEN_TO_GLOBAL_X,
- newY + SCREEN_TO_GLOBAL_Y,
- newW, newH, weight);
- }
-
- /* Redraw everything. FIXME: there must be times when we don't need
- to do this. Perhaps when top-left weighting and no gravity? */
-
- RootlessDamageRect(pWin, -newBW, -newBW, newW, newH);
-
- for (i = 0; i < 2; i++) {
- if (gResizeDeathPix[i] != NULL) {
- FreeScratchPixmapHeader(gResizeDeathPix[i]);
- gResizeDeathPix[i] = NULL;
- }
- }
-
- free(gResizeDeathBits);
- gResizeDeathBits = NULL;
-
- if (gravity) {
- pScreen->CopyWindow = gResizeOldCopyWindowProc;
- }
-}
-
-
-/*
- * RootlessMoveWindow
- * If kind==VTOther, window border is resizing (and borderWidth is
- * already changed!!@#$) This case works like window resize, not move.
- */
-void
-RootlessMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind)
-{
- RootlessWindowRec *winRec = WINREC(pWin);
- ScreenPtr pScreen = pWin->drawable.pScreen;
- CopyWindowProcPtr oldCopyWindowProc = NULL;
- int oldX = 0, oldY = 0, newX = 0, newY = 0;
- unsigned int oldW = 0, oldH = 0, oldBW = 0;
- unsigned int newW = 0, newH = 0, newBW = 0;
- Bool resize_after = FALSE;
- RegionRec saveRoot;
-
- RL_DEBUG_MSG("movewindow start \n");
-
- if (winRec) {
- if (kind == VTMove) {
- oldX = winRec->x;
- oldY = winRec->y;
- RootlessRedisplay(pWin);
- RootlessStartDrawing(pWin);
- } else {
- RL_DEBUG_MSG("movewindow border resizing ");
-
- oldBW = winRec->borderWidth;
- oldX = winRec->x;
- oldY = winRec->y;
- oldW = winRec->width;
- oldH = winRec->height;
-
- newBW = wBorderWidth(pWin);
- newX = x;
- newY = y;
- newW = pWin->drawable.width + 2*newBW;
- newH = pWin->drawable.height + 2*newBW;
-
- resize_after = StartFrameResize(pWin, FALSE,
- oldX, oldY, oldW, oldH, oldBW,
- newX, newY, newW, newH, newBW);
- }
- }
-
- HUGE_ROOT(pWin);
- SCREEN_UNWRAP(pScreen, MoveWindow);
-
- if (winRec) {
- oldCopyWindowProc = pScreen->CopyWindow;
- pScreen->CopyWindow = RootlessNoCopyWindow;
- }
- pScreen->MoveWindow(pWin, x, y, pSib, kind);
- if (winRec) {
- pScreen->CopyWindow = oldCopyWindowProc;
- }
-
- NORMAL_ROOT(pWin);
- SCREEN_WRAP(pScreen, MoveWindow);
-
- if (winRec) {
- if (kind == VTMove) {
- winRec->x = x;
- winRec->y = y;
- RootlessStopDrawing(pWin, FALSE);
- SCREENREC(pScreen)->imp->MoveFrame(winRec->wid, pScreen,
- x + SCREEN_TO_GLOBAL_X,
- y + SCREEN_TO_GLOBAL_Y);
- } else {
- FinishFrameResize(pWin, FALSE, oldX, oldY, oldW, oldH, oldBW,
- newX, newY, newW, newH, newBW, resize_after);
- }
- }
-
- RL_DEBUG_MSG("movewindow end\n");
-}
-
-
-/*
- * RootlessResizeWindow
- * Note: (x, y, w, h) as passed to this procedure don't match the frame
- * definition. (x,y) is corner of very outer edge, *outside* border.
- * w,h is width and height *inside* border, *ignoring* border width.
- * The rect (x, y, w, h) doesn't mean anything. (x, y, w+2*bw, h+2*bw)
- * is total rect and (x+bw, y+bw, w, h) is inner rect.
- */
-void
-RootlessResizeWindow(WindowPtr pWin, int x, int y,
- unsigned int w, unsigned int h, WindowPtr pSib)
-{
- RootlessWindowRec *winRec = WINREC(pWin);
- ScreenPtr pScreen = pWin->drawable.pScreen;
- int oldX = 0, oldY = 0, newX = 0, newY = 0;
- unsigned int oldW = 0, oldH = 0, oldBW = 0, newW = 0, newH = 0, newBW = 0;
- Bool resize_after = FALSE;
- RegionRec saveRoot;
-
- RL_DEBUG_MSG("resizewindow start (win 0x%x) ", pWin);
-
- if(pWin->parent) {
- if (winRec) {
- oldBW = winRec->borderWidth;
- oldX = winRec->x;
- oldY = winRec->y;
- oldW = winRec->width;
- oldH = winRec->height;
-
- newBW = oldBW;
- newX = x;
- newY = y;
- newW = w + 2*newBW;
- newH = h + 2*newBW;
-
- resize_after = StartFrameResize(pWin, TRUE,
- oldX, oldY, oldW, oldH, oldBW,
- newX, newY, newW, newH, newBW);
- }
-
- HUGE_ROOT(pWin);
- SCREEN_UNWRAP(pScreen, ResizeWindow);
- pScreen->ResizeWindow(pWin, x, y, w, h, pSib);
- SCREEN_WRAP(pScreen, ResizeWindow);
- NORMAL_ROOT(pWin);
-
- if (winRec) {
- FinishFrameResize(pWin, TRUE, oldX, oldY, oldW, oldH, oldBW,
- newX, newY, newW, newH, newBW, resize_after);
- }
- } else {
- /* Special case for resizing the root window */
- BoxRec box;
-
- pWin->drawable.x = x;
- pWin->drawable.y = y;
- pWin->drawable.width = w;
- pWin->drawable.height = h;
-
- box.x1 = x; box.y1 = y;
- box.x2 = x + w; box.y2 = y + h;
- RegionUninit(&pWin->winSize);
- RegionInit(&pWin->winSize, &box, 1);
- RegionCopy(&pWin->borderSize, &pWin->winSize);
- RegionCopy(&pWin->clipList, &pWin->winSize);
- RegionCopy(&pWin->borderClip, &pWin->winSize);
-
- if (winRec) {
- SCREENREC(pScreen)->imp->ResizeFrame(winRec->wid, pScreen,
- x + SCREEN_TO_GLOBAL_X,
- y + SCREEN_TO_GLOBAL_Y,
- w, h, RL_GRAVITY_NONE);
- }
-
- miSendExposures(pWin, &pWin->borderClip,
- pWin->drawable.x, pWin->drawable.y);
- }
-
- RL_DEBUG_MSG("resizewindow end\n");
-}
-
-
-/*
- * RootlessRepositionWindow
- * Called by the implementation when a window needs to be repositioned to
- * its correct location on the screen. This routine is typically needed
- * due to changes in the underlying window system, such as a screen layout
- * change.
- */
-void
-RootlessRepositionWindow(WindowPtr pWin)
-{
- RootlessWindowRec *winRec = WINREC(pWin);
- ScreenPtr pScreen = pWin->drawable.pScreen;
-
- if (winRec == NULL)
- return;
-
- RootlessStopDrawing(pWin, FALSE);
- SCREENREC(pScreen)->imp->MoveFrame(winRec->wid, pScreen,
- winRec->x + SCREEN_TO_GLOBAL_X,
- winRec->y + SCREEN_TO_GLOBAL_Y);
-
- RootlessReorderWindow(pWin);
-}
-
-
-/*
- * RootlessReparentWindow
- * Called after a window has been reparented. Generally windows are not
- * framed until they are mapped. However, a window may be framed early by the
- * implementation calling RootlessFrameForWindow. (e.g. this could be needed
- * to attach a VRAM surface to it.) If the window is subsequently reparented
- * by the window manager before being mapped, we need to give the frame to
- * the new top-level window.
- */
-void
-RootlessReparentWindow(WindowPtr pWin, WindowPtr pPriorParent)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- RootlessWindowRec *winRec = WINREC(pWin);
- WindowPtr pTopWin;
-
- /* Check that window is not top-level now, but used to be. */
- if (IsRoot(pWin) || IsRoot(pWin->parent)
- || IsTopLevel(pWin) || winRec == NULL)
- {
- goto out;
- }
-
- /* If the formerly top-level window has a frame, we want to give the
- frame to its new top-level parent. If we can't do that, we'll just
- have to jettison it... */
-
- pTopWin = TopLevelParent(pWin);
- assert(pTopWin != pWin);
-
- pWin->rootlessUnhittable = FALSE;
-
- DeleteProperty (serverClient, pWin, xa_native_window_id ());
-
- if (WINREC(pTopWin) != NULL) {
- /* We're screwed. */
- RootlessDestroyFrame(pWin, winRec);
- } else {
- if (!pTopWin->realized && pWin->realized) {
- SCREENREC(pScreen)->imp->UnmapFrame(winRec->wid);
- }
-
- /* Switch the frame record from one to the other. */
-
- SETWINREC(pWin, NULL);
- SETWINREC(pTopWin, winRec);
-
- RootlessInitializeFrame(pTopWin, winRec);
- RootlessReshapeFrame(pTopWin);
-
- SCREENREC(pScreen)->imp->ResizeFrame(winRec->wid, pScreen,
- winRec->x + SCREEN_TO_GLOBAL_X,
- winRec->y + SCREEN_TO_GLOBAL_Y,
- winRec->width, winRec->height,
- RL_GRAVITY_NONE);
-
- if (SCREENREC(pScreen)->imp->SwitchWindow) {
- SCREENREC(pScreen)->imp->SwitchWindow(winRec, pWin);
- }
-
- if (pTopWin->realized && !pWin->realized)
- winRec->is_reorder_pending = TRUE;
- }
-
-out:
- if (SCREENREC(pScreen)->ReparentWindow) {
- SCREEN_UNWRAP(pScreen, ReparentWindow);
- pScreen->ReparentWindow(pWin, pPriorParent);
- SCREEN_WRAP(pScreen, ReparentWindow);
- }
-}
-
-
-void
-RootlessFlushWindowColormap (WindowPtr pWin)
-{
- RootlessWindowRec *winRec = WINREC (pWin);
- ScreenPtr pScreen = pWin->drawable.pScreen;
-
- if (winRec == NULL)
- return;
-
- RootlessStopDrawing (pWin, FALSE);
-
- if (SCREENREC(pScreen)->imp->UpdateColormap)
- SCREENREC(pScreen)->imp->UpdateColormap(winRec->wid, pScreen);
-}
-
-/*
- * RootlessChangeBorderWidth
- * FIXME: untested!
- * pWin inside corner stays the same; pWin->drawable.[xy] stays the same
- * Frame moves and resizes.
- */
-void
-RootlessChangeBorderWidth(WindowPtr pWin, unsigned int width)
-{
- RegionRec saveRoot;
- Bool resize_after = FALSE;
-
- RL_DEBUG_MSG("change border width ");
-
- if (width != wBorderWidth(pWin)) {
- RootlessWindowRec *winRec = WINREC(pWin);
- int oldX = 0, oldY = 0, newX = 0, newY = 0;
- unsigned int oldW = 0, oldH = 0, oldBW = 0;
- unsigned int newW = 0, newH = 0, newBW = 0;
-
- if (winRec) {
- oldBW = winRec->borderWidth;
- oldX = winRec->x;
- oldY = winRec->y;
- oldW = winRec->width;
- oldH = winRec->height;
-
- newBW = width;
- newX = pWin->drawable.x - newBW;
- newY = pWin->drawable.y - newBW;
- newW = pWin->drawable.width + 2*newBW;
- newH = pWin->drawable.height + 2*newBW;
-
- resize_after = StartFrameResize(pWin, FALSE,
- oldX, oldY, oldW, oldH, oldBW,
- newX, newY, newW, newH, newBW);
- }
-
- HUGE_ROOT(pWin);
- SCREEN_UNWRAP(pWin->drawable.pScreen, ChangeBorderWidth);
- pWin->drawable.pScreen->ChangeBorderWidth(pWin, width);
- SCREEN_WRAP(pWin->drawable.pScreen, ChangeBorderWidth);
- NORMAL_ROOT(pWin);
-
- if (winRec) {
- FinishFrameResize(pWin, FALSE, oldX, oldY, oldW, oldH, oldBW,
- newX, newY, newW, newH, newBW, resize_after);
- }
- }
-
- RL_DEBUG_MSG("change border width end\n");
-}
-
-/*
- * RootlessOrderAllWindows
- * Brings all X11 windows to the top of the window stack
- * (i.e in front of Aqua windows) -- called when X11.app is given focus
- */
-void
-RootlessOrderAllWindows (Bool include_unhitable)
-{
- int i;
- WindowPtr pWin;
-
- if (windows_hidden)
- return;
-
- RL_DEBUG_MSG("RootlessOrderAllWindows() ");
- for (i = 0; i < screenInfo.numScreens; i++) {
- if (screenInfo.screens[i] == NULL) continue;
- pWin = screenInfo.screens[i]->root;
- if (pWin == NULL) continue;
-
- for (pWin = pWin->firstChild; pWin != NULL; pWin = pWin->nextSib) {
- if (!pWin->realized) continue;
- if (RootlessEnsureFrame(pWin) == NULL) continue;
- if (!include_unhitable && pWin->rootlessUnhittable) continue;
- RootlessReorderWindow (pWin);
- }
- }
- RL_DEBUG_MSG("RootlessOrderAllWindows() done");
-}
-
-void
-RootlessEnableRoot (ScreenPtr pScreen)
-{
- WindowPtr pRoot;
- pRoot = pScreen->root;
-
- RootlessEnsureFrame (pRoot);
- (*pScreen->ClearToBackground) (pRoot, 0, 0, 0, 0, TRUE);
- RootlessReorderWindow (pRoot);
-}
-
-void
-RootlessDisableRoot (ScreenPtr pScreen)
-{
- WindowPtr pRoot;
- RootlessWindowRec *winRec;
-
- pRoot = pScreen->root;
- winRec = WINREC (pRoot);
-
- if (NULL == winRec)
- return;
-
- RootlessDestroyFrame (pRoot, winRec);
- DeleteProperty (serverClient, pRoot, xa_native_window_id ());
-}
-
-void
-RootlessHideAllWindows (void)
-{
- int i;
- ScreenPtr pScreen;
- WindowPtr pWin;
- RootlessWindowRec *winRec;
-
- if (windows_hidden)
- return;
-
- windows_hidden = TRUE;
-
- for (i = 0; i < screenInfo.numScreens; i++)
- {
- pScreen = screenInfo.screens[i];
- if (pScreen == NULL)
- continue;
- pWin = pScreen->root;
- if (pWin == NULL)
- continue;
-
- for (pWin = pWin->firstChild; pWin != NULL; pWin = pWin->nextSib)
- {
- if (!pWin->realized)
- continue;
-
- RootlessStopDrawing (pWin, FALSE);
-
- winRec = WINREC (pWin);
- if (winRec != NULL)
- {
- if (SCREENREC(pScreen)->imp->HideWindow)
- SCREENREC(pScreen)->imp->HideWindow(winRec->wid);
- }
- }
- }
-}
-
-void
-RootlessShowAllWindows (void)
-{
- int i;
- ScreenPtr pScreen;
- WindowPtr pWin;
- RootlessWindowRec *winRec;
-
- if (!windows_hidden)
- return;
-
- windows_hidden = FALSE;
-
- for (i = 0; i < screenInfo.numScreens; i++)
- {
- pScreen = screenInfo.screens[i];
- if (pScreen == NULL)
- continue;
- pWin = pScreen->root;
- if (pWin == NULL)
- continue;
-
- for (pWin = pWin->firstChild; pWin != NULL; pWin = pWin->nextSib)
- {
- if (!pWin->realized)
- continue;
-
- winRec = RootlessEnsureFrame (pWin);
- if (winRec == NULL)
- continue;
-
- RootlessReorderWindow (pWin);
- }
-
- RootlessScreenExpose (pScreen);
- }
-}
-
-/*
- * SetPixmapOfAncestors
- * Set the Pixmaps on all ParentRelative windows up the ancestor chain.
- */
-void
-RootlessSetPixmapOfAncestors(WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- WindowPtr topWin = TopLevelParent(pWin);
- RootlessWindowRec *topWinRec = WINREC(topWin);
-
- while (pWin->backgroundState == ParentRelative) {
- if (pWin == topWin) {
- // disallow ParentRelative background state on top level
- XID pixel = 0;
- ChangeWindowAttributes(pWin, CWBackPixel, &pixel, serverClient);
- RL_DEBUG_MSG("Cleared ParentRelative on 0x%x.\n", pWin);
- break;
- }
-
- pWin = pWin->parent;
- pScreen->SetWindowPixmap(pWin, topWinRec->pixmap);
- }
-}
-
+/* + * Rootless window management + */ +/* + * Copyright (c) 2001 Greg Parker. All Rights Reserved. + * Copyright (c) 2002-2004 Torrey T. Lyons. All Rights Reserved. + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name(s) of the above copyright + * holders shall not be used in advertising or otherwise to promote the sale, + * use or other dealings in this Software without prior written authorization. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stddef.h> /* For NULL */ +#include <limits.h> /* For CHAR_BIT */ +#include <assert.h> +#include <X11/Xatom.h> +#ifdef __APPLE__ +#include <Xplugin.h> +#include "mi.h" +#include "pixmapstr.h" +#include "windowstr.h" +//#include <X11/extensions/applewm.h> +extern int darwinMainScreenX, darwinMainScreenY; +extern Bool no_configure_window; +#endif +#include "fb.h" + +#include "rootlessCommon.h" +#include "rootlessWindow.h" + +#define SCREEN_TO_GLOBAL_X \ + (pScreen->x + rootlessGlobalOffsetX) +#define SCREEN_TO_GLOBAL_Y \ + (pScreen->y + rootlessGlobalOffsetY) + +#define DEFINE_ATOM_HELPER(func,atom_name) \ + static Atom func (void) { \ + static unsigned int generation = 0; \ + static Atom atom; \ + if (generation != serverGeneration) { \ + generation = serverGeneration; \ + atom = MakeAtom (atom_name, strlen (atom_name), TRUE); \ + } \ + return atom; \ + } + +DEFINE_ATOM_HELPER(xa_native_window_id, "_NATIVE_WINDOW_ID") + +static Bool windows_hidden; + +// TODO - abstract xp functions + +#ifdef __APPLE__ + +// XXX: identical to x_cvt_vptr_to_uint ? +#define MAKE_WINDOW_ID(x) ((xp_window_id)((size_t)(x))) + +void +RootlessNativeWindowStateChanged(WindowPtr pWin, unsigned int state) +{ + RootlessWindowRec *winRec; + + if (pWin == NULL) + return; + + winRec = WINREC(pWin); + if (winRec == NULL) + return; + + winRec->is_offscreen = ((state & XP_WINDOW_STATE_OFFSCREEN) != 0); + winRec->is_obscured = ((state & XP_WINDOW_STATE_OBSCURED) != 0); + pWin->rootlessUnhittable = winRec->is_offscreen; +} + +void +RootlessNativeWindowMoved(WindowPtr pWin) +{ + xp_box bounds; + int sx, sy, err; + XID vlist[2]; + Mask mask; + ClientPtr pClient; + RootlessWindowRec *winRec; + + winRec = WINREC(pWin); + + if (xp_get_window_bounds(MAKE_WINDOW_ID(winRec->wid), &bounds) != Success) + return; + + sx = pWin->drawable.pScreen->x + darwinMainScreenX; + sy = pWin->drawable.pScreen->y + darwinMainScreenY; + + /* Fake up a ConfigureWindow packet to resize the window to the current bounds. */ + vlist[0] = (INT16) bounds.x1 - sx; + vlist[1] = (INT16) bounds.y1 - sy; + mask = CWX | CWY; + + /* pretend we're the owner of the window! */ + err = + dixLookupClient(&pClient, pWin->drawable.id, serverClient, + DixUnknownAccess); + if (err != Success) { + ErrorF("RootlessNativeWindowMoved(): Failed to lookup window: 0x%x\n", + (unsigned int) pWin->drawable.id); + return; + } + + /* Don't want to do anything to the physical window (avoids + notification-response feedback loops) */ + + no_configure_window = TRUE; + ConfigureWindow(pWin, mask, vlist, pClient); + no_configure_window = FALSE; +} + +#endif /* __APPLE__ */ + +/* + * RootlessCreateWindow + * For now, don't create a physical window until either the window is + * realized, or we really need it (e.g. to attach VRAM surfaces to). + * Do reset the window size so it's not clipped by the root window. + */ +Bool +RootlessCreateWindow(WindowPtr pWin) +{ + Bool result; + RegionRec saveRoot; + + SETWINREC(pWin, NULL); + dixSetPrivate(&pWin->devPrivates, rootlessWindowOldPixmapPrivateKey, NULL); + + SCREEN_UNWRAP(pWin->drawable.pScreen, CreateWindow); + + if (!IsRoot(pWin)) { + /* win/border size set by DIX, not by wrapped CreateWindow, so + correct it here. Don't HUGE_ROOT when pWin is the root! */ + + HUGE_ROOT(pWin); + SetWinSize(pWin); + SetBorderSize(pWin); + } + + result = pWin->drawable.pScreen->CreateWindow(pWin); + + if (pWin->parent) { + NORMAL_ROOT(pWin); + } + + SCREEN_WRAP(pWin->drawable.pScreen, CreateWindow); + + return result; +} + +/* + * RootlessDestroyFrame + * Destroy the physical window associated with the given window. + */ +static void +RootlessDestroyFrame(WindowPtr pWin, RootlessWindowPtr winRec) +{ + SCREENREC(pWin->drawable.pScreen)->imp->DestroyFrame(winRec->wid); + free(winRec); + SETWINREC(pWin, NULL); +} + +/* + * RootlessDestroyWindow + * Destroy the physical window associated with the given window. + */ +Bool +RootlessDestroyWindow(WindowPtr pWin) +{ + RootlessWindowRec *winRec = WINREC(pWin); + Bool result; + + if (winRec != NULL) { + RootlessDestroyFrame(pWin, winRec); + } + + SCREEN_UNWRAP(pWin->drawable.pScreen, DestroyWindow); + result = pWin->drawable.pScreen->DestroyWindow(pWin); + SCREEN_WRAP(pWin->drawable.pScreen, DestroyWindow); + + return result; +} + +static Bool +RootlessGetShape(WindowPtr pWin, RegionPtr pShape) +{ + if (wBoundingShape(pWin) == NULL) + return FALSE; + + /* wBoundingShape is relative to *inner* origin of window. + Translate by borderWidth to get the outside-relative position. */ + + RegionNull(pShape); + RegionCopy(pShape, wBoundingShape(pWin)); + RegionTranslate(pShape, pWin->borderWidth, pWin->borderWidth); + + return TRUE; +} + +/* + * RootlessReshapeFrame + * Set the frame shape. + */ +static void +RootlessReshapeFrame(WindowPtr pWin) +{ + RootlessWindowRec *winRec = WINREC(pWin); + RegionRec newShape; + RegionPtr pShape; + + // If the window is not yet framed, do nothing + if (winRec == NULL) + return; + + if (IsRoot(pWin)) + return; + + RootlessStopDrawing(pWin, FALSE); + + pShape = RootlessGetShape(pWin, &newShape) ? &newShape : NULL; + +#ifdef ROOTLESSDEBUG + RL_DEBUG_MSG("reshaping..."); + if (pShape != NULL) { + RL_DEBUG_MSG("numrects %d, extents %d %d %d %d ", + RegionNumRects(&newShape), + newShape.extents.x1, newShape.extents.y1, + newShape.extents.x2, newShape.extents.y2); + } + else { + RL_DEBUG_MSG("no shape "); + } +#endif + + SCREENREC(pWin->drawable.pScreen)->imp->ReshapeFrame(winRec->wid, pShape); + + if (pShape != NULL) + RegionUninit(&newShape); +} + +/* + * RootlessSetShape + * Shape is usually set before a window is mapped and the window will + * not have a frame associated with it. In this case, the frame will be + * shaped when the window is framed. + */ +void +RootlessSetShape(WindowPtr pWin, int kind) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + + SCREEN_UNWRAP(pScreen, SetShape); + pScreen->SetShape(pWin, kind); + SCREEN_WRAP(pScreen, SetShape); + + RootlessReshapeFrame(pWin); +} + +/* Disallow ParentRelative background on top-level windows + because the root window doesn't really have the right background. + */ +Bool +RootlessChangeWindowAttributes(WindowPtr pWin, unsigned long vmask) +{ + Bool result; + ScreenPtr pScreen = pWin->drawable.pScreen; + + RL_DEBUG_MSG("change window attributes start "); + + SCREEN_UNWRAP(pScreen, ChangeWindowAttributes); + result = pScreen->ChangeWindowAttributes(pWin, vmask); + SCREEN_WRAP(pScreen, ChangeWindowAttributes); + + if (WINREC(pWin)) { + // disallow ParentRelative background state + if (pWin->backgroundState == ParentRelative) { + XID pixel = 0; + + ChangeWindowAttributes(pWin, CWBackPixel, &pixel, serverClient); + } + } + + RL_DEBUG_MSG("change window attributes end\n"); + return result; +} + +/* + * RootlessPositionWindow + * This is a hook for when DIX moves or resizes a window. + * Update the frame position now although the physical window is moved + * in RootlessMoveWindow. (x, y) are *inside* position. After this, + * mi and fb are expecting the pixmap to be at the new location. + */ +Bool +RootlessPositionWindow(WindowPtr pWin, int x, int y) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + RootlessWindowRec *winRec = WINREC(pWin); + Bool result; + + RL_DEBUG_MSG("positionwindow start (win 0x%x @ %i, %i)\n", pWin, x, y); + + if (winRec) { + if (winRec->is_drawing) { + // Reset frame's pixmap and move it to the new position. + int bw = wBorderWidth(pWin); + + winRec->pixmap->devPrivate.ptr = winRec->pixelData; + SetPixmapBaseToScreen(winRec->pixmap, x - bw, y - bw); + } + } + + SCREEN_UNWRAP(pScreen, PositionWindow); + result = pScreen->PositionWindow(pWin, x, y); + SCREEN_WRAP(pScreen, PositionWindow); + + RL_DEBUG_MSG("positionwindow end\n"); + return result; +} + +/* + * RootlessInitializeFrame + * Initialize some basic attributes of the frame. Note that winRec + * may already have valid data in it, so don't overwrite anything + * valuable. + */ +static void +RootlessInitializeFrame(WindowPtr pWin, RootlessWindowRec * winRec) +{ + DrawablePtr d = &pWin->drawable; + int bw = wBorderWidth(pWin); + + winRec->win = pWin; + + winRec->x = d->x - bw; + winRec->y = d->y - bw; + winRec->width = d->width + 2 * bw; + winRec->height = d->height + 2 * bw; + winRec->borderWidth = bw; +} + +/* + * RootlessEnsureFrame + * Make sure the given window is framed. If the window doesn't have a + * physical window associated with it, attempt to create one. If that + * is unsuccessful, return NULL. + */ +static RootlessWindowRec * +RootlessEnsureFrame(WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + RootlessWindowRec *winRec; + RegionRec shape; + RegionPtr pShape = NULL; + + if (WINREC(pWin) != NULL) + return WINREC(pWin); + + if (!IsTopLevel(pWin) && !IsRoot(pWin)) + return NULL; + + if (pWin->drawable.class != InputOutput) + return NULL; + + winRec = malloc(sizeof(RootlessWindowRec)); + + if (!winRec) + return NULL; + + RootlessInitializeFrame(pWin, winRec); + + winRec->is_drawing = FALSE; + winRec->is_reorder_pending = FALSE; + winRec->pixmap = NULL; + winRec->wid = NULL; + winRec->level = 0; + + SETWINREC(pWin, winRec); + + // Set the frame's shape if the window is shaped + if (RootlessGetShape(pWin, &shape)) + pShape = &shape; + + RL_DEBUG_MSG("creating frame "); + + if (!SCREENREC(pScreen)->imp->CreateFrame(winRec, pScreen, + winRec->x + SCREEN_TO_GLOBAL_X, + winRec->y + SCREEN_TO_GLOBAL_Y, + pShape)) { + RL_DEBUG_MSG("implementation failed to create frame!\n"); + free(winRec); + SETWINREC(pWin, NULL); + return NULL; + } + + if (pWin->drawable.depth == 8) + RootlessFlushWindowColormap(pWin); + + if (pShape != NULL) + RegionUninit(&shape); + + return winRec; +} + +/* + * RootlessRealizeWindow + * The frame is usually created here and not in CreateWindow so that + * windows do not eat memory until they are realized. + */ +Bool +RootlessRealizeWindow(WindowPtr pWin) +{ + Bool result; + RegionRec saveRoot; + ScreenPtr pScreen = pWin->drawable.pScreen; + + RL_DEBUG_MSG("realizewindow start (win 0x%x) ", pWin); + + if ((IsTopLevel(pWin) && pWin->drawable.class == InputOutput)) { + RootlessWindowRec *winRec; + + winRec = RootlessEnsureFrame(pWin); + if (winRec == NULL) + return FALSE; + + winRec->is_reorder_pending = TRUE; + + RL_DEBUG_MSG("Top level window "); + + // Disallow ParentRelative background state on top-level windows. + // This might have been set before the window was mapped. + if (pWin->backgroundState == ParentRelative) { + XID pixel = 0; + + ChangeWindowAttributes(pWin, CWBackPixel, &pixel, serverClient); + } + } + + if (!IsRoot(pWin)) + HUGE_ROOT(pWin); + SCREEN_UNWRAP(pScreen, RealizeWindow); + result = pScreen->RealizeWindow(pWin); + SCREEN_WRAP(pScreen, RealizeWindow); + if (!IsRoot(pWin)) + NORMAL_ROOT(pWin); + + RL_DEBUG_MSG("realizewindow end\n"); + return result; +} + +/* + * RootlessFrameForWindow + * Returns the frame ID for the physical window displaying the given window. + * If CREATE is true and the window has no frame, attempt to create one. + */ +RootlessFrameID +RootlessFrameForWindow(WindowPtr pWin, Bool create) +{ + WindowPtr pTopWin; + RootlessWindowRec *winRec; + + pTopWin = TopLevelParent(pWin); + if (pTopWin == NULL) + return NULL; + + winRec = WINREC(pTopWin); + + if (winRec == NULL && create && pWin->drawable.class == InputOutput) { + winRec = RootlessEnsureFrame(pTopWin); + } + + if (winRec == NULL) + return NULL; + + return winRec->wid; +} + +/* + * RootlessUnrealizeWindow + * Unmap the physical window. + */ +Bool +RootlessUnrealizeWindow(WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + RootlessWindowRec *winRec = WINREC(pWin); + Bool result; + + RL_DEBUG_MSG("unrealizewindow start "); + + if (winRec) { + RootlessStopDrawing(pWin, FALSE); + + SCREENREC(pScreen)->imp->UnmapFrame(winRec->wid); + + winRec->is_reorder_pending = FALSE; + } + + SCREEN_UNWRAP(pScreen, UnrealizeWindow); + result = pScreen->UnrealizeWindow(pWin); + SCREEN_WRAP(pScreen, UnrealizeWindow); + + RL_DEBUG_MSG("unrealizewindow end\n"); + return result; +} + +/* + * RootlessReorderWindow + * Reorder the frame associated with the given window so that it's + * physically above the window below it in the X stacking order. + */ +void +RootlessReorderWindow(WindowPtr pWin) +{ + RootlessWindowRec *winRec = WINREC(pWin); + + if (pWin->realized && winRec != NULL && !winRec->is_reorder_pending && + !windows_hidden) { + WindowPtr newPrevW; + RootlessWindowRec *newPrev; + RootlessFrameID newPrevID; + ScreenPtr pScreen = pWin->drawable.pScreen; + + /* Check if the implementation wants the frame to not be reordered + even though the X11 window is restacked. This can be useful if + frames are ordered-in with animation so that the reordering is not + done until the animation is complete. */ + if (SCREENREC(pScreen)->imp->DoReorderWindow) { + if (!SCREENREC(pScreen)->imp->DoReorderWindow(winRec)) + return; + } + + RootlessStopDrawing(pWin, FALSE); + + /* Find the next window above this one that has a mapped frame. + * Only include cases where the windows are in the same category of + * hittability to ensure offscreen windows dont get restacked + * relative to onscreen ones (but that the offscreen ones maintain + * their stacking order if they are explicitly asked to Reorder + */ + + newPrevW = pWin->prevSib; + while (newPrevW && + (WINREC(newPrevW) == NULL || !newPrevW->realized || + newPrevW->rootlessUnhittable != pWin->rootlessUnhittable)) + newPrevW = newPrevW->prevSib; + + newPrev = newPrevW != NULL ? WINREC(newPrevW) : NULL; + newPrevID = newPrev != NULL ? newPrev->wid : 0; + + /* If it exists, reorder the frame above us first. */ + + if (newPrev && newPrev->is_reorder_pending) { + newPrev->is_reorder_pending = FALSE; + RootlessReorderWindow(newPrevW); + } + + SCREENREC(pScreen)->imp->RestackFrame(winRec->wid, newPrevID); + } +} + +/* + * RootlessRestackWindow + * This is a hook for when DIX changes the window stacking order. + * The window has already been inserted into its new position in the + * DIX window stack. We need to change the order of the physical + * window to match. + */ +void +RootlessRestackWindow(WindowPtr pWin, WindowPtr pOldNextSib) +{ + RegionRec saveRoot; + RootlessWindowRec *winRec = WINREC(pWin); + ScreenPtr pScreen = pWin->drawable.pScreen; + + RL_DEBUG_MSG("restackwindow start "); + if (winRec) + RL_DEBUG_MSG("restack top level \n"); + + HUGE_ROOT(pWin); + SCREEN_UNWRAP(pScreen, RestackWindow); + + if (pScreen->RestackWindow) + pScreen->RestackWindow(pWin, pOldNextSib); + + SCREEN_WRAP(pScreen, RestackWindow); + NORMAL_ROOT(pWin); + + if (winRec && pWin->viewable) { + RootlessReorderWindow(pWin); + } + + RL_DEBUG_MSG("restackwindow end\n"); +} + +/* + * Specialized window copy procedures + */ + +// Globals needed during window resize and move. +static pointer gResizeDeathBits = NULL; +static int gResizeDeathCount = 0; +static PixmapPtr gResizeDeathPix[2] = { NULL, NULL }; + +static BoxRec gResizeDeathBounds[2]; +static CopyWindowProcPtr gResizeOldCopyWindowProc = NULL; + +/* + * RootlessNoCopyWindow + * CopyWindow() that doesn't do anything. For MoveWindow() of + * top-level windows. + */ +static void +RootlessNoCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) +{ + // some code expects the region to be translated + int dx = ptOldOrg.x - pWin->drawable.x; + int dy = ptOldOrg.y - pWin->drawable.y; + + RL_DEBUG_MSG("ROOTLESSNOCOPYWINDOW "); + + RegionTranslate(prgnSrc, -dx, -dy); +} + +/* + * RootlessResizeCopyWindow + * CopyWindow used during ResizeWindow for gravity moves. Based on + * fbCopyWindow. The original always draws on the root pixmap, which + * we don't have. Instead, draw on the parent window's pixmap. + * Resize version: the old location's pixels are in gResizeCopyWindowSource. + */ +static void +RootlessResizeCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, + RegionPtr prgnSrc) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + RegionRec rgnDst; + int dx, dy; + + RL_DEBUG_MSG("resizecopywindowFB start (win 0x%x) ", pWin); + + /* Don't unwrap pScreen->CopyWindow. + The bogus rewrap with RootlessCopyWindow causes a crash if + CopyWindow is called again during the same resize. */ + + if (gResizeDeathCount == 0) + return; + + RootlessStartDrawing(pWin); + + dx = ptOldOrg.x - pWin->drawable.x; + dy = ptOldOrg.y - pWin->drawable.y; + RegionTranslate(prgnSrc, -dx, -dy); + RegionNull(&rgnDst); + RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc); + + if (gResizeDeathCount == 1) { + /* Simple case, we only have a single source pixmap. */ + + fbCopyRegion(&gResizeDeathPix[0]->drawable, + &pScreen->GetWindowPixmap(pWin)->drawable, 0, + &rgnDst, dx, dy, fbCopyWindowProc, 0, 0); + } + else { + int i; + RegionRec clip, clipped; + + /* More complex case, N source pixmaps (usually two). So we + intersect the destination with each source and copy those bits. */ + + for (i = 0; i < gResizeDeathCount; i++) { + RegionInit(&clip, gResizeDeathBounds + 0, 1); + RegionNull(&clipped); + RegionIntersect(&rgnDst, &clip, &clipped); + + fbCopyRegion(&gResizeDeathPix[i]->drawable, + &pScreen->GetWindowPixmap(pWin)->drawable, 0, + &clipped, dx, dy, fbCopyWindowProc, 0, 0); + + RegionUninit(&clipped); + RegionUninit(&clip); + } + } + + /* Don't update - resize will update everything */ + RegionUninit(&rgnDst); + + fbValidateDrawable(&pWin->drawable); + + RL_DEBUG_MSG("resizecopywindowFB end\n"); +} + +/* + * RootlessCopyWindow + * Update *new* location of window. Old location is redrawn with + * miPaintWindow. Cloned from fbCopyWindow. + * The original always draws on the root pixmap, which we don't have. + * Instead, draw on the parent window's pixmap. + */ +void +RootlessCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + RegionRec rgnDst; + int dx, dy; + BoxPtr extents; + int area; + + RL_DEBUG_MSG("copywindowFB start (win 0x%x) ", pWin); + + SCREEN_UNWRAP(pScreen, CopyWindow); + + dx = ptOldOrg.x - pWin->drawable.x; + dy = ptOldOrg.y - pWin->drawable.y; + RegionTranslate(prgnSrc, -dx, -dy); + + RegionNull(&rgnDst); + RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc); + + extents = RegionExtents(&rgnDst); + area = (extents->x2 - extents->x1) * (extents->y2 - extents->y1); + + /* If the area exceeds threshold, use the implementation's + accelerated version. */ + if (area > rootless_CopyWindow_threshold && + SCREENREC(pScreen)->imp->CopyWindow) { + RootlessWindowRec *winRec; + WindowPtr top; + + top = TopLevelParent(pWin); + if (top == NULL) { + RL_DEBUG_MSG("no parent\n"); + goto out; + } + + winRec = WINREC(top); + if (winRec == NULL) { + RL_DEBUG_MSG("not framed\n"); + goto out; + } + + /* Move region to window local coords */ + RegionTranslate(&rgnDst, -winRec->x, -winRec->y); + + RootlessStopDrawing(pWin, FALSE); + + SCREENREC(pScreen)->imp->CopyWindow(winRec->wid, + RegionNumRects(&rgnDst), + RegionRects(&rgnDst), dx, dy); + } + else { + RootlessStartDrawing(pWin); + + fbCopyRegion((DrawablePtr) pWin, (DrawablePtr) pWin, + 0, &rgnDst, dx, dy, fbCopyWindowProc, 0, 0); + + /* prgnSrc has been translated to dst position */ + RootlessDamageRegion(pWin, prgnSrc); + } + + out: + RegionUninit(&rgnDst); + fbValidateDrawable(&pWin->drawable); + + SCREEN_WRAP(pScreen, CopyWindow); + + RL_DEBUG_MSG("copywindowFB end\n"); +} + +/* + * Window resize procedures + */ + +enum { + WIDTH_SMALLER = 1, + HEIGHT_SMALLER = 2, +}; + +/* + * ResizeWeighting + * Choose gravity to avoid local copies. Do that by looking for + * a corner that doesn't move _relative to the screen_. + */ +static inline unsigned int +ResizeWeighting(int oldX1, int oldY1, int oldX2, int oldY2, int oldBW, + int newX1, int newY1, int newX2, int newY2, int newBW) +{ +#ifdef ROOTLESS_RESIZE_GRAVITY + if (newBW != oldBW) + return RL_GRAVITY_NONE; + + if (newX1 == oldX1 && newY1 == oldY1) + return RL_GRAVITY_NORTH_WEST; + else if (newX1 == oldX1 && newY2 == oldY2) + return RL_GRAVITY_SOUTH_WEST; + else if (newX2 == oldX2 && newY2 == oldY2) + return RL_GRAVITY_SOUTH_EAST; + else if (newX2 == oldX2 && newY1 == oldY1) + return RL_GRAVITY_NORTH_EAST; + else + return RL_GRAVITY_NONE; +#else + return RL_GRAVITY_NONE; +#endif +} + +/* + * StartFrameResize + * Prepare to resize a top-level window. The old window's pixels are + * saved and the implementation is told to change the window size. + * (x,y,w,h) is outer frame of window (outside border) + */ +static Bool +StartFrameResize(WindowPtr pWin, Bool gravity, + int oldX, int oldY, int oldW, int oldH, int oldBW, + int newX, int newY, int newW, int newH, int newBW) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + RootlessWindowRec *winRec = WINREC(pWin); + Bool need_window_source = FALSE, resize_after = FALSE; + + BoxRec rect; + int oldX2, newX2; + int oldY2, newY2; + unsigned int weight; + + oldX2 = oldX + oldW, newX2 = newX + newW; + oldY2 = oldY + oldH, newY2 = newY + newH; + + /* Decide which resize weighting to use */ + weight = ResizeWeighting(oldX, oldY, oldW, oldH, oldBW, + newX, newY, newW, newH, newBW); + + /* Compute intersection between old and new rects */ + rect.x1 = max(oldX, newX); + rect.y1 = max(oldY, newY); + rect.x2 = min(oldX2, newX2); + rect.y2 = min(oldY2, newY2); + + RL_DEBUG_MSG("RESIZE TOPLEVEL WINDOW with gravity %i ", gravity); + RL_DEBUG_MSG("%d %d %d %d %d %d %d %d %d %d\n", + oldX, oldY, oldW, oldH, oldBW, newX, newY, newW, newH, newBW); + + RootlessRedisplay(pWin); + + /* If gravity is true, then we need to have a way of recovering all + the original bits in the window for when X rearranges the contents + based on the various gravity settings. The obvious way is to just + snapshot the entire backing store before resizing it, but that + it slow on large windows. + + So the optimization here is to use the implementation's resize + weighting options (if available) to allow us to reason about what + is left in the backing store after the resize. We can then only + copy what won't be there after the resize, and do a two-stage copy + operation. + + Most of these optimizations are only applied when the top-left + corner of the window is fixed, since that's the common case. They + could probably be extended with some thought. */ + + gResizeDeathCount = 0; + + if (gravity && weight == RL_GRAVITY_NORTH_WEST) { + unsigned int code = 0; + + /* Top left corner is anchored. We never need to copy the + entire window. */ + + need_window_source = TRUE; + + /* These comparisons were chosen to avoid setting bits when the sizes + are the same. (So the fastest case automatically gets taken when + dimensions are unchanging.) */ + + if (newW < oldW) + code |= WIDTH_SMALLER; + if (newH < oldH) + code |= HEIGHT_SMALLER; + + if (((code ^ (code >> 1)) & 1) == 0) { + /* Both dimensions are either getting larger, or both + are getting smaller. No need to copy anything. */ + + if (code == (WIDTH_SMALLER | HEIGHT_SMALLER)) { + /* Since the window is getting smaller, we can do gravity + repair on it with it's current size, then resize it + afterwards. */ + + resize_after = TRUE; + } + + gResizeDeathCount = 1; + } + else { + unsigned int copy_rowbytes, Bpp; + unsigned int copy_rect_width, copy_rect_height; + BoxRec copy_rect; + + /* We can get away with a partial copy. 'rect' is the + intersection between old and new bounds, so copy + everything to the right of or below the intersection. */ + + RootlessStartDrawing(pWin); + + if (code == WIDTH_SMALLER) { + copy_rect.x1 = rect.x2; + copy_rect.y1 = rect.y1; + copy_rect.x2 = oldX2; + copy_rect.y2 = oldY2; + } + else if (code == HEIGHT_SMALLER) { + copy_rect.x1 = rect.x1; + copy_rect.y1 = rect.y2; + copy_rect.x2 = oldX2; + copy_rect.y2 = oldY2; + } + else + OsAbort(); + + Bpp = winRec->win->drawable.bitsPerPixel / 8; + copy_rect_width = copy_rect.x2 - copy_rect.x1; + copy_rect_height = copy_rect.y2 - copy_rect.y1; + copy_rowbytes = ((copy_rect_width * Bpp) + 31) & ~31; + gResizeDeathBits = malloc(copy_rowbytes * copy_rect_height); + + if (copy_rect_width * copy_rect_height > + rootless_CopyBytes_threshold && + SCREENREC(pScreen)->imp->CopyBytes) { + SCREENREC(pScreen)->imp->CopyBytes(copy_rect_width * Bpp, + copy_rect_height, + ((char *) winRec->pixelData) + + + ((copy_rect.y1 - + oldY) * + winRec->bytesPerRow) + + (copy_rect.x1 - + oldX) * Bpp, + winRec->bytesPerRow, + gResizeDeathBits, + copy_rowbytes); + } + else { + fbBlt((FbBits *) (winRec->pixelData + + + ((copy_rect.y1 - oldY) * winRec->bytesPerRow) + + (copy_rect.x1 - oldX) * Bpp), + winRec->bytesPerRow / sizeof(FbBits), 0, + (FbBits *) gResizeDeathBits, + copy_rowbytes / sizeof(FbBits), 0, copy_rect_width * Bpp, + copy_rect_height, GXcopy, FB_ALLONES, Bpp, 0, 0); + } + + gResizeDeathBounds[1] = copy_rect; + gResizeDeathPix[1] + = GetScratchPixmapHeader(pScreen, copy_rect_width, + copy_rect_height, + winRec->win->drawable.depth, + winRec->win->drawable.bitsPerPixel, + winRec->bytesPerRow, + (void *) gResizeDeathBits); + + SetPixmapBaseToScreen(gResizeDeathPix[1], + copy_rect.x1, copy_rect.y1); + + gResizeDeathCount = 2; + } + } + else if (gravity) { + /* The general case. Just copy everything. */ + + RootlessStartDrawing(pWin); + + gResizeDeathBits = malloc(winRec->bytesPerRow * winRec->height); + + memcpy(gResizeDeathBits, winRec->pixelData, + winRec->bytesPerRow * winRec->height); + + gResizeDeathBounds[0] = (BoxRec) { + oldX, oldY, oldX2, oldY2}; + gResizeDeathPix[0] + = GetScratchPixmapHeader(pScreen, winRec->width, + winRec->height, + winRec->win->drawable.depth, + winRec->win->drawable.bitsPerPixel, + winRec->bytesPerRow, + (void *) gResizeDeathBits); + + SetPixmapBaseToScreen(gResizeDeathPix[0], oldX, oldY); + gResizeDeathCount = 1; + } + + RootlessStopDrawing(pWin, FALSE); + + winRec->x = newX; + winRec->y = newY; + winRec->width = newW; + winRec->height = newH; + winRec->borderWidth = newBW; + + /* Unless both dimensions are getting smaller, Resize the frame + before doing gravity repair */ + + if (!resize_after) { + SCREENREC(pScreen)->imp->ResizeFrame(winRec->wid, pScreen, + newX + SCREEN_TO_GLOBAL_X, + newY + SCREEN_TO_GLOBAL_Y, + newW, newH, weight); + } + + RootlessStartDrawing(pWin); + + /* If necessary, create a source pixmap pointing at the current + window bits. */ + + if (need_window_source) { + gResizeDeathBounds[0] = (BoxRec) { + oldX, oldY, oldX2, oldY2}; + gResizeDeathPix[0] + = GetScratchPixmapHeader(pScreen, oldW, oldH, + winRec->win->drawable.depth, + winRec->win->drawable.bitsPerPixel, + winRec->bytesPerRow, winRec->pixelData); + + SetPixmapBaseToScreen(gResizeDeathPix[0], oldX, oldY); + } + + /* Use custom CopyWindow when moving gravity bits around + ResizeWindow assumes the old window contents are in the same + pixmap, but here they're in deathPix instead. */ + + if (gravity) { + gResizeOldCopyWindowProc = pScreen->CopyWindow; + pScreen->CopyWindow = RootlessResizeCopyWindow; + } + + /* If we can't rely on the window server preserving the bits we + need in the position we need, copy the pixels in the + intersection from src to dst. ResizeWindow assumes these pixels + are already present when making gravity adjustments. pWin + currently has new-sized pixmap but is in old position. + + FIXME: border width change! (?) */ + + if (gravity && weight == RL_GRAVITY_NONE) { + PixmapPtr src, dst; + + assert(gResizeDeathCount == 1); + + src = gResizeDeathPix[0]; + dst = pScreen->GetWindowPixmap(pWin); + + RL_DEBUG_MSG("Resize copy rect %d %d %d %d\n", + rect.x1, rect.y1, rect.x2, rect.y2); + + /* rect is the intersection of the old location and new location */ + if (BOX_NOT_EMPTY(rect) && src != NULL && dst != NULL) { + /* The window drawable still has the old frame position, which + means that DST doesn't actually point at the origin of our + physical backing store when adjusted by the drawable.x,y + position. So sneakily adjust it temporarily while copying.. */ + + ((PixmapPtr) dst)->devPrivate.ptr = winRec->pixelData; + SetPixmapBaseToScreen(dst, newX, newY); + + fbCopyWindowProc(&src->drawable, &dst->drawable, NULL, + &rect, 1, 0, 0, FALSE, FALSE, 0, 0); + + ((PixmapPtr) dst)->devPrivate.ptr = winRec->pixelData; + SetPixmapBaseToScreen(dst, oldX, oldY); + } + } + + return resize_after; +} + +static void +FinishFrameResize(WindowPtr pWin, Bool gravity, int oldX, int oldY, + unsigned int oldW, unsigned int oldH, unsigned int oldBW, + int newX, int newY, unsigned int newW, unsigned int newH, + unsigned int newBW, Bool resize_now) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + RootlessWindowRec *winRec = WINREC(pWin); + int i; + + RootlessStopDrawing(pWin, FALSE); + + if (resize_now) { + unsigned int weight; + + /* We didn't resize anything earlier, so do it now, now that + we've finished gravitating the bits. */ + + weight = ResizeWeighting(oldX, oldY, oldW, oldH, oldBW, + newX, newY, newW, newH, newBW); + + SCREENREC(pScreen)->imp->ResizeFrame(winRec->wid, pScreen, + newX + SCREEN_TO_GLOBAL_X, + newY + SCREEN_TO_GLOBAL_Y, + newW, newH, weight); + } + + /* Redraw everything. FIXME: there must be times when we don't need + to do this. Perhaps when top-left weighting and no gravity? */ + + RootlessDamageRect(pWin, -newBW, -newBW, newW, newH); + + for (i = 0; i < 2; i++) { + if (gResizeDeathPix[i] != NULL) { + FreeScratchPixmapHeader(gResizeDeathPix[i]); + gResizeDeathPix[i] = NULL; + } + } + + free(gResizeDeathBits); + gResizeDeathBits = NULL; + + if (gravity) { + pScreen->CopyWindow = gResizeOldCopyWindowProc; + } +} + +/* + * RootlessMoveWindow + * If kind==VTOther, window border is resizing (and borderWidth is + * already changed!!@#$) This case works like window resize, not move. + */ +void +RootlessMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind) +{ + RootlessWindowRec *winRec = WINREC(pWin); + ScreenPtr pScreen = pWin->drawable.pScreen; + CopyWindowProcPtr oldCopyWindowProc = NULL; + int oldX = 0, oldY = 0, newX = 0, newY = 0; + unsigned int oldW = 0, oldH = 0, oldBW = 0; + unsigned int newW = 0, newH = 0, newBW = 0; + Bool resize_after = FALSE; + RegionRec saveRoot; + + RL_DEBUG_MSG("movewindow start \n"); + + if (winRec) { + if (kind == VTMove) { + oldX = winRec->x; + oldY = winRec->y; + RootlessRedisplay(pWin); + RootlessStartDrawing(pWin); + } + else { + RL_DEBUG_MSG("movewindow border resizing "); + + oldBW = winRec->borderWidth; + oldX = winRec->x; + oldY = winRec->y; + oldW = winRec->width; + oldH = winRec->height; + + newBW = wBorderWidth(pWin); + newX = x; + newY = y; + newW = pWin->drawable.width + 2 * newBW; + newH = pWin->drawable.height + 2 * newBW; + + resize_after = StartFrameResize(pWin, FALSE, + oldX, oldY, oldW, oldH, oldBW, + newX, newY, newW, newH, newBW); + } + } + + HUGE_ROOT(pWin); + SCREEN_UNWRAP(pScreen, MoveWindow); + + if (winRec) { + oldCopyWindowProc = pScreen->CopyWindow; + pScreen->CopyWindow = RootlessNoCopyWindow; + } + pScreen->MoveWindow(pWin, x, y, pSib, kind); + if (winRec) { + pScreen->CopyWindow = oldCopyWindowProc; + } + + NORMAL_ROOT(pWin); + SCREEN_WRAP(pScreen, MoveWindow); + + if (winRec) { + if (kind == VTMove) { + winRec->x = x; + winRec->y = y; + RootlessStopDrawing(pWin, FALSE); + SCREENREC(pScreen)->imp->MoveFrame(winRec->wid, pScreen, + x + SCREEN_TO_GLOBAL_X, + y + SCREEN_TO_GLOBAL_Y); + } + else { + FinishFrameResize(pWin, FALSE, oldX, oldY, oldW, oldH, oldBW, + newX, newY, newW, newH, newBW, resize_after); + } + } + + RL_DEBUG_MSG("movewindow end\n"); +} + +/* + * RootlessResizeWindow + * Note: (x, y, w, h) as passed to this procedure don't match the frame + * definition. (x,y) is corner of very outer edge, *outside* border. + * w,h is width and height *inside* border, *ignoring* border width. + * The rect (x, y, w, h) doesn't mean anything. (x, y, w+2*bw, h+2*bw) + * is total rect and (x+bw, y+bw, w, h) is inner rect. + */ +void +RootlessResizeWindow(WindowPtr pWin, int x, int y, + unsigned int w, unsigned int h, WindowPtr pSib) +{ + RootlessWindowRec *winRec = WINREC(pWin); + ScreenPtr pScreen = pWin->drawable.pScreen; + int oldX = 0, oldY = 0, newX = 0, newY = 0; + unsigned int oldW = 0, oldH = 0, oldBW = 0, newW = 0, newH = 0, newBW = 0; + Bool resize_after = FALSE; + RegionRec saveRoot; + + RL_DEBUG_MSG("resizewindow start (win 0x%x) ", pWin); + + if (pWin->parent) { + if (winRec) { + oldBW = winRec->borderWidth; + oldX = winRec->x; + oldY = winRec->y; + oldW = winRec->width; + oldH = winRec->height; + + newBW = oldBW; + newX = x; + newY = y; + newW = w + 2 * newBW; + newH = h + 2 * newBW; + + resize_after = StartFrameResize(pWin, TRUE, + oldX, oldY, oldW, oldH, oldBW, + newX, newY, newW, newH, newBW); + } + + HUGE_ROOT(pWin); + SCREEN_UNWRAP(pScreen, ResizeWindow); + pScreen->ResizeWindow(pWin, x, y, w, h, pSib); + SCREEN_WRAP(pScreen, ResizeWindow); + NORMAL_ROOT(pWin); + + if (winRec) { + FinishFrameResize(pWin, TRUE, oldX, oldY, oldW, oldH, oldBW, + newX, newY, newW, newH, newBW, resize_after); + } + } + else { + /* Special case for resizing the root window */ + BoxRec box; + + pWin->drawable.x = x; + pWin->drawable.y = y; + pWin->drawable.width = w; + pWin->drawable.height = h; + + box.x1 = x; + box.y1 = y; + box.x2 = x + w; + box.y2 = y + h; + RegionUninit(&pWin->winSize); + RegionInit(&pWin->winSize, &box, 1); + RegionCopy(&pWin->borderSize, &pWin->winSize); + RegionCopy(&pWin->clipList, &pWin->winSize); + RegionCopy(&pWin->borderClip, &pWin->winSize); + + if (winRec) { + SCREENREC(pScreen)->imp->ResizeFrame(winRec->wid, pScreen, + x + SCREEN_TO_GLOBAL_X, + y + SCREEN_TO_GLOBAL_Y, + w, h, RL_GRAVITY_NONE); + } + + miSendExposures(pWin, &pWin->borderClip, + pWin->drawable.x, pWin->drawable.y); + } + + RL_DEBUG_MSG("resizewindow end\n"); +} + +/* + * RootlessRepositionWindow + * Called by the implementation when a window needs to be repositioned to + * its correct location on the screen. This routine is typically needed + * due to changes in the underlying window system, such as a screen layout + * change. + */ +void +RootlessRepositionWindow(WindowPtr pWin) +{ + RootlessWindowRec *winRec = WINREC(pWin); + ScreenPtr pScreen = pWin->drawable.pScreen; + + if (winRec == NULL) + return; + + RootlessStopDrawing(pWin, FALSE); + SCREENREC(pScreen)->imp->MoveFrame(winRec->wid, pScreen, + winRec->x + SCREEN_TO_GLOBAL_X, + winRec->y + SCREEN_TO_GLOBAL_Y); + + RootlessReorderWindow(pWin); +} + +/* + * RootlessReparentWindow + * Called after a window has been reparented. Generally windows are not + * framed until they are mapped. However, a window may be framed early by the + * implementation calling RootlessFrameForWindow. (e.g. this could be needed + * to attach a VRAM surface to it.) If the window is subsequently reparented + * by the window manager before being mapped, we need to give the frame to + * the new top-level window. + */ +void +RootlessReparentWindow(WindowPtr pWin, WindowPtr pPriorParent) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + RootlessWindowRec *winRec = WINREC(pWin); + WindowPtr pTopWin; + + /* Check that window is not top-level now, but used to be. */ + if (IsRoot(pWin) || IsRoot(pWin->parent) + || IsTopLevel(pWin) || winRec == NULL) { + goto out; + } + + /* If the formerly top-level window has a frame, we want to give the + frame to its new top-level parent. If we can't do that, we'll just + have to jettison it... */ + + pTopWin = TopLevelParent(pWin); + assert(pTopWin != pWin); + + pWin->rootlessUnhittable = FALSE; + + DeleteProperty(serverClient, pWin, xa_native_window_id()); + + if (WINREC(pTopWin) != NULL) { + /* We're screwed. */ + RootlessDestroyFrame(pWin, winRec); + } + else { + if (!pTopWin->realized && pWin->realized) { + SCREENREC(pScreen)->imp->UnmapFrame(winRec->wid); + } + + /* Switch the frame record from one to the other. */ + + SETWINREC(pWin, NULL); + SETWINREC(pTopWin, winRec); + + RootlessInitializeFrame(pTopWin, winRec); + RootlessReshapeFrame(pTopWin); + + SCREENREC(pScreen)->imp->ResizeFrame(winRec->wid, pScreen, + winRec->x + SCREEN_TO_GLOBAL_X, + winRec->y + SCREEN_TO_GLOBAL_Y, + winRec->width, winRec->height, + RL_GRAVITY_NONE); + + if (SCREENREC(pScreen)->imp->SwitchWindow) { + SCREENREC(pScreen)->imp->SwitchWindow(winRec, pWin); + } + + if (pTopWin->realized && !pWin->realized) + winRec->is_reorder_pending = TRUE; + } + + out: + if (SCREENREC(pScreen)->ReparentWindow) { + SCREEN_UNWRAP(pScreen, ReparentWindow); + pScreen->ReparentWindow(pWin, pPriorParent); + SCREEN_WRAP(pScreen, ReparentWindow); + } +} + +void +RootlessFlushWindowColormap(WindowPtr pWin) +{ + RootlessWindowRec *winRec = WINREC(pWin); + ScreenPtr pScreen = pWin->drawable.pScreen; + + if (winRec == NULL) + return; + + RootlessStopDrawing(pWin, FALSE); + + if (SCREENREC(pScreen)->imp->UpdateColormap) + SCREENREC(pScreen)->imp->UpdateColormap(winRec->wid, pScreen); +} + +/* + * RootlessChangeBorderWidth + * FIXME: untested! + * pWin inside corner stays the same; pWin->drawable.[xy] stays the same + * Frame moves and resizes. + */ +void +RootlessChangeBorderWidth(WindowPtr pWin, unsigned int width) +{ + RegionRec saveRoot; + Bool resize_after = FALSE; + + RL_DEBUG_MSG("change border width "); + + if (width != wBorderWidth(pWin)) { + RootlessWindowRec *winRec = WINREC(pWin); + int oldX = 0, oldY = 0, newX = 0, newY = 0; + unsigned int oldW = 0, oldH = 0, oldBW = 0; + unsigned int newW = 0, newH = 0, newBW = 0; + + if (winRec) { + oldBW = winRec->borderWidth; + oldX = winRec->x; + oldY = winRec->y; + oldW = winRec->width; + oldH = winRec->height; + + newBW = width; + newX = pWin->drawable.x - newBW; + newY = pWin->drawable.y - newBW; + newW = pWin->drawable.width + 2 * newBW; + newH = pWin->drawable.height + 2 * newBW; + + resize_after = StartFrameResize(pWin, FALSE, + oldX, oldY, oldW, oldH, oldBW, + newX, newY, newW, newH, newBW); + } + + HUGE_ROOT(pWin); + SCREEN_UNWRAP(pWin->drawable.pScreen, ChangeBorderWidth); + pWin->drawable.pScreen->ChangeBorderWidth(pWin, width); + SCREEN_WRAP(pWin->drawable.pScreen, ChangeBorderWidth); + NORMAL_ROOT(pWin); + + if (winRec) { + FinishFrameResize(pWin, FALSE, oldX, oldY, oldW, oldH, oldBW, + newX, newY, newW, newH, newBW, resize_after); + } + } + + RL_DEBUG_MSG("change border width end\n"); +} + +/* + * RootlessOrderAllWindows + * Brings all X11 windows to the top of the window stack + * (i.e in front of Aqua windows) -- called when X11.app is given focus + */ +void +RootlessOrderAllWindows(Bool include_unhitable) +{ + int i; + WindowPtr pWin; + + if (windows_hidden) + return; + + RL_DEBUG_MSG("RootlessOrderAllWindows() "); + for (i = 0; i < screenInfo.numScreens; i++) { + if (screenInfo.screens[i] == NULL) + continue; + pWin = screenInfo.screens[i]->root; + if (pWin == NULL) + continue; + + for (pWin = pWin->firstChild; pWin != NULL; pWin = pWin->nextSib) { + if (!pWin->realized) + continue; + if (RootlessEnsureFrame(pWin) == NULL) + continue; + if (!include_unhitable && pWin->rootlessUnhittable) + continue; + RootlessReorderWindow(pWin); + } + } + RL_DEBUG_MSG("RootlessOrderAllWindows() done"); +} + +void +RootlessEnableRoot(ScreenPtr pScreen) +{ + WindowPtr pRoot; + + pRoot = pScreen->root; + + RootlessEnsureFrame(pRoot); + (*pScreen->ClearToBackground) (pRoot, 0, 0, 0, 0, TRUE); + RootlessReorderWindow(pRoot); +} + +void +RootlessDisableRoot(ScreenPtr pScreen) +{ + WindowPtr pRoot; + RootlessWindowRec *winRec; + + pRoot = pScreen->root; + winRec = WINREC(pRoot); + + if (NULL == winRec) + return; + + RootlessDestroyFrame(pRoot, winRec); + DeleteProperty(serverClient, pRoot, xa_native_window_id()); +} + +void +RootlessHideAllWindows(void) +{ + int i; + ScreenPtr pScreen; + WindowPtr pWin; + RootlessWindowRec *winRec; + + if (windows_hidden) + return; + + windows_hidden = TRUE; + + for (i = 0; i < screenInfo.numScreens; i++) { + pScreen = screenInfo.screens[i]; + if (pScreen == NULL) + continue; + pWin = pScreen->root; + if (pWin == NULL) + continue; + + for (pWin = pWin->firstChild; pWin != NULL; pWin = pWin->nextSib) { + if (!pWin->realized) + continue; + + RootlessStopDrawing(pWin, FALSE); + + winRec = WINREC(pWin); + if (winRec != NULL) { + if (SCREENREC(pScreen)->imp->HideWindow) + SCREENREC(pScreen)->imp->HideWindow(winRec->wid); + } + } + } +} + +void +RootlessShowAllWindows(void) +{ + int i; + ScreenPtr pScreen; + WindowPtr pWin; + RootlessWindowRec *winRec; + + if (!windows_hidden) + return; + + windows_hidden = FALSE; + + for (i = 0; i < screenInfo.numScreens; i++) { + pScreen = screenInfo.screens[i]; + if (pScreen == NULL) + continue; + pWin = pScreen->root; + if (pWin == NULL) + continue; + + for (pWin = pWin->firstChild; pWin != NULL; pWin = pWin->nextSib) { + if (!pWin->realized) + continue; + + winRec = RootlessEnsureFrame(pWin); + if (winRec == NULL) + continue; + + RootlessReorderWindow(pWin); + } + + RootlessScreenExpose(pScreen); + } +} + +/* + * SetPixmapOfAncestors + * Set the Pixmaps on all ParentRelative windows up the ancestor chain. + */ +void +RootlessSetPixmapOfAncestors(WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + WindowPtr topWin = TopLevelParent(pWin); + RootlessWindowRec *topWinRec = WINREC(topWin); + + while (pWin->backgroundState == ParentRelative) { + if (pWin == topWin) { + // disallow ParentRelative background state on top level + XID pixel = 0; + + ChangeWindowAttributes(pWin, CWBackPixel, &pixel, serverClient); + RL_DEBUG_MSG("Cleared ParentRelative on 0x%x.\n", pWin); + break; + } + + pWin = pWin->parent; + pScreen->SetWindowPixmap(pWin, topWinRec->pixmap); + } +} diff --git a/xorg-server/miext/rootless/rootlessWindow.h b/xorg-server/miext/rootless/rootlessWindow.h index 2da96e661..d3955fc89 100644 --- a/xorg-server/miext/rootless/rootlessWindow.h +++ b/xorg-server/miext/rootless/rootlessWindow.h @@ -1,60 +1,63 @@ -/*
- * Rootless window management
- */
-/*
- * Copyright (c) 2001 Greg Parker. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name(s) of the above copyright
- * holders shall not be used in advertising or otherwise to promote the sale,
- * use or other dealings in this Software without prior written authorization.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#ifndef _ROOTLESSWINDOW_H
-#define _ROOTLESSWINDOW_H
-
-#include "rootlessCommon.h"
-
-Bool RootlessCreateWindow(WindowPtr pWin);
-Bool RootlessDestroyWindow(WindowPtr pWin);
-
-void RootlessSetShape(WindowPtr pWin, int kind);
-
-Bool RootlessChangeWindowAttributes(WindowPtr pWin, unsigned long vmask);
-Bool RootlessPositionWindow(WindowPtr pWin, int x, int y);
-Bool RootlessRealizeWindow(WindowPtr pWin);
-Bool RootlessUnrealizeWindow(WindowPtr pWin);
-void RootlessRestackWindow(WindowPtr pWin, WindowPtr pOldNextSib);
-void RootlessCopyWindow(WindowPtr pWin,DDXPointRec ptOldOrg,RegionPtr prgnSrc);
-void RootlessMoveWindow(WindowPtr pWin,int x,int y,WindowPtr pSib,VTKind kind);
-void RootlessResizeWindow(WindowPtr pWin, int x, int y,
- unsigned int w, unsigned int h, WindowPtr pSib);
-void RootlessReparentWindow(WindowPtr pWin, WindowPtr pPriorParent);
-void RootlessChangeBorderWidth(WindowPtr pWin, unsigned int width);
-#ifdef __APPLE__
-void RootlessNativeWindowMoved (WindowPtr pWin);
-void RootlessNativeWindowStateChanged (WindowPtr pWin, unsigned int state);
-#endif
-
-#endif
+/* + * Rootless window management + */ +/* + * Copyright (c) 2001 Greg Parker. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name(s) of the above copyright + * holders shall not be used in advertising or otherwise to promote the sale, + * use or other dealings in this Software without prior written authorization. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef _ROOTLESSWINDOW_H +#define _ROOTLESSWINDOW_H + +#include "rootlessCommon.h" + +Bool RootlessCreateWindow(WindowPtr pWin); +Bool RootlessDestroyWindow(WindowPtr pWin); + +void RootlessSetShape(WindowPtr pWin, int kind); + +Bool RootlessChangeWindowAttributes(WindowPtr pWin, unsigned long vmask); +Bool RootlessPositionWindow(WindowPtr pWin, int x, int y); +Bool RootlessRealizeWindow(WindowPtr pWin); +Bool RootlessUnrealizeWindow(WindowPtr pWin); +void RootlessRestackWindow(WindowPtr pWin, WindowPtr pOldNextSib); +void RootlessCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, + RegionPtr prgnSrc); +void RootlessMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pSib, + VTKind kind); +void RootlessResizeWindow(WindowPtr pWin, int x, int y, unsigned int w, + unsigned int h, WindowPtr pSib); +void RootlessReparentWindow(WindowPtr pWin, WindowPtr pPriorParent); +void RootlessChangeBorderWidth(WindowPtr pWin, unsigned int width); + +#ifdef __APPLE__ +void RootlessNativeWindowMoved(WindowPtr pWin); +void RootlessNativeWindowStateChanged(WindowPtr pWin, unsigned int state); +#endif + +#endif diff --git a/xorg-server/miext/shadow/shadow.c b/xorg-server/miext/shadow/shadow.c index 95f11cd21..d2ba68497 100644 --- a/xorg-server/miext/shadow/shadow.c +++ b/xorg-server/miext/shadow/shadow.c @@ -37,6 +37,7 @@ #include "shadow.h" static DevPrivateKeyRec shadowScrPrivateKeyRec; + #define shadowScrPrivateKey (&shadowScrPrivateKeyRec) #define wrap(priv, real, mem) {\ @@ -55,11 +56,11 @@ shadowRedisplay(ScreenPtr pScreen) RegionPtr pRegion; if (!pBuf || !pBuf->pDamage || !pBuf->update) - return; + return; pRegion = DamageRegion(pBuf->pDamage); if (RegionNotEmpty(pRegion)) { - (*pBuf->update)(pScreen, pBuf); - DamageEmpty(pBuf->pDamage); + (*pBuf->update) (pScreen, pBuf); + DamageEmpty(pBuf->pDamage); } } @@ -78,14 +79,15 @@ 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) + 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); + shadowRedisplay(pScreen); unwrap(pBuf, pScreen, GetImage); pScreen->GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine); wrap(pBuf, pScreen, GetImage); @@ -103,10 +105,10 @@ shadowCloseScreen(int i, ScreenPtr pScreen) shadowRemove(pScreen, pBuf->pPixmap); DamageDestroy(pBuf->pDamage); #ifdef BACKWARDS_COMPATIBILITY - RegionUninit(&pBuf->damage); /* bc */ + RegionUninit(&pBuf->damage); /* bc */ #endif if (pBuf->pPixmap) - pScreen->DestroyPixmap(pBuf->pPixmap); + pScreen->DestroyPixmap(pBuf->pPixmap); free(pBuf); return pScreen->CloseScreen(i, pScreen); } @@ -117,7 +119,7 @@ shadowReportFunc(DamagePtr pDamage, RegionPtr pRegion, void *closure) { ScreenPtr pScreen = closure; shadowBufPtr pBuf = (shadowBufPtr) - dixLookupPrivate(&pScreen->devPrivates, shadowScrPrivateKey); + dixLookupPrivate(&pScreen->devPrivates, shadowScrPrivateKey); /* Register the damaged region, use DamageReportNone below when we * want to break BC below... */ @@ -137,28 +139,26 @@ shadowSetup(ScreenPtr pScreen) shadowBufPtr pBuf; if (!dixRegisterPrivateKey(&shadowScrPrivateKeyRec, PRIVATE_SCREEN, 0)) - return FALSE; + return FALSE; if (!DamageSetup(pScreen)) - return FALSE; + return FALSE; pBuf = malloc(sizeof(shadowBufRec)); if (!pBuf) - return FALSE; + return FALSE; #ifdef BACKWARDS_COMPATIBILITY - pBuf->pDamage = DamageCreate((DamageReportFunc)shadowReportFunc, - (DamageDestroyFunc)NULL, - DamageReportRawRegion, - TRUE, pScreen, pScreen); + pBuf->pDamage = DamageCreate((DamageReportFunc) shadowReportFunc, + (DamageDestroyFunc) NULL, + DamageReportRawRegion, TRUE, pScreen, pScreen); #else - pBuf->pDamage = DamageCreate((DamageReportFunc)NULL, - (DamageDestroyFunc)NULL, - DamageReportNone, - TRUE, pScreen, pScreen); + pBuf->pDamage = DamageCreate((DamageReportFunc) NULL, + (DamageDestroyFunc) NULL, + DamageReportNone, TRUE, pScreen, pScreen); #endif if (!pBuf->pDamage) { - free(pBuf); - return FALSE; + free(pBuf); + return FALSE; } wrap(pBuf, pScreen, CloseScreen); @@ -169,7 +169,7 @@ shadowSetup(ScreenPtr pScreen) pBuf->closure = 0; pBuf->randr = 0; #ifdef BACKWARDS_COMPATIBILITY - RegionNull(&pBuf->damage); /* bc */ + RegionNull(&pBuf->damage); /* bc */ #endif dixSetPrivate(&pScreen->devPrivates, shadowScrPrivateKey, pBuf); @@ -178,13 +178,13 @@ shadowSetup(ScreenPtr pScreen) Bool shadowAdd(ScreenPtr pScreen, PixmapPtr pPixmap, ShadowUpdateProc update, - ShadowWindowProc window, int randr, void *closure) + ShadowWindowProc window, int randr, void *closure) { shadowBuf(pScreen); if (!RegisterBlockAndWakeupHandlers(shadowBlockHandler, shadowWakeupHandler, - (pointer)pScreen)) - return FALSE; + (pointer) pScreen)) + return FALSE; /* * Map simple rotation values to bitmasks; fortunately, @@ -192,17 +192,17 @@ shadowAdd(ScreenPtr pScreen, PixmapPtr pPixmap, ShadowUpdateProc update, */ switch (randr) { case 0: - randr = SHADOW_ROTATE_0; - break; + randr = SHADOW_ROTATE_0; + break; case 90: - randr = SHADOW_ROTATE_90; - break; + randr = SHADOW_ROTATE_90; + break; case 180: - randr = SHADOW_ROTATE_180; - break; + randr = SHADOW_ROTATE_180; + break; case 270: - randr = SHADOW_ROTATE_270; - break; + randr = SHADOW_ROTATE_270; + break; } pBuf->update = update; pBuf->window = window; @@ -219,31 +219,31 @@ 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; + 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); + (pointer) pScreen); } Bool shadowInit(ScreenPtr pScreen, ShadowUpdateProc update, ShadowWindowProc window) { PixmapPtr pPixmap; - + pPixmap = pScreen->CreatePixmap(pScreen, pScreen->width, pScreen->height, - pScreen->rootDepth, 0); + pScreen->rootDepth, 0); if (!pPixmap) - return FALSE; - + return FALSE; + if (!shadowSetup(pScreen)) { - pScreen->DestroyPixmap(pPixmap); - return FALSE; + pScreen->DestroyPixmap(pPixmap); + return FALSE; } shadowAdd(pScreen, pPixmap, update, window, SHADOW_ROTATE_0, 0); diff --git a/xorg-server/miext/shadow/shadow.h b/xorg-server/miext/shadow/shadow.h index f4473052d..83de22ccc 100644 --- a/xorg-server/miext/shadow/shadow.h +++ b/xorg-server/miext/shadow/shadow.h @@ -30,35 +30,32 @@ #include "damage.h" #include "damagestr.h" -typedef struct _shadowBuf *shadowBufPtr; +typedef struct _shadowBuf *shadowBufPtr; -typedef void (*ShadowUpdateProc) (ScreenPtr pScreen, - shadowBufPtr pBuf); +typedef void (*ShadowUpdateProc) (ScreenPtr pScreen, shadowBufPtr pBuf); #define SHADOW_WINDOW_RELOCATE 1 #define SHADOW_WINDOW_READ 2 #define SHADOW_WINDOW_WRITE 4 -typedef void *(*ShadowWindowProc) (ScreenPtr pScreen, - CARD32 row, - CARD32 offset, - int mode, - CARD32 *size, - void *closure); +typedef void *(*ShadowWindowProc) (ScreenPtr pScreen, + CARD32 row, + CARD32 offset, + int mode, CARD32 *size, void *closure); /* BC hack: do not move the damage member. see shadow.c for explanation. */ typedef struct _shadowBuf { - DamagePtr pDamage; - ShadowUpdateProc update; - ShadowWindowProc window; - RegionRec damage; - PixmapPtr pPixmap; - void *closure; - int randr; + DamagePtr pDamage; + ShadowUpdateProc update; + ShadowWindowProc window; + RegionRec damage; + PixmapPtr pPixmap; + void *closure; + int randr; /* screen wrappers */ - GetImageProcPtr GetImage; - CloseScreenProcPtr CloseScreen; + GetImageProcPtr GetImage; + CloseScreenProcPtr CloseScreen; } shadowBufRec; /* Match defines from randr extension */ @@ -77,105 +74,86 @@ extern _X_EXPORT DevPrivateKey shadowScrPrivateKey; #define shadowGetBuf(pScr) ((shadowBufPtr) \ dixLookupPrivate(&(pScr)->devPrivates, shadowScrPrivateKey)) #define shadowBuf(pScr) shadowBufPtr pBuf = shadowGetBuf(pScr) -#define shadowDamage(pBuf) DamageRegion(pBuf->pDamage) +#define shadowDamage(pBuf) DamageRegion(pBuf->pDamage) extern _X_EXPORT Bool -shadowSetup (ScreenPtr pScreen); + shadowSetup(ScreenPtr pScreen); extern _X_EXPORT Bool -shadowAdd (ScreenPtr pScreen, - PixmapPtr pPixmap, - ShadowUpdateProc update, - ShadowWindowProc window, - int randr, - void *closure); + +shadowAdd(ScreenPtr pScreen, + PixmapPtr pPixmap, + ShadowUpdateProc update, + ShadowWindowProc window, int randr, void *closure); extern _X_EXPORT void -shadowRemove (ScreenPtr pScreen, PixmapPtr pPixmap); + shadowRemove(ScreenPtr pScreen, PixmapPtr pPixmap); extern _X_EXPORT Bool -shadowInit (ScreenPtr pScreen, ShadowUpdateProc update, ShadowWindowProc window); -extern _X_EXPORT void * -shadowAlloc (int width, int height, int bpp); +shadowInit(ScreenPtr pScreen, ShadowUpdateProc update, ShadowWindowProc window); + +extern _X_EXPORT void *shadowAlloc(int width, int height, int bpp); extern _X_EXPORT void -shadowUpdatePacked (ScreenPtr pScreen, - shadowBufPtr pBuf); + shadowUpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf); extern _X_EXPORT void -shadowUpdatePlanar4 (ScreenPtr pScreen, - shadowBufPtr pBuf); + shadowUpdatePlanar4(ScreenPtr pScreen, shadowBufPtr pBuf); extern _X_EXPORT void -shadowUpdatePlanar4x8 (ScreenPtr pScreen, - shadowBufPtr pBuf); + shadowUpdatePlanar4x8(ScreenPtr pScreen, shadowBufPtr pBuf); extern _X_EXPORT void -shadowUpdateRotatePacked (ScreenPtr pScreen, - shadowBufPtr pBuf); + shadowUpdateRotatePacked(ScreenPtr pScreen, shadowBufPtr pBuf); extern _X_EXPORT void -shadowUpdateRotate8_90 (ScreenPtr pScreen, - shadowBufPtr pBuf); + shadowUpdateRotate8_90(ScreenPtr pScreen, shadowBufPtr pBuf); extern _X_EXPORT void -shadowUpdateRotate16_90 (ScreenPtr pScreen, - shadowBufPtr pBuf); + shadowUpdateRotate16_90(ScreenPtr pScreen, shadowBufPtr pBuf); extern _X_EXPORT void -shadowUpdateRotate16_90YX (ScreenPtr pScreen, - shadowBufPtr pBuf); + shadowUpdateRotate16_90YX(ScreenPtr pScreen, shadowBufPtr pBuf); extern _X_EXPORT void -shadowUpdateRotate32_90 (ScreenPtr pScreen, - shadowBufPtr pBuf); + shadowUpdateRotate32_90(ScreenPtr pScreen, shadowBufPtr pBuf); extern _X_EXPORT void -shadowUpdateRotate8_180 (ScreenPtr pScreen, - shadowBufPtr pBuf); + shadowUpdateRotate8_180(ScreenPtr pScreen, shadowBufPtr pBuf); extern _X_EXPORT void -shadowUpdateRotate16_180 (ScreenPtr pScreen, - shadowBufPtr pBuf); + shadowUpdateRotate16_180(ScreenPtr pScreen, shadowBufPtr pBuf); extern _X_EXPORT void -shadowUpdateRotate32_180 (ScreenPtr pScreen, - shadowBufPtr pBuf); + shadowUpdateRotate32_180(ScreenPtr pScreen, shadowBufPtr pBuf); extern _X_EXPORT void -shadowUpdateRotate8_270 (ScreenPtr pScreen, - shadowBufPtr pBuf); + shadowUpdateRotate8_270(ScreenPtr pScreen, shadowBufPtr pBuf); extern _X_EXPORT void -shadowUpdateRotate16_270 (ScreenPtr pScreen, - shadowBufPtr pBuf); + shadowUpdateRotate16_270(ScreenPtr pScreen, shadowBufPtr pBuf); extern _X_EXPORT void -shadowUpdateRotate16_270YX (ScreenPtr pScreen, - shadowBufPtr pBuf); + shadowUpdateRotate16_270YX(ScreenPtr pScreen, shadowBufPtr pBuf); extern _X_EXPORT void -shadowUpdateRotate32_270 (ScreenPtr pScreen, - shadowBufPtr pBuf); + shadowUpdateRotate32_270(ScreenPtr pScreen, shadowBufPtr pBuf); extern _X_EXPORT void -shadowUpdateRotate8 (ScreenPtr pScreen, - shadowBufPtr pBuf); + shadowUpdateRotate8(ScreenPtr pScreen, shadowBufPtr pBuf); extern _X_EXPORT void -shadowUpdateRotate16 (ScreenPtr pScreen, - shadowBufPtr pBuf); + shadowUpdateRotate16(ScreenPtr pScreen, shadowBufPtr pBuf); extern _X_EXPORT void -shadowUpdateRotate32 (ScreenPtr pScreen, - shadowBufPtr pBuf); + shadowUpdateRotate32(ScreenPtr pScreen, shadowBufPtr pBuf); -typedef void (* shadowUpdateProc)(ScreenPtr, shadowBufPtr); +typedef void (*shadowUpdateProc) (ScreenPtr, shadowBufPtr); extern _X_EXPORT shadowUpdateProc shadowUpdatePackedWeak(void); extern _X_EXPORT shadowUpdateProc shadowUpdatePlanar4Weak(void); extern _X_EXPORT shadowUpdateProc shadowUpdatePlanar4x8Weak(void); extern _X_EXPORT shadowUpdateProc shadowUpdateRotatePackedWeak(void); -#endif /* _SHADOW_H_ */ +#endif /* _SHADOW_H_ */ diff --git a/xorg-server/miext/shadow/shpacked.c b/xorg-server/miext/shadow/shpacked.c index c37dca175..d2b2e5e24 100644 --- a/xorg-server/miext/shadow/shpacked.c +++ b/xorg-server/miext/shadow/shpacked.c @@ -41,78 +41,76 @@ #include "fb.h" void -shadowUpdatePacked (ScreenPtr pScreen, - shadowBufPtr pBuf) +shadowUpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf) { - RegionPtr damage = shadowDamage (pBuf); - PixmapPtr pShadow = pBuf->pPixmap; - int nbox = RegionNumRects (damage); - BoxPtr pbox = RegionRects (damage); - FbBits *shaBase, *shaLine, *sha; - FbStride shaStride; - int scrBase, scrLine, scr; - int shaBpp; - _X_UNUSED int shaXoff, shaYoff; - int x, y, w, h, width; - int i; - FbBits *winBase = NULL, *win; - CARD32 winSize; + RegionPtr damage = shadowDamage(pBuf); + PixmapPtr pShadow = pBuf->pPixmap; + int nbox = RegionNumRects(damage); + BoxPtr pbox = RegionRects(damage); + FbBits *shaBase, *shaLine, *sha; + FbStride shaStride; + int scrBase, scrLine, scr; + int shaBpp; + _X_UNUSED int shaXoff, shaYoff; + int x, y, w, h, width; + int i; + FbBits *winBase = NULL, *win; + CARD32 winSize; - fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff); - while (nbox--) - { - x = pbox->x1 * shaBpp; - y = pbox->y1; - w = (pbox->x2 - pbox->x1) * shaBpp; - h = pbox->y2 - pbox->y1; + fbGetDrawable(&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, + shaYoff); + while (nbox--) { + x = pbox->x1 * shaBpp; + y = pbox->y1; + w = (pbox->x2 - pbox->x1) * shaBpp; + h = pbox->y2 - pbox->y1; - scrLine = (x >> FB_SHIFT); - shaLine = shaBase + y * shaStride + (x >> FB_SHIFT); - - x &= FB_MASK; - w = (w + x + FB_MASK) >> FB_SHIFT; - - while (h--) - { - winSize = 0; - scrBase = 0; - width = w; - scr = scrLine; - sha = shaLine; - while (width) { - /* how much remains in this window */ - i = scrBase + winSize - scr; - if (i <= 0 || scr < scrBase) - { - winBase = (FbBits *) (*pBuf->window) (pScreen, - y, - scr * sizeof (FbBits), - SHADOW_WINDOW_WRITE, - &winSize, - pBuf->closure); - if(!winBase) - return; - scrBase = scr; - winSize /= sizeof (FbBits); - i = winSize; - } - win = winBase + (scr - scrBase); - if (i > width) - i = width; - width -= i; - scr += i; + scrLine = (x >> FB_SHIFT); + shaLine = shaBase + y * shaStride + (x >> FB_SHIFT); + + x &= FB_MASK; + w = (w + x + FB_MASK) >> FB_SHIFT; + + while (h--) { + winSize = 0; + scrBase = 0; + width = w; + scr = scrLine; + sha = shaLine; + while (width) { + /* how much remains in this window */ + i = scrBase + winSize - scr; + if (i <= 0 || scr < scrBase) { + winBase = (FbBits *) (*pBuf->window) (pScreen, + y, + scr * sizeof(FbBits), + SHADOW_WINDOW_WRITE, + &winSize, + pBuf->closure); + if (!winBase) + return; + scrBase = scr; + winSize /= sizeof(FbBits); + i = winSize; + } + win = winBase + (scr - scrBase); + if (i > width) + i = width; + width -= i; + scr += i; #define PickBit(a,i) (((a) >> (i)) & 1) - memcpy(win, sha, i * sizeof(FbBits)); - sha += i; - } - shaLine += shaStride; - y++; - } - pbox++; + memcpy(win, sha, i * sizeof(FbBits)); + sha += i; + } + shaLine += shaStride; + y++; + } + pbox++; } } shadowUpdateProc -shadowUpdatePackedWeak(void) { +shadowUpdatePackedWeak(void) +{ return shadowUpdatePacked; } diff --git a/xorg-server/miext/shadow/shplanar.c b/xorg-server/miext/shadow/shplanar.c index 350405186..4f6542cb6 100644 --- a/xorg-server/miext/shadow/shplanar.c +++ b/xorg-server/miext/shadow/shplanar.c @@ -44,7 +44,7 @@ * 32 4-bit pixels per write */ -#define PL_SHIFT 7 +#define PL_SHIFT 7 #define PL_UNIT (1 << PL_SHIFT) #define PL_MASK (PL_UNIT - 1) @@ -87,94 +87,94 @@ #endif void -shadowUpdatePlanar4 (ScreenPtr pScreen, - shadowBufPtr pBuf) +shadowUpdatePlanar4(ScreenPtr pScreen, shadowBufPtr pBuf) { - RegionPtr damage = shadowDamage (pBuf); - PixmapPtr pShadow = pBuf->pPixmap; - int nbox = RegionNumRects (damage); - BoxPtr pbox = RegionRects (damage); - CARD32 *shaBase, *shaLine, *sha; - FbStride shaStride; - int scrBase, scrLine, scr; - int shaBpp; - _X_UNUSED int shaXoff, shaYoff; - int x, y, w, h, width; - int i; - CARD32 *winBase = NULL, *win; - CARD32 winSize; - int plane; - CARD32 m,m5,m6; - CARD8 s1, s2, s3, s4; + RegionPtr damage = shadowDamage(pBuf); + PixmapPtr pShadow = pBuf->pPixmap; + int nbox = RegionNumRects(damage); + BoxPtr pbox = RegionRects(damage); + CARD32 *shaBase, *shaLine, *sha; + FbStride shaStride; + int scrBase, scrLine, scr; + int shaBpp; + _X_UNUSED int shaXoff, shaYoff; + int x, y, w, h, width; + int i; + CARD32 *winBase = NULL, *win; + CARD32 winSize; + int plane; + CARD32 m, m5, m6; + CARD8 s1, s2, s3, s4; - fbGetStipDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff); - while (nbox--) - { - x = (pbox->x1) * shaBpp; - y = (pbox->y1); - w = (pbox->x2 - pbox->x1) * shaBpp; - h = pbox->y2 - pbox->y1; + fbGetStipDrawable(&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, + shaYoff); + while (nbox--) { + x = (pbox->x1) * shaBpp; + y = (pbox->y1); + w = (pbox->x2 - pbox->x1) * shaBpp; + h = pbox->y2 - pbox->y1; - w = (w + (x & PL_MASK) + PL_MASK) >> PL_SHIFT; - x &= ~PL_MASK; - - scrLine = (x >> PL_SHIFT); - shaLine = shaBase + y * shaStride + (x >> FB_SHIFT); - - while (h--) - { - for (plane = 0; plane < 4; plane++) - { - width = w; - scr = scrLine; - sha = shaLine; - winSize = 0; - scrBase = 0; - while (width) { - /* how much remains in this window */ - i = scrBase + winSize - scr; - if (i <= 0 || scr < scrBase) - { - winBase = (CARD32 *) (*pBuf->window) (pScreen, - y, - (scr << 4) | (plane), - SHADOW_WINDOW_WRITE, - &winSize, - pBuf->closure); - if(!winBase) - return; - winSize >>= 2; - scrBase = scr; - i = winSize; - } - win = winBase + (scr - scrBase); - if (i > width) - i = width; - width -= i; - scr += i; - - while (i--) - { - GetBits(plane,0,s1); - GetBits(plane,1,s2); - GetBits(plane,2,s3); - GetBits(plane,3,s4); - *win++ = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); - sha += 4; - } - } - } - shaLine += shaStride; - y++; - } - pbox++; + w = (w + (x & PL_MASK) + PL_MASK) >> PL_SHIFT; + x &= ~PL_MASK; + + scrLine = (x >> PL_SHIFT); + shaLine = shaBase + y * shaStride + (x >> FB_SHIFT); + + while (h--) { + for (plane = 0; plane < 4; plane++) { + width = w; + scr = scrLine; + sha = shaLine; + winSize = 0; + scrBase = 0; + while (width) { + /* how much remains in this window */ + i = scrBase + winSize - scr; + if (i <= 0 || scr < scrBase) { + winBase = (CARD32 *) (*pBuf->window) (pScreen, + y, + (scr << 4) | + (plane), + SHADOW_WINDOW_WRITE, + &winSize, + pBuf->closure); + if (!winBase) + return; + winSize >>= 2; + scrBase = scr; + i = winSize; + } + win = winBase + (scr - scrBase); + if (i > width) + i = width; + width -= i; + scr += i; + + while (i--) { + GetBits(plane, 0, s1); + GetBits(plane, 1, s2); + GetBits(plane, 2, s3); + GetBits(plane, 3, s4); + *win++ = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); + sha += 4; + } + } + } + shaLine += shaStride; + y++; + } + pbox++; } } -shadowUpdateProc shadowUpdatePlanar4Weak(void) { +shadowUpdateProc +shadowUpdatePlanar4Weak(void) +{ return shadowUpdatePlanar4; } -shadowUpdateProc shadowUpdatePlanar4x8Weak(void) { +shadowUpdateProc +shadowUpdatePlanar4x8Weak(void) +{ return shadowUpdatePlanar4x8; } diff --git a/xorg-server/miext/shadow/shplanar8.c b/xorg-server/miext/shadow/shplanar8.c index d0648147a..214fa9aac 100644 --- a/xorg-server/miext/shadow/shplanar8.c +++ b/xorg-server/miext/shadow/shplanar8.c @@ -90,86 +90,81 @@ #endif void -shadowUpdatePlanar4x8 (ScreenPtr pScreen, - shadowBufPtr pBuf) +shadowUpdatePlanar4x8(ScreenPtr pScreen, shadowBufPtr pBuf) { - RegionPtr damage = shadowDamage (pBuf); - PixmapPtr pShadow = pBuf->pPixmap; - int nbox = RegionNumRects (damage); - BoxPtr pbox = RegionRects (damage); - CARD32 *shaBase, *shaLine, *sha; - CARD8 s1, s2, s3, s4; - FbStride shaStride; - int scrBase, scrLine, scr; - int shaBpp; - _X_UNUSED int shaXoff, shaYoff; - int x, y, w, h, width; - int i; - CARD32 *winBase = NULL, *win; - CARD32 winSize; - int plane; + RegionPtr damage = shadowDamage(pBuf); + PixmapPtr pShadow = pBuf->pPixmap; + int nbox = RegionNumRects(damage); + BoxPtr pbox = RegionRects(damage); + CARD32 *shaBase, *shaLine, *sha; + CARD8 s1, s2, s3, s4; + FbStride shaStride; + int scrBase, scrLine, scr; + int shaBpp; + _X_UNUSED int shaXoff, shaYoff; + int x, y, w, h, width; + int i; + CARD32 *winBase = NULL, *win; + CARD32 winSize; + int plane; - fbGetStipDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff); - while (nbox--) - { - x = pbox->x1 * shaBpp; - y = pbox->y1; - w = (pbox->x2 - pbox->x1) * shaBpp; - h = pbox->y2 - pbox->y1; + fbGetStipDrawable(&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, + shaYoff); + while (nbox--) { + x = pbox->x1 * shaBpp; + y = pbox->y1; + w = (pbox->x2 - pbox->x1) * shaBpp; + h = pbox->y2 - pbox->y1; - w = (w + (x & PL_MASK) + PL_MASK) >> PL_SHIFT; - x &= ~PL_MASK; - - scrLine = (x >> PL_SHIFT); - shaLine = shaBase + y * shaStride + (x >> FB_SHIFT); - - while (h--) - { - for (plane = 0; plane < 4; plane++) - { - width = w; - scr = scrLine; - sha = shaLine; - winSize = 0; - scrBase = 0; - while (width) { - /* how much remains in this window */ - i = scrBase + winSize - scr; - if (i <= 0 || scr < scrBase) - { - winBase = (CARD32 *) (*pBuf->window) (pScreen, - y, - (scr << 4) | (plane), - SHADOW_WINDOW_WRITE, - &winSize, - pBuf->closure); - if(!winBase) - return; - winSize >>= 2; - scrBase = scr; - i = winSize; - } - win = winBase + (scr - scrBase); - if (i > width) - i = width; - width -= i; - scr += i; - - while (i--) - { - GetBits(plane,0,s1); - GetBits(plane,2,s2); - GetBits(plane,4,s3); - GetBits(plane,6,s4); - *win++ = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); - sha += 8; - } - } - } - shaLine += shaStride; - y++; - } - pbox++; + w = (w + (x & PL_MASK) + PL_MASK) >> PL_SHIFT; + x &= ~PL_MASK; + + scrLine = (x >> PL_SHIFT); + shaLine = shaBase + y * shaStride + (x >> FB_SHIFT); + + while (h--) { + for (plane = 0; plane < 4; plane++) { + width = w; + scr = scrLine; + sha = shaLine; + winSize = 0; + scrBase = 0; + while (width) { + /* how much remains in this window */ + i = scrBase + winSize - scr; + if (i <= 0 || scr < scrBase) { + winBase = (CARD32 *) (*pBuf->window) (pScreen, + y, + (scr << 4) | + (plane), + SHADOW_WINDOW_WRITE, + &winSize, + pBuf->closure); + if (!winBase) + return; + winSize >>= 2; + scrBase = scr; + i = winSize; + } + win = winBase + (scr - scrBase); + if (i > width) + i = width; + width -= i; + scr += i; + + while (i--) { + GetBits(plane, 0, s1); + GetBits(plane, 2, s2); + GetBits(plane, 4, s3); + GetBits(plane, 6, s4); + *win++ = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); + sha += 8; + } + } + } + shaLine += shaStride; + y++; + } + pbox++; } } - diff --git a/xorg-server/miext/shadow/shrotate.c b/xorg-server/miext/shadow/shrotate.c index 090120387..779a905d2 100644 --- a/xorg-server/miext/shadow/shrotate.c +++ b/xorg-server/miext/shadow/shrotate.c @@ -49,265 +49,256 @@ #define BOTTOM_TO_TOP -2 void -shadowUpdateRotatePacked (ScreenPtr pScreen, - shadowBufPtr pBuf) +shadowUpdateRotatePacked(ScreenPtr pScreen, shadowBufPtr pBuf) { - RegionPtr damage = shadowDamage (pBuf); - PixmapPtr pShadow = pBuf->pPixmap; - int nbox = RegionNumRects (damage); - BoxPtr pbox = RegionRects (damage); - FbBits *shaBits; - FbStride shaStride; - int shaBpp; - _X_UNUSED int shaXoff, shaYoff; - int box_x1, box_x2, box_y1, box_y2; - int sha_x1 = 0, sha_y1 = 0; - int scr_x1 = 0, scr_x2 = 0, scr_y1 = 0, scr_y2 = 0, scr_w, scr_h; - int scr_x, scr_y; - int w; - int pixelsPerBits; - int pixelsMask; - FbStride shaStepOverY = 0, shaStepDownY = 0; - FbStride shaStepOverX = 0, shaStepDownX = 0; - FbBits *shaLine, *sha; - int shaHeight = pShadow->drawable.height; - int shaWidth = pShadow->drawable.width; - FbBits shaMask; - int shaFirstShift, shaShift; - int o_x_dir; - int o_y_dir; - int x_dir; - int y_dir; + RegionPtr damage = shadowDamage(pBuf); + PixmapPtr pShadow = pBuf->pPixmap; + int nbox = RegionNumRects(damage); + BoxPtr pbox = RegionRects(damage); + FbBits *shaBits; + FbStride shaStride; + int shaBpp; + _X_UNUSED int shaXoff, shaYoff; + int box_x1, box_x2, box_y1, box_y2; + int sha_x1 = 0, sha_y1 = 0; + int scr_x1 = 0, scr_x2 = 0, scr_y1 = 0, scr_y2 = 0, scr_w, scr_h; + int scr_x, scr_y; + int w; + int pixelsPerBits; + int pixelsMask; + FbStride shaStepOverY = 0, shaStepDownY = 0; + FbStride shaStepOverX = 0, shaStepDownX = 0; + FbBits *shaLine, *sha; + int shaHeight = pShadow->drawable.height; + int shaWidth = pShadow->drawable.width; + FbBits shaMask; + int shaFirstShift, shaShift; + int o_x_dir; + int o_y_dir; + int x_dir; + int y_dir; - fbGetDrawable (&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, shaYoff); - pixelsPerBits = (sizeof (FbBits) * 8) / shaBpp; + fbGetDrawable(&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, + shaYoff); + pixelsPerBits = (sizeof(FbBits) * 8) / shaBpp; pixelsMask = ~(pixelsPerBits - 1); - shaMask = FbBitsMask (FB_UNIT-shaBpp, shaBpp); + shaMask = FbBitsMask(FB_UNIT - shaBpp, shaBpp); /* * Compute rotation related constants to walk the shadow */ o_x_dir = LEFT_TO_RIGHT; o_y_dir = TOP_TO_BOTTOM; if (pBuf->randr & SHADOW_REFLECT_X) - o_x_dir = -o_x_dir; + o_x_dir = -o_x_dir; if (pBuf->randr & SHADOW_REFLECT_Y) - o_y_dir = -o_y_dir; + o_y_dir = -o_y_dir; switch (pBuf->randr & (SHADOW_ROTATE_ALL)) { - case SHADOW_ROTATE_0: /* upper left shadow -> upper left screen */ + case SHADOW_ROTATE_0: /* upper left shadow -> upper left screen */ default: - x_dir = o_x_dir; - y_dir = o_y_dir; - break; - case SHADOW_ROTATE_90: /* upper right shadow -> upper left screen */ - x_dir = o_y_dir; - y_dir = -o_x_dir; - break; - case SHADOW_ROTATE_180: /* lower right shadow -> upper left screen */ - x_dir = -o_x_dir; - y_dir = -o_y_dir; - break; - case SHADOW_ROTATE_270: /* lower left shadow -> upper left screen */ - x_dir = -o_y_dir; - y_dir = o_x_dir; - break; + x_dir = o_x_dir; + y_dir = o_y_dir; + break; + case SHADOW_ROTATE_90: /* upper right shadow -> upper left screen */ + x_dir = o_y_dir; + y_dir = -o_x_dir; + break; + case SHADOW_ROTATE_180: /* lower right shadow -> upper left screen */ + x_dir = -o_x_dir; + y_dir = -o_y_dir; + break; + case SHADOW_ROTATE_270: /* lower left shadow -> upper left screen */ + x_dir = -o_y_dir; + y_dir = o_x_dir; + break; } switch (x_dir) { case LEFT_TO_RIGHT: - shaStepOverX = shaBpp; - shaStepOverY = 0; - break; + shaStepOverX = shaBpp; + shaStepOverY = 0; + break; case TOP_TO_BOTTOM: - shaStepOverX = 0; - shaStepOverY = shaStride; - break; + shaStepOverX = 0; + shaStepOverY = shaStride; + break; case RIGHT_TO_LEFT: - shaStepOverX = -shaBpp; - shaStepOverY = 0; - break; + shaStepOverX = -shaBpp; + shaStepOverY = 0; + break; case BOTTOM_TO_TOP: - shaStepOverX = 0; - shaStepOverY = -shaStride; - break; + shaStepOverX = 0; + shaStepOverY = -shaStride; + break; } switch (y_dir) { case TOP_TO_BOTTOM: - shaStepDownX = 0; - shaStepDownY = shaStride; - break; + shaStepDownX = 0; + shaStepDownY = shaStride; + break; case RIGHT_TO_LEFT: - shaStepDownX = -shaBpp; - shaStepDownY = 0; - break; + shaStepDownX = -shaBpp; + shaStepDownY = 0; + break; case BOTTOM_TO_TOP: - shaStepDownX = 0; - shaStepDownY = -shaStride; - break; + shaStepDownX = 0; + shaStepDownY = -shaStride; + break; case LEFT_TO_RIGHT: - shaStepDownX = shaBpp; - shaStepDownY = 0; - break; + shaStepDownX = shaBpp; + shaStepDownY = 0; + break; } - - while (nbox--) - { + + while (nbox--) { box_x1 = pbox->x1; box_y1 = pbox->y1; box_x2 = pbox->x2; box_y2 = pbox->y2; pbox++; - /* - * Compute screen and shadow locations for this box - */ - switch (x_dir) { - case LEFT_TO_RIGHT: - scr_x1 = box_x1 & pixelsMask; - scr_x2 = (box_x2 + pixelsPerBits - 1) & pixelsMask; - - sha_x1 = scr_x1; - break; - case TOP_TO_BOTTOM: - scr_x1 = box_y1 & pixelsMask; - scr_x2 = (box_y2 + pixelsPerBits - 1) & pixelsMask; + /* + * Compute screen and shadow locations for this box + */ + switch (x_dir) { + case LEFT_TO_RIGHT: + scr_x1 = box_x1 & pixelsMask; + scr_x2 = (box_x2 + pixelsPerBits - 1) & pixelsMask; + + sha_x1 = scr_x1; + break; + case TOP_TO_BOTTOM: + scr_x1 = box_y1 & pixelsMask; + scr_x2 = (box_y2 + pixelsPerBits - 1) & pixelsMask; + + sha_y1 = scr_x1; + break; + case RIGHT_TO_LEFT: + scr_x1 = (shaWidth - box_x2) & pixelsMask; + scr_x2 = (shaWidth - box_x1 + pixelsPerBits - 1) & pixelsMask; + + sha_x1 = (shaWidth - scr_x1 - 1); + break; + case BOTTOM_TO_TOP: + scr_x1 = (shaHeight - box_y2) & pixelsMask; + scr_x2 = (shaHeight - box_y1 + pixelsPerBits - 1) & pixelsMask; - sha_y1 = scr_x1; - break; - case RIGHT_TO_LEFT: - scr_x1 = (shaWidth - box_x2) & pixelsMask; - scr_x2 = (shaWidth - box_x1 + pixelsPerBits - 1) & pixelsMask; + sha_y1 = (shaHeight - scr_x1 - 1); + break; + } + switch (y_dir) { + case TOP_TO_BOTTOM: + scr_y1 = box_y1; + scr_y2 = box_y2; - sha_x1 = (shaWidth - scr_x1 - 1); - break; - case BOTTOM_TO_TOP: - scr_x1 = (shaHeight - box_y2) & pixelsMask; - scr_x2 = (shaHeight - box_y1 + pixelsPerBits - 1) & pixelsMask; - - sha_y1 = (shaHeight - scr_x1 - 1); - break; - } - switch (y_dir) { - case TOP_TO_BOTTOM: - scr_y1 = box_y1; - scr_y2 = box_y2; + sha_y1 = scr_y1; + break; + case RIGHT_TO_LEFT: + scr_y1 = (shaWidth - box_x2); + scr_y2 = (shaWidth - box_x1); - sha_y1 = scr_y1; - break; - case RIGHT_TO_LEFT: - scr_y1 = (shaWidth - box_x2); - scr_y2 = (shaWidth - box_x1); + sha_x1 = box_x2 - 1; + break; + case BOTTOM_TO_TOP: + scr_y1 = shaHeight - box_y2; + scr_y2 = shaHeight - box_y1; - sha_x1 = box_x2 - 1; - break; - case BOTTOM_TO_TOP: - scr_y1 = shaHeight - box_y2; - scr_y2 = shaHeight - box_y1; - - sha_y1 = box_y2 - 1; - break; - case LEFT_TO_RIGHT: - scr_y1 = box_x1; - scr_y2 = box_x2; + sha_y1 = box_y2 - 1; + break; + case LEFT_TO_RIGHT: + scr_y1 = box_x1; + scr_y2 = box_x2; - sha_x1 = box_x1; - break; - } - scr_w = ((scr_x2 - scr_x1) * shaBpp) >> FB_SHIFT; - scr_h = scr_y2 - scr_y1; - scr_y = scr_y1; + sha_x1 = box_x1; + break; + } + scr_w = ((scr_x2 - scr_x1) * shaBpp) >> FB_SHIFT; + scr_h = scr_y2 - scr_y1; + scr_y = scr_y1; - /* shift amount for first pixel on screen */ - shaFirstShift = FB_UNIT - ((sha_x1 * shaBpp) & FB_MASK) - shaBpp; - - /* pointer to shadow data first placed on screen */ - shaLine = (shaBits + - sha_y1 * shaStride + - ((sha_x1 * shaBpp) >> FB_SHIFT)); + /* shift amount for first pixel on screen */ + shaFirstShift = FB_UNIT - ((sha_x1 * shaBpp) & FB_MASK) - shaBpp; - /* - * Copy the bits, always write across the physical frame buffer - * to take advantage of write combining. - */ - while (scr_h--) - { - int p; - FbBits bits; - FbBits *win; - int i; - CARD32 winSize; - - sha = shaLine; - shaShift = shaFirstShift; - w = scr_w; - scr_x = scr_x1 * shaBpp >> FB_SHIFT; + /* pointer to shadow data first placed on screen */ + shaLine = (shaBits + + sha_y1 * shaStride + ((sha_x1 * shaBpp) >> FB_SHIFT)); - while (w) - { - /* - * Map some of this line - */ - win = (FbBits *) (*pBuf->window) (pScreen, - scr_y, - scr_x << 2, - SHADOW_WINDOW_WRITE, - &winSize, - pBuf->closure); - i = (winSize >> 2); - if (i > w) - i = w; - w -= i; - scr_x += i; - /* - * Copy the portion of the line mapped - */ - while (i--) - { - bits = 0; - p = pixelsPerBits; - /* - * Build one word of output from multiple inputs - * - * Note that for 90/270 rotations, this will walk - * down the shadow hitting each scanline once. - * This is probably not very efficient. - */ - while (p--) - { - bits = FbScrLeft(bits, shaBpp); - bits |= FbScrRight (*sha, shaShift) & shaMask; + /* + * Copy the bits, always write across the physical frame buffer + * to take advantage of write combining. + */ + while (scr_h--) { + int p; + FbBits bits; + FbBits *win; + int i; + CARD32 winSize; - shaShift -= shaStepOverX; - if (shaShift >= FB_UNIT) - { - shaShift -= FB_UNIT; - sha--; - } - else if (shaShift < 0) - { - shaShift += FB_UNIT; - sha++; - } - sha += shaStepOverY; - } - *win++ = bits; - } - } - scr_y++; - shaFirstShift -= shaStepDownX; - if (shaFirstShift >= FB_UNIT) - { - shaFirstShift -= FB_UNIT; - shaLine--; - } - else if (shaFirstShift < 0) - { - shaFirstShift += FB_UNIT; - shaLine++; - } - shaLine += shaStepDownY; - } + sha = shaLine; + shaShift = shaFirstShift; + w = scr_w; + scr_x = scr_x1 * shaBpp >> FB_SHIFT; + + while (w) { + /* + * Map some of this line + */ + win = (FbBits *) (*pBuf->window) (pScreen, + scr_y, + scr_x << 2, + SHADOW_WINDOW_WRITE, + &winSize, pBuf->closure); + i = (winSize >> 2); + if (i > w) + i = w; + w -= i; + scr_x += i; + /* + * Copy the portion of the line mapped + */ + while (i--) { + bits = 0; + p = pixelsPerBits; + /* + * Build one word of output from multiple inputs + * + * Note that for 90/270 rotations, this will walk + * down the shadow hitting each scanline once. + * This is probably not very efficient. + */ + while (p--) { + bits = FbScrLeft(bits, shaBpp); + bits |= FbScrRight(*sha, shaShift) & shaMask; + + shaShift -= shaStepOverX; + if (shaShift >= FB_UNIT) { + shaShift -= FB_UNIT; + sha--; + } + else if (shaShift < 0) { + shaShift += FB_UNIT; + sha++; + } + sha += shaStepOverY; + } + *win++ = bits; + } + } + scr_y++; + shaFirstShift -= shaStepDownX; + if (shaFirstShift >= FB_UNIT) { + shaFirstShift -= FB_UNIT; + shaLine--; + } + else if (shaFirstShift < 0) { + shaFirstShift += FB_UNIT; + shaLine++; + } + shaLine += shaStepDownY; + } } } -shadowUpdateProc shadowUpdateRotatePackedWeak(void) { +shadowUpdateProc +shadowUpdateRotatePackedWeak(void) +{ return shadowUpdateRotatePacked; } diff --git a/xorg-server/miext/shadow/shrotpack.h b/xorg-server/miext/shadow/shrotpack.h index 16afff184..b1cb30d5c 100644 --- a/xorg-server/miext/shadow/shrotpack.h +++ b/xorg-server/miext/shadow/shrotpack.h @@ -94,72 +94,76 @@ #endif void -FUNC (ScreenPtr pScreen, - shadowBufPtr pBuf) +FUNC(ScreenPtr pScreen, shadowBufPtr pBuf) { - RegionPtr damage = shadowDamage (pBuf); - PixmapPtr pShadow = pBuf->pPixmap; - int nbox = RegionNumRects (damage); - BoxPtr pbox = RegionRects (damage); - FbBits *shaBits; - Data *shaBase, *shaLine, *sha; - FbStride shaStride; - int scrBase, scrLine, scr; - int shaBpp; - _X_UNUSED int shaXoff, shaYoff; - int x, y, w, h, width; - int i; - Data *winBase = NULL, *win; - CARD32 winSize; - - fbGetDrawable (&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, shaYoff); + RegionPtr damage = shadowDamage(pBuf); + PixmapPtr pShadow = pBuf->pPixmap; + int nbox = RegionNumRects(damage); + BoxPtr pbox = RegionRects(damage); + FbBits *shaBits; + Data *shaBase, *shaLine, *sha; + FbStride shaStride; + int scrBase, scrLine, scr; + int shaBpp; + _X_UNUSED int shaXoff, shaYoff; + int x, y, w, h, width; + int i; + Data *winBase = NULL, *win; + CARD32 winSize; + + fbGetDrawable(&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, + shaYoff); shaBase = (Data *) shaBits; - shaStride = shaStride * sizeof (FbBits) / sizeof (Data); + shaStride = shaStride * sizeof(FbBits) / sizeof(Data); #if (DANDEBUG > 1) - ErrorF ("-> Entering Shadow Update:\r\n |- Origins: pShadow=%x, pScreen=%x, damage=%x\r\n |- Metrics: shaStride=%d, shaBase=%x, shaBpp=%d\r\n | \n", pShadow, pScreen, damage, shaStride, shaBase, shaBpp); + ErrorF + ("-> Entering Shadow Update:\r\n |- Origins: pShadow=%x, pScreen=%x, damage=%x\r\n |- Metrics: shaStride=%d, shaBase=%x, shaBpp=%d\r\n | \n", + pShadow, pScreen, damage, shaStride, shaBase, shaBpp); #endif - while (nbox--) - { + while (nbox--) { x = pbox->x1; y = pbox->y1; w = (pbox->x2 - pbox->x1); h = pbox->y2 - pbox->y1; - + #if (DANDEBUG > 2) - ErrorF (" |-> Redrawing box - Metrics: X=%d, Y=%d, Width=%d, Height=%d\n", x, y, w, h); + ErrorF + (" |-> Redrawing box - Metrics: X=%d, Y=%d, Width=%d, Height=%d\n", + x, y, w, h); #endif - scrLine = SCRLEFT(x,y,w,h); - shaLine = shaBase + FIRSTSHA(x,y,w,h); - - while (STEPDOWN(x,y,w,h)) - { + scrLine = SCRLEFT(x, y, w, h); + shaLine = shaBase + FIRSTSHA(x, y, w, h); + + while (STEPDOWN(x, y, w, h)) { winSize = 0; scrBase = 0; - width = SCRWIDTH(x,y,w,h); + width = SCRWIDTH(x, y, w, h); scr = scrLine; sha = shaLine; #if (DANDEBUG > 3) - ErrorF (" | |-> StepDown - Metrics: width=%d, scr=%x, sha=%x\n", width, scr, sha); + ErrorF(" | |-> StepDown - Metrics: width=%d, scr=%x, sha=%x\n", + width, scr, sha); #endif - while (width) - { + while (width) { /* how much remains in this window */ i = scrBase + winSize - scr; - if (i <= 0 || scr < scrBase) - { + if (i <= 0 || scr < scrBase) { winBase = (Data *) (*pBuf->window) (pScreen, - SCRY(x,y,w,h), - scr * sizeof (Data), - SHADOW_WINDOW_WRITE, - &winSize, - pBuf->closure); - if(!winBase) + SCRY(x, y, w, h), + scr * sizeof(Data), + SHADOW_WINDOW_WRITE, + &winSize, + pBuf->closure); + if (!winBase) return; scrBase = scr; - winSize /= sizeof (Data); + winSize /= sizeof(Data); i = winSize; #if(DANDEBUG > 4) - ErrorF (" | | |-> Starting New Line - Metrics: winBase=%x, scrBase=%x, winSize=%d\r\n | | | Xstride=%d, Ystride=%d, w=%d h=%d\n", winBase, scrBase, winSize, SHASTEPX(shaStride), SHASTEPY(shaStride), w, h); + ErrorF + (" | | |-> Starting New Line - Metrics: winBase=%x, scrBase=%x, winSize=%d\r\n | | | Xstride=%d, Ystride=%d, w=%d h=%d\n", + winBase, scrBase, winSize, SHASTEPX(shaStride), + SHASTEPY(shaStride), w, h); #endif } win = winBase + (scr - scrBase); @@ -168,20 +172,23 @@ FUNC (ScreenPtr pScreen, width -= i; scr += i; #if(DANDEBUG > 5) - ErrorF (" | | |-> Writing Line - Metrics: win=%x, sha=%x\n", win, sha); + ErrorF + (" | | |-> Writing Line - Metrics: win=%x, sha=%x\n", + win, sha); #endif - while (i--) - { + while (i--) { #if(DANDEBUG > 6) - ErrorF (" | | |-> Writing Pixel - Metrics: win=%x, sha=%d, remaining=%d\n", win, sha, i); + ErrorF + (" | | |-> Writing Pixel - Metrics: win=%x, sha=%d, remaining=%d\n", + win, sha, i); #endif *win++ = *sha; sha += SHASTEPX(shaStride); - } /* i */ - } /* width */ + } /* i */ + } /* width */ shaLine += SHASTEPY(shaStride); - NEXTY(x,y,w,h); - } /* STEPDOWN */ + NEXTY(x, y, w, h); + } /* STEPDOWN */ pbox++; - } /* nbox */ + } /* nbox */ } diff --git a/xorg-server/miext/shadow/shrotpackYX.h b/xorg-server/miext/shadow/shrotpackYX.h index d7b01ec2a..57fcf22fa 100644 --- a/xorg-server/miext/shadow/shrotpackYX.h +++ b/xorg-server/miext/shadow/shrotpackYX.h @@ -54,107 +54,102 @@ #endif void -FUNC (ScreenPtr pScreen, - shadowBufPtr pBuf); + FUNC(ScreenPtr pScreen, shadowBufPtr pBuf); void -FUNC (ScreenPtr pScreen, - shadowBufPtr pBuf) +FUNC(ScreenPtr pScreen, shadowBufPtr pBuf) { - RegionPtr damage = shadowDamage(pBuf); - PixmapPtr pShadow = pBuf->pPixmap; - int nbox = RegionNumRects (damage); - BoxPtr pbox = RegionRects (damage); - FbBits *shaBits; - Data *shaBase, *shaLine, *sha; - FbStride shaStride, winStride; - int shaBpp; - _X_UNUSED int shaXoff, shaYoff; - int x, y, w, h; - Data *winBase, *win, *winLine; - CARD32 winSize; - - fbGetDrawable (&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, shaYoff); + RegionPtr damage = shadowDamage(pBuf); + PixmapPtr pShadow = pBuf->pPixmap; + int nbox = RegionNumRects(damage); + BoxPtr pbox = RegionRects(damage); + FbBits *shaBits; + Data *shaBase, *shaLine, *sha; + FbStride shaStride, winStride; + int shaBpp; + _X_UNUSED int shaXoff, shaYoff; + int x, y, w, h; + Data *winBase, *win, *winLine; + CARD32 winSize; + + fbGetDrawable(&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, + shaYoff); shaBase = (Data *) shaBits; - shaStride = shaStride * sizeof (FbBits) / sizeof (Data); + shaStride = shaStride * sizeof(FbBits) / sizeof(Data); winBase = (Data *) (*pBuf->window) (pScreen, 0, 0, - SHADOW_WINDOW_WRITE, - &winSize, pBuf->closure); + SHADOW_WINDOW_WRITE, + &winSize, pBuf->closure); winStride = (Data *) (*pBuf->window) (pScreen, 1, 0, - SHADOW_WINDOW_WRITE, - &winSize, pBuf->closure) - winBase; + SHADOW_WINDOW_WRITE, + &winSize, pBuf->closure) - winBase; - while (nbox--) - { + while (nbox--) { x = pbox->x1; y = pbox->y1; w = (pbox->x2 - pbox->x1); h = pbox->y2 - pbox->y1; - shaLine = shaBase + (y * shaStride) + x; + shaLine = shaBase + (y * shaStride) + x; #ifdef PREFETCH - __builtin_prefetch (shaLine); + __builtin_prefetch(shaLine); #endif - winLine = winBase + WINSTART(x, y); + winLine = winBase + WINSTART(x, y); - while (h--) - { - sha = shaLine; - win = winLine; + while (h--) { + sha = shaLine; + win = winLine; - while (sha < (shaLine + w - 16)) - { + while (sha < (shaLine + w - 16)) { #ifdef PREFETCH - __builtin_prefetch (sha + shaStride); + __builtin_prefetch(sha + shaStride); #endif - *win = *sha++; - win += WINSTEPX(winStride); - *win = *sha++; - win += WINSTEPX(winStride); - *win = *sha++; - win += WINSTEPX(winStride); - *win = *sha++; - win += WINSTEPX(winStride); - - *win = *sha++; - win += WINSTEPX(winStride); - *win = *sha++; - win += WINSTEPX(winStride); - *win = *sha++; - win += WINSTEPX(winStride); - *win = *sha++; - win += WINSTEPX(winStride); - - *win = *sha++; - win += WINSTEPX(winStride); - *win = *sha++; - win += WINSTEPX(winStride); - *win = *sha++; - win += WINSTEPX(winStride); - *win = *sha++; - win += WINSTEPX(winStride); - - *win = *sha++; - win += WINSTEPX(winStride); - *win = *sha++; - win += WINSTEPX(winStride); - *win = *sha++; - win += WINSTEPX(winStride); - *win = *sha++; - win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); } - while (sha < (shaLine + w)) - { - *win = *sha++; - win += WINSTEPX(winStride); + while (sha < (shaLine + w)) { + *win = *sha++; + win += WINSTEPX(winStride); } - y++; - shaLine += shaStride; - winLine += WINSTEPY(); + y++; + shaLine += shaStride; + winLine += WINSTEPY(); } pbox++; - } /* nbox */ + } /* nbox */ } diff --git a/xorg-server/miext/sync/misync.c b/xorg-server/miext/sync/misync.c index f3b711d58..b1e2a36f7 100644 --- a/xorg-server/miext/sync/misync.c +++ b/xorg-server/miext/sync/misync.c @@ -1,200 +1,201 @@ -/*
- * Copyright © 2010 NVIDIA Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "scrnintstr.h"
-#include "misync.h"
-#include "misyncstr.h"
-
-static DevPrivateKeyRec syncScreenPrivateKeyRec;
-static DevPrivateKey syncScreenPrivateKey = &syncScreenPrivateKeyRec;
-
-#define SYNC_SCREEN_PRIV(pScreen) \
- (SyncScreenPrivPtr) dixLookupPrivate(&pScreen->devPrivates, \
- syncScreenPrivateKey)
-
-typedef struct _syncScreenPriv {
- /* Wrappable sync-specific screen functions */
- SyncScreenFuncsRec funcs;
-
- /* Wrapped screen functions */
- CloseScreenProcPtr CloseScreen;
-} SyncScreenPrivRec, *SyncScreenPrivPtr;
-
-/* Default implementations of the sync screen functions */
-void
-miSyncScreenCreateFence(ScreenPtr pScreen, SyncFence* pFence,
- Bool initially_triggered)
-{
- (void)pScreen;
-
- pFence->triggered = initially_triggered;
-}
-
-void miSyncScreenDestroyFence(ScreenPtr pScreen, SyncFence* pFence)
-{
- (void)pScreen;
- (void)pFence;
-}
-
-/* Default implementations of the per-object functions */
-static void
-miSyncFenceSetTriggered(SyncFence* pFence)
-{
- pFence->triggered = TRUE;
-}
-
-static void
-miSyncFenceReset(SyncFence* pFence)
-{
- pFence->triggered = FALSE;
-}
-
-static Bool
-miSyncFenceCheckTriggered(SyncFence* pFence)
-{
- return pFence->triggered;
-}
-
-static void
-miSyncFenceAddTrigger(SyncTrigger* pTrigger)
-{
- (void)pTrigger;
-
- return;
-}
-
-static void
-miSyncFenceDeleteTrigger(SyncTrigger* pTrigger)
-{
- (void)pTrigger;
-
- return;
-}
-
-/* Machine independent portion of the fence sync object implementation */
-void
-miSyncInitFence(ScreenPtr pScreen, SyncFence* pFence, Bool initially_triggered)
-{
- SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen);
- static const SyncFenceFuncsRec miSyncFenceFuncs = {
- &miSyncFenceSetTriggered,
- &miSyncFenceReset,
- &miSyncFenceCheckTriggered,
- &miSyncFenceAddTrigger,
- &miSyncFenceDeleteTrigger
- };
-
- pFence->pScreen = pScreen;
- pFence->funcs = miSyncFenceFuncs;
-
- pScreenPriv->funcs.CreateFence(pScreen, pFence, initially_triggered);
-}
-
-void
-miSyncDestroyFence(SyncFence* pFence)
-{
- ScreenPtr pScreen = pFence->pScreen;
- SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen);
- SyncTriggerList *ptl, *pNext;
-
- pFence->sync.beingDestroyed = TRUE;
- /* tell all the fence's triggers that the counter has been destroyed */
- for (ptl = pFence->sync.pTriglist; ptl; ptl = pNext)
- {
- (*ptl->pTrigger->CounterDestroyed)(ptl->pTrigger);
- pNext = ptl->next;
- free(ptl); /* destroy the trigger list as we go */
- }
-
- pScreenPriv->funcs.DestroyFence(pScreen, pFence);
-
- dixFreeObjectWithPrivates(pFence, PRIVATE_SYNC_FENCE);
-}
-
-void
-miSyncTriggerFence(SyncFence* pFence)
-{
- SyncTriggerList *ptl, *pNext;
- CARD64 unused;
-
- pFence->funcs.SetTriggered(pFence);
-
- XSyncIntToValue(&unused, 0L);
-
- /* run through triggers to see if any fired */
- for (ptl = pFence->sync.pTriglist; ptl; ptl = pNext)
- {
- pNext = ptl->next;
- if ((*ptl->pTrigger->CheckTrigger)(ptl->pTrigger, unused))
- (*ptl->pTrigger->TriggerFired)(ptl->pTrigger);
- }
-}
-
-SyncScreenFuncsPtr miSyncGetScreenFuncs(ScreenPtr pScreen)
-{
- SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen);
-
- return &pScreenPriv->funcs;
-}
-
-static Bool
-SyncCloseScreen (int i, ScreenPtr pScreen)
-{
- SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen);
-
- pScreen->CloseScreen = pScreenPriv->CloseScreen;
-
- return (*pScreen->CloseScreen) (i, pScreen);
-}
-
-Bool
-miSyncSetup(ScreenPtr pScreen)
-{
- SyncScreenPrivPtr pScreenPriv;
-
- static const SyncScreenFuncsRec miSyncScreenFuncs = {
- &miSyncScreenCreateFence,
- &miSyncScreenDestroyFence
- };
-
- if (dixPrivateKeyRegistered(syncScreenPrivateKey))
- return TRUE;
-
- if (!dixRegisterPrivateKey(syncScreenPrivateKey, PRIVATE_SCREEN,
- sizeof(SyncScreenPrivRec)))
- return FALSE;
-
- pScreenPriv = SYNC_SCREEN_PRIV(pScreen);
-
- pScreenPriv->funcs = miSyncScreenFuncs;
-
- /* Wrap CloseScreen to clean up */
- pScreenPriv->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = SyncCloseScreen;
-
- return TRUE;
-}
+/* + * Copyright © 2010 NVIDIA Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "scrnintstr.h" +#include "misync.h" +#include "misyncstr.h" + +static DevPrivateKeyRec syncScreenPrivateKeyRec; +static DevPrivateKey syncScreenPrivateKey = &syncScreenPrivateKeyRec; + +#define SYNC_SCREEN_PRIV(pScreen) \ + (SyncScreenPrivPtr) dixLookupPrivate(&pScreen->devPrivates, \ + syncScreenPrivateKey) + +typedef struct _syncScreenPriv { + /* Wrappable sync-specific screen functions */ + SyncScreenFuncsRec funcs; + + /* Wrapped screen functions */ + CloseScreenProcPtr CloseScreen; +} SyncScreenPrivRec, *SyncScreenPrivPtr; + +/* Default implementations of the sync screen functions */ +void +miSyncScreenCreateFence(ScreenPtr pScreen, SyncFence * pFence, + Bool initially_triggered) +{ + (void) pScreen; + + pFence->triggered = initially_triggered; +} + +void +miSyncScreenDestroyFence(ScreenPtr pScreen, SyncFence * pFence) +{ + (void) pScreen; + (void) pFence; +} + +/* Default implementations of the per-object functions */ +static void +miSyncFenceSetTriggered(SyncFence * pFence) +{ + pFence->triggered = TRUE; +} + +static void +miSyncFenceReset(SyncFence * pFence) +{ + pFence->triggered = FALSE; +} + +static Bool +miSyncFenceCheckTriggered(SyncFence * pFence) +{ + return pFence->triggered; +} + +static void +miSyncFenceAddTrigger(SyncTrigger * pTrigger) +{ + (void) pTrigger; + + return; +} + +static void +miSyncFenceDeleteTrigger(SyncTrigger * pTrigger) +{ + (void) pTrigger; + + return; +} + +/* Machine independent portion of the fence sync object implementation */ +void +miSyncInitFence(ScreenPtr pScreen, SyncFence * pFence, Bool initially_triggered) +{ + SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen); + + static const SyncFenceFuncsRec miSyncFenceFuncs = { + &miSyncFenceSetTriggered, + &miSyncFenceReset, + &miSyncFenceCheckTriggered, + &miSyncFenceAddTrigger, + &miSyncFenceDeleteTrigger + }; + + pFence->pScreen = pScreen; + pFence->funcs = miSyncFenceFuncs; + + pScreenPriv->funcs.CreateFence(pScreen, pFence, initially_triggered); +} + +void +miSyncDestroyFence(SyncFence * pFence) +{ + ScreenPtr pScreen = pFence->pScreen; + SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen); + SyncTriggerList *ptl, *pNext; + + pFence->sync.beingDestroyed = TRUE; + /* tell all the fence's triggers that the counter has been destroyed */ + for (ptl = pFence->sync.pTriglist; ptl; ptl = pNext) { + (*ptl->pTrigger->CounterDestroyed) (ptl->pTrigger); + pNext = ptl->next; + free(ptl); /* destroy the trigger list as we go */ + } + + pScreenPriv->funcs.DestroyFence(pScreen, pFence); + + dixFreeObjectWithPrivates(pFence, PRIVATE_SYNC_FENCE); +} + +void +miSyncTriggerFence(SyncFence * pFence) +{ + SyncTriggerList *ptl, *pNext; + CARD64 unused; + + pFence->funcs.SetTriggered(pFence); + + XSyncIntToValue(&unused, 0L); + + /* run through triggers to see if any fired */ + for (ptl = pFence->sync.pTriglist; ptl; ptl = pNext) { + pNext = ptl->next; + if ((*ptl->pTrigger->CheckTrigger) (ptl->pTrigger, unused)) + (*ptl->pTrigger->TriggerFired) (ptl->pTrigger); + } +} + +SyncScreenFuncsPtr +miSyncGetScreenFuncs(ScreenPtr pScreen) +{ + SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen); + + return &pScreenPriv->funcs; +} + +static Bool +SyncCloseScreen(int i, ScreenPtr pScreen) +{ + SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen); + + pScreen->CloseScreen = pScreenPriv->CloseScreen; + + return (*pScreen->CloseScreen) (i, pScreen); +} + +Bool +miSyncSetup(ScreenPtr pScreen) +{ + SyncScreenPrivPtr pScreenPriv; + + static const SyncScreenFuncsRec miSyncScreenFuncs = { + &miSyncScreenCreateFence, + &miSyncScreenDestroyFence + }; + + if (dixPrivateKeyRegistered(syncScreenPrivateKey)) + return TRUE; + + if (!dixRegisterPrivateKey(syncScreenPrivateKey, PRIVATE_SCREEN, + sizeof(SyncScreenPrivRec))) + return FALSE; + + pScreenPriv = SYNC_SCREEN_PRIV(pScreen); + + pScreenPriv->funcs = miSyncScreenFuncs; + + /* Wrap CloseScreen to clean up */ + pScreenPriv->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = SyncCloseScreen; + + return TRUE; +} diff --git a/xorg-server/miext/sync/misync.h b/xorg-server/miext/sync/misync.h index 644309324..deebb82bc 100644 --- a/xorg-server/miext/sync/misync.h +++ b/xorg-server/miext/sync/misync.h @@ -1,77 +1,79 @@ -/*
- * Copyright © 2010 NVIDIA Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#ifndef _MISYNC_H_
-#define _MISYNC_H_
-
-typedef struct _SyncFence SyncFence;
-typedef struct _SyncTrigger SyncTrigger;
-
-typedef void (*SyncScreenCreateFenceFunc) (ScreenPtr pScreen,
- SyncFence* pFence,
- Bool initially_triggered);
-typedef void (*SyncScreenDestroyFenceFunc) (ScreenPtr pScreen,
- SyncFence* pFence);
-
-typedef struct _syncScreenFuncs {
- SyncScreenCreateFenceFunc CreateFence;
- SyncScreenDestroyFenceFunc DestroyFence;
-} SyncScreenFuncsRec, *SyncScreenFuncsPtr;
-
-extern _X_EXPORT void
-miSyncScreenCreateFence(ScreenPtr pScreen, SyncFence* pFence,
- Bool initially_triggered);
-extern _X_EXPORT void
-miSyncScreenDestroyFence(ScreenPtr pScreen, SyncFence* pFence);
-
-typedef void (*SyncFenceSetTriggeredFunc) (SyncFence* pFence);
-typedef void (*SyncFenceResetFunc) (SyncFence* pFence);
-typedef Bool (*SyncFenceCheckTriggeredFunc) (SyncFence* pFence);
-typedef void (*SyncFenceAddTriggerFunc) (SyncTrigger* pTrigger);
-typedef void (*SyncFenceDeleteTriggerFunc) (SyncTrigger* pTrigger);
-
-typedef struct _syncFenceFuncs {
- SyncFenceSetTriggeredFunc SetTriggered;
- SyncFenceResetFunc Reset;
- SyncFenceCheckTriggeredFunc CheckTriggered;
- SyncFenceAddTriggerFunc AddTrigger;
- SyncFenceDeleteTriggerFunc DeleteTrigger;
-} SyncFenceFuncsRec, *SyncFenceFuncsPtr;
-
-extern _X_EXPORT void
-miSyncInitFence(ScreenPtr pScreen, SyncFence* pFence, Bool initially_triggered);
-extern _X_EXPORT void
-miSyncDestroyFence(SyncFence* pFence);
-extern _X_EXPORT void
-miSyncTriggerFence(SyncFence* pFence);
-
-extern _X_EXPORT SyncScreenFuncsPtr
-miSyncGetScreenFuncs(ScreenPtr pScreen);
-extern _X_EXPORT Bool
-miSyncSetup(ScreenPtr pScreen);
-
-#endif /* _MISYNC_H_ */
+/* + * Copyright © 2010 NVIDIA Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef _MISYNC_H_ +#define _MISYNC_H_ + +typedef struct _SyncFence SyncFence; +typedef struct _SyncTrigger SyncTrigger; + +typedef void (*SyncScreenCreateFenceFunc) (ScreenPtr pScreen, + SyncFence * pFence, + Bool initially_triggered); +typedef void (*SyncScreenDestroyFenceFunc) (ScreenPtr pScreen, + SyncFence * pFence); + +typedef struct _syncScreenFuncs { + SyncScreenCreateFenceFunc CreateFence; + SyncScreenDestroyFenceFunc DestroyFence; +} SyncScreenFuncsRec, *SyncScreenFuncsPtr; + +extern _X_EXPORT void + +miSyncScreenCreateFence(ScreenPtr pScreen, SyncFence * pFence, + Bool initially_triggered); +extern _X_EXPORT void + miSyncScreenDestroyFence(ScreenPtr pScreen, SyncFence * pFence); + +typedef void (*SyncFenceSetTriggeredFunc) (SyncFence * pFence); +typedef void (*SyncFenceResetFunc) (SyncFence * pFence); +typedef Bool (*SyncFenceCheckTriggeredFunc) (SyncFence * pFence); +typedef void (*SyncFenceAddTriggerFunc) (SyncTrigger * pTrigger); +typedef void (*SyncFenceDeleteTriggerFunc) (SyncTrigger * pTrigger); + +typedef struct _syncFenceFuncs { + SyncFenceSetTriggeredFunc SetTriggered; + SyncFenceResetFunc Reset; + SyncFenceCheckTriggeredFunc CheckTriggered; + SyncFenceAddTriggerFunc AddTrigger; + SyncFenceDeleteTriggerFunc DeleteTrigger; +} SyncFenceFuncsRec, *SyncFenceFuncsPtr; + +extern _X_EXPORT void + +miSyncInitFence(ScreenPtr pScreen, SyncFence * pFence, + Bool initially_triggered); +extern _X_EXPORT void + miSyncDestroyFence(SyncFence * pFence); +extern _X_EXPORT void + miSyncTriggerFence(SyncFence * pFence); + +extern _X_EXPORT SyncScreenFuncsPtr miSyncGetScreenFuncs(ScreenPtr pScreen); +extern _X_EXPORT Bool + miSyncSetup(ScreenPtr pScreen); + +#endif /* _MISYNC_H_ */ diff --git a/xorg-server/miext/sync/misyncstr.h b/xorg-server/miext/sync/misyncstr.h index 9b0f24365..e19256fee 100644 --- a/xorg-server/miext/sync/misyncstr.h +++ b/xorg-server/miext/sync/misyncstr.h @@ -1,86 +1,82 @@ -/*
- * Copyright © 2010 NVIDIA Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#ifndef _MISYNCSTR_H_
-#define _MISYNCSTR_H_
-
-#include "dix.h"
-#include <X11/extensions/syncconst.h>
-
-#define CARD64 XSyncValue /* XXX temporary! need real 64 bit values for Alpha */
-
-/* Sync object types */
-#define SYNC_COUNTER 0
-#define SYNC_FENCE 1
-
-typedef struct _SyncObject {
- ClientPtr client; /* Owning client. 0 for system counters */
- struct _SyncTriggerList *pTriglist; /* list of triggers */
- XID id; /* resource ID */
- unsigned char type; /* SYNC_* */
- Bool beingDestroyed; /* in process of going away */
-} SyncObject;
-
-typedef struct _SyncCounter {
- SyncObject sync; /* Common sync object data */
- CARD64 value; /* counter value */
- struct _SysCounterInfo *pSysCounterInfo; /* NULL if not a system counter */
-} SyncCounter;
-
-struct _SyncFence {
- SyncObject sync; /* Common sync object data */
- ScreenPtr pScreen; /* Screen of this fence object */
- SyncFenceFuncsRec funcs; /* Funcs for performing ops on fence */
- Bool triggered; /* fence state */
- PrivateRec *devPrivates; /* driver-specific per-fence data */
-};
-
-struct _SyncTrigger {
- SyncObject *pSync;
- CARD64 wait_value; /* wait value */
- unsigned int value_type; /* Absolute or Relative */
- unsigned int test_type; /* transition or Comparision type */
- CARD64 test_value; /* trigger event threshold value */
- Bool (*CheckTrigger)(
- struct _SyncTrigger * /*pTrigger*/,
- CARD64 /*newval*/
- );
- void (*TriggerFired)(
- struct _SyncTrigger * /*pTrigger*/
- );
- void (*CounterDestroyed)(
- struct _SyncTrigger * /*pTrigger*/
- );
-};
-
-typedef struct _SyncTriggerList {
- SyncTrigger *pTrigger;
- struct _SyncTriggerList *next;
-} SyncTriggerList;
-
-#endif /* _MISYNCSTR_H_ */
-
+/* + * Copyright © 2010 NVIDIA Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef _MISYNCSTR_H_ +#define _MISYNCSTR_H_ + +#include "dix.h" +#include <X11/extensions/syncconst.h> + +#define CARD64 XSyncValue /* XXX temporary! need real 64 bit values for Alpha */ + +/* Sync object types */ +#define SYNC_COUNTER 0 +#define SYNC_FENCE 1 + +typedef struct _SyncObject { + ClientPtr client; /* Owning client. 0 for system counters */ + struct _SyncTriggerList *pTriglist; /* list of triggers */ + XID id; /* resource ID */ + unsigned char type; /* SYNC_* */ + Bool beingDestroyed; /* in process of going away */ +} SyncObject; + +typedef struct _SyncCounter { + SyncObject sync; /* Common sync object data */ + CARD64 value; /* counter value */ + struct _SysCounterInfo *pSysCounterInfo; /* NULL if not a system counter */ +} SyncCounter; + +struct _SyncFence { + SyncObject sync; /* Common sync object data */ + ScreenPtr pScreen; /* Screen of this fence object */ + SyncFenceFuncsRec funcs; /* Funcs for performing ops on fence */ + Bool triggered; /* fence state */ + PrivateRec *devPrivates; /* driver-specific per-fence data */ +}; + +struct _SyncTrigger { + SyncObject *pSync; + CARD64 wait_value; /* wait value */ + unsigned int value_type; /* Absolute or Relative */ + unsigned int test_type; /* transition or Comparision type */ + CARD64 test_value; /* trigger event threshold value */ + Bool (*CheckTrigger) (struct _SyncTrigger * /*pTrigger */ , + CARD64 /*newval */ + ); + void (*TriggerFired) (struct _SyncTrigger * /*pTrigger */ + ); + void (*CounterDestroyed) (struct _SyncTrigger * /*pTrigger */ + ); +}; + +typedef struct _SyncTriggerList { + SyncTrigger *pTrigger; + struct _SyncTriggerList *next; +} SyncTriggerList; + +#endif /* _MISYNCSTR_H_ */ |