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