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>
38 // To disable a macro with the same name from one of OpenGL headers
43 namespace TizenPlatform
45 class TizenPlatformAbstraction;
57 ApplicationPtr Application::gPreInitializedApplication(NULL);
59 ApplicationPtr Application::New(
62 const std::string& stylesheet,
63 Dali::Application::WINDOW_MODE windowMode,
64 const PositionSize& positionSize,
65 Framework::Type applicationType)
67 ApplicationPtr application(new Application(argc, argv, stylesheet, windowMode, positionSize, applicationType));
71 void Application::PreInitialize(int* argc, char** argv[])
73 if(!gPreInitializedApplication)
75 Dali::TextAbstraction::FontClientPreInitialize();
77 gPreInitializedApplication = new Application(argc, argv, "", Dali::Application::OPAQUE, PositionSize(), Framework::NORMAL);
78 gPreInitializedApplication->CreateWindow(); // Only create window
79 gPreInitializedApplication->mLaunchpadState = Launchpad::PRE_INITIALIZED;
83 Application::Application(int* argc, char** argv[], const std::string& stylesheet, Dali::Application::WINDOW_MODE windowMode, const PositionSize& positionSize, Framework::Type applicationType)
90 mLanguageChangedSignal(),
91 mRegionChangedSignal(),
94 mCommandLineOptions(nullptr),
95 mAdaptorBuilder(nullptr),
98 mMainWindowMode(windowMode),
100 mStylesheet(stylesheet),
101 mEnvironmentOptions(),
102 mWindowPositionSize(positionSize),
103 mLaunchpadState(Launchpad::NONE),
106 // Get mName from environment options
107 mMainWindowName = mEnvironmentOptions.GetWindowName();
108 if(mMainWindowName.empty() && argc && (*argc > 0))
110 // Set mName from command-line args if environment option not set
111 mMainWindowName = (*argv)[0];
114 mCommandLineOptions = new CommandLineOptions(argc, argv);
115 mFramework = new Framework(*this, argc, argv, applicationType);
116 mUseRemoteSurface = (applicationType == Framework::WATCH);
119 Application::~Application()
121 SingletonService service = SingletonService::Get();
122 // Note this can be false i.e. if Application has never created a Core instance
125 service.UnregisterAll();
130 delete mAdaptorBuilder;
131 delete mCommandLineOptions;
135 void Application::CreateWindow()
137 if(mWindowPositionSize.width == 0 && mWindowPositionSize.height == 0)
139 if(mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0)
141 // Command line options override environment options and full screen
142 mWindowPositionSize.width = mCommandLineOptions->stageWidth;
143 mWindowPositionSize.height = mCommandLineOptions->stageHeight;
145 else if(mEnvironmentOptions.GetWindowWidth() && mEnvironmentOptions.GetWindowHeight())
147 // Environment options override full screen functionality if command line arguments not provided
148 mWindowPositionSize.width = mEnvironmentOptions.GetWindowWidth();
149 mWindowPositionSize.height = mEnvironmentOptions.GetWindowHeight();
153 const std::string& windowClassName = mEnvironmentOptions.GetWindowClassName();
155 Internal::Adaptor::Window* window = Internal::Adaptor::Window::New(mWindowPositionSize, mMainWindowName, windowClassName, mMainWindowMode == Dali::Application::TRANSPARENT);
156 mMainWindow = Dali::Window(window);
158 // Quit the application when the window is closed
159 GetImplementation(mMainWindow).DeleteRequestSignal().Connect(mSlotDelegate, &Application::Quit);
162 void Application::CreateAdaptor()
164 DALI_ASSERT_ALWAYS(mMainWindow && "Window required to create adaptor");
166 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
168 Integration::SceneHolder sceneHolder = Integration::SceneHolder(&Dali::GetImplementation(mMainWindow));
170 mAdaptor = Adaptor::New(graphicsFactory, sceneHolder, &mEnvironmentOptions);
172 Adaptor::GetImplementation(*mAdaptor).SetUseRemoteSurface(mUseRemoteSurface);
175 void Application::CreateAdaptorBuilder()
177 mAdaptorBuilder = new AdaptorBuilder(mEnvironmentOptions);
180 void Application::MainLoop()
182 // Run the application
186 void Application::Lower()
188 // Lower the application without quitting it.
192 void Application::Quit()
194 // Actually quit the application.
195 // Force a call to Quit even if adaptor is not running.
196 Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).AddIdle(MakeCallback(this, &Application::QuitFromMainLoop), false, true);
199 void Application::QuitFromMainLoop()
201 Accessibility::Bridge::GetCurrentBridge()->Terminate();
206 // This will trigger OnTerminate(), below, after the main loop has completed.
209 void Application::OnInit()
211 mFramework->AddAbortCallback(MakeCallback(this, &Application::QuitFromMainLoop));
213 CreateAdaptorBuilder();
214 // If an application was pre-initialized, a window was made in advance
215 if(mLaunchpadState == Launchpad::NONE)
224 Accessibility::Accessible::SetObjectRegistry(mAdaptor->GetObjectRegistry());
226 if(!mStylesheet.empty())
228 Dali::StyleMonitor::Get().SetTheme(mStylesheet);
231 // Wire up the LifecycleController
232 Dali::LifecycleController lifecycleController = Dali::LifecycleController::Get();
234 InitSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnInit);
235 TerminateSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnTerminate);
236 PauseSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnPause);
237 ResumeSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnResume);
238 ResetSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnReset);
239 LanguageChangedSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnLanguageChanged);
241 Dali::Application application(this);
242 mInitSignal.Emit(application);
244 mAdaptor->NotifySceneCreated();
247 void Application::OnTerminate()
249 // We've been told to quit by AppCore, ecore_x_destroy has been called, need to quit synchronously
250 // delete the window as ecore_x has been destroyed by AppCore
252 Dali::Application application(this);
253 mTerminateSignal.Emit(application);
257 // Ensure that the render-thread is not using the surface(window) after we delete it
261 mMainWindow.Reset(); // This only resets (clears) the default Window
264 void Application::OnPause()
266 // A DALi app should handle Pause/Resume events.
267 // DALi just delivers the framework Pause event to the application, but not actually pause DALi core.
268 // Pausing DALi core only occurs on the Window Hidden framework event
269 Dali::Application application(this);
270 mPauseSignal.Emit(application);
273 void Application::OnResume()
275 // Emit the signal first so the application can queue any messages before we do an update/render
276 // This ensures we do not just redraw the last frame before pausing if that's not required
277 Dali::Application application(this);
278 mResumeSignal.Emit(application);
280 // DALi just delivers the framework Resume event to the application.
281 // Resuming DALi core only occurs on the Window Show framework event
283 // Trigger processing of events queued up while paused
284 CoreEventInterface& coreEventInterface = Internal::Adaptor::Adaptor::GetImplementation(GetAdaptor());
285 coreEventInterface.ProcessCoreEvents();
288 void Application::OnReset()
291 * usually, reset callback was called when a caller request to launch this application via aul.
292 * because Application class already handled initialization in OnInit(), OnReset do nothing.
294 Dali::Application application(this);
295 mResetSignal.Emit(application);
298 void Application::OnAppControl(void* data)
300 Dali::Application application(this);
301 mAppControlSignal.Emit(application, data);
304 void Application::OnLanguageChanged()
306 mAdaptor->NotifyLanguageChanged();
307 Dali::Application application(this);
308 mLanguageChangedSignal.Emit(application);
311 void Application::OnRegionChanged()
313 Dali::Application application(this);
314 mRegionChangedSignal.Emit(application);
317 void Application::OnBatteryLow(Dali::DeviceStatus::Battery::Status status)
319 Dali::Application application(this);
320 mLowBatterySignal.Emit(status);
323 void Application::OnMemoryLow(Dali::DeviceStatus::Memory::Status status)
325 Dali::Application application(this);
326 mLowMemorySignal.Emit(status);
329 void Application::OnSurfaceCreated(Any newSurface)
331 void* newWindow = AnyCast<void*>(newSurface);
332 void* oldWindow = AnyCast<void*>(mMainWindow.GetNativeHandle());
333 if(oldWindow != newWindow)
335 auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory();
336 std::unique_ptr<WindowRenderSurface> newSurfacePtr = renderSurfaceFactory->CreateWindowRenderSurface(PositionSize(), newSurface, true);
338 mAdaptor->ReplaceSurface(mMainWindow, *newSurfacePtr.release());
342 void Application::OnSurfaceDestroyed(Any surface)
346 bool Application::AddIdle(CallbackBase* callback, bool hasReturnValue)
348 return mAdaptor->AddIdle(callback, hasReturnValue);
351 std::string Application::GetRegion() const
353 return mFramework->GetRegion();
356 std::string Application::GetLanguage() const
358 return mFramework->GetLanguage();
361 Dali::ObjectRegistry Application::GetObjectRegistry() const
363 Dali::ObjectRegistry objectRegistry;
366 objectRegistry = mAdaptor->GetObjectRegistry();
368 return objectRegistry;
371 Dali::Adaptor& Application::GetAdaptor()
376 Dali::Window Application::GetWindow()
381 std::string Application::GetResourcePath()
383 return Internal::Adaptor::Framework::GetResourcePath();
386 std::string Application::GetDataPath()
388 return Internal::Adaptor::Framework::GetDataPath();
391 void Application::SetStyleSheet(const std::string& stylesheet)
393 mStylesheet = stylesheet;
396 void Application::SetCommandLineOptions(int* argc, char** argv[])
398 delete mCommandLineOptions;
400 mCommandLineOptions = new CommandLineOptions(argc, argv);
402 mFramework->SetCommandLineOptions(argc, argv);
405 ApplicationPtr Application::GetPreInitializedApplication()
407 return gPreInitializedApplication;
410 } // namespace Adaptor
412 } // namespace Internal