/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 WARP source code is provided to you solely for  */
/*    the purpose of assisting you in your development of OS/2 WARP device   */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
/*    Copyright statement may not be removed.                                */
/*                                                                           */
/*****************************************************************************/
/**********************************************************************/
/*                                                                    */
/*   Module          = EDDQQERY                                       */
/*                                                                    */
/*   Description     = Display Device Driver Query functions:         */
/*                     QueryDeviceBitmaps,                            */
/*                     QueryDeviceCaps,                               */
/*                     QueryHardcopyCaps.                             */
/*                                                                    */
/*   Function        = QueryDeviceBitmaps returns the Internal        */
/*                     bitmap formats supported by the driver.        */
/*                     QueryDeviceCaps returns information about      */
/*                     the capabilities of the driver.                */
/*                     QueryHardcopyCaps returns information about    */
/*                     the hardware capabilities of the driver.       */
/*                                                                    */
/*   Reference       = Winthorn Functional Specification              */
/*                     Device Driver Interface Specification          */
/*                     Display Device Driver Design Specification     */
/*                                                                    */
/*                                                                    */
/*                                                                    */
/*   78190   JOHNB     Added device capability for new 16bpp          */
/*                     external format support                        */
/*                                                                    */
/**********************************************************************/
#define INCL_DOSMEMMGR
#define INCL_DOSSEMAPHORES
#define INCL_GRE_DEVICE
#define INCL_DDIMISC
#include <eddinclt.h>

#include <edddtypt.h>

#include <eddacone.h>
#include <eddbcone.h>
#include <eddvcone.h>

#include <eddgextf.h>
#include <eddqextf.h>

#include <eddqcone.h>
#include <eddesres.h>

/**********************************************************************/
/* Most of these externals hold data which is returned as Caps        */
/* values, or rather used to calculate the returned value             */
/**********************************************************************/
extern DDTType                  DDT;
extern AvioFontTableType        AvioBaseFont[NO_OF_AVIO_FONTS];
extern BYTE                     DefaultNormalFont;
extern BYTE                     DefaultSmallFont;
extern ULONG                    cPhysicalColors;
extern USHORT                   MaxLogColorIndex;
extern USHORT                   ResidentFonts;
extern BOOL                     fRealizeSupported;

#define NO_OF_INT_BMAP_FORMATS  2

/**********************************************************************/
/* The table of values returned by QueryDeviceCaps                    */
/* !!!! means the value is filled in at fill physical device time     */
/* by the routine FillInCapsTable below                               */
/**********************************************************************/
#ifdef EXTRAMIX
#define LAST_CAPS_INDEX CAPS_EXTRA_LINE_BACKGROUND_MIX
#else /* EXTRAMIX */
#define LAST_CAPS_INDEX CAPS_DEVICE_FONT_SIM
#endif /* EXTRAMIX */
#define FILLED_IN_LATER 0

