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 Dali::TextAbstraction::FontClientPreInitialize();
85 gPreInitializedApplication = new Application ( argc, argv, "", Dali::Application::OPAQUE, PositionSize(), Framework::NORMAL );
86 gPreInitializedApplication->CreateWindow(); // Only create window
87 gPreInitializedApplication->mLaunchpadState = Launchpad::PRE_INITIALIZED;
91 Application::Application( int* argc, char** argv[], const std::string& stylesheet,
92 Dali::Application::WINDOW_MODE windowMode, const PositionSize& positionSize, Framework::Type applicationType )
100 mLanguageChangedSignal(),
101 mRegionChangedSignal(),
104 mEventLoop( nullptr ),
105 mFramework( nullptr ),
106 mContextLossConfiguration( Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS ),
107 mCommandLineOptions( nullptr ),
108 mAdaptorBuilder( nullptr ),
111 mMainWindowMode( windowMode ),
113 mMainWindowReplaced( false ),
114 mStylesheet( stylesheet ),
115 mEnvironmentOptions(),
116 mWindowPositionSize( positionSize ),
117 mLaunchpadState( Launchpad::NONE ),
118 mSlotDelegate( this ),
120 mStereoBase( DEFAULT_STEREO_BASE )
122 // Get mName from environment options
123 mMainWindowName = mEnvironmentOptions.GetWindowName();
124 if( mMainWindowName.empty() && argc && ( *argc > 0 ) )
126 // Set mName from command-line args if environment option not set
127 mMainWindowName = (*argv)[0];
130 mCommandLineOptions = new CommandLineOptions(argc, argv);
131 mFramework = new Framework( *this, argc, argv, applicationType );
132 mUseRemoteSurface = (applicationType == Framework::WATCH);
135 Application::~Application()
137 SingletonService service = SingletonService::Get();
138 // Note this can be false i.e. if Application has never created a Core instance
141 service.UnregisterAll();
146 delete mAdaptorBuilder;
147 delete mCommandLineOptions;
151 void Application::CreateWindow()
153 if( mWindowPositionSize.width == 0 && mWindowPositionSize.height == 0 )
155 if( mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0 )
157 // Command line options override environment options and full screen
158 mWindowPositionSize.width = mCommandLineOptions->stageWidth;
159 mWindowPositionSize.height = mCommandLineOptions->stageHeight;
161 else if( mEnvironmentOptions.GetWindowWidth() && mEnvironmentOptions.GetWindowHeight() )
163 // Environment options override full screen functionality if command line arguments not provided
164 mWindowPositionSize.width = mEnvironmentOptions.GetWindowWidth();
165 mWindowPositionSize.height = mEnvironmentOptions.GetWindowHeight();
169 const std::string& windowClassName = mEnvironmentOptions.GetWindowClassName();
171 Internal::Adaptor::Window* window = Internal::Adaptor::Window::New( mWindowPositionSize, mMainWindowName, windowClassName, mMainWindowMode == Dali::Application::TRANSPARENT );
172 mMainWindow = Dali::Window( window );
174 // Quit the application when the window is closed
175 GetImplementation( mMainWindow ).DeleteRequestSignal().Connect( mSlotDelegate, &Application::Quit );
178 void Application::CreateAdaptor()
180 DALI_ASSERT_ALWAYS( mMainWindow && "Window required to create adaptor" );
182 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
184 Integration::SceneHolder sceneHolder = Integration::SceneHolder( &Dali::GetImplementation( mMainWindow ) );
186 mAdaptor = Adaptor::New( graphicsFactory, sceneHolder, mContextLossConfiguration, &mEnvironmentOptions );
188 mAdaptor->ResizedSignal().Connect( mSlotDelegate, &Application::OnResize );
190 Adaptor::GetImplementation( *mAdaptor ).SetUseRemoteSurface( mUseRemoteSurface );
193 void Application::CreateAdaptorBuilder()
195 mAdaptorBuilder = new AdaptorBuilder();
198 void Application::MainLoop(Dali::Configuration::ContextLoss configuration)
200 mContextLossConfiguration = configuration;
202 // Run the application
206 void Application::Lower()
208 // Lower the application without quitting it.
212 void Application::Quit()
214 // Actually quit the application.
215 // Force a call to Quit even if adaptor is not running.
216 Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).AddIdle( MakeCallback( this, &Application::QuitFromMainLoop ), false, true );
219 void Application::QuitFromMainLoop()
224 // This will trigger OnTerminate(), below, after the main loop has completed.
227 void Application::OnInit()
229 mFramework->AddAbortCallback( MakeCallback( this, &Application::QuitFromMainLoop ) );
231 CreateAdaptorBuilder();
232 // If an application was pre-initialized, a window was made in advance
233 if( mLaunchpadState == Launchpad::NONE )
243 if( ! mStylesheet.empty() )
245 Dali::StyleMonitor::Get().SetTheme( mStylesheet );
248 // Wire up the LifecycleController
249 Dali::LifecycleController lifecycleController = Dali::LifecycleController::Get();
251 InitSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnInit );
252 TerminateSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnTerminate );
253 PauseSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnPause );
254 ResumeSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnResume );
255 ResetSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnReset );
256 ResizeSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnResize );
257 LanguageChangedSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnLanguageChanged );
259 Dali::Application application(this);
260 mInitSignal.Emit( application );
262 mAdaptor->NotifySceneCreated();
265 void Application::OnTerminate()
267 // We've been told to quit by AppCore, ecore_x_destroy has been called, need to quit synchronously
268 // delete the window as ecore_x has been destroyed by AppCore
270 Dali::Application application(this);
271 mTerminateSignal.Emit( application );
275 // Ensure that the render-thread is not using the surface(window) after we delete it
279 mMainWindow.Reset(); // This only resets (clears) the default Window
282 void Application::OnPause()
284 // A DALi app should handle Pause/Resume events.
285 // DALi just delivers the framework Pause event to the application, but not actually pause DALi core.
286 // Pausing DALi core only occurs on the Window Hidden framework event
287 Dali::Application application(this);
288 mPauseSignal.Emit( application );
291 void Application::OnResume()
293 // Emit the signal first so the application can queue any messages before we do an update/render
294 // This ensures we do not just redraw the last frame before pausing if that's not required
295 Dali::Application application(this);
296 mResumeSignal.Emit( application );
298 // DALi just delivers the framework Resume event to the application.
299 // Resuming DALi core only occurs on the Window Show framework event
301 // Trigger processing of events queued up while paused
302 CoreEventInterface& coreEventInterface = Internal::Adaptor::Adaptor::GetImplementation( GetAdaptor() );
303 coreEventInterface.ProcessCoreEvents();
306 void Application::OnReset()
309 * usually, reset callback was called when a caller request to launch this application via aul.
310 * because Application class already handled initialization in OnInit(), OnReset do nothing.
312 Dali::Application application(this);
313 mResetSignal.Emit( application );
316 void Application::OnAppControl(void *data)
318 Dali::Application application(this);
319 mAppControlSignal.Emit( application , data );
322 void Application::OnLanguageChanged()
324 mAdaptor->NotifyLanguageChanged();
325 Dali::Application application(this);
326 mLanguageChangedSignal.Emit( application );
329 void Application::OnRegionChanged()
331 Dali::Application application(this);
332 mRegionChangedSignal.Emit( application );
335 void Application::OnBatteryLow( Dali::DeviceStatus::Battery::Status status )
337 Dali::Application application(this);
338 mBatteryLowSignal.Emit( application );
340 mLowBatterySignal.Emit( status );
343 void Application::OnMemoryLow( Dali::DeviceStatus::Memory::Status status )
345 Dali::Application application(this);
346 mMemoryLowSignal.Emit( application );
348 mLowMemorySignal.Emit( status );
351 void Application::OnSurfaceCreated( Any newSurface )
353 void* newWindow = AnyCast< void* >( newSurface );
354 void* oldWindow = AnyCast< void* >( mMainWindow.GetNativeHandle() );
355 if( oldWindow != newWindow )
357 auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory();
358 std::unique_ptr< WindowRenderSurface > newSurfacePtr
359 = renderSurfaceFactory->CreateWindowRenderSurface( PositionSize(), newSurface, true );
361 mAdaptor->ReplaceSurface( mMainWindow, *newSurfacePtr.release() );
365 void Application::OnSurfaceDestroyed( Any surface )
369 void Application::OnResize(Dali::Adaptor& adaptor)
371 Dali::Application application(this);
372 mResizeSignal.Emit( application );
375 bool Application::AddIdle( CallbackBase* callback, bool hasReturnValue )
377 return mAdaptor->AddIdle( callback, hasReturnValue );
380 std::string Application::GetRegion() const
382 return mFramework->GetRegion();
385 std::string Application::GetLanguage() const
387 return mFramework->GetLanguage();
390 Dali::Adaptor& Application::GetAdaptor()
395 Dali::Window Application::GetWindow()
397 // Changed to return a different window handle after ReplaceWindow is called
398 // just for backward compatibility to make the test case pass
399 if ( mMainWindowReplaced )
401 Internal::Adaptor::Window* window = Internal::Adaptor::Window::New( PositionSize(), "ReplacedWindow", "", false );
402 return Dali::Window( window );
412 void Application::SetViewMode( ViewMode viewMode )
414 mViewMode = viewMode;
417 ViewMode Application::GetViewMode() const
422 void Application::SetStereoBase( float stereoBase )
424 mStereoBase = stereoBase;
427 float Application::GetStereoBase() const
432 void Application::ReplaceWindow( const PositionSize& positionSize, const std::string& name )
434 // This API is kept just for backward compatibility to make the test case pass.
436 mMainWindowReplaced = true;
437 OnResize( *mAdaptor );
440 std::string Application::GetResourcePath()
442 return Internal::Adaptor::Framework::GetResourcePath();
445 std::string Application::GetDataPath()
447 return Internal::Adaptor::Framework::GetDataPath();
450 void Application::SetStyleSheet( const std::string& stylesheet )
452 mStylesheet = stylesheet;
455 void Application::SetCommandLineOptions( int* argc, char **argv[] )
457 delete mCommandLineOptions;
459 mCommandLineOptions = new CommandLineOptions( argc, argv );
461 mFramework->SetCommandLineOptions( argc, argv );
464 ApplicationPtr Application::GetPreInitializedApplication()
466 return gPreInitializedApplication;
469 } // namespace Adaptor
471 } // namespace Internal