/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 WARP source code is provided to you solely for  */
/*    the purpose of assisting you in your development of OS/2 WARP device   */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
/*    Copyright statement may not be removed.                                */
/*                                                                           */
/*****************************************************************************/
/**********************************************************************/
/*                                                                    */
/*   Module          = EDDSPOLY                                       */
/*                                                                    */
/*   Description     = Display Device Driver minor function handler   */
/*                     PolyScanLine                                   */
/*                                                                    */
/*   Function        = PolyScanLine fills the area between two        */
/*                     polyshortlines using the current pattern       */
/*                     attributes                                     */
/*                                                                    */
/*   Reference       = Winthorn Functional Specification              */
/*                     Device Driver Interface Specification          */
/*                     Display Device Driver Design Specification     */
/*                                                                    */
/*                                                                    */
/* CHANGE ACTIVITY =                                                  */
/*   DATE      FLAG        APAR   CHANGE DESCRIPTION                  */
/*   --------  ----------  -----  ------------------------------------*/
/*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx                             */
/*   03/19/93              62482  Patterned stripes appear when       */
/*                                solid colors asked for. (8514)      */
/**********************************************************************/
#define INCL_DDICOMFLAGS
#define INCL_DDIMISC
#define INCL_DDIPATHS
#include <eddinclt.h>

#include <eddaextf.h>
#include <eddbextf.h>
#include <eddcextf.h>
#include <eddgextf.h>
#include <eddlextf.h>
#include <eddmextf.h>
#include <eddsextf.h>
#ifdef DCAF                                                               //DCAF
#include <dcafextf.h>                                                     //DCAF
#endif                                                                    //DCAF

#include <eddecone.h>

#include <eddhcone.h>
#include <eddhtype.h>

#include <eddfcone.h>
#include <eddftype.h>

#include <cursor.h>
#include <hwaccess.h>
#ifdef VRAMPTR
#include <eddncach.h>
#endif /* VRAMPTR */

#ifdef _8514
#include <8514.h>
#endif /* _8514 */

/**********************************************************************/
/* For performance code..                                             */
/**********************************************************************/
extern BITBLTPB         AIxfer;
#ifndef   _8514
extern MMReg            ShadowXGARegs;
extern pMMReg           pRealXGARegs;
extern pMMReg           pXGARegs;
#else
extern MM8514Reg        Shadow8514Regs;
extern pMM8514Reg       p8514Regs;
extern BitmapHeader     DirectListEntry;
#endif
extern BYTE             WinToXway[];
extern BitmapHeader     NewPatternTable[];

extern RGNRECT          GetClipsControl;
extern ClipRectangle    GetClipsBounds;
extern BOOL             DitheredPattern;
extern CURSORDATA       cursor_data;

extern SHORT                    softDrawInUse;
extern ULONG                    LinePatternCur;
extern ULONG                    LinePatternPhys;
extern ULONG                    LinePatternSys;
extern ULONG                    MarkerCur;
extern ULONG                    MarkerPhys;
extern ULONG                    MarkerSys;
extern ULONG                    pCurCacheBasePhy;
extern ULONG                    pSysCacheStartPhy;
extern drawFunctionsTable       softDrawTable;
extern drawFunctionsTable       hardDrawTable;
extern SHORT                    foregroundSession;
extern ULONG                    pPhunkPhys;

extern pDrawFunctionsTable      pDrawFunctions;

/**********************************************************************/
/* edds_PolyScanLine - hooked function                                */
/*                                                                    */
/* The following assumptions about the parameters are made (in line   */
/* with the description in MS DDK)...                                 */
/*                                                                    */
/* The polyshortlines which define the area will always occur in      */
/* pairs of the same height and in they will always run from bottom   */
/* to top.                                                            */
/* Coordinates will be in screen coordinates                          */
/**********************************************************************/
DDIENTRY edds_PolyScanLine (HDC         hdc,
                            PSCANDATA   pScanData,
                            PDC         pdcArg,
                            ULONG       FunN)

