update license
[apps/core/preloaded/image-viewer.git] / src / image-viewer.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
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
7  *
8  *        http://floralicense.org/license/
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 #include <stdio.h>
18 #include <stdbool.h>
19
20 #include <Elementary.h>
21 #include <app.h>
22
23 #include <utilX.h>
24 #include <Evas.h>
25 #include <Ecore_X.h>
26
27 #include <ui-gadget-module.h>
28 #include <ui-gadget.h>
29
30 #include "image-viewer.h"
31
32 #define PACKAGE "image-viewer"
33 #define LOCALEDIR "/usr/apps/com.image-viewer/res/locale"
34
35 #define UG_MODE_SINGLE "SINGLE"
36 #define UG_STANDALONE_VALUE "TRUE"
37
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"
42
43 #define UG_BUNDLE_VALUE_VIEW_MODE_SLIDESHOW   "SLIDESHOW"
44
45 #define SERVICE_OPERATION_CROP "http://tizen.org/appcontrol/operation/crop"
46 #define SERVICE_OPERATION_IMAGE_CROP "http://tizen.org/appcontrol/operation/image/crop"
47
48 static const char *_conver_error(int err)
49 {
50         switch(err)
51         {
52                 case SERVICE_ERROR_NONE:
53                         return "Successful";
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";
62                 default:
63                 {
64                         static char error[128];
65                         sprintf(error, "Unknow Error : %d(0x%08x)", err, err);
66                         return error;
67                 }
68         }
69         return NULL;
70 }
71
72
73
74 static void dump_obj(Evas_Object *obj, int lvl, int max)
75 {
76         Eina_List *list = evas_object_smart_members_get(obj);
77
78         if ( lvl == 0 )
79         {
80                 int x, y, w, h;
81
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);
87
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);
89                 lvl++;
90         }
91
92         Evas_Object *data;
93         Eina_List *l;
94
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))
96         {
97                 int x, y, w, h;
98
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);
104
105                 if ( lvl == 0 )
106                 {
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);
108                 }
109                 else
110                 {
111                         char *space = (char *)malloc(sizeof(char) * lvl*2+1 );
112                         int i;
113                         for ( i = 0; i < lvl*2; i++)
114                         {
115                                 space[i] = ' ';
116                         }
117
118                         space[lvl*2] = '\0';
119
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);
121
122                         free(space);
123                 }
124
125                 if ( lvl < max )
126                 {
127                         dump_obj(data, lvl+1, max);
128                 }
129
130         }
131 }
132
133
134 static Eina_Bool _exit_timer_cb(void *data)
135 {
136         IV_MSG_HIGH("%s is called", __func__);
137
138         elm_exit();             // will tirgger app_terminated
139
140         return ECORE_CALLBACK_CANCEL;
141 }
142
143 static void
144 _rot_changed_cb(void *data, Evas_Object *obj, void *event)
145 {
146         appdata_iv *ap = (appdata_iv *)data;
147
148         int changed_ang;
149
150         changed_ang = elm_win_rotation_get(obj);
151
152         IV_MSG_HIGH("Rotation is changed. %d", changed_ang);
153 #if 0
154         if (changed_ang != current_ang)
155         {
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.
160         ...
161         }
162 #endif
163         int degree = 0;
164         enum ug_event evt = UG_EVENT_NONE;
165
166         switch(changed_ang)
167         {
168                 case 0:
169                degree = 0;
170                evt = UG_EVENT_ROTATE_PORTRAIT;
171                break;
172                 case 90:
173                degree = 90;
174                evt = UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN;
175                break;
176
177                 case 180:
178                degree = 180;
179                evt = UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN;
180                break;
181
182                 case 270:
183                evt = UG_EVENT_ROTATE_LANDSCAPE;
184                degree = 270;
185                break;
186                 default:
187                         IV_MSG_ERROR("Unknown rotation degree. %d", changed_ang);
188                         return;
189                         break;
190         }
191
192         ug_send_event( evt );
193
194 }
195
196
197 /**
198 * @brief        The win delete function
199 *
200 * @param data
201 * @param obj
202 * @param event_info
203 */
204 static void _win_del(void *data, Evas_Object *obj, void *event_info)
205 {
206         IV_MSG_HIGH("%s is called", __func__);
207         elm_exit();
208 }
209
210
211 /**
212 * @brief        Create the main window
213 *
214 * @param name   The title of the window
215 *
216 * @return  the win on sucess
217 */
218 static Evas_Object* _create_win(const char *name)
219 {
220         iv_retv_if(name == NULL, NULL);
221         Evas_Object *eo;
222
223         eo = elm_win_add(NULL, name, ELM_WIN_BASIC);
224         if (eo)
225         {
226                 elm_win_title_set(eo, name);
227                 evas_object_smart_callback_add(eo, "delete,request", _win_del, NULL);
228                 int w, h;
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);
232         }
233
234         return eo;
235 }
236
237 Evas_Object* _create_bg(Evas_Object* parent, int r, int g, int b)
238 {
239     IV_ASSERT(parent != NULL);
240
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);
244
245         elm_win_resize_object_add(parent, bg);
246
247         elm_bg_color_set(bg, r,  g, b);
248
249         evas_object_show(bg);
250
251         return bg;
252 }
253
254 /**
255 * @brief The layout callback after ug created
256 *
257 * @param ug     The ug created
258 * @param mode   The UG mode, FULLVIEW or FRAMEVIEW
259 * @param priv   The privite data
260 */
261 void _ug_layout_cb(ui_gadget_h ug, enum ug_mode mode, void* priv)
262 {
263         IV_MSG_HIGH("ug Layout CB. UG=0x%08x Priv=0x%08x Mode=%d", ug, priv, mode);
264
265         if (!ug || !priv)
266         {
267                 IV_MSG_ERROR("Abnormal value. UG=0x%08x Priv=0x%08x Mode=%d", ug, priv, mode);
268                 return;
269         }
270
271         appdata_iv *ap = (appdata_iv *)priv;
272
273         Evas_Object *win = ap->win_main;
274         IV_ASSERT(win != NULL);
275
276         ap->lyClient = ug_get_layout(ug);
277
278         if (ap->lyClient == NULL)
279         {
280                 IV_MSG_ERROR( "ug_get_layout is failed");
281                 return;
282         }
283
284         if(ap->lyBase == NULL)
285         {
286                 ap->lyBase = elm_layout_add(ap->conformant);
287
288                 evas_object_name_set(ap->lyBase, "IV Base");
289
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");
292         }
293
294         elm_object_part_content_set(ap->lyBase, "elm.swallow.content", ap->lyClient);
295
296 // Set client contents.
297
298         switch (mode)
299         {
300                 case UG_MODE_FULLVIEW:
301                         ug_disable_effect(ug);
302
303                                 elm_win_conformant_set(win, EINA_TRUE);
304
305                                 evas_object_size_hint_weight_set(ap->conformant, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
306
307                         elm_object_content_set(ap->conformant, ap->lyBase);
308
309                                 elm_win_resize_object_add(win, ap->conformant);
310
311                                 evas_object_show(ap->conformant);
312
313 //                      dump_obj(ap->conformant, 0, 10);
314                         break;
315                 default:
316                         IV_MSG_ERROR("Unknow UG mode : %d", mode);
317                         break;
318         }
319
320         if(ap->black_obj)
321         {
322                 evas_object_del(ap->black_obj);
323                 ap->black_obj = NULL;
324         }
325 }
326
327 /**
328 * @brief        The return callback on ug send result
329 *
330 * @param ug     The ug created
331 * @param result The result received from ug
332 * @param priv   The privite data
333 */
334 void _ug_result_cb(ui_gadget_h ug, service_h reply, void *priv)
335 {
336         IV_MSG_HIGH("UG Result CB.");
337
338         if (!ug || !priv)
339         {
340                 IV_MSG_ERROR("Abnormal value. UG=0x%08x Priv=0x%08x", ug, priv);
341                 return;
342         }
343
344         appdata_iv *ap = (appdata_iv *)priv;
345
346         int ret = service_reply_to_launch_request(reply, ap->service_handle, SERVICE_RESULT_SUCCEEDED);
347         if (ret != SERVICE_ERROR_NONE)
348         {
349                 IV_MSG_ERROR("service_reply_to_launch_request failed! [%s]", _conver_error(ret));
350         }
351 }
352
353 /**
354 * @brief The close callback on ug destroy
355 *
356 * @param ug     The ug created
357 * @param priv   The privite data
358 */
359 void _ug_destroy_cb(ui_gadget_h ug, void *priv)
360 {
361         IV_MSG_HIGH("UG will destroy");
362
363         if (!ug || !priv)
364         {
365                 IV_MSG_ERROR("Abnormal value. UG=0x%08x Priv=0x%08x", ug, priv);
366                 return;
367         }
368
369         appdata_iv *ap = (appdata_iv *)priv;
370
371         if(ap->iv_ug)
372         {
373                 ug_destroy(ap->iv_ug);
374                 ap->iv_ug = NULL;
375         }
376
377         elm_exit();
378
379 // Enable only when find memory leak
380 //      ecore_timer_add(0.5, _exit_timer_cb, NULL);
381 }
382
383 /**
384 * @brief        Create the image-viewer-ug
385 *
386 * @param data   The app data
387 *
388 * @return  ug on sucess, NULL on fail
389 */
390 ui_gadget_h _create_ug(void* data)
391 {
392         iv_retv_if(data == NULL, NULL);
393
394         appdata_iv *ap = (appdata_iv *)data;
395
396         ui_gadget_h ug;
397         struct ug_cbs cbs = {0,};
398
399         cbs.layout_cb = _ug_layout_cb;
400         cbs.result_cb = _ug_result_cb;
401         cbs.destroy_cb = _ug_destroy_cb;
402         cbs.priv = ap;
403
404         IV_MSG_HIGH("UG Create : Begin");
405
406         ug = ug_create(NULL, "image-viewer-efl", UG_MODE_FULLVIEW, ap->service_handle, &cbs);
407
408         IV_MSG_HIGH("UG Create : End");
409         return ug;
410 }
411
412
413 static bool _iter_extra_data_cb(service_h service, const char *key, void *user_data)
414 {
415         char *value = NULL;
416
417         IV_MSG_HIGH("  Key=%s Value=%s", key, value);
418
419         int ret = service_get_extra_data(service, key, &value);
420         if (ret != SERVICE_ERROR_NONE)
421         {
422                 IV_MSG_ERROR("service_get_extra_data %s failed, [%s]", key, _conver_error(ret));
423                 return false;
424         }
425
426         free(value);
427
428         return true;
429 }
430
431
432 static bool _app_create(void *user_data)
433 {
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);
439
440         IV_MSG_HIGH("App Create");
441
442         elm_config_preferred_engine_set("opengl_x11");  //enabling the OpenGL as the backend of the EFL.
443
444         appdata_iv *ap = (appdata_iv *) user_data;
445
446         Evas_Object *win = _create_win(PACKAGE);
447         if ( win == NULL )
448         {
449                 IV_MSG_ERROR("Cannot create app. pkg=%s", PACKAGE);
450                 return false;
451         }
452
453         ap->win_main = win;
454
455         UG_INIT_EFL(ap->win_main, UG_OPT_INDICATOR_ENABLE);     // Init UG module
456
457         if (elm_win_wm_rotation_supported_get(win) == EINA_TRUE)
458         {
459                 int rots[4] = { 0, 90, 180, 270 };
460                 elm_win_wm_rotation_available_rotations_set(win, &rots, 4);
461         }
462         else
463         {
464                 IV_MSG_HIGH("Rotation is not supported. ");
465         }
466
467         evas_object_smart_callback_add(win, "wm,rotation,changed", _rot_changed_cb, user_data);
468
469         //create conformant
470         ap->conformant = elm_conformant_add(win);
471         evas_object_name_set(ap->conformant, "conformant");
472
473         return true;
474 }
475
476 static void _app_service(service_h service, void *user_data)
477 {
478 // How to get Alarm service????
479         appdata_iv *ap = (appdata_iv *)user_data;
480
481         IV_MSG_HIGH("%s", __func__);
482
483         char *operation = NULL;
484         char *uri = NULL;
485
486         int ret = service_get_operation(service, &operation);
487         if (ret != SERVICE_ERROR_NONE)
488         {
489                 IV_MSG_ERROR("service_get_operation failed, [%s]", _conver_error(ret));
490                 goto EXIT;
491         }
492
493         if ( operation == NULL )
494         {
495                 IV_MSG_ERROR("Operation cannot be NULL.");
496                 goto EXIT;
497         }
498
499         ret = service_foreach_extra_data(service, _iter_extra_data_cb, NULL);
500         if (ret != SERVICE_ERROR_NONE)
501         {
502                 IV_MSG_ERROR("service_foreach_extra_data failed, [%s]", _conver_error(ret));
503                 goto EXIT;
504         }
505
506         ret = service_get_uri(service, &uri);
507         if (ret != SERVICE_ERROR_NONE)
508         {
509                 IV_MSG_ERROR("service_get_uri failed, [%s]", _conver_error(ret));
510                 goto EXIT;
511         }
512
513         IV_MSG_HIGH( "Operation=%s URI=%s", operation, uri);
514
515         ret = service_clone(&ap->service_handle, service);
516         if (ret != SERVICE_ERROR_NONE)
517         {
518                 IV_MSG_ERROR("service_clone failed, [%s]", _conver_error(ret));
519                 goto EXIT;
520         }
521
522         if( strcmp(operation, SERVICE_OPERATION_VIEW) == 0 || strcmp(operation, SERVICE_OPERATION_DEFAULT) == 0)
523         {
524                 if(uri) // uri can entered through argv[1]
525                 {
526                         ap->iv_param_path = uri;
527                 }
528                 if ( ap->iv_param_path == NULL )
529                 {
530                         IV_MSG_ERROR("Entered path is NULL");
531                         goto EXIT;
532                 }
533
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("*****************************");
538
539                 free(operation);
540
541                 //disable launch effect at slide show
542                 char* szMode = NULL;
543                 service_get_extra_data (service, UG_BUNDLE_KEY_VIEW_MODE, &szMode);
544                 if (szMode != NULL)
545                 {
546                         if(strncmp(szMode, UG_BUNDLE_VALUE_VIEW_MODE_SLIDESHOW, strlen(UG_BUNDLE_VALUE_VIEW_MODE_SLIDESHOW)) == 0)
547                         {
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);
553                         }
554                         free(szMode);
555                 }
556         }
557         else if( strcmp(operation, SERVICE_OPERATION_CROP) == 0 || strcmp(operation, SERVICE_OPERATION_IMAGE_CROP) == 0)
558         {
559                 char *value = NULL;             // Will freed on terminate
560
561                 if(uri) // uri can entered through argv[1]
562                 {
563                         ap->iv_param_path = uri;
564                 }
565                 if ( ap->iv_param_path == NULL )
566                 {
567                         IV_MSG_ERROR("Entered path is NULL");
568                         goto EXIT;
569                 }
570
571                 service_add_extra_data(ap->service_handle, UG_BUNDLE_KEY_VIEW_MODE, "SETAS");
572
573                 service_get_extra_data(ap->service_handle, UG_BUNDLE_KEY_SETAS_TYPE, &value);
574                 if(value == NULL)
575                 {
576                         service_add_extra_data(ap->service_handle, UG_BUNDLE_KEY_SETAS_TYPE, "Crop");
577                 }
578
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("*****************************");
583
584                 free(operation);
585         }
586         else
587         {
588                 IV_MSG_ERROR("Unknown operation. %s", operation);
589                 free(operation);
590
591                 if ( ap->iv_param_path == NULL )
592                 {
593                         IV_MSG_ERROR("Entered path is NULL");
594                         goto EXIT;
595                 }
596         }
597
598         if(ap->iv_param_path == NULL)
599         {
600                 IV_MSG_ERROR("File path is NULL. cannot create UG");
601                 goto EXIT;
602         }
603
604         elm_win_activate(ap->win_main);
605
606         evas_object_show(ap->win_main);
607
608         if(ap->iv_ug != NULL)
609         {
610                 // Create Previous UG if exist
611                 IV_MSG_HIGH("Removing previous UG=0x%08x", ap->iv_ug);
612
613                 service_h s = NULL;
614                 service_create(&s);
615
616                 service_add_extra_data(s, "Destroy", "OK");
617
618                 ug_send_message(ap->iv_ug, s);
619                 service_destroy(s);
620
621                 ug_destroy(ap->iv_ug);
622                 ap->iv_ug = NULL;
623         }
624
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)
628         {
629                 service_add_extra_data(ap->service_handle, UG_BUNDLE_KEY_VIEW_MODE, UG_MODE_SINGLE);
630         }
631
632         service_add_extra_data(ap->service_handle, UG_BUNDLE_KEY_PATH, ap->iv_param_path);
633
634         service_add_extra_data(ap->service_handle, UG_BUNDLE_KEY_STANDALONE, UG_STANDALONE_VALUE);
635
636         ap->iv_ug = _create_ug(ap);
637         if(ap->iv_ug == NULL)
638         {
639                 IV_MSG_HIGH("create_ug failed. Terminated");
640                 elm_exit();
641                 return;
642         }
643
644         return;
645
646 EXIT:
647         if(ap->service_handle)
648                 service_destroy(ap->service_handle);
649         ap->service_handle = NULL;
650         elm_exit();
651         return;
652
653 }
654
655
656 void _app_pause(void *user_data)
657 {
658 // Take necessary actions when application becomes invisible.
659         IV_MSG_HIGH("%s", __func__);
660
661         appdata_iv *ap = (appdata_iv *)user_data;
662
663         if(ap->black_obj == NULL)
664         {
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 */
667         }
668
669         ap->lyBase = elm_object_content_unset(ap->conformant);
670
671         ap->lyClient = elm_object_part_content_unset(ap->lyBase, "elm.swallow.content");
672
673         elm_object_part_content_set(ap->lyBase, "elm.swallow.content", ap->black_obj);
674         evas_object_show(ap->black_obj);
675
676         evas_object_hide(ap->lyClient);
677
678         ug_pause();
679 }
680
681 void _app_resume(void *user_data)
682 {
683 // Take necessary actions when application becomes visible.
684         IV_MSG_HIGH("%s", __func__);
685
686         appdata_iv *ap = (appdata_iv *)user_data;
687
688         elm_object_part_content_set(ap->lyBase, "elm.swallow.content", ap->lyClient);
689
690         elm_object_content_set(ap->conformant, ap->lyBase);
691
692         evas_object_show(ap->lyClient);
693
694         if(ap->black_obj)
695         {
696                 evas_object_del(ap->black_obj);
697                 ap->black_obj = NULL;
698         }
699
700         ug_resume();
701 }
702
703 void _app_terminate(void *user_data)
704 {
705 // Release all resources
706         IV_MSG_HIGH("%s", __func__);
707
708         appdata_iv *ap = (appdata_iv *)user_data;
709
710         if(ap->black_obj)
711         {
712                 evas_object_del(ap->black_obj);
713                 ap->black_obj = NULL;
714         }
715
716         if(ap->service_handle) {
717                 service_destroy(ap->service_handle);
718                 ap->service_handle = NULL;
719         }
720
721         if(ap->iv_ug)
722         {
723                 ug_destroy(ap->iv_ug);
724                 ap->iv_ug = NULL;
725         }
726
727         if(ap->lyClient)
728         {
729                 evas_object_del(ap->lyClient);
730                 ap->lyClient = NULL;
731         }
732
733         if(ap->lyBase)
734         {
735                 evas_object_del(ap->lyBase);
736                 ap->lyBase = NULL;
737         }
738
739         if(ap->conformant)
740         {
741                 evas_object_del(ap->conformant);
742                 ap->conformant = NULL;
743         }
744
745         IV_MSG_HIGH("%s terminated.", __func__);
746 }
747
748 void _region_changed(void *user_data)
749 {
750         IV_MSG_HIGH("%s", __func__);
751         // Not used yet.
752 }
753
754 void _low_battery(void *user_data)
755 {
756         IV_MSG_HIGH("%s", __func__);
757         ug_send_event( UG_EVENT_LOW_BATTERY );
758 }
759
760 void _low_memory(void *user_data)
761 {
762         IV_MSG_HIGH("%s", __func__);
763         ug_send_event( UG_EVENT_LOW_MEMORY );
764
765 }
766
767 void _lang_changed(void *user_data)
768 {
769         IV_MSG_HIGH("%s", __func__);
770         ug_send_event( UG_EVENT_LANG_CHANGE );
771
772 }
773
774
775 /**
776 * @brief The main function
777 *
778 * @param argc   The number of arguments
779 * @param argv[] The arguments
780 *
781 * @return 0 on sucess, others on fail
782 */
783 int main(int argc, char *argv[])
784 {
785         //setenv("ELM_ENGINE", "gl", 1); //changed to elm_config_preferred_engine_set("opengl_x11") at _app_create
786
787         appdata_iv ad = {0,};
788
789         app_event_callback_s event_callback = {0,};
790
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;
796
797         event_callback.low_memory = _low_memory;
798         event_callback.low_battery = _low_battery;
799
800 //      event_callback.device_orientation = _orient_changed;
801
802         event_callback.language_changed = _lang_changed;                /* Currently, Application will terminated when change language */
803         event_callback.region_format_changed = NULL;
804
805         if ( argc == 2 )                // For command line options.
806         {
807                 IV_MSG_HIGH("Parsing from cmd line. file=%s", argv[1]);
808                 ad.iv_param_path = strdup(argv[1]);
809         }
810
811         int ret = APP_ERROR_NONE;
812
813         ret = app_efl_main(&argc, &argv, &event_callback, &ad);
814
815         if ( ret != APP_ERROR_NONE )
816         {
817                 IV_MSG_ERROR("app_efl_main() is failed. err=%d", ret);
818                 // Go through
819         }
820
821         return ret;
822
823 }
824