/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT (C) Lexmark 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.                                */
/*                                                                           */
/*****************************************************************************/
/**************************************************************************
 *
 * SOURCE FILE NAME = PRDEEDC
 *
 * DESCRIPTIVE NAME =
 *
 *
 * VERSION
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS    prde_EnableDC
 *              prde_GetVarSizeMemory
 *              prde_GetAttrsMemory
 *              prdn_SetEnableDCIDefaults
 *              prdn_SetCompleteOpenDCIDefaults
 *              prdn_SetStartDocDCIDefaults
 *              prdn_SetResetDCDCIDefaults
 *              prdn_SetDCIFlags
 *              prdn_SetDCIAttributes
 *              prde_QueryProcessCP
 *
 * ENTRY POINTS:
 *
 * DEPENDENCIES:
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/

#define INCL_32                   /* CON3201 */
#define INCL_DOSNLS               /* CON3201 */
#define INCL_DOSSEMAPHORES
#define INCL_DOSPROCESS
#define INCL_GREALL
#define INCL_GPIPRIMITIVES
#define INCL_WINHEAP
#define INCL_GPIBITMAPS
#define INCL_GPILOGCOLORTABLE
#define INCL_GPIERRORS
#define INCL_WINPOINTERS
#include <os2.h>
#undef INCL_DOSNLS                /* CON3201 */
#undef INCL_DOSSEMAPHORES
#undef INCL_DOSPROCESS
#undef INCL_GREALL
#undef INCL_GPIPRIMITIVES
#undef INCL_WINHEAP
#undef INCL_GPIBITMAPS
#undef INCL_GPILOGCOLORTABLE
#undef INCL_GPIERRORS
#undef INCL_WINPOINTERS

#define INCL_DDIBUNDLES
#define INCL_DDIFONTSTRUCS
#define INCL_DDIDEFS
#define INCL_DDIMISC
#define INCL_DDICOMFLAGS
#define INCL_GRE_DEVSUPPORT
#include <pmddi.h>
#undef INCL_DDIBUNDLES
#undef INCL_DDIFONTSTRUCS
#undef INCL_DDIDEFS
#undef INCL_DDIMISC
#undef INCL_DDICOMFLAGS
#undef INCL_GRE_DEVSUPPORT

#define INCL_WINP_SELECTIVE
#define INCL_WINP_SEI
#define INCL_WINP_MISC
#include <pmwinx.h>
#undef INCL_WINP_SELECTIVE
#undef INCL_WINP_SEI
#undef INCL_WINP_MISC
#undef INCL_32                    /* CON3201 */

#include <prdconse.h>
#include <prdccone.h>
#include <prddcone.h>
#include <prdecone.h>
#include <prdtcone.h>

#define ENCON_INCL
#define FOCON_INCL
#define COCON_INCL
#define MOCON_INCL
#define PRDMTYPE_INCL
#define PRDFTYPE_INCL
#define NO_CONSTANT_INCL
#include <prdinclt.h>
#undef NO_CONSTANT_INCL
#undef ENCON_INCL
#undef FOCON_INCL
#undef COCON_INCL
#undef MOCON_INCL
#undef PRDMTYPE_INCL
#undef PRDFTYPE_INCL

#include <prdeextf.h>
#include <prdaextf.h>
#include <prdcextf.h>
#include <prdiextf.h>
#include <prdgextf.h>
#include <prdyextf.h>
#include <prdtextf.h>
#include <prdnextf.h>
#include <prduextf.h>
#include <prdfextf.h>
#include <prdncone.h>
#include <prdicone.h>
#include <prdacone.h>

/******************************************************************************/
/*  Set up external accesses.                                                 */
/******************************************************************************/
extern DefaultColorTableType     DefaultColorTable;
extern lplpFontCPListType        DVTFontCPList[];
extern CHAR                      szDefaultString[];

/******************************************************************************/
/*  FUNCTION: prde_EnableDC                                                   */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  EDCParamsLst far *param1; Pointer to list of parameters for this function */
/*  ULONG             param2; Unused parameter                                */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This function creates a heap for a DC, allocates space in it for the DC   */
/*  Instance table and sets up fields in the DC Instance data to the          */
/*  appropriate defaults.                                                     */
/*                                                                            */
/*  CHANGES:                                                                  */
/*                                                                            */
/*  If extra fields are required in the DC Instance data structure then they  */
/*  will have to be allowed for here.  If they are hung from the data DC      */
/*  Instance data memory will have to be allocated (possibly in               */
/*  GetAttrsMemory or GetVarSizeMemory) and the fields will have to be        */
/*  initialized to their default values (possibly in SetDCIDefaults).         */
/*                                                                            */
/*  NOTE:  Memory Allocation                                                  */
/*                                                                            */
/*  It is *important* to realize that there is about 2.5k's worth of memory   */
/*  that is allocated within this routine and the subsequently called routines*/
/*  that does not explicitly get freed anywhere in the code.  This is *not* a */
/*  problem in that the memory is being freed by prde_DisableDC() when the    */
/*  DisableDC is processed.  All remaining memory that is acquired during the */
/*  life of the DC is managed correctly and is being freed.  During the final */
/*  phases of the DisableDC code, all heap selectors for the DC *including*   */
/*  the present selector where the DCIData resides are freed.  This has taken */
/*  a good bit of debugging to reach this conclusion and therefore I'd like to*/
/*  save someone else the bother later.                                       */
/******************************************************************************/

/* CON3201 ***********************************/
/* ULONG pascal prde_EnableDC(param1, param2)*/
/*                                           */
/* EDCParamsLst far  *param1;                */
/* ULONG              param2;                */
/**********************************************/

