60952dfe94c41b612cc705d7b3ea0e1a49b72fa4
[apps/core/preloaded/quickpanel.git] / daemon / notifications / ticker.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 <Elementary.h>
18 #include <Ecore_X.h>
19 #include <appcore-common.h>
20 #include <vconf.h>
21 #include <appsvc.h>
22 #include <app_service.h>
23 #include <notification.h>
24 #include <time.h>
25 #include <feedback.h>
26
27 #include "quickpanel-ui.h"
28 #include "common.h"
29 #include "noti_win.h"
30
31 #define QP_TICKER_DURATION      5
32 #define QP_TICKER_DETAIL_DURATION 6
33
34 #define TICKER_MSG_LEN                          1024
35 #define DEFAULT_ICON ICONDIR            "/quickpanel_icon_default.png"
36
37 static Evas_Object *g_window;
38 static Evas_Object *g_ticker;
39 static Ecore_Timer *g_timer;
40 static int g_noti_height;
41
42 static int quickpanel_ticker_init(void *data);
43 static int quickpanel_ticker_fini(void *data);
44 static int quickpanel_ticker_enter_hib(void *data);
45 static int quickpanel_ticker_leave_hib(void *data);
46 static void quickpanel_ticker_reflesh(void *data);
47
48 QP_Module ticker = {
49         .name = "ticker",
50         .init = quickpanel_ticker_init,
51         .fini = quickpanel_ticker_fini,
52         .hib_enter = quickpanel_ticker_enter_hib,
53         .hib_leave = quickpanel_ticker_leave_hib,
54         .lang_changed = NULL,
55         .refresh = quickpanel_ticker_reflesh
56 };
57
58 static int latest_inserted_time;
59
60 /*****************************************************************************
61  *
62  * (Static) Util functions
63  *
64  *****************************************************************************/
65
66 static int _quickpanel_ticker_check_ticker_off(notification_h noti)
67 {
68         char *pkgname = NULL;
69         int ret = 0;
70         int boolval = 0;
71
72         notification_get_application(noti, &pkgname);
73
74         if (pkgname == NULL)
75                 notification_get_pkgname(noti, &pkgname);
76
77         if (pkgname == NULL)
78                 return 1;       /* Ticker is not displaying. */
79
80         if (!strcmp(pkgname, VENDOR".message")) {
81                 ret = vconf_get_bool(
82                         VCONFKEY_SETAPPL_STATE_TICKER_NOTI_MESSAGES_BOOL,
83                         &boolval);
84                 if (ret == 0 && boolval == 0)
85                         return 1;
86         } else if (!strcmp(pkgname, VENDOR".email")) {
87                 ret = vconf_get_bool(
88                         VCONFKEY_SETAPPL_STATE_TICKER_NOTI_EMAIL_BOOL,
89                         &boolval);
90                 if (ret == 0 && boolval == 0)
91                         return 1;
92         } else if (!strcmp(pkgname, VENDOR".ims-syspopup")) {
93                 ret = vconf_get_bool(
94                                 VCONFKEY_SETAPPL_STATE_TICKER_NOTI_IM_BOOL,
95                         &boolval);
96                 if (ret == 0 && boolval == 0)
97                         return 1;
98         }
99
100         /* Displaying ticker! */
101         return 0;
102 }
103
104 static int _quickpanel_ticker_check_displaying_contents_off(notification_h noti)
105 {
106         char *pkgname = NULL;
107         int ret = 0;
108         int boolval = 0;
109
110         notification_get_application(noti, &pkgname);
111
112         if (pkgname == NULL)
113                 notification_get_pkgname(noti, &pkgname);
114
115         if (pkgname == NULL)
116                 return 0;       /* Ticker is not displaying. */
117
118         if (!strcmp(pkgname, VENDOR".message")) {
119                 ret = vconf_get_bool(
120                         VCONFKEY_TICKER_NOTI_DISPLAY_CONTENT_MESSASGES,
121                         &boolval);
122                 if (ret == 0 && boolval == 0)
123                         return 1;
124         } else if (!strcmp(pkgname, VENDOR".email")) {
125                 ret = vconf_get_bool(
126                         VCONFKEY_TICKER_NOTI_DISPLAY_CONTENT_EMAIL,
127                         &boolval);
128                 if (ret == 0 && boolval == 0)
129                         return 1;
130         } else if (!strcmp(pkgname, VENDOR".ims-syspopup")) {
131                 ret = vconf_get_bool(
132                         VCONFKEY_TICKER_NOTI_DISPLAY_CONTENT_IM,
133                         &boolval);
134                 if (ret == 0 && boolval == 0)
135                         return 1;
136         }
137
138         /* Displaying ticker! */
139         return 0;
140 }
141
142 static inline void __ticker_only_noti_del(notification_h noti)
143 {
144         int applist = NOTIFICATION_DISPLAY_APP_ALL;
145
146         retif(noti == NULL, ,"noti is null");
147
148         notification_get_display_applist(noti, &applist);
149         if (applist & NOTIFICATION_DISPLAY_APP_TICKER) {
150                 if (!(applist & NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY)) {
151                         char *pkgname = NULL;
152                         int priv_id = 0;
153
154                         notification_get_pkgname(noti, &pkgname);
155                         notification_get_id(noti, NULL, &priv_id);
156                         notification_delete_by_priv_id(pkgname,
157                                                 NOTIFICATION_TYPE_NONE,
158                                                 priv_id);
159                 }
160         }
161 }
162
163 static void _quickpanel_ticker_hide(void *data)
164 {
165         if (g_ticker) {
166                 evas_object_hide(g_ticker);
167                 evas_object_del(g_ticker);
168                 g_ticker = NULL;
169         }
170 }
171
172 static Eina_Bool _quickpanel_ticker_timeout_cb(void *data)
173 {
174         DBG("");
175
176         g_timer = NULL;
177
178         _quickpanel_ticker_hide(data);
179
180         return ECORE_CALLBACK_CANCEL;
181 }
182
183 static void _quickpanel_ticker_detail_hide_cb(void *data, Evas *e,
184                                         Evas_Object *obj,
185                                         void *event_info)
186 {
187         DBG("");
188         notification_h noti = (notification_h) data;
189
190         if (g_timer) {
191                 ecore_timer_del(g_timer);
192                 g_timer = NULL;
193         }
194
195         retif(noti == NULL, , "Invalid parameter!");
196
197         __ticker_only_noti_del(noti);
198         notification_free(noti);
199 }
200
201 static void _quickpanel_ticker_detail_show_cb(void *data, Evas *e,
202                                         Evas_Object *obj,
203                                         void *event_info)
204 {
205         DBG("");
206 }
207
208 static void _quickpanel_ticker_clicked_cb(void *data, Evas_Object *obj,
209                                         void *event_info)
210 {
211         notification_h noti = (notification_h) data;
212         char *caller_pkgname = NULL;
213         char *pkgname = NULL;
214         bundle *args = NULL;
215         bundle *single_service_handle = NULL;
216         int priv_id = 0;
217         int flags = 0;
218         int ret = 0;
219         int val = 0;
220         int flag_launch = 0;
221         int flag_delete = 0;
222         int type = NOTIFICATION_TYPE_NONE;
223
224         DBG("");
225
226         retif(noti == NULL, , "Invalid parameter!");
227
228         /* Check idle lock state */
229         ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &val);
230
231         /* If Lock state, there is not any action when clicked. */
232         if (ret != 0 || val == VCONFKEY_IDLE_LOCK)
233                 return;
234
235         notification_get_pkgname(noti, &caller_pkgname);
236         notification_get_application(noti, &pkgname);
237         if (pkgname == NULL)
238                 pkgname = caller_pkgname;
239
240         notification_get_id(noti, NULL, &priv_id);
241         notification_get_property(noti, &flags);
242         notification_get_type(noti, &type);
243
244         if (flags & NOTIFICATION_PROP_DISABLE_APP_LAUNCH)
245                 flag_launch = 0;
246         else
247                 flag_launch = 1;
248
249         if (flags & NOTIFICATION_PROP_DISABLE_AUTO_DELETE)
250                 flag_delete = 0;
251         else
252                 flag_delete = 1;
253
254         notification_get_execute_option(noti,
255                                 NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH,
256                                 NULL, &single_service_handle);
257
258         if (flag_launch == 1) {
259                 if (single_service_handle != NULL)
260                         appsvc_run_service(single_service_handle, 0, NULL,
261                                            NULL);
262                 else {
263                         notification_get_args(noti, &args, NULL);
264                         quickpanel_launch_app(pkgname, args);
265                 }
266
267                 /* Hide quickpanel */
268                 Ecore_X_Window zone;
269                 zone = ecore_x_e_illume_zone_get(elm_win_xwindow_get(g_window));
270                 ecore_x_e_illume_quickpanel_state_send(zone,
271                                 ECORE_X_ILLUME_QUICKPANEL_STATE_OFF);
272         }
273
274         if (flag_delete == 1 && type == NOTIFICATION_TYPE_NOTI) {
275                 notification_delete_by_priv_id(caller_pkgname,
276                                                 NOTIFICATION_TYPE_NOTI,
277                                                 priv_id);
278         }
279 }
280
281 static void _quickpanel_ticker_button_clicked_cb(void *data, Evas_Object *obj,
282                                         void *event_info)
283 {
284         DBG("");
285
286         if (g_timer) {
287                 ecore_timer_del(g_timer);
288                 g_timer = NULL;
289         }
290
291         _quickpanel_ticker_hide(data);
292 }
293
294 static Evas_Object *_quickpanel_ticker_create_button(Evas_Object *parent,
295                                                 notification_h noti)
296 {
297         Evas_Object *button = NULL;
298         int ret = 0;
299         int val = 0;
300
301         retif(noti == NULL || parent == NULL, NULL, "Invalid parameter!");
302
303         /* Check idle lock state */
304         ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &val);
305         /* If Lock state, button is diabled */
306         if (ret != 0 || val == VCONFKEY_IDLE_LOCK)
307                 return NULL;
308
309         button = elm_button_add(parent);
310         elm_object_style_set(button, "tickernoti");
311         elm_object_text_set(button, _S("IDS_COM_BODY_CLOSE"));
312         evas_object_smart_callback_add(button, "clicked",
313                                 _quickpanel_ticker_button_clicked_cb, noti);
314
315         return button;
316 }
317
318 static Evas_Object *_quickpanel_ticker_create_icon(Evas_Object *parent,
319                                                 notification_h noti)
320 {
321         char *icon_path = NULL;
322         Evas_Object *icon = NULL;
323
324         retif(noti == NULL || parent == NULL, NULL, "Invalid parameter!");
325
326         notification_get_image(noti, NOTIFICATION_IMAGE_TYPE_ICON, &icon_path);
327         icon = elm_image_add(parent);
328
329         if (icon_path == NULL
330             || (elm_image_file_set(icon, icon_path, NULL) == EINA_FALSE)) {
331                 elm_image_file_set(icon, DEFAULT_ICON, NULL);
332                 elm_image_resizable_set(icon, EINA_TRUE, EINA_TRUE);
333         }
334
335         return icon;
336 }
337
338 static char *_quickpanel_ticker_get_label(notification_h noti)
339 {
340         char buf[TICKER_MSG_LEN] = { 0, };
341         int len = 0;
342         char *domain = NULL;
343         char *dir = NULL;
344         char *result_title = NULL;
345         char *result_content = NULL;
346         char *title_utf8 = NULL;
347         char *content_utf8 = NULL;
348         notification_error_e noti_err = NOTIFICATION_ERROR_NONE;
349
350         retif(noti == NULL, NULL, "Invalid parameter!");
351
352         notification_get_text_domain(noti, &domain, &dir);
353         if (domain != NULL && dir != NULL)
354                 bindtextdomain(domain, dir);
355
356         noti_err = notification_get_text(noti, NOTIFICATION_TEXT_TYPE_TITLE,
357                         &result_title);
358         if (noti_err == NOTIFICATION_ERROR_NONE && result_title)
359                 title_utf8 = elm_entry_utf8_to_markup(result_title);
360
361         if (_quickpanel_ticker_check_displaying_contents_off(noti) == 1) {
362                 noti_err = notification_get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT_FOR_DISPLAY_OPTION_IS_OFF,
363                                 &result_content);
364         }
365         else {
366                 noti_err = notification_get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT,
367                                 &result_content);
368         }
369
370         if (noti_err == NOTIFICATION_ERROR_NONE && result_content)
371                 content_utf8 = elm_entry_utf8_to_markup(result_content);
372
373         if (title_utf8 && content_utf8) {
374                 len = snprintf(buf, sizeof(buf),
375                         "<font_size=26><color=#BABABA>%s</color></font>"
376                         "<br><font_size=29><color=#F4F4F4>%s</color></font>",
377                         title_utf8, content_utf8);
378         } else if (title_utf8) {
379                 len = snprintf(buf, sizeof(buf),
380                         "<font_size=29><color=#BABABA>%s</color></font>",
381                         title_utf8);
382         }
383
384         if (title_utf8)
385                 free(title_utf8);
386
387         if (content_utf8)
388                 free(content_utf8);
389
390         if (len > 0)
391                 return strdup(buf);
392
393         return NULL;
394 }
395
396 static void _noti_hide_cb(void *data, Evas_Object *obj,
397                         const char *emission, const char *source)
398 {
399         DBG("");
400
401         if (g_timer) {
402                 ecore_timer_del(g_timer);
403                 g_timer = NULL;
404         }
405
406         _quickpanel_ticker_hide(data);
407 }
408
409 static Evas_Object *_quickpanel_ticker_create_tickernoti(void *data)
410 {
411         notification_h noti = (notification_h) data;
412         Evas_Object *tickernoti = NULL;
413         Evas_Object *icon = NULL;
414         Evas_Object *detail = NULL;
415         Evas_Object *button = NULL;
416         char *buf = NULL;
417         const char *data_win_height = NULL;
418         int noti_height = 0;
419
420         retif(noti == NULL, NULL, "Invalid parameter!");
421
422         tickernoti = noti_win_add(NULL);
423         retif(tickernoti == NULL, NULL, "Failed to add elm tickernoti.");
424
425         detail = elm_layout_add(tickernoti);
426         if (!detail) {
427                 ERR("Failed to get detailview.");
428                 evas_object_del(tickernoti);
429                 return NULL;
430         }
431         elm_layout_theme_set(detail, "tickernoti", "base", "default");
432         elm_object_signal_callback_add(detail, "request,hide", "",
433                                 _noti_hide_cb, noti);
434
435         data_win_height = (char *)elm_layout_data_get(detail, "height");
436         if (data_win_height != NULL && elm_config_scale_get() > 0.0)
437                 noti_height = (int)(elm_config_scale_get()
438                                         * atoi(data_win_height));
439         evas_object_size_hint_min_set(detail, 1, noti_height);
440         g_noti_height = noti_height;
441
442         noti_win_content_set(tickernoti, detail);
443
444         icon = _quickpanel_ticker_create_icon(detail, noti);
445         if (icon != NULL)
446                 elm_object_part_content_set(detail, "icon", icon);
447
448         button = _quickpanel_ticker_create_button(detail, noti);
449         if (button != NULL)
450                 elm_object_part_content_set(detail, "button", button);
451
452         buf = _quickpanel_ticker_get_label(noti);
453         if (buf != NULL) {
454                 elm_object_part_text_set(detail, "elm.text", buf);
455                 free(buf);
456         }
457
458         /* Use style "default" for detailview mode and
459          * "info" for text only mode
460          */
461         elm_object_style_set(tickernoti, "default");
462
463         return tickernoti;
464 }
465
466 static int _quickpanel_ticker_get_angle(void *data)
467 {
468         struct appdata *ad = (struct appdata *)data;
469         Ecore_X_Window xwin, root;
470         int ret = 0, angle = 0, count = 0;
471         unsigned char *prop_data = NULL;
472
473         xwin = elm_win_xwindow_get(ad->win);
474         root = ecore_x_window_root_get(xwin);
475
476         ret = ecore_x_window_prop_property_get(root,
477                                 ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE,
478                                 ECORE_X_ATOM_CARDINAL, 32,
479                                 &prop_data, &count);
480
481         if (ret && prop_data) {
482                 memcpy(&angle, prop_data, sizeof(int));
483
484                 if (prop_data)
485                         free(prop_data);
486
487                 return angle;
488         } else {
489                 ERR("Fail to get angle");
490                 if (prop_data)
491                         free(prop_data);
492
493                 return -1;
494         }
495 }
496
497 static void _quickpanel_ticker_update_geometry_on_rotation(void *data, int *x, int *y, int *w, int *h) {
498         int angle = 0;
499
500         if (!data)
501                 return;
502         angle = _quickpanel_ticker_get_angle(data);
503         Evas_Coord root_w, root_h;
504
505         /*
506          * manually calculate win_tickernoti_indi window position & size
507          *  - win_indi is not full size window
508          */
509         ecore_x_window_size_get(ecore_x_window_root_first_get(), &root_w, &root_h);
510
511         // rotate win
512         switch(angle)
513         {
514                 case 90:
515                         *w = g_noti_height;
516                         *h = root_h;
517                         break;
518                 case 270:
519                         *w = g_noti_height;
520                         *h = root_h;
521                         *x = root_w - g_noti_height;
522                         break;
523                 case 180:
524                         *w = root_w;
525                         *h = g_noti_height;
526                         *y = root_h - g_noti_height;
527                         break;
528                 case 0:
529                 default:
530                         *w = root_w;
531                         *h = g_noti_height;
532                         break;
533         }
534         elm_win_rotation_set(g_ticker, angle);
535 }
536
537 static void _quickpanel_ticker_win_rotated(void *data) {
538         retif(data == NULL, ,"data is NULL");
539         struct appdata *ad = data;
540         int x = 0, y = 0, w = 0, h = 0;
541
542         _quickpanel_ticker_update_geometry_on_rotation(ad, &x, &y, &w, &h);
543
544         if (g_ticker != NULL) {
545                 evas_object_move(g_ticker, x, y);
546                 evas_object_resize(g_ticker, w, h);
547         }
548 }
549
550 static void _quickpanel_ticker_noti_detailed_changed_cb(void *data, notification_type_e type, notification_op *op_list, int num_op)
551 {
552         notification_h noti = NULL;
553         int flags = 0;
554         int applist = NOTIFICATION_DISPLAY_APP_ALL;
555         int ret = 0;
556         int op_type = 0;
557         int priv_id = 0;
558
559         INFO("_quickpanel_ticker_noti_changed_cb");
560
561         retif(op_list == NULL, ,"op_list is NULL");
562
563         if (num_op == 1) {
564                 notification_op_get_data(op_list, NOTIFICATION_OP_DATA_TYPE, &op_type);
565                 notification_op_get_data(op_list, NOTIFICATION_OP_DATA_PRIV_ID, &priv_id);
566                 DBG("op_type:%d", op_type);
567                 DBG("op_priv_id:%d", priv_id);
568
569                 if (op_type == NOTIFICATION_OP_INSERT) {
570                         noti = notification_load(NULL, priv_id);
571                 } else if (op_type == NOTIFICATION_OP_UPDATE) {
572                         noti = notification_load(NULL, priv_id);
573                 } else {
574                         return ;
575                 }
576         } else {
577                 return ;
578         }
579
580         retif(noti == NULL, ,"noti is NULL");
581
582         notification_get_display_applist(noti, &applist);
583         if (!(applist & NOTIFICATION_DISPLAY_APP_TICKER)) {
584                 DBG("No Ticker Msg");
585                 notification_free(noti);
586                 return ;
587         }
588
589         /* Check setting's event notification */
590         ret = _quickpanel_ticker_check_ticker_off(noti);
591         if (ret == 1) {
592                 INFO("Disable tickernoti ret : %d", ret);
593                 /* delete temporary here only ticker noti display item */
594                 __ticker_only_noti_del(noti);
595                 notification_free(noti);
596
597                 return;
598         }
599
600         /* Play sound */
601         notification_sound_type_e nsound_type = NOTIFICATION_SOUND_TYPE_NONE;
602         const char *nsound_path = NULL;
603
604         notification_get_sound(noti, &nsound_type, &nsound_path);
605         DBG("Sound : %d, %s", nsound_type, nsound_path);
606         if (nsound_type > NOTIFICATION_SOUND_TYPE_NONE
607             || nsound_type < NOTIFICATION_SOUND_TYPE_MAX) {
608
609                 switch (nsound_type) {
610                 case NOTIFICATION_SOUND_TYPE_DEFAULT:
611                         feedback_play_type(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_UNLOCK);
612                         break;
613                 case NOTIFICATION_SOUND_TYPE_USER_DATA:
614                         quickpanel_player_play(SOUND_TYPE_NOTIFICATION, nsound_path);
615                         break;
616                 default:
617                         break;
618                 }
619         }
620         /* Play Vibration */
621         notification_vibration_type_e nvibration_type =
622             NOTIFICATION_VIBRATION_TYPE_NONE;
623         const char *nvibration_path = NULL;
624
625         notification_get_vibration(noti, &nvibration_type, &nvibration_path);
626         DBG("Vibration : %d, %s", nvibration_type, nvibration_path);
627         if (nvibration_type > NOTIFICATION_VIBRATION_TYPE_NONE
628             || nvibration_type < NOTIFICATION_VIBRATION_TYPE_MAX) {
629
630                 switch (nvibration_type) {
631                 case NOTIFICATION_SOUND_TYPE_DEFAULT:
632                         feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_GENERAL);
633                         break;
634                 case NOTIFICATION_SOUND_TYPE_USER_DATA:
635                         break;
636                 default:
637                         break;
638                 }
639         }
640
641         /* Skip if previous ticker is still shown */
642         if (g_ticker != NULL) {
643                 _quickpanel_ticker_hide(NULL);
644         }
645
646         /* Check tickernoti flag */
647         notification_get_property(noti, &flags);
648
649         if (flags & NOTIFICATION_PROP_DISABLE_TICKERNOTI) {
650                 INFO("NOTIFICATION_PROP_DISABLE_TICKERNOTI");
651                 __ticker_only_noti_del(noti);
652                 notification_free(noti);
653         } else if (applist & NOTIFICATION_DISPLAY_APP_TICKER) {
654                 /* Display ticker */
655                 if (g_timer)
656                         ecore_timer_del(g_timer);
657
658                 g_ticker = _quickpanel_ticker_create_tickernoti(noti);
659                 if (g_ticker == NULL) {
660                         ERR("Fail to create tickernoti");
661                         __ticker_only_noti_del(noti);
662                         notification_free(noti);
663                         return;
664                 }
665
666                 g_timer = ecore_timer_add(QP_TICKER_DURATION,
667                                 _quickpanel_ticker_timeout_cb, noti);
668
669                 _quickpanel_ticker_win_rotated(data);
670                 evas_object_show(g_ticker);
671
672                 evas_object_event_callback_add(g_ticker, EVAS_CALLBACK_SHOW,
673                                         _quickpanel_ticker_detail_show_cb,
674                                         g_ticker);
675                 evas_object_event_callback_add(g_ticker, EVAS_CALLBACK_HIDE,
676                                         _quickpanel_ticker_detail_hide_cb,
677                                         noti);
678                 evas_object_smart_callback_add(g_ticker, "clicked",
679                                         _quickpanel_ticker_clicked_cb,
680                                         noti);
681         }
682 }
683
684 /*****************************************************************************
685  *
686  * Util functions
687  *
688  *****************************************************************************/
689 static int quickpanel_ticker_init(void *data)
690 {
691         struct appdata *ad = (struct appdata *)data;
692
693         latest_inserted_time = time(NULL);
694         g_window = ad->win;
695
696         notification_register_detailed_changed_cb(_quickpanel_ticker_noti_detailed_changed_cb,
697                                         data);
698
699         return QP_OK;
700 }
701
702 static int quickpanel_ticker_fini(void *data)
703 {
704         _quickpanel_ticker_hide(NULL);
705
706         return QP_OK;
707 }
708
709 static int quickpanel_ticker_enter_hib(void *data)
710 {
711         return QP_OK;
712 }
713
714 static int quickpanel_ticker_leave_hib(void *data)
715 {
716         return QP_OK;
717 }
718
719 static void quickpanel_ticker_reflesh(void *data)
720 {
721         retif(data == NULL, , "Invalid parameter!");
722
723         if (g_ticker != NULL) {
724                 _quickpanel_ticker_win_rotated(data);
725         }
726 }