;*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 = BUNDLE.ASM
;*
;* DESCRIPTIVE NAME = This file contains the routines which manage bitmaps.
;*
;*
;* VERSION      V2.0
;*
;* DATE         08/25/87
;*
;* DESCRIPTION   This file contains the routines which handle bundle attribute 
;*               calls
;*
;* FUNCTIONS    set_basic_attributes
;*              dsa_char
;*              dsa_marker
;*              dsa_pattern
;*              dsa_line
;*              DeviceSetAttributes         
;*              DeviceGetAttributes
;*              devicesetglobalattribute    
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*   08/25/87                     Written by Hock Lee
;*   07/07/88                     Walt Moore [waltm] Delay mapping image data
;*                                foreground mix mode.
;*   10/09/91                     Cliff Levesque  [cliffl]
;*                                Convert to 32 bit operation.
;*   08/18/92              DCR37  Added needed changes for DCR 37
;*
;*****************************************************************************/
        .386

        OPTION  OLDSTRUCTS

INCL_DDIBUNDLES         equ     1
INCL_GRE_DEVMISC1       equ     1
INCL_FONTFILEFORMAT     equ     1
INCL_DDIMISC            equ     1
INCL_GRE_DEVSUPPORT     equ     1
INCL_GPIERRORS          equ     1
INCL_WINSYS             equ     1
DINCL_ENABLE            equ     1
DINCL_BITMAP            equ     1
OS2P_DEFD               equ     1

        .xlist

        include pmgre.inc
        include driver.inc
        include extern.inc
        include protos.inc

        .list

        .MODEL FLAT

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

        .DATA

;/*
;** We want some more convenient names for the basic attributes.  We'll
;** do all the error checking up front so it doesn't mess the code up
;** all over the place.
;*/

BB_COLOR        equ     00000001b
BB_BACK_COLOR   equ     00000010b
BB_MIX          equ     00000100b
BB_BACK_MIX     equ     00001000b
BASIC_ATTR_MASK equ     BB_COLOR or BB_BACK_COLOR or BB_MIX or BB_BACK_MIX

        .errnz  BB_COLOR-LBB_COLOR
        .errnz  BB_BACK_COLOR-LBB_BACK_COLOR
        .errnz  BB_MIX-LBB_MIX_MODE
        .errnz  BB_BACK_MIX-LBB_BACK_MIX_MODE

        .errnz  BB_COLOR-CBB_COLOR
        .errnz  BB_BACK_COLOR-CBB_BACK_COLOR
        .errnz  BB_MIX-CBB_MIX_MODE
        .errnz  BB_BACK_MIX-CBB_BACK_MIX_MODE

        .errnz  BB_COLOR-MBB_COLOR
        .errnz  BB_BACK_COLOR-MBB_BACK_COLOR
        .errnz  BB_MIX-MBB_MIX_MODE
        .errnz  BB_BACK_MIX-MBB_BACK_MIX_MODE

        .errnz  BB_COLOR-ABB_COLOR
        .errnz  BB_BACK_COLOR-ABB_BACK_COLOR
        .errnz  BB_MIX-ABB_MIX_MODE
        .errnz  BB_BACK_MIX-ABB_BACK_MIX_MODE

        .errnz  BB_COLOR-IBB_COLOR
        .errnz  BB_BACK_COLOR-IBB_BACK_COLOR
        .errnz  BB_MIX-IBB_MIX_MODE
        .errnz  BB_BACK_MIX-IBB_BACK_MIX_MODE


PUBLIC sba_done_background

MAX_BUNDLE_TYPE equ     PRIM_IMAGE      ;Assume image is the last type

        .errnz  PRIM_IMAGE-5    ;Incase they change it



abAttrsMasks    label   byte

        db      BB_COLOR

        .errnz  ATYPE_COLOR-1

        db      BB_BACK_COLOR

        .errnz  ATYPE_BACK_COLOR-2

        db      BB_MIX

        .errnz  ATYPE_MIX_MODE-3

        db      BB_BACK_MIX

        .errnz  ATYPE_BACK_MIX_MODE-4

;/*
;**
;** ausAttrOffset contains the offsets to the basic attributes for
;** each of the bundle attributes.
;**
;*/

ausAttrOffset   label   dword

        dd      OFFSET DDC.ddc_la.la_ba

        .errnz  PRIM_LINE-1

        dd      OFFSET DDC.ddc_ca.ca_ba

        .errnz  PRIM_CHAR-2

        dd      OFFSET DDC.ddc_ma.ma_ba

        .errnz  PRIM_MARKER-3

        dd      OFFSET DDC.ddc_pa.pa_ba

        .errnz  PRIM_AREA-4

        dd      OFFSET DDC.ddc_ia.ia_ba

        .errnz  PRIM_IMAGE-5

;/*
;** anpfnAttrProcs contains the processors for each of the basic
;** attributes
;*/

anpfnAttrProcs  label   dword           ;Dispatch table for which

        dd      dsa_line                ;  attribute we want to set

        .errnz  PRIM_LINE-1

        dd      dsa_char

        .errnz  PRIM_CHAR-2

        dd      dsa_marker

        .errnz  PRIM_MARKER-3

        dd      dsa_pattern

        .errnz  PRIM_AREA-4

        dd      dsa_image

        .errnz  PRIM_IMAGE-5

;/*
;** acbSaveSize contains the number of bytes of attribute information
;** in the ddc which must be saved to be able to recover from an error.
;*/

acbSaveSize     label   dword           ;Number of words of current attribute

        dd      LA_DSA_SAVE_LIM/4       ;  to save on stack for error recovery

        .errnz  PRIM_LINE-1

        dd      CA_DSA_SAVE_LIM/4

        .errnz  PRIM_CHAR-2

        dd      MA_DSA_SAVE_LIM/4

        .errnz  PRIM_MARKER-3

        dd      PA_DSA_SAVE_LIM/4

        .errnz  PRIM_AREA-4

        dd      IA_DSA_SAVE_LIM/4

        .errnz  PRIM_IMAGE-5

        .errnz  LA_DSA_SAVE_LIM and 3
        .errnz  CA_DSA_SAVE_LIM and 3
        .errnz  MA_DSA_SAVE_LIM and 3
        .errnz  PA_DSA_SAVE_LIM and 3
        .errnz  IA_DSA_SAVE_LIM and 3

        .erre   PA_DSA_SAVE_LIM gt LA_DSA_SAVE_LIM
        .erre   PA_DSA_SAVE_LIM gt CA_DSA_SAVE_LIM
        .erre   PA_DSA_SAVE_LIM gt MA_DSA_SAVE_LIM
        .erre   PA_DSA_SAVE_LIM gt IA_DSA_SAVE_LIM

