;*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    58,132
        TITLE   VdhGetCP.Asm -- Get CodePage Fonts from the Font File

;/****************************************************************************
;*
;* SOURCE FILE NAME = VdhGetCP.Asm
;*
;* DESCRIPTIVE NAME = Get CodePage Fonts from the Font File 
;*
;*
;* VERSION      V2.0
;*
;* DATE         
;*
;* DESCRIPTION  Get CodePage Fonts from the Font File  
;*
;* FUNCTIONS    _GetCodePage 
;*              ReadFont
;*              RandomRead 
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES  CDIB                              
;*
;* EXTERNAL FUNCTIONS   DOSOPEN, DOSREAD, DOSCHGFILEPTR, DOSCLOSE,  
;*                      DOSGETSHRSEG, DOSFREESEG
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR    CHANGE DESCRIPTION
;*   --------  ----------  -----   --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx   xxxxxxx
;****************************************************************************/

        .286p

        INCLUDE cdib.inc                          ;CodePage Data Info Block
        INCLUDE fontfile.inc                      ;Font File structures
        .xlist
        INCLUDE error2.inc                        ;Error codes
        INCLUDE struc.inc                         ;Structured Macros
        .list

        EXTRN   DOSGETSHRSEG:FAR                  ;Dos Get Shared Segment routine
        EXTRN   DOSFREESEG:FAR                    ;Dos Free Segment routine

        EXTRN   DOSOPEN:FAR                       ;Dos Open routine
        EXTRN   DOSREAD:FAR                       ;Dos Read routine
        EXTRN   DOSCHGFILEPTR:FAR                 ;Dos Change File Ptr routine
        EXTRN   DOSCLOSE:FAR                      ;Dos Close routine

        extrn   _SaveRegs:FAR
        extrn   _RestoreRegs:FAR

VDHGSEG SEGMENT PARA PUBLIC 'DATA'      ;Global data segment for WDH

CDIBsel dw      0                                 ;CDIB selector
Handle  dw      0                                 ;Font file handle
CPID    dw      0                                 ;Selected CodePage Id
NumFonts dw     0                                 ;Number of Fonts read
TotalSize dw    0                                 ;Total Size of Fonts read
FontSizes dw    0,0,0,0,0,0,0,0,0,0               ;Sizes of Fonts read
        public  FontSizes

Buffer  fonthdr <>                                ;Read buffer for font headers
Scratch dd      0                                 ;Scratch area

CDIBname db     '\SHAREMEM\DOS\CDIB',0  ;CDIB name

VDHGSEG ENDS

R2CSEG  SEGMENT BYTE PUBLIC 'CODE'
        ASSUME  CS:R2CSEG

;/****************************************************************************
;*
;* SUBROUTINE NAME:  GetPreparedCodePages          
;*                                                   
;* DESCRIPTIVE NAME:   Get the Prepared CodePages for the VDH  
;*                                                   
;* FUNCTION:   Copies the requested CodePage fonts to the callers 
;*             data area.                            
;*                                                   
;* NOTES:  Executes on Level 3                      
;*                                                   
;* ENTRY POINT:  GetPreparedCodePages               
;*   LINKAGE:  Call GetPreparedCodePages           
;*                                                   
;* INPUT:  DS = PPBVSCB, ES = CodePage Data Info Block (CDIB)  
;*         CX = Number of CodePages                 
;*         SI = Offset of CodePage substructure in CDIB  
;*                                                   
;* EXIT-NORMAL:  AX = 0                              
;*                                                   
;* EXIT-ERROR:  AX = DOSxxx return code            
;*                                                   
;* EFFECTS:  None                                    
;*                                                   
;* INTERNAL REFERENCES: None                         
;*   ROUTINES:  ReadFont, RandomRead                
;*                                                   
;* EXTERNAL REFERENCES:  CDIB                        
;*   ROUTINES: DOSOPEN, DOSREAD, DOSCHGFILEPTR, DOSCLOSE,  
;*             DOSGETSHRSEG, DOSFREESEG
;****************************************************************************/

