f75fa091e456cbdc06a0a69ead89bcab4ebe7cf9
[apps/home/quickpanel.git] / daemon / notifications / ticker.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 <Elementary.h>
20 #include <Ecore_X.h>
21 #include <appcore-common.h>
22 #include <vconf.h>
23 #include <app_control.h>
24 #include <notification.h>
25 #include <feedback.h>
26
27 #include "quickpanel-ui.h"
28 #include "common.h"
29 #include "noti.h"
30 #include "noti_win.h"
31 #include "noti_util.h"
32 #ifdef QP_EMERGENCY_MODE_ENABLE
33 #include "emergency_mode.h"
34 #endif
35 #include "animated_icon.h"
36
37 #define QP_TICKER_DURATION      3
38 #define QP_TICKER_DETAIL_DURATION 6
39
40 #define TICKER_MSG_LEN                          1024
41 #define DEFAULT_ICON ICONDIR            "/quickpanel_icon_default.png"
42
43 #define E_DATA_IS_TICKERNOTI_CONTENT "E_DATA_TN_CONTENT"
44 #define E_DATA_IS_TICKERNOTI_EXECUTED "E_DATA_TN_EXECUTED"
45
46 #define FORMAT_1LINE "<font_size=29><color=#F4F4F4FF>%s</color></font_size>"
47 #define FORMAT_2LINE "<font_size=26><color=#BABABAFF>%s</color></font_size><br/><font_size=29><color=#F4F4F4FF>%s</color></font_size>"
48
49 static Evas_Object *g_window = NULL;
50 static Evas_Object *g_ticker = NULL;
51 static Evas_Object *g_scroller = NULL;
52 static Ecore_Timer *g_timer = NULL;
53 static Eina_List *ticker_list = NULL;
54
55 static int quickpanel_ticker_init(void *data);
56 static int quickpanel_ticker_fini(void *data);
57 static int quickpanel_ticker_enter_hib(void *data);
58 static int quickpanel_ticker_leave_hib(void *data);
59 static void quickpanel_ticker_reflesh(void *data);
60 static void _quickpanel_ticker_destroy_tickernoti(Evas_Object *tickernoti);
61 static void _quickpanel_ticker_create_tickernoti(void *data);
62 static void _quickpanel_ticker_win_rotated(void *data, int need_hide);
63
64 QP_Module ticker = {
65         .name = "ticker",
66         .init = quickpanel_ticker_init,
67         .fini = quickpanel_ticker_fini,
68         .hib_enter = quickpanel_ticker_enter_hib,
69         .hib_leave = quickpanel_ticker_leave_hib,
70         .lang_changed = NULL,
71         .refresh = quickpanel_ticker_reflesh
72 };
73
74 static inline int _is_text_exist(const char *text) {
75         if (text != NULL) {
76                 if (strlen(text) > 0) {
77                         if (strcmp(text, "") != 0) {
78                                 return 1;
79                         }
80                 }
81         }
82
83         return 0;
84 }
85
86 static int _is_sound_playable(void) {
87         int status = 0, ret = 0;
88
89         ret = vconf_get_int(VCONFKEY_CAMERA_STATE, &status);
90         if (ret == 0 && status == VCONFKEY_CAMERA_STATE_RECORDING) {
91                 ERR("camcorder is working, don't play notification sound %d %d", ret, status);
92                 return 0;
93         }
94
95 #ifdef TBD
96         if ((ret = sound_manager_get_current_sound_type(&type))
97                         == SOUND_MANAGER_ERROR_CAPTURE_ONLY) {
98                 ERR("capturing sound is working, don't play notification sound");
99                 return 0;
100         }
101 #endif
102
103         return 1;
104 }
105
106 static int _is_blocking_mode_on(void) {
107         int ret = 0;
108         int is_blocking_mode_on = 0;
109
110         if ((ret = vconf_get_bool(VCONFKEY_SETAPPL_BLOCKINGMODE_NOTIFICATIONS, &is_blocking_mode_on)) == 0) {
111                 if (ret == 0 && is_blocking_mode_on == 1) {
112                         return 1;
113                 }
114         }
115
116         return 0;
117 }
118
119 static int _is_security_lockscreen_launched(void) {
120         int ret = 0;
121         int is_lock_launched = 0;
122
123         if ((ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &is_lock_launched)) == 0) {
124                 if (is_lock_launched == VCONFKEY_IDLE_LOCK && (ret = vconf_get_int(VCONFKEY_SETAPPL_SCREEN_LOCK_TYPE_INT, &is_lock_launched)) == 0) {
125                         if (is_lock_launched != SETTING_SCREEN_LOCK_TYPE_NONE && is_lock_launched != SETTING_SCREEN_LOCK_TYPE_SWIPE) {
126                                 return 1;
127                         }
128                 }
129         }
130
131         return 0;
132 }
133
134 static int _check_is_noti_from_email(char *pkgname) {
135         retif(pkgname == NULL, 0, "Invalid parameter!");
136
137 #define TBD
138 #ifdef TBD
139         if (strcmp(pkgname, VENDOR".email") == 0 || strcmp(pkgname, "/usr/bin/eas-engine") == 0) {
140                 return 1;
141         } else {
142                 return 0;
143         }
144 #else
145         return 0;
146 #endif
147 }
148
149 static int _check_is_noti_from_message(char *pkgname) {
150         retif(pkgname == NULL, 0, "Invalid parameter!");
151
152         if (strcmp(pkgname, VENDOR".message-lite") == 0 || strcmp(pkgname, "/usr/bin/msg-server") == 0) {
153                 return 1;
154         } else {
155                 return 0;
156         }
157 }
158
159 static int _check_is_noti_from_im(char *pkgname) {
160         retif(pkgname == NULL, 0, "Invalid parameter!");
161
162         if (strcmp(pkgname, "xnq5eh9vop.ChatON") == 0) {
163                 return 1;
164         } else {
165                 return 0;
166         }
167 }
168
169 static notification_h _get_instant_latest_message_from_list(void) {
170         int count = 0;
171         notification_h noti = NULL;
172
173         count = eina_list_count(ticker_list);
174         if (count > 1) {
175                 noti = eina_list_nth(ticker_list, count-1);
176         }
177         eina_list_free(ticker_list);
178         ticker_list = NULL;
179
180         //eina_shutdown();
181
182         return noti;
183 }
184
185 /*****************************************************************************
186  *
187  * (Static) Util functions
188  *
189  *****************************************************************************/
190
191 static int _quickpanel_ticker_check_ticker_off(notification_h noti)
192 {
193         char *pkgname = NULL;
194         int ret = 0;
195         int boolval = 0;
196
197         notification_get_pkgname(noti, &pkgname);
198
199         if (pkgname == NULL)
200                 return 1;       /* Ticker is not displaying. */
201
202         if (_check_is_noti_from_message(pkgname) == 1)
203         {
204                 ret = vconf_get_bool(
205                         VCONFKEY_SETAPPL_STATE_TICKER_NOTI_MESSAGES_BOOL,
206                         &boolval);
207                 if (ret == 0 && boolval == 0)
208                 {
209                         return 1;
210                 }
211                 else
212                 {
213                         /* Displaying ticker! */
214                         return 0;
215                 }
216         }
217         else
218         {
219                 return 0;
220         }
221 }
222
223 static int _quickpanel_ticker_check_displaying_contents_off(notification_h noti)
224 {
225         char *pkgname = NULL;
226         int ret = 0;
227         int boolval = 0;
228
229         notification_get_pkgname(noti, &pkgname);
230
231         if (pkgname == NULL)
232                 return 0;       /* Ticker is not displaying. */
233
234         if (_check_is_noti_from_message(pkgname) == 1) {
235                 ret = vconf_get_bool(
236                         VCONFKEY_TICKER_NOTI_DISPLAY_CONTENT_MESSASGES,
237                         &boolval);
238                 if (ret == 0 && boolval == 0)
239                         return 1;
240         } else if (_check_is_noti_from_email(pkgname) == 1) {
241                 ret = vconf_get_bool(
242                         VCONFKEY_TICKER_NOTI_DISPLAY_CONTENT_EMAIL,
243                         &boolval);
244                 if (ret == 0 && boolval == 0)
245                         return 1;
246         } else if (_check_is_noti_from_im(pkgname) == 1) {
247                 ret = vconf_get_bool(
248                         VCONFKEY_TICKER_NOTI_DISPLAY_CONTENT_IM,
249                         &boolval);
250                 if (ret == 0 && boolval == 0)
251                         return 1;
252         }
253
254         /* Displaying ticker! */
255         return 0;
256 }
257
258 static int _quickpanel_ticker_check_sound_off(notification_h noti)
259 {
260         char *pkgname = NULL;
261         int ret = 0;
262         int boolval = 0;
263
264         notification_get_pkgname(noti, &pkgname);
265
266         if (pkgname == NULL)
267                 return 0;       /* don't play sound */
268
269         if (_check_is_noti_from_message(pkgname) == 1) {
270                 ret = vconf_get_bool(
271                                 VCONFKEY_TICKER_NOTI_SOUND_MESSAGES,
272                         &boolval);
273                 DBG("VCONFKEY_TICKER_NOTI_SOUND_MESSAGES:%d", boolval);
274
275                 if (ret == 0 && boolval == 0)
276                         return 1;
277                 else if (ret != 0){
278                         ERR("Failed to get a value of %s(%d)",
279                                         "VCONFKEY_TICKER_NOTI_SOUND_MESSAGES", ret);
280                 }
281         } else if (_check_is_noti_from_email(pkgname) == 1) {
282                 ret = vconf_get_bool(
283                                 VCONFKEY_TICKER_NOTI_SOUND_EMAIL,
284                         &boolval);
285                 if (ret == 0 && boolval == 0)
286                         return 1;
287                 else if (ret != 0){
288                         ERR("Failed to get a value of %s(%d)",
289                                         "VCONFKEY_TICKER_NOTI_SOUND_EMAIL", ret);
290                 }
291         } else if (_check_is_noti_from_im(pkgname) == 1) {
292                 ret = vconf_get_bool(
293                                 VCONFKEY_TICKER_NOTI_SOUND_IM,
294                         &boolval);
295                 if (ret == 0 && boolval == 0)
296                         return 1;
297                 else if (ret != 0){
298                         ERR("Failed to get a value of %s(%d)",
299                                         "VCONFKEY_TICKER_NOTI_SOUND_IM", ret);
300                 }
301         }
302
303         return 0;
304 }
305
306 static inline void __ticker_only_noti_del(notification_h noti)
307 {
308         int applist = NOTIFICATION_DISPLAY_APP_ALL;
309
310         retif(noti == NULL, ,"noti is null");
311
312         notification_get_display_applist(noti, &applist);
313         if (applist & NOTIFICATION_DISPLAY_APP_TICKER) {
314                 if (!(applist & NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY)) {
315                         char *pkgname = NULL;
316                         int priv_id = 0;
317
318                         notification_get_pkgname(noti, &pkgname);
319                         notification_get_id(noti, NULL, &priv_id);
320                         notification_delete_by_priv_id(pkgname,
321                                                 NOTIFICATION_TYPE_NONE,
322                                                 priv_id);
323                 }
324         }
325 }
326
327 static void _quickpanel_ticker_del(void *data)
328 {
329         if (g_ticker) {
330                 evas_object_del(g_ticker);
331         }
332 }
333
334 static Eina_Bool _quickpanel_ticker_timeout_cb(void *data)
335 {
336         DBG("ticker dismissed by timeout callback");
337
338         int h_page = 0;
339         int v_page = 0;
340         int h_last_page = 0;
341         int v_last_page = 0;
342         //notification_h noti = (notification_h) data;
343
344         /* If count is 1, self*/
345         if (ticker_list && eina_list_count(ticker_list) > 1) {
346                 if (g_timer) {
347                         ecore_timer_del(g_timer);
348                         g_timer = NULL;
349                 }
350                 _quickpanel_ticker_del(data);
351
352                 return ECORE_CALLBACK_CANCEL;
353         }
354
355         elm_scroller_last_page_get(g_scroller, &h_last_page, &v_last_page);
356         elm_scroller_current_page_get(g_scroller, &h_page, &v_page);
357
358         if (v_last_page > v_page) {
359                 elm_scroller_page_bring_in(g_scroller, h_page, v_page + 1);
360
361                 return ECORE_CALLBACK_RENEW;
362         }
363
364         if (g_timer) {
365                 ecore_timer_del(g_timer);
366                 g_timer = NULL;
367         }
368         _quickpanel_ticker_del(data);
369
370         return ECORE_CALLBACK_CANCEL;
371 }
372
373 static void _quickpanel_ticker_detail_delete_cb(void *data, Evas *e,
374                                         Evas_Object *obj,
375                                         void *event_info)
376 {
377         DBG("ticker dismissed by touching a hide button");
378
379         notification_h noti = (notification_h) data;
380
381         _quickpanel_ticker_destroy_tickernoti(g_ticker);
382         g_ticker = NULL;
383
384         if (g_timer) {
385                 ecore_timer_del(g_timer);
386                 g_timer = NULL;
387         }
388
389         retif(noti == NULL, , "Invalid parameter!");
390
391         __ticker_only_noti_del(noti);
392         notification_free(noti);
393
394         if (ticker_list) {
395                 noti = _get_instant_latest_message_from_list();
396                 if (noti != NULL) {
397                         _quickpanel_ticker_create_tickernoti(noti);
398                 }
399         }
400 }
401
402 static void _quickpanel_ticker_detail_show_cb(void *data, Evas *e,
403                                         Evas_Object *obj,
404                                         void *event_info)
405 {
406         DBG("");
407 }
408
409 static Evas_Object *_quickpanel_ticker_create_icon(Evas_Object *parent,
410                                                 notification_h noti)
411 {
412         char *pkgname = NULL;
413         char *icon_path = NULL;
414         char *icon_default = NULL;
415         Evas_Object *icon = NULL;
416
417         retif(noti == NULL || parent == NULL, NULL, "Invalid parameter!");
418
419         notification_get_pkgname(noti, &pkgname);
420         notification_get_image(noti, NOTIFICATION_IMAGE_TYPE_ICON, &icon_path);
421
422         icon = quickpanel_service_animated_icon_get(parent, icon_path);
423         if (icon == NULL) {
424                 icon = elm_image_add(parent);
425                 if (icon_path == NULL
426                     || (elm_image_file_set(icon, icon_path, NULL) == EINA_FALSE)) {
427                         icon_default = quickpanel_ui_get_pkginfo_icon(pkgname);
428                         if (icon_default != NULL) {
429                                 elm_image_file_set(icon, icon_default, NULL);
430                                 elm_image_resizable_set(icon, EINA_TRUE, EINA_TRUE);
431                                 free(icon_default);
432                         } else {
433                                 elm_image_file_set(icon, DEFAULT_ICON, NULL);
434                                 elm_image_resizable_set(icon, EINA_TRUE, EINA_TRUE);
435                         }
436                 }
437         }
438
439         return icon;
440 }
441
442 static inline char *_get_text(notification_h noti, notification_text_type_e text_type) {
443         time_t time = 0;
444         char *text = NULL;
445         char buf[TICKER_MSG_LEN] = {0,};
446
447         if (notification_get_time_from_text(noti, text_type, &time) == NOTIFICATION_ERROR_NONE) {
448                 if ((int)time > 0) {
449                         quickpanel_noti_get_time(time, buf, sizeof(buf));
450                         text = buf;
451                 }
452         } else {
453                 notification_get_text(noti, text_type, &text);
454         }
455
456         if (text != NULL) {
457                 return elm_entry_utf8_to_markup(text);
458         }
459
460         return NULL;
461 }
462
463 static inline void _strbuf_add(Eina_Strbuf *str_buf, char *text, const char *delimiter) {
464         if (text != NULL) {
465                 if (strlen(text) > 0) {
466                         if (delimiter != NULL) {
467                                 eina_strbuf_append(str_buf, delimiter);
468                         }
469                         eina_strbuf_append(str_buf, text);
470                 }
471         }
472 }
473
474 static inline void _check_and_add_to_buffer(Eina_Strbuf *str_buf, char *text, int is_check_phonenumber) {
475         char buf_number[QP_UTIL_PHONE_NUMBER_MAX_LEN * 2] = { 0, };
476
477         if (text != NULL) {
478                 if (strlen(text) > 0) {
479                         if (quickpanel_util_is_phone_number(text) && is_check_phonenumber) {
480                                 quickpanel_util_phone_number_tts_make(buf_number, text,
481                                                 (QP_UTIL_PHONE_NUMBER_MAX_LEN * 2) - 1);
482                                 eina_strbuf_append(str_buf, buf_number);
483                         } else {
484                                 eina_strbuf_append(str_buf, text);
485                         }
486                         eina_strbuf_append_char(str_buf, '\n');
487                 }
488         }
489 }
490
491 static char *_quickpanel_ticker_get_label_layout_default(notification_h noti, int is_screenreader, char **str_line1, char **str_line2)
492 {
493         int len = 0;
494         int num_line = 0;
495         char *domain = NULL;
496         char *dir = NULL;
497         char *title_utf8 = NULL;
498         char *content_utf8 = NULL;
499         char *info1_utf8 = NULL;
500         char *info1_sub_utf8 = NULL;
501         char *info2_utf8 = NULL;
502         char *info2_sub_utf8 = NULL;
503         char *event_count_utf8 = NULL;
504         const char *tmp = NULL;
505         Eina_Strbuf *line1 = NULL;
506         Eina_Strbuf *line2 = NULL;
507         char buf[TICKER_MSG_LEN] = { 0, };
508
509         retif(noti == NULL, NULL, "Invalid parameter!");
510
511         notification_get_text_domain(noti, &domain, &dir);
512         if (domain != NULL && dir != NULL)
513                 bindtextdomain(domain, dir);
514
515         title_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_TITLE);
516         if (_quickpanel_ticker_check_displaying_contents_off(noti) == 1) {
517                 content_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT_FOR_DISPLAY_OPTION_IS_OFF);
518         }
519         else {
520                 content_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT);
521         }
522         info1_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_INFO_1);
523         info1_sub_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_INFO_SUB_1);
524         info2_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_INFO_2);
525         info2_sub_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_INFO_SUB_2);
526         //event_count_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_EVENT_COUNT);
527
528         if (is_screenreader == 0) {
529                 line1 = eina_strbuf_new();
530                 line2 = eina_strbuf_new();
531
532                 if (line1 != NULL && line2 != NULL) {
533                         if (_is_text_exist(title_utf8) && (_is_text_exist(content_utf8)
534                                         || _is_text_exist(event_count_utf8))) {
535                                 _strbuf_add(line1, title_utf8, NULL);
536                                 _strbuf_add(line2, content_utf8, NULL);
537                                 if (_is_text_exist(content_utf8)) {
538                                         _strbuf_add(line2, event_count_utf8, " ");
539                                 } else {
540                                         _strbuf_add(line2, event_count_utf8, "");
541                                 }
542                                 num_line = 2;
543                         } else if (_is_text_exist(info1_utf8) && (_is_text_exist(content_utf8)
544                                         || _is_text_exist(event_count_utf8))) {
545                                 _strbuf_add(line1, content_utf8, NULL);
546                                 _strbuf_add(line1, event_count_utf8, " ");
547                                 _strbuf_add(line2, info1_utf8, NULL);
548                                 _strbuf_add(line2, info1_sub_utf8, " ");
549                                 num_line = 2;
550                         } else if (_is_text_exist(info1_utf8) && _is_text_exist(info2_utf8)) {
551                                 _strbuf_add(line1, info1_utf8, NULL);
552                                 _strbuf_add(line1, info1_sub_utf8, " ");
553                                 _strbuf_add(line2, info2_utf8, NULL);
554                                 _strbuf_add(line2, info2_sub_utf8, " ");
555                                 num_line = 2;
556                         } else if (_is_text_exist(title_utf8)) {
557                                 _strbuf_add(line1, title_utf8, NULL);
558                                 num_line = 1;
559                         } else if (_is_text_exist(content_utf8)) {
560                                 _strbuf_add(line1, content_utf8, NULL);
561                                 num_line = 1;
562                         }
563
564                         if (num_line == 2) {
565                                 tmp = eina_strbuf_string_get(line1);
566                                 if (str_line1 != NULL && tmp != NULL) {
567                                         *str_line1 = strdup(tmp);
568                                 }
569
570                                 tmp = eina_strbuf_string_get(line2);
571                                 if (str_line2 != NULL && tmp != NULL) {
572                                         *str_line2 = strdup(tmp);
573                                 }
574                         } else {
575                                 tmp = eina_strbuf_string_get(line1);
576                                 if (str_line1 != NULL && tmp != NULL) {
577                                         *str_line1 = strdup(tmp);
578                                 }
579                         }
580
581                         eina_strbuf_free(line1);
582                         eina_strbuf_free(line2);
583                 } else {
584                         ERR("failed to allocate string buffer");
585                 }
586         } else {
587                 if (title_utf8 == NULL
588                                 && event_count_utf8 == NULL
589                                 && content_utf8 == NULL
590                                 && info1_utf8 == NULL
591                                 && info1_sub_utf8 == NULL
592                                 && info2_utf8 == NULL
593                                 && info2_sub_utf8 == NULL) {
594                         len = 0;
595                 } else {
596                         Eina_Strbuf *strbuf = eina_strbuf_new();
597                         if (strbuf != NULL) {
598                                 eina_strbuf_append(strbuf, _("IDS_QP_BUTTON_NOTIFICATION"));
599                                 eina_strbuf_append_char(strbuf, '\n');
600                                 _check_and_add_to_buffer(strbuf, title_utf8, 1);
601                                 _check_and_add_to_buffer(strbuf, event_count_utf8, 0);
602                                 _check_and_add_to_buffer(strbuf, content_utf8, 1);
603                                 _check_and_add_to_buffer(strbuf, info1_utf8, 1);
604                                 _check_and_add_to_buffer(strbuf, info1_sub_utf8, 1);
605                                 _check_and_add_to_buffer(strbuf, info2_utf8, 1);
606                                 _check_and_add_to_buffer(strbuf, info2_sub_utf8, 1);
607
608                                 if (eina_strbuf_length_get(strbuf) > 0) {
609                                         len = snprintf(buf, sizeof(buf) - 1, "%s", eina_strbuf_string_get(strbuf));
610                                 }
611                                 eina_strbuf_free(strbuf);
612                         }
613                 }
614         }
615
616         if (title_utf8)
617                 free(title_utf8);
618
619         if (content_utf8)
620                 free(content_utf8);
621
622 //      if (event_count_utf8)
623 //              free(event_count_utf8);
624
625         if (info1_utf8)
626                 free(info1_utf8);
627
628         if (info1_sub_utf8)
629                 free(info1_sub_utf8);
630
631         if (info2_utf8)
632                 free(info2_utf8);
633
634         if (info2_sub_utf8)
635                 free(info2_sub_utf8);
636
637         if (len > 0)
638                 return strdup(buf);
639
640         return NULL;
641 }
642
643 static char *_quickpanel_ticker_get_label_layout_single(notification_h noti, int is_screenreader, char **str_line1, char **str_line2)
644 {
645         int num_line = 0;
646         int len = 0;
647         char *domain = NULL;
648         char *dir = NULL;
649         char *title_utf8 = NULL;
650         char *content_utf8 = NULL;
651         char *info1_utf8 = NULL;
652         char *info1_sub_utf8 = NULL;
653         char *info2_utf8 = NULL;
654         char *info2_sub_utf8 = NULL;
655         Eina_Strbuf *line1 = NULL;
656         Eina_Strbuf *line2 = NULL;
657         const char *tmp = NULL;
658         char buf[TICKER_MSG_LEN] = { 0, };
659
660         retif(noti == NULL, NULL, "Invalid parameter!");
661
662         notification_get_text_domain(noti, &domain, &dir);
663         if (domain != NULL && dir != NULL)
664                 bindtextdomain(domain, dir);
665
666         title_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_TITLE);
667         if (_quickpanel_ticker_check_displaying_contents_off(noti) == 1) {
668                 content_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT_FOR_DISPLAY_OPTION_IS_OFF);
669         }
670         else {
671                 content_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT);
672         }
673         info1_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_INFO_1);
674         info1_sub_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_INFO_SUB_1);
675         info2_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_INFO_2);
676         info2_sub_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_INFO_SUB_2);
677
678         if (is_screenreader == 0) {
679                 line1 = eina_strbuf_new();
680                 line2 = eina_strbuf_new();
681
682                 if (line1 != NULL && line2 != NULL) {
683                         if (_is_text_exist(info1_utf8) && _is_text_exist(content_utf8)) {
684                                 _strbuf_add(line1, content_utf8, NULL);
685                                 _strbuf_add(line2, info1_utf8, NULL);
686                                 _strbuf_add(line2, info1_sub_utf8, " ");
687                                 num_line = 2;
688                         } else if (_is_text_exist(title_utf8) && _is_text_exist(content_utf8)) {
689                                 _strbuf_add(line1, title_utf8, NULL);
690                                 _strbuf_add(line2, content_utf8, NULL);
691                                 num_line = 2;
692                         } else if (_is_text_exist(title_utf8)) {
693                                 _strbuf_add(line1, title_utf8, NULL);
694                                 num_line = 1;
695                         } else if (_is_text_exist(content_utf8)) {
696                                 _strbuf_add(line1, content_utf8, NULL);
697                                 num_line = 1;
698                         }
699
700                         if (num_line == 2) {
701                                 tmp = eina_strbuf_string_get(line1);
702                                 if (str_line1 != NULL && tmp != NULL) {
703                                         *str_line1 = strdup(tmp);
704                                 }
705
706                                 tmp = eina_strbuf_string_get(line2);
707                                 if (str_line2 != NULL && tmp != NULL) {
708                                         *str_line2 = strdup(tmp);
709                                 }
710                         } else {
711                                 tmp = eina_strbuf_string_get(line1);
712                                 if (str_line1 != NULL && tmp != NULL) {
713                                         *str_line1 = strdup(tmp);
714                                 }
715                         }
716
717                         eina_strbuf_free(line1);
718                         eina_strbuf_free(line2);
719                 } else {
720                         ERR("failed to allocate string buffer");
721                 }
722         } else {
723                 if (title_utf8 == NULL
724                                 && content_utf8 == NULL
725                                 && info1_utf8 == NULL
726                                 && info1_sub_utf8 == NULL) {
727                         len = 0;
728                 } else {
729                         Eina_Strbuf *strbuf = eina_strbuf_new();
730                         if (strbuf != NULL) {
731                                 eina_strbuf_append(strbuf, _("IDS_QP_BUTTON_NOTIFICATION"));
732                                 eina_strbuf_append_char(strbuf, '\n');
733                                 if (info1_utf8 == NULL) {
734                                         _check_and_add_to_buffer(strbuf, title_utf8, 1);
735                                         _check_and_add_to_buffer(strbuf, content_utf8, 1);
736                                 } else {
737                                         if (content_utf8 == NULL) {
738                                                 _check_and_add_to_buffer(strbuf, title_utf8, 1);
739                                         }
740                                         _check_and_add_to_buffer(strbuf, content_utf8, 1);
741                                         _check_and_add_to_buffer(strbuf, info1_utf8, 1);
742                                         _check_and_add_to_buffer(strbuf, info1_sub_utf8, 1);
743                                 }
744
745                                 if (eina_strbuf_length_get(strbuf) > 0) {
746                                         len = snprintf(buf, sizeof(buf) - 1, "%s", eina_strbuf_string_get(strbuf));
747                                 }
748                                 eina_strbuf_free(strbuf);
749                         }
750                 }
751         }
752
753         if (title_utf8)
754                 free(title_utf8);
755
756         if (content_utf8)
757                 free(content_utf8);
758
759         if (info1_utf8)
760                 free(info1_utf8);
761
762         if (info1_sub_utf8)
763                 free(info1_sub_utf8);
764
765         if (info2_utf8)
766                 free(info2_utf8);
767
768         if (info2_sub_utf8)
769                 free(info2_sub_utf8);
770
771         if (len > 0)
772                 return strdup(buf);
773
774         return NULL;
775 }
776
777 static char *_quickpanel_ticker_get_text(notification_h noti, int is_screenreader, char **line1, char **line2)
778 {
779         char *result = NULL;
780         notification_ly_type_e layout;
781
782         retif(noti == NULL, NULL, "Invalid parameter!");
783
784         notification_get_layout(noti, &layout);
785
786         if (_quickpanel_ticker_check_displaying_contents_off(noti) == 1) {
787                 result = _quickpanel_ticker_get_label_layout_default(noti, is_screenreader, line1, line2);
788         } else if (layout == NOTIFICATION_LY_NOTI_EVENT_SINGLE) {
789                 result = _quickpanel_ticker_get_label_layout_single(noti, is_screenreader, line1, line2);
790         } else {
791                 result = _quickpanel_ticker_get_label_layout_default(noti, is_screenreader, line1, line2);
792         }
793
794         return result;
795 }
796
797 static void _noti_hide_cb(void *data, Evas_Object *obj,
798                         const char *emission, const char *source)
799 {
800         DBG("");
801
802         if (g_timer) {
803                 ecore_timer_del(g_timer);
804                 g_timer = NULL;
805         }
806
807         _quickpanel_ticker_del(data);
808 }
809
810 static void _quickpanel_ticker_create_tickernoti(void *data)
811 {
812         Eina_Bool ret = EINA_FALSE;
813
814         notification_h noti = (notification_h) data;
815         Evas_Object *icon = NULL;
816         Evas_Object *detail = NULL;
817         Evas_Object *textblock = NULL;
818         char *line1 = NULL;
819         char *line2 = NULL;
820         const char *data_win_height = NULL;
821         int noti_height = 0;
822         int *is_ticker_executed = NULL;
823         //double scale = elm_config_scale_get();
824
825         retif(noti == NULL, , "Invalid parameter!");
826
827         if (g_ticker != NULL) {
828                 ERR("Instant notification exists");
829                 return;
830         }
831
832         g_ticker = noti_win_add(NULL);
833         retif(g_ticker == NULL, , "Failed to add elm tickernoti.");
834
835         detail = elm_layout_add(g_ticker);
836         if (!detail) {
837                 ERR("Failed to get detailview.");
838                 _quickpanel_ticker_del(g_ticker);
839                 return;
840         }
841         //
842         ret = elm_layout_file_set(detail, TICKER_EDJ, "quickpanel/tickernoti/normal");
843         retif(ret == EINA_FALSE, , "failed to load layout");
844         //
845         elm_layout_theme_set(detail, "tickernoti", "base", "default");
846         elm_object_signal_callback_add(detail, "request,hide", "",
847                                 _noti_hide_cb, noti);
848         //elm_object_signal_callback_add(detail, "clicked", "",
849         //              _quickpanel_ticker_clicked_cb, noti);
850         evas_object_event_callback_add(detail,
851                 EVAS_CALLBACK_MOUSE_DOWN, _noti_hide_cb, noti);
852
853         data_win_height = (char *)elm_layout_data_get(detail, "height");
854         /*if (data_win_height != NULL && elm_config_scale_get() > 0.0)
855                 noti_height = (int)(elm_config_scale_get()
856                                         * atoi(data_win_height));*/
857         evas_object_size_hint_min_set(detail, 1, noti_height);
858
859         noti_win_content_set(g_ticker, detail);
860
861         icon = _quickpanel_ticker_create_icon(detail, noti);
862         if (icon != NULL)
863                 elm_object_part_content_set(detail, "icon", icon);
864
865         g_scroller = elm_scroller_add(detail);
866         elm_scroller_policy_set(g_scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
867         elm_scroller_page_size_set(g_scroller, 434, 28);
868
869         elm_scroller_movement_block_set(g_scroller, ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL|ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL);
870
871         textblock = elm_layout_add(g_ticker);
872         if (!textblock) {
873                 ERR("Failed to get detailview.");
874                 _quickpanel_ticker_del(g_ticker);
875                 return;
876         }
877
878         ret = elm_layout_file_set(textblock, TICKER_EDJ, "quickpanel/tickernoti/text");
879         retif(ret == EINA_FALSE, , "failed to load layout");
880
881         elm_layout_theme_set(detail, "tickernoti", "base", "default");
882
883         elm_object_content_set(g_scroller, textblock);
884
885         elm_object_part_content_set(detail, "text_rect", g_scroller);
886
887         _quickpanel_ticker_get_text(noti, 0, &line1, &line2);
888
889         if (line1 == NULL) {
890                 if (line2 != NULL) {
891                         elm_object_part_text_set(textblock, "elm.text", line2);
892                         SERR("text [%s]", line2);
893                         free(line2);
894                 }
895         }
896         else if (line2 == NULL) {
897                 elm_object_part_text_set(textblock, "elm.text", line1);
898                 SERR("text [%s]", line1);
899                 free(line1);
900         }
901         else {
902                 Eina_Strbuf *buffer = eina_strbuf_new();
903                 eina_strbuf_append(buffer, line1);
904                 eina_strbuf_append(buffer, "<br/>");
905                 eina_strbuf_append(buffer, line2);
906                 elm_object_part_text_set(textblock, "elm.text", eina_strbuf_string_get(buffer));
907                 SERR("text [%s]", eina_strbuf_string_get(buffer));
908                 free(line1);
909                 free(line2);
910                 eina_strbuf_free(buffer);
911         }
912
913         /* Use style "default" for detailview mode and
914          * "info" for text only mode
915          */
916         elm_object_style_set(g_ticker, "default");
917         evas_object_data_set(g_ticker, E_DATA_IS_TICKERNOTI_CONTENT, detail);
918         is_ticker_executed = (int *)malloc(sizeof(int));
919         if (is_ticker_executed != NULL) {
920                 *is_ticker_executed = 0;
921                 evas_object_data_set(detail, E_DATA_IS_TICKERNOTI_EXECUTED, is_ticker_executed);
922         }
923
924         SERR("ticker noti is created");
925
926         g_timer = ecore_timer_add(QP_TICKER_DURATION,
927                         _quickpanel_ticker_timeout_cb, noti);
928
929         _quickpanel_ticker_win_rotated(data, 0);
930
931         evas_object_show(g_ticker);
932         SERR("show ticker noti");
933
934         evas_object_event_callback_add(g_ticker, EVAS_CALLBACK_SHOW,
935                                 _quickpanel_ticker_detail_show_cb,
936                                 g_ticker);
937         evas_object_event_callback_add(g_ticker, EVAS_CALLBACK_DEL,
938                                 _quickpanel_ticker_detail_delete_cb,
939                                 noti);
940 }
941
942 static void _quickpanel_ticker_destroy_tickernoti(Evas_Object *tickernoti)
943 {
944         int *is_ticker_executed = NULL;
945         Evas_Object *detail = NULL;
946
947         retif(tickernoti == NULL, , "Invalid parameter!");
948
949         detail = evas_object_data_get(tickernoti, E_DATA_IS_TICKERNOTI_CONTENT);
950
951         if (detail != NULL) {
952                 is_ticker_executed = evas_object_data_get(detail, E_DATA_IS_TICKERNOTI_EXECUTED);
953                 if (is_ticker_executed != NULL) {
954                         evas_object_data_del(detail, E_DATA_IS_TICKERNOTI_EXECUTED);
955                         free(is_ticker_executed);
956                 }
957                 evas_object_data_del(detail, E_DATA_IS_TICKERNOTI_CONTENT);
958         }
959 }
960
961 static void _quickpanel_ticker_win_rotated(void *data, int need_hide) {
962         int angle = 0;
963         retif(data == NULL, ,"data is NULL");
964         struct appdata *ad = data;
965
966         if (g_ticker != NULL) {
967                 angle = elm_win_rotation_get(g_ticker);
968
969                 if (((angle == 0 || angle == 180) && (ad->angle == 90 || ad->angle == 270))
970                                 || ((angle == 90 || angle == 270) && (ad->angle == 0 || ad->angle == 180))) {
971                         if (need_hide == 1) {
972                                 evas_object_hide(g_ticker);
973                         }
974                 }
975         }
976 }
977
978 static void _quickpanel_noti_media_feedback_sound(notification_h noti) {
979         int ret = 0, priv_id = 0;
980         const char *nsound_path = NULL;
981         notification_sound_type_e nsound_type = NOTIFICATION_SOUND_TYPE_NONE;
982 #ifdef VCONFKEY_SETAPPL_NOTI_MSG_RINGTONE_PATH_STR
983         char *default_msg_tone = NULL;
984 #endif
985         retif(noti == NULL, ,"op_list is NULL");
986
987         notification_get_id(noti, NULL, &priv_id);
988         notification_get_sound(noti, &nsound_type, &nsound_path);
989         SDBG("notification sound: %d, %s", nsound_type, nsound_path);
990
991         switch (nsound_type) {
992                 case NOTIFICATION_SOUND_TYPE_USER_DATA:
993                         /*
994                          *  if user data file isn't playable, play the default ringtone
995                          */
996                         if (nsound_path != NULL)
997                         {
998                                 if (quickpanel_media_playable_check(nsound_path) == EINA_TRUE)
999                                 {
1000                                         ret = quickpanel_player_play(SOUND_TYPE_NOTIFICATION, nsound_path);
1001                                         if (quickpanel_player_is_drm_error(ret) == 1)
1002                                         {
1003                                                 ERR("failed to play notification sound due to DRM problem");
1004 #ifdef VCONFKEY_SETAPPL_NOTI_MSG_RINGTONE_PATH_STR
1005                                                 default_msg_tone = vconf_get_str(VCONFKEY_SETAPPL_NOTI_MSG_RINGTONE_PATH_STR);
1006
1007                                                 if (default_msg_tone != NULL) {
1008                                                         ret = quickpanel_player_play(SOUND_TYPE_NOTIFICATION, default_msg_tone);
1009                                                         free(default_msg_tone);
1010                                                 }
1011 #endif
1012                                         }
1013                                         if (ret == PLAYER_ERROR_NONE)
1014                                         {
1015                                                 quickpanel_player_id_set(priv_id);
1016                                         }else
1017                                         {
1018                                                 ERR("failed to play notification sound");
1019                                         }
1020                                         break;
1021                                 }
1022                                 else
1023                                 {
1024                                         ERR("playable false, So unlock tone");
1025                                         feedback_play_type(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_UNLOCK);
1026                                 }
1027                         }
1028                         else
1029                         {
1030                                 ERR("sound path null");
1031                                 //feedback_play_type(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_UNLOCK);
1032                         }
1033
1034                         break;
1035                 case NOTIFICATION_SOUND_TYPE_DEFAULT:
1036 #ifdef VCONFKEY_SETAPPL_NOTI_MSG_RINGTONE_PATH_STR
1037                         default_msg_tone = vconf_get_str(VCONFKEY_SETAPPL_NOTI_MSG_RINGTONE_PATH_STR);
1038
1039                         if (default_msg_tone != NULL) {
1040                                 ret = quickpanel_player_play(SOUND_TYPE_NOTIFICATION, default_msg_tone);
1041                                 free(default_msg_tone);
1042                                 if (ret == PLAYER_ERROR_NONE) {
1043                                         quickpanel_player_id_set(priv_id);
1044                                 } else {
1045                                         ERR("failed to play notification sound(default)");
1046                                 }
1047                         } else {
1048                                 feedback_play_type(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_UNLOCK);
1049                         }
1050 #else
1051                         feedback_play_type(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_UNLOCK);
1052 #endif
1053                         break;
1054                 case NOTIFICATION_SOUND_TYPE_MAX:
1055                 case NOTIFICATION_SOUND_TYPE_NONE:
1056                         ERR("None type: No sound");
1057                         break;
1058
1059                 default:
1060                         ERR("UnKnown type[%d]", (int)nsound_type);
1061                         break;
1062         }
1063 }
1064
1065 static void _quickpanel_noti_media_feedback_vibration(notification_h noti) {
1066         retif(noti == NULL, ,"op_list is NULL");
1067
1068         /* Play Vibration */
1069         notification_vibration_type_e nvibration_type =
1070                 NOTIFICATION_VIBRATION_TYPE_NONE;
1071         const char *nvibration_path = NULL;
1072
1073         notification_get_vibration(noti, &nvibration_type, &nvibration_path);
1074         DBG("notification vibration: %d, %s", nvibration_type, nvibration_path);
1075         switch (nvibration_type) {
1076                 case NOTIFICATION_VIBRATION_TYPE_USER_DATA:
1077                 case    NOTIFICATION_VIBRATION_TYPE_DEFAULT:
1078                         feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_MESSAGE);
1079                         break;
1080                 case NOTIFICATION_VIBRATION_TYPE_MAX:
1081                 case NOTIFICATION_VIBRATION_TYPE_NONE:
1082                         break;
1083         }
1084 }
1085
1086 static void _quickpanel_ticker_noti_detailed_changed_cb(void *data, notification_type_e type, notification_op *op_list, int num_op)
1087 {
1088         notification_h noti = NULL;
1089         notification_h noti_from_master = NULL;
1090         int flags = 0;
1091         int applist = NOTIFICATION_DISPLAY_APP_ALL;
1092         int ret = 0;
1093         int op_type = 0;
1094         int priv_id = 0;
1095
1096         DBG("_quickpanel_ticker_noti_changed_cb");
1097
1098         retif(op_list == NULL, ,"op_list is NULL");
1099
1100         if (num_op == 1) {
1101                 notification_op_get_data(op_list, NOTIFICATION_OP_DATA_TYPE, &op_type);
1102                 notification_op_get_data(op_list, NOTIFICATION_OP_DATA_PRIV_ID, &priv_id);
1103                 notification_op_get_data(op_list, NOTIFICATION_OP_DATA_NOTI, &noti_from_master);
1104                 DBG("op_type:%d", op_type);
1105                 DBG("op_priv_id:%d", priv_id);
1106                 DBG("noti:%p", noti_from_master);
1107
1108                 if (op_type != NOTIFICATION_OP_INSERT &&
1109                                 op_type != NOTIFICATION_OP_UPDATE) {
1110                         return ;
1111                 }
1112                 if (noti_from_master == NULL) {
1113                         ERR("failed to get a notification from master");
1114                         return ;
1115                 }
1116                 if (notification_clone(noti_from_master, &noti) != NOTIFICATION_ERROR_NONE) {
1117                         ERR("failed to create a cloned notification");
1118                         return ;
1119                 }
1120 #ifdef QP_EMERGENCY_MODE_ENABLE
1121                 if (quickpanel_emergency_mode_is_on()) {
1122                         if (quickpanel_emergency_mode_notification_filter(noti, 1)) {
1123                                 DBG("notification filtered");
1124                                 notification_free(noti);
1125                                 return ;
1126                         }
1127                 }
1128 #endif
1129         }
1130
1131         retif(noti == NULL, ,"noti is NULL");
1132
1133         if (op_type == NOTIFICATION_OP_INSERT || op_type == NOTIFICATION_OP_UPDATE) {
1134                 if (_is_blocking_mode_on() == 0) {
1135                         if (_is_sound_playable() == 1) {
1136                                 if (_quickpanel_ticker_check_sound_off(noti) == 0) {
1137                                         DBG("try to play notification sound");
1138                                         _quickpanel_noti_media_feedback_sound(noti);
1139                                 }
1140                                 if (quickpanel_is_vib_enabled() == 1
1141                                                 || quickpanel_is_sound_enabled() == 1) {
1142                                         _quickpanel_noti_media_feedback_vibration(noti);
1143                                 }
1144                         }
1145                 }
1146         }
1147
1148         notification_get_display_applist(noti, &applist);
1149         if (!(applist & NOTIFICATION_DISPLAY_APP_TICKER)) {
1150                 DBG("displaying ticker option is off");
1151                 notification_free(noti);
1152                 return ;
1153         }
1154
1155         /* Check setting's event notification */
1156         ret = _quickpanel_ticker_check_ticker_off(noti);
1157         if (ret == 1) {
1158                 DBG("Disabled tickernoti ret : %d", ret);
1159                 /* delete temporary here only ticker noti display item */
1160                 __ticker_only_noti_del(noti);
1161                 notification_free(noti);
1162
1163                 return;
1164         }
1165
1166         /* Skip if previous ticker is still shown */
1167 /*
1168         if (g_ticker != NULL) {
1169                 DBG("delete ticker noti");
1170                 _quickpanel_ticker_del(NULL);
1171                 g_ticker = NULL;
1172         }
1173 */
1174
1175         /* Check tickernoti flag */
1176         notification_get_property(noti, &flags);
1177
1178         if (flags & NOTIFICATION_PROP_DISABLE_TICKERNOTI) {
1179                 DBG("NOTIFICATION_PROP_DISABLE_TICKERNOTI");
1180                 __ticker_only_noti_del(noti);
1181                 notification_free(noti);
1182         } else if (applist & NOTIFICATION_DISPLAY_APP_TICKER) {
1183                 if (_is_security_lockscreen_launched()) {
1184                         ERR("lockscreen or sview launched, creating a ticker canceled");
1185                         notification_free(noti);
1186                         return;
1187                 }
1188
1189                 if (quickpanel_is_opened()) {
1190                         ERR("quickpanel is opened, tickernoit will be not displayed");
1191                         notification_free(noti);
1192                         return;
1193                 }
1194
1195                 ticker_list = eina_list_append(ticker_list, noti);
1196                 /* wait if g_ticker is not NULL */
1197                 if (g_ticker == NULL) {
1198                         _quickpanel_ticker_create_tickernoti(noti);
1199                 }
1200                 if (g_ticker == NULL) {
1201                         ERR("Fail to create tickernoti");
1202                         __ticker_only_noti_del(noti);
1203                         notification_free(noti);
1204                         return;
1205                 }
1206         }
1207 }
1208
1209 /*****************************************************************************
1210  *
1211  * Util functions
1212  *
1213  *****************************************************************************/
1214 static Eina_Bool _tickernoti_callback_register_idler_cb(void *data)
1215 {
1216         struct appdata *ad = data;
1217         retif(ad == NULL, EINA_FALSE, "Invalid parameter!");
1218
1219         notification_register_detailed_changed_cb(_quickpanel_ticker_noti_detailed_changed_cb, ad);
1220
1221         return EINA_FALSE;
1222 }
1223
1224 static int quickpanel_ticker_init(void *data)
1225 {
1226         struct appdata *ad = (struct appdata *)data;
1227
1228         g_window = ad->win;
1229
1230         /* Register notification changed cb */
1231         ecore_idler_add(_tickernoti_callback_register_idler_cb, ad);
1232
1233         return QP_OK;
1234 }
1235
1236 static int quickpanel_ticker_fini(void *data)
1237 {
1238         if (g_timer) {
1239                 ecore_timer_del(g_timer);
1240                 g_timer = NULL;
1241         }
1242
1243         return QP_OK;
1244 }
1245
1246 static int quickpanel_ticker_enter_hib(void *data)
1247 {
1248         return QP_OK;
1249 }
1250
1251 static int quickpanel_ticker_leave_hib(void *data)
1252 {
1253         return QP_OK;
1254 }
1255
1256 static void quickpanel_ticker_reflesh(void *data)
1257 {
1258         retif(data == NULL, , "Invalid parameter!");
1259
1260         if (g_ticker != NULL) {
1261                 _quickpanel_ticker_win_rotated(data, 1);
1262         }
1263 }