2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (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
8 * http://floralicense.org/license/
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.
17 #include <Elementary.h>
19 #include <appcore-common.h>
22 #include <app_service.h>
23 #include <notification.h>
26 #include "quickpanel-ui.h"
30 #include "noti_util.h"
32 #define QP_TICKER_DURATION 5
33 #define QP_TICKER_DETAIL_DURATION 6
35 #define TICKER_MSG_LEN 1024
36 #define DEFAULT_ICON ICONDIR "/quickpanel_icon_default.png"
38 #define E_DATA_IS_TICKERNOTI_CONTENT "E_DATA_TN_CONTENT"
39 #define E_DATA_IS_TICKERNOTI_EXECUTED "E_DATA_TN_EXECUTED"
41 #define FORMAT_1LINE "<font_size=29><color=#BABABA>%s</color></font>"
42 #define FORMAT_2LINE "<font_size=26><color=#BABABA>%s</color></font><br><font_size=29><color=#F4F4F4>%s</color></font>"
43 #define FORMAT_2LINE_SINGLE "<font_size=26><color=#BABABA>%s</color></font><br><font_size=29><color=#F4F4F4>%s %s</color></font>"
44 #define FORMAT_2LINE_MULTI "<font_size=26><color=#BABABA>%s</color></font><br><font_size=29><color=#F4F4F4>%s %s</color></font>"
46 static Evas_Object *g_window;
47 static Evas_Object *g_ticker;
48 static Ecore_Timer *g_timer;
49 static int g_noti_height;
51 static int quickpanel_ticker_init(void *data);
52 static int quickpanel_ticker_fini(void *data);
53 static int quickpanel_ticker_enter_hib(void *data);
54 static int quickpanel_ticker_leave_hib(void *data);
55 static void quickpanel_ticker_reflesh(void *data);
56 static void _quickpanel_ticker_destroy_tickernoti(Evas_Object *tickernoti);
60 .init = quickpanel_ticker_init,
61 .fini = quickpanel_ticker_fini,
62 .hib_enter = quickpanel_ticker_enter_hib,
63 .hib_leave = quickpanel_ticker_leave_hib,
65 .refresh = quickpanel_ticker_reflesh
68 static int _is_lockscreen_launched(void) {
70 int is_lock_launched = VCONFKEY_IDLE_UNLOCK;
72 if ((ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &is_lock_launched)) == 0) {
73 if (ret == 0 && is_lock_launched == VCONFKEY_IDLE_LOCK) {
81 /*****************************************************************************
83 * (Static) Util functions
85 *****************************************************************************/
86 static void _quickpanel_ticker_clicked_cb(void *data, Evas_Object *obj,
87 const char *emission, const char *source) {
90 char *caller_pkgname = NULL;
92 bundle *group_args = NULL;
93 bundle *single_service_handle = NULL;
94 bundle *multi_service_handle = NULL;
95 int flags = 0, group_id = 0, priv_id = 0, count = 0, flag_launch = 0,
97 notification_type_e type = NOTIFICATION_TYPE_NONE;
98 notification_h noti = NULL;
99 int *is_ticker_executed = NULL;
102 retif(noti == NULL, , "Invalid parameter!");
104 quickpanel_play_feedback();
106 if (_is_lockscreen_launched()) {
110 notification_get_pkgname(noti, &caller_pkgname);
111 notification_get_application(noti, &pkgname);
113 pkgname = caller_pkgname;
115 notification_get_id(noti, &group_id, &priv_id);
116 notification_get_property(noti, &flags);
117 notification_get_type(noti, &type);
119 if (flags & NOTIFICATION_PROP_DISABLE_APP_LAUNCH) {
122 is_ticker_executed = evas_object_data_get(obj, E_DATA_IS_TICKERNOTI_EXECUTED);
123 if (is_ticker_executed != NULL) {
124 if (*is_ticker_executed == 0) {
126 *is_ticker_executed = 1;
135 if (flags & NOTIFICATION_PROP_DISABLE_AUTO_DELETE)
140 notification_get_execute_option(noti,
141 NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH,
142 NULL, &single_service_handle);
143 notification_get_execute_option(noti,
144 NOTIFICATION_EXECUTE_TYPE_MULTI_LAUNCH,
145 NULL, &multi_service_handle);
147 if (flag_launch == 1) {
148 /* Hide quickpanel */
149 quickpanel_close_quickpanel(true);
151 char *text_count = NULL;
152 notification_get_text(noti, NOTIFICATION_TEXT_TYPE_EVENT_COUNT, &text_count);
154 if (text_count != NULL) {
155 count = atoi(text_count);
160 if (single_service_handle != NULL && multi_service_handle == NULL) {
161 ret = quickpanel_launch_app(NULL, single_service_handle);
162 quickpanel_launch_app_inform_result(pkgname, ret);
164 if (single_service_handle == NULL && multi_service_handle != NULL) {
165 ret = quickpanel_launch_app(NULL, multi_service_handle);
166 quickpanel_launch_app_inform_result(pkgname, ret);
168 if (single_service_handle != NULL && multi_service_handle != NULL) {
170 ret = quickpanel_launch_app(NULL, single_service_handle);
171 quickpanel_launch_app_inform_result(pkgname, ret);
173 ret = quickpanel_launch_app(NULL, multi_service_handle);
174 quickpanel_launch_app_inform_result(pkgname, ret);
177 if (single_service_handle == NULL && multi_service_handle == NULL) {
178 notification_get_args(noti, &args, &group_args);
180 if (count > 1 && group_args != NULL) {
181 ret = quickpanel_launch_app(pkgname, group_args);
182 quickpanel_launch_app_inform_result(pkgname, ret);
184 ret = quickpanel_launch_app(pkgname, args);
185 quickpanel_launch_app_inform_result(pkgname, ret);
190 if (flag_delete == 1 && type == NOTIFICATION_TYPE_NOTI) {
191 notification_delete_by_priv_id(caller_pkgname,
192 NOTIFICATION_TYPE_NOTI,
197 static inline void __ticker_only_noti_del(notification_h noti)
199 int applist = NOTIFICATION_DISPLAY_APP_ALL;
201 retif(noti == NULL, ,"noti is null");
203 notification_get_display_applist(noti, &applist);
204 if (applist & NOTIFICATION_DISPLAY_APP_TICKER) {
205 if (!(applist & NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY)) {
206 char *pkgname = NULL;
209 notification_get_pkgname(noti, &pkgname);
210 notification_get_id(noti, NULL, &priv_id);
211 notification_delete_by_priv_id(pkgname,
212 NOTIFICATION_TYPE_NONE,
218 static void _quickpanel_ticker_hide(void *data)
221 evas_object_hide(g_ticker);
222 _quickpanel_ticker_destroy_tickernoti(g_ticker);
227 static Eina_Bool _quickpanel_ticker_timeout_cb(void *data)
229 INFO("ticker dismissed by timeout callback");
233 _quickpanel_ticker_hide(data);
235 return ECORE_CALLBACK_CANCEL;
238 static void _quickpanel_ticker_detail_hide_cb(void *data, Evas *e,
242 INFO("ticker dismissed by touching a hide button");
244 notification_h noti = (notification_h) data;
247 ecore_timer_del(g_timer);
251 retif(noti == NULL, , "Invalid parameter!");
253 __ticker_only_noti_del(noti);
254 notification_free(noti);
257 static void _quickpanel_ticker_detail_show_cb(void *data, Evas *e,
264 static void _quickpanel_ticker_button_clicked_cb(void *data, Evas_Object *obj,
268 ecore_timer_del(g_timer);
272 _quickpanel_ticker_hide(data);
275 static Evas_Object *_quickpanel_ticker_create_button(Evas_Object *parent,
278 Evas_Object *button = NULL;
280 retif(noti == NULL || parent == NULL, NULL, "Invalid parameter!");
282 if (_is_lockscreen_launched()) {
286 button = elm_button_add(parent);
287 elm_object_style_set(button, "tickernoti");
288 elm_object_text_set(button, _S("IDS_COM_BODY_CLOSE"));
289 evas_object_smart_callback_add(button, "clicked",
290 _quickpanel_ticker_button_clicked_cb, noti);
295 static Evas_Object *_quickpanel_ticker_create_icon(Evas_Object *parent,
298 char *icon_path = NULL;
299 Evas_Object *icon = NULL;
301 retif(noti == NULL || parent == NULL, NULL, "Invalid parameter!");
303 notification_get_image(noti, NOTIFICATION_IMAGE_TYPE_ICON, &icon_path);
304 icon = elm_image_add(parent);
306 if (icon_path == NULL
307 || (elm_image_file_set(icon, icon_path, NULL) == EINA_FALSE)) {
308 elm_image_file_set(icon, DEFAULT_ICON, NULL);
309 elm_image_resizable_set(icon, EINA_TRUE, EINA_TRUE);
315 static inline char *_get_text(notification_h noti, notification_text_type_e text_type) {
318 char buf[TICKER_MSG_LEN] = { 0, };
320 if (notification_get_time_from_text(noti, text_type, &time) == NOTIFICATION_ERROR_NONE) {
322 quickpanel_noti_get_time(time, buf, sizeof(buf));
326 notification_get_text(noti, text_type, &text);
330 return elm_entry_utf8_to_markup(text);
335 static char *_quickpanel_ticker_get_label_layout_default(notification_h noti)
337 char buf[TICKER_MSG_LEN] = { 0, };
341 char *title_utf8 = NULL;
342 char *content_utf8 = NULL;
343 char *event_count_utf8 = NULL;
345 retif(noti == NULL, NULL, "Invalid parameter!");
347 notification_get_text_domain(noti, &domain, &dir);
348 if (domain != NULL && dir != NULL)
349 bindtextdomain(domain, dir);
351 title_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_TITLE);
352 content_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT);
354 event_count_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_EVENT_COUNT);
356 if (event_count_utf8 == NULL) {
357 if (title_utf8 && content_utf8) {
358 len = snprintf(buf, sizeof(buf),FORMAT_2LINE, title_utf8, content_utf8);
359 } else if (title_utf8) {
360 len = snprintf(buf, sizeof(buf),FORMAT_1LINE, title_utf8);
363 if (title_utf8 && content_utf8) {
364 len = snprintf(buf, sizeof(buf),FORMAT_2LINE_MULTI, title_utf8, event_count_utf8, content_utf8);
365 } else if (title_utf8) {
366 len = snprintf(buf, sizeof(buf),FORMAT_1LINE, title_utf8);
376 if (event_count_utf8)
377 free(event_count_utf8);
385 static char *_quickpanel_ticker_get_label_layout_single(notification_h noti)
387 char buf[TICKER_MSG_LEN] = { 0, };
391 char *title_utf8 = NULL;
392 char *content_utf8 = NULL;
393 char *info_1_utf8 = NULL;
394 char *info_sub_1_utf8 = NULL;
396 retif(noti == NULL, NULL, "Invalid parameter!");
398 notification_get_text_domain(noti, &domain, &dir);
399 if (domain != NULL && dir != NULL)
400 bindtextdomain(domain, dir);
402 title_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_TITLE);
403 content_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT);
405 info_1_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_INFO_1);
406 info_sub_1_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_INFO_SUB_1);
408 if (info_1_utf8 == NULL) {
409 if (title_utf8 && content_utf8) {
410 len = snprintf(buf, sizeof(buf),FORMAT_2LINE, title_utf8, content_utf8);
411 } else if (title_utf8) {
412 len = snprintf(buf, sizeof(buf),FORMAT_1LINE, title_utf8);
415 if (info_sub_1_utf8) {
417 len = snprintf(buf, sizeof(buf), FORMAT_2LINE_SINGLE, content_utf8, info_1_utf8, info_sub_1_utf8);
419 len = snprintf(buf, sizeof(buf), FORMAT_2LINE_SINGLE, title_utf8, info_1_utf8, info_sub_1_utf8);
422 len = snprintf(buf, sizeof(buf), FORMAT_2LINE, content_utf8, info_1_utf8);
424 len = snprintf(buf, sizeof(buf), FORMAT_2LINE, title_utf8, info_1_utf8);
438 free(info_sub_1_utf8);
446 static char *_quickpanel_ticker_get_label(notification_h noti)
449 notification_ly_type_e layout;
451 retif(noti == NULL, NULL, "Invalid parameter!");
453 notification_get_layout(noti, &layout);
456 if (layout == NOTIFICATION_LY_NOTI_EVENT_SINGLE) {
457 result = _quickpanel_ticker_get_label_layout_single(noti);
459 result = _quickpanel_ticker_get_label_layout_default(noti);
465 static void _noti_hide_cb(void *data, Evas_Object *obj,
466 const char *emission, const char *source)
471 ecore_timer_del(g_timer);
475 _quickpanel_ticker_hide(data);
478 static Evas_Object *_quickpanel_ticker_create_tickernoti(void *data)
480 notification_h noti = (notification_h) data;
481 Evas_Object *tickernoti = NULL;
482 Evas_Object *icon = NULL;
483 Evas_Object *detail = NULL;
484 Evas_Object *button = NULL;
486 const char *data_win_height = NULL;
488 int *is_ticker_executed = NULL;
490 retif(noti == NULL, NULL, "Invalid parameter!");
492 tickernoti = noti_win_add(NULL);
493 retif(tickernoti == NULL, NULL, "Failed to add elm tickernoti.");
495 detail = elm_layout_add(tickernoti);
497 ERR("Failed to get detailview.");
498 _quickpanel_ticker_destroy_tickernoti(tickernoti);
501 elm_layout_theme_set(detail, "tickernoti", "base", "default");
502 elm_object_signal_callback_add(detail, "request,hide", "",
503 _noti_hide_cb, noti);
504 elm_object_signal_callback_add(detail, "clicked", "",
505 _quickpanel_ticker_clicked_cb, noti);
507 data_win_height = (char *)elm_layout_data_get(detail, "height");
508 if (data_win_height != NULL && elm_config_scale_get() > 0.0)
509 noti_height = (int)(elm_config_scale_get()
510 * atoi(data_win_height));
511 evas_object_size_hint_min_set(detail, 1, noti_height);
512 g_noti_height = noti_height;
514 noti_win_content_set(tickernoti, detail);
516 icon = _quickpanel_ticker_create_icon(detail, noti);
518 elm_object_part_content_set(detail, "icon", icon);
520 button = _quickpanel_ticker_create_button(detail, noti);
522 elm_object_part_content_set(detail, "button", button);
524 buf = _quickpanel_ticker_get_label(noti);
526 elm_object_part_text_set(detail, "elm.text", buf);
530 /* Use style "default" for detailview mode and
531 * "info" for text only mode
533 elm_object_style_set(tickernoti, "default");
534 evas_object_data_set(tickernoti, E_DATA_IS_TICKERNOTI_CONTENT, detail);
535 is_ticker_executed = (int *)malloc(sizeof(int));
536 if (is_ticker_executed != NULL) {
537 *is_ticker_executed = 0;
538 evas_object_data_set(detail, E_DATA_IS_TICKERNOTI_EXECUTED, is_ticker_executed);
544 static void _quickpanel_ticker_destroy_tickernoti(Evas_Object *tickernoti)
546 int *is_ticker_executed = NULL;
547 Evas_Object *detail = NULL;
549 retif(tickernoti == NULL, , "Invalid parameter!");
551 detail = evas_object_data_get(tickernoti, E_DATA_IS_TICKERNOTI_CONTENT);
553 if (detail != NULL) {
554 is_ticker_executed = evas_object_data_get(detail, E_DATA_IS_TICKERNOTI_EXECUTED);
555 if (is_ticker_executed != NULL) {
556 evas_object_data_del(detail, E_DATA_IS_TICKERNOTI_EXECUTED);
557 free(is_ticker_executed);
559 evas_object_data_del(detail, E_DATA_IS_TICKERNOTI_CONTENT);
562 evas_object_del(tickernoti);
565 static int _quickpanel_ticker_get_angle(void *data)
567 struct appdata *ad = (struct appdata *)data;
568 Ecore_X_Window xwin, root;
569 int ret = 0, angle = 0, count = 0;
570 unsigned char *prop_data = NULL;
572 xwin = elm_win_xwindow_get(ad->win);
573 root = ecore_x_window_root_get(xwin);
575 ret = ecore_x_window_prop_property_get(root,
576 ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE,
577 ECORE_X_ATOM_CARDINAL, 32,
580 if (ret && prop_data) {
581 memcpy(&angle, prop_data, sizeof(int));
588 ERR("Fail to get angle");
596 static void _quickpanel_ticker_update_geometry_on_rotation(void *data, int *x, int *y, int *w, int *h) {
601 angle = _quickpanel_ticker_get_angle(data);
602 Evas_Coord root_w, root_h;
605 * manually calculate win_tickernoti_indi window position & size
606 * - win_indi is not full size window
608 ecore_x_window_size_get(ecore_x_window_root_first_get(), &root_w, &root_h);
620 *x = root_w - g_noti_height;
625 *y = root_h - g_noti_height;
633 elm_win_rotation_set(g_ticker, angle);
636 static void _quickpanel_ticker_win_rotated(void *data) {
637 retif(data == NULL, ,"data is NULL");
638 struct appdata *ad = data;
639 int x = 0, y = 0, w = 0, h = 0;
641 _quickpanel_ticker_update_geometry_on_rotation(ad, &x, &y, &w, &h);
643 if (g_ticker != NULL) {
644 evas_object_move(g_ticker, x, y);
645 evas_object_resize(g_ticker, w, h);
649 static void _quickpanel_noti_media_feedback(notification_h noti) {
651 retif(noti == NULL, ,"op_list is NULL");
653 if (quickpanel_is_sound_enabled() == 1) {
654 notification_sound_type_e nsound_type = NOTIFICATION_SOUND_TYPE_NONE;
655 const char *nsound_path = NULL;
656 #ifdef VCONFKEY_SETAPPL_NOTI_MSG_RINGTONE_PATH_STR
657 char *default_msg_tone = NULL;
660 notification_get_sound(noti, &nsound_type, &nsound_path);
661 DBG("notification sound: %d, %s", nsound_type, nsound_path);
663 switch (nsound_type) {
664 case NOTIFICATION_SOUND_TYPE_USER_DATA:
665 quickpanel_player_play(SOUND_TYPE_NOTIFICATION, nsound_path);
667 case NOTIFICATION_SOUND_TYPE_DEFAULT:
668 #ifdef VCONFKEY_SETAPPL_NOTI_MSG_RINGTONE_PATH_STR
669 default_msg_tone = vconf_get_str(VCONFKEY_SETAPPL_NOTI_MSG_RINGTONE_PATH_STR);
671 if (default_msg_tone != NULL) {
672 quickpanel_player_play(SOUND_TYPE_NOTIFICATION, default_msg_tone);
673 free(default_msg_tone);
675 feedback_play_type(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_UNLOCK);
678 feedback_play_type(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_UNLOCK);
681 case NOTIFICATION_SOUND_TYPE_MAX:
682 case NOTIFICATION_SOUND_TYPE_NONE:
688 notification_vibration_type_e nvibration_type =
689 NOTIFICATION_VIBRATION_TYPE_NONE;
690 const char *nvibration_path = NULL;
692 notification_get_vibration(noti, &nvibration_type, &nvibration_path);
693 DBG("notification vibration: %d, %s", nvibration_type, nvibration_path);
694 switch (nvibration_type) {
695 case NOTIFICATION_VIBRATION_TYPE_USER_DATA:
696 case NOTIFICATION_VIBRATION_TYPE_DEFAULT:
697 feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_GENERAL);
699 case NOTIFICATION_VIBRATION_TYPE_MAX:
700 case NOTIFICATION_VIBRATION_TYPE_NONE:
705 static void _quickpanel_ticker_noti_detailed_changed_cb(void *data, notification_type_e type, notification_op *op_list, int num_op)
707 notification_h noti = NULL;
708 notification_h noti_from_master = NULL;
710 int applist = NOTIFICATION_DISPLAY_APP_ALL;
714 INFO("_quickpanel_ticker_noti_changed_cb");
716 retif(op_list == NULL, ,"op_list is NULL");
718 if (_is_lockscreen_launched()) {
719 ERR("lockscreen launched, creating a ticker canceled");
724 notification_op_get_data(op_list, NOTIFICATION_OP_DATA_TYPE, &op_type);
725 notification_op_get_data(op_list, NOTIFICATION_OP_DATA_PRIV_ID, &priv_id);
726 notification_op_get_data(op_list, NOTIFICATION_OP_DATA_NOTI, ¬i_from_master);
727 DBG("op_type:%d", op_type);
728 DBG("op_priv_id:%d", priv_id);
729 DBG("noti:%p", noti_from_master);
731 if (op_type != NOTIFICATION_OP_INSERT &&
732 op_type != NOTIFICATION_OP_UPDATE) {
735 if (noti_from_master == NULL) {
736 ERR("failed to get a notification from master");
739 if (notification_clone(noti_from_master, ¬i) != NOTIFICATION_ERROR_NONE) {
740 ERR("failed to create a cloned notification");
745 retif(noti == NULL, ,"noti is NULL");
747 if (op_type == NOTIFICATION_OP_INSERT || op_type == NOTIFICATION_OP_UPDATE) {
748 INFO("playing notification sound");
749 _quickpanel_noti_media_feedback(noti);
752 notification_get_display_applist(noti, &applist);
753 if (!(applist & NOTIFICATION_DISPLAY_APP_TICKER)) {
754 INFO("displaying ticker option is off");
755 notification_free(noti);
759 /* Skip if previous ticker is still shown */
760 if (g_ticker != NULL) {
761 _quickpanel_ticker_hide(NULL);
764 /* Check tickernoti flag */
765 notification_get_property(noti, &flags);
767 if (flags & NOTIFICATION_PROP_DISABLE_TICKERNOTI) {
768 INFO("NOTIFICATION_PROP_DISABLE_TICKERNOTI");
769 __ticker_only_noti_del(noti);
770 notification_free(noti);
771 } else if (applist & NOTIFICATION_DISPLAY_APP_TICKER) {
774 ecore_timer_del(g_timer);
776 g_ticker = _quickpanel_ticker_create_tickernoti(noti);
777 if (g_ticker == NULL) {
778 ERR("Fail to create tickernoti");
779 __ticker_only_noti_del(noti);
780 notification_free(noti);
784 g_timer = ecore_timer_add(QP_TICKER_DURATION,
785 _quickpanel_ticker_timeout_cb, noti);
787 _quickpanel_ticker_win_rotated(data);
788 evas_object_show(g_ticker);
790 evas_object_event_callback_add(g_ticker, EVAS_CALLBACK_SHOW,
791 _quickpanel_ticker_detail_show_cb,
793 evas_object_event_callback_add(g_ticker, EVAS_CALLBACK_HIDE,
794 _quickpanel_ticker_detail_hide_cb,
799 /*****************************************************************************
803 *****************************************************************************/
804 static int quickpanel_ticker_init(void *data)
806 struct appdata *ad = (struct appdata *)data;
810 notification_register_detailed_changed_cb(_quickpanel_ticker_noti_detailed_changed_cb,
816 static int quickpanel_ticker_fini(void *data)
818 _quickpanel_ticker_hide(NULL);
823 static int quickpanel_ticker_enter_hib(void *data)
828 static int quickpanel_ticker_leave_hib(void *data)
833 static void quickpanel_ticker_reflesh(void *data)
835 retif(data == NULL, , "Invalid parameter!");
837 if (g_ticker != NULL) {
838 _quickpanel_ticker_win_rotated(data);