;/****************************************************************************
;*
;* FUNCTION NAME = _GetCodePage
;*
;* DESCRIPTION   = 
;*
;* INPUT         = 
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;* PSEUDOCODE
;*
;*      Bgnsub CPInit
;*        Get the Screen information from the CDIB
;*        If CodePages specified
;*          Call DOSOPEN for the CodePage file
;*          If no error
;*            Call RandomRead to get the number of fonts from the header
;*            Do for each specified code page
;*              Do for each font in the font file
;*                Call RandomRead to get the font ptr from the file header
;*                Call RandomRead to get the complete font header
;*                If font is for this CodePage
;*                  Call ReadFont to update BVSCPnn
;*                Endif
;*              Enddo
;*            Enddo
;*            Call DOSCLOSE for the CodePage file
;*          Endif
;*        Endif
;*      Endsub
;*
;****************************************************************************/

_GetCodePage PROC FAR
        public  _GetCodePage

        push    bp
        mov     bp,sp
        Call    _SaveRegs
        push    ds

        push    VDHGSEG
        pop     ds
        sub     bx,bx

        mov     ds:NumFonts,bx                    ;Init number of fonts read to zero
        mov     ds:TotalSize,bx                   ;Init size of fonts read to zero

        push    ds
        push    offset CDIBname                   ;Ptr to CDIB name
        push    ds
        push    offset CDIBsel                    ;Ptr to CDIB selector
        Call    DOSGETSHRSEG                      ;Get the CDIB selector

        .if     <zero ax> near
            mov     es,ds:CDIBsel
            mov     di,es:[bx].CDIB_codepage_ptr ;ES:DI = CodePage Info
            mov     cx,es:[di].CDIB_cp_number_codepages

            mov     ax,ERROR_VIO_BAD_CP
            mov     si,[bp+6]                     ;Get requested CP Id index
            .if     <si b cx> near                ;Requested CP not available

                imul    si,size CDIB_cp_id_section
                add     si,di
                mov     si,es:[si].CDIB_cp_first_id ;Get selected CP Id
                mov     ds:CPID,si               ;Save in global data

                mov     di,es:[bx].CDIB_screen_ptr ;Get offset of screen
                .if     <nonzero di>             ;Screen substructure found
                    mov     di,es:[di].CDIB_dev_filename_ptr ;Offset of file name
                .endif

                .if     <nonzero di>             ;Filename specified
                    push    es
                    push    di                   ;Device name ASCIIZ string
                    push    ds
                    push    offset Handle ;Return for device handle
                    push    ds
                    push    offset Scratch ;Action Taken
                    push    bx
                    push    bx            ;File Size
                    push    bx            ;File Attribute
                    push    00001h        ;Open Flag = Fail if missing
                    push    00020h        ;Open Mode = Read Only/Deny Write
                    push    bx
                    push    bx            ;Reserved (0:0)
                    Call    DOSOPEN       ;Open the CodePage file

                    .if     <zero ax>
                        sub              dx,dx
                        sub              si,si ;Point to file header

                        push             ds
                        pop              es
                        mov              di,offset ds:Buffer ;ES:DI = Buffer ptr
                        mov              cx,size fontfilehdr
                        Call             RandomRead ;Read the font file header

                        .if              <zero ax>
                            mov     cx,word ptr ds:Buffer+ffh_numfonts ;Number
                            mov     si,word ptr ds:Buffer+ffh_ptroffset ;Offset

                            .repeat
                                 push cx ;Number of fonts left in file
                                 sub dx,dx
                                 push si ;Fonthdr ptr

                                 push ds
                                 pop es
                                 mov di,offset ds:Buffer
                                 mov cx,4
                                 Call RandomRead ;Read the fonthdr ptr
                                 .if <zero ax>

                                     mov     si,word ptr ds:Buffer
                                     mov     dx,word ptr ds:Buffer+2 ;Get fonthdr ptr
                                     mov     cx,size fonthdr
                                     Call    RandomRead ;Read the fonthdr
                                     .if     <zero ax>

                                  mov ax,ds:CPID
                                  .if <ax eq <word ptr ds:Buffer+fh_cpid>>
                                      Call    ReadFont
                                  .endif

                                     .endif
                                 .endif

                                 pop si
                                 add si,4 ;Next ptr to font ptr
                                 pop cx
                            .loop                ;Until all fonts examined

                        .endif
                        push                     ds:Handle
                        Call                     DOSCLOSE ;Close the Font File
                    .endif
                .endif

                mov     ax,ERROR_VIO_BAD_CP ;Preset error code
                .if     <ds:NumFonts ne bx> ;Some fonts were loaded
                    les     di,dword ptr [bp+8]
                    mov     ax,ds:CPID
                    stosw                         ;Return CodePage Id

                    sub     ax,ax                 ;Set good return code
                .endif
            .endif

            push    ax
            push    ds:CDIBsel
            Call    DOSFREESEG                    ;Relinquish use of the CDIB
            pop     ax
        .endif

        pop     ds
        Call    _RestoreRegs
        pop     bp
        RET
