upload tizen1.0 source
[framework/uifw/e17.git] / src / modules / notification / e_mod_main.c
1 #include "e_mod_main.h"
2
3 /* Gadcon function protos */
4 static E_Gadcon_Client *_gc_init(E_Gadcon   *gc,
5                                  const char *name,
6                                  const char *id,
7                                  const char *style);
8 static void         _gc_shutdown(E_Gadcon_Client *gcc);
9 static const char  *_gc_label(E_Gadcon_Client_Class *client_class);
10 static Evas_Object *_gc_icon(E_Gadcon_Client_Class *client_class,
11                              Evas                  *evas);
12 static const char  *_gc_id_new(E_Gadcon_Client_Class *client_class);
13 static void         _gc_id_del(E_Gadcon_Client_Class *client_class,
14                                const char            *id);
15
16 /* Callback function protos */
17 static int  _notification_cb_notify(E_Notification_Daemon *daemon,
18                                     E_Notification        *n);
19 static void _notification_cb_close_notification(E_Notification_Daemon *daemon,
20                                                 unsigned int           id);
21
22 /* Config function protos */
23 static Config *_notification_cfg_new(void);
24 static void    _notification_cfg_free(Config *cfg);
25
26 /* Global variables */
27 E_Module *notification_mod = NULL;
28 Config *notification_cfg = NULL;
29
30 static E_Config_DD *conf_edd = NULL;
31 static E_Config_DD *conf_item_edd = NULL;
32
33 /* Gadcon Api Functions */
34 const E_Gadcon_Client_Class _gc_class =
35 {
36    GADCON_CLIENT_CLASS_VERSION, "notification",
37    {
38       _gc_init, _gc_shutdown, _gc_orient, _gc_label, _gc_icon, _gc_id_new, _gc_id_del,
39       e_gadcon_site_is_not_toolbar
40    },
41    E_GADCON_CLIENT_STYLE_PLAIN
42 };
43
44 static E_Gadcon_Client *
45 _gc_init(E_Gadcon   *gc,
46          const char *name,
47          const char *id,
48          const char *style)
49 {
50    Notification_Box *b;
51    E_Gadcon_Client *gcc;
52    Config_Item *ci;
53    Instance *inst;
54
55    inst = E_NEW(Instance, 1);
56    ci = notification_box_config_item_get(id);
57    b = notification_box_get(ci->id, gc->evas);
58
59    inst->ci = ci;
60    b->inst = inst;
61    inst->n_box = b;
62
63    gcc = e_gadcon_client_new(gc, name, id, style, b->o_box);
64    gcc->data = inst;
65    inst->gcc = gcc;
66
67    evas_object_event_callback_add(b->o_box, EVAS_CALLBACK_MOVE,
68                                   notification_box_cb_obj_moveresize, inst);
69    evas_object_event_callback_add(b->o_box, EVAS_CALLBACK_RESIZE,
70                                   notification_box_cb_obj_moveresize, inst);
71    notification_cfg->instances = eina_list_append(notification_cfg->instances, inst);
72    _gc_orient(gcc, gc->orient);
73    return gcc;
74 }
75
76 static void
77 _gc_shutdown(E_Gadcon_Client *gcc)
78 {
79    Instance *inst;
80
81    inst = gcc->data;
82    notification_box_visible_set(inst->n_box, EINA_FALSE);
83    notification_cfg->instances = eina_list_remove(notification_cfg->instances, inst);
84    free(inst);
85 }
86
87 void
88 _gc_orient(E_Gadcon_Client *gcc,
89            E_Gadcon_Orient  orient)
90 {
91    Instance *inst;
92
93    inst = gcc->data;
94    switch (orient)
95      {
96       case E_GADCON_ORIENT_FLOAT:
97       case E_GADCON_ORIENT_HORIZ:
98       case E_GADCON_ORIENT_TOP:
99       case E_GADCON_ORIENT_BOTTOM:
100       case E_GADCON_ORIENT_CORNER_TL:
101       case E_GADCON_ORIENT_CORNER_TR:
102       case E_GADCON_ORIENT_CORNER_BL:
103       case E_GADCON_ORIENT_CORNER_BR:
104         notification_box_orient_set(inst->n_box, 1);
105         e_gadcon_client_aspect_set(gcc, MAX(eina_list_count(inst->n_box->icons), 1) * 16, 16);
106         break;
107
108       case E_GADCON_ORIENT_VERT:
109       case E_GADCON_ORIENT_LEFT:
110       case E_GADCON_ORIENT_RIGHT:
111       case E_GADCON_ORIENT_CORNER_LT:
112       case E_GADCON_ORIENT_CORNER_RT:
113       case E_GADCON_ORIENT_CORNER_LB:
114       case E_GADCON_ORIENT_CORNER_RB:
115         notification_box_orient_set(inst->n_box, 0);
116         e_gadcon_client_aspect_set(gcc, 16, MAX(eina_list_count(inst->n_box->icons), 1) * 16);
117         break;
118
119       default:
120         break;
121      }
122    e_gadcon_client_min_size_set(gcc, 16, 16);
123 }
124
125 static const char *
126 _gc_label(E_Gadcon_Client_Class *client_class __UNUSED__)
127 {
128    return _("Notification Box");
129 }
130
131 static Evas_Object *
132 _gc_icon(E_Gadcon_Client_Class *client_class __UNUSED__,
133          Evas                  *evas)
134 {
135    Evas_Object *o;
136    char buf[4096];
137
138    o = edje_object_add(evas);
139    snprintf(buf, sizeof(buf), "%s/e-module-notification.edj",
140             e_module_dir_get(notification_mod));
141    if (!e_theme_edje_object_set(o, "base/theme/modules/notification",
142                                 "icon"))
143      edje_object_file_set(o, buf, "icon");
144    return o;
145 }
146
147 static const char *
148 _gc_id_new(E_Gadcon_Client_Class *client_class __UNUSED__)
149 {
150    Config_Item *ci;
151
152    ci = notification_box_config_item_get(NULL);
153    return ci->id;
154 }
155
156 static void
157 _gc_id_del(E_Gadcon_Client_Class *client_class __UNUSED__,
158            const char            *id)
159 {
160    Config_Item *ci;
161
162    notification_box_del(id);
163    ci = notification_box_config_item_get(id);
164    if (!ci) return;
165    eina_stringshare_del(ci->id);
166    notification_cfg->items = eina_list_remove(notification_cfg->items, ci);
167    free(ci);
168 }
169
170 static unsigned int
171 _notification_notify(E_Notification *n)
172 {
173    const char *appname = e_notification_app_name_get(n);
174    unsigned int replaces_id = e_notification_replaces_id_get(n);
175    unsigned int new_id;
176    int popuped;
177
178    if (replaces_id) new_id = replaces_id;
179    else new_id = notification_cfg->next_id++;
180
181    e_notification_id_set(n, new_id);
182
183    popuped = notification_popup_notify(n, replaces_id, appname);
184    notification_box_notify(n, replaces_id, new_id);
185
186    if (!popuped)
187      {
188         e_notification_hint_urgency_set(n, 4);
189         notification_popup_notify(n, replaces_id, appname);
190      }
191
192    return new_id;
193 }
194
195 static void
196 _notification_show_common(const char *summary,
197                           const char *body,
198                           int         replaces_id)
199 {
200    E_Notification *n = e_notification_full_new
201        ("enlightenment", replaces_id, "enlightenment", summary, body, -1);
202
203    if (!n)
204      return;
205
206    _notification_notify(n);
207    e_notification_unref(n);
208 }
209
210 static void
211 _notification_show_presentation(Eina_Bool enabled)
212 {
213    const char *summary, *body;
214
215    if (enabled)
216      {
217         summary = _("Enter Presentation Mode");
218         body = _("Enlightenment is in <b>presentation</b> mode."
219                  "<br>During presentation mode, screen saver, lock and "
220                  "power saving will be disabled so you are not interrupted.");
221      }
222    else
223      {
224         summary = _("Exited Presentation Mode");
225         body = _("Presentation mode is over."
226                  "<br>Now screen saver, lock and "
227                  "power saving settings will be restored.");
228      }
229
230    _notification_show_common(summary, body, -1);
231 }
232
233 static void
234 _notification_show_offline(Eina_Bool enabled)
235 {
236    const char *summary, *body;
237
238    if (enabled)
239      {
240         summary = _("Enter Offline Mode");
241         body = _("Enlightenment is in <b>offline</b> mode.<br>"
242                  "During offline mode, modules that use network will stop "
243                  "polling remote services.");
244      }
245    else
246      {
247         summary = _("Exited Offline Mode");
248         body = _("Now in <b>online</b> mode.<br>"
249                  "Now modules that use network will "
250                  "resume regular tasks.");
251      }
252
253    _notification_show_common(summary, body, -1);
254 }
255
256 static Eina_Bool
257 _notification_cb_config_mode_changed(Config *m_cfg,
258                                      int   type __UNUSED__,
259                                      void *event __UNUSED__)
260 {
261    if (m_cfg->last_config_mode.presentation != e_config->mode.presentation)
262      {
263         m_cfg->last_config_mode.presentation = e_config->mode.presentation;
264         _notification_show_presentation(e_config->mode.presentation);
265      }
266
267    if (m_cfg->last_config_mode.offline != e_config->mode.offline)
268      {
269         m_cfg->last_config_mode.offline = e_config->mode.offline;
270         _notification_show_offline(e_config->mode.offline);
271      }
272
273    return EINA_TRUE;
274 }
275
276 static Eina_Bool
277 _notification_cb_initial_mode_timer(Config *m_cfg)
278 {
279    if (e_config->mode.presentation)
280      _notification_show_presentation(1);
281    if (e_config->mode.offline)
282      _notification_show_offline(1);
283
284    m_cfg->initial_mode_timer = NULL;
285    return EINA_FALSE;
286 }
287
288 /* Module Api Functions */
289 EAPI E_Module_Api e_modapi = {E_MODULE_API_VERSION, "Notification"};
290
291 EAPI void *
292 e_modapi_init(E_Module *m)
293 {
294    E_Notification_Daemon *d;
295    char buf[PATH_MAX];
296
297    snprintf(buf, sizeof(buf), "%s/e-module-notification.edj", m->dir);
298    /* register config panel entry */
299    e_configure_registry_category_add("extensions", 90, _("Extensions"), NULL,
300                                      "preferences-extensions");
301    e_configure_registry_item_add("extensions/notification", 30, 
302                                  _("Notification"), NULL,
303                                  buf, e_int_config_notification_module);
304
305    conf_item_edd = E_CONFIG_DD_NEW("Notification_Config_Item", Config_Item);
306 #undef T
307 #undef D
308 #define T Config_Item
309 #define D conf_item_edd
310    E_CONFIG_VAL(D, T, id, STR);
311    E_CONFIG_VAL(D, T, show_label, INT);
312    E_CONFIG_VAL(D, T, show_popup, INT);
313    E_CONFIG_VAL(D, T, focus_window, INT);
314    E_CONFIG_VAL(D, T, store_low, INT);
315    E_CONFIG_VAL(D, T, store_normal, INT);
316    E_CONFIG_VAL(D, T, store_critical, INT);
317
318    conf_edd = E_CONFIG_DD_NEW("Notification_Config", Config);
319 #undef T
320 #undef D
321 #define T Config
322 #define D conf_edd
323    E_CONFIG_VAL(D, T, version, INT);
324    E_CONFIG_VAL(D, T, show_low, INT);
325    E_CONFIG_VAL(D, T, show_normal, INT);
326    E_CONFIG_VAL(D, T, show_critical, INT);
327    E_CONFIG_VAL(D, T, corner, INT);
328    E_CONFIG_VAL(D, T, timeout, FLOAT);
329    E_CONFIG_VAL(D, T, force_timeout, INT);
330    E_CONFIG_VAL(D, T, ignore_replacement, INT);
331    E_CONFIG_VAL(D, T, dual_screen, INT);
332    E_CONFIG_LIST(D, T, items, conf_item_edd);
333
334    notification_cfg = e_config_domain_load("module.notification", conf_edd);
335    if (notification_cfg &&
336        !(e_util_module_config_check(_("Notification Module"),
337                                     notification_cfg->version,
338                                     MOD_CFG_FILE_VERSION)))
339      {
340         _notification_cfg_free(notification_cfg);
341      }
342
343    if (!notification_cfg)
344      {
345         notification_cfg = _notification_cfg_new();
346      }
347
348    /* set up the notification daemon */
349    e_notification_daemon_init();
350    d = e_notification_daemon_add("e_notification_module", "Enlightenment");
351    if (!d)
352      {
353         _notification_cfg_free(notification_cfg);
354         notification_cfg = NULL;
355         e_util_dialog_show(_("Error During DBus Init!"),
356                            _("Error during DBus init! Please check if "
357                               "dbus is correctly installed and running."));
358         return NULL;
359      }
360    notification_cfg->daemon = d;
361    e_notification_daemon_data_set(d, notification_cfg);
362    e_notification_daemon_callback_notify_set(d, _notification_cb_notify);
363    e_notification_daemon_callback_close_notification_set(d, _notification_cb_close_notification);
364
365    notification_cfg->last_config_mode.presentation = e_config->mode.presentation;
366    notification_cfg->last_config_mode.offline = e_config->mode.offline;
367    notification_cfg->handlers = eina_list_append
368        (notification_cfg->handlers, ecore_event_handler_add
369          (E_EVENT_CONFIG_MODE_CHANGED, (Ecore_Event_Handler_Cb)_notification_cb_config_mode_changed,
370          notification_cfg));
371    notification_cfg->initial_mode_timer = ecore_timer_add
372        (0.1, (Ecore_Task_Cb)_notification_cb_initial_mode_timer, notification_cfg);
373
374    /* set up the borders events callbacks */
375    notification_cfg->handlers = eina_list_append
376        (notification_cfg->handlers, ecore_event_handler_add
377          (E_EVENT_BORDER_REMOVE, (Ecore_Event_Handler_Cb)notification_box_cb_border_remove, NULL));
378
379    notification_mod = m;
380    e_gadcon_provider_register(&_gc_class);
381    return m;
382 }
383
384 EAPI int
385 e_modapi_shutdown(E_Module *m __UNUSED__)
386 {
387    Ecore_Event_Handler *h;
388    Config_Item *ci;
389
390    e_gadcon_provider_unregister(&_gc_class);
391
392    if (notification_cfg->initial_mode_timer)
393      ecore_timer_del(notification_cfg->initial_mode_timer);
394
395    EINA_LIST_FREE(notification_cfg->handlers, h)
396      ecore_event_handler_del(h);
397
398    if (notification_cfg->cfd) e_object_del(E_OBJECT(notification_cfg->cfd));
399    e_configure_registry_item_del("extensions/notification");
400    e_configure_registry_category_del("extensions");
401
402    if (notification_cfg->menu)
403      {
404         e_menu_post_deactivate_callback_set(notification_cfg->menu, NULL, NULL);
405         e_object_del(E_OBJECT(notification_cfg->menu));
406         notification_cfg->menu = NULL;
407      }
408
409    EINA_LIST_FREE(notification_cfg->items, ci)
410      {
411         eina_stringshare_del(ci->id);
412         free(ci);
413      }
414
415    notification_box_shutdown();
416    notification_popup_shutdown();
417
418    e_notification_daemon_free(notification_cfg->daemon);
419    e_notification_daemon_shutdown();
420    _notification_cfg_free(notification_cfg);
421    E_CONFIG_DD_FREE(conf_item_edd);
422    E_CONFIG_DD_FREE(conf_edd);
423    notification_mod = NULL;
424
425    return 1;
426 }
427
428 EAPI int
429 e_modapi_save(E_Module *m __UNUSED__)
430 {
431    int ret;
432    ret = e_config_domain_save("module.notification", conf_edd, notification_cfg);
433    return ret;
434 }
435
436 /* Callbacks */
437 static int
438 _notification_cb_notify(E_Notification_Daemon *daemon __UNUSED__,
439                         E_Notification        *n)
440 {
441    return _notification_notify(n);
442 }
443
444 static void
445 _notification_cb_close_notification(E_Notification_Daemon *daemon __UNUSED__,
446                                     unsigned int           id)
447 {
448    notification_popup_close(id);
449 }
450
451 static Config *
452 _notification_cfg_new(void)
453 {
454    Config *cfg;
455
456    cfg = E_NEW(Config, 1);
457    cfg->cfd = NULL;
458    cfg->version = MOD_CFG_FILE_VERSION;
459    cfg->show_low = 0;
460    cfg->show_normal = 1;
461    cfg->show_critical = 1;
462    cfg->timeout = 5.0;
463    cfg->force_timeout = 0;
464    cfg->ignore_replacement = 0;
465    cfg->dual_screen = 0;
466    cfg->corner = CORNER_TR;
467
468    return cfg;
469 }
470
471 static void
472 _notification_cfg_free(Config *cfg)
473 {
474    E_FREE(cfg);
475 }
476