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