2
* Id: fbgc.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
/* $XdotOrg: xserver/xorg/fb/fbgc.c,v 1.6 2006/01/18 06:49:17 airlied Exp $ */
25
/* $XFree86: xc/programs/Xserver/fb/fbgc.c,v 1.14 2003/12/18 15:22:32 alanh Exp $ */
27
#ifdef HAVE_DIX_CONFIG_H
28
#include <dix-config.h>
33
#include "xf86_ansic.h"
36
const GCFuncs fbGCFuncs = {
46
const GCOps fbGCOps = {
67
#ifdef NEED_LINEHELPER
75
pGC->clientClip = NULL;
76
pGC->clientClipType = CT_NONE;
78
pGC->ops = (GCOps *) &fbGCOps;
79
pGC->funcs = (GCFuncs *) &fbGCFuncs;
81
/* fb wants to translate before scan conversion */
84
fbGetRotatedPixmap(pGC) = 0;
86
fbGetFreeCompClip(pGC) = 0;
87
fbGetCompositeClip(pGC) = 0;
88
fbGetGCPrivate(pGC)->bpp = BitsPerPixel (pGC->depth);
93
* Pad pixmap to FB_UNIT bits wide
96
fbPadPixmap (PixmapPtr pPixmap)
108
fbGetDrawable (&pPixmap->drawable, bits, stride, bpp, xOff, yOff);
110
width = pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel;
111
height = pPixmap->drawable.height;
112
mask = FbBitsMask (0, width);
119
b = b | FbScrRight(b, w);
128
* Verify that 'bits' repeats every 'len' bits
131
fbBitsRepeat (FbBits bits, int len, int width)
133
FbBits mask = FbBitsMask(0, len);
134
FbBits orig = bits & mask;
139
for (i = 0; i < width / len; i++)
141
if ((bits & mask) != orig)
143
bits = FbScrLeft(bits,len);
149
* Check whether an entire bitmap line is a repetition of
150
* the first 'len' bits
153
fbLineRepeat (FbBits *bits, int len, int width)
155
FbBits first = bits[0];
157
if (!fbBitsRepeat (first, len, width))
159
width = (width + FB_UNIT-1) >> FB_SHIFT;
168
* The even stipple code wants the first FB_UNIT/bpp bits on
169
* each scanline to represent the entire stipple
172
fbCanEvenStipple (PixmapPtr pStipple, int bpp)
174
int len = FB_UNIT / bpp;
178
int stipXoff, stipYoff;
181
/* can't even stipple 24bpp drawables */
182
if ((bpp & (bpp-1)) != 0)
184
/* make sure the stipple width is a multiple of the even stipple width */
185
if (pStipple->drawable.width % len != 0)
187
fbGetDrawable (&pStipple->drawable, bits, stride, stip_bpp, stipXoff, stipYoff);
188
h = pStipple->drawable.height;
189
/* check to see that the stipple repeats horizontally */
192
if (!fbLineRepeat (bits, len, pStipple->drawable.width))
200
fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
202
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
205
pGC->lastWinOrg.x = pDrawable->x;
206
pGC->lastWinOrg.y = pDrawable->y;
209
* if the client clip is different or moved OR the subwindowMode has
210
* changed OR the window's clip has changed since the last validation
211
* we need to recompute the composite clip
214
if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) ||
215
(pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
218
miComputeCompositeClip (pGC, pDrawable);
219
pPriv->oneRect = REGION_NUM_RECTS(fbGetCompositeClip(pGC)) == 1;
223
if (pPriv->bpp != pDrawable->bitsPerPixel)
225
changes |= GCStipple|GCForeground|GCBackground|GCPlaneMask;
226
pPriv->bpp = pDrawable->bitsPerPixel;
228
if ((changes & GCTile) && fbGetRotatedPixmap(pGC))
230
(*pGC->pScreen->DestroyPixmap) (fbGetRotatedPixmap(pGC));
231
fbGetRotatedPixmap(pGC) = 0;
234
if (pGC->fillStyle == FillTiled)
236
PixmapPtr pOldTile, pNewTile;
238
pOldTile = pGC->tile.pixmap;
239
if (pOldTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel)
241
pNewTile = fbGetRotatedPixmap(pGC);
242
if (!pNewTile || pNewTile ->drawable.bitsPerPixel != pDrawable->bitsPerPixel)
245
(*pGC->pScreen->DestroyPixmap) (pNewTile);
246
pNewTile = fb24_32ReformatTile (pOldTile, pDrawable->bitsPerPixel);
250
fbGetRotatedPixmap(pGC) = pOldTile;
251
pGC->tile.pixmap = pNewTile;
257
if (changes & GCTile)
259
if (!pGC->tileIsPixel &&
260
FbEvenTile (pGC->tile.pixmap->drawable.width *
261
pDrawable->bitsPerPixel))
262
fbPadPixmap (pGC->tile.pixmap);
264
if (changes & GCStipple)
266
pPriv->evenStipple = FALSE;
270
/* can we do an even stipple ?? */
271
if (FbEvenStip (pGC->stipple->drawable.width,
272
pDrawable->bitsPerPixel) &&
273
(fbCanEvenStipple (pGC->stipple, pDrawable->bitsPerPixel)))
274
pPriv->evenStipple = TRUE;
276
if (pGC->stipple->drawable.width * pDrawable->bitsPerPixel < FB_UNIT)
277
fbPadPixmap (pGC->stipple);
281
* Recompute reduced rop values
283
if (changes & (GCForeground|GCBackground|GCPlaneMask|GCFunction))
288
mask = FbFullMask(pDrawable->bitsPerPixel);
289
depthMask = FbFullMask(pDrawable->depth);
291
pPriv->fg = pGC->fgPixel & mask;
292
pPriv->bg = pGC->bgPixel & mask;
294
if ((pGC->planemask & depthMask) == depthMask)
297
pPriv->pm = pGC->planemask & mask;
299
s = pDrawable->bitsPerPixel;
302
pPriv->fg |= pPriv->fg << s;
303
pPriv->bg |= pPriv->bg << s;
304
pPriv->pm |= pPriv->pm << s;
307
pPriv->and = fbAnd(pGC->alu, pPriv->fg, pPriv->pm);
308
pPriv->xor = fbXor(pGC->alu, pPriv->fg, pPriv->pm);
309
pPriv->bgand = fbAnd(pGC->alu, pPriv->bg, pPriv->pm);
310
pPriv->bgxor = fbXor(pGC->alu, pPriv->bg, pPriv->pm);
312
if (changes & GCDashList)
314
unsigned short n = pGC->numInDashList;
315
unsigned char *dash = pGC->dash;
316
unsigned int dashLength = 0;
319
dashLength += (unsigned int ) *dash++;
320
pPriv->dashLength = dashLength;