2 * Copyright (c) 2015 - 2017 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
24 #include <Elementary.h>
25 #include <widget_errno.h>
26 #include <widget_instance.h>
28 #include "widget_base.h"
29 #include "widget_app.h"
30 #include "widget-log.h"
31 #include "widget-private.h"
32 #include "widget_app_internal.h"
38 #define LOG_TAG "CAPI_WIDGET_APPLICATION"
40 struct instance_data {
45 widget_app_lifecycle_callback_s *callback;
49 struct app_class_cb_info {
50 widget_instance_lifecycle_callback_s callback;
54 static GList *__class_data_list;
56 static int __class_resize(widget_base_instance_h instance_h, int w, int h,
60 struct instance_data *data;
61 struct app_class_cb_info *callback_data =
62 (struct app_class_cb_info *)class_data;
64 widget_base_class_on_resize(instance_h, w, h);
65 data = (struct instance_data *)
66 widget_base_context_get_user_data(instance_h);
69 _E("widget_base_context_get_user_data() returns null");
75 evas_object_resize(data->win, w, h);
77 _E("unable to find window");
79 if (callback_data && callback_data->callback.resize) {
80 ret = callback_data->callback.resize(
81 (widget_context_h)instance_h,
82 w, h, callback_data->user_data);
88 static int __class_update(widget_base_instance_h instance_h, bundle *content,
89 int force, void *class_data)
92 struct app_class_cb_info *callback_data =
93 (struct app_class_cb_info *)class_data;
95 widget_base_class_on_update(instance_h, content, force);
96 if (callback_data && callback_data->callback.update) {
97 ret = callback_data->callback.update(
98 (widget_context_h)instance_h,
99 content, force, callback_data->user_data);
105 static int __class_create(widget_base_instance_h instance_h, bundle *content,
106 int w, int h, void *class_data)
109 struct app_class_cb_info *callback_data =
110 (struct app_class_cb_info *)class_data;
112 widget_base_class_on_create(instance_h, content, w, h);
113 if (callback_data && callback_data->callback.create) {
114 ret = callback_data->callback.create(
115 (widget_context_h)instance_h,
116 content, w, h, callback_data->user_data);
121 static int __class_destroy(widget_base_instance_h instance_h,
122 widget_base_destroy_type_e reason, bundle *content,
126 struct instance_data *data;
127 struct app_class_cb_info *callback_data =
128 (struct app_class_cb_info *)class_data;
130 if (callback_data && callback_data->callback.destroy) {
131 ret = callback_data->callback.destroy(
132 (widget_context_h)instance_h,
133 reason, content, callback_data->user_data);
136 data = (struct instance_data *)widget_base_context_get_user_data(instance_h);
138 widget_base_context_set_user_data(instance_h, NULL);
142 widget_base_class_on_destroy(instance_h, reason, content);
147 static int __class_pause(widget_base_instance_h instance_h, void *class_data)
150 struct app_class_cb_info *callback_data =
151 (struct app_class_cb_info *)class_data;
153 widget_base_class_on_pause(instance_h);
154 if (callback_data && callback_data->callback.pause) {
155 ret = callback_data->callback.pause(
156 (widget_context_h)instance_h,
157 callback_data->user_data);
163 static int __class_resume(widget_base_instance_h instance_h, void *class_data)
166 struct app_class_cb_info *callback_data =
167 (struct app_class_cb_info *)class_data;
169 widget_base_class_on_resume(instance_h);
170 if (callback_data && callback_data->callback.resume) {
171 ret = callback_data->callback.resume(
172 (widget_context_h)instance_h,
173 callback_data->user_data);
179 static int __widget_app_create(void *data)
181 struct app_cb_info *cb_info = (struct app_cb_info *)data;
182 widget_app_lifecycle_callback_s *callback;
184 widget_base_on_create();
185 if (cb_info && cb_info->callback && cb_info->callback->create) {
186 callback = cb_info->callback;
187 if (callback->create(cb_info->user_data) == NULL) {
188 _D("fail to create widget");
191 _D("widget app is created");
198 static int __widget_app_terminate(void *data)
200 struct app_cb_info *cb_info = (struct app_cb_info *)data;
201 widget_app_lifecycle_callback_s *callback;
203 if (cb_info && cb_info->callback && cb_info->callback->terminate) {
204 callback = cb_info->callback;
205 callback->terminate(cb_info->user_data);
206 widget_base_on_terminate();
207 _D("widget app is terminated");
212 widget_base_on_terminate();
217 static void __widget_app_init(int argc, char **argv, void *data)
219 elm_init(argc, argv);
222 static void __widget_app_finish(void)
227 static void __widget_app_run(void *data)
232 static void __widget_app_exit(void *data)
237 EXPORT_API int widget_app_main(int argc, char **argv,
238 widget_app_lifecycle_callback_s *callback, void *user_data)
241 struct app_cb_info cb_info;
244 if (argc <= 0 || argv == NULL || callback == NULL)
245 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER,
248 if (callback->create == NULL)
249 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER,
251 "widget_app_create_cb() callback must be "
254 ops.create = __widget_app_create;
255 ops.terminate = __widget_app_terminate;
256 ops.init = __widget_app_init;
257 ops.finish = __widget_app_finish;
258 ops.run = __widget_app_run;
259 ops.exit = __widget_app_exit;
261 cb_info.callback = callback;
262 cb_info.user_data = user_data;
264 r = widget_base_init(ops, argc, argv, &cb_info);
267 if (__class_data_list) {
268 g_list_free_full(__class_data_list, free);
269 __class_data_list = NULL;
275 EXPORT_API int widget_app_exit(void)
277 return widget_base_exit();
280 EXPORT_API int widget_app_terminate_context(widget_context_h context)
282 return widget_base_terminate_context((widget_base_instance_h)context);
285 EXPORT_API int widget_app_foreach_context(widget_context_cb cb, void *data)
287 return widget_base_foreach_context((widget_base_instance_cb)cb, data);
290 EXPORT_API int widget_app_add_event_handler(app_event_handler_h *event_handler,
291 app_event_type_e event_type,
292 app_event_cb callback,
295 return widget_base_add_event_handler(event_handler, event_type,
296 callback, user_data);
299 EXPORT_API int widget_app_remove_event_handler(app_event_handler_h
302 return widget_base_remove_event_handler(event_handler);
305 EXPORT_API const char *widget_app_get_id(widget_context_h context)
311 set_last_result(WIDGET_ERROR_INVALID_PARAMETER);
315 ret = widget_base_context_get_id((widget_base_instance_h)context, &id);
316 if (ret != WIDGET_BASE_ERROR_NONE) {
317 _E("failed to get context id"); /* LCOV_EXCL_LINE */
318 set_last_result(ret); /* LCOV_EXCL_LINE */
319 return NULL; /* LCOV_EXCL_LINE */
322 set_last_result(WIDGET_ERROR_NONE);
326 static void __win_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
329 plug_id = evas_object_data_del(obj, "___PLUGID");
333 EXPORT_API int widget_app_get_elm_win(widget_context_h context,
336 Evas_Object *ret_win = NULL;
337 Ecore_Wl_Window *wl_win;
338 struct instance_data *data;
345 if (context == NULL || win == NULL)
346 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER,
349 ret = widget_base_context_get_id((widget_base_instance_h)context, &id);
350 if (ret != WIDGET_BASE_ERROR_NONE) {
351 _E("failed to get context id"); /* LCOV_EXCL_LINE */
352 goto fault; /* LCOV_EXCL_LINE */
355 ret_win = elm_win_add(NULL, id, ELM_WIN_BASIC);
356 if (ret_win == NULL) {
357 _E("failed to create window"); /* LCOV_EXCL_LINE */
358 goto fault; /* LCOV_EXCL_LINE */
361 elm_win_wm_rotation_preferred_rotation_set(ret_win, -1);
362 elm_win_wm_rotation_available_rotations_set(ret_win, rots, 1);
364 wl_win = elm_win_wl_window_get(ret_win);
365 if (wl_win == NULL) {
366 _E("failed to get wayland window"); /* LCOV_EXCL_LINE */
370 ecore_wl_window_class_name_set(wl_win, id);
371 elm_win_aux_hint_add(ret_win, "wm.policy.win.user.geometry", "1");
372 widget_base_context_window_bind((widget_base_instance_h)context, id, wl_win);
374 /* Set data to use in accessibility */
375 snprintf(buffer, sizeof(buffer), "%s:%d", id, getpid());
376 evas_object_data_set(ret_win, "___PLUGID", strdup(buffer));
377 evas_object_event_callback_add(ret_win, EVAS_CALLBACK_DEL, __win_del_cb, NULL);
379 win_id = ecore_wl_window_id_get(wl_win);
380 _D("window created: %d", win_id);
382 data = (struct instance_data *)widget_base_context_get_user_data(
383 (widget_base_instance_h)context);
385 data = calloc(1, sizeof(struct instance_data));
387 _E("failed to alloc instance_data"); /* LCOV_EXCL_LINE */
388 goto fault; /* LCOV_EXCL_LINE */
391 ret = widget_base_context_set_user_data((widget_base_instance_h)context, data);
392 if (ret != WIDGET_BASE_ERROR_NONE) {
393 _E("fail to set extra data"); /* LCOV_EXCL_LINE */
394 goto fault; /* LCOV_EXCL_LINE */
401 return WIDGET_ERROR_NONE;
404 if (ret_win) /* LCOV_EXCL_LINE */
405 evas_object_del(ret_win); /* LCOV_EXCL_LINE */
407 return WIDGET_ERROR_FAULT; /* LCOV_EXCL_LINE */
410 EXPORT_API widget_class_h widget_app_class_add(widget_class_h widget_class,
411 const char *class_id,
412 widget_instance_lifecycle_callback_s callback, void *user_data)
414 widget_base_class cls;
415 struct app_class_cb_info *callback_data;
418 cls = widget_base_class_get_default();
420 /* override methods */
421 cls.ops.create = __class_create;
422 cls.ops.destroy = __class_destroy;
423 cls.ops.pause = __class_pause;
424 cls.ops.resume = __class_resume;
425 cls.ops.resize = __class_resize;
426 cls.ops.update = __class_update;
428 callback_data = calloc(1, sizeof(struct app_class_cb_info));
429 if (!callback_data) {
430 _E("failed to calloc : %s", __FUNCTION__);
431 set_last_result(WIDGET_ERROR_OUT_OF_MEMORY);
434 callback_data->callback = callback;
435 callback_data->user_data = user_data;
437 wc = (widget_class_h)widget_base_class_add(cls, class_id,
445 __class_data_list = g_list_append(__class_data_list, callback_data);
446 set_last_result(WIDGET_ERROR_NONE);
451 EXPORT_API widget_class_h widget_app_class_create(
452 widget_instance_lifecycle_callback_s callback, void *user_data)
459 LOGE("appid is NULL");
463 wc = (widget_class_h)widget_app_class_add(NULL, appid, callback,
470 EXPORT_API int widget_app_context_set_tag(widget_context_h context, void *tag)
474 ret = widget_base_context_set_tag((widget_base_instance_h)context, tag);
475 if (ret != WIDGET_BASE_ERROR_NONE)
476 return widget_app_error(ret, __FUNCTION__, NULL);
478 return WIDGET_ERROR_NONE;
481 EXPORT_API int widget_app_context_get_tag(widget_context_h context, void **tag)
485 ret = widget_base_context_get_tag((widget_base_instance_h)context, tag);
486 if (ret != WIDGET_BASE_ERROR_NONE)
487 return widget_app_error(ret, __FUNCTION__, NULL);
489 return WIDGET_ERROR_NONE;
492 EXPORT_API int widget_app_context_set_content_info(widget_context_h context,
493 bundle *content_info)
497 ret = widget_base_context_set_content_info(
498 (widget_base_instance_h)context, content_info);
499 if (ret != WIDGET_BASE_ERROR_NONE)
500 return widget_app_error(ret, __FUNCTION__, NULL);
502 return WIDGET_ERROR_NONE;
505 EXPORT_API int widget_app_context_set_title(widget_context_h context,
508 struct instance_data *data = NULL;
511 if (!context || !title) {
512 _E("Invalid parameter %p %p", context, title);
513 return WIDGET_ERROR_INVALID_PARAMETER;
516 data = (struct instance_data *)widget_base_context_get_user_data(
517 (widget_base_instance_h)context);
519 data = calloc(1, sizeof(struct instance_data));
521 return widget_app_error(WIDGET_ERROR_FAULT,
524 ret = widget_base_context_set_user_data(context, data);
525 if (ret != WIDGET_BASE_ERROR_NONE)
526 widget_app_error(ret, __FUNCTION__, NULL);
530 elm_win_title_set(data->win, title);
532 return WIDGET_ERROR_NONE;