ULONG prde_EnableDC(EDCParamsLst *param1, ULONG param2)
{
#define TFUNC "prde_EnableDC"

    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
/* CON3201 */
//    USHORT     DosResult;              /* dos call return code                */
//    SEL        GlobalSel;              /* global info seg selector            */
//    HHEAP      HeapHandle;             /* The handle and ...                  */
//    unsigned   HeapSelector;           /*  ... selector of the heap we create */

    lpDCI      DCIData;                /* The DCIData we are going to set up  */
    BYTE      *ItemOffset;             /* offset on heap of new item          */
    USHORT     i;

/* CON3201 *********************************************/
    PVOID     pvHeap;
    PVOID     pvItem;
    ULONG     DosResult;              /* dos call return code                */

    TRACE4(TFUNC, "Entry", FNULL, 0);
    TRACE4(TFUNC, "DcType", &(param1->DcType), 1);
    TRACE4(TFUNC, "DcH", &(param1->DcH), 1);

    /**************************************************************************/
    /*  Create a heap for this DC.                                            */
    /*************************************************************************/
    TRACE4(TFUNC, "Create DC Heap", FNULL, 0);

#ifdef DEBUG_FSM
    OutputPrompt("Enter EnableDC");
#endif
#ifdef PRD_TIMING
    DEKHOOK0(A,8,37)
#endif

  /* CON3201 *********************************************************/
  /*if (prdg_CreateHeap(&HeapHandle, (PUSHORT)&HeapSelector,         */
  /*                     NON_SHARED_HEAP) != OK)                     */
  /*******************************************************************/

    /* CON3201 prdg_CreateHeap now creates a private heap by default */
    if (prdg_CreateHeap(&pvHeap) != OK)
    {

        /**********************************************************************/
        /*  Error already logged by CreateHeap function so just exit          */
        /**********************************************************************/
        TRACE4(TFUNC, "create heap failed", FNULL, 0);
#ifdef PRD_TIMING
    DEKHOOK0(A,8,B7)
#endif
        return ((ULONG)ERROR_NEG);
    }
    /* CON3201 *********************************************/
    /*TRACE4(TFUNC, "DC Heap Handle", &HeapHandle, 1);     */
    /*TRACE4(TFUNC, "DC Heap Selector", &HeapSelector, 1); */
    /*******************************************************/

    TRACE4(TFUNC, "DC Heap ", &pvHeap, 1);

    /**************************************************************************/
    /*  Create the DC Instance Data from the created Heap.  Note we cannot use*/
    /*  prdg_allocheapitem for this since it takes the DC Instance data as a  */
    /*  parameter, and that's what we're trying to allocate.                  */
    /**************************************************************************/
    TRACE4(TFUNC, "Alloc DC Instance", FNULL, 0);
    DosResult = DosSubAllocMem(pvHeap, &pvItem, sizeof(DCIType));
    if (DosResult)
    {
       goto ErrorReturn;
    }

      DCIData = (lpDCI)pvItem; /* CON3201 */

  /* CON3201 ***********************************************/
  /*ItemOffset = WinAllocMem (HeapHandle, sizeof(DCIType));*/
  /*if (ItemOffset == NULL)                                */
  /*                                                       */
  /*{                                                      */
  /*    goto ErrorReturn;                                  */
  /*}                                                      */
  /*((PUSHORT) &DCIData)[1] = HeapSelector;                */
  /*((PUSHORT) &DCIData)[0] = (USHORT)ItemOffset;          */
  /*********************************************************/


    /**************************************************************************/
    /*  Having set up DC Heap, and obtained DC Instance Data, save the Heap   */
    /*  Handle and Selector in the Instance Data Heap List.                   */
    /**************************************************************************/
  /* CON3201 *****************************************/
  /*DCIData->DCIHeapList.HeapHandle = HeapHandle;    */
  /*DCIData->DCIHeapList.HeapSel    = HeapSelector;  */
  /*DCIData->DCIHeapList.Next       = FNULL;         */
  /***************************************************/

      DCIData->DCIHeapList.pbHLEHeap =  pvHeap;   /* CON3201 */
      DCIData->DCIHeapList.Next       = FNULL;          /* CON3201 */
    /**************************************************************************/
    /*  Also set the heap handle and selector of the current heap to be the   */
    /*  one we've just created.                                               */
    /**************************************************************************/
  /*** CON3201 ******************************/
  /*DCIData->DCICurrHHeap   = HeapHandle;   */
  /*DCIData->DCICurrHeapSel = HeapSelector; */
  /******************************************/

      DCIData->DCICurrHeap   = pvHeap;         /* CON3201 */

    /**************************************************************************/
    /*  Copy the DC handle into the DC instance                               */
    /**************************************************************************/
    DCIData->DcH = param1->DcH;

    /**************************************************************************/
    /*  Set the DC Type, pointer to next DC Instance Data, DC Instance self   */
    /*  reference (for integrity checks).  Save the supplied Engine handle to */
    /*  DC for subsequent call-backs to the Engine.                           */
    /**************************************************************************/
    DCIData->DCIDCType    = (USHORT)param1->DcType;
    DCIData->DCINextEntry = FNULL;
    DCIData->DCISelfRef   = DCIData;

    /**************************************************************************/
    /*  Link the PDB Instance Data into the DC Instance Data.                 */
    /**************************************************************************/
    DCIData->DCIPdbInstance = (lpPDBI)param1->PDBInstance;
    TRACE4(TFUNC, "addr PDB Instance", &(param1->PDBInstance), 1);
    TRACE4(TFUNC, "PDB Instance",param1->PDBInstance, sizeof(PDBIType)/4);

    /**************************************************************************/
    /*  Set count of saved DC states to zero                                  */
    /**************************************************************************/
    DCIData->DCISaveCount = 0;

    /**************************************************************************/
    /*  Get the Process ID                                                    */
    /**************************************************************************/
   /* CON3201 *************************************************************/
   /*if (DosResult = DosGetInfoSeg(&GlobalSel, &SELECTOROF(DCIData->LIS)))*/
   /*{                                                                    */
   /*  LOGDOSERR(TFUNC, "DosGetInfoSeg failed", FNULL, 0, DosResult);     */
   /*  goto ErrorReturn;                                                  */
   /*}                                                                    */
   /***********************************************************************/
    /* CON3201 ***************************************************************/
    /* DosGetInfoBlocks has no return code, we have to assume that it returns*/
    /* the correct values through its parameters                             */
    /*************************************************************************/
    DosGetInfoBlocks(&(DCIData->ptibDCI), &(DCIData->ppibDCI)); /* CON3201 */

    /* CON3201 **************************************/
    /*OFFSETOF(DCIData->LIS) = 0;                   */
    /*DCIData->ProcessID = DCIData->LIS->pidCurrent;*/
    /************************************************/
    DCIData->ProcessID = DCIData->ppibDCI->pib_ulpid;
    DCIData->LockDCInfo.LockCount = 0;
    DCIData->LockDCInfo.tidLock   = 0;

    /**************************************************************************/
    /*  Current attributes bundles are initialised to the global defaults -   */
    /*  done in prde_SetDCIDefaults.  Memory must be acquired for these       */
    /*  bundles so call prde_GetAttrsMemory.                                  */
    /**************************************************************************/
    if (prde_GetAttrsMemory(DCIData) != OK)
        goto ErrorReturn;

    /**************************************************************************/
    /*  Get memory for the variable size attributes hung off the DC Instance  */
    /*  data - these are just the clip rectangles.                            */
    /**************************************************************************/
    if (prde_GetVarSizeMemory(DCIData) != OK)
        goto ErrorReturn;

    /**************************************************************************/
    /*  Copy the Spooler Handle from the PDB to the DC Instance Data          */
    /**************************************************************************/
    DCIData->DCISplHandle = DCIData->DCIPdbInstance->PDBSplHandle;

    /**************************************************************************/
    /*  Indicate no selected bitmap as yet                                    */
    /**************************************************************************/
    DCIData->DCISelBitmap = FNULL;

    /**************************************************************************/
    /*  Indicate that the default text attributes bundle has not been set up  */
    /*  yet to ensure it is not used to set up the current text attributes    */
    /*  bundle (in SetDCIDefaults).                                           */
    /**************************************************************************/
    DCIData->DCIDefTxtAts = FNULL;

    /**************************************************************************/
    /*  Initialise the FontData so that LocateFont sets up a font the first   */
    /*  time it is called (from SetTextAttrs).                                */
    /**************************************************************************/
    DCIData->DCIFontData.Info.pFont = FNULL;

    /**************************************************************************/
    /*  Initiate the set of DC state bit flags.  The setting of the           */
    /*  LOCATE_FONT_REQD flag must be done before SetDCIDefaults is called    */
    /*  since this in turn calls SetTextAttrs which needs to, in turn, call   */
    /*  prdt_LocateFont to set up the DCI font data.                          */
    /**************************************************************************/
    DCIData->DCIStateFlags = LOCATE_FONT_REQD;

    /**************************************************************************/
    /*  Allocate memory for color table here.  Values are set up in           */
    /*  SetDCIAttributes.                                                     */
    /**************************************************************************/
    if (prdg_AllocHeapItem(DCIData, sizeof(ColorTableType) * DEF_COL_TABLE_SIZE,
                           (PUSHORT *)&DCIData->DCIColorTable) != OK)
        goto ErrorReturn;

    /**************************************************************************/
    /*  PD00506 : Init the color format flag so that SetDCIAttributes knows   */
    /*  what to do with the color table and the color format et al.           */
    /**************************************************************************/
    DCIData->DCIColFormat = LCOLF_BOGUS;

    /**************************************************************************/
    /*  Setup the DC info to defaults.                                        */
    /**************************************************************************/
    (VOID)prdn_SetEnableDCIDefaults(DCIData);

    /**************************************************************************/
    /*  Set flag for text only optimisation to TRUE.  This will be set to     */
    /*  FALSE whenever some drawing takes place into the band.  If its value  */
    /*  is still TRUE at the time of printing (in PRDPBAND) then all          */
    /*  processing of the band can be skipped.                                */
    /**************************************************************************/
    DCIData->TextOnlyDC = TRUE;

    /**************************************************************************/
    /*  Set no of used cards and the indices to zero.                         */
    /**************************************************************************/
    DCIData->DCICardCount = 0;
    for (i = 0; i < MAX_NO_OF_CARD_SLOTS; i++)
        DCIData->DCICardIndx[i] = 0;

    /**************************************************************************/
    /*  Set up the command mask for this DC.  If is an INFO DC or a queued    */
    /*  standard DC we want to switch of the COM_DRAW bit since no drawing    */
    /*  should be done.                                                       */
    /**************************************************************************/
    DCIData->CommandMask = 0xFFFF0000L;      /* CON3201 - CommandMask changed */
                                             /*           to a ULONG          */
    if (DCIData->Flags & (INFO | QUEUED_STD))
    {
        DCIData->CommandMask &= ~COM_DRAW;
    }

    /**************************************************************************/
    /*  Set the number of download fonts.                                     */
    /**************************************************************************/
    if (!(DCIData->Flags & MEMORY))
    {
        DCIData->DCINoOfDownFonts = DCIData->DCIPdbInstance->
                                             PrinterData->DownFontCount;
    }
    else
    {
        DCIData->DCINoOfDownFonts = 0;
    }
    TRACE6(TFUNC, "No of download fonts", &DCIData->DCINoOfDownFonts, 1);

    /**************************************************************************/
    /*  Set up the Download font list - Initial download fonts are sent down  */
    /*  to the printer after prdp_PrintStart has been called.                 */
    /**************************************************************************/
    if (DCIData->DCINoOfDownFonts)
    {
        TRACE6(TFUNC, "Set up down fonts", FNULL, 0);
        if (OK != prdg_AllocHeapItem(DCIData,
                      DCIData->DCINoOfDownFonts * sizeof(DownFlagType),
                      (PUSHORT *)&(DCIData->DCIDownFontFlags)))
        {
            goto ErrorReturn;
        }
        for (i = 0; i < DCIData->DCINoOfDownFonts; i++)
        {
            DCIData->DCIDownFontFlags[i].Used   = FALSE;
            DCIData->DCIDownFontFlags[i].Loaded = FALSE;
        }
    }

    /**************************************************************************/
    /*  Allocate and initialize the download codepage Used and Loaded flags.  */
    /*  These flags are only used by the 4019 Heritage driver.  The routine   */
    /*  prde_LoadDownDynamicDownCps is called by prdn_InitPrinterAllPages to  */
    /*  accomplish the download of the BIN files for any codepage used on a   */
    /*  page.                                                                 */
    /**************************************************************************/
    TRACE6(TFUNC, "Set up down Cp Flags", FNULL, 0);
    /******************************************************************/
    /* PD00241 : Allocate the maximum possible number of code pages   */
    /* instead of using OutlineCodepageEntries which now changes      */
    /* dynamically as new code pages are encountered.                 */
    /******************************************************************/
    if ( prdg_AllocHeapItem(DCIData,
                     MAX_OUTLINE_CODEPAGE_ENTRIES * sizeof(DownFlagType),
                     (PUSHORT *)&(DCIData->DCIDownCpFlags)) != OK )
    {
        goto ErrorReturn;
    }
    /******************************************************************/
    /* PD00241 : Set all the USED and LOADED flags to FALSE           */
    /******************************************************************/
    for ( i = 0; i < MAX_OUTLINE_CODEPAGE_ENTRIES; i++ )
    {
        DCIData->DCIDownCpFlags[i].Used   = FALSE;
        DCIData->DCIDownCpFlags[i].Loaded = FALSE;
    }

    /**************************************************************************/
    /*  PD00547: initialize accumulated error.                                */
    /**************************************************************************/
    DCIData->Remainder = 0;

    /**************************************************************************/
    /*  And finally the default style ratio.                                  */
    /**************************************************************************/
    DCIData->DCIStyleRatio = 0x0101;   /* MSB is y component,                 */
                                       /* LSB is x component                  */
#ifdef PRD_TIMING
    DEKHOOK0(A,8,B7)
#endif
    return ((ULONG)DCIData);

ErrorReturn:
    /******************************************************************/
    /* Free the DC Heap before returning any error - note we do not   */
    /* need to bother with scanning the heap list since at this point */
    /* there will only be a single entry.                             */
    /******************************************************************/
  /* CON3201 ****************************/
  /*(VOID)prdg_DeleteHeap(HeapSelector);*/
  /**************************************/
    (VOID)prdg_DeleteHeap(pvHeap);
#ifdef PRD_TIMING
    DEKHOOK0(A,8,B7)
#endif
    return((ULONG)ERROR_NEG);
}
#undef TFUNC

