[Tizen][ATSPI] Accessibility initial implementation
[platform/core/uifw/dali-adaptor.git] / dali / dali-bridge / src / Common.hpp
1 #ifndef COMMON_HPP
2 #define COMMON_HPP
3
4 #include "DBus.hpp"
5 #include "dbusLocators.hpp"
6 #include <dali/devel-api/adaptor-framework/accessibility.h>
7 #include <dali/integration-api/debug.h>
8 #include <iomanip>
9 #include <sstream>
10 #include <string>
11
12 #define A11Y_DBUS_NAME "org.a11y.Bus"
13 #define A11Y_DBUS_PATH "/org/a11y/bus"
14 #define A11Y_DBUS_STATUS_INTERFACE "org.a11y.Status"
15 #define ATSPI_DBUS_NAME_REGISTRY "org.a11y.atspi.Registry"
16 #define ATSPI_DBUS_PATH_ROOT "/org/a11y/atspi/accessible/root"
17 #define ATSPI_DBUS_INTERFACE_SOCKET "org.a11y.atspi.Socket"
18 #define ATSPI_PATH "/org/a11y/atspi/accessible"
19 #define ATSPI_DBUS_INTERFACE_ACCESSIBLE "org.a11y.atspi.Accessible"
20 #define ATSPI_DBUS_INTERFACE_ACTION "org.a11y.atspi.Action"
21 #define ATSPI_DBUS_INTERFACE_APPLICATION "org.a11y.atspi.Application"
22 #define ATSPI_DBUS_INTERFACE_COLLECTION "org.a11y.atspi.Collection"
23 #define ATSPI_DBUS_INTERFACE_COMPONENT "org.a11y.atspi.Component"
24 #define ATSPI_DBUS_INTERFACE_DOCUMENT "org.a11y.atspi.Document"
25 #define ATSPI_DBUS_INTERFACE_EDITABLE_TEXT "org.a11y.atspi.EditableText"
26 #define ATSPI_DBUS_INTERFACE_EVENT_KEYBOARD "org.a11y.atspi.Event.Keyboard"
27 #define ATSPI_DBUS_INTERFACE_EVENT_MOUSE "org.a11y.atspi.Event.Mouse"
28 #define ATSPI_DBUS_INTERFACE_EVENT_OBJECT "org.a11y.atspi.Event.Object"
29 #define ATSPI_DBUS_INTERFACE_HYPERLINK "org.a11y.atspi.Hyperlink"
30 #define ATSPI_DBUS_INTERFACE_HYPERTEXT "org.a11y.atspi.Hypertext"
31 #define ATSPI_DBUS_INTERFACE_IMAGE "org.a11y.atspi.Image"
32 #define ATSPI_DBUS_INTERFACE_SELECTION "org.a11y.atspi.Selection"
33 #define ATSPI_DBUS_INTERFACE_TABLE "org.a11y.atspi.Table"
34 #define ATSPI_DBUS_INTERFACE_TABLE_CELL "org.a11y.atspi.TableCell"
35 #define ATSPI_DBUS_INTERFACE_TEXT "org.a11y.atspi.Text"
36 #define ATSPI_DBUS_INTERFACE_VALUE "org.a11y.atspi.Value"
37 #define ATSPI_DBUS_INTERFACE_SOCKET "org.a11y.atspi.Socket"
38 #define ATSPI_DBUS_INTERFACE_EVENT_WINDOW "org.a11y.atspi.Event.Window"
39
40 #define ATSPI_DBUS_PATH_DEC "/org/a11y/atspi/registry/deviceeventcontroller"
41 #define ATSPI_DBUS_INTERFACE_DEC "org.a11y.atspi.DeviceEventController"
42 #define ATSPI_DBUS_INTERFACE_DEVICE_EVENT_LISTENER "org.a11y.atspi.DeviceEventListener"
43
44 namespace DBus
45 {
46 class CurrentBridgePtr
47 {
48   static Dali::Accessibility::Bridge*& get()
49   {
50     static thread_local Dali::Accessibility::Bridge* b = nullptr;
51     return b;
52   }
53   Dali::Accessibility::Bridge* prev;
54   CurrentBridgePtr( const CurrentBridgePtr& ) = delete;
55   CurrentBridgePtr( CurrentBridgePtr&& ) = delete;
56   CurrentBridgePtr& operator=( const CurrentBridgePtr& ) = delete;
57   CurrentBridgePtr& operator=( CurrentBridgePtr&& ) = delete;
58
59 public:
60   CurrentBridgePtr( Dali::Accessibility::Bridge* b ) : prev( get() ) { get() = b; }
61   ~CurrentBridgePtr() { get() = prev; }
62
63   static Dali::Accessibility::Bridge* current() { return get(); }
64 };
65 namespace detail
66 {
67 template < typename T >
68 struct signature_accessible_impl
69 {
70   using subtype = std::pair< std::string, DBus::ObjectPath >;
71
72   /**
73       * @brief Returns name of type marshalled, for informative purposes
74       */
75   static std::string name()
76   {
77     return "AtspiAccessiblePtr";
78   }
79   /**
80       * @brief Returns DBUS' signature of type marshalled
81       */
82   static std::string sig()
83   {
84     return "(so)";
85   }
86   /**
87       * @brief Marshals value v as marshalled type into message
88       */
89   static void set( Eldbus_Message_Iter* iter, T* t )
90   {
91     const auto prefixPath = "/org/a11y/atspi/accessible/";
92     const auto nullPath = "/org/a11y/atspi/null";
93
94     if( t )
95     {
96       auto v = t->GetAddress();
97       signature< subtype >::set( iter, {v.GetBus(), DBus::ObjectPath{std::string{prefixPath} + v.GetPath()}} );
98     }
99     else
100     {
101       signature< subtype >::set( iter, {"", DBus::ObjectPath{nullPath}} );
102     }
103   }
104   /**
105       * @brief Marshals value from marshalled type into variable v
106       */
107   static bool get( Eldbus_Message_Iter* iter, T*& v )
108   {
109     const auto prefixPath = "/org/a11y/atspi/accessible/";
110     const auto nullPath = "/org/a11y/atspi/null";
111     subtype tmp;
112     if( !signature< subtype >::get( iter, tmp ) )
113       return false;
114     if( tmp.second.value == nullPath )
115     {
116       v = nullptr;
117       return true;
118     }
119     if( tmp.second.value.substr( 0, strlen( prefixPath ) ) != prefixPath )
120       return false;
121     auto b = CurrentBridgePtr::current();
122     if( b->GetBusName() != tmp.first )
123       return false;
124     v = b->FindByPath( tmp.second.value.substr( strlen( prefixPath ) ) );
125     return v != nullptr;
126   }
127 };
128 template <>
129 struct signature< Dali::Accessibility::Accessible* > : public signature_accessible_impl< Dali::Accessibility::Accessible >
130 {
131 };
132
133 template <>
134 struct signature< Dali::Accessibility::Address >
135 {
136   using subtype = std::pair< std::string, DBus::ObjectPath >;
137
138   /**
139       * @brief Returns name of type marshalled, for informative purposes
140       */
141   static std::string name()
142   {
143     return "AtspiAccessiblePtr";
144   }
145   /**
146       * @brief Returns DBUS' signature of type marshalled
147       */
148   static std::string sig()
149   {
150     return "(so)";
151   }
152   /**
153       * @brief Marshals value v as marshalled type into message
154       */
155   static void set( Eldbus_Message_Iter* iter, const Dali::Accessibility::Address& v )
156   {
157     const auto prefixPath = "/org/a11y/atspi/accessible/";
158     const auto nullPath = "/org/a11y/atspi/null";
159
160     if( v )
161     {
162       signature< subtype >::set( iter, {v.GetBus(), DBus::ObjectPath{std::string{prefixPath} + v.GetPath()}} );
163     }
164     else
165     {
166       signature< subtype >::set( iter, {v.GetBus(), DBus::ObjectPath{nullPath}} );
167     }
168   }
169   /**
170       * @brief Marshals value from marshalled type into variable v
171       */
172   static bool get( Eldbus_Message_Iter* iter, Dali::Accessibility::Address& v )
173   {
174     const auto prefixPath = "/org/a11y/atspi/accessible/";
175     const auto nullPath = "/org/a11y/atspi/null";
176     subtype tmp;
177     if( !signature< subtype >::get( iter, tmp ) )
178       return false;
179     if( tmp.second.value == nullPath )
180     {
181       v = {};
182       return true;
183     }
184     if( tmp.second.value.substr( 0, strlen( prefixPath ) ) != prefixPath )
185       return false;
186     v = {std::move( tmp.first ), tmp.second.value.substr( strlen( prefixPath ) )};
187     return true;
188   }
189 };
190 template <>
191 struct signature< Dali::Accessibility::States >
192 {
193   using subtype = std::array< uint32_t, 2 >;
194
195   /**
196       * @brief Returns name of type marshalled, for informative purposes
197       */
198   static std::string name()
199   {
200     return signature< subtype >::name();
201   }
202   /**
203       * @brief Returns DBUS' signature of type marshalled
204       */
205   static std::string sig()
206   {
207     return signature< subtype >::sig();
208   }
209   /**
210       * @brief Marshals value v as marshalled type into message
211       */
212   static void set( Eldbus_Message_Iter* iter, const Dali::Accessibility::States& v )
213   {
214     signature< subtype >::set( iter, v.GetRawData() );
215   }
216   /**
217       * @brief Marshals value from marshalled type into variable v
218       */
219   static bool get( Eldbus_Message_Iter* iter, Dali::Accessibility::States& v )
220   {
221     subtype tmp;
222     if( !signature< subtype >::get( iter, tmp ) )
223       return false;
224     v = Dali::Accessibility::States{tmp};
225     return true;
226   }
227 };
228 }
229 }
230
231 struct _Logger
232 {
233   const char* file;
234   int line;
235   std::ostringstream tmp;
236
237   _Logger( const char* f, int l ) : file( f ), line( l ) {}
238   ~_Logger()
239   {
240     Dali::Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo, "%s:%d: %s", file, line, tmp.str().c_str() );
241   }
242   template < typename T >
243   _Logger& operator<<( T&& t )
244   {
245     tmp << std::forward< T >( t );
246     return *this;
247   }
248 };
249
250 struct _LoggerScope
251 {
252   const char* file;
253   int line;
254
255   _LoggerScope( const char* f, int l ) : file( f ), line( l )
256   {
257     Dali::Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo, "%s:%d: +", file, line );
258   }
259   ~_LoggerScope()
260   {
261     Dali::Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo, "%s:%d: -", file, line );
262   }
263 };
264 #define LOG() _Logger( __FILE__, __LINE__ )
265 #define SCOPE() _LoggerScope _l##__LINE__( __FILE__, __LINE__ )
266
267 #endif