TWAIN Helper Glue/TWGlue.c

// ===========================================================================
//  TWGlue.c            TWAIN 1.9               ©1991-2001 TWAIN Working Group
// ===========================================================================
//  
//
 
#include "TWAIN.h"
#include "TWGlue.h"
#include "TWDefs.h"
#include "TWAcquire.h"
#include "TWUtilities.h"
#include "TWSystem.h"
#include "DebugPrintf.h"
 
 
  //
 //    move the following defines to TWAIN.h
//
#define MSG_REGISTER_CALLBACK   0x0902
#define MSG_INVOKE_CALLBACK     0x0903
#define DAT_CALLBACK            0x0010
 
 
 
TW_UINT16   DSM_Glue_Entry(pTW_IDENTITY pSource, pTW_IDENTITY pDestin, 
                        TW_UINT32 DG, TW_UINT16 Dat, TW_UINT16 Msg, TW_MEMREF pData);
                                  
static TW_INT16     Initialized=FALSE;
static TW_INT16     DSMOpen=FALSE;
 
static TW_STR255    defaultVolName="\p";
static TW_INT16     defaultVolRef=0;
 
static TW_IDENTITY  AppIdentity;
 
static TW_INT16     DSOpen=FALSE;
static TW_INT16     DSSelected=FALSE;
static TW_INT16     DSEnabled=FALSE;
static TW_IDENTITY  DSIdentity;
 
#pragma mark *** Application ***
 
// ---------------------------------------------------------------------------
//  TWGetAppIdentity                                                  
// ---------------------------------------------------------------------------
//  
 
pTW_IDENTITY TWGetAppIdentity(void)
{
   return (&AppIdentity);
}
 
 
#pragma mark -
#pragma mark *** Source Manager ***
 
// ---------------------------------------------------------------------------
//  DSM_Glue_Entry                                                
// ---------------------------------------------------------------------------
//  Main DSM Entry Point
 
TW_UINT16 DSM_Glue_Entry (  pTW_IDENTITY pSource, 
                            pTW_IDENTITY pDestin, 
                            TW_UINT32 DG, 
                            TW_UINT16 Dat, 
                            TW_UINT16 Msg, 
                            TW_MEMREF pData )
 
{
    TW_UINT16 Result = TWERR;
    
    if ( Initialized == true && DSMOpen == true ) 
    {
        Result = DSM_Entry(pSource,pDestin,DG,Dat,Msg,pData);
    }
    
    return Result;
}
 
 
 
// ---------------------------------------------------------------------------
//  TWInitialize                                                  
// ---------------------------------------------------------------------------
//  
 
TW_INT16 TWInitialize ( pTW_IDENTITY pIdentity )
{
    TW_INT16 result = TWRC_SUCCESS;
    if (DSM_Entry == (void*) kUnresolvedCFragSymbolAddress)
    {
        // Weak link failed.
        result=TWRC_FAILURE;
    }
    else
    
    
    {
        Initialized=TRUE;
        
        AppIdentity=*pIdentity;
        
        //DSIdentity.ProductName[0]=0;
        DSIdentity.Id=0;
    }
    return result;
}
 
 
// ---------------------------------------------------------------------------
//  TWTerminate                                               
// ---------------------------------------------------------------------------
//  
 
TW_INT16 TWTerminate()
{
    TW_INT16 Result=TWRC_SUCCESS;
    
    if (Initialized==FALSE)
        return(TWERR);
    
    if (DSEnabled)
    {
        TW_USERINTERFACE    UserInterface = {false, false, nil};
        Result = TWDisableDS(&UserInterface);
    }
        
    if (DSOpen)
        Result = TWCloseDS();
        
    if (DSMOpen)
        Result = TWCloseDSM();
    
    Initialized = FALSE;
    
    return(Result);
}
 
 
 
// ---------------------------------------------------------------------------
//  TWMessageDSM                                                  
// ---------------------------------------------------------------------------
//  
 
TW_INT16 TWMessageDSM ( TW_UINT32 DG, TW_UINT16 Dat, TW_UINT16 Msg, TW_MEMREF pData )
{
    TW_INT16 Result=TWRC_SUCCESS;
    
    Result=DSM_Glue_Entry(&AppIdentity,NULL,DG,Dat,Msg,pData);
    
    return(Result);
}
 
 
 
// ---------------------------------------------------------------------------
//  TWOpenDSM                                                 
// ---------------------------------------------------------------------------
//  
 
TW_INT16 TWOpenDSM()
{
    TW_INT16 Result=TWRC_SUCCESS;
 
    DSMOpen = TRUE;
    
    Result = DSM_Glue_Entry(&AppIdentity, NULL, DG_CONTROL, DAT_PARENT, MSG_OPENDSM, NULL);
 
    return(Result);
}
 
 
// ---------------------------------------------------------------------------
//  TWCloseDSM                                                
// ---------------------------------------------------------------------------
//  
 
