;*DDK*************************************************************************/
;
; COPYRIGHT (C) Microsoft Corporation, 1989
; 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 = SSB.ASM
;*
;* DESCRIPTIVE NAME = Save/Restore screen bits
;*
;*
;* VERSION      V2.0
;*
;* DATE         05/19/87
;*
;* DESCRIPTION  The function SaveScreenBits saves a rectangle of bits
;*              from the display to unused display memory, returning a handle
;*              to the caller.  It returns an error if either the memory is
;*              nonexistent or is not available for use.
;*
;*              The function RestoreScreenBits discards the saved bits and/or
;*              restores them to the display.  It returns an error if the
;*              memory is either nonexistent, or there are not any bits saved.
;*
;*              Restrictions:
;*
;*              Only one rectangle of bits can be saved at a time.
;*              The hdc passed in must be the screen DC.
;*
;*
;* FUNCTIONS    SaveScreenBits
;*              RestoreScreenBits
;*
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*   05/19/87                     Written by Bob Grudem [bobgru] (Windows),
;*                                Wes Rupel [wesleyr] (PM)
;*   08/06/87                     Bob Grudem [bobgru] Replaced some magic
;*                                numbers with equates; cleanup style.
;*   10/23/87                     Bob Grudem [bobgru] Debugged; now copies
;*                                to/from specific address in upper EGA mem.
;*   11/05/87                     Bob Grudem [bobgru] Split into two functions
;*                                according to interface.
;*   12/09/87                     Bob Grudem [bobgru] Improved register usage.
;*                                Added lots of comments.
;*   05/27/88                     Bob Grudem [bobgru] Now saves marker and
;*                                pattern attribute flags before calling Bitblt,
;*                                clears them for the call, and restores them
;*                                afterwards.  Also added firewall to check
;*                                return code from Bitblt.
;*
;*****************************************************************************/


        .386

        .xlist

INCL_GRE_BITMAPS        equ     1
INCL_DDICOMFLAGS        equ     1
INCL_DOSMVDM            equ     1

        include pmgre.inc

DINCL_SAVE_SCREEN_BITS  equ     1
DINCL_ENABLE            equ     1
DINCL_BITMAP            equ     1

        include driver.inc
        include display.inc
        include egafam.inc
        include extern.inc
        include protos.inc

        .list

        .MODEL FLAT

        ASSUME  CS:FLAT,SS:FLAT,DS:FLAT,ES:FLAT

        .DATA

SSB_COOKIE      equ     'bs'            ;the only allowed hSB


        .CODE

;/***************************************************************************
;*
;* FUNCTION NAME = SaveScreenBits
;*
;* DESCRIPTION   =
;*
;*        Save a rectangle of bits to unused display memory.
;*
;*        Device                        Offset in
;*        coord                         screen RAM
;*        -----------------------------------------
;*        y+    |                       offset 0000
;*              |    +-------------+
;*              |    |             |
;*              |    |             |
;*              |    |      A      |
;*              |    |             |
;*              |    |             |
;*              |....+-------------+
;*              |    .
;*              |    .
;*              |    .
;*        0,0   +======================
;*              +-------------+         offset xxxx
;*              |             |
;*              |             |
;*              |   Saved A   |
;*              |             |
;*              |             |
;*              +-------------+
;*              |
;*              |
;*              |
;*        y-    |                       offset FFFF
;*
;*
;*        The rectangle of bits is saved at a fixed location in upper
;*        screen memory.
;*
;*        Registers Preserved:
;*              SI,DI,DS,BP
;*        Registers Destroyed:
;*              AX,BX,CX,DX,ES,FLAGS
;*
;* INPUT         =   EGA registers in default state
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = AX = handle to saved bits
;* RETURN-ERROR  = AX = 0 if unable to save bits
;*
;**************************************************************************/


SaveScreenBits  PROC SYSCALL USES ebx esi edi,      hdc:DWORD, lpRect:DWORD,
                                                hddc:DWORD, FunN:DWORD
                LOCAL   loc_screen_sel:DWORD,
                        loc_exclude_x1:DWORD,
                        loc_exclude_y1:DWORD,
                        loc_exclude_x2:DWORD
                LOCAL   loc_exclude_y2:DWORD,
                        loc_x_origin:DWORD,
                        loc_y_origin:DWORD


        DebugMsg <SaveScreenBits, DISPATCH, ssb, CLIFFL>


        cld
        mov     edx,hddc
        call    enter_driver
        jc      ssb_exit_no_lock        ;DX:AX = 0 on error

        xor     eax,eax                   ;return 0 for error
        cwd
        call    leave_driver

ssb_exit_no_lock:

        fw_zero <ecx>

                RET