;/*
;** afbDefClr is used to set the BA_CLR_INVALID, BA_CLR_BACK_INV,
;** BA_CLR_DEF, BA_CLR_BACK_DEF, and BA_REREALIZE in the ba_fb flags.
;*/

afbDefClr       label   byte

        db      0
        db      BA_REREALIZE or BA_CLR_INVALID or BA_CLR_DEF

        .errnz  BB_COLOR-1

        db      BA_REREALIZE or BA_CLR_BACK_INV or BA_CLR_BACK_DEF

        .errnz  BB_BACK_COLOR-2

        db      BA_REREALIZE or BA_CLR_INVALID or BA_CLR_DEF or BA_CLR_BACK_INV or BA_CLR_BACK_DEF

        .errnz  (BB_COLOR or BB_BACK_COLOR)-3

;/*
;** asBundleOffset contains the offset from the start of a bundle to the
;** each of the basic attributes.  This is used by DeviceSetGlobalAttribute
;** to synthesize a pointer to the stack to the attribute to be set.
;*/

acBundleOffset  label   dword

        dd      -(DLINEBUNDLE.dlbnd_lbnd.lbnd_lColor)

        .errnz  BB_COLOR-1

        dd      -(DLINEBUNDLE.dlbnd_lbnd.lbnd_lBackColor)

        .errnz  BB_BACK_COLOR-2

        dd      -(DLINEBUNDLE.dlbnd_lbnd.lbnd_usMixMode)

        .errnz  BB_MIX-4

        dd      -(DLINEBUNDLE.dlbnd_lbnd.lbnd_usBackMixMode)

        .errnz  BB_BACK_MIX-8           ;Bunches of .errnzs above too
page

        .CODE

;/***************************************************************************
;*
;* FUNCTION NAME = set_basic_attributes
;*
;* DESCRIPTION   = Sets basic attributes color, background color, mix mode, and           
;*                 background mix mode in the DC.                                         
;*
;*                 Registers Preserved:
;*                       EBX,ECX,ESI,EDI,EBP
;*                
;*                 Registers Destroyed:
;*                       EAX,EDX,FLAGS
;*
;* INPUT         = EBX     =  ddc
;*                 EBP     =  Attribute index (a word index)
;*                 CL      =  default mask (used only for colors)
;*                 EDI     =  attribute mask
;*                 ESI     =  bundle record
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = EAX = 1         
;*                 ZF cleared      
;* RETURN-ERROR  = EAX = 0         
;*                 ZF set          
;*                 error logged    
;*
;**************************************************************************/
        ASSUME  esi:PTR DLINEBUNDLE

ALIGN 4
set_basic_attributes    PROC SYSCALL USES esi edi ebx ecx

ifdef FIREWALLS

        ddc?    ebx

        test    cl,not (BB_COLOR or BB_BACK_COLOR)
        jnz     sba_internal_error
        cmp     ebp,(MAX_BUNDLE_TYPE*SIZE_WORD)-2
        ja      sba_internal_error
        test    ebp,00000001b
        jz      @F

sba_internal_error:

        rip     text,<set_basic_attributes - internal error>
@@:
endif

;/*
;** Set the ba_fb flags BA_CLR_INVALID, BA_CLR_BACK_INV, BA_CLR_DEF,
;** and BA_CLR_BACK_DEF as appropriate.
;**
;** We'll basically do a table lookup to get the bits to set/clear in
;** the ba_fb word.
;*/

        add     ebx,ausAttrOffset[ebp*2]        ;--> attribute to change
;----------------------------------------------------------------------------
        ASSUME ebx:PTR BASIC_ATTRS
;----------------------------------------------------------------------------
        movzx   ecx,cl
        xchg    ebx,ecx                 ;CX --> ba_
        mov     bh,afbDefClr[ebx]       ;BH = defaults OR mask, BL = defs mask
        mov     eax,edi
        and     eax,BB_COLOR or BB_BACK_COLOR
        xchg    eax,ebx                 ;AH = defaults OR mask, AL = defs mask
        mov     bh,afbDefClr[ebx]       ;BH = non-defs OR mask (with some work)
        xchg    eax,ecx                 ;CH = defaults OR mask, CL = defs mask
        xchg    eax,ebx                 ;BX --> ba_, AH = non-defs mask
        mov     al,[ebx].ba_fb
        or      al,ch                   ;Set INV, DEF bits for default colors
        or      al,ah                   ;Set INV bits for non-default colors
        and     ah,BA_CLR_DEF or BA_CLR_BACK_DEF
        xor     al,ah                   ;Clear def bits from non-defs mask
        mov     [ebx].ba_fb,al

sba_done_defaults:

;/*
;** Set foreground color
;*/

        test    edi,BB_COLOR
        jz      sba_done_foreground

;/*
;** Validate the index a little.  If the high byte is non-zero, then we
;** can do a range check on the special colors.  If it is zero, we can't
;** do anything until they try to use the color.
;*/

        mov     eax,[esi].dlbnd_lbnd.lbnd_lColor
        mov     edx,eax
        shr     edx,16
        mov     [ebx].ba_clr,eax
        or      dh,dh
        jz      sba_done_foreground
        cmp     edx,0ffffh
        jnz     sba_invalid_color
        cmp     eax,MIN_SPECIAL_COLOR
        jae     sba_done_foreground

sba_invalid_color:

        mov     edx,PMERR_INV_COLOR_ATTR
        jmp     sba_log_error
ALIGN 4

sba_invalid_back_color:

        mov     edx,PMERR_INV_BACKGROUND_COL_ATTR

