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