/*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 = PRDESAVE
 *
 * DESCRIPTIVE NAME =
 *
 *
 * VERSION
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS   prde_SaveDC
 *
 * ENTRY POINTS:
 *
 * DEPENDENCIES:
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/

#define INCL_32                         /* Convert to C/SET2    CON3201       */
#define INCL_DOSPROCESS                 /* Convert to C/SET2    CON3201       */
#define INCL_DOSSEMAPHORES
#define INCL_GPIPRIMITIVES
#define INCL_WINHEAP
#define INCL_GPIBITMAPS
#define INCL_GPILOGCOLORTABLE
#define INCL_GPIERRORS
#include <os2.h>
#undef INCL_DOSPROCESS                  /* Convert to C/SET2    CON3201       */
#undef INCL_DOSSEMAPHORES
#undef INCL_GPIPRIMITIVES
#undef INCL_WINHEAP
#undef INCL_GPIBITMAPS
#undef INCL_GPILOGCOLORTABLE
#undef INCL_GPIERRORS

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

#define INCL_WINP_SELECTIVE
#define INCL_WINP_SEI
#include <pmwinx.h>
#undef INCL_WINP_SELECTIVE
#undef INCL_WINP_SEI
#undef INCL_32                          /* Convert to C/SET2    CON3201       */

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

#define NO_SYS
#define NO_CONSTANT_INCL
#include <prdinclt.h>
#undef NO_CONSTANT_INCL
#undef NO_SYS

#include <prdmtypt.h>
#include <prdupatt.h>

#include <prdeextf.h>
#include <prdgextf.h>
#include <prduextf.h>
#include <prdicone.h>

/******************************************************************************/
/*  FUNCTION: prde_SaveDC                                                     */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  lpDCI  DCIData;  Pointer to DC Instance data                              */
/*  ULONG  param ;   Unused parameter                                         */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This function saves a DC by 'pushing' it on the 'stack'.  The current DC  */
/*  which remains is identical to that which was saved except for DCISaveCount*/
/*  and DCINextEntry.                                                         */
/*                                                                            */
/*  CHANGES:                                                                  */
/*                                                                            */
/*  This function will have to make identical copies of any extra items of    */
/*  information hung from the DC Instance data.                               */
/******************************************************************************/
#if 0
USHORT pascal prde_SaveDC(DCIData, param2)

lpDCI         DCIData;
PBYTE         param2;
#endif

SHORT prde_SaveDC( lpDCI  DCIData,                                 /* CON3201 */
                   PBYTE  param2 )                                 /* CON3201 */

