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