Fix duplicate instance creation
[platform/core/appfw/app-core.git] / src / multiwindow_base / appcore_multiwindow_base_instance.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 <string.h>
20 #include <stdlib.h>
21 #include <stdbool.h>
22 #include <malloc.h>
23
24 #include <glib-object.h>
25 #include <glib.h>
26 #include <gio/gio.h>
27
28 #include "appcore_base.h"
29 #include "appcore_multiwindow_base.h"
30 #include "appcore_multiwindow_base_private.h"
31
32 extern appcore_multiwindow_base_context _appcore_mw_context;
33
34 static gint __comp(gconstpointer a, gconstpointer b)
35 {
36         const appcore_multiwindow_base_class *cls = a;
37
38         return strcmp(cls->id, b);
39 }
40
41 EXPORT_API appcore_multiwindow_base_instance_h appcore_multiwindow_base_instance_run(const char *class_id, const char *id, void *extra)
42 {
43         appcore_multiwindow_base_instance *inst;
44         GList * class_node = g_list_find_custom(_appcore_mw_context.classes, class_id, __comp);
45
46         if (!class_node)
47                 return NULL;
48
49         if (appcore_multiwindow_base_instance_find(id)) {
50                 _ERR("alread exist");
51                 return NULL;
52         }
53
54         inst = malloc(sizeof(appcore_multiwindow_base_instance));
55         if (!inst)
56                 return NULL;
57
58         inst->shell = class_node->data;
59         inst->window_id = 0;
60         inst->id = strdup(id);
61         inst->extra = extra;
62         inst->is_resumed = false;
63
64         _appcore_mw_context.instances = g_list_append(_appcore_mw_context.instances, inst);
65         if (inst->shell->create)
66                 inst->shell->create(inst, inst->shell->data);
67
68         return inst;
69 }
70
71 EXPORT_API void appcore_multiwindow_base_instance_exit(appcore_multiwindow_base_instance_h context)
72 {
73         appcore_multiwindow_base_instance *inst = context;
74
75         appcore_multiwindow_base_instance_pause(inst);
76         if (inst->shell->terminate)
77                 inst->shell->terminate(inst, inst->shell->data);
78
79         _appcore_mw_context.instances = g_list_remove(_appcore_mw_context.instances, inst);
80         free(inst->id);
81         free(inst);
82 }
83
84 EXPORT_API void appcore_multiwindow_base_instance_drop(appcore_multiwindow_base_instance_h context)
85 {
86         appcore_multiwindow_base_instance *inst = context;
87
88         inst->shell->terminate(inst, inst->shell->data);
89
90         _appcore_mw_context.instances = g_list_remove(_appcore_mw_context.instances, inst);
91         free(inst->id);
92         free(inst);
93 }
94
95 EXPORT_API void *appcore_multiwindow_base_instance_get_extra(appcore_multiwindow_base_instance_h context)
96 {
97         appcore_multiwindow_base_instance *inst = context;
98
99         return inst->extra;
100 }
101
102 EXPORT_API void appcore_multiwindow_base_instance_set_extra(appcore_multiwindow_base_instance_h context, void *extra)
103 {
104         appcore_multiwindow_base_instance *inst = context;
105
106         inst->extra = extra;
107 }
108
109 EXPORT_API bool appcore_multiwindow_base_instance_is_resumed(appcore_multiwindow_base_instance_h context)
110 {
111         appcore_multiwindow_base_instance *inst = context;
112
113         return inst->is_resumed;
114 }
115
116 EXPORT_API void appcore_multiwindow_base_instance_pause(appcore_multiwindow_base_instance_h context)
117 {
118         appcore_multiwindow_base_instance *inst = context;
119
120         if (!inst->is_resumed)
121                 return;
122
123         if (inst->shell->pause)
124                 inst->shell->pause(inst, inst->shell->data);
125         inst->is_resumed = false;
126 }
127
128 EXPORT_API void appcore_multiwindow_base_instance_resume(appcore_multiwindow_base_instance_h context)
129 {
130         appcore_multiwindow_base_instance *inst = context;
131
132         if (inst->is_resumed)
133                 return;
134
135         if (inst->shell->resume)
136                 inst->shell->resume(inst, inst->shell->data);
137         inst->is_resumed = true;
138 }
139
140 EXPORT_API const char *appcore_multiwindow_base_instance_get_id(appcore_multiwindow_base_instance_h context)
141 {
142         appcore_multiwindow_base_instance *inst = context;
143
144         return inst->id;
145 }
146
147 EXPORT_API const char *appcore_multiwindow_base_instance_get_class_id(appcore_multiwindow_base_instance_h context)
148 {
149         appcore_multiwindow_base_instance *inst = context;
150
151         return inst->shell->id;
152 }
153
154 EXPORT_API const appcore_multiwindow_base_class *appcore_multiwindow_base_instance_get_class(appcore_multiwindow_base_instance_h context)
155 {
156         appcore_multiwindow_base_instance *inst = context;
157
158         return inst->shell;
159 }
160
161 static gint __comp_id(gconstpointer a, gconstpointer b)
162 {
163         const appcore_multiwindow_base_instance *inst = a;
164
165         return strcmp(inst->id, b);
166 }
167
168 EXPORT_API appcore_multiwindow_base_instance_h appcore_multiwindow_base_instance_find(const char *id)
169 {
170         GList * inst_node = g_list_find_custom(_appcore_mw_context.instances, id, __comp_id);
171
172         if (!inst_node)
173                 return NULL;
174
175         return inst_node->data;
176 }
177
178 EXPORT_API void appcore_multiwindow_base_instance_foreach(const char *class_id,
179                 appcore_multiwindow_base_instance_cb cb, void *data)
180 {
181         GList * inst_node = _appcore_mw_context.instances;
182         appcore_multiwindow_base_instance *inst;
183
184         if (!class_id || !cb)
185                 return;
186
187         while (inst_node) {
188                 inst = inst_node->data;
189
190                 if (!strcmp(class_id, inst->shell->id))
191                         cb(class_id, inst->id, inst, data);
192
193                 inst_node = g_list_next(inst_node);
194         }
195 }
196
197 EXPORT_API void appcore_multiwindow_base_instance_foreach_full(appcore_multiwindow_base_instance_cb cb,
198                 void *data)
199 {
200         GList * inst_node = _appcore_mw_context.instances;
201         appcore_multiwindow_base_instance *inst;
202
203         if (!cb)
204                 return;
205
206         while (inst_node) {
207                 inst = inst_node->data;
208                 cb(inst->shell->id, inst->id, inst, data);
209                 inst_node = g_list_next(inst_node);
210         }
211 }
212
213 EXPORT_API int appcore_multiwindow_base_instance_get_cnt(void)
214 {
215         return g_list_length(_appcore_mw_context.instances);
216 }
217
218