eedc5f7a83d648aa9809571edc71b62b10a1adf3
[platform/core/uifw/dali-adaptor.git] / dali / internal / accessibility / bridge / bridge-object.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 #include <dali/internal/accessibility/bridge/bridge-object.h>
20
21 // EXTERNAL INCLUDES
22 #include <iostream>
23 #include <string>
24
25 using namespace Dali::Accessibility;
26
27 namespace
28 {
29 inline std::string GetAccessiblePath(Accessible* accessible)
30 {
31   auto address = accessible->GetAddress();
32   return address ? ATSPI_PREFIX_PATH + address.GetPath() : ATSPI_NULL_PATH;
33 }
34 } // namespace
35
36 BridgeObject::BridgeObject()
37 {
38 }
39
40 void BridgeObject::RegisterInterfaces()
41 {
42   // DBus::DBusInterfaceDescription desc{ AtspiDbusInterfaceEventObject };
43   // stateChanged = addSignal<std::string, int, int, DBus::EldbusVariant<int>, Accessible*>(desc, "StateChanged");
44   // mDbusServer.addInterface("/", desc, true);
45 }
46
47 void BridgeObject::EmitActiveDescendantChanged(Accessible* obj, Accessible* child)
48 {
49   if(!IsUp()) return;
50   auto index = child->GetIndexInParent();
51
52   mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<Address>, Address>(
53     GetAccessiblePath(obj),
54     AtspiDbusInterfaceEventObject,
55     "ActiveDescendantChanged",
56     "",
57     index,
58     0,
59     {child->GetAddress()},
60     {"", "root"});
61 }
62
63 void BridgeObject::Emit(Accessible* obj, Dali::Accessibility::ObjectPropertyChangeEvent ev)
64 {
65   if(!IsUp()) return;
66   const char* name = nullptr;
67
68   switch(ev)
69   {
70     case ObjectPropertyChangeEvent::NAME:
71     {
72       name = "accessible-name";
73       break;
74     }
75     case ObjectPropertyChangeEvent::DESCRIPTION:
76     {
77       name = "accessible-description";
78       break;
79     }
80     case ObjectPropertyChangeEvent::VALUE:
81     {
82       name = "accessible-value";
83       break;
84     }
85     case ObjectPropertyChangeEvent::PARENT:
86     {
87       name = "accessible-parent";
88       break;
89     }
90     case ObjectPropertyChangeEvent::ROLE:
91     {
92       name = "accessible-role";
93       break;
94     }
95   }
96
97   if(name)
98   {
99     mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
100       GetAccessiblePath(obj),
101       AtspiDbusInterfaceEventObject,
102       "PropertyChange",
103       name,
104       0,
105       0,
106       {0},
107       {"", "root"});
108   }
109 }
110
111 void BridgeObject::Emit(Accessible* obj, WindowEvent event, unsigned int detail)
112 {
113   if(!IsUp()) return;
114   const char* name = nullptr;
115
116   switch(event)
117   {
118     case WindowEvent::PROPERTY_CHANGE:
119     {
120       name = "PropertyChange";
121       break;
122     }
123     case WindowEvent::MINIMIZE:
124     {
125       name = "Minimize";
126       break;
127     }
128     case WindowEvent::MAXIMIZE:
129     {
130       name = "Maximize";
131       break;
132     }
133     case WindowEvent::RESTORE:
134     {
135       name = "Restore";
136       break;
137     }
138     case WindowEvent::CLOSE:
139     {
140       name = "Close";
141       break;
142     }
143     case WindowEvent::CREATE:
144     {
145       name = "Create";
146       break;
147     }
148     case WindowEvent::REPARENT:
149     {
150       name = "Reparent";
151       break;
152     }
153     case WindowEvent::DESKTOP_CREATE:
154     {
155       name = "DesktopCreate";
156       break;
157     }
158     case WindowEvent::DESKTOP_DESTROY:
159     {
160       name = "DesktopDestroy";
161       break;
162     }
163     case WindowEvent::DESTROY:
164     {
165       name = "Destroy";
166       break;
167     }
168     case WindowEvent::ACTIVATE:
169     {
170       name = "Activate";
171       break;
172     }
173     case WindowEvent::DEACTIVATE:
174     {
175       name = "Deactivate";
176       break;
177     }
178     case WindowEvent::RAISE:
179     {
180       name = "Raise";
181       break;
182     }
183     case WindowEvent::LOWER:
184     {
185       name = "Lower";
186       break;
187     }
188     case WindowEvent::MOVE:
189     {
190       name = "Move";
191       break;
192     }
193     case WindowEvent::RESIZE:
194     {
195       name = "Resize";
196       break;
197     }
198     case WindowEvent::SHADE:
199     {
200       name = "Shade";
201       break;
202     }
203     case WindowEvent::UU_SHADE:
204     {
205       name = "uUshade";
206       break;
207     }
208     case WindowEvent::RESTYLE:
209     {
210       name = "Restyle";
211       break;
212     }
213   }
214
215   if(name)
216   {
217     mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
218       GetAccessiblePath(obj),
219       AtspiDbusInterfaceEventWindow,
220       name,
221       "",
222       detail,
223       0,
224       {0},
225       {"", "root"});
226   }
227 }
228
229 void BridgeObject::EmitStateChanged(Accessible* obj, State state, int newValue, int reserved)
230 {
231   if(!IsUp()) return;
232   const char* stateName = nullptr;
233
234   switch(state)
235   {
236     case State::INVALID:
237     {
238       stateName = "invalid";
239       break;
240     }
241     case State::ACTIVE:
242     {
243       stateName = "active";
244       break;
245     }
246     case State::ARMED:
247     {
248       stateName = "armed";
249       break;
250     }
251     case State::BUSY:
252     {
253       stateName = "busy";
254       break;
255     }
256     case State::CHECKED:
257     {
258       stateName = "checked";
259       break;
260     }
261     case State::COLLAPSED:
262     {
263       stateName = "collapsed";
264       break;
265     }
266     case State::DEFUNCT:
267     {
268       stateName = "defunct";
269       break;
270     }
271     case State::EDITABLE:
272     {
273       stateName = "editable";
274       break;
275     }
276     case State::ENABLED:
277     {
278       stateName = "enabled";
279       break;
280     }
281     case State::EXPANDABLE:
282     {
283       stateName = "expandable";
284       break;
285     }
286     case State::EXPANDED:
287     {
288       stateName = "expanded";
289       break;
290     }
291     case State::FOCUSABLE:
292     {
293       stateName = "focusable";
294       break;
295     }
296     case State::FOCUSED:
297     {
298       stateName = "focused";
299       break;
300     }
301     case State::HAS_TOOLTIP:
302     {
303       stateName = "has-tooltip";
304       break;
305     }
306     case State::HORIZONTAL:
307     {
308       stateName = "horizontal";
309       break;
310     }
311     case State::ICONIFIED:
312     {
313       stateName = "iconified";
314       break;
315     }
316     case State::MODAL:
317     {
318       stateName = "modal";
319       break;
320     }
321     case State::MULTI_LINE:
322     {
323       stateName = "multi-line";
324       break;
325     }
326     case State::MULTI_SELECTABLE:
327     {
328       stateName = "multiselectable";
329       break;
330     }
331     case State::OPAQUE:
332     {
333       stateName = "opaque";
334       break;
335     }
336     case State::PRESSED:
337     {
338       stateName = "pressed";
339       break;
340     }
341     case State::RESIZEABLE:
342     {
343       stateName = "resizable";
344       break;
345     }
346     case State::SELECTABLE:
347     {
348       stateName = "selectable";
349       break;
350     }
351     case State::SELECTED:
352     {
353       stateName = "selected";
354       break;
355     }
356     case State::SENSITIVE:
357     {
358       stateName = "sensitive";
359       break;
360     }
361     case State::SHOWING:
362     {
363       stateName = "showing";
364       break;
365     }
366     case State::SINGLE_LINE:
367     {
368       stateName = "single-line";
369       break;
370     }
371     case State::STALE:
372     {
373       stateName = "stale";
374       break;
375     }
376     case State::TRANSIENT:
377     {
378       stateName = "transient";
379       break;
380     }
381     case State::VERTICAL:
382     {
383       stateName = "vertical";
384       break;
385     }
386     case State::VISIBLE:
387     {
388       stateName = "visible";
389       break;
390     }
391     case State::MANAGES_DESCENDANTS:
392     {
393       stateName = "manages-descendants";
394       break;
395     }
396     case State::INDETERMINATE:
397     {
398       stateName = "indeterminate";
399       break;
400     }
401     case State::REQUIRED:
402     {
403       stateName = "required";
404       break;
405     }
406     case State::TRUNCATED:
407     {
408       stateName = "truncated";
409       break;
410     }
411     case State::ANIMATED:
412     {
413       stateName = "animated";
414       break;
415     }
416     case State::INVALID_ENTRY:
417     {
418       stateName = "invalid-entry";
419       break;
420     }
421     case State::SUPPORTS_AUTOCOMPLETION:
422     {
423       stateName = "supports-autocompletion";
424       break;
425     }
426     case State::SELECTABLE_TEXT:
427     {
428       stateName = "selectable-text";
429       break;
430     }
431     case State::IS_DEFAULT:
432     {
433       stateName = "is-default";
434       break;
435     }
436     case State::VISITED:
437     {
438       stateName = "visited";
439       break;
440     }
441     case State::CHECKABLE:
442     {
443       stateName = "checkable";
444       break;
445     }
446     case State::HAS_POPUP:
447     {
448       stateName = "has-popup";
449       break;
450     }
451     case State::READ_ONLY:
452     {
453       stateName = "read-only";
454       break;
455     }
456     case State::HIGHLIGHTED:
457     {
458       stateName = "highlighted";
459       break;
460     }
461     case State::HIGHLIGHTABLE:
462     {
463       stateName = "highlightable";
464       break;
465     }
466     case State::MAX_COUNT:
467     {
468       break;
469     }
470   }
471
472   if(stateName)
473   {
474     mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
475       GetAccessiblePath(obj),
476       AtspiDbusInterfaceEventObject,
477       "StateChanged",
478       stateName,
479       newValue,
480       reserved,
481       {0},
482       {"", "root"});
483   }
484 }
485
486 void BridgeObject::EmitBoundsChanged(Accessible* obj, Dali::Rect<> rect)
487 {
488   if(!IsBoundsChangedEventAllowed) return;
489
490   DBus::EldbusVariant<std::tuple<int32_t, int32_t, int32_t, int32_t> > tmp{
491     std::tuple<int32_t, int32_t, int32_t, int32_t>{rect.x, rect.y, rect.width, rect.height}};
492
493   AddFilteredEvent(FilteredEvents::BOUNDS_CHANGED, obj, 1.0f, [=]() {
494     mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<std::tuple<int32_t, int32_t, int32_t, int32_t> >, Address>(
495       GetAccessiblePath(obj),
496       AtspiDbusInterfaceEventObject,
497       "BoundsChanged",
498       "",
499       0,
500       0,
501       tmp,
502       {"", "root"});
503   });
504 }
505
506 void BridgeObject::EmitCursorMoved(Accessible* obj, unsigned int cursorPosition)
507 {
508   mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
509     GetAccessiblePath(obj),
510     AtspiDbusInterfaceEventObject,
511     "TextCaretMoved",
512     "",
513     cursorPosition,
514     0,
515     {0},
516     {"", "root"});
517 }
518
519 void BridgeObject::EmitTextChanged(Accessible* obj, TextChangedState state, unsigned int position, unsigned int length, const std::string& content)
520 {
521   const char* stateName = nullptr;
522   switch(state)
523   {
524     case TextChangedState::INSERTED:
525     {
526       stateName = "insert";
527       break;
528     }
529     case TextChangedState::DELETED:
530     {
531       stateName = "delete";
532       break;
533     }
534     case TextChangedState::MAX_COUNT:
535     {
536       break;
537     }
538   }
539
540   if(stateName)
541   {
542     mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<std::string>, Address>(
543       GetAccessiblePath(obj),
544       AtspiDbusInterfaceEventObject,
545       "TextChanged",
546       stateName,
547       position,
548       length,
549       {content},
550       {"", "root"});
551   }
552 }
553
554 void BridgeObject::EmitMovedOutOfScreen(Accessible* obj, ScreenRelativeMoveType type)
555 {
556   mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
557     GetAccessiblePath(obj),
558     AtspiDbusInterfaceEventObject,
559     "MoveOuted",
560     "",
561     static_cast<int>(type),
562     0,
563     {0},
564     {"", "root"});
565 }