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