/*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 = PRDCQERY
 *
 * DESCRIPTIVE NAME =
 *
 *
 * VERSION
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS  prdc_QueryRealColors
 *            prdc_QueryNearestColor
 *            prdc_QueryColorIndex
 *            prdc_QueryRGBColor
 *
 * ENTRY POINTS:
 *
 * DEPENDENCIES:
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/

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

#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                    /* CON3201 */

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

#include <prdcextf.h>
#include <prdgextf.h>
#include <prdyextf.h>

extern DefaultColorTableType DefaultColorTable;
/* USHORT pascal prdz_EnterDriver(lpDCI);  */

/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdc_QueryRealColors                                   */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   See "OS/2 Technical Reference: I/O Subsytems and Device Drivers" */
/*                                                                    */
/*   hanDC         DcH;                                               */
/*   ULONG         ArgOptions;                                        */
/*   ULONG         ArgStart;                                          */
/*   ULONG         ArgCount;                                          */
/*   ULONG     *   ArgArray;                                          */
/*   lpDCI         DCIData;                                           */
/*   ULONG         FunN;                                              */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function returns the real colours available to the printer. */
/*   On a monochrome printer this will be black and white.            */
/*                                                                    */
/*   CHANGES:                                                         */
/*                                                                    */
/*   This function should handle non-monochrome devices without change*/
/*   as long as the DDT colour table has been set up correctly.       */
/*                                                                    */
/**********************************************************************/
ULONG prdc_QueryRealColors (  hanDC    DcH,
                              ULONG    ArgOptions,
                              ULONG    ArgStart,
                              ULONG    ArgCount,
                              ULONG  * ArgArray,
                              lpDCI    DCIData,
                              ULONG    FunN)