ULONG QueryCapsTable[LAST_CAPS_INDEX+1] = {
        FILLED_IN_LATER,        /* CAPS_FAMILY - DC type 0 -> 8       */
        CAPS_IO_SUPPORTS_OP,    /* CAPS_IO_CAPS                       */
        CAPS_TECH_RASTER_DISPLAY,
                                /* CAPS_TECHNOLOGY                    */
        0x0200,                 /* CAPS_DRIVER_VERSION = 2.0          */
        FILLED_IN_LATER,        /* CAPS_WIDTH                   !!!!  */
        FILLED_IN_LATER,        /* CAPS_HEIGHT                  !!!!  */
        FILLED_IN_LATER,        /* CAPS_WIDTH_IN_CHARS          !!!!  */
        FILLED_IN_LATER,        /* CAPS_HEIGHT_IN_CHARS         !!!!  */
        FILLED_IN_LATER,        /* CAPS_HORIZONTAL_RESOLUTION   !!!!  */
        FILLED_IN_LATER,        /* CAPS_VERTICAL_RESOLUTION     !!!!  */
        FILLED_IN_LATER,        /* CAPS_CHAR_WIDTH              !!!!  */
        FILLED_IN_LATER,        /* CAPS_CHAR_HEIGHT             !!!!  */
        FILLED_IN_LATER,        /* CAPS_SMALL_CHAR_WIDTH        !!!!  */
        FILLED_IN_LATER,        /* CAPS_SMALL_CHAR_HEIGHT       !!!!  */
        FILLED_IN_LATER,        /* CAPS_COLORS                  !!!!  */
        STANDARD_FORMAT_PLANES, /* CAPS_COLOR_PLANES                  */
        FILLED_IN_LATER,        /* CAPS_COLOR_BITCOUNT          !!!!  */
        FILLED_IN_LATER,        /* CAPS_COLOR_TABLE_SUPPORT     !!!!  */
        0,                      /* CAPS_MOUSE_BUTTONS:                */
        CAPS_FM_OR               |
         CAPS_FM_OVERPAINT       |
         CAPS_FM_XOR             |
         CAPS_FM_LEAVEALONE      |
         CAPS_FM_AND             |
         CAPS_FM_GENERAL_BOOLEAN,
                                /* CAPS_FOREGROUND_MIX_SUPPORT        */
        CAPS_BM_OR              |
         CAPS_BM_OVERPAINT      |
         CAPS_BM_XOR            |
         CAPS_BM_LEAVEALONE     |
         CAPS_BM_SRCTRANSPARENT |
         CAPS_BM_DESTTRANSPARENT,
                                /* CAPS_BACKGROUND_MIX_SUPPORT        */
        CNT_LOADABLE_LCIDS,     /* CAPS_VIO_LOADABLE_FONTS            */
        CAPS_BYTE_ALIGN_NOT_REQUIRED,
                                /* CAPS_WINDOW_BYTE_ALIGNMENT         */
        NO_OF_INT_BMAP_FORMATS, /* CAPS_BITMAP_FORMATS                */
        CAPS_RASTER_BITBLT          |
         CAPS_RASTER_BITBLT_SCALING |
         CAPS_RASTER_SET_PEL        |
#ifdef FLOOD_FILL
         CAPS_RASTER_FLOOD_FILL     |
#endif /* FLOOD_FILL */
         CAPS_RASTER_FONTS,     /* CAPS_RASTER_CAPS                   */
        DEF_MARKER_HEIGHT,      /* CAPS_MARKER_HEIGHT                 */
        DEF_MARKER_WIDTH,       /* CAPS_MARKER_WIDTH                  */
        FILLED_IN_LATER,        /* CAPS_DEVICE_FONTS            !!!!  */
        0,                      /* CAPS_GRAPHICS_SUBSET               */
        0,                      /* CAPS_GRAPHICS_VERSION              */
        0,                      /* CAPS_GRAPHICS_VERCTOR_SUBSET       */
        CAPS_DEV_WINDOWING_SUPPORT,
                                /* CAPS_DEVICE_WINDOWING              */
        /**************************************************************/
        /* we now let the engine manage our device font               */
        /**************************************************************/
         CAPS_FONT_IMAGE_DEFAULT      |
         CAPS_FONT_IMAGE_MANAGE       |
         CAPS_EXTERNAL_16_BITCOUNT    |                    /* 78190 */
         CAPS_COLOR_CURSOR_SUPPORT,
                                /* CAPS_ADDITIONAL_GRAPHICS           */
        FILLED_IN_LATER,        /* CAPS_PHYS_COLORS             !!!!  */
        FILLED_IN_LATER,        /* CAPS_COLOR_INDEX             !!!!  */
        FILLED_IN_LATER,        /* CAPS_GRAPHICS_CHAR_WIDTH     !!!!  */
        FILLED_IN_LATER,        /* CAPS_GRAPHICS_CHAR_HEIGHT    !!!!  */
#ifdef FONTSIZE
        FILLED_IN_LATER,        /* CAPS_HORIZONTAL_FONT_RES           */
        FILLED_IN_LATER,        /* CAPS_VERTICAL_FONT_RES             */
#else /* FONTSIZE */
        96,                     /* CAPS_HORIZONTAL_FONT_RES           */
        96,                     /* CAPS_VERTICAL_FONT_RES             */
#endif /* FONTSIZE */
        CAPS_DEV_FONT_SIM_BOLD        |
         CAPS_DEV_FONT_SIM_ITALIC     |
         CAPS_DEV_FONT_SIM_UNDERSCORE |
         CAPS_DEV_FONT_SIM_STRIKEOUT,
                                /* CAPS_DEVICE_FONT_SIM               */
#ifdef EXTRAMIX
        0,                      /* CAPS_LINEWIDTH_THICK               */
        CAPS_BM_OR               |
         CAPS_BM_OVERPAINT       |
         CAPS_BM_XOR             |
         CAPS_BM_LEAVEALONE      |
         CAPS_BM_AND             |
         CAPS_BM_GENERAL_BOOLEAN,
                                /* CAPS_EXTRA_AREA_BACKGROUND_MIX     */
        CAPS_BM_OR               |
         CAPS_BM_OVERPAINT       |
         CAPS_BM_XOR             |
         CAPS_BM_LEAVEALONE      |
         CAPS_BM_AND             |
         CAPS_BM_GENERAL_BOOLEAN,
                                /* CAPS_EXTRA_LINE_BACKGROUND_MIX     */
#endif /* EXTRAMIX */
      };

