/*
** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE 
** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). 
** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER 
** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
** FULL TEXT OF THE NON-WARRANTY PROVISIONS.  
** 
** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
** THE UNITED STATES.  
** 
** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
**
**
** $Revision: 1.1.1.1 $ 
** $Date: 1999/12/07 21:49:06 $ 
**
*/


#include "init.h"
#include "fxinit.h"

#include <stdio.h>
#include <stdlib.h>

#if defined(__WATCOMC__)
#define _inp inp
#define _outp outp
#define _outpw outpw
#endif
#if defined(__linux__)

#define _inp(port) pioInByte(port)
#define _outp(port, data) pioOutByte(port, data)
#define _outpw(port, data) pioOutWord(port, data);

#endif

#include <init96.h>
#include <sst1init.h>

#ifdef _WIN32
#define _WIN32_LEAN_AND_MEAN_
#include <windows.h>
#endif

#include <fxpci.h>
#include <gdebug.h>

static const PciRegister PCI_VENDOR_ID       = { 0x0,  2, READ_ONLY };
static const PciRegister PCI_DEVICE_ID       = { 0x2,  2, READ_ONLY };


/*-------------------------------------------------------------------
  Module Constants
  -------------------------------------------------------------------*/


static InitContext
  contexts[NUM_3DFX_PRODUCTS];  /* pool of device contexts */
InitContext
  *context;                     /* Current device context */
static InitDeviceInfo
  hwInfo[INIT_MAX_DEVICES];     /* Info for all supported devices */
static FxU32
  numDevicesInSystem,           /* Number of supported devices. */
  numSst1s;                     /* # SST1s in system */
static FxBool
  libInitialized;               /* Well, has it been? */

/*-------------------------------------------------------------------
  Function: initEnumHardware
  Date: 10/9
  Implementor(s): jdt
  Library: init
  Description:
  Calls a user supplied function on an initialized InitDeviceInfo
  structure for each device in the system.  Calls a user supplied
  callback repeatedly for each device in the system.  The callback
  can stop the enumeration cycle by return a value of FXTRUE.
  Arguments:
  cb - callback function of type INitHWEnumCallback which is called on
       an initialzied InitDeviceInfo structure
  Return:
  none
  -------------------------------------------------------------------*/
