/*
 * Copyright 1992-2003 by Alan Hourihane, North Wales, UK.
 *
 * Permission to use, copy, modify, distribute, and sell this software
 * and its documentation for any purpose is hereby granted without
 * fee, provided that the above copyright notice appear in all copies
 * and that both that copyright notice and this permission notice
 * appear in supporting documentation, and that the name of Alan
 * Hourihane not be used in advertising or publicity pertaining to
 * distribution of the software without specific, written prior
 * permission.  Alan Hourihane makes no representations about the
 * suitability of this software for any purpose.  It is provided
 * "as is" without express or implied warranty.
 *
 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS, IN NO EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY
 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 *
 * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
 *
 * Trident accelerated options.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "xf86.h"
#include "xf86_OSproc.h"

#include "xf86Pci.h"

#include "miline.h"

#include "trident.h"
#include "trident_regs.h"

#ifdef HAVE_XAA_H
#include "xaalocal.h"
#include "xaarop.h"

static void TridentSync(ScrnInfoPtr pScrn);
static void TridentSetupForDashedLine(ScrnInfoPtr pScrn,
                                        int fg, int bg,
                                        int rop,
                                        unsigned int planemask,
                                        int length,
                                        unsigned char *pattern);
static void TridentSubsequentDashedBresenhamLine(ScrnInfoPtr pScrn,
                                                    int x, int y,
                                                    int dmaj, int dmin,
                                                    int e, int len,
                                                    int octant,
                                                    int phase);
static void TridentSetupForSolidLine(ScrnInfoPtr pScrn,
                                        int color,
                                        int rop,
                                        unsigned int planemask);
static void TridentSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,
                                                int x, int y,
                                                int dmaj, int dmin,
                                                int e, int len,
                                                int octant);
static void TridentSubsequentSolidHorVertLine(ScrnInfoPtr pScrn,
                                                int x, int y,
                                                int len, int dir);
static void TridentSetupForFillRectSolid(ScrnInfoPtr pScrn,
                                            int color,
                                            int rop,
                                            unsigned int planemask);
static void TridentSubsequentFillRectSolid(ScrnInfoPtr pScrn,
                                            int x, int y,
                                            int w, int h);
static void TridentSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
                                                int x1, int y1,
                                                int x2, int y2,
                                                int w, int h);
static void TridentSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
                                                int xdir, int ydir,
                                                int rop,
                                                unsigned int planemask,
                                                int transparency_color);
static void TridentSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
                                                int patternx,
                                                int patterny,
                                                int fg, int bg,
                                                int rop,
                                                unsigned int planemask);
static void TridentSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
                                                    int patternx,
                                                    int patterny,
                                                    int x, int y,
                                                    int w, int h);
#if 0
static void TridentSetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
                                                int patternx,
                                                int patterny,
                                                int rop,
                                                unsigned int planemask,
                                                int trans_col);
static void TridentSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn,
                                                        int patternx,
                                                        int patterny,
                                                        int x, int y,
                                                        int w, int h);
#endif
#if 0
static void TridentSetupForScanlineCPUToScreenColorExpandFill(
                                            ScrnInfoPtr pScrn,
                                            int fg, int bg,
                                            int rop,
                                            unsigned int planemask);
static void TridentSubsequentScanlineCPUToScreenColorExpandFill(
                                    ScrnInfoPtr pScrn,
                                    int x, int y,
                                    int w, int h,
                                    int skipleft);
static void TridentSubsequentColorExpandScanline(ScrnInfoPtr pScrn,
                                                    int bufno);
#endif


static void
TridentInitializeAccelerator(ScrnInfoPtr pScrn)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);

    /* This forces updating the clipper */
    pTrident->Clipping = TRUE;

    CHECKCLIPPING;

    if ((pTrident->Chipset == PROVIDIA9682) ||
            (pTrident->Chipset == CYBER9385) ||
            (pTrident->Chipset == CYBER9382))
        pTrident->EngineOperation |= 0x100; /* Disable Clipping */

    TGUI_OPERMODE(pTrident->EngineOperation);

    pTrident->PatternLocation = pScrn->displayWidth *
                                pScrn->bitsPerPixel / 8;
}
#endif

