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),
134 mXEventManager.Initialize();
142 // @todo Consider allowing the EventHandler class to inherit from WindowEventInterface directly
143 virtual void TouchEvent( Dali::TouchPoint& point, unsigned long timeStamp )
145 mHandler->SendEvent( point, timeStamp );
147 virtual void KeyEvent( Dali::KeyEvent& keyEvent )
149 mHandler->SendEvent( keyEvent );
151 virtual void WheelEvent( Dali::WheelEvent& wheelEvent )
153 mHandler->SendWheelEvent( wheelEvent );
155 virtual void DamageEvent( Rect<int>& damageArea )
157 mHandler->SendEvent( damageArea );
159 virtual void WindowFocusOut( )
161 // used to do some work with ime
163 virtual void WindowFocusIn()
165 // used to do some work with ime
169 XEventManager mXEventManager;
170 EventHandler* mHandler;
173 EventHandler::EventHandler( RenderSurface* surface, CoreEventInterface& coreEventInterface, GestureManager& gestureManager, DamageObserver& damageObserver, DragAndDropDetectorPtr dndDetector )
174 : mCoreEventInterface(coreEventInterface),
175 mGestureManager( gestureManager ),
176 mStyleMonitor( StyleMonitor::Get() ),
177 mDamageObserver( damageObserver ),
178 mRotationObserver( NULL ),
179 mDragAndDropDetector( dndDetector ),
180 mClipboardEventNotifier( ClipboardEventNotifier::Get() ),
181 mClipboard(Clipboard::Get()),
184 Ecore_X_Window window = 0;
186 // this code only works with the EcoreX11 RenderSurface so need to downcast
187 ECore::WindowRenderSurface* ecoreSurface = dynamic_cast< ECore::WindowRenderSurface* >( surface );
190 window = ecoreSurface->GetXWindow();
191 Display* display = static_cast< Display* >(ecore_x_display_get());
193 mImpl = new Impl(this, window, display );
199 EventHandler::~EventHandler()
206 mGestureManager.Stop();
209 void EventHandler::SendEvent(TouchPoint& point, unsigned long timeStamp)
213 timeStamp = GetCurrentMilliSeconds();
216 Integration::TouchEvent touchEvent;
217 Integration::HoverEvent hoverEvent;
218 Integration::TouchEventCombiner::EventDispatchType type = mCombiner.GetNextTouchEvent(point, timeStamp, touchEvent, hoverEvent);
219 if(type != Integration::TouchEventCombiner::DispatchNone )
221 DALI_LOG_INFO(gTouchEventLogFilter, Debug::General, "%d: Device %d: Button state %d (%.2f, %.2f)\n", timeStamp, point.deviceId, point.state, point.local.x, point.local.y);
223 // First the touch and/or hover event & related gesture events are queued
224 if(type == Integration::TouchEventCombiner::DispatchTouch || type == Integration::TouchEventCombiner::DispatchBoth)
226 mCoreEventInterface.QueueCoreEvent( touchEvent );
227 mGestureManager.SendEvent(touchEvent);
230 if(type == Integration::TouchEventCombiner::DispatchHover || type == Integration::TouchEventCombiner::DispatchBoth)
232 mCoreEventInterface.QueueCoreEvent( hoverEvent );
235 // Next the events are processed with a single call into Core
236 mCoreEventInterface.ProcessCoreEvents();
240 void EventHandler::SendEvent(KeyEvent& keyEvent)
242 Dali::PhysicalKeyboard physicalKeyboard = PhysicalKeyboard::Get();
243 if ( physicalKeyboard )
245 if ( ! KeyLookup::IsDeviceButton( keyEvent.keyPressedName.c_str() ) )
247 GetImplementation( physicalKeyboard ).KeyReceived( keyEvent.time > 1 );
251 // Create KeyEvent and send to Core.
252 Integration::KeyEvent event(keyEvent.keyPressedName, keyEvent.keyPressed, keyEvent.keyCode,
253 keyEvent.keyModifier, keyEvent.time, static_cast<Integration::KeyEvent::State>(keyEvent.state));
254 mCoreEventInterface.QueueCoreEvent( event );
255 mCoreEventInterface.ProcessCoreEvents();
258 void EventHandler::SendWheelEvent( WheelEvent& wheelEvent )
260 // Create WheelEvent and send to Core.
261 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
262 mCoreEventInterface.QueueCoreEvent( event );
263 mCoreEventInterface.ProcessCoreEvents();
266 void EventHandler::SendEvent( StyleChange::Type styleChange )
268 DALI_ASSERT_DEBUG( mStyleMonitor && "StyleMonitor Not Available" );
269 GetImplementation( mStyleMonitor ).StyleChanged(styleChange);
272 void EventHandler::SendEvent( const DamageArea& area )
274 mDamageObserver.OnDamaged( area );
277 void EventHandler::SendRotationPrepareEvent( const RotationEvent& event )
279 if( mRotationObserver != NULL )
281 mRotationObserver->OnRotationPrepare( event );
285 void EventHandler::SendRotationRequestEvent( )
287 if( mRotationObserver != NULL )
289 mRotationObserver->OnRotationRequest( );
293 void EventHandler::FeedTouchPoint( TouchPoint& point, int timeStamp)
295 SendEvent(point, timeStamp);
298 void EventHandler::FeedWheelEvent( WheelEvent& wheelEvent )
300 SendWheelEvent( wheelEvent );
303 void EventHandler::FeedKeyEvent( KeyEvent& event )
308 void EventHandler::FeedEvent( Integration::Event& event )
310 mCoreEventInterface.QueueCoreEvent( event );
311 mCoreEventInterface.ProcessCoreEvents();
314 void EventHandler::Reset()
318 // Any touch listeners should be told of the interruption.
319 Integration::TouchEvent event;
320 TouchPoint point(0, TouchPoint::Interrupted, 0, 0);
321 event.AddPoint( point );
323 // First the touch event & related gesture events are queued
324 mCoreEventInterface.QueueCoreEvent( event );
325 mGestureManager.SendEvent( event );
327 // Next the events are processed with a single call into Core
328 mCoreEventInterface.ProcessCoreEvents();
331 void EventHandler::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
333 mDragAndDropDetector = detector;
336 void EventHandler::SetRotationObserver( RotationObserver* observer )
338 mRotationObserver = observer;
341 } // namespace Adaptor
343 } // namespace Internal