/*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 = PRDBCREA
 *
 * DESCRIPTIVE NAME =
 *
 *
 * VERSION
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS  prdb_CreateBitmap
 *            prdb_DeviceCreateBitmap
 *
 * 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_GPIERRORS
#define INCL_GPIPRIMITIVES
#define INCL_WINHEAP
#define INCL_GPIBITMAPS
#define INCL_DOSMEMMGR
#include <os2.h>
#undef INCL_DOSPROCESS                  /* Convert to C/SET2    CON3201       */
#undef INCL_DOSSEMAPHORES
#undef INCL_GPIERRORS
#undef INCL_GPIPRIMITIVES
#undef INCL_WINHEAP
#undef INCL_GPIBITMAPS
#undef INCL_DOSMEMMGR

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

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

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

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

#include <prdbtyp1.h>
#include <prdbextf.h>
#include <prdcextf.h>
#include <prddcone.h>
#include <prdgextf.h>
#include <prdyextf.h>
#include <prduextf.h>
#include <prdbsize.h>

/******************************************************************************/
/*  A few externals...                                                        */
/******************************************************************************/
extern USHORT   prdd_HugeInc;
extern GDTType  GDT;
extern USHORT   DRIVER_TYPE;

/******************************************************************************/
/*  FUNCTION: prdb_CreateBitmap                                               */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  lpDCI              DCIData        Pointer to DDT                          */
/*  BOOL               CreateBand;    Creating band or not flag               */
/*  BitmapParms far *  BitmapFormat;  Bitmap parameters                       */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This function creates a bitmap of the specified size and format and sets  */
/*  it to the current background colour.  It returns the base address via     */
/*  Pbitmap and any huge increment necessary in Huge.                         */
/******************************************************************************/
/*   CON3201  Convert to C/SET2                                               */
BitmapListEntry * prdb_CreateBitmap( lpDCI        DCIData,
                                     BOOL         CreateBand,
                                     BitmapParms *BitmapFormat )

