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