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

#define INCL_DOS
#define INCL_GPI
#define INCL_GPIERRORS
#define INCL_DEV
#define INCL_SPL
#include <os2.h>

#define INCL_GRE_LINES
#define INCL_GRE_SCANS
#define INCL_DDICOMFLAGS
#define INCL_DDIMISC
#define INCL_DDIPATHS
#include <pmddi.h>

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

// driver includes
#define INCL_INNER_GRE
#include "def.h"
#include "driver.h"
#include "funcs.h"
#include "assert.h"


//----------------------------------------------------------------------------------------
LONG ENGENTRY DisjointLines(            HDC            hdc,
                                        PPOINTL        paptlPoint,
                                        LONG           cPoints,
                                        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;
  }


  // not called by new engine
  assert( FALSE );


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



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

LONG ENGENTRY DrawLinesInPath(          HDC            hdc,
                                        PRECTL         prclBound,
                                        PCURVE         pLine,
                                        ULONG          cLines,
                                        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 );


  // relay to shadow DC in the display driver

  lrc = InnerGreDrawLinesInPath( pddc->hdcShadow, prclBound, pLine, cLines, ulFunction );
  assert( lrc != GPI_ERROR );



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



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

LONG ENGENTRY GetCurrentPosition(       HDC            hdc,
                                        PPOINTL        paptlPosition,
                                        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 );

  ulrc = InnerGreGetCurrentPosition( pddc->hdcShadow, paptlPosition, ulFunction );
  assert( ulrc );

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



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

LONG ENGENTRY PolyLine(                 HDC            hdc,
                                        PPOINTL        paptlPoint,
                                        LONG           cPoints,
                                        PDDC           pddc,
                                        ULONG          ulFunction )
{
  REGREC      regrec;
  ULONG       ulException;
  ULONG       ulrc;
  PFN         pfnPolyLine;


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

  ENTERDDC( pddc );


  if( ulFunction &  ( COM_PATH | COM_AREA )) {
    // this polyline drawing is part of an area or path definition
    // call back into the engine to do the clipping
    // call the simulation function
    // obtain the original engine pointer to polyline before I replaced it at FILL_LOGICAL in ENABLE.C
    pfnPolyLine = globals.ppfnDispatchTableCopy[ NGrePolyLine & 0x00FF ];
    ulrc = (ULONG) ( *pfnPolyLine )( hdc, paptlPoint, cPoints, pddc, ulFunction );
    assert( ulrc != GPI_ERROR );
    ulrc = GPI_OK;

  } else {

    // no path or area in effect
    // get the shadow DC to do the drawing
    ulrc = InnerGrePolyLine( pddc->hdcShadow, paptlPoint, cPoints, ulFunction );
    assert( ulrc != GPI_ERROR );
    ulrc = GPI_OK;
  }

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



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

LONG ENGENTRY PolyScanline(             HDC            hdc,
                                        PSCANDATA      pScanData,
                                        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 );



  ulrc = InnerGrePolyScanline( pddc->hdcShadow, pScanData, ulFunction );
  assert( ulrc != GPI_ERROR );


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




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


LONG ENGENTRY PolyShortLine(            HDC            hdc,
                                        PSHORTLINE     pShortLine,
                                        PDDC           pddc,
                                        ULONG          ulFunction )
{
  REGREC      regrec;
  ULONG       ulException;
  ULONG       ulrc;


  REGISTERHANDLER( regrec );
  ulException = setjmp( regrec.jmp );
  if( ulException ) {
    CheckForTermination( &regrec, ulException, pddc );
    // error result
    ulrc = GPI_ERROR;
    goto depart;
  }

  // not called by new engine
  assert( FALSE );

depart:
  UNREGISTERHANDLER( regrec );
  return ulrc;
}



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

LONG ENGENTRY SetCurrentPosition(       HDC            hdc,
                                        PPOINTL        pptlPosition,
                                        PDDC           pddc,
                                        ULONG          ulFunction )
{
  REGREC      regrec;
  ULONG       ulException;
  ULONG       ulrc;
  PFN         pfnSetCurrentPosition;


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

  ENTERDDC( pddc );


  if( ulFunction &  ( COM_PATH | COM_AREA )) {

    // obtain the original engine pointer to setcurrentposition to call back into the engine
    pfnSetCurrentPosition = globals.ppfnDispatchTableCopy[ NGreSetCurrentPosition & 0x00FF ];
    ulrc = (ULONG) ( *pfnSetCurrentPosition )( hdc, pptlPosition, pddc, ulFunction );
    assert( ulrc != GPI_ERROR );
  }

  // call into the shadow dc
  ulrc = InnerGreSetCurrentPosition( pddc->hdcShadow, pptlPosition, ulFunction );
  assert( ulrc != GPI_ERROR );

  ulrc = TRUE;

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