/******************************************************************************/
/*  FUNCTION: prde_GetAttrsMemory                                             */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  lpDCI  DCIData;  Pointer to DC Instance data                              */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This function allocates memory on the DC heap for the attribute bundles   */
/*  and sets the pointers in DC Instance data to these areas.                 */
/******************************************************************************/
/* CON3201 *******************************************/
/*USHORT pascal prde_GetAttrsMemory(DCIData)         */
/*                                                   */
/*lpDCI   DCIData;                                   */
/*****************************************************/

SHORT prde_GetAttrsMemory(lpDCI DCIData)
{
#define TFUNC "prde_GetAttrMem"

    /**************************************************************************/
    /*  Get memory for Line Attributes                                        */
    /**************************************************************************/
    TRACE4(TFUNC, "Set up Line Attributes", &DCIData, 1);
    if (prdg_AllocHeapItem(DCIData, sizeof(DLINEBUNDLE),
                           (PUSHORT *)&(DCIData->DCICurLinAts)) != OK)
    {
        return(ERROR_NEG); /* CON3201 removed cast to USHORT */
    }

    /**************************************************************************/
    /*  Get memory for Text Attributes                                        */
    /**************************************************************************/
    TRACE4(TFUNC, "Set up Text Attributes", &DCIData, 1);
    if (prdg_AllocHeapItem(DCIData, sizeof(DCHARBUNDLE),
                           (PUSHORT *)&(DCIData->DCICurTxtAts)) != OK)
    {
        return(ERROR_NEG); /* CON3201 removed cast to USHORT */
    }
    /**************************************************************************/
    /*  Get memory for Marker Attributes                                      */
    /**************************************************************************/
    TRACE4(TFUNC, "Set up Marker Attributes", &DCIData, 1);
    if (prdg_AllocHeapItem(DCIData, sizeof(DMARKERBUNDLE),
                           (PUSHORT *)&(DCIData->DCICurMrkAts)) != OK)
    {
        return(ERROR_NEG); /* CON3201 removed cast to USHORT */
    }
    /**************************************************************************/
    /*  Get memory for Pattern Attributes                                     */
    /**************************************************************************/
    TRACE4(TFUNC, "Set up Pattern Attributes", &DCIData, 1);
    if (prdg_AllocHeapItem(DCIData, sizeof(DAREABUNDLE),
                           (PUSHORT *)&(DCIData->DCICurPtnAts)) != OK)
    {
        return(ERROR_NEG); /* CON3201 removed cast to USHORT */
    }

    /**************************************************************************/
    /*  Get memory for Image Attributes                                       */
    /**************************************************************************/
    TRACE4(TFUNC, "Set up Image Attributes", &DCIData, 1);
    if (prdg_AllocHeapItem(DCIData, sizeof(DIMAGEBUNDLE),
                           (PUSHORT *)&(DCIData->DCICurImgAts)) != OK)
    {
        return(ERROR_NEG); /* CON3201 removed cast to USHORT */
    }
    return(OK); /* CON3201 removed cast to USHORT */
}
#undef TFUNC

