/*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 = PRDQQERY
 *
 * DESCRIPTIVE NAME =
 *
 *
 * VERSION
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS   prdq_QueryDeviceBitmaps
 *             prdq_QueryDevResource
 *             prdq_QueryDeviceCaps
 *
 * ENTRY POINTS:
 *
 * DEPENDENCIES:
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/

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

#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
#define INCL_WINP_MISC
#include <pmwinx.h>
#undef INCL_WINP_SELECTIVE
#undef INCL_WINP_SEI
#undef INCL_WINP_MISC
#undef INCL_32                    /* CON3201 */

#include <prdacone.h>
#include <prdccone.h>
#include <prddcone.h>
#include <prdconse.h>
#include <prdncone.h>
#include <prdtcone.h>
#include <prdmcone.h>

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

#include <prdgextf.h>
#include <prdqextf.h>
#include <prdaextf.h>
#include <prduextf.h>
#include <prdyextf.h>

extern USHORT           DRIVER_TYPE;
extern HMODULE           prdd_ModHandle;
/* extern USHORT           PMVersion; CON3201 - No longer needed */
extern lpDDTType        DDT [];

/******************************************************************************/
/*                                                                            */
/*   FUNCTION: prdq_QueryDeviceBitmaps                                        */
/*                                                                            */
/*   PARAMETERS:                                                              */
/*                                                                            */
/*   See "OS/2 Technical Reference: I/O Subsytems and Device Drivers"         */
/*                                                                            */
/*   hanDC           DcH;                                                     */
/*   PULONG          ArgOutData;                                              */
/*   LONG            ArgOutDataLength;                                        */
/*   lpDCI           DCIData;                                                 */
/*   ULONG           FunN;                                                    */
/*                                                                            */
/*   DESCRIPTION:                                                             */
/*                                                                            */
/*   This function returns information about the bit map formats              */
/*   supported by the printer.  For monochrome printers this will             */
/*   be 1 Planes and 1 BitsPerPel.                                            */
/*                                                                            */
/*   CHANGES:                                                                 */
/*                                                                            */
/*   If you want to support more than one format of internal bitmap           */
/*   then this function will have to be able to return the formats            */
/*   which are supported - getting the data from wherever it is held.         */
/*                                                                            */
/*   PD00093 : change ArgOutDataLength to LONG.                               */
/******************************************************************************/
ULONG prdq_QueryDeviceBitmaps ( hanDC           DcH,
                                PULONG          ArgOutData,
                                LONG            ArgOutDataLength,
                                lpDCI           DCIData,
                                ULONG           FunN)

{
#define TFUNC "prdq_QryDevBmps"

    /**************************************************************************/
    /* Local Variables                                                        */
    /**************************************************************************/
    lpDDTType           pDDT;          /* Pointer to DDT in PDB       */
    USHORT              LoopCnt;       /* Loop counter for zeroing    */

    TRACE8(TFUNC, "DcH", &DcH, 0);

    prdm_EnterDriver(DCIData);

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

    /**************************************************************************/
    /* Check that OutData has sufficient room for the output.                 */
    /* PD00257 : ArgOutDataLength must be an even number as well as being     */
    /*           greater than or equal to 2.                                  */
    /**************************************************************************/
    if ((ArgOutDataLength < 2) || (ArgOutDataLength % 2 != 0))
    {
        LOGERR(TFUNC, "short OutData",
                     &ArgOutDataLength, 1, PMERR_INV_LENGTH_OR_COUNT);
        prdm_LeaveDriver(DCIData);
        return((ULONG)ERROR_ZERO);
    }

    /**************************************************************************/
    /* Return the values.                                                     */
    /**************************************************************************/
    ArgOutData[0] = pDDT->DDTFormat->Planes;
    ArgOutData[1] = pDDT->DDTFormat->BitCount;

    /**************************************************************************/
    /* Excess elements in the array are set to zero (the application          */
    /* may have provided enough space for several bitmap formats so we        */
    /* must zero these to show we only support one).                          */
    /**************************************************************************/
    for ( LoopCnt = 2;
          LoopCnt < ((USHORT) ArgOutDataLength);
          LoopCnt++ )
        ArgOutData[LoopCnt] = 0L;

    TRACE8(TFUNC, "Out", ArgOutData, ArgOutDataLength);

    TRACE4(TFUNC, "Return OK", FNULL, 0);
    prdm_LeaveDriver(DCIData);
    return((ULONG)OK);
}
#undef TFUNC





