1 #include "batman.h"
2 
3 EINTERN Eina_Bool upower;
4 EINTERN Eina_List *batman_device_batteries;
5 EINTERN Eina_List *batman_device_ac_adapters;
6 EINTERN double batman_init_time;
7 
8 static Eina_Bool _batman_cb_warning_popup_timeout(void *data);
9 static void      _batman_cb_warning_popup_hide(void *data, Evas *e, Evas_Object *obj, void *event);
10 static void      _batman_warning_popup_destroy(Instance *inst);
11 static void      _batman_warning_popup(Instance *inst, int time, double percent);
12 
13 Eina_List *
_batman_battery_find(const char * udi)14 _batman_battery_find(const char *udi)
15 {
16    Eina_List *l;
17    Battery *bat;
18    Eina_List *batteries = NULL;
19    EINA_LIST_FOREACH(batman_device_batteries, l, bat)
20      { /* these are always stringshared */
21        if (udi == bat->udi) batteries = eina_list_append(batteries, bat);
22      }
23 
24    return batteries;
25 }
26 
27 Eina_List *
_batman_ac_adapter_find(const char * udi)28 _batman_ac_adapter_find(const char *udi)
29 {
30    Eina_List *l;
31    Ac_Adapter *ac;
32    Eina_List *adapters = NULL;
33    EINA_LIST_FOREACH(batman_device_ac_adapters, l, ac)
34      { /* these are always stringshared */
35        if (udi == ac->udi) adapters = eina_list_append(adapters, ac);
36      }
37 
38    return adapters;
39 }
40 
41 static void
_batman_face_level_set(Evas_Object * battery,double level)42 _batman_face_level_set(Evas_Object *battery, double level)
43 {
44    Edje_Message_Float msg;
45 
46    if (level < 0.0) level = 0.0;
47    else if (level > 1.0)
48      level = 1.0;
49    msg.val = level;
50    edje_object_message_send(elm_layout_edje_get(battery), EDJE_MESSAGE_FLOAT, 1, &msg);
51 }
52 
53 static void
_batman_popup_dismissed(void * data,Evas_Object * obj,void * event_info EINA_UNUSED)54 _batman_popup_dismissed(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
55 {
56    Instance *inst = data;
57    E_FREE_FUNC(obj, evas_object_del);
58    inst->cfg->batman.popup = NULL;
59 }
60 
61 static void
_batman_popup_deleted(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)62 _batman_popup_deleted(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
63 {
64    Instance *inst = data;
65    inst->cfg->batman.popup = NULL;
66 }
67 
68 static Evas_Object *
_batman_popup_create(Instance * inst)69 _batman_popup_create(Instance *inst)
70 {
71    Evas_Object *popup, *box, *pbar, *label;
72    Battery *bat;
73    Eina_List *l;
74    char buf[128], buf2[128 + 100];
75    int hrs = 0, mins = 0;
76    Eina_List *udis = NULL;
77 
78    hrs = (inst->cfg->batman.time_left / 3600);
79    mins = ((inst->cfg->batman.time_left) / 60 - (hrs * 60));
80    if (mins < 0) mins = 0;
81 
82    popup = elm_ctxpopup_add(e_comp->elm);
83    elm_object_style_set(popup, "noblock");
84    evas_object_smart_callback_add(popup, "dismissed",
85                                   _batman_popup_dismissed, inst);
86    evas_object_event_callback_add(popup, EVAS_CALLBACK_DEL,
87                                   _batman_popup_deleted, inst);
88 
89    box = elm_box_add(popup);
90    elm_box_horizontal_set(box, EINA_FALSE);
91    E_EXPAND(box); E_FILL(box);
92    elm_object_content_set(popup, box);
93    evas_object_show(box);
94 
95    label = elm_label_add(box);
96    E_EXPAND(label); E_ALIGN(label, 0.5, 0.5);
97    elm_object_text_set(label, buf);
98    elm_box_pack_end(box, label);
99    evas_object_show(label);
100 
101    if (eina_list_count(batman_device_batteries) == 0)
102      snprintf(buf, sizeof(buf), _("No Battery Found"));
103    else if (inst->cfg->batman.have_power && (inst->cfg->batman.full < 99))
104      snprintf(buf, sizeof(buf), _("Battery Charging"));
105    else if (inst->cfg->batman.full >= 99)
106      snprintf(buf, sizeof(buf), _("Battery Fully Charged"));
107    else
108      snprintf(buf, sizeof(buf), _("Time Remaining: %i:%02i"), hrs, mins);
109    snprintf(buf2, sizeof(buf2), "<big><b>%s</b></big>", buf);
110    elm_object_text_set(label, buf2);
111 
112    EINA_LIST_FOREACH(batman_device_batteries, l, bat)
113      {
114         if (!eina_list_count(udis) || !eina_list_data_find(udis, bat->udi))
115           {
116              udis = eina_list_append(udis, bat->udi);
117              if (bat->vendor && bat->vendor[0] && bat->model && bat->model[0])
118                {
119                   label = elm_label_add(box);
120                   E_EXPAND(label); E_ALIGN(label, 0.5, 0.5);
121                   snprintf(buf, sizeof(buf), "%s (%s)", bat->vendor, bat->model);
122                   elm_object_text_set(label, buf);
123                   elm_box_pack_end(box, label);
124                   evas_object_show(label);
125                }
126 
127              pbar = elm_progressbar_add(box);
128              E_EXPAND(pbar); E_FILL(pbar);
129              elm_progressbar_span_size_set(pbar, 200 * e_scale);
130              elm_progressbar_value_set(pbar, bat->percent / 100);
131              elm_box_pack_end(box, pbar);
132              evas_object_show(pbar);
133           }
134      }
135    if (eina_list_count(udis))
136      eina_list_free(udis);
137    e_gadget_util_ctxpopup_place(inst->o_main, popup,
138                                 inst->cfg->batman.o_gadget);
139    evas_object_show(popup);
140 
141    return popup;
142 }
143 
144 static Evas_Object *
_batman_configure_cb(Evas_Object * g)145 _batman_configure_cb(Evas_Object *g)
146 {
147    Instance *inst = evas_object_data_get(g, "Instance");
148 
149    if (!sysinfo_config) return NULL;
150    if (inst->cfg->batman.popup) return NULL;
151    return batman_configure(inst);
152 }
153 
154 static void
_batman_mouse_up_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_data)155 _batman_mouse_up_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_data)
156 {
157    Evas_Event_Mouse_Up *ev = event_data;
158    Instance *inst = data;
159 
160    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
161    if (ev->button == 1)
162      {
163         if (inst->cfg->batman.popup)
164           elm_ctxpopup_dismiss(inst->cfg->batman.popup);
165         else
166           inst->cfg->batman.popup = _batman_popup_create(inst);
167      }
168 }
169 
170 static Eina_Bool
_powersave_cb_config_update(void * data,int type EINA_UNUSED,void * event EINA_UNUSED)171 _powersave_cb_config_update(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
172 {
173    Instance *inst = data;
174 
175    if (!inst->cfg->batman.have_battery)
176      e_powersave_mode_set(E_POWERSAVE_MODE_LOW);
177    else
178      {
179         if (inst->cfg->batman.have_power)
180           e_powersave_mode_set(E_POWERSAVE_MODE_LOW);
181         else if (inst->cfg->batman.full > 95)
182           e_powersave_mode_set(E_POWERSAVE_MODE_MEDIUM);
183         else if (inst->cfg->batman.full > 30)
184           e_powersave_mode_set(E_POWERSAVE_MODE_HIGH);
185         else
186           e_powersave_mode_set(E_POWERSAVE_MODE_EXTREME);
187      }
188    return ECORE_CALLBACK_RENEW;
189 }
190 
191 void
_batman_update(Instance * inst,int full,int time_left,Eina_Bool have_battery,Eina_Bool have_power)192 _batman_update(Instance *inst, int full, int time_left, Eina_Bool have_battery, Eina_Bool have_power)
193 {
194    static double debounce_time = 0.0;
195 
196    if (!inst) return;
197    if (!inst->cfg) return;
198    if (inst->cfg->esm != E_SYSINFO_MODULE_BATMAN && inst->cfg->esm != E_SYSINFO_MODULE_SYSINFO) return;
199 
200    if (have_power != inst->cfg->batman.have_power)
201      {
202         if (have_power && (full < 100))
203           elm_layout_signal_emit(inst->cfg->batman.o_gadget,
204                                  "e,state,charging",
205                                  "e");
206         else
207           {
208              elm_layout_signal_emit(inst->cfg->batman.o_gadget,
209                                     "e,state,discharging",
210                                     "e");
211              if (inst->popup_battery)
212                elm_layout_signal_emit(inst->popup_battery,
213                                       "e,state,discharging", "e");
214           }
215      }
216    if (have_battery)
217      {
218         if (inst->cfg->batman.full != full)
219           {
220              double val;
221 
222              if (full >= 100) val = 1.0;
223              else val = (double)full / 100.0;
224              _batman_face_level_set(inst->cfg->batman.o_gadget, val);
225              if (inst->popup_battery)
226                _batman_face_level_set(inst->popup_battery, val);
227           }
228      }
229    else
230      {
231         _batman_face_level_set(inst->cfg->batman.o_gadget, 0.0);
232      }
233    if (have_battery &&
234        (!have_power) &&
235        (full < 100) &&
236        (
237          (
238            (time_left > 0) &&
239            inst->cfg->batman.alert &&
240            ((time_left / 60) <= inst->cfg->batman.alert)
241          ) ||
242          (
243            inst->cfg->batman.alert_p &&
244            (full <= inst->cfg->batman.alert_p)
245          )
246        )
247        )
248      {
249         double t;
250 
251         printf("-------------------------------------- bat warn .. why below\n");
252         printf("have_battery = %i\n", (int)have_battery);
253         printf("have_power = %i\n", (int)have_power);
254         printf("full = %i\n", (int)full);
255         printf("time_left = %i\n", (int)time_left);
256         printf("inst->cfg->batman.alert = %i\n", (int)inst->cfg->batman.alert);
257         printf("inst->cfg->batman.alert_p = %i\n", (int)inst->cfg->batman.alert_p);
258         t = ecore_time_get();
259         if ((t - debounce_time) > 30.0)
260           {
261              printf("t-debounce = %3.3f\n", (t - debounce_time));
262              debounce_time = t;
263              if ((t - batman_init_time) > 5.0)
264                _batman_warning_popup(inst, time_left, (double)full / 100.0);
265           }
266      }
267    else if (have_power || ((time_left / 60) > inst->cfg->batman.alert))
268      _batman_warning_popup_destroy(inst);
269    if ((have_battery) && (!have_power) && (full >= 0) &&
270        (inst->cfg->batman.suspend_below > 0) &&
271        (full < inst->cfg->batman.suspend_below))
272      {
273         if (inst->cfg->batman.suspend_method == SUSPEND)
274           e_sys_action_do(E_SYS_SUSPEND, NULL);
275         else if (inst->cfg->batman.suspend_method == HIBERNATE)
276           e_sys_action_do(E_SYS_HIBERNATE, NULL);
277         else if (inst->cfg->batman.suspend_method == SHUTDOWN)
278           e_sys_action_do(E_SYS_HALT, NULL);
279      }
280    inst->cfg->batman.full = full;
281    inst->cfg->batman.time_left = time_left;
282    inst->cfg->batman.have_battery = have_battery;
283    inst->cfg->batman.have_power = have_power;
284 
285    if (!have_battery)
286      e_powersave_mode_set(E_POWERSAVE_MODE_LOW);
287    else
288      {
289         if (have_power)
290           e_powersave_mode_set(E_POWERSAVE_MODE_LOW);
291         else if (full > 95)
292           e_powersave_mode_set(E_POWERSAVE_MODE_MEDIUM);
293         else if (full > 30)
294           e_powersave_mode_set(E_POWERSAVE_MODE_HIGH);
295         else
296           e_powersave_mode_set(E_POWERSAVE_MODE_EXTREME);
297      }
298 }
299 
300 void
_batman_device_update(Instance * inst)301 _batman_device_update(Instance *inst)
302 {
303    Eina_List *l;
304    Battery *bat;
305    Ac_Adapter *ac;
306    int full = -1;
307    int time_left = -1;
308    int have_battery = 0;
309    int have_power = 0;
310    int charging = 0;
311 
312    int batnum = 0;
313    int acnum = 0;
314 
315    EINA_LIST_FOREACH(batman_device_ac_adapters, l, ac)
316      {
317         if (ac->present)
318           {
319              acnum++;
320              have_power = 1;
321           }
322      }
323 
324    EINA_LIST_FOREACH(batman_device_batteries, l, bat)
325      {
326         if (!bat->got_prop)
327           continue;
328         have_battery = 1;
329         batnum++;
330         if (bat->charging == 1) have_power = 1;
331         if (full == -1) full = 0;
332         if (bat->percent >= 0)
333           full += bat->percent;
334         else if (bat->last_full_charge > 0)
335           full += (bat->current_charge * 100) / bat->last_full_charge;
336         else if (bat->design_charge > 0)
337           full += (bat->current_charge * 100) / bat->design_charge;
338         if (bat->time_left > 0)
339           {
340              if (time_left < 0) time_left = bat->time_left;
341              else time_left += bat->time_left;
342           }
343         charging += bat->charging;
344      }
345 
346    if ((batman_device_batteries) && (batnum == 0))
347      return;  /* not ready yet, no properties received for any battery */
348 
349    if (batnum > 0) full /= batnum;
350    if ((full == 100) && have_power)
351      {
352         time_left = -1;
353      }
354    if (time_left < 1) time_left = -1;
355 
356    _batman_update(inst, full, time_left, have_battery, have_power);
357 }
358 
359 static Eina_Bool
_screensaver_on(void * data)360 _screensaver_on(void *data)
361 {
362 #if defined(HAVE_EEZE) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__)
363    Instance *inst = data;
364 #else
365    (void)data;
366 #endif
367 
368 #if defined(HAVE_EEZE)
369    _batman_udev_stop(inst);
370 #elif defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__)
371    _batman_sysctl_stop(inst);
372 #elif defined(upower)
373    _batman_upower_stop();
374 #else
375    _batman_fallback_stop();
376 #endif
377 
378    return ECORE_CALLBACK_RENEW;
379 }
380 
381 static Eina_Bool
_screensaver_off(void * data)382 _screensaver_off(void *data)
383 {
384    Instance *inst = data;
385 
386    _batman_config_updated(inst);
387 
388    return ECORE_CALLBACK_RENEW;
389 }
390 
391 void
_batman_config_updated(Instance * inst)392 _batman_config_updated(Instance *inst)
393 {
394    int ok = 0;
395 
396    if (!inst->cfg) return;
397 
398    if (inst->cfg->id == -1)
399      {
400         _batman_face_level_set(inst->cfg->batman.o_gadget, 1.0);
401         return;
402      }
403    if ((inst->cfg->batman.force_mode == UNKNOWN) ||
404        (inst->cfg->batman.force_mode == SUBSYSTEM))
405      {
406 #if defined(HAVE_EEZE)
407         ok = _batman_udev_start(inst);
408 #elif defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__)
409         ok = _batman_sysctl_start(inst);
410 #else
411         ok = _batman_upower_start(inst);
412         if (ok)
413           upower = EINA_TRUE;
414 #endif
415      }
416    if (ok) return;
417 
418    if ((inst->cfg->batman.force_mode == UNKNOWN) ||
419        (inst->cfg->batman.force_mode == NOSUBSYSTEM))
420      {
421         ok = _batman_fallback_start(inst);
422      }
423 }
424 
425 static void
_warning_popup_dismissed(void * data,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)426 _warning_popup_dismissed(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
427 {
428    Instance *inst = data;
429 
430    E_FREE_FUNC(inst->popup_battery, evas_object_del);
431    E_FREE_FUNC(inst->warning, evas_object_del);
432 }
433 
434 static Eina_Bool
_batman_cb_warning_popup_timeout(void * data)435 _batman_cb_warning_popup_timeout(void *data)
436 {
437    Instance *inst;
438 
439    inst = data;
440    elm_ctxpopup_dismiss(inst->warning);
441    inst->cfg->batman.alert_timer = NULL;
442    return ECORE_CALLBACK_CANCEL;
443 }
444 
445 static void
_batman_cb_warning_popup_hide(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event EINA_UNUSED)446 _batman_cb_warning_popup_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
447 {
448    Instance *inst = NULL;
449 
450    inst = (Instance *)data;
451    if ((!inst) || (!inst->warning)) return;
452    evas_object_hide(inst->warning);
453 }
454 
455 static void
_batman_warning_popup_destroy(Instance * inst)456 _batman_warning_popup_destroy(Instance *inst)
457 {
458    if (inst->cfg->batman.alert_timer)
459      {
460         ecore_timer_del(inst->cfg->batman.alert_timer);
461         inst->cfg->batman.alert_timer = NULL;
462      }
463    if (!inst->warning) return;
464    elm_ctxpopup_dismiss(inst->warning);
465 }
466 
467 static void
_batman_warning_popup_cb(void * data,unsigned int id)468 _batman_warning_popup_cb(void *data, unsigned int id)
469 {
470    Instance *inst = data;
471 
472    inst->notification_id = id;
473 }
474 
475 static void
_batman_warning_popup(Instance * inst,int t,double percent)476 _batman_warning_popup(Instance *inst, int t, double percent)
477 {
478    Evas_Object *popup_bg = NULL;
479    int x, y, w, h;
480    char buf[4096];
481    int hrs = 0, mins = 0;
482 
483    if ((!inst) || (inst->warning)) return;
484 
485    hrs = (t / 3600);
486    mins = ((t) / 60 - (hrs * 60));
487    if (mins < 0) mins = 0;
488    snprintf(buf, 4096, _("AC power is recommended. %i:%02i Remaining"), hrs, mins);
489 
490    if (inst->cfg->batman.desktop_notifications)
491      {
492         E_Notification_Notify n;
493         memset(&n, 0, sizeof(E_Notification_Notify));
494         n.app_name = _("Battery");
495         n.replaces_id = 0;
496         n.icon.icon = "battery-low";
497         n.summary = _("Your battery is low!");
498         n.body = buf;
499         n.timeout = inst->cfg->batman.alert_timeout * 1000;
500         e_notification_client_send(&n, _batman_warning_popup_cb, inst);
501         return;
502      }
503 
504    inst->warning = elm_ctxpopup_add(e_comp->elm);
505    elm_object_style_set(inst->warning, "noblock");
506    evas_object_smart_callback_add(inst->warning, "dismissed", _warning_popup_dismissed, inst);
507    if (!inst->warning) return;
508 
509    popup_bg = elm_layout_add(inst->warning);
510    inst->popup_battery = elm_layout_add(popup_bg);
511 
512    if ((!popup_bg) || (!inst->popup_battery))
513      {
514         elm_ctxpopup_dismiss(inst->warning);
515         inst->warning = NULL;
516         return;
517      }
518 
519    e_theme_edje_object_set(popup_bg, "base/theme/gadget/batman/popup",
520                            "e/gadget/batman/popup");
521    e_theme_edje_object_set(inst->popup_battery, "base/theme/gadget/batman",
522                            "e/gadget/batman/main");
523    if (edje_object_part_exists(elm_layout_edje_get(popup_bg), "e.swallow.batman"))
524      elm_layout_content_set(popup_bg, "e.swallow.batman", inst->popup_battery);
525    else
526      elm_layout_content_set(popup_bg, "battery", inst->popup_battery);
527 
528    elm_layout_text_set(popup_bg, "e.text.title",
529                        _("Your battery is low!"));
530    elm_layout_text_set(popup_bg, "e.text.label", buf);
531    evas_object_show(inst->popup_battery);
532    evas_object_show(popup_bg);
533 
534    elm_object_content_set(inst->warning, popup_bg);
535    e_gadget_util_ctxpopup_place(inst->o_main, inst->warning, inst->cfg->batman.o_gadget);
536    evas_object_layer_set(inst->warning, E_LAYER_POPUP);
537    evas_object_show(inst->warning);
538 
539    evas_object_geometry_get(inst->warning, &x, &y, &w, &h);
540    evas_object_event_callback_add(inst->warning, EVAS_CALLBACK_MOUSE_UP,
541                                   _batman_cb_warning_popup_hide, inst);
542 
543    _batman_face_level_set(inst->popup_battery, percent);
544    edje_object_signal_emit(inst->popup_battery, "e,state,discharging", "e");
545 
546    if ((inst->cfg->batman.alert_timeout > 0) &&
547        (!inst->cfg->batman.alert_timer))
548      {
549         inst->cfg->batman.alert_timer =
550           ecore_timer_loop_add(inst->cfg->batman.alert_timeout,
551                                _batman_cb_warning_popup_timeout, inst);
552      }
553 }
554 
555 static void
_batman_resize_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_data EINA_UNUSED)556 _batman_resize_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_data EINA_UNUSED)
557 {
558    Evas_Coord w, h;
559    Instance *inst = data;
560 
561    edje_object_parts_extends_calc(elm_layout_edje_get(inst->cfg->batman.o_gadget), 0, 0, &w, &h);
562    if (w < 1) w = 1;
563    if (h < 1) h = 1;
564    if (inst->cfg->esm == E_SYSINFO_MODULE_BATMAN)
565      evas_object_size_hint_aspect_set(inst->o_main, EVAS_ASPECT_CONTROL_BOTH, w, h);
566    else
567      evas_object_size_hint_aspect_set(inst->cfg->batman.o_gadget, EVAS_ASPECT_CONTROL_BOTH, w, h);
568 }
569 
570 static void
_batman_removed_cb(void * data,Evas_Object * obj EINA_UNUSED,void * event_data)571 _batman_removed_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_data)
572 {
573    Instance *inst = data;
574    Ecore_Event_Handler *handler;
575 
576    if (inst->o_main != event_data) return;
577    if (inst->cfg->batman.popup)
578      E_FREE_FUNC(inst->cfg->batman.popup, evas_object_del);
579    if (inst->cfg->batman.configure)
580      E_FREE_FUNC(inst->cfg->batman.configure, evas_object_del);
581    EINA_LIST_FREE(inst->cfg->batman.handlers, handler)
582      ecore_event_handler_del(handler);
583 #if defined(HAVE_EEZE)
584    _batman_udev_stop(inst);
585 #elif defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__)
586    _batman_sysctl_stop(inst);
587 #elif defined(upower)
588    _batman_upower_stop();
589 #else
590    _batman_fallback_stop();
591 #endif
592 
593    evas_object_event_callback_del_full(inst->o_main, EVAS_CALLBACK_DEL, sysinfo_batman_remove, data);
594    evas_object_smart_callback_del_full(e_gadget_site_get(inst->o_main), "gadget_removed",
595                                        _batman_removed_cb, inst);
596 
597    sysinfo_config->items = eina_list_remove(sysinfo_config->items, inst->cfg);
598    if (inst->cfg->id >= 0)
599      sysinfo_instances = eina_list_remove(sysinfo_instances, inst);
600    E_FREE(inst->cfg);
601    E_FREE(inst);
602 }
603 
604 void
sysinfo_batman_remove(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_data EINA_UNUSED)605 sysinfo_batman_remove(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_data EINA_UNUSED)
606 {
607    Instance *inst = data;
608    Ecore_Event_Handler *handler;
609 
610    if (inst->cfg->batman.popup)
611      E_FREE_FUNC(inst->cfg->batman.popup, evas_object_del);
612    if (inst->cfg->batman.configure)
613      E_FREE_FUNC(inst->cfg->batman.configure, evas_object_del);
614    EINA_LIST_FREE(inst->cfg->batman.handlers, handler)
615      ecore_event_handler_del(handler);
616 #if defined(HAVE_EEZE)
617    _batman_udev_stop(inst);
618 #elif defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__)
619    _batman_sysctl_stop(inst);
620 #elif defined(upower)
621    (void)inst;
622    _batman_upower_stop();
623 #else
624    (void)inst;
625    _batman_fallback_stop();
626 #endif
627 }
628 
629 static void
_batman_created_cb(void * data,Evas_Object * obj,void * event_data EINA_UNUSED)630 _batman_created_cb(void *data, Evas_Object *obj, void *event_data EINA_UNUSED)
631 {
632    Instance *inst = data;
633    E_Gadget_Site_Orient orient = e_gadget_site_orient_get(e_gadget_site_get(inst->o_main));
634 
635    e_gadget_configure_cb_set(inst->o_main, _batman_configure_cb);
636 
637    inst->cfg->batman.full = -2;
638    inst->cfg->batman.time_left = -2;
639    inst->cfg->batman.have_battery = -2;
640    inst->cfg->batman.have_power = -2;
641 
642    inst->cfg->batman.o_gadget = elm_layout_add(inst->o_main);
643    if (orient == E_GADGET_SITE_ORIENT_VERTICAL)
644      e_theme_edje_object_set(inst->cfg->batman.o_gadget,
645                              "base/theme/gadget/batman",
646                              "e/gadget/batman/main_vert");
647    else
648      e_theme_edje_object_set(inst->cfg->batman.o_gadget, "base/theme/gadget/batman",
649                              "e/gadget/batman/main");
650    E_EXPAND(inst->cfg->batman.o_gadget);
651    E_FILL(inst->cfg->batman.o_gadget);
652    elm_box_pack_end(inst->o_main, inst->cfg->batman.o_gadget);
653    evas_object_event_callback_add(inst->cfg->batman.o_gadget,
654                                   EVAS_CALLBACK_MOUSE_UP,
655                                   _batman_mouse_up_cb, inst);
656    evas_object_event_callback_add(inst->cfg->batman.o_gadget, EVAS_CALLBACK_RESIZE, _batman_resize_cb, inst);
657    evas_object_show(inst->cfg->batman.o_gadget);
658    evas_object_smart_callback_del_full(obj, "gadget_created", _batman_created_cb, data);
659 
660    E_LIST_HANDLER_APPEND(inst->cfg->batman.handlers, E_EVENT_SCREENSAVER_ON, _screensaver_on, inst);
661    E_LIST_HANDLER_APPEND(inst->cfg->batman.handlers, E_EVENT_SCREENSAVER_OFF, _screensaver_off, inst);
662    E_LIST_HANDLER_APPEND(inst->cfg->batman.handlers, E_EVENT_POWERSAVE_CONFIG_UPDATE,
663                                       _powersave_cb_config_update, inst);
664 
665    _batman_config_updated(inst);
666 }
667 
668 Evas_Object *
sysinfo_batman_create(Evas_Object * parent,Instance * inst)669 sysinfo_batman_create(Evas_Object *parent, Instance *inst)
670 {
671    inst->cfg->batman.full = -2;
672    inst->cfg->batman.time_left = -2;
673    inst->cfg->batman.have_battery = -2;
674    inst->cfg->batman.have_power = -2;
675 
676    inst->cfg->batman.o_gadget = elm_layout_add(parent);
677    e_theme_edje_object_set(inst->cfg->batman.o_gadget, "base/theme/gadget/batman",
678                            "e/gadget/batman/main");
679    E_EXPAND(inst->cfg->batman.o_gadget);
680    E_FILL(inst->cfg->batman.o_gadget);
681    evas_object_event_callback_add(inst->cfg->batman.o_gadget,
682                                   EVAS_CALLBACK_MOUSE_UP,
683                                   _batman_mouse_up_cb, inst);
684    evas_object_event_callback_add(inst->cfg->batman.o_gadget, EVAS_CALLBACK_RESIZE, _batman_resize_cb, inst);
685    evas_object_show(inst->cfg->batman.o_gadget);
686 
687    E_LIST_HANDLER_APPEND(inst->cfg->batman.handlers, E_EVENT_SCREENSAVER_ON, _screensaver_on, inst);
688    E_LIST_HANDLER_APPEND(inst->cfg->batman.handlers, E_EVENT_SCREENSAVER_OFF, _screensaver_off, inst);
689    E_LIST_HANDLER_APPEND(inst->cfg->batman.handlers, E_EVENT_POWERSAVE_CONFIG_UPDATE,
690                                       _powersave_cb_config_update, inst);
691 
692    _batman_config_updated(inst);
693 
694    return inst->cfg->batman.o_gadget;
695 }
696 
697 static Config_Item *
_conf_item_get(int * id)698 _conf_item_get(int *id)
699 {
700    Config_Item *ci;
701    Eina_List *l;
702 
703    if (*id > 0)
704      {
705         EINA_LIST_FOREACH(sysinfo_config->items, l, ci)
706           if (*id == ci->id && ci->esm == E_SYSINFO_MODULE_BATMAN) return ci;
707      }
708 
709    ci = E_NEW(Config_Item, 1);
710 
711    if (*id != -1)
712      ci->id = eina_list_count(sysinfo_config->items) + 1;
713    else
714      ci->id = -1;
715 
716    ci->esm = E_SYSINFO_MODULE_BATMAN;
717    ci->batman.poll_interval = 512;
718    ci->batman.alert = 30;
719    ci->batman.alert_p = 10;
720    ci->batman.alert_timeout = 0;
721    ci->batman.suspend_below = 0;
722    ci->batman.force_mode = 0;
723    ci->batman.full = -2;
724    ci->batman.time_left = -2;
725    ci->batman.have_battery = -2;
726    ci->batman.have_power = -2;
727 #if defined(HAVE_EEZE) || defined(__OpenBSD__) || defined(__NetBSD__)
728    ci->batman.fuzzy = 0;
729 #endif
730    ci->batman.desktop_notifications = 0;
731    ci->batman.configure = NULL;
732 
733    sysinfo_config->items = eina_list_append(sysinfo_config->items, ci);
734 
735    return ci;
736 }
737 
738 Evas_Object *
batman_create(Evas_Object * parent,int * id,E_Gadget_Site_Orient orient EINA_UNUSED)739 batman_create(Evas_Object *parent, int *id, E_Gadget_Site_Orient orient EINA_UNUSED)
740 {
741    Instance *inst;
742 
743    inst = E_NEW(Instance, 1);
744    inst->cfg = _conf_item_get(id);
745    *id = inst->cfg->id;
746    inst->o_main = elm_box_add(parent);
747    evas_object_data_set(inst->o_main, "Instance", inst);
748    evas_object_smart_callback_add(parent, "gadget_created", _batman_created_cb, inst);
749    evas_object_smart_callback_add(parent, "gadget_removed", _batman_removed_cb, inst);
750    evas_object_event_callback_add(inst->o_main, EVAS_CALLBACK_DEL, sysinfo_batman_remove, inst);
751    evas_object_show(inst->o_main);
752 
753    if (inst->cfg->id < 0) return inst->o_main;
754 
755    sysinfo_instances =
756      eina_list_append(sysinfo_instances, inst);
757 
758    return inst->o_main;
759 }
760