2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <events/event-handler.h>
26 #include <X11/extensions/XInput2.h>
27 #include <X11/extensions/XI2.h>
33 #ifndef DALI_PROFILE_UBUNTU
35 #include <vconf-keys.h>
36 #endif // DALI_PROFILE_UBUNTU
38 #include <dali/public-api/common/vector-wrapper.h>
39 #include <dali/public-api/events/touch-point.h>
40 #include <dali/public-api/events/key-event.h>
41 #include <dali/public-api/events/wheel-event.h>
42 #include <dali/integration-api/debug.h>
43 #include <dali/integration-api/events/key-event-integ.h>
44 #include <dali/integration-api/events/touch-event-integ.h>
45 #include <dali/integration-api/events/hover-event-integ.h>
46 #include <dali/integration-api/events/wheel-event-integ.h>
49 #include <x-events/x-event-manager.h>
50 #include <events/gesture-manager.h>
51 #include <window-render-surface.h>
52 #include <clipboard-impl.h>
54 #include <physical-keyboard-impl.h>
55 #include <style-monitor-impl.h>
56 #include <base/core-event-interface.h>
57 #include <base/interfaces/window-event-interface.h>
68 #if defined(DEBUG_ENABLED)
71 Integration::Log::Filter* gTouchEventLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_TOUCH");
72 } // unnamed namespace
79 const unsigned int PRIMARY_TOUCH_BUTTON_ID( 1 );
81 const unsigned int BYTES_PER_CHARACTER_FOR_ATTRIBUTES = 3;
84 // Copied from x server
85 static unsigned int GetCurrentMilliSeconds(void)
90 static clockid_t clockid;
94 #ifdef CLOCK_MONOTONIC_COARSE
95 if (clock_getres(CLOCK_MONOTONIC_COARSE, &tp) == 0 &&
96 (tp.tv_nsec / 1000) <= 1000 && clock_gettime(CLOCK_MONOTONIC_COARSE, &tp) == 0)
98 clockid = CLOCK_MONOTONIC_COARSE;
102 if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
104 clockid = CLOCK_MONOTONIC;
111 if (clockid != ~0L && clock_gettime(clockid, &tp) == 0)
113 return (tp.tv_sec * 1000) + (tp.tv_nsec / 1000000L);
116 gettimeofday(&tv, NULL);
117 return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
120 } // unnamed namespace
123 struct EventHandler::Impl : public WindowEventInterface
125 // Construction & Destruction
130 Impl( EventHandler* handler, XID window, Display* display )
131 : mXEventManager(window, display, this),
135 mXEventManager.Initialize();
143 // @todo Consider allowing the EventHandler class to inherit from WindowEventInterface directly
144 virtual void TouchEvent( Dali::Integration::Point& point, unsigned long timeStamp )
146 mHandler->SendEvent( point, timeStamp );
148 virtual void KeyEvent( Dali::KeyEvent& keyEvent )
150 mHandler->SendEvent( keyEvent );
152 virtual void WheelEvent( Dali::WheelEvent& wheelEvent )
154 mHandler->SendWheelEvent( wheelEvent );
156 virtual void DamageEvent( Rect<int>& damageArea )
158 mHandler->SendEvent( damageArea );
160 virtual void WindowFocusOut( )
162 // used to do some work with ime
164 virtual void WindowFocusIn()
166 // used to do some work with ime
170 XEventManager mXEventManager;
171 EventHandler* mHandler;
175 EventHandler::EventHandler( RenderSurface* surface, CoreEventInterface& coreEventInterface, GestureManager& gestureManager, DamageObserver& damageObserver, DragAndDropDetectorPtr dndDetector )
176 : mCoreEventInterface(coreEventInterface),
177 mGestureManager( gestureManager ),
178 mStyleMonitor( StyleMonitor::Get() ),
179 mDamageObserver( damageObserver ),
180 mRotationObserver( NULL ),
181 mDragAndDropDetector( dndDetector ),
182 mClipboardEventNotifier( ClipboardEventNotifier::Get() ),
183 mClipboard(Clipboard::Get()),
186 Ecore_X_Window window = 0;
188 // this code only works with the EcoreX11 RenderSurface so need to downcast
189 ECore::WindowRenderSurface* ecoreSurface = dynamic_cast< ECore::WindowRenderSurface* >( surface );
192 window = ecoreSurface->GetXWindow();
193 Display* display = static_cast< Display* >(ecore_x_display_get());
195 mImpl = new Impl(this, window, display );
201 EventHandler::~EventHandler()
208 mGestureManager.Stop();
211 void EventHandler::SendEvent(Dali::Integration::Point& point, unsigned long timeStamp)
215 timeStamp = GetCurrentMilliSeconds();
218 Integration::TouchEvent touchEvent;
219 Integration::HoverEvent hoverEvent;
220 Integration::TouchEventCombiner::EventDispatchType type = mCombiner.GetNextTouchEvent(point, timeStamp, touchEvent, hoverEvent);
221 if(type != Integration::TouchEventCombiner::DispatchNone )
223 DALI_LOG_INFO(gTouchEventLogFilter, Debug::General, "%d: Device %d: Button state %d (%.2f, %.2f)\n", timeStamp, point.GetDeviceId(), point.GetState(), point.GetLocalPosition().x, point.GetLocalPosition().y);
225 // First the touch and/or hover event & related gesture events are queued
226 if(type == Integration::TouchEventCombiner::DispatchTouch || type == Integration::TouchEventCombiner::DispatchBoth)
228 mCoreEventInterface.QueueCoreEvent( touchEvent );
229 mGestureManager.SendEvent(touchEvent);
232 if(type == Integration::TouchEventCombiner::DispatchHover || type == Integration::TouchEventCombiner::DispatchBoth)
234 mCoreEventInterface.QueueCoreEvent( hoverEvent );
237 // Next the events are processed with a single call into Core
238 mCoreEventInterface.ProcessCoreEvents();
242 void EventHandler::SendEvent(KeyEvent& keyEvent)
244 Dali::PhysicalKeyboard physicalKeyboard = PhysicalKeyboard::Get();
245 if ( physicalKeyboard )
247 if ( ! KeyLookup::IsDeviceButton( keyEvent.keyPressedName.c_str() ) )
249 GetImplementation( physicalKeyboard ).KeyReceived( keyEvent.time > 1 );
253 // Create KeyEvent and send to Core.
254 Integration::KeyEvent event(keyEvent.keyPressedName, keyEvent.keyPressed, keyEvent.keyCode,
255 keyEvent.keyModifier, keyEvent.time, static_cast<Integration::KeyEvent::State>(keyEvent.state));
256 mCoreEventInterface.QueueCoreEvent( event );
257 mCoreEventInterface.ProcessCoreEvents();
260 void EventHandler::SendWheelEvent( WheelEvent& wheelEvent )
262 // Create WheelEvent and send to Core.
263 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
264 mCoreEventInterface.QueueCoreEvent( event );
265 mCoreEventInterface.ProcessCoreEvents();
268 void EventHandler::SendEvent( StyleChange::Type styleChange )
270 DALI_ASSERT_DEBUG( mStyleMonitor && "StyleMonitor Not Available" );
271 GetImplementation( mStyleMonitor ).StyleChanged(styleChange);
274 void EventHandler::SendEvent( const DamageArea& area )
276 mDamageObserver.OnDamaged( area );
279 void EventHandler::SendRotationPrepareEvent( const RotationEvent& event )
281 if( mRotationObserver != NULL )
283 mRotationObserver->OnRotationPrepare( event );
287 void EventHandler::SendRotationRequestEvent( )
289 if( mRotationObserver != NULL )
291 mRotationObserver->OnRotationRequest( );
295 void EventHandler::FeedTouchPoint( TouchPoint& point, int timeStamp)
297 Integration::Point convertedPoint( point );
298 SendEvent( convertedPoint, timeStamp );
301 void EventHandler::FeedWheelEvent( WheelEvent& wheelEvent )
303 SendWheelEvent( wheelEvent );
306 void EventHandler::FeedKeyEvent( KeyEvent& event )
311 void EventHandler::FeedEvent( Integration::Event& event )
313 mCoreEventInterface.QueueCoreEvent( event );
314 mCoreEventInterface.ProcessCoreEvents();
317 void EventHandler::Reset()
321 // Any touch listeners should be told of the interruption.
322 Integration::TouchEvent event;
323 Integration::Point point;
324 point.SetState( PointState::INTERRUPTED );
325 event.AddPoint( point );
327 // First the touch event & related gesture events are queued
328 mCoreEventInterface.QueueCoreEvent( event );
329 mGestureManager.SendEvent( event );
331 // Next the events are processed with a single call into Core
332 mCoreEventInterface.ProcessCoreEvents();
335 void EventHandler::Pause()
341 void EventHandler::Resume()
347 void EventHandler::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
349 mDragAndDropDetector = detector;
352 void EventHandler::SetRotationObserver( RotationObserver* observer )
354 mRotationObserver = observer;
357 } // namespace Adaptor
359 } // namespace Internal