_GetCodePage ENDP

;/****************************************************************************
;*
;* FUNCTION NAME = ReadFont
;*
;* DESCRIPTION   = 
;*
;* INPUT         = 
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;* PSEUDOCODE
;*
;*     Bgnsub ReadFont
;*       Call DOSREALLOCSEG to expand BVSCPnn to hold the this font
;*       Call RandomRead to read the entire font into BVSCPnn
;*     Endsub
;*
;****************************************************************************/

ReadFont PROC   NEAR
        public  ReadFont

        les     di,[bp+12]                        ;Ptr to Font Buffer
        add     di,ds:TotalSize                   ;Get the new segment address
        mov     cx,word ptr ds:Buffer+fh_datalen  ;Get font length
        sub     dx,dx
        add     si,word ptr ds:Buffer+fh_dataoffset
        adc     dx,bx                             ;32-bit Offset of font in file
        Call    RandomRead                        ;Read the font data

        .if     <zero ax>
            mov     si,ds:NumFonts
            add     si,si
            add     si,offset FontSizes
            mov     ax,word ptr ds:Buffer+fh_cellcols
            mov     [si],ax                       ;Save size of this font

            sub     al,al                         ;;;
            mov     cx,ax                         ;Force maximum font size ;;;

            inc     ds:NumFonts                   ;Update count of fonts
            add     ds:TotalSize,cx               ;Set next font offset
        .endif

        RET
ReadFont ENDP

;/****************************************************************************
;*
;* FUNCTION NAME = RandomRead:
;*
;* DESCRIPTION   = 
;*
;* INPUT         = DX:SI = New file offset
;*                 ES:DI = Ptr to buffer
;*                 CX    = Length of buffer
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;* PSEUDOCODE
;*
;*     Bgnsub RandomRead
;*       Call DOSCHGFILEPTR to prepare for the random read
;*       Call DOSREAD to read the data
;*     Endsub
;*
;****************************************************************************/

RandomRead PROC NEAR
        public  RandomRead

        push    ds:Handle                         ;File handle
        push    dx
        push    si                                ;Distance
        push    bx                                ;Type = Abs from Start
        push    ds
        push    offset Scratch                    ;New ptr return area
        Call    DOSCHGFILEPTR                     ;Set new file read location

        push    ds:Handle                         ;File handle
        push    es
        push    di                                ;Buffer ptr
        push    cx                                ;Read Length
        push    ds
        push    offset Scratch                    ;Return Length
        Call    DOSREAD                           ;Read from current location

        ret
RandomRead ENDP

R2CSEG  ENDS
        END