{
#define TFUNC "prdb_CreateBmap"

    /**************************************************************************/
    /*  Local Variables                                                       */
    /**************************************************************************/

    /**************************************************************************/
    /*  CON3201 : eliminate variables no longer needed for 32-bit             */
    /**************************************************************************/
#if 0
    USHORT                 NoOfSegments;/* Parameters to DosAllocHuge         */
    USHORT                 LastSegmentSize;/* or SSALLOCSEG                   */
    USHORT                 MaxNumSeg;
    USHORT                 i;          /* Loop control variable               */
    PBYTE                  Work;       /* Work variable used in initializing  */
                                       /* huge bitmaps                        */
#endif
    ULONG                  TotalBytes; /* Bitmap size in bytes                */
    USHORT                 DosResult;  /* Result of Dos memory alloc calls    */
#if 0
    PBYTE                  Selector;   /* Selector returned by Dos alloc calls*/
#endif
                                                                   /* CON3201 */
    PBYTE                  pBaseAddr;  /* Pointer returned by Dos alloc calls */
    BYTE                   Background; /* Byte defining background color to   */
                                       /* initialize bitmap to                */
/*  BitmapListEntry far *  NewEntry;      CON3201 remove far ref              */
    BitmapListEntry     *  NewEntry;   /* Pointer for allocating memory for   */
                                       /* the bitmap                          */
    USHORT                 Huge;
    USHORT                 BytesPerRow;/* bytes in one bitmap row             */
    lpDDTType              pDDT;       /* Pointer to DDT in PDB               */


    /**************************************************************************/
    /*  Set up the pointer to the DDT.                                        */
    /**************************************************************************/
    pDDT = &DCIData->DCIPdbInstance->DDT;

    /**************************************************************************/
    /*  PD00567 : We need to fudge the bitcount if this is a call from        */
    /*  prdj_MakeBand and the current printer is an IBM4019...                */
    /**************************************************************************/
    if ((CreateBand) && !((DRIVER_TYPE == DDT_IBM42XX_DRV) &&
        (DCIData->DCIPdbInstance->PrinterType == IBM_4224_COLOR)))
    {
        BitmapFormat->Bitcount = 1;
    }

    /**************************************************************************/
    /*  Work out total number of bytes needed for bitmap                      */
    /**************************************************************************/
    BytesPerRow = (USHORT)((BitmapFormat->Width *
                            BitmapFormat->Bitcount + 31) / 32) * 4;
    TotalBytes = BytesPerRow * BitmapFormat->Height;
    TRACE4(TFUNC, "Total Bytes", &TotalBytes, 1);

    /**************************************************************************/
    /*  CON3201 : don't need any of the following for 32-bit                  */
    /**************************************************************************/
#if 0
    /**************************************************************************/
    /*  Work out how many segments this is                                    */
    /**************************************************************************/
    NoOfSegments    = (USHORT) (TotalBytes / 65536);
    LastSegmentSize = (USHORT) (TotalBytes % 65536);
    MaxNumSeg       = 0;
    TRACE4(TFUNC, "No. of Segs", &NoOfSegments, 1);
    TRACE4(TFUNC, "Last seg size", &LastSegmentSize, 1);
    if ((NoOfSegments == 0) || ((NoOfSegments == 1) && (LastSegmentSize == 0)))
    {

        /**********************************************************************/
        /*  The bitmap will fit in one segment so use SSALLOCSEG.             */
        /**********************************************************************/
        DosResult = SSALLOCSEG(LastSegmentSize, &SELECTOROF(Selector),
                               SHARED_HEAP);

        /**********************************************************************/
        /*  And show that it has only one segment by setting Huge to 0.       */
        /**********************************************************************/
        Huge = 0;
    }
    else
    {

        /**********************************************************************/
        /*  The bitmap requires more than one segment so use DosAllocHuge.    */
        /*                                                                    */
        /*     DosResult = DosAllocHuge(NoOfSegments, LastSegmentSize,        */
        /*                              &SELECTOROF(Selector), MaxNumSeg (=0),*/
        /*                              SHARED_HEAP );                        */
        /*                                                                    */
        /*  No; use SSAllocHuge.  This has NoOfSegments parameter equal to the*/
        /*  TOTAL number of segments, including the last, non- 64K segment.   */
        /**********************************************************************/
        MaxNumSeg = NoOfSegments;
        if (LastSegmentSize != 0)
            MaxNumSeg++;
        DosResult = SSALLOCHUGE(NoOfSegments, LastSegmentSize,
                                &SELECTOROF(Selector), MaxNumSeg, SHARED_HEAP);
        TRACE4(TFUNC, "DosResult of alloc", &DosResult, 1);
        Huge = prdd_HugeInc;
    }
#endif
    DosResult = SafeSSALLOCMEM(&pBaseAddr, TotalBytes, 0);        /* CON3201 */
    if (DosResult != DOS_OK)
    {

        /**********************************************************************/
        /*  Return and log an error if any of the Dos calls have failed       */
        /**********************************************************************/
        LOGDOSERR(TFUNC, "Error in DOSALLOC", &DosResult, 1, DosResult);
        return(ERROR_ZERO);
    }
 /* OFFSETOF(Selector) = 0;  CON3201 - don't need this */

    /**************************************************************************/
    /*  We are initialising the whole bitmap to the background colour - i.e.  */
    /*  CLR_WHITE.                                                            */
    /**************************************************************************/
    if (BitmapFormat->Bitcount == 1)
    {
        Background = prdc_ColorToPelBits((ULONG)CLR_WHITE, DCIData,
                                          GDT.GDT11ColorTable);
        if (Background == 1)
            Background = 0xFF;
    }
    else
    {
        Background = prdc_RGBColorToPelBits(0x00FFFFFF, GDT.GDT41ColorTable);
        Background = (Background << 4) + Background;
    }
    TRACE4(TFUNC, "background byte", &Background, 1);

    /**************************************************************************/
    /* CON3201 : Don't need the following code.                               */
    /*           The memset has been changed to handle a long rather than     */
    /*           a short lentgth.                                             */
    /**************************************************************************/
#if 0
    /**************************************************************************/
    /*  Initialise the bitmap by filling it with the background color.        */
    /*  Pbitmap is a pointer to the bitmap handle although it is cast as a    */
    /*  Dptr so we cast it to a Dword far * and then pick up the handle to the*/
    /*  bitmap by dereferencing this and then cast the result of this (the    */
    /*  bitmap handle) to a void far * for the memset.                        */
    /**************************************************************************/
    if (Huge == 0)
    {

        /**********************************************************************/
        /*  It requires two memsets because the count for memset must be <=   */
        /*  65535 and TotalBytes may be upto 65536.                           */
        /**********************************************************************/
        (VOID)prdu_memset((PBYTE)Selector, Background, 1);
        (VOID)prdu_memset(((PBYTE)Selector + 1), Background,
                          (USHORT)(TotalBytes-1) );
    }
    else
    {

        /**********************************************************************/
        /*  This is a huge bitmap so have to memset segment by segment.  Note */
        /*  that NoOfSegments is the number of complete segments ie it does   */
        /*  not include the last one.  Set work to point to the start of the  */
        /*  first segment.                                                    */
        /**********************************************************************/
/*      Work = (VOID far *)Selector;  */
        Work = (VOID *)Selector;                                   /* CON3201 */
        for (i = 0; i < NoOfSegments; i++)
        {

            /******************************************************************/
            /*  To clear a whole segment have to do 2 memsets because 'count' */
            /*  parameter has a maximum value of 65535.                       */
            /******************************************************************/
            (VOID)prdu_memset((PBYTE)Work, Background, 1);
            (VOID)prdu_memset((PBYTE)Work + 1, Background, 65535);

            /******************************************************************/
            /*  Use the huge increment to move to the next segment.           */
            /******************************************************************/
            SELECTOROF(Work) += Huge;
        }

        /**********************************************************************/
        /*  Now do the final segment                                          */
        /**********************************************************************/
        if (LastSegmentSize != 0)
        {
            (VOID)prdu_memset((PBYTE)Work, Background, LastSegmentSize);
        }
    }
#endif
    (VOID)prdu_memset(pBaseAddr, Background, TotalBytes);          /* CON3201 */

    /**************************************************************************/
    /*  Make a bitmap info structure asscociated with this new bitmap         */
    /**************************************************************************/
/*  if (prdg_AllocGlobalHeapItem(LIST_ENTRY_SIZE, (PBYTE far *)&NewEntry) != OK)*/
                                                                   /* CON3201 */
    if (prdg_AllocGlobalHeapItem(LIST_ENTRY_SIZE, (PBYTE *)&NewEntry) != OK)
        return(ERROR_ZERO);

    /**************************************************************************/
    /*  Now initialise the list entry.  These values are either taken from the*/
    /*  parameters to the call or set to defaults.                            */
    /**************************************************************************/
 /* NewEntry->Bitmap         = Selector; */
    NewEntry->Bitmap         = pBaseAddr;                          /* CON3201 */
    NewEntry->DCHandle       = FNULL;
    NewEntry->Parms.Width    = BitmapFormat->Width;
    NewEntry->Parms.Height   = BitmapFormat->Height;
    NewEntry->Parms.Planes   = BitmapFormat->Planes;
    NewEntry->Parms.Bitcount = BitmapFormat->Bitcount;
 /* NewEntry->Huge           = Huge; */
    NewEntry->Huge           = 0;                                  /* CON3201 */

    /**************************************************************************/
    /*  The bitmap is padded to Dword boundaries.                             */
    /**************************************************************************/
    NewEntry->Parms.BytesPerRow = BytesPerRow;
    NewEntry->BandXOrigin       = 0;
    NewEntry->BandYOrigin       = 0;

    /**************************************************************************/
    /*  Set the pointer to the correct colour table from the GDT.             */
    /**************************************************************************/
    if (NewEntry->Parms.Bitcount == 1)
    {
        NewEntry->DCTPtr = GDT.GDT11ColorTable;
    }
    else
    {
        NewEntry->DCTPtr = GDT.GDT41ColorTable;
    }

    /**************************************************************************/
    /*  the bitmap is initially unlocked                                      */
    /**************************************************************************/
    NewEntry->BMLocked = FALSE;
    return(NewEntry);
}
#undef TFUNC

