Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
Relevant replacement documents include:
Source/SampleDS.c
/* |
File: SampleDS.c |
Description: Sample Data Source (DS) |
Author: Image Capture Engineering |
Copyright: © Copyright 2003 Apple Computer, Inc. All rights reserved. |
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. |
("Apple") in consideration of your agreement to the following terms, and your |
use, installation, modification or redistribution of this Apple software |
constitutes acceptance of these terms. If you do not agree with these terms, |
please do not use, install, modify or redistribute this Apple software. |
In consideration of your agreement to abide by the following terms, and subject |
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs |
copyrights in this original Apple software (the "Apple Software"), to use, |
reproduce, modify and redistribute the Apple Software, with or without |
modifications, in source and/or binary forms; provided that if you redistribute |
the Apple Software in its entirety and without modifications, you must retain |
this notice and the following text and disclaimers in all such redistributions of |
the Apple Software. Neither the name, trademarks, service marks or logos of |
Apple Computer, Inc. may be used to endorse or promote products derived from the |
Apple Software without specific prior written permission from Apple. Except as |
expressly stated in this notice, no other rights or licenses, express or implied, |
are granted by Apple herein, including but not limited to any patent rights that |
may be infringed by your derivative works or by other works in which the Apple |
Software may be incorporated. |
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO |
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED |
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN |
COMBINATION WITH YOUR PRODUCTS. |
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR |
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION |
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT |
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN |
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
Change History (most recent first): |
<1> 6/17/03 WN first file |
*/ |
// =========================================================================== |
// |
// Example code for TWAIN Data Source. |
#include <TWAIN/TWAIN.h> |
#include "TWDefs.h" |
#include "TWSystem.h" |
#include "TWUtilities.h" |
#include <QuickTime/QuickTime.h> // for GraphicsImporter |
#include <string.h> |
#include "SampleDS.h" |
#define DEBUGGING 1 |
static TW_IDENTITY Identity; |
static TW_INT16 DSIsAlive=FALSE; |
static TW_INT16 gCurrentState=STATE_DSLOADED; |
static TW_INT16 gConditionCode = TWCC_SUCCESS; |
static TW_STR32 Manufacturer = "\pApple"; |
static TW_STR32 ProductFamily = "\pApple sample ds"; |
static TW_STR32 ProductName = "\pSample DS"; |
static TW_STR32 VersionInfo = "\p1.23"; |
static PicHandle hPicture=NULL; |
static TW_INT16 gTransferReady = FALSE; |
static TW_INT16 TWMessage=-1; |
static TW_IMAGEINFO ImageInfo; |
static TW_IMAGELAYOUT ImageLayout; |
static TW_SETUPFILEXFER GlobalSetupFile; |
static TW_STR32 FileString="\pClasp.tmp"; |
static TW_INT16 PixelTypes[]={TWPT_BW,TWPT_GRAY,TWPT_RGB,TWPT_PALETTE}; |
static TW_INT16 NumPixelTypes=4; |
static TW_INT16 CurPixelType=TWPT_RGB; |
static TW_INT16 DefPixelType=TWPT_RGB; |
static TW_INT32 XResMinValue=50; |
static TW_INT32 XResMaxValue=300; |
static TW_INT32 XResStepSize=10; |
static TW_INT32 XResDefaultValue=300; |
static TW_INT32 XResCurrentValue=300; |
static TW_INT32 YResNumItems=4; |
static TW_INT32 YResCurrentIndex=3; |
static TW_INT32 YResDefaultIndex=3; |
static TW_FIX32 YResItemList[4]={{50,0},{75,0},{150,0},{300,0}}; |
static FSSpec gFileSpec = {0, 0, "\p"}; |
static bool gInfoLoaded = false; |
static GWorldPtr gGWorld = nil; |
static UInt32 gRowsTransfered = 0; |
static TW_INT16 gTransferMode = TWSX_NATIVE; |
static PicHandle gPicture = NULL; |
static ControlRef gScanButton; |
static ControlRef gCancelButton; |
static DialogRef gDialog; |
static Boolean gDebugInitialized = false; |
static CFDictionaryRef gDebugDictionary = NULL; |
#define kScanButton 1 |
#define kCancelButton 2 |
#define kReturn 0x0D |
#define kEnter 0x03 |
// -------------------------------------------------------------------------------- |
#pragma mark - |
#pragma mark ---------------------- Debugging |
// --------------------------------------------------------------------------- |
// ¥ DS_LogText |
// --------------------------------------------------------------------------- |
// Log a string |
void DS_LogText ( const char* pFormat, ... ) |
{ |
#if ICA_DEBUG |
va_list pArg; |
char outString[1024]; |
int len; |
va_start(pArg, pFormat); |
len = vsnprintf(outString, 1020, pFormat, pArg); |
va_end( pArg ); |
printf(outString); |
#endif |
} |
// --------------------------------------------------------------------------- |
// ¥ DS_LogValue |
// --------------------------------------------------------------------------- |
// |
void DS_LogValue (char* label, |
char* labelKey, |
char* format, |
UInt32 value) |
{ |
char key[64]; |
Boolean found = false; |
sprintf(key, format, value); |
if (gDebugDictionary) |
{ |
CFStringRef keyRef; |
CFStringRef strRef; |
CFDictionaryRef dictRef = NULL; |
// find the sub-dictionary |
keyRef = CFStringCreateWithCString(NULL, labelKey, 0); |
if (keyRef) |
{ |
dictRef = (CFDictionaryRef)CFDictionaryGetValue(gDebugDictionary, keyRef); |
CFRelease(keyRef); |
} |
if (dictRef) |
{ |
// find the value |
keyRef = CFStringCreateWithCString(NULL, key, 0); |
if (keyRef) |
{ |
strRef = (CFStringRef)CFDictionaryGetValue(dictRef, keyRef); |
if (strRef) |
{ |
DS_LogText ( "%s [%s] - %s\n", label, key, CFStringGetCStringPtr(strRef,0)); |
found = true; |
} |
CFRelease(keyRef); |
} |
} |
} |
if (!found) |
DS_LogText ( "%s [%s]\n", label, key ); |
} |
// --------------------------------------------------------------------------- |
// ¥ DS_LogResult |
// --------------------------------------------------------------------------- |
// Log errors |
void DS_LogResult ( UInt16 result, |
UInt16 condition ) |
{ |
if ( result != TWRC_SUCCESS |
&& result != TWRC_NOTDSEVENT |
&& result != TWRC_DSEVENT ) |
{ |
DS_LogValue(" result : ", "Result", "%d", result); |
if ( condition != TWCC_SUCCESS ) |
{ |
DS_LogValue(" Condition : ", "Condition", "%d", condition); |
} |
DS_LogText ( "\n" ); |
} |
} |
// --------------------------------------------------------------------------- |
// ¥ DS_LogMessage |
// --------------------------------------------------------------------------- |
void DS_LogMessage(UInt16 message) |
{ |
DS_LogValue(" message : ", "Messages", "0x%04x", message); |
} |
// --------------------------------------------------------------------------- |
// ¥ DS_LogTriplet |
// --------------------------------------------------------------------------- |
// Log the triplet passed to DS_Entry(). |
void DS_LogTriplet ( UInt32 group, |
UInt16 attribute, |
UInt16 message, |
Ptr data ) |
{ |
// don't log the event loop triplets |
if ( message != MSG_PROCESSEVENT ) |
{ |
DS_LogValue(" group : ", "DataGroup", "%d", group); |
DS_LogValue(" attribute : ", "Attribute", "0x%04x", attribute); |
DS_LogValue(" message : ", "Messages", "0x%04x", message); |
if ( attribute == DAT_CAPABILITY ) |
DS_LogValue("capability : ", "Capabilities", "0x%04x", ((pTW_CAPABILITY) data)->Cap ); |
DS_LogText ( "\n" ); |
} |
} |
// --------------------------------------------------------------------------- |
// ¥ DS_DebugInitialize |
// --------------------------------------------------------------------------- |
// |
void DS_DebugInitialize() |
{ |
// write a header of sorts |
// Date format: YYYY '-' MM '-' DD ' ' hh ':' mm ':' ss.fff |
CFTimeZoneRef tz = CFTimeZoneCopySystem(); // specifically choose system time zone for logs |
CFGregorianDate gdate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), tz); |
CFRelease(tz); |
gdate.second = gdate.second + 0.0005; |
DS_LogText ( "*****************************************************************\n"); |
DS_LogText ( "TWAIN mach-o DS Debug Log - %02d:%02d:%06.3f \n", gdate.hour, gdate.minute, gdate.second); |
DS_LogText ( "*****************************************************************\n"); |
// load the gDebugDictionary... |
CFURLRef fileURL = NULL; |
Boolean status; |
CFDataRef resourceData = NULL; |
SInt32 errorCode; |
CFStringRef errorString = NULL; |
CFBundleRef bundle; |
bundle = CFBundleGetBundleWithIdentifier ( CFSTR( "com.apple.sampleds" ) ); |
fileURL = CFBundleCopyResourceURL(bundle, CFSTR("DSDebug"), CFSTR("plist"), NULL); |
if (fileURL) |
{ |
status = CFURLCreateDataAndPropertiesFromResource(NULL, fileURL, &resourceData, NULL, NULL, &errorCode); |
if (status && resourceData) |
{ |
gDebugDictionary = (CFDictionaryRef)CFPropertyListCreateFromXMLData( NULL, resourceData, kCFPropertyListImmutable, &errorString); |
CFRelease(resourceData); |
} |
CFRelease(fileURL); |
} |
} |
// --------------------------------------------------------------------------- |
// ¥ DS_DebugTerminate |
// --------------------------------------------------------------------------- |
// |
void DS_DebugTerminate() |
{ |
DS_LogText ( "--------------------------------------------------------------------------------\n" ); |
} |
#pragma mark - |
#pragma mark ---------------------- DS_Entry |
// --------------------------------------------------------------------------- |
// DS_Entry |
// --------------------------------------------------------------------------- |
// Entry point for Data Source. |
TW_UINT16 DS_Entry ( pTW_IDENTITY pSource, |
TW_UINT32 DG, |
TW_UINT16 Dat, |
TW_UINT16 Msg, |
TW_MEMREF pData ) |
{ |
TW_INT16 result = TWRC_SUCCESS; |
if ( !gDebugInitialized ) |
{ |
DS_DebugInitialize(); |
gDebugInitialized = true; |
} |
DS_LogTriplet ( DG, Dat, Msg, pData ); |
if (DSIsAlive == FALSE) /* initialize on first call */ |
{ |
Identity.Id =1; |
Identity.Version.MajorNum =1; |
Identity.Version.MinorNum =9; |
Identity.Version.Language =1; /* jjg fill in later */ |
Identity.Version.Country =01; |
pstrcopy((pTW_UINT8)Identity.Version.Info,(pTW_UINT8)VersionInfo); |
Identity.ProtocolMajor =1; |
Identity.ProtocolMinor =9; |
Identity.SupportedGroups =DG_CONTROL|DG_IMAGE; |
pstrcopy((pTW_UINT8)Identity.Manufacturer,(pTW_UINT8)Manufacturer); |
pstrcopy((pTW_UINT8)Identity.ProductFamily,(pTW_UINT8)ProductFamily); |
pstrcopy((pTW_UINT8)Identity.ProductName,(pTW_UINT8)ProductName); |
GlobalSetupFile.Format =TWFF_TIFF; |
GlobalSetupFile.VRefNum =0; |
pstrcopy((pTW_UINT8)GlobalSetupFile.FileName,(pTW_UINT8)FileString); |
GetDefaultImageLayout(&ImageLayout); |
// init QuickTime |
EnterMovies(); |
DSIsAlive=TRUE; |
} |
switch (DG) |
{ |
case DG_CONTROL: |
result = DS_Control(pSource,Dat,Msg,pData); |
break; |
case DG_IMAGE: |
result = DS_Image(pSource,Dat,Msg,pData); |
break; |
case DG_AUDIO: |
result = TWRC_SUCCESS; |
break; |
default: |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADPROTOCOL; |
break; |
} |
if (result == TWRC_SUCCESS) /* clear the condition */ |
{ |
gConditionCode = TWCC_SUCCESS; |
} else |
{ |
DS_LogResult ( result, gConditionCode ); |
} |
return(result); |
} |
#pragma mark - |
#pragma mark ---------------------- Control Data Group |
// --------------------------------------------------------------------------- |
// DS_Control |
// --------------------------------------------------------------------------- |
// Process Data Argument types for the DG_CONTROL Data Group. |
TW_INT16 DS_Control(pTW_IDENTITY pSource, TW_UINT16 Dat, TW_UINT16 Msg, TW_MEMREF pData) |
{ |
TW_INT16 result = TWRC_SUCCESS; |
switch (Dat) |
{ |
case DAT_STATUS: |
result = DS_Control_Status(pSource,Msg,(pTW_STATUS)pData); |
break; |
case DAT_IDENTITY: |
result = DS_Control_Identity(pSource,Msg,(pTW_IDENTITY)pData); |
break; |
case DAT_EVENT: |
result = DS_Control_Event(pSource,Msg,(pTW_EVENT)pData); |
break; |
case DAT_CAPABILITY: |
result = DS_Control_Capability(pSource,Msg,(pTW_CAPABILITY)pData); |
break; |
case DAT_PENDINGXFERS: |
result = DS_Control_PendingXfers(pSource,Msg,(pTW_UINT16)pData); |
break; |
case DAT_SETUPMEMXFER: |
result = DS_Control_SetupMemXfer(pSource,Msg,(pTW_SETUPMEMXFER)pData); |
break; |
/* |
case DAT_SETUPFILEXFER: |
result = DS_Control_SetupFileXfer(pSource,Msg,(pTW_SETUPFILEXFER)pData); |
break; |
*/ |
case DAT_USERINTERFACE: |
result = DS_Control_UserInterface(pSource,Msg,(pTW_USERINTERFACE)pData); |
break; |
case DAT_XFERGROUP: |
result = DS_Control_XferGroup(pSource,Msg,(pTW_UINT16)pData); |
break; |
default: |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADPROTOCOL; |
break; |
} |
return(result); |
} |
// --------------------------------------------------------------------------- |
// DS_Control_Status |
// --------------------------------------------------------------------------- |
// |
TW_INT16 DS_Control_Status ( pTW_IDENTITY pSource, TW_UINT16 Msg, pTW_STATUS pStatus ) |
{ |
TW_INT16 result = TWRC_SUCCESS; |
switch (Msg) |
{ |
case MSG_GET: |
pStatus->ConditionCode = gConditionCode; |
pStatus->Reserved=0; |
gConditionCode = TWCC_SUCCESS; |
break; |
default: |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADPROTOCOL; |
break; |
} |
return(result); |
} |
// --------------------------------------------------------------------------- |
// DS_Control_Identity |
// --------------------------------------------------------------------------- |
// |
TW_INT16 DS_Control_Identity ( pTW_IDENTITY pSource, TW_UINT16 Msg, pTW_IDENTITY pIdentity) |
{ |
TW_INT16 result = TWRC_SUCCESS; |
switch (Msg) |
{ |
case MSG_GET: /* get the DS's identity */ |
if (pIdentity!=NULL) |
*pIdentity=Identity; |
break; |
case MSG_OPENDS: /* open the Data source for transfers */ |
if (gCurrentState==STATE_DSLOADED) |
{ |
if (pIdentity!=NULL) *pIdentity=Identity; |
gCurrentState=STATE_DSOPEN; |
} else |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_SEQERROR; |
} |
break; |
case MSG_CLOSEDS: /* do any house cleaning needed before unload */ |
if (gCurrentState==STATE_DSOPEN) |
{ |
gCurrentState=STATE_DSLOADED; |
} else |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_SEQERROR; |
} |
break; |
default: |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADPROTOCOL; |
break; |
} |
return(result); |
} |
// --------------------------------------------------------------------------- |
// DS_Control_Event |
// --------------------------------------------------------------------------- |
// |
TW_INT16 DS_Control_Event ( pTW_IDENTITY pSource, TW_UINT16 Msg, pTW_EVENT pEvent ) |
{ |
TW_INT16 result = TWRC_NOTDSEVENT; |
pEvent->TWMessage=MSG_NULL; |
return result; |
switch (Msg) |
{ |
case MSG_PROCESSEVENT: /* Process an event record */ |
if ((gCurrentState>=STATE_DSENABLED)&&(gCurrentState<=STATE_XFERREADY)) |
{ |
WindowRef windowRef; |
ControlRef controlRef; |
EventRecord * event; |
int partCode; |
int controlPartCode; |
if (pEvent && pEvent->pEvent) |
{ |
event = (EventRecord *)pEvent->pEvent; |
switch (event->what) |
{ |
case mouseDown: |
DS_LogText("event->what = mouseDown (%08X)\n", event->what); |
partCode = FindWindow(event->where, &windowRef); |
switch (partCode) |
{ |
case inMenuBar: |
break; |
case inContent: |
SetPortWindowPort ( windowRef ); |
GlobalToLocal(&event->where); |
controlPartCode = FindControl(event->where, windowRef, &controlRef); |
switch (controlPartCode) |
{ |
case kControlButtonPart: |
if (TrackControl(controlRef, event->where, nil)) |
{ |
if (controlRef == gCancelButton) |
{ |
DS_LogText(" cancel button pressed\n"); |
TWMessage = MSG_CLOSEDSREQ; |
} else if (controlRef == gScanButton) |
{ |
DS_LogText(" scan button pressed\n"); |
gTransferReady = TRUE; |
TWMessage = MSG_XFERREADY; |
gCurrentState = STATE_XFERREADY; |
DS_LogText(" gTransferReady = TRUE\n"); |
DS_LogText(" TWMessage = MSG_XFERREADY\n"); |
DS_LogText(" gCurrentState = STATE_XFERREADY\n"); |
} |
} |
break; |
default: |
DS_LogText(" controlPartCode = %d\n", controlPartCode); |
break; |
} |
break; |
case inGoAway: |
break; |
default: |
break; |
} |
break; |
case mouseUp: |
DS_LogText("event->what = mouseUp (%08X)\n", event->what); |
break; |
case keyDown: |
DS_LogText("event->what = keyDown (%08X)\n", event->what); |
break; |
case keyUp: |
DS_LogText("event->what = keyUp (%08X)\n", event->what); |
break; |
case autoKey: |
DS_LogText("event->what = autoKey (%08X)\n", event->what); |
break; |
case updateEvt: |
DS_LogText("event->what = updateEvt (%08X)\n", event->what); |
windowRef = (WindowRef)event->message; |
SetPortWindowPort ( windowRef ); |
BeginUpdate ( windowRef ); |
DrawControls(windowRef); |
EndUpdate ( windowRef ); |
break; |
case diskEvt: |
DS_LogText("event->what = diskEvt (%08X)\n", event->what); |
break; |
case activateEvt: |
DS_LogText("event->what = activateEvt (%08X)\n", event->what); |
break; |
case kHighLevelEvent: |
DS_LogText("event->what = kHighLevelEvent (%08X)\n", event->what); |
break; |
default: |
break; |
} |
} |
if (TWMessage == -1) |
{ |
pEvent->TWMessage=MSG_NULL; |
} else |
{ |
if (DEBUGGING) |
{ |
switch (TWMessage) |
{ |
case MSG_CLOSEDSREQ: |
DS_LogText("DS_Control_Event: MSG_CLOSEDSREQ\n"); |
break; |
case MSG_XFERREADY: |
DS_LogText("DS_Control_Event: MSG_XFERREADY\n"); |
break; |
} |
} |
pEvent->TWMessage=TWMessage; |
TWMessage=-1; |
} |
} else |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_SEQERROR; |
} |
break; |
default: |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADPROTOCOL; |
break; |
} |
return(result); |
} |
// --------------------------------------------------------------------------- |
// DS_Control_Capability |
// --------------------------------------------------------------------------- |
// |
TW_INT16 DS_Control_Capability ( pTW_IDENTITY pSource, TW_UINT16 Msg, pTW_CAPABILITY pCapability) |
{ |
TW_INT16 CurrentIndex; |
TW_INT16 DefaultIndex; |
TW_INT32 TempValue; |
TW_INT16 ValueType; |
TW_INT16 Count; |
TW_INT16 result = TWRC_SUCCESS; |
TW_UINT16 TempArray[16]; |
if ((Msg==MSG_SET)||(Msg==MSG_RESET)) |
{ |
if (gCurrentState!=STATE_DSOPEN) |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_SEQERROR; |
return(result); |
} |
} |
else |
{ |
if (gCurrentState==STATE_DSLOADED) |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_SEQERROR; |
return(result); |
} |
} |
switch (Msg) |
{ |
case MSG_GET: /* get the current and possible values for a capability */ |
switch (pCapability->Cap) |
{ |
case CAP_XFERCOUNT: |
if (gTransferReady == TRUE) |
SetupOneValue(pCapability,TWTY_UINT16,(TW_INT32)1); |
else |
SetupOneValue(pCapability,TWTY_UINT16,(TW_INT32)0); |
break; |
case CAP_SUPPORTEDCAPS: |
{ |
TW_UINT16 capList[] = {CAP_XFERCOUNT, ICAP_XFERMECH, ICAP_COMPRESSION, |
ICAP_PIXELTYPE, ICAP_UNITS, ICAP_XRESOLUTION, ICAP_YRESOLUTION}; |
SetupArray(pCapability, TWTY_UINT16, 7, (TW_UINT8*) capList); |
} |
break; |
case CAP_UICONTROLLABLE: |
SetupOneValue(pCapability,TWTY_BOOL,(TW_INT32) true); |
break; |
case ICAP_PLANARCHUNKY: |
SetupOneValue(pCapability,TWTY_UINT16,(TW_INT32)TWPC_CHUNKY); |
break; |
case ICAP_XFERMECH: |
{ |
TW_UINT16 xferList[] = {TWSX_NATIVE, TWSX_MEMORY}; |
SetupEnumeration(pCapability, TWTY_UINT16, 2, |
FindIndex(gTransferMode, xferList, 2), |
FindIndex(TWSX_NATIVE, xferList, 2), |
(pTW_UINT8) xferList); |
} |
break; |
case ICAP_COMPRESSION: |
SetupOneValue(pCapability, TWTY_UINT16, TWCP_NONE); |
break; |
case ICAP_PIXELTYPE: |
SetupEnumeration(pCapability, TWTY_UINT16, NumPixelTypes, |
FindIndex(CurPixelType, PixelTypes, NumPixelTypes), |
FindIndex(TWPT_RGB, PixelTypes, NumPixelTypes), |
(pTW_UINT8) PixelTypes); |
break; |
case ICAP_PIXELFLAVOR: |
SetupOneValue(pCapability, TWTY_UINT16, TWPF_CHOCOLATE); |
break; |
case ICAP_UNITS: |
SetupOneValue(pCapability, TWTY_UINT16, TWUN_PIXELS); |
break; |
case ICAP_PHYSICALHEIGHT: |
case ICAP_PHYSICALWIDTH: |
SetupOneValue(pCapability, TWTY_FIX32, 0); |
break; |
case ICAP_BITORDER: |
SetupOneValue(pCapability, TWTY_UINT16, TWBO_MSBFIRST); |
break; |
case ICAP_XRESOLUTION: /* provided as an example of a range */ |
SetupRange(pCapability,TWTY_FIX32, XResMinValue, XResMaxValue, |
XResStepSize,XResDefaultValue,XResCurrentValue); |
break; |
case ICAP_YRESOLUTION: /* provided as an example of an enumeration */ |
SetupEnumeration(pCapability, TWTY_FIX32, YResNumItems, |
YResCurrentIndex,YResDefaultIndex,(TW_UINT8 *)YResItemList); |
break; |
default: |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADCAP; |
break; |
} |
break; |
case MSG_GETCURRENT: |
switch (pCapability->Cap) |
{ |
case CAP_XFERCOUNT: /* same as get */ |
if (gTransferReady == TRUE) |
SetupOneValue(pCapability,TWTY_UINT16,(TW_INT32)1); |
else |
SetupOneValue(pCapability,TWTY_UINT16,(TW_INT32)0); |
break; |
case ICAP_PLANARCHUNKY: /* same as get */ |
SetupOneValue(pCapability,TWTY_UINT16,(TW_INT32)TWPC_CHUNKY); |
break; |
case ICAP_XFERMECH: |
SetupOneValue(pCapability,TWTY_UINT16,(TW_INT32) gTransferMode); |
break; |
case ICAP_COMPRESSION: /* same as get */ |
SetupOneValue(pCapability,TWTY_UINT16,(TW_INT32)TWCP_NONE); |
break; |
case ICAP_PIXELTYPE: |
SetupOneValue(pCapability,TWTY_UINT16,(TW_INT32)CurPixelType); |
break; |
case ICAP_PIXELFLAVOR: |
SetupOneValue(pCapability, TWTY_UINT16, (TW_INT32) TWPF_CHOCOLATE); |
break; |
case ICAP_UNITS: /* same as get */ |
SetupOneValue(pCapability,TWTY_UINT16,(TW_INT32) TWUN_PIXELS); |
break; |
case ICAP_PHYSICALHEIGHT: |
case ICAP_PHYSICALWIDTH: |
SetupOneValue(pCapability, TWTY_FIX32, (TW_INT32) 0); |
break; |
case ICAP_BITORDER: |
SetupOneValue(pCapability, TWTY_UINT16, (TW_INT32) TWBO_MSBFIRST); |
break; |
case ICAP_XRESOLUTION: /* provided as an example of a range */ |
SetupOneValue(pCapability,TWTY_FIX32,XResCurrentValue); |
break; |
default: |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADCAP; |
break; |
} |
break; |
case MSG_GETDEFAULT: /* get the default value for a capability */ |
switch (pCapability->Cap) |
{ |
case CAP_XFERCOUNT: |
SetupOneValue(pCapability,TWTY_UINT16,(TW_INT32)0); |
break; |
case ICAP_PLANARCHUNKY: |
SetupOneValue(pCapability,TWTY_UINT16,(TW_INT32)TWPC_CHUNKY); |
break; |
case ICAP_XFERMECH: |
SetupOneValue(pCapability,TWTY_UINT16,(TW_INT32)TWSX_NATIVE); |
break; |
case ICAP_COMPRESSION: |
SetupOneValue(pCapability,TWTY_UINT16,(TW_INT32)TWCP_NONE); |
break; |
case ICAP_PIXELTYPE: |
SetupOneValue(pCapability,TWTY_UINT16,(TW_INT32)TWPT_RGB); |
break; |
case ICAP_PIXELFLAVOR: |
SetupOneValue(pCapability, TWTY_UINT16, (TW_INT32) TWPF_CHOCOLATE); |
break; |
case ICAP_UNITS: |
SetupOneValue(pCapability,TWTY_UINT16,(TW_INT32)TWUN_PIXELS); |
break; |
case ICAP_PHYSICALHEIGHT: |
case ICAP_PHYSICALWIDTH: |
SetupOneValue(pCapability, TWTY_FIX32, (TW_INT32) 0); |
break; |
case ICAP_BITORDER: |
SetupOneValue(pCapability, TWTY_UINT16, (TW_INT32) TWBO_MSBFIRST); |
break; |
case ICAP_XRESOLUTION: /* provided as an example of a range */ |
SetupOneValue(pCapability,TWTY_FIX32,XResDefaultValue); |
break; |
case ICAP_YRESOLUTION: /* provided as an example of a enumeration */ |
TempValue=YResItemList[YResDefaultIndex].Whole; |
SetupOneValue(pCapability,TWTY_FIX32,(TW_INT32)TempValue); |
break; |
default: |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADCAP; |
break; |
} |
break; |
case MSG_RESET: |
switch (pCapability->Cap) |
{ |
case CAP_XFERCOUNT: |
SetupOneValue(pCapability,TWTY_UINT16,(TW_INT32)0); |
break; |
case ICAP_XFERMECH: |
SetupOneValue(pCapability,TWTY_UINT16,(TW_INT32)TWSX_NATIVE); |
gTransferMode = TWSX_NATIVE; |
break; |
case ICAP_COMPRESSION: |
SetupOneValue(pCapability,TWTY_UINT16,(TW_INT32)TWCP_NONE); |
break; |
case ICAP_PIXELTYPE: |
NumPixelTypes=4; |
CurPixelType=2; |
PixelTypes[0]=TWPT_BW; |
PixelTypes[1]=TWPT_GRAY; |
PixelTypes[2]=TWPT_RGB; |
PixelTypes[3]=TWPT_PALETTE; |
SetupOneValue(pCapability,TWTY_UINT16,(TW_INT32)TWPT_RGB); |
break; |
case ICAP_PIXELFLAVOR: |
SetupOneValue(pCapability, TWTY_UINT16, (TW_INT32) TWPF_CHOCOLATE); |
break; |
case ICAP_UNITS: |
SetupOneValue(pCapability,TWTY_UINT16,(TW_INT32)TWUN_PIXELS); |
break; |
case ICAP_PHYSICALHEIGHT: |
case ICAP_PHYSICALWIDTH: |
SetupOneValue(pCapability, TWTY_FIX32, (TW_INT32) 0); |
break; |
case ICAP_BITORDER: |
SetupOneValue(pCapability, TWTY_UINT16, (TW_INT32) TWBO_MSBFIRST); |
break; |
case ICAP_XRESOLUTION: /* provided as an example of a range */ |
XResMinValue=50; |
XResMaxValue=300; |
XResStepSize=10; |
XResDefaultValue=300; |
XResCurrentValue=300; |
SetupRange(pCapability,TWTY_FIX32,XResMinValue,XResMaxValue, |
XResStepSize,XResDefaultValue,XResCurrentValue); |
break; |
default: |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADCAP; |
break; |
} |
break; |
case MSG_SET: /* set the current value for a capability */ |
switch (pCapability->Cap) |
{ |
case CAP_XFERCOUNT: |
GetOneValue(pCapability,NULL,&TempValue); |
if (TempValue!=0) |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADVALUE; |
} |
break; |
case ICAP_XFERMECH: |
TempValue = TWSX_NATIVE; |
switch (pCapability->ConType) |
{ |
case TWON_ONEVALUE: |
result = GetOneValue(pCapability,NULL,&TempValue); |
break; |
case TWON_ENUMERATION: |
result = GetEnumeration(pCapability, &ValueType, &Count, |
&CurrentIndex, &DefaultIndex, (pTW_UINT8) TempArray, 32); |
if (result == TWRC_SUCCESS) |
{ |
if (ValueType == TWTY_UINT16 || ValueType == TWTY_INT16) |
{ |
TempValue = TempArray[CurrentIndex]; |
if (TempValue != TWSX_NATIVE && TempValue != TWSX_MEMORY) |
TempValue = TempArray[DefaultIndex]; |
} |
else if (ValueType == TWTY_UINT8 || ValueType == TWTY_INT8) |
{ |
TempValue = ((TW_INT8*) TempArray)[CurrentIndex]; |
if (TempValue != TWSX_NATIVE && TempValue != TWSX_MEMORY) |
TempValue = ((TW_INT8*) TempArray)[DefaultIndex]; |
} |
else |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADVALUE; |
} |
} |
break; |
default: |
break; |
} |
if (result != TWRC_SUCCESS || |
(TempValue != TWSX_NATIVE && TempValue != TWSX_MEMORY)) |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADVALUE; |
} |
else |
{ |
gTransferMode = TempValue; |
} |
break; |
case ICAP_COMPRESSION: |
GetOneValue(pCapability,NULL,&TempValue); |
if (TempValue!=TWCP_NONE) |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADVALUE; |
} |
break; |
case ICAP_PIXELTYPE: |
if (pCapability->ConType==TWON_ONEVALUE) |
{ |
GetOneValue(pCapability,NULL,&TempValue); |
CurPixelType=(TW_INT16)TempValue; |
} |
else |
{ |
GetEnumeration(pCapability,NULL,&NumPixelTypes, |
&CurrentIndex,&DefaultIndex,(pTW_UINT8)&PixelTypes,8); |
CurPixelType=PixelTypes[CurrentIndex]; |
DefPixelType=PixelTypes[DefaultIndex]; |
} |
break; |
case ICAP_PIXELFLAVOR: |
// Do nothing... this is an example DS, not an example |
// of how to write Mac imaging code... :-) |
break; |
case ICAP_UNITS: |
GetOneValue(pCapability,NULL,&TempValue); |
if (TempValue!=TWUN_PIXELS) |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADVALUE; |
} |
break; |
case ICAP_XRESOLUTION: /* provided as an example of a range */ |
if (pCapability->ConType==TWON_ONEVALUE) |
{ |
GetOneValue(pCapability,NULL,&XResCurrentValue); |
} |
else |
{ |
GetRange(pCapability,NULL,&XResMinValue,&XResMaxValue, |
&XResStepSize,&XResDefaultValue,&XResCurrentValue); |
} |
break; |
default: |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADCAP; |
break; |
} |
break; |
default: |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADPROTOCOL; |
break; |
} |
return(result); |
} |
// --------------------------------------------------------------------------- |
// DS_Control_PendingXfers |
// --------------------------------------------------------------------------- |
// |
TW_INT16 DS_Control_PendingXfers ( pTW_IDENTITY pSource, TW_UINT16 Msg, pTW_UINT16 pPendingXfers ) |
{ |
TW_INT16 result = TWRC_SUCCESS; |
switch (Msg) |
{ |
case MSG_GET: /* get the number of pending transfers */ |
if (gCurrentState!=STATE_DSLOADED) |
{ |
if (gTransferReady == TRUE) |
*pPendingXfers = 1; |
else |
*pPendingXfers = 0; |
} |
else |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_SEQERROR; |
} |
break; |
case MSG_ENDXFER: /* terminate the current transfer */ |
if (gCurrentState==STATE_XFER) /* this will never happen since we only do natives */ |
{ |
if (gTransferReady == TRUE) |
{ |
if (hPicture!=NULL) |
DisposeHandle((Handle) hPicture); |
hPicture=NULL; |
gTransferReady = FALSE; |
} |
*pPendingXfers=0; |
gCurrentState=STATE_DSENABLED; |
TWMessage=MSG_CLOSEDSREQ; |
} |
else |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_SEQERROR; |
} |
break; |
case MSG_RESET: |
if (gCurrentState==STATE_XFERREADY) |
{ |
if (gTransferReady == TRUE) |
{ |
if (hPicture!=NULL) |
DisposeHandle((Handle) hPicture); |
hPicture=NULL; |
gTransferReady = FALSE; |
gCurrentState=STATE_DSENABLED; |
} |
*pPendingXfers=0; |
} |
else |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_SEQERROR; |
} |
break; |
default: |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADPROTOCOL; |
break; |
} |
return(result); |
} |
// --------------------------------------------------------------------------- |
// DS_Control_SetupMemXfer |
// --------------------------------------------------------------------------- |
// |
TW_INT16 DS_Control_SetupMemXfer ( pTW_IDENTITY pSource, TW_UINT16 Msg, pTW_SETUPMEMXFER pSetupMem ) |
{ |
TW_INT16 result = TWRC_SUCCESS; |
switch (Msg) |
{ |
case MSG_GET: |
if ((gCurrentState>=STATE_DSOPEN)&&(gCurrentState<=STATE_XFERREADY)) |
{ |
if (!gInfoLoaded) |
result = GetImageInfo(); |
if (result == TWRC_SUCCESS) |
{ |
pSetupMem->MinBufSize = 32 * 1024; |
// Width * Samples rounded to the next 16 byte boundry * height |
pSetupMem->MaxBufSize = |
pSetupMem->Preferred = |
((((ImageInfo.ImageWidth * |
(ImageInfo.BitsPerPixel / 8)) + 15) / 16) * 16) * |
ImageInfo.ImageLength; |
} |
} |
else |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_SEQERROR; |
} |
break; |
default: |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADPROTOCOL; |
break; |
} |
return(result); |
} |
// --------------------------------------------------------------------------- |
// DS_Control_SetupFileXfer |
// --------------------------------------------------------------------------- |
// |
TW_INT16 DS_Control_SetupFileXfer ( pTW_IDENTITY pSource, |
TW_UINT16 Msg, |
pTW_SETUPFILEXFER pSetupFile ) |
{ |
TW_INT16 result = TWRC_SUCCESS; |
if ((gCurrentState<STATE_DSOPEN)||(gCurrentState>STATE_XFERREADY)) |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_SEQERROR; |
return(result); |
} |
switch (Msg) |
{ |
case MSG_GET: |
*pSetupFile=GlobalSetupFile; |
break; |
case MSG_GETDEFAULT: |
pstrcopy((pTW_UINT8)pSetupFile->FileName,(pTW_UINT8)FileString); |
pSetupFile->Format=TWFF_TIFF; |
pSetupFile->VRefNum=0; |
break; |
case MSG_SET: |
GlobalSetupFile=*pSetupFile; |
break; |
case MSG_RESET: |
pstrcopy((pTW_UINT8)GlobalSetupFile.FileName,(pTW_UINT8)FileString); |
GlobalSetupFile.Format=TWFF_TIFF; |
GlobalSetupFile.VRefNum=0; |
*pSetupFile=GlobalSetupFile; |
break; |
default: |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADPROTOCOL; |
break; |
} |
return(result); |
} |
// --------------------------------------------------------------------------- |
// DS_Control_UserInterface |
// --------------------------------------------------------------------------- |
// |
TW_INT16 DS_Control_UserInterface ( pTW_IDENTITY pSource, |
TW_UINT16 Msg, |
pTW_USERINTERFACE pUserInterface) |
{ |
TW_INT16 result = TWRC_SUCCESS; |
switch (Msg) |
{ |
case MSG_ENABLEDS: /* show the UI and arm for possible transfers */ |
if (gCurrentState==STATE_DSOPEN) |
{ |
gCurrentState=STATE_DSENABLED; |
if (pUserInterface->ShowUI) |
{ |
DisplayUserInterface(); |
} |
} else |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_SEQERROR; |
} |
break; |
case MSG_DISABLEDS: /* hide the UI and disarm */ |
DisposeDialog(gDialog); |
if (gCurrentState==STATE_DSENABLED) |
{ |
gCurrentState=STATE_DSOPEN; |
} else |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_SEQERROR; |
} |
break; |
default: |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADPROTOCOL; |
break; |
} |
return(result); |
} |
// --------------------------------------------------------------------------- |
// DS_Control_XferGroup |
// --------------------------------------------------------------------------- |
// |
TW_INT16 DS_Control_XferGroup ( pTW_IDENTITY pSource, TW_UINT16 Msg, pTW_UINT16 pXferGroup) |
{ |
TW_INT16 result = TWRC_SUCCESS; |
switch (Msg) |
{ |
case MSG_GET: |
if ((gCurrentState>=STATE_DSOPEN)&&(gCurrentState<=STATE_XFERREADY)) |
{ |
*pXferGroup=DG_IMAGE; |
} else |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_SEQERROR; |
} |
break; |
default: |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADPROTOCOL; |
break; |
} |
return(result); |
} |
#pragma mark - |
#pragma mark ---------------------- Event handling |
// --------------------------------------------------------------------------- |
// doDrawContent |
// --------------------------------------------------------------------------- |
// |
void doDrawContent(WindowRef windowRef) |
{ |
GrafPtr oldPort; |
GetPort(&oldPort); |
SetPortWindowPort(windowRef); |
BeginUpdate ( windowRef ); |
DrawControls(windowRef); |
EndUpdate ( windowRef ); |
SetPort(oldPort); |
} |
// --------------------------------------------------------------------------- |
// doCloseCommand |
// --------------------------------------------------------------------------- |
// |
void doCloseCommand() |
{ |
} |
// --------------------------------------------------------------------------- |
// doAdjustCursor |
// --------------------------------------------------------------------------- |
// |
void doAdjustCursor(WindowRef windowRef) |
{ |
#pragma unused (windowRef) |
SetThemeCursor(kThemePlusCursor); |
} |
// --------------------------------------------------------------------------- |
// windowEventHandler |
// --------------------------------------------------------------------------- |
// |
OSStatus windowEventHandler(EventHandlerCallRef eventHandlerCallRef, |
EventRef eventRef, |
void* userData) |
{ |
#pragma unused (eventHandlerCallRef, userData) |
OSStatus result = eventNotHandledErr; |
UInt32 eventClass; |
UInt32 eventKind; |
EventRecord eventRecord; |
SInt16 itemHit; |
SInt8 charCode; |
ControlRef controlRef; |
UInt32 finalTicks; |
eventClass = GetEventClass(eventRef); |
eventKind = GetEventKind(eventRef); |
//DS_LogText("windowEventHandler eventClass - '%4.4s'\n", &eventClass); |
//DS_LogText(" eventKind - '%d'\n", eventKind); |
switch(eventClass) |
{ |
case kEventClassWindow: // event class window |
ConvertEventRefToEventRecord(eventRef,&eventRecord); |
switch(eventKind) |
{ |
case kEventWindowUpdate: |
doDrawContent(GetDialogWindow(gDialog)); |
break; |
case kEventWindowDrawContent: |
DrawControls(GetDialogWindow(gDialog)); |
result = noErr; |
break; |
case kEventWindowActivated: |
DialogSelect(&eventRecord,&gDialog,&itemHit); |
result = noErr; |
break; |
case kEventWindowClose: |
QuitApplicationEventLoop(); |
result = noErr; |
break; |
} |
case kEventClassMouse: // event class mouse |
ConvertEventRefToEventRecord(eventRef,&eventRecord); |
switch(eventKind) |
{ |
case kEventMouseDown: |
if(IsDialogEvent(&eventRecord)) |
{ |
if(DialogSelect(&eventRecord,&gDialog,&itemHit)) |
{ |
TW_CALLBACK callback = {}; |
if (itemHit == kScanButton) |
{ |
DS_LogText("kScanButton pressed\n"); |
gTransferReady = true; |
gCurrentState = STATE_XFERREADY; |
// now call into the DSM... |
callback.Message = MSG_XFERREADY; |
result = DSM_Entry((pTW_IDENTITY)&Identity, |
(pTW_IDENTITY)NULL, |
(TW_UINT32)DG_CONTROL, |
(TW_UINT16)DAT_CALLBACK, |
(TW_UINT16)MSG_INVOKE_CALLBACK, |
(TW_MEMREF) &callback); |
} else if(itemHit == kCancelButton) |
{ |
DS_LogText("kCancelButton pressed\n"); |
// now call into the DSM... |
callback.Message = MSG_CLOSEDSREQ; |
result = DSM_Entry((pTW_IDENTITY)&Identity, |
(pTW_IDENTITY)NULL, |
(TW_UINT32)DG_CONTROL, |
(TW_UINT16)DAT_CALLBACK, |
(TW_UINT16)MSG_INVOKE_CALLBACK, |
(TW_MEMREF) &callback); |
} |
} |
} |
doAdjustCursor(GetDialogWindow(gDialog)); |
break; |
case kEventMouseMoved: |
{ |
Rect pictRect; |
DialogItemType itemType; |
Handle item; |
Point mouseLocation; |
SetPortWindowPort ( GetDialogWindow(gDialog) ); |
GetDialogItem(gDialog, 3, &itemType, &item, &pictRect); |
GetMouse(&mouseLocation); |
if (PtInRect(mouseLocation, &pictRect)) |
SetThemeCursor(kThemePlusCursor); |
else |
SetThemeCursor(kThemeArrowCursor); |
} |
break; |
} |
break; |
case kEventClassKeyboard: // event class keyboard |
switch(eventKind) |
{ |
case kEventRawKeyDown: |
ConvertEventRefToEventRecord(eventRef,&eventRecord); |
GetEventParameter(eventRef,kEventParamKeyMacCharCodes,typeChar,NULL, |
sizeof(charCode),NULL,&charCode); |
if((charCode == kReturn) || (charCode == kEnter)) |
{ |
GetDialogItemAsControl(gDialog,kScanButton,&controlRef); |
HiliteControl(controlRef,kControlButtonPart); |
Delay(8,&finalTicks); |
HiliteControl(controlRef,kControlEntireControl); |
return noErr; |
} |
break; |
} |
break; |
} |
return result; |
} |
#pragma mark - |
#pragma mark ---------------------- Image Data Group |
// --------------------------------------------------------------------------- |
// DS_Image |
// --------------------------------------------------------------------------- |
// Process Data Argument types for the DG_IMAGE Data Group. |
TW_INT16 DS_Image ( pTW_IDENTITY pSource, TW_UINT16 Dat, TW_UINT16 Msg, TW_MEMREF pData) |
/* |
** Parameters: None. |
** Globals: None. |
** Operation: |
** Return: |
** status TWRC_SUCCESS |
** TWRC_FAILURE |
** History: |
*/ |
{ |
TW_INT16 result = TWRC_SUCCESS; |
switch (Dat) |
{ |
case DAT_IMAGEINFO: |
result = DS_Image_ImageInfo(pSource,Msg,(pTW_IMAGEINFO)pData); |
break; |
case DAT_IMAGENATIVEXFER: |
result = DS_Image_NativeXfer(pSource,Msg,(PicHandle *)pData); |
break; |
case DAT_IMAGEFILEXFER: |
result = DS_Image_FileXfer(pSource,Msg,pData); |
break; |
case DAT_IMAGEMEMXFER: |
result = DS_Image_MemXfer(pSource,Msg,(pTW_IMAGEMEMXFER)pData); |
break; |
case DAT_IMAGELAYOUT: |
result = DS_Image_ImageLayout(pSource,Msg,(pTW_IMAGELAYOUT)pData); |
break; |
default: |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADPROTOCOL; |
break; |
} |
return(result); |
} |
// --------------------------------------------------------------------------- |
// DS_Image_ImageInfo |
// --------------------------------------------------------------------------- |
// |
TW_INT16 DS_Image_ImageInfo ( pTW_IDENTITY pSource, TW_UINT16 Msg, pTW_IMAGEINFO pImageInfo ) |
{ |
TW_INT16 result = TWRC_SUCCESS; |
switch (Msg) |
{ |
case MSG_GET: /* get the current transfers image information */ |
if (gCurrentState==STATE_XFERREADY) |
{ |
if (!gInfoLoaded) |
result = GetImageInfo(); |
if (result == TWRC_SUCCESS) |
*pImageInfo=ImageInfo; |
} else |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_SEQERROR; |
} |
break; |
default: |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADPROTOCOL; |
break; |
} |
return(result); |
} |
// --------------------------------------------------------------------------- |
// DS_Image_ImageLayout |
// --------------------------------------------------------------------------- |
// |
TW_INT16 DS_Image_ImageLayout ( pTW_IDENTITY pSource, TW_UINT16 Msg, pTW_IMAGELAYOUT pImageLayout) |
{ |
TW_INT16 result = TWRC_SUCCESS; |
switch (Msg) |
{ |
case MSG_GET: /* get the current transfers image information */ |
if ((gCurrentState>=STATE_DSOPEN)&&(gCurrentState<=STATE_XFERREADY)) |
{ |
*pImageLayout=ImageLayout; |
} else |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_SEQERROR; |
} |
break; |
case MSG_GETDEFAULT: /* get the current transfers image information */ |
if ((gCurrentState>=STATE_DSOPEN)&&(gCurrentState<=STATE_XFERREADY)) |
{ |
GetDefaultImageLayout(pImageLayout); |
} else |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_SEQERROR; |
} |
break; |
case MSG_RESET: /* get the current transfers image information */ |
if (gCurrentState==STATE_DSOPEN) |
{ |
GetDefaultImageLayout(pImageLayout); |
ImageLayout=*pImageLayout; |
} else |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_SEQERROR; |
} |
break; |
case MSG_SET: /* get the current transfers image information */ |
if (gCurrentState==STATE_DSOPEN) |
{ |
ImageLayout=*pImageLayout; |
} else |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_SEQERROR; |
} |
break; |
default: |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADPROTOCOL; |
break; |
} |
return(result); |
} |
// --------------------------------------------------------------------------- |
// DS_Image_NativeXfer |
// --------------------------------------------------------------------------- |
// |
TW_INT16 DS_Image_NativeXfer ( pTW_IDENTITY pSource, TW_UINT16 Msg, PicHandle *pHandle ) |
{ |
TW_INT16 result = TWRC_SUCCESS; |
switch (Msg) |
{ |
case MSG_GET: |
if (gCurrentState==STATE_XFERREADY) |
{ |
if (gTransferReady) |
{ |
if (hPicture == nil) |
result = LoadImageAsPict(); |
if (result == TWRC_SUCCESS) |
{ |
*pHandle=hPicture; |
hPicture = NULL; |
gTransferReady = FALSE; |
gCurrentState = STATE_XFER; |
} else |
{ |
*pHandle = nil; |
hPicture = nil; |
gTransferReady = FALSE; |
gCurrentState = STATE_XFERREADY; |
} |
} |
} else |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_SEQERROR; |
} |
break; |
default: |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADPROTOCOL; |
break; |
} |
return(result); |
} |
// --------------------------------------------------------------------------- |
// DS_Image_MemXfer |
// --------------------------------------------------------------------------- |
// |
TW_INT16 DS_Image_MemXfer ( pTW_IDENTITY pSource, TW_UINT16 Msg, pTW_IMAGEMEMXFER pImageXfer ) |
{ |
TW_INT16 result = TWRC_SUCCESS; |
switch (Msg) |
{ |
case MSG_GET: /* get a block of image information */ |
if ((gCurrentState==STATE_XFERREADY) || (gCurrentState==STATE_XFER)) |
{ |
if (gTransferReady) |
{ |
if (gGWorld == nil) |
result = LoadImageAsGWorld(); |
if (result == TWRC_SUCCESS) |
{ |
// Clear the image buffer |
char* buffer = pImageXfer->Memory.TheMem; |
UInt32 rowsThisTime; |
if (pImageXfer->Memory.Flags & TWMF_HANDLE) |
buffer = (char*) * (Handle) buffer; |
memset(buffer, 128, pImageXfer->Memory.Length); |
// Figure how many rows to transfer on this pass |
rowsThisTime = pImageXfer->Memory.Length / (ImageInfo.ImageWidth * 3); |
if (gRowsTransfered + rowsThisTime > ImageInfo.ImageLength) |
rowsThisTime = ImageInfo.ImageLength - gRowsTransfered; |
// Fill in the info |
pImageXfer->Compression = TWCP_NONE; |
pImageXfer->BytesPerRow = ImageInfo.ImageWidth * 3; |
pImageXfer->Columns = ImageInfo.ImageWidth; |
pImageXfer->Rows = rowsThisTime; |
pImageXfer->XOffset = 0; |
pImageXfer->YOffset = gRowsTransfered; |
pImageXfer->BytesWritten = pImageXfer->Memory.Length; |
// Move pixels from the GWorld to the buffer |
(void) LockPixels(GetGWorldPixMap(gGWorld)); |
{ |
UInt32 gworldRowBytes = (*GetGWorldPixMap(gGWorld))->rowBytes & 0x3FFE; |
UInt32 col, row; |
UInt8* gworldPixel; |
UInt8* bitmapPixel; |
for (row = 0; row < rowsThisTime; row++) |
{ |
gworldPixel = (UInt8*) GetPixBaseAddr( |
GetGWorldPixMap(gGWorld)) + |
((row + gRowsTransfered) * gworldRowBytes); |
bitmapPixel = (UInt8*) (buffer + (row * pImageXfer->BytesPerRow)); |
for (col = 0; col < ImageInfo.ImageWidth; col++) |
{ |
bitmapPixel[0] = gworldPixel[1]; |
bitmapPixel[1] = gworldPixel[2]; |
bitmapPixel[2] = gworldPixel[3]; |
bitmapPixel += 3; |
gworldPixel += 4; |
} |
} |
} |
UnlockPixels(GetGWorldPixMap(gGWorld)); |
gCurrentState=STATE_XFER; |
gRowsTransfered += rowsThisTime; |
// See if we are done |
if (gRowsTransfered == ImageInfo.ImageLength) |
{ |
gRowsTransfered = 0; |
gTransferReady = FALSE; |
gCurrentState=STATE_XFER; |
result = TWRC_XFERDONE; |
} |
} else |
{ |
} |
} |
} else |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_SEQERROR; |
} |
break; |
default: |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADPROTOCOL; |
break; |
} |
return(result); |
} |
// --------------------------------------------------------------------------- |
// DS_Image_FileXfer |
// --------------------------------------------------------------------------- |
// |
TW_INT16 DS_Image_FileXfer ( pTW_IDENTITY pSource, |
TW_UINT16 Msg, |
TW_MEMREF pNULL ) |
{ |
TW_INT16 result = TWRC_SUCCESS; |
switch (Msg) |
{ |
#if 0 |
case MSG_GET: /* get a block of image information */ |
DS_LogText("DS_Image_FileXfer: MSG_GET\n"); |
if (gCurrentState==STATE_XFERREADY) |
{ |
/* do file transfer */ |
gCurrentState=STATE_XFER; |
} else |
{ |
result = TWRC_FAILURE; |
gConditionCode = TWCC_SEQERROR; |
} |
break; |
#endif |
default: |
result = TWRC_FAILURE; |
gConditionCode = TWCC_BADPROTOCOL; |
break; |
} |
return(result); |
} |
#pragma mark - |
#pragma mark ---------------------- Internal |
// --------------------------------------------------------------------------- |
// FSPathMakeFSSpec |
// --------------------------------------------------------------------------- |
OSErr FSPathMakeFSSpec( const UInt8 * inPath, |
FSSpec * outFSSpec, |
Boolean * outIsDirectory ) |
{ |
OSStatus err; |
FSRef ref; |
err = FSPathMakeRef( inPath, &ref, outIsDirectory ); |
require_noerr( err, exit ); |
err = FSGetCatalogInfo( &ref, kFSCatInfoNone, NULL, NULL, outFSSpec, NULL ); |
require_noerr( err, exit ); |
exit: |
return( err ); |
} |
// --------------------------------------------------------------------------- |
// DisplayUserInterface |
// --------------------------------------------------------------------------- |
// |
void DisplayUserInterface() |
{ |
SInt16 savedResRefNum; |
SInt16 resRefNum = 0; |
CFBundleRef selfBundleRef; |
OSStatus status = noErr; |
ControlRef pictureControlRef; |
EventTypeSpec windowEvents[] = { { kEventClassWindow, kEventWindowDrawContent }, |
{ kEventClassWindow, kEventWindowUpdate }, |
{ kEventClassWindow, kEventWindowClose }, |
{ kEventClassWindow, kEventWindowClickDragRgn }, |
{ kEventClassMouse, kEventMouseDown }, |
{ kEventClassMouse, kEventMouseMoved } }; |
selfBundleRef = CFBundleGetBundleWithIdentifier ( CFSTR ( "com.apple.sampleds" ) ); |
if (selfBundleRef) |
resRefNum = CFBundleOpenBundleResourceMap ( selfBundleRef ); |
else |
DS_LogText("ERROR: selfBundleRef is NULL"); |
savedResRefNum = CurResFile(); |
UseResFile ( resRefNum ); |
gDialog = GetNewDialog(128, nil, (WindowRef)-1); |
UseResFile ( savedResRefNum ); |
ChangeWindowAttributes(GetDialogWindow(gDialog),kWindowStandardHandlerAttribute | |
kWindowCloseBoxAttribute, |
kWindowCollapseBoxAttribute); |
GetDialogItemAsControl(gDialog, kScanButton, &gScanButton); |
DS_LogText("gScanButton = %08X\n", gScanButton); |
GetDialogItemAsControl(gDialog, kCancelButton, &gCancelButton); |
DS_LogText("gCancelButton = %08X\n", gCancelButton); |
InstallStandardEventHandler(GetWindowEventTarget(GetDialogWindow(gDialog))); |
InstallWindowEventHandler(GetDialogWindow(gDialog), |
NewEventHandlerUPP((EventHandlerProcPtr) windowEventHandler), |
GetEventTypeCount(windowEvents), windowEvents, |
0,NULL); |
DS_LogText("InstallWindowEventHandler done\n"); |
ShowWindow(GetDialogWindow(gDialog)); |
// drop the file selection sheet |
// gImageFileInfo.specified = FilteredChooseOneFile ( &gImageFileInfo.spec, GetDialogWindow ( gDialog ) ); |
// LoadImageAsPICT(); |
status = GetDialogItemAsControl ( gDialog, 3, &pictureControlRef ); |
require_noerr ( status, BAIL ); |
gPicture = GetPicture(130); |
status = SetControlData ( pictureControlRef, kControlPicturePart, kControlPictureHandleTag, sizeof ( PicHandle ), &gPicture ); |
require_noerr ( status, BAIL ); |
DrawOneControl ( pictureControlRef ); |
BAIL: |
return; |
} |
// -------------------------------------------------------------------------------- |
// SelectFile |
// |
// Ask the user to choose a file |
// -------------------------------------------------------------------------------- |
TW_INT16 SelectFile(void) |
{ |
TW_INT16 result = TWRC_FAILURE; |
OSErr err = noErr; |
NavReplyRecord navReplyRec; |
NavDialogOptions navDialogOptions; |
NavTypeListHandle fileTypeListHandle; |
err = NavLoad(); |
navReplyRec.validRecord = false; |
NavGetDefaultDialogOptions ( &navDialogOptions ); |
navDialogOptions.dialogOptionFlags &= ~kNavAllowMultipleFiles; |
fileTypeListHandle = (NavTypeListHandle)Get1Resource ( 'open', 128 ); |
err = ResError(); |
err = NavChooseFile ( nil, &navReplyRec, &navDialogOptions, nil, nil, nil, fileTypeListHandle, nil ); |
if ( ( err != noErr ) || navReplyRec.validRecord == false ) |
{ |
result = TWRC_CANCEL; |
} else |
{ |
AEDesc specDesc; |
AEDescList selectedItems = navReplyRec.selection; |
err = AECoerceDesc ( &selectedItems, typeFSS, &specDesc ); |
gFileSpec = **(FSSpec**) specDesc.dataHandle; |
AEDisposeDesc ( &specDesc ); |
gTransferReady = true; |
TWMessage = MSG_XFERREADY; |
gCurrentState = STATE_XFERREADY; |
result = TWRC_SUCCESS; |
} |
// cleanup |
if ( navReplyRec.validRecord ) |
NavDisposeReply ( &navReplyRec ); |
ReleaseResource ( (Handle)fileTypeListHandle ); |
NavUnload(); |
return result; |
} |
// -------------------------------------------------------------------------------- |
// LoadImageAsPict |
// |
// Load the selected image as a PICT |
// -------------------------------------------------------------------------------- |
TW_INT16 LoadImageAsPict(void) |
{ |
TW_INT16 result = TWRC_FAILURE; |
GraphicsImportComponent importer = nil; |
if (GetGraphicsImporterForFile(&gFileSpec, &importer) == noErr) |
{ |
#ifdef USING_QUICKTIME_4 |
if (GraphicsImportSetFlags(importer, kGraphicsImporterDontDoGammaCorrection) == noErr) |
#endif |
{ |
PicHandle pictHandle = nil; |
if (GraphicsImportGetAsPicture(importer, &pictHandle) == noErr) |
{ |
// Whew! We now have a PicHandle. Unfortunately, the caller |
// expects a normal Handle. Copy the data and kill the picture. |
UInt32 pictSize = GetHandleSize((Handle) pictHandle); |
Handle dataHandle = NewHandle(pictSize); |
if (dataHandle && MemError() == noErr) |
{ |
BlockMoveData(*pictHandle, *dataHandle, pictSize); |
hPicture = (PicHandle) dataHandle; |
result = TWRC_SUCCESS; |
} |
KillPicture(pictHandle); |
} |
} |
// Clean up |
if (importer) |
CloseComponent(importer); |
} |
return (result); |
} |
// -------------------------------------------------------------------------------- |
// LoadImageAsGWorld |
// |
// Load the selected image as a GWorld |
// -------------------------------------------------------------------------------- |
TW_INT16 LoadImageAsGWorld(void) |
{ |
TW_INT16 result = TWRC_FAILURE; |
GraphicsImportComponent importer = nil; |
if (GetGraphicsImporterForFile(&gFileSpec, &importer) == noErr) |
{ |
#ifdef USING_QUICKTIME_4 |
if (GraphicsImportSetFlags(importer, kGraphicsImporterDontDoGammaCorrection) == noErr) |
#endif |
{ |
// Create a GWorld to hold the image |
Rect rect = {0, 0, ImageInfo.ImageLength, ImageInfo.ImageWidth}; |
UInt16 depth = ImageInfo.BitsPerPixel; |
if (depth == 24) |
depth = 32; |
if (NewGWorld(&gGWorld, depth, &rect, nil, nil, useTempMem) == noErr) |
{ |
// Erase the GWorld so the picture loads correctly |
CGrafPtr savePort; |
GDHandle saveDevice; |
RGBColor white = {65535, 65535, 65535}; |
RGBColor black = {0, 0, 0}; |
GetGWorld(&savePort, &saveDevice); |
SetGWorld(gGWorld, nil); |
RGBForeColor(&white); |
RGBBackColor(&black); |
EraseRect(&rect); |
// Load the image |
if (GraphicsImportSetGWorld(importer, gGWorld, nil) == noErr) |
{ |
if (GraphicsImportDraw(importer) == noErr) |
{ |
result = TWRC_SUCCESS; |
} |
} |
SetGWorld(savePort, saveDevice); |
} |
} |
// Clean up |
if (importer) |
CloseComponent(importer); |
} |
if (result != TWRC_SUCCESS) |
{ |
if (gGWorld != nil) |
{ |
DisposeGWorld(gGWorld); |
gGWorld = nil; |
} |
} |
return (result); |
} |
// -------------------------------------------------------------------------------- |
// GetImageInfo |
// |
// Loads ImageInfo with information about the image |
// -------------------------------------------------------------------------------- |
TW_INT16 GetImageInfo(void) |
{ |
TW_INT16 result = TWRC_FAILURE; |
CFURLRef fileURL = NULL; |
CFBundleRef bundle; |
FSRef fsRef; |
gFileSpec.name[0] = 0; |
// find the sample.pict in our bundle... |
bundle = CFBundleGetBundleWithIdentifier ( CFSTR( "com.apple.sampleds" ) ); |
fileURL = CFBundleCopyResourceURL(bundle, CFSTR("sample"), CFSTR("pict"), NULL); |
if (fileURL) |
{ |
if ( CFURLGetFSRef(fileURL, &fsRef) ) |
{ |
char buffer[256]; |
FSRefMakePath(&fsRef, buffer, 256); |
DS_LogText ( "found sample pict: '%s'\n", buffer ); |
FSPathMakeFSSpec(buffer, &gFileSpec, 0); |
} |
CFStringRef pathStr = CFURLCopyPath(fileURL); |
if (pathStr) |
{ |
CFRelease(pathStr); |
} |
CFRelease(fileURL); |
} |
if (gFileSpec.name[0]) |
{ |
GraphicsImportComponent importer = nil; |
ImageDescriptionHandle imageDescHandle = nil; |
ImageDescriptionPtr imageDescPtr = nil; |
if (GetGraphicsImporterForFile(&gFileSpec, &importer) == noErr) |
{ |
#ifdef USING_QUICKTIME_4 |
if (GraphicsImportSetFlags(importer, kGraphicsImporterDontDoGammaCorrection) == noErr) |
#endif |
{ |
if (GraphicsImportGetImageDescription(importer, &imageDescHandle) == noErr) |
{ |
HLock ( (Handle)imageDescHandle ); |
{ |
imageDescPtr = *imageDescHandle; |
ImageInfo.XResolution.Whole = Fix2Long(imageDescPtr->hRes); |
ImageInfo.XResolution.Frac = 0; |
ImageInfo.YResolution.Whole = Fix2Long(imageDescPtr->vRes); |
ImageInfo.YResolution.Frac = 0; |
ImageInfo.ImageWidth = imageDescPtr->width; |
ImageInfo.ImageLength = imageDescPtr->height; |
ImageInfo.SamplesPerPixel = 3; |
ImageInfo.BitsPerPixel = imageDescPtr->depth; |
// Clip to 24 bits, since Mac GWorlds are usually 32 bits |
if (ImageInfo.BitsPerPixel > 24) |
ImageInfo.BitsPerPixel = 24; |
ImageInfo.BitsPerSample[0] = ImageInfo.BitsPerPixel / ImageInfo.SamplesPerPixel; |
ImageInfo.BitsPerSample[1] = ImageInfo.BitsPerPixel / ImageInfo.SamplesPerPixel; |
ImageInfo.BitsPerSample[2] = ImageInfo.BitsPerPixel / ImageInfo.SamplesPerPixel; |
ImageInfo.Planar = FALSE; |
ImageInfo.PixelType = TWPT_RGB; |
ImageInfo.Compression = TWCP_NONE; |
// Always return that the image is 24 bits for this sample |
// Handling lower bit depth images is left as an exercise for the |
// reader... |
ImageInfo.BitsPerPixel = 24; |
gInfoLoaded = true; |
result = TWRC_SUCCESS; |
} |
HUnlock ( (Handle)imageDescHandle ); |
} |
} |
} |
// Clean up |
if (importer) |
CloseComponent(importer); |
if (imageDescHandle) |
DisposeHandle((Handle) imageDescHandle); |
} |
else |
{ |
TWMessage=MSG_CLOSEDSREQ; |
return(TWRC_CANCEL); |
} |
return (result); |
} |
// --------------------------------------------------------------------------- |
// FindIndex |
// --------------------------------------------------------------------------- |
// Retruns the index of the requested Item. |
TW_INT16 FindIndex(TW_INT16 Item, |
pTW_INT16 pList, |
TW_INT16 Number) |
{ |
TW_INT16 i; |
for (i=0;i<Number;i++) |
{ |
if (pList[i]==Item) |
return(i); |
} |
return(TWERR); |
} |
// --------------------------------------------------------------------------- |
// GetDefaultImageLayout |
// --------------------------------------------------------------------------- |
// |
TW_INT16 GetDefaultImageLayout(pTW_IMAGELAYOUT pImageLayout) |
{ |
pImageLayout->Frame.Top.Whole =0; |
pImageLayout->Frame.Top.Frac =0; |
pImageLayout->Frame.Bottom.Whole=11; |
pImageLayout->Frame.Bottom.Frac =0; |
pImageLayout->Frame.Left.Whole =0; |
pImageLayout->Frame.Left.Frac =0; |
pImageLayout->Frame.Right.Whole =8; |
pImageLayout->Frame.Right.Frac =65536/2; |
pImageLayout->DocumentNumber =0; |
pImageLayout->PageNumber =0; |
pImageLayout->FrameNumber =0; |
return(OKAY); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-07-10