1*3a700b0aSSteve Yin /**************************************************************
2*3a700b0aSSteve Yin  *
3*3a700b0aSSteve Yin  * Licensed to the Apache Software Foundation (ASF) under one
4*3a700b0aSSteve Yin  * or more contributor license agreements.  See the NOTICE file
5*3a700b0aSSteve Yin  * distributed with this work for additional information
6*3a700b0aSSteve Yin  * regarding copyright ownership.  The ASF licenses this file
7*3a700b0aSSteve Yin  * to you under the Apache License, Version 2.0 (the
8*3a700b0aSSteve Yin  * "License"); you may not use this file except in compliance
9*3a700b0aSSteve Yin  * with the License.  You may obtain a copy of the License at
10*3a700b0aSSteve Yin  *
11*3a700b0aSSteve Yin  *   http://www.apache.org/licenses/LICENSE-2.0
12*3a700b0aSSteve Yin  *
13*3a700b0aSSteve Yin  * Unless required by applicable law or agreed to in writing,
14*3a700b0aSSteve Yin  * software distributed under the License is distributed on an
15*3a700b0aSSteve Yin  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*3a700b0aSSteve Yin  * KIND, either express or implied.  See the License for the
17*3a700b0aSSteve Yin  * specific language governing permissions and limitations
18*3a700b0aSSteve Yin  * under the License.
19*3a700b0aSSteve Yin  *
20*3a700b0aSSteve Yin  *************************************************************/
215fdc4257SSteve Yin 
225fdc4257SSteve Yin #include <cppuhelper/bootstrap.hxx>
235fdc4257SSteve Yin #include <com/sun/star/bridge/XUnoUrlResolver.hpp>
245fdc4257SSteve Yin #include <com/sun/star/lang/XMultiServiceFactory.hpp>
255fdc4257SSteve Yin #include <toolkit/awt/Vclxwindow.hxx>
265fdc4257SSteve Yin 
275fdc4257SSteve Yin #ifndef _SV_SYSDATA_HXX
285fdc4257SSteve Yin #if defined( WIN ) || defined( WNT ) || defined( OS2 )
295fdc4257SSteve Yin typedef sal_Int32 HWND;
305fdc4257SSteve Yin #endif
315fdc4257SSteve Yin #endif
325fdc4257SSteve Yin #include "AccEventListener.hxx"
335fdc4257SSteve Yin #include "AccObjectManagerAgent.hxx"
345fdc4257SSteve Yin #include "unomsaaevent.hxx"
355fdc4257SSteve Yin 
365fdc4257SSteve Yin #include <com/sun/star/accessibility/XAccessible.hpp>
375fdc4257SSteve Yin #include <com/sun/star/accessibility/AccessibleStateType.hpp>
385fdc4257SSteve Yin #include <com/sun/star/accessibility/AccessibleEventId.hpp>
395fdc4257SSteve Yin #include <com/sun/star/accessibility/AccessibleRole.hpp>
405fdc4257SSteve Yin #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
415fdc4257SSteve Yin #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
425fdc4257SSteve Yin 
435fdc4257SSteve Yin #include <stdio.h>
445fdc4257SSteve Yin 
455fdc4257SSteve Yin using namespace com::sun::star::uno;
465fdc4257SSteve Yin using namespace com::sun::star::accessibility;
475fdc4257SSteve Yin using namespace rtl;
485fdc4257SSteve Yin using namespace cppu;
495fdc4257SSteve Yin 
AccEventListener(com::sun::star::accessibility::XAccessible * pAcc,AccObjectManagerAgent * Agent)505fdc4257SSteve Yin AccEventListener::AccEventListener(com::sun::star::accessibility::XAccessible* pAcc,
515fdc4257SSteve Yin                                    AccObjectManagerAgent* Agent)
525fdc4257SSteve Yin         :pAccessible(pAcc),
535fdc4257SSteve Yin         pAgent(Agent),
545fdc4257SSteve Yin         m_isDisposed(false),
555fdc4257SSteve Yin         m_refcount(0)
565fdc4257SSteve Yin {}
575fdc4257SSteve Yin 
~AccEventListener()585fdc4257SSteve Yin AccEventListener::~AccEventListener()
595fdc4257SSteve Yin {
605fdc4257SSteve Yin }
615fdc4257SSteve Yin 
625fdc4257SSteve Yin /**
635fdc4257SSteve Yin  *	Uno's event notifier when event is captured
645fdc4257SSteve Yin  *	@param AccessibleEventObject	the event object which contains information about event
655fdc4257SSteve Yin  */
notifyEvent(const::com::sun::star::accessibility::AccessibleEventObject & aEvent)665fdc4257SSteve Yin void  AccEventListener::notifyEvent( const ::com::sun::star::accessibility::AccessibleEventObject& aEvent )
675fdc4257SSteve Yin throw (::com::sun::star::uno::RuntimeException)
685fdc4257SSteve Yin {
695fdc4257SSteve Yin 
705fdc4257SSteve Yin     switch (aEvent.EventId)
715fdc4257SSteve Yin     {
725fdc4257SSteve Yin     case AccessibleEventId::NAME_CHANGED:
735fdc4257SSteve Yin         handleNameChangedEvent(aEvent.NewValue);
745fdc4257SSteve Yin         break;
755fdc4257SSteve Yin     case AccessibleEventId::DESCRIPTION_CHANGED:
765fdc4257SSteve Yin         handleDescriptionChangedEvent(aEvent.NewValue);
775fdc4257SSteve Yin         break;
785fdc4257SSteve Yin     case AccessibleEventId::STATE_CHANGED:
795fdc4257SSteve Yin         handleStateChangedEvent(aEvent.OldValue, aEvent.NewValue);
805fdc4257SSteve Yin         break;
815fdc4257SSteve Yin     default:
825fdc4257SSteve Yin         break;
835fdc4257SSteve Yin     }
845fdc4257SSteve Yin }
855fdc4257SSteve Yin 
865fdc4257SSteve Yin /**
875fdc4257SSteve Yin  *	handle the NAME_CHANGED event
885fdc4257SSteve Yin  *	@param	name		the new name with changed.
895fdc4257SSteve Yin  */
handleNameChangedEvent(Any name)905fdc4257SSteve Yin void AccEventListener::handleNameChangedEvent(Any name)
915fdc4257SSteve Yin {
925fdc4257SSteve Yin     if ( pAgent->IsTopWinAcc( pAccessible ) )
935fdc4257SSteve Yin     {
945fdc4257SSteve Yin         XAccessible* pAccDoc = pAgent->GetAccDocByAccTopWin( pAccessible );
955fdc4257SSteve Yin         if ( pAccDoc )
965fdc4257SSteve Yin         {
975fdc4257SSteve Yin             pAgent->UpdateAccName(pAccDoc);
985fdc4257SSteve Yin             pAgent->NotifyAccEvent(UM_EVENT_OBJECT_NAMECHANGE, pAccDoc);
995fdc4257SSteve Yin         }
1005fdc4257SSteve Yin     }
1015fdc4257SSteve Yin 
1025fdc4257SSteve Yin     pAgent->UpdateAccName(pAccessible, name);
1035fdc4257SSteve Yin     pAgent->NotifyAccEvent(UM_EVENT_OBJECT_NAMECHANGE, pAccessible);
1045fdc4257SSteve Yin }
1055fdc4257SSteve Yin 
1065fdc4257SSteve Yin /**
1075fdc4257SSteve Yin  *	handle the DESCRIPTION_CHANGED event
1085fdc4257SSteve Yin  *	@param	desc		the new description
1095fdc4257SSteve Yin  */
handleDescriptionChangedEvent(Any desc)1105fdc4257SSteve Yin void AccEventListener::handleDescriptionChangedEvent(Any desc)
1115fdc4257SSteve Yin {
1125fdc4257SSteve Yin     pAgent->UpdateDescription(pAccessible, desc);
1135fdc4257SSteve Yin     pAgent->NotifyAccEvent(UM_EVENT_OBJECT_DESCRIPTIONCHANGE, pAccessible);
1145fdc4257SSteve Yin }
1155fdc4257SSteve Yin 
1165fdc4257SSteve Yin /**
1175fdc4257SSteve Yin  *	handle the BOUNDRECT_CHANGED event
1185fdc4257SSteve Yin  */
handleBoundrectChangedEvent()1195fdc4257SSteve Yin void AccEventListener::handleBoundrectChangedEvent()
1205fdc4257SSteve Yin {
1215fdc4257SSteve Yin     pAgent->UpdateLocation(pAccessible);
1225fdc4257SSteve Yin     pAgent->NotifyAccEvent(UM_EVENT_BOUNDRECT_CHANGED, pAccessible);
1235fdc4257SSteve Yin }
1245fdc4257SSteve Yin 
1255fdc4257SSteve Yin /**
1265fdc4257SSteve Yin  *	handle the VISIBLE_DATA_CHANGED event
1275fdc4257SSteve Yin  */
handleVisibleDataChangedEvent()1285fdc4257SSteve Yin void AccEventListener::handleVisibleDataChangedEvent()
1295fdc4257SSteve Yin {
1305fdc4257SSteve Yin     pAgent->UpdateValue(pAccessible);
1315fdc4257SSteve Yin     pAgent->NotifyAccEvent(UM_EVENT_VISIBLE_DATA_CHANGED, pAccessible);
1325fdc4257SSteve Yin }
1335fdc4257SSteve Yin 
1345fdc4257SSteve Yin /**
1355fdc4257SSteve Yin  *	handle the STATE_CHANGED event
1365fdc4257SSteve Yin  *  @param	oldValue	the old state of the source of event
1375fdc4257SSteve Yin  *  @param	newValue	the new state of the source of event
1385fdc4257SSteve Yin  */
handleStateChangedEvent(Any oldValue,Any newValue)1395fdc4257SSteve Yin void AccEventListener::handleStateChangedEvent(Any oldValue, Any newValue)
1405fdc4257SSteve Yin {
1415fdc4257SSteve Yin     short newV, oldV;
1425fdc4257SSteve Yin     if( newValue >>= newV)
1435fdc4257SSteve Yin     {
1445fdc4257SSteve Yin         setComponentState(newV, true);
1455fdc4257SSteve Yin     }
1465fdc4257SSteve Yin     else if (oldValue >>= oldV)
1475fdc4257SSteve Yin     {
1485fdc4257SSteve Yin         setComponentState(oldV, false);
1495fdc4257SSteve Yin     }
1505fdc4257SSteve Yin }
1515fdc4257SSteve Yin 
1525fdc4257SSteve Yin /**
1535fdc4257SSteve Yin  *	set the new state and fire the MSAA event
1545fdc4257SSteve Yin  *	@param	state		new state id
1555fdc4257SSteve Yin  *	@param	enable		true if state is set, false if state is unset
1565fdc4257SSteve Yin  */
setComponentState(short state,bool enable)1575fdc4257SSteve Yin void AccEventListener::setComponentState(short state, bool enable )
1585fdc4257SSteve Yin {
1595fdc4257SSteve Yin     switch (state)
1605fdc4257SSteve Yin     {
1615fdc4257SSteve Yin     case AccessibleStateType::FOCUSED:
1625fdc4257SSteve Yin         fireStateFocusdChange(enable);
1635fdc4257SSteve Yin         break;
1645fdc4257SSteve Yin     default:
1655fdc4257SSteve Yin         fireStatePropertyChange(state, enable);
1665fdc4257SSteve Yin         break;
1675fdc4257SSteve Yin     }
1685fdc4257SSteve Yin }
1695fdc4257SSteve Yin 
1705fdc4257SSteve Yin /**
1715fdc4257SSteve Yin  *	handle the focused event
1725fdc4257SSteve Yin  *	@param enable	true if get focus, false if lose focus
1735fdc4257SSteve Yin  */
fireStateFocusdChange(bool enable)1745fdc4257SSteve Yin void AccEventListener::fireStateFocusdChange(bool enable)
1755fdc4257SSteve Yin {
1765fdc4257SSteve Yin     if(enable)
1775fdc4257SSteve Yin     {
1785fdc4257SSteve Yin         pAgent->IncreaseState( pAccessible, AccessibleStateType::FOCUSED);
1795fdc4257SSteve Yin         pAgent->NotifyAccEvent(UM_EVENT_STATE_FOCUSED, pAccessible);
1805fdc4257SSteve Yin     }
1815fdc4257SSteve Yin     else
1825fdc4257SSteve Yin     {
1835fdc4257SSteve Yin         // no focus lost event in MSAA
1845fdc4257SSteve Yin     }
1855fdc4257SSteve Yin }
1865fdc4257SSteve Yin 
1875fdc4257SSteve Yin 
1885fdc4257SSteve Yin /**
1895fdc4257SSteve Yin  *	fire the MSAA state changed event
1905fdc4257SSteve Yin  *	@param state	the state id
1915fdc4257SSteve Yin  *	@param set		true if state is set, false if state is unset
1925fdc4257SSteve Yin  */
fireStatePropertyChange(short state,bool set)1935fdc4257SSteve Yin void AccEventListener::fireStatePropertyChange(short state, bool set )
1945fdc4257SSteve Yin {
1955fdc4257SSteve Yin     if( set )
1965fdc4257SSteve Yin     {
1975fdc4257SSteve Yin         //get new state
1985fdc4257SSteve Yin     }
1995fdc4257SSteve Yin     else
2005fdc4257SSteve Yin     {
2015fdc4257SSteve Yin         //lose old state
2025fdc4257SSteve Yin     }
2035fdc4257SSteve Yin }
2045fdc4257SSteve Yin 
2055fdc4257SSteve Yin /**
2065fdc4257SSteve Yin  *	get the role of accessible object which is observed
2075fdc4257SSteve Yin  */
getRole()2085fdc4257SSteve Yin short AccEventListener::getRole()
2095fdc4257SSteve Yin {
2105fdc4257SSteve Yin     Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pAccessible->getAccessibleContext(),UNO_QUERY);
2115fdc4257SSteve Yin     if(xContext.is())
2125fdc4257SSteve Yin     {
2135fdc4257SSteve Yin         return xContext->getAccessibleRole();
2145fdc4257SSteve Yin     }
2155fdc4257SSteve Yin     return -1;
2165fdc4257SSteve Yin }
2175fdc4257SSteve Yin 
2185fdc4257SSteve Yin /**
2195fdc4257SSteve Yin  *	get the role of accessible parent object which is observed
2205fdc4257SSteve Yin  */
getParentRole()2215fdc4257SSteve Yin short AccEventListener::getParentRole()
2225fdc4257SSteve Yin {
2235fdc4257SSteve Yin     if(pAccessible)
2245fdc4257SSteve Yin     {
2255fdc4257SSteve Yin         return pAgent->GetParentRole(pAccessible);
2265fdc4257SSteve Yin     }
2275fdc4257SSteve Yin     return -1;
2285fdc4257SSteve Yin }
2295fdc4257SSteve Yin /**
2305fdc4257SSteve Yin  *	remove the listener from accessible object
2315fdc4257SSteve Yin  */
removeMeFromBroadcaster()2325fdc4257SSteve Yin void AccEventListener::removeMeFromBroadcaster()
2335fdc4257SSteve Yin {
2345fdc4257SSteve Yin     try
2355fdc4257SSteve Yin     {
2365fdc4257SSteve Yin         vos::OGuard aGuard(aRemoveMutex);
2375fdc4257SSteve Yin         if(m_isDisposed)
2385fdc4257SSteve Yin             return;
2395fdc4257SSteve Yin         //get accessible context
2405fdc4257SSteve Yin         Reference< XAccessibleContext > pRContext;
2415fdc4257SSteve Yin         XAccessibleContext* pContext =NULL;
2425fdc4257SSteve Yin 
2435fdc4257SSteve Yin         if( pAccessible == NULL)
2445fdc4257SSteve Yin         {
2455fdc4257SSteve Yin             return;
2465fdc4257SSteve Yin         }
2475fdc4257SSteve Yin         pRContext = pAccessible->getAccessibleContext();
2485fdc4257SSteve Yin         if( !pRContext.is() )
2495fdc4257SSteve Yin         {
2505fdc4257SSteve Yin             return;
2515fdc4257SSteve Yin         }
2525fdc4257SSteve Yin 
2535fdc4257SSteve Yin         //get broadcaster from accessible component
2545fdc4257SSteve Yin         Reference<XAccessibleComponent> xComponent(pRContext,UNO_QUERY);
2555fdc4257SSteve Yin         if(!xComponent.is())
2565fdc4257SSteve Yin         {
2575fdc4257SSteve Yin             return;
2585fdc4257SSteve Yin         }
2595fdc4257SSteve Yin         Reference<XAccessibleEventBroadcaster> broadcaster(xComponent,UNO_QUERY);
2605fdc4257SSteve Yin         XAccessibleEventBroadcaster* pBroadcaster = broadcaster.get();
2615fdc4257SSteve Yin         if (pBroadcaster != NULL)
2625fdc4257SSteve Yin         {
2635fdc4257SSteve Yin             //remove the lister from accessible object
2645fdc4257SSteve Yin             pBroadcaster->removeEventListener(this);
2655fdc4257SSteve Yin             m_isDisposed = true;
2665fdc4257SSteve Yin             pAgent->NotifyDestroy(pAccessible);
2675fdc4257SSteve Yin         }
2685fdc4257SSteve Yin     }
2695fdc4257SSteve Yin     catch(...)
2705fdc4257SSteve Yin     {
2715fdc4257SSteve Yin         return;
2725fdc4257SSteve Yin     }
2735fdc4257SSteve Yin 
2745fdc4257SSteve Yin }
2755fdc4257SSteve Yin 
2765fdc4257SSteve Yin /**
2775fdc4257SSteve Yin  *	this method is invoked before listener is disposed
2785fdc4257SSteve Yin  */
disposing(const::com::sun::star::lang::EventObject & Source)2795fdc4257SSteve Yin void AccEventListener::disposing( const ::com::sun::star::lang::EventObject& Source )
2805fdc4257SSteve Yin throw (::com::sun::star::uno::RuntimeException)
2815fdc4257SSteve Yin {
2825fdc4257SSteve Yin     removeMeFromBroadcaster();
2835fdc4257SSteve Yin }
2845fdc4257SSteve Yin 
2855fdc4257SSteve Yin //need to investigate further
queryInterface(const::com::sun::star::uno::Type & aType)2865fdc4257SSteve Yin ::com::sun::star::uno::Any SAL_CALL AccEventListener::queryInterface( const ::com::sun::star::uno::Type& aType ) throw (::com::sun::star::uno::RuntimeException)
2875fdc4257SSteve Yin {
2885fdc4257SSteve Yin     if(aType.equals(::getCppuType( (Reference< com::sun::star::accessibility::XAccessibleEventListener> const *)0 ) ))
2895fdc4257SSteve Yin     {
2905fdc4257SSteve Yin         Reference< com::sun::star::accessibility::XAccessibleEventListener> xEventListener( static_cast< com::sun::star::accessibility::XAccessibleEventListener* >(this));
2915fdc4257SSteve Yin         return makeAny(xEventListener);
2925fdc4257SSteve Yin     }
2935fdc4257SSteve Yin 
2945fdc4257SSteve Yin     return Any();
2955fdc4257SSteve Yin }
2965fdc4257SSteve Yin 
acquire()2975fdc4257SSteve Yin void AccEventListener::acquire(  ) throw ()
2985fdc4257SSteve Yin {
2995fdc4257SSteve Yin     ::osl_incrementInterlockedCount( &m_refcount );
3005fdc4257SSteve Yin }
3015fdc4257SSteve Yin 
release()3025fdc4257SSteve Yin void AccEventListener::release() throw ()
3035fdc4257SSteve Yin {
3045fdc4257SSteve Yin     // thread-safe decrementation of reference count
3055fdc4257SSteve Yin     if (0 == ::osl_decrementInterlockedCount( &m_refcount ))
3065fdc4257SSteve Yin     {
3075fdc4257SSteve Yin         delete this; // shutdown this object
3085fdc4257SSteve Yin     }
3095fdc4257SSteve Yin }
310