sba_log_error:

        xchg    eax,edx

        save_error_code

        xor     eax,eax
        jmp     sba_exit
ALIGN 4

sba_done_foreground:


;/*
;** Set background color
;*/

        test    edi,BB_BACK_COLOR
        jz      sba_done_background
        mov     eax,[esi].dlbnd_lbnd.lbnd_lBackColor
        mov     edx,eax
        shr     edx,16
        mov     [ebx].ba_clrBack,eax
        or      dh,dh
        jz      sba_done_background
        cmp     edx,0ffffh
        jnz     sba_invalid_back_color
        cmp     eax,MIN_SPECIAL_COLOR
        jb      sba_invalid_back_color

sba_done_background::


;/*
;** Set foreground mix mode attribute.  There is no default mask bit
;** for it.  If the range is invalid, report an error.
;*/

        test    edi,BB_MIX
        jz      sba_done_fore_mix
        mov     edx,PMERR_INV_MIX_ATTR
        movzx   eax,[esi].dlbnd_lbnd.lbnd_usMixMode
        dec     eax                     ;DCR 22793 removed 0
        cmp     eax,FM_ONE
        jae     sba_log_error
        cmp     eax,3-1                 ;Reserved - underpaint
        je      sba_log_error
        cmp     ebp,(PRIM_IMAGE-1)*2    ;Don't map image data mix mode
        je      have_fore_mix
        mov     edx,edi
        mov     edi,anpabForeMix[ebp*2]
        xchg    eax,ebx
        mov     bl,BYTE PTR [edi][ebx]
        xchg    eax,ebx
        mov     edi,edx

have_fore_mix:

        mov     [ebx].ba_bmix,al

sba_done_fore_mix:

;/*
;** Set background mix mode attribute.  There is no default mask bit
;** for it.  If the range is invalid, return an error.
;*/

        test    edi,BB_BACK_MIX
        jz      sba_done_back_mix
        mov     edx,PMERR_INV_BACKGROUND_MIX_ATTR

        mov     cx,DEVCAPS_COLORS       ;          
        cmp     cx,16                   ;          
        ja      DCR37_Implemented       ;          
        mov     ecx,BM_ONE              ;           Last valid entry of BM_ with no DCR37
        jmp     @f                      ;          
DCR37_Implemented:                      ;          
        mov     ecx,BM_DESTTRANSPARENT  ;           Last valid entry of BM_ DCR37
@@:                                     ;          
        movzx   eax,[esi].dlbnd_lbnd.lbnd_usBackMixMode
        dec     eax                     ;DCR 22793 removed 0
        cmp     eax,ecx                 ;          
        jae     sba_log_error           ;!!we will use it.

        cmp     eax,3-1                 ;Reserved - underpaint
        je      sba_log_error

have_back_mix:

        mov     edx,edi
        mov     edi,anpabBackMix[ebp*2]
        xchg    eax,ebx
        mov     bl,BYTE PTR [edi][ebx]
        xchg    eax,ebx
        mov     edi,edx
        mov     [ebx].ba_bkmix,al

sba_done_back_mix:

        mov     eax,1                   ;Show success

sba_exit:

        sub     ebx,ausAttrOffset[ebp*2]        ;--> to start of the ddc
        or      eax,eax                 ;Set/clear 'Z'

                        RET

set_basic_attributes    ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = dsa_char
;*
;* DESCRIPTION   = This function is used to set the attributes for characters                 
;*
;*                 Registers Preserved:
;*                       EBX,ESI,EDI,EBPS        CL if only basic attributes
;*                 
;*                 Registers Destroyed:
;*                       EAX,CH,EDX,FLAGS        CL if other than basic attributes
;*                 
;* INPUT         = EBX     --> ddc
;*                 EBP     =  Attribute index (a word index)
;*                 CL      =  default mask (used only for colors)
;*                 CH      =  basic attributes mask
;*                 EDI     =  attribute mask
;*                 ESI     =  bundle record
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = EAX = 1   
;* RETURN-ERROR  = EAX = 0       
;*                 error logged  
;**************************************************************************/


ALIGN 4
dsa_char        PROC    SYSCALL USES ebx esi edi

        ASSUME  ebx:PTR DDC, esi:PTR DCHARBUNDLE

        ddc?    ebx

        or      ch,ch
        jz      dsac_basics_set
        INVOKE  set_basic_attributes
        jnz     dsac_basics_set         ;No errors so far

dsac_exit_no_adjust:                    ;Don't reset ddc pointer

        jmp     dsac_exit               ;AX = return code
ALIGN 4

dsac_log_mode_error:

        mov     eax,PMERR_INV_CHAR_MODE_ATTR
        jmp     dsac_log_error
ALIGN 4

dsac_log_dir_error:

        mov     eax,PMERR_INV_CHAR_DIRECTION_ATTR
        jmp     dsac_log_error
ALIGN 4

dsac_log_align_error:

        mov     eax,PMERR_INV_CHAR_ALIGN_ATTR

dsac_log_error:

        save_error_code

        xor     eax,eax
        jmp     dsac_exit               ;Need to fix up ddc pointer
ALIGN 4

;/*
;** Process any other character, marker, or pattern attributes.  Take a
;** quick out if none are to be set.
;*/

dsac_basics_set:

        mov     eax,1                   ;Assume nothing else will change
        test    edi,CBB_MODE or CBB_DIRECTION or CBB_TEXT_ALIGN or CBB_SET or CBB_EXTRA or CBB_BREAK_EXTRA
        jz      dsac_exit_no_adjust     ;All done, take quick out, AX <> 0
        mov     ecx,[ebx].ddc_ca.ca_fs  ;Will be using this a lot

;/*
;** Process text spacings (I keep the values here in case we decide to
;** do justification in the driver.  Then we may want to keep them in
;** device units too.)
;*/

        test    edi,CBB_EXTRA
        jz      dsac_done_extra
        movsx   eax,WORD PTR [esi].dcbnd_cbnd.cbnd_fxExtra[2]
        mov     [ebx].ddc_ca.ca_fxExtra,eax

