[ATSPI] Hypertext and Hyperlink interface support - dbus glue-code
[platform/core/uifw/dali-adaptor.git] / dali / internal / accessibility / bridge / accessible.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19
20 //INTERNAL INCLUDES
21 #include <dali/internal/accessibility/bridge/accessibility-common.h>
22 #include <third-party/libunibreak/linebreak.h>
23 #include <third-party/libunibreak/wordbreak.h>
24
25 using namespace Dali::Accessibility;
26
27 std::vector<std::string> Accessible::GetInterfaces()
28 {
29   std::vector<std::string> tmp;
30   tmp.push_back(AtspiDbusInterfaceAccessible);
31   if(dynamic_cast<Collection*>(this))
32   {
33     tmp.push_back(AtspiDbusInterfaceCollection);
34   }
35   if(dynamic_cast<Text*>(this))
36   {
37     tmp.push_back(AtspiDbusInterfaceText);
38   }
39   if(dynamic_cast<EditableText*>(this))
40   {
41     tmp.push_back(AtspiDbusInterfaceEditableText);
42   }
43   if(dynamic_cast<Value*>(this))
44   {
45     tmp.push_back(AtspiDbusInterfaceValue);
46   }
47   if(dynamic_cast<Component*>(this))
48   {
49     tmp.push_back(AtspiDbusInterfaceComponent);
50   }
51   if(auto action = dynamic_cast<Action*>(this))
52   {
53     if(action->GetActionCount() > 0)
54     {
55       tmp.push_back(AtspiDbusInterfaceAction);
56     }
57   }
58   if(dynamic_cast<Selection*>(this))
59   {
60     tmp.push_back(AtspiDbusInterfaceSelection);
61   }
62   if(dynamic_cast<Hypertext*>(this))
63   {
64     tmp.push_back(AtspiDbusInterfaceHypertext);
65   }
66   if(dynamic_cast<Hyperlink*>(this))
67   {
68     tmp.push_back(AtspiDbusInterfaceHyperlink);
69   }
70   return tmp;
71 }
72
73 Accessible::Accessible()
74 {
75 }
76
77 Accessible::~Accessible()
78 {
79   auto handle = mBridgeData.lock();
80   if(handle)
81   {
82     handle->mKnownObjects.erase(this);
83   }
84 }
85
86 void Accessible::EmitActiveDescendantChanged(Accessible* obj, Accessible* child)
87 {
88   if(auto bridgeData = GetBridgeData())
89   {
90     bridgeData->mBridge->EmitActiveDescendantChanged(obj, child);
91   }
92 }
93
94 void Accessible::EmitStateChanged(State state, int newValue, int reserved)
95 {
96   if(auto bridgeData = GetBridgeData())
97   {
98     bridgeData->mBridge->EmitStateChanged(this, state, newValue, reserved);
99   }
100 }
101
102 void Accessible::EmitShowing(bool isShowing)
103 {
104   if(auto bridgeData = GetBridgeData())
105   {
106     bridgeData->mBridge->EmitStateChanged(this, State::SHOWING, isShowing ? 1 : 0, 0);
107   }
108 }
109
110 void Accessible::EmitVisible(bool isVisible)
111 {
112   if(auto bridgeData = GetBridgeData())
113   {
114     bridgeData->mBridge->EmitStateChanged(this, State::VISIBLE, isVisible ? 1 : 0, 0);
115   }
116 }
117
118 void Accessible::EmitHighlighted(bool isHighlighted)
119 {
120   if(auto bridgeData = GetBridgeData())
121   {
122     bridgeData->mBridge->EmitStateChanged(this, State::HIGHLIGHTED, isHighlighted ? 1 : 0, 0);
123   }
124 }
125
126 void Accessible::EmitFocused(bool isFocused)
127 {
128   if(auto bridgeData = GetBridgeData())
129   {
130     bridgeData->mBridge->EmitStateChanged(this, State::FOCUSED, isFocused ? 1 : 0, 0);
131   }
132 }
133 void Accessible::EmitTextInserted(unsigned int position, unsigned int length, const std::string& content)
134 {
135   if(auto bridgeData = GetBridgeData())
136   {
137     bridgeData->mBridge->EmitTextChanged(this, TextChangedState::INSERTED, position, length, content);
138   }
139 }
140 void Accessible::EmitTextDeleted(unsigned int position, unsigned int length, const std::string& content)
141 {
142   if(auto bridgeData = GetBridgeData())
143   {
144     bridgeData->mBridge->EmitTextChanged(this, TextChangedState::DELETED, position, length, content);
145   }
146 }
147 void Accessible::EmitTextCursorMoved(unsigned int cursorPosition)
148 {
149   if(auto bridgeData = GetBridgeData())
150   {
151     bridgeData->mBridge->EmitCursorMoved(this, cursorPosition);
152   }
153 }
154
155 void Accessible::EmitMovedOutOfScreen(ScreenRelativeMoveType type)
156 {
157   if(auto bridgeData = GetBridgeData())
158   {
159     bridgeData->mBridge->EmitMovedOutOfScreen(this, type);
160   }
161 }
162
163 void Accessible::Emit(WindowEvent event, unsigned int detail)
164 {
165   if(auto bridgeData = GetBridgeData())
166   {
167     bridgeData->mBridge->Emit(this, event, detail);
168   }
169 }
170 void Accessible::Emit(ObjectPropertyChangeEvent event)
171 {
172   if(auto bridgeData = GetBridgeData())
173   {
174     bridgeData->mBridge->Emit(this, event);
175   }
176 }
177
178 void Accessible::EmitBoundsChanged(Rect<> rect)
179 {
180   if(auto bridgeData = GetBridgeData())
181   {
182     bridgeData->mBridge->EmitBoundsChanged(this, rect);
183   }
184 }
185
186 std::vector<Accessible*> Accessible::GetChildren()
187 {
188   std::vector<Accessible*> tmp(GetChildCount());
189   for(auto i = 0u; i < tmp.size(); ++i)
190   {
191     tmp[i] = GetChildAtIndex(i);
192   }
193   return tmp;
194 }
195
196 std::shared_ptr<Bridge::Data> Accessible::GetBridgeData()
197 {
198   auto handle = mBridgeData.lock();
199   if(!handle)
200   {
201     auto bridge = Bridge::GetCurrentBridge();
202     handle      = bridge->mData;
203   }
204   return handle;
205 }
206
207 Address Accessible::GetAddress()
208 {
209   auto handle = mBridgeData.lock();
210   if(!handle)
211   {
212     handle = GetBridgeData();
213     if(handle)
214     {
215       handle->mBridge->RegisterOnBridge(this);
216     }
217   }
218   std::ostringstream tmp;
219   tmp << this;
220   return {handle ? handle->mBusName : "", tmp.str()};
221 }
222
223 void Bridge::RegisterOnBridge(Accessible* object)
224 {
225   assert(!object->mBridgeData.lock() || object->mBridgeData.lock() == mData);
226   if(!object->mBridgeData.lock())
227   {
228     assert(mData);
229     mData->mKnownObjects.insert(object);
230     object->mBridgeData = mData;
231   }
232 }
233
234 bool Accessible::IsProxy()
235 {
236   return false;
237 }
238
239 Accessible* Accessible::GetDefaultLabel()
240 {
241   return this;
242 }
243
244 void Accessible::NotifyAccessibilityStateChange(Dali::Accessibility::States states, bool isRecursive)
245 {
246   if(auto data = GetBridgeData())
247   {
248     auto currentState = GetStates() & states;
249     for(auto i = 0u; i < currentState.size(); i++)
250     {
251       auto index = static_cast<Dali::Accessibility::State>(i);
252       if(currentState[index])
253       {
254         data->mBridge->EmitStateChanged(this, index, 1, 0);
255       }
256     }
257
258     if(isRecursive)
259     {
260       auto children = GetChildren();
261       for(auto iter : children)
262       {
263         iter->NotifyAccessibilityStateChange(states, isRecursive);
264       }
265     }
266   }
267 }
268
269 void Accessible::FindWordSeparationsUtf8(const utf8_t* string, size_t length, const char* language, char* breaks)
270 {
271   set_wordbreaks_utf8(string, length, language, breaks);
272 }
273
274 void Accessible::FindLineSeparationsUtf8(const utf8_t* string, size_t length, const char* language, char* breaks)
275 {
276   set_linebreaks_utf8(string, length, language, breaks);
277 }