{
#define TFUNC "prde_SaveDC"

    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
    lpDCI  SaveDCIData;                /* Pointer to saved DC data            */

    /******************************************************************/
    /* Do entry processing                                            */
    /******************************************************************/
#ifdef PRD_TIMING
    DEKHOOK0(A,7,4F)
#endif
    prdm_EnterDriver(DCIData);
#ifdef DEBUG_FSM
    OutputString("Enter SaveDC");
#endif
    /******************************************************************/
    /* PD00474 : Mark the pattern as invalid.                         */
    /******************************************************************/
    DCIData->usPatValid = FALSE;

    /**************************************************************************/
    /*  Get memory off the heap to allocate the new instance data.            */
    /**************************************************************************/
    if (prdg_AllocHeapItem(DCIData, sizeof(DCIType),
                           (PUSHORT *)&SaveDCIData) != OK)
    {
        prdm_LeaveDriver(DCIData);
     /* return((USHORT)ERROR_NEG); */
        return((SHORT)ERROR_NEG);                                  /* CON3201 */
    }

    /**************************************************************************/
    /*  Copy the current DC instance data into the new one.                   */
    /**************************************************************************/
    TRACE4(TFUNC, "Data before", SaveDCIData,sizeof(DCIType)/4+1);
    prdu_memcpy((PBYTE)SaveDCIData, (PBYTE)DCIData, (unsigned)sizeof(DCIType));
    TRACE4(TFUNC, "Data after", SaveDCIData, sizeof(DCIType)/4+1);

    /**************************************************************************/
    /*  Chain the old instance data as the next entry on the 'stack' below the*/
    /*  new one.                                                              */
    /**************************************************************************/
    DCIData->DCINextEntry = SaveDCIData;

    /**************************************************************************/
    /*  At the moment DCIData and SaveDCIData are identical so their pointers */
    /*  via which data is attached to them point to the same actual blocks of */
    /*  data.  We want them to point to identical copies of the data so for   */
    /*  all these cases the approach is to allocate new memory attached to the*/
    /*  SaveDCIData structure and then copy the contents of the equivalent    */
    /*  memory attached to the DCIData to this new memory.                    */
    /**************************************************************************/

    /**************************************************************************/
    /*  Get memory for Line Attributes                                        */
    /**************************************************************************/
    TRACE4(TFUNC, "Set up Line Attributes", &DCIData, 1);
    if (prdg_AllocHeapItem(DCIData, sizeof(DLINEBUNDLE),
                           (PUSHORT *)&(SaveDCIData->DCICurLinAts)) != OK)
    {
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,CF)
#endif
     /* return((USHORT)ERROR_NEG); */
        return((SHORT)ERROR_NEG);                                  /* CON3201 */
    }

    /**************************************************************************/
    /*  Get memory for Text Attributes                                        */
    /**************************************************************************/
    TRACE4(TFUNC, "Set up Text Attributes", &DCIData, 1);
    if (prdg_AllocHeapItem(DCIData, sizeof(DCHARBUNDLE),
                           (PUSHORT *)&(SaveDCIData->DCICurTxtAts)) != OK)
    {
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,CF)
#endif
     /* return((USHORT)ERROR_NEG); */
        return((SHORT)ERROR_NEG);                                  /* CON3201 */
    }

    /**************************************************************************/
    /*  Get memory for Marker Attributes                                      */
    /**************************************************************************/
    TRACE4(TFUNC, "Set up Marker Attributes", &DCIData, 1);
    if (prdg_AllocHeapItem(DCIData, sizeof(DMARKERBUNDLE),
                           (PUSHORT *)&(SaveDCIData->DCICurMrkAts)) != OK)
    {
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,CF)
#endif
     /* return((USHORT)ERROR_NEG); */
        return((SHORT)ERROR_NEG);                                  /* CON3201 */
    }

    /**************************************************************************/
    /*  Get memory for Pattern Attributes                                     */
    /**************************************************************************/
    TRACE4(TFUNC, "Set up Pattern Attributes", &DCIData, 1);
    if (prdg_AllocHeapItem(DCIData, sizeof(DAREABUNDLE),
                           (PUSHORT *)&(SaveDCIData->DCICurPtnAts)) != OK)
    {
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,CF)
#endif
     /* return((USHORT)ERROR_NEG); */
        return((SHORT)ERROR_NEG);                                  /* CON3201 */
    }

    /**************************************************************************/
    /*  Get memory for Image Attributes                                       */
    /**************************************************************************/
    TRACE4(TFUNC, "Set up Image Attributes", &DCIData, 1);
    if (prdg_AllocHeapItem(DCIData, sizeof(DIMAGEBUNDLE),
                           (PUSHORT *)&(SaveDCIData->DCICurImgAts)) != OK)
    {
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,CF)
#endif
     /* return((USHORT)ERROR_NEG); */
        return((SHORT)ERROR_NEG);                                  /* CON3201 */
    }
//    /**************************************************************************/
//    /*  Get space for new attributes bundles.                                 */
//    /**************************************************************************/
//    if (prde_GetAttrsMemory(SaveDCIData) != OK)
//    {
//        prdm_LeaveDriver(DCIData);
//        return(ERROR_NEG);
//    }