Bool
TridentAccelInit(ScreenPtr pScreen)
{
#ifdef HAVE_XAA_H
    XAAInfoRecPtr infoPtr;
    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);

    if (pTrident->NoAccel)
        return FALSE;

    pTrident->AccelInfoRec = infoPtr = XAACreateInfoRec();
    if (!infoPtr) return FALSE;

    if (!((pTrident->Chipset == TGUI9440AGi) &&
            (pScrn->bitsPerPixel > 8)))
        infoPtr->Flags = PIXMAP_CACHE |
                            OFFSCREEN_PIXMAPS |
                            LINEAR_FRAMEBUFFER;

    pTrident->InitializeAccelerator = TridentInitializeAccelerator;
    TridentInitializeAccelerator(pScrn);

    infoPtr->PixmapCacheFlags = DO_NOT_BLIT_STIPPLES;

    infoPtr->Sync = TridentSync;

    infoPtr->SolidLineFlags = NO_PLANEMASK;
    infoPtr->SetupForSolidLine = TridentSetupForSolidLine;
    infoPtr->SolidBresenhamLineErrorTermBits = 12;
    infoPtr->SubsequentSolidBresenhamLine =
                                TridentSubsequentSolidBresenhamLine;
    infoPtr->SubsequentSolidHorVertLine =
                                TridentSubsequentSolidHorVertLine;

    infoPtr->DashedLineFlags = LINE_PATTERN_MSBFIRST_LSBJUSTIFIED |
                                NO_PLANEMASK |
                                LINE_PATTERN_POWER_OF_2_ONLY;
    infoPtr->SetupForDashedLine = TridentSetupForDashedLine;
    infoPtr->DashedBresenhamLineErrorTermBits = 12;
    infoPtr->SubsequentDashedBresenhamLine =
                                TridentSubsequentDashedBresenhamLine;
    infoPtr->DashPatternMaxLength = 16;

    infoPtr->SolidFillFlags = NO_PLANEMASK;
    infoPtr->SetupForSolidFill = TridentSetupForFillRectSolid;
    infoPtr->SubsequentSolidFillRect = TridentSubsequentFillRectSolid;

    infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK;

    if (!HAS_DST_TRANS)
        infoPtr->ScreenToScreenCopyFlags |= NO_TRANSPARENCY;

    infoPtr->SetupForScreenToScreenCopy =
                                    TridentSetupForScreenToScreenCopy;
    infoPtr->SubsequentScreenToScreenCopy =
                                TridentSubsequentScreenToScreenCopy;

    if (!(((pTrident->Chipset == PROVIDIA9685) ||
            (pTrident->Chipset == CYBER9388)) &&
            (pScrn->bitsPerPixel > 8))) {
        infoPtr->Mono8x8PatternFillFlags =  NO_PLANEMASK |
                                    HARDWARE_PATTERN_SCREEN_ORIGIN |
                                    BIT_ORDER_IN_BYTE_MSBFIRST;

        infoPtr->SetupForMono8x8PatternFill =
                                    TridentSetupForMono8x8PatternFill;
        infoPtr->SubsequentMono8x8PatternFillRect =
                            TridentSubsequentMono8x8PatternFillRect;
    }

#if 0
    /*
     * Not convinced this works 100% yet.
     */
    infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK |
                                    HARDWARE_PATTERN_SCREEN_ORIGIN |
                                    BIT_ORDER_IN_BYTE_MSBFIRST;

    if (!HAS_DST_TRANS)
        infoPtr->Color8x8PatternFillFlags |= NO_TRANSPARENCY;

    infoPtr->SetupForColor8x8PatternFill =
                                TridentSetupForColor8x8PatternFill;
    infoPtr->SubsequentColor8x8PatternFillRect =
                            TridentSubsequentColor8x8PatternFillRect;
#endif

#if 0
    /*
     * This is buggy, it only seems to work 95% of the time....
     */
    {
        infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
                                        NO_PLANEMASK |
                                        NO_TRANSPARENCY |
                                        BIT_ORDER_IN_BYTE_MSBFIRST;

        pTrident->XAAScanlineColorExpandBuffers[0] =
                            xnfalloc(((pScrn->virtualX + 63)) * 4 *
                                        (pScrn->bitsPerPixel / 8));

        infoPtr->NumScanlineColorExpandBuffers = 1;
        infoPtr->ScanlineColorExpandBuffers =
                            pTrident->XAAScanlineColorExpandBuffers;

        infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
                TridentSetupForScanlineCPUToScreenColorExpandFill;
        infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
                TridentSubsequentScanlineCPUToScreenColorExpandFill;
        infoPtr->SubsequentColorExpandScanline =
                TridentSubsequentColorExpandScanline;
    }
