/*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 = PRDBGETP
 *
 * DESCRIPTIVE NAME =
 *
 *
 * VERSION
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS   prdb_GetPel
 *
 * 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_DEV
#define INCL_GPIPRIMITIVES
#define INCL_WINHEAP
#define INCL_GPIBITMAPS
#define INCL_GPIERRORS
#define INCL_GPILOGCOLORTABLE
#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_GPIERRORS
#undef INCL_GPILOGCOLORTABLE

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

#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 <prdbcone.h>
#include <prdconse.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 <prdgextf.h>
#include <prdyextf.h>

/* Word pascal prdz_EnterDriver(lpDCI); */

#define TFUNC "prdb_GetPel"
/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdb_GetPel                                            */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   See "OS/2 Technical Reference: I/O Subsytems and Device Drivers" */
/*                                                                    */
/*   hanDC         DcH;                                               */
/*   WcsPoint far *ArgXY;                                             */
/*   lpDCI         DCIData;                                           */
/*   ULONG         FunN;                                              */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function returns the colour of the pel specified by ArgXY.  */
/*   The return value is either a RGB value an index into the colour  */
/*   table for this DC Instance or NO_COLOUR_INDEX.                   */
/*                                                                    */
/**********************************************************************/
ULONG EXPENTRY prdb_GetPel ( hanDC     DcH,
                             WcsPoint *ArgXY,
                             lpDCI     DCIData,
                             ULONG     FunN )

{
    /******************************************************************/
    /* Local variables                                                */
    /******************************************************************/
/*  USHORT               Command; */   /* CON3201                     */
    ULONG                Command;      /* Command part of FunN        */
 /* BitmapListEntry far *ListEntry;       Pointer to a bitmap list    */
    BitmapListEntry     *ListEntry;    /* Pointer to a bitmap list    */
                                       /* entry              CON3201  */
    DevPoint             Coord;        /* Pel's position in device    */
                                       /* coordinates                 */
    ULONG                ByteOffset;   /* Offsets to the required byte*/
    USHORT               BitOffset;    /* and bit in the bitmap for   */
                                       /* this pel                    */
    BYTE                 PelValue;     /* The bits from the bitmap for*/
                                       /* this pel                    */
    BYTE                 Mask;         /* Mask to isolate the bits for*/
                                       /* the pel we are interested in*/
    ULONG                PhysRGB;      /* The physical colour for the */
                                       /* pel                         */
    USHORT               Bitcount;     /* The number of bitmap bits   */
                                       /* per pel                     */
    USHORT               i;            /* Loop control variable       */

    Command = FunN & 0xFFFF000L;
    TRACE8("prdbgetp", "Command", &Command, 1);

    /******************************************************************/
    /* Trace the input parameters                                     */
    /******************************************************************/
    TRACE8("prdbgetp", "FunN",  &FunN, 1);
    TRACE8("prdbgetp", "DcH",   &DcH, 1);
    TRACE8("prdbgetp", "DCIData",   &DCIData, 1);
    TRACE8("prdbgetp", "Parms", ArgXY, 2);

    /******************************************************************/
    /* Do entry processing                                            */
    /******************************************************************/
    if ( !prdz_EnterDriver(DCIData) )
        return(ERROR_NEG);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,50)
