/*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          = EDDBDELT                                       */
/*                                                                    */
/*   Description     = Display Device Driver Function :               */
/*                     DeviceDeleteBitmap                             */
/*                                                                    */
/*   Function        = De-allocates memory for a specified bitmap     */
/*                     and removes its entry from the Bitmap List.    */
/*                                                                    */
/*   Reference       = Winthorn Functional Specification              */
/*                     Device Driver Interface Specification          */
/*                     Display Device Driver Design Specification     */
/*                                                                    */
/*                                                                    */
/**********************************************************************/
#define INCL_DEV
#define INCL_DDIMISC
#include <eddinclt.h>

#include <eddbtypt.h>
#include <edddtypt.h>

#include <eddbextf.h>
#include <eddgextf.h>

#include <eddbcone.h>

#include <semaphor.h>
#include <memman.h>

/**********************************************************************/
/*                                                                    */
/*   DeviceDeleteBitmap deletes a specified bitmap by deleting its    */
/* bitmap header and de-allocating the memory for the bitmap. The     */
/* function returns an error if the bitmap is currently selected      */
/* into a DC.                                                         */
/*                                                                    */
/*   If the UsageParameter is set to CBM_INIT the function returns    */
/* pointers to the bitmap bits and a BITMAPINFO structure with which  */
/* to interpret these bits.  The values in this table are taken       */
/* from the bitmap header.                                            */
/*                                                                    */
/*   The returned bitmap bits are in external format.  The device     */
/* driver therefore converts from its own format to allow for the     */
/* 'origin flip' and padding at the ends of scanlines.                */
/*                                                                    */
/*   In order to do this conversion the driver allocates new memory   */
/* for the bitmap bits and de-allocates the old memory after the      */
/* conversion.                                                        */
/*                                                                    */
/* Neither the HDC nor the PDC parameter is likely to be valid, so    */
/* must not be used.                                                  */
/**********************************************************************/
DDIENTRY eddb_DeviceDeleteBitmap (HDC              hdc,
                                  pBitmapHeader    ArgHandle,
                                  PDELETERETURN    ArgReturns,
                                  ULONG            ArgUsage,
                                  PDC              pdcArg,
                                  ULONG            FunN)
{
    /******************************************************************/
    /* Local variables                                                */
    /******************************************************************/
    ULONG            RequiredMemory;  /* for new bitmap (bytes)       */
    PBITMAPINFO2     InfoParms;       /* bitmap info parms returned   */
    ULONG            BytesPerRow;     /* external bytes per row       */
    POINTL           ptlStartPoint;   /* used by conversion function  */
    ULONG            ScanLinesSet;    /* used by conversion function  */
    ULONG            ColourTableSize; /* size of structure in bytes   */

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

    /******************************************************************/
    /* We must instruct EnterDriver to just grab the lock semaphore.  */
    /*                                                                */
    /* Just in case pdcArg is not NULL, we pass NULL to EnterDriver.  */
    /* This will then set the global pdc value to NULL, and having    */
    /* a NULL pdc is the best firewall we have to ensure that we      */
    /* dont use the pdc in any lower level functions.                 */
    /******************************************************************/
    EnterDriver(NULL, FunN, EDF_EXCLUSIVE | EDF_DC_NULL | EDF_DONT_CLEAN);

    /******************************************************************/
    /* Return bitmap if required (after converting to external        */
    /* format)                                                        */
    /******************************************************************/
    if (ArgUsage & CBM_INIT)
    {
        /**************************************************************/
        /* Calculate the size of the external bitmap color table.     */
        /**************************************************************/
        #ifdef   BPP24
        if ((ArgHandle->Info.BitCount == 16)||(ArgHandle->Info.BitCount == 24 ))
        #else
        if (ArgHandle->Info.BitCount == 16)
        #endif
        {
            /**********************************************************/
            /* Internal 16bpp is returned as external 24 bpp, so      */
            /* there is no color table                                */
            /**********************************************************/
            ColourTableSize = 0;
        }
        else
        {
            /**********************************************************/
            /* Internal formats of 1, 4 and 8 bpp all map directly    */
            /* to the equivalent external formats.                    */
            /**********************************************************/
            ColourTableSize =
                         sizeof(RGB2) * (1 << ArgHandle->Info.BitCount);
        }

        /**************************************************************/
        /* Allocate memory for bitmap info table. return error if     */
        /* allocation fails.                                          */
        /**************************************************************/
        /**************************************************************/
        /* we don't want to setup a full BITMAPINFO2 structure        */
        /* all we want is the first 5 fields                          */
        /*      ULONG    cbFix                                        */
        /*      ULONG    cx,cy                                        */
        /*      USHORT   cPlanes,cBitCount                            */
        /* This comes to a total of 16 bytes                          */
        /**************************************************************/
#define BITMAPINFOUSEDPART 16
        /**************************************************************/
        /* Defect 58460. Use MO_SSALLOC flag to prevent our private   */
        /* header being allocated.                                    */
        /**************************************************************/
        InfoParms = AllocateMemory( BITMAPINFOUSEDPART + ColourTableSize,
                                    MT_BITMAP_INFO2,
                                    MO_SSALLOC);
        if (InfoParms == NULL)
        {
            ExitDriver(NULL, FunN,
                       EDF_EXCLUSIVE | EDF_DC_NULL | EDF_DONT_CLEAN);
            return(FALSE);
        }


        /**************************************************************/
        /* Fill in the parameters in BITMAPINFO structure             */
        /**************************************************************/
        InfoParms->cbFix     = BITMAPINFOUSEDPART;
        InfoParms->cx        = (ULONG)ArgHandle->Info.Width;
        InfoParms->cy        = (ULONG)ArgHandle->Info.Height;
        InfoParms->cPlanes   = STANDARD_FORMAT_PLANES;
        if (ArgHandle->Info.BitCount == 16)
        {
            /**********************************************************/
            /* 16 bpp bitmaps are returned at 24 bpp.                 */
            /**********************************************************/
            InfoParms->cBitCount = 24;
        }
        else
        {
            InfoParms->cBitCount = ArgHandle->Info.BitCount;
        }

        /**************************************************************/
        /* Calculate memory required for new format and request it.   */
        /**************************************************************/

        /**************************************************************/
        /* External bitmap is padded to DWORDS so get the number of   */
        /* bytes per row now.                                         */
        /*                                                            */
        /* Defect 51573: We were previously doing this calculation    */
        /* before we adjusted the 16 bbp to 24 bbp. Therefore we      */
        /* calculated the amount of memory needed based on 16 bpp.    */
        /* We ran over the memory limit in this situation. JC (8/7/92)*/
        /**************************************************************/

        BytesPerRow = (4 * (((ULONG)InfoParms->cBitCount *
                             (ULONG)ArgHandle->Info.Width + 31)/32));

        RequiredMemory  = (ULONG)ArgHandle->Info.Height * BytesPerRow;


        /**************************************************************/
        /* Defect 58460. Use MO_SSALLOC flag to prevent our private   */
        /* header being allocated.                                    */
        /**************************************************************/
        ArgReturns->pBits = (ULONG) AllocateMemory( RequiredMemory,
                                                    MT_EXT_BITMAP,
                                                    MO_SSALLOC );

        /**************************************************************/
        /* If error allocating memory for bitmap de-allocate          */
        /* memory for BITMAPINFO structure and return error           */
        /**************************************************************/
        if ( ArgReturns->pBits == NULL )
        {
            FreeMemory(InfoParms);
            ExitDriver(NULL, FunN,
                       EDF_EXCLUSIVE | EDF_DC_NULL | EDF_DONT_CLEAN);
            return(FALSE);
        }

        /**************************************************************/
        /* Set the returned BITMAPINFO structure pointer              */
        /**************************************************************/
        ArgReturns->pInfo = (ULONG)InfoParms;

        /**************************************************************/
        /* Set up remaining parameters used by conversion function    */
        /**************************************************************/
        ptlStartPoint.x = 0;
        ptlStartPoint.y = 0;
        ScanLinesSet = ArgHandle->Info.Height;

        /**************************************************************/
        /* Transfer bits from the bitmap to application storage       */
        /* using a conversion function                                */
        /**************************************************************/
        ConvertIntToExt( (PBYTE)ArgReturns->pBits,
                         (PBITMAPINFO2)ArgReturns->pInfo,
                         ArgHandle,
                         &ptlStartPoint,
                         ScanLinesSet);

    }    /* end of return bitmap section                              */

    /******************************************************************/
    /* Free the memory used for the bitmap bits and the bitmap list   */
    /* entry                                                          */
    /******************************************************************/
    eddb_FreeMemForBitmap(ArgHandle);
    FreeMemory(ArgHandle);

    /******************************************************************/
    /* Return OK                                                      */
    /******************************************************************/
    ExitDriver(NULL, FunN, EDF_EXCLUSIVE | EDF_DC_NULL | EDF_DONT_CLEAN);

    return(TRUE);
}