void
initEnumHardware( InitHWEnumCallback *cb )
{
  FxU32  busLocation;
  FxU32  device;
  if ( !libInitialized ) {

    /* When initializing the Library snoop out all 3Dfx devices 
       and fill a static data structure with pertinant data.  */

    numDevicesInSystem = 0;
    numSst1s = 0;
    if ( !pciOpen() ) return;
    for( busLocation = 0; busLocation < MAX_PCI_DEVICES; busLocation++ ) {
      if ( pciDeviceExists( busLocation ) ) {
        FxU32 vId, dId;
        pciGetConfigData( PCI_VENDOR_ID, busLocation, &vId );
        pciGetConfigData( PCI_DEVICE_ID, busLocation, &dId );

        GDBG_INFO((80, "initEnumHardware:  Vendor:  0x%x  Device:  0x%x\n", vId, dId));

#if defined( SST1 )
        if ( (vId == TDFXVID) &&
            (dId == SST1DID) ) { /* Detect SST1 */
          FxU32 *base;
          sst1DeviceInfoStruct info;

          /* Scanline interleave must be two boards back to back
             if there is a second board in the system,
             and the previous board was SLI, then this is the slave */
          if ( numDevicesInSystem > 0 ) {
            if ( hwInfo[numDevicesInSystem-1].hwClass==INIT_VOODOO &&
                hwInfo[numDevicesInSystem-1].hwDep.vgInfo.sliDetect ) {

              hwInfo[numDevicesInSystem-1].hwDep.vgInfo.slaveBaseAddr =
                (FxU32)sst1InitMapBoard( numSst1s );
              hwInfo[numDevicesInSystem-1].regs.hwDep.VGRegDesc.slavePtr = 
                (FxU32*)hwInfo[numDevicesInSystem-1].hwDep.vgInfo.slaveBaseAddr;
              numSst1s++;
              continue;

            }
          }

          hwInfo[numDevicesInSystem].vendorID  = (FxU16) vId;
          hwInfo[numDevicesInSystem].deviceID  = (FxU16) dId;
          hwInfo[numDevicesInSystem].devNumber = numDevicesInSystem;
          hwInfo[numDevicesInSystem].hwClass   = INIT_VOODOO;

          /* On SST-1 We Have to Initialize the Registers
             to Discover the configuration of the board */
#if 0
          base = sst1InitMapBoard( numSst1s );
          sst1InitRegisters( base );
#else
          base = (FxU32*)initMapBoard(numSst1s);
#endif
          sst1InitGetDeviceInfo( base, &info );

          hwInfo[numDevicesInSystem].hwDep.vgInfo.vgBaseAddr = (FxU32) base;
          hwInfo[numDevicesInSystem].hwDep.vgInfo.pfxRev    = info.fbiRevision;
          hwInfo[numDevicesInSystem].hwDep.vgInfo.pfxRam    = info.fbiMemSize;
          hwInfo[numDevicesInSystem].hwDep.vgInfo.nTFX      = info.numberTmus;
          hwInfo[numDevicesInSystem].hwDep.vgInfo.tfxRev    = info.tmuRevision;
          hwInfo[numDevicesInSystem].hwDep.vgInfo.tfxRam    = info.tmuMemSize[0];
          hwInfo[numDevicesInSystem].hwDep.vgInfo.sliDetect = info.sstSliDetect;
          hwInfo[numDevicesInSystem].hwDep.vgInfo.slaveBaseAddr = 0;
          hwInfo[numDevicesInSystem].regs.hwDep.VGRegDesc.baseAddress = base;
          hwInfo[numDevicesInSystem].regs.hwDep.VGRegDesc.slavePtr = 0;

          numSst1s++;
          numDevicesInSystem++;
        }
#elif defined(SST96)
#define IS_CHIP(name) (vId == name##VID && dId == name##DID)

        if (IS_CHIP(AT3D) ||
            IS_CHIP(MCRX)) {

          if (IS_CHIP(MCRX)) {
            /* In the case of Macronix, look for 3d4/3f[2] == 1, as
               they set that bit when we're attached.  */
            FxU8 regVal;
            _outp(0x3d4, 0x3f);
            regVal = _inp(0x3d5);
            
            if (!(regVal & (1 << 2))) /* we're not there */
              continue;
          }

          hwInfo[numDevicesInSystem].vendorID  = (FxU16) vId;
          hwInfo[numDevicesInSystem].deviceID  = (FxU16) dId;
          hwInfo[numDevicesInSystem].devNumber = numDevicesInSystem;
          hwInfo[numDevicesInSystem].hwClass   = INIT_VG96;

          /* SST-96 initialization also retrieves board configuration info */
#if 0
          init96MapBoard(&hwInfo[numDevicesInSystem].regs,
                         &hwInfo[numDevicesInSystem].hwDep.vg96Info,
                         (FxU16) vId, (FxU16) dId);
#else
          initMapBoard(numDevicesInSystem);
#endif

          hwInfo[numDevicesInSystem].hwDep.vg96Info.vgaBaseAddr = 
            (FxU32)hwInfo[numDevicesInSystem].regs.hwDep.VG96RegDesc.partnerRegPtr;
          hwInfo[numDevicesInSystem].hwDep.vg96Info.vg96BaseAddr = 
            (FxU32)hwInfo[numDevicesInSystem].regs.hwDep.VG96RegDesc.baseAddress;
          
          numDevicesInSystem++;
        } 
#else
#  error "Do hardware enumeration for this chip!"
#endif
      }
    }
    

    /* Sanity Check for SLI detection */
    for( device = 0; device < numDevicesInSystem; device++ ) {
      if ( hwInfo[device].hwClass == INIT_VOODOO &&
          hwInfo[device].hwDep.vgInfo.sliDetect              &&
          hwInfo[device].hwDep.vgInfo.slaveBaseAddr == 0 ) {
        hwInfo[device].hwDep.vgInfo.sliDetect = FXFALSE;
      }
    }

    /* Initialize all drivers */
    vgDriverInit( &contexts[INIT_VOODOO] );
    vg96DriverInit( &contexts[INIT_VG96] );
    h3DriverInit( &contexts[INIT_H3] );


    /* Mark the library as initialized */
    libInitialized = FXTRUE;
  }
  
  if ( cb ) {
    for( device = 0; device < numDevicesInSystem; device++ ) {
      cb( &hwInfo[device] );
    } 
  }
  return;
} /* initEnumHardware */

