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