/******************************************************************************/
/*  FUNCTION: prdb_DeviceCreateBitmap                                         */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  See "OS/2 Technical Reference: I/O Subsystems and Device Drivers"         */
/*                                                                            */
/*  hanDC              DcH;                                                   */
/*  PBITMAPINFOHEADER  lpInfoHdr;                                             */
/*  ULONG              ArgUsage;                                              */
/*  PBYTE              ArgBits;                                               */
/*  PBITMAPINFO        lpInitInfo;                                            */
/*  lpDCI              DCIData;                                               */
/*  ULONG              FunN;                                                  */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This function creates a bit map according to the parameters at lpInfoHdr. */
/*  If required it will also initialize it using the bitmap at ArgBits and the*/
/*  information at lpInitInfo.                                                */
/******************************************************************************/
/*   CON3201  Convert to C/SET2                                               */
ULONG EXPENTRY prdb_DeviceCreateBitmap( hanDC              DcH,
  /* CON3201 GRE CHANGE */              PBITMAPINFOHEADER2 lpInfoHdr,
                                        ULONG              ArgUsage,
                                        PBYTE              ArgBits,
  /* CON3201 GRE CHANGE */              PBITMAPINFO2       lpInitInfo,
                                        lpDCI              DCIData,
                                        ULONG              FunN )

