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