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