8242ba672d7997ad796a11133c7c56cbe0c0346f
[apps/core/preloaded/quickpanel.git] / daemon / minictrl / minictrl.c
1 /*
2  * Copyright (c) 2009-2015 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
18
19 #include <glib.h>
20 #include <minicontrol-viewer.h>
21 #include <minicontrol-monitor.h>
22 #include <string.h>
23 #include "common.h"
24 #include "quickpanel-ui.h"
25 #include "quickpanel_def.h"
26 #include "list_util.h"
27 #include "quickpanel_debug_util.h"
28 #ifdef QP_SCREENREADER_ENABLE
29 #include "accessibility.h"
30 #endif
31 #include "minictrl.h"
32 #include "vi_manager.h"
33
34 #define MINICONTROL_TYPE_STR_VIEWER "::[viewer="
35 #define MINICONTROL_TYPE_STR_QUICKPANEL "QUICKPANEL"
36 #define MINICONTROL_TYPE_STR_LOCKSCREEN "LOCKSCREEN"
37 #define MINICONTROL_TYPE_STR_ONGOING "_ongoing]"
38
39 static Eina_Bool _anim_init_cb(void *data);
40 static Eina_Bool _anim_job_cb(void *data);
41 static Eina_Bool _anim_done_cb(void *data);
42 static int _init(void *data);
43 static int _fini(void *data);
44 static int _suspend(void *data);
45 static int _resume(void *data);
46
47 QP_Module minictrl = {
48         .name = "minictrl",
49         .init = _init,
50         .fini = _fini,
51         .suspend = _suspend,
52         .resume = _resume,
53         .hib_enter = NULL,
54         .hib_leave = NULL,
55         .lang_changed = NULL,
56         .refresh = NULL,
57         .get_height = NULL,
58 };
59
60 struct _viewer_item {
61         char *name;
62         unsigned int width;
63         unsigned int height;
64         minicontrol_priority_e priority;
65         Evas_Object *viewer;
66         void *data;
67 };
68
69 static void _minictrl_resize_vi(Evas_Object *list,
70                                         struct _viewer_item *item, int to_w, int to_h);
71
72 GHashTable *g_prov_table;
73
74 static int _viewer_check(const char *name)
75 {
76         char *pos_start = NULL;
77         retif(!name, 0, "name is NULL");
78
79         if ((pos_start = strstr(name, MINICONTROL_TYPE_STR_VIEWER)) != NULL) {
80                 if (strstr(pos_start, MINICONTROL_TYPE_STR_QUICKPANEL) != NULL) {
81                         return 1;
82                 } else {
83                         return 0;
84                 }
85         } else if (strstr(name, MINICONTROL_TYPE_STR_LOCKSCREEN) != NULL) {
86                 return 0;
87         }
88
89         return 1;
90 }
91
92 static void _viewer_freeze(Evas_Object *viewer)
93 {
94         int freezed_count = 0;
95         retif(viewer == NULL, , "Invalid parameter!");
96
97         freezed_count = elm_object_scroll_freeze_get(viewer);
98
99         if (freezed_count <= 0) {
100                 elm_object_scroll_freeze_push(viewer);
101         }
102 }
103
104 static void _viewer_unfreeze(Evas_Object *viewer)
105 {
106         int i = 0, freezed_count = 0;
107         retif(viewer == NULL, , "Invalid parameter!");
108
109         freezed_count = elm_object_scroll_freeze_get(viewer);
110
111         for (i = 0 ; i < freezed_count; i++) {
112                 elm_object_scroll_freeze_pop(viewer);
113         }
114 }
115
116 static Evas_Object *_get_minictrl_obj(Evas_Object *layout)
117 {
118         retif(layout == NULL, NULL, "Invalid parameter!");
119
120         return elm_object_part_content_get(layout, "elm.icon");
121 }
122
123 static void _viewer_set_size(Evas_Object *layout, void *data, int width, int height)
124 {
125         Evas_Object *viewer = NULL;
126         retif(layout == NULL, , "Invalid parameter!");
127         retif(data == NULL, , "Invalid parameter!");
128         retif(width < 0, , "Invalid parameter!");
129         retif(height < 0, , "Invalid parameter!");
130         struct appdata *ad = data;
131         int max_width = 0;
132         int resized_width = 0;
133         int is_landscape = 0;
134
135         viewer = _get_minictrl_obj(layout);
136         retif(viewer == NULL, , "Invalid parameter!");
137
138         is_landscape = (width > ad->win_width) ? 1 : 0;
139
140         if (is_landscape) {
141                 max_width = (ad->scale * ad->win_height);
142         } else {
143                 max_width = (ad->scale * ad->win_width);
144         }
145         resized_width = (width > max_width) ? max_width : width;
146
147         SERR("minicontroller view is resized to w:%d(%d) h:%d Landscape[%d]", resized_width, width, height, is_landscape);
148
149         evas_object_size_hint_min_set(viewer, resized_width, height);
150         evas_object_size_hint_max_set(viewer, resized_width, height);
151 }
152
153 static void _viewer_item_free(struct _viewer_item *item)
154 {
155         struct appdata *ad = quickpanel_get_app_data();
156         retif(ad == NULL, , "Invalid parameter!");
157         retif(ad->list == NULL, , "Invalid parameter!");
158         retif(item == NULL, , "Invalid parameter!");
159
160         if (item->name) {
161                 free(item->name);
162         }
163
164         if (item->viewer) {
165                 quickpanel_list_util_item_unpack_by_object(ad->list, item->viewer, 0, 0);
166                 quickpanel_list_util_item_del_tag(item->viewer);
167                 if (item->viewer != NULL) {
168                         evas_object_del(item->viewer);
169                         item->viewer = NULL;
170                 }
171         }
172
173         free(item);
174 }
175
176 static Evas_Object *_minictrl_create_view(struct appdata *ad, const char *name)
177 {
178         retif(ad == NULL, NULL, "Invalid parameter!");
179         retif(ad->list == NULL, NULL, "Invalid parameter!");
180         retif(name == NULL, NULL, "Invalid parameter!");
181
182         Evas_Object *layout = NULL;
183
184         layout = elm_layout_add(ad->list);
185
186         elm_layout_file_set(layout, DEFAULT_EDJ,
187                         "quickpanel/minictrl/default");
188
189         evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
190         evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
191         evas_object_show(layout);
192
193         Evas_Object *viewer = minicontrol_viewer_add(layout, name);
194         if (!viewer) {
195                 ERR("fail to add viewer - %s", name);
196                 if (layout) {
197                         evas_object_del(layout);
198                 }
199                 return NULL;
200         }
201         elm_object_focus_allow_set(viewer, EINA_TRUE);
202         elm_object_part_content_set(layout, "elm.icon", viewer);
203
204         Evas_Object *focus = quickpanel_accessibility_ui_get_focus_object(layout);
205         elm_object_part_content_set(layout, "focus", focus);
206
207 #ifdef QP_SCREENREADER_ENABLE
208         Evas_Object *ao = quickpanel_accessibility_screen_reader_object_get(layout,
209                         SCREEN_READER_OBJ_TYPE_ELM_OBJECT, "focus", layout);
210
211         if (ao != NULL) {
212                 elm_access_info_cb_set(ao, ELM_ACCESS_TYPE, quickpanel_accessibility_info_cb,
213                                 _NOT_LOCALIZED("Mini controller"));
214         }
215 #endif
216
217         return layout;
218 }
219
220 static int _minictrl_is_ongoing(const char *str)
221 {
222         if (str == NULL) {
223                 return 0;
224         }
225
226         if (strstr(str, MINICONTROL_TYPE_STR_ONGOING) != NULL) {
227                 return 1;
228         } else {
229                 return 0;
230         }
231 }
232
233 static qp_item_type_e _minictrl_priority_to_type(minicontrol_priority_e priority)
234 {
235         qp_item_type_e type;
236
237         switch (priority) {
238         case MINICONTROL_PRIORITY_TOP:
239                 type = QP_ITEM_TYPE_MINICTRL_TOP;
240                 break;
241         case MINICONTROL_PRIORITY_MIDDLE:
242                 type = QP_ITEM_TYPE_MINICTRL_MIDDLE;
243                 break;
244         case MINICONTROL_PRIORITY_LOW:
245         default:
246                 type = QP_ITEM_TYPE_MINICTRL_LOW;
247                 break;
248         }
249
250         return type;
251 }
252
253 static void _minictrl_release_cb(void *data, Evas *e,
254                 Evas_Object *obj, void *event_info)
255 {
256         struct appdata *ad;
257         retif(!data, , "data is NULL");
258         ad = data;
259
260         _viewer_unfreeze(ad->scroller);
261 }
262
263 static void _minictrl_add(const char *name, unsigned int width,
264                                 unsigned int height,
265                                 minicontrol_priority_e priority,
266                                 void *data)
267 {
268         qp_item_data *qid = NULL;
269         struct _viewer_item *vit = NULL;
270         qp_item_type_e type;
271         struct appdata *ad;
272         Evas_Object *viewer = NULL;
273
274         retif(!name, , "name is NULL");
275         retif(!data, , "data is NULL");
276
277         ad = data;
278         retif(!ad->list, , "list is NULL");
279
280         if (g_prov_table) {
281                 struct _viewer_item *found = NULL;
282                 found = g_hash_table_lookup(g_prov_table, name);
283
284                 if (found) {
285                         ERR("already have it : %s", name);
286                         return;
287                 }
288         } else {
289                 ERR("g_prov_table is NULL");
290                 return;
291         }
292
293         /* elm_plug receives 'server_del' event,
294          * if it repeats connect and disconnect frequently.
295          *
296          */
297         viewer = _minictrl_create_view(ad, name);
298         if (!viewer) {
299                 ERR("Failed to create view[%s]", name);
300                 return;
301         }
302         _viewer_set_size(viewer, ad, width, height);
303         quickpanel_uic_initial_resize(viewer,
304                         (height > QP_THEME_LIST_ITEM_MINICONTRL_HEIGHT + QP_THEME_LIST_ITEM_SEPERATOR_HEIGHT)
305                         ? height : QP_THEME_LIST_ITEM_MINICONTRL_HEIGHT + QP_THEME_LIST_ITEM_SEPERATOR_HEIGHT);
306
307         evas_object_event_callback_add(_get_minictrl_obj(viewer), EVAS_CALLBACK_MOUSE_UP,
308                         _minictrl_release_cb, ad);
309
310         vit = malloc(sizeof(struct _viewer_item));
311         if (!vit) {
312                 ERR("fail to alloc vit");
313                 if (viewer != NULL) {
314                         evas_object_del(viewer);
315                         viewer = NULL;
316                 }
317                 return;
318         }
319
320         if (_minictrl_is_ongoing(name) == 1) {
321                 type = QP_ITEM_TYPE_MINICTRL_ONGOING;
322         } else {
323                 type = _minictrl_priority_to_type(priority);
324         }
325         qid = quickpanel_list_util_item_new(type, vit);
326         if (!qid) {
327                 ERR("fail to alloc vit");
328                 if (viewer != NULL) {
329                         evas_object_del(viewer);
330                         viewer = NULL;
331                 }
332                 free(vit);
333                 return;
334         }
335         vit->name = strdup(name);
336         vit->width = width;
337         vit->height = height;
338         vit->priority = priority;
339         vit->viewer = viewer;
340         vit->data = data;
341         quickpanel_list_util_item_set_tag(vit->viewer, qid);
342         quickpanel_list_util_sort_insert(ad->list, vit->viewer);
343
344         g_hash_table_insert(g_prov_table, g_strdup(name), vit);
345
346         DBG("success to add minicontrol %s", name);
347         quickpanel_minictrl_rotation_report(ad->angle);
348 }
349
350 static void _minictrl_remove(const char *name, void *data)
351 {
352         if (g_prov_table) {
353                 if (g_hash_table_remove(g_prov_table, name)) {
354                         DBG("success to remove %s", name);
355
356                         retif(data == NULL, , "data is NULL");
357                 } else {
358                         WARN("unknown provider name : %s", name);
359                 }
360         }
361 }
362
363 static void _minictrl_update(const char *name, unsigned int width,
364                                 unsigned int height, void *data)
365 {
366         int old_h = 0;
367         struct appdata *ad = data;
368         struct _viewer_item *found = NULL;
369
370         retif(!g_prov_table, , "data is NULL");
371         retif(!ad, , "data is NULL");
372
373         found = g_hash_table_lookup(g_prov_table, name);
374
375         if (!found) {
376                 WARN("unknown provider name : %s", name);
377                 return;
378         }
379
380         old_h = found->height;
381
382         if (found->viewer) {
383                 if (old_h != height) {
384                         _minictrl_resize_vi(ad->list,
385                                 found, width, height);
386                 } else {
387                         _viewer_set_size(found->viewer, ad, width, height);
388                         quickpanel_uic_initial_resize(found->viewer,
389                                         (height > QP_THEME_LIST_ITEM_MINICONTRL_HEIGHT + QP_THEME_LIST_ITEM_SEPERATOR_HEIGHT)
390                                         ? height : QP_THEME_LIST_ITEM_MINICONTRL_HEIGHT + QP_THEME_LIST_ITEM_SEPERATOR_HEIGHT);
391                 }
392         }
393 }
394
395 static void _minictrl_request(const char *name, int action, int value, void *data)
396 {
397         struct appdata *ad = data;
398         retif(!name, , "name is NULL");
399         retif(!ad, , "data is NULL");
400
401         SDBG("%s %d %d", name, action, value);
402
403         if (action == MINICONTROL_REQ_HIDE_VIEWER) {
404                 quickpanel_uic_close_quickpanel(true, 0);
405         } else if (action == MINICONTROL_REQ_FREEZE_SCROLL_VIEWER) {
406                 if (ad->list != NULL) {
407                         ERR("freezed by %s", name);
408                         _viewer_freeze(ad->scroller);
409                 }
410         } else if (action == MINICONTROL_REQ_UNFREEZE_SCROLL_VIEWER) {
411                 if (ad->list != NULL) {
412                         ERR("unfreezed by %s", name);
413                         _viewer_unfreeze(ad->scroller);
414                 }
415         } 
416 #ifdef HAVE_X
417         else if (action == MINICONTROL_REQ_REPORT_VIEWER_ANGLE) {
418                 if (ad->list != NULL) {
419                         SERR("need to broadcasting angle by %s %d", name, action);
420                         quickpanel_minictrl_rotation_report(ad->angle);
421                 }
422         }
423 #endif
424 }
425
426 static void _mctrl_monitor_cb(minicontrol_action_e action,
427                                 const char *name, unsigned int width,
428                                 unsigned int height,
429                                 minicontrol_priority_e priority,
430                                 void *data)
431 {
432         retif(!data, , "data is NULL");
433         retif(!name, , "name is NULL");
434
435         if (_viewer_check(name) == 0) {
436                 ERR("%s: ignored", name);
437                 return;
438         }
439
440         switch (action) {
441         case MINICONTROL_ACTION_START:
442                 _minictrl_add(name, width, height, priority, data);
443                 break;
444         case MINICONTROL_ACTION_RESIZE:
445                 _minictrl_update(name, width, height, data);
446                 break;
447         case MINICONTROL_ACTION_STOP:
448                 _minictrl_remove(name, data);
449                 break;
450         case MINICONTROL_ACTION_REQUEST:
451                 _minictrl_request(name, width, height, data);
452                 break;
453         default:
454                 break;
455         }
456 }
457
458 static void _minictrl_resize_vi(Evas_Object *list,
459                                         struct _viewer_item *item, int to_w, int to_h)
460 {
461         QP_VI *vi = NULL;
462         retif(list == NULL, , "invalid parameter");
463         retif(item == NULL, , "invalid parameter");
464
465         vi = quickpanel_vi_new_with_data(
466                         VI_OP_RESIZE,
467                         QP_ITEM_TYPE_MINICTRL_MIDDLE,
468                         list,
469                         item->viewer,
470                         _anim_init_cb,
471                         _anim_job_cb,
472                         _anim_done_cb,
473                         _anim_done_cb,
474                         vi,
475                         item,
476                         to_w,
477                         to_h);
478         quickpanel_vi_start(vi);
479 }
480
481 static void _anim_init_resize(void *data)
482 {
483         QP_VI *vi = data;
484         retif(vi == NULL, , "invalid parameter");
485         retif(vi->target == NULL, , "invalid parameter");
486
487         Evas_Object *item = vi->target;
488         evas_object_color_set(item, 0, 0, 0, 0);
489 }
490
491 static void _reorder_transit_del_cb(void *data, Elm_Transit *transit)
492 {
493         QP_VI *vi = data;
494         int to_w = 0, to_h = 0;
495         Evas_Object *item = NULL;
496         retif(vi == NULL, , "data is NULL");
497         retif(vi->target == NULL, , "invalid parameter");
498
499         item = vi->target;
500         to_w = vi->extra_flag_1;
501         to_h = vi->extra_flag_2;
502
503         struct appdata *ad = quickpanel_get_app_data();
504         retif(ad == NULL, , "Invalid parameter!");
505
506         _viewer_set_size(item, ad, to_w, to_h);
507         quickpanel_uic_initial_resize(item,
508                         (to_h > QP_THEME_LIST_ITEM_MINICONTRL_HEIGHT + QP_THEME_LIST_ITEM_SEPERATOR_HEIGHT)
509                         ? to_h : QP_THEME_LIST_ITEM_MINICONTRL_HEIGHT + QP_THEME_LIST_ITEM_SEPERATOR_HEIGHT);
510 }
511
512 static void _anim_job_resize(void *data)
513 {
514         QP_VI *vi = data;
515         int to_w = 0, to_h = 0;
516         Elm_Transit *transit_layout_parent = NULL;
517         Elm_Transit *transit_fadein = NULL;
518         Evas_Object *item = NULL;
519         struct _viewer_item *viewer_item = NULL;
520
521         struct appdata *ad = quickpanel_get_app_data();
522         retif(ad == NULL, , "Invalid parameter!");
523         retif(vi == NULL, , "invalid parameter");
524         retif(vi->target == NULL, , "invalid parameter");
525         retif(vi->extra_data_2 == NULL, , "invalid parameter");
526
527         item = vi->target;
528         to_w = vi->extra_flag_1;
529         to_h = vi->extra_flag_2;
530         viewer_item = vi->extra_data_2;
531
532         transit_layout_parent = quickpanel_list_util_get_reorder_transit(viewer_item->viewer, NULL, to_h - viewer_item->height);
533         if (transit_layout_parent != NULL) {
534                 elm_transit_del_cb_set(transit_layout_parent, _reorder_transit_del_cb, vi);
535         } else {
536                 _viewer_set_size(item, ad, to_w, to_h);
537                 quickpanel_uic_initial_resize(item,
538                                 (to_h > QP_THEME_LIST_ITEM_MINICONTRL_HEIGHT + QP_THEME_LIST_ITEM_SEPERATOR_HEIGHT)
539                                 ? to_h : QP_THEME_LIST_ITEM_MINICONTRL_HEIGHT + QP_THEME_LIST_ITEM_SEPERATOR_HEIGHT);
540         }
541
542         transit_fadein = elm_transit_add();
543         if (transit_fadein != NULL) {
544                 elm_transit_object_add(transit_fadein, item);
545                 elm_transit_effect_color_add(transit_fadein, 0, 0, 0, 0, 255, 255, 255, 255);
546                 elm_transit_duration_set(transit_fadein, 0.35);
547                 elm_transit_tween_mode_set(transit_fadein,
548                                 quickpanel_vim_get_tweenmode(VI_OP_INSERT));
549                 elm_transit_del_cb_set(transit_fadein, quickpanel_vi_done_cb_for_transit, vi);
550                 elm_transit_objects_final_state_keep_set(transit_fadein, EINA_TRUE);
551
552                 if (transit_layout_parent != NULL) {
553                         elm_transit_chain_transit_add(transit_layout_parent, transit_fadein);
554                         elm_transit_go(transit_layout_parent);
555                 } else {
556                         elm_transit_go(transit_fadein);
557                 }
558         } else {
559                 ERR("Failed to create all the transit");
560                 quickpanel_vi_done(vi);
561         }
562 }
563
564 static void _anim_done_resize(void *data)
565 {
566         QP_VI *vi = data;
567         struct _viewer_item *viewer_item = NULL;
568         struct appdata *ad = quickpanel_get_app_data();
569         retif(ad == NULL, , "Invalid parameter!");
570         retif(vi == NULL, , "invalid parameter");
571         retif(vi->target == NULL, , "invalid parameter");
572
573         Evas_Object *item = vi->target;
574         viewer_item = vi->extra_data_2;
575
576         viewer_item->width = vi->extra_flag_1;
577         viewer_item->height = vi->extra_flag_2;
578
579         _viewer_set_size(item, ad, viewer_item->width, viewer_item->height);
580         quickpanel_uic_initial_resize(item,
581                         (viewer_item->height > QP_THEME_LIST_ITEM_MINICONTRL_HEIGHT + QP_THEME_LIST_ITEM_SEPERATOR_HEIGHT)
582                         ? viewer_item->height : QP_THEME_LIST_ITEM_MINICONTRL_HEIGHT + QP_THEME_LIST_ITEM_SEPERATOR_HEIGHT);
583         evas_object_color_set(item, 255, 255, 255, 255);
584 }
585
586 static Eina_Bool _anim_init_cb(void *data)
587 {
588         QP_VI *vi = data;
589         retif(vi == NULL, EINA_FALSE, "invalid parameter");
590
591         static qp_vi_op_table anim_init_table[] = {
592                 {
593                         .op_type = VI_OP_RESIZE,
594                         .handler = _anim_init_resize,
595                 },
596                 {
597                         .op_type = VI_OP_NONE,
598                         .handler = NULL,
599                 },
600         };
601
602         int i = 0;
603         for (i = 0; anim_init_table[i].op_type != VI_OP_NONE; i++) {
604                 if (anim_init_table[i].op_type != vi->op_type) {
605                         continue;
606                 }
607
608                 anim_init_table[i].handler(vi);
609                 break;
610         }
611
612         return EINA_TRUE;
613 }
614
615 static Eina_Bool _anim_job_cb(void *data)
616 {
617         QP_VI *vi = data;
618         retif(vi == NULL, EINA_FALSE, "invalid parameter");
619
620         static qp_vi_op_table anim_job_table[] = {
621                 {
622                         .op_type = VI_OP_RESIZE,
623                         .handler = _anim_job_resize,
624                 },
625                 {
626                         .op_type = VI_OP_NONE,
627                         .handler = NULL,
628                 },
629         };
630
631         int i = 0;
632         for (i = 0; anim_job_table[i].op_type != VI_OP_NONE; i++) {
633                 if (anim_job_table[i].op_type != vi->op_type) {
634                         continue;
635                 }
636
637                 anim_job_table[i].handler(vi);
638                 break;
639         }
640
641         return EINA_TRUE;
642 }
643
644 static Eina_Bool _anim_done_cb(void *data)
645 {
646         QP_VI *vi = data;
647         retif(vi == NULL, EINA_FALSE, "invalid parameter");
648
649         static qp_vi_op_table anim_done_table[] = {
650                 {
651                         .op_type = VI_OP_RESIZE,
652                         .handler = _anim_done_resize,
653                 },
654                 {
655                         .op_type = VI_OP_NONE,
656                         .handler = NULL,
657                 },
658         };
659
660         int i = 0;
661         for (i = 0; anim_done_table[i].op_type != VI_OP_NONE; i++) {
662                 if (anim_done_table[i].op_type != vi->op_type) {
663                         continue;
664                 }
665
666                 anim_done_table[i].handler(vi);
667                 break;
668         }
669
670         return EINA_TRUE;
671 }
672
673 static int _init(void *data)
674 {
675         minicontrol_error_e ret;
676
677         retif(!data, QP_FAIL, "Invalid parameter!");
678
679         g_prov_table = g_hash_table_new_full(g_str_hash, g_str_equal,
680                                         (GDestroyNotify)g_free,
681                                         (GDestroyNotify)_viewer_item_free);
682
683         ret = minicontrol_monitor_start(_mctrl_monitor_cb, data);
684         if (ret != MINICONTROL_ERROR_NONE) {
685                 ERR("fail to minicontrol_monitor_start()- %d", ret);
686                 return QP_FAIL;
687         }
688
689         return QP_OK;
690 }
691
692 static int _fini(void *data)
693 {
694         minicontrol_error_e ret;
695         ret = minicontrol_monitor_stop();
696         if (ret != MINICONTROL_ERROR_NONE) {
697                 ERR("fail to minicontrol_monitor_stop()- %d", ret);
698         }
699
700         if (g_prov_table) {
701                 g_hash_table_remove_all(g_prov_table);
702                 g_prov_table = NULL;
703         }
704
705         return QP_OK;
706 }
707
708 static int _suspend(void *data)
709 {
710         struct appdata *ad = data;
711         retif(ad == NULL, QP_FAIL, "Invalid parameter!");
712
713         if (ad->list != NULL) {
714                 _viewer_unfreeze(ad->scroller);
715         }
716
717         return QP_OK;
718 }
719
720 static int _resume(void *data)
721 {
722         struct appdata *ad = data;
723         retif(ad == NULL, QP_FAIL, "Invalid parameter!");
724
725         if (ad->list != NULL) {
726                 _viewer_unfreeze(ad->scroller);
727         }
728
729         return QP_OK;
730 }
731
732 HAPI void quickpanel_minictrl_rotation_report(int angle)
733 {
734         if (g_prov_table != NULL) {
735                 if (g_hash_table_size(g_prov_table) > 0) {
736                         SINFO("minicontrol rotation:%d", angle);
737 #ifdef HAVE_X
738                         minicontrol_viewer_request(QP_PKG_QUICKPANEL,
739                                         MINICONTROL_REQ_ROTATE_PROVIDER, angle);
740 #endif
741                 }
742         }
743 }