2 * Copyright (c) 2020 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/public-api/object/object-registry.h>
23 #include <dali/integration-api/debug.h>
24 #include <dali/devel-api/common/singleton-service.h>
27 #include <dali/devel-api/adaptor-framework/style-monitor.h>
28 #include <dali/devel-api/text-abstraction/font-client.h>
29 #include <dali/internal/adaptor/common/adaptor-impl.h>
30 #include <dali/internal/system/common/command-line-options.h>
31 #include <dali/internal/adaptor/common/framework.h>
32 #include <dali/internal/adaptor/common/lifecycle-controller-impl.h>
33 #include <dali/internal/window-system/common/window-impl.h>
34 #include <dali/internal/window-system/common/window-render-surface.h>
35 #include <dali/internal/window-system/common/render-surface-factory.h>
37 // To disable a macro with the same name from one of OpenGL headers
43 namespace TizenPlatform
45 class TizenPlatformAbstraction;
59 ApplicationPtr Application::gPreInitializedApplication( NULL );
61 ApplicationPtr Application::New(
64 const std::string& stylesheet,
65 Dali::Application::WINDOW_MODE windowMode,
66 const PositionSize& positionSize,
67 Framework::Type applicationType)
69 ApplicationPtr application ( new Application (argc, argv, stylesheet, windowMode, positionSize, applicationType ) );
73 void Application::PreInitialize( int* argc, char** argv[] )
75 if( !gPreInitializedApplication )
77 Dali::TextAbstraction::FontClientPreInitialize();
79 gPreInitializedApplication = new Application ( argc, argv, "", Dali::Application::OPAQUE, PositionSize(), Framework::NORMAL );
80 gPreInitializedApplication->CreateWindow(); // Only create window
81 gPreInitializedApplication->mLaunchpadState = Launchpad::PRE_INITIALIZED;
85 Application::Application( int* argc, char** argv[], const std::string& stylesheet,
86 Dali::Application::WINDOW_MODE windowMode, const PositionSize& positionSize, Framework::Type applicationType )
93 mLanguageChangedSignal(),
94 mRegionChangedSignal(),
95 mEventLoop( nullptr ),
96 mFramework( nullptr ),
97 mCommandLineOptions( nullptr ),
98 mAdaptorBuilder( nullptr ),
101 mMainWindowMode( windowMode ),
103 mStylesheet( stylesheet ),
104 mEnvironmentOptions(),
105 mWindowPositionSize( positionSize ),
106 mLaunchpadState( Launchpad::NONE ),
107 mSlotDelegate( this )
109 // Get mName from environment options
110 mMainWindowName = mEnvironmentOptions.GetWindowName();
111 if( mMainWindowName.empty() && argc && ( *argc > 0 ) )
113 // Set mName from command-line args if environment option not set
114 mMainWindowName = (*argv)[0];
117 mCommandLineOptions = new CommandLineOptions(argc, argv);
118 mFramework = new Framework( *this, argc, argv, applicationType );
119 mUseRemoteSurface = (applicationType == Framework::WATCH);
122 Application::~Application()
124 SingletonService service = SingletonService::Get();
125 // Note this can be false i.e. if Application has never created a Core instance
128 service.UnregisterAll();
133 delete mAdaptorBuilder;
134 delete mCommandLineOptions;
138 void Application::CreateWindow()
140 if( mWindowPositionSize.width == 0 && mWindowPositionSize.height == 0 )
142 if( mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0 )
144 // Command line options override environment options and full screen
145 mWindowPositionSize.width = mCommandLineOptions->stageWidth;
146 mWindowPositionSize.height = mCommandLineOptions->stageHeight;
148 else if( mEnvironmentOptions.GetWindowWidth() && mEnvironmentOptions.GetWindowHeight() )
150 // Environment options override full screen functionality if command line arguments not provided
151 mWindowPositionSize.width = mEnvironmentOptions.GetWindowWidth();
152 mWindowPositionSize.height = mEnvironmentOptions.GetWindowHeight();
156 const std::string& windowClassName = mEnvironmentOptions.GetWindowClassName();
158 Internal::Adaptor::Window* window = Internal::Adaptor::Window::New(mWindowPositionSize, mMainWindowName, windowClassName, mMainWindowMode == Dali::Application::TRANSPARENT);
159 mMainWindow = Dali::Window( window );
161 // Quit the application when the window is closed
162 GetImplementation( mMainWindow ).DeleteRequestSignal().Connect( mSlotDelegate, &Application::Quit );
165 void Application::CreateAdaptor()
167 DALI_ASSERT_ALWAYS( mMainWindow && "Window required to create adaptor" );
169 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
171 Integration::SceneHolder sceneHolder = Integration::SceneHolder( &Dali::GetImplementation( mMainWindow ) );
173 mAdaptor = Adaptor::New( graphicsFactory, sceneHolder, &mEnvironmentOptions );
175 Adaptor::GetImplementation( *mAdaptor ).SetUseRemoteSurface( mUseRemoteSurface );
178 void Application::CreateAdaptorBuilder()
180 mAdaptorBuilder = new AdaptorBuilder();
183 void Application::MainLoop()
185 // Run the application
189 void Application::Lower()
191 // Lower the application without quitting it.
195 void Application::Quit()
197 // Actually quit the application.
198 // Force a call to Quit even if adaptor is not running.
199 Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).AddIdle( MakeCallback( this, &Application::QuitFromMainLoop ), false, true );
202 void Application::QuitFromMainLoop()
207 // This will trigger OnTerminate(), below, after the main loop has completed.
210 void Application::OnInit()
212 mFramework->AddAbortCallback( MakeCallback( this, &Application::QuitFromMainLoop ) );
214 CreateAdaptorBuilder();
215 // If an application was pre-initialized, a window was made in advance
216 if( mLaunchpadState == Launchpad::NONE )
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
337 = renderSurfaceFactory->CreateWindowRenderSurface( PositionSize(), newSurface, true );
339 mAdaptor->ReplaceSurface( mMainWindow, *newSurfacePtr.release() );
343 void Application::OnSurfaceDestroyed( Any surface )
347 bool Application::AddIdle( CallbackBase* callback, bool hasReturnValue )
349 return mAdaptor->AddIdle( callback, hasReturnValue );
352 std::string Application::GetRegion() const
354 return mFramework->GetRegion();
357 std::string Application::GetLanguage() const
359 return mFramework->GetLanguage();
362 Dali::ObjectRegistry Application::GetObjectRegistry() const
364 Dali::ObjectRegistry objectRegistry;
367 objectRegistry = mAdaptor->GetObjectRegistry();
369 return objectRegistry;
372 Dali::Adaptor& Application::GetAdaptor()
377 Dali::Window Application::GetWindow()
382 std::string Application::GetResourcePath()
384 return Internal::Adaptor::Framework::GetResourcePath();
387 std::string Application::GetDataPath()
389 return Internal::Adaptor::Framework::GetDataPath();
392 void Application::SetStyleSheet( const std::string& stylesheet )
394 mStylesheet = stylesheet;
397 void Application::SetCommandLineOptions( int* argc, char **argv[] )
399 delete mCommandLineOptions;
401 mCommandLineOptions = new CommandLineOptions( argc, argv );
403 mFramework->SetCommandLineOptions( argc, argv );
406 ApplicationPtr Application::GetPreInitializedApplication()
408 return gPreInitializedApplication;
411 } // namespace Adaptor
413 } // namespace Internal