SaveScreenBits  ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = RestoreScreenBits
;*
;* DESCRIPTION   =
;*
;*        Restore a rectangle of bits from unused display memory to the display.
;*
;*        Device                        Offset in
;*        coord                         screen RAM
;*        -----------------------------------------
;*        y+    |                       offset 0000
;*              |    +-------------+
;*              |    |             |
;*              |    + - - - - - + |
;*              |    |             |
;*              |    |           | |
;*              |    |             |
;*              |....+-----------+-+
;*              |    .
;*              |    .
;*              |    .
;*        0,0   +======================
;*              +-------------+         offset xxxx
;*              |             |
;*              + - - - - - + |
;*              |             |
;*              |           | |
;*              |             |
;*            A +-----------+-+
;*              |
;*              |
;*              |
;*        y-    |                       offset FFFF
;*
;*
;*        The source (x,y) is always at "A" in the diagram above.  The clipping is
;*        performed by adjusting the upper right corner of the destination
;*        rectangle, so that the saved bits appear flush with the lower left.
;*
;*        Note:  If the saved bits were clipped to the display borders, then the
;*               caller must restore in such a way that RestoreScreenBits can put
;*               up all the bits, or it will return an error.
;*
;*               Registers Preserved:
;*                     SI,DI,DS,BP
;*               Registers Destroyed:
;*                     AX,BX,CX,DX,ES,FLAGS
;*
;* INPUT         = EGA registers in default state
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = AX = 1 if no error
;* RETURN-ERROR  = AX = 0 if error occured
;*
;**************************************************************************/


RestoreScreenBits       PROC SYSCALL USES ebx esi edi,  hdc:DWORD, hSB:DWORD,
                                                        lpRect:DWORD, Options:DWORD,
                                                        hddc:DWORD, FunN:DWORD
                        LOCAL   Points[3]:RECTL,
                                loc_x_origin:DWORD,
                                loc_y_origin:DWORD,
                                loc_x_extent:DWORD,
                                loc_y_extent:DWORD,
                                loc_x_clip_lft:DWORD
                        LOCAL   loc_y_clip_btm:DWORD,
                                loc_x_clip_rgt:DWORD,
                                loc_y_clip_top:DWORD,
                                loc_y_offscreen:DWORD,
                                new_x_extent:DWORD
                        LOCAL   new_y_extent:DWORD,
                                new_x_clip_lft:DWORD,
                                new_y_clip_btm:DWORD,
                                new_x_clip_rgt:DWORD,
                                new_y_clip_top:DWORD,
                                saved_iflags:BYTE,
                                saved_pflags:BYTE,
                                loc_bit_align:BYTE


        DebugMsg <RestoreScreenBits, DISPATCH, ssb, CLIFFL>


        cld
        mov     edx,hddc
        call    enter_driver
        jc      rsb_exit_no_lock        ;DX:AX = 0 on error

        xor     eax,eax                   ;return 0 for error

        test    Options,RSB_FREE     ;free also?
        jz      rsb_really_exit         ;no, so don't discard

        sub     edx,edx
        test    fbOffScreen,OFFSCR_VDD  ;Video VDD loaded?
        jz      rsb_no_vdd              ;nope

        push    eax                      ;save return code

        INVOKE  DosRequestVDD, hVideoVDD, 0, VVDSYSREQ_FREEMEM, 0, 0, nbOffScreenUsed,
                                ADDR pOffScreenUsed

        pop     eax                      ;restore return code

rsb_no_vdd:

        mov     pOffScreenUsed,edx   ;zero all these fields now
        mov     pOffScreenScan,edx
        mov     yOffScreenScan,edx
        mov     nbOffScreenUsed,edx
        and     fbOffScreen,NOT OFFSCR_TRASHED

;;/*        ;          
;;** If COM_SCR_BOUND is not set, then skip DCAF code.  ;          
;;*/        ;          
; test FunN,COM_SCR_BOUND    ;          
; jz bounds_considered    ;          
;;/*        ;          
;;** Save the contents of esi and edi.    ;          
;;*/        ;          
; pushem esi,edi      ;          
;;/*        ;          
;;** Only 2 bits of the Command word are of interest to us. ;          
;;*/        ;          
; mov edi,FunN     ;          
; and edi,COM_SCR_BOUND or COM_DRAW   ;          
;        ;          
;       mov     esi,lpRect     ;          
;       mov     eax,[esi].RECTL.rcl_xLeft   ;          
;       mov     ecx,[esi].RECTL.rcl_xRight   ;          
;       mov     edx,[esi].RECTL.rcl_yBottom   ;          
;       mov     ebx,[esi].RECTL.rcl_yTop   ;          
;        ;          
;;/*        ;          
;;** Make esi point to the ddc.     ;          
;;*/        ;          
; mov esi,hddc     ;          
;;/*        ;          
;;** (eax,ebx)-(ecx,edx) = inclusive rect to accumulate  ;          
;;** esi = DDC, edi = Command     ;          
;;*/        ;          
; call InnerAccumulateBounds    ;          
;        ;          
; popem esi,edi      ;          
;        ;          
;bounds_considered:      ;          

rsb_really_exit:

        cwd                             ;return DX:AX

        call    leave_driver

rsb_exit_no_lock:

        fw_zero <ecx>

                        RET

RestoreScreenBits       ENDP

        end
