76681c5d07ba151b40e9a3d8ace1c7a3a536698a
[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 (!bg_state)
448                 __raise_win();
449 }
450
451 EXPORT_API int appcore_ui_base_on_receive(aul_type type, bundle *b)
452 {
453         if (__context.state == AS_DYING) {
454                 _ERR("Skip the event in dying state");
455                 return 0;
456         }
457
458         if (type == AUL_TERMINATE_BGAPP && __context.state != AS_PAUSED)
459                 return 0;
460
461         if (type == AUL_START)
462                 __exit_from_suspend();
463
464         appcore_base_on_receive(type, b);
465
466         switch (type) {
467         case AUL_START:
468                 __do_start(b);
469                 break;
470         case AUL_RESUME:
471                 if (bg_state)
472                         __unset_bg_state();
473                 __raise_win();
474                 break;
475         case AUL_TERMINATE:
476                 break;
477         case AUL_TERMINATE_BGAPP:
478                 _DBG("[APP %d] is paused. TERMINATE", getpid());
479                 __context.state = AS_DYING;
480                 aul_status_update(STATUS_DYING);
481                 if (__context.ops.base.exit)
482                         __context.ops.base.exit(__context.data);
483                 break;
484         case AUL_PAUSE:
485                 __pause_win();
486                 break;
487         default:
488                 break;
489         }
490
491         return 0;
492 }
493
494 EXPORT_API int appcore_ui_base_on_create(void)
495 {
496         appcore_base_on_create();
497
498         __context.hshow = ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_SHOW, __stub_show_cb, NULL);
499         __context.hhide = ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_HIDE, __stub_hide_cb, NULL);
500         __context.hvchange = ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE,
501                                 __stub_visibility_cb, NULL);
502         __context.hlower = ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_LOWER, __stub_lower_cb, NULL);
503         __context.state = AS_CREATED;
504         LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:create:done]", __context.appid);
505
506         return 0;
507 }
508
509 EXPORT_API int appcore_ui_base_on_terminate(void)
510 {
511         if (__context.state == AS_RUNNING) {
512                 if (__context.ops.pause)
513                         __context.ops.pause(__context.data);
514         }
515
516         __context.state = AS_DYING;
517
518         appcore_base_on_terminate();
519
520         return 0;
521 }
522
523 EXPORT_API int appcore_ui_base_on_pause(void)
524 {
525         return 0;
526 }
527
528 EXPORT_API int appcore_ui_base_on_resume(void)
529 {
530         return 0;
531 }
532
533 EXPORT_API int appcore_ui_base_on_control(bundle *b)
534 {
535         LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:reset:start]", __context.appid);
536         appcore_base_on_control(b);
537         LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:reset:done]", __context.appid);
538
539         return 0;
540 }
541
542 static void __group_attach()
543 {
544         if (!(__context.hint & APPCORE_UI_BASE_HINT_WINDOW_GROUP_CONTROL))
545                 return;
546
547         appcore_ui_base_group_add();
548 }
549
550 static void __group_lower()
551 {
552         if (!(__context.hint & APPCORE_UI_BASE_HINT_WINDOW_GROUP_CONTROL))
553                 return;
554         appcore_ui_base_group_remove();
555 }
556
557 EXPORT_API void appcore_ui_base_group_add()
558 {
559         static bool attached = false;
560
561         _DBG("__group_attach");
562         if (attached)
563                 return;
564
565         int wid = __get_main_surface();
566         if (wid == 0) {
567                 _ERR("window wasn't ready");
568                 return;
569         }
570
571         aul_app_group_set_window(wid);
572         attached = true;
573 }
574
575 EXPORT_API void appcore_ui_base_group_remove()
576 {
577         int exit = 0;
578
579         _DBG("__group_lower");
580         aul_app_group_lower(&exit);
581         if (exit) {
582                 _DBG("__group_lower : sub-app!");
583                 if (__context.ops.base.exit)
584                         __context.ops.base.exit(__context.data);
585         }
586 }
587
588 EXPORT_API void appcore_ui_base_window_on_show(int type, void *event)
589 {
590         Ecore_Wl_Event_Window_Show *ev;
591
592         ev = event;
593         if (ev->parent_win != 0) {
594                 /* This is child window. Skip!!! */
595                 return;
596         }
597
598         _DBG("[EVENT_TEST][EVENT] GET SHOW EVENT!!!. WIN:%x, %d\n", ev->win, ev->data[0]);
599
600         if (!__find_win((unsigned int)ev->win))
601                 __add_win((unsigned int)ev->win, (unsigned int)ev->data[0]);
602         else
603                 __update_win((unsigned int)ev->win, (unsigned int)ev->data[0], FALSE);
604
605         if (ev->data[0] != 0)
606                 __group_attach();
607 }
608
609 static bool __check_visible(void)
610 {
611         GSList *iter = NULL;
612         struct win_node *entry = NULL;
613
614         _DBG("[EVENT_TEST][EVENT] __check_visible\n");
615
616         for (iter = g_winnode_list; iter != NULL; iter = g_slist_next(iter)) {
617                 entry = iter->data;
618                 _DBG("win : %x obscured : %d\n", entry->win, entry->bfobscured);
619                 if (entry->bfobscured == FALSE)
620                         return true;
621         }
622
623         return false;
624 }
625
626 EXPORT_API void appcore_ui_base_window_on_hide(int type, void *event)
627 {
628         Ecore_Wl_Event_Window_Hide *ev;
629         int bvisibility;
630
631         ev = event;
632         _DBG("[EVENT_TEST][EVENT] GET HIDE EVENT!!!. WIN:%x\n", ev->win);
633
634         if (__find_win((unsigned int)ev->win)) {
635                 __delete_win((unsigned int)ev->win);
636                 bvisibility = __check_visible();
637                 if (!bvisibility && b_active == TRUE) {
638                         _DBG(" Go to Pasue state \n");
639                         b_active = FALSE;
640                         __do_pause();
641                 }
642         }
643 }
644
645 EXPORT_API void appcore_ui_base_window_on_lower(int type, void *event)
646 {
647         Ecore_Wl_Event_Window_Lower *ev;
648
649         ev = event;
650         if (!ev)
651                 return;
652         _DBG("ECORE_WL_EVENT_WINDOW_LOWER window id:%u\n", ev->win);
653         __group_lower();
654 }
655
656 EXPORT_API void appcore_ui_base_window_on_visibility(int type, void *event)
657 {
658         Ecore_Wl_Event_Window_Visibility_Change *ev;
659         int bvisibility;
660
661         ev = event;
662         __update_win((unsigned int)ev->win, 0, ev->fully_obscured);
663         bvisibility = __check_visible();
664
665         _DBG("bvisibility %d, b_active %d", bvisibility, b_active);
666
667         if (bvisibility && b_active == FALSE) {
668                 _DBG(" Go to Resume state\n");
669                 b_active = TRUE;
670                 __do_resume();
671         } else if (!bvisibility && b_active == TRUE) {
672                 _DBG(" Go to Pasue state \n");
673                 b_active = FALSE;
674                 __do_pause();
675         } else {
676                 _DBG(" No change state \n");
677         }
678
679 }
680
681 EXPORT_API int appcore_ui_base_init(appcore_ui_base_ops ops, int argc, char **argv,
682                 void *data, unsigned int hint)
683 {
684         char *hwacc;
685         const char *bg_launch;
686         bundle *b;
687         char appid[PATH_MAX] = {0, };
688         int r;
689         bool is_vc_vt_automode = false;
690
691         appcore_ui_plugin_init(&ops, &hint);
692         aul_app_get_appid_bypid(getpid(), appid, sizeof(appid));
693         __context.ops = ops;
694         __context.data = data;
695         __context.argc = argc;
696         __context.argv = argv;
697         __context.hint = hint;
698         __context.state = AS_NONE;
699         __context.appid = strdup(appid);
700
701         LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:main:done]", appid);
702         elm_init(argc, argv);
703
704         r = vc_elm_is_supported_vt_auto(&is_vc_vt_automode);
705         if (r != 0) {
706                 _ERR("[VC] Fail to get vconfkey of vt_automode");
707         } else {
708                 if (is_vc_vt_automode == true) {
709                         vc_elm_initialize();
710                         vc_elm_set_auto_register_mode(2, 0);
711                 }
712         }
713
714         if (__context.hint & APPCORE_UI_BASE_HINT_HW_ACC_CONTROL) {
715                 hwacc = getenv("HWACC");
716
717                 if (hwacc == NULL) {
718                         _DBG("elm_config_accel_preference_set is not called");
719                 } else if (strcmp(hwacc, "USE") == 0) {
720                         elm_config_accel_preference_set("hw");
721                         _DBG("elm_config_accel_preference_set : hw");
722                 } else if (strcmp(hwacc, "NOT_USE") == 0) {
723                         elm_config_accel_preference_set("none");
724                         _DBG("elm_config_accel_preference_set : none");
725                 } else {
726                         _DBG("elm_config_accel_preference_set is not called");
727                 }
728         }
729
730         if (__context.hint & APPCORE_UI_BASE_HINT_BG_LAUNCH_CONTROL) {
731                 b = bundle_import_from_argv(argc, argv);
732                 if (b) {
733                         bg_launch = bundle_get_val(b, AUL_SVC_K_BG_LAUNCH);
734                         if (bg_launch && strcmp(bg_launch, "enable") == 0)
735                                 __set_bg_state();
736
737                         bundle_free(b);
738                 }
739         }
740
741         return appcore_base_init(ops.base, argc, argv, data);
742 }
743
744 EXPORT_API void appcore_ui_base_fini(void)
745 {
746         bool is_vc_vt_automode = false;
747         int r;
748
749         appcore_base_fini();
750         appcore_ui_plugin_fini();
751
752         if (__context.hshow)
753                 ecore_event_handler_del(__context.hshow);
754         if (__context.hhide)
755                 ecore_event_handler_del(__context.hhide);
756         if (__context.hvchange)
757                 ecore_event_handler_del(__context.hvchange);
758         if (__context.hlower)
759                 ecore_event_handler_del(__context.hlower);
760
761         __finish_wl();
762
763         r = vc_elm_is_supported_vt_auto(&is_vc_vt_automode);
764         if (r != 0) {
765                 _ERR("[VC] Fail to get vconfkey of vt_automode");
766         } else {
767                 if (is_vc_vt_automode == true)
768                         vc_elm_deinitialize();
769         }
770
771         elm_shutdown();
772
773         /* Check loader case */
774         if (getenv("AUL_LOADER_INIT")) {
775                 unsetenv("AUL_LOADER_INIT");
776                 elm_shutdown();
777         }
778
779         free(__context.appid);
780         __context.appid = NULL;
781 }
782
783 EXPORT_API void appcore_ui_base_pause(void)
784 {
785         __do_pause();
786 }
787
788 EXPORT_API void appcore_ui_base_resume(void)
789 {
790         __do_resume();
791 }
792
793 EXPORT_API bool appcore_ui_base_is_resumed(void)
794 {
795         return __context.state == AS_RUNNING;
796 }
797
798 EXPORT_API void appcore_ui_base_exit(void)
799 {
800         if (__context.ops.base.exit)
801                 __context.ops.base.exit(__context.data);
802 }
803
804 EXPORT_API unsigned int appcore_ui_base_get_main_window(void)
805 {
806         return __get_main_window();
807 }
808
809 EXPORT_API unsigned int appcore_ui_base_get_main_surface(void)
810 {
811         return __get_main_surface();
812 }
813
814 static int __on_receive(aul_type type, bundle *b, void *data)
815 {
816         return appcore_ui_base_on_receive(type, b);
817 }
818
819 static int __on_create(void *data)
820 {
821         return appcore_ui_base_on_create();
822 }
823
824 static int __on_terminate(void *data)
825 {
826         return appcore_ui_base_on_terminate();
827 }
828
829 static int __on_pause(void *data)
830 {
831         return appcore_ui_base_on_pause();
832 }
833
834 static int __on_resume(void *data)
835 {
836         return appcore_ui_base_on_resume();
837 }
838
839 static void __window_on_show(int type, void *event, void *data)
840 {
841         appcore_ui_base_window_on_show(type, event);
842 }
843
844 static void __window_on_hide(int type, void *event, void *data)
845 {
846         appcore_ui_base_window_on_hide(type, event);
847 }
848
849 static void __window_on_lower(int type, void *event, void *data)
850 {
851         appcore_ui_base_window_on_lower(type, event);
852 }
853
854 static void __window_on_visibility(int type, void *event, void *data)
855 {
856         appcore_ui_base_window_on_visibility(type, event);
857 }
858
859 static void __run(void *data)
860 {
861         elm_run();
862 }
863
864 static void __exit(void *data)
865 {
866         elm_exit();
867 }
868
869 EXPORT_API appcore_ui_base_ops appcore_ui_base_get_default_ops(void)
870 {
871         appcore_ui_base_ops ops;
872
873         ops.base = appcore_base_get_default_ops();
874
875         /* override methods */
876         ops.base.create = __on_create;
877         ops.base.terminate = __on_terminate;
878         ops.base.receive = __on_receive;
879         ops.base.run = __run;
880         ops.base.exit = __exit;
881
882         ops.pause = __on_pause;
883         ops.resume = __on_resume;
884         ops.window.show = __window_on_show;
885         ops.window.hide = __window_on_hide;
886         ops.window.lower = __window_on_lower;
887         ops.window.visibility = __window_on_visibility;
888
889         return ops;
890 }
891
892