VOID FillInCapsTable(VOID)
{
    /******************************************************************/
    /* These are the fields in the caps table which can only be       */
    /* determined once the driver is up and running                   */
    /* (mostly they depend on which monitor is attached)              */
    /*                                                                */
    /* This routine is called once only by FillPhysicalDeviceBlock    */
    /******************************************************************/
    QueryCapsTable[CAPS_WIDTH]  = (ULONG)DDT.ScreenWidth;
    QueryCapsTable[CAPS_HEIGHT] = (ULONG)DDT.ScreenHeight;
    QueryCapsTable[CAPS_WIDTH_IN_CHARS] = (ULONG)DDT.ScreenWidth /
                       (ULONG)AvioBaseFont[DefaultNormalFont].CellWidth;
    QueryCapsTable[CAPS_HEIGHT_IN_CHARS] = (ULONG)DDT.ScreenHeight /
                      (ULONG)AvioBaseFont[DefaultNormalFont].CellHeight;
    QueryCapsTable[CAPS_HORIZONTAL_RESOLUTION] =
                                       (ULONG)DDT.horizontal_resolution;
    QueryCapsTable[CAPS_VERTICAL_RESOLUTION] =
                                         (ULONG)DDT.vertical_resolution;
    QueryCapsTable[CAPS_CHAR_WIDTH] =
                       (ULONG)AvioBaseFont[DefaultNormalFont].CellWidth;
    QueryCapsTable[CAPS_CHAR_HEIGHT] =
                      (ULONG)AvioBaseFont[DefaultNormalFont].CellHeight;
    QueryCapsTable[CAPS_SMALL_CHAR_WIDTH] =
                        (ULONG)AvioBaseFont[DefaultSmallFont].CellWidth;
    QueryCapsTable[CAPS_SMALL_CHAR_HEIGHT] =
                       (ULONG)AvioBaseFont[DefaultSmallFont].CellHeight;
    QueryCapsTable[CAPS_COLORS]         = cPhysicalColors;
    QueryCapsTable[CAPS_COLOR_BITCOUNT] = DDT.BitCount;
    QueryCapsTable[CAPS_DEVICE_FONTS]   = ResidentFonts;

    /******************************************************************/
    /* Our reported color capabilities depend on the number of bpp.   */
    /******************************************************************/
    if (DDT.BitCount == 8)
    {
        /**************************************************************/
        /* At 8bpp we support palette manager.                        */
        /**************************************************************/
        QueryCapsTable[CAPS_ADDITIONAL_GRAPHICS] |= CAPS_PALETTE_MANAGER;
    }

    if (fRealizeSupported)
    {
        QueryCapsTable[CAPS_COLOR_TABLE_SUPPORT] = CAPS_COLTABL_RGB_8 |
                                                   CAPS_COLTABL_TRUE_MIX |
                                                   CAPS_COLTABL_REALIZE;
    }
    else
    {
        QueryCapsTable[CAPS_COLOR_TABLE_SUPPORT] = CAPS_COLTABL_RGB_8;
    }

    QueryCapsTable[CAPS_PHYS_COLORS]    = 1 << DDT.BitCount;
    QueryCapsTable[CAPS_COLOR_INDEX]    = MaxLogColorIndex;
    QueryCapsTable[CAPS_GRAPHICS_CHAR_WIDTH] =
                                         (ULONG)DDT.graphics_char_width;
    QueryCapsTable[CAPS_GRAPHICS_CHAR_HEIGHT] =
                                        (ULONG)DDT.graphics_char_height;

#ifdef FONTSIZE
    /******************************************************************/
    /* DCR 50 requires us to return different font resolution values  */
    /* for low or high res modes.                                     */
    /******************************************************************/
    if ( DDT.ScreenWidth <= LO_RES_WIDTH )
    {
      /**************************************************************/
      /* Low res - return 96 for both resolutions.                  */
      /**************************************************************/
      QueryCapsTable[CAPS_HORIZONTAL_FONT_RES] = LO_RES_H_FONT_RES;
      QueryCapsTable[CAPS_VERTICAL_FONT_RES]   = LO_RES_V_FONT_RES;
    }
    else if ( DDT.ScreenWidth <= RES_800_WIDTH )
    {
      QueryCapsTable[CAPS_HORIZONTAL_FONT_RES] = RES_800_H_FONT_RES;
      QueryCapsTable[CAPS_VERTICAL_FONT_RES]   = RES_800_V_FONT_RES;
    }
    else
    {
      /**************************************************************/
      /* high res - return 120 unless it's a 17" screen (9518),     */
      /* which requires 96.                                         */
      /**************************************************************/
//    if (17" screen) Need DMQS files to get the width value for 9518
//    {
//      QueryCapsTable[CAPS_HORIZONTAL_FONT_RES] = LO_RES_H_FONT_RES;
//      QueryCapsTable[CAPS_VERTICAL_FONT_RES]   = LO_RES_V_FONT_RES;
//    }
//    else
      {
        QueryCapsTable[CAPS_HORIZONTAL_FONT_RES] = HI_RES_H_FONT_RES;
        QueryCapsTable[CAPS_VERTICAL_FONT_RES]   = HI_RES_V_FONT_RES;
      }
    }
#endif /* FONTSIZE */
}