{
#define TFUNC "prdb_DevCreBmap"

    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
    pBMListEntry  ListEntry;           /* Pointer to added list entry         */
    BitmapParms   NewParms;            /* New bitmap parameters               */
    lpDDTType     pDDT;                /* Pointer to DDT in PDB               */
    USHORT        ScanLines;           /* No. of lines to initialise          */

    /**************************************************************************/
    /*  TRACE8 the function parameters                                        */
    /**************************************************************************/
    TRACE8(TFUNC, "DcH", &DcH, 1);
    TRACE8(TFUNC, "InfoHdr", &lpInfoHdr, 1);
    TRACE8(TFUNC, "Usage", &ArgUsage, 1);
    TRACE8(TFUNC, "Bits", ArgBits, 1);
    TRACE8(TFUNC, "Info Table", lpInitInfo, 1);
    TRACE8(TFUNC, "DCIData", &DCIData, 1);
    TRACE8(TFUNC, "FuncNo", &FunN, 1);

    /**************************************************************************/
    /*  PD00256 : Check that the length of the BITMAPINFO structure is Ok     */
    /*                                                                        */
    /*  PD00423 : Have to also see if perhaps the app has passed in the       */
    /*  size, mistaking the BITMAPINFOHEADER structure for the BITMAPINFO     */
    /*  structure.  These two structures are identical except that the latter */
    /*  also contains an RGB structure at the end of the structure, making it */
    /*  3 bytes longer.  Since this error reporting stuff on this field is a  */
    /*  bit esoteric anyway, it really shouldn't cause us to crash and burn.  */
    /**************************************************************************/
    if ((ArgUsage & CBM_INIT) &&
        ((lpInitInfo->cbFix != sizeof(BITMAPINFO)) &&
         (lpInitInfo->cbFix != sizeof(BITMAPINFOHEADER)) &&
        ((lpInitInfo->cbFix < MIN_BITMAPINFO2)) ||
         (lpInitInfo->cbFix > sizeof(BITMAPINFOHEADER2))))
/*****************************************************************************/
/* CON3201 - Due to changes in GRE the above check must be made              */
/*      ((lpInitInfo->cbFix != sizeof(BITMAPINFO)) &&                        */
/*       (lpInitInfo->cbFix != sizeof(BITMAPINFOHEADER))))                   */
/*****************************************************************************/

    {
        LOGERR(TFUNC, "invalid BMINFO", FNULL, 0, PMERR_INV_INFO_TABLE);
        return (ERROR_ZERO);
    }

    /**************************************************************************/
    /*  PD00256 : Check that the length of the BITMAPINFOHEADER structure is  */
    /*  Ok                                                                    */
    /**************************************************************************/
/* CON3201 - MORE GRE CHANGES                            */
/*  if (lpInfoHdr->cbFix != sizeof(BITMAPINFOHEADER2))   */
    if ((lpInfoHdr->cbFix < MIN_BITMAPINFOHEADER) ||
         (lpInfoHdr->cbFix > sizeof(BITMAPINFOHEADER2)))
    {
        LOGERR(TFUNC, "invalid BMINFOHEADER", FNULL, 0,
               PMERR_INV_LENGTH_OR_COUNT);
        return(ERROR_ZERO);
    }

    /**************************************************************************/
    /*  If we are asked to create a bitmap with an x or y dimension of 0 then */
    /*  log and return an error.                                              */
    /*  PD00257 : Width and height have a maximum value of 64k and also 0 x 0 */
    /*  is a valid dimension as it is a one bit bitmap with subscripts (0,0). */
    /**************************************************************************/
    if ((lpInfoHdr->cx < 0) || (lpInfoHdr->cx > 0x03FFF) ||
        (lpInfoHdr->cy < 0) || (lpInfoHdr->cy > 0x03FFF))
    {
        LOGERR(TFUNC, "Bad bitmap dimension", FNULL, 0,
               PMERR_INV_BITMAP_DIMENSION);
        return(ERROR_ZERO);
    }

    /**************************************************************************/
    /*  If bitmap is to be initialised then check the format parameters (done */
    /*  here to avoid allocating and then freeing memory)                     */
    /**************************************************************************/
    if ((ArgUsage & CBM_INIT) &&
        ((lpInitInfo->cPlanes != 1) ||
         (lpInitInfo->cBitCount != 1 && lpInitInfo->cBitCount != 4 &&
          lpInitInfo->cBitCount != 8 && lpInitInfo->cBitCount != 24)))
    {
        LOGERR(TFUNC, "Not standard format", FNULL, 0, PMERR_INV_INFO_TABLE);
        return(ERROR_ZERO);
    }

    /******************************************************************/
    /* So entry processing                                            */
    /******************************************************************/
#ifdef PRD_TIMING
    DEKHOOK0(A,7,46)
#endif
/*  prdz_EnterDriver(DCIData);  */

    /**************************************************************************/
    /*  Set up DDT pointer from DC Instance data.                             */
    /**************************************************************************/
    pDDT = &DCIData->DCIPdbInstance->DDT;

    /**************************************************************************/
    /*  We set up the number of planes to be the internal format number of    */
    /*  planes, regardless of what the caller wants.                          */
    /**************************************************************************/
    NewParms.Planes = pDDT->DDTFormat->Planes;

    /**************************************************************************/
    /*  PD00567 : We need to set the bitcount.  If we're working on a         */
    /*  monochrome device (4019, 4201, etc.), we will now create a 4,1 bitmap */
    /*  when we are asked to create a source bitmap.  This is to allow us to  */
    /*  greyscale the source bitmap at prdb_DoBitBlt() time.  However, in the */
    /*  case where we are creating a target bitmap, we still need to create a */
    /*  1,1 bitmap so that we will print properly.  The CBM_INIT flag in the  */
    /*  ArgUsage parameter is the basic indicator as to whether or not the    */
    /*  request is for a source bitmap or a target bitmap - if CBM_INIT is    */
    /*  set, this is a request for a source bitmap.                           */
    /*                                                                        */
    /*  This is made even more interesting by the fact that the engine will   */
    /*  simulate stretched or compressed bitmaps by creating a new bitmap     */
    /*  without setting the CBM_INIT flag, opting rather to use GetBitmapBits */
    /*  and SetBitmapBits to transfer the bitmap rather than passing an       */
    /*  initialization bitmap pointer in at bitmap creation time.  In this    */
    /*  case, we need to supply the engine with a 4,1 bitmap.  We can detect  */
    /*  this condition with a DCIStateFlags flag.                             */
    /*                                                                        */
    /*  However, we need to honor the request for a 1,1 source bitmap even    */
    /*  though we could override the request and simply create a 4,1 bitmap.  */
    /*  This will do two things: first, it will allow us to avoid the         */
    /*  additional overhead of the greyscaled source bitmap code which would  */
    /*  require extensive code to properly handle the case where a 1,1 bitmap */
    /*  was requested; second, it will improve overall performance for those  */
    /*  apps that intermix various bitmap formats on a page or throughout a   */
    /*  job (DeScribe, Aldus PageMaker, etc.).                                */
    /*                                                                        */
    /*  With a little luck, we can balance on the knife's edge and all of this*/
    /*  will work...                                                          */
    /*                                                                        */
    /*  PD00805 : Changes an OR to an AND to create a 4,1 bitmap even if the  */
    /*  CBM_INIT flag has not been set...                                     */
    /**************************************************************************/
    if (!((DRIVER_TYPE == DDT_IBM42XX_DRV) &&
          (DCIData->DCIPdbInstance->PrinterType == IBM_4224_COLOR)))
    {

        /**********************************************************************/
        /*  The printer is monochrome... need to be careful here...           */
        /**********************************************************************/
        if (lpInfoHdr->cBitCount == 1)
        {

            /******************************************************************/
            /*  The bitmap is monochrome, so create a 1,1 bitmap...           */
            /******************************************************************/
            NewParms.Bitcount = 1;
        }
        else
        {

            /******************************************************************/
            /*  The bitmap is color, so create a 4,1 bitmap...  we'll         */
            /*  greyscale this later...                                       */
            /******************************************************************/
            NewParms.Bitcount = pDDT->DDTFormat->BitCount;
        }
    }
    else
    {

        /**********************************************************************/
        /*  The printer is color...                                           */
        /**********************************************************************/
        NewParms.Bitcount = pDDT->DDTFormat->BitCount;
    }

    /**************************************************************************/
    /*  Set up parameters for creating bitmap having already validated these  */
    /*  parameters.                                                           */
    /**************************************************************************/
    NewParms.Width  = lpInfoHdr->cx;
    NewParms.Height = lpInfoHdr->cy;
    TRACE4(TFUNC, "Params Wi,He,Pl,Bi", &NewParms, 4);

    /**************************************************************************/
    /*  Get the memory needed for the bitmap and return any error.  The second*/
    /*  parameter being set to FALSE indicates that this is not the band being*/
    /*  set up so that CreateBitmap knows that it needs to initialise the     */
    /*  bitmap to CLR_FALSE if this is a monochrome bitmap or CLR_WHITE is    */
    /*  this is a color bitmap.                                               */
    /**************************************************************************/
    if (!(ListEntry = prdb_CreateBitmap(DCIData, FALSE, &NewParms)))
    {
/*      prdm_LeaveDriver(DCIData);   */
#ifdef PRD_TIMING
    DEKHOOK0(A,7,C6)
#endif
        return (ERROR_ZERO);
    }

    /**************************************************************************/
    /*  Set up the DC origin to be default                                    */
    /**************************************************************************/
    ListEntry->XOrigin = 0;
    ListEntry->YOrigin = 0;

    /**************************************************************************/
    /*  If the caller wanted a mono bitmap but the driver creates a color     */
    /*  bitmap set the "mono bitmap requested" flag on; else set to off.  This*/
    /*  flag should only be checked for memory bitmaps.                       */
    /**************************************************************************/
    if ((lpInfoHdr->cBitCount == 1) && (ListEntry->Parms.Bitcount != 1))
        ListEntry->Parms.MonBmapReq = TRUE;
    else
        ListEntry->Parms.MonBmapReq = FALSE;

    /**************************************************************************/
    /*  If the caller wanted a color bitmap but the driver creates a mono     */
    /*  bitmap set the "colour bitmap requested" flag on; else set to off.    */
    /*  This flag should only be checked for memory bitmaps.                  */
    /**************************************************************************/
    if ((lpInfoHdr->cBitCount != 1) && (ListEntry->Parms.Bitcount == 1))
        ListEntry->ColBmapReq = TRUE;
    else
        ListEntry->ColBmapReq = FALSE;

    /**************************************************************************/
    /*  PD00567 : Need to init the ColorDetected flag...  will only be set if */
    /*  the bitmap is a source bitmap and color nibbles (4,1 bitmap only) are */
    /*  encountered.                                                          */
    /*                                                                        */
    /*  Note that for the time being we are initializing to TRUE if we've     */
    /*  created a 4,1 bitmap as this is the trigger in prdb_DoBitBlt() that   */
    /*  sends us in to greyscale the source bitmap.  Ultimately, we want to   */
    /*  run a color detection routine here to weed out the monochrome 4,1     */
    /*  bitmap.  However, this implies that we are capable of converting the  */
    /*  4,1 bitmap to 1,1 without going through the greyscaling code.  At this*/
    /*  time, we don't have that path through the prdb_GreyscaleSourceBitmap()*/
    /*  code.  Obviously it would be faster, but by how much is unclear.      */
    /*                                                                        */
    /*  Another note: If the bitmap we're creating is for the case where we're*/
    /*  creating a source color bitmap for greyscaling, we need to fudge the  */
    /*  ColBmapReq flag so that the SrcCopyMode is set up correctly later on  */
    /*  in the prdb_BitBlt() code.  Otherwise, the bitmap will be inverted... */
    /*  not a        sight.                                                   */
    /**************************************************************************/
    if (!((DRIVER_TYPE == DDT_IBM42XX_DRV) &&
          (DCIData->DCIPdbInstance->PrinterType == IBM_4224_COLOR)) &&
        (ListEntry->Parms.Bitcount == 4))
    {
        ListEntry->ColorDetected = TRUE;
        ListEntry->ColBmapReq    = TRUE;
    }
    else
    {
        ListEntry->ColorDetected = FALSE;
    }

    /**************************************************************************/
    /*  The CBM_INIT flag signifies that we have to initialise the bitmap from*/
    /*  the bitmap supplied in the parameters to the function - ArgBits &     */
    /*  lpInitInfo (this is *definitely* a source bitmap)                     */
    /**************************************************************************/
    if (ArgUsage & CBM_INIT)
    {

        /**********************************************************************/
        /*  Work out how many lines to transfer.  The values of cy in         */
        /*  lpInitInfo and in lpInfoHdr should be the same; if they are not,  */
        /*  we use the minimum of them.                                       */
        /**********************************************************************/
        ScanLines = (USHORT)min(ListEntry->Parms.Height, lpInitInfo->cy);

        /**********************************************************************/
        /*  Call ConvertExttoInt to convert the supplied bitmap.  Note that we*/
        /*  do not bother with updating bounds, because will will probably be */
        /*  filling the whole of the bitmap.                                  */
        /*                                                                    */
        /*  PD00400 : GWD.  Add DCIData to call                               */
        /**********************************************************************/
        prdb_ConvertExttoInt(ListEntry, ArgBits, lpInitInfo, (ULONG) 0,
                             ScanLines, DCIData);
    }

    /**************************************************************************/
    /*  Return the bitmap handle.                                             */
    /**************************************************************************/
/*  prdm_LeaveDriver(DCIData);   */
#ifdef PRD_TIMING
    DEKHOOK0(A,7,C6)
#endif
    return((ULONG)ListEntry);
}
#undef TFUNC
