Merge "Add function to set maximum/minimum size" 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     SurfaceResized();
888
889     mAdaptor->SurfaceResizePrepare(mSurface.get(), newSize);
890
891     DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Updated PositionSize by server :resize signal [%d x %d]\n", this, mNativeWindowId, newRect.width, newRect.height);
892     Dali::Window handle(this);
893     mResizeSignal.Emit(handle, newSize);
894     mAdaptor->SurfaceResizeComplete(mSurface.get(), newSize);
895   }
896
897   mSurface->SetFullSwapNextFrame();
898
899   Dali::Accessibility::Accessible::Get(mScene.GetRootLayer())->EmitBoundsChanged(Dali::Rect<>(positionSize.x, positionSize.y, positionSize.width, positionSize.height));
900 }
901
902 void Window::OnTouchPoint(Dali::Integration::Point& point, int timeStamp)
903 {
904   mLastTouchEvent = Dali::Integration::NewTouchEvent(timeStamp, point);
905   FeedTouchPoint(point, timeStamp);
906 }
907
908 void Window::OnWheelEvent(Dali::Integration::WheelEvent& wheelEvent)
909 {
910   FeedWheelEvent(wheelEvent);
911 }
912
913 void Window::OnKeyEvent(Dali::Integration::KeyEvent& keyEvent)
914 {
915   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);
916   FeedKeyEvent(keyEvent);
917 }
918
919 void Window::OnRotation(const RotationEvent& rotation)
920 {
921   PositionSize newPositionSize(rotation.x, rotation.y, rotation.width, rotation.height);
922
923   mRotationAngle = rotation.angle;
924   mWindowWidth   = rotation.width;
925   mWindowHeight  = rotation.height;
926
927   // Notify that the orientation is changed
928   mOrientation->OnOrientationChange(rotation);
929
930   mWindowSurface->RequestRotation(mRotationAngle, newPositionSize);
931
932   int orientation = (mRotationAngle + mWindowBase->GetScreenRotationAngle()) % 360;
933   SurfaceRotated(mWindowWidth, mWindowHeight, orientation);
934
935   mAdaptor->SurfaceResizePrepare(mSurface.get(), Adaptor::SurfaceSize(mWindowWidth, mWindowHeight));
936
937   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);
938   // Emit signal
939   Dali::Window handle(this);
940   mResizeSignal.Emit(handle, Dali::Window::WindowSize(mWindowWidth, mWindowHeight));
941
942   mAdaptor->SurfaceResizeComplete(mSurface.get(), Adaptor::SurfaceSize(mWindowWidth, mWindowHeight));
943 }
944
945 void Window::OnPause()
946 {
947   if(mEventHandler)
948   {
949     mEventHandler->Pause();
950   }
951 }
952
953 void Window::OnResume()
954 {
955   if(mEventHandler)
956   {
957     mEventHandler->Resume();
958   }
959
960   mSurface->SetFullSwapNextFrame();
961 }
962
963 void Window::OnAuxiliaryMessage(const std::string& key, const std::string& value, const Property::Array& options)
964 {
965   mAuxiliaryMessageSignal.Emit(key, value, options);
966 }
967
968 void Window::OnAccessibilityEnabled()
969 {
970   auto bridge     = Accessibility::Bridge::GetCurrentBridge();
971   auto rootLayer  = mScene.GetRootLayer();
972   auto accessible = Accessibility::Accessible::Get(rootLayer);
973   bridge->AddTopLevelWindow(accessible);
974
975   if(!mVisible || mIconified)
976   {
977     return;
978   }
979
980   Dali::Window handle(this);
981   bridge->WindowShown(handle);
982
983   if(mFocused)
984   {
985     bridge->WindowFocused(handle);
986   }
987 }
988
989 void Window::OnAccessibilityDisabled()
990 {
991   auto bridge     = Accessibility::Bridge::GetCurrentBridge();
992   auto rootLayer  = mScene.GetRootLayer();
993   auto accessible = Accessibility::Accessible::Get(rootLayer);
994   bridge->RemoveTopLevelWindow(accessible);
995 }
996
997 void Window::RecalculateTouchPosition(Integration::Point& point)
998 {
999   Vector2 position = point.GetScreenPosition();
1000   Vector2 convertedPosition;
1001
1002   switch(mRotationAngle)
1003   {
1004     case 90:
1005     {
1006       convertedPosition.x = static_cast<float>(mWindowWidth) - position.y;
1007       convertedPosition.y = position.x;
1008       break;
1009     }
1010     case 180:
1011     {
1012       convertedPosition.x = static_cast<float>(mWindowWidth) - position.x;
1013       convertedPosition.y = static_cast<float>(mWindowHeight) - position.y;
1014       break;
1015     }
1016     case 270:
1017     {
1018       convertedPosition.x = position.y;
1019       convertedPosition.y = static_cast<float>(mWindowHeight) - position.x;
1020       break;
1021     }
1022     default:
1023     {
1024       convertedPosition = position;
1025       break;
1026     }
1027   }
1028
1029   point.SetScreenPosition(convertedPosition);
1030 }
1031
1032 Dali::Window Window::Get(Dali::Actor actor)
1033 {
1034   Internal::Adaptor::Window* windowImpl = nullptr;
1035
1036   if(Internal::Adaptor::Adaptor::IsAvailable())
1037   {
1038     Dali::Internal::Adaptor::Adaptor& adaptor = Internal::Adaptor::Adaptor::GetImplementation(Internal::Adaptor::Adaptor::Get());
1039     windowImpl                                = dynamic_cast<Internal::Adaptor::Window*>(adaptor.GetWindow(actor));
1040     if(windowImpl)
1041     {
1042       return Dali::Window(windowImpl);
1043     }
1044   }
1045
1046   return Dali::Window();
1047 }
1048
1049 void Window::SetParent(Dali::Window& parent)
1050 {
1051   if(DALI_UNLIKELY(parent))
1052   {
1053     mParentWindow     = parent;
1054     Dali::Window self = Dali::Window(this);
1055     // check circular parent window setting
1056     if(Dali::DevelWindow::GetParent(parent) == self)
1057     {
1058       Dali::DevelWindow::Unparent(parent);
1059     }
1060     mWindowBase->SetParent(GetImplementation(mParentWindow).mWindowBase, false);
1061   }
1062 }
1063
1064 void Window::SetParent(Dali::Window& parent, bool belowParent)
1065 {
1066   if(DALI_UNLIKELY(parent))
1067   {
1068     mParentWindow     = parent;
1069     Dali::Window self = Dali::Window(this);
1070     // check circular parent window setting
1071     if(Dali::DevelWindow::GetParent(parent) == self)
1072     {
1073       Dali::DevelWindow::Unparent(parent);
1074     }
1075     mWindowBase->SetParent(GetImplementation(mParentWindow).mWindowBase, belowParent);
1076   }
1077 }
1078
1079 void Window::Unparent()
1080 {
1081   mWindowBase->SetParent(nullptr, false);
1082   mParentWindow.Reset();
1083 }
1084
1085 Dali::Window Window::GetParent()
1086 {
1087   return mParentWindow;
1088 }
1089
1090 WindowOrientation Window::GetCurrentOrientation() const
1091 {
1092   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), GetCurrentOrientation(): %d\n", this, mNativeWindowId, mRotationAngle);
1093   return ConvertToOrientation(mRotationAngle);
1094 }
1095
1096 int Window::GetPhysicalOrientation() const
1097 {
1098   return (mRotationAngle + mWindowBase->GetScreenRotationAngle()) % 360;
1099 }
1100
1101 void Window::SetAvailableOrientations(const Dali::Vector<WindowOrientation>& orientations)
1102 {
1103   Dali::Vector<float>::SizeType count = orientations.Count();
1104   for(Dali::Vector<float>::SizeType index = 0; index < count; ++index)
1105   {
1106     if(IsOrientationAvailable(orientations[index]) == false)
1107     {
1108       DALI_LOG_ERROR("Window::SetAvailableOrientations, invalid orientation: %d\n", orientations[index]);
1109       continue;
1110     }
1111
1112     bool found          = false;
1113     int  convertedAngle = ConvertToAngle(orientations[index]);
1114
1115     for(std::size_t i = 0; i < mAvailableAngles.size(); i++)
1116     {
1117       if(mAvailableAngles[i] == convertedAngle)
1118       {
1119         found = true;
1120         break;
1121       }
1122     }
1123
1124     if(!found)
1125     {
1126       DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), SetAvailableOrientations: %d\n", this, mNativeWindowId, convertedAngle);
1127       mAvailableAngles.push_back(convertedAngle);
1128     }
1129   }
1130   SetAvailableAnlges(mAvailableAngles);
1131 }
1132
1133 int32_t Window::GetNativeId() const
1134 {
1135   return mWindowBase->GetNativeWindowId();
1136 }
1137
1138 void Window::RequestMoveToServer()
1139 {
1140   mWindowBase->RequestMoveToServer();
1141 }
1142
1143 void Window::RequestResizeToServer(WindowResizeDirection direction)
1144 {
1145   mWindowBase->RequestResizeToServer(direction);
1146 }
1147
1148 void Window::EnableFloatingMode(bool enable)
1149 {
1150   mWindowBase->EnableFloatingMode(enable);
1151 }
1152
1153 Rect<int> Window::RecalculateRect(const Rect<int>& rect)
1154 {
1155   Rect<int> newRect;
1156   int       screenWidth, screenHeight;
1157
1158   WindowSystem::GetScreenSize(screenWidth, screenHeight);
1159
1160   if(mRotationAngle == 90)
1161   {
1162     newRect.x      = rect.y;
1163     newRect.y      = screenHeight - (rect.x + rect.width);
1164     newRect.width  = rect.height;
1165     newRect.height = rect.width;
1166   }
1167   else if(mRotationAngle == 180)
1168   {
1169     newRect.x      = screenWidth - (rect.x + rect.width);
1170     newRect.y      = screenHeight - (rect.y + rect.height);
1171     newRect.width  = rect.width;
1172     newRect.height = rect.height;
1173   }
1174   else if(mRotationAngle == 270)
1175   {
1176     newRect.x      = screenWidth - (rect.y + rect.height);
1177     newRect.y      = rect.x;
1178     newRect.width  = rect.height;
1179     newRect.height = rect.width;
1180   }
1181   else
1182   {
1183     newRect.x      = rect.x;
1184     newRect.y      = rect.y;
1185     newRect.width  = rect.width;
1186     newRect.height = rect.height;
1187   }
1188   return newRect;
1189 }
1190
1191 void Window::IncludeInputRegion(const Rect<int>& inputRegion)
1192 {
1193   Rect<int> convertRegion = RecalculateRect(inputRegion);
1194
1195   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);
1196   mWindowBase->IncludeInputRegion(convertRegion);
1197 }
1198
1199 void Window::ExcludeInputRegion(const Rect<int>& inputRegion)
1200 {
1201   Rect<int> convertRegion = RecalculateRect(inputRegion);
1202
1203   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);
1204   mWindowBase->ExcludeInputRegion(convertRegion);
1205 }
1206
1207 void Window::SetNeedsRotationCompletedAcknowledgement(bool needAcknowledgement)
1208 {
1209   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), needAcknowledgement(%d) Set needs Rotation Completed Acknowledgement\n", this, mNativeWindowId, needAcknowledgement);
1210   mWindowSurface->SetNeedsRotationCompletedAcknowledgement(needAcknowledgement);
1211   mWindowRotationAcknowledgement = needAcknowledgement;
1212 }
1213
1214 void Window::SendRotationCompletedAcknowledgement()
1215 {
1216   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), SendRotationCompletedAcknowledgement(): orientation: %d, mWindowRotationAcknowledgement: %d\n", this, mNativeWindowId, mRotationAngle, mWindowRotationAcknowledgement);
1217   if(mWindowRotationAcknowledgement)
1218   {
1219     SetRotationCompletedAcknowledgement();
1220   }
1221 }
1222
1223 bool Window::IsWindowRotating() const
1224 {
1225   return mWindowSurface->IsWindowRotating();
1226 }
1227
1228 const Dali::KeyEvent& Window::GetLastKeyEvent() const
1229 {
1230   return mLastKeyEvent;
1231 }
1232
1233 const Dali::TouchEvent& Window::GetLastTouchEvent() const
1234 {
1235   return mLastTouchEvent;
1236 }
1237
1238 } // namespace Adaptor
1239
1240 } // namespace Internal
1241
1242 } // namespace Dali