/******************************************************************************/
/*  FUNCTION: prde_GetVarSizeMemory                                           */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  lpDCI  DCIData;  Pointer to DC Instance data                              */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This function allocates memory on the DC heap for clip rectangles and     */
/*  sets the pointer in the DC Instance data.                                 */
/******************************************************************************/
/* CON3201 ************************************/
/*USHORT pascal prde_GetVarSizeMemory(DCIData)*/
/*                                            */
/*lpDCI   DCIData;                            */
/**********************************************/

SHORT prde_GetVarSizeMemory(lpDCI DCIData)
{
#define TFUNC "prde_GetVarSzeM"

    TRACE4(TFUNC, "Entry", FNULL, 0);

    /**************************************************************************/
    /*  Allocate memory for the default clip rectangle.                       */
    /**************************************************************************/
    TRACE4(TFUNC, "Set up Clip Rectangles", FNULL, 0);
    if (OK != prdg_AllocHeapItem(DCIData,
                                 MAX_CLIP_RECTS * sizeof(ClipRectangle),
                                 (PUSHORT *)&(DCIData->DCIClipRects)))
    {
        return (ERROR_NEG); /* CON3201 removed cast to USHORT */
    }
    return(OK); /* CON3201 removed cast to USHORT */
}
#undef TFUNC

