home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-22 | 63.8 KB | 2,106 lines | [TEXT/MPS ] |
- /*
- File: Clipbd.cpp
-
- Contains: Implementation for ODClipboard class.
-
- Owned by: Craig Carper
-
- Copyright: © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <3> 3/29/96 DM 1296171: suppress fatal Bento container
- errors in all clipboard methods
- <2> 3/26/96 CC 1333462: CloseClipboard: ClearAllPromises
- if not externalizing the clipboard draft.
- <54> 10/9/95 CC 1289794: Avoid calling GetScrap if scrap is
- in an inconsistent state.
- 1288241: SetPlatformClipboard prevents
- exporting clipboard.
- 1290782: Purge is not implemented.
- 1286400: Preflight scrap memory
- allocations.
- <53> 10/3/95 TJ Changes done by RefBall Team
- <52> 9/26/95 EL 1285709: ODClipboard does not close down
- properly if it was never accessed.
- <51> 9/8/95 TÇ 1281096 FB2:Many constants in ODTypesB
- without kOD prefix!
- <50> 8/31/95 DM 1273863, 1275336: add ODClipboard::
- DraftSaved(), make GetOriginalDraft() honor
- standard endianess
- <49> 8/30/95 EL 1279832: Storage THROW_IF_NULL problems.
- <48> 8/29/95 DM 1276549: call parent Purge in ODClipboard
- <47> 8/26/95 TÇ 1274606 FB2: Patching Remarks
- <46> 8/25/95 CC 1264154: Added ActionDone, ActionUndone,
- and ActionRedone methods.
- <45> 8/21/95 VL 1277291: Use GetOriginalCloneKind from
- StorUtil.
- <44> 8/16/95 NP 1274946: ErrorDef.idl problems. Add include
- file.
- <43> 8/12/95 TÇ 1276812 Need to use TempObjs and TempRefs
- for exception safety and to avoid TRY
- blocks, 1276807 Opt./Bug: use StdTypIO
- routines for portable streaming & smaller
- footprint
- <42> 8/3/95 RR #1257260: Collapse B classes. Remove
- somInit methods. Don't call IsInitialized
- or SubclassResponsibility
- <41> 7/26/95 DM #1270320: Memory leak fixes: dispose handle
- on return in ODClipboardImportContent
- <40> 7/20/95 CC 1153954: ExportPlatformTypes: Don't move
- types to scrap that are not platform types.
- 1260342: Clear: fail if process is in the
- background.
- <39> 7/1/95 CC 1264197: DraftClosing must not remove
- Original Draft property. Instead, change
- original clone kind to kODCloneCopy.
- 1257374: Added ForceZeroScrap(), called
- from SetPlatformClipboard() and
- ExportClipboard() methods.
- <38> 6/23/95 CC 1260902: ImportContent: Skip if scrap
- handle is null, and Ignore types of size
- zero.
- 1257374: GetContentStorageUnit: Never issue
- debugger break on failure to import from
- the system scrap.
- <37> 6/19/95 CC 1259079: Added local function
- IsFrontProcess.
- GetContentStorageUnit: Don't warn if
- process is in background.
- <36> 5/26/95 VL 1251403: Multithreading naming support.
- <35> 5/22/95 CC 1251106: CloseClipboard externalizes root
- SU to resolve promises before externalizing
- the clipboard draft.
- <34> 5/18/95 CC 1250280: ShowPasteAsDialog throws on
- invalid null arguments.
- <33> 5/17/95 RR #1250135/1250137/1250143 Getters increment
- refcount
- <32> 5/16/95 CC 1244991: ExportClipboard: Re-export
- clipboard if link spec has been removed.
- ExportClipboard: Set fOriginalDraft field.
- DiscardClipboard: Added SOM_CATCH return.
- <31> 5/5/95 CC 1224474: ImportContent: Fixed memory leak
- due to variable theISOType
- <30> 4/25/95 CC 1242555: PutContentOnPlatformClipboard:
- Removed obsolete $5 comment.
- <29> 4/14/95 TÇ #1235279 BB: InfoUtil & StdTypIO functions
- should take Environment* and SU* when
- possible
- <28> 4/11/95 CC 1231378: DraftClosing: Removed link spec if
- present.
- <27> 3/22/95 CC 1230322: Changed parameter to
- ShowPasteAsDialog().
- <26> 3/10/95 CC 1225050: Added DraftClosing() method.
- 1227468: Clear: Set fScrapCount to ensure a
- changed clipboard is exported again.
- <25> 2/24/95 CC 1222076: BB: Clipboard contents lost on
- error converting to Mac scrap.
- 1184034: BB: Error -108 during
- cross-document paste link.
- 1186774, 1201430, 1218790: Ignore GetScrap
- errors.
- 1223020: ODClipboard calls LoadScrap() at
- innapropriate times.
- Fixed mismatched delimiters: #include
- <ODDebug.h".
- <24> 2/14/95 jpa Added return statement to a SOM_CATCH
- [1215160]
- <23> 2/10/95 CG #1177475: Added include for StdDefs.xh.
- <22> 2/7/95 CC 1211295: Added GetOriginalCloneKind().
- Pass isMove parameter to ShowPasteAsDialog.
- 1216124: ShowPasteAsDialog aquires modal
- focus.
- <21> 2/1/95 CC 1153802: Improvements to
- ImportStyledTextType().
- ImportContent(): Create stxt only if not
- already present.
- <20> 1/26/95 VL #???: Use updated Storage Unit Ref API.
- <19> 1/25/95 CC 1153802 Conversion between 'styl' and
- 'stxt' types: Added ImportStyledTextType
- and ExportStylType functions.
- <18> 1/19/95 CC 1212419 Add parameter to
- GetMemoryContainer.
- 1212833 Change to use
- kODScrapTypeODBentoContainer.
- <17> 12/20/94 VL 1195012: Make Storage calls be
- marshallable.
- <16> 12/8/94 CC 1186774, 1201430 - Suppress errors returned
- when reading the scrap.
- <15> 9/29/94 RA 1189812: Mods for 68K build.
- <14> 9/23/94 VL 1155579, 1184272: Use StorUtil to
- create/get container and get its file.
- <13> 9/19/94 CC 1187315 - somUninit() must call parent
- method last.
- 1160121 - Clear() must not return an error.
- <12> 9/15/94 CC 1186774 - Suppress GetScrap() errors.
- <11> 8/26/94 VL 1183174: Use updated cloning APIs.
- <10> 8/15/94 TÇ #1180922 Removed most obsolete types from
- StdTypes.idl
- <9> 8/3/94 CC Removed Lock() and Unlock(); removed
- ODClipboardKey parameter from other
- methods. (1160484)
- <8> 8/3/94 VL 1153123: Storage to ODStor.
- <7> 8/2/94 CC #1178169 - ShowPasteAsDialog() takes
- ODFacet* instead of ODFrame*.
- <6> 7/31/94 CC Change WASSERTs to WARNs.
- <5> 7/12/94 CC Companion to .idl checkin -- no changes.
- <4> 6/28/94 VL Used Translt.xh.
- <3> 6/24/94 CC Use kODScrapTypePart constant in
- ConstDef.h.
- <2> 6/24/94 CC Fleshed out ShowPasteAsDialog().
- <1> 6/21/94 CC first checked in
-
- ------------------- CC ---- Converted to SOM
-
- <13> 5/9/94 MB Changes necessary to install MMM. Bug
- #1162181.
- <12> 4/4/94 CC SetPlatformClipboard() &
- ExportPlatformClipboard(): Parameter
- changed from XMPTypeSet to XMPTypeList
- (1153046)
- <11> 3/28/94 CG 1153547: Renamed XMPSessn.h to XMPSessM.h
- <10> 3/27/94 TÇ #1153523. Adjust name of
- kXMPPropRootPartSU to more clearly indicate
- what it is supposed to be used for.
- <9> 3/25/94 JA Added missing #include (1147588)
- <8> 3/18/94 CC Added counting locks to Lock() and
- Unlock(); Implementation of and calls to
- ValidateKey(). (1151853)
- <7> 3/16/94 CG #1151186: Added call to InitPlatformTypeSet
- after new XMPPlatformTypeSet.
- <6> 3/2/94 CC Lock() & Unlock(): Commented out erroneous
- WASSERTs. (1145487)
- <5> 2/28/94 VL Changed code that may cause memory
- problems.
- <4> 2/22/94 VL THROW -> THROW_IF_ERROR.
- <3> 2/15/94 CC Bug #1142933 - Added key parameter to
- SetPlatformClipboard.
- <2> 2/15/94 CC Bug #1142949 - Adapted to method name
- changes in XMPPlatformTypeSet.
- <3> 2/8/94 VL Use new exception macros.
- <2> 2/4/94 VL Session.h -> XMPSessn.h.
- <1> 2/4/94 VL first checked in
-
- <21> 2/4/94 VL Moved to PPC Header and began code cleanup.
- <20> 1/28/94 CC Implemented change ids; replaced DebugStrs
- with WASSERTMs.
- <19> 1/21/94 CC Converted from XMPTimeStamp to XMPUpdateID.
- Added GetUpdateID. GetLock() returns
- boolean result and returns key in second
- parameter.
- <18> 1/21/94 CG Renamed kXMPMemoryContainer to
- kXMPDefaultMemoryContainer.
- <17> 1/18/94 CG Added include for StorgDef.yh
- <16> 1/18/94 CC Use kXMPScrapTypePart; release draft
- properties on failure in NewClipboard() and
- ImportClipboard().
- <15> 1/14/94 CC Added type XMPClipboardKey, added key
- parameter to various routines, replaced
- GetGeneration() with GetTimeStamp, renamed
- AcquireStorageUnit() GetContentStorageUnit();
- changed from using a handle to a pointer in
- ExportPlatformTypes() and
- PutContentOnPlatformClipboard().
- <14> 1/11/94 TÇ Init... changes
- <13> 12/21/93 VL Changed XMPStorageUnit::GetValueSize to
- StorageUnit::GetSize.
- <12> 12/15/93 TÇ more InitObject changes, remove
- Initialize() method
- <11> 12/15/93 TÇ InitObject changes
- <10> 12/2/93 CC Added Lock(), Unlock(), and GetGeneration()
- methods.
- <9> 11/10/93 CC Doesn't externalize draft before disposing
- memory container
- <8> 11/1/93 VL Used Strong reference.
- <7> 10/29/93 RR XMPClipboard:: -> XMPMacClipboard
- <6> 10/27/93 CC Added methods to transfer to/from the
- platform clipboard.
- <5> 10/20/93 CC Added session parameter to XMPClipboard
- constructor; added SetPlatformClipboard
- method; added code to create the clipboard
- container.
- <3> 4/29/93 VL More 8.3 Name Change.
- <2> 4/29/93 VL 8.3 Name Change.
- <1> 4/27/93 VL first checked in
-
- To Do:
- • Reuse fContainerHandle when possible after exporting it.
- • Add a resolvePromises parameter to ExportClipboard (but maybe we need to
- do this all the time).
- • Vincent will add a draft change seed. The clipboard object can examine
- the seed for the clipboard draft to determine if the clipboard has
- been changed since it was exported (if the clipboard generation is the
- same).
- • XMPClipboard::Clear() should clear the system clipboard.
-
- In Progress:
-
- */
-
- #define VARIABLE_MACROS
-
- #define ODClipboard_Class_Source
- #include <Clipbd.xih>
-
- #ifndef SOM_Module_OpenDoc_StdDefs_defined
- #include <StdDefs.xh>
- #endif
-
- #ifndef _EXCEPT_
- #include <Except.h>
- #endif
-
- #ifndef _ODMEMORY_
- #include <ODMemory.h>
- #endif
-
- #ifndef _CONSTDEF_
- #include <ConstDef.h>
- #endif
-
- #ifndef _PLFMDEF_
- #include <PlfmDef.h>
- #endif
-
- #ifndef _ISOSTR_
- #include <ISOStr.h>
- #endif
-
- #ifndef _ODUTILS_
- #include <ODUtils.h>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdProps_defined
- #include <StdProps.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdTypes_defined
- #include <StdTypes.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_Foci_defined
- #include <Foci.xh>
- #endif
-
- #ifndef SOM_ODSession_xh
- #include <ODSessn.xh>
- #endif
-
- #ifndef SOM_ODArbitrator_xh
- #include <Arbitrat.xh>
- #endif
-
- #ifndef SOM_ODContainer_xh
- #include <ODCtr.xh>
- #endif
-
- #ifndef SOM_ODDocument_xh
- #include <Document.xh>
- #endif
-
- #ifndef SOM_ODDraft_xh
- #include <Draft.xh>
- #endif
-
- #ifndef SOM_ODStorageSystem_xh
- #include <ODStor.xh>
- #endif
-
- #ifndef SOM_ODStorageUnit_xh
- #include <StorageU.xh>
- #endif
-
- #ifndef SOM_ODTranslation_xh
- #include <Translt.xh>
- #endif
-
- #ifndef SOM_ODTypeList_xh
- #include <TypeList.xh>
- #endif
-
- #ifndef SOM_ODPlatformTypeList_xh
- #include <PfTypLs.xh>
- #endif
-
- #ifndef _LINKDLGS_
- #include <LinkDlgs.h>
- #endif
-
- #ifndef __SCRAP__
- #include <Scrap.h>
- #endif
-
- #ifndef _ODDEBUG_
- #include <ODDebug.h>
- #endif
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef _STDTYPIO_
- #include <StdTypIO.h>
- #endif
-
- #ifndef _TEMPOBJ_
- #include <TempObj.h>
- #endif
-
- #ifndef _STORUTIL_
- #include <StorUtil.h>
- #endif
-
- #ifndef _UTILERRS_
- #include "UtilErrs.h"
- #endif
-
- #ifndef __TEXTEDIT__
- #include <TextEdit.h> // for ScrpSTElement
- #endif
-
- #pragma segment ODClipboard
-
- #include "ClipbdB.cpp" // Platform-independent methods, if any
-
- #if ODDebug
- #define ODDebugClipboard 0
- #undef _REPORT_SCRAP_ERRORS_
- #else
- #define ODDebugClipboard 0
- #undef _REPORT_SCRAP_ERRORS_
- #endif
-
- //==============================================================================
- // Constants
- //==============================================================================
-
- const short kInvalidScrapCount = -1; // Must never match the scrap count!
-
- // Mac Scrap state constants
- const short kUninitializedScrap = -1;
- const short kScrapOnDisk = 0;
-
- //==============================================================================
- // Function Prototypes
- //==============================================================================
-
- ODStatic ODULong ApplicationHeapFree();
- ODStatic short GetMacScrapCount();
- ODStatic ODBoolean IsFrontProcess();
- ODStatic void ImportStyledTextType(ODClipboard *somSelf, Environment *ev);
- ODStatic OSErr ExportStylType(ODPtr stxtData);
- ODStatic void CloseClipboard(ODClipboard *somSelf, Environment *ev, ODBoolean externalize);
- ODStatic void OpenClipboard(ODClipboard *somSelf, Environment *ev);
- ODStatic ODBoolean ScrapIsInconsistent();
- ODStatic ODBoolean ScrapHasData();
- ODStatic ODBoolean ScrapHasType(ODPlatformType type);
- ODStatic OSErr ForceZeroScrap();
- ODStatic ODBoolean ScrapMemoryAvailable(Size dataSize);
- ODStatic OSErr UnloadScrapIfMemLow(Size dataSize);
- ODStatic OSErr ClipboardLoadScrap();
- ODStatic OSErr ClipboardPutScrap(Size dataSize, ODPlatformType platformType, ODPtr data);
-
- //==============================================================================
- // Utility Functions
- //==============================================================================
-
- //------------------------------------------------------------------------------
- // SetOriginalCloneKind
- //------------------------------------------------------------------------------
-
- static void SetOriginalCloneKind(Environment* ev, ODDraft* draft, ODCloneKind cloneKind)
- {
- if ( draft != kODNULL )
- {
- TempODStorageUnit draftProperties = draft->AcquireDraftProperties(ev);
- ODSetULongProp(ev, draftProperties, kODPropOriginalCloneKind, kODULong, (ODULong)cloneKind);
- }
- }
-
- //------------------------------------------------------------------------------
- // GetOriginalDraft
- //------------------------------------------------------------------------------
- // Returns kODNULL if the original draft is unknown. This is the case when content
- // was placed in the draft without cloning.
-
- static ODDraft* GetOriginalDraft(Environment* ev, ODDraft* draft)
- {
- TempODStorageUnit draftProperties = draft->AcquireDraftProperties(ev);
- return (ODDraft*)ODGetULongProp(ev, draftProperties, kODPropOriginalDraft, kODULong);
- }
-
- //==============================================================================
- // ODClipboard
- //==============================================================================
-
- extern ODBoolean gODSuppressBentoFatalError; // defined in SessHdr.cpp
-
- //------------------------------------------------------------------------------
- // ODClipboard::somUninit
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK ODClipboardsomUninit(ODClipboard *somSelf)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
- ODClipboardMethodDebug("ODClipboard","somUninit");
-
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- Environment *ev = somGetGlobalEnvironment();
- // somSelf->DiscardClipboard(ev);
- // It is incorrect to call methods on somSelf inside somUninit,
- // a subclass may have already been somUninited. See OpenDoc Building Code for details.
- // Instead the implementation of DiscardClipboard has been copied here.
-
- // BEGIN copy of DiscardClipboard implementation
- CloseClipboard(somSelf, ev, kODFalse);
-
- ODDisposeHandle(_fContainerHandle);
- _fContainerHandle = (ODHandle) kODNULL;
- // END copy of DiscardClipboard implementation
-
- parent_somUninit(somSelf);
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
- }
-
- //------------------------------------------------------------------------------
- // ODClipboard::InitClipboard
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK ODClipboardInitClipboard(ODClipboard *somSelf, Environment *ev,
- ODSession* session)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
- ODClipboardMethodDebug("ODClipboard","InitClipboard");
-
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- /* Moved from somInit. SOM itself sets fields to zero
- _fSession = (ODSession*) kODNULL;
- _fContainerHandle = (ODHandle) kODNULL;
- _fContainer = (ODContainer*) kODNULL;
- _fDocument = (ODDocument*) kODNULL;
- _fDraft = (ODDraft*) kODNULL;
- _fSU = (ODStorageUnit*) kODNULL;
-
- _fOriginalDraft = (ODDraft*) kODNULL;
- _fExportedLinkSpec = kODFalse;
-
- _fClonePasteCount = 0;
- */
- somSelf->InitObject(ev);
-
- _fSession = session;
-
- // Initialize our scrap count to an invalid value so a paste will force copying
- // from the platform scrap.
- _fScrapCount = kInvalidScrapCount;
- _fScrapCountLastChange = kInvalidScrapCount;
-
- _fUpdateID = kODUnknownUpdate;
- _fNextUpdateID = _fSession->UniqueUpdateID(ev);
-
- _fOriginalCloneKind = kODCloneCopy;
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
- }
-
- //------------------------------------------------------------------------------
- // ApplicationHeapFree
- //------------------------------------------------------------------------------
-
- ODStatic ODULong ApplicationHeapFree()
- {
- ODULong free;
- THz curZone = GetZone();
- SetZone(ApplicationZone());
- free = FreeMem();
- SetZone(curZone);
- return free;
- }
-
- //------------------------------------------------------------------------------
- // ODClipboard::Purge (OVERRIDE)
- //------------------------------------------------------------------------------
-
- SOM_Scope ODSize SOMLINK ODClipboardPurge(ODClipboard *somSelf, Environment *ev,
- ODSize size)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
- ODClipboardMethodDebug("ODClipboard","Purge");
-
- ODSize freed = 0;
- ODVolatile(freed);
-
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- SOM_TRY
-
- Size scrapSize = InfoScrap()->scrapSize;
- short scrapCount = GetMacScrapCount();
-
- if ( InfoScrap()->scrapState > kScrapOnDisk )
- {
- freed += scrapSize;
- if ( (scrapCount == _fScrapCountLastChange) && (scrapCount == _fScrapCount) )
- {
- ForceZeroScrap();
- // Update scrap later
- _fScrapCountLastChange = _fScrapCount = GetMacScrapCount();
-
- #if ODDebugClipboard
- PRINT("ODClipboard::Purge: Scrap cleared\n");
- #endif
- }
- else
- {
- UnloadScrap();
-
- #if ODDebugClipboard
- if ( InfoScrap()->scrapState > kScrapOnDisk )
- PRINT("ODClipboard::Purge: Scrap unloaded\n");
- #endif
- }
- #if ODDebugClipboard
- PRINT("ODClipboard::Purge: Freed %ld bytes in app heap\n", freed);
- #endif
- }
-
- freed += parent_Purge(somSelf, ev, size); // always call parent version of Purge()
-
- SOM_CATCH_ALL
- WARN("Error %ld trying to purge in ODClipboardPurge",ErrorCode());
- SetErrorCode(kODNoError); // Eat the exception; Purge should not
- // propagate it because clients function
- // fine whether memory was purged or not.
- SOM_ENDTRY
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
-
- return freed;
- }
-
- //------------------------------------------------------------------------------
- // ODClipboard::NewClipboard
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK ODClipboardNewClipboard(ODClipboard *somSelf, Environment *ev)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
- ODClipboardMethodDebug("ODClipboard","NewClipboard");
-
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- SOM_CATCH
- {
- gODSuppressBentoFatalError = oldSuppress; // neutral
- return;
- }
-
- ODStorageUnit* draftProperties = (ODStorageUnit*) kODNULL;
-
- ODVolatile(draftProperties);
- ODVolatile(somSelf);
- ODVolatile(ev);
-
- TRY
- // Create a new clipboard in-memory container
- _fContainerHandle = ODNewHandle(0);
- _fContainer = CreateMemoryContainer(ev, _fSession, _fContainerHandle, kODBentoMemoryContainer);
-
- // Create the root content storage unit
- _fDocument = _fContainer->AcquireDocument(ev, kODDefaultDocument);
- _fDraft = _fDocument->AcquireBaseDraft(ev, kODDPExclusiveWrite);
- _fSU = _fDraft->CreateStorageUnit(ev);
-
- // Store a reference to the content storage unit in the draft properties
- draftProperties = _fDraft->AcquireDraftProperties(ev);
- ODSetStrongSURefProp(ev, draftProperties, kODPropRootPartSU, kODStrongStorageUnitRef, _fSU->GetID(ev));
- draftProperties->Release(ev);
-
- CATCH_ALL
- #ifdef _REPORT_SCRAP_ERRORS_
- WARN("ODClipboard: Cannot create clipboard - error %ld",ErrorCode());
- #endif
- somSelf->DiscardClipboard(ev);
- ODReleaseObject(ev, draftProperties);
- RERAISE;
- ENDTRY
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
- }
-
- //------------------------------------------------------------------------------
- // CloseClipboard
- //------------------------------------------------------------------------------
- // Close the current clipboard container, without disposing of the container handle.
- // Note: CloseClipboard must not make any method calls to somSelf, since
- // CloseClipboard is called from the somUninit method.
-
- ODStatic void CloseClipboard(ODClipboard *somSelf, Environment *ev, ODBoolean externalize)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
-
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- // If the draft must be externalized, first externalize the root storage unit
- // to resolve promises. Otherwise, externalizing the draft may fail with an
- // iterator-out-of-sync error because resolving promises may add storage units
- // to the draft's collection during iteration. In theory, the only promises
- // should be in the root storage unit, so explicitly externalize it first to
- // resolve promises before interating over all storage units.
-
- if ( _fSU != kODNULL )
- {
- if ( externalize )
- _fSU->Externalize(ev);
- else
- _fSU->ClearAllPromises(ev);
- }
-
- if ( (_fDraft != kODNULL) && externalize )
- {
- _fDraft->Externalize(ev);
- }
-
- ODReleaseObject(ev,_fSU);
- ODReleaseObject(ev,_fDraft);
- ODReleaseObject(ev,_fDocument);
- ODReleaseObject(ev,_fContainer);
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
- }
-
- //------------------------------------------------------------------------------
- // ODClipboard::DiscardClipboard
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK ODClipboardDiscardClipboard(ODClipboard *somSelf, Environment *ev)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
- ODClipboardMethodDebug("ODClipboard","DiscardClipboard");
-
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- SOM_CATCH
- {
- gODSuppressBentoFatalError = oldSuppress; // neutral
- return;
- }
-
- CloseClipboard(somSelf, ev, kODFalse);
-
- ODDisposeHandle(_fContainerHandle);
- _fContainerHandle = (ODHandle) kODNULL;
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
- }
-
- //------------------------------------------------------------------------------
- // ODClipboard::ImportContent
- //------------------------------------------------------------------------------
- //
- // On entry, assumes the scrap has already been checked for consistency.
- // Returns an exception if the scrap can't be loaded into memory.
-
- SOM_Scope void SOMLINK ODClipboardImportContent(ODClipboard *somSelf, Environment *ev)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
- ODClipboardMethodDebug("ODClipboard","ImportContent");
-
- ODHandle hData = kODNULL;
- long scrapOffset = 0;
-
- ODVolatile(hData);
-
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- SOM_TRY
-
- hData = ODNewHandle(0);
-
- // Because we walk the scrap, it must be loaded in memory.
- THROW_IF_ERROR(ClipboardLoadScrap());
-
- PScrapStuff myScrapStuff = InfoScrap();
- Handle hScrap = myScrapStuff->scrapHandle;
-
- while ( scrapOffset < myScrapStuff->scrapSize )
- {
- long scrapTypeLength;
- ResType theType;
- ODULong realOffset;
-
- // There is more in the scrap
- theType = *(ResTypePtr)(((long) *hScrap) + scrapOffset);
- scrapTypeLength = GetScrap((Handle) hData, theType, (long*) &realOffset);
- if ( scrapTypeLength < 0 )
- THROW(scrapTypeLength);
-
- if ( realOffset < scrapOffset )
- {
- // We tried to read a second occurance of the same resource type
- // on the scrap. Since the result of GetScrap is the length
- // of the first occurance, we can't read the scrap past this point.
- // So just quit.
- #ifdef _REPORT_SCRAP_ERRORS_
- PRINT("ODClipboard: ImportContent: Duplicate resource on scrap, type = \'%.4s\'\n", &theType);
- #endif
- break;
- }
-
- #if ODDebugClipboard
- PRINT("Found scrap type \'%.4s\'\n", &theType);
- #endif
- if ( scrapTypeLength > 0 )
- {
- #ifdef _REPORT_SCRAP_ERRORS_
- if ( theType == kODScrapTypeODBentoContainer )
- {
- // Internal error
- WARN("ODClipboard: ImportContent: Reading BentoContainer as scrap type!");
- }
- #endif
- // Special case: If 'styl' is present, create an 'stxt' if one
- // isn't also on the scrap
- if ( theType == 'styl' )
- {
- long dummy;
- if ( GetScrap(nil, 'stxt', &dummy) == noTypeErr )
- ImportStyledTextType(somSelf, ev);
- }
-
- TempODType theISOType = kODNULL;
- theISOType = _fSession->GetTranslation(ev)->GetISOTypeFromPlatformType(ev, theType, kODPlatformDataType);
-
- if ( theISOType != (ODType) kODNULL )
- {
- if ( ODSUExistsThenFocus(ev, _fSU, kODPropContents, (ODType) theISOType) )
- {
- WARN("ODClipboard: Replacing value on clipboard");
- _fSU->Remove(ev);
- }
- ODSUForceFocus(ev, _fSU, kODPropContents, (ODType) theISOType);
- ODValue pData = ODLockHandle(hData);
- StorageUnitSetValue(_fSU, ev, (ODULong) scrapTypeLength, pData);
- ODUnlockHandle(hData);
- }
- }
-
- // The length must be EVEN!
- if (scrapTypeLength & 1)
- {
- scrapTypeLength += 1;
- }
- scrapOffset = realOffset + scrapTypeLength;
- }
-
- SOM_CATCH_ALL
-
- #ifdef _REPORT_SCRAP_ERRORS_
- WARN("ODClipboard: ImportContent: Failed with error %ld",ErrorCode());
- #endif
- if ( ErrorCode() == memFullErr )
- SetErrorCode(kODErrOutOfMemory);
-
- SOM_ENDTRY
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
-
- ODDisposeHandle(hData);
- }
-
- //------------------------------------------------------------------------------
- // ODClipboard::PutContentOnPlatformClipboard
- //------------------------------------------------------------------------------
- //
- // Copy values with corresponding platform types onto the desk scrap.
- // THROWs an exception if any error occurs, which may cause the desk scrap to
- // be only partially updated. The desk scrap requires copying the data in one chunk.
-
- SOM_Scope void SOMLINK ODClipboardPutContentOnPlatformClipboard(ODClipboard *somSelf, Environment *ev)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
- ODClipboardMethodDebug("ODClipboard","PutContentOnPlatformClipboard");
-
- ODULong count;
- ODULong index;
- ODPlatformType platformType;
-
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- SOM_TRY
-
- if ( (_fSU == kODNULL) && (_fContainerHandle != kODNULL) )
- OpenClipboard(somSelf, ev);
-
- if ( _fSU )
- {
- _fSU->Focus(ev, kODPropContents, kODPosUndefined, 0, 0, kODPosUndefined);
- count = _fSU->CountValues(ev);
- for (index = 1; index <= count; ++index)
- {
- _fSU->Focus(ev, kODPropContents, kODPosUndefined, 0, index, kODPosUndefined);
- TempODType theISOType = _fSU->GetType(ev);
- platformType = _fSession->GetTranslation(ev)->GetPlatformTypeFromISOType(ev, (ODType) theISOType);
- if (platformType != (ODPlatformType) kODNULL)
- {
- _fSU->Focus(ev, kODPropContents, kODPosUndefined, (ODType) theISOType, 0, kODPosUndefined);
- Size dataSize = _fSU->GetSize(ev);
-
- TempODPtr data = kODNULL;
- data = ODNewPtr(dataSize, kDefaultHeapID);
-
- StorageUnitGetValue(_fSU, ev, dataSize, (ODValue) data);
-
- THROW_IF_ERROR(ClipboardPutScrap(dataSize, platformType, data));
-
- // If styled text ('stxt') was just written to the scrap, also write
- // 'stly' if a 'TEXT' representation will also be written.
- if ( platformType == 'stxt' )
- if ( _fSU->Exists(ev, kODPropContents, kODAppleTEXT, 0) )
- if ( !_fSU->Exists(ev, kODPropContents, kODApplestyl, 0) )
- THROW_IF_ERROR(ExportStylType(data));
- }
- }
- }
-
- SOM_CATCH_ALL
-
- SOM_ENDTRY
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
- }
-
- //------------------------------------------------------------------------------
- // ODClipboard::ExportPlatformTypes
- //------------------------------------------------------------------------------
- //
- // Export data of the argument platform types to the host clipboard.
- // Since only one ISO type corresponds directly to a platform type (no translation
- // is attempted), we just examine each value on the clipboard and check if
- // its platform equivalent is present in the argument set.
-
-
- SOM_Scope void SOMLINK ODClipboardExportPlatformTypes(ODClipboard *somSelf, Environment *ev,
- ODPlatformTypeList* typeList)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
- ODClipboardMethodDebug("ODClipboard","ExportPlatformTypes");
-
- ODULong countOfValues;
- ODULong index;
- ODULong countToExport;
-
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- SOM_TRY
-
- if ( (_fSU == kODNULL) && (_fContainerHandle != kODNULL) )
- OpenClipboard(somSelf, ev);
-
- if ( _fSU )
- {
- _fSU->Focus(ev, kODPropContents, kODPosUndefined, 0, 0, kODPosUndefined);
- countOfValues = _fSU->CountValues(ev);
- if (typeList != (ODPlatformTypeList*) kODNULL)
- countToExport = typeList->Count(ev);
- else
- countToExport = countOfValues;
-
- for (index = 1; (index <= countOfValues) && (countToExport > 0); ++index)
- {
- _fSU->Focus(ev, kODPropContents, kODPosUndefined, 0, index, kODPosUndefined);
- TempODType theISOType = _fSU->GetType(ev);
-
- ODPlatformType platformType =
- _fSession->GetTranslation(ev)->GetPlatformTypeFromISOType(ev, (ODType) theISOType);
- if ( platformType != (ODPlatformType) 0 )
- {
- if ((typeList == (ODPlatformTypeList*) kODNULL) || (typeList->Contains(ev, platformType)))
- {
- _fSU->Focus(ev, kODPropContents, kODPosUndefined, (ODType) theISOType, 0, kODPosUndefined);
- Size dataSize = _fSU->GetSize(ev);
-
- TempODPtr data = kODNULL;
- data = ODNewPtr(dataSize, kDefaultHeapID);
-
- StorageUnitGetValue(_fSU, ev, dataSize, (ODValue) data);
-
- THROW_IF_ERROR(ClipboardPutScrap(dataSize, platformType, data));
-
- if (typeList != (ODPlatformTypeList*) kODNULL)
- typeList->Remove(ev, platformType);
- countToExport -= 1;
- }
- }
- }
- }
-
- SOM_CATCH_ALL
-
- if ( ErrorCode() == memFullErr )
- SetErrorCode(kODErrOutOfMemory);
-
- SOM_ENDTRY
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
- }
-
- //------------------------------------------------------------------------------
- // OpenClipboard
- //------------------------------------------------------------------------------
-
- ODStatic void OpenClipboard(ODClipboard *somSelf, Environment *ev)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
-
- ODStorageUnitID suID;
-
- ODVolatile(somSelf);
- ODVolatile(ev);
-
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- if ( _fContainerHandle )
- {
- TRY
- _fContainer = GetMemoryContainer(ev, _fSession, _fContainerHandle, kODBentoMemoryContainer);
- _fDocument = _fContainer->AcquireDocument(ev, kODDefaultDocument);
- _fDraft = _fDocument->AcquireBaseDraft(ev, kODDPExclusiveWrite);
-
- { TempODStorageUnit draftProperties = _fDraft->AcquireDraftProperties(ev);
- suID = ODGetStrongSURefProp(ev, draftProperties, kODPropRootPartSU, kODStrongStorageUnitRef);
- }
-
- _fSU = _fDraft->AcquireStorageUnit(ev, suID);
- CATCH_ALL
- CloseClipboard(somSelf, ev, kODFalse);
- RERAISE;
- ENDTRY
- }
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
- }
-
- //------------------------------------------------------------------------------
- // ODClipboard::PutClipboardOnPlatformClipboard
- //------------------------------------------------------------------------------
- //
- // This method has the side effect of closing the clipboard container.
- // Also note that by externalizing the clipboard draft, all promises are resolved.
-
- SOM_Scope void SOMLINK ODClipboardPutClipboardOnPlatformClipboard(ODClipboard *somSelf, Environment *ev)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
- ODClipboardMethodDebug("ODClipboard","PutClipboardOnPlatformClipboard");
-
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- SOM_TRY
-
- // Externalize then close the clipboard container
- CloseClipboard(somSelf, ev, kODTrue);
-
- if ( _fContainerHandle )
- {
- OSErr error;
- Size dataSize;
- char flags;
-
- dataSize = ODGetHandleSize(_fContainerHandle);
-
- THROW_IF_ERROR(UnloadScrapIfMemLow(dataSize));
-
- flags = HGetState((Handle) _fContainerHandle);
- Ptr containerPtr = (Ptr) ODLockHandle(_fContainerHandle);
- error = (OSErr) PutScrap(dataSize, kODScrapTypeODBentoContainer, containerPtr);
- HSetState((Handle) _fContainerHandle, flags);
-
- #ifdef _REPORT_SCRAP_ERRORS_
- WASSERTM(error == noErr, "ODClipboard: PutScrap() failed");
- #endif
- THROW_IF_ERROR(error);
- }
- #ifdef _REPORT_SCRAP_ERRORS_
- else
- {
- // Internal error
- WARN("ODClipboard: PutClipboardOnPlatformClipboard: No Clipboard to export!\n");
- }
- #endif
-
- SOM_CATCH_ALL
-
- #ifdef _REPORT_SCRAP_ERRORS_
- WARN("ODClipboard: PutClipboardOnPlatformClipboard: Raising exception %d\n", ErrorCode());
- #endif
-
- SOM_ENDTRY
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
- }
-
- //------------------------------------------------------------------------------
- // ODClipboard::ImportClipboard
- //------------------------------------------------------------------------------
- //
- // A bento memory container is always used for data interchange.
- // If OpenClipboard throws, its probably because a bad resource of type
- // kODScrapTypeODBentoContainer was found on the clipboard (currently error 1012,
- // but it may change and there may be others).
- // This routine returns:
- // kODFalse, if the platform clipboard does not contain an OpenDoc clipboard;
- // kODTrue, if an OpenDoc clipboard is successfully imported;
- // an exception if an OpenDoc clipboard could not be imported
-
- SOM_Scope ODBoolean SOMLINK ODClipboardImportClipboard(ODClipboard *somSelf, Environment *ev)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
- ODClipboardMethodDebug("ODClipboard","ImportClipboard");
-
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- SOM_CATCH
- {
- gODSuppressBentoFatalError = oldSuppress; // neutral
- return kODFalse;
- }
-
- ODHandle hData = kODNULL;
- Size dataSize;
- long dummy;
-
- WASSERTM(_fContainerHandle == (ODHandle) kODNULL, "ODClipboard: fContainerHandle not null");
- WASSERTM(_fContainer == (ODContainer*) kODNULL, "ODClipboard: fContainer not null");
- WASSERTM(_fDocument == (ODDocument*) kODNULL, "ODClipboard: fDocument not null");
- WASSERTM(_fDraft == (ODDraft*) kODNULL, "ODClipboard: fDraft not null");
- WASSERTM(_fSU == (ODStorageUnit*) kODNULL, "ODClipboard: fSU not null");
-
- if ( !ScrapHasType(kODScrapTypeODBentoContainer) )
- return kODFalse;
-
- ODVolatile(hData);
-
- TRY
- hData = ODNewHandle(0);
-
- dataSize = GetScrap((Handle) hData, kODScrapTypeODBentoContainer, &dummy);
- if ( dataSize < 0 )
- {
- if ( dataSize == memFullErr )
- THROW(kODErrOutOfMemory);
- else
- THROW(dataSize);
- }
-
- _fContainerHandle = hData;
-
- OpenClipboard(somSelf, ev);
- CATCH_ALL
- #ifdef _REPORT_SCRAP_ERRORS_
- WARN("ODClipboard: Cannot import clipboard - error %ld",ErrorCode());
- #endif
- _fContainerHandle = kODNULL;
- ODDisposeHandle(hData);
- RERAISE;
- ENDTRY
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
-
- return kODTrue;
- }
-
- //------------------------------------------------------------------------------
- // ODClipboard::GetUpdateID
- //------------------------------------------------------------------------------
-
- SOM_Scope ODUpdateID SOMLINK ODClipboardGetUpdateID(ODClipboard *somSelf, Environment *ev)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
- ODClipboardMethodDebug("ODClipboard","GetUpdateID");
-
- short curScrapCount = GetMacScrapCount();
-
- // If the desk scrap has not changed since we last imported it,
- // or if the desk scrap has not changed since the last change to this clipboard,
- // return the current change id, otherwise, return the next change id.
- // Note that this routine will return the same "next" change id
- // even if the desk scrap has changed since the last call to this routine.
- if (curScrapCount == _fScrapCount)
- return _fUpdateID;
- else if (curScrapCount == _fScrapCountLastChange)
- return _fUpdateID;
- else
- return _fNextUpdateID;
- }
-
- //------------------------------------------------------------------------------
- // ODClipboard::Clear
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK ODClipboardClear(ODClipboard *somSelf, Environment *ev)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
- ODClipboardMethodDebug("ODClipboard","Clear");
-
- #if ODDebugClipboard
- PRINT("ODClipboard::Clear \n");
- #endif
-
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- if ( !IsFrontProcess() )
- {
- ODSetSOMException(ev, kODErrBackgroundClipboardClear);
- return;
- }
-
- // Unless called when the process is in the background,
- // don't return an error so this method can be called in a failure handler.
- FN_CATCH
- {
- gODSuppressBentoFatalError = oldSuppress; // neutral
- return;
- }
-
- #if ODDebugClipboard
- if ( (_fSU != (ODStorageUnit*) kODNULL) && (_fSU->GetRefCount(ev) != 1) )
- PRINT("ODClipboard::Clear - Storage unit refCount = %d\n", _fSU->GetRefCount(ev));
- #endif
-
- somSelf->DiscardClipboard(ev);
-
- _fUpdateID = _fNextUpdateID;
- _fNextUpdateID = _fSession->UniqueUpdateID(ev);
-
- #if ODDebugClipboard
- PRINT("ODClipboard::Clear _fOriginalDraft = kODNULL\n");
- #endif
-
- _fOriginalDraft = kODNULL;
- _fOriginalCloneKind = kODCloneCopy;
- _fClonePasteCount = 0;
-
- // Remember to export to desk scrap
- _fScrapCountLastChange = _fScrapCount = GetMacScrapCount();
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
- }
-
- //------------------------------------------------------------------------------
- // ODClipboard::GetContentStorageUnit
- //------------------------------------------------------------------------------
- //
- // If importing from the host clipboard fails, this method returns a new, empty
- // storage unit. No alert is displayed to inform the user. This method will
- // retry importing until Clear() is called. An exception is returned only if
- // an empty clipboard cannot be created.
- //
- // If this routine is called when the process is in the background, GetScrap()
- // will probably return memFullError. Even if it did return scrap data, the
- // data would not be reliable because the forground application might be keeping
- // the true clipboard data in a private scrap. So rather than returning a scrap
- // error, just return an empty clipboard.
-
- SOM_Scope ODStorageUnit* SOMLINK ODClipboardGetContentStorageUnit(ODClipboard *somSelf, Environment *ev)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
- ODClipboardMethodDebug("ODClipboard","GetContentStorageUnit");
-
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- SOM_CATCH
- {
- gODSuppressBentoFatalError = oldSuppress; // neutral
- #ifdef _REPORT_SCRAP_ERRORS_
- WARN("ODClipboard: GetContentStorageUnit: Raising exception %d\n", ErrorCode());
- #endif
- return kODNULL;
- }
-
- ODVolatile(somSelf);
- ODVolatile(ev);
-
- short curScrapCount = GetMacScrapCount();
-
- #if ODDebugClipboard
- if ( (_fSU != (ODStorageUnit*) kODNULL) && (_fSU->GetRefCount(ev) != 1) )
- PRINT("ODClipboard::GetContentStorageUnit - Storage unit refCount = %d\n", _fSU->GetRefCount(ev));
- #endif
-
- // _fScrapCount is the platform scrap count that was last imported or in effect when the clipboard changed.
- // If "curScrapCount == _fScrapCount", the platform scrap has not changed since it was last imported.
- // _fScrapCountLastChange is the platform scrap count at the time the OpenDoc clipboard last changed.
- // If "curScrapCount == _fScrapCountLastChange", the platform scrap has not changed since the
- // OpenDoc clipboard last changed.
-
- if ( (curScrapCount != _fScrapCount) && (curScrapCount != _fScrapCountLastChange) )
- {
- // Import from desk scrap into the OpenDoc clipboard
- #if ODDebugClipboard
- PRINT("ODClipboard: GetContentStorageUnit: Updating clipboard from scrap\n");
- #endif
-
- somSelf->DiscardClipboard(ev);
-
- TRY
- if ( ScrapHasData() )
- {
- if ( !somSelf->ImportClipboard(ev) )
- {
- somSelf->NewClipboard(ev);
- somSelf->ImportContent(ev);
- }
- }
- else
- {
- somSelf->NewClipboard(ev);
- }
- _fScrapCount = curScrapCount;
- _fUpdateID = _fNextUpdateID;
- _fNextUpdateID = _fSession->UniqueUpdateID(ev);
- CATCH_ALL
- #ifdef _REPORT_SCRAP_ERRORS_
- if ( IsFrontProcess() )
- WARN("ODClipboard: GetContentStorageUnit: Importing from desk scrap raised exception %d\n", ErrorCode());
- #endif
- // Importing an OpenDoc clipboard, content, or NewClibpard failed;
- // just create a new, empty clipboard
- somSelf->DiscardClipboard(ev);
- somSelf->NewClipboard(ev);
- ENDTRY
- _fOriginalDraft = kODNULL;
- _fOriginalCloneKind = kODCloneCopy;
- _fClonePasteCount = 0;
- }
- else if ( _fContainerHandle == (ODHandle) kODNULL )
- {
- // Open a new clipboard container if a container handle doesn't exist
- // This case can only happen after an error or after Clear() is called
- somSelf->NewClipboard(ev);
- _fOriginalDraft = kODNULL;
- _fOriginalCloneKind = kODCloneCopy;
- _fClonePasteCount = 0;
- }
- else
- {
- // reopen the container handle if necessary.
- if ( _fContainer == kODNULL )
- OpenClipboard(somSelf, ev);
- if ( _fOriginalDraft == kODNULL )
- _fOriginalDraft = GetOriginalDraft(ev, _fDraft);
- }
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
-
- return _fSU;
- }
-
- //------------------------------------------------------------------------------
- // ODClipboard::ActionDone
- //------------------------------------------------------------------------------
-
- SOM_Scope ODUpdateID SOMLINK ODClipboardActionDone(ODClipboard *somSelf, Environment *ev,
- ODCloneKind cloneKind)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
- ODClipboardMethodDebug("ODClipboard","ActionDone");
-
- ODUpdateID update = kODUnknownUpdate;
-
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- SOM_TRY
-
- // Note that if the clipboard is changed by one OpenDoc document,
- // and used (via Paste) in another, the sequence of undo, redo,
- // and paste actions is separate in each document. That is, the
- // first document is unaware of the Paste in the second document.
- // This isn't semantically correct, but doesn't cause errors [cc].
-
- if ( (cloneKind == kODCloneCut) || (cloneKind == kODCloneCopy) )
- {
- _fOriginalCloneKind = cloneKind;
- _fClonePasteCount = 0;
- }
- else if ( cloneKind == kODClonePaste )
- {
- _fClonePasteCount += 1;
- }
- else
- THROW(kODErrIllegalClipboardCloneKind);
-
- update = _fUpdateID;
-
- SOM_CATCH_ALL
-
- SOM_ENDTRY
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
-
- return update;
- }
-
- //------------------------------------------------------------------------------
- // ODClipboard::ActionUndone
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK ODClipboardActionUndone(ODClipboard *somSelf, Environment *ev,
- ODUpdateID update,
- ODCloneKind originalCloneKind)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
- ODClipboardMethodDebug("ODClipboard","ActionUndone");
-
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- SOM_TRY
-
- if ( update == _fUpdateID )
- {
- if ( originalCloneKind == kODCloneCut )
- {
- SetOriginalCloneKind(ev, _fDraft, kODCloneCopy);
- }
- else if ( originalCloneKind == kODClonePaste )
- {
- _fClonePasteCount -= 1;
- if ( (_fClonePasteCount == 0) && (_fOriginalCloneKind == kODCloneCut) )
- SetOriginalCloneKind(ev, _fDraft, kODCloneCut);
- }
- else if ( originalCloneKind != kODCloneCopy )
- THROW(kODErrIllegalClipboardCloneKind);
- }
-
- SOM_CATCH_ALL
-
- SOM_ENDTRY
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
- }
-
- //------------------------------------------------------------------------------
- // ODClipboard::ActionRedone
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK ODClipboardActionRedone(ODClipboard *somSelf, Environment *ev,
- ODUpdateID update,
- ODCloneKind originalCloneKind)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
- ODClipboardMethodDebug("ODClipboard","ActionRedone");
-
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- SOM_TRY
-
- if ( update == _fUpdateID )
- {
- if ( originalCloneKind == kODCloneCut )
- {
- SetOriginalCloneKind(ev, _fDraft, kODCloneCut);
- }
- else if ( originalCloneKind == kODClonePaste )
- {
- _fClonePasteCount += 1;
- if ( (_fClonePasteCount == 1) )
- SetOriginalCloneKind(ev, _fDraft, kODCloneCopy);
- }
- else if ( originalCloneKind != kODCloneCopy )
- THROW(kODErrIllegalClipboardCloneKind);
- }
-
- SOM_CATCH_ALL
-
- SOM_ENDTRY
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
- }
-
- //------------------------------------------------------------------------------
- // ODClipboard::SetPlatformClipboard
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK ODClipboardSetPlatformClipboard(ODClipboard *somSelf, Environment *ev,
- ODPlatformTypeList* typeList)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
- ODClipboardMethodDebug("ODClipboard","SetPlatformClipboard");
-
- ODPlatformTypeList* requestedTypes = (ODPlatformTypeList*) kODNULL;
- ODVolatile(requestedTypes);
-
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- short scrapCount = GetMacScrapCount();
-
- if ( (scrapCount == _fScrapCountLastChange) && (scrapCount == _fScrapCount) )
- {
- SOM_TRY
-
- THROW_IF_ERROR(ForceZeroScrap());
-
- if ( _fSU != (ODStorageUnit*) kODNULL )
- {
- if ( typeList )
- requestedTypes = _fSession->GetStorageSystem(ev)->CreatePlatformTypeList(ev, typeList);
-
- TRY
- somSelf->ExportPlatformTypes(ev, requestedTypes);
- CATCH_ALL
- ZeroScrap();
- RERAISE;
- ENDTRY
- }
-
- SOM_CATCH_ALL
-
- SOM_ENDTRY
-
- if ( requestedTypes )
- delete requestedTypes;
-
- // Since the scrap has only been partially updated, or an error has
- // occurred, we still need to remember to transfer everything later [cc]
- _fScrapCountLastChange = _fScrapCount = GetMacScrapCount();
- }
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
- }
-
- //------------------------------------------------------------------------------
- // ODClipboard::ExportClipboard
- //------------------------------------------------------------------------------
- //
- // Returns a SOM exception if setting the platform clipboard fails.
- // Unfortunately, until the clipboard container is closed its size isn't known.
-
- SOM_Scope void SOMLINK ODClipboardExportClipboard(ODClipboard *somSelf, Environment *ev)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
- ODClipboardMethodDebug("ODClipboard","ExportClipboard");
-
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- SOM_TRY
-
- // If this clipboard was the last change to the platform scrap ("count == _fScrapCountLastChange"),
- // and this clipboard has not already been copied to the platform scrap
- // ("count == _fScrapCount"), update the platform scrap now. [cc]
-
- short count = GetMacScrapCount();
-
- #if ODDebugClipboard
- PRINT("ODClipboard::ExportClipboard called\n");
- if (count == _fScrapCountLastChange)
- {
- PRINT("ExportClipboard: OpenDoc clipboard contains last change\n");
- if ( count == _fScrapCount )
- {
- PRINT("ExportClipboard: OpenDoc clipboard needs exporting");
- if ( _fSU && _fSU->Exists(ev, kODPropLinkSpec, kODNULL, 0) )
- PRINT(" (has link spec)");
- PRINT("\n");
- }
- else if ( _fExportedLinkSpec && _fSU && !_fSU->Exists(ev, kODPropLinkSpec, kODNULL, 0) )
- PRINT("ExportClipboard: OpenDoc clipboard needs exporting to remove link spec\n");
- else
- PRINT("ExportClipboard: OpenDoc clipboard already copied to platform scrap\n");
- }
- #endif
-
- ODBoolean needToExport = kODFalse;
- ODBoolean needToExportToRemoveLinkSpec = kODFalse;
- if (count == _fScrapCountLastChange )
- {
- if ( count == _fScrapCount )
- {
- needToExport = kODTrue;
- _fExportedLinkSpec = _fSU && _fSU->Exists(ev, kODPropLinkSpec, kODNULL, 0);
- }
- else if ( _fExportedLinkSpec )
- {
- needToExportToRemoveLinkSpec = _fSU && !_fSU->Exists(ev, kODPropLinkSpec, kODNULL, 0);
- }
- }
-
- // Immediately after changing the clipboard, _fOriginalDraft won't be set correctly
- // because the clipboard is not informed when a part is finished writing. [cc]
- if ( needToExport && (_fOriginalDraft == kODNULL) )
- {
- ASSERT(_fDraft != kODNULL, kODErrAssertionFailed);
- _fOriginalDraft = GetOriginalDraft(ev, _fDraft);
- WASSERTM(_fOriginalDraft != kODNULL, "Last clipboard change did not clone");
- }
-
- if ( needToExport || needToExportToRemoveLinkSpec )
- {
- // Copy the OpenDoc clipboard to the scrap
- THROW_IF_ERROR(ForceZeroScrap());
-
- // Optimistically load the scrap into memory if it was unloaded
- LoadScrap();
-
- TRY
- somSelf->PutContentOnPlatformClipboard(ev);
- somSelf->PutClipboardOnPlatformClipboard(ev);
-
- _fScrapCountLastChange = GetMacScrapCount();
- CATCH_ALL
- // If writing the scrap fails, remove any scrap types written [cc]
- ZeroScrap();
- #ifdef _REPORT_SCRAP_ERRORS_
- PRINT("ODClipboard::ExportClipboard failed; clearing scrap\n");
- #endif
- RERAISE;
- ENDTRY
-
- #if ODDebugClipboard
- PRINT("ODClipboard::ExportClipboard updated the scrap, size is %ld\n", InfoScrap()->scrapSize);
- #endif
- }
-
- // Exporting was successful
- if ( needToExportToRemoveLinkSpec )
- _fExportedLinkSpec = kODFalse;
-
- SOM_CATCH_ALL
-
- // If we fail to update the scrap for any reason, ensure fScrapCountLastChanged
- // and fScrapCount equals the Mac scrap count, so we can try again later if
- // no other cut or copy is attempted.
- _fScrapCountLastChange = _fScrapCount = GetMacScrapCount();
-
- #if ODDebugClipboard
- PRINT("ODClipboard::ExportClipboard failed!\n");
- #endif
-
- SOM_ENDTRY
-
- #if ODDebugClipboard
- PRINT("ODClipboard::ExportClipboard done, fExportedLinkSpec = %d\n", _fExportedLinkSpec);
- #endif
-
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
- }
-
- //------------------------------------------------------------------------------
- // ODClipboard::DraftClosing
- //------------------------------------------------------------------------------
- //
- // Forces resolution of promises, and prevents moving content across draft closings
- // via the clipboard. In order to work correctly, parts MUST use BeginClone-EndClone
- // when writing to the clipboard.
-
- SOM_Scope void SOMLINK ODClipboardDraftClosing(ODClipboard *somSelf, Environment *ev,
- ODDraft* draft)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
- ODClipboardMethodDebug("ODClipboard","DraftClosing");
-
- #if ODDebugClipboard
- PRINT("ODClipboard::DraftClosing called, draft is %x\n", draft);
- #endif
-
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- SOM_CATCH
- {
- gODSuppressBentoFatalError = oldSuppress; // neutral
- return;
- }
-
- if ( draft )
- {
- // Immediately after changing the clipboard, _fOriginalDraft won't be set correctly
- // because the clipboard is not informed when a part is finished writing.
-
- short scrapCount = GetMacScrapCount();
- ODBoolean needToExport = (scrapCount == _fScrapCountLastChange) && (scrapCount == _fScrapCount);
- if ( needToExport && (_fOriginalDraft == kODNULL) )
- {
- ASSERT(_fDraft != kODNULL, kODErrAssertionFailed);
- _fOriginalDraft = GetOriginalDraft(ev, _fDraft);
- WASSERTM(_fOriginalDraft != kODNULL, "Last clipboard change did not clone");
- }
-
- #if ODDebugClipboard
- PRINT("Last draft to change clipboard is %x\n", _fOriginalDraft);
- #endif
-
- if ( _fOriginalDraft == draft )
- {
- // Last draft that wrote the clipboard is being closed.
-
- #if ODDebugClipboard
- PRINT("ODClipboard::Draft that last wrote clipboard is closing\n", draft);
- if ( needToExport )
- PRINT("ODClipboard::Clipboard needs exporting\n");
- #endif
- // If the clipboard container is open, force resolution of promises
- // by externalizing the clipboard draft. (If there are unresolved promises,
- // the clipboard hasn't be exported yet). Otherwise open the container.
-
- if ( _fContainer )
- _fDraft->Externalize(ev);
- else
- OpenClipboard(somSelf, ev);
-
- // Remove a link spec if present
- ODSURemoveProperty(ev, _fSU, kODPropLinkSpec);
-
- // Check to see if content was cut (not copied) to the clipboard.
- // If so, change the original clone kind to copy, so any future
- // paste won't be treated as a move.
-
- if ( GetOriginalCloneKind(ev, _fDraft) == kODCloneCut )
- {
- SetOriginalCloneKind(ev, _fDraft, kODCloneCopy);
- // Force exporting to platform clipboard
- _fScrapCountLastChange = _fScrapCount = GetMacScrapCount();
- }
-
- _fOriginalDraft = kODNULL;
- }
- }
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
- }
-
- //------------------------------------------------------------------------------
- // ODClipboard::DraftSaved
- //------------------------------------------------------------------------------
- //
-
- SOM_Scope void SOMLINK ODClipboardDraftSaved(ODClipboard *somSelf, Environment *ev,
- ODDraft* draft)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
- ODClipboardMethodDebug("ODClipboard","DraftSaved");
-
- #if ODDebugClipboard
- PRINT("ODClipboard::DraftSaved called, draft %08x, orig %08x, fDraft %08x\n",
- (long) draft, (long) _fOriginalDraft, (long) _fDraft);
- #endif
-
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- SOM_CATCH
- {
- gODSuppressBentoFatalError = oldSuppress; // neutral
- return;
- }
-
- // ODDraft* tDraft = _fDraft;
- // ODDraft* tOriginalDraft = _fOriginalDraft;
-
- if ( draft )
- {
- if ( _fOriginalDraft == kODNULL )
- {
- if (_fDraft != kODNULL) // can be null if never accessed
- _fOriginalDraft = GetOriginalDraft(ev, _fDraft);
-
- #if ODDebugClipboard
- PRINT(" ODClipboard::DraftSaved orig %08x\n",
- (long) _fOriginalDraft);
- #endif
- }
-
- if ( _fOriginalDraft == draft && _fDraft )
- {
- // Check to see if content was cut (not copied) to the clipboard.
- // If so, change the original clone kind to copy, so any future
- // paste won't be treated as a move.
-
- #if ODDebugClipboard
- PRINT(" ODClipboard::DraftSaved try cut -> copy\n");
- #endif
-
- if ( GetOriginalCloneKind(ev, _fDraft) == kODCloneCut )
- {
- SetOriginalCloneKind(ev, _fDraft, kODCloneCopy);
-
- #if ODDebugClipboard
- PRINT(" ODClipboard::DraftSaved perform cut -> copy\n");
- #endif
- }
- }
- }
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
- }
-
- //------------------------------------------------------------------------------
- // ODClipboard::ShowPasteAsDialog
- //------------------------------------------------------------------------------
-
- SOM_Scope ODBoolean SOMLINK ODClipboardShowPasteAsDialog(ODClipboard *somSelf, Environment *ev,
- ODBoolean canPasteLink,
- ODPasteAsMergeSetting mergeSetting,
- ODFacet* facet,
- ODTypeToken viewType,
- ODPasteAsResult* result)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
- ODClipboardMethodDebug("ODClipboard","ShowPasteAsDialog");
-
- ODBoolean returnValue = kODFalse;
-
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- SOM_CATCH
- {
- gODSuppressBentoFatalError = oldSuppress; // neutral
- return kODFalse;
- }
-
- THROW_IF_NULL(facet, kODErrNullFacetInput);
- THROW_IF_NULL(result, kODErrNullPasteAsResultInput);
-
- ODTypeToken modalFocus = _fSession->Tokenize(ev, kODModalFocus);
- ODArbitrator* arbitrator = _fSession->GetArbitrator(ev);
- TempODFrame currentOwner = arbitrator->AcquireFocusOwner(ev, modalFocus);
-
- if ( arbitrator->RequestFocus(ev, modalFocus, facet->GetFrame(ev)) )
- {
- ODStorageUnit* clipContentSU = somSelf->GetContentStorageUnit(ev);
-
- ODBoolean isMove = (GetOriginalCloneKind(ev, clipContentSU->GetDraft(ev)) == kODCloneCut);
-
- returnValue = ShowPasteAsDialog(
- canPasteLink,
- mergeSetting,
- isMove,
- clipContentSU,
- facet,
- viewType,
- result);
-
- arbitrator->TransferFocus(ev, modalFocus, facet->GetFrame(ev), currentOwner);
- }
- else
- {
- SysBeep(2);
- }
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
-
- return returnValue;
- }
-
- //==============================================================================
- // Local Functions
- //==============================================================================
-
- //------------------------------------------------------------------------------
- // GetMacScrapCount
- //------------------------------------------------------------------------------
- //
- // This function returns the identification stamp of the last mac scrap change,
- // NOT the count of items on the scrap!
-
- ODStatic short GetMacScrapCount()
- {
- return InfoScrap()->scrapCount;
- }
-
- //------------------------------------------------------------------------------
- // IsFrontProcess
- //------------------------------------------------------------------------------
-
- ODStatic ODBoolean IsFrontProcess()
- {
- ProcessSerialNumber psnFront, psnMine;
- ODBoolean frontmost;
-
- GetFrontProcess(&psnFront);
- GetCurrentProcess(&psnMine);
- SameProcess(&psnFront, &psnMine, &frontmost);
-
- return frontmost;
- }
-
- //------------------------------------------------------------------------------
- // ImportStyledTextType
- //------------------------------------------------------------------------------
-
- ODStatic void ImportStyledTextType(ODClipboard *somSelf, Environment *ev)
- {
- ODClipboardData *somThis = ODClipboardGetData(somSelf);
-
- ODHandle hndl = kODNULL;
- ODValue value;
- long dummy;
-
- ODVolatile(hndl);
- ODVolatile(somSelf);
- ODVolatile(somThis);
- ODVolatile(ev);
-
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- SOM_CATCH
- {
- gODSuppressBentoFatalError = oldSuppress; // neutral
- if ( ODSUExistsThenFocus(ev, _fSU, kODPropContents, kODApplestxt) )
- _fSU->Remove(ev);
-
- ODDisposeHandle(hndl);
- return;
- }
-
- // Make sure both 'TEXT' and 'styl' are present
- ODULong sizeText = GetScrap(nil, 'TEXT', &dummy);
- ODULong sizeStyl = GetScrap(nil, 'styl', &dummy);
-
- if ( (sizeText < 0) || (sizeStyl < 0) )
- return;
-
- if ( ODSUExistsThenFocus(ev, _fSU, kODPropContents, kODApplestxt) )
- {
- #ifdef _REPORT_SCRAP_ERRORS_
- WARN("ODClipboard: Replacing value on clipboard");
- #endif
- _fSU->Remove(ev);
- }
-
- ODSUForceFocus(ev, _fSU, kODPropContents, kODApplestxt);
-
- hndl = ODNewHandle(sizeStyl);
-
- sizeStyl = GetScrap((Handle) hndl, 'styl', &dummy);
- if ( sizeStyl < 0 )
- THROW(sizeStyl);
-
- value = (ODValue) ODLockHandle(hndl);
- StorageUnitSetValue(_fSU, ev, sizeStyl, value);
- ODUnlockHandle(hndl);
- ODDisposeHandle(hndl);
- hndl = kODNULL;
-
- hndl = ODNewHandle(sizeText);
-
- sizeText = GetScrap((Handle) hndl, 'TEXT', &dummy);
- if ( sizeText < 0 )
- THROW(sizeText);
-
- value = (ODValue) ODLockHandle(hndl);
- StorageUnitSetValue(_fSU, ev, sizeText, value);
- ODUnlockHandle(hndl);
-
- ODDisposeHandle(hndl);
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
- }
-
- //------------------------------------------------------------------------------
- // ExportStylType
- //------------------------------------------------------------------------------
- //
- // Argument is a pointer to styled text, with begins with a style record.
-
- ODStatic OSErr ExportStylType(ODPtr stxtData)
- {
- Size stylSize = *((short *) stxtData);
- stylSize = (stylSize * sizeof(ScrpSTElement)) + sizeof(short);
-
- return ClipboardPutScrap(stylSize, 'styl', stxtData);
- }
-
- //------------------------------------------------------------------------------
- // ScrapIsInconsistent
- //------------------------------------------------------------------------------
-
- ODStatic ODBoolean ScrapIsInconsistent()
- {
- // Return false if the scrap in an inconsistent state and thus cannot
- // be read. [cc]
-
- #if ODDebugClipboard
- if ( (InfoScrap()->scrapState > 0) && (InfoScrap()->scrapHandle == nil) )
- PRINT("ODClipboard: Scrap is inconsistent!\n");
- #endif
-
- return ((InfoScrap()->scrapState > 0) && (InfoScrap()->scrapHandle == nil));
-
- }
-
- //------------------------------------------------------------------------------
- // ScrapHasData
- //------------------------------------------------------------------------------
-
- ODStatic ODBoolean ScrapHasData()
- {
- // Return true if the scrap size is greater than zero and the scrap is
- // in a consistent state. [cc]
-
- return ((InfoScrap()->scrapSize > 0) && (!ScrapIsInconsistent()));
- }
-
- //------------------------------------------------------------------------------
- // ScrapHasType
- //------------------------------------------------------------------------------
-
- ODStatic ODBoolean ScrapHasType(ODPlatformType type)
- {
- long dummy;
- Size dataSize;
- ODBoolean result = kODFalse;
-
- if ( ScrapHasData() )
- {
- dataSize = GetScrap(nil, type, &dummy);
- if ( dataSize >= 0 )
- result = kODTrue;
- #ifdef _REPORT_SCRAP_ERRORS_
- else
- {
- if (dataSize != noTypeErr )
- WARN("ODClipboard: ScrapHasType: GetScrap() returned error %ld, type = %.4s", dataSize, &type);
- }
- #endif
- }
-
- return result;
- }
-
- //------------------------------------------------------------------------------
- // ForceZeroScrap
- //------------------------------------------------------------------------------
-
- ODStatic OSErr ForceZeroScrap()
- {
- OSErr err = ZeroScrap();
- if ( err == nilHandleErr )
- {
- #ifdef _REPORT_SCRAP_ERRORS_
- PRINT("ODClipboard: ZeroScrap returned error -109\n");
- #endif
- // According to Dylan Ashe, if the scrap is inconsistent the best thing to
- // do is force re-initiaization of the scrap. Use of this constant to
- // force re-initiaization will continue to work in Maxwell. [cc]
- InfoScrap()->scrapState = kUninitializedScrap;
- err = ZeroScrap();
- }
- return err;
- }
-
- //------------------------------------------------------------------------------
- // ScrapMemoryAvailable
- //------------------------------------------------------------------------------
- //
- // This function ensures than allocating dataSize bytes would still leave
- // a 40K contiguous block free, as recommended by Inside Mac, Memory, 1-43. [cc]
-
- ODStatic ODBoolean ScrapMemoryAvailable(Size dataSize)
- {
- const Size kMemCushion = 40*1024;
-
- Size totalFree;
- Size contigFree;
-
- PurgeSpace(&totalFree, &contigFree);
-
- #if ODDebugClipboard
- PRINT("Request %ld bytes with %ld available\n", dataSize, contigFree);
- #endif
-
- return (dataSize + kMemCushion) < contigFree;
- }
-
- //------------------------------------------------------------------------------
- // UnloadScrapIfMemLow
- //------------------------------------------------------------------------------
-
- ODStatic OSErr UnloadScrapIfMemLow(Size dataSize)
- {
- OSErr unloadError = noErr;
-
- if ( InfoScrap()->scrapState != kScrapOnDisk )
- {
- if ( !ScrapMemoryAvailable(dataSize) )
- {
- unloadError = UnloadScrap();
-
- #if ODDebugClipboard
- PRINT("ODClipboard: Scrap unloaded with error %d\n", unloadError);
- #endif
- }
- }
-
- return unloadError;
- }
-
- //------------------------------------------------------------------------------
- // ClipboardLoadScrap
- //------------------------------------------------------------------------------
-
- ODStatic OSErr ClipboardLoadScrap()
- {
- OSErr loadError = noErr;
-
- if ( InfoScrap()->scrapState == kScrapOnDisk )
- {
- if ( ScrapMemoryAvailable(InfoScrap()->scrapSize) )
- {
- loadError = LoadScrap();
-
- #if ODDebugClipboard
- PRINT("ODClipboard: Scrap loaded with error %d\n", loadError);
- #endif
- }
- else
- {
- loadError = kODErrOutOfMemory;
- }
- }
-
- return loadError;
- }
-
- //------------------------------------------------------------------------------
- // ClipboardPutScrap
- //------------------------------------------------------------------------------
-
- ODStatic OSErr ClipboardPutScrap(Size dataSize, ODPlatformType platformType, ODPtr data)
- {
- OSErr error = UnloadScrapIfMemLow(dataSize);
-
- if ( error == noErr )
- {
- error = (OSErr) PutScrap(dataSize, platformType, data);
-
- #ifdef _REPORT_SCRAP_ERRORS_
- WASSERTM(error == noErr, "ODClipboard: PutScrap() failed");
- #endif
- }
-
- return error;
- }