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;
58 ApplicationPtr Application::gPreInitializedApplication( NULL );
60 ApplicationPtr Application::New(
63 const std::string& stylesheet,
64 Dali::Application::WINDOW_MODE windowMode,
65 const PositionSize& positionSize,
66 Framework::Type applicationType)
68 ApplicationPtr application ( new Application (argc, argv, stylesheet, windowMode, positionSize, applicationType ) );
72 void Application::PreInitialize( int* argc, char** argv[] )
74 if( !gPreInitializedApplication )
76 Dali::TextAbstraction::FontClientPreInitialize();
78 gPreInitializedApplication = new Application ( argc, argv, "", Dali::Application::OPAQUE, PositionSize(), Framework::NORMAL );
79 gPreInitializedApplication->CreateWindow(); // Only create window
80 gPreInitializedApplication->mLaunchpadState = Launchpad::PRE_INITIALIZED;
84 Application::Application( int* argc, char** argv[], const std::string& stylesheet,
85 Dali::Application::WINDOW_MODE windowMode, const PositionSize& positionSize, Framework::Type applicationType )
92 mLanguageChangedSignal(),
93 mRegionChangedSignal(),
94 mEventLoop( nullptr ),
95 mFramework( nullptr ),
96 mContextLossConfiguration( Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS ),
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, mContextLossConfiguration, &mEnvironmentOptions );
175 Adaptor::GetImplementation( *mAdaptor ).SetUseRemoteSurface( mUseRemoteSurface );
178 void Application::CreateAdaptorBuilder()
180 mAdaptorBuilder = new AdaptorBuilder();
183 void Application::MainLoop(Dali::Configuration::ContextLoss configuration)
185 mContextLossConfiguration = configuration;
187 // Run the application
191 void Application::Lower()
193 // Lower the application without quitting it.
197 void Application::Quit()
199 // Actually quit the application.
200 // Force a call to Quit even if adaptor is not running.
201 Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).AddIdle( MakeCallback( this, &Application::QuitFromMainLoop ), false, true );
204 void Application::QuitFromMainLoop()
209 // This will trigger OnTerminate(), below, after the main loop has completed.
212 void Application::OnInit()
214 mFramework->AddAbortCallback( MakeCallback( this, &Application::QuitFromMainLoop ) );
216 CreateAdaptorBuilder();
217 // If an application was pre-initialized, a window was made in advance
218 if( mLaunchpadState == Launchpad::NONE )
228 if( ! mStylesheet.empty() )
230 Dali::StyleMonitor::Get().SetTheme( mStylesheet );
233 // Wire up the LifecycleController
234 Dali::LifecycleController lifecycleController = Dali::LifecycleController::Get();
236 InitSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnInit );
237 TerminateSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnTerminate );
238 PauseSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnPause );
239 ResumeSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnResume );
240 ResetSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnReset );
241 LanguageChangedSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnLanguageChanged );
243 Dali::Application application(this);
244 mInitSignal.Emit( application );
246 mAdaptor->NotifySceneCreated();
249 void Application::OnTerminate()
251 // We've been told to quit by AppCore, ecore_x_destroy has been called, need to quit synchronously
252 // delete the window as ecore_x has been destroyed by AppCore
254 Dali::Application application(this);
255 mTerminateSignal.Emit( application );
259 // Ensure that the render-thread is not using the surface(window) after we delete it
263 mMainWindow.Reset(); // This only resets (clears) the default Window
266 void Application::OnPause()
268 // A DALi app should handle Pause/Resume events.
269 // DALi just delivers the framework Pause event to the application, but not actually pause DALi core.
270 // Pausing DALi core only occurs on the Window Hidden framework event
271 Dali::Application application(this);
272 mPauseSignal.Emit( application );
275 void Application::OnResume()
277 // Emit the signal first so the application can queue any messages before we do an update/render
278 // This ensures we do not just redraw the last frame before pausing if that's not required
279 Dali::Application application(this);
280 mResumeSignal.Emit( application );
282 // DALi just delivers the framework Resume event to the application.
283 // Resuming DALi core only occurs on the Window Show framework event
285 // Trigger processing of events queued up while paused
286 CoreEventInterface& coreEventInterface = Internal::Adaptor::Adaptor::GetImplementation( GetAdaptor() );
287 coreEventInterface.ProcessCoreEvents();
290 void Application::OnReset()
293 * usually, reset callback was called when a caller request to launch this application via aul.
294 * because Application class already handled initialization in OnInit(), OnReset do nothing.
296 Dali::Application application(this);
297 mResetSignal.Emit( application );
300 void Application::OnAppControl(void *data)
302 Dali::Application application(this);
303 mAppControlSignal.Emit( application , data );
306 void Application::OnLanguageChanged()
308 mAdaptor->NotifyLanguageChanged();
309 Dali::Application application(this);
310 mLanguageChangedSignal.Emit( application );
313 void Application::OnRegionChanged()
315 Dali::Application application(this);
316 mRegionChangedSignal.Emit( application );
319 void Application::OnBatteryLow( Dali::DeviceStatus::Battery::Status status )
321 Dali::Application application(this);
322 mLowBatterySignal.Emit( status );
325 void Application::OnMemoryLow( Dali::DeviceStatus::Memory::Status status )
327 Dali::Application application(this);
328 mLowMemorySignal.Emit( status );
331 void Application::OnSurfaceCreated( Any newSurface )
333 void* newWindow = AnyCast< void* >( newSurface );
334 void* oldWindow = AnyCast< void* >( mMainWindow.GetNativeHandle() );
335 if( oldWindow != newWindow )
337 auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory();
338 std::unique_ptr< WindowRenderSurface > newSurfacePtr
339 = renderSurfaceFactory->CreateWindowRenderSurface( PositionSize(), newSurface, true );
341 mAdaptor->ReplaceSurface( mMainWindow, *newSurfacePtr.release() );
345 void Application::OnSurfaceDestroyed( Any surface )
349 bool Application::AddIdle( CallbackBase* callback, bool hasReturnValue )
351 return mAdaptor->AddIdle( callback, hasReturnValue );
354 std::string Application::GetRegion() const
356 return mFramework->GetRegion();
359 std::string Application::GetLanguage() const
361 return mFramework->GetLanguage();
364 Dali::Adaptor& Application::GetAdaptor()
369 Dali::Window Application::GetWindow()
374 std::string Application::GetResourcePath()
376 return Internal::Adaptor::Framework::GetResourcePath();
379 std::string Application::GetDataPath()
381 return Internal::Adaptor::Framework::GetDataPath();
384 void Application::SetStyleSheet( const std::string& stylesheet )
386 mStylesheet = stylesheet;
389 void Application::SetCommandLineOptions( int* argc, char **argv[] )
391 delete mCommandLineOptions;
393 mCommandLineOptions = new CommandLineOptions( argc, argv );
395 mFramework->SetCommandLineOptions( argc, argv );
398 ApplicationPtr Application::GetPreInitializedApplication()
400 return gPreInitializedApplication;
403 } // namespace Adaptor
405 } // namespace Internal