{
#define TFUNC "prdc_QueryRealColors"
    /******************************************************************/
    /* Local variables                                                */
    /******************************************************************/
    USHORT      i;             /* Loop variable                       */
    USHORT      j;             /* Loop variable                       */
    USHORT      lcCount;       /* Number of values returned           */
    USHORT      MaxCount;      /* Maximum number of values which can  */
                               /* be returned (this depends on the    */
                               /* size of the array available to      */
                               /* return them in).                    */
    USHORT      Match;         /* Index in DCIColorTable for a        */
                               /* matched colour                      */
    lpDDTType   pDDT;          /* pointer to DDT in PDB               */


    /******************************************************************/
    /* Trace the parameters                                           */
    /******************************************************************/
    TRACE8(TFUNC, "&Array", &ArgArray, 1);
    TRACE8(TFUNC, "Count", &ArgCount, 1);
    TRACE8(TFUNC, "Start", &ArgStart, 1);
    TRACE8(TFUNC, "Options", &ArgOptions, 1);
    TRACE8(TFUNC, "DcH", &DcH, 1);
    TRACE8(TFUNC, "&FunN", &FunN, 1);

    /******************************************************************/
    /* Do entry processing                                            */
    /******************************************************************/
    if (!prdz_EnterDriver(DCIData))
        return(ERROR_NEG);

#ifdef PRD_TIMING
    DEKHOOK0(A,7,1A)
#endif
    /******************************************************************/
    /* Set up pDDT                                                    */
    /******************************************************************/
    pDDT = &DCIData->DCIPdbInstance->DDT;

    /******************************************************************/
    /* PD00125 : check for invalid ArgCount                           */
    /******************************************************************/
    if ( (LONG)ArgCount < 0 )
    {
        LOGERR(TFUNC, "Invalid count", FNULL, 0,PMERR_INV_LENGTH_OR_COUNT);
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,9A)
#endif
        return((ULONG)ERROR_NEG);
    }

    /******************************************************************/
    /* Check for an invalid start (ie index beyond the number of      */
    /* colours available).                                            */
    /******************************************************************/
    if (ArgStart >= pDDT->DDTMaxColors )
    {
        LOGERR(TFUNC, "Bad Start", FNULL, 0,PMERR_INV_COLOR_START_INDEX);
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,9A)
#endif
        return((ULONG)ERROR_NEG);
    }

    /******************************************************************/
    /* Calculate the maximum number of values which we can return     */
    /* taking the size of the space available for returned values and */
    /* the format we must return the values in into account.          */
    /******************************************************************/
    lcCount   = 0;
    MaxCount  = (USHORT) ArgCount;
    if (ArgOptions & LCOLOPT_INDEX)
        MaxCount -= MaxCount % 2;

    TRACE4(TFUNC, "MaxCount", &MaxCount, 1);

    /******************************************************************/
    /* If the colour table format is RGB mode then return the RGB     */
    /* values in the DDTDevColorTable (if LCOLOPT_INDEX is set then   */
    /* return the colour as the index as well).                       */
    /* This code will also handle the case where no index values (for */
    /* the logical colour table) are required.                        */
    /******************************************************************/
    if ((DCIData->DCIColFormat == LCOLF_RGB) ||
                                         !(ArgOptions & LCOLOPT_INDEX))
    {
        TRACE4(TFUNC, "RGB Mode", FNULL, 0);

        /**************************************************************/
        /* Go through the DDTDevColorTable until the end of it or all */
        /* the space available to return values in is used up.        */
        /**************************************************************/
        for (i = (USHORT)ArgStart; i < pDDT->DDTMaxColors &&
                                                lcCount < MaxCount; i++)
        {
            if (ArgOptions & LCOLOPT_INDEX)
            {
                /******************************************************/
                /* Return the RGB value as the index if in LCOLF_RGB  */
                /* mode and LCOLOPT_INDEX is set.                     */
                /******************************************************/
                ArgArray[lcCount++] = pDDT->DDTDevColorTable->Colors[i];
            }

            ArgArray[lcCount++] = pDDT->DDTDevColorTable->Colors[i];
        }

        /**************************************************************/
        /* Return the number of entries written to ArgArray           */
        /**************************************************************/
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,9A)
#endif
        return(lcCount);
    }
    /*.. if ((DCIData->DCIColFormat == LCOLF_RGB) || .no colour table.*/

    /******************************************************************/
    /* This code handles the case when an index is required and there */
    /* is a logical colour table (ie LCOLF_INDRGB or LCOLF_DEFAULT)   */
    /* For each colour in the DDTDevColorTable it finds the index to  */
    /* the first entry in the logical colour table with a physical    */
    /* colour equal to this colour and returns it along with the RGB  */
    /* values from DDTDevColorTable in the data at ArgArray.  If no   */
    /* match is found in the logical colour table then a special      */
    /* index (CLR_NOINDEX) is returned.                               */
    /******************************************************************/
    for ( i = (USHORT)ArgStart;
          i < pDDT->DDTMaxColors && lcCount < MaxCount;
          i++)
    {
        /**************************************************************/
        /* Look for physical colour in the logical colour table that  */
        /* matches the device colour and put its index in Match.      */
        /**************************************************************/
        Match = 0xFFFF;
        for (j = 0; j < DCIData->DCIColTabSize && Match == 0xFFFF; j++)
            if (pDDT->DDTDevColorTable->Colors[i] ==
                                      DCIData->DCIColorTable[j].PhysRGB)
                Match = j;

        /**************************************************************/
        /* Return the index or CLR_NOINDEX                            */
        /**************************************************************/
        if (Match == 0xFFFF)
            ArgArray[lcCount++] = (ULONG)CLR_NOINDEX;
        else
            ArgArray[lcCount++] = Match;

        /**************************************************************/
        /* Return RGB value                                           */
        /**************************************************************/
        ArgArray[lcCount++] = pDDT->DDTDevColorTable->Colors[i];
    }
    /*.. for (i = (USHORT)ArgStart; pDDT->DDTMaxColors .device colours*/

    TRACE4(TFUNC, "Return Count", &lcCount, 1);

    /******************************************************************/
    /* Return the number of entries written to ArgArray               */
    /******************************************************************/
    prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,9A)
#endif
    return(lcCount);
}
#undef TFUNC


