Remove CXX03 Build & old Tizen Version Builds
[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   mAdaptor = Dali::Internal::Adaptor::Adaptor::New( graphicsFactory, mMainWindow, mContextLossConfiguration, &mEnvironmentOptions );
185
186   mAdaptor->ResizedSignal().Connect( mSlotDelegate, &Application::OnResize );
187
188   Internal::Adaptor::Adaptor::GetImplementation( *mAdaptor ).SetUseRemoteSurface( mUseRemoteSurface );
189 }
190
191 void Application::CreateAdaptorBuilder()
192 {
193   mAdaptorBuilder = new AdaptorBuilder();
194 }
195
196 void Application::MainLoop(Dali::Configuration::ContextLoss configuration)
197 {
198   mContextLossConfiguration = configuration;
199
200   // Run the application
201   mFramework->Run();
202 }
203
204 void Application::Lower()
205 {
206   // Lower the application without quitting it.
207   mMainWindow.Lower();
208 }
209
210 void Application::Quit()
211 {
212   // Actually quit the application.
213   // Force a call to Quit even if adaptor is not running.
214   Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).AddIdle( MakeCallback( this, &Application::QuitFromMainLoop ), false, true );
215 }
216
217 void Application::QuitFromMainLoop()
218 {
219   mAdaptor->Stop();
220
221   mFramework->Quit();
222   // This will trigger OnTerminate(), below, after the main loop has completed.
223 }
224
225 void Application::OnInit()
226 {
227   mFramework->AddAbortCallback( MakeCallback( this, &Application::QuitFromMainLoop ) );
228
229   CreateAdaptorBuilder();
230
231   // If an application was pre-initialized, a window was made in advance
232   if( mLaunchpadState == Launchpad::NONE )
233   {
234     CreateWindow();
235   }
236
237   CreateAdaptor();
238
239   // Run the adaptor
240   mAdaptor->Start();
241
242   // Check if user requires no vsyncing and set Adaptor
243   if (mCommandLineOptions->noVSyncOnRender)
244   {
245     mAdaptor->SetUseHardwareVSync(false);
246   }
247
248   if( ! mStylesheet.empty() )
249   {
250     Dali::StyleMonitor::Get().SetTheme( mStylesheet );
251   }
252
253   // Wire up the LifecycleController
254   Dali::LifecycleController lifecycleController = Dali::LifecycleController::Get();
255
256   InitSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnInit );
257   TerminateSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnTerminate );
258   PauseSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnPause );
259   ResumeSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnResume );
260   ResetSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnReset );
261   ResizeSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnResize );
262   LanguageChangedSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnLanguageChanged );
263
264   Dali::Application application(this);
265   mInitSignal.Emit( application );
266
267   mAdaptor->NotifySceneCreated();
268 }
269
270 void Application::OnTerminate()
271 {
272   // We've been told to quit by AppCore, ecore_x_destroy has been called, need to quit synchronously
273   // delete the window as ecore_x has been destroyed by AppCore
274
275   Dali::Application application(this);
276   mTerminateSignal.Emit( application );
277
278   if( mAdaptor )
279   {
280     // Ensure that the render-thread is not using the surface(window) after we delete it
281     mAdaptor->Stop();
282   }
283
284   mMainWindow.Reset(); // This only resets (clears) the default Window
285 }
286
287 void Application::OnPause()
288 {
289   // A DALi app should handle Pause/Resume events.
290   // DALi just delivers the framework Pause event to the application, but not actually pause DALi core.
291   // Pausing DALi core only occurs on the Window Hidden framework event
292   Dali::Application application(this);
293   mPauseSignal.Emit( application );
294 }
295
296 void Application::OnResume()
297 {
298   // Emit the signal first so the application can queue any messages before we do an update/render
299   // This ensures we do not just redraw the last frame before pausing if that's not required
300   Dali::Application application(this);
301   mResumeSignal.Emit( application );
302
303   // DALi just delivers the framework Resume event to the application.
304   // Resuming DALi core only occurs on the Window Show framework event
305
306   // Trigger processing of events queued up while paused
307   CoreEventInterface& coreEventInterface = Internal::Adaptor::Adaptor::GetImplementation( GetAdaptor() );
308   coreEventInterface.ProcessCoreEvents();
309 }
310
311 void Application::OnReset()
312 {
313   /*
314    * usually, reset callback was called when a caller request to launch this application via aul.
315    * because Application class already handled initialization in OnInit(), OnReset do nothing.
316    */
317   Dali::Application application(this);
318   mResetSignal.Emit( application );
319 }
320
321 void Application::OnAppControl(void *data)
322 {
323   Dali::Application application(this);
324   mAppControlSignal.Emit( application , data );
325 }
326
327 void Application::OnLanguageChanged()
328 {
329   mAdaptor->NotifyLanguageChanged();
330   Dali::Application application(this);
331   mLanguageChangedSignal.Emit( application );
332 }
333
334 void Application::OnRegionChanged()
335 {
336   Dali::Application application(this);
337   mRegionChangedSignal.Emit( application );
338 }
339
340 void Application::OnBatteryLow( Dali::DeviceStatus::Battery::Status status )
341 {
342   Dali::Application application(this);
343   mBatteryLowSignal.Emit( application );
344
345   mLowBatterySignal.Emit( status );
346 }
347
348 void Application::OnMemoryLow( Dali::DeviceStatus::Memory::Status status )
349 {
350   Dali::Application application(this);
351   mMemoryLowSignal.Emit( application );
352
353   mLowMemorySignal.Emit( status );
354 }
355
356 void Application::OnResize(Dali::Adaptor& adaptor)
357 {
358   Dali::Application application(this);
359   mResizeSignal.Emit( application );
360 }
361
362 bool Application::AddIdle( CallbackBase* callback, bool hasReturnValue )
363 {
364   return mAdaptor->AddIdle( callback, hasReturnValue );
365 }
366
367 std::string Application::GetRegion() const
368 {
369   return mFramework->GetRegion();
370 }
371
372 std::string Application::GetLanguage() const
373 {
374   return mFramework->GetLanguage();
375 }
376
377 Dali::Adaptor& Application::GetAdaptor()
378 {
379   return *mAdaptor;
380 }
381
382 Dali::Window Application::GetWindow()
383 {
384   // Changed to return a different window handle after ReplaceWindow is called
385   // just for backward compatibility to make the test case pass
386   if ( mMainWindowReplaced )
387   {
388     Internal::Adaptor::Window* window = Internal::Adaptor::Window::New( PositionSize(), "ReplacedWindow", "", false );
389     return Dali::Window( window );
390   }
391   else
392   {
393     return mMainWindow;
394   }
395 }
396
397 // Stereoscopy
398
399 void Application::SetViewMode( ViewMode viewMode )
400 {
401   mViewMode = viewMode;
402 }
403
404 ViewMode Application::GetViewMode() const
405 {
406   return mViewMode;
407 }
408
409 void Application::SetStereoBase( float stereoBase )
410 {
411   mStereoBase = stereoBase;
412 }
413
414 float Application::GetStereoBase() const
415 {
416   return mStereoBase;
417 }
418
419 void Application::ReplaceWindow( const PositionSize& positionSize, const std::string& name )
420 {
421   // This API is kept just for backward compatibility to make the test case pass.
422
423   mMainWindowReplaced = true;
424   OnResize( *mAdaptor );
425 }
426
427 std::string Application::GetResourcePath()
428 {
429   return Internal::Adaptor::Framework::GetResourcePath();
430 }
431
432 std::string Application::GetDataPath()
433 {
434   return Internal::Adaptor::Framework::GetDataPath();
435 }
436
437 void Application::SetStyleSheet( const std::string& stylesheet )
438 {
439   mStylesheet = stylesheet;
440 }
441
442 ApplicationPtr Application::GetPreInitializedApplication()
443 {
444   return gPreInitializedApplication;
445 }
446
447 } // namespace Adaptor
448
449 } // namespace Internal
450
451 } // namespace Dali