/******************************************************************************/
/*  FUNCTION: prdn_SetEnableDCIDefaults                                       */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  lpDCI  DCIData                                                            */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  Called from EnableDC only. This sets up the DCI attributes and            */
/*  resets various flags.                                                     */
/******************************************************************************/
/* CON3201 ****************************************/
/*USHORT pascal prdn_SetEnableDCIDefaults(DCIData)*/
/*                                                */
/*lpDCI  DCIData;                                 */
/**************************************************/

SHORT prdn_SetEnableDCIDefaults(lpDCI DCIData)
{

    DCIData->Flags = 0L;
    if (DCIData->DCIDCType == OD_QUEUED)
    {

        /**********************************************************************/
        /*  Note QUEUED = (QUEUED_RAW | QUEUED_STD).                          */
        /**********************************************************************/
        if (DCIData->DCIPdbInstance->PDBOutputType == IBMQSTD)
        {
            DCIData->Flags |= QUEUED_STD;
        }
        else
        {
            DCIData->Flags |= QUEUED_RAW;
        }
    }
    else
    {
        if (DCIData->DCIDCType == OD_DIRECT)
        {
            DCIData->Flags |= DIRECT;
        }
        else
        {
            if (DCIData->DCIDCType == OD_MEMORY)
            {
                DCIData->Flags |= MEMORY;
            }
            else
            {
                if (DCIData->DCIDCType == OD_INFO)
                {
                    DCIData->Flags |= INFO;
                }
            }
        }
    }

    /**************************************************************************/
    /*  Now do present attr bundle bits (line, txt, marker, pattern, image,   */
    /*  coltable, curr pos, kern, codepage, bounsds, clipregion, FFparser.    */
    /**************************************************************************/
    (VOID)prdn_SetDCIAttributes(DCIData);

    /**************************************************************************/
    /*  Initialize the transform stored in DCI         PD00073                */
    /**************************************************************************/
    (VOID)prdn_SetDCIXform(DCIData);

    /**************************************************************************/
    /*  Now other bit (with AllDefaults flag = TRUE in old code) :- DC origin,*/
    /*  DC flags: Aborted, Drawn, PageNumber.                                 */
    /**************************************************************************/
    prdn_SetDCIFlags(DCIData);
    return(OK);
}

/******************************************************************************/
/*  FUNCTION: prdn_SetCompleteOpenDCIDefaults                                 */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  lpDCI  DCIData                                                            */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  Called from complete_open only. Most setup done in EnableDC; this just    */
/*  finishes it off. Split between the two is arbitrary (follows old code     */
/*  approximately).                                                           */
/******************************************************************************/
/* CON3201 **************************************************/
/*USHORT pascal prdn_SetCompleteOpenDCIDefaults(DCIData)    */
/*                                                          */
/*lpDCI  DCIData;                                           */
/************************************************************/