volatile FxU32*
initMapBoard(const FxU32 boardNum)
{
   volatile FxU32* retVal = NULL;
   FxBool okP = (boardNum < INIT_MAX_DEVICES);
   
   if (okP) {
      InitDeviceInfo* infoP = (hwInfo + boardNum);
      const FxU32 vId = infoP->vendorID;
      const FxU32 dId = infoP->deviceID;
      
#if defined(SST1)
      okP = ((vId == TDFXVID) &&
             (dId == SST1DID));

      if (okP) {
         retVal = sst1InitMapBoard(boardNum);
         sst1InitRegisters((FxU32*)retVal);
      }
#elif defined(SST96)
      okP = (IS_CHIP(AT3D) ||
             IS_CHIP(MCRX));

      if (okP) {
         init96MapBoard(&infoP->regs, &infoP->hwDep.vg96Info,
                        (FxU16)vId, (FxU16)dId);
         retVal = infoP->regs.hwDep.VG96RegDesc.baseAddress;
      }
#else
#error "Need to define initMapBoard for this chip!"
#endif /* HW Check */
   }

   return retVal;
}


/*-------------------------------------------------------------------
  Function: initClose
  Date: 10/17
  Implementor(s): jdt
  Library: init
  Description:
  Unmap all hardware and set library to unitialized state
  Arguments:
  none
  Return:
  none
  -------------------------------------------------------------------*/
void initClose( void ) {
    if ( libInitialized ) {
        unsigned i;
        for ( i = 0; i < numDevicesInSystem; i++ ) {
            /* Insert unmap code here */ /* FIXME!!!! */
        }
        pciClose();
        libInitialized = FXFALSE;
    } 
} /* initClose */

/*-------------------------------------------------------------------
  Function: initGetDeviceInfo
  Date: 10/9
  Implementor(s): jdt
  Library: init
  Description:
  Fills a user supplied area of memory with information describing
  the a 3Dfx device.  The device is identified on the bus by the unique
  devNumber assigned by the library and revealed to the user through
  initEnumHardware.
  Arguments:
  devNumber - number identifying device in system
  info      - pointer to user memory to be filled with dev info
  Return:
  FXTRUE  - succeed
  FXFALSE - one or both parameters invalid
  -------------------------------------------------------------------*/
FxBool
initGetDeviceInfo( FxU32 devNumber, InitDeviceInfo *info )
{
    FxBool rv;

    if ( devNumber < numDevicesInSystem ) {
        *info = hwInfo[devNumber];
        rv = FXTRUE;
    } else {
        rv = FXFALSE;
    }
    return rv;
} /* initGetDeviceInfo */


/*-------------------------------------------------------------------
  Function: initDeviceSelect
  Date: 10/9
  Implementor(s): jdt
  Library: init
  Description: 
  Selects a 3Dfx device ( potentially from among many in the system ) and 
  initializes the internal init driver functions with behavior appropriate
  to the type of the selected device.
  Arguments:
  devNumber - unique number assigned to each device by initEnumHardware
  Return:
  FXTRUE - success
  FXFALSE - invalide device number
  -------------------------------------------------------------------*/

FxBool
initDeviceSelect( FxU32 devNumber ) 
{
  FxBool rv = FXFALSE;
  
  if ( devNumber < numDevicesInSystem ) {
    context = &contexts[hwInfo[devNumber].hwClass];
    context->info = hwInfo[devNumber];
    rv =  FXTRUE;
  } 
  
  return rv;

}/* initDeviceSelect */

/*-------------------------------------------------------------------
  Function: initSetWriteMethod
  Date: 10/17
  Implementor(s): jdt
  Library: init
  Description:
  Sets up a register write method that respects the fifo conventions
  of the hardware.
  Arguments:
  wcb - callback to be used to do direct writes from init code
  Return:
  none
  -------------------------------------------------------------------*/
void initSetWriteMethod( InitWriteCallback *wcb ) {
    if ( context )
        context->writeMethod = wcb;
    return;
} /* initSetWriteMethod */



