2d3d01061040b588f9486c2f427f7c0d7a503c1a
[platform/core/appfw/app-core.git] / src / multiwindow_base / appcore_multiwindow_base_window.c
1 /*
2  * Copyright (c) 2017 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 <stdio.h>
18 #include <stdarg.h>
19 #include <errno.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <malloc.h>
23 #include <stdbool.h>
24
25 #include <Ecore_Wl2.h>
26 #include <glib-object.h>
27 #include <glib.h>
28 #include <gio/gio.h>
29
30 #include "appcore_base.h"
31 #include "appcore_multiwindow_base.h"
32 #include "appcore_multiwindow_base_private.h"
33
34 typedef struct _win_context {
35         appcore_multiwindow_base_instance_h inst;
36         int win_id;
37 } win_context;
38
39 static GList *__win_contexts;
40 static guint __flush_timer;
41
42 static gint __comp(gconstpointer a, gconstpointer b)
43 {
44         const win_context *cxt = a;
45
46         if (!a || !b)
47                 return -1;
48
49         if (cxt->inst == b)
50                 return 0;
51
52         return -1;
53 }
54
55 static gint __comp_wid(gconstpointer a, gconstpointer b)
56 {
57         int wid = GPOINTER_TO_INT(b);
58         const win_context *cxt = a;
59
60         if (!a || !b)
61                 return -1;
62
63         if (cxt->win_id == wid)
64                 return 0;
65
66         return -1;
67 }
68
69 static win_context *__find_win_context(appcore_multiwindow_base_instance_h h)
70 {
71         GList *node = g_list_find_custom(__win_contexts, h, __comp);
72
73         if (!node)
74                 return NULL;
75
76         return node->data;
77 }
78
79 static win_context *__find_win_context_by_wid(int wid)
80 {
81         GList *node = g_list_find_custom(__win_contexts, GINT_TO_POINTER(wid), __comp_wid);
82
83         if (!node)
84                 return NULL;
85
86         return node->data;
87 }
88
89 static bool __is_resumed(void)
90 {
91         win_context *ctx;
92         GList *iter;
93
94         iter = __win_contexts;
95         while (iter) {
96                 ctx = (win_context *)iter->data;
97                 if (appcore_multiwindow_base_instance_is_resumed(ctx->inst))
98                         return true;
99                 iter = g_list_next(iter);
100         }
101
102         return false;
103 }
104
105 static gboolean __flush_memory(gpointer data)
106 {
107         _DBG("Flush memory");
108         appcore_base_flush_memory();
109         __flush_timer = 0;
110         return G_SOURCE_REMOVE;
111 }
112
113 static void __add_flush_timer(void)
114 {
115         if (__flush_timer)
116                 return;
117
118         __flush_timer = g_timeout_add(5000, __flush_memory, NULL);
119 }
120
121 static void __remove_flush_timer(void)
122 {
123         if (!__flush_timer)
124                 return;
125
126         g_source_remove(__flush_timer);
127         __flush_timer = 0;
128 }
129
130 EXPORT_API void appcore_multiwindow_base_window_on_show(int type, void *event)
131 {
132 }
133
134 EXPORT_API void appcore_multiwindow_base_window_on_hide(int type, void *event)
135 {
136         Ecore_Wl2_Event_Window_Hide *ev = event;
137         win_context *cxt = __find_win_context_by_wid(ev->win);
138
139         if (!cxt)
140                 return;
141
142         __win_contexts = g_list_remove(__win_contexts, cxt);
143         free(cxt);
144 }
145
146 EXPORT_API void appcore_multiwindow_base_window_on_lower(int type, void *event)
147 {
148 }
149
150 EXPORT_API void appcore_multiwindow_base_window_on_visibility(int type, void *event)
151 {
152         Ecore_Wl2_Event_Window_Visibility_Change *ev = event;
153         win_context *cxt = __find_win_context_by_wid(ev->win);
154
155         if (!cxt)
156                 return;
157
158         if (ev->fully_obscured) {
159                 appcore_multiwindow_base_instance_pause(cxt->inst);
160                 if (!__is_resumed())
161                         __add_flush_timer();
162         } else {
163                 appcore_multiwindow_base_instance_resume(cxt->inst);
164                 __remove_flush_timer();
165         }
166 }
167
168 EXPORT_API void appcore_multiwindow_base_window_on_pre_visibility(int type, void *event)
169 {
170         Ecore_Wl2_Event_Window_Pre_Visibility_Change *ev = event;
171         win_context *cxt = __find_win_context_by_wid(ev->win);
172
173         if (!cxt)
174                 return;
175
176         if (ev->type == ECORE_WL2_WINDOW_VISIBILITY_TYPE_PRE_UNOBSCURED) {
177                 appcore_multiwindow_base_instance_resume(cxt->inst);
178                 __remove_flush_timer();
179         }
180 }
181
182 EXPORT_API void appcore_multiwindow_base_window_bind(appcore_multiwindow_base_instance_h h, Ecore_Wl2_Window *wl_win)
183 {
184         win_context *cxt;
185         int id;
186
187         if (!wl_win) {
188                 _ERR("Invalid parameter");
189                 return;
190         }
191
192         cxt = __find_win_context(h);
193         if (cxt) {
194                 _ERR("This instance is already binded");
195                 return;
196         }
197
198         id = ecore_wl2_window_id_get(wl_win);
199
200         cxt = malloc(sizeof(win_context));
201         if (cxt == NULL) {
202                 _ERR("Out of memory");
203                 return;
204         }
205
206         cxt->win_id = id;
207         cxt->inst = h;
208         __win_contexts = g_list_append(__win_contexts, cxt);
209 }
210
211 EXPORT_API void appcore_multiwindow_base_window_unbind(appcore_multiwindow_base_instance_h h)
212 {
213         win_context *cxt;
214
215         cxt = __find_win_context(h);
216         if (!cxt)
217                 return;
218
219         __win_contexts = g_list_remove(__win_contexts, cxt);
220         free(cxt);
221 }
222