2
* Id: fbpixmap.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
4
* Copyright � 1998 Keith Packard
6
* Permission to use, copy, modify, distribute, and sell this software and its
7
* documentation for any purpose is hereby granted without fee, provided that
8
* the above copyright notice appear in all copies and that both that
9
* copyright notice and this permission notice appear in supporting
10
* documentation, and that the name of Keith Packard not be used in
11
* advertising or publicity pertaining to distribution of the software without
12
* specific, written prior permission. Keith Packard makes no
13
* representations about the suitability of this software for any purpose. It
14
* is provided "as is" without express or implied warranty.
16
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22
* PERFORMANCE OF THIS SOFTWARE.
24
/* $XFree86: xc/programs/Xserver/fb/fbpixmap.c,v 1.11 2002/09/16 18:05:34 eich Exp $ */
28
#include "xf86_ansic.h"
32
fbCreatePixmapBpp (ScreenPtr pScreen, int width, int height, int depth, int bpp)
40
paddedWidth = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (FbBits);
41
datasize = height * paddedWidth;
43
base = pScreen->totalPixmapSize;
45
base = sizeof (PixmapRec);
49
adjust = 8 - (base & 7);
52
datasize += 2 * paddedWidth;
54
pPixmap = AllocatePixmap(pScreen, datasize);
57
pPixmap->drawable.type = DRAWABLE_PIXMAP;
58
pPixmap->drawable.class = 0;
59
pPixmap->drawable.pScreen = pScreen;
60
pPixmap->drawable.depth = depth;
61
pPixmap->drawable.bitsPerPixel = bpp;
62
pPixmap->drawable.id = 0;
63
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
64
pPixmap->drawable.x = 0;
65
pPixmap->drawable.y = 0;
66
pPixmap->drawable.width = width;
67
pPixmap->drawable.height = height;
68
pPixmap->devKind = paddedWidth;
70
pPixmap->devPrivate.ptr = (pointer) ((char *)pPixmap + base + adjust);
72
pPixmap->devPrivate.ptr = (void *) ((char *) pPixmap->devPrivate.ptr + paddedWidth);
73
fbInitializeDrawable (&pPixmap->drawable);
80
fbCreatePixmap (ScreenPtr pScreen, int width, int height, int depth)
83
bpp = BitsPerPixel (depth);
84
#ifdef FB_SCREEN_PRIVATE
85
if (bpp == 32 && depth <= 24)
86
bpp = fbGetScreenPrivate(pScreen)->pix32bpp;
88
return fbCreatePixmapBpp (pScreen, width, height, depth, bpp);
92
fbDestroyPixmap (PixmapPtr pPixmap)
100
#define ADDRECT(reg,r,fr,rx1,ry1,rx2,ry2) \
101
if (((rx1) < (rx2)) && ((ry1) < (ry2)) && \
102
(!((reg)->data->numRects && \
103
((r-1)->y1 == (ry1)) && \
104
((r-1)->y2 == (ry2)) && \
105
((r-1)->x1 <= (rx1)) && \
106
((r-1)->x2 >= (rx2))))) \
108
if ((reg)->data->numRects == (reg)->data->size) \
110
miRectAlloc(reg, 1); \
111
fr = REGION_BOXPTR(reg); \
112
r = fr + (reg)->data->numRects; \
118
(reg)->data->numRects++; \
119
if(r->x1 < (reg)->extents.x1) \
120
(reg)->extents.x1 = r->x1; \
121
if(r->x2 > (reg)->extents.x2) \
122
(reg)->extents.x2 = r->x2; \
126
/* Convert bitmap clip mask into clipping region.
127
* First, goes through each line and makes boxes by noting the transitions
128
* from 0 to 1 and 1 to 0.
129
* Then it coalesces the current line with the previous if they have boxes
130
* at the same X coordinates.
133
fbPixmapToRegion(PixmapPtr pPix)
135
register RegionPtr pReg;
138
int width, h, base, rx1 = 0, crects;
140
int irectPrevStart, irectLineStart;
141
register BoxPtr prectO, prectN;
142
BoxPtr FirstRect, rects, prectLineStart;
144
register FbBits mask0 = FB_ALLONES & ~FbScrRight(FB_ALLONES, 1);
148
pReg = REGION_CREATE(pPix->drawable.pScreen, NULL, 1);
151
FirstRect = REGION_BOXPTR(pReg);
154
pwLine = (FbBits *) pPix->devPrivate.ptr;
155
nWidth = pPix->devKind >> (FB_SHIFT-3);
157
width = pPix->drawable.width;
158
pReg->extents.x1 = width - 1;
159
pReg->extents.x2 = 0;
161
for(h = 0; h < pPix->drawable.height; h++)
165
irectLineStart = rects - FirstRect;
166
/* If the Screen left most bit of the word is set, we're starting in
175
/* Process all words which are fully in the pixmap */
176
pwLineEnd = pw + (width >> FB_SHIFT);
177
for (base = 0; pw < pwLineEnd; base += FB_UNIT)
190
for(ib = 0; ib < FB_UNIT; ib++)
192
/* If the Screen left most bit of the word is set, we're
208
ADDRECT(pReg, rects, FirstRect,
209
rx1, h, base + ib, h + 1);
213
/* Shift the word VISUALLY left one. */
219
/* Process final partial word on line */
221
for(ib = 0; ib < (width & FB_MASK); ib++)
223
/* If the Screen left most bit of the word is set, we're
239
ADDRECT(pReg, rects, FirstRect,
240
rx1, h, base + ib, h + 1);
244
/* Shift the word VISUALLY left one. */
248
/* If scanline ended with last bit set, end the box */
251
ADDRECT(pReg, rects, FirstRect,
252
rx1, h, base + (width & FB_MASK), h + 1);
254
/* if all rectangles on this line have the same x-coords as
255
* those on the previous line, then add 1 to all the previous y2s and
256
* throw away all the rectangles from this line
259
if(irectPrevStart != -1)
261
crects = irectLineStart - irectPrevStart;
262
if(crects == ((rects - FirstRect) - irectLineStart))
264
prectO = FirstRect + irectPrevStart;
265
prectN = prectLineStart = FirstRect + irectLineStart;
267
while(prectO < prectLineStart)
269
if((prectO->x1 != prectN->x1) || (prectO->x2 != prectN->x2))
279
prectO = FirstRect + irectPrevStart;
280
while(prectO < prectLineStart)
286
pReg->data->numRects -= crects;
291
irectPrevStart = irectLineStart;
293
if (!pReg->data->numRects)
294
pReg->extents.x1 = pReg->extents.x2 = 0;
297
pReg->extents.y1 = REGION_BOXPTR(pReg)->y1;
298
pReg->extents.y2 = REGION_END(pReg)->y2;
299
if (pReg->data->numRects == 1)
302
pReg->data = (RegDataPtr)NULL;
306
if (!miValidRegion(pReg))
307
FatalError("Assertion failed file %s, line %d: expr\n", __FILE__, __LINE__);
321
fbValidateBits (FbStip *bits, int stride, FbStip data)
328
NCD_DEBUG ((DEBUG_FAILURE, "fdValidateBits failed at 0x%x (is 0x%x want 0x%x)",
331
fprintf (stderr, "fbValidateBits failed\n");
340
fbValidateDrawable (DrawablePtr pDrawable)
342
FbStip *bits, *first, *last;
348
if (pDrawable->type != DRAWABLE_PIXMAP)
349
pDrawable = (DrawablePtr) fbGetWindowPixmap(pDrawable);
350
fbGetStipDrawable(pDrawable, bits, stride, bpp, xoff, yoff);
351
first = bits - stride;
352
last = bits + stride * pDrawable->height;
353
if (!fbValidateBits (first, stride, FB_HEAD_BITS) ||
354
!fbValidateBits (last, stride, FB_TAIL_BITS))
355
fbInitializeDrawable(pDrawable);
359
fbSetBits (FbStip *bits, int stride, FbStip data)
366
fbInitializeDrawable (DrawablePtr pDrawable)
368
FbStip *bits, *first, *last;
372
fbGetStipDrawable(pDrawable, bits, stride, bpp, xoff, yoff);
373
first = bits - stride;
374
last = bits + stride * pDrawable->height;
375
fbSetBits (first, stride, FB_HEAD_BITS);
376
fbSetBits (last, stride, FB_TAIL_BITS);
378
#endif /* FB_DEBUG */