/*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.                                */
/*                                                                           */
/*****************************************************************************/
// query.c

#define INCL_DOS
#define INCL_PM
#include <os2.h>

#define INCL_GRE_DEVICE
#define INCL_DDIMISC
#define INCL_WINSEI
#define INCL_WINSHELLDATA
#define INCL_GPIERRORS
#include <pmddi.h>

// c includes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
#include <builtin.h>

#include "def.h"
#include "driver.h"
#include "funcs.h"
#include "assert.h"


//----------------------------------------------------------------------------------------
LONG ENGENTRY QueryDeviceBitmaps(       HDC            hdc,
                                        PLONG          paOutData,
                                        LONG           cOutData,
                                        PDDC           pddc,
                                        ULONG          ulFunction )
{
  REGREC      regrec;
  ULONG       ulException;
  LONG        lrc;


  REGISTERHANDLER( regrec );
  ulException = setjmp( regrec.jmp );
  if( ulException ) {
    // clean up here
    assert( FALSE );
    CheckForTermination( &regrec, ulException, pddc );
    // error result
    lrc = FALSE;
    goto depart;
  }
  ENTERDDC( pddc );


  lrc = GreQueryDeviceBitmaps( pddc->hdcShadow,  paOutData, cOutData  );
  assert( lrc );

depart:
  EXITDDC( pddc );
  UNREGISTERHANDLER( regrec );
  return lrc;
}



//----------------------------------------------------------------------------------------

LONG ENGENTRY QueryDeviceCaps(          HDC            hdc,
                                        LONG           lIndex,
                                        PLONG          paOutData,
                                        LONG           cOutData,
                                        PDDC           pddc,
                                        ULONG          ulFunction )
{
  REGREC      regrec;
  ULONG       ulException;
  ULONG       lCap;
  LONG        lrc;
  LONG        i;
  BOOL        fOK;
  PLONG       plCap;
  PLONG       alShadowCaps;


  REGISTERHANDLER( regrec );
  ulException = setjmp( regrec.jmp );
  if( ulException ) {
    assert( FALSE );
    // clean up here
    CheckForTermination( &regrec, ulException, pddc );
    // error result
    SetErrorInfo( SEVERITY_ERROR, PMERR_INV_LENGTH_OR_COUNT );
    lrc = FALSE;
    goto depart;
  }

  // check args;
  if( lIndex < 0  ||  cOutData  < 1  ||  !paOutData  ) RAISEEXCEPTION( XCPT_USER );

  // get the capabilities of the shadow DC
  alShadowCaps = (PLONG) AllocMem(  pddc->pdb->pvHeap,  sizeof( LONG ) * cOutData );
  assert( alShadowCaps );

  fOK = DevQueryCaps( pddc->hdcShadow, lIndex, cOutData, alShadowCaps );
  assert( fOK );


  for( i = 0, lCap = lIndex;   i < cOutData;   i++, lCap++  ) {

    plCap = paOutData + i;

    switch( lCap ) {

    case CAPS_BACKGROUND_MIX_SUPPORT:
    case CAPS_BITMAP_FORMATS:
    case CAPS_COLORS:
    case CAPS_COLOR_BITCOUNT:
    case CAPS_COLOR_INDEX:
    case CAPS_COLOR_PLANES:
    case CAPS_COLOR_TABLE_SUPPORT:
    case CAPS_FOREGROUND_MIX_SUPPORT:
    case CAPS_HORIZONTAL_FONT_RES:
    case CAPS_MARKER_HEIGHT:
    case CAPS_MARKER_WIDTH:
    case CAPS_PHYS_COLORS:
    case CAPS_RASTER_CAPS:
    case CAPS_SMALL_CHAR_HEIGHT:
    case CAPS_SMALL_CHAR_WIDTH:
    case CAPS_VERTICAL_FONT_RES:
      // these capabilities of the printer are the same as the shadow DC
      *plCap = alShadowCaps[ lCap ];
      break;


    case CAPS_DEVICE_FONTS:
    case CAPS_DEVICE_FONT_SIM:
    case CAPS_DEVICE_POLYSET_POINTS:
    case CAPS_DEVICE_WINDOWING:
    case CAPS_GRAPHICS_SUBSET:
    case CAPS_GRAPHICS_VECTOR_SUBSET:
    case CAPS_GRAPHICS_VERSION:
    case CAPS_LINEWIDTH_THICK:
    case CAPS_MOUSE_BUTTONS:
    case CAPS_WINDOW_BYTE_ALIGNMENT:
    default:
      // unsupported capabilities
      *plCap = 0;
      break;




    case CAPS_FAMILY:
      // customary to return OD_DIRECT (5) for this
      *plCap = OD_DIRECT;
      break;

    case CAPS_IO_CAPS:
      // device supports output (2)
      *plCap = CAPS_IO_SUPPORTS_OP;
      break;

    case CAPS_TECHNOLOGY:
      *plCap = CAPS_TECH_RASTER_PRINTER;
      break;

    case CAPS_DRIVER_VERSION:
      // written for OS/2 2.1
      *plCap = 0x00000210;
      break;

    case CAPS_HEIGHT:
      // default page height in pels
      assert( pddc->pdb );
      assert( pddc->pdb->pSupportedDevice );
      *plCap = pddc->pdb->pSupportedDevice->paFormInfo->hcinfo.yPels;
      break;

    case CAPS_WIDTH:
      // default page height in pels
      assert( pddc->pdb );
      assert( pddc->pdb->pSupportedDevice );
      *plCap = pddc->pdb->pSupportedDevice->paFormInfo->hcinfo.xPels;
      break;

    case CAPS_HEIGHT_IN_CHARS:
      // assume 6 lines per inch of 12 point text on Letter
      *plCap = 66;
      break;

    case CAPS_WIDTH_IN_CHARS:
      // assume 80 chars per line of 12 point text on Letter
      *plCap = 80;
      break;

    case CAPS_VERTICAL_RESOLUTION:
    case CAPS_HORIZONTAL_RESOLUTION:
      // return cap in pels per meter; there are 39.37 inches per meter
      assert( pddc->pdb->pSupportedDevice->ulXResolution ==  pddc->pdb->pSupportedDevice->ulYResolution );
      *plCap = ( pddc->pdb->pSupportedDevice->ulXResolution * 3937 ) / 100;
      break;

    case CAPS_CHAR_HEIGHT:
    case CAPS_GRAPHICS_CHAR_HEIGHT:
      // default char height in pels
      if( pddc->pdb->ulType == OD_MEMORY ) {
        *plCap = alShadowCaps[ lCap ];
      } else {
        *plCap = ( DEFAULT_POINTSIZE * pddc->pdb->pSupportedDevice->ulXResolution ) / 72;
      }
      break;

    case CAPS_CHAR_WIDTH:
    case CAPS_GRAPHICS_CHAR_WIDTH:
      if( pddc->pdb->ulType == OD_MEMORY ) {
        *plCap = alShadowCaps[ lCap ];
      } else {
        *plCap = pddc->pdb->pSupportedDevice->ulXResolution / DEFAULT_PITCH;
      }
      break;



    case CAPS_VIO_LOADABLE_FONTS:
      if( pddc->pdb->ulType == OD_MEMORY ) {
        *plCap = alShadowCaps[ lCap ];
      } else {
        *plCap = 0;
      }
      break;


    case CAPS_ADDITIONAL_GRAPHICS:
      if( pddc->pdb->ulType == OD_MEMORY) {
        *plCap = alShadowCaps[ lCap ]
                   &~CAPS_FONT_OUTLINE_DEFAULT
                   &~CAPS_FONT_IMAGE_DEFAULT
                   &~CAPS_FONT_OUTLINE_MANAGE
                   &~CAPS_FONT_IMAGE_MANAGE
                   &~CAPS_ENHANCED_FONTMETRICS
                   | CAPS_CLIP_FILLS ;
      } else {
        *plCap = 0;
      }
      break;


    }


  }

  FreeMem( alShadowCaps );

  lrc = TRUE;
depart:
  UNREGISTERHANDLER( regrec );
  return lrc;
}