/******************************************************************************/
/*                                                                            */
/*   FUNCTION: prdq_QueryDevResource                                          */
/*                                                                            */
/*   PARAMETERS:                                                              */
/*                                                                            */
/*   See "OS/2 Technical Reference: I/O Subsytems and Device Drivers"         */
/*                                                                            */
/*   hanDC           DcH;                                                     */
/*   ULONG           ArgTypeID;                                               */
/*   ULONG           ArgNameID;                                               */
/*   lpDCI           lpDCIData;                                               */
/*   ULONG           FunN;                                                    */
/*                                                                            */
/*   DESCRIPTION:                                                             */
/*                                                                            */
/*   This function returns information about the resources                    */
/*   available in the printer driver. If the requested resource               */
/*   is available, a pointer to it is returned. If the requested              */
/*   resource is not available, zero is returned.                             */
/*                                                                            */
/*   This function is used when the engine is asked to manage the             */
/*   default font, and the default font is a device font. The engine          */
/*   needs to get access to the default font's metrics so that it             */
/*   can perform the necessary calculations.                                  */
/*                                                                            */
/*   The function is called in the above case with:                           */
/*       ArgTypeID == RT_FONT                                                 */
/*       ArgNameID == SFONT_RASTER or SFONT_OUTLINE                           */
/*                    (according to whether the engine has been asked         */
/*                     to manage a raster font or an outline font).           */
/*                                                                            */
/******************************************************************************/
ULONG  prdq_QueryDevResource ( hanDC   DcH,
                               ULONG   ArgTypeID,
                               ULONG   ArgNameID,
                               lpDCI   DCIData,
                               ULONG   FunN)

{
#define TFUNC "prdq_QryDevRes"

    /**************************************************************************/
    /* Local Variables                                                        */
    /**************************************************************************/
    PVOID          Selector;
    USHORT         Result;
    lpDDTType      pDDT;                /* Pointer to DDT in PDB      */

    TRACE8(TFUNC, "DcH", &DcH, 0);

    /**************************************************************************/
    /* Should never get here.  This function is not sensible.                 */
    /**************************************************************************/
//  prdm_EnterDriver(DCIData);
//  haltproc();

//   /******************************************************************/
//   /* Set the pointer for the DDT in the PDB.                        */
//   /******************************************************************/
//   pDDT = &DCIData->DCIPdbInstance->DDT;
//
//   /******************************************************************/
//   /* Reset Selector                                                 */
//   /******************************************************************/
//   Selector = 0;
//
//   if ((ArgTypeID == RT_FONT) && (ArgNameID == SFONT_RASTER))
//   {
//       /**************************************************************/
//       /* The engine wants to know the address of our default image  */
//       /* font.                                                      */
//       /**************************************************************/
//       if ( (DCIData->DCIDCType != OD_MEMORY) &&
//            (DCIData->DCIPdbInstance->PrinterData->
//                                DfltFontInfo.Info.Type != FT_ENGINE) )
//       {
//           /**********************************************************/
//           /* We have a default font.                                */
//           /* Temporary usage.. just return first device font.       */
//           /**********************************************************/
//           Result = DosGetResource(
//                              (HMODULE)prdd_ModHandle,
//                              (USHORT)1000,
//                              (USHORT)pDDT->DDTFontList[0]->ResourceId,
//                              (PSEL)&Selector);
//
//           TRACE4(TFUNC, "Selector", &Selector, 1);
//
//           if (Result != DOS_OK)
//           {
//               TRACE4(TFUNC, "DosGetResource failed", &Result, 1);
//               LOGDOSERR(TFUNC, "Error in DosGetResource",
//                                                   FNULL, 0, Result);
//               prdm_LeaveDriver(DCIData);
//               return(0L);
//           }
//       }
//   }
//
//  prdm_LeaveDriver(DCIData);
    return((ULONG)Selector);
}
#undef TFUNC




/******************************************************************************/
/*                                                                            */
/*   FUNCTION: prdq_QueryDeviceCaps                                           */
/*                                                                            */
/*   PARAMETERS:                                                              */
/*                                                                            */
/*   See "OS/2 Technical Reference: I/O Subsytems and Device Drivers"         */
/*                                                                            */
/*   hanDC           DcH;                                                     */
/*   ULONG           ArgOutIndex;                                             */
/*   PULONG          ArgOutData;                                              */
/*   ULONG           ArgOutCount;                                             */
/*   lpDCI           DCIData;                                                 */
/*   ULONG           FunN;                                                    */
/*                                                                            */
/*   DESCRIPTION:                                                             */
/*                                                                            */
/*   This function can return information about a variety of the              */
/*   printers capabilities:  See "OS/2 Technical Reference:  I/O              */
/*   Subsytems and Device Drivers" for more information on what this          */
/*   function can return.                                                     */
/*                                                                            */
/*   CHANGES:                                                                 */
/*                                                                            */
/*   This function will have to be changed so it returns the actual           */
/*   capabilities of your driver/printer combination.                         */
/*                                                                            */
/******************************************************************************/
ULONG prdq_QueryDeviceCaps ( hanDC     DcH,
                             ULONG     ArgOutIndex,
                             PULONG    ArgOutData,
                             ULONG     ArgOutCount,
                             lpDCI     DCIData,
                             ULONG     FunN)

