Revert "[Tizen](ATSPI) squashed implementation"
[platform/core/uifw/dali-adaptor.git] / dali / internal / window-system / common / event-handler.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/window-system/common/event-handler.h>
20
21 // EXTERNAL INCLUDES
22 #include <cstring>
23 #include <sys/time.h>
24
25 #include <dali/public-api/events/touch-point.h>
26 #include <dali/public-api/events/key-event.h>
27 #include <dali/public-api/events/wheel-event.h>
28 #include <dali/integration-api/debug.h>
29 #include <dali/integration-api/events/key-event-integ.h>
30 #include <dali/integration-api/events/touch-event-integ.h>
31 #include <dali/integration-api/events/hover-event-integ.h>
32 #include <dali/integration-api/events/wheel-event-integ.h>
33
34 // INTERNAL INCLUDES
35 #include <dali/internal/clipboard/common/clipboard-impl.h>
36 #include <dali/internal/styling/common/style-monitor-impl.h>
37 #include <dali/internal/window-system/common/window-render-surface.h>
38
39 namespace Dali
40 {
41
42 namespace Internal
43 {
44
45 namespace Adaptor
46 {
47
48 #if defined(DEBUG_ENABLED)
49 namespace
50 {
51 Integration::Log::Filter* gSelectionEventLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_SELECTION");
52 } // unnamed namespace
53 #endif
54
55 #ifdef DALI_ELDBUS_AVAILABLE
56 namespace
57 {
58
59 // Copied from x server
60 static uint32_t GetCurrentMilliSeconds(void)
61 {
62   struct timeval tv;
63
64   struct timespec tp;
65   static clockid_t clockid;
66
67   if (!clockid)
68   {
69 #ifdef CLOCK_MONOTONIC_COARSE
70     if (clock_getres(CLOCK_MONOTONIC_COARSE, &tp) == 0 &&
71       (tp.tv_nsec / 1000) <= 1000 && clock_gettime(CLOCK_MONOTONIC_COARSE, &tp) == 0)
72     {
73       clockid = CLOCK_MONOTONIC_COARSE;
74     }
75     else
76 #endif
77     if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
78     {
79       clockid = CLOCK_MONOTONIC;
80     }
81     else
82     {
83       clockid = ~0L;
84     }
85   }
86   if (clockid != ~0L && clock_gettime(clockid, &tp) == 0)
87   {
88     return static_cast<uint32_t>( (tp.tv_sec * 1000 ) + (tp.tv_nsec / 1000000L) );
89   }
90
91   gettimeofday(&tv, NULL);
92   return static_cast<uint32_t>( (tv.tv_sec * 1000 ) + (tv.tv_usec / 1000) );
93 }
94
95 } // unnamed namespace
96 #endif
97
98 EventHandler::EventHandler( WindowRenderSurface* surface, DamageObserver& damageObserver )
99 : mStyleMonitor( StyleMonitor::Get() ),
100   mDamageObserver( damageObserver ),
101   mAccessibilityAdaptor( AccessibilityAdaptor::Get() ),
102   mClipboardEventNotifier( ClipboardEventNotifier::Get() ),
103   mClipboard( Clipboard::Get() ),
104   mPaused( false )
105 {
106   if( surface )
107   {
108     WindowBase* windowBase = surface->GetWindowBase();
109
110     // Connect signals
111     windowBase->WindowDamagedSignal().Connect( this, &EventHandler::OnWindowDamaged );
112     windowBase->FocusChangedSignal().Connect( this, &EventHandler::OnFocusChanged );
113     windowBase->RotationSignal().Connect( this, &EventHandler::OnRotation );
114     windowBase->TouchEventSignal().Connect( this, &EventHandler::OnTouchEvent );
115     windowBase->WheelEventSignal().Connect( this, &EventHandler::OnWheelEvent );
116     windowBase->KeyEventSignal().Connect( this, &EventHandler::OnKeyEvent );
117     windowBase->SelectionDataSendSignal().Connect( this, &EventHandler::OnSelectionDataSend );
118     windowBase->SelectionDataReceivedSignal().Connect( this, &EventHandler::OnSelectionDataReceived );
119     windowBase->StyleChangedSignal().Connect( this, &EventHandler::OnStyleChanged );
120     windowBase->AccessibilitySignal().Connect( this, &EventHandler::OnAccessibilityNotification );
121   }
122 }
123
124 EventHandler::~EventHandler()
125 {
126 }
127
128 void EventHandler::SendEvent( StyleChange::Type styleChange )
129 {
130   DALI_ASSERT_DEBUG( mStyleMonitor && "StyleMonitor Not Available" );
131   GetImplementation( mStyleMonitor ).StyleChanged(styleChange);
132 }
133
134 void EventHandler::SendEvent( const DamageArea& area )
135 {
136   mDamageObserver.OnDamaged( area );
137 }
138
139 void EventHandler::Pause()
140 {
141   mPaused = true;
142 }
143
144 void EventHandler::Resume()
145 {
146   mPaused = false;
147 }
148
149 void EventHandler::OnTouchEvent( Integration::Point& point, uint32_t timeStamp )
150 {
151   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
152   {
153     (*iter)->OnTouchPoint( point, timeStamp );
154   }
155 }
156
157 void EventHandler::OnWheelEvent( WheelEvent& wheelEvent )
158 {
159   Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
160
161   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
162   {
163     (*iter)->OnWheelEvent( event );
164   }
165 }
166
167 void EventHandler::OnKeyEvent( Integration::KeyEvent& keyEvent )
168 {
169   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
170   {
171     (*iter)->OnKeyEvent( keyEvent );
172   }
173 }
174
175 void EventHandler::OnFocusChanged( bool focusIn )
176 {
177   // If the window gains focus and we hid the keyboard then show it again.
178   if( focusIn )
179   {
180     Dali::Clipboard clipboard = Clipboard::Get();
181     if ( clipboard )
182     {
183       clipboard.HideClipboard();
184     }
185   }
186   else
187   {
188     // Hiding clipboard event will be ignored once because window focus out event is always received on showing clipboard
189     Dali::Clipboard clipboard = Clipboard::Get();
190     if ( clipboard )
191     {
192       Clipboard& clipBoardImpl( GetImplementation( clipboard ) );
193       clipBoardImpl.HideClipboard(true);
194     }
195   }
196 }
197
198 void EventHandler::OnRotation( const RotationEvent& event )
199 {
200   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
201   {
202     (*iter)->OnRotation( event );
203   }
204 }
205
206 void EventHandler::OnWindowDamaged( const DamageArea& area )
207 {
208   SendEvent( area );
209 }
210
211 void EventHandler::OnSelectionDataSend( void* event )
212 {
213   Dali::Clipboard clipboard = Clipboard::Get();
214   if( clipboard )
215   {
216     Clipboard& clipBoardImpl( GetImplementation( clipboard ) );
217     clipBoardImpl.ExcuteBuffered( true, event );
218   }
219 }
220
221 void EventHandler::OnSelectionDataReceived( void* event )
222 {
223   // We have got the selected content, inform the clipboard event listener (if we have one).
224   Dali::Clipboard clipboard = Clipboard::Get();
225   char* selectionData = NULL;
226   if( clipboard )
227   {
228     Clipboard& clipBoardImpl( GetImplementation( clipboard ) );
229     selectionData = clipBoardImpl.ExcuteBuffered( false, event );
230   }
231
232   if( selectionData && mClipboardEventNotifier )
233   {
234     ClipboardEventNotifier& clipboardEventNotifier( ClipboardEventNotifier::GetImplementation( mClipboardEventNotifier ) );
235     std::string content( selectionData, strlen( selectionData ) );
236
237     clipboardEventNotifier.SetContent( content );
238     clipboardEventNotifier.EmitContentSelectedSignal();
239
240     DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "EcoreEventSelectionNotify: Content(%d): %s\n" , strlen(selectionData), selectionData );
241   }
242 }
243
244 void EventHandler::OnStyleChanged( StyleChange::Type styleChange )
245 {
246   SendEvent( styleChange );
247 }
248
249 void EventHandler::OnAccessibilityNotification( const WindowBase::AccessibilityInfo& info )
250 {
251 #ifdef DALI_ELDBUS_AVAILABLE
252   if( mPaused )
253   {
254     return;
255   }
256
257   if( !mAccessibilityAdaptor )
258   {
259     DALI_LOG_ERROR( "Invalid accessibility adaptor\n" );
260     return;
261   }
262
263   AccessibilityAdaptor* accessibilityAdaptor( &AccessibilityAdaptor::GetImplementation( mAccessibilityAdaptor ) );
264   if( !accessibilityAdaptor )
265   {
266     DALI_LOG_ERROR( "Cannot access accessibility adaptor\n" );
267     return;
268   }
269
270   // Create a touch point object.
271   TouchPoint::State touchPointState( TouchPoint::Down );
272   if( info.state == 0 )
273   {
274     touchPointState = TouchPoint::Down; // Mouse down.
275   }
276   else if( info.state == 1 )
277   {
278     touchPointState = TouchPoint::Motion; // Mouse move.
279   }
280   else if( info.state == 2 )
281   {
282     touchPointState = TouchPoint::Up; // Mouse up.
283   }
284   else
285   {
286     touchPointState = TouchPoint::Interrupted; // Error.
287   }
288
289   // Send touch event to accessibility adaptor.
290   TouchPoint point( 0, touchPointState, static_cast< float >( info.startX ), static_cast< float >( info.startY ) );
291
292   // Perform actions based on received gestures.
293   // Note: This is seperated from the reading so we can have other input readers without changing the below code.
294   switch( info.gestureValue )
295   {
296     case 0: // OneFingerHover
297     {
298       // Focus, read out.
299       accessibilityAdaptor->HandleActionReadEvent( static_cast< unsigned int >( info.startX ), static_cast< unsigned int >( info.startY ), true /* allow read again */ );
300       break;
301     }
302     case 1: // TwoFingersHover
303     {
304       // In accessibility mode, scroll action should be handled when the currently focused actor is contained in scrollable control
305       accessibilityAdaptor->HandleActionScrollEvent( point, GetCurrentMilliSeconds() );
306       break;
307     }
308     case 2: // ThreeFingersHover
309     {
310       // Read from top item on screen continuously.
311       accessibilityAdaptor->HandleActionReadFromTopEvent();
312       break;
313     }
314     case 3: // OneFingerFlickLeft
315     {
316       // Move to previous item.
317       accessibilityAdaptor->HandleActionReadPreviousEvent();
318       break;
319     }
320     case 4: // OneFingerFlickRight
321     {
322       // Move to next item.
323       accessibilityAdaptor->HandleActionReadNextEvent();
324       break;
325     }
326     case 5: // OneFingerFlickUp
327     {
328       // Move to previous item.
329       accessibilityAdaptor->HandleActionPreviousEvent();
330       break;
331     }
332     case 6: // OneFingerFlickDown
333     {
334       // Move to next item.
335       accessibilityAdaptor->HandleActionNextEvent();
336       break;
337     }
338     case 7: // TwoFingersFlickUp
339     {
340       // Scroll up the list.
341       accessibilityAdaptor->HandleActionScrollUpEvent();
342       break;
343     }
344     case 8: // TwoFingersFlickDown
345     {
346       // Scroll down the list.
347       accessibilityAdaptor->HandleActionScrollDownEvent();
348       break;
349     }
350     case 9: // TwoFingersFlickLeft
351     {
352       // Scroll left to the previous page
353       accessibilityAdaptor->HandleActionPageLeftEvent();
354       break;
355     }
356     case 10: // TwoFingersFlickRight
357     {
358       // Scroll right to the next page
359       accessibilityAdaptor->HandleActionPageRightEvent();
360       break;
361     }
362     case 11: // ThreeFingersFlickLeft
363     {
364       // Not exist yet
365       break;
366     }
367     case 12: // ThreeFingersFlickRight
368     {
369       // Not exist yet
370       break;
371     }
372     case 13: // ThreeFingersFlickUp
373     {
374       // Not exist yet
375       break;
376     }
377     case 14: // ThreeFingersFlickDown
378     {
379       // Not exist yet
380       break;
381     }
382     case 15: // OneFingerSingleTap
383     {
384       // Focus, read out.
385       accessibilityAdaptor->HandleActionReadEvent( static_cast< unsigned int >( info.startX ), static_cast< unsigned int >( info.startY ), true /* allow read again */ );
386       break;
387     }
388     case 16: // OneFingerDoubleTap
389     {
390       // Activate selected item / active edit mode.
391       accessibilityAdaptor->HandleActionActivateEvent();
392       break;
393     }
394     case 17: // OneFingerTripleTap
395     {
396       // Zoom
397       accessibilityAdaptor->HandleActionZoomEvent();
398       break;
399     }
400     case 18: // TwoFingersSingleTap
401     {
402       // Pause/Resume current speech
403       accessibilityAdaptor->HandleActionReadPauseResumeEvent();
404       break;
405     }
406     case 19: // TwoFingersDoubleTap
407     {
408       // Start/Stop current action
409       accessibilityAdaptor->HandleActionStartStopEvent();
410       break;
411     }
412     case 20: // TwoFingersTripleTap
413     {
414       // Read information from indicator
415       // Not supported
416       break;
417     }
418     case 21: // ThreeFingersSingleTap
419     {
420       // Read from top item on screen continuously.
421       accessibilityAdaptor->HandleActionReadFromTopEvent();
422       break;
423     }
424     case 22: // ThreeFingersDoubleTap
425     {
426       // Read from next item continuously.
427       accessibilityAdaptor->HandleActionReadFromNextEvent();
428       break;
429     }
430     case 23: // ThreeFingersTripleTap
431     {
432       // Not exist yet
433       break;
434     }
435     case 24: // OneFingerFlickLeftReturn
436     {
437       // Scroll up to the previous page
438       accessibilityAdaptor->HandleActionPageUpEvent();
439       break;
440     }
441     case 25: // OneFingerFlickRightReturn
442     {
443       // Scroll down to the next page
444       accessibilityAdaptor->HandleActionPageDownEvent();
445       break;
446     }
447     case 26: // OneFingerFlickUpReturn
448     {
449       // Move to the first item on screen
450       accessibilityAdaptor->HandleActionMoveToFirstEvent();
451       break;
452     }
453     case 27: // OneFingerFlickDownReturn
454     {
455       // Move to the last item on screen
456       accessibilityAdaptor->HandleActionMoveToLastEvent();
457       break;
458     }
459     case 28: // TwoFingersFlickLeftReturn
460     {
461       // Not exist yet
462       break;
463     }
464     case 29: // TwoFingersFlickRightReturn
465     {
466       // Not exist yet
467       break;
468     }
469     case 30: // TwoFingersFlickUpReturn
470     {
471       // Not exist yet
472       break;
473     }
474     case 31: // TwoFingersFlickDownReturn
475     {
476       // Not exist yet
477       break;
478     }
479     case 32: // ThreeFingersFlickLeftReturn
480     {
481       // Not exist yet
482       break;
483     }
484     case 33: // ThreeFingersFlickRightReturn
485     {
486       // Not exist yet
487       break;
488     }
489     case 34: // ThreeFingersFlickUpReturn
490     {
491       // Not exist yet
492       break;
493     }
494     case 35: // ThreeFingersFlickDownReturn
495     {
496       // Not exist yet
497       break;
498     }
499   }
500 #endif
501 }
502
503 void EventHandler::AddObserver( Observer& observer )
504 {
505   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
506
507   if ( match == mObservers.end() )
508   {
509     mObservers.push_back( &observer );
510   }
511 }
512
513 void EventHandler::RemoveObserver( Observer& observer )
514 {
515   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
516
517   if ( match != mObservers.end() )
518   {
519     mObservers.erase( match );
520   }
521 }
522
523 } // namespace Adaptor
524
525 } // namespace Internal
526
527 } // namespace Dali