diff --git a/src/bin/e_notification.c b/src/bin/e_notification.c index 4cc95c641..c5cedf58c 100644 --- a/src/bin/e_notification.c +++ b/src/bin/e_notification.c @@ -273,3 +273,153 @@ error: evas_object_del(o); return NULL; } + +/* client API */ + +static void +client_notify_cb(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + unsigned id = 0; + E_Notification_Client_Send_Cb cb = edbus_pending_data_del(pending, "cb"); + EDBus_Connection *conn = edbus_pending_data_del(pending, "conn"); + if (edbus_message_error_get(msg, NULL, NULL)) + goto end; + if (!edbus_message_arguments_get(msg, "u", &id)) + goto end; +end: + cb(data, id); + edbus_connection_unref(conn); + edbus_shutdown(); +} + +static Eina_Bool +notification_cliend_dbus_send(E_Notification_Notify *notify, E_Notification_Client_Send_Cb cb, const void *data) +{ + EDBus_Connection *conn; + EDBus_Message *msg; + EDBus_Message_Iter *main_iter, *actions, *hints; + EDBus_Message_Iter *entry, *var; + EDBus_Pending *p; + EINA_SAFETY_ON_NULL_RETURN_VAL(notify, EINA_FALSE); + edbus_init(); + conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SESSION); + EINA_SAFETY_ON_NULL_RETURN_VAL(conn, EINA_FALSE); + + msg = edbus_message_method_call_new(BUS, PATH, INTERFACE, "Notify"); + EINA_SAFETY_ON_NULL_RETURN_VAL(msg, EINA_FALSE); + + //build message + main_iter = edbus_message_iter_get(msg); + if (!edbus_message_iter_arguments_append(main_iter, "susssas", + notify->app_name, + notify->replaces_id, + notify->icon.icon, + notify->sumary, notify->body, + &actions)) + goto error; + edbus_message_iter_container_close(main_iter, actions); + if (!edbus_message_iter_arguments_append(main_iter, "a{sv}", &hints)) + goto error; + + if (notify->icon.raw.data) + { + EDBus_Message_Iter *st, *data_iter; + int i; + edbus_message_iter_arguments_append(hints, "{sv}", &entry); + edbus_message_iter_arguments_append(entry, "s", "image-data"); + var = edbus_message_iter_container_new(entry, 'v', "(iiibiiay)"); + edbus_message_iter_arguments_append(var, "(iiibiiay)", &st); + edbus_message_iter_arguments_append(st, "iiibiiay", + notify->icon.raw.width, + notify->icon.raw.height, + notify->icon.raw.rowstride, + notify->icon.raw.has_alpha, + notify->icon.raw.bits_per_sample, + notify->icon.raw.channels, + &data_iter); + for (i = 0; i < notify->icon.raw.data_size; i++) + edbus_message_iter_basic_append(data_iter, 'y', notify->icon.raw.data[i]); + edbus_message_iter_container_close(st, data_iter); + edbus_message_iter_container_close(var, st); + edbus_message_iter_container_close(entry, var); + edbus_message_iter_container_close(hints, entry); + } + if (notify->icon.icon_path) + { + edbus_message_iter_arguments_append(hints, "{sv}", &entry); + edbus_message_iter_arguments_append(entry, "s", "image-path"); + var = edbus_message_iter_container_new(entry, 'v', "s"); + edbus_message_iter_arguments_append(var, "s", notify->icon.icon_path); + edbus_message_iter_container_close(entry, var); + edbus_message_iter_container_close(hints, entry); + } + + edbus_message_iter_arguments_append(hints, "{sv}", &entry); + edbus_message_iter_arguments_append(entry, "s", "urgency"); + var = edbus_message_iter_container_new(entry, 'v', "y"); + edbus_message_iter_arguments_append(var, "y", notify->urgency); + edbus_message_iter_container_close(entry, var); + edbus_message_iter_container_close(hints, entry); + + edbus_message_iter_container_close(main_iter, hints); + + edbus_message_iter_arguments_append(main_iter, "i", notify->timeout); + + p = edbus_connection_send(conn, msg, client_notify_cb, data, 5000); + EINA_SAFETY_ON_NULL_GOTO(p, error); + edbus_pending_data_set(p, "cb", cb); + edbus_pending_data_set(p, "conn", conn); + edbus_message_unref(msg); + return EINA_TRUE; +error: + edbus_message_unref(msg); + return EINA_FALSE; +} + +static const char * +null_strings_replace(const char *text) +{ + if (!text) + return eina_stringshare_add(""); + return text; +} + +static void +normalize_notify(E_Notification_Notify *notify) +{ + notify->app_name = null_strings_replace(notify->app_name); + notify->body = null_strings_replace(notify->body); + notify->sumary = null_strings_replace(notify->sumary); + notify->icon.icon = null_strings_replace(notify->icon.icon); + if (!notify->timeout) + notify->timeout = -1; +} + +EAPI Eina_Bool +e_notification_client_send(E_Notification_Notify *notify, E_Notification_Client_Send_Cb cb, const void *data) +{ + unsigned id; + E_Notification_Notify *copy; + + EINA_SAFETY_ON_NULL_RETURN_VAL(notify, EINA_FALSE); + normalize_notify(notify); + if (!n_data) + return notification_cliend_dbus_send(notify, cb, data); + + //local + copy = malloc(sizeof(E_Notification_Notify)); + EINA_SAFETY_ON_NULL_RETURN_VAL(copy, EINA_FALSE); + memcpy(copy, notify, sizeof(E_Notification_Notify)); + + copy->app_name = eina_stringshare_add(notify->app_name); + copy->body = eina_stringshare_add(notify->body); + copy->sumary = eina_stringshare_add(notify->sumary); + copy->icon.icon = eina_stringshare_add(notify->icon.icon); + if (notify->icon.icon_path) + copy->icon.icon_path = eina_stringshare_add(notify->icon.icon_path); + + id = n_data->notify_cb(n_data->data, copy); + if (cb) + cb((void *) data, id); + return EINA_TRUE; +} diff --git a/src/bin/e_notification.h b/src/bin/e_notification.h index 8b496ca2b..291c2114e 100644 --- a/src/bin/e_notification.h +++ b/src/bin/e_notification.h @@ -77,4 +77,8 @@ EAPI void e_notification_notify_free(E_Notification_Notify *notify); EAPI void e_notification_notify_close(E_Notification_Notify *notify, E_Notification_Notify_Closed_Reason reason); EAPI Evas_Object *e_notification_notify_raw_image_get(E_Notification_Notify *notify, Evas *evas); +//client +typedef void (*E_Notification_Client_Send_Cb)(void *data, unsigned int id); +EAPI Eina_Bool e_notification_client_send(E_Notification_Notify *notify, E_Notification_Client_Send_Cb cb, const void *data); + #endif diff --git a/src/modules/notification/e_mod_main.c b/src/modules/notification/e_mod_main.c index 39a35cd83..a762b4fb1 100644 --- a/src/modules/notification/e_mod_main.c +++ b/src/modules/notification/e_mod_main.c @@ -213,13 +213,14 @@ e_modapi_init(E_Module *m) notification_cfg = _notification_cfg_new(); /* set up the notification daemon */ - if (!e_notification_start(_notification_cb_notify, - _notification_cb_close, - &server_info, notification_cfg)) + if (!e_notification_server_register(&server_info, _notification_cb_notify, + _notification_cb_close, + notification_cfg)) { - e_util_dialog_show(_("Error During DBus Init!"), - _("Error during DBus init! Please check if " - "dbus is correctly installed and running.")); + e_util_dialog_show(_("Error during notification server initialization"), + _("Ensure there's no other module acting as a server" + " and that D-Bus is correctly installed and " + " running")); return NULL; } @@ -252,7 +253,7 @@ e_modapi_init(E_Module *m) e_configure_option_category_tag_add(_("screen"), _("notification")); e_configure_option_category_tag_add(_("notification"), _("notification")); e_configure_option_category_icon_set(_("notification"), buf); - + return m; } @@ -270,7 +271,7 @@ e_modapi_shutdown(E_Module *m __UNUSED__) e_configure_registry_category_del("extensions"); notification_popup_shutdown(); - e_notification_stop(); + e_notification_server_unregister(); E_CONFIGURE_OPTION_LIST_CLEAR(cfg_opts); diff --git a/src/modules/notification/e_mod_popup.c b/src/modules/notification/e_mod_popup.c index c5eaa9159..ebb38347f 100644 --- a/src/modules/notification/e_mod_popup.c +++ b/src/modules/notification/e_mod_popup.c @@ -8,9 +8,9 @@ static int _notification_popup_place(Popup_Data *popup, int num); static void _notification_popup_refresh(Popup_Data *popup); static void _notification_popup_del(unsigned int id, - E_Notification_Closed_Reason reason); + E_Notification_Notify_Closed_Reason reason); static void _notification_popdown(Popup_Data *popup, - E_Notification_Closed_Reason reason); + E_Notification_Notify_Closed_Reason reason); #define POPUP_LIMIT 7 static int popups_displayed = 0; @@ -23,7 +23,7 @@ static int next_pos = 0; static Eina_Bool _notification_timer_cb(Popup_Data *popup) { - _notification_popup_del(popup->id, E_NOTIFICATION_CLOSED_REASON_EXPIRED); + _notification_popup_del(popup->id, E_NOTIFICATION_NOTIFY_CLOSED_REASON_EXPIRED); return EINA_FALSE; } @@ -96,13 +96,13 @@ notification_popup_shutdown(void) Popup_Data *popup; EINA_LIST_FREE(notification_cfg->popups, popup) - _notification_popdown(popup, E_NOTIFICATION_CLOSED_REASON_REQUESTED); + _notification_popdown(popup, E_NOTIFICATION_NOTIFY_CLOSED_REASON_REQUESTED); } void notification_popup_close(unsigned int id) { - _notification_popup_del(id, E_NOTIFICATION_CLOSED_REASON_REQUESTED); + _notification_popup_del(id, E_NOTIFICATION_NOTIFY_CLOSED_REASON_REQUESTED); } static void @@ -121,7 +121,7 @@ _notification_theme_cb_close(Popup_Data *popup, const char *emission __UNUSED__, const char *source __UNUSED__) { - _notification_popup_del(popup->id, E_NOTIFICATION_CLOSED_REASON_DISMISSED); + _notification_popup_del(popup->id, E_NOTIFICATION_NOTIFY_CLOSED_REASON_DISMISSED); } static void @@ -378,7 +378,8 @@ _notification_popup_refresh(Popup_Data *popup) } else { - popup->app_icon = e_notification_raw_image_get(popup->e, popup->notif); + popup->app_icon = e_notification_notify_raw_image_get(popup->notif, + popup->e); evas_object_image_filled_set(popup->app_icon, EINA_TRUE); evas_object_image_alpha_set(popup->app_icon, EINA_TRUE); evas_object_image_size_get(popup->app_icon, &w, &h); @@ -447,7 +448,7 @@ _notification_popup_find(unsigned int id) static void _notification_popup_del(unsigned int id, - E_Notification_Closed_Reason reason) + E_Notification_Notify_Closed_Reason reason) { Popup_Data *popup; Eina_List *l, *l2; @@ -469,7 +470,7 @@ _notification_popup_del(unsigned int id, static void _notification_popdown(Popup_Data *popup, - E_Notification_Closed_Reason reason) + E_Notification_Notify_Closed_Reason reason) { if (popup->timer) ecore_timer_del(popup->timer); e_popup_hide(popup->win); @@ -477,7 +478,7 @@ _notification_popdown(Popup_Data *popup, evas_object_del(popup->app_icon); evas_object_del(popup->theme); e_object_del(E_OBJECT(popup->win)); - e_notification_notification_closed(popup->id, reason); + e_notification_notify_close(popup->notif, reason); e_notification_notify_free(popup->notif); free(popup); }