update for beta release
[platform/core/uifw/e17.git] / src / modules / temperature / e_mod_main.c
1 #include "e.h"
2 #include "e_mod_main.h"
3
4 #ifdef __FreeBSD__
5 #include <sys/types.h>
6 #include <sys/sysctl.h>
7 #endif
8
9 #ifdef __OpenBSD__
10 #include <sys/types.h>
11 #include <sys/sysctl.h>
12 #include <sys/sensors.h>
13 #endif
14
15
16 /* gadcon requirements */
17 static E_Gadcon_Client *_gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style);
18 static void _gc_shutdown(E_Gadcon_Client *gcc);
19 static void _gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient);
20 static const char *_gc_label(E_Gadcon_Client_Class *client_class);
21 static Evas_Object *_gc_icon(E_Gadcon_Client_Class *client_class, Evas *evas);
22 static const char *_gc_id_new(E_Gadcon_Client_Class *client_class);
23 /* and actually define the gadcon class that this module provides (just 1) */
24 static const E_Gadcon_Client_Class _gadcon_class =
25 {
26    GADCON_CLIENT_CLASS_VERSION, "temperature",
27      {
28         _gc_init, _gc_shutdown, _gc_orient, _gc_label, _gc_icon, _gc_id_new, NULL,
29         e_gadcon_site_is_not_toolbar
30      },
31    E_GADCON_CLIENT_STYLE_PLAIN
32 };
33
34 /* actual module specifics */
35
36 static void _temperature_face_cb_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info);
37 static void _temperature_face_cb_post_menu(void *data, E_Menu *m);
38
39 static void _temperature_face_cb_menu_configure(void *data, E_Menu *m, E_Menu_Item *mi);
40
41 static Eina_Bool _temperature_face_shutdown(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *hdata, void *fdata __UNUSED__);
42 static Eina_Bool _temperature_face_id_max(const Eina_Hash *hash __UNUSED__, const void *key, void *hdata __UNUSED__, void *fdata);
43
44 static E_Config_DD *conf_edd = NULL;
45 static E_Config_DD *conf_face_edd = NULL;
46
47 static int uuid = 0;
48
49 static Config *temperature_config = NULL;
50
51 static E_Gadcon_Client *
52 _gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style)
53 {
54    Evas_Object *o;
55    E_Gadcon_Client *gcc;
56    Config_Face *inst;
57
58    inst = eina_hash_find(temperature_config->faces, id);
59    if (!inst)
60      {
61         inst = E_NEW(Config_Face, 1);
62         inst->id = eina_stringshare_add(id);
63         inst->poll_interval = 128;
64         inst->low = 30;
65         inst->high = 80;
66         inst->sensor_type = SENSOR_TYPE_NONE;
67         inst->sensor_name = NULL;
68         inst->units = CELCIUS;
69 #ifdef HAVE_EEZE
70         inst->backend = UDEV;
71 #endif
72         if (!temperature_config->faces)
73           temperature_config->faces = eina_hash_string_superfast_new(NULL);
74         eina_hash_direct_add(temperature_config->faces, inst->id, inst);
75      }
76    if (!inst->id) inst->id = eina_stringshare_add(id);
77    E_CONFIG_LIMIT(inst->poll_interval, 1, 1024);
78    E_CONFIG_LIMIT(inst->low, 0, 100);
79    E_CONFIG_LIMIT(inst->high, 0, 220);
80    E_CONFIG_LIMIT(inst->units, CELCIUS, FAHRENHEIT);
81 #ifdef HAVE_EEZE
82    E_CONFIG_LIMIT(inst->backend, TEMPGET, UDEV);
83 #endif
84
85    o = edje_object_add(gc->evas);
86    e_theme_edje_object_set(o, "base/theme/modules/temperature",
87                            "e/modules/temperature/main");
88
89    gcc = e_gadcon_client_new(gc, name, id, style, o);
90    gcc->data = inst;
91
92    inst->gcc = gcc;
93    inst->o_temp = o;
94    inst->module = temperature_config->module;
95    inst->have_temp = -1;
96 #ifdef HAVE_EEZE
97    if (inst->backend == TEMPGET)
98      {
99         inst->tempget_data_handler = 
100           ecore_event_handler_add(ECORE_EXE_EVENT_DATA,
101                                   _temperature_cb_exe_data, inst);
102         inst->tempget_del_handler = 
103           ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
104                                   _temperature_cb_exe_del, inst);
105      }
106    else
107      {
108         eeze_init();
109         inst->temp_poller = 
110           ecore_poller_add(ECORE_POLLER_CORE, inst->poll_interval, 
111                            temperature_udev_update_poll, inst);
112         temperature_udev_update(inst);
113      }
114 #else 
115    inst->tempget_data_handler = 
116      ecore_event_handler_add(ECORE_EXE_EVENT_DATA,
117                              _temperature_cb_exe_data, inst);
118    inst->tempget_del_handler = 
119      ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
120                              _temperature_cb_exe_del, inst);
121 #endif
122
123    temperature_face_update_config(inst);
124
125    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN,
126                                   _temperature_face_cb_mouse_down, inst);
127    return gcc;
128 }
129
130 static void
131 _gc_shutdown(E_Gadcon_Client *gcc)
132 {
133    Config_Face *inst;
134
135    inst = gcc->data;
136
137    if (inst->tempget_exe)
138      {
139         ecore_exe_terminate(inst->tempget_exe);
140         ecore_exe_free(inst->tempget_exe);
141         inst->tempget_exe = NULL;
142      }
143    if (inst->tempget_data_handler)
144      {
145         ecore_event_handler_del(inst->tempget_data_handler);
146         inst->tempget_data_handler = NULL;
147      }
148    if (inst->tempget_del_handler)
149      {
150         ecore_event_handler_del(inst->tempget_del_handler);
151         inst->tempget_del_handler = NULL;
152      }
153 #ifdef HAVE_EEEZ_UDEV
154    if (inst->temp_poller)
155      ecore_poller_del(inst->temp_poller);
156    eeze_shutdown();
157 #endif
158    if (inst->o_temp) evas_object_del(inst->o_temp);
159    inst->o_temp = NULL;
160    if (inst->config_dialog) e_object_del(E_OBJECT(inst->config_dialog));
161    inst->config_dialog = NULL;
162    if (inst->menu) e_object_del(E_OBJECT(inst->menu));
163    inst->menu = NULL;
164 }
165
166 static void
167 _gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient __UNUSED__)
168 {
169    e_gadcon_client_aspect_set(gcc, 16, 16);
170    e_gadcon_client_min_size_set(gcc, 16, 16);
171 }
172
173 static const char *
174 _gc_label(E_Gadcon_Client_Class *client_class __UNUSED__)
175 {
176    return _("Temperature");
177 }
178
179 static Evas_Object *
180 _gc_icon(E_Gadcon_Client_Class *client_class __UNUSED__, Evas *evas)
181 {
182    Evas_Object *o;
183    char buf[PATH_MAX];
184
185    o = edje_object_add(evas);
186    snprintf(buf, sizeof(buf), "%s/e-module-temperature.edj",
187             e_module_dir_get(temperature_config->module));
188    edje_object_file_set(o, buf, "icon");
189    return o;
190 }
191
192 static const char *
193 _gc_id_new(E_Gadcon_Client_Class *client_class __UNUSED__)
194 {
195    Config_Face *inst;
196    char id[128];
197
198    snprintf(id, sizeof(id), "%s.%d", _gadcon_class.name, ++uuid);
199
200    inst = E_NEW(Config_Face, 1);
201    inst->id = eina_stringshare_add(id);
202    inst->poll_interval = 128;
203    inst->low = 30;
204    inst->high = 80;
205    inst->sensor_type = SENSOR_TYPE_NONE;
206    inst->sensor_name = NULL;
207    inst->units = CELCIUS;
208 #ifdef HAVE_EEZE
209    inst->backend = TEMPGET;
210 #endif
211    if (!temperature_config->faces)
212      temperature_config->faces = eina_hash_string_superfast_new(NULL);
213    eina_hash_direct_add(temperature_config->faces, inst->id, inst);
214    return inst->id;
215 }
216
217 static void
218 _temperature_face_cb_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
219 {
220    Config_Face *inst;
221    Evas_Event_Mouse_Down *ev;
222
223    inst = data;
224    ev = event_info;
225    if ((ev->button == 3) && (!inst->menu))
226      {
227         E_Menu *m;
228         E_Menu_Item *mi;
229         int cx, cy;
230
231         m = e_menu_new();
232         mi = e_menu_item_new(m);
233         e_menu_item_label_set(mi, _("Settings"));
234         e_util_menu_item_theme_icon_set(mi, "configure");
235         e_menu_item_callback_set(mi, _temperature_face_cb_menu_configure, inst);
236
237         m = e_gadcon_client_util_menu_items_append(inst->gcc, m, 0);
238         e_menu_post_deactivate_callback_set(m, _temperature_face_cb_post_menu, inst);
239         inst->menu = m;
240
241         e_gadcon_canvas_zone_geometry_get(inst->gcc->gadcon,
242                                           &cx, &cy, NULL, NULL);
243         e_menu_activate_mouse(m,
244                               e_util_zone_current_get(e_manager_current_get()),
245                               cx + ev->output.x, cy + ev->output.y, 1, 1,
246                               E_MENU_POP_DIRECTION_AUTO, ev->timestamp);
247      }
248 }
249
250 static void
251 _temperature_face_cb_post_menu(void *data, E_Menu *m __UNUSED__)
252 {
253    Config_Face *inst;
254
255    inst = data;
256    if (!inst->menu) return;
257    e_object_del(E_OBJECT(inst->menu));
258    inst->menu = NULL;
259 }
260
261 void
262 _temperature_face_level_set(Config_Face *inst, double level)
263 {
264    Edje_Message_Float msg;
265
266    if (level < 0.0) level = 0.0;
267    else if (level > 1.0) level = 1.0;
268    msg.val = level;
269    edje_object_message_send(inst->o_temp, EDJE_MESSAGE_FLOAT, 1, &msg);
270 }
271
272 static void
273 _temperature_face_cb_menu_configure(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
274 {
275    Config_Face *inst;
276
277    inst = data;
278    if (inst->config_dialog) return;
279    config_temperature_module(inst);
280 }
281
282 static Eina_Bool
283 _temperature_face_shutdown(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *hdata, void *fdata __UNUSED__)
284 {
285    Config_Face *inst;
286
287    inst = hdata;
288    if (inst->sensor_name) eina_stringshare_del(inst->sensor_name);
289    if (inst->id) eina_stringshare_del(inst->id);
290 #ifdef HAVE_EEZE
291    if (inst->tempdevs)
292      {
293         const char *s;
294
295         EINA_LIST_FREE(inst->tempdevs, s)
296           eina_stringshare_del(s);
297      }
298 #endif
299    E_FREE(inst);
300    return EINA_TRUE;
301 }
302
303 static Eina_Bool
304 _temperature_face_id_max(const Eina_Hash *hash __UNUSED__, const void *key, void *hdata __UNUSED__, void *fdata)
305 {
306    const char *p;
307    int *max;
308    int num = -1;
309
310    max = fdata;
311    p = strrchr(key, '.');
312    if (p) num = atoi(p + 1);
313    if (num > *max) *max = num;
314    return EINA_TRUE;
315 }
316
317 void 
318 temperature_face_update_config(Config_Face *inst)
319 {
320    char buf[PATH_MAX];
321
322    if (inst->tempget_exe)
323      {
324         ecore_exe_terminate(inst->tempget_exe);
325         ecore_exe_free(inst->tempget_exe);
326         inst->tempget_exe = NULL;
327      }
328
329 #ifdef HAVE_EEZE
330    if (inst->backend == TEMPGET)
331      {
332         if (inst->temp_poller)
333           {
334              ecore_poller_del(inst->temp_poller);
335              inst->temp_poller = NULL;
336           }
337         if (!inst->tempget_exe) 
338           {
339              snprintf(buf, sizeof(buf),
340                       "%s/%s/tempget %i \"%s\" %i", 
341                       e_module_dir_get(temperature_config->module), MODULE_ARCH, 
342                       inst->sensor_type,
343                       (inst->sensor_name ? inst->sensor_name : "(null)"),
344                       inst->poll_interval);
345              inst->tempget_exe = 
346                ecore_exe_pipe_run(buf, ECORE_EXE_PIPE_READ | 
347                                   ECORE_EXE_PIPE_READ_LINE_BUFFERED |
348                                   ECORE_EXE_NOT_LEADER, inst);
349           }
350      }
351    else if (inst->backend == UDEV)
352      {
353         /*avoid creating a new poller if possible*/
354         if (inst->temp_poller)
355           ecore_poller_poller_interval_set(inst->temp_poller, 
356                                            inst->poll_interval);
357         else 
358           {
359              inst->temp_poller = 
360                ecore_poller_add(ECORE_POLLER_CORE, inst->poll_interval, 
361                                 temperature_udev_update_poll, inst);
362           }
363      }
364 #else
365    if (!inst->tempget_exe) 
366      {
367         snprintf(buf, sizeof(buf),
368                  "%s/%s/tempget %i \"%s\" %i", 
369                  e_module_dir_get(temperature_config->module), MODULE_ARCH, 
370                  inst->sensor_type,
371                  (inst->sensor_name ? inst->sensor_name : "(null)"),
372                  inst->poll_interval);
373         inst->tempget_exe = 
374           ecore_exe_pipe_run(buf, ECORE_EXE_PIPE_READ | 
375                              ECORE_EXE_PIPE_READ_LINE_BUFFERED |
376                              ECORE_EXE_NOT_LEADER, inst);
377      }
378 #endif
379 }
380
381 Eina_List *
382 temperature_get_bus_files(const char* bus)
383 {
384    Eina_List *result, *therms;
385    char path[PATH_MAX];
386    char busdir[PATH_MAX];
387
388    result = NULL;
389    if (result)
390      {
391         snprintf(busdir, sizeof(busdir), "/sys/bus/%s/devices", bus);
392         /* Look through all the devices for the given bus. */
393         therms = ecore_file_ls(busdir);
394         if (therms)
395           {
396              char *name;
397
398              EINA_LIST_FREE(therms, name)
399                {
400                   Eina_List *files;
401                   char *file;
402
403                   /* Search each device for temp*_input, these should be 
404                    * temperature devices. */
405                   snprintf(path, sizeof(path), "%s/%s", busdir, name);
406                   files = ecore_file_ls(path);
407                   EINA_LIST_FREE(files, file)
408                     {
409                        if ((!strncmp("temp", file, 4)) && 
410                            (!strcmp("_input", &file[strlen(file) - 6])))
411                          {
412                             char *f;
413
414                             snprintf(path, sizeof(path),
415                                      "%s/%s/%s", busdir, name, file);
416                             f = strdup(path);
417                             if (f) result = eina_list_append(result, f);
418                          }
419                        free(file);
420                     }
421                   free(name);
422                }
423           }
424      }
425    return result;
426 }
427
428 /* module setup */
429 EAPI E_Module_Api e_modapi = 
430 {
431    E_MODULE_API_VERSION,
432      "Temperature"
433 };
434
435 EAPI void *
436 e_modapi_init(E_Module *m)
437 {
438    conf_face_edd = E_CONFIG_DD_NEW("Temperature_Config_Face", Config_Face);
439 #undef T
440 #undef D
441 #define T Config_Face
442 #define D conf_face_edd
443    E_CONFIG_VAL(D, T, id, STR);
444    E_CONFIG_VAL(D, T, poll_interval, INT);
445    E_CONFIG_VAL(D, T, low, INT);
446    E_CONFIG_VAL(D, T, high, INT);
447    E_CONFIG_VAL(D, T, sensor_type, INT);
448 #ifdef HAVE_EEZE
449    E_CONFIG_VAL(D, T, backend, INT);
450 #endif
451    E_CONFIG_VAL(D, T, sensor_name, STR);
452    E_CONFIG_VAL(D, T, units, INT);
453
454    conf_edd = E_CONFIG_DD_NEW("Temperature_Config", Config);
455 #undef T
456 #undef D
457 #define T Config
458 #define D conf_edd
459    E_CONFIG_HASH(D, T, faces, conf_face_edd);
460
461    temperature_config = e_config_domain_load("module.temperature", conf_edd);
462    if (!temperature_config)
463      temperature_config = E_NEW(Config, 1);
464    else
465      eina_hash_foreach(temperature_config->faces, _temperature_face_id_max, &uuid);
466    temperature_config->module = m;
467
468    e_gadcon_provider_register(&_gadcon_class);
469    return m;
470 }
471
472 EAPI int
473 e_modapi_shutdown(E_Module *m __UNUSED__)
474 {
475    e_gadcon_provider_unregister(&_gadcon_class);
476    eina_hash_foreach(temperature_config->faces, _temperature_face_shutdown, NULL);
477    eina_hash_free(temperature_config->faces);
478    free(temperature_config);
479    temperature_config = NULL;
480    E_CONFIG_DD_FREE(conf_face_edd);
481    E_CONFIG_DD_FREE(conf_edd);
482    return 1;
483 }
484
485 EAPI int
486 e_modapi_save(E_Module *m __UNUSED__)
487 {
488    e_config_domain_save("module.temperature", conf_edd, temperature_config);
489    return 1;
490 }