smi_xaa.c revision 09885543
109885543Smrg/*
209885543SmrgCopyright (C) 1994-1999 The XFree86 Project, Inc.  All Rights Reserved.
309885543SmrgCopyright (C) 2000 Silicon Motion, Inc.  All Rights Reserved.
409885543Smrg
509885543SmrgPermission is hereby granted, free of charge, to any person obtaining a copy of
609885543Smrgthis software and associated documentation files (the "Software"), to deal in
709885543Smrgthe Software without restriction, including without limitation the rights to
809885543Smrguse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
909885543Smrgof the Software, and to permit persons to whom the Software is furnished to do
1009885543Smrgso, subject to the following conditions:
1109885543Smrg
1209885543SmrgThe above copyright notice and this permission notice shall be included in all
1309885543Smrgcopies or substantial portions of the Software.
1409885543Smrg
1509885543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1609885543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
1709885543SmrgNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
1809885543SmrgXFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
1909885543SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
2009885543SmrgWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2109885543Smrg
2209885543SmrgExcept as contained in this notice, the names of the XFree86 Project and
2309885543SmrgSilicon Motion shall not be used in advertising or otherwise to promote the
2409885543Smrgsale, use or other dealings in this Software without prior written
2509885543Smrgauthorization from the XFree86 Project and silicon Motion.
2609885543Smrg*/
2709885543Smrg
2809885543Smrg#ifdef HAVE_CONFIG_H
2909885543Smrg#include "config.h"
3009885543Smrg#endif
3109885543Smrg
3209885543Smrg#include "smi.h"
3309885543Smrg
3409885543Smrg#include "miline.h"
3509885543Smrg#include "xaalocal.h"
3609885543Smrg#include "xaarop.h"
3709885543Smrg#include "servermd.h"
3809885543Smrg
3909885543Smrgstatic void SMI_SetupForScreenToScreenCopy(ScrnInfoPtr, int, int, int,
4009885543Smrg					   unsigned int, int);
4109885543Smrgstatic void SMI_SubsequentScreenToScreenCopy(ScrnInfoPtr, int, int, int, int,
4209885543Smrg					     int, int);
4309885543Smrgstatic void SMI_SetupForSolidFill(ScrnInfoPtr, int, int, unsigned);
4409885543Smrgstatic void SMI_SubsequentSolidFillRect(ScrnInfoPtr, int, int, int, int);
4509885543Smrgstatic void SMI_SubsequentSolidHorVertLine(ScrnInfoPtr, int, int, int, int);
4609885543Smrgstatic void SMI_SetupForCPUToScreenColorExpandFill(ScrnInfoPtr, int, int, int,
4709885543Smrg						   unsigned int);
4809885543Smrgstatic void SMI_SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr, int, int, int,
4909885543Smrg						     int, int);
5009885543Smrgstatic void SMI_SetupForMono8x8PatternFill(ScrnInfoPtr, int, int, int, int, int,
5109885543Smrg					   unsigned int);
5209885543Smrgstatic void SMI_SubsequentMono8x8PatternFillRect(ScrnInfoPtr, int, int, int,
5309885543Smrg						 int, int, int);
5409885543Smrgstatic void SMI_SetupForColor8x8PatternFill(ScrnInfoPtr, int, int, int,
5509885543Smrg					    unsigned int, int);
5609885543Smrgstatic void SMI_SubsequentColor8x8PatternFillRect(ScrnInfoPtr, int, int, int,
5709885543Smrg						  int, int, int);
5809885543Smrg#if SMI_USE_IMAGE_WRITES
5909885543Smrgstatic void SMI_SetupForImageWrite(ScrnInfoPtr, int, unsigned int, int, int,
6009885543Smrg				   int);
6109885543Smrgstatic void SMI_SubsequentImageWriteRect(ScrnInfoPtr, int, int, int, int, int);
6209885543Smrg#endif
6309885543Smrg/* #671 */
6409885543Smrgstatic void SMI_ValidatePolylines(GCPtr, unsigned long, DrawablePtr);
6509885543Smrgstatic void SMI_Polylines(DrawablePtr, GCPtr, int, int, DDXPointPtr);
6609885543Smrg
6709885543Smrg
6809885543SmrgBool
6909885543SmrgSMI_XAAInit(ScreenPtr pScreen)
7009885543Smrg{
7109885543Smrg    XAAInfoRecPtr infoPtr;
7209885543Smrg    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
7309885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
7409885543Smrg    /*BoxRec AvailFBArea;*/
7509885543Smrg    Bool ret;
7609885543Smrg    /*int numLines, maxLines;*/
7709885543Smrg
7809885543Smrg    ENTER_PROC("SMI_XAAInit");
7909885543Smrg
8009885543Smrg    pSmi->XAAInfoRec = infoPtr = XAACreateInfoRec();
8109885543Smrg    if (infoPtr == NULL) {
8209885543Smrg	LEAVE_PROC("SMI_AccelInit");
8309885543Smrg	return FALSE;
8409885543Smrg    }
8509885543Smrg
8609885543Smrg    infoPtr->Flags = PIXMAP_CACHE
8709885543Smrg		   | LINEAR_FRAMEBUFFER
8809885543Smrg		   | OFFSCREEN_PIXMAPS;
8909885543Smrg
9009885543Smrg    infoPtr->Sync = SMI_AccelSync;
9109885543Smrg
9209885543Smrg    /* Screen to screen copies */
9309885543Smrg    infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK
9409885543Smrg				     | ONLY_TWO_BITBLT_DIRECTIONS;
9509885543Smrg    infoPtr->SetupForScreenToScreenCopy = SMI_SetupForScreenToScreenCopy;
9609885543Smrg    infoPtr->SubsequentScreenToScreenCopy = SMI_SubsequentScreenToScreenCopy;
9709885543Smrg    if (pScrn->bitsPerPixel == 24) {
9809885543Smrg	infoPtr->ScreenToScreenCopyFlags |= NO_TRANSPARENCY;
9909885543Smrg    }
10009885543Smrg    if ((pSmi->Chipset == SMI_LYNX3D) && (pScrn->bitsPerPixel == 8)) {
10109885543Smrg	infoPtr->ScreenToScreenCopyFlags |= GXCOPY_ONLY;
10209885543Smrg    }
10309885543Smrg
10409885543Smrg    /* Solid Fills */
10509885543Smrg    infoPtr->SolidFillFlags = NO_PLANEMASK;
10609885543Smrg    infoPtr->SetupForSolidFill = SMI_SetupForSolidFill;
10709885543Smrg    infoPtr->SubsequentSolidFillRect = SMI_SubsequentSolidFillRect;
10809885543Smrg
10909885543Smrg    /* Solid Lines */
11009885543Smrg    infoPtr->SolidLineFlags = NO_PLANEMASK;
11109885543Smrg    infoPtr->SetupForSolidLine = SMI_SetupForSolidFill;
11209885543Smrg    infoPtr->SubsequentSolidHorVertLine = SMI_SubsequentSolidHorVertLine;
11309885543Smrg
11409885543Smrg    /* Color Expansion Fills */
11509885543Smrg    infoPtr->CPUToScreenColorExpandFillFlags = ROP_NEEDS_SOURCE
11609885543Smrg					     | NO_PLANEMASK
11709885543Smrg					     | BIT_ORDER_IN_BYTE_MSBFIRST
11809885543Smrg					     | LEFT_EDGE_CLIPPING
11909885543Smrg					     | CPU_TRANSFER_PAD_DWORD
12009885543Smrg					     | SCANLINE_PAD_DWORD;
12109885543Smrg    infoPtr->ColorExpandBase = pSmi->DataPortBase;
12209885543Smrg    infoPtr->ColorExpandRange = pSmi->DataPortSize;
12309885543Smrg    infoPtr->SetupForCPUToScreenColorExpandFill =
12409885543Smrg	    SMI_SetupForCPUToScreenColorExpandFill;
12509885543Smrg    infoPtr->SubsequentCPUToScreenColorExpandFill =
12609885543Smrg	    SMI_SubsequentCPUToScreenColorExpandFill;
12709885543Smrg
12809885543Smrg    /* 8x8 Mono Pattern Fills */
12909885543Smrg    infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK
13009885543Smrg				     | HARDWARE_PATTERN_PROGRAMMED_BITS
13109885543Smrg				     | HARDWARE_PATTERN_SCREEN_ORIGIN
13209885543Smrg				     | BIT_ORDER_IN_BYTE_MSBFIRST;
13309885543Smrg    infoPtr->SetupForMono8x8PatternFill = SMI_SetupForMono8x8PatternFill;
13409885543Smrg    infoPtr->SubsequentMono8x8PatternFillRect =
13509885543Smrg	SMI_SubsequentMono8x8PatternFillRect;
13609885543Smrg
13709885543Smrg    /* 8x8 Color Pattern Fills */
13809885543Smrg    if (!SMI_LYNX3D_SERIES(pSmi->Chipset) || (pScrn->bitsPerPixel != 24)) {
13909885543Smrg	infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK
14009885543Smrg					  | HARDWARE_PATTERN_SCREEN_ORIGIN;
14109885543Smrg	infoPtr->SetupForColor8x8PatternFill =
14209885543Smrg		SMI_SetupForColor8x8PatternFill;
14309885543Smrg	infoPtr->SubsequentColor8x8PatternFillRect =
14409885543Smrg		SMI_SubsequentColor8x8PatternFillRect;
14509885543Smrg    }
14609885543Smrg
14709885543Smrg#if SMI_USE_IMAGE_WRITES
14809885543Smrg    /* Image Writes */
14909885543Smrg    infoPtr->ImageWriteFlags = ROP_NEEDS_SOURCE
15009885543Smrg			     | NO_PLANEMASK
15109885543Smrg			     | CPU_TRANSFER_PAD_DWORD
15209885543Smrg			     | SCANLINE_PAD_DWORD;
15309885543Smrg    infoPtr->ImageWriteBase = pSmi->DataPortBase;
15409885543Smrg    infoPtr->ImageWriteRange = pSmi->DataPortSize;
15509885543Smrg    infoPtr->SetupForImageWrite = SMI_SetupForImageWrite;
15609885543Smrg    infoPtr->SubsequentImageWriteRect = SMI_SubsequentImageWriteRect;
15709885543Smrg#endif
15809885543Smrg
15909885543Smrg    /* Clipping */
16009885543Smrg    infoPtr->ClippingFlags = HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY
16109885543Smrg			   | HARDWARE_CLIP_MONO_8x8_FILL
16209885543Smrg			   | HARDWARE_CLIP_COLOR_8x8_FILL
16309885543Smrg			   | HARDWARE_CLIP_SOLID_FILL
16409885543Smrg			   | HARDWARE_CLIP_SOLID_LINE
16509885543Smrg			   | HARDWARE_CLIP_DASHED_LINE;
16609885543Smrg    infoPtr->SetClippingRectangle = SMI_SetClippingRectangle;
16709885543Smrg    infoPtr->DisableClipping = SMI_DisableClipping;
16809885543Smrg
16909885543Smrg    /* Pixmap Cache */
17009885543Smrg    if (pScrn->bitsPerPixel == 24) {
17109885543Smrg	infoPtr->CachePixelGranularity = 16;
17209885543Smrg    } else {
17309885543Smrg	infoPtr->CachePixelGranularity = 128 / pScrn->bitsPerPixel;
17409885543Smrg    }
17509885543Smrg
17609885543Smrg    /* Offscreen Pixmaps */
17709885543Smrg    infoPtr->maxOffPixWidth  = 4096;
17809885543Smrg    infoPtr->maxOffPixHeight = 4096;
17909885543Smrg    if (pScrn->bitsPerPixel == 24) {
18009885543Smrg	infoPtr->maxOffPixWidth = 4096 / 3;
18109885543Smrg
18209885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
18309885543Smrg	    infoPtr->maxOffPixHeight = 4096 / 3;
18409885543Smrg	}
18509885543Smrg    }
18609885543Smrg
18709885543Smrg    SMI_EngineReset(pScrn);
18809885543Smrg
18909885543Smrg
19009885543Smrg    /* CZ 18.06.2001: moved to smi_driver.c before the NoAccel question
19109885543Smrg       to have offscreen framebuffer in NoAccel mode */
19209885543Smrg#if 0
19309885543Smrg    maxLines = pSmi->FBReserved / (pSmi->width * pSmi->Bpp);
19409885543Smrg    if (pSmi->rotate) {
19509885543Smrg	numLines = maxLines;
19609885543Smrg    } else {
19709885543Smrg#if SMI_USE_VIDEO
19809885543Smrg	numLines = ((pSmi->FBReserved - pSmi->width * pSmi->Bpp * pSmi->height)
19909885543Smrg		   * 25 / 100 + pSmi->width * pSmi->Bpp - 1)
20009885543Smrg		   / (pSmi->width * pSmi->Bpp);
20109885543Smrg	numLines += pSmi->height;
20209885543Smrg#else
20309885543Smrg	numLines = maxLines;
20409885543Smrg#endif
20509885543Smrg    }
20609885543Smrg
20709885543Smrg    AvailFBArea.x1 = 0;
20809885543Smrg    AvailFBArea.y1 = 0;
20909885543Smrg    AvailFBArea.x2 = pSmi->width;
21009885543Smrg    AvailFBArea.y2 = numLines;
21109885543Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "FrameBuffer Box: %d,%d - %d,%d\n",
21209885543Smrg		AvailFBArea.x1, AvailFBArea.y1, AvailFBArea.x2, AvailFBArea.y2);
21309885543Smrg    xf86InitFBManager(pScreen, &AvailFBArea);
21409885543Smrg#endif
21509885543Smrg
21609885543Smrg    ret = XAAInit(pScreen, infoPtr);
21709885543Smrg    if (ret && pSmi->shadowFB)	/* #671 */ {
21809885543Smrg	pSmi->ValidatePolylines = infoPtr->ValidatePolylines;
21909885543Smrg	infoPtr->ValidatePolylines = SMI_ValidatePolylines;
22009885543Smrg    }
22109885543Smrg
22209885543Smrg    LEAVE_PROC("SMI_XAAInit");
22309885543Smrg    return ret;
22409885543Smrg}
22509885543Smrg
22609885543Smrg/******************************************************************************/
22709885543Smrg/*	Screen to Screen Copies						      */
22809885543Smrg/******************************************************************************/
22909885543Smrg
23009885543Smrgstatic void
23109885543SmrgSMI_SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
23209885543Smrg			       unsigned int planemask, int trans)
23309885543Smrg{
23409885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
23509885543Smrg
23609885543Smrg    ENTER_PROC("SMI_SetupForScreenToScreenCopy");
23709885543Smrg    DEBUG((VERBLEV, "xdir=%d ydir=%d rop=%02X trans=%08X\n", xdir, ydir,
23809885543Smrg	   rop, trans));
23909885543Smrg
24009885543Smrg    pSmi->AccelCmd = XAAGetCopyROP(rop)
24109885543Smrg		   | SMI_BITBLT
24209885543Smrg		   | SMI_START_ENGINE;
24309885543Smrg
24409885543Smrg    if ((xdir == -1) || (ydir == -1)) {
24509885543Smrg	pSmi->AccelCmd |= SMI_RIGHT_TO_LEFT;
24609885543Smrg    }
24709885543Smrg
24809885543Smrg    if (trans != -1) {
24909885543Smrg	pSmi->AccelCmd |= SMI_TRANSPARENT_SRC | SMI_TRANSPARENT_PXL;
25009885543Smrg	WaitQueue(1);
25109885543Smrg	WRITE_DPR(pSmi, 0x20, trans);
25209885543Smrg    }
25309885543Smrg
25409885543Smrg    if (pSmi->ClipTurnedOn) {
25509885543Smrg	WaitQueue(1);
25609885543Smrg	WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
25709885543Smrg	pSmi->ClipTurnedOn = FALSE;
25809885543Smrg    }
25909885543Smrg
26009885543Smrg    LEAVE_PROC("SMI_SetupForScreenToScreenCopy");
26109885543Smrg}
26209885543Smrg
26309885543Smrgstatic void
26409885543SmrgSMI_SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2,
26509885543Smrg				 int y2, int w, int h)
26609885543Smrg{
26709885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
26809885543Smrg
26909885543Smrg    ENTER_PROC("SMI_SubsequentScreenToScreenCopy");
27009885543Smrg    DEBUG((VERBLEV, "x1=%d y1=%d x2=%d y2=%d w=%d h=%d\n", x1, y1, x2, y2, w, h));
27109885543Smrg
27209885543Smrg    if (pSmi->AccelCmd & SMI_RIGHT_TO_LEFT) {
27309885543Smrg	x1 += w - 1;
27409885543Smrg	y1 += h - 1;
27509885543Smrg	x2 += w - 1;
27609885543Smrg	y2 += h - 1;
27709885543Smrg    }
27809885543Smrg
27909885543Smrg    if (pScrn->bitsPerPixel == 24) {
28009885543Smrg	x1 *= 3;
28109885543Smrg	x2 *= 3;
28209885543Smrg	w  *= 3;
28309885543Smrg
28409885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
28509885543Smrg	    y1 *= 3;
28609885543Smrg	    y2 *= 3;
28709885543Smrg	}
28809885543Smrg
28909885543Smrg	if (pSmi->AccelCmd & SMI_RIGHT_TO_LEFT) {
29009885543Smrg	    x1 += 2;
29109885543Smrg	    x2 += 2;
29209885543Smrg	}
29309885543Smrg    }
29409885543Smrg
29509885543Smrg    WaitQueue(4);
29609885543Smrg    WRITE_DPR(pSmi, 0x00, (x1 << 16) + (y1 & 0xFFFF));
29709885543Smrg    WRITE_DPR(pSmi, 0x04, (x2 << 16) + (y2 & 0xFFFF));
29809885543Smrg    WRITE_DPR(pSmi, 0x08, (w  << 16) + (h  & 0xFFFF));
29909885543Smrg    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
30009885543Smrg
30109885543Smrg    LEAVE_PROC("SMI_SubsequentScreenToScreenCopy");
30209885543Smrg}
30309885543Smrg
30409885543Smrg/******************************************************************************/
30509885543Smrg/*   Solid Fills							      */
30609885543Smrg/******************************************************************************/
30709885543Smrg
30809885543Smrgstatic void
30909885543SmrgSMI_SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
31009885543Smrg		      unsigned int planemask)
31109885543Smrg{
31209885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
31309885543Smrg
31409885543Smrg    ENTER_PROC("SMI_SetupForSolidFill");
31509885543Smrg    DEBUG((VERBLEV, "color=%08X rop=%02X\n", color, rop));
31609885543Smrg
31709885543Smrg    pSmi->AccelCmd = XAAGetPatternROP(rop)
31809885543Smrg		   | SMI_BITBLT
31909885543Smrg		   | SMI_START_ENGINE;
32009885543Smrg
32109885543Smrg    if (pSmi->ClipTurnedOn) {
32209885543Smrg	WaitQueue(4);
32309885543Smrg	WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
32409885543Smrg	pSmi->ClipTurnedOn = FALSE;
32509885543Smrg    } else {
32609885543Smrg	WaitQueue(3);
32709885543Smrg    }
32809885543Smrg    WRITE_DPR(pSmi, 0x14, color);
32909885543Smrg    WRITE_DPR(pSmi, 0x34, 0xFFFFFFFF);
33009885543Smrg    WRITE_DPR(pSmi, 0x38, 0xFFFFFFFF);
33109885543Smrg
33209885543Smrg    LEAVE_PROC("SMI_SetupForSolidFill");
33309885543Smrg}
33409885543Smrg
33509885543Smrgvoid
33609885543SmrgSMI_SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
33709885543Smrg{
33809885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
33909885543Smrg
34009885543Smrg    ENTER_PROC("SMI_SubsequentSolidFillRect");
34109885543Smrg    DEBUG((VERBLEV, "x=%d y=%d w=%d h=%d\n", x, y, w, h));
34209885543Smrg
34309885543Smrg    if (pScrn->bitsPerPixel == 24) {
34409885543Smrg	x *= 3;
34509885543Smrg	w *= 3;
34609885543Smrg
34709885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
34809885543Smrg	    y *= 3;
34909885543Smrg	}
35009885543Smrg    }
35109885543Smrg
35209885543Smrg    WaitQueue(3);
35309885543Smrg    WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
35409885543Smrg    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
35509885543Smrg    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
35609885543Smrg
35709885543Smrg    LEAVE_PROC("SMI_SubsequentSolidFillRect");
35809885543Smrg}
35909885543Smrg
36009885543Smrg/******************************************************************************/
36109885543Smrg/*   Solid Lines							      */
36209885543Smrg/******************************************************************************/
36309885543Smrg
36409885543Smrgstatic void
36509885543SmrgSMI_SubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len,
36609885543Smrg							   int dir)
36709885543Smrg{
36809885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
36909885543Smrg    int w, h;
37009885543Smrg
37109885543Smrg    ENTER_PROC("SMI_SubsequentSolidHorVertLine");
37209885543Smrg    DEBUG((VERBLEV, "x=%d y=%d len=%d dir=%d\n", x, y, len, dir));
37309885543Smrg
37409885543Smrg    if (dir == DEGREES_0) {
37509885543Smrg	w = len;
37609885543Smrg	h = 1;
37709885543Smrg    } else {
37809885543Smrg	w = 1;
37909885543Smrg	h = len;
38009885543Smrg    }
38109885543Smrg
38209885543Smrg    if (pScrn->bitsPerPixel == 24) {
38309885543Smrg	x *= 3;
38409885543Smrg	w *= 3;
38509885543Smrg
38609885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
38709885543Smrg	    y *= 3;
38809885543Smrg	}
38909885543Smrg    }
39009885543Smrg
39109885543Smrg    WaitQueue(3);
39209885543Smrg    WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
39309885543Smrg    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
39409885543Smrg    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
39509885543Smrg
39609885543Smrg    LEAVE_PROC("SMI_SubsequentSolidHorVertLine");
39709885543Smrg}
39809885543Smrg
39909885543Smrg/******************************************************************************/
40009885543Smrg/*  Color Expansion Fills						      */
40109885543Smrg/******************************************************************************/
40209885543Smrg
40309885543Smrgstatic void
40409885543SmrgSMI_SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg,
40509885543Smrg				       int rop, unsigned int planemask)
40609885543Smrg{
40709885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
40809885543Smrg
40909885543Smrg    ENTER_PROC("SMI_SetupForCPUToScreenColorExpandFill");
41009885543Smrg    DEBUG((VERBLEV, "fg=%08X bg=%08X rop=%02X\n", fg, bg, rop));
41109885543Smrg
41209885543Smrg    pSmi->AccelCmd = XAAGetCopyROP(rop)
41309885543Smrg		   | SMI_HOSTBLT_WRITE
41409885543Smrg		   | SMI_SRC_MONOCHROME
41509885543Smrg		   | SMI_START_ENGINE;
41609885543Smrg
41709885543Smrg    if (bg == -1) {
41809885543Smrg	pSmi->AccelCmd |= SMI_TRANSPARENT_SRC;
41909885543Smrg
42009885543Smrg	WaitQueue(3);
42109885543Smrg	WRITE_DPR(pSmi, 0x14, fg);
42209885543Smrg	WRITE_DPR(pSmi, 0x18, ~fg);
42309885543Smrg	WRITE_DPR(pSmi, 0x20, fg);
42409885543Smrg    } else {
42509885543Smrg	WaitQueue(2);
42609885543Smrg	WRITE_DPR(pSmi, 0x14, fg);
42709885543Smrg	WRITE_DPR(pSmi, 0x18, bg);
42809885543Smrg    }
42909885543Smrg
43009885543Smrg    LEAVE_PROC("SMI_SetupForCPUToScreenColorExpandFill");
43109885543Smrg}
43209885543Smrg
43309885543Smrgvoid
43409885543SmrgSMI_SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, int y, int w,
43509885543Smrg					 int h, int skipleft)
43609885543Smrg{
43709885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
43809885543Smrg
43909885543Smrg    ENTER_PROC("SMI_SubsequentCPUToScreenColorExpandFill");
44009885543Smrg    DEBUG((VERBLEV, "x=%d y=%d w=%d h=%d skipleft=%d\n", x, y, w, h, skipleft));
44109885543Smrg
44209885543Smrg    if (pScrn->bitsPerPixel == 24) {
44309885543Smrg	x        *= 3;
44409885543Smrg	w        *= 3;
44509885543Smrg	skipleft *= 3;
44609885543Smrg
44709885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
44809885543Smrg	    y *= 3;
44909885543Smrg	}
45009885543Smrg    }
45109885543Smrg
45209885543Smrg    if (skipleft) {
45309885543Smrg	WaitQueue(5);
45409885543Smrg	WRITE_DPR(pSmi, 0x2C, (pSmi->ScissorsLeft & 0xFFFF0000)
45509885543Smrg			      | (x + skipleft) | 0x2000);
45609885543Smrg	pSmi->ClipTurnedOn = TRUE;
45709885543Smrg    } else {
45809885543Smrg	if (pSmi->ClipTurnedOn) {
45909885543Smrg	    WaitQueue(5);
46009885543Smrg	    WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
46109885543Smrg	    pSmi->ClipTurnedOn = FALSE;
46209885543Smrg	} else {
46309885543Smrg	    WaitQueue(4);
46409885543Smrg	}
46509885543Smrg    }
46609885543Smrg    WRITE_DPR(pSmi, 0x00, 0);
46709885543Smrg    WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
46809885543Smrg    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
46909885543Smrg    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
47009885543Smrg
47109885543Smrg    LEAVE_PROC("SMI_SubsequentCPUToScreenColorExpandFill");
47209885543Smrg}
47309885543Smrg
47409885543Smrg/******************************************************************************/
47509885543Smrg/* 8x8 Mono Pattern Fills						      */
47609885543Smrg/******************************************************************************/
47709885543Smrg
47809885543Smrgstatic void
47909885543SmrgSMI_SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, int fg,
48009885543Smrg			       int bg, int rop, unsigned int planemask)
48109885543Smrg{
48209885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
48309885543Smrg
48409885543Smrg    ENTER_PROC("SMI_SetupForMono8x8PatternFill");
48509885543Smrg    DEBUG((VERBLEV, "patx=%08X paty=%08X fg=%08X bg=%08X rop=%02X\n", patx,
48609885543Smrg	   paty, fg, bg, rop));
48709885543Smrg
48809885543Smrg    pSmi->AccelCmd = XAAGetPatternROP(rop)
48909885543Smrg		   | SMI_BITBLT
49009885543Smrg		   | SMI_START_ENGINE;
49109885543Smrg
49209885543Smrg    if (pSmi->ClipTurnedOn) {
49309885543Smrg	WaitQueue(1);
49409885543Smrg	WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
49509885543Smrg	pSmi->ClipTurnedOn = FALSE;
49609885543Smrg    }
49709885543Smrg
49809885543Smrg    if (bg == -1) {
49909885543Smrg	WaitQueue(5);
50009885543Smrg	WRITE_DPR(pSmi, 0x14, fg);
50109885543Smrg	WRITE_DPR(pSmi, 0x18, ~fg);
50209885543Smrg	WRITE_DPR(pSmi, 0x20, fg);
50309885543Smrg	WRITE_DPR(pSmi, 0x34, patx);
50409885543Smrg	WRITE_DPR(pSmi, 0x38, paty);
50509885543Smrg    } else {
50609885543Smrg	WaitQueue(4);
50709885543Smrg	WRITE_DPR(pSmi, 0x14, fg);
50809885543Smrg	WRITE_DPR(pSmi, 0x18, bg);
50909885543Smrg	WRITE_DPR(pSmi, 0x34, patx);
51009885543Smrg	WRITE_DPR(pSmi, 0x38, paty);
51109885543Smrg    }
51209885543Smrg
51309885543Smrg    LEAVE_PROC("SMI_SetupForMono8x8PatternFill");
51409885543Smrg}
51509885543Smrg
51609885543Smrgstatic void
51709885543SmrgSMI_SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty,
51809885543Smrg				     int x, int y, int w, int h)
51909885543Smrg{
52009885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
52109885543Smrg
52209885543Smrg    ENTER_PROC("SMI_SubsequentMono8x8PatternFillRect");
52309885543Smrg    DEBUG((VERBLEV, "x=%d y=%d w=%d h=%d\n", x, y, w, h));
52409885543Smrg
52509885543Smrg    if (pScrn->bitsPerPixel == 24) {
52609885543Smrg	x *= 3;
52709885543Smrg	w *= 3;
52809885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
52909885543Smrg	    y *= 3;
53009885543Smrg	}
53109885543Smrg    }
53209885543Smrg
53309885543Smrg    WaitQueue(3);
53409885543Smrg    WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
53509885543Smrg    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
53609885543Smrg    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
53709885543Smrg
53809885543Smrg    LEAVE_PROC("SMI_SubsequentMono8x8PatternFillRect");
53909885543Smrg}
54009885543Smrg
54109885543Smrg/******************************************************************************/
54209885543Smrg/* 8x8 Color Pattern Fills						      */
54309885543Smrg/******************************************************************************/
54409885543Smrg
54509885543Smrgstatic void
54609885543SmrgSMI_SetupForColor8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, int rop,
54709885543Smrg				unsigned int planemask, int trans_color)
54809885543Smrg{
54909885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
55009885543Smrg
55109885543Smrg    ENTER_PROC("SMI_SetupForColor8x8PatternFill");
55209885543Smrg    DEBUG((VERBLEV, "patx=%d paty=%d rop=%02X trans_color=%08X\n", patx, paty,
55309885543Smrg	   rop, trans_color));
55409885543Smrg
55509885543Smrg    pSmi->AccelCmd = XAAGetPatternROP(rop)
55609885543Smrg		   | SMI_BITBLT
55709885543Smrg		   | SMI_COLOR_PATTERN
55809885543Smrg		   | SMI_START_ENGINE;
55909885543Smrg
56009885543Smrg    if (pScrn->bitsPerPixel <= 16) {
56109885543Smrg	/* PDR#950 */
56209885543Smrg	CARD8* pattern = pSmi->FBBase + (patx + paty * pSmi->Stride) * pSmi->Bpp;
56309885543Smrg
56409885543Smrg	WaitIdleEmpty();
56509885543Smrg	WRITE_DPR(pSmi, 0x0C, SMI_BITBLT | SMI_COLOR_PATTERN);
56609885543Smrg	memcpy(pSmi->DataPortBase, pattern, 8 * pSmi->Bpp * 8);
56709885543Smrg    } else {
56809885543Smrg	if (pScrn->bitsPerPixel == 24) {
56909885543Smrg	    patx *= 3;
57009885543Smrg
57109885543Smrg	    if (pSmi->Chipset == SMI_LYNX) {
57209885543Smrg		paty *= 3;
57309885543Smrg	    }
57409885543Smrg	}
57509885543Smrg
57609885543Smrg	WaitQueue(1);
57709885543Smrg	WRITE_DPR(pSmi, 0x00, (patx << 16) | (paty & 0xFFFF));
57809885543Smrg    }
57909885543Smrg
58009885543Smrg    if (trans_color == -1) {
58109885543Smrg	pSmi->AccelCmd |= SMI_TRANSPARENT_SRC | SMI_TRANSPARENT_PXL;
58209885543Smrg
58309885543Smrg	WaitQueue(1);
58409885543Smrg	WRITE_DPR(pSmi, 0x20, trans_color);
58509885543Smrg    }
58609885543Smrg
58709885543Smrg    if (pSmi->ClipTurnedOn) {
58809885543Smrg	WaitQueue(1);
58909885543Smrg	WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
59009885543Smrg	pSmi->ClipTurnedOn = FALSE;
59109885543Smrg    }
59209885543Smrg
59309885543Smrg    LEAVE_PROC("SMI_SetupForColor8x8PatternFill");
59409885543Smrg}
59509885543Smrg
59609885543Smrgstatic void
59709885543SmrgSMI_SubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty,
59809885543Smrg				      int x, int y, int w, int h)
59909885543Smrg{
60009885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
60109885543Smrg
60209885543Smrg    ENTER_PROC("SMI_SubsequentColor8x8PatternFillRect");
60309885543Smrg    DEBUG((VERBLEV, "x=%d y=%d w=%d h=%d\n", x, y, w, h));
60409885543Smrg
60509885543Smrg    if (pScrn->bitsPerPixel == 24) {
60609885543Smrg	x *= 3;
60709885543Smrg	w *= 3;
60809885543Smrg
60909885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
61009885543Smrg	    y *= 3;
61109885543Smrg	}
61209885543Smrg    }
61309885543Smrg
61409885543Smrg    WaitQueue(3);
61509885543Smrg    WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
61609885543Smrg    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));	/* PDR#950 */
61709885543Smrg    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
61809885543Smrg
61909885543Smrg    LEAVE_PROC("SMI_SubsequentColor8x8PatternFillRect");
62009885543Smrg}
62109885543Smrg
62209885543Smrg#if SMI_USE_IMAGE_WRITES
62309885543Smrg/******************************************************************************/
62409885543Smrg/*  Image Writes							      */
62509885543Smrg/******************************************************************************/
62609885543Smrg
62709885543Smrgstatic void
62809885543SmrgSMI_SetupForImageWrite(ScrnInfoPtr pScrn, int rop, unsigned int planemask,
62909885543Smrg		       int trans_color, int bpp, int depth)
63009885543Smrg{
63109885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
63209885543Smrg
63309885543Smrg    ENTER_PROC("SMI_SetupForImageWrite");
63409885543Smrg    DEBUG((VERBLEV, "rop=%02X trans_color=%08X bpp=%d depth=%d\n", rop,
63509885543Smrg	   trans_color, bpp, depth));
63609885543Smrg
63709885543Smrg    pSmi->AccelCmd = XAAGetCopyROP(rop)
63809885543Smrg		   | SMI_HOSTBLT_WRITE
63909885543Smrg		   | SMI_START_ENGINE;
64009885543Smrg
64109885543Smrg    if (trans_color != -1) {
64209885543Smrg	pSmi->AccelCmd |= SMI_TRANSPARENT_SRC | SMI_TRANSPARENT_PXL;
64309885543Smrg
64409885543Smrg	WaitQueue(1);
64509885543Smrg	WRITE_DPR(pSmi, 0x20, trans_color);
64609885543Smrg    }
64709885543Smrg
64809885543Smrg    LEAVE_PROC("SMI_SetupForImageWrite");
64909885543Smrg}
65009885543Smrg
65109885543Smrgstatic void
65209885543SmrgSMI_SubsequentImageWriteRect(ScrnInfoPtr pScrn, int x, int y, int w, int h,
65309885543Smrg			     int skipleft)
65409885543Smrg{
65509885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
65609885543Smrg
65709885543Smrg    ENTER_PROC("SMI_SubsequentImageWriteRect");
65809885543Smrg    DEBUG((VERBLEV, "x=%d y=%d w=%d h=%d skipleft=%d\n", x, y, w, h, skipleft));
65909885543Smrg
66009885543Smrg    if (pScrn->bitsPerPixel == 24) {
66109885543Smrg	x        *= 3;
66209885543Smrg	w        *= 3;
66309885543Smrg	skipleft *= 3;
66409885543Smrg
66509885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
66609885543Smrg	    y *= 3;
66709885543Smrg	}
66809885543Smrg    }
66909885543Smrg
67009885543Smrg    if (skipleft) {
67109885543Smrg	WaitQueue(5);
67209885543Smrg	WRITE_DPR(pSmi, 0x2C, (pSmi->ScissorsLeft & 0xFFFF0000) |
67309885543Smrg			      (x + skipleft) | 0x2000);
67409885543Smrg	pSmi->ClipTurnedOn = TRUE;
67509885543Smrg    } else {
67609885543Smrg	if (pSmi->ClipTurnedOn) {
67709885543Smrg	    WaitQueue(5);
67809885543Smrg	    WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
67909885543Smrg	    pSmi->ClipTurnedOn = FALSE;
68009885543Smrg	} else {
68109885543Smrg	    WaitQueue(4);
68209885543Smrg	}
68309885543Smrg    }
68409885543Smrg    WRITE_DPR(pSmi, 0x00, 0);
68509885543Smrg    WRITE_DPR(pSmi, 0x04, (x << 16) | (y * 0xFFFF));
68609885543Smrg    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
68709885543Smrg    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
68809885543Smrg
68909885543Smrg    LEAVE_PROC("SMI_SubsequentImageWriteRect");
69009885543Smrg}
69109885543Smrg#endif
69209885543Smrg
69309885543Smrg/******************************************************************************/
69409885543Smrg/*  Polylines							         #671 */
69509885543Smrg/******************************************************************************/
69609885543Smrg
69709885543Smrg/*
69809885543Smrg
69909885543SmrgIn order to speed up the "logout" screen in rotated modes, we need to intercept
70009885543Smrgthe Polylines function. Normally, the polylines are drawn and the shadowFB is
70109885543Smrgthen sending a request of the bounding rectangle of those poylines. This should
70209885543Smrgbe okay, if it weren't for the fact that the Gnome logout screen is drawing
70309885543Smrgpolylines in rectangles and this asks for a rotation of the entire rectangle.
70409885543SmrgThis is very slow.
70509885543Smrg
70609885543SmrgTo circumvent this slowness, we intercept the ValidatePolylines function and
70709885543Smrgoverride the default "Fallback" Polylines with our own Polylines function. Our
70809885543SmrgPolylines function first draws the polylines through the original Fallback
70909885543Smrgfunction and then rotates the lines, line by line. We then set a flag and
71009885543Smrgreturn control to the shadowFB which will try to rotate the bounding rectangle.
71109885543SmrgHowever, the flag has been set and the RefreshArea function does nothing but
71209885543Smrgclear the flag so the next Refresh that comes in shoiuld be handled correctly.
71309885543Smrg
71409885543SmrgAll this code improves the speed quite a bit.
71509885543Smrg
71609885543Smrg*/
71709885543Smrg
71809885543Smrg#define IS_VISIBLE(pWin) \
71909885543Smrg( \
72009885543Smrg    pScrn->vtSema \
72109885543Smrg    && (((WindowPtr) pWin)->visibility != VisibilityFullyObscured) \
72209885543Smrg)
72309885543Smrg
72409885543Smrg#define TRIM_BOX(box, pGC) \
72509885543Smrg{ \
72609885543Smrg    BoxPtr extents = &pGC->pCompositeClip->extents; \
72709885543Smrg    if (box.x1 < extents->x1) box.x1 = extents->x1; \
72809885543Smrg    if (box.y1 < extents->y1) box.y1 = extents->y1; \
72909885543Smrg    if (box.x2 > extents->x2) box.x2 = extents->x2; \
73009885543Smrg    if (box.y2 > extents->y2) box.y2 = extents->y2; \
73109885543Smrg}
73209885543Smrg
73309885543Smrg#define TRANSLATE_BOX(box, pDraw) \
73409885543Smrg{ \
73509885543Smrg    box.x1 += pDraw->x; \
73609885543Smrg    box.y1 += pDraw->y; \
73709885543Smrg    box.x2 += pDraw->x; \
73809885543Smrg    box.y2 += pDraw->y; \
73909885543Smrg}
74009885543Smrg
74109885543Smrg#define BOX_NOT_EMPTY(box) \
74209885543Smrg    ((box.x2 > box.x1) && (box.y2 > box.y1))
74309885543Smrg
74409885543Smrgstatic void
74509885543SmrgSMI_ValidatePolylines(GCPtr pGC, unsigned long changes, DrawablePtr pDraw)
74609885543Smrg{
74709885543Smrg    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
74809885543Smrg    SMIPtr pSmi = SMIPTR(infoRec->pScrn);
74909885543Smrg
75009885543Smrg    ENTER_PROC("SMI_ValidatePolylines");
75109885543Smrg
75209885543Smrg    pSmi->ValidatePolylines(pGC, changes, pDraw);
75309885543Smrg    if (pGC->ops->Polylines == XAAGetFallbackOps()->Polylines) {
75409885543Smrg	/* Override the Polylines function with our own Polylines function. */
75509885543Smrg	pGC->ops->Polylines = SMI_Polylines;
75609885543Smrg    }
75709885543Smrg
75809885543Smrg    LEAVE_PROC("SMI_ValidatePolylines");
75909885543Smrg}
76009885543Smrg
76109885543Smrgstatic void
76209885543SmrgSMI_Polylines(DrawablePtr pDraw, GCPtr pGC, int mode, int npt,
76309885543Smrg	      DDXPointPtr pptInit)
76409885543Smrg{
76509885543Smrg    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
76609885543Smrg    ScrnInfoPtr pScrn = infoRec->pScrn;
76709885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
76809885543Smrg
76909885543Smrg    ENTER_PROC("SMI_Polylines");
77009885543Smrg
77109885543Smrg    /* Call the original Polylines function. */
77209885543Smrg    pGC->ops->Polylines = XAAGetFallbackOps()->Polylines;
77309885543Smrg    (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit);
77409885543Smrg    pGC->ops->Polylines = SMI_Polylines;
77509885543Smrg
77609885543Smrg    if (IS_VISIBLE(pDraw) && npt) {
77709885543Smrg	/* Allocate a temporary buffer for all segments of the polyline. */
77809885543Smrg	BoxPtr pBox = xnfcalloc(sizeof(BoxRec), npt);
77909885543Smrg	int extra = pGC->lineWidth >> 1, box;
78009885543Smrg
78109885543Smrg	if (npt > 1) {
78209885543Smrg	    /* Adjust the extra space required per polyline segment. */
78309885543Smrg	    if (pGC->joinStyle == JoinMiter) {
78409885543Smrg		extra = 6 * pGC->lineWidth;
78509885543Smrg	    } else if (pGC->capStyle == CapProjecting) {
78609885543Smrg		extra = pGC->lineWidth;
78709885543Smrg	    }
78809885543Smrg	}
78909885543Smrg
79009885543Smrg	for (box = 0; --npt;) {
79109885543Smrg	    /* Setup the bounding box for one polyline segment. */
79209885543Smrg	    pBox[box].x1 = pptInit->x;
79309885543Smrg	    pBox[box].y1 = pptInit->y;
79409885543Smrg	    pptInit++;
79509885543Smrg	    pBox[box].x2 = pptInit->x;
79609885543Smrg	    pBox[box].y2 = pptInit->y;
79709885543Smrg	    if (mode == CoordModePrevious) {
79809885543Smrg		pBox[box].x2 += pBox[box].x1;
79909885543Smrg		pBox[box].y2 += pBox[box].y1;
80009885543Smrg	    }
80109885543Smrg
80209885543Smrg	    /* Sort coordinates. */
80309885543Smrg	    if (pBox[box].x1 > pBox[box].x2) {
80409885543Smrg		int tmp = pBox[box].x1;
80509885543Smrg		pBox[box].x1 = pBox[box].x2;
80609885543Smrg		pBox[box].x2 = tmp;
80709885543Smrg	    }
80809885543Smrg	    if (pBox[box].y1 > pBox[box].y2) {
80909885543Smrg		int tmp = pBox[box].y1;
81009885543Smrg		pBox[box].y1 = pBox[box].y2;
81109885543Smrg		pBox[box].y2 = tmp;
81209885543Smrg	    }
81309885543Smrg
81409885543Smrg	    /* Add extra space required for each polyline segment. */
81509885543Smrg	    pBox[box].x1 -= extra;
81609885543Smrg	    pBox[box].y1 -= extra;
81709885543Smrg	    pBox[box].x2 += extra + 1;
81809885543Smrg	    pBox[box].y2 += extra + 1;
81909885543Smrg
82009885543Smrg	    /* See if we need to draw this polyline segment. */
82109885543Smrg	    TRANSLATE_BOX(pBox[box], pDraw);
82209885543Smrg	    TRIM_BOX(pBox[box], pGC);
82309885543Smrg	    if (BOX_NOT_EMPTY(pBox[box])) {
82409885543Smrg		box++;
82509885543Smrg	    }
82609885543Smrg	}
82709885543Smrg
82809885543Smrg	if (box) {
82909885543Smrg	    /* Refresh all polyline segments now. */
83009885543Smrg	    if (pSmi->Chipset == SMI_COUGAR3DR) {
83109885543Smrg		SMI_RefreshArea730(pScrn, box, pBox);
83209885543Smrg	    } else {
83309885543Smrg		SMI_RefreshArea(pScrn, box, pBox);
83409885543Smrg	    }
83509885543Smrg	}
83609885543Smrg
83709885543Smrg	/* Free the temporary buffer. */
83809885543Smrg	xfree(pBox);
83909885543Smrg    }
84009885543Smrg
84109885543Smrg    pSmi->polyLines = TRUE;
84209885543Smrg    LEAVE_PROC("SMI_Polylines");
84309885543Smrg}
84409885543Smrg
845