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