Merge "Remove CXX03 Build & old Tizen Version Builds" into devel/master
[platform/core/uifw/dali-adaptor.git] / dali / internal / adaptor / common / application-impl.cpp
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/adaptor/common/application-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23
24 // INTERNAL INCLUDES
25 #include <dali/devel-api/adaptor-framework/style-monitor.h>
26 #include <dali/devel-api/text-abstraction/font-client.h>
27 #include <dali/internal/system/common/command-line-options.h>
28 #include <dali/internal/adaptor/common/framework.h>
29 #include <dali/internal/system/common/singleton-service-impl.h>
30 #include <dali/internal/adaptor/common/lifecycle-controller-impl.h>
31 #include <dali/internal/window-system/common/window-impl.h>
32 #include <dali/internal/window-system/common/window-render-surface.h>
33 #include <dali/internal/window-system/common/render-surface-factory.h>
34
35 // To disable a macro with the same name from one of OpenGL headers
36 #undef Status
37
38 namespace Dali
39 {
40
41 namespace TizenPlatform
42 {
43 class TizenPlatformAbstraction;
44 }
45
46 namespace Integration
47 {
48 class Core;
49 }
50
51 namespace Internal
52 {
53
54 namespace Adaptor
55 {
56
57 namespace
58 {
59
60 const float DEFAULT_STEREO_BASE( 65.0f );
61
62 } // unnamed namespace
63
64 ApplicationPtr Application::gPreInitializedApplication( NULL );
65
66 ApplicationPtr Application::New(
67   int* argc,
68   char **argv[],
69   const std::string& stylesheet,
70   Dali::Application::WINDOW_MODE windowMode,
71   const PositionSize& positionSize,
72   Framework::Type applicationType)
73 {
74   ApplicationPtr application ( new Application (argc, argv, stylesheet, windowMode, positionSize, applicationType ) );
75   return application;
76 }
77
78 void Application::PreInitialize( int* argc, char** argv[] )
79 {
80   if( !gPreInitializedApplication )
81   {
82     gPreInitializedApplication = new Application ( argc, argv, "", Dali::Application::OPAQUE, PositionSize(), Framework::NORMAL );
83
84     gPreInitializedApplication->CreateWindow();    // Only create window
85
86     gPreInitializedApplication->mLaunchpadState = Launchpad::PRE_INITIALIZED;
87
88     //Make DefaultFontDescription cached
89     Dali::TextAbstraction::FontClient fontClient = Dali::TextAbstraction::FontClient::Get();
90     Dali::TextAbstraction::FontDescription defaultFontDescription;
91     fontClient.GetDefaultPlatformFontDescription( defaultFontDescription );
92   }
93 }
94
95 Application::Application( int* argc, char** argv[], const std::string& stylesheet,
96   Dali::Application::WINDOW_MODE windowMode, const PositionSize& positionSize, Framework::Type applicationType )
97 : mInitSignal(),
98   mTerminateSignal(),
99   mPauseSignal(),
100   mResumeSignal(),
101   mResetSignal(),
102   mResizeSignal(),
103   mAppControlSignal(),
104   mLanguageChangedSignal(),
105   mRegionChangedSignal(),
106   mBatteryLowSignal(),
107   mMemoryLowSignal(),
108   mEventLoop( nullptr ),
109   mFramework( nullptr ),
110   mContextLossConfiguration( Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS ),
111   mCommandLineOptions( nullptr ),
112   mSingletonService( SingletonService::New() ),
113   mAdaptorBuilder( nullptr ),
114   mAdaptor( nullptr ),
115   mMainWindow(),
116   mMainWindowMode( windowMode ),
117   mMainWindowName(),
118   mMainWindowReplaced( false ),
119   mStylesheet( stylesheet ),
120   mEnvironmentOptions(),
121   mWindowPositionSize( positionSize ),
122   mLaunchpadState( Launchpad::NONE ),
123   mSlotDelegate( this ),
124   mViewMode( MONO ),
125   mStereoBase( DEFAULT_STEREO_BASE )
126 {
127   // Get mName from environment options
128   mMainWindowName = mEnvironmentOptions.GetWindowName();
129   if( mMainWindowName.empty() && argc && ( *argc > 0 ) )
130   {
131     // Set mName from command-line args if environment option not set
132     mMainWindowName = (*argv)[0];
133   }
134
135   mCommandLineOptions = new CommandLineOptions(argc, argv);
136   mFramework = new Framework( *this, argc, argv, applicationType );
137   mUseRemoteSurface = (applicationType == Framework::WATCH);
138 }
139
140 Application::~Application()
141 {
142   mSingletonService.UnregisterAll();
143
144   mMainWindow.Reset();
145   delete mAdaptor;
146   delete mAdaptorBuilder;
147   delete mCommandLineOptions;
148   delete mFramework;
149 }
150
151 void Application::CreateWindow()
152 {
153   if( mWindowPositionSize.width == 0 && mWindowPositionSize.height == 0 )
154   {
155     if( mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0 )
156     {
157       // Command line options override environment options and full screen
158       mWindowPositionSize.width = mCommandLineOptions->stageWidth;
159       mWindowPositionSize.height = mCommandLineOptions->stageHeight;
160     }
161     else if( mEnvironmentOptions.GetWindowWidth() && mEnvironmentOptions.GetWindowHeight() )
162     {
163       // Environment options override full screen functionality if command line arguments not provided
164       mWindowPositionSize.width = mEnvironmentOptions.GetWindowWidth();
165       mWindowPositionSize.height = mEnvironmentOptions.GetWindowHeight();
166     }
167   }
168
169   const std::string& windowClassName = mEnvironmentOptions.GetWindowClassName();
170
171   Internal::Adaptor::Window* window = Internal::Adaptor::Window::New( mWindowPositionSize, mMainWindowName, windowClassName, mMainWindowMode == Dali::Application::TRANSPARENT );
172   mMainWindow = Dali::Window( window );
173
174   // Quit the application when the window is closed
175   GetImplementation( mMainWindow ).DeleteRequestSignal().Connect( mSlotDelegate, &Application::Quit );
176 }
177
178 void Application::CreateAdaptor()
179 {
180   DALI_ASSERT_ALWAYS( mMainWindow && "Window required to create adaptor" );
181
182   auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
183
184   Integration::SceneHolder sceneHolder = Integration::SceneHolder( &Dali::GetImplementation( mMainWindow ) );
185
186   mAdaptor = Adaptor::New( graphicsFactory, sceneHolder, mContextLossConfiguration, &mEnvironmentOptions );
187
188   mAdaptor->ResizedSignal().Connect( mSlotDelegate, &Application::OnResize );
189
190   Adaptor::GetImplementation( *mAdaptor ).SetUseRemoteSurface( mUseRemoteSurface );
191 }
192
193 void Application::CreateAdaptorBuilder()
194 {
195   mAdaptorBuilder = new AdaptorBuilder();
196 }
197
198 void Application::MainLoop(Dali::Configuration::ContextLoss configuration)
199 {
200   mContextLossConfiguration = configuration;
201
202   // Run the application
203   mFramework->Run();
204 }
205
206 void Application::Lower()
207 {
208   // Lower the application without quitting it.
209   mMainWindow.Lower();
210 }
211
212 void Application::Quit()
213 {
214   // Actually quit the application.
215   // Force a call to Quit even if adaptor is not running.
216   Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).AddIdle( MakeCallback( this, &Application::QuitFromMainLoop ), false, true );
217 }
218
219 void Application::QuitFromMainLoop()
220 {
221   mAdaptor->Stop();
222
223   mFramework->Quit();
224   // This will trigger OnTerminate(), below, after the main loop has completed.
225 }
226
227 void Application::OnInit()
228 {
229   mFramework->AddAbortCallback( MakeCallback( this, &Application::QuitFromMainLoop ) );
230
231   CreateAdaptorBuilder();
232
233   // If an application was pre-initialized, a window was made in advance
234   if( mLaunchpadState == Launchpad::NONE )
235   {
236     CreateWindow();
237   }
238
239   CreateAdaptor();
240
241   // Run the adaptor
242   mAdaptor->Start();
243
244   // Check if user requires no vsyncing and set Adaptor
245   if (mCommandLineOptions->noVSyncOnRender)
246   {
247     mAdaptor->SetUseHardwareVSync(false);
248   }
249
250   if( ! mStylesheet.empty() )
251   {
252     Dali::StyleMonitor::Get().SetTheme( mStylesheet );
253   }
254
255   // Wire up the LifecycleController
256   Dali::LifecycleController lifecycleController = Dali::LifecycleController::Get();
257
258   InitSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnInit );
259   TerminateSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnTerminate );
260   PauseSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnPause );
261   ResumeSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnResume );
262   ResetSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnReset );
263   ResizeSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnResize );
264   LanguageChangedSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnLanguageChanged );
265
266   Dali::Application application(this);
267   mInitSignal.Emit( application );
268
269   mAdaptor->NotifySceneCreated();
270 }
271
272 void Application::OnTerminate()
273 {
274   // We've been told to quit by AppCore, ecore_x_destroy has been called, need to quit synchronously
275   // delete the window as ecore_x has been destroyed by AppCore
276
277   Dali::Application application(this);
278   mTerminateSignal.Emit( application );
279
280   if( mAdaptor )
281   {
282     // Ensure that the render-thread is not using the surface(window) after we delete it
283     mAdaptor->Stop();
284   }
285
286   mMainWindow.Reset(); // This only resets (clears) the default Window
287 }
288
289 void Application::OnPause()
290 {
291   // A DALi app should handle Pause/Resume events.
292   // DALi just delivers the framework Pause event to the application, but not actually pause DALi core.
293   // Pausing DALi core only occurs on the Window Hidden framework event
294   Dali::Application application(this);
295   mPauseSignal.Emit( application );
296 }
297
298 void Application::OnResume()
299 {
300   // Emit the signal first so the application can queue any messages before we do an update/render
301   // This ensures we do not just redraw the last frame before pausing if that's not required
302   Dali::Application application(this);
303   mResumeSignal.Emit( application );
304
305   // DALi just delivers the framework Resume event to the application.
306   // Resuming DALi core only occurs on the Window Show framework event
307
308   // Trigger processing of events queued up while paused
309   CoreEventInterface& coreEventInterface = Internal::Adaptor::Adaptor::GetImplementation( GetAdaptor() );
310   coreEventInterface.ProcessCoreEvents();
311 }
312
313 void Application::OnReset()
314 {
315   /*
316    * usually, reset callback was called when a caller request to launch this application via aul.
317    * because Application class already handled initialization in OnInit(), OnReset do nothing.
318    */
319   Dali::Application application(this);
320   mResetSignal.Emit( application );
321 }
322
323 void Application::OnAppControl(void *data)
324 {
325   Dali::Application application(this);
326   mAppControlSignal.Emit( application , data );
327 }
328
329 void Application::OnLanguageChanged()
330 {
331   mAdaptor->NotifyLanguageChanged();
332   Dali::Application application(this);
333   mLanguageChangedSignal.Emit( application );
334 }
335
336 void Application::OnRegionChanged()
337 {
338   Dali::Application application(this);
339   mRegionChangedSignal.Emit( application );
340 }
341
342 void Application::OnBatteryLow( Dali::DeviceStatus::Battery::Status status )
343 {
344   Dali::Application application(this);
345   mBatteryLowSignal.Emit( application );
346
347   mLowBatterySignal.Emit( status );
348 }
349
350 void Application::OnMemoryLow( Dali::DeviceStatus::Memory::Status status )
351 {
352   Dali::Application application(this);
353   mMemoryLowSignal.Emit( application );
354
355   mLowMemorySignal.Emit( status );
356 }
357
358 void Application::OnResize(Dali::Adaptor& adaptor)
359 {
360   Dali::Application application(this);
361   mResizeSignal.Emit( application );
362 }
363
364 bool Application::AddIdle( CallbackBase* callback, bool hasReturnValue )
365 {
366   return mAdaptor->AddIdle( callback, hasReturnValue );
367 }
368
369 std::string Application::GetRegion() const
370 {
371   return mFramework->GetRegion();
372 }
373
374 std::string Application::GetLanguage() const
375 {
376   return mFramework->GetLanguage();
377 }
378
379 Dali::Adaptor& Application::GetAdaptor()
380 {
381   return *mAdaptor;
382 }
383
384 Dali::Window Application::GetWindow()
385 {
386   // Changed to return a different window handle after ReplaceWindow is called
387   // just for backward compatibility to make the test case pass
388   if ( mMainWindowReplaced )
389   {
390     Internal::Adaptor::Window* window = Internal::Adaptor::Window::New( PositionSize(), "ReplacedWindow", "", false );
391     return Dali::Window( window );
392   }
393   else
394   {
395     return mMainWindow;
396   }
397 }
398
399 // Stereoscopy
400
401 void Application::SetViewMode( ViewMode viewMode )
402 {
403   mViewMode = viewMode;
404 }
405
406 ViewMode Application::GetViewMode() const
407 {
408   return mViewMode;
409 }
410
411 void Application::SetStereoBase( float stereoBase )
412 {
413   mStereoBase = stereoBase;
414 }
415
416 float Application::GetStereoBase() const
417 {
418   return mStereoBase;
419 }
420
421 void Application::ReplaceWindow( const PositionSize& positionSize, const std::string& name )
422 {
423   // This API is kept just for backward compatibility to make the test case pass.
424
425   mMainWindowReplaced = true;
426   OnResize( *mAdaptor );
427 }
428
429 std::string Application::GetResourcePath()
430 {
431   return Internal::Adaptor::Framework::GetResourcePath();
432 }
433
434 std::string Application::GetDataPath()
435 {
436   return Internal::Adaptor::Framework::GetDataPath();
437 }
438
439 void Application::SetStyleSheet( const std::string& stylesheet )
440 {
441   mStylesheet = stylesheet;
442 }
443
444 ApplicationPtr Application::GetPreInitializedApplication()
445 {
446   return gPreInitializedApplication;
447 }
448
449 } // namespace Adaptor
450
451 } // namespace Internal
452
453 } // namespace Dali