/**********************************************************************/
/*                                                                    */
/*   QueryDeviceBitmaps returns a list of the Internal bitmap         */
/* formats that the display driver supports into OutData.             */
/*                                                                    */
/*   An application can query the number of Internal formats          */
/* supported using QueryDeviceCaps.                                   */
/*                                                                    */
/*   Each format is returned in the form ( number of planes,          */
/* bitcount ).  The default internal format is returned first; the    */
/* bitcount depends on the current display configuration, the number  */
/* of planes is fixed at one.  The other format is fixed at (1,1).    */
/*                                                                    */
/**********************************************************************/

DDIENTRY eddq_QueryDeviceBitmaps (HDC           hdc,
                                  PBITMAPFORMAT pbmf,
                                  LONG          clBitmapFormats,
                                  PDC           pdcArg,
                                  ULONG         FunN)

{
    /******************************************************************/
    /* Local variables                                                */
    /******************************************************************/
    LONG              i;             /* Loop count                   */

    /******************************************************************/
    /* Prevent compiler warnings.                                     */
    /******************************************************************/
    IgnoreParam(hdc);

    EnterDriver(pdcArg, FunN, EDF_STANDARD);

    /******************************************************************/
    /* the clBitmapFormats parameter is the number of BITMAPFORMAT    */
    /* array elements (according to MS DDK Development Guide) or the  */
    /* number of LONGs in the array (according to IBM OS2 Prog.Ref.)  */
    /* Since the latter seems to work, this requires that the         */
    /* paramter is even (since sizeof(BITMAPFORMAT) = 4). We can      */
    /* enforce this, and also access the array correctly, by dividing */
    /* clBitmapFormat by 2                                            */
    /******************************************************************/
    clBitmapFormats /= 2;

    /******************************************************************/
    /* need at least one BITMAPFORMAT array element to be able to     */
    /* return any data                                                */
    /******************************************************************/
    if (clBitmapFormats <= 0)
    {
        LogError(PMERR_INV_LENGTH_OR_COUNT);
        goto QUERYDEVBITMAPS_ERR_EXIT;
    }

    /******************************************************************/
    /* Place both Internal formats in the user buffer. That most      */
    /* closely matching the physical device goes in the first element */
    /* of the BITMAPFORMAT array                                      */
    /******************************************************************/
    if (clBitmapFormats >= 1)
    {
        /**************************************************************/
        /* Return the color format.                                   */
        /**************************************************************/
        pbmf[0].cPlanes   = 1;
        pbmf[0].cBitCount = DDT.BitCount;

        if (clBitmapFormats >= 2)
        {
            /**********************************************************/
            /* Return the mono format.                                */
            /**********************************************************/
            pbmf[1].cPlanes   = 1;
            pbmf[1].cBitCount = 1;

            /**********************************************************/
            /* Excess elements in the array are set to zero           */
            /**********************************************************/
            for (i = NO_OF_INT_BMAP_FORMATS;
                 i < clBitmapFormats; i++)
            {
                pbmf[i].cPlanes   = 0;
                pbmf[i].cBitCount = 0;
            }
        }
    }

    ExitDriver(pdcArg, FunN, EDF_STANDARD);
    return(OK);

QUERYDEVBITMAPS_ERR_EXIT:
    ExitDriver(pdcArg, FunN, EDF_STANDARD);
    return(ERROR_ZERO);
}