#endif

    return(XAAInit(pScreen, infoPtr));
#else
    return FALSE;
#endif
}

#ifdef HAVE_XAA_H
static void
TridentSync(ScrnInfoPtr pScrn)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    int count = 0, timeout = 0;
    int busy;

    TGUI_OPERMODE(pTrident->EngineOperation);

    for (;;) {
        BLTBUSY(busy);
        if (busy != GE_BUSY) {
            return;
        }

        count++;
        if (count == 10000000) {
            ErrorF("Trident: BitBLT engine time-out.\n");
            count = 9990000;
            timeout++;
            if (timeout == 8) {
                /* Reset BitBLT Engine */
                TGUI_STATUS(0x00);
                return;
            }
        }
    }
}

static void
TridentClearSync(ScrnInfoPtr pScrn)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    int count = 0, timeout = 0;
    int busy;

    for (;;) {
        BLTBUSY(busy);
        if (busy != GE_BUSY) {
            return;
        }
        count++;
        if (count == 10000000) {
            ErrorF("Trident: BitBLT engine time-out.\n");
            count = 9990000;
            timeout++;
            if (timeout == 8) {
                /* Reset BitBLT Engine */
                TGUI_STATUS(0x00);
                return;
            }
        }
    }
}

static void
TridentSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
                                    int xdir, int ydir,
                                    int rop,
                                    unsigned int planemask,
                                    int transparency_color)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    int dst = 0;

    pTrident->BltScanDirection = 0;
    if (xdir < 0) pTrident->BltScanDirection |= XNEG;
    if (ydir < 0) pTrident->BltScanDirection |= YNEG;

    REPLICATE(transparency_color);
    if (transparency_color != -1) {
        if ((pTrident->Chipset == PROVIDIA9685) ||
                (pTrident->Chipset == CYBER9388)) {
            dst |= (1 << 16);
        } else {
            TGUI_OPERMODE(pTrident->EngineOperation | DST_ENABLE);
        }
        TGUI_CKEY(transparency_color);
    }

    TGUI_DRAWFLAG(pTrident->DrawFlag | pTrident->BltScanDirection |
                    SCR2SCR | dst);
    TGUI_FMIX(XAAGetCopyROP(rop));
}

static void
TridentSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
                                    int x1, int y1,
                                    int x2, int y2,
                                    int w, int h)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);

    if (pTrident->BltScanDirection & YNEG) {
        y1 = y1 + h - 1;
        y2 = y2 + h - 1;
    }
    if (pTrident->BltScanDirection & XNEG) {
        x1 = x1 + w - 1;
        x2 = x2 + w - 1;
    }
    TGUI_SRC_XY(x1,y1);
    TGUI_DEST_XY(x2, y2);
    TGUI_DIM_XY(w, h);
    TGUI_COMMAND(GE_BLT);
    TridentClearSync(pScrn);
}

static void
TridentSetupForSolidLine(ScrnInfoPtr pScrn,
                            int color,
                            int rop,
                            unsigned int planemask)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);

    pTrident->BltScanDirection = 0;
    REPLICATE(color);
    TGUI_FMIX(XAAGetPatternROP(rop));
    if ((pTrident->Chipset == PROVIDIA9685) ||
            (pTrident->Chipset == CYBER9388)) {
        TGUI_FPATCOL(color);
    } else {
        TGUI_FCOLOUR(color);
    }
}

static void
TridentSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,
                                    int x, int y,
                                    int dmaj, int dmin,
                                    int e, int len, int octant)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    int tmp = pTrident->BltScanDirection;

    if (octant & YMAJOR) tmp |= YMAJ;
    if (octant & XDECREASING) tmp |= XNEG;
    if (octant & YDECREASING) tmp |= YNEG;
    TGUI_DRAWFLAG(pTrident->DrawFlag | SOLIDFILL | STENCIL | tmp);
    TGUI_SRC_XY(dmin-dmaj,dmin);
    TGUI_DEST_XY(x, y);
    TGUI_DIM_XY(dmin + e, len);
    TGUI_COMMAND(GE_BRESLINE);
    TridentSync(pScrn);
}

static void
TridentSubsequentSolidHorVertLine(ScrnInfoPtr pScrn,
                                    int x, int y,
                                    int len, int dir)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);

    TGUI_DRAWFLAG(pTrident->DrawFlag | SOLIDFILL);
    if (dir == DEGREES_0) {
        TGUI_DIM_XY(len, 1);
        TGUI_DEST_XY(x, y);
    } else {
        TGUI_DIM_XY(1, len);
        TGUI_DEST_XY(x, y);
    }
    TGUI_COMMAND(GE_BLT);
    TridentSync(pScrn);
}

