/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT (C) Microsoft 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.                                */
/*                                                                           */
/*****************************************************************************/
#pragma  pagesize(55)

/**************************************************************************
 *
 * SOURCE FILE NAME =  DISPATCH.C
 *
 * DESCRIPTIVE NAME =  plotter driver source
 *
 *
 * VERSION = V2.0
 *
 * DATE        09/18/88
 *
 * DESCRIPTION This file contains functions and macros to hook and unhook
 *             entries in the dispatch table.
 *
 *
 * FUNCTIONS   exchange_dispatch()  Modify the engine supplied dispatch table.
 *
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/

#include "plotters.h"
#include "dispatch.h"                  /* Our dispatch table                */
#include "attribs.h"
#include "bitmap.h"
#include "bounds.h"
#include "box.h"
#include "clip.h"
#include "color.h"
#include "escquery.h"
#include "font.h"
#include "marker.h"
#include "outparc.h"
#include "outpline.h"
#include "paths.h"
#include "textout.h"
#include "xforms.h"
#include "enable.h"

#define COPY(Fun)                                                 \
    da##Fun = (PFNL)*(pDispatchTable + (NGre##Fun & 0xffL));

#define HOOK(Fun)                                                 \
    *(pDispatchTable + (NGre##Fun & 0xffL)) = (ULONG)Fun;

#define SWAP(Fun)                                                 \
    da##Fun = (PFNL)*(pDispatchTable + (NGre##Fun & 0xffL));      \
    *(pDispatchTable + (NGre##Fun & 0xffL)) = (ULONG)Fun;

/*
** Waiting for new GRE headers to be updated
** we can take this out when nGreDevicePalette is in pmddim.h
*/
#ifndef  NGreDevicePalette
#define  NGreDevicePalette 0x4040
#endif

/*****************************************************************************
** To Hook the original Gre function for MEMORY DC. C/Set2 Conversion : Kran
******************************************************************************/

#define UNHOOK(Fun)                                              \
    *(pDispatchTable + (NGre##Fun & 0xffL)) = (ULONG)da##Fun;
/*
**      Following variables are set to contain the entry address of the
**   corresponding entry point in the dispatch table supplied to us by
**   the engine.  We use these to call directly into the engine bypassing
**   the normal dispatch mechanism.  This is done whenever we hook the
**   function and also wich to call the engine's function,  and is also
**   used in the few occasions when we wish to avoid the dispatch overhead.
*/
/*
** Simulated or utility functions on the non raster GRE
*/
PFNL daArc;
PFNL daBeginArea;
PFNL daBoxBoth;
PFNL daBoxBoundary;
PFNL daBoxInterior;
PFNL daCharString;
PFNL daCharStringPos;
PFNL daConvert;
PFNL daConvertWithMatrix;
PFNL daDeviceQueryFontAttributes;
PFNL daDisjointLines;
PFNL daEndArea;
PFNL daFillPath;
PFNL daFullArcBoth;
PFNL daFullArcBoundary;
PFNL daFullArcInterior;
PFNL daNotifyClipChange;
PFNL daNotifyTransformChange;
PFNL daPaintRegion;
PFNL daPartialArc;
PFNL daPolyLine;
PFNL daPolyMarker;
PFNL daPolySpline;
PFNL daQueryCharPositions;
PFNL daQueryTextBox;
PFNL daQueryWidthTable;
PFNL daSelectClipPath;
PFNL daSetArcParameters;
PFNL daSetCurrentPosition;
PFNL daStrokePath;
PFNL daPolygonSet;
PFNL daDevicePolygonSet;
/* Need the following variables to store entry addresses for Memorydc */
PFNL daGetStyleRatio;
PFNL daSetStyleRatio;
PFNL daBitblt;

/*
** Additional Simulated or utility functions on the raster GRE
*/
PFNL daAccumulateBounds;
PFNL daCreateLogColorTable;
PFNL daDeviceCreateBitmap;
PFNL daDeviceDeleteBitmap;
PFNL daDeviceGetAttributes;
PFNL daDeviceQueryFonts;
PFNL daDeviceSelectBitmap;
PFNL daDeviceSetAttributes;
PFNL daDeviceSetDCOrigin;
PFNL daDeviceSetGlobalAttribute;
PFNL daDrawLinesInPath;
PFNL daErasePS;
PFNL daGetBitmapBits;
PFNL daGetBoundsData;
PFNL daGetCodePage;
PFNL daGetCurrentPosition;
PFNL daGetDCOrigin;
PFNL daGetLineOrigin;
PFNL daGetPairKerningTable;
PFNL daGetPel;
PFNL daGetStyleRatio;
PFNL daImageData;
PFNL daLockDevice;
PFNL daPolyShortLine;
PFNL daPolyScanline;
PFNL daQueryColorData;
PFNL daQueryColorIndex;
PFNL daQueryDeviceBitmaps;
PFNL daQueryDeviceCaps;
PFNL daQueryLogColorTable;
PFNL daQueryNearestColor;
PFNL daQueryRealColors;
PFNL daQueryRGBColor;
PFNL daRealizeColorTable;
PFNL daRealizeFont;
PFNL daResetBounds;
PFNL daSetBitmapBits;
PFNL daSetCodePage;
//PFNL daSetDefaultAttributes;
PFNL daSetLineOrigin;
PFNL daSetPel;
PFNL daUnlockDevice;
PFNL daUnrealizeColorTable;


 /*
 ** Global Function Header
 */
/***************************************************************************
 *
 * FUNCTION NAME = exchange_dispatch()
 *
 *
 * DESCRIPTION   = Modify the engine supplied dispatch table.
 *
 *
 * INPUT         = pDispatchTable
 *
 *
 *
 * OUTPUT        = NONE
 *
 *
 *
 *
 * RETURN-NORMAL = NONE
 *
 *
 *
 * RETURN-ERROR  = NONE
 *
 *
 *
 **************************************************************************/

VOID exchange_dispatch(PULONG pDispatchTable)
{
  LONG lEngineVersion = GreQueryEngineVersion();

  /*
  **   The following are functions which the plotter driver does NOT
  ** hook, but needs to save the Engine address because it makes that
  ** particular Engine call.
  */
  COPY(Convert);
  COPY(SelectClipPath);
  COPY(ConvertWithMatrix);

  /*
  **     Functions which we hook and process completely.  None of these
  **   involve engine call-back.
  */
  HOOK(Escape);                            /* Must remain hooked for new GRE */
  HOOK(DevicePalette);                     /* Must remain hooked for new GRE */
  HOOK(QueryHardcopyCaps);                 /* Must remain hooked for new GRE */

  /*
  ** Functions which we will hook for a direct DC and unhook for memory DC
  */
  /*
  ** For the new Raster GRE do not hook bitmap functions.
  ** We will hook sdBitBlt in QueryDeviceSurface.
  ** We also do not need to hook the color functions.
  **
  */
  if (lEngineVersion >= RASTER_ENGINE_22)
  {
    COPY(DeviceCreateBitmap);
    COPY(DeviceDeleteBitmap);
    COPY(DeviceSelectBitmap);
    COPY(GetBitmapBits);
    COPY(GetPel);
    COPY(ImageData);
    COPY(QueryDeviceBitmaps);
    COPY(SetBitmapBits);
    COPY(SetPel);

    COPY(CreateLogColorTable);
    COPY(QueryColorData);
    COPY(QueryColorIndex);
    COPY(QueryLogColorTable);
    COPY(QueryNearestColor);
    COPY(QueryRealColors);
    COPY(QueryRGBColor);
    COPY(RealizeColorTable);
    COPY(UnrealizeColorTable);
  }
  else
  {
    SWAP(Bitblt);
    SWAP(DeviceCreateBitmap);
    SWAP(DeviceDeleteBitmap);
    SWAP(DeviceSelectBitmap);
    SWAP(GetBitmapBits);
    SWAP(GetPel);
    SWAP(ImageData);
    SWAP(QueryDeviceBitmaps);
    SWAP(SetBitmapBits);
    SWAP(SetPel);

    SWAP(CreateLogColorTable);
    SWAP(QueryColorData);
    SWAP(QueryColorIndex);
    SWAP(QueryLogColorTable);
    SWAP(QueryNearestColor);
    SWAP(QueryRealColors);
    SWAP(QueryRGBColor);
    SWAP(RealizeColorTable);
    SWAP(UnrealizeColorTable);
  }

  /*
  **    Function that we wish to hook out,  but whose address is also
  **  needed because we may call back to the engine if the call cannot
  **  be processed.
  */
  SWAP(AccumulateBounds);
  SWAP(DeviceGetAttributes);
  SWAP(DeviceQueryFonts);
  SWAP(DeviceSetAttributes);
  SWAP(DeviceSetDCOrigin);
  SWAP(DeviceSetGlobalAttribute);
  SWAP(DrawLinesInPath);
  SWAP(ErasePS);
  SWAP(GetBoundsData);
  SWAP(GetCodePage);
  SWAP(GetCurrentPosition);
  SWAP(GetDCOrigin);
  SWAP(GetLineOrigin);
  SWAP(GetPairKerningTable);
  SWAP(GetStyleRatio);
  SWAP(LockDevice);
  SWAP(PolyShortLine);
  SWAP(PolyScanline);
  SWAP(QueryDeviceCaps);
  SWAP(RealizeFont);
  SWAP(ResetBounds);
  SWAP(SetCodePage);
  SWAP(SetLineOrigin);
  SWAP(UnlockDevice);

  /*
  **    Function that we wish to hook out,  but whose address is also
  **  needed because we may call back to the engine if the call cannot
  **  be processed.
  */
  SWAP(Arc);
  SWAP(BeginArea);
  SWAP(BoxBoth);
  SWAP(BoxBoundary);
  SWAP(BoxInterior);
  SWAP(CharString);
  SWAP(CharStringPos);
  SWAP(DeviceQueryFontAttributes);
  SWAP(DisjointLines);
  SWAP(EndArea);
  SWAP(FillPath);
  SWAP(FullArcBoth);
  SWAP(FullArcBoundary);
  SWAP(FullArcInterior);
  SWAP(NotifyClipChange);
  SWAP(NotifyTransformChange);
  SWAP(PaintRegion);
  SWAP(PartialArc);
  SWAP(PolyLine);
  SWAP(PolyMarker);
  SWAP(PolySpline);
  SWAP(QueryCharPositions);
  SWAP(QueryTextBox);
  SWAP(QueryWidthTable);
  SWAP(SetArcParameters);
  SWAP(SetCurrentPosition);
//  SWAP(SetDefaultAttributes);
  SWAP(SetStyleRatio);                /* NEED TO UNHOOK IN FPDB FOR MEMORY_DC */
  SWAP(StrokePath);
//  32 bit only
  SWAP(PolygonSet);
//  SWAP(DevicePolygonSet);
}

/***************************************************************************
 * FUNCTION NAME = unhook_for_memDC
 *
 * DESCRIPTION   = UnHooks all the functions that are not mandatory and hooks
 *                 all the mandatory functions.
 *                 Support for Bitmap Handling and MEMORY DC
 *                 This function should only be called for MemoryDC
 *
 * Created 06/08/93 : Kran
 ***************************************************************************/

VOID unhook_for_memDC  (PULONG pDispatchTable)
{
 /*********** UnHook the extra functions that are not mandatory ************/
 /* note this macro actually copies the original address. Kran */


  LONG lEngineVersion = GreQueryEngineVersion();
  /*
  ** For an engine memory DC we unhook everything
  ** except Escape DevicePalette QueryHardcopyCaps
  */
  if (lEngineVersion >= RASTER_ENGINE_22)
  {
    // bitmap stuff was never hooked for gre22
    //UNHOOK(DeviceCreateBitmap);
    //UNHOOK(DeviceDeleteBitmap);
    //UNHOOK(DeviceSelectBitmap);
    //UNHOOK(GetBitmapBits);
    //UNHOOK(GetPel);
    //UNHOOK(ImageData);
    //UNHOOK(QueryDeviceBitmaps);
    //UNHOOK(SetBitmapBits);
    //UNHOOK(SetPel);

    // Color stuff was never hooked for gre22
    //UNHOOK(CreateLogColorTable);
    //UNHOOK(QueryColorData);
    //UNHOOK(QueryColorIndex);
    //UNHOOK(QueryLogColorTable);
    //UNHOOK(QueryNearestColor);
    //UNHOOK(QueryRealColors);
    //UNHOOK(QueryRGBColor);
    //UNHOOK(RealizeColorTable);
    //UNHOOK(UnrealizeColorTable);

    UNHOOK(AccumulateBounds);
    UNHOOK(CharString);
    UNHOOK(CharStringPos);
    UNHOOK(DeviceGetAttributes);
    UNHOOK(DeviceQueryFonts);
    UNHOOK(DeviceQueryFontAttributes);
    UNHOOK(DeviceSetAttributes);
    UNHOOK(DeviceSetDCOrigin);
    UNHOOK(DeviceSetGlobalAttribute);
    UNHOOK(DisjointLines);
    UNHOOK(DrawLinesInPath);
    UNHOOK(ErasePS);
    UNHOOK(GetBoundsData);
    UNHOOK(GetCodePage);
    UNHOOK(GetCurrentPosition);
    UNHOOK(GetDCOrigin);
    UNHOOK(GetLineOrigin);
    UNHOOK(GetPairKerningTable);
    UNHOOK(GetStyleRatio);
    UNHOOK(LockDevice);
    UNHOOK(NotifyClipChange);
    UNHOOK(NotifyTransformChange);
    UNHOOK(PolyLine);
    UNHOOK(PolyShortLine);
    UNHOOK(PolyScanline);
    UNHOOK(QueryCharPositions);
    UNHOOK(QueryDeviceCaps);
    UNHOOK(QueryTextBox);
    UNHOOK(QueryWidthTable);
    UNHOOK(RealizeFont);
    UNHOOK(ResetBounds);
    UNHOOK(SetCodePage);
    UNHOOK(SetCurrentPosition);
    UNHOOK(SetLineOrigin);
    UNHOOK(UnlockDevice);
  }
  else
  {
    /*
    ** For a display Memory DC (Shadow DC we must leave the mandatory
    ** functions hooked and hook the other display mandatory funtctions
    */
    /***************************************************************************
    * OK Now Hook all the mandatory functions which we haven't already hooked *
    * in exchange_dispatch function.             Kran                         *
    ****************************************************************************/
    HOOK(DrawBits);
    HOOK(DrawBorder);
    HOOK(QueryDevResource2);
  }

  /*
  **  Unhook the non mandatory functions we hooked
  */

  UNHOOK(Arc);
  UNHOOK(BeginArea);
  UNHOOK(BoxBoth);
  UNHOOK(BoxBoundary);
  UNHOOK(BoxInterior);
//  UNHOOK(DevicePolygonSet);
  UNHOOK(EndArea);
  UNHOOK(FillPath);
  UNHOOK(FullArcBoth);
  UNHOOK(FullArcBoundary);
  UNHOOK(FullArcInterior);
  UNHOOK(PaintRegion);
  UNHOOK(PartialArc);
  UNHOOK(PolyMarker);
  UNHOOK(PolygonSet);
  UNHOOK(PolySpline);
  UNHOOK(SetArcParameters);
//  UNHOOK(SetDefaultAttributes);
  UNHOOK(SetStyleRatio);
  UNHOOK(StrokePath);

} /* hook_unhook */

/***************************************************************************
 * FUNCTION NAME = unhook_for_gre_raster
 *
 * DESCRIPTION   = UnHooks all the functions that we want the GRE to draw
 *                 into a surface bitmap
 *
 * Created 01/23/94 : MV
 ***************************************************************************/

VOID unhook_for_gre_raster (PULONG pDispatchTable)
{

  LONG lEngineVersion = GreQueryEngineVersion();
  /*
  ** For engine raster we unhook all functions except
  ** the attributes and font functions
  */
  if (lEngineVersion >= RASTER_ENGINE_22)
  {
     /*
     **   Function that must remain hooked for new GRE
     **
     **   HOOK(Escape);
     **   HOOK(DevicePalette);
     **   HOOK(QueryHardcopyCaps);
     **
     */

     /*
     **   Function that must remain hooked for us to continue
     **   to process device fonts.
     **
     ** Font Stuff
     **   HOOK(CharString);
     **   HOOK(CharStringPos);
     **   HOOK(DeviceQueryFontAttributes);
     **   HOOK(DeviceQueryFonts);
     **   HOOK(GetPairKerningTable);
     **   HOOK(QueryCharPositions);
     **   HOOK(QueryTextBox);
     **   HOOK(QueryWidthTable);
     **   HOOK(RealizeFont);
     **
     ** Device Caps Stuff
     **   HOOK(QueryDeviceCaps);
     */

     /*
     **   Attribute functions which we leave hooked to minimize the
     **   changes to the code to support vector and raster with device
     **   fonts.
     **
     ** Code Page stuff
     **   HOOK(SetCodePage);
     **   HOOK(GetCodePage);
     ** Attribute stuff
     **   HOOK(DeviceGetAttributes);
     **   HOOK(DeviceSetAttributes);
     **   HOOK(DeviceSetGlobalAttribute);
     **   HOOK(SetDefaultAttributes);
     ** Current Position stuff
     **   HOOK(GetCurrentPosition);
     **   HOOK(SetCurrentPosition);
     ** Color table stuff we never hooked
     **   X HOOK(CreateLogColorTable);
     **   X HOOK(QueryColorData);
     **   X HOOK(QueryColorIndex);
     **   X HOOK(QueryLogColorTable);
     **   X HOOK(QueryNearestColor);
     **   X HOOK(QueryRealColors);
     **   X HOOK(QueryRGBColor);
     **   X HOOK(RealizeColorTable);
     **   X HOOK(UnrealizeColorTable);
     ** Clip stuff
     **   HOOK(NotifyClipChange);
     ** Transform stuff
     **   HOOK(NotifyTransformChange);
     **
     **/


     /*
     **  Function that we never hooked for new GRE
     **
     **  Bitmap stuff
     **   COPY(Bitblt);
     **   COPY(DeviceCreateBitmap);
     **   COPY(DeviceDeleteBitmap);
     **   COPY(DeviceSelectBitmap);
     **   COPY(GetBitmapBits);
     **   COPY(GetPel);
     **   COPY(ImageData);
     **   COPY(QueryDeviceBitmaps);
     **   COPY(SetBitmapBits);
     **   COPY(SetPel);
     ** Color table stuff we never hooked
     **   COPY(CreateLogColorTable);
     **   COPY(QueryColorData);
     **   COPY(QueryColorIndex);
     **   COPY(QueryLogColorTable);
     **   COPY(QueryNearestColor);
     **   COPY(QueryRealColors);
     **   COPY(QueryRGBColor);
     **   COPY(RealizeColorTable);
     **   COPY(UnrealizeColorTable);
     **
     */

     /*
     **  Function that we must uhhooked for new GRE
     **  to rasterize the bitmap.
     */
     UNHOOK(AccumulateBounds);
     UNHOOK(DeviceSetDCOrigin);
     UNHOOK(DrawLinesInPath);
     UNHOOK(ErasePS);
     UNHOOK(GetBoundsData);
     UNHOOK(GetDCOrigin);
     UNHOOK(GetLineOrigin);
     UNHOOK(GetStyleRatio);
     UNHOOK(LockDevice);
     UNHOOK(PolyShortLine);
     UNHOOK(PolyScanline);
     UNHOOK(ResetBounds);
     UNHOOK(SetLineOrigin);
     UNHOOK(UnlockDevice);

     UNHOOK(Arc);
     UNHOOK(BeginArea);
     UNHOOK(BoxBoth);
     UNHOOK(BoxBoundary);
     UNHOOK(BoxInterior);
     UNHOOK(DisjointLines);
     UNHOOK(EndArea);
     UNHOOK(FillPath);
     UNHOOK(FullArcBoth);
     UNHOOK(FullArcBoundary);
     UNHOOK(FullArcInterior);
     UNHOOK(PaintRegion);
     UNHOOK(PartialArc);
     UNHOOK(PolyLine);
     UNHOOK(PolyMarker);
     UNHOOK(PolySpline);
     UNHOOK(SetArcParameters);
     UNHOOK(SetCurrentPosition);
     UNHOOK(SetStyleRatio);                /* NEED TO UNHOOK IN FPDB FOR MEMORY_DC */
     UNHOOK(StrokePath);
     /////  32 bit only
     UNHOOK(PolygonSet);
     //  UNHOOK(DevicePolygonSet);
  }
} /* end function unhook_for_gre_raster */


/***************************************************************************
 * FUNCTION NAME = hook_bitblt2
 *
 * DESCRIPTION   = Hooks bitblt2
 *
 ***************************************************************************/

VOID hook_bitblt2 (PULONG pDispatchTable)
{
  LONG lEngineVersion = GreQueryEngineVersion();
  if (lEngineVersion >= RASTER_ENGINE_22)
  {
    COPY(Bitblt);
    *(pDispatchTable + (NGreBitblt & 0xffL)) = (ULONG)Bitblt2;
  }
}
