aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/fb/fbpixmap.c
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2011-04-01 07:17:02 +0000
committermarha <marha@users.sourceforge.net>2011-04-01 07:17:02 +0000
commit5d8e1ad0cd01de0bd0b43dc916c1d39fd293e79d (patch)
treeb7092d8d81a5246dd5cec7fa9742e41eaccb69d6 /xorg-server/fb/fbpixmap.c
parent140242b0d4aed1d595d6565d088d9567c456d6b4 (diff)
downloadvcxsrv-5d8e1ad0cd01de0bd0b43dc916c1d39fd293e79d.tar.gz
vcxsrv-5d8e1ad0cd01de0bd0b43dc916c1d39fd293e79d.tar.bz2
vcxsrv-5d8e1ad0cd01de0bd0b43dc916c1d39fd293e79d.zip
libXext xserver libXmu libX11 libXdmcp xextproto libxtrans mesa git update 1 Apr 2011
Diffstat (limited to 'xorg-server/fb/fbpixmap.c')
-rw-r--r--xorg-server/fb/fbpixmap.c782
1 files changed, 390 insertions, 392 deletions
diff --git a/xorg-server/fb/fbpixmap.c b/xorg-server/fb/fbpixmap.c
index 155f1e134..a356c67b6 100644
--- a/xorg-server/fb/fbpixmap.c
+++ b/xorg-server/fb/fbpixmap.c
@@ -1,392 +1,390 @@
-/*
- * Copyright © 1998 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdlib.h>
-
-#include "fb.h"
-
-PixmapPtr
-fbCreatePixmapBpp (ScreenPtr pScreen, int width, int height, int depth, int bpp,
- unsigned usage_hint)
-{
- PixmapPtr pPixmap;
- size_t datasize;
- size_t paddedWidth;
- int adjust;
- int base;
-
- paddedWidth = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (FbBits);
- if (paddedWidth / 4 > 32767 || height > 32767)
- return NullPixmap;
- datasize = height * paddedWidth;
- base = pScreen->totalPixmapSize;
- adjust = 0;
- if (base & 7)
- adjust = 8 - (base & 7);
- datasize += adjust;
-#ifdef FB_DEBUG
- datasize += 2 * paddedWidth;
-#endif
- pPixmap = AllocatePixmap(pScreen, datasize);
- if (!pPixmap)
- return NullPixmap;
- pPixmap->drawable.type = DRAWABLE_PIXMAP;
- pPixmap->drawable.class = 0;
- pPixmap->drawable.pScreen = pScreen;
- pPixmap->drawable.depth = depth;
- pPixmap->drawable.bitsPerPixel = bpp;
- pPixmap->drawable.id = 0;
- pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- pPixmap->drawable.x = 0;
- pPixmap->drawable.y = 0;
- pPixmap->drawable.width = width;
- pPixmap->drawable.height = height;
- pPixmap->devKind = paddedWidth;
- pPixmap->refcnt = 1;
- pPixmap->devPrivate.ptr = (pointer) ((char *)pPixmap + base + adjust);
-
-#ifdef FB_DEBUG
- pPixmap->devPrivate.ptr = (void *) ((char *) pPixmap->devPrivate.ptr + paddedWidth);
- fbInitializeDrawable (&pPixmap->drawable);
-#endif
-
-#ifdef COMPOSITE
- pPixmap->screen_x = 0;
- pPixmap->screen_y = 0;
-#endif
-
- pPixmap->usage_hint = usage_hint;
-
- return pPixmap;
-}
-
-PixmapPtr
-fbCreatePixmap (ScreenPtr pScreen, int width, int height, int depth,
- unsigned usage_hint)
-{
- int bpp;
- bpp = BitsPerPixel (depth);
-#ifdef FB_SCREEN_PRIVATE
- if (bpp == 32 && depth <= 24)
- bpp = fbGetScreenPrivate(pScreen)->pix32bpp;
-#endif
- return fbCreatePixmapBpp (pScreen, width, height, depth, bpp, usage_hint);
-}
-
-Bool
-fbDestroyPixmap (PixmapPtr pPixmap)
-{
- if(--pPixmap->refcnt)
- return TRUE;
- FreePixmap(pPixmap);
- return TRUE;
-}
-
-#define ADDRECT(reg,r,fr,rx1,ry1,rx2,ry2) \
-if (((rx1) < (rx2)) && ((ry1) < (ry2)) && \
- (!((reg)->data->numRects && \
- ((r-1)->y1 == (ry1)) && \
- ((r-1)->y2 == (ry2)) && \
- ((r-1)->x1 <= (rx1)) && \
- ((r-1)->x2 >= (rx2))))) \
-{ \
- if ((reg)->data->numRects == (reg)->data->size) \
- { \
- RegionRectAlloc(reg, 1); \
- fr = RegionBoxptr(reg); \
- r = fr + (reg)->data->numRects; \
- } \
- r->x1 = (rx1); \
- r->y1 = (ry1); \
- r->x2 = (rx2); \
- r->y2 = (ry2); \
- (reg)->data->numRects++; \
- if(r->x1 < (reg)->extents.x1) \
- (reg)->extents.x1 = r->x1; \
- if(r->x2 > (reg)->extents.x2) \
- (reg)->extents.x2 = r->x2; \
- r++; \
-}
-
-/* Convert bitmap clip mask into clipping region.
- * First, goes through each line and makes boxes by noting the transitions
- * from 0 to 1 and 1 to 0.
- * Then it coalesces the current line with the previous if they have boxes
- * at the same X coordinates.
- */
-RegionPtr
-fbPixmapToRegion(PixmapPtr pPix)
-{
- register RegionPtr pReg;
- FbBits *pw, w;
- register int ib;
- int width, h, base, rx1 = 0, crects;
- FbBits *pwLineEnd;
- int irectPrevStart, irectLineStart;
- register BoxPtr prectO, prectN;
- BoxPtr FirstRect, rects, prectLineStart;
- Bool fInBox, fSame;
- register FbBits mask0 = FB_ALLONES & ~FbScrRight(FB_ALLONES, 1);
- FbBits *pwLine;
- int nWidth;
-
- pReg = RegionCreate(NULL, 1);
- if(!pReg)
- return NullRegion;
- FirstRect = RegionBoxptr(pReg);
- rects = FirstRect;
-
- fbPrepareAccess(&pPix->drawable);
-
- pwLine = (FbBits *) pPix->devPrivate.ptr;
- nWidth = pPix->devKind >> (FB_SHIFT-3);
-
- width = pPix->drawable.width;
- pReg->extents.x1 = width - 1;
- pReg->extents.x2 = 0;
- irectPrevStart = -1;
- for(h = 0; h < pPix->drawable.height; h++)
- {
- pw = pwLine;
- pwLine += nWidth;
- irectLineStart = rects - FirstRect;
- /* If the Screen left most bit of the word is set, we're starting in
- * a box */
- if(READ(pw) & mask0)
- {
- fInBox = TRUE;
- rx1 = 0;
- }
- else
- fInBox = FALSE;
- /* Process all words which are fully in the pixmap */
- pwLineEnd = pw + (width >> FB_SHIFT);
- for (base = 0; pw < pwLineEnd; base += FB_UNIT)
- {
- w = READ(pw++);
- if (fInBox)
- {
- if (!~w)
- continue;
- }
- else
- {
- if (!w)
- continue;
- }
- for(ib = 0; ib < FB_UNIT; ib++)
- {
- /* If the Screen left most bit of the word is set, we're
- * starting a box */
- if(w & mask0)
- {
- if(!fInBox)
- {
- rx1 = base + ib;
- /* start new box */
- fInBox = TRUE;
- }
- }
- else
- {
- if(fInBox)
- {
- /* end box */
- ADDRECT(pReg, rects, FirstRect,
- rx1, h, base + ib, h + 1);
- fInBox = FALSE;
- }
- }
- /* Shift the word VISUALLY left one. */
- w = FbScrLeft(w, 1);
- }
- }
- if(width & FB_MASK)
- {
- /* Process final partial word on line */
- w = READ(pw++);
- for(ib = 0; ib < (width & FB_MASK); ib++)
- {
- /* If the Screen left most bit of the word is set, we're
- * starting a box */
- if(w & mask0)
- {
- if(!fInBox)
- {
- rx1 = base + ib;
- /* start new box */
- fInBox = TRUE;
- }
- }
- else
- {
- if(fInBox)
- {
- /* end box */
- ADDRECT(pReg, rects, FirstRect,
- rx1, h, base + ib, h + 1);
- fInBox = FALSE;
- }
- }
- /* Shift the word VISUALLY left one. */
- w = FbScrLeft(w, 1);
- }
- }
- /* If scanline ended with last bit set, end the box */
- if(fInBox)
- {
- ADDRECT(pReg, rects, FirstRect,
- rx1, h, base + (width & FB_MASK), h + 1);
- }
- /* if all rectangles on this line have the same x-coords as
- * those on the previous line, then add 1 to all the previous y2s and
- * throw away all the rectangles from this line
- */
- fSame = FALSE;
- if(irectPrevStart != -1)
- {
- crects = irectLineStart - irectPrevStart;
- if(crects == ((rects - FirstRect) - irectLineStart))
- {
- prectO = FirstRect + irectPrevStart;
- prectN = prectLineStart = FirstRect + irectLineStart;
- fSame = TRUE;
- while(prectO < prectLineStart)
- {
- if((prectO->x1 != prectN->x1) || (prectO->x2 != prectN->x2))
- {
- fSame = FALSE;
- break;
- }
- prectO++;
- prectN++;
- }
- if (fSame)
- {
- prectO = FirstRect + irectPrevStart;
- while(prectO < prectLineStart)
- {
- prectO->y2 += 1;
- prectO++;
- }
- rects -= crects;
- pReg->data->numRects -= crects;
- }
- }
- }
- if(!fSame)
- irectPrevStart = irectLineStart;
- }
- if (!pReg->data->numRects)
- pReg->extents.x1 = pReg->extents.x2 = 0;
- else
- {
- pReg->extents.y1 = RegionBoxptr(pReg)->y1;
- pReg->extents.y2 = RegionEnd(pReg)->y2;
- if (pReg->data->numRects == 1)
- {
- free(pReg->data);
- pReg->data = (RegDataPtr)NULL;
- }
- }
-
- fbFinishAccess(&pPix->drawable);
-#ifdef DEBUG
- if (!RegionIsValid(pReg))
- FatalError("Assertion failed file %s, line %d: expr\n", __FILE__, __LINE__);
-#endif
- return pReg;
-}
-
-#ifdef FB_DEBUG
-
-#ifndef WIN32
-#include <stdio.h>
-#else
-#include <dbg.h>
-#endif
-
-static Bool
-fbValidateBits (FbStip *bits, int stride, FbStip data)
-{
- while (stride--)
- {
- if (*bits != data)
- {
-#ifdef WIN32
- NCD_DEBUG ((DEBUG_FAILURE, "fdValidateBits failed at 0x%x (is 0x%x want 0x%x)",
- bits, *bits, data));
-#else
- fprintf (stderr, "fbValidateBits failed\n");
-#endif
- return FALSE;
- }
- bits++;
- }
-}
-
-void
-fbValidateDrawable (DrawablePtr pDrawable)
-{
- FbStip *bits, *first, *last;
- int stride, bpp;
- int xoff, yoff;
- int height;
- Bool failed;
-
- if (pDrawable->type != DRAWABLE_PIXMAP)
- pDrawable = (DrawablePtr) fbGetWindowPixmap(pDrawable);
- fbGetStipDrawable(pDrawable, bits, stride, bpp, xoff, yoff);
- first = bits - stride;
- last = bits + stride * pDrawable->height;
- if (!fbValidateBits (first, stride, FB_HEAD_BITS) ||
- !fbValidateBits (last, stride, FB_TAIL_BITS))
- fbInitializeDrawable(pDrawable);
- fbFinishAccess (pDrawable);
-}
-
-void
-fbSetBits (FbStip *bits, int stride, FbStip data)
-{
- while (stride--)
- *bits++ = data;
-}
-
-void
-fbInitializeDrawable (DrawablePtr pDrawable)
-{
- FbStip *bits, *first, *last;
- int stride, bpp;
- int xoff, yoff;
-
- fbGetStipDrawable(pDrawable, bits, stride, bpp, xoff, yoff);
- first = bits - stride;
- last = bits + stride * pDrawable->height;
- fbSetBits (first, stride, FB_HEAD_BITS);
- fbSetBits (last, stride, FB_TAIL_BITS);
- fbFinishAccess (pDrawable);
-}
-#endif /* FB_DEBUG */
+/*
+ * Copyright © 1998 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "fb.h"
+
+PixmapPtr
+fbCreatePixmapBpp (ScreenPtr pScreen, int width, int height, int depth, int bpp,
+ unsigned usage_hint)
+{
+ PixmapPtr pPixmap;
+ size_t datasize;
+ size_t paddedWidth;
+ int adjust;
+ int base;
+
+ paddedWidth = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (FbBits);
+ if (paddedWidth / 4 > 32767 || height > 32767)
+ return NullPixmap;
+ datasize = height * paddedWidth;
+ base = pScreen->totalPixmapSize;
+ adjust = 0;
+ if (base & 7)
+ adjust = 8 - (base & 7);
+ datasize += adjust;
+#ifdef FB_DEBUG
+ datasize += 2 * paddedWidth;
+#endif
+ pPixmap = AllocatePixmap(pScreen, datasize);
+ if (!pPixmap)
+ return NullPixmap;
+ pPixmap->drawable.type = DRAWABLE_PIXMAP;
+ pPixmap->drawable.class = 0;
+ pPixmap->drawable.pScreen = pScreen;
+ pPixmap->drawable.depth = depth;
+ pPixmap->drawable.bitsPerPixel = bpp;
+ pPixmap->drawable.id = 0;
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pPixmap->drawable.x = 0;
+ pPixmap->drawable.y = 0;
+ pPixmap->drawable.width = width;
+ pPixmap->drawable.height = height;
+ pPixmap->devKind = paddedWidth;
+ pPixmap->refcnt = 1;
+ pPixmap->devPrivate.ptr = (pointer) ((char *)pPixmap + base + adjust);
+
+#ifdef FB_DEBUG
+ pPixmap->devPrivate.ptr = (void *) ((char *) pPixmap->devPrivate.ptr + paddedWidth);
+ fbInitializeDrawable (&pPixmap->drawable);
+#endif
+
+#ifdef COMPOSITE
+ pPixmap->screen_x = 0;
+ pPixmap->screen_y = 0;
+#endif
+
+ pPixmap->usage_hint = usage_hint;
+
+ return pPixmap;
+}
+
+PixmapPtr
+fbCreatePixmap (ScreenPtr pScreen, int width, int height, int depth,
+ unsigned usage_hint)
+{
+ int bpp;
+ bpp = BitsPerPixel (depth);
+ if (bpp == 32 && depth <= 24)
+ bpp = fbGetScreenPrivate(pScreen)->pix32bpp;
+ return fbCreatePixmapBpp (pScreen, width, height, depth, bpp, usage_hint);
+}
+
+Bool
+fbDestroyPixmap (PixmapPtr pPixmap)
+{
+ if(--pPixmap->refcnt)
+ return TRUE;
+ FreePixmap(pPixmap);
+ return TRUE;
+}
+
+#define ADDRECT(reg,r,fr,rx1,ry1,rx2,ry2) \
+if (((rx1) < (rx2)) && ((ry1) < (ry2)) && \
+ (!((reg)->data->numRects && \
+ ((r-1)->y1 == (ry1)) && \
+ ((r-1)->y2 == (ry2)) && \
+ ((r-1)->x1 <= (rx1)) && \
+ ((r-1)->x2 >= (rx2))))) \
+{ \
+ if ((reg)->data->numRects == (reg)->data->size) \
+ { \
+ RegionRectAlloc(reg, 1); \
+ fr = RegionBoxptr(reg); \
+ r = fr + (reg)->data->numRects; \
+ } \
+ r->x1 = (rx1); \
+ r->y1 = (ry1); \
+ r->x2 = (rx2); \
+ r->y2 = (ry2); \
+ (reg)->data->numRects++; \
+ if(r->x1 < (reg)->extents.x1) \
+ (reg)->extents.x1 = r->x1; \
+ if(r->x2 > (reg)->extents.x2) \
+ (reg)->extents.x2 = r->x2; \
+ r++; \
+}
+
+/* Convert bitmap clip mask into clipping region.
+ * First, goes through each line and makes boxes by noting the transitions
+ * from 0 to 1 and 1 to 0.
+ * Then it coalesces the current line with the previous if they have boxes
+ * at the same X coordinates.
+ */
+RegionPtr
+fbPixmapToRegion(PixmapPtr pPix)
+{
+ register RegionPtr pReg;
+ FbBits *pw, w;
+ register int ib;
+ int width, h, base, rx1 = 0, crects;
+ FbBits *pwLineEnd;
+ int irectPrevStart, irectLineStart;
+ register BoxPtr prectO, prectN;
+ BoxPtr FirstRect, rects, prectLineStart;
+ Bool fInBox, fSame;
+ register FbBits mask0 = FB_ALLONES & ~FbScrRight(FB_ALLONES, 1);
+ FbBits *pwLine;
+ int nWidth;
+
+ pReg = RegionCreate(NULL, 1);
+ if(!pReg)
+ return NullRegion;
+ FirstRect = RegionBoxptr(pReg);
+ rects = FirstRect;
+
+ fbPrepareAccess(&pPix->drawable);
+
+ pwLine = (FbBits *) pPix->devPrivate.ptr;
+ nWidth = pPix->devKind >> (FB_SHIFT-3);
+
+ width = pPix->drawable.width;
+ pReg->extents.x1 = width - 1;
+ pReg->extents.x2 = 0;
+ irectPrevStart = -1;
+ for(h = 0; h < pPix->drawable.height; h++)
+ {
+ pw = pwLine;
+ pwLine += nWidth;
+ irectLineStart = rects - FirstRect;
+ /* If the Screen left most bit of the word is set, we're starting in
+ * a box */
+ if(READ(pw) & mask0)
+ {
+ fInBox = TRUE;
+ rx1 = 0;
+ }
+ else
+ fInBox = FALSE;
+ /* Process all words which are fully in the pixmap */
+ pwLineEnd = pw + (width >> FB_SHIFT);
+ for (base = 0; pw < pwLineEnd; base += FB_UNIT)
+ {
+ w = READ(pw++);
+ if (fInBox)
+ {
+ if (!~w)
+ continue;
+ }
+ else
+ {
+ if (!w)
+ continue;
+ }
+ for(ib = 0; ib < FB_UNIT; ib++)
+ {
+ /* If the Screen left most bit of the word is set, we're
+ * starting a box */
+ if(w & mask0)
+ {
+ if(!fInBox)
+ {
+ rx1 = base + ib;
+ /* start new box */
+ fInBox = TRUE;
+ }
+ }
+ else
+ {
+ if(fInBox)
+ {
+ /* end box */
+ ADDRECT(pReg, rects, FirstRect,
+ rx1, h, base + ib, h + 1);
+ fInBox = FALSE;
+ }
+ }
+ /* Shift the word VISUALLY left one. */
+ w = FbScrLeft(w, 1);
+ }
+ }
+ if(width & FB_MASK)
+ {
+ /* Process final partial word on line */
+ w = READ(pw++);
+ for(ib = 0; ib < (width & FB_MASK); ib++)
+ {
+ /* If the Screen left most bit of the word is set, we're
+ * starting a box */
+ if(w & mask0)
+ {
+ if(!fInBox)
+ {
+ rx1 = base + ib;
+ /* start new box */
+ fInBox = TRUE;
+ }
+ }
+ else
+ {
+ if(fInBox)
+ {
+ /* end box */
+ ADDRECT(pReg, rects, FirstRect,
+ rx1, h, base + ib, h + 1);
+ fInBox = FALSE;
+ }
+ }
+ /* Shift the word VISUALLY left one. */
+ w = FbScrLeft(w, 1);
+ }
+ }
+ /* If scanline ended with last bit set, end the box */
+ if(fInBox)
+ {
+ ADDRECT(pReg, rects, FirstRect,
+ rx1, h, base + (width & FB_MASK), h + 1);
+ }
+ /* if all rectangles on this line have the same x-coords as
+ * those on the previous line, then add 1 to all the previous y2s and
+ * throw away all the rectangles from this line
+ */
+ fSame = FALSE;
+ if(irectPrevStart != -1)
+ {
+ crects = irectLineStart - irectPrevStart;
+ if(crects == ((rects - FirstRect) - irectLineStart))
+ {
+ prectO = FirstRect + irectPrevStart;
+ prectN = prectLineStart = FirstRect + irectLineStart;
+ fSame = TRUE;
+ while(prectO < prectLineStart)
+ {
+ if((prectO->x1 != prectN->x1) || (prectO->x2 != prectN->x2))
+ {
+ fSame = FALSE;
+ break;
+ }
+ prectO++;
+ prectN++;
+ }
+ if (fSame)
+ {
+ prectO = FirstRect + irectPrevStart;
+ while(prectO < prectLineStart)
+ {
+ prectO->y2 += 1;
+ prectO++;
+ }
+ rects -= crects;
+ pReg->data->numRects -= crects;
+ }
+ }
+ }
+ if(!fSame)
+ irectPrevStart = irectLineStart;
+ }
+ if (!pReg->data->numRects)
+ pReg->extents.x1 = pReg->extents.x2 = 0;
+ else
+ {
+ pReg->extents.y1 = RegionBoxptr(pReg)->y1;
+ pReg->extents.y2 = RegionEnd(pReg)->y2;
+ if (pReg->data->numRects == 1)
+ {
+ free(pReg->data);
+ pReg->data = (RegDataPtr)NULL;
+ }
+ }
+
+ fbFinishAccess(&pPix->drawable);
+#ifdef DEBUG
+ if (!RegionIsValid(pReg))
+ FatalError("Assertion failed file %s, line %d: expr\n", __FILE__, __LINE__);
+#endif
+ return pReg;
+}
+
+#ifdef FB_DEBUG
+
+#ifndef WIN32
+#include <stdio.h>
+#else
+#include <dbg.h>
+#endif
+
+static Bool
+fbValidateBits (FbStip *bits, int stride, FbStip data)
+{
+ while (stride--)
+ {
+ if (*bits != data)
+ {
+#ifdef WIN32
+ NCD_DEBUG ((DEBUG_FAILURE, "fdValidateBits failed at 0x%x (is 0x%x want 0x%x)",
+ bits, *bits, data));
+#else
+ fprintf (stderr, "fbValidateBits failed\n");
+#endif
+ return FALSE;
+ }
+ bits++;
+ }
+}
+
+void
+fbValidateDrawable (DrawablePtr pDrawable)
+{
+ FbStip *bits, *first, *last;
+ int stride, bpp;
+ int xoff, yoff;
+ int height;
+ Bool failed;
+
+ if (pDrawable->type != DRAWABLE_PIXMAP)
+ pDrawable = (DrawablePtr) fbGetWindowPixmap(pDrawable);
+ fbGetStipDrawable(pDrawable, bits, stride, bpp, xoff, yoff);
+ first = bits - stride;
+ last = bits + stride * pDrawable->height;
+ if (!fbValidateBits (first, stride, FB_HEAD_BITS) ||
+ !fbValidateBits (last, stride, FB_TAIL_BITS))
+ fbInitializeDrawable(pDrawable);
+ fbFinishAccess (pDrawable);
+}
+
+void
+fbSetBits (FbStip *bits, int stride, FbStip data)
+{
+ while (stride--)
+ *bits++ = data;
+}
+
+void
+fbInitializeDrawable (DrawablePtr pDrawable)
+{
+ FbStip *bits, *first, *last;
+ int stride, bpp;
+ int xoff, yoff;
+
+ fbGetStipDrawable(pDrawable, bits, stride, bpp, xoff, yoff);
+ first = bits - stride;
+ last = bits + stride * pDrawable->height;
+ fbSetBits (first, stride, FB_HEAD_BITS);
+ fbSetBits (last, stride, FB_TAIL_BITS);
+ fbFinishAccess (pDrawable);
+}
+#endif /* FB_DEBUG */