[dali_2.0.8] Merge branch 'devel/master'
[platform/core/uifw/dali-adaptor.git] / dali / internal / adaptor / macos / framework-mac.mm
1 /*
2  * Copyright (c) 2020 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 #import <Cocoa/Cocoa.h>
19
20 #include "extern-definitions.h"
21
22 // CLASS HEADER
23 #include <dali/internal/adaptor/common/framework.h>
24
25 // EXTERNAL INCLUDES
26 #include <dali/integration-api/debug.h>
27
28 // INTERNAL INCLUDES
29 #include <dali/internal/system/common/callback-manager.h>
30
31 namespace Dali
32 {
33
34 namespace Internal
35 {
36
37 namespace Adaptor
38 {
39
40 namespace
41 {
42
43 /// Application Status Enum
44 enum
45 {
46   APP_CREATE,
47   APP_TERMINATE,
48   APP_PAUSE,
49   APP_RESUME,
50   APP_RESET,
51   APP_LANGUAGE_CHANGE,
52 };
53
54 } // Unnamed namespace
55
56 /**
57  * Impl to hide WindowsSystem data members
58  */
59 struct Framework::Impl
60 {
61   // Constructor
62
63   Impl(void* data)
64   : mAbortCallBack( nullptr ),
65     mLanguage( "NOT_SUPPORTED" ),
66     mRegion( "NOT_SUPPORTED" )
67   {
68   }
69
70   ~Impl()
71   {
72     delete mAbortCallBack;
73   }
74
75   std::string GetLanguage() const
76   {
77     return mLanguage;
78   }
79
80   std::string GetRegion() const
81   {
82     return mRegion;
83   }
84
85   void SetAbortCallback( CallbackBase *base )
86   {
87     mAbortCallBack = base;
88   }
89
90   bool ExecuteCallback()
91   {
92     if( nullptr != mAbortCallBack )
93     {
94       CallbackBase::Execute( *mAbortCallBack );
95       return true;
96     }
97
98     return false;
99   }
100
101 private:
102   // Undefined
103   Impl( const Impl& impl ) = delete;
104
105   // Undefined
106   Impl& operator=( const Impl& impl ) = delete;
107
108 private:
109   // Data
110   CallbackBase* mAbortCallBack;
111   std::string mLanguage;
112   std::string mRegion;
113 };
114
115 Framework::Framework( Framework::Observer& observer, int *argc, char ***argv, Type type )
116 : mObserver(observer),
117   mInitialised(false),
118   mPaused(false),
119   mRunning(false),
120   mArgc(argc),
121   mArgv(argv),
122   mBundleName(""),
123   mBundleId(""),
124   mAbortHandler( MakeCallback( this, &Framework::AbortCallback ) ),
125   mImpl(NULL)
126 {
127     InitThreads();
128     mImpl = new Impl(this);
129
130     // ensures the NSApp global object is initialized
131     [NSApplication sharedApplication];
132
133     // this is needed for applications without a bundle
134     [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
135
136     // make sure we can become the key window
137     [NSApp activateIgnoringOtherApps:YES];
138 }
139
140 Framework::~Framework()
141 {
142   if (mRunning)
143   {
144     Quit();
145   }
146
147   delete mImpl;
148 }
149
150 void Framework::Run()
151 {
152   mRunning = true;
153   AppStatusHandler(APP_CREATE, nullptr);
154   [NSApp run];
155   mRunning = false;
156 }
157
158 void Framework::Quit()
159 {
160   AppStatusHandler(APP_TERMINATE, nullptr);
161 }
162
163 bool Framework::IsMainLoopRunning()
164 {
165   return mRunning;
166 }
167
168 void Framework::AddAbortCallback( CallbackBase* callback )
169 {
170   mImpl->SetAbortCallback( callback );
171 }
172
173 std::string Framework::GetBundleName() const
174 {
175   return mBundleName;
176 }
177
178 void Framework::SetBundleName(const std::string& name)
179 {
180   mBundleName = name;
181 }
182
183 std::string Framework::GetBundleId() const
184 {
185   return mBundleId;
186 }
187
188 std::string Framework::GetResourcePath()
189 {
190   // "DALI_APPLICATION_PACKAGE" is used by macOS specifically to get the already configured Application package path.
191   const char* macEnvironmentVariable = "DALI_APPLICATION_PACKAGE";
192   char* value = getenv( macEnvironmentVariable );
193
194   std::string resourcePath;
195   if ( value != NULL )
196   {
197     resourcePath = value;
198   }
199
200   if( resourcePath.back() != '/' )
201   {
202     resourcePath+="/";
203   }
204
205   return resourcePath;
206 }
207
208 std::string Framework::GetDataPath()
209 {
210   return app_get_data_path();
211 }
212
213 void Framework::SetBundleId(const std::string& id)
214 {
215   mBundleId = id;
216 }
217
218 void Framework::AbortCallback( )
219 {
220   // if an abort call back has been installed run it.
221   if( false == mImpl->ExecuteCallback() )
222   {
223     Quit();
224   }
225 }
226
227 bool Framework::AppStatusHandler(int type, void *)
228 {
229   switch (type)
230   {
231     case APP_CREATE:
232     {
233       mInitialised = true;
234       mObserver.OnInit();
235       break;
236     }
237
238     case APP_RESET:
239       mObserver.OnReset();
240       break;
241
242     case APP_RESUME:
243       mObserver.OnResume();
244       break;
245
246     case APP_TERMINATE:
247       mObserver.OnTerminate();
248       break;
249
250     case APP_PAUSE:
251       mObserver.OnPause();
252       break;
253
254     case APP_LANGUAGE_CHANGE:
255       mObserver.OnLanguageChanged();
256       break;
257
258     default:
259       break;
260   }
261
262   return true;
263 }
264
265 void Framework::InitThreads()
266 {
267 }
268
269 std::string Framework::GetLanguage() const
270 {
271   return mImpl->GetLanguage();
272 }
273
274 std::string Framework::GetRegion() const
275 {
276   return mImpl->GetRegion();
277 }
278
279 } // namespace Adaptor
280
281 } // namespace Internal
282
283 } // namespace Dali