/*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.                                */
/*                                                                           */
/*****************************************************************************/
/**********************************************************************/
/*                                                                    */
/*   Module          = EDDVSETF                                       */
/*                                                                    */
/*   Description     = Display Device Driver Function:                */
/*                     DeviceSetAVIOFont                              */
/*                                                                    */
/*   Function        = This puts the address of a loadable AVIO font  */
/*                     in the DC instance data                        */
/*                                                                    */
/*   Reference       = Winthorn Functional Specification              */
/*                     Device Driver Interface Specification          */
/*                     Display Device Driver Design Specification     */
/*                                                                    */
/*                                                                    */
/**********************************************************************/
#define INCL_DDIFONTSTRUCS
#define INCL_DDIMISC
#define INCL_GRE_FONTS
#define INCL_NOSHIELDPROCS
#define INCL_GRE_DCS        /* to call GreGetHandle */      
#define INCL_PMERRORS                                       
#include <eddinclt.h>

#include <eddacone.h>
#include <eddvcone.h>

#include <edddtypt.h>
#include <eddtcone.h>
#include <eddhcone.h>
#include <eddhtype.h>

#include <eddgextf.h>
#include <eddvextf.h>
#include <eddtextf.h>

#ifdef DBCS                                                 
#include <eddjdef.h>
#include <eddjfm.h>
#include <eddjcp.h>
#include <eddjfont.h>
#include <eddvjtyp.h>
#endif                                                      

extern PFONTCACHEINFO      pFontCacheInfo;
#ifdef DBCS                                                 
extern USHORT           usDefaultCodePage;
extern ULONG pascal GetPSAddress(ULONG hVio);
extern PVOID pascal Dos32SelToFlat(ULONG f16pSel);
extern ULONG pascal Dos32FlatToSel(PVOID p);
ULONG  APIENTRY InnerGre32Entry4(HDC,ULONG,ULONG,ULONG);
#endif                                                      

#ifdef TMP                                                  
// Temporary fix for JD20-JS06374. Aviod infinite loop.
// This code should be removed when the defect 80597 is integrated.
#ifdef _8514
#include <8514.h>
#include <cacheman.h>
extern PHWMAP       pHWMap;
#endif
#endif 

/**********************************************************************/
/*                                                                    */
/* DeviceSetAVIOFont is passed a font that is associated with         */
/* one of the AVIO logical fonts 1..3. These character sets are then  */
/* used to draw buffer cells whose definition is four bytes long and  */
/* whose font id is 1, 2 or 3.                                        */
/*                                                                    */
/* The function checks that the supplied character set is fixed       */
/* pitch, single plane, and that its size matches the base AVIO font  */
/* cell size.                                                         */
/*                                                                    */
/* NOTE when the base font changes size (but not when it changes      */
/* codepage) all the loadable fonts are cleared.                      */
/*                                                                    */
/**********************************************************************/

DDIENTRY eddv_DeviceSetAVIOFont2 (HDC           hdc,
                                  PFATTRS       pFattrs,
                                  PFOCAFONT     FontDef,
                                  LONG          LCIDindex,
                                  PDC           pdcArg,
                                  ULONG         FunN)

