[Libreoffice-commits] .: 3 commits - dtrans/Library_sysdtrans.mk dtrans/source
Kohei Yoshida
kohei at kemper.freedesktop.org
Fri Dec 2 11:31:26 PST 2011
dtrans/Library_sysdtrans.mk | 2
dtrans/source/inc/MtaOleClipb.hxx | 137 ----
dtrans/source/win32/clipb/MtaOleClipb.cxx | 891 ++++++++++++++++++++++++++++
dtrans/source/win32/clipb/MtaOleClipb.hxx | 137 ++++
dtrans/source/win32/clipb/WinClipbImpl.hxx | 2
dtrans/source/win32/mtaole/MtaOleClipb.cxx | 892 -----------------------------
6 files changed, 1030 insertions(+), 1031 deletions(-)
New commits:
commit 61fce03ff2eb532e41a769f51ad8495f641edfb9
Author: Kohei Yoshida <kohei.yoshida at suse.com>
Date: Fri Dec 2 14:04:05 2011 -0500
inline keyword makes sense only when the definition is in header.
diff --git a/dtrans/source/win32/clipb/MtaOleClipb.cxx b/dtrans/source/win32/clipb/MtaOleClipb.cxx
index baa2999..86c83b6 100644
--- a/dtrans/source/win32/clipb/MtaOleClipb.cxx
+++ b/dtrans/source/win32/clipb/MtaOleClipb.cxx
@@ -874,7 +874,6 @@ unsigned int WINAPI CMtaOleClipboard::clipboardChangedNotifierThreadProc( LPVOID
//
//--------------------------------------------------------------------
-inline
bool CMtaOleClipboard::WaitForThreadReady( ) const
{
bool bRet = false;
commit 6b5e43305798e261d0942298483440ed378fe525
Author: Kohei Yoshida <kohei.yoshida at suse.com>
Date: Fri Dec 2 14:02:45 2011 -0500
sal_Bool to bool.
diff --git a/dtrans/source/win32/clipb/MtaOleClipb.cxx b/dtrans/source/win32/clipb/MtaOleClipb.cxx
index 6ad8c30..baa2999 100644
--- a/dtrans/source/win32/clipb/MtaOleClipb.cxx
+++ b/dtrans/source/win32/clipb/MtaOleClipb.cxx
@@ -277,7 +277,7 @@ CMtaOleClipboard::CMtaOleClipboard( ) :
m_MtaOleReqWndClassAtom( 0 ),
m_hwndNextClipViewer( NULL ),
m_pfncClipViewerCallback( NULL ),
- m_bRunClipboardNotifierThread( sal_True ),
+ m_bRunClipboardNotifierThread( true ),
m_hClipboardChangedEvent( m_hClipboardChangedNotifierEvents[0] ),
m_hTerminateClipboardChangedNotifierEvent( m_hClipboardChangedNotifierEvents[1] ),
m_ClipboardChangedEventCount( 0 )
@@ -321,7 +321,7 @@ CMtaOleClipboard::~CMtaOleClipboard( )
ResetEvent( m_hEvtThrdReady );
// terminate the clipboard changed notifier thread
- m_bRunClipboardNotifierThread = sal_False;
+ m_bRunClipboardNotifierThread = false;
SetEvent( m_hTerminateClipboardChangedNotifierEvent );
sal_uInt32 dwResult = WaitForSingleObject(
@@ -474,15 +474,15 @@ HRESULT CMtaOleClipboard::setClipboard( IDataObject* pIDataObject )
// register a clipboard viewer
//--------------------------------------------------------------------
-sal_Bool CMtaOleClipboard::registerClipViewer( LPFNC_CLIPVIEWER_CALLBACK_t pfncClipViewerCallback )
+bool CMtaOleClipboard::registerClipViewer( LPFNC_CLIPVIEWER_CALLBACK_t pfncClipViewerCallback )
{
if ( !WaitForThreadReady( ) )
{
OSL_FAIL( "clipboard sta thread not ready" );
- return sal_False;
+ return false;
}
- sal_Bool bRet = sal_False;
+ bool bRet = false;
OSL_ENSURE( GetCurrentThreadId( ) != m_uOleThreadId, "registerClipViewer from within the OleThread called" );
@@ -501,9 +501,9 @@ sal_Bool CMtaOleClipboard::registerClipViewer( LPFNC_CLIPVIEWER_CALLBACK_t pfncC
// register a clipboard viewer
//--------------------------------------------------------------------
-sal_Bool CMtaOleClipboard::onRegisterClipViewer( LPFNC_CLIPVIEWER_CALLBACK_t pfncClipViewerCallback )
+bool CMtaOleClipboard::onRegisterClipViewer( LPFNC_CLIPVIEWER_CALLBACK_t pfncClipViewerCallback )
{
- sal_Bool bRet = sal_True;
+ bool bRet = true;
// we need exclusive access because the clipboard changed notifier
// thread also accesses this variable
@@ -514,13 +514,13 @@ sal_Bool CMtaOleClipboard::onRegisterClipViewer( LPFNC_CLIPVIEWER_CALLBACK_t pfn
{
// SetClipboardViewer sends a WM_DRAWCLIPBOARD message we ignore
// this message if we register ourself as clip viewer
- m_bInRegisterClipViewer = sal_True;
+ m_bInRegisterClipViewer = true;
m_hwndNextClipViewer = SetClipboardViewer( m_hwndMtaOleReqWnd );
- m_bInRegisterClipViewer = sal_False;
+ m_bInRegisterClipViewer = false;
// if there is no other cb-viewer the
// return value is NULL!!!
- bRet = IsWindow( m_hwndNextClipViewer ) ? sal_True : sal_False;
+ bRet = IsWindow( m_hwndNextClipViewer ) ? true : false;
// save the new callback function
m_pfncClipViewerCallback = pfncClipViewerCallback;
@@ -651,9 +651,9 @@ LRESULT CMtaOleClipboard::sendMessage( UINT msg, WPARAM wParam, LPARAM lParam )
// something to our wrapped window
//--------------------------------------------------------------------
-sal_Bool CMtaOleClipboard::postMessage( UINT msg, WPARAM wParam, LPARAM lParam )
+bool CMtaOleClipboard::postMessage( UINT msg, WPARAM wParam, LPARAM lParam )
{
- return PostMessageA( m_hwndMtaOleReqWnd, msg, wParam, lParam ) ? sal_True : sal_False;
+ return PostMessageA( m_hwndMtaOleReqWnd, msg, wParam, lParam ) ? true : false;
}
@@ -875,9 +875,9 @@ unsigned int WINAPI CMtaOleClipboard::clipboardChangedNotifierThreadProc( LPVOID
//--------------------------------------------------------------------
inline
-sal_Bool CMtaOleClipboard::WaitForThreadReady( ) const
+bool CMtaOleClipboard::WaitForThreadReady( ) const
{
- sal_Bool bRet = sal_False;
+ bool bRet = false;
if ( NULL != m_hEvtThrdReady )
{
diff --git a/dtrans/source/win32/clipb/MtaOleClipb.hxx b/dtrans/source/win32/clipb/MtaOleClipb.hxx
index dd4d079..532e792 100644
--- a/dtrans/source/win32/clipb/MtaOleClipb.hxx
+++ b/dtrans/source/win32/clipb/MtaOleClipb.hxx
@@ -68,28 +68,28 @@ public:
// a clipboard viewer
// returns true on success else false; use GetLastError( ) in
// false case
- sal_Bool registerClipViewer( LPFNC_CLIPVIEWER_CALLBACK_t pfncClipViewerCallback );
+ bool registerClipViewer( LPFNC_CLIPVIEWER_CALLBACK_t pfncClipViewerCallback );
private:
unsigned int run( );
- // create a hidden windows which serves as an request
- // target; so we guarantee synchronization
+ // create a hidden window which serves as an request target; so we
+ // guarantee synchronization
void createMtaOleReqWnd( );
// message support
- sal_Bool postMessage( UINT msg, WPARAM wParam = 0, LPARAM lParam = 0 );
+ bool postMessage( UINT msg, WPARAM wParam = 0, LPARAM lParam = 0 );
LRESULT sendMessage( UINT msg, WPARAM wParam = 0, LPARAM lParam = 0 );
//---------------------------------------------------------------
- // message handler functions; remeber these functions are called
+ // message handler functions; remember these functions are called
// from a different thread context!
//---------------------------------------------------------------
LRESULT onSetClipboard( IDataObject* pIDataObject );
LRESULT onGetClipboard( LPSTREAM* ppStream );
LRESULT onFlushClipboard( );
- sal_Bool onRegisterClipViewer( LPFNC_CLIPVIEWER_CALLBACK_t pfncClipViewerCallback );
+ bool onRegisterClipViewer( LPFNC_CLIPVIEWER_CALLBACK_t pfncClipViewerCallback );
// win32 clipboard-viewer support
LRESULT onChangeCBChain( HWND hWndRemove, HWND hWndNext );
@@ -100,7 +100,7 @@ private:
static unsigned int WINAPI clipboardChangedNotifierThreadProc( LPVOID pParam );
- sal_Bool WaitForThreadReady( ) const;
+ bool WaitForThreadReady( ) const;
private:
HANDLE m_hOleThread;
@@ -110,9 +110,9 @@ private:
ATOM m_MtaOleReqWndClassAtom;
HWND m_hwndNextClipViewer;
LPFNC_CLIPVIEWER_CALLBACK_t m_pfncClipViewerCallback;
- sal_Bool m_bInRegisterClipViewer;
+ bool m_bInRegisterClipViewer;
- sal_Bool m_bRunClipboardNotifierThread;
+ bool m_bRunClipboardNotifierThread;
HANDLE m_hClipboardChangedNotifierThread;
HANDLE m_hClipboardChangedNotifierEvents[2];
HANDLE& m_hClipboardChangedEvent;
commit 0f49c6c3d8d0e8d7410e0346fda31ebf7cd9b00c
Author: Kohei Yoshida <kohei.yoshida at suse.com>
Date: Fri Dec 2 13:53:58 2011 -0500
Encapsulate implementation of CMtaOleClipboard under win32.
This class is used only for win32 clipboard implementation. Better
move it to where only the win32 implementation code can access it.
diff --git a/dtrans/Library_sysdtrans.mk b/dtrans/Library_sysdtrans.mk
index ad365db..8fb7a41 100644
--- a/dtrans/Library_sysdtrans.mk
+++ b/dtrans/Library_sysdtrans.mk
@@ -66,8 +66,8 @@ $(eval $(call gb_Library_add_exception_objects,sysdtrans,\
dtrans/source/win32/clipb/WinClipbImpl \
dtrans/source/win32/clipb/WinClipboard \
dtrans/source/win32/clipb/wcbentry \
+ dtrans/source/win32/clipb/MtaOleClipb \
dtrans/source/win32/misc/ImplHelper \
- dtrans/source/win32/mtaole/MtaOleClipb \
))
# vim: set noet sw=4 ts=4:
diff --git a/dtrans/source/inc/MtaOleClipb.hxx b/dtrans/source/inc/MtaOleClipb.hxx
deleted file mode 100644
index dd4d079..0000000
--- a/dtrans/source/inc/MtaOleClipb.hxx
+++ /dev/null
@@ -1,137 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*************************************************************************
- *
- * 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.
- *
- ************************************************************************/
-
-#ifndef _MTAOLECLIPB_HXX_
-#define _MTAOLECLIPB_HXX_
-
-#include <sal/types.h>
-#include <osl/mutex.hxx>
-
-#if defined _MSC_VER
-#pragma warning(push,1)
-#endif
-#include <objidl.h>
-#if defined _MSC_VER
-#pragma warning(pop)
-#endif
-
-//--------------------------------------------------------
-// the Mta-Ole clipboard class is for internal use only!
-// only one instance of this class should be created, the
-// user has to ensure this!
-// the class is not thread-safe because it will be used
-// only from within the clipboard service and the methods
-// of the clipboard service are already synchronized
-//--------------------------------------------------------
-
-class CMtaOleClipboard
-{
-public:
- typedef void ( WINAPI *LPFNC_CLIPVIEWER_CALLBACK_t )( void );
-
-public:
- CMtaOleClipboard( );
- ~CMtaOleClipboard( );
-
- // clipboard functions
- HRESULT setClipboard( IDataObject* pIDataObject );
- HRESULT getClipboard( IDataObject** ppIDataObject );
- HRESULT flushClipboard( );
-
- // register/unregister a clipboard viewer; there can only
- // be one at a time; parameter NULL means unregister
- // a clipboard viewer
- // returns true on success else false; use GetLastError( ) in
- // false case
- sal_Bool registerClipViewer( LPFNC_CLIPVIEWER_CALLBACK_t pfncClipViewerCallback );
-
-private:
- unsigned int run( );
-
- // create a hidden windows which serves as an request
- // target; so we guarantee synchronization
- void createMtaOleReqWnd( );
-
- // message support
- sal_Bool postMessage( UINT msg, WPARAM wParam = 0, LPARAM lParam = 0 );
- LRESULT sendMessage( UINT msg, WPARAM wParam = 0, LPARAM lParam = 0 );
-
- //---------------------------------------------------------------
- // message handler functions; remeber these functions are called
- // from a different thread context!
- //---------------------------------------------------------------
-
- LRESULT onSetClipboard( IDataObject* pIDataObject );
- LRESULT onGetClipboard( LPSTREAM* ppStream );
- LRESULT onFlushClipboard( );
- sal_Bool onRegisterClipViewer( LPFNC_CLIPVIEWER_CALLBACK_t pfncClipViewerCallback );
-
- // win32 clipboard-viewer support
- LRESULT onChangeCBChain( HWND hWndRemove, HWND hWndNext );
- LRESULT onDrawClipboard( );
-
- static LRESULT CALLBACK mtaOleReqWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
- static unsigned int WINAPI oleThreadProc( LPVOID pParam );
-
- static unsigned int WINAPI clipboardChangedNotifierThreadProc( LPVOID pParam );
-
- sal_Bool WaitForThreadReady( ) const;
-
-private:
- HANDLE m_hOleThread;
- unsigned m_uOleThreadId;
- HANDLE m_hEvtThrdReady;
- HWND m_hwndMtaOleReqWnd;
- ATOM m_MtaOleReqWndClassAtom;
- HWND m_hwndNextClipViewer;
- LPFNC_CLIPVIEWER_CALLBACK_t m_pfncClipViewerCallback;
- sal_Bool m_bInRegisterClipViewer;
-
- sal_Bool m_bRunClipboardNotifierThread;
- HANDLE m_hClipboardChangedNotifierThread;
- HANDLE m_hClipboardChangedNotifierEvents[2];
- HANDLE& m_hClipboardChangedEvent;
- HANDLE& m_hTerminateClipboardChangedNotifierEvent;
- osl::Mutex m_ClipboardChangedEventCountMutex;
- sal_Int32 m_ClipboardChangedEventCount;
-
- osl::Mutex m_pfncClipViewerCallbackMutex;
-
- static CMtaOleClipboard* s_theMtaOleClipboardInst;
-
-// not allowed
-private:
- CMtaOleClipboard( const CMtaOleClipboard& );
- CMtaOleClipboard& operator=( const CMtaOleClipboard& );
-
- friend LRESULT CALLBACK mtaOleReqWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
-};
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dtrans/source/win32/clipb/MtaOleClipb.cxx b/dtrans/source/win32/clipb/MtaOleClipb.cxx
new file mode 100644
index 0000000..6ad8c30
--- /dev/null
+++ b/dtrans/source/win32/clipb/MtaOleClipb.cxx
@@ -0,0 +1,892 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+/*
+ MtaOleClipb.cxx - documentation
+
+ This class setup a single threaded apartment (sta) thread to deal with
+ the ole clipboard, which runs only in an sta thread.
+ The consequence is that callback from the ole clipboard are in the
+ context of this sta thread. In the soffice applications this may lead
+ to problems because they all use the one and only mutex called
+ SolarMutex.
+ In order to transfer clipboard requests to our sta thread we use a
+ hidden window an forward these requests via window messages.
+*/
+
+#ifdef _MSC_VER
+#pragma warning( disable : 4786 ) // identifier was truncated to 'number'
+ // characters in the debug information
+#endif
+
+//#define UNICODE
+#include <osl/diagnose.h>
+
+#include "MtaOleClipb.hxx"
+#include <osl/conditn.hxx>
+
+#include <wchar.h>
+#include <process.h>
+
+#include <systools/win32/comtools.hxx>
+#ifdef __MINGW32__
+#define __uuidof(I) IID_##I
+#endif
+
+//----------------------------------------------------------------
+// namespace directives
+//----------------------------------------------------------------
+
+using osl::Condition;
+using osl::Mutex;
+using osl::MutexGuard;
+using osl::ClearableMutexGuard;
+
+//----------------------------------------------------------------
+// defines
+//----------------------------------------------------------------
+
+namespace /* private */
+{
+ char CLIPSRV_DLL_NAME[] = "sysdtrans.dll";
+ char g_szWndClsName[] = "MtaOleReqWnd###";
+
+ //--------------------------------------------------------
+ // messages constants
+ //--------------------------------------------------------
+
+ const sal_uInt32 MSG_SETCLIPBOARD = WM_USER + 0x0001;
+ const sal_uInt32 MSG_GETCLIPBOARD = WM_USER + 0x0002;
+ const sal_uInt32 MSG_REGCLIPVIEWER = WM_USER + 0x0003;
+ const sal_uInt32 MSG_FLUSHCLIPBOARD = WM_USER + 0x0004;
+ const sal_uInt32 MSG_SHUTDOWN = WM_USER + 0x0005;
+
+ const sal_uInt32 MAX_WAITTIME = 10000; // msec
+ const sal_uInt32 MAX_WAIT_SHUTDOWN = 10000; // msec
+ const sal_uInt32 MAX_CLIPEVENT_PROCESSING_TIME = 5000; // msec
+
+ const sal_Bool MANUAL_RESET = sal_True;
+ const sal_Bool AUTO_RESET = sal_False;
+ const sal_Bool INIT_NONSIGNALED = sal_False;
+
+ //------------------------------------------------------
+ /* Cannot use osl conditions because they are blocking
+ without waking up on messages sent by another thread
+ this leads to deadlocks because we are blocking the
+ communication between inter-thread marshalled COM
+ pointers.
+ COM Proxy-Stub communication uses SendMessages for
+ synchronization purposes.
+ */
+ class Win32Condition
+ {
+ public:
+ // ctor
+ Win32Condition()
+ {
+ m_hEvent = CreateEvent(
+ 0, /* no security */
+ true, /* manual reset */
+ false, /* initial state not signaled */
+ 0); /* automatic name */
+ }
+
+ // dtor
+ ~Win32Condition()
+ {
+ CloseHandle(m_hEvent);
+ }
+
+ // wait infinite for event be signaled
+ // leave messages sent through
+ void wait()
+ {
+ while(1)
+ {
+ DWORD dwResult =
+ MsgWaitForMultipleObjects(1, &m_hEvent, FALSE, INFINITE, QS_SENDMESSAGE);
+
+ switch (dwResult)
+ {
+ case WAIT_OBJECT_0:
+ return;
+
+ case WAIT_OBJECT_0 + 1:
+ {
+ /* PeekMessage processes all messages in the SendMessage
+ queue that's what we want, messages from the PostMessage
+ queue stay untouched */
+ MSG msg;
+ PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
+
+ break;
+ }
+ }
+ }
+ }
+
+ // reset the event
+ void set()
+ {
+ SetEvent(m_hEvent);
+ }
+
+ private:
+ HANDLE m_hEvent;
+
+ // prevent copy/assignment
+ private:
+ Win32Condition(const Win32Condition&);
+ Win32Condition& operator=(const Win32Condition&);
+ };
+
+ //------------------------------------------
+ // we use one condition for every request
+ //------------------------------------------
+
+ struct MsgCtx
+ {
+ Win32Condition aCondition;
+ HRESULT hr;
+ };
+
+} /* namespace private */
+
+//----------------------------------------------------------------
+// static member initialization
+//----------------------------------------------------------------
+
+CMtaOleClipboard* CMtaOleClipboard::s_theMtaOleClipboardInst = NULL;
+
+//--------------------------------------------------------------------
+// marshal an IDataObject
+//--------------------------------------------------------------------
+
+//inline
+HRESULT MarshalIDataObjectInStream( IDataObject* pIDataObject, LPSTREAM* ppStream )
+{
+ OSL_ASSERT( NULL != pIDataObject );
+ OSL_ASSERT( NULL != ppStream );
+
+ *ppStream = NULL;
+ return CoMarshalInterThreadInterfaceInStream(
+ __uuidof(IDataObject), //The IID of inteface to be marshaled
+ pIDataObject, //The interface pointer
+ ppStream //IStream pointer
+ );
+}
+
+//--------------------------------------------------------------------
+// unmarshal an IDataObject
+//--------------------------------------------------------------------
+
+//inline
+HRESULT UnmarshalIDataObjectAndReleaseStream( LPSTREAM lpStream, IDataObject** ppIDataObject )
+{
+ OSL_ASSERT( NULL != lpStream );
+ OSL_ASSERT( NULL != ppIDataObject );
+
+ *ppIDataObject = NULL;
+ return CoGetInterfaceAndReleaseStream(
+ lpStream,
+ __uuidof(IDataObject),
+ reinterpret_cast<LPVOID*>(ppIDataObject));
+}
+
+//--------------------------------------------------------------------
+// helper class to ensure that the calling thread has com initialized
+//--------------------------------------------------------------------
+
+class CAutoComInit
+{
+public:
+ CAutoComInit( )
+ {
+ /*
+ to be safe we call CoInitialize
+ although it is not necessary if
+ the calling thread was created
+ using osl_CreateThread because
+ this function calls CoInitialize
+ for every thread it creates
+ */
+ m_hResult = CoInitialize( NULL );
+
+ if ( S_OK == m_hResult )
+ OSL_FAIL( \
+ "com was not yet initialzed, the thread was not created using osl_createThread" );
+ else if ( FAILED( m_hResult ) && !( RPC_E_CHANGED_MODE == m_hResult ) )
+ OSL_FAIL( \
+ "com could not be initialized, maybe the thread was not created using osl_createThread" );
+ }
+
+ ~CAutoComInit( )
+ {
+ /*
+ we only call CoUninitialize when
+ CoInitailize returned S_FALSE, what
+ means that com was already initialize
+ for that thread so we keep the balance
+ if CoInitialize returned S_OK what means
+ com was not yet initialized we better
+ let com initialized or we may run into
+ the realm of undefined behaviour
+ */
+ if ( m_hResult == S_FALSE )
+ CoUninitialize( );
+ }
+
+private:
+ HRESULT m_hResult;
+};
+
+//--------------------------------------------------------------------
+// ctor
+//--------------------------------------------------------------------
+
+CMtaOleClipboard::CMtaOleClipboard( ) :
+ m_hOleThread( NULL ),
+ m_uOleThreadId( 0 ),
+ m_hEvtThrdReady( NULL ),
+ m_hwndMtaOleReqWnd( NULL ),
+ m_MtaOleReqWndClassAtom( 0 ),
+ m_hwndNextClipViewer( NULL ),
+ m_pfncClipViewerCallback( NULL ),
+ m_bRunClipboardNotifierThread( sal_True ),
+ m_hClipboardChangedEvent( m_hClipboardChangedNotifierEvents[0] ),
+ m_hTerminateClipboardChangedNotifierEvent( m_hClipboardChangedNotifierEvents[1] ),
+ m_ClipboardChangedEventCount( 0 )
+{
+ // signals that the thread was successfully setup
+ m_hEvtThrdReady = CreateEventA( 0, MANUAL_RESET, INIT_NONSIGNALED, NULL );
+
+ OSL_ASSERT( NULL != m_hEvtThrdReady );
+
+ s_theMtaOleClipboardInst = this;
+
+ m_hOleThread = (HANDLE)_beginthreadex(
+ NULL, 0, CMtaOleClipboard::oleThreadProc, this, 0, &m_uOleThreadId );
+ OSL_ASSERT( NULL != m_hOleThread );
+
+ //----------------------------------------------
+ // setup the clipboard changed notifier thread
+ //----------------------------------------------
+
+ m_hClipboardChangedNotifierEvents[0] = CreateEventA( 0, MANUAL_RESET, INIT_NONSIGNALED, NULL );
+ OSL_ASSERT( NULL != m_hClipboardChangedNotifierEvents[0] );
+
+ m_hClipboardChangedNotifierEvents[1] = CreateEventA( 0, MANUAL_RESET, INIT_NONSIGNALED, NULL );
+ OSL_ASSERT( NULL != m_hClipboardChangedNotifierEvents[1] );
+
+ unsigned uThreadId;
+ m_hClipboardChangedNotifierThread = (HANDLE)_beginthreadex(
+ NULL, 0, CMtaOleClipboard::clipboardChangedNotifierThreadProc, this, 0, &uThreadId );
+
+ OSL_ASSERT( NULL != m_hClipboardChangedNotifierThread );
+}
+
+//--------------------------------------------------------------------
+// dtor
+//--------------------------------------------------------------------
+
+CMtaOleClipboard::~CMtaOleClipboard( )
+{
+ // block calling threads out
+ if ( NULL != m_hEvtThrdReady )
+ ResetEvent( m_hEvtThrdReady );
+
+ // terminate the clipboard changed notifier thread
+ m_bRunClipboardNotifierThread = sal_False;
+ SetEvent( m_hTerminateClipboardChangedNotifierEvent );
+
+ sal_uInt32 dwResult = WaitForSingleObject(
+ m_hClipboardChangedNotifierThread, MAX_WAIT_SHUTDOWN );
+
+ OSL_ENSURE( dwResult == WAIT_OBJECT_0, "clipboard notifier thread could not terminate" );
+
+ if ( NULL != m_hClipboardChangedNotifierThread )
+ CloseHandle( m_hClipboardChangedNotifierThread );
+
+ if ( NULL != m_hClipboardChangedNotifierEvents[0] )
+ CloseHandle( m_hClipboardChangedNotifierEvents[0] );
+
+ if ( NULL != m_hClipboardChangedNotifierEvents[1] )
+ CloseHandle( m_hClipboardChangedNotifierEvents[1] );
+
+ // end the thread
+ // because DestroyWindow can only be called
+ // from within the thread that created the window
+ sendMessage( MSG_SHUTDOWN,
+ static_cast< WPARAM >( 0 ),
+ static_cast< LPARAM >( 0 ) );
+
+ // wait for thread shutdown
+ dwResult = WaitForSingleObject( m_hOleThread, MAX_WAIT_SHUTDOWN );
+ OSL_ENSURE( dwResult == WAIT_OBJECT_0, "OleThread could not terminate" );
+
+ if ( NULL != m_hOleThread )
+ CloseHandle( m_hOleThread );
+
+ if ( NULL != m_hEvtThrdReady )
+ CloseHandle( m_hEvtThrdReady );
+
+ if ( m_MtaOleReqWndClassAtom )
+ UnregisterClassA( g_szWndClsName, NULL );
+
+ OSL_ENSURE( ( NULL == m_pfncClipViewerCallback ) &&
+ !IsWindow( m_hwndNextClipViewer ), \
+ "Clipboard viewer not properly unregistered" );
+}
+
+
+//--------------------------------------------------------------------
+//
+//--------------------------------------------------------------------
+
+HRESULT CMtaOleClipboard::flushClipboard( )
+{
+ if ( !WaitForThreadReady( ) )
+ {
+ OSL_FAIL( "clipboard sta thread not ready" );
+ return E_FAIL;
+ }
+
+ OSL_ENSURE( GetCurrentThreadId( ) != m_uOleThreadId, \
+ "flushClipboard from within clipboard sta thread called" );
+
+ MsgCtx aMsgCtx;
+
+ postMessage( MSG_FLUSHCLIPBOARD,
+ static_cast< WPARAM >( 0 ),
+ reinterpret_cast< LPARAM >( &aMsgCtx ) );
+
+ aMsgCtx.aCondition.wait( /* infinite */ );
+
+ return aMsgCtx.hr;
+}
+
+//--------------------------------------------------------------------
+//
+//--------------------------------------------------------------------
+
+HRESULT CMtaOleClipboard::getClipboard( IDataObject** ppIDataObject )
+{
+ OSL_PRECOND( NULL != ppIDataObject, "invalid parameter" );
+ OSL_PRECOND( GetCurrentThreadId( ) != m_uOleThreadId, "getClipboard from within clipboard sta thread called" );
+
+ if ( !WaitForThreadReady( ) )
+ {
+ OSL_FAIL( "clipboard sta thread not ready" );
+ return E_FAIL;
+ }
+
+ CAutoComInit comAutoInit;
+
+ LPSTREAM lpStream;
+ HRESULT hr = E_FAIL;
+
+ *ppIDataObject = NULL;
+
+ MsgCtx aMsgCtx;
+
+ postMessage( MSG_GETCLIPBOARD,
+ reinterpret_cast< WPARAM >( &lpStream ),
+ reinterpret_cast< LPARAM >( &aMsgCtx ) );
+
+ aMsgCtx.aCondition.wait( /* infinite */ );
+
+ hr = aMsgCtx.hr;
+
+ if ( SUCCEEDED( hr ) )
+ {
+ hr = UnmarshalIDataObjectAndReleaseStream( lpStream, ppIDataObject );
+ OSL_ENSURE( SUCCEEDED( hr ), "unmarshalling clipboard data object failed" );
+ }
+
+ return hr;
+}
+
+//--------------------------------------------------------------------
+// this is an asynchronous method that's why we don't wait until the
+// request is completed
+//--------------------------------------------------------------------
+
+HRESULT CMtaOleClipboard::setClipboard( IDataObject* pIDataObject )
+{
+ if ( !WaitForThreadReady( ) )
+ {
+ OSL_FAIL( "clipboard sta thread not ready" );
+ return E_FAIL;
+ }
+
+ CAutoComInit comAutoInit;
+
+ OSL_ENSURE( GetCurrentThreadId( ) != m_uOleThreadId, "setClipboard from within the clipboard sta thread called" );
+
+ // because we marshall this request
+ // into the sta thread we better
+ // acquire the interface here so
+ // that the object will not be
+ // destroyed before the ole clipboard
+ // can acquire it
+ // remember: pIDataObject may be NULL
+ // which is an request to clear the
+ // current clipboard content
+ if ( pIDataObject )
+ pIDataObject->AddRef( );
+
+ postMessage(
+ MSG_SETCLIPBOARD,
+ reinterpret_cast< WPARAM >( pIDataObject ),
+ 0 );
+
+ // because this is an asynchronous function
+ // the return value is useless
+ return S_OK;
+}
+
+//--------------------------------------------------------------------
+// register a clipboard viewer
+//--------------------------------------------------------------------
+
+sal_Bool CMtaOleClipboard::registerClipViewer( LPFNC_CLIPVIEWER_CALLBACK_t pfncClipViewerCallback )
+{
+ if ( !WaitForThreadReady( ) )
+ {
+ OSL_FAIL( "clipboard sta thread not ready" );
+ return sal_False;
+ }
+
+ sal_Bool bRet = sal_False;
+
+ OSL_ENSURE( GetCurrentThreadId( ) != m_uOleThreadId, "registerClipViewer from within the OleThread called" );
+
+ MsgCtx aMsgCtx;
+
+ postMessage( MSG_REGCLIPVIEWER,
+ reinterpret_cast<WPARAM>( pfncClipViewerCallback ),
+ reinterpret_cast<LPARAM>( &aMsgCtx ) );
+
+ aMsgCtx.aCondition.wait( /* infinite */ );
+
+ return bRet;
+}
+
+//--------------------------------------------------------------------
+// register a clipboard viewer
+//--------------------------------------------------------------------
+
+sal_Bool CMtaOleClipboard::onRegisterClipViewer( LPFNC_CLIPVIEWER_CALLBACK_t pfncClipViewerCallback )
+{
+ sal_Bool bRet = sal_True;
+
+ // we need exclusive access because the clipboard changed notifier
+ // thread also accesses this variable
+ MutexGuard aGuard( m_pfncClipViewerCallbackMutex );
+
+ // register if not yet done
+ if ( ( NULL != pfncClipViewerCallback ) && ( NULL == m_pfncClipViewerCallback ) )
+ {
+ // SetClipboardViewer sends a WM_DRAWCLIPBOARD message we ignore
+ // this message if we register ourself as clip viewer
+ m_bInRegisterClipViewer = sal_True;
+ m_hwndNextClipViewer = SetClipboardViewer( m_hwndMtaOleReqWnd );
+ m_bInRegisterClipViewer = sal_False;
+
+ // if there is no other cb-viewer the
+ // return value is NULL!!!
+ bRet = IsWindow( m_hwndNextClipViewer ) ? sal_True : sal_False;
+
+ // save the new callback function
+ m_pfncClipViewerCallback = pfncClipViewerCallback;
+ }
+ else if ( ( NULL == pfncClipViewerCallback ) && ( NULL != m_pfncClipViewerCallback ) )
+ {
+ m_pfncClipViewerCallback = NULL;
+
+ // unregister if input parameter is NULL and we previously registered
+ // as clipboard viewer
+ ChangeClipboardChain( m_hwndMtaOleReqWnd, m_hwndNextClipViewer );
+ m_hwndNextClipViewer = NULL;
+ }
+
+ return bRet;
+}
+
+//--------------------------------------------------------------------
+//
+//--------------------------------------------------------------------
+
+LRESULT CMtaOleClipboard::onSetClipboard( IDataObject* pIDataObject )
+{
+ return static_cast<LRESULT>( OleSetClipboard( pIDataObject ) );
+}
+
+//--------------------------------------------------------------------
+//
+//--------------------------------------------------------------------
+
+LRESULT CMtaOleClipboard::onGetClipboard( LPSTREAM* ppStream )
+{
+ OSL_ASSERT(NULL != ppStream);
+
+ IDataObjectPtr pIDataObject;
+
+ // forward the request to the OleClipboard
+ HRESULT hr = OleGetClipboard( &pIDataObject );
+ if ( SUCCEEDED( hr ) )
+ {
+ hr = MarshalIDataObjectInStream(pIDataObject.get(), ppStream);
+ OSL_ENSURE(SUCCEEDED(hr), "marshalling cliboard data object failed");
+ }
+ return static_cast<LRESULT>(hr);
+}
+
+//--------------------------------------------------------------------
+// flush the ole-clipboard
+//--------------------------------------------------------------------
+
+LRESULT CMtaOleClipboard::onFlushClipboard( )
+{
+ return static_cast<LRESULT>( OleFlushClipboard( ) );
+}
+
+//--------------------------------------------------------------------
+// handle clipboard chain change event
+//--------------------------------------------------------------------
+
+LRESULT CMtaOleClipboard::onChangeCBChain( HWND hWndRemove, HWND hWndNext )
+{
+ if ( hWndRemove == m_hwndNextClipViewer )
+ m_hwndNextClipViewer = hWndNext;
+ else if ( IsWindow( m_hwndNextClipViewer ) )
+ {
+ // forward the message to the next one
+ DWORD_PTR dwpResult;
+ SendMessageTimeoutA(
+ m_hwndNextClipViewer,
+ WM_CHANGECBCHAIN,
+ reinterpret_cast<WPARAM>(hWndRemove),
+ reinterpret_cast<LPARAM>(hWndNext),
+ SMTO_BLOCK,
+ MAX_CLIPEVENT_PROCESSING_TIME,
+ &dwpResult );
+ }
+
+ return 0;
+}
+
+//--------------------------------------------------------------------
+// handle draw clipboard event
+//--------------------------------------------------------------------
+
+LRESULT CMtaOleClipboard::onDrawClipboard( )
+{
+ // we don't send a notification if we are
+ // registering ourself as clipboard
+ if ( !m_bInRegisterClipViewer )
+ {
+ ClearableMutexGuard aGuard( m_ClipboardChangedEventCountMutex );
+
+ m_ClipboardChangedEventCount++;
+ SetEvent( m_hClipboardChangedEvent );
+
+ aGuard.clear( );
+ }
+
+ // foward the message to the next viewer in the chain
+ if ( IsWindow( m_hwndNextClipViewer ) )
+ {
+ DWORD_PTR dwpResult;
+ SendMessageTimeoutA(
+ m_hwndNextClipViewer,
+ WM_DRAWCLIPBOARD,
+ static_cast< WPARAM >( 0 ),
+ static_cast< LPARAM >( 0 ),
+ SMTO_BLOCK,
+ MAX_CLIPEVENT_PROCESSING_TIME,
+ &dwpResult );
+ }
+
+ return 0;
+}
+
+//--------------------------------------------------------------------
+// SendMessage so we don't need to supply the HWND if we send
+// something to our wrapped window
+//--------------------------------------------------------------------
+
+LRESULT CMtaOleClipboard::sendMessage( UINT msg, WPARAM wParam, LPARAM lParam )
+{
+ return ::SendMessageA( m_hwndMtaOleReqWnd, msg, wParam, lParam );
+}
+
+//--------------------------------------------------------------------
+// PostMessage so we don't need to supply the HWND if we send
+// something to our wrapped window
+//--------------------------------------------------------------------
+
+sal_Bool CMtaOleClipboard::postMessage( UINT msg, WPARAM wParam, LPARAM lParam )
+{
+ return PostMessageA( m_hwndMtaOleReqWnd, msg, wParam, lParam ) ? sal_True : sal_False;
+}
+
+
+//--------------------------------------------------------------------
+// the window proc
+//--------------------------------------------------------------------
+
+LRESULT CALLBACK CMtaOleClipboard::mtaOleReqWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
+{
+ LRESULT lResult = 0;
+
+ // get a connection to the class-instance via the static member
+ CMtaOleClipboard* pImpl = CMtaOleClipboard::s_theMtaOleClipboardInst;
+ OSL_ASSERT( NULL != pImpl );
+
+ switch( uMsg )
+ {
+ case MSG_SETCLIPBOARD:
+ {
+ IDataObject* pIDataObject = reinterpret_cast< IDataObject* >( wParam );
+ pImpl->onSetClipboard( pIDataObject );
+
+ // in setClipboard we did acquire the
+ // interface pointer in order to prevent
+ // destruction of the object before the
+ // ole clipboard can acquire the interface
+ // now we release the interface so that
+ // our lostOwnership mechanism works
+ // remember: pIDataObject may be NULL
+ if ( pIDataObject )
+ pIDataObject->Release( );
+ }
+ break;
+
+ case MSG_GETCLIPBOARD:
+ {
+ MsgCtx* aMsgCtx = reinterpret_cast< MsgCtx* >( lParam );
+ OSL_ASSERT( aMsgCtx );
+
+ aMsgCtx->hr = pImpl->onGetClipboard( reinterpret_cast< LPSTREAM* >(wParam) );
+ aMsgCtx->aCondition.set( );
+ }
+ break;
+
+ case MSG_FLUSHCLIPBOARD:
+ {
+ MsgCtx* aMsgCtx = reinterpret_cast< MsgCtx* >( lParam );
+ OSL_ASSERT( aMsgCtx );
+
+ aMsgCtx->hr = pImpl->onFlushClipboard( );
+ aMsgCtx->aCondition.set( );
+ }
+ break;
+
+ case MSG_REGCLIPVIEWER:
+ {
+ MsgCtx* aMsgCtx = reinterpret_cast< MsgCtx* >( lParam );
+ OSL_ASSERT( aMsgCtx );
+
+ pImpl->onRegisterClipViewer( reinterpret_cast<CMtaOleClipboard::LPFNC_CLIPVIEWER_CALLBACK_t>(wParam) );
+ aMsgCtx->aCondition.set( );
+ }
+ break;
+
+ case WM_CHANGECBCHAIN:
+ lResult = pImpl->onChangeCBChain(
+ reinterpret_cast< HWND >( wParam ), reinterpret_cast< HWND >( lParam ) );
+ break;
+
+ case WM_DRAWCLIPBOARD:
+ lResult = pImpl->onDrawClipboard( );
+ break;
+
+ case MSG_SHUTDOWN:
+ DestroyWindow( pImpl->m_hwndMtaOleReqWnd );
+ break;
+
+ // force the sta thread to end
+ case WM_DESTROY:
+ PostQuitMessage( 0 );
+ break;
+
+ default:
+ lResult = DefWindowProcA( hWnd, uMsg, wParam, lParam );
+ break;
+ }
+
+ return lResult;
+}
+
+//--------------------------------------------------------------------
+//
+//--------------------------------------------------------------------
+
+void CMtaOleClipboard::createMtaOleReqWnd( )
+{
+ WNDCLASSEXA wcex;
+
+ HINSTANCE hInst = GetModuleHandleA( CLIPSRV_DLL_NAME );
+ OSL_ENSURE( NULL != hInst, "The name of the clipboard service dll must have changed" );
+
+ ZeroMemory( &wcex, sizeof( WNDCLASSEXA ) );
+
+ wcex.cbSize = sizeof(WNDCLASSEXA);
+ wcex.style = 0;
+ wcex.lpfnWndProc = static_cast< WNDPROC >( CMtaOleClipboard::mtaOleReqWndProc );
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = hInst;
+ wcex.hIcon = NULL;
+ wcex.hCursor = NULL;
+ wcex.hbrBackground = NULL;
+ wcex.lpszMenuName = NULL;
+ wcex.lpszClassName = g_szWndClsName;
+ wcex.hIconSm = NULL;
+
+ m_MtaOleReqWndClassAtom = RegisterClassExA( &wcex );
+
+ if ( 0 != m_MtaOleReqWndClassAtom )
+ m_hwndMtaOleReqWnd = CreateWindowA(
+ g_szWndClsName, NULL, 0, 0, 0, 0, 0, NULL, NULL, hInst, NULL );
+}
+
+//--------------------------------------------------------------------
+//
+//--------------------------------------------------------------------
+
+unsigned int CMtaOleClipboard::run( )
+{
+ #if OSL_DEBUG_LEVEL > 0
+ HRESULT hr =
+ #endif
+ OleInitialize( NULL );
+ OSL_ASSERT( SUCCEEDED( hr ) );
+
+ createMtaOleReqWnd( );
+
+ unsigned int nRet;
+
+ if ( IsWindow( m_hwndMtaOleReqWnd ) )
+ {
+ if ( NULL != m_hEvtThrdReady )
+ SetEvent( m_hEvtThrdReady );
+
+ // pumping messages
+ MSG msg;
+ while( GetMessageA( &msg, NULL, 0, 0 ) )
+ DispatchMessageA( &msg );
+
+ nRet = 0;
+ }
+ else
+ nRet = ~0U;
+
+ OleUninitialize( );
+
+ return nRet;
+}
+
+//--------------------------------------------------------------------
+//
+//--------------------------------------------------------------------
+
+unsigned int WINAPI CMtaOleClipboard::oleThreadProc( LPVOID pParam )
+{
+ CMtaOleClipboard* pInst =
+ reinterpret_cast<CMtaOleClipboard*>( pParam );
+ OSL_ASSERT( NULL != pInst );
+
+ return pInst->run( );
+}
+
+//--------------------------------------------------------------------
+//
+//--------------------------------------------------------------------
+
+unsigned int WINAPI CMtaOleClipboard::clipboardChangedNotifierThreadProc( LPVOID pParam )
+{
+ CMtaOleClipboard* pInst = reinterpret_cast< CMtaOleClipboard* >( pParam );
+ OSL_ASSERT( NULL != pInst );
+
+ CoInitialize( NULL );
+
+ // assuming we don't need a lock for
+ // a boolean variable like m_bRun...
+ while ( pInst->m_bRunClipboardNotifierThread )
+ {
+ // wait for clipboard changed or terminate event
+ WaitForMultipleObjects( 2, pInst->m_hClipboardChangedNotifierEvents, false, INFINITE );
+
+ ClearableMutexGuard aGuard( pInst->m_ClipboardChangedEventCountMutex );
+
+ if ( pInst->m_ClipboardChangedEventCount > 0 )
+ {
+ pInst->m_ClipboardChangedEventCount--;
+ if ( 0 == pInst->m_ClipboardChangedEventCount )
+ ResetEvent( pInst->m_hClipboardChangedEvent );
+
+ aGuard.clear( );
+
+ // nobody should touch m_pfncClipViewerCallback while we do
+ MutexGuard aClipViewerGuard( pInst->m_pfncClipViewerCallbackMutex );
+
+ // notify all clipboard listener
+ if ( pInst->m_pfncClipViewerCallback )
+ pInst->m_pfncClipViewerCallback( );
+ }
+ else
+ aGuard.clear( );
+ }
+
+ CoUninitialize( );
+
+ return ( 0 );
+}
+
+//--------------------------------------------------------------------
+//
+//--------------------------------------------------------------------
+
+inline
+sal_Bool CMtaOleClipboard::WaitForThreadReady( ) const
+{
+ sal_Bool bRet = sal_False;
+
+ if ( NULL != m_hEvtThrdReady )
+ {
+ DWORD dwResult = WaitForSingleObject(
+ m_hEvtThrdReady, MAX_WAITTIME );
+ bRet = ( dwResult == WAIT_OBJECT_0 );
+ }
+
+ return bRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dtrans/source/win32/clipb/MtaOleClipb.hxx b/dtrans/source/win32/clipb/MtaOleClipb.hxx
new file mode 100644
index 0000000..dd4d079
--- /dev/null
+++ b/dtrans/source/win32/clipb/MtaOleClipb.hxx
@@ -0,0 +1,137 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _MTAOLECLIPB_HXX_
+#define _MTAOLECLIPB_HXX_
+
+#include <sal/types.h>
+#include <osl/mutex.hxx>
+
+#if defined _MSC_VER
+#pragma warning(push,1)
+#endif
+#include <objidl.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+//--------------------------------------------------------
+// the Mta-Ole clipboard class is for internal use only!
+// only one instance of this class should be created, the
+// user has to ensure this!
+// the class is not thread-safe because it will be used
+// only from within the clipboard service and the methods
+// of the clipboard service are already synchronized
+//--------------------------------------------------------
+
+class CMtaOleClipboard
+{
+public:
+ typedef void ( WINAPI *LPFNC_CLIPVIEWER_CALLBACK_t )( void );
+
+public:
+ CMtaOleClipboard( );
+ ~CMtaOleClipboard( );
+
+ // clipboard functions
+ HRESULT setClipboard( IDataObject* pIDataObject );
+ HRESULT getClipboard( IDataObject** ppIDataObject );
+ HRESULT flushClipboard( );
+
+ // register/unregister a clipboard viewer; there can only
+ // be one at a time; parameter NULL means unregister
+ // a clipboard viewer
+ // returns true on success else false; use GetLastError( ) in
+ // false case
+ sal_Bool registerClipViewer( LPFNC_CLIPVIEWER_CALLBACK_t pfncClipViewerCallback );
+
+private:
+ unsigned int run( );
+
+ // create a hidden windows which serves as an request
+ // target; so we guarantee synchronization
+ void createMtaOleReqWnd( );
+
+ // message support
+ sal_Bool postMessage( UINT msg, WPARAM wParam = 0, LPARAM lParam = 0 );
+ LRESULT sendMessage( UINT msg, WPARAM wParam = 0, LPARAM lParam = 0 );
+
+ //---------------------------------------------------------------
+ // message handler functions; remeber these functions are called
+ // from a different thread context!
+ //---------------------------------------------------------------
+
+ LRESULT onSetClipboard( IDataObject* pIDataObject );
+ LRESULT onGetClipboard( LPSTREAM* ppStream );
+ LRESULT onFlushClipboard( );
+ sal_Bool onRegisterClipViewer( LPFNC_CLIPVIEWER_CALLBACK_t pfncClipViewerCallback );
+
+ // win32 clipboard-viewer support
+ LRESULT onChangeCBChain( HWND hWndRemove, HWND hWndNext );
+ LRESULT onDrawClipboard( );
+
+ static LRESULT CALLBACK mtaOleReqWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
+ static unsigned int WINAPI oleThreadProc( LPVOID pParam );
+
+ static unsigned int WINAPI clipboardChangedNotifierThreadProc( LPVOID pParam );
+
+ sal_Bool WaitForThreadReady( ) const;
+
+private:
+ HANDLE m_hOleThread;
+ unsigned m_uOleThreadId;
+ HANDLE m_hEvtThrdReady;
+ HWND m_hwndMtaOleReqWnd;
+ ATOM m_MtaOleReqWndClassAtom;
+ HWND m_hwndNextClipViewer;
+ LPFNC_CLIPVIEWER_CALLBACK_t m_pfncClipViewerCallback;
+ sal_Bool m_bInRegisterClipViewer;
+
+ sal_Bool m_bRunClipboardNotifierThread;
+ HANDLE m_hClipboardChangedNotifierThread;
+ HANDLE m_hClipboardChangedNotifierEvents[2];
+ HANDLE& m_hClipboardChangedEvent;
+ HANDLE& m_hTerminateClipboardChangedNotifierEvent;
+ osl::Mutex m_ClipboardChangedEventCountMutex;
+ sal_Int32 m_ClipboardChangedEventCount;
+
+ osl::Mutex m_pfncClipViewerCallbackMutex;
+
+ static CMtaOleClipboard* s_theMtaOleClipboardInst;
+
+// not allowed
+private:
+ CMtaOleClipboard( const CMtaOleClipboard& );
+ CMtaOleClipboard& operator=( const CMtaOleClipboard& );
+
+ friend LRESULT CALLBACK mtaOleReqWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dtrans/source/win32/clipb/WinClipbImpl.hxx b/dtrans/source/win32/clipb/WinClipbImpl.hxx
index aa7a98d..0321478 100644
--- a/dtrans/source/win32/clipb/WinClipbImpl.hxx
+++ b/dtrans/source/win32/clipb/WinClipbImpl.hxx
@@ -39,7 +39,7 @@
#include <com/sun/star/datatransfer/XTransferable.hpp>
#include <com/sun/star/datatransfer/clipboard/XClipboardListener.hpp>
#include <com/sun/star/datatransfer/clipboard/XClipboardOwner.hpp>
-#include "../../inc/MtaOleClipb.hxx"
+#include "MtaOleClipb.hxx"
#if defined _MSC_VER
#pragma warning(push,1)
diff --git a/dtrans/source/win32/mtaole/MtaOleClipb.cxx b/dtrans/source/win32/mtaole/MtaOleClipb.cxx
deleted file mode 100644
index ecf10eb..0000000
--- a/dtrans/source/win32/mtaole/MtaOleClipb.cxx
+++ /dev/null
@@ -1,892 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*************************************************************************
- *
- * 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.
- *
- ************************************************************************/
-
-/*
- MtaOleClipb.cxx - documentation
-
- This class setup a single threaded apartment (sta) thread to deal with
- the ole clipboard, which runs only in an sta thread.
- The consequence is that callback from the ole clipboard are in the
- context of this sta thread. In the soffice applications this may lead
- to problems because they all use the one and only mutex called
- SolarMutex.
- In order to transfer clipboard requests to our sta thread we use a
- hidden window an forward these requests via window messages.
-*/
-
-#ifdef _MSC_VER
-#pragma warning( disable : 4786 ) // identifier was truncated to 'number'
- // characters in the debug information
-#endif
-
-//#define UNICODE
-#include <osl/diagnose.h>
-
-#include "../../inc/MtaOleClipb.hxx"
-#include <osl/conditn.hxx>
-
-#include <wchar.h>
-#include <process.h>
-
-#include <systools/win32/comtools.hxx>
-#ifdef __MINGW32__
-#define __uuidof(I) IID_##I
-#endif
-
-//----------------------------------------------------------------
-// namespace directives
-//----------------------------------------------------------------
-
-using osl::Condition;
-using osl::Mutex;
-using osl::MutexGuard;
-using osl::ClearableMutexGuard;
-
-//----------------------------------------------------------------
-// defines
-//----------------------------------------------------------------
-
-namespace /* private */
-{
- char CLIPSRV_DLL_NAME[] = "sysdtrans.dll";
- char g_szWndClsName[] = "MtaOleReqWnd###";
-
- //--------------------------------------------------------
- // messages constants
- //--------------------------------------------------------
-
- const sal_uInt32 MSG_SETCLIPBOARD = WM_USER + 0x0001;
- const sal_uInt32 MSG_GETCLIPBOARD = WM_USER + 0x0002;
- const sal_uInt32 MSG_REGCLIPVIEWER = WM_USER + 0x0003;
- const sal_uInt32 MSG_FLUSHCLIPBOARD = WM_USER + 0x0004;
- const sal_uInt32 MSG_SHUTDOWN = WM_USER + 0x0005;
-
- const sal_uInt32 MAX_WAITTIME = 10000; // msec
- const sal_uInt32 MAX_WAIT_SHUTDOWN = 10000; // msec
- const sal_uInt32 MAX_CLIPEVENT_PROCESSING_TIME = 5000; // msec
-
- const sal_Bool MANUAL_RESET = sal_True;
- const sal_Bool AUTO_RESET = sal_False;
- const sal_Bool INIT_NONSIGNALED = sal_False;
-
- //------------------------------------------------------
- /* Cannot use osl conditions because they are blocking
- without waking up on messages sent by another thread
- this leads to deadlocks because we are blocking the
- communication between inter-thread marshalled COM
- pointers.
- COM Proxy-Stub communication uses SendMessages for
- synchronization purposes.
- */
- class Win32Condition
- {
- public:
- // ctor
- Win32Condition()
- {
- m_hEvent = CreateEvent(
- 0, /* no security */
- true, /* manual reset */
- false, /* initial state not signaled */
- 0); /* automatic name */
- }
-
- // dtor
- ~Win32Condition()
- {
- CloseHandle(m_hEvent);
- }
-
- // wait infinite for event be signaled
- // leave messages sent through
- void wait()
- {
- while(1)
- {
- DWORD dwResult =
- MsgWaitForMultipleObjects(1, &m_hEvent, FALSE, INFINITE, QS_SENDMESSAGE);
-
- switch (dwResult)
- {
- case WAIT_OBJECT_0:
- return;
-
- case WAIT_OBJECT_0 + 1:
- {
- /* PeekMessage processes all messages in the SendMessage
- queue that's what we want, messages from the PostMessage
- queue stay untouched */
- MSG msg;
- PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
-
- break;
- }
- }
- }
- }
-
- // reset the event
- void set()
- {
- SetEvent(m_hEvent);
- }
-
- private:
- HANDLE m_hEvent;
-
- // prevent copy/assignment
- private:
- Win32Condition(const Win32Condition&);
- Win32Condition& operator=(const Win32Condition&);
- };
-
- //------------------------------------------
- // we use one condition for every request
- //------------------------------------------
-
- struct MsgCtx
- {
- Win32Condition aCondition;
- HRESULT hr;
- };
-
-} /* namespace private */
-
-//----------------------------------------------------------------
-// static member initialization
-//----------------------------------------------------------------
-
-CMtaOleClipboard* CMtaOleClipboard::s_theMtaOleClipboardInst = NULL;
-
-//--------------------------------------------------------------------
-// marshal an IDataObject
-//--------------------------------------------------------------------
-
-//inline
-HRESULT MarshalIDataObjectInStream( IDataObject* pIDataObject, LPSTREAM* ppStream )
-{
- OSL_ASSERT( NULL != pIDataObject );
- OSL_ASSERT( NULL != ppStream );
-
- *ppStream = NULL;
- return CoMarshalInterThreadInterfaceInStream(
- __uuidof(IDataObject), //The IID of inteface to be marshaled
- pIDataObject, //The interface pointer
- ppStream //IStream pointer
- );
-}
-
-//--------------------------------------------------------------------
-// unmarshal an IDataObject
-//--------------------------------------------------------------------
-
-//inline
-HRESULT UnmarshalIDataObjectAndReleaseStream( LPSTREAM lpStream, IDataObject** ppIDataObject )
-{
- OSL_ASSERT( NULL != lpStream );
- OSL_ASSERT( NULL != ppIDataObject );
-
- *ppIDataObject = NULL;
- return CoGetInterfaceAndReleaseStream(
- lpStream,
- __uuidof(IDataObject),
- reinterpret_cast<LPVOID*>(ppIDataObject));
-}
-
-//--------------------------------------------------------------------
-// helper class to ensure that the calling thread has com initialized
-//--------------------------------------------------------------------
-
-class CAutoComInit
-{
-public:
- CAutoComInit( )
- {
- /*
- to be safe we call CoInitialize
- although it is not necessary if
- the calling thread was created
- using osl_CreateThread because
- this function calls CoInitialize
- for every thread it creates
- */
- m_hResult = CoInitialize( NULL );
-
- if ( S_OK == m_hResult )
- OSL_FAIL( \
- "com was not yet initialzed, the thread was not created using osl_createThread" );
- else if ( FAILED( m_hResult ) && !( RPC_E_CHANGED_MODE == m_hResult ) )
- OSL_FAIL( \
- "com could not be initialized, maybe the thread was not created using osl_createThread" );
- }
-
- ~CAutoComInit( )
- {
- /*
- we only call CoUninitialize when
- CoInitailize returned S_FALSE, what
- means that com was already initialize
- for that thread so we keep the balance
- if CoInitialize returned S_OK what means
- com was not yet initialized we better
- let com initialized or we may run into
- the realm of undefined behaviour
- */
- if ( m_hResult == S_FALSE )
- CoUninitialize( );
- }
-
-private:
- HRESULT m_hResult;
-};
-
-//--------------------------------------------------------------------
-// ctor
-//--------------------------------------------------------------------
-
-CMtaOleClipboard::CMtaOleClipboard( ) :
- m_hOleThread( NULL ),
- m_uOleThreadId( 0 ),
- m_hEvtThrdReady( NULL ),
- m_hwndMtaOleReqWnd( NULL ),
- m_MtaOleReqWndClassAtom( 0 ),
- m_hwndNextClipViewer( NULL ),
- m_pfncClipViewerCallback( NULL ),
- m_bRunClipboardNotifierThread( sal_True ),
- m_hClipboardChangedEvent( m_hClipboardChangedNotifierEvents[0] ),
- m_hTerminateClipboardChangedNotifierEvent( m_hClipboardChangedNotifierEvents[1] ),
- m_ClipboardChangedEventCount( 0 )
-{
- // signals that the thread was successfully setup
- m_hEvtThrdReady = CreateEventA( 0, MANUAL_RESET, INIT_NONSIGNALED, NULL );
-
- OSL_ASSERT( NULL != m_hEvtThrdReady );
-
- s_theMtaOleClipboardInst = this;
-
- m_hOleThread = (HANDLE)_beginthreadex(
- NULL, 0, CMtaOleClipboard::oleThreadProc, this, 0, &m_uOleThreadId );
- OSL_ASSERT( NULL != m_hOleThread );
-
- //----------------------------------------------
- // setup the clipboard changed notifier thread
- //----------------------------------------------
-
- m_hClipboardChangedNotifierEvents[0] = CreateEventA( 0, MANUAL_RESET, INIT_NONSIGNALED, NULL );
- OSL_ASSERT( NULL != m_hClipboardChangedNotifierEvents[0] );
-
- m_hClipboardChangedNotifierEvents[1] = CreateEventA( 0, MANUAL_RESET, INIT_NONSIGNALED, NULL );
- OSL_ASSERT( NULL != m_hClipboardChangedNotifierEvents[1] );
-
- unsigned uThreadId;
- m_hClipboardChangedNotifierThread = (HANDLE)_beginthreadex(
- NULL, 0, CMtaOleClipboard::clipboardChangedNotifierThreadProc, this, 0, &uThreadId );
-
- OSL_ASSERT( NULL != m_hClipboardChangedNotifierThread );
-}
-
-//--------------------------------------------------------------------
-// dtor
-//--------------------------------------------------------------------
-
-CMtaOleClipboard::~CMtaOleClipboard( )
-{
- // block calling threads out
- if ( NULL != m_hEvtThrdReady )
- ResetEvent( m_hEvtThrdReady );
-
- // terminate the clipboard changed notifier thread
- m_bRunClipboardNotifierThread = sal_False;
- SetEvent( m_hTerminateClipboardChangedNotifierEvent );
-
- sal_uInt32 dwResult = WaitForSingleObject(
- m_hClipboardChangedNotifierThread, MAX_WAIT_SHUTDOWN );
-
- OSL_ENSURE( dwResult == WAIT_OBJECT_0, "clipboard notifier thread could not terminate" );
-
- if ( NULL != m_hClipboardChangedNotifierThread )
- CloseHandle( m_hClipboardChangedNotifierThread );
-
- if ( NULL != m_hClipboardChangedNotifierEvents[0] )
- CloseHandle( m_hClipboardChangedNotifierEvents[0] );
-
- if ( NULL != m_hClipboardChangedNotifierEvents[1] )
- CloseHandle( m_hClipboardChangedNotifierEvents[1] );
-
- // end the thread
- // because DestroyWindow can only be called
- // from within the thread that created the window
- sendMessage( MSG_SHUTDOWN,
- static_cast< WPARAM >( 0 ),
- static_cast< LPARAM >( 0 ) );
-
- // wait for thread shutdown
- dwResult = WaitForSingleObject( m_hOleThread, MAX_WAIT_SHUTDOWN );
- OSL_ENSURE( dwResult == WAIT_OBJECT_0, "OleThread could not terminate" );
-
- if ( NULL != m_hOleThread )
- CloseHandle( m_hOleThread );
-
- if ( NULL != m_hEvtThrdReady )
- CloseHandle( m_hEvtThrdReady );
-
- if ( m_MtaOleReqWndClassAtom )
- UnregisterClassA( g_szWndClsName, NULL );
-
- OSL_ENSURE( ( NULL == m_pfncClipViewerCallback ) &&
- !IsWindow( m_hwndNextClipViewer ), \
- "Clipboard viewer not properly unregistered" );
-}
-
-
-//--------------------------------------------------------------------
-//
-//--------------------------------------------------------------------
-
-HRESULT CMtaOleClipboard::flushClipboard( )
-{
- if ( !WaitForThreadReady( ) )
- {
- OSL_FAIL( "clipboard sta thread not ready" );
- return E_FAIL;
- }
-
- OSL_ENSURE( GetCurrentThreadId( ) != m_uOleThreadId, \
- "flushClipboard from within clipboard sta thread called" );
-
- MsgCtx aMsgCtx;
-
- postMessage( MSG_FLUSHCLIPBOARD,
- static_cast< WPARAM >( 0 ),
- reinterpret_cast< LPARAM >( &aMsgCtx ) );
-
- aMsgCtx.aCondition.wait( /* infinite */ );
-
- return aMsgCtx.hr;
-}
-
-//--------------------------------------------------------------------
-//
-//--------------------------------------------------------------------
-
-HRESULT CMtaOleClipboard::getClipboard( IDataObject** ppIDataObject )
-{
- OSL_PRECOND( NULL != ppIDataObject, "invalid parameter" );
- OSL_PRECOND( GetCurrentThreadId( ) != m_uOleThreadId, "getClipboard from within clipboard sta thread called" );
-
- if ( !WaitForThreadReady( ) )
- {
- OSL_FAIL( "clipboard sta thread not ready" );
- return E_FAIL;
- }
-
- CAutoComInit comAutoInit;
-
- LPSTREAM lpStream;
- HRESULT hr = E_FAIL;
-
- *ppIDataObject = NULL;
-
- MsgCtx aMsgCtx;
-
- postMessage( MSG_GETCLIPBOARD,
- reinterpret_cast< WPARAM >( &lpStream ),
- reinterpret_cast< LPARAM >( &aMsgCtx ) );
-
- aMsgCtx.aCondition.wait( /* infinite */ );
-
- hr = aMsgCtx.hr;
-
- if ( SUCCEEDED( hr ) )
- {
- hr = UnmarshalIDataObjectAndReleaseStream( lpStream, ppIDataObject );
- OSL_ENSURE( SUCCEEDED( hr ), "unmarshalling clipboard data object failed" );
- }
-
- return hr;
-}
-
-//--------------------------------------------------------------------
-// this is an asynchronous method that's why we don't wait until the
-// request is completed
-//--------------------------------------------------------------------
-
-HRESULT CMtaOleClipboard::setClipboard( IDataObject* pIDataObject )
-{
- if ( !WaitForThreadReady( ) )
- {
- OSL_FAIL( "clipboard sta thread not ready" );
- return E_FAIL;
- }
-
- CAutoComInit comAutoInit;
-
- OSL_ENSURE( GetCurrentThreadId( ) != m_uOleThreadId, "setClipboard from within the clipboard sta thread called" );
-
- // because we marshall this request
- // into the sta thread we better
- // acquire the interface here so
- // that the object will not be
- // destroyed before the ole clipboard
- // can acquire it
- // remember: pIDataObject may be NULL
- // which is an request to clear the
- // current clipboard content
- if ( pIDataObject )
- pIDataObject->AddRef( );
-
- postMessage(
- MSG_SETCLIPBOARD,
- reinterpret_cast< WPARAM >( pIDataObject ),
- 0 );
-
- // because this is an asynchronous function
- // the return value is useless
- return S_OK;
-}
-
-//--------------------------------------------------------------------
-// register a clipboard viewer
-//--------------------------------------------------------------------
-
-sal_Bool CMtaOleClipboard::registerClipViewer( LPFNC_CLIPVIEWER_CALLBACK_t pfncClipViewerCallback )
-{
- if ( !WaitForThreadReady( ) )
- {
- OSL_FAIL( "clipboard sta thread not ready" );
- return sal_False;
- }
-
- sal_Bool bRet = sal_False;
-
- OSL_ENSURE( GetCurrentThreadId( ) != m_uOleThreadId, "registerClipViewer from within the OleThread called" );
-
- MsgCtx aMsgCtx;
-
- postMessage( MSG_REGCLIPVIEWER,
- reinterpret_cast<WPARAM>( pfncClipViewerCallback ),
- reinterpret_cast<LPARAM>( &aMsgCtx ) );
-
- aMsgCtx.aCondition.wait( /* infinite */ );
-
- return bRet;
-}
-
-//--------------------------------------------------------------------
-// register a clipboard viewer
-//--------------------------------------------------------------------
-
-sal_Bool CMtaOleClipboard::onRegisterClipViewer( LPFNC_CLIPVIEWER_CALLBACK_t pfncClipViewerCallback )
-{
- sal_Bool bRet = sal_True;
-
- // we need exclusive access because the clipboard changed notifier
- // thread also accesses this variable
- MutexGuard aGuard( m_pfncClipViewerCallbackMutex );
-
- // register if not yet done
- if ( ( NULL != pfncClipViewerCallback ) && ( NULL == m_pfncClipViewerCallback ) )
- {
- // SetClipboardViewer sends a WM_DRAWCLIPBOARD message we ignore
- // this message if we register ourself as clip viewer
- m_bInRegisterClipViewer = sal_True;
- m_hwndNextClipViewer = SetClipboardViewer( m_hwndMtaOleReqWnd );
- m_bInRegisterClipViewer = sal_False;
-
- // if there is no other cb-viewer the
- // return value is NULL!!!
- bRet = IsWindow( m_hwndNextClipViewer ) ? sal_True : sal_False;
-
- // save the new callback function
- m_pfncClipViewerCallback = pfncClipViewerCallback;
- }
- else if ( ( NULL == pfncClipViewerCallback ) && ( NULL != m_pfncClipViewerCallback ) )
- {
- m_pfncClipViewerCallback = NULL;
-
- // unregister if input parameter is NULL and we previously registered
- // as clipboard viewer
- ChangeClipboardChain( m_hwndMtaOleReqWnd, m_hwndNextClipViewer );
- m_hwndNextClipViewer = NULL;
- }
-
- return bRet;
-}
-
-//--------------------------------------------------------------------
-//
-//--------------------------------------------------------------------
-
-LRESULT CMtaOleClipboard::onSetClipboard( IDataObject* pIDataObject )
-{
- return static_cast<LRESULT>( OleSetClipboard( pIDataObject ) );
-}
-
-//--------------------------------------------------------------------
-//
-//--------------------------------------------------------------------
-
-LRESULT CMtaOleClipboard::onGetClipboard( LPSTREAM* ppStream )
-{
- OSL_ASSERT(NULL != ppStream);
-
- IDataObjectPtr pIDataObject;
-
- // forward the request to the OleClipboard
- HRESULT hr = OleGetClipboard( &pIDataObject );
- if ( SUCCEEDED( hr ) )
- {
- hr = MarshalIDataObjectInStream(pIDataObject.get(), ppStream);
- OSL_ENSURE(SUCCEEDED(hr), "marshalling cliboard data object failed");
- }
- return static_cast<LRESULT>(hr);
-}
-
-//--------------------------------------------------------------------
-// flush the ole-clipboard
-//--------------------------------------------------------------------
-
-LRESULT CMtaOleClipboard::onFlushClipboard( )
-{
- return static_cast<LRESULT>( OleFlushClipboard( ) );
-}
-
-//--------------------------------------------------------------------
-// handle clipboard chain change event
-//--------------------------------------------------------------------
-
-LRESULT CMtaOleClipboard::onChangeCBChain( HWND hWndRemove, HWND hWndNext )
-{
- if ( hWndRemove == m_hwndNextClipViewer )
- m_hwndNextClipViewer = hWndNext;
- else if ( IsWindow( m_hwndNextClipViewer ) )
- {
- // forward the message to the next one
- DWORD_PTR dwpResult;
- SendMessageTimeoutA(
- m_hwndNextClipViewer,
- WM_CHANGECBCHAIN,
- reinterpret_cast<WPARAM>(hWndRemove),
- reinterpret_cast<LPARAM>(hWndNext),
- SMTO_BLOCK,
- MAX_CLIPEVENT_PROCESSING_TIME,
- &dwpResult );
- }
-
- return 0;
-}
-
-//--------------------------------------------------------------------
-// handle draw clipboard event
-//--------------------------------------------------------------------
-
-LRESULT CMtaOleClipboard::onDrawClipboard( )
-{
- // we don't send a notification if we are
- // registering ourself as clipboard
- if ( !m_bInRegisterClipViewer )
- {
- ClearableMutexGuard aGuard( m_ClipboardChangedEventCountMutex );
-
- m_ClipboardChangedEventCount++;
- SetEvent( m_hClipboardChangedEvent );
-
- aGuard.clear( );
- }
-
- // foward the message to the next viewer in the chain
- if ( IsWindow( m_hwndNextClipViewer ) )
- {
- DWORD_PTR dwpResult;
- SendMessageTimeoutA(
- m_hwndNextClipViewer,
- WM_DRAWCLIPBOARD,
- static_cast< WPARAM >( 0 ),
- static_cast< LPARAM >( 0 ),
- SMTO_BLOCK,
- MAX_CLIPEVENT_PROCESSING_TIME,
- &dwpResult );
- }
-
- return 0;
-}
-
-//--------------------------------------------------------------------
-// SendMessage so we don't need to supply the HWND if we send
-// something to our wrapped window
-//--------------------------------------------------------------------
-
-LRESULT CMtaOleClipboard::sendMessage( UINT msg, WPARAM wParam, LPARAM lParam )
-{
- return ::SendMessageA( m_hwndMtaOleReqWnd, msg, wParam, lParam );
-}
-
-//--------------------------------------------------------------------
-// PostMessage so we don't need to supply the HWND if we send
-// something to our wrapped window
-//--------------------------------------------------------------------
-
-sal_Bool CMtaOleClipboard::postMessage( UINT msg, WPARAM wParam, LPARAM lParam )
-{
- return PostMessageA( m_hwndMtaOleReqWnd, msg, wParam, lParam ) ? sal_True : sal_False;
-}
-
-
-//--------------------------------------------------------------------
-// the window proc
-//--------------------------------------------------------------------
-
-LRESULT CALLBACK CMtaOleClipboard::mtaOleReqWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
-{
- LRESULT lResult = 0;
-
- // get a connection to the class-instance via the static member
- CMtaOleClipboard* pImpl = CMtaOleClipboard::s_theMtaOleClipboardInst;
- OSL_ASSERT( NULL != pImpl );
-
- switch( uMsg )
- {
- case MSG_SETCLIPBOARD:
- {
- IDataObject* pIDataObject = reinterpret_cast< IDataObject* >( wParam );
- pImpl->onSetClipboard( pIDataObject );
-
- // in setClipboard we did acquire the
- // interface pointer in order to prevent
- // destruction of the object before the
- // ole clipboard can acquire the interface
- // now we release the interface so that
- // our lostOwnership mechanism works
- // remember: pIDataObject may be NULL
- if ( pIDataObject )
- pIDataObject->Release( );
- }
- break;
-
- case MSG_GETCLIPBOARD:
- {
- MsgCtx* aMsgCtx = reinterpret_cast< MsgCtx* >( lParam );
- OSL_ASSERT( aMsgCtx );
-
- aMsgCtx->hr = pImpl->onGetClipboard( reinterpret_cast< LPSTREAM* >(wParam) );
- aMsgCtx->aCondition.set( );
- }
- break;
-
- case MSG_FLUSHCLIPBOARD:
- {
- MsgCtx* aMsgCtx = reinterpret_cast< MsgCtx* >( lParam );
- OSL_ASSERT( aMsgCtx );
-
- aMsgCtx->hr = pImpl->onFlushClipboard( );
- aMsgCtx->aCondition.set( );
- }
- break;
-
- case MSG_REGCLIPVIEWER:
- {
- MsgCtx* aMsgCtx = reinterpret_cast< MsgCtx* >( lParam );
- OSL_ASSERT( aMsgCtx );
-
- pImpl->onRegisterClipViewer( reinterpret_cast<CMtaOleClipboard::LPFNC_CLIPVIEWER_CALLBACK_t>(wParam) );
- aMsgCtx->aCondition.set( );
- }
- break;
-
- case WM_CHANGECBCHAIN:
- lResult = pImpl->onChangeCBChain(
- reinterpret_cast< HWND >( wParam ), reinterpret_cast< HWND >( lParam ) );
- break;
-
- case WM_DRAWCLIPBOARD:
- lResult = pImpl->onDrawClipboard( );
- break;
-
- case MSG_SHUTDOWN:
- DestroyWindow( pImpl->m_hwndMtaOleReqWnd );
- break;
-
- // force the sta thread to end
- case WM_DESTROY:
- PostQuitMessage( 0 );
- break;
-
- default:
- lResult = DefWindowProcA( hWnd, uMsg, wParam, lParam );
- break;
- }
-
- return lResult;
-}
-
-//--------------------------------------------------------------------
-//
-//--------------------------------------------------------------------
-
-void CMtaOleClipboard::createMtaOleReqWnd( )
-{
- WNDCLASSEXA wcex;
-
- HINSTANCE hInst = GetModuleHandleA( CLIPSRV_DLL_NAME );
- OSL_ENSURE( NULL != hInst, "The name of the clipboard service dll must have changed" );
-
- ZeroMemory( &wcex, sizeof( WNDCLASSEXA ) );
-
- wcex.cbSize = sizeof(WNDCLASSEXA);
- wcex.style = 0;
- wcex.lpfnWndProc = static_cast< WNDPROC >( CMtaOleClipboard::mtaOleReqWndProc );
- wcex.cbClsExtra = 0;
- wcex.cbWndExtra = 0;
- wcex.hInstance = hInst;
- wcex.hIcon = NULL;
- wcex.hCursor = NULL;
- wcex.hbrBackground = NULL;
- wcex.lpszMenuName = NULL;
- wcex.lpszClassName = g_szWndClsName;
- wcex.hIconSm = NULL;
-
- m_MtaOleReqWndClassAtom = RegisterClassExA( &wcex );
-
- if ( 0 != m_MtaOleReqWndClassAtom )
- m_hwndMtaOleReqWnd = CreateWindowA(
- g_szWndClsName, NULL, 0, 0, 0, 0, 0, NULL, NULL, hInst, NULL );
-}
-
-//--------------------------------------------------------------------
-//
-//--------------------------------------------------------------------
-
-unsigned int CMtaOleClipboard::run( )
-{
- #if OSL_DEBUG_LEVEL > 0
- HRESULT hr =
- #endif
- OleInitialize( NULL );
- OSL_ASSERT( SUCCEEDED( hr ) );
-
- createMtaOleReqWnd( );
-
- unsigned int nRet;
-
- if ( IsWindow( m_hwndMtaOleReqWnd ) )
- {
- if ( NULL != m_hEvtThrdReady )
- SetEvent( m_hEvtThrdReady );
-
- // pumping messages
- MSG msg;
- while( GetMessageA( &msg, NULL, 0, 0 ) )
- DispatchMessageA( &msg );
-
- nRet = 0;
- }
- else
- nRet = ~0U;
-
- OleUninitialize( );
-
- return nRet;
-}
-
-//--------------------------------------------------------------------
-//
-//--------------------------------------------------------------------
-
-unsigned int WINAPI CMtaOleClipboard::oleThreadProc( LPVOID pParam )
-{
- CMtaOleClipboard* pInst =
- reinterpret_cast<CMtaOleClipboard*>( pParam );
- OSL_ASSERT( NULL != pInst );
-
- return pInst->run( );
-}
-
-//--------------------------------------------------------------------
-//
-//--------------------------------------------------------------------
-
-unsigned int WINAPI CMtaOleClipboard::clipboardChangedNotifierThreadProc( LPVOID pParam )
-{
- CMtaOleClipboard* pInst = reinterpret_cast< CMtaOleClipboard* >( pParam );
- OSL_ASSERT( NULL != pInst );
-
- CoInitialize( NULL );
-
- // assuming we don't need a lock for
- // a boolean variable like m_bRun...
- while ( pInst->m_bRunClipboardNotifierThread )
- {
- // wait for clipboard changed or terminate event
- WaitForMultipleObjects( 2, pInst->m_hClipboardChangedNotifierEvents, false, INFINITE );
-
- ClearableMutexGuard aGuard( pInst->m_ClipboardChangedEventCountMutex );
-
- if ( pInst->m_ClipboardChangedEventCount > 0 )
- {
- pInst->m_ClipboardChangedEventCount--;
- if ( 0 == pInst->m_ClipboardChangedEventCount )
- ResetEvent( pInst->m_hClipboardChangedEvent );
-
- aGuard.clear( );
-
- // nobody should touch m_pfncClipViewerCallback while we do
- MutexGuard aClipViewerGuard( pInst->m_pfncClipViewerCallbackMutex );
-
- // notify all clipboard listener
- if ( pInst->m_pfncClipViewerCallback )
- pInst->m_pfncClipViewerCallback( );
- }
- else
- aGuard.clear( );
- }
-
- CoUninitialize( );
-
- return ( 0 );
-}
-
-//--------------------------------------------------------------------
-//
-//--------------------------------------------------------------------
-
-inline
-sal_Bool CMtaOleClipboard::WaitForThreadReady( ) const
-{
- sal_Bool bRet = sal_False;
-
- if ( NULL != m_hEvtThrdReady )
- {
- DWORD dwResult = WaitForSingleObject(
- m_hEvtThrdReady, MAX_WAITTIME );
- bRet = ( dwResult == WAIT_OBJECT_0 );
- }
-
- return bRet;
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
More information about the Libreoffice-commits
mailing list