1 #include "BridgeImpl.hpp"
2 #include "BridgeAccessible.hpp"
3 #include "BridgeAction.hpp"
4 #include "BridgeCollection.hpp"
5 #include "BridgeComponent.hpp"
6 #include "BridgeObject.hpp"
7 #include "BridgeValue.hpp"
11 #include <dali/integration-api/debug.h>
13 using namespace Dali::Accessibility;
15 class BridgeImpl : public virtual BridgeBase, public BridgeAccessible, public BridgeObject, public BridgeComponent, public BridgeCollection, public BridgeAction, public BridgeValue
17 DBus::DBusClient listenOnAtspiEnabledSignalClient;
18 DBus::DBusClient registryClient;
19 Accessible* currentWindow = nullptr;
20 bool screenReaderEnabled = false, isEnabled = false;
25 DBus::setDebugPrinter( []( const char* buf, size_t len ) {
26 std::string s{buf, len};
27 Dali::Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo, "%s", s.c_str() );
31 Consumed Emit( KeyEventType type, unsigned int keyCode, const std::string& keyName, unsigned int timeStamp, bool isText ) override
33 unsigned int evType = 0;
37 case KeyEventType::KeyPressed:
42 case KeyEventType::KeyReleased:
52 auto m = registryClient.method< bool( std::tuple< uint32_t, int32_t, int32_t, int32_t, int32_t, std::string, bool > ) >( "NotifyListenersSync" );
53 auto result = m.call( std::tuple< uint32_t, int32_t, int32_t, int32_t, int32_t, std::string, bool >{evType, 0, static_cast< int32_t >( keyCode ), 0, static_cast< int32_t >( timeStamp ), keyName, isText ? 1 : 0} );
56 LOG() << result.getError().message;
59 return std::get< 0 >( result ) ? Consumed::Yes : Consumed::No;
62 void ForceDown() override
65 BridgeAccessible::ForceDown();
69 ForceUpResult ForceUp() override
71 if( BridgeAccessible::ForceUp() == ForceUpResult::alreadyUp )
72 return ForceUpResult::alreadyUp;
74 BridgeObject::RegisterInterfaces();
75 BridgeAccessible::RegisterInterfaces();
76 BridgeComponent::RegisterInterfaces();
77 BridgeCollection::RegisterInterfaces();
78 BridgeAction::RegisterInterfaces();
79 BridgeValue::RegisterInterfaces();
81 RegisterOnBridge( &application );
83 registryClient = {ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_DEC, ATSPI_DBUS_INTERFACE_DEC, con};
84 auto proxy = DBus::DBusClient{ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_ROOT, ATSPI_DBUS_INTERFACE_SOCKET, con};
86 data->busName, "root"};
87 auto res = proxy.method< Address( Address ) >( "Embed" ).call( root );
89 application.parent.SetAddress( std::move( std::get< 0 >( res ) ) );
91 return ForceUpResult::justStarted;
94 void ApplicationHidden() override
98 currentWindow->Emit( WindowEvent::Deactivate, 0 );
99 currentWindow = nullptr;
102 void ApplicationShown() override
104 auto win = application.getActiveWindow();
105 if( win && win != currentWindow )
108 win->Emit( WindowEvent::Activate, 0 );
111 void Initialize() override
113 auto req = DBus::DBusClient{A11Y_DBUS_NAME, A11Y_DBUS_PATH, A11Y_DBUS_STATUS_INTERFACE, DBus::ConnectionType::SESSION};
114 auto p = req.property< bool >( "ScreenReaderEnabled" ).get();
116 screenReaderEnabled = std::get< 0 >( p );
117 p = req.property< bool >( "IsEnabled" ).get();
119 isEnabled = std::get< 0 >( p );
120 if( screenReaderEnabled || isEnabled )
123 static std::shared_ptr< Bridge > Create()
125 auto ptr = std::make_shared< BridgeImpl >();
126 ptr->MakePublic( Bridge::Visibility::allThreads );
127 ptr->listenOnAtspiEnabledSignalClient = DBus::DBusClient{A11Y_DBUS_NAME, A11Y_DBUS_PATH, A11Y_DBUS_STATUS_INTERFACE,
128 DBus::ConnectionType::SESSION};
131 ptr->listenOnAtspiEnabledSignalClient.addPropertyChangedEvent< bool >( "ScreenReaderEnabled", [p]( bool res ) {
132 p->screenReaderEnabled = res;
133 if( p->screenReaderEnabled || p->isEnabled )
138 ptr->listenOnAtspiEnabledSignalClient.addPropertyChangedEvent< bool >( "IsEnabled", [p]( bool res ) {
140 if( p->screenReaderEnabled || p->isEnabled )
150 std::shared_ptr< Bridge > Dali::Accessibility::CreateBridge()
154 return BridgeImpl::Create();
156 catch( AccessibleError& e )