Add trace logs to check performance
[platform/core/uifw/dali-adaptor.git] / dali / internal / window-system / common / window-impl.cpp
1 /*
2  * Copyright (c) 2022 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/window-impl.h>
20
21 // EXTERNAL HEADERS
22 #include <dali/devel-api/adaptor-framework/orientation.h>
23 #include <dali/devel-api/events/key-event-devel.h>
24 #include <dali/integration-api/core.h>
25 #include <dali/integration-api/events/touch-event-integ.h>
26 #include <dali/integration-api/events/touch-integ.h>
27 #include <dali/public-api/actors/actor.h>
28 #include <dali/public-api/actors/camera-actor.h>
29 #include <dali/public-api/actors/layer.h>
30 #include <dali/public-api/adaptor-framework/window-enumerations.h>
31 #include <dali/public-api/render-tasks/render-task-list.h>
32 #include <dali/public-api/render-tasks/render-task.h>
33 #include <dali/public-api/rendering/frame-buffer.h>
34 #include <thread>
35
36 // INTERNAL HEADERS
37 #include <dali/devel-api/adaptor-framework/accessibility-bridge.h>
38 #include <dali/devel-api/atspi-interfaces/accessible.h>
39 #include <dali/integration-api/adaptor-framework/render-surface-interface.h>
40 #include <dali/internal/graphics/gles/egl-graphics.h>
41 #include <dali/internal/window-system/common/event-handler.h>
42 #include <dali/internal/window-system/common/orientation-impl.h>
43 #include <dali/internal/window-system/common/render-surface-factory.h>
44 #include <dali/internal/window-system/common/window-base.h>
45 #include <dali/internal/window-system/common/window-factory.h>
46 #include <dali/internal/window-system/common/window-render-surface.h>
47 #include <dali/internal/window-system/common/window-system.h>
48 #include <dali/internal/window-system/common/window-visibility-observer.h>
49
50 namespace Dali
51 {
52 namespace Internal
53 {
54 namespace Adaptor
55 {
56 namespace
57 {
58 #if defined(DEBUG_ENABLED)
59 Debug::Filter* gWindowLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_WINDOW");
60 #endif
61
62 } // unnamed namespace
63
64 Window* Window::New(const PositionSize& positionSize, const std::string& name, const std::string& className, Dali::WindowType type, bool isTransparent)
65 {
66   Any surface;
67   return Window::New(surface, positionSize, name, className, type, isTransparent);
68 }
69
70 Window* Window::New(Any surface, const PositionSize& positionSize, const std::string& name, const std::string& className, Dali::WindowType type, bool isTransparent)
71 {
72   Window* window         = new Window();
73   window->mIsTransparent = isTransparent;
74   window->Initialize(surface, positionSize, name, className, type);
75   return window;
76 }
77
78 Window::Window()
79 : mWindowSurface(nullptr),
80   mWindowBase(),
81   mParentWindow(NULL),
82   mPreferredAngle(static_cast<int>(WindowOrientation::NO_ORIENTATION_PREFERENCE)),
83   mRotationAngle(0),
84   mWindowWidth(0),
85   mWindowHeight(0),
86   mNativeWindowId(-1),
87   mOrientationMode(Internal::Adaptor::Window::OrientationMode::PORTRAIT),
88   mDeleteRequestSignal(),
89   mFocusChangeSignal(),
90   mResizeSignal(),
91   mVisibilityChangedSignal(),
92   mTransitionEffectEventSignal(),
93   mKeyboardRepeatSettingsChangedSignal(),
94   mAuxiliaryMessageSignal(),
95   mMovedSignal(),
96   mLastKeyEvent(),
97   mLastTouchEvent(),
98   mIsTransparent(false),
99   mIsFocusAcceptable(true),
100   mIconified(false),
101   mOpaqueState(false),
102   mWindowRotationAcknowledgement(false),
103   mFocused(false)
104 {
105 }
106
107 Window::~Window()
108 {
109   if(mScene)
110   {
111     auto bridge     = Accessibility::Bridge::GetCurrentBridge();
112     auto rootLayer  = mScene.GetRootLayer();
113     auto accessible = Accessibility::Accessible::Get(rootLayer);
114     bridge->RemoveTopLevelWindow(accessible);
115     // Related to multi-window case. This is called for default window and non-default window, but it is effective for non-default window.
116     bridge->Emit(accessible, Accessibility::WindowEvent::DESTROY);
117   }
118
119   if(mAdaptor)
120   {
121     mAdaptor->RemoveWindow(this);
122   }
123
124   if(mEventHandler)
125   {
126     mEventHandler->RemoveObserver(*this);
127   }
128 }
129
130 void Window::Initialize(Any surface, const PositionSize& positionSize, const std::string& name, const std::string& className, WindowType type)
131 {
132   // Create a window render surface
133   auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory();
134   mSurface                  = renderSurfaceFactory->CreateWindowRenderSurface(positionSize, surface, mIsTransparent);
135   mWindowSurface            = static_cast<WindowRenderSurface*>(mSurface.get());
136
137   // Get a window base
138   mWindowBase = mWindowSurface->GetWindowBase();
139
140   // Set Window Type
141   mWindowBase->SetType(type);
142
143   // Initialize for Ime window type
144   if(type == WindowType::IME)
145   {
146     mWindowBase->InitializeIme();
147     mWindowSurface->InitializeImeSurface();
148   }
149
150   // Connect signals
151   mWindowBase->IconifyChangedSignal().Connect(this, &Window::OnIconifyChanged);
152   mWindowBase->FocusChangedSignal().Connect(this, &Window::OnFocusChanged);
153   mWindowBase->DeleteRequestSignal().Connect(this, &Window::OnDeleteRequest);
154   mWindowBase->TransitionEffectEventSignal().Connect(this, &Window::OnTransitionEffectEvent);
155   mWindowBase->KeyboardRepeatSettingsChangedSignal().Connect(this, &Window::OnKeyboardRepeatSettingsChanged);
156   mWindowBase->WindowRedrawRequestSignal().Connect(this, &Window::OnWindowRedrawRequest);
157   mWindowBase->UpdatePositionSizeSignal().Connect(this, &Window::OnUpdatePositionSize);
158   mWindowBase->AuxiliaryMessageSignal().Connect(this, &Window::OnAuxiliaryMessage);
159
160   mWindowSurface->OutputTransformedSignal().Connect(this, &Window::OnOutputTransformed);
161
162   AddAuxiliaryHint("wm.policy.win.user.geometry", "1");
163
164   SetClass(name, className);
165
166   mOrientation = Orientation::New(this);
167
168   // Get OrientationMode
169   int screenWidth, screenHeight;
170   WindowSystem::GetScreenSize(screenWidth, screenHeight);
171   if(screenWidth > screenHeight)
172   {
173     mOrientationMode = Internal::Adaptor::Window::OrientationMode::LANDSCAPE;
174   }
175   else
176   {
177     mOrientationMode = Internal::Adaptor::Window::OrientationMode::PORTRAIT;
178   }
179   // For Debugging
180   mNativeWindowId = mWindowBase->GetNativeWindowId();
181 }
182
183 void Window::OnAdaptorSet(Dali::Adaptor& adaptor)
184 {
185   mEventHandler = EventHandlerPtr(new EventHandler(mWindowSurface->GetWindowBase(), *mAdaptor));
186   mEventHandler->AddObserver(*this);
187
188   // Add Window to bridge for ATSPI
189   auto bridge = Accessibility::Bridge::GetCurrentBridge();
190   if(bridge->IsUp())
191   {
192     auto rootLayer  = mScene.GetRootLayer();
193     auto accessible = Accessibility::Accessible::Get(rootLayer);
194     bridge->AddTopLevelWindow(accessible);
195   }
196
197   bridge->EnabledSignal().Connect(this, &Window::OnAccessibilityEnabled);
198   bridge->DisabledSignal().Connect(this, &Window::OnAccessibilityDisabled);
199
200   // If you call the 'Show' before creating the adaptor, the application cannot know the app resource id.
201   // The show must be called after the adaptor is initialized.
202   Show();
203 }
204
205 void Window::OnSurfaceSet(Dali::RenderSurfaceInterface* surface)
206 {
207   mWindowSurface = static_cast<WindowRenderSurface*>(surface);
208 }
209
210 void Window::SetClass(std::string name, std::string className)
211 {
212   mName      = name;
213   mClassName = className;
214   mWindowBase->SetClass(name, className);
215 }
216
217 std::string Window::GetClassName() const
218 {
219   return mClassName;
220 }
221
222 void Window::Raise()
223 {
224   mWindowBase->Raise();
225
226   mSurface->SetFullSwapNextFrame();
227
228   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Raise() \n", this, mNativeWindowId);
229 }
230
231 void Window::Lower()
232 {
233   mWindowBase->Lower();
234
235   mSurface->SetFullSwapNextFrame();
236
237   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Lower() \n", this, mNativeWindowId);
238 }
239
240 void Window::Activate()
241 {
242   mWindowBase->Activate();
243
244   mSurface->SetFullSwapNextFrame();
245
246   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Activate() \n", this, mNativeWindowId);
247 }
248
249 void Window::Maximize(bool maximize)
250 {
251   mWindowBase->Maximize(maximize);
252
253   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Maximize: %d\n", this, mNativeWindowId, maximize);
254 }
255
256 bool Window::IsMaximized() const
257 {
258   return mWindowBase->IsMaximized();
259 }
260
261 void Window::SetMaximumSize(Dali::Window::WindowSize size)
262 {
263   mWindowBase->SetMaximumSize(size);
264 }
265
266 void Window::Minimize(bool minimize)
267 {
268   mWindowBase->Minimize(minimize);
269
270   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Minimize: %d\n", this, mNativeWindowId, minimize);
271 }
272
273 bool Window::IsMinimized() const
274 {
275   return mWindowBase->IsMinimized();
276 }
277
278 void Window::SetMimimumSize(Dali::Window::WindowSize size)
279 {
280   mWindowBase->SetMimimumSize(size);
281 }
282
283 uint32_t Window::GetLayerCount() const
284 {
285   return mScene.GetLayerCount();
286 }
287
288 Dali::Layer Window::GetLayer(uint32_t depth) const
289 {
290   return mScene.GetLayer(depth);
291 }
292
293 Dali::RenderTaskList Window::GetRenderTaskList() const
294 {
295   return mScene.GetRenderTaskList();
296 }
297
298 std::string Window::GetNativeResourceId() const
299 {
300   return mWindowBase->GetNativeWindowResourceId();
301 }
302
303 void Window::AddAvailableOrientation(WindowOrientation orientation)
304 {
305   if(IsOrientationAvailable(orientation) == false)
306   {
307     return;
308   }
309
310   bool found          = false;
311   int  convertedAngle = ConvertToAngle(orientation);
312   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), AddAvailableOrientation: %d\n", this, mNativeWindowId, convertedAngle);
313   for(std::size_t i = 0; i < mAvailableAngles.size(); i++)
314   {
315     if(mAvailableAngles[i] == convertedAngle)
316     {
317       found = true;
318       break;
319     }
320   }
321
322   if(!found)
323   {
324     mAvailableAngles.push_back(convertedAngle);
325     SetAvailableAnlges(mAvailableAngles);
326   }
327 }
328
329 void Window::RemoveAvailableOrientation(WindowOrientation orientation)
330 {
331   if(IsOrientationAvailable(orientation) == false)
332   {
333     return;
334   }
335
336   int convertedAngle = ConvertToAngle(orientation);
337   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), RemoveAvailableOrientation: %d\n", this, mNativeWindowId, convertedAngle);
338   for(std::vector<int>::iterator iter = mAvailableAngles.begin();
339       iter != mAvailableAngles.end();
340       ++iter)
341   {
342     if(*iter == convertedAngle)
343     {
344       mAvailableAngles.erase(iter);
345       break;
346     }
347   }
348
349   SetAvailableAnlges(mAvailableAngles);
350 }
351
352 void Window::SetPreferredOrientation(WindowOrientation orientation)
353 {
354   if(orientation < WindowOrientation::NO_ORIENTATION_PREFERENCE || orientation > WindowOrientation::LANDSCAPE_INVERSE)
355   {
356     DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window::CheckOrientation: Invalid input orientation [%d]\n", orientation);
357     return;
358   }
359   mPreferredAngle = ConvertToAngle(orientation);
360   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), SetPreferredOrientation: %d\n", this, mNativeWindowId, mPreferredAngle);
361   mWindowBase->SetPreferredAngle(mPreferredAngle);
362 }
363
364 WindowOrientation Window::GetPreferredOrientation()
365 {
366   WindowOrientation preferredOrientation = ConvertToOrientation(mPreferredAngle);
367   return preferredOrientation;
368 }
369
370 void Window::SetPositionSizeWithOrientation(PositionSize positionSize, WindowOrientation orientation)
371 {
372   int angle = ConvertToAngle(orientation);
373   mWindowBase->SetPositionSizeWithAngle(positionSize, angle);
374 }
375
376 void Window::EmitAccessibilityHighlightSignal(bool highlight)
377 {
378   Dali::Window handle(this);
379   mAccessibilityHighlightSignal.Emit(handle, highlight);
380 }
381
382 void Window::SetAvailableAnlges(const std::vector<int>& angles)
383 {
384   if(angles.size() > 4)
385   {
386     DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window::SetAvailableAnlges: Invalid vector size! [%d]\n", angles.size());
387     return;
388   }
389
390   mWindowBase->SetAvailableAnlges(angles);
391 }
392
393 int Window::ConvertToAngle(WindowOrientation orientation)
394 {
395   int convertAngle = static_cast<int>(orientation);
396   if(mOrientationMode == Internal::Adaptor::Window::OrientationMode::LANDSCAPE)
397   {
398     switch(orientation)
399     {
400       case WindowOrientation::LANDSCAPE:
401       {
402         convertAngle = 0;
403         break;
404       }
405       case WindowOrientation::PORTRAIT:
406       {
407         convertAngle = 90;
408         break;
409       }
410       case WindowOrientation::LANDSCAPE_INVERSE:
411       {
412         convertAngle = 180;
413         break;
414       }
415       case WindowOrientation::PORTRAIT_INVERSE:
416       {
417         convertAngle = 270;
418         break;
419       }
420       case WindowOrientation::NO_ORIENTATION_PREFERENCE:
421       {
422         convertAngle = -1;
423         break;
424       }
425     }
426   }
427   return convertAngle;
428 }
429
430 WindowOrientation Window::ConvertToOrientation(int angle) const
431 {
432   WindowOrientation orientation = static_cast<WindowOrientation>(angle);
433   if(mOrientationMode == Internal::Adaptor::Window::OrientationMode::LANDSCAPE)
434   {
435     switch(angle)
436     {
437       case 0:
438       {
439         orientation = WindowOrientation::LANDSCAPE;
440         break;
441       }
442       case 90:
443       {
444         orientation = WindowOrientation::PORTRAIT;
445         break;
446       }
447       case 180:
448       {
449         orientation = WindowOrientation::LANDSCAPE_INVERSE;
450         break;
451       }
452       case 270:
453       {
454         orientation = WindowOrientation::PORTRAIT_INVERSE;
455         break;
456       }
457       case -1:
458       {
459         orientation = WindowOrientation::NO_ORIENTATION_PREFERENCE;
460         break;
461       }
462     }
463   }
464   return orientation;
465 }
466
467 bool Window::IsOrientationAvailable(WindowOrientation orientation) const
468 {
469   if(orientation <= WindowOrientation::NO_ORIENTATION_PREFERENCE || orientation > WindowOrientation::LANDSCAPE_INVERSE)
470   {
471     DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window::IsOrientationAvailable: Invalid input orientation [%d]\n", orientation);
472     return false;
473   }
474   return true;
475 }
476
477 Dali::Any Window::GetNativeHandle() const
478 {
479   return mWindowSurface->GetNativeWindow();
480 }
481
482 void Window::SetAcceptFocus(bool accept)
483 {
484   mIsFocusAcceptable = accept;
485
486   mWindowBase->SetAcceptFocus(accept);
487 }
488
489 bool Window::IsFocusAcceptable() const
490 {
491   return mIsFocusAcceptable;
492 }
493
494 void Window::Show()
495 {
496   mVisible = true;
497
498   mWindowBase->Show();
499
500   if(!mIconified)
501   {
502     Dali::Window handle(this);
503     mVisibilityChangedSignal.Emit(handle, true);
504     Dali::Accessibility::Bridge::GetCurrentBridge()->WindowShown(handle);
505
506     WindowVisibilityObserver* observer(mAdaptor);
507     observer->OnWindowShown();
508   }
509
510   mSurface->SetFullSwapNextFrame();
511
512   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Show(): iconified = %d, visible = %d\n", this, mNativeWindowId, mIconified, mVisible);
513 }
514
515 void Window::Hide()
516 {
517   mVisible = false;
518
519   mWindowBase->Hide();
520
521   if(!mIconified)
522   {
523     Dali::Window handle(this);
524     mVisibilityChangedSignal.Emit(handle, false);
525     Dali::Accessibility::Bridge::GetCurrentBridge()->WindowHidden(handle);
526
527     WindowVisibilityObserver* observer(mAdaptor);
528     observer->OnWindowHidden();
529   }
530
531   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Hide(): iconified = %d, visible = %d\n", this, mNativeWindowId, mIconified, mVisible);
532 }
533
534 bool Window::IsVisible() const
535 {
536   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), IsVisible(): iconified = %d, visible = %d\n", this, mNativeWindowId, mIconified, mVisible);
537   return mVisible && !mIconified;
538 }
539
540 unsigned int Window::GetSupportedAuxiliaryHintCount() const
541 {
542   return mWindowBase->GetSupportedAuxiliaryHintCount();
543 }
544
545 std::string Window::GetSupportedAuxiliaryHint(unsigned int index) const
546 {
547   return mWindowBase->GetSupportedAuxiliaryHint(index);
548 }
549
550 unsigned int Window::AddAuxiliaryHint(const std::string& hint, const std::string& value)
551 {
552   return mWindowBase->AddAuxiliaryHint(hint, value);
553 }
554
555 bool Window::RemoveAuxiliaryHint(unsigned int id)
556 {
557   return mWindowBase->RemoveAuxiliaryHint(id);
558 }
559
560 bool Window::SetAuxiliaryHintValue(unsigned int id, const std::string& value)
561 {
562   return mWindowBase->SetAuxiliaryHintValue(id, value);
563 }
564
565 std::string Window::GetAuxiliaryHintValue(unsigned int id) const
566 {
567   return mWindowBase->GetAuxiliaryHintValue(id);
568 }
569
570 unsigned int Window::GetAuxiliaryHintId(const std::string& hint) const
571 {
572   return mWindowBase->GetAuxiliaryHintId(hint);
573 }
574
575 void Window::SetInputRegion(const Rect<int>& inputRegion)
576 {
577   Rect<int> convertRegion = RecalculateRect(inputRegion);
578
579   DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window (%p), WinId (%d), SetInputRegion, RecalculateRegion, (%d,%d), (%d x %d)\n", this, mNativeWindowId, convertRegion.x, convertRegion.y, convertRegion.width, convertRegion.height);
580
581   mWindowBase->SetInputRegion(convertRegion);
582 }
583
584 void Window::SetType(WindowType type)
585 {
586   mWindowBase->SetType(type);
587 }
588
589 WindowType Window::GetType() const
590 {
591   return mWindowBase->GetType();
592 }
593
594 WindowOperationResult Window::SetNotificationLevel(WindowNotificationLevel level)
595 {
596   WindowType type = mWindowBase->GetType();
597   if(type != WindowType::NOTIFICATION)
598   {
599     DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window::SetNotificationLevel: Not supported window type [%d]\n", type);
600     return WindowOperationResult::INVALID_OPERATION;
601   }
602
603   return mWindowBase->SetNotificationLevel(level);
604 }
605
606 WindowNotificationLevel Window::GetNotificationLevel() const
607 {
608   WindowType type = mWindowBase->GetType();
609   if(type != WindowType::NOTIFICATION)
610   {
611     DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window::GetNotificationLevel: Not supported window type [%d]\n", type);
612     return WindowNotificationLevel::NONE;
613   }
614
615   return mWindowBase->GetNotificationLevel();
616 }
617
618 void Window::SetOpaqueState(bool opaque)
619 {
620   mOpaqueState = opaque;
621
622   mWindowBase->SetOpaqueState(opaque);
623
624   DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window::SetOpaqueState: opaque = %d\n", opaque);
625 }
626
627 bool Window::IsOpaqueState() const
628 {
629   return mOpaqueState;
630 }
631
632 WindowOperationResult Window::SetScreenOffMode(WindowScreenOffMode screenOffMode)
633 {
634   return mWindowBase->SetScreenOffMode(screenOffMode);
635 }
636
637 WindowScreenOffMode Window::GetScreenOffMode() const
638 {
639   return mWindowBase->GetScreenOffMode();
640 }
641
642 WindowOperationResult Window::SetBrightness(int brightness)
643 {
644   if(brightness < 0 || brightness > 100)
645   {
646     DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window::SetBrightness: Invalid brightness value [%d]\n", brightness);
647     return WindowOperationResult::INVALID_OPERATION;
648   }
649
650   return mWindowBase->SetBrightness(brightness);
651 }
652
653 int Window::GetBrightness() const
654 {
655   return mWindowBase->GetBrightness();
656 }
657
658 void Window::SetSize(Dali::Window::WindowSize size)
659 {
660   PositionSize oldRect = mSurface->GetPositionSize();
661
662   mWindowSurface->MoveResize(PositionSize(oldRect.x, oldRect.y, size.GetWidth(), size.GetHeight()));
663
664   PositionSize newRect = mSurface->GetPositionSize();
665
666   // When surface size is updated, inform adaptor of resizing and emit ResizeSignal
667   if((oldRect.width != newRect.width) || (oldRect.height != newRect.height))
668   {
669     Uint16Pair newSize(newRect.width, newRect.height);
670
671     mWindowWidth  = newRect.width;
672     mWindowHeight = newRect.height;
673
674     SurfaceResized();
675
676     mAdaptor->SurfaceResizePrepare(mSurface.get(), newSize);
677
678     DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), current angle (%d), SetSize(): resize signal [%d x %d]\n", this, mNativeWindowId, mRotationAngle, newRect.width, newRect.height);
679
680     Dali::Window handle(this);
681     mResizeSignal.Emit(handle, newSize);
682
683     mAdaptor->SurfaceResizeComplete(mSurface.get(), newSize);
684   }
685
686   mSurface->SetFullSwapNextFrame();
687
688   Dali::Accessibility::Accessible::Get(mScene.GetRootLayer())->EmitBoundsChanged(Dali::Rect<>(oldRect.x, oldRect.y, size.GetWidth(), size.GetHeight()));
689 }
690
691 Dali::Window::WindowSize Window::GetSize() const
692 {
693   PositionSize positionSize = mSurface->GetPositionSize();
694
695   return Dali::Window::WindowSize(positionSize.width, positionSize.height);
696 }
697
698 void Window::SetPosition(Dali::Window::WindowPosition position)
699 {
700   PositionSize oldRect = mSurface->GetPositionSize();
701   int32_t      newX    = position.GetX();
702   int32_t      newY    = position.GetY();
703
704   mWindowSurface->MoveResize(PositionSize(newX, newY, oldRect.width, oldRect.height));
705
706   if((oldRect.x != newX) || (oldRect.y != newY))
707   {
708     Dali::Window                 handle(this);
709     Dali::Window::WindowPosition newPosition(newX, newY);
710
711     DALI_LOG_RELEASE_INFO("send moved signal with new position: %d, %d\n", newPosition.GetX(), newPosition.GetY());
712     mMovedSignal.Emit(handle, newPosition);
713   }
714
715   mSurface->SetFullSwapNextFrame();
716
717   Dali::Accessibility::Accessible::Get(mScene.GetRootLayer())->EmitBoundsChanged(Dali::Rect<>(position.GetX(), position.GetY(), oldRect.width, oldRect.height));
718 }
719
720 Dali::Window::WindowPosition Window::GetPosition() const
721 {
722   PositionSize positionSize = mSurface->GetPositionSize();
723
724   return Dali::Window::WindowPosition(positionSize.x, positionSize.y);
725 }
726
727 PositionSize Window::GetPositionSize() const
728 {
729   return mSurface->GetPositionSize();
730 }
731
732 void Window::SetPositionSize(PositionSize positionSize)
733 {
734   PositionSize oldRect = mSurface->GetPositionSize();
735   Dali::Window handle(this);
736
737   mWindowSurface->MoveResize(positionSize);
738
739   PositionSize newRect = mSurface->GetPositionSize();
740
741   if((oldRect.x != newRect.x) || (oldRect.y != newRect.y))
742   {
743     Dali::Window::WindowPosition position(newRect.x, newRect.y);
744     mMovedSignal.Emit(handle, position);
745   }
746
747   // When surface size is updated, inform adaptor of resizing and emit ResizeSignal
748   if((oldRect.width != newRect.width) || (oldRect.height != newRect.height))
749   {
750     Uint16Pair newSize(newRect.width, newRect.height);
751
752     mWindowWidth  = newRect.width;
753     mWindowHeight = newRect.height;
754
755     SurfaceResized();
756
757     mAdaptor->SurfaceResizePrepare(mSurface.get(), newSize);
758
759     DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), current angle (%d), SetPositionSize():resize signal [%d x %d]\n", this, mNativeWindowId, mRotationAngle, newRect.width, newRect.height);
760     mResizeSignal.Emit(handle, newSize);
761     mAdaptor->SurfaceResizeComplete(mSurface.get(), newSize);
762   }
763
764   mSurface->SetFullSwapNextFrame();
765
766   Dali::Accessibility::Accessible::Get(mScene.GetRootLayer())->EmitBoundsChanged(Dali::Rect<>(positionSize.x, positionSize.y, positionSize.width, positionSize.height));
767 }
768
769 Dali::Layer Window::GetRootLayer() const
770 {
771   return mScene.GetRootLayer();
772 }
773
774 void Window::SetTransparency(bool transparent)
775 {
776   mWindowSurface->SetTransparency(transparent);
777 }
778
779 bool Window::GrabKey(Dali::KEY key, KeyGrab::KeyGrabMode grabMode)
780 {
781   return mWindowBase->GrabKey(key, grabMode);
782 }
783
784 bool Window::UngrabKey(Dali::KEY key)
785 {
786   return mWindowBase->UngrabKey(key);
787 }
788
789 bool Window::GrabKeyList(const Dali::Vector<Dali::KEY>& key, const Dali::Vector<KeyGrab::KeyGrabMode>& grabMode, Dali::Vector<bool>& result)
790 {
791   return mWindowBase->GrabKeyList(key, grabMode, result);
792 }
793
794 bool Window::UngrabKeyList(const Dali::Vector<Dali::KEY>& key, Dali::Vector<bool>& result)
795 {
796   return mWindowBase->UngrabKeyList(key, result);
797 }
798
799 void Window::OnIconifyChanged(bool iconified)
800 {
801   if(iconified)
802   {
803     mIconified = true;
804
805     if(mVisible)
806     {
807       Dali::Window handle(this);
808       mVisibilityChangedSignal.Emit(handle, false);
809       Dali::Accessibility::Bridge::GetCurrentBridge()->WindowHidden(handle);
810
811       WindowVisibilityObserver* observer(mAdaptor);
812       observer->OnWindowHidden();
813     }
814
815     DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Iconified: visible = %d\n", this, mNativeWindowId, mVisible);
816   }
817   else
818   {
819     mIconified = false;
820
821     if(mVisible)
822     {
823       Dali::Window handle(this);
824       mVisibilityChangedSignal.Emit(handle, true);
825       Dali::Accessibility::Bridge::GetCurrentBridge()->WindowShown(handle);
826
827       WindowVisibilityObserver* observer(mAdaptor);
828       observer->OnWindowShown();
829     }
830
831     DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Deiconified: visible = %d\n", this, mNativeWindowId, mVisible);
832   }
833
834   mSurface->SetFullSwapNextFrame();
835 }
836
837 void Window::OnFocusChanged(bool focusIn)
838 {
839   Dali::Window handle(this);
840   mFocusChangeSignal.Emit(handle, focusIn);
841
842   mSurface->SetFullSwapNextFrame();
843
844   if(auto bridge = Dali::Accessibility::Bridge::GetCurrentBridge())
845   {
846     if(focusIn)
847     {
848       bridge->WindowFocused(handle);
849     }
850     else
851     {
852       bridge->WindowUnfocused(handle);
853     }
854   }
855   mFocused = focusIn;
856 }
857
858 void Window::OnOutputTransformed()
859 {
860   PositionSize positionSize = mSurface->GetPositionSize();
861
862   int orientation = (mRotationAngle + mWindowBase->GetScreenRotationAngle()) % 360;
863   SurfaceRotated(static_cast<float>(positionSize.width), static_cast<float>(positionSize.height), orientation);
864
865   mAdaptor->SurfaceResizePrepare(mSurface.get(), Adaptor::SurfaceSize(positionSize.width, positionSize.height));
866   mAdaptor->SurfaceResizeComplete(mSurface.get(), Adaptor::SurfaceSize(positionSize.width, positionSize.height));
867 }
868
869 void Window::OnDeleteRequest()
870 {
871   mDeleteRequestSignal.Emit();
872 }
873
874 void Window::OnTransitionEffectEvent(WindowEffectState state, WindowEffectType type)
875 {
876   Dali::Window handle(this);
877   mTransitionEffectEventSignal.Emit(handle, state, type);
878 }
879
880 void Window::OnKeyboardRepeatSettingsChanged()
881 {
882   Dali::Window handle(this);
883   mKeyboardRepeatSettingsChangedSignal.Emit();
884 }
885
886 void Window::OnWindowRedrawRequest()
887 {
888   mAdaptor->RenderOnce();
889 }
890
891 void Window::OnUpdatePositionSize(Dali::PositionSize& positionSize)
892 {
893   bool         resized = false;
894   bool         moved   = false;
895   Dali::Window handle(this);
896   PositionSize oldRect = mSurface->GetPositionSize();
897
898   mWindowSurface->UpdatePositionSize(positionSize);
899
900   PositionSize newRect = positionSize;
901
902   if((oldRect.x != newRect.x) || (oldRect.y != newRect.y))
903   {
904     moved = true;
905   }
906
907   if((oldRect.width != newRect.width) || (oldRect.height != newRect.height))
908   {
909     resized = true;
910   }
911
912   if(moved)
913   {
914     Dali::Window::WindowPosition position(newRect.x, newRect.y);
915     mMovedSignal.Emit(handle, position);
916   }
917
918   // When surface size is updated, inform adaptor of resizing and emit ResizeSignal
919   if(resized)
920   {
921     Uint16Pair newSize(newRect.width, newRect.height);
922
923     mWindowWidth  = newRect.width;
924     mWindowHeight = newRect.height;
925
926     SurfaceResized();
927
928     mAdaptor->SurfaceResizePrepare(mSurface.get(), newSize);
929
930     DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Updated PositionSize by server :resize signal [%d x %d]\n", this, mNativeWindowId, newRect.width, newRect.height);
931     mResizeSignal.Emit(handle, newSize);
932     mAdaptor->SurfaceResizeComplete(mSurface.get(), newSize);
933   }
934
935   mSurface->SetFullSwapNextFrame();
936
937   Dali::Accessibility::Accessible::Get(mScene.GetRootLayer())->EmitBoundsChanged(Dali::Rect<>(positionSize.x, positionSize.y, positionSize.width, positionSize.height));
938 }
939
940 void Window::OnTouchPoint(Dali::Integration::Point& point, int timeStamp)
941 {
942   mLastTouchEvent = Dali::Integration::NewTouchEvent(timeStamp, point);
943   FeedTouchPoint(point, timeStamp);
944 }
945
946 void Window::OnWheelEvent(Dali::Integration::WheelEvent& wheelEvent)
947 {
948   FeedWheelEvent(wheelEvent);
949 }
950
951 void Window::OnKeyEvent(Dali::Integration::KeyEvent& keyEvent)
952 {
953   mLastKeyEvent = Dali::DevelKeyEvent::New(keyEvent.keyName, keyEvent.logicalKey, keyEvent.keyString, keyEvent.keyCode, keyEvent.keyModifier, keyEvent.time, static_cast<Dali::KeyEvent::State>(keyEvent.state), keyEvent.compose, keyEvent.deviceName, keyEvent.deviceClass, keyEvent.deviceSubclass);
954   FeedKeyEvent(keyEvent);
955 }
956
957 void Window::OnRotation(const RotationEvent& rotation)
958 {
959   PositionSize newPositionSize(rotation.x, rotation.y, rotation.width, rotation.height);
960
961   mRotationAngle = rotation.angle;
962   mWindowWidth   = rotation.width;
963   mWindowHeight  = rotation.height;
964
965   // Notify that the orientation is changed
966   mOrientation->OnOrientationChange(rotation);
967
968   mWindowSurface->RequestRotation(mRotationAngle, newPositionSize);
969
970   int orientation = (mRotationAngle + mWindowBase->GetScreenRotationAngle()) % 360;
971   SurfaceRotated(mWindowWidth, mWindowHeight, orientation);
972
973   mAdaptor->SurfaceResizePrepare(mSurface.get(), Adaptor::SurfaceSize(mWindowWidth, mWindowHeight));
974
975   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), OnRotation(): x[%d], y[%d], resize signal emit [%d x %d]\n", this, mNativeWindowId, newPositionSize.x, newPositionSize.y, mWindowWidth, mWindowHeight);
976   // Emit signal
977   Dali::Window handle(this);
978   mResizeSignal.Emit(handle, Dali::Window::WindowSize(mWindowWidth, mWindowHeight));
979
980   mAdaptor->SurfaceResizeComplete(mSurface.get(), Adaptor::SurfaceSize(mWindowWidth, mWindowHeight));
981 }
982
983 void Window::OnPause()
984 {
985   if(mEventHandler)
986   {
987     mEventHandler->Pause();
988   }
989 }
990
991 void Window::OnResume()
992 {
993   if(mEventHandler)
994   {
995     mEventHandler->Resume();
996   }
997
998   mSurface->SetFullSwapNextFrame();
999 }
1000
1001 void Window::OnAuxiliaryMessage(const std::string& key, const std::string& value, const Property::Array& options)
1002 {
1003   mAuxiliaryMessageSignal.Emit(key, value, options);
1004 }
1005
1006 void Window::OnAccessibilityEnabled()
1007 {
1008   auto bridge     = Accessibility::Bridge::GetCurrentBridge();
1009   auto rootLayer  = mScene.GetRootLayer();
1010   auto accessible = Accessibility::Accessible::Get(rootLayer);
1011   bridge->AddTopLevelWindow(accessible);
1012
1013   if(!mVisible || mIconified)
1014   {
1015     return;
1016   }
1017
1018   Dali::Window handle(this);
1019   bridge->WindowShown(handle);
1020
1021   if(mFocused)
1022   {
1023     bridge->WindowFocused(handle);
1024   }
1025 }
1026
1027 void Window::OnAccessibilityDisabled()
1028 {
1029   auto bridge     = Accessibility::Bridge::GetCurrentBridge();
1030   auto rootLayer  = mScene.GetRootLayer();
1031   auto accessible = Accessibility::Accessible::Get(rootLayer);
1032   bridge->RemoveTopLevelWindow(accessible);
1033 }
1034
1035 void Window::RecalculateTouchPosition(Integration::Point& point)
1036 {
1037   Vector2 position = point.GetScreenPosition();
1038   Vector2 convertedPosition;
1039
1040   switch(mRotationAngle)
1041   {
1042     case 90:
1043     {
1044       convertedPosition.x = static_cast<float>(mWindowWidth) - position.y;
1045       convertedPosition.y = position.x;
1046       break;
1047     }
1048     case 180:
1049     {
1050       convertedPosition.x = static_cast<float>(mWindowWidth) - position.x;
1051       convertedPosition.y = static_cast<float>(mWindowHeight) - position.y;
1052       break;
1053     }
1054     case 270:
1055     {
1056       convertedPosition.x = position.y;
1057       convertedPosition.y = static_cast<float>(mWindowHeight) - position.x;
1058       break;
1059     }
1060     default:
1061     {
1062       convertedPosition = position;
1063       break;
1064     }
1065   }
1066
1067   point.SetScreenPosition(convertedPosition);
1068 }
1069
1070 Dali::Window Window::Get(Dali::Actor actor)
1071 {
1072   Internal::Adaptor::Window* windowImpl = nullptr;
1073
1074   if(Internal::Adaptor::Adaptor::IsAvailable())
1075   {
1076     Dali::Internal::Adaptor::Adaptor& adaptor = Internal::Adaptor::Adaptor::GetImplementation(Internal::Adaptor::Adaptor::Get());
1077     windowImpl                                = dynamic_cast<Internal::Adaptor::Window*>(adaptor.GetWindow(actor));
1078     if(windowImpl)
1079     {
1080       return Dali::Window(windowImpl);
1081     }
1082   }
1083
1084   return Dali::Window();
1085 }
1086
1087 void Window::SetParent(Dali::Window& parent)
1088 {
1089   if(DALI_UNLIKELY(parent))
1090   {
1091     mParentWindow     = parent;
1092     Dali::Window self = Dali::Window(this);
1093     // check circular parent window setting
1094     if(Dali::DevelWindow::GetParent(parent) == self)
1095     {
1096       Dali::DevelWindow::Unparent(parent);
1097     }
1098     mWindowBase->SetParent(GetImplementation(mParentWindow).mWindowBase, false);
1099   }
1100 }
1101
1102 void Window::SetParent(Dali::Window& parent, bool belowParent)
1103 {
1104   if(DALI_UNLIKELY(parent))
1105   {
1106     mParentWindow     = parent;
1107     Dali::Window self = Dali::Window(this);
1108     // check circular parent window setting
1109     if(Dali::DevelWindow::GetParent(parent) == self)
1110     {
1111       Dali::DevelWindow::Unparent(parent);
1112     }
1113     mWindowBase->SetParent(GetImplementation(mParentWindow).mWindowBase, belowParent);
1114   }
1115 }
1116
1117 void Window::Unparent()
1118 {
1119   mWindowBase->SetParent(nullptr, false);
1120   mParentWindow.Reset();
1121 }
1122
1123 Dali::Window Window::GetParent()
1124 {
1125   return mParentWindow;
1126 }
1127
1128 WindowOrientation Window::GetCurrentOrientation() const
1129 {
1130   return ConvertToOrientation(mRotationAngle);
1131 }
1132
1133 int Window::GetPhysicalOrientation() const
1134 {
1135   return (mRotationAngle + mWindowBase->GetScreenRotationAngle()) % 360;
1136 }
1137
1138 void Window::SetAvailableOrientations(const Dali::Vector<WindowOrientation>& orientations)
1139 {
1140   Dali::Vector<float>::SizeType count = orientations.Count();
1141   for(Dali::Vector<float>::SizeType index = 0; index < count; ++index)
1142   {
1143     if(IsOrientationAvailable(orientations[index]) == false)
1144     {
1145       DALI_LOG_ERROR("Window::SetAvailableOrientations, invalid orientation: %d\n", orientations[index]);
1146       continue;
1147     }
1148
1149     bool found          = false;
1150     int  convertedAngle = ConvertToAngle(orientations[index]);
1151
1152     for(std::size_t i = 0; i < mAvailableAngles.size(); i++)
1153     {
1154       if(mAvailableAngles[i] == convertedAngle)
1155       {
1156         found = true;
1157         break;
1158       }
1159     }
1160
1161     if(!found)
1162     {
1163       DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), SetAvailableOrientations: %d\n", this, mNativeWindowId, convertedAngle);
1164       mAvailableAngles.push_back(convertedAngle);
1165     }
1166   }
1167   SetAvailableAnlges(mAvailableAngles);
1168 }
1169
1170 int32_t Window::GetNativeId() const
1171 {
1172   return mWindowBase->GetNativeWindowId();
1173 }
1174
1175 void Window::RequestMoveToServer()
1176 {
1177   mWindowBase->RequestMoveToServer();
1178 }
1179
1180 void Window::RequestResizeToServer(WindowResizeDirection direction)
1181 {
1182   mWindowBase->RequestResizeToServer(direction);
1183 }
1184
1185 void Window::EnableFloatingMode(bool enable)
1186 {
1187   mWindowBase->EnableFloatingMode(enable);
1188 }
1189
1190 Rect<int> Window::RecalculateRect(const Rect<int>& rect)
1191 {
1192   Rect<int> newRect;
1193   int       screenWidth, screenHeight;
1194
1195   WindowSystem::GetScreenSize(screenWidth, screenHeight);
1196
1197   if(mRotationAngle == 90)
1198   {
1199     newRect.x      = rect.y;
1200     newRect.y      = screenHeight - (rect.x + rect.width);
1201     newRect.width  = rect.height;
1202     newRect.height = rect.width;
1203   }
1204   else if(mRotationAngle == 180)
1205   {
1206     newRect.x      = screenWidth - (rect.x + rect.width);
1207     newRect.y      = screenHeight - (rect.y + rect.height);
1208     newRect.width  = rect.width;
1209     newRect.height = rect.height;
1210   }
1211   else if(mRotationAngle == 270)
1212   {
1213     newRect.x      = screenWidth - (rect.y + rect.height);
1214     newRect.y      = rect.x;
1215     newRect.width  = rect.height;
1216     newRect.height = rect.width;
1217   }
1218   else
1219   {
1220     newRect.x      = rect.x;
1221     newRect.y      = rect.y;
1222     newRect.width  = rect.width;
1223     newRect.height = rect.height;
1224   }
1225   return newRect;
1226 }
1227
1228 void Window::IncludeInputRegion(const Rect<int>& inputRegion)
1229 {
1230   Rect<int> convertRegion = RecalculateRect(inputRegion);
1231
1232   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), IncludeInputRegion, RecalculateRegion, (%d,%d), (%d x %d)\n", this, mNativeWindowId, convertRegion.x, convertRegion.y, convertRegion.width, convertRegion.height);
1233   mWindowBase->IncludeInputRegion(convertRegion);
1234 }
1235
1236 void Window::ExcludeInputRegion(const Rect<int>& inputRegion)
1237 {
1238   Rect<int> convertRegion = RecalculateRect(inputRegion);
1239
1240   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), ExcludeInputRegion, RecalculateRegion, (%d,%d), (%d x %d)\n", this, mNativeWindowId, convertRegion.x, convertRegion.y, convertRegion.width, convertRegion.height);
1241   mWindowBase->ExcludeInputRegion(convertRegion);
1242 }
1243
1244 void Window::SetNeedsRotationCompletedAcknowledgement(bool needAcknowledgement)
1245 {
1246   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), needAcknowledgement(%d) Set needs Rotation Completed Acknowledgement\n", this, mNativeWindowId, needAcknowledgement);
1247   mWindowSurface->SetNeedsRotationCompletedAcknowledgement(needAcknowledgement);
1248   mWindowRotationAcknowledgement = needAcknowledgement;
1249 }
1250
1251 void Window::SendRotationCompletedAcknowledgement()
1252 {
1253   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), SendRotationCompletedAcknowledgement(): orientation: %d, mWindowRotationAcknowledgement: %d\n", this, mNativeWindowId, mRotationAngle, mWindowRotationAcknowledgement);
1254   if(mWindowRotationAcknowledgement)
1255   {
1256     SetRotationCompletedAcknowledgement();
1257   }
1258 }
1259
1260 bool Window::IsWindowRotating() const
1261 {
1262   return mWindowSurface->IsWindowRotating();
1263 }
1264
1265 const Dali::KeyEvent& Window::GetLastKeyEvent() const
1266 {
1267   return mLastKeyEvent;
1268 }
1269
1270 const Dali::TouchEvent& Window::GetLastTouchEvent() const
1271 {
1272   return mLastTouchEvent;
1273 }
1274
1275 } // namespace Adaptor
1276
1277 } // namespace Internal
1278
1279 } // namespace Dali