modules/information/ext_storage: fix sigsegv
[apps/core/preloaded/indicator-win.git] / src / list.c
1 /*
2  *  Indicator
3  *
4  * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20
21
22 #include "indicator.h"
23 #include "log.h"
24 #include "util.h"
25 #include "list.h"
26 #include "icon.h"
27
28 static Eina_List *fixed_icon_list = NULL;
29 static Eina_List *system_icon_list = NULL;
30 static Eina_List *noti_icon_list = NULL;
31 static Eina_List *alarm_icon_list = NULL;
32
33
34
35 extern void icon_free(icon_s *icon)
36 {
37         if (icon) {
38                 if (icon->obj_exist == EINA_TRUE) {
39                         if (icon_del(icon) == EINA_TRUE) {
40                                 icon->obj_exist = EINA_FALSE;
41                                 icon->img_obj.obj = NULL;
42                         }
43                 }
44         }
45 }
46
47
48
49 static void _list_free(Eina_List *list)
50 {
51         Eina_List *l;
52         Eina_List *l_next;
53         icon_s *data;
54
55         ret_if(!list);
56
57         EINA_LIST_FOREACH_SAFE(list, l, l_next, data) {
58                 icon_free(data);
59                 list = eina_list_remove_list(list, l);
60         }
61         eina_list_free(list);
62         list = NULL;
63
64         return;
65 }
66
67
68
69 extern int list_free_all(void)
70 {
71         _list_free(fixed_icon_list);
72         _list_free(system_icon_list);
73         _list_free(noti_icon_list);
74         _list_free(alarm_icon_list);
75
76         return true;
77 }
78
79
80
81 static Eina_List *_insert_icon_to_list(Eina_List *list, icon_s *icon)
82 {
83         Eina_List *l;
84         icon_s *data;
85
86         /* FIXME */
87         //retv_if(!list, NULL);
88         retv_if(!icon, NULL);
89
90         /* Insert icon to list */
91         EINA_LIST_REVERSE_FOREACH(list, l, data) {
92                 if (data->priority == icon->priority
93                         && data->always_top == EINA_TRUE)
94                         continue;
95
96                 if (data->priority <= icon->priority) {
97                         list = eina_list_append_relative_list(list, icon, l);
98                         return list;
99                 }
100         }
101
102         /* If finding condition is failed, append it at tail */
103         list = eina_list_prepend(list, icon);
104         return list;
105 }
106
107
108
109 extern void list_update(icon_s *icon)
110 {
111         ret_if(!icon);
112
113         switch (icon->area) {
114         case INDICATOR_ICON_AREA_FIXED:
115                 fixed_icon_list = eina_list_remove(fixed_icon_list, icon);
116                 fixed_icon_list = _insert_icon_to_list(fixed_icon_list, icon);
117                 break;
118         case INDICATOR_ICON_AREA_SYSTEM:
119                 system_icon_list = eina_list_remove(system_icon_list, icon);
120                 system_icon_list = _insert_icon_to_list(system_icon_list, icon);
121                 break;
122         case INDICATOR_ICON_AREA_NOTI:
123                 noti_icon_list = eina_list_remove(noti_icon_list, icon);
124                 noti_icon_list = _insert_icon_to_list(noti_icon_list, icon);
125                 break;
126         case INDICATOR_ICON_AREA_ALARM:
127                 alarm_icon_list = eina_list_remove(alarm_icon_list, icon);
128                 alarm_icon_list = _insert_icon_to_list(alarm_icon_list, icon);
129                 break;
130         default:
131                 break;
132         }
133
134         return;
135 }
136
137
138
139 static indicator_error_e _icon_exist_in_list(Eina_List *list, icon_s *icon)
140 {
141         Eina_List *l;
142         icon_s *data;
143
144         /* Check name */
145         EINA_LIST_REVERSE_FOREACH(fixed_icon_list, l, data) {
146                 if (data->name == icon->name) {
147                         _D("[%s] is already exist in the list", icon->name);
148                         return INDICATOR_ERROR_FAIL;
149                 }
150         }
151         return INDICATOR_ERROR_NONE;
152 }
153
154
155 extern void list_insert_icon(icon_s *icon)
156 {
157         ret_if(!icon);
158         ret_if(!icon->name);
159
160         switch (icon->area) {
161         case INDICATOR_ICON_AREA_FIXED:
162                 if (INDICATOR_ERROR_NONE != _icon_exist_in_list(fixed_icon_list, icon)) return;
163
164                 /* Set internal data */
165                 icon->wish_to_show = EINA_FALSE;
166                 fixed_icon_list = _insert_icon_to_list(fixed_icon_list, icon);
167                 break;
168         case INDICATOR_ICON_AREA_SYSTEM:
169                 if (INDICATOR_ERROR_NONE != _icon_exist_in_list(system_icon_list, icon)) return;
170
171                 /* Set internal data */
172                 icon->wish_to_show = EINA_FALSE;
173                 system_icon_list = _insert_icon_to_list(system_icon_list, icon);
174                 break;
175         case INDICATOR_ICON_AREA_NOTI:
176                 if (INDICATOR_ERROR_NONE != _icon_exist_in_list(noti_icon_list, icon)) return;
177
178                 /* Set internal data */
179                 icon->wish_to_show = EINA_FALSE;
180                 noti_icon_list = _insert_icon_to_list(noti_icon_list, icon);
181                 break;
182         case INDICATOR_ICON_AREA_ALARM:
183                 if (INDICATOR_ERROR_NONE != _icon_exist_in_list(alarm_icon_list, icon)) return;
184
185                 /* Set internal data */
186                 icon->wish_to_show = EINA_FALSE;
187                 alarm_icon_list = eina_list_append(alarm_icon_list, icon);
188                 break;
189         default:
190                 break;
191         }
192
193         return;
194 }
195
196
197 extern void list_remove_icon(icon_s *icon)
198 {
199         ret_if(!icon);
200
201         switch (icon->area) {
202         case INDICATOR_ICON_AREA_FIXED:
203                 ret_if(!fixed_icon_list);
204                 fixed_icon_list = eina_list_remove(fixed_icon_list, icon);
205                 break;
206         case INDICATOR_ICON_AREA_SYSTEM:
207                 ret_if(!system_icon_list);
208                 system_icon_list = eina_list_remove(system_icon_list, icon);
209                 break;
210         case INDICATOR_ICON_AREA_NOTI:
211                 ret_if(!noti_icon_list);
212                 noti_icon_list = eina_list_remove(noti_icon_list, icon);
213                 break;
214         case INDICATOR_ICON_AREA_ALARM:
215                 ret_if(!alarm_icon_list);
216                 alarm_icon_list = eina_list_remove(alarm_icon_list, icon);
217                 break;
218         default:
219                 _E("default");
220                 break;
221         }
222 }
223
224
225 extern icon_s *list_try_to_find_icon_to_show(int area, int priority)
226 {
227         Eina_List *l;
228         icon_s *data = NULL;
229         icon_s *icon = NULL;
230
231         switch (area) {
232         case INDICATOR_ICON_AREA_FIXED:
233                 EINA_LIST_REVERSE_FOREACH(fixed_icon_list, l, data) {
234                         if (data->priority == priority
235                                 && data->wish_to_show == EINA_TRUE
236                                 && data->exist_in_view == EINA_FALSE) {
237                                 icon = data;
238                                 break;
239                         }
240                 }
241                 break;
242         case INDICATOR_ICON_AREA_SYSTEM:
243                 EINA_LIST_REVERSE_FOREACH(system_icon_list, l, data) {
244                         if (data->wish_to_show == EINA_TRUE
245                                 && data->exist_in_view == EINA_FALSE) {
246                                 icon = data;
247                                 break;
248                         }
249                 }
250                 break;
251         case INDICATOR_ICON_AREA_NOTI:
252                 EINA_LIST_REVERSE_FOREACH(noti_icon_list, l, data) {
253                         if (data->wish_to_show == EINA_TRUE
254                                 && data->exist_in_view == EINA_FALSE) {
255                                 icon = data;
256                                 break;
257                         }
258                 }
259                 break;
260         case INDICATOR_ICON_AREA_ALARM:
261                 EINA_LIST_REVERSE_FOREACH(alarm_icon_list, l, data) {
262                         if (data->wish_to_show == EINA_TRUE
263                                 && data->exist_in_view == EINA_FALSE) {
264                                 icon = data;
265                                 break;
266                         }
267                 }
268                 break;
269         default:
270                 _E("default");
271                 break;
272         }
273
274         retv_if(!icon, NULL);
275
276         return icon;
277 }
278
279
280
281 extern icon_s *list_try_to_find_icon_to_remove(int area, int priority)
282 {
283         Eina_List *l;
284         icon_s *data = NULL;
285         icon_s *icon = NULL;
286
287
288         switch (area) {
289         case INDICATOR_ICON_AREA_FIXED:
290                 EINA_LIST_REVERSE_FOREACH(fixed_icon_list, l, data) {
291                         if (data->priority == priority
292                                 && data->wish_to_show == EINA_TRUE) {
293                                 icon = data;
294                                 break;
295                         }
296                 }
297                 break;
298         case INDICATOR_ICON_AREA_SYSTEM:
299                 /* Find lowest priority of icon */
300                 EINA_LIST_FOREACH(system_icon_list, l, data) {
301                         if (data->wish_to_show == EINA_TRUE
302                                 && data->always_top == EINA_FALSE
303                                 && data->exist_in_view == EINA_TRUE) {
304                                 icon = data;
305                                 break;
306                         }
307                 }
308                 break;
309         case INDICATOR_ICON_AREA_NOTI:
310                 /* Find lowest priority of icon */
311                 EINA_LIST_REVERSE_FOREACH(noti_icon_list, l, data) {
312                         if (data->wish_to_show == EINA_TRUE
313                                 && data->always_top == EINA_FALSE
314                                 && data->exist_in_view == EINA_TRUE) {
315                                 icon = data;
316                                 break;
317                         }
318                 }
319                 break;
320         case INDICATOR_ICON_AREA_ALARM:
321                 /* Find lowest priority of icon */
322                 EINA_LIST_FOREACH(alarm_icon_list, l, data) {
323                         if (data->wish_to_show == EINA_TRUE
324                                 && data->always_top == EINA_FALSE
325                                 && data->exist_in_view == EINA_TRUE) {
326                                 icon = data;
327                                 break;
328                         }
329                 }
330                 break;
331         default:
332                 _E("default");
333                 break;
334         }
335
336         retv_if(!icon, NULL);
337
338         return icon;
339 }
340
341
342
343 extern unsigned int list_get_noti_count(void)
344 {
345         Eina_List *l;
346         icon_s *data = NULL;
347         int cnt = 0;
348
349         EINA_LIST_FOREACH(noti_icon_list, l, data) {
350                 if (data->wish_to_show == EINA_TRUE
351                         || data->exist_in_view == EINA_TRUE) {
352                         if (!strcmp(data->name, "more_notify")) continue; // Except more noti
353                         cnt++;
354                 }
355         }
356
357         return cnt;
358 }
359
360 /* End of file */