#endif

    /******************************************************************/
    /* Invalid for INFO or QUEUED STD DC's                            */
    /******************************************************************/
    if (( DCIData->DCIDCType == OD_INFO ) ||
        ((DCIData->DCIDCType == OD_QUEUED) &&
         (DCIData->DCIPdbInstance->PDBOutputType == IBMQSTD)))
    {
        LOGERR(TFUNC, "Invalid DC Type", FNULL, 0,PMERR_INCORRECT_DC_TYPE);
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,D0)
#endif
        return(ERROR_NEG);
    }

    /******************************************************************/
    /* Make sure there is a bitmap selected for this memory DC        */
    /******************************************************************/
 /* if ( !((PBYTE)ListEntry = DCIData->DCISelBitmap) ) */
    if ( !(ListEntry = (BitmapListEntry *)DCIData->DCISelBitmap) ) /*CON3201*/
    {
        LOGERR(TFUNC, "No Bitmap", FNULL, 0,PMERR_NO_BITMAP_SELECTED);
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,D0)
#endif
        return (ERROR_NEG);
    }

    /******************************************************************/
    /* Get the correct bitmap list entry - transform from world       */
    /* to device coordinates                                          */
    /******************************************************************/
    if ( prdg_Convert ( (PULONG)ArgXY,
                        (PULONG)&Coord,
                        COORD_WORLD,
                        COORD_DEVICE_WORD,
                        1L,
                        DcH,
                        Command) != OK)
    {
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,D0)
#endif
        return(ERROR_NEG);
    }

    /******************************************************************/
    /* Check if the desired coordinate is outside the bitmap.         */
    /******************************************************************/
    if (Coord.X >= (USHORT)ListEntry->Parms.Width ||
        Coord.Y >= (USHORT)ListEntry->Parms.Height)
    {
        /**************************************************************/
        /* Coordinate is outside the bitmap so log and return an error*/
        /**************************************************************/
        LOGERR("prdbsetp", "Pel outside bitmap", FNULL, 0,
                                                  PMERR_PEL_IS_CLIPPED);
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,D0)
#endif
        return(ERROR_NEG);
    }

    /******************************************************************/
    /* Use Getoffsets to get the byte and bit offsets to the required */
    /* pel.                                                           */
    /******************************************************************/
    (void) prdb_GetOffsets (ListEntry,
                            Coord.X,
                            Coord.Y,
                            &ByteOffset,
                            &BitOffset) ;
    TRACE4("prdbgetp", "ByteOffset", &ByteOffset, 1);
    TRACE4("prdbgetp", "BitOffset", &BitOffset,  1);

    /******************************************************************/
    /* Set up the Mask so that the BitCount least significant bits    */
    /* are set.                                                       */
    /******************************************************************/
    switch ( Bitcount = (USHORT)ListEntry->Parms.Bitcount )
    {
        case 1:
            Mask = (BYTE)0x01 << BitOffset;
            break;
        case 4:
            Mask = (BYTE)0xf0 >> (7 - BitOffset);
            break;
        case 8:
            Mask = 0xff;
            break;
    }

    /******************************************************************/
    /* Get the bits from the bitmap allowing for huge bitmaps         */
    /* shifting the required pel into the least significant bits.     */
    /******************************************************************/
    if (ListEntry->Huge == 0)
    {
        PelValue = ((ListEntry->Bitmap) [ByteOffset] & Mask);
    }
    else
    {
        PelValue = Mask & prdb_HugeGetByte( (PBYTE)ListEntry->Bitmap,
                                            ByteOffset);
    }

    /******************************************************************/
    /* shift the required pel into the least significant bits         */
    /******************************************************************/
    switch ( Bitcount )
    {
        case 1:
            PelValue >>= BitOffset;
            break;
        case 4:
            PelValue >>= (BitOffset - 3);
            break;
    }

    /******************************************************************/
    /* Now find the RGB value for this pel value                      */
    /******************************************************************/
    PhysRGB = ListEntry->DCTPtr->Colors[PelValue];

    /******************************************************************/
    /* If color table format is RGB mode then simply return the       */
    /* RGB colour from the colour table.                              */
    /******************************************************************/
    if (DCIData->DCIColFormat == LCOLF_RGB)
    {
        TRACE4("prdbgetp", "RGB Mode", FNULL, 0);
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,D0)
#endif
        return(PhysRGB);
    }

    /******************************************************************/
    /* If the colour table is index format then try to find a match   */
    /* in the DCIColorTable.  We use the physical colour table so     */
    /* we return an index which will actually produce the colour if   */
    /* selected.                                                      */
    /* Check RGB_RESET and RGB_CONTRAST first so that monochrome      */
    /* devices give sensible return                                   */
    /******************************************************************/
    if (PhysRGB == DCIData->DCIColorTable[0].PhysRGB)
    {
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,D0)
#endif
        return(0);
    }
    if (PhysRGB == DCIData->DCIColorTable[7].PhysRGB)
    {
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,D0)
#endif
        return(7);
    }
    for (i = 1; i < DCIData->DCIColTabSize; i++)
        if (PhysRGB == DCIData->DCIColorTable[i].PhysRGB)
        {
            prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,D0)
#endif
            return(i);
        }


    /******************************************************************/
    /* We haven't found a match for the RGB in the table in the DC    */
    /* Instance data so return NO_COLOUR_INDEX.                       */
    /******************************************************************/
    prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,D0)
#endif
    return (NO_COLOUR_INDEX);


}
#undef TFUNC