TW_INT16 TWCloseDSM()
{
    TW_INT16 Result=TWRC_SUCCESS;
 
    if ((Initialized==FALSE)||(DSMOpen==FALSE)) 
        return(TWERR);
    
    Result=DSM_Glue_Entry(&AppIdentity,NULL,DG_CONTROL,DAT_PARENT,MSG_CLOSEDSM,NULL); 
 
    DSMOpen     =FALSE;
    
    DSOpen      =FALSE;
    DSEnabled   =FALSE;
    
    return(TWRC_SUCCESS);
}
 
 
 
// ---------------------------------------------------------------------------
//  TWSelectDS                                                
// ---------------------------------------------------------------------------
//  
 
TW_INT16 TWSelectDS()
{
    TW_INT16        Result=TWRC_SUCCESS;
    TW_IDENTITY     NewDSIdentity;
    
    if (DSMOpen==FALSE) 
    {
        Result=TWOpenDSM();
        if (Result != TWRC_SUCCESS) 
            return(TWERR);
    }
    
    NewDSIdentity.Id=0;
    NewDSIdentity.ProductName[0]=0;
    
    Result=DSM_Glue_Entry(&AppIdentity,NULL,DG_CONTROL,DAT_IDENTITY,
        MSG_USERSELECT,(TW_MEMREF)&NewDSIdentity);
 
    if (Result==TWRC_SUCCESS) 
        DSIdentity=NewDSIdentity;
    
    DSSelected=TRUE;
    
    return(Result);
}
 
// ---------------------------------------------------------------------------
//  TWRegisterCallback
// ---------------------------------------------------------------------------
TW_INT16 TWRegisterCallback(DSMENTRYPROC ptr)
{
    TW_INT16        Result=TWRC_SUCCESS;
    
    if (DSMOpen==FALSE)
    {
        Result=TWOpenDSM();
        if (Result != TWRC_SUCCESS)
            return(TWERR);
    }
 
    Result=DSM_Glue_Entry(&AppIdentity, NULL, DG_CONTROL, DAT_CALLBACK, MSG_REGISTER_CALLBACK, (TW_MEMREF)ptr);
    
    return Result;
}
 
 
#pragma mark -
#pragma mark *** Data Source ***
 
// ---------------------------------------------------------------------------
//  TWEventDS                                                 
// ---------------------------------------------------------------------------
//  
 
TW_INT16 TWEventDS ( EventRecord *pEvent, pTW_INT16 pMessage )
{
    TW_EVENT    TWEvent;
    TW_INT16    Result;
    
    if (DSOpen==FALSE) 
        return(TWRC_NOTDSEVENT);
    if (DSEnabled==FALSE) 
        return(TWRC_NOTDSEVENT);
    
    TWEvent.pEvent=(TW_MEMREF)pEvent;
    
    Result=TWMessageDS(DG_CONTROL,DAT_EVENT,MSG_PROCESSEVENT,(TW_MEMREF)&TWEvent);
                    
    if (TWEvent.TWMessage!=MSG_NULL) /* we got a message */
    {
        if (TWEvent.TWMessage!=MSG_XFERREADY) /* not an xfer ready message */
        {
            Result=ProcessTWMessage(TWEvent.TWMessage);
        }
        else /* was an xfer ready message */
        {
            if (pMessage!=NULL) 
                *pMessage=TWEvent.TWMessage;
        }
    }
    return(Result);
}
 
 
 
// ---------------------------------------------------------------------------
//  TWOpenDSIdentity                                                  
// ---------------------------------------------------------------------------
//  
 
TW_INT16 TWOpenDSIdentity ( pTW_IDENTITY pDSIdentity )
{
    TW_INT16 Result=TWRC_SUCCESS;
    
    Result = TWOpenDS();
    if (Result == TWRC_SUCCESS && pDSIdentity != NULL) {
        *pDSIdentity = DSIdentity;
    }
    
    return Result;
}
 
 
 
// ---------------------------------------------------------------------------
//  TWOpenDS                                                  
// ---------------------------------------------------------------------------
//  
 
TW_INT16 TWOpenDS()
{
    TW_INT16 Result=TWRC_SUCCESS;
    
    if (DSMOpen==FALSE) 
    {
        Result=TWOpenDSM();
        if (Result!=TWRC_SUCCESS) return(TWERR);
    }
    if (DSSelected==TRUE)
    {
        Result=DSM_Glue_Entry(&AppIdentity,NULL,
            DG_CONTROL,DAT_IDENTITY,MSG_OPENDS,(TW_MEMREF)&DSIdentity);
    }
    else
    {
        Result=DSM_Glue_Entry(&AppIdentity,NULL,
            DG_CONTROL,DAT_IDENTITY,MSG_OPENDS,(TW_MEMREF)&DSIdentity);
    }
    if (Result==TWRC_SUCCESS)
        DSOpen=TRUE;
    
    return(Result);
}
 
 
 