{
    /******************************************************************/
    /* Local variables                                                */
    /******************************************************************/
    LONG               AvioLCID;     /* Converted AVIO LCID (1..3)    */
    USHORT             usCodePage;
#ifndef DBCS                                                
    PUSHORT            pCodePageVector;
#else                                                       
    ULONG              hVio;
    PVIOPSNLSEXT       templpNLSExt;
    PBYTE           pDBCSEv;
    USHORT          i;
#ifdef JFIX_AVIOSETF                                        
    PJFIXVIOPS         VioPS;
    ULONG              f16pFontDef;
#else
    PVIOPS             VioPS;
#endif 
#endif 

    /******************************************************************/
    /* Prevent compiler warnings.                                     */
    /******************************************************************/
    IgnoreParam(hdc);

    /******************************************************************/
    /* Get driver semaphore and perform entry checks                  */
    /******************************************************************/
    EnterDriver(pdcArg, FunN, EDF_STANDARD | EDF_DONT_CLEAN);

    /******************************************************************/
    /* Apply the DC command mask to the command bits                  */
    /******************************************************************/
    COMMANDBITS(FunN) &= pdc->DCICommandMask;

    /******************************************************************/
    /* Return an error if this is not a Direct DC                     */
    /******************************************************************/
    if ( pdc->DCIDCType == OD_INFO )
    {
        /**************************************************************/
        /* Just return OK                                             */
        /**************************************************************/
        goto SETAVIOFONT_OK_EXIT;
    }
    else if (pdc->DCIDCType != OD_DIRECT)
    {
        LogError(PMERR_INCORRECT_DC_TYPE);
        goto SETAVIOFONT_ERR_EXIT;
    }

#ifdef DBCS                                                 
    /******************************************************************/
    /* Now we call GreGetHandle by InnerGre32Entry4 to get hVio.       /
    /******************************************************************/
    if (!(hVio = (ULONG)InnerGre32Entry4(hdc,
                                         AVIO_PS_HANDLE_INDEX,
                                         0L,
                                         NGreGetHandle)))
    {
        LogError(PMERR_INV_HDC);
        goto SETAVIOFONT_ERR_EXIT;
    }

    /******************************************************************/
    /* Now we call GetPSAddress to get pointer to VioPresentationSpace./
    /******************************************************************/
#ifdef JFIX_AVIOSETF                                        
    if (!(VioPS = (PJFIXVIOPS)GetPSAddress(hVio)))
#else                                                       
    if (!(VioPS = (PVIOPS)GetPSAddress(hVio)))
#endif 
    {
        LogError(PMERR_INV_HDC);
        goto SETAVIOFONT_ERR_EXIT;
    }
#endif 

    /******************************************************************/
    /* The AVIO LCID index that we are passed is LCID_AVIO_1/2/3 -    */
    /* which are -2, -3, -4. Make sure the lcid is in range.          */
    /******************************************************************/
    AvioLCID = -(SHORT)(LCIDindex + 1) ;
    if ( (AvioLCID < 1) || (AvioLCID > CNT_LOADABLE_LCIDS) )
    {
        /**************************************************************/
        /* The AVIO LCID is invalid. Return an error.                 */
        /**************************************************************/
        LogError(PMERR_INV_SETID);
        goto SETAVIOFONT_ERR_EXIT;
    }

    /******************************************************************/
    /* If the FontDef parameter is null then we just have to clear    */
    /* out the specified AVIO LCID.                                   */
    /******************************************************************/
    if (FontDef == FNULL)
    {
        /**************************************************************/
        /* AH-HA! we need to free the cached font if it exists...     */
        /**************************************************************/
        if (pdc->DCIAvioFonts[AvioLCID].pFocaFont)
        {
            eddt_FreeCachedFont(
                     pdc->DCIAvioFonts[AvioLCID].usFontID,
                     pdc->DCIAvioFonts[AvioLCID].usCachedFontIndex );
        }

#ifdef DBCS                                                 
        /************************************************************/
        /* We have to clear pMapFontsLoaded, pFontsLoaded           */
        /* fields in VioPresentationSpace, which all                */
        /* correspond to AvioLCID.  (DCR 150 for JP20)              */
        /************************************************************/
#ifdef JFIX_AVIOSETF                                        
        VioPS->selFontsLoaded[AvioLCID-1]  = (SEL)NULL;
#else                                                       
        VioPS->pMapFontsLoaded[AvioLCID-1] = FNULL;
        VioPS->pFontsLoaded[AvioLCID-1]    = FNULL;
#endif 
#endif 

        /**************************************************************/
        /* Clear out this AVIO LCID and leave.                        */
        /**************************************************************/
        pdc->DCIAvioFonts[AvioLCID].pFocaFont = FNULL;

#ifndef DBCS                                                
        /**************************************************************/
        /* We no longer use pfciTable.                                */
        /**************************************************************/
        pdc->DCIAvioInfo.pfciTable[AvioLCID] = FNULL;
#endif 
        goto SETAVIOFONT_OK_EXIT;
    }


    /******************************************************************/
    /* Check that the font is fixed pitch, single plane, and that its */
    /* size matches one of the supported AVIO sizes.                  */
    /******************************************************************/
    if (FontDef->fdDefinitions.fsFontdef != FONTDEFFONT1)
    {
        /**************************************************************/
        /* The font is proportionally-spaced or multiplane, so we     */
        /* cannot use it. Return an error.                            */
        /**************************************************************/
        LogError(PMERR_INV_FONT_ATTRS);
        goto SETAVIOFONT_ERR_EXIT;
    }
#ifndef TMP                                                 
    /******************************************************************/
    /* Size must be same as base font!                                */
    /******************************************************************/
    if ( (pdc->DCIAvioFonts[0].pFocaFont->fdDefinitions.yCellHeight !=
                                 FontDef->fdDefinitions.yCellHeight) ||
         (pdc->DCIAvioFonts[0].pFocaFont->fdDefinitions.xCellWidth !=
                                 FontDef->fdDefinitions.xCellWidth )   )
    {
        /**************************************************************/
        /* No match was found, so return an error.                    */
        /**************************************************************/
        LogError(PMERR_INV_FONT_ATTRS);
        goto SETAVIOFONT_ERR_EXIT;
    }
#endif 

#ifdef TMP                                                  
  #ifdef _8514
    // Temporary fix for JD20-JS06374. Aviod infinite loop.
    // This code should be removed when the defect 80597 is integrated.

    if (pHWMap->num_font_planes < 4)
    {
        LogError (PMERR_INV_SETID);
        goto SETAVIOFONT_ERR_EXIT;
    }
  #endif // _8514
#endif 

    /******************************************************************/
    /* Font is OK and we're going ahead, so lets free up any old      */
    /* cached font for this lcid.                                     */
    /******************************************************************/
    if (pdc->DCIAvioFonts[AvioLCID].pFocaFont)
    {
        eddt_FreeCachedFont(
                     pdc->DCIAvioFonts[AvioLCID].usFontID,
                     pdc->DCIAvioFonts[AvioLCID].usCachedFontIndex );
        /**************************************************************/
        /* in case somthing goes wrong, clear the lcid                */
        /**************************************************************/
        pdc->DCIAvioFonts[AvioLCID].pFocaFont = FNULL;
#ifndef DBCS                                                
        /**************************************************************/
        /* We no longer use pfciTable.                                */
        /**************************************************************/
        pdc->DCIAvioInfo.pfciTable[AvioLCID]  = FNULL;
#endif 
    }

    /******************************************************************/
    /* Now get the codepage, using the fattrs value if it is passed   */
    /* in.                                                            */
    /******************************************************************/
    usCodePage = FontDef->fmMetrics.usCodePage;
#ifdef DBCS                                                             /*KASA*/
    /******************************************************************//*KASA*/
    /* We construct codepage mapping vector here by using DBCS        *//*KASA*/
    /* unique routine which checks codepage and constructs            *//*KASA*/
    /* codepage mapping vector.  As an argument for the routine,      *//*KASA*/
    /* use logical font codepage if it's available.                   *//*KASA*/
    /* i.e If codepage in Fattrs is defined and codepage in font      *//*KASA*/
    /* metrics is 850, use codepage in Fattrs. Otherwise use codepage *//*KASA*/
    /* in font metrics.                                               *//*KASA*/
    /******************************************************************//*KASA*/
    if ( pFattrs && (usCodePage == 850))                                /*KASA*/
    {                                                                   /*KASA*/
       usCodePage = pFattrs->usCodePage;                                /*KASA*/
    }                                                                   /*KASA*/
    /******************************************************************//*KASA*/
    /* Now call the routine.                                          *//*KASA*/
    /******************************************************************//*KASA*/
    if(!eddj_QueryCPVectors((ULONG)usCodePage,                          /*KASA*/
                          &pdc->DCIAvioFonts[AvioLCID].pCodePageVector, /*KASA*/
                          &pdc->DCIAvioFonts[AvioLCID].pDBCSMap,        /*KASA*/
                          &pdc->DCIAvioFonts[AvioLCID].NLSParseFlag))   /*KASA*/
    {                                                                   /*KASA*/
       usCodePage = usDefaultCodePage;                                  /*KASA*/
       eddj_QueryCPVectors((ULONG)usCodePage,                           /*KASA*/
                          &pdc->DCIAvioFonts[AvioLCID].pCodePageVector, /*KASA*/
                          &pdc->DCIAvioFonts[AvioLCID].pDBCSMap,        /*KASA*/
                          &pdc->DCIAvioFonts[AvioLCID].NLSParseFlag);   /*KASA*/
    }                                                                   /*KASA*/
    if(!(pdc->DCIAvioFonts[AvioLCID].NLSParseFlag & NLSCA_MAP_SBCS))    /*KASA*/
    {                                                                   /*KASA*/
        pdc->DCIAvioFonts[AvioLCID].pCodePageVector = FNULL;            /*KASA*/
    }                                                                   /*KASA*/
    if(!(pdc->DCIAvioFonts[AvioLCID].NLSParseFlag & NLSCA_MAP_DBCS))    /*KASA*/
    {                                                                   /*KASA*/
        pdc->DCIAvioFonts[AvioLCID].pDBCSMap = FNULL;                   /*KASA*/
    }                                                                   /*KASA*/
                                                                        /*KASA*/
    /******************************************************************//*KASA*/
    /* We succeeded to validate CodePage and get CodePage Mapping     *//*KASA*/
    /* Vector. Now we set the offset of pointer to CodePage Mapping   *//*KASA*/
    /* Vector and pointer to FontDef in the VioPresentationSpace      *//*KASA*/
    /* structure for OS/2 J.                                          *//*KASA*/
    /******************************************************************//*KASA*/
#ifdef JFIX_AVIOSETF                                                    /*KASA*/
    f16pFontDef = Dos32FlatToSel((PVOID)FontDef);                       /*KASA*/
    VioPS->selFontsLoaded[AvioLCID-1] = (SEL)(f16pFontDef >> 16);       /*KASA*/
#else                                                                   /*KASA*/
    VioPS->pMapFontsLoaded[AvioLCID-1]                                  /*KASA*/
                         = pdc->DCIAvioFonts[AvioLCID].pCodePageVector; /*KASA*/
    VioPS->pFontsLoaded[AvioLCID-1]                                     /*KASA*/
                         = (PVOID)FontDef;                              /*KASA*/
#endif /* end JFIX_AVIOSETF */                                          /*KASA*/
                                                                        /*KASA*/
    /******************************************************************//*KASA*/
    /* We also store font information in DCI for our own code.        *//*KASA*/
    /******************************************************************//*KASA*/
    pdc->DCIAvioFonts[AvioLCID].pFocaFont = FontDef;                    /*KASA*/
/*  pdc->DCIAvioFonts[AvioLCID].usFontType = FT_FOCAFONT; */            /*KASA*/
                                             /* This line is deleted */ /*KASA*/
                                             /* from PHASE3B.        */ /*KASA*/
                                                                        /*KASA*/
    pdc->DCIAvioFonts[AvioLCID].usCodePage = usCodePage;                /*KASA*/
                                                                        /*KASA*/
    /******************************************************************//*KASA*/
    /* For NLSFontFlag and FMCacheSize, we also get them and store    *//*KASA*/
    /* them inDCI.                                                    *//*KASA*/
    /******************************************************************//*KASA*/
    eddj_QueryFontProfile(FontDef,                                      /*KASA*/
                          &pdc->DCIAvioFonts[AvioLCID].NLSFontFlag,     /*KASA*/
                          &pdc->DCIAvioFonts[AvioLCID].FMCacheSize);    /*KASA*/
#else                                                                   /*KASA*/
    if ( pFattrs )
    {
        /**************************************************************/
        /* If Fattrs codepage is zero, use the DC current codepage.   */
        /**************************************************************/
        if ( !(usCodePage = pFattrs->usCodePage) )
        {
            usCodePage = (USHORT)pdc->DCICodePage;
        }
    }

    /******************************************************************/
    /* Get the codepage vector from the engine                        */
    /******************************************************************/
    pCodePageVector = NULL;
    if (usCodePage)
    {
        pCodePageVector = (PUSHORT)GreQueryCodePageVector(usCodePage);
    }

    pdc->DCIAvioFonts[AvioLCID].pFocaFont = FontDef;
    pdc->DCIAvioFonts[AvioLCID].usCodePage = usCodePage;
    pdc->DCIAvioFonts[AvioLCID].pCodePageVector = pCodePageVector;
#endif 

#ifdef DBCS                                                             /*KASA*/
    /******************************************************************//*KASA*/
    /* BVHWNDW needs to know DBCS Environment Vector to support       *//*KASA*/
    /* multiple DBCS cell formats correctly. It gets access to the    *//*KASA*/
    /* vector by using pointer to NLSExtendedControlBlock in          *//*KASA*/
    /* VioPresentationSpace structure. So we put DBCS Environment     *//*KASA*/
    /* Vector , codepage, and country code into the block at an       *//*KASA*/
    /* appropriate position for the AvioLCID font.                    *//*KASA*/
    /*                                            (DCR 150 for JP20)  *//*KASA*/
    /******************************************************************//*KASA*/
                                                                        /*KASA*/
    /******************************************************************//*KASA*/
    /* If we can't get lpNLSExt, or system doesn't have DBCS          *//*KASA*/
    /* capability, we'll do nothing.                                  *//*KASA*/
    /******************************************************************//*KASA*/
    if ((VioPS->lpNLSExt != FNULL)      &&                              /*KASA*/
        CHECKENV(ENV_DBCS_CAPABLE))                                     /*KASA*/
    {                                                                   /*KASA*/
#ifdef JFIX_AVIOSETF                                                    /*KASA*/
       templpNLSExt = Dos32SelToFlat((ULONG)(VioPS->lpNLSExt));         /*KASA*/
#else                                                                   /*KASA*/
       templpNLSExt = VioPS->lpNLSExt;                                  /*KASA*/
#endif /* end JFIX_AVIOSETF */                                          /*KASA*/
                                                                        /*KASA*/
       /***************************************************************//*KASA*/
       /* For country code, use default font's (LCID 0) country       *//*KASA*/
       /* code.                                                       *//*KASA*/
       /***************************************************************//*KASA*/
       templpNLSExt->DBCSEvInfo[AvioLCID].cc                            /*KASA*/
                     = templpNLSExt->DBCSEvInfo[0].cc;                  /*KASA*/
                                                                        /*KASA*/
       /***************************************************************//*KASA*/
       /* For codepage, we use codepage validated at last time.       *//*KASA*/
       /***************************************************************//*KASA*/
       templpNLSExt->DBCSEvInfo[AvioLCID].cp = usCodePage;              /*KASA*/
                                                                        /*KASA*/
       /***************************************************************//*KASA*/
       /* We set the DBCS Environment Vector in                       *//*KASA*/
       /* NLSExtendedControlBlock.                                    *//*KASA*/
       /***************************************************************//*KASA*/
       if((pdc->DCIAvioFonts[AvioLCID].NLSParseFlag & NLSCA_MAP_DBCS))  /*KASA*/
       {                                                                /*KASA*/
         pDBCSEv = pdc->DCIAvioFonts[AvioLCID].pDBCSMap + 256;          /*KASA*/
         for (i=0; i <= DBCSEvBufSiz; i++)                              /*KASA*/
         {                                                              /*KASA*/
             templpNLSExt->DBCSEvInfo[AvioLCID].DBCSVector[i]           /*KASA*/
                                                       = (* pDBCSEv);   /*KASA*/
             pDBCSEv++;                                                 /*KASA*/
         } /* endfor */                                                 /*KASA*/
       } /* endif */                                                    /*KASA*/
    } /* endif */                                                       /*KASA*/
#endif /* end DBCS */                                                   /*KASA*/

    /******************************************************************/
    /* Now ensure this is cacheable. This sets the FontId and         */
    /* FontCacheIndex fields.                                         */
    /******************************************************************/
    eddt_LocateCachedFont( &(pdc->DCIAvioFonts[AvioLCID]) );

#ifndef DBCS                                                            /*KASA*/
    /******************************************************************//*KASA*/
    /* We no longer use pfciTable.                                    *//*KASA*/
    /******************************************************************//*KASA*/

    /******************************************************************/
    /* Setup pointer in AVIOParms for this font                       */
    /******************************************************************/
    pdc->DCIAvioInfo.pfciTable[AvioLCID] = &( pFontCacheInfo[
                   pdc->DCIAvioFonts[AvioLCID].usCachedFontIndex ] );
#endif /* end DBCS */                                                   /*KASA*/

SETAVIOFONT_OK_EXIT:
    /******************************************************************/
    /* Release driver semaphore                                       */
    /******************************************************************/
    ExitDriver(pdcArg, FunN, EDF_STANDARD | EDF_DONT_CLEAN);
    return(OK);

SETAVIOFONT_ERR_EXIT:
    /******************************************************************/
    /* Release driver semaphore                                       */
    /******************************************************************/
    ExitDriver(pdcArg, FunN, EDF_STANDARD | EDF_DONT_CLEAN);
    return(ERROR_ZERO);
}
