Tizen 2.1 base
[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 unsigned int quickpanel_minictrl_get_height(void *data);
36
37 QP_Module minictrl = {
38         .name = "minictrl",
39         .init = quickpanel_minictrl_init,
40         .fini = quickpanel_minictrl_fini,
41         .suspend = NULL,
42         .resume = NULL,
43         .hib_enter = NULL,
44         .hib_leave = NULL,
45         .lang_changed = NULL,
46         .refresh = NULL,
47         .get_height = quickpanel_minictrl_get_height,
48 };
49
50 struct _viewer_item {
51         char *name;
52         unsigned int width;
53         unsigned int height;
54         minicontrol_priority_e priority;
55         Evas_Object *viewer;
56         Elm_Object_Item *it;
57         void *data;
58 };
59
60 GHashTable *g_prov_table;
61
62 static void _viewer_set_size(Evas_Object *viewer, void *data, int width, int height)
63 {
64         retif(viewer == NULL, , "Invalid parameter!");
65         retif(data == NULL, , "Invalid parameter!");
66         retif(width < 0, , "Invalid parameter!");
67         retif(height < 0, , "Invalid parameter!");
68         struct appdata *ad = data;
69         int max_width = 0;
70         int resized_width = 0;
71
72         DBG("mini w:%d h:%d", width, height);
73
74         if (ad->angle == 90 || ad->angle == 270) {
75                 max_width = (ad->scale * MINICONTROL_WIDTH_L_MAX) - 1;
76         } else {
77                 max_width = (ad->scale * MINICONTROL_WIDTH_P_MAX) - 1;
78         }
79         resized_width = (width > max_width) ? max_width : width;
80         evas_object_size_hint_min_set(viewer, resized_width, height);
81 }
82
83 static void _viewer_item_free(struct _viewer_item *item)
84 {
85         if (!item)
86                 return;
87
88         if (item->name)
89                 free(item->name);
90
91         if (item->it)
92                 elm_object_item_del(item->it);
93
94         if (item->viewer) {
95                 evas_object_unref(item->viewer);
96                 evas_object_del(item->viewer);
97         }
98
99         free(item);
100 }
101
102 #if 0
103 static Evas_Object *_minictrl_load_viewer(Evas_Object *parent,
104                                         struct _viewer_item *item)
105 {
106         Evas_Object *viewer = NULL;
107
108         if (!parent) {
109                 ERR("parent is NULL");
110                 return NULL;
111         }
112
113         if (!item) {
114                 ERR("item is NULL");
115                 return NULL;
116         }
117
118         if (!item->name) {
119                 ERR("item name is NULL");
120                 return NULL;
121         }
122
123         viewer = minicontrol_viewer_add(parent, item->name);
124         if (!viewer) {
125                 ERR("fail to create viewer for [%s]", item->name);
126                 return NULL;
127         }
128
129         evas_object_size_hint_min_set(viewer, item->width - QP_R_MARGIN , item->height);
130
131         return viewer;
132 }
133 #endif
134
135 static Evas_Object *_minictrl_gl_get_content(void *data, Evas_Object * obj,
136                                         const char *part)
137 {
138         Evas_Object *content = NULL;
139         qp_item_data *qid = NULL;
140         struct _viewer_item *item = NULL;
141
142         retif(data == NULL, NULL, "Invalid parameter!");
143         qid = data;
144
145         item = quickpanel_list_util_item_get_data(qid);
146         retif(!item, NULL, "item is NULL");
147
148         if (strcmp(part, "elm.icon") == 0)
149                 content = item->viewer;
150
151         return content;
152 }
153
154
155 static Eina_Bool _minictrl_gl_get_state(void *data, Evas_Object *obj,
156                                         const char *part)
157 {
158         return EINA_FALSE;
159 }
160
161 static void _minictrl_gl_del(void *data, Evas_Object *obj)
162 {
163         if (data) {
164                 quickpanel_list_util_del_count(data);
165                 free(data);
166         }
167
168         return;
169 }
170
171 static Elm_Genlist_Item_Class *_minictrl_gl_style_get(void)
172 {
173         Elm_Genlist_Item_Class *itc = NULL;
174
175         itc = elm_genlist_item_class_new();
176         if (!itc) {
177                 ERR("fail to elm_genlist_item_class_new()");
178                 return NULL;
179         }
180
181         itc->item_style = "minicontrol/default";
182         itc->func.text_get = NULL;
183         itc->func.content_get = _minictrl_gl_get_content;
184         itc->func.state_get = _minictrl_gl_get_state;
185         itc->func.del = _minictrl_gl_del;
186
187         return itc;
188 }
189
190 static int _minictrl_is_ongoing(const char *str)
191 {
192         if (str == NULL) return 0;
193
194         if (strstr(str, MINICONTROL_TYPE_STR_ONGOING) != NULL) {
195                 return 1;
196         } else {
197                 return 0;
198         }
199 }
200
201 qp_item_type_e _minictrl_priority_to_type(minicontrol_priority_e priority)
202 {
203         qp_item_type_e type;
204
205         switch (priority) {
206         case MINICONTROL_PRIORITY_TOP:
207                 type = QP_ITEM_TYPE_MINICTRL_TOP;
208                 break;
209         case MINICONTROL_PRIORITY_MIDDLE:
210                 type = QP_ITEM_TYPE_MINICTRL_MIDDLE;
211                 break;
212         case MINICONTROL_PRIORITY_LOW:
213         default:
214                 type = QP_ITEM_TYPE_MINICTRL_LOW;
215                 break;
216         }
217
218         return type;
219 }
220
221 static void _minictrl_add(const char *name, unsigned int width,
222                                 unsigned int height,
223                                 minicontrol_priority_e priority,
224                                 void *data)
225 {
226         qp_item_data *qid = NULL;
227         Elm_Genlist_Item_Class *itc = NULL;
228         struct _viewer_item *vit = NULL;
229         qp_item_type_e type;
230         struct appdata *ad;
231         Evas_Object *viewer = NULL;
232
233         retif(!name, , "name is NULL");
234         retif(!data, , "data is NULL");
235
236         ad = data;
237         retif(!ad->list, , "list is NULL");
238
239         if (g_prov_table) {
240                 struct _viewer_item *found = NULL;
241                 found = g_hash_table_lookup(g_prov_table, name);
242
243                 if (found) {
244                         ERR("already have it : %s", name);
245                         return;
246                 }
247         } else {
248                 ERR("g_prov_table is NULL");
249                 return;
250         }
251
252         /* elm_plug receives 'server_del' event,
253          * if it repeats connect and disconnect frequently.
254          *
255          */
256         viewer = minicontrol_viewer_add(ad->list, name);
257         if (!viewer) {
258                 ERR("fail to add viewer - %s", name);
259                 return;
260         }
261         evas_object_ref(viewer);
262         _viewer_set_size(viewer, ad, width, height);
263
264         itc = _minictrl_gl_style_get();
265         if (!itc) {
266                 ERR("fail to _minictrl_gl_style_get()");
267                 evas_object_del(viewer);
268                 return;
269         }
270
271         vit = malloc(sizeof(struct _viewer_item));
272         if (!vit) {
273                 ERR("fail to alloc vit");
274                 evas_object_del(viewer);
275                 elm_genlist_item_class_free(itc);
276                 return;
277         }
278
279
280         if (_minictrl_is_ongoing(name) == 1) {
281                 DBG("QP_ITEM_TYPE_MINICTRL_ONGOING is added");
282                 type = QP_ITEM_TYPE_MINICTRL_ONGOING;
283         } else {
284                 type = _minictrl_priority_to_type(priority);
285         }
286         qid = quickpanel_list_util_item_new(type, vit);
287         if (!qid) {
288                 ERR("fail to alloc vit");
289                 evas_object_del(viewer);
290                 elm_genlist_item_class_free(itc);
291                 free(vit);
292                 return;
293         }
294         vit->name = strdup(name);
295         vit->width = width;
296         vit->height = height;
297         vit->priority = priority;
298         vit->viewer = viewer;
299         vit->data = data;
300         vit->it = quickpanel_list_util_sort_insert(ad->list, itc, qid, NULL,
301                         ELM_GENLIST_ITEM_NONE, NULL, NULL);
302
303         g_hash_table_insert(g_prov_table, g_strdup(name), vit);
304
305         INFO("success to add %s", name);
306
307         elm_genlist_item_class_free(itc);
308
309         quickpanel_ui_update_height(ad);
310 }
311
312 static void _minictrl_remove(const char *name, void *data)
313 {
314         if (g_prov_table) {
315                 if (g_hash_table_remove(g_prov_table, name))
316                 {
317                         INFO("success to remove %s", name);
318
319                         retif(data == NULL, , "data is NULL");
320                         quickpanel_ui_update_height(data);
321                 }
322                 else
323                         WARN("unknown provider name : %s", name);
324         }
325 }
326
327 static void _minictrl_update(const char *name, unsigned int width,
328                                 unsigned int height, void *data)
329 {
330         struct _viewer_item *found = NULL;
331         struct appdata *ad = NULL;
332
333         if (!g_prov_table)
334                 return;
335
336         retif(!data, , "data is NULL");
337         ad = data;
338
339         found = g_hash_table_lookup(g_prov_table, name);
340
341         if (!found) {
342                 WARN("unknown provider name : %s", name);
343                 return;
344         }
345
346         found->width = width;
347         found->height = height;
348
349         if (found->viewer) {
350                 _viewer_set_size(found->viewer, ad, width, height);
351         }
352
353         if (found->it) {
354                 elm_genlist_item_update(found->it);
355                 quickpanel_ui_update_height(ad);
356         }
357 }
358
359 static void _minictrl_request(const char *name, int action, void *data)
360 {
361         Ecore_X_Window xwin;
362         struct appdata *ad = NULL;
363         retif(!name, , "name is NULL");
364         retif(!data, , "data is NULL");
365         ad = data;
366
367         if (action == MINICONTROL_REQ_HIDE_VIEWER) {
368                 xwin = elm_win_xwindow_get(ad->win);
369                 if (xwin != 0) {
370                         DBG("close by minictrl:%s", name);
371                         debug_printf("close by minictrl:%s", name);
372                         ecore_x_e_illume_quickpanel_state_send(ecore_x_e_illume_zone_get(xwin),ECORE_X_ILLUME_QUICKPANEL_STATE_OFF);
373                 }
374         }
375 }
376
377 static void _mctrl_monitor_cb(minicontrol_action_e action,
378                                 const char *name, unsigned int width,
379                                 unsigned int height,
380                                 minicontrol_priority_e priority,
381                                 void *data)
382 {
383         retif(!data, , "data is NULL");
384         retif(!name, , "name is NULL");
385
386         switch (action) {
387         case MINICONTROL_ACTION_START:
388                 _minictrl_add(name, width, height, priority, data);
389                 break;
390         case MINICONTROL_ACTION_RESIZE:
391                 _minictrl_update(name, width, height, data);
392                 break;
393         case MINICONTROL_ACTION_STOP:
394                 _minictrl_remove(name, data);
395                 break;
396         case MINICONTROL_ACTION_REQUEST:
397                 _minictrl_request(name, width, data);
398                 break;
399         default:
400                 break;
401         }
402 }
403
404 static int quickpanel_minictrl_init(void *data)
405 {
406         minicontrol_error_e ret;
407
408         retif(!data, QP_FAIL, "Invalid parameter!");
409
410         g_prov_table = g_hash_table_new_full(g_str_hash, g_str_equal,
411                                         (GDestroyNotify)g_free,
412                                         (GDestroyNotify)_viewer_item_free);
413
414         ret = minicontrol_monitor_start(_mctrl_monitor_cb, data);
415         if (ret != MINICONTROL_ERROR_NONE) {
416                 ERR("fail to minicontrol_monitor_start()- %d", ret);
417                 return QP_FAIL;
418         }
419
420         return QP_OK;
421 }
422
423 static int quickpanel_minictrl_fini(void *data)
424 {
425         minicontrol_error_e ret;
426         ret = minicontrol_monitor_stop();
427         if (ret != MINICONTROL_ERROR_NONE)
428                 ERR("fail to minicontrol_monitor_stop()- %d", ret);
429
430         if (g_prov_table) {
431                 g_hash_table_remove_all(g_prov_table);
432                 g_prov_table = NULL;
433         }
434
435         return QP_OK;
436 }
437
438
439 static void _quickpanel_minictrl_hf_sum_height(gpointer key, gpointer value, gpointer data)
440 {
441         struct _viewer_item *item = value;
442
443         if (item != NULL && data != NULL) {
444                 *((unsigned int *)data) += item->height;
445         }
446 }
447
448 static unsigned int quickpanel_minictrl_get_height(void *data)
449 {
450         unsigned int height_minictrl = 0;
451
452         if (g_prov_table != NULL) {
453                 g_hash_table_foreach(g_prov_table, _quickpanel_minictrl_hf_sum_height, &height_minictrl);
454         }
455
456         return height_minictrl;
457 }