SHORT prdn_SetCompleteOpenDCIDefaults( lpDCI DCIData)
{
#define TFUNC "prde_SetCompleteOpenDCIDefaults"
    /**************************************************************************/
    /*  Local variables.                                                      */
    /**************************************************************************/
    lpPDBI               PDBInstance;  /* Pointer to PDB data                 */
    lpDDTType            pDDT;         /* Pointer to DDT in PDB               */
    lpPrtDataEntry       PrinterData;

    /**************************************************************************/
    /*  And now those final bits that only need to be done at enable time, and*/
    /*  not before.                                                           */
    /**************************************************************************/

    /**************************************************************************/
    /*  Set the pointer for the DDT and the Printer Data in the PDB           */
    /**************************************************************************/
    PDBInstance = DCIData->DCIPdbInstance;
    PrinterData = PDBInstance->PrinterData;
    pDDT = &PDBInstance->DDT;

    /**************************************************************************/
    /*  The current text attribute bundle now contains the correct default    */
    /*  font info.  Store a copy of this to use later as the default text     */
    /*  attribute bundle for this DC.                                         */
    /**************************************************************************/
    if (prdg_AllocHeapItem(DCIData, sizeof(DCHARBUNDLE),
                           (PUSHORT *)&(DCIData->DCIDefTxtAts)) != OK)
        return(ERROR_NEG);  /* CON3201 removed cast to USHORT */
    TRACE6(TFUNC, "Set up dflt bundle", FNULL, 0);
    prdu_memcpy((PBYTE)DCIData->DCIDefTxtAts, (PBYTE)DCIData->DCICurTxtAts,
                sizeof(DCHARBUNDLE));

    /**************************************************************************/
    /*  Don't have a name from StartDoc yet, so use default.                  */
    /**************************************************************************/
    DCIData->DCIDocName = (PULONG)szDefaultString;
    return(OK);
}
#undef TFUNC

/******************************************************************************/
/*  FUNCTION: prdn_SetStartDocDCIDefaults                                     */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  lpDCI  DCIData                                                            */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  Called from StartDoc only. This sets up the DCI stuff, but not the enable */
/*  time stuff.                                                               */
/******************************************************************************/
/* CON3201 ******************************************/
/*USHORT pascal prdn_SetStartDocDCIDefaults(DCIData)*/
/*                                                  */
/*lpDCI   DCIData;                                  */
/****************************************************/

SHORT prdn_SetStartDocDCIDefaults(lpDCI DCIData)
{

    (VOID)prdn_SetDCIAttributes(DCIData);

    /**************************************************************************/
    /*  Note: this resets the Aborted flag - needed for the case when AbortDoc*/
    /*  happens in WAIT_START state (direct_dc), to prevent aborting from     */
    /*  occurring.                                                            */
    /**************************************************************************/
    prdn_SetDCIFlags(DCIData);
    return(OK);
}

/******************************************************************************/
/*  FUNCTION: prdn_SetResetDCDCIDefaults                                      */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  lpDCI  DCIData                                                            */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  Called from StartDoc only. This sets up the DCI stuff, but not the enable */
/*  time stuff.                                                               */
/******************************************************************************/
/* CON3201 *******************************************/
/*USHORT pascal prdn_SetResetDCDCIDefaults(DCIData)  */
/*                                                   */
/*lpDCI  DCIData;                                    */
/*****************************************************/

SHORT prdn_SetResetDCDCIDefaults(lpDCI DCIData)
{
    return(prdn_SetDCIAttributes(DCIData));
}

/******************************************************************************/
/*  FUNCTION: prdn_SetDCIFlags                                                */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  lpDCI  DCIData                                                            */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  Setup DC flags for startdoc, enableDC. Reset DC origin.                   */
/******************************************************************************/
/* CON3201 *************************************/
/*USHORT pascal prdn_SetDCIFlags(DCIData)      */
/*                                             */
/*lpDCI  DCIData;                              */
/***********************************************/

SHORT prdn_SetDCIFlags(lpDCI DCIData)
{
    DCIData->DCIPageNumber = 1;

    /**************************************************************************/
    /*  Char mode simulation                                                  */
    /**************************************************************************/
    DCIData->DCIStateFlags = 0L;
    DCIData->Flags &= ~ABORTED;

    /**************************************************************************/
    /*  Set the DC origin.                                                    */
    /**************************************************************************/
    DCIData->DCIOrigin.X = 0;
    DCIData->DCIOrigin.Y = 0;
    return(OK);
}

/******************************************************************************/
/*  FUNCTION: prdn_SetDCIAttributes                                           */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  lpDCI  DCIData                                                            */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  Setup attributes, color table, current position, codepage, bounds,        */
/*  clipregion.                                                               */
/******************************************************************************/
/* CON3201 **************************************/
/*USHORT pascal prdn_SetDCIAttributes(DCIData)  */
/*                                              */
/*lpDCI  DCIData;                               */
/************************************************/

SHORT prdn_SetDCIAttributes(lpDCI DCIData )