dsac_done_extra:

        test    edi,CBB_BREAK_EXTRA
        jz      dsac_done_break_extra
        movsx   eax,WORD PTR [esi].dcbnd_cbnd.cbnd_fxBreakExtra[2]
        mov     [ebx].ddc_ca.ca_fxBreakExtra,eax

dsac_done_break_extra:

;/*
;** Process any text precision (they call it mode)
;*/
        test    edi,CBB_MODE
        jz      dsac_done_mode
        and     cx,not CA_PREC_NOT_1    ;Assume precision 1
        mov     ax,[esi].dcbnd_cbnd.cbnd_usPrecision
        dec     ax                      ;DCR 22793 removed CM_DEFAULT (0)
        cmp     ax,CM_MODE3             ;Check for legal modes
        jae     dsac_log_mode_error          ;It's illegal
        neg     ax                      ;'C' set if not mode 1
        sbb     ax,ax                   ;AX = FFFF if not mode 1
        and     ax,CA_PREC_NOT_1
        or      cx,ax

        .errnz  CM_MODE1-1              ;It was decremented above

dsac_done_mode:

;/*
;** Process any drawing direction
;*/

        test    edi,CBB_DIRECTION
        jz      dsac_done_dir
        mov     ax,[esi].dcbnd_cbnd.cbnd_usDirection
        dec     ax                      
        cmp     ax,CHDIRN_BOTTOMTOP
        jae     dsac_log_dir_error
        and     cl,not CA_DIRECTION
        or      cl,al

        .errnz  CHDIRN_LEFTRIGHT-1
        .errnz  CHDIRN_TOPBOTTOM-2
        .errnz  CHDIRN_RIGHTLEFT-3
        .errnz  CHDIRN_BOTTOMTOP-4
        .errnz  CA_DIRECTION-00000011b

dsac_done_dir:

;/*
;** Process any text align.
;** check the dd_ca value 
;*/

        test    edi,CBB_TEXT_ALIGN
        jz      dsac_done_align
        mov     ax,[esi].dcbnd_cbnd.cbnd_usTextAlign
        dec     al
        cmp     al,TA_STANDARD_HORIZ
        jae     dsac_log_align_error
        dec     ah
        cmp     ah,(TA_STANDARD_VERT shr 8)
        jae     dsac_log_align_error
        inc     al
        inc     ah
        cwde
        mov     [ebx].ddc_ca.ca_usTextAlign,eax

.errnz TA_NORMAL_HORIZ   - 0001h
.errnz TA_LEFT           - 0002h
.errnz TA_CENTER         - 0003h
.errnz TA_RIGHT          - 0004h
.errnz TA_STANDARD_HORIZ - 0005h
.errnz TA_NORMAL_VERT    - 0100h
.errnz TA_TOP            - 0200h
.errnz TA_HALF           - 0300h
.errnz TA_BASE           - 0400h
.errnz TA_BOTTOM         - 0500h
.errnz TA_STANDARD_VERT  - 0600h

dsac_done_align:

;/*
;** Process any font change
;*/

CA_CLEAR = CA_VECTOR or CA_MUST_MAP    or CA_CHAR_EXTRA or CA_ABC_SPACE
CA_CLEAR = CA_CLEAR  or CA_FIXED_PITCH or CA_WIDTH_IS_8 or CA_STRIKEOUT
CA_CLEAR = CA_CLEAR  or CA_UNDERSCORE  or CA_ITALIC     or CA_BOLD
CA_CLEAR = CA_CLEAR  or CA_USER_FONT

        mov     eax,1                   ;Assume no font change
        test    edi,CBB_SET
        jz      dsac_save_flags


;/*
;** Need ES:[SI] -> CHARDEFS temporarily.  Use indirection in case size of
;** CHARBUNDLE changes.
;*/



        and     ecx,not CA_CLEAR
        mov     eax,[esi].dcbnd_cdef.cdef_fFlags
        and     eax,(CDEF_STRIKEOUT+CDEF_UNDERSCORE+CDEF_ITALIC+CDEF_BOLD)
        add     eax,eax
        or      ecx,eax

        .errnz  (CDEF_BOLD       shl 1) - CA_BOLD
        .errnz  (CDEF_ITALIC     shl 1) - CA_ITALIC
        .errnz  (CDEF_UNDERSCORE shl 1) - CA_UNDERSCORE
        .errnz  (CDEF_STRIKEOUT  shl 1) - CA_STRIKEOUT

        mov     eax,[esi].dcbnd_cdef.cdef_defSet

        ASSUME  esi:PTR DCHARBUNDLE

        cmp     [esi].dcbnd_cbnd.cbnd_usSet,LCID_DEFAULT
        je      dsac_have_font
        or      ecx,CA_USER_FONT

dsac_have_font:

        mov     [ebx].ddc_ca.ca_pFont,eax

;/*
;** Invoke the routine which deals with font selection.  The registers
;** being passed are:
;**
;**       EBX --> ddc
;**       EAX    =  font handle / font pointer
;**       EBP    =  attr index for characters
;**       ECX    =  ca_fs
;**       ESI --> attribute bundle
;**
;** We expect this routine to set BA_REREALIZE if it is appropriate.
;*/

        call    SetCharFont             ;AX = return code

dsac_save_flags:

        mov     [ebx].ddc_ca.ca_fs,ecx

dsac_exit:

                RET

dsa_char        ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = dsa_marker
;*
;* DESCRIPTION   = Sets marker attributes in the ddc.                                   
;*
;*                 Registers Preserved:
;*                       EBX,CL,ESI,EDI,EBP
;*                
;*                 Registers Destroyed:
;*                       EAX,CH,EDX,FLAGS
;*
;* INPUT         = EBX     --> ddc
;*                 EBP     =  Attribute index (a word index)
;*                 CL      =  default mask (used only for colors)
;*                 CH      =  basic attributes mask
;*                 EDI     =  attribute mask
;*                 ESI     =  bundle record
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = EAX = 1 
;* RETURN-ERROR  = EAX = 0     
;*                 error logged  
;**************************************************************************/

                ASSUME  ebx:PTR DDC, esi:PTR DMARKERBUNDLE

