/*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          = EDDBSUBR                                       */
/*                                                                    */
/*   Description     = Display Device Driver Subroutines for Bitmap   */
/*                     Functions:                                     */
/*                     AllocMemForBitmap,                             */
/*                     FreeMemForBitmap.                              */
/*                                                                    */
/*   Function        = AllocMemForBitmap allocates memory for a       */
/*                     Bitmap and initialises it to a colour; it can  */
/*                     also allocate memory for a bitmap header.      */
/*                     FreeMemForBitmap frees the memory for a bitmap */
/*                     and a bitmap header.                           */
/*                                                                    */
/*   Reference       = Winthorn Functional Specification              */
/*                     Device Driver Interface Specification          */
/*                     Display Device Driver Design Specification     */
/*                                                                    */
/*                                                                    */
/**********************************************************************/
#define INCL_DEV
#define INCL_DDIMISC
#include <eddinclt.h>

#include <eddbcone.h>
#include <eddhcone.h>
#include <eddecone.h>

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

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

#include <eddhcone.h>
#include <eddhtype.h>
#include <eddhmacr.h>

#include <memman.h>
#ifdef VRAMPTR
#include <eddncach.h>
#endif /* VRAMPTR */

extern SHORT                  softDrawInUse;

extern DDTType                DDT;

extern ULONG                  pPhunkPhys;
extern PVOID                  pPhunkVirt;
#ifndef VRAMPTR
extern pBitmapHeader          cached_pattern; DELETE
#endif /* ndef VRAMPTR */


/**********************************************************************/
/*                                                                    */
/*   AllocMemForBitmap acquires memory for a bitmap                   */
/*                                                                    */
/*   On entry the following fields of the bitmap header must be       */
/*   already initialised:                                             */
/*      Info.Width                                                    */
/*      Info.Height                                                   */
/*      Info.BitCount                                                 */
/*                                                                    */
/*   Other fields are initialised by this function                    */
/*                                                                    */
/**********************************************************************/

USHORT eddb_AllocMemForBitmap (pBitmapHeader  pHeader)

{

    /******************************************************************/
    /* Initialise the header as much as possible at this stage.       */
    /******************************************************************/
    pHeader->DCHandle = FNULL;
    pHeader->Info.HWHeight = pHeader->Info.Height - (USHORT)1;
#ifdef VRAMPTR
    pHeader->bm_cache_slot = BITMAP_NOT_CACHED;
#endif /* VRAMPTR */

    if ( pHeader->Info.BitCount == 1 )
    {
        pHeader->Info.HWFormat = ONE_BIT_PER_PEL;
        pHeader->Info.HWWidth  =
                    (USHORT)((((ULONG)pHeader->Info.Width + 7) & 0xfff8) - 1);
    }
    else if (pHeader->Info.BitCount == 8)
    {
        pHeader->Info.HWFormat = EIGHT_BITS_PER_PEL;
        pHeader->Info.HWWidth  = pHeader->Info.Width - (USHORT)1;
    }
    else if (pHeader->Info.BitCount == 4)
    {
        pHeader->Info.HWFormat = FOUR_BITS_PER_PEL;
        pHeader->Info.HWWidth  =
               (USHORT)((((ULONG)pHeader->Info.Width + 1) & 0xfffe) - 1);
    }
    else if (pHeader->Info.BitCount == 16)
    {
        pHeader->Info.HWFormat = SIXTEEN_BITS_PER_PEL;
        pHeader->Info.HWWidth  = pHeader->Info.Width - (USHORT)1;
    }

    #ifdef   BPP24
    else if (pHeader->Info.BitCount == 24)
    {
        pHeader->Info.HWFormat = TWENTYFOUR_BITS_PER_PEL;
        pHeader->Info.HWWidth  = pHeader->Info.Width - (USHORT)1;
    }
    #endif

    /******************************************************************/
    /* Work out the number of bytes per line.                         */
    /******************************************************************/
    pHeader->BytesPerLine =
            (USHORT)((((ULONG)pHeader->Info.Width *
                       (ULONG)pHeader->Info.BitCount + 7)/8 ));

    /******************************************************************/
    /* Zero the bitmap header physical address field so we know it    */
    /* hasn't been locked.                                            */
    /******************************************************************/
    pHeader->BMPhys = FNULL;

    /******************************************************************/
    /* Fill in the bitmap information in the header.                  */
    /******************************************************************/

    /**************************************************************/
    /* Calculate the amount of memory we need to allocate         */
    /**************************************************************/
    pHeader->BMSize = pHeader->Info.Height * pHeader->BytesPerLine;

    /******************************************************************/
    /* Get the memory for the bitmap.                                 */
    /******************************************************************/
    /******************************************************************/
    /* To make things easier for the software drawing code, we will   */
    /* allocate an extra byte at each side of the bitmap. This avoids */
    /* traps which would otherwise occur when accessing the first and */
    /* last pels of the bitmap as word quantities.                    */
    /******************************************************************/
    pHeader->Bitmap = AllocateMemory( pHeader->BMSize + 2,
                                      MT_BITMAP,
                                      MO_SHARED );
    if (pHeader->Bitmap == NULL)
    {
        /**************************************************************/
        /* The memory allocation failed.                              */
        /**************************************************************/
        return(ERROR_ZERO);
    }

    /******************************************************************/
    /* Adjust this value to allow for the required extra initial      */
    /* byte which the software drawing code needs.                    */
    /******************************************************************/
    pHeader->Bitmap = pHeader->Bitmap + 1;

    /******************************************************************/
    /* Allocation was sucessful so return OK.                         */
    /******************************************************************/
    return (OK);
}