{
#define TFUNC "prdq_QryDevCaps"

#ifndef CAPS_ENHANCED_FONTMETRICS
#define CAPS_ENHANCED_FONTMETRICS    8192L     /* PD00673             */
#endif
#ifndef CAPS_CLIP_FILLS
#define CAPS_CLIP_FILLS            4096L /* P500079/PD00791                   */
#endif

    /**************************************************************************/
    /* Local variables                                                        */
    /**************************************************************************/
    ULONG               CapValue;              /* The value to be returned for*/
                                               /* each 'capability'           */
    lpDDTType           pDDT;                  /* Pointer to DDT in PDB       */
    ULONG               PageWidthPels;         /* Paper width in pels         */
    ULONG               PageDepthPels;         /* Paper height in pels        */
    ULONG               RasterWidth;           /* Horizontal resolution       */
    ULONG               RasterDepth;           /* Vertical resolution         */
    ULONG               CellWidth;             /* character cell width        */
    ULONG               CellHeight;            /* character cell height       */
    lpFontInfoType      pFontInfo;             /* default font info           */
    ULONG               CellWidth2;            /* character cell width        */
    ULONG               CellHeight2;           /* character cell height       */
    lpDfltFontInfoType  pDfltFontInfo;
    lpFMFFileStruc      pMetricsFile;
    USHORT              Size;
    USHORT              ResAdjFactorX;         /* Used to adjust values for   */
                                               /* this resolution             */
    USHORT              ResAdjFactorY;         /* Used to adjust values for   */
                                               /* this resolution             */
    BOOL                DefaultFontWidth;
    USHORT              fsXform;
    XFORM               xfm;
    POINTL              CharBox;
    LONG                EmHeight;
    LONG                EmInc;
    lpPrtDataEntry      PrinterData;           /* PrinterStateData for    */
                                               /* current printer         */
    ULONG               i;                     /* Loop variable           */
    lpCardFontListType  pCardList;             /*                    ..   */
    USHORT              NumberOfSlots;
    USHORT              TotalCartridgeFonts;
    BYTE                DfltFontRealized;      /* PD00681                  */
    BOOL                QualityFlag;           /* PD00737                  */
    BOOL                CardFont1;             /* PD00737                  */
    BOOL                CardFont2;             /* PD00737                  */
    SHORT               SystemCodePage;        /* PD00737                  */
    SHORT               SystemCodePage1;       /* PD00737                  */
    SHORT               SystemCodePage2;       /* PD00737                  */
    SHORT               FMFCodePage;           /* PD00737                  */

    /**************************************************************************/
    /* Trace the parameters                                                   */
    /**************************************************************************/
    TRACE4(TFUNC, "Entry", FNULL, 0);
    TRACE8(TFUNC, "ArgOutIndex", &ArgOutIndex, 1);
    TRACE8(TFUNC, "ArgOutCount", &ArgOutCount, 1);
    TRACE4(TFUNC, "ArgOutData address", &ArgOutData, 1);
    TRACE4(TFUNC, "DCIData address", &DCIData, 1);

    /**************************************************************************/
    /* Do entry processing                                                    */
    /**************************************************************************/
#ifdef PRD_TIMING
    DEKHOOK0(A,9,58)
#endif
    prdm_EnterDriver(DCIData);

    pDDT = &DCIData->DCIPdbInstance->DDT;

    /**************************************************************************/
    /* Do simple error checks and log an error if necessary.  A count of zero */
    /* is regarded as an error.  Values for indices outside the valid range   */
    /* are filled with zeroes.  A maximum count of 16K is imposed (as the VGA */
    /* does) to avoid going over a 64K segment.  The only check made on the   */
    /* buffer is to check that it is not null.                                */
    /**************************************************************************/
    if ((ArgOutData == FNULL) || (ArgOutCount == 0))
    {
        LOGERR(TFUNC, "Bad params", FNULL, 0, PMERR_INV_LENGTH_OR_COUNT);
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,9,D8)
#endif
        return((ULONG)ERROR_ZERO);
    }

    if ( ArgOutCount > 0x4000 )
        ArgOutCount = 0x4000;

    /**************************************************************************/
    /* Widths and Depths must be swapped if orientation is landscape as       */
    /* opposed to standard portrait.                                          */
    /**************************************************************************/
    if (DCIData->DCIPdbInstance->Orientation == PORTRAIT)
    {
        TRACE4(TFUNC,"Portrait mode",FNULL,0);

        PageWidthPels = DCIData->DCIPdbInstance->PageWidthPels;
        PageDepthPels = DCIData->DCIPdbInstance->PageDepthPels;
        RasterWidth   = pDDT->DDTRasterMode->ResWidth;
        RasterDepth   = pDDT->DDTRasterMode->ResDepth;
        /**********************************************************************/
        /* See note below.                                                    */
        /**********************************************************************/
        CellWidth  = prda_GetDfltCharBox( (HDC)DcH,
                                          WIDTH,
                                          DEVICE_COORDS,
                                          DCIData );

        CellHeight = prda_GetDfltCharBox( (HDC) DcH,
                                          HEIGHT,
                                          DEVICE_COORDS,
                                          DCIData );
    }
    else
    {
        TRACE4(TFUNC,"Landscape mode",FNULL,0);

        PageWidthPels = DCIData->DCIPdbInstance->PageDepthPels;
        PageDepthPels = DCIData->DCIPdbInstance->PageWidthPels;
        RasterWidth   = pDDT->DDTRasterMode->ResDepth;
        RasterDepth   = pDDT->DDTRasterMode->ResWidth;
        /**********************************************************************/
        /* See note below.                                                    */
        /**********************************************************************/
        CellWidth  = prda_GetDfltCharBox( (HDC)DcH,
                                          HEIGHT,
                                          DEVICE_COORDS,
                                          DCIData );

        CellHeight = prda_GetDfltCharBox( (HDC) DcH,
                                          WIDTH,
                                          DEVICE_COORDS,
                                          DCIData );
    }
    /**************************************************************************/
    /* CellWidth and CellHeight are now fixed at 1/6 inch.  This value is     */
    /* returned for CAPS_GRAPHICS_CHAR_WIDTH/_HEIGHT, CAPS_CHAR_WIDTH/_HEIGHT.*/
    /*                                                                        */
    /* Note that these values DO NOT REFLECT THE DEFAULT FONT!  and in fact   */
    /* are only relevant to the default char box.  NB DDT                     */
    /*                                                                        */
    /* Find CellWidth2 and CellHeight2 to use for CAPS_WIDTH/HEIGHT_ IN_CHARS.*/
    /* It is based on the MaxBaselineext and the AvgCharWidth.                */
    /**************************************************************************/
    DefaultFontWidth = FALSE;
    if (DCIData->DCIFontData.Genre == DEVICE_FONT)
    {
        pDfltFontInfo = &(DCIData->DCIPdbInstance->DfltDeviceFont);

        DefaultFontWidth = TRUE;
        pMetricsFile = pDfltFontInfo->Info.pFont;
        CellWidth2 = pMetricsFile->Metrics.xAveCharWidth;
        CellHeight2 = pMetricsFile->Metrics.yMaxBaselineExt;

        /*******************************************************************/
        /* If necessary we need to adjust for the current resolution       */
        /*******************************************************************/
        ResAdjFactorX =  pMetricsFile->Metrics.xDeviceRes/
                                         pDDT->DDTRasterMode->ResWidth;
        ResAdjFactorY =  pMetricsFile->Metrics.yDeviceRes/
                                         pDDT->DDTRasterMode->ResDepth;

        /*******************************************************************/
        /* If there is a conversion to be done...  convert using half      */
        /* rounding.  Note, this may be incorrect for a device that        */
        /* supports nonequivalent resolution device landscape fonts.  The  */
        /* resadjfactor may need to be switched.                           */
        /*******************************************************************/
        if (ResAdjFactorX != 1)
        {
           Size = (USHORT)(CellWidth2 / ResAdjFactorX);
           if ((CellWidth2 % ResAdjFactorX) > (ResAdjFactorX/2))
              Size++;
           CellWidth2 = Size;
        }
        if (ResAdjFactorY != 1)
        {
           Size = (USHORT)(CellHeight2 / ResAdjFactorY);
           if ((CellHeight2 % ResAdjFactorY) > (ResAdjFactorY/2))
              Size++;
           CellHeight2 = Size;
        }
    }
    /**************************************************************************/
    /* Selection of output uses a for - case loop.                            */
    /**************************************************************************/
    for ( ; ArgOutCount-- > 0; )
    {
        switch ( (SHORT)(USHORT)ArgOutIndex++ )
        {

        case  CAPS_FAMILY:
            /******************************************************************/
            /* Device Family : Return DC Type.                                */
            /******************************************************************/
            CapValue = DCIData->DCIDCType;
            break;

        case  CAPS_IO_CAPS:
            /******************************************************************/
            /* Device Input/Output capability                                 */
            /******************************************************************/
            CapValue = CAPS_IO_SUPPORTS_OP;
            break;

        case  CAPS_TECHNOLOGY:
            /******************************************************************/
            /* Technology                                                     */
            /******************************************************************/
            CapValue = CAPS_TECH_RASTER_PRINTER;
            break;

        case  CAPS_DRIVER_VERSION:
            /******************************************************************/
            /* Driver version is 1.2.                                         */
            /******************************************************************/
/*          CapValue = 0x00000120;   CON3201 - GRE change                     */
            CapValue = 0x00000200;
            break;

        case  CAPS_WIDTH:
            /******************************************************************/
            /* Default Page Width in pels.                                    */
            /******************************************************************/
            CapValue = PageWidthPels;
            break;

        case  CAPS_HEIGHT:
            /******************************************************************/
            /* Default Page Height in pels.                                   */
            /******************************************************************/
            CapValue = PageDepthPels;
            break;

        case  CAPS_WIDTH_IN_CHARS:
            /******************************************************************/
            /* This refers to device fonts.                                   */
            /******************************************************************/
            if (DefaultFontWidth)
            {
               CapValue = (PageWidthPels) / CellWidth2;
            }
            else
            {
               CapValue = PageWidthPels / CellWidth;
            }
            break;

        case  CAPS_HEIGHT_IN_CHARS:
            /******************************************************************/
            /* This refers to device fonts.                                   */
            /******************************************************************/
            if (DefaultFontWidth)
            {
               CapValue = (PageDepthPels) / CellHeight2;
            }
            else
            {
               CapValue = PageDepthPels / CellHeight;
            }
            break;

     case CAPS_HORIZONTAL_RESOLUTION:
            /******************************************************************/
            /* Multiply the number of dots per inch by the number of inches in*/
            /* a metre to get the horizontal resolution in dots per metre.    */
            /* Include a .5 for rounding.                                     */
            /******************************************************************/
            /******************************************************************/
            /* PD00521 : Don't round CapValue since this causes GPIQueryPS to */
            /* calculate the PS width as one twip too small at 150x150 res.   */
            /* which causes applications to wrap a character.                 */
            /******************************************************************/
//          CapValue = ((RasterWidth * 3937L) + 50L) / 100L;
            CapValue = (RasterWidth * 3937L) / 100L;
            break;

     case  CAPS_VERTICAL_RESOLUTION:
            /******************************************************************/
            /* Multiply the number of dots per inch by the number of inches in*/
            /* a metre to get the vertical resolution in dots per metre.      */
            /* Include a .5 for rounding.                                     */
            /******************************************************************/
            /******************************************************************/
            /* PD00521 : Don't round CapValue since this causes GPIQueryPS to */
            /* calculate the PS width as one twip too small at 150x150 res.   */
            /* which causes applications to wrap a character.                 */
            /******************************************************************/
//          CapValue = ((RasterDepth * 3937L) + 50L) / 100L;
            CapValue = (RasterDepth * 3937L) / 100L;
            break;

        case CAPS_CHAR_WIDTH:
            /******************************************************************/
            /* For 1.2 this is probably an AVIO field but Lexington say that  */
            /* applications are using it.  In fact appls should use           */
            /* CAPS_GRAPHIC_CHAR_WIDTH.                                       */
            /******************************************************************/
//          CapValue = CellWidth;
            /******************************************************************/
            /* PD00652 : Return size of default font not default char box.    */
            /******************************************************************/
            if (DefaultFontWidth)
            {
               /***************************************************************/
               /* This refers to device fonts.                                */
               /***************************************************************/
               CapValue = CellWidth2;
            }
            else
            {
               CapValue = CellWidth;
            }
            break;

        case CAPS_CHAR_HEIGHT:
            /******************************************************************/
            /* For 1.2 this is probably an AVIO field but Lexington say that  */
            /* applications are using it.  IN fact appls should use           */
            /* CAPS_GRAPHIC_CHAR_HEIGHT.                                      */
            /******************************************************************/
//          CapValue = CellHeight;

            /******************************************************************/
            /* PD00652 : Return size of default font not default char box.    */
            /******************************************************************/
            if (DefaultFontWidth)
            {
               /***************************************************************/
               /* This refers to device fonts.                                */
               /***************************************************************/
               CapValue = CellHeight2;
            }
            else
            {
               CapValue =  CellHeight;
            }
            break;

        case CAPS_SMALL_CHAR_WIDTH:
            /******************************************************************/
            /* This is an AVIO value so return 0.                             */
            /******************************************************************/
            CapValue = 0;
            break;

        case CAPS_SMALL_CHAR_HEIGHT:
            /******************************************************************/
            /* This is an AVIO value so return 0.                             */
            /******************************************************************/
            CapValue = 0;
            break;

        case CAPS_COLORS:
            /******************************************************************/
            /* Return the number of distinct colors supported PD00462: changed*/
            /* from 2 to 16.                                                  */
            /******************************************************************/
            CapValue = 16;
            break;

        case CAPS_COLOR_PLANES:
            /******************************************************************/
            /* Get the number of colour planes from the DDT.                  */
            /******************************************************************/
            CapValue = pDDT->DDTFormat->Planes;
            break;

        case CAPS_COLOR_BITCOUNT:
            /******************************************************************/
            /* Get the number of bits per pel from the DDT.                   */
            /******************************************************************/
            CapValue = pDDT->DDTFormat->BitCount;
            break;

        case CAPS_COLOR_TABLE_SUPPORT:
            /******************************************************************/
            /* No loadable colour table support.                              */
            /******************************************************************/
            CapValue = 0;
            break;

        case CAPS_MOUSE_BUTTONS:
            CapValue = 0;
            break;

        case CAPS_FOREGROUND_MIX_SUPPORT:
            /******************************************************************/
            /* All foreground mixes supported for raster printers.            */
            /******************************************************************/
            CapValue = CAPS_FM_OR             |
                       CAPS_FM_OVERPAINT      |
                       CAPS_FM_XOR            |
                       CAPS_FM_LEAVEALONE     |
                       CAPS_FM_AND            |
                       CAPS_FM_GENERAL_BOOLEAN;
            break;

        case CAPS_BACKGROUND_MIX_SUPPORT:
            /******************************************************************/
            /* All background mixes supported for raster printers.            */
            /******************************************************************/
            CapValue = CAPS_BM_OR        |
                       CAPS_BM_OVERPAINT |
                       CAPS_BM_XOR       |
                       CAPS_BM_LEAVEALONE;
            break;

        case CAPS_VIO_LOADABLE_FONTS:
            /******************************************************************/
            /* This is an AVIO value so return 0.                             */
            /******************************************************************/
            CapValue = 0;
            break;

        case CAPS_WINDOW_BYTE_ALIGNMENT:
            CapValue = 0;
            break;

        case CAPS_BITMAP_FORMATS:
            /******************************************************************/
            /* Raster printers support one bitmap format.                     */
            /******************************************************************/
            CapValue = 1;
            break;

        case CAPS_RASTER_CAPS:
            /******************************************************************/
            /* We say we support engine raster fonts up until the CompleteOpen*/
            /* call to get our default font set up.                           */
            /******************************************************************/
            CapValue = CAPS_RASTER_BITBLT         |
                       CAPS_RASTER_BITBLT_SCALING |
                       CAPS_RASTER_SET_PEL;

            /******************************************************************/
            /* Commented Out : always say we support Engine Raster Fonts even */
            /* after the CompleteOpen call.  ( SMP 29/6/90 )                  */
            /******************************************************************/
//          if ( !(DCIData->DCIStateFlags & COMPLETE_OPEN_DONE) )
                CapValue |= CAPS_RASTER_FONTS;

            break;

        case CAPS_MARKER_WIDTH:
            /******************************************************************/
            /* Width in pels of markers from the default marker set.          */
            /******************************************************************/
            CapValue = 8;
            break;

        case CAPS_MARKER_HEIGHT:
            /******************************************************************/
            /* Height in pels of markers from the default marker set.         */
            /******************************************************************/
            CapValue = 8;
            break;

        case CAPS_DEVICE_FONTS:
            /******************************************************************/
            /* FontCount will be zero if device fonts are not available.  This*/
            /* is set up in FillPdb.                                          */
            /******************************************************************/
            /******************************************************************/
            /* PD00507 : For queued and raw jobs only count the fonts that are*/
            /* on cards in the slots.                                         */
            /******************************************************************/
            if ( DCIData->DCIPdbInstance->FontCount )
            {
               if (DCIData->Flags & QUEUED_RAW)
               {
                 PrinterData = DCIData->DCIPdbInstance->PrinterData;
                 TotalCartridgeFonts = 0;
                 QualityFlag = TRUE;                               /* PD00737 */
                 CardFont1 = FALSE;                                /* PD00737 */
                 CardFont2 = FALSE;                                /* PD00737 */
                 SystemCodePage = (SHORT)WinQueryProcessCP();      /* PD00737 */
                 SystemCodePage1 = SystemCodePage;                 /* PD00737 */
                 SystemCodePage2 = SystemCodePage;                 /* PD00737 */

                 /*************************************************************/
                 /*  PD00737 : Set some flags before processing the Card Fonts*/
                 /*************************************************************/
                 for ( i = 0, pCardList = PrinterData->CardData;
                       i < PrinterData->CardFontCount;
                       i++, pCardList++ )
                 {
                      FMFCodePage = pCardList->pFMFData->Metrics.usCodePage;
                      if ((PrinterData->
                              SlotInfo[0].OwnedCardIndex !=
                              NO_CARD_IN_SLOT) &&          /* CON3203 */
                          (SystemCodePage == FMFCodePage) &&
                          (!prdu_strcmp(pCardList->pCardName,
                                        PrinterData->CardData[PrinterData->
                                            SlotInfo[0].FontIndex].pCardName)))
                      {
                         /*****************************************************/
                         /*  If the first card has the system code page.      */
                         /*****************************************************/
                         CardFont1 = TRUE;
                      }
                      else if ((PrinterData->
                                SlotInfo[1].OwnedCardIndex !=
                                NO_CARD_IN_SLOT) &&        /* CON3203 */
                               (SystemCodePage == FMFCodePage) &&
                               (!prdu_strcmp(pCardList->pCardName,
                                             PrinterData->CardData[PrinterData->
                                             SlotInfo[1].FontIndex].pCardName)))
                      {
                         /*****************************************************/
                         /*  If the second card has the system code page.     */
                         /*****************************************************/
                         CardFont2 = TRUE;
                      }
                 }

                 for ( i = 0, pCardList = PrinterData->CardData;
                       i < PrinterData->CardFontCount;
                       i++, pCardList++ )
                 {
                 /*************************************************************/
                 /* Check if outline font.                                    */
                 /*************************************************************/
                   for (NumberOfSlots = 0 ; NumberOfSlots <
                          pDDT->DDTNoOfCardSlots ; NumberOfSlots++)
                   {
                      if ( PrinterData->
                                SlotInfo[NumberOfSlots].OwnedCardIndex ==
                                NO_CARD_IN_SLOT )          /* CON3203 */
                         continue;
                      if (!prdu_strcmp(pCardList->pCardName,
                              PrinterData->CardData[PrinterData->
                              SlotInfo[NumberOfSlots].FontIndex].pCardName) )
                      {
                         if ( (pDDT->DDTDialogFlags & DDT_LIMIT_FONTS) &&
                              (pDDT->DDTPrinterFonts==DEV_FONTS_LIMITED) )
                         {
                            /***********************************************/
                            /*  PD00737 : Limit by quality and codepage.   */
                            /*  Set up the code page to be used for one    */
                            /*  card, SystemCodePage1, and the code page   */
                            /*  to be used for the second card, if there   */
                            /*  is one, SystemCodePage2.                   */
                            /***********************************************/
                            if (!CardFont1)
                            {
                                SystemCodePage1 = PrinterData->
                                      CardData[PrinterData->SlotInfo[0].
                                      FontIndex].pFMFData->Metrics.
                                      usCodePage;
                                CardFont1 = TRUE;
                            }

                            if ((!CardFont2) &&
                                 prdu_strcmp(pCardList->pCardName,
                                      PrinterData->CardData[PrinterData->
                                      SlotInfo[0].FontIndex].pCardName))
                            {
                                SystemCodePage2 = pCardList->pFMFData->
                                                  Metrics.usCodePage;
                                CardFont2 = TRUE;
                            }

                            FMFCodePage = pCardList->pFMFData->
                                                          Metrics.usCodePage;

                            /***********************************************/
                            /*  If the fmf has either code page 437, 850   */
                            /*  or the determined SystemCodePage and is    */
                            /*  the correct quality level then allow it.   */
                            /*  PD00740 : Change from QualityFlag to       */
                            /*  !QualityFlag.                              */
                            /***********************************************/
                            if ((((SystemCodePage1 == FMFCodePage) &&
                                  (!prdu_strcmp(pCardList->pCardName,
                                     PrinterData->CardData[PrinterData->
                                      SlotInfo[0].FontIndex].pCardName))) ||
                                 ((SystemCodePage2 == FMFCodePage) &&
                                  (prdu_strcmp(pCardList->pCardName,
                                    PrinterData->CardData[PrinterData->
                                      SlotInfo[0].FontIndex].pCardName))) ||
                                 (FMFCodePage == 437) || (FMFCodePage == 850))
                                 && (!QualityFlag))
                            {
                                TotalCartridgeFonts += 2;
                            }

                            if (!QualityFlag)
                            {
                                /*******************************************/
                                /*  PD00740: Change value from FALSE to    */
                                /*  TRUE here and vis-versa on the next    */
                                /*  one.                                   */
                                /*******************************************/
                                QualityFlag = TRUE;
                            }
                            else
                            {
                                QualityFlag = FALSE;
                            }
                         }
                         else
                         {
                             TotalCartridgeFonts +=
                                                pDDT->DDTCardImageNumAttrs;
                         }
                      }
                      else
                      {
                         continue;
                      }
                      break;
                   }
                 }

                    CapValue = DCIData->DCIPdbInstance->TotalResidentFonts+
                               DCIData->DCIPdbInstance->TotalCodePageFonts+
                               DCIData->DCIPdbInstance->TotalDownloadFonts+
                               TotalCartridgeFonts;
               }
               else
               {
                  CapValue = DCIData->DCIPdbInstance->TotalResidentFonts+
                             DCIData->DCIPdbInstance->TotalCodePageFonts+
                             DCIData->DCIPdbInstance->TotalDownloadFonts+
                             DCIData->DCIPdbInstance->TotalCartridgeFonts;
               }
            }
            else
            {
                CapValue = 0;
            }
            break;

        case CAPS_GRAPHICS_SUBSET:
            CapValue = 0;
            break;

        case CAPS_GRAPHICS_VERSION:
            CapValue = 0;
            break;

        case CAPS_GRAPHICS_VECTOR_SUBSET:
            CapValue = 0;
            break;

        case CAPS_DEVICE_WINDOWING:
            CapValue = 0;
            break;

        case CAPS_ADDITIONAL_GRAPHICS:
            /******************************************************************/
            /* Additional graphics support.                                   */
            /******************************************************************/
            CapValue = CAPS_GRAPHICS_KERNING_SUPPORT;

            /******************************************************************/
            /* Get the FontInfo for the default font.  No check for memory dc */
            /* because the default font is always set up.                     */
            /******************************************************************/
            pFontInfo = &(DCIData->DCIPdbInstance->DfltFont.Info);

            if (pFontInfo->Type != FT_ENGINE)
            {
               CapValue |= CAPS_FONT_IMAGE_DEFAULT;
            }

            /******************************************************************/
            /* PD00673: Set CAPS_ENHANCED_FONTMETRICS flag to tell 2.0 engine */
            /* that the driver can expand the metrics beyond the old          */
            /* sizeof(FONTMETRICS) size                                       */
            /******************************************************************/
            CapValue |= CAPS_ENHANCED_FONTMETRICS;

            /******************************************************************/
            /*  P500079/PD00791: Set CAPS_CLIP_FILLS flag to tell 32-bit      */
            /*  engine that the driver will check for COM_PRECLIP and if set  */
            /*  it will assume the engine has pre-clipped.                    */
            /******************************************************************/
            CapValue |= CAPS_CLIP_FILLS;
            break;

        case CAPS_PHYS_COLORS:

                /**************************************************************/
                /*  PD00567 : Have to fudge the values returned here so that  */
                /*  we don't confuse the apps into thinking that our source   */
                /*  bitmap greyscale capable drivers are really color         */
                /*  printers.                                                 */
                /**************************************************************/
                if ((DRIVER_TYPE == DDT_IBM42XX_DRV) &&
                    (DCIData->DCIPdbInstance->PrinterType == IBM_4224_COLOR))
                {
                    CapValue = DDT_EIGHT_COLORS;
                }
                else
                {
                    CapValue = DDT_TWO_COLORS;
                }
            break;

        case CAPS_COLOR_INDEX:
            CapValue = MAX_COLOR_INDEX;
            break;

        case CAPS_GRAPHICS_CHAR_WIDTH:
            CapValue = CellWidth;
            break;

        case  CAPS_GRAPHICS_CHAR_HEIGHT:
            CapValue = CellHeight;
            break;

        case CAPS_HORIZONTAL_FONT_RES:
            /******************************************************************/
            /* Used to return the maximum resolution, this being the          */
            /* resolution that the fonts are defined in.                      */
            /******************************************************************/
//          Printer  = DCIData->DCIPdbInstance->PrinterType;
//          Index    = DDT[Printer]->DDTNoOfRasterModes;
//          CapValue = DDT[Printer]->DDTRasterMode[Index-1].ResWidth;

            /******************************************************************/
            /* Return the current resolution.                                 */
            /******************************************************************/
            CapValue = RasterWidth;

            break;

        case  CAPS_VERTICAL_FONT_RES:
            /******************************************************************/
            /* Used to return the maximum resolution.  This being the         */
            /* resolution that the fonts are defined in.                      */
            /******************************************************************/
//          Printer  = DCIData->DCIPdbInstance->PrinterType;
//          Index    = DDT[Printer]->DDTNoOfRasterModes;
//          CapValue = DDT[Printer]->DDTRasterMode[Index-1].ResDepth;

            /******************************************************************/
            /* Return the current resolution.                                 */
            /******************************************************************/
            CapValue = RasterDepth;

            break;

        case  CAPS_DEVICE_FONT_SIM:
            /******************************************************************/
            /* Indicate which font attributes we require the engine to        */
            /* simulate when a device font is being used: don't simulate      */
            /* italic as this produces incorrect output since device text     */
            /* cannot be clipped to the opaque rect PD00076: Strikeout no     */
            /* longer simulated.                                              */
            /******************************************************************/
            CapValue = 0L;
            break;

        default:
            /******************************************************************/
            /* Caps values for out of range indices are set to 0.             */
            /******************************************************************/
            CapValue = 0L;
            break;
        }
        /*.. switch ( (USHORT) ArgOutIndex++ ) .......................*/

        TRACE4(TFUNC, "Arg Value", &CapValue, 1);

        /**********************************************************************/
        /* Write the CapValue                                                 */
        /**********************************************************************/
        *ArgOutData++ = CapValue;
    }
    /*.. for ( ; ArgOutCount-- > 0; ) ................................*/

    TRACE4(TFUNC, "Exit OK", FNULL, 0);

    prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,9,D8)
#endif
    return((ULONG)OK);
}
#undef TFUNC
