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_interface_eo.h"
10 #include "elm_sys_notify_eo.h"
11 #include "elm_sys_notify_dbus_eo.h"
12 #include "elm_sys_notify_dbus_eo.legacy.h"
13
14 #define MY_CLASS ELM_SYS_NOTIFY_CLASS
15
16 #define MY_CLASS_NAME "Elm_Sys_Notify"
17 #define MY_CLASS_NAME_LEGACY "elm_sys_notify"
18
19 EAPI int ELM_EVENT_SYS_NOTIFY_NOTIFICATION_CLOSED = 0;
20 EAPI int ELM_EVENT_SYS_NOTIFY_ACTION_INVOKED = 0;
21
22 typedef const Efl_Class *(*Class_Get_Func)(void);
23
24 static Elm_Sys_Notify *_singleton = NULL;
25
26 /*
27 * Registration of notification servers is done UNIQUELY
28 * in the two structures below.
29 * 1) ALWAYS add a SRV_XXX before __SRV_LAST
30 * 2) copy the #if ... #else ... #endif with the appropriate class
31 * getter (generated by Eolian) or NULL when unsupported
32 *
33 * The rest of the code relies on the Srv enum and _class_getters
34 * to register/unregister notification servers.
35 */
36
37 typedef enum
38 {
39 SRV_DBUS = 0,
40 __SRV_LAST /* Sentinel */
41 } Srv;
42
43 static Class_Get_Func _class_getters[__SRV_LAST] =
44 {
45 #ifdef ELM_SYS_NOTIFY_DBUS_CLASS
46 [SRV_DBUS] = elm_sys_notify_dbus_class_get
47 #else
48 [SRV_DBUS] = NULL
49 #endif
50 };
51
52
53
54 typedef struct
55 {
56 Eo *servers[__SRV_LAST];
57 } Elm_Sys_Notify_Data;
58
59 /*============================================================================*
60 * Constructor/Destructor - Singleton setup *
61 *============================================================================*/
62
63 EOLIAN static Efl_Object *
_elm_sys_notify_efl_object_constructor(Eo * obj,Elm_Sys_Notify_Data * sd EINA_UNUSED)64 _elm_sys_notify_efl_object_constructor(Eo *obj,
65 Elm_Sys_Notify_Data *sd EINA_UNUSED)
66 {
67 if (_singleton != NULL)
68 {
69 ERR("Attempted to create another system notification manager");
70 return NULL;
71 }
72
73 obj = efl_constructor(efl_super(obj, MY_CLASS));
74 _singleton = obj;
75
76 return obj;
77 }
78
79 EOLIAN static void
_elm_sys_notify_efl_object_destructor(Eo * obj,Elm_Sys_Notify_Data * sd EINA_UNUSED)80 _elm_sys_notify_efl_object_destructor(Eo *obj,
81 Elm_Sys_Notify_Data *sd EINA_UNUSED)
82 {
83 efl_destructor(efl_super(obj, MY_CLASS));
84 _singleton = NULL;
85 }
86
87
88 /*============================================================================*
89 * Notification Interface *
90 *============================================================================*/
91
92 EOLIAN static void
_elm_sys_notify_elm_sys_notify_interface_send(const Eo * obj EINA_UNUSED,Elm_Sys_Notify_Data * sd,unsigned int replaces_id,const char * icon,const char * summary,const char * body,Elm_Sys_Notify_Urgency urgency,int timeout,Elm_Sys_Notify_Send_Cb cb,const void * cb_data)93 _elm_sys_notify_elm_sys_notify_interface_send(const Eo *obj EINA_UNUSED,
94 Elm_Sys_Notify_Data *sd,
95 unsigned int replaces_id,
96 const char *icon,
97 const char *summary,
98 const char *body,
99 Elm_Sys_Notify_Urgency urgency,
100 int timeout,
101 Elm_Sys_Notify_Send_Cb cb,
102 const void *cb_data)
103 {
104 Srv i;
105
106 /* Propagate to all registered servers */
107 for (i = SRV_DBUS; i < __SRV_LAST; ++i)
108 if (sd->servers[i])
109 elm_obj_sys_notify_interface_send(sd->servers[i], replaces_id, icon, summary, body, urgency, timeout, cb, cb_data);
110 }
111
112 EOLIAN static void
_elm_sys_notify_elm_sys_notify_interface_simple_send(const Eo * obj EINA_UNUSED,Elm_Sys_Notify_Data * sd,const char * icon,const char * summary,const char * body)113 _elm_sys_notify_elm_sys_notify_interface_simple_send(const Eo *obj EINA_UNUSED,
114 Elm_Sys_Notify_Data *sd,
115 const char *icon,
116 const char *summary,
117 const char *body)
118 {
119 Srv i;
120
121 /* Propagate to all registered servers */
122 for (i = SRV_DBUS; i < __SRV_LAST; ++i)
123 if (sd->servers[i])
124 elm_obj_sys_notify_interface_simple_send(sd->servers[i], icon, summary, body);
125 }
126
127 EOLIAN static void
_elm_sys_notify_elm_sys_notify_interface_close(const Eo * obj EINA_UNUSED,Elm_Sys_Notify_Data * sd,unsigned int id)128 _elm_sys_notify_elm_sys_notify_interface_close(const Eo *obj EINA_UNUSED,
129 Elm_Sys_Notify_Data *sd,
130 unsigned int id)
131 {
132 Srv i;
133
134 /* Propagate to all registered servers */
135 for (i = SRV_DBUS; i < __SRV_LAST; ++i)
136 if (sd->servers[i])
137 elm_obj_sys_notify_interface_close(sd->servers[i], id);
138 }
139
140
141 /*============================================================================*
142 * Methods *
143 *============================================================================*/
144
145 EOLIAN static Eina_Bool
_elm_sys_notify_servers_set(Eo * obj EINA_UNUSED,Elm_Sys_Notify_Data * sd,Elm_Sys_Notify_Server servers)146 _elm_sys_notify_servers_set(Eo *obj EINA_UNUSED,
147 Elm_Sys_Notify_Data *sd,
148 Elm_Sys_Notify_Server servers)
149 {
150 Srv i;
151 Class_Get_Func class_get;
152
153 /* Update the notification servers */
154 for (i = SRV_DBUS; i < __SRV_LAST; ++i)
155 {
156 if (sd->servers[i])
157 {
158 /* Delete if server type is not provided */
159 if (!(servers & (1 << i)))
160 efl_del(sd->servers[i]);
161 }
162 else
163 {
164 /* If server is required, create when nonexistant */
165 if (servers & (1 << i))
166 {
167 class_get = _class_getters[i];
168 if (!class_get)
169 {
170 CRI("Unsupported notification server");
171 return EINA_FALSE;
172 }
173
174 sd->servers[i] = efl_add(class_get(), NULL);
175 if (EINA_UNLIKELY(!(sd->servers[i])))
176 {
177 CRI("Failed to create notification server");
178 return EINA_FALSE;
179 }
180 }
181 }
182 }
183
184 return EINA_TRUE;
185 }
186
187 EOLIAN static Elm_Sys_Notify_Server
_elm_sys_notify_servers_get(const Eo * obj EINA_UNUSED,Elm_Sys_Notify_Data * sd)188 _elm_sys_notify_servers_get(const Eo *obj EINA_UNUSED,
189 Elm_Sys_Notify_Data *sd)
190 {
191 Elm_Sys_Notify_Server servers = ELM_SYS_NOTIFY_SERVER_NONE;
192 Srv i;
193
194 for (i = SRV_DBUS; i < __SRV_LAST; ++i)
195 if (sd->servers[i])
196 servers |= (1 << i);
197
198 return servers;
199 }
200
201 EOLIAN static Elm_Sys_Notify *
_elm_sys_notify_singleton_get(void)202 _elm_sys_notify_singleton_get(void)
203 {
204 if (!_singleton)
205 _singleton = efl_add(MY_CLASS, efl_main_loop_get());
206 return _singleton;
207 }
208
209 EOLIAN static void
_elm_sys_notify_class_constructor(Efl_Class * klass EINA_UNUSED)210 _elm_sys_notify_class_constructor(Efl_Class *klass EINA_UNUSED)
211 {
212 ELM_EVENT_SYS_NOTIFY_NOTIFICATION_CLOSED = ecore_event_type_new();
213 ELM_EVENT_SYS_NOTIFY_ACTION_INVOKED = ecore_event_type_new();
214 }
215
216 /*============================================================================*
217 * Legacy API *
218 *============================================================================*/
219
220 void
_elm_unneed_sys_notify(void)221 _elm_unneed_sys_notify(void)
222 {
223 Elm_Sys_Notify *manager = elm_obj_sys_notify_singleton_get();
224 if (manager)
225 {
226 elm_obj_sys_notify_servers_set(manager, ELM_SYS_NOTIFY_SERVER_NONE);
227 efl_del(manager);
228 }
229 }
230
231 EAPI Eina_Bool
elm_need_sys_notify(void)232 elm_need_sys_notify(void)
233 {
234 Elm_Sys_Notify_Server servers = ELM_SYS_NOTIFY_SERVER_NONE;
235 Elm_Sys_Notify *manager;
236 Srv i;
237
238 /* In theory, there can be N notification managers, but
239 * in the implementation there will be only one: the
240 * singleton which is initialized here. */
241 manager = elm_obj_sys_notify_singleton_get();
242 if (EINA_UNLIKELY(!manager))
243 {
244 CRI("Failed to get notification manager");
245 return EINA_FALSE;
246 }
247
248 /* If servers have alread been configured, this is not the right
249 * function to be called! */
250 if (elm_sys_notify_servers_get(manager) != ELM_SYS_NOTIFY_SERVER_NONE)
251 {
252 ERR("Notification servers have already been configured. "
253 "Use elm_sys_notify_servers_set() instead.");
254 return EINA_FALSE;
255 }
256
257 /* Register available notification servers */
258 for (i = SRV_DBUS; i < __SRV_LAST; ++i)
259 if (_class_getters[i])
260 servers |= (1 << i);
261
262 /* If no server are available, don't even bother... */
263 if (servers == ELM_SYS_NOTIFY_SERVER_NONE)
264 return EINA_FALSE;
265
266 return elm_sys_notify_servers_set(manager, servers);
267 }
268
269 EAPI void
elm_sys_notify_send(unsigned int replaces_id,const char * icon,const char * summary,const char * body,Elm_Sys_Notify_Urgency urgency,int timeout,Elm_Sys_Notify_Send_Cb cb,const void * cb_data)270 elm_sys_notify_send(unsigned int replaces_id,
271 const char *icon,
272 const char *summary,
273 const char *body,
274 Elm_Sys_Notify_Urgency urgency,
275 int timeout,
276 Elm_Sys_Notify_Send_Cb cb,
277 const void *cb_data)
278 {
279 elm_obj_sys_notify_interface_send(_singleton, replaces_id, icon, summary, body, urgency, timeout, cb, cb_data);
280 }
281
282 EAPI void
elm_sys_notify_close(unsigned int id)283 elm_sys_notify_close(unsigned int id)
284 {
285 elm_obj_sys_notify_interface_close(_singleton, id);
286 }
287
288 #include "elm_sys_notify_eo.c"
289
290