1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright © 1998 Keith Packard
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Permission to use, copy, modify, distribute, and sell this software and its
5*4882a593Smuzhiyun * documentation for any purpose is hereby granted without fee, provided that
6*4882a593Smuzhiyun * the above copyright notice appear in all copies and that both that
7*4882a593Smuzhiyun * copyright notice and this permission notice appear in supporting
8*4882a593Smuzhiyun * documentation, and that the name of Keith Packard not be used in
9*4882a593Smuzhiyun * advertising or publicity pertaining to distribution of the software without
10*4882a593Smuzhiyun * specific, written prior permission. Keith Packard makes no
11*4882a593Smuzhiyun * representations about the suitability of this software for any purpose. It
12*4882a593Smuzhiyun * is provided "as is" without express or implied warranty.
13*4882a593Smuzhiyun *
14*4882a593Smuzhiyun * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15*4882a593Smuzhiyun * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16*4882a593Smuzhiyun * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17*4882a593Smuzhiyun * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18*4882a593Smuzhiyun * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19*4882a593Smuzhiyun * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20*4882a593Smuzhiyun * PERFORMANCE OF THIS SOFTWARE.
21*4882a593Smuzhiyun */
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
24*4882a593Smuzhiyun #include <dix-config.h>
25*4882a593Smuzhiyun #endif
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun #include <stdlib.h>
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun #include "fb.h"
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun const GCFuncs fbGCFuncs = {
32*4882a593Smuzhiyun fbValidateGC,
33*4882a593Smuzhiyun miChangeGC,
34*4882a593Smuzhiyun miCopyGC,
35*4882a593Smuzhiyun miDestroyGC,
36*4882a593Smuzhiyun miChangeClip,
37*4882a593Smuzhiyun miDestroyClip,
38*4882a593Smuzhiyun miCopyClip,
39*4882a593Smuzhiyun };
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun const GCOps fbGCOps = {
42*4882a593Smuzhiyun fbFillSpans,
43*4882a593Smuzhiyun fbSetSpans,
44*4882a593Smuzhiyun fbPutImage,
45*4882a593Smuzhiyun fbCopyArea,
46*4882a593Smuzhiyun fbCopyPlane,
47*4882a593Smuzhiyun fbPolyPoint,
48*4882a593Smuzhiyun fbPolyLine,
49*4882a593Smuzhiyun fbPolySegment,
50*4882a593Smuzhiyun fbPolyRectangle,
51*4882a593Smuzhiyun fbPolyArc,
52*4882a593Smuzhiyun miFillPolygon,
53*4882a593Smuzhiyun fbPolyFillRect,
54*4882a593Smuzhiyun fbPolyFillArc,
55*4882a593Smuzhiyun miPolyText8,
56*4882a593Smuzhiyun miPolyText16,
57*4882a593Smuzhiyun miImageText8,
58*4882a593Smuzhiyun miImageText16,
59*4882a593Smuzhiyun fbImageGlyphBlt,
60*4882a593Smuzhiyun fbPolyGlyphBlt,
61*4882a593Smuzhiyun fbPushPixels
62*4882a593Smuzhiyun };
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun Bool
fbCreateGC(GCPtr pGC)65*4882a593Smuzhiyun fbCreateGC(GCPtr pGC)
66*4882a593Smuzhiyun {
67*4882a593Smuzhiyun pGC->ops = (GCOps *) &fbGCOps;
68*4882a593Smuzhiyun pGC->funcs = (GCFuncs *) &fbGCFuncs;
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun /* fb wants to translate before scan conversion */
71*4882a593Smuzhiyun pGC->miTranslate = 1;
72*4882a593Smuzhiyun pGC->fExpose = 1;
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun return TRUE;
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun /*
78*4882a593Smuzhiyun * Pad pixmap to FB_UNIT bits wide
79*4882a593Smuzhiyun */
80*4882a593Smuzhiyun void
fbPadPixmap(PixmapPtr pPixmap)81*4882a593Smuzhiyun fbPadPixmap(PixmapPtr pPixmap)
82*4882a593Smuzhiyun {
83*4882a593Smuzhiyun int width;
84*4882a593Smuzhiyun FbBits *bits;
85*4882a593Smuzhiyun FbBits b;
86*4882a593Smuzhiyun FbBits mask;
87*4882a593Smuzhiyun int height;
88*4882a593Smuzhiyun int w;
89*4882a593Smuzhiyun int stride;
90*4882a593Smuzhiyun int bpp;
91*4882a593Smuzhiyun _X_UNUSED int xOff, yOff;
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun fbGetDrawable(&pPixmap->drawable, bits, stride, bpp, xOff, yOff);
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun width = pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel;
96*4882a593Smuzhiyun height = pPixmap->drawable.height;
97*4882a593Smuzhiyun mask = FbBitsMask(0, width);
98*4882a593Smuzhiyun while (height--) {
99*4882a593Smuzhiyun b = READ(bits) & mask;
100*4882a593Smuzhiyun w = width;
101*4882a593Smuzhiyun while (w < FB_UNIT) {
102*4882a593Smuzhiyun b = b | FbScrRight(b, w);
103*4882a593Smuzhiyun w <<= 1;
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun WRITE(bits, b);
106*4882a593Smuzhiyun bits += stride;
107*4882a593Smuzhiyun }
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun fbFinishAccess(&pPixmap->drawable);
110*4882a593Smuzhiyun }
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun void
fbValidateGC(GCPtr pGC,unsigned long changes,DrawablePtr pDrawable)113*4882a593Smuzhiyun fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
114*4882a593Smuzhiyun {
115*4882a593Smuzhiyun FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
116*4882a593Smuzhiyun FbBits mask;
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun /*
119*4882a593Smuzhiyun * if the client clip is different or moved OR the subwindowMode has
120*4882a593Smuzhiyun * changed OR the window's clip has changed since the last validation
121*4882a593Smuzhiyun * we need to recompute the composite clip
122*4882a593Smuzhiyun */
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun if ((changes &
125*4882a593Smuzhiyun (GCClipXOrigin | GCClipYOrigin | GCClipMask | GCSubwindowMode)) ||
126*4882a593Smuzhiyun (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
127*4882a593Smuzhiyun ) {
128*4882a593Smuzhiyun miComputeCompositeClip(pGC, pDrawable);
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun if (changes & GCTile) {
132*4882a593Smuzhiyun if (!pGC->tileIsPixel &&
133*4882a593Smuzhiyun FbEvenTile(pGC->tile.pixmap->drawable.width *
134*4882a593Smuzhiyun pDrawable->bitsPerPixel))
135*4882a593Smuzhiyun fbPadPixmap(pGC->tile.pixmap);
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun if (changes & GCStipple) {
138*4882a593Smuzhiyun if (pGC->stipple) {
139*4882a593Smuzhiyun if (pGC->stipple->drawable.width * pDrawable->bitsPerPixel <
140*4882a593Smuzhiyun FB_UNIT)
141*4882a593Smuzhiyun fbPadPixmap(pGC->stipple);
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun /*
145*4882a593Smuzhiyun * Recompute reduced rop values
146*4882a593Smuzhiyun */
147*4882a593Smuzhiyun if (changes & (GCForeground | GCBackground | GCPlaneMask | GCFunction)) {
148*4882a593Smuzhiyun int s;
149*4882a593Smuzhiyun FbBits depthMask;
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun mask = FbFullMask(pDrawable->bitsPerPixel);
152*4882a593Smuzhiyun depthMask = FbFullMask(pDrawable->depth);
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun pPriv->fg = pGC->fgPixel & mask;
155*4882a593Smuzhiyun pPriv->bg = pGC->bgPixel & mask;
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun if ((pGC->planemask & depthMask) == depthMask)
158*4882a593Smuzhiyun pPriv->pm = mask;
159*4882a593Smuzhiyun else
160*4882a593Smuzhiyun pPriv->pm = pGC->planemask & mask;
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun s = pDrawable->bitsPerPixel;
163*4882a593Smuzhiyun while (s < FB_UNIT) {
164*4882a593Smuzhiyun pPriv->fg |= pPriv->fg << s;
165*4882a593Smuzhiyun pPriv->bg |= pPriv->bg << s;
166*4882a593Smuzhiyun pPriv->pm |= pPriv->pm << s;
167*4882a593Smuzhiyun s <<= 1;
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun pPriv->and = fbAnd(pGC->alu, pPriv->fg, pPriv->pm);
170*4882a593Smuzhiyun pPriv->xor = fbXor(pGC->alu, pPriv->fg, pPriv->pm);
171*4882a593Smuzhiyun pPriv->bgand = fbAnd(pGC->alu, pPriv->bg, pPriv->pm);
172*4882a593Smuzhiyun pPriv->bgxor = fbXor(pGC->alu, pPriv->bg, pPriv->pm);
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun if (changes & GCDashList) {
175*4882a593Smuzhiyun unsigned short n = pGC->numInDashList;
176*4882a593Smuzhiyun unsigned char *dash = pGC->dash;
177*4882a593Smuzhiyun unsigned int dashLength = 0;
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun while (n--)
180*4882a593Smuzhiyun dashLength += (unsigned int) *dash++;
181*4882a593Smuzhiyun pPriv->dashLength = dashLength;
182*4882a593Smuzhiyun }
183*4882a593Smuzhiyun }
184