summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean Guyomarc'h <jean.guyomarch@gmail.com>2016-01-04 11:49:11 -0800
committerCedric BAIL <cedric@osg.samsung.com>2016-01-04 11:49:16 -0800
commit34d2c8e1250c21e06593efba67eeefc97a216d98 (patch)
tree690367f49823c9959519d8ca58f595bcd0605152
parentfa6bcdda8cf5cc69c37a96a96c1bd7ed93df52c9 (diff)
sys_notify: support several notification servers
Summary: An Eo class Elm.Sys_Notify acts as a manager of notification servers. A manager registers and unregisters notification servers. Notification servers implement the Elm.Sys_Notify_Interface which allows to send and close notifications. Currently, only the DBus server is implemented (legacy code). Even though there are many changes in the code, there should be no API nor ABI breaks. Reviewers: naguirre, seoz, cedric Reviewed By: cedric Differential Revision: https://phab.enlightenment.org/D3172 Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
-rw-r--r--src/lib/Makefile.am7
-rw-r--r--src/lib/elm_sys_notify.c513
-rw-r--r--src/lib/elm_sys_notify.eo90
-rw-r--r--src/lib/elm_sys_notify.h92
-rw-r--r--src/lib/elm_sys_notify_dbus.c398
-rw-r--r--src/lib/elm_sys_notify_dbus.eo14
-rw-r--r--src/lib/elm_sys_notify_interface.c9
-rw-r--r--src/lib/elm_sys_notify_interface.eo66
8 files changed, 827 insertions, 362 deletions
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 424095ee9..20f6521b8 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -348,6 +348,8 @@ elm_systray_eo.h \
348elm_systray_common.h \ 348elm_systray_common.h \
349elm_systray_watcher.h \ 349elm_systray_watcher.h \
350elm_sys_notify.h \ 350elm_sys_notify.h \
351elm_sys_notify.eo.h \
352elm_sys_notify_dbus.eo.h \
351elm_table.h \ 353elm_table.h \
352elm_table_eo.h \ 354elm_table_eo.h \
353elm_table_legacy.h \ 355elm_table_legacy.h \
@@ -477,7 +479,9 @@ elm_spinner.c \
477elm_store.c \ 479elm_store.c \
478elm_systray.c \ 480elm_systray.c \
479elm_systray_watcher.c \ 481elm_systray_watcher.c \
482elm_sys_notify_interface.c \
480elm_sys_notify.c \ 483elm_sys_notify.c \
484elm_sys_notify_dbus.c \
481elm_table.c \ 485elm_table.c \
482elm_theme.c \ 486elm_theme.c \
483elm_thumb.c \ 487elm_thumb.c \
@@ -594,6 +598,9 @@ elm_separator.eo \
594elm_slider.eo \ 598elm_slider.eo \
595elm_slideshow.eo \ 599elm_slideshow.eo \
596elm_spinner.eo \ 600elm_spinner.eo \
601elm_sys_notify_interface.eo \
602elm_sys_notify.eo \
603elm_sys_notify_dbus.eo \
597elm_systray.eo \ 604elm_systray.eo \
598elm_table.eo \ 605elm_table.eo \
599elm_thumb.eo \ 606elm_thumb.eo \
diff --git a/src/lib/elm_sys_notify.c b/src/lib/elm_sys_notify.c
index 23c936f2f..87536b806 100644
--- a/src/lib/elm_sys_notify.c
+++ b/src/lib/elm_sys_notify.c
@@ -6,372 +6,291 @@
6 6
7#include "elm_priv.h" 7#include "elm_priv.h"
8 8
9#define OBJ "/org/freedesktop/Notifications" 9#include "elm_sys_notify_dbus.eo.h"
10#define BUS "org.freedesktop.Notifications" 10#include "elm_sys_notify_dbus.eo.legacy.h"
11#define INTERFACE "org.freedesktop.Notifications" 11
12#define MY_CLASS ELM_SYS_NOTIFY_CLASS
13
14#define MY_CLASS_NAME "Elm_Sys_Notify"
15#define MY_CLASS_NAME_LEGACY "elm_sys_notify"
12 16
13EAPI int ELM_EVENT_SYS_NOTIFY_NOTIFICATION_CLOSED = 0; 17EAPI int ELM_EVENT_SYS_NOTIFY_NOTIFICATION_CLOSED = 0;
14EAPI int ELM_EVENT_SYS_NOTIFY_ACTION_INVOKED = 0; 18EAPI int ELM_EVENT_SYS_NOTIFY_ACTION_INVOKED = 0;
15 19
16static Eina_Bool _elm_need_sys_notify = EINA_FALSE; 20typedef const Eo_Class *(*Class_Get_Func)(void);
17 21
18static Eldbus_Connection *_elm_sysnotif_conn = NULL; 22static Elm_Sys_Notify *_singleton = NULL;
19static Eldbus_Object *_elm_sysnotif_obj = NULL;
20static Eldbus_Proxy *_elm_sysnotif_proxy = NULL;
21 23
22static Eina_Bool _has_markup = EINA_FALSE; 24/*
25 * Registration of notification servers is done UNIQUELY
26 * in the two structures below.
27 * 1) ALWAYS add a SRV_XXX before __SRV_LAST
28 * 2) copy the #if ... #else ... #endif with the appropriate class
29 * getter (generated by Eolian) or NULL when unsupported
30 *
31 * The rest of the code relies on the Srv enum and _class_getters
32 * to register/unregister notification servers.
33 */
23 34
24typedef struct _Elm_Sys_Notify_Send_Data 35typedef enum
25{ 36{
26 Elm_Sys_Notify_Send_Cb cb; 37 SRV_DBUS = 0,
27 const void *data; 38 __SRV_LAST /* Sentinel */
28} Elm_Sys_Notify_Send_Data; 39} Srv;
29 40
30static void 41static Class_Get_Func _class_getters[__SRV_LAST] =
31_elm_sys_notify_marshal_dict_byte(Eldbus_Message_Iter *array,
32 const char *key,
33 const char value)
34{ 42{
35 Eldbus_Message_Iter *var, *entry; 43#ifdef ELM_SYS_NOTIFY_DBUS_CLASS
44 [SRV_DBUS] = elm_sys_notify_dbus_class_get
45#else
46 [SRV_DBUS] = NULL
47#endif
48};
36 49
37 eldbus_message_iter_arguments_append(array, "{sv}", &entry);
38 eldbus_message_iter_basic_append(entry, 's', key);
39 50
40 var = eldbus_message_iter_container_new(entry, 'v', "y");
41 eldbus_message_iter_basic_append(var, 'y', value);
42 eldbus_message_iter_container_close(entry, var);
43 eldbus_message_iter_container_close(array, entry);
44}
45 51
46static void 52typedef struct
47_elm_sys_notify_marshal_dict_string(Eldbus_Message_Iter *array,
48 const char *key,
49 const char *value)
50{ 53{
51 Eldbus_Message_Iter *var, *entry; 54 Eo *servers[__SRV_LAST];
55} Elm_Sys_Notify_Data;
52 56
53 eldbus_message_iter_arguments_append(array, "{sv}", &entry); 57/*============================================================================*
54 eldbus_message_iter_basic_append(entry, 's', key); 58 * Constructor/Destructor - Singleton setup *
59 *============================================================================*/
55 60
56 var = eldbus_message_iter_container_new(entry, 'v', "s"); 61EOLIAN static Eo_Base *
57 eldbus_message_iter_basic_append(var, 's', value); 62_elm_sys_notify_eo_base_constructor(Eo *obj,
58 eldbus_message_iter_container_close(entry, var); 63 Elm_Sys_Notify_Data *sd EINA_UNUSED)
59 eldbus_message_iter_container_close(array, entry);
60}
61
62static void
63_get_capabilities_cb(void *data EINA_UNUSED,
64 const Eldbus_Message *msg,
65 Eldbus_Pending *pending EINA_UNUSED)
66{ 64{
67 char *val; 65 if (_singleton != NULL)
68 Eldbus_Message_Iter *arr; 66 {
69 67 ERR("Attempted to create another system notification manager");
70 if (eldbus_message_error_get(msg, NULL, NULL) || 68 return NULL;
71 !eldbus_message_arguments_get(msg, "as", &arr)) goto end; 69 }
72 70
73 while (eldbus_message_iter_get_and_next(arr, 's', &val)) 71 obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
74 if (!strcmp(val, "body-markup")) 72 _singleton = obj;
75 {
76 _has_markup = EINA_TRUE;
77 return;
78 }
79 73
80end: 74 return obj;
81 _has_markup = EINA_FALSE;
82} 75}
83 76
84void 77EOLIAN static void
85_elm_sys_notify_capabilities_get(void) 78_elm_sys_notify_eo_base_destructor(Eo *obj,
79 Elm_Sys_Notify_Data *sd EINA_UNUSED)
86{ 80{
87 EINA_SAFETY_ON_NULL_RETURN(_elm_sysnotif_proxy); 81 eo_do_super(obj, MY_CLASS, eo_destructor());
88 82 _singleton = NULL;
89 if (!eldbus_proxy_call(_elm_sysnotif_proxy, "GetCapabilities",
90 _get_capabilities_cb, NULL, -1, ""))
91 ERR("Error sending message: "INTERFACE".GetCapabilities.");
92} 83}
93 84
94static void
95_close_notification_cb(void *data EINA_UNUSED,
96 const Eldbus_Message *msg,
97 Eldbus_Pending *pending EINA_UNUSED)
98{
99 const char *errname, *errmsg;
100
101 if (eldbus_message_error_get(msg, &errname, &errmsg))
102 {
103 if (errmsg && errmsg[0] == '\0')
104 INF("Notification no longer exists.");
105 else
106 ERR("Eldbus Error: %s %s", errname, errmsg);
107 }
108}
109 85
110EAPI void 86/*============================================================================*
111elm_sys_notify_close(unsigned int id) 87 * Notification Interface *
88 *============================================================================*/
89
90EOLIAN static void
91_elm_sys_notify_elm_sys_notify_interface_send(const Eo *obj EINA_UNUSED,
92 Elm_Sys_Notify_Data *sd,
93 unsigned int replaces_id,
94 const char *icon,
95 const char *summary,
96 const char *body,
97 Elm_Sys_Notify_Urgency urgency,
98 int timeout,
99 Elm_Sys_Notify_Send_Cb cb,
100 const void *cb_data)
112{ 101{
113 EINA_SAFETY_ON_FALSE_RETURN(_elm_need_sys_notify); 102 Srv i;
114 EINA_SAFETY_ON_NULL_RETURN(_elm_sysnotif_proxy); 103
115 104 /* Propagate to all registered servers */
116 if (!eldbus_proxy_call(_elm_sysnotif_proxy, "CloseNotification", 105 for (i = SRV_DBUS; i < __SRV_LAST; ++i)
117 _close_notification_cb, NULL, -1, "u", id)) 106 if (sd->servers[i])
118 ERR("Error sending message: "INTERFACE".CloseNotification."); 107 eo_do(sd->servers[i],
108 elm_obj_sys_notify_interface_send(replaces_id,
109 icon, summary, body,
110 urgency, timeout,
111 cb, cb_data));
119} 112}
120 113
121static void 114EOLIAN static void
122_notify_cb(void *data, 115_elm_sys_notify_elm_sys_notify_interface_simple_send(const Eo *obj EINA_UNUSED,
123 const Eldbus_Message *msg, 116 Elm_Sys_Notify_Data *sd,
124 Eldbus_Pending *pending EINA_UNUSED) 117 const char *icon,
118 const char *summary,
119 const char *body)
125{ 120{
126 const char *errname, *errmsg; 121 Srv i;
127 Elm_Sys_Notify_Send_Data *d = data;
128 unsigned int id = 0;
129 122
130 if (eldbus_message_error_get(msg, &errname, &errmsg)) 123 /* Propagate to all registered servers */
131 ERR("Error: %s %s", errname, errmsg); 124 for (i = SRV_DBUS; i < __SRV_LAST; ++i)
132 else if (!eldbus_message_arguments_get(msg, "u", &id)) 125 if (sd->servers[i])
133 { 126 eo_do(sd->servers[i],
134 ERR("Error getting return values of "INTERFACE".Notify."); 127 elm_obj_sys_notify_interface_simple_send(icon, summary, body));
135 id = 0;
136 }
137
138 if (d->cb) d->cb((void *)d->data, id);
139 free(d);
140} 128}
141 129
142EAPI void 130EOLIAN static void
143elm_sys_notify_send(unsigned int replaces_id, const char *icon, 131_elm_sys_notify_elm_sys_notify_interface_close(const Eo *obj EINA_UNUSED,
144 const char *summary, const char *body, 132 Elm_Sys_Notify_Data *sd,
145 Elm_Sys_Notify_Urgency urgency, int timeout, 133 unsigned int id)
146 Elm_Sys_Notify_Send_Cb cb, const void *cb_data)
147{ 134{
148 Eldbus_Message *msg; 135 Srv i;
149 Eldbus_Message_Iter *iter, *actions, *hints;
150 Elm_Sys_Notify_Send_Data *data;
151 char *body_free = NULL;
152 char *desk_free = NULL;
153 const char *deskentry = elm_app_desktop_entry_get();
154 const char *appname = elm_app_name_get();
155
156 EINA_SAFETY_ON_FALSE_RETURN(_elm_need_sys_notify);
157 EINA_SAFETY_ON_NULL_RETURN(_elm_sysnotif_proxy);
158
159 data = malloc(sizeof(Elm_Sys_Notify_Send_Data));
160 EINA_SAFETY_ON_NULL_GOTO(data, error);
161 data->cb = cb;
162 data->data = cb_data;
163
164 if (!icon) icon = "";
165 if (!summary) summary = "";
166 if (!body)
167 body = "";
168 else if (!_has_markup)
169 body = body_free = elm_entry_markup_to_utf8(body);
170
171 msg = eldbus_proxy_method_call_new(_elm_sysnotif_proxy, "Notify");
172
173 iter = eldbus_message_iter_get(msg);
174 eldbus_message_iter_arguments_append(iter, "susssas", appname, replaces_id,
175 icon, summary, body, &actions);
176 /* actions */
177 eldbus_message_iter_container_close(iter, actions);
178
179 /* hints */
180 eldbus_message_iter_arguments_append(iter, "a{sv}", &hints);
181 _elm_sys_notify_marshal_dict_byte(hints, "urgency", (char) urgency);
182
183 if (strcmp(deskentry, ""))
184 {
185 deskentry = ecore_file_file_get(deskentry);
186 deskentry = desk_free = ecore_file_strip_ext(deskentry);
187 _elm_sys_notify_marshal_dict_string(hints, "desktop_entry", deskentry);
188 }
189 eldbus_message_iter_container_close(iter, hints);
190 136
191 /* timeout */ 137 /* Propagate to all registered servers */
192 eldbus_message_iter_arguments_append(iter, "i", timeout); 138 for (i = SRV_DBUS; i < __SRV_LAST; ++i)
139 if (sd->servers[i])
140 eo_do(sd->servers[i],
141 elm_obj_sys_notify_interface_close(id));
142}
193 143
194 eldbus_proxy_send(_elm_sysnotif_proxy, msg, _notify_cb, data, -1);
195 free(desk_free);
196 free(body_free);
197 return;
198 144
199error: 145/*============================================================================*
200 if (cb) cb((void *)cb_data, 0); 146 * Methods *
201} 147 *============================================================================*/
202 148
203static void 149EOLIAN static Eina_Bool
204_on_notification_closed(void *data EINA_UNUSED, 150_elm_sys_notify_servers_set(Eo *obj EINA_UNUSED,
205 const Eldbus_Message *msg) 151 Elm_Sys_Notify_Data *sd,
152 Elm_Sys_Notify_Server servers)
206{ 153{
207 const char *errname; 154 Srv i;
208 const char *errmsg; 155 Class_Get_Func class_get;
209 Elm_Sys_Notify_Notification_Closed *d;
210 156
211 if (eldbus_message_error_get(msg, &errname, &errmsg)) 157 /* Update the notification servers */
158 for (i = SRV_DBUS; i < __SRV_LAST; ++i)
212 { 159 {
213 ERR("Eldbus Error: %s %s", errname, errmsg); 160 if (sd->servers[i])
214 return; 161 {
162 /* Delete if server type is not provided */
163 if (!(servers & (1 << i)))
164 eo_del(sd->servers[i]);
165 }
166 else
167 {
168 /* If server is required, create when nonexistant */
169 if (servers & (1 << i))
170 {
171 class_get = _class_getters[i];
172 if (!class_get)
173 {
174 CRI("Unsupported notification server");
175 return EINA_FALSE;
176 }
177
178 sd->servers[i] = eo_add(class_get(), NULL);
179 if (EINA_UNLIKELY(!(sd->servers[i])))
180 {
181 CRI("Failed to create notification server");
182 return EINA_FALSE;
183 }
184 }
185 }
215 } 186 }
216 187
217 d = malloc(sizeof(*d)); 188 return EINA_TRUE;
218 189}
219 if (!eldbus_message_arguments_get(msg, "uu", &(d->id), &(d->reason)))
220 {
221 ERR("Error processing signal: "INTERFACE".NotificationClosed.");
222 goto cleanup;
223 }
224 190
225 if (!ecore_event_add(ELM_EVENT_SYS_NOTIFY_NOTIFICATION_CLOSED, d, 191EOLIAN static Elm_Sys_Notify_Server
226 NULL, NULL)) goto cleanup; 192_elm_sys_notify_servers_get(Eo *obj EINA_UNUSED,
193 Elm_Sys_Notify_Data *sd)
194{
195 Elm_Sys_Notify_Server servers = ELM_SYS_NOTIFY_SERVER_NONE;
196 Srv i;
227 197
228 return; 198 for (i = SRV_DBUS; i < __SRV_LAST; ++i)
199 if (sd->servers[i])
200 servers |= (1 << i);
229 201
230cleanup: 202 return servers;
231 free(d);
232} 203}
233 204
234static void 205EOLIAN static Elm_Sys_Notify *
235_ev_action_invoked_free(void *data EINA_UNUSED, 206_elm_sys_notify_singleton_get(Eo *obj EINA_UNUSED,
236 void *ev_data) 207 void *sd EINA_UNUSED)
237{ 208{
238 Elm_Sys_Notify_Action_Invoked *d = ev_data; 209 if (!_singleton)
239 210 _singleton = eo_add(MY_CLASS, NULL);
240 free(d->action_key); 211 return _singleton;
241 free(d);
242} 212}
243 213
244static void 214EOLIAN static void
245_on_action_invoked(void *data EINA_UNUSED, 215_elm_sys_notify_class_constructor(Eo_Class *klass EINA_UNUSED)
246 const Eldbus_Message *msg)
247{ 216{
248 const char *errname; 217 ELM_EVENT_SYS_NOTIFY_NOTIFICATION_CLOSED = ecore_event_type_new();
249 const char *aux; 218 ELM_EVENT_SYS_NOTIFY_ACTION_INVOKED = ecore_event_type_new();
250 219}
251 Elm_Sys_Notify_Action_Invoked *d;
252
253 if (eldbus_message_error_get(msg, &errname, &aux))
254 {
255 ERR("Eldbus Error: %s %s", errname, aux);
256 return;
257 }
258
259 d = calloc(1, sizeof(*d));
260 if (!d)
261 {
262 ERR("Fail to allocate memory");
263 return;
264 }
265
266 if (!eldbus_message_arguments_get(msg, "us", &(d->id), &aux))
267 {
268 ERR("Error processing signal: "INTERFACE".ActionInvoked.");
269 goto cleanup;
270 }
271
272 d->action_key = strdup(aux);
273
274 if (!ecore_event_add(ELM_EVENT_SYS_NOTIFY_ACTION_INVOKED, d,
275 _ev_action_invoked_free, NULL)) goto cleanup;
276 220
277 return; 221/*============================================================================*
222 * Legacy API *
223 *============================================================================*/
278 224
279cleanup: 225void
280 free(d->action_key); 226_elm_unneed_sys_notify(void)
281 free(d); 227{
228 eo_do(_singleton,
229 elm_obj_sys_notify_servers_set(ELM_SYS_NOTIFY_SERVER_NONE));
230 eo_del(_singleton);
282} 231}
283 232
284static void 233EAPI Eina_Bool
285_release(void) 234elm_need_sys_notify(void)
286{ 235{
287 if (_elm_sysnotif_proxy) 236 Elm_Sys_Notify_Server servers = ELM_SYS_NOTIFY_SERVER_NONE;
237 Elm_Sys_Notify *manager;
238 Srv i;
239
240 /* In theory, there can be N notification managers, but
241 * in the implementation there will be only one: the
242 * singleton which is initialized here. */
243 manager = elm_sys_notify_singleton_get();
244 if (EINA_UNLIKELY(!manager))
288 { 245 {
289 eldbus_proxy_unref(_elm_sysnotif_proxy); 246 CRI("Failed to get notification manager");
290 _elm_sysnotif_proxy = NULL; 247 return EINA_FALSE;
291 } 248 }
292 249
293 if (_elm_sysnotif_obj) 250 /* If servers have alread been configured, this is not the right
251 * function to be called! */
252 if (elm_sys_notify_servers_get(manager) != ELM_SYS_NOTIFY_SERVER_NONE)
294 { 253 {
295 eldbus_object_unref(_elm_sysnotif_obj); 254 ERR("Notification servers have already been configured. "
296 _elm_sysnotif_obj = NULL; 255 "Use elm_sys_notify_servers_set() instead.");
256 return EINA_FALSE;
297 } 257 }
298}
299 258
300static void 259 /* Register available notification servers */
301_update(void) 260 for (i = SRV_DBUS; i < __SRV_LAST; ++i)
302{ 261 if (_class_getters[i])
303 _release(); 262 servers |= (1 << i);
304 _elm_sysnotif_obj = eldbus_object_get(_elm_sysnotif_conn, BUS, OBJ);
305 _elm_sysnotif_proxy = eldbus_proxy_get(_elm_sysnotif_obj, INTERFACE);
306 _elm_sys_notify_capabilities_get();
307
308 eldbus_proxy_signal_handler_add(_elm_sysnotif_proxy, "NotificationClosed",
309 _on_notification_closed, NULL);
310 263
311 eldbus_proxy_signal_handler_add(_elm_sysnotif_proxy, "ActionInvoked", 264 /* If no server are available, don't even bother... */
312 _on_action_invoked, NULL); 265 if (servers == ELM_SYS_NOTIFY_SERVER_NONE)
313} 266 return EINA_FALSE;
314
315static void
316_name_owner_get_cb(void *data EINA_UNUSED,
317 const Eldbus_Message *msg,
318 Eldbus_Pending *pending EINA_UNUSED)
319{
320 const char *errname, *errmsg;
321 267
322 if (eldbus_message_error_get(msg, &errname, &errmsg)) 268 return elm_sys_notify_servers_set(manager, servers);
323 ERR("Eldbus Error: %s %s", errname, errmsg);
324 else
325 _update();
326} 269}
327 270
328static void 271EAPI void
329_name_owner_changed_cb(void *data EINA_UNUSED, 272elm_sys_notify_send(unsigned int replaces_id,
330 const char *bus EINA_UNUSED, 273 const char *icon,
331 const char *old_id EINA_UNUSED, 274 const char *summary,
332 const char *new_id) 275 const char *body,
276 Elm_Sys_Notify_Urgency urgency,
277 int timeout,
278 Elm_Sys_Notify_Send_Cb cb,
279 const void *cb_data)
333{ 280{
334 if ((!new_id) || (*new_id == '\0')) 281 eo_do(_singleton,
335 _release(); 282 elm_obj_sys_notify_interface_send(replaces_id,
336 else 283 icon, summary, body,
337 _update(); 284 urgency, timeout,
285 cb, cb_data));
338} 286}
339 287
340EAPI Eina_Bool 288EAPI void
341elm_need_sys_notify(void) 289elm_sys_notify_close(unsigned int id)
342{ 290{
343 if (_elm_need_sys_notify) return EINA_TRUE; 291 eo_do(_singleton,
344 292 elm_obj_sys_notify_interface_close(id));
345 if (!elm_need_eldbus()) return EINA_FALSE;
346
347 if (!ELM_EVENT_SYS_NOTIFY_NOTIFICATION_CLOSED)
348 ELM_EVENT_SYS_NOTIFY_NOTIFICATION_CLOSED = ecore_event_type_new();
349
350 if (!ELM_EVENT_SYS_NOTIFY_ACTION_INVOKED)
351 ELM_EVENT_SYS_NOTIFY_ACTION_INVOKED = ecore_event_type_new();
352
353 _elm_sysnotif_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
354
355 eldbus_name_owner_changed_callback_add(_elm_sysnotif_conn, BUS,
356 _name_owner_changed_cb, NULL,
357 EINA_FALSE);
358
359 eldbus_name_owner_get(_elm_sysnotif_conn, BUS, _name_owner_get_cb, NULL);
360
361 _elm_need_sys_notify = EINA_TRUE;
362
363 return EINA_TRUE;
364} 293}
365 294
366void 295#include "elm_sys_notify.eo.c"
367_elm_unneed_sys_notify(void)
368{
369 if (!_elm_need_sys_notify) return;
370
371 _elm_need_sys_notify = EINA_FALSE;
372 296
373 _release();
374
375 eldbus_connection_unref(_elm_sysnotif_conn);
376 _elm_sysnotif_conn = NULL;
377}
diff --git a/src/lib/elm_sys_notify.eo b/src/lib/elm_sys_notify.eo
new file mode 100644
index 000000000..7eb0df2df
--- /dev/null
+++ b/src/lib/elm_sys_notify.eo
@@ -0,0 +1,90 @@
1enum Elm.Sys_Notify.Server
2{
3 none = 0, [[No notificationserver (disables notifications)]]
4 dbus = 1 << 0 [[Use DBus as a notification server]]
5}
6
7enum Elm.Sys_Notify.Closed_Reason
8{
9 [[The reason the notification was closed
10
11 @since 1.8
12 ]]
13
14 legacy: elm_sys_notify_closed;
15
16 expired, [[The notification expired]]
17 dismissed, [[The notification was dismissed by the user]]
18 requested, [[The notification was closed by a call to CloseNotification method]]
19 undefined [[Undefined/reserved reasons]]
20}
21
22struct Elm.Sys_Notify.Notification_Closed
23{
24 [[Data on event when notification closed is emitted
25
26 @since 1.8
27 ]]
28 id: uint; [[ID of the notification]]
29 reason: Elm.Sys_Notify.Closed_Reason; [[The reason the notification was closed]]
30}
31
32struct Elm.Sys_Notify.Action_Invoked
33{
34 [[Data on event when the action invoked is emitted
35
36 @since 1.8
37 ]]
38 id: uint; [[ID of the notification]]
39 action_key: char *; [[The key of the action invoked. These match the
40 keys sent over in the list of actions]]
41}
42
43class Elm.Sys_Notify (Eo.Base, Elm.Sys_Notify_Interface)
44{
45 legacy_prefix: elm_sys_notify;
46 eo_prefix: elm_obj_sys_notify;
47
48 methods {
49 @property servers {
50 get {
51 [[Get the notification servers that have been registered
52
53 @since 1.16
54 ]]
55 }
56 set {
57 [[Set the notifications server to be used.
58
59 Note: This is an advanced function that should be used only to
60 fullfill very specific purposes. Use elm_need_sys_notify()
61 which activates the default available notification
62 servers.
63 ]]
64 return: bool; [[$true on success, $false on failure]]
65 }
66 values {
67 servers: Elm.Sys_Notify.Server; [[Binary mask of servers to enable.
68 If a server is not present in the binary mask but was previously
69 registered, it will be unregistered.]]
70 }
71 }
72
73 singleton_get @class {
74 [[Returns the singleton instance of the notification manager
75 Elm.Sys_Notify. It is initialized upon the first call of this
76 function]]
77 return: Elm.Sys_Notify *; [[The unique notification manager]]
78 }
79 }
80
81 implements {
82 class.constructor;
83 Eo.Base.constructor;
84 Eo.Base.destructor;
85 Elm.Sys_Notify_Interface.send;
86 Elm.Sys_Notify_Interface.simple_send;
87 Elm.Sys_Notify_Interface.close;
88 }
89}
90
diff --git a/src/lib/elm_sys_notify.h b/src/lib/elm_sys_notify.h
index aeff5a006..4534838ca 100644
--- a/src/lib/elm_sys_notify.h
+++ b/src/lib/elm_sys_notify.h
@@ -1,67 +1,25 @@
1#ifndef ELM_SYS_NOTIFY_H 1#ifndef ELM_SYS_NOTIFY_H
2#define ELM_SYS_NOTIFY_H 2#define ELM_SYS_NOTIFY_H
3 3
4/**
5 * The reason the notification was closed
6 *
7 * @since 1.8
8 */
9typedef enum _Elm_Sys_Notify_Closed_Reason
10{
11 ELM_SYS_NOTIFY_CLOSED_EXPIRED, /** The notification expired. */
12 ELM_SYS_NOTIFY_CLOSED_DISMISSED, /** The notification was dismissed by the user. */
13 ELM_SYS_NOTIFY_CLOSED_REQUESTED, /** The notification was closed by a call to CloseNotification method. */
14 ELM_SYS_NOTIFY_CLOSED_UNDEFINED /** Undefined/reserved reasons. */
15} Elm_Sys_Notify_Closed_Reason;
16
17/**
18 * Urgency levels of a notification
19 *
20 * @see elm_sys_notify_send()
21 *
22 * @since 1.8
23 */
24typedef enum _Elm_Sys_Notify_Urgency
25{
26 ELM_SYS_NOTIFY_URGENCY_LOW,
27 ELM_SYS_NOTIFY_URGENCY_NORMAL,
28 ELM_SYS_NOTIFY_URGENCY_CRITICAL
29} Elm_Sys_Notify_Urgency;
30
31typedef void (*Elm_Sys_Notify_Send_Cb)(void *data, unsigned int id); 4typedef void (*Elm_Sys_Notify_Send_Cb)(void *data, unsigned int id);
32 5
6#include "elm_sys_notify_interface.eo.h"
7#include "elm_sys_notify_interface.eo.legacy.h"
8#include "elm_sys_notify.eo.h"
9#include "elm_sys_notify.eo.legacy.h"
10
33/** 11/**
34 * Emitted when the signal NotificationClosed is received. 12 * Emitted when the signal NotificationClosed is received.
13 * @since 1.8
35 */ 14 */
36EAPI extern int ELM_EVENT_SYS_NOTIFY_NOTIFICATION_CLOSED; 15EAPI extern int ELM_EVENT_SYS_NOTIFY_NOTIFICATION_CLOSED;
37 16
38/** 17/**
39 * Emitted when the signal ActionInvoked is received. 18 * Emitted when the signal ActionInvoked is received.
40 */
41EAPI extern int ELM_EVENT_SYS_NOTIFY_ACTION_INVOKED; /**< A Action has been invoked. */
42
43/**
44 * Data on event when Notification Closed is emitted.
45 *
46 * @since 1.8 19 * @since 1.8
47 */ 20 */
48typedef struct _Elm_Sys_Notify_Notification_Closed 21EAPI extern int ELM_EVENT_SYS_NOTIFY_ACTION_INVOKED; /**< A Action has been invoked. */
49{
50 unsigned int id; /**< ID of the notification. */
51 Elm_Sys_Notify_Closed_Reason reason; /**< The Reason the notification was closed. */
52} Elm_Sys_Notify_Notification_Closed;
53
54 22
55/**
56 * Data on event when Action Invoked is emitted.
57 *
58 * @since 1.8
59 */
60typedef struct _Elm_Sys_Notify_Action_Invoked
61{
62 unsigned int id; /**< ID of the notification. */
63 char *action_key; /**< The key of the action invoked. These match the keys sent over in the list of actions. */
64} Elm_Sys_Notify_Action_Invoked;
65 23
66/** 24/**
67 * @def elm_sys_notify_simple_send 25 * @def elm_sys_notify_simple_send
@@ -82,22 +40,9 @@ typedef struct _Elm_Sys_Notify_Action_Invoked
82 -1, NULL, NULL) 40 -1, NULL, NULL)
83 41
84/** 42/**
85 * Causes a notification to be forcefully closed and removed from the user's 43 * Sends a notification to the notification servers that have
86 * view. It can be used, for example, in the event that what the notification 44 * been registered by elm_need_sys_notify() or
87 * pertains to is no longer relevant, or to cancel a notification * with no 45 * elm_sys_notify_servers_set().
88 * expiration time.
89 *
90 * @param id Notification id
91 *
92 * @note If the notification no longer exists,
93 * an empty D-BUS Error message is sent back.
94 *
95 * @since 1.8
96 */
97EAPI void elm_sys_notify_close(unsigned int id);
98
99/**
100 * Sends a notification to the notification server.
101 * 46 *
102 * @param replaces_id Notification ID that this notification replaces. 47 * @param replaces_id Notification ID that this notification replaces.
103 * The value 0 means a new notification. 48 * The value 0 means a new notification.
@@ -120,4 +65,21 @@ EAPI void elm_sys_notify_send(unsigned int replaces_id,
120 int timeout, 65 int timeout,
121 Elm_Sys_Notify_Send_Cb cb, 66 Elm_Sys_Notify_Send_Cb cb,
122 const void *cb_data); 67 const void *cb_data);
68
69/**
70 * Causes a notification to be forcefully closed and removed from the user's
71 * view. It can be used, for example, in the event that what the notification
72 * pertains to is no longer relevant, or to cancel a notification * with no
73 * expiration time.
74 *
75 * @param id Notification id
76 *
77 * @note If the notification no longer exists,
78 * an empty D-BUS Error message is sent back.
79 *
80 * @since 1.8
81 */
82EAPI void elm_sys_notify_close(unsigned int id);
83
123#endif 84#endif
85
diff --git a/src/lib/elm_sys_notify_dbus.c b/src/lib/elm_sys_notify_dbus.c
new file mode 100644
index 000000000..bd0fa1e05
--- /dev/null
+++ b/src/lib/elm_sys_notify_dbus.c
@@ -0,0 +1,398 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#include <Elementary.h>
6
7#include "elm_priv.h"
8
9#include "elm_sys_notify_dbus.eo.h"
10#include "elm_sys_notify_dbus.eo.legacy.h"
11
12#define MY_CLASS ELM_SYS_NOTIFY_DBUS_CLASS
13
14#define OBJ "/org/freedesktop/Notifications"
15#define BUS "org.freedesktop.Notifications"
16#define INTERFACE "org.freedesktop.Notifications"
17
18static Eldbus_Connection *_elm_sysnotif_conn = NULL;
19static Eldbus_Object *_elm_sysnotif_obj = NULL;
20static Eldbus_Proxy *_elm_sysnotif_proxy = NULL;
21
22static Eina_Bool _has_markup = EINA_FALSE;
23
24typedef struct _Elm_Sys_Notify_Send_Data
25{
26 Elm_Sys_Notify_Send_Cb cb;
27 const void *data;
28} Elm_Sys_Notify_Send_Data;
29
30static void
31_elm_sys_notify_marshal_dict_byte(Eldbus_Message_Iter *array,
32 const char *key,
33 const char value)
34{
35 Eldbus_Message_Iter *var, *entry;
36
37 eldbus_message_iter_arguments_append(array, "{sv}", &entry);
38 eldbus_message_iter_basic_append(entry, 's', key);
39
40 var = eldbus_message_iter_container_new(entry, 'v', "y");
41 eldbus_message_iter_basic_append(var, 'y', value);
42 eldbus_message_iter_container_close(entry, var);
43 eldbus_message_iter_container_close(array, entry);
44}
45
46static void
47_elm_sys_notify_marshal_dict_string(Eldbus_Message_Iter *array,
48 const char *key,
49 const char *value)
50{
51 Eldbus_Message_Iter *var, *entry;
52
53 eldbus_message_iter_arguments_append(array, "{sv}", &entry);
54 eldbus_message_iter_basic_append(entry, 's', key);
55
56 var = eldbus_message_iter_container_new(entry, 'v', "s");
57 eldbus_message_iter_basic_append(var, 's', value);
58 eldbus_message_iter_container_close(entry, var);
59 eldbus_message_iter_container_close(array, entry);
60}
61
62static void
63_get_capabilities_cb(void *data EINA_UNUSED,
64 const Eldbus_Message *msg,
65 Eldbus_Pending *pending EINA_UNUSED)
66{
67 char *val;
68 Eldbus_Message_Iter *arr;
69
70 if (eldbus_message_error_get(msg, NULL, NULL) ||
71 !eldbus_message_arguments_get(msg, "as", &arr)) goto end;
72
73 while (eldbus_message_iter_get_and_next(arr, 's', &val))
74 if (!strcmp(val, "body-markup"))
75 {
76 _has_markup = EINA_TRUE;
77 return;
78 }
79
80end:
81 _has_markup = EINA_FALSE;
82}
83
84void
85_elm_sys_notify_capabilities_get(void)
86{
87 EINA_SAFETY_ON_NULL_RETURN(_elm_sysnotif_proxy);
88
89 if (!eldbus_proxy_call(_elm_sysnotif_proxy, "GetCapabilities",
90 _get_capabilities_cb, NULL, -1, ""))
91 ERR("Error sending message: "INTERFACE".GetCapabilities.");
92}
93
94static void
95_close_notification_cb(void *data EINA_UNUSED,
96 const Eldbus_Message *msg,
97 Eldbus_Pending *pending EINA_UNUSED)
98{
99 const char *errname, *errmsg;
100
101 if (eldbus_message_error_get(msg, &errname, &errmsg))
102 {
103 if (errmsg && errmsg[0] == '\0')
104 INF("Notification no longer exists.");
105 else
106 ERR("Eldbus Error: %s %s", errname, errmsg);
107 }
108}
109
110EOLIAN static void
111_elm_sys_notify_dbus_elm_sys_notify_interface_close(const Eo *obj EINA_UNUSED,
112 void *sd EINA_UNUSED,
113 unsigned int id)
114{
115 EINA_SAFETY_ON_NULL_RETURN(_elm_sysnotif_proxy);
116
117 if (!eldbus_proxy_call(_elm_sysnotif_proxy, "CloseNotification",
118 _close_notification_cb, NULL, -1, "u", id))
119 ERR("Error sending message: "INTERFACE".CloseNotification.");
120}
121
122static void
123_notify_cb(void *data,
124 const Eldbus_Message *msg,
125 Eldbus_Pending *pending EINA_UNUSED)
126{
127 const char *errname, *errmsg;
128 Elm_Sys_Notify_Send_Data *d = data;
129 unsigned int id = 0;
130
131 if (eldbus_message_error_get(msg, &errname, &errmsg))
132 ERR("Error: %s %s", errname, errmsg);
133 else if (!eldbus_message_arguments_get(msg, "u", &id))
134 {
135 ERR("Error getting return values of "INTERFACE".Notify.");
136 id = 0;
137 }
138
139 if (d->cb) d->cb((void *)d->data, id);
140 free(d);
141}
142
143EOLIAN static void
144_elm_sys_notify_dbus_elm_sys_notify_interface_send(const Eo *obj EINA_UNUSED,
145 void *sd EINA_UNUSED,
146 unsigned int replaces_id,
147 const char *icon,
148 const char *summary,
149 const char *body,
150 Elm_Sys_Notify_Urgency urgency,
151 int timeout,
152 Elm_Sys_Notify_Send_Cb cb,
153 const void *cb_data)
154{
155 Eldbus_Message *msg;
156 Eldbus_Message_Iter *iter, *actions, *hints;
157 Elm_Sys_Notify_Send_Data *data;
158 char *body_free = NULL;
159 char *desk_free = NULL;
160 const char *deskentry = elm_app_desktop_entry_get();
161 const char *appname = elm_app_name_get();
162
163 EINA_SAFETY_ON_NULL_RETURN(_elm_sysnotif_proxy);
164
165 data = malloc(sizeof(Elm_Sys_Notify_Send_Data));
166 EINA_SAFETY_ON_NULL_GOTO(data, error);
167 data->cb = cb;
168 data->data = cb_data;
169
170 if (!icon) icon = "";
171 if (!summary) summary = "";
172 if (!body)
173 body = "";
174 else if (!_has_markup)
175 body = body_free = elm_entry_markup_to_utf8(body);
176
177 msg = eldbus_proxy_method_call_new(_elm_sysnotif_proxy, "Notify");
178
179 iter = eldbus_message_iter_get(msg);
180 eldbus_message_iter_arguments_append(iter, "susssas", appname, replaces_id,
181 icon, summary, body, &actions);
182 /* actions */
183 eldbus_message_iter_container_close(iter, actions);
184
185 /* hints */
186 eldbus_message_iter_arguments_append(iter, "a{sv}", &hints);
187 _elm_sys_notify_marshal_dict_byte(hints, "urgency", (char) urgency);
188
189 if (strcmp(deskentry, ""))
190 {
191 deskentry = ecore_file_file_get(deskentry);
192 deskentry = desk_free = ecore_file_strip_ext(deskentry);
193 _elm_sys_notify_marshal_dict_string(hints, "desktop_entry", deskentry);
194 }
195 eldbus_message_iter_container_close(iter, hints);
196
197 /* timeout */
198 eldbus_message_iter_arguments_append(iter, "i", timeout);
199
200 eldbus_proxy_send(_elm_sysnotif_proxy, msg, _notify_cb, data, -1);
201 free(desk_free);
202 free(body_free);
203 return;
204
205error:
206 if (cb) cb((void *)cb_data, 0);
207}
208
209EOLIAN static void
210_elm_sys_notify_dbus_elm_sys_notify_interface_simple_send(const Eo *obj,
211 void *sd,
212 const char *icon,
213 const char *summary,
214 const char *body)
215{
216 _elm_sys_notify_dbus_elm_sys_notify_interface_send(obj, sd,
217 0, icon, summary, body,
218 ELM_SYS_NOTIFY_URGENCY_NORMAL,
219 -1, NULL, NULL);
220}
221
222static void
223_on_notification_closed(void *data EINA_UNUSED,
224 const Eldbus_Message *msg)
225{
226 const char *errname;
227 const char *errmsg;
228 Elm_Sys_Notify_Notification_Closed *d;
229
230 if (eldbus_message_error_get(msg, &errname, &errmsg))
231 {
232 ERR("Eldbus Error: %s %s", errname, errmsg);
233 return;
234 }
235
236 d = malloc(sizeof(*d));
237
238 if (!eldbus_message_arguments_get(msg, "uu", &(d->id), &(d->reason)))
239 {
240 ERR("Error processing signal: "INTERFACE".NotificationClosed.");
241 goto cleanup;
242 }
243
244 if (!ecore_event_add(ELM_EVENT_SYS_NOTIFY_NOTIFICATION_CLOSED, d,
245 NULL, NULL)) goto cleanup;
246
247 return;
248
249cleanup:
250 free(d);
251}
252
253static void
254_ev_action_invoked_free(void *data EINA_UNUSED,
255 void *ev_data)
256{
257 Elm_Sys_Notify_Action_Invoked *d = ev_data;
258
259 free(d->action_key);
260 free(d);
261}
262
263static void
264_on_action_invoked(void *data EINA_UNUSED,
265 const Eldbus_Message *msg)
266{
267 const char *errname;
268 const char *aux;
269
270 Elm_Sys_Notify_Action_Invoked *d;
271
272 if (eldbus_message_error_get(msg, &errname, &aux))
273 {
274 ERR("Eldbus Error: %s %s", errname, aux);
275 return;
276 }
277
278 d = calloc(1, sizeof(*d));
279 if (!d)
280 {
281 ERR("Fail to allocate memory");
282 return;
283 }
284
285 if (!eldbus_message_arguments_get(msg, "us", &(d->id), &aux))
286 {
287 ERR("Error processing signal: "INTERFACE".ActionInvoked.");
288 goto cleanup;
289 }
290
291 d->action_key = strdup(aux);
292
293 if (!ecore_event_add(ELM_EVENT_SYS_NOTIFY_ACTION_INVOKED, d,
294 _ev_action_invoked_free, NULL)) goto cleanup;
295
296 return;
297
298cleanup:
299 free(d->action_key);
300 free(d);
301}
302
303static void
304_release(void)
305{
306 if (_elm_sysnotif_proxy)
307 {
308 eldbus_proxy_unref(_elm_sysnotif_proxy);
309 _elm_sysnotif_proxy = NULL;
310 }
311
312 if (_elm_sysnotif_obj)
313 {
314 eldbus_object_unref(_elm_sysnotif_obj);
315 _elm_sysnotif_obj = NULL;
316 }
317}
318
319static void
320_update(void)
321{
322 _release();
323 _elm_sysnotif_obj = eldbus_object_get(_elm_sysnotif_conn, BUS, OBJ);
324 _elm_sysnotif_proxy = eldbus_proxy_get(_elm_sysnotif_obj, INTERFACE);
325 _elm_sys_notify_capabilities_get();
326
327 eldbus_proxy_signal_handler_add(_elm_sysnotif_proxy, "NotificationClosed",
328 _on_notification_closed, NULL);
329
330 eldbus_proxy_signal_handler_add(_elm_sysnotif_proxy, "ActionInvoked",
331 _on_action_invoked, NULL);
332}
333
334static void
335_name_owner_get_cb(void *data EINA_UNUSED,
336 const Eldbus_Message *msg,
337 Eldbus_Pending *pending EINA_UNUSED)
338{
339 const char *errname, *errmsg;
340
341 if (eldbus_message_error_get(msg, &errname, &errmsg))
342 ERR("Eldbus Error: %s %s", errname, errmsg);
343 else
344 _update();
345}
346
347static void
348_name_owner_changed_cb(void *data EINA_UNUSED,
349 const char *bus EINA_UNUSED,
350 const char *old_id EINA_UNUSED,
351 const char *new_id)
352{
353 if ((!new_id) || (*new_id == '\0'))
354 _release();
355 else
356 _update();
357}
358
359EOLIAN static Eo_Base *
360_elm_sys_notify_dbus_eo_base_constructor(Eo *obj,
361 void *sd EINA_UNUSED)
362{
363 /* Don't create the same object twice (singleton) */
364 if (!_elm_sysnotif_conn)
365 {
366 if (!elm_need_eldbus()) return NULL;
367
368 _elm_sysnotif_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
369 if (!_elm_sysnotif_conn) return NULL;
370
371 eldbus_name_owner_changed_callback_add(_elm_sysnotif_conn, BUS,
372 _name_owner_changed_cb, NULL,
373 EINA_FALSE);
374
375 eldbus_name_owner_get(_elm_sysnotif_conn, BUS, _name_owner_get_cb, NULL);
376
377 obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
378 return obj;
379 }
380
381 ERR("Elm.Sys_Notify.Dbus is a singleton. It has already been created");
382 return NULL;
383}
384
385EOLIAN static void
386_elm_sys_notify_dbus_eo_base_destructor(Eo *obj,
387 void *sd EINA_UNUSED)
388{
389 _release();
390
391 eldbus_connection_unref(_elm_sysnotif_conn);
392 _elm_sysnotif_conn = NULL;
393 eo_do_super(obj, MY_CLASS, eo_destructor());
394}
395
396
397#include "elm_sys_notify_dbus.eo.c"
398
diff --git a/src/lib/elm_sys_notify_dbus.eo b/src/lib/elm_sys_notify_dbus.eo
new file mode 100644
index 000000000..df8eb9c85
--- /dev/null
+++ b/src/lib/elm_sys_notify_dbus.eo
@@ -0,0 +1,14 @@
1class Elm.Sys_Notify.Dbus (Eo.Base, Elm.Sys_Notify_Interface)
2{
3 eo_prefix: elm_obj_sys_notify_dbus;
4 data: null;
5
6 implements {
7 Eo.Base.constructor;
8 Eo.Base.destructor;
9 Elm.Sys_Notify_Interface.send;
10 Elm.Sys_Notify_Interface.simple_send;
11 Elm.Sys_Notify_Interface.close;
12 }
13}
14
diff --git a/src/lib/elm_sys_notify_interface.c b/src/lib/elm_sys_notify_interface.c
new file mode 100644
index 000000000..c630afec6
--- /dev/null
+++ b/src/lib/elm_sys_notify_interface.c
@@ -0,0 +1,9 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#include <Elementary.h>
6
7#include "elm_priv.h"
8#include "elm_sys_notify_interface.eo.c"
9
diff --git a/src/lib/elm_sys_notify_interface.eo b/src/lib/elm_sys_notify_interface.eo
new file mode 100644
index 000000000..627586b09
--- /dev/null
+++ b/src/lib/elm_sys_notify_interface.eo
@@ -0,0 +1,66 @@
1enum Elm.Sys_Notify.Urgency
2{
3 [[Urgency levels of a notification
4
5 @since 1.8
6 ]]
7 low, [[Low urgency]]
8 normal, [[Normal urgency]]
9 critical [[Critical urgency]]
10}
11
12interface Elm.Sys_Notify_Interface
13{
14 eo_prefix: elm_obj_sys_notify_interface;
15 legacy_prefix: elm_sys_notify_interface;
16
17 methods {
18 send @const {
19 [[Causes a notification to be forcefully closed and removed from the
20 user's view. It can be used, for example, in the event that what the
21 notification pertains to is no longer relevant, or to cancel a
22 notification with no expiration time.
23
24 @since 1.8
25 ]]
26 params {
27 @in replaces_id: uint; [[Notification ID that this notification replaces.
28 The value 0 means a new notification.]]
29 @in icon: const(char) *; [[The optional program icon of the calling application]]
30 @in summary: const(char) *; [[The summary text briefly describing the notification]]
31 @in body: const(char) * @optional; [[The optional detailed body text. Can be empty]]
32 @in urgency: Elm.Sys_Notify.Urgency; [[The urgency level]]
33 @in timeout: int; [[Timeout display in milliseconds]]
34 @in cb: Elm_Sys_Notify_Send_Cb; [[Callback used to retrieve the notification id
35 returned by the Notification Server]]
36 @in cb_data: const(void) * @optional; [[Optional context data]]
37 }
38 }
39 simple_send @const {
40 [[Create a new notification just with Icon, Body and Summary.
41 It is a helper that wraps the send method
42
43 @since 1.16
44 ]]
45
46 params {
47 @in icon: const(char) *; [[The optional program icon of the calling application]]
48 @in summary: const(char) *; [[The summary text briefly describing the notification]]
49 @in body: const(char) *; [[The optional detailed body text. Can be empty]]
50 }
51 }
52 close @const {
53 [[Causes a notification to be forcefully closed and removed from the
54 user's view. It can be used, for example, in the event that what the
55 notification pertains to is no longer relevant, or to cancel a
56 notification with no expiration time.
57
58 @since 1.8
59 ]]
60 params {
61 @in id: uint; [[Notification ID]]
62 }
63 }
64 }
65}
66