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

//  DeviceQueryFontAttributes
//  DeviceQueryFonts
//  ErasePS
//  NotifyClipChange
//  NotifyTransformChange
//  RealizeFont
//  RealizeFont


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

#define INCL_DDIMISC
#define INCL_DDIMISC2
#define INCL_DDICOMFLAGS
#define INCL_GRE_DEVMISC2
#define INCL_GRE_REGIONS
#define INCL_GRE_CLIP
#define INCL_INNER_GRE
#define INCL_GRE_XFORMS
#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 DeviceQueryFontAttributes(HDC            hdc,
                                        ULONG          cMetrics,
                                        PFONTMETRICS   pfm,
                                        PDDC           pddc,
                                        ULONG          ulFunction )
{
  REGREC      regrec;
  ULONG       ulException;
  ULONG       ulrc;


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

  ENTERDDC( pddc );

  // has no fonts
  // should never be called
  assert( FALSE );


  ulrc = TRUE;


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



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

LONG ENGENTRY DeviceQueryFonts(         HDC            hdc,
                                        ULONG          flOptions,
                                        PSZ            pszFacename,
                                        PFONTMETRICS   pfm,
                                        ULONG          cMetrics,
                                        PLONG          pcFonts,
                                        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 = GPI_ALTERROR;
    goto depart;
  }


  // no device fonts supported
  assert( pcFonts );
  *pcFonts = 0;

  // no more to return
  lrc = 0;


depart:
  UNREGISTERHANDLER( regrec );
  return lrc;
}



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

LONG ENGENTRY ErasePS(                  HDC            hdc,
                                        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 = GreErasePS( pddc->hdcShadow );
  assert( lrc != GPI_ERROR );


  lrc = TRUE;

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



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

LONG ENGENTRY NotifyClipChange(         HDC            hdc,
                                        PRECTL         prclBound,
                                        ULONG          cRect,
                                        ULONG          idClipPath,
                                        PDDC           pddc,
                                        ULONG          ulFunction )
{
  REGREC      regrec;
  RECTL       rclBounds;
  POINTL      ptl;
  ULONG       ulException;
  LONG        lrc;
  HRGN        hrgnOld = (HRGN)0;
  ULONG       ul;
  PFN         pfnNotifyClipChange;


  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 );



  // de-select any current clip region from the shadow DC by setting a null one
  lrc = GreSelectClipRegion( pddc->hdcShadow, (HRGN)0, &hrgnOld );
  assert( lrc != RGN_ERROR );
  assert( hrgnOld ? hrgnOld == pddc->hrgnShadow : TRUE );

  // copy this DC's clip region into the region I created at enable time
  lrc = GreCopyClipRegion( hdc, pddc->hrgnShadow, &rclBounds, COPYCRGN_ALLINTERSECT );
  assert( lrc != RGN_ERROR );

  // is there a DC offset for copied region?
  if( pddc->ptlDCOrigin.x || pddc->ptlDCOrigin.y ) {
    ptl.x = -pddc->ptlDCOrigin.x;
    ptl.y = -pddc->ptlDCOrigin.y;
    lrc = GreOffsetRegion( hdc, pddc->hrgnShadow, &ptl );
    assert( lrc );
  }

  // set it to shadow dc
  ul = GreSelectClipRegion( pddc->hdcShadow, pddc->hrgnShadow, &hrgnOld );
  assert( ul != RGN_ERROR );
  assert( hrgnOld == (HRGN) 0  );

  // call back the simulation function for NotifyClipChange
  pfnNotifyClipChange = globals.ppfnDispatchTableCopy[ NGreNotifyClipChange & 0x00FF ];
  assert( pfnNotifyClipChange );
  lrc = (LONG) ( *pfnNotifyClipChange ) ( hdc, prclBound, cRect, idClipPath, pddc, ulFunction );
  assert( lrc );

  // successful result
  lrc = TRUE;

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



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

LONG ENGENTRY NotifyTransformChange(    HDC            hdc,
                                        ULONG          flFlags,
                                        PNOTIFYTRANSFORMDATA pXformdata,
                                        PDDC           pddc,
                                        ULONG          ulFunction )
{
  REGREC      regrec;
  ULONG       ulException;
  ULONG       lrc;
  PFN         pfnNotifyTransformChange;


  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 );

  // set this transform at the shadow DC device level
  lrc = InnerGreSetModelXform( pddc->hdcShadow, &pXformdata->xform, SX_OVERWRITE,
                                (ulFunction & 0xFFFF0000)|NGreSetModelXform );

  // if setting xform is successful at device level, set also at engine level
  if( lrc ) {
    pfnNotifyTransformChange = globals.ppfnDispatchTableCopy[ NGreNotifyTransformChange & 0x00FF ];
    assert( pfnNotifyTransformChange );
    lrc = (LONG) ( *pfnNotifyTransformChange ) ( hdc, flFlags, pXformdata, pddc, ulFunction );
    assert( lrc );
  }


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



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

LONG ENGENTRY RealizeFont(              HDC            hdc,
                                        ULONG          cmdCommand,
                                        PFATTRS        pLogFont,
                                        PULONG         pFont,
                                        PDDC           pddc,
                                        ULONG          ulFunction )
{
  REGREC      regrec;
  ULONG       ulException;
  ULONG       ulrc;


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


  ENTERDDC( pddc );


  switch( cmdCommand ) {
  case RF_DEVICE_FONT:
    // no device fonts; return 0 meaning no match found
    ulrc = 0;
    break;
  case RF_LOAD_ENGINE_FONT:
    // engine asking driver to convert an engine font into a device font; 0 means no support
    ulrc = 0;
    break;
  case RF_DELETE_FONT:
    // assert( FALSE );
    ulrc = GPI_ERROR;
    break;
  case RF_DELETE_ENGINE_FONT:
    // assert( FALSE );
    ulrc = GPI_ERROR;
    break;
  default:
    assert( FALSE );
    break;
  }

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