Add ttrace points
[platform/core/appfw/app-core.git] / src / ui_base / appcore_ui_base.c
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
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 #include <sys/types.h>
18 #include <sys/socket.h>
19 #include <sys/un.h>
20 #include <stdio.h>
21 #include <unistd.h>
22 #include <stdarg.h>
23 #include <errno.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <linux/limits.h>
27
28 #include <Ecore_Wayland.h>
29 #include <wayland-client.h>
30 #include <wayland-tbm-client.h>
31 #include <tizen-extension-client-protocol.h>
32
33 #include <Ecore.h>
34 #include <Ecore_Evas.h>
35 #include <Ecore_Input_Evas.h>
36 #include <Elementary.h>
37 #include <glib-object.h>
38 #include <malloc.h>
39 #include <glib.h>
40 #include <gio/gio.h>
41 #include <stdbool.h>
42 #include <aul.h>
43 #include <aul_svc.h>
44 #include <bundle_internal.h>
45 #include <ttrace.h>
46
47 #include "appcore_base.h"
48 #include "appcore_ui_base.h"
49 #include "appcore_ui_base_private.h"
50 #include "appcore_ui_plugin.h"
51
52 enum app_state {
53         AS_NONE,
54         AS_CREATED,
55         AS_RUNNING,
56         AS_PAUSED,
57         AS_DYING,
58 };
59
60 typedef struct _appcore_ui_base_context {
61         appcore_ui_base_ops ops;
62         void *data;
63         int argc;
64         char **argv;
65         unsigned int hint;
66         char *below_app;
67         char *appid;
68
69         int state;
70         Ecore_Event_Handler *hshow;
71         Ecore_Event_Handler *hhide;
72         Ecore_Event_Handler *hvchange;
73         Ecore_Event_Handler *hlower;
74 } appcore_ui_base_context;
75
76
77 static bool b_active = false;
78 static bool first_launch = true;
79
80 struct win_node {
81         unsigned int win;
82         unsigned int surf;
83         bool bfobscured;
84 };
85
86 static GSList *g_winnode_list;
87 static appcore_ui_base_context __context;
88 static struct wl_display *dsp;
89 static struct wl_registry *reg;
90 static struct tizen_policy *tz_policy;
91 static bool bg_state = false;
92
93 static void __wl_listener_cb(void *data, struct wl_registry *reg,
94                 uint32_t id, const char *interface, uint32_t ver)
95 {
96         if (interface && !strcmp(interface, "tizen_policy")) {
97                 if (!tz_policy)
98                         tz_policy = wl_registry_bind(reg, id,
99                                         &tizen_policy_interface, 1);
100         }
101 }
102
103 static void __wl_listener_remove_cb(void *data, struct wl_registry *reg,
104                 unsigned int id)
105 {
106         /* do nothing */
107 }
108
109 static const struct wl_registry_listener reg_listener = {
110         __wl_listener_cb,
111         __wl_listener_remove_cb
112 };
113
114 static Eina_Bool __stub_show_cb(void *data, int type, void *event)
115 {
116         if (__context.ops.window.show)
117                 __context.ops.window.show(type, event, __context.data);
118
119         return ECORE_CALLBACK_RENEW;
120 }
121
122 static Eina_Bool __stub_hide_cb(void *data, int type, void *event)
123 {
124         if (__context.ops.window.hide)
125                 __context.ops.window.hide(type, event, __context.data);
126
127         return ECORE_CALLBACK_RENEW;
128 }
129
130 static Eina_Bool __stub_visibility_cb(void *data, int type, void *event)
131 {
132         if (__context.ops.window.visibility)
133                 __context.ops.window.visibility(type, event, __context.data);
134
135         return ECORE_CALLBACK_RENEW;
136 }
137
138 static Eina_Bool __stub_lower_cb(void *data, int type, void *event)
139 {
140         if (__context.ops.window.lower)
141                 __context.ops.window.lower(type, event, __context.data);
142
143         return ECORE_CALLBACK_RENEW;
144 }
145
146 static void __prepare_to_suspend(void)
147 {
148         int suspend = APPCORE_BASE_SUSPENDED_STATE_WILL_ENTER_SUSPEND;
149
150         if (appcore_base_is_bg_allowed() && !appcore_base_is_suspended()) {
151                 appcore_base_raise_event((void *)&suspend, APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE);
152                 appcore_base_toggle_suspended_state();
153         }
154 }
155
156 static void __exit_from_suspend(void)
157 {
158         int suspend = APPCORE_BASE_SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND;
159
160         if (appcore_base_is_suspended()) {
161                 appcore_base_raise_event((void *)&suspend, APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE);
162                 appcore_base_toggle_suspended_state();
163         }
164 }
165
166 static void __do_pause(void)
167 {
168         if (__context.state == AS_RUNNING) {
169                 if (__context.ops.pause) {
170                         traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:PAUSE");
171                         __context.ops.pause(__context.data);
172                         traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
173                 }
174
175                 __context.state = AS_PAUSED;
176                 __prepare_to_suspend();
177         }
178         aul_status_update(STATUS_BG);
179 }
180
181 static void __do_resume(void)
182 {
183         if (__context.state == AS_PAUSED || __context.state == AS_CREATED) {
184                 __exit_from_suspend();
185                 if (__context.ops.resume) {
186                         LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:resume:start]", __context.appid);
187                         traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:RESUME");
188                         __context.ops.resume(__context.data);
189                         traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
190                         LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:resume:done]", __context.appid);
191                         LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:Launching:done]", __context.appid);
192                 }
193                 if ((__context.hint & APPCORE_UI_BASE_HINT_WINDOW_STACK_CONTROL) &&
194                                 __context.below_app) {
195                         aul_app_group_activate_below(__context.below_app);
196                         free(__context.below_app);
197                         __context.below_app = NULL;
198                 }
199                 __context.state = AS_RUNNING;
200         }
201
202         aul_status_update(STATUS_VISIBLE);
203 }
204
205 static GSList *__find_win(unsigned int win)
206 {
207         GSList *iter;
208         struct win_node *t;
209
210         for (iter = g_winnode_list; iter; iter = g_slist_next(iter)) {
211                 t = iter->data;
212                 if (t && t->win == win)
213                         return iter;
214         }
215
216         return NULL;
217 }
218
219 static int __get_main_window(void)
220 {
221         struct win_node *entry = NULL;
222
223         if (g_winnode_list != NULL) {
224                 entry = g_winnode_list->data;
225                 return (unsigned int) entry->win;
226         }
227
228         return 0;
229 }
230
231 static int __get_main_surface(void)
232 {
233         struct win_node *entry = NULL;
234
235         if (g_winnode_list != NULL) {
236                 entry = g_winnode_list->data;
237                 return (unsigned int) entry->surf;
238         }
239
240         return 0;
241 }
242
243 static bool __add_win(unsigned int win, unsigned int surf)
244 {
245         struct win_node *t;
246         GSList *f;
247
248         _DBG("[EVENT_TEST][EVENT] __add_win WIN:%x\n", win);
249
250         f = __find_win(win);
251         if (f) {
252                 errno = ENOENT;
253                 _DBG("[EVENT_TEST][EVENT] ERROR There is already window : %x \n", win);
254                 return FALSE;
255         }
256
257         t = calloc(1, sizeof(struct win_node));
258         if (t == NULL)
259                 return FALSE;
260
261         t->win = win;
262         t->surf = surf;
263         t->bfobscured = FALSE;
264
265         g_winnode_list = g_slist_append(g_winnode_list, t);
266
267         return TRUE;
268 }
269
270 static bool __delete_win(unsigned int win)
271 {
272         GSList *f;
273
274         f = __find_win(win);
275         if (!f) {
276                 errno = ENOENT;
277                 _DBG("[EVENT_TEST][EVENT] ERROR There is no window : %x \n",
278                                 win);
279                 return FALSE;
280         }
281
282         free(f->data);
283         g_winnode_list = g_slist_delete_link(g_winnode_list, f);
284
285         return TRUE;
286 }
287
288 static bool __update_win(unsigned int win, unsigned int surf, bool bfobscured)
289 {
290         GSList *f;
291         struct win_node *t;
292
293         _DBG("[EVENT_TEST][EVENT] __update_win WIN:%x fully_obscured %d\n", win,
294              bfobscured);
295
296         f = __find_win(win);
297         if (!f) {
298                 errno = ENOENT;
299                 _DBG("[EVENT_TEST][EVENT] ERROR There is no window : %x \n", win);
300                 return FALSE;
301         }
302
303         t = (struct win_node *)f->data;
304         t->win = win;
305         if (surf != 0)
306                 t->surf = surf;
307         t->bfobscured = bfobscured;
308
309         return TRUE;
310 }
311
312 static void __raise_win(void)
313 {
314         Ecore_Wl_Window *win;
315         unsigned int win_id;
316
317         if (!(__context.hint & APPCORE_UI_BASE_HINT_WINDOW_STACK_CONTROL))
318                 return;
319
320         win_id = __get_main_window();
321
322         _DBG("Raise window: %d", win_id);
323         win = ecore_wl_window_find(win_id);
324         ecore_wl_window_activate(win);
325 }
326
327 static void __pause_win(void)
328 {
329         Ecore_Wl_Window *win;
330         GSList *wlist = g_winnode_list;
331         struct win_node *entry = NULL;
332
333         if (!(__context.hint & APPCORE_UI_BASE_HINT_WINDOW_STACK_CONTROL))
334                 return;
335
336         _DBG("Pause window");
337
338         while (wlist) {
339                 entry = wlist->data;
340
341                 _DBG("Pause window: %d", entry->win);
342                 win = ecore_wl_window_find(entry->win);
343                 ecore_wl_window_iconified_set(win, EINA_TRUE);
344
345                 wlist = wlist->next;
346         }
347 }
348
349 static int __init_wl(void)
350 {
351         _DBG("initialize wayland");
352         dsp = wl_display_connect(NULL);
353         if (dsp == NULL) {
354                 _ERR("Failed to connect wl display");
355                 return -1;
356         }
357
358         reg = wl_display_get_registry(dsp);
359         if (reg == NULL) {
360                 _ERR("Failed to get registry");
361                 wl_display_disconnect(dsp);
362                 return -1;
363         }
364
365         wl_registry_add_listener(reg, &reg_listener, NULL);
366         wl_display_roundtrip(dsp);
367
368         if (!tz_policy) {
369                 _ERR("Failed to get tizen policy interface");
370                 wl_registry_destroy(reg);
371                 wl_display_disconnect(dsp);
372                 return -1;
373         }
374
375         return 0;
376 }
377
378 static void __finish_wl(void)
379 {
380         if (tz_policy) {
381                 tizen_policy_destroy(tz_policy);
382                 tz_policy = NULL;
383         }
384
385         if (reg) {
386                 wl_registry_destroy(reg);
387                 reg = NULL;
388         }
389
390         if (dsp) {
391                 wl_display_disconnect(dsp);
392                 dsp = NULL;
393         }
394 }
395
396 static void __set_bg_state(void)
397 {
398         if (!tz_policy && __init_wl() < 0)
399                 return;
400
401         tizen_policy_set_background_state(tz_policy, getpid());
402         wl_display_roundtrip(dsp);
403         bg_state = true;
404         _DBG("bg state: %d", bg_state);
405 }
406
407 static void __unset_bg_state(void)
408 {
409         if (!tz_policy)
410                 return;
411
412         tizen_policy_unset_background_state(tz_policy, getpid());
413         wl_display_roundtrip(dsp);
414         bg_state = false;
415         _DBG("bg state: %d", bg_state);
416 }
417
418 static void __do_start(bundle *b)
419 {
420         const char *bg_launch;
421         const char *below_app;
422
423         if (__context.hint & APPCORE_UI_BASE_HINT_WINDOW_STACK_CONTROL) {
424                 if (__context.below_app) {
425                         free(__context.below_app);
426                         __context.below_app = NULL;
427                 }
428
429                 below_app = bundle_get_val(b, AUL_SVC_K_RELOCATE_BELOW);
430                 if (below_app)
431                         __context.below_app = strdup(below_app);
432         }
433
434         if (first_launch) {
435                 first_launch = FALSE;
436                 return;
437         }
438
439         if (__context.hint & APPCORE_UI_BASE_HINT_BG_LAUNCH_CONTROL) {
440                 bg_launch = bundle_get_val(b, AUL_SVC_K_BG_LAUNCH);
441                 if (bg_launch && strcmp(bg_launch, "enable") == 0) {
442                         if (!bg_state && __context.state != AS_RUNNING)
443                                 __set_bg_state();
444                 } else {
445                         if (bg_state)
446                                 __unset_bg_state();
447                 }
448         }
449
450         if (__context.hint & APPCORE_UI_BASE_HINT_WINDOW_AUTO_CONTROL) {
451                 if (!bg_state)
452                         __raise_win();
453         }
454 }
455
456 EXPORT_API int appcore_ui_base_on_receive(aul_type type, bundle *b)
457 {
458         if (__context.state == AS_DYING) {
459                 _ERR("Skip the event in dying state");
460                 return 0;
461         }
462
463         if (type == AUL_TERMINATE_BGAPP && __context.state != AS_PAUSED)
464                 return 0;
465
466         if (type == AUL_START)
467                 __exit_from_suspend();
468
469         appcore_base_on_receive(type, b);
470
471         switch (type) {
472         case AUL_START:
473                 __do_start(b);
474                 break;
475         case AUL_RESUME:
476                 if (bg_state)
477                         __unset_bg_state();
478                 __raise_win();
479                 break;
480         case AUL_TERMINATE:
481                 break;
482         case AUL_TERMINATE_BGAPP:
483                 _DBG("[APP %d] is paused. TERMINATE", getpid());
484                 __context.state = AS_DYING;
485                 aul_status_update(STATUS_DYING);
486                 if (__context.ops.base.exit)
487                         __context.ops.base.exit(__context.data);
488                 break;
489         case AUL_PAUSE:
490                 __pause_win();
491                 break;
492         default:
493                 break;
494         }
495
496         return 0;
497 }
498
499 EXPORT_API int appcore_ui_base_on_create(void)
500 {
501         appcore_base_on_create();
502
503         __context.hshow = ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_SHOW, __stub_show_cb, NULL);
504         __context.hhide = ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_HIDE, __stub_hide_cb, NULL);
505         __context.hvchange = ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE,
506                                 __stub_visibility_cb, NULL);
507         __context.hlower = ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_LOWER, __stub_lower_cb, NULL);
508         __context.state = AS_CREATED;
509         LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:create:done]", __context.appid);
510
511         return 0;
512 }
513
514 EXPORT_API int appcore_ui_base_on_terminate(void)
515 {
516         if (__context.state == AS_RUNNING) {
517                 if (__context.ops.pause)
518                         __context.ops.pause(__context.data);
519         }
520
521         __context.state = AS_DYING;
522
523         appcore_base_on_terminate();
524
525         return 0;
526 }
527
528 EXPORT_API int appcore_ui_base_on_pause(void)
529 {
530         return 0;
531 }
532
533 EXPORT_API int appcore_ui_base_on_resume(void)
534 {
535         return 0;
536 }
537
538 EXPORT_API int appcore_ui_base_on_control(bundle *b)
539 {
540         LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:reset:start]", __context.appid);
541         appcore_base_on_control(b);
542         LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:reset:done]", __context.appid);
543
544         return 0;
545 }
546
547 static void __group_attach()
548 {
549         if (!(__context.hint & APPCORE_UI_BASE_HINT_WINDOW_GROUP_CONTROL))
550                 return;
551
552         appcore_ui_base_group_add();
553 }
554
555 static void __group_lower()
556 {
557         if (!(__context.hint & APPCORE_UI_BASE_HINT_WINDOW_GROUP_CONTROL))
558                 return;
559         appcore_ui_base_group_remove();
560 }
561
562 EXPORT_API void appcore_ui_base_group_add()
563 {
564         static bool attached = false;
565
566         _DBG("__group_attach");
567         if (attached)
568                 return;
569
570         int wid = __get_main_surface();
571         if (wid == 0) {
572                 _ERR("window wasn't ready");
573                 return;
574         }
575
576         aul_app_group_set_window(wid);
577         attached = true;
578 }
579
580 EXPORT_API void appcore_ui_base_group_remove()
581 {
582         int exit = 0;
583
584         _DBG("__group_lower");
585         aul_app_group_lower(&exit);
586         if (exit) {
587                 _DBG("__group_lower : sub-app!");
588                 if (__context.ops.base.exit)
589                         __context.ops.base.exit(__context.data);
590         }
591 }
592
593 EXPORT_API void appcore_ui_base_window_on_show(int type, void *event)
594 {
595         Ecore_Wl_Event_Window_Show *ev;
596
597         ev = event;
598         if (ev->parent_win != 0) {
599                 /* This is child window. Skip!!! */
600                 return;
601         }
602
603         _DBG("[EVENT_TEST][EVENT] GET SHOW EVENT!!!. WIN:%x, %d\n", ev->win, ev->data[0]);
604
605         if (!__find_win((unsigned int)ev->win))
606                 __add_win((unsigned int)ev->win, (unsigned int)ev->data[0]);
607         else
608                 __update_win((unsigned int)ev->win, (unsigned int)ev->data[0], FALSE);
609
610         if (ev->data[0] != 0)
611                 __group_attach();
612 }
613
614 static bool __check_visible(void)
615 {
616         GSList *iter = NULL;
617         struct win_node *entry = NULL;
618
619         _DBG("[EVENT_TEST][EVENT] __check_visible\n");
620
621         for (iter = g_winnode_list; iter != NULL; iter = g_slist_next(iter)) {
622                 entry = iter->data;
623                 _DBG("win : %x obscured : %d\n", entry->win, entry->bfobscured);
624                 if (entry->bfobscured == FALSE)
625                         return true;
626         }
627
628         return false;
629 }
630
631 EXPORT_API void appcore_ui_base_window_on_hide(int type, void *event)
632 {
633         Ecore_Wl_Event_Window_Hide *ev;
634         int bvisibility;
635
636         ev = event;
637         _DBG("[EVENT_TEST][EVENT] GET HIDE EVENT!!!. WIN:%x\n", ev->win);
638
639         if (__find_win((unsigned int)ev->win)) {
640                 __delete_win((unsigned int)ev->win);
641                 bvisibility = __check_visible();
642                 if (!bvisibility && b_active == TRUE) {
643                         _DBG(" Go to Pasue state \n");
644                         b_active = FALSE;
645                         __do_pause();
646                 }
647         }
648 }
649
650 EXPORT_API void appcore_ui_base_window_on_lower(int type, void *event)
651 {
652         Ecore_Wl_Event_Window_Lower *ev;
653
654         ev = event;
655         if (!ev)
656                 return;
657         _DBG("ECORE_WL_EVENT_WINDOW_LOWER window id:%u\n", ev->win);
658         __group_lower();
659 }
660
661 EXPORT_API void appcore_ui_base_window_on_visibility(int type, void *event)
662 {
663         Ecore_Wl_Event_Window_Visibility_Change *ev;
664         int bvisibility;
665
666         ev = event;
667         __update_win((unsigned int)ev->win, 0, ev->fully_obscured);
668         bvisibility = __check_visible();
669
670         _DBG("bvisibility %d, b_active %d", bvisibility, b_active);
671
672         if (bvisibility && b_active == FALSE) {
673                 _DBG(" Go to Resume state\n");
674                 b_active = TRUE;
675                 __do_resume();
676         } else if (!bvisibility && b_active == TRUE) {
677                 _DBG(" Go to Pasue state \n");
678                 b_active = FALSE;
679                 __do_pause();
680         } else {
681                 _DBG(" No change state \n");
682         }
683
684 }
685
686 EXPORT_API int appcore_ui_base_init(appcore_ui_base_ops ops, int argc, char **argv,
687                 void *data, unsigned int hint)
688 {
689         char *hwacc;
690         const char *bg_launch;
691         bundle *b;
692         char appid[PATH_MAX] = {0, };
693
694         appcore_ui_plugin_init(&ops, &hint);
695         aul_app_get_appid_bypid(getpid(), appid, sizeof(appid));
696         __context.ops = ops;
697         __context.data = data;
698         __context.argc = argc;
699         __context.argv = argv;
700         __context.hint = hint;
701         __context.state = AS_NONE;
702         __context.appid = strdup(appid);
703
704         LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:main:done]", appid);
705         elm_init(argc, argv);
706
707         if (__context.hint & APPCORE_UI_BASE_HINT_HW_ACC_CONTROL) {
708                 hwacc = getenv("HWACC");
709
710                 if (hwacc == NULL) {
711                         _DBG("elm_config_accel_preference_set is not called");
712                 } else if (strcmp(hwacc, "USE") == 0) {
713                         elm_config_accel_preference_set("hw");
714                         _DBG("elm_config_accel_preference_set : hw");
715                 } else if (strcmp(hwacc, "NOT_USE") == 0) {
716                         elm_config_accel_preference_set("none");
717                         _DBG("elm_config_accel_preference_set : none");
718                 } else {
719                         _DBG("elm_config_accel_preference_set is not called");
720                 }
721         }
722
723         if (__context.hint & APPCORE_UI_BASE_HINT_BG_LAUNCH_CONTROL) {
724                 b = bundle_import_from_argv(argc, argv);
725                 if (b) {
726                         bg_launch = bundle_get_val(b, AUL_SVC_K_BG_LAUNCH);
727                         if (bg_launch && strcmp(bg_launch, "enable") == 0)
728                                 __set_bg_state();
729
730                         bundle_free(b);
731                 }
732         }
733
734         return appcore_base_init(ops.base, argc, argv, data);
735 }
736
737 EXPORT_API void appcore_ui_base_fini(void)
738 {
739         appcore_base_fini();
740         appcore_ui_plugin_fini();
741
742         if (__context.hshow)
743                 ecore_event_handler_del(__context.hshow);
744         if (__context.hhide)
745                 ecore_event_handler_del(__context.hhide);
746         if (__context.hvchange)
747                 ecore_event_handler_del(__context.hvchange);
748         if (__context.hlower)
749                 ecore_event_handler_del(__context.hlower);
750
751         __finish_wl();
752         elm_shutdown();
753
754         /* Check loader case */
755         if (getenv("AUL_LOADER_INIT")) {
756                 unsetenv("AUL_LOADER_INIT");
757                 elm_shutdown();
758         }
759
760         free(__context.appid);
761         __context.appid = NULL;
762 }
763
764 EXPORT_API void appcore_ui_base_pause(void)
765 {
766         __do_pause();
767 }
768
769 EXPORT_API void appcore_ui_base_resume(void)
770 {
771         __do_resume();
772 }
773
774 EXPORT_API bool appcore_ui_base_is_resumed(void)
775 {
776         return __context.state == AS_RUNNING;
777 }
778
779 EXPORT_API void appcore_ui_base_exit(void)
780 {
781         if (__context.ops.base.exit)
782                 __context.ops.base.exit(__context.data);
783 }
784
785 EXPORT_API unsigned int appcore_ui_base_get_main_window(void)
786 {
787         return __get_main_window();
788 }
789
790 EXPORT_API unsigned int appcore_ui_base_get_main_surface(void)
791 {
792         return __get_main_surface();
793 }
794
795 static int __on_receive(aul_type type, bundle *b, void *data)
796 {
797         return appcore_ui_base_on_receive(type, b);
798 }
799
800 static int __on_create(void *data)
801 {
802         return appcore_ui_base_on_create();
803 }
804
805 static int __on_terminate(void *data)
806 {
807         return appcore_ui_base_on_terminate();
808 }
809
810 static int __on_pause(void *data)
811 {
812         return appcore_ui_base_on_pause();
813 }
814
815 static int __on_resume(void *data)
816 {
817         return appcore_ui_base_on_resume();
818 }
819
820 static void __window_on_show(int type, void *event, void *data)
821 {
822         appcore_ui_base_window_on_show(type, event);
823 }
824
825 static void __window_on_hide(int type, void *event, void *data)
826 {
827         appcore_ui_base_window_on_hide(type, event);
828 }
829
830 static void __window_on_lower(int type, void *event, void *data)
831 {
832         appcore_ui_base_window_on_lower(type, event);
833 }
834
835 static void __window_on_visibility(int type, void *event, void *data)
836 {
837         appcore_ui_base_window_on_visibility(type, event);
838 }
839
840 static void __run(void *data)
841 {
842         elm_run();
843 }
844
845 static void __exit(void *data)
846 {
847         elm_exit();
848 }
849
850 EXPORT_API appcore_ui_base_ops appcore_ui_base_get_default_ops(void)
851 {
852         appcore_ui_base_ops ops;
853
854         ops.base = appcore_base_get_default_ops();
855
856         /* override methods */
857         ops.base.create = __on_create;
858         ops.base.terminate = __on_terminate;
859         ops.base.receive = __on_receive;
860         ops.base.run = __run;
861         ops.base.exit = __exit;
862
863         ops.pause = __on_pause;
864         ops.resume = __on_resume;
865         ops.window.show = __window_on_show;
866         ops.window.hide = __window_on_hide;
867         ops.window.lower = __window_on_lower;
868         ops.window.visibility = __window_on_visibility;
869
870         return ops;
871 }
872
873