// ---------------------------------------------------------------------------
//  TWCloseDS                                                 
// ---------------------------------------------------------------------------
//  
 
TW_INT16 TWCloseDS()
{
    TW_INT16 Result;
    
    Result=DSM_Glue_Entry(&AppIdentity,NULL,
            DG_CONTROL,DAT_IDENTITY,MSG_CLOSEDS,(TW_MEMREF)&DSIdentity);
 
    
    DSOpen=FALSE;
    DSEnabled=FALSE;
    
    return(Result);
}
 
 
 
// ---------------------------------------------------------------------------
//  TWEnableDS                                                
// ---------------------------------------------------------------------------
//  
 
TW_INT16 TWEnableDS ( pTW_USERINTERFACE pUserInterface )
{
    TW_INT16        Result;
    
    Result=TWMessageDS(DG_CONTROL,DAT_USERINTERFACE,MSG_ENABLEDS,
        (TW_MEMREF)pUserInterface);
        
    if (Result==TWRC_SUCCESS) DSEnabled=TRUE;
    
    return(Result);
}
 
 
 
// ---------------------------------------------------------------------------
//  TWDisableDS                                               
// ---------------------------------------------------------------------------
//  
 
TW_INT16 TWDisableDS ( pTW_USERINTERFACE pUserInterface )
{
    TW_INT16 Result;
    
    Result=TWMessageDS(DG_CONTROL,DAT_USERINTERFACE,MSG_DISABLEDS,
        (TW_MEMREF)pUserInterface);
        
    if (Result==TWRC_SUCCESS) 
        DSEnabled=FALSE;
    
    return(Result);
}
 
 
 
// ---------------------------------------------------------------------------
//  TWMessageDS                                               
// ---------------------------------------------------------------------------
//  
 
TW_INT16 TWMessageDS ( TW_UINT32 DG, TW_UINT16 Dat, TW_UINT16 Msg, TW_MEMREF pData )
{
    TW_INT16 Result=TWRC_SUCCESS;
    
    Result=DSM_Glue_Entry(&AppIdentity, &DSIdentity, DG, Dat, Msg, pData);
//  DEBUGPRINTF("DSM_Glue_Entry: Result = %d ", Result);
 
    return(Result);
}
 
 
 
// ---------------------------------------------------------------------------
//  TWGetDSIdentity                                               
// ---------------------------------------------------------------------------
//  
 
pTW_IDENTITY TWGetDSIdentity()
{
   return &DSIdentity;
}
 
 
 
// ---------------------------------------------------------------------------
//  TWIsDSEnabled                                                 
// ---------------------------------------------------------------------------
//  
 
TW_INT16 TWIsDSEnabled()
{
    return DSEnabled;
}
 
 
 
// ---------------------------------------------------------------------------
//  ¥ TWGetDSCapability                                               
// ---------------------------------------------------------------------------
//  Simplifies capability negotiation. Tests one capability value at a time.
 
TW_INT16 TWGetDSCapability ( TW_UINT16 capabilityID, TW_INT16 value, pTW_INT16 isCapable )
{
    TW_CAPABILITY capability;
    TW_INT16 result;
    TW_INT16 itemType;
 
    *isCapable = FALSE;
    capability.Cap = capabilityID;
    
    result = TWMessageDS ( DG_CONTROL, DAT_CAPABILITY, MSG_GET, (TW_MEMREF)&capability );
    if ( result == TWRC_SUCCESS )
    {
        switch ( capability.ConType )
        {
            case TWON_ONEVALUE:
            {
                TW_INT32 item;
                result = DumpOneValue ( &capability, &itemType, &item );
                if ( item == value )
                    *isCapable = TRUE;                      
            } 
            break;
            
            case TWON_ENUMERATION:
            {
                TW_INT16 itemCount, currentIndex, defaultIndex, i;
                TW_UINT16 itemList[16];
                
                result = DumpEnumeration ( &capability, 
                                           &itemType, 
                                           &itemCount,
                                           &currentIndex, 
                                           &defaultIndex, 
                                           (pTW_UINT8)itemList, 
                                           32 );
                
                switch ( itemType )
                {
                    case TWTY_INT16:
                    case TWTY_UINT16:
                    {
                        for ( i=0; i < itemCount; i++ )
                        {
                            if ( itemList[i] == value )
                                *isCapable = TRUE;
                        }
                    }
                    break;
                    
                    case TWTY_INT8:
                    case TWTY_UINT8:
                    {
                        for ( i=0; i < itemCount; i++ )
                        {
                            if ( ( (TW_INT8 *)itemList )[i] == value )
                                *isCapable = TRUE;
                        }
                    
                    }
                    break;
                    
                    default:
                        result = TWRC_INFONOTSUPPORTED;
                    break;
                }
            }
            break;
            
            case TWON_ARRAY:
            case TWON_RANGE:
            default:
                result = TWRC_INFONOTSUPPORTED;
            break;
        }
    }
    
    return result;  
        
}
 
 
 
