/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <style-monitor.h>
#include <command-line-options.h>
#include <common/adaptor-impl.h>
+#include <common/framework.h>
#include <singleton-service-impl.h>
#include <lifecycle-controller-impl.h>
namespace Adaptor
{
+ApplicationPtr Application::gPreInitializedApplication( NULL );
+
ApplicationPtr Application::New(
int* argc,
char **argv[],
- const std::string& name,
- const DeviceLayout& baseLayout,
- Dali::Application::WINDOW_MODE windowMode)
+ const std::string& stylesheet,
+ Dali::Application::WINDOW_MODE windowMode,
+ const PositionSize& positionSize,
+ Framework::Type applicationType)
{
- ApplicationPtr application ( new Application (argc, argv, name, baseLayout, windowMode ) );
+ ApplicationPtr application ( new Application (argc, argv, stylesheet, windowMode, positionSize, applicationType ) );
return application;
}
-Application::Application( int* argc, char** argv[], const std::string& name, const DeviceLayout& baseLayout, Dali::Application::WINDOW_MODE windowMode)
+void Application::PreInitialize( int* argc, char** argv[] )
+{
+ if( !gPreInitializedApplication )
+ {
+ gPreInitializedApplication = new Application ( argc, argv, "", Dali::Application::OPAQUE, PositionSize(), Framework::NORMAL );
+
+ gPreInitializedApplication->CreateWindow(); // Only create window
+
+ gPreInitializedApplication->mLaunchpadState = Launchpad::PRE_INITIALIZED;
+ }
+}
+
+Application::Application( int* argc, char** argv[], const std::string& stylesheet,
+ Dali::Application::WINDOW_MODE windowMode, const PositionSize& positionSize, Framework::Type applicationType )
: mInitSignal(),
mTerminateSignal(),
mPauseSignal(),
mMemoryLowSignal(),
mEventLoop( NULL ),
mFramework( NULL ),
+ mContextLossConfiguration( Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS ),
mCommandLineOptions( NULL ),
mSingletonService( SingletonService::New() ),
mAdaptor( NULL ),
mWindow(),
mWindowMode( windowMode ),
- mName( name ),
- mInitialized( false ),
- mBaseLayout( baseLayout ),
+ mName(),
+ mStylesheet( stylesheet ),
+ mEnvironmentOptions(),
+ mWindowPositionSize( positionSize ),
+ mLaunchpadState( Launchpad::NONE ),
mSlotDelegate( this )
{
- mCommandLineOptions = new CommandLineOptions(argc, argv);
+ // Get mName from environment options
+ mName = mEnvironmentOptions.GetWindowName();
+ if( mName.empty() && argc && ( *argc > 0 ) )
+ {
+ // Set mName from command-line args if environment option not set
+ mName = (*argv)[0];
+ }
- mFramework = new Framework(*this, argc, argv, name);
+ mCommandLineOptions = new CommandLineOptions(argc, argv);
+ mFramework = new Framework( *this, argc, argv, applicationType );
+ mUseRemoteSurface = (applicationType == Framework::WATCH);
}
Application::~Application()
{
mSingletonService.UnregisterAll();
- delete mFramework;
- delete mCommandLineOptions;
- delete mAdaptor;
mWindow.Reset();
+ delete mAdaptor;
+ delete mCommandLineOptions;
+ delete mFramework;
}
void Application::CreateWindow()
{
- PositionSize windowPosition(0, 0, 0, 0); // this will use full screen
+ if( mWindowPositionSize.width == 0 && mWindowPositionSize.height == 0 )
+ {
+ if( mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0 )
+ {
+ // Command line options override environment options and full screen
+ mWindowPositionSize.width = mCommandLineOptions->stageWidth;
+ mWindowPositionSize.height = mCommandLineOptions->stageHeight;
+ }
+ else if( mEnvironmentOptions.GetWindowWidth() && mEnvironmentOptions.GetWindowHeight() )
+ {
+ // Environment options override full screen functionality if command line arguments not provided
+ mWindowPositionSize.width = mEnvironmentOptions.GetWindowWidth();
+ mWindowPositionSize.height = mEnvironmentOptions.GetWindowHeight();
+ }
+ }
- if( mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0 )
+ const std::string& windowClassName = mEnvironmentOptions.GetWindowClassName();
+ mWindow = Dali::Window::New( mWindowPositionSize, mName, windowClassName, mWindowMode == Dali::Application::TRANSPARENT );
+
+ int indicatorVisibleMode = mEnvironmentOptions.GetIndicatorVisibleMode();
+ if( indicatorVisibleMode >= Dali::Window::INVISIBLE && indicatorVisibleMode <= Dali::Window::AUTO )
{
- // let the command line options over ride
- windowPosition = PositionSize( 0, 0, mCommandLineOptions->stageWidth, mCommandLineOptions->stageHeight );
+ GetImplementation( mWindow ).SetIndicatorVisibleMode( static_cast< Dali::Window::IndicatorVisibleMode >( indicatorVisibleMode ) );
}
- mWindow = Dali::Window::New( windowPosition, mName, mWindowMode == Dali::Application::TRANSPARENT );
+ // Quit the application when the window is closed
+ GetImplementation( mWindow ).DeleteRequestSignal().Connect( mSlotDelegate, &Application::Quit );
}
void Application::CreateAdaptor()
{
DALI_ASSERT_ALWAYS( mWindow && "Window required to create adaptor" );
- mAdaptor = &Dali::Adaptor::New( mWindow, mBaseLayout, mContextLossConfiguration );
-
- std::string dpiStr = mCommandLineOptions->stageDPI;
- if(!dpiStr.empty())
- {
- // Use DPI from command line.
- unsigned int hDPI = 0;
- unsigned int vDPI = 0;
-
- sscanf(dpiStr.c_str(), "%ux%u", &hDPI, &vDPI);
-
- Internal::Adaptor::Adaptor::GetImplementation( *mAdaptor ).SetDpi(hDPI, vDPI);
- }
+ mAdaptor = Dali::Internal::Adaptor::Adaptor::New( mWindow, mContextLossConfiguration, &mEnvironmentOptions );
mAdaptor->ResizedSignal().Connect( mSlotDelegate, &Application::OnResize );
+
+ Internal::Adaptor::Adaptor::GetImplementation( *mAdaptor ).SetUseRemoteSurface( mUseRemoteSurface );
}
void Application::MainLoop(Dali::Configuration::ContextLoss configuration)
void Application::Quit()
{
// Actually quit the application.
- AddIdle( MakeCallback( this, &Application::QuitFromMainLoop ) );
+ // Force a call to Quit even if adaptor is not running.
+ Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).AddIdle( MakeCallback( this, &Application::QuitFromMainLoop ), true );
}
void Application::QuitFromMainLoop()
{
mAdaptor->Stop();
- Dali::Application application(this);
- mTerminateSignal.Emit( application );
-
mFramework->Quit();
// This will trigger OnTerminate(), below, after the main loop has completed.
- mInitialized = false;
}
-void Application::OnInit()
+void Application::DoInit()
{
- mFramework->AddAbortCallback( MakeCallback( this, &Application::QuitFromMainLoop ) );
+ // If an application was pre-initialized, a window was made in advance
+ if( mLaunchpadState == Launchpad::NONE )
+ {
+ CreateWindow();
+ }
- CreateWindow();
CreateAdaptor();
// Run the adaptor
mAdaptor->Start();
- // Check if user requires no vsyncing and set on X11 Adaptor
+ // Check if user requires no vsyncing and set Adaptor
if (mCommandLineOptions->noVSyncOnRender)
{
mAdaptor->SetUseHardwareVSync(false);
Internal::Adaptor::Adaptor::GetImplementation( *mAdaptor ).SetViewMode( viewMode );
}
- mInitialized = true;
+ if( ! mStylesheet.empty() )
+ {
+ Dali::StyleMonitor::Get().SetTheme( mStylesheet );
+ }
+}
+
+void Application::DoStart()
+{
+ mAdaptor->NotifySceneCreated();
+}
+
+void Application::DoTerminate()
+{
+ if( mAdaptor )
+ {
+ // Ensure that the render-thread is not using the surface(window) after we delete it
+ mAdaptor->Stop();
+ }
+
+ mWindow.Reset();
+}
+
+void Application::DoPause()
+{
+ mAdaptor->Pause();
+}
+
+void Application::DoResume()
+{
+ mAdaptor->Resume();
+}
+
+void Application::DoLanguageChange()
+{
+ mAdaptor->NotifyLanguageChanged();
+}
+
+void Application::OnInit()
+{
+ DALI_LOG_RELEASE_INFO( "Application::OnInit has started.\n" );
+
+ mFramework->AddAbortCallback( MakeCallback( this, &Application::QuitFromMainLoop ) );
+
+ DoInit();
// Wire up the LifecycleController
Dali::LifecycleController lifecycleController = Dali::LifecycleController::Get();
Dali::Application application(this);
mInitSignal.Emit( application );
- Internal::Adaptor::Adaptor::GetImplementation( *mAdaptor ).GetCore().SceneCreated();
+ DoStart();
+
+ DALI_LOG_RELEASE_INFO( "Application::OnInit has finished.\n" );
}
void Application::OnTerminate()
{
+ DALI_LOG_RELEASE_INFO( "Application::OnTerminate\n" );
+
// we've been told to quit by AppCore, ecore_x_destroy has been called, need to quit synchronously
// delete the window as ecore_x has been destroyed by AppCore
- mWindow.Reset();
- mInitialized = false;
+ Dali::Application application(this);
+ mTerminateSignal.Emit( application );
+
+ DoTerminate();
}
void Application::OnPause()
{
- mAdaptor->Pause();
+ DALI_LOG_RELEASE_INFO( "Application::OnPause has started.\n" );
+
+ // A DALi app should handle Pause/Resume events.
+ // DALi just delivers the framework Pause event to the application, but not actually pause DALi core.
+ // Pausing DALi core only occurs on the Window Hidden framework event
Dali::Application application(this);
mPauseSignal.Emit( application );
+
+ DALI_LOG_RELEASE_INFO( "Application::OnPause has finished.\n" );
}
void Application::OnResume()
{
- mAdaptor->Resume();
+ DALI_LOG_RELEASE_INFO( "Application::OnResume has started.\n" );
+
+ // Emit the signal first so the application can queue any messages before we do an update/render
+ // This ensures we do not just redraw the last frame before pausing if that's not required
Dali::Application application(this);
mResumeSignal.Emit( application );
+
+ // DALi just delivers the framework Resume event to the application.
+ // Resuming DALi core only occurs on the Window Show framework event
+
+ // Trigger processing of events queued up while paused
+ CoreEventInterface& coreEventInterface = Internal::Adaptor::Adaptor::GetImplementation( GetAdaptor() );
+ coreEventInterface.ProcessCoreEvents();
+
+ DALI_LOG_RELEASE_INFO( "Application::OnResume has finished.\n" );
}
void Application::OnReset()
*/
Dali::Application application(this);
mResetSignal.Emit( application );
-
- mWindow.Raise();
}
void Application::OnAppControl(void *data)
{
+ DALI_LOG_RELEASE_INFO( "Application::OnAppControl has started.\n" );
+
Dali::Application application(this);
mAppControlSignal.Emit( application , data );
+
+ DALI_LOG_RELEASE_INFO( "Application::OnAppControl has finished.\n" );
}
void Application::OnLanguageChanged()
{
- mAdaptor->NotifyLanguageChanged();
+ DoLanguageChange();
+ Dali::Application application(this);
+ mLanguageChangedSignal.Emit( application );
}
void Application::OnRegionChanged()
mRegionChangedSignal.Emit( application );
}
-void Application::OnBatteryLow()
+void Application::OnBatteryLow( Dali::DeviceStatus::Battery::Status status )
{
Dali::Application application(this);
mBatteryLowSignal.Emit( application );
+
+ mLowBatterySignal.Emit( status );
}
-void Application::OnMemoryLow()
+void Application::OnMemoryLow( Dali::DeviceStatus::Memory::Status status )
{
Dali::Application application(this);
mMemoryLowSignal.Emit( application );
-}
+ mLowMemorySignal.Emit( status );
+}
void Application::OnResize(Dali::Adaptor& adaptor)
{
Dali::Application application(this);
return mAdaptor->AddIdle( callback );
}
-Dali::Adaptor& Application::GetAdaptor()
+std::string Application::GetRegion() const
{
- return *mAdaptor;
+ return mFramework->GetRegion();
}
-Dali::Window Application::GetWindow()
+std::string Application::GetLanguage() const
{
- return mWindow;
+ return mFramework->GetLanguage();
}
-const std::string& Application::GetTheme()
+Dali::Adaptor& Application::GetAdaptor()
{
- return Dali::StyleMonitor::Get().GetTheme();
+ return *mAdaptor;
}
-void Application::SetTheme(const std::string& themeFilePath)
+Dali::Window Application::GetWindow()
{
- return Dali::StyleMonitor::Get().SetTheme(themeFilePath);
+ return mWindow;
}
// Stereoscopy
}
-void Application::ReplaceWindow(PositionSize windowPosition, const std::string& name)
+void Application::ReplaceWindow( const PositionSize& positionSize, const std::string& name )
{
- Dali::Window newWindow = Dali::Window::New( windowPosition, name, mWindowMode == Dali::Application::TRANSPARENT );
+ Dali::Window newWindow = Dali::Window::New( positionSize, name, mWindowMode == Dali::Application::TRANSPARENT );
Window& windowImpl = GetImplementation(newWindow);
windowImpl.SetAdaptor(*mAdaptor);
- newWindow.ShowIndicator(Dali::Window::INVISIBLE);
+
+ int indicatorVisibleMode = mEnvironmentOptions.GetIndicatorVisibleMode();
+ if( indicatorVisibleMode >= Dali::Window::INVISIBLE && indicatorVisibleMode <= Dali::Window::AUTO )
+ {
+ GetImplementation( newWindow ).SetIndicatorVisibleMode( static_cast< Dali::Window::IndicatorVisibleMode >( indicatorVisibleMode ) );
+ }
+
Dali::RenderSurface* renderSurface = windowImpl.GetSurface();
Any nativeWindow = newWindow.GetNativeHandle();
Internal::Adaptor::Adaptor::GetImplementation( *mAdaptor ).ReplaceSurface(nativeWindow, *renderSurface);
mWindow = newWindow;
+ mWindowPositionSize = positionSize;
+}
+
+std::string Application::GetResourcePath()
+{
+ return Internal::Adaptor::Framework::GetResourcePath();
+}
+
+void Application::SetStyleSheet( const std::string& stylesheet )
+{
+ mStylesheet = stylesheet;
+}
+
+
+ApplicationPtr Application::GetPreInitializedApplication()
+{
+ return gPreInitializedApplication;
}
} // namespace Adaptor