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