void
TridentSetupForDashedLine(ScrnInfoPtr pScrn,
                            int fg, int bg,
                            int rop,
                            unsigned int planemask,
                            int length,
                            unsigned char *pattern)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    CARD32 *DashPattern = (CARD32*)pattern;
    CARD32 NiceDashPattern = DashPattern[0];

    NiceDashPattern = *((CARD16 *)pattern) & ((1 << length) - 1);
    switch(length) {
    case 2:	NiceDashPattern |= NiceDashPattern << 2;
    case 4:	NiceDashPattern |= NiceDashPattern << 4;
    case 8:	NiceDashPattern |= NiceDashPattern << 8;
    }
    pTrident->BltScanDirection = 0;
    REPLICATE(fg);
    if ((pTrident->Chipset == PROVIDIA9685) ||
            (pTrident->Chipset == CYBER9388)) {
        TGUI_FPATCOL(fg);
        if (bg == -1) {
            pTrident->BltScanDirection |= (1 << 12);
            TGUI_BPATCOL(~fg);
        } else {
            REPLICATE(bg);
            TGUI_BPATCOL(bg);
        }
    } else {
        TGUI_FCOLOUR(fg);
        if (bg == -1) {
            pTrident->BltScanDirection |= (1 << 12);
            TGUI_BCOLOUR(~fg);
        } else {
            REPLICATE(bg);
            TGUI_BCOLOUR(bg);
        }
    }
    TGUI_FMIX(XAAGetPatternROP(rop));
    pTrident->LinePattern = NiceDashPattern;
}


void
TridentSubsequentDashedBresenhamLine(ScrnInfoPtr pScrn,
                                        int x, int y,
                                        int dmaj, int dmin,
                                        int e, int len,
                                        int octant, int phase)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    int tmp = pTrident->BltScanDirection;

    if (octant & YMAJOR) tmp |= YMAJ;
    if (octant & XDECREASING) tmp |= XNEG;
    if (octant & YDECREASING) tmp |= YNEG;

    TGUI_STYLE(((pTrident->LinePattern >> phase) |
            (pTrident->LinePattern << (16-phase))) & 0x0000FFFF);
    TGUI_DRAWFLAG(pTrident->DrawFlag | STENCIL | tmp);
    TGUI_SRC_XY(dmin - dmaj, dmin);
    TGUI_DEST_XY(x, y);
    TGUI_DIM_XY(e + dmin, len);
    TGUI_COMMAND(GE_BRESLINE);
    TridentSync(pScrn);
}

static void
TridentSetupForFillRectSolid(ScrnInfoPtr pScrn,
                                int color,
                                int rop,
                                unsigned int planemask)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    int drawflag = 0;

    REPLICATE(color);
    TGUI_FMIX(XAAGetPatternROP(rop));
    if ((pTrident->Chipset == PROVIDIA9685) ||
            (pTrident->Chipset == CYBER9388)) {
        TGUI_FPATCOL(color);
    } else {
        drawflag |= PATMONO;
        TGUI_FCOLOUR(color);
    }

    TGUI_DRAWFLAG(pTrident->DrawFlag | SOLIDFILL | drawflag);
}

static void
TridentSubsequentFillRectSolid(ScrnInfoPtr pScrn,
                                int x, int y,
                                int w, int h)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);

    TGUI_DIM_XY(w, h);
    TGUI_DEST_XY(x, y);
    TGUI_COMMAND(GE_BLT);
    TridentSync(pScrn);
}

#if 0
static void
MoveDWORDS(register CARD32* dest,
            register CARD32* src,
            register int dwords)
{
    while(dwords & ~0x03) {
        *dest = *src;
        *(dest + 1) = *(src + 1);
        *(dest + 2) = *(src + 2);
        *(dest + 3) = *(src + 3);
        src += 4;
        dest += 4;
        dwords -= 4;
    }

    if (!dwords) return;
    *dest = *src;
    dest += 1;
    src += 1;
    if (dwords == 1) return;
    *dest = *src;
    dest += 1;
    src += 1;
    if (dwords == 2) return;
    *dest = *src;
    dest += 1;
    src += 1;
}
#endif

