summaryrefslogtreecommitdiff
path: root/dtrans/source/win32/mtaole/MtaOleClipb.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'dtrans/source/win32/mtaole/MtaOleClipb.cxx')
-rw-r--r--dtrans/source/win32/mtaole/MtaOleClipb.cxx895
1 files changed, 0 insertions, 895 deletions
diff --git a/dtrans/source/win32/mtaole/MtaOleClipb.cxx b/dtrans/source/win32/mtaole/MtaOleClipb.cxx
deleted file mode 100644
index 3dc560fae7..0000000000
--- a/dtrans/source/win32/mtaole/MtaOleClipb.cxx
+++ /dev/null
@@ -1,895 +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.
- *
- ************************************************************************/
-
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_dtrans.hxx"
-
-/*
- 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: */