/*-------------------------------------------------------------------
  Function: initSetVideo
  Date: 10/9
  Implementor(s): jdt, murali
  Library: init
  Description:
        This will initialize the video, and allocate color and aux buffers
        prior to rendering.
  Arguments:
  hwnd - pointer to a window handle or null.  If NULL, then 
         the application window handle will be inferred though
         the GetActiveWindow() api.
  resolution - either one of the pre-defined glide resolutions,
               or GR_RESOLUTION_NONE, in which case the window
               size is inferred from the size application window
  refresh - requested fullscreen refresh rate, ignored in a window
  format  - requested ccolor format for glide packed color values
  origin  - location of coordinate origin either upper left or
                    lower right
  nColBuffers - number of color buffers to attempt to allocate
                0 - meaningless
                1 - allocate a front buffer only
                2 - allocate a front and back buffer
                3 - allocate a front, back, aux buffer for tripple buffering
  nAuxBuffers - number of aux buffers to attempt to allocate
                0 - no alpha or z buffers
                1 - allocate one aux buffer for alpha/depth buffering
                2 - allocate on depth and one alpha buffer ( unsup )
  xres        - x resolution return val ( for user windows )
  yres        - y resolution return val ( for user windows )
  fbStride    - stride in pixels of frame buffer
  Return:
  FXTRUE - all resources requested where allocated
  FXFALSE - some or all resources were not available.  By comparing
            desc before and after call, the user can determine which
            resources were denied.
  -------------------------------------------------------------------*/
FxBool initSetVideo( FxU32                hWnd,
                     GrScreenResolution_t sRes,
                     GrScreenRefresh_t    vRefresh,
                     InitColorFormat_t    cFormat,
                     InitOriginLocation_t yOrigin,
                     int                  nColBuffers,
                     int                  nAuxBuffers,
                     int                  *xres,
                     int                  *yres,
                     int                  *fbStride,
                     sst1VideoTimingStruct *vidTimings) {
    FxBool rv;
    if ( context ) {
        rv = context->setVideo( hWnd, sRes, vRefresh, cFormat, 
                                yOrigin, nColBuffers, nAuxBuffers,
                                xres, yres, fbStride, vidTimings);
    } else {
        rv = FXFALSE;
    }
    return rv;
} /* initSetVideo */


/*-------------------------------------------------------------------
  Function: initRestoreVideo
  Date: 10/16
  Implementor(s): jdt
  Library: init
  Description:
  Restore video to its state prior to initSetVideo
  Arguments:
  none
  Return:
  none
  -------------------------------------------------------------------*/
void initRestoreVideo( void ) {
    if ( context ) 
        context->restoreVideo();
} /* initRestoreVideo */

/*-------------------------------------------------------------------
  Function: initEnableTransport
  Date: 10/17
  Implementor(s): jdt
  Library: init
  Description:
  Enable the command transport mechanism for the underlying 
  hardware and return information about accessing the transport
  to the caller
  Arguments:
  info - data structure describing state of transport
  Return:
  FXTRUE  - successfully enabled the command transport
  FXFALSE - failed ot enable the command transport
  -------------------------------------------------------------------*/
FxBool initEnableTransport( InitFIFOData *info ) {
    FxBool rv;
    if ( context ) {
        rv = context->enableTransport( info );
    } else {
        rv = FXFALSE;
    }
    return rv;
} /* initEnableTransport */

/*-------------------------------------------------------------------
  Function: initDisableTransport
  Date: 10/17
  Implementor(s): jdt
  Library: init
  Description:
  Return transport control to reset state
  Arguments:
  none
  Return:
  none
  -------------------------------------------------------------------*/
void initDisableTransport( void ) {
    if ( context ) 
        context->disableTransport();
} /* initDisableTransport */

/*-------------------------------------------------------------------
  Function: initSwapBuffers
  Date: 10/9
  Implementor(s): jdt, murali
  Library: init
  Description:
  Initiate a buffer swap.  
  Arguments: 
  code - code describing type of swap, wether to sync to vretrace, how
         many vretraces to wait, etc.
  -------------------------------------------------------------------*/
void initSwapBuffers( FxU32 code ) {
    if ( context )
        context->swapBuffers( code );
} /* initSwapBuffers */

