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