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.
HoseIrda.c
/* |
File: HoseIrda.c |
Contains: Sample code to demonstrate how a LaserWriter communication hose |
plugin can be written. An Irda (Infrared) hose is used here. |
Written by: Chorng-Shyan Lin and Ingrid Kelly |
Copyright: Copyright © 1999 by Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source code" after having made |
changes. If you're going to re-distribute the source, we require that you make |
it clear in the source that the code was descended from Apple sample source |
code, but that you've made changes. |
Change History (most recent first): |
7/26/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 |
5/5/99 lin changed the way cntl-D is sent at close time, |
longer time-out |
*/ |
#include <CommResources.h> |
#include <CTBUtilities.h> |
#include <Connections.h> |
#include "Hose.h" |
#include "HoseIrda.h" |
#include "PSWriterErr.h" |
#define LockHint(collection, tag, id) SetCollectionItemInfo((collection), (tag), (id), kCollectionLockMask, kCollectionLockMask) |
/* The following two macros are intended to make it easier to |
declare routines that will be invoked by the MixedMode Mgr. |
DeclareProcPtr() will create a routine descriptor with the |
name g_'proc' if we are compiling in an environment that |
needs routine descriptors. If we are in the old 68K environment |
then this macro does nothing. MakeProcPtr creates a reference to |
the function pointer 'proc'. If we are using routine descriptors |
then the reference is the address of the descriptor created by |
DeclareProcPtr(). If we are in a 68K world then the reference |
is just the proc pointer itself. |
*/ |
#if TARGET_RT_MAC_CFM |
#define DeclareProcPtr(proc, upp) \ |
RoutineDescriptor g_##proc = BUILD_ROUTINE_DESCRIPTOR(upp, proc); |
#define ExternalProcPtr(proc) \ |
extern RoutineDescriptor g_##proc; |
#define MakeProcPtr(proc, procType) \ |
((procType)&g_##proc) |
#else |
#define DeclareProcPtr(proc, upp) |
#define ExternalProcPtr(proc) |
#define MakeProcPtr(proc, procType) \ |
((procType)proc) |
#endif |
/*** Constants ***/ |
#define kClosingTimeOut 3600 |
/*** Variable Types ***/ |
struct IrdaHoseRec { |
ConnHandle connectionH; |
ConnState connectionState; |
MemQElemPtr writeMemQElemPtr; |
MemQElemPtr readMemQElemPtr; |
BufCallbacks callbacks; |
Boolean eojFired; |
Boolean needToDumpDataOut; |
Boolean needToRequestStatus; |
OSErr openResult; |
Boolean needCloseEoj; |
long startCloseTime; |
}; |
typedef struct IrdaHoseRec IrdaHoseRec; |
typedef IrdaHoseRec* IrdaHoseRecPtr; |
/*** Prototypes ***/ |
OSErr InitLib(CFragInitBlockPtr initBlkPtr); |
void TerminateLib(void); |
// hose API |
static OSStatus closeIrdaHose(void *refcon); |
static OSStatus outIrdaHose(void *refcon, MemQElemPtr memElem); |
static OSStatus inIrdaHose(void *refcon, MemQElemPtr memElem); |
static OSStatus idleIrdaHose(void *refcon); |
static OSStatus statusIrdaHose(void *refcon, StringPtr statusStr); |
static OSStatus disposeIrdaHose(void *refcon); |
static ConnState connStateIrdaHose(void *refcon); |
// callback from CTB |
static void commOpenCompletion(ConnHandle connectionH); |
static void commWriteCompletion(ConnHandle connectionH); |
static void commReadCompletion(ConnHandle connectionH); |
static void commStatusCompletion(ConnHandle connectionH); |
static void closingEojSentCompletion(ConnHandle connectionH); |
static void closingEojReceivedCompletion(ConnHandle connectionH); |
// utilities |
static OSStatus requestStatus(IrdaHoseRecPtr irdaHoseP); |
static OSStatus cmWritePending(ConnHandle connectionH, Boolean* writePendingP); |
static OSErr translateErr(OSErr err); |
static void StripEOJs(unsigned char* buffer, SInt32* nBytesP); // lin016 |
static OSErr UnLockHint(Collection collection, CollectionTag tag, long id); |
/***Globals**/ |
unsigned char gInCntlD = 0x04; |
unsigned char gOutCntlD = 0x04; |
unsigned char gCntlT = 0x14; |
long gInOne = 1; |
long gOutOne = 1; |
char *gIrDALaserconfigStr = "myClass: LaserPrinter myAttr: IrDA:IrLMP:LsapSel peerClass: IrLPT peerAttr: IrDA:IrLMP:LsapSel\0"; |
DeclareProcPtr(commOpenCompletion, uppConnectionCompletionProcInfo) |
DeclareProcPtr(commWriteCompletion, uppConnectionCompletionProcInfo) |
DeclareProcPtr(commReadCompletion, uppConnectionCompletionProcInfo) |
DeclareProcPtr(commStatusCompletion, uppConnectionCompletionProcInfo) |
DeclareProcPtr(closingEojSentCompletion, uppConnectionCompletionProcInfo) |
DeclareProcPtr(closingEojReceivedCompletion, uppConnectionCompletionProcInfo) |
/*** Code ***/ |
OSErr InitLib(CFragInitBlockPtr /* initBlkPtr */) |
{ |
return noErr; |
} |
void TerminateLib(void) |
{ |
// any clean up if needed |
// do nothing in this case |
} |
#pragma mark - |
#pragma export on |
OSStatus hoseOpen(HoseInfo *hoseInfo, BufCallbacks *callbacks, Collection hints, Handle /* papaH */) |
/* |
Fill out 'hose' with information that describes the IrDA hose |
and Open connection to IrDA printer. |
*/ |
{ |
OSStatus err = noErr; |
short irdaProcID = -1; // -1 is invalid ProcID |
ConnHandle connectionH = 0; |
CMBufferSizes irDaBufSizes; |
IrdaHoseRecPtr irdaHoseP = 0; |
Boolean eighthBit = false; |
Boolean transparentBit = false; |
short i; |
// fill out the proc pointers to our hose |
hoseInfo->out = outIrdaHose; |
hoseInfo->in = inIrdaHose; |
hoseInfo->idle = idleIrdaHose; |
hoseInfo->close = closeIrdaHose; |
hoseInfo->connState = connStateIrdaHose; |
hoseInfo->status = statusIrdaHose; |
hoseInfo->dispose = disposeIrdaHose; |
// buffer info |
hoseInfo->bufSize = kPrinterHoseBufSize; |
hoseInfo->minBufs = 4; |
hoseInfo->maxBufs = kPrinterHoseMaxBufs; |
// add necessary hints |
err = UnLockHint(hints, kHintEighthBitTag, kHintDataFormatId); |
err = AddCollectionItem(hints, kHintEighthBitTag, kHintDataFormatId, sizeof(eighthBit), &eighthBit); |
if(!err) err = LockHint(hints, kHintEighthBitTag, kHintDataFormatId); |
if(!err) err = UnLockHint(hints, kHintTransparentChannelTag, kHintTransparentChannelId); |
if(!err) err = AddCollectionItem(hints, kHintTransparentChannelTag, kHintTransparentChannelId, |
sizeof(transparentBit), &transparentBit); |
if(!err) err = LockHint(hints, kHintTransparentChannelTag, kHintTransparentChannelId); |
// allocate private storage for the hose |
if(!err) irdaHoseP = (IrdaHoseRecPtr)NewPtrClear(sizeof(IrdaHoseRec)); |
if(irdaHoseP){ |
hoseInfo->refcon = (void *)irdaHoseP; |
irdaHoseP->connectionH = 0; |
irdaHoseP->callbacks = *callbacks; |
if(InitCRM != 0){ // if there is Communication Toolbox, initialize it |
err = InitCRM(); |
if(!err) |
err = InitCTBUtilities(); |
if(!err) |
err = InitCM(); |
if(!err){ |
irdaProcID = CMGetProcID("\pIrDA Tool"); // name of IrDA tool |
if(irdaProcID != -1){ |
for(i = cmDataIn; i <= cmRsrvOut ; i++) |
irDaBufSizes[i] = 0; // let IrDA tool decide buffer sizes |
// make a new connection record |
irdaHoseP->connectionH = connectionH = CMNew(irdaProcID, cmData | cmNoMenus | cmQuiet, irDaBufSizes, (long)irdaHoseP, 0); |
if(connectionH){ |
// configure the connection record |
err = CMSetConfig (connectionH, gIrDALaserconfigStr); |
if(err == cmNoErr){ |
irdaHoseP->connectionState = kConnOpening; |
// try to open a connection async. |
err = CMOpen(connectionH, true, MakeProcPtr(commOpenCompletion, ConnectionCompletionUPP), -1); |
if(err != cmNoErr) |
irdaHoseP->connectionState = kConnClosed; |
}else{ |
err = irdaHoseP->openResult = errIrdaUnknownOpenErr; |
/* CTB does not provide a good error code */ |
} |
}else{ |
err = irdaHoseP->openResult = errIrdaUnknownOpenErr; |
/* CTB does not provide a good error code, possibly out of memory */ |
} |
}else{ |
err = irdaHoseP->openResult = errIrdaToolNotFoundErr; // no comm. tool for irDA |
} |
} |
}else{ |
err = irdaHoseP->openResult = errHoseCantBeUsed; // CTB not available |
} |
}else{ |
err = irdaHoseP->openResult = memFullErr; // out of memory |
} |
if(err){ // clean up |
if(connectionH) |
CMDispose(connectionH); |
if(irdaHoseP){ |
DisposePtr((Ptr)irdaHoseP); |
hoseInfo->refcon = 0; |
} |
} |
return (translateErr(err)); |
} |
#pragma export off |
static OSStatus statusIrdaHose(void *refcon, StringPtr /* statusStr */) |
{ |
IrdaHoseRecPtr irdaHoseP; |
OSStatus err = noErr; |
if((irdaHoseP = (IrdaHoseRecPtr)refcon) != 0){ |
irdaHoseP->needToRequestStatus = true; |
// request status from printer |
err = requestStatus(irdaHoseP); |
} |
if(err){ |
err = statusErr; |
if(irdaHoseP && irdaHoseP->openResult) |
err = irdaHoseP->openResult; |
} |
return (err); |
} |
static OSStatus closeIrdaHose(void *refcon) |
{ |
OSStatus err = noErr; |
IrdaHoseRecPtr irdaHoseP; |
ConnHandle connectionH; |
Boolean writePending; |
if((irdaHoseP = (IrdaHoseRecPtr)refcon) != 0){ |
irdaHoseP->connectionState = kConnClosing; |
if((connectionH = irdaHoseP->connectionH) != 0){ |
// depending on the type of hose and printer, we may not want to |
// report "closed" until the printer is done and ready for the next job |
// in this particular hose, we wait for the printer to respond to our extra eoj |
irdaHoseP->startCloseTime = TickCount(); |
irdaHoseP->needCloseEoj = true; |
err = cmWritePending(connectionH, &writePending); |
if(!err && !writePending){ |
irdaHoseP->needCloseEoj = false; |
gOutOne = 1; |
err = CMWrite(connectionH, |
&gOutCntlD, |
&gOutOne, |
cmData, |
true, |
MakeProcPtr(closingEojSentCompletion, ConnectionCompletionUPP), |
-1, |
0); |
} |
} |
} |
return (noErr); |
} |
/* |
routine to write data stream out, async. |
*/ |
static OSStatus outIrdaHose(void *refcon, MemQElemPtr memElem) |
{ |
OSStatus err = paramErr; |
IrdaHoseRecPtr irdaHoseP; |
ConnHandle connectionH; |
Boolean writePending; |
if((irdaHoseP = (IrdaHoseRecPtr)refcon) != 0){ |
if(irdaHoseP->connectionState == kConnClosing){ |
err = noErr; // ignore it if we are already closing |
}else{ |
if(irdaHoseP->connectionState == kConnOpen){ // if the hose is open |
irdaHoseP->writeMemQElemPtr = memElem; |
irdaHoseP->eojFired = false; |
if((connectionH = irdaHoseP->connectionH) != 0){ |
// CTB does not allow multiple writes, may have to postpone it |
err = cmWritePending(connectionH, &writePending); |
if(!err){ |
irdaHoseP->needToDumpDataOut = writePending ? true : false; |
if(!writePending){ |
err = CMWrite(connectionH, |
memElem->buf, |
&(memElem->nBytes), |
cmData, |
true, |
MakeProcPtr(commWriteCompletion, ConnectionCompletionUPP), |
-1, |
0); |
if(err){ |
err = errIrdaDisconnectedErr; |
err = translateErr(err); |
} |
} |
} |
} |
}else{ |
err = PAPNoPrinter; |
} |
} |
} |
if(err){ |
if(irdaHoseP && irdaHoseP->openResult) |
err = irdaHoseP->openResult; |
} |
return err; |
} |
/* |
routine to read data stream in, async. |
*/ |
static OSStatus inIrdaHose(void *refcon, MemQElemPtr memElem) |
{ |
OSStatus err = paramErr; |
IrdaHoseRecPtr irdaHoseP; |
ConnHandle connectionH; |
long numOfBytes; |
CMBufferSizes cmBufSizes; |
CMStatFlags cmFlags; |
memElem->nBytes = 0; |
if((irdaHoseP = (IrdaHoseRecPtr)refcon) != 0){ |
if(irdaHoseP->connectionState == kConnClosing){ |
err = noErr; // ignore it if we are already closing |
}else{ |
if(irdaHoseP->connectionState == kConnOpen){ // if the hose is open |
irdaHoseP->readMemQElemPtr = memElem; |
if((connectionH = irdaHoseP->connectionH) != 0){ |
err = CMStatus(connectionH, |
cmBufSizes, |
&cmFlags); |
if(!err){ |
numOfBytes = cmBufSizes[cmDataIn]; // number of bytes available |
if(numOfBytes > memElem->maxBytes) |
numOfBytes = memElem->maxBytes; |
if(numOfBytes <= 0) |
numOfBytes = 1; // try to read at least one byte |
err = CMRead(connectionH, |
memElem->buf, |
&numOfBytes, |
cmData, |
true, |
MakeProcPtr(commReadCompletion, ConnectionCompletionUPP), |
-1, |
0); |
if(err){ |
err = errIrdaDisconnectedErr; |
err = translateErr(err); |
} |
} |
} |
}else{ |
err = PAPNoPrinter; |
} |
} |
} |
if(err){ |
if(irdaHoseP && irdaHoseP->openResult) |
err = irdaHoseP->openResult; |
} |
return err; |
} |
static OSStatus idleIrdaHose(void *refcon) |
{ |
IrdaHoseRecPtr irdaHoseP; |
ConnHandle connectionH; |
OSStatus err = noErr; |
if((irdaHoseP = (IrdaHoseRecPtr)refcon) != 0){ |
if((connectionH = irdaHoseP->connectionH) != 0){ |
CMIdle(connectionH); |
// take this chance to request status if necessary |
requestStatus(irdaHoseP); |
} |
err = irdaHoseP->openResult ? irdaHoseP->openResult : noErr; |
} |
return(err); |
} |
static OSStatus disposeIrdaHose(void *refcon) |
{ |
OSStatus err = noErr; |
IrdaHoseRecPtr irdaHoseP; |
ConnHandle connectionH; |
if((irdaHoseP = (IrdaHoseRecPtr)refcon) != 0){ |
if((connectionH = irdaHoseP->connectionH) != 0){ |
// close connection |
err = CMClose(connectionH, false, 0, -1, true); |
// dispose connection record |
CMDispose(connectionH); |
} |
// dispose private storage |
DisposePtr((Ptr)irdaHoseP); |
} |
return noErr; |
} |
/* Return the current state of the hose |
*/ |
static ConnState connStateIrdaHose(void *refcon) |
{ |
IrdaHoseRecPtr irdaHoseP; |
ConnHandle connectionH; |
ConnState connState = kConnClosed; |
OSStatus err = noErr; |
Boolean writePending; |
if((irdaHoseP = (IrdaHoseRecPtr)refcon) != 0){ |
if(irdaHoseP->connectionState == kConnClosing){ // if we are closing down the hose |
if((TickCount() - irdaHoseP->startCloseTime) > kClosingTimeOut){ // test time-out |
irdaHoseP->connectionState = kConnClosed; |
}else{ |
// write an extra eoj to printer as part of closing process |
connectionH = irdaHoseP->connectionH; |
if(irdaHoseP->needCloseEoj && connectionH){ |
err = cmWritePending(connectionH, &writePending); |
if(!err && !writePending){ |
gOutOne = 1; |
err = CMWrite(connectionH, |
&gOutCntlD, |
&gOutOne, |
cmData, |
true, |
MakeProcPtr(closingEojSentCompletion, ConnectionCompletionUPP), |
-1, |
0); |
irdaHoseP->needCloseEoj = false; |
} |
} |
} |
} |
connState = irdaHoseP->connectionState; |
} |
return connState; |
} |
/* |
This call-back routine is called by CTB when our open request completes |
*/ |
static void commOpenCompletion(ConnHandle connectionH) |
{ |
IrdaHoseRecPtr irdaHoseP; |
if(connectionH){ |
irdaHoseP = (IrdaHoseRecPtr)(*connectionH)->refCon; |
if(irdaHoseP){ |
irdaHoseP->connectionState = (*connectionH)->errCode ? kConnClosed : kConnOpen; |
irdaHoseP->openResult = (*connectionH)->errCode ? PAPNoPrinter : noErr; |
} |
} |
} |
static void closingEojSentCompletion(ConnHandle connectionH) |
{ |
IrdaHoseRecPtr irdaHoseP; |
OSStatus err; |
if(connectionH){ |
if((irdaHoseP = (IrdaHoseRecPtr)(*connectionH)->refCon) != 0){ |
err = (*connectionH)->errCode; |
if(err == noErr){ |
gInOne = 1; |
err = CMRead(connectionH, |
&gInCntlD, |
&gInOne, |
cmData, |
true, |
MakeProcPtr(closingEojReceivedCompletion, ConnectionCompletionUPP), |
-1, |
0); |
} |
} |
} |
} |
static void closingEojReceivedCompletion(ConnHandle connectionH) |
{ |
IrdaHoseRecPtr irdaHoseP; |
/* we can further test if the received data contain eoj from the printer. |
we don't do this here b/c we seem to have posponed the closing report long enough |
already and also it could be an overkill to wait for the eoj. |
*/ |
if(connectionH){ |
if((irdaHoseP = (IrdaHoseRecPtr)(*connectionH)->refCon) != 0){ |
irdaHoseP->connectionState = kConnClosed; |
} |
} |
} |
static void commWriteCompletion(ConnHandle connectionH) |
{ |
IrdaHoseRecPtr irdaHoseP; |
MemQElemPtr writeMemQElemPtr; |
OSStatus err; |
if(connectionH){ |
irdaHoseP = (IrdaHoseRecPtr)(*connectionH)->refCon; |
if(irdaHoseP){ |
writeMemQElemPtr = irdaHoseP->writeMemQElemPtr; |
err = (*connectionH)->errCode; |
if(err){ |
err = errIrdaDisconnectedErr; |
err = translateErr(err); |
} |
// if we have sent an eoj as part of the previous write request |
if(irdaHoseP->eojFired){ |
requestStatus(irdaHoseP); // give status request a chance |
irdaHoseP->eojFired = false; |
// notify client of completion |
if(err && (irdaHoseP->connectionState == kConnClosing)) |
err = noErr; |
if(irdaHoseP->callbacks.finishedWrite) |
(irdaHoseP->callbacks.finishedWrite)(writeMemQElemPtr, err); |
}else{ |
if(!err && writeMemQElemPtr->eoj){ // need to send an eoj |
irdaHoseP->eojFired = true; |
gOutOne = 1; |
err = CMWrite(connectionH, |
&gOutCntlD, |
&gOutOne, |
cmData, |
true, |
MakeProcPtr(commWriteCompletion, ConnectionCompletionUPP), |
-1, |
0); |
// notify client of error |
if(err){ |
irdaHoseP->eojFired = false; |
if(err && (irdaHoseP->connectionState == kConnClosing)) |
err = noErr; |
if(irdaHoseP->callbacks.finishedWrite) |
(irdaHoseP->callbacks.finishedWrite)(writeMemQElemPtr, err); |
} |
}else{ |
requestStatus(irdaHoseP); // give status request a chance |
if(err && (irdaHoseP->connectionState == kConnClosing)) |
err = noErr; |
// notify client of completion |
if(irdaHoseP->callbacks.finishedWrite) |
(irdaHoseP->callbacks.finishedWrite)(writeMemQElemPtr, err); |
} |
} |
} |
} |
} |
static void commReadCompletion(ConnHandle connectionH) |
{ |
IrdaHoseRecPtr irdaHoseP; |
MemQElemPtr readMemQElemPtr; |
OSStatus err; |
if(connectionH){ |
err = (*connectionH)->errCode; |
if(err){ |
err = errIrdaDisconnectedErr; |
err = translateErr(err); |
} |
irdaHoseP = (IrdaHoseRecPtr)(*connectionH)->refCon; |
if(irdaHoseP){ |
if(err && (irdaHoseP->connectionState == kConnClosing)) |
err = noErr; |
readMemQElemPtr = irdaHoseP->readMemQElemPtr; |
if(readMemQElemPtr){ |
readMemQElemPtr->nBytes = *(SInt32*)(&((*connectionH)->asyncCount[cmDataIn])); |
StripEOJs(readMemQElemPtr->buf, &readMemQElemPtr->nBytes); |
if(irdaHoseP->callbacks.finishedRead) |
(irdaHoseP->callbacks.finishedRead)(readMemQElemPtr, err); |
} |
} |
} |
} |
static void commStatusCompletion(ConnHandle connectionH) |
{ |
IrdaHoseRecPtr irdaHoseP; |
OSStatus err; |
if(connectionH){ |
irdaHoseP = (IrdaHoseRecPtr)(*connectionH)->refCon; |
// if there is data waiting to be sent |
if(irdaHoseP && (irdaHoseP->needToDumpDataOut)){ |
irdaHoseP->needToDumpDataOut = false; |
err = CMWrite(connectionH, |
irdaHoseP->writeMemQElemPtr->buf, |
&(irdaHoseP->writeMemQElemPtr->nBytes), |
cmData, |
true, |
MakeProcPtr(commWriteCompletion, ConnectionCompletionUPP), |
-1, |
0); |
} |
} |
} |
static OSStatus requestStatus(IrdaHoseRecPtr irdaHoseP) |
{ |
OSStatus err = noErr; |
ConnHandle connectionH; |
Boolean writePending; |
if((irdaHoseP->connectionState == kConnOpen) && (irdaHoseP->needToRequestStatus)){ |
if((connectionH = irdaHoseP->connectionH) != 0){ |
err = cmWritePending(connectionH, &writePending); |
// CTB does NOT allow multiple writes |
if(!err && !writePending){ |
irdaHoseP->needToRequestStatus = false; |
gOutOne = 1; |
// request status from printer |
err = CMWrite(connectionH, |
&gCntlT, |
&gOutOne, |
cmData, |
true, |
MakeProcPtr(commStatusCompletion, ConnectionCompletionUPP), |
-1, |
0); |
} |
} |
} |
return (err); |
} |
static OSStatus cmWritePending(ConnHandle connectionH, Boolean* writePendingP) |
{ |
OSStatus err; |
CMBufferSizes cmBufSizes; |
CMStatFlags cmFlags; |
*writePendingP = false; |
err = CMStatus(connectionH, |
cmBufSizes, |
&cmFlags); |
// CTB does NOT allow multiple writes |
if(!err && (cmFlags & cmStatusDWPend)) |
*writePendingP = true; |
return (err); |
} |
/* |
translate connection Mgr. errors to something meaningful |
*/ |
static OSErr translateErr(OSErr err) |
{ |
OSErr newErr = err; |
switch(err){ |
case cmNotOpen: |
case readErr: // readErr and writErr should be mapped to 'errIrdaDisconnectedErr' when |
case writErr: // we can supply better error reporting for that error. |
case cmNotClosed: // This should be 'errHoseInUse' when we can supply better error reporting. |
case errIrdaDisconnectedErr: // also make sure that this error is mapped |
newErr = PAPNoPrinter; |
break; |
case errIrdaUnknownOpenErr: |
newErr = errUnableToDoNewIrdaConnection; |
break; |
case cmNoTools: |
newErr = errIrdaToolNotFoundErr; |
break; |
case cmGenericError: |
case cmRejected: |
case cmFailed: |
case cmTimeOut: |
case cmNoRequestPending: |
case cmNotSupported: |
case cmUserCancel: |
case cmUnknownError: |
newErr = errGenericComponentErr; |
break; |
} |
return newErr; |
} |
static void StripEOJs(unsigned char* buffer, SInt32* nBytesP) |
{ |
unsigned char *src, *dst; |
SInt32 count; |
src = dst = buffer; |
count = *nBytesP + 1; // +1 for pre-decrement |
while (--count) |
{ |
if ((*dst++ = *src++) == '\x04') |
{ |
dst--; // Opps, we hit a control-D, backup a character & decrement num bytes |
(*nBytesP)--; |
} |
} |
} |
static OSErr UnLockHint(Collection collection, CollectionTag tag, long id) |
/* If the hint is locked UnLockHint() will unlock it, if |
it is unlocked UnLockHint() will do nothing. |
*/ |
{ |
OSErr err = noErr; |
long attributes; |
err = GetCollectionItemInfo(collection, tag, id, kCollectionDontWantIndex, kCollectionDontWantSize, &attributes); |
if(!err){ |
attributes = attributes & ~kCollectionLockMask; |
err = SetCollectionItemInfo(collection, tag, id, kCollectionLockMask, attributes); |
} |
if(err == collectionItemNotFoundErr) err = noErr; //If it wasn't there that's fine. |
return err; |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-03-26