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/integration-api/debug.h>
23 #include <dali/devel-api/common/singleton-service.h>
26 #include <dali/devel-api/adaptor-framework/style-monitor.h>
27 #include <dali/devel-api/text-abstraction/font-client.h>
28 #include <dali/internal/adaptor/common/adaptor-impl.h>
29 #include <dali/internal/system/common/command-line-options.h>
30 #include <dali/internal/adaptor/common/framework.h>
31 #include <dali/internal/adaptor/common/lifecycle-controller-impl.h>
32 #include <dali/internal/window-system/common/window-impl.h>
33 #include <dali/internal/window-system/common/window-render-surface.h>
34 #include <dali/internal/window-system/common/render-surface-factory.h>
36 // To disable a macro with the same name from one of OpenGL headers
42 namespace TizenPlatform
44 class TizenPlatformAbstraction;
61 const float DEFAULT_STEREO_BASE( 65.0f );
63 } // unnamed namespace
65 ApplicationPtr Application::gPreInitializedApplication( NULL );
67 ApplicationPtr Application::New(
70 const std::string& stylesheet,
71 Dali::Application::WINDOW_MODE windowMode,
72 const PositionSize& positionSize,
73 Framework::Type applicationType)
75 ApplicationPtr application ( new Application (argc, argv, stylesheet, windowMode, positionSize, applicationType ) );
79 void Application::PreInitialize( int* argc, char** argv[] )
81 if( !gPreInitializedApplication )
83 gPreInitializedApplication = new Application ( argc, argv, "", Dali::Application::OPAQUE, PositionSize(), Framework::NORMAL );
84 gPreInitializedApplication->CreateWindow(); // Only create window
85 gPreInitializedApplication->mLaunchpadState = Launchpad::PRE_INITIALIZED;
89 Application::Application( int* argc, char** argv[], const std::string& stylesheet,
90 Dali::Application::WINDOW_MODE windowMode, const PositionSize& positionSize, Framework::Type applicationType )
98 mLanguageChangedSignal(),
99 mRegionChangedSignal(),
102 mEventLoop( nullptr ),
103 mFramework( nullptr ),
104 mContextLossConfiguration( Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS ),
105 mCommandLineOptions( nullptr ),
106 mAdaptorBuilder( nullptr ),
109 mMainWindowMode( windowMode ),
111 mMainWindowReplaced( false ),
112 mStylesheet( stylesheet ),
113 mEnvironmentOptions(),
114 mWindowPositionSize( positionSize ),
115 mLaunchpadState( Launchpad::NONE ),
116 mSlotDelegate( this ),
118 mStereoBase( DEFAULT_STEREO_BASE )
120 // Get mName from environment options
121 mMainWindowName = mEnvironmentOptions.GetWindowName();
122 if( mMainWindowName.empty() && argc && ( *argc > 0 ) )
124 // Set mName from command-line args if environment option not set
125 mMainWindowName = (*argv)[0];
128 mCommandLineOptions = new CommandLineOptions(argc, argv);
129 mFramework = new Framework( *this, argc, argv, applicationType );
130 mUseRemoteSurface = (applicationType == Framework::WATCH);
133 Application::~Application()
135 SingletonService service = SingletonService::Get();
136 // Note this can be false i.e. if Application has never created a Core instance
139 service.UnregisterAll();
144 delete mAdaptorBuilder;
145 delete mCommandLineOptions;
149 void Application::CreateWindow()
151 if( mWindowPositionSize.width == 0 && mWindowPositionSize.height == 0 )
153 if( mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0 )
155 // Command line options override environment options and full screen
156 mWindowPositionSize.width = mCommandLineOptions->stageWidth;
157 mWindowPositionSize.height = mCommandLineOptions->stageHeight;
159 else if( mEnvironmentOptions.GetWindowWidth() && mEnvironmentOptions.GetWindowHeight() )
161 // Environment options override full screen functionality if command line arguments not provided
162 mWindowPositionSize.width = mEnvironmentOptions.GetWindowWidth();
163 mWindowPositionSize.height = mEnvironmentOptions.GetWindowHeight();
167 const std::string& windowClassName = mEnvironmentOptions.GetWindowClassName();
169 Internal::Adaptor::Window* window = Internal::Adaptor::Window::New( mWindowPositionSize, mMainWindowName, windowClassName, mMainWindowMode == Dali::Application::TRANSPARENT );
170 mMainWindow = Dali::Window( window );
172 // Quit the application when the window is closed
173 GetImplementation( mMainWindow ).DeleteRequestSignal().Connect( mSlotDelegate, &Application::Quit );
176 void Application::CreateAdaptor()
178 DALI_ASSERT_ALWAYS( mMainWindow && "Window required to create adaptor" );
180 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
182 Integration::SceneHolder sceneHolder = Integration::SceneHolder( &Dali::GetImplementation( mMainWindow ) );
184 mAdaptor = Adaptor::New( graphicsFactory, sceneHolder, mContextLossConfiguration, &mEnvironmentOptions );
186 mAdaptor->ResizedSignal().Connect( mSlotDelegate, &Application::OnResize );
188 Adaptor::GetImplementation( *mAdaptor ).SetUseRemoteSurface( mUseRemoteSurface );
191 void Application::CreateAdaptorBuilder()
193 mAdaptorBuilder = new AdaptorBuilder();
196 void Application::MainLoop(Dali::Configuration::ContextLoss configuration)
198 mContextLossConfiguration = configuration;
200 // Run the application
204 void Application::Lower()
206 // Lower the application without quitting it.
210 void Application::Quit()
212 // Actually quit the application.
213 // Force a call to Quit even if adaptor is not running.
214 Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).AddIdle( MakeCallback( this, &Application::QuitFromMainLoop ), false, true );
217 void Application::QuitFromMainLoop()
222 // This will trigger OnTerminate(), below, after the main loop has completed.
225 void Application::OnInit()
227 mFramework->AddAbortCallback( MakeCallback( this, &Application::QuitFromMainLoop ) );
229 CreateAdaptorBuilder();
230 // If an application was pre-initialized, a window was made in advance
231 if( mLaunchpadState == Launchpad::NONE )
241 if( ! mStylesheet.empty() )
243 Dali::StyleMonitor::Get().SetTheme( mStylesheet );
246 // Wire up the LifecycleController
247 Dali::LifecycleController lifecycleController = Dali::LifecycleController::Get();
249 InitSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnInit );
250 TerminateSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnTerminate );
251 PauseSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnPause );
252 ResumeSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnResume );
253 ResetSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnReset );
254 ResizeSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnResize );
255 LanguageChangedSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnLanguageChanged );
257 Dali::Application application(this);
258 mInitSignal.Emit( application );
260 mAdaptor->NotifySceneCreated();
263 void Application::OnTerminate()
265 // We've been told to quit by AppCore, ecore_x_destroy has been called, need to quit synchronously
266 // delete the window as ecore_x has been destroyed by AppCore
268 Dali::Application application(this);
269 mTerminateSignal.Emit( application );
273 // Ensure that the render-thread is not using the surface(window) after we delete it
277 mMainWindow.Reset(); // This only resets (clears) the default Window
280 void Application::OnPause()
282 // A DALi app should handle Pause/Resume events.
283 // DALi just delivers the framework Pause event to the application, but not actually pause DALi core.
284 // Pausing DALi core only occurs on the Window Hidden framework event
285 Dali::Application application(this);
286 mPauseSignal.Emit( application );
289 void Application::OnResume()
291 // Emit the signal first so the application can queue any messages before we do an update/render
292 // This ensures we do not just redraw the last frame before pausing if that's not required
293 Dali::Application application(this);
294 mResumeSignal.Emit( application );
296 // DALi just delivers the framework Resume event to the application.
297 // Resuming DALi core only occurs on the Window Show framework event
299 // Trigger processing of events queued up while paused
300 CoreEventInterface& coreEventInterface = Internal::Adaptor::Adaptor::GetImplementation( GetAdaptor() );
301 coreEventInterface.ProcessCoreEvents();
304 void Application::OnReset()
307 * usually, reset callback was called when a caller request to launch this application via aul.
308 * because Application class already handled initialization in OnInit(), OnReset do nothing.
310 Dali::Application application(this);
311 mResetSignal.Emit( application );
314 void Application::OnAppControl(void *data)
316 Dali::Application application(this);
317 mAppControlSignal.Emit( application , data );
320 void Application::OnLanguageChanged()
322 mAdaptor->NotifyLanguageChanged();
323 Dali::Application application(this);
324 mLanguageChangedSignal.Emit( application );
327 void Application::OnRegionChanged()
329 Dali::Application application(this);
330 mRegionChangedSignal.Emit( application );
333 void Application::OnBatteryLow( Dali::DeviceStatus::Battery::Status status )
335 Dali::Application application(this);
336 mBatteryLowSignal.Emit( application );
338 mLowBatterySignal.Emit( status );
341 void Application::OnMemoryLow( Dali::DeviceStatus::Memory::Status status )
343 Dali::Application application(this);
344 mMemoryLowSignal.Emit( application );
346 mLowMemorySignal.Emit( status );
349 void Application::OnSurfaceCreated( Any newSurface )
351 void* newWindow = AnyCast< void* >( newSurface );
352 void* oldWindow = AnyCast< void* >( mMainWindow.GetNativeHandle() );
353 if( oldWindow != newWindow )
355 auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory();
356 std::unique_ptr< WindowRenderSurface > newSurfacePtr
357 = renderSurfaceFactory->CreateWindowRenderSurface( PositionSize(), newSurface, true );
359 mAdaptor->ReplaceSurface( mMainWindow, *newSurfacePtr.release() );
363 void Application::OnSurfaceDestroyed( Any surface )
367 void Application::OnResize(Dali::Adaptor& adaptor)
369 Dali::Application application(this);
370 mResizeSignal.Emit( application );
373 bool Application::AddIdle( CallbackBase* callback, bool hasReturnValue )
375 return mAdaptor->AddIdle( callback, hasReturnValue );
378 std::string Application::GetRegion() const
380 return mFramework->GetRegion();
383 std::string Application::GetLanguage() const
385 return mFramework->GetLanguage();
388 Dali::Adaptor& Application::GetAdaptor()
393 Dali::Window Application::GetWindow()
395 // Changed to return a different window handle after ReplaceWindow is called
396 // just for backward compatibility to make the test case pass
397 if ( mMainWindowReplaced )
399 Internal::Adaptor::Window* window = Internal::Adaptor::Window::New( PositionSize(), "ReplacedWindow", "", false );
400 return Dali::Window( window );
410 void Application::SetViewMode( ViewMode viewMode )
412 mViewMode = viewMode;
415 ViewMode Application::GetViewMode() const
420 void Application::SetStereoBase( float stereoBase )
422 mStereoBase = stereoBase;
425 float Application::GetStereoBase() const
430 void Application::ReplaceWindow( const PositionSize& positionSize, const std::string& name )
432 // This API is kept just for backward compatibility to make the test case pass.
434 mMainWindowReplaced = true;
435 OnResize( *mAdaptor );
438 std::string Application::GetResourcePath()
440 return Internal::Adaptor::Framework::GetResourcePath();
443 std::string Application::GetDataPath()
445 return Internal::Adaptor::Framework::GetDataPath();
448 void Application::SetStyleSheet( const std::string& stylesheet )
450 mStylesheet = stylesheet;
453 void Application::SetCommandLineOptions( int* argc, char **argv[] )
455 delete mCommandLineOptions;
457 mCommandLineOptions = new CommandLineOptions( argc, argv );
459 mFramework->SetCommandLineOptions( argc, argv );
462 ApplicationPtr Application::GetPreInitializedApplication()
464 return gPreInitializedApplication;
467 } // namespace Adaptor
469 } // namespace Internal