static void
TridentSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
                                    int patternx, int patterny,
                                    int fg, int bg,
                                    int rop,
                                    unsigned int planemask)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    int drawflag = 0;

    REPLICATE(fg);
    if ((pTrident->Chipset == PROVIDIA9685) ||
            (pTrident->Chipset == CYBER9388))
        TGUI_FPATCOL(fg);
    else
        TGUI_FCOLOUR(fg);

    if (bg == -1) {
        drawflag |= (1 << 12);
        if ((pTrident->Chipset == PROVIDIA9685) ||
                (pTrident->Chipset == CYBER9388))
            TGUI_BPATCOL(~fg);
        else
            TGUI_BCOLOUR(~fg);
    } else {
        REPLICATE(bg);
        if ((pTrident->Chipset == PROVIDIA9685) ||
                (pTrident->Chipset == CYBER9388))
            TGUI_BPATCOL(bg);
        else
            TGUI_BCOLOUR(bg);
    }

    if ((pTrident->Chipset == PROVIDIA9685) ||
            (pTrident->Chipset == CYBER9388)) {
        drawflag |= (7 << 18);
    }

    TGUI_DRAWFLAG(pTrident->DrawFlag | PAT2SCR | PATMONO | drawflag);
    TGUI_PATLOC(((patterny * pTrident->PatternLocation) +
                    (patternx * pScrn->bitsPerPixel / 8)) >> 6);
    TGUI_FMIX(XAAGetPatternROP(rop));
}

static void
TridentSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
                                        int patternx, int patterny,
                                        int x, int y,
                                        int w, int h)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);

    TGUI_DEST_XY(x, y);
    TGUI_DIM_XY(w, h);
    TGUI_COMMAND(GE_BLT);
    TridentSync(pScrn);
}

#if 0
static void
TridentSetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
                                    int patternx, int patterny,
                                    int rop,
                                    unsigned int planemask,
                                    int transparency_color)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    int drawflag = 0;

    REPLICATE(transparency_color);
    if (transparency_color != -1) {
        if ((pTrident->Chipset == PROVIDIA9685) ||
                (pTrident->Chipset == CYBER9388)) {
            drawflag |= (1 << 16);
        } else {
            TGUI_OPERMODE(pTrident->EngineOperation | DST_ENABLE);
        }

        TGUI_CKEY(transparency_color);
    }

    TGUI_DRAWFLAG(pTrident->DrawFlag | PAT2SCR | drawflag);
    TGUI_PATLOC(((patterny * pTrident->PatternLocation) +
                (patternx * pScrn->bitsPerPixel / 8)) >> 6);
    TGUI_FMIX(XAAGetPatternROP(rop));
}

static void
TridentSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn,
                                            int patternx, int patterny,
                                            int x, int y,
                                            int w, int h)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);

    TGUI_DEST_XY(x, y);
    TGUI_DIM_XY(w, h);
    TGUI_COMMAND(GE_BLT);
    TridentClearSync(pScrn);
}
#endif

#if 0
static void
TridentSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
                                                int fg, int bg,
                                                int rop,
                                                unsigned int planemask)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    int drawflag = SRCMONO;

    REPLICATE(fg);
    TGUI_FCOLOUR(fg);
    if (bg == -1) {
        drawflag |= (1 << 12);
        TGUI_BCOLOUR(~fg);
    } else {
        REPLICATE(bg);
        TGUI_BCOLOUR(bg);
    }

    TGUI_SRC_XY(0, 0);
    TGUI_DRAWFLAG(drawflag);
    TGUI_FMIX(XAAGetCopyROP(rop));
}

static void
TridentSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
                                                    int x, int y,
                                                    int w, int h,
                                                    int skipleft)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    pTrident->dwords = ((w + 31) >> 5);
    pTrident->h = h;
    pTrident->y = y;
    pTrident->x = x;
    pTrident->w = w;

    TGUI_DEST_XY(x, pTrident->y++);
    TGUI_DIM_XY(w, 1);
    TGUI_COMMAND(GE_BLT);
}

static void
TridentSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    XAAInfoRecPtr infoRec;
    infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);

    MoveDWORDS((CARD32 *)pTrident->FbBase,
            (CARD32 *)pTrident->XAAScanlineColorExpandBuffers[0],
            pTrident->dwords);

    pTrident->h--;
    TridentSync(pScrn);
    if (pTrident->h) {
        TGUI_DEST_XY(pTrident->x, pTrident->y++);
        TGUI_DIM_XY(pTrident->w, 1);
        TGUI_COMMAND(GE_BLT);
    }
}
#endif
#endif
