1 #include "e_mod_main.h"
2 
3 /* Config function protos */
4 static Config *_notification_cfg_new(void);
5 static void    _notification_cfg_free(Config *cfg);
6 
7 /* Global variables */
8 E_Module *notification_mod = NULL;
9 Config *notification_cfg = NULL;
10 
11 static E_Config_DD *conf_edd = NULL;
12 
13 static unsigned int offline_id;
14 static unsigned int pres_id;
15 
16 static unsigned int
_notification_notify(E_Notification_Notify * n)17 _notification_notify(E_Notification_Notify *n)
18 {
19    unsigned int new_id;
20 
21    if (e_desklock_state_get()) return 0;
22 
23    notification_cfg->next_id++;
24    new_id = notification_cfg->next_id;
25    notification_popup_notify(n, new_id);
26 
27    return new_id;
28 }
29 
30 static void
_notification_id_update(void * d,unsigned int id)31 _notification_id_update(void *d, unsigned int id)
32 {
33    uintptr_t *update_id = d;
34 
35    *update_id = id;
36 }
37 
38 static void
_notification_show_common(const char * summary,const char * body,unsigned int * update_id)39 _notification_show_common(const char *summary,
40                           const char *body,
41                           unsigned int *update_id)
42 {
43    E_Notification_Notify n;
44    memset(&n, 0, sizeof(E_Notification_Notify));
45    n.app_name = "enlightenment";
46    n.replaces_id = *update_id;
47    n.icon.icon = "enlightenment";
48    n.summary = summary;
49    n.body = body;
50    n.urgency = E_NOTIFICATION_NOTIFY_URGENCY_CRITICAL;
51    e_notification_client_send(&n, _notification_id_update, update_id);
52 }
53 
54 static void
_notification_show_presentation(Eina_Bool enabled)55 _notification_show_presentation(Eina_Bool enabled)
56 {
57    const char *summary, *body;
58 
59    if (enabled)
60      {
61         summary = _("Entered Presentation Mode");
62         body = _("Enlightenment has now entered <b>presentation</b> mode."
63                  "<ps/>During presentation mode, screen saver, lock and "
64                  "power saving will be disabled so you are not interrupted.");
65      }
66    else
67      {
68         summary = _("Exited Presentation Mode");
69         body = _("Presentation mode has been exited."
70                  "<ps/>Now screen saver, lock and "
71                  "power saving settings will be restored.");
72      }
73 
74    _notification_show_common(summary, body, &pres_id);
75 }
76 
77 static void
_notification_show_offline(Eina_Bool enabled)78 _notification_show_offline(Eina_Bool enabled)
79 {
80    const char *summary, *body;
81 
82    if (enabled)
83      {
84         summary = _("Enter Offline Mode");
85         body = _("Enlightenment is in <b>offline</b> mode.<ps/>"
86                  "During offline mode, modules that use network will stop "
87                  "polling remote services.");
88      }
89    else
90      {
91         summary = _("Exited Offline Mode");
92         body = _("Now in <b>online</b> mode.<ps/>"
93                  "Now modules that use network will "
94                  "resume regular tasks.");
95      }
96 
97    _notification_show_common(summary, body, &offline_id);
98 }
99 
100 static Eina_Bool
_notification_cb_config_mode_changed(Config * m_cfg,int type EINA_UNUSED,void * event EINA_UNUSED)101 _notification_cb_config_mode_changed(Config *m_cfg,
102                                      int   type EINA_UNUSED,
103                                      void *event EINA_UNUSED)
104 {
105    if (m_cfg->last_config_mode.presentation != e_config->mode.presentation)
106      {
107         m_cfg->last_config_mode.presentation = e_config->mode.presentation;
108         _notification_show_presentation(e_config->mode.presentation);
109      }
110 
111    if (m_cfg->last_config_mode.offline != e_config->mode.offline)
112      {
113         m_cfg->last_config_mode.offline = e_config->mode.offline;
114         _notification_show_offline(e_config->mode.offline);
115      }
116 
117    return EINA_TRUE;
118 }
119 
120 static Eina_Bool
_notification_cb_initial_mode_timer(Config * m_cfg)121 _notification_cb_initial_mode_timer(Config *m_cfg)
122 {
123    if (e_config->mode.presentation)
124      _notification_show_presentation(1);
125    if (e_config->mode.offline)
126      _notification_show_offline(1);
127 
128    m_cfg->initial_mode_timer = NULL;
129    return EINA_FALSE;
130 }
131 
132 /* Module Api Functions */
133 E_API E_Module_Api e_modapi = {E_MODULE_API_VERSION, "Notification"};
134 
135 static const E_Notification_Server_Info server_info = {
136    .name = "e17",
137    .vendor = "enlightenment.org",
138    .version = "0.17",
139    .spec_version = "1.2",
140    .capabilities = { "body", "body-markup", NULL }
141 };
142 
143 /* Callbacks */
144 static unsigned int
_notification_cb_notify(void * data EINA_UNUSED,E_Notification_Notify * n)145 _notification_cb_notify(void *data EINA_UNUSED, E_Notification_Notify *n)
146 {
147    return _notification_notify(n);
148 }
149 
150 static void
_notification_cb_close(void * data EINA_UNUSED,unsigned int id)151 _notification_cb_close(void *data EINA_UNUSED, unsigned int id)
152 {
153    notification_popup_close(id);
154 }
155 
156 E_API void *
e_modapi_init(E_Module * m)157 e_modapi_init(E_Module *m)
158 {
159    char buf[PATH_MAX];
160 
161    snprintf(buf, sizeof(buf), "%s/e-module-notification.edj", m->dir);
162    /* register config panel entry */
163    e_configure_registry_category_add("extensions", 90, _("Extensions"), NULL,
164                                      "preferences-extensions");
165    e_configure_registry_item_add("extensions/notification", 30,
166                                  _("Notification"), NULL,
167                                  buf, e_int_config_notification_module);
168 
169 
170    conf_edd = E_CONFIG_DD_NEW("Notification_Config", Config);
171 #undef T
172 #undef D
173 #define T Config
174 #define D conf_edd
175    E_CONFIG_VAL(D, T, version, INT);
176    E_CONFIG_VAL(D, T, show_low, INT);
177    E_CONFIG_VAL(D, T, show_normal, INT);
178    E_CONFIG_VAL(D, T, show_critical, INT);
179    E_CONFIG_VAL(D, T, corner, INT);
180    E_CONFIG_VAL(D, T, timeout, FLOAT);
181    E_CONFIG_VAL(D, T, force_timeout, INT);
182    E_CONFIG_VAL(D, T, ignore_replacement, INT);
183    E_CONFIG_VAL(D, T, dual_screen, INT);
184 
185    notification_cfg = e_config_domain_load("module.notification", conf_edd);
186    if (notification_cfg &&
187        !(e_util_module_config_check(_("Notification Module"),
188                                     notification_cfg->version,
189                                     MOD_CONFIG_FILE_VERSION)))
190      {
191         _notification_cfg_free(notification_cfg);
192         notification_cfg = NULL;
193      }
194 
195    if (!notification_cfg)
196      notification_cfg = _notification_cfg_new();
197    /* upgrades */
198    if (notification_cfg->version - (MOD_CONFIG_FILE_EPOCH * 1000000) < 1)
199      {
200         if (notification_cfg->dual_screen) notification_cfg->dual_screen = POPUP_DISPLAY_POLICY_MULTI;
201      }
202    notification_cfg->version = MOD_CONFIG_FILE_VERSION;
203 
204    /* set up the notification daemon */
205    if (!e_notification_server_register(&server_info, _notification_cb_notify,
206                                        _notification_cb_close, NULL))
207      {
208         e_util_dialog_show(_("Error during notification server initialization"),
209                            _("Ensure there's no other module acting as a server "
210                              "and that D-Bus is correctly installed and "
211                              "running"));
212         return NULL;
213      }
214 
215    notification_cfg->last_config_mode.presentation = e_config->mode.presentation;
216    notification_cfg->last_config_mode.offline = e_config->mode.offline;
217    notification_cfg->handler = ecore_event_handler_add
218          (E_EVENT_CONFIG_MODE_CHANGED, (Ecore_Event_Handler_Cb)_notification_cb_config_mode_changed,
219          notification_cfg);
220    notification_cfg->initial_mode_timer = ecore_timer_loop_add
221        (0.1, (Ecore_Task_Cb)_notification_cb_initial_mode_timer, notification_cfg);
222 
223    notification_mod = m;
224 
225    return m;
226 }
227 
228 E_API int
e_modapi_shutdown(E_Module * m EINA_UNUSED)229 e_modapi_shutdown(E_Module *m EINA_UNUSED)
230 {
231    if (notification_cfg->initial_mode_timer)
232      ecore_timer_del(notification_cfg->initial_mode_timer);
233 
234    if (notification_cfg->handler)
235      ecore_event_handler_del(notification_cfg->handler);
236 
237    if (notification_cfg->cfd) e_object_del(E_OBJECT(notification_cfg->cfd));
238    e_configure_registry_item_del("extensions/notification");
239    e_configure_registry_category_del("extensions");
240 
241    notification_popup_shutdown();
242    e_notification_server_unregister();
243 
244 
245    _notification_cfg_free(notification_cfg);
246    E_CONFIG_DD_FREE(conf_edd);
247    notification_mod = NULL;
248 
249    return 1;
250 }
251 
252 E_API int
e_modapi_save(E_Module * m EINA_UNUSED)253 e_modapi_save(E_Module *m EINA_UNUSED)
254 {
255    return e_config_domain_save("module.notification", conf_edd, notification_cfg);
256 }
257 
258 static Config *
_notification_cfg_new(void)259 _notification_cfg_new(void)
260 {
261    Config *cfg;
262 
263    cfg = E_NEW(Config, 1);
264    cfg->cfd = NULL;
265    cfg->version = MOD_CONFIG_FILE_VERSION;
266    cfg->show_low = 0;
267    cfg->show_normal = 1;
268    cfg->show_critical = 1;
269    cfg->timeout = 5.0;
270    cfg->force_timeout = 0;
271    cfg->ignore_replacement = 0;
272    cfg->dual_screen = POPUP_DISPLAY_POLICY_FIRST;
273    cfg->corner = CORNER_TR;
274 
275    return cfg;
276 }
277 
278 static void
_notification_cfg_free(Config * cfg)279 _notification_cfg_free(Config *cfg)
280 {
281    free(cfg);
282 }
283