2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/adaptor/common/application-impl.h>
22 #include <dali/devel-api/common/singleton-service.h>
23 #include <dali/integration-api/debug.h>
24 #include <dali/public-api/object/object-registry.h>
27 #include <dali/devel-api/adaptor-framework/accessibility-impl.h>
28 #include <dali/devel-api/adaptor-framework/style-monitor.h>
29 #include <dali/devel-api/text-abstraction/font-client.h>
30 #include <dali/internal/adaptor/common/adaptor-impl.h>
31 #include <dali/internal/adaptor/common/framework.h>
32 #include <dali/internal/adaptor/common/lifecycle-controller-impl.h>
33 #include <dali/internal/system/common/command-line-options.h>
34 #include <dali/internal/window-system/common/render-surface-factory.h>
35 #include <dali/internal/window-system/common/window-impl.h>
36 #include <dali/internal/window-system/common/window-render-surface.h>
37 #include <dali/internal/window-system/common/window-system.h>
39 // To disable a macro with the same name from one of OpenGL headers
44 namespace TizenPlatform
46 class TizenPlatformAbstraction;
58 ApplicationPtr Application::gPreInitializedApplication(NULL);
60 ApplicationPtr Application::New(
63 const std::string& stylesheet,
64 Dali::Application::WINDOW_MODE windowMode,
65 const PositionSize& positionSize,
66 Framework::Type applicationType)
68 ApplicationPtr application(new Application(argc, argv, stylesheet, windowMode, positionSize, applicationType));
72 void Application::PreInitialize(int* argc, char** argv[])
74 if(!gPreInitializedApplication)
76 Dali::TextAbstraction::FontClientPreInitialize();
78 gPreInitializedApplication = new Application(argc, argv, "", Dali::Application::OPAQUE, PositionSize(), Framework::NORMAL);
79 gPreInitializedApplication->CreateWindow(); // Only create window
80 gPreInitializedApplication->mLaunchpadState = Launchpad::PRE_INITIALIZED;
84 Application::Application(int* argc, char** argv[], const std::string& stylesheet, Dali::Application::WINDOW_MODE windowMode, const PositionSize& positionSize, Framework::Type applicationType)
91 mLanguageChangedSignal(),
92 mRegionChangedSignal(),
95 mCommandLineOptions(nullptr),
96 mAdaptorBuilder(nullptr),
99 mMainWindowMode(windowMode),
101 mStylesheet(stylesheet),
102 mEnvironmentOptions(),
103 mWindowPositionSize(positionSize),
104 mLaunchpadState(Launchpad::NONE),
107 // Get mName from environment options
108 mMainWindowName = mEnvironmentOptions.GetWindowName();
109 if(mMainWindowName.empty() && argc && (*argc > 0))
111 // Set mName from command-line args if environment option not set
112 mMainWindowName = (*argv)[0];
115 mCommandLineOptions = new CommandLineOptions(argc, argv);
116 mFramework = new Framework(*this, argc, argv, applicationType);
117 mUseRemoteSurface = (applicationType == Framework::WATCH);
120 Application::~Application()
122 SingletonService service = SingletonService::Get();
123 // Note this can be false i.e. if Application has never created a Core instance
126 service.UnregisterAll();
131 delete mAdaptorBuilder;
132 delete mCommandLineOptions;
136 void Application::StoreWindowPositionSize(PositionSize positionSize)
138 mWindowPositionSize = positionSize;
141 void Application::ChangePreInitializedWindowSize()
143 int screenWidth, screenHeight;
144 Dali::Internal::Adaptor::WindowSystem::GetScreenSize(screenWidth, screenHeight);
146 if(mWindowPositionSize != PositionSize(0, 0, 0, 0))
148 Dali::DevelWindow::SetPositionSize(mMainWindow, mWindowPositionSize);
150 else if(mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0)
152 // Command line options override environment options and full screen
153 mWindowPositionSize.width = mCommandLineOptions->stageWidth;
154 mWindowPositionSize.height = mCommandLineOptions->stageHeight;
155 mMainWindow.SetSize(Dali::Window::WindowSize(mWindowPositionSize.width, mWindowPositionSize.height));
157 else if(mEnvironmentOptions.GetWindowWidth() && mEnvironmentOptions.GetWindowHeight())
159 // Environment options override full screen functionality if command line arguments not provided
160 mWindowPositionSize.width = mEnvironmentOptions.GetWindowWidth();
161 mWindowPositionSize.height = mEnvironmentOptions.GetWindowHeight();
162 mMainWindow.SetSize(Dali::Window::WindowSize(mWindowPositionSize.width, mWindowPositionSize.height));
164 else if(screenWidth != mWindowPositionSize.width || screenHeight != mWindowPositionSize.height)
166 //Some apps can receive screen size differently after launching by specifying size in manifest.
167 mWindowPositionSize.width = screenWidth;
168 mWindowPositionSize.height = screenHeight;
169 mMainWindow.SetSize(Dali::Window::WindowSize(mWindowPositionSize.width, mWindowPositionSize.height));
173 void Application::CreateWindow()
175 if(mWindowPositionSize.width == 0 && mWindowPositionSize.height == 0)
177 if(mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0)
179 // Command line options override environment options and full screen
180 mWindowPositionSize.width = mCommandLineOptions->stageWidth;
181 mWindowPositionSize.height = mCommandLineOptions->stageHeight;
183 else if(mEnvironmentOptions.GetWindowWidth() && mEnvironmentOptions.GetWindowHeight())
185 // Environment options override full screen functionality if command line arguments not provided
186 mWindowPositionSize.width = mEnvironmentOptions.GetWindowWidth();
187 mWindowPositionSize.height = mEnvironmentOptions.GetWindowHeight();
191 const std::string& windowClassName = mEnvironmentOptions.GetWindowClassName();
193 Internal::Adaptor::Window* window = Internal::Adaptor::Window::New(mWindowPositionSize, mMainWindowName, windowClassName, mMainWindowMode == Dali::Application::TRANSPARENT);
194 mMainWindow = Dali::Window(window);
196 // Quit the application when the window is closed
197 GetImplementation(mMainWindow).DeleteRequestSignal().Connect(mSlotDelegate, &Application::Quit);
200 void Application::CreateAdaptor()
202 DALI_ASSERT_ALWAYS(mMainWindow && "Window required to create adaptor");
204 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
206 Integration::SceneHolder sceneHolder = Integration::SceneHolder(&Dali::GetImplementation(mMainWindow));
208 mAdaptor = Adaptor::New(graphicsFactory, sceneHolder, &mEnvironmentOptions);
210 Adaptor::GetImplementation(*mAdaptor).SetUseRemoteSurface(mUseRemoteSurface);
213 void Application::CreateAdaptorBuilder()
215 mAdaptorBuilder = new AdaptorBuilder(mEnvironmentOptions);
218 void Application::MainLoop()
220 // Run the application
224 void Application::Lower()
226 // Lower the application without quitting it.
230 void Application::Quit()
232 // Actually quit the application.
233 // Force a call to Quit even if adaptor is not running.
234 Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).AddIdle(MakeCallback(this, &Application::QuitFromMainLoop), false, true);
237 void Application::QuitFromMainLoop()
239 Accessibility::Bridge::GetCurrentBridge()->Terminate();
244 // This will trigger OnTerminate(), below, after the main loop has completed.
247 void Application::OnInit()
249 mFramework->AddAbortCallback(MakeCallback(this, &Application::QuitFromMainLoop));
251 CreateAdaptorBuilder();
252 // If an application was pre-initialized, a window was made in advance
253 if(mLaunchpadState == Launchpad::NONE)
260 if(mLaunchpadState == Launchpad::PRE_INITIALIZED)
262 ChangePreInitializedWindowSize();
267 Accessibility::Accessible::SetObjectRegistry(mAdaptor->GetObjectRegistry());
269 if(!mStylesheet.empty())
271 Dali::StyleMonitor::Get().SetTheme(mStylesheet);
274 // Wire up the LifecycleController
275 Dali::LifecycleController lifecycleController = Dali::LifecycleController::Get();
277 InitSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnInit);
278 TerminateSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnTerminate);
279 PauseSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnPause);
280 ResumeSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnResume);
281 ResetSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnReset);
282 LanguageChangedSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnLanguageChanged);
284 Dali::Application application(this);
285 mInitSignal.Emit(application);
287 mAdaptor->NotifySceneCreated();
290 void Application::OnTerminate()
292 // We've been told to quit by AppCore, ecore_x_destroy has been called, need to quit synchronously
293 // delete the window as ecore_x has been destroyed by AppCore
295 Dali::Application application(this);
296 mTerminateSignal.Emit(application);
300 // Ensure that the render-thread is not using the surface(window) after we delete it
304 mMainWindow.Reset(); // This only resets (clears) the default Window
307 void Application::OnPause()
309 // A DALi app should handle Pause/Resume events.
310 // DALi just delivers the framework Pause event to the application, but not actually pause DALi core.
311 // Pausing DALi core only occurs on the Window Hidden framework event
312 Dali::Application application(this);
313 mPauseSignal.Emit(application);
316 void Application::OnResume()
318 // Emit the signal first so the application can queue any messages before we do an update/render
319 // This ensures we do not just redraw the last frame before pausing if that's not required
320 Dali::Application application(this);
321 mResumeSignal.Emit(application);
323 // DALi just delivers the framework Resume event to the application.
324 // Resuming DALi core only occurs on the Window Show framework event
326 // Trigger processing of events queued up while paused
327 CoreEventInterface& coreEventInterface = Internal::Adaptor::Adaptor::GetImplementation(GetAdaptor());
328 coreEventInterface.ProcessCoreEvents();
331 void Application::OnReset()
334 * usually, reset callback was called when a caller request to launch this application via aul.
335 * because Application class already handled initialization in OnInit(), OnReset do nothing.
337 Dali::Application application(this);
338 mResetSignal.Emit(application);
341 void Application::OnAppControl(void* data)
343 Dali::Application application(this);
344 mAppControlSignal.Emit(application, data);
347 void Application::OnLanguageChanged()
349 mAdaptor->NotifyLanguageChanged();
350 Dali::Application application(this);
351 mLanguageChangedSignal.Emit(application);
354 void Application::OnRegionChanged()
356 Dali::Application application(this);
357 mRegionChangedSignal.Emit(application);
360 void Application::OnBatteryLow(Dali::DeviceStatus::Battery::Status status)
362 Dali::Application application(this);
363 mLowBatterySignal.Emit(status);
366 void Application::OnMemoryLow(Dali::DeviceStatus::Memory::Status status)
368 Dali::Application application(this);
369 mLowMemorySignal.Emit(status);
372 void Application::OnSurfaceCreated(Any newSurface)
374 void* newWindow = AnyCast<void*>(newSurface);
375 void* oldWindow = AnyCast<void*>(mMainWindow.GetNativeHandle());
376 if(oldWindow != newWindow)
378 auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory();
379 std::unique_ptr<WindowRenderSurface> newSurfacePtr = renderSurfaceFactory->CreateWindowRenderSurface(PositionSize(), newSurface, true);
381 mAdaptor->ReplaceSurface(mMainWindow, *newSurfacePtr.release());
385 void Application::OnSurfaceDestroyed(Any surface)
389 bool Application::AddIdle(CallbackBase* callback, bool hasReturnValue)
391 return mAdaptor->AddIdle(callback, hasReturnValue);
394 std::string Application::GetRegion() const
396 return mFramework->GetRegion();
399 std::string Application::GetLanguage() const
401 return mFramework->GetLanguage();
404 Dali::ObjectRegistry Application::GetObjectRegistry() const
406 Dali::ObjectRegistry objectRegistry;
409 objectRegistry = mAdaptor->GetObjectRegistry();
411 return objectRegistry;
414 Dali::Adaptor& Application::GetAdaptor()
419 Dali::Window Application::GetWindow()
424 std::string Application::GetResourcePath()
426 return Internal::Adaptor::Framework::GetResourcePath();
429 std::string Application::GetDataPath()
431 return Internal::Adaptor::Framework::GetDataPath();
434 void Application::SetStyleSheet(const std::string& stylesheet)
436 mStylesheet = stylesheet;
439 void Application::SetCommandLineOptions(int* argc, char** argv[])
441 delete mCommandLineOptions;
443 mCommandLineOptions = new CommandLineOptions(argc, argv);
445 mFramework->SetCommandLineOptions(argc, argv);
448 ApplicationPtr Application::GetPreInitializedApplication()
450 return gPreInitializedApplication;
453 Graphics::Controller& Application::GetController()
455 auto& adaptor = Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor);
456 return adaptor.GetGraphicsInterface().GetController();
459 } // namespace Adaptor
461 } // namespace Internal