home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / opendc12.zip / od124os2.exe / od12osr1.exe / src / Clipbd.cpp < prev    next >
Text File  |  1997-03-21  |  123KB  |  3,592 lines

  1. //====START_GENERATED_PROLOG======================================
  2. //
  3. //
  4. //   COMPONENT_NAME: oddataxfer
  5. //
  6. //   CLASSES: none
  7. //
  8. //   ORIGINS: 82,27
  9. //
  10. //
  11. //   (C) COPYRIGHT International Business Machines Corp. 1995,1996
  12. //   All Rights Reserved
  13. //   Licensed Materials - Property of IBM
  14. //   US Government Users Restricted Rights - Use, duplication or
  15. //   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  16. //       
  17. //   IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  18. //   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  19. //   PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  20. //   CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  21. //   USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  22. //   OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
  23. //   OR PERFORMANCE OF THIS SOFTWARE.
  24. //
  25. //====END_GENERATED_PROLOG========================================
  26. //
  27. // @(#) 1.16 com/src/storage/Clipbd.cpp, oddataxfer, od96os2, odos29712d 3/20/97 14:08:00 [ 3/21/97 17:21:22 ]
  28. /*
  29.     File:        Clipbd.cpp
  30.  
  31.     Contains:    Implementation for ODClipboard class.
  32.  
  33.     Owned by:    Craig Carper
  34.  
  35.     Copyright:    ⌐ 1993 - 1995 by Apple Computer, Inc., all rights reserved.
  36.  
  37.     Change History (most recent first):
  38.  
  39.         <54>     10/9/95    CC        1289794: Avoid calling GetScrap if scrap is
  40.                                     in an inconsistent state.
  41.                                     1288241: SetPlatformClipboard prevents
  42.                                     exporting clipboard.
  43.                                     1290782: Purge is not implemented.
  44.                                     1286400: Preflight scrap memory
  45.                                     allocations.
  46.         <53>     10/3/95    TJ        Changes done by RefBall Team
  47.         <52>     9/26/95    EL        1285709: ODClipboard does not close down
  48.                                     properly if it was never accessed.
  49.         <51>      9/8/95    Té        1281096 FB2:Many constants in ODTypesB
  50.                                     without kOD prefix!
  51.         <50>     8/31/95    DM        1273863, 1275336: add ODClipboard::
  52.                                     DraftSaved(), make GetOriginalDraft() honor
  53.                                     standard endianess
  54.         <49>     8/30/95    EL        1279832: Storage THROW_IF_NULL problems.
  55.         <48>     8/29/95    DM        1276549: call parent Purge in ODClipboard
  56.         <47>     8/26/95    Té        1274606 FB2: Patching Remarks
  57.         <46>     8/25/95    CC        1264154: Added ActionDone, ActionUndone,
  58.                                     and ActionRedone methods.
  59.         <45>     8/21/95    VL        1277291: Use GetOriginalCloneKind from
  60.                                     StorUtil.
  61.         <44>     8/16/95    NP        1274946: ErrorDef.idl problems. Add include
  62.                                     file.
  63.         <43>     8/12/95    Té        1276812 Need to use TempObjs and TempRefs
  64.                                     for exception safety and to avoid TRY
  65.                                     blocks, 1276807 Opt./Bug: use StdTypIO
  66.                                     routines for portable streaming & smaller
  67.                                     footprint
  68.         <42>      8/3/95    RR        #1257260: Collapse B classes. Remove
  69.                                     somInit methods. Don't call IsInitialized
  70.                                     or SubclassResponsibility
  71.         <41>     7/26/95    DM        #1270320: Memory leak fixes: dispose handle
  72.                                     on return in ODClipboardImportContent
  73.         <40>     7/20/95    CC        1153954: ExportPlatformTypes: Don't move
  74.                                     types to scrap that are not platform types.
  75.                                     1260342: Clear: fail if process is in the
  76.                                     background.
  77.         <39>      7/1/95    CC        1264197: DraftClosing must not remove
  78.                                     Original Draft property.  Instead, change
  79.                                     original clone kind to kODCloneCopy.
  80.                                     1257374: Added ForceZeroScrap(), called
  81.                                     from SetPlatformClipboard() and
  82.                                     ExportClipboard() methods.
  83.         <38>     6/23/95    CC        1260902: ImportContent: Skip if scrap
  84.                                     handle is null, and Ignore types of size
  85.                                     zero.
  86.                                     1257374: GetContentStorageUnit: Never issue
  87.                                     debugger break on failure to import from
  88.                                     the system scrap.
  89.         <37>     6/19/95    CC        1259079: Added local function
  90.                                     IsFrontProcess.
  91.                                     GetContentStorageUnit: Don't warn if
  92.                                     process is in background.
  93.         <36>     5/26/95    VL        1251403: Multithreading naming support.
  94.         <35>     5/22/95    CC        1251106: CloseClipboard externalizes root
  95.                                     SU to resolve promises before externalizing
  96.                                     the clipboard draft.
  97.         <34>     5/18/95    CC        1250280: ShowPasteAsDialog throws on
  98.                                     invalid null arguments.
  99.         <33>     5/17/95    RR        #1250135/1250137/1250143 Getters increment
  100.                                     refcount
  101.         <32>     5/16/95    CC        1244991: ExportClipboard: Re-export
  102.                                     clipboard if link spec has been removed.
  103.                                     ExportClipboard: Set fOriginalDraft field.
  104.                                     DiscardClipboard: Added SOM_CATCH return.
  105.         <31>      5/5/95    CC        1224474: ImportContent: Fixed memory leak
  106.                                     due to variable theISOType
  107.         <30>     4/25/95    CC        1242555: PutContentOnPlatformClipboard:
  108.                                     Removed obsolete $5 comment.
  109.         <29>     4/14/95    Té        #1235279 BB: InfoUtil & StdTypIO functions
  110.                                     should take Environment* and SU* when
  111.                                     possible
  112.         <28>     4/11/95    CC        1231378: DraftClosing: Removed link spec if
  113.                                     present.
  114.         <27>     3/22/95    CC        1230322: Changed parameter to
  115.                                     ShowPasteAsDialog().
  116.         <26>     3/10/95    CC        1225050: Added DraftClosing() method.
  117.                                     1227468: Clear: Set fScrapCount to ensure a
  118.                                     changed clipboard is exported again.
  119.         <25>     2/24/95    CC        1222076: BB: Clipboard contents lost on
  120.                                     error converting to Mac scrap.
  121.                                     1184034:    BB: Error -108 during
  122.                                     cross-document paste link.
  123.                                     1186774, 1201430, 1218790:    Ignore GetScrap
  124.                                     errors.
  125.                                     1223020:    ODClipboard calls LoadScrap() at
  126.                                     innapropriate times.
  127.                                     Fixed mismatched delimiters: #include
  128.                                     <ODDebug.h".
  129.         <24>     2/14/95    jpa        Added return statement to a SOM_CATCH
  130.                                     [1215160]
  131.         <23>     2/10/95    CG        #1177475: Added include for StdDefs.xh.
  132.         <22>      2/7/95    CC        1211295: Added GetOriginalCloneKind().
  133.                                     Pass isMove parameter to ShowPasteAsDialog.
  134.                                     1216124: ShowPasteAsDialog aquires modal
  135.                                     focus.
  136.         <21>      2/1/95    CC        1153802: Improvements to
  137.                                     ImportStyledTextType().
  138.                                     ImportContent(): Create stxt only if not
  139.                                     already present.
  140.         <20>     1/26/95    VL        #???: Use updated Storage Unit Ref API.
  141.         <19>     1/25/95    CC        1153802 Conversion between 'styl' and
  142.                                     'stxt' types: Added ImportStyledTextType
  143.                                     and ExportStylType functions.
  144.         <18>     1/19/95    CC        1212419 Add parameter to
  145.                                     GetMemoryContainer.
  146.                                     1212833 Change to use
  147.                                     kODScrapTypeODBentoContainer.
  148.         <17>    12/20/94    VL        1195012: Make Storage calls be
  149.                                     marshallable.
  150.         <16>     12/8/94    CC        1186774, 1201430 - Suppress errors returned
  151.                                     when reading the scrap.
  152.         <15>     9/29/94    RA        1189812: Mods for 68K build.
  153.         <14>     9/23/94    VL        1155579, 1184272: Use StorUtil to
  154.                                     create/get container and get its file.
  155.         <13>     9/19/94    CC        1187315 - somUninit() must call parent
  156.                                     method last.
  157.                                     1160121 - Clear() must not return an error.
  158.         <12>     9/15/94    CC        1186774 - Suppress GetScrap() errors.
  159.         <11>     8/26/94    VL        1183174: Use updated cloning APIs.
  160.         <10>     8/15/94    Té        #1180922 Removed most obsolete types from
  161.                                     StdTypes.idl
  162.          <9>      8/3/94    CC        Removed Lock() and Unlock(); removed
  163.                                     ODClipboardKey parameter from other
  164.                                     methods.  (1160484)
  165.          <8>      8/3/94    VL        1153123: Storage to ODStor.
  166.          <7>      8/2/94    CC        #1178169 - ShowPasteAsDialog() takes
  167.                                     ODFacet* instead of ODFrame*.
  168.          <6>     7/31/94    CC        Change WASSERTs to WARNs.
  169.          <5>     7/12/94    CC        Companion to .idl checkin -- no changes.
  170.          <4>     6/28/94    VL        Used Translt.xh.
  171.          <3>     6/24/94    CC        Use kODScrapTypePart constant in
  172.                                     ConstDef.h.
  173.          <2>     6/24/94    CC        Fleshed out ShowPasteAsDialog().
  174.          <1>     6/21/94    CC        first checked in
  175.  
  176.         ------------------- CC ---- Converted to SOM
  177.  
  178.         <13>      5/9/94    MB        Changes necessary to install MMM. Bug
  179.                                     #1162181.
  180.         <12>      4/4/94    CC        SetPlatformClipboard() &
  181.                                     ExportPlatformClipboard(): Parameter
  182.                                     changed from XMPTypeSet to XMPTypeList
  183.                                     (1153046)
  184.         <11>     3/28/94    CG        1153547: Renamed XMPSessn.h to XMPSessM.h
  185.         <10>     3/27/94    Té        #1153523.  Adjust name of
  186.                                     kXMPPropRootPartSU to more clearly indicate
  187.                                     what it is supposed to be used for.
  188.          <9>     3/25/94    JA        Added missing #include (1147588)
  189.          <8>     3/18/94    CC        Added counting locks to Lock() and
  190.                                     Unlock(); Implementation of and calls to
  191.                                     ValidateKey(). (1151853)
  192.          <7>     3/16/94    CG        #1151186: Added call to InitPlatformTypeSet
  193.                                     after new XMPPlatformTypeSet.
  194.          <6>      3/2/94    CC        Lock() & Unlock(): Commented out erroneous
  195.                                     WASSERTs. (1145487)
  196.          <5>     2/28/94    VL        Changed code that may cause memory
  197.                                     problems.
  198.          <4>     2/22/94    VL        THROW -> THROW_IF_ERROR.
  199.          <3>     2/15/94    CC        Bug #1142933 - Added key parameter to
  200.                                     SetPlatformClipboard.
  201.          <2>     2/15/94    CC        Bug #1142949 - Adapted to method name
  202.                                     changes in XMPPlatformTypeSet.
  203.          <3>      2/8/94    VL        Use new exception macros.
  204.          <2>      2/4/94    VL        Session.h -> XMPSessn.h.
  205.          <1>      2/4/94    VL        first checked in
  206.  
  207.         <21>      2/4/94    VL        Moved to PPC Header and began code cleanup.
  208.         <20>     1/28/94    CC        Implemented change ids; replaced DebugStrs
  209.                                     with WASSERTMs.
  210.         <19>     1/21/94    CC        Converted from XMPTimeStamp to XMPUpdateID.
  211.                                     Added GetUpdateID.  GetLock() returns
  212.                                     boolean result and returns key in second
  213.                                     parameter.
  214.         <18>     1/21/94    CG        Renamed kXMPMemoryContainer to
  215.                                     kXMPDefaultMemoryContainer.
  216.         <17>     1/18/94    CG        Added include for StorgDef.yh
  217.         <16>     1/18/94    CC        Use kXMPScrapTypePart; release draft
  218.                                     properties on failure in NewClipboard() and
  219.                                     ImportClipboard().
  220.         <15>     1/14/94    CC        Added type XMPClipboardKey, added key
  221.                                     parameter to various routines, replaced
  222.                                     GetGeneration() with GetTimeStamp, renamed
  223.                                     AcquireStorageUnit() GetContentStorageUnit();
  224.                                     changed from using a handle to a pointer in
  225.                                     ExportPlatformTypes() and
  226.                                     PutContentOnPlatformClipboard().
  227.         <14>     1/11/94    Té        Init... changes
  228.         <13>    12/21/93    VL        Changed XMPStorageUnit::GetValueSize to
  229.                                     StorageUnit::GetSize.
  230.         <12>    12/15/93    Té        more InitObject changes, remove
  231.                                     Initialize() method
  232.         <11>    12/15/93    Té        InitObject changes
  233.         <10>     12/2/93    CC        Added Lock(), Unlock(), and GetGeneration()
  234.                                     methods.
  235.          <9>    11/10/93    CC        Doesn't externalize draft before disposing
  236.                                     memory container
  237.          <8>     11/1/93    VL        Used Strong reference.
  238.          <7>    10/29/93    RR        XMPClipboard:: -> XMPMacClipboard
  239.          <6>    10/27/93    CC        Added methods to transfer to/from the
  240.                                     platform clipboard.
  241.          <5>    10/20/93    CC        Added session parameter to XMPClipboard
  242.                                     constructor; added SetPlatformClipboard
  243.                                     method; added code to create the clipboard
  244.                                     container.
  245.          <3>     4/29/93    VL        More 8.3 Name Change.
  246.          <2>     4/29/93    VL        8.3 Name Change.
  247.          <1>     4/27/93    VL        first checked in
  248.  
  249.     To Do:
  250.     Ñ Reuse fContainerHandle when possible after exporting it.
  251.     Ñ Add a resolvePromises parameter to ExportClipboard (but maybe we need to
  252.         do this all the time).
  253.     Ñ Vincent will add a draft change seed.  The clipboard object can examine
  254.         the seed for the clipboard draft to determine if the clipboard has
  255.         been changed since it was exported (if the clipboard generation is the
  256.         same).
  257.     Ñ XMPClipboard::Clear() should clear the system clipboard.
  258.     
  259.     In Progress:
  260.         
  261. */
  262.  
  263. #define VARIABLE_MACROS
  264.  
  265. #define ODClipboard_Class_Source
  266. #include <Clipbd.xih>
  267.  
  268. #ifndef SOM_ODPartHandlerRegistry_xh
  269. #include <ODPrtReg.xih>
  270. #endif
  271.  
  272. #ifndef SOM_Module_OpenDoc_StdDefs_defined
  273. #include <StdDefs.xh>
  274. #endif
  275.  
  276. #ifndef _EXCEPT_
  277. #include <Except.h>
  278. #endif
  279.  
  280. #ifndef _ODMEMORY_
  281. #include <ODMemory.h>
  282. #endif
  283.  
  284. #ifdef _PLATFORM_MACINTOSH_
  285. #ifndef _CONSTDEF_
  286. #include <ConstDef.h>
  287. #endif
  288. #endif
  289.  
  290. #ifndef _PLFMDEF_
  291. #include <PlfmDef.h>
  292. #endif
  293.  
  294. #ifndef _ISOSTR_
  295. #include <ISOStr.h>
  296. #endif
  297.  
  298. #ifndef _ODUTILS_
  299. #include <ODUtils.h>
  300. #endif
  301.  
  302. #ifndef SOM_Module_OpenDoc_StdProps_defined
  303. #include <StdProps.xh>
  304. #endif
  305.  
  306. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  307. #include <StdTypes.xh>
  308. #endif
  309.  
  310. #ifndef SOM_Module_OpenDoc_Foci_defined
  311. #include <Foci.xh>
  312. #endif
  313.  
  314. #ifndef SOM_ODSession_xh
  315. #include <ODSessn.xh>
  316. #endif
  317.  
  318. #ifndef SOM_ODArbitrator_xh
  319. #include <Arbitrat.xh>
  320. #endif
  321.  
  322. #ifndef SOM_ODContainer_xh
  323. #include <ODCtr.xh>
  324. #endif
  325.  
  326. #ifndef SOM_ODDocument_xh
  327. #include <Document.xh>
  328. #endif
  329.  
  330. #ifndef SOM_ODDraft_xh
  331. #include <Draft.xh>
  332. #endif
  333.  
  334. #ifndef SOM_ODStorageSystem_xh
  335. #include <ODStor.xh>
  336. #endif
  337.  
  338. #ifndef SOM_ODStorageUnit_xh
  339. #include <StorageU.xh>
  340. #endif
  341.  
  342. //#if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  343. #ifndef SOM_ODTranslation_xh
  344. #include <Translt.xh>
  345. #endif
  346. //#endif // MAC or AIX
  347.  
  348. #ifndef SOM_ODTypeList_xh
  349. #include <TypeList.xh>
  350. #endif
  351.  
  352. #ifndef SOM_ODTypeListIterator_xh 
  353. #include <TypLsItr.xh>
  354. #endif
  355.  
  356. #ifndef SOM_ODPlatformTypeList_xh
  357. #include <PfTypLs.xh>
  358. #endif
  359.  
  360. #ifndef SOM_ODFacet_xh
  361. #include <Facet.xh>
  362. #endif
  363.  
  364. #ifndef SOM_ODFrame_xh
  365. #include <Frame.xh>
  366. #endif
  367.  
  368. #ifndef SOM_ODShape_xh
  369. #include <Shape.xh>
  370. #endif
  371.  
  372. #ifndef _LINKDLGS_
  373. #include <LinkDlgs.h>
  374. #endif
  375.  
  376. #ifndef SOM_RegistryManager_xh
  377. #include <RManager.xh>
  378. #endif 
  379.  
  380. #ifdef _PLATFORM_MACINTOSH_
  381. #ifndef __SCRAP__
  382. #include <Scrap.h>
  383. #endif
  384. #endif
  385.  
  386. #ifndef _ODDEBUG_
  387. #include <ODDebug.h>
  388. #endif
  389.  
  390. #ifndef __ERRORS__
  391. #include <Errors.h>
  392. #endif
  393.  
  394. #ifndef _STDTYPIO_
  395. #include <StdTypIO.h>
  396. #endif
  397.  
  398. #ifndef _TEMPOBJ_
  399. #include <TempObj.h>
  400. #endif
  401.  
  402. #ifndef _STORUTIL_
  403. #include <StorUtil.h>
  404. #endif
  405.  
  406. #ifndef _UTILERRS_
  407. #include "UtilErrs.h"
  408. #endif
  409.  
  410. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  411. #ifndef __TEXTEDIT__
  412. #include <TextEdit.h>    // for ScrpSTElement
  413. #endif
  414. #endif // MAC or AIX
  415.  
  416. #ifdef _PLATFORM_OS2_
  417. #ifndef _ORDCOLL_
  418. #include <OrdColl.h>
  419. #endif
  420.  
  421. #ifdef OLE_STUFF
  422. #ifndef OLEDEFS_H
  423. #include <OLEDefs.h>
  424. #endif
  425. #endif // OLE_STUFF
  426.  
  427. #endif // _PLATFORM_OS2_
  428.  
  429. #ifdef _PLATFORM_MACINTOSH_
  430. #pragma segment ODClipboard
  431. #endif
  432.  
  433. #include "ClipbdB.cpp"    // Platform-independent methods, if any
  434.  
  435. #if ODDebug
  436. #define ODDebugClipboard 0
  437. #undef _REPORT_SCRAP_ERRORS_
  438. #else
  439. #define ODDebugClipboard 0
  440. #undef _REPORT_SCRAP_ERRORS_
  441. #endif
  442.  
  443. //==============================================================================
  444. // Constants
  445. //==============================================================================
  446.  
  447. const short kInvalidScrapCount = -1;    // Must never match the scrap count!
  448.  
  449. // Mac Scrap state constants
  450. const short kUninitializedScrap = -1;
  451. const short kScrapOnDisk = 0;
  452.  
  453. #ifdef _PLATFORM_OS2_
  454. #define kCF_OPENDOCDOCUMENT "CF_OPENDOCDOCUMENT"
  455. #define CF_OPENDOCDOCUMENT  WinFindAtom(WinQuerySystemAtomTable(),kCF_OPENDOCDOCUMENT)
  456. #define kCF_OPENDOCOWNERID "CF_OPENDOCOWNERID"
  457. #define CF_OPENDOCOWNERID   WinFindAtom(WinQuerySystemAtomTable(),kCF_OPENDOCOWNERID)
  458. /*---------------------------------------------------------------------------
  459.                                TypeDefs
  460. ---------------------------------------------------------------------------*/
  461. typedef struct ClipboardTypeInfo
  462. {
  463.    ODType               opendocType;
  464.    ODPlatformType       platformType;
  465.    ODULong              formatInfo;
  466.    ODBoolean            deletable;
  467. } CLIPBOARDTYPEINFO;
  468.  
  469. CLIPBOARDTYPEINFO clipboardTypeInfo[] =
  470. {
  471.    { kODKindOS2Text,       CF_TEXT,             CFI_POINTER,    kODFalse },
  472.    { kCF_OPENDOCDOCUMENT,  CF_OPENDOCDOCUMENT,  CFI_POINTER,    kODFalse },
  473.    { kCF_OPENDOCOWNERID,   CF_OPENDOCOWNERID,   CFI_HANDLE,     kODFalse },
  474.    { kODKindOS2DspText,    CF_DSPTEXT,          CFI_POINTER,    kODFalse },
  475.    { kODKindOS2Bitmap,     CF_BITMAP,           CFI_HANDLE,     kODFalse },
  476.    { kODKindOS2DspBitmap,  CF_DSPBITMAP,        CFI_HANDLE,     kODFalse },
  477.    { kODKindOS2Metafile,   CF_METAFILE,         CFI_HANDLE,     kODFalse },
  478.    { kODKindOS2DspMetafile,CF_DSPMETAFILE,      CFI_HANDLE,     kODFalse },
  479.    { kODKindOS2Palette,    CF_PALETTE,          CFI_HANDLE,     kODFalse }
  480. };
  481. #endif
  482.  
  483. //==============================================================================
  484. // Function Prototypes
  485. //==============================================================================
  486.  
  487. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  488. ODStatic ODULong ApplicationHeapFree();
  489. ODStatic short GetMacScrapCount();
  490. ODStatic ODBoolean IsFrontProcess();
  491. ODStatic void ImportStyledTextType(ODClipboard *somSelf, Environment *ev);
  492. ODStatic OSErr ExportStylType(ODPtr    stxtData);
  493. #endif // MAC or AIX
  494. ODStatic void CloseClipboard(ODClipboard *somSelf, Environment *ev, ODBoolean externalize);
  495. ODStatic void OpenClipboard(ODClipboard *somSelf, Environment *ev);
  496. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  497. ODStatic ODBoolean ScrapIsInconsistent();
  498. ODStatic ODBoolean ScrapHasData();
  499. ODStatic ODBoolean ScrapHasType(ODPlatformType type);
  500. ODStatic OSErr ForceZeroScrap();
  501. ODStatic ODBoolean ScrapMemoryAvailable(Size dataSize);
  502. ODStatic OSErr UnloadScrapIfMemLow(Size dataSize);
  503. ODStatic OSErr ClipboardLoadScrap();
  504. ODStatic OSErr ClipboardPutScrap(Size dataSize, ODPlatformType    platformType, ODPtr data);
  505. #endif // MAC or AIX
  506. #ifdef _PLATFORM_OS2_
  507. ULONG GetScrap( ODClipboard *somSelf, Handle hData, ODPlatformType type, long * dummy );
  508. ODStatic ODBoolean SetClipboardOwnership( ODClipboard *somSelf,
  509.                                           Environment *ev );
  510. ODBoolean PutPMPromise( ODClipboard *somSelf, ODPlatformType platformType );
  511. OSErr PutScrap( ODClipboard *somSelf, ULONG dataSize,
  512.                                 ODPlatformType platformType, Ptr data);
  513. ODStatic ODUpdateID GetPMUpdateID(HAB hab);
  514. ODStatic ODBoolean ScrapHasData();
  515. ODStatic void SetPMUpdateID(HAB hab, ODUpdateID id);
  516. ULONG GetDataHandle(Environment*ev, ODStorageUnit* su);
  517. #ifdef OLE_STUFF
  518. void PutOleContentOnPlatformClipboard(ODStorageUnit *su);
  519. void GetOleContentFromPlatformClipboard(ODStorageUnit *su);
  520. #endif // OLE_STUFF
  521. ODULong GetFormatInfo( ODClipboard *somSelf, ODPlatformType ulType  ); // [140007]
  522. HBITMAP BitmapFromStorage(Environment* ev, ODStorageUnit* storageUnit);
  523. HMF MetafileFromStorage(Environment* ev, ODStorageUnit* storageUnit);
  524. #endif
  525.  
  526. //==============================================================================
  527. // Utility Functions
  528. //==============================================================================
  529.  
  530. //------------------------------------------------------------------------------
  531. // SetOriginalCloneKind
  532. //------------------------------------------------------------------------------
  533.  
  534. static void SetOriginalCloneKind(Environment* ev, ODDraft* draft, ODCloneKind cloneKind)
  535. {
  536.     if ( draft != kODNULL )
  537.     {
  538.         TempODStorageUnit draftProperties = draft->AcquireDraftProperties(ev);
  539.         ODSetULongProp(ev, draftProperties, kODPropOriginalCloneKind, kODULong, (ODULong)cloneKind);
  540.     }
  541. }
  542.  
  543. //------------------------------------------------------------------------------
  544. // GetOriginalDraft
  545. //------------------------------------------------------------------------------
  546. // Returns kODNULL if the original draft is unknown.  This is the case when content
  547. // was placed in the draft without cloning.
  548.  
  549. static ODDraft* GetOriginalDraft(Environment* ev, ODDraft* draft)
  550. {
  551.     TempODStorageUnit    draftProperties = draft->AcquireDraftProperties(ev);
  552.     return (ODDraft*)ODGetULongProp(ev, draftProperties, kODPropOriginalDraft, kODULong);
  553. }
  554.  
  555. //==============================================================================
  556. // ODClipboard
  557. //==============================================================================
  558.  
  559. //------------------------------------------------------------------------------
  560. // ODClipboard::somUninit
  561. //------------------------------------------------------------------------------
  562.  
  563. SOM_Scope void  SOMLINK ODClipboardsomUninit(ODClipboard *somSelf)
  564. {
  565.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  566.     ODClipboardMethodDebug("ODClipboard","somUninit");
  567.     
  568.     Environment *ev = somGetGlobalEnvironment();
  569.     // somSelf->DiscardClipboard(ev); 
  570.     // It is incorrect to call methods on somSelf inside somUninit, 
  571.     // a subclass may have already been somUninited.  See OpenDoc Building Code for details.
  572.     // Instead the implementation of DiscardClipboard has been copied here.
  573.     
  574.     // BEGIN copy of DiscardClipboard implementation
  575.     CloseClipboard(somSelf, ev, kODFalse);
  576.     
  577.     ODDisposeHandle(_fContainerHandle);
  578.     _fContainerHandle = (ODHandle) kODNULL;
  579.     // END copy of DiscardClipboard implementation
  580. #ifdef _PLATFORM_OS2_
  581.         delete _fTypeCollection;
  582. #endif
  583.  
  584.     parent_somUninit(somSelf);
  585. }
  586.  
  587. //------------------------------------------------------------------------------
  588. // ODClipboard::InitClipboard
  589. //------------------------------------------------------------------------------
  590.  
  591. SOM_Scope void  SOMLINK ODClipboardInitClipboard(ODClipboard *somSelf, Environment *ev,
  592.         ODSession* session)
  593. {
  594.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  595.     ODClipboardMethodDebug("ODClipboard","InitClipboard");
  596.  
  597.     /* Moved from somInit. SOM itself sets fields to zero
  598.     _fSession            = (ODSession*) kODNULL;
  599.     _fContainerHandle    = (ODHandle) kODNULL;
  600.     _fContainer            = (ODContainer*) kODNULL;
  601.     _fDocument            = (ODDocument*) kODNULL;
  602.     _fDraft                = (ODDraft*) kODNULL;
  603.     _fSU                = (ODStorageUnit*) kODNULL;
  604.     
  605.     _fOriginalDraft        = (ODDraft*) kODNULL;
  606.     _fExportedLinkSpec    = kODFalse;
  607.  
  608.     _fClonePasteCount    = 0;
  609.     */
  610.     somSelf->InitObject(ev);
  611.             
  612.     _fSession = session;
  613. #if defined(_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  614.     // Initialize our scrap count to an invalid value so a paste will force copying
  615.     // from the platform scrap.
  616.     _fScrapCount            = kInvalidScrapCount;
  617.     _fScrapCountLastChange    = kInvalidScrapCount;
  618. #endif
  619.     
  620. #if defined(_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  621.     _fUpdateID = kODUnknownUpdate;
  622.     _fNextUpdateID = _fSession->UniqueUpdateID(ev);
  623. #endif // MAC or AIX
  624. #ifdef _PLATFORM_OS2_
  625.   _fUpdateID = kODUnknownUpdate;
  626.   _fLastImportUpdateID = kODUnknownUpdate;
  627.   _fNextUpdateID = _fSession->UniqueUpdateID(ev);
  628.   _fArePromises = kODFalse;
  629.   _fHab = WinQueryAnchorBlock( HWND_DESKTOP );
  630.    _fTypeCollection = new OrderedCollection;
  631.  
  632.    for ( int i = 0;
  633.          i < sizeof( clipboardTypeInfo ) / sizeof( clipboardTypeInfo[0] );
  634.          i++ )
  635.       {
  636.       _fTypeCollection->AddLast( (ElementType)&clipboardTypeInfo[i] );
  637.       }
  638.  
  639.    WinAddAtom(WinQuerySystemAtomTable(), kCF_OPENDOCDOCUMENT);
  640.    WinAddAtom(WinQuerySystemAtomTable(), kCF_OPENDOCOWNERID);
  641. #endif // _PLATFORM_OS2_
  642.  
  643.     _fOriginalCloneKind = kODCloneCopy;
  644. }
  645.  
  646. #if defined(_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  647. //------------------------------------------------------------------------------
  648. // ApplicationHeapFree
  649. //------------------------------------------------------------------------------
  650.  
  651. ODStatic ODULong ApplicationHeapFree()
  652. {
  653.     ODULong free;
  654.     THz curZone = GetZone();
  655.     SetZone(ApplicationZone());
  656.     free = FreeMem();
  657.     SetZone(curZone);
  658.     return free;
  659. }
  660. #endif
  661.  
  662. //------------------------------------------------------------------------------
  663. // ODClipboard::Purge (OVERRIDE)
  664. //------------------------------------------------------------------------------
  665.  
  666. SOM_Scope ODSize  SOMLINK ODClipboardPurge(ODClipboard *somSelf, Environment *ev,
  667.     ODSize size)
  668. {
  669.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  670.     ODClipboardMethodDebug("ODClipboard","Purge");
  671.     
  672.     ODSize freed = 0;
  673.     ODVolatile(freed);
  674. #if defined(_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  675.             
  676.     SOM_TRY
  677.  
  678.         Size scrapSize = InfoScrap()->scrapSize;
  679.         short scrapCount = GetMacScrapCount();
  680.         
  681.         if ( (scrapCount == _fScrapCountLastChange) && (scrapCount == _fScrapCount) )
  682.         {
  683.             ForceZeroScrap();
  684.             // Update scrap later
  685.             _fScrapCountLastChange = _fScrapCount = GetMacScrapCount();
  686.  
  687. #if ODDebugClipboard
  688.             PRINT("ODClipboard::Purge: Scrap cleared\n");
  689. #endif
  690.         }
  691.         else
  692.         {
  693. #if ODDebugClipboard
  694.             if ( InfoScrap()->scrapState > kScrapOnDisk )
  695.                 PRINT("ODClipboard::Purge: Scrap unloaded\n");
  696. #endif
  697.             UnloadScrap();
  698.         }
  699.  
  700. #if ODDebugClipboard
  701.         PRINT("ODClipboard::Purge: Freed %ld bytes in app heap\n", freed);
  702. #endif
  703.  
  704.         freed = parent_Purge(somSelf, ev, size); // always call parent version of Purge()
  705.  
  706.     SOM_CATCH_ALL
  707.     
  708.     SOM_ENDTRY
  709. #endif
  710.  
  711.     return freed;
  712. }
  713.  
  714. //------------------------------------------------------------------------------
  715. // ODClipboard::NewClipboard
  716. //------------------------------------------------------------------------------
  717.  
  718. SOM_Scope void  SOMLINK ODClipboardNewClipboard(ODClipboard *somSelf, Environment *ev)
  719. {
  720.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  721.     ODClipboardMethodDebug("ODClipboard","NewClipboard");
  722.  
  723. #ifdef _PLATFORM_MACINTOSH_
  724.     SOM_CATCH return;
  725. #else
  726.         SOM_TRY
  727. #endif // _PLATFORM_MACINTOSH_
  728.  
  729.     ODStorageUnit* draftProperties = (ODStorageUnit*) kODNULL;
  730.     
  731.     ODVolatile(draftProperties);
  732.     ODVolatile(somSelf);
  733.     ODVolatile(ev);
  734.  
  735.     TRY
  736.         // Create a new clipboard in-memory container
  737.         _fContainerHandle = ODNewHandle(0);
  738.         _fContainer = CreateMemoryContainer(ev, _fSession, _fContainerHandle, kODBentoMemoryContainer);
  739.  
  740.         // Create the root content storage unit
  741.         _fDocument = _fContainer->AcquireDocument(ev, kODDefaultDocument);
  742.         _fDraft = _fDocument->AcquireBaseDraft(ev, kODDPExclusiveWrite);
  743.         _fSU = _fDraft->CreateStorageUnit(ev);
  744.  
  745.         // Store a reference to the content storage unit in the draft properties
  746.         draftProperties = _fDraft->AcquireDraftProperties(ev);
  747.         ODSetStrongSURefProp(ev, draftProperties, kODPropRootPartSU, kODStrongStorageUnitRef, _fSU->GetID(ev));    
  748.         draftProperties->Release(ev);
  749.  
  750.     CATCH_ALL
  751. #ifdef _REPORT_SCRAP_ERRORS_
  752.         WARNMSG_DEBUG(WARN_INDEX(-1),"ODClipboard: Cannot create clipboard - error %ld",ErrorCode());
  753. #endif
  754.         somSelf->DiscardClipboard(ev);
  755.         ODReleaseObject(ev, draftProperties);
  756.         RERAISE;
  757.     ENDTRY
  758. #if defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
  759.         SOM_CATCH_ALL
  760.         SOM_ENDTRY
  761.           return;
  762. #endif
  763. }
  764.  
  765. //------------------------------------------------------------------------------
  766. // CloseClipboard
  767. //------------------------------------------------------------------------------
  768. // Close the current clipboard container, without disposing of the container handle.
  769. // Note: CloseClipboard must not make any method calls to somSelf, since
  770. //         CloseClipboard is called from the somUninit method.
  771.  
  772. ODStatic void CloseClipboard(ODClipboard *somSelf, Environment *ev, ODBoolean externalize)
  773. {
  774.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  775.     
  776.     if ( externalize && _fDraft )
  777.     {
  778.         // Externalize may fail with an iterator-out-of-sync error because 
  779.         // resolving promises may add storage units to the draft's collection
  780.         // during iteration.  In theory, the only promises should be in the
  781.         // root storage unit, so explicitly externalize it first to resolve
  782.         // promises before interating over all storage units.
  783.         if ( _fSU )
  784.             _fSU->Externalize(ev);
  785.         _fDraft->Externalize(ev);
  786.     }
  787.  
  788.     ODReleaseObject(ev,_fSU);
  789.     ODReleaseObject(ev,_fDraft);
  790.     ODReleaseObject(ev,_fDocument);
  791.     ODReleaseObject(ev,_fContainer);
  792. }
  793.  
  794. //------------------------------------------------------------------------------
  795. // ODClipboard::DiscardClipboard
  796. //------------------------------------------------------------------------------
  797.  
  798. SOM_Scope void  SOMLINK ODClipboardDiscardClipboard(ODClipboard *somSelf, Environment *ev)
  799. {
  800.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  801.     ODClipboardMethodDebug("ODClipboard","DiscardClipboard");
  802.  
  803. #ifdef _PLATFORM_MACINTOSH_
  804.     SOM_CATCH return;
  805. #else
  806.         SOM_TRY
  807. #endif // _PLATFORM_MACINTOSH_
  808.     
  809.     CloseClipboard(somSelf, ev, kODFalse);
  810.     
  811.     ODDisposeHandle(_fContainerHandle);
  812.     _fContainerHandle = (ODHandle) kODNULL;
  813. #if defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
  814.         SOM_CATCH_ALL
  815.         SOM_ENDTRY
  816.           return;
  817. #endif
  818. }
  819.  
  820. //------------------------------------------------------------------------------
  821. // ODClipboard::ImportContent
  822. //------------------------------------------------------------------------------
  823. //
  824. // On entry, assumes the scrap has already been checked for consistency.
  825. // Returns an exception if the scrap can't be loaded into memory.
  826.  
  827. SOM_Scope void  SOMLINK ODClipboardImportContent(ODClipboard *somSelf, Environment *ev)
  828. {
  829.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  830.     ODClipboardMethodDebug("ODClipboard","ImportContent");
  831.     
  832.     ODHandle    hData = kODNULL;
  833.     long        scrapOffset = 0;
  834.     
  835.     ODVolatile(hData);
  836.     
  837.     SOM_TRY
  838.     
  839.         hData = ODNewHandle(0);
  840.  
  841. #if defined(_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  842.  
  843.         // Because we walk the scrap, it must be loaded in memory.
  844.         THROW_IF_ERROR(ClipboardLoadScrap());
  845.     
  846.         PScrapStuff myScrapStuff = InfoScrap();
  847.         Handle        hScrap = myScrapStuff->scrapHandle;
  848.  
  849.         while ( scrapOffset < myScrapStuff->scrapSize )
  850.         {
  851.             long        scrapTypeLength;
  852.             ResType        theType;
  853.             ODULong        realOffset;
  854.     
  855.             // There is more in the scrap
  856.             theType = *(ResTypePtr)(((long) *hScrap) + scrapOffset);
  857. #endif // AIX or MAC
  858. #ifdef _PLATFORM_OS2_
  859.  
  860.  
  861.                 ResType theType, thePrevType = 0;
  862.                 while ( (theType = WinEnumClipbrdFmts( _fHab, thePrevType)) != 0 )
  863.                 {
  864.                     long    scrapTypeLength;
  865.                     ODType    theISOType;
  866.                     ODULong  realOffset;
  867.  
  868.                     theISOType = _fSession->GetTranslation(ev)->GetISOTypeFromPlatformType(ev, theType, kODPlatformDataType );
  869.  
  870.                     if (theISOType != (ODType) kODNULL)
  871.                     {
  872. #endif // _PLATFORM_OS2_
  873. #if defined(_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  874.             scrapTypeLength = GetScrap((Handle) hData, theType, (long*) &realOffset);
  875. #endif // MAC or AIX
  876. #ifdef _PLATFORM_OS2_
  877.                         scrapTypeLength = GetScrap( somSelf, (Handle) hData, theType,
  878.                                         (long*) &realOffset);
  879. #endif // _PLATFORM_OS2_
  880.             if ( scrapTypeLength < 0 )
  881.                 THROW(scrapTypeLength);
  882.  
  883. #if defined(_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  884.             if ( realOffset < scrapOffset )
  885.             {
  886.                 // We tried to read a second occurance of the same resource type
  887.                 // on the scrap.  Since the result of GetScrap is the length
  888.                 // of the first occurance, we can't read the scrap past this point.
  889.                 // So just quit.
  890. #ifdef _REPORT_SCRAP_ERRORS_
  891.                 PRINT("ODClipboard: ImportContent: Duplicate resource on scrap, type = \'%.4s\'\n", &theType);
  892. #endif
  893.                 break;
  894.             }
  895. #endif // MAC or AIX
  896. #if ODDebugClipboard
  897.             PRINT("Found scrap type \'%.4s\'\n", &theType);
  898. #endif
  899.             if ( scrapTypeLength > 0 )
  900.             {
  901. #ifdef _REPORT_SCRAP_ERRORS_
  902.                 if ( theType == kODScrapTypeODBentoContainer )
  903.                 {
  904.                     // Internal error
  905.                     WARNMSG_DEBUG(WARN_INDEX(-1),"ODClipboard: ImportContent: Reading BentoContainer as scrap type!");
  906.                 }
  907. #endif
  908.  
  909. #if defined(_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  910.                 // Special case: If 'styl' is present, create an 'stxt' if one
  911.                 // isn't also on the scrap
  912.                 if ( theType == 'styl' )
  913.                 {
  914.                     long dummy;
  915.                     if ( GetScrap(nil, 'stxt', &dummy) == noTypeErr )
  916.                         ImportStyledTextType(somSelf, ev);
  917.                 }
  918.                 
  919.                 TempODType theISOType = kODNULL;
  920.                 theISOType = _fSession->GetTranslation(ev)->GetISOTypeFromPlatformType(ev, theType, kODPlatformDataType);
  921. #endif // MAC or AIX        
  922.  
  923.                 if ( theISOType != (ODType) kODNULL )
  924.                 {
  925.                     if ( ODSUExistsThenFocus(ev, _fSU, kODPropContents, (ODType) theISOType) )
  926.                     {
  927.                         WARNMSG_DEBUG(WARN_INDEX(-1),"ODClipboard: Replacing value on clipboard");
  928.                         _fSU->Remove(ev);
  929.                     }
  930.                     ODSUForceFocus(ev, _fSU, kODPropContents, (ODType) theISOType);
  931.                     ODValue pData = ODLockHandle(hData);
  932.                     StorageUnitSetValue(_fSU, ev, (ODULong) scrapTypeLength, pData);
  933.                     ODUnlockHandle(hData);
  934.                 }
  935.             }
  936. #ifdef _PLATFORM_OS2_
  937.                         thePrevType = theType;
  938.                     }
  939.  
  940. #if defined(_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  941.             // The length must be EVEN!
  942.             if (scrapTypeLength & 1)
  943.             {
  944.                 scrapTypeLength += 1;
  945.             }
  946.             scrapOffset = realOffset + scrapTypeLength;
  947. #endif // MAC or AIX
  948.         }
  949.  
  950.     SOM_CATCH_ALL
  951.  
  952. #ifdef _REPORT_SCRAP_ERRORS_
  953.         WARNMSG_DEBUG(WARN_INDEX(-1),"ODClipboard: ImportContent: Failed with error %ld",ErrorCode());
  954. #endif
  955.         if ( ErrorCode() == memFullErr )
  956.             SetErrorCode(kODErrOutOfMemory);
  957.  
  958.     SOM_ENDTRY
  959.  
  960. #ifdef _PLATFORM_OS2_
  961.       _fArePromises = kODFalse;
  962. #endif
  963.     ODDisposeHandle(hData);
  964. }
  965.  
  966. //------------------------------------------------------------------------------
  967. // ODClipboard::PutContentOnPlatformClipboard
  968. //------------------------------------------------------------------------------
  969. //
  970. // Copy values with corresponding platform types onto the desk scrap.
  971. // THROWs an exception if any error occurs, which may cause the desk scrap to
  972. // be only partially updated. The desk scrap requires copying the data in one chunk.
  973.  
  974. SOM_Scope void  SOMLINK ODClipboardPutContentOnPlatformClipboard(ODClipboard *somSelf, Environment *ev)
  975. {
  976.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  977.     ODClipboardMethodDebug("ODClipboard","PutContentOnPlatformClipboard");
  978.     
  979.     ODULong            count;
  980.     ODULong            index;
  981.     ODPlatformType    platformType;
  982.  
  983.     SOM_TRY
  984.  
  985.         if ( (_fSU == kODNULL) && (_fContainerHandle != kODNULL) )
  986.             OpenClipboard(somSelf, ev);
  987.             
  988.         if ( _fSU )
  989.         {
  990.                         //sesh -- [136778]
  991. #ifdef OLE_STUFF
  992.                         if (  _fSU->Exists(ev,kODPropContents, kODKindOlePart, 0))
  993.                         {
  994.                            PutOleContentOnPlatformClipboard(_fSU);
  995.                         }
  996. #endif // OLE_STUFF
  997.             _fSU->Focus(ev, kODPropContents, kODPosUndefined, 0, 0, kODPosUndefined);
  998.             count = _fSU->CountValues(ev);
  999.             for (index = 1; index <= count; ++index)
  1000.             {
  1001.                 _fSU->Focus(ev, kODPropContents, kODPosUndefined, 0, index, kODPosUndefined);
  1002.                 TempODType theISOType = _fSU->GetType(ev);
  1003.  
  1004. #if defined(_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1005.                 platformType = _fSession->GetTranslation(ev)->GetPlatformTypeFromISOType(ev, (ODType) theISOType);
  1006. #endif // MAC or AIX
  1007. #ifdef _PLATFORM_OS2_
  1008.                                 platformType = _fSession->GetTranslation(ev)->GetPlatformTypeFromISOType(ev, theISOType );
  1009. #endif // _PLATFORM_OS2_
  1010.                 if (platformType != (ODPlatformType) kODNULL)
  1011.                 {
  1012.  
  1013.                     _fSU->Focus(ev, kODPropContents, kODPosUndefined, (ODType) theISOType, 0, kODPosUndefined); // rrk 26 jul 96
  1014. #if defined(_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1015. //                    _fSU->Focus(ev, kODPropContents, kODPosUndefined, (ODType) theISOType, 0, kODPosUndefined);
  1016.                     Size dataSize = _fSU->GetSize(ev);
  1017.  
  1018.                     TempODPtr data = kODNULL;
  1019.                     data = ODNewPtr(dataSize, kDefaultHeapID);
  1020.  
  1021.                     StorageUnitGetValue(_fSU, ev, dataSize, (ODValue) data);
  1022.     
  1023.                     THROW_IF_ERROR(ClipboardPutScrap(dataSize, platformType, data));
  1024.  
  1025.                     // If styled text ('stxt') was just written to the scrap, also write
  1026.                     // 'stly' if a 'TEXT' representation will also be written.
  1027.                     if ( platformType == 'stxt' )
  1028.                         if ( _fSU->Exists(ev, kODPropContents, kODAppleTEXT, 0) )
  1029.                             if ( !_fSU->Exists(ev, kODPropContents, kODApplestyl, 0) )
  1030.                                 THROW_IF_ERROR(ExportStylType(data));
  1031. #endif // MAC or AIX
  1032. #ifdef _PLATFORM_OS2_
  1033.                                         OSErr  error;
  1034.                                         ODPtr  data = (ODPtr) kODNULL;
  1035.                                         ULONG  dataSize;
  1036.  
  1037.                                //         _fSU->Focus(ev, kODPropContents, kODPosUndefined, theISOType, 0,
  1038.                                //                                kODPosUndefined);
  1039.                                         if ( _fSU->IsPromiseValue( ev ))
  1040.                                         {
  1041.                                //            _fArePromises = kODTrue;
  1042.                                            PutPMPromise( somSelf, platformType );
  1043.                                            _fArePromises = kODTrue;
  1044.                                /* [146569] - commented out promise removal
  1045.                                            _fSU->Remove( ev );
  1046.                                            index--;
  1047.                                */
  1048.                                            error = noErr;
  1049.                                         }
  1050.                                         else
  1051.                                         {
  1052.                                            ULONG handle = NULLHANDLE;
  1053.                                            if(handle = GetDataHandle(ev, _fSU)) {
  1054.                                                dataSize = sizeof(handle);
  1055.                                                data = &handle;
  1056.                                            }
  1057.                                            else {
  1058.                                                 dataSize = _fSU->GetSize(ev);
  1059.                                                 // there may be no size, but we need to use a real size here
  1060.                                                 // so that all the storage stuff works.
  1061.                                                 if (dataSize == 0) dataSize = 4;
  1062.                                                 data = ODNewPtrClear(dataSize, kDefaultHeapID);
  1063.                                                 StorageUnitGetValue(_fSU, ev, dataSize, (ODValue) data);
  1064.                                            }
  1065.                                            error = (OSErr) PutScrap( somSelf, dataSize, platformType, (Ptr) data);
  1066.                                            if(!handle) ODDisposePtr(data);
  1067.                                         }
  1068.                                         if (error != noErr)
  1069.                                         {
  1070.                                            ODDisposePtr(theISOType);
  1071.                                            THROW(error);
  1072.                                         }
  1073. #endif // _PLATFORM_OS2_
  1074.                 }
  1075.             }
  1076.         }
  1077.  
  1078.     SOM_CATCH_ALL
  1079.  
  1080.     SOM_ENDTRY
  1081. }
  1082.  
  1083. //------------------------------------------------------------------------------
  1084. // ODClipboard::ExportPlatformTypes
  1085. //------------------------------------------------------------------------------
  1086. //
  1087. // Export data of the argument platform types to the host clipboard.
  1088. // Since only one ISO type corresponds directly to a platform type (no translation
  1089. // is attempted), we just examine each value on the clipboard and check if
  1090. // its platform equivalent is present in the argument set.
  1091.  
  1092.  
  1093. SOM_Scope void  SOMLINK ODClipboardExportPlatformTypes(ODClipboard *somSelf, Environment *ev,
  1094.     ODPlatformTypeList* typeList)
  1095. {
  1096.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  1097.     ODClipboardMethodDebug("ODClipboard","ExportPlatformTypes");
  1098. #ifdef _PLATFORM_OS2_    
  1099.         OSErr  error = noErr;
  1100. #endif
  1101.     ODULong    countOfValues;
  1102.     ODULong    index;
  1103.     ODULong    countToExport;
  1104.     
  1105.     SOM_TRY
  1106.  
  1107.         if ( (_fSU == kODNULL) && (_fContainerHandle != kODNULL) )
  1108.             OpenClipboard(somSelf, ev);
  1109.             
  1110.         if ( _fSU )
  1111.         {
  1112.             _fSU->Focus(ev, kODPropContents, kODPosUndefined, 0, 0, kODPosUndefined);
  1113.             countOfValues = _fSU->CountValues(ev);
  1114.             if (typeList != (ODPlatformTypeList*) kODNULL)
  1115.                 countToExport = typeList->Count(ev);
  1116.             else
  1117.                 countToExport = countOfValues;
  1118.             
  1119.             for (index = 1; (index <= countOfValues) && (countToExport > 0); ++index)
  1120.             {
  1121.                 _fSU->Focus(ev, kODPropContents, kODPosUndefined, 0, index, kODPosUndefined);
  1122.                 TempODType theISOType = _fSU->GetType(ev);
  1123.             
  1124.                 ODPlatformType platformType = 
  1125. #if defined(_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1126.                     _fSession->GetTranslation(ev)->GetPlatformTypeFromISOType(ev, (ODType) theISOType);
  1127. #endif // MAC or AIX
  1128. #ifdef _PLATFORM_OS2_
  1129.                                         _fSession->GetTranslation(ev)->GetPlatformTypeFromISOType(ev, theISOType );
  1130. #endif // _PLATFORM_OS2_
  1131.                 if ( platformType != (ODPlatformType) 0 )
  1132.                 {
  1133.                     if ((typeList == (ODPlatformTypeList*) kODNULL) || (typeList->Contains(ev, platformType)))
  1134.                     {
  1135.                         _fSU->Focus(ev, kODPropContents, kODPosUndefined, (ODType) theISOType, 0, kODPosUndefined);
  1136. #ifdef _PLATFORM_OS2_
  1137.                                                 if ( _fSU->IsPromiseValue( ev ))
  1138.                                                 {
  1139.                                                   PutPMPromise( somSelf, platformType );
  1140.                                                   _fArePromises = kODTrue;
  1141.                                  /* [146569] - commented out promise removal
  1142.                                                   _fSU->Remove( ev );
  1143.                                                   index--;
  1144.                                  */
  1145.                                                   error = noErr;
  1146.                                                 }
  1147.                                                 else
  1148.                                                 {
  1149. #endif
  1150.                         ULONG dataSize = _fSU->GetSize(ev);
  1151.  
  1152.                         TempODPtr data = kODNULL;
  1153.                         data = ODNewPtr(dataSize, kDefaultHeapID);
  1154.                 
  1155.                         StorageUnitGetValue(_fSU, ev, dataSize, (ODValue) data);
  1156.             
  1157.  
  1158. #if defined(_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1159.                         THROW_IF_ERROR(ClipboardPutScrap(dataSize, platformType, data));
  1160. #endif    
  1161. #ifdef _PLATFORM_OS2_
  1162.                                                 error = (OSErr) PutScrap( somSelf, dataSize, platformType, /*(Ptr)*/(char*)(void*) data);
  1163.                                                 if (error != noErr)
  1164.                                                 {
  1165.  
  1166.                                                   ODDisposePtr(theISOType);
  1167.                                                   THROW(error);
  1168.                                                 }
  1169.                                                 }
  1170. #endif
  1171.                         if (typeList != (ODPlatformTypeList*) kODNULL)
  1172.                             typeList->Remove(ev, platformType);
  1173.                         countToExport -= 1;
  1174.                     }
  1175.                 }
  1176.             }
  1177.         }
  1178.  
  1179.     SOM_CATCH_ALL
  1180.     
  1181. #if defined(_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1182.         if ( ErrorCode() == memFullErr )
  1183.             SetErrorCode(kODErrOutOfMemory);
  1184. #endif // MAC or AIX
  1185.  
  1186.     SOM_ENDTRY
  1187. }
  1188.  
  1189. //------------------------------------------------------------------------------
  1190. // OpenClipboard
  1191. //------------------------------------------------------------------------------
  1192.  
  1193. ODStatic void OpenClipboard(ODClipboard *somSelf, Environment *ev)
  1194. {
  1195.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  1196.  
  1197.     ODStorageUnitID    suID;
  1198.     
  1199.     ODVolatile(somSelf);
  1200.     ODVolatile(ev);
  1201.  
  1202.     if ( _fContainerHandle )
  1203.     {
  1204.         TRY
  1205.             _fContainer = GetMemoryContainer(ev, _fSession, _fContainerHandle, kODBentoMemoryContainer);        
  1206.             _fDocument = _fContainer->AcquireDocument(ev, kODDefaultDocument);
  1207.             _fDraft = _fDocument->AcquireBaseDraft(ev, kODDPExclusiveWrite);
  1208.     
  1209.             { TempODStorageUnit draftProperties = _fDraft->AcquireDraftProperties(ev);
  1210.               suID = ODGetStrongSURefProp(ev, draftProperties, kODPropRootPartSU, kODStrongStorageUnitRef);
  1211.             }
  1212.     
  1213.             _fSU = _fDraft->AcquireStorageUnit(ev, suID);
  1214.         CATCH_ALL
  1215.             CloseClipboard(somSelf, ev, kODFalse);
  1216.             RERAISE;
  1217.         ENDTRY
  1218.     }
  1219. }
  1220.  
  1221. //------------------------------------------------------------------------------
  1222. // ODClipboard::PutClipboardOnPlatformClipboard
  1223. //------------------------------------------------------------------------------
  1224. //
  1225. // This method has the side effect of closing the clipboard container.
  1226. // Also note that by externalizing the clipboard draft, all promises are resolved.
  1227.  
  1228. SOM_Scope void  SOMLINK ODClipboardPutClipboardOnPlatformClipboard(ODClipboard *somSelf, Environment *ev)
  1229. {
  1230.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  1231.     ODClipboardMethodDebug("ODClipboard","PutClipboardOnPlatformClipboard");
  1232.     
  1233.     SOM_TRY 
  1234.  
  1235.     // Externalize then close the clipboard container
  1236.     CloseClipboard(somSelf, ev, kODTrue);
  1237.  
  1238.     if ( _fContainerHandle )
  1239.     {
  1240.         OSErr    error;
  1241.         ULONG    dataSize;
  1242.         char    flags;
  1243.     
  1244.         dataSize = ODGetHandleSize(_fContainerHandle);
  1245.  
  1246.  
  1247. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1248.         THROW_IF_ERROR(UnloadScrapIfMemLow(dataSize));
  1249. #endif // MAC or AIX
  1250.  
  1251. #ifdef OSA_INCLUDED
  1252.         flags = HGetState((Handle) _fContainerHandle);
  1253. #endif // OSA_INCLUDED
  1254.         Ptr containerPtr = (Ptr) ODLockHandle(_fContainerHandle);
  1255. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1256.         error = (OSErr) PutScrap(dataSize, kODScrapTypeODBentoContainer, containerPtr);
  1257. #endif // MAC or AIX
  1258. #ifdef _PLATFORM_OS2_
  1259.                 error = (OSErr) PutScrap(somSelf, dataSize, CF_OPENDOCDOCUMENT,
  1260.                                 (Ptr)*((Handle)_fContainerHandle));
  1261. #endif // _PLATFORM_OS2_
  1262. #ifdef OSA_INCLUDED
  1263.         HSetState((Handle) _fContainerHandle, flags);
  1264. #endif // OSA_INCLUDED
  1265.  
  1266. #ifdef _REPORT_SCRAP_ERRORS_
  1267.         WASSERTM(error == noErr, "ODClipboard: PutScrap() failed");
  1268. #endif
  1269.         THROW_IF_ERROR(error);
  1270.     }
  1271. #ifdef _REPORT_SCRAP_ERRORS_
  1272.     else
  1273.     {
  1274.         // Internal error
  1275.         WARNMSG_DEBUG(WARN_INDEX(-1),"ODClipboard: PutClipboardOnPlatformClipboard: No Clipboard to export!\n");
  1276.     }
  1277. #endif
  1278.  
  1279.     SOM_CATCH_ALL
  1280.     
  1281. #ifdef _REPORT_SCRAP_ERRORS_
  1282.         WARNMSG_DEBUG(WARN_INDEX(-1),"ODClipboard: PutClipboardOnPlatformClipboard: Raising exception %d\n", ErrorCode());
  1283. #endif
  1284.  
  1285.     SOM_ENDTRY
  1286. }
  1287.  
  1288. //------------------------------------------------------------------------------
  1289. // ODClipboard::ImportClipboard
  1290. //------------------------------------------------------------------------------
  1291. //
  1292. // A bento memory container is always used for data interchange.
  1293. // If OpenClipboard throws, its probably because a bad resource of type
  1294. // kODScrapTypeODBentoContainer was found on the clipboard (currently error 1012,
  1295. // but it may change and there may be others).
  1296. // This routine returns:
  1297. //        kODFalse, if the platform clipboard does not contain an OpenDoc clipboard;
  1298. //        kODTrue, if an OpenDoc clipboard is successfully imported;
  1299. //        an exception if an OpenDoc clipboard could not be imported
  1300.  
  1301. SOM_Scope ODBoolean  SOMLINK ODClipboardImportClipboard(ODClipboard *somSelf, Environment *ev)
  1302.     {
  1303.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  1304.     ODClipboardMethodDebug("ODClipboard","ImportClipboard");
  1305.  
  1306.         ODBoolean retVal;
  1307. #ifdef _PLATFORM_MACINTOSH_
  1308.     SOM_CATCH return kODFalse;
  1309. #else
  1310.         SOM_TRY
  1311. #endif // _PLATFORM_MACINTOSH_
  1312.     
  1313.     ODHandle    hData = kODNULL;
  1314.     ULONG        dataSize;
  1315.     long        dummy;
  1316. #ifdef _PLATFORM_OS2_
  1317.         ULONG        ulFmtInfo;
  1318. #endif
  1319.     
  1320.     WASSERTMSG_DEBUG(_fContainerHandle == (ODHandle) kODNULL, "ODClipboard: fContainerHandle not null");
  1321.     WASSERTMSG_DEBUG(_fContainer == (ODContainer*) kODNULL, "ODClipboard: fContainer not null");
  1322.     WASSERTMSG_DEBUG(_fDocument == (ODDocument*) kODNULL, "ODClipboard: fDocument not null");
  1323.     WASSERTMSG_DEBUG(_fDraft == (ODDraft*) kODNULL, "ODClipboard: fDraft not null");
  1324.     WASSERTMSG_DEBUG(_fSU == (ODStorageUnit*) kODNULL, "ODClipboard: fSU not null");
  1325.     
  1326. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1327.     if ( !ScrapHasType(kODScrapTypeODBentoContainer) )
  1328.         return kODFalse;
  1329. #endif // MAC or AIX
  1330. #ifdef _PLATFORM_OS2_
  1331.    if (!WinQueryClipbrdFmtInfo( _fHab, CF_OPENDOCDOCUMENT, &ulFmtInfo ))
  1332.       return kODFalse;
  1333. #endif
  1334.     
  1335.     ODVolatile(hData);
  1336.     
  1337.     TRY
  1338.         hData = ODNewHandle(0);
  1339.     
  1340. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1341.         dataSize = GetScrap((Handle) hData, kODScrapTypeODBentoContainer, &dummy);
  1342. #endif // MAC or AIX
  1343. #ifdef _PLATFORM_OS2_
  1344.                 dataSize = GetScrap(somSelf, (Handle) hData, CF_OPENDOCDOCUMENT, &dummy);
  1345. #endif
  1346.         if ( dataSize < 0 )
  1347.         {
  1348.             if ( dataSize == memFullErr )
  1349.                 THROW(kODErrOutOfMemory);
  1350.             else
  1351.                 THROW(dataSize);
  1352.         }
  1353.     
  1354.         _fContainerHandle = hData;
  1355.  
  1356.         OpenClipboard(somSelf, ev);
  1357.     CATCH_ALL
  1358. #ifdef _REPORT_SCRAP_ERRORS_
  1359.         WARNMSG_DEBUG(WARN_INDEX(-1),"ODClipboard: Cannot import clipboard - error %ld",ErrorCode());
  1360. #endif
  1361.         _fContainerHandle = kODNULL;
  1362.         ODDisposeHandle(hData);
  1363.         RERAISE;
  1364.     ENDTRY
  1365.         retVal = kODTrue;
  1366. #if defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
  1367.         SOM_CATCH_ALL
  1368.           retVal = kODFalse;
  1369.         SOM_ENDTRY
  1370. #endif
  1371.     
  1372.     return retVal;
  1373. }
  1374.  
  1375. //------------------------------------------------------------------------------
  1376. // ODClipboard::GetUpdateID
  1377. //------------------------------------------------------------------------------
  1378.  
  1379. SOM_Scope ODUpdateID  SOMLINK ODClipboardGetUpdateID(ODClipboard *somSelf, Environment *ev)
  1380. {
  1381.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  1382.     ODClipboardMethodDebug("ODClipboard","GetUpdateID");
  1383.     
  1384. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1385.     short curScrapCount = GetMacScrapCount();
  1386.     
  1387.     // If the desk scrap has not changed since we last imported it, 
  1388.     // or if the desk scrap has not changed since the last change to this clipboard,
  1389.     // return the current change id, otherwise, return the next change id.
  1390.     // Note that this routine will return the same "next" change id
  1391.     // even if the desk scrap has changed since the last call to this routine.
  1392.     if (curScrapCount == _fScrapCount)
  1393.         return _fUpdateID;
  1394.     else if (curScrapCount == _fScrapCountLastChange)
  1395.         return _fUpdateID;
  1396.     else
  1397.         return _fNextUpdateID;
  1398. #endif // MAC or AIX
  1399. #ifdef _PLATFORM_OS2_
  1400.    ODUpdateID updateID = GetPMUpdateID(_fHab);
  1401.  
  1402.    if(!updateID)
  1403.       return _fNextUpdateID;
  1404.  
  1405.    if( (!_fUpdateID) || (_fLastImportUpdateID == updateID) )
  1406.       return _fUpdateID;
  1407.  
  1408.    return _fNextUpdateID;
  1409. #endif
  1410. }
  1411.  
  1412. //------------------------------------------------------------------------------
  1413. // ODClipboard::Clear
  1414. //------------------------------------------------------------------------------
  1415.  
  1416. SOM_Scope void  SOMLINK ODClipboardClear(ODClipboard *somSelf, Environment *ev)
  1417. {
  1418.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  1419.     ODClipboardMethodDebug("ODClipboard","Clear");
  1420.  
  1421. #if ODDebugClipboard
  1422.     PRINT("ODClipboard::Clear \n");
  1423. #endif
  1424.     
  1425. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1426.     if ( !IsFrontProcess() )
  1427.     {
  1428.         ODSetSOMException(ev, kODErrBackgroundClipboardClear);
  1429.         return;
  1430.     }
  1431.     
  1432.     // Unless called when the process is in the background,
  1433.     // don't return an error so this method can be called in a failure handler.
  1434.     FN_CATCH return;
  1435. #endif // MAC or AIX
  1436.  
  1437. #if ODDebugClipboard
  1438.     if ( (_fSU != (ODStorageUnit*) kODNULL) && (_fSU->GetRefCount(ev) != 1) )
  1439.         PRINT("ODClipboard::Clear - Storage unit refCount = %d\n", _fSU->GetRefCount(ev));
  1440. #endif
  1441.     
  1442. #ifdef _PLATFORM_OS2_
  1443.   WinOpenClipbrd(_fHab);
  1444.   WinEmptyClipbrd(_fHab);
  1445.   WinCloseClipbrd(_fHab);
  1446.   ODUpdateID updateID = GetPMUpdateID(_fHab);
  1447.  
  1448.   _fLastImportUpdateID = updateID;
  1449.   if(!_fLastImportUpdateID) {
  1450.            _fLastImportUpdateID = _fSession->UniqueUpdateID(ev);
  1451.            SetPMUpdateID(_fHab, _fLastImportUpdateID);
  1452.   }
  1453. #endif
  1454.     somSelf->DiscardClipboard(ev);
  1455.     
  1456.     _fUpdateID = _fNextUpdateID;
  1457.     _fNextUpdateID = _fSession->UniqueUpdateID(ev);
  1458.  
  1459. #if ODDebugClipboard
  1460.     PRINT("ODClipboard::Clear _fOriginalDraft = kODNULL\n");
  1461. #endif
  1462.     
  1463.     _fOriginalDraft = kODNULL;
  1464.     _fOriginalCloneKind = kODCloneCopy;
  1465.     _fClonePasteCount = 0;
  1466.     
  1467.  
  1468. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1469.     // Remember to export to desk scrap
  1470.     _fScrapCountLastChange = _fScrapCount = GetMacScrapCount();
  1471. #endif // MAC or AIX
  1472. }
  1473.  
  1474. //------------------------------------------------------------------------------
  1475. // ODClipboard::GetContentStorageUnit
  1476. //------------------------------------------------------------------------------
  1477. //
  1478. // If importing from the host clipboard fails, this method returns a new, empty
  1479. // storage unit.  No alert is displayed to inform the user.  This method will
  1480. // retry importing until Clear() is called.  An exception is returned only if
  1481. // an empty clipboard cannot be created.
  1482. //
  1483. // If this routine is called when the process is in the background, GetScrap()
  1484. // will probably return memFullError.  Even if it did return scrap data, the
  1485. // data would not be reliable because the forground application might be keeping
  1486. // the true clipboard data in a private scrap.  So rather than returning a scrap
  1487. // error, just return an empty clipboard.
  1488.  
  1489. SOM_Scope ODStorageUnit*  SOMLINK ODClipboardGetContentStorageUnit(ODClipboard *somSelf, Environment *ev)
  1490. {
  1491.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  1492.     ODClipboardMethodDebug("ODClipboard","GetContentStorageUnit");
  1493.     
  1494. #ifdef _PLATFORM_MACINTOSH_
  1495.     SOM_CATCH
  1496.     {
  1497. #ifdef _REPORT_SCRAP_ERRORS_
  1498.         WARNMSG_DEBUG(WARN_INDEX(-1),"ODClipboard: GetContentStorageUnit: Raising exception %d\n", ErrorCode());
  1499. #endif
  1500.         return kODNULL;
  1501.     }
  1502. #else
  1503.         SOM_TRY
  1504. #endif // _PLATFORM_MACINTOSH_
  1505.     
  1506.     ODVolatile(somSelf);
  1507.     ODVolatile(ev);
  1508.  
  1509. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1510.     short curScrapCount = GetMacScrapCount();
  1511. #endif // MAC or AIX
  1512.     
  1513. #if ODDebugClipboard
  1514.     if ( (_fSU != (ODStorageUnit*) kODNULL) && (_fSU->GetRefCount(ev) != 1) )
  1515.         PRINT("ODClipboard::GetContentStorageUnit - Storage unit refCount = %d\n", _fSU->GetRefCount(ev));
  1516. #endif
  1517.  
  1518.     // _fScrapCount is the platform scrap count that was last imported or in effect when the clipboard changed.
  1519.     // If "curScrapCount == _fScrapCount", the platform scrap has not changed since it was last imported.
  1520.     // _fScrapCountLastChange is the platform scrap count at the time the OpenDoc clipboard last changed.
  1521.     // If "curScrapCount == _fScrapCountLastChange", the platform scrap has not changed since the
  1522.     // OpenDoc clipboard last changed.
  1523.  
  1524. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1525.     if ( (curScrapCount != _fScrapCount) && (curScrapCount != _fScrapCountLastChange) )
  1526.     {
  1527. #endif // MAC or AIX
  1528. #ifdef _PLATFORM_OS2_
  1529.         ODUpdateID updateID = GetPMUpdateID(_fHab);
  1530.  
  1531.         if(!updateID || updateID != _fLastImportUpdateID)
  1532.         {
  1533.                 WinOpenClipbrd( _fHab );
  1534.                 _fLastImportUpdateID = updateID;
  1535. #endif
  1536.         // Import from desk scrap into the OpenDoc clipboard
  1537. #if ODDebugClipboard
  1538.         PRINT("ODClipboard: GetContentStorageUnit: Updating clipboard from scrap\n");
  1539. #endif
  1540.  
  1541.         somSelf->DiscardClipboard(ev);
  1542.  
  1543.         TRY
  1544.             if ( ScrapHasData() )
  1545.             {
  1546.                 if ( !somSelf->ImportClipboard(ev) )
  1547.                 {
  1548.                     somSelf->NewClipboard(ev);
  1549.                     somSelf->ImportContent(ev);
  1550.                 }
  1551. #ifdef _PLATFORM_OS2_
  1552.                                 if(!_fLastImportUpdateID) {
  1553.                                        _fLastImportUpdateID = _fSession->UniqueUpdateID(ev);
  1554.                                        WinSetClipbrdData( _fHab, _fLastImportUpdateID, CF_OPENDOCOWNERID, CFI_HANDLE );
  1555.                                 }
  1556. #endif
  1557.             }
  1558.             else
  1559.             {
  1560.                 somSelf->NewClipboard(ev);
  1561.             }
  1562. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1563.             _fScrapCount = curScrapCount;
  1564. #endif // MAC or AIX
  1565.             _fUpdateID = _fNextUpdateID;
  1566.             _fNextUpdateID = _fSession->UniqueUpdateID(ev);
  1567. #ifdef _PLATFORM_OS2_
  1568.                         _fArePromises = kODFalse;
  1569. #endif // _PLATFORM_OS2_
  1570.         CATCH_ALL
  1571. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1572. #ifdef _REPORT_SCRAP_ERRORS_
  1573.             if ( IsFrontProcess() )
  1574.                 WARN("ODClipboard: GetContentStorageUnit: Importing from desk scrap raised exception %d\n", ErrorCode());
  1575. #endif
  1576. #endif // MAC or AIX
  1577.             // Importing an OpenDoc clipboard, content, or NewClibpard failed;
  1578.             // just create a new, empty clipboard
  1579.             somSelf->DiscardClipboard(ev);
  1580.             somSelf->NewClipboard(ev);
  1581.         ENDTRY
  1582.         _fOriginalDraft = kODNULL;
  1583.         _fOriginalCloneKind = kODCloneCopy;
  1584.         _fClonePasteCount = 0;
  1585. #ifdef _PLATFORM_OS2_
  1586.                 WinCloseClipbrd( _fHab );
  1587. #endif
  1588.     }
  1589.     else if ( _fContainerHandle == (ODHandle) kODNULL )
  1590.     {
  1591.         // Open a new clipboard container if a container handle doesn't exist
  1592.         // This case can only happen after an error or after Clear() is called
  1593.         somSelf->NewClipboard(ev);
  1594.         _fOriginalDraft = kODNULL;
  1595.         _fOriginalCloneKind = kODCloneCopy;
  1596.         _fClonePasteCount = 0;
  1597.     }
  1598.     else
  1599.     {
  1600.         // reopen the container handle if necessary.
  1601.         if ( _fContainer == kODNULL )
  1602.             OpenClipboard(somSelf, ev);
  1603.         if ( _fOriginalDraft == kODNULL )
  1604.             _fOriginalDraft = GetOriginalDraft(ev, _fDraft);
  1605.     }
  1606.  
  1607.     return _fSU;
  1608. #if defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
  1609.         SOM_CATCH_ALL
  1610.     {
  1611. #ifdef _REPORT_SCRAP_ERRORS_
  1612.         WARNMSG_DEBUG(WARN_INDEX(-1),"ODClipboard: GetContentStorageUnit: Raising exception %d\n", ErrorCode());
  1613.         WARNMSG_DEBUG(WARN_INDEX(-1),"ODClipboard: Cannot create clipboard - error %ld",ErrorCode());
  1614. #endif
  1615.     }
  1616.         SOM_ENDTRY
  1617.     return kODNULL;
  1618. #endif
  1619. }
  1620.  
  1621. //------------------------------------------------------------------------------
  1622. // ODClipboard::ActionDone
  1623. //------------------------------------------------------------------------------
  1624.  
  1625. SOM_Scope ODUpdateID  SOMLINK ODClipboardActionDone(ODClipboard *somSelf, Environment *ev,
  1626.     ODCloneKind cloneKind)
  1627. {
  1628.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  1629.     ODClipboardMethodDebug("ODClipboard","ActionDone");
  1630.  
  1631.     ODUpdateID update = kODUnknownUpdate;
  1632.     
  1633.     SOM_TRY
  1634.  
  1635.         // Note that if the clipboard is changed by one OpenDoc document,
  1636.         // and used (via Paste) in another, the sequence of undo, redo, 
  1637.         // and paste actions is separate in each document. That is, the
  1638.         // first document is unaware of the Paste in the second document.
  1639.         // This isn't semantically correct, but doesn't cause errors [cc].
  1640.  
  1641.         if ( (cloneKind == kODCloneCut) || (cloneKind == kODCloneCopy) )
  1642.         {
  1643.             _fOriginalCloneKind = cloneKind;
  1644.             _fClonePasteCount = 0;
  1645.         }
  1646.         else if ( cloneKind == kODClonePaste )
  1647.         {
  1648.             _fClonePasteCount += 1;
  1649.         }
  1650.         else
  1651.             THROW(kODErrIllegalClipboardCloneKind);
  1652.  
  1653.         update = _fUpdateID;
  1654.     
  1655.     SOM_CATCH_ALL
  1656.     
  1657.     SOM_ENDTRY
  1658.     
  1659.     return update;
  1660. }
  1661.  
  1662. //------------------------------------------------------------------------------
  1663. // ODClipboard::ActionUndone
  1664. //------------------------------------------------------------------------------
  1665.  
  1666. SOM_Scope void  SOMLINK ODClipboardActionUndone(ODClipboard *somSelf, Environment *ev,
  1667.     ODUpdateID update,
  1668.     ODCloneKind originalCloneKind)
  1669. {
  1670.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  1671.     ODClipboardMethodDebug("ODClipboard","ActionUndone");
  1672.  
  1673.     SOM_TRY
  1674.  
  1675.         if ( update == _fUpdateID )
  1676.         {
  1677.             if ( originalCloneKind == kODCloneCut )
  1678.             {
  1679.                 SetOriginalCloneKind(ev, _fDraft, kODCloneCopy);
  1680.             }
  1681.             else if ( originalCloneKind == kODClonePaste )
  1682.             {
  1683.                 _fClonePasteCount -= 1;
  1684.                 if ( (_fClonePasteCount == 0) && (_fOriginalCloneKind == kODCloneCut) )
  1685.                     SetOriginalCloneKind(ev, _fDraft, kODCloneCut);
  1686.             }
  1687.             else if ( originalCloneKind != kODCloneCopy )
  1688.                 THROW(kODErrIllegalClipboardCloneKind);
  1689.         }
  1690.  
  1691.     SOM_CATCH_ALL
  1692.     
  1693.     SOM_ENDTRY
  1694. }
  1695.  
  1696. //------------------------------------------------------------------------------
  1697. // ODClipboard::ActionRedone
  1698. //------------------------------------------------------------------------------
  1699.  
  1700. SOM_Scope void  SOMLINK ODClipboardActionRedone(ODClipboard *somSelf, Environment *ev,
  1701.     ODUpdateID update,
  1702.     ODCloneKind originalCloneKind)
  1703. {
  1704.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  1705.     ODClipboardMethodDebug("ODClipboard","ActionRedone");
  1706.  
  1707.     SOM_TRY
  1708.  
  1709.         if ( update == _fUpdateID )
  1710.         {
  1711.             if ( originalCloneKind == kODCloneCut )
  1712.             {
  1713.                 SetOriginalCloneKind(ev, _fDraft, kODCloneCut);
  1714.             }
  1715.             else if ( originalCloneKind == kODClonePaste )
  1716.             {
  1717.                 _fClonePasteCount += 1;
  1718.                 if ( (_fClonePasteCount == 1) )
  1719.                     SetOriginalCloneKind(ev, _fDraft, kODCloneCopy);
  1720.             }
  1721.             else if ( originalCloneKind != kODCloneCopy )
  1722.                 THROW(kODErrIllegalClipboardCloneKind);
  1723.         }
  1724.  
  1725.     SOM_CATCH_ALL
  1726.     
  1727.     SOM_ENDTRY
  1728. }
  1729.  
  1730. //------------------------------------------------------------------------------
  1731. // ODClipboard::SetPlatformClipboard
  1732. //------------------------------------------------------------------------------
  1733.  
  1734. SOM_Scope void  SOMLINK ODClipboardSetPlatformClipboard(ODClipboard *somSelf, Environment *ev,
  1735.     ODPlatformTypeList* typeList)
  1736. {
  1737.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  1738.     ODClipboardMethodDebug("ODClipboard","SetPlatformClipboard");
  1739.     
  1740.     ODPlatformTypeList* requestedTypes = (ODPlatformTypeList*) kODNULL;
  1741.     ODVolatile(requestedTypes);
  1742.     
  1743. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1744.     short scrapCount = GetMacScrapCount();
  1745.  
  1746.     if ( (scrapCount == _fScrapCountLastChange) && (scrapCount == _fScrapCount) )
  1747.     {
  1748. #endif // MAC or AIX
  1749. #ifdef _PLATFORM_OS2_
  1750.                ODUpdateID updateID = GetPMUpdateID(_fHab);
  1751.  
  1752.                 if(!updateID || _fLastImportUpdateID != updateID) return;
  1753. #endif // _PLATFORM_OS2_
  1754.         SOM_TRY
  1755.         
  1756. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1757.             THROW_IF_ERROR(ForceZeroScrap());
  1758. #endif // MAC or AIX
  1759.  
  1760.             if ( _fSU != (ODStorageUnit*) kODNULL )
  1761.             {
  1762. #ifdef _PLATFORM_OS2_
  1763.                                 WinOpenClipbrd( _fHab );
  1764.                                 WinEmptyClipbrd( _fHab );
  1765. #endif // _PLATFORM_OS2_
  1766.                 if ( typeList )
  1767.                     requestedTypes = _fSession->GetStorageSystem(ev)->CreatePlatformTypeList(ev, typeList);
  1768.  
  1769.                 TRY
  1770.                     somSelf->ExportPlatformTypes(ev, requestedTypes);
  1771. #ifdef _PLATFORM_OS2_
  1772.                                         SetClipboardOwnership( somSelf, ev );
  1773.                                         _fLastImportUpdateID = _fUpdateID;
  1774. #endif // _PLATFORM_OS2_
  1775.                 CATCH_ALL
  1776. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1777.                     ZeroScrap();
  1778. #endif // MAC or AIX
  1779. #ifdef _PLATFORM_OS2_
  1780.                                         WinEmptyClipbrd( _fHab );
  1781. #endif // _PLATFORM_OS2_
  1782.                     RERAISE;
  1783.                 ENDTRY
  1784. #ifdef _PLATFORM_OS2_
  1785.                                 WinCloseClipbrd( _fHab );
  1786. #endif // _PLATFORM_OS2_
  1787.             }
  1788.  
  1789.         SOM_CATCH_ALL
  1790.         
  1791.         SOM_ENDTRY
  1792.  
  1793.         if ( requestedTypes )
  1794.             delete requestedTypes;
  1795.  
  1796. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1797.         // Since the scrap has only been partially updated, or an error has
  1798.         // occurred, we still need to remember to transfer everything later [cc]
  1799.         _fScrapCountLastChange = _fScrapCount = GetMacScrapCount();
  1800.     }
  1801. #endif // MAC or AIX
  1802. }
  1803.  
  1804. //------------------------------------------------------------------------------
  1805. // ODClipboard::ExportClipboard
  1806. //------------------------------------------------------------------------------
  1807. //
  1808. // Returns a SOM exception if setting the platform clipboard fails.
  1809. // Unfortunately, until the clipboard container is closed its size isn't known.
  1810.  
  1811. SOM_Scope void  SOMLINK ODClipboardExportClipboard(ODClipboard *somSelf, Environment *ev)
  1812. {
  1813.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  1814.     ODClipboardMethodDebug("ODClipboard","ExportClipboard");
  1815.     
  1816.     SOM_TRY 
  1817.     
  1818. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1819.         // If this clipboard was the last change to the platform scrap ("count == _fScrapCountLastChange"),
  1820.         // and this clipboard has not already been copied to the platform scrap
  1821.         // ("count == _fScrapCount"), update the platform scrap now. [cc]
  1822.         
  1823.         short count = GetMacScrapCount();
  1824. #endif // MAC or AIX
  1825.         
  1826. #ifdef _PLATFORM_OS2_
  1827. // aml - [146749]
  1828. // we need to figure out whether we should update the PM Clipboard
  1829.  
  1830.                 ODUpdateID updateID = GetPMUpdateID(_fHab);
  1831.                 if(_fLastImportUpdateID && _fLastImportUpdateID == updateID) {
  1832. //                    we've imported the clipboard, so we must have the latest changes
  1833.                 // rrk 20mar97 - if we are read-only, don't export a linkspec
  1834.                 ODWindow *window = _fSession->GetWindowState(ev)->AcquireActiveWindow(ev);
  1835.                 if(window) {
  1836.                    ODBoolean isDraftReadOnly = (window->GetDraft(ev)->GetPermissions(ev) == kODDPReadOnly);
  1837.                    //PRINT("ExportClipboard: isDraftReadOnly is %d.\n", isDraftReadOnly);
  1838.                    if (isDraftReadOnly)
  1839.               if ( _fSU->Exists(ev, kODPropLinkSpec, kODNULL, 0) )
  1840.                   ODSURemoveProperty(ev, _fSU, kODPropLinkSpec);
  1841.                    ODReleaseObject(ev,window);
  1842.                 }
  1843.         ODBoolean needToExportToRemoveLinkSpec = kODFalse;
  1844.             if ( _fExportedLinkSpec )
  1845.         {
  1846.             needToExportToRemoveLinkSpec = _fSU && !_fSU->Exists(ev, kODPropLinkSpec, kODNULL, 0);
  1847.         }
  1848.                    if((_fLastImportUpdateID == _fUpdateID) && !needToExportToRemoveLinkSpec) // we're in sync
  1849.                      return;
  1850.                 }
  1851.                 else return; // we don't own clipboard contents
  1852.  
  1853.                 WinOpenClipbrd( _fHab );
  1854.                 WinEmptyClipbrd( _fHab );
  1855. #endif // _PLATFORM_OS2_
  1856. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1857. #if ODDebugClipboard
  1858.         PRINT("ODClipboard::ExportClipboard called\n");
  1859.         if (count == _fScrapCountLastChange)
  1860.         {
  1861.             PRINT("ExportClipboard: OpenDoc clipboard contains last change\n");
  1862.             if ( count == _fScrapCount )
  1863.             {
  1864.                 PRINT("ExportClipboard: OpenDoc clipboard needs exporting");
  1865.                 if ( _fSU && _fSU->Exists(ev, kODPropLinkSpec, kODNULL, 0) )
  1866.                     PRINT(" (has link spec)");
  1867.                 PRINT("\n");
  1868.             }
  1869.             else if ( _fExportedLinkSpec && _fSU && !_fSU->Exists(ev, kODPropLinkSpec, kODNULL, 0) )
  1870.                 PRINT("ExportClipboard: OpenDoc clipboard needs exporting to remove link spec\n");
  1871.             else
  1872.                 PRINT("ExportClipboard: OpenDoc clipboard already copied to platform scrap\n");
  1873.         }
  1874. #endif
  1875. #endif // MAC or AIX
  1876.     
  1877. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1878.         ODBoolean needToExport = kODFalse;
  1879. #endif // MAC or AIX
  1880. #ifdef _PLATFORM_OS2_
  1881.                 // if we got this far in OS/2, we know we need to export the clipboard
  1882.         ODBoolean needToExport = kODTrue;
  1883. #endif // _PLATFORM_OS2_
  1884.         ODBoolean needToExportToRemoveLinkSpec = kODFalse;
  1885. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1886.         if  (count == _fScrapCountLastChange )
  1887.         {
  1888.             if ( count == _fScrapCount )
  1889.             {
  1890.                 needToExport = kODTrue;
  1891.                 _fExportedLinkSpec = _fSU && _fSU->Exists(ev, kODPropLinkSpec, kODNULL, 0);
  1892.             }
  1893.             else if ( _fExportedLinkSpec )
  1894.             {
  1895.                 needToExportToRemoveLinkSpec = _fSU && !_fSU->Exists(ev, kODPropLinkSpec, kODNULL, 0);
  1896.             }
  1897.         }
  1898. #endif // MAC or AIX
  1899. #ifdef _PLATFORM_OS2_
  1900.         _fExportedLinkSpec = _fSU && _fSU->Exists(ev, kODPropLinkSpec, kODNULL, 0);
  1901.                 if ( _fExportedLinkSpec )
  1902.             {
  1903.             needToExportToRemoveLinkSpec = _fSU && !_fSU->Exists(ev, kODPropLinkSpec, kODNULL, 0);
  1904.         }
  1905. #endif // _PLATFORM_OS2_
  1906.     
  1907.         // Immediately after changing the clipboard, _fOriginalDraft won't be set correctly
  1908.         // because the clipboard is not informed when a part is finished writing. [cc]
  1909.         if ( needToExport && (_fOriginalDraft == kODNULL) )
  1910.         {
  1911.             ASSERT(_fDraft != kODNULL, kODErrAssertionFailed);
  1912.             _fOriginalDraft = GetOriginalDraft(ev, _fDraft);
  1913.                 WASSERTMSG(_fOriginalDraft != kODNULL, "Last clipboard change did not clone", AMSG_861);
  1914.         }
  1915.     
  1916.         if ( needToExport || needToExportToRemoveLinkSpec )
  1917.         {
  1918. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1919.             // Copy the OpenDoc clipboard to the scrap
  1920.             THROW_IF_ERROR(ForceZeroScrap());
  1921.     
  1922.             // Optimistically load the scrap into memory if it was unloaded
  1923.             LoadScrap();
  1924. #endif // MAC or AIX
  1925.     
  1926.             TRY
  1927.                 somSelf->PutContentOnPlatformClipboard(ev);
  1928.                 somSelf->PutClipboardOnPlatformClipboard(ev);
  1929.                 
  1930. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1931.                 _fScrapCountLastChange = GetMacScrapCount();
  1932. #endif // MAC or AIX
  1933. #ifdef _PLATFORM_OS2_
  1934.                                 SetClipboardOwnership( somSelf, ev );
  1935.                                 _fLastImportUpdateID = _fUpdateID;     // [146749]
  1936. #endif // _PLATFORM_OS2_
  1937.             CATCH_ALL
  1938. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1939.                 // If writing the scrap fails, remove any scrap types written [cc]
  1940.                 ZeroScrap();
  1941. #endif // MAC or AIX
  1942. #ifdef _REPORT_SCRAP_ERRORS_
  1943.                 PRINT("ODClipboard::ExportClipboard failed; clearing scrap\n");
  1944. #endif
  1945.                 RERAISE;
  1946.             ENDTRY
  1947.  
  1948. #if ODDebugClipboard
  1949.             PRINT("ODClipboard::ExportClipboard updated the scrap, size is %ld\n", InfoScrap()->scrapSize);
  1950. #endif
  1951.         }
  1952.     
  1953.         // Exporting was successful
  1954.         if ( needToExportToRemoveLinkSpec )
  1955.             _fExportedLinkSpec = kODFalse;
  1956.  
  1957.     SOM_CATCH_ALL
  1958.  
  1959. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  1960.         // If we fail to update the scrap for any reason, ensure fScrapCountLastChanged
  1961.         // and fScrapCount equals the Mac scrap count, so we can try again later if 
  1962.         // no other cut or copy is attempted.
  1963.         _fScrapCountLastChange = _fScrapCount = GetMacScrapCount();
  1964. #endif // MAC or AIX
  1965.  
  1966. #if ODDebugClipboard
  1967.         PRINT("ODClipboard::ExportClipboard failed!\n");
  1968. #endif
  1969.  
  1970.     SOM_ENDTRY
  1971. #ifdef _PLATFORM_OS2_
  1972.         WinCloseClipbrd( _fHab );
  1973. #endif // _PLATFORM_OS2_
  1974.     
  1975. #if ODDebugClipboard
  1976.     PRINT("ODClipboard::ExportClipboard done, fExportedLinkSpec = %d\n", _fExportedLinkSpec);
  1977. #endif
  1978.  
  1979. }
  1980.  
  1981. //------------------------------------------------------------------------------
  1982. // ODClipboard::DraftClosing
  1983. //------------------------------------------------------------------------------
  1984. //
  1985. // Forces resolution of promises, and prevents moving content across draft closings
  1986. // via the clipboard. In order to work correctly, parts MUST use BeginClone-EndClone
  1987. // when writing to the clipboard.
  1988.  
  1989. SOM_Scope void  SOMLINK ODClipboardDraftClosing(ODClipboard *somSelf, Environment *ev,
  1990.         ODDraft* draft)
  1991. {
  1992.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  1993.     ODClipboardMethodDebug("ODClipboard","DraftClosing");
  1994.  
  1995. #if ODDebugClipboard
  1996.     PRINT("ODClipboard::DraftClosing called, draft is %x\n", draft);
  1997. #endif
  1998.  
  1999. #ifdef _PLATFORM_MACINTOSH_
  2000.     SOM_CATCH return;
  2001. #else
  2002.         SOM_TRY
  2003. #endif // _PLATFORM_MACINTOSH_
  2004.  
  2005.     if ( draft )
  2006.     {
  2007.         // Immediately after changing the clipboard, _fOriginalDraft won't be set correctly
  2008.         // because the clipboard is not informed when a part is finished writing.
  2009.     
  2010. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  2011.         short scrapCount = GetMacScrapCount();
  2012.         ODBoolean needToExport = (scrapCount == _fScrapCountLastChange) && (scrapCount == _fScrapCount);
  2013. #endif // MAC or AIX
  2014. #ifdef _PLATFORM_OS2_
  2015.                 ODUpdateID updateID = GetPMUpdateID(_fHab);
  2016. //                ODBoolean needToExport = (_fLastImportUpdateID != updateID) || (_fLastImportUpdateID != _fUpdateID); 
  2017.                 ODBoolean needToExport = (_fLastImportUpdateID && _fLastImportUpdateID != updateID); 
  2018. #endif // _PLATFORM_OS2_                                                    
  2019.         if ( needToExport && (_fOriginalDraft == kODNULL) )
  2020.         {
  2021.             ASSERT(_fDraft != kODNULL, kODErrAssertionFailed);
  2022.             _fOriginalDraft = GetOriginalDraft(ev, _fDraft);
  2023.             WASSERTMSG(_fOriginalDraft != kODNULL, "Last clipboard change did not clone", AMSG_861);
  2024.         }
  2025.     
  2026. #if ODDebugClipboard
  2027.         PRINT("Last draft to change clipboard is %x\n", _fOriginalDraft);
  2028. #endif
  2029.  
  2030.         if ( _fOriginalDraft == draft )
  2031.         {
  2032.             // Last draft that wrote the clipboard is being closed.
  2033.  
  2034. #if ODDebugClipboard
  2035.             PRINT("ODClipboard::Draft that last wrote clipboard is closing\n", draft);
  2036.             if ( needToExport )
  2037.                 PRINT("ODClipboard::Clipboard needs exporting\n");
  2038. #endif
  2039.             // If the clipboard container is open, force resolution of promises 
  2040.             // by externalizing the clipboard draft. (If there are unresolved promises, 
  2041.             // the clipboard hasn't be exported yet). Otherwise open the container.
  2042.  
  2043.             if ( _fContainer )
  2044.                 _fDraft->Externalize(ev);
  2045.             else
  2046. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  2047.                 OpenClipboard(somSelf, ev);
  2048. #endif // MAC or AIX
  2049. #ifdef _PLATFORM_OS2_
  2050.                         {
  2051.                 OpenClipboard(somSelf, ev);
  2052.                                 somSelf->ResolvePMPromises(ev);
  2053.                         }
  2054. #endif // _PLATFORM_OS2_
  2055.  
  2056.             // Remove a link spec if present
  2057.                 if ( _fSU->Exists(ev, kODPropLinkSpec, kODNULL, 0) ) {
  2058.                ODSURemoveProperty(ev, _fSU, kODPropLinkSpec);
  2059.                        _fUpdateID = _fNextUpdateID;
  2060.                        _fNextUpdateID = _fSession->UniqueUpdateID(ev);
  2061.                         }
  2062.  
  2063.             // Check to see if content was cut (not copied) to the clipboard.
  2064.             // If so, change the original clone kind to copy, so any future
  2065.             // paste won't be treated as a move.
  2066.                         
  2067.             if ( GetOriginalCloneKind(ev, _fDraft) == kODCloneCut )
  2068.             {
  2069.                 SetOriginalCloneKind(ev, _fDraft, kODCloneCopy);
  2070. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  2071.                 // Force exporting to platform clipboard
  2072.                 _fScrapCountLastChange = _fScrapCount = GetMacScrapCount();
  2073. #endif // MAC or AIX
  2074. #if defined (_PLATFORM_OS2_)
  2075.                 // Force exporting to platform clipboard
  2076.                             _fUpdateID = _fNextUpdateID;
  2077.                             _fNextUpdateID = _fSession->UniqueUpdateID(ev);
  2078. #endif // MAC or AIX
  2079.             }
  2080.                         somSelf->ExportClipboard(ev);
  2081.             _fOriginalDraft = kODNULL;
  2082.         }
  2083.     }
  2084. #if defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
  2085.         SOM_CATCH_ALL
  2086.         SOM_ENDTRY
  2087.           return;
  2088. #endif
  2089. }
  2090.  
  2091. //------------------------------------------------------------------------------
  2092. // ODClipboard::DraftSaved
  2093. //------------------------------------------------------------------------------
  2094. //
  2095.  
  2096. SOM_Scope void  SOMLINK ODClipboardDraftSaved(ODClipboard *somSelf, Environment *ev,
  2097.         ODDraft* draft)
  2098. {
  2099.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  2100.     ODClipboardMethodDebug("ODClipboard","DraftSaved");
  2101.  
  2102. #if ODDebugClipboard
  2103.     PRINT("ODClipboard::DraftSaved called, draft %08x, orig %08x, fDraft %08x\n", 
  2104.         (long) draft, (long) _fOriginalDraft, (long) _fDraft);
  2105. #endif
  2106.  
  2107. #ifdef _PLATFORM_MACINTOSH_
  2108.     SOM_CATCH return;
  2109. #else
  2110.         SOM_TRY
  2111. #endif // _PLATFORM_MACINTOSH_
  2112.     
  2113.     // ODDraft* tDraft = _fDraft;
  2114.     // ODDraft* tOriginalDraft = _fOriginalDraft;
  2115.     
  2116.     if ( draft )
  2117.     {
  2118.         if ( _fOriginalDraft == kODNULL )
  2119.         {
  2120.             if (_fDraft != kODNULL)        // can be null if never accessed
  2121.                 _fOriginalDraft = GetOriginalDraft(ev, _fDraft);
  2122.  
  2123. #if ODDebugClipboard
  2124.     PRINT("    ODClipboard::DraftSaved orig %08x\n", 
  2125.         (long) _fOriginalDraft);
  2126. #endif
  2127.         }
  2128.  
  2129.         if ( _fOriginalDraft == draft && _fDraft )
  2130.         {
  2131.             // Check to see if content was cut (not copied) to the clipboard.
  2132.             // If so, change the original clone kind to copy, so any future
  2133.             // paste won't be treated as a move.
  2134.  
  2135. #if ODDebugClipboard
  2136.             PRINT("        ODClipboard::DraftSaved try cut -> copy\n");
  2137. #endif
  2138.                         
  2139.             if ( GetOriginalCloneKind(ev, _fDraft) == kODCloneCut )
  2140.             {
  2141.                 SetOriginalCloneKind(ev, _fDraft, kODCloneCopy);
  2142.  
  2143. #if ODDebugClipboard
  2144.                 PRINT("            ODClipboard::DraftSaved perform cut -> copy\n");
  2145. #endif
  2146.             }
  2147.         }
  2148.     }
  2149. #if defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
  2150.         SOM_CATCH_ALL
  2151.         SOM_ENDTRY
  2152.           return;
  2153. #endif
  2154. }
  2155.  
  2156. //------------------------------------------------------------------------------
  2157. // ODClipboard::ShowPasteAsDialog
  2158. //------------------------------------------------------------------------------
  2159.  
  2160. SOM_Scope ODBoolean  SOMLINK ODClipboardShowPasteAsDialog(ODClipboard *somSelf, Environment *ev,
  2161.         ODBoolean canPasteLink,
  2162.         ODPasteAsMergeSetting mergeSetting,
  2163.         ODFacet* facet,
  2164.         ODTypeToken viewType,
  2165.         ODPasteAsResult* result)
  2166. {
  2167.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  2168.     ODClipboardMethodDebug("ODClipboard","ShowPasteAsDialog");
  2169.  
  2170.     ODBoolean returnValue = kODFalse;
  2171.  
  2172. #ifdef _PLATFORM_MACINTOSH_
  2173.     SOM_CATCH return kODFalse;
  2174. #else
  2175.         SOM_TRY
  2176. #endif // _PLATFORM_MACINTOSH_
  2177.  
  2178.     THROW_IF_NULL(facet, kODErrNullFacetInput);
  2179.     THROW_IF_NULL(result, kODErrNullPasteAsResultInput);
  2180.  
  2181.     ODTypeToken modalFocus = _fSession->Tokenize(ev, kODModalFocus);
  2182.     ODArbitrator* arbitrator = _fSession->GetArbitrator(ev);
  2183.     TempODFrame currentOwner = arbitrator->AcquireFocusOwner(ev, modalFocus);
  2184.  
  2185.     if ( arbitrator->RequestFocus(ev, modalFocus, facet->GetFrame(ev)) )
  2186.     {
  2187.         ODStorageUnit* clipContentSU = somSelf->GetContentStorageUnit(ev);
  2188.     
  2189.         ODBoolean isMove = (GetOriginalCloneKind(ev, clipContentSU->GetDraft(ev)) == kODCloneCut);
  2190.  
  2191.         returnValue = ShowPasteAsDialog(
  2192.                                 canPasteLink, 
  2193.                                 mergeSetting,
  2194.                                 isMove,
  2195.                                 clipContentSU,
  2196.                                 facet, 
  2197.                                 viewType, 
  2198.                                 result);
  2199.  
  2200.         arbitrator->TransferFocus(ev, modalFocus, facet->GetFrame(ev), currentOwner);
  2201.     }
  2202.     else
  2203.     {
  2204. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  2205.         SysBeep(2);
  2206. #endif // MAC or AIX
  2207. #ifdef _PLATFORM_OS2_
  2208.                 WinAlarm(HWND_DESKTOP, WA_ERROR);
  2209. #endif
  2210.     }
  2211. #if defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
  2212.         SOM_CATCH_ALL
  2213.           returnValue =  kODFalse;
  2214.         SOM_ENDTRY
  2215.     return returnValue;
  2216. #endif
  2217. }
  2218.  
  2219. #ifdef _PLATFORM_OS2_
  2220. /*---------------------------------------------------------------------------
  2221.         ODClipboard::DeregisterClipboardFormat
  2222. ---------------------------------------------------------------------------*/
  2223. SOM_Scope ODBoolean SOMLINK ODClipboardDeregisterClipboardFormat(
  2224.                                 ODClipboard *somSelf,
  2225.                                 Environment *ev,
  2226.                                 ODType theISOType )
  2227. {
  2228.    ODClipboardData *somThis = ODClipboardGetData(somSelf);
  2229.    ODClipboardMethodDebug("ODClipboard","DeregisterClipboardFormat");
  2230.  
  2231.    OrderedCollectionIterator * iter = kODNULL;
  2232.    ODBoolean result = kODFalse;
  2233.  
  2234.    //ODBeginTryBlock;
  2235.  
  2236. #if ODDebugClipboard
  2237.    somPrintf( "ODClipboard::DeregisterClipboardFormat\n" );
  2238. #endif
  2239.  
  2240.    iter = _fTypeCollection->CreateIterator();
  2241.    CLIPBOARDTYPEINFO *pclipboardTypeInfo;
  2242.  
  2243.    try {
  2244.       for ( pclipboardTypeInfo = (CLIPBOARDTYPEINFO *)iter->First();
  2245.             iter->IsNotComplete();
  2246.             pclipboardTypeInfo = (CLIPBOARDTYPEINFO *)iter->Next())
  2247.          {
  2248.          if ( !strcmp(pclipboardTypeInfo->opendocType, theISOType ))
  2249.             {
  2250.             if ( pclipboardTypeInfo->deletable == kODTrue )
  2251.                {
  2252.                delete [] pclipboardTypeInfo->opendocType;
  2253.                _fTypeCollection->Remove( pclipboardTypeInfo );
  2254.                result = kODTrue;
  2255.                }
  2256.             break;
  2257.             }
  2258.          }
  2259.  
  2260.         } catch( ... ) {
  2261. #if ODDebugClipboard
  2262.       somPrintf( "ODClipboard::DeregisterClipboardFormat - SOM EXCEPTION THROWN\n" );
  2263. #endif
  2264.       result = kODFalse;
  2265.    }
  2266.  
  2267.    delete iter;
  2268.  
  2269.    //ODExitTryBlock;
  2270.    return( result );
  2271. /*
  2272. OnException:
  2273.  
  2274.    if (iter != kODNULL) delete iter;
  2275.  
  2276. #if ODDebugClipboard
  2277.    somPrintf( "ODClipboard::DeregisterClipboardFormat - OS2 EXCEPTION THROWN\n" );
  2278. #endif
  2279.    ODLogError( SEVERITY_WARNING, PMERR_INVALID_PARAMETER );
  2280.    return( result );
  2281. */
  2282. }
  2283.  
  2284. /*---------------------------------------------------------------------------
  2285.         ODClipboard::DispatchHandler
  2286.  
  2287.         This method is unique to OS/2. It was introduced to facilitate
  2288.         delayed rendering of the Opendoc clipboard. This method is called
  2289.         from the dispatcher when an WM_RENDERFMT message is encountered.
  2290. ---------------------------------------------------------------------------*/
  2291. SOM_Scope ODBoolean SOMLINK ODClipboardDispatchHandler(
  2292.                                 ODClipboard     *somSelf,
  2293.                                 Environment     *ev,
  2294.                                 ODEventData     *event )
  2295. {
  2296.    ODClipboardData *somThis = ODClipboardGetData( somSelf );
  2297.    ODClipboardMethodDebug( "ODClipboard","ODClipboardDispatchHandler" );
  2298.  
  2299. #if ODDebugClipboard
  2300.    somPrintf( "ODClipboard::DispatchHandler\n" );
  2301. #endif
  2302.  
  2303.    ODBoolean result = kODTrue;
  2304.  
  2305.    TRY
  2306.       if ( event->msg != WM_RENDERFMT )
  2307.       {
  2308.          // we shouldn't get here - only WM_RENDERFMT msgs are forwarded.
  2309. #if ODDebugClipboard
  2310.          somPrintf( "ODClipboard::DispatchHandler"
  2311.                   " - Warning: msg not WM_RENDERFMT" );
  2312. #endif
  2313.          result = kODFalse;
  2314.       }
  2315.       else
  2316.       {
  2317. /* [146749] - aml - we cannot use this any more...
  2318.          ODPart *part = _fClipboardOwner;
  2319.          if (kODNULL == part)
  2320.          {
  2321.             // we shouldn't get here - the "giving" part can't be found
  2322. #if ODDebugClipboard
  2323.             somPrintf( "ODClipboard::DispatchHandler"
  2324.                      " - Warning: _fClipboardOwner is null\n" );
  2325. #endif
  2326.          }
  2327.          else
  2328.          {
  2329. */
  2330. // [146569] start
  2331. /*
  2332.             // borrow from the drag & drop stuff, to build a storage unit we
  2333.             // can pass along to the part...
  2334.             ODMemDragItem  *newItem = kODNULL;
  2335.             newItem = new(ODGetDefaultHeap())
  2336.                      ODMemDragItem(_fSession->GetStorageSystem( ev ), kODFalse);
  2337.             if ( kODNULL == newItem )
  2338.             {
  2339.                                         // out of memory
  2340. #if ODDebugClipboard
  2341.                somPrintf( "ODClipboard::DispatchHandler"
  2342.                         " - Error: can't alloc newItem\n" );
  2343. #endif
  2344.             }
  2345.             else
  2346.             {
  2347.                newItem->Initialize(ev);
  2348.  
  2349.                // set up the storage unit view for the part to fulfill
  2350.                ODStorageUnit *su = newItem->fSU;
  2351.                su->AddProperty(ev, kODPropContents);
  2352.                PSZ type = _fSession->GetTranslation(ev)->GetISOTypeFromPlatformType(ev, (ODULong)event->mp1, kODPlatformDataType );
  2353. //               PSZ type = GetISOTypeFromPlatformType( somSelf, (ODULong)event->mp1 );
  2354.                su->AddValue( ev, type );
  2355.                                         ODStorageUnitView *destSUView = su->CreateView(ev);
  2356. #if ODDebugClipboard
  2357.                somPrintf( "ODClipboard::DispatchHandler"
  2358.                         " - About to call FulfillPromise type(%s)\n", type );
  2359. #endif
  2360.                (part)->FulfillPromise( ev, destSUView );
  2361. */
  2362.                if(!_fSU && _fContainerHandle) {
  2363.                        OpenClipboard(somSelf, ev);
  2364.                }
  2365.                else if(!_fSU) return result;
  2366.                PSZ theISOType = _fSession->GetTranslation(ev)->GetISOTypeFromPlatformType(ev, (ODULong)event->mp1, kODPlatformDataType);
  2367.                if (theISOType != (ODType) kODNULL &&
  2368.                    ODSUExistsThenFocus(ev,_fSU,kODPropContents,(ODValueType)theISOType))
  2369.                {
  2370.                  ODStorageUnitView *destSUView = _fSU->CreateView(ev);
  2371.                  if(_fSU->IsPromiseValue(ev)) {
  2372.                    ODByteArray ba;  // [146749]
  2373.                    ODPart *sourcePart;
  2374.                    _fSU->GetPromiseValue(ev, (ODValueType)theISOType,
  2375.                                         0, 0, &ba, &sourcePart );
  2376.                    sourcePart->FulfillPromise( ev, destSUView );
  2377.                  }
  2378.  
  2379.                  ODPlatformType ulType = (ODPlatformType)event->mp1;
  2380.                  ODULong flag = GetFormatInfo(somSelf,ulType);
  2381.  
  2382.                  if(flag == CFI_HANDLE)
  2383.                  {
  2384.                      ULONG handle = NULLHANDLE;
  2385.  
  2386.                      if(!(handle = GetDataHandle(ev, _fSU))) {  // [146749]
  2387.                        destSUView->SetOffset( ev, 0 );
  2388.                        StorageUnitViewGetValue(destSUView, ev,
  2389.                            sizeof( ULONG ), (ODValue) &handle);
  2390.                      }
  2391.                      result = WinSetClipbrdData( _fHab, (ULONG)handle,
  2392.                                                  ulType, CFI_HANDLE );
  2393. //                     _fArePromises = kODTrue;
  2394. #if ODDebugClipboard
  2395.                      somPrintf( "ODClipboard::DispatchHandler"
  2396.                               " - result(%d) = WinSetClipbdData( handle(%lX) )\n",
  2397.                                            result, handle );
  2398. #endif
  2399.                  }
  2400.                  else  // if(flag == CFI_POINTER)
  2401.                  {
  2402.                      ULONG dataSize = destSUView->GetSize(ev);
  2403.                      PBYTE  pbData = kODNULL;
  2404.                      APIRET rc = DosAllocSharedMem( (PPVOID)&pbData, 0L,
  2405.                                       dataSize,
  2406.                                       PAG_READ | PAG_WRITE | PAG_COMMIT |
  2407.                                       OBJ_GIVEABLE | OBJ_GETTABLE | OBJ_TILE );
  2408.                      if ( kODNULL == rc )
  2409.                         {
  2410.                         destSUView->SetOffset( ev, 0 );
  2411.                         StorageUnitViewGetValue(destSUView, ev,
  2412.                               dataSize, (ODValue) pbData);
  2413.  
  2414.                         WinSetClipbrdData( _fHab, (ULONG)pbData,
  2415.                                                                                                                  (ODULong)event->mp1, CFI_POINTER );
  2416. #if ODDebugClipboard
  2417.                         somPrintf( "ODClipboard::DispatchHandler"
  2418.                                  " - result(%d) = WinSetClipbdData( pointer(%p) )\n",
  2419.                                            result, pbData );
  2420. #endif
  2421.                         }
  2422.                      // the free of pbData is done for us by PM...
  2423. //                     break;
  2424.                  }
  2425.  
  2426. //               delete destSUView;
  2427. //               delete newItem;
  2428.                }
  2429. //            }           // newItem
  2430. //         }              // part   [146749]
  2431.       }                 // WM_RENDERFMT
  2432.  
  2433.         CATCH_ALL
  2434. #if ODDebugClipboard
  2435.       somPrintf( "ODClipboard::DispatchHandler - SOM EXCEPTION THROWN\n" );
  2436. #endif
  2437.    ENDTRY
  2438.  
  2439.    return result;      // handled
  2440. }
  2441.  
  2442. /*---------------------------------------------------------------------------
  2443.         ODClipboard::QueryContent
  2444. ---------------------------------------------------------------------------*/
  2445. SOM_Scope void  SOMLINK ODClipboardQueryContent(
  2446.                                 ODClipboard *somSelf,
  2447.                                 Environment *ev,
  2448.                                 ODTypeList *typeList)
  2449. {
  2450.    ODClipboardData *somThis = ODClipboardGetData(somSelf);
  2451.    ODClipboardMethodDebug("ODClipboard","QueryContent");
  2452.  
  2453. #if ODDebugClipboard
  2454.    somPrintf( "ODClipboard::QueryContent\n" );
  2455. #endif
  2456.  
  2457.    typeList->InitTypeList(ev,kODNULL);
  2458.    ODType    theISOType;
  2459.    TRY
  2460.  
  2461.       ODUpdateID updateID = GetPMUpdateID(_fHab);
  2462.       if(updateID && updateID == _fLastImportUpdateID && _fContainerHandle) {
  2463.          if(!_fSU )
  2464.              OpenClipboard(somSelf, ev);
  2465.          if(!ODSUExistsThenFocus(ev,_fSU,kODPropContents,kODNULL)) return;
  2466.          ODULong count = _fSU->CountValues(ev);
  2467.          for (ODULong index = 1; index <= count;index++)
  2468.          {
  2469.             _fSU->Focus(ev, kODPropContents, kODPosUndefined, 0, index,
  2470.                                 kODPosUndefined);
  2471.             theISOType = _fSU->GetType(ev);
  2472.             if (theISOType != (ODType) kODNULL)
  2473.             {
  2474.                typeList->AddLast(ev,theISOType);
  2475.             }
  2476.          }
  2477.          return;
  2478.       }
  2479.       ResType theType, thePrevType = 0;
  2480.       while ( (theType = WinEnumClipbrdFmts( _fHab, thePrevType)) != 0 )
  2481.       {
  2482.          long    scrapTypeLength;
  2483.          ODULong  realOffset;
  2484.  
  2485.          if(theType == CF_OPENDOCDOCUMENT) typeList->AddLast(ev,kCF_OPENDOCDOCUMENT); // [145019]
  2486.          else {
  2487.            theISOType = _fSession->GetTranslation(ev)->GetISOTypeFromPlatformType(ev, theType, kODPlatformDataType );
  2488.            if (theISOType != (ODType) kODNULL)
  2489.            {
  2490.                typeList->AddLast(ev,theISOType);
  2491.            }
  2492.          }
  2493.          thePrevType = theType;
  2494.       }
  2495.  
  2496.     CATCH_ALL
  2497. #if ODDebugClipboard
  2498.       somPrintf( "ODClipboard::QueryContent - SOM EXCEPTION THROWN\n" );
  2499. #endif
  2500.       RERAISE;
  2501.    ENDTRY
  2502.  
  2503. }
  2504.  
  2505. /*---------------------------------------------------------------------------
  2506.         ODClipboard::CanEmbed
  2507. ---------------------------------------------------------------------------*/
  2508. SOM_Scope ODBoolean  SOMLINK ODClipboardCanEmbed(
  2509.                                 ODClipboard *somSelf,
  2510.                                 Environment *ev)
  2511. {
  2512. //   CHAR typeList[CCHMAXPATH];
  2513.    ODType theType;
  2514.    ODBoolean result = kODFalse;
  2515.    ODTypeList* typeList = new ODTypeList();
  2516.    somSelf->QueryContent(ev,typeList);
  2517.    if(!typeList->Count(ev)) {
  2518.       delete typeList;
  2519.       return kODFalse;
  2520.    }
  2521. //#ifdef LATER
  2522.    RegistryManager* registrationMgr;
  2523.    registrationMgr = new RegistryManager;
  2524.    ODPartHandlerRegistry* odRegistry;
  2525.    odRegistry = registrationMgr->GetODPartHandlerRegistry( ev);
  2526.    ODTypeListIterator* iter = typeList->CreateTypeListIterator(ev);
  2527.    for(theType = iter->First(ev); iter->IsNotComplete(ev); theType = iter->Next(ev))
  2528.    {
  2529.       if(strcmp((PSZ)theType, kCF_OPENDOCDOCUMENT) == 0) result = kODTrue;
  2530.       else if(theType[0]) {
  2531.          _IDL_SEQUENCE_ISOString partHandlerList = odRegistry->GetPartHandlerList( ev,theType, 0) ;
  2532.          if ( partHandlerList. _length ) {
  2533.             result = kODTrue;
  2534.          }
  2535.          for ( int i = 0; i < partHandlerList. _length; i++)
  2536.          {
  2537.               SOMFree( partHandlerList. _buffer[i]);
  2538.          }
  2539.          SOMFree( partHandlerList. _buffer);
  2540.       }
  2541.       if(result) break;
  2542.    }
  2543.    ODDeleteObject(iter);
  2544.    ODDeleteObject(typeList);
  2545.    return result;
  2546. //#else
  2547. //   return kODFalse;
  2548. //#endif // LATER
  2549. }
  2550.  
  2551.  
  2552. /*---------------------------------------------------------------------------
  2553.         ODClipboard::CanIncorporate
  2554. ---------------------------------------------------------------------------*/
  2555. SOM_Scope ODBoolean  SOMLINK ODClipboardCanIncorporate(
  2556.                                 ODClipboard *somSelf,
  2557.                                 Environment *ev,
  2558.                                 ODType kind)
  2559. {
  2560.    ODClipboardData *somThis = ODClipboardGetData(somSelf);
  2561.    ODClipboardMethodDebug("ODClipboard","CanIncorporate");
  2562.  
  2563.    ULONG fmtInfo;
  2564.    ULONG fmt;
  2565.    ODBoolean result = kODFalse;;
  2566.  
  2567.    TRY
  2568.    ODUpdateID updateID = GetPMUpdateID(_fHab);
  2569.    if(updateID && _fLastImportUpdateID == updateID) {
  2570.         // this clipboard SU is up-to-date, check its kODPropContents
  2571.             if ( !_fSU && _fContainerHandle )
  2572.                    OpenClipboard(somSelf, ev);
  2573.             else return kODFalse;
  2574.             return(_fSU->Exists(ev, kODPropContents, kind, 0));
  2575.    }
  2576.    if (!ScrapHasData() ) return kODFalse;
  2577.    fmt = _fSession->GetTranslation(ev)->GetPlatformTypeFromISOType(ev, kind);
  2578.    if(fmt) result = WinQueryClipbrdFmtInfo(_fHab, fmt, &fmtInfo);
  2579.    else {
  2580.      // may be an OpenDoc kind
  2581.      if(WinQueryClipbrdFmtInfo(_fHab, CF_OPENDOCDOCUMENT, &fmtInfo)) {
  2582.        if(!WinOpenClipbrd(_fHab)) return kODFalse;
  2583.        somSelf->DiscardClipboard(ev);
  2584.        if(!somSelf->ImportClipboard(ev)) {
  2585.            somSelf->NewClipboard(ev);
  2586.        }
  2587.        somSelf->ImportContent(ev);
  2588.        _fLastImportUpdateID = updateID;
  2589.        if(!_fLastImportUpdateID) {
  2590.            _fLastImportUpdateID = _fSession->UniqueUpdateID(ev);
  2591.            WinSetClipbrdData( _fHab, _fLastImportUpdateID, CF_OPENDOCOWNERID, CFI_HANDLE );
  2592.        }
  2593.        _fUpdateID = _fLastImportUpdateID;
  2594.        WinCloseClipbrd(_fHab);
  2595.        if(_fSU)
  2596.          result = _fSU->Exists(ev, kODPropContents, kind, 0);
  2597.      }
  2598.    }
  2599.     CATCH_ALL
  2600. #if ODDebugClipboard
  2601.       somPrintf( "ODClipboard::CanIncorporate - SOM EXCEPTION THROWN\n" );
  2602. #endif
  2603.       RERAISE;
  2604.    ENDTRY
  2605.    return result;
  2606. }
  2607.  
  2608. /*---------------------------------------------------------------------------
  2609.         ODClipboard::RegisterClipboardFormat
  2610. ---------------------------------------------------------------------------*/
  2611. SOM_Scope ODBoolean SOMLINK ODClipboardRegisterClipboardFormat(
  2612.                                 ODClipboard *somSelf,
  2613.                                 Environment *ev,
  2614.                                 ODType theISOType,
  2615.                                 ODPlatformType platformType,
  2616.                                 ODULong formatInfo )
  2617. {
  2618.    ODClipboardData *somThis = ODClipboardGetData(somSelf);
  2619.    ODClipboardMethodDebug("ODClipboard","RegisterClipboardFormat");
  2620.  
  2621.    OrderedCollectionIterator * iter = kODNULL;
  2622.    ODBoolean result = kODTrue;
  2623.  
  2624.    //ODBeginTryBlock;
  2625.  
  2626.    iter = _fTypeCollection->CreateIterator();
  2627.    CLIPBOARDTYPEINFO *pclipboardTypeInfo;
  2628.  
  2629.    try {
  2630.       for ( pclipboardTypeInfo = (CLIPBOARDTYPEINFO *)iter->First();
  2631.             iter->IsNotComplete();
  2632.             pclipboardTypeInfo = (CLIPBOARDTYPEINFO *)iter->Next())
  2633.          {
  2634.          // if it's not unique, bail out
  2635.          if ( !strcmp(pclipboardTypeInfo->opendocType, theISOType ) ||
  2636.               pclipboardTypeInfo->platformType == platformType )
  2637.             {
  2638.             result = kODFalse;
  2639.             break;
  2640.             }
  2641.          }
  2642.  
  2643.       delete iter;
  2644.  
  2645.       if ( result == kODTrue )
  2646.          {
  2647.          pclipboardTypeInfo = new CLIPBOARDTYPEINFO;
  2648.  
  2649.          pclipboardTypeInfo->opendocType = new char[ strlen( theISOType ) + 1 ];
  2650.          strcpy( pclipboardTypeInfo->opendocType, theISOType );
  2651.          pclipboardTypeInfo->platformType = platformType;
  2652.          pclipboardTypeInfo->formatInfo = formatInfo;
  2653.          pclipboardTypeInfo->deletable = kODTrue;
  2654.  
  2655.          _fTypeCollection->AddLast(pclipboardTypeInfo);
  2656.          }
  2657.    } catch( ... ) {
  2658.  
  2659. #if ODDebugClipboard
  2660.       somPrintf( "ODClipboard::RegisterClipboardFormat - SOM EXCEPTION THROWN\n" );
  2661. #endif
  2662.       result = kODFalse;
  2663.  
  2664.    }
  2665.  
  2666.    //ODExitTryBlock;
  2667.    return( result );
  2668.  
  2669. /*
  2670. OnException:
  2671. #if ODDebugClipboard
  2672.    somPrintf( "ODClipboard::RegisterClipboardFormat - OS2 EXCEPTION THROWN\n" );
  2673. #endif
  2674.    ODLogError( SEVERITY_WARNING, PMERR_INVALID_PARAMETER );
  2675.    return( kODFalse );
  2676. */
  2677. }
  2678.  
  2679. // [146749]
  2680. /*---------------------------------------------------------------------------
  2681.         ODClipboard::ResolvePMPromises
  2682. ---------------------------------------------------------------------------*/
  2683. SOM_Scope void SOMLINK ODClipboardResolvePMPromises(
  2684.                                 ODClipboard *somSelf,
  2685.                                 Environment *ev)
  2686. {
  2687.    ODClipboardData *somThis = ODClipboardGetData(somSelf);
  2688.    ODClipboardMethodDebug("ODClipboard","ResolvePMPromises");
  2689.  
  2690.    ODUpdateID updateID = somSelf->GetUpdateID(ev);
  2691.    if(updateID != _fUpdateID || !_fArePromises) return;
  2692.    WinOpenClipbrd( _fHab );
  2693.    USHORT usFormat = 0;
  2694.    while ( usFormat = (USHORT) WinEnumClipbrdFmts( _fHab, usFormat ) )
  2695.         WinQueryClipbrdData( _fHab,  usFormat);
  2696.    WinCloseClipbrd( _fHab );
  2697.    _fArePromises = kODFalse;
  2698. }
  2699. #endif
  2700. //==============================================================================
  2701. // Local Functions
  2702. //==============================================================================
  2703.  
  2704. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  2705. //------------------------------------------------------------------------------
  2706. // GetMacScrapCount
  2707. //------------------------------------------------------------------------------
  2708. //
  2709. // This function returns the identification stamp of the last mac scrap change,
  2710. // NOT the count of items on the scrap!
  2711.  
  2712. ODStatic short GetMacScrapCount()
  2713. {
  2714.     return InfoScrap()->scrapCount;
  2715. }
  2716.  
  2717. //------------------------------------------------------------------------------
  2718. // IsFrontProcess
  2719. //------------------------------------------------------------------------------
  2720.  
  2721. ODStatic ODBoolean IsFrontProcess()
  2722. {
  2723.     ProcessSerialNumber psnFront, psnMine;
  2724.     ODBoolean frontmost;
  2725.  
  2726.     GetFrontProcess(&psnFront);
  2727.     GetCurrentProcess(&psnMine);
  2728.     SameProcess(&psnFront, &psnMine, &frontmost);
  2729.  
  2730.     return frontmost;
  2731. }
  2732.  
  2733. //------------------------------------------------------------------------------
  2734. // ImportStyledTextType
  2735. //------------------------------------------------------------------------------
  2736.  
  2737. ODStatic void ImportStyledTextType(ODClipboard *somSelf, Environment *ev)
  2738. {
  2739.     ODClipboardData *somThis = ODClipboardGetData(somSelf);
  2740.  
  2741.     ODHandle    hndl = kODNULL;
  2742.     ODValue        value;
  2743.     long        dummy;
  2744.  
  2745.     ODVolatile(hndl);
  2746.     ODVolatile(somSelf);
  2747.     ODVolatile(somThis);
  2748.     ODVolatile(ev);
  2749.  
  2750.     SOM_CATCH
  2751.     {
  2752.         if ( ODSUExistsThenFocus(ev, _fSU, kODPropContents, kODApplestxt) )
  2753.             _fSU->Remove(ev);
  2754.  
  2755.         ODDisposeHandle(hndl);
  2756.         return;
  2757.     }
  2758.     
  2759.     // Make sure both 'TEXT' and 'styl' are present
  2760.     ODULong sizeText = GetScrap(nil, 'TEXT', &dummy);
  2761.     ODULong sizeStyl = GetScrap(nil, 'styl', &dummy);
  2762.     
  2763.     if ( (sizeText < 0) || (sizeStyl < 0) )
  2764.         return;
  2765.  
  2766.     if ( ODSUExistsThenFocus(ev, _fSU, kODPropContents, kODApplestxt) )
  2767.     {
  2768. #ifdef _REPORT_SCRAP_ERRORS_
  2769.         WARN("ODClipboard: Replacing value on clipboard");
  2770. #endif
  2771.         _fSU->Remove(ev);
  2772.     }
  2773.     
  2774.     ODSUForceFocus(ev, _fSU, kODPropContents, kODApplestxt);
  2775.  
  2776.     hndl = ODNewHandle(sizeStyl);
  2777.     
  2778.     sizeStyl = GetScrap((Handle) hndl, 'styl', &dummy);
  2779.     if ( sizeStyl < 0 )
  2780.         THROW(sizeStyl);
  2781.  
  2782.     value = (ODValue) ODLockHandle(hndl);
  2783.     StorageUnitSetValue(_fSU, ev, sizeStyl, value);
  2784.     ODUnlockHandle(hndl);
  2785.     ODDisposeHandle(hndl);
  2786.     hndl = kODNULL;
  2787.  
  2788.     hndl = ODNewHandle(sizeText);
  2789.  
  2790.     sizeText = GetScrap((Handle) hndl, 'TEXT', &dummy);
  2791.     if ( sizeText < 0 )
  2792.         THROW(sizeText);
  2793.     
  2794.     value = (ODValue) ODLockHandle(hndl);
  2795.     StorageUnitSetValue(_fSU, ev, sizeText, value);
  2796.     ODUnlockHandle(hndl);
  2797.  
  2798.     ODDisposeHandle(hndl);
  2799. }
  2800.  
  2801. //------------------------------------------------------------------------------
  2802. // ExportStylType
  2803. //------------------------------------------------------------------------------
  2804. //
  2805. // Argument is a pointer to styled text, with begins with a style record.
  2806.  
  2807. ODStatic OSErr ExportStylType(ODPtr    stxtData)
  2808. {
  2809.     Size stylSize = *((short *) stxtData);
  2810.     stylSize = (stylSize * sizeof(ScrpSTElement)) + sizeof(short);
  2811.     
  2812.     return ClipboardPutScrap(stylSize, 'styl', stxtData);
  2813. }
  2814.  
  2815. //------------------------------------------------------------------------------
  2816. // ScrapIsInconsistent
  2817. //------------------------------------------------------------------------------
  2818.  
  2819. ODStatic ODBoolean ScrapIsInconsistent()
  2820. {
  2821.     // Return false if the scrap in an inconsistent state and thus cannot
  2822.     // be read. [cc]
  2823.  
  2824. #if ODDebugClipboard
  2825.     if ( (InfoScrap()->scrapState > 0) && (InfoScrap()->scrapHandle == nil) )
  2826.         PRINT("ODClipboard: Scrap is inconsistent!\n");
  2827. #endif
  2828.  
  2829.     return  ((InfoScrap()->scrapState > 0) && (InfoScrap()->scrapHandle == nil));
  2830.     
  2831. }    
  2832.  
  2833. #endif // MAC or AIX
  2834. //------------------------------------------------------------------------------
  2835. // ScrapHasData
  2836. //------------------------------------------------------------------------------
  2837.  
  2838. ODStatic ODBoolean ScrapHasData()
  2839. {
  2840.     // Return true if the scrap size is greater than zero and the scrap is 
  2841.     // in a consistent state. [cc]
  2842.  
  2843. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  2844.     return ((InfoScrap()->scrapSize > 0) && (!ScrapIsInconsistent()));
  2845. #endif // MAC or AIX
  2846. #ifdef _PLATFORM_OS2_
  2847.   return (WinEnumClipbrdFmts(WinQueryAnchorBlock(HWND_DESKTOP), 0L) != 0L );
  2848. #endif // _PLATFORM_OS2_
  2849. }    
  2850.  
  2851. #if defined (_PLATFORM_MACINTOSH_) || defined(_PLATFORM_AIX_)
  2852. //------------------------------------------------------------------------------
  2853. // ScrapHasType
  2854. //------------------------------------------------------------------------------
  2855.  
  2856. ODStatic ODBoolean ScrapHasType(ODPlatformType type)
  2857. {
  2858.     long        dummy;
  2859.     Size        dataSize;
  2860.     ODBoolean    result = kODFalse;
  2861.  
  2862.     if ( ScrapHasData() )
  2863.     {
  2864.         dataSize = GetScrap(nil, type, &dummy);
  2865.         if ( dataSize >= 0 )
  2866.             result = kODTrue;
  2867. #ifdef _REPORT_SCRAP_ERRORS_
  2868.         else
  2869.         {
  2870.             if (dataSize != noTypeErr )
  2871.                 WARN("ODClipboard: ScrapHasType: GetScrap() returned error %ld, type = %.4s", dataSize, &type);
  2872.         }
  2873. #endif
  2874.     }
  2875.     
  2876.     return result;
  2877. }
  2878.  
  2879. //------------------------------------------------------------------------------
  2880. // ForceZeroScrap
  2881. //------------------------------------------------------------------------------
  2882.  
  2883. ODStatic OSErr ForceZeroScrap()
  2884. {
  2885.     OSErr err = ZeroScrap();
  2886.     if ( err == nilHandleErr )
  2887.     {
  2888. #ifdef _REPORT_SCRAP_ERRORS_
  2889.         PRINT("ODClipboard: ZeroScrap returned error -109\n");
  2890. #endif
  2891.         // According to Dylan Ashe, if the scrap is inconsistent the best thing to
  2892.         // do is force re-initiaization of the scrap.  Use of this constant to
  2893.         // force re-initiaization will continue to work in Maxwell. [cc]
  2894.         InfoScrap()->scrapState = kUninitializedScrap;
  2895.         err = ZeroScrap();
  2896.     }
  2897.     return err;
  2898. }
  2899.  
  2900. //------------------------------------------------------------------------------
  2901. // ScrapMemoryAvailable
  2902. //------------------------------------------------------------------------------
  2903. //
  2904. // This function ensures than allocating dataSize bytes would still leave
  2905. // a 40K contiguous block free, as recommended by Inside Mac, Memory, 1-43. [cc]
  2906.  
  2907. ODStatic ODBoolean ScrapMemoryAvailable(Size dataSize)
  2908. {
  2909.     const Size kMemCushion = 40*1024;
  2910.     
  2911.     Size totalFree;
  2912.     Size contigFree;
  2913.     
  2914.     PurgeSpace(&totalFree, &contigFree);
  2915.     
  2916. #if ODDebugClipboard
  2917.     PRINT("Request %ld bytes with %ld available\n", dataSize, contigFree);
  2918. #endif
  2919.  
  2920.     return (dataSize + kMemCushion) < contigFree;
  2921. }
  2922.  
  2923. //------------------------------------------------------------------------------
  2924. // UnloadScrapIfMemLow
  2925. //------------------------------------------------------------------------------
  2926.  
  2927. ODStatic OSErr UnloadScrapIfMemLow(Size dataSize)
  2928. {
  2929.     OSErr unloadError = noErr;
  2930.     
  2931.     if ( InfoScrap()->scrapState != kScrapOnDisk )
  2932.     {
  2933.         if ( !ScrapMemoryAvailable(dataSize) )
  2934.         {
  2935.             unloadError = UnloadScrap();
  2936.     
  2937. #if ODDebugClipboard
  2938.             PRINT("ODClipboard: Scrap unloaded with error %d\n", unloadError);
  2939. #endif
  2940.         }
  2941.     }
  2942.  
  2943.     return unloadError;
  2944. }
  2945.  
  2946. //------------------------------------------------------------------------------
  2947. // ClipboardLoadScrap
  2948. //------------------------------------------------------------------------------
  2949.  
  2950. ODStatic OSErr ClipboardLoadScrap()
  2951. {
  2952.     OSErr loadError = noErr;
  2953.     
  2954.     if ( InfoScrap()->scrapState == kScrapOnDisk )
  2955.     {
  2956.         if ( ScrapMemoryAvailable(InfoScrap()->scrapSize) )
  2957.         {
  2958.             loadError = LoadScrap();
  2959.     
  2960. #if ODDebugClipboard
  2961.              PRINT("ODClipboard: Scrap loaded with error %d\n", loadError);
  2962. #endif
  2963.         }
  2964.         else
  2965.         {
  2966.             loadError = kODErrOutOfMemory;
  2967.         }
  2968.     }
  2969.  
  2970.     return loadError;
  2971. }
  2972.  
  2973. //------------------------------------------------------------------------------
  2974. // ClipboardPutScrap
  2975. //------------------------------------------------------------------------------
  2976.  
  2977. ODStatic OSErr ClipboardPutScrap(Size dataSize, ODPlatformType    platformType, ODPtr data)
  2978. {
  2979.     OSErr error = UnloadScrapIfMemLow(dataSize);
  2980.     
  2981.     if ( error == noErr )
  2982.     {
  2983.         error = (OSErr) PutScrap(dataSize, platformType, data);
  2984.  
  2985. #ifdef _REPORT_SCRAP_ERRORS_
  2986.         WASSERTM(error == noErr, "ODClipboard: PutScrap() failed");
  2987. #endif
  2988.     }
  2989.  
  2990.     return error;
  2991. }
  2992.  
  2993. #endif // MAC or AIX
  2994. #ifdef _PLATFORM_OS2_
  2995.          
  2996. // [140007]
  2997. /*---------------------------------------------------------------------------
  2998.         GetFormatInfo
  2999. ---------------------------------------------------------------------------*/
  3000. ODULong GetFormatInfo(ODClipboard* somSelf, ODPlatformType ulType  )
  3001. {
  3002.    ODClipboardData *somThis = ODClipboardGetData(somSelf);
  3003.    OrderedCollectionIterator * iter = _fTypeCollection->CreateIterator();
  3004.    CLIPBOARDTYPEINFO *pclipboardTypeInfo;
  3005.  
  3006.    ODULong ulFlag = 0l;
  3007.    for ( pclipboardTypeInfo = (CLIPBOARDTYPEINFO *)iter->First();
  3008.          iter->IsNotComplete();
  3009.          pclipboardTypeInfo = (CLIPBOARDTYPEINFO *)iter->Next())
  3010.    {
  3011.       if ( pclipboardTypeInfo->platformType == ulType)
  3012.       {
  3013.          ulFlag = pclipboardTypeInfo->formatInfo;
  3014.          break;
  3015.       }
  3016.    }
  3017.  
  3018.    delete iter;
  3019.  
  3020.  
  3021.    return( ulFlag );
  3022. }
  3023.  
  3024. /*---------------------------------------------------------------------------
  3025.         GetScrap
  3026. ---------------------------------------------------------------------------*/
  3027. ULONG GetScrap( ODClipboard *somSelf, Handle hData, ODPlatformType type, long * dummy )
  3028. {
  3029.    ODClipboardData *somThis = ODClipboardGetData(somSelf);
  3030.  
  3031.    PBYTE        pbData;
  3032.    PULONG       pulData;
  3033.    ULONG        ulSize = 0;
  3034.  
  3035. #if ODDebugClipboard
  3036.    somPrintf( "GetScrap - type = %ld\n", type );
  3037. #endif
  3038.  
  3039.         pbData = (PBYTE)WinQueryClipbrdData( _fHab, type );
  3040.  
  3041. #if ODDebugClipboard
  3042.    somPrintf( "pbData: %p\n", pbData );
  3043. #endif
  3044.    if ( pbData )
  3045.       {
  3046.       switch ( type )
  3047. // aml - [140007] start
  3048.          {
  3049.          case CF_TEXT:
  3050.          case CF_DSPTEXT:
  3051.             ulSize = strlen( (PSZ)pbData ) + 1;
  3052.  
  3053.             ODSetHandleSize( (ODHandle)hData, ulSize );
  3054.             ODBlockMove( pbData, *hData, ulSize );
  3055.             break;
  3056.  
  3057.          case CF_METAFILE:
  3058.          case CF_DSPMETAFILE:
  3059.             ulSize = GpiQueryMetaFileLength( (HMF)pbData );
  3060.             ODSetHandleSize( (ODHandle)hData, ulSize );
  3061.             GpiQueryMetaFileBits( (HMF)pbData, 0, ulSize, (PBYTE)*hData );
  3062.             break;
  3063.  
  3064.          case CF_BITMAP:
  3065.          case CF_DSPBITMAP:
  3066.             {
  3067.             BITMAPINFOHEADER2 bmih;
  3068.             PBITMAPINFO2 pbmih = NULL;
  3069.             ULONG scansize;
  3070.             LONG bmisize;
  3071.             PVOID  data;
  3072.             HPS     hpsMem;
  3073.             HDC     hdcMem;
  3074.             HBITMAP hbmMem = (HBITMAP)pbData;
  3075.             SIZEL sizlPage;
  3076.  
  3077.             hdcMem = DevOpenDC( _fHab,OD_MEMORY,"*",0L,NULL,NULLHANDLE);
  3078.             sizlPage.cx = sizlPage.cy = 0;
  3079.  
  3080.             hpsMem = GpiCreatePS( _fHab, hdcMem, &sizlPage,
  3081.                            PU_PELS | GPIA_ASSOC );
  3082.             HBITMAP hbmOld = GpiSetBitmap( hpsMem, hbmMem );
  3083.  
  3084.             bmih.cbFix = sizeof(bmih);
  3085.             GpiQueryBitmapInfoHeader(hbmMem, &bmih);
  3086.  
  3087.             scansize = ((bmih.cBitCount*bmih.cx+31)/32)*bmih.cPlanes*4;
  3088.             // bitmap size calc changed; defect 22946 (Merlin OS/2 defect 155161
  3089.             //bmisize = (bmih.cbFix+(sizeof(RGB2))*
  3090.             //                     (bmih.cclrUsed ? bmih.cclrUsed :
  3091.             //                      2<<(bmih.cBitCount*bmih.cPlanes) ) );
  3092.             bmisize = bmih.cbFix;
  3093.             if ((bmih.cBitCount * bmih.cPlanes) < 24) {
  3094.                bmisize += sizeof(RGB2) * (1 << bmih.cBitCount * bmih.cPlanes);
  3095.             ulSize = bmisize+scansize*bmih.cy;
  3096.             }
  3097.  
  3098.             ODSetHandleSize( (ODHandle)hData, ulSize );
  3099.             pbmih = (PBITMAPINFO2)*hData;
  3100.  
  3101.             data = (PVOID)pbmih;
  3102.             memcpy(data, (PVOID)&bmih, bmih.cbFix);
  3103.             pbmih->cBitCount = bmih.cBitCount*bmih.cPlanes;
  3104.             pbmih->cPlanes = 1;
  3105.             pbmih->cbImage = scansize*bmih.cy;
  3106.             pbmih->ulCompression = 0;
  3107.             GpiQueryBitmapBits(hpsMem, 0, bmih.cy,
  3108.                                 ((PSZ)data)+bmisize, pbmih);
  3109.             GpiSetBitmap( hpsMem, hbmOld );
  3110. //            GpiDeleteBitmap( hbmMem );
  3111.  
  3112.             GpiSetBitmap(hpsMem,NULLHANDLE);
  3113.             GpiAssociate( hpsMem, NULLHANDLE );
  3114.             GpiDestroyPS( hpsMem );
  3115.             DevCloseDC( hdcMem );
  3116.  
  3117.             break;
  3118.             }
  3119.  
  3120.          case CF_PALETTE:
  3121.          {
  3122.             HPAL hpal = (HPAL)pbData;
  3123.             ULONG flOptions = 0L;
  3124.             ULONG ulCount = 0L;
  3125.             PULONG aulArray = kODNULL;
  3126.             ulSize = 0L;
  3127.             ulCount = GpiQueryPaletteInfo(hpal,NULLHANDLE, flOptions, 0L, 0L, aulArray);
  3128.             if(ulCount == PAL_ERROR) break;
  3129.             ulSize = (ulCount+1)*sizeof(ULONG);
  3130.             ODSetHandleSize( (ODHandle)hData, ulSize );
  3131.             aulArray = (PULONG)*hData;
  3132.             *aulArray++ = ulCount;
  3133.             ulCount = GpiQueryPaletteInfo(hpal,NULLHANDLE, flOptions, 0L, ulCount, aulArray);
  3134.             break;
  3135.          }
  3136. // aml - [140007] end
  3137.          default:
  3138.             if ( type == CF_OPENDOCDOCUMENT )
  3139.             {
  3140.                pulData = (PULONG)pbData;
  3141.                ulSize = *pulData;
  3142.  
  3143.                ODSetHandleSize( (ODHandle)hData, ulSize );
  3144.                ODBlockMove( pbData + sizeof( ULONG ), *hData, ulSize );
  3145.             }
  3146.             else {
  3147.                // this is to accomodate stuff placed on the pm clipboard
  3148.                // but not defined by a standard cf_ value.
  3149.                ULONG format;
  3150.                if(!WinQueryClipbrdFmtInfo(_fHab,type,&format))
  3151.                   format = 0L;
  3152.                if(!(format & CFI_POINTER)) break;
  3153.                ULONG ulFlags;
  3154.                ulSize = -1;
  3155.  
  3156.                if ( 0 == DosQueryMem( (PVOID)pbData, &ulSize, &ulFlags ))
  3157.                {
  3158.                   ODSetHandleSize( (ODHandle)hData, ulSize );
  3159.                   ODBlockMove( pbData, *hData, ulSize );
  3160.                }
  3161.             }
  3162.             break;
  3163.          }
  3164.       }
  3165.  
  3166.    return ulSize;
  3167. }
  3168.  
  3169.            
  3170.  
  3171. /*---------------------------------------------------------------------------
  3172.         PutPMPromise
  3173. ---------------------------------------------------------------------------*/
  3174. ODBoolean PutPMPromise( ODClipboard *somSelf, ODPlatformType platformType )
  3175. {
  3176.    ODClipboardData *somThis = ODClipboardGetData(somSelf);
  3177.    ODBoolean fResult = kODFalse;
  3178.  
  3179. #if ODDebugClipboard
  3180.    somPrintf( "PutPMPromise - platformType( %ld )\n", platformType );
  3181. #endif
  3182.  
  3183. /*
  3184.    switch ( platformType )
  3185.       {
  3186.       case CF_BITMAP:
  3187.       case CF_DSPBITMAP:
  3188.       case CF_METAFILE:
  3189.       case CF_DSPMETAFILE:
  3190.       case CF_PALETTE:
  3191.  
  3192.          fResult = WinSetClipbrdData( _fHab, (ULONG)0,
  3193.                                             platformType, CFI_HANDLE );
  3194.          break;
  3195.  
  3196.       default:
  3197.          fResult = WinSetClipbrdData( _fHab, (ULONG)0,
  3198.                                       platformType, CFI_POINTER );
  3199.          break;
  3200.       }
  3201. */
  3202.  
  3203.       ODULong flag = GetFormatInfo(somSelf,platformType);
  3204.       if(!flag) flag = CFI_POINTER;
  3205.       fResult = WinSetClipbrdData( _fHab, (ULONG)0,
  3206.                                       platformType, flag );
  3207.       _fArePromises = kODTrue;
  3208. #if ODDebugClipboard
  3209.    somPrintf( "result (%d)\n", fResult );
  3210. #endif
  3211.    return( fResult );
  3212. }
  3213.            
  3214. /*---------------------------------------------------------------------------
  3215.         PutScrap
  3216. ---------------------------------------------------------------------------*/
  3217. OSErr PutScrap( ODClipboard *somSelf, ULONG dataSize, ODPlatformType platformType, Ptr data)
  3218. {
  3219.    ODClipboardData *somThis = ODClipboardGetData(somSelf);
  3220.  
  3221. #if ODDebugClipboard
  3222.    somPrintf( "PutScrap - size( %ld ) - platformType( %ld )\n",
  3223.                         dataSize, platformType );
  3224. #endif
  3225.  
  3226.    BOOL   fResult;
  3227.    PBYTE  pbData;
  3228.    APIRET rc;
  3229.    OSErr  err = noErr;
  3230.    PULONG pulData;
  3231.  
  3232.    switch ( platformType )
  3233.       {
  3234.       case CF_BITMAP:
  3235.       case CF_DSPBITMAP:
  3236.       case CF_METAFILE:
  3237.       case CF_DSPMETAFILE:
  3238.       case CF_PALETTE:     // [140007]
  3239.          pulData = (PULONG)data;
  3240.          fResult = WinSetClipbrdData( _fHab, (ULONG)*pulData,
  3241.                                             platformType, CFI_HANDLE );
  3242.          break;
  3243.  
  3244.       default:
  3245.          ULONG  ulSize =
  3246.             ( platformType == CF_OPENDOCDOCUMENT ) ? sizeof( ULONG ) : 0L;
  3247.  
  3248.          rc = DosAllocSharedMem( (PPVOID)&pbData, 0L, dataSize + ulSize,
  3249.                                     PAG_READ | PAG_WRITE | PAG_COMMIT |
  3250.                                     OBJ_GIVEABLE | OBJ_GETTABLE | OBJ_TILE );
  3251.          if ( rc )
  3252.             {
  3253.             err = kODErrOutOfMemory;
  3254.             }
  3255.          else
  3256.             {
  3257.             pulData = (PULONG)pbData;
  3258.             *pulData = dataSize;      // possibly overwritten by memcpy()
  3259.  
  3260.             memcpy( pbData + ulSize, data, dataSize );
  3261.             fResult = WinSetClipbrdData( _fHab, (ULONG)pbData,
  3262.                                             platformType, CFI_POINTER );
  3263.             // No need to free pbData here, the clipboard mgr has already
  3264.             // taken it from us...
  3265.             }
  3266.          break;
  3267.       }
  3268.  
  3269.    return err;
  3270. }
  3271.  
  3272. /*---------------------------------------------------------------------------
  3273.         SetClipboardOwnership
  3274.  
  3275.         This method is unique to OS/2. It sets up the PM clipboard so
  3276.         that we can later fulfill promies.
  3277. ---------------------------------------------------------------------------*/
  3278. ODStatic ODBoolean SetClipboardOwnership(
  3279.                                 ODClipboard *somSelf,
  3280.                                 Environment *ev )
  3281. {
  3282.    ODClipboardData *somThis = ODClipboardGetData(somSelf);
  3283.  
  3284.    ODBoolean result = kODTrue;
  3285.  
  3286. #if ODDebugClipboard
  3287.    somPrintf( "SetClipboardOwnership - _fUpdateID(%08lX)\n", _fUpdateID );
  3288. #endif
  3289.  
  3290. //   _fUpdateID = _fSession->UniqueUpdateID(ev);
  3291.  
  3292.    result = WinSetClipbrdData( _fHab, _fUpdateID,        // stamp it
  3293.                       CF_OPENDOCOWNERID, CFI_HANDLE );
  3294.  
  3295. #if ODDebugClipboard
  3296.    somPrintf( "result(%d) = WinSetClipbrdData( CF_OPENDOCOWNERID )\n", result );
  3297. #endif
  3298.  
  3299.    // We are assuming everyone is a good citizen here right...
  3300.    ODTypeToken clipboardFocus =
  3301.                     _fSession->Tokenize(ev, kODClipboardFocus);
  3302. //D137529   ODFrame *frame = _fSession->GetArbitrator( ev )->
  3303. //D137529                                AcquireFocusOwner( ev, clipboardFocus );
  3304.    TempODFrame frame = _fSession->GetArbitrator( ev )->                      //D137529
  3305.                                 AcquireFocusOwner( ev, clipboardFocus );     //D137529
  3306.    ODWindow* window = kODNULL;
  3307.    HWND hwndOwner = NULLHANDLE;
  3308.    if(frame == kODNULL) { // this may get called when no one has the clipboard focus;
  3309.       window = _fSession->GetWindowState(ev)->AcquireActiveWindow(ev);
  3310.    }
  3311.    else {
  3312.       window = frame->AcquireWindow( ev );
  3313.    }
  3314.    if(window) {
  3315.       hwndOwner = window->GetPlatformWindow( ev );
  3316.       ODReleaseObject(ev,window);
  3317.    }
  3318.    else return kODFalse;
  3319. /*
  3320.    ODPart* part = kODNULL;
  3321.    ODReleaseObject(ev,_fClipboardOwner);
  3322.    if(frame)
  3323.       part = frame->AcquirePart( ev );
  3324.    _fClipboardOwner = part;
  3325. */
  3326.    // This is who we will send the WM_RENDERFMT to...
  3327.    result = WinSetClipbrdOwner( _fHab, hwndOwner );
  3328.  
  3329. #if ODDebugClipboard
  3330.          somPrintf( "result(%d) = WinSetClipbrdOwner( %08lX )\n",
  3331.                               result, hwndOwner );
  3332. #endif
  3333.  
  3334.    return( result );
  3335. }
  3336.  
  3337.  
  3338. ODStatic void SetPMUpdateID(HAB hab, ODUpdateID id)
  3339. {
  3340.  
  3341. #if ODDebugClipboard
  3342.    PRINT("SetPMUpdateID called: %d.\n", id);
  3343. #endif
  3344.    WinOpenClipbrd( hab );
  3345.    WinSetClipbrdData( hab, id, CF_OPENDOCOWNERID, CFI_HANDLE );
  3346.    WinCloseClipbrd( hab );
  3347. }
  3348.  
  3349. /*
  3350.         GetPMUpdateID
  3351.  
  3352.         Return the last change ID placed on the PM clipboard.
  3353. */
  3354. ODStatic ODUpdateID GetPMUpdateID(HAB hab)
  3355. {
  3356.    ODUpdateID updateID = 0;
  3357.  
  3358.    WinOpenClipbrd( hab );
  3359.  
  3360.    updateID = WinQueryClipbrdData( hab, CF_OPENDOCOWNERID );
  3361.  
  3362.    WinCloseClipbrd( hab );
  3363.  
  3364. #if ODDebugClipboard
  3365.    PRINT("GetPMUpdateID called: %d.\n", updateID);
  3366. #endif
  3367.    return( updateID );
  3368. }
  3369. #ifdef OLE_STUFF
  3370. //D001  @SESH
  3371. //------------------------------------------------------------------------------
  3372. //   Function:   PutOleContentOnPlatformClipboard
  3373. //   Parameters: ODStorageUnit
  3374. //-------------------------------------------------------------------------------
  3375. //
  3376. void PutOleContentOnPlatformClipboard(ODStorageUnit *su)
  3377. {
  3378.  
  3379.   CHAR pszLibName[] = "PROXYHND";
  3380.   CHAR szMsg[80];
  3381.   HMODULE ModuleHandle;
  3382.   APIRET rc;
  3383.  
  3384.   typedef APIRET (_System *pfnODExportOlePart)(ODStorageUnit *);
  3385.   pfnODExportOlePart ODExportOlePart;
  3386.  
  3387.   rc =  DosLoadModule(szMsg, sizeof(szMsg), pszLibName, &ModuleHandle);
  3388.   if (rc != 0)
  3389.   {
  3390.  
  3391. #if ODDebugClipboard
  3392.       somPrintf("Could not Load PROXYHND.DLL, return code = %ld", rc);
  3393. #endif
  3394.   }
  3395.  
  3396.   rc = DosQueryProcAddr(ModuleHandle, 0, "ODExportOlePart", (PFN*)&ODExportOlePart);
  3397.   if (rc != 0)
  3398.       somPrintf("DosQueryProcAddr error: rc = %ld",rc);
  3399.   else
  3400.       ODExportOlePart(su);
  3401.   return;
  3402. }  //D001
  3403.  
  3404. //D001 -- SESH for Ole Interoperability
  3405.  
  3406. //------------------------------------------------------------------------------
  3407. //   Function:   GetOleContentFromPlatformClipboard
  3408. //   Parameters: ODStorageUnit
  3409. //-------------------------------------------------------------------------------
  3410. //
  3411. void GetOleContentFromPlatformClipboard(ODStorageUnit *su)
  3412. {
  3413.  
  3414.   CHAR pszLibName[] = "PROXYHND";
  3415.   CHAR szMsg[80];
  3416.   HMODULE ModuleHandle;
  3417.   APIRET rc;
  3418.   Environment *ev = somGetGlobalEnvironment();
  3419.  
  3420.   char   FmtName[20];
  3421.   USHORT usFormat = 0;        /* Temporary used when enumerating */
  3422.   HAB    vhab = WinInitialize(0);   /* if you don't have it already */
  3423.  
  3424.   /*
  3425.    * Cycle through the available clipboard formats
  3426.    */
  3427.  
  3428.    while ( usFormat = (USHORT) WinEnumClipbrdFmts( vhab, usFormat ) )
  3429.    {
  3430.       switch ( usFormat )
  3431.       {
  3432. //         case CF_EMPTY:
  3433.          case CF_TEXT:
  3434.          case CF_DSPTEXT:
  3435.          case CF_BITMAP:
  3436.          case CF_DSPBITMAP:
  3437.          case CF_METAFILE:
  3438.          case CF_DSPMETAFILE:
  3439.               break;
  3440.  
  3441.          default:
  3442.  
  3443.          /*
  3444.           *  Get the format name from the system atom table.
  3445.           */
  3446.          if ( WinQueryAtomName( WinQuerySystemAtomTable(),
  3447.                                usFormat, FmtName, sizeof(FmtName)) )
  3448.          {
  3449.              if (stricmp(FmtName, "DataObject") == 0)
  3450.              {
  3451.                  /* we have an OLE object to import */
  3452.  
  3453.                  typedef APIRET (_System *pfnODImportOlePart)(ODStorageUnit *);
  3454.                  pfnODImportOlePart ODImportOlePart;
  3455.  
  3456.                  rc =  DosLoadModule(szMsg, sizeof(szMsg), pszLibName, &ModuleHandle);
  3457.                  if (rc != 0)
  3458.                  {
  3459.                      somPrintf("Could not Load PROXYHND.DLL, return code = %ld", rc);
  3460.                      return;
  3461.                  }
  3462.  
  3463.                  rc = DosQueryProcAddr(ModuleHandle, 0, "ODImportOlePart", (PFN*)&ODImportOlePart);
  3464.                  if (rc != 0)
  3465.                      somPrintf("DosQueryProcAddr error: rc = %ld",rc);
  3466.                  else
  3467.                  {
  3468.                     const ODType kODOpenDocPresNormal = "OpenDoc:Presentation:Normal"; //#D001
  3469.                     ODEditor partEditor = "Proxyhnd:Proxyhnd";
  3470.  
  3471.                     ODDraft* clipdraft = su->GetDraft(ev);
  3472.                     ODPart* OlePart = clipdraft->CreatePart(ev,kODKindOlePart, partEditor);
  3473.                     if(OlePart == kODNULL)
  3474.                           THROW(kODErrCannotCreatePart);
  3475.  
  3476.                     //SESH -- needs to be checked again
  3477.                     ODShape* newShape = new ODShape;
  3478.                     newShape->InitShape(ev);
  3479.  
  3480.                     ODFrame* OleFrame = clipdraft->CreateFrame(ev, (ODType)kODFrameObject, (ODFrame*)kODNULL,
  3481.                                         newShape, (ODCanvas*)kODNULL, OlePart,(ODTypeToken)"OpenDoc:ViewAs:Frame",
  3482.                                         su->GetSession(ev)->Tokenize(ev, kODOpenDocPresNormal),
  3483.                                         kODFalse, kODFalse);
  3484.                     if(OleFrame == kODNULL)
  3485.                         THROW(kODErrCannotCreateFrame);
  3486.  
  3487.                     ODID frameInfoData = OleFrame->GetID(ev);
  3488.                     StorageUnitSetValue(su, ev, sizeof(ODID), (ODValue)&frameInfoData);
  3489.                     su->AddProperty(ev, kODPropContentFrame);
  3490.                     su->Focus(ev, kODPropContentFrame, kODPosUndefined, kODNULL, 0, kODPosUndefined);
  3491.                     su->AddValue(ev, kODWeakStorageUnitRef);
  3492.  
  3493.                     su->AddProperty(ev, kODPropFrameShape);
  3494.  
  3495.                     ODImportOlePart(su);
  3496.                  }
  3497.                  return;
  3498.              }
  3499.          }
  3500.          break;
  3501.       }
  3502.    }
  3503. }
  3504. //D001  OleInteroperability
  3505. #endif // OLE_STUFF
  3506. #endif // _PLATFORM_OS2_
  3507.  
  3508. ULONG GetDataHandle(Environment*ev, ODStorageUnit* su)
  3509. {
  3510.  
  3511.    ODType               theISOType;
  3512.    ULONG handle = NULLHANDLE;
  3513.    theISOType = su->GetType(ev);
  3514.    if(strcmp((PSZ)theISOType, kODKindOS2Bitmap) == 0)
  3515.       handle = (ULONG)BitmapFromStorage(ev,su);
  3516.    else if(strcmp((PSZ)theISOType, kODKindOS2Metafile) == 0)
  3517.       handle = (ULONG)MetafileFromStorage(ev,su);
  3518.    return handle;
  3519. }
  3520.  
  3521.  
  3522. HBITMAP BitmapFromStorage(Environment* ev, ODStorageUnit* storageUnit)
  3523. {
  3524.          SIZEL sizlPage = {0, 0};
  3525.          HAB hab = WinQueryAnchorBlock(HWND_DESKTOP);
  3526.          HDC hdc = DevOpenDC( hab,OD_MEMORY,"*",0L,NULL,NULLHANDLE);
  3527.          HPS hps = GpiCreatePS(hab, hdc, &sizlPage, PU_PELS | GPIA_ASSOC );
  3528.          HBITMAP hBitmap = NULLHANDLE;
  3529.          if(storageUnit->Exists(ev, kODPropContents, kODKindOS2Bitmap, 0)) {
  3530.             storageUnit->Focus(ev, kODPropContents, kODPosUndefined, kODKindOS2Bitmap, 0, kODPosUndefined);
  3531.             ULONG dataSize = storageUnit->GetSize( ev );
  3532.             if(dataSize > 0) {
  3533.                PBYTE Bitmap;
  3534.  
  3535.                DosAllocMem ((PPVOID)&Bitmap, dataSize,
  3536.                               PAG_COMMIT | PAG_READ | PAG_WRITE);
  3537.  
  3538.                StorageUnitGetValue(storageUnit, ev, dataSize, (ODValue) Bitmap );
  3539.  
  3540.                PBITMAPINFOHEADER2  pbmih = (PBITMAPINFOHEADER2)Bitmap;
  3541.                ULONG bmisize = (pbmih->cbFix+(sizeof(RGB2))*
  3542.                                        (pbmih->cclrUsed ? pbmih->cclrUsed :
  3543.                                         2<<(pbmih->cBitCount*pbmih->cPlanes) ) );
  3544.  
  3545.                hBitmap = GpiCreateBitmap (hps, pbmih, CBM_INIT,
  3546.                                 Bitmap + bmisize, (PBITMAPINFO2)pbmih);
  3547.  
  3548.                if (hBitmap == GPI_ERROR)
  3549.                   hBitmap = 0;
  3550.  
  3551.                DosFreeMem( Bitmap );
  3552.             }
  3553.          }
  3554.          if (hps)
  3555.          {
  3556.             GpiAssociate(hps, 0);
  3557.             GpiDestroyPS(hps);
  3558.          }
  3559.          if (hdc)
  3560.             DevCloseDC(hdc);
  3561.          return hBitmap;
  3562. }
  3563.  
  3564. HMF MetafileFromStorage(Environment* ev, ODStorageUnit* storageUnit)
  3565. {
  3566.        HMF hMetafile = NULLHANDLE;
  3567.        if ( storageUnit->Exists(ev, kODPropContents, kODKindOS2Metafile, 0) )
  3568.        {
  3569.          storageUnit->Focus(ev, kODPropContents, kODPosUndefined, kODKindOS2Metafile, 0, kODPosUndefined);
  3570.          ULONG dataSize = storageUnit->GetSize( ev );
  3571.          if(dataSize > 0) {
  3572.           PBYTE Metafile;
  3573.           DosAllocMem ((PPVOID)&Metafile, dataSize,
  3574.                         PAG_COMMIT | PAG_READ | PAG_WRITE);
  3575.  
  3576.           StorageUnitGetValue(storageUnit, ev, dataSize, (ODValue) Metafile );
  3577.           DEVOPENSTRUC dop;
  3578.           HDC hdcMeta;
  3579.           SIZEL size = {0L,0L};
  3580.           HAB hab = WinQueryAnchorBlock(HWND_DESKTOP);
  3581.           dop.pszLogAddress = (PSZ) NULL;
  3582.           dop.pszDriverName = "DISPLAY";
  3583.           hdcMeta = DevOpenDC(hab,OD_METAFILE,"*",2L,(PDEVOPENDATA)&dop, (HDC)NULLHANDLE);
  3584.           hMetafile = DevCloseDC(hdcMeta);
  3585.           GpiSetMetaFileBits(hMetafile,0L,dataSize,Metafile);
  3586.           DosFreeMem(Metafile);
  3587.          }
  3588.        }
  3589.        return hMetafile;
  3590. }
  3591. #endif // _PLATFORM_OS2_
  3592.