/*-------------------------------------------------------------------
  Function: initStatus
  Date: 10/9
  Implementor(s): jdt
  Library: init
  Description:
  Returns the status word from the hardware
  Arguments:
  none
  Return:
  32-bit status word ( chip specific )
  -------------------------------------------------------------------*/
FxU32 initStatus( void ) {
    FxU32 rv;
    if ( context ) {
        rv = context->status();
    } else {
        rv = 0;
    }
    return rv;
} /* initStatus */

/*-------------------------------------------------------------------
  Function: initBusy
  Date: 10/9
  Implementor(s): jdt
  Library: init
  Description:
  return true if hardware is busy rendering
  Arguments:
  none
  Return:
  FXTRUE  - if busy
  FXFALSE - if idle
  -------------------------------------------------------------------*/
FxBool initBusy( void ) {
    FxBool rv;
    if ( context ) {
        rv = context->busy();
    } else {
        rv = FXTRUE;
    }
    return rv;
} /* initBusy */

/*-------------------------------------------------------------------
  Function: initIdle
  Date: 10/9
  Implementor(s): jdt
  Library: init
  Description:
  Returns only when graphics pipeline is completely idle. 
  May hang software if hardware is permanently busy.
  Arguments:
  none
  Return:
  none
  -------------------------------------------------------------------*/
void initIdle( void ) {
    if ( context )
        context->idle();
} /* initIdle */

/*-------------------------------------------------------------------
  Function: initGetBufferPtr
  Date: 2/25
  Implementor(s): jdt
  Library: Init
  Description:
  Get the current pointer to a particular buffer
  Arguments:
  buffer - which buffer to get pointer to 
  Return:
  integer pointer
  -------------------------------------------------------------------*/
void *initGetBufferPtr( InitBuffer_t buffer, int *strideBytes ) {
    if ( context )
        return context->getBufferPtr( buffer, strideBytes );
    else
        return 0;
} /* initGetBufferPtr */

/*-------------------------------------------------------------------
  Function: initRenderBuffer
  Date: 2/25
  Implementor(s): jdt
  Library: init 
  Description:
  Sets the current render buffer
  Arguments:
  buffer - which buffer to render to ( front or back )
  Return:
  none
  -------------------------------------------------------------------*/
void initRenderBuffer( InitBuffer_t buffer ) {
    if ( context ) context->renderBuffer( buffer );
    return;
} /* initRenderBuffer */

/*-------------------------------------------------------------------
  Function: initOrigin
  Date: 2/25
  Implementor(s): jdt
  Library: init
  Description:
  Set the yorigin
  Arguments:
  origin - origin designation
  Return:
  none
  -------------------------------------------------------------------*/
void initOrigin( InitOriginLocation_t origin ) {
    if ( context ) context->origin( origin );
    return;
} /* initOrigin */

/*-------------------------------------------------------------------
  Function:initIOCtl
  Date: 10/9
  Implementor(s): jdt
  Library: init
  Description:
  CYA function so that emergency functionality may be added w/o 
  corrupting dll interface
  Arguments:
  token    - describes IOCTL function
  argument - pointer to arguments
  Return:
  none
  -------------------------------------------------------------------*/
void initIOCtl( FxU32 token, void *argument ) {
    if ( context )
        context->ioCtl( token, argument );
} /* initIOCtl */

/*-------------------------------------------------------------------
  Function: initControl
  Date: 10/9
  Implementor(s): murali
  Library: init
  Description:
        This will re-attach new buffers for the rendering context, used
        typically only in a windowing system where buffers need to move 
        and resize. Also, implicitly detach old associated buffers.
  Arguments:
        XXX
  Return:
  FXTRUE - all resources requested where allocated
  FXFALSE - some or all resources were not available.  By comparing
            desc before and after call, the user can determine which
            resources were denied.
  -------------------------------------------------------------------*/
FxBool initControl( FxU32 code)
{

    FxBool rv;

    GDBG_INFO((80, "initControl: code = %d, context=%.08x\n", code, context));
    if ( context ) {
        rv = context->control( code );
    } else {
        rv = FXFALSE;
    }
    return rv;
} /* initControl */

