2 * Copyright (c) 2018 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;
87 //Make DefaultFontDescription cached
88 Dali::TextAbstraction::FontClient fontClient = Dali::TextAbstraction::FontClient::Get();
89 Dali::TextAbstraction::FontDescription defaultFontDescription;
90 fontClient.GetDefaultPlatformFontDescription( defaultFontDescription );
94 Application::Application( int* argc, char** argv[], const std::string& stylesheet,
95 Dali::Application::WINDOW_MODE windowMode, const PositionSize& positionSize, Framework::Type applicationType )
103 mLanguageChangedSignal(),
104 mRegionChangedSignal(),
107 mEventLoop( nullptr ),
108 mFramework( nullptr ),
109 mContextLossConfiguration( Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS ),
110 mCommandLineOptions( nullptr ),
111 mAdaptorBuilder( nullptr ),
114 mMainWindowMode( windowMode ),
116 mMainWindowReplaced( false ),
117 mStylesheet( stylesheet ),
118 mEnvironmentOptions(),
119 mWindowPositionSize( positionSize ),
120 mLaunchpadState( Launchpad::NONE ),
121 mSlotDelegate( this ),
123 mStereoBase( DEFAULT_STEREO_BASE )
125 // Get mName from environment options
126 mMainWindowName = mEnvironmentOptions.GetWindowName();
127 if( mMainWindowName.empty() && argc && ( *argc > 0 ) )
129 // Set mName from command-line args if environment option not set
130 mMainWindowName = (*argv)[0];
133 mCommandLineOptions = new CommandLineOptions(argc, argv);
134 mFramework = new Framework( *this, argc, argv, applicationType );
135 mUseRemoteSurface = (applicationType == Framework::WATCH);
138 Application::~Application()
140 SingletonService service = SingletonService::Get();
141 // Note this can be false i.e. if Application has never created a Core instance
144 service.UnregisterAll();
149 delete mAdaptorBuilder;
150 delete mCommandLineOptions;
154 void Application::CreateWindow()
156 if( mWindowPositionSize.width == 0 && mWindowPositionSize.height == 0 )
158 if( mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0 )
160 // Command line options override environment options and full screen
161 mWindowPositionSize.width = mCommandLineOptions->stageWidth;
162 mWindowPositionSize.height = mCommandLineOptions->stageHeight;
164 else if( mEnvironmentOptions.GetWindowWidth() && mEnvironmentOptions.GetWindowHeight() )
166 // Environment options override full screen functionality if command line arguments not provided
167 mWindowPositionSize.width = mEnvironmentOptions.GetWindowWidth();
168 mWindowPositionSize.height = mEnvironmentOptions.GetWindowHeight();
172 const std::string& windowClassName = mEnvironmentOptions.GetWindowClassName();
174 Internal::Adaptor::Window* window = Internal::Adaptor::Window::New( mWindowPositionSize, mMainWindowName, windowClassName, mMainWindowMode == Dali::Application::TRANSPARENT );
175 mMainWindow = Dali::Window( window );
177 // Quit the application when the window is closed
178 GetImplementation( mMainWindow ).DeleteRequestSignal().Connect( mSlotDelegate, &Application::Quit );
181 void Application::CreateAdaptor()
183 DALI_ASSERT_ALWAYS( mMainWindow && "Window required to create adaptor" );
185 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
187 Integration::SceneHolder sceneHolder = Integration::SceneHolder( &Dali::GetImplementation( mMainWindow ) );
189 mAdaptor = Adaptor::New( graphicsFactory, sceneHolder, mContextLossConfiguration, &mEnvironmentOptions );
191 mAdaptor->ResizedSignal().Connect( mSlotDelegate, &Application::OnResize );
193 Adaptor::GetImplementation( *mAdaptor ).SetUseRemoteSurface( mUseRemoteSurface );
196 void Application::CreateAdaptorBuilder()
198 mAdaptorBuilder = new AdaptorBuilder();
201 void Application::MainLoop(Dali::Configuration::ContextLoss configuration)
203 mContextLossConfiguration = configuration;
205 // Run the application
209 void Application::Lower()
211 // Lower the application without quitting it.
215 void Application::Quit()
217 // Actually quit the application.
218 // Force a call to Quit even if adaptor is not running.
219 Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).AddIdle( MakeCallback( this, &Application::QuitFromMainLoop ), false, true );
222 void Application::QuitFromMainLoop()
227 // This will trigger OnTerminate(), below, after the main loop has completed.
230 void Application::OnInit()
232 mFramework->AddAbortCallback( MakeCallback( this, &Application::QuitFromMainLoop ) );
234 CreateAdaptorBuilder();
235 // If an application was pre-initialized, a window was made in advance
236 if( mLaunchpadState == Launchpad::NONE )
246 if( ! mStylesheet.empty() )
248 Dali::StyleMonitor::Get().SetTheme( mStylesheet );
251 // Wire up the LifecycleController
252 Dali::LifecycleController lifecycleController = Dali::LifecycleController::Get();
254 InitSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnInit );
255 TerminateSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnTerminate );
256 PauseSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnPause );
257 ResumeSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnResume );
258 ResetSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnReset );
259 ResizeSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnResize );
260 LanguageChangedSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnLanguageChanged );
262 Dali::Application application(this);
263 mInitSignal.Emit( application );
265 mAdaptor->NotifySceneCreated();
268 void Application::OnTerminate()
270 // We've been told to quit by AppCore, ecore_x_destroy has been called, need to quit synchronously
271 // delete the window as ecore_x has been destroyed by AppCore
273 Dali::Application application(this);
274 mTerminateSignal.Emit( application );
278 // Ensure that the render-thread is not using the surface(window) after we delete it
282 mMainWindow.Reset(); // This only resets (clears) the default Window
285 void Application::OnPause()
287 // A DALi app should handle Pause/Resume events.
288 // DALi just delivers the framework Pause event to the application, but not actually pause DALi core.
289 // Pausing DALi core only occurs on the Window Hidden framework event
290 Dali::Application application(this);
291 mPauseSignal.Emit( application );
294 void Application::OnResume()
296 // Emit the signal first so the application can queue any messages before we do an update/render
297 // This ensures we do not just redraw the last frame before pausing if that's not required
298 Dali::Application application(this);
299 mResumeSignal.Emit( application );
301 // DALi just delivers the framework Resume event to the application.
302 // Resuming DALi core only occurs on the Window Show framework event
304 // Trigger processing of events queued up while paused
305 CoreEventInterface& coreEventInterface = Internal::Adaptor::Adaptor::GetImplementation( GetAdaptor() );
306 coreEventInterface.ProcessCoreEvents();
309 void Application::OnReset()
312 * usually, reset callback was called when a caller request to launch this application via aul.
313 * because Application class already handled initialization in OnInit(), OnReset do nothing.
315 Dali::Application application(this);
316 mResetSignal.Emit( application );
319 void Application::OnAppControl(void *data)
321 Dali::Application application(this);
322 mAppControlSignal.Emit( application , data );
325 void Application::OnLanguageChanged()
327 mAdaptor->NotifyLanguageChanged();
328 Dali::Application application(this);
329 mLanguageChangedSignal.Emit( application );
332 void Application::OnRegionChanged()
334 Dali::Application application(this);
335 mRegionChangedSignal.Emit( application );
338 void Application::OnBatteryLow( Dali::DeviceStatus::Battery::Status status )
340 Dali::Application application(this);
341 mBatteryLowSignal.Emit( application );
343 mLowBatterySignal.Emit( status );
346 void Application::OnMemoryLow( Dali::DeviceStatus::Memory::Status status )
348 Dali::Application application(this);
349 mMemoryLowSignal.Emit( application );
351 mLowMemorySignal.Emit( status );
354 void Application::OnSurfaceCreated( Any newSurface )
356 void* newWindow = AnyCast< void* >( newSurface );
357 void* oldWindow = AnyCast< void* >( mMainWindow.GetNativeHandle() );
358 if( oldWindow != newWindow )
360 auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory();
361 std::unique_ptr< WindowRenderSurface > newSurfacePtr
362 = renderSurfaceFactory->CreateWindowRenderSurface( PositionSize(), newSurface, true );
364 mAdaptor->ReplaceSurface( mMainWindow, *newSurfacePtr.release() );
368 void Application::OnSurfaceDestroyed( Any surface )
370 void* windowToDelete = AnyCast< void* >( surface );
371 void* oldWindow = AnyCast< void* >( mMainWindow.GetNativeHandle() );
372 if( oldWindow == windowToDelete )
374 mAdaptor->DeleteSurface( mAdaptor->GetSurface() );
378 void Application::OnResize(Dali::Adaptor& adaptor)
380 Dali::Application application(this);
381 mResizeSignal.Emit( application );
384 bool Application::AddIdle( CallbackBase* callback, bool hasReturnValue )
386 return mAdaptor->AddIdle( callback, hasReturnValue );
389 std::string Application::GetRegion() const
391 return mFramework->GetRegion();
394 std::string Application::GetLanguage() const
396 return mFramework->GetLanguage();
399 Dali::Adaptor& Application::GetAdaptor()
404 Dali::Window Application::GetWindow()
406 // Changed to return a different window handle after ReplaceWindow is called
407 // just for backward compatibility to make the test case pass
408 if ( mMainWindowReplaced )
410 Internal::Adaptor::Window* window = Internal::Adaptor::Window::New( PositionSize(), "ReplacedWindow", "", false );
411 return Dali::Window( window );
421 void Application::SetViewMode( ViewMode viewMode )
423 mViewMode = viewMode;
426 ViewMode Application::GetViewMode() const
431 void Application::SetStereoBase( float stereoBase )
433 mStereoBase = stereoBase;
436 float Application::GetStereoBase() const
441 void Application::ReplaceWindow( const PositionSize& positionSize, const std::string& name )
443 // This API is kept just for backward compatibility to make the test case pass.
445 mMainWindowReplaced = true;
446 OnResize( *mAdaptor );
449 std::string Application::GetResourcePath()
451 return Internal::Adaptor::Framework::GetResourcePath();
454 std::string Application::GetDataPath()
456 return Internal::Adaptor::Framework::GetDataPath();
459 void Application::SetStyleSheet( const std::string& stylesheet )
461 mStylesheet = stylesheet;
464 void Application::SetCommandLineOptions( int* argc, char **argv[] )
466 delete mCommandLineOptions;
468 mCommandLineOptions = new CommandLineOptions( argc, argv );
470 mFramework->SetCommandLineOptions( argc, argv );
473 ApplicationPtr Application::GetPreInitializedApplication()
475 return gPreInitializedApplication;
478 } // namespace Adaptor
480 } // namespace Internal