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 mContextLossConfiguration( Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS ),
98 mCommandLineOptions( nullptr ),
99 mAdaptorBuilder( nullptr ),
102 mMainWindowMode( windowMode ),
104 mStylesheet( stylesheet ),
105 mEnvironmentOptions(),
106 mWindowPositionSize( positionSize ),
107 mLaunchpadState( Launchpad::NONE ),
108 mSlotDelegate( this )
110 // Get mName from environment options
111 mMainWindowName = mEnvironmentOptions.GetWindowName();
112 if( mMainWindowName.empty() && argc && ( *argc > 0 ) )
114 // Set mName from command-line args if environment option not set
115 mMainWindowName = (*argv)[0];
118 mCommandLineOptions = new CommandLineOptions(argc, argv);
119 mFramework = new Framework( *this, argc, argv, applicationType );
120 mUseRemoteSurface = (applicationType == Framework::WATCH);
123 Application::~Application()
125 SingletonService service = SingletonService::Get();
126 // Note this can be false i.e. if Application has never created a Core instance
129 service.UnregisterAll();
134 delete mAdaptorBuilder;
135 delete mCommandLineOptions;
139 void Application::CreateWindow()
141 if( mWindowPositionSize.width == 0 && mWindowPositionSize.height == 0 )
143 if( mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0 )
145 // Command line options override environment options and full screen
146 mWindowPositionSize.width = mCommandLineOptions->stageWidth;
147 mWindowPositionSize.height = mCommandLineOptions->stageHeight;
149 else if( mEnvironmentOptions.GetWindowWidth() && mEnvironmentOptions.GetWindowHeight() )
151 // Environment options override full screen functionality if command line arguments not provided
152 mWindowPositionSize.width = mEnvironmentOptions.GetWindowWidth();
153 mWindowPositionSize.height = mEnvironmentOptions.GetWindowHeight();
157 const std::string& windowClassName = mEnvironmentOptions.GetWindowClassName();
159 Internal::Adaptor::Window* window = Internal::Adaptor::Window::New(mWindowPositionSize, mMainWindowName, windowClassName, mMainWindowMode == Dali::Application::TRANSPARENT);
160 mMainWindow = Dali::Window( window );
162 // Quit the application when the window is closed
163 GetImplementation( mMainWindow ).DeleteRequestSignal().Connect( mSlotDelegate, &Application::Quit );
166 void Application::CreateAdaptor()
168 DALI_ASSERT_ALWAYS( mMainWindow && "Window required to create adaptor" );
170 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
172 Integration::SceneHolder sceneHolder = Integration::SceneHolder( &Dali::GetImplementation( mMainWindow ) );
174 mAdaptor = Adaptor::New( graphicsFactory, sceneHolder, mContextLossConfiguration, &mEnvironmentOptions );
176 Adaptor::GetImplementation( *mAdaptor ).SetUseRemoteSurface( mUseRemoteSurface );
179 void Application::CreateAdaptorBuilder()
181 mAdaptorBuilder = new AdaptorBuilder();
184 void Application::MainLoop(Dali::Configuration::ContextLoss configuration)
186 mContextLossConfiguration = configuration;
188 // Run the application
192 void Application::Lower()
194 // Lower the application without quitting it.
198 void Application::Quit()
200 // Actually quit the application.
201 // Force a call to Quit even if adaptor is not running.
202 Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).AddIdle( MakeCallback( this, &Application::QuitFromMainLoop ), false, true );
205 void Application::QuitFromMainLoop()
210 // This will trigger OnTerminate(), below, after the main loop has completed.
213 void Application::OnInit()
215 mFramework->AddAbortCallback( MakeCallback( this, &Application::QuitFromMainLoop ) );
217 CreateAdaptorBuilder();
218 // If an application was pre-initialized, a window was made in advance
219 if( mLaunchpadState == Launchpad::NONE )
229 if( ! mStylesheet.empty() )
231 Dali::StyleMonitor::Get().SetTheme( mStylesheet );
234 // Wire up the LifecycleController
235 Dali::LifecycleController lifecycleController = Dali::LifecycleController::Get();
237 InitSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnInit );
238 TerminateSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnTerminate );
239 PauseSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnPause );
240 ResumeSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnResume );
241 ResetSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnReset );
242 LanguageChangedSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnLanguageChanged );
244 Dali::Application application(this);
245 mInitSignal.Emit( application );
247 mAdaptor->NotifySceneCreated();
250 void Application::OnTerminate()
252 // We've been told to quit by AppCore, ecore_x_destroy has been called, need to quit synchronously
253 // delete the window as ecore_x has been destroyed by AppCore
255 Dali::Application application(this);
256 mTerminateSignal.Emit( application );
260 // Ensure that the render-thread is not using the surface(window) after we delete it
264 mMainWindow.Reset(); // This only resets (clears) the default Window
267 void Application::OnPause()
269 // A DALi app should handle Pause/Resume events.
270 // DALi just delivers the framework Pause event to the application, but not actually pause DALi core.
271 // Pausing DALi core only occurs on the Window Hidden framework event
272 Dali::Application application(this);
273 mPauseSignal.Emit( application );
276 void Application::OnResume()
278 // Emit the signal first so the application can queue any messages before we do an update/render
279 // This ensures we do not just redraw the last frame before pausing if that's not required
280 Dali::Application application(this);
281 mResumeSignal.Emit( application );
283 // DALi just delivers the framework Resume event to the application.
284 // Resuming DALi core only occurs on the Window Show framework event
286 // Trigger processing of events queued up while paused
287 CoreEventInterface& coreEventInterface = Internal::Adaptor::Adaptor::GetImplementation( GetAdaptor() );
288 coreEventInterface.ProcessCoreEvents();
291 void Application::OnReset()
294 * usually, reset callback was called when a caller request to launch this application via aul.
295 * because Application class already handled initialization in OnInit(), OnReset do nothing.
297 Dali::Application application(this);
298 mResetSignal.Emit( application );
301 void Application::OnAppControl(void *data)
303 Dali::Application application(this);
304 mAppControlSignal.Emit( application , data );
307 void Application::OnLanguageChanged()
309 mAdaptor->NotifyLanguageChanged();
310 Dali::Application application(this);
311 mLanguageChangedSignal.Emit( application );
314 void Application::OnRegionChanged()
316 Dali::Application application(this);
317 mRegionChangedSignal.Emit( application );
320 void Application::OnBatteryLow( Dali::DeviceStatus::Battery::Status status )
322 Dali::Application application(this);
323 mLowBatterySignal.Emit( status );
326 void Application::OnMemoryLow( Dali::DeviceStatus::Memory::Status status )
328 Dali::Application application(this);
329 mLowMemorySignal.Emit( status );
332 void Application::OnSurfaceCreated( Any newSurface )
334 void* newWindow = AnyCast< void* >( newSurface );
335 void* oldWindow = AnyCast< void* >( mMainWindow.GetNativeHandle() );
336 if( oldWindow != newWindow )
338 auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory();
339 std::unique_ptr< WindowRenderSurface > newSurfacePtr
340 = renderSurfaceFactory->CreateWindowRenderSurface( PositionSize(), newSurface, true );
342 mAdaptor->ReplaceSurface( mMainWindow, *newSurfacePtr.release() );
346 void Application::OnSurfaceDestroyed( Any surface )
350 bool Application::AddIdle( CallbackBase* callback, bool hasReturnValue )
352 return mAdaptor->AddIdle( callback, hasReturnValue );
355 std::string Application::GetRegion() const
357 return mFramework->GetRegion();
360 std::string Application::GetLanguage() const
362 return mFramework->GetLanguage();
365 Dali::ObjectRegistry Application::GetObjectRegistry() const
367 Dali::ObjectRegistry objectRegistry;
370 objectRegistry = mAdaptor->GetObjectRegistry();
372 return objectRegistry;
375 Dali::Adaptor& Application::GetAdaptor()
380 Dali::Window Application::GetWindow()
385 std::string Application::GetResourcePath()
387 return Internal::Adaptor::Framework::GetResourcePath();
390 std::string Application::GetDataPath()
392 return Internal::Adaptor::Framework::GetDataPath();
395 void Application::SetStyleSheet( const std::string& stylesheet )
397 mStylesheet = stylesheet;
400 void Application::SetCommandLineOptions( int* argc, char **argv[] )
402 delete mCommandLineOptions;
404 mCommandLineOptions = new CommandLineOptions( argc, argv );
406 mFramework->SetCommandLineOptions( argc, argv );
409 ApplicationPtr Application::GetPreInitializedApplication()
411 return gPreInitializedApplication;
414 } // namespace Adaptor
416 } // namespace Internal