;*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 = ESCAPE.ASM
;*
;* DESCRIPTIVE NAME = This file contains the (dev)escape function.
;*
;*
;* VERSION      V2.0
;*
;* DATE         8/4/92
;*
;* FUNCTIONS    
;*              
;*
;* 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/09/89                     Wes Rupel [wesleyr] - Wrote it
;*
;*****************************************************************************/

        .286p
        .xlist
        include cmacros.inc
INCL_GRE_DEVICE         equ     1
INCL_DEV                equ     1
INCL_DDICOMFLAGS        equ     1
        include pmgre.inc
        include driver.inc
        include njmp.mac
        .list

        errcode <INV_LENGTH_OR_COUNT>

        externA COUNT_DEV_CAPS_DATA     ;# of elements in adDevCapsData
        externA cDevVioCells


sBegin  Data
        externD adDevVioCells           ; Vio Cell Sizes table
sEnd    Data


sBegin  BlueMoon
assumes cs,BlueMoon

        externW BlueMoonData

CPUMode 386


;/***************************************************************************
;*
;* FUNCTION NAME = Escape 
;*
;* DESCRIPTION   = The only escape function supported by the driver is the 
;*                 QueryEscapeSupport function.                            
;*
;*                 Registers Preserved:       
;*                       SI,DI,BP,DS          
;*                 Registers Destroyed:       
;*                       AX,BX,CX,DX,ES,FLAGS 
;*
;* INPUT         = None
;* OUTPUT        = None
;*
;* RETURN-NORMAL = DX:AX = DEVESC_NOTIMPLEMENTED if not supported 
;*                 DX:AX = 1 if supported
;* RETURN-ERROR  = DX:AX = DEVESC_ERROR                           
;*                 Error logged                                   
;**************************************************************************/

        check   Escape,<hdc,lCmd,cbIn,pbIn,pcbOut,pbOut,hddc,ulFunN>

        assumes ds,nothing
        assumes es,nothing

cProc   Escape,<PUBLIC,FAR,NODATA,NONWIN>,<ds,di,si>

        parmD   hdc
        parmD   iEscape
        parmD   cbIn
        parmD   lpInData
        parmD   pcbOut
        parmD   lpOutData
        parmD   hddc
        parmD   FunN

cBegin

        mov     ds,BlueMoonData
        assumes ds,Data

; See if it is one of the few escapes the driver supports

        xor     ax,ax                   ; AX = 0 : used below
        errnz   DEVESC_NOTIMPLEMENTED
        cmp     iEscape.hi,ax
        jne     esc_exit

        mov     dx,iEscape.lo           ; DX = escape

        cmp     dx,DEVESC_QUERYVIOCELLSIZES
        je      esc_viocellsizes
        cmp     dx,DEVESC_QUERYESCSUPPORT
        jne     esc_exit

;/*
;**  QueryEscSupport
;*/

        cmp     cbIn.hi,ax
        jne     esc_log_error
        cmp     cbIn.lo,SIZE_DWORD
        jb      esc_log_error
        errnz   DEVESC_NOTIMPLEMENTED

        les     bx,lpInData             ; ES:BX = lpInData
        assumes es,nothing
        cmp     es:[bx].hi,DEVESC_QUERYESCSUPPORT
        jne     esc_support_exit
        mov     dx,es:[bx].lo           ; DX = escape

        cmp     dx,DEVESC_QUERYVIOCELLSIZES
        je      @F
        cmp     dx,DEVESC_QUERYESCSUPPORT
        jne     esc_support_exit
@@:
        inc     ax                      ;Show supported
esc_support_exit:
        jmp     esc_exit

;/*
;**  QueryVioCellSizes
;** 
;**  Process QueryVioCellSizes
;**    Return following structure in OutData -
;**      struct {
;**        LONG maxcount
;**        LONG count
;**       }
;**    followed by count copies of
;**      struct VIOFONTCELLSIZE {
;**        LONG xwidth
;**        LONG ywidth
;**       }
;** 
;**    - if outcount < Size_Dword, return no data
;**    - if outcount = Size_Dword, set maxcount to number of cell
;**      sizes supported
;**    - if outcount > Size_Dword, set maxcount as above, count to
;**      the number of cell sizes actually returned, and count copies
;**      of VIOFONTCELLSIZE
;*/

esc_viocellsizes:

;/*
;*/

        les     bx, pcbOut
        mov     eax,es:[bx]             ; EAX = received outcount

        cmp     eax, 4
        jge     esc_cnt_required

        ;/*
        ;**  pcbOut is less than size (LONG), just update this to zero
        ;*/
        xor     eax, eax
        mov     es:[bx], eax            ; return zero in pcbOut
        inc     eax                     ; return one in AX
        jmp     esc_exit

esc_cnt_required:
        cmp     eax, 8
        jge     esc_data_required

        ;/*
        ;** Just room for the count of cells, so output length is four
        ;*/ 
        mov     dword ptr es:[bx], 4    ; return four in pcbOut
        les     di,lpOutData
        mov     dword ptr es:[di],cDevVioCells
        mov     eax, 1                  ; return one in AX
        jmp     esc_exit

esc_data_required:

        ;/*
        ;**  pcBout is greater than size (LONG), so return full information
        ;**  but only as much as there is room in the output buffer
        ;** 
        ;**  Output buffer can take (cbOut - 8)/8 structures
        ;*/
        shr     eax, 3
        dec     eax                     ; EAX is room in buffer for structures
        mov     ecx, cDevVioCells       ; ECX is maximum cell structures
        cmp     eax, ecx                ; make EAX the smallest of these
        jle     esc_do_copy
        mov     eax, ecx                ; less data than cell structures

esc_do_copy:
 
        ;/*
        ;**  Write outcount back in bytes
        ;*/
        mov     ecx, eax                ; save number of cell structures
        inc     eax
        shl     eax, 3
        mov     es:[bx], eax

        ;/* 
        ;**    Write the header data into the output buffer
        ;*/ 
        les     di,lpOutData            ; address output buffer
        mov     eax,cDevVioCells        ; store count of sizes available
        stosd
        mov     eax,ecx                 ; store count of sizes returned
        stosd

        mov     si,offset adDevVioCells ; start size copying loop
        jcxz    esc_q_done              ; stop if none to do
        xor     ax, ax                  ; zero so that STOSW works

esc_next_size:
        movsw                           ; copy the width
        stosw
        movsw                           ; copy the height
        stosw
        add     si,4                    ; move to next record (skip font ptr)
        loop    esc_next_size

esc_q_done:
        mov     eax, 1                  ; return one in AX
        jmp     esc_exit

esc_log_error:
        mov     ax,PMERR_INV_LENGTH_OR_COUNT
        save_error_code
        mov     ax,DEVESC_ERROR

esc_exit:
        cwd

cEnd
sEnd    BlueMoon
end