/**********************************************************************/
/*                                                                    */
/* FreeMemForBitmap frees the memory for the given bitmap, when       */
/* passed its bitmap handle.                                          */
/*                                                                    */
/**********************************************************************/

VOID eddb_FreeMemForBitmap (pBitmapHeader   pBMHeader)

{

#ifdef SDBM20
#ifdef FIREWALLS
    /******************************************************************/
    /* If we are trying to free the PHUNK then something is WRONG!!!  */
    /******************************************************************/
    if ((pBMHeader->Bitmap == pPhunkVirt) ||
        (pBMHeader->BMPhys == pPhunkPhys))
    {
        haltproc();
    }
#endif /* FIREWALLS */
#endif /* SDBM20 */
#ifndef VRAMPTR
    if ( cached_pattern == pBMHeader )
    {
        cached_pattern = NULL;
    }
#endif /* ndef VRAMPTR */

#ifdef VRAMPTR
    /******************************************************************/
    /* If this bitmap is cached in VRAM then release the cache slot.  */
    /******************************************************************/
    if ( pBMHeader->bm_cache_slot != BITMAP_NOT_CACHED )
    {
      evict_cached_bitmap(pBMHeader->bm_cache_slot);
    }
#endif /* VRAMPTR */

    /******************************************************************/
    /* Free the bitmap memory.                                        */
    /******************************************************************/
    /******************************************************************/
    /* Remember that when we allocated the memory for the bitmap we   */
    /* allocated an extra byte each side of the bitmap to make things */
    /* easier for the software drawing code. We must take this into   */
    /* account here otherwise FreeMemory will not be able to find its */
    /* memory object info block correctly.                            */
    /******************************************************************/
    FreeMemory( pBMHeader->Bitmap - 1 );

}

/**********************************************************************/
/* Allocate memory for a bitmap header structure.                     */
/**********************************************************************/
pBitmapHeader eddb_AllocBitmapHeader(VOID)
{
    pBitmapHeader      pNewHeader;    /* ptr to the new bitmap header */

    /******************************************************************/
    /* Allocate memory for the bitmap header                          */
    /******************************************************************/
    pNewHeader = AllocateMemory(  sizeof(BitmapHeader),
                                  MT_BITMAP_HEADER,
                                  MO_SHARED );

    /******************************************************************/
    /* Return the alloc'd pointer which may be null if the alloc      */
    /* failed.                                                        */
    /******************************************************************/
    return(pNewHeader);

} /* AllocBitmapHeader */


/**********************************************************************/
/* fills the bitmap defined by BMHeader with the BackgroundColour     */
/* MEBTEMP:                                                           */
/*   Seems like a     to me - this won't work at 16bpp!               */
/**********************************************************************/
VOID eddb_FillBitmap(pBitmapHeader   BMHeader,
                     BYTE            BackgroundColour)
{
    /******************************************************************/
    /* All small bitmaps: initialise the data                         */
    /******************************************************************/
    memset( BMHeader->Bitmap,
            BackgroundColour,
            BMHeader->Info.Height * BMHeader->BytesPerLine
          );
} /* FillBitmap */