ALIGN 4
dsa_marker      PROC    SYSCALL PUBLIC USES ebx ecx esi edi

        ddc?    ebx

;/*
;** We don't care about the marker cell size.  We don't do any scaling
;** or support non-raster fonts, so we'll ignore it.  The code point
;** can never be invalid since we use the default for any code point
;** which isn't in the set.
;*/

        or      ch,ch
        jz      dsam_basics_set
        INVOKE  set_basic_attributes
        jz      dsam_exit_relay_z       ;AX = return code

dsam_basics_set:

;/*
;** If we have a new code point, we'll have to save it.  We won't validate
;** it until we use it when we have a good font, etc.
;*/

        test    edi,MBB_SYMBOL
        jz      dsam_code_point_done
        mov     ax,[esi].dmbnd_mbnd.mbnd_usSymbol
        mov     [ebx].ddc_ma.ma_ch,al
        or      [ebx].ddc_ma.ma_fs,CA_CHANGED
        or      [ebx].ddc_ma.ma_ba.ba_fb,BA_REREALIZE

dsam_code_point_done:

;/*
;** Process any font change.  We'll allow non-raster fonts which we'll
;** just pass to the engine.
;*/

        mov     eax,1                   ;Assume no font change
        test    edi,MBB_SET

dsam_exit_relay_z:

        jz      dsam_exit
        mov     ecx,[ebx].ddc_ma.ma_fs
        and     ecx,not CA_CLEAR
        mov     eax,[esi].dmbnd_mdef.mdef_fFlags
        and     eax,(CDEF_STRIKEOUT+CDEF_UNDERSCORE+CDEF_ITALIC+CDEF_BOLD)
        add     eax,eax
        or      ecx,eax

        .errnz  (CDEF_BOLD       shl 1) - CA_BOLD
        .errnz  (CDEF_ITALIC     shl 1) - CA_ITALIC
        .errnz  (CDEF_UNDERSCORE shl 1) - CA_UNDERSCORE
        .errnz  (CDEF_STRIKEOUT  shl 1) - CA_STRIKEOUT

        or      ecx,CA_USER_FONT        ;Assume user font
        cmp     [esi].dmbnd_mbnd.mbnd_usSet,LCID_DEFAULT
        je      dsam_use_default_font
        mov     eax,[esi].dmbnd_mdef.mdef_defSet

        or      eax,eax                 ;User font if non-zero
        jnz     dsam_have_font

dsam_use_default_font:

ifdef FIREWALLS

        test    [esi].dmbnd_mdef.mdef_fFlags,1 
        jz      @F
        rip     text,<dsa_char - Default font was flagged FNT_GENERIC>
@@:
endif
        and     ecx,not CA_USER_FONT
        mov     eax,ddcInit.ddc_ma.ma_pFont

dsam_have_font:

        mov     [ebx].ddc_ma.ma_pFont,eax

;/*
;** Invoke the routine which deals with font selection.  The registers
;** being passed are:
;**
;**       EBX --> ddc
;**       EAX    =  font handle / font pointer
;**       EBP    =  attr index for characters
;**       ECX    =  ma_fs
;**       ESI -->
;**
;** We expect this routine to set BA_REREALIZE if it is appropriate.
;*/

        call    SetMarkerFont           ;AX = return code
        mov     [ebx].ddc_ma.ma_fs,ecx

dsam_exit:

                RET

dsa_marker      ENDP

page

;/***************************************************************************
;*
;* FUNCTION NAME = dsa_pattern
;*
;* DESCRIPTION   = Sets pattern attributes in the ddc.                                          
;*
;*                 Registers Preserved:
;*                       EBX,CL,ESI,EDI,EBP
;*                
;*                 Registers Destroyed:
;*                       EAX,CH,EDX,FLAGS
;*
;* INPUT         = EBX     --> ddc
;*                 EBP     =  Attribute index (a word index)
;*                 CL      =  default mask (used only for colors)
;*                 CH      =  basic attributes mask
;*                 EDI     =  attribute mask
;*                 ESI     =  bundle record
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = EAX = 1         
;* RETURN-ERROR  = EAX = 0        
;*                 error logged   
;**************************************************************************/
        ASSUME  ebx:PTR DDC,esi:PTR DAREABUNDLE

ALIGN 4
dsa_pattern     PROC    SYSCALL USES ebx ecx esi edi

        ddc?    ebx
        or      ch,ch
        jz      dsap_basics_set
        INVOKE  set_basic_attributes
        jz      jz_dsap_exit_relay      ;AX = return code

dsap_basics_set:

;/*
;** If we have a new code point, we'll have to save it.  We won't validate
;** it until we use it when we have a good font, etc.
;*/

        test    edi,ABB_SYMBOL
        jz      dsap_code_point_done
        mov     ax,[esi].dabnd_abnd.pbnd_usSymbol
        mov     [ebx].ddc_pa.pa_ch,al
        or      [ebx].ddc_pa.pa_fs,CA_CHANGED
        or      [ebx].ddc_pa.pa_ba.ba_fb,BA_REREALIZE

dsap_code_point_done:

;/*
;** Process any pattern origin change.  If we have a change, make sure
;** the new origin will be valid in device coordinates.  Since we saved
;** the state of this attribute bundle, we can go ahead and save the new
;** pattern origin in the ddc.  If we end up with an error, the bundle
;** will be cleaned up for us.
;*/

        test    edi,ABB_REF_POINT
        jz      dsap_done_ref_ptl
        mov     eax,[esi].dabnd_abnd.pbnd_ptlRefPoint.ptl_x
        mov     [ebx].ddc_pa.pa_ptlOrg.ptl_x,eax
        mov     eax,[esi].dabnd_abnd.pbnd_ptlRefPoint.ptl_y
        mov     [ebx].ddc_pa.pa_ptlOrg.ptl_y,eax
        or      [ebx].ddc_pa.pa_ba.ba_fb,BA_REREALIZE
        xchg    ebx,esi                 ;DS:SI --> ddc
        push    ecx
        push    ebx
        push    edi
        INVOKE  xform_pattern_origin
        pop     edi
        pop     ebx
        pop     ecx
        xchg    ebx,esi
        or      eax,eax

