$(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) \
$(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) \
$(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) \
$(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) \
$(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) \
$(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) \
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
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
+++ /dev/null
-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
+++ /dev/null
-#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;
-}
+++ /dev/null
-#include "BridgeAccessible.hpp"
-#include <iostream>
-
-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() )};
-}
+++ /dev/null
-#ifndef BRIDGE_ACCESSIBLE_HPP
-#define BRIDGE_ACCESSIBLE_HPP
-
-#include "BridgeBase.hpp"
-#include <array>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-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
+++ /dev/null
-#include "BridgeAction.hpp"
-#include <iostream>
-
-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 + "'"};
-}
+++ /dev/null
-#ifndef BRIDGE_ACTION_HPP
-#define BRIDGE_ACTION_HPP
-
-#include "BridgeBase.hpp"
-
-#include <tuple>
-#include <vector>
-
-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
+++ /dev/null
-#include "BridgeBase.hpp"
-#include <atomic>
-#include <cstdlib>
-
-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() );
-}
+++ /dev/null
-#ifndef BRIDGE_HPP
-#define BRIDGE_HPP
-
-#include "Common.hpp"
-#include <memory>
-
-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
+++ /dev/null
-#include "BridgeCollection.hpp"
-#include <algorithm>
-#include <iostream>
-#include <unordered_set>
-#include <vector>
-
-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;
-}
+++ /dev/null
-#ifndef BRIDGE_COLLECTION_HPP
-#define BRIDGE_COLLECTION_HPP
-
-#include "BridgeBase.hpp"
-
-#include <array>
-#include <tuple>
-#include <unordered_map>
-#include <vector>
-
-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
+++ /dev/null
-#include "BridgeComponent.hpp"
-#include <iostream>
-
-#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();
-}
+++ /dev/null
-#ifndef BRIDGE_COMPONENT_HPP
-#define BRIDGE_COMPONENT_HPP
-
-#include "BridgeBase.hpp"
-#include <array>
-#include <string>
-#include <tuple>
-#include <unordered_map>
-#include <vector>
-
-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
+++ /dev/null
-#include "BridgeEditableText.hpp"
-
-#include <dali/internal/clipboard/common/clipboard-impl.h>
-#include <dali/internal/input/common/imf-manager-impl.h>
-
-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;
-}
+++ /dev/null
-#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
+++ /dev/null
-#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 <iostream>
-
-#include <dali/integration-api/debug.h>
-
-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 {};
- }
-}
+++ /dev/null
-#ifndef BRIDGE_IMPL_HPP
-#define BRIDGE_IMPL_HPP
-
-#endif
+++ /dev/null
-#include "BridgeObject.hpp"
-#include <iostream>
-#include <string>
-
-using namespace Dali::Accessibility;
-
-BridgeObject::BridgeObject()
-{
-}
-
-void BridgeObject::RegisterInterfaces()
-{
- // DBus::DBusInterfaceDescription desc{ ATSPI_DBUS_INTERFACE_EVENT_OBJECT };
- // stateChanged = addSignal<std::string, int, int, DBus::EldbusVariant<int>, 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"} );
- }
-}
+++ /dev/null
-#ifndef BRIDGE_OBJECT_HPP
-#define BRIDGE_OBJECT_HPP
-
-#include "BridgeBase.hpp"
-#include <array>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-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
+++ /dev/null
-#include "BridgeText.hpp"
-
-#include <dali/internal/input/common/imf-manager-impl.h>
-
-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 );
-}
+++ /dev/null
-#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
+++ /dev/null
-#include "BridgeValue.hpp"
-#include <iostream>
-
-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();
-}
+++ /dev/null
-#ifndef BRIDGE_VALUE_HPP
-#define BRIDGE_VALUE_HPP
-
-#include "BridgeBase.hpp"
-#include <array>
-#include <string>
-#include <tuple>
-#include <unordered_map>
-#include <vector>
-
-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
+++ /dev/null
-#ifndef COMMON_HPP
-#define COMMON_HPP
-
-#include "DBus.hpp"
-#include "dbusLocators.hpp"
-#include <dali/devel-api/adaptor-framework/accessibility.h>
-#include <dali/integration-api/debug.h>
-#include <iomanip>
-#include <sstream>
-#include <string>
-
-#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
+++ /dev/null
-#include "Common.hpp"
-#include <iostream>
-
-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;
-}
+++ /dev/null
-/*
- * 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 <sstream>
-//#include "Atspi.hpp"
-#include <iostream>
-#include <mutex>
-
-#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() );
-}
+++ /dev/null
-/*
- * 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 <Eldbus.h>
-#include <memory>
-
-#include "Optional.hpp"
-#include <array>
-#include <atomic>
-#include <cstdint>
-#include <map>
-#include <sstream>
-#include <string>
-#include <thread>
-#include <tuple>
-#include <type_traits>
-#include <unordered_map>
-#include <vector>
-
-#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<std::tuple<int, float>(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<int, float>, which gives signature <B>(id)</B> - std::tuple acts
- * as struct container. Returned value v will be of type ValueOrError<std::tuple<int, float>>.\n
- * Slightly different (asynchronous) example:
- * \code{.cpp}
- * auto dbus = DBusClient{ ... };
- * std::function<void(ValueOrError<int, float>)> callback;
- * dbus.method<ValueOrError<int, float>(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<void> 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<Eldbus_Connection>;
-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<std::string, std::string, std::tuple<std::string>> \endcode
- * While (ss(s)) is represented as
- * \code{.cpp} std::tuple<std::string, std::string, std::tuple<std::string>> \endcode
- * or
- * \code{.cpp} ValueOrError<std::tuple<std::string, std::string, std::tuple<std::string>>> \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<void> type
- */
-template <>
-struct signature< ValueOrError< void > >
-{
- /**
- * @brief Returns name of type marshalled, for informative purposes
- */
- static std::string name()
- {
- return "ValueOrError<void>";
- }
- /**
- * @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<key, value> 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<key, value> 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<std::shared_ptr<AtspiAccessible>> {
-// using subtype = std::pair<std::string, std::string>;
-
-// /**
-// * @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<AtspiAccessible> &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<subtype>::set(iter, { bus, std::string{prefixPath} + path });
-// g_free(path);
-// g_free(bus);
-// } else {
-// signature<subtype>::set(iter, { {}, std::string{nullPath} });
-// }
-// }
-// /**
-// * @brief Marshals value from marshalled type into variable v
-// */
-// static bool get(Eldbus_Message_Iter *iter, std::shared_ptr<AtspiAccessible> &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<int(float, float)> \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<void> 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<int(float, float)> \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<int(float, float)> \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<void(void)> done_cb) {
- * // process something later on
- * DBusServer::getCurrentObjectPath(); // this will return empty string
- * };
- * interface.addAsyncMethod<void()>("m", [=](std::function<void(void)> 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<void(void)> done_cb) {
- * // process something later on
- * DBusServer::getCurrentObjectPath(); // this will return empty string
- * };
- * interface.addAsyncMethod<void()>("m", [=](std::function<void(void)> 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
+++ /dev/null
-/*
- * 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<int> v = ...;
- * if (v) ... // if v has value, then do something
- * - accessing value (via operator *), for example:
- * Optional<int> 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 <cassert>
-#include <new>
-#include <type_traits>
-#include <utility>
-
-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<int> 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
+++ /dev/null
-/*
- * 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
+++ /dev/null
-#ifndef ATSPI_BRIDGE_HPP
-#define ATSPI_BRIDGE_HPP
-
-#include <dali/public-api/actors/actor.h>
-#include <dali/public-api/adaptor-framework/accessibility.h>
-
-#include <atomic>
-#include <bitset>
-#include <exception>
-#include <functional>
-#include <memory>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-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
$(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 \
+++ /dev/null
-#include <dali/devel-api/adaptor-framework/accessibility.h>
-#include <dali/integration-api/debug.h>
-#include <dali/public-api/actors/actor.h>
-#include <dali/public-api/actors/layer.h>
-#include <dali/public-api/common/stage.h>
-#include <dali/public-api/object/base-object.h>
-#include <dali/public-api/object/object-registry.h>
-#include <dali/public-api/object/type-info.h>
-#include <dali/public-api/object/type-registry-helper.h>
-
-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;
-}
# 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 \
#include <dali/internal/window-system/common/display-connection.h>
#include <dali/internal/window-system/common/window-impl.h>
-#include <dali/devel-api/adaptor-framework/accessibility.h>
-#include <dali/devel-api/adaptor-framework/image-loading.h>
#include <dali/internal/system/common/logging.h>
+#include <dali/devel-api/adaptor-framework/image-loading.h>
#include <dali/internal/system/common/locale-utils.h>
-#include <aul.h>
-#include <unistd.h>
-
using Dali::TextAbstraction::FontClient;
namespace Dali
}
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()
{
if ( PAUSED_WHILE_HIDDEN == mState )
{
- accessibilityObserver.atspiBridge->ApplicationShown();
-
// Adaptor can now be resumed
mState = PAUSED;
{
if ( RUNNING == mState )
{
- accessibilityObserver.atspiBridge->ApplicationHidden();
-
Pause();
// Adaptor cannot be resumed until the window is shown
namespace Dali
{
-namespace Accessibility
-{
-class Bridge;
-}
-
class RenderSurface;
class Window;
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
+++ /dev/null
-#ifndef __DALI_ACCESSIBILITY_H__
-#define __DALI_ACCESSIBILITY_H__
-
-#include <dali/public-api/actors/actor.h>
-
-#include <atomic>
-#include <bitset>
-#include <exception>
-#include <functional>
-#include <memory>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-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
$(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 \