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/devel-api/adaptor-framework/accessibility-impl.h>
30 #include <dali/internal/adaptor/common/adaptor-impl.h>
31 #include <dali/internal/system/common/command-line-options.h>
32 #include <dali/internal/adaptor/common/framework.h>
33 #include <dali/internal/adaptor/common/lifecycle-controller-impl.h>
34 #include <dali/internal/window-system/common/window-impl.h>
35 #include <dali/internal/window-system/common/window-render-surface.h>
36 #include <dali/internal/window-system/common/render-surface-factory.h>
38 // To disable a macro with the same name from one of OpenGL headers
44 namespace TizenPlatform
46 class TizenPlatformAbstraction;
60 ApplicationPtr Application::gPreInitializedApplication( NULL );
62 ApplicationPtr Application::New(
65 const std::string& stylesheet,
66 Dali::Application::WINDOW_MODE windowMode,
67 const PositionSize& positionSize,
68 Framework::Type applicationType)
70 ApplicationPtr application ( new Application (argc, argv, stylesheet, windowMode, positionSize, applicationType ) );
74 void Application::PreInitialize( int* argc, char** argv[] )
76 if( !gPreInitializedApplication )
78 Dali::TextAbstraction::FontClientPreInitialize();
80 gPreInitializedApplication = new Application ( argc, argv, "", Dali::Application::OPAQUE, PositionSize(), Framework::NORMAL );
81 gPreInitializedApplication->CreateWindow(); // Only create window
82 gPreInitializedApplication->mLaunchpadState = Launchpad::PRE_INITIALIZED;
86 Application::Application( int* argc, char** argv[], const std::string& stylesheet,
87 Dali::Application::WINDOW_MODE windowMode, const PositionSize& positionSize, Framework::Type applicationType )
94 mLanguageChangedSignal(),
95 mRegionChangedSignal(),
96 mEventLoop( nullptr ),
97 mFramework( nullptr ),
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, &mEnvironmentOptions );
176 Adaptor::GetImplementation( *mAdaptor ).SetUseRemoteSurface( mUseRemoteSurface );
179 void Application::CreateAdaptorBuilder()
181 mAdaptorBuilder = new AdaptorBuilder();
184 void Application::MainLoop()
186 // Run the application
190 void Application::Lower()
192 // Lower the application without quitting it.
196 void Application::Quit()
198 // Actually quit the application.
199 // Force a call to Quit even if adaptor is not running.
200 Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).AddIdle( MakeCallback( this, &Application::QuitFromMainLoop ), false, true );
203 void Application::QuitFromMainLoop()
205 Accessibility::Bridge::GetCurrentBridge()->Terminate();
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 )
228 Accessibility::Accessible::SetObjectRegistry(mAdaptor->GetObjectRegistry());
230 if( ! mStylesheet.empty() )
232 Dali::StyleMonitor::Get().SetTheme( mStylesheet );
235 // Wire up the LifecycleController
236 Dali::LifecycleController lifecycleController = Dali::LifecycleController::Get();
238 InitSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnInit );
239 TerminateSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnTerminate );
240 PauseSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnPause );
241 ResumeSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnResume );
242 ResetSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnReset );
243 LanguageChangedSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnLanguageChanged );
245 Dali::Application application(this);
246 mInitSignal.Emit( application );
248 mAdaptor->NotifySceneCreated();
251 void Application::OnTerminate()
253 // We've been told to quit by AppCore, ecore_x_destroy has been called, need to quit synchronously
254 // delete the window as ecore_x has been destroyed by AppCore
256 Dali::Application application(this);
257 mTerminateSignal.Emit( application );
261 // Ensure that the render-thread is not using the surface(window) after we delete it
265 mMainWindow.Reset(); // This only resets (clears) the default Window
268 void Application::OnPause()
270 // A DALi app should handle Pause/Resume events.
271 // DALi just delivers the framework Pause event to the application, but not actually pause DALi core.
272 // Pausing DALi core only occurs on the Window Hidden framework event
273 Dali::Application application(this);
274 mPauseSignal.Emit( application );
277 void Application::OnResume()
279 // Emit the signal first so the application can queue any messages before we do an update/render
280 // This ensures we do not just redraw the last frame before pausing if that's not required
281 Dali::Application application(this);
282 mResumeSignal.Emit( application );
284 // DALi just delivers the framework Resume event to the application.
285 // Resuming DALi core only occurs on the Window Show framework event
287 // Trigger processing of events queued up while paused
288 CoreEventInterface& coreEventInterface = Internal::Adaptor::Adaptor::GetImplementation( GetAdaptor() );
289 coreEventInterface.ProcessCoreEvents();
292 void Application::OnReset()
295 * usually, reset callback was called when a caller request to launch this application via aul.
296 * because Application class already handled initialization in OnInit(), OnReset do nothing.
298 Dali::Application application(this);
299 mResetSignal.Emit( application );
302 void Application::OnAppControl(void *data)
304 Dali::Application application(this);
305 mAppControlSignal.Emit( application , data );
308 void Application::OnLanguageChanged()
310 mAdaptor->NotifyLanguageChanged();
311 Dali::Application application(this);
312 mLanguageChangedSignal.Emit( application );
315 void Application::OnRegionChanged()
317 Dali::Application application(this);
318 mRegionChangedSignal.Emit( application );
321 void Application::OnBatteryLow( Dali::DeviceStatus::Battery::Status status )
323 Dali::Application application(this);
324 mLowBatterySignal.Emit( status );
327 void Application::OnMemoryLow( Dali::DeviceStatus::Memory::Status status )
329 Dali::Application application(this);
330 mLowMemorySignal.Emit( status );
333 void Application::OnSurfaceCreated( Any newSurface )
335 void* newWindow = AnyCast< void* >( newSurface );
336 void* oldWindow = AnyCast< void* >( mMainWindow.GetNativeHandle() );
337 if( oldWindow != newWindow )
339 auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory();
340 std::unique_ptr< WindowRenderSurface > newSurfacePtr
341 = renderSurfaceFactory->CreateWindowRenderSurface( PositionSize(), newSurface, true );
343 mAdaptor->ReplaceSurface( mMainWindow, *newSurfacePtr.release() );
347 void Application::OnSurfaceDestroyed( Any surface )
351 bool Application::AddIdle( CallbackBase* callback, bool hasReturnValue )
353 return mAdaptor->AddIdle( callback, hasReturnValue );
356 std::string Application::GetRegion() const
358 return mFramework->GetRegion();
361 std::string Application::GetLanguage() const
363 return mFramework->GetLanguage();
366 Dali::ObjectRegistry Application::GetObjectRegistry() const
368 Dali::ObjectRegistry objectRegistry;
371 objectRegistry = mAdaptor->GetObjectRegistry();
373 return objectRegistry;
376 Dali::Adaptor& Application::GetAdaptor()
381 Dali::Window Application::GetWindow()
386 std::string Application::GetResourcePath()
388 return Internal::Adaptor::Framework::GetResourcePath();
391 std::string Application::GetDataPath()
393 return Internal::Adaptor::Framework::GetDataPath();
396 void Application::SetStyleSheet( const std::string& stylesheet )
398 mStylesheet = stylesheet;
401 void Application::SetCommandLineOptions( int* argc, char **argv[] )
403 delete mCommandLineOptions;
405 mCommandLineOptions = new CommandLineOptions( argc, argv );
407 mFramework->SetCommandLineOptions( argc, argv );
410 ApplicationPtr Application::GetPreInitializedApplication()
412 return gPreInitializedApplication;
415 } // namespace Adaptor
417 } // namespace Internal