jz_dsap_exit_relay:

        jz      dsap_exit               ;Error occured

dsap_done_ref_ptl:

;/*
;** Process any font change.  We only allow bitmaps and raster fonts
;*/

        test    edi,ABB_SET
        jz      dsap_have_font
        and     [ebx].ddc_pa.pa_fs,not (CA_CLEAR)
        and     [ebx].ddc_pa.pa_fb,not (PA_BITMAP_SRC or PA_COLOR_TRUTH)
        or      [ebx].ddc_pa.pa_fs,CA_CHANGED
        or      [ebx].ddc_pa.pa_ba.ba_fb,BA_REREALIZE
        cmp     [esi].dabnd_abnd.pbnd_usSet,LCID_DEFAULT
        je      dsap_have_font
        mov     edx,[esi].dabnd_adef.adef_defSet
        or      edx,edx                 ;User font if non-zero
        jz      dsap_have_font          ;Its the default
        mov     [ebx].ddc_pa.pa_pFont,edx


;/*
;** Invoke the routine which deals with font selection for patterns
;**
;**       EBX --> ddc
;**       EDX    =  font handle / font pointer / bitmap handle
;**       EBP    =  attr index for characters
;**       ESI --> attribute bundle
;**
;*/
        call    SetPatternFont          ;AX = return code
        jmp     dsap_exit
ALIGN 4

dsap_have_font:

        mov     eax,1                   ;Assume no font change

dsap_exit:

                RET

dsa_pattern     ENDP

page

;/***************************************************************************
;*
;* FUNCTION NAME = dsa_image
;*
;* DESCRIPTION   = There are only the basic attributes for image data, so we can            
;*                 just use the set_basic_attributes function.                              
;*
;*                 Registers Preserved:
;*                       EBX,CL,ESI,EDI,EBP
;*                
;*                 Registers Destroyed:
;*                       EAX,CH,EDX,FLAGS
;*
;* INPUT         = EBX     --> ddc
;*                 EBP     =  Attribute index (a word index)
;*                 CL      =  default mask (used only for colors)
;*                 CH      =  basic attributes mask
;*                 EDI     =  attribute mask
;*                 ESI     =  bundle record
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = EAX = 1  
;* RETURN-ERROR  = EAX = 0      
;*                 error logged 
;**************************************************************************/

dsa_image       equ     set_basic_attributes
page

;/***************************************************************************
;*
;* FUNCTION NAME = dsa_line
;*
;* DESCRIPTION   = Sets line attributes in the ddc.                                 
;*
;*                 Registers Preserved:
;*                       EBX,CL,ESI,EDI,EBP
;*                
;*                 Registers Destroyed:
;*                       EAX,CH,EDX,FLAGS
;*
;* INPUT         = EBX     --> ddc
;*                 EBP     =  Attribute index (a word index)
;*                 CL      =  default mask (used only for colors)
;*                 CH      =  basic attributes mask
;*                 EDI     =  attribute mask
;*                 ESI     =  bundle record
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = EAX = 1   
;* RETURN-ERROR  = EAX = 0       
;*                 error logged  
;**************************************************************************/

ALIGN 4
dsa_line        PROC    SYSCALL USES ebx ecx esi edi

        ASSUME  esi:PTR _DLINEBUNDLE, ebx:PTR DDC

        ddc?    ebx

        or      ch,ch
        jz      dsal_basics_set         ;No basic attributes will change
        INVOKE  set_basic_attributes
        jz      dsal_exit               ;Had an error, AX = 0

dsal_basics_set:

;/*
;** If a line type is being set, validate it and set it if valid.
;*/

        test    edi,LBB_TYPE
        jz      dsal_check_width
        mov     ax,[esi].dlbnd_lbnd.lbnd_usType
        dec     ax                      ;DCR 22793 removed LINETYPE_DEFAULT (0)
        cmp     ax,LINETYPE_ALTERNATE
        jb      dsal_line_type_ok
        mov     eax,PMERR_INV_LINE_TYPE_ATTR

        save_error_code

        xor     eax,eax
        jmp     dsal_exit
ALIGN 4

dsal_line_type_ok:

        mov     [ebx].ddc_la.la_usType,eax 

dsal_check_width:

        test    edi,LBB_WIDTH
        jz      dsa_line_done

;/*
;** Move the high portion of the line width into the line bundle.  Since
;** the line width is fixed point, the lower word is not relevant.
;*/

        movsx   eax,WORD PTR [esi].dlbnd_lbnd.lbnd_fxWidth[2]       ; Set line width
        mov     [ebx].ddc_la.la_sWidth,eax

dsa_line_done:

        mov     eax,1                   ;Show success

dsal_exit:

                RET

dsa_line        ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = DeviceSetAttributes  
;*
;* DESCRIPTION   = Sets selected attributes in the DC. The current attributes for 
;*                 the given bundle will be saved incase an error is encountered 
;*                 and restored if one actually occurs.                                                 
;*
;*                 Registers Preserved:
;*                       ESI,EDI,EBP
;*                
;*                 Registers Destroyed:
;*                       EAX,EBX,ECX,EDX,FLAGS
;*                
;* INPUT         = NONE
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = EAX = 1 
;* RETURN-ERROR  = EAX = 0     
;*                 error logged
;**************************************************************************/
        ASSUME  ebx:PTR DDC

ALIGN 4
DeviceSetAttributes     PROC    SYSCALL PUBLIC USES edi esi ebx, hdc:DWORD,
                                BType:DWORD, DefsMask:DWORD, AttrsMask:DWORD,
                                lpAttrs:DWORD, hddc:DWORD, FunN:DWORD
                                LOCAL abTemp:PATTERN_ATTRS

        DebugMsg <DeviceSetAttributes CLIFFL>

ifdef FIREWALL

        ddc?    hddc

;/*
;** If the bundle type is invalid, the Engine screwed up.  If the default
;** mask contains anything other than BB_COLOR or BB_BACK_COLOR, it should
;** be considered an error (at least for this release).
;**
;** The high word of the attributes mask should be zero
;*/

        cmp     WORD PTR DefsMask[2],0
        jne     dsa_internal_error
        test    WORD PTR DefsMask[0],not (BB_COLOR or BB_BACK_COLOR)
        jz      @F