//    /**************************************************************************/
//    /*  A new heap may have been created by the AllocHeapItem calls in        */
//    /*  GetAttrsMemory, and we must keep the current heap pointer in DCIData. */
//    /**************************************************************************/
//    DCIData->DCICurrHHeap   = SaveDCIData->DCICurrHHeap;
//    DCIData->DCICurrHeapSel = SaveDCIData->DCICurrHeapSel;

    /**************************************************************************/
    /*  Copy the text attribute bundle.                                       */
    /**************************************************************************/
    prdu_memcpy((PBYTE)SaveDCIData->DCICurTxtAts, (PBYTE)DCIData->DCICurTxtAts,
                sizeof(DCHARBUNDLE));

    /**************************************************************************/
    /*  Copy the line attribute bundle                                        */
    /**************************************************************************/
    prdu_memcpy((PBYTE)SaveDCIData->DCICurLinAts, (PBYTE)DCIData->DCICurLinAts,
                sizeof(DLINEBUNDLE));

    /**************************************************************************/
    /*  Copy the marker attribute bundle                                      */
    /**************************************************************************/
    prdu_memcpy((PBYTE)SaveDCIData->DCICurMrkAts, (PBYTE)DCIData->DCICurMrkAts,
                sizeof(DMARKERBUNDLE));

    /**************************************************************************/
    /*  Copy the pattern attribute bundle                                     */
    /**************************************************************************/
    prdu_memcpy((PBYTE)SaveDCIData->DCICurPtnAts, (PBYTE)DCIData->DCICurPtnAts,
                sizeof(DAREABUNDLE));

    /**************************************************************************/
    /*  Copy the image attribute bundle                                       */
    /**************************************************************************/
    prdu_memcpy((PBYTE)SaveDCIData->DCICurImgAts, (PBYTE)DCIData->DCICurImgAts,
                sizeof(DIMAGEBUNDLE));

    /**************************************************************************/
    /*  Get space for the clip rectangles.                                    */
    /**************************************************************************/
    if (OK != prdg_AllocHeapItem(DCIData,
                                 MAX_CLIP_RECTS * sizeof(ClipRectangle),
                                 (PUSHORT *)&(SaveDCIData->DCIClipRects)))
    {
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,CF)
#endif
        return(ERROR_NEG);
    }

    /**************************************************************************/
    /*  Copy the clip rectangle data.                                         */
    /**************************************************************************/
    prdu_memcpy((PBYTE)SaveDCIData->DCIClipRects, (PBYTE)DCIData->DCIClipRects,
                MAX_CLIP_RECTS * sizeof(ClipRectangle));

    if (DCIData->DCIColFormat != LCOLF_RGB)
    {

        /**********************************************************************/
        /*  There is a color table so get space for a copy of it.             */
        /**********************************************************************/
        if (OK != prdg_AllocHeapItem(DCIData,
                                DCIData->DCIColTabSize * sizeof(ColorTableType),
                                (PUSHORT *)&(SaveDCIData->DCIColorTable)))
        {
            prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,CF)
#endif
            return(ERROR_NEG);
        }

        /**********************************************************************/
        /*  Copy the current color table across.                              */
        /**********************************************************************/
        prdu_memcpy((PBYTE)SaveDCIData->DCIColorTable,
                    (PBYTE)DCIData->DCIColorTable,
                    DCIData->DCIColTabSize * sizeof(ColorTableType));
    }

    /**************************************************************************/
    /*  A new heap may have been created by the AllocHeapItem calls above, and*/
    /*  this must be known to SavedDCI as well.                               */
    /**************************************************************************/
 /* SaveDCIData->DCICurrHHeap   = DCIData->DCICurrHHeap;   */
 /* SaveDCIData->DCICurrHeapSel = DCIData->DCICurrHeapSel; */
    SaveDCIData->DCICurrHeap   = DCIData->DCICurrHeap;             /* CON3201 */

    /**************************************************************************/
    /*  Increment save count (ie the number of DCs on the stack)              */
    /**************************************************************************/
    DCIData->DCISaveCount++;
    TRACE4(TFUNC, "SaveCount", &DCIData->DCISaveCount, 1);
    prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,CF)
#endif
    return(OK);
}
#undef TFUNC