{
#define TFUNC "prde_SetDCIAttr"

    /**************************************************************************/
    /*  Local Variables                                                       */
    /**************************************************************************/
    lpDDTType            pDDT;         /* Pointer to DDT in PDB               */
    SHORT                i;            /* Loop control variable               */
    lpDfltFontInfoType   pDfltFont;
    lpDfltFontInfoType   pDfltDeviceFont;                          /* PD00660 */
    USHORT               Return;                                   /* PD00660 */
    TRACE4(TFUNC, "Entry", FNULL, 0);

    /**************************************************************************/
    /*  Set up pointers.                                                      */
    /**************************************************************************/
    pDDT      = &DCIData->DCIPdbInstance->DDT;
    pDfltFont = &DCIData->DCIPdbInstance->DfltFont;
    pDfltDeviceFont = &DCIData->DCIPdbInstance->DfltDeviceFont;    /* PD00660 */

    /**************************************************************************/
    /*  Set DCICodePage to the system code page.                              */
    /**************************************************************************/
/* CON3201 ****************************************/
    DCIData->DCICodePage = WinQueryProcessCP();
/**************************************************/
/*  DCIData->DCICodePage = prde_QueryProcessCP(); */

    if (pDfltFont->Info.Type != FT_ENGINE)
    {
        /**********************************************************************/
        /*  If default font is a device font then we have to make sure we are */
        /*  pointing to the font in the system code page.  This is so we don't*/
        /*  fail the GPICreatePS.  If the font is not a device font then all  */
        /*  has been set up correctly at Fill PDB time.                       */
        /**********************************************************************/
        if (DCIData->DCICodePage != pDfltFont->Info.pFont->Metrics.usCodePage)
        {
            prda_FindDeviceCodePage(DCIData->DCICodePage, DCIData, pDfltFont);
        }
    }

    /**************************************************************************/
    /* PD00784 : Moved this code out of if statment above to setup correct    */
    /* codepage even when the default font is the system font. For raw jobs   */
    /* the system font won't be used so must setup code page for the font     */
    /* that will be used for printing.                                        */
    /**************************************************************************/
    /**************************************************************************/
    /* PD00660 : We need to do the same for the DefaultDeviceFont, but we want*/
    /* to change it to code page 850 if our font doesn't support the          */
    /* DCICodePage.                                                           */
    /**************************************************************************/
    if (DCIData->DCICodePage != pDfltDeviceFont->Info.pFont->Metrics.usCodePage)
    {
       Return = prda_MatchExactCodePage(DCIData->DCICodePage,
                                        DCIData,
                                        pDfltDeviceFont);

       /***********************************************************************/
       /* Try to match codepage 850, if we can.                               */
       /***********************************************************************/
       if ( (Return == CODEPAGE_NOT_FOUND) &&
            (DCIData->DCICodePage != 850 ) )
          Return = prda_MatchExactCodePage( (USHORT) 850,
                                            DCIData,
                                            pDfltDeviceFont);
    }

    /**************************************************************************/
    /* We also have to make sure that the default font escape sequences get   */
    /* sent to the printer.                                                   */
    /**************************************************************************/
    DCIData->Flags |= RESET_DFLT_FONT;



    /**************************************************************************/
    /*  The prda_Set????Attrs functions are used to set the default           */
    /*  attributes.                                                           */
    /*                                                                        */
    /*  NOTE : Initialization of DCIFontData.                                 */
    /*                                                                        */
    /*  This is done by LocateFont (called from SetTextAttrs) - hence the     */
    /*  LOCATE_FONT_REQD flag and the default font info structure must be set */
    /*  up BEFORE SetTextAttrs is called.                                     */
    /*                                                                        */
    /*  If the default font selected by the user is a device font then the    */
    /*  font data set up is valid; if user selected an engine font then the   */
    /*  font data will be set up as for the default DEVICE font until the     */
    /*  engine gives us a DeviceSet(Text)Attrs call to set the current font to*/
    /*  an engine font in response to the returned value in QueryDeviceCaps   */
    /*  for CAPS_ADDITIONAL_GRAPHICS (called by the engine directly after     */
    /*  EnableDC).                                                            */
    /*                                                                        */
    /*  DCIFontData is only (temporarily) invalid in the above case.          */
    /*  LocateFont is structured so that the font data is left untouched (at  */
    /*  the previous settings) should the call fail.                          */
    /**************************************************************************/
    (VOID)prda_SetLineAttrs(0xFFFF, 0, FNULL, DCIData->DCICurLinAts, DCIData);
    (VOID)prda_SetTextAttrs((HDC)DCIData->DcH, 0xFFFF, 0, FNULL,
                            DCIData->DCICurTxtAts, DCIData);
    (VOID)prda_SetMarkAttrs(0xFFFF, 0, FNULL, DCIData->DCICurMrkAts);
    (VOID)prda_SetPtrnAttrs(0xFFFF, 0, FNULL, DCIData->DCICurPtnAts);
    DCIData->DCIPattOriDev.X = (USHORT)0;
    DCIData->DCIPattOriDev.Y = (USHORT)0;
    (VOID) prda_SetImagAttrs(0xFFFF, 0, FNULL, DCIData->DCICurImgAts);

    /**************************************************************************/
    /*  Color Table - memory allocated in EnableDC:- only do this once.  Set  */
    /*  up the values here.                                                   */
    /*                                                                        */
    /*  PD00315 : Check that the memory allocated by EnableDC has not been    */
    /*  freed.  If it has, then reallocate it.  If for some reason we can't   */
    /*  get memory, then for now we'll just skip the color table assignments  */
    /*  and continue from there (since to really process the error correctly  */
    /*  we'd need to revamp error handling all the way up the calling chain,  */
    /*  which I'm not going to do... I'm going camping instead ;-).           */
    /**************************************************************************/
    if (DCIData->DCIColorTable == FNULL)
    {
        if (prdg_AllocHeapItem(DCIData,
                               sizeof(ColorTableType) * DEF_COL_TABLE_SIZE,
                               (PUSHORT *)&DCIData->DCIColorTable) != OK)
            goto ErrorShortCut;
    }
    if (pDDT->DDTMaxColors == DDT_TWO_COLORS)
    {

        /**********************************************************************/
        /*  Set the color table to the default and for a monochrome printer   */
        /*  set all physical colors to foreground except index 0 which is set */
        /*  to the background.                                                */
        /**********************************************************************/
        for (i = DEF_COL_TABLE_SIZE - 1; i; i--)
        {
            DCIData->DCIColorTable[i].LogRGB = DefaultColorTable[i];
            DCIData->DCIColorTable[i].PhysRGB = pDDT->DDTDevColorTable->
                                                         Colors[PRD_FOREGROUND];
        }
        DCIData->DCIColorTable[0].LogRGB = DefaultColorTable[0];
        DCIData->DCIColorTable[0].PhysRGB = pDDT->DDTDevColorTable->
                                                         Colors[PRD_BACKGROUND];
    }
    else
    {
        if (pDDT->DDTMaxColors == DDT_EIGHT_COLORS)
        {
            for (i = DEF_COL_TABLE_SIZE - 1; i >= 0; i--)
            {
                DCIData->DCIColorTable[i].LogRGB = DefaultColorTable[i];
                DCIData->DCIColorTable[i].PhysRGB = pDDT->DDTDevColorTable->
                             Colors[prdc_RGBColorToPelBits(DefaultColorTable[i],
                             pDDT->DDTDevColorTable)];
            }
        }
    }

ErrorShortCut:                         /* PD00315 : Hope we never use this... */

    /**************************************************************************/
    /*  Initialize the fields related to the color table.                     */
    /*                                                                        */
    /*  PD00506 : To avoid a major undertaking for StartDoc processing (where */
    /*  we incorrectly re-initialize the entire DC when StartDoc is processed */
    /*  when in reality we're not supposed to do this), we are going to see   */
    /*  if the DCIColFormat has already been set up to a sensible value.  If  */
    /*  it has, we'll leave it alone and if it's LCOLF_RGB we have to undo all*/
    /*  the color table stuff we just did.  If the value of DCIColFormat is   */
    /*  none of the sensible values, we set the value to LCOLF_DEFAULT.  Note */
    /*  that we initialize this flag to LCOLF_BOGUS in prde_EnableDC().       */
    /**************************************************************************/
    DCIData->DCIColTabSize = DEF_COL_TABLE_SIZE;
    DCIData->DCILowIndex   = 0;
    DCIData->DCIHighIndex  = DEF_COL_TABLE_SIZE - 1;
    switch (DCIData->DCIColFormat)
    {
        case LCOLF_RGB       :
            if (DCIData->DCIColorTable != FNULL)
            {
                TRACE4(TFUNC, "Free Old Table", FNULL, 0);
                (VOID)prdg_FreeHeapItem(DCIData, DCIData->
                                        DCIColTabSize * sizeof(ColorTableType),
                                        (PUSHORT)DCIData->DCIColorTable);
                DCIData->DCIColorTable = FNULL;
            }
            DCIData->DCIColTabSize = 0;
            DCIData->DCILowIndex   = 0;
            DCIData->DCIHighIndex  = 0;
            break;
        case LCOLF_DEFAULT   :
        case LCOLF_INDRGB    :
        case LCOLF_CONSECRGB :
            break;
        default              :
            DCIData->DCIColFormat = LCOLF_DEFAULT;
    }

    /**************************************************************************/
    /*  Current position                                                      */
    /**************************************************************************/
    DCIData->DCICurrPosDev.X  = 0;
    DCIData->DCICurrPosDev.Y  = 0;
    DCIData->DCICurrPosWcs.X  = 0L;
    DCIData->DCICurrPosWcs.Y  = 0L;
    DCIData->DCICurrPosFont.x = 0;
    DCIData->DCICurrPosFont.y = 0;
    DCIData->DCIStateFlags   |= FONT_COORDS_VALID;

    /**************************************************************************/
    /*  Set the bounds to their default                                       */
    /**************************************************************************/
    DCIData->DCIBounds[0].X = 0x07FFFFFFL;
    DCIData->DCIBounds[0].Y = 0x07FFFFFFL;
    DCIData->DCIBounds[1].X = 0xF8000000L;
    DCIData->DCIBounds[1].Y = 0xF8000000L;

    /**************************************************************************/
    /*  Set the default clip region                                           */
    /**************************************************************************/
    (VOID)prdi_DefaultClip(DCIData);

    /**************************************************************************/
    /*  Formfeed handling parser initialisation.                              */
    /**************************************************************************/
    DCIData->ParserSequence = NULL;
    DCIData->ParserState    = prdg_Text;
    DCIData->FFstate        = prdg_FFtext;
    TRACE4(TFUNC, "Exit OK", FNULL, 0);
    return(OK);
}
#undef TFUNC