dsa_internal_error:

        rip     text,<DeviceSetAttributes - Invalid mask encountered>
@@:
        cmp     WORD PTR AttrsMask[2],0
        jne     dsa_internal_error
        cmp     WORD PTR BType[2],0
        jne     dsa_bad_type
        cmp     WORD PTR BType[0],0
        je      dsa_bad_type
        cmp     WORD PTR BType[0],MAX_BUNDLE_TYPE
        jbe     @F

dsa_bad_type:

        rip     text,<DeviceSetAttributes - Invalid bundle type>
@@:
endif

;/*
;** Save the current attributes on the stack so we can recover from
;** an error.
;*/

        mov     edx,hddc
        call    enter_driver_sem
        jc      dsa_exit_no_lock        ; DX:AX = 0 on error
        mov     ebx,hddc
        or      [ebx].ddc_fbBelow,DDC_DIRTY_ATTRS
        mov     esi,BType
        dec     esi
        add     esi,esi                 ;Indexing into words
        mov     BType,esi               ;Will need it later

;/*
;** Don't need to do save if only default attributes will be set since
;** default attributes cannot fail.  I want the attributes masks to be
;** mutually exclusive.
;*/

        mov     eax,AttrsMask           ;A bit in the DefsMask is only valid
        and     eax,DefsMask            ;  if same bit is set in AttrsMask
        mov     DefsMask,eax
        xor     eax,AttrsMask
        jz      dsa_save_done
        mov     ecx,acbSaveSize[esi*2]  ;# bytes to move
        mov     esi,ausAttrOffset[esi*2]        ;Offset into ddc of attributes
        add     esi,ebx                 ;Add in start of ddc
        lea     edi,abTemp
        cld
        rep     movsd

dsa_save_done:

;/*
;** Invoke the correct attribute processor to do our dirty work for us.
;*/

        mov     ecx,DefsMask
        mov     edi,eax
        or      al,cl
        and     al,BASIC_ATTR_MASK
        mov     ch,al
        mov     esi,lpAttrs
        push    ebp
        mov     ebp,BType
        call    anpfnAttrProcs[ebp*2]   ;Return code will be returned in AX
        pop     ebp
        or      eax,eax
        jnz     dsa_all_done

;/*
;** An error occured.  The saved attributes must be restored.
;*/

        or      edi,edi
        jz      dsa_all_done            ;Attributes were not saved
        mov     esi,BType
        mov     ecx,acbSaveSize[esi*2]  ;# bytes to move
        mov     edi,ausAttrOffset[esi*2]        ;Offset into ddc of attributes
        add     edi,ebx                 ;Add in start of ddc
        lea     esi,abTemp
        cld
        rep     movsd

dsa_all_done:

        call    leave_driver
dsa_exit_no_lock:

        fw_zero <ecx>

                        RET

DeviceSetAttributes     ENDP

page

;/***************************************************************************
;*
;* FUNCTION NAME = DeviceSetGlobalAttribute   
;*
;* DESCRIPTION   = This function sets the five individual primitive attributes to 
;*                 the specified value, in the pen, pattern, character, image 
;*                 and marker bundles.                                                               
;*
;*                 Registers Preserved:
;*                       ESI,EDI,EBP
;*                
;*                 Registers Destroyed:
;*                       EAX,EBX,ECX,EDX,FLAGS
;*
;* INPUT         = NONE
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = EAX = 1 
;* RETURN-ERROR  = EAX = 0      
;*                 error logged 
;**************************************************************************/

;/*
;** abAttrsMasks is used to turn the AttributeType parameter into a
;** bit index which can then be passed to set_basic_attributes
;*/

        ASSUME  ebx:PTR DDC

ALIGN 4
devicesetglobalattribute       PROC    SYSCALL PUBLIC USES edi esi ebx,
                                        hdc:DWORD, AttributeType:DWORD,
                                        Attribute:DWORD, Options:DWORD,
                                        hddc:DWORD, FunN:DWORD

        DebugMsg <DeviceSetGlobalAttribute CLIFFL DISPATCH bundle.asm>
ifdef FIREWALLS

        ddc?    hddc
        cmp     WORD PTR AttributeType[2],0
        jne     dsga_error
        mov     ax,WORD PTR AttributeType[0]
        dec     ax
        cmp     ax,ATYPE_BACK_MIX_MODE
        jb      @F

dsga_error:

        rip     text,<DeviceSetGlobalAttribute - Invalid attribute type>
@@:
endif

        mov     edx,hddc
        call    enter_driver
        jc      dsga_exit_no_lock       ; DX:AX = 0 on error
        mov     ebx,hddc
        or      [ebx].ddc_fbBelow,DDC_DIRTY_ATTRS
        push    ebp                     ;We'll be using BP soon
        mov     esi,AttributeType
        dec     esi
        mov     cl,abAttrsMasks[esi]    ;Get the mask for the attribute
        movzx   ecx,cl
        xor     edi,edi
        test    Options,GATTR_DEFAULT
        jnz     dsga_set_first_attr     ;Defaults cannot fail
        xchg    edi,ecx                 ;Not default, it's user defined

;/*
;** Now we get a little slimey.  We can simply adjust the pointer passed
;** to set_basic_attributes so that when the attribute field is accessed,
;** it will reference our stack parameter.
;*/


        mov     esi,acBundleOffset[esi*4]
        lea     esi,Attribute[esi]      ;Add efective address of offset

;/*
;** Save the current attributes on the stack so we can recover from
;** an error.  We only have to save one attribute bundle, and only
;** the basic attributes in it.  If the set succeeds for the first
;** attribute bundle, it will succeed for all of them.  If we are
;** setting the defaults, we don't save this stuff since defaults
;** can never fail.
;*/

        push    [ebx].ddc_ia.ia_ba.ba_clr
        push    [ebx].ddc_ia.ia_ba.ba_clrBack
        push    word ptr [ebx].ddc_ia.ia_ba.ba_bReserved

        .errnz  BASIC_ATTRS.ba_fb-BASIC_ATTRS.ba_bReserved-1

