2 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/accessibility/bridge/bridge-object.h>
24 #include <string_view>
25 #include <unordered_map>
27 using namespace Dali::Accessibility;
31 inline std::string GetAccessiblePath(Accessible* accessible)
33 auto address = accessible->GetAddress();
34 return address ? ATSPI_PREFIX_PATH + address.GetPath() : ATSPI_NULL_PATH;
38 BridgeObject::BridgeObject()
42 void BridgeObject::RegisterInterfaces()
44 // DBus::DBusInterfaceDescription desc{Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT)};
45 // mStateChanged = addSignal<std::string, int, int, DBus::EldbusVariant<int>, Accessible*>(desc, "StateChanged");
46 // mDbusServer.addInterface("/", desc, true);
49 void BridgeObject::EmitActiveDescendantChanged(Accessible* obj, Accessible* child)
51 if(!IsUp() || obj->IsHidden() || obj->GetSuppressedEvents()[AtspiEvent::ACTIVE_DESCENDANT_CHANGED] || child->IsHidden())
56 auto index = child->GetIndexInParent();
58 mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<Address>, Address>(
59 GetAccessiblePath(obj),
60 Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
61 "ActiveDescendantChanged",
65 {child->GetAddress()},
69 void BridgeObject::Emit(Accessible* obj, ObjectPropertyChangeEvent event)
71 static const std::unordered_map<ObjectPropertyChangeEvent, std::string_view> eventMap{
72 {ObjectPropertyChangeEvent::NAME, "accessible-name"},
73 {ObjectPropertyChangeEvent::DESCRIPTION, "accessible-description"},
74 {ObjectPropertyChangeEvent::VALUE, "accessible-value"},
75 {ObjectPropertyChangeEvent::PARENT, "accessible-parent"},
76 {ObjectPropertyChangeEvent::ROLE, "accessible-role"},
79 if(!IsUp() || obj->IsHidden() || obj->GetSuppressedEvents()[AtspiEvent::PROPERTY_CHANGED])
84 auto eventName = eventMap.find(event);
86 if(eventName != eventMap.end())
88 mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
89 GetAccessiblePath(obj),
90 Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
92 std::string{eventName->second},
100 void BridgeObject::Emit(Accessible* obj, WindowEvent event, unsigned int detail)
102 static const std::unordered_map<WindowEvent, std::string_view> eventMap{
103 {WindowEvent::PROPERTY_CHANGE, "PropertyChange"},
104 {WindowEvent::MINIMIZE, "Minimize"},
105 {WindowEvent::MAXIMIZE, "Maximize"},
106 {WindowEvent::RESTORE, "Restore"},
107 {WindowEvent::CLOSE, "Close"},
108 {WindowEvent::CREATE, "Create"},
109 {WindowEvent::REPARENT, "Reparent"},
110 {WindowEvent::DESKTOP_CREATE, "DesktopCreate"},
111 {WindowEvent::DESKTOP_DESTROY, "DesktopDestroy"},
112 {WindowEvent::DESTROY, "Destroy"},
113 {WindowEvent::ACTIVATE, "Activate"},
114 {WindowEvent::DEACTIVATE, "Deactivate"},
115 {WindowEvent::RAISE, "Raise"},
116 {WindowEvent::LOWER, "Lower"},
117 {WindowEvent::MOVE, "Move"},
118 {WindowEvent::RESIZE, "Resize"},
119 {WindowEvent::SHADE, "Shade"},
120 {WindowEvent::UU_SHADE, "uUshade"},
121 {WindowEvent::RESTYLE, "Restyle"},
122 {WindowEvent::POST_RENDER, "PostRender"},
125 if(!IsUp() || obj->IsHidden() || obj->GetSuppressedEvents()[AtspiEvent::WINDOW_CHANGED])
130 auto eventName = eventMap.find(event);
132 if(eventName != eventMap.end())
134 mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
135 GetAccessiblePath(obj),
136 Accessible::GetInterfaceName(AtspiInterface::EVENT_WINDOW),
137 std::string{eventName->second},
146 void BridgeObject::EmitStateChanged(Accessible* obj, State state, int newValue, int reserved)
148 static const std::unordered_map<State, std::string_view> stateMap{
149 {State::INVALID, "invalid"},
150 {State::ACTIVE, "active"},
151 {State::ARMED, "armed"},
152 {State::BUSY, "busy"},
153 {State::CHECKED, "checked"},
154 {State::COLLAPSED, "collapsed"},
155 {State::DEFUNCT, "defunct"},
156 {State::EDITABLE, "editable"},
157 {State::ENABLED, "enabled"},
158 {State::EXPANDABLE, "expandable"},
159 {State::EXPANDED, "expanded"},
160 {State::FOCUSABLE, "focusable"},
161 {State::FOCUSED, "focused"},
162 {State::HAS_TOOLTIP, "has-tooltip"},
163 {State::HORIZONTAL, "horizontal"},
164 {State::ICONIFIED, "iconified"},
165 {State::MODAL, "modal"},
166 {State::MULTI_LINE, "multi-line"},
167 {State::MULTI_SELECTABLE, "multiselectable"},
168 {State::OPAQUE, "opaque"},
169 {State::PRESSED, "pressed"},
170 {State::RESIZEABLE, "resizable"},
171 {State::SELECTABLE, "selectable"},
172 {State::SELECTED, "selected"},
173 {State::SENSITIVE, "sensitive"},
174 {State::SHOWING, "showing"},
175 {State::SINGLE_LINE, "single-line"},
176 {State::STALE, "stale"},
177 {State::TRANSIENT, "transient"},
178 {State::VERTICAL, "vertical"},
179 {State::VISIBLE, "visible"},
180 {State::MANAGES_DESCENDANTS, "manages-descendants"},
181 {State::INDETERMINATE, "indeterminate"},
182 {State::REQUIRED, "required"},
183 {State::TRUNCATED, "truncated"},
184 {State::ANIMATED, "animated"},
185 {State::INVALID_ENTRY, "invalid-entry"},
186 {State::SUPPORTS_AUTOCOMPLETION, "supports-autocompletion"},
187 {State::SELECTABLE_TEXT, "selectable-text"},
188 {State::IS_DEFAULT, "is-default"},
189 {State::VISITED, "visited"},
190 {State::CHECKABLE, "checkable"},
191 {State::HAS_POPUP, "has-popup"},
192 {State::READ_ONLY, "read-only"},
193 {State::HIGHLIGHTED, "highlighted"},
194 {State::HIGHLIGHTABLE, "highlightable"},
197 if(!IsUp() || obj->IsHidden() || obj->GetSuppressedEvents()[AtspiEvent::STATE_CHANGED]) // separate ?
202 auto stateName = stateMap.find(state);
204 if(stateName != stateMap.end())
206 mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
207 GetAccessiblePath(obj),
208 Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
210 std::string{stateName->second},
218 void BridgeObject::EmitBoundsChanged(Accessible* obj, Dali::Rect<> rect)
220 if(!IsUp() || !IsBoundsChangedEventAllowed || obj->IsHidden() || obj->GetSuppressedEvents()[AtspiEvent::BOUNDS_CHANGED])
225 DBus::EldbusVariant<std::tuple<int32_t, int32_t, int32_t, int32_t> > tmp{
226 std::tuple<int32_t, int32_t, int32_t, int32_t>{rect.x, rect.y, rect.width, rect.height}};
228 AddCoalescableMessage(CoalescableMessages::BOUNDS_CHANGED, obj, 1.0f, [=]() {
229 mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<std::tuple<int32_t, int32_t, int32_t, int32_t> >, Address>(
230 GetAccessiblePath(obj),
231 Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
241 void BridgeObject::EmitCursorMoved(Accessible* obj, unsigned int cursorPosition)
243 if(!IsUp() || obj->IsHidden() || obj->GetSuppressedEvents()[AtspiEvent::TEXT_CARET_MOVED])
248 mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
249 GetAccessiblePath(obj),
250 Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
259 void BridgeObject::EmitTextChanged(Accessible* obj, TextChangedState state, unsigned int position, unsigned int length, const std::string& content)
261 static const std::unordered_map<TextChangedState, std::string_view> stateMap{
262 {TextChangedState::INSERTED, "insert"},
263 {TextChangedState::DELETED, "delete"},
266 if(!IsUp() || obj->IsHidden() || obj->GetSuppressedEvents()[AtspiEvent::TEXT_CHANGED])
271 auto stateName = stateMap.find(state);
273 if(stateName != stateMap.end())
275 mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<std::string>, Address>(
276 GetAccessiblePath(obj),
277 Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
279 std::string{stateName->second},
287 void BridgeObject::EmitMovedOutOfScreen(Accessible* obj, ScreenRelativeMoveType type)
289 if(!IsUp() || obj->IsHidden() || obj->GetSuppressedEvents()[AtspiEvent::MOVED_OUT])
294 mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
295 GetAccessiblePath(obj),
296 Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
299 static_cast<int>(type),
305 void BridgeObject::EmitSocketAvailable(Accessible* obj)
307 if(!IsUp() || obj->IsHidden()) //TODO Suppress SocketAvailable event
312 mDbusServer.emit2<Address, Address>(
313 GetAccessiblePath(obj),
314 Accessible::GetInterfaceName(AtspiInterface::SOCKET),
320 void BridgeObject::EmitScrollStarted(Accessible* obj)
322 if(!IsUp() || obj->IsHidden() || obj->GetSuppressedEvents()[AtspiEvent::SCROLL_STARTED])
327 mDbusServer.emit2<Address>(
328 GetAccessiblePath(obj),
329 Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
334 void BridgeObject::EmitScrollFinished(Accessible* obj)
336 if(!IsUp() || obj->IsHidden() || obj->GetSuppressedEvents()[AtspiEvent::SCROLL_FINISHED])
341 mDbusServer.emit2<Address>(
342 GetAccessiblePath(obj),
343 Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),