{
    /******************************************************************/
    /* Local variables                                                */
    /******************************************************************/
    DevRect             Bounds;
    PSHORTLINE          ShortLineL;
    PSHORTLINE          ShortLineR;
    ULONG               ulResult;
    LONG                YDirection;
    PULONG              StepL;
    PULONG              StepR;
    LONG                CurrY;
    ULONG               ulStep;
    ULONG               ulNumsteps;
    DevRect             CoordRect;
    BYTE                Mix;

    /******************************************************************/
    /* Prevent compiler warnings.                                     */
    /******************************************************************/
    IgnoreParam(hdc);

    /******************************************************************/
    /* We do not need exclusive access as a LockDevice call will      */
    /* always be made before a PolyScanLine call.  BUT we do it just  */
    /* in case (because we have been loosing semaphor protection in   */
    /* stress tests and this is one of the potential holes).          */
    /******************************************************************/
    EnterDriver(pdcArg, FunN, EDF_STANDARD);

    SetDrawModeHard;

    /******************************************************************/
    /* Apply the DC command mask to the command bits                  */
    /******************************************************************/
    COMMANDBITS(FunN) &= pdc->DCICommandMask;

    /******************************************************************/
    /* Reset bit 0 of the style high word, to indicate figure not     */
    /* starting                                                       */
    /******************************************************************/
    pdc->StyleNumber &= 0xFFFEFFFF;

    if ( (FunNTest(COM_BOUND | COM_ALT_BOUND)) ||
#ifdef DCAF                                                               //DCAF
         DCAFBoundsRequired(FunN) ||                                      //DCAF
#endif                                                                    //DCAF
         (cursor_data.cursor_status & CURSOR_SOFTWARE) )
    {
        /**************************************************************/
        /* If bounds are required then use the bounds passed in via   */
        /* SCANDATA.                                                  */
        /**************************************************************/
        Bounds[0].X = (SHORT)pScanData->rclBound.xLeft -
                                                  pdc->DCIOrigin.X;
        Bounds[1].X = (SHORT)pScanData->rclBound.xRight -
                                                  pdc->DCIOrigin.X;
        Bounds[0].Y = (SHORT)pScanData->rclBound.yBottom -
                                                  pdc->DCIOrigin.Y;
        Bounds[1].Y = (SHORT)pScanData->rclBound.yTop -
                                                  pdc->DCIOrigin.Y;

        /**************************************************************/
        /* And add them to our bounds..                               */
        /* !!! It looks as though we do not need to accumulate    !!! */
        /* !!! bounds - the engine does this for us.              !!! */
        /**************************************************************/
//      if ( FunNTest(COM_BOUND | COM_ALT_BOUND) )
//          eddg_AddBounds ((pDevRect)Bounds,
//                          FunN,
//                          COORD_DEVICE_WORD);

#ifdef DCAF                                                               //DCAF
        /**************************************************************/  //DCAF
        /* Accumulate DCAF screen bounds if required                  */  //DCAF
        /**************************************************************/  //DCAF
        if (DCAFBoundsRequired(FunN))                                     //DCAF
        {                                                                 //DCAF
            AccumulateScreenBoundsThroughClips( (pDevRect)Bounds,         //DCAF
                                                COORD_DEVICE_WORD );      //DCAF
        }                                                                 //DCAF
#endif                                                                    //DCAF
    }

    if (FunNTest(COM_CORRELATE) && (pdc->DCICorrInvalid))
    {
        /**************************************************************/
        /* Correlation required and our correlation data is invalid   */
        /**************************************************************/
        if (! eddg_ClipPickWindow())
        {
            goto POLYSCANLINE_ERR_EXIT;
        }
    }

    /******************************************************************/
    /* If draw bit then proceed with the drawing                      */
    /***+**************************************************************/
    if ( FunNTest(COM_DRAW) )
    {
        if ( pdc->DCIBitmapType == BITMAP_NOT_SELECTED )
        {
            /**********************************************************/
            /* No bitmap selected AND COM_DRAW set so log an error    */
            /**********************************************************/
            LogError(PMERR_NO_BITMAP_SELECTED);
            goto POLYSCANLINE_ERR_EXIT;
        }

        /**************************************************************/
        /* Now it is time to set the drawing mode correctly..         */
        /**************************************************************/
        if (pdc->DCIBitmapType == BITMAP_IS_SCREEN)
        {
            SetDrawModeHard;
        }
        else
        {
            SetDrawModeSoft;
        }

        /**************************************************************/
        /* Put the destination bitmap header's address into the       */
        /* parameter block                                            */
        /**************************************************************/
        AIxfer.pbmhDest = pdc->DCISelListEntry;

        /**************************************************************/
        /* exclude the cursor if necessary and disable updates        */
        /**************************************************************/
        if ( cursor_data.cursor_status & CURSOR_SOFTWARE )
        {
           eddm_ExcludeCursor(Bounds, COORD_DEVICE_WORD);
        }


        /**************************************************************/
        /* if the pattern symbol or set has changed then we need to   */
        /* get the new data                                           */
        /**************************************************************/
        if ( pdc->DCIChanged & NEW_PATTERN_SYMBOL )
        {
            if ( !edda_PatternSetUp() )
            {
                goto POLYSCANLINE_ERR_EXIT;
            }
        }

        /**************************************************************/
        /* Set up the pattern and colours (including dithering where  */
        /* appropriate).                                              */
        /* We thought that dithering should only be allowed if the    */
        /* foreground mix is source or inverse source BUT we hit a    */
        /* testcase in BitBlt which needs all (appropriate) rops to   */
        /* allow dithered colours, so it appears that we should also  */
        /* allow dithering for all mixes here                         */
        /* (SetDithColourAndPattern will check that pattern is solid) */
        /**************************************************************/
        if (eddc_SetDithColourAndPattern(pdc->DCICurPtnAts.abnd.lColor))

        {
            /**********************************************************/
            /* The mix allows dithering and SetDithColourAndPattern   */
            /* has returned true indicating that dithering should be  */
            /* used.                                                  */
            /**********************************************************/

            /**********************************************************/
            /* Set up the dither origin to be the pattern origin.     */
            /**********************************************************/
            AIxfer.rcsSrc.pts1.x = pdc->DCIPatternOrigin.X;
            AIxfer.rcsSrc.pts1.y = pdc->DCIPatternOrigin.Y;

            if (pdc->DCISelListEntry->Info.BitCount != 1)
            {
                /******************************************************/
                /* Use the coloured dither pattern                    */
                /* Set up the source bitmap as the dithered pattern   */
                /******************************************************/
                AIxfer.pbmhSrc = &NewPatternTable[PATSYM_DITHERED];

                /******************************************************/
                /* Set up the pixel op so that it will use a source   */
                /* pixel map for the blt..                            */
                /******************************************************/
                AIxfer.ulPixelOp = BACK_SRC_SRC_PIX_MAP |
                                   FORE_SRC_SRC_PIX_MAP |
                                   STEP_PXBLT |
                                   SRC_PIX_MAP_B |
                                   DST_PIX_MAP_A |
                                   PAT_PIX_MAP_FORE |
                                   MASK_PIX_MAP_OFF |
                                   DRAW_MODE_DONTCARE |
                                   DIR_OCTANT_LRTB;

#ifdef _8514
                #ifndef   BPP24
                Shadow8514Regs.Color_1 = (USHORT)AIxfer.pbmhSrc->Bitmap[0];
                Shadow8514Regs.Color_0 = (USHORT)AIxfer.pbmhSrc->Bitmap[1];
                #else
                Shadow8514Regs.Color_1 = AIxfer.pbmhSrc->Bitmap[0];
                Shadow8514Regs.Color_0 = AIxfer.pbmhSrc->Bitmap[1];
                #endif

                //            - Unnecessary code deleted.
#endif

            }
            else
            {
                /******************************************************/
                /* Use the mono dither pattern                        */
                /* Set up the source bitmap as the dithered pattern   */
                /******************************************************/
                AIxfer.pbmhSrc = &NewPatternTable[PATSYM_MONODITH];

                /******************************************************/
                /* Set the pixel op to use a pattern pixel map and    */
                /* the foreground and background colours.             */
                /******************************************************/
                AIxfer.ulPixelOp = BACK_SRC_BACK_COL |
                                   FORE_SRC_FORE_COL |
                                   STEP_PXBLT |
                                   SRC_PIX_MAP_DONTCARE |
                                   DST_PIX_MAP_A |
                                   PAT_PIX_MAP_B |
                                   MASK_PIX_MAP_OFF |
                                   DRAW_MODE_DONTCARE |
                                   DIR_OCTANT_LRTB;

                /******************************************************/
                /* Set up the colours to use.                         */
                /* these must be 1 and 0                              */
                /******************************************************/
                #ifndef   _8514
                ShadowXGARegs.FgCol = 1;
                ShadowXGARegs.BgCol = 0;
                #else
                Shadow8514Regs.Color_1 = 1;
                Shadow8514Regs.Color_0 = 0;
                #endif
            }
        }
        else
        {
            /**********************************************************/
            /* Dithering is not allowed/required.                     */
            /**********************************************************/

            /**********************************************************/
            /* Set up the source bitmap as the current pattern and    */
            /* also set the pattern origin.                           */
            /**********************************************************/
            AIxfer.pbmhSrc = pdc->TempPattern;
            AIxfer.rcsSrc.pts1.x = pdc->DCIPatternOrigin.X;
            AIxfer.rcsSrc.pts1.y = pdc->DCIPatternOrigin.Y;

            /**********************************************************/
            /* we use different pixel ops according to whether we     */
            /* have a colour or a mono pattern                        */
            /**********************************************************/
            if (pdc->TempPattern->Info.BitCount == 1)
            {
                /******************************************************/
                /* pattern is mono                                    */
                /******************************************************/
                /******************************************************/
                /* Set the pixel op to use a pattern pixel map and    */
                /* the foreground and background colours.             */
                /******************************************************/
                AIxfer.ulPixelOp = BACK_SRC_BACK_COL |
                                   FORE_SRC_FORE_COL |
                                   STEP_PXBLT |
                                   SRC_PIX_MAP_DONTCARE |
                                   DST_PIX_MAP_A |
                                   PAT_PIX_MAP_B |
                                   MASK_PIX_MAP_OFF |
                                   DRAW_MODE_DONTCARE |
                                   DIR_OCTANT_LRTB;

                /******************************************************/
                /* Set up the colours to use.                         */
                /******************************************************/
                #ifndef   _8514
                ShadowXGARegs.FgCol = (USHORT)pdc->DCIPattColatts.ForeColor;
                ShadowXGARegs.BgCol = (USHORT)pdc->DCIPattColatts.BackColor;
                #else
                #ifndef   BPP24
                Shadow8514Regs.Color_1 = (USHORT)pdc->DCIPattColatts.ForeColor;
                Shadow8514Regs.Color_0 = (USHORT)pdc->DCIPattColatts.BackColor;
                #else
                Shadow8514Regs.Color_1 = pdc->DCIPattColatts.ForeColor;
                Shadow8514Regs.Color_0 = pdc->DCIPattColatts.BackColor;
                #endif
                #endif
            }
            else
            {
                /******************************************************/
                /* check we are not trying to draw a coloured pattern */
                /* into a 1bpp bitmap (the h/w can't cope with such   */
                /* a mixture of bpps)                                 */
                /******************************************************/
                if ( pdc->DCISelListEntry->Info.BitCount != 1 )
                {
                    /**************************************************/
                    /* pattern is colour                              */
                    /* we use the same pixel op as we do in the       */
                    /* dithered pattern case                          */
                    /**************************************************/
                    AIxfer.ulPixelOp = BACK_SRC_SRC_PIX_MAP |
                                       FORE_SRC_SRC_PIX_MAP |
                                       STEP_PXBLT |
                                       SRC_PIX_MAP_B |
                                       DST_PIX_MAP_A |
                                       PAT_PIX_MAP_FORE |
                                       MASK_PIX_MAP_OFF |
                                       DRAW_MODE_DONTCARE |
                                       DIR_OCTANT_LRTB;
                }
                else
                {
                    /**************************************************/
                    /* blt from a colour bitmap to a mono one         */
                    /* basically without a software simulation we     */
                    /* can't cope - so as a temporary measure we      */
                    /* substitute a halftone pattern                  */
                    /**************************************************/
                    AIxfer.pbmhSrc =
                                   &NewPatternTable[PATSYM_HALFTONE-1];

                    /**************************************************/
                    /* Set the pixel op to use a pattern pixel map and*/
                    /* the foreground and background colours.         */
                    /**************************************************/
                    AIxfer.ulPixelOp = BACK_SRC_BACK_COL |
                                       FORE_SRC_FORE_COL |
                                       STEP_PXBLT |
                                       SRC_PIX_MAP_DONTCARE |
                                       DST_PIX_MAP_A |
                                       PAT_PIX_MAP_B |
                                       MASK_PIX_MAP_OFF |
                                       DRAW_MODE_DONTCARE |
                                       DIR_OCTANT_LRTB;

                    /**************************************************/
                    /* Set up the colours to use.                     */
                    /**************************************************/
                    #ifndef   _8514
                    ShadowXGARegs.FgCol = (USHORT)pdc->DCIPattColatts.ForeColor;
                    ShadowXGARegs.BgCol = (USHORT)pdc->DCIPattColatts.BackColor;
                    #else
                    #ifndef   BPP24
                    Shadow8514Regs.Color_1 = (USHORT)pdc->DCIPattColatts.ForeColor;
                    Shadow8514Regs.Color_0 = (USHORT)pdc->DCIPattColatts.BackColor;
                    #else
                    Shadow8514Regs.Color_1 = pdc->DCIPattColatts.ForeColor;
                    Shadow8514Regs.Color_0 = pdc->DCIPattColatts.BackColor;
                    #endif
                    #endif
                }
            }

        }

        /**************************************************************/
        /* Set up the mixes...                                        */
        /* NB set up both mixes although the background mix is        */
        /* irrelevant for a dithered or coloured pattern.             */
        /**************************************************************/
        Mix = WinToXway[pdc->DCICurPtnAts.abnd.usMixMode];
        #ifndef _8514
        ShadowXGARegs.FgMix = Mix;
        ShadowXGARegs.ColCompCond = COLCOMP_ALWAYS;
        #else
        Shadow8514Regs.Function_1.Mix = Mix;
        Shadow8514Regs.Function_1.SrcSelect = FUNC_2OP_COPY;
        Shadow8514Regs.Mode.UnderPaint = MD_UP_FALSE;
        #endif

        if (DitheredPattern)
        {
            /**********************************************************/
            /* coloured dithers don't use a bg mix                    */
            /* mono dithers need bg and fg mix the same               */
            /**********************************************************/
            #ifndef   _8514
            ShadowXGARegs.BgMix = Mix;
            #else
            Shadow8514Regs.Function_0.Mix = Mix;
            Shadow8514Regs.Function_0.SrcSelect = FUNC_2OP_COPY;
            #endif
        }
        else
        {
            #ifndef   _8514
            ShadowXGARegs.BgMix =
              (BYTE)WinToXway[pdc->DCICurPtnAts.abnd.usBackMixMode];
            #else
            Shadow8514Regs.Function_0.Mix =
              (BYTE)WinToXway[pdc->DCICurPtnAts.abnd.usBackMixMode];
            Shadow8514Regs.Function_0.SrcSelect = FUNC_2OP_COPY;
            #endif
        }

        /**************************************************************/
        /* Set up parameters for PMSCANLINE - the clip rectangles     */
        /* and the shortlines.                                        */
        /**************************************************************/
        AIxfer.pNextDestClipRect = pdc->DCIClipRects;
        AIxfer.pSLHeaderLeft  = (PSHORTLINE)pScanData->pslFirstLeft;
        AIxfer.pSLHeaderRight = (PSHORTLINE)pScanData->pslFirstRight;

        /**************************************************************/
        /* if the pattern is not in VRAM and we are in hardware       */
        /* drawing mode then we need to copy it into the PHUNK        */
        /**************************************************************/
        if ( (!AIxfer.pbmhSrc->BMPhys) && !softDrawInUse )
        {
            eddb_PhunkThatBitmap(AIxfer.pbmhSrc);
        }

        /**************************************************************/
        /* Transfer the shadow register values we have set to the     */
        /* real hw registers.                                         */
        /**************************************************************/
        TransferShadowRegisters(TSR_COLOUR_MIX);

        /**************************************************************/
        /* Single bitmap case ..                                      */
        /**************************************************************/

        /**************************************************************/
        /* If we are going to call back to the engine to get the clip */
        /* rectangles, set up the bounding clip                       */
        /**************************************************************/
        if (pdc->ClipChanged )
        {
            /**********************************************************/
            /* If number of clips too many for the cache use the      */
            /* bounding clip passed in as bounds for clips from the   */
            /* engine.  Otherwise use fill the cache                  */
            /**********************************************************/
            if (pdc->DCIEngineClips > CACHED_CLIPS)
            {
                /******************************************************/
                /* Intersect supplied bounds with the drawing area    */
                /******************************************************/
                GetClipsBounds.X0 = max(((SHORT)0),
                                 ((SHORT)pScanData->rclBound.xLeft));
                GetClipsBounds.X1 =
                          min (((SHORT)(pScanData->rclBound.xRight)),
                             ((SHORT)(pdc->DCIBoundingClip[1].X)));
                GetClipsBounds.X1++;
                GetClipsBounds.Y0 = max(((SHORT)0),
                               ((SHORT)pScanData->rclBound.yBottom));
                GetClipsBounds.Y1 =
                            min (((SHORT)(pScanData->rclBound.yTop)),
                             ((SHORT)(pdc->DCIBoundingClip[1].Y)));
                GetClipsBounds.Y1++;

                /******************************************************/
                /* Check if bounds inside drawing area                */
                /******************************************************/
                if (((SHORT)GetClipsBounds.X1 < 0) ||
                    ((SHORT)GetClipsBounds.Y1 < 0) ||
                    ((SHORT)GetClipsBounds.X0 >=
                                    pdc->DCIBoundingClip[1].X) ||
                    ((SHORT)GetClipsBounds.Y0 >=
                                      pdc->DCIBoundingClip[1].Y))
                    goto DRAWING_DONE;
            }
            else
            {
                /******************************************************/
                /* Set bounds which intersect clip to drawing area    */
                /******************************************************/
                GetClipsBounds.X0 = pdc->DCIBoundingClip[0].X;
                GetClipsBounds.X1 = pdc->DCIBoundingClip[1].X + (USHORT)1;
                GetClipsBounds.Y0 = pdc->DCIBoundingClip[0].Y;
                GetClipsBounds.Y1 = pdc->DCIBoundingClip[1].Y + (USHORT)1;
            }
        }

        /**************************************************************/
        /* do the appropriate blt to all clip regions                 */
        /**************************************************************/
        GetClipsControl.ircStart = 1;
        do /* for each rectangle comprising the clip region */
        {
            /**********************************************************/
            /* set the GetClips control structure number of           */
            /* rectangles returned to zero so that we will exit loop  */
            /* if all rectangles processed                            */
            /**********************************************************/
            GetClipsControl.crcReturned = 0;

            /**********************************************************/
            /* if the total number of clips comprising the region     */
            /* exceed the size of the dc cache or NotifyClipChange    */
            /* was called then get the cache updated from engine      */
            /**********************************************************/
            if ( (pdc->DCIEngineClips > CACHED_CLIPS) ||
                                               pdc->ClipChanged )
            {
                edda_GetClipRectangles();
                /******************************************************/
                /* reset the start rectangle for next iteration       */
                /******************************************************/
                GetClipsControl.ircStart +=
                                        GetClipsControl.crcReturned;

            }

            /**********************************************************/
            /* if we now have some clip rectangles then call the low  */
            /* level function which can cope with drawing to all the  */
            /* cached clip rectangles                                 */
            /**********************************************************/
            if (pdc->DCIClipNum)
            {
                AIxfer.cDestClipRects = pdc->DCIClipNum;
                (*(*pDrawFunctions)[index_PMSCANLINE])();
            }

        } while ( GetClipsControl.crcReturned &&
              (GetClipsControl.ircStart <= pdc->DCIEngineClips));


        /**************************************************************/
        /* If we PHUNKed the pattern then we must now unPHUNK it      */
        /**************************************************************/
        if ( AIxfer.pbmhSrc->BMPhys == pPhunkPhys )
        {
            AIxfer.pbmhSrc->BMPhys = FNULL;
        }

#ifdef VRAMPTR
        /**************************************************************/
        /* If the target bitmap is cached then evict it since it has  */
        /* been drawn to.                                             */
        /**************************************************************/
        if ( BITMAP_IS_CACHED(AIxfer.pbmhDest) )
        {
          evict_cached_bitmap(AIxfer.pbmhDest->bm_cache_slot);
        }
#endif /* VRAMPTR */

    }     /* if draw bit is set                                       */



DRAWING_DONE:
    /******************************************************************/
    /* reenable cursor updates                                        */
    /******************************************************************/
    reenable_cursor();

    /******************************************************************/
    /* Set ulResult to OK. This will be altered to OK_CORR if a       */
    /* correlation hit occurs.                                        */
    /******************************************************************/
    ulResult = OK;

    /******************************************************************/
    /* If the COM_CORRELATE bit is set and the number of correlation  */
    /* rectangles is non-zero then correlate on the scanlines         */
    /******************************************************************/
    if (FunNTest(COM_CORRELATE) && (pdc->DCICorrNum))
    {
        /**************************************************************/
        /* Traverse the linked list of shortline definition pairs     */
        /* Assume that the left and right pointers do in fact point   */
        /* to the left and right polyshortline in each pair. This is  */
        /* also true as the pair of linked polyshortline lists are    */
        /* traversed.                                                 */
        /**************************************************************/
        for (ShortLineL = (PSHORTLINE)pScanData->pslFirstLeft,
              ShortLineR = (PSHORTLINE)pScanData->pslFirstRight;
             (ShortLineL != FNULL) ||
              (ShortLineR != FNULL);
             ShortLineL = (PSHORTLINE)ShortLineL->slh.pslhNext,
              ShortLineR = (PSHORTLINE)ShortLineR->slh.pslhNext)
        {

            /**********************************************************/
            /* Set up y increment in hardware coords. Assumes start   */
            /* and stop positions are in screen coordinates (ie the   */
            /* y coordinates go in different directions)              */
            /**********************************************************/
            if (ShortLineL->slh.ptlStart.y < ShortLineL->slh.ptlStop.y )
            {
                YDirection = -1;
            }
            else
            {
                YDirection = 1;
            }

            /**********************************************************/
            /* Set up the number of steps.                            */
            /**********************************************************/
            ulNumsteps = abs(ShortLineL->slh.ptlStart.y -
                             ShortLineR->slh.ptlStop.y);

            /**********************************************************/
            /* Set up the initial position in screen coordinates      */
            /**********************************************************/
            StepL = (PULONG)ShortLineL->ax;
            StepR = (PULONG)ShortLineR->ax;
            CurrY = pdc->DCISelListEntry->Info.Height -
                              1 - ShortLineL->slh.ptlStart.y;

            /**********************************************************/
            /* correlate aginst each step                             */
            /**********************************************************/
            for (ulStep = 0; ulStep < ulNumsteps; ulStep++)
            {
                /******************************************************/
                /* Treat scanline as a rectangle                      */
                /******************************************************/
                CoordRect[0].X = (SHORT)StepL[ulStep];
                CoordRect[0].Y = (SHORT)CurrY;
                CoordRect[1].X = (SHORT)(StepR[ulStep] - 1);
                CoordRect[1].Y = (SHORT)CurrY;
                if (eddg_CheckRectCorrelation((pDevRect)CoordRect)
                                                            == OK_CORR)
                {
                    ulResult = OK_CORR;
                    goto POLYSCANLINE_OK_EXIT;
                }

                /******************************************************/
                /* Move to next y position                            */
                /******************************************************/
                CurrY = CurrY + YDirection;
            }
        }
    }

POLYSCANLINE_OK_EXIT:
    ExitDriver(pdcArg, FunN, EDF_STANDARD);
    return (ulResult);

POLYSCANLINE_ERR_EXIT:
    ExitDriver(pdcArg, FunN, EDF_STANDARD);
    return (ERROR_ZERO);
}