//----------------------------------------------------------------------------------------

LONG ENGENTRY QueryDevResource2(        HDC            hdc,
                                        ULONG          lType,
                                        ULONG          id,
                                        PDDC           pddc,
                                        ULONG          ulFunction )
{
  REGREC      regrec;
  ULONG       ulException;
  LONG        lrc;

  REGISTERHANDLER( regrec );
  ulException = setjmp( regrec.jmp );
  if( ulException ) {
    CheckForTermination( &regrec, ulException, pddc );
    // error result
    SetErrorInfo( SEVERITY_ERROR, PMERR_INV_LENGTH_OR_COUNT );
    lrc = GPI_ALTERROR;
    goto depart;
  }

  // none available
  lrc = 0;

depart:
  UNREGISTERHANDLER( regrec );
  return lrc;
}



//----------------------------------------------------------------------------------------

LONG ENGENTRY QueryHardcopyCaps(        HDC            hdc,
                                        LONG           lStart,
                                        LONG           cCount,
                                        PHCINFO        pInfo,
                                        PDDC           pddc,
                                        ULONG          ulFunction )
{
  REGREC      regrec;
  ULONG       ulException;
  LONG        lrc;
  LONG        i;
  PFORMINFO   pfi;



  assert( pddc );
  assert( pddc->pdb );
  assert( pddc->pdb->pSupportedDevice );


  REGISTERHANDLER( regrec );
  ulException = setjmp( regrec.jmp );
  if( ulException ) {
    assert( FALSE );
    CheckForTermination( &regrec, ulException, pddc );
    // error result
    SetErrorInfo( SEVERITY_ERROR, PMERR_INV_LENGTH_OR_COUNT );
    lrc = DQHC_ERROR;
    goto depart;
  }


  if( cCount == 0 ) {
    // return count of hard copy forms supported for this device
    lrc = pddc->pdb->pSupportedDevice->cForms;
    goto depart;
  }

  if( lStart >= pddc->pdb->pSupportedDevice->cForms ) {
    // request is out of range
    lrc = 0;
    goto depart;
  }


  // copy this many hdcinfo structs
  cCount = min( pddc->pdb->pSupportedDevice->cForms - lStart, cCount );

  pfi = pddc->pdb->pSupportedDevice->paFormInfo + lStart;

  for( i=0; i < cCount; i++ ) {
    *pInfo = pfi->hcinfo;
    pInfo++;
    pfi++;
  }

  lrc = cCount;

depart:
  UNREGISTERHANDLER( regrec );
  return lrc;
}


