2
* Id: s3draw.c,v 1.1 1999/11/02 03:54:47 keithp Exp $
4
* Copyright 1999 SuSE, Inc.
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 SuSE not be used in advertising or
11
* publicity pertaining to distribution of the software without specific,
12
* written prior permission. SuSE makes no representations about the
13
* suitability of this software for any purpose. It is provided "as is"
14
* without express or implied warranty.
16
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
18
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
* Author: Keith Packard, SuSE, Inc.
25
/* $RCSId: xc/programs/Xserver/hw/kdrive/savage/s3draw.c,v 1.6 2001/05/29 04:54:11 keithp Exp $ */
28
#include <kdrive-config.h>
35
#include "scrnintstr.h"
36
#include "pixmapstr.h"
37
#include "regionstr.h"
39
#include "fontstruct.h"
40
#include "dixfontstr.h"
46
* Map X rops to S3 rops
69
* Handle pixel transfers
74
#define PixTransDeclare VOL32 *pix_trans_base = (VOL32 *) (s3c->registers),\
75
*pix_trans = pix_trans_base
76
#define PixTransStart(n) if (pix_trans + (n) > pix_trans_base + 8192) pix_trans = pix_trans_base
77
#define PixTransStore(t) *pix_trans++ = (t)
79
#define PixTransDeclare VOL32 *pix_trans = &s3->pix_trans
80
#define PixTransStart(n)
81
#define PixTransStore(t) *pix_trans = (t)
85
int s3WindowPrivateIndex;
91
Bit Blit for all window to window blits.
94
#define sourceInvarient(alu) (((alu) & 3) == (((alu) >> 2) & 3))
97
s3CopyNtoN (DrawablePtr pSrcDrawable,
98
DrawablePtr pDstDrawable,
109
SetupS3(pDstDrawable->pScreen);
110
int srcX, srcY, dstX, dstY;
114
if (sourceInvarient (pGC->alu))
116
s3FillBoxSolid (pDstDrawable, nbox, pbox, 0, pGC->alu, pGC->planemask);
120
s3SetGlobalBitmap (pDstDrawable->pScreen, s3GCMap (pGC));
121
_s3SetBlt(s3,pGC->alu,pGC->planemask);
122
DRAW_DEBUG ((DEBUG_RENDER, "s3CopyNtoN alu %d planemask 0x%x",
123
pGC->alu, pGC->planemask));
126
w = pbox->x2 - pbox->x1;
127
h = pbox->y2 - pbox->y1;
151
_s3Blt (s3, srcX, srcY, dstX, dstY, w, h, flags);
154
MarkSyncS3 (pSrcDrawable->pScreen);
158
s3CopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
159
int srcx, int srcy, int width, int height, int dstx, int dsty)
161
SetupS3(pDstDrawable->pScreen);
163
if (pSrcDrawable->type == DRAWABLE_WINDOW &&
164
pDstDrawable->type == DRAWABLE_WINDOW)
166
return fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
167
srcx, srcy, width, height,
168
dstx, dsty, s3CopyNtoN, 0, 0);
170
return KdCheckCopyArea (pSrcDrawable, pDstDrawable, pGC,
171
srcx, srcy, width, height, dstx, dsty);
174
typedef struct _s31toNargs {
175
unsigned long copyPlaneFG, copyPlaneBG;
180
_s3Stipple (S3CardInfo *s3c,
191
FbStip *psrcLine, *psrc;
193
FbStip bits, tmp, lastTmp;
194
int leftShift, rightShift;
199
/* Compute blt address and parameters */
200
psrc = psrcBase + srcy * widthSrc + (srcx >> 5);
201
nlMiddle = (width + 31) >> 5;
202
leftShift = srcx & 0x1f;
203
rightShift = 32 - leftShift;
204
widthRest = widthSrc - nlMiddle;
206
_s3PlaneBlt(s3,dstx,dsty,width,height);
217
S3AdjustBits32 (tmp);
233
tmp = FbStipLeft(bits, leftShift);
235
tmp |= FbStipRight(bits, rightShift);
245
s3Copy1toN (DrawablePtr pSrcDrawable,
246
DrawablePtr pDstDrawable,
257
SetupS3(pDstDrawable->pScreen);
259
s31toNargs *args = closure;
264
int srcXoff, srcYoff;
266
if (args->opaque && sourceInvarient (pGC->alu))
268
s3FillBoxSolid (pDstDrawable, nbox, pbox,
269
pGC->bgPixel, pGC->alu, pGC->planemask);
273
s3SetGlobalBitmap (pDstDrawable->pScreen, s3GCMap (pGC));
274
fbGetStipDrawable (pSrcDrawable, psrcBase, widthSrc, srcBpp, srcXoff, srcYoff);
278
_s3SetOpaquePlaneBlt(s3,pGC->alu,pGC->planemask,args->copyPlaneFG,
283
_s3SetTransparentPlaneBlt (s3, pGC->alu,
284
pGC->planemask, args->copyPlaneFG);
294
dstx + dx - srcXoff, dsty + dy - srcYoff,
296
pbox->x2 - dstx, pbox->y2 - dsty);
299
MarkSyncS3 (pDstDrawable->pScreen);
303
s3CopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
304
int srcx, int srcy, int width, int height,
305
int dstx, int dsty, unsigned long bitPlane)
307
SetupS3 (pDstDrawable->pScreen);
311
if (pDstDrawable->type == DRAWABLE_WINDOW &&
312
pSrcDrawable->depth == 1)
314
args.copyPlaneFG = pGC->fgPixel;
315
args.copyPlaneBG = pGC->bgPixel;
317
return fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
318
srcx, srcy, width, height,
319
dstx, dsty, s3Copy1toN, bitPlane, &args);
321
return KdCheckCopyPlane(pSrcDrawable, pDstDrawable, pGC,
322
srcx, srcy, width, height,
323
dstx, dsty, bitPlane);
327
s3PushPixels (GCPtr pGC, PixmapPtr pBitmap,
328
DrawablePtr pDrawable,
329
int w, int h, int x, int y)
331
SetupS3 (pDrawable->pScreen);
334
if (pDrawable->type == DRAWABLE_WINDOW && pGC->fillStyle == FillSolid)
337
args.copyPlaneFG = pGC->fgPixel;
338
(void) fbDoCopy ((DrawablePtr) pBitmap, pDrawable, pGC,
339
0, 0, w, h, x, y, s3Copy1toN, 1, &args);
343
KdCheckPushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
348
s3FillBoxSolid (DrawablePtr pDrawable, int nBox, BoxPtr pBox,
349
unsigned long pixel, int alu, unsigned long planemask)
351
SetupS3(pDrawable->pScreen);
354
s3SetGlobalBitmap (pDrawable->pScreen, s3DrawMap (pDrawable));
355
_s3SetSolidFill(s3,pixel,alu,planemask);
358
_s3SolidRect(s3,pBox->x1,pBox->y1,pBox->x2-pBox->x1,pBox->y2-pBox->y1);
361
MarkSyncS3 (pDrawable->pScreen);
365
_s3SetPattern (ScreenPtr pScreen, int ma,
366
int alu, unsigned long planemask, s3PatternPtr pPattern)
369
S3PatternCache *cache;
371
_s3LoadPattern (pScreen, ma, pPattern);
372
cache = pPattern->cache;
374
switch (pPattern->fillStyle) {
376
_s3SetTile(s3,alu,planemask);
379
_s3SetStipple(s3,alu,planemask,pPattern->fore);
381
case FillOpaqueStippled:
382
_s3SetOpaqueStipple(s3,alu,planemask,pPattern->fore,pPattern->back);
388
s3FillBoxPattern (DrawablePtr pDrawable, int nBox, BoxPtr pBox,
389
int alu, unsigned long planemask, s3PatternPtr pPattern)
391
SetupS3(pDrawable->pScreen);
392
S3PatternCache *cache;
395
s3SetGlobalBitmap (pDrawable->pScreen, s3DrawMap (pDrawable));
396
_s3SetPattern (pDrawable->pScreen, s3DrawMap(pDrawable), alu, planemask, pPattern);
397
cache = pPattern->cache;
400
_s3PatRect(s3,cache->x, cache->y,
402
pBox->x2-pBox->x1, pBox->y2-pBox->y1);
405
MarkSyncS3 (pDrawable->pScreen);
409
s3FillBoxLargeStipple (DrawablePtr pDrawable, GCPtr pGC,
410
int nBox, BoxPtr pBox)
412
SetupS3(pDrawable->pScreen);
413
DrawablePtr pStipple = &pGC->stipple->drawable;
414
int xRot = pGC->patOrg.x + pDrawable->x;
415
int yRot = pGC->patOrg.y + pDrawable->y;
419
int stipXoff, stipYoff;
420
int stipWidth, stipHeight;
421
int dstX, dstY, width, height;
423
stipWidth = pStipple->width;
424
stipHeight = pStipple->height;
425
fbGetStipDrawable (pStipple, stip, stipStride, stipBpp, stipXoff, stipYoff);
427
s3SetGlobalBitmap (pDrawable->pScreen, s3DrawMap (pDrawable));
428
if (pGC->fillStyle == FillOpaqueStippled)
430
_s3SetOpaquePlaneBlt(s3,pGC->alu,pGC->planemask,
431
pGC->fgPixel, pGC->bgPixel);
436
_s3SetTransparentPlaneBlt(s3,pGC->alu,pGC->planemask, pGC->fgPixel);
441
int stipX, stipY, sx;
448
width = pBox->x2 - pBox->x1;
449
height = pBox->y2 - pBox->y1;
451
modulus (dstY - yRot - stipYoff, stipHeight, stipY);
452
modulus (dstX - xRot - stipXoff, stipWidth, stipX);
456
h = stipHeight - stipY;
465
w = (stipWidth - sx);
482
MarkSyncS3 (pDrawable->pScreen);
485
#define NUM_STACK_RECTS 1024
488
s3PolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
489
int nrectFill, xRectangle *prectInit)
494
register BoxPtr pbox;
495
register BoxPtr pboxClipped;
496
BoxPtr pboxClippedBase;
498
BoxRec stackRects[NUM_STACK_RECTS];
504
prgnClip = fbGetCompositeClip(pGC);
522
numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
523
if (numRects > NUM_STACK_RECTS)
525
pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec));
526
if (!pboxClippedBase)
530
pboxClippedBase = stackRects;
532
pboxClipped = pboxClippedBase;
534
if (REGION_NUM_RECTS(prgnClip) == 1)
536
int x1, y1, x2, y2, bx2, by2;
538
pextent = REGION_RECTS(prgnClip);
545
if ((pboxClipped->x1 = prect->x) < x1)
546
pboxClipped->x1 = x1;
548
if ((pboxClipped->y1 = prect->y) < y1)
549
pboxClipped->y1 = y1;
551
bx2 = (int) prect->x + (int) prect->width;
554
pboxClipped->x2 = bx2;
556
by2 = (int) prect->y + (int) prect->height;
559
pboxClipped->y2 = by2;
562
if ((pboxClipped->x1 < pboxClipped->x2) &&
563
(pboxClipped->y1 < pboxClipped->y2))
571
int x1, y1, x2, y2, bx2, by2;
573
pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
582
if ((box.x1 = prect->x) < x1)
585
if ((box.y1 = prect->y) < y1)
588
bx2 = (int) prect->x + (int) prect->width;
593
by2 = (int) prect->y + (int) prect->height;
600
if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
603
n = REGION_NUM_RECTS (prgnClip);
604
pbox = REGION_RECTS(prgnClip);
606
/* clip the rectangle to each box in the clip region
607
this is logically equivalent to calling Intersect()
611
pboxClipped->x1 = max(box.x1, pbox->x1);
612
pboxClipped->y1 = max(box.y1, pbox->y1);
613
pboxClipped->x2 = min(box.x2, pbox->x2);
614
pboxClipped->y2 = min(box.y2, pbox->y2);
617
/* see if clipping left anything */
618
if(pboxClipped->x1 < pboxClipped->x2 &&
619
pboxClipped->y1 < pboxClipped->y2)
626
if (pboxClipped != pboxClippedBase)
628
if (pGC->fillStyle == FillSolid)
629
s3FillBoxSolid(pDrawable,
630
pboxClipped-pboxClippedBase, pboxClippedBase,
631
pGC->fgPixel, pGC->alu, pGC->planemask);
632
else if (s3Priv->pPattern)
633
s3FillBoxPattern (pDrawable,
634
pboxClipped-pboxClippedBase, pboxClippedBase,
635
pGC->alu, pGC->planemask,
638
s3FillBoxLargeStipple (pDrawable, pGC,
639
pboxClipped-pboxClippedBase,
642
if (pboxClippedBase != stackRects)
643
DEALLOCATE_LOCAL(pboxClippedBase);
647
_s3FillSpanLargeStipple (DrawablePtr pDrawable, GCPtr pGC,
648
int n, DDXPointPtr ppt, int *pwidth)
650
SetupS3 (pDrawable->pScreen);
651
DrawablePtr pStipple = &pGC->stipple->drawable;
652
int xRot = pGC->patOrg.x + pDrawable->x;
653
int yRot = pGC->patOrg.y + pDrawable->y;
657
int stipXoff, stipYoff;
658
int stipWidth, stipHeight;
659
int dstX, dstY, width, height;
661
s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
662
stipWidth = pStipple->width;
663
stipHeight = pStipple->height;
664
fbGetStipDrawable (pStipple, stip, stipStride, stipBpp, stipXoff, stipYoff);
665
if (pGC->fillStyle == FillOpaqueStippled)
667
_s3SetOpaquePlaneBlt(s3,pGC->alu,pGC->planemask,
668
pGC->fgPixel, pGC->bgPixel);
673
_s3SetTransparentPlaneBlt(s3,pGC->alu,pGC->planemask, pGC->fgPixel);
677
int stipX, stipY, sx;
685
modulus (dstY - yRot - stipYoff, stipHeight, stipY);
686
modulus (dstX - xRot - stipXoff, stipWidth, stipX);
692
w = (stipWidth - sx);
709
s3FillSpans (DrawablePtr pDrawable, GCPtr pGC, int n,
710
DDXPointPtr ppt, int *pwidth, int fSorted)
713
SetupS3(pDrawable->pScreen);
714
int x, y, x1, y1, x2, y2;
716
/* next three parameters are post-clip */
718
int *pwidthFree;/* copies of the pointers to free */
721
S3PatternCache *cache;
722
RegionPtr pClip = fbGetCompositeClip (pGC);
724
s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
725
if (REGION_NUM_RECTS(pClip) == 1 &&
726
(pGC->fillStyle == FillSolid || s3Priv->pPattern))
728
extents = REGION_RECTS(pClip);
733
if (pGC->fillStyle == FillSolid)
735
_s3SetSolidFill(s3,pGC->fgPixel,pGC->alu,pGC->planemask);
740
_s3SetPattern (pDrawable->pScreen, s3GCMap(pGC), pGC->alu, pGC->planemask,
742
cache = s3Priv->pPattern->cache;
747
if (y1 <= y && y < y2)
762
_s3PatRect(s3, cache->x, cache->y, x, y, width, 1);
766
_s3SolidRect(s3,x,y,width,1);
776
nTmp = n * miFindMaxBand(pClip);
777
pwidthFree = (int *)ALLOCATE_LOCAL(nTmp * sizeof(int));
778
pptFree = (DDXPointRec *)ALLOCATE_LOCAL(nTmp * sizeof(DDXPointRec));
779
if(!pptFree || !pwidthFree)
781
if (pptFree) DEALLOCATE_LOCAL(pptFree);
782
if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
785
n = miClipSpans(fbGetCompositeClip(pGC),
787
pptFree, pwidthFree, fSorted);
790
if (pGC->fillStyle == FillSolid)
792
_s3SetSolidFill(s3,pGC->fgPixel,pGC->alu,pGC->planemask);
801
_s3SolidRect(s3,x,y,width,1);
805
else if (s3Priv->pPattern)
807
_s3SetPattern (pDrawable->pScreen, s3GCMap(pGC), pGC->alu, pGC->planemask,
809
cache = s3Priv->pPattern->cache;
818
_s3PatRect(s3, cache->x, cache->y, x, y, width, 1);
824
_s3FillSpanLargeStipple (pDrawable, pGC, n, ppt, pwidth);
826
DEALLOCATE_LOCAL(pptFree);
827
DEALLOCATE_LOCAL(pwidthFree);
829
MarkSyncS3 (pDrawable->pScreen);
832
#include "mifillarc.h"
834
#define FILLSPAN(s3,y,__x1,__x2) {\
835
DRAW_DEBUG ((DEBUG_ARCS, "FILLSPAN %d: %d->%d", y, __x1, __x2)); \
836
if ((__x2) >= (__x1)) {\
837
_s3SolidRect(s3,(__x1),(y),(__x2)-(__x1)+1,1); \
841
#define FILLSLICESPANS(flip,__y) \
844
FILLSPAN(s3,__y,xl,xr) \
849
FILLSPAN(s3, __y, xc, xr) \
851
FILLSPAN(s3, __y, xl, xc) \
855
_s3FillEllipse (DrawablePtr pDraw, S3Ptr s3, xArc *arc)
857
KdScreenPriv(pDraw->pScreen);
859
int yk, xk, ym, xm, dx, dy, xorg, yorg;
865
s3SetGlobalBitmap (pDraw->pScreen, s3DrawMap (pDraw));
866
miFillArcSetup(arc, &info);
868
y_top = pDraw->y + yorg - y;
869
y_bot = pDraw->y + yorg + y + dy;
879
_s3SolidRect (s3,xpos,y_top,slw,1);
880
if (miFillArcLower(slw))
881
_s3SolidRect (s3,xpos,y_bot,slw,1);
887
_s3FillArcSlice (DrawablePtr pDraw, GCPtr pGC, S3Ptr s3, xArc *arc)
889
KdScreenPriv(pDraw->pScreen);
890
int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
891
register int x, y, e;
897
s3SetGlobalBitmap (pDraw->pScreen, s3DrawMap (pDraw));
898
DRAW_DEBUG ((DEBUG_ARCS, "slice %dx%d+%d+%d %d->%d",
899
arc->width, arc->height, arc->x, arc->y,
900
arc->angle1, arc->angle2));
901
miFillArcSetup(arc, &info);
902
miFillArcSliceSetup(arc, &slice, pGC);
903
DRAW_DEBUG ((DEBUG_ARCS, "edge1.x %d edge2.x %d",
904
slice.edge1.x, slice.edge2.x));
906
DRAW_DEBUG ((DEBUG_ARCS, "xorg %d yorg %d",
911
y_bot = yorg + y + dy;
912
slice.edge1.x += pDraw->x;
913
slice.edge2.x += pDraw->x;
914
DRAW_DEBUG ((DEBUG_ARCS, "xorg %d y_top %d y_bot %d",
915
xorg, y_top, y_bot));
921
MIARCSLICESTEP(slice.edge1);
922
MIARCSLICESTEP(slice.edge2);
923
if (miFillSliceUpper(slice))
925
MIARCSLICEUPPER(xl, xr, slice, slw);
926
FILLSLICESPANS(slice.flip_top, y_top);
928
if (miFillSliceLower(slice))
930
MIARCSLICELOWER(xl, xr, slice, slw);
931
FILLSLICESPANS(slice.flip_bot, y_bot);
937
s3PolyFillArcSolid (DrawablePtr pDraw, GCPtr pGC, int narcs, xArc *parcs)
939
SetupS3(pDraw->pScreen);
944
RegionPtr pClip = fbGetCompositeClip(pGC);
948
for (; --narcs >= 0; parcs++)
950
if (miFillArcEmpty(parcs))
952
if (miCanFillArc(parcs))
954
box.x1 = parcs->x + pDraw->x;
955
box.y1 = parcs->y + pDraw->y;
956
box.x2 = box.x1 + (int)parcs->width + 1;
957
box.y2 = box.y1 + (int)parcs->height + 1;
958
switch (RECT_IN_REGION(pDraw->pScreen, pClip, &box))
963
_s3SetSolidFill (s3, pGC->fgPixel, pGC->alu, pGC->planemask);
966
if ((parcs->angle2 >= FULLCIRCLE) ||
967
(parcs->angle2 <= -FULLCIRCLE))
969
DRAW_DEBUG ((DEBUG_ARCS, "Full circle ellipse %dx%d",
970
parcs->width, parcs->height));
971
_s3FillEllipse (pDraw, s3, parcs);
975
DRAW_DEBUG ((DEBUG_ARCS, "Partial ellipse %dx%d",
976
parcs->width, parcs->height));
977
_s3FillArcSlice (pDraw, pGC, s3, parcs);
979
/* fall through ... */
988
MarkSyncS3 (pDraw->pScreen);
991
KdCheckPolyFillArc(pDraw, pGC, 1, parcs);
995
MarkSyncS3 (pDraw->pScreen);
1001
s3FillPoly (DrawablePtr pDrawable, GCPtr pGC, int shape,
1002
int mode, int countInit, DDXPointPtr ptsIn)
1004
SetupS3(pDrawable->pScreen);
1009
register int vertex1, vertex2;
1011
RegionPtr pClip = fbGetCompositeClip(pGC);
1015
int *vertex1p, *vertex2p;
1027
if (mode == CoordModePrevious || REGION_NUM_RECTS(pClip) != 1)
1029
KdCheckFillPolygon (pDrawable, pGC, shape, mode, countInit, ptsIn);
1033
s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
1036
origin = *((int *) &pDrawable->x);
1037
origin -= (origin & 0x8000) << 1;
1038
extents = &pClip->extents;
1039
vertex1 = *((int *) &extents->x1) - origin;
1040
vertex2 = *((int *) &extents->x2) - origin - 0x00010001;
1045
vertex2p = (int *) ptsIn;
1046
endp = vertex2p + countInit;
1047
if (shape == Convex)
1053
clip |= (c - vertex1) | (vertex2 - c);
1055
DRAW_DEBUG ((DEBUG_POLYGON, "Y coordinate %d", c));
1059
vertex1p = vertex2p;
1076
clip |= (c - vertex1) | (vertex2 - c);
1078
DRAW_DEBUG ((DEBUG_POLYGON, "Y coordinate %d", c));
1082
vertex1p = vertex2p;
1094
dx2 = dx1 = (c - x1) >> 31;
1097
if ((c - x1) >> 31 != dx1)
1104
x1 = (x2 - c) >> 31;
1115
if (clip & 0x80008000)
1117
KdCheckFillPolygon (pDrawable, pGC, shape, mode, countInit, ptsIn);
1120
_s3SetSolidFill(s3,pGC->fgPixel,pGC->alu,pGC->planemask);
1122
vertex2p = vertex1p;
1123
vertex2 = vertex1 = *vertex2p++;
1124
if (vertex2p == endp)
1125
vertex2p = (int *) ptsIn;
1126
#define Setup(c,x,vertex,dx,dy,e,sign,step) {\
1127
x = intToX(vertex); \
1128
if (dy = intToY(c) - y) { \
1129
dx = intToX(c) - x; \
1146
step = - (dx / dy); \
1155
#define Step(x,dx,dy,e,sign,step) {\
1157
if ((e += dx) > 0) \
1164
DRAW_DEBUG ((DEBUG_POLYGON, "Starting polygon at %d", sy));
1167
DRAW_DEBUG ((DEBUG_POLYGON, "vertex1 0x%x vertex2 0x%x y %d vy1 %d vy2 %d",
1169
y, intToY(vertex1), intToY (vertex2)));
1170
if (y == intToY(vertex1))
1172
DRAW_DEBUG ((DEBUG_POLYGON, "Find next -- vertext"));
1175
if (vertex1p == (int *) ptsIn)
1178
Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1);
1179
DRAW_DEBUG ((DEBUG_POLYGON, "-- vertex 0x%x y %d",
1180
vertex1, intToY(vertex1)));
1181
} while (y >= intToY(vertex1));
1186
Step(x1,dx1,dy1,e1,sign1,step1)
1187
h = intToY(vertex1) - y;
1189
if (y == intToY(vertex2))
1191
DRAW_DEBUG ((DEBUG_POLYGON, "Find next ++ vertext"));
1195
if (vertex2p == endp)
1196
vertex2p = (int *) ptsIn;
1197
Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2)
1198
DRAW_DEBUG ((DEBUG_POLYGON, "++ vertex 0x%x y %d",
1199
vertex1, intToY(vertex1)));
1200
} while (y >= intToY(vertex2));
1206
Step(x2,dx2,dy2,e2,sign2,step2)
1207
if ((c = (intToY(vertex2) - y)) < h)
1210
DRAW_DEBUG ((DEBUG_POLYGON, "This band %d", h));
1211
/* fill spans for this segment */
1215
DRAW_DEBUG ((DEBUG_POLYGON, "This span %d->%d", x1, x2));
1224
_s3SolidRect(s3,l,sy,nmiddle,1);
1230
Step(x1,dx1,dy1,e1,sign1,step1)
1231
Step(x2,dx2,dy2,e2,sign2,step2)
1236
MarkSyncS3 (pDrawable->pScreen);
1240
s3PolyGlyphBltClipped (DrawablePtr pDrawable,
1243
unsigned int nglyph,
1244
CharInfoPtr *ppciInit,
1247
SetupS3(pDrawable->pScreen);
1253
FontPtr pfont = pGC->font;
1255
unsigned long *bits;
1260
FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC);
1261
RegionPtr pClip = fbGetCompositeClip(pGC);
1269
s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
1273
if (pglyphBase == (pointer) 1)
1276
yBack = y - FONTASCENT(pGC->font);
1278
hBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
1284
wBack += (*ppci++)->metrics.characterWidth;
1288
xBack = xBack + wBack;
1293
yBack = yBack + hBack;
1306
_s3SetSolidFill (s3, pGC->bgPixel, GXcopy, pGC->planemask);
1307
for (nbox = REGION_NUM_RECTS (pClip),
1308
pBox = REGION_RECTS (pClip);
1316
if (x1 < pBox->x1) x1 = pBox->x1;
1317
if (x2 > pBox->x2) x2 = pBox->x2;
1318
if (y1 < pBox->y1) y1 = pBox->y1;
1319
if (y2 > pBox->y2) y2 = pBox->y2;
1320
if (x1 < x2 && y1 < y2)
1322
_s3SolidRect (s3, x1, y1, x2 - x1, y2 - y1);
1325
MarkSyncS3 (pDrawable->pScreen);
1332
h = pci->metrics.ascent + pci->metrics.descent;
1333
w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
1334
x1 = x + pci->metrics.leftSideBearing;
1335
y1 = y - pci->metrics.ascent;
1340
switch (RECT_IN_REGION(pGC->pScreen, pClip, &bbox))
1344
lw = h * ((w + 31) >> 5);
1349
_s3SetTransparentPlaneBlt (s3, alu, pGC->planemask, pGC->fgPixel);
1353
x + pci->metrics.leftSideBearing,
1354
y - pci->metrics.ascent,
1356
bits = (unsigned long *) pci->bits;
1364
MarkSyncS3 (pDrawable->pScreen);
1370
CheckSyncS3 (pDrawable->pScreen);
1371
fbPutXYImage (pDrawable,
1380
(FbStip *) pci->bits,
1387
x += pci->metrics.characterWidth;
1392
* Blt glyphs using S3 image transfer register, this does both
1393
* poly glyph blt and image glyph blt (when pglyphBase == 1)
1397
s3PolyGlyphBlt (DrawablePtr pDrawable,
1400
unsigned int nglyph,
1401
CharInfoPtr *ppciInit,
1404
SetupS3(pDrawable->pScreen);
1410
FontPtr pfont = pGC->font;
1412
unsigned long *bits;
1420
s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
1424
/* compute an approximate (but covering) bounding box */
1429
w += (*ppci++)->metrics.characterWidth;
1440
w = FONTMINBOUNDS(pfont,leftSideBearing);
1443
w = FONTMAXBOUNDS(pfont, rightSideBearing) - FONTMINBOUNDS(pfont, characterWidth);
1446
bbox.y1 = y - FONTMAXBOUNDS(pfont,ascent);
1447
bbox.y2 = y + FONTMAXBOUNDS(pfont,descent);
1449
DRAW_DEBUG ((DEBUG_TEXT, "PolyGlyphBlt %d box is %d %d", nglyph,
1451
switch (RECT_IN_REGION(pGC->pScreen, fbGetCompositeClip(pGC), &bbox))
1456
s3PolyGlyphBltClipped(pDrawable, pGC, x - pDrawable->x,
1458
nglyph, ppciInit, pglyphBase);
1463
if (pglyphBase == (pointer) 1)
1466
yBack = y - FONTASCENT(pGC->font);
1468
hBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
1474
wBack += (*ppci++)->metrics.characterWidth;
1478
xBack = xBack + wBack;
1483
yBack = yBack + hBack;
1496
_s3SetSolidFill (s3, pGC->bgPixel, GXcopy, pGC->planemask);
1497
_s3SolidRect (s3, xBack, yBack, wBack, hBack);
1499
_s3SetTransparentPlaneBlt (s3, alu, pGC->planemask, pGC->fgPixel);
1504
h = pci->metrics.ascent + pci->metrics.descent;
1505
w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
1506
lw = h * ((w + 31) >> 5);
1510
x + pci->metrics.leftSideBearing,
1511
y - pci->metrics.ascent,
1513
bits = (unsigned long *) pci->bits;
1522
x += pci->metrics.characterWidth;
1524
MarkSyncS3 (pDrawable->pScreen);
1528
s3ImageGlyphBlt (DrawablePtr pDrawable,
1531
unsigned int nglyph,
1535
s3PolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, (pointer) 1);
1539
* Blt TE fonts using S3 image transfer. Differs from
1540
* above in that it doesn't need to fill a solid rect for
1541
* the background and it can draw multiple characters at a time
1545
s3ImageTEGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
1546
int xInit, int yInit,
1547
unsigned int nglyph,
1551
SetupS3(pDrawable->pScreen);
1555
FontPtr pfont = pGC->font;
1556
unsigned long *char1, *char2, *char3, *char4;
1557
int widthGlyphs, widthGlyph;
1562
s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
1563
widthGlyph = FONTMAXBOUNDS(pfont,characterWidth);
1567
h = FONTASCENT(pfont) + FONTDESCENT(pfont);
1571
DRAW_DEBUG ((DEBUG_TEXT, "ImageTEGlyphBlt chars are %d %d",
1574
x = xInit + FONTMAXBOUNDS(pfont,leftSideBearing) + pDrawable->x;
1575
y = yInit - FONTASCENT(pfont) + pDrawable->y;
1578
bbox.x2 = x + (widthGlyph * nglyph);
1582
switch (RECT_IN_REGION(pGC->pScreen, fbGetCompositeClip(pGC), &bbox))
1587
if (pglyphBase == (pointer) 1)
1590
pglyphBase = (pointer) 1;
1591
s3PolyGlyphBltClipped(pDrawable, pGC,
1600
if (pglyphBase == (pointer) 1)
1602
_s3SetTransparentPlaneBlt (s3, pGC->alu, pGC->planemask, pGC->fgPixel);
1606
_s3SetOpaquePlaneBlt (s3, GXcopy, pGC->planemask, pGC->fgPixel, pGC->bgPixel);
1609
#if BITMAP_BIT_ORDER == LSBFirst
1615
#define LoopIt(count, w, loadup, fetch) \
1616
while (nglyph >= count) \
1619
_s3PlaneBlt (s3, x, y, w, h); \
1626
S3AdjustBits32(tmp); \
1627
PixTransStore(tmp); \
1631
if (widthGlyph <= 8)
1633
widthGlyphs = widthGlyph << 2;
1634
LoopIt(4, widthGlyphs,
1635
char1 = (unsigned long *) (*ppci++)->bits;
1636
char2 = (unsigned long *) (*ppci++)->bits;
1637
char3 = (unsigned long *) (*ppci++)->bits;
1638
char4 = (unsigned long *) (*ppci++)->bits;,
1639
(*char1++ | ((*char2++ | ((*char3++ | (*char4++
1644
else if (widthGlyph <= 10)
1646
widthGlyphs = (widthGlyph << 1) + widthGlyph;
1647
LoopIt(3, widthGlyphs,
1648
char1 = (unsigned long *) (*ppci++)->bits;
1649
char2 = (unsigned long *) (*ppci++)->bits;
1650
char3 = (unsigned long *) (*ppci++)->bits;,
1651
(*char1++ | ((*char2++ | (*char3++ SHIFT widthGlyph)) SHIFT widthGlyph)))
1653
else if (widthGlyph <= 16)
1655
widthGlyphs = widthGlyph << 1;
1656
LoopIt(2, widthGlyphs,
1657
char1 = (unsigned long *) (*ppci++)->bits;
1658
char2 = (unsigned long *) (*ppci++)->bits;,
1659
(*char1++ | (*char2++ SHIFT widthGlyph)))
1661
lw = h * ((widthGlyph + 31) >> 5);
1664
_s3PlaneBlt (s3, x, y, widthGlyph, h);
1666
char1 = (unsigned long *) (*ppci++)->bits;
1672
S3AdjustBits32(tmp);
1676
MarkSyncS3 (pDrawable->pScreen);
1680
s3PolyTEGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
1682
unsigned int nglyph, CharInfoPtr *ppci,
1685
s3ImageTEGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, (pointer) 1);
1689
_s3Segment (DrawablePtr pDrawable,
1698
SetupS3(pDrawable->pScreen);
1699
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
1700
RegionPtr pClip = fbGetCompositeClip(pGC);
1703
int adx; /* abs values of dx and dy */
1705
int signdx; /* sign of dx and dy */
1707
int e, e1, e2; /* bresenham error and increments */
1708
int len; /* length of segment */
1709
int axis; /* major axis */
1712
unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
1713
unsigned int oc1; /* outcode of point 1 */
1714
unsigned int oc2; /* outcode of point 2 */
1716
CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy,
1725
e2 = e1 - (adx << 1);
1734
e2 = e1 - (ady << 1);
1736
SetYMajorOctant(octant);
1740
/* S3 line drawing hardware has limited resolution for error terms */
1745
KdCheckSync (pDrawable->pScreen);
1746
fbSegment (pDrawable, pGC, x1, y1, x2, y2, drawLast, &dashOff);
1750
FIXUP_ERROR (e, octant, bias);
1752
nBox = REGION_NUM_RECTS (pClip);
1753
pBox = REGION_RECTS (pClip);
1760
/* we have bresenham parameters and two points.
1761
all we have to do now is clip and draw.
1770
OUTCODES(oc1, x1, y1, pBox);
1771
OUTCODES(oc2, x2, y2, pBox);
1772
if ((oc1 | oc2) == 0)
1776
s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
1777
_s3SetSolidFill (s3, pGC->fgPixel, pGC->alu, pGC->planemask);
1780
_s3SetCur (s3, x1, y1);
1781
_s3ClipLine (s3, cmd, e1, e2, e, len);
1790
int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
1791
int clip1 = 0, clip2 = 0;
1795
if (miZeroClipLine(pBox->x1, pBox->y1, pBox->x2-1,
1797
&new_x1, &new_y1, &new_x2, &new_y2,
1798
adx, ady, &clip1, &clip2,
1799
octant, bias, oc1, oc2) == -1)
1806
len = abs(new_x2 - new_x1);
1808
len = abs(new_y2 - new_y1);
1809
if (clip2 != 0 || drawLast)
1813
/* unwind bresenham error term to first point */
1817
clipdx = abs(new_x1 - x1);
1818
clipdy = abs(new_y1 - y1);
1820
err += (e2 - e1) * clipdy + e1 * clipdx;
1822
err += (e2 - e1) * clipdx + e1 * clipdy;
1826
s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
1827
_s3SetSolidFill (s3, pGC->fgPixel, pGC->alu, pGC->planemask);
1830
_s3SetCur (s3, new_x1, new_y1);
1831
_s3ClipLine (s3, cmd, e1, e2, err, len);
1835
} /* while (nBox--) */
1840
s3Polylines (DrawablePtr pDrawable, GCPtr pGC,
1841
int mode, int npt, DDXPointPtr ppt)
1843
SetupS3(pDrawable->pScreen);
1845
int ox = pDrawable->x, oy = pDrawable->y;
1856
if (mode == CoordModePrevious)
1866
s3Set = _s3Segment (pDrawable, pGC, x, y, nx, ny,
1867
npt == 1 && pGC->capStyle != CapNotLast,
1873
MarkSyncS3 (pDrawable->pScreen);
1877
s3PolySegment (DrawablePtr pDrawable, GCPtr pGC,
1878
int nsegInit, xSegment *pSegInit)
1880
SetupS3(pDrawable->pScreen);
1882
int ox = pDrawable->x, oy = pDrawable->y;
1883
RegionPtr pClip = fbGetCompositeClip (pGC);
1889
int maj, min, len, inc;
1896
drawLast = pGC->capStyle != CapNotLast;
1898
for (nseg = nsegInit, pSeg = pSegInit; nseg--; pSeg++)
1900
s3Set = _s3Segment (pDrawable, pGC, pSeg->x1 + ox, pSeg->y1 + oy,
1901
pSeg->x2 + ox, pSeg->y2 + oy, drawLast, s3Set);
1905
MarkSyncS3 (pDrawable->pScreen);
1909
* Check to see if a pattern can be painted with the S3
1912
#define _s3CheckPatternSize(s) ((s) <= S3_TILE_SIZE && ((s) & ((s) - 1)) == 0)
1913
#define s3CheckPattern(w,h) (_s3CheckPatternSize(w) && _s3CheckPatternSize(h))
1916
s3AllocPattern (ScreenPtr pScreen,
1920
int fillStyle, Pixel fg, Pixel bg,
1921
s3PatternPtr *ppPattern)
1923
KdScreenPriv(pScreen);
1924
s3ScreenInfo(pScreenPriv);
1925
s3PatternPtr pPattern;
1927
if (s3s->fb[ma].patterns.cache && fillStyle != FillSolid &&
1928
s3CheckPattern (pPixmap->drawable.width, pPixmap->drawable.height))
1930
if (!(pPattern = *ppPattern))
1932
pPattern = (s3PatternPtr) xalloc (sizeof (s3PatternRec));
1935
*ppPattern = pPattern;
1938
pPattern->cache = 0;
1940
pPattern->pPixmap = pPixmap;
1941
pPattern->fillStyle = fillStyle;
1942
pPattern->xrot = (-xorg) & (S3_TILE_SIZE-1);
1943
pPattern->yrot = (-yorg) & (S3_TILE_SIZE-1);
1944
pPattern->fore = fg;
1945
pPattern->back = bg;
1960
s3CheckGCFill (GCPtr pGC)
1962
s3PrivGCPtr s3Priv = s3GetGCPrivate (pGC);
1965
switch (pGC->fillStyle) {
1969
case FillOpaqueStippled:
1971
pPixmap = pGC->stipple;
1974
pPixmap = pGC->tile.pixmap;
1977
s3AllocPattern (pGC->pScreen,
1980
pGC->patOrg.x + pGC->lastWinOrg.x,
1981
pGC->patOrg.y + pGC->lastWinOrg.y,
1982
pGC->fillStyle, pGC->fgPixel, pGC->bgPixel,
1987
s3MoveGCFill (GCPtr pGC)
1989
s3PrivGCPtr s3Priv = s3GetGCPrivate (pGC);
1991
s3PatternPtr pPattern;
1993
if (pPattern = s3Priv->pPattern)
1998
xorg = pGC->patOrg.x + pGC->lastWinOrg.x;
1999
yorg = pGC->patOrg.y + pGC->lastWinOrg.y;
2000
pPattern->xrot = (-xorg) & (S3_TILE_SIZE - 1);
2001
pPattern->yrot = (-yorg) & (S3_TILE_SIZE - 1);
2003
* Invalidate cache entry
2006
pPattern->cache = 0;
2011
* S3 Patterns. These are always full-depth images, stored in off-screen
2016
s3FetchPatternPixel (s3PatternPtr pPattern, int x, int y)
2021
PixmapPtr pPixmap = pPattern->pPixmap;
2023
x = (x + pPattern->xrot) % pPixmap->drawable.width;
2024
y = (y + pPattern->yrot) % pPixmap->drawable.height;
2025
src = (CARD8 *) pPixmap->devPrivate.ptr + y * pPixmap->devKind;
2026
switch (pPixmap->drawable.bitsPerPixel) {
2028
return (src[x>>3] >> (x & 7)) & 1 ? 0xffffffff : 0x00;
2031
return src[x>>1] >> 4;
2033
return src[x>>1] & 0xf;
2037
src16 = (CARD16 *) src;
2040
src32 = (CARD32 *) src;
2046
* Place pattern image on screen; done with S3 locked
2049
_s3PutPattern (ScreenPtr pScreen, int ma, s3PatternPtr pPattern)
2052
s3ScreenInfo(pScreenPriv);
2054
CARD8 *dstLine, *dst8;
2057
S3PatternCache *cache = pPattern->cache;
2061
int fb = s3s->fbmap[ma];
2064
DRAW_DEBUG ((DEBUG_PATTERN, "_s3PutPattern 0x%x id %d to %d %d",
2065
pPattern, pPattern->id, cache->x, cache->y));
2067
dstLine = (pScreenPriv->screen->fb[fb].frameBuffer +
2068
cache->y * pScreenPriv->screen->fb[fb].byteStride +
2069
cache->x * pScreenPriv->bytesPerPixel[fb]);
2071
CheckSyncS3 (pScreen);
2073
for (y = 0; y < S3_TILE_SIZE; y++)
2075
switch (pScreenPriv->screen->fb[fb].bitsPerPixel) {
2078
for (x = 0; x < S3_TILE_SIZE; x++)
2079
*dst8++ = s3FetchPatternPixel (pPattern, x, y);
2080
DRAW_DEBUG ((DEBUG_PATTERN, "%c%c%c%c%c%c%c%c",
2081
dstLine[0] ? 'X' : ' ',
2082
dstLine[1] ? 'X' : ' ',
2083
dstLine[2] ? 'X' : ' ',
2084
dstLine[3] ? 'X' : ' ',
2085
dstLine[4] ? 'X' : ' ',
2086
dstLine[5] ? 'X' : ' ',
2087
dstLine[6] ? 'X' : ' ',
2088
dstLine[7] ? 'X' : ' '));
2091
dst16 = (CARD16 *) dstLine;
2092
for (x = 0; x < S3_TILE_SIZE; x++)
2093
*dst16++ = s3FetchPatternPixel (pPattern, x, y);
2096
dst32 = (CARD32 *) dstLine;
2097
for (x = 0; x < S3_TILE_SIZE; x++)
2098
*dst32++ = s3FetchPatternPixel (pPattern, x, y);
2101
dstLine += pScreenPriv->screen->fb[fb].byteStride;
2106
* Load a stipple to off-screen memory; done with S3 locked
2109
_s3LoadPattern (ScreenPtr pScreen, int ma, s3PatternPtr pPattern)
2112
s3ScreenInfo(pScreenPriv);
2113
S3PatternCache *cache;
2115
DRAW_DEBUG((DEBUG_PATTERN,
2116
"s3LoadPattern 0x%x id %d cache 0x%x cacheid %d",
2117
pPattern, pPattern->id, pPattern->cache,
2118
pPattern->cache ? pPattern->cache->id : -1));
2120
* Check to see if its still loaded
2122
cache = pPattern->cache;
2123
if (cache && cache->id == pPattern->id)
2126
* Lame replacement strategy; assume we'll have plenty of room.
2128
cache = &s3s->fb[ma].patterns.cache[s3s->fb[ma].patterns.last_used];
2129
if (++s3s->fb[ma].patterns.last_used == s3s->fb[ma].patterns.ncache)
2130
s3s->fb[ma].patterns.last_used = 0;
2131
cache->id = ++s3s->fb[ma].patterns.last_id;
2132
pPattern->id = cache->id;
2133
pPattern->cache = cache;
2134
_s3PutPattern (pScreen, ma, pPattern);
2138
s3DestroyGC (GCPtr pGC)
2140
s3PrivGCPtr s3Priv = s3GetGCPrivate (pGC);
2142
if (s3Priv->pPattern)
2143
xfree (s3Priv->pPattern);
2147
GCFuncs s3GCFuncs = {
2158
s3CreateGC (GCPtr pGC)
2160
KdScreenPriv(pGC->pScreen);
2161
s3ScreenInfo(pScreenPriv);
2164
if (!fbCreateGC (pGC))
2167
if (pGC->depth != 1)
2168
pGC->funcs = &s3GCFuncs;
2170
s3Priv = s3GetGCPrivate(pGC);
2171
s3Priv->type = DRAWABLE_PIXMAP;
2172
s3Priv->pPattern = 0;
2174
if (pGC->depth == s3s->primary_depth)
2183
s3CreateWindow (WindowPtr pWin)
2185
KdScreenPriv(pWin->drawable.pScreen);
2186
s3ScreenInfo(pScreenPriv);
2188
pWin->devPrivates[s3WindowPrivateIndex].ptr = 0;
2189
return KdCreateWindow (pWin);
2193
s3DestroyWindow (WindowPtr pWin)
2195
s3PatternPtr pPattern;
2196
if (pPattern = s3GetWindowPrivate(pWin))
2198
return fbDestroyWindow (pWin);
2202
s3ChangeWindowAttributes (WindowPtr pWin, Mask mask)
2204
KdScreenPriv(pWin->drawable.pScreen);
2206
s3PatternPtr pPattern;
2210
ret = fbChangeWindowAttributes (pWin, mask);
2211
if (mask & CWBackPixmap)
2213
if (pWin->backgroundState == BackgroundPixmap)
2215
pPixmap = pWin->background.pixmap;
2216
fillStyle = FillTiled;
2221
fillStyle = FillSolid;
2223
pPattern = s3GetWindowPrivate(pWin);
2224
s3AllocPattern (pWin->drawable.pScreen,
2225
s3DrawMap (&pWin->drawable),
2227
pWin->drawable.x, pWin->drawable.y,
2228
fillStyle, 0, 0, &pPattern);
2229
DRAW_DEBUG ((DEBUG_PAINT_WINDOW, "Background pattern 0x%x pixmap 0x%x style %d",
2230
pPattern, pPixmap, fillStyle));
2231
s3SetWindowPrivate (pWin, pPattern);
2239
s3PaintKey (DrawablePtr pDrawable,
2244
SetupS3 (pDrawable->pScreen);
2245
s3ScreenInfo (pScreenPriv);
2246
int nBox = REGION_NUM_RECTS(pRegion);
2247
BoxPtr pBox = REGION_RECTS(pRegion);
2253
for (ma = 0; s3s->fbmap[ma] >= 0; ma++)
2254
if (s3s->fbmap[ma] == fb)
2256
s3SetGlobalBitmap (pDrawable->pScreen, ma);
2257
_s3SetSolidFill (s3, pixel, GXcopy, 0xffffffff);
2260
_s3SolidRect(s3,pBox->x1,pBox->y1,pBox->x2-pBox->x1,pBox->y2-pBox->y1);
2263
MarkSyncS3 (pDrawable->pScreen);
2268
s3PaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
2270
SetupS3(pWin->drawable.pScreen);
2271
s3ScreenInfo(pScreenPriv);
2272
s3PatternPtr pPattern;
2274
DRAW_DEBUG ((DEBUG_PAINT_WINDOW, "s3PaintWindow 0x%x extents %d %d %d %d n %d",
2276
pRegion->extents.x1, pRegion->extents.y1,
2277
pRegion->extents.x2, pRegion->extents.y2,
2278
REGION_NUM_RECTS(pRegion)));
2279
if (!REGION_NUM_RECTS(pRegion))
2283
switch (pWin->backgroundState) {
2286
case ParentRelative:
2288
pWin = pWin->parent;
2289
} while (pWin->backgroundState == ParentRelative);
2290
(*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion,
2293
case BackgroundPixmap:
2294
pPattern = s3GetWindowPrivate(pWin);
2297
s3FillBoxPattern ((DrawablePtr)pWin,
2298
(int)REGION_NUM_RECTS(pRegion),
2299
REGION_RECTS(pRegion),
2300
GXcopy, ~0, pPattern);
2304
case BackgroundPixel:
2305
s3FillBoxSolid((DrawablePtr)pWin,
2306
(int)REGION_NUM_RECTS(pRegion),
2307
REGION_RECTS(pRegion),
2308
pWin->background.pixel, GXcopy, ~0);
2314
if (s3s->fbmap[1] >= 0)
2315
fbOverlayUpdateLayerRegion (pWin->drawable.pScreen,
2316
fbOverlayWindowLayer (pWin),
2319
if (pWin->borderIsPixel)
2321
s3FillBoxSolid((DrawablePtr)pWin,
2322
(int)REGION_NUM_RECTS(pRegion),
2323
REGION_RECTS(pRegion),
2324
pWin->border.pixel, GXcopy, ~0);
2329
KdCheckPaintWindow (pWin, pRegion, what);
2333
s3CopyWindowProc (DrawablePtr pSrcDrawable,
2334
DrawablePtr pDstDrawable,
2345
SetupS3(pDstDrawable->pScreen);
2346
s3ScreenInfo(pScreenPriv);
2347
KdScreenInfo *screen = pScreenPriv->screen;
2348
int srcX, srcY, dstX, dstY;
2352
int fb = (int) closure;
2361
for (ma = 0; s3s->fbmap[ma] >= 0; ma++)
2362
if (s3s->fbmap[ma] == fb)
2365
bitsPerPixel = screen->fb[fb].bitsPerPixel;
2366
if (bitsPerPixel == 24)
2370
s3SetGlobalBitmap (pDstDrawable->pScreen, ma);
2371
_s3SetBlt(s3,GXcopy,~0);
2376
if (bitsPerPixel == 24)
2383
h = pbox->y2 - pbox->y1;
2398
dstY = pbox->y2 - 1;
2407
_s3Blt (s3, srcX, srcY, dstX, dstY, w, h, flags);
2410
MarkSyncS3 (pDstDrawable->pScreen);
2414
s3CopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
2416
ScreenPtr pScreen = pWin->drawable.pScreen;
2417
KdScreenPriv (pScreen);
2418
s3ScreenInfo (pScreenPriv);
2419
KdScreenInfo *screen = pScreenPriv->screen;
2424
pwinRoot = WindowTable[pWin->drawable.pScreen->myNum];
2426
dx = ptOldOrg.x - pWin->drawable.x;
2427
dy = ptOldOrg.y - pWin->drawable.y;
2429
REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
2431
REGION_INIT (pWin->drawable.pScreen, &rgnDst, NullBox, 0);
2433
REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst,
2434
&pWin->borderClip, prgnSrc);
2436
fbCopyRegion ((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
2438
&rgnDst, dx, dy, s3CopyWindowProc, 0, 0);
2440
REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
2444
s3_24FillBoxSolid (DrawablePtr pDrawable, int nBox, BoxPtr pBox,
2445
unsigned long pixel, int alu, unsigned long planemask)
2447
SetupS3(pDrawable->pScreen);
2451
s3SetGlobalBitmap (pDrawable->pScreen, s3DrawMap (pDrawable));
2452
_s3SetSolidFill(s3,pixel,alu,planemask);
2457
_s3SolidRect(s3,x1,pBox->y1,x2-x1,pBox->y2-pBox->y1);
2460
MarkSyncS3 (pDrawable->pScreen);
2463
#define ok24(p) (((p) & 0xffffff) == ((((p) & 0xff) << 16) | (((p) >> 8) & 0xffff)))
2466
s3_24FillSpans (DrawablePtr pDrawable, GCPtr pGC, int n,
2467
DDXPointPtr ppt, int *pwidth, int fSorted)
2469
SetupS3(pDrawable->pScreen);
2470
int x, y, x1, y1, x2, y2;
2472
/* next three parameters are post-clip */
2474
int *pwidthFree;/* copies of the pointers to free */
2475
DDXPointPtr pptFree;
2477
RegionPtr pClip = fbGetCompositeClip (pGC);
2479
if (pGC->fillStyle != FillSolid || !ok24 (pGC->fgPixel) || !ok24(pGC->planemask))
2481
KdCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
2485
s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
2486
if (REGION_NUM_RECTS(pClip) == 1)
2488
extents = REGION_RECTS(pClip);
2493
_s3SetSolidFill(s3,pGC->fgPixel,pGC->alu,pGC->planemask);
2497
if (y1 <= y && y < y2)
2510
_s3SolidRect(s3,x*3,y,width*3,1);
2519
nTmp = n * miFindMaxBand(pClip);
2520
pwidthFree = (int *)ALLOCATE_LOCAL(nTmp * sizeof(int));
2521
pptFree = (DDXPointRec *)ALLOCATE_LOCAL(nTmp * sizeof(DDXPointRec));
2522
if(!pptFree || !pwidthFree)
2524
if (pptFree) DEALLOCATE_LOCAL(pptFree);
2525
if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
2528
n = miClipSpans(fbGetCompositeClip(pGC),
2530
pptFree, pwidthFree, fSorted);
2531
pwidth = pwidthFree;
2533
_s3SetSolidFill(s3,pGC->fgPixel,pGC->alu,pGC->planemask);
2542
_s3SolidRect(s3,x*3,y,width*3,1);
2545
DEALLOCATE_LOCAL(pptFree);
2546
DEALLOCATE_LOCAL(pwidthFree);
2548
MarkSyncS3 (pDrawable->pScreen);
2552
s3_24CopyNtoN (DrawablePtr pSrcDrawable,
2553
DrawablePtr pDstDrawable,
2564
SetupS3(pDstDrawable->pScreen);
2565
int srcX, srcY, dstX, dstY;
2570
if (sourceInvarient (pGC->alu))
2572
s3_24FillBoxSolid (pDstDrawable, nbox, pbox, 0, pGC->alu, pGC->planemask);
2576
s3SetGlobalBitmap (pDstDrawable->pScreen, s3GCMap (pGC));
2577
_s3SetBlt(s3,pGC->alu,pGC->planemask);
2578
DRAW_DEBUG ((DEBUG_RENDER, "s3CopyNtoN alu %d planemask 0x%x",
2579
pGC->alu, pGC->planemask));
2586
h = pbox->y2 - pbox->y1;
2601
dstY = pbox->y2 - 1;
2610
_s3Blt (s3, srcX, srcY, dstX, dstY, w, h, flags);
2613
MarkSyncS3 (pSrcDrawable->pScreen);
2617
s3_24CopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
2618
int srcx, int srcy, int width, int height, int dstx, int dsty)
2620
SetupS3(pDstDrawable->pScreen);
2622
if (pSrcDrawable->type == DRAWABLE_WINDOW &&
2623
pDstDrawable->type == DRAWABLE_WINDOW &&
2624
ok24(pGC->planemask))
2626
return fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
2627
srcx, srcy, width, height,
2628
dstx, dsty, s3_24CopyNtoN, 0, 0);
2630
return KdCheckCopyArea (pSrcDrawable, pDstDrawable, pGC,
2631
srcx, srcy, width, height, dstx, dsty);
2635
#define NUM_STACK_RECTS 1024
2638
s3_24PolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
2639
int nrectFill, xRectangle *prectInit)
2644
register BoxPtr pbox;
2645
register BoxPtr pboxClipped;
2646
BoxPtr pboxClippedBase;
2648
BoxRec stackRects[NUM_STACK_RECTS];
2654
if (pGC->fillStyle != FillSolid || !ok24 (pGC->fgPixel) || !ok24(pGC->planemask))
2656
KdCheckPolyFillRect (pDrawable, pGC, nrectFill, prectInit);
2660
prgnClip = fbGetCompositeClip(pGC);
2661
xorg = pDrawable->x;
2662
yorg = pDrawable->y;
2678
numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
2679
if (numRects > NUM_STACK_RECTS)
2681
pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec));
2682
if (!pboxClippedBase)
2686
pboxClippedBase = stackRects;
2688
pboxClipped = pboxClippedBase;
2690
if (REGION_NUM_RECTS(prgnClip) == 1)
2692
int x1, y1, x2, y2, bx2, by2;
2694
pextent = REGION_RECTS(prgnClip);
2701
if ((pboxClipped->x1 = prect->x) < x1)
2702
pboxClipped->x1 = x1;
2704
if ((pboxClipped->y1 = prect->y) < y1)
2705
pboxClipped->y1 = y1;
2707
bx2 = (int) prect->x + (int) prect->width;
2710
pboxClipped->x2 = bx2;
2712
by2 = (int) prect->y + (int) prect->height;
2715
pboxClipped->y2 = by2;
2718
if ((pboxClipped->x1 < pboxClipped->x2) &&
2719
(pboxClipped->y1 < pboxClipped->y2))
2727
int x1, y1, x2, y2, bx2, by2;
2729
pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
2738
if ((box.x1 = prect->x) < x1)
2741
if ((box.y1 = prect->y) < y1)
2744
bx2 = (int) prect->x + (int) prect->width;
2749
by2 = (int) prect->y + (int) prect->height;
2756
if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
2759
n = REGION_NUM_RECTS (prgnClip);
2760
pbox = REGION_RECTS(prgnClip);
2762
/* clip the rectangle to each box in the clip region
2763
this is logically equivalent to calling Intersect()
2767
pboxClipped->x1 = max(box.x1, pbox->x1);
2768
pboxClipped->y1 = max(box.y1, pbox->y1);
2769
pboxClipped->x2 = min(box.x2, pbox->x2);
2770
pboxClipped->y2 = min(box.y2, pbox->y2);
2773
/* see if clipping left anything */
2774
if(pboxClipped->x1 < pboxClipped->x2 &&
2775
pboxClipped->y1 < pboxClipped->y2)
2782
if (pboxClipped != pboxClippedBase)
2784
s3_24FillBoxSolid(pDrawable,
2785
pboxClipped-pboxClippedBase, pboxClippedBase,
2786
pGC->fgPixel, pGC->alu, pGC->planemask);
2788
if (pboxClippedBase != stackRects)
2789
DEALLOCATE_LOCAL(pboxClippedBase);
2793
s3_24SolidBoxClipped (DrawablePtr pDrawable,
2801
SetupS3 (pDrawable->pScreen);
2804
int partX1, partX2, partY1, partY2;
2806
s3SetGlobalBitmap (pDrawable->pScreen, s3DrawMap (pDrawable));
2807
_s3SetSolidFill(s3,fg,GXcopy,~0);
2809
for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip);
2821
if (partX2 <= partX1)
2832
if (partY2 <= partY1)
2837
_s3SolidRect(s3,partX1, partY1, partX2-partX1, partY2-partY1);
2839
MarkSyncS3(pDrawable->pScreen);
2843
s3_24ImageGlyphBlt (DrawablePtr pDrawable,
2847
unsigned int nglyph,
2848
CharInfoPtr *ppciInit,
2851
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
2854
unsigned char *pglyph; /* pointer bits in glyph */
2855
int gWidth, gHeight; /* width and height of glyph */
2856
FbStride gStride; /* stride of glyph */
2863
int dstXoff, dstYoff;
2865
int xBack, widthBack;
2866
int yBack, heightBack;
2868
depthMask = FbFullMask(pDrawable->depth);
2869
if (!ok24 (pGC->fgPixel) ||
2870
!ok24(pGC->bgPixel) ||
2871
!ok24(pGC->planemask))
2873
KdCheckImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppciInit, pglyphBase);
2876
fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
2885
widthBack += (*ppci++)->metrics.characterWidth;
2891
widthBack = -widthBack;
2893
yBack = y - FONTASCENT(pGC->font);
2894
heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
2895
s3_24SolidBoxClipped (pDrawable,
2896
fbGetCompositeClip(pGC),
2903
KdCheckSync (pDrawable->pScreen);
2909
pglyph = FONTGLYPHBITS(pglyphBase, pci);
2910
gWidth = GLYPHWIDTHPIXELS(pci);
2911
gHeight = GLYPHHEIGHTPIXELS(pci);
2912
if (gWidth && gHeight)
2914
gx = x + pci->metrics.leftSideBearing;
2915
gy = y - pci->metrics.ascent;
2916
if (gWidth <= sizeof (FbStip) * 8 &&
2917
fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight))
2919
fbGlyph24 (dst + (gy - dstYoff) * dstStride,
2929
gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip);
2930
fbPutXYImage (pDrawable,
2931
fbGetCompositeClip(pGC),
2947
x += pci->metrics.characterWidth;
2951
static const GCOps s3_24GCOps = {
2960
KdCheckPolyRectangle,
2970
KdCheckPolyGlyphBlt,
2972
#ifdef NEED_LINEHELPER
2978
s3_24ValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable)
2980
if (pDrawable->type != DRAWABLE_WINDOW)
2981
pGC->ops = (GCOps *) &kdAsyncPixmapGCOps;
2983
pGC->ops = (GCOps *) &s3_24GCOps;
2984
fbValidateGC (pGC, changes, pDrawable);
2987
GCFuncs s3_24GCFuncs = {
2998
s3_24CreateGC (GCPtr pGC)
3000
if (!fbCreateGC (pGC))
3003
if (pGC->depth != 1)
3004
pGC->funcs = &s3_24GCFuncs;
3010
s3_24CreateWindow(WindowPtr pWin)
3012
return fbCreateWindow (pWin);
3016
s3_24PaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
3018
SetupS3(pWin->drawable.pScreen);
3019
s3PatternPtr pPattern;
3021
DRAW_DEBUG ((DEBUG_PAINT_WINDOW, "s3PaintWindow 0x%x extents %d %d %d %d n %d",
3023
pRegion->extents.x1, pRegion->extents.y1,
3024
pRegion->extents.x2, pRegion->extents.y2,
3025
REGION_NUM_RECTS(pRegion)));
3026
if (!REGION_NUM_RECTS(pRegion))
3030
switch (pWin->backgroundState) {
3033
case ParentRelative:
3035
pWin = pWin->parent;
3036
} while (pWin->backgroundState == ParentRelative);
3037
(*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion,
3040
case BackgroundPixel:
3041
if (ok24(pWin->background.pixel))
3043
s3_24FillBoxSolid((DrawablePtr)pWin,
3044
(int)REGION_NUM_RECTS(pRegion),
3045
REGION_RECTS(pRegion),
3046
pWin->background.pixel, GXcopy, ~0);
3052
if (pWin->borderIsPixel && ok24(pWin->border.pixel))
3054
s3_24FillBoxSolid((DrawablePtr)pWin,
3055
(int)REGION_NUM_RECTS(pRegion),
3056
REGION_RECTS(pRegion),
3057
pWin->border.pixel, GXcopy, ~0);
3062
KdCheckPaintWindow (pWin, pRegion, what);
3066
s3DrawInit (ScreenPtr pScreen)
3068
KdScreenPriv(pScreen);
3069
s3ScreenInfo(pScreenPriv);
3070
int ncache_w, ncache_h, ncache;
3072
S3PatternCache *cache;
3076
switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
3088
* Hook up asynchronous drawing
3090
RegisterSync (pScreen);
3092
* Replace various fb screen functions
3096
pScreen->CreateGC = s3_24CreateGC;
3097
pScreen->CreateWindow = s3_24CreateWindow;
3098
pScreen->PaintWindowBackground = s3_24PaintWindow;
3099
pScreen->PaintWindowBorder = s3_24PaintWindow;
3100
pScreen->CopyWindow = s3CopyWindow;
3104
if (serverGeneration != s3Generation)
3106
s3GCPrivateIndex = AllocateGCPrivateIndex ();
3107
s3WindowPrivateIndex = AllocateWindowPrivateIndex ();
3108
s3Generation = serverGeneration;
3110
if (!AllocateWindowPrivate(pScreen, s3WindowPrivateIndex, 0))
3112
if (!AllocateGCPrivate(pScreen, s3GCPrivateIndex, sizeof (s3PrivGCRec)))
3114
pScreen->CreateGC = s3CreateGC;
3115
pScreen->CreateWindow = s3CreateWindow;
3116
pScreen->ChangeWindowAttributes = s3ChangeWindowAttributes;
3117
pScreen->DestroyWindow = s3DestroyWindow;
3118
pScreen->PaintWindowBackground = s3PaintWindow;
3119
pScreen->PaintWindowBorder = s3PaintWindow;
3121
if (pScreenPriv->screen->fb[1].depth)
3123
FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen);
3125
pScrPriv->PaintKey = s3PaintKey;
3126
pScrPriv->CopyWindow = s3CopyWindowProc;
3127
pScreen->CopyWindow = fbOverlayCopyWindow;
3131
pScreen->CopyWindow = s3CopyWindow;
3134
* Initialize patterns
3139
for (ma = 0; s3s->fbmap[ma] >= 0; ma++)
3142
ncache_w = s3s->fb[ma].offscreen_width / S3_TILE_SIZE;
3143
ncache_h = s3s->fb[ma].offscreen_height / S3_TILE_SIZE;
3144
ncache = ncache_w * ncache_h;
3147
DRAW_DEBUG ((DEBUG_S3INIT, "ncache_w %d ncache_h %d ncache %d",
3148
ncache_w, ncache_h, ncache));
3149
s3s->fb[ma].patterns.cache = (S3PatternCache *) xalloc (ncache * sizeof (S3PatternCache));
3150
if (s3s->fb[ma].patterns.cache)
3152
DRAW_DEBUG ((DEBUG_S3INIT, "Have pattern cache"));
3153
s3s->fb[ma].patterns.ncache = ncache;
3154
s3s->fb[ma].patterns.last_used = 0;
3155
s3s->fb[ma].patterns.last_id = 0;
3156
cache = s3s->fb[ma].patterns.cache;
3157
for (py = 0; py < ncache_h && ncache; py++)
3158
for (px = 0; px < ncache_w && ncache; px++)
3161
cache->x = s3s->fb[ma].offscreen_x + px * S3_TILE_SIZE;
3162
cache->y = s3s->fb[ma].offscreen_y + py * S3_TILE_SIZE;
3173
s3DrawEnable (ScreenPtr pScreen)
3176
s3ScreenInfo(pScreenPriv);
3180
s3SetGlobalBitmap (pScreen, 0);
3181
_s3WaitIdleEmpty (s3);
3182
if (pScreenPriv->screen->fb[0].bitsPerPixel == 24)
3184
_s3SetScissorsTl(s3, 0, 0);
3185
_s3SetScissorsBr(s3, pScreenPriv->screen->width*3 - 1, pScreenPriv->screen->height - 1);
3186
_s3SetSolidFill(s3, pScreen->whitePixel, GXcopy, ~0);
3187
_s3SolidRect (s3, 0, 0, pScreenPriv->screen->width*3, pScreenPriv->screen->height);
3192
* Flush pattern cache
3197
for (ma = 0; s3s->fbmap[ma] >= 0; ma++)
3200
for (c = 0; c < s3s->fb[ma].patterns.ncache; c++)
3201
s3s->fb[ma].patterns.cache[c].id = 0;
3204
_s3SetScissorsTl(s3, 0, 0);
3205
_s3SetScissorsBr(s3, pScreenPriv->screen->width - 1, pScreenPriv->screen->height - 1);
3206
_s3SetSolidFill(s3, pScreen->blackPixel, GXcopy, ~0);
3207
_s3SolidRect (s3, 0, 0, pScreenPriv->screen->width, pScreenPriv->screen->height);
3209
MarkSyncS3 (pScreen);
3213
s3DrawDisable (ScreenPtr pScreen)
3216
_s3WaitIdleEmpty (s3);
3220
s3DrawFini (ScreenPtr pScreen)
3223
s3ScreenInfo(pScreenPriv);
3229
for (ma = 0; s3s->fbmap[ma] >= 0; ma++)
3232
if (s3s->fb[ma].patterns.cache)
3234
xfree (s3s->fb[ma].patterns.cache);
3235
s3s->fb[ma].patterns.cache = 0;
3236
s3s->fb[ma].patterns.ncache = 0;
3242
s3DrawSync (ScreenPtr pScreen)
3246
_s3WaitIdleEmpty(s3c->s3);