summaryrefslogtreecommitdiff
path: root/daemon
diff options
context:
space:
mode:
authorJinkun Jang <jinkun.jang@samsung.com>2013-03-13 01:38:12 +0900
committerJinkun Jang <jinkun.jang@samsung.com>2013-03-13 01:38:12 +0900
commit7c83e9661e76a4297913256f65d84709c9c3e26e (patch)
tree7f76d9983beab3974ec626e29f8b30fd969778ce /daemon
parentd122c66eb003810833ffc2c9e7ba275c48ef5b95 (diff)
downloadquickpanel-7c83e9661e76a4297913256f65d84709c9c3e26e.tar.gz
quickpanel-7c83e9661e76a4297913256f65d84709c9c3e26e.tar.bz2
quickpanel-7c83e9661e76a4297913256f65d84709c9c3e26e.zip
Tizen 2.1 base
Diffstat (limited to 'daemon')
-rwxr-xr-xdaemon/common.h113
-rwxr-xr-xdaemon/idletxt/idletxt.c537
-rwxr-xr-xdaemon/list_util.c391
-rwxr-xr-xdaemon/list_util.h81
-rwxr-xr-xdaemon/minictrl/minictrl.c457
-rwxr-xr-xdaemon/modules.c197
-rwxr-xr-xdaemon/modules.h34
-rwxr-xr-xdaemon/notifications/brightness.c464
-rwxr-xr-xdaemon/notifications/noti.c1999
-rwxr-xr-xdaemon/notifications/noti.h20
-rwxr-xr-xdaemon/notifications/noti_box.c480
-rwxr-xr-xdaemon/notifications/noti_box.h46
-rwxr-xr-xdaemon/notifications/noti_display_app.c422
-rwxr-xr-xdaemon/notifications/noti_display_app.h28
-rwxr-xr-xdaemon/notifications/noti_gridbox.c454
-rwxr-xr-xdaemon/notifications/noti_gridbox.h34
-rwxr-xr-xdaemon/notifications/noti_node.c146
-rwxr-xr-xdaemon/notifications/noti_node.h41
-rwxr-xr-xdaemon/notifications/noti_win.c314
-rwxr-xr-xdaemon/notifications/noti_win.h41
-rwxr-xr-xdaemon/notifications/status_msg.c315
-rwxr-xr-xdaemon/notifications/ticker.c726
-rwxr-xr-xdaemon/quickpanel-ui.c1156
-rwxr-xr-xdaemon/quickpanel-ui.h123
24 files changed, 8619 insertions, 0 deletions
diff --git a/daemon/common.h b/daemon/common.h
new file mode 100755
index 0000000..79ffbb1
--- /dev/null
+++ b/daemon/common.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __QP_COMMON_H_
+#define __QP_COMMON_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "quickpanel_debug_util.h"
+
+#define QP_OK (0)
+#define QP_FAIL (-1)
+
+#ifdef _DLOG_USED
+#define LOG_TAG "quickpanel"
+#include <dlog.h>
+
+#define DBG(fmt , args...) \
+ do { \
+ LOGD("[%s : %d] "fmt"\n", __func__, __LINE__, ##args); \
+ } while (0)
+
+#define INFO(fmt , args...) \
+ do { \
+ LOGI("[%s : %d] "fmt"\n", __func__, __LINE__, ##args); \
+ } while (0)
+
+#define WARN(fmt , args...) \
+ do { \
+ LOGI("[%s : %d] "fmt"\n", __func__, __LINE__, ##args); \
+ } while (0)
+
+#define ERR(fmt , args...) \
+ do { \
+ LOGI("[%s : %d] "fmt"\n", __func__, __LINE__, ##args); \
+ } while (0)
+
+#elif FILE_DEBUG /*_DLOG_USED*/
+#define DBG(fmt , args...) \
+ do { \
+ debug_printf("[D]%s : %d] "fmt"\n", \
+ __func__, __LINE__, ##args); \
+ } while (0)
+
+#define INFO(fmt , args...) \
+ do { \
+ debug_printf("[I][%s : %d] "fmt"\n",\
+ __func__, __LINE__, ##args); \
+ } while (0)
+
+#define WARN(fmt , args...) \
+ do { \
+ debug_printf("[W][%s : %d] "fmt"\n", \
+ __func__, __LINE__, ##args); \
+ } while (0)
+
+#define ERR(fmt , args...) \
+ do { \
+ debug_printf("[E][%s : %d] "fmt"\n", \
+ __func__, __LINE__, ##args); \
+ } while (0)
+
+#else /*_DLOG_USED*/
+#define DBG(fmt , args...) \
+ do { \
+ fprintf("[D][%s : %d] "fmt"\n", __func__, __LINE__, ##args); \
+ } while (0)
+
+#define INFO(fmt , args...) \
+ do { \
+ fprintf("[I][%s : %d] "fmt"\n", __func__, __LINE__, ##args); \
+ } while (0)
+
+#define WARN(fmt , args...) \
+ do { \
+ fprintf("[W][%s : %d] "fmt"\n", __func__, __LINE__, ##args); \
+ } while (0)
+
+#define ERR(fmt , args...) \
+ do { \
+ fprintf("[E][%s : %d] "fmt"\n", __func__, __LINE__, ##args); \
+ } while (0)
+#endif /*_DLOG_USED*/
+
+#define retif(cond, ret, str, args...) do { \
+ if (cond) { \
+ WARN(str, ##args);\
+ return ret;\
+ } \
+} while (0);
+
+#define gotoif(cond, target, str, args...) do { \
+ if (cond) { \
+ WARN(str, ##args); \
+ goto target; \
+ } \
+} while (0);
+
+#endif /* __QP_COMMON_H_ */
diff --git a/daemon/idletxt/idletxt.c b/daemon/idletxt/idletxt.c
new file mode 100755
index 0000000..0b4c72e
--- /dev/null
+++ b/daemon/idletxt/idletxt.c
@@ -0,0 +1,537 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <Ecore_X.h>
+#include <vconf.h>
+#include "common.h"
+#include "quickpanel-ui.h"
+
+#define QP_IDLETXT_PART "qp.noti.swallow.spn"
+
+#define QP_SPN_BASE_PART "qp.base.spn.swallow"
+#define QP_SPN_BOX_PART "qp.spn.swallow"
+#define QP_BUTTON_PART "qp.button.swallow"
+
+#define QP_IDLETXT_MAX_KEY 4
+#define QP_IDLETXT_MAX_LEN 1024
+#define QP_IDLETXT_SLIDE_LEN 130
+
+#define QP_IDLETXT_LABEL_STRING \
+ "<font_size=36 font=Tizen:style=Medium><color=#959494FF><align=left>%s</align>" \
+ "</color></font_size>"
+
+static int quickpanel_idletxt_init(void *data);
+static int quickpanel_idletxt_fini(void *data);
+static int quickpanel_idletxt_suspend(void *data);
+static int quickpanel_idletxt_resume(void *data);
+static void quickpanel_idletxt_lang_changed(void *data);
+
+QP_Module idletxt = {
+ .name = "idletxt",
+ .init = quickpanel_idletxt_init,
+ .fini = quickpanel_idletxt_fini,
+ .suspend = quickpanel_idletxt_suspend,
+ .resume = quickpanel_idletxt_resume,
+ .lang_changed = quickpanel_idletxt_lang_changed
+};
+
+static int _quickpanel_idletxt_map_exceptional_nwname(char *txt, char *map_txt, int map_txt_len)
+{
+ int is_mapped = 0;
+
+ if (txt == NULL || map_txt == NULL) {
+ return is_mapped;
+ }
+
+ if (strncasecmp(txt, "No Service", strlen("No Service")) == 0) {
+ strncpy(map_txt, _S("IDS_COM_BODY_NO_SERVICE"), map_txt_len);
+ is_mapped = 1;
+ } else if (strncasecmp(txt, "EMERGENCY", strlen("EMERGENCY")) == 0) {
+ strncpy(map_txt, _("IDS_CALL_POP_CALLING_EMERG_ONLY"), map_txt_len);
+ is_mapped = 1;
+ } else if (strncasecmp(txt, "Searching", strlen("Searching")) == 0) {
+ strncpy(map_txt, _S("IDS_COM_BODY_SEARCHING"), map_txt_len);
+ is_mapped = 1;
+ } else if (strncasecmp(txt, "SIM Error", strlen("SIM Error")) == 0) {
+ strncpy(map_txt, _S("IDS_COM_BODY_INVALID_SIM_CARD"), map_txt_len);
+ is_mapped = 1;
+ } else if (strncasecmp(txt, "NO SIM", strlen("NO SIM")) == 0) {
+ strncpy(map_txt, _S("IDS_COM_BODY_NO_SIM"), map_txt_len);
+ is_mapped = 1;
+ }
+
+ return is_mapped;
+}
+
+static Evas_Object *_quickpanel_idletxt_create_label(Evas_Object * parent,
+ char *txt)
+{
+ Evas_Object *obj = NULL;
+ char buf[QP_IDLETXT_MAX_LEN] = { 0, };
+ char localized_txt[QP_IDLETXT_MAX_LEN] = { 0, };
+ int len = 0;
+
+ retif(parent == NULL || txt == NULL, NULL, "Invalid parameter!");
+
+ memset(buf, 0x00, sizeof(buf));
+
+ if (_quickpanel_idletxt_map_exceptional_nwname(txt, localized_txt, QP_IDLETXT_MAX_LEN) == 1) {
+ len = snprintf(buf, sizeof(buf), QP_IDLETXT_LABEL_STRING, localized_txt);
+ } else {
+ len = snprintf(buf, sizeof(buf), QP_IDLETXT_LABEL_STRING, txt);
+ }
+
+ retif(len < 0, NULL, "len < 0");
+
+ obj = elm_label_add(parent);
+ if (obj != NULL) {
+ elm_object_text_set(obj, buf);
+
+ evas_object_size_hint_weight_set(obj, EVAS_HINT_EXPAND,
+ EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, 0.5);
+
+ evas_object_show(obj);
+ }
+
+ return obj;
+}
+
+static Evas_Object *_quickpanel_idletxt_create_box(Evas_Object * parent)
+{
+ Evas_Object *box = NULL;
+
+ retif(parent == NULL, NULL, "Invalid parameter!");
+
+ box = elm_box_add(parent);
+ if (box != NULL) {
+ elm_box_horizontal_set(box, EINA_FALSE);
+
+ evas_object_show(box);
+ }
+
+ return box;
+}
+
+static int _quickpanel_idletxt_get_txt(const char *key, char *txt, int size)
+{
+ int len = 0;
+ char *str = NULL;
+ int i = 0;
+
+ str = vconf_get_str(key);
+ if (str == NULL || str[0] == '\0')
+ return 0;
+
+ /* check ASCII code */
+ for (i = strlen(str) - 1; i >= 0; i--) {
+ if (str[i] <= 31 || str[i] >= 127)
+ goto failed;
+ }
+
+ len = snprintf(txt, size, "%s", str);
+
+ failed:
+ if (str)
+ free(str);
+
+ return len;
+}
+
+static Evas_Object *_quickpanel_idletxt_add_label(Evas_Object * box,
+ char *key[])
+{
+ char txt[QP_IDLETXT_MAX_LEN] = { 0, };
+ char buf[QP_IDLETXT_MAX_LEN] = { 0, };
+ int len = 0;
+ int i = 0;
+ Evas_Object *obj = NULL;
+
+ retif(key == NULL || key[0] == '\0', NULL, "Invalid parameter!");
+
+ memset(txt, 0x00, sizeof(txt));
+
+ for (i = 0; key[i]; i++) {
+ memset(buf, 0x00, sizeof(buf));
+
+ /* get next key string */
+ if (_quickpanel_idletxt_get_txt(key[i], buf, sizeof(buf))) {
+ INFO("VCONFKEY(%s) = %s", key[i], buf);
+
+ len = strlen(txt);
+
+ snprintf(&txt[len], sizeof(txt) - len, "%s%s",
+ len ? " - " : "", buf);
+ }
+ }
+
+ len = strlen(txt);
+
+ if (len) {
+ obj = _quickpanel_idletxt_create_label(box, txt);
+
+ if (obj != NULL) {
+ if (len > QP_IDLETXT_SLIDE_LEN)
+ elm_label_slide_set(obj, EINA_TRUE);
+
+ return obj;
+ }
+ }
+
+ return NULL;
+}
+
+static Evas_Object *_quickpanel_idletxt_exception_add_label(Evas_Object * box)
+{
+ int service_type = VCONFKEY_TELEPHONY_SVCTYPE_SEARCH;
+ char *text = NULL;
+ Evas_Object *obj = NULL;
+
+ if (vconf_get_int(VCONFKEY_TELEPHONY_SVCTYPE, &service_type) != 0) {
+ DBG("fail to get VCONFKEY_TELEPHONY_SVCTYPE");
+ }
+
+ switch(service_type) {
+ case VCONFKEY_TELEPHONY_SVCTYPE_NOSVC:
+ text = _S("IDS_COM_BODY_NO_SERVICE");
+ break;
+ case VCONFKEY_TELEPHONY_SVCTYPE_EMERGENCY:
+ text = _("IDS_CALL_POP_CALLING_EMERG_ONLY");
+ break;
+ default:
+ if (service_type > VCONFKEY_TELEPHONY_SVCTYPE_SEARCH) {
+ text = vconf_get_str(VCONFKEY_TELEPHONY_NWNAME);
+ } else {
+ text = _S("IDS_COM_BODY_SEARCHING");
+ }
+ break;
+ }
+
+ if (text != NULL) {
+ obj = _quickpanel_idletxt_create_label(box, text);
+
+ if (obj != NULL) {
+ if (strlen(text) > QP_IDLETXT_SLIDE_LEN)
+ elm_label_slide_set(obj, EINA_TRUE);
+
+ return obj;
+ }
+ }
+
+ return NULL;
+}
+
+static Evas_Object *_quickpanel_idletxt_get_spn(Evas_Object * box)
+{
+ Evas_Object *label = NULL;
+ char *keylist[QP_IDLETXT_MAX_KEY] = { 0, };
+ int ret = 0;
+ int state = 0;
+ int i = 0;
+ int service_type = VCONFKEY_TELEPHONY_SVCTYPE_NONE;
+
+ /* make keylist */
+ if (vconf_get_int(VCONFKEY_TELEPHONY_SVCTYPE, &service_type) != 0) {
+ DBG("fail to get VCONFKEY_TELEPHONY_SVCTYPE");
+ }
+
+ ret = vconf_get_int(VCONFKEY_TELEPHONY_SPN_DISP_CONDITION, &state);
+ if (ret == 0) {
+ INFO("VCONFKEY(%s) = %d",
+ VCONFKEY_TELEPHONY_SPN_DISP_CONDITION, state);
+
+ if (state != VCONFKEY_TELEPHONY_DISP_INVALID
+ && service_type > VCONFKEY_TELEPHONY_SVCTYPE_SEARCH) {
+ if (i < QP_IDLETXT_MAX_KEY) {
+ if (state & VCONFKEY_TELEPHONY_DISP_SPN) {
+ keylist[i++] =
+ strdup(VCONFKEY_TELEPHONY_SPN_NAME);
+ }
+
+ if (state & VCONFKEY_TELEPHONY_DISP_PLMN) {
+ keylist[i++] =
+ strdup(VCONFKEY_TELEPHONY_NWNAME);
+ }
+ }
+
+ if (i > 0) {
+ /* get string with keylist */
+ label = _quickpanel_idletxt_add_label(box, keylist);
+
+ /* free keylist */
+ while (i > 0) {
+ if (keylist[i])
+ free(keylist[i]);
+
+ i--;
+ }
+ }
+ } else {
+ label = _quickpanel_idletxt_exception_add_label(box);
+ }
+ }
+
+ return label;
+}
+
+static Evas_Object *_quickpanel_idletxt_get_sat_text(Evas_Object * box)
+{
+ Evas_Object *label = NULL;
+ char *keylist[] = { VCONFKEY_SAT_IDLE_TEXT, 0 };
+
+ /* get string with keylist */
+ label = _quickpanel_idletxt_add_label(box, keylist);
+
+ return label;
+}
+
+static void _quickpanel_idletxt_button_clicked(void *data, Evas_Object * obj, void *event_info)
+{
+ struct appdata *ad = data;
+ retif(obj == NULL, , "Invalid parameter!");
+ retif(ad == NULL, , "Invalid parameter!");
+ retif(ad->win == NULL, , "ad->win is NULL");
+
+ Ecore_X_Window zone;
+
+ if (ad->is_emul == 1)
+ quickpanel_launch_app(QP_SETTING_PKG_SETTING_EMUL, NULL);
+ else
+ quickpanel_launch_app(QP_SETTING_PKG_SETTING, NULL);
+
+ zone = ecore_x_e_illume_zone_get(elm_win_xwindow_get(ad->win));
+ ecore_x_e_illume_quickpanel_state_send(zone,
+ ECORE_X_ILLUME_QUICKPANEL_STATE_OFF);
+
+ elm_object_signal_emit(obj, "elm,action,button,reset", "elm");
+}
+
+static void quickpanel_idletxt_update(void *data)
+{
+ struct appdata *ad = NULL;
+ Evas_Object *label = NULL;
+ Evas_Object *idletxtbox = NULL;
+ Evas_Object *button_settings = NULL;
+ Evas_Object *spn = NULL;
+
+ retif(!data, , "Invalid parameter!");
+ ad = data;
+
+ retif(!ad->ly, , "layout is NULL!");
+
+ spn = elm_object_part_content_get(ad->ly, QP_SPN_BASE_PART);
+ retif(!spn, , "spn layout is NULL!");
+
+ idletxtbox = elm_object_part_content_get(spn, QP_SPN_BOX_PART);
+ button_settings = elm_object_part_content_get(spn, QP_BUTTON_PART);
+
+ if (idletxtbox == NULL) {
+ idletxtbox = _quickpanel_idletxt_create_box(spn);
+ retif(idletxtbox == NULL, , "Failed to create box!");
+ elm_object_part_content_set(spn,
+ QP_SPN_BOX_PART, idletxtbox);
+ }
+
+ elm_box_clear(idletxtbox);
+
+ /* get spn */
+ label = _quickpanel_idletxt_get_spn(idletxtbox);
+ if (label != NULL)
+ elm_box_pack_end(idletxtbox, label);
+
+ /* get sat idle text */
+ label = _quickpanel_idletxt_get_sat_text(idletxtbox);
+ if (label != NULL)
+ elm_box_pack_end(idletxtbox, label);
+
+ if (button_settings == NULL) {
+ button_settings = elm_button_add(spn);
+ retif(button_settings == NULL, , "Failed to create clear button!");
+ elm_object_style_set(button_settings, "quickpanel_standard");
+ elm_object_part_content_set(spn,
+ QP_BUTTON_PART, button_settings);
+ evas_object_smart_callback_add(button_settings, "clicked",
+ _quickpanel_idletxt_button_clicked, ad);
+ }
+
+ elm_object_text_set(button_settings, _S("IDS_COM_BODY_SETTINGS"));
+}
+
+static void quickpanel_idletxt_changed_cb(keynode_t *node, void *data)
+{
+ quickpanel_idletxt_update(data);
+}
+
+static int _quickpanel_idletxt_register_event_handler(void *data)
+{
+ int ret = 0;
+
+ ret = vconf_notify_key_changed(VCONFKEY_TELEPHONY_SVCTYPE,
+ quickpanel_idletxt_changed_cb, data);
+ if (ret != 0)
+ ERR("Failed to register [%s]",
+ VCONFKEY_TELEPHONY_SVCTYPE);
+
+ ret = vconf_notify_key_changed(VCONFKEY_TELEPHONY_SPN_DISP_CONDITION,
+ quickpanel_idletxt_changed_cb, data);
+ if (ret != 0)
+ ERR("Failed to register [%s]",
+ VCONFKEY_TELEPHONY_SPN_DISP_CONDITION);
+
+ ret = vconf_notify_key_changed(VCONFKEY_TELEPHONY_SPN_NAME,
+ quickpanel_idletxt_changed_cb, data);
+ if (ret != 0)
+ ERR("Failed to register [%s]",
+ VCONFKEY_TELEPHONY_SPN_NAME);
+
+
+ ret = vconf_notify_key_changed(VCONFKEY_TELEPHONY_NWNAME,
+ quickpanel_idletxt_changed_cb, data);
+ if (ret != 0)
+ ERR("Failed to register [%s]",
+ VCONFKEY_TELEPHONY_NWNAME);
+
+ ret = vconf_notify_key_changed(VCONFKEY_SAT_IDLE_TEXT,
+ quickpanel_idletxt_changed_cb, data);
+ if (ret != 0)
+ ERR("Failed to register [%s]",
+ VCONFKEY_SAT_IDLE_TEXT);
+
+
+ return QP_OK;
+}
+
+static int _quickpanel_idletxt_unregister_event_handler(void)
+{
+ int ret = 0;
+
+ ret = vconf_ignore_key_changed(VCONFKEY_TELEPHONY_SVCTYPE,
+ quickpanel_idletxt_changed_cb);
+ if (ret != 0)
+ ERR("Failed to unregister [%s]",
+ VCONFKEY_TELEPHONY_SVCTYPE);
+
+ ret = vconf_ignore_key_changed(VCONFKEY_TELEPHONY_SPN_DISP_CONDITION,
+ quickpanel_idletxt_changed_cb);
+ if (ret != 0)
+ ERR("Failed to unregister [%s]",
+ VCONFKEY_TELEPHONY_SPN_DISP_CONDITION);
+
+ ret = vconf_ignore_key_changed(VCONFKEY_TELEPHONY_SPN_NAME,
+ quickpanel_idletxt_changed_cb);
+ if (ret != 0)
+ ERR("Failed to unregister [%s]",
+ VCONFKEY_TELEPHONY_SPN_NAME);
+
+
+ ret = vconf_ignore_key_changed(VCONFKEY_TELEPHONY_NWNAME,
+ quickpanel_idletxt_changed_cb);
+ if (ret != 0)
+ ERR("Failed to unregister [%s]",
+ VCONFKEY_TELEPHONY_NWNAME);
+
+ ret = vconf_ignore_key_changed(VCONFKEY_SAT_IDLE_TEXT,
+ quickpanel_idletxt_changed_cb);
+ if (ret != 0)
+ ERR("Failed to unregister [%s]",
+ VCONFKEY_SAT_IDLE_TEXT);
+
+ return QP_OK;
+}
+
+static Evas_Object *_idletxt_load_edj(Evas_Object * parent, const char *file,
+ const char *group)
+{
+ Eina_Bool r;
+ Evas_Object *eo = NULL;
+
+ retif(parent == NULL, NULL, "Invalid parameter!");
+
+ eo = elm_layout_add(parent);
+ retif(eo == NULL, NULL, "Failed to add layout object!");
+
+ r = elm_layout_file_set(eo, file, group);
+ retif(r != EINA_TRUE, NULL, "Failed to set edje object file!");
+
+ evas_object_size_hint_weight_set(eo,
+ EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_show(eo);
+
+ return eo;
+}
+
+static int quickpanel_idletxt_init(void *data)
+{
+ struct appdata *ad = NULL;
+ Evas_Object *spn = NULL;
+
+ retif(!data, QP_FAIL, "Invalid parameter!");
+ ad = data;
+
+ spn = _idletxt_load_edj(ad->ly, DEFAULT_EDJ, "quickpanel/spn");
+ retif(!spn, QP_FAIL, "fail to load spn layout");
+
+ elm_object_part_content_set(ad->ly, QP_SPN_BASE_PART, spn);
+
+ quickpanel_idletxt_update(data);
+
+ _quickpanel_idletxt_register_event_handler(data);
+
+ return QP_OK;
+}
+
+static int quickpanel_idletxt_fini(void *data)
+{
+ struct appdata *ad = (struct appdata *)data;
+ Evas_Object *spn = NULL;
+ Evas_Object *idletxtbox = NULL;
+
+ retif(ad == NULL, QP_FAIL, "Invalid parameter!");
+
+ _quickpanel_idletxt_unregister_event_handler();
+
+ retif(!ad->ly, QP_FAIL, "Invalid parameter!");
+
+ spn = elm_object_part_content_unset(ad->ly, QP_SPN_BASE_PART);
+ retif(!spn, QP_OK, "spn is NULL");
+
+ idletxtbox = elm_object_part_content_get(spn, QP_SPN_BOX_PART);
+ if (idletxtbox) {
+ elm_object_part_content_unset(spn, QP_SPN_BOX_PART);
+ evas_object_del(idletxtbox);
+ }
+
+ evas_object_del(spn);
+
+ return QP_OK;
+}
+
+static int quickpanel_idletxt_suspend(void *data)
+{
+ return QP_OK;
+}
+
+static int quickpanel_idletxt_resume(void *data)
+{
+ return QP_OK;
+}
+
+static void quickpanel_idletxt_lang_changed(void *data)
+{
+ retif(data == NULL, , "Invalid parameter!");
+
+ quickpanel_idletxt_update(data);
+}
diff --git a/daemon/list_util.c b/daemon/list_util.c
new file mode 100755
index 0000000..a4e5a5e
--- /dev/null
+++ b/daemon/list_util.c
@@ -0,0 +1,391 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <Elementary.h>
+#include <stdlib.h>
+
+#include "common.h"
+#include "list_util.h"
+
+struct _qp_item_data {
+ qp_item_type_e type;
+ void *data;
+};
+
+static qp_item_count g_qp_item_count = {
+ .group = 0,
+ .ongoing = 0,
+ .noti = 0,
+ .minicontrol = 0,
+};
+
+qp_item_data *quickpanel_list_util_item_new(qp_item_type_e type, void *data)
+{
+ qp_item_data *qid = NULL;
+
+ qid = malloc(sizeof(struct _qp_item_data));
+ if (!qid) {
+ ERR("fail to alloc qid");
+ return NULL;
+ }
+
+ qid->type = type;
+ qid->data = data;
+
+ return qid;
+}
+
+qp_item_type_e quickpanel_list_util_item_get_item_type(qp_item_data *qid)
+{
+ qp_item_type_e item_type = QP_ITEM_TYPE_NONE;
+
+ if (!qid)
+ return QP_ITEM_TYPE_NONE;
+
+ item_type = qid->type;
+
+ return item_type;
+}
+
+void *quickpanel_list_util_item_get_data(qp_item_data *qid)
+{
+ void *user_data = NULL;
+
+ if (!qid)
+ return NULL;
+
+ user_data = qid->data;
+
+ return user_data;
+}
+
+void quickpanel_list_util_item_set_data(qp_item_data *qid, void *data)
+{
+ if (!qid)
+ return ;
+
+ qid->data = data;
+}
+
+int quickpanel_list_util_item_compare(const void *data1, const void *data2)
+{
+ int diff = 0;
+ qp_item_data *qid1 = NULL;
+ qp_item_data *qid2 = NULL;
+ const Elm_Object_Item *it1 = data1;
+ const Elm_Object_Item *it2 = data2;
+
+ if (!it1) {
+ INFO("it1 is NULL");
+ return -1;
+ }
+
+ if (!it2) {
+ INFO("it2 is NULL");
+ return 1;
+ }
+
+ qid1 = elm_object_item_data_get(it1);
+ qid2 = elm_object_item_data_get(it2);
+
+ if (!qid1) {
+ INFO("qid1 is NULL");
+ return -1;
+ }
+
+ if (!qid2) {
+ INFO("qid2 is NULL");
+ return 1;
+ }
+
+ /* elm_genlist sort is not working as i expected */
+ if (qid1->type == qid2->type)
+ return 1;
+
+ diff = qid1->type - qid2->type;
+ return diff;
+}
+
+void quickpanel_list_util_item_del_by_type(Evas_Object *list,
+ const Elm_Object_Item *refer_item,
+ qp_item_type_e type)
+{
+ const Elm_Object_Item *start_item = NULL;
+
+ if (!list)
+ return;
+
+ if (refer_item)
+ start_item = refer_item;
+ else
+ start_item = elm_genlist_first_item_get(list);
+
+ while (start_item) {
+ qp_item_data *qid = NULL;
+ const Elm_Object_Item *next = NULL;
+
+ next = elm_genlist_item_next_get(start_item);
+ qid = elm_object_item_data_get(start_item);
+ if (!qid) {
+ ERR("fail to get qid, continue loop");
+ start_item = next;
+ continue;
+ }
+
+ if (qid->type > type)
+ break;
+ else if (qid->type == type)
+ elm_object_item_del((Elm_Object_Item *)start_item);
+
+ start_item = next;
+ }
+
+ return;
+}
+
+void quickpanel_list_util_item_update_by_type(Evas_Object *list,
+ Elm_Object_Item *refer_item,
+ qp_item_type_e type)
+{
+ Elm_Object_Item *start_item = NULL;
+
+ if (!list)
+ return;
+
+ if (refer_item)
+ start_item = refer_item;
+ else
+ start_item = elm_genlist_first_item_get(list);
+
+ while (start_item) {
+ qp_item_data *qid = NULL;
+ Elm_Object_Item *next = NULL;
+
+ next = elm_genlist_item_next_get(start_item);
+ qid = elm_object_item_data_get(start_item);
+ if (!qid) {
+ ERR("fail to get qid, continue loop");
+ start_item = next;
+ continue;
+ }
+
+ if (qid->type > type)
+ break;
+ else if (qid->type == type) {
+ elm_genlist_item_fields_update(start_item, "*", ELM_GENLIST_ITEM_FIELD_ALL);
+ }
+
+ start_item = next;
+ }
+
+ return;
+}
+
+Elm_Object_Item *quickpanel_list_util_find_item_by_type(Evas_Object *list,
+ void *data,
+ Elm_Object_Item *refer_item,
+ qp_item_type_e type)
+{
+ Elm_Object_Item *start_item = NULL;
+ Elm_Object_Item *found = NULL;
+
+ if (!list)
+ return NULL;
+
+ if (refer_item)
+ start_item = refer_item;
+ else
+ start_item = elm_genlist_first_item_get(list);
+
+ while (start_item) {
+ qp_item_data *qid = NULL;
+ Elm_Object_Item *next = NULL;
+ void *user_data = NULL;
+
+ next = elm_genlist_item_next_get(start_item);
+ qid = elm_object_item_data_get(start_item);
+ if (!qid) {
+ ERR("fail to get qid, continue loop");
+ start_item = next;
+ continue;
+ }
+
+ if (qid->type > type)
+ break;
+ else if (qid->type == type) {
+ user_data = quickpanel_list_util_item_get_data(qid);
+ if (user_data == data) {
+ found = start_item;
+ break;
+ }
+ }
+
+ start_item = next;
+ }
+
+ return found;
+}
+
+static int __item_compare(const void *data1, const void *data2)
+{
+ int diff = 0;
+ const Elm_Object_Item *it1 = data1;
+ const qp_item_data *qid1 = NULL;
+ const qp_item_data *qid2 = data2;
+
+ if (!data1) {
+ INFO("data1 is NULL");
+ return -1;
+ }
+
+ if (!data2) {
+ INFO("data2 is NULL");
+ return 1;
+ }
+
+ qid1 = elm_object_item_data_get(it1);
+
+ if (!qid1) {
+ INFO("qid1 is NULL");
+ return -1;
+ }
+
+ diff = qid1->type - qid2->type;
+
+ return diff;
+}
+
+
+Elm_Object_Item *quickpanel_list_util_sort_insert(Evas_Object *list,
+ const Elm_Genlist_Item_Class *itc,
+ const void *item_data,
+ Elm_Object_Item *parent,
+ Elm_Genlist_Item_Type type,
+ Evas_Smart_Cb func,
+ const void *func_data)
+{
+ Elm_Object_Item *it = NULL;
+ Elm_Object_Item *first = NULL;
+
+ retif(!list, NULL, "list is NULL");
+ retif(!itc, NULL, "itc is NULL");
+ retif(!item_data, NULL, "item_data is NULL");
+
+ first = elm_genlist_first_item_get(list);
+ while (first) {
+ if (__item_compare(first, item_data) >= 0)
+ break;
+
+ first = elm_genlist_item_next_get(first);
+ }
+
+ if (!first)
+ it = elm_genlist_item_append(list, itc, item_data, parent,
+ type, func, func_data);
+ else
+ it = elm_genlist_item_insert_before(list, itc, item_data,
+ parent, first, type, func, func_data);
+
+ if (it != NULL) {
+ quickpanel_list_util_add_count((qp_item_data *)item_data);
+ }
+
+ return it;
+}
+
+qp_item_count *quickpanel_list_util_get_item_count(void)
+{
+ return &g_qp_item_count;
+}
+
+void quickpanel_list_util_add_count(qp_item_data *qid)
+{
+ retif(qid == NULL, , "qid is NULL");
+
+ switch(qid->type)
+ {
+ case QP_ITEM_TYPE_ONGOING_NOTI:
+ g_qp_item_count.ongoing++;
+ break;
+ case QP_ITEM_TYPE_NOTI_GROUP:
+ g_qp_item_count.group++;
+ break;
+ case QP_ITEM_TYPE_NOTI:
+ g_qp_item_count.noti++;
+ break;
+ case QP_ITEM_TYPE_MINICTRL_ONGOING:
+ case QP_ITEM_TYPE_MINICTRL_TOP:
+ case QP_ITEM_TYPE_MINICTRL_MIDDLE:
+ case QP_ITEM_TYPE_MINICTRL_LOW:
+ g_qp_item_count.minicontrol++;
+ break;
+ case QP_ITEM_TYPE_NONE:
+ case QP_ITEM_TYPE_SETTING:
+ case QP_ITEM_TYPE_TOGGLE:
+ case QP_ITEM_TYPE_BRIGHTNESS:
+ case QP_ITEM_TYPE_MAX:
+ break;
+ }
+
+ DBG("(type:%d)\nnum_ongoing:%d, num_group:%d, num_noti:%d, num_minicontrol:%d"
+ , qid->type
+ , g_qp_item_count.ongoing
+ , g_qp_item_count.group
+ , g_qp_item_count.noti
+ , g_qp_item_count.minicontrol);
+}
+
+void quickpanel_list_util_del_count(qp_item_data *qid)
+{
+ retif(qid == NULL, , "qid is NULL");
+
+ quickpanel_list_util_del_count_by_itemtype(qid->type);
+}
+
+void quickpanel_list_util_del_count_by_itemtype(qp_item_type_e type)
+{
+ switch(type)
+ {
+ case QP_ITEM_TYPE_ONGOING_NOTI:
+ g_qp_item_count.ongoing = (g_qp_item_count.ongoing <= 0) ? 0 : g_qp_item_count.ongoing - 1;
+ break;
+ case QP_ITEM_TYPE_NOTI_GROUP:
+ g_qp_item_count.group = (g_qp_item_count.group <= 0) ? 0 : g_qp_item_count.group - 1;
+ break;
+ case QP_ITEM_TYPE_NOTI:
+ g_qp_item_count.noti = (g_qp_item_count.noti <= 0) ? 0 : g_qp_item_count.noti - 1;
+ break;
+ case QP_ITEM_TYPE_MINICTRL_ONGOING:
+ case QP_ITEM_TYPE_MINICTRL_TOP:
+ case QP_ITEM_TYPE_MINICTRL_MIDDLE:
+ case QP_ITEM_TYPE_MINICTRL_LOW:
+ g_qp_item_count.minicontrol = (g_qp_item_count.minicontrol <= 0) ? 0 : g_qp_item_count.minicontrol - 1;
+ break;
+ case QP_ITEM_TYPE_NONE:
+ case QP_ITEM_TYPE_SETTING:
+ case QP_ITEM_TYPE_TOGGLE:
+ case QP_ITEM_TYPE_BRIGHTNESS:
+ case QP_ITEM_TYPE_MAX:
+ break;
+ }
+
+ DBG("(type:%d)\nnum_ongoing:%d, num_group:%d, num_noti:%d, num_minicontrol:%d"
+ , type
+ , g_qp_item_count.ongoing
+ , g_qp_item_count.group
+ , g_qp_item_count.noti
+ , g_qp_item_count.minicontrol);
+}
diff --git a/daemon/list_util.h b/daemon/list_util.h
new file mode 100755
index 0000000..902ec2d
--- /dev/null
+++ b/daemon/list_util.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _QP_LIST_UTIL_DEF_
+#define _QP_LIST_UTIL_DEF_
+
+#include <Elementary.h>
+
+typedef enum {
+ QP_ITEM_TYPE_NONE = -1,
+ QP_ITEM_TYPE_SETTING = 0,
+ QP_ITEM_TYPE_TOGGLE,
+ QP_ITEM_TYPE_BRIGHTNESS,
+ QP_ITEM_TYPE_ONGOING_NOTI,
+ QP_ITEM_TYPE_MINICTRL_ONGOING,
+ QP_ITEM_TYPE_MINICTRL_TOP,
+ QP_ITEM_TYPE_MINICTRL_MIDDLE,
+ QP_ITEM_TYPE_MINICTRL_LOW,
+ QP_ITEM_TYPE_NOTI_GROUP,
+ QP_ITEM_TYPE_NOTI,
+ QP_ITEM_TYPE_MAX,
+} qp_item_type_e;
+
+typedef struct _qp_item_data qp_item_data;
+typedef struct _qp_item_count {
+ int group;
+ int ongoing;
+ int noti;
+ int minicontrol;
+} qp_item_count;
+
+
+qp_item_data *quickpanel_list_util_item_new(qp_item_type_e type, void *data);
+
+qp_item_type_e quickpanel_list_util_item_get_item_type(qp_item_data *qid);
+void *quickpanel_list_util_item_get_data(qp_item_data *qid);
+void quickpanel_list_util_item_set_data(qp_item_data *qid, void *data);
+
+int quickpanel_list_util_item_compare(const void *data1, const void *data2);
+
+void quickpanel_list_util_item_del_by_type(Evas_Object *list,
+ const Elm_Object_Item *refer_item,
+ qp_item_type_e type);
+
+void quickpanel_list_util_item_update_by_type(Evas_Object *list,
+ Elm_Object_Item *refer_item,
+ qp_item_type_e type);
+
+Elm_Object_Item *quickpanel_list_util_find_item_by_type(Evas_Object *list,
+ void *data,
+ Elm_Object_Item *refer_item,
+ qp_item_type_e type);
+
+Elm_Object_Item *quickpanel_list_util_sort_insert(Evas_Object *list,
+ const Elm_Genlist_Item_Class *itc,
+ const void *item_data,
+ Elm_Object_Item *parent,
+ Elm_Genlist_Item_Type type,
+ Evas_Smart_Cb func,
+ const void *func_data);
+
+qp_item_count *quickpanel_list_util_get_item_count(void);
+void quickpanel_list_util_add_count(qp_item_data *qid);
+void quickpanel_list_util_del_count(qp_item_data *qid);
+void quickpanel_list_util_del_count_by_itemtype(qp_item_type_e type);
+
+#endif /* _QP_LIST_UTIL_DEF_ */
+
diff --git a/daemon/minictrl/minictrl.c b/daemon/minictrl/minictrl.c
new file mode 100755
index 0000000..e7c7e74
--- /dev/null
+++ b/daemon/minictrl/minictrl.c
@@ -0,0 +1,457 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <glib.h>
+#include <Ecore_X.h>
+#include <minicontrol-viewer.h>
+#include <minicontrol-monitor.h>
+#include <string.h>
+#include "common.h"
+#include "quickpanel-ui.h"
+#include "list_util.h"
+#include "quickpanel_debug_util.h"
+
+#define QP_R_MARGIN 12
+#define MINICONTROL_WIDTH_P_MAX 692
+#define MINICONTROL_WIDTH_L_MAX 1252
+
+#define MINICONTROL_TYPE_STR_ONGOING "_ongoing]"
+
+static int quickpanel_minictrl_init(void *data);
+static int quickpanel_minictrl_fini(void *data);
+static unsigned int quickpanel_minictrl_get_height(void *data);
+
+QP_Module minictrl = {
+ .name = "minictrl",
+ .init = quickpanel_minictrl_init,
+ .fini = quickpanel_minictrl_fini,
+ .suspend = NULL,
+ .resume = NULL,
+ .hib_enter = NULL,
+ .hib_leave = NULL,
+ .lang_changed = NULL,
+ .refresh = NULL,
+ .get_height = quickpanel_minictrl_get_height,
+};
+
+struct _viewer_item {
+ char *name;
+ unsigned int width;
+ unsigned int height;
+ minicontrol_priority_e priority;
+ Evas_Object *viewer;
+ Elm_Object_Item *it;
+ void *data;
+};
+
+GHashTable *g_prov_table;
+
+static void _viewer_set_size(Evas_Object *viewer, void *data, int width, int height)
+{
+ retif(viewer == NULL, , "Invalid parameter!");
+ retif(data == NULL, , "Invalid parameter!");
+ retif(width < 0, , "Invalid parameter!");
+ retif(height < 0, , "Invalid parameter!");
+ struct appdata *ad = data;
+ int max_width = 0;
+ int resized_width = 0;
+
+ DBG("mini w:%d h:%d", width, height);
+
+ if (ad->angle == 90 || ad->angle == 270) {
+ max_width = (ad->scale * MINICONTROL_WIDTH_L_MAX) - 1;
+ } else {
+ max_width = (ad->scale * MINICONTROL_WIDTH_P_MAX) - 1;
+ }
+ resized_width = (width > max_width) ? max_width : width;
+ evas_object_size_hint_min_set(viewer, resized_width, height);
+}
+
+static void _viewer_item_free(struct _viewer_item *item)
+{
+ if (!item)
+ return;
+
+ if (item->name)
+ free(item->name);
+
+ if (item->it)
+ elm_object_item_del(item->it);
+
+ if (item->viewer) {
+ evas_object_unref(item->viewer);
+ evas_object_del(item->viewer);
+ }
+
+ free(item);
+}
+
+#if 0
+static Evas_Object *_minictrl_load_viewer(Evas_Object *parent,
+ struct _viewer_item *item)
+{
+ Evas_Object *viewer = NULL;
+
+ if (!parent) {
+ ERR("parent is NULL");
+ return NULL;
+ }
+
+ if (!item) {
+ ERR("item is NULL");
+ return NULL;
+ }
+
+ if (!item->name) {
+ ERR("item name is NULL");
+ return NULL;
+ }
+
+ viewer = minicontrol_viewer_add(parent, item->name);
+ if (!viewer) {
+ ERR("fail to create viewer for [%s]", item->name);
+ return NULL;
+ }
+
+ evas_object_size_hint_min_set(viewer, item->width - QP_R_MARGIN , item->height);
+
+ return viewer;
+}
+#endif
+
+static Evas_Object *_minictrl_gl_get_content(void *data, Evas_Object * obj,
+ const char *part)
+{
+ Evas_Object *content = NULL;
+ qp_item_data *qid = NULL;
+ struct _viewer_item *item = NULL;
+
+ retif(data == NULL, NULL, "Invalid parameter!");
+ qid = data;
+
+ item = quickpanel_list_util_item_get_data(qid);
+ retif(!item, NULL, "item is NULL");
+
+ if (strcmp(part, "elm.icon") == 0)
+ content = item->viewer;
+
+ return content;
+}
+
+
+static Eina_Bool _minictrl_gl_get_state(void *data, Evas_Object *obj,
+ const char *part)
+{
+ return EINA_FALSE;
+}
+
+static void _minictrl_gl_del(void *data, Evas_Object *obj)
+{
+ if (data) {
+ quickpanel_list_util_del_count(data);
+ free(data);
+ }
+
+ return;
+}
+
+static Elm_Genlist_Item_Class *_minictrl_gl_style_get(void)
+{
+ Elm_Genlist_Item_Class *itc = NULL;
+
+ itc = elm_genlist_item_class_new();
+ if (!itc) {
+ ERR("fail to elm_genlist_item_class_new()");
+ return NULL;
+ }
+
+ itc->item_style = "minicontrol/default";
+ itc->func.text_get = NULL;
+ itc->func.content_get = _minictrl_gl_get_content;
+ itc->func.state_get = _minictrl_gl_get_state;
+ itc->func.del = _minictrl_gl_del;
+
+ return itc;
+}
+
+static int _minictrl_is_ongoing(const char *str)
+{
+ if (str == NULL) return 0;
+
+ if (strstr(str, MINICONTROL_TYPE_STR_ONGOING) != NULL) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+qp_item_type_e _minictrl_priority_to_type(minicontrol_priority_e priority)
+{
+ qp_item_type_e type;
+
+ switch (priority) {
+ case MINICONTROL_PRIORITY_TOP:
+ type = QP_ITEM_TYPE_MINICTRL_TOP;
+ break;
+ case MINICONTROL_PRIORITY_MIDDLE:
+ type = QP_ITEM_TYPE_MINICTRL_MIDDLE;
+ break;
+ case MINICONTROL_PRIORITY_LOW:
+ default:
+ type = QP_ITEM_TYPE_MINICTRL_LOW;
+ break;
+ }
+
+ return type;
+}
+
+static void _minictrl_add(const char *name, unsigned int width,
+ unsigned int height,
+ minicontrol_priority_e priority,
+ void *data)
+{
+ qp_item_data *qid = NULL;
+ Elm_Genlist_Item_Class *itc = NULL;
+ struct _viewer_item *vit = NULL;
+ qp_item_type_e type;
+ struct appdata *ad;
+ Evas_Object *viewer = NULL;
+
+ retif(!name, , "name is NULL");
+ retif(!data, , "data is NULL");
+
+ ad = data;
+ retif(!ad->list, , "list is NULL");
+
+ if (g_prov_table) {
+ struct _viewer_item *found = NULL;
+ found = g_hash_table_lookup(g_prov_table, name);
+
+ if (found) {
+ ERR("already have it : %s", name);
+ return;
+ }
+ } else {
+ ERR("g_prov_table is NULL");
+ return;
+ }
+
+ /* elm_plug receives 'server_del' event,
+ * if it repeats connect and disconnect frequently.
+ *
+ */
+ viewer = minicontrol_viewer_add(ad->list, name);
+ if (!viewer) {
+ ERR("fail to add viewer - %s", name);
+ return;
+ }
+ evas_object_ref(viewer);
+ _viewer_set_size(viewer, ad, width, height);
+
+ itc = _minictrl_gl_style_get();
+ if (!itc) {
+ ERR("fail to _minictrl_gl_style_get()");
+ evas_object_del(viewer);
+ return;
+ }
+
+ vit = malloc(sizeof(struct _viewer_item));
+ if (!vit) {
+ ERR("fail to alloc vit");
+ evas_object_del(viewer);
+ elm_genlist_item_class_free(itc);
+ return;
+ }
+
+
+ if (_minictrl_is_ongoing(name) == 1) {
+ DBG("QP_ITEM_TYPE_MINICTRL_ONGOING is added");
+ type = QP_ITEM_TYPE_MINICTRL_ONGOING;
+ } else {
+ type = _minictrl_priority_to_type(priority);
+ }
+ qid = quickpanel_list_util_item_new(type, vit);
+ if (!qid) {
+ ERR("fail to alloc vit");
+ evas_object_del(viewer);
+ elm_genlist_item_class_free(itc);
+ free(vit);
+ return;
+ }
+ vit->name = strdup(name);
+ vit->width = width;
+ vit->height = height;
+ vit->priority = priority;
+ vit->viewer = viewer;
+ vit->data = data;
+ vit->it = quickpanel_list_util_sort_insert(ad->list, itc, qid, NULL,
+ ELM_GENLIST_ITEM_NONE, NULL, NULL);
+
+ g_hash_table_insert(g_prov_table, g_strdup(name), vit);
+
+ INFO("success to add %s", name);
+
+ elm_genlist_item_class_free(itc);
+
+ quickpanel_ui_update_height(ad);
+}
+
+static void _minictrl_remove(const char *name, void *data)
+{
+ if (g_prov_table) {
+ if (g_hash_table_remove(g_prov_table, name))
+ {
+ INFO("success to remove %s", name);
+
+ retif(data == NULL, , "data is NULL");
+ quickpanel_ui_update_height(data);
+ }
+ else
+ WARN("unknown provider name : %s", name);
+ }
+}
+
+static void _minictrl_update(const char *name, unsigned int width,
+ unsigned int height, void *data)
+{
+ struct _viewer_item *found = NULL;
+ struct appdata *ad = NULL;
+
+ if (!g_prov_table)
+ return;
+
+ retif(!data, , "data is NULL");
+ ad = data;
+
+ found = g_hash_table_lookup(g_prov_table, name);
+
+ if (!found) {
+ WARN("unknown provider name : %s", name);
+ return;
+ }
+
+ found->width = width;
+ found->height = height;
+
+ if (found->viewer) {
+ _viewer_set_size(found->viewer, ad, width, height);
+ }
+
+ if (found->it) {
+ elm_genlist_item_update(found->it);
+ quickpanel_ui_update_height(ad);
+ }
+}
+
+static void _minictrl_request(const char *name, int action, void *data)
+{
+ Ecore_X_Window xwin;
+ struct appdata *ad = NULL;
+ retif(!name, , "name is NULL");
+ retif(!data, , "data is NULL");
+ ad = data;
+
+ if (action == MINICONTROL_REQ_HIDE_VIEWER) {
+ xwin = elm_win_xwindow_get(ad->win);
+ if (xwin != 0) {
+ DBG("close by minictrl:%s", name);
+ debug_printf("close by minictrl:%s", name);
+ ecore_x_e_illume_quickpanel_state_send(ecore_x_e_illume_zone_get(xwin),ECORE_X_ILLUME_QUICKPANEL_STATE_OFF);
+ }
+ }
+}
+
+static void _mctrl_monitor_cb(minicontrol_action_e action,
+ const char *name, unsigned int width,
+ unsigned int height,
+ minicontrol_priority_e priority,
+ void *data)
+{
+ retif(!data, , "data is NULL");
+ retif(!name, , "name is NULL");
+
+ switch (action) {
+ case MINICONTROL_ACTION_START:
+ _minictrl_add(name, width, height, priority, data);
+ break;
+ case MINICONTROL_ACTION_RESIZE:
+ _minictrl_update(name, width, height, data);
+ break;
+ case MINICONTROL_ACTION_STOP:
+ _minictrl_remove(name, data);
+ break;
+ case MINICONTROL_ACTION_REQUEST:
+ _minictrl_request(name, width, data);
+ break;
+ default:
+ break;
+ }
+}
+
+static int quickpanel_minictrl_init(void *data)
+{
+ minicontrol_error_e ret;
+
+ retif(!data, QP_FAIL, "Invalid parameter!");
+
+ g_prov_table = g_hash_table_new_full(g_str_hash, g_str_equal,
+ (GDestroyNotify)g_free,
+ (GDestroyNotify)_viewer_item_free);
+
+ ret = minicontrol_monitor_start(_mctrl_monitor_cb, data);
+ if (ret != MINICONTROL_ERROR_NONE) {
+ ERR("fail to minicontrol_monitor_start()- %d", ret);
+ return QP_FAIL;
+ }
+
+ return QP_OK;
+}
+
+static int quickpanel_minictrl_fini(void *data)
+{
+ minicontrol_error_e ret;
+ ret = minicontrol_monitor_stop();
+ if (ret != MINICONTROL_ERROR_NONE)
+ ERR("fail to minicontrol_monitor_stop()- %d", ret);
+
+ if (g_prov_table) {
+ g_hash_table_remove_all(g_prov_table);
+ g_prov_table = NULL;
+ }
+
+ return QP_OK;
+}
+
+
+static void _quickpanel_minictrl_hf_sum_height(gpointer key, gpointer value, gpointer data)
+{
+ struct _viewer_item *item = value;
+
+ if (item != NULL && data != NULL) {
+ *((unsigned int *)data) += item->height;
+ }
+}
+
+static unsigned int quickpanel_minictrl_get_height(void *data)
+{
+ unsigned int height_minictrl = 0;
+
+ if (g_prov_table != NULL) {
+ g_hash_table_foreach(g_prov_table, _quickpanel_minictrl_hf_sum_height, &height_minictrl);
+ }
+
+ return height_minictrl;
+}
diff --git a/daemon/modules.c b/daemon/modules.c
new file mode 100755
index 0000000..a1ddd81
--- /dev/null
+++ b/daemon/modules.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "common.h"
+#include "modules.h"
+
+/*******************************************************************
+ *
+ * MODULES
+ *
+ *****************************************************************/
+/* searchbar */
+/* extern QP_Module searchbar; */
+#ifdef QP_MINICTRL_ENABLE
+extern QP_Module minictrl;
+#endif /* QP_MINICTRL_ENABLE */
+#ifdef QP_BRIGHTNESS_ENABLE
+/* brightness */
+extern QP_Module brightness_ctrl;
+#endif /* QP_BRIGHTNESS_ENABLE */
+/* notification */
+extern QP_Module noti;
+extern QP_Module ticker;
+extern QP_Module ticker_status;
+/* idle test */
+extern QP_Module idletxt;
+
+static QP_Module *modules[] = {
+#ifdef QP_MINICTRL_ENABLE
+ &minictrl,
+#endif /* QP_MINICTRL_ENABLE */
+#ifdef QP_BRIGHTNESS_ENABLE
+ &brightness_ctrl,
+#endif /* QP_BRIGHTNESS_ENABLE */
+ &noti,
+ &ticker,
+ &ticker_status,
+ &idletxt
+};
+
+int init_modules(void *data)
+{
+ int i;
+
+ retif(data == NULL, QP_FAIL, "Invalid parameter!");
+
+ for (i = 0; i < sizeof(modules) / sizeof(modules[0]); i++) {
+ if (modules[i]->init)
+ modules[i]->init(data);
+ }
+
+ return QP_OK;
+}
+
+int fini_modules(void *data)
+{
+ int i;
+
+ retif(data == NULL, QP_FAIL, "Invalid parameter!");
+
+ for (i = 0; i < sizeof(modules) / sizeof(modules[0]); i++) {
+ if (modules[i]->fini)
+ modules[i]->fini(data);
+ }
+
+ return QP_OK;
+}
+
+int suspend_modules(void *data)
+{
+ int i;
+
+ retif(data == NULL, QP_FAIL, "Invalid parameter!");
+
+ for (i = 0; i < sizeof(modules) / sizeof(modules[0]); i++) {
+ if (modules[i]->suspend)
+ modules[i]->suspend(data);
+ }
+
+ return QP_OK;
+}
+
+int resume_modules(void *data)
+{
+ int i;
+
+ retif(data == NULL, QP_FAIL, "Invalid parameter!");
+
+ for (i = 0; i < sizeof(modules) / sizeof(modules[0]); i++) {
+ if (modules[i]->resume)
+ modules[i]->resume(data);
+ }
+
+ return QP_OK;
+}
+
+int hib_enter_modules(void *data)
+{
+ int i;
+
+ retif(data == NULL, QP_FAIL, "Invalid parameter!");
+
+ for (i = 0; i < sizeof(modules) / sizeof(modules[0]); i++) {
+ if (modules[i]->hib_enter)
+ modules[i]->hib_enter(data);
+ }
+
+ return QP_OK;
+}
+
+int hib_leave_modules(void *data)
+{
+ int i;
+
+ retif(data == NULL, QP_FAIL, "Invalid parameter!");
+
+ for (i = 0; i < sizeof(modules) / sizeof(modules[0]); i++) {
+ if (modules[i]->hib_leave)
+ modules[i]->hib_leave(data);
+ }
+
+ return QP_OK;
+}
+
+/******************************************************************
+ *
+ * LANGUAGE
+ *
+ ****************************************************************/
+
+void lang_change_modules(void *data)
+{
+ int i;
+ retif(data == NULL, , "Invalid parameter!");
+
+ for (i = 0; i < sizeof(modules) / sizeof(modules[0]); i++) {
+ if (modules[i]->lang_changed)
+ modules[i]->lang_changed(data);
+ }
+}
+
+void refresh_modules(void *data)
+{
+ int i;
+ retif(data == NULL, , "Invalid parameter!");
+
+ for (i = 0; i < sizeof(modules) / sizeof(modules[0]); i++) {
+ if (modules[i]->refresh)
+ modules[i]->refresh(data);
+ }
+}
+
+/******************************************************************
+ *
+ * Quickpanel open/close Events
+ *
+ ****************************************************************/
+int qp_opened_modules(void *data)
+{
+ int i;
+
+ retif(data == NULL, QP_FAIL, "Invalid parameter!");
+
+ for (i = 0; i < sizeof(modules) / sizeof(modules[0]); i++) {
+ if (modules[i]->qp_opened)
+ modules[i]->qp_opened(data);
+ }
+
+ return QP_OK;
+}
+
+int qp_closed_modules(void *data)
+{
+ int i;
+
+ retif(data == NULL, QP_FAIL, "Invalid parameter!");
+
+ for (i = 0; i < sizeof(modules) / sizeof(modules[0]); i++) {
+ if (modules[i]->qp_closed)
+ modules[i]->qp_closed(data);
+ }
+
+ return QP_OK;
+}
diff --git a/daemon/modules.h b/daemon/modules.h
new file mode 100755
index 0000000..99ec615
--- /dev/null
+++ b/daemon/modules.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __QP_MODULES_H__
+#define __QP_MODULES_H__
+
+#include <stdlib.h>
+#include "quickpanel-ui.h"
+
+extern int init_modules(void *data);
+extern int fini_modules(void *data);
+extern int suspend_modules(void *data);
+extern int resume_modules(void *data);
+extern int hib_enter_modules(void *data);
+extern int hib_leave_modules(void *data);
+extern void lang_change_modules(void *data);
+extern void refresh_modules(void *data);
+extern int qp_opened_modules(void *data);
+extern int qp_closed_modules(void *data);
+
+#endif /* __QP_MODULES_H__ */
diff --git a/daemon/notifications/brightness.c b/daemon/notifications/brightness.c
new file mode 100755
index 0000000..1a98da7
--- /dev/null
+++ b/daemon/notifications/brightness.c
@@ -0,0 +1,464 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include <vconf.h>
+#include <device.h>
+#include "common.h"
+#include "quickpanel-ui.h"
+#include "list_util.h"
+#include "quickpanel_theme_def.h"
+
+#define BRIGHTNESS_MIN 1
+#define BRIGHTNESS_MAX 100
+
+#define QP_BRIGHTNESS_CONTROL_ICON_IMG ICONDIR"/Q02_Notification_brightness.png"
+
+static int quickpanel_brightness_init(void *data);
+static int quickpanel_brightness_fini(void *data);
+static void quickpanel_brightness_lang_changed(void *data);
+static unsigned int quickpanel_brightness_get_height(void *data);
+static void quickpanel_brightness_qp_opened(void *data);
+static void quickpanel_brightness_qp_closed(void *data);
+
+QP_Module brightness_ctrl = {
+ .name = "brightness_ctrl",
+ .init = quickpanel_brightness_init,
+ .fini = quickpanel_brightness_fini,
+ .suspend = NULL,
+ .resume = NULL,
+ .hib_enter = NULL,
+ .hib_leave = NULL,
+ .lang_changed = quickpanel_brightness_lang_changed,
+ .refresh = NULL,
+ .get_height = quickpanel_brightness_get_height,
+ .qp_opened = quickpanel_brightness_qp_opened,
+ .qp_closed = quickpanel_brightness_qp_closed,
+};
+
+typedef struct _brightness_ctrl_obj {
+ int min_level;
+ int max_level;
+ Evas_Object *checker;
+ Evas_Object *slider;
+ Elm_Object_Item *it;
+ void *data;
+} brightness_ctrl_obj;
+
+brightness_ctrl_obj *g_ctrl_obj;
+
+static void _brightness_vconf_cb(keynode_t *key, void* data) {
+ brightness_ctrl_obj *ctrl_obj = NULL;
+
+ retif(data == NULL, , "Data parameter is NULL");
+ ctrl_obj = data;
+
+ if (ctrl_obj->it != NULL) {
+ elm_genlist_item_fields_update(ctrl_obj->it, "elm.check.swallow", ELM_GENLIST_ITEM_FIELD_CONTENT);
+ elm_genlist_item_fields_update(g_ctrl_obj->it, "elm.swallow.slider", ELM_GENLIST_ITEM_FIELD_CONTENT);
+ }
+}
+
+static void quickpanel_brightness_qp_opened(void *data)
+{
+ struct appdata *ad = NULL;
+
+ retif(data == NULL, , "Invalid parameter!");
+ ad = data;
+
+ retif(g_ctrl_obj == NULL, , "Invalid parameter!");
+
+ if (g_ctrl_obj->it != NULL) {
+ elm_genlist_item_fields_update(g_ctrl_obj->it, "elm.swallow.slider", ELM_GENLIST_ITEM_FIELD_CONTENT);
+ elm_genlist_item_fields_update(g_ctrl_obj->it, "elm.check.swallow", ELM_GENLIST_ITEM_FIELD_CONTENT);
+ vconf_ignore_key_changed(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, _brightness_vconf_cb);
+ }
+}
+
+static void quickpanel_brightness_qp_closed(void *data)
+{
+ struct appdata *ad = NULL;
+
+ retif(data == NULL, , "Invalid parameter!");
+ ad = data;
+
+ retif(g_ctrl_obj == NULL, , "Invalid parameter!");
+
+ if (g_ctrl_obj->it != NULL) {
+ vconf_notify_key_changed(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, _brightness_vconf_cb, g_ctrl_obj);
+ }
+}
+
+int _brightness_is_low_battery(void) {
+ int battery_value;
+
+ vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &battery_value);
+
+ if (battery_value < VCONFKEY_SYSMAN_BAT_WARNING_LOW)
+ return 1;
+ else
+ return 0;
+}
+
+int _brightness_set_level(int level) {
+ int ret = DEVICE_ERROR_NONE;
+
+ ret = device_set_brightness_to_settings(0, level);
+ if (ret != DEVICE_ERROR_NONE) {
+ ERR("failed to set brightness");
+ }
+
+ return level;
+}
+
+int _brightness_get_level(void) {
+ int level = 0;
+
+ if (vconf_get_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, &level) == 0)
+ return level;
+ else
+ return SETTING_BRIGHTNESS_LEVEL5;
+}
+
+int _brightness_set_automate_level(int is_on) {
+ return vconf_set_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, is_on);
+}
+
+int _brightness_get_automate_level(void) {
+ int is_on = 0;
+
+ if (vconf_get_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, &is_on) == 0)
+ return is_on;
+ else
+ return SETTING_BRIGHTNESS_AUTOMATIC_OFF;
+}
+
+static void
+_brightness_ctrl_slider_changed_cb(void *data,
+ Evas_Object *obj,
+ void *event_info)
+{
+ int ret = DEVICE_ERROR_NONE;
+ int value = 0;
+ static int old_val = -1;
+ brightness_ctrl_obj *ctrl_obj = NULL;
+
+ DBG("");
+
+ retif(data == NULL, , "Data parameter is NULL");
+ ctrl_obj = data;
+
+ if (ctrl_obj->checker != NULL) {
+ value = elm_check_state_get(ctrl_obj->checker);
+ if (value == 1) { /* it is automatic setting mode, */
+ /* do nothing */
+ return;
+ }
+ }
+
+ double val = elm_slider_value_get(obj);
+ value = (int)(val + 0.5);
+
+ DBG("value:%d old_val:%d", value, old_val);
+
+ if (value != old_val)
+ {
+ DBG("min_level:%d max_level:%d", ctrl_obj->min_level, ctrl_obj->max_level);
+ if (value >= ctrl_obj->min_level && value <= ctrl_obj->max_level) {
+ DBG("new brgt:%d", value);
+ ret = device_set_brightness_to_settings(0, value);
+ old_val = value;
+ if (ret != DEVICE_ERROR_NONE) {
+ ERR("failed to set brightness");
+ }
+ }
+ }
+}
+
+static void
+_brightness_ctrl_slider_delayed_changed_cb(void *data,
+ Evas_Object *obj,
+ void *event_info)
+{
+ int ret = DEVICE_ERROR_NONE;
+ int value = 0;
+
+ ret = device_get_brightness(0, &value);
+
+ DBG("ret:%d value:%d", ret, value);
+ if (ret == DEVICE_ERROR_NONE) {
+ DBG("delayed new brgt:%d", value);
+ _brightness_set_level(value);
+ }
+}
+
+static void _brightness_ctrl_checker_toggle_cb(void *data,
+ Evas_Object * obj,
+ void *event_info)
+{
+ retif(obj == NULL, , "obj parameter is NULL");
+
+ int status = elm_check_state_get(obj);
+ brightness_ctrl_obj *ctrl_obj = NULL;
+
+ retif(data == NULL, , "Data parameter is NULL");
+ ctrl_obj = data;
+
+ _brightness_set_automate_level(status);
+
+ if (ctrl_obj->it != NULL) {
+ elm_genlist_item_fields_update(ctrl_obj->it, "elm.swallow.slider", ELM_GENLIST_ITEM_FIELD_CONTENT);
+ elm_genlist_item_fields_update(ctrl_obj->it, "elm.check.swallow", ELM_GENLIST_ITEM_FIELD_CONTENT);
+ }
+}
+
+static char *_quickpanel_noti_gl_get_text(void *data, Evas_Object * obj,
+ const char *part)
+{
+ if (strcmp(part, "elm.check.text") == 0) {
+ return strdup(_("IDS_QP_BODY_AUTO"));
+ }
+ if (strcmp(part, "elm.text.label") == 0) {
+ return strdup(_S("IDS_COM_OPT_BRIGHTNESS"));
+ }
+ return NULL;
+}
+
+static Evas_Object *_brightness_gl_get_content(void *data, Evas_Object * obj,
+ const char *part)
+{
+ qp_item_data *qid = NULL;
+ brightness_ctrl_obj *ctrl_obj = NULL;
+
+ retif(data == NULL, NULL, "Invalid parameter!");
+ qid = data;
+
+ ctrl_obj = quickpanel_list_util_item_get_data(qid);
+ retif(!ctrl_obj, NULL, "item is NULL");
+
+ if (strcmp(part, "elm.swallow.thumbnail") == 0) {
+ Evas_Object *image = elm_image_add(obj);
+
+ if (image != NULL) {
+ elm_image_file_set(image, QP_BRIGHTNESS_CONTROL_ICON_IMG, NULL);
+ elm_image_resizable_set(image, EINA_FALSE, EINA_TRUE);
+ }
+
+ return image;
+ } else if (strcmp(part, "elm.swallow.slider") == 0) {
+ int value = _brightness_get_level();
+ Evas_Object *slider = elm_slider_add(obj);
+
+ if (slider != NULL) {
+ ctrl_obj->slider = NULL;
+ elm_object_style_set(slider, "quickpanel");
+ elm_slider_indicator_format_set(slider, "%1.0f");
+
+ evas_object_size_hint_weight_set(slider, EVAS_HINT_EXPAND, 0.0);
+ evas_object_size_hint_align_set(slider, EVAS_HINT_FILL, 0.5);
+ elm_slider_min_max_set(slider, ctrl_obj->min_level, ctrl_obj->max_level);
+ elm_slider_value_set(slider, value);
+ evas_object_smart_callback_add(slider, "changed", _brightness_ctrl_slider_changed_cb, ctrl_obj);
+ evas_object_smart_callback_add(slider, "delay,changed", _brightness_ctrl_slider_delayed_changed_cb, ctrl_obj);
+
+ if (_brightness_get_automate_level() || _brightness_is_low_battery() == 1) {
+ elm_object_disabled_set(slider, EINA_TRUE);
+ } else {
+ elm_object_disabled_set(slider, EINA_FALSE);
+ }
+
+ ctrl_obj->slider = slider;
+ return slider;
+ }
+ } else if (strcmp(part, "elm.check.swallow") == 0) {
+ Evas_Object *checker = elm_check_add(obj);
+
+ if (checker != NULL) {
+ ctrl_obj->checker = NULL;
+
+ elm_object_style_set(checker, "quickpanel");
+ elm_check_state_set(checker, _brightness_get_automate_level());
+ evas_object_smart_callback_add(checker,"changed",_brightness_ctrl_checker_toggle_cb , ctrl_obj);
+
+ if (_brightness_is_low_battery() == 1) {
+ elm_object_disabled_set(checker, EINA_TRUE);
+ } else {
+ elm_object_disabled_set(checker, EINA_FALSE);
+ }
+ ctrl_obj->checker = checker;
+
+ return checker;
+ }
+ }
+
+ return NULL;
+}
+
+static Eina_Bool _brightness_gl_get_state(void *data, Evas_Object *obj,
+ const char *part)
+{
+ return EINA_FALSE;
+}
+
+static void _brightness_gl_del(void *data, Evas_Object *obj)
+{
+ if (data) {
+ quickpanel_list_util_del_count(data);
+ free(data);
+ }
+
+ return;
+}
+
+static Elm_Genlist_Item_Class *_brightness_gl_style_get(void)
+{
+ Elm_Genlist_Item_Class *itc = NULL;
+
+ itc = elm_genlist_item_class_new();
+ if (!itc) {
+ ERR("fail to elm_genlist_item_class_new()");
+ return NULL;
+ }
+
+ itc->item_style = "brightness_controller/default";
+ itc->func.text_get = _quickpanel_noti_gl_get_text;
+ itc->func.content_get = _brightness_gl_get_content;
+ itc->func.state_get = _brightness_gl_get_state;
+ itc->func.del = _brightness_gl_del;
+
+ return itc;
+}
+
+static void _brightness_add(brightness_ctrl_obj *ctrl_obj, void *data)
+{
+ qp_item_data *qid = NULL;
+ Elm_Genlist_Item_Class *itc = NULL;
+ qp_item_type_e type = QP_ITEM_TYPE_BRIGHTNESS;
+ struct appdata *ad;
+
+ ad = data;
+ retif(!ad->list, , "list is NULL");
+
+ itc = _brightness_gl_style_get();
+ if (!itc) {
+ ERR("fail to _brightness_gl_style_get()");
+ return;
+ }
+
+ qid = quickpanel_list_util_item_new(type, ctrl_obj);
+ if (!qid) {
+ ERR("fail to alloc vit");
+ elm_genlist_item_class_free(itc);
+ free(g_ctrl_obj);
+ return;
+ }
+ ctrl_obj->data = data;
+ ctrl_obj->it = quickpanel_list_util_sort_insert(ad->list, itc, qid, NULL,
+ ELM_GENLIST_ITEM_NONE, NULL, NULL);
+
+ elm_genlist_item_class_free(itc);
+
+ quickpanel_ui_update_height(ad);
+}
+
+static void _brightness_remove(brightness_ctrl_obj *ctrl_obj, void *data)
+{
+ if (g_ctrl_obj != NULL) {
+ INFO("success to remove brightness controller");
+ free(g_ctrl_obj);
+ g_ctrl_obj = NULL;
+ retif(data == NULL, , "data is NULL");
+ quickpanel_ui_update_height(data);
+ }
+}
+
+static void _brightness_register_event_cb(brightness_ctrl_obj *ctrl_obj)
+{
+ retif(ctrl_obj == NULL, , "Invalid parameter!");
+
+ vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, _brightness_vconf_cb, ctrl_obj);
+ vconf_notify_key_changed(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, _brightness_vconf_cb, ctrl_obj);
+}
+
+static void _brightness_deregister_event_cb(brightness_ctrl_obj *ctrl_obj)
+{
+ retif(ctrl_obj == NULL, , "Invalid parameter!");
+
+ vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, _brightness_vconf_cb);
+ vconf_ignore_key_changed(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, _brightness_vconf_cb);
+}
+
+static int quickpanel_brightness_init(void *data)
+{
+ retif(data == NULL, QP_FAIL, "Invalid parameter!");
+
+ if (g_ctrl_obj == NULL) {
+ DBG("brightness controller alloced");
+ g_ctrl_obj = (brightness_ctrl_obj *)malloc(sizeof(brightness_ctrl_obj));
+ }
+
+ DBG("");
+
+ if (g_ctrl_obj != NULL) {
+ g_ctrl_obj->min_level = BRIGHTNESS_MIN;
+ g_ctrl_obj->max_level = BRIGHTNESS_MAX;
+
+ DBG("brightness range %d~%d\n", g_ctrl_obj->min_level, g_ctrl_obj->max_level);
+
+ _brightness_add(g_ctrl_obj, data);
+ _brightness_register_event_cb(g_ctrl_obj);
+ }
+
+ return QP_OK;
+}
+
+static int quickpanel_brightness_fini(void *data)
+{
+ retif(data == NULL, QP_FAIL, "Invalid parameter!");
+
+ if (g_ctrl_obj != NULL) {
+ _brightness_deregister_event_cb(g_ctrl_obj);
+ _brightness_remove(g_ctrl_obj, data);
+ }
+
+ _brightness_remove(g_ctrl_obj, data);
+
+ g_ctrl_obj = NULL;
+ return QP_OK;
+}
+
+static void quickpanel_brightness_lang_changed(void *data)
+{
+ retif(data == NULL, , "Invalid parameter!");
+
+ if (g_ctrl_obj != NULL && g_ctrl_obj->it != NULL) {
+ elm_genlist_item_fields_update(g_ctrl_obj->it, "elm.check.text", ELM_GENLIST_ITEM_FIELD_TEXT);
+ elm_genlist_item_fields_update(g_ctrl_obj->it, "elm.text.label", ELM_GENLIST_ITEM_FIELD_TEXT);
+ }
+}
+
+static unsigned int quickpanel_brightness_get_height(void *data)
+{
+ struct appdata *ad = data;
+
+ retif(ad == NULL, 0, "Invalid parameter!");
+
+ if (g_ctrl_obj != NULL)
+ return QP_THEME_LIST_ITEM_BRIGHTNESS_HEIGHT * ad->scale;
+ else
+ return 0;
+}
diff --git a/daemon/notifications/noti.c b/daemon/notifications/noti.c
new file mode 100755
index 0000000..ecec5c3
--- /dev/null
+++ b/daemon/notifications/noti.c
@@ -0,0 +1,1999 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <appsvc.h>
+
+#include <time.h>
+#include <vconf.h>
+#include <appcore-common.h>
+#include <app_service.h>
+#include <runtime_info.h>
+#include <Ecore_X.h>
+
+#include <unicode/uloc.h>
+#include <unicode/udat.h>
+#include <unicode/udatpg.h>
+#include <unicode/ustring.h>
+#ifdef QP_DETAILED_NOTI_CHANGE_CB_ENABLE
+#include "noti_node.h"
+#endif
+#include <notification.h>
+
+#include "quickpanel-ui.h"
+#include "common.h"
+#include "list_util.h"
+#include "quickpanel_theme_def.h"
+#include "noti_gridbox.h"
+#include "noti_box.h"
+#include "noti.h"
+
+#ifndef VCONFKEY_QUICKPANEL_STARTED
+#define VCONFKEY_QUICKPANEL_STARTED "memory/private/"PACKAGE_NAME"/started"
+#endif /* VCONFKEY_QUICKPANEL_STARTED */
+
+#define QP_DEFAULT_ICON ICONDIR"/quickpanel_icon_default.png"
+#define QP_NOTI_DAY_DEC (24 * 60 * 60)
+
+#define QP_NOTI_ONGOING_DBUS_PATH "/dbus/signal"
+#define QP_NOTI_ONGOING_DBUS_INTERFACE "notification.ongoing"
+
+static int suspended;
+
+#ifdef QP_DETAILED_NOTI_CHANGE_CB_ENABLE
+noti_node *g_noti_node;
+#else
+static notification_list_h g_notification_list;
+static notification_list_h g_notification_ongoing_list;
+#endif
+static Eina_List *g_animated_image_list;
+
+static Evas_Object *g_noti_gridbox;
+static Elm_Genlist_Item_Class *itc_noti;
+static Elm_Genlist_Item_Class *itc_ongoing;
+static Elm_Genlist_Item_Class *g_itc;
+
+static Evas_Object *g_window;
+
+static Elm_Object_Item *noti_group;
+static Elm_Object_Item *ongoing_first;
+static Elm_Object_Item *noti_first;
+
+static int quickpanel_noti_init(void *data);
+static int quickpanel_noti_fini(void *data);
+static int quickpanel_noti_suspend(void *data);
+static int quickpanel_noti_resume(void *data);
+static void quickpanel_noti_lang_changed(void *data);
+static void quickpanel_noti_refresh(void *data);
+static unsigned int quickpanel_noti_get_height(void *data);
+
+QP_Module noti = {
+ .name = "noti",
+ .init = quickpanel_noti_init,
+ .fini = quickpanel_noti_fini,
+ .suspend = quickpanel_noti_suspend,
+ .resume = quickpanel_noti_resume,
+ .lang_changed = quickpanel_noti_lang_changed,
+ .hib_enter = NULL,
+ .hib_leave = NULL,
+ .refresh = quickpanel_noti_refresh,
+ .get_height = quickpanel_noti_get_height,
+};
+
+Eina_Bool _quickpanel_noti_update_notibox_idler(void *data)
+{
+ retif(data == NULL, ECORE_CALLBACK_CANCEL, "data is null");
+
+ Elm_Object_Item *item = data;
+ elm_genlist_item_update(item);
+
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static void _quickpanel_noti_update_notibox(void) {
+ if (noti_group != NULL) {
+ ecore_idler_add(_quickpanel_noti_update_notibox_idler, noti_group);
+ }
+
+ if (noti_first != NULL) {
+ ecore_idler_add(_quickpanel_noti_update_notibox_idler, noti_first);
+ }
+}
+
+static void _quickpanel_noti_clear_clicked_cb(void *data, Evas_Object * obj,
+ void *event_info)
+{
+ notification_error_e noti_err = NOTIFICATION_ERROR_NONE;
+
+ noti_err = notifiation_clear(NOTIFICATION_TYPE_NOTI);
+
+ DBG("Clear Clicked : noti_err(%d)", noti_err);
+}
+
+static char *_quickpanel_noti_get_progress(notification_h noti, char *buf,
+ int buf_len)
+{
+ double size = 0.0;
+ double percentage = 0.0;
+
+ retif(noti == NULL, NULL, "Invalid parameter!");
+
+ notification_get_size(noti, &size);
+ notification_get_progress(noti, &percentage);
+
+ if (percentage < 1 && percentage > 0) {
+ if (snprintf(buf, buf_len, "%d%%", (int)(percentage * 100))
+ <= 0)
+ return NULL;
+
+ return buf;
+ } else if (size > 0) {
+ if (size > (1 << 30)) {
+ if (snprintf(buf, buf_len, "%.1lfGB",
+ size / 1000000000.0) <= 0)
+ return NULL;
+
+ return buf;
+ } else if (size > (1 << 20)) {
+ if (snprintf(buf, buf_len, "%.1lfMB",
+ size / 1000000.0) <= 0)
+ return NULL;
+
+ return buf;
+ } else if (size > (1 << 10)) {
+ if (snprintf(buf, buf_len, "%.1lfKB",
+ size / 1000.0) <= 0)
+ return NULL;
+
+ return buf;
+ } else {
+ if (snprintf(buf, buf_len, "%lfB", size) <= 0)
+ return NULL;
+
+ return buf;
+ }
+ }
+
+ return NULL;
+}
+
+static notification_h _quickpanel_noti_update_item_progress(const char *pkgname,
+ int priv_id,
+ double progress)
+{
+#ifdef QP_DETAILED_NOTI_CHANGE_CB_ENABLE
+ char *noti_pkgname = NULL;
+ int noti_priv_id = 0;
+
+ noti_node_item *node = noti_node_get(g_noti_node, priv_id);
+
+ if (node != NULL && node->noti != NULL) {
+ notification_get_pkgname(node->noti, &noti_pkgname);
+ notification_get_id(node->noti, NULL, &noti_priv_id);
+ if (!strcmp(noti_pkgname, pkgname)
+ && priv_id == noti_priv_id) {
+ notification_set_progress(node->noti, progress);
+ return node->noti;
+ }
+ }
+#else
+ notification_h noti = NULL;
+ notification_list_h head = NULL;
+ char *noti_pkgname = NULL;
+ int noti_priv_id = 0;
+
+ if (g_notification_ongoing_list) {
+ head = notification_list_get_head(g_notification_ongoing_list);
+
+ while (head != NULL) {
+ noti = notification_list_get_data(head);
+ notification_get_pkgname(noti, &noti_pkgname);
+ notification_get_id(noti, NULL, &noti_priv_id);
+ if (!strcmp(noti_pkgname, pkgname)
+ && priv_id == noti_priv_id) {
+ notification_set_progress(noti, progress);
+ return noti;
+ }
+ head = notification_list_get_next(head);
+ }
+ }
+
+ if (g_notification_list) {
+ head = notification_list_get_head(g_notification_list);
+
+ while (head != NULL) {
+ noti = notification_list_get_data(head);
+ notification_get_pkgname(noti, &noti_pkgname);
+ notification_get_id(noti, NULL, &noti_priv_id);
+ if (!strcmp(noti_pkgname, pkgname)
+ && priv_id == noti_priv_id) {
+ notification_set_progress(noti, progress);
+ return noti;
+ }
+ head = notification_list_get_next(head);
+ }
+ }
+#endif
+
+ return NULL;
+}
+
+static notification_h _quickpanel_noti_update_item_size(const char *pkgname,
+ int priv_id,
+ double size)
+{
+#ifdef QP_DETAILED_NOTI_CHANGE_CB_ENABLE
+ char *noti_pkgname = NULL;
+ int noti_priv_id = 0;
+
+ noti_node_item *node = noti_node_get(g_noti_node, priv_id);
+
+ if (node != NULL && node->noti != NULL) {
+ notification_get_pkgname(node->noti, &noti_pkgname);
+ notification_get_id(node->noti, NULL, &noti_priv_id);
+ if (!strcmp(noti_pkgname, pkgname)
+ && priv_id == noti_priv_id) {
+ notification_set_size(node->noti, size);
+ return node->noti;
+ }
+ }
+#else
+ notification_h noti = NULL;
+ notification_list_h head = NULL;
+ char *noti_pkgname = NULL;
+ int noti_priv_id = 0;
+
+ if (g_notification_ongoing_list) {
+ head = notification_list_get_head(g_notification_ongoing_list);
+
+ while (head != NULL) {
+ noti = notification_list_get_data(head);
+ notification_get_pkgname(noti, &noti_pkgname);
+ notification_get_id(noti, NULL, &noti_priv_id);
+ if (!strcmp(noti_pkgname, pkgname)
+ && priv_id == noti_priv_id) {
+ notification_set_size(noti, size);
+ return noti;
+ }
+ head = notification_list_get_next(head);
+ }
+ }
+
+ if (g_notification_list) {
+ head = notification_list_get_head(g_notification_list);
+
+ while (head != NULL) {
+ noti = notification_list_get_data(head);
+ notification_get_pkgname(noti, &noti_pkgname);
+ notification_get_id(noti, NULL, &noti_priv_id);
+ if (!strcmp(noti_pkgname, pkgname)
+ && priv_id == noti_priv_id) {
+ notification_set_size(noti, size);
+ return noti;
+ }
+ head = notification_list_get_next(head);
+ }
+ }
+#endif
+
+ return NULL;
+}
+
+static notification_h _quickpanel_noti_update_item_content(const char *pkgname,
+ int priv_id,
+ char *content)
+{
+#ifdef QP_DETAILED_NOTI_CHANGE_CB_ENABLE
+ char *noti_pkgname = NULL;
+ int noti_priv_id = 0;
+
+ noti_node_item *node = noti_node_get(g_noti_node, priv_id);
+
+ if (node != NULL && node->noti != NULL) {
+ notification_get_pkgname(node->noti, &noti_pkgname);
+ notification_get_id(node->noti, NULL, &noti_priv_id);
+ if (!strcmp(noti_pkgname, pkgname)
+ && priv_id == noti_priv_id) {
+ notification_set_text(node->noti,
+ NOTIFICATION_TEXT_TYPE_CONTENT,
+ content, NULL,
+ NOTIFICATION_VARIABLE_TYPE_NONE);
+ return node->noti;
+ }
+ }
+#else
+ notification_h noti = NULL;
+ notification_list_h head = NULL;
+ char *noti_pkgname = NULL;
+ int noti_priv_id = 0;
+
+ if (g_notification_ongoing_list) {
+ head = notification_list_get_head(g_notification_ongoing_list);
+
+ while (head != NULL) {
+ noti = notification_list_get_data(head);
+ notification_get_pkgname(noti, &noti_pkgname);
+ notification_get_id(noti, NULL, &noti_priv_id);
+ if (!strcmp(noti_pkgname, pkgname)
+ && priv_id == noti_priv_id) {
+ notification_set_text(noti,
+ NOTIFICATION_TEXT_TYPE_CONTENT,
+ content, NULL,
+ NOTIFICATION_VARIABLE_TYPE_NONE);
+ return noti;
+ }
+ head = notification_list_get_next(head);
+ }
+ }
+
+ if (g_notification_list) {
+ head = notification_list_get_head(g_notification_list);
+
+ while (head != NULL) {
+ noti = notification_list_get_data(head);
+ notification_get_pkgname(noti, &noti_pkgname);
+ notification_get_id(noti, NULL, &noti_priv_id);
+ if (!strcmp(noti_pkgname, pkgname)
+ && priv_id == noti_priv_id) {
+ notification_set_text(noti,
+ NOTIFICATION_TEXT_TYPE_CONTENT,
+ content, NULL,
+ NOTIFICATION_VARIABLE_TYPE_NONE);
+ return noti;
+ }
+ head = notification_list_get_next(head);
+ }
+ }
+#endif
+
+ return NULL;
+}
+
+static void _quickpanel_noti_update_progressbar(void *data,
+ notification_h update_noti)
+{
+ struct appdata *ad = NULL;
+ Elm_Object_Item *found = NULL;
+
+ retif(!data, , "data is NULL");
+ ad = data;
+
+ retif(!ad->list, , "ad->list is NULL");
+
+#ifdef QP_DETAILED_NOTI_CHANGE_CB_ENABLE
+ int priv_id = 0;
+
+ if (notification_get_id(update_noti, NULL, &priv_id) == NOTIFICATION_ERROR_NONE) {
+ noti_node_item *node = noti_node_get(g_noti_node, priv_id);
+
+ if (node != NULL) {
+ found = node->view;
+ }
+ }
+#else
+ if (ad->show_setting)
+ found = quickpanel_list_util_find_item_by_type(ad->list,
+ update_noti, ongoing_first,
+ QP_ITEM_TYPE_ONGOING_NOTI);
+ else
+ found = quickpanel_list_util_find_item_by_type(ad->list,
+ update_noti, noti_first,
+ QP_ITEM_TYPE_NOTI);
+#endif
+
+ retif(!found, , "fail to find %p related gl item", update_noti);
+
+ elm_genlist_item_fields_update(found, "*", ELM_GENLIST_ITEM_FIELD_ALL);
+}
+
+static void _quickpanel_noti_item_progress_update_cb(void *data,
+ DBusMessage *msg)
+{
+ DBusError err;
+ char *pkgname = 0;
+ int priv_id = 0;
+ double progress = 0;
+ notification_h noti = NULL;
+
+ retif(data == NULL || msg == NULL, , "Invalid parameter!");
+
+ dbus_error_init(&err);
+ dbus_message_get_args(msg, &err,
+ DBUS_TYPE_STRING, &pkgname,
+ DBUS_TYPE_INT32, &priv_id,
+ DBUS_TYPE_DOUBLE, &progress,
+ DBUS_TYPE_INVALID);
+
+ if (dbus_error_is_set(&err)) {
+ ERR("dbus err: %s", err.message);
+ dbus_error_free(&err);
+ return;
+ }
+
+ if (pkgname == NULL) {
+ ERR("pkgname is null");
+ return;
+ }
+
+ /* check item on the list */
+ noti = _quickpanel_noti_update_item_progress(pkgname,
+ priv_id, progress);
+ retif(noti == NULL, , "Can not found noti data.");
+
+ DBG("pkgname[%s], priv_id[%d], progress[%lf]",
+ pkgname, priv_id, progress);
+ if (!suspended)
+ _quickpanel_noti_update_progressbar(data, noti);
+}
+
+static void _quickpanel_noti_item_size_update_cb(void *data, DBusMessage * msg)
+{
+ DBusError err;
+ char *pkgname = 0;
+ int priv_id = 0;
+ double size = 0;
+ notification_h noti = NULL;
+
+ retif(data == NULL || msg == NULL, , "Invalid parameter!");
+
+ dbus_error_init(&err);
+ dbus_message_get_args(msg, &err,
+ DBUS_TYPE_STRING, &pkgname,
+ DBUS_TYPE_INT32, &priv_id,
+ DBUS_TYPE_DOUBLE, &size, DBUS_TYPE_INVALID);
+ if (dbus_error_is_set(&err)) {
+ ERR("dbus err: %s", err.message);
+ dbus_error_free(&err);
+ return;
+ }
+
+ if (pkgname == NULL) {
+ ERR("pkgname is null");
+ return;
+ }
+
+ /* check item on the list */
+ noti = _quickpanel_noti_update_item_size(pkgname, priv_id, size);
+ retif(noti == NULL, , "Can not found noti data.");
+
+ DBG("pkgname[%s], priv_id[%d], progress[%lf]",
+ pkgname, priv_id, size);
+
+ if (!suspended)
+ _quickpanel_noti_update_progressbar(data, noti);
+}
+
+static void _quickpanel_noti_item_content_update_cb(void *data,
+ DBusMessage *msg)
+{
+ DBusError err;
+ char *pkgname = NULL;
+ int priv_id = 0;
+ char *content = NULL;
+ notification_h noti = NULL;
+
+ retif(data == NULL || msg == NULL, , "Invalid parameter!");
+
+ dbus_error_init(&err);
+ dbus_message_get_args(msg, &err,
+ DBUS_TYPE_STRING, &pkgname,
+ DBUS_TYPE_INT32, &priv_id,
+ DBUS_TYPE_STRING, &content, DBUS_TYPE_INVALID);
+
+ if (pkgname == NULL) {
+ ERR("pkgname is null");
+ return;
+ }
+ if (content == NULL) {
+ ERR("content is null");
+ return;
+ }
+
+ if (dbus_error_is_set(&err)) {
+ ERR("dbus err: %s", err.message);
+ dbus_error_free(&err);
+ return;
+ }
+
+ DBG("pkgname[%s], priv_id[%d], content[%s]",
+ pkgname, priv_id, content);
+
+ /* check item on the list */
+ noti = _quickpanel_noti_update_item_content(pkgname, priv_id, content);
+ retif(noti == NULL, , "Can not found noti data.");
+
+ if (!suspended)
+ _quickpanel_noti_update_progressbar(data, noti);
+}
+
+char *quickpanel_noti_get_time(time_t t, char *buf, int buf_len)
+{
+ UErrorCode status = U_ZERO_ERROR;
+ UDateTimePatternGenerator *generator;
+ UDateFormat *formatter;
+ UChar skeleton[40] = { 0 };
+ UChar pattern[40] = { 0 };
+ UChar formatted[40] = { 0 };
+ int32_t patternCapacity, formattedCapacity;
+ int32_t skeletonLength, patternLength, formattedLength;
+ UDate date;
+ const char *locale;
+ const char customSkeleton[] = UDAT_YEAR_NUM_MONTH_DAY;
+ char bf1[32] = { 0, };
+ bool is_24hour_enabled = FALSE;
+
+ struct tm loc_time;
+ time_t today, yesterday;
+ int ret = 0;
+
+ today = time(NULL);
+ localtime_r(&today, &loc_time);
+
+ loc_time.tm_sec = 0;
+ loc_time.tm_min = 0;
+ loc_time.tm_hour = 0;
+ today = mktime(&loc_time);
+
+ yesterday = today - QP_NOTI_DAY_DEC;
+
+ localtime_r(&t, &loc_time);
+
+ if (t >= yesterday && t < today) {
+ ret = snprintf(buf, buf_len, _S("IDS_COM_BODY_YESTERDAY"));
+ } else if (t < yesterday) {
+ /* set UDate from time_t */
+ date = (UDate) t * 1000;
+
+ /* get default locale */
+ /* for thread saftey */
+ uloc_setDefault(__secure_getenv("LC_TIME"), &status);
+ locale = uloc_getDefault();
+
+ /* open datetime pattern generator */
+ generator = udatpg_open(locale, &status);
+ if (generator == NULL)
+ return NULL;
+
+ /* calculate pattern string capacity */
+ patternCapacity =
+ (int32_t) (sizeof(pattern) / sizeof((pattern)[0]));
+
+ /* ascii to unicode for input skeleton */
+ u_uastrcpy(skeleton, customSkeleton);
+
+ /* get skeleton length */
+ skeletonLength = strlen(customSkeleton);
+
+ /* get best pattern using skeleton */
+ patternLength =
+ udatpg_getBestPattern(generator, skeleton, skeletonLength,
+ pattern, patternCapacity, &status);
+
+ /* open datetime formatter using best pattern */
+ formatter =
+ udat_open(UDAT_IGNORE, UDAT_DEFAULT, locale, NULL, -1,
+ pattern, patternLength, &status);
+ if (formatter == NULL) {
+ udatpg_close(generator);
+ return NULL;
+ }
+
+ /* calculate formatted string capacity */
+ formattedCapacity =
+ (int32_t) (sizeof(formatted) / sizeof((formatted)[0]));
+
+ /* formatting date using formatter by best pattern */
+ formattedLength =
+ udat_format(formatter, date, formatted, formattedCapacity,
+ NULL, &status);
+
+ /* unicode to ascii to display */
+ u_austrcpy(bf1, formatted);
+
+ /* close datetime pattern generator */
+ udatpg_close(generator);
+
+ /* close datetime formatter */
+ udat_close(formatter);
+
+ ret = snprintf(buf, buf_len, "%s", bf1);
+ } else {
+ ret = runtime_info_get_value_bool(
+ RUNTIME_INFO_KEY_24HOUR_CLOCK_FORMAT_ENABLED, &is_24hour_enabled);
+ if (ret == RUNTIME_INFO_ERROR_NONE && is_24hour_enabled == TRUE) {
+ ret = strftime(buf, buf_len, "%H:%M", &loc_time);
+ } else {
+ strftime(bf1, sizeof(bf1), "%l:%M", &loc_time);
+
+ if (loc_time.tm_hour >= 0 && loc_time.tm_hour < 12)
+ ret = snprintf(buf, buf_len, "%s%s", bf1, "AM");
+ else
+ ret = snprintf(buf, buf_len, "%s%s", bf1, "PM");
+ }
+
+ }
+
+ return ret <= 0 ? NULL : buf;
+}
+
+static void _quickpanel_noti_ani_image_control(Eina_Bool on)
+{
+ const Eina_List *l = NULL;
+ const Eina_List *ln = NULL;
+ Evas_Object *entry_obj = NULL;
+
+ retif(g_animated_image_list == NULL, ,"");
+
+ EINA_LIST_FOREACH_SAFE(g_animated_image_list, l, ln, entry_obj) {
+ if (entry_obj == NULL) continue;
+
+ if (on == EINA_TRUE) {
+ if (elm_image_animated_play_get(entry_obj) == EINA_FALSE) {
+ elm_image_animated_play_set(entry_obj, EINA_TRUE);
+ }
+ } else {
+ if (elm_image_animated_play_get(entry_obj) == EINA_TRUE) {
+ elm_image_animated_play_set(entry_obj, EINA_FALSE);
+ }
+ }
+ }
+}
+
+static void _quickpanel_noti_ani_image_deleted_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ retif(obj == NULL, , "obj is NULL");
+ retif(g_animated_image_list == NULL, , "list is empty");
+
+ g_animated_image_list = eina_list_remove(g_animated_image_list, obj);
+}
+
+static Evas_Object *_quickpanel_noti_box_gl_get_content(void *data,
+ Evas_Object *obj, const char *part) {
+ retif(part == NULL, NULL, "invalid parameter");
+
+ if (strcmp(part, "elm.icon") == 0) {
+ DBG("returned:%p", g_noti_gridbox);
+ return g_noti_gridbox;
+ }
+
+ return NULL;
+}
+
+static Evas_Object *_quickpanel_noti_gl_get_content(void *data,
+ Evas_Object *obj, const char *part)
+{
+ qp_item_data *qid = NULL;
+ notification_h noti = NULL;
+ Evas_Object *ic = NULL;
+ char *icon_path = NULL;
+ char *thumbnail_path = NULL;
+ char *ret_path = NULL;
+ double size = 0.0;
+ double percentage = 0.0;
+ notification_type_e type = NOTIFICATION_TYPE_NONE;
+ char group_name[64] = {0,};
+ notification_ly_type_e layout = NOTIFICATION_LY_NONE ;
+
+ retif(!data, NULL, "data is NULL");
+ qid = data;
+
+ noti = quickpanel_list_util_item_get_data(qid);
+ retif(noti == NULL, NULL, "noti is NULL");
+
+ if (!strncmp
+ (part, "elm.swallow.progress", strlen("elm.swallow.progress"))) {
+ notification_get_type(noti, &type);
+ if (type == NOTIFICATION_TYPE_ONGOING) {
+ notification_get_size(noti, &size);
+ notification_get_progress(noti, &percentage);
+ notification_get_layout(noti, &layout);
+
+ if (layout != NOTIFICATION_LY_ONGOING_EVENT) {
+ if (percentage > 0 && percentage <= 1) {
+ ic = elm_progressbar_add(obj);
+ if (ic == NULL)
+ return NULL;
+
+ elm_object_style_set(ic, "quickpanel/list_progress");
+ elm_progressbar_value_set(ic, percentage);
+ elm_progressbar_horizontal_set(ic, EINA_TRUE);
+ elm_progressbar_pulse(ic, EINA_FALSE);
+ } else if (size > 0) {
+ ic = elm_progressbar_add(obj);
+ if (ic == NULL)
+ return NULL;
+
+ elm_object_style_set(ic, "quickpanel/pending_list");
+ elm_progressbar_horizontal_set(ic, EINA_TRUE);
+ elm_progressbar_pulse(ic, EINA_TRUE);
+ }
+ }
+ }
+ return ic;
+ }
+
+ ic = elm_image_add(obj);
+ retif(ic == NULL, NULL, "Failed to create elm icon.");
+
+ notification_get_image(noti, NOTIFICATION_IMAGE_TYPE_THUMBNAIL,
+ &thumbnail_path);
+ notification_get_image(noti, NOTIFICATION_IMAGE_TYPE_ICON, &icon_path);
+
+ snprintf(group_name, sizeof(group_name) - 1, "notification_item_%d", eina_list_count(g_animated_image_list));
+
+ if (!strncmp
+ (part, "elm.swallow.thumbnail", strlen("elm.swallow.thumbnail"))) {
+ if (thumbnail_path == NULL)
+ ret_path = icon_path;
+ else
+ ret_path = thumbnail_path;
+
+ elm_image_resizable_set(ic, EINA_FALSE, EINA_TRUE);
+
+ if (ret_path == NULL
+ || (elm_image_file_set(ic, ret_path, group_name) == EINA_FALSE))
+ elm_image_file_set(ic, QP_DEFAULT_ICON, group_name);
+ } else if (!strncmp(part, "elm.swallow.icon",
+ strlen("elm.swallow.icon"))) {
+ if (thumbnail_path == NULL)
+ ret_path = NULL;
+ else
+ ret_path = icon_path;
+
+ if (ret_path != NULL)
+ elm_image_file_set(ic, ret_path, group_name);
+ }
+
+ if (ic != NULL && elm_image_animated_available_get(ic) == EINA_TRUE) {
+ elm_image_animated_set(ic, EINA_TRUE);
+ g_animated_image_list = eina_list_append(g_animated_image_list, ic);
+ evas_object_event_callback_add(ic, EVAS_CALLBACK_DEL, _quickpanel_noti_ani_image_deleted_cb, ic);
+
+ if (suspended == 0)
+ elm_image_animated_play_set(ic, EINA_TRUE);
+ }
+ return ic;
+}
+
+static char *_quickpanel_ongoing_noti_gl_get_text(void *data, Evas_Object * obj,
+ const char *part)
+{
+ qp_item_data *qid = NULL;
+ notification_h noti = NULL;
+ notification_error_e noti_err = NOTIFICATION_ERROR_NONE;
+ char *text = NULL;
+ char *domain = NULL;
+ char *dir = NULL;
+ char *pkgname = NULL;
+ char *caller_pkgname = NULL;
+ int group_id = 0, priv_id = 0;
+ char buf[128] = { 0, };
+ notification_type_e type = NOTIFICATION_TYPE_NONE;
+ double size = 0.0;
+ double percentage = 0.0;
+ int isProgressBarEnabled = 1;
+ notification_ly_type_e layout = NOTIFICATION_LY_NONE ;
+
+ retif(!data, NULL, "data is NULL");
+ qid = data;
+
+ noti = quickpanel_list_util_item_get_data(qid);
+ retif(noti == NULL, NULL, "noti is NULL");
+
+ /* Set text domain */
+ notification_get_text_domain(noti, &domain, &dir);
+ if (domain != NULL && dir != NULL)
+ bindtextdomain(domain, dir);
+
+ /* Get pkgname & id */
+ notification_get_pkgname(noti, &pkgname);
+ notification_get_application(noti, &caller_pkgname);
+ notification_get_id(noti, &group_id, &priv_id);
+ notification_get_type(noti, &type);
+ notification_get_size(noti, &size);
+ notification_get_progress(noti, &percentage);
+ notification_get_layout(noti, &layout);
+
+ DBG("percentage:%f size:%f", percentage, size);
+
+ if (percentage <= 0.0 && size <= 0.0) {
+ isProgressBarEnabled = 0;
+ }
+
+ if (!strcmp(part, "elm.text.title")) {
+ noti_err = notification_get_text(noti,
+ NOTIFICATION_TEXT_TYPE_TITLE,
+ &text);
+ if (noti_err != NOTIFICATION_ERROR_NONE)
+ text = NULL;
+ } else if (!strcmp(part, "elm.text.content")) {
+ noti_err = notification_get_text(noti,
+ NOTIFICATION_TEXT_TYPE_CONTENT,
+ &text);
+ if (noti_err != NOTIFICATION_ERROR_NONE)
+ text = NULL;
+ } else if (!strcmp(part, "elm.text.time")) {
+ if (isProgressBarEnabled == 0)
+ return NULL;
+
+ if (layout == NOTIFICATION_LY_ONGOING_EVENT) {
+ return NULL;
+ }
+
+ text = _quickpanel_noti_get_progress(noti, buf,
+ sizeof(buf));
+ }
+
+ if (text != NULL)
+ return strdup(text);
+
+ return NULL;
+}
+
+static Eina_Bool _quickpanel_noti_gl_get_state(void *data, Evas_Object * obj,
+ const char *part)
+{
+ qp_item_data *qid = NULL;
+ notification_h noti = NULL;
+ char *pkgname = NULL;
+ int group_id = 0, priv_id = 0;
+ char *content = NULL;
+ time_t time;
+
+ retif(!data, EINA_FALSE, "data is NULL");
+ qid = data;
+
+ noti = quickpanel_list_util_item_get_data(qid);
+ retif(noti == NULL, EINA_FALSE, "noti is NULL");
+
+ notification_get_pkgname(noti, &pkgname);
+ notification_get_id(noti, &group_id, &priv_id);
+
+ if (!strcmp(part, "elm.text.content")) {
+ notification_get_text(noti,
+ NOTIFICATION_TEXT_TYPE_CONTENT, &content);
+ if (content != NULL)
+ return EINA_TRUE;
+ } else if (!strcmp(part, "elm.text.time")) {
+ notification_get_time(noti, &time);
+
+ if ((int) time > 0)
+ return EINA_TRUE;
+ }
+
+ return EINA_FALSE;
+}
+
+static void _quickpanel_do_noti_delete(notification_h noti) {
+ char *pkgname = NULL;
+ char *caller_pkgname = NULL;
+ int flags = 0, priv_id = 0, flag_delete = 0;
+ notification_type_e type = NOTIFICATION_TYPE_NONE;
+
+ retif(noti == NULL, , "Invalid parameter!");
+
+ notification_get_pkgname(noti, &caller_pkgname);
+ notification_get_application(noti, &pkgname);
+ if (pkgname == NULL)
+ pkgname = caller_pkgname;
+
+ notification_get_id(noti, NULL, &priv_id);
+ notification_get_property(noti, &flags);
+ notification_get_type(noti, &type);
+
+ if (flags & NOTIFICATION_PROP_PERMANENT_DISPLAY)
+ flag_delete = 0;
+ else
+ flag_delete = 1;
+
+ if (flag_delete == 1 && type == NOTIFICATION_TYPE_NOTI) {
+ notification_delete_by_priv_id(caller_pkgname, NOTIFICATION_TYPE_NOTI,
+ priv_id);
+ }
+}
+
+static void _quickpanel_do_noti_press(notification_h noti) {
+ char *pkgname = NULL;
+ char *caller_pkgname = NULL;
+ bundle *args = NULL;
+ bundle *group_args = NULL;
+ bundle *single_service_handle = NULL;
+ bundle *multi_service_handle = NULL;
+ int flags = 0, group_id = 0, priv_id = 0, count = 0, flag_launch = 0,
+ flag_delete = 0;
+ notification_type_e type = NOTIFICATION_TYPE_NONE;
+
+ retif(noti == NULL, , "Invalid parameter!");
+
+ notification_get_pkgname(noti, &caller_pkgname);
+ notification_get_application(noti, &pkgname);
+ if (pkgname == NULL)
+ pkgname = caller_pkgname;
+
+ notification_get_id(noti, &group_id, &priv_id);
+ notification_get_property(noti, &flags);
+ notification_get_type(noti, &type);
+
+ if (flags & NOTIFICATION_PROP_DISABLE_APP_LAUNCH)
+ flag_launch = 0;
+ else
+ flag_launch = 1;
+
+ if (flags & NOTIFICATION_PROP_DISABLE_AUTO_DELETE)
+ flag_delete = 0;
+ else
+ flag_delete = 1;
+
+ notification_get_execute_option(noti,
+ NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH,
+ NULL, &single_service_handle);
+ notification_get_execute_option(noti,
+ NOTIFICATION_EXECUTE_TYPE_MULTI_LAUNCH,
+ NULL, &multi_service_handle);
+
+ if (flag_launch == 1) {
+ /* Hide quickpanel */
+ Ecore_X_Window zone;
+ zone = ecore_x_e_illume_zone_get(elm_win_xwindow_get(g_window));
+ ecore_x_e_illume_quickpanel_state_send(zone,
+ ECORE_X_ILLUME_QUICKPANEL_STATE_OFF);
+
+ if (group_id != NOTIFICATION_GROUP_ID_NONE)
+ notification_get_count(type,
+ caller_pkgname, group_id,
+ priv_id, &count);
+ else
+ count = 1;
+
+ if (count > 1 && multi_service_handle != NULL)
+ appsvc_run_service(multi_service_handle, 0, NULL, NULL);
+ else if (single_service_handle != NULL)
+ appsvc_run_service(single_service_handle, 0, NULL,
+ NULL);
+ else {
+ notification_get_args(noti, &args, &group_args);
+
+ if (count > 1 && group_args != NULL) {
+ quickpanel_launch_app(pkgname, group_args);
+ } else {
+ quickpanel_launch_app(pkgname, args);
+ }
+ }
+ }
+
+#ifdef QP_DETAILED_NOTI_CHANGE_CB_ENABLE
+ if (flag_delete == 1 && type == NOTIFICATION_TYPE_NOTI) {
+ notification_delete_by_priv_id(caller_pkgname,
+ NOTIFICATION_TYPE_NOTI,
+ priv_id);
+ }
+#else
+ if (flag_delete == 1 && type == NOTIFICATION_TYPE_NOTI)
+ notification_delete_group_by_priv_id(caller_pkgname,
+ NOTIFICATION_TYPE_NOTI, priv_id);
+#endif
+}
+
+static void quickpanel_notibox_delete_cb(void *data, Evas_Object * obj) {
+ DBG("");
+ noti_node_item *item = data;
+ retif(item == NULL, , "Invalid parameter!");
+
+ notification_h noti = item->noti;
+ retif(noti == NULL, , "Invalid parameter!");
+
+ _quickpanel_do_noti_delete(noti);
+
+}
+
+static void quickpanel_notibox_select_cb(void *data, Evas_Object * obj) {
+ DBG("");
+ noti_node_item *item = data;
+ retif(item == NULL, , "Invalid parameter!");
+
+ notification_h noti = item->noti;
+ retif(noti == NULL, , "Invalid parameter!");
+
+ _quickpanel_do_noti_press(noti);
+}
+
+static void quickpanel_noti_select_cb(void *data, Evas_Object * obj,
+ void *event_info) {
+#ifdef QP_DETAILED_NOTI_CHANGE_CB_ENABLE
+ notification_h noti = (notification_h) quickpanel_list_util_item_get_data(data);
+#else
+ notification_h noti = (notification_h) data;
+#endif
+
+ retif(noti == NULL, , "Invalid parameter!");
+
+ elm_genlist_item_selected_set((Elm_Object_Item *) event_info, EINA_FALSE);
+
+ _quickpanel_do_noti_press(noti);
+}
+
+static Evas_Object *_quickpanel_noti_gl_get_group_content(void *data,
+ Evas_Object *obj,
+ const char *part)
+{
+ Evas_Object *eo = NULL;
+
+ eo = elm_button_add(obj);
+ retif(eo == NULL, NULL, "Failed to create clear button!");
+
+ elm_object_style_set(eo, "quickpanel_standard");
+
+ elm_object_text_set(eo, _S("IDS_COM_BODY_CLEAR_ALL"));
+ evas_object_smart_callback_add(eo, "clicked",
+ _quickpanel_noti_clear_clicked_cb, NULL);
+
+ return eo;
+}
+
+static char *_quickpanel_noti_gl_get_group_text(void *data, Evas_Object * obj,
+ const char *part)
+{
+ char buf[128] = { 0, };
+ int noti_count = 0;
+
+ if (!strncmp(part, "elm.text", 8)) {
+ char format[256] = { 0, };
+ memset(buf, 0x00, sizeof(buf));
+
+ if (g_noti_node != NULL) {
+ noti_count =
+ noti_node_get_item_count(g_noti_node, NOTIFICATION_TYPE_NOTI);
+ } else {
+ noti_count = 0;
+ }
+
+ snprintf(format, sizeof(format), "%s %%d", _("IDS_QP_BODY_NOTIFICATIONS_ABB2"));
+ snprintf(buf, sizeof(buf), format, noti_count);
+
+ return strdup(buf);
+ }
+
+ return NULL;
+}
+
+static void _quickpanel_list_noti_gl_del(void *data, Evas_Object *obj)
+{
+ int noti_priv_id = 0;
+ qp_item_type_e item_type = QP_ITEM_TYPE_NONE;
+ notification_h noti = NULL;
+
+ if (data) {
+ noti = quickpanel_list_util_item_get_data(data);
+ item_type = quickpanel_list_util_item_get_item_type(data);
+
+ DBG("item type:%d", item_type);
+ if (noti != NULL) {
+ if (item_type == QP_ITEM_TYPE_ONGOING_NOTI) {
+ notification_get_id(noti, NULL, &noti_priv_id);
+ noti_node_remove(g_noti_node, noti_priv_id);
+ DBG("noti:%d removed", noti_priv_id);
+ }
+ }
+ free(data);
+ }
+
+ return;
+}
+
+static void _quickpanel_list_noti_group_gl_del(void *data, Evas_Object *obj) {
+ if (data != NULL) {
+ free(data);
+ }
+ return;
+}
+
+static void _quickpanel_notibox_gl_del(void *data, Evas_Object *obj) {
+ if (data != NULL) {
+ free(data);
+ }
+ return;
+}
+
+static void _quickpanel_noti_gl_style_init(void)
+{
+ Elm_Genlist_Item_Class *noti = NULL;
+ Elm_Genlist_Item_Class *noti_ongoing = NULL;
+ Elm_Genlist_Item_Class *group = NULL;
+
+ /* item style for noti items*/
+ noti = elm_genlist_item_class_new();
+ if (noti) {
+ noti->item_style = "qp_notibox/default";
+ noti->func.text_get = NULL;
+ noti->func.content_get = _quickpanel_noti_box_gl_get_content;
+ noti->func.state_get = NULL;
+ noti->func.del = _quickpanel_notibox_gl_del;
+ itc_noti = noti;
+ }
+
+ noti_ongoing = elm_genlist_item_class_new();
+ if (noti_ongoing) {
+ noti_ongoing->item_style = "notification_ongoing_item";
+ noti_ongoing->func.text_get = _quickpanel_ongoing_noti_gl_get_text;
+ noti_ongoing->func.content_get = _quickpanel_noti_gl_get_content;
+ noti_ongoing->func.state_get = _quickpanel_noti_gl_get_state;
+ noti_ongoing->func.del = _quickpanel_list_noti_gl_del;
+ itc_ongoing = noti_ongoing;
+ }
+
+ /* item style for noti group title */
+ group = elm_genlist_item_class_new();
+ if (group) {
+ group->item_style = "qp_group_title";
+ group->func.text_get = _quickpanel_noti_gl_get_group_text;
+ group->func.content_get = _quickpanel_noti_gl_get_group_content;
+ group->func.del = _quickpanel_list_noti_group_gl_del;
+ g_itc = group;
+ }
+}
+
+static void _quickpanel_noti_gl_style_fini(void)
+{
+ if (itc_noti) {
+ elm_genlist_item_class_free(itc_noti);
+ itc_noti = NULL;
+ }
+
+ if (itc_ongoing) {
+ elm_genlist_item_class_free(itc_ongoing);
+ itc_ongoing = NULL;
+ }
+
+ if (g_itc) {
+ elm_genlist_item_class_free(g_itc);
+ g_itc = NULL;
+ }
+
+ if (g_animated_image_list) {
+ g_animated_image_list = eina_list_free(g_animated_image_list);
+ }
+}
+
+static inline void __ongoing_comp_n_copy(notification_h old, notification_h new)
+{
+ int priv_id = 0;
+ int new_priv_id = 0;
+ char *pkgname = NULL;
+ char *new_pkgname = NULL;
+
+ if (!old)
+ return;
+
+ if (!new)
+ return;
+
+ notification_get_id(old, NULL, &priv_id);
+ notification_get_id(new, NULL, &new_priv_id);
+
+ notification_get_pkgname(old, &pkgname);
+ notification_get_pkgname(new, &new_pkgname);
+
+ if (!pkgname || !new_pkgname)
+ return;
+
+ if (!strcmp(pkgname, new_pkgname) && priv_id == new_priv_id) {
+ double percentage = 0.0;
+ double size = 0.0;
+ time_t insert_time = 0;
+ time_t new_insert_time = 0;
+
+ notification_get_progress(old, &percentage);
+ notification_get_size(old, &size);
+ notification_set_progress(new, percentage);
+ notification_set_size(new, size);
+ notification_get_insert_time(old, &insert_time);
+ notification_get_insert_time(new, &new_insert_time);
+
+ if (insert_time == new_insert_time) {
+ char *content = NULL;
+ notification_get_text(old,
+ NOTIFICATION_TEXT_TYPE_CONTENT, &content);
+ notification_set_text(new,
+ NOTIFICATION_TEXT_TYPE_CONTENT, content,
+ NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
+ }
+ }
+}
+
+#ifndef QP_DETAILED_NOTI_CHANGE_CB_ENABLE
+static void _quickpanel_noti_get_new_divided_list(void)
+{
+ notification_list_h new_noti_list = NULL;
+ notification_list_h head = NULL;
+ notification_list_h new_head = NULL;
+ notification_h noti = NULL;
+ notification_h new_noti = NULL;
+
+ /* Get ongoing list */
+ notification_get_grouping_list(NOTIFICATION_TYPE_ONGOING, -1,
+ &new_noti_list);
+ if (g_notification_ongoing_list != NULL) {
+ head = notification_list_get_head(g_notification_ongoing_list);
+ while (head != NULL) {
+ new_head = notification_list_get_head(new_noti_list);
+ while (new_head != NULL) {
+ noti = notification_list_get_data(head);
+ new_noti = notification_list_get_data(new_head);
+
+ __ongoing_comp_n_copy(noti, new_noti);
+
+ new_head = notification_list_get_next(new_head);
+ }
+ head = notification_list_get_next(head);
+ }
+
+ notification_free_list(g_notification_ongoing_list);
+ g_notification_ongoing_list = new_noti_list;
+ } else {
+ g_notification_ongoing_list = new_noti_list;
+ }
+
+ /* Get noti list */
+ notification_get_grouping_list(NOTIFICATION_TYPE_NOTI, -1,
+ &new_noti_list);
+ if (g_notification_list != NULL) {
+ notification_free_list(g_notification_list);
+ g_notification_list = new_noti_list;
+ }
+
+ g_notification_list = new_noti_list;
+}
+
+static void _quickpanel_noti_get_new_list(void)
+{
+ notification_list_h new_noti_list = NULL;
+ notification_list_h head = NULL;
+ notification_list_h new_head = NULL;
+ notification_h noti = NULL;
+ notification_h new_noti = NULL;
+ notification_type_e new_type = NOTIFICATION_TYPE_NONE;
+
+ if (g_notification_ongoing_list != NULL) {
+ notification_free_list(g_notification_ongoing_list);
+ g_notification_ongoing_list = new_noti_list;
+ }
+
+ /* Get all list */
+ notification_get_grouping_list(NOTIFICATION_TYPE_NONE, -1,
+ &new_noti_list);
+ if (g_notification_list != NULL) {
+ head = notification_list_get_head(g_notification_list);
+ while (head != NULL) {
+ new_head = notification_list_get_head(new_noti_list);
+ while (new_head != NULL) {
+ noti = notification_list_get_data(head);
+ new_noti = notification_list_get_data(new_head);
+
+ notification_get_type(new_noti, &new_type);
+
+ if (new_type == NOTIFICATION_TYPE_ONGOING)
+ __ongoing_comp_n_copy(noti, new_noti);
+
+ new_head = notification_list_get_next(new_head);
+ }
+ head = notification_list_get_next(head);
+ }
+
+ notification_free_list(g_notification_list);
+ g_notification_list = new_noti_list;
+ } else {
+ g_notification_list = new_noti_list;
+ }
+}
+#endif
+
+static void _quickpanel_noti_clear_ongoinglist(Evas_Object *list)
+{
+ if (!list)
+ return;
+
+ if (!ongoing_first)
+ return;
+
+ quickpanel_list_util_item_del_by_type(list, ongoing_first,
+ QP_ITEM_TYPE_ONGOING_NOTI);
+}
+
+static void _quickpanel_noti_clear_notilist(Evas_Object *list)
+{
+ if (!list)
+ return;
+
+ if (!g_noti_gridbox)
+ return;
+
+ if (g_noti_gridbox != NULL) {
+ gridbox_remove(g_noti_gridbox);
+ g_noti_gridbox = NULL;
+ }
+ if (noti_first != NULL) {
+ elm_object_item_del(noti_first);
+ noti_first= NULL;
+ }
+ if (noti_group != NULL) {
+ elm_object_item_del(noti_group);
+ noti_group= NULL;
+ }
+}
+
+static void _quickpanel_noti_clear_list_all(Evas_Object *list)
+{
+ _quickpanel_noti_clear_ongoinglist(list);
+ ongoing_first = NULL;
+
+ _quickpanel_noti_clear_notilist(list);
+}
+
+static void _quickpanel_noti_ongoing_add(Evas_Object *list, void *data)
+{
+ qp_item_data *qid = NULL;
+ Elm_Object_Item *it = NULL;
+
+ if (!list)
+ return;
+
+ qid = quickpanel_list_util_item_new(QP_ITEM_TYPE_ONGOING_NOTI, data);
+ if (!qid)
+ return;
+
+#ifdef QP_DETAILED_NOTI_CHANGE_CB_ENABLE
+ it = quickpanel_list_util_sort_insert(list, itc_ongoing, qid, NULL,
+ ELM_GENLIST_ITEM_NONE, quickpanel_noti_select_cb, qid);
+#else
+ it = quickpanel_list_util_sort_insert(list, itc_ongoing, qid, NULL,
+ ELM_GENLIST_ITEM_NONE, quickpanel_noti_select_cb, data);
+#endif
+
+ if (it) {
+ ongoing_first = it;
+#ifdef QP_DETAILED_NOTI_CHANGE_CB_ENABLE
+ noti_node_add(g_noti_node, (void *)data, (void *)it);
+#endif
+ }
+ else
+ ERR("fail to insert item to list : %p", data);
+
+ DBG("noti ongoing[%p] data[%p] added, it[%p]", qid, data, it);
+}
+
+static void _quickpanel_noti_group_add(Evas_Object *list, void *data)
+{
+ qp_item_data *qid = NULL;
+ Elm_Object_Item *it = NULL;
+
+ if (!list)
+ return;
+
+ qid = quickpanel_list_util_item_new(QP_ITEM_TYPE_NOTI_GROUP, data);
+ if (!qid)
+ return;
+
+ it = quickpanel_list_util_sort_insert(list, g_itc, qid, NULL,
+ ELM_GENLIST_ITEM_GROUP, NULL, NULL);
+
+ if (it)
+ noti_group = it;
+ else
+ ERR("fail to insert item to list : %p", data);
+
+ DBG("noti group[%p] data[%p] added, it[%p]", qid, data, it);
+}
+
+void _quickpanel_noti_box_deleted_cb(void *data, Evas_Object *obj) {
+ DBG("deleting:%p", obj);
+
+ int priv_id = -1;
+
+ retif(data == NULL, , "Invalid parameter!");
+ retif(obj == NULL, , "Invalid parameter!");
+
+ noti_node_item *item = data;
+ notification_h noti = item->noti;
+
+ if (noti != NULL) {
+ notification_get_id(noti, NULL, &priv_id);
+ noti_node_remove(g_noti_node, priv_id);
+ }
+}
+
+static void _quickpanel_noti_noti_add(Evas_Object *list, void *data, int is_prepend)
+{
+ retif(list == NULL, , "Invalid parameter!");
+ qp_item_data *qid = NULL;
+ Elm_Object_Item *it = NULL;
+ notification_h noti = data;
+ notification_ly_type_e layout = NOTIFICATION_LY_NOTI_EVENT_SINGLE;
+
+ qid = quickpanel_list_util_item_new(QP_ITEM_TYPE_NOTI, NULL);
+ retif(qid == NULL, , "Invalid parameter!");
+
+ if (!noti_group)
+ _quickpanel_noti_group_add(list, NULL);
+
+#ifdef QP_DETAILED_NOTI_CHANGE_CB_ENABLE
+ if (noti_first == NULL) {
+ if (g_noti_gridbox == NULL) {
+ g_noti_gridbox = gridbox_create(list, quickpanel_get_app_data());
+ gridbox_set_item_deleted_cb(g_noti_gridbox, _quickpanel_noti_box_deleted_cb);
+ }
+
+ it = quickpanel_list_util_sort_insert(list, itc_noti, qid, noti_group,
+ ELM_GENLIST_ITEM_NONE, NULL, qid);
+ noti_first = it;
+ }
+#else
+ it = quickpanel_list_util_sort_insert(list, itc_noti, qid, noti_group,
+ ELM_GENLIST_ITEM_NONE, quickpanel_noti_select_cb, data);
+#endif
+
+ if (noti != NULL) {
+ notification_get_layout(noti, &layout);
+ }
+ Evas_Object *noti_box = noti_box_create(list, layout);
+
+ if (noti_box != NULL) {
+#ifdef QP_DETAILED_NOTI_CHANGE_CB_ENABLE
+ noti_node_item *item = noti_node_add(g_noti_node, (void*)data, (void*)noti_box);
+ if (item != NULL) {
+ noti_box_node_set(noti_box, item);
+ noti_box_set_item_selected_cb(noti_box, quickpanel_notibox_select_cb);
+ noti_box_set_item_deleted_cb(noti_box, quickpanel_notibox_delete_cb);
+ gridbox_add_item(g_noti_gridbox, noti_box, is_prepend);
+ }
+#endif
+ } else
+ ERR("fail to insert item to list : %p", data);
+
+ DBG("noti[%p] data[%p] added, it[%p] of gridbox[%p]",
+ qid, data, noti_box, g_noti_gridbox);
+}
+
+
+void _quickpanel_noti_update_notilist(struct appdata *ad)
+{
+ Evas_Object *list = NULL;
+ notification_h noti = NULL;
+ notification_h noti_save = NULL;
+ notification_list_h get_list = NULL;
+ int applist = NOTIFICATION_DISPLAY_APP_ALL;
+
+ DBG("");
+
+ retif(ad == NULL, , "Invalid parameter!");
+
+ list = ad->list;
+ retif(list == NULL, , "Failed to get noti genlist.");
+
+#ifdef QP_DETAILED_NOTI_CHANGE_CB_ENABLE
+ _quickpanel_noti_clear_list_all(list);
+
+ notification_get_list(NOTIFICATION_TYPE_ONGOING, -1, &get_list);
+ while (get_list != NULL) {
+ noti = notification_list_get_data(get_list);
+ notification_get_display_applist(noti, &applist);
+
+ if (applist &
+ NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY) {
+ notification_clone(noti, &noti_save);
+ _quickpanel_noti_ongoing_add(list, noti_save);
+ }
+ get_list = notification_list_get_next(get_list);
+ }
+ notification_free_list(get_list);
+
+ notification_get_list(NOTIFICATION_TYPE_NOTI , -1, &get_list);
+ while (get_list != NULL) {
+ noti = notification_list_get_data(get_list);
+ notification_get_display_applist(noti, &applist);
+
+ if (applist &
+ NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY) {
+ notification_clone(noti, &noti_save);
+ _quickpanel_noti_noti_add(list, noti_save, GRIDBOX_APPEND);
+ }
+ get_list = notification_list_get_next(get_list);
+ }
+ notification_free_list(get_list);
+
+ if (g_noti_gridbox != NULL) {
+ elm_box_recalculate(g_noti_gridbox);
+ }
+#else
+ /* Clear genlist */
+ _quickpanel_noti_clear_list_all(list);
+
+ /* Update notification list */
+ if (ad->show_setting)
+ _quickpanel_noti_get_new_divided_list();
+ else
+ _quickpanel_noti_get_new_list();
+
+ /* append ongoing data to genlist */
+ if (g_notification_ongoing_list) {
+ get_list =
+ notification_list_get_tail(g_notification_ongoing_list);
+ noti = notification_list_get_data(get_list);
+
+ while (get_list != NULL) {
+ notification_get_display_applist(noti, &applist);
+
+ if (applist &
+ NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY) {
+ _quickpanel_noti_ongoing_add(list, noti);
+ }
+
+ get_list = notification_list_get_prev(get_list);
+ noti = notification_list_get_data(get_list);
+ }
+ }
+
+ /* append noti data to genlist */
+ if (g_notification_list) {
+ get_list = notification_list_get_tail(g_notification_list);
+ noti = notification_list_get_data(get_list);
+
+ while (get_list != NULL) {
+ notification_get_display_applist(noti, &applist);
+
+ if (applist & NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY)
+ _quickpanel_noti_noti_add(list, noti, GRIDBOX_PREPEND);
+
+ get_list = notification_list_get_prev(get_list);
+ noti = notification_list_get_data(get_list);
+ }
+ }
+#endif
+}
+
+static void _quickpanel_noti_delete_volatil_data(void)
+{
+ notification_list_h noti_list = NULL;
+ notification_list_h noti_list_head = NULL;
+ notification_h noti = NULL;
+ int property = 0;
+
+ notification_get_grouping_list(NOTIFICATION_TYPE_NONE, -1, &noti_list);
+
+ noti_list_head = noti_list;
+
+ while (noti_list != NULL) {
+ noti = notification_list_get_data(noti_list);
+ notification_get_property(noti, &property);
+
+ if (property & NOTIFICATION_PROP_VOLATILE_DISPLAY) {
+ notification_set_property(noti,
+ property |
+ NOTIFICATION_PROP_DISABLE_UPDATE_ON_DELETE);
+ notification_delete(noti);
+ }
+
+ noti_list = notification_list_get_next(noti_list);
+ }
+
+ notification_free_list(noti_list_head);
+
+ notification_update(NULL);
+}
+
+static void _quickpanel_noti_detailed_changed_cb(void *data, notification_type_e type, notification_op *op_list, int num_op)
+{
+ int i = 0;
+ int op_type = 0;
+ int priv_id = 0;
+ struct appdata *ad = NULL;
+ notification_h new_noti = NULL;
+ notification_type_e noti_type = NOTIFICATION_TYPE_NONE;
+ int noti_applist = NOTIFICATION_DISPLAY_APP_ALL;
+ notification_ly_type_e noti_layout = NOTIFICATION_LY_NONE;
+
+ retif(data == NULL, , "Invalid parameter!");
+ ad = data;
+
+ DBG("test detailed quickpanel:%d", num_op);
+
+ for (i = 0; i < num_op; i++) {
+ notification_op_get_data(op_list + i, NOTIFICATION_OP_DATA_TYPE, &op_type);
+ DBG("op_type:%d", op_type);
+ notification_op_get_data(op_list + i, NOTIFICATION_OP_DATA_PRIV_ID, &priv_id);
+ DBG("op_priv_id:%d", priv_id);
+
+ if (op_type == NOTIFICATION_OP_INSERT) {
+ new_noti = notification_load(NULL, priv_id);
+ if (new_noti == NULL) continue;
+
+ notification_get_type(new_noti, &noti_type);
+ notification_get_display_applist(new_noti, &noti_applist);
+ notification_get_layout(new_noti, &noti_layout);
+
+ DBG("layout:%d", noti_layout);
+
+ if (noti_applist & NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY) {
+ noti_node_item *node = noti_node_get(g_noti_node, priv_id);
+ if (node != NULL) {
+ if (noti_type == NOTIFICATION_TYPE_NOTI) {
+ DBG("cb after inserted:%d", priv_id);
+ }
+ } else {
+ if (noti_type == NOTIFICATION_TYPE_NOTI) {
+ _quickpanel_noti_noti_add(ad->list, new_noti, GRIDBOX_PREPEND);
+ } else if (noti_type == NOTIFICATION_TYPE_ONGOING) {
+ _quickpanel_noti_ongoing_add(ad->list, new_noti);
+ }
+ }
+ DBG("%d noti added", priv_id);
+ } else {
+ notification_free(new_noti);
+ }
+ }
+ if (op_type == NOTIFICATION_OP_DELETE) {
+ noti_node_item *node = noti_node_get(g_noti_node, priv_id);
+
+ if (node != NULL && node->noti != NULL) {
+ notification_h noti = node->noti;
+ notification_get_type(noti, &noti_type);
+
+ if (noti_type == NOTIFICATION_TYPE_NOTI) {
+ gridbox_remove_item(g_noti_gridbox, node->view, 0);
+ } else if (noti_type == NOTIFICATION_TYPE_ONGOING) {
+ elm_object_item_del(node->view);
+ }
+ }
+ DBG("%d noti deleted", priv_id);
+ }
+ if (op_type == NOTIFICATION_OP_UPDATE) {
+ noti_node_item *node = noti_node_get(g_noti_node, priv_id);
+ qp_item_data *qid = NULL;
+ notification_h old_noti = NULL;
+
+ new_noti = notification_load(NULL, priv_id);
+ retif(new_noti == NULL, , "fail to load updated noti");
+
+ if (node != NULL && node->view != NULL && node->noti != NULL) {
+ notification_get_type(new_noti, &noti_type);
+
+ if (noti_type == NOTIFICATION_TYPE_NOTI) {
+ gridbox_remove_item(g_noti_gridbox, node->view, 0);
+ _quickpanel_noti_noti_add(ad->list, new_noti, GRIDBOX_PREPEND);
+/*
+ gridbox_remove_and_add_item(g_noti_gridbox, node->view,
+ _quickpanel_noti_noti_add
+ ,ad->list, new_noti, GRIDBOX_PREPEND);
+*/
+ } else if (noti_type == NOTIFICATION_TYPE_ONGOING) {
+ old_noti = node->noti;
+ node->noti = new_noti;
+
+ qid = elm_object_item_data_get(node->view);
+ retif(qid == NULL, , "noti is already deleted");
+ quickpanel_list_util_item_set_data(qid, new_noti);
+ elm_genlist_item_fields_update(node->view, "*",
+ ELM_GENLIST_ITEM_FIELD_ALL);
+ }
+
+ if (old_noti != NULL) {
+ notification_free(old_noti);
+ }
+ } else {
+ notification_get_display_applist(new_noti, &noti_applist);
+
+ if (noti_applist & NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY) {
+
+ if (noti_type == NOTIFICATION_TYPE_NOTI) {
+ _quickpanel_noti_noti_add(ad->list, new_noti, GRIDBOX_PREPEND);
+ } else if (noti_type == NOTIFICATION_TYPE_ONGOING) {
+ _quickpanel_noti_ongoing_add(ad->list, new_noti);
+ }
+ }
+ }
+
+ DBG("%d noti updated", priv_id);
+ }
+ }
+
+ if (noti_node_get_item_count(g_noti_node, NOTIFICATION_TYPE_NOTI)
+ <= 0) {
+ struct appdata *ad = quickpanel_get_app_data();
+ _quickpanel_noti_clear_notilist(ad->list);
+ } else {
+ if (noti_group != NULL) {
+ elm_genlist_item_fields_update(noti_group, "*",
+ ELM_GENLIST_ITEM_FIELD_ALL);
+ }
+ _quickpanel_noti_update_notibox();
+ }
+}
+
+static void _quickpanel_noti_update_sim_status_cb(keynode_t *node, void *data)
+{
+ struct appdata *ad = data;
+
+ if (ad != NULL && ad->list != NULL) {
+ _quickpanel_noti_update_notilist(ad);
+
+ _quickpanel_noti_update_notibox();
+ }
+}
+
+static int _quickpanel_noti_register_event_handler(struct appdata *ad)
+{
+ int ret = 0;
+ retif(ad == NULL, QP_FAIL, "Invalid parameter!");
+
+ /* Add dbus signal */
+ e_dbus_init();
+ ad->dbus_connection = e_dbus_bus_get(DBUS_BUS_SYSTEM);
+ if (ad->dbus_connection == NULL) {
+ ERR("noti register : failed to get dbus bus");
+ return -1;
+ }
+
+ ad->dbus_handler_size =
+ e_dbus_signal_handler_add(ad->dbus_connection, NULL,
+ QP_NOTI_ONGOING_DBUS_PATH,
+ QP_NOTI_ONGOING_DBUS_INTERFACE, "update_progress",
+ _quickpanel_noti_item_progress_update_cb,
+ ad);
+ if (ad->dbus_handler_size == NULL)
+ ERR("fail to add size signal");
+
+ ad->dbus_handler_progress =
+ e_dbus_signal_handler_add(ad->dbus_connection, NULL,
+ QP_NOTI_ONGOING_DBUS_PATH,
+ QP_NOTI_ONGOING_DBUS_INTERFACE, "update_size",
+ _quickpanel_noti_item_size_update_cb,
+ ad);
+ if (ad->dbus_handler_progress == NULL)
+ ERR("fail to add progress signal");
+
+ ad->dbus_handler_content =
+ e_dbus_signal_handler_add(ad->dbus_connection, NULL,
+ QP_NOTI_ONGOING_DBUS_PATH,
+ QP_NOTI_ONGOING_DBUS_INTERFACE, "update_content",
+ _quickpanel_noti_item_content_update_cb,
+ ad);
+ if (ad->dbus_handler_content == NULL)
+ ERR("fail to add content signal");
+
+ /* Notify vconf key */
+ ret = vconf_notify_key_changed(VCONFKEY_TELEPHONY_SIM_SLOT,
+ _quickpanel_noti_update_sim_status_cb,
+ (void *)ad);
+ if (ret != 0)
+ ERR("Failed to register SIM_SLOT change callback!");
+
+ /* Register notification changed cb */
+#ifdef QP_DETAILED_NOTI_CHANGE_CB_ENABLE
+ notification_register_detailed_changed_cb(_quickpanel_noti_detailed_changed_cb, ad);
+#else
+ notification_resister_changed_cb(_quickpanel_noti_changed_cb, ad);
+#endif
+
+ return ret;
+}
+
+static int _quickpanel_noti_unregister_event_handler(struct appdata *ad)
+{
+ int ret = 0;
+
+ /* Unregister notification changed cb */
+#ifdef QP_DETAILED_NOTI_CHANGE_CB_ENABLE
+ notification_unregister_detailed_changed_cb(_quickpanel_noti_detailed_changed_cb, (void *)ad);
+#else
+ notification_unresister_changed_cb(_quickpanel_noti_changed_cb);
+#endif
+
+ /* Ignore vconf key */
+ ret = vconf_ignore_key_changed(VCONFKEY_TELEPHONY_SIM_SLOT,
+ _quickpanel_noti_update_sim_status_cb);
+ if (ret != 0)
+ ERR("Failed to ignore SIM_SLOT change callback!");
+
+ /* Delete dbus signal */
+ if (ad->dbus_handler_size != NULL) {
+ e_dbus_signal_handler_del(ad->dbus_connection,
+ ad->dbus_handler_size);
+ ad->dbus_handler_size = NULL;
+ }
+ if (ad->dbus_handler_progress != NULL) {
+ e_dbus_signal_handler_del(ad->dbus_connection,
+ ad->dbus_handler_progress);
+ ad->dbus_handler_progress = NULL;
+ }
+ if (ad->dbus_handler_content != NULL) {
+ e_dbus_signal_handler_del(ad->dbus_connection,
+ ad->dbus_handler_content);
+ ad->dbus_handler_content = NULL;
+ }
+
+ if (ad->dbus_connection != NULL) {
+ e_dbus_connection_close(ad->dbus_connection);
+ ad->dbus_connection = NULL;
+ }
+
+ return QP_OK;
+}
+
+static int _quickpanel_noti_check_first_start(void)
+{
+ int status = 0;
+ int ret = 0;
+
+ ret = vconf_get_bool(VCONFKEY_QUICKPANEL_STARTED, &status);
+ if (ret) {
+ INFO("fail to get %s", VCONFKEY_QUICKPANEL_STARTED);
+ /* reboot */
+ ret = vconf_set_bool(VCONFKEY_QUICKPANEL_STARTED, 1);
+ INFO("set : %s, result : %d", VCONFKEY_QUICKPANEL_STARTED, ret);
+ }
+
+ if (status)
+ return 0;
+
+ return 1;
+}
+
+static Eina_Bool quickpanel_noti_refresh_gridbox(void *data)
+{
+ struct appdata *ad = NULL;
+
+ retif(data == NULL, EINA_FALSE, "Invalid parameter!");
+ ad = data;
+
+ DBG("wr");
+
+ /* Update notification list */
+ _quickpanel_noti_update_notilist(ad);
+
+ _quickpanel_noti_register_event_handler(ad);
+
+ _quickpanel_noti_update_notibox();
+
+ return EINA_FALSE;
+}
+
+static int quickpanel_noti_init(void *data)
+{
+ struct appdata *ad = data;
+ int is_first = 0;
+
+ retif(ad == NULL, QP_FAIL, "Invalid parameter!");
+
+ g_window = ad->win;
+
+#ifdef QP_DETAILED_NOTI_CHANGE_CB_ENABLE
+ noti_node_create(&g_noti_node);
+#endif
+
+ is_first = _quickpanel_noti_check_first_start();
+ if (is_first) {
+ /* Remove ongoing and volatile noti data */
+ notifiation_clear(NOTIFICATION_TYPE_ONGOING);
+ _quickpanel_noti_delete_volatil_data();
+ }
+
+ _quickpanel_noti_gl_style_init();
+
+ ecore_timer_add(0.200, quickpanel_noti_refresh_gridbox, ad);
+
+ return QP_OK;
+}
+
+static int quickpanel_noti_fini(void *data)
+{
+ struct appdata *ad = data;
+ retif(ad == NULL, QP_FAIL, "Invalid parameter!");
+#ifdef QP_DETAILED_NOTI_CHANGE_CB_ENABLE
+ if (g_noti_node != NULL) {
+ noti_node_destroy(&g_noti_node);
+ }
+#else
+ /* Remove notification list */
+ if (g_notification_ongoing_list != NULL) {
+ notification_free_list(g_notification_ongoing_list);
+
+ g_notification_ongoing_list = NULL;
+ }
+
+ if (g_notification_list != NULL) {
+ notification_free_list(g_notification_list);
+
+ g_notification_list = NULL;
+ }
+#endif
+ /* Unregister event handler */
+ _quickpanel_noti_unregister_event_handler(data);
+ _quickpanel_noti_clear_list_all(ad->list);
+ _quickpanel_noti_gl_style_fini();
+ return QP_OK;
+}
+
+static int quickpanel_noti_suspend(void *data)
+{
+ struct appdata *ad = data;
+ retif(ad == NULL, QP_FAIL, "Invalid parameter!");
+
+ suspended = 1;
+
+ if (ad->list) {
+ _quickpanel_noti_ani_image_control(EINA_FALSE);
+ }
+
+ return QP_OK;
+}
+
+static int quickpanel_noti_resume(void *data)
+{
+ struct appdata *ad = data;
+ retif(ad == NULL, QP_FAIL, "Invalid parameter!");
+
+ suspended = 0;
+
+ if (ad->list) {
+ quickpanel_list_util_item_update_by_type(ad->list,
+ ongoing_first, QP_ITEM_TYPE_ONGOING_NOTI);
+
+ _quickpanel_noti_ani_image_control(EINA_TRUE);
+
+ _quickpanel_noti_update_notibox();
+ }
+
+ return QP_OK;
+}
+
+static void quickpanel_noti_refresh(void *data) {
+ struct appdata *ad = NULL;
+
+ retif(data == NULL, , "Invalid parameter!");
+ ad = data;
+
+ if (g_noti_gridbox != NULL) {
+ gridbox_rotation(g_noti_gridbox, ad->angle);
+ }
+ _quickpanel_noti_update_notibox();
+}
+
+void quickpanel_noti_lang_changed(void *data)
+{
+ struct appdata *ad = data;
+
+ retif(ad == NULL, , "Invalid parameter!");
+
+ _quickpanel_noti_update_notilist(ad);
+
+ _quickpanel_noti_update_notibox();
+}
+
+static unsigned int quickpanel_noti_get_height(void *data)
+{
+ int height = 0;
+ struct appdata *ad = data;
+
+ retif(ad == NULL, 0, "Invalid parameter!");
+
+ if (noti_group) {
+ height = QP_THEME_LIST_ITEM_GROUP_HEIGHT;
+ }
+ height +=
+ noti_node_get_item_count(
+ g_noti_node,
+ NOTIFICATION_TYPE_NOTI) * QP_THEME_LIST_ITEM_NOTI_HEIGHT
+ + noti_node_get_item_count(g_noti_node, NOTIFICATION_TYPE_ONGOING) * (QP_THEME_LIST_ITEM_ONGOING_HEIGHT + QP_THEME_LIST_ITEM_ONGOING_SEPERATOR_HEIGHT);return
+ height * ad->scale;
+}
diff --git a/daemon/notifications/noti.h b/daemon/notifications/noti.h
new file mode 100755
index 0000000..9a31a1f
--- /dev/null
+++ b/daemon/notifications/noti.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __NOTI_H__
+#define __NOTI_H__
+char *quickpanel_noti_get_time(time_t t, char *buf, int buf_len);
+#endif
diff --git a/daemon/notifications/noti_box.c b/daemon/notifications/noti_box.c
new file mode 100755
index 0000000..fae1be9
--- /dev/null
+++ b/daemon/notifications/noti_box.c
@@ -0,0 +1,480 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include <Ecore_X.h>
+
+#include "quickpanel-ui.h"
+#include "common.h"
+#include "list_util.h"
+#include "quickpanel_theme_def.h"
+#include "noti_box.h"
+#include "noti_node.h"
+#include "noti.h"
+
+static void _noti_box_call_item_cb(Evas_Object *noti_box, const char *emission) {
+ retif(noti_box == NULL, , "invalid parameter");
+ retif(emission == NULL, , "invalid parameter");
+
+ DBG("%s", emission);
+
+ void (*cb)(void *data, Evas_Object *obj) = NULL;
+ noti_box_h *data = NULL;
+
+ data = evas_object_data_get(noti_box, E_DATA_NOTI_BOX_H);
+
+ if (strncmp(emission,"selected", strlen("selected")) == 0) {
+ cb = evas_object_data_get(noti_box, E_DATA_CB_SELECTED_ITEM);
+
+ if (cb != NULL && data != NULL) {
+ cb(data->data, noti_box);
+ }
+ }
+ if (strncmp(emission,"deleted", strlen("deleted")) == 0) {
+ cb = evas_object_data_get(noti_box, E_DATA_CB_DELETED_ITEM);
+
+ if (cb != NULL && data != NULL) {
+ cb(data->data, noti_box);
+ }
+ }
+}
+
+void _signal_cb(void *data, Evas_Object *o, const char *emission, const char *source)
+{
+ retif(data == NULL, , "invalid parameter");
+ retif(o == NULL, , "invalid parameter");
+ retif(emission == NULL, , "invalid parameter");
+
+ _noti_box_call_item_cb(o, emission);
+}
+
+Evas_Object *noti_box_create(Evas_Object *parent, notification_ly_type_e layout) {
+ Evas_Object *box = NULL;
+
+ box = elm_layout_add(parent);
+
+ DBG("");
+ if (layout == NOTIFICATION_LY_NOTI_EVENT_SINGLE
+ || layout == NOTIFICATION_LY_NOTI_EVENT_MULTIPLE) {
+ elm_layout_file_set(box, DEFAULT_EDJ,
+ "quickpanel/notibox/single_multi");
+ } else if (layout == NOTIFICATION_LY_NOTI_THUMBNAIL) {
+ elm_layout_file_set(box, DEFAULT_EDJ, "quickpanel/notibox/thumbnail");
+ } else {
+ elm_layout_file_set(box, DEFAULT_EDJ,
+ "quickpanel/notibox/single_multi");
+ }
+
+ evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_show(box);
+
+ noti_box_h *box_h = (noti_box_h *) malloc(sizeof(noti_box_h));
+ box_h->layout = layout;
+ box_h->status = STATE_NORMAL;
+ box_h->data = NULL;
+ evas_object_data_set(box, E_DATA_NOTI_BOX_H, box_h);
+ DBG("created box:%p", box);
+
+ //add event
+ elm_object_signal_callback_add(box,
+ "selected",
+ "object.layer.touch",
+ _signal_cb,
+ parent
+ );
+ //add event
+ elm_object_signal_callback_add(box,
+ "deleted",
+ "object.layer.touch",
+ _signal_cb,
+ parent
+ );
+
+ return box;
+}
+
+static void _set_image(Evas_Object *noti_box, notification_h noti,
+ notification_image_type_e image_type, const char *part, int is_stretch) {
+
+ DBG("");
+
+ char *image = NULL;
+
+ notification_get_image(noti, image_type, &image);
+
+ if (image != NULL) {
+ Evas_Object *content = NULL;
+ content = elm_image_add(noti_box);
+ elm_image_file_set(content, image, NULL);
+ if (is_stretch == 1) {
+ elm_image_aspect_fixed_set(content, EINA_FALSE);
+ elm_image_resizable_set(content, EINA_TRUE, EINA_TRUE);
+ }
+
+ elm_object_part_content_set(noti_box, part, content);
+ }
+}
+
+static int _set_text(Evas_Object *noti_box, notification_h noti,
+ notification_text_type_e text_type, const char *part) {
+ char buf[128] = { 0, };
+
+ char *text = NULL;
+ time_t time = 0;
+
+ if (notification_get_time_from_text(noti, text_type, &time) == NOTIFICATION_ERROR_NONE) {
+ if ((int)time > 0) {
+ quickpanel_noti_get_time(time, buf, sizeof(buf));
+ text = buf;
+ }
+ } else {
+ notification_get_text(noti, text_type, &text);
+ }
+
+ if (text != NULL) {
+ elm_object_part_text_set(noti_box, part, text);
+
+ return strlen(text);
+ }
+
+ return 0;
+}
+
+static int _check_text_null(notification_h noti,
+ notification_text_type_e text_type) {
+ DBG("");
+
+ char *text = NULL;
+
+ notification_get_text(noti, text_type, &text);
+
+ if (text == NULL) {
+ return 1;
+ }
+
+ return 0;
+}
+
+static int _check_image_null(notification_h noti,
+ notification_image_type_e image_type) {
+ DBG("");
+
+ char *image = NULL;
+
+ notification_get_image(noti, image_type, &image);
+
+ if (image == NULL) {
+ return 1;
+ }
+
+ return 0;
+}
+
+static void _noti_box_set_layout_single(Evas_Object *noti_box,
+ notification_h noti) {
+ DBG("");
+
+ char *dir = NULL;
+ char *domain = NULL;
+
+ notification_get_text_domain(noti, &domain, &dir);
+ if (domain != NULL && dir != NULL)
+ bindtextdomain(domain, dir);
+
+ _set_text(noti_box, noti, NOTIFICATION_TEXT_TYPE_TITLE,
+ "object.text.title");
+ _set_text(noti_box, noti, NOTIFICATION_TEXT_TYPE_CONTENT,
+ "object.text.contents");
+
+ if (_check_text_null(noti, NOTIFICATION_TEXT_TYPE_INFO_1) == 0) {
+ if (_check_text_null(noti, NOTIFICATION_TEXT_TYPE_INFO_SUB_1) == 1) {
+ _set_text(noti_box, noti, NOTIFICATION_TEXT_TYPE_INFO_1,
+ "object.text.info.1");
+ } else {
+ _set_text(noti_box, noti, NOTIFICATION_TEXT_TYPE_INFO_1,
+ "object.text.info.1.short");
+ _set_text(noti_box, noti, NOTIFICATION_TEXT_TYPE_INFO_SUB_1,
+ "object.text.info.sub.1");
+ }
+ }
+ _set_text(noti_box, noti, NOTIFICATION_TEXT_TYPE_INFO_2,
+ "object.text.info.2");
+
+ if (_check_image_null(noti, NOTIFICATION_IMAGE_TYPE_THUMBNAIL) == 0) {
+ _set_image(noti_box, noti, NOTIFICATION_IMAGE_TYPE_ICON,
+ "object.icon.sub", 1);
+ _set_image(noti_box, noti, NOTIFICATION_IMAGE_TYPE_THUMBNAIL,
+ "object.icon", 1);
+ } else {
+ _set_image(noti_box, noti, NOTIFICATION_IMAGE_TYPE_ICON,
+ "object.icon", 1);
+ _set_image(noti_box, noti, NOTIFICATION_IMAGE_TYPE_ICON_SUB,
+ "object.icon.sub", 1);
+ }
+ _set_image(noti_box, noti, NOTIFICATION_IMAGE_TYPE_BACKGROUND,
+ "object.icon.background", 1);
+
+ if (_check_image_null(noti, NOTIFICATION_IMAGE_TYPE_BACKGROUND) == 0) {
+ elm_object_signal_emit(noti_box, "box.show.dim", "box.prog");
+ }
+ if (_check_image_null(noti, NOTIFICATION_IMAGE_TYPE_ICON) == 1
+ && _check_image_null(noti, NOTIFICATION_IMAGE_TYPE_THUMBNAIL) == 1) {
+ elm_object_signal_emit(noti_box, "box.hide.icon.bg", "box.prog");
+ }
+ if (_check_image_null(noti, NOTIFICATION_IMAGE_TYPE_ICON_SUB) == 0
+ || _check_image_null(noti, NOTIFICATION_IMAGE_TYPE_THUMBNAIL) == 0) {
+ elm_object_signal_emit(noti_box, "box.show.sub.bg", "box.prog");
+ }
+}
+
+static void _noti_box_set_layout_multi(Evas_Object *noti_box,
+ notification_h noti) {
+ DBG("");
+
+ int length = 0;
+ char *dir = NULL;
+ char *domain = NULL;
+ char buf[128] = {0,};
+
+ notification_get_text_domain(noti, &domain, &dir);
+ if (domain != NULL && dir != NULL)
+ bindtextdomain(domain, dir);
+
+ _set_text(noti_box, noti, NOTIFICATION_TEXT_TYPE_TITLE,
+ "object.text.title");
+ if (_check_text_null(noti, NOTIFICATION_TEXT_TYPE_EVENT_COUNT) == 0) {
+ _set_text(noti_box, noti, NOTIFICATION_TEXT_TYPE_CONTENT,
+ "object.text.contents.short");
+ length = _set_text(noti_box, noti, NOTIFICATION_TEXT_TYPE_EVENT_COUNT,
+ "object.text.count");
+ length = (length >= 5) ? 5 : length;
+ snprintf(buf, sizeof(buf), "box.count.%d", length);
+ elm_object_signal_emit(noti_box, buf, "box.prog");
+ DBG("buf:%s", buf);
+ } else {
+ _set_text(noti_box, noti, NOTIFICATION_TEXT_TYPE_CONTENT,
+ "object.text.contents");
+ }
+
+ if (_check_text_null(noti, NOTIFICATION_TEXT_TYPE_INFO_1) == 0) {
+ if (_check_text_null(noti, NOTIFICATION_TEXT_TYPE_INFO_SUB_1) == 1) {
+ _set_text(noti_box, noti, NOTIFICATION_TEXT_TYPE_INFO_1,
+ "object.text.info.1");
+ } else {
+ _set_text(noti_box, noti, NOTIFICATION_TEXT_TYPE_INFO_1,
+ "object.text.info.1.short");
+ _set_text(noti_box, noti, NOTIFICATION_TEXT_TYPE_INFO_SUB_1,
+ "object.text.info.sub.1");
+ }
+ }
+ if (_check_text_null(noti, NOTIFICATION_TEXT_TYPE_INFO_2) == 0) {
+ if (_check_text_null(noti, NOTIFICATION_TEXT_TYPE_INFO_SUB_2) == 1) {
+ _set_text(noti_box, noti, NOTIFICATION_TEXT_TYPE_INFO_2,
+ "object.text.info.2");
+ } else {
+ _set_text(noti_box, noti, NOTIFICATION_TEXT_TYPE_INFO_2,
+ "object.text.info.2.short");
+ _set_text(noti_box, noti, NOTIFICATION_TEXT_TYPE_INFO_SUB_2,
+ "object.text.info.sub.2");
+ }
+ }
+
+ if (_check_image_null(noti, NOTIFICATION_IMAGE_TYPE_THUMBNAIL) == 0) {
+ _set_image(noti_box, noti, NOTIFICATION_IMAGE_TYPE_ICON,
+ "object.icon.sub", 1);
+ _set_image(noti_box, noti, NOTIFICATION_IMAGE_TYPE_THUMBNAIL,
+ "object.icon", 1);
+ } else {
+ _set_image(noti_box, noti, NOTIFICATION_IMAGE_TYPE_ICON,
+ "object.icon", 1);
+ _set_image(noti_box, noti, NOTIFICATION_IMAGE_TYPE_ICON_SUB,
+ "object.icon.sub", 1);
+ }
+ _set_image(noti_box, noti, NOTIFICATION_IMAGE_TYPE_BACKGROUND,
+ "object.icon.background", 1);
+ if (_check_image_null(noti, NOTIFICATION_IMAGE_TYPE_BACKGROUND) == 0) {
+ elm_object_signal_emit(noti_box, "box.show.dim", "box.prog");
+ }
+ if (_check_image_null(noti, NOTIFICATION_IMAGE_TYPE_ICON) == 1
+ && _check_image_null(noti, NOTIFICATION_IMAGE_TYPE_THUMBNAIL) == 1) {
+ elm_object_signal_emit(noti_box, "box.hide.icon.bg", "box.prog");
+ }
+ if (_check_image_null(noti, NOTIFICATION_IMAGE_TYPE_ICON_SUB) == 0
+ || _check_image_null(noti, NOTIFICATION_IMAGE_TYPE_THUMBNAIL) == 0) {
+ elm_object_signal_emit(noti_box, "box.show.sub.bg", "box.prog");
+ }
+}
+
+static void _noti_box_set_layout_thumbnail(Evas_Object *noti_box,
+ notification_h noti) {
+ DBG("");
+
+ char *dir = NULL;
+ char *domain = NULL;
+
+ notification_get_text_domain(noti, &domain, &dir);
+ if (domain != NULL && dir != NULL)
+ bindtextdomain(domain, dir);
+
+ _set_text(noti_box, noti, NOTIFICATION_TEXT_TYPE_TITLE,
+ "object.text.title");
+ _set_text(noti_box, noti, NOTIFICATION_TEXT_TYPE_CONTENT,
+ "object.text.contents");
+
+ if (_check_image_null(noti, NOTIFICATION_IMAGE_TYPE_THUMBNAIL) == 0) {
+ _set_image(noti_box, noti, NOTIFICATION_IMAGE_TYPE_ICON,
+ "object.icon.sub", 0);
+ _set_image(noti_box, noti, NOTIFICATION_IMAGE_TYPE_THUMBNAIL,
+ "object.icon", 0);
+ } else {
+ _set_image(noti_box, noti, NOTIFICATION_IMAGE_TYPE_ICON,
+ "object.icon", 0);
+ _set_image(noti_box, noti, NOTIFICATION_IMAGE_TYPE_ICON_SUB,
+ "object.icon.sub", 0);
+ }
+ _set_image(noti_box, noti, NOTIFICATION_IMAGE_TYPE_BACKGROUND,
+ "object.icon.background", 1);
+
+ _set_image(noti_box, noti, NOTIFICATION_IMAGE_TYPE_LIST_1,
+ "object.thumbnail.list.1", 1);
+ _set_image(noti_box, noti, NOTIFICATION_IMAGE_TYPE_LIST_2,
+ "object.thumbnail.list.2", 1);
+ _set_image(noti_box, noti, NOTIFICATION_IMAGE_TYPE_LIST_3,
+ "object.thumbnail.list.3", 1);
+ _set_image(noti_box, noti, NOTIFICATION_IMAGE_TYPE_LIST_4,
+ "object.thumbnail.list.4", 1);
+ _set_image(noti_box, noti, NOTIFICATION_IMAGE_TYPE_LIST_5,
+ "object.thumbnail.list.5", 1);
+
+ if (_check_image_null(noti, NOTIFICATION_IMAGE_TYPE_BACKGROUND) == 0) {
+ elm_object_signal_emit(noti_box, "box.show.dim", "box.prog");
+ }
+ if (_check_image_null(noti, NOTIFICATION_IMAGE_TYPE_ICON) == 1
+ && _check_image_null(noti, NOTIFICATION_IMAGE_TYPE_THUMBNAIL) == 1) {
+ elm_object_signal_emit(noti_box, "box.hide.icon.bg", "box.prog");
+ }
+ if (_check_image_null(noti, NOTIFICATION_IMAGE_TYPE_ICON_SUB) == 0
+ || _check_image_null(noti, NOTIFICATION_IMAGE_TYPE_THUMBNAIL) == 0) {
+ elm_object_signal_emit(noti_box, "box.show.sub.bg", "box.prog");
+ }
+}
+
+static void _noti_box_set_layout(Evas_Object *noti_box, notification_h noti,
+ notification_ly_type_e layout) {
+
+ DBG("layout:%d", layout);
+
+ switch (layout) {
+ case NOTIFICATION_LY_NOTI_EVENT_SINGLE:
+ _noti_box_set_layout_single(noti_box, noti);
+ break;
+ case NOTIFICATION_LY_NOTI_EVENT_MULTIPLE:
+ _noti_box_set_layout_multi(noti_box, noti);
+ break;
+ case NOTIFICATION_LY_NOTI_THUMBNAIL:
+ _noti_box_set_layout_thumbnail(noti_box, noti);
+ break;
+ case NOTIFICATION_LY_NONE:
+ case NOTIFICATION_LY_ONGOING_EVENT:
+ case NOTIFICATION_LY_ONGOING_PROGRESS:
+ case NOTIFICATION_LY_MAX:
+ DBG("not supported layout type:%d", layout);
+ break;
+ }
+}
+
+void noti_box_remove(Evas_Object *noti_box) {
+
+ retif(noti_box == NULL, , "invalid parameter");
+
+ noti_box_h *noti_box_h = evas_object_data_get(noti_box, E_DATA_NOTI_BOX_H);
+
+ if (noti_box_h != NULL)
+ free(noti_box_h);
+
+ evas_object_data_del(noti_box, E_DATA_NOTI_BOX_H);
+ evas_object_data_del(noti_box, E_DATA_CB_SELECTED_ITEM);
+ evas_object_data_del(noti_box, E_DATA_CB_DELETED_ITEM);
+
+ evas_object_del(noti_box);
+}
+
+void noti_box_set_status(Evas_Object *noti_box, int status) {
+ retif(noti_box == NULL, , "invalid parameter");
+
+ noti_box_h *noti_box_h = evas_object_data_get(noti_box, E_DATA_NOTI_BOX_H);
+
+ if (noti_box_h != NULL) {
+ noti_box_h->status = status;
+ }
+}
+
+int noti_box_get_status(Evas_Object *noti_box) {
+ retif(noti_box == NULL, STATE_NORMAL, "invalid parameter");
+
+ noti_box_h *noti_box_h = evas_object_data_get(noti_box, E_DATA_NOTI_BOX_H);
+
+ if (noti_box_h != NULL) {
+ return noti_box_h->status;
+ }
+
+ return STATE_DELETING;
+}
+
+void noti_box_node_set(Evas_Object *noti_box, void *data) {
+ retif(noti_box == NULL, , "invalid parameter");
+ retif(data == NULL, , "invalid parameter");
+
+ noti_box_h *noti_box_data = evas_object_data_get(noti_box, E_DATA_NOTI_BOX_H);
+
+ if (noti_box_data != NULL) {
+ noti_box_data->data = data;
+
+ if (data != NULL) {
+ noti_node_item *item = data;
+ _noti_box_set_layout(noti_box, item->noti, noti_box_data->layout);
+ }
+ }
+}
+
+void *noti_box_node_get(Evas_Object *noti_box) {
+ retif(noti_box == NULL, NULL, "invalid parameter");
+
+ noti_box_h *noti_box_data = evas_object_data_get(noti_box, E_DATA_NOTI_BOX_H);
+
+ if (noti_box_data != NULL) {
+ return noti_box_data->data;
+ }
+
+ return NULL;
+}
+
+void noti_box_set_item_selected_cb(Evas_Object *noti_box,
+ void(*selected_cb)(void *data, Evas_Object *obj)) {
+ retif(noti_box == NULL, , "invalid parameter");
+ retif(selected_cb == NULL, , "invalid parameter");
+
+ evas_object_data_set(noti_box, E_DATA_CB_SELECTED_ITEM, selected_cb);
+}
+
+void noti_box_set_item_deleted_cb(Evas_Object *noti_box,
+ void(*deleted_cb)(void *data, Evas_Object *obj)) {
+ retif(noti_box == NULL, , "invalid parameter");
+ retif(deleted_cb == NULL, , "invalid parameter");
+
+ evas_object_data_set(noti_box, E_DATA_CB_DELETED_ITEM, deleted_cb);
+}
diff --git a/daemon/notifications/noti_box.h b/daemon/notifications/noti_box.h
new file mode 100755
index 0000000..d5d8fd2
--- /dev/null
+++ b/daemon/notifications/noti_box.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __QUICKPANEL_NOTI_BOX_H__
+#define __QUICKPANEL_NOTI_BOX_H__
+
+#include <notification.h>
+
+#define STATE_NORMAL 1
+#define STATE_DELETING 0
+
+#define E_DATA_NOTI_BOX_H "noti_box"
+#define E_DATA_CB_SELECTED_ITEM "noti_box_cb_selected"
+#define E_DATA_CB_DELETED_ITEM "noti_box_cb_deleted"
+
+typedef struct _noti_box_h {
+ int status;
+ void *data;
+ notification_ly_type_e layout;
+} noti_box_h;
+
+Evas_Object *noti_box_create(Evas_Object *parent, notification_ly_type_e layout);
+void noti_box_node_set(Evas_Object *noti_box, void *data);
+void *noti_box_node_get(Evas_Object *noti_box);
+void noti_box_remove(Evas_Object *noti_box);
+void noti_box_set_item_selected_cb(Evas_Object *noti_box,
+ void(*selected_cb)(void *data, Evas_Object *obj));
+void noti_box_set_item_deleted_cb(Evas_Object *noti_box,
+ void(*deleted_cb)(void *data, Evas_Object *obj));
+int noti_box_get_status(Evas_Object *noti_box);
+void noti_box_set_status(Evas_Object *noti_box, int status);
+
+#endif
diff --git a/daemon/notifications/noti_display_app.c b/daemon/notifications/noti_display_app.c
new file mode 100755
index 0000000..3c3d5bd
--- /dev/null
+++ b/daemon/notifications/noti_display_app.c
@@ -0,0 +1,422 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <E_Notify.h>
+#include <E_Notification_Daemon.h>
+#include <Elementary.h>
+#include "noti_win.h"
+#include "quickpanel-ui.h"
+#include "noti_display_app.h"
+
+#define INFO(str, args...) fprintf(stdout, str"\n", ##args)
+#define ERR(str, args...) fprintf(stderr, str"\n", ##args)
+
+static E_Notification_Daemon *g_notification_daemon;
+static const char *data_key = "_noti_data";
+static Evas_Object *app_win;
+
+struct Daemon_Data {
+ E_Notification_Daemon *daemon;
+ Eina_List *notes;
+ double default_timeout;
+ int next_id;
+};
+
+struct Timer_Data {
+ struct Daemon_Data *daemon_data;
+ E_Notification *n;
+ Ecore_Timer *timer;
+ enum Noti_Orient orient;
+};
+
+struct Noti_Data {
+ E_Notification *n;
+ const char *time;
+};
+
+/* Windows to display different orientations of notification */
+static Evas_Object *noti_win[NOTI_ORIENT_LAST];
+
+Eina_List *notification_daemon_note_list_get()
+{
+ struct Daemon_Data *daemon_data;
+
+ if (!g_notification_daemon)
+ return NULL;
+ daemon_data = e_notification_daemon_data_get(g_notification_daemon);
+ if (!daemon_data)
+ return NULL;
+ return daemon_data->notes;
+}
+
+void notification_daemon_note_list_clear()
+{
+ struct Daemon_Data *daemon_data;
+ Eina_List *l;
+ E_Notification *n;
+ struct Noti_Data *noti_data;
+
+ if (!g_notification_daemon)
+ return;
+ daemon_data = e_notification_daemon_data_get(g_notification_daemon);
+ if (!daemon_data)
+ return;
+ EINA_LIST_FOREACH(daemon_data->notes, l, noti_data) {
+ daemon_data->notes = eina_list_remove(daemon_data->notes,
+ noti_data);
+ n = noti_data->n;
+ eina_stringshare_replace(&noti_data->time, NULL);
+ e_notification_unref(n);
+ free(noti_data);
+ }
+}
+
+static struct Noti_Data *_notification_daemon_noti_data_find(
+ struct Daemon_Data *daemon_data, E_Notification *n)
+{
+ Eina_List *l;
+ struct Noti_Data *noti_data;
+
+ EINA_LIST_FOREACH(daemon_data->notes, l, noti_data)
+ if (noti_data->n == n)
+ return noti_data;
+
+ return NULL;
+}
+
+static void _notification_daemon_note_close(struct Daemon_Data *daemon_data,
+ E_Notification *n, int reason)
+{
+ struct Noti_Data *noti_data;
+
+ noti_data = _notification_daemon_noti_data_find(daemon_data, n);
+ if (!noti_data)
+ return;
+ daemon_data->notes = eina_list_remove(daemon_data->notes, noti_data);
+ n = noti_data->n;
+ eina_stringshare_replace(&noti_data->time, NULL);
+ e_notification_unref(n);
+ free(noti_data);
+ e_notification_closed_set(n, 1);
+ e_notification_daemon_signal_notification_closed(daemon_data->daemon,
+ e_notification_id_get(n), reason);
+}
+
+static void _note_destroy(struct Timer_Data *timer_data,
+ enum E_Notification_Closed_Reason reason)
+{
+ enum Noti_Orient orient;
+
+ if (!timer_data)
+ return;
+ orient = timer_data->orient;
+ if (!e_notification_closed_get(timer_data->n))
+ _notification_daemon_note_close(timer_data->daemon_data,
+ timer_data->n,
+ reason);
+ e_notification_unref(timer_data->n);
+ ecore_timer_del(timer_data->timer);
+ free(timer_data);
+ if (noti_win[orient]) {
+ evas_object_data_set(noti_win[orient], data_key, NULL);
+ evas_object_del(noti_win[orient]);
+ noti_win[orient] = NULL;
+ }
+}
+
+Eina_Bool _note_close_timer_cb(void *data)
+{
+ _note_destroy(data, E_NOTIFICATION_CLOSED_EXPIRED);
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static E_Notification *_notification_daemon_note_open_find(
+ struct Daemon_Data *daemon_data, unsigned int id)
+{
+ Eina_List *l;
+ struct Noti_Data *noti_data;
+
+ EINA_LIST_FOREACH(daemon_data->notes, l, noti_data)
+ if (e_notification_id_get(noti_data->n) == id)
+ return noti_data->n;
+
+ return NULL;
+}
+
+static void _notification_daemon_note_close_cb(E_Notification_Daemon *daemon,
+ unsigned int notification_id)
+{
+ struct Daemon_Data *daemon_data;
+ E_Notification *n;
+
+ daemon_data = e_notification_daemon_data_get(daemon);
+ n = _notification_daemon_note_open_find(daemon_data, notification_id);
+ if (n)
+ _notification_daemon_note_close(daemon_data, n,
+ E_NOTIFICATION_CLOSED_REQUESTED);
+ /* else send error */
+}
+
+
+static void _noti_hide_cb(void *data, Evas_Object *obj,
+ const char *emission, const char *source)
+{
+ _note_destroy(data, E_NOTIFICATION_CLOSED_DISMISSED);
+}
+
+static void _noti_button_clicked_cb(void *data, Evas_Object *obj,
+ void *event_info)
+{
+ _note_destroy(data, E_NOTIFICATION_CLOSED_REQUESTED);
+}
+
+static void _noti_show(E_Notification *n, enum Noti_Orient orient,
+ struct Timer_Data *timer_data)
+{
+ const char *summary;
+ Evas_Object *layout;
+ const char *path_icon;
+ Evas_Object *icon;
+ const char *data_win_height = NULL;
+ int noti_height = 50;
+ struct Timer_Data *old_timer_data = NULL;
+ Evas_Object *button = NULL;
+
+ if (noti_win[orient]) {
+ old_timer_data = evas_object_data_get(noti_win[orient],
+ data_key);
+ _note_destroy(old_timer_data, E_NOTIFICATION_CLOSED_REQUESTED);
+ }
+ noti_win[orient] = noti_win_add(NULL);
+ evas_object_data_set(noti_win[orient], data_key, timer_data);
+ layout = elm_layout_add(noti_win[orient]);
+ /* Only for sample code the theme implementation for layout has been
+ used. Apps should implement this layout/edje object which can have
+ at least one TEXT/TEXT BLOCK for showing body of notification and one
+ swallow part for showing icon of the notification.
+ Optionally the summary can be shown as well.
+ Applications need to set the minimum height of the layout or edje object
+ using evas_object_size_hint_min_set which can be used by the
+ notification window to resize itself.
+ */
+ if (orient == NOTI_ORIENT_BOTTOM)
+ elm_layout_theme_set(layout, "tickernoti", "base", "info");
+ else {
+ elm_layout_theme_set(layout, "tickernoti", "base",
+ "default");
+ button = elm_button_add(layout);
+ elm_object_style_set(button, "tickernoti");
+ elm_object_text_set(button, _S("IDS_COM_BODY_CLOSE"));
+ elm_object_part_content_set(layout, "button", button);
+ evas_object_smart_callback_add(button, "clicked",
+ _noti_button_clicked_cb, timer_data);
+ }
+ elm_object_signal_callback_add(layout, "request,hide", "",
+ _noti_hide_cb, timer_data);
+ /* Getting the height of the layout from theme just for sample code.
+ App is free to use any other method.
+ */
+ data_win_height = (char *)elm_layout_data_get(layout, "height");
+ if (data_win_height != NULL && elm_config_scale_get() > 0.0)
+ noti_height = (int)(elm_config_scale_get()
+ * atoi(data_win_height));
+ evas_object_size_hint_min_set(layout, 1, noti_height);
+ noti_win_content_set(noti_win[orient], layout);
+ summary = e_notification_summary_get(n);
+ if (summary)
+ elm_object_part_text_set(layout, "elm.text", summary);
+ else
+ elm_object_part_text_set(layout, "elm.text",
+ "new notification");
+ path_icon = e_notification_app_icon_get(n);
+ if (path_icon) {
+ INFO("%s", path_icon);
+ icon = elm_image_add(layout);
+ if (elm_image_file_set(icon, path_icon, NULL)) {
+ elm_image_resizable_set(icon, EINA_TRUE, EINA_TRUE);
+ elm_object_part_content_set(layout, "icon", icon);
+ }
+ }
+ noti_win_orient_set(noti_win[orient], orient);
+ if (app_win)
+ elm_win_rotation_with_resize_set(noti_win[orient],
+ elm_win_rotation_get(app_win));
+ evas_object_show(noti_win[orient]);
+}
+
+void _notification_daemon_note_show(struct Daemon_Data *daemon_data,
+ E_Notification *n)
+{
+ int timeout;
+ const char *category;
+ enum Noti_Orient orient = NOTI_ORIENT_TOP;
+ struct Noti_Data *noti_data;
+ time_t current;
+ char buf[256];
+ struct tm time_st;
+ struct Timer_Data *timer_data;
+
+ category = e_notification_hint_category_get(n);
+ if (category) {
+ if (!strcmp("device", category))
+ orient = NOTI_ORIENT_BOTTOM;
+ }
+
+ noti_data = calloc(1, sizeof(struct Noti_Data));
+ if (!noti_data)
+ return;
+ e_notification_ref(n);
+ noti_data->n = n;
+ current = time(NULL);
+ localtime_r(&current, &time_st);
+ strftime(buf, sizeof(buf), "%I:%M %p", &time_st);
+ eina_stringshare_replace(&noti_data->time, buf);
+ daemon_data->notes = eina_list_append(daemon_data->notes, noti_data);
+ timeout = e_notification_timeout_get(n);
+ timer_data = calloc(1, sizeof(struct Timer_Data));
+ _noti_show(n, orient, timer_data);
+ timer_data->daemon_data = daemon_data;
+ timer_data->orient = orient;
+ e_notification_ref(n);
+ e_notification_closed_set(n, 0);
+ timer_data->n = n;
+ timer_data->timer = ecore_timer_add(timeout == -1 ?
+ daemon_data->default_timeout : (float)timeout / 1000,
+ _note_close_timer_cb, timer_data);
+
+ INFO("Received notification from %s:%s %s",
+ e_notification_app_name_get(n),
+ e_notification_summary_get(n), e_notification_body_get(n));
+}
+
+static int _notification_cb(E_Notification_Daemon *daemon, E_Notification *n)
+{
+ struct Daemon_Data *daemon_data;
+ unsigned int replaces_id;
+ unsigned int new_id;
+
+ daemon_data = e_notification_daemon_data_get(daemon);
+ replaces_id = e_notification_replaces_id_get(n);
+ if (replaces_id)
+ new_id = replaces_id;
+ else
+ new_id = daemon_data->next_id++;
+ e_notification_id_set(n, new_id);
+ _notification_daemon_note_show(daemon_data, n);
+ return new_id;
+}
+
+static Eina_Bool _init()
+{
+ Eina_Bool ret = EINA_FALSE;
+ struct Daemon_Data *daemon_data;
+
+ if (!g_notification_daemon) {
+ e_notification_daemon_init();
+ g_notification_daemon = e_notification_daemon_add("notification"
+ , "Enlightenment");
+ if (!g_notification_daemon) {
+ ERR("Unable to add a notification daemon");
+ return EINA_FALSE;
+ }
+ daemon_data = calloc(1, sizeof(struct Daemon_Data));
+ if (!daemon_data) {
+ notification_daemon_shutdown();
+ return EINA_FALSE;
+ }
+ daemon_data->default_timeout = 1.0;
+ daemon_data->daemon = g_notification_daemon;
+ e_notification_daemon_data_set(g_notification_daemon,
+ daemon_data);
+ e_notification_daemon_callback_notify_set(g_notification_daemon,
+ _notification_cb);
+ e_notification_daemon_callback_close_notification_set(
+ g_notification_daemon,
+ _notification_daemon_note_close_cb);
+ INFO("Initializing Notification Daemon");
+ }
+ ret = !!g_notification_daemon;
+ return ret;
+}
+
+static Eina_Bool _shutdown()
+{
+ struct Daemon_Data *daemon_data;
+ Eina_List *l;
+ E_Notification *n;
+ int i;
+ struct Noti_Data *noti_data;
+ Eina_Bool ret = EINA_FALSE;
+
+ for (i = 0; i < NOTI_ORIENT_LAST; i++)
+ if (noti_win[i]) {
+ evas_object_del(noti_win[i]);
+ noti_win[i] = NULL;
+ }
+ if (!g_notification_daemon)
+ return ret;
+ daemon_data = e_notification_daemon_data_get(
+ g_notification_daemon);
+ if (!daemon_data)
+ return ret;
+ EINA_LIST_FOREACH(daemon_data->notes, l, noti_data) {
+ daemon_data->notes = eina_list_remove(daemon_data->notes,
+ noti_data);
+ n = noti_data->n;
+ eina_stringshare_replace(&noti_data->time, NULL);
+ e_notification_unref(n);
+ free(noti_data);
+ }
+ free(daemon_data);
+ e_notification_daemon_free(g_notification_daemon);
+ e_notification_daemon_shutdown();
+ g_notification_daemon = NULL;
+ ret = EINA_TRUE;
+ return ret;
+}
+
+void notification_daemon_init()
+{
+ int i;
+
+ if (!_init()) {
+ ERR("Error in intializing the notification daemon");
+ return;
+ }
+ for (i = 0; i < NOTI_ORIENT_LAST; i++)
+ if (noti_win[i]) {
+ evas_object_del(noti_win[i]);
+ noti_win[i] = NULL;
+ }
+}
+
+void notification_daemon_win_set(Evas_Object *win)
+{
+ /* This window is used to detect the orientation of the receiver app
+ window to support rotation of the notification window.
+ */
+ app_win = win;
+}
+
+void notification_daemon_shutdown()
+{
+ if (!_shutdown()) {
+ ERR("Error in shutting down the notification daemon");
+ return;
+ }
+ app_win = NULL;
+ INFO("Terminating Notification Daemon");
+}
diff --git a/daemon/notifications/noti_display_app.h b/daemon/notifications/noti_display_app.h
new file mode 100755
index 0000000..652ee43
--- /dev/null
+++ b/daemon/notifications/noti_display_app.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __NOTI_DISPLAY_APP_H__
+#define __NOTI_DISPLAY_APP_H__
+#include <Elementary.h>
+
+/* Initializes the notification daemon */
+void notification_daemon_init();
+/* Sets the window which rotation will be used to rotate the notification popup
+while displaying */
+void notification_daemon_win_set(Evas_Object *win);
+/* Terminates the notification daemon */
+void notification_daemon_shutdown();
+#endif
diff --git a/daemon/notifications/noti_gridbox.c b/daemon/notifications/noti_gridbox.c
new file mode 100755
index 0000000..49e906c
--- /dev/null
+++ b/daemon/notifications/noti_gridbox.c
@@ -0,0 +1,454 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <Ecore_X.h>
+
+#include "quickpanel-ui.h"
+#include "common.h"
+#include "list_util.h"
+#include "quickpanel_theme_def.h"
+#include "noti_gridbox.h"
+#include "noti_box.h"
+
+#define E_DATA_LAYOUT_PORTRAIT "layout_portrait"
+#define E_DATA_LAYOUT_LANDSCAPE "layout_landscape"
+#define E_DATA_CB_DELETE_ITEM "cb_delete_item"
+#define E_DATA_CB_REMOVED "cb_removed"
+#define E_DATA_APP_DATA "app_data"
+
+typedef struct _gridbox_info_layout {
+ int n_per_rows;
+ int padding_top;
+ int padding_left;
+ int padding_right;
+ int padding_bottom;
+ int padding_between;
+ int child_w;
+ int child_h;
+ double scale;
+} gridbox_info_layout;
+
+typedef struct _gridbox_info_animation {
+ Evas_Object *gridbox;
+ Evas_Object *item;
+
+ void (*update_cb)(Evas_Object *list, void *data, int is_prepend);
+ Evas_Object *container;
+ void *noti;
+ int pos;
+} gridbox_info_animation;
+
+static void _gridbox_layout_get_pos(int order, int *x, int *y, void *data) {
+ gridbox_info_layout *info_layout = data;
+
+ retif(data == NULL, , "invalid parameter");
+ retif(x == NULL, , "invalid parameter");
+ retif(y == NULL, , "invalid parameter");
+
+ int n_per_row = info_layout->n_per_rows;
+
+ int row = (order - 1) / n_per_row;
+ int column = (order - 1) - (row * n_per_row);
+
+ //DBG("order:%d r:%d c:%d", order, row, column);
+
+ int row_x = info_layout->padding_left
+ + ((info_layout->child_w + info_layout->padding_between) * column);
+
+ int row_y = info_layout->padding_top
+ + ((info_layout->child_h + info_layout->padding_between) * row);
+
+ *x = row_x;
+ *y = row_y;
+}
+
+static void _gridbox_layout(Evas_Object *o, Evas_Object_Box_Data *priv,
+ void *data) {
+ int n_children;
+ int x, y, w, h;
+ int off_x = 0, off_y = 0;
+ Eina_List *l;
+ Eina_List *l_next;
+ Evas_Object_Box_Option *opt;
+ int child_w, child_h;
+
+ retif(o == NULL, , "invalid parameter");
+ retif(priv == NULL, , "invalid parameter");
+ retif(data == NULL, , "invalid parameter");
+
+ gridbox_info_layout *info_layout = (gridbox_info_layout *) data;
+
+ n_children = eina_list_count(priv->children);
+ DBG("layout function:%d", n_children);
+ DBG("ref count:%p(%d)",o, evas_object_ref_get(o));
+ if (!n_children) {
+ return;
+ }
+
+ //box geometry
+ evas_object_geometry_get(o, &x, &y, &w, &h);
+
+ //set info about children
+ opt = eina_list_data_get(priv->children);
+ evas_object_size_hint_min_get(opt->obj, &child_w, &child_h);
+
+ info_layout->child_w = child_w;
+ info_layout->child_h = child_h;
+
+ DBG("grid layout children:%d %d", child_w, child_h);
+
+ int order_children = 1;
+ EINA_LIST_FOREACH_SAFE(priv->children, l, l_next, opt)
+ {
+ _gridbox_layout_get_pos(order_children, &off_x, &off_y, info_layout);
+ evas_object_move(opt->obj, x + off_x, y + off_y);
+ evas_object_resize(opt->obj, info_layout->child_w,
+ info_layout->child_h);
+ order_children++;
+ }
+
+ evas_object_size_hint_min_set(o, -1,
+ off_y + info_layout->child_h + info_layout->padding_bottom);
+}
+
+Evas_Object *gridbox_create(Evas_Object *parent, void *data) {
+
+ retif(parent == NULL, NULL, "invalid parameter");
+ retif(data == NULL, NULL, "invalid parameter");
+ struct appdata *ad = data;
+ Evas_Object *gridbox = NULL;
+
+ gridbox_info_layout *info_layout_portrait = NULL;
+ gridbox_info_layout *info_layout_landscape = NULL;
+
+ info_layout_portrait = (gridbox_info_layout *) malloc(
+ sizeof(gridbox_info_layout));
+ retif(info_layout_portrait == NULL, NULL, "memory allocation failed");
+ info_layout_portrait->padding_between = 12 * ad->scale;
+ info_layout_portrait->padding_top = 0;
+ info_layout_portrait->padding_left = 14 * ad->scale;
+ info_layout_portrait->padding_bottom = 12 * ad->scale;
+ info_layout_portrait->n_per_rows = 2;
+ info_layout_portrait->child_w = 0; //340;
+ info_layout_portrait->child_h = 0; //400;
+ info_layout_portrait->scale = ad->scale;
+
+ info_layout_landscape = (gridbox_info_layout *) malloc(
+ sizeof(gridbox_info_layout));
+ retif(info_layout_landscape == NULL, NULL, "memory allocation failed");
+ info_layout_landscape->padding_between = 12 * ad->scale;
+ info_layout_landscape->padding_top = 0;
+ info_layout_landscape->padding_left = 14 * ad->scale;
+ info_layout_landscape->padding_bottom = 12 * ad->scale;
+ info_layout_landscape->n_per_rows = 3;
+ info_layout_landscape->child_w = 0; //409;
+ info_layout_landscape->child_h = 0; //400;
+ info_layout_landscape->scale = ad->scale;
+
+ gridbox = elm_box_add(parent);
+ evas_object_size_hint_weight_set(gridbox, EVAS_HINT_EXPAND,
+ EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(gridbox, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+ if (ad->angle == 270 || ad->angle == 90)
+ elm_box_layout_set(gridbox, _gridbox_layout, info_layout_landscape,
+ NULL);
+ else
+ elm_box_layout_set(gridbox, _gridbox_layout, info_layout_portrait,
+ NULL);
+
+ evas_object_ref(gridbox);
+ evas_object_show(gridbox);
+
+ evas_object_data_set(gridbox, E_DATA_LAYOUT_PORTRAIT, info_layout_portrait);
+ evas_object_data_set(gridbox, E_DATA_LAYOUT_LANDSCAPE,
+ info_layout_landscape);
+ evas_object_data_set(gridbox, E_DATA_CB_DELETE_ITEM, NULL);
+ evas_object_data_set(gridbox, E_DATA_APP_DATA, ad);
+
+ return gridbox;
+}
+
+void gridbox_remove(Evas_Object *gridbox) {
+
+ retif(gridbox == NULL, , "invalid parameter");
+
+ gridbox_info_layout *info_layout_portrait = evas_object_data_get(gridbox,
+ E_DATA_LAYOUT_PORTRAIT);
+ gridbox_info_layout *info_layout_landscape = evas_object_data_get(gridbox,
+ E_DATA_LAYOUT_LANDSCAPE);
+
+ gridbox_remove_all_item(gridbox, 0);
+ evas_object_data_del(gridbox, E_DATA_LAYOUT_PORTRAIT);
+ evas_object_data_del(gridbox, E_DATA_LAYOUT_LANDSCAPE);
+ evas_object_data_del(gridbox, E_DATA_CB_DELETE_ITEM);
+ evas_object_data_del(gridbox, E_DATA_APP_DATA);
+ evas_object_unref(gridbox);
+ evas_object_del(gridbox);
+
+ if (info_layout_portrait != NULL)
+ free(info_layout_portrait);
+ if (info_layout_landscape != NULL)
+ free(info_layout_landscape);
+}
+
+void gridbox_set_item_deleted_cb(Evas_Object *gridbox,
+ void(*deleted_cb)(void *data, Evas_Object *obj)) {
+ retif(gridbox == NULL, , "invalid parameter");
+ retif(deleted_cb == NULL, , "invalid parameter");
+
+ evas_object_data_set(gridbox, E_DATA_CB_DELETE_ITEM, deleted_cb);
+}
+
+static void _gridbox_call_item_deleted_cb(Evas_Object *gridbox, void *data,
+ Evas_Object *obj) {
+ retif(gridbox == NULL, , "invalid parameter");
+
+ void (*deleted_cb)(void *data, Evas_Object *obj) = NULL;
+
+ deleted_cb = evas_object_data_get(gridbox, E_DATA_CB_DELETE_ITEM);
+
+ if (deleted_cb != NULL) {
+ deleted_cb(data, obj);
+ }
+}
+
+void gridbox_add_item(Evas_Object *gridbox, Evas_Object *item, int is_prepend) {
+ const char *signal = NULL;
+
+ retif(gridbox == NULL, , "invalid parameter");
+ retif(item == NULL, , "invalid parameter");
+
+ struct appdata *ad = evas_object_data_get(gridbox, E_DATA_APP_DATA);
+
+ if (ad != NULL) {
+ if (ad->angle == 270 || ad->angle == 90) {
+ signal = "box.landscape";
+ } else {
+ signal = "box.portrait";
+ }
+ }
+
+ DBG("set to %s, %x", signal, item);
+
+ elm_object_signal_emit(item, signal, "box.prog");
+ edje_object_message_signal_process(_EDJ(item));
+ elm_layout_sizing_eval(item);
+
+ if (is_prepend == GRIDBOX_PREPEND)
+ elm_box_pack_start(gridbox, item);
+ else
+ elm_box_pack_end(gridbox, item);
+}
+
+static void _gridbox_remove_item_anim_cb(void *data, Elm_Transit *transit) {
+ DBG("");
+ retif(data == NULL, , "invalid parameter");
+ retif(transit == NULL, , "invalid parameter");
+
+ gridbox_info_animation *info_animation = data;
+
+ retif(info_animation->gridbox == NULL, , "invalid parameter");
+ retif(info_animation->item == NULL, , "invalid parameter");
+
+ DBG("remove:%p", info_animation->item);
+
+ elm_box_unpack(info_animation->gridbox, info_animation->item);
+
+ _gridbox_call_item_deleted_cb(info_animation->gridbox,
+ noti_box_node_get(info_animation->item), info_animation->item);
+ noti_box_remove(info_animation->item);
+
+ if (info_animation->update_cb != NULL) {
+ retif(info_animation->container == NULL, , "invalid parameter");
+ retif(info_animation->noti == NULL, , "invalid parameter");
+
+ info_animation->update_cb(info_animation->container,
+ info_animation->noti, info_animation->pos);
+ }
+
+ free(info_animation);
+ info_animation = NULL;
+}
+
+void gridbox_remove_item(Evas_Object *gridbox, Evas_Object *item, int with_animation) {
+ DBG("remove:%p", item);
+ retif(gridbox == NULL, , "invalid parameter");
+ retif(item == NULL, , "invalid parameter");
+
+ if (noti_box_get_status(item) == STATE_DELETING) {
+ return ;
+ }
+ noti_box_set_status(item, STATE_DELETING);
+
+ if (with_animation == 1) {
+ gridbox_info_animation *info_animation = (gridbox_info_animation *) malloc(
+ sizeof(gridbox_info_animation));
+ if (info_animation == NULL)
+ return;
+ info_animation->gridbox = gridbox;
+ info_animation->item = item;
+ info_animation->update_cb = NULL;
+ info_animation->container = NULL;
+ info_animation->noti = NULL;
+ info_animation->pos = 0;
+
+ Elm_Transit *transit = elm_transit_add();
+ //Fade in and out with layout object.
+ elm_transit_object_add(transit, item);
+ elm_transit_effect_fade_add(transit);
+ elm_transit_duration_set(transit, 0.7);
+ elm_transit_del_cb_set(transit, _gridbox_remove_item_anim_cb,
+ info_animation);
+ elm_transit_go(transit);
+ } else {
+ _gridbox_call_item_deleted_cb(gridbox,
+ noti_box_node_get(item), item);
+ elm_box_unpack(gridbox, item);
+ noti_box_remove(item);
+ }
+}
+
+void gridbox_remove_all_item(Evas_Object *gridbox, int with_animation) {
+ DBG("");
+ retif(gridbox == NULL, , "invalid parameter");
+
+ Eina_List *l;
+ Eina_List *l_next;
+ Evas_Object *obj;
+ Eina_List *item_list = elm_box_children_get(gridbox);
+
+ EINA_LIST_FOREACH_SAFE(item_list, l, l_next, obj)
+ {
+ if (obj != NULL) {
+ // call deleted callback
+ gridbox_remove_item(gridbox, obj, with_animation);
+ }
+ }
+}
+
+void gridbox_update_item(Evas_Object *gridbox, Evas_Object *item) {
+
+ retif(gridbox == NULL, , "invalid parameter");
+ retif(item == NULL, , "invalid parameter");
+}
+
+void gridbox_remove_and_add_item(Evas_Object *gridbox, Evas_Object *item
+ ,void (*update_cb)(Evas_Object *list, void *data, int is_prepend)
+ ,void *container, void *data, int pos) {
+
+ retif(gridbox == NULL, , "invalid parameter");
+ retif(item == NULL, , "invalid parameter");
+ retif(update_cb == NULL, , "invalid parameter");
+ retif(container == NULL, , "invalid parameter");
+ retif(data == NULL, , "invalid parameter");
+
+ if (noti_box_get_status(item) == STATE_DELETING) {
+ return ;
+ }
+ noti_box_set_status(item, STATE_DELETING);
+
+ gridbox_info_animation *info_animation = (gridbox_info_animation *) malloc(
+ sizeof(gridbox_info_animation));
+ if (info_animation == NULL)
+ return;
+ info_animation->gridbox = gridbox;
+ info_animation->item = item;
+ info_animation->update_cb = update_cb;
+ info_animation->container = container;
+ info_animation->noti = data;
+ info_animation->pos = pos;
+
+ Elm_Transit *transit = elm_transit_add();
+ //Fade in and out with layout object.
+ elm_transit_object_add(transit, item);
+ elm_transit_effect_fade_add(transit);
+ elm_transit_duration_set(transit, 0.4);
+ elm_transit_del_cb_set(transit, _gridbox_remove_item_anim_cb,
+ info_animation);
+ elm_transit_go(transit);
+}
+
+void gridbox_finalize_rotation_cb(void *data) {
+ retif(data == NULL, , "invalid parameter");
+ Evas_Object *gridbox = data;
+
+ elm_box_recalculate(gridbox);
+}
+
+void gridbox_rotation(Evas_Object *gridbox, int angle) {
+ const char *signal = NULL;
+
+ retif(gridbox == NULL, , "invalid parameter");
+
+ gridbox_info_layout *info_layout_portrait = evas_object_data_get(gridbox,
+ E_DATA_LAYOUT_PORTRAIT);
+ gridbox_info_layout *info_layout_landscape = evas_object_data_get(gridbox,
+ E_DATA_LAYOUT_LANDSCAPE);
+
+ retif(info_layout_portrait == NULL || info_layout_landscape == NULL, ,
+ "gridbox is crashed");
+
+ Eina_List *l;
+ Eina_List *l_next;
+ Evas_Object *obj;
+ Eina_List *item_list = elm_box_children_get(gridbox);
+
+ if (angle == 270 || angle == 90) {
+ signal = "box.landscape";
+ } else {
+ signal = "box.portrait";
+ }
+
+ DBG("all count:%d", eina_list_count (item_list));
+
+ EINA_LIST_FOREACH_SAFE(item_list, l, l_next, obj)
+ {
+ if (obj != NULL) {
+ elm_object_signal_emit(obj, signal, "box.prog");
+ edje_object_message_signal_process(_EDJ(obj));
+ elm_layout_sizing_eval(obj);
+ DBG("set to %s, %x", signal, obj);
+ }
+ }
+
+ if (angle == 270 || angle == 90) {
+ elm_box_layout_set(gridbox, _gridbox_layout, info_layout_landscape,
+ NULL);
+
+#if 0
+ layout_data = elm_box_transition_new(0.0, _gridbox_layout,
+ info_layout_portrait, NULL, _gridbox_layout,
+ info_layout_landscape, NULL, gridbox_finalize_rotation_cb,
+ gridbox);
+#endif
+ } else {
+ elm_box_layout_set(gridbox, _gridbox_layout, info_layout_portrait,
+ NULL);
+#if 0
+ layout_data = elm_box_transition_new(0.0, _gridbox_layout,
+ info_layout_landscape, NULL, _gridbox_layout,
+ info_layout_portrait, NULL, gridbox_finalize_rotation_cb,
+ gridbox);
+#endif
+ }
+
+#if 0
+ elm_box_layout_set(gridbox, elm_box_layout_transition, layout_data,
+ elm_box_transition_free);
+#endif
+ DBG("Angle Rotation is %d", angle);
+}
diff --git a/daemon/notifications/noti_gridbox.h b/daemon/notifications/noti_gridbox.h
new file mode 100755
index 0000000..03b2eb4
--- /dev/null
+++ b/daemon/notifications/noti_gridbox.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __QUICKPANEL_GRIDBOX_H__
+#define __QUICKPANEL_GRIDBOX_H__
+
+#define GRIDBOX_PREPEND 1
+#define GRIDBOX_APPEND 0
+
+Evas_Object *gridbox_create(Evas_Object *parent, void *data);
+void gridbox_remove(Evas_Object *gridbox);
+void gridbox_add_item(Evas_Object *gridbox, Evas_Object *item, int is_prepend);
+void gridbox_remove_item(Evas_Object *gridbox, Evas_Object *item, int with_animation);
+void gridbox_rotation(Evas_Object *gridbox, int angle);
+void gridbox_remove_and_add_item(Evas_Object *gridbox, Evas_Object *item
+ ,void (*update_cb)(Evas_Object *list, void *data, int is_prepend)
+ ,void *container, void *data, int pos);
+void gridbox_remove_all_item(Evas_Object *gridbox, int with_animation);
+void gridbox_set_item_deleted_cb(Evas_Object *gridbox,
+ void(*deleted_cb)(void *data, Evas_Object *obj));
+#endif
diff --git a/daemon/notifications/noti_node.c b/daemon/notifications/noti_node.c
new file mode 100755
index 0000000..440af1b
--- /dev/null
+++ b/daemon/notifications/noti_node.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "quickpanel-ui.h"
+#include "common.h"
+#include "list_util.h"
+#include "noti_node.h"
+
+static void _noti_node_free(noti_node_item *node);
+
+void noti_node_create(noti_node **handle)
+{
+ retif(handle == NULL, , "Invalid parameter!");
+
+ *handle = (noti_node *)malloc(sizeof(noti_node));
+
+ if (*handle != NULL) {
+ (*handle)->table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL,
+ (GDestroyNotify)_noti_node_free);
+
+ (*handle)->n_ongoing = 0;
+ (*handle)->n_noti = 0;
+ } else {
+ *handle = NULL;
+ }
+}
+
+void noti_node_destroy(noti_node **handle)
+{
+ retif(handle == NULL, , "Invalid parameter!");
+ retif(*handle == NULL, , "Invalid parameter!");
+
+ g_hash_table_remove_all((*handle)->table);
+ g_hash_table_destroy((*handle)->table);
+ (*handle)->table = NULL;
+
+ free((*handle));
+ *handle = NULL;
+}
+
+noti_node_item *noti_node_add(noti_node *handle, notification_h noti, void *view)
+{
+ int priv_id = 0;
+ notification_type_e noti_type = NOTIFICATION_TYPE_NONE;
+ noti_node_item *node = NULL;
+
+ retif(handle == NULL || noti == NULL, NULL, "Invalid parameter!");
+
+ if (notification_get_id(noti, NULL, &priv_id) == NOTIFICATION_ERROR_NONE) {
+ node = malloc(sizeof(noti_node_item));
+ if (!node) {
+ ERR("fail to alloc item");
+ return NULL;
+ }
+
+ node->noti = noti;
+ node->view = view;
+
+ g_hash_table_insert(handle->table, GINT_TO_POINTER(priv_id), (gpointer *)node);
+
+ notification_get_type(noti, &noti_type);
+
+ if (noti_type == NOTIFICATION_TYPE_NOTI)
+ handle->n_noti++;
+ else if (noti_type == NOTIFICATION_TYPE_ONGOING)
+ handle->n_ongoing++;
+
+ return node;
+ }
+
+ return NULL;
+}
+
+void noti_node_remove(noti_node *handle, int priv_id)
+{
+ notification_type_e noti_type = NOTIFICATION_TYPE_NONE;
+
+ retif(handle == NULL, , "Invalid parameter!");
+ retif(handle->table == NULL, , "Invalid parameter!");
+
+ noti_node_item *item = noti_node_get(handle, priv_id);
+
+ if (item != NULL) {
+ if (item->noti != NULL) {
+ notification_get_type(item->noti, &noti_type);
+
+ if (noti_type == NOTIFICATION_TYPE_NOTI)
+ handle->n_noti--;
+ else if (noti_type == NOTIFICATION_TYPE_ONGOING)
+ handle->n_ongoing--;
+ }
+
+ notification_free(item->noti);
+ item->noti = NULL;
+ item->view = NULL;
+
+ if (g_hash_table_remove(handle->table, GINT_TO_POINTER(priv_id)))
+ {
+ INFO("success to remove %d", priv_id);
+ }
+ }
+}
+
+noti_node_item *noti_node_get(noti_node *handle, int priv_id)
+{
+ retif(handle == NULL, NULL, "Invalid parameter!");
+ retif(handle->table == NULL, NULL, "Invalid parameter!");
+
+ return (noti_node_item *)g_hash_table_lookup
+ (handle->table, GINT_TO_POINTER(priv_id));
+}
+
+int noti_node_get_item_count(noti_node *handle, notification_type_e noti_type)
+{
+ retif(handle == NULL, 0, "Invalid parameter!");
+
+ if (noti_type == NOTIFICATION_TYPE_NOTI)
+ return handle->n_noti;
+ else if (noti_type == NOTIFICATION_TYPE_ONGOING)
+ return handle->n_ongoing;
+
+ return 0;
+}
+
+static void _noti_node_free(noti_node_item *node)
+{
+ retif(node == NULL, , "Invalid parameter!");
+
+ DBG("item_node is freed:%p", node);
+
+ free(node);
+}
diff --git a/daemon/notifications/noti_node.h b/daemon/notifications/noti_node.h
new file mode 100755
index 0000000..00debbc
--- /dev/null
+++ b/daemon/notifications/noti_node.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __QUICKPANEL_NOTI_NODE_H__
+#define __QUICKPANEL_NOTI_NODE_H__
+
+#include <glib.h>
+#include <notification.h>
+
+typedef struct _noti_node {
+ GHashTable *table;
+ int n_ongoing;
+ int n_noti;
+} noti_node;
+
+typedef struct _noti_node_item {
+ notification_h noti;
+ void *view;
+} noti_node_item;
+
+void noti_node_create(noti_node **handle);
+void noti_node_destroy(noti_node **handle);
+noti_node_item *noti_node_add(noti_node *handle, notification_h noti, void *view);
+void noti_node_remove(noti_node *handle, int priv_id);
+noti_node_item *noti_node_get(noti_node *handle, int priv_id);
+int noti_node_get_item_count(noti_node *handle, notification_type_e noti_type);
+
+#endif
diff --git a/daemon/notifications/noti_win.c b/daemon/notifications/noti_win.c
new file mode 100755
index 0000000..fa8330f
--- /dev/null
+++ b/daemon/notifications/noti_win.c
@@ -0,0 +1,314 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <Elementary.h>
+#include <utilX.h>
+
+#define NOTI_HEIGHT 50
+#ifndef __UNUSED__
+#define __UNUSED__ __attribute__((unused))
+#endif
+/* Using this macro to emphasize that some portion like stacking and
+rotation handling are implemented for X based platform
+*/
+
+#ifdef HAVE_X
+#include <Ecore_X.h>
+#endif
+#include "common.h"
+#include "noti_win.h"
+
+struct Internal_Data {
+ Evas_Object *content;
+ Ecore_Event_Handler *rotation_event_handler;
+ Evas_Coord w;
+ Evas_Coord h;
+ int angle;
+ enum Noti_Orient orient;
+};
+
+static const char *data_key = "_data";
+
+static void _set_win_type_notification_level(Evas_Object *win)
+{
+ retif(win == NULL, , "invalid parameter");
+
+ Ecore_X_Window w = elm_win_xwindow_get(win);
+
+ if (w > 0) {
+ ecore_x_icccm_hints_set(w, 0, ECORE_X_WINDOW_STATE_HINT_NONE, 0, 0,
+ 0, 0, 0);
+ ecore_x_netwm_opacity_set(w, 0);
+
+ ecore_x_netwm_window_type_set(w,
+ ECORE_X_WINDOW_TYPE_NOTIFICATION);
+ utilx_set_system_notification_level(ecore_x_display_get(), w,
+ UTILX_NOTIFICATION_LEVEL_HIGH);
+ }
+}
+
+static void _show(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
+ void *event_info __UNUSED__)
+{
+ struct Internal_Data *wd = evas_object_data_get(obj, data_key);
+
+ if (!wd)
+ return;
+ if (wd->content)
+ evas_object_show(wd->content);
+}
+
+static void _content_hide(void *data, Evas *e __UNUSED__,
+ Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ evas_object_hide(data);
+}
+
+static void _content_changed_size_hints(void *data, Evas *e __UNUSED__,
+ Evas_Object *obj, void *event_info __UNUSED__)
+{
+ Evas_Coord h;
+ struct Internal_Data *wd = evas_object_data_get(data, data_key);
+
+ if (!wd)
+ return;
+
+ evas_object_size_hint_min_get(obj, NULL, &h);
+ if ((h > 0)) {
+ wd->h = h;
+ evas_object_size_hint_min_set(obj, wd->w, wd->h);
+ evas_object_size_hint_min_set(data, wd->w, wd->h);
+ evas_object_resize(data, wd->w, wd->h);
+ }
+}
+
+static void _sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
+{
+ struct Internal_Data *wd = evas_object_data_get(obj, data_key);
+ Evas_Object *sub = event_info;
+
+ if (!wd)
+ return;
+ if (sub == wd->content) {
+ evas_object_event_callback_del(wd->content, EVAS_CALLBACK_HIDE,
+ _content_hide);
+ evas_object_event_callback_del(wd->content,
+ EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+ _content_changed_size_hints);
+ wd->content = NULL;
+ }
+}
+
+static void _del(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
+ void *event_info __UNUSED__)
+{
+ struct Internal_Data *wd = evas_object_data_get(obj, data_key);
+
+ if (!wd)
+ return;
+ if (wd->rotation_event_handler)
+ ecore_event_handler_del(wd->rotation_event_handler);
+ evas_object_data_set(data, data_key, NULL);
+ free(wd);
+}
+
+#ifdef HAVE_X
+static void _update_geometry_on_rotation(Evas_Object *obj, int angle,
+ int *x, int *y, int *w)
+{
+ Evas_Coord root_w, root_h;
+ struct Internal_Data *wd = evas_object_data_get(obj, data_key);
+
+ if (!wd)
+ return;
+
+ ecore_x_window_size_get(ecore_x_window_root_first_get(), &root_w,
+ &root_h);
+
+ /* rotate window */
+ switch (angle) {
+ case 90:
+ *w = root_h;
+ if (wd->orient == NOTI_ORIENT_BOTTOM)
+ *x = root_w - wd->h;
+ break;
+ case 270:
+ *w = root_h;
+ if (!(wd->orient == NOTI_ORIENT_BOTTOM))
+ *x = root_w - wd->h;
+ break;
+ case 180:
+ *w = root_w;
+ if (!wd->orient == NOTI_ORIENT_BOTTOM)
+ *y = root_h - wd->h;
+ break;
+ case 0:
+ default:
+ *w = root_w;
+ if (wd->orient == NOTI_ORIENT_BOTTOM)
+ *y = root_h - wd->h;
+ break;
+ }
+}
+
+static void _win_rotated(Evas_Object *obj)
+{
+ int x = 0;
+ int y = 0;
+ int w = 0;
+ int angle = 0;
+ struct Internal_Data *wd = evas_object_data_get(obj, data_key);
+
+ if (!wd)
+ return;
+ angle = elm_win_rotation_get(obj);
+ if (angle % 90)
+ return;
+ angle %= 360;
+ if (angle < 0)
+ angle += 360;
+ wd->angle = angle;
+
+ _update_geometry_on_rotation(obj, wd->angle, &x, &y, &w);
+
+ evas_object_move(obj, x, y);
+ wd->w = w;
+ evas_object_resize(obj, wd->w, wd->h);
+}
+
+static Eina_Bool _prop_change(void *data, int type __UNUSED__, void *event)
+{
+ Ecore_X_Event_Window_Property *ev;
+ struct Internal_Data *wd = evas_object_data_get(data, data_key);
+
+ if (!wd)
+ return ECORE_CALLBACK_PASS_ON;
+ ev = event;
+ if (ev->atom == ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE)
+ if (ev->win == elm_win_xwindow_get(data))
+ _win_rotated(data);
+ return ECORE_CALLBACK_PASS_ON;
+}
+#endif
+
+Evas_Object *noti_win_add(Evas_Object *parent)
+{
+ Evas_Object *win;
+ Evas_Object *bg;
+ struct Internal_Data *wd;
+ Evas_Coord w = 0;
+
+ win = elm_win_add(parent, "noti_win", ELM_WIN_NOTIFICATION);
+ elm_win_alpha_set(win, EINA_TRUE);
+
+ if (!win)
+ return NULL;
+ elm_win_title_set(win, "noti_win");
+ elm_win_borderless_set(win, EINA_TRUE);
+ elm_win_autodel_set(win, EINA_TRUE);
+ evas_object_size_hint_weight_set(win, EVAS_HINT_EXPAND,
+ EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(win, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ bg = elm_bg_add(win);
+ evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND,
+ EVAS_HINT_EXPAND);
+ elm_win_resize_object_add(win, bg);
+ evas_object_show(bg);
+
+ _set_win_type_notification_level(win);
+
+ wd = (struct Internal_Data *) calloc(1, sizeof(struct Internal_Data));
+ if (!wd)
+ return NULL;
+ evas_object_data_set(win, data_key, wd);
+ wd->angle = 0;
+ wd->orient = NOTI_ORIENT_TOP;
+ evas_object_move(win, 0, 0);
+#ifdef HAVE_X
+ ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, NULL);
+ evas_object_resize(win, w, NOTI_HEIGHT);
+ wd->rotation_event_handler = ecore_event_handler_add(
+ ECORE_X_EVENT_WINDOW_PROPERTY, _prop_change, win);
+#endif
+ wd->w = w;
+ wd->h = NOTI_HEIGHT;
+ evas_object_smart_callback_add(win, "sub-object-del", _sub_del, NULL);
+ evas_object_event_callback_add(win, EVAS_CALLBACK_SHOW, _show, NULL);
+ evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _del, NULL);
+ return win;
+}
+
+void noti_win_content_set(Evas_Object *obj, Evas_Object *content)
+{
+ Evas_Coord h;
+ struct Internal_Data *wd;
+
+ if (!obj)
+ return;
+ wd = evas_object_data_get(obj, data_key);
+ if (!wd)
+ return;
+ if (wd->content)
+ evas_object_del(content);
+ wd->content = content;
+ if (content) {
+ evas_object_size_hint_weight_set(wd->content, EVAS_HINT_EXPAND,
+ EVAS_HINT_EXPAND);
+ elm_win_resize_object_add(obj, wd->content);
+ evas_object_size_hint_min_get(wd->content, NULL, &h);
+ if (h)
+ wd->h = h;
+ evas_object_size_hint_min_set(wd->content, wd->w, wd->h);
+ evas_object_resize(obj, wd->w, wd->h);
+ evas_object_event_callback_add(wd->content, EVAS_CALLBACK_HIDE,
+ _content_hide, obj);
+ evas_object_event_callback_add(wd->content,
+ EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+ _content_changed_size_hints, obj);
+ }
+}
+
+void noti_win_orient_set(Evas_Object *obj, enum Noti_Orient orient)
+{
+#ifdef HAVE_X
+ Evas_Coord root_w, root_h;
+#endif
+ struct Internal_Data *wd = evas_object_data_get(obj, data_key);
+
+ if (!wd)
+ return;
+ if (orient >= NOTI_ORIENT_LAST)
+ return;
+#ifdef HAVE_X
+ ecore_x_window_size_get(ecore_x_window_root_first_get(), &root_w,
+ &root_h);
+#endif
+ switch (orient) {
+ case NOTI_ORIENT_BOTTOM:
+#ifdef HAVE_X
+ evas_object_move(obj, 0, root_h - wd->h);
+#endif
+ wd->orient = NOTI_ORIENT_BOTTOM;
+ break;
+ case NOTI_ORIENT_TOP:
+ default:
+#ifdef HAVE_X
+ evas_object_move(obj, 0, 0);
+#endif
+ wd->orient = NOTI_ORIENT_TOP;
+ break;
+ }
+}
diff --git a/daemon/notifications/noti_win.h b/daemon/notifications/noti_win.h
new file mode 100755
index 0000000..951ac06
--- /dev/null
+++ b/daemon/notifications/noti_win.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __NOTI_WIN_H__
+#define __NOTI_WIN_H__
+#include <Evas.h>
+
+enum Noti_Orient {
+ NOTI_ORIENT_TOP = 0,
+ NOTI_ORIENT_BOTTOM,
+ NOTI_ORIENT_LAST
+ } ;
+
+/* Creates and return a new window (of widget type elm_win) of width equal to
+root window
+*/
+Evas_Object *noti_win_add(Evas_Object *parent);
+
+/* Sets an Evas Object as content of the notification window created using
+noti_win_add
+*/
+void noti_win_content_set(Evas_Object *obj, Evas_Object *content);
+
+/* Sets the orientation of the notification window, this can be of type
+Noti_Orient
+*/
+void noti_win_orient_set(Evas_Object *obj, enum Noti_Orient orient);
+#endif
diff --git a/daemon/notifications/status_msg.c b/daemon/notifications/status_msg.c
new file mode 100755
index 0000000..898d7e4
--- /dev/null
+++ b/daemon/notifications/status_msg.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <Elementary.h>
+#include <Ecore_X.h>
+#include <vconf.h>
+#include <notification.h>
+
+#include "quickpanel-ui.h"
+#include "common.h"
+#include "noti_win.h"
+
+#define QP_STATUS_DURATION 3
+#define QP_STATUS_DETAIL_DURATION 6
+
+#define STATUS_MSG_LEN 1024
+#define DEFAULT_ICON ICONDIR "/quickpanel_icon_default.png"
+
+#define E_DATA_STATUS_DETAIL "detail"
+
+static Evas_Object *g_status_win;
+static Ecore_Timer *g_status_timer;
+static int g_noti_height;
+
+static int quickpanel_status_init(void *data);
+static int quickpanel_status_fini(void *data);
+static void quickpanel_status_reflesh(void *data);
+
+QP_Module ticker_status = {
+ .name = "ticker_status",
+ .init = quickpanel_status_init,
+ .fini = quickpanel_status_fini,
+ .hib_enter = NULL,
+ .hib_leave = NULL,
+ .lang_changed = NULL,
+ .refresh = quickpanel_status_reflesh
+};
+
+/*****************************************************************************
+ *
+ * (Static) Util functions
+ *
+ *****************************************************************************/
+static void _quickpanel_status_hide(void *data)
+{
+ if (g_status_win) {
+ evas_object_hide(g_status_win);
+ evas_object_del(g_status_win);
+ g_status_win = NULL;
+ }
+}
+
+static void _quickpanel_status_set_text(Evas_Object *detail, const char *message) {
+ retif(detail == NULL, , "Invalid parameter!");
+ retif(message == NULL, , "Invalid parameter!");
+
+ elm_object_part_text_set(detail, "elm.text", message);
+}
+
+static Eina_Bool _quickpanel_status_timeout_cb(void *data)
+{
+ DBG("");
+
+ g_status_timer = NULL;
+
+ _quickpanel_status_hide(data);
+
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static void _quickpanel_status_detail_hide_cb(void *data, Evas *e,
+ Evas_Object *obj,
+ void *event_info)
+{
+ if (g_status_timer) {
+ ecore_timer_del(g_status_timer);
+ g_status_timer = NULL;
+ }
+}
+
+static void _quickpanel_status_detail_show_cb(void *data, Evas *e,
+ Evas_Object *obj,
+ void *event_info)
+{
+ DBG("");
+}
+
+static void _quickpanel_status_clicked_cb(void *data, Evas_Object *obj,
+ void *event_info)
+{
+ _quickpanel_status_hide(data);
+}
+
+static void _noti_hide_cb(void *data, Evas_Object *obj,
+ const char *emission, const char *source)
+{
+ DBG("");
+
+ if (g_status_timer) {
+ ecore_timer_del(g_status_timer);
+ g_status_timer = NULL;
+ }
+}
+
+static Evas_Object *_quickpanel_status_create_status_noti(const char *message, void *data)
+{
+ Evas_Object *status_noti = NULL;
+ Evas_Object *detail = NULL;
+ const char *data_win_height = NULL;
+ int noti_height = 0;
+
+ retif(message == NULL, NULL, "Invalid parameter!");
+
+ status_noti = noti_win_add(NULL);
+ retif(status_noti == NULL, NULL, "Failed to add elm status_noti.");
+
+ detail = elm_layout_add(status_noti);
+ if (!detail) {
+ ERR("Failed to get detailview.");
+ evas_object_del(status_noti);
+ return NULL;
+ }
+ elm_layout_theme_set(detail, "tickernoti", "base", "textonly");
+ elm_object_signal_callback_add(detail, "request,hide", "",
+ _noti_hide_cb, NULL);
+
+ data_win_height = (char *)elm_layout_data_get(detail, "height");
+ if (data_win_height != NULL && elm_config_scale_get() > 0.0)
+ noti_height = (int)(elm_config_scale_get()
+ * atoi(data_win_height));
+ evas_object_size_hint_min_set(detail, 1, noti_height);
+ g_noti_height = noti_height;
+ DBG("height:%d", g_noti_height);
+
+ noti_win_content_set(status_noti, detail);
+
+ _quickpanel_status_set_text(detail, message);
+ /* Use style "default" for detailview mode and
+ * "info" for text only mode
+ */
+ elm_object_style_set(status_noti, "textonly");
+ evas_object_data_set(status_noti, E_DATA_STATUS_DETAIL, detail);
+
+ return status_noti;
+}
+
+static int _quickpanel_status_get_angle(void *data)
+{
+ struct appdata *ad = (struct appdata *)data;
+ Ecore_X_Window xwin, root;
+ int ret = 0, angle = 0, count = 0;
+ unsigned char *prop_data = NULL;
+
+ xwin = elm_win_xwindow_get(ad->win);
+ root = ecore_x_window_root_get(xwin);
+
+ ret = ecore_x_window_prop_property_get(root,
+ ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE,
+ ECORE_X_ATOM_CARDINAL, 32,
+ &prop_data, &count);
+
+ if (ret && prop_data) {
+ memcpy(&angle, prop_data, sizeof(int));
+
+ if (prop_data)
+ free(prop_data);
+
+ return angle;
+ } else {
+ ERR("Fail to get angle");
+ if (prop_data)
+ free(prop_data);
+
+ return -1;
+ }
+}
+
+static void _quickpanel_status_update_geometry_on_rotation(void *data, int *x, int *y, int *w, int *h) {
+ int angle = 0;
+
+ if (!data)
+ return;
+
+ angle = _quickpanel_status_get_angle(data);
+ Evas_Coord root_w, root_h;
+
+ /*
+ * manually calculate win_status_noti_indi window position & size
+ * - win_indi is not full size window
+ */
+ ecore_x_window_size_get(ecore_x_window_root_first_get(), &root_w, &root_h);
+
+ // rotate win
+ switch(angle)
+ {
+ case 90:
+ *w = g_noti_height;
+ *h = root_h;
+ break;
+ case 270:
+ *w = g_noti_height;
+ *h = root_h;
+ *x = root_w - g_noti_height;
+ break;
+ case 180:
+ *w = root_w;
+ *h = g_noti_height;
+ *y = root_h - g_noti_height;
+ break;
+ case 0:
+ default:
+ *w = root_w;
+ *h = g_noti_height;
+ break;
+ }
+ elm_win_rotation_set(g_status_win, angle);
+}
+
+static void _quickpanel_status_win_rotated(void *data) {
+ retif(data == NULL, ,"data is NULL");
+
+ struct appdata *ad = data;
+ int x = 0, y = 0, w = 0, h = 0;
+
+ _quickpanel_status_update_geometry_on_rotation(ad, &x, &y, &w, &h);
+
+ if (g_status_win != NULL) {
+ evas_object_move(g_status_win, x, y);
+ evas_object_resize(g_status_win, w, h);
+ }
+}
+
+static void _quickpanel_status_cb(const char *message, void *data)
+{
+ DBG("");
+ retif(message == NULL, ,"message is NULL");
+ retif(data == NULL, ,"data is NULL");
+
+ if (g_status_timer)
+ ecore_timer_del(g_status_timer);
+
+ /* Skip if previous status is still shown */
+ if (g_status_win != NULL) {
+ Evas_Object *detail = evas_object_data_get(g_status_win, E_DATA_STATUS_DETAIL);
+ _quickpanel_status_set_text(detail, message);
+ elm_win_activate(g_status_win);
+ } else {
+ g_status_win = _quickpanel_status_create_status_noti(message, data);
+ if (g_status_win == NULL) {
+ ERR("Fail to create status_noti");
+ return;
+ }
+
+ _quickpanel_status_win_rotated(data);
+ evas_object_show(g_status_win);
+
+ evas_object_event_callback_add(g_status_win, EVAS_CALLBACK_SHOW,
+ _quickpanel_status_detail_show_cb,
+ g_status_win);
+ evas_object_event_callback_add(g_status_win, EVAS_CALLBACK_HIDE,
+ _quickpanel_status_detail_hide_cb,
+ g_status_win);
+ evas_object_smart_callback_add(g_status_win, "clicked",
+ _quickpanel_status_clicked_cb,
+ g_status_win);
+ }
+
+ g_status_timer = ecore_timer_add(QP_STATUS_DURATION,
+ _quickpanel_status_timeout_cb, NULL);
+}
+
+/*****************************************************************************
+ *
+ * Util functions
+ *
+ *****************************************************************************/
+static int quickpanel_status_init(void *data)
+{
+ int ret = QP_OK;
+
+ ret = notification_status_monitor_message_cb_set(_quickpanel_status_cb, data);
+
+ return ret;
+}
+
+static int quickpanel_status_fini(void *data)
+{
+ int ret = 0;
+ _quickpanel_status_hide(NULL);
+
+ ret = notification_status_monitor_message_cb_unset();
+
+ return ret;
+}
+
+static void quickpanel_status_reflesh(void *data)
+{
+ retif(data == NULL, , "Invalid parameter!");
+
+ if (g_status_win != NULL) {
+ _quickpanel_status_win_rotated(data);
+ }
+}
diff --git a/daemon/notifications/ticker.c b/daemon/notifications/ticker.c
new file mode 100755
index 0000000..60952df
--- /dev/null
+++ b/daemon/notifications/ticker.c
@@ -0,0 +1,726 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <Elementary.h>
+#include <Ecore_X.h>
+#include <appcore-common.h>
+#include <vconf.h>
+#include <appsvc.h>
+#include <app_service.h>
+#include <notification.h>
+#include <time.h>
+#include <feedback.h>
+
+#include "quickpanel-ui.h"
+#include "common.h"
+#include "noti_win.h"
+
+#define QP_TICKER_DURATION 5
+#define QP_TICKER_DETAIL_DURATION 6
+
+#define TICKER_MSG_LEN 1024
+#define DEFAULT_ICON ICONDIR "/quickpanel_icon_default.png"
+
+static Evas_Object *g_window;
+static Evas_Object *g_ticker;
+static Ecore_Timer *g_timer;
+static int g_noti_height;
+
+static int quickpanel_ticker_init(void *data);
+static int quickpanel_ticker_fini(void *data);
+static int quickpanel_ticker_enter_hib(void *data);
+static int quickpanel_ticker_leave_hib(void *data);
+static void quickpanel_ticker_reflesh(void *data);
+
+QP_Module ticker = {
+ .name = "ticker",
+ .init = quickpanel_ticker_init,
+ .fini = quickpanel_ticker_fini,
+ .hib_enter = quickpanel_ticker_enter_hib,
+ .hib_leave = quickpanel_ticker_leave_hib,
+ .lang_changed = NULL,
+ .refresh = quickpanel_ticker_reflesh
+};
+
+static int latest_inserted_time;
+
+/*****************************************************************************
+ *
+ * (Static) Util functions
+ *
+ *****************************************************************************/
+
+static int _quickpanel_ticker_check_ticker_off(notification_h noti)
+{
+ char *pkgname = NULL;
+ int ret = 0;
+ int boolval = 0;
+
+ notification_get_application(noti, &pkgname);
+
+ if (pkgname == NULL)
+ notification_get_pkgname(noti, &pkgname);
+
+ if (pkgname == NULL)
+ return 1; /* Ticker is not displaying. */
+
+ if (!strcmp(pkgname, VENDOR".message")) {
+ ret = vconf_get_bool(
+ VCONFKEY_SETAPPL_STATE_TICKER_NOTI_MESSAGES_BOOL,
+ &boolval);
+ if (ret == 0 && boolval == 0)
+ return 1;
+ } else if (!strcmp(pkgname, VENDOR".email")) {
+ ret = vconf_get_bool(
+ VCONFKEY_SETAPPL_STATE_TICKER_NOTI_EMAIL_BOOL,
+ &boolval);
+ if (ret == 0 && boolval == 0)
+ return 1;
+ } else if (!strcmp(pkgname, VENDOR".ims-syspopup")) {
+ ret = vconf_get_bool(
+ VCONFKEY_SETAPPL_STATE_TICKER_NOTI_IM_BOOL,
+ &boolval);
+ if (ret == 0 && boolval == 0)
+ return 1;
+ }
+
+ /* Displaying ticker! */
+ return 0;
+}
+
+static int _quickpanel_ticker_check_displaying_contents_off(notification_h noti)
+{
+ char *pkgname = NULL;
+ int ret = 0;
+ int boolval = 0;
+
+ notification_get_application(noti, &pkgname);
+
+ if (pkgname == NULL)
+ notification_get_pkgname(noti, &pkgname);
+
+ if (pkgname == NULL)
+ return 0; /* Ticker is not displaying. */
+
+ if (!strcmp(pkgname, VENDOR".message")) {
+ ret = vconf_get_bool(
+ VCONFKEY_TICKER_NOTI_DISPLAY_CONTENT_MESSASGES,
+ &boolval);
+ if (ret == 0 && boolval == 0)
+ return 1;
+ } else if (!strcmp(pkgname, VENDOR".email")) {
+ ret = vconf_get_bool(
+ VCONFKEY_TICKER_NOTI_DISPLAY_CONTENT_EMAIL,
+ &boolval);
+ if (ret == 0 && boolval == 0)
+ return 1;
+ } else if (!strcmp(pkgname, VENDOR".ims-syspopup")) {
+ ret = vconf_get_bool(
+ VCONFKEY_TICKER_NOTI_DISPLAY_CONTENT_IM,
+ &boolval);
+ if (ret == 0 && boolval == 0)
+ return 1;
+ }
+
+ /* Displaying ticker! */
+ return 0;
+}
+
+static inline void __ticker_only_noti_del(notification_h noti)
+{
+ int applist = NOTIFICATION_DISPLAY_APP_ALL;
+
+ retif(noti == NULL, ,"noti is null");
+
+ notification_get_display_applist(noti, &applist);
+ if (applist & NOTIFICATION_DISPLAY_APP_TICKER) {
+ if (!(applist & NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY)) {
+ char *pkgname = NULL;
+ int priv_id = 0;
+
+ notification_get_pkgname(noti, &pkgname);
+ notification_get_id(noti, NULL, &priv_id);
+ notification_delete_by_priv_id(pkgname,
+ NOTIFICATION_TYPE_NONE,
+ priv_id);
+ }
+ }
+}
+
+static void _quickpanel_ticker_hide(void *data)
+{
+ if (g_ticker) {
+ evas_object_hide(g_ticker);
+ evas_object_del(g_ticker);
+ g_ticker = NULL;
+ }
+}
+
+static Eina_Bool _quickpanel_ticker_timeout_cb(void *data)
+{
+ DBG("");
+
+ g_timer = NULL;
+
+ _quickpanel_ticker_hide(data);
+
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static void _quickpanel_ticker_detail_hide_cb(void *data, Evas *e,
+ Evas_Object *obj,
+ void *event_info)
+{
+ DBG("");
+ notification_h noti = (notification_h) data;
+
+ if (g_timer) {
+ ecore_timer_del(g_timer);
+ g_timer = NULL;
+ }
+
+ retif(noti == NULL, , "Invalid parameter!");
+
+ __ticker_only_noti_del(noti);
+ notification_free(noti);
+}
+
+static void _quickpanel_ticker_detail_show_cb(void *data, Evas *e,
+ Evas_Object *obj,
+ void *event_info)
+{
+ DBG("");
+}
+
+static void _quickpanel_ticker_clicked_cb(void *data, Evas_Object *obj,
+ void *event_info)
+{
+ notification_h noti = (notification_h) data;
+ char *caller_pkgname = NULL;
+ char *pkgname = NULL;
+ bundle *args = NULL;
+ bundle *single_service_handle = NULL;
+ int priv_id = 0;
+ int flags = 0;
+ int ret = 0;
+ int val = 0;
+ int flag_launch = 0;
+ int flag_delete = 0;
+ int type = NOTIFICATION_TYPE_NONE;
+
+ DBG("");
+
+ retif(noti == NULL, , "Invalid parameter!");
+
+ /* Check idle lock state */
+ ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &val);
+
+ /* If Lock state, there is not any action when clicked. */
+ if (ret != 0 || val == VCONFKEY_IDLE_LOCK)
+ return;
+
+ notification_get_pkgname(noti, &caller_pkgname);
+ notification_get_application(noti, &pkgname);
+ if (pkgname == NULL)
+ pkgname = caller_pkgname;
+
+ notification_get_id(noti, NULL, &priv_id);
+ notification_get_property(noti, &flags);
+ notification_get_type(noti, &type);
+
+ if (flags & NOTIFICATION_PROP_DISABLE_APP_LAUNCH)
+ flag_launch = 0;
+ else
+ flag_launch = 1;
+
+ if (flags & NOTIFICATION_PROP_DISABLE_AUTO_DELETE)
+ flag_delete = 0;
+ else
+ flag_delete = 1;
+
+ notification_get_execute_option(noti,
+ NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH,
+ NULL, &single_service_handle);
+
+ if (flag_launch == 1) {
+ if (single_service_handle != NULL)
+ appsvc_run_service(single_service_handle, 0, NULL,
+ NULL);
+ else {
+ notification_get_args(noti, &args, NULL);
+ quickpanel_launch_app(pkgname, args);
+ }
+
+ /* Hide quickpanel */
+ Ecore_X_Window zone;
+ zone = ecore_x_e_illume_zone_get(elm_win_xwindow_get(g_window));
+ ecore_x_e_illume_quickpanel_state_send(zone,
+ ECORE_X_ILLUME_QUICKPANEL_STATE_OFF);
+ }
+
+ if (flag_delete == 1 && type == NOTIFICATION_TYPE_NOTI) {
+ notification_delete_by_priv_id(caller_pkgname,
+ NOTIFICATION_TYPE_NOTI,
+ priv_id);
+ }
+}
+
+static void _quickpanel_ticker_button_clicked_cb(void *data, Evas_Object *obj,
+ void *event_info)
+{
+ DBG("");
+
+ if (g_timer) {
+ ecore_timer_del(g_timer);
+ g_timer = NULL;
+ }
+
+ _quickpanel_ticker_hide(data);
+}
+
+static Evas_Object *_quickpanel_ticker_create_button(Evas_Object *parent,
+ notification_h noti)
+{
+ Evas_Object *button = NULL;
+ int ret = 0;
+ int val = 0;
+
+ retif(noti == NULL || parent == NULL, NULL, "Invalid parameter!");
+
+ /* Check idle lock state */
+ ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &val);
+ /* If Lock state, button is diabled */
+ if (ret != 0 || val == VCONFKEY_IDLE_LOCK)
+ return NULL;
+
+ button = elm_button_add(parent);
+ elm_object_style_set(button, "tickernoti");
+ elm_object_text_set(button, _S("IDS_COM_BODY_CLOSE"));
+ evas_object_smart_callback_add(button, "clicked",
+ _quickpanel_ticker_button_clicked_cb, noti);
+
+ return button;
+}
+
+static Evas_Object *_quickpanel_ticker_create_icon(Evas_Object *parent,
+ notification_h noti)
+{
+ char *icon_path = NULL;
+ Evas_Object *icon = NULL;
+
+ retif(noti == NULL || parent == NULL, NULL, "Invalid parameter!");
+
+ notification_get_image(noti, NOTIFICATION_IMAGE_TYPE_ICON, &icon_path);
+ icon = elm_image_add(parent);
+
+ if (icon_path == NULL
+ || (elm_image_file_set(icon, icon_path, NULL) == EINA_FALSE)) {
+ elm_image_file_set(icon, DEFAULT_ICON, NULL);
+ elm_image_resizable_set(icon, EINA_TRUE, EINA_TRUE);
+ }
+
+ return icon;
+}
+
+static char *_quickpanel_ticker_get_label(notification_h noti)
+{
+ char buf[TICKER_MSG_LEN] = { 0, };
+ int len = 0;
+ char *domain = NULL;
+ char *dir = NULL;
+ char *result_title = NULL;
+ char *result_content = NULL;
+ char *title_utf8 = NULL;
+ char *content_utf8 = NULL;
+ notification_error_e noti_err = NOTIFICATION_ERROR_NONE;
+
+ retif(noti == NULL, NULL, "Invalid parameter!");
+
+ notification_get_text_domain(noti, &domain, &dir);
+ if (domain != NULL && dir != NULL)
+ bindtextdomain(domain, dir);
+
+ noti_err = notification_get_text(noti, NOTIFICATION_TEXT_TYPE_TITLE,
+ &result_title);
+ if (noti_err == NOTIFICATION_ERROR_NONE && result_title)
+ title_utf8 = elm_entry_utf8_to_markup(result_title);
+
+ if (_quickpanel_ticker_check_displaying_contents_off(noti) == 1) {
+ noti_err = notification_get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT_FOR_DISPLAY_OPTION_IS_OFF,
+ &result_content);
+ }
+ else {
+ noti_err = notification_get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT,
+ &result_content);
+ }
+
+ if (noti_err == NOTIFICATION_ERROR_NONE && result_content)
+ content_utf8 = elm_entry_utf8_to_markup(result_content);
+
+ if (title_utf8 && content_utf8) {
+ len = snprintf(buf, sizeof(buf),
+ "<font_size=26><color=#BABABA>%s</color></font>"
+ "<br><font_size=29><color=#F4F4F4>%s</color></font>",
+ title_utf8, content_utf8);
+ } else if (title_utf8) {
+ len = snprintf(buf, sizeof(buf),
+ "<font_size=29><color=#BABABA>%s</color></font>",
+ title_utf8);
+ }
+
+ if (title_utf8)
+ free(title_utf8);
+
+ if (content_utf8)
+ free(content_utf8);
+
+ if (len > 0)
+ return strdup(buf);
+
+ return NULL;
+}
+
+static void _noti_hide_cb(void *data, Evas_Object *obj,
+ const char *emission, const char *source)
+{
+ DBG("");
+
+ if (g_timer) {
+ ecore_timer_del(g_timer);
+ g_timer = NULL;
+ }
+
+ _quickpanel_ticker_hide(data);
+}
+
+static Evas_Object *_quickpanel_ticker_create_tickernoti(void *data)
+{
+ notification_h noti = (notification_h) data;
+ Evas_Object *tickernoti = NULL;
+ Evas_Object *icon = NULL;
+ Evas_Object *detail = NULL;
+ Evas_Object *button = NULL;
+ char *buf = NULL;
+ const char *data_win_height = NULL;
+ int noti_height = 0;
+
+ retif(noti == NULL, NULL, "Invalid parameter!");
+
+ tickernoti = noti_win_add(NULL);
+ retif(tickernoti == NULL, NULL, "Failed to add elm tickernoti.");
+
+ detail = elm_layout_add(tickernoti);
+ if (!detail) {
+ ERR("Failed to get detailview.");
+ evas_object_del(tickernoti);
+ return NULL;
+ }
+ elm_layout_theme_set(detail, "tickernoti", "base", "default");
+ elm_object_signal_callback_add(detail, "request,hide", "",
+ _noti_hide_cb, noti);
+
+ data_win_height = (char *)elm_layout_data_get(detail, "height");
+ if (data_win_height != NULL && elm_config_scale_get() > 0.0)
+ noti_height = (int)(elm_config_scale_get()
+ * atoi(data_win_height));
+ evas_object_size_hint_min_set(detail, 1, noti_height);
+ g_noti_height = noti_height;
+
+ noti_win_content_set(tickernoti, detail);
+
+ icon = _quickpanel_ticker_create_icon(detail, noti);
+ if (icon != NULL)
+ elm_object_part_content_set(detail, "icon", icon);
+
+ button = _quickpanel_ticker_create_button(detail, noti);
+ if (button != NULL)
+ elm_object_part_content_set(detail, "button", button);
+
+ buf = _quickpanel_ticker_get_label(noti);
+ if (buf != NULL) {
+ elm_object_part_text_set(detail, "elm.text", buf);
+ free(buf);
+ }
+
+ /* Use style "default" for detailview mode and
+ * "info" for text only mode
+ */
+ elm_object_style_set(tickernoti, "default");
+
+ return tickernoti;
+}
+
+static int _quickpanel_ticker_get_angle(void *data)
+{
+ struct appdata *ad = (struct appdata *)data;
+ Ecore_X_Window xwin, root;
+ int ret = 0, angle = 0, count = 0;
+ unsigned char *prop_data = NULL;
+
+ xwin = elm_win_xwindow_get(ad->win);
+ root = ecore_x_window_root_get(xwin);
+
+ ret = ecore_x_window_prop_property_get(root,
+ ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE,
+ ECORE_X_ATOM_CARDINAL, 32,
+ &prop_data, &count);
+
+ if (ret && prop_data) {
+ memcpy(&angle, prop_data, sizeof(int));
+
+ if (prop_data)
+ free(prop_data);
+
+ return angle;
+ } else {
+ ERR("Fail to get angle");
+ if (prop_data)
+ free(prop_data);
+
+ return -1;
+ }
+}
+
+static void _quickpanel_ticker_update_geometry_on_rotation(void *data, int *x, int *y, int *w, int *h) {
+ int angle = 0;
+
+ if (!data)
+ return;
+ angle = _quickpanel_ticker_get_angle(data);
+ Evas_Coord root_w, root_h;
+
+ /*
+ * manually calculate win_tickernoti_indi window position & size
+ * - win_indi is not full size window
+ */
+ ecore_x_window_size_get(ecore_x_window_root_first_get(), &root_w, &root_h);
+
+ // rotate win
+ switch(angle)
+ {
+ case 90:
+ *w = g_noti_height;
+ *h = root_h;
+ break;
+ case 270:
+ *w = g_noti_height;
+ *h = root_h;
+ *x = root_w - g_noti_height;
+ break;
+ case 180:
+ *w = root_w;
+ *h = g_noti_height;
+ *y = root_h - g_noti_height;
+ break;
+ case 0:
+ default:
+ *w = root_w;
+ *h = g_noti_height;
+ break;
+ }
+ elm_win_rotation_set(g_ticker, angle);
+}
+
+static void _quickpanel_ticker_win_rotated(void *data) {
+ retif(data == NULL, ,"data is NULL");
+ struct appdata *ad = data;
+ int x = 0, y = 0, w = 0, h = 0;
+
+ _quickpanel_ticker_update_geometry_on_rotation(ad, &x, &y, &w, &h);
+
+ if (g_ticker != NULL) {
+ evas_object_move(g_ticker, x, y);
+ evas_object_resize(g_ticker, w, h);
+ }
+}
+
+static void _quickpanel_ticker_noti_detailed_changed_cb(void *data, notification_type_e type, notification_op *op_list, int num_op)
+{
+ notification_h noti = NULL;
+ int flags = 0;
+ int applist = NOTIFICATION_DISPLAY_APP_ALL;
+ int ret = 0;
+ int op_type = 0;
+ int priv_id = 0;
+
+ INFO("_quickpanel_ticker_noti_changed_cb");
+
+ retif(op_list == NULL, ,"op_list is NULL");
+
+ if (num_op == 1) {
+ notification_op_get_data(op_list, NOTIFICATION_OP_DATA_TYPE, &op_type);
+ notification_op_get_data(op_list, NOTIFICATION_OP_DATA_PRIV_ID, &priv_id);
+ DBG("op_type:%d", op_type);
+ DBG("op_priv_id:%d", priv_id);
+
+ if (op_type == NOTIFICATION_OP_INSERT) {
+ noti = notification_load(NULL, priv_id);
+ } else if (op_type == NOTIFICATION_OP_UPDATE) {
+ noti = notification_load(NULL, priv_id);
+ } else {
+ return ;
+ }
+ } else {
+ return ;
+ }
+
+ retif(noti == NULL, ,"noti is NULL");
+
+ notification_get_display_applist(noti, &applist);
+ if (!(applist & NOTIFICATION_DISPLAY_APP_TICKER)) {
+ DBG("No Ticker Msg");
+ notification_free(noti);
+ return ;
+ }
+
+ /* Check setting's event notification */
+ ret = _quickpanel_ticker_check_ticker_off(noti);
+ if (ret == 1) {
+ INFO("Disable tickernoti ret : %d", ret);
+ /* delete temporary here only ticker noti display item */
+ __ticker_only_noti_del(noti);
+ notification_free(noti);
+
+ return;
+ }
+
+ /* Play sound */
+ notification_sound_type_e nsound_type = NOTIFICATION_SOUND_TYPE_NONE;
+ const char *nsound_path = NULL;
+
+ notification_get_sound(noti, &nsound_type, &nsound_path);
+ DBG("Sound : %d, %s", nsound_type, nsound_path);
+ if (nsound_type > NOTIFICATION_SOUND_TYPE_NONE
+ || nsound_type < NOTIFICATION_SOUND_TYPE_MAX) {
+
+ switch (nsound_type) {
+ case NOTIFICATION_SOUND_TYPE_DEFAULT:
+ feedback_play_type(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_UNLOCK);
+ break;
+ case NOTIFICATION_SOUND_TYPE_USER_DATA:
+ quickpanel_player_play(SOUND_TYPE_NOTIFICATION, nsound_path);
+ break;
+ default:
+ break;
+ }
+ }
+ /* Play Vibration */
+ notification_vibration_type_e nvibration_type =
+ NOTIFICATION_VIBRATION_TYPE_NONE;
+ const char *nvibration_path = NULL;
+
+ notification_get_vibration(noti, &nvibration_type, &nvibration_path);
+ DBG("Vibration : %d, %s", nvibration_type, nvibration_path);
+ if (nvibration_type > NOTIFICATION_VIBRATION_TYPE_NONE
+ || nvibration_type < NOTIFICATION_VIBRATION_TYPE_MAX) {
+
+ switch (nvibration_type) {
+ case NOTIFICATION_SOUND_TYPE_DEFAULT:
+ feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_GENERAL);
+ break;
+ case NOTIFICATION_SOUND_TYPE_USER_DATA:
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* Skip if previous ticker is still shown */
+ if (g_ticker != NULL) {
+ _quickpanel_ticker_hide(NULL);
+ }
+
+ /* Check tickernoti flag */
+ notification_get_property(noti, &flags);
+
+ if (flags & NOTIFICATION_PROP_DISABLE_TICKERNOTI) {
+ INFO("NOTIFICATION_PROP_DISABLE_TICKERNOTI");
+ __ticker_only_noti_del(noti);
+ notification_free(noti);
+ } else if (applist & NOTIFICATION_DISPLAY_APP_TICKER) {
+ /* Display ticker */
+ if (g_timer)
+ ecore_timer_del(g_timer);
+
+ g_ticker = _quickpanel_ticker_create_tickernoti(noti);
+ if (g_ticker == NULL) {
+ ERR("Fail to create tickernoti");
+ __ticker_only_noti_del(noti);
+ notification_free(noti);
+ return;
+ }
+
+ g_timer = ecore_timer_add(QP_TICKER_DURATION,
+ _quickpanel_ticker_timeout_cb, noti);
+
+ _quickpanel_ticker_win_rotated(data);
+ evas_object_show(g_ticker);
+
+ evas_object_event_callback_add(g_ticker, EVAS_CALLBACK_SHOW,
+ _quickpanel_ticker_detail_show_cb,
+ g_ticker);
+ evas_object_event_callback_add(g_ticker, EVAS_CALLBACK_HIDE,
+ _quickpanel_ticker_detail_hide_cb,
+ noti);
+ evas_object_smart_callback_add(g_ticker, "clicked",
+ _quickpanel_ticker_clicked_cb,
+ noti);
+ }
+}
+
+/*****************************************************************************
+ *
+ * Util functions
+ *
+ *****************************************************************************/
+static int quickpanel_ticker_init(void *data)
+{
+ struct appdata *ad = (struct appdata *)data;
+
+ latest_inserted_time = time(NULL);
+ g_window = ad->win;
+
+ notification_register_detailed_changed_cb(_quickpanel_ticker_noti_detailed_changed_cb,
+ data);
+
+ return QP_OK;
+}
+
+static int quickpanel_ticker_fini(void *data)
+{
+ _quickpanel_ticker_hide(NULL);
+
+ return QP_OK;
+}
+
+static int quickpanel_ticker_enter_hib(void *data)
+{
+ return QP_OK;
+}
+
+static int quickpanel_ticker_leave_hib(void *data)
+{
+ return QP_OK;
+}
+
+static void quickpanel_ticker_reflesh(void *data)
+{
+ retif(data == NULL, , "Invalid parameter!");
+
+ if (g_ticker != NULL) {
+ _quickpanel_ticker_win_rotated(data);
+ }
+}
diff --git a/daemon/quickpanel-ui.c b/daemon/quickpanel-ui.c
new file mode 100755
index 0000000..4deb6d5
--- /dev/null
+++ b/daemon/quickpanel-ui.c
@@ -0,0 +1,1156 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <signal.h>
+#include <app.h>
+#include <system_info.h>
+#include <sys/utsname.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <utilX.h>
+#include <Ecore_X.h>
+#include <Ecore_Input.h>
+#include <heynoti.h>
+#include <vconf.h>
+#include <unistd.h>
+#include <privilege-control.h>
+#include <bundle.h>
+#include <feedback.h>
+
+#include "common.h"
+#include "quickpanel-ui.h"
+#include "modules.h"
+#include "notifications/noti_display_app.h"
+#include "quickpanel_def.h"
+
+#define HIBERNATION_ENTER_NOTI "HIBERNATION_ENTER"
+#define HIBERNATION_LEAVE_NOTI "HIBERNATION_LEAVE"
+
+#define QP_WINDOW_PRIO 300
+#define QP_PLAY_DURATION_LIMIT 15
+
+/* heynoti handle */
+static int g_hdl_heynoti;
+static player_h g_sound_player;
+static Ecore_Timer *g_sound_player_timer;
+struct appdata *g_app_data = NULL;
+
+/* binary information */
+#define QP_EMUL_STR "Emulator"
+
+static int common_cache_flush(void *evas);
+
+/*****************************************************************************
+ *
+ * HIBERNATION
+ *
+ ****************************************************************************/
+static void _hibernation_enter_cb(void *data)
+{
+ struct appdata *ad = data;
+
+ INFO(" >>>>>>>>>>>>>>> ENTER HIBERNATION!! <<<<<<<<<<<<<<<< ");
+ hib_enter_modules(data);
+ if (ad)
+ common_cache_flush(ad->evas);
+}
+
+static void _hibernation_leave_cb(void *data)
+{
+ hib_leave_modules(data);
+ INFO(" >>>>>>>>>>>>>>> LEAVE HIBERNATION!! <<<<<<<<<<<<<<<< ");
+}
+
+/******************************************************************************
+ *
+ * UI
+ *
+ ****************************************************************************/
+static Eina_Bool quickpanel_ui_refresh_cb(void *data)
+{
+ struct appdata *ad = NULL;
+
+ retif(data == NULL, QP_FAIL, "Invalid parameter!");
+ ad = data;
+
+ INFO(" >>>>>>>>>>>>>>> Refresh QP modules!! <<<<<<<<<<<<<<<< ");
+ refresh_modules(data);
+
+ if (ad->list) {
+ elm_genlist_realized_items_update(ad->list);
+ }
+
+ quickpanel_init_size_genlist(ad);
+ quickpanel_ui_update_height(ad);
+
+ return EINA_FALSE;
+}
+
+static int common_cache_flush(void *evas)
+{
+ int file_cache;
+ int collection_cache;
+ int image_cache;
+ int font_cache;
+
+ retif(evas == NULL, QP_FAIL, "Evas is NULL\n");
+
+ file_cache = edje_file_cache_get();
+ collection_cache = edje_collection_cache_get();
+ image_cache = evas_image_cache_get(evas);
+ font_cache = evas_font_cache_get(evas);
+
+ edje_file_cache_set(file_cache);
+ edje_collection_cache_set(collection_cache);
+ evas_image_cache_set(evas, 0);
+ evas_font_cache_set(evas, 0);
+
+ evas_image_cache_flush(evas);
+ evas_render_idle_flush(evas);
+ evas_font_cache_flush(evas);
+
+ edje_file_cache_flush();
+ edje_collection_cache_flush();
+
+ edje_file_cache_set(file_cache);
+ edje_collection_cache_set(collection_cache);
+ evas_image_cache_set(evas, image_cache);
+ evas_font_cache_set(evas, font_cache);
+
+ return QP_OK;
+}
+
+static int _resize_noti_win(void *data, int new_angle)
+{
+ struct appdata *ad = (struct appdata *)data;
+ int w = 0, h = 0;
+ int tot_h = 0;
+ int diff = 0;
+
+ diff = (ad->angle > new_angle) ?
+ (ad->angle - new_angle) : (new_angle - ad->angle);
+
+#if 0
+ int tot_h = QP_HANDLE_H * ad->scale;
+
+ /* get indicator height */
+ ecore_x_e_illume_indicator_geometry_get(ecore_x_window_root_first_get(),
+ NULL, NULL, NULL, &h);
+ if (h <= 0)
+ h = (int)(QP_INDICATOR_H * ad->scale);
+
+ tot_h += h;
+ INFO("tot_h[%d], scale[%lf],indi[%d]", tot_h, ad->scale, h);
+#else
+ tot_h = 0;
+ INFO("tot_h[%d], scale[%lf]", tot_h, ad->scale);
+#endif
+
+ ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, &h);
+ if (diff % 180 != 0) {
+ int width = 0;
+ int height = 0;
+ if (ad->angle % 180 == 0) {
+ width = w - tot_h;
+ height = h;
+ } else {
+ width = h - tot_h;
+ height = w;
+ }
+ INFO("win[%dx%d], Resize[%dx%d] diff[%d], angle[%d]",
+ w, h, width, height, diff, ad->angle);
+ evas_object_resize(ad->win, (int)width-1, (int)height-1); //workaround
+ evas_object_resize(ad->win, (int)width, (int)height);
+ }
+ return 0;
+}
+
+static Eina_Bool quickpanel_hardkey_cb(void *data, int type, void *event)
+{
+ struct appdata *ad = NULL;
+ Ecore_Event_Key *key_event = NULL;
+ Ecore_X_Window xwin;
+
+ retif(data == NULL || event == NULL,
+ EINA_FALSE, "Invalid parameter!");
+ ad = data;
+ key_event = event;
+
+ if (!strcmp(key_event->keyname, KEY_SELECT)) {
+ xwin = elm_win_xwindow_get(ad->win);
+ if (xwin != 0)
+ ecore_x_e_illume_quickpanel_state_send(ecore_x_e_illume_zone_get(xwin),ECORE_X_ILLUME_QUICKPANEL_STATE_OFF);
+ }
+ return EINA_FALSE;
+}
+
+static Eina_Bool quickpanel_ui_client_message_cb(void *data, int type,
+ void *event)
+{
+ struct appdata *ad = data;
+ Ecore_X_Event_Client_Message *ev = event;
+ int new_angle;
+
+ retif(data == NULL || event == NULL,
+ ECORE_CALLBACK_RENEW, "Invalid parameter!");
+
+ if (ev->message_type == ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE) {
+ new_angle = ev->data.l[0];
+
+ if (new_angle == 0 || new_angle == 90 || new_angle == 180 || new_angle == 270) {
+ if (new_angle != ad->angle) {
+ INFO("ROTATION: new:%d old:%d", new_angle, ad->angle);
+ _resize_noti_win(ad, new_angle);
+
+ elm_win_rotation_with_resize_set(ad->win,
+ new_angle);
+ ad->angle = new_angle;
+
+ quickpanel_ui_set_indicator_cover(ad);
+ }
+ }
+ ecore_idler_add(quickpanel_ui_refresh_cb, ad);
+ } else if (ev->message_type == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE) {
+ if (ev->data.l[0] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ON) {
+ qp_opened_modules(data);
+ } else {
+ qp_closed_modules(data);
+ }
+ }
+ return ECORE_CALLBACK_RENEW;
+}
+
+static Evas_Object *_quickpanel_ui_window_add(const char *name, int prio)
+{
+ Evas_Object *eo = NULL;
+ Ecore_X_Window xwin;
+
+ eo = elm_win_add(NULL, name, ELM_WIN_BASIC);
+
+ if (eo != NULL) {
+ elm_win_alpha_set(eo, EINA_TRUE);
+ elm_win_indicator_mode_set(eo, ELM_WIN_INDICATOR_SHOW);
+ elm_win_title_set(eo, name);
+ elm_win_borderless_set(eo, EINA_TRUE);
+ elm_win_autodel_set(eo, EINA_TRUE);
+
+ /* set this window as a quickpanel */
+ elm_win_quickpanel_set(eo, 1);
+ elm_win_quickpanel_priority_major_set(eo, prio);
+
+ /* icccm name class set */
+ xwin = elm_win_xwindow_get(eo);
+ ecore_x_icccm_name_class_set(xwin, "QUICKPANEL", "QUICKPANEL");
+ evas_object_show(eo);
+ }
+
+ return eo;
+}
+
+Evas_Object *quickpanel_ui_load_edj(Evas_Object * parent, const char *file,
+ const char *group, int is_just_load)
+{
+ Eina_Bool r;
+ Evas_Object *eo = NULL;
+
+ retif(parent == NULL, NULL, "Invalid parameter!");
+
+ eo = elm_layout_add(parent);
+ retif(eo == NULL, NULL, "Failed to add layout object!");
+
+ r = elm_layout_file_set(eo, file, group);
+ retif(r != EINA_TRUE, NULL,
+ "Failed to set edje object file[%s-%s]!", file, group);
+
+ evas_object_size_hint_weight_set(eo,
+ EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+
+ if (is_just_load == 1) {
+ elm_win_resize_object_add(parent, eo);
+ }
+ evas_object_show(eo);
+
+ return eo;
+}
+
+static void _quickpanel_ui_close_quickpanel(void *data, Evas_Object *o,
+ const char *emission, const char *source) {
+
+ Ecore_X_Window xwin = 0;
+ struct appdata *ad = NULL;
+
+ retif(data == NULL, , "data is NULL");
+ ad = data;
+
+ DBG("close quick panel");
+
+ xwin = elm_win_xwindow_get(ad->win);
+
+ if (xwin != 0)
+ ecore_x_e_illume_quickpanel_state_send(ecore_x_e_illume_zone_get(xwin),ECORE_X_ILLUME_QUICKPANEL_STATE_OFF);
+}
+
+static int _quickpanel_ui_create_win(void *data)
+{
+ struct appdata *ad = data;
+ int w = 0;
+ int h = 0;
+
+ retif(data == NULL, QP_FAIL, "Invialid parameter!");
+
+ ad->win = _quickpanel_ui_window_add("Quickpanel Window",
+ QP_WINDOW_PRIO);
+ if (ad->win == NULL) {
+ ERR("ui create : failed to create window.");
+ return -1;
+ }
+#ifdef QP_INDICATOR_WIDGET_ENABLE
+ ad->comformant = elm_conformant_add(ad->win);
+ elm_object_style_set(ad->comformant, "nokeypad");
+
+ ad->ly = quickpanel_ui_load_edj(ad->comformant,
+ DEFAULT_EDJ, "quickpanel/gl_base", 0);
+ if (ad->ly == NULL)
+ return -1;
+
+ evas_object_size_hint_weight_set(ad->comformant,
+ EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ elm_win_resize_object_add(ad->win, ad->comformant);
+ evas_object_show(ad->comformant);
+ elm_object_content_set(ad->comformant, ad->ly);
+
+#else
+ ad->ly = quickpanel_ui_load_edj(ad->win,
+ DEFAULT_EDJ, "quickpanel/gl_base", 0);
+ if (ad->ly == NULL)
+ return -1;
+#endif
+
+ /* get noti evas */
+ ad->evas = evas_object_evas_get(ad->win);
+
+ ad->list = elm_genlist_add(ad->ly);
+ if (!ad->list) {
+ ERR("failed to elm_genlist_add");
+ evas_object_del(ad->ly);
+ evas_object_del(ad->win);
+ ad->ly = NULL;
+ ad->win = NULL;
+ ad->evas = NULL;
+ return -1;
+ }
+ elm_genlist_homogeneous_set(ad->list, EINA_FALSE);
+ elm_scroller_policy_set(ad->list, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
+ elm_object_part_content_set(ad->ly, "qp.gl_base.gl.swallow", ad->list);
+
+ ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, &h);
+ evas_object_resize(ad->win, w, h);
+
+ ad->win_width = w;
+ ad->win_height = h;
+
+ edje_object_signal_callback_add(_EDJ(ad->ly),
+ "close.quickpanel", "*", _quickpanel_ui_close_quickpanel,
+ ad);
+
+ quickpanel_init_size_genlist(ad);
+
+ quickpanel_ui_set_indicator_cover(ad);
+
+ /* key grab */
+ utilx_grab_key(ecore_x_display_get(), elm_win_xwindow_get(ad->win), KEY_SELECT, SHARED_GRAB);
+
+ return 0;
+}
+
+
+void quickpanel_ui_set_indicator_cover(void *data)
+{
+ retif(data == NULL, , "data is NULL");
+ struct appdata *ad = data;
+
+ int x_1 = 0, y_1 = 0;
+ int x_2 = 0, y_2 = 0;
+ int angle = ad->angle;
+
+ int width = INDICATOR_COVER_W * ad->scale;
+ int height = INDICATOR_COVER_H * ad->scale;
+
+ switch (angle) {
+ case 0:
+ x_1 = 0;
+ y_1 = 0;
+ x_2 = ad->win_width - width;
+ y_2 = 0;
+ break;
+ case 90:
+ x_1 = 0;
+ y_1 = 0;
+ x_2 = ad->win_height - width;
+ y_2 = 0;
+ break;
+ case 180:
+ x_1 = 0;
+ y_1 = 0;
+ x_2 = ad->win_width - width;
+ y_2 = 0;
+ break;
+ case 270:
+ x_1 = 0;
+ y_1 = 0;
+ x_2 = ad->win_height - width;
+ y_2 = 0;
+ break;
+ }
+
+ if (ad->cover_indicator_left == NULL) {
+ Evas_Object *bg = evas_object_rectangle_add(ad->evas);
+ evas_object_color_set(bg, 52, 52, 50, 255); // opaque white background
+ evas_object_repeat_events_set(bg, EINA_FALSE);
+ evas_object_resize(bg, width, height); // covers full canvas
+ evas_object_move(bg, x_1, y_1);
+ evas_object_show(bg);
+ ad->cover_indicator_left = bg;
+ } else {
+ evas_object_move(ad->cover_indicator_left, x_1, y_1);
+ }
+ if (ad->cover_indicator_right == NULL) {
+ Evas_Object *bg = evas_object_rectangle_add(ad->evas);
+ evas_object_color_set(bg, 52, 52, 50, 255); // opaque white background
+ evas_object_repeat_events_set(bg, EINA_FALSE);
+ evas_object_resize(bg, width, height); // covers full canvas
+ evas_object_move(bg, x_2, y_2);
+ evas_object_show(bg);
+ ad->cover_indicator_right = bg;
+ } else {
+ evas_object_move(ad->cover_indicator_right, x_2, y_2);
+ }
+}
+
+void quickpanel_ui_window_set_input_region(void *data, int contents_height)
+{
+ struct appdata *ad = NULL;
+ Ecore_X_Window xwin;
+ Ecore_X_Atom atom_window_input_region = 0;
+ unsigned int window_input_region[4] = {0,};
+
+ retif(data == NULL, , "Invialid parameter!");
+ ad = data;
+
+ xwin = elm_win_xwindow_get(ad->win);
+
+ DBG("angle:%d", ad->angle);
+ switch (ad->angle) {
+ case 0:
+ window_input_region[0] = 0; //X
+ window_input_region[1] = contents_height; // Y
+ window_input_region[2] = ad->win_width; // Width
+ window_input_region[3] = ad->scale * QP_HANDLE_H; // height
+ break;
+ case 90:
+ window_input_region[0] = contents_height; //X
+ window_input_region[1] = 0; // Y
+ window_input_region[2] = ad->scale * QP_HANDLE_H; // Width
+ window_input_region[3] = ad->win_height; // height
+ break;
+ case 180:
+ window_input_region[0] = 0; //X
+ window_input_region[1] = ad->win_height - contents_height - ad->scale * QP_HANDLE_H; // Y
+ window_input_region[2] = ad->win_width; // Width
+ window_input_region[3] = ad->scale * QP_HANDLE_H; // height
+ break;
+ case 270:
+ window_input_region[0] = ad->win_width - contents_height - ad->scale * QP_HANDLE_H ; //X
+ window_input_region[1] = 0; // Y
+ window_input_region[2] = ad->scale * QP_HANDLE_H; // Width
+ window_input_region[3] = ad->win_height; // height
+ break;
+ }
+
+ DBG("win_input_0:%d\nwin_input_1:%d\nwin_input_2:%d\nwin_input_3:%d\n"
+ ,window_input_region[0]
+ ,window_input_region[1]
+ ,window_input_region[2]
+ ,window_input_region[3]
+ );
+
+ atom_window_input_region = ecore_x_atom_get(STR_ATOM_WINDOW_INPUT_REGION);
+ ecore_x_window_prop_card32_set(xwin, atom_window_input_region, window_input_region, 4);
+}
+
+void quickpanel_ui_window_set_content_region(void *data, int contents_height)
+{
+ struct appdata *ad = NULL;
+ Ecore_X_Window xwin;
+ Ecore_X_Atom atom_window_contents_region = 0;
+ unsigned int window_contents_region[4] = {0,};
+
+ retif(data == NULL, , "Invialid parameter!");
+ ad = data;
+
+ xwin = elm_win_xwindow_get(ad->win);
+
+ DBG("angle:%d", ad->angle);
+ switch (ad->angle) {
+ case 0:
+ window_contents_region[0] = 0; //X
+ window_contents_region[1] = 0; // Y
+ window_contents_region[2] = ad->win_width; // Width
+ window_contents_region[3] = contents_height; // height
+ break;
+ case 90:
+ window_contents_region[0] = 0; //X
+ window_contents_region[1] = 0; // Y
+ window_contents_region[2] = contents_height; // Width
+ window_contents_region[3] = ad->win_height; // height
+ break;
+ case 180:
+ window_contents_region[0] = 0; //X
+ window_contents_region[1] = ad->win_height - contents_height; // Y
+ window_contents_region[2] = ad->win_width; // Width
+ window_contents_region[3] = contents_height; // height
+ break;
+ case 270:
+ window_contents_region[0] = ad->win_width - contents_height ; //X
+ window_contents_region[1] = 0; // Y
+ window_contents_region[2] = contents_height; // Width
+ window_contents_region[3] = ad->win_height; // height
+ break;
+ }
+
+ DBG("win_contents_0:%d\nwin_contents_1:%d\nwin_contents_2:%d\nwin_contents_3:%d\n"
+ ,window_contents_region[0]
+ ,window_contents_region[1]
+ ,window_contents_region[2]
+ ,window_contents_region[3]
+ );
+
+ atom_window_contents_region = ecore_x_atom_get(STR_ATOM_WINDOW_CONTENTS_REGION);
+ ecore_x_window_prop_card32_set(xwin, atom_window_contents_region, window_contents_region, 4);
+}
+
+static void _quickpanel_move_data_to_service(const char *key, const char *val, void *data)
+{
+ retif(data == NULL || key == NULL || val == NULL, , "Invialid parameter!");
+
+ service_h service = data;
+ service_add_extra_data(service, key, val);
+}
+
+int quickpanel_launch_app(char *app_id, void *data)
+{
+ int ret = SERVICE_ERROR_NONE;
+ service_h service = NULL;
+
+ retif(app_id == NULL, SERVICE_ERROR_INVALID_PARAMETER, "Invialid parameter!");
+
+ ret = service_create(&service);
+ if (ret != SERVICE_ERROR_NONE) {
+ DBG("service_create() return error : %d", ret);
+ return ret;
+ }
+ retif(service == NULL, SERVICE_ERROR_INVALID_PARAMETER, "fail to create service handle!");
+
+ service_set_operation(service, SERVICE_OPERATION_DEFAULT);
+ service_set_app_id(service, app_id);
+
+ if (data != NULL) {
+ bundle_iterate((bundle *)data, _quickpanel_move_data_to_service, service);
+ }
+
+ ret = service_send_launch_request(service, NULL, NULL);
+ if (ret != SERVICE_ERROR_NONE) {
+ DBG("service_send_launch_request() is failed : %d", ret);
+ service_destroy(service);
+ return ret;
+ }
+ service_destroy(service);
+ return ret;
+}
+
+static void _quickpanel_player_free(player_h *sound_player)
+{
+ retif(sound_player == NULL, , "invalid parameter");
+
+ player_state_e state = PLAYER_STATE_NONE;
+
+ if (*sound_player != NULL) {
+ if (player_get_state(*sound_player, &state) == PLAYER_ERROR_NONE) {
+
+ DBG("state of player %d", state);
+
+ if (state == PLAYER_STATE_PLAYING) {
+ player_stop(*sound_player);
+ player_unprepare(*sound_player);
+ }
+ if (state == PLAYER_STATE_READY) {
+ player_unprepare(*sound_player);
+ }
+ }
+ player_destroy(*sound_player);
+ *sound_player = NULL;
+ }
+}
+
+static void
+_quickpanel_player_del_timeout_timer(void)
+{
+ if (g_sound_player_timer) {
+ ecore_timer_del(g_sound_player_timer);
+ g_sound_player_timer = NULL;
+ }
+}
+
+static Eina_Bool _quickpanel_player_timeout_cb(void *data)
+{
+ g_sound_player_timer = NULL;
+
+ retif(data == NULL, ECORE_CALLBACK_CANCEL, "invalid parameter");
+ player_h *sound_player = data;
+
+ _quickpanel_player_free(sound_player);
+
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_quickpanel_player_completed_cb(void *user_data)
+{
+ retif(user_data == NULL, , "invalid parameter");
+ player_h *sound_player = user_data;
+
+ _quickpanel_player_del_timeout_timer();
+ _quickpanel_player_free(sound_player);
+}
+
+static void
+_quickpanel_player_interrupted_cb(player_interrupted_code_e code, void *user_data)
+{
+ retif(user_data == NULL, , "invalid parameter");
+ player_h *sound_player = user_data;
+
+ _quickpanel_player_del_timeout_timer();
+ _quickpanel_player_free(sound_player);
+}
+
+static void
+_quickpanel_player_error_cb(int error_code, void *user_data)
+{
+ retif(user_data == NULL, , "invalid parameter");
+ player_h *sound_player = user_data;
+
+ _quickpanel_player_del_timeout_timer();
+ _quickpanel_player_free(sound_player);
+}
+
+void quickpanel_player_play(sound_type_e sound_type, const char *sound_file)
+{
+ player_h *sound_player = &g_sound_player;
+
+ int ret = PLAYER_ERROR_NONE;
+ player_state_e state = PLAYER_STATE_NONE;
+
+ _quickpanel_player_del_timeout_timer();
+
+ if (*sound_player != NULL) {
+ _quickpanel_player_free(sound_player);
+ }
+
+ ret = player_create(sound_player);
+ if (ret != PLAYER_ERROR_NONE) {
+ ERR("creating the player handle failed[%d]", ret);
+ player_destroy(*sound_player);
+ }
+
+ ret = player_set_sound_type(*sound_player, SOUND_TYPE_MEDIA);
+ if (ret != PLAYER_ERROR_NONE) {
+ ERR("player_set_sound_type() ERR: %x!!!!", ret);
+ _quickpanel_player_free(sound_player);
+ return ;
+ }
+
+ player_get_state(*sound_player, &state);
+ if (state > PLAYER_STATE_READY) {
+ _quickpanel_player_free(sound_player);
+ return;
+ }
+
+ ret = player_set_uri(*sound_player, sound_file);
+ if (ret != PLAYER_ERROR_NONE) {
+ DBG("set attribute---profile_uri[%d]", ret);
+ _quickpanel_player_free(sound_player);
+ return;
+ }
+
+ ret = player_prepare(*sound_player);
+ if (ret != PLAYER_ERROR_NONE) {
+ DBG("realizing the player handle failed[%d]", ret);
+ _quickpanel_player_free(sound_player);
+ return;
+ }
+
+ player_get_state(*sound_player, &state);
+ if (state != PLAYER_STATE_READY) {
+ DBG("state of player is invalid %d", state);
+ _quickpanel_player_free(sound_player);
+ return;
+ }
+
+ /* register callback */
+ ret = player_set_completed_cb(*sound_player, _quickpanel_player_completed_cb, sound_player);
+ if (ret != PLAYER_ERROR_NONE) {
+ DBG("player_set_completed_cb() ERR: %x!!!!", ret);
+ _quickpanel_player_free(sound_player);
+ return;
+ }
+
+ ret = player_set_interrupted_cb(*sound_player, _quickpanel_player_interrupted_cb, sound_player);
+ if (ret != PLAYER_ERROR_NONE) {
+ _quickpanel_player_free(sound_player);
+ return;
+ }
+
+ ret = player_set_error_cb(*sound_player, _quickpanel_player_error_cb, sound_player);
+ if (ret != PLAYER_ERROR_NONE) {
+ _quickpanel_player_free(sound_player);
+ return;
+ }
+
+ ret = player_start(*sound_player);
+ if (ret != PLAYER_ERROR_NONE) { /* if directly return retor.. */
+ DBG("player_start [%d]", ret);
+ _quickpanel_player_free(sound_player);
+ return;
+ }
+
+ g_sound_player_timer = ecore_timer_add(QP_PLAY_DURATION_LIMIT,
+ _quickpanel_player_timeout_cb, sound_player);
+}
+
+static int _quickpanel_ui_delete_win(void *data)
+{
+ struct appdata *ad = data;
+ retif(data == NULL, QP_FAIL, "Invialid parameter!");
+
+ if (ad->ly != NULL) {
+ evas_object_del(ad->ly);
+ ad->ly = NULL;
+ }
+ if (ad->win != NULL) {
+ evas_object_del(ad->win);
+ ad->win = NULL;
+ }
+
+ return QP_OK;
+}
+
+static void _quickpanel_ui_init_heynoti(struct appdata *ad)
+{
+ int ret = 0;
+
+ /* init heynoti */
+ g_hdl_heynoti = heynoti_init();
+ if (g_hdl_heynoti == -1) {
+ ERR("ui init heynoti : fail to heynoti_init.");
+ g_hdl_heynoti = 0;
+ return;
+ }
+
+ /* subscribe hibernation */
+ heynoti_subscribe(g_hdl_heynoti, HIBERNATION_ENTER_NOTI,
+ _hibernation_enter_cb, (void *)ad);
+ heynoti_subscribe(g_hdl_heynoti, HIBERNATION_LEAVE_NOTI,
+ _hibernation_leave_cb, (void *)ad);
+
+ ret = heynoti_attach_handler(g_hdl_heynoti);
+ if (ret == -1) {
+ ERR("ui init heynoti : fail to heynoti_attach_handler.");
+ return;
+ }
+}
+
+static void _quickpanel_ui_fini_heynoti(void)
+{
+ if (g_hdl_heynoti != 0) {
+ /* unsubscribe hibernation */
+ heynoti_unsubscribe(g_hdl_heynoti, HIBERNATION_ENTER_NOTI,
+ _hibernation_enter_cb);
+ heynoti_unsubscribe(g_hdl_heynoti, HIBERNATION_LEAVE_NOTI,
+ _hibernation_leave_cb);
+
+ /* close heynoti */
+ heynoti_close(g_hdl_heynoti);
+ g_hdl_heynoti = 0;
+ }
+}
+
+static void _quickpanel_ui_init_ecore_event(struct appdata *ad)
+{
+ Ecore_Event_Handler *hdl = NULL;
+ Ecore_Event_Handler *hdl_key = NULL;
+
+ /* Register window rotate event */
+ hdl = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE,
+ quickpanel_ui_client_message_cb, ad);
+ if (hdl == NULL)
+ ERR("failed to add handler(ECORE_X_EVENT_CLIENT_MESSAGE)");
+
+ ad->hdl_client_message = hdl;
+
+ hdl_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, quickpanel_hardkey_cb, ad);
+ if (hdl_key == NULL)
+ ERR("failed to add handler(ECORE_EVENT_KEY_UP)");
+
+ ad->hdl_hardkey = hdl_key;
+}
+
+static void _quickpanel_ui_fini_ecore_event(struct appdata *ad)
+{
+ if (ad->hdl_client_message != NULL) {
+ ecore_event_handler_del(ad->hdl_client_message);
+ ad->hdl_client_message = NULL;
+ }
+ if (ad->hdl_hardkey != NULL) {
+ ecore_event_handler_del(ad->hdl_hardkey);
+ ad->hdl_hardkey = NULL;
+ }
+}
+int quickpanel_ui_check_emul(void)
+{
+ int is_emul = 0;
+ char *info = NULL;
+
+ if (system_info_get_value_string(SYSTEM_INFO_KEY_MODEL, &info) == 0) {
+ if (info == NULL) return 0;
+ if (!strncmp(QP_EMUL_STR, info, strlen(info))) {
+ is_emul = 1;
+ }
+ }
+
+ if (info != NULL) free(info);
+
+ return is_emul;
+}
+
+static void _quickpanel_ui_setting_show(struct appdata *ad, int show)
+{
+ if (!ad)
+ return;
+
+ if (!ad->ly)
+ return;
+
+ ad->show_setting = 1;
+
+}
+
+#ifdef QP_BRIGHTNESS_ENABLE
+/* toggle */
+extern QP_Module brightness_ctrl;
+#endif /* QP_BRIGHTNESS_ENABLE */
+#ifdef QP_MINICTRL_ENABLE
+extern QP_Module minictrl;
+#endif /* QP_MINICTRL_ENABLE */
+extern QP_Module noti;
+
+static void _quickpanel_ui_update_height(void *data)
+{
+ int contents_height = 0;
+ int height_genlist = 0;
+
+ struct appdata *ad = NULL;
+
+ retif(data == NULL, , "data is NULL");
+ ad = data;
+
+ DBG("current item count:%d", elm_genlist_items_count(ad->list));
+
+ height_genlist += noti.get_height(data);
+#ifdef QP_BRIGHTNESS_ENABLE
+ height_genlist += brightness_ctrl.get_height(data);
+#endif
+#ifdef QP_MINICTRL_ENABLE
+ height_genlist += minictrl.get_height(data);
+#endif
+
+ height_genlist = ad->gl_limit_height;
+
+ contents_height = ad->gl_distance_from_top + height_genlist + ad->gl_distance_to_bottom - ad->scale * QP_HANDLE_H;
+
+ DBG("height_genlist:%d\n gl_distance_from_top:%d\n gl_distance_to_bottom:%d\n gl_limit_height:%d\nnew_height:%d"
+ ,height_genlist
+ ,ad->gl_distance_from_top
+ ,ad->gl_distance_to_bottom
+ ,ad->gl_limit_height
+ ,contents_height
+ );
+
+ quickpanel_ui_window_set_input_region(ad, contents_height);
+ quickpanel_ui_window_set_content_region(ad, contents_height);
+}
+
+void quickpanel_ui_update_height(void *data)
+{
+ _quickpanel_ui_update_height(data);
+}
+
+void quickpanel_init_size_genlist(void *data)
+{
+ struct appdata *ad = NULL;
+ int max_height_window = 0;
+ Evas_Coord genlist_y = 0;
+ Evas_Coord spn_height = 0;
+
+ retif(data == NULL, , "data is NULL");
+ ad = data;
+
+ if (ad->angle == 90 || ad->angle == 270 )
+ max_height_window = ad->win_width;
+ else
+ max_height_window = ad->win_height;
+
+ edje_object_part_geometry_get(_EDJ(ad->ly), "qp.gl_base.gl.swallow", NULL, &genlist_y, NULL, NULL);
+ DBG("quickpanel, qp.gl_base.gl.swallow y: %d",genlist_y);
+
+ edje_object_part_geometry_get(_EDJ(ad->ly), "qp.base.spn.swallow", NULL, NULL, NULL, &spn_height);
+ DBG("quickpanel, to spn_height: %d",spn_height);
+
+ ad->gl_distance_from_top = genlist_y;
+ ad->gl_distance_to_bottom = spn_height + (1 * ad->scale) + (ad->scale*QP_HANDLE_H) ;
+ ad->gl_limit_height = max_height_window - ad->gl_distance_from_top - ad->gl_distance_to_bottom;
+}
+
+void *quickpanel_get_app_data(void)
+{
+ return g_app_data;
+}
+
+/*****************************************************************************
+ *
+ * App efl main interface
+ *
+ ****************************************************************************/
+
+static void _signal_handler(int signum, siginfo_t *info, void *unused)
+{
+ DBG("Terminated...");
+ app_efl_exit();
+}
+
+static void _heynoti_event_power_off(void *data)
+{
+ DBG("Terminated...");
+ app_efl_exit();
+}
+
+static bool quickpanel_app_create(void *data)
+{
+ DBG("");
+
+ pid_t pid;
+ int r;
+
+ // signal handler
+ struct sigaction act;
+ act.sa_sigaction = _signal_handler;
+ act.sa_flags = SA_SIGINFO;
+
+ int ret = sigemptyset(&act.sa_mask);
+ if (ret < 0) {
+ ERR("Failed to sigemptyset[%s]", strerror(errno));
+ }
+ ret = sigaddset(&act.sa_mask, SIGTERM);
+ if (ret < 0) {
+ ERR("Failed to sigaddset[%s]", strerror(errno));
+ }
+ ret = sigaction(SIGTERM, &act, NULL);
+ if (ret < 0) {
+ ERR("Failed to sigaction[%s]", strerror(errno));
+ }
+
+ pid = setsid();
+ if (pid < 0)
+ WARN("Failed to set session id!");
+
+ r = nice(2);
+ if (r == -1)
+ WARN("Failed to set nice value!");
+
+ return TRUE;
+}
+
+static void quickpanel_app_terminate(void *data)
+{
+ DBG("");
+
+ struct appdata *ad = data;
+ retif(ad == NULL, , "invalid data.");
+
+ /* fini quickpanel modules */
+ fini_modules(ad);
+
+ common_cache_flush(ad->evas);
+
+ feedback_deinitialize();
+
+ /* unregister system event callback */
+ _quickpanel_ui_fini_heynoti();
+
+ notification_daemon_shutdown();
+
+ _quickpanel_ui_fini_ecore_event(ad);
+
+ if (ad->cover_indicator_left != NULL) {
+ evas_object_del(ad->cover_indicator_left);
+ ad->cover_indicator_left = NULL;
+ }
+ if (ad->cover_indicator_right != NULL) {
+ evas_object_del(ad->cover_indicator_right);
+ ad->cover_indicator_right = NULL;
+ }
+ /* delete quickpanel window */
+ _quickpanel_ui_delete_win(ad);
+
+ INFO(" >>>>>>>>>>>>>>> QUICKPANEL IS TERMINATED!! <<<<<<<<<<<<<<<< ");
+}
+
+static void quickpanel_app_pause(void *data)
+{
+ DBG("");
+
+ struct appdata *ad = data;
+ retif(ad == NULL,, "invalid data.");
+
+ suspend_modules(ad);
+
+ common_cache_flush(ad->evas);
+}
+
+static void quickpanel_app_resume(void *data)
+{
+ DBG("");
+
+ struct appdata *ad = data;
+ retif(ad == NULL,, "invalid data.");
+
+ resume_modules(data);
+}
+
+static void quickpanel_app_service(service_h service, void *data)
+{
+ struct appdata *ad = data;
+ int ret = 0;
+
+ retif(ad == NULL, , "Invialid parameter!");
+
+ INFO(" >>>>>>>>>>>>>>> QUICKPANEL IS STARTED!! <<<<<<<<<<<<<<<< ");
+
+ /* Check emulator */
+ ad->is_emul = quickpanel_ui_check_emul();
+ INFO("quickpanel run in %s", ad->is_emul ? "Emul" : "Device");
+
+ ad->scale = elm_config_scale_get();
+ if (ad->scale < 0)
+ ad->scale = 1.0;
+
+ /* Get theme */
+ elm_theme_extension_add(NULL, DEFAULT_THEME_EDJ);
+
+ /* create quickpanel window */
+ ret = _quickpanel_ui_create_win(ad);
+ retif(ret != QP_OK, , "Failed to create window!");
+
+ /* init internationalization */
+ notification_daemon_win_set(ad->win);
+
+ _quickpanel_ui_init_ecore_event(ad);
+
+ _quickpanel_ui_init_heynoti(ad);
+
+ feedback_initialize();
+
+#ifdef QP_SETTING_ENABLE
+ _quickpanel_ui_setting_show(ad, 1);
+#else /* QP_SETTING_ENABLE */
+ _quickpanel_ui_setting_show(ad, 0);
+#endif /* QP_SETTING_ENABLE */
+
+ /* init quickpanel modules */
+ init_modules(ad);
+
+ ecore_idler_add(quickpanel_ui_refresh_cb, ad);
+}
+
+static void quickpanel_app_language_changed_cb(void *data)
+{
+ retif(data == NULL, , "Invalid parameter!");
+
+ INFO(" >>>>>>>>>>>>>>> LANGUAGE CHANGED!! <<<<<<<<<<<<<<<< ");
+ lang_change_modules(data);
+}
+
+static void quickpanel_app_region_format_changed_cb(void *data)
+{
+ INFO(" >>>>>>>>>>>>>>> region_format CHANGED!! <<<<<<<<<<<<<<<< ");
+}
+
+int main(int argc, char *argv[])
+{
+ int r = 0;
+ struct appdata ad;
+ app_event_callback_s app_callback = {0,};
+
+ r = control_privilege();
+ if (r != 0) {
+ WARN("Failed to control privilege!");
+ }
+
+ int heyfd = heynoti_init();
+ if (heyfd > 0) {
+ int ret = heynoti_subscribe(heyfd, "power_off_start", _heynoti_event_power_off, NULL);
+ if (ret > 0) {
+ ret = heynoti_attach_handler(heyfd);
+ if (ret < 0) {
+ ERR("Failed to heynoti_attach_handler[%d]", ret);
+ }
+ } else {
+ ERR("Failed to heynoti_subscribe[%d]", ret);
+ }
+ } else {
+ ERR("Failed to heynoti_init[%d]", heyfd);
+ }
+
+ app_callback.create = quickpanel_app_create;
+ app_callback.terminate = quickpanel_app_terminate;
+ app_callback.pause = quickpanel_app_pause;
+ app_callback.resume = quickpanel_app_resume;
+ app_callback.service = quickpanel_app_service;
+ app_callback.low_memory = NULL;
+ app_callback.low_battery = NULL;
+ app_callback.device_orientation = NULL;
+ app_callback.language_changed = quickpanel_app_language_changed_cb;
+ app_callback.region_format_changed = quickpanel_app_region_format_changed_cb;
+
+ memset(&ad, 0x0, sizeof(struct appdata));
+
+ notification_daemon_init();
+
+ g_app_data = &ad;
+
+ DBG("start main");
+ return app_efl_main(&argc, &argv, &app_callback, (void *)&ad);
+}
diff --git a/daemon/quickpanel-ui.h b/daemon/quickpanel-ui.h
new file mode 100755
index 0000000..e3ec9cf
--- /dev/null
+++ b/daemon/quickpanel-ui.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __QUICKPANEL_UI_H__
+#define __QUICKPANEL_UI_H__
+
+#include <Elementary.h>
+#include <player.h>
+
+#if !defined(VENDOR)
+# define VENDOR "org.tizen"
+#endif
+#if !defined(PACKAGE)
+# define PACKAGE "quickpanel"
+#endif
+
+#if !defined(LOCALEDIR)
+# define LOCALEDIR "/usr/apps/"VENDOR"."PACKAGE"/res/locale"
+#endif
+
+#if !defined(EDJDIR)
+# define EDJDIR "/usr/apps/"VENDOR"."PACKAGE"/res/edje"
+#endif
+
+/* EDJ theme */
+#define DEFAULT_EDJ EDJDIR"/"PACKAGE".edj"
+#define DEFAULT_THEME_EDJ EDJDIR"/"PACKAGE"_theme.edj"
+
+#define _EDJ(o) elm_layout_edje_get(o)
+#define _S(str) dgettext("sys_string", str)
+#undef _
+#define _(str) gettext(str)
+#define _NOT_LOCALIZED(str) (str)
+
+#define STR_ATOM_WINDOW_INPUT_REGION "_E_COMP_WINDOW_INPUT_REGION"
+#define STR_ATOM_WINDOW_CONTENTS_REGION "_E_COMP_WINDOW_CONTENTS_REGION"
+
+#define MAX_NAM_LEN 4096
+
+#define INDICATOR_COVER_W 82
+#define INDICATOR_COVER_H 60
+
+#define QP_SETTING_PKG_SETTING VENDOR".setting"
+#define QP_SETTING_PKG_SETTING_EMUL "kto5jikgul.Settings"
+
+struct appdata {
+ Evas_Object *win;
+#ifdef QP_INDICATOR_WIDGET_ENABLE
+ Evas_Object *comformant;
+#endif
+ Evas_Object *ly;
+ Evas *evas;
+
+ Evas_Object *list;
+ int angle;
+ double scale;
+ char *theme;
+
+ int win_width;
+ int win_height;
+ int gl_limit_height;
+ int gl_distance_from_top;
+ int gl_distance_to_bottom;
+
+ int is_emul; /* 0 : target, 1 : emul */
+ int show_setting;
+
+ Ecore_Event_Handler *hdl_client_message;
+ Ecore_Event_Handler *hdl_hardkey;
+
+ E_DBus_Connection *dbus_connection;
+ E_DBus_Signal_Handler *dbus_handler_size;
+ E_DBus_Signal_Handler *dbus_handler_progress;
+ E_DBus_Signal_Handler *dbus_handler_content;
+
+ Evas_Object *cover_indicator_left;
+ Evas_Object *cover_indicator_right;
+};
+
+typedef struct _QP_Module {
+ char *name;
+ /* func */
+ int (*init) (void *);
+ int (*fini) (void *);
+ int (*suspend) (void *);
+ int (*resume) (void *);
+ int (*hib_enter) (void *);
+ int (*hib_leave) (void *);
+ void (*lang_changed) (void *);
+ void (*refresh) (void *);
+ unsigned int (*get_height) (void *);
+ void (*qp_opened) (void *);
+ void (*qp_closed) (void *);
+
+ /* do not modify this area */
+ /* internal data */
+ Eina_Bool state;
+} QP_Module;
+
+void quickpanel_player_play(sound_type_e sound_type, const char *sound_file);
+int quickpanel_launch_app(char *app_id, void *data);
+int quickpanel_ui_check_emul(void);
+void quickpanel_init_size_genlist(void *data);
+void quickpanel_ui_update_height(void *data);
+void *quickpanel_get_app_data(void);
+Evas_Object *quickpanel_ui_load_edj(Evas_Object * parent, const char *file,
+ const char *group, int is_just_load);
+void quickpanel_ui_set_indicator_cover(void *data);
+
+#endif /* __QUICKPANEL_UI_H__ */