/**********************************************************************/
/*                                                                    */
/*   QueryDeviceCaps returns a number of pieces of information about  */
/* the capabilities of the display driver into OutData.               */
/*                                                                    */
/*   Which pieces of information are to be returned is determined by  */
/* the OutIndex and OutCount parameters.  These refer to a numbered   */
/* list given in the Winthorn Spec.                                   */
/*                                                                    */
/**********************************************************************/
DDIENTRY eddq_QueryDeviceCaps (HDC      hdc,
                               LONG     ArgOutIndex,
                               PULONG   ArgOutData,
                               ULONG    ArgOutCount,
                               PDC      pdcArg,
                               ULONG    FunN)
{
    /******************************************************************/
    /* Prevent compiler warnings.                                     */
    /******************************************************************/
    IgnoreParam(hdc);

    /***************************************************************/
    /* Get driver semaphore and perform entry checks               */
    /***************************************************************/
    EnterDriver(pdcArg, FunN, EDF_STANDARD);

    /******************************************************************/
    /* Do a simple error check on the parameters.                     */
    /******************************************************************/
    if ( (ArgOutIndex < 0) ||
         (ArgOutData == FNULL) )
    {
        LogError(PMERR_INV_QUERY_ELEMENT_NO);
        goto QUERYDEVCAPS_ERR_EXIT;
    }

    /******************************************************************/
    /* Put the only non constant value into the caps table            */
    /******************************************************************/
    QueryCapsTable[CAPS_FAMILY] = pdc->DCIDCType;

    /******************************************************************/
    /* copy any values from the table                                 */
    /******************************************************************/
    while ( ArgOutCount > 0 && ArgOutIndex <= LAST_CAPS_INDEX)
    {
        *ArgOutData++ = QueryCapsTable[ArgOutIndex++];
        ArgOutCount--;
    }

    /******************************************************************/
    /* zero fill any remaining values                                 */
    /******************************************************************/
    while ( ArgOutCount-- > 0)
    {
        *ArgOutData++ = 0;
    }

    /******************************************************************/
    /* Release driver semaphore                                       */
    /******************************************************************/
    ExitDriver(pdcArg, FunN, EDF_STANDARD);

    return(OK);

QUERYDEVCAPS_ERR_EXIT:
    /******************************************************************/
    /* Release driver semaphore                                       */
    /******************************************************************/
    ExitDriver(pdcArg, FunN, EDF_STANDARD);

    return(ERROR_ZERO);
}


/**********************************************************************/
/*                                                                    */
/*   QueryHardcopyCaps returns information about the hardcopy         */
/* capabilities of a device.  It is therefore not relevant for the    */
/* display.  The function will simply return zero indicating that     */
/* the number of forms available is zero.                             */
/*                                                                    */
/**********************************************************************/
DDIENTRY eddq_QueryHardcopyCaps (HDC     hdc,
                                 ULONG   ArgStart,
                                 ULONG   ArgCount,
                                 PHCINFO ArgFormInfo,
                                 PDC     pdcArg,
                                 ULONG   FunN )
{
    /******************************************************************/
    /* Prevent compiler warnings.                                     */
    /******************************************************************/
    IgnoreParam(hdc);
    IgnoreParam(ArgStart);
    IgnoreParam(ArgCount);
    IgnoreParam(ArgFormInfo);

#ifdef FIREWALLS
    /******************************************************************/
    /* Return zero to indicate that no forms are supported.           */
    /* We still enter and exit driver so that we know this call has   */
    /* been made while debugging / timing etc.                        */
    /******************************************************************/
    EnterDriver(pdcArg, FunN, EDF_STANDARD);
    ExitDriver(pdcArg, FunN, EDF_STANDARD);
#endif

    return(0);
}