/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdc_QueryNearestColor                                 */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   See "OS/2 Technical Reference: I/O Subsytems and Device Drivers" */
/*                                                                    */
/*   hanDC        DcH;                                                */
/*   ULONG        ArgOptions;                                         */
/*   ULONG        ArgRGBColorIn;                                      */
/*   lpDCI        DCIData;                                            */
/*   ULONG        FunN;                                               */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function returns the nearest colour available on the        */
/*   printer to ArgRGBColorIn in RGB format.                          */
/*                                                                    */
/*   CHANGES:                                                         */
/*                                                                    */
/*   This function should handle non-monochrome devices without change*/
/*   as long as the DDT colour table has been set up correctly.       */
/*                                                                    */
/**********************************************************************/
ULONG prdc_QueryNearestColor ( hanDC        DcH,
                               ULONG        ArgOptions,
                               ULONG        ArgRGBColorIn,
                               lpDCI        DCIData,
                               ULONG        FunN)

{
#define TFUNC "prdc_QueryNearestColor"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    ULONG            RetColor;         /* The index to return         */
    lpDVTColorTable  DCTab;            /* A pointer to the device     */
                                       /* colour table                */

    /******************************************************************/
    /* Trace the parameters                                           */
    /******************************************************************/

    TRACE8(TFUNC, "Options", &ArgOptions, 1);
    TRACE8(TFUNC, "RgbColorIn", &ArgRGBColorIn, 1);
    TRACE8(TFUNC, "DcH", &DcH, 1);
    TRACE8(TFUNC, "FunN", &FunN, 1);

    /******************************************************************/
    /* Do entry processing                                            */
    /******************************************************************/
    if (!prdz_EnterDriver(DCIData))
        return(ERROR_NEG);

#ifdef PRD_TIMING
    DEKHOOK0(A,7,1B)
#endif
    if (DCIData->DCIColorTable != NULL)                       /* PD00462 */
    {

       /******************************************************************/
       /* Look up nearest available color in Device Color Table - this   */
       /* does not have to be in the logical color table                 */
       /* Both colors are specified in RGB terms                         */
       /******************************************************************/
       RetColor = DCIData->DCIColorTable[prdc_RGBToCLRIndex(
                                   ULTORGB(ArgRGBColorIn),DCIData)].LogRGB;
    }
    else
    {
       /******************************************************************/
       /* Set up DCTab to access the table of colours the printer can    */
       /* produce.                                                       */
       /******************************************************************/
       DCTab = DCIData->DCIPdbInstance->DDT.DDTDevColorTable;

       /******************************************************************/
       /* Look up nearest available color in Device Color Table - this   */
       /* does not have to be in the logical color table                 */
       /* Both colors are specified in RGB terms                         */
       /******************************************************************/
       RetColor = DCTab->Colors[prdc_RGBColorToPelBits(ArgRGBColorIn, DCTab)];
    }

    prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,9B)
#endif
    return(RetColor);

}
#undef TFUNC


/******************************************************************************/
/*  FUNCTION: prdc_QueryColorIndex                                            */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  See "OS/2 Technical Reference: I/O Subsytems and Device Drivers"          */
/*                                                                            */
/*  hanDC  DcH;                                                               */
/*  ULONG  ArgOptions;                                                        */
/*  ULONG  ArgRGBColor;                                                       */
/*  lpDCI  DCIData;                                                           */
/*  ULONG  FunN;                                                              */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This function returns the index into the logical color table of the       */
/*  nearest colour available on the printer to ArgRGBColor.  If in LCOLF_RGB  */
/*  mode then return the RGB value passed in.                                 */
/*                                                                            */
/*  CHANGES:                                                                  */
/*                                                                            */
/*  This function should handle non-monochrome devices without change as long */
/*  as the DDT colour table has been set up correctly.                        */
/******************************************************************************/
ULONG prdc_QueryColorIndex ( hanDC  DcH,
                             ULONG  ArgOptions,
                             ULONG  ArgRGBColor,
                             lpDCI  DCIData,
                             ULONG  FunN)

{
#define TFUNC "prdc_QueryColorIndex"

    /**************************************************************************/
    /* Local Variables                                                        */
    /**************************************************************************/
    ULONG        PhysIndex;        /* The index to return                     */

    /**************************************************************************/
    /* Trace the parameters                                                   */
    /**************************************************************************/
    TRACE8(TFUNC, "Options", &ArgOptions, 1);
    TRACE8(TFUNC, "RgbColor", &ArgRGBColor, 1);
    TRACE8(TFUNC, "DcH", &DcH, 1);
    TRACE8(TFUNC, "FunN", &FunN, 1);

    /******************************************************************/
    /* Do entry processing                                            */
    /******************************************************************/
    if (!prdz_EnterDriver(DCIData))
        return(ERROR_NEG);

#ifdef PRD_TIMING
    DEKHOOK0(A,7,1C)
#endif

    /**************************************************************************/
    /* If RGB mode then return the supplied RGB value                         */
    /**************************************************************************/
    if (DCIData->DCIColFormat == LCOLF_RGB)
    {
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,9C)
#endif
        return(ArgRGBColor);
    }
    PhysIndex = prdc_RGBToCLRIndex(ULTORGB(ArgRGBColor), DCIData);
    prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,9C)
