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