Revert "[Tizen] Temporarily modified so that window is no null"
[platform/core/uifw/dali-adaptor.git] / dali / internal / system / tizen-wayland / widget-application-impl-tizen.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/system/tizen-wayland/widget-application-impl-tizen.h>
20
21 // INTERNAL INCLUDE
22 #include <dali/public-api/adaptor-framework/widget.h>
23 #include <dali/public-api/adaptor-framework/widget-impl.h>
24 #include <dali/internal/adaptor/common/adaptor-impl.h>
25 #include <dali/internal/system/common/environment-variables.h>
26 #include <dali/internal/system/tizen-wayland/widget-controller-tizen.h>
27
28 // EXTERNAL INCLUDES
29 #include <bundle.h>
30 #include <widget_base.h>
31
32 namespace Dali
33 {
34
35 namespace Internal
36 {
37
38 namespace
39 {
40
41 int OnInstanceInit(widget_base_instance_h instanceHandle, bundle *content, int w, int h, void *classData)
42 {
43   char *id;
44   widget_base_context_get_id(instanceHandle, &id);
45
46   widget_base_class_on_create(instanceHandle, content, w, h);
47
48   Dali::Internal::Adaptor::WidgetApplicationTizen* application = static_cast<Dali::Internal::Adaptor::WidgetApplicationTizen*>(classData);
49
50   Dali::Window window;
51   if( application->GetWidgetCount() == 0)
52   {
53     window = application->GetWindow();
54     DALI_LOG_RELEASE_INFO("Widget Instance use default Window(win:%p), so it need to bind widget (%dx%d) (id:%s) \n",window, w, h, std::string(id).c_str());
55   }
56   else
57   {
58     window = Dali::Window::New(PositionSize(0,0,w,h) ,"", false);
59     if( window )
60     {
61       DALI_LOG_RELEASE_INFO("Widget Instance create new Window  (win:%p, cnt:%d) (%dx%d) (id:%s )\n", window, application->GetWidgetCount(), w, h, std::string(id).c_str());
62     }
63     else
64     {
65       DALI_LOG_ERROR("This device can't support Multi Widget. it means UI may not be properly drawn.");
66       window = application->GetWindow();
67     }
68   }
69
70   Any nativeHandle = window.GetNativeHandle();
71
72 #ifdef ECORE_WAYLAND2
73   Ecore_Wl2_Window * wlWindow = AnyCast<Ecore_Wl2_Window*>( nativeHandle );
74 #else
75   Ecore_Wl_Window * wlWindow = AnyCast<Ecore_Wl_Window*>( nativeHandle );
76 #endif
77
78   widget_base_context_window_bind( instanceHandle, id, wlWindow );
79   window.SetSize( Dali::Window::WindowSize( w, h ) );
80
81   Dali::Internal::Adaptor::WidgetApplication::CreateWidgetFunctionPair pair = application->GetWidgetCreatingFunctionPair(std::string(id));
82   Dali::WidgetApplication::CreateWidgetFunction createFunction = pair.second;
83
84   Dali::Widget widgetInstance = createFunction( pair.first );
85   application->AddWidget( instanceHandle, widgetInstance , window );
86
87   Dali::Internal::Adaptor::Widget::Impl *widgetImpl = new Dali::Internal::Adaptor::WidgetImplTizen(instanceHandle);
88   Internal::Adaptor::GetImplementation(widgetInstance).SetImpl( widgetImpl );
89
90   std::string encodedContentString = "";
91
92   if( bundle_get_count( content ) )
93   {
94     bundle_raw *bundleRaw;
95     int len;
96     bundle_encode(content, &bundleRaw, &len);
97     char* encodedContent = reinterpret_cast< char* >( bundleRaw );
98     encodedContentString = std::string( encodedContent );
99     free(bundleRaw);
100   }
101
102   Internal::Adaptor::GetImplementation(widgetInstance).OnCreate( encodedContentString, window );
103
104   return 0;
105 }
106
107 int OnInstanceDestroy(widget_base_instance_h instanceHandle, widget_base_destroy_type_e reason, bundle *content, void *classData)
108 {
109   Dali::Internal::Adaptor::WidgetApplicationTizen* application = static_cast<Dali::Internal::Adaptor::WidgetApplicationTizen*>(classData);
110
111   // Get Dali::Widget instance.
112   Dali::Widget widgetInstance = application->GetWidget( instanceHandle );
113
114   Dali::Widget::Termination destroyReason = Dali::Widget::Termination::TEMPORARY;
115
116   if(reason == WIDGET_BASE_DESTROY_TYPE_PERMANENT)
117   {
118     destroyReason = Dali::Widget::Termination::PERMANENT;
119   }
120
121   std::string encodedContentString = "";
122
123   if( bundle_get_count( content ) )
124   {
125     bundle_raw *bundleRaw;
126     int len;
127     bundle_encode(content, &bundleRaw, &len);
128     char* encodedContent = reinterpret_cast< char* >( bundleRaw );
129     encodedContentString = std::string(encodedContent);
130     free(bundleRaw);
131   }
132
133   Internal::Adaptor::GetImplementation(widgetInstance).OnTerminate( encodedContentString, destroyReason );
134
135   widget_base_class_on_destroy(instanceHandle, reason, content);
136
137   application->DeleteWidget( instanceHandle );
138
139   return 0;
140 }
141
142 int OnInstancePause(widget_base_instance_h instanceHandle, void *classData)
143 {
144   widget_base_class_on_pause(instanceHandle);
145
146   Dali::Internal::Adaptor::WidgetApplicationTizen* application = static_cast<Dali::Internal::Adaptor::WidgetApplicationTizen*>(classData);
147
148   // Get Dali::Widget instance.
149   Dali::Widget widgetInstance = application->GetWidget( instanceHandle );
150
151   Internal::Adaptor::GetImplementation(widgetInstance).OnPause();
152
153   return 0;
154 }
155
156 int OnInstanceResume(widget_base_instance_h instanceHandle, void *classData)
157 {
158   widget_base_class_on_resume(instanceHandle);
159
160   Dali::Internal::Adaptor::WidgetApplicationTizen* application = static_cast<Dali::Internal::Adaptor::WidgetApplicationTizen*>(classData);
161
162   // Get Dali::Widget instance.
163   Dali::Widget widgetInstance = application->GetWidget( instanceHandle );
164
165   Internal::Adaptor::GetImplementation(widgetInstance).OnResume();
166
167   return 0;
168 }
169
170 int OnInstanceResize(widget_base_instance_h instanceHandle, int w, int h, void *classData)
171 {
172   widget_base_class_on_resize(instanceHandle, w, h);
173
174   Dali::Internal::Adaptor::WidgetApplicationTizen* application = static_cast<Dali::Internal::Adaptor::WidgetApplicationTizen*>(classData);
175
176   // Get Dali::Widget instance.
177   Dali::Widget widgetInstance = application->GetWidget( instanceHandle );
178   Dali::Window window = application->GetWindowFromWidget( instanceHandle );
179   window.SetSize( Dali::Window::WindowSize(w, h) );
180   Internal::Adaptor::GetImplementation(widgetInstance).OnResize(window);
181
182   return 0;
183 }
184
185 int OnInstanceUpdate(widget_base_instance_h instanceHandle, bundle *content, int force, void *classData)
186 {
187   widget_base_class_on_update(instanceHandle, content, force);
188
189   Dali::Internal::Adaptor::WidgetApplicationTizen* application = static_cast<Dali::Internal::Adaptor::WidgetApplicationTizen*>(classData);
190
191   // Get Dali::Widget instance.
192   Dali::Widget widgetInstance = application->GetWidget( instanceHandle );
193
194   std::string encodedContentString = "";
195
196   if( bundle_get_count( content ) )
197   {
198     bundle_raw *bundleRaw;
199     int len;
200     bundle_encode(content, &bundleRaw, &len);
201     char* encodedContent = reinterpret_cast< char* >( bundleRaw );
202     encodedContentString = std::string(encodedContent);
203     free(bundleRaw);
204   }
205
206   Internal::Adaptor::GetImplementation(widgetInstance).OnUpdate( encodedContentString, force );
207
208   return 0;
209 }
210
211 unsigned int GetEnvWidgetRenderRefreshRate()
212 {
213   const char* envVariable = std::getenv( DALI_WIDGET_REFRESH_RATE );
214
215   return envVariable ? std::atoi( envVariable ) : 1u; // Default 60 fps
216 }
217
218 } // anonymous namespace
219
220 namespace Adaptor
221 {
222
223 WidgetApplicationPtr WidgetApplicationTizen::New(
224   int* argc,
225   char **argv[],
226   const std::string& stylesheet)
227 {
228   return new WidgetApplicationTizen(argc, argv, stylesheet );
229 }
230
231 WidgetApplicationTizen::WidgetApplicationTizen( int* argc, char** argv[], const std::string& stylesheet )
232 :WidgetApplication(argc, argv, stylesheet)
233 {
234 }
235
236 WidgetApplicationTizen::~WidgetApplicationTizen()
237 {
238 }
239
240
241 void WidgetApplicationTizen::RegisterWidgetCreatingFunction( const std::string& widgetName, Dali::WidgetApplication::CreateWidgetFunction createFunction )
242 {
243   AddWidgetCreatingFunctionPair( CreateWidgetFunctionPair(widgetName, createFunction) );
244
245   // Register widget class to widget framework
246   widget_base_class cls = widget_base_class_get_default();
247   cls.ops.create = OnInstanceInit;
248   cls.ops.destroy = OnInstanceDestroy;
249   cls.ops.pause = OnInstancePause;
250   cls.ops.resume = OnInstanceResume;
251   cls.ops.resize = OnInstanceResize;
252   cls.ops.update = OnInstanceUpdate;
253
254   widget_base_class_add(cls, widgetName.c_str(), this);
255 }
256
257 void WidgetApplicationTizen::AddWidgetCreatingFunctionPair( CreateWidgetFunctionPair pair )
258 {
259   mCreateWidgetFunctionContainer.push_back( pair );
260 }
261
262 WidgetApplicationTizen::CreateWidgetFunctionPair WidgetApplicationTizen::GetWidgetCreatingFunctionPair( const std::string& widgetName )
263 {
264   int idx = widgetName.find(":");
265   std::string widgetID = widgetName.substr( idx + 1 );
266   for( CreateWidgetFunctionContainer::const_iterator iter = mCreateWidgetFunctionContainer.begin(); iter != mCreateWidgetFunctionContainer.end(); ++iter )
267   {
268     if( widgetID.compare((*iter).first) == 0)
269     {
270       return *iter;
271     }
272   }
273
274   return CreateWidgetFunctionPair( "", NULL );
275 }
276
277 void WidgetApplicationTizen::AddWidget( widget_base_instance_h widgetBaseInstance, Dali::Widget widget , Dali::Window window )
278 {
279   mWidgetInstanceContainer.push_back( WidgetInstancePair(widgetBaseInstance, widget) );
280   mWindowInstanceContainer.push_back( WindowInstancePair(widgetBaseInstance, window) );
281 }
282
283 Dali::Widget WidgetApplicationTizen::GetWidget( widget_base_instance_h widgetBaseInstance ) const
284 {
285   for( auto&& iter : mWidgetInstanceContainer )
286   {
287     if( (iter).first == widgetBaseInstance  )
288     {
289       return (iter).second;
290     }
291   }
292   return Dali::Widget();
293 }
294
295 void WidgetApplicationTizen::DeleteWidget( widget_base_instance_h widgetBaseInstance )
296 {
297   // Delete WidgetInstance
298   auto widgetInstance = std::find_if( mWidgetInstanceContainer.begin(),
299                                       mWidgetInstanceContainer.end(),
300                                       [widgetBaseInstance]( WidgetInstancePair pair )
301                                       { return (pair.first == widgetBaseInstance); } );
302
303   if(widgetInstance != mWidgetInstanceContainer.end())
304   {
305     mWidgetInstanceContainer.erase(widgetInstance);
306   }
307
308   // Delete WindowInstance
309   auto windowInstance = std::find_if( mWindowInstanceContainer.begin(),
310                                       mWindowInstanceContainer.end(),
311                                       [widgetBaseInstance]( WindowInstancePair pair )
312                                       { return (pair.first == widgetBaseInstance); } );
313
314   if(windowInstance != mWindowInstanceContainer.end())
315   {
316     mWindowInstanceContainer.erase(windowInstance);
317   }
318 }
319
320 Dali::Window WidgetApplicationTizen::GetWindowFromWidget( widget_base_instance_h widgetBaseInstance ) const
321 {
322   for( auto&& iter : mWindowInstanceContainer )
323   {
324     if( (iter).first == widgetBaseInstance  )
325     {
326       Dali::Window ret = (iter).second;
327       return ret;
328     }
329   }
330   return Dali::Window();
331 }
332
333 int WidgetApplicationTizen::GetWidgetCount()
334 {
335   return mWidgetInstanceContainer.size();
336 }
337
338 void WidgetApplicationTizen::OnInit()
339 {
340   WidgetApplication::OnInit();
341
342   Dali::Adaptor::Get().SetRenderRefreshRate( GetEnvWidgetRenderRefreshRate() );
343 }
344
345 // factory function, must be implemented
346 namespace WidgetApplicationFactory
347 {
348 /**
349  * Create a new widget application
350  * @param[in]  argc         A pointer to the number of arguments
351  * @param[in]  argv         A pointer to the argument list
352  * @param[in]  stylesheet   The path to user defined theme file
353  */
354 Dali::Internal::Adaptor::WidgetApplicationPtr Create( int* argc, char **argv[], const std::string& stylesheet )
355 {
356   return WidgetApplicationTizen::New( argc, argv, stylesheet );
357 }
358
359 } // namespace Factory
360
361 } // namespace Adaptor
362
363 } // namespace Internal
364
365 } // namespace Dali