dsga_set_first_attr:

        mov     ebp,(PRIM_IMAGE-1)*SIZE_WORD ;--> first attribute to change

        .errnz  MAX_BUNDLE_TYPE-PRIM_IMAGE

dsga_set_next_attr:

        call    set_basic_attributes
        jz      dsga_error_occured
        dec     ebp
        dec     ebp
        jg      dsga_set_next_attr      ;If this far, AX = 1
        js      dsga_attributes_set

;/*
;** The last bundle is the linebundle.  We aren't allowed to change its
;** background color or mix mode, because it didn't have any in old versions.
;*/

        .errnz  PRIM_LINE-1

        xor     edx,edx
        or      dl,cl
        or      edx,edi
        test    edx,(LBB_BACK_COLOR OR LBB_BACK_MIX_MODE)
        jz      dsga_set_next_attr

dsga_attributes_set:

;/*
;** We need to clean the saved basic attributes off the stack if we
;** pushed them.  If the defaults mask is zero, then we did not save
;** the attributes.
;*/

        or      cl,cl
        jnz     dsga_exit
        add     esp,5*SIZE_WORD         ;Remove saved basic attributes
        jmp     dsga_exit
ALIGN 4

dsga_error_occured:

ifdef FIREWALLS

        cmp     ebp,(PRIM_IMAGE-1)*SIZE_WORD
        je      @F                      ;Should only have this error
                                        ;  on first attribute set
        rip     text,<DeviceSetGlobalAttribute - Error occured after first attribute set>
@@:
endif

;/*
;** We know we saved the parameters since default cannot fail.
;*/

        pop     word ptr [ebx].ddc_ia.ia_ba.ba_bReserved

        .errnz  BASIC_ATTRS.ba_fb-BASIC_ATTRS.ba_bReserved-1

        pop     [ebx].ddc_ia.ia_ba.ba_clrBack
        pop     [ebx].ddc_ia.ia_ba.ba_clr

dsga_exit:                              ;AX = return code

        pop     ebp
        call    leave_driver

dsga_exit_no_lock:

        fw_zero <ecx>

                                RET

devicesetglobalattribute       ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = DeviceGetAttributes 
;*
;* DESCRIPTION   = Get the current attributes.  Although a [TYPE]BUNDLE is returned,
;*                 this function only returns the foreground and background colours.
;*                                                                                            
;*                   BType    - type of bundle wanted (PRIM_*) (e.g. PRIM_CHAR)              
;*                                                                                            
;*                   TheMask  - the mask indicated what the caller wants returned. 
;*                              Only valid masks are xBB_COLOR AND xBB_BACK_COLOR 
;*                              where xe{LCMAI} (e.g. CBB_COLOR)                                             
;*                                                                                            
;*                   lpAttrrs - long pointer to a *BUNDLE structure (e.g. CHARBUNDLE)
;*                                                                                             
;*                 Registers Preserved:
;*                       ESI,EDI,EBP
;*                
;*                 Registers Destroyed:
;*                       EBX,ECX
;*
;*
;* INPUT         =  NONE
;* OUTPUT        =  NONE
;*
;* RETURN-NORMAL =  EDX:EAX = BOOL 
;* RETURN-ERROR  =  EDX:EAX = BOOL 
;*
;**************************************************************************/
                ASSUME  ebx:PTR BASIC_ATTRS

ALIGN 4
DeviceGetAttributes     PROC    SYSCALL PUBLIC USES edi esi ebx, hdc:DWORD,
                                BType:DWORD, TheMask:DWORD, lpAttrs:DWORD,
                                hddc:DWORD, FunN:DWORD

        DebugMsg <DeviceGetAttributes CLIFFL>
ifdef FIREWALLS                         ;Callable only from engine.

        ddc?    hddc
        mov     ax,WORD PTR TheMask[2]
        or      ax,WORD PTR BType[2]
        jnz     dga_firewall_error
        test    WORD PTR TheMask[0],not (BB_COLOR or BB_BACK_COLOR)
        jnz     dga_firewall_error
        mov     cx,WORD PTR BType[0]
        jcxz    dga_firewall_error
        cmp     cx,MAX_BUNDLE_TYPE
        jbe     @f

dga_firewall_error:

        rip     text,<DeviceGetAttributes - bad parameters>

@@:
endif
        mov     edx,hddc
        call    enter_driver
        MOV     eax,0      
        jc      dga_exit_no_lock

        mov     ebx,BType

        .errnz  PRIM_LINE-1

        dec     ebx
        add     ebx,ebx
        mov     ebx,ausAttrOffset[ebx*2]
        add     ebx,hddc

        mov     edi,lpAttrs

        mov     dl,[ebx].ba_fb
        mov     ecx,TheMask             ;CH = 0

;/*
;** Return either the current foreground color or the default foreground
;** color if asked for.  The default must be return as a system color
;** index because they might be in index color table mode in which case
;** an RGB triplet is useless.
;*/

        test    cl,BB_COLOR
        jz      dga_done_foreground_color
        mov     eax,[ebx].ba_clr
        test    dl,BA_CLR_DEF
        jz      @F
        or      ch,BB_COLOR             ;Show default color
        mov     eax,SYSCLR_WINDOWTEXT
@@:
        ASSUME  edi:PTR LINEBUNDLE

        mov     [edi].lbnd_lColor,eax

dga_done_foreground_color:

;/*
;** Return either the current background color or the default background
;** color if asked for.
;*/

        test    cl,BB_BACK_COLOR
        jz      dga_no_background_color ;Did not ask for foreground color
        mov     eax,[ebx].ba_clrBack
        test    dl,BA_CLR_BACK_DEF
        jz      @F
        or      ch,BB_BACK_COLOR        ;Show default color
        mov     eax,SYSCLR_WINDOW
@@:
        mov     [edi].lbnd_lBackColor,eax

dga_no_background_color:


        call    leave_driver
        mov     eax,1                   ;Return success

dga_exit_no_lock:

        RET

DeviceGetAttributes     ENDP

end