#endif
    return PhysIndex;
}
#undef TFUNC

/**********************************************************************/
/*                                                                    */
/*   FUNCTION: QueryRGBColor                                          */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   See "OS/2 Technical Reference: I/O Subsytems and Device Drivers" */
/*                                                                    */
/*   hanDC         DcH;                                               */
/*   ULONG         ArgOptions;                                        */
/*   ULONG         ArgColor;                                          */
/*   lpDCI         DCIData;                                           */
/*   ULONG         FunN;                                              */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function returns the RGB colour which corresponds to the    */
/*   index to the logical colour index supplied.                      */
/*                                                                    */
/*   ArgColor may be an index into a logical color table or an RGB    */
/*   value.  If the color index is RGB mode the nearest RGB color in  */
/*   the Device Color Table is returned.  Otherwise the actual        */
/*   (physical) RGB colour which is indicated by the index into the   */
/*   logical colour table.  Note that prdc_ColorToPelBits can also    */
/*   handle negative colour indexes.                                  */
/*                                                                    */
/*   CHANGES:                                                         */
/*                                                                    */
/*   This function should handle non-monochrome devices without change*/
/*   as long as the DDT colour table has been set up correctly.       */
/*                                                                    */
/**********************************************************************/
ULONG prdc_QueryRGBColor ( hanDC         DcH,
                           ULONG         ArgOptions,
                           ULONG         ArgColor,
                           lpDCI         DCIData,
                           ULONG         FunN)

{
#define TFUNC "prdc_QueryRGBColor"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    BYTE             DCTabIndex;       /* Index to Device Color Table */
    lpDVTColorTable  DCTab;            /* Pointer to device colour    */
                                       /* table                       */

    /******************************************************************/
    /* Trace the parameters                                           */
    /******************************************************************/
    TRACE8(TFUNC, "Options", &ArgOptions, 1);
    TRACE8(TFUNC, "Color", &ArgColor, 1);
    TRACE8(TFUNC, "DcH", &DcH, 1);
    TRACE8(TFUNC, "FunN", &FunN, 1);

    /******************************************************************/
    /* Do netyr processing                                            */
    /******************************************************************/
    if (!prdz_EnterDriver(DCIData))
        return(ERROR_NEG);

#ifdef PRD_TIMING
    DEKHOOK0(A,7,1D)
#endif

    if ( ((LONG)ArgColor < (LONG)0) || (DCIData->DCIColorTable == NULL) )
    {
       /******************************************************************/
       /* Set up pointer to device colour table.                         */
       /******************************************************************/
       DCTab = DCIData->DCIPdbInstance->DDT.DDTDevColorTable;

       /******************************************************************/
       /* Call prdc_ColorToPelBits which can handle all the possible     */
       /* inputs in ArgColor (positive and negative indexes and RGB mode)*/
       /******************************************************************/
       DCTabIndex = prdc_ColorToPelBits(ArgColor, DCIData, DCTab);

       /******************************************************************/
       /* Return the RGB colour from the device colour table indicated   */
       /* by the index returned from prdc_ColorToPelBits.                */
       /******************************************************************/
       if ( DCTabIndex != (BYTE)ERROR_NEG )
       {
          prdm_LeaveDriver(DCIData);
          return( DCTab->Colors[DCTabIndex] );
       }
    }
    else
    {
       if ( ArgColor < DCIData->DCIColTabSize )
       {
            prdm_LeaveDriver(DCIData);
            return( DCIData->DCIColorTable[ArgColor].LogRGB);
       }

    }
    prdm_LeaveDriver(DCIData);
    return(ERROR_NEG);

}
#undef TFUNC
