diff options
author | Vladimir Glazounov <vg@openoffice.org> | 2006-03-14 09:53:33 +0000 |
---|---|---|
committer | Vladimir Glazounov <vg@openoffice.org> | 2006-03-14 09:53:33 +0000 |
commit | 33e79dd1b1d55555df69a83606f1b4392994d5ea (patch) | |
tree | 9f5c2ec457418067bd70d384b9027f9b8cbf51e6 /toolkit/source/awt | |
parent | 42afd399c88d806ffea3cba22ef359583ca36293 (diff) |
INTEGRATION: CWS pbrwuno (1.55.8); FILE MERGED
2006/02/09 15:39:06 fs 1.55.8.7: RESYNC: (1.56-1.57); FILE MERGED
2005/11/01 08:04:29 fs 1.55.8.6: RESYNC: (1.55-1.56); FILE MERGED
2005/10/31 15:34:42 fs 1.55.8.5: #i10000#
2005/10/19 08:48:57 fs 1.55.8.4: proper detection of being disposed
2005/10/19 08:42:47 fs 1.55.8.3: disposing: protect mpImpl against duplicate deletion
2005/10/19 08:27:46 fs 1.55.8.2: make IEventProcessor ref-counted
2005/10/07 12:21:58 fs 1.55.8.1: AsyncEventNotifier was reworked in the course of #i53095#, adjusted the usage
Diffstat (limited to 'toolkit/source/awt')
-rw-r--r-- | toolkit/source/awt/vclxwindow.cxx | 105 |
1 files changed, 79 insertions, 26 deletions
diff --git a/toolkit/source/awt/vclxwindow.cxx b/toolkit/source/awt/vclxwindow.cxx index a2ce1638e633..17bfd4d4ffc0 100644 --- a/toolkit/source/awt/vclxwindow.cxx +++ b/toolkit/source/awt/vclxwindow.cxx @@ -4,9 +4,9 @@ * * $RCSfile: vclxwindow.cxx,v $ * - * $Revision: 1.57 $ + * $Revision: 1.58 $ * - * last change: $Author: kz $ $Date: 2006-02-06 13:00:26 $ + * last change: $Author: vg $ $Date: 2006-03-14 10:53:33 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -167,21 +167,32 @@ using ::com::sun::star::style::VerticalAlignment_MAKE_FIXED_SIZE; #define EVENT_MOUSE_ENTERED 2 #define EVENT_MOUSE_EXITED 3 +struct AnyMouseEvent : public ::comphelper::EventHolder< ::com::sun::star::awt::MouseEvent > +{ + sal_Int16 nMouseEventType; + + AnyMouseEvent( const ::com::sun::star::awt::MouseEvent& _rEvent, sal_Int16 _nType ) + :comphelper::EventHolder< ::com::sun::star::awt::MouseEvent >( _rEvent ) + ,nMouseEventType( _nType ) + { + } +}; + class SAL_DLLPRIVATE VCLXWindowImpl : public ::comphelper::IEventProcessor { private: - typedef ::comphelper::EventObjectHolder< ::com::sun::star::awt::MouseEvent > - MouseEventType; - typedef ::std::vector< ::rtl::Reference< ::comphelper::EventDescription > > + typedef ::std::vector< ::rtl::Reference< ::comphelper::AnyEvent > > EventArray; - typedef ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > - ComponentReference; private: + oslInterlockedCount m_refCount; VCLXWindow& mrAntiImpl; ::vos::IMutex& mrMutex; + bool mbDisposed; + #ifdef THREADED_NOTIFICATION - ::comphelper::AsyncEventNotifier* mpAsyncNotifier; + ::rtl::Reference< ::comphelper::AsyncEventNotifier > + mpAsyncNotifier; #else #if !defined( SYNCHRON_NOTIFICATION ) EventArray maEvents; @@ -205,21 +216,42 @@ public: */ void disposing(); + virtual void SAL_CALL acquire(); + virtual void SAL_CALL release(); + protected: + ~VCLXWindowImpl(); + // IEventProcessor - virtual void processEvent( const ::comphelper::EventDescription& _rEvent ); - virtual ComponentReference getComponent(); + virtual void processEvent( const ::comphelper::AnyEvent& _rEvent ); #if !defined( SYNCHRON_NOTIFICATION ) && !defined( THREADED_NOTIFICATION ) private: DECL_LINK( OnProcessEvent, void* ); #endif + +private: + /** determines whether the instance is already disposed + @precond + m_aMutex must be acquired + */ + inline bool impl_isDisposed() + { + return mbDisposed; + } + +private: + VCLXWindowImpl(); // never implemented + VCLXWindowImpl( const VCLXWindowImpl& ); // never implemented + VCLXWindowImpl& operator=( const VCLXWindowImpl& ); // never implemented }; //-------------------------------------------------------------------- VCLXWindowImpl::VCLXWindowImpl( VCLXWindow& _rAntiImpl, ::vos::IMutex& _rMutex ) :mrAntiImpl( _rAntiImpl ) + ,m_refCount( 0 ) ,mrMutex( _rMutex ) + ,mbDisposed( false ) #ifdef THREADED_NOTIFICATION ,mpAsyncNotifier( NULL ) #else @@ -231,13 +263,18 @@ VCLXWindowImpl::VCLXWindowImpl( VCLXWindow& _rAntiImpl, ::vos::IMutex& _rMutex ) } //-------------------------------------------------------------------- +VCLXWindowImpl::~VCLXWindowImpl() +{ +} + +//-------------------------------------------------------------------- void VCLXWindowImpl::disposing() { ::vos::OGuard aGuard( mrMutex ); #ifdef THREADED_NOTIFICATION - if ( mpAsyncNotifier ) + if ( mpAsyncNotifier.is() ) { - mpAsyncNotifier->release(); + mpAsyncNotifier->removeEventsForProcessor( this ); mpAsyncNotifier = NULL; } #else @@ -247,6 +284,7 @@ void VCLXWindowImpl::disposing() mnEventId = 0; #endif #endif + mbDisposed= true; } //-------------------------------------------------------------------- @@ -255,15 +293,14 @@ void VCLXWindowImpl::notifyMouseEvent( const ::com::sun::star::awt::MouseEvent& ::vos::OClearableGuard aGuard( mrMutex ); if ( mrAntiImpl.GetMouseListeners().getLength() ) { - ::rtl::Reference< ::comphelper::EventDescription > aEvent( new MouseEventType( _rMouseEvent, _nType ) ); + ::rtl::Reference< ::comphelper::AnyEvent > aEvent( new AnyMouseEvent( _rMouseEvent, _nType ) ); #ifdef THREADED_NOTIFICATION - if ( !mpAsyncNotifier ) + if ( !mpAsyncNotifier.is() ) { - mpAsyncNotifier = new ::comphelper::AsyncEventNotifier( this ); - mpAsyncNotifier->acquire(); + mpAsyncNotifier = new ::comphelper::AsyncEventNotifier; mpAsyncNotifier->create(); } - mpAsyncNotifier->addEvent( aEvent ); + mpAsyncNotifier->addEvent( aEvent, this ); #else #ifdef SYNCHRON_NOTIFICATION aGuard.clear(); @@ -311,11 +348,16 @@ IMPL_LINK( VCLXWindowImpl, OnProcessEvent, void*, NOINTERESTEDIN ) #endif //-------------------------------------------------------------------- -void VCLXWindowImpl::processEvent( const ::comphelper::EventDescription& _rEvent ) +void VCLXWindowImpl::processEvent( const ::comphelper::AnyEvent& _rEvent ) { - const MouseEventType aEventDescriptor( static_cast< const MouseEventType& >( _rEvent ) ); - const ::com::sun::star::awt::MouseEvent& rEvent( aEventDescriptor.getEventObject() ); - switch ( aEventDescriptor.getEventType() ) + ::vos::OGuard aGuard( mrMutex ); + if ( impl_isDisposed() ) + // while we were waiting for our mutex, another thread disposed us + return; + + const AnyMouseEvent& rEventDescriptor( static_cast< const AnyMouseEvent& >( _rEvent ) ); + const ::com::sun::star::awt::MouseEvent& rEvent( rEventDescriptor.getEventObject() ); + switch ( rEventDescriptor.nMouseEventType ) { case EVENT_MOUSE_PRESSED: mrAntiImpl.GetMouseListeners().mousePressed( rEvent ); @@ -335,9 +377,16 @@ void VCLXWindowImpl::processEvent( const ::comphelper::EventDescription& _rEvent } //-------------------------------------------------------------------- -VCLXWindowImpl::ComponentReference VCLXWindowImpl::getComponent() +void SAL_CALL VCLXWindowImpl::acquire() { - return static_cast< ::com::sun::star::awt::XWindow* >( &mrAntiImpl ); + osl_incrementInterlockedCount( &m_refCount ); +} + +//-------------------------------------------------------------------- +void SAL_CALL VCLXWindowImpl::release() +{ + if ( 0 == osl_decrementInterlockedCount( &m_refCount ) ) + delete this; } //==================================================================== @@ -421,6 +470,7 @@ VCLXWindow::VCLXWindow() DBG_CTOR( VCLXWindow, 0 ); mpImpl = new VCLXWindowImpl( *this, GetMutex() ); + mpImpl->acquire(); mbDisposing = sal_False; mbDesignMode = sal_False; @@ -437,8 +487,6 @@ VCLXWindow::~VCLXWindow() GetWindow()->SetWindowPeer( NULL, NULL ); GetWindow()->SetAccessible( NULL ); } - - DELETEZ( mpImpl ); } void VCLXWindow::SetWindow( Window* pWindow ) @@ -988,7 +1036,12 @@ void VCLXWindow::dispose( ) throw(::com::sun::star::uno::RuntimeException) { mbDisposing = sal_True; - mpImpl->disposing(); + if ( mpImpl ) + { + mpImpl->disposing(); + mpImpl->release(); + mpImpl = NULL; + } ::com::sun::star::lang::EventObject aObj; aObj.Source = static_cast< ::cppu::OWeakObject* >( this ); |