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