;*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.;
;*****************************************************************************/
        page        ,132
;/*****************************************************************************
;*
;* SOURCE FILE NAME = GETCLIP.ASM
;*
;* DESCRIPTIVE NAME = Region and path clipping functions
;*
;*
;* VERSION      V2.0
;*
;* DATE         8/4/92
;*
;* DESCRIPTION
;*      The Application can select into the DC two distinct clip areas:
;*      The clip region and the clip path.
;*      In addition the Window manager keeps another clip region known
;*      as the vis-region.  This is the part of the Window that is visible
;*      on the screen -- not overlapped by other windows.
;*     
;*      The "region" structures are a bunch of rects, while the
;*      clip path is defined by linked ShortLine structures.  The Engine
;*      intersects the two regions so that all we see in the Driver is
;*      the "rao region" -- the actual region where we are allowed to draw.
;*      So at this level we just have to clip to the rao region and
;*      the clip path.  Some driver functions are pre-cliped by the Engine
;*      and PolyScanline is pre-clipped to the clip path, but not the rao region:
;*      
;*      
;*                              Driver Drawing Operations
;*                              -------------------------
;*      
;*           no clipping             Clip to                clip to both region
;*             needed                   region only                  and clip path
;*         --------------         ----------------       -------------------
;*      
;*        DrawLinesInPath          PolyScanLine                StrBlt
;*        PolyShortLine                                 BitBlt
;*        (DrawConicsInPath?                                ImageData (Calls Bitblt)
;*        probably simulation)                        SetPel
;*                                                      PolyLine
;*     
;*      Even though PolyScanline appears to have different clipping needs,
;*      it is in fact the same as Strblt and Bitblt because a linked list
;*      of ShortLines (ScansData) is passed to PolyScanline as the target.
;*      Therefore the following subroutine is designed to be called by
;*      PolyScanline, Strblt, and Bitblt.
;*
;* FUNCTIONS    far_get_clip_rects
;*              get_clip_rects
;*                                 
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*   03/12/87                     Charles Whitmer [chuckwh] - created
;*   09/06/87                     Wesley O. Rupel [wesleyr]
;*                                  Wrote get_clip_rects
;*****************************************************************************/

        .286p
        .xlist
        include        cmacros.inc
INCL_GPIREGIONS equ        1
INCL_GRE_CLIP        equ        1
        include        pmgre.inc
        include driver.inc
        include scanline.inc
        .list


sBegin        Data
        externD pfnDefGetClipRects
sEnd        Data

sBegin        Code
        assumes        cs,Code

;/***************************************************************************
;*
;* FUNCTION NAME = get_clip_rects(extended control structure) 
;*
;* DESCRIPTION   = Returns the rectangles in the clipping region of the DC. 
;*                 Registers Destroyed:   
;*                         AX,BX,CX,DX,ES 
;*
;* INPUT         = DS:SI =        ddc                     
;*                 SS:BP =        extended control buffer 
;*
;* OUTPUT        =
;*    lpRectBound  A far pointer to a bounding rectangle.  Only rectangles           
;*                intersecting this bounding rectangle will be returned.             
;*                If this pointer is NULL, all rectangles in the region              
;*                will be enumerated.                                                
;*                                                                                   
;*                     A "NULL" bounding rectangle is assumed to be one              
;*                     whose selector is 0.                                          
;*                                                                                   
;*    lpRectBuffer (aka RectList)                                                    
;*         A far pointer to a buffer where the list of rectangles is to be           
;*         returned.                                                                 
;*                                                                                   
;*    lpControl                                                                      
;*         A far pointer to a structure containing the following elements:           
;*                                                                                   
;*         wStart                                                                    
;*             The rectangle number to start enumerating at.  Set this to            
;*             zero to start from the beginning.                                     
;*                                                                                   
;*         wBufsize                                                                  
;*             The number of rectangles that will fit into the buffer.               
;*             Must be at least 1.                                                   
;*                                                                                   
;*         wNumWritten                                                               
;*             A returned value indicating how many rectangles were                  
;*             written into the buffer.        A value below U16_BUFSIZE means there 
;*             are no more rectangles to enumerate.                                  
;*                                                                                   
;*         wDirection                                                                
;*             Indicates the direction the rectangles are listed.                    
;*                                                                                   
;* RETURN-NORMAL = AX=0
;* RETURN-ERROR  = AX=error
;*
;* PSEUDO-CODE   =
;*
;*{
;*   // The driver can handle this call without calling the engine IF
;*   // (there is only 1 clip rect) OR
;*   // ((the number of clip rects is less or equal to NUM_CLIP_RECTS)
;*   // AND (the direction is 4))
;*
;*       if ( we can handle it )
;*               copy the clip rects stored in the DDC into RectBuffer
;*               trimming them to RectBound as we do it.
;*       else
;*               call engine ( GetClipRects )
;*}
;***************************************************************************/

NRECTS        equ        5


        assumes        ds,Data
        assumes        es,nothing

cProc        far_get_clip_rects,<PUBLIC,FAR,NODATA,NONWIN>
cBegin
        cCall get_clip_rects
cEnd

cProc        get_clip_rects,<PUBLIC,NEAR>,<di>
cBegin
        ddc?        si
;/*
;**   !!!  Some sort of semaphore is needed for the case when
;**   !!!  the clip rects change while we're looping back to get more.
;*/

;/*
;**    The driver can handle this call without calling the engine IF
;**    (there is only 1 clip rect) OR
;**    ((the number of clip rects is less or equal to NUM_CLIP_RECTS)
;**    AND (the direction is 4))
;*/

        mov        cx,[si].ddc_crcsClip
        cmp        cx,1
        jz        we_can_do_it
        cmp        cx,NUM_CLIP_RECTS
        ja        must_call_engine

;/*
;**  This magic four someday becomes RECTDIR_LFRT_BOTTOP
;**  Actually, this routine can always assume this direction.
;*/
        cmp        ss:[bp].ec_buffer.rgnrc_usDirection,4
        jnz        must_call_engine

we_can_do_it:
        missing_code        <driver can handle without calling engine>

must_call_engine:
        farPtr        hdcTemp,<[si].ddc_hdc.hi>,<[si].ddc_hdc.lo>

        farPtr        pControl,ss,bp
        .errnz        ec_control

        lea        bx,[bp].ec_buffer
        farPtr        pRectBuff,ss,bx

        lea        di,[bp].ec_rect_bound
        farPtr        pRectBound,ss,di

        farPtr        hddcNull,0,0
        check        GetClipRects,<hdc,prclBounds,prgnrc,prclClip,hddc,ulFunN>
        cCall        pfnDefGetClipRects,<hdcTemp,pRectBound,pControl,pRectBuff,hddcNull,GreGetClipRects>

ifdef FIREWALLS                        ;!!! make this an assert
        or        ax,ax
        jnz        result_ok
        rip        text,<GetClipRects returns error>
result_ok:
endif


gcr_exit:

cEnd

sEnd        Code
end