/*-------------------------------------------------------------------
  Function: initWrapFIFO
  Date: 13-Feb-97
  Implementor(s): dow
  Library: init
  Description:
  Reset the command transport when the fifo is full
  Arguments:
  pointer to fifo data
  Return:
  none
  -------------------------------------------------------------------*/
FxBool initWrapFIFO(InitFIFOData *fifoData) {
    if ( context )
        return context->wrapFIFO(fifoData);
    else
        return FXFALSE;
} /* initWrapFIFO */

/*-------------------------------------------------------------------
  Function: initGamma
  Date: 10/9
  Implementor(s): jdt
  Library: init
  Description:
  SST-1 holdover function which initializes the gamma table in some
  video hardware to normalize monitor brightness
  Arguments:
  gamma - floating point gamma correction factor
  Return:
  none
  -------------------------------------------------------------------*/
void initGamma( double gamma ) {
    if ( context )
        context->gamma( gamma );
} /* initGamma */

/*-------------------------------------------------------------------
  Function: initSliPciOwner
  Date: 10/9
  Implementor(s): jdt
  Library: init
  Description:
  Do some voodoo(tm) to change the owner of the PCI bus in an SLI
  configuration
  Arguments:
  regbase - ask scott sellers
  owner   - ask scott sellers
  Return:
  none
  -------------------------------------------------------------------*/
void initSliPciOwner( FxU32 *regbase, FxU32 owner ) {
    if ( context )
        context->sliPciOwner( regbase, owner );
} /* initSliPciOwner */


/*-------------------------------------------------------------------
  Function: initNumBoardsInSystem
  Date: 19970813
  Implementor(s): pgj
  Library: init
  Description:
    Computes the number of boards compatible with the hardware the init
    library is compiled for, i.e. this will count either the number
    of VG xor Rush cards present.
  Return:
    number of boards found
  -------------------------------------------------------------------*/
FxU32 initNumBoardsInSystem(void)
{
    FxU32 numBoards, j, n;

    if(getenv(("SST_BOARDS"))) {
        numBoards = atoi(getenv(("SST_BOARDS")));
    } else {
        numBoards = 0;
#if defined(SST1)
        for(j=0; j<INIT_MAX_DEVICES; j++) {
            if(pciFindCardMulti(TDFXVID, SST1DID, &n, j)) numBoards++;
        }
#elif defined(SST96)
        for(j=0; j<INIT_MAX_DEVICES; j++) {
            if(pciFindCardMulti(AT3DVID, AT3DDID, &n, j)) numBoards++;
            if(pciFindCardMulti(MCRXVID, MCRXDID, &n, j)) numBoards++;
        }
#else
#  error "initNumBoardsInSystem: unknown device!!!"
#endif
    }
    return(numBoards);
} /* end initNumBoardsInSystem() */

/*-------------------------------------------------------------------
  Function: initGammaRGB
  Date: Mar-2-98
  Implementor(s): atai
  Library: init
  Description:
  initialize Gamma table givin RGB value
  Arguments:
  Return:
  none
  -------------------------------------------------------------------*/
FxBool initGammaRGB( double r, double g, double b ) {
    if ( context )
        return context->gammaRGB( r, g, b );
    return FXFALSE;
} /* initGammaRGB */

/*-------------------------------------------------------------------
  Function: initGammaTable
  Date: Mar-2-98
  Implementor(s): atai
  Library: init
  Description:
  initialize Gamma table givin RGB table
  Arguments:
  Return:
  none
  -------------------------------------------------------------------*/
FxBool initGammaTable(FxU32 nentries, FxU32 *r, FxU32 *g, FxU32 *b) {
    if ( context )
        return context->initGammaTable( nentries, r, g, b );
    return FXFALSE;
} /* initGammaTable */

/*-------------------------------------------------------------------
  Function: initFindVideoTimingStruct
  Date: Mar-2-98
  Implementor(s): atai
  Library: init
  Description:
  find video timing structure
  Arguments:
  Return:
  none
  -------------------------------------------------------------------*/
sst1VideoTimingStruct *initFindVideoTimingStruct(GrScreenResolution_t sRes, GrScreenRefresh_t vRefresh) {
    if ( context )
        return context->findVidTimingStruct( sRes, vRefresh );
    return NULL;
} /* initGamma */

