2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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.
20 #include <Elementary.h>
27 #include <ui-gadget-module.h>
28 #include <ui-gadget.h>
30 #include "image-viewer.h"
32 #define PACKAGE "image-viewer"
33 #define LOCALEDIR "/usr/apps/com.image-viewer/res/locale"
35 #define UG_MODE_SINGLE "SINGLE"
36 #define UG_STANDALONE_VALUE "TRUE"
38 #define UG_BUNDLE_KEY_VIEW_MODE "View Mode"
39 #define UG_BUNDLE_KEY_PATH "Path"
40 #define UG_BUNDLE_KEY_SETAS_TYPE "Setas type"
41 #define UG_BUNDLE_KEY_STANDALONE "Standalone"
43 #define UG_BUNDLE_VALUE_VIEW_MODE_SLIDESHOW "SLIDESHOW"
45 #define SERVICE_OPERATION_CROP "http://tizen.org/appcontrol/operation/crop"
46 #define SERVICE_OPERATION_IMAGE_CROP "http://tizen.org/appcontrol/operation/image/crop"
48 static const char *_conver_error(int err)
52 case SERVICE_ERROR_NONE:
54 case SERVICE_ERROR_INVALID_PARAMETER:
55 return "Invalid parameter";
56 case SERVICE_ERROR_KEY_NOT_FOUND:
57 return "Specified key not found";
58 case SERVICE_ERROR_OUT_OF_MEMORY:
59 return "Out of memory";
60 case SERVICE_ERROR_INVALID_DATA_TYPE:
61 return "Invalid data type";
64 static char error[128];
65 sprintf(error, "Unknow Error : %d(0x%08x)", err, err);
74 static void dump_obj(Evas_Object *obj, int lvl, int max)
76 Eina_List *list = evas_object_smart_members_get(obj);
82 evas_object_geometry_get(obj, &x, &y, &w, &h);
83 Eina_Bool repeat = evas_object_repeat_events_get(obj);
84 Eina_Bool pass = evas_object_pass_events_get(obj);
85 Eina_Bool visible = evas_object_visible_get(obj);
86 Eina_Bool propagate = evas_object_propagate_events_get(obj);
88 IV_MSG_HIGH("Obj=%s(%s,0x%08x) (%d,%d,%d,%d) P%d|R%d|V%d|E%d", evas_object_name_get(obj), evas_object_type_get(obj), obj, x, y, w, h, pass, repeat, visible, propagate);
95 for (l = list, data = (Evas_Object *)eina_list_data_get(l); l; l = eina_list_next(l), data = (Evas_Object *)eina_list_data_get(l))
99 evas_object_geometry_get(data, &x, &y, &w, &h);
100 Eina_Bool repeat = evas_object_repeat_events_get(data);
101 Eina_Bool pass = evas_object_pass_events_get(data);
102 Eina_Bool visible = evas_object_visible_get(data);
103 Eina_Bool propagate = evas_object_propagate_events_get(data);
107 IV_MSG_HIGH("Obj=%s(%s,0x%08x) (%d,%d,%d,%d) P%d|R%d|V%d|E%d", evas_object_name_get(data), evas_object_type_get(data), data, x, y, w, h, pass, repeat, visible, propagate);
111 char *space = (char *)malloc(sizeof(char) * lvl*2+1 );
113 for ( i = 0; i < lvl*2; i++)
120 IV_MSG_HIGH("%sObj=%s(%s,0x%08x) (%d,%d,%d,%d) P%d|R%d|V%d|E%d", space, evas_object_name_get(data), evas_object_type_get(data), data, x, y, w, h, pass, repeat, visible, propagate);
127 dump_obj(data, lvl+1, max);
134 static Eina_Bool _exit_timer_cb(void *data)
136 IV_MSG_HIGH("%s is called", __func__);
138 elm_exit(); // will tirgger app_terminated
140 return ECORE_CALLBACK_CANCEL;
144 _rot_changed_cb(void *data, Evas_Object *obj, void *event)
146 appdata_iv *ap = (appdata_iv *)data;
150 changed_ang = elm_win_rotation_get(obj);
152 IV_MSG_HIGH("Rotation is changed. %d", changed_ang);
154 if (changed_ang != current_ang)
156 current_ang = changed_ang;
157 // Perform an UI update according to the given rotation angle.
158 // Do not call elm_win_rotation_set / elm_win_rotation_with_resize_set.
159 // ecore_evas has already called elm_win_rotation_set / elm_win_rotation_with_resize_set function.
164 enum ug_event evt = UG_EVENT_NONE;
170 evt = UG_EVENT_ROTATE_PORTRAIT;
174 evt = UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN;
179 evt = UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN;
183 evt = UG_EVENT_ROTATE_LANDSCAPE;
187 IV_MSG_ERROR("Unknown rotation degree. %d", changed_ang);
192 ug_send_event( evt );
198 * @brief The win delete function
204 static void _win_del(void *data, Evas_Object *obj, void *event_info)
206 IV_MSG_HIGH("%s is called", __func__);
212 * @brief Create the main window
214 * @param name The title of the window
216 * @return the win on sucess
218 static Evas_Object* _create_win(const char *name)
220 iv_retv_if(name == NULL, NULL);
223 eo = elm_win_add(NULL, name, ELM_WIN_BASIC);
226 elm_win_title_set(eo, name);
227 evas_object_smart_callback_add(eo, "delete,request", _win_del, NULL);
229 ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, &h);
230 IV_MSG_HIGH("x_window_size %d, %d", w, h);
231 evas_object_resize (eo, w, h);
237 Evas_Object* _create_bg(Evas_Object* parent, int r, int g, int b)
239 IV_ASSERT(parent != NULL);
241 Evas_Object *bg = elm_bg_add(parent);
242 evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
243 evas_object_size_hint_align_set(bg, EVAS_HINT_FILL, EVAS_HINT_FILL);
245 elm_win_resize_object_add(parent, bg);
247 elm_bg_color_set(bg, r, g, b);
249 evas_object_show(bg);
255 * @brief The layout callback after ug created
257 * @param ug The ug created
258 * @param mode The UG mode, FULLVIEW or FRAMEVIEW
259 * @param priv The privite data
261 void _ug_layout_cb(ui_gadget_h ug, enum ug_mode mode, void* priv)
263 IV_MSG_HIGH("ug Layout CB. UG=0x%08x Priv=0x%08x Mode=%d", ug, priv, mode);
267 IV_MSG_ERROR("Abnormal value. UG=0x%08x Priv=0x%08x Mode=%d", ug, priv, mode);
271 appdata_iv *ap = (appdata_iv *)priv;
273 Evas_Object *win = ap->win_main;
274 IV_ASSERT(win != NULL);
276 ap->lyClient = ug_get_layout(ug);
278 if (ap->lyClient == NULL)
280 IV_MSG_ERROR( "ug_get_layout is failed");
284 if(ap->lyBase == NULL)
286 ap->lyBase = elm_layout_add(ap->conformant);
288 evas_object_name_set(ap->lyBase, "IV Base");
290 IV_MSG_HIGH("Load edj : %s", PREFIX"/res/edje/iv-main.edj");
291 elm_layout_file_set(ap->lyBase, PREFIX"/res/edje/iv-main.edj", "mainview");
294 elm_object_part_content_set(ap->lyBase, "elm.swallow.content", ap->lyClient);
296 // Set client contents.
300 case UG_MODE_FULLVIEW:
301 ug_disable_effect(ug);
303 elm_win_conformant_set(win, EINA_TRUE);
305 evas_object_size_hint_weight_set(ap->conformant, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
307 elm_object_content_set(ap->conformant, ap->lyBase);
309 elm_win_resize_object_add(win, ap->conformant);
311 evas_object_show(ap->conformant);
313 // dump_obj(ap->conformant, 0, 10);
316 IV_MSG_ERROR("Unknow UG mode : %d", mode);
322 evas_object_del(ap->black_obj);
323 ap->black_obj = NULL;
328 * @brief The return callback on ug send result
330 * @param ug The ug created
331 * @param result The result received from ug
332 * @param priv The privite data
334 void _ug_result_cb(ui_gadget_h ug, service_h reply, void *priv)
336 IV_MSG_HIGH("UG Result CB.");
340 IV_MSG_ERROR("Abnormal value. UG=0x%08x Priv=0x%08x", ug, priv);
344 appdata_iv *ap = (appdata_iv *)priv;
346 int ret = service_reply_to_launch_request(reply, ap->service_handle, SERVICE_RESULT_SUCCEEDED);
347 if (ret != SERVICE_ERROR_NONE)
349 IV_MSG_ERROR("service_reply_to_launch_request failed! [%s]", _conver_error(ret));
354 * @brief The close callback on ug destroy
356 * @param ug The ug created
357 * @param priv The privite data
359 void _ug_destroy_cb(ui_gadget_h ug, void *priv)
361 IV_MSG_HIGH("UG will destroy");
365 IV_MSG_ERROR("Abnormal value. UG=0x%08x Priv=0x%08x", ug, priv);
369 appdata_iv *ap = (appdata_iv *)priv;
373 ug_destroy(ap->iv_ug);
379 // Enable only when find memory leak
380 // ecore_timer_add(0.5, _exit_timer_cb, NULL);
384 * @brief Create the image-viewer-ug
386 * @param data The app data
388 * @return ug on sucess, NULL on fail
390 ui_gadget_h _create_ug(void* data)
392 iv_retv_if(data == NULL, NULL);
394 appdata_iv *ap = (appdata_iv *)data;
397 struct ug_cbs cbs = {0,};
399 cbs.layout_cb = _ug_layout_cb;
400 cbs.result_cb = _ug_result_cb;
401 cbs.destroy_cb = _ug_destroy_cb;
404 IV_MSG_HIGH("UG Create : Begin");
406 ug = ug_create(NULL, "image-viewer-efl", UG_MODE_FULLVIEW, ap->service_handle, &cbs);
408 IV_MSG_HIGH("UG Create : End");
413 static bool _iter_extra_data_cb(service_h service, const char *key, void *user_data)
417 IV_MSG_HIGH(" Key=%s Value=%s", key, value);
419 int ret = service_get_extra_data(service, key, &value);
420 if (ret != SERVICE_ERROR_NONE)
422 IV_MSG_ERROR("service_get_extra_data %s failed, [%s]", key, _conver_error(ret));
432 static bool _app_create(void *user_data)
434 // Hook to take necessary actions before main event loop starts
435 // Initialize UI resources and application's data
436 // If this function returns true, the main loop of application starts
437 // If this function returns false, the application is terminated
438 IV_ASSERT(user_data != NULL);
440 IV_MSG_HIGH("App Create");
442 elm_config_preferred_engine_set("opengl_x11"); //enabling the OpenGL as the backend of the EFL.
444 appdata_iv *ap = (appdata_iv *) user_data;
446 Evas_Object *win = _create_win(PACKAGE);
449 IV_MSG_ERROR("Cannot create app. pkg=%s", PACKAGE);
455 UG_INIT_EFL(ap->win_main, UG_OPT_INDICATOR_ENABLE); // Init UG module
457 if (elm_win_wm_rotation_supported_get(win) == EINA_TRUE)
459 int rots[4] = { 0, 90, 180, 270 };
460 elm_win_wm_rotation_available_rotations_set(win, &rots, 4);
464 IV_MSG_HIGH("Rotation is not supported. ");
467 evas_object_smart_callback_add(win, "wm,rotation,changed", _rot_changed_cb, user_data);
470 ap->conformant = elm_conformant_add(win);
471 evas_object_name_set(ap->conformant, "conformant");
476 static void _app_service(service_h service, void *user_data)
478 // How to get Alarm service????
479 appdata_iv *ap = (appdata_iv *)user_data;
481 IV_MSG_HIGH("%s", __func__);
483 char *operation = NULL;
486 int ret = service_get_operation(service, &operation);
487 if (ret != SERVICE_ERROR_NONE)
489 IV_MSG_ERROR("service_get_operation failed, [%s]", _conver_error(ret));
493 if ( operation == NULL )
495 IV_MSG_ERROR("Operation cannot be NULL.");
499 ret = service_foreach_extra_data(service, _iter_extra_data_cb, NULL);
500 if (ret != SERVICE_ERROR_NONE)
502 IV_MSG_ERROR("service_foreach_extra_data failed, [%s]", _conver_error(ret));
506 ret = service_get_uri(service, &uri);
507 if (ret != SERVICE_ERROR_NONE)
509 IV_MSG_ERROR("service_get_uri failed, [%s]", _conver_error(ret));
513 IV_MSG_HIGH( "Operation=%s URI=%s", operation, uri);
515 ret = service_clone(&ap->service_handle, service);
516 if (ret != SERVICE_ERROR_NONE)
518 IV_MSG_ERROR("service_clone failed, [%s]", _conver_error(ret));
522 if( strcmp(operation, SERVICE_OPERATION_VIEW) == 0 || strcmp(operation, SERVICE_OPERATION_DEFAULT) == 0)
524 if(uri) // uri can entered through argv[1]
526 ap->iv_param_path = uri;
528 if ( ap->iv_param_path == NULL )
530 IV_MSG_ERROR("Entered path is NULL");
534 IV_MSG_HIGH("*****************************");
535 IV_MSG_HIGH("image-viewer : Case View");
536 IV_MSG_HIGH(" URI path : %s", ap->iv_param_path);
537 IV_MSG_HIGH("*****************************");
541 //disable launch effect at slide show
543 service_get_extra_data (service, UG_BUNDLE_KEY_VIEW_MODE, &szMode);
546 if(strncmp(szMode, UG_BUNDLE_VALUE_VIEW_MODE_SLIDESHOW, strlen(UG_BUNDLE_VALUE_VIEW_MODE_SLIDESHOW)) == 0)
548 IV_MSG_HIGH("Disabe effect for slideshow");
549 utilx_set_window_effect_style((Display*)ecore_x_display_get(), elm_win_xwindow_get(ap->win_main),
550 UTILX_EFFECT_TYPE_MAP, UTILX_EFFECT_STYLE_NONE);
551 utilx_set_window_effect_style((Display*)ecore_x_display_get(), elm_win_xwindow_get(ap->win_main),
552 UTILX_EFFECT_TYPE_UNMAP, UTILX_EFFECT_STYLE_NONE);
557 else if( strcmp(operation, SERVICE_OPERATION_CROP) == 0 || strcmp(operation, SERVICE_OPERATION_IMAGE_CROP) == 0)
559 char *value = NULL; // Will freed on terminate
561 if(uri) // uri can entered through argv[1]
563 ap->iv_param_path = uri;
565 if ( ap->iv_param_path == NULL )
567 IV_MSG_ERROR("Entered path is NULL");
571 service_add_extra_data(ap->service_handle, UG_BUNDLE_KEY_VIEW_MODE, "SETAS");
573 service_get_extra_data(ap->service_handle, UG_BUNDLE_KEY_SETAS_TYPE, &value);
576 service_add_extra_data(ap->service_handle, UG_BUNDLE_KEY_SETAS_TYPE, "Crop");
579 IV_MSG_HIGH("*****************************");
580 IV_MSG_HIGH("image-viewer : Case Crop");
581 IV_MSG_HIGH(" URI path : %s", ap->iv_param_path);
582 IV_MSG_HIGH("*****************************");
588 IV_MSG_ERROR("Unknown operation. %s", operation);
591 if ( ap->iv_param_path == NULL )
593 IV_MSG_ERROR("Entered path is NULL");
598 if(ap->iv_param_path == NULL)
600 IV_MSG_ERROR("File path is NULL. cannot create UG");
604 elm_win_activate(ap->win_main);
606 evas_object_show(ap->win_main);
608 if(ap->iv_ug != NULL)
610 // Create Previous UG if exist
611 IV_MSG_HIGH("Removing previous UG=0x%08x", ap->iv_ug);
616 service_add_extra_data(s, "Destroy", "OK");
618 ug_send_message(ap->iv_ug, s);
621 ug_destroy(ap->iv_ug);
625 char *view_mode = NULL;
626 service_get_extra_data(ap->service_handle, UG_BUNDLE_KEY_VIEW_MODE, &view_mode);
627 if(view_mode == NULL)
629 service_add_extra_data(ap->service_handle, UG_BUNDLE_KEY_VIEW_MODE, UG_MODE_SINGLE);
632 service_add_extra_data(ap->service_handle, UG_BUNDLE_KEY_PATH, ap->iv_param_path);
634 service_add_extra_data(ap->service_handle, UG_BUNDLE_KEY_STANDALONE, UG_STANDALONE_VALUE);
636 ap->iv_ug = _create_ug(ap);
637 if(ap->iv_ug == NULL)
639 IV_MSG_HIGH("create_ug failed. Terminated");
647 if(ap->service_handle)
648 service_destroy(ap->service_handle);
649 ap->service_handle = NULL;
656 void _app_pause(void *user_data)
658 // Take necessary actions when application becomes invisible.
659 IV_MSG_HIGH("%s", __func__);
661 appdata_iv *ap = (appdata_iv *)user_data;
663 if(ap->black_obj == NULL)
665 ap->black_obj = evas_object_rectangle_add(evas_object_evas_get(ap->conformant));
666 evas_object_color_set(ap->black_obj, 0, 0, 0, 255); /* black bg */
669 ap->lyBase = elm_object_content_unset(ap->conformant);
671 ap->lyClient = elm_object_part_content_unset(ap->lyBase, "elm.swallow.content");
673 elm_object_part_content_set(ap->lyBase, "elm.swallow.content", ap->black_obj);
674 evas_object_show(ap->black_obj);
676 evas_object_hide(ap->lyClient);
681 void _app_resume(void *user_data)
683 // Take necessary actions when application becomes visible.
684 IV_MSG_HIGH("%s", __func__);
686 appdata_iv *ap = (appdata_iv *)user_data;
688 elm_object_part_content_set(ap->lyBase, "elm.swallow.content", ap->lyClient);
690 elm_object_content_set(ap->conformant, ap->lyBase);
692 evas_object_show(ap->lyClient);
696 evas_object_del(ap->black_obj);
697 ap->black_obj = NULL;
703 void _app_terminate(void *user_data)
705 // Release all resources
706 IV_MSG_HIGH("%s", __func__);
708 appdata_iv *ap = (appdata_iv *)user_data;
712 evas_object_del(ap->black_obj);
713 ap->black_obj = NULL;
716 if(ap->service_handle) {
717 service_destroy(ap->service_handle);
718 ap->service_handle = NULL;
723 ug_destroy(ap->iv_ug);
729 evas_object_del(ap->lyClient);
735 evas_object_del(ap->lyBase);
741 evas_object_del(ap->conformant);
742 ap->conformant = NULL;
745 IV_MSG_HIGH("%s terminated.", __func__);
748 void _region_changed(void *user_data)
750 IV_MSG_HIGH("%s", __func__);
754 void _low_battery(void *user_data)
756 IV_MSG_HIGH("%s", __func__);
757 ug_send_event( UG_EVENT_LOW_BATTERY );
760 void _low_memory(void *user_data)
762 IV_MSG_HIGH("%s", __func__);
763 ug_send_event( UG_EVENT_LOW_MEMORY );
767 void _lang_changed(void *user_data)
769 IV_MSG_HIGH("%s", __func__);
770 ug_send_event( UG_EVENT_LANG_CHANGE );
776 * @brief The main function
778 * @param argc The number of arguments
779 * @param argv[] The arguments
781 * @return 0 on sucess, others on fail
783 int main(int argc, char *argv[])
785 //setenv("ELM_ENGINE", "gl", 1); //changed to elm_config_preferred_engine_set("opengl_x11") at _app_create
787 appdata_iv ad = {0,};
789 app_event_callback_s event_callback = {0,};
791 event_callback.create = _app_create;
792 event_callback.terminate = _app_terminate;
793 event_callback.pause = _app_pause;
794 event_callback.resume = _app_resume;
795 event_callback.service = _app_service;
797 event_callback.low_memory = _low_memory;
798 event_callback.low_battery = _low_battery;
800 // event_callback.device_orientation = _orient_changed;
802 event_callback.language_changed = _lang_changed; /* Currently, Application will terminated when change language */
803 event_callback.region_format_changed = NULL;
805 if ( argc == 2 ) // For command line options.
807 IV_MSG_HIGH("Parsing from cmd line. file=%s", argv[1]);
808 ad.iv_param_path = strdup(argv[1]);
811 int ret = APP_ERROR_NONE;
813 ret = app_efl_main(&argc, &argv, &event_callback, &ad);
815 if ( ret != APP_ERROR_NONE )
817 IV_MSG_ERROR("app_efl_main() is failed. err=%d", ret);