From: dongsug.song Date: Thu, 3 May 2018 10:44:06 +0000 (+0900) Subject: Revert "[Tizen][ATSPI] Accessibility initial implementation" X-Git-Tag: accepted/tizen/unified/20180514.094031~13 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git;a=commitdiff_plain;h=d44e8530f0ffa9e68e51df5b9a3726076d361bb0 Revert "[Tizen][ATSPI] Accessibility initial implementation" This reverts commit c7445a69ae335ad6a034bf20f48ad49bc56f5b04. Change-Id: I86523566cf4cdca452bd8e75956c70f5e862d166 --- diff --git a/build/tizen/adaptor/Makefile.am b/build/tizen/adaptor/Makefile.am index 90f7104..190aab1 100644 --- a/build/tizen/adaptor/Makefile.am +++ b/build/tizen/adaptor/Makefile.am @@ -40,7 +40,6 @@ LIBDALI_ADAPTOR_LA_SOURCES = \ $(adaptor_clipboard_common_src_files) \ $(adaptor_clipboard_ubuntu_x11_src_files) \ $(devel_api_src_files) \ - $(bridge_src_files) \ $(adaptor_devel_api_text_abstraction_src_files) \ $(adaptor_graphics_common_src_files) \ $(adaptor_graphics_gles20_src_files) \ @@ -96,7 +95,6 @@ LIBDALI_ADAPTOR_LA_SOURCES = \ $(adaptor_adaptor_tizen_wayland_src_files) \ $(adaptor_clipboard_common_src_files) \ $(devel_api_src_files) \ - $(bridge_src_files) \ $(adaptor_devel_api_text_abstraction_src_files) \ $(adaptor_graphics_common_src_files) \ $(adaptor_graphics_gles20_src_files) \ @@ -160,7 +158,6 @@ LIBDALI_ADAPTOR_LA_SOURCES = \ $(adaptor_adaptor_tizen_wayland_src_files) \ $(adaptor_clipboard_common_src_files) \ $(devel_api_src_files) \ - $(bridge_src_files) \ $(adaptor_devel_api_text_abstraction_src_files) \ $(adaptor_graphics_common_src_files) \ $(adaptor_graphics_gles20_src_files) \ @@ -224,7 +221,6 @@ LIBDALI_ADAPTOR_LA_SOURCES = \ $(adaptor_adaptor_tizen_wayland_src_files) \ $(adaptor_clipboard_common_src_files) \ $(devel_api_src_files) \ - $(bridge_src_files) \ $(adaptor_devel_api_text_abstraction_src_files) \ $(adaptor_graphics_common_src_files) \ $(adaptor_graphics_gles20_src_files) \ @@ -286,7 +282,6 @@ LIBDALI_ADAPTOR_LA_SOURCES = \ $(adaptor_adaptor_tizen_wayland_src_files) \ $(adaptor_clipboard_common_src_files) \ $(devel_api_src_files) \ - $(bridge_src_files) \ $(adaptor_devel_api_text_abstraction_src_files) \ $(adaptor_graphics_common_src_files) \ $(adaptor_graphics_gles20_src_files) \ @@ -351,7 +346,6 @@ LIBDALI_ADAPTOR_LA_SOURCES = \ $(adaptor_adaptor_tizen_wearable_src_files) \ $(adaptor_clipboard_common_src_files) \ $(devel_api_src_files) \ - $(bridge_src_files) \ $(adaptor_devel_api_text_abstraction_src_files) \ $(adaptor_graphics_common_src_files) \ $(adaptor_graphics_gles20_src_files) \ diff --git a/build/tizen/adaptor/module.list b/build/tizen/adaptor/module.list index c38a303..297e0b3 100755 --- a/build/tizen/adaptor/module.list +++ b/build/tizen/adaptor/module.list @@ -7,10 +7,6 @@ include ../../../dali/internal/accessibility/file.list adaptor_adaptor_dir = ../../../dali/internal/adaptor include ../../../dali/internal/adaptor/file.list -# Module: atspi-bridge -bridge_src_dir = ../../../dali/dali-bridge -include ../../../dali/dali-bridge/file.list - # Module: clipboard adaptor_clipboard_dir = ../../../dali/internal/clipboard include ../../../dali/internal/clipboard/file.list @@ -63,7 +59,7 @@ include ../../../dali/internal/video/file.list adaptor_web_engine_dir = ../../../dali/internal/web-engine-lite include ../../../dali/internal/web-engine-lite/file.list -# Module: window-system +# Module: window-system adaptor_window_system_dir = ../../../dali/internal/window-system include ../../../dali/internal/window-system/file.list diff --git a/dali/dali-bridge/file.list b/dali/dali-bridge/file.list deleted file mode 100644 index 0cb402d..0000000 --- a/dali/dali-bridge/file.list +++ /dev/null @@ -1,14 +0,0 @@ -bridge_src_files = \ - $(bridge_src_dir)/src/Accessible.cpp \ - $(bridge_src_dir)/src/Component.cpp \ - $(bridge_src_dir)/src/BridgeAccessible.cpp \ - $(bridge_src_dir)/src/BridgeCollection.cpp \ - $(bridge_src_dir)/src/BridgeBase.cpp \ - $(bridge_src_dir)/src/BridgeComponent.cpp \ - $(bridge_src_dir)/src/BridgeAction.cpp \ - $(bridge_src_dir)/src/BridgeValue.cpp \ - $(bridge_src_dir)/src/BridgeObject.cpp \ - $(bridge_src_dir)/src/BridgeImpl.cpp \ - $(bridge_src_dir)/src/DBus.cpp \ - $(bridge_src_dir)/src/BridgeText.cpp \ - $(bridge_src_dir)/src/BridgeEditableText.cpp diff --git a/dali/dali-bridge/src/Accessible.cpp b/dali/dali-bridge/src/Accessible.cpp deleted file mode 100755 index 9612143..0000000 --- a/dali/dali-bridge/src/Accessible.cpp +++ /dev/null @@ -1,157 +0,0 @@ -#include "Common.hpp" - -using namespace Dali::Accessibility; - -std::vector< std::string > Accessible::GetInterfaces() -{ - std::vector< std::string > tmp; - tmp.push_back( ATSPI_DBUS_INTERFACE_ACCESSIBLE ); - if( dynamic_cast< Collection* >( this ) ) - tmp.push_back( ATSPI_DBUS_INTERFACE_COLLECTION ); - if( dynamic_cast< Text* >( this ) ) - tmp.push_back( ATSPI_DBUS_INTERFACE_TEXT ); - if( dynamic_cast< Value* >( this ) ) - tmp.push_back( ATSPI_DBUS_INTERFACE_VALUE ); - if( dynamic_cast< Component* >( this ) ) - tmp.push_back( ATSPI_DBUS_INTERFACE_COMPONENT ); - if( auto d = dynamic_cast< Action* >( this ) ) - { - if( d->GetActionCount() > 0 ) - tmp.push_back( ATSPI_DBUS_INTERFACE_ACTION ); - } - return tmp; -} - -thread_local std::atomic< Bridge* > threadLocalBridge{}; -std::atomic< Bridge* > allThreads{}; - -Bridge* Bridge::GetCurrentBridge() -{ - auto p = threadLocalBridge.load(); - if( !p ) - p = allThreads.load(); - return p; -} - -Accessible::Accessible() -{ -} - -Accessible::~Accessible() -{ - auto b = bridgeData.lock(); - if( b ) - b->objects.erase( it ); -} - -void Bridge::MakePublic( Visibility vis ) -{ - bool res = false; - Bridge* expected = this; - - switch( vis ) - { - case Visibility::hidden: - { - threadLocalBridge.compare_exchange_strong( expected, nullptr ); - allThreads.compare_exchange_strong( expected, nullptr ); - break; - } - case Visibility::thisThreadOnly: - { - res = threadLocalBridge.exchange( this ); - assert( !res ); - break; - } - case Visibility::allThreads: - { - res = allThreads.exchange( this ); - assert( !res ); - break; - } - } -} - -void Accessible::EmitShowing( bool showing ) -{ - if( auto b = GetBridgeData() ) - { - b->bridge->EmitStateChanged( this, State::Showing, showing ? 1 : 0, 0 ); - } -} - -void Accessible::EmitVisible( bool visible ) -{ - if( auto b = GetBridgeData() ) - { - b->bridge->EmitStateChanged( this, State::Visible, visible ? 1 : 0, 0 ); - } -} - -void Accessible::EmitHighlighted( bool set ) -{ - if( auto b = GetBridgeData() ) - { - b->bridge->EmitStateChanged( this, State::Highlighted, set ? 1 : 0, 0 ); - } -} - -void Accessible::Emit( WindowEvent we, unsigned int detail1 ) -{ - if( auto b = GetBridgeData() ) - { - b->bridge->Emit( this, we, detail1 ); - } -} - -std::vector< Accessible* > Accessible::GetChildren() -{ - std::vector< Accessible* > tmp( GetChildCount() ); - for( auto i = 0u; i < tmp.size(); ++i ) - { - tmp[i] = GetChildAtIndex( i ); - } - return tmp; -} - -std::shared_ptr< Bridge::Data > Accessible::GetBridgeData() -{ - auto b = bridgeData.lock(); - if( !b ) - { - auto p = Bridge::GetCurrentBridge(); - if( !p ) - return {}; - b = p->data; - } - return b; -} - -Address Accessible::GetAddress() -{ - auto b = bridgeData.lock(); - if( !b ) - { - b = GetBridgeData(); - assert( b ); - b->bridge->RegisterOnBridge( this ); - } - return {b->busName, b->root == this ? "root" : std::to_string( it->first )}; -} - -void Bridge::RegisterOnBridge( Accessible* obj ) -{ - assert( !obj->bridgeData.lock() || obj->bridgeData.lock() == data ); - if( !obj->bridgeData.lock() ) - { - assert( data ); - auto oid = ++data->objectId; - obj->it = data->objects.insert( {oid, obj} ).first; - obj->bridgeData = data; - } -} - -bool Accessible::IsProxy() -{ - return false; -} diff --git a/dali/dali-bridge/src/BridgeAccessible.cpp b/dali/dali-bridge/src/BridgeAccessible.cpp deleted file mode 100755 index eafa947..0000000 --- a/dali/dali-bridge/src/BridgeAccessible.cpp +++ /dev/null @@ -1,732 +0,0 @@ -#include "BridgeAccessible.hpp" -#include - -using namespace Dali::Accessibility; - -#define GET_NAVIGABLE_AT_POINT_MAX_RECURSION_DEPTH 10000 - -BridgeAccessible::BridgeAccessible() -{ -} - -void BridgeAccessible::RegisterInterfaces() -{ - DBus::DBusInterfaceDescription desc{ATSPI_DBUS_INTERFACE_ACCESSIBLE}; - AddGetPropertyToInterface( desc, "ChildCount", &BridgeAccessible::GetChildCount ); - AddGetPropertyToInterface( desc, "Name", &BridgeAccessible::GetName ); - AddGetPropertyToInterface( desc, "Description", &BridgeAccessible::GetDescription ); - AddGetPropertyToInterface( desc, "Parent", &BridgeAccessible::GetParent ); - AddFunctionToInterface( desc, "GetRole", &BridgeAccessible::GetRole ); - AddFunctionToInterface( desc, "GetRoleName", &BridgeAccessible::GetRoleName ); - AddFunctionToInterface( desc, "GetLocalizedRoleName", &BridgeAccessible::GetLocalizedRoleName ); - AddFunctionToInterface( desc, "GetState", &BridgeAccessible::GetStates ); - AddFunctionToInterface( desc, "GetAttributes", &BridgeAccessible::GetAttributes ); - AddFunctionToInterface( desc, "GetInterfaces", &BridgeAccessible::GetInterfaces ); - AddFunctionToInterface( desc, "GetChildAtIndex", &BridgeAccessible::GetChildAtIndex ); - AddFunctionToInterface( desc, "GetChildren", &BridgeAccessible::GetChildren ); - AddFunctionToInterface( desc, "GetIndexInParent", &BridgeAccessible::GetIndexInParent ); - AddFunctionToInterface( desc, "GetNavigableAtPoint", &BridgeAccessible::GetNavigableAtPoint ); - AddFunctionToInterface( desc, "GetNeighbor", &BridgeAccessible::GetNeighbor ); - AddFunctionToInterface( desc, "GetDefaultLabelInfo", &BridgeAccessible::GetDefaultLabelInfo ); - AddFunctionToInterface( desc, "DoGesture", &BridgeAccessible::DoGesture ); - AddFunctionToInterface( desc, "GetReadingMaterial", &BridgeAccessible::GetReadingMaterial ); - dbusServer.addInterface( "/", desc, true ); -} - -static bool AcceptObjectCheckRole( Component* obj ) -{ - if( !obj ) - return false; - switch( obj->GetRole() ) - { - case Role::Application: - case Role::Filler: - case Role::ScrollPane: - case Role::SplitPane: - case Role::Window: - case Role::Image: - case Role::ImageMap: - case Role::List: - case Role::Icon: - case Role::ToolBar: - case Role::RedundantObject: - case Role::ColorChooser: - case Role::TreeTable: - case Role::PageTabList: - case Role::PageTab: - case Role::SpinButton: - case Role::InputMethodWindow: - case Role::Embedded: - case Role::Invalid: - case Role::Notification: - case Role::DateEditor: - { - return false; - } - default: - { - break; - } - } - - return true; -} - -static Component* GetScrollableParent( Accessible* obj ) -{ - while( obj ) - { - obj = obj->GetParent(); - auto comp = dynamic_cast< Component* >( obj ); - if( comp && comp->IsScrollable() ) - return comp; - } - return nullptr; -} - -static bool ObjectIsItem( Component* obj ) -{ - if( !obj ) - return false; - auto role = obj->GetRole(); - return role == Role::ListItem || role == Role::MenuItem; -} - -static bool ObjectIsCollapsed( Component* obj ) -{ - if( !obj ) - return false; - const auto states = obj->GetStates(); - return states[State::Expandable] && !states[State::Expanded]; -} - -static bool OobjectIsZeroSize( Component* obj ) -{ - if( !obj ) - return false; - auto size = obj->GetExtents( CoordType::Window ).size; - return size.height == 0 || size.width == 0; -} - -static bool AcceptObject( Component* obj ) -{ - if( !obj ) - return false; - const auto states = obj->GetStates(); - if( !states[State::Visible] ) - return false; - if( !AcceptObjectCheckRole( obj ) ) - return false; -/* - TODO: add relations - if (CALL(get_object_in_relation_by_type, obj, ATSPI_RELATION_CONTROLLED_BY) != NULL) return 0; -*/ - if( !states[State::Highlightable] ) - return false; - - if( GetScrollableParent( obj ) != nullptr ) - { - auto parent = dynamic_cast< Component* >( obj->GetParent() ); - - if( parent ) - { - return !ObjectIsItem( obj ) || !ObjectIsCollapsed( parent ); - } - } - else - { - if( OobjectIsZeroSize( obj ) ) - { - return false; - } - if( !states[State::Showing] ) - { - return false; - } - } - return true; -} - -static bool AcceptObject( Accessible* obj ) -{ - auto c = dynamic_cast< Component* >( obj ); - return AcceptObject( c ); -} - -static bool AcceptObjectOrProxy( Component* obj ) -{ - return obj->IsProxy() || AcceptObject( obj ); -} - -static Component* CalculateNavigableAccessibleAtPoint( Accessible* root, Point p, CoordType cType, unsigned int maxRecursionDepth ) -{ - if( !root || maxRecursionDepth == 0 ) - return nullptr; - auto root_component = dynamic_cast< Component* >( root ); - if( root_component && !root_component->Contains( p, cType ) ) - { - return nullptr; - } - - auto children = root->GetChildren(); - for( auto childIt = children.rbegin(); childIt != children.rend(); childIt++ ) - { - auto result = CalculateNavigableAccessibleAtPoint( *childIt, p, cType, maxRecursionDepth - 1 ); - if( result ) - return result; - } - if( root_component && AcceptObjectOrProxy( root_component ) ) - return root_component; - return nullptr; - - /* - TODO: add relations - void *relation_obj = CALL(get_object_in_relation_by_type, root, ATSPI_RELATION_CONTROLLED_BY); - unsigned char contains = 0; - if (relation_obj) - { - contains = CALL(object_contains, relation_obj, x, y, coordinates_are_screen_based); - if (contains) root = relation_obj; - } - */ -} - -BridgeAccessible::ReadingMaterialType BridgeAccessible::GetReadingMaterial() -{ - auto self = FindSelf(); - auto attributes = self->GetAttributes(); - auto name = self->GetName(); - std::string labeledByName = ""; - std::string textIfceName = ""; - auto role = static_cast< uint32_t >( self->GetRole() ); - auto states = self->GetStates(); - auto localizedName = self->GetLocalizedRoleName(); - auto childCount = static_cast< int32_t >( self->GetChildCount() ); - - double currentValue = 0.0; - double minimumIncrement = 0.0; - double maximumValue = 0.0; - double minimumValue = 0.0; - - auto description = self->GetDescription(); - auto indexInParent = static_cast< int32_t >( self->GetIndexInParent() ); - bool isSelectedInParent = false; - bool hasCheckBoxChild = false; - int32_t firstSelectedChildIndex = 0; - int32_t selectedChildCount = 0; - - for( auto i = 0u; i < static_cast< size_t >( childCount ); ++i ) - { - auto q = self->GetChildAtIndex( i ); - auto s = q->GetStates(); - if( s[State::Selectable] ) - { - ++selectedChildCount; - if( s[State::Selected] ) - { - if( firstSelectedChildIndex < 0 ) - firstSelectedChildIndex = static_cast< int32_t >( i ); - } - } - if( q->GetRole() == Role::CheckBox ) - hasCheckBoxChild = true; - } - - int32_t listChildrenCount = 0; - Accessible* parent = self->GetParent(); - auto parentStateSet = parent ? parent->GetStates() : States{}; - auto parentChildCount = parent ? static_cast< int32_t >( parent->GetChildCount() ) : 0; - auto parentRole = static_cast< uint32_t >( parent ? parent->GetRole() : Role{} ); - Accessible* describedByObject = nullptr; - - return { - attributes, - name, - labeledByName, - textIfceName, - role, - states, - localizedName, - childCount, - currentValue, - minimumIncrement, - maximumValue, - minimumValue, - description, - indexInParent, - isSelectedInParent, - hasCheckBoxChild, - listChildrenCount, - firstSelectedChildIndex, - parent, - parentStateSet, - parentChildCount, - parentRole, - selectedChildCount, - describedByObject}; -} - -DBus::ValueOrError< bool > BridgeAccessible::DoGesture( int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, uint32_t ) -{ - return false; -} - -DBus::ValueOrError< Accessible*, uint8_t, Accessible* > BridgeAccessible::GetNavigableAtPoint( int32_t x, int32_t y, uint32_t coordType ) -{ - SCOPE(); - Accessible* deputy = nullptr; - auto accessible = FindSelf(); - auto cType = static_cast< CoordType >( coordType ); - auto component = CalculateNavigableAccessibleAtPoint( accessible, {x, y}, cType, GET_NAVIGABLE_AT_POINT_MAX_RECURSION_DEPTH ); - bool recurse = false; - if( component ) - { - const auto states = component->GetStates(); - if( states[State::Modal] ) - { - component = nullptr; - } - } - if( component ) - { - recurse = component->IsProxy(); - } - //TODO: add deputy - return {component, recurse, deputy}; -} - -static bool CheckChainEndWithAttribute( Accessible* obj, unsigned char forward ) -{ - if( !obj ) - return false; - auto attrs = obj->GetAttributes(); - for( auto& attr : attrs ) - { - if( attr.first == "relation_chain_end" ) - { - if( ( attr.second == "prev,end" && forward == 0 ) || ( attr.second == "next,end" && forward == 1 ) || attr.second == "prev,next,end" ) - { - return true; - } - } - } - return false; -} - -static Accessible* DeputyOfProxyInParentGet( Accessible* obj ) -{ - return nullptr; -/* -if (!obj) - return nullptr; - -Accessible *deputy = nullptr; -auto children = obj->GetChildren(); -unsigned int index = 0; -for (auto child : children) { - if (child->IsProxy()) { - if (index == 0) { - //WRN("Proxy does not have deputy object"); - break; - } - deputy = children[index - 1]; - break; - } - index++; -} -return deputy; -*/ -} - -Accessible* BridgeAccessible::GetCurrentlyHighlighted() -{ - //TODO: add currently highlighted object - return nullptr; -} - -std::vector< Accessible* > BridgeAccessible::ValidChildrenGet( const std::vector< Accessible* >& children, Accessible* start, Accessible* root ) -{ - /* condition to find first(last) object regardless of scrollable parent. - looping navigation does not care scrollable parent. - 1. currently highlighted object exists - 2. both start and root are same */ - - /* TODO: add code, we need a scrollable implementation first - Accessible *current = GetCurrentlyHighlighted(); - if (current && start == root) return children; - if(children.size() == 0) return {}; - - Eo *child = children[0]; - - if (child) - { - Evas_Coord x = 0, y = 0, w = 0, h = 0; - Evas_Coord sx = 0, sy = 0, sw = 0, sh = 0; - - if (_new_scrollable_parent_viewport_geometry_get(child, start, - &sx, &sy, &sw, &sh)) - { - Eina_List *l, *l_next; - EINA_LIST_FOREACH_SAFE(children, l, l_next, child) - { - eo_do(child, - elm_interface_atspi_component_extents_get(EINA_FALSE, - &x, &y, &w, &h)); - if (w == 0 || h == 0 || - !ELM_RECTS_INTERSECT(x, y, w, h, sx, sy, sw, sh)) - children = eina_list_remove_list(children, l); - } - } - } - */ - return children; -} - -static bool DeputyIs( Accessible* obj ) -{ - //TODO: add deputy - return false; -} - -static Accessible* GetObjectInRelationFlow( Accessible* ptr, RelationType type ) -{ - //TODO: add relations - return nullptr; -} -static Accessible* ProxyInParentGet( Accessible* obj ) -{ - if( !obj ) - return nullptr; - auto children = obj->GetChildren(); - for( auto& child : children ) - { - if( child->IsProxy() ) - return child; - } - return nullptr; -} - -static bool ObjectRoleIsAcceptableWhenNavigatingNextPrev( Accessible* obj ) -{ - if( !obj ) - return false; - auto role = obj->GetRole(); - return role != Role::PopupMenu && role != Role::Dialog; -} - -template < class T > -struct CycleDetection -{ - CycleDetection( const T value ) : key( value ), currentSearchSize( 1 ), counter( 1 ) {} - bool check( const T value ) - { - if( key == value ) - return true; - if( --counter == 0 ) - { - currentSearchSize <<= 1; - if( currentSearchSize == 0 ) - return true; // UNDEFINED BEHAVIOR - counter = currentSearchSize; - key = value; - } - return false; - } - T key; - unsigned int currentSearchSize; - unsigned int counter; -}; - -static Accessible* FindNonDefunctChild( const std::vector< Accessible* >& children, unsigned int currentIndex, unsigned char forward ) -{ - unsigned int childrenCount = children.size(); - for( ; currentIndex < childrenCount; forward ? ++currentIndex : --currentIndex ) - { - Accessible* n = children[currentIndex]; - if( n && !n->GetStates()[State::Defunct] ) - return n; - } - return nullptr; -} - -static Accessible* DirectionalDepthFirstSearchTryNonDefunctChild( Accessible* node, const std::vector< Accessible* >& children, unsigned char forward ) -{ - if( !node ) - return nullptr; - auto childrenCount = children.size(); - if( childrenCount > 0 ) - { - const bool isShowing = GetScrollableParent( node ) == nullptr ? node->GetStates()[State::Showing] : true; - if( isShowing ) - { - return FindNonDefunctChild( children, forward ? 0 : childrenCount - 1, forward ); - } - } - return nullptr; -} - -Accessible* BridgeAccessible::GetNextNonDefunctSibling( Accessible* obj, Accessible* start, Accessible* root, unsigned char forward ) -{ - if( !obj ) - return nullptr; - auto parent = obj->GetParent(); - if( !parent ) - return nullptr; - - auto children = ValidChildrenGet( parent->GetChildren(), start, root ); - - unsigned int children_count = children.size(); - if( children_count == 0 ) - { - return nullptr; - } - unsigned int current = 0; - for( ; current < children_count && children[current] != obj; ++current ) - ; - if( current >= children_count ) - { - return nullptr; - } - forward ? ++current : --current; - auto ret = FindNonDefunctChild( children, current, forward ); - return ret; -} - -Accessible* BridgeAccessible::DirectionalDepthFirstSearchTryNonDefunctSibling( bool& all_children_visited, Accessible* node, Accessible* start, Accessible* root, unsigned char forward ) -{ - while( true ) - { - Accessible* sibling = GetNextNonDefunctSibling( node, start, root, forward ); - if( sibling ) - { - node = sibling; - all_children_visited = false; - break; - } - // walk up... - node = node->GetParent(); - if( node == nullptr || node == root ) - return nullptr; - - // in backward traversing stop the walk up on parent - if( !forward ) - break; - } - return node; -} - -Accessible* BridgeAccessible::CalculateNeighbor( Accessible* root, Accessible* start, unsigned char forward, BridgeAccessible::GetNeighborSearchMode search_mode ) -{ - if( start && CheckChainEndWithAttribute( start, forward ) ) - return start; - if( root && root->GetStates()[State::Defunct] ) - return NULL; - if( start && start->GetStates()[State::Defunct] ) - { - start = NULL; - forward = 1; - } - - if( search_mode == BridgeAccessible::GetNeighborSearchMode::recurseToOutside ) - { - /* This only works if we navigate backward, and it is not possible to - find in embedded process. In this case the deputy should be used */ - return DeputyOfProxyInParentGet( start ); - } - - Accessible* node = start ? start : root; - if( !node ) - return nullptr; - - // initialization of all-children-visited flag for start node - we assume - // that when we begin at start node and we navigate backward, then all children - // are visited, so navigation will ignore start's children and go to - // previous sibling available. - /* Regarding condtion (start != root): - The last object can be found only if all_children_visited is false. - The start is same with root, when looking for the last object. */ - bool all_children_visited = ( start != root ) && ( search_mode != BridgeAccessible::GetNeighborSearchMode::recurseFromRoot && !forward ); - // true, if starting element should be ignored. this is only used in rare case of - // recursive search failing to find an object. - // consider tree, where element A on bus BUS_A has child B on bus BUS_B. when going "next" from - // element A algorithm has to descend into BUS_B and search element B and its children. this is done - // by returning to our caller object B with special flag set (meaning - continue the search from B on bus BUS_B). - // if next object will be found there (on BUS_B), then search ends. but if not, then our caller will find it out - // and will call us again with object A and flag search_mode set to NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING. - // this flag means, that object A was already checked previously and we should skip it and its children. - bool force_next = ( search_mode == BridgeAccessible::GetNeighborSearchMode::continueAfterFailedRecursion ); - - CycleDetection< Accessible* > cycleDetection( node ); - while( node ) - { - if( node->GetStates()[State::Defunct] ) - return nullptr; - - // always accept proxy object from different world - if( !force_next && node->IsProxy() ) - return node; - - auto children = node->GetChildren(); - children = ValidChildrenGet( children, start, root ); - - // do accept: - // 1. not start node - // 2. parent after all children in backward traversing - // 3. Nodes with roles: ATSPI_ROLE_PAGE_TAB, ATSPI_ROLE_POPUP_MENU and ATSPI_ROLE_DIALOG, only when looking for first or last element. - // Objects with those roles shouldnt be reachable, when navigating next / prev. - bool all_children_visited_or_moving_forward = ( children.size() == 0 || forward || all_children_visited ); - if( !force_next && node != start && all_children_visited_or_moving_forward && AcceptObject( node ) ) - { - if( start == NULL || ObjectRoleIsAcceptableWhenNavigatingNextPrev( node ) ) - return node; - } - - Accessible* next_related_in_direction = !force_next ? GetObjectInRelationFlow( node, forward ? RelationType::FlowsTo : RelationType::FlowsFrom ) : nullptr; - /* force_next means that the search_mode is NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING - in this case the node is elm_layout which is parent of proxy object. - There is an access object working for the proxy object, and the access - object could have relation information. This relation information should - be checked first before using the elm_layout as a node. */ - if( force_next && forward ) - { - auto deputy = DeputyOfProxyInParentGet( node ); - next_related_in_direction = - GetObjectInRelationFlow( deputy, forward ? RelationType::FlowsTo : RelationType::FlowsFrom ); - } - - if( next_related_in_direction && start->GetStates()[State::Defunct] ) - next_related_in_direction = NULL; - unsigned char want_cycle_detection = 0; - if( next_related_in_direction ) - { - /* Check next_related_in_direction is deputy object */ - Accessible* parent; - if( !forward ) - { - /* If the prev object is deputy, then go to inside of its proxy first */ - if( DeputyIs( next_related_in_direction ) ) - { - parent = next_related_in_direction->GetParent(); - next_related_in_direction = ProxyInParentGet( parent ); - } - } - else - { - /* If current object is deputy, and it has relation next object, - then do not use the relation next object, and use proxy first */ - if( DeputyIs( node ) ) - { - parent = node->GetParent(); - next_related_in_direction = ProxyInParentGet( parent ); - } - } - node = next_related_in_direction; - want_cycle_detection = 1; - } - else - { - auto child = !force_next && !all_children_visited ? DirectionalDepthFirstSearchTryNonDefunctChild( node, children, forward ) : nullptr; - if( child ) - { - want_cycle_detection = 1; - } - else - { - if( !force_next && node == root ) - return NULL; - all_children_visited = true; - child = DirectionalDepthFirstSearchTryNonDefunctSibling( all_children_visited, node, start, root, forward ); - } - node = child; - } - force_next = 0; - if( want_cycle_detection && cycleDetection.check( node ) ) - { - return NULL; - } - } - return NULL; -} - -DBus::ValueOrError< Accessible*, uint8_t > BridgeAccessible::GetNeighbor( std::string rootPath, int32_t direction, int32_t search_mode ) -{ - auto start = FindSelf(); - rootPath = StripPrefix( rootPath ); - auto root = !rootPath.empty() ? Find( rootPath ) : nullptr; - auto accessible = CalculateNeighbor( root, start, direction == 1, static_cast< GetNeighborSearchMode >( search_mode ) ); - unsigned char recurse = 0; - if( accessible ) - { - recurse = accessible->IsProxy(); - } - return {accessible, recurse}; -} - -Accessible* BridgeAccessible::GetParent() -{ - // NOTE: currently bridge supports single application root element. - // only element set as application root might return nullptr from GetParent - // if you want more, then you need to change setApplicationRoot to - // add/remove ApplicationRoot and make roots a vector. - auto z = FindSelf(); - auto p = z->GetParent(); - assert( p ); - return p; -} -DBus::ValueOrError< std::vector< Accessible* > > BridgeAccessible::GetChildren() -{ - return FindSelf()->GetChildren(); -} -std::string BridgeAccessible::GetDescription() -{ - return FindSelf()->GetDescription(); -} -DBus::ValueOrError< uint32_t > BridgeAccessible::GetRole() -{ - return static_cast< unsigned int >( FindSelf()->GetRole() ); -} -DBus::ValueOrError< std::string > BridgeAccessible::GetRoleName() -{ - return FindSelf()->GetRoleName(); -} -DBus::ValueOrError< std::string > BridgeAccessible::GetLocalizedRoleName() -{ - return FindSelf()->GetLocalizedRoleName(); -} -DBus::ValueOrError< int32_t > BridgeAccessible::GetIndexInParent() -{ - return FindSelf()->GetIndexInParent(); -} -DBus::ValueOrError< std::array< uint32_t, 2 > > BridgeAccessible::GetStates() -{ - return FindSelf()->GetStates().GetRawData(); -} -DBus::ValueOrError< std::unordered_map< std::string, std::string > > BridgeAccessible::GetAttributes() -{ - return FindSelf()->GetAttributes(); -} -DBus::ValueOrError< std::vector< std::string > > BridgeAccessible::GetInterfaces() -{ - return FindSelf()->GetInterfaces(); -} -int BridgeAccessible::GetChildCount() -{ - return FindSelf()->GetChildCount(); -} -DBus::ValueOrError< Accessible* > BridgeAccessible::GetChildAtIndex( int index ) -{ - if( index < 0 ) - throw AccessibleError{"negative index (" + std::to_string( index ) + ")"}; - return FindSelf()->GetChildAtIndex( static_cast< size_t >( index ) ); -} - -std::string BridgeAccessible::GetName() -{ - return FindSelf()->GetName(); -} - -DBus::ValueOrError< Accessible*, uint32_t > BridgeAccessible::GetDefaultLabelInfo() -{ - auto p = FindSelf(); - return {p, static_cast< uint32_t >( p->GetRole() )}; -} diff --git a/dali/dali-bridge/src/BridgeAccessible.hpp b/dali/dali-bridge/src/BridgeAccessible.hpp deleted file mode 100644 index fcc4217..0000000 --- a/dali/dali-bridge/src/BridgeAccessible.hpp +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef BRIDGE_ACCESSIBLE_HPP -#define BRIDGE_ACCESSIBLE_HPP - -#include "BridgeBase.hpp" -#include -#include -#include -#include - -class BridgeAccessible : public virtual BridgeBase -{ -protected: - BridgeAccessible(); - - void RegisterInterfaces(); - -public: - enum class GetNeighborSearchMode - { - normal = 0, - recurseFromRoot = 1, - continueAfterFailedRecursion = 2, - recurseToOutside = 3, - }; - int GetChildCount(); - DBus::ValueOrError< Dali::Accessibility::Accessible* > GetChildAtIndex( int index ); - Dali::Accessibility::Accessible* GetParent(); - DBus::ValueOrError< std::vector< Dali::Accessibility::Accessible* > > GetChildren(); - std::string GetName(); - std::string GetDescription(); - DBus::ValueOrError< uint32_t > GetRole(); - DBus::ValueOrError< std::string > GetRoleName(); - DBus::ValueOrError< std::string > GetLocalizedRoleName(); - DBus::ValueOrError< int32_t > GetIndexInParent(); - DBus::ValueOrError< std::array< uint32_t, 2 > > GetStates(); - DBus::ValueOrError< std::unordered_map< std::string, std::string > > GetAttributes(); - DBus::ValueOrError< std::vector< std::string > > GetInterfaces(); - DBus::ValueOrError< Dali::Accessibility::Accessible*, uint8_t, Dali::Accessibility::Accessible* > GetNavigableAtPoint( int32_t x, int32_t y, uint32_t coordType ); - DBus::ValueOrError< Dali::Accessibility::Accessible*, uint8_t > GetNeighbor( std::string root_path, int32_t direction, int32_t search_mode ); - DBus::ValueOrError< Dali::Accessibility::Accessible*, uint32_t > GetDefaultLabelInfo(); - using ReadingMaterialType = DBus::ValueOrError< - std::unordered_map< std::string, std::string >, // attributes - std::string, // name - std::string, // labeledByName - std::string, // textIfceName - uint32_t, - Dali::Accessibility::States, - std::string, // localized name - int32_t, // child count - double, // current value - double, // minimum increment - double, // maximum value - double, // minimum value - std::string, // description - int32_t, // index in parent - bool, // isSelectedInParent - bool, // hasCheckBoxChild - int32_t, // listChildrenCount - int32_t, // firstSelectedChildIndex - Dali::Accessibility::Accessible*, // parent - Dali::Accessibility::States, // parentStateSet - int32_t, // parentChildCount - uint32_t, // parentRole - int32_t, // selectedChildCount, - Dali::Accessibility::Accessible* // describedByObject - >; - - ReadingMaterialType GetReadingMaterial(); - - DBus::ValueOrError< bool > DoGesture( int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, uint32_t ); - -private: - Dali::Accessibility::Accessible* CalculateNeighbor( Dali::Accessibility::Accessible* root, Dali::Accessibility::Accessible* start, unsigned char forward, GetNeighborSearchMode search_mode ); - std::vector< Dali::Accessibility::Accessible* > ValidChildrenGet( const std::vector< Dali::Accessibility::Accessible* >& children, Dali::Accessibility::Accessible* start, Dali::Accessibility::Accessible* root ); - Dali::Accessibility::Accessible* GetCurrentlyHighlighted(); - Dali::Accessibility::Accessible* DirectionalDepthFirstSearchTryNonDefunctSibling( bool& all_children_visited, Dali::Accessibility::Accessible* node, Dali::Accessibility::Accessible* start, Dali::Accessibility::Accessible* root, unsigned char forward ); - Dali::Accessibility::Accessible* GetNextNonDefunctSibling( Dali::Accessibility::Accessible* obj, Dali::Accessibility::Accessible* start, Dali::Accessibility::Accessible* root, unsigned char forward ); -}; - -#endif diff --git a/dali/dali-bridge/src/BridgeAction.cpp b/dali/dali-bridge/src/BridgeAction.cpp deleted file mode 100755 index 664a665..0000000 --- a/dali/dali-bridge/src/BridgeAction.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include "BridgeAction.hpp" -#include - -using namespace Dali::Accessibility; - -void BridgeAction::RegisterInterfaces() -{ - DBus::DBusInterfaceDescription desc{ATSPI_DBUS_INTERFACE_ACTION}; - - AddGetPropertyToInterface( desc, "NActions", &BridgeAction::GetActionCount ); - - AddFunctionToInterface( desc, "GetName", &BridgeAction::GetActionName ); - AddFunctionToInterface( desc, "GetLocalizedName", &BridgeAction::GetLocalizedActionName ); - AddFunctionToInterface( desc, "GetDescription", &BridgeAction::GetActionDescription ); - AddFunctionToInterface( desc, "GetKeyBinding", &BridgeAction::GetActionKeyBinding ); - AddFunctionToInterface( desc, "DoAction", &BridgeAction::DoAction ); - AddFunctionToInterface( desc, "DoActionName", &BridgeAction::DoActionName ); - dbusServer.addInterface( "/", desc, true ); -} - -Action* BridgeAction::FindSelf() const -{ - auto s = BridgeBase::FindSelf(); - assert( s ); - auto s2 = dynamic_cast< Action* >( s ); - if( !s2 ) - throw AccessibleError{"object " + s->GetAddress().ToString() + " doesn't have Action interface"}; - return s2; -} - -DBus::ValueOrError< std::string > BridgeAction::GetActionName( int32_t index ) -{ - auto self = FindSelf(); - return self->GetActionName( index ); -} - -DBus::ValueOrError< std::string > BridgeAction::GetLocalizedActionName( int32_t index ) -{ - auto self = FindSelf(); - return self->GetLocalizedActionName( index ); -} - -DBus::ValueOrError< std::string > BridgeAction::GetActionDescription( int32_t index ) -{ - auto self = FindSelf(); - return self->GetActionDescription( index ); -} - -DBus::ValueOrError< std::string > BridgeAction::GetActionKeyBinding( int32_t index ) -{ - auto self = FindSelf(); - return self->GetActionKeyBinding( index ); -} - -DBus::ValueOrError< int32_t > BridgeAction::GetActionCount() -{ - auto self = FindSelf(); - return self->GetActionCount(); - ; -} - -DBus::ValueOrError< bool > BridgeAction::DoAction( int32_t index ) -{ - auto self = FindSelf(); - return self->DoAction( index ); -} - -DBus::ValueOrError< bool > BridgeAction::DoActionName( std::string name ) -{ - auto self = FindSelf(); - auto cnt = self->GetActionCount(); - for( auto i = 0u; i < cnt; ++i ) - { - if( self->GetActionName( i ) == name ) - { - return self->DoAction( i ); - } - } - throw AccessibleError{"object " + self->GetAddress().ToString() + " doesn't have action '" + name + "'"}; -} diff --git a/dali/dali-bridge/src/BridgeAction.hpp b/dali/dali-bridge/src/BridgeAction.hpp deleted file mode 100644 index 5ff10e8..0000000 --- a/dali/dali-bridge/src/BridgeAction.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef BRIDGE_ACTION_HPP -#define BRIDGE_ACTION_HPP - -#include "BridgeBase.hpp" - -#include -#include - -class BridgeAction : public virtual BridgeBase -{ -protected: - BridgeAction() = default; - - void RegisterInterfaces(); - - Dali::Accessibility::Action* FindSelf() const; - -public: - DBus::ValueOrError< std::string > GetActionName( int32_t index ); - DBus::ValueOrError< std::string > GetLocalizedActionName( int32_t index ); - DBus::ValueOrError< std::string > GetActionDescription( int32_t index ); - DBus::ValueOrError< std::string > GetActionKeyBinding( int32_t index ); - DBus::ValueOrError< int32_t > GetActionCount(); - DBus::ValueOrError< bool > DoAction( int32_t index ); - DBus::ValueOrError< bool > DoActionName( std::string name ); -}; - -#endif diff --git a/dali/dali-bridge/src/BridgeBase.cpp b/dali/dali-bridge/src/BridgeBase.cpp deleted file mode 100755 index d607c01..0000000 --- a/dali/dali-bridge/src/BridgeBase.cpp +++ /dev/null @@ -1,165 +0,0 @@ -#include "BridgeBase.hpp" -#include -#include - -using namespace Dali::Accessibility; - -BridgeBase::BridgeBase() -{ -} - -BridgeBase::ForceUpResult BridgeBase::ForceUp() -{ - if( Bridge::ForceUp() == ForceUpResult::alreadyUp ) - return ForceUpResult::alreadyUp; - auto proxy = DBus::DBusClient{dbusLocators::atspi::BUS, dbusLocators::atspi::OBJ_PATH, - dbusLocators::atspi::BUS_INTERFACE, DBus::ConnectionType::SESSION}; - auto addr = proxy.method< std::string() >( dbusLocators::atspi::GET_ADDRESS ).call(); - - if( !addr ) - throw AccessibleError{std::string( "failed at call '" ) + dbusLocators::atspi::GET_ADDRESS + - "': " + addr.getError().message}; - - con = std::make_shared< DBus::EldbusConnection >( eldbus_address_connection_get( std::get< 0 >( addr ).c_str() ) ); - data->busName = DBus::getConnectionName( con ); - data->root = &application; - dbusServer = {con}; - - { - DBus::DBusInterfaceDescription desc{"org.a11y.atspi.Cache"}; - AddFunctionToInterface( desc, "GetItems", &BridgeBase::GetItems ); - dbusServer.addInterface( "/org/a11y/atspi/cache", desc ); - } - { - DBus::DBusInterfaceDescription desc{"org.a11y.atspi.Application"}; - AddGetSetPropertyToInterface( desc, "Id", &BridgeBase::IdGet, &BridgeBase::IdSet ); - dbusServer.addInterface( ATSPI_PATH, desc ); - } - return ForceUpResult::justStarted; -} - -void BridgeBase::ForceDown() -{ - Bridge::ForceDown(); - dbusServer = {}; - con = {}; -} - -const std::string& BridgeBase::GetBusName() const -{ - static std::string empty; - return data ? data->busName : empty; -} - -Accessible* BridgeBase::FindByPath( const std::string& name ) const -{ - try - { - return Find( name ); - } - catch( AccessibleError ) - { - return nullptr; - } -} - -void BridgeBase::SetApplicationChild( Accessible* root ) -{ - // for now you can set root only once. - // to set it multiple times you'd have to remove old one first, which usually involves - // a lot of messy events and cornercases (imagine old root becoming child of new-not-yet-announced one) - application.children.push_back( root ); - SetIsOnRootLevel( root ); -} - -// Accessible *BridgeBase::getApplicationRoot() const -// { -// return rootElement; -// } - -std::string BridgeBase::StripPrefix( const std::string& path ) -{ - auto size = strlen( ATSPI_PATH ); - return path.substr( size + 1 ); -} - -Accessible* BridgeBase::Find( const std::string& path ) const -{ - if( path == "root" ) - return &application; - char* p; - auto val = std::strtoll( path.c_str(), &p, 10 ); - if( p == path.c_str() ) - throw AccessibleError{"invalid path '" + path + "'"}; - auto it = data->objects.find( val ); - if( it == data->objects.end() ) - throw AccessibleError{"unknown object '" + path + "'"}; - return it->second; -} - -Accessible* BridgeBase::Find( const Address& ptr ) const -{ - assert( ptr.GetBus() == data->busName ); - return Find( ptr.GetPath() ); -} - -Accessible* BridgeBase::FindSelf() const -{ - auto pth = DBus::DBusServer::getCurrentObjectPath(); - auto size = strlen( ATSPI_PATH ); - if( pth.size() <= size ) - throw AccessibleError{"invalid path '" + pth + "'"}; - if( pth.substr( 0, size ) != ATSPI_PATH ) - throw AccessibleError{"invalid path '" + pth + "'"}; - if( pth[size] != '/' ) - throw AccessibleError{"invalid path '" + pth + "'"}; - return Find( StripPrefix( pth ) ); -} - -void BridgeBase::IdSet( int id ) -{ - this->id = id; -} -int BridgeBase::IdGet() -{ - return this->id; -} - -auto BridgeBase::GetItems() -> DBus::ValueOrError< std::vector< CacheElementType > > -{ - auto root = &application; - - std::vector< CacheElementType > res; - - res.emplace_back( std::move( CreateCacheElement( root ) ) ); - for( auto const& it : data->objects ) - res.emplace_back( std::move( CreateCacheElement( it.second ) ) ); - - return res; -} - -auto BridgeBase::CreateCacheElement( Accessible* item ) -> CacheElementType -{ - if( !item ) - return {}; - - auto root = &application; - auto parent = item->GetParent(); - - std::vector< Address > children; - for( auto i = 0u; i < item->GetChildCount(); ++i ) - { - children.emplace_back( item->GetChildAtIndex( i )->GetAddress() ); - } - - return std::make_tuple( - item->GetAddress(), - root->GetAddress(), - parent->GetAddress(), - children, - item->GetInterfaces(), - item->GetName(), - item->GetRole(), - item->GetDescription(), - item->GetStates().GetRawData() ); -} diff --git a/dali/dali-bridge/src/BridgeBase.hpp b/dali/dali-bridge/src/BridgeBase.hpp deleted file mode 100644 index 10a16a1..0000000 --- a/dali/dali-bridge/src/BridgeBase.hpp +++ /dev/null @@ -1,215 +0,0 @@ -#ifndef BRIDGE_HPP -#define BRIDGE_HPP - -#include "Common.hpp" -#include - -class AppAccessible : public virtual Dali::Accessibility::Accessible, public virtual Dali::Accessibility::Collection -{ -public: - Dali::Accessibility::EmptyAccessibleWithAddress parent; - std::vector< Dali::Accessibility::Accessible* > children; - std::string name; - - std::string GetName() override - { - return name; - } - std::string GetDescription() override - { - return ""; - } - Dali::Accessibility::Accessible* GetParent() override - { - return &parent; - } - size_t GetChildCount() override - { - return children.size(); - } - Dali::Accessibility::Accessible* GetChildAtIndex( size_t index ) override - { - auto s = children.size(); - if( index >= s ) - throw Dali::Accessibility::AccessibleError{"invalid index " + std::to_string( index ) + " for object with " + std::to_string( s ) + " children"}; - return children[index]; - } - size_t GetIndexInParent() override - { - throw Dali::Accessibility::AccessibleError{"can't call GetIndexInParent on application object"}; - } - Dali::Accessibility::Role GetRole() override - { - return Dali::Accessibility::Role::Application; - } - Dali::Accessibility::States GetStates() override - { - return {}; - } - Dali::Accessibility::Attributes GetAttributes() override - { - return {}; - } - Dali::Accessibility::Accessible* getActiveWindow() - { - return children.empty() ? nullptr : children[0]; - } -}; - -class BridgeBase : public Dali::Accessibility::Bridge -{ -public: - const std::string& GetBusName() const override; - void SetApplicationChild( Dali::Accessibility::Accessible* root ) override; - Dali::Accessibility::Accessible* GetApplication() const override - { - return &application; - } - - template < typename SELF, typename... RET, typename... ARGS > - void AddFunctionToInterface( - DBus::DBusInterfaceDescription& desc, const std::string& funcName, - DBus::ValueOrError< RET... > ( SELF::*funcPtr )( ARGS... ) ) - { - desc.addMethod< DBus::ValueOrError< RET... >( ARGS... ) >( funcName, - [=]( ARGS... args ) -> DBus::ValueOrError< RET... > { - try - { - return ( dynamic_cast< SELF* >( this )->*funcPtr )( std::move( args )... ); - } - catch( Dali::Accessibility::AccessibleError& e ) - { - return DBus::Error{e.what()}; - } - } ); - } - template < typename T, typename SELF > - void AddGetPropertyToInterface( DBus::DBusInterfaceDescription& desc, - const std::string& funcName, T ( SELF::*funcPtr )() ) - { - desc.addProperty< T >( funcName, - [=]() -> DBus::ValueOrError< T > { - try - { - return ( dynamic_cast< SELF* >( this )->*funcPtr )(); - } - catch( Dali::Accessibility::AccessibleError& e ) - { - return DBus::Error{e.what()}; - } - }, - {} ); - } - template < typename T, typename SELF > - void AddSetPropertyToInterface( DBus::DBusInterfaceDescription& desc, - const std::string& funcName, void ( SELF::*funcPtr )( T ) ) - { - desc.addProperty< T >( funcName, {}, - [=]( T t ) -> DBus::ValueOrError< void > { - try - { - ( dynamic_cast< SELF* >( this )->*funcPtr )( std::move( t ) ); - return {}; - } - catch( Dali::Accessibility::AccessibleError& e ) - { - return DBus::Error{e.what()}; - } - } ); - } - template < typename T, typename T1, typename SELF > - void AddGetSetPropertyToInterface( DBus::DBusInterfaceDescription& desc, - const std::string& funcName, T1 ( SELF::*funcPtrGet )(), DBus::ValueOrError< void > ( SELF::*funcPtrSet )( T ) ) - { - desc.addProperty< T >( funcName, - [=]() -> DBus::ValueOrError< T > { - try - { - return ( dynamic_cast< SELF* >( this )->*funcPtrGet )(); - } - catch( Dali::Accessibility::AccessibleError& e ) - { - return DBus::Error{e.what()}; - } - }, - [=]( T t ) -> DBus::ValueOrError< void > { - try - { - ( dynamic_cast< SELF* >( this )->*funcPtrSet )( std::move( t ) ); - return {}; - } - catch( Dali::Accessibility::AccessibleError& e ) - { - return DBus::Error{e.what()}; - } - } ); - } - template < typename T, typename T1, typename SELF > - void AddGetSetPropertyToInterface( DBus::DBusInterfaceDescription& desc, - const std::string& funcName, T1 ( SELF::*funcPtrGet )(), void ( SELF::*funcPtrSet )( T ) ) - { - desc.addProperty< T >( funcName, - [=]() -> DBus::ValueOrError< T > { - try - { - return ( dynamic_cast< SELF* >( this )->*funcPtrGet )(); - } - catch( Dali::Accessibility::AccessibleError& e ) - { - return DBus::Error{e.what()}; - } - }, - [=]( T t ) -> DBus::ValueOrError< void > { - try - { - ( dynamic_cast< SELF* >( this )->*funcPtrSet )( std::move( t ) ); - return {}; - } - catch( Dali::Accessibility::AccessibleError& e ) - { - return DBus::Error{e.what()}; - } - } ); - } - static std::string StripPrefix( const std::string& path ); - - Dali::Accessibility::Accessible* Find( const std::string& path ) const; - Dali::Accessibility::Accessible* Find( const Dali::Accessibility::Address& ptr ) const; - Dali::Accessibility::Accessible* FindSelf() const; - Dali::Accessibility::Accessible* FindByPath( const std::string& name ) const override; - void SetApplicationName( std::string name ) override - { - application.name = std::move( name ); - } - -protected: - mutable AppAccessible application; - -private: - void IdSet( int id ); - int IdGet(); - - using CacheElementType = std::tuple< - Dali::Accessibility::Address, Dali::Accessibility::Address, Dali::Accessibility::Address, - std::vector< Dali::Accessibility::Address >, - std::vector< std::string >, - std::string, - Dali::Accessibility::Role, - std::string, - std::array< uint32_t, 2 > >; - DBus::ValueOrError< std::vector< CacheElementType > > GetItems(); - CacheElementType CreateCacheElement( Dali::Accessibility::Accessible* item ); - -protected: - BridgeBase(); - virtual ~BridgeBase() = default; - - ForceUpResult ForceUp() override; - void ForceDown() override; - - DBus::DBusServer dbusServer; - std::shared_ptr< DBus::EldbusConnection > con; - int id = 0; -}; - -#endif diff --git a/dali/dali-bridge/src/BridgeCollection.cpp b/dali/dali-bridge/src/BridgeCollection.cpp deleted file mode 100644 index 22fcddc..0000000 --- a/dali/dali-bridge/src/BridgeCollection.cpp +++ /dev/null @@ -1,366 +0,0 @@ -#include "BridgeCollection.hpp" -#include -#include -#include -#include - -using namespace Dali::Accessibility; - -void BridgeCollection::RegisterInterfaces() -{ - DBus::DBusInterfaceDescription desc{ATSPI_DBUS_INTERFACE_COLLECTION}; - AddFunctionToInterface( desc, "GetMatches", &BridgeCollection::GetMatches ); - dbusServer.addInterface( "/", desc, true ); -} - -Collection* BridgeCollection::FindSelf() const -{ - auto s = BridgeBase::FindSelf(); - assert( s ); - auto s2 = dynamic_cast< Collection* >( s ); - if( !s2 ) - throw AccessibleError{"object " + s->GetAddress().ToString() + " doesn't have Collection interface"}; - return s2; -} - -enum -{ - ATSPI_Collection_MATCH_INVALID, - ATSPI_Collection_MATCH_ALL, - ATSPI_Collection_MATCH_ANY, - ATSPI_Collection_MATCH_NONE, - ATSPI_Collection_MATCH_EMPTY, - ATSPI_Collection_MATCH_LAST_DEFINED, -}; - -struct BridgeCollection::Comparer -{ - using Mode = MatchType; - - enum class CompareFuncExit - { - firstFound, - firstNotFound - }; - - static Mode ConvertToMatchType( int32_t mode ) - { - switch( mode ) - { - case ATSPI_Collection_MATCH_INVALID: - { - return Mode::Invalid; - } - case ATSPI_Collection_MATCH_ALL: - { - return Mode::All; - } - case ATSPI_Collection_MATCH_ANY: - { - return Mode::Any; - } - case ATSPI_Collection_MATCH_NONE: - { - return Mode::None; - } - case ATSPI_Collection_MATCH_EMPTY: - { - return Mode::Empty; - } - } - return Mode::Invalid; - } - - struct ComparerInterfaces - { - std::unordered_set< std::string > object; - std::vector< std::string > requested; - Mode mode = Mode::Invalid; - - ComparerInterfaces( MatchRule* rule ) : mode( ConvertToMatchType( std::get< Index::InterfacesMatchType >( *rule ) ) ) - { - requested = {std::get< Index::Interfaces >( *rule ).begin(), std::get< Index::Interfaces >( *rule ).end()}; - } - void Update( Accessible* obj ) - { - object.clear(); - for( auto& q : obj->GetInterfaces() ) - object.insert( std::move( q ) ); - } - bool RequestEmpty() const { return requested.empty(); } - bool ObjectEmpty() const { return object.empty(); } - bool Compare( CompareFuncExit exit ) - { - bool foundAny = false; - for( auto& iname : requested ) - { - bool found = ( object.find( iname ) != object.end() ); - if( found ) - foundAny = true; - if( found == ( exit == CompareFuncExit::firstFound ) ) - return found; - } - return foundAny; - } - }; - struct ComparerAttributes - { - std::unordered_map< std::string, std::string > requested, object; - Mode mode = Mode::Invalid; - - ComparerAttributes( MatchRule* rule ) : mode( ConvertToMatchType( std::get< Index::AttributesMatchType >( *rule ) ) ) - { - requested = std::get< Index::Attributes >( *rule ); - } - void Update( Accessible* obj ) - { - object = obj->GetAttributes(); - } - bool RequestEmpty() const { return requested.empty(); } - bool ObjectEmpty() const { return object.empty(); } - bool Compare( CompareFuncExit exit ) - { - bool foundAny = false; - for( auto& iname : requested ) - { - auto it = object.find( iname.first ); - bool found = it != object.end() && iname.second == it->second; - if( found ) - foundAny = true; - if( found == ( exit == CompareFuncExit::firstFound ) ) - { - return found; - } - } - return foundAny; - } - }; - struct ComparerRoles - { - using Roles = BitStates< 4, Role >; - Roles requested, object; - Mode mode = Mode::Invalid; - - ComparerRoles( MatchRule* rule ) : mode( ConvertToMatchType( std::get< Index::RolesMatchType >( *rule ) ) ) - { - requested = Roles{std::get< Index::Roles >( *rule )}; - } - void Update( Accessible* obj ) - { - object = {}; - object[obj->GetRole()] = true; - assert( object ); - } - bool RequestEmpty() const { return !requested; } - bool ObjectEmpty() const { return !object; } - bool Compare( CompareFuncExit exit ) - { - switch( mode ) - { - case Mode::Invalid: - { - return true; - } - case Mode::Empty: - case Mode::All: - { - return requested == ( object & requested ); - } - case Mode::Any: - { - return bool( object & requested ); - } - case Mode::None: - { - return bool( object & requested ); - } - } - return false; - } - }; - struct ComparerStates - { - States requested, object; - Mode mode = Mode::Invalid; - - ComparerStates( MatchRule* rule ) : mode( ConvertToMatchType( std::get< Index::StatesMatchType >( *rule ) ) ) - { - requested = States{std::get< Index::States >( *rule )}; - } - void Update( Accessible* obj ) - { - object = obj->GetStates(); - } - bool RequestEmpty() const { return !requested; } - bool ObjectEmpty() const { return !object; } - bool Compare( CompareFuncExit exit ) - { - switch( mode ) - { - case Mode::Invalid: - { - return true; - } - case Mode::Empty: - case Mode::All: - { - return requested == ( object & requested ); - } - case Mode::Any: - { - return bool( object & requested ); - } - case Mode::None: - { - return bool( object & requested ); - } - } - return false; - } - }; - - template < typename T > - bool compareFunc( T& cmp, Accessible* obj ) - { - if( cmp.mode == Mode::Invalid ) - return true; - cmp.Update( obj ); - switch( cmp.mode ) - { - case Mode::Any: - { - if( cmp.RequestEmpty() || cmp.ObjectEmpty() ) - return false; - break; - } - case Mode::All: - { - if( cmp.RequestEmpty() ) - return true; - if( cmp.ObjectEmpty() ) - return false; - break; - } - case Mode::None: - { - if( cmp.RequestEmpty() || cmp.ObjectEmpty() ) - return true; - break; - } - case Mode::Empty: - { - if( cmp.RequestEmpty() && cmp.ObjectEmpty() ) - return true; - if( cmp.RequestEmpty() || cmp.ObjectEmpty() ) - return false; - break; - } - case Mode::Invalid: - { - return true; - } - } - - switch( cmp.mode ) - { - case Mode::Empty: - case Mode::All: - { - if( !cmp.Compare( CompareFuncExit::firstNotFound ) ) - return false; - break; - } - case Mode::Any: - { - if( cmp.Compare( CompareFuncExit::firstFound ) ) - return true; - break; - } - case Mode::None: - { - if( cmp.Compare( CompareFuncExit::firstFound ) ) - return false; - break; - } - case Mode::Invalid: - { - return true; - } - } - switch( cmp.mode ) - { - case Mode::Empty: - case Mode::All: - case Mode::None: - { - return true; - } - case Mode::Any: - { - return false; - } - case Mode::Invalid: - { - return true; - } - } - return false; - } - - ComparerInterfaces ci; - ComparerAttributes ca; - ComparerRoles cr; - ComparerStates cs; - - Comparer( MatchRule* mr ) : ci( mr ), ca( mr ), cr( mr ), cs( mr ) {} - - bool operator()( Accessible* obj ) - { - return compareFunc( ci, obj ) && - compareFunc( ca, obj ) && - compareFunc( cr, obj ) && - compareFunc( cs, obj ); - } -}; - -void BridgeCollection::VisitNodes( Accessible* obj, std::vector< Accessible* >& result, Comparer& cmp, size_t maxCount ) -{ - if( result.size() >= maxCount ) - return; - - if( cmp( obj ) ) - result.emplace_back( obj ); - - for( auto i = 0u; i < obj->GetChildCount(); ++i ) - VisitNodes( obj->GetChildAtIndex( i ), result, cmp, maxCount ); -} - -DBus::ValueOrError< std::vector< Accessible* > > BridgeCollection::GetMatches( MatchRule rule, uint32_t sortBy, int32_t count, bool traverse ) -{ - std::vector< Accessible* > res; - auto self = BridgeBase::FindSelf(); - auto matcher = Comparer{&rule}; - VisitNodes( self, res, matcher, count ); - - switch( static_cast< SortOrder >( sortBy ) ) - { - case SortOrder::Canonical: - { - break; - } - - case SortOrder::ReverseCanonical: - { - std::reverse( res.begin(), res.end() ); - break; - } - - default: - { - throw AccessibleError{"unsupported sorting order"}; - } - //TODO: other cases - } - - return res; -} diff --git a/dali/dali-bridge/src/BridgeCollection.hpp b/dali/dali-bridge/src/BridgeCollection.hpp deleted file mode 100644 index ba92f30..0000000 --- a/dali/dali-bridge/src/BridgeCollection.hpp +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef BRIDGE_COLLECTION_HPP -#define BRIDGE_COLLECTION_HPP - -#include "BridgeBase.hpp" - -#include -#include -#include -#include - -class BridgeCollection : public virtual BridgeBase -{ -private: - struct Comparer; - static void VisitNodes( Dali::Accessibility::Accessible* obj, std::vector< Dali::Accessibility::Accessible* >& result, Comparer& cmp, size_t maxCount ); - -protected: - BridgeCollection() = default; - - void RegisterInterfaces(); - - Dali::Accessibility::Collection* FindSelf() const; - -public: - using MatchRule = std::tuple< - std::array< int32_t, 2 >, int32_t, - std::unordered_map< std::string, std::string >, int32_t, - std::array< int32_t, 4 >, int32_t, - std::vector< std::string >, int32_t, - bool >; - struct Index - { - enum - { - States, - StatesMatchType, - Attributes, - AttributesMatchType, - Roles, - RolesMatchType, - Interfaces, - InterfacesMatchType, - }; - }; - - DBus::ValueOrError< std::vector< Dali::Accessibility::Accessible* > > GetMatches( MatchRule rule, uint32_t sortBy, int32_t count, bool traverse ); -}; - -#endif diff --git a/dali/dali-bridge/src/BridgeComponent.cpp b/dali/dali-bridge/src/BridgeComponent.cpp deleted file mode 100644 index 6bbfaff..0000000 --- a/dali/dali-bridge/src/BridgeComponent.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "BridgeComponent.hpp" -#include - -#define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties" - -using namespace Dali::Accessibility; - -BridgeComponent::BridgeComponent() -{ -} - -void BridgeComponent::RegisterInterfaces() -{ - DBus::DBusInterfaceDescription desc{ATSPI_DBUS_INTERFACE_COMPONENT}; - AddFunctionToInterface( desc, "Contains", &BridgeComponent::Contains ); - AddFunctionToInterface( desc, "GetAccessibleAtPoint", &BridgeComponent::GetAccessibleAtPoint ); - AddFunctionToInterface( desc, "GetExtents", &BridgeComponent::GetExtents ); - AddFunctionToInterface( desc, "GetPosition", &BridgeComponent::GetPosition ); - AddFunctionToInterface( desc, "GetSize", &BridgeComponent::GetSize ); - AddFunctionToInterface( desc, "GetLayer", &BridgeComponent::GetLayer ); - AddFunctionToInterface( desc, "GetAlpha", &BridgeComponent::GetAlpha ); - AddFunctionToInterface( desc, "GrabHighlight", &BridgeComponent::GrabHighlight ); - AddFunctionToInterface( desc, "ClearHighlight", &BridgeComponent::ClearHighlight ); - dbusServer.addInterface( "/", desc, true ); -} - -Component* BridgeComponent::FindSelf() const -{ - auto s = BridgeBase::FindSelf(); - assert( s ); - auto s2 = dynamic_cast< Component* >( s ); - if( !s2 ) - throw AccessibleError{"object " + s->GetAddress().ToString() + " doesn't have Component interface"}; - return s2; -} - -DBus::ValueOrError< bool > BridgeComponent::Contains( int32_t x, int32_t y, uint32_t coordType ) -{ - return FindSelf()->Contains( {x, y}, static_cast< CoordType >( coordType ) ); -} -DBus::ValueOrError< Accessible* > BridgeComponent::GetAccessibleAtPoint( int32_t x, int32_t y, uint32_t coordType ) -{ - return FindSelf()->GetAccessibleAtPoint( {x, y}, static_cast< CoordType >( coordType ) ); -} -DBus::ValueOrError< std::tuple< int32_t, int32_t, int32_t, int32_t > > BridgeComponent::GetExtents( uint32_t coordType ) -{ - auto p = FindSelf()->GetExtents( static_cast< CoordType >( coordType ) ); - return std::tuple< int32_t, int32_t, int32_t, int32_t >{p.position.x, p.position.y, p.size.width, p.size.height}; -} -DBus::ValueOrError< int32_t, int32_t > BridgeComponent::GetPosition( uint32_t coordType ) -{ - auto p = FindSelf()->GetExtents( static_cast< CoordType >( coordType ) ); - return {p.position.x, p.position.y}; -} -DBus::ValueOrError< int32_t, int32_t > BridgeComponent::GetSize( uint32_t coordType ) -{ - auto p = FindSelf()->GetExtents( static_cast< CoordType >( coordType ) ); - return {p.size.width, p.size.height}; -} -DBus::ValueOrError< ComponentLayer > BridgeComponent::GetLayer() -{ - return FindSelf()->GetLayer(); -} -DBus::ValueOrError< double > BridgeComponent::GetAlpha() -{ - return FindSelf()->GetAlpha(); -} -DBus::ValueOrError< bool > BridgeComponent::GrabHighlight() -{ - return FindSelf()->GrabHighlight(); -} -DBus::ValueOrError< bool > BridgeComponent::ClearHighlight() -{ - return FindSelf()->ClearHighlight(); -} diff --git a/dali/dali-bridge/src/BridgeComponent.hpp b/dali/dali-bridge/src/BridgeComponent.hpp deleted file mode 100644 index 8a2a5d4..0000000 --- a/dali/dali-bridge/src/BridgeComponent.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef BRIDGE_COMPONENT_HPP -#define BRIDGE_COMPONENT_HPP - -#include "BridgeBase.hpp" -#include -#include -#include -#include -#include - -class BridgeComponent : public virtual BridgeBase -{ -protected: - BridgeComponent(); - - void RegisterInterfaces(); - - Dali::Accessibility::Component* FindSelf() const; - -public: - DBus::ValueOrError< bool > Contains( int32_t x, int32_t y, uint32_t coordType ); - DBus::ValueOrError< Dali::Accessibility::Accessible* > GetAccessibleAtPoint( int32_t x, int32_t y, uint32_t coordType ); - DBus::ValueOrError< std::tuple< int32_t, int32_t, int32_t, int32_t > > GetExtents( uint32_t coordType ); - DBus::ValueOrError< int32_t, int32_t > GetPosition( uint32_t coordType ); - DBus::ValueOrError< int32_t, int32_t > GetSize( uint32_t coordType ); - DBus::ValueOrError< Dali::Accessibility::ComponentLayer > GetLayer(); - DBus::ValueOrError< double > GetAlpha(); - DBus::ValueOrError< bool > GrabHighlight(); - DBus::ValueOrError< bool > ClearHighlight(); -}; - -#endif diff --git a/dali/dali-bridge/src/BridgeEditableText.cpp b/dali/dali-bridge/src/BridgeEditableText.cpp deleted file mode 100644 index 4c3e5e9..0000000 --- a/dali/dali-bridge/src/BridgeEditableText.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "BridgeEditableText.hpp" - -#include -#include - -using namespace Dali::Accessibility; - -void BridgeEditableText::RegisterInterfaces() -{ - DBus::DBusInterfaceDescription desc{ATSPI_DBUS_INTERFACE_EDITABLE_TEXT}; - AddFunctionToInterface( desc, "CopyText", &BridgeEditableText::CopyText ); - AddFunctionToInterface( desc, "CutText", &BridgeEditableText::CutText ); - AddFunctionToInterface( desc, "PasteText", &BridgeEditableText::PasteText ); - dbusServer.addInterface( "/", desc, true ); -} - -EditableText* BridgeEditableText::FindSelf() const -{ - auto s = BridgeBase::FindSelf(); - assert( s ); - auto s2 = dynamic_cast< EditableText* >( s ); - if( !s2 ) - throw AccessibleError{"object " + s->GetAddress().ToString() + " doesn't have Text interface"}; - return s2; -} - -DBus::ValueOrError< bool > BridgeEditableText::CopyText( int32_t startPos, int32_t endPos ) -{ - return FindSelf()->CopyText( startPos, endPos ); -} - -DBus::ValueOrError< bool > BridgeEditableText::CutText( int32_t startPos, int32_t endPos ) -{ - return FindSelf()->CutText( startPos, endPos ); -} - -DBus::ValueOrError< bool > BridgeEditableText::PasteText( int32_t pos ) -{ - auto imfManager = Dali::Internal::Adaptor::ImfManager::Get(); - imfManager.SetCursorPosition( pos ); - auto clipboard = Dali::Internal::Adaptor::Clipboard::Get(); - clipboard.RequestItem(); - - return true; -} diff --git a/dali/dali-bridge/src/BridgeEditableText.hpp b/dali/dali-bridge/src/BridgeEditableText.hpp deleted file mode 100644 index 37008a4..0000000 --- a/dali/dali-bridge/src/BridgeEditableText.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef BRIDGE_EDITABLE_TEXT_HPP -#define BRIDGE_EDITABLE_TEXT_HPP - -#include "BridgeBase.hpp" - -class BridgeEditableText : public virtual BridgeBase -{ -protected: - BridgeEditableText() = default; - - void RegisterInterfaces(); - - Dali::Accessibility::EditableText* FindSelf() const; - -public: - DBus::ValueOrError< bool > CopyText( int32_t startPos, int32_t endPos ); - DBus::ValueOrError< bool > CutText( int32_t startPos, int32_t endPos ); - DBus::ValueOrError< bool > PasteText( int32_t pos ); -}; - -#endif diff --git a/dali/dali-bridge/src/BridgeImpl.cpp b/dali/dali-bridge/src/BridgeImpl.cpp deleted file mode 100644 index 6ad9a1b..0000000 --- a/dali/dali-bridge/src/BridgeImpl.cpp +++ /dev/null @@ -1,160 +0,0 @@ -#include "BridgeImpl.hpp" -#include "BridgeAccessible.hpp" -#include "BridgeAction.hpp" -#include "BridgeCollection.hpp" -#include "BridgeComponent.hpp" -#include "BridgeObject.hpp" -#include "BridgeValue.hpp" -#include "DBus.hpp" -#include - -#include - -using namespace Dali::Accessibility; - -class BridgeImpl : public virtual BridgeBase, public BridgeAccessible, public BridgeObject, public BridgeComponent, public BridgeCollection, public BridgeAction, public BridgeValue -{ - DBus::DBusClient listenOnAtspiEnabledSignalClient; - DBus::DBusClient registryClient; - Accessible* currentWindow = nullptr; - bool screenReaderEnabled = false, isEnabled = false; - -public: - BridgeImpl() - { - DBus::setDebugPrinter( []( const char* buf, size_t len ) { - std::string s{buf, len}; - Dali::Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo, "%s", s.c_str() ); - } ); - } - - Consumed Emit( KeyEventType type, unsigned int keyCode, const std::string& keyName, unsigned int timeStamp, bool isText ) override - { - unsigned int evType = 0; - - switch( type ) - { - case KeyEventType::KeyPressed: - evType = 0; - { - break; - } - case KeyEventType::KeyReleased: - evType = 1; - { - break; - } - default: - { - return Consumed::No; - } - } - auto m = registryClient.method< bool( std::tuple< uint32_t, int32_t, int32_t, int32_t, int32_t, std::string, bool > ) >( "NotifyListenersSync" ); - 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} ); - if( !result ) - { - LOG() << result.getError().message; - return Consumed::No; - } - return std::get< 0 >( result ) ? Consumed::Yes : Consumed::No; - } - - void ForceDown() override - { - ApplicationHidden(); - BridgeAccessible::ForceDown(); - registryClient = {}; - } - - ForceUpResult ForceUp() override - { - if( BridgeAccessible::ForceUp() == ForceUpResult::alreadyUp ) - return ForceUpResult::alreadyUp; - - BridgeObject::RegisterInterfaces(); - BridgeAccessible::RegisterInterfaces(); - BridgeComponent::RegisterInterfaces(); - BridgeCollection::RegisterInterfaces(); - BridgeAction::RegisterInterfaces(); - BridgeValue::RegisterInterfaces(); - - RegisterOnBridge( &application ); - - registryClient = {ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_DEC, ATSPI_DBUS_INTERFACE_DEC, con}; - auto proxy = DBus::DBusClient{ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_ROOT, ATSPI_DBUS_INTERFACE_SOCKET, con}; - Address root{ - data->busName, "root"}; - auto res = proxy.method< Address( Address ) >( "Embed" ).call( root ); - assert( res ); - application.parent.SetAddress( std::move( std::get< 0 >( res ) ) ); - ApplicationShown(); - return ForceUpResult::justStarted; - } - - void ApplicationHidden() override - { - if( currentWindow ) - { - currentWindow->Emit( WindowEvent::Deactivate, 0 ); - currentWindow = nullptr; - } - } - void ApplicationShown() override - { - auto win = application.getActiveWindow(); - if( win && win != currentWindow ) - { - currentWindow = win; - win->Emit( WindowEvent::Activate, 0 ); - } - } - void Initialize() override - { - auto req = DBus::DBusClient{A11Y_DBUS_NAME, A11Y_DBUS_PATH, A11Y_DBUS_STATUS_INTERFACE, DBus::ConnectionType::SESSION}; - auto p = req.property< bool >( "ScreenReaderEnabled" ).get(); - if( p ) - screenReaderEnabled = std::get< 0 >( p ); - p = req.property< bool >( "IsEnabled" ).get(); - if( p ) - isEnabled = std::get< 0 >( p ); - if( screenReaderEnabled || isEnabled ) - ForceUp(); - } - static std::shared_ptr< Bridge > Create() - { - auto ptr = std::make_shared< BridgeImpl >(); - ptr->MakePublic( Bridge::Visibility::allThreads ); - ptr->listenOnAtspiEnabledSignalClient = DBus::DBusClient{A11Y_DBUS_NAME, A11Y_DBUS_PATH, A11Y_DBUS_STATUS_INTERFACE, - DBus::ConnectionType::SESSION}; - { - auto p = ptr.get(); - ptr->listenOnAtspiEnabledSignalClient.addPropertyChangedEvent< bool >( "ScreenReaderEnabled", [p]( bool res ) { - p->screenReaderEnabled = res; - if( p->screenReaderEnabled || p->isEnabled ) - p->ForceUp(); - else - p->ForceDown(); - } ); - ptr->listenOnAtspiEnabledSignalClient.addPropertyChangedEvent< bool >( "IsEnabled", [p]( bool res ) { - p->isEnabled = res; - if( p->screenReaderEnabled || p->isEnabled ) - p->ForceUp(); - else - p->ForceDown(); - } ); - } - return ptr; - } -}; - -std::shared_ptr< Bridge > Dali::Accessibility::CreateBridge() -{ - try - { - return BridgeImpl::Create(); - } - catch( AccessibleError& e ) - { - return {}; - } -} diff --git a/dali/dali-bridge/src/BridgeImpl.hpp b/dali/dali-bridge/src/BridgeImpl.hpp deleted file mode 100644 index e068478..0000000 --- a/dali/dali-bridge/src/BridgeImpl.hpp +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef BRIDGE_IMPL_HPP -#define BRIDGE_IMPL_HPP - -#endif diff --git a/dali/dali-bridge/src/BridgeObject.cpp b/dali/dali-bridge/src/BridgeObject.cpp deleted file mode 100644 index f28dcbe..0000000 --- a/dali/dali-bridge/src/BridgeObject.cpp +++ /dev/null @@ -1,401 +0,0 @@ -#include "BridgeObject.hpp" -#include -#include - -using namespace Dali::Accessibility; - -BridgeObject::BridgeObject() -{ -} - -void BridgeObject::RegisterInterfaces() -{ - // DBus::DBusInterfaceDescription desc{ ATSPI_DBUS_INTERFACE_EVENT_OBJECT }; - // stateChanged = addSignal, Accessible*>(desc, "StateChanged"); - // dbusServer.addInterface("/", desc, true); -} - -void BridgeObject::Emit( Accessible* obj, WindowEvent we, unsigned int detail1 ) -{ - const char* name = nullptr; - switch( we ) - { - case WindowEvent::PropertyChange: - { - name = "PropertyChange"; - break; - } - case WindowEvent::Minimize: - { - name = "Minimize"; - break; - } - case WindowEvent::Maximize: - { - name = "Maximize"; - break; - } - case WindowEvent::Restore: - { - name = "Restore"; - break; - } - case WindowEvent::Close: - { - name = "Close"; - break; - } - case WindowEvent::Create: - { - name = "Create"; - break; - } - case WindowEvent::Reparent: - { - name = "Reparent"; - break; - } - case WindowEvent::DesktopCreate: - { - name = "DesktopCreate"; - break; - } - case WindowEvent::DesktopDestroy: - { - name = "DesktopDestroy"; - break; - } - case WindowEvent::Destroy: - { - name = "Destroy"; - break; - } - case WindowEvent::Activate: - { - name = "Activate"; - break; - } - case WindowEvent::Deactivate: - { - name = "Deactivate"; - break; - } - case WindowEvent::Raise: - { - name = "Raise"; - break; - } - case WindowEvent::Lower: - { - name = "Lower"; - break; - } - case WindowEvent::Move: - { - name = "Move"; - break; - } - case WindowEvent::Resize: - { - name = "Resize"; - break; - } - case WindowEvent::Shade: - { - name = "Shade"; - break; - } - case WindowEvent::UuShade: - { - name = "uUshade"; - break; - } - case WindowEvent::Restyle: - { - name = "Restyle"; - break; - } - } - if( name ) - { - auto addr = obj->GetAddress(); - const auto prefixPath = "/org/a11y/atspi/accessible/"; - const auto nullPath = "/org/a11y/atspi/null"; - std::string p; - if( addr ) - p = prefixPath + addr.GetPath(); - else - p = nullPath; - dbusServer.emit2< std::string, int, int, DBus::EldbusVariant< int >, Address >( - p, - ATSPI_DBUS_INTERFACE_EVENT_WINDOW, - name, - "", - detail1, - 0, - {0}, - {GetBusName(), "root"} ); - } -} - -void BridgeObject::EmitStateChanged( Accessible* obj, State state, int newValue1, int newValue2 ) -{ - const char* stateName = nullptr; - switch( state ) - { - case State::Invalid: - { - stateName = "invalid"; - break; - } - case State::Active: - { - stateName = "active"; - break; - } - case State::Armed: - { - stateName = "armed"; - break; - } - case State::Busy: - { - stateName = "busy"; - break; - } - case State::Checked: - { - stateName = "checked"; - break; - } - case State::Collapsed: - { - stateName = "collapsed"; - break; - } - case State::Defunct: - { - stateName = "defunct"; - break; - } - case State::Editable: - { - stateName = "editable"; - break; - } - case State::Enabled: - { - stateName = "enabled"; - break; - } - case State::Expandable: - { - stateName = "expandable"; - break; - } - case State::Expanded: - { - stateName = "expanded"; - break; - } - case State::Focusable: - { - stateName = "focusable"; - break; - } - case State::Focused: - { - stateName = "focused"; - break; - } - case State::HasTooltip: - { - stateName = "has-tooltip"; - break; - } - case State::Horizontal: - { - stateName = "horizontal"; - break; - } - case State::Iconified: - { - stateName = "iconified"; - break; - } - case State::Modal: - { - stateName = "modal"; - break; - } - case State::MultiLine: - { - stateName = "multi-line"; - break; - } - case State::MultiSelectable: - { - stateName = "multiselectable"; - break; - } - case State::Opaque: - { - stateName = "opaque"; - break; - } - case State::Pressed: - { - stateName = "pressed"; - break; - } - case State::Resizeable: - { - stateName = "resizable"; - break; - } - case State::Selectable: - { - stateName = "selectable"; - break; - } - case State::Selected: - { - stateName = "selected"; - break; - } - case State::Sensitive: - { - stateName = "sensitive"; - break; - } - case State::Showing: - { - stateName = "showing"; - break; - } - case State::SingleLine: - { - stateName = "single-line"; - break; - } - case State::Stale: - { - stateName = "stale"; - break; - } - case State::Transient: - { - stateName = "transient"; - break; - } - case State::Vertical: - { - stateName = "vertical"; - break; - } - case State::Visible: - { - stateName = "visible"; - break; - } - case State::ManagesDescendants: - { - stateName = "manages-descendants"; - break; - } - case State::Indeterminate: - { - stateName = "indeterminate"; - break; - } - case State::Required: - { - stateName = "required"; - break; - } - case State::Truncated: - { - stateName = "truncated"; - break; - } - case State::Animated: - { - stateName = "animated"; - break; - } - case State::InvalidEntry: - { - stateName = "invalid-entry"; - break; - } - case State::SupportsAutocompletion: - { - stateName = "supports-autocompletion"; - break; - } - case State::SelectableText: - { - stateName = "selectable-text"; - break; - } - case State::IsDefault: - { - stateName = "is-default"; - break; - } - case State::Visited: - { - stateName = "visited"; - break; - } - case State::Checkable: - { - stateName = "checkable"; - break; - } - case State::HasPopup: - { - stateName = "has-popup"; - break; - } - case State::ReadOnly: - { - stateName = "read-only"; - break; - } - case State::Highlighted: - { - stateName = "highlighted"; - break; - } - case State::Highlightable: - { - stateName = "highlightable"; - break; - } - case State::_Count: - { - break; - } - } - if( stateName ) - { - auto addr = obj->GetAddress(); - const auto prefixPath = "/org/a11y/atspi/accessible/"; - const auto nullPath = "/org/a11y/atspi/null"; - std::string p; - if( addr ) - p = prefixPath + addr.GetPath(); - else - p = nullPath; - dbusServer.emit2< std::string, int, int, DBus::EldbusVariant< int >, Address >( - p, - ATSPI_DBUS_INTERFACE_EVENT_OBJECT, - "StateChanged", - stateName, - newValue1, - newValue2, - {0}, - {GetBusName(), "root"} ); - } -} diff --git a/dali/dali-bridge/src/BridgeObject.hpp b/dali/dali-bridge/src/BridgeObject.hpp deleted file mode 100644 index af496d1..0000000 --- a/dali/dali-bridge/src/BridgeObject.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef BRIDGE_OBJECT_HPP -#define BRIDGE_OBJECT_HPP - -#include "BridgeBase.hpp" -#include -#include -#include -#include - -class BridgeObject : public virtual BridgeBase -{ -protected: - BridgeObject(); - - void RegisterInterfaces(); - - DBus::DBusInterfaceDescription::SignalId stateChanged; - - void EmitStateChanged( Dali::Accessibility::Accessible* obj, Dali::Accessibility::State state, int val1, int val2 ) override; - void Emit( Dali::Accessibility::Accessible* obj, Dali::Accessibility::WindowEvent we, unsigned int detail1 ) override; - -public: - int GetChildCount(); - DBus::ValueOrError< Dali::Accessibility::Accessible* > GetChildAtIndex( int index ); - Dali::Accessibility::Accessible* GetParent(); - DBus::ValueOrError< std::vector< Dali::Accessibility::Accessible* > > GetChildren(); - std::string GetName(); - std::string GetDescription(); - DBus::ValueOrError< uint32_t > GetRole(); - DBus::ValueOrError< std::string > GetRoleName(); - DBus::ValueOrError< std::string > GetLocalizedRoleName(); - DBus::ValueOrError< int32_t > GetIndexInParent(); - DBus::ValueOrError< std::array< uint32_t, 2 > > GetStates(); - DBus::ValueOrError< std::unordered_map< std::string, std::string > > GetAttributes(); - DBus::ValueOrError< std::vector< std::string > > GetInterfaces(); -}; - -#endif \ No newline at end of file diff --git a/dali/dali-bridge/src/BridgeText.cpp b/dali/dali-bridge/src/BridgeText.cpp deleted file mode 100644 index 651b981..0000000 --- a/dali/dali-bridge/src/BridgeText.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "BridgeText.hpp" - -#include - -using namespace Dali::Accessibility; - -void BridgeText::RegisterInterfaces() -{ - DBus::DBusInterfaceDescription desc{ATSPI_DBUS_INTERFACE_TEXT}; - AddFunctionToInterface( desc, "GetText", &BridgeText::GetText ); - AddGetPropertyToInterface( desc, "CharacterCount", &BridgeText::GetCharacterCount ); - AddGetPropertyToInterface( desc, "CaretOffset", &BridgeText::GetCaretOffset ); - AddFunctionToInterface( desc, "SetCaretOffset", &BridgeText::SetCaretOffset ); - AddFunctionToInterface( desc, "GetTextAtOffset", &BridgeText::GetTextAtOffset ); - AddFunctionToInterface( desc, "GetSelection", &BridgeText::GetSelection ); - AddFunctionToInterface( desc, "SetSelection", &BridgeText::SetSelection ); - AddFunctionToInterface( desc, "RemoveSelection", &BridgeText::RemoveSelection ); - dbusServer.addInterface( "/", desc, true ); -} - -Text* BridgeText::FindSelf() const -{ - auto s = BridgeBase::FindSelf(); - assert( s ); - auto s2 = dynamic_cast< Text* >( s ); - if( !s2 ) - throw AccessibleError{"object " + s->GetAddress().ToString() + " doesn't have Text interface"}; - return s2; -} - -DBus::ValueOrError< std::string > BridgeText::GetText( int startOffset, int endOffset ) -{ - return FindSelf()->GetText( startOffset, endOffset ); -} - -DBus::ValueOrError< int32_t > BridgeText::GetCharacterCount() -{ - return FindSelf()->GetCharacterCount(); -} - -DBus::ValueOrError< int32_t > BridgeText::GetCaretOffset() -{ - auto imfManager = Dali::Internal::Adaptor::ImfManager::Get(); - return imfManager.GetCursorPosition(); -} - -DBus::ValueOrError< bool > BridgeText::SetCaretOffset( int32_t offset ) -{ - auto imfManager = Dali::Internal::Adaptor::ImfManager::Get(); - imfManager.SetCursorPosition( offset ); - return true; -} - -DBus::ValueOrError< std::string, int, int > BridgeText::GetTextAtOffset( int32_t offset, uint32_t boundary ) -{ - auto r = FindSelf()->GetTextAtOffset( offset, static_cast< TextBoundary >( boundary ) ); - return {r.content, static_cast< int >( r.startOffset ), static_cast< int >( r.endOffset )}; -} - -DBus::ValueOrError< int, int > BridgeText::GetSelection( int32_t selectionNum ) -{ - auto r = FindSelf()->GetSelection( selectionNum ); - return {static_cast< int >( r.startOffset ), static_cast< int >( r.endOffset )}; -} - -DBus::ValueOrError< bool > BridgeText::RemoveSelection( int32_t selectionNum ) -{ - return FindSelf()->RemoveSelection( selectionNum ); -} - -DBus::ValueOrError< bool > BridgeText::SetSelection( int32_t selectionNum, int32_t startOffset, int32_t endOffset ) -{ - return FindSelf()->SetSelection( selectionNum, startOffset, endOffset ); -} diff --git a/dali/dali-bridge/src/BridgeText.hpp b/dali/dali-bridge/src/BridgeText.hpp deleted file mode 100644 index fdb0894..0000000 --- a/dali/dali-bridge/src/BridgeText.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef BRIDGE_TEXT_HPP -#define BRIDGE_TEXT_HPP - -#include "BridgeBase.hpp" - -class BridgeText : public virtual BridgeBase -{ -protected: - BridgeText() = default; - - void RegisterInterfaces(); - - Dali::Accessibility::Text* FindSelf() const; - -public: - DBus::ValueOrError< std::string > GetText( int startOffset, int endOffset ); - DBus::ValueOrError< int32_t > GetCharacterCount(); - DBus::ValueOrError< int32_t > GetCaretOffset(); - DBus::ValueOrError< bool > SetCaretOffset( int32_t offset ); - DBus::ValueOrError< std::string, int, int > GetTextAtOffset( int32_t offset, uint32_t boundary ); - DBus::ValueOrError< int, int > GetSelection( int32_t selectionNum ); - DBus::ValueOrError< bool > RemoveSelection( int32_t selectionNum ); - DBus::ValueOrError< bool > SetSelection( int32_t selectionNum, int32_t startOffset, int32_t endOffset ); -}; - -#endif diff --git a/dali/dali-bridge/src/BridgeValue.cpp b/dali/dali-bridge/src/BridgeValue.cpp deleted file mode 100644 index 7c158b6..0000000 --- a/dali/dali-bridge/src/BridgeValue.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "BridgeValue.hpp" -#include - -using namespace Dali::Accessibility; - -BridgeValue::BridgeValue() -{ -} - -void BridgeValue::RegisterInterfaces() -{ - DBus::DBusInterfaceDescription desc{ATSPI_DBUS_INTERFACE_VALUE}; - AddGetSetPropertyToInterface( desc, "CurrentValue", &BridgeValue::GetCurrentValue, &BridgeValue::SetCurrentValue ); - AddGetPropertyToInterface( desc, "MaximumValue", &BridgeValue::GetMaximumValue ); - AddGetPropertyToInterface( desc, "MinimumIncrement", &BridgeValue::GetMinimumIncrement ); - AddGetPropertyToInterface( desc, "MinimumValue", &BridgeValue::GetMinimumValue ); - dbusServer.addInterface( "/", desc, true ); -} - -Value* BridgeValue::FindSelf() const -{ - auto s = BridgeBase::FindSelf(); - assert( s ); - auto s2 = dynamic_cast< Value* >( s ); - if( !s2 ) - throw AccessibleError{"object " + s->GetAddress().ToString() + " doesn't have Value interface"}; - return s2; -} -double BridgeValue::GetCurrentValue() -{ - return FindSelf()->GetCurrent(); -} -void BridgeValue::SetCurrentValue( double new_value ) -{ - FindSelf()->SetCurrent( new_value ); -} -double BridgeValue::GetMaximumValue() -{ - return FindSelf()->GetMaximum(); -} -double BridgeValue::GetMinimumIncrement() -{ - return FindSelf()->GetMinimumIncrement(); -} -double BridgeValue::GetMinimumValue() -{ - return FindSelf()->GetMinimum(); -} diff --git a/dali/dali-bridge/src/BridgeValue.hpp b/dali/dali-bridge/src/BridgeValue.hpp deleted file mode 100644 index beb1d86..0000000 --- a/dali/dali-bridge/src/BridgeValue.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef BRIDGE_VALUE_HPP -#define BRIDGE_VALUE_HPP - -#include "BridgeBase.hpp" -#include -#include -#include -#include -#include - -class BridgeValue : public virtual BridgeBase -{ -protected: - BridgeValue(); - - void RegisterInterfaces(); - - Dali::Accessibility::Value* FindSelf() const; - -public: - double GetCurrentValue(); - void SetCurrentValue( double new_value ); - double GetMaximumValue(); - double GetMinimumIncrement(); - double GetMinimumValue(); -}; - -#endif diff --git a/dali/dali-bridge/src/Common.hpp b/dali/dali-bridge/src/Common.hpp deleted file mode 100755 index acbef6f..0000000 --- a/dali/dali-bridge/src/Common.hpp +++ /dev/null @@ -1,267 +0,0 @@ -#ifndef COMMON_HPP -#define COMMON_HPP - -#include "DBus.hpp" -#include "dbusLocators.hpp" -#include -#include -#include -#include -#include - -#define A11Y_DBUS_NAME "org.a11y.Bus" -#define A11Y_DBUS_PATH "/org/a11y/bus" -#define A11Y_DBUS_STATUS_INTERFACE "org.a11y.Status" -#define ATSPI_DBUS_NAME_REGISTRY "org.a11y.atspi.Registry" -#define ATSPI_DBUS_PATH_ROOT "/org/a11y/atspi/accessible/root" -#define ATSPI_DBUS_INTERFACE_SOCKET "org.a11y.atspi.Socket" -#define ATSPI_PATH "/org/a11y/atspi/accessible" -#define ATSPI_DBUS_INTERFACE_ACCESSIBLE "org.a11y.atspi.Accessible" -#define ATSPI_DBUS_INTERFACE_ACTION "org.a11y.atspi.Action" -#define ATSPI_DBUS_INTERFACE_APPLICATION "org.a11y.atspi.Application" -#define ATSPI_DBUS_INTERFACE_COLLECTION "org.a11y.atspi.Collection" -#define ATSPI_DBUS_INTERFACE_COMPONENT "org.a11y.atspi.Component" -#define ATSPI_DBUS_INTERFACE_DOCUMENT "org.a11y.atspi.Document" -#define ATSPI_DBUS_INTERFACE_EDITABLE_TEXT "org.a11y.atspi.EditableText" -#define ATSPI_DBUS_INTERFACE_EVENT_KEYBOARD "org.a11y.atspi.Event.Keyboard" -#define ATSPI_DBUS_INTERFACE_EVENT_MOUSE "org.a11y.atspi.Event.Mouse" -#define ATSPI_DBUS_INTERFACE_EVENT_OBJECT "org.a11y.atspi.Event.Object" -#define ATSPI_DBUS_INTERFACE_HYPERLINK "org.a11y.atspi.Hyperlink" -#define ATSPI_DBUS_INTERFACE_HYPERTEXT "org.a11y.atspi.Hypertext" -#define ATSPI_DBUS_INTERFACE_IMAGE "org.a11y.atspi.Image" -#define ATSPI_DBUS_INTERFACE_SELECTION "org.a11y.atspi.Selection" -#define ATSPI_DBUS_INTERFACE_TABLE "org.a11y.atspi.Table" -#define ATSPI_DBUS_INTERFACE_TABLE_CELL "org.a11y.atspi.TableCell" -#define ATSPI_DBUS_INTERFACE_TEXT "org.a11y.atspi.Text" -#define ATSPI_DBUS_INTERFACE_VALUE "org.a11y.atspi.Value" -#define ATSPI_DBUS_INTERFACE_SOCKET "org.a11y.atspi.Socket" -#define ATSPI_DBUS_INTERFACE_EVENT_WINDOW "org.a11y.atspi.Event.Window" - -#define ATSPI_DBUS_PATH_DEC "/org/a11y/atspi/registry/deviceeventcontroller" -#define ATSPI_DBUS_INTERFACE_DEC "org.a11y.atspi.DeviceEventController" -#define ATSPI_DBUS_INTERFACE_DEVICE_EVENT_LISTENER "org.a11y.atspi.DeviceEventListener" - -namespace DBus -{ -class CurrentBridgePtr -{ - static Dali::Accessibility::Bridge*& get() - { - static thread_local Dali::Accessibility::Bridge* b = nullptr; - return b; - } - Dali::Accessibility::Bridge* prev; - CurrentBridgePtr( const CurrentBridgePtr& ) = delete; - CurrentBridgePtr( CurrentBridgePtr&& ) = delete; - CurrentBridgePtr& operator=( const CurrentBridgePtr& ) = delete; - CurrentBridgePtr& operator=( CurrentBridgePtr&& ) = delete; - -public: - CurrentBridgePtr( Dali::Accessibility::Bridge* b ) : prev( get() ) { get() = b; } - ~CurrentBridgePtr() { get() = prev; } - - static Dali::Accessibility::Bridge* current() { return get(); } -}; -namespace detail -{ -template < typename T > -struct signature_accessible_impl -{ - using subtype = std::pair< std::string, DBus::ObjectPath >; - - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "AtspiAccessiblePtr"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return "(so)"; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, T* t ) - { - const auto prefixPath = "/org/a11y/atspi/accessible/"; - const auto nullPath = "/org/a11y/atspi/null"; - - if( t ) - { - auto v = t->GetAddress(); - signature< subtype >::set( iter, {v.GetBus(), DBus::ObjectPath{std::string{prefixPath} + v.GetPath()}} ); - } - else - { - signature< subtype >::set( iter, {"", DBus::ObjectPath{nullPath}} ); - } - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, T*& v ) - { - const auto prefixPath = "/org/a11y/atspi/accessible/"; - const auto nullPath = "/org/a11y/atspi/null"; - subtype tmp; - if( !signature< subtype >::get( iter, tmp ) ) - return false; - if( tmp.second.value == nullPath ) - { - v = nullptr; - return true; - } - if( tmp.second.value.substr( 0, strlen( prefixPath ) ) != prefixPath ) - return false; - auto b = CurrentBridgePtr::current(); - if( b->GetBusName() != tmp.first ) - return false; - v = b->FindByPath( tmp.second.value.substr( strlen( prefixPath ) ) ); - return v != nullptr; - } -}; -template <> -struct signature< Dali::Accessibility::Accessible* > : public signature_accessible_impl< Dali::Accessibility::Accessible > -{ -}; - -template <> -struct signature< Dali::Accessibility::Address > -{ - using subtype = std::pair< std::string, DBus::ObjectPath >; - - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "AtspiAccessiblePtr"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return "(so)"; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const Dali::Accessibility::Address& v ) - { - const auto prefixPath = "/org/a11y/atspi/accessible/"; - const auto nullPath = "/org/a11y/atspi/null"; - - if( v ) - { - signature< subtype >::set( iter, {v.GetBus(), DBus::ObjectPath{std::string{prefixPath} + v.GetPath()}} ); - } - else - { - signature< subtype >::set( iter, {v.GetBus(), DBus::ObjectPath{nullPath}} ); - } - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, Dali::Accessibility::Address& v ) - { - const auto prefixPath = "/org/a11y/atspi/accessible/"; - const auto nullPath = "/org/a11y/atspi/null"; - subtype tmp; - if( !signature< subtype >::get( iter, tmp ) ) - return false; - if( tmp.second.value == nullPath ) - { - v = {}; - return true; - } - if( tmp.second.value.substr( 0, strlen( prefixPath ) ) != prefixPath ) - return false; - v = {std::move( tmp.first ), tmp.second.value.substr( strlen( prefixPath ) )}; - return true; - } -}; -template <> -struct signature< Dali::Accessibility::States > -{ - using subtype = std::array< uint32_t, 2 >; - - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return signature< subtype >::name(); - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return signature< subtype >::sig(); - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const Dali::Accessibility::States& v ) - { - signature< subtype >::set( iter, v.GetRawData() ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, Dali::Accessibility::States& v ) - { - subtype tmp; - if( !signature< subtype >::get( iter, tmp ) ) - return false; - v = Dali::Accessibility::States{tmp}; - return true; - } -}; -} -} - -struct _Logger -{ - const char* file; - int line; - std::ostringstream tmp; - - _Logger( const char* f, int l ) : file( f ), line( l ) {} - ~_Logger() - { - Dali::Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo, "%s:%d: %s", file, line, tmp.str().c_str() ); - } - template < typename T > - _Logger& operator<<( T&& t ) - { - tmp << std::forward< T >( t ); - return *this; - } -}; - -struct _LoggerScope -{ - const char* file; - int line; - - _LoggerScope( const char* f, int l ) : file( f ), line( l ) - { - Dali::Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo, "%s:%d: +", file, line ); - } - ~_LoggerScope() - { - Dali::Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo, "%s:%d: -", file, line ); - } -}; -#define LOG() _Logger( __FILE__, __LINE__ ) -#define SCOPE() _LoggerScope _l##__LINE__( __FILE__, __LINE__ ) - -#endif diff --git a/dali/dali-bridge/src/Component.cpp b/dali/dali-bridge/src/Component.cpp deleted file mode 100644 index 8085569..0000000 --- a/dali/dali-bridge/src/Component.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "Common.hpp" -#include - -using namespace Dali::Accessibility; - -bool Component::Contains( Point p, CoordType ctype ) -{ - auto extents = GetExtents( ctype ); - return p.x >= extents.position.x && p.y >= extents.position.y && p.x <= extents.position.x + extents.size.width && p.y <= extents.position.y + extents.size.height; -} - -Component* Component::GetAccessibleAtPoint( Point p, CoordType ctype ) -{ - auto children = GetChildren(); - for( auto childIt = children.rbegin(); childIt != children.rend(); childIt++ ) - { - auto component = dynamic_cast< Component* >( *childIt ); - if( component && component->Contains( p, ctype ) ) - { - return component; - } - } - return nullptr; -} - -bool Component::IsScrollable() -{ - return false; -} diff --git a/dali/dali-bridge/src/DBus.cpp b/dali/dali-bridge/src/DBus.cpp deleted file mode 100644 index f8af9bc..0000000 --- a/dali/dali-bridge/src/DBus.cpp +++ /dev/null @@ -1,490 +0,0 @@ -/* - * Copyright 2017 Samsung Electronics Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "DBus.hpp" -#include -//#include "Atspi.hpp" -#include -#include - -#define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties" - -#undef EINA_FALSE -#undef EINA_TRUE -#define EINA_TRUE static_cast< Eina_Bool >( 1 ) -#define EINA_FALSE static_cast< Eina_Bool >( 0 ) - -//#define DBUS_DEBUG(...) do { DBus::debugPrint(__FILE__, __LINE__, __VA_ARGS__); } while (0) - -std::atomic< unsigned int > DBus::detail::CallId::LastId{0}; -static std::function< void( const char*, size_t ) > debugPrinter; -static std::function< void( DBus::DBusAction ) > notificationCallback; -static std::mutex debugLock, notificationLock; - -DBus::detail::CallOnDestructionList& DBus::detail::CallOnDestructionList::operator=( DBus::detail::CallOnDestructionList&& d ) -{ - for( auto& q : functions ) - { - q(); - } - functions = std::move( d.functions ); - d.functions.clear(); - return *this; -} - -void DBus::detail::CallOnDestructionList::add( const std::function< void() >& c ) -{ - functions.push_back( c ); -} - -void DBus::setDBusActionNotifier( std::function< void( DBus::DBusAction ) > callback ) -{ - std::lock_guard< std::mutex > lock( notificationLock ); - notificationCallback = std::move( callback ); -} - -void DBus::detail::emitNotification( const char* bus, const char* path, const char* interface, const char* member, DBus::DBusActionType type ) -{ - std::lock_guard< std::mutex > lock( notificationLock ); - if( notificationCallback ) - { - notificationCallback( DBusAction{type, bus, path, interface, member} ); - } -} - -void DBus::setDebugPrinter( std::function< void( const char*, size_t ) > printer ) -{ - std::lock_guard< std::mutex > lock( debugLock ); - debugPrinter = std::move( printer ); -} - -void DBus::debugPrint( const char* file, size_t line, const char* format, ... ) -{ - std::function< void( const char*, size_t ) > debugPrintFunc; - { - std::lock_guard< std::mutex > lock( debugLock ); - if( !debugPrinter ) - return; - debugPrintFunc = debugPrinter; - } - std::vector< char > buf( 4096 ); - int offset; - while( true ) - { - offset = snprintf( buf.data(), buf.size(), "%s:%u: ", file, static_cast< unsigned int >( line ) ); - if( offset < 0 ) - return; - if( static_cast< size_t >( offset ) < buf.size() ) - break; - buf.resize( offset + 1 ); - } - - while( true ) - { - va_list args; - va_start( args, format ); - int z = vsnprintf( buf.data() + offset, buf.size() - offset, format, args ); - va_end( args ); - if( z < 0 ) - return; - bool done = static_cast< size_t >( z ) + static_cast< size_t >( offset ) < buf.size(); - buf.resize( static_cast< size_t >( z ) + static_cast< size_t >( offset ) ); - if( done ) - break; - } - debugPrintFunc( buf.data(), buf.size() ); -} - -std::shared_ptr< DBus::EldbusConnection > DBus::getDBusConnectionByName( const std::string& name ) -{ - eldbus_init(); - auto z = getDBusConnectionByType( ConnectionType::SYSTEM ); - auto connection = eldbus_address_connection_get( name.c_str() ); - auto ptr = std::make_shared< EldbusConnection >( connection ); - eldbus_shutdown(); - return ptr; -} - -std::shared_ptr< DBus::EldbusConnection > DBus::getDBusConnectionByType( ConnectionType connectionType ) -{ - Eldbus_Connection_Type eldbusType = ELDBUS_CONNECTION_TYPE_SYSTEM; - - switch( connectionType ) - { - case ConnectionType::SYSTEM: - { - eldbusType = ELDBUS_CONNECTION_TYPE_SYSTEM; - break; - } - case ConnectionType::SESSION: - { - eldbusType = ELDBUS_CONNECTION_TYPE_SESSION; - break; - } - } - - eldbus_init(); - auto connection = eldbus_connection_get( eldbusType ); - auto ptr = std::make_shared< EldbusConnection >( connection ); - eldbus_shutdown(); - return ptr; -} - -DBus::DBusClient::DBusClient( std::string busName, std::string pathName, std::string interfaceName, ConnectionType tp ) : DBusClient( std::move( busName ), std::move( pathName ), std::move( interfaceName ), getDBusConnectionByType( tp ) ) -{ -} - -struct caller_eldbus_object_unref -{ - void operator()( Eldbus_Object* p ) const - { - eldbus_object_unref( p ); - } -}; - -DBus::DBusClient::DBusClient( std::string busName, std::string pathName, std::string interfaceName, const std::shared_ptr< DBus::EldbusConnection >& conn ) -{ - if( !conn ) - connectionState.connection = getDBusConnectionByType( ConnectionType::SESSION ); - else - connectionState.connection = conn; - - std::ostringstream o; - o << "bus = " << busName << " path = " << pathName << " connection = " << eldbus_connection_unique_name_get( connectionState.connection->get() ); - info = o.str(); - - auto c = connectionState.connection; - connectionState.object = { - eldbus_object_get( connectionState.connection->get(), busName.c_str(), pathName.c_str() ), - [c]( Eldbus_Object* p ) { - eldbus_object_unref( p ); - }}; - if( connectionState.object ) - { - auto obj = connectionState.object; - connectionState.proxy = { - eldbus_proxy_get( connectionState.object.get(), interfaceName.c_str() ), - [obj]( Eldbus_Proxy* p ) { - eldbus_proxy_unref( p ); - }}; - if( interfaceName != DBUS_INTERFACE_PROPERTIES ) - { - auto obj = connectionState.object; - connectionState.propertiesProxy = { - eldbus_proxy_get( connectionState.object.get(), DBUS_INTERFACE_PROPERTIES ), - [obj]( Eldbus_Proxy* p ) { - eldbus_proxy_unref( p ); - }}; - } - else - { - connectionState.propertiesProxy = connectionState.proxy; - } - } - connectionInfo = std::make_shared< ConnectionInfo >(); - connectionInfo->busName = std::move( busName ); - connectionInfo->pathName = std::move( pathName ); - connectionInfo->interfaceName = std::move( interfaceName ); -} - -DBus::DBusServer::DBusServer( ConnectionType tp ) : DBus::DBusServer( DBus::getDBusConnectionByType( tp ) ) -{ -} - -DBus::DBusServer::DBusServer( const std::shared_ptr< DBus::EldbusConnection >& conn ) -{ - if( !conn ) - connection = getDBusConnectionByType( ConnectionType::SESSION ); - else - connection = conn; -} - -DBus::DBusInterfaceDescription::DBusInterfaceDescription( std::string interfaceName ) : interfaceName( std::move( interfaceName ) ) -{ -} - -struct Implementation -{ - Eldbus_Service_Interface_Desc dsc; - std::vector< Eldbus_Method > methods; - std::vector< Eldbus_Signal > signals; - std::vector< Eldbus_Property > properties; - DBus::detail::StringStorage strings; - - std::unordered_map< std::string, DBus::DBusInterfaceDescription::MethodInfo > methodsMap; - std::unordered_map< std::string, DBus::DBusInterfaceDescription::PropertyInfo > propertiesMap; - std::unordered_map< unsigned int, DBus::DBusInterfaceDescription::SignalInfo > signalsMap; - - std::shared_ptr< DBus::EldbusConnection > connection; -}; - -static std::unordered_map< const Eldbus_Service_Interface*, std::unique_ptr< Implementation > > globalEntries; -static std::mutex globalEntriesMutex; -static thread_local const char* currentObjectPath = ""; -static thread_local std::shared_ptr< DBus::EldbusConnection > currentConnection; - -class CurrentObjectSetter -{ -public: - CurrentObjectSetter( std::shared_ptr< DBus::EldbusConnection > con, const Eldbus_Message* m ) - { - currentObjectPath = eldbus_message_path_get( m ); - currentConnection = std::move( con ); - } - ~CurrentObjectSetter() - { - currentObjectPath = ""; - currentConnection = {}; - } - CurrentObjectSetter( const CurrentObjectSetter& ) = delete; - CurrentObjectSetter( CurrentObjectSetter&& ) = delete; - void operator=( const CurrentObjectSetter& ) = delete; - void operator=( CurrentObjectSetter&& ) = delete; -}; - -std::string DBus::DBusServer::getCurrentObjectPath() -{ - return currentObjectPath; -} - -std::shared_ptr< DBus::EldbusConnection > DBus::DBusServer::getCurrentConnection() -{ - return currentConnection; -} - -static Eina_Bool property_get_callback( const Eldbus_Service_Interface* iface, const char* propertyName, Eldbus_Message_Iter* iter, - const Eldbus_Message* message, Eldbus_Message** error ) -{ - Implementation* impl = nullptr; - { - std::lock_guard< std::mutex > lock( globalEntriesMutex ); - auto it = globalEntries.find( iface ); - if( it != globalEntries.end() ) - impl = it->second.get(); - } - if( !impl ) - return EINA_FALSE; - - auto it = impl->propertiesMap.find( propertyName ); - if( it == impl->propertiesMap.end() || !it->second.getCallback ) - return EINA_FALSE; - - CurrentObjectSetter currentObjectSetter( impl->connection, message ); - auto reply = it->second.getCallback( message, iter ); - if( !reply ) - { - if( error ) - *error = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", reply.getError().message.c_str() ); - return EINA_FALSE; - } - - return EINA_TRUE; -} - -static Eldbus_Message* property_set_callback( const Eldbus_Service_Interface* iface, const char* propertyName, Eldbus_Message_Iter* iter, - const Eldbus_Message* message ) -{ - Implementation* impl = nullptr; - { - std::lock_guard< std::mutex > lock( globalEntriesMutex ); - auto it = globalEntries.find( iface ); - if( it != globalEntries.end() ) - impl = it->second.get(); - } - if( !impl ) - { - auto ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", "Unknown interface" ); - return ret; - } - auto it = impl->propertiesMap.find( propertyName ); - if( it == impl->propertiesMap.end() || !it->second.setCallback ) - { - auto ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", "Unknown setter" ); - return ret; - } - CurrentObjectSetter currentObjectSetter( impl->connection, message ); - auto reply = it->second.setCallback( message, iter ); - - Eldbus_Message* ret = nullptr; - if( !reply ) - { - ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", reply.getError().message.c_str() ); - } - else - { - ret = eldbus_message_method_return_new( message ); - } - return ret; -} - -static Eldbus_Message* method_callback( const Eldbus_Service_Interface* iface, const Eldbus_Message* message ) -{ - Implementation* impl = nullptr; - { - std::lock_guard< std::mutex > lock( globalEntriesMutex ); - auto it = globalEntries.find( iface ); - if( it != globalEntries.end() ) - impl = it->second.get(); - } - if( !impl ) - { - auto ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", "Unknown interface" ); - return ret; - } - std::string memberName = eldbus_message_member_get( message ); - auto it = impl->methodsMap.find( memberName ); - if( it == impl->methodsMap.end() ) - { - auto ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", "Unknown method" ); - return ret; - } - CurrentObjectSetter currentObjectSetter( impl->connection, message ); - auto reply = it->second.callback( message ); - return reply; -} - -static void addInterfaceImpl( bool fallback, const std::string& pathName, - const std::shared_ptr< DBus::EldbusConnection >& connection, - const std::string& interfaceName, - std::unordered_map< unsigned int, std::pair< const Eldbus_Service_Interface*, unsigned int > >& signalData, - DBus::detail::StringStorage& strings, - std::vector< DBus::DBusInterfaceDescription::MethodInfo >& dscrMethods, - std::vector< DBus::DBusInterfaceDescription::PropertyInfo >& dscrProperties, - std::vector< DBus::DBusInterfaceDescription::SignalInfo >& dscrSignals, - DBus::detail::CallOnDestructionList& destructors ) -{ - std::vector< Eldbus_Method > methods; - std::vector< Eldbus_Signal > signals; - std::vector< Eldbus_Property > properties; - std::unordered_map< std::string, DBus::DBusInterfaceDescription::MethodInfo > methodsMap; - std::unordered_map< std::string, DBus::DBusInterfaceDescription::PropertyInfo > propertiesMap; - std::unordered_map< unsigned int, DBus::DBusInterfaceDescription::SignalInfo > signalsMap; - - DBUS_DEBUG( "interface %s path %s on bus %s", interfaceName.c_str(), pathName.c_str(), DBus::getConnectionName( connection ).c_str() ); - for( auto& ee : dscrMethods ) - { - auto key = ee.memberName; - DBUS_DEBUG( "adding method %s", ee.memberName.c_str() ); - for( auto& r : ee.in ) - { - if( !r.name ) - break; - DBUS_DEBUG( "in %s '%s'", r.name, r.signature ); - } - for( auto& r : ee.out ) - { - if( !r.name ) - break; - DBUS_DEBUG( "out %s '%s'", r.name, r.signature ); - } - auto& e = ( methodsMap[key] = std::move( ee ) ); - methods.push_back( {} ); - auto& m = methods.back(); - m.member = e.memberName.c_str(); - m.in = e.in.data(); - m.out = e.out.data(); - m.cb = method_callback; - m.flags = 0; - } - for( auto& ee : dscrProperties ) - { - auto key = ee.memberName; - DBUS_DEBUG( "adding property %s", ee.memberName.c_str() ); - auto& e = ( propertiesMap[key] = std::move( ee ) ); - properties.push_back( {} ); - auto& m = properties.back(); - m.name = e.memberName.c_str(); - m.type = e.typeSignature.c_str(); - m.get_func = e.getCallback ? property_get_callback : nullptr; - m.set_func = e.setCallback ? property_set_callback : nullptr; - m.flags = 0; - } - unsigned int signalIndex = 0; - std::vector< unsigned int > signalIds; - for( auto& ee : dscrSignals ) - { - DBUS_DEBUG( "adding signal %s", ee.memberName.c_str() ); - auto& e = ( signalsMap[ee.id.id] = std::move( ee ) ); - signals.push_back( {} ); - auto& m = signals.back(); - m.name = e.memberName.c_str(); - m.args = e.args.data(); - m.flags = 0; - signalData[e.id.id].second = signalIndex++; - signalIds.push_back( e.id.id ); - } - dscrMethods.clear(); - dscrProperties.clear(); - dscrSignals.clear(); - - methods.push_back( {nullptr, nullptr, nullptr, nullptr, 0} ); - signals.push_back( {nullptr, nullptr, 0} ); - properties.push_back( {nullptr, nullptr, nullptr, nullptr, 0} ); - - auto impl = std::unique_ptr< Implementation >( new Implementation{ - {interfaceName.c_str(), - methods.data(), - signals.data(), - properties.data(), - nullptr, - nullptr}, - std::move( methods ), - std::move( signals ), - std::move( properties ), - std::move( strings ), - std::move( methodsMap ), - std::move( propertiesMap ), - std::move( signalsMap ), - connection} ); - - { - std::lock_guard< std::mutex > lock( globalEntriesMutex ); - auto v = fallback ? eldbus_service_interface_fallback_register( connection->get(), pathName.c_str(), &impl->dsc ) : eldbus_service_interface_register( connection->get(), pathName.c_str(), &impl->dsc ); - assert( v ); - globalEntries[v] = std::move( impl ); - DBUS_DEBUG( "registering interface %p (%d)", v, fallback ? 1 : 0 ); - destructors.add( [=]() { - eldbus_service_interface_unregister( v ); - std::lock_guard< std::mutex > lock( globalEntriesMutex ); - globalEntries.erase( v ); - DBUS_DEBUG( "unregistering interface %p (%d)", v, fallback ? 1 : 0 ); - } ); - for( auto id : signalIds ) - { - signalData[id].first = v; - } - } -} - -std::shared_ptr< DBus::EldbusConnection > DBus::DBusServer::getConnection() -{ - return connection; -} - -void DBus::DBusServer::addInterface( const std::string& pathName, DBusInterfaceDescription& dscr, bool fallback ) -{ - addInterfaceImpl( fallback, pathName, connection, dscr.interfaceName, signalData, dscr.strings, dscr.methods, dscr.properties, dscr.signals, destructors ); -} - -std::string DBus::DBusServer::getBusName() const -{ - return getConnectionName( connection ); -} - -std::string DBus::getConnectionName( const std::shared_ptr< DBus::EldbusConnection >& c ) -{ - return eldbus_connection_unique_name_get( c->get() ); -} diff --git a/dali/dali-bridge/src/DBus.hpp b/dali/dali-bridge/src/DBus.hpp deleted file mode 100755 index 5e956df..0000000 --- a/dali/dali-bridge/src/DBus.hpp +++ /dev/null @@ -1,3104 +0,0 @@ -/* - * Copyright 2017 Samsung Electronics Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef DBUS_HPP -#define DBUS_HPP - -#include -#include - -#include "Optional.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DBUS_DEBUG( ... ) \ - do \ - { \ - DBus::debugPrint( __FILE__, __LINE__, __VA_ARGS__ ); \ - } while( 0 ) - -/** - * @brief Template based, single file, wrapper library around eldbus for DBUS based communication. - * - * Main motivation was missing asynchronous calls in AT-SPI library and difficulties, - * when using eldbus from C++. - * - * The library: - * - takes care of marshalling arguments to and from DBUS calls. - * - allows synchronous and asynchronous calls. - * - allows synchronous and asynchronous listeners on signals. - * - manages all involved objects' lifetimes. - * - errors are passed as optional-alike objects, no exceptions are used. - * - allows setting additional debug-print function for more details about - * what's going on - * - * DBUS's method signatures (and expected return values) are specified as template argument, - * using functor syntax. For example: - * \code{.cpp} - * auto dbus = DBusClient{ ... }; - * auto v = dbus.method(float, float, std::string)>("foo").call(1.0f, 2.0f, "qwe"); - * \endcode - * means (synchronous) call on dbus object, which takes three arguments (thus making call signature \b dds) - * of types float, float and string (float will be automatically converted to double). - * Expected return value is std::tuple, which gives signature (id) - std::tuple acts - * as struct container. Returned value v will be of type ValueOrError>.\n - * Slightly different (asynchronous) example: - * \code{.cpp} - * auto dbus = DBusClient{ ... }; - * std::function)> callback; - * dbus.method(float, float, std::string)>("foo").asyncCall(callback, 1.0f, 2.0f, "qwe"); - * \endcode - * Now the call takes the same arguments and has the same signature. But expected values are different - - * now the signature is simply \b id. ValueOrError acts in this case as placeholder for list of values, - * which DBUS allows as return data. The call itself is asynchronous - instead of expecting reply - * you need to pass a callback, which will be called either with received data and error message. - * - * Library is not thread-safe, the same object shouldn't be called from different threads without - * synchronization. There's no guarantee, that callbacks will be executed on the same thread. - */ -namespace DBus -{ -/// \cond -class DBusServer; -class DBusClient; -class DBusInterfaceDescription; - -/** - * @brief DBus action enumeration - * - * @param METHOD_CALL DBus is about to call a method on some external target - * @param SETTER_CALL DBus is about to call a setter method on some external target - * @param GETTER_CALL DBus is about to call a getter method on some external target - * @param SIGNAL_RECEIVED DBus just received a signal - * @param METHOD_RESPONSE DBus server received a method call - * @param SETTER_RESPONSE DBus server received a setter call - * @param GETTER_RESPONSE DBus server received a getter call - * @param SIGNAL_EMIT DBus server is about to emit a signal - */ -enum class DBusActionType -{ - METHOD_CALL, - SETTER_CALL, - GETTER_CALL, - SIGNAL_RECEIVED, - METHOD_RESPONSE, - SETTER_RESPONSE, - GETTER_RESPONSE, - SIGNAL_EMIT, -}; - -/** - * @brief Structure containing information about DBus activity, when calling notification callback - * - * @param type type of the action - * @param path path of the object, that's involved in action - * @param interface interface, on which member was acted upon. Note, that in case of getters and setters - * this will be real interface, not org.freedesktop.DBus.Properties - * @param member member name, that was involved (either method / setter / getter / signal) - */ -struct DBusAction -{ - const DBusActionType type; - const char* const bus = nullptr; - const char* const path = nullptr; - const char* const interface = nullptr; - const char* const member = nullptr; - - DBusAction( const DBusActionType type, - const char* const bus = nullptr, - const char* const path = nullptr, - const char* const interface = nullptr, - const char* const member = nullptr ) : type( type ), bus( bus ), path( path ), interface( interface ), member( member ) {} -}; - -/** - * @brief Formats debug message and calls debug printer (if any) with it - */ -void debugPrint( const char* file, size_t line, const char* format, ... ); - -/** - * @brief Sets debug printer callback, which will be called with debug messages - * - * Callback will be called in various moments of DBus activity. First value passed to callback - * is pointer to text, second it's length. Text is ended with 0 (not counted towards it's size), - * user can safely printf it. - */ -void setDebugPrinter( std::function< void( const char*, size_t ) > ); - -/** - * @brief Sets notification callback about processing of DBus call - * - * Notification callback can be set independently either on client or server. - * On client's side callback will be called, when user calls method / getter / setter - * or when client has received a signal. - * On server's side callback will be called, when sever has received a request to - * handle method / getter / setter or when server is going to emit a signal. - * Callback should returns as fast as possible. - * User can't call setDBusActionNotifier from inside the callback call - - * it will cause a deadlock - */ -void setDBusActionNotifier( std::function< void( DBusAction ) > callback ); - -namespace detail -{ -void emitNotification( const char* bus, const char* path, const char* interface, const char* member, DBusActionType type ); -} - -struct Error -{ - std::string message; - - Error() = default; - Error( std::string msg ) : message( std::move( msg ) ) - { - assert( !message.empty() ); - } -}; -struct Success -{ -}; -/// \endcond - -/** - * @brief Value representing data, that came from DBUS or error message - * - * Object of this class either helds series of values (of types ARGS...) - * or error message. This object will be true in boolean context, if has data - * and false, if an error occured. - * It's valid to create ValueOrError object with empty argument list or void: - * \code{.cpp} - * ValueOrError<> v1; - * ValueOrError v2; - * \endcode - * Both mean the same - ValueOrError containing no real data and being a marker, - * wherever operation successed or failed and containing possible error message. - */ -template < typename... ARGS > -class ValueOrError -{ -public: - /** - * @brief Empty constructor. Valid only, if all ARGS types are default constructible. - */ - ValueOrError() = default; - - /** - * @brief Value constructor. - * - * This will be initialized as success with passed in values. - */ - ValueOrError( ARGS... t ) : value( std::move( t )... ) {} - - /** - * @brief Alternative Value constructor. - * - * This will be initialized as success with passed in values. - */ - ValueOrError( std::tuple< ARGS... > t ) : value( std::move( t ) ) {} - - /** - * @brief Error constructor. This will be initialized as failure with given error message. - */ - ValueOrError( Error e ) : error( std::move( e ) ) - { - assert( !error.message.empty() ); - } - - /** - * @brief bool operator. - * - * Returns true, if operation was successful (getValues member is callable), or false - * when operation failed (getError is callable). - */ - explicit operator bool() const - { - return error.message.empty(); - } - - /** - * @brief Returns error message object. - * - * Returns object containing error message associated with the failed operation. - * Only callable, if operation actually failed, otherwise will assert. - */ - const Error& getError() const - { - return error; - } - - /** - * @brief Returns modifiable tuple of held data. - * - * Returns reference to the internal tuple containing held data. - * User can modify (or move) data safely. - * Only callable, if operation actually successed, otherwise will assert. - */ - std::tuple< ARGS... >& getValues() - { - assert( *this ); - return value; - } - - /** - * @brief Returns const tuple of held data. - * - * Returns const reference to the internal tuple containing held data. - * Only callable, if operation actually successed, otherwise will assert. - */ - const std::tuple< ARGS... >& getValues() const - { - assert( *this ); - return value; - } - -protected: - /// \cond - std::tuple< ARGS... > value; - Error error; - /// \endcond -}; - -/// \cond -template <> -class ValueOrError<> -{ -public: - ValueOrError() = default; - ValueOrError( std::tuple<> t ) {} - ValueOrError( Error e ) : error( std::move( e ) ) - { - assert( !error.message.empty() ); - } - - explicit operator bool() const - { - return error.message.empty(); - } - const Error& getError() const - { - return error; - } - std::tuple<>& getValues() - { - assert( *this ); - static std::tuple<> t; - return t; - } - std::tuple<> getValues() const - { - assert( *this ); - return {}; - } - -protected: - Error error; -}; - -template <> -class ValueOrError< void > -{ -public: - ValueOrError() = default; - ValueOrError( Success ) {} - ValueOrError( Error e ) : error( std::move( e ) ) - { - assert( !error.message.empty() ); - } - - explicit operator bool() const - { - return error.message.empty(); - } - const Error& getError() const - { - return error; - } - std::tuple<>& getValues() - { - assert( *this ); - static std::tuple<> t; - return t; - } - std::tuple<> getValues() const - { - assert( *this ); - return {}; - } - -protected: - Error error; -}; -struct ObjectPath -{ - std::string value; -}; -namespace detail -{ -class CallOnDestructionList -{ -public: - CallOnDestructionList() = default; - CallOnDestructionList( const CallOnDestructionList& ) = delete; - CallOnDestructionList( CallOnDestructionList&& ) = default; - - CallOnDestructionList& operator=( const CallOnDestructionList& ) = delete; - CallOnDestructionList& operator=( CallOnDestructionList&& ); - - void add( const std::function< void() >& c ); - -private: - std::vector< std::function< void() > > functions; -}; - -struct caller_eldbus_connection_unref -{ - void operator()( Eldbus_Connection* p ) const - { - eldbus_connection_unref( p ); - } -}; - -struct caller_eldbus_message_unref -{ - void operator()( Eldbus_Message* p ) const - { - eldbus_message_unref( p ); - } -}; - -struct caller_eldbus_proxy_unref -{ - void operator()( Eldbus_Proxy* p ) const - { - eldbus_proxy_unref( p ); - } -}; -} -/// \endcond - -/** - * @brief Class used to marshall DBUS's variant type - * - * Minimalistic class, that allows user to specify DBUS variant type - * as argument or return value. You need to pass real type hidden under variant as - * template type \b A. At this point library doesn't allow to expected one of few classes - * as return data in variant. So for example user can't specify method call, which on return - * expects DBUS variant holding either string or int. - */ -template < typename A > -struct EldbusVariant -{ - A value; -}; - -/// \cond -class EldbusConnection -{ - Eldbus_Connection* ptr = nullptr; - -public: - EldbusConnection( Eldbus_Connection* c ) : ptr( c ) - { - eldbus_init(); - } - EldbusConnection() = delete; - EldbusConnection( const EldbusConnection& ) = delete; - EldbusConnection( EldbusConnection&& ) = delete; - ~EldbusConnection() - { - eldbus_connection_unref( ptr ); - eldbus_shutdown(); - } - - Eldbus_Connection* get() const - { - return ptr; - } -}; -//using EldbusConnectionCallbackHandle = std::shared_ptr; -using EldbusMessageCallbackHandle = std::unique_ptr< Eldbus_Message, detail::caller_eldbus_message_unref >; -using EldbusObjectCallbackHandle = std::shared_ptr< Eldbus_Object >; -using EldbusProxyHandle = std::shared_ptr< Eldbus_Proxy >; -/// \endcond - -/** - * @brief Namespace for private, internal functions and classes - * - */ -namespace detail -{ -/// \cond -template < typename T, typename = void > -struct signature; -template < typename... ARGS > -struct signature< std::tuple< ARGS... > >; -template < typename A, typename B > -struct signature< std::pair< A, B > >; -template < typename A > -struct signature< std::vector< A > >; -template < typename A, size_t N > -struct signature< std::array< A, N > >; -template < typename A, typename B > -struct signature< std::unordered_map< A, B > >; -template < typename A, typename B > -struct signature< std::map< A, B > >; - -template < typename T > -struct signature< T, typename std::enable_if< std::is_enum< T >::value, void >::type > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "enum"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - // TODO: add check for failure in marshalling arguments - return "i"; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, T v ) - { - eldbus_message_iter_arguments_append( iter, sig().c_str(), static_cast< int >( v ) ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, T& v ) - { - int q; - auto z = eldbus_message_iter_get_and_next( iter, sig()[0], &q ); - v = static_cast< T >( q ); - return z; - } -}; -/// \endcond - -/** - * @brief Signature class for marshalling uint8 type. - */ -template <> -struct signature< uint8_t > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "uint8_t"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return "y"; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, uint8_t v ) - { - eldbus_message_iter_arguments_append( iter, sig().c_str(), v ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, uint8_t& v ) - { - return eldbus_message_iter_get_and_next( iter, sig()[0], &v ); - } -}; - -/** - * @brief Signature class for marshalling uint16 type. - */ -template <> -struct signature< uint16_t > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "uint16_t"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return "q"; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, uint16_t v ) - { - eldbus_message_iter_arguments_append( iter, sig().c_str(), v ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, uint16_t& v ) - { - return eldbus_message_iter_get_and_next( iter, sig()[0], &v ); - } -}; - -/** - * @brief Signature class for marshalling uint32 type. - */ -template <> -struct signature< uint32_t > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "uint32_t"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return "u"; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, uint32_t v ) - { - eldbus_message_iter_arguments_append( iter, sig().c_str(), v ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, uint32_t& v ) - { - return eldbus_message_iter_get_and_next( iter, sig()[0], &v ); - } -}; - -/** - * @brief Signature class for marshalling uint64 type. - */ -template <> -struct signature< uint64_t > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "uint64_t"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return "t"; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, uint64_t v ) - { - eldbus_message_iter_arguments_append( iter, sig().c_str(), v ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, uint64_t& v ) - { - return eldbus_message_iter_get_and_next( iter, sig()[0], &v ); - } -}; - -/** - * @brief Signature class for marshalling int16 type. - */ -template <> -struct signature< int16_t > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "int16_t"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return "n"; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, int16_t v ) - { - eldbus_message_iter_arguments_append( iter, sig().c_str(), v ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, int16_t& v ) - { - return eldbus_message_iter_get_and_next( iter, sig()[0], &v ); - } -}; - -/** - * @brief Signature class for marshalling int32 type. - */ -template <> -struct signature< int32_t > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "int32_t"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return "i"; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, int32_t v ) - { - eldbus_message_iter_arguments_append( iter, sig().c_str(), v ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, int32_t& v ) - { - return eldbus_message_iter_get_and_next( iter, sig()[0], &v ); - } -}; - -/** - * @brief Signature class for marshalling int64 type. - */ -template <> -struct signature< int64_t > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "int64_t"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return "x"; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, int64_t v ) - { - eldbus_message_iter_arguments_append( iter, sig().c_str(), v ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, int64_t& v ) - { - return eldbus_message_iter_get_and_next( iter, sig()[0], &v ); - } -}; - -/** - * @brief Signature class for marshalling double type. - */ -template <> -struct signature< double > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "double"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return "d"; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, double v ) - { - eldbus_message_iter_arguments_append( iter, sig().c_str(), v ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, double& v ) - { - return eldbus_message_iter_get_and_next( iter, sig()[0], &v ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, float& v2 ) - { - double v = 0; - auto r = eldbus_message_iter_get_and_next( iter, sig()[0], &v ); - v2 = static_cast< float >( v ); - return r; - } -}; - -/** - * @brief Signature class for marshalling float type. - */ -template <> -struct signature< float > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "float"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return "d"; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, float v ) - { - eldbus_message_iter_arguments_append( iter, sig().c_str(), v ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, double& v ) - { - return eldbus_message_iter_get_and_next( iter, sig()[0], &v ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, float& v2 ) - { - double v = 0; - auto r = eldbus_message_iter_get_and_next( iter, sig()[0], &v ); - v2 = static_cast< float >( v ); - return r; - } -}; - -/** - * @brief Signature class for marshalling boolean type. - */ -template <> -struct signature< bool > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "bool"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return "b"; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, bool v ) - { - eldbus_message_iter_arguments_append( iter, sig().c_str(), v ? 1 : 0 ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, bool& v ) - { - unsigned char q; - auto z = eldbus_message_iter_get_and_next( iter, sig()[0], &q ); - v = q != 0; - return z; - } -}; - -/** - * @brief Signature class for marshalling string type. - * - * Both (const) char * and std::string types are accepted as value to send. - * Only std::string is accepted as value to receive. - */ -template <> -struct signature< std::string > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "string"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return "s"; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const std::string& v ) - { - eldbus_message_iter_arguments_append( iter, sig().c_str(), v.c_str() ); - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const char* v ) - { - eldbus_message_iter_arguments_append( iter, sig().c_str(), v ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, std::string& v ) - { - const char* q; - if( !eldbus_message_iter_get_and_next( iter, 's', &q ) ) - { - if( !eldbus_message_iter_get_and_next( iter, 'o', &q ) ) - return false; - } - v = q; - return true; - } -}; -template <> -struct signature< ObjectPath > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "path"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return "o"; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const std::string& v ) - { - eldbus_message_iter_arguments_append( iter, sig().c_str(), v.c_str() ); - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const ObjectPath& v ) - { - eldbus_message_iter_arguments_append( iter, sig().c_str(), v.value.c_str() ); - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const char* v ) - { - eldbus_message_iter_arguments_append( iter, sig().c_str(), v ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, ObjectPath& v ) - { - const char* q; - if( !eldbus_message_iter_get_and_next( iter, 'o', &q ) ) - return false; - v.value = q; - return true; - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, std::string& v ) - { - const char* q; - if( !eldbus_message_iter_get_and_next( iter, 'o', &q ) ) - return false; - v = q; - return true; - } -}; - -/** - * @brief Signature class for marshalling (const) char * type. - * - * Both (const) char * and std::string types are accepted as value to send. - * You can't use (const) char * variable type to receive value. - */ -template <> -struct signature< char* > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "string"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return "s"; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const std::string& v ) - { - eldbus_message_iter_arguments_append( iter, sig().c_str(), v.c_str() ); - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const char* v ) - { - eldbus_message_iter_arguments_append( iter, sig().c_str(), v ); - } -}; - -/** - * @brief Signature class for marshalling (const) char[N] type. - * - * Both (const) char[N] and std::string types are accepted as value to send. - * You can't use (const) char[N] variable type to receive value. - */ -template < size_t N > -struct signature< char[N] > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "string"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return "s"; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const std::string& v ) - { - eldbus_message_iter_arguments_append( iter, sig().c_str(), v.c_str() ); - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const char* v ) - { - eldbus_message_iter_arguments_append( iter, sig().c_str(), v ); - } -}; -/// \cond -template < size_t INDEX, typename A, typename... ARGS > -struct signature_tuple_element_type_helper -{ - using type = typename signature_tuple_element_type_helper< INDEX - 1, ARGS... >::type; -}; -template < typename A, typename... ARGS > -struct signature_tuple_element_type_helper< 0, A, ARGS... > -{ - using type = A; -}; -/// \endcond - -/** - * @brief Helper class to marshall tuples - * - * This class marshals all elements of the tuple value starting at the index INDEX - * and incrementing. This class recursively calls itself with increasing INDEX value - * until INDEX is equal to SIZE, where recursive calling ends. - */ -template < size_t INDEX, size_t SIZE, typename... ARGS > -struct signature_tuple_helper -{ - using current_type = typename signature_tuple_element_type_helper< INDEX, ARGS... >::type; - - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - if( INDEX + 1 >= SIZE ) - return signature< current_type >::name(); - return signature< current_type >::name() + ", " + signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::name(); - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return signature< current_type >::sig() + signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::sig(); - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const std::tuple< ARGS... >& args ) - { - signature< current_type >::set( iter, std::get< INDEX >( args ) ); - signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::set( iter, args ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, std::tuple< ARGS... >& args ) - { - return signature< current_type >::get( iter, std::get< INDEX >( args ) ) && - signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::get( iter, args ); - } -}; - -/** - * @brief Helper class to marshall tuples - * - * This class marks end of the tuple marshalling. Members of this class are called - * when INDEX value is equal to SIZE. - */ -template < size_t SIZE, typename... ARGS > -struct signature_tuple_helper< SIZE, SIZE, ARGS... > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return ""; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return ""; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const std::tuple< ARGS... >& args ) - { - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, std::tuple< ARGS... >& args ) - { - return true; - } -}; - -/** - * @brief Signature class for marshalling tuple of values - * - * This class marshalls tuple of values. This represents - * DBUS struct typle, encoded with character 'r' - */ -template < typename... ARGS > -struct signature< std::tuple< ARGS... > > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "tuple<" + signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::name() + ">"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return "(" + signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::sig() + ")"; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const std::tuple< ARGS... >& args ) - { - auto entry = eldbus_message_iter_container_new( iter, 'r', NULL ); - signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::set( entry, args ); - eldbus_message_iter_container_close( iter, entry ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, std::tuple< ARGS... >& args ) - { - Eldbus_Message_Iter* entry; - if( !eldbus_message_iter_get_and_next( iter, 'r', &entry ) ) - return false; - auto z = signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::get( entry, args ); - return z; - } -}; -/** - * @brief Signature class for marshalling ValueOrError template type - * - * ValueOrError template type is used to marshall list of values passed to - * DBUS (or received from) at the "top" level. For example ss(s) is represented as - * \code{.cpp} ValueOrError> \endcode - * While (ss(s)) is represented as - * \code{.cpp} std::tuple> \endcode - * or - * \code{.cpp} ValueOrError>> \endcode - */ -template < typename... ARGS > -struct signature< ValueOrError< ARGS... > > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "ValueOrError<" + signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::name() + ">"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::sig(); - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const ValueOrError< ARGS... >& args ) - { - signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::set( iter, args.getValues() ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, ValueOrError< ARGS... >& args ) - { - return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::get( iter, args.getValues() ); - } -}; -/** - * @brief Signature class for marshalling ValueOrError type - */ -template <> -struct signature< ValueOrError< void > > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "ValueOrError"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return ""; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const ValueOrError< void >& args ) - { - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, ValueOrError< void >& args ) - { - return true; - } -}; -/** - * @brief Signature class for marshalling ValueOrError<> type - */ -template <> -struct signature< ValueOrError<> > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "ValueOrError<>"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return ""; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const ValueOrError<>& args ) - { - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, ValueOrError<>& args ) - { - return true; - } -}; -/** - * @brief Signature class for marshalling pair of types - */ -template < typename A, typename B > -struct signature< std::pair< A, B > > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "pair<" + signature_tuple_helper< 0, 2, A, B >::name() + ">"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return "(" + signature_tuple_helper< 0, 2, A, B >::sig() + ")"; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const std::pair< A, B >& ab, bool dictionary = false ) - { - auto entry = eldbus_message_iter_container_new( iter, dictionary ? 'e' : 'r', NULL ); - signature_tuple_helper< 0, 2, A, B >::set( entry, ab ); - eldbus_message_iter_container_close( iter, entry ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, std::pair< A, B >& ab ) - { - char sg = 'r'; - char* t = eldbus_message_iter_signature_get( iter ); - if( t && t[0] == '{' ) - sg = '{'; - free( t ); - - Eldbus_Message_Iter* entry; - if( !eldbus_message_iter_get_and_next( iter, sg, &entry ) ) - return false; - std::tuple< A, B > ab_tmp; - auto z = signature_tuple_helper< 0, 2, A, B >::get( entry, ab_tmp ); - if( z ) - { - ab.first = std::move( std::get< 0 >( ab_tmp ) ); - ab.second = std::move( std::get< 1 >( ab_tmp ) ); - } - return z; - } -}; -/** - * @brief Signature class for marshalling std::vector template type - * - * This marshals container's content as DBUS a ascii character type code. - */ -template < typename A > -struct signature< std::vector< A > > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "vector<" + signature< A >::name() + ">"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return "a" + signature< A >::sig(); - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const std::vector< A >& v ) - { - auto lst = eldbus_message_iter_container_new( iter, 'a', signature< A >::sig().c_str() ); - assert( lst ); - for( auto& a : v ) - { - signature< A >::set( lst, a ); - } - eldbus_message_iter_container_close( iter, lst ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, std::vector< A >& v ) - { - Eldbus_Message_Iter* s; - v.clear(); - if( !eldbus_message_iter_get_and_next( iter, 'a', &s ) ) - return false; - A a; - while( signature< A >::get( s, a ) ) - v.push_back( std::move( a ) ); - - return true; - } -}; - -/** - * @brief Signature class for marshalling std::array template type - * - * This marshals container's content as DBUS a ascii character type code. - */ -template < typename A, size_t N > -struct signature< std::array< A, N > > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "array<" + signature< A >::name() + ", " + std::to_string( N ) + ">"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return "a" + signature< A >::sig(); - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const std::array< A, N >& v ) - { - auto lst = eldbus_message_iter_container_new( iter, 'a', signature< A >::sig().c_str() ); - assert( lst ); - for( auto& a : v ) - { - signature< A >::set( lst, a ); - } - eldbus_message_iter_container_close( iter, lst ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, std::array< A, N >& v ) - { - Eldbus_Message_Iter* s; - if( !eldbus_message_iter_get_and_next( iter, 'a', &s ) ) - return false; - for( auto& a : v ) - { - if( !signature< A >::get( s, a ) ) - return false; - } - return true; - } -}; - -/** - * @brief Signature class for marshalling EldbusVariant type - * - * This marshals variant's content as DBUS v ascii character type code. - */ -template < typename A > -struct signature< EldbusVariant< A > > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "variant<" + signature< A >::name() + ">"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return "v"; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const EldbusVariant< A >& v ) - { - set( iter, v.value ); - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const A& v ) - { - auto var = eldbus_message_iter_container_new( iter, 'v', signature< A >::sig().c_str() ); - signature< A >::set( var, v ); - eldbus_message_iter_container_close( iter, var ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, EldbusVariant< A >& v ) - { - Eldbus_Message_Iter* s; - if( !eldbus_message_iter_get_and_next( iter, 'v', &s ) ) - return false; - return signature< A >::get( s, v.value ); - } -}; -/** - * @brief Signature class for marshalling std::unordered_map template type - * - * This marshals container's content as DBUS {} ascii character type code. - * Note, that library doesnt check, if the key is basic type, as DBUS - * specification mandates. - * User can always exchange std::unordered_map for std::map and the reverse. - * User can receive such values as std::vector of std::pair values. - * Order of such values is unspecified. - */ -template < typename A, typename B > -struct signature< std::unordered_map< A, B > > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "unordered_map<" + signature< A >::name() + ", " + signature< B >::name() + ">"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return "a{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}"; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const std::unordered_map< A, B >& v ) - { - auto sig = "{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}"; - auto lst = eldbus_message_iter_container_new( iter, 'a', sig.c_str() ); - assert( lst ); - for( auto& a : v ) - { - signature< std::pair< A, B > >::set( lst, a, true ); - } - eldbus_message_iter_container_close( iter, lst ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, std::unordered_map< A, B >& v ) - { - Eldbus_Message_Iter* s; - v.clear(); - if( !eldbus_message_iter_get_and_next( iter, 'a', &s ) ) - return false; - std::pair< A, B > a; - while( signature< std::pair< A, B > >::get( s, a ) ) - v.insert( std::move( a ) ); - return true; - } -}; -/** - * @brief Signature class for marshalling std::unordered_map template type - * - * This marshals container's content as DBUS {} ascii character type code. - * Note, that library doesnt check, if the key is basic type, as DBUS - * specification mandates. - * User can always exchange std::unordered_map for std::map and the reverse. - * User can receive such values as std::vector of std::pair values. - * Order of such values is unspecified. - */ -template < typename A, typename B > -struct signature< std::map< A, B > > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "map<" + signature< A >::name() + ", " + signature< B >::name() + ">"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return "a{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}"; - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const std::map< A, B >& v ) - { - auto sig = "{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}"; - auto lst = eldbus_message_iter_container_new( iter, 'a', sig.c_str() ); - assert( lst ); - for( auto& a : v ) - { - signature< std::pair< A, B > >::set( lst, a, true ); - } - eldbus_message_iter_container_close( iter, lst ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static bool get( Eldbus_Message_Iter* iter, std::map< A, B >& v ) - { - Eldbus_Message_Iter* s; - if( !eldbus_message_iter_get_and_next( iter, 'a', &s ) ) - return false; - std::pair< A, B > a; - while( signature< std::pair< A, B > >::get( s, a ) ) - v.insert( std::move( a ) ); - return true; - } -}; -/** - * @brief Signature helper class for marshalling const reference types - */ -template < typename A > -struct signature< const A& > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "const " + signature< A >::name() + "&"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return signature< A >::sig(); - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const A& v ) - { - signature< A >::set( iter, v ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static void get( Eldbus_Message_Iter* iter, A& v ) - { - signature< A >::get( iter, v ); - } -}; -/** - * @brief Signature helper class for marshalling reference types - */ -template < typename A > -struct signature< A& > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return signature< A >::name() + "&"; - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return signature< A >::sig(); - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const A& v ) - { - signature< A >::set( iter, v ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static void get( Eldbus_Message_Iter* iter, A& v ) - { - signature< A >::get( iter, v ); - } -}; -/** - * @brief Signature helper class for marshalling const types - */ -template < typename A > -struct signature< const A > -{ - /** - * @brief Returns name of type marshalled, for informative purposes - */ - static std::string name() - { - return "const " + signature< A >::name(); - } - /** - * @brief Returns DBUS' signature of type marshalled - */ - static std::string sig() - { - return signature< A >::sig(); - } - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( Eldbus_Message_Iter* iter, const A& v ) - { - signature< A >::set( iter, v ); - } - /** - * @brief Marshals value from marshalled type into variable v - */ - static void get( Eldbus_Message_Iter* iter, A& v ) - { - signature< A >::get( iter, v ); - } -}; -// /** -// * @brief Signature helper class for marshalling AT-SPI Accessible pointer values -// * -// * In AT-SPI specification those values are mandated to be marshalled as struct (so) -// * where o is object (exactly as string, but with different ascii -// * character code. -// */ -// template <> struct signature> { -// using subtype = std::pair; - -// /** -// * @brief Returns name of type marshalled, for informative purposes -// */ -// static std::string name() -// { -// return "AtspiAccessiblePtr"; -// } -// /** -// * @brief Returns DBUS' signature of type marshalled -// */ -// static std::string sig() -// { -// return "(so)"; -// } -// /** -// * @brief Marshals value v as marshalled type into message -// */ -// static void set(Eldbus_Message_Iter *iter, const std::shared_ptr &v) -// { -// const auto prefixPath = "/org/a11y/atspi/accessible/"; -// const auto nullPath = "/org/a11y/atspi/null"; - -// if (v) { -// auto bus = atspi_accessible_get_bus_name(v.get(), NULL); -// auto path = atspi_accessible_get_path(v.get(), NULL); -// signature::set(iter, { bus, std::string{prefixPath} + path }); -// g_free(path); -// g_free(bus); -// } else { -// signature::set(iter, { {}, std::string{nullPath} }); -// } -// } -// /** -// * @brief Marshals value from marshalled type into variable v -// */ -// static bool get(Eldbus_Message_Iter *iter, std::shared_ptr &v); -// }; -/// \cond -struct CallId -{ - friend class ::DBus::DBusServer; - friend class ::DBus::DBusClient; - friend class ::DBus::DBusInterfaceDescription; - static std::atomic< unsigned int > LastId; - unsigned int id = ++LastId; -}; -template < typename ValueType > -ValueType unpackValues( CallId callId, const Eldbus_Message* msg ) -{ - auto iter = eldbus_message_iter_get( msg ); - ValueType r; - - if( iter ) - { - if( !signature< ValueType >::get( iter, r ) ) - { - DBUS_DEBUG( "ValueType is %s", signature< ValueType >::name().c_str() ); - r = Error{"call " + std::to_string( callId.id ) + ": failed to unpack values, got signature '" + - eldbus_message_signature_get( msg ) + "', expected '" + signature< ValueType >::sig() + "'"}; - } - } - else - { - r = Error{"call " + std::to_string( callId.id ) + ": failed to get iterator"}; - } - return r; -} -inline void packValues_helper( Eldbus_Message_Iter* iter ) {} -template < typename A, typename... ARGS > -void packValues_helper( Eldbus_Message_Iter* iter, A&& a, ARGS&&... r ) -{ - signature< A >::set( iter, std::forward< A >( a ) ); - packValues_helper( iter, std::forward< ARGS >( r )... ); -} -template < typename... ARGS > -void packValues( CallId callId, Eldbus_Message* msg, ARGS&&... r ) -{ - auto iter = eldbus_message_iter_get( msg ); - packValues_helper( iter, std::forward< ARGS >( r )... ); -} - -template < typename > -struct ReturnType; -template < typename R, typename... ARGS > -struct ReturnType< R( ARGS... ) > -{ - using type = R; -}; -template < typename R, typename... ARGS > -struct ReturnType< std::function< R( ARGS... ) > > -{ - using type = R; -}; -template < int... > -struct sequence -{ -}; -template < int N, int... S > -struct sequence_gen : sequence_gen< N - 1, N - 1, S... > -{ -}; -template < int... S > -struct sequence_gen< 0, S... > -{ - typedef sequence< S... > type; -}; -template < typename C, typename... ARGS > -struct apply_helper -{ - const std::function< C >& c; - const std::tuple< ARGS... >& args; - - template < int... S > - auto apply_2( sequence< S... > ) const -> decltype( c( std::get< S >( args )... ) ) - { - return c( std::get< S >( args )... ); - } - auto apply_1() const -> decltype( apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() ) ) - { - return apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() ); - } -}; -template < typename C, typename A, typename... ARGS > -struct apply_helper_2 -{ - const std::function< C >& c; - const A& a; - const std::tuple< ARGS... >& args; - - template < int... S > - auto apply_2( sequence< S... > ) const -> decltype( c( a, std::get< S >( args )... ) ) - { - return c( a, std::get< S >( args )... ); - } - auto apply_1() const -> decltype( apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() ) ) - { - return apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() ); - } -}; -template < typename C, typename... ARGS > -auto apply( const std::function< C >& c, const std::tuple< ARGS... >& args ) -> typename ReturnType< C >::type -{ - apply_helper< C, ARGS... > ah{c, args}; - return ah.apply_1(); -} -template < typename C, typename D, typename... ARGS > -auto apply( const std::function< C >& c, const D& d, const std::tuple< ARGS... >& args ) -> typename ReturnType< C >::type -{ - apply_helper_2< C, D, ARGS... > ah{c, d, args}; - return ah.apply_1(); -} - -struct EldbusProxyBase -{ - EldbusProxyBase() - { - eldbus_init(); - } - ~EldbusProxyBase() - { - eldbus_shutdown(); - } -}; - -constexpr static int ELDBUS_CALL_TIMEOUT = 1000; - -struct ConnectionState -{ - std::shared_ptr< DBus::EldbusConnection > connection; - EldbusObjectCallbackHandle object; - EldbusProxyHandle proxy; - EldbusProxyHandle propertiesProxy; -}; -using CallAsyncDataType = std::tuple< CallId, std::function< void( const Eldbus_Message* ) > >; - -static void callAsyncCb( void* data, const Eldbus_Message* msg, Eldbus_Pending* pending ) -{ - auto d = static_cast< CallAsyncDataType* >( data ); - DBUS_DEBUG( "call %d: got reply", std::get< 0 >( *d ).id ); - std::get< 1 > ( *d )( msg ); -} -static void pendingFreeCb( void* data, const void* ) -{ - auto d = static_cast< CallAsyncDataType* >( data ); - DBUS_DEBUG( "call %d: deleting", std::get< 0 >( *d ).id ); - delete d; -} -template < typename RETTYPE, typename... ARGS > -RETTYPE call( CallId callId, ConnectionState& connectionState, bool property, const std::string& funcName, const ARGS&... args ) -{ - auto proxy = property ? connectionState.propertiesProxy : connectionState.proxy; - if( !proxy ) - { - DBUS_DEBUG( "call %d: not initialized", callId.id ); - return Error{"not initialized"}; - } - - DBUS_DEBUG( "call %d: calling '%s'", callId.id, funcName.c_str() ); - EldbusMessageCallbackHandle msg{eldbus_proxy_method_call_new( proxy.get(), funcName.c_str() )}; - if( !msg ) - { - DBUS_DEBUG( "call %d: failed", callId.id ); - return Error{"failed to create message"}; - } - - detail::packValues( callId, msg.get(), args... ); - auto replyRawPtr = eldbus_proxy_send_and_block( proxy.get(), msg.release(), ELDBUS_CALL_TIMEOUT ); - EldbusMessageCallbackHandle reply{replyRawPtr}; - DBUS_DEBUG( "call %d: calling '%s' done", callId.id, funcName.c_str() ); - if( !reply ) - { - DBUS_DEBUG( "call %d: failed", callId.id ); - return Error{"eldbus returned null as reply"}; - } - const char *errname, *errmsg; - if( eldbus_message_error_get( reply.get(), &errname, &errmsg ) ) - { - DBUS_DEBUG( "call %d: %s: %s", callId.id, errname, errmsg ); - return Error{std::string( errname ) + ": " + errmsg}; - } - DBUS_DEBUG( "call %d: got reply with signature '%s'", callId.id, eldbus_message_signature_get( reply.get() ) ); - return detail::unpackValues< RETTYPE >( callId, reply.get() ); -} - -template < typename RETTYPE, typename... ARGS > -void asyncCall( CallId callId, ConnectionState connectionState, - bool property, const std::string& funcName, - std::function< void( RETTYPE ) > callback, const ARGS&... args ) -{ - auto proxy = property ? connectionState.propertiesProxy : connectionState.proxy; - if( !proxy ) - { - DBUS_DEBUG( "call %d: not initialized", callId.id ); - callback( Error{"not initialized"} ); - return; - } - - EldbusMessageCallbackHandle msg{eldbus_proxy_method_call_new( proxy.get(), funcName.c_str() )}; - if( !msg ) - { - DBUS_DEBUG( "call %d: failed", callId.id ); - callback( Error{"failed to create message"} ); - return; - } - - auto cbData = new CallAsyncDataType{callId, [callback, callId, proxy]( const Eldbus_Message* reply ) { - DBUS_DEBUG( "call %d: calling done", callId.id ); - if( !reply ) - { - DBUS_DEBUG( "call %d: failed", callId.id ); - callback( Error{"eldbus returned null as reply"} ); - } - else - { - const char *errname, *errmsg; - if( eldbus_message_error_get( reply, &errname, &errmsg ) ) - { - DBUS_DEBUG( "call %d: %s: %s", callId.id, errname, errmsg ); - callback( Error{std::string( errname ) + ": " + errmsg} ); - } - else - { - DBUS_DEBUG( "call %d: got reply with signature '%s'", callId.id, eldbus_message_signature_get( reply ) ); - callback( detail::unpackValues< RETTYPE >( callId, reply ) ); - } - } - }}; - detail::packValues( callId, msg.get(), args... ); - auto pending = eldbus_proxy_send( proxy.get(), msg.release(), callAsyncCb, cbData, ELDBUS_CALL_TIMEOUT ); - if( pending ) - { - eldbus_pending_free_cb_add( pending, pendingFreeCb, cbData ); - DBUS_DEBUG( "call %d: call sent", callId.id ); - } - else - { - DBUS_DEBUG( "call %d: failed to send call", callId.id ); - callback( Error{"failed to send call"} ); - } -} -inline void displayDebugCallInfo( CallId callId, const std::string& funcName, const std::string& info, const std::string& interfaceName ) -{ - DBUS_DEBUG( "call %d: %s iname = %s fname = %s", callId.id, info.c_str(), interfaceName.c_str(), funcName.c_str() ); -} -inline void displayDebugCallInfoSignal( CallId callId, const std::string& funcName, const std::string& info, const std::string& interfaceName ) -{ - DBUS_DEBUG( "call %d: %s signal iname = %s fname = %s", callId.id, info.c_str(), interfaceName.c_str(), funcName.c_str() ); -} -inline void displayDebugCallInfoProperty( CallId callId, const std::string& funcName, std::string info, const std::string& interfaceName, - const std::string& propertyName ) -{ - DBUS_DEBUG( "call %d: %s iname = %s pname = %s", callId.id, info.c_str(), interfaceName.c_str(), propertyName.c_str() ); -} - -class StringStorage -{ - struct char_ptr_deleter - { - void operator()( char* p ) - { - free( p ); - } - }; - std::vector< std::unique_ptr< char, char_ptr_deleter > > storage; - -public: - const char* add( const char* txt ) - { - auto ptr = strdup( txt ); - storage.push_back( std::unique_ptr< char, char_ptr_deleter >( ptr ) ); - return storage.back().get(); - } - const char* add( const std::string& txt ) - { - return add( txt.c_str() ); - } -}; -template < typename A, typename... ARGS > -struct EldbusArgGenerator_Helper -{ - static void add( std::vector< Eldbus_Arg_Info >& r, StringStorage& strings ) - { - auto s = r.size(); - auto sig = signature< A >::sig(); - assert( !sig.empty() ); - auto name = "p" + std::to_string( s + 1 ); - r.push_back( Eldbus_Arg_Info{strings.add( sig ), strings.add( name )} ); - EldbusArgGenerator_Helper< ARGS... >::add( r, strings ); - } -}; -template <> -struct EldbusArgGenerator_Helper< void > -{ - static void add( std::vector< Eldbus_Arg_Info >&, StringStorage& ) - { - } -}; -template <> -struct EldbusArgGenerator_Helper< ValueOrError< void >, void > -{ - static void add( std::vector< Eldbus_Arg_Info >&, StringStorage& ) - { - } -}; -template <> -struct EldbusArgGenerator_Helper< ValueOrError<>, void > -{ - static void add( std::vector< Eldbus_Arg_Info >&, StringStorage& ) - { - } -}; -template < typename... ARGS > -struct EldbusArgGenerator_Helper< std::tuple< ARGS... > > -{ - static void add( std::vector< Eldbus_Arg_Info >& r, StringStorage& strings ) - { - EldbusArgGenerator_Helper< ARGS..., void >::add( r, strings ); - } -}; -template < typename RetType > -struct dbus_interface_return_type_traits -{ - using type = ValueOrError< RetType >; -}; -template < typename... ARGS > -struct dbus_interface_return_type_traits< ValueOrError< ARGS... > > -{ - using type = ValueOrError< ARGS... >; -}; -template < typename T > -struct dbus_interface_traits; -template < typename RetType, typename... ARGS > -struct dbus_interface_traits< RetType( ARGS... ) > -{ - using Ret = typename dbus_interface_return_type_traits< RetType >::type; - using SyncCB = std::function< Ret( ARGS... ) >; - using AsyncCB = std::function< void( std::function< void( Ret ) >, ARGS... ) >; - using VEArgs = ValueOrError< ARGS... >; -}; -template < typename T > -struct EldbusArgGenerator_Args; -template < typename RetType, typename... ARGS > -struct EldbusArgGenerator_Args< RetType( ARGS... ) > -{ - static std::string name() - { - return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::name(); - } - static std::vector< Eldbus_Arg_Info > get( StringStorage& strings ) - { - std::vector< Eldbus_Arg_Info > tmp; - EldbusArgGenerator_Helper< ARGS..., void >::add( tmp, strings ); - tmp.push_back( {nullptr, nullptr} ); - return tmp; - } -}; -template < typename T > -struct EldbusArgGenerator_ReturnType; -template < typename RetType, typename... ARGS > -struct EldbusArgGenerator_ReturnType< RetType( ARGS... ) > -{ - static std::string name() - { - return signature< RetType >::name(); - } - static std::vector< Eldbus_Arg_Info > get( StringStorage& strings ) - { - std::vector< Eldbus_Arg_Info > tmp; - EldbusArgGenerator_Helper< RetType, void >::add( tmp, strings ); - tmp.push_back( {nullptr, nullptr} ); - return tmp; - } -}; -template < typename T > -struct EldbusArgGenerator_ReturnType; -template < typename... ARGS > -struct EldbusArgGenerator_ReturnType< void( ARGS... ) > -{ - static std::string name() - { - return ""; - } - static std::vector< Eldbus_Arg_Info > get( StringStorage& strings ) - { - std::vector< Eldbus_Arg_Info > tmp; - tmp.push_back( {nullptr, nullptr} ); - return tmp; - } -}; -/// \endcond -} - -/** - * @brief Enumeration determining, which DBUS session user wants to connect to. - */ -enum class ConnectionType -{ - SYSTEM, - SESSION -}; - -/** - * @brief Class representing client's end of DBUS connection - * - * Allows calling (synchronous and asynchronos) methods on selected interface - * Allows (synchronous and asynchronos) setting / getting properties. - * Allows registering signals. - */ -class DBusClient : private detail::EldbusProxyBase -{ - /// \cond - struct ConnectionInfo - { - std::string interfaceName, busName, pathName; - void emit( const char* member, DBusActionType type ) - { - detail::emitNotification( busName.c_str(), pathName.c_str(), interfaceName.c_str(), member, type ); - } - }; - /// \endcond -public: - /** - * @brief Default constructor, creates non-connected object. - */ - DBusClient() = default; - /** - * @brief Connects to dbus choosen by tp, using given arguments - * - * @param bus_name name of the bus to connect to - * @param path_name object's path - * @param interface_name interface name - */ - DBusClient( std::string busName_, std::string pathName_, std::string interfaceName_, - ConnectionType tp ); - /** - * @brief Connects to dbus using connection conn - * - * @param bus_name name of the bus to connect to - * @param path_name object's path - * @param interface_name interface name - * @param conn connection object from getDBusConnectionByType call - */ - DBusClient( std::string busName_, std::string pathName_, std::string interfaceName_, - const std::shared_ptr< DBus::EldbusConnection >& conn = {} ); - /** - * @brief Destructor object. - * - * All signals added will be disconnected. - * All asynchronous calls will be cancelled, their callback's will be called - * with failure message. - */ - ~DBusClient() = default; - DBusClient( const DBusClient& ) = delete; - DBusClient( DBusClient&& ) = default; - - DBusClient& operator=( DBusClient&& ) = default; - DBusClient& operator=( const DBusClient& ) = delete; - - /** - * @brief bool operator - * - * Returns true, if object is connected to DBUS - */ - explicit operator bool() const - { - return bool( connectionState.proxy ); - } - - /** - * @brief Helper class for calling a method - * - * Template type T defines both arguments sent to the method - * and expected values. Receiving different values will be reported as - * error. For example: - * \code{.cpp} Method \endcode - * defines method, which takes two arguments (two floats) and return - * single value of type int. - */ - template < typename T > - struct Method - { - /// \cond - using RetType = typename detail::dbus_interface_traits< T >::Ret; - detail::ConnectionState connectionState; - std::string funcName; - std::string info; - std::shared_ptr< ConnectionInfo > connectionInfo; - /// \endcond - - /** - * @brief Executes synchronous call on DBUS's method - * - * The function returns ValueOrError<...> object, which - * contains either received values or error message. - * - * @param args arguments to pass to the method - */ - template < typename... ARGS > - RetType call( const ARGS&... args ) - { - detail::CallId callId; - detail::displayDebugCallInfo( callId, funcName, info, connectionInfo->interfaceName ); - return detail::call< RetType >( callId, connectionState, false, funcName, args... ); - } - - /** - * @brief Executes asynchronous call on DBUS's method - * - * The function calls callback with either received values or error message. - * - * @param callback callback functor, which will be called with return value(s) or error message - * @param args arguments to pass to the method - */ - template < typename... ARGS > - void asyncCall( std::function< void( RetType ) > callback, const ARGS&... args ) - { - detail::CallId callId; - detail::displayDebugCallInfo( callId, funcName, info, connectionInfo->interfaceName ); - auto connectionState = this->connectionState; - detail::asyncCall< RetType >( callId, connectionState, false, funcName, std::move( callback ), args... ); - } - }; - - /** - * @brief Helper class for calling a property - * - * Template type T defines type of the value hidden under property. - * Note, that library automatically wraps both sent and received value into - * DBUS's wrapper type. - */ - template < typename T > - struct Property - { - /// \cond - using RetType = typename detail::dbus_interface_return_type_traits< T >::type; - using VariantRetType = typename detail::dbus_interface_return_type_traits< EldbusVariant< T > >::type; - detail::ConnectionState connectionState; - std::string propName; - std::string info; - std::shared_ptr< ConnectionInfo > connectionInfo; - /// \endcond - - /** - * @brief executes synchronous get on property - * - * The function returns ValueOrError<...> object, which - * contains either received values or error message. - */ - RetType get() - { - connectionInfo->emit( propName.c_str(), DBusActionType::GETTER_CALL ); - detail::CallId callId; - detail::displayDebugCallInfoProperty( callId, "Get", info, connectionInfo->interfaceName, propName ); - auto z = detail::call< VariantRetType >( callId, connectionState, true, "Get", connectionInfo->interfaceName, propName ); - if( !z ) - return z.getError(); - return {std::get< 0 >( z.getValues() ).value}; - } - - /** - * @brief executes asynchronous get on property - * - * The function calls callback with either received values or error message. - * - * @param callback callback functor, which will be called with return value(s) or error message - */ - void asyncGet( std::function< void( RetType ) > callback ) - { - connectionInfo->emit( propName.c_str(), DBusActionType::GETTER_CALL ); - detail::CallId callId; - detail::displayDebugCallInfoProperty( callId, "Get", info, connectionInfo->interfaceName, propName ); - auto connectionState = this->connectionState; - auto cc = [callback]( VariantRetType reply ) { - if( reply ) - callback( std::move( std::get< 0 >( reply.getValues() ).value ) ); - else - callback( reply.getError() ); - }; - detail::asyncCall< VariantRetType >( callId, connectionState, true, "Get", std::move( cc ), connectionInfo->interfaceName, propName ); - } - - /** - * @brief executes synchronous set on property - * - * The function returns ValueOrError object, with - * possible error message. - */ - ValueOrError< void > set( const T& r ) - { - connectionInfo->emit( propName.c_str(), DBusActionType::SETTER_CALL ); - detail::CallId callId; - detail::displayDebugCallInfoProperty( callId, "Set", info, connectionInfo->interfaceName, propName ); - EldbusVariant< T > variantValue{std::move( r )}; - return detail::call< ValueOrError< void > >( callId, connectionState, true, "Set", connectionInfo->interfaceName, propName, variantValue ); - } - - /** - * @brief executes asynchronous get on property - * - * The function calls callback with either received values or error message. - * - * @param callback callback functor, which will be called with return value(s) or error message - */ - void asyncSet( std::function< void( ValueOrError< void > ) > callback, const T& r ) - { - connectionInfo->emit( propName.c_str(), DBusActionType::SETTER_CALL ); - detail::CallId callId; - detail::displayDebugCallInfoProperty( callId, "Set", info, connectionInfo->interfaceName, propName ); - EldbusVariant< T > variantValue{std::move( r )}; - detail::asyncCall< ValueOrError< void > >( callId, connectionState, true, "Set", std::move( callback ), connectionInfo->interfaceName, propName, variantValue ); - } - }; - - /** - * @brief Constructs Property<...> object for calling properties - * - * The function constructs and returns proxy object for calling property. - * - * @param propName property name to set and / or query - */ - template < typename PropertyType > - Property< PropertyType > property( std::string propName ) - { - return Property< PropertyType >{connectionState, std::move( propName ), info, connectionInfo}; - } - - /** - * @brief Constructs Method<...> object for calling methods - * - * The function constructs and returns proxy object for calling method. - * - * @param funcName function name to call - */ - template < typename MethodType > - Method< MethodType > method( std::string funcName ) - { - return Method< MethodType >{connectionState, std::move( funcName ), info, connectionInfo}; - } - - /** - * @brief Registers notification callback, when property has changed - * - * The callback will be called with new value, when property's value has changed. - * Note, that template type V must match expected type, otherwise undefined behavior will occur, - * there's no check for this. - */ - template < typename V > - void addPropertyChangedEvent( std::string propertyName, std::function< void( V ) > callback ) - { - detail::CallId callId; - detail::displayDebugCallInfoSignal( callId, propertyName, info, connectionInfo->interfaceName ); - DBUS_DEBUG( "call %d: adding property", callId.id ); - auto cS = this->connectionState; - auto cI = this->connectionInfo; - auto callbackLambdaPtr = new std::function< void( Eldbus_Proxy_Event_Property_Changed* ) >; - *callbackLambdaPtr = [callId, cS, callback, propertyName, cI]( Eldbus_Proxy_Event_Property_Changed* ev ) { - const char* ifc = eldbus_proxy_interface_get( ev->proxy ); - DBUS_DEBUG( "call %d: property changed iname = %s pname = %s (name %s iface %s)", - callId.id, cI->interfaceName.c_str(), propertyName.c_str(), ev->name, ifc ); - V val = 0; - if( ev->name && ev->name == propertyName && ifc && cI->interfaceName == ifc ) - { - if( !eina_value_get( ev->value, &val ) ) - { - DBUS_DEBUG( "unable to get property's value" ); - return; - } - DBUS_DEBUG( ". %d", val ); - callback( val ); - DBUS_DEBUG( "." ); - } - DBUS_DEBUG( "." ); - }; - auto p = connectionState.proxy.get(); - eldbus_proxy_event_callback_add( p, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED, - listenerEventChangedCallback, callbackLambdaPtr ); - destructors.add( [=]() { - eldbus_proxy_event_callback_del( p, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED, - listenerEventChangedCallback, callbackLambdaPtr ); - delete callbackLambdaPtr; - } ); - } - /** - * @brief Registers callback on the DBUS' signal - * - * The function registers callback signalName. When signal comes, callback will be called. - * Callback object will exists as long as signal is registered. You can unregister signal - * by destroying DBusClient object. - * - * @param signalName name of the signal to register - * @param callback callback to call - */ - template < typename SignalType > - void addSignal( std::string signalName, std::function< SignalType > callback ) - { - detail::CallId callId; - detail::displayDebugCallInfoSignal( callId, signalName, info, connectionInfo->interfaceName ); - auto cS = this->connectionState; - auto cI = this->connectionInfo; - auto callbackLambda = [callId, cS, callback, signalName, cI]( const Eldbus_Message* msg ) -> void { - const char *errname, *aux; - if( eldbus_message_error_get( msg, &errname, &aux ) ) - { - DBUS_DEBUG( "call %d: Eldbus error: %s %s", callId.id, errname, aux ); - return; - } - cI->emit( signalName.c_str(), DBusActionType::SIGNAL_RECEIVED ); - DBUS_DEBUG( "call %d: received signal with signature '%s'", callId.id, eldbus_message_signature_get( msg ) ); - using ParamsType = typename detail::dbus_interface_traits< SignalType >::VEArgs; - auto params = detail::unpackValues< ParamsType >( callId, msg ); - if( !params ) - { - DBUS_DEBUG( "call %d: failed: %s", callId.id, params.getError().message.c_str() ); - return; - } - try - { - detail::apply( callback, params.getValues() ); - } - catch( ... ) - { - DBUS_DEBUG( "unhandled exception" ); - assert( 0 ); - } - }; - auto tmp = new std::function< void( const Eldbus_Message* msg ) >{std::move( callbackLambda )}; - auto handler = eldbus_proxy_signal_handler_add( connectionState.proxy.get(), signalName.c_str(), listenerCallback, tmp ); - destructors.add( [=]() { - eldbus_signal_handler_del( handler ); - delete tmp; - } ); - } - -private: - /// \cond - detail::ConnectionState connectionState; - detail::CallOnDestructionList destructors; - std::string info; - std::shared_ptr< ConnectionInfo > connectionInfo; - void emitNotification( DBusActionType type ); - - static void listenerCallback( void* data, const Eldbus_Message* msg ) - { - auto p = static_cast< std::function< void( const Eldbus_Message* msg ) >* >( data ); - ( *p )( msg ); - } - static void listenerEventChangedCallback( void* data, Eldbus_Proxy* proxy EINA_UNUSED, void* event ) - { - auto p = static_cast< std::function< void( Eldbus_Proxy_Event_Property_Changed* ) >* >( data ); - ( *p )( static_cast< Eldbus_Proxy_Event_Property_Changed* >( event ) ); - } - /// \endcond -}; - -/** - * @brief Helper class describing DBUS's server interface - * - */ -class DBusInterfaceDescription -{ - friend class DBusServer; - -public: - /// \cond - struct MethodInfo - { - detail::CallId id; - std::string memberName; - std::vector< Eldbus_Arg_Info > in, out; - std::function< Eldbus_Message*( const Eldbus_Message* msg ) > callback; - }; - struct SignalInfo - { - detail::CallId id; - std::string memberName; - std::vector< Eldbus_Arg_Info > args; - unsigned int uniqueId; - }; - struct PropertyInfo - { - detail::CallId setterId, getterId; - std::string memberName, typeSignature; - std::function< ValueOrError< void >( const Eldbus_Message*src, Eldbus_Message_Iter*dst ) > getCallback, setCallback; - }; - class SignalId - { - friend class ::DBus::DBusServer; - friend class ::DBus::DBusClient; - friend class ::DBus::DBusInterfaceDescription; - detail::CallId id; - - SignalId( detail::CallId id ) : id( id ) {} - - public: - SignalId() = default; - }; - /// \endcond - - /** - * @brief Creates empty interface description with given name - * - * @param interfaceName name of the interface - */ - DBusInterfaceDescription( std::string interfaceName ); - - /** - * @brief adds new, synchronous method to the interface - * - * When method memberName is called on DBUS, callback functor will be called - * with values received from DBUS. callback won't be called, if method was - * called with invalid signature. Value returned from functor (or error message) - * will be marshalled back to the caller. - * - * Template type T defines both arguments sent to the method - * and expected values. Receiving different values will be reported as - * error. For example: - * \code{.cpp} Method \endcode - * defines method, which takes two arguments (two floats) and return - * single value of type int. - * - * @param memberName name of the method - * @param callback functor, which will be called - */ - template < typename T > - void addMethod( const std::string& memberName, typename detail::dbus_interface_traits< T >::SyncCB callback ) - { - detail::CallId callId; - MethodInfo mi; - methods.push_back( std::move( mi ) ); - auto& z = methods.back(); - z.in = detail::EldbusArgGenerator_Args< T >::get( strings ); - z.out = detail::EldbusArgGenerator_ReturnType< T >::get( strings ); - z.memberName = memberName; - DBUS_DEBUG( "call %d: method %s, in %s, out %s", callId.id, memberName.c_str(), - detail::EldbusArgGenerator_Args< T >::name().c_str(), - detail::EldbusArgGenerator_ReturnType< T >::name().c_str() ); - z.callback = construct< T >( callId, callback ); - z.id = callId; - } - - /** - * @brief adds new, asynchronous method to the interface - * - * When method memberName is called on DBUS, callback functor will be called - * with values received from DBUS. callback won't be called, if method was - * called with invalid signature. callback will called with reply callback functor. - * Reply callback functor must be called with reply value, when it's ready. - * It's safe to ignore calling reply callback, but some resources might be kept - * as long as either reply callback exists or reply timeout hasn't yet been met. - * - * Template type T defines both arguments sent to the method - * and expected values. Receiving different values will be reported as - * error. For example: - * \code{.cpp} Method \endcode - * defines method, which takes two arguments (two floats) and return - * single value of type int. - * - * @param memberName name of the method - * @param callback functor, which will be called - */ - template < typename T > - void addAsyncMethod( const std::string& memberName, typename detail::dbus_interface_traits< T >::AsyncCB callback ); - - /** - * @brief adds new, synchronous property to the interface - * - * When property memberName is called on DBUS, respective callback functor will be called - * with values received from DBUS. callback won't be called, if method was - * called with invalid signature. Value returned from functor (or error message) - * will be marshalled back to the caller. - * - * Template type T defines type of the value hidden under property. - * Note, that library automatically wraps both sent and received value into - * DBUS's wrapper type. - * - * @param memberName name of the method - * @param getter functor, which will be called when property is being read - * @param setter functor, which will be called when property is being set - */ - template < typename T > - void addProperty( const std::string& memberName, std::function< ValueOrError< T >() > getter, std::function< ValueOrError< void >( T ) > setter ) - { - properties.push_back( {} ); - auto& z = properties.back(); - z.memberName = memberName; - z.typeSignature = detail::signature< T >::sig(); - if( getter ) - { - detail::CallId getterId; - z.getterId = getterId; - DBUS_DEBUG( "call %d: property %s (get) type %s", getterId.id, memberName.c_str(), detail::signature< T >::name().c_str() ); - z.getCallback = [=]( const Eldbus_Message* src, Eldbus_Message_Iter* dst ) -> ValueOrError< void > { - detail::emitNotification( eldbus_message_sender_get( src ), - eldbus_message_path_get( src ), interfaceName.c_str(), memberName.c_str(), DBusActionType::GETTER_RESPONSE ); - try - { - auto v = detail::apply( getter, std::tuple<>{} ); - if( v ) - { - detail::signature< T >::set( dst, std::get< 0 >( v.getValues() ) ); - DBUS_DEBUG( "call %d: success", getterId.id ); - return Success{}; - } - DBUS_DEBUG( "call %d: failed: %s", getterId.id, v.getError().message.c_str() ); - return v.getError(); - } - catch( std::exception& e ) - { - return Error{std::string( "unhandled exception (" ) + e.what() + ")"}; - } - catch( ... ) - { - return Error{"unhandled exception"}; - } - }; - } - if( setter ) - { - detail::CallId setterId; - z.setterId = setterId; - DBUS_DEBUG( "call %d: property %s (set) type %s", setterId.id, memberName.c_str(), detail::signature< T >::name().c_str() ); - z.setCallback = [=]( const Eldbus_Message* src, Eldbus_Message_Iter* src_iter ) -> ValueOrError< void > { - detail::emitNotification( eldbus_message_sender_get( src ), - eldbus_message_path_get( src ), interfaceName.c_str(), memberName.c_str(), DBusActionType::SETTER_RESPONSE ); - std::tuple< T > value; - auto src_signature = eldbus_message_iter_signature_get( src_iter ); - if( detail::signature< T >::get( src_iter, std::get< 0 >( value ) ) ) - { - try - { - auto v = detail::apply( setter, std::move( value ) ); - if( v ) - { - DBUS_DEBUG( "call %d: success", setterId.id ); - return Success{}; - } - DBUS_DEBUG( "call %d: failed: %s", setterId.id, v.getError().message.c_str() ); - free( src_signature ); - return v.getError(); - } - catch( std::exception& e ) - { - return Error{std::string( "unhandled exception (" ) + e.what() + ")"}; - } - catch( ... ) - { - return Error{"unhandled exception"}; - } - } - DBUS_DEBUG( "call %d: failed to unpack values, got signature '%s', expected '%s'", setterId.id, - src_signature, detail::signature< T >::sig().c_str() ); - return Error{"call " + std::to_string( setterId.id ) + ": failed to unpack values, got signature '" + - src_signature + "', expected '" + detail::signature< T >::sig() + "'"}; - }; - } - } - - /** - * @brief adds new signal to the interface - * - * Template types ARGS defines values, which will be emited with the signal - * - * @param memberName name of the method - */ - template < typename... ARGS > - SignalId addSignal( const std::string& memberName ) - { - detail::CallId callId; - signals.push_back( {} ); - auto& z = signals.back(); - z.memberName = memberName; - z.args = detail::EldbusArgGenerator_Args< void( ARGS... ) >::get( strings ); - z.id = callId; - DBUS_DEBUG( "call %d: signal %s", callId.id, memberName.c_str() ); - return SignalId{callId}; - } - -private: - /// \cond - std::vector< MethodInfo > methods; - std::vector< PropertyInfo > properties; - std::vector< SignalInfo > signals; - std::string interfaceName; - detail::StringStorage strings; - - template < typename T > - std::function< Eldbus_Message*( const Eldbus_Message* msg ) > construct( detail::CallId callId, - typename detail::dbus_interface_traits< T >::SyncCB callback ) - { - using VEArgs = typename detail::dbus_interface_traits< T >::VEArgs; - return [=]( const Eldbus_Message* msg ) -> Eldbus_Message* { - DBUS_DEBUG( "call %d: entering", callId.id ); - detail::emitNotification( eldbus_message_sender_get( msg ), - eldbus_message_path_get( msg ), interfaceName.c_str(), eldbus_message_member_get( msg ), DBusActionType::METHOD_RESPONSE ); - Eldbus_Message* ret = nullptr; - auto args = detail::unpackValues< VEArgs >( callId, msg ); - if( args ) - { - try - { - auto v = detail::apply( callback, std::move( args.getValues() ) ); - if( v ) - { - DBUS_DEBUG( "call %d: success", callId.id ); - ret = eldbus_message_method_return_new( msg ); - packValues( callId, ret, v ); - } - else - { - DBUS_DEBUG( "call %d: failed: %s", callId.id, v.getError().message.c_str() ); - ret = eldbus_message_error_new( msg, "org.freedesktop.DBus.Error.Failed", v.getError().message.c_str() ); - } - } - catch( std::exception& e ) - { - auto txt = std::string( "unhandled exception (" ) + e.what() + ")"; - DBUS_DEBUG( "call %d: failed: %s", callId.id, txt.c_str() ); - ret = eldbus_message_error_new( msg, "org.freedesktop.DBus.Error.Failed", txt.c_str() ); - } - catch( ... ) - { - DBUS_DEBUG( "call %d: failed: %s", callId.id, "unhandled exception" ); - ret = eldbus_message_error_new( msg, "org.freedesktop.DBus.Error.Failed", "unhandled exception" ); - } - } - else - { - std::ostringstream err; - err << "expected signature '" << detail::signature< VEArgs >::sig() << "', got '" << eldbus_message_signature_get( msg ) << "'"; - auto str = err.str(); - DBUS_DEBUG( "call %d: failed: %s", callId.id, str.c_str() ); - ret = eldbus_message_error_new( msg, "org.freedesktop.DBus.Error.InvalidArgs", str.c_str() ); - } - return ret; - }; - } - /// \endcond -}; - -/** - * @brief Class representing server's end of DBUS connection - * - * Allows listening (synchronously and asynchronosly) on methods on selected interface - * Allows listening (synchronously and asynchronosly) on setting / getting properties. - * Allows emiting signals. - */ -class DBusServer : private detail::EldbusProxyBase -{ -public: - /** - * @brief Constructs non-connected dbus server. - */ - DBusServer() = default; - - /** - * @brief Constructs dbus server on either system or user dbus connection. - */ - - DBusServer( ConnectionType tp ); - /** - * @brief Constructs dbus server on connection from getDBusConnectionByType - */ - - DBusServer( const std::shared_ptr< DBus::EldbusConnection >& conn ); - /** - * @brief Destructor - * - * Destructor will properly destroy everything. Destructor will cancel - * pending replies. - */ - ~DBusServer() = default; - - DBusServer( const DBusServer& ) = delete; - DBusServer( DBusServer&& ) = default; - - DBusServer& operator=( DBusServer&& ) = default; - DBusServer& operator=( const DBusServer& ) = delete; - - /** - * @brief Registers interface on given path name - * - * @param pathName path object to register interface on. - * @param dscr - * @param fallback - */ - void addInterface( const std::string& pathName, DBusInterfaceDescription& dscr, bool fallback = false ); - - /** - * @brief Gets bus name of the current connection (must be connected) - */ - std::string getBusName() const; - - /** - * @brief Returns connection object for this dbus server object - * - * @return connection object - */ - std::shared_ptr< DBus::EldbusConnection > getConnection(); - - /** - * @brief Emits signal - * - * You must pass identifier of the signal, got as result of calling DBusInterfaceDescription::addSignal. - * Types of the arguments must match EXACTLY types used to call addSignal. - * - * @param signal identifier of the signal - * @param args values to emit - */ - template < typename... ARGS > - void emit( DBusInterfaceDescription::SignalId signal, const ARGS&... args ) - { - auto it = signalData.find( signal.id.id ); - if( it != signalData.end() ) - { - auto msg = eldbus_service_signal_new( it->second.first, it->second.second ); - detail::packValues( signal.id, msg, args... ); - eldbus_service_signal_send( it->second.first, msg ); - } - else - { - DBUS_DEBUG( "signal %d not found", signal.id.id ); - } - } - - /** - * @brief Emits signal - * - * Emits signal based only on data passed to the function - * - * @param signal identifier of the signal - * @param args values to emit - */ - template < typename... ARGS > - void emit2( const std::string& path, const std::string& interfaceName, - const std::string& signalName, const ARGS&... args ) - { - auto msg = eldbus_message_signal_new( path.c_str(), interfaceName.c_str(), signalName.c_str() ); - detail::CallId id; - detail::packValues( id, msg, args... ); - eldbus_connection_send( connection->get(), msg, nullptr, nullptr, -1 ); - } - /** - * @brief Returns current object path, when handling call to property / method - * - * User can call this function from inside callback used to handle property / method calls. - * It will retrieve object's path used in the call. Note, that in asynchronous handling - * of those calls user need to retrieve and store the current object / current connection - * as the value will change at the moment user's callback handling will exit. For example: - * \code{.cpp} - * DBusInterfaceDescription interface{"name"}; - * auto handler_later = [](std::function done_cb) { - * // process something later on - * DBusServer::getCurrentObjectPath(); // this will return empty string - * }; - * interface.addAsyncMethod("m", [=](std::function done_cb) { - * DBusServer::getCurrentObjectPath(); // this will current object's path - * - * // do some processing later on and call done_cb, when it's done - * register_to_call_sometime_later_on(std::move(done_cb)); - * }; - * \endcode - */ - static std::string getCurrentObjectPath(); - - /** - * @brief Returns current connection object, when handling call to property / method - * - * User can call this function from inside callback used to handle property / method calls. - * It will retrieve object's path used in the call. Note, that in asynchronous handling - * of those calls user need to retrieve and store the current object / current connection - * as the value will change at the moment user's callback handling will exit. For example: - * \code{.cpp} - * DBusInterfaceDescription interface{"name"}; - * auto handler_later = [](std::function done_cb) { - * // process something later on - * DBusServer::getCurrentObjectPath(); // this will return empty string - * }; - * interface.addAsyncMethod("m", [=](std::function done_cb) { - * DBusServer::getCurrentObjectPath(); // this will current object's path - * - * // do some processing later on and call done_cb, when it's done - * register_to_call_sometime_later_on(std::move(done_cb)); - * }; - * \endcode - */ - static std::shared_ptr< DBus::EldbusConnection > getCurrentConnection(); - -private: - /// \cond - std::shared_ptr< DBus::EldbusConnection > connection; - detail::CallOnDestructionList destructors; - std::unordered_map< unsigned int, std::pair< const Eldbus_Service_Interface*, unsigned int > > signalData; - /// \endcond -}; - -template < typename T > -void DBusInterfaceDescription::addAsyncMethod( const std::string& memberName, typename detail::dbus_interface_traits< T >::AsyncCB callback ) -{ - detail::CallId callId; - MethodInfo mi; - methods.push_back( std::move( mi ) ); - auto& z = methods.back(); - z.in = detail::EldbusArgGenerator_Args< T >::get( strings ); - z.out = detail::EldbusArgGenerator_ReturnType< T >::get( strings ); - z.memberName = memberName; - DBUS_DEBUG( "call %d: method %s, in %s, out %s", callId.id, memberName.c_str(), - detail::EldbusArgGenerator_Args< T >::name().c_str(), - detail::EldbusArgGenerator_ReturnType< T >::name().c_str() ); - using VEArgs = typename detail::dbus_interface_traits< T >::VEArgs; - z.callback = [=]( const Eldbus_Message* msg ) -> Eldbus_Message* { - detail::emitNotification( eldbus_message_sender_get( msg ), - eldbus_message_path_get( msg ), interfaceName.c_str(), memberName.c_str(), DBusActionType::METHOD_RESPONSE ); - struct CallState - { - bool replyRunning = true; - Eldbus_Message* reply = nullptr; - EldbusMessageCallbackHandle message; - }; - auto callState = std::make_shared< CallState >(); - callState->message.reset( eldbus_message_ref( const_cast< Eldbus_Message* >( msg ) ) ); - auto connection = DBusServer::getCurrentConnection(); - auto retCallback = [=]( typename detail::dbus_interface_traits< T >::Ret v ) { - if( v ) - { - callState->reply = eldbus_message_method_return_new( callState->message.get() ); - packValues( callId, callState->reply, v ); - } - else - { - DBUS_DEBUG( "call %d: failed: %s", callId.id, v.getError().message.c_str() ); - callState->reply = eldbus_message_error_new( callState->message.get(), "org.freedesktop.DBus.Error.Failed", v.getError().message.c_str() ); - } - if( !callState->replyRunning ) - { - eldbus_connection_send( connection->get(), callState->reply, NULL, NULL, -1 ); - } - }; - Eldbus_Message* ret = nullptr; - auto args = detail::unpackValues< VEArgs >( callId, msg ); - if( args ) - { - auto error = [&]( const std::string& txt ) { - if( !callState->reply ) - { - DBUS_DEBUG( "call %d: failed: %s", callId.id, txt.c_str() ); - callState->reply = eldbus_message_error_new( callState->message.get(), "org.freedesktop.DBus.Error.Failed", txt.c_str() ); - } - }; - try - { - detail::apply( callback, std::move( retCallback ), std::move( args.getValues() ) ); - } - catch( std::exception& e ) - { - error( std::string( "unhandled exception (" ) + e.what() + ")" ); - } - catch( ... ) - { - error( "unhandled exception" ); - } - - callState->replyRunning = false; - ret = callState->reply; - } - else - { - std::ostringstream err; - err << "expected signature '" << detail::signature< VEArgs >::sig() << "', got '" << eldbus_message_signature_get( msg ) << "'"; - auto str = err.str(); - ret = eldbus_message_error_new( msg, "org.freedesktop.DBus.Error.InvalidArgs", str.c_str() ); - } - return ret; - }; - - z.id = callId; -} - -/// \cond -std::shared_ptr< EldbusConnection > getDBusConnectionByType( ConnectionType tp ); -std::shared_ptr< EldbusConnection > getDBusConnectionByName( const std::string& name ); -std::string getConnectionName( const std::shared_ptr< EldbusConnection >& ); -/// \endcond -} - -/// \cond -namespace std -{ -template < size_t INDEX, typename... ARGS > -inline auto get( DBus::ValueOrError< ARGS... >& v ) -> decltype( std::get< INDEX >( v.getValues() ) ) & -{ - return std::get< INDEX >( v.getValues() ); -} -template < size_t INDEX, typename... ARGS > -inline auto get( const DBus::ValueOrError< ARGS... >& v ) -> decltype( std::get< INDEX >( v.getValues() ) ) -{ - return std::get< INDEX >( v.getValues() ); -} -} -/// \endcond - -#endif diff --git a/dali/dali-bridge/src/Optional.hpp b/dali/dali-bridge/src/Optional.hpp deleted file mode 100755 index d4401fe..0000000 --- a/dali/dali-bridge/src/Optional.hpp +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright 2017 Samsung Electronics Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef OPTIONAL_HPP -#define OPTIONAL_HPP - -/** - * Minimalistic implementation of standard library std::optional (c++17) for c++11 compiler. - * - * After project conversion to C++17 standard, this template class will be deleted and - * Optional will point to std::optional. - * - * Allowed operations (note, to make code simplier, than original, value class must have accessible copy and move constructor): - * - constructing empty (valueless) object - * - copying Optional (with and without value) - * - moving Optional (with and without value) - * - querying, if Optional has value (via explicit operator bool), for example: - * Optional v = ...; - * if (v) ... // if v has value, then do something - * - accessing value (via operator *), for example: - * Optional v = ...; - * auto z = *v; // z now has the same int, as v (copied) - * auto &y = *v; // y now has REFERENCE to int inside v, so modifying y modifies v - */ - -#include -#include -#include -#include - -template < typename A > -class Optional -{ - /// \cond - union - { - A place; - }; - bool hasValue = false; - /// \endcond -public: - /** - * @brief Empty constructor. - * Creates empty Optional object, which will be false in boolean context. - * So: - * \code{.cpp} - * Optional o; - * if (o) printf("1\n"); - * \endcode - * won't print 1. - */ - Optional() {} - - /** - * @brief Single element constructor, when implicit convertion can be applied. - * - * This constructor will be selected, when type of given argument (U) is - * implicitly convertable to expected type A. In other words following - * code must be valid: - * \code{.cpp} - * A foo() { - * return U(); - * } - * \endcode - * - * @param a value held by Optional object will be initialized from a. - */ - template < typename U = A, typename std::enable_if< - std::is_convertible< U&&, A >::value && - std::is_constructible< A, U&& >::value && - !std::is_same< typename std::decay< U >::type, Optional< A > >::value, - int* >::type = nullptr > - constexpr Optional( U&& a ) - : place( std::forward< U >( a ) ), hasValue( true ) - { - } - - /** - * @brief Single element constructor, when only explicit convertion can be applied. - * - * This constructor will be selected, when type of given argument (U) is - * convertable to expected type A. - * - * @param a value held by Optional object will be initialized from a. - */ - template < typename U = A, typename std::enable_if< - !std::is_convertible< U&&, A >::value && - std::is_constructible< A, U&& >::value && - !std::is_same< typename std::decay< U >::type, Optional< A > >::value, - int* >::type = nullptr > - explicit constexpr Optional( U&& a ) - : place( std::forward< U >( a ) ), hasValue( true ) - { - } - - /** - * @brief Copy constructor. - * - * @param v Optional value to copy from. Will cause to copy data held by object v, - * if v has data. - */ - Optional( const Optional& v ) : hasValue( v.hasValue ) - { - if( hasValue ) - new( &place ) A( v.place ); - } - - /** - * @brief Move constructor. - * - * @param v Optional value to copy from. Will move data help by v, if any. - * After construction \code{.cpp} bool(v) \endcode will be false. - */ - Optional( Optional&& v ) : hasValue( v.hasValue ) - { - if( hasValue ) - new( &place ) A( std::move( v.place ) ); - } - - /** - * @brief Destructor. - */ - ~Optional() - { - if( hasValue ) - { - place.~A(); - } - } - - /** - * @brief Explicit bool operator - * - * Will return true if and only if object is helding data. - */ - explicit operator bool() const - { - return hasValue; - } - - /** - * @brief Accessor (*) operator - * - * Will return modifiable reference to held object. Will assert, if not object is held. - */ - A& operator*() - { - assert( hasValue ); - return place; - } - - /** - * @brief Accessor (*) const operator - * - * Will return const reference to held object. Will assert, if not object is held. - */ - const A& operator*() const - { - assert( hasValue ); - return place; - } - - /** - * @brief Accessor (->) operator - * - * Will return pointer to held object allowing access to the value's members. - * Will assert, if not object is held. - */ - A* operator->() - { - assert( hasValue ); - return &place; - } - - /** - * @brief Accessor (->) operator - * - * Will return pointer to (const) held object allowing access to the value's members. - * Will assert, if not object is held. - */ - const A* operator->() const - { - assert( hasValue ); - return &place; - } - - /** - * @brief Assignment operator - * - * Will copy held value from v, if any. - * - * @param v Value to copy from - */ - Optional& operator=( const Optional& v ) - { - if( this != &v ) - { - if( hasValue != v.hasValue ) - { - if( v.hasValue ) - new( &place ) A( v.place ); - else - place.~A(); - hasValue = v.hasValue; - } - else if( hasValue ) - { - place = v.place; - } - } - return *this; - } - - /** - * @brief Assignment move operator - * - * Will move held value from v, if any. In all cases v won't held a value - * after assignment is done. - * - * @param v Value to copy from - */ - Optional& operator=( Optional&& v ) - { - if( this != &v ) - { - if( hasValue != v.hasValue ) - { - if( v.hasValue ) - new( &place ) A( std::move( v.place ) ); - else - place.~A(); - hasValue = v.hasValue; - } - else if( hasValue ) - { - place = std::move( v.place ); - } - } - return *this; - } - - /** - * @brief Assignment operator from value of type held. - * - * Will initialize held value from given parameter a. - * Type of the parameter must be the same (barring cv convertions), - * as the type of the value held. - * - * @param a Value to copy from - */ - template < class U, class = typename std::enable_if< - std::is_same< typename std::remove_reference< U >::type, A >::value && - std::is_constructible< A, U >::value && - std::is_assignable< A&, U >::value >::type > - Optional& operator=( U&& a ) - { - if( hasValue ) - place = std::forward< U >( a ); - else - { - hasValue = true; - new( &place ) A( std::forward< U >( a ) ); - } - return *this; - } -}; - -#endif diff --git a/dali/dali-bridge/src/dbusLocators.hpp b/dali/dali-bridge/src/dbusLocators.hpp deleted file mode 100644 index 9b34bbe..0000000 --- a/dali/dali-bridge/src/dbusLocators.hpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2017 Samsung Electronics Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef DBUS_LOCATORS_HPP -#define DBUS_LOCATORS_HPP - -namespace dbusLocators -{ -namespace callmgr -{ -static constexpr const char* BUS = "org.tizen.callmgr"; -static constexpr const char* OBJ_PATH = "/org/tizen/callmgr"; -static constexpr const char* INTERFACE = "org.tizen.callmgr"; -} - -namespace accessibilityEMod -{ -static constexpr const char* BUS = "org.enlightenment.wm-screen-reader"; -static constexpr const char* OBJ_PATH = "/org/tizen/GestureNavigation"; -static constexpr const char* INTERFACE = "org.tizen.GestureNavigation"; - -static constexpr const char* ACCESSORIES_SP_ENABLED = "AccessoriesSwitchProviderEnabled"; -static constexpr const char* KEY_DOWN_SIGNAL = "KeyDown"; -static constexpr const char* KEY_UP_SIGNAL = "KeyUp"; - -static constexpr const char* SCREEN_SP_ENABLED = "ScreenSwitchProviderEnabled"; -static constexpr const char* MOUSE_DOWN_SIGNAL = "MouseDown"; -static constexpr const char* MOUSE_UP_SIGNAL = "MouseUp"; - -static constexpr const char* BACK_BUTTON_INTERCEPTION_ENABLED = "BackButtonInterceptionEnabled"; -static constexpr const char* BACK_BUTTON_DOWN_SIGNAL = "BackButtonDown"; -static constexpr const char* BACK_BUTTON_UP_SIGNAL = "BackButtonUp"; -} - -namespace freeDesktop -{ -static constexpr const char* BUS = "org.freedesktop.DBus"; -static constexpr const char* OBJ_PATH = "/org/freedesktop/DBus"; -static constexpr const char* INTERFACE = "org.freedesktop.DBus"; -static constexpr const char* PROPERTIES_INTERFACE = "org.freedesktop.DBus.Properties"; -static constexpr const char* GET_CONNECTION_UNIX_PROCESS_ID = "GetConnectionUnixProcessID"; -static constexpr const char* SET = "Set"; -static constexpr const char* GET = "Get"; -} - -namespace windowManager -{ -static constexpr const char* BUS = "org.enlightenment.wm"; -static constexpr const char* OBJ_PATH = "/org/enlightenment/wm"; -static constexpr const char* INTERFACE = "org.enlightenment.wm.proc"; -static constexpr const char* GET_VISIBLE_WIN_INFO = "GetVisibleWinInfo"; -static constexpr const char* GET_FOCUS_PROC = "GetFocusProc"; -} - -namespace atspi -{ -static constexpr const char* BUS = "org.a11y.Bus"; -static constexpr const char* OBJ_PATH = "/org/a11y/bus"; -static constexpr const char* BUS_INTERFACE = "org.a11y.Bus"; -static constexpr const char* STATUS_INTERFACE = "org.a11y.Status"; - -static constexpr const char* GET_ADDRESS = "GetAddress"; -static constexpr const char* IS_ENABLED = "IsEnabled"; -static constexpr const char* GET_ATTRIBUTES = "GetAttributes"; -static constexpr const char* DO_ACTION_NAME = "DoActionName"; -static constexpr const char* PARENT = "Parent"; -static constexpr const char* GET_MATCHES = "GetMatches"; -static constexpr const char* GET_INDEX_IN_PARENT = "GetIndexInParent"; -static constexpr const char* SELECT_CHILD = "SelectChild"; -static constexpr const char* NAME = "Name"; -static constexpr const char* GET_ROLE = "GetRole"; -static constexpr const char* CHILD_COUNT = "ChildCount"; -static constexpr const char* GET_CHILD_AT_INDEX = "GetChildAtIndex"; -static constexpr const char* GET_STATE = "GetState"; -static constexpr const char* GET_RELATION_SET = "GetRelationSet"; -static constexpr const char* GET_EXTENTS = "GetExtents"; -static constexpr const char* CURRENT_VALUE = "CurrentValue"; -static constexpr const char* MAXIMUM_VALUE = "MaximumValue"; -static constexpr const char* MINIMUM_VALUE = "MinimumValue"; -static constexpr const char* GET_INTERFACES = "GetInterfaces"; -static constexpr const char* GET_NAVIGABLE_AT_POINT = "GetNavigableAtPoint"; -} -} - -#endif diff --git a/dali/devel-api/adaptor-framework/accessibility.h b/dali/devel-api/adaptor-framework/accessibility.h deleted file mode 100644 index 15881b0..0000000 --- a/dali/devel-api/adaptor-framework/accessibility.h +++ /dev/null @@ -1,248 +0,0 @@ -#ifndef ATSPI_BRIDGE_HPP -#define ATSPI_BRIDGE_HPP - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Dali -{ -namespace Accessibility -{ -class Accessible; -class Text; -class Value; -class Component; -class Collection; -class Action; - -using ObjectsMapType = std::unordered_map< unsigned int, Accessible* >; - -struct DALI_IMPORT_API Bridge -{ - enum class Visibility - { - hidden, - thisThreadOnly, - allThreads - }; - enum class ForceUpResult - { - justStarted, - alreadyUp - }; - virtual ~Bridge() = default; - - virtual const std::string& GetBusName() const = 0; - virtual void SetApplicationChild( Accessible* ) = 0; - virtual void SetApplicationName( std::string ) = 0; - virtual Accessible* GetApplication() const = 0; - virtual Accessible* FindByPath( const std::string& ) const = 0; - virtual void ApplicationShown() = 0; - virtual void ApplicationHidden() = 0; - virtual void Initialize() = 0; - virtual ForceUpResult ForceUp() - { - if( data ) - return ForceUpResult::alreadyUp; - data = std::make_shared< Data >(); - data->bridge = this; - return ForceUpResult::justStarted; - } - virtual void ForceDown() - { - data = {}; - } - bool IsUp() const { return bool(data); } - - virtual void EmitStateChanged( Accessible* obj, State state, int val1, int val2 = 0 ) = 0; - virtual void Emit( Accessible* obj, WindowEvent we, unsigned int detail1 = 0 ) = 0; - virtual Consumed Emit( KeyEventType type, unsigned int keyCode, const std::string& keyName, unsigned int timeStamp, bool isText ) = 0; - void MakePublic( Visibility ); - - static Bridge* GetCurrentBridge(); - -protected: - struct Data - { - ObjectsMapType objects; - std::atomic< unsigned int > objectId; - std::string busName; - Accessible* root = nullptr; - Bridge* bridge = nullptr; - }; - std::shared_ptr< Data > data; - friend class Accessible; - - void RegisterOnBridge( Accessible* ); - void SetIsOnRootLevel( Accessible* ); -}; - -inline bool IsUp() -{ - return Bridge::GetCurrentBridge()->IsUp(); -} - -class DALI_IMPORT_API Accessible -{ -protected: - Accessible(); - - Accessible( const Accessible& ) = delete; - Accessible( Accessible&& ) = delete; - - Accessible& operator=( const Accessible& ) = delete; - Accessible& operator=( Accessible&& ) = delete; - -public: - virtual ~Accessible(); - - void EmitShowing( bool showing ); - void EmitVisible( bool visible ); - void EmitHighlighted( bool set ); - void Emit( WindowEvent we, unsigned int detail1 = 0 ); - - virtual std::string GetName() = 0; - virtual std::string GetDescription() = 0; - virtual Accessible* GetParent() = 0; - virtual size_t GetChildCount() = 0; - virtual std::vector< Accessible* > GetChildren(); - virtual Accessible* GetChildAtIndex( size_t index ) = 0; - virtual size_t GetIndexInParent() = 0; - virtual Role GetRole() = 0; - virtual std::string GetRoleName(); - virtual std::string GetLocalizedRoleName(); - virtual States GetStates() = 0; - virtual Attributes GetAttributes() = 0; - virtual bool IsProxy(); - virtual Address GetAddress(); - - std::vector< std::string > GetInterfaces(); - bool GetIsOnRootLevel() const { return isOnRootLevel; } - - static void RegisterControlAccessibilityGetter( std::function< Accessible*( Dali::Actor ) > ); - static Accessible* Get( Dali::Actor actor ); - -protected: - std::shared_ptr< Bridge::Data > GetBridgeData(); - -private: - friend class Bridge; - - std::weak_ptr< Bridge::Data > bridgeData; - ObjectsMapType::iterator it; - bool isOnRootLevel = false; -}; - -class DALI_IMPORT_API Action : public virtual Accessible -{ -public: - virtual std::string GetActionName( size_t index ) = 0; - virtual std::string GetLocalizedActionName( size_t index ) = 0; - virtual std::string GetActionDescription( size_t index ) = 0; - virtual std::string GetActionKeyBinding( size_t index ) = 0; - virtual size_t GetActionCount() = 0; - virtual bool DoAction( size_t index ) = 0; -}; - -class DALI_IMPORT_API Collection : public virtual Accessible -{ -public: -}; - -class DALI_IMPORT_API Component : public virtual Accessible -{ -public: - virtual Rectangle GetExtents( CoordType ctype ) = 0; - virtual ComponentLayer GetLayer() = 0; - virtual int GetMdiZOrder() = 0; - virtual bool GrabFocus() = 0; - virtual double GetAlpha() = 0; - virtual bool SetExtents( Rectangle rect, CoordType ctype ) = 0; - virtual bool GrabHighlight() = 0; - virtual bool ClearHighlight() = 0; - virtual int GetHighlightIndex() = 0; - virtual bool IsScrollable(); - virtual Component* GetAccessibleAtPoint( Point p, CoordType ctype ); - virtual bool Contains( Point p, CoordType ctype ); -}; - -class DALI_IMPORT_API Value : public virtual Accessible -{ -public: - virtual double GetMinimum() = 0; - virtual double GetCurrent() = 0; - virtual double GetMaximum() = 0; - virtual bool SetCurrent( double ) = 0; - virtual double GetMinimumIncrement() = 0; -}; - -class DALI_IMPORT_API Text : public virtual Accessible -{ -public: - virtual std::string GetText( size_t startOffset, size_t endOffset ) = 0; - virtual size_t GetCharacterCount() = 0; - virtual Range GetTextAtOffset( size_t offset, TextBoundary boundary ) = 0; - virtual Range GetSelection( size_t selectionNum ) = 0; - virtual bool RemoveSelection( size_t selectionNum ) = 0; - virtual bool SetSelection( size_t selectionNum, size_t startOffset, size_t endOffset ) = 0; -}; - -class DALI_IMPORT_API EditableText : public virtual Accessible -{ -public: - virtual bool CopyText( size_t startPosition, size_t endPosition ) = 0; - virtual bool CutText( size_t startPosition, size_t endPosition ) = 0; -}; - -/** - * @brief minimalistic, always empty Accessible object with settable address - * - * For those situations, where you want to return address in different bridge - * (embedding for example), but the object itself ain't planned to be used otherwise. - * This object has null parent, no children, empty name and so on - */ -class DALI_IMPORT_API EmptyAccessibleWithAddress : public virtual Accessible -{ -public: - EmptyAccessibleWithAddress() = default; - EmptyAccessibleWithAddress( Address address ) : address( std::move( address ) ) {} - - void SetAddress( Address address ) { this->address = std::move( address ); } - - std::string GetName() override { return ""; } - std::string GetDescription() override { return ""; } - Accessible* GetParent() override { return nullptr; } - size_t GetChildCount() override { return 0; } - std::vector< Accessible* > GetChildren() override { return {}; } - Accessible* GetChildAtIndex( size_t index ) override - { - throw AccessibleError{"out of bounds index (" + std::to_string( index ) + ") - no children"}; - } - size_t GetIndexInParent() override { return static_cast< size_t >( -1 ); } - Role GetRole() override { return {}; } - std::string GetRoleName() override; - States GetStates() override { return {}; } - Attributes GetAttributes() override { return {}; } - Address GetAddress() override - { - return address; - } - -private: - Address address; -}; - -std::shared_ptr< Bridge > CreateBridge(); -} -} - -#endif diff --git a/dali/devel-api/file.list b/dali/devel-api/file.list old mode 100755 new mode 100644 index e62fef3..696291a --- a/dali/devel-api/file.list +++ b/dali/devel-api/file.list @@ -67,9 +67,8 @@ devel_api_adaptor_framework_header_files = \ $(adaptor_devel_api_dir)/adaptor-framework/key-extension-plugin.h \ $(adaptor_devel_api_dir)/adaptor-framework/virtual-keyboard.h \ $(adaptor_devel_api_dir)/adaptor-framework/physical-keyboard.h \ - $(adaptor_devel_api_dir)/adaptor-framework/key-devel.h \ - $(adaptor_devel_api_dir)/adaptor-framework/accessibility.h - + $(adaptor_devel_api_dir)/adaptor-framework/key-devel.h + devel_api_text_abstraction_src_files = \ $(adaptor_devel_api_dir)/text-abstraction/bidirectional-support.cpp \ $(adaptor_devel_api_dir)/text-abstraction/font-client.cpp \ diff --git a/dali/internal/accessibility/accessibility-impl.cpp b/dali/internal/accessibility/accessibility-impl.cpp deleted file mode 100644 index 7e6fb7d..0000000 --- a/dali/internal/accessibility/accessibility-impl.cpp +++ /dev/null @@ -1,646 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace Dali::Accessibility; - -std::string EmptyAccessibleWithAddress::GetRoleName() -{ - return ""; -} - -std::string Accessible::GetLocalizedRoleName() -{ - return GetRoleName(); -} - -std::string Accessible::GetRoleName() -{ - switch( GetRole() ) - { - case Role::Invalid: - { - return "invalid"; - } - case Role::AcceleratorLabel: - { - return "accelerator label"; - } - case Role::Alert: - { - return "alert"; - } - case Role::Animation: - { - return "animation"; - } - case Role::Arrow: - { - return "arrow"; - } - case Role::Calendar: - { - return "calendar"; - } - case Role::Canvas: - { - return "canvas"; - } - case Role::CheckBox: - { - return "check box"; - } - case Role::CheckMenuItem: - { - return "check menu item"; - } - case Role::ColorChooser: - { - return "color chooser"; - } - case Role::ColumnHeader: - { - return "column header"; - } - case Role::ComboBox: - { - return "combo box"; - } - case Role::DateEditor: - { - return "date editor"; - } - case Role::DesktopIcon: - { - return "desktop icon"; - } - case Role::DesktopFrame: - { - return "desktop frame"; - } - case Role::Dial: - { - return "dial"; - } - case Role::Dialog: - { - return "dialog"; - } - case Role::DirectoryPane: - { - return "directory pane"; - } - case Role::DrawingArea: - { - return "drawing area"; - } - case Role::FileChooser: - { - return "file chooser"; - } - case Role::Filler: - { - return "filler"; - } - case Role::FocusTraversable: - { - return "focus traversable"; - } - case Role::FontChooser: - { - return "font chooser"; - } - case Role::Frame: - { - return "frame"; - } - case Role::GlassPane: - { - return "glass pane"; - } - case Role::HtmlContainer: - { - return "html container"; - } - case Role::Icon: - { - return "icon"; - } - case Role::Image: - { - return "image"; - } - case Role::InternalFrame: - { - return "internal frame"; - } - case Role::Label: - { - return "label"; - } - case Role::LayeredPane: - { - return "layered pane"; - } - case Role::List: - { - return "list"; - } - case Role::ListItem: - { - return "list item"; - } - case Role::Menu: - { - return "menu"; - } - case Role::MenuBar: - { - return "menu bar"; - } - case Role::MenuItem: - { - return "menu item"; - } - case Role::OptionPane: - { - return "option pane"; - } - case Role::PageTab: - { - return "page tab"; - } - case Role::PageTabList: - { - return "page tab list"; - } - case Role::Panel: - { - return "panel"; - } - case Role::PasswordText: - { - return "password text"; - } - case Role::PopupMenu: - { - return "popup menu"; - } - case Role::ProgressBar: - { - return "progress bar"; - } - case Role::PushButton: - { - return "push button"; - } - case Role::RadioButton: - { - return "radio button"; - } - case Role::RadioMenuItem: - { - return "radio menu item"; - } - case Role::RootPane: - { - return "root pane"; - } - case Role::RowHeader: - { - return "row header"; - } - case Role::ScrollBar: - { - return "scroll bar"; - } - case Role::ScrollPane: - { - return "scroll pane"; - } - case Role::Separator: - { - return "separator"; - } - case Role::Slider: - { - return "slider"; - } - case Role::SpinButton: - { - return "spin button"; - } - case Role::SplitPane: - { - return "split pane"; - } - case Role::StatusBar: - { - return "status bar"; - } - case Role::Table: - { - return "table"; - } - case Role::TableCell: - { - return "table cell"; - } - case Role::TableColumnHeader: - { - return "table column header"; - } - case Role::TableRowHeader: - { - return "table row header"; - } - case Role::TearoffMenuItem: - { - return "tearoff menu item"; - } - case Role::Terminal: - { - return "terminal"; - } - case Role::Text: - { - return "text"; - } - case Role::ToggleButton: - { - return "toggle button"; - } - case Role::ToolBar: - { - return "tool bar"; - } - case Role::ToolTip: - { - return "tool tip"; - } - case Role::Tree: - { - return "tree"; - } - case Role::TreeTable: - { - return "tree table"; - } - case Role::Unknown: - { - return "unknown"; - } - case Role::Viewport: - { - return "viewport"; - } - case Role::Window: - { - return "window"; - } - case Role::Extended: - { - return "extended"; - } - case Role::Header: - { - return "header"; - } - case Role::Footer: - { - return "footer"; - } - case Role::Paragraph: - { - return "paragraph"; - } - case Role::Ruler: - { - return "ruler"; - } - case Role::Application: - { - return "application"; - } - case Role::Autocomplete: - { - return "autocomplete"; - } - case Role::Editbar: - { - return "edit bar"; - } - case Role::Embedded: - { - return "embedded"; - } - case Role::Entry: - { - return "entry"; - } - case Role::Chart: - { - return "chart"; - } - case Role::Caption: - { - return "caution"; - } - case Role::DocumentFrame: - { - return "document frame"; - } - case Role::Heading: - { - return "heading"; - } - case Role::Page: - { - return "page"; - } - case Role::Section: - { - return "section"; - } - case Role::RedundantObject: - { - return "redundant object"; - } - case Role::Form: - { - return "form"; - } - case Role::Link: - { - return "link"; - } - case Role::InputMethodWindow: - { - return "input method window"; - } - case Role::TableRow: - { - return "table row"; - } - case Role::TreeItem: - { - return "tree item"; - } - case Role::DocumentSpreadsheet: - { - return "document spreadsheet"; - } - case Role::DocumentPresentation: - { - return "document presentation"; - } - case Role::DocumentText: - { - return "document text"; - } - case Role::DocumentWeb: - { - return "document web"; - } - case Role::DocumentEmail: - { - return "document email"; - } - case Role::Comment: - { - return "comment"; - } - case Role::ListBox: - { - return "list box"; - } - case Role::Grouping: - { - return "grouping"; - } - case Role::ImageMap: - { - return "image map"; - } - case Role::Notification: - { - return "notification"; - } - case Role::InfoBar: - { - return "info bar"; - } - case Role::LevelBar: - { - return "level bar"; - } - case Role::TitleBar: - { - return "title bar"; - } - case Role::BlockQuote: - { - return "block quote"; - } - case Role::Audio: - { - return "audio"; - } - case Role::Video: - { - return "video"; - } - case Role::Definition: - { - return "definition"; - } - case Role::Article: - { - return "article"; - } - case Role::Landmark: - { - return "landmark"; - } - case Role::Log: - { - return "log"; - } - case Role::Marquee: - { - return "marquee"; - } - case Role::Math: - { - return "math"; - } - case Role::Rating: - { - return "rating"; - } - case Role::Timer: - { - return "timer"; - } - case Role::Static: - { - return "static"; - } - case Role::MathFraction: - { - return "math fraction"; - } - case Role::MathRoot: - { - return "math root"; - } - case Role::Subscript: - { - return "subscript"; - } - case Role::Superscript: - { - return "superscript"; - } - case Role::_Count: - { - break; - } - } - return ""; -} - -void Bridge::SetIsOnRootLevel( Accessible* o ) -{ - o->isOnRootLevel = true; -} - -class NonControlAccessible : public virtual Accessible, public virtual Collection -{ -public: - Dali::Actor actor; - bool root = false; - - NonControlAccessible( Dali::Actor actor ) : actor( actor ) - { - Dali::Stage stage = Dali::Stage::GetCurrent(); - root = stage.GetRootLayer() == actor; - } - - std::string GetName() override - { - return actor.GetName(); - } - std::string GetDescription() override - { - return ""; - } - Accessible* GetParent() override - { - if( GetIsOnRootLevel() ) - { - auto b = GetBridgeData(); - return b->bridge->GetApplication(); - } - return Get( actor.GetParent() ); - } - size_t GetChildCount() override - { - return static_cast< size_t >( actor.GetChildCount() ); - } - Accessible* GetChildAtIndex( size_t index ) override - { - auto s = static_cast< size_t >( actor.GetChildCount() ); - if( index >= s ) - throw AccessibleError{"invalid index " + std::to_string( index ) + " for object with " + std::to_string( s ) + " children"}; - return Get( actor.GetChildAt( static_cast< unsigned int >( index ) ) ); - } - size_t GetIndexInParent() override - { - auto p = actor.GetParent(); - if( !p ) - return 0; - auto s = static_cast< size_t >( p.GetChildCount() ); - for( auto i = 0u; i < s; ++i ) - { - if( p.GetChildAt( i ) == actor ) - return i; - } - throw AccessibleError{"actor is not a child of it's parent"}; - } - Role GetRole() override - { - return root ? Role::Window : Role::RedundantObject; - } - States GetStates() override - { - States s; - if( root ) - { - s[State::Highlightable] = true; - s[State::Enabled] = true; - s[State::Sensitive] = true; - s[State::Showing] = true; - s[State::Active] = true; - } - else - { - auto t = GetParent()->GetStates(); - s[State::Showing] = t[State::Showing]; - s[State::Visible] = t[State::Visible]; - } - return s; - } - Attributes GetAttributes() override - { - Dali::TypeInfo type; - actor.GetTypeInfo( type ); - return { - {"t", type.GetName()}, - }; - } -}; - -using NonControlAccessiblesType = std::unordered_map< const Dali::RefObject*, std::unique_ptr< NonControlAccessible > >; -static NonControlAccessiblesType nonControlAccessibles; - -static std::function< Accessible*( Dali::Actor ) > convertingFunctor = []( Dali::Actor ) -> Accessible* { - return nullptr; -}; - -void Accessible::RegisterControlAccessibilityGetter( std::function< Accessible*( Dali::Actor ) > functor ) -{ - convertingFunctor = functor; -} - -Accessible* Accessible::Get( Dali::Actor actor ) -{ - if( !actor ) - { - return nullptr; - } - auto p = convertingFunctor( actor ); - if( !p ) - { - if( nonControlAccessibles.empty() ) - { - auto registry = Dali::Stage::GetCurrent().GetObjectRegistry(); - registry.ObjectDestroyedSignal().Connect( []( const Dali::RefObject* obj ) { - nonControlAccessibles.erase( obj ); - } ); - } - auto it = nonControlAccessibles.emplace( &actor.GetBaseObject(), nullptr ); - if( it.second ) - { - it.first->second.reset( new NonControlAccessible( actor ) ); - } - p = it.first->second.get(); - } - return p; -} diff --git a/dali/internal/accessibility/file.list b/dali/internal/accessibility/file.list index 2278f8e..8ccdb83 100644 --- a/dali/internal/accessibility/file.list +++ b/dali/internal/accessibility/file.list @@ -2,7 +2,6 @@ # module: accessibility, backend: common adaptor_accessibility_common_src_files=\ - ${adaptor_accessibility_dir}/accessibility-impl.cpp \ ${adaptor_accessibility_dir}/common/tts-player-factory.cpp \ ${adaptor_accessibility_dir}/common/tts-player-impl.cpp \ ${adaptor_accessibility_dir}/common/accessibility-adaptor-impl.cpp \ diff --git a/dali/internal/adaptor/common/adaptor-impl.cpp b/dali/internal/adaptor/common/adaptor-impl.cpp index f14eb95..3fa8e3f 100644 --- a/dali/internal/adaptor/common/adaptor-impl.cpp +++ b/dali/internal/adaptor/common/adaptor-impl.cpp @@ -55,15 +55,11 @@ #include #include -#include -#include #include +#include #include -#include -#include - using Dali::TextAbstraction::FontClient; namespace Dali @@ -247,38 +243,6 @@ void Adaptor::Initialize( Dali::Configuration::ContextLoss configuration ) } SetupSystemInformation(); - - Dali::Stage stage = Dali::Stage::GetCurrent(); - - char appname[4096] = {0}; - int pid = getpid(); - aul_app_get_pkgname_bypid( pid, appname, sizeof( appname ) ); - - accessibilityObserver.atspiBridge = Accessibility::CreateBridge(); - auto accessible = Accessibility::Accessible::Get( stage.GetRootLayer() ); - accessibilityObserver.atspiBridge->SetApplicationChild( accessible ); - accessibilityObserver.atspiBridge->SetApplicationName( appname ); - accessibilityObserver.atspiBridge->Initialize(); - - Dali::Stage::GetCurrent().KeyEventSignal().Connect( &accessibilityObserver, &AccessibilityObserver::OnAccessibleKeyEvent ); -} - -void Adaptor::AccessibilityObserver::OnAccessibleKeyEvent( const KeyEvent& event ) -{ - Accessibility::KeyEventType type; - if( event.state == KeyEvent::Down ) - { - type = Accessibility::KeyEventType::KeyPressed; - } - else if( event.state == KeyEvent::Up ) - { - type = Accessibility::KeyEventType::KeyReleased; - } - else - { - return; - } - atspiBridge->Emit( type, event.keyCode, event.keyPressedName, event.time, !event.keyPressed.empty() ); } Adaptor::~Adaptor() @@ -784,8 +748,6 @@ void Adaptor::OnWindowShown() { if ( PAUSED_WHILE_HIDDEN == mState ) { - accessibilityObserver.atspiBridge->ApplicationShown(); - // Adaptor can now be resumed mState = PAUSED; @@ -800,8 +762,6 @@ void Adaptor::OnWindowHidden() { if ( RUNNING == mState ) { - accessibilityObserver.atspiBridge->ApplicationHidden(); - Pause(); // Adaptor cannot be resumed until the window is shown diff --git a/dali/internal/adaptor/common/adaptor-impl.h b/dali/internal/adaptor/common/adaptor-impl.h index 2476136..27508e6 100644 --- a/dali/internal/adaptor/common/adaptor-impl.h +++ b/dali/internal/adaptor/common/adaptor-impl.h @@ -48,11 +48,6 @@ namespace Dali { -namespace Accessibility -{ -class Bridge; -} - class RenderSurface; class Window; @@ -608,18 +603,8 @@ private: // Data SocketFactory mSocketFactory; ///< Socket factory const bool mEnvironmentOptionsOwned:1; ///< Whether we own the EnvironmentOptions (and thus, need to delete it) bool mUseRemoteSurface; ///< whether the remoteSurface is used or not - - class AccessibilityObserver : public ConnectionTracker - { - public: - std::shared_ptr< Dali::Accessibility::Bridge > atspiBridge; - - void OnAccessibleKeyEvent( const KeyEvent& event ); - }; - AccessibilityObserver accessibilityObserver; - public: - inline static Adaptor& GetImplementation(Dali::Adaptor& adaptor) { return *adaptor.mImpl; } + inline static Adaptor& GetImplementation(Dali::Adaptor& adaptor) {return *adaptor.mImpl;} }; } // namespace Internal diff --git a/dali/public-api/adaptor-framework/accessibility.h b/dali/public-api/adaptor-framework/accessibility.h deleted file mode 100644 index 6faa6f5..0000000 --- a/dali/public-api/adaptor-framework/accessibility.h +++ /dev/null @@ -1,503 +0,0 @@ -#ifndef __DALI_ACCESSIBILITY_H__ -#define __DALI_ACCESSIBILITY_H__ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Dali -{ -class Actor; - -namespace Accessibility -{ -enum class RelationType -{ - FlowsFrom, - FlowsTo -}; - -enum class MatchType : int32_t -{ - Invalid, - All, - Any, - None, - Empty -}; - -enum class SortOrder : uint32_t -{ - Invalid, - Canonical, - Flow, - Tab, - ReverseCanonical, - ReverseFlow, - ReverseTab, - LastDefined -}; - -enum class CoordType -{ - Screen, - Window -}; - -enum class NeighborSearchDirection -{ - Forward, - Backward -}; - -enum class ComponentLayer -{ - Invalid, - Background, - Canvas, - Widget, - Mdi, - Popup, - Overlay, - Window, - LastDefined, -}; - -enum class Role : uint32_t -{ - Invalid, - AcceleratorLabel, - Alert, - Animation, - Arrow, - Calendar, - Canvas, - CheckBox, - CheckMenuItem, - ColorChooser, - ColumnHeader, - ComboBox, - DateEditor, - DesktopIcon, - DesktopFrame, - Dial, - Dialog, - DirectoryPane, - DrawingArea, - FileChooser, - Filler, - FocusTraversable, - FontChooser, - Frame, - GlassPane, - HtmlContainer, - Icon, - Image, - InternalFrame, - Label, - LayeredPane, - List, - ListItem, - Menu, - MenuBar, - MenuItem, - OptionPane, - PageTab, - PageTabList, - Panel, - PasswordText, - PopupMenu, - ProgressBar, - PushButton, - RadioButton, - RadioMenuItem, - RootPane, - RowHeader, - ScrollBar, - ScrollPane, - Separator, - Slider, - SpinButton, - SplitPane, - StatusBar, - Table, - TableCell, - TableColumnHeader, - TableRowHeader, - TearoffMenuItem, - Terminal, - Text, - ToggleButton, - ToolBar, - ToolTip, - Tree, - TreeTable, - Unknown, - Viewport, - Window, - Extended, - Header, - Footer, - Paragraph, - Ruler, - Application, - Autocomplete, - Editbar, - Embedded, - Entry, - Chart, - Caption, - DocumentFrame, - Heading, - Page, - Section, - RedundantObject, - Form, - Link, - InputMethodWindow, - TableRow, - TreeItem, - DocumentSpreadsheet, - DocumentPresentation, - DocumentText, - DocumentWeb, - DocumentEmail, - Comment, - ListBox, - Grouping, - ImageMap, - Notification, - InfoBar, - LevelBar, - TitleBar, - BlockQuote, - Audio, - Video, - Definition, - Article, - Landmark, - Log, - Marquee, - Math, - Rating, - Timer, - Static, - MathFraction, - MathRoot, - Subscript, - Superscript, - _Count, -}; - -enum class State : uint32_t -{ - Invalid, - Active, - Armed, - Busy, - Checked, - Collapsed, - Defunct, - Editable, - Enabled, - Expandable, - Expanded, - Focusable, - Focused, - HasTooltip, - Horizontal, - Iconified, - Modal, - MultiLine, - MultiSelectable, - Opaque, - Pressed, - Resizeable, - Selectable, - Selected, - Sensitive, - Showing, - SingleLine, - Stale, - Transient, - Vertical, - Visible, - ManagesDescendants, - Indeterminate, - Required, - Truncated, - Animated, - InvalidEntry, - SupportsAutocompletion, - SelectableText, - IsDefault, - Visited, - Checkable, - HasPopup, - ReadOnly, - Highlighted, - Highlightable, - _Count -}; - -enum class WindowEvent -{ - PropertyChange, - Minimize, - Maximize, - Restore, - Close, - Create, - Reparent, - DesktopCreate, - DesktopDestroy, - Destroy, - Activate, - Deactivate, - Raise, - Lower, - Move, - Resize, - Shade, - UuShade, - Restyle, -}; - -enum class TextBoundary : uint32_t -{ - Character, - WordStart, - WordEnd, - SentenceStart, - SentenceEnd, - LineStart, - LineEnd, - _Count -}; - -template < size_t I, typename S > -class BitStates -{ - std::array< uint32_t, I > data; - -public: - BitStates() - { - for( auto& u : data ) - u = 0; - } - explicit BitStates( std::array< uint32_t, I > d ) - { - for( auto i = 0u; i < I; ++i ) - data[i] = d[i]; - } - explicit BitStates( std::array< int32_t, I > d ) - { - for( auto i = 0u; i < I; ++i ) - data[i] = static_cast< uint32_t >( d[i] ); - } - - struct reference - { - std::array< uint32_t, I >& data; - size_t pos; - bool operator=( reference r ) - { - return ( *this ) = static_cast< bool >( r ); - } - bool operator=( bool v ) - { - if( v ) - data[pos / 32] |= 1 << ( pos & 31 ); - else - data[pos / 32] &= ~( 1 << ( pos & 31 ) ); - return v; - } - operator bool() const - { - auto i = static_cast< size_t >( pos ); - return ( data[i / 32] & ( 1 << ( i & 31 ) ) ) != 0; - } - }; - reference operator[]( S index ) { return {data, static_cast< size_t >( index )}; } - bool operator[]( S index ) const - { - auto i = static_cast< size_t >( index ); - return ( data[i / 32] & ( 1 << ( i & 31 ) ) ) != 0; - } - std::array< uint32_t, I > GetRawData() const { return data; } - - BitStates operator|( BitStates b ) const - { - BitStates r; - for( auto i = 0u; i < I; ++i ) - r.data[i] = data[i] | b.data[i]; - return r; - } - BitStates operator&( BitStates b ) const - { - BitStates r; - for( auto i = 0u; i < I; ++i ) - r.data[i] = data[i] & b.data[i]; - return r; - } - bool operator==( BitStates b ) const - { - for( auto i = 0u; i < I; ++i ) - if( data[i] != b.data[i] ) - return false; - return true; - } - explicit operator bool() const - { - for( auto& u : data ) - if( u ) - return true; - return false; - } -}; - -using States = BitStates< 2, State >; -using Attributes = std::unordered_map< std::string, std::string >; - -class DALI_IMPORT_API Address -{ -public: - Address() = default; - Address( std::string bus, std::string path ) : bus( std::move( bus ) ), path( std::move( path ) ) {} - - explicit operator bool() const { return !path.empty(); } - std::string ToString() const - { - return *this ? bus + ":" + path : "::null"; - } - const std::string& GetBus() const { return bus; } - const std::string& GetPath() const { return path; } - -private: - std::string bus, path; -}; - -enum class KeyEventType -{ - KeyPressed, - KeyReleased, -}; -enum class Consumed -{ - No, - Yes -}; -struct DALI_IMPORT_API Point -{ - int x = 0; - int y = 0; - - Point() = default; - Point( int x, int y ) : x( x ), y( y ) {} - - bool operator==( Point p ) const - { - return x == p.x && y == p.y; - } - bool operator!=( Point p ) const - { - return !( *this == p ); - } -}; - -struct DALI_IMPORT_API Size -{ - int width = 0; - int height = 0; - - Size() = default; - Size( int w, int h ) : width( w ), height( h ) {} - - bool operator==( Size p ) const - { - return width == p.width && height == p.height; - } - bool operator!=( Size p ) const - { - return !( *this == p ); - } -}; - -struct DALI_IMPORT_API Rectangle -{ - Point position; - Size size; - - bool operator==( Rectangle p ) const - { - return position == p.position && size == p.size; - } - bool operator!=( Rectangle p ) const - { - return !( *this == p ); - } -}; -struct DALI_IMPORT_API Range -{ - int startOffset = 0; - int endOffset = 0; - std::string content; - - Range() = default; - Range( size_t start, size_t end ) : startOffset( start ), endOffset( end ) - { - } - Range( size_t start, size_t end, std::string content ) : startOffset( start ), endOffset( end ), content( content ) - { - } -}; - -class DALI_IMPORT_API AccessibleError : public std::exception -{ -public: - AccessibleError( std::string msg ) : msg( std::move( msg ) ) {} - const char* what() const noexcept override { return msg.c_str(); } - -private: - std::string msg; -}; -} -} - -namespace std -{ -template <> -struct hash< Dali::Accessibility::Point > -{ - size_t operator()( Dali::Accessibility::Point p ) - { - return static_cast< size_t >( p.x ) ^ ( static_cast< size_t >( p.y ) * 11 ); - } -}; -template <> -struct hash< Dali::Accessibility::Size > -{ - size_t operator()( Dali::Accessibility::Size p ) - { - return static_cast< size_t >( p.width ) ^ ( static_cast< size_t >( p.height ) * 11 ); - } -}; -template <> -struct hash< Dali::Accessibility::Rectangle > -{ - size_t operator()( Dali::Accessibility::Rectangle p ) - { - return hash< Dali::Accessibility::Point >()( p.position ) ^ ( hash< Dali::Accessibility::Size >()( p.size ) * 11 ); - } -}; -} - -#endif diff --git a/dali/public-api/file.list b/dali/public-api/file.list index fc24b4f..2f1471d 100644 --- a/dali/public-api/file.list +++ b/dali/public-api/file.list @@ -21,7 +21,6 @@ public_api_adaptor_framework_header_files = \ $(adaptor_public_api_dir)/adaptor-framework/device-status.h \ $(adaptor_public_api_dir)/adaptor-framework/input-method.h \ $(adaptor_public_api_dir)/adaptor-framework/key.h \ - $(adaptor_public_api_dir)/adaptor-framework/accessibility.h \ $(adaptor_public_api_dir)/adaptor-framework/key-grab.h \ $(adaptor_public_api_dir)/adaptor-framework/style-change.h \ $(adaptor_public_api_dir)/adaptor-framework/timer.h \ diff --git a/packaging/dali-adaptor.spec b/packaging/dali-adaptor.spec old mode 100755 new mode 100644