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::TouchPoint& 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;
174 EventHandler::EventHandler( RenderSurface* surface, CoreEventInterface& coreEventInterface, GestureManager& gestureManager, DamageObserver& damageObserver, DragAndDropDetectorPtr dndDetector )
175 : mCoreEventInterface(coreEventInterface),
176 mGestureManager( gestureManager ),
177 mStyleMonitor( StyleMonitor::Get() ),
178 mDamageObserver( damageObserver ),
179 mRotationObserver( NULL ),
180 mDragAndDropDetector( dndDetector ),
181 mClipboardEventNotifier( ClipboardEventNotifier::Get() ),
182 mClipboard(Clipboard::Get()),
185 Ecore_X_Window window = 0;
187 // this code only works with the EcoreX11 RenderSurface so need to downcast
188 ECore::WindowRenderSurface* ecoreSurface = dynamic_cast< ECore::WindowRenderSurface* >( surface );
191 window = ecoreSurface->GetXWindow();
192 Display* display = static_cast< Display* >(ecore_x_display_get());
194 mImpl = new Impl(this, window, display );
200 EventHandler::~EventHandler()
207 mGestureManager.Stop();
210 void EventHandler::SendEvent(TouchPoint& point, unsigned long timeStamp)
214 timeStamp = GetCurrentMilliSeconds();
217 Integration::TouchEvent touchEvent;
218 Integration::HoverEvent hoverEvent;
219 Integration::TouchEventCombiner::EventDispatchType type = mCombiner.GetNextTouchEvent(point, timeStamp, touchEvent, hoverEvent);
220 if(type != Integration::TouchEventCombiner::DispatchNone )
222 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);
224 // First the touch and/or hover event & related gesture events are queued
225 if(type == Integration::TouchEventCombiner::DispatchTouch || type == Integration::TouchEventCombiner::DispatchBoth)
227 mCoreEventInterface.QueueCoreEvent( touchEvent );
228 mGestureManager.SendEvent(touchEvent);
231 if(type == Integration::TouchEventCombiner::DispatchHover || type == Integration::TouchEventCombiner::DispatchBoth)
233 mCoreEventInterface.QueueCoreEvent( hoverEvent );
236 // Next the events are processed with a single call into Core
237 mCoreEventInterface.ProcessCoreEvents();
241 void EventHandler::SendEvent(KeyEvent& keyEvent)
243 Dali::PhysicalKeyboard physicalKeyboard = PhysicalKeyboard::Get();
244 if ( physicalKeyboard )
246 if ( ! KeyLookup::IsDeviceButton( keyEvent.keyPressedName.c_str() ) )
248 GetImplementation( physicalKeyboard ).KeyReceived( keyEvent.time > 1 );
252 // Create KeyEvent and send to Core.
253 Integration::KeyEvent event(keyEvent.keyPressedName, keyEvent.keyPressed, keyEvent.keyCode,
254 keyEvent.keyModifier, keyEvent.time, static_cast<Integration::KeyEvent::State>(keyEvent.state));
255 mCoreEventInterface.QueueCoreEvent( event );
256 mCoreEventInterface.ProcessCoreEvents();
259 void EventHandler::SendWheelEvent( WheelEvent& wheelEvent )
261 // Create WheelEvent and send to Core.
262 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
263 mCoreEventInterface.QueueCoreEvent( event );
264 mCoreEventInterface.ProcessCoreEvents();
267 void EventHandler::SendEvent( StyleChange::Type styleChange )
269 DALI_ASSERT_DEBUG( mStyleMonitor && "StyleMonitor Not Available" );
270 GetImplementation( mStyleMonitor ).StyleChanged(styleChange);
273 void EventHandler::SendEvent( const DamageArea& area )
275 mDamageObserver.OnDamaged( area );
278 void EventHandler::SendRotationPrepareEvent( const RotationEvent& event )
280 if( mRotationObserver != NULL )
282 mRotationObserver->OnRotationPrepare( event );
286 void EventHandler::SendRotationRequestEvent( )
288 if( mRotationObserver != NULL )
290 mRotationObserver->OnRotationRequest( );
294 void EventHandler::FeedTouchPoint( TouchPoint& point, int timeStamp)
296 SendEvent(point, timeStamp);
299 void EventHandler::FeedWheelEvent( WheelEvent& wheelEvent )
301 SendWheelEvent( wheelEvent );
304 void EventHandler::FeedKeyEvent( KeyEvent& event )
309 void EventHandler::FeedEvent( Integration::Event& event )
311 mCoreEventInterface.QueueCoreEvent( event );
312 mCoreEventInterface.ProcessCoreEvents();
315 void EventHandler::Reset()
319 // Any touch listeners should be told of the interruption.
320 Integration::TouchEvent event;
321 TouchPoint point(0, TouchPoint::Interrupted, 0, 0);
322 event.AddPoint( point );
324 // First the touch event & related gesture events are queued
325 mCoreEventInterface.QueueCoreEvent( event );
326 mGestureManager.SendEvent( event );
328 // Next the events are processed with a single call into Core
329 mCoreEventInterface.ProcessCoreEvents();
332 void EventHandler::Pause()
338 void EventHandler::Resume()
344 void EventHandler::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
346 mDragAndDropDetector = detector;
349 void EventHandler::SetRotationObserver( RotationObserver* observer )
351 mRotationObserver = observer;
354 } // namespace Adaptor
356 } // namespace Internal