1e1e85c969f0e25785326d15a048acbb2738d4ef
[apps/core/preloaded/quickpanel.git] / daemon / minictrl / minictrl.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.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://floralicense.org/license/
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 <glib.h>
18 #include <Ecore_X.h>
19 #include <minicontrol-viewer.h>
20 #include <minicontrol-monitor.h>
21 #include <string.h>
22 #include "common.h"
23 #include "quickpanel-ui.h"
24 #include "list_util.h"
25 #include "quickpanel_debug_util.h"
26
27 #define QP_R_MARGIN 12
28 #define MINICONTROL_WIDTH_P_MAX 692
29 #define MINICONTROL_WIDTH_L_MAX 1252
30
31 #define MINICONTROL_TYPE_STR_ONGOING "_ongoing]"
32
33 static int quickpanel_minictrl_init(void *data);
34 static int quickpanel_minictrl_fini(void *data);
35 static int quickpanel_minictrl_suspend(void *data);
36 static int quickpanel_minictrl_resume(void *data);
37
38 QP_Module minictrl = {
39         .name = "minictrl",
40         .init = quickpanel_minictrl_init,
41         .fini = quickpanel_minictrl_fini,
42         .suspend = quickpanel_minictrl_suspend,
43         .resume = quickpanel_minictrl_resume,
44         .hib_enter = NULL,
45         .hib_leave = NULL,
46         .lang_changed = NULL,
47         .refresh = NULL,
48         .get_height = NULL,
49 };
50
51 struct _viewer_item {
52         char *name;
53         unsigned int width;
54         unsigned int height;
55         minicontrol_priority_e priority;
56         Evas_Object *viewer;
57         void *data;
58 };
59
60 GHashTable *g_prov_table;
61
62 static void _viewer_freeze(Evas_Object *viewer)
63 {
64         int freezed_count = 0;
65         retif(viewer == NULL, , "Invalid parameter!");
66
67         freezed_count = elm_object_scroll_freeze_get(viewer);
68
69         if (freezed_count <= 0) {
70                 elm_object_scroll_freeze_push(viewer);
71         }
72 }
73
74 static void _viewer_unfreeze(Evas_Object *viewer)
75 {
76         int i = 0, freezed_count = 0;
77         retif(viewer == NULL, , "Invalid parameter!");
78
79         freezed_count = elm_object_scroll_freeze_get(viewer);
80
81         for (i = 0 ; i < freezed_count; i++) {
82                 elm_object_scroll_freeze_pop(viewer);
83         }
84 }
85
86 static Evas_Object *_get_minictrl_obj(Evas_Object *layout) {
87         retif(layout == NULL, NULL, "Invalid parameter!");
88
89         return elm_object_part_content_get(layout, "elm.icon");
90 }
91
92 static void _viewer_set_size(Evas_Object *layout, void *data, int width, int height)
93 {
94         Evas_Object *viewer = NULL;
95         retif(layout == NULL, , "Invalid parameter!");
96         retif(data == NULL, , "Invalid parameter!");
97         retif(width < 0, , "Invalid parameter!");
98         retif(height < 0, , "Invalid parameter!");
99         struct appdata *ad = data;
100         int max_width = 0;
101         int resized_width = 0;
102
103         viewer = _get_minictrl_obj(layout);
104         retif(viewer == NULL, , "Invalid parameter!");
105
106         if (ad->angle == 90 || ad->angle == 270) {
107                 max_width = (ad->scale * MINICONTROL_WIDTH_L_MAX) - 1;
108         } else {
109                 max_width = (ad->scale * MINICONTROL_WIDTH_P_MAX) - 1;
110         }
111         resized_width = (width > max_width) ? max_width : width;
112
113         DBG("resize:%d %d", resized_width, height);
114
115         evas_object_size_hint_min_set(viewer, resized_width, height);
116 }
117
118 static void _viewer_item_free(struct _viewer_item *item)
119 {
120         struct appdata *ad = quickpanel_get_app_data();
121         retif(ad == NULL, , "Invalid parameter!");
122         retif(ad->list == NULL, , "Invalid parameter!");
123         retif(item == NULL, , "Invalid parameter!");
124
125         if (item->name)
126                 free(item->name);
127
128         if (item->viewer) {
129 #ifdef TBD
130                 evas_object_unref(item->viewer);
131 #endif
132                 quickpanel_list_util_item_unpack_by_object(ad->list, item->viewer);
133                 quickpanel_list_util_item_del_tag(item->viewer);
134                 evas_object_del(item->viewer);
135         }
136
137         free(item);
138 }
139
140 static Evas_Object *_minictrl_create_view(struct appdata *ad, const char *name)
141 {
142         retif(ad == NULL, NULL, "Invalid parameter!");
143         retif(ad->list == NULL, NULL, "Invalid parameter!");
144         retif(name == NULL, NULL, "Invalid parameter!");
145
146         Evas_Object *layout = NULL;
147
148         layout = elm_layout_add(ad->list);
149
150         DBG("");
151         elm_layout_file_set(layout, DEFAULT_EDJ,
152                         "quickpanel/minictrl/default");
153
154         evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
155         evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
156         evas_object_show(layout);
157
158         Evas_Object *viewer = minicontrol_viewer_add(layout, name);
159         if (!viewer) {
160                 ERR("fail to add viewer - %s", name);
161                 return NULL;
162         }
163 #ifdef TBD
164         evas_object_ref(viewer);
165 #endif
166         elm_object_part_content_set(layout, "elm.icon", viewer);
167
168         return layout;
169 }
170
171 static int _minictrl_is_ongoing(const char *str)
172 {
173         if (str == NULL) return 0;
174
175         if (strstr(str, MINICONTROL_TYPE_STR_ONGOING) != NULL) {
176                 return 1;
177         } else {
178                 return 0;
179         }
180 }
181
182 qp_item_type_e _minictrl_priority_to_type(minicontrol_priority_e priority)
183 {
184         qp_item_type_e type;
185
186         switch (priority) {
187         case MINICONTROL_PRIORITY_TOP:
188                 type = QP_ITEM_TYPE_MINICTRL_TOP;
189                 break;
190         case MINICONTROL_PRIORITY_MIDDLE:
191                 type = QP_ITEM_TYPE_MINICTRL_MIDDLE;
192                 break;
193         case MINICONTROL_PRIORITY_LOW:
194         default:
195                 type = QP_ITEM_TYPE_MINICTRL_LOW;
196                 break;
197         }
198
199         return type;
200 }
201
202 static void _minictrl_release_cb(void *data, Evas *e,
203                 Evas_Object *obj, void *event_info) {
204         struct appdata *ad;
205         retif(!data, , "data is NULL");
206         ad = data;
207
208         DBG("");
209         _viewer_unfreeze(ad->scroller);
210 }
211
212 static void _minictrl_add(const char *name, unsigned int width,
213                                 unsigned int height,
214                                 minicontrol_priority_e priority,
215                                 void *data)
216 {
217         qp_item_data *qid = NULL;
218         struct _viewer_item *vit = NULL;
219         qp_item_type_e type;
220         struct appdata *ad;
221         Evas_Object *viewer = NULL;
222
223         retif(!name, , "name is NULL");
224         retif(!data, , "data is NULL");
225
226         ad = data;
227         retif(!ad->list, , "list is NULL");
228
229         if (g_prov_table) {
230                 struct _viewer_item *found = NULL;
231                 found = g_hash_table_lookup(g_prov_table, name);
232
233                 if (found) {
234                         ERR("already have it : %s", name);
235                         return;
236                 }
237         } else {
238                 ERR("g_prov_table is NULL");
239                 return;
240         }
241
242         /* elm_plug receives 'server_del' event,
243          * if it repeats connect and disconnect frequently.
244          *
245          */
246         viewer = _minictrl_create_view(ad, name);
247         _viewer_set_size(viewer, ad, width, height);
248
249         evas_object_event_callback_add(_get_minictrl_obj(viewer), EVAS_CALLBACK_MOUSE_UP,
250                         _minictrl_release_cb, ad);
251
252         vit = malloc(sizeof(struct _viewer_item));
253         if (!vit) {
254                 ERR("fail to alloc vit");
255                 evas_object_del(viewer);
256                 return;
257         }
258
259         if (_minictrl_is_ongoing(name) == 1) {
260                 DBG("QP_ITEM_TYPE_MINICTRL_ONGOING is added");
261                 type = QP_ITEM_TYPE_MINICTRL_ONGOING;
262         } else {
263                 type = _minictrl_priority_to_type(priority);
264         }
265         qid = quickpanel_list_util_item_new(type, vit);
266         if (!qid) {
267                 ERR("fail to alloc vit");
268                 evas_object_del(viewer);
269                 free(vit);
270                 return;
271         }
272         vit->name = strdup(name);
273         vit->width = width;
274         vit->height = height;
275         vit->priority = priority;
276         vit->viewer = viewer;
277         vit->data = data;
278         quickpanel_list_util_item_set_tag(vit->viewer, qid);
279         quickpanel_list_util_sort_insert(ad->list, vit->viewer);
280
281         g_hash_table_insert(g_prov_table, g_strdup(name), vit);
282
283         INFO("success to add %s", name);
284 }
285
286 static void _minictrl_remove(const char *name, void *data)
287 {
288         if (g_prov_table) {
289                 if (g_hash_table_remove(g_prov_table, name))
290                 {
291                         INFO("success to remove %s", name);
292
293                         retif(data == NULL, , "data is NULL");
294                 }
295                 else
296                         WARN("unknown provider name : %s", name);
297         }
298 }
299
300 static void _minictrl_update(const char *name, unsigned int width,
301                                 unsigned int height, void *data)
302 {
303         struct _viewer_item *found = NULL;
304         struct appdata *ad = NULL;
305
306         if (!g_prov_table)
307                 return;
308
309         retif(!data, , "data is NULL");
310         ad = data;
311
312         found = g_hash_table_lookup(g_prov_table, name);
313
314         if (!found) {
315                 WARN("unknown provider name : %s", name);
316                 return;
317         }
318
319         found->width = width;
320         found->height = height;
321
322         if (found->viewer) {
323                 _viewer_set_size(found->viewer, ad, width, height);
324         }
325 }
326
327 static void _minictrl_request(const char *name, int action, void *data)
328 {
329         struct appdata *ad = NULL;
330         retif(!name, , "name is NULL");
331         retif(!data, , "data is NULL");
332         ad = data;
333
334         if (action == MINICONTROL_REQ_HIDE_VIEWER) {
335                 quickpanel_close_quickpanel(true);
336         }
337         if (action == MINICONTROL_REQ_FREEZE_SCROLL_VIEWER) {
338                 if (ad->list != NULL) {
339                         ERR("freezed by %s", name);
340                         _viewer_freeze(ad->scroller);
341                 }
342         }
343         if (action == MINICONTROL_REQ_UNFREEZE_SCROLL_VIEWER) {
344                 if (ad->list != NULL) {
345                         ERR("unfreezed by %s", name);
346                         _viewer_unfreeze(ad->scroller);
347                 }
348         }
349 }
350
351 static void _mctrl_monitor_cb(minicontrol_action_e action,
352                                 const char *name, unsigned int width,
353                                 unsigned int height,
354                                 minicontrol_priority_e priority,
355                                 void *data)
356 {
357         retif(!data, , "data is NULL");
358         retif(!name, , "name is NULL");
359
360         switch (action) {
361         case MINICONTROL_ACTION_START:
362                 _minictrl_add(name, width, height, priority, data);
363                 break;
364         case MINICONTROL_ACTION_RESIZE:
365                 _minictrl_update(name, width, height, data);
366                 break;
367         case MINICONTROL_ACTION_STOP:
368                 _minictrl_remove(name, data);
369                 break;
370         case MINICONTROL_ACTION_REQUEST:
371                 _minictrl_request(name, width, data);
372                 break;
373         default:
374                 break;
375         }
376 }
377
378 static int quickpanel_minictrl_init(void *data)
379 {
380         minicontrol_error_e ret;
381
382         retif(!data, QP_FAIL, "Invalid parameter!");
383
384         g_prov_table = g_hash_table_new_full(g_str_hash, g_str_equal,
385                                         (GDestroyNotify)g_free,
386                                         (GDestroyNotify)_viewer_item_free);
387
388         ret = minicontrol_monitor_start(_mctrl_monitor_cb, data);
389         if (ret != MINICONTROL_ERROR_NONE) {
390                 ERR("fail to minicontrol_monitor_start()- %d", ret);
391                 return QP_FAIL;
392         }
393
394         return QP_OK;
395 }
396
397 static int quickpanel_minictrl_fini(void *data)
398 {
399         minicontrol_error_e ret;
400         ret = minicontrol_monitor_stop();
401         if (ret != MINICONTROL_ERROR_NONE)
402                 ERR("fail to minicontrol_monitor_stop()- %d", ret);
403
404         if (g_prov_table) {
405                 g_hash_table_remove_all(g_prov_table);
406                 g_prov_table = NULL;
407         }
408
409         return QP_OK;
410 }
411
412 static int quickpanel_minictrl_suspend(void *data)
413 {
414         struct appdata *ad = data;
415         retif(ad == NULL, QP_FAIL, "Invalid parameter!");
416
417         if (ad->list != NULL) {
418                 _viewer_unfreeze(ad->scroller);
419         }
420
421         return QP_OK;
422 }
423
424 static int quickpanel_minictrl_resume(void *data)
425 {
426         struct appdata *ad = data;
427         retif(ad == NULL, QP_FAIL, "Invalid parameter!");
428
429         if (ad->list != NULL) {
430                 _viewer_unfreeze(ad->scroller);
431         }
432
433         return QP_OK;
434 }