summaryrefslogtreecommitdiff
path: root/dtrans/source/os2/clipb/Os2Clipboard.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'dtrans/source/os2/clipb/Os2Clipboard.cxx')
-rw-r--r--dtrans/source/os2/clipb/Os2Clipboard.cxx447
1 files changed, 447 insertions, 0 deletions
diff --git a/dtrans/source/os2/clipb/Os2Clipboard.cxx b/dtrans/source/os2/clipb/Os2Clipboard.cxx
new file mode 100644
index 000000000000..494df04b640a
--- /dev/null
+++ b/dtrans/source/os2/clipb/Os2Clipboard.cxx
@@ -0,0 +1,447 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+
+#include "Os2Clipboard.hxx"
+
+//------------------------------------------------------------------------
+// namespace directives
+//------------------------------------------------------------------------
+
+using namespace com::sun::star::datatransfer;
+using namespace com::sun::star::datatransfer::clipboard;
+using namespace com::sun::star::datatransfer::clipboard::RenderingCapabilities;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::uno;
+using namespace cppu;
+using namespace osl;
+using namespace rtl;
+using namespace os2;
+
+const Type CPPUTYPE_SEQINT8 = getCppuType( ( Sequence< sal_Int8 >* )0 );
+const Type CPPUTYPE_OUSTRING = getCppuType( (OUString*)0 );
+
+#define DTRANS_OBJ_CLASSNAME "DTRANSOBJWND"
+
+// -----------------------------------------------------------------------
+
+inline void SetWindowPtr( HWND hWnd, Os2Clipboard* pThis )
+{
+ WinSetWindowULong( hWnd, QWL_USER, (ULONG)pThis );
+}
+
+inline Os2Clipboard* GetWindowPtr( HWND hWnd )
+{
+ return (Os2Clipboard*)WinQueryWindowULong( hWnd, QWL_USER );
+}
+
+// -----------------------------------------------------------------------
+
+MRESULT EXPENTRY DtransObjWndProc( HWND hWnd, ULONG nMsg, MPARAM nMP1, MPARAM nMP2 )
+{
+
+ switch ( nMsg )
+ {
+ case WM_DRAWCLIPBOARD: // clipboard content has changed
+ {
+ Os2Clipboard* os2Clipboard = GetWindowPtr( hWnd);
+ if (os2Clipboard)
+ {
+ //MutexGuard aGuard(os2Clipboard->m_aMutex);
+ debug_printf("WM_DRAWCLIPBOARD os2Clipboard %08x\n", os2Clipboard);
+ if (os2Clipboard->m_bInSetClipboardData)
+ {
+ debug_printf("WM_DRAWCLIPBOARD our change\n");
+ }
+ else
+ {
+ // notify listener for clipboard change
+ debug_printf("WM_DRAWCLIPBOARD notify change\n");
+ os2Clipboard->notifyAllClipboardListener();
+ }
+ }
+ }
+ break;
+ }
+
+ return WinDefWindowProc( hWnd, nMsg, nMP1, nMP2 );
+}
+
+// -----------------------------------------------------------------------
+
+Os2Clipboard::Os2Clipboard() :
+ m_aMutex(),
+ WeakComponentImplHelper4< XClipboardEx, XClipboardNotifier, XServiceInfo, XInitialization > (m_aMutex),
+ m_bInitialized(sal_False),
+ m_bInSetClipboardData(sal_False)
+{
+ MutexGuard aGuard(m_aMutex);
+
+ debug_printf("Os2Clipboard::Os2Clipboard\n");
+ hAB = WinQueryAnchorBlock( HWND_DESKTOP );
+ hText = 0;
+ hBitmap = 0;
+
+#if 0
+ // register object class
+ if ( WinRegisterClass( hAB, (PSZ)DTRANS_OBJ_CLASSNAME,
+ (PFNWP)DtransObjWndProc, 0, sizeof(ULONG) ))
+ {
+ APIRET rc;
+ // create object window to get clip viewer messages
+ hObjWnd = WinCreateWindow( HWND_OBJECT, (PCSZ)DTRANS_OBJ_CLASSNAME,
+ (PCSZ)"", 0, 0, 0, 0, 0,
+ HWND_OBJECT, HWND_TOP,
+ 222, NULL, NULL);
+ // store pointer
+ SetWindowPtr( hObjWnd, this);
+ // register the viewer window
+ rc = WinOpenClipbrd(hAB);
+ rc = WinSetClipbrdViewer(hAB, hObjWnd);
+ rc = WinCloseClipbrd(hAB);
+ }
+#endif
+
+}
+
+Os2Clipboard::~Os2Clipboard()
+{
+ debug_printf("Os2Clipboard::~Os2Clipboard\n");
+}
+
+void SAL_CALL Os2Clipboard::initialize( const Sequence< Any >& aArguments )
+ throw(Exception, RuntimeException)
+{
+ if (!m_bInitialized)
+ {
+ for (sal_Int32 n = 0, nmax = aArguments.getLength(); n < nmax; n++)
+ if (aArguments[n].getValueType() == getCppuType((OUString *) 0))
+ {
+ aArguments[0] >>= m_aName;
+ break;
+ }
+ }
+}
+
+OUString SAL_CALL Os2Clipboard::getImplementationName() throw( RuntimeException )
+{
+ debug_printf("Os2Clipboard::getImplementationName\n");
+ return OUString::createFromAscii( OS2_CLIPBOARD_IMPL_NAME );
+}
+
+sal_Bool SAL_CALL Os2Clipboard::supportsService( const OUString& ServiceName ) throw( RuntimeException )
+{
+ debug_printf("Os2Clipboard::supportsService\n");
+ Sequence < OUString > SupportedServicesNames = Os2Clipboard_getSupportedServiceNames();
+
+ for ( sal_Int32 n = SupportedServicesNames.getLength(); n--; )
+ if (SupportedServicesNames[n].compareTo(ServiceName) == 0)
+ return sal_True;
+
+ return sal_False;
+}
+
+Sequence< OUString > SAL_CALL Os2Clipboard::getSupportedServiceNames() throw( RuntimeException )
+{
+ debug_printf("Os2Clipboard::getSupportedServiceNames\n");
+ return Os2Clipboard_getSupportedServiceNames();
+}
+
+Reference< XTransferable > SAL_CALL Os2Clipboard::getContents() throw( RuntimeException )
+{
+ debug_printf("Os2Clipboard::getContents\n");
+ MutexGuard aGuard(m_aMutex);
+
+ // os2 can have only one viewer at time, and we don't get a notification
+ // when the viewer changes. So we need to check handles of clipboard
+ // data and compare with previous handles
+ if (UWinOpenClipbrd(hAB)) {
+ sal_Bool fireChanged = sal_False;
+ ULONG handle = UWinQueryClipbrdData( hAB, UCLIP_CF_UNICODETEXT);
+ if (handle) {
+ if (handle != hText) {
+ hText = handle;
+ fireChanged = sal_True;
+ }
+ }
+ handle = UWinQueryClipbrdData( hAB, UCLIP_CF_BITMAP);
+ if (handle) {
+ if (handle != hBitmap) {
+ hBitmap = handle;
+ fireChanged = sal_True;
+ }
+ }
+ UWinCloseClipbrd( hAB);
+ if (fireChanged)
+ {
+ // notify listener for clipboard change
+ debug_printf("Os2Clipboard::getContents notify change\n");
+ notifyAllClipboardListener();
+ }
+ }
+
+ if( ! m_aContents.is() )
+ m_aContents = new Os2Transferable( static_cast< OWeakObject* >(this) );
+
+ return m_aContents;
+}
+
+void SAL_CALL Os2Clipboard::setContents( const Reference< XTransferable >& xTrans, const Reference< XClipboardOwner >& xClipboardOwner ) throw( RuntimeException )
+{
+ debug_printf("Os2Clipboard::setContents\n");
+ // remember old values for callbacks before setting the new ones.
+ ClearableMutexGuard aGuard(m_aMutex);
+
+ Reference< XClipboardOwner > oldOwner(m_aOwner);
+ m_aOwner = xClipboardOwner;
+
+ Reference< XTransferable > oldContents(m_aContents);
+ m_aContents = xTrans;
+
+ aGuard.clear();
+
+ // notify old owner on loss of ownership
+ if( oldOwner.is() )
+ oldOwner->lostOwnership(static_cast < XClipboard * > (this), oldContents);
+
+ // notify all listeners on content changes
+ OInterfaceContainerHelper *pContainer =
+ rBHelper.aLC.getContainer(getCppuType( (Reference < XClipboardListener > *) 0));
+ if (pContainer)
+ {
+ ClipboardEvent aEvent(static_cast < XClipboard * > (this), m_aContents);
+ OInterfaceIteratorHelper aIterator(*pContainer);
+
+ while (aIterator.hasMoreElements())
+ {
+ Reference < XClipboardListener > xListener(aIterator.next(), UNO_QUERY);
+ if (xListener.is())
+ xListener->changedContents(aEvent);
+ }
+ }
+
+#if OSL_DEBUG_LEVEL>0
+ // dump list of available mimetypes
+ Sequence< DataFlavor > aFlavors( m_aContents->getTransferDataFlavors() );
+ for( int i = 0; i < aFlavors.getLength(); i++ )
+ debug_printf("Os2Clipboard::setContents available mimetype: %d %s\n",
+ i, CHAR_POINTER(aFlavors.getConstArray()[i].MimeType));
+#endif
+
+ // we can only export text or bitmap
+ DataFlavor nFlavorText( OUString::createFromAscii( "text/plain;charset=utf-16" ),
+ OUString::createFromAscii( "Unicode-Text" ), CPPUTYPE_OUSTRING);
+ DataFlavor nFlavorBitmap( OUString::createFromAscii( "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" ),
+ OUString::createFromAscii( "Bitmap" ), CPPUTYPE_DEFAULT);
+
+ // try text transfer data (if any)
+ PSZ pSharedText = NULL;
+ HBITMAP hbm = NULL;
+ try
+ {
+ Any aAny = m_aContents->getTransferData( nFlavorText );
+ if (aAny.hasValue())
+ {
+ APIRET rc;
+ // copy unicode text to clipboard
+ OUString aString;
+ aAny >>= aString;
+ // share text
+ rc = DosAllocSharedMem( (PPVOID) &pSharedText, NULL,
+ aString.getLength() * 2 + 2,
+ PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE | OBJ_ANY);
+ if (!rc)
+ memcpy( pSharedText, aString.getStr(), aString.getLength() * 2 + 2 );
+ else
+ pSharedText = NULL;
+ debug_printf("Os2Clipboard::setContents SetClipbrdData text done\n");
+ }
+ } catch ( UnsupportedFlavorException&) {
+ debug_printf("Os2Clipboard::setContents UnsupportedFlavorException (no text)\n");
+ }
+
+ // try bitmap transfer data (if any)
+ try
+ {
+ Any aAnyB = m_aContents->getTransferData( nFlavorBitmap );
+ if (aAnyB.hasValue())
+ {
+ hbm = OOoBmpToOS2Handle( aAnyB);
+ debug_printf("Os2Clipboard::setContents SetClipbrdData bitmap done\n");
+ }
+ } catch ( UnsupportedFlavorException&) {
+ debug_printf("Os2Clipboard::setContents UnsupportedFlavorException (no bitmap)\n");
+ }
+
+ // copy to clipboard
+ if ( UWinOpenClipbrd( hAB) && (pSharedText || hbm))
+ {
+ // set the flag, so we will ignore the next WM_DRAWCLIPBOARD
+ // since we generate it with following code.
+ m_bInSetClipboardData = sal_True;
+ UWinEmptyClipbrd( hAB);
+ // give pointer to clipboard (it will become owner of pSharedText!)
+ if (pSharedText) {
+ UWinSetClipbrdData( hAB, (ULONG) pSharedText, UCLIP_CF_UNICODETEXT, CFI_POINTER);
+ // update internal handle to avoid detection of this text as new data
+ hText = (ULONG)pSharedText;
+ }
+ // give bitmap to clipboard
+ if (hbm) {
+ UWinSetClipbrdData( hAB, (ULONG) hbm, UCLIP_CF_BITMAP, CFI_HANDLE);
+ // update internal handle to avoid detection of this bitmap as new data
+ hBitmap = hbm;
+ }
+ // reset the flag, so we will not ignore next WM_DRAWCLIPBOARD
+ m_bInSetClipboardData = sal_False;
+ UWinCloseClipbrd( hAB);
+ }
+
+}
+
+OUString SAL_CALL Os2Clipboard::getName() throw( RuntimeException )
+{
+ debug_printf("Os2Clipboard::getName\n");
+ return m_aName;
+}
+
+sal_Int8 SAL_CALL Os2Clipboard::getRenderingCapabilities() throw( RuntimeException )
+{
+ debug_printf("Os2Clipboard::getRenderingCapabilities\n");
+ return Delayed;
+}
+
+//========================================================================
+// XClipboardNotifier
+//========================================================================
+
+void SAL_CALL Os2Clipboard::addClipboardListener( const Reference< XClipboardListener >& listener ) throw( RuntimeException )
+{
+ debug_printf("Os2Clipboard::addClipboardListener\n");
+ MutexGuard aGuard( rBHelper.rMutex );
+ OSL_ENSURE( !rBHelper.bInDispose, "do not add listeners in the dispose call" );
+ OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" );
+ if (!rBHelper.bInDispose && !rBHelper.bDisposed)
+ rBHelper.aLC.addInterface( getCppuType( (const ::com::sun::star::uno::Reference< XClipboardListener > *) 0), listener );
+}
+
+void SAL_CALL Os2Clipboard::removeClipboardListener( const Reference< XClipboardListener >& listener ) throw( RuntimeException )
+{
+ debug_printf("Os2Clipboard::removeClipboardListener\n");
+ MutexGuard aGuard( rBHelper.rMutex );
+ OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" );
+ if (!rBHelper.bInDispose && !rBHelper.bDisposed)
+ rBHelper.aLC.removeInterface( getCppuType( (const Reference< XClipboardListener > *) 0 ), listener ); \
+}
+
+// ------------------------------------------------------------------------
+
+void SAL_CALL Os2Clipboard::notifyAllClipboardListener( )
+{
+ if ( !rBHelper.bDisposed )
+ {
+ ClearableMutexGuard aGuard( rBHelper.rMutex );
+ if ( !rBHelper.bDisposed )
+ {
+ aGuard.clear( );
+
+ ClearableMutexGuard aGuard(m_aMutex);
+ // copy member references on stack so they can be called
+ // without having the mutex
+ Reference< XClipboardOwner > xOwner( m_aOwner );
+ Reference< XTransferable > xTrans( m_aContents );
+ // clear members
+ m_aOwner.clear();
+ m_aContents.clear();
+ // release the mutex
+ aGuard.clear();
+
+ // inform previous owner of lost ownership
+ if ( xOwner.is() )
+ xOwner->lostOwnership(static_cast < XClipboard * > (this), m_aContents);
+
+ OInterfaceContainerHelper* pICHelper = rBHelper.aLC.getContainer(
+ getCppuType( ( Reference< XClipboardListener > * ) 0 ) );
+
+ if ( pICHelper )
+ {
+ try
+ {
+ OInterfaceIteratorHelper iter(*pICHelper);
+ m_aContents = 0;
+ m_aContents = new Os2Transferable( static_cast< OWeakObject* >(this) );
+ ClipboardEvent aClipbEvent(static_cast<XClipboard*>(this), m_aContents);
+
+ while(iter.hasMoreElements())
+ {
+ try
+ {
+ Reference<XClipboardListener> xCBListener(iter.next(), UNO_QUERY);
+ if (xCBListener.is())
+ xCBListener->changedContents(aClipbEvent);
+ }
+ catch(RuntimeException&)
+ {
+ OSL_ENSURE( false, "RuntimeException caught" );
+ debug_printf( "RuntimeException caught" );
+ }
+ }
+ }
+ catch(const ::com::sun::star::lang::DisposedException&)
+ {
+ OSL_ENSURE(false, "Service Manager disposed");
+ debug_printf( "Service Manager disposed");
+
+ // no further clipboard changed notifications
+ //m_pImpl->unregisterClipboardViewer();
+ }
+
+ } // end if
+ } // end if
+ } // end if
+}
+
+// ------------------------------------------------------------------------
+
+Sequence< OUString > SAL_CALL Os2Clipboard_getSupportedServiceNames()
+{
+ Sequence< OUString > aRet(1);
+ aRet[0] = OUString::createFromAscii( OS2_CLIPBOARD_SERVICE_NAME );
+ return aRet;
+}
+
+// ------------------------------------------------------------------------
+
+Reference< XInterface > SAL_CALL Os2Clipboard_createInstance(
+ const Reference< XMultiServiceFactory > & xMultiServiceFactory)
+{
+ return Reference < XInterface >( ( OWeakObject * ) new Os2Clipboard());
+}
+