// ---------------------------------------------------------------------------
//  ¥ TWSetDSCapability                                               
// ---------------------------------------------------------------------------
//  Simplifies capability negotiation. One value.
 
TW_INT16 TWSetDSCapability ( TW_UINT16 capabilityID, TW_INT16 value )
{
    TW_INT16 result = TWRC_SUCCESS;
    
    TW_CAPABILITY capability;
    capability.Cap = capabilityID;
    SetupOneValue ( &capability, TWTY_UINT16, (TW_INT32)value );
    result = TWMessageDS ( DG_CONTROL, DAT_CAPABILITY, MSG_SET, (TW_MEMREF)&capability );
    
    return result;
}
 
 
 
// ---------------------------------------------------------------------------
//  TWGetPixelTypes                                               
// ---------------------------------------------------------------------------
//  Capability negotion for supported pixel types.
 
TW_INT16 TWGetPixelTypes ( pTW_INT16 pDoesBW, 
                           pTW_INT16 pDoesGray, 
                           pTW_INT16 pDoesRGB, 
                           pTW_INT16 pDoesPalette )
{
    TW_INT16 Result = TWRC_SUCCESS;
    
    if ( pDoesBW != NULL )
        Result = TWGetDSCapability ( ICAP_PIXELTYPE, TWPT_BW, pDoesBW );
    if ( pDoesGray != NULL )
        Result = TWGetDSCapability ( ICAP_PIXELTYPE, TWPT_GRAY, pDoesGray );
    if ( pDoesRGB != NULL )
        Result = TWGetDSCapability ( ICAP_PIXELTYPE, TWPT_RGB, pDoesRGB );
    if ( pDoesPalette != NULL )
        Result = TWGetDSCapability ( ICAP_PIXELTYPE, TWPT_PALETTE, pDoesPalette );
        
    /* less simple, but somewhat better performance
    
    TW_INT16            i;
    TW_CAPABILITY       Capability;
    TW_INT16            ItemType;
    TW_INT16            NumItems;
    TW_INT16            CurrentIndex;
    TW_INT16            DefaultIndex;
    TW_INT16            ItemList[4];
    TW_INT16            Result;
    
    Capability.Cap=ICAP_PIXELTYPE;
    
    Result=TWMessageDS(DG_CONTROL,DAT_CAPABILITY,MSG_GET,(TW_MEMREF)&Capability);
 
    DumpEnumeration(&Capability,&ItemType,&NumItems,&CurrentIndex,
        &DefaultIndex,(pTW_UINT8)ItemList,8);
    
    if (pDoesBW!=NULL) *pDoesBW=FALSE;
    if (pDoesGray!=NULL) *pDoesGray=FALSE;
    if (pDoesRGB!=NULL) *pDoesRGB=FALSE;
    if (pDoesPalette!=NULL) *pDoesPalette=FALSE;
    
    for (i=0;i<NumItems;i++)
    {
        if ((ItemList[i]==TWPT_BW)&&(pDoesBW!=NULL)) 
            *pDoesBW=TRUE;
        if ((ItemList[i]==TWPT_GRAY)&&(pDoesGray!=NULL)) 
            *pDoesGray=TRUE;
        if ((ItemList[i]==TWPT_RGB)&&(pDoesRGB!=NULL)) 
            *pDoesRGB=TRUE;
        if ((ItemList[i]==TWPT_PALETTE)&&(pDoesPalette!=NULL)) 
            *pDoesPalette=TRUE;
    }
    
    */
        
    return Result ;
}
 
 
 
// ---------------------------------------------------------------------------
//  TWSetPixelType                                                
// ---------------------------------------------------------------------------
//  
 
TW_INT16 TWSetPixelType ( TW_INT16 PixelType )
{
    TW_INT16 result = TWRC_SUCCESS;
    
    result = TWSetDSCapability ( ICAP_PIXELTYPE, PixelType );
    
    return result;
    
    /*
 
    TW_CAPABILITY       Capability;
    TW_INT16            Result;
    TW_INT16            ItemReturned;
    
    Capability.Cap=ICAP_PIXELTYPE;
    
    SetupOneValue(&Capability,TWON_ONEVALUE,(TW_INT32)PixelType);
    
    Result=TWMessageDS(DG_CONTROL,DAT_CAPABILITY,MSG_SET,
        (TW_MEMREF)&Capability);
 
    DumpOneValue(&Capability,NULL,(pTW_INT32)&ItemReturned);
    
    return(Result);
    
    */
}