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