/******************************************************************************/
/*  FUNCTION: prdn_SetDCIXform                 PD00073                        */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  lpDCI  DCIData                                                            */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  Initialize the transform matrix stored in DC Instance data. This will     */
/*  later get set to the current transform when we get the                    */
/*  NotifyTransform change call.                                              */
/*                                                                            */
/******************************************************************************/
/* CON3201 ********************************/
/*VOID pascal prdn_SetDCIXform(DCIData)   */
/*                                        */
/*lpDCI  DCIData;                         */
/******************************************/

VOID prdn_SetDCIXform(lpDCI DCIData)
{

    /**************************************************************************/
    /*  Set up the tranform matrix and flag.                                  */
    /**************************************************************************/
    DCIData->DCITransformFlags = 0L;

    DCIData->DCITransform.fxM11 = (FIXED)0x10000;
    DCIData->DCITransform.fxM12 = 0;
    DCIData->DCITransform.fxM21 = 0;
    DCIData->DCITransform.fxM22 = (FIXED)0x10000;
    DCIData->DCITransform.lM41 = 0;
    DCIData->DCITransform.lM42 = 0;

}

#if 0
/******************************************************************************/
/*  FUNCTION: prde_QueryProcessCP                                             */
/*                                                                            */
/*  Parameters:                                                               */
/*                                                                            */
/*  Returns   : ULONG    Current Code Page                                    */
/*                                                                            */
/*  Description:                                                              */
/*  Gets the current code page of the process.                                */
/*                                                                            */
/******************************************************************************/
USHORT prde_QueryProcessCP(VOID)
{
ULONG CpList;
ULONG CpSize;
APIRET rc;

   rc = DosQueryCp(sizeof(ULONG), &CpList, &